Merge branch 'for-2.6.31' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6
[pandora-kernel.git] / drivers / staging / agnx / phy.c
1 /**
2  * Airgo MIMO wireless driver
3  *
4  * Copyright (c) 2007 Li YanBo <dreamfly281@gmail.com>
5
6  * Thanks for Jeff Williams <angelbane@gmail.com> do reverse engineer
7  * works and published the SPECS at http://airgo.wdwconsulting.net/mymoin
8
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  */
13
14 #include <linux/init.h>
15 #include <linux/etherdevice.h>
16 #include <linux/pci.h>
17 #include <linux/delay.h>
18 #include "agnx.h"
19 #include "debug.h"
20 #include "phy.h"
21 #include "table.h"
22 #include "sta.h"
23 #include "xmit.h"
24
25 u8 read_from_eeprom(struct agnx_priv *priv, u16 address)
26 {
27         void __iomem *ctl = priv->ctl;
28         struct agnx_eeprom cmd;
29         u32 reg;
30
31         memset(&cmd, 0, sizeof(cmd));
32         cmd.cmd = EEPROM_CMD_READ << AGNX_EEPROM_COMMAND_SHIFT;
33         cmd.address = address;
34         /* Verify that the Status bit is clear */
35         /* Read Command and Address are written to the Serial Interface */
36         iowrite32(*(__le32 *)&cmd, ctl + AGNX_CIR_SERIALITF);
37         /* Wait for the Status bit to clear again */
38         eeprom_delay();
39         /* Read from Data */
40         reg = ioread32(ctl + AGNX_CIR_SERIALITF);
41
42         cmd = *(struct agnx_eeprom *)&reg;
43
44         return cmd.data;
45 }
46
47 static int card_full_reset(struct agnx_priv *priv)
48 {
49         void __iomem *ctl = priv->ctl;
50         u32 reg;
51         AGNX_TRACE;
52
53         reg = agnx_read32(ctl, AGNX_CIR_BLKCTL);
54         agnx_write32(ctl, AGNX_CIR_BLKCTL, 0x80);
55         reg = agnx_read32(ctl, AGNX_CIR_BLKCTL);
56         return 0;
57 }
58
59 inline void enable_power_saving(struct agnx_priv *priv)
60 {
61         void __iomem *ctl = priv->ctl;
62         u32 reg;
63
64         reg = agnx_read32(ctl, AGNX_PM_PMCTL);
65         reg &= ~0x8;
66         agnx_write32(ctl, AGNX_PM_PMCTL, reg);
67 }
68
69 inline void disable_power_saving(struct agnx_priv *priv)
70 {
71         void __iomem *ctl = priv->ctl;
72         u32 reg;
73
74         reg = agnx_read32(ctl, AGNX_PM_PMCTL);
75         reg |= 0x8;
76         agnx_write32(ctl, AGNX_PM_PMCTL, reg);
77 }
78
79
80 void disable_receiver(struct agnx_priv *priv)
81 {
82         void __iomem *ctl = priv->ctl;
83         AGNX_TRACE;
84
85         /* FIXME Disable the receiver */
86         agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x0);
87         /* Set gain control reset */
88         agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x1);
89         /* Reset gain control reset */
90         agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x0);
91 }
92
93
94 /* Fixme this shoule be disable RX, above is enable RX */
95 void enable_receiver(struct agnx_priv *priv)
96 {
97         void __iomem *ctl = priv->ctl;
98         AGNX_TRACE;
99
100         /* Set adaptive gain control discovery mode */
101         agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x3);
102         /* Set gain control reset */
103         agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x1);
104         /* Clear gain control reset */
105         agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x0);
106 }
107
108 static void mac_address_set(struct agnx_priv *priv)
109 {
110         void __iomem *ctl = priv->ctl;
111         u8 *mac_addr = priv->mac_addr;
112         u32 reg;
113
114         /* FIXME */
115         reg = (mac_addr[0] << 24) | (mac_addr[1] << 16) | mac_addr[2] << 8 | mac_addr[3];
116         iowrite32(reg, ctl + AGNX_RXM_MACHI);
117         reg = (mac_addr[4] << 8) | mac_addr[5];
118         iowrite32(reg, ctl + AGNX_RXM_MACLO);
119 }
120
121 static void receiver_bssid_set(struct agnx_priv *priv, const u8 *bssid)
122 {
123         void __iomem *ctl = priv->ctl;
124         u32 reg;
125
126         disable_receiver(priv);
127         /* FIXME */
128         reg = bssid[0] << 24 | (bssid[1] << 16) | (bssid[2] << 8) | bssid[3];
129         iowrite32(reg, ctl + AGNX_RXM_BSSIDHI);
130         reg = (bssid[4] << 8) | bssid[5];
131         iowrite32(reg, ctl + AGNX_RXM_BSSIDLO);
132
133         /* Enable the receiver */
134         enable_receiver(priv);
135
136         /* Clear the TSF */
137 /*      agnx_write32(ctl, AGNX_TXM_TSFLO, 0x0); */
138 /*      agnx_write32(ctl, AGNX_TXM_TSFHI, 0x0); */
139         /* Clear the TBTT */
140         agnx_write32(ctl, AGNX_TXM_TBTTLO, 0x0);
141         agnx_write32(ctl, AGNX_TXM_TBTTHI, 0x0);
142         disable_receiver(priv);
143 } /* receiver_bssid_set */
144
145 static void band_management_init(struct agnx_priv *priv)
146 {
147         void __iomem *ctl = priv->ctl;
148         void __iomem *data = priv->data;
149         u32 reg;
150         int i;
151         AGNX_TRACE;
152
153         agnx_write32(ctl, AGNX_BM_TXWADDR, AGNX_PDU_TX_WQ);
154         agnx_write32(ctl, AGNX_CIR_ADDRWIN, 0x0);
155         memset_io(data + AGNX_PDUPOOL, 0x0, AGNX_PDUPOOL_SIZE);
156         agnx_write32(ctl, AGNX_BM_BMCTL, 0x200);
157
158         agnx_write32(ctl, AGNX_BM_CIPDUWCNT, 0x40);
159         agnx_write32(ctl, AGNX_BM_SPPDUWCNT, 0x2);
160         agnx_write32(ctl, AGNX_BM_RFPPDUWCNT, 0x0);
161         agnx_write32(ctl, AGNX_BM_RHPPDUWCNT, 0x22);
162
163         /* FIXME Initialize the Free Pool Linked List */
164         /*    1. Write the Address of the Next Node ((0x41800 + node*size)/size)
165               to the first word of each node.  */
166         for (i = 0; i < PDU_FREE_CNT; i++) {
167                 iowrite32((AGNX_PDU_FREE + (i+1)*PDU_SIZE)/PDU_SIZE,
168                           data + AGNX_PDU_FREE + (PDU_SIZE * i));
169                 /* The last node should be set to 0x0 */
170                 if ((i + 1) == PDU_FREE_CNT)
171                         memset_io(data + AGNX_PDU_FREE + (PDU_SIZE * i),
172                                   0x0, PDU_SIZE);
173         }
174
175         /* Head is First Pool address (0x41800) / size (0x80) */
176         agnx_write32(ctl, AGNX_BM_FPLHP, AGNX_PDU_FREE/PDU_SIZE);
177         /* Tail is Last Pool Address (0x47f80) / size (0x80) */
178         agnx_write32(ctl, AGNX_BM_FPLTP, 0x47f80/PDU_SIZE);
179         /* Count is Number of Nodes in the Pool (0xd0) */
180         agnx_write32(ctl, AGNX_BM_FPCNT, PDU_FREE_CNT);
181
182         /* Start all workqueue */
183         agnx_write32(ctl, AGNX_BM_CIWQCTL, 0x80000);
184         agnx_write32(ctl, AGNX_BM_CPULWCTL, 0x80000);
185         agnx_write32(ctl, AGNX_BM_CPUHWCTL, 0x80000);
186         agnx_write32(ctl, AGNX_BM_CPUTXWCTL, 0x80000);
187         agnx_write32(ctl, AGNX_BM_CPURXWCTL, 0x80000);
188         agnx_write32(ctl, AGNX_BM_SPRXWCTL, 0x80000);
189         agnx_write32(ctl, AGNX_BM_SPTXWCTL, 0x80000);
190         agnx_write32(ctl, AGNX_BM_RFPWCTL, 0x80000);
191
192         /* Enable the Band Management */
193         reg = agnx_read32(ctl, AGNX_BM_BMCTL);
194         reg |= 0x1;
195         agnx_write32(ctl, AGNX_BM_BMCTL, reg);
196 } /* band_managment_init */
197
198
199 static void system_itf_init(struct agnx_priv *priv)
200 {
201         void __iomem *ctl = priv->ctl;
202         u32 reg;
203         AGNX_TRACE;
204
205         agnx_write32(ctl, AGNX_SYSITF_GPIOUT, 0x0);
206         agnx_write32(ctl, AGNX_PM_TESTPHY, 0x11e143a);
207
208         if (priv->revid == 0) {
209                 reg = agnx_read32(ctl, AGNX_SYSITF_SYSMODE);
210                 reg |= 0x11;
211                 agnx_write32(ctl, AGNX_SYSITF_SYSMODE, reg);
212         }
213         /* ??? What is that means? it should difference for differice type
214          of cards */
215         agnx_write32(ctl, AGNX_CIR_SERIALITF, 0xfff81006);
216
217         agnx_write32(ctl, AGNX_SYSITF_GPIOIN, 0x1f0000);
218         agnx_write32(ctl, AGNX_SYSITF_GPIOUT, 0x5);
219         reg = agnx_read32(ctl, AGNX_SYSITF_GPIOIN);
220 }
221
222 static void encryption_init(struct agnx_priv *priv)
223 {
224         void __iomem *ctl = priv->ctl;
225         AGNX_TRACE;
226
227         agnx_write32(ctl, AGNX_ENCRY_WEPKEY0, 0x0);
228         agnx_write32(ctl, AGNX_ENCRY_WEPKEY1, 0x0);
229         agnx_write32(ctl, AGNX_ENCRY_WEPKEY2, 0x0);
230         agnx_write32(ctl, AGNX_ENCRY_WEPKEY3, 0x0);
231         agnx_write32(ctl, AGNX_ENCRY_CCMRECTL, 0x8);
232 }
233
234 static void tx_management_init(struct agnx_priv *priv)
235 {
236         void __iomem *ctl = priv->ctl;
237         void __iomem *data = priv->data;
238         u32 reg;
239         AGNX_TRACE;
240
241         /* Fill out the ComputationalEngineLookupTable
242          * starting at memory #2 offset 0x800
243          */
244         tx_engine_lookup_tbl_init(priv);
245         memset_io(data + 0x1000, 0, 0xfe0);
246         /* Enable Transmission Management Functions */
247         agnx_write32(ctl, AGNX_TXM_ETMF, 0x3ff);
248         /* Write 0x3f to Transmission Template */
249         agnx_write32(ctl, AGNX_TXM_TXTEMP, 0x3f);
250
251         if (priv->revid >= 2)
252                 agnx_write32(ctl, AGNX_TXM_SIFSPIFS, 0x1e140a0b);
253         else
254                 agnx_write32(ctl, AGNX_TXM_SIFSPIFS, 0x1e190a0b);
255
256         reg = agnx_read32(ctl, AGNX_TXM_TIFSEIFS);
257         reg &= 0xff00;
258         reg |= 0xb;
259         agnx_write32(ctl, AGNX_TXM_TIFSEIFS, reg);
260         reg = agnx_read32(ctl, AGNX_TXM_TIFSEIFS);
261         reg &= 0xffff00ff;
262         reg |= 0xa00;
263         agnx_write32(ctl, AGNX_TXM_TIFSEIFS, reg);
264         /* Enable TIFS */
265         agnx_write32(ctl, AGNX_TXM_CTL, 0x40000);
266
267         reg = agnx_read32(ctl, AGNX_TXM_TIFSEIFS);
268         reg &= 0xff00ffff;
269         reg |= 0x510000;
270         agnx_write32(ctl, AGNX_TXM_TIFSEIFS, reg);
271         reg = agnx_read32(ctl, AGNX_TXM_PROBDELAY);
272         reg &= 0xff00ffff;
273         agnx_write32(ctl, AGNX_TXM_PROBDELAY, reg);
274         reg = agnx_read32(ctl, AGNX_TXM_TIFSEIFS);
275         reg &= 0x00ffffff;
276         reg |= 0x1c000000;
277         agnx_write32(ctl, AGNX_TXM_TIFSEIFS, reg);
278         reg = agnx_read32(ctl, AGNX_TXM_PROBDELAY);
279         reg &= 0x00ffffff;
280         reg |= 0x01000000;
281         agnx_write32(ctl, AGNX_TXM_PROBDELAY, reg);
282
283         /* # Set DIF 0-1,2-3,4-5,6-7 to defaults */
284         agnx_write32(ctl, AGNX_TXM_DIF01, 0x321d321d);
285         agnx_write32(ctl, AGNX_TXM_DIF23, 0x321d321d);
286         agnx_write32(ctl, AGNX_TXM_DIF45, 0x321d321d);
287         agnx_write32(ctl, AGNX_TXM_DIF67, 0x321d321d);
288
289         /* Max Ack timeout limit */
290         agnx_write32(ctl, AGNX_TXM_MAXACKTIM, 0x1e19);
291         /* Max RX Data Timeout count, */
292         reg = agnx_read32(ctl, AGNX_TXM_MAXRXTIME);
293         reg &= 0xffff0000;
294         reg |= 0xff;
295         agnx_write32(ctl, AGNX_TXM_MAXRXTIME, reg);
296
297         /* CF poll RX Timeout count */
298         reg = agnx_read32(ctl, AGNX_TXM_CFPOLLRXTIM);
299         reg &= 0xffff;
300         reg |= 0xff0000;
301         agnx_write32(ctl, AGNX_TXM_CFPOLLRXTIM, reg);
302
303         /* Max Timeout Exceeded count, */
304         reg = agnx_read32(ctl, AGNX_TXM_MAXTIMOUT);
305         reg &= 0xff00ffff;
306         reg |= 0x190000;
307         agnx_write32(ctl, AGNX_TXM_MAXTIMOUT, reg);
308
309         /* CF ack timeout limit for 11b */
310         reg = agnx_read32(ctl, AGNX_TXM_CFACKT11B);
311         reg &= 0xff00;
312         reg |= 0x1e;
313         agnx_write32(ctl, AGNX_TXM_CFACKT11B, reg);
314
315         /* Max CF Poll Timeout Count */
316         reg = agnx_read32(ctl, AGNX_TXM_CFPOLLRXTIM);
317         reg &= 0xffff0000;
318         reg |= 0x19;
319         agnx_write32(ctl, AGNX_TXM_CFPOLLRXTIM, reg);
320         /* CF Poll RX Timeout Count */
321         reg = agnx_read32(ctl, AGNX_TXM_CFPOLLRXTIM);
322         reg &= 0xffff0000;
323         reg |= 0x1e;
324         agnx_write32(ctl, AGNX_TXM_CFPOLLRXTIM, reg);
325
326         /* # write default to */
327         /*    1. Schedule Empty Count */
328         agnx_write32(ctl, AGNX_TXM_SCHEMPCNT, 0x5);
329         /*    2. CFP Period Count */
330         agnx_write32(ctl, AGNX_TXM_CFPERCNT, 0x1);
331         /*    3. CFP MDV  */
332         agnx_write32(ctl, AGNX_TXM_CFPMDV, 0x10000);
333
334         /* Probe Delay */
335         reg = agnx_read32(ctl, AGNX_TXM_PROBDELAY);
336         reg &= 0xffff0000;
337         reg |= 0x400;
338         agnx_write32(ctl, AGNX_TXM_PROBDELAY, reg);
339
340         /* Max CCA count Slot */
341         reg = agnx_read32(ctl, AGNX_TXM_MAXCCACNTSLOT);
342         reg &= 0xffff00ff;
343         reg |= 0x900;
344         agnx_write32(ctl, AGNX_TXM_MAXCCACNTSLOT, reg);
345
346         /* Slot limit/1 msec Limit */
347         reg = agnx_read32(ctl, AGNX_TXM_SLOTLIMIT);
348         reg &= 0xff00ffff;
349         reg |= 0x140077;
350         agnx_write32(ctl, AGNX_TXM_SLOTLIMIT, reg);
351
352         /* # Set CW #(0-7) to default */
353         agnx_write32(ctl, AGNX_TXM_CW0, 0xff0007);
354         agnx_write32(ctl, AGNX_TXM_CW1, 0xff0007);
355         agnx_write32(ctl, AGNX_TXM_CW2, 0xff0007);
356         agnx_write32(ctl, AGNX_TXM_CW3, 0xff0007);
357         agnx_write32(ctl, AGNX_TXM_CW4, 0xff0007);
358         agnx_write32(ctl, AGNX_TXM_CW5, 0xff0007);
359         agnx_write32(ctl, AGNX_TXM_CW6, 0xff0007);
360         agnx_write32(ctl, AGNX_TXM_CW7, 0xff0007);
361
362         /* # Set Short/Long limit #(0-7) to default */
363         agnx_write32(ctl, AGNX_TXM_SLBEALIM0,  0xa000a);
364         agnx_write32(ctl, AGNX_TXM_SLBEALIM1,  0xa000a);
365         agnx_write32(ctl, AGNX_TXM_SLBEALIM2,  0xa000a);
366         agnx_write32(ctl, AGNX_TXM_SLBEALIM3,  0xa000a);
367         agnx_write32(ctl, AGNX_TXM_SLBEALIM4,  0xa000a);
368         agnx_write32(ctl, AGNX_TXM_SLBEALIM5,  0xa000a);
369         agnx_write32(ctl, AGNX_TXM_SLBEALIM6,  0xa000a);
370         agnx_write32(ctl, AGNX_TXM_SLBEALIM7,  0xa000a);
371
372         reg = agnx_read32(ctl, AGNX_TXM_CTL);
373         reg |= 0x1400;
374         agnx_write32(ctl, AGNX_TXM_CTL, reg);
375         /* Wait for bit 0 in Control Reg to clear  */
376         udelay(80);
377         reg = agnx_read32(ctl, AGNX_TXM_CTL);
378         /* Or 0x18000 to Control reg */
379         reg = agnx_read32(ctl, AGNX_TXM_CTL);
380         reg |= 0x18000;
381         agnx_write32(ctl, AGNX_TXM_CTL, reg);
382         /* Wait for bit 0 in Control Reg to clear */
383         udelay(80);
384         reg = agnx_read32(ctl, AGNX_TXM_CTL);
385
386         /* Set Listen Interval Count to default */
387         agnx_write32(ctl, AGNX_TXM_LISINTERCNT, 0x1);
388         /* Set DTIM period count to default */
389         agnx_write32(ctl, AGNX_TXM_DTIMPERICNT, 0x2000);
390 } /* tx_management_init */
391
392 static void rx_management_init(struct agnx_priv *priv)
393 {
394         void __iomem *ctl = priv->ctl;
395         AGNX_TRACE;
396
397         /* Initialize the Routing Table */
398         routing_table_init(priv);
399
400         if (priv->revid >= 3) {
401                 agnx_write32(ctl, 0x2074, 0x1f171710);
402                 agnx_write32(ctl, 0x2078, 0x10100d0d);
403                 agnx_write32(ctl, 0x207c, 0x11111010);
404         } else {
405                 agnx_write32(ctl, AGNX_RXM_DELAY11, 0x0);
406         }
407         agnx_write32(ctl, AGNX_RXM_REQRATE, 0x8195e00);
408 }
409
410
411 static void agnx_timer_init(struct agnx_priv *priv)
412 {
413         void __iomem *ctl = priv->ctl;
414         AGNX_TRACE;
415
416 /*      /\* Write 0x249f00 (tick duration?) to Timer 1 *\/ */
417 /*      agnx_write32(ctl, AGNX_TIMCTL_TIMER1, 0x249f00); */
418 /*      /\* Write 0xe2 to Timer 1 Control *\/ */
419 /*      agnx_write32(ctl, AGNX_TIMCTL_TIM1CTL, 0xe2); */
420
421         /* Write 0x249f00 (tick duration?) to Timer 1 */
422         agnx_write32(ctl, AGNX_TIMCTL_TIMER1, 0x0);
423         /* Write 0xe2 to Timer 1 Control */
424         agnx_write32(ctl, AGNX_TIMCTL_TIM1CTL, 0x0);
425
426         iowrite32(0xFFFFFFFF, priv->ctl + AGNX_TXM_BEACON_CTL);
427 }
428
429 static void power_manage_init(struct agnx_priv *priv)
430 {
431         void __iomem *ctl = priv->ctl;
432         u32 reg;
433         AGNX_TRACE;
434
435         agnx_write32(ctl, AGNX_PM_MACMSW, 0x1f);
436         agnx_write32(ctl, AGNX_PM_RFCTL, 0x1f);
437
438         reg = agnx_read32(ctl, AGNX_PM_PMCTL);
439         reg &= 0xf00f;
440         reg |= 0xa0;
441         agnx_write32(ctl, AGNX_PM_PMCTL, reg);
442
443         if (priv->revid >= 3) {
444                 reg = agnx_read32(ctl, AGNX_PM_SOFTRST);
445                 reg |= 0x18;
446                 agnx_write32(ctl, AGNX_PM_SOFTRST, reg);
447         }
448 } /* power_manage_init */
449
450
451 static void gain_ctlcnt_init(struct agnx_priv *priv)
452 {
453         void __iomem *ctl = priv->ctl;
454         u32 reg;
455         AGNX_TRACE;
456
457         agnx_write32(ctl, AGNX_GCR_TRACNT5, 0x119);
458         agnx_write32(ctl, AGNX_GCR_TRACNT6, 0x118);
459         agnx_write32(ctl, AGNX_GCR_TRACNT7, 0x117);
460
461         reg = agnx_read32(ctl, AGNX_PM_PMCTL);
462         reg |= 0x8;
463         agnx_write32(ctl, AGNX_PM_PMCTL, reg);
464
465         reg = agnx_read32(ctl, AGNX_PM_PMCTL);
466         reg &= ~0x8;
467         agnx_write32(ctl, AGNX_PM_PMCTL, reg);
468
469         agnx_write32(ctl, AGNX_CIR_ADDRWIN, 0x0);
470
471         /* FIXME Write the initial Station Descriptor for the card */
472         sta_init(priv, LOCAL_STAID);
473         sta_init(priv, BSSID_STAID);
474
475         /* Enable staion 0 and 1 can do TX */
476         /* It seemed if we set other bit to 1 the bit 0 will
477            be auto change to 0 */
478         agnx_write32(ctl, AGNX_BM_TXTOPEER, 0x2 | 0x1);
479 /*      agnx_write32(ctl, AGNX_BM_TXTOPEER, 0x1); */
480 } /* gain_ctlcnt_init */
481
482
483 static void phy_init(struct agnx_priv *priv)
484 {
485         void __iomem *ctl = priv->ctl;
486         void __iomem *data = priv->data;
487         u32 reg;
488         AGNX_TRACE;
489
490         /* Load InitialGainTable */
491         gain_table_init(priv);
492
493         agnx_write32(ctl, AGNX_CIR_ADDRWIN, 0x2000000);
494
495         /* Clear the following offsets in Memory Range #2: */
496         memset_io(data + 0x5040, 0, 0xa * 4);
497         memset_io(data + 0x5080, 0, 0xa * 4);
498         memset_io(data + 0x50c0, 0, 0xa * 4);
499         memset_io(data + 0x5400, 0, 0x80 * 4);
500         memset_io(data + 0x6000, 0, 0x280 * 4);
501         memset_io(data + 0x7000, 0, 0x280 * 4);
502         memset_io(data + 0x8000, 0, 0x280 * 4);
503
504         /* Initialize the Following Registers According to PCI Revision ID */
505         if (priv->revid == 0) {
506                 /* fixme the part hasn't been update but below has been update
507                    based on WGM511 */
508                 agnx_write32(ctl, AGNX_ACI_LEN, 0xf);
509                 agnx_write32(ctl, AGNX_ACI_TIMER1, 0x1d);
510                 agnx_write32(ctl, AGNX_ACI_TIMER2, 0x3);
511                 agnx_write32(ctl, AGNX_ACI_AICCHA0OVE, 0x11);
512                 agnx_write32(ctl, AGNX_ACI_AICCHA1OVE, 0x0);
513                 agnx_write32(ctl, AGNX_GCR_THD0A, 0x64);
514                 agnx_write32(ctl, AGNX_GCR_THD0AL, 0x4b);
515                 agnx_write32(ctl, AGNX_GCR_THD0B, 0x4b);
516                 agnx_write32(ctl, AGNX_GCR_DUNSAT, 0x14);
517                 agnx_write32(ctl, AGNX_GCR_DSAT, 0x24);
518                 agnx_write32(ctl, AGNX_GCR_DFIRCAL, 0x8);
519                 agnx_write32(ctl, AGNX_GCR_DGCTL11A, 0x1a);
520                 agnx_write32(ctl, AGNX_GCR_DGCTL11B, 0x3);
521                 agnx_write32(ctl, AGNX_GCR_GAININIT, 0xd);
522                 agnx_write32(ctl, AGNX_GCR_THNOSIG, 0x1);
523                 agnx_write32(ctl, AGNX_GCR_COARSTEP, 0x7);
524                 agnx_write32(ctl, AGNX_GCR_SIFST11A, 0x28);
525                 agnx_write32(ctl, AGNX_GCR_SIFST11B, 0x28);
526                 reg = agnx_read32(ctl, AGNX_GCR_CWDETEC);
527                 reg |= 0x1;
528                 agnx_write32(ctl, AGNX_GCR_CWDETEC, reg);
529                 agnx_write32(ctl, AGNX_GCR_0X38, 0x1e);
530                 agnx_write32(ctl, AGNX_GCR_BOACT, 0x26);
531                 agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x3);
532                 agnx_write32(ctl, AGNX_GCR_NLISTANT, 0x3);
533                 agnx_write32(ctl, AGNX_GCR_NACTIANT, 0x3);
534                 agnx_write32(ctl, AGNX_GCR_NMEASANT, 0x3);
535                 agnx_write32(ctl, AGNX_GCR_NCAPTANT, 0x3);
536                 agnx_write32(ctl, AGNX_GCR_THCAP11A, 0x0);
537                 agnx_write32(ctl, AGNX_GCR_THCAP11B, 0x0);
538                 agnx_write32(ctl, AGNX_GCR_THCAPRX11A, 0x0);
539                 agnx_write32(ctl, AGNX_GCR_THCAPRX11B, 0x0);
540                 agnx_write32(ctl, AGNX_GCR_THLEVDRO, 0x10);
541                 agnx_write32(ctl, AGNX_GCR_MAXRXTIME11A, 0x1);
542                 agnx_write32(ctl, AGNX_GCR_MAXRXTIME11B, 0x1);
543                 agnx_write32(ctl, AGNX_GCR_CORRTIME, 0x190);
544                 agnx_write32(ctl, AGNX_GCR_SIGHTH, 0x78);
545                 agnx_write32(ctl, AGNX_GCR_SIGLTH, 0x1c);
546                 agnx_write32(ctl, AGNX_GCR_CORRDROP, 0x0);
547                 agnx_write32(ctl, AGNX_GCR_THCD, 0x0);
548                 agnx_write32(ctl, AGNX_GCR_MAXPOWDIFF, 0x1);
549                 agnx_write32(ctl, AGNX_GCR_TESTBUS, 0x0);
550                 agnx_write32(ctl, AGNX_GCR_ANTCFG, 0x1f);
551                 agnx_write32(ctl, AGNX_GCR_THJUMP, 0x14);
552                 agnx_write32(ctl, AGNX_GCR_THPOWER, 0x0);
553                 agnx_write32(ctl, AGNX_GCR_THPOWCLIP, 0x30);
554                 agnx_write32(ctl, AGNX_GCR_THD0BTFEST, 0x32);
555                 agnx_write32(ctl, AGNX_GCR_THRX11BPOWMIN, 0x19);
556                 agnx_write32(ctl, AGNX_GCR_0X14c, 0x0);
557                 agnx_write32(ctl, AGNX_GCR_0X150, 0x0);
558                 agnx_write32(ctl, 0x9400, 0x0);
559                 agnx_write32(ctl, 0x940c, 0x6ff);
560                 agnx_write32(ctl, 0x9428, 0xa0);
561                 agnx_write32(ctl, 0x9434, 0x0);
562                 agnx_write32(ctl, 0x9c04, 0x15);
563                 agnx_write32(ctl, 0x9c0c, 0x7f);
564                 agnx_write32(ctl, 0x9c34, 0x0);
565                 agnx_write32(ctl, 0xc000, 0x38d);
566                 agnx_write32(ctl, 0x14018, 0x0);
567                 agnx_write32(ctl, 0x16000, 0x1);
568                 agnx_write32(ctl, 0x11004, 0x0);
569                 agnx_write32(ctl, 0xec54, 0xa);
570                 agnx_write32(ctl, 0xec1c, 0x5);
571         } else if (priv->revid > 0) {
572                 agnx_write32(ctl, AGNX_ACI_LEN, 0xf);
573                 agnx_write32(ctl, AGNX_ACI_TIMER1, 0x21);
574                 agnx_write32(ctl, AGNX_ACI_TIMER2, 0x27);
575                 agnx_write32(ctl, AGNX_ACI_AICCHA0OVE, 0x11);
576                 agnx_write32(ctl, AGNX_ACI_AICCHA1OVE, 0x0);
577                 agnx_write32(ctl, AGNX_GCR_DUNSAT, 0x14);
578                 agnx_write32(ctl, AGNX_GCR_DSAT, 0x24);
579                 agnx_write32(ctl, AGNX_GCR_DFIRCAL, 0x8);
580                 agnx_write32(ctl, AGNX_GCR_DGCTL11A, 0x1a);
581                 agnx_write32(ctl, AGNX_GCR_DGCTL11B, 0x3);
582                 agnx_write32(ctl, AGNX_GCR_GAININIT, 0xd);
583                 agnx_write32(ctl, AGNX_GCR_THNOSIG, 0x1);
584                 agnx_write32(ctl, AGNX_GCR_COARSTEP, 0x7);
585                 agnx_write32(ctl, AGNX_GCR_SIFST11A, 0x28);
586                 agnx_write32(ctl, AGNX_GCR_SIFST11B, 0x28);
587                 agnx_write32(ctl, AGNX_GCR_CWDETEC, 0x0);
588                 agnx_write32(ctl, AGNX_GCR_0X38, 0x1e);
589 /*              agnx_write32(ctl, AGNX_GCR_BOACT, 0x26);*/
590                 agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x3);
591
592                 agnx_write32(ctl, AGNX_GCR_THCAP11A, 0x32);
593                 agnx_write32(ctl, AGNX_GCR_THCAP11B, 0x32);
594                 agnx_write32(ctl, AGNX_GCR_THCAPRX11A, 0x32);
595                 agnx_write32(ctl, AGNX_GCR_THCAPRX11B, 0x32);
596                 agnx_write32(ctl, AGNX_GCR_THLEVDRO, 0x10);
597                 agnx_write32(ctl, AGNX_GCR_MAXRXTIME11A, 0x1ad);
598                 agnx_write32(ctl, AGNX_GCR_MAXRXTIME11B, 0xa10);
599                 agnx_write32(ctl, AGNX_GCR_CORRTIME, 0x190);
600                 agnx_write32(ctl, AGNX_GCR_CORRDROP, 0x0);
601                 agnx_write32(ctl, AGNX_GCR_THCD, 0x0);
602                 agnx_write32(ctl, AGNX_GCR_THCS, 0x0);
603                 agnx_write32(ctl, AGNX_GCR_MAXPOWDIFF, 0x4);
604                 agnx_write32(ctl, AGNX_GCR_TESTBUS, 0x0);
605                 agnx_write32(ctl, AGNX_GCR_THJUMP, 0x1e);
606                 agnx_write32(ctl, AGNX_GCR_THPOWER, 0x0);
607                 agnx_write32(ctl, AGNX_GCR_THPOWCLIP, 0x2a);
608                 agnx_write32(ctl, AGNX_GCR_THD0BTFEST, 0x3c);
609                 agnx_write32(ctl, AGNX_GCR_THRX11BPOWMIN, 0x19);
610                 agnx_write32(ctl, AGNX_GCR_0X14c, 0x0);
611                 agnx_write32(ctl, AGNX_GCR_0X150, 0x0);
612                 agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x0);
613                 agnx_write32(ctl, AGNX_GCR_WATCHDOG, 0x37);
614                 agnx_write32(ctl, 0x9400, 0x0);
615                 agnx_write32(ctl, 0x940c, 0x6ff);
616                 agnx_write32(ctl, 0x9428, 0xa0);
617                 agnx_write32(ctl, 0x9434, 0x0);
618                 agnx_write32(ctl, 0x9c04, 0x15);
619                 agnx_write32(ctl, 0x9c0c, 0x7f);
620                 agnx_write32(ctl, 0x9c34, 0x0);
621                 agnx_write32(ctl, 0xc000, 0x38d);
622                 agnx_write32(ctl, 0x14014, 0x1000);
623                 agnx_write32(ctl, 0x14018, 0x0);
624                 agnx_write32(ctl, 0x16000, 0x1);
625                 agnx_write32(ctl, 0x11004, 0x0);
626                 agnx_write32(ctl, 0xec54, 0xa);
627                 agnx_write32(ctl, 0xec1c, 0x50);
628         } else if (priv->revid > 1) {
629                 reg = agnx_read32(ctl, 0xec18);
630                 reg |= 0x8;
631                 agnx_write32(ctl, 0xec18, reg);
632         }
633
634         /* Write the TX Fir Coefficient Table */
635         tx_fir_table_init(priv);
636
637         reg = agnx_read32(ctl, AGNX_PM_PMCTL);
638         reg &= ~0x8;
639         agnx_write32(ctl, AGNX_PM_PMCTL, reg);
640         reg = agnx_read32(ctl, AGNX_PM_PLLCTL);
641         reg |= 0x1;
642         agnx_write32(ctl, AGNX_PM_PLLCTL, reg);
643
644 /*      reg = agnx_read32(ctl, 0x1a030); */
645 /*      reg &= ~0x4; */
646 /*      agnx_write32(ctl, 0x1a030, reg); */
647
648         agnx_write32(ctl, AGNX_GCR_TRACNT4, 0x113);
649 } /* phy_init */
650
651 static void chip_init(struct agnx_priv *priv)
652 {
653         void __iomem *ctl = priv->ctl;
654         u32 reg;
655         AGNX_TRACE;
656
657         band_management_init(priv);
658
659         rf_chips_init(priv);
660
661         reg = agnx_read32(ctl, AGNX_PM_PMCTL);
662         reg |= 0x8;
663         agnx_write32(ctl, AGNX_PM_PMCTL, reg);
664
665         /* Initialize the PHY */
666         phy_init(priv);
667
668         encryption_init(priv);
669
670         tx_management_init(priv);
671
672         rx_management_init(priv);
673
674         power_manage_init(priv);
675
676         /* Initialize the Timers */
677         agnx_timer_init(priv);
678
679         /* Write 0xc390bf9 to Interrupt Mask (Disable TX) */
680         reg = 0xc390bf9 & ~IRQ_TX_BEACON;
681         reg &= ~IRQ_TX_DISABLE;
682         agnx_write32(ctl, AGNX_INT_MASK, reg);
683
684         reg = agnx_read32(ctl, AGNX_CIR_BLKCTL);
685         reg |= 0x800;
686         agnx_write32(ctl, AGNX_CIR_BLKCTL, reg);
687
688         /* set it when need get multicast enable? */
689         agnx_write32(ctl, AGNX_BM_MTSM, 0xff);
690 } /* chip_init */
691
692
693 static inline void set_promis_and_managed(struct agnx_priv *priv)
694 {
695         void __iomem *ctl = priv->ctl;
696         agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x10 | 0x2);
697         agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x10 | 0x2);
698 }
699 static inline void set_learn_mode(struct agnx_priv *priv)
700 {
701         void __iomem *ctl = priv->ctl;
702         agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x8);
703 }
704 static inline void set_scan_mode(struct agnx_priv *priv)
705 {
706         void __iomem *ctl = priv->ctl;
707         agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x20);
708 }
709 static inline void set_promiscuous_mode(struct agnx_priv *priv)
710 {
711         void __iomem *ctl = priv->ctl;
712         /* agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x210);*/
713         agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x10);
714 }
715 static inline void set_managed_mode(struct agnx_priv *priv)
716 {
717         void __iomem *ctl = priv->ctl;
718         agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x2);
719 }
720 static inline void set_adhoc_mode(struct agnx_priv *priv)
721 {
722         void __iomem *ctl = priv->ctl;
723         agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x0);
724 }
725
726 #if 0
727 static void unknow_register_write(struct agnx_priv *priv)
728 {
729         void __iomem *ctl = priv->ctl;
730
731         agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x0, 0x3e);
732         agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x4, 0xb2);
733         agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x8, 0x140);
734         agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0xc, 0x1C0);
735         agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x10, 0x1FF);
736         agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x14, 0x1DD);
737         agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x18, 0x15F);
738         agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x1c, 0xA1);
739         agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x20, 0x3E7);
740         agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x24, 0x36B);
741         agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x28, 0x348);
742         agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x2c, 0x37D);
743         agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x30, 0x3DE);
744         agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x34, 0x36);
745         agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x38, 0x64);
746         agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x3c, 0x57);
747         agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x40, 0x23);
748         agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x44, 0x3ED);
749         agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x48, 0x3C9);
750         agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x4c, 0x3CA);
751         agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x50, 0x3E7);
752         agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x54, 0x8);
753         agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x58, 0x1F);
754         agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x5c, 0x1a);
755 }
756 #endif
757
758 static void card_interface_init(struct agnx_priv *priv)
759 {
760         void __iomem *ctl = priv->ctl;
761         u8 bssid[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
762         u32 reg;
763         unsigned int i;
764         AGNX_TRACE;
765
766         might_sleep();
767         /* Clear RX Control and Enable RX queues */
768         agnx_write32(ctl, AGNX_CIR_RXCTL, 0x8);
769
770         might_sleep();
771         /* Do a full reset of the card */
772         card_full_reset(priv);
773         might_sleep();
774
775         /* Check and set Card Endianness */
776         reg = ioread32(priv->ctl + AGNX_CIR_ENDIAN);
777         /* TODO If not 0xB3B2B1B0 set to 0xB3B2B1B0 */
778         printk(KERN_INFO PFX "CIR_ENDIAN is %x\n", reg);
779
780
781         /* Config the eeprom */
782         agnx_write32(ctl, AGNX_CIR_SERIALITF, 0x7000086);
783         udelay(10);
784         reg = agnx_read32(ctl, AGNX_CIR_SERIALITF);
785
786
787         agnx_write32(ctl, AGNX_PM_SOFTRST, 0x80000033);
788         reg = agnx_read32(ctl, 0xec50);
789         reg |= 0xf;
790         agnx_write32(ctl, 0xec50, reg);
791         agnx_write32(ctl, AGNX_PM_SOFTRST, 0x0);
792
793
794         reg = agnx_read32(ctl, AGNX_SYSITF_GPIOIN);
795         udelay(10);
796         reg = agnx_read32(ctl, AGNX_CIR_SERIALITF);
797
798         /* Dump the eeprom */
799         do {
800                 char eeprom[0x100000/0x100];
801
802                 for (i = 0; i < 0x100000; i += 0x100) {
803                         agnx_write32(ctl, AGNX_CIR_SERIALITF, 0x3000000 + i);
804                         udelay(13);
805                         reg = agnx_read32(ctl, AGNX_CIR_SERIALITF);
806                         udelay(70);
807                         reg = agnx_read32(ctl, AGNX_CIR_SERIALITF);
808                         eeprom[i/0x100] = reg & 0xFF;
809                         udelay(10);
810                 }
811                 print_hex_dump_bytes(PFX "EEPROM: ", DUMP_PREFIX_NONE, eeprom,
812                                      ARRAY_SIZE(eeprom));
813         } while (0);
814
815         spi_rc_write(ctl, RF_CHIP0, 0x26);
816         reg = agnx_read32(ctl, AGNX_SPI_RLSW);
817
818         /* Initialize the system interface */
819         system_itf_init(priv);
820
821         might_sleep();
822         /* Chip Initialization (Polaris) */
823         chip_init(priv);
824         might_sleep();
825
826         /* Calibrate the antennae */
827         antenna_calibrate(priv);
828
829         reg = agnx_read32(ctl, 0xec50);
830         reg &= ~0x40;
831         agnx_write32(ctl, 0xec50, reg);
832         agnx_write32(ctl, AGNX_PM_SOFTRST, 0x0);
833         agnx_write32(ctl, AGNX_PM_PLLCTL, 0x1);
834
835         reg = agnx_read32(ctl, AGNX_BM_BMCTL);
836         reg |= 0x8000;
837         agnx_write32(ctl, AGNX_BM_BMCTL, reg);
838         enable_receiver(priv);
839         reg = agnx_read32(ctl, AGNX_SYSITF_SYSMODE);
840         reg |= 0x200;
841         agnx_write32(ctl, AGNX_SYSITF_SYSMODE, reg);
842         enable_receiver(priv);
843
844         might_sleep();
845         /* Initialize Gain Control Counts */
846         gain_ctlcnt_init(priv);
847
848         /* Write Initial Station Power Template for this station(#0) */
849         sta_power_init(priv, LOCAL_STAID);
850
851         might_sleep();
852         /* Initialize the rx,td,tm rings, for each node in the ring */
853         fill_rings(priv);
854
855         might_sleep();
856
857
858         agnx_write32(ctl, AGNX_PM_SOFTRST, 0x80000033);
859         agnx_write32(ctl, 0xec50, 0xc);
860         agnx_write32(ctl, AGNX_PM_SOFTRST, 0x0);
861
862         /* FIXME Initialize the transmit control register */
863         agnx_write32(ctl, AGNX_TXM_CTL, 0x194c1);
864
865         enable_receiver(priv);
866
867         might_sleep();
868         /* FIXME Set the Receive Control Mac Address to card address */
869         mac_address_set(priv);
870         enable_receiver(priv);
871         might_sleep();
872
873         /* Set the recieve request rate */
874         /* FIXME Enable the request */
875         /* Check packet length */
876         /* Set maximum packet length */
877 /*      agnx_write32(ctl, AGNX_RXM_REQRATE, 0x88195e00); */
878 /*      enable_receiver(priv); */
879
880         /* Set the Receiver BSSID */
881         receiver_bssid_set(priv, bssid);
882
883         /* FIXME Set to managed mode */
884         set_managed_mode(priv);
885 /*      set_promiscuous_mode(priv); */
886 /*      set_scan_mode(priv); */
887 /*      set_learn_mode(priv); */
888 /*      set_promis_and_managed(priv); */
889 /*      set_adhoc_mode(priv); */
890
891         /* Set the recieve request rate */
892         /* Check packet length */
893         agnx_write32(ctl, AGNX_RXM_REQRATE, 0x08000000);
894         reg = agnx_read32(ctl, AGNX_RXM_REQRATE);
895         /* Set maximum packet length */
896         reg |= 0x00195e00;
897         agnx_write32(ctl, AGNX_RXM_REQRATE, reg);
898
899         /* Configure the RX and TX interrupt */
900         reg = ENABLE_RX_INTERRUPT | RX_CACHE_LINE | FRAG_LEN_2048 | FRAG_BE;
901         agnx_write32(ctl, AGNX_CIR_RXCFG, reg);
902         /* FIXME */
903         reg = ENABLE_TX_INTERRUPT | TX_CACHE_LINE | FRAG_LEN_2048 | FRAG_BE;
904         agnx_write32(ctl, AGNX_CIR_TXCFG, reg);
905
906         /* Enable RX TX Interrupts */
907         agnx_write32(ctl, AGNX_CIR_RXCTL, 0x80);
908         agnx_write32(ctl, AGNX_CIR_TXMCTL, 0x80);
909         agnx_write32(ctl, AGNX_CIR_TXDCTL, 0x80);
910
911         /* FIXME Set the master control interrupt in block control */
912         agnx_write32(ctl, AGNX_CIR_BLKCTL, 0x800);
913
914         /* Enable RX and TX queues */
915         reg = agnx_read32(ctl, AGNX_CIR_RXCTL);
916         reg |= 0x8;
917         agnx_write32(ctl, AGNX_CIR_RXCTL, reg);
918         reg = agnx_read32(ctl, AGNX_CIR_TXMCTL);
919         reg |= 0x8;
920         agnx_write32(ctl, AGNX_CIR_TXMCTL, reg);
921         reg = agnx_read32(ctl, AGNX_CIR_TXDCTL);
922         reg |= 0x8;
923         agnx_write32(ctl, AGNX_CIR_TXDCTL, reg);
924
925         agnx_write32(ctl, AGNX_SYSITF_GPIOUT, 0x5);
926         /* FIXME */
927         /*  unknow_register_write(priv); */
928         /* Update local card hash entry */
929         hash_write(priv, priv->mac_addr, LOCAL_STAID);
930
931         might_sleep();
932
933         /* FIXME */
934         agnx_set_channel(priv, 1);
935         might_sleep();
936 } /* agnx_card_interface_init */
937
938
939 void agnx_hw_init(struct agnx_priv *priv)
940 {
941         AGNX_TRACE;
942         might_sleep();
943         card_interface_init(priv);
944 }
945
946 int agnx_hw_reset(struct agnx_priv *priv)
947 {
948         return card_full_reset(priv);
949 }
950
951 int agnx_set_ssid(struct agnx_priv *priv, u8 *ssid, size_t ssid_len)
952 {
953         AGNX_TRACE;
954         return 0;
955 }
956
957 void agnx_set_bssid(struct agnx_priv *priv, const u8 *bssid)
958 {
959         receiver_bssid_set(priv, bssid);
960 }