ide_pci_generic: add quirk for Netcell ATA RAID
[linux-2.6] / drivers / staging / rtl8187se / r8180_gct.c
1 /*
2    This files contains GCT radio frontend programming routines.
3
4    This is part of rtl8180 OpenSource driver
5    Copyright (C) Andrea Merello 2004-2005  <andreamrl@tiscali.it>
6    Released under the terms of GPL (General Public Licence)
7
8    Parts of this driver are based on the GPL part of the
9    official realtek driver
10
11    Parts of this driver are based on the rtl8180 driver skeleton
12    from Patric Schenke & Andres Salomon
13
14    Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
15
16    Code from Rtw8180 NetBSD driver by David Young has been really useful to
17    understand some things and gets some ideas
18
19    Code from rtl8181 project has been useful to me to understand some things.
20
21    Some code from 'Deuce' work
22
23    We want to tanks the Authors of such projects and the Ndiswrapper
24    project Authors.
25 */
26
27
28 #include "r8180.h"
29 #include "r8180_hw.h"
30 #include "r8180_gct.h"
31
32
33 //#define DEBUG_GCT
34
35 /* the following experiment are just experiments.
36  * this means if you enable them you can have every kind
37  * of result, included damage the RF chip, so don't
38  * touch them if you don't know what you are doing.
39  * In any case, if you do it, do at your own risk
40  */
41
42 //#define GCT_EXPERIMENT1  //improve RX sensivity
43
44 //#define GCT_EXPERIMENT2
45
46 //#define GCT_EXPERIMENT3  //iprove a bit RX signal quality ?
47
48 //#define GCT_EXPERIMENT4 //maybe solve some brokeness with experiment1 ?
49
50 //#define GCT_EXPERIMENT5
51
52 //#define GCT_EXPERIMENT6  //not good
53
54
55 u32 gct_chan[] = {
56         0x0,    //dummy channel 0
57         0x0, //1
58         0x1, //2
59         0x2, //3
60         0x3, //4
61         0x4, //5
62         0x5, //6
63         0x6, //7
64         0x7, //8
65         0x8, //9
66         0x9, //10
67         0xa, //11
68         0xb, //12
69         0xc, //13
70         0xd, //14
71 };
72
73 int gct_encode[16] = {
74         0, 8, 4, 0xC,
75         2, 0xA, 6, 0xE,
76         1, 9, 5, 0xD,
77         3, 0xB, 7, 0xF
78 };
79
80 void gct_rf_stabilize(struct net_device *dev)
81 {
82         force_pci_posting(dev);
83         mdelay(3); //for now use a great value.. we may optimize in future
84 }
85
86
87 void write_gct(struct net_device *dev, u8 adr, u32 data)
88 {
89 //      struct r8180_priv *priv = ieee80211_priv(dev);
90         u32 phy_config;
91
92         phy_config =  gct_encode[(data & 0xf00) >> 8];
93         phy_config |= gct_encode[(data & 0xf0) >> 4 ] << 4;
94         phy_config |= gct_encode[(data & 0xf)       ] << 8;
95         phy_config |= gct_encode[(adr >> 1) & 0xf   ] << 12;
96         phy_config |=            (adr & 1 )           << 16;
97         phy_config |= gct_encode[(data & 0xf000)>>12] << 24;
98
99         phy_config |= 0x90000000; // MAC will bang bits to the chip
100
101
102         write_nic_dword(dev,PHY_CONFIG,phy_config);
103 #ifdef DEBUG_GCT
104         DMESG("Writing GCT: %x (adr %x)",phy_config,adr);
105 #endif
106         gct_rf_stabilize(dev);
107 }
108
109
110
111 void gct_write_phy_antenna(struct net_device *dev,short ch)
112 {
113         struct r8180_priv *priv = ieee80211_priv(dev);
114         u8 ant;
115
116         ant = GCT_ANTENNA;
117         if(priv->antb) /*default antenna is antenna B */
118                 ant |= BB_ANTENNA_B;
119         if(ch == 14)
120                 ant |= BB_ANTATTEN_CHAN14;
121         write_phy(dev,0x10,ant);
122         //DMESG("BB antenna %x ",ant);
123 }
124
125
126 void gct_rf_set_chan(struct net_device *dev, short ch)
127 {
128         struct r8180_priv *priv = ieee80211_priv(dev);
129         u32 txpw = 0xff & priv->chtxpwr[ch];
130         u32 chan = gct_chan[ch];
131
132         //write_phy(dev,3,txpw);
133 #ifdef DEBUG_GCT
134         DMESG("Gct set channel");
135 #endif
136         /* set TX power */
137         write_gct(dev,0x15,0);
138         write_gct(dev,6, txpw);
139         write_gct(dev,0x15, 0x10);
140         write_gct(dev,0x15,0);
141
142         /*set frequency*/
143         write_gct(dev,7, 0);
144         write_gct(dev,0xB, chan);
145         write_gct(dev,7, 0x1000);
146
147 #ifdef DEBUG_GCT
148         DMESG("Gct set channel > write phy antenna");
149 #endif
150
151
152         gct_write_phy_antenna(dev,ch);
153
154 }
155
156
157 void gct_rf_close(struct net_device *dev)
158 {
159         u32 anaparam;
160
161         anaparam = read_nic_dword(dev,ANAPARAM);
162         anaparam &= 0x000fffff;
163         anaparam |= 0x3f900000;
164         rtl8180_set_anaparam(dev, anaparam);
165
166         write_gct(dev, 0x7, 0);
167         write_gct(dev, 0x1f, 0x45);
168         write_gct(dev, 0x1f, 0x5);
169         write_gct(dev, 0x0, 0x8e4);
170 }
171
172
173 void gct_rf_init(struct net_device *dev)
174 {
175         struct r8180_priv *priv = ieee80211_priv(dev);
176         //u32 anaparam;
177
178
179         write_nic_byte(dev,PHY_DELAY,0x6);      //this is general
180         write_nic_byte(dev,CARRIER_SENSE_COUNTER,0x4c); //this is general
181
182         //DMESG("%x", read_nic_dword(dev,ANAPARAM));
183         /* we should set anaparm here*/
184         //rtl8180_set_anaparam(dev,anaparam);
185
186         write_gct(dev,0x1f,0);
187         write_gct(dev,0x1f,0);
188         write_gct(dev,0x1f,0x40);
189         write_gct(dev,0x1f,0x60);
190         write_gct(dev,0x1f,0x61);
191         write_gct(dev,0x1f,0x61);
192         write_gct(dev,0x0,0xae4);
193         write_gct(dev,0x1f,0x1);
194         write_gct(dev,0x1f,0x41);
195         write_gct(dev,0x1f,0x61);
196         write_gct(dev,0x1,0x1a23);
197         write_gct(dev,0x2,0x4971);
198         write_gct(dev,0x3,0x41de);
199         write_gct(dev,0x4,0x2d80);
200 #ifdef GCT_EXPERIMENT1
201         //write_gct(dev,0x5,0x6810);  // from zydas driver. sens+ but quite slow
202         //write_gct(dev,0x5,0x681f);  //good+ (somewhat stable, better sens, performance decent)
203         write_gct(dev,0x5,0x685f);  //good performances, not sure sens is really so beeter
204         //write_gct(dev,0x5,0x687f);  //good performances, maybe sens is not improved
205         //write_gct(dev,0x5,0x689f);  //like above
206         //write_gct(dev,0x5,0x685e);  //bad
207         //write_gct(dev,0x5,0x68ff);  //good+ (somewhat stable, better sens(?), performance decent)
208         //write_gct(dev,0x5,0x68f0);  //bad
209         //write_gct(dev,0x5,0x6cff);  //sens+ but not so good
210         //write_gct(dev,0x5,0x6dff);  //sens+,apparentely very good but broken
211         //write_gct(dev,0x5,0x65ff);  //sens+,good
212         //write_gct(dev,0x5,0x78ff);  //sens + but almost broken
213         //write_gct(dev,0x5,0x7810);  //- //snes + but broken
214         //write_gct(dev,0x5,0x781f);  //-- //sens +
215         //write_gct(dev,0x5,0x78f0);  //low sens
216 #else
217         write_gct(dev,0x5,0x61ff);   //best performance but weak sensitivity
218 #endif
219 #ifdef GCT_EXPERIMENT2
220         write_gct(dev,0x6,0xe);
221 #else
222         write_gct(dev,0x6,0x0);
223 #endif
224         write_gct(dev,0x7,0x0);
225         write_gct(dev,0x8,0x7533);
226         write_gct(dev,0x9,0xc401);
227         write_gct(dev,0xa,0x0);
228         write_gct(dev,0xc,0x1c7);
229         write_gct(dev,0xd,0x29d3);
230         write_gct(dev,0xe,0x2e8);
231         write_gct(dev,0x10,0x192);
232 #ifdef GCT_EXPERIMENT3
233         write_gct(dev,0x11,0x246);
234 #else
235         write_gct(dev,0x11,0x248);
236 #endif
237         write_gct(dev,0x12,0x0);
238         write_gct(dev,0x13,0x20c4);
239 #ifdef GCT_EXPERIMENT4
240         write_gct(dev,0x14,0xf488);
241 #else
242         write_gct(dev,0x14,0xf4fc);
243 #endif
244 #ifdef GCT_EXPERIMENT5
245         write_gct(dev,0x15,0xb152);
246 #else
247         write_gct(dev,0x15,0x0);
248 #endif
249 #ifdef GCT_EXPERIMENT6
250         write_gct(dev,0x1e,0x1);
251 #endif
252         write_gct(dev,0x16,0x1500);
253
254         write_gct(dev,0x7,0x1000);
255         /*write_gct(dev,0x15,0x0);
256         write_gct(dev,0x6,0x15);
257         write_gct(dev,0x15,0x8);
258         write_gct(dev,0x15,0x0);
259 */
260         write_phy(dev,0,0xa8);
261
262 /*      write_gct(dev,0x15,0x0);
263         write_gct(dev,0x6,0x12);
264         write_gct(dev,0x15,0x8);
265         write_gct(dev,0x15,0x0);
266 */
267         write_phy(dev,3,0x0);
268         write_phy(dev,4,0xc0); /* lna det*/
269         write_phy(dev,5,0x90);
270         write_phy(dev,6,0x1e);
271         write_phy(dev,7,0x64);
272
273 #ifdef DEBUG_GCT
274         DMESG("Gct init> write phy antenna");
275 #endif
276
277         gct_write_phy_antenna(dev,priv->chan);
278
279         write_phy(dev,0x11,0x88);
280         if(!priv->diversity)
281                 write_phy(dev,0x12,0xc0);
282         else
283                 write_phy(dev,0x12,0x40);
284
285         write_phy(dev,0x13,0x90 | priv->cs_treshold );
286
287         write_phy(dev,0x19,0x0);
288         write_phy(dev,0x1a,0xa0);
289         write_phy(dev,0x1b,0x44);
290
291 #ifdef DEBUG_GCT
292         DMESG("Gct init > set channel2");
293 #endif
294
295         gct_rf_set_chan(dev,priv->chan);
296 }