2 * Airgo MIMO wireless driver
4 * Copyright (c) 2007 Li YanBo <dreamfly281@gmail.com>
6 * Thanks for Jeff Williams <angelbane@gmail.com> do reverse engineer
7 * works and published the SPECS at http://airgo.wdwconsulting.net/mymoin
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.
14 #include <linux/init.h>
15 #include <linux/etherdevice.h>
16 #include <linux/pci.h>
17 #include <linux/delay.h>
25 u8 read_from_eeprom(struct agnx_priv *priv, u16 address)
27 void __iomem *ctl = priv->ctl;
28 struct agnx_eeprom cmd;
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 */
40 reg = ioread32(ctl + AGNX_CIR_SERIALITF);
42 cmd = *(struct agnx_eeprom *)®
47 static int card_full_reset(struct agnx_priv *priv)
49 void __iomem *ctl = priv->ctl;
53 reg = agnx_read32(ctl, AGNX_CIR_BLKCTL);
54 agnx_write32(ctl, AGNX_CIR_BLKCTL, 0x80);
55 reg = agnx_read32(ctl, AGNX_CIR_BLKCTL);
59 inline void enable_power_saving(struct agnx_priv *priv)
61 void __iomem *ctl = priv->ctl;
64 reg = agnx_read32(ctl, AGNX_PM_PMCTL);
66 agnx_write32(ctl, AGNX_PM_PMCTL, reg);
69 inline void disable_power_saving(struct agnx_priv *priv)
71 void __iomem *ctl = priv->ctl;
74 reg = agnx_read32(ctl, AGNX_PM_PMCTL);
76 agnx_write32(ctl, AGNX_PM_PMCTL, reg);
80 void disable_receiver(struct agnx_priv *priv)
82 void __iomem *ctl = priv->ctl;
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);
94 /* Fixme this shoule be disable RX, above is enable RX */
95 void enable_receiver(struct agnx_priv *priv)
97 void __iomem *ctl = priv->ctl;
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);
108 static void mac_address_set(struct agnx_priv *priv)
110 void __iomem *ctl = priv->ctl;
111 u8 *mac_addr = priv->mac_addr;
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);
121 static void receiver_bssid_set(struct agnx_priv *priv, u8 *bssid)
123 void __iomem *ctl = priv->ctl;
126 disable_receiver(priv);
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);
133 /* Enable the receiver */
134 enable_receiver(priv);
137 /* agnx_write32(ctl, AGNX_TXM_TSFLO, 0x0); */
138 /* agnx_write32(ctl, AGNX_TXM_TSFHI, 0x0); */
140 agnx_write32(ctl, AGNX_TXM_TBTTLO, 0x0);
141 agnx_write32(ctl, AGNX_TXM_TBTTHI, 0x0);
142 disable_receiver(priv);
143 } /* receiver_bssid_set */
145 static void band_management_init(struct agnx_priv *priv)
147 void __iomem *ctl = priv->ctl;
148 void __iomem *data = priv->data;
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);
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);
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),
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);
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);
192 /* Enable the Band Management */
193 reg = agnx_read32(ctl, AGNX_BM_BMCTL);
195 agnx_write32(ctl, AGNX_BM_BMCTL, reg);
196 } /* band_managment_init */
199 static void system_itf_init(struct agnx_priv *priv)
201 void __iomem *ctl = priv->ctl;
205 agnx_write32(ctl, AGNX_SYSITF_GPIOUT, 0x0);
206 agnx_write32(ctl, AGNX_PM_TESTPHY, 0x11e143a);
208 if (priv->revid == 0) {
209 reg = agnx_read32(ctl, AGNX_SYSITF_SYSMODE);
211 agnx_write32(ctl, AGNX_SYSITF_SYSMODE, reg);
213 /* ??? What is that means? it should difference for differice type
215 agnx_write32(ctl, AGNX_CIR_SERIALITF, 0xfff81006);
217 agnx_write32(ctl, AGNX_SYSITF_GPIOIN, 0x1f0000);
218 agnx_write32(ctl, AGNX_SYSITF_GPIOUT, 0x5);
219 reg = agnx_read32(ctl, AGNX_SYSITF_GPIOIN);
222 static void encryption_init(struct agnx_priv *priv)
224 void __iomem *ctl = priv->ctl;
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);
234 static void tx_management_init(struct agnx_priv *priv)
236 void __iomem *ctl = priv->ctl;
237 void __iomem *data = priv->data;
241 /* Fill out the ComputationalEngineLookupTable
242 * starting at memory #2 offset 0x800
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);
251 if (priv->revid >= 2)
252 agnx_write32(ctl, AGNX_TXM_SIFSPIFS, 0x1e140a0b);
254 agnx_write32(ctl, AGNX_TXM_SIFSPIFS, 0x1e190a0b);
256 reg = agnx_read32(ctl, AGNX_TXM_TIFSEIFS);
259 agnx_write32(ctl, AGNX_TXM_TIFSEIFS, reg);
260 reg = agnx_read32(ctl, AGNX_TXM_TIFSEIFS);
263 agnx_write32(ctl, AGNX_TXM_TIFSEIFS, reg);
265 agnx_write32(ctl, AGNX_TXM_CTL, 0x40000);
267 reg = agnx_read32(ctl, AGNX_TXM_TIFSEIFS);
270 agnx_write32(ctl, AGNX_TXM_TIFSEIFS, reg);
271 reg = agnx_read32(ctl, AGNX_TXM_PROBDELAY);
273 agnx_write32(ctl, AGNX_TXM_PROBDELAY, reg);
274 reg = agnx_read32(ctl, AGNX_TXM_TIFSEIFS);
277 agnx_write32(ctl, AGNX_TXM_TIFSEIFS, reg);
278 reg = agnx_read32(ctl, AGNX_TXM_PROBDELAY);
281 agnx_write32(ctl, AGNX_TXM_PROBDELAY, reg);
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);
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);
295 agnx_write32(ctl, AGNX_TXM_MAXRXTIME, reg);
297 /* CF poll RX Timeout count */
298 reg = agnx_read32(ctl, AGNX_TXM_CFPOLLRXTIM);
301 agnx_write32(ctl, AGNX_TXM_CFPOLLRXTIM, reg);
303 /* Max Timeout Exceeded count, */
304 reg = agnx_read32(ctl, AGNX_TXM_MAXTIMOUT);
307 agnx_write32(ctl, AGNX_TXM_MAXTIMOUT, reg);
309 /* CF ack timeout limit for 11b */
310 reg = agnx_read32(ctl, AGNX_TXM_CFACKT11B);
313 agnx_write32(ctl, AGNX_TXM_CFACKT11B, reg);
315 /* Max CF Poll Timeout Count */
316 reg = agnx_read32(ctl, AGNX_TXM_CFPOLLRXTIM);
319 agnx_write32(ctl, AGNX_TXM_CFPOLLRXTIM, reg);
320 /* CF Poll RX Timeout Count */
321 reg = agnx_read32(ctl, AGNX_TXM_CFPOLLRXTIM);
324 agnx_write32(ctl, AGNX_TXM_CFPOLLRXTIM, reg);
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);
332 agnx_write32(ctl, AGNX_TXM_CFPMDV, 0x10000);
335 reg = agnx_read32(ctl, AGNX_TXM_PROBDELAY);
338 agnx_write32(ctl, AGNX_TXM_PROBDELAY, reg);
340 /* Max CCA count Slot */
341 reg = agnx_read32(ctl, AGNX_TXM_MAXCCACNTSLOT);
344 agnx_write32(ctl, AGNX_TXM_MAXCCACNTSLOT, reg);
346 /* Slot limit/1 msec Limit */
347 reg = agnx_read32(ctl, AGNX_TXM_SLOTLIMIT);
350 agnx_write32(ctl, AGNX_TXM_SLOTLIMIT, reg);
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);
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);
372 reg = agnx_read32(ctl, AGNX_TXM_CTL);
374 agnx_write32(ctl, AGNX_TXM_CTL, reg);
375 /* Wait for bit 0 in Control Reg to clear */
377 reg = agnx_read32(ctl, AGNX_TXM_CTL);
378 /* Or 0x18000 to Control reg */
379 reg = agnx_read32(ctl, AGNX_TXM_CTL);
381 agnx_write32(ctl, AGNX_TXM_CTL, reg);
382 /* Wait for bit 0 in Control Reg to clear */
384 reg = agnx_read32(ctl, AGNX_TXM_CTL);
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 */
392 static void rx_management_init(struct agnx_priv *priv)
394 void __iomem *ctl = priv->ctl;
397 /* Initialize the Routing Table */
398 routing_table_init(priv);
400 if (priv->revid >= 3) {
401 agnx_write32(ctl, 0x2074, 0x1f171710);
402 agnx_write32(ctl, 0x2078, 0x10100d0d);
403 agnx_write32(ctl, 0x207c, 0x11111010);
406 agnx_write32(ctl, AGNX_RXM_DELAY11, 0x0);
407 agnx_write32(ctl, AGNX_RXM_REQRATE, 0x8195e00);
411 static void agnx_timer_init(struct agnx_priv *priv)
413 void __iomem *ctl = priv->ctl;
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); */
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);
426 iowrite32(0xFFFFFFFF, priv->ctl + AGNX_TXM_BEACON_CTL);
429 static void power_manage_init(struct agnx_priv *priv)
431 void __iomem *ctl = priv->ctl;
435 agnx_write32(ctl, AGNX_PM_MACMSW, 0x1f);
436 agnx_write32(ctl, AGNX_PM_RFCTL, 0x1f);
438 reg = agnx_read32(ctl, AGNX_PM_PMCTL);
441 agnx_write32(ctl, AGNX_PM_PMCTL, reg);
443 if (priv->revid >= 3) {
444 reg = agnx_read32(ctl, AGNX_PM_SOFTRST);
446 agnx_write32(ctl, AGNX_PM_SOFTRST, reg);
448 } /* power_manage_init */
451 static void gain_ctlcnt_init(struct agnx_priv *priv)
453 void __iomem *ctl = priv->ctl;
457 agnx_write32(ctl, AGNX_GCR_TRACNT5, 0x119);
458 agnx_write32(ctl, AGNX_GCR_TRACNT6, 0x118);
459 agnx_write32(ctl, AGNX_GCR_TRACNT7, 0x117);
461 reg = agnx_read32(ctl, AGNX_PM_PMCTL);
463 agnx_write32(ctl, AGNX_PM_PMCTL, reg);
465 reg = agnx_read32(ctl, AGNX_PM_PMCTL);
467 agnx_write32(ctl, AGNX_PM_PMCTL, reg);
469 agnx_write32(ctl, AGNX_CIR_ADDRWIN, 0x0);
471 /* FIXME Write the initial Station Descriptor for the card */
472 sta_init(priv, LOCAL_STAID);
473 sta_init(priv, BSSID_STAID);
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 */
483 static void phy_init(struct agnx_priv *priv)
485 void __iomem *ctl = priv->ctl;
486 void __iomem *data = priv->data;
490 /* Load InitialGainTable */
491 gain_table_init(priv);
493 agnx_write32(ctl, AGNX_CIR_ADDRWIN, 0x2000000);
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);
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
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);
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);
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);
631 agnx_write32(ctl, 0xec18, reg);
634 /* Write the TX Fir Coefficient Table */
635 tx_fir_table_init(priv);
637 reg = agnx_read32(ctl, AGNX_PM_PMCTL);
639 agnx_write32(ctl, AGNX_PM_PMCTL, reg);
640 reg = agnx_read32(ctl, AGNX_PM_PLLCTL);
642 agnx_write32(ctl, AGNX_PM_PLLCTL, reg);
644 /* reg = agnx_read32(ctl, 0x1a030); */
646 /* agnx_write32(ctl, 0x1a030, reg); */
648 agnx_write32(ctl, AGNX_GCR_TRACNT4, 0x113);
651 static void chip_init(struct agnx_priv *priv)
653 void __iomem *ctl = priv->ctl;
657 band_management_init(priv);
661 reg = agnx_read32(ctl, AGNX_PM_PMCTL);
663 agnx_write32(ctl, AGNX_PM_PMCTL, reg);
665 /* Initialize the PHY */
668 encryption_init(priv);
670 tx_management_init(priv);
672 rx_management_init(priv);
674 power_manage_init(priv);
676 /* Initialize the Timers */
677 agnx_timer_init(priv);
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);
684 reg = agnx_read32(ctl, AGNX_CIR_BLKCTL);
686 agnx_write32(ctl, AGNX_CIR_BLKCTL, reg);
688 /* set it when need get multicast enable? */
689 agnx_write32(ctl, AGNX_BM_MTSM, 0xff);
693 static inline void set_promis_and_managed(struct agnx_priv *priv)
695 void __iomem *ctl = priv->ctl;
696 agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x10 | 0x2);
697 agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x10 | 0x2);
699 static inline void set_learn_mode(struct agnx_priv *priv)
701 void __iomem *ctl = priv->ctl;
702 agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x8);
704 static inline void set_scan_mode(struct agnx_priv *priv)
706 void __iomem *ctl = priv->ctl;
707 agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x20);
709 static inline void set_promiscuous_mode(struct agnx_priv *priv)
711 void __iomem *ctl = priv->ctl;
712 /* agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x210);*/
713 agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x10);
715 static inline void set_managed_mode(struct agnx_priv *priv)
717 void __iomem *ctl = priv->ctl;
718 agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x2);
720 static inline void set_adhoc_mode(struct agnx_priv *priv)
722 void __iomem *ctl = priv->ctl;
723 agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x0);
727 static void unknow_register_write(struct agnx_priv *priv)
729 void __iomem *ctl = priv->ctl;
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);
758 static void card_interface_init(struct agnx_priv *priv)
760 void __iomem *ctl = priv->ctl;
761 u8 bssid[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
767 /* Clear RX Control and Enable RX queues */
768 agnx_write32(ctl, AGNX_CIR_RXCTL, 0x8);
771 /* Do a full reset of the card */
772 card_full_reset(priv);
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);
781 /* Config the eeprom */
782 agnx_write32(ctl, AGNX_CIR_SERIALITF, 0x7000086);
784 reg = agnx_read32(ctl, AGNX_CIR_SERIALITF);
787 agnx_write32(ctl, AGNX_PM_SOFTRST, 0x80000033);
788 reg = agnx_read32(ctl, 0xec50);
790 agnx_write32(ctl, 0xec50, reg);
791 agnx_write32(ctl, AGNX_PM_SOFTRST, 0x0);
794 reg = agnx_read32(ctl, AGNX_SYSITF_GPIOIN);
796 reg = agnx_read32(ctl, AGNX_CIR_SERIALITF);
798 /* Dump the eeprom */
800 char eeprom[0x100000/0x100];
802 for (i = 0; i < 0x100000; i += 0x100) {
803 agnx_write32(ctl, AGNX_CIR_SERIALITF, 0x3000000 + i);
805 reg = agnx_read32(ctl, AGNX_CIR_SERIALITF);
807 reg = agnx_read32(ctl, AGNX_CIR_SERIALITF);
808 eeprom[i/0x100] = reg & 0xFF;
811 print_hex_dump_bytes(PFX "EEPROM: ", DUMP_PREFIX_NONE, eeprom,
815 spi_rc_write(ctl, RF_CHIP0, 0x26);
816 reg = agnx_read32(ctl, AGNX_SPI_RLSW);
818 /* Initialize the system interface */
819 system_itf_init(priv);
822 /* Chip Initialization (Polaris) */
826 /* Calibrate the antennae */
827 antenna_calibrate(priv);
829 reg = agnx_read32(ctl, 0xec50);
831 agnx_write32(ctl, 0xec50, reg);
832 agnx_write32(ctl, AGNX_PM_SOFTRST, 0x0);
833 agnx_write32(ctl, AGNX_PM_PLLCTL, 0x1);
835 reg = agnx_read32(ctl, AGNX_BM_BMCTL);
837 agnx_write32(ctl, AGNX_BM_BMCTL, reg);
838 enable_receiver(priv);
839 reg = agnx_read32(ctl, AGNX_SYSITF_SYSMODE);
841 agnx_write32(ctl, AGNX_SYSITF_SYSMODE, reg);
842 enable_receiver(priv);
845 /* Initialize Gain Control Counts */
846 gain_ctlcnt_init(priv);
848 /* Write Initial Station Power Template for this station(#0) */
849 sta_power_init(priv, LOCAL_STAID);
852 /* Initialize the rx,td,tm rings, for each node in the ring */
858 agnx_write32(ctl, AGNX_PM_SOFTRST, 0x80000033);
859 agnx_write32(ctl, 0xec50, 0xc);
860 agnx_write32(ctl, AGNX_PM_SOFTRST, 0x0);
862 /* FIXME Initialize the transmit control register */
863 agnx_write32(ctl, AGNX_TXM_CTL, 0x194c1);
865 enable_receiver(priv);
868 /* FIXME Set the Receive Control Mac Address to card address */
869 mac_address_set(priv);
870 enable_receiver(priv);
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); */
880 /* Set the Receiver BSSID */
881 receiver_bssid_set(priv, bssid);
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);
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 */
897 agnx_write32(ctl, AGNX_RXM_REQRATE, reg);
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);
903 reg = ENABLE_TX_INTERRUPT | TX_CACHE_LINE | FRAG_LEN_2048 | FRAG_BE;
904 agnx_write32(ctl, AGNX_CIR_TXCFG, reg);
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);
911 /* FIXME Set the master control interrupt in block control */
912 agnx_write32(ctl, AGNX_CIR_BLKCTL, 0x800);
914 /* Enable RX and TX queues */
915 reg = agnx_read32(ctl, AGNX_CIR_RXCTL);
917 agnx_write32(ctl, AGNX_CIR_RXCTL, reg);
918 reg = agnx_read32(ctl, AGNX_CIR_TXMCTL);
920 agnx_write32(ctl, AGNX_CIR_TXMCTL, reg);
921 reg = agnx_read32(ctl, AGNX_CIR_TXDCTL);
923 agnx_write32(ctl, AGNX_CIR_TXDCTL, reg);
925 agnx_write32(ctl, AGNX_SYSITF_GPIOUT, 0x5);
927 /* unknow_register_write(priv); */
928 /* Update local card hash entry */
929 hash_write(priv, priv->mac_addr, LOCAL_STAID);
934 agnx_set_channel(priv, 1);
936 } /* agnx_card_interface_init */
939 void agnx_hw_init(struct agnx_priv *priv)
943 card_interface_init(priv);
946 int agnx_hw_reset(struct agnx_priv *priv)
948 return card_full_reset(priv);
951 int agnx_set_ssid(struct agnx_priv *priv, u8 *ssid, size_t ssid_len)
957 void agnx_set_bssid(struct agnx_priv *priv, u8 *bssid)
959 receiver_bssid_set(priv, bssid);