aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/rtl8187se/r8180_gct.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/rtl8187se/r8180_gct.c')
-rw-r--r--drivers/staging/rtl8187se/r8180_gct.c296
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);
+}