diff options
Diffstat (limited to 'drivers/staging/rtl8187se/r8180_gct.c')
-rw-r--r-- | drivers/staging/rtl8187se/r8180_gct.c | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/drivers/staging/rtl8187se/r8180_gct.c b/drivers/staging/rtl8187se/r8180_gct.c new file mode 100644 index 000000000000..86cb427a7a40 --- /dev/null +++ b/drivers/staging/rtl8187se/r8180_gct.c @@ -0,0 +1,296 @@ +/* + This files contains GCT radio frontend programming routines. + + This is part of rtl8180 OpenSource driver + Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it> + Released under the terms of GPL (General Public Licence) + + Parts of this driver are based on the GPL part of the + official realtek driver + + Parts of this driver are based on the rtl8180 driver skeleton + from Patric Schenke & Andres Salomon + + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. + + Code from Rtw8180 NetBSD driver by David Young has been really useful to + understand some things and gets some ideas + + Code from rtl8181 project has been useful to me to understand some things. + + Some code from 'Deuce' work + + We want to tanks the Authors of such projects and the Ndiswrapper + project Authors. +*/ + + +#include "r8180.h" +#include "r8180_hw.h" +#include "r8180_gct.h" + + +//#define DEBUG_GCT + +/* the following experiment are just experiments. + * this means if you enable them you can have every kind + * of result, included damage the RF chip, so don't + * touch them if you don't know what you are doing. + * In any case, if you do it, do at your own risk + */ + +//#define GCT_EXPERIMENT1 //improve RX sensivity + +//#define GCT_EXPERIMENT2 + +//#define GCT_EXPERIMENT3 //iprove a bit RX signal quality ? + +//#define GCT_EXPERIMENT4 //maybe solve some brokeness with experiment1 ? + +//#define GCT_EXPERIMENT5 + +//#define GCT_EXPERIMENT6 //not good + + +u32 gct_chan[] = { + 0x0, //dummy channel 0 + 0x0, //1 + 0x1, //2 + 0x2, //3 + 0x3, //4 + 0x4, //5 + 0x5, //6 + 0x6, //7 + 0x7, //8 + 0x8, //9 + 0x9, //10 + 0xa, //11 + 0xb, //12 + 0xc, //13 + 0xd, //14 +}; + +int gct_encode[16] = { + 0, 8, 4, 0xC, + 2, 0xA, 6, 0xE, + 1, 9, 5, 0xD, + 3, 0xB, 7, 0xF +}; + +void gct_rf_stabilize(struct net_device *dev) +{ + force_pci_posting(dev); + mdelay(3); //for now use a great value.. we may optimize in future +} + + +void write_gct(struct net_device *dev, u8 adr, u32 data) +{ +// struct r8180_priv *priv = ieee80211_priv(dev); + u32 phy_config; + + phy_config = gct_encode[(data & 0xf00) >> 8]; + phy_config |= gct_encode[(data & 0xf0) >> 4 ] << 4; + phy_config |= gct_encode[(data & 0xf) ] << 8; + phy_config |= gct_encode[(adr >> 1) & 0xf ] << 12; + phy_config |= (adr & 1 ) << 16; + phy_config |= gct_encode[(data & 0xf000)>>12] << 24; + + phy_config |= 0x90000000; // MAC will bang bits to the chip + + + write_nic_dword(dev,PHY_CONFIG,phy_config); +#ifdef DEBUG_GCT + DMESG("Writing GCT: %x (adr %x)",phy_config,adr); +#endif + gct_rf_stabilize(dev); +} + + + +void gct_write_phy_antenna(struct net_device *dev,short ch) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + u8 ant; + + ant = GCT_ANTENNA; + if(priv->antb) /*default antenna is antenna B */ + ant |= BB_ANTENNA_B; + if(ch == 14) + ant |= BB_ANTATTEN_CHAN14; + write_phy(dev,0x10,ant); + //DMESG("BB antenna %x ",ant); +} + + +void gct_rf_set_chan(struct net_device *dev, short ch) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + u32 txpw = 0xff & priv->chtxpwr[ch]; + u32 chan = gct_chan[ch]; + + //write_phy(dev,3,txpw); +#ifdef DEBUG_GCT + DMESG("Gct set channel"); +#endif + /* set TX power */ + write_gct(dev,0x15,0); + write_gct(dev,6, txpw); + write_gct(dev,0x15, 0x10); + write_gct(dev,0x15,0); + + /*set frequency*/ + write_gct(dev,7, 0); + write_gct(dev,0xB, chan); + write_gct(dev,7, 0x1000); + +#ifdef DEBUG_GCT + DMESG("Gct set channel > write phy antenna"); +#endif + + + gct_write_phy_antenna(dev,ch); + +} + + +void gct_rf_close(struct net_device *dev) +{ + u32 anaparam; + + anaparam = read_nic_dword(dev,ANAPARAM); + anaparam &= 0x000fffff; + anaparam |= 0x3f900000; + rtl8180_set_anaparam(dev, anaparam); + + write_gct(dev, 0x7, 0); + write_gct(dev, 0x1f, 0x45); + write_gct(dev, 0x1f, 0x5); + write_gct(dev, 0x0, 0x8e4); +} + + +void gct_rf_init(struct net_device *dev) +{ + struct r8180_priv *priv = ieee80211_priv(dev); + //u32 anaparam; + + + write_nic_byte(dev,PHY_DELAY,0x6); //this is general + write_nic_byte(dev,CARRIER_SENSE_COUNTER,0x4c); //this is general + + //DMESG("%x", read_nic_dword(dev,ANAPARAM)); + /* we should set anaparm here*/ + //rtl8180_set_anaparam(dev,anaparam); + + write_gct(dev,0x1f,0); + write_gct(dev,0x1f,0); + write_gct(dev,0x1f,0x40); + write_gct(dev,0x1f,0x60); + write_gct(dev,0x1f,0x61); + write_gct(dev,0x1f,0x61); + write_gct(dev,0x0,0xae4); + write_gct(dev,0x1f,0x1); + write_gct(dev,0x1f,0x41); + write_gct(dev,0x1f,0x61); + write_gct(dev,0x1,0x1a23); + write_gct(dev,0x2,0x4971); + write_gct(dev,0x3,0x41de); + write_gct(dev,0x4,0x2d80); +#ifdef GCT_EXPERIMENT1 + //write_gct(dev,0x5,0x6810); // from zydas driver. sens+ but quite slow + //write_gct(dev,0x5,0x681f); //good+ (somewhat stable, better sens, performance decent) + write_gct(dev,0x5,0x685f); //good performances, not sure sens is really so beeter + //write_gct(dev,0x5,0x687f); //good performances, maybe sens is not improved + //write_gct(dev,0x5,0x689f); //like above + //write_gct(dev,0x5,0x685e); //bad + //write_gct(dev,0x5,0x68ff); //good+ (somewhat stable, better sens(?), performance decent) + //write_gct(dev,0x5,0x68f0); //bad + //write_gct(dev,0x5,0x6cff); //sens+ but not so good + //write_gct(dev,0x5,0x6dff); //sens+,apparentely very good but broken + //write_gct(dev,0x5,0x65ff); //sens+,good + //write_gct(dev,0x5,0x78ff); //sens + but almost broken + //write_gct(dev,0x5,0x7810); //- //snes + but broken + //write_gct(dev,0x5,0x781f); //-- //sens + + //write_gct(dev,0x5,0x78f0); //low sens +#else + write_gct(dev,0x5,0x61ff); //best performance but weak sensitivity +#endif +#ifdef GCT_EXPERIMENT2 + write_gct(dev,0x6,0xe); +#else + write_gct(dev,0x6,0x0); +#endif + write_gct(dev,0x7,0x0); + write_gct(dev,0x8,0x7533); + write_gct(dev,0x9,0xc401); + write_gct(dev,0xa,0x0); + write_gct(dev,0xc,0x1c7); + write_gct(dev,0xd,0x29d3); + write_gct(dev,0xe,0x2e8); + write_gct(dev,0x10,0x192); +#ifdef GCT_EXPERIMENT3 + write_gct(dev,0x11,0x246); +#else + write_gct(dev,0x11,0x248); +#endif + write_gct(dev,0x12,0x0); + write_gct(dev,0x13,0x20c4); +#ifdef GCT_EXPERIMENT4 + write_gct(dev,0x14,0xf488); +#else + write_gct(dev,0x14,0xf4fc); +#endif +#ifdef GCT_EXPERIMENT5 + write_gct(dev,0x15,0xb152); +#else + write_gct(dev,0x15,0x0); +#endif +#ifdef GCT_EXPERIMENT6 + write_gct(dev,0x1e,0x1); +#endif + write_gct(dev,0x16,0x1500); + + write_gct(dev,0x7,0x1000); + /*write_gct(dev,0x15,0x0); + write_gct(dev,0x6,0x15); + write_gct(dev,0x15,0x8); + write_gct(dev,0x15,0x0); +*/ + write_phy(dev,0,0xa8); + +/* write_gct(dev,0x15,0x0); + write_gct(dev,0x6,0x12); + write_gct(dev,0x15,0x8); + write_gct(dev,0x15,0x0); +*/ + write_phy(dev,3,0x0); + write_phy(dev,4,0xc0); /* lna det*/ + write_phy(dev,5,0x90); + write_phy(dev,6,0x1e); + write_phy(dev,7,0x64); + +#ifdef DEBUG_GCT + DMESG("Gct init> write phy antenna"); +#endif + + gct_write_phy_antenna(dev,priv->chan); + + write_phy(dev,0x11,0x88); + if(!priv->diversity) + write_phy(dev,0x12,0xc0); + else + write_phy(dev,0x12,0x40); + + write_phy(dev,0x13,0x90 | priv->cs_treshold ); + + write_phy(dev,0x19,0x0); + write_phy(dev,0x1a,0xa0); + write_phy(dev,0x1b,0x44); + +#ifdef DEBUG_GCT + DMESG("Gct init > set channel2"); +#endif + + gct_rf_set_chan(dev,priv->chan); +} |