[PATCH] bcm43xx-softmac: Init, shutdown and restart fixes
[safe/jmp/linux-2.6] / drivers / net / wireless / bcm43xx / bcm43xx_main.c
1 /*
2
3   Broadcom BCM43xx wireless driver
4
5   Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
6                      Stefano Brivio <st3@riseup.net>
7                      Michael Buesch <mbuesch@freenet.de>
8                      Danny van Dyk <kugelfang@gentoo.org>
9                      Andreas Jaggi <andreas.jaggi@waterwave.ch>
10
11   Some parts of the code in this file are derived from the ipw2200
12   driver  Copyright(c) 2003 - 2004 Intel Corporation.
13
14   This program is free software; you can redistribute it and/or modify
15   it under the terms of the GNU General Public License as published by
16   the Free Software Foundation; either version 2 of the License, or
17   (at your option) any later version.
18
19   This program is distributed in the hope that it will be useful,
20   but WITHOUT ANY WARRANTY; without even the implied warranty of
21   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22   GNU General Public License for more details.
23
24   You should have received a copy of the GNU General Public License
25   along with this program; see the file COPYING.  If not, write to
26   the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
27   Boston, MA 02110-1301, USA.
28
29 */
30
31 #include <linux/delay.h>
32 #include <linux/init.h>
33 #include <linux/moduleparam.h>
34 #include <linux/if_arp.h>
35 #include <linux/etherdevice.h>
36 #include <linux/version.h>
37 #include <linux/firmware.h>
38 #include <linux/wireless.h>
39 #include <linux/workqueue.h>
40 #include <linux/skbuff.h>
41 #include <linux/dma-mapping.h>
42 #include <net/iw_handler.h>
43
44 #include "bcm43xx.h"
45 #include "bcm43xx_main.h"
46 #include "bcm43xx_debugfs.h"
47 #include "bcm43xx_radio.h"
48 #include "bcm43xx_phy.h"
49 #include "bcm43xx_dma.h"
50 #include "bcm43xx_pio.h"
51 #include "bcm43xx_power.h"
52 #include "bcm43xx_wx.h"
53 #include "bcm43xx_ethtool.h"
54 #include "bcm43xx_xmit.h"
55 #include "bcm43xx_sysfs.h"
56
57
58 MODULE_DESCRIPTION("Broadcom BCM43xx wireless driver");
59 MODULE_AUTHOR("Martin Langer");
60 MODULE_AUTHOR("Stefano Brivio");
61 MODULE_AUTHOR("Michael Buesch");
62 MODULE_LICENSE("GPL");
63
64 #ifdef CONFIG_BCM947XX
65 extern char *nvram_get(char *name);
66 #endif
67
68 #if defined(CONFIG_BCM43XX_DMA) && defined(CONFIG_BCM43XX_PIO)
69 static int modparam_pio;
70 module_param_named(pio, modparam_pio, int, 0444);
71 MODULE_PARM_DESC(pio, "enable(1) / disable(0) PIO mode");
72 #elif defined(CONFIG_BCM43XX_DMA)
73 # define modparam_pio   0
74 #elif defined(CONFIG_BCM43XX_PIO)
75 # define modparam_pio   1
76 #endif
77
78 static int modparam_bad_frames_preempt;
79 module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
80 MODULE_PARM_DESC(bad_frames_preempt, "enable(1) / disable(0) Bad Frames Preemption");
81
82 static int modparam_short_retry = BCM43xx_DEFAULT_SHORT_RETRY_LIMIT;
83 module_param_named(short_retry, modparam_short_retry, int, 0444);
84 MODULE_PARM_DESC(short_retry, "Short-Retry-Limit (0 - 15)");
85
86 static int modparam_long_retry = BCM43xx_DEFAULT_LONG_RETRY_LIMIT;
87 module_param_named(long_retry, modparam_long_retry, int, 0444);
88 MODULE_PARM_DESC(long_retry, "Long-Retry-Limit (0 - 15)");
89
90 static int modparam_locale = -1;
91 module_param_named(locale, modparam_locale, int, 0444);
92 MODULE_PARM_DESC(country, "Select LocaleCode 0-11 (For travelers)");
93
94 static int modparam_noleds;
95 module_param_named(noleds, modparam_noleds, int, 0444);
96 MODULE_PARM_DESC(noleds, "Turn off all LED activity");
97
98 #ifdef CONFIG_BCM43XX_DEBUG
99 static char modparam_fwpostfix[64];
100 module_param_string(fwpostfix, modparam_fwpostfix, 64, 0444);
101 MODULE_PARM_DESC(fwpostfix, "Postfix for .fw files. Useful for debugging.");
102 #else
103 # define modparam_fwpostfix  ""
104 #endif /* CONFIG_BCM43XX_DEBUG*/
105
106
107 /* If you want to debug with just a single device, enable this,
108  * where the string is the pci device ID (as given by the kernel's
109  * pci_name function) of the device to be used.
110  */
111 //#define DEBUG_SINGLE_DEVICE_ONLY      "0001:11:00.0"
112
113 /* If you want to enable printing of each MMIO access, enable this. */
114 //#define DEBUG_ENABLE_MMIO_PRINT
115
116 /* If you want to enable printing of MMIO access within
117  * ucode/pcm upload, initvals write, enable this.
118  */
119 //#define DEBUG_ENABLE_UCODE_MMIO_PRINT
120
121 /* If you want to enable printing of PCI Config Space access, enable this */
122 //#define DEBUG_ENABLE_PCILOG
123
124
125 /* Detailed list maintained at:
126  * http://openfacts.berlios.de/index-en.phtml?title=Bcm43xxDevices
127  */
128         static struct pci_device_id bcm43xx_pci_tbl[] = {
129         /* Broadcom 4303 802.11b */
130         { PCI_VENDOR_ID_BROADCOM, 0x4301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
131         /* Broadcom 4307 802.11b */
132         { PCI_VENDOR_ID_BROADCOM, 0x4307, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
133         /* Broadcom 4318 802.11b/g */
134         { PCI_VENDOR_ID_BROADCOM, 0x4318, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
135         /* Broadcom 4319 802.11a/b/g */
136         { PCI_VENDOR_ID_BROADCOM, 0x4319, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
137         /* Broadcom 4306 802.11b/g */
138         { PCI_VENDOR_ID_BROADCOM, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
139         /* Broadcom 4306 802.11a */
140 //      { PCI_VENDOR_ID_BROADCOM, 0x4321, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
141         /* Broadcom 4309 802.11a/b/g */
142         { PCI_VENDOR_ID_BROADCOM, 0x4324, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
143         /* Broadcom 43XG 802.11b/g */
144         { PCI_VENDOR_ID_BROADCOM, 0x4325, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
145 #ifdef CONFIG_BCM947XX
146         /* SB bus on BCM947xx */
147         { PCI_VENDOR_ID_BROADCOM, 0x0800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
148 #endif
149         { 0 },
150 };
151 MODULE_DEVICE_TABLE(pci, bcm43xx_pci_tbl);
152
153 static void bcm43xx_ram_write(struct bcm43xx_private *bcm, u16 offset, u32 val)
154 {
155         u32 status;
156
157         status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
158         if (!(status & BCM43xx_SBF_XFER_REG_BYTESWAP))
159                 val = swab32(val);
160
161         bcm43xx_write32(bcm, BCM43xx_MMIO_RAM_CONTROL, offset);
162         mmiowb();
163         bcm43xx_write32(bcm, BCM43xx_MMIO_RAM_DATA, val);
164 }
165
166 static inline
167 void bcm43xx_shm_control_word(struct bcm43xx_private *bcm,
168                               u16 routing, u16 offset)
169 {
170         u32 control;
171
172         /* "offset" is the WORD offset. */
173
174         control = routing;
175         control <<= 16;
176         control |= offset;
177         bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_CONTROL, control);
178 }
179
180 u32 bcm43xx_shm_read32(struct bcm43xx_private *bcm,
181                        u16 routing, u16 offset)
182 {
183         u32 ret;
184
185         if (routing == BCM43xx_SHM_SHARED) {
186                 if (offset & 0x0003) {
187                         /* Unaligned access */
188                         bcm43xx_shm_control_word(bcm, routing, offset >> 2);
189                         ret = bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED);
190                         ret <<= 16;
191                         bcm43xx_shm_control_word(bcm, routing, (offset >> 2) + 1);
192                         ret |= bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA);
193
194                         return ret;
195                 }
196                 offset >>= 2;
197         }
198         bcm43xx_shm_control_word(bcm, routing, offset);
199         ret = bcm43xx_read32(bcm, BCM43xx_MMIO_SHM_DATA);
200
201         return ret;
202 }
203
204 u16 bcm43xx_shm_read16(struct bcm43xx_private *bcm,
205                        u16 routing, u16 offset)
206 {
207         u16 ret;
208
209         if (routing == BCM43xx_SHM_SHARED) {
210                 if (offset & 0x0003) {
211                         /* Unaligned access */
212                         bcm43xx_shm_control_word(bcm, routing, offset >> 2);
213                         ret = bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED);
214
215                         return ret;
216                 }
217                 offset >>= 2;
218         }
219         bcm43xx_shm_control_word(bcm, routing, offset);
220         ret = bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA);
221
222         return ret;
223 }
224
225 void bcm43xx_shm_write32(struct bcm43xx_private *bcm,
226                          u16 routing, u16 offset,
227                          u32 value)
228 {
229         if (routing == BCM43xx_SHM_SHARED) {
230                 if (offset & 0x0003) {
231                         /* Unaligned access */
232                         bcm43xx_shm_control_word(bcm, routing, offset >> 2);
233                         mmiowb();
234                         bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED,
235                                         (value >> 16) & 0xffff);
236                         mmiowb();
237                         bcm43xx_shm_control_word(bcm, routing, (offset >> 2) + 1);
238                         mmiowb();
239                         bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA,
240                                         value & 0xffff);
241                         return;
242                 }
243                 offset >>= 2;
244         }
245         bcm43xx_shm_control_word(bcm, routing, offset);
246         mmiowb();
247         bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, value);
248 }
249
250 void bcm43xx_shm_write16(struct bcm43xx_private *bcm,
251                          u16 routing, u16 offset,
252                          u16 value)
253 {
254         if (routing == BCM43xx_SHM_SHARED) {
255                 if (offset & 0x0003) {
256                         /* Unaligned access */
257                         bcm43xx_shm_control_word(bcm, routing, offset >> 2);
258                         mmiowb();
259                         bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED,
260                                         value);
261                         return;
262                 }
263                 offset >>= 2;
264         }
265         bcm43xx_shm_control_word(bcm, routing, offset);
266         mmiowb();
267         bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA, value);
268 }
269
270 void bcm43xx_tsf_read(struct bcm43xx_private *bcm, u64 *tsf)
271 {
272         /* We need to be careful. As we read the TSF from multiple
273          * registers, we should take care of register overflows.
274          * In theory, the whole tsf read process should be atomic.
275          * We try to be atomic here, by restaring the read process,
276          * if any of the high registers changed (overflew).
277          */
278         if (bcm->current_core->rev >= 3) {
279                 u32 low, high, high2;
280
281                 do {
282                         high = bcm43xx_read32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_HIGH);
283                         low = bcm43xx_read32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW);
284                         high2 = bcm43xx_read32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_HIGH);
285                 } while (unlikely(high != high2));
286
287                 *tsf = high;
288                 *tsf <<= 32;
289                 *tsf |= low;
290         } else {
291                 u64 tmp;
292                 u16 v0, v1, v2, v3;
293                 u16 test1, test2, test3;
294
295                 do {
296                         v3 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_3);
297                         v2 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_2);
298                         v1 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_1);
299                         v0 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_0);
300
301                         test3 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_3);
302                         test2 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_2);
303                         test1 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_1);
304                 } while (v3 != test3 || v2 != test2 || v1 != test1);
305
306                 *tsf = v3;
307                 *tsf <<= 48;
308                 tmp = v2;
309                 tmp <<= 32;
310                 *tsf |= tmp;
311                 tmp = v1;
312                 tmp <<= 16;
313                 *tsf |= tmp;
314                 *tsf |= v0;
315         }
316 }
317
318 void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf)
319 {
320         u32 status;
321
322         status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
323         status |= BCM43xx_SBF_TIME_UPDATE;
324         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
325         mmiowb();
326
327         /* Be careful with the in-progress timer.
328          * First zero out the low register, so we have a full
329          * register-overflow duration to complete the operation.
330          */
331         if (bcm->current_core->rev >= 3) {
332                 u32 lo = (tsf & 0x00000000FFFFFFFFULL);
333                 u32 hi = (tsf & 0xFFFFFFFF00000000ULL) >> 32;
334
335                 bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW, 0);
336                 mmiowb();
337                 bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_HIGH, hi);
338                 mmiowb();
339                 bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW, lo);
340         } else {
341                 u16 v0 = (tsf & 0x000000000000FFFFULL);
342                 u16 v1 = (tsf & 0x00000000FFFF0000ULL) >> 16;
343                 u16 v2 = (tsf & 0x0000FFFF00000000ULL) >> 32;
344                 u16 v3 = (tsf & 0xFFFF000000000000ULL) >> 48;
345
346                 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_0, 0);
347                 mmiowb();
348                 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_3, v3);
349                 mmiowb();
350                 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_2, v2);
351                 mmiowb();
352                 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_1, v1);
353                 mmiowb();
354                 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_0, v0);
355         }
356
357         status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
358         status &= ~BCM43xx_SBF_TIME_UPDATE;
359         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
360 }
361
362 static
363 void bcm43xx_macfilter_set(struct bcm43xx_private *bcm,
364                            u16 offset,
365                            const u8 *mac)
366 {
367         u16 data;
368
369         offset |= 0x0020;
370         bcm43xx_write16(bcm, BCM43xx_MMIO_MACFILTER_CONTROL, offset);
371
372         data = mac[0];
373         data |= mac[1] << 8;
374         bcm43xx_write16(bcm, BCM43xx_MMIO_MACFILTER_DATA, data);
375         data = mac[2];
376         data |= mac[3] << 8;
377         bcm43xx_write16(bcm, BCM43xx_MMIO_MACFILTER_DATA, data);
378         data = mac[4];
379         data |= mac[5] << 8;
380         bcm43xx_write16(bcm, BCM43xx_MMIO_MACFILTER_DATA, data);
381 }
382
383 static void bcm43xx_macfilter_clear(struct bcm43xx_private *bcm,
384                                     u16 offset)
385 {
386         const u8 zero_addr[ETH_ALEN] = { 0 };
387
388         bcm43xx_macfilter_set(bcm, offset, zero_addr);
389 }
390
391 static void bcm43xx_write_mac_bssid_templates(struct bcm43xx_private *bcm)
392 {
393         const u8 *mac = (const u8 *)(bcm->net_dev->dev_addr);
394         const u8 *bssid = (const u8 *)(bcm->ieee->bssid);
395         u8 mac_bssid[ETH_ALEN * 2];
396         int i;
397
398         memcpy(mac_bssid, mac, ETH_ALEN);
399         memcpy(mac_bssid + ETH_ALEN, bssid, ETH_ALEN);
400
401         /* Write our MAC address and BSSID to template ram */
402         for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32))
403                 bcm43xx_ram_write(bcm, 0x20 + i, *((u32 *)(mac_bssid + i)));
404         for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32))
405                 bcm43xx_ram_write(bcm, 0x78 + i, *((u32 *)(mac_bssid + i)));
406         for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32))
407                 bcm43xx_ram_write(bcm, 0x478 + i, *((u32 *)(mac_bssid + i)));
408 }
409
410 //FIXME: Well, we should probably call them from somewhere.
411 #if 0
412 static void bcm43xx_set_slot_time(struct bcm43xx_private *bcm, u16 slot_time)
413 {
414         /* slot_time is in usec. */
415         if (bcm43xx_current_phy(bcm)->type != BCM43xx_PHYTYPE_G)
416                 return;
417         bcm43xx_write16(bcm, 0x684, 510 + slot_time);
418         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0010, slot_time);
419 }
420
421 static void bcm43xx_short_slot_timing_enable(struct bcm43xx_private *bcm)
422 {
423         bcm43xx_set_slot_time(bcm, 9);
424 }
425
426 static void bcm43xx_short_slot_timing_disable(struct bcm43xx_private *bcm)
427 {
428         bcm43xx_set_slot_time(bcm, 20);
429 }
430 #endif
431
432 /* FIXME: To get the MAC-filter working, we need to implement the
433  *        following functions (and rename them :)
434  */
435 #if 0
436 static void bcm43xx_disassociate(struct bcm43xx_private *bcm)
437 {
438         bcm43xx_mac_suspend(bcm);
439         bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC);
440
441         bcm43xx_ram_write(bcm, 0x0026, 0x0000);
442         bcm43xx_ram_write(bcm, 0x0028, 0x0000);
443         bcm43xx_ram_write(bcm, 0x007E, 0x0000);
444         bcm43xx_ram_write(bcm, 0x0080, 0x0000);
445         bcm43xx_ram_write(bcm, 0x047E, 0x0000);
446         bcm43xx_ram_write(bcm, 0x0480, 0x0000);
447
448         if (bcm->current_core->rev < 3) {
449                 bcm43xx_write16(bcm, 0x0610, 0x8000);
450                 bcm43xx_write16(bcm, 0x060E, 0x0000);
451         } else
452                 bcm43xx_write32(bcm, 0x0188, 0x80000000);
453
454         bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0004, 0x000003ff);
455
456         if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_G &&
457             ieee80211_is_ofdm_rate(bcm->softmac->txrates.default_rate))
458                 bcm43xx_short_slot_timing_enable(bcm);
459
460         bcm43xx_mac_enable(bcm);
461 }
462
463 static void bcm43xx_associate(struct bcm43xx_private *bcm,
464                               const u8 *mac)
465 {
466         memcpy(bcm->ieee->bssid, mac, ETH_ALEN);
467
468         bcm43xx_mac_suspend(bcm);
469         bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_ASSOC, mac);
470         bcm43xx_write_mac_bssid_templates(bcm);
471         bcm43xx_mac_enable(bcm);
472 }
473 #endif
474
475 /* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable.
476  * Returns the _previously_ enabled IRQ mask.
477  */
478 static inline u32 bcm43xx_interrupt_enable(struct bcm43xx_private *bcm, u32 mask)
479 {
480         u32 old_mask;
481
482         old_mask = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK);
483         bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK, old_mask | mask);
484
485         return old_mask;
486 }
487
488 /* Disable a Generic IRQ. "mask" is the mask of which IRQs to disable.
489  * Returns the _previously_ enabled IRQ mask.
490  */
491 static inline u32 bcm43xx_interrupt_disable(struct bcm43xx_private *bcm, u32 mask)
492 {
493         u32 old_mask;
494
495         old_mask = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK);
496         bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK, old_mask & ~mask);
497
498         return old_mask;
499 }
500
501 /* Synchronize IRQ top- and bottom-half.
502  * IRQs must be masked before calling this.
503  * This must not be called with the irq_lock held.
504  */
505 static void bcm43xx_synchronize_irq(struct bcm43xx_private *bcm)
506 {
507         synchronize_irq(bcm->irq);
508         tasklet_disable(&bcm->isr_tasklet);
509 }
510
511 /* Make sure we don't receive more data from the device. */
512 static int bcm43xx_disable_interrupts_sync(struct bcm43xx_private *bcm)
513 {
514         unsigned long flags;
515
516         spin_lock_irqsave(&bcm->irq_lock, flags);
517         if (unlikely(bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)) {
518                 spin_unlock_irqrestore(&bcm->irq_lock, flags);
519                 return -EBUSY;
520         }
521         bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
522         bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK); /* flush */
523         spin_unlock_irqrestore(&bcm->irq_lock, flags);
524         bcm43xx_synchronize_irq(bcm);
525
526         return 0;
527 }
528
529 static int bcm43xx_read_radioinfo(struct bcm43xx_private *bcm)
530 {
531         struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
532         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
533         u32 radio_id;
534         u16 manufact;
535         u16 version;
536         u8 revision;
537
538         if (bcm->chip_id == 0x4317) {
539                 if (bcm->chip_rev == 0x00)
540                         radio_id = 0x3205017F;
541                 else if (bcm->chip_rev == 0x01)
542                         radio_id = 0x4205017F;
543                 else
544                         radio_id = 0x5205017F;
545         } else {
546                 bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_CONTROL, BCM43xx_RADIOCTL_ID);
547                 radio_id = bcm43xx_read16(bcm, BCM43xx_MMIO_RADIO_DATA_HIGH);
548                 radio_id <<= 16;
549                 bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_CONTROL, BCM43xx_RADIOCTL_ID);
550                 radio_id |= bcm43xx_read16(bcm, BCM43xx_MMIO_RADIO_DATA_LOW);
551         }
552
553         manufact = (radio_id & 0x00000FFF);
554         version = (radio_id & 0x0FFFF000) >> 12;
555         revision = (radio_id & 0xF0000000) >> 28;
556
557         dprintk(KERN_INFO PFX "Detected Radio: ID: %x (Manuf: %x Ver: %x Rev: %x)\n",
558                 radio_id, manufact, version, revision);
559
560         switch (phy->type) {
561         case BCM43xx_PHYTYPE_A:
562                 if ((version != 0x2060) || (revision != 1) || (manufact != 0x17f))
563                         goto err_unsupported_radio;
564                 break;
565         case BCM43xx_PHYTYPE_B:
566                 if ((version & 0xFFF0) != 0x2050)
567                         goto err_unsupported_radio;
568                 break;
569         case BCM43xx_PHYTYPE_G:
570                 if (version != 0x2050)
571                         goto err_unsupported_radio;
572                 break;
573         }
574
575         radio->manufact = manufact;
576         radio->version = version;
577         radio->revision = revision;
578
579         if (phy->type == BCM43xx_PHYTYPE_A)
580                 radio->txpower_desired = bcm->sprom.maxpower_aphy;
581         else
582                 radio->txpower_desired = bcm->sprom.maxpower_bgphy;
583
584         return 0;
585
586 err_unsupported_radio:
587         printk(KERN_ERR PFX "Unsupported Radio connected to the PHY!\n");
588         return -ENODEV;
589 }
590
591 static const char * bcm43xx_locale_iso(u8 locale)
592 {
593         /* ISO 3166-1 country codes.
594          * Note that there aren't ISO 3166-1 codes for
595          * all or locales. (Not all locales are countries)
596          */
597         switch (locale) {
598         case BCM43xx_LOCALE_WORLD:
599         case BCM43xx_LOCALE_ALL:
600                 return "XX";
601         case BCM43xx_LOCALE_THAILAND:
602                 return "TH";
603         case BCM43xx_LOCALE_ISRAEL:
604                 return "IL";
605         case BCM43xx_LOCALE_JORDAN:
606                 return "JO";
607         case BCM43xx_LOCALE_CHINA:
608                 return "CN";
609         case BCM43xx_LOCALE_JAPAN:
610         case BCM43xx_LOCALE_JAPAN_HIGH:
611                 return "JP";
612         case BCM43xx_LOCALE_USA_CANADA_ANZ:
613         case BCM43xx_LOCALE_USA_LOW:
614                 return "US";
615         case BCM43xx_LOCALE_EUROPE:
616                 return "EU";
617         case BCM43xx_LOCALE_NONE:
618                 return "  ";
619         }
620         assert(0);
621         return "  ";
622 }
623
624 static const char * bcm43xx_locale_string(u8 locale)
625 {
626         switch (locale) {
627         case BCM43xx_LOCALE_WORLD:
628                 return "World";
629         case BCM43xx_LOCALE_THAILAND:
630                 return "Thailand";
631         case BCM43xx_LOCALE_ISRAEL:
632                 return "Israel";
633         case BCM43xx_LOCALE_JORDAN:
634                 return "Jordan";
635         case BCM43xx_LOCALE_CHINA:
636                 return "China";
637         case BCM43xx_LOCALE_JAPAN:
638                 return "Japan";
639         case BCM43xx_LOCALE_USA_CANADA_ANZ:
640                 return "USA/Canada/ANZ";
641         case BCM43xx_LOCALE_EUROPE:
642                 return "Europe";
643         case BCM43xx_LOCALE_USA_LOW:
644                 return "USAlow";
645         case BCM43xx_LOCALE_JAPAN_HIGH:
646                 return "JapanHigh";
647         case BCM43xx_LOCALE_ALL:
648                 return "All";
649         case BCM43xx_LOCALE_NONE:
650                 return "None";
651         }
652         assert(0);
653         return "";
654 }
655
656 static inline u8 bcm43xx_crc8(u8 crc, u8 data)
657 {
658         static const u8 t[] = {
659                 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
660                 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
661                 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
662                 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
663                 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
664                 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
665                 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
666                 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
667                 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
668                 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
669                 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
670                 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
671                 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
672                 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
673                 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
674                 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
675                 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
676                 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
677                 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
678                 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
679                 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
680                 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
681                 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
682                 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
683                 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
684                 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
685                 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
686                 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
687                 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
688                 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
689                 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
690                 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F,
691         };
692         return t[crc ^ data];
693 }
694
695 static u8 bcm43xx_sprom_crc(const u16 *sprom)
696 {
697         int word;
698         u8 crc = 0xFF;
699
700         for (word = 0; word < BCM43xx_SPROM_SIZE - 1; word++) {
701                 crc = bcm43xx_crc8(crc, sprom[word] & 0x00FF);
702                 crc = bcm43xx_crc8(crc, (sprom[word] & 0xFF00) >> 8);
703         }
704         crc = bcm43xx_crc8(crc, sprom[BCM43xx_SPROM_VERSION] & 0x00FF);
705         crc ^= 0xFF;
706
707         return crc;
708 }
709
710 int bcm43xx_sprom_read(struct bcm43xx_private *bcm, u16 *sprom)
711 {
712         int i;
713         u8 crc, expected_crc;
714
715         for (i = 0; i < BCM43xx_SPROM_SIZE; i++)
716                 sprom[i] = bcm43xx_read16(bcm, BCM43xx_SPROM_BASE + (i * 2));
717         /* CRC-8 check. */
718         crc = bcm43xx_sprom_crc(sprom);
719         expected_crc = (sprom[BCM43xx_SPROM_VERSION] & 0xFF00) >> 8;
720         if (crc != expected_crc) {
721                 printk(KERN_WARNING PFX "WARNING: Invalid SPROM checksum "
722                                         "(0x%02X, expected: 0x%02X)\n",
723                        crc, expected_crc);
724                 return -EINVAL;
725         }
726
727         return 0;
728 }
729
730 int bcm43xx_sprom_write(struct bcm43xx_private *bcm, const u16 *sprom)
731 {
732         int i, err;
733         u8 crc, expected_crc;
734         u32 spromctl;
735
736         /* CRC-8 validation of the input data. */
737         crc = bcm43xx_sprom_crc(sprom);
738         expected_crc = (sprom[BCM43xx_SPROM_VERSION] & 0xFF00) >> 8;
739         if (crc != expected_crc) {
740                 printk(KERN_ERR PFX "SPROM input data: Invalid CRC\n");
741                 return -EINVAL;
742         }
743
744         printk(KERN_INFO PFX "Writing SPROM. Do NOT turn off the power! Please stand by...\n");
745         err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCICFG_SPROMCTL, &spromctl);
746         if (err)
747                 goto err_ctlreg;
748         spromctl |= 0x10; /* SPROM WRITE enable. */
749         bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl);
750         if (err)
751                 goto err_ctlreg;
752         /* We must burn lots of CPU cycles here, but that does not
753          * really matter as one does not write the SPROM every other minute...
754          */
755         printk(KERN_INFO PFX "[ 0%%");
756         mdelay(500);
757         for (i = 0; i < BCM43xx_SPROM_SIZE; i++) {
758                 if (i == 16)
759                         printk("25%%");
760                 else if (i == 32)
761                         printk("50%%");
762                 else if (i == 48)
763                         printk("75%%");
764                 else if (i % 2)
765                         printk(".");
766                 bcm43xx_write16(bcm, BCM43xx_SPROM_BASE + (i * 2), sprom[i]);
767                 mmiowb();
768                 mdelay(20);
769         }
770         spromctl &= ~0x10; /* SPROM WRITE enable. */
771         bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl);
772         if (err)
773                 goto err_ctlreg;
774         mdelay(500);
775         printk("100%% ]\n");
776         printk(KERN_INFO PFX "SPROM written.\n");
777         bcm43xx_controller_restart(bcm, "SPROM update");
778
779         return 0;
780 err_ctlreg:
781         printk(KERN_ERR PFX "Could not access SPROM control register.\n");
782         return -ENODEV;
783 }
784
785 static int bcm43xx_sprom_extract(struct bcm43xx_private *bcm)
786 {
787         u16 value;
788         u16 *sprom;
789 #ifdef CONFIG_BCM947XX
790         char *c;
791 #endif
792
793         sprom = kzalloc(BCM43xx_SPROM_SIZE * sizeof(u16),
794                         GFP_KERNEL);
795         if (!sprom) {
796                 printk(KERN_ERR PFX "sprom_extract OOM\n");
797                 return -ENOMEM;
798         }
799 #ifdef CONFIG_BCM947XX
800         sprom[BCM43xx_SPROM_BOARDFLAGS2] = atoi(nvram_get("boardflags2"));
801         sprom[BCM43xx_SPROM_BOARDFLAGS] = atoi(nvram_get("boardflags"));
802
803         if ((c = nvram_get("il0macaddr")) != NULL)
804                 e_aton(c, (char *) &(sprom[BCM43xx_SPROM_IL0MACADDR]));
805
806         if ((c = nvram_get("et1macaddr")) != NULL)
807                 e_aton(c, (char *) &(sprom[BCM43xx_SPROM_ET1MACADDR]));
808
809         sprom[BCM43xx_SPROM_PA0B0] = atoi(nvram_get("pa0b0"));
810         sprom[BCM43xx_SPROM_PA0B1] = atoi(nvram_get("pa0b1"));
811         sprom[BCM43xx_SPROM_PA0B2] = atoi(nvram_get("pa0b2"));
812
813         sprom[BCM43xx_SPROM_PA1B0] = atoi(nvram_get("pa1b0"));
814         sprom[BCM43xx_SPROM_PA1B1] = atoi(nvram_get("pa1b1"));
815         sprom[BCM43xx_SPROM_PA1B2] = atoi(nvram_get("pa1b2"));
816
817         sprom[BCM43xx_SPROM_BOARDREV] = atoi(nvram_get("boardrev"));
818 #else
819         bcm43xx_sprom_read(bcm, sprom);
820 #endif
821
822         /* boardflags2 */
823         value = sprom[BCM43xx_SPROM_BOARDFLAGS2];
824         bcm->sprom.boardflags2 = value;
825
826         /* il0macaddr */
827         value = sprom[BCM43xx_SPROM_IL0MACADDR + 0];
828         *(((u16 *)bcm->sprom.il0macaddr) + 0) = cpu_to_be16(value);
829         value = sprom[BCM43xx_SPROM_IL0MACADDR + 1];
830         *(((u16 *)bcm->sprom.il0macaddr) + 1) = cpu_to_be16(value);
831         value = sprom[BCM43xx_SPROM_IL0MACADDR + 2];
832         *(((u16 *)bcm->sprom.il0macaddr) + 2) = cpu_to_be16(value);
833
834         /* et0macaddr */
835         value = sprom[BCM43xx_SPROM_ET0MACADDR + 0];
836         *(((u16 *)bcm->sprom.et0macaddr) + 0) = cpu_to_be16(value);
837         value = sprom[BCM43xx_SPROM_ET0MACADDR + 1];
838         *(((u16 *)bcm->sprom.et0macaddr) + 1) = cpu_to_be16(value);
839         value = sprom[BCM43xx_SPROM_ET0MACADDR + 2];
840         *(((u16 *)bcm->sprom.et0macaddr) + 2) = cpu_to_be16(value);
841
842         /* et1macaddr */
843         value = sprom[BCM43xx_SPROM_ET1MACADDR + 0];
844         *(((u16 *)bcm->sprom.et1macaddr) + 0) = cpu_to_be16(value);
845         value = sprom[BCM43xx_SPROM_ET1MACADDR + 1];
846         *(((u16 *)bcm->sprom.et1macaddr) + 1) = cpu_to_be16(value);
847         value = sprom[BCM43xx_SPROM_ET1MACADDR + 2];
848         *(((u16 *)bcm->sprom.et1macaddr) + 2) = cpu_to_be16(value);
849
850         /* ethernet phy settings */
851         value = sprom[BCM43xx_SPROM_ETHPHY];
852         bcm->sprom.et0phyaddr = (value & 0x001F);
853         bcm->sprom.et1phyaddr = (value & 0x03E0) >> 5;
854         bcm->sprom.et0mdcport = (value & (1 << 14)) >> 14;
855         bcm->sprom.et1mdcport = (value & (1 << 15)) >> 15;
856
857         /* boardrev, antennas, locale */
858         value = sprom[BCM43xx_SPROM_BOARDREV];
859         bcm->sprom.boardrev = (value & 0x00FF);
860         bcm->sprom.locale = (value & 0x0F00) >> 8;
861         bcm->sprom.antennas_aphy = (value & 0x3000) >> 12;
862         bcm->sprom.antennas_bgphy = (value & 0xC000) >> 14;
863         if (modparam_locale != -1) {
864                 if (modparam_locale >= 0 && modparam_locale <= 11) {
865                         bcm->sprom.locale = modparam_locale;
866                         printk(KERN_WARNING PFX "Operating with modified "
867                                                 "LocaleCode %u (%s)\n",
868                                bcm->sprom.locale,
869                                bcm43xx_locale_string(bcm->sprom.locale));
870                 } else {
871                         printk(KERN_WARNING PFX "Module parameter \"locale\" "
872                                                 "invalid value. (0 - 11)\n");
873                 }
874         }
875
876         /* pa0b* */
877         value = sprom[BCM43xx_SPROM_PA0B0];
878         bcm->sprom.pa0b0 = value;
879         value = sprom[BCM43xx_SPROM_PA0B1];
880         bcm->sprom.pa0b1 = value;
881         value = sprom[BCM43xx_SPROM_PA0B2];
882         bcm->sprom.pa0b2 = value;
883
884         /* wl0gpio* */
885         value = sprom[BCM43xx_SPROM_WL0GPIO0];
886         if (value == 0x0000)
887                 value = 0xFFFF;
888         bcm->sprom.wl0gpio0 = value & 0x00FF;
889         bcm->sprom.wl0gpio1 = (value & 0xFF00) >> 8;
890         value = sprom[BCM43xx_SPROM_WL0GPIO2];
891         if (value == 0x0000)
892                 value = 0xFFFF;
893         bcm->sprom.wl0gpio2 = value & 0x00FF;
894         bcm->sprom.wl0gpio3 = (value & 0xFF00) >> 8;
895
896         /* maxpower */
897         value = sprom[BCM43xx_SPROM_MAXPWR];
898         bcm->sprom.maxpower_aphy = (value & 0xFF00) >> 8;
899         bcm->sprom.maxpower_bgphy = value & 0x00FF;
900
901         /* pa1b* */
902         value = sprom[BCM43xx_SPROM_PA1B0];
903         bcm->sprom.pa1b0 = value;
904         value = sprom[BCM43xx_SPROM_PA1B1];
905         bcm->sprom.pa1b1 = value;
906         value = sprom[BCM43xx_SPROM_PA1B2];
907         bcm->sprom.pa1b2 = value;
908
909         /* idle tssi target */
910         value = sprom[BCM43xx_SPROM_IDL_TSSI_TGT];
911         bcm->sprom.idle_tssi_tgt_aphy = value & 0x00FF;
912         bcm->sprom.idle_tssi_tgt_bgphy = (value & 0xFF00) >> 8;
913
914         /* boardflags */
915         value = sprom[BCM43xx_SPROM_BOARDFLAGS];
916         if (value == 0xFFFF)
917                 value = 0x0000;
918         bcm->sprom.boardflags = value;
919         /* boardflags workarounds */
920         if (bcm->board_vendor == PCI_VENDOR_ID_DELL &&
921             bcm->chip_id == 0x4301 &&
922             bcm->board_revision == 0x74)
923                 bcm->sprom.boardflags |= BCM43xx_BFL_BTCOEXIST;
924         if (bcm->board_vendor == PCI_VENDOR_ID_APPLE &&
925             bcm->board_type == 0x4E &&
926             bcm->board_revision > 0x40)
927                 bcm->sprom.boardflags |= BCM43xx_BFL_PACTRL;
928
929         /* antenna gain */
930         value = sprom[BCM43xx_SPROM_ANTENNA_GAIN];
931         if (value == 0x0000 || value == 0xFFFF)
932                 value = 0x0202;
933         /* convert values to Q5.2 */
934         bcm->sprom.antennagain_aphy = ((value & 0xFF00) >> 8) * 4;
935         bcm->sprom.antennagain_bgphy = (value & 0x00FF) * 4;
936
937         kfree(sprom);
938
939         return 0;
940 }
941
942 static int bcm43xx_geo_init(struct bcm43xx_private *bcm)
943 {
944         struct ieee80211_geo *geo;
945         struct ieee80211_channel *chan;
946         int have_a = 0, have_bg = 0;
947         int i;
948         u8 channel;
949         struct bcm43xx_phyinfo *phy;
950         const char *iso_country;
951
952         geo = kzalloc(sizeof(*geo), GFP_KERNEL);
953         if (!geo)
954                 return -ENOMEM;
955
956         for (i = 0; i < bcm->nr_80211_available; i++) {
957                 phy = &(bcm->core_80211_ext[i].phy);
958                 switch (phy->type) {
959                 case BCM43xx_PHYTYPE_B:
960                 case BCM43xx_PHYTYPE_G:
961                         have_bg = 1;
962                         break;
963                 case BCM43xx_PHYTYPE_A:
964                         have_a = 1;
965                         break;
966                 default:
967                         assert(0);
968                 }
969         }
970         iso_country = bcm43xx_locale_iso(bcm->sprom.locale);
971
972         if (have_a) {
973                 for (i = 0, channel = IEEE80211_52GHZ_MIN_CHANNEL;
974                       channel <= IEEE80211_52GHZ_MAX_CHANNEL; channel++) {
975                         chan = &geo->a[i++];
976                         chan->freq = bcm43xx_channel_to_freq_a(channel);
977                         chan->channel = channel;
978                 }
979                 geo->a_channels = i;
980         }
981         if (have_bg) {
982                 for (i = 0, channel = IEEE80211_24GHZ_MIN_CHANNEL;
983                       channel <= IEEE80211_24GHZ_MAX_CHANNEL; channel++) {
984                         chan = &geo->bg[i++];
985                         chan->freq = bcm43xx_channel_to_freq_bg(channel);
986                         chan->channel = channel;
987                 }
988                 geo->bg_channels = i;
989         }
990         memcpy(geo->name, iso_country, 2);
991         if (0 /*TODO: Outdoor use only */)
992                 geo->name[2] = 'O';
993         else if (0 /*TODO: Indoor use only */)
994                 geo->name[2] = 'I';
995         else
996                 geo->name[2] = ' ';
997         geo->name[3] = '\0';
998
999         ieee80211_set_geo(bcm->ieee, geo);
1000         kfree(geo);
1001
1002         return 0;
1003 }
1004
1005 /* DummyTransmission function, as documented on 
1006  * http://bcm-specs.sipsolutions.net/DummyTransmission
1007  */
1008 void bcm43xx_dummy_transmission(struct bcm43xx_private *bcm)
1009 {
1010         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1011         struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
1012         unsigned int i, max_loop;
1013         u16 value = 0;
1014         u32 buffer[5] = {
1015                 0x00000000,
1016                 0x0000D400,
1017                 0x00000000,
1018                 0x00000001,
1019                 0x00000000,
1020         };
1021
1022         switch (phy->type) {
1023         case BCM43xx_PHYTYPE_A:
1024                 max_loop = 0x1E;
1025                 buffer[0] = 0xCC010200;
1026                 break;
1027         case BCM43xx_PHYTYPE_B:
1028         case BCM43xx_PHYTYPE_G:
1029                 max_loop = 0xFA;
1030                 buffer[0] = 0x6E840B00; 
1031                 break;
1032         default:
1033                 assert(0);
1034                 return;
1035         }
1036
1037         for (i = 0; i < 5; i++)
1038                 bcm43xx_ram_write(bcm, i * 4, buffer[i]);
1039
1040         bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
1041
1042         bcm43xx_write16(bcm, 0x0568, 0x0000);
1043         bcm43xx_write16(bcm, 0x07C0, 0x0000);
1044         bcm43xx_write16(bcm, 0x050C, ((phy->type == BCM43xx_PHYTYPE_A) ? 1 : 0));
1045         bcm43xx_write16(bcm, 0x0508, 0x0000);
1046         bcm43xx_write16(bcm, 0x050A, 0x0000);
1047         bcm43xx_write16(bcm, 0x054C, 0x0000);
1048         bcm43xx_write16(bcm, 0x056A, 0x0014);
1049         bcm43xx_write16(bcm, 0x0568, 0x0826);
1050         bcm43xx_write16(bcm, 0x0500, 0x0000);
1051         bcm43xx_write16(bcm, 0x0502, 0x0030);
1052
1053         if (radio->version == 0x2050 && radio->revision <= 0x5)
1054                 bcm43xx_radio_write16(bcm, 0x0051, 0x0017);
1055         for (i = 0x00; i < max_loop; i++) {
1056                 value = bcm43xx_read16(bcm, 0x050E);
1057                 if (value & 0x0080)
1058                         break;
1059                 udelay(10);
1060         }
1061         for (i = 0x00; i < 0x0A; i++) {
1062                 value = bcm43xx_read16(bcm, 0x050E);
1063                 if (value & 0x0400)
1064                         break;
1065                 udelay(10);
1066         }
1067         for (i = 0x00; i < 0x0A; i++) {
1068                 value = bcm43xx_read16(bcm, 0x0690);
1069                 if (!(value & 0x0100))
1070                         break;
1071                 udelay(10);
1072         }
1073         if (radio->version == 0x2050 && radio->revision <= 0x5)
1074                 bcm43xx_radio_write16(bcm, 0x0051, 0x0037);
1075 }
1076
1077 static void key_write(struct bcm43xx_private *bcm,
1078                       u8 index, u8 algorithm, const u16 *key)
1079 {
1080         unsigned int i, basic_wep = 0;
1081         u32 offset;
1082         u16 value;
1083  
1084         /* Write associated key information */
1085         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x100 + (index * 2),
1086                             ((index << 4) | (algorithm & 0x0F)));
1087  
1088         /* The first 4 WEP keys need extra love */
1089         if (((algorithm == BCM43xx_SEC_ALGO_WEP) ||
1090             (algorithm == BCM43xx_SEC_ALGO_WEP104)) && (index < 4))
1091                 basic_wep = 1;
1092  
1093         /* Write key payload, 8 little endian words */
1094         offset = bcm->security_offset + (index * BCM43xx_SEC_KEYSIZE);
1095         for (i = 0; i < (BCM43xx_SEC_KEYSIZE / sizeof(u16)); i++) {
1096                 value = cpu_to_le16(key[i]);
1097                 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
1098                                     offset + (i * 2), value);
1099  
1100                 if (!basic_wep)
1101                         continue;
1102  
1103                 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
1104                                     offset + (i * 2) + 4 * BCM43xx_SEC_KEYSIZE,
1105                                     value);
1106         }
1107 }
1108
1109 static void keymac_write(struct bcm43xx_private *bcm,
1110                          u8 index, const u32 *addr)
1111 {
1112         /* for keys 0-3 there is no associated mac address */
1113         if (index < 4)
1114                 return;
1115
1116         index -= 4;
1117         if (bcm->current_core->rev >= 5) {
1118                 bcm43xx_shm_write32(bcm,
1119                                     BCM43xx_SHM_HWMAC,
1120                                     index * 2,
1121                                     cpu_to_be32(*addr));
1122                 bcm43xx_shm_write16(bcm,
1123                                     BCM43xx_SHM_HWMAC,
1124                                     (index * 2) + 1,
1125                                     cpu_to_be16(*((u16 *)(addr + 1))));
1126         } else {
1127                 if (index < 8) {
1128                         TODO(); /* Put them in the macaddress filter */
1129                 } else {
1130                         TODO();
1131                         /* Put them BCM43xx_SHM_SHARED, stating index 0x0120.
1132                            Keep in mind to update the count of keymacs in 0x003E as well! */
1133                 }
1134         }
1135 }
1136
1137 static int bcm43xx_key_write(struct bcm43xx_private *bcm,
1138                              u8 index, u8 algorithm,
1139                              const u8 *_key, int key_len,
1140                              const u8 *mac_addr)
1141 {
1142         u8 key[BCM43xx_SEC_KEYSIZE] = { 0 };
1143
1144         if (index >= ARRAY_SIZE(bcm->key))
1145                 return -EINVAL;
1146         if (key_len > ARRAY_SIZE(key))
1147                 return -EINVAL;
1148         if (algorithm < 1 || algorithm > 5)
1149                 return -EINVAL;
1150
1151         memcpy(key, _key, key_len);
1152         key_write(bcm, index, algorithm, (const u16 *)key);
1153         keymac_write(bcm, index, (const u32 *)mac_addr);
1154
1155         bcm->key[index].algorithm = algorithm;
1156
1157         return 0;
1158 }
1159
1160 static void bcm43xx_clear_keys(struct bcm43xx_private *bcm)
1161 {
1162         static const u32 zero_mac[2] = { 0 };
1163         unsigned int i,j, nr_keys = 54;
1164         u16 offset;
1165
1166         if (bcm->current_core->rev < 5)
1167                 nr_keys = 16;
1168         assert(nr_keys <= ARRAY_SIZE(bcm->key));
1169
1170         for (i = 0; i < nr_keys; i++) {
1171                 bcm->key[i].enabled = 0;
1172                 /* returns for i < 4 immediately */
1173                 keymac_write(bcm, i, zero_mac);
1174                 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
1175                                     0x100 + (i * 2), 0x0000);
1176                 for (j = 0; j < 8; j++) {
1177                         offset = bcm->security_offset + (j * 4) + (i * BCM43xx_SEC_KEYSIZE);
1178                         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
1179                                             offset, 0x0000);
1180                 }
1181         }
1182         dprintk(KERN_INFO PFX "Keys cleared\n");
1183 }
1184
1185 /* Lowlevel core-switch function. This is only to be used in
1186  * bcm43xx_switch_core() and bcm43xx_probe_cores()
1187  */
1188 static int _switch_core(struct bcm43xx_private *bcm, int core)
1189 {
1190         int err;
1191         int attempts = 0;
1192         u32 current_core;
1193
1194         assert(core >= 0);
1195         while (1) {
1196                 err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_ACTIVE_CORE,
1197                                                  (core * 0x1000) + 0x18000000);
1198                 if (unlikely(err))
1199                         goto error;
1200                 err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCICFG_ACTIVE_CORE,
1201                                                 &current_core);
1202                 if (unlikely(err))
1203                         goto error;
1204                 current_core = (current_core - 0x18000000) / 0x1000;
1205                 if (current_core == core)
1206                         break;
1207
1208                 if (unlikely(attempts++ > BCM43xx_SWITCH_CORE_MAX_RETRIES))
1209                         goto error;
1210                 udelay(10);
1211         }
1212 #ifdef CONFIG_BCM947XX
1213         if (bcm->pci_dev->bus->number == 0)
1214                 bcm->current_core_offset = 0x1000 * core;
1215         else
1216                 bcm->current_core_offset = 0;
1217 #endif
1218
1219         return 0;
1220 error:
1221         printk(KERN_ERR PFX "Failed to switch to core %d\n", core);
1222         return -ENODEV;
1223 }
1224
1225 int bcm43xx_switch_core(struct bcm43xx_private *bcm, struct bcm43xx_coreinfo *new_core)
1226 {
1227         int err;
1228
1229         if (unlikely(!new_core))
1230                 return 0;
1231         if (!new_core->available)
1232                 return -ENODEV;
1233         if (bcm->current_core == new_core)
1234                 return 0;
1235         err = _switch_core(bcm, new_core->index);
1236         if (unlikely(err))
1237                 goto out;
1238
1239         bcm->current_core = new_core;
1240 out:
1241         return err;
1242 }
1243
1244 static int bcm43xx_core_enabled(struct bcm43xx_private *bcm)
1245 {
1246         u32 value;
1247
1248         value = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1249         value &= BCM43xx_SBTMSTATELOW_CLOCK | BCM43xx_SBTMSTATELOW_RESET
1250                  | BCM43xx_SBTMSTATELOW_REJECT;
1251
1252         return (value == BCM43xx_SBTMSTATELOW_CLOCK);
1253 }
1254
1255 /* disable current core */
1256 static int bcm43xx_core_disable(struct bcm43xx_private *bcm, u32 core_flags)
1257 {
1258         u32 sbtmstatelow;
1259         u32 sbtmstatehigh;
1260         int i;
1261
1262         /* fetch sbtmstatelow from core information registers */
1263         sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1264
1265         /* core is already in reset */
1266         if (sbtmstatelow & BCM43xx_SBTMSTATELOW_RESET)
1267                 goto out;
1268
1269         if (sbtmstatelow & BCM43xx_SBTMSTATELOW_CLOCK) {
1270                 sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK |
1271                                BCM43xx_SBTMSTATELOW_REJECT;
1272                 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1273
1274                 for (i = 0; i < 1000; i++) {
1275                         sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1276                         if (sbtmstatelow & BCM43xx_SBTMSTATELOW_REJECT) {
1277                                 i = -1;
1278                                 break;
1279                         }
1280                         udelay(10);
1281                 }
1282                 if (i != -1) {
1283                         printk(KERN_ERR PFX "Error: core_disable() REJECT timeout!\n");
1284                         return -EBUSY;
1285                 }
1286
1287                 for (i = 0; i < 1000; i++) {
1288                         sbtmstatehigh = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH);
1289                         if (!(sbtmstatehigh & BCM43xx_SBTMSTATEHIGH_BUSY)) {
1290                                 i = -1;
1291                                 break;
1292                         }
1293                         udelay(10);
1294                 }
1295                 if (i != -1) {
1296                         printk(KERN_ERR PFX "Error: core_disable() BUSY timeout!\n");
1297                         return -EBUSY;
1298                 }
1299
1300                 sbtmstatelow = BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK |
1301                                BCM43xx_SBTMSTATELOW_REJECT |
1302                                BCM43xx_SBTMSTATELOW_RESET |
1303                                BCM43xx_SBTMSTATELOW_CLOCK |
1304                                core_flags;
1305                 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1306                 udelay(10);
1307         }
1308
1309         sbtmstatelow = BCM43xx_SBTMSTATELOW_RESET |
1310                        BCM43xx_SBTMSTATELOW_REJECT |
1311                        core_flags;
1312         bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1313
1314 out:
1315         bcm->current_core->enabled = 0;
1316
1317         return 0;
1318 }
1319
1320 /* enable (reset) current core */
1321 static int bcm43xx_core_enable(struct bcm43xx_private *bcm, u32 core_flags)
1322 {
1323         u32 sbtmstatelow;
1324         u32 sbtmstatehigh;
1325         u32 sbimstate;
1326         int err;
1327
1328         err = bcm43xx_core_disable(bcm, core_flags);
1329         if (err)
1330                 goto out;
1331
1332         sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK |
1333                        BCM43xx_SBTMSTATELOW_RESET |
1334                        BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK |
1335                        core_flags;
1336         bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1337         udelay(1);
1338
1339         sbtmstatehigh = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH);
1340         if (sbtmstatehigh & BCM43xx_SBTMSTATEHIGH_SERROR) {
1341                 sbtmstatehigh = 0x00000000;
1342                 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATEHIGH, sbtmstatehigh);
1343         }
1344
1345         sbimstate = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMSTATE);
1346         if (sbimstate & (BCM43xx_SBIMSTATE_IB_ERROR | BCM43xx_SBIMSTATE_TIMEOUT)) {
1347                 sbimstate &= ~(BCM43xx_SBIMSTATE_IB_ERROR | BCM43xx_SBIMSTATE_TIMEOUT);
1348                 bcm43xx_write32(bcm, BCM43xx_CIR_SBIMSTATE, sbimstate);
1349         }
1350
1351         sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK |
1352                        BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK |
1353                        core_flags;
1354         bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1355         udelay(1);
1356
1357         sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK | core_flags;
1358         bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1359         udelay(1);
1360
1361         bcm->current_core->enabled = 1;
1362         assert(err == 0);
1363 out:
1364         return err;
1365 }
1366
1367 /* http://bcm-specs.sipsolutions.net/80211CoreReset */
1368 void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy)
1369 {
1370         u32 flags = 0x00040000;
1371
1372         if ((bcm43xx_core_enabled(bcm)) &&
1373             !bcm43xx_using_pio(bcm)) {
1374 //FIXME: Do we _really_ want #ifndef CONFIG_BCM947XX here?
1375 #if 0
1376 #ifndef CONFIG_BCM947XX
1377                 /* reset all used DMA controllers. */
1378                 bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA1_BASE);
1379                 bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA2_BASE);
1380                 bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA3_BASE);
1381                 bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA4_BASE);
1382                 bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA1_BASE);
1383                 if (bcm->current_core->rev < 5)
1384                         bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA4_BASE);
1385 #endif
1386 #endif
1387         }
1388         if (bcm43xx_status(bcm) == BCM43xx_STAT_SHUTTINGDOWN) {
1389                 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
1390                                 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
1391                                 & ~(BCM43xx_SBF_MAC_ENABLED | 0x00000002));
1392         } else {
1393                 if (connect_phy)
1394                         flags |= 0x20000000;
1395                 bcm43xx_phy_connect(bcm, connect_phy);
1396                 bcm43xx_core_enable(bcm, flags);
1397                 bcm43xx_write16(bcm, 0x03E6, 0x0000);
1398                 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
1399                                 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
1400                                 | BCM43xx_SBF_400);
1401         }
1402 }
1403
1404 static void bcm43xx_wireless_core_disable(struct bcm43xx_private *bcm)
1405 {
1406         bcm43xx_radio_turn_off(bcm);
1407         bcm43xx_write16(bcm, 0x03E6, 0x00F4);
1408         bcm43xx_core_disable(bcm, 0);
1409 }
1410
1411 /* Mark the current 80211 core inactive. */
1412 static void bcm43xx_wireless_core_mark_inactive(struct bcm43xx_private *bcm)
1413 {
1414         u32 sbtmstatelow;
1415
1416         bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
1417         bcm43xx_radio_turn_off(bcm);
1418         sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1419         sbtmstatelow &= 0xDFF5FFFF;
1420         sbtmstatelow |= 0x000A0000;
1421         bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1422         udelay(1);
1423         sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1424         sbtmstatelow &= 0xFFF5FFFF;
1425         sbtmstatelow |= 0x00080000;
1426         bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1427         udelay(1);
1428 }
1429
1430 static void handle_irq_transmit_status(struct bcm43xx_private *bcm)
1431 {
1432         u32 v0, v1;
1433         u16 tmp;
1434         struct bcm43xx_xmitstatus stat;
1435
1436         while (1) {
1437                 v0 = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_0);
1438                 if (!v0)
1439                         break;
1440                 v1 = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_1);
1441
1442                 stat.cookie = (v0 >> 16) & 0x0000FFFF;
1443                 tmp = (u16)((v0 & 0xFFF0) | ((v0 & 0xF) >> 1));
1444                 stat.flags = tmp & 0xFF;
1445                 stat.cnt1 = (tmp & 0x0F00) >> 8;
1446                 stat.cnt2 = (tmp & 0xF000) >> 12;
1447                 stat.seq = (u16)(v1 & 0xFFFF);
1448                 stat.unknown = (u16)((v1 >> 16) & 0xFF);
1449
1450                 bcm43xx_debugfs_log_txstat(bcm, &stat);
1451
1452                 if (stat.flags & BCM43xx_TXSTAT_FLAG_IGNORE)
1453                         continue;
1454                 if (!(stat.flags & BCM43xx_TXSTAT_FLAG_ACK)) {
1455                         //TODO: packet was not acked (was lost)
1456                 }
1457                 //TODO: There are more (unknown) flags to test. see bcm43xx_main.h
1458
1459                 if (bcm43xx_using_pio(bcm))
1460                         bcm43xx_pio_handle_xmitstatus(bcm, &stat);
1461                 else
1462                         bcm43xx_dma_handle_xmitstatus(bcm, &stat);
1463         }
1464 }
1465
1466 static void bcm43xx_generate_noise_sample(struct bcm43xx_private *bcm)
1467 {
1468         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x408, 0x7F7F);
1469         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x40A, 0x7F7F);
1470         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD,
1471                         bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD) | (1 << 4));
1472         assert(bcm->noisecalc.core_at_start == bcm->current_core);
1473         assert(bcm->noisecalc.channel_at_start == bcm43xx_current_radio(bcm)->channel);
1474 }
1475
1476 static void bcm43xx_calculate_link_quality(struct bcm43xx_private *bcm)
1477 {
1478         /* Top half of Link Quality calculation. */
1479
1480         if (bcm->noisecalc.calculation_running)
1481                 return;
1482         bcm->noisecalc.core_at_start = bcm->current_core;
1483         bcm->noisecalc.channel_at_start = bcm43xx_current_radio(bcm)->channel;
1484         bcm->noisecalc.calculation_running = 1;
1485         bcm->noisecalc.nr_samples = 0;
1486
1487         bcm43xx_generate_noise_sample(bcm);
1488 }
1489
1490 static void handle_irq_noise(struct bcm43xx_private *bcm)
1491 {
1492         struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
1493         u16 tmp;
1494         u8 noise[4];
1495         u8 i, j;
1496         s32 average;
1497
1498         /* Bottom half of Link Quality calculation. */
1499
1500         assert(bcm->noisecalc.calculation_running);
1501         if (bcm->noisecalc.core_at_start != bcm->current_core ||
1502             bcm->noisecalc.channel_at_start != radio->channel)
1503                 goto drop_calculation;
1504         tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x408);
1505         noise[0] = (tmp & 0x00FF);
1506         noise[1] = (tmp & 0xFF00) >> 8;
1507         tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x40A);
1508         noise[2] = (tmp & 0x00FF);
1509         noise[3] = (tmp & 0xFF00) >> 8;
1510         if (noise[0] == 0x7F || noise[1] == 0x7F ||
1511             noise[2] == 0x7F || noise[3] == 0x7F)
1512                 goto generate_new;
1513
1514         /* Get the noise samples. */
1515         assert(bcm->noisecalc.nr_samples < 8);
1516         i = bcm->noisecalc.nr_samples;
1517         noise[0] = limit_value(noise[0], 0, ARRAY_SIZE(radio->nrssi_lt) - 1);
1518         noise[1] = limit_value(noise[1], 0, ARRAY_SIZE(radio->nrssi_lt) - 1);
1519         noise[2] = limit_value(noise[2], 0, ARRAY_SIZE(radio->nrssi_lt) - 1);
1520         noise[3] = limit_value(noise[3], 0, ARRAY_SIZE(radio->nrssi_lt) - 1);
1521         bcm->noisecalc.samples[i][0] = radio->nrssi_lt[noise[0]];
1522         bcm->noisecalc.samples[i][1] = radio->nrssi_lt[noise[1]];
1523         bcm->noisecalc.samples[i][2] = radio->nrssi_lt[noise[2]];
1524         bcm->noisecalc.samples[i][3] = radio->nrssi_lt[noise[3]];
1525         bcm->noisecalc.nr_samples++;
1526         if (bcm->noisecalc.nr_samples == 8) {
1527                 /* Calculate the Link Quality by the noise samples. */
1528                 average = 0;
1529                 for (i = 0; i < 8; i++) {
1530                         for (j = 0; j < 4; j++)
1531                                 average += bcm->noisecalc.samples[i][j];
1532                 }
1533                 average /= (8 * 4);
1534                 average *= 125;
1535                 average += 64;
1536                 average /= 128;
1537
1538                 tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x40C);
1539                 tmp = (tmp / 128) & 0x1F;
1540                 if (tmp >= 8)
1541                         average += 2;
1542                 else
1543                         average -= 25;
1544                 if (tmp == 8)
1545                         average -= 72;
1546                 else
1547                         average -= 48;
1548
1549 /* FIXME: This is wrong, but people want fancy stats. well... */
1550 bcm->stats.noise = average;
1551                 if (average > -65)
1552                         bcm->stats.link_quality = 0;
1553                 else if (average > -75)
1554                         bcm->stats.link_quality = 1;
1555                 else if (average > -85)
1556                         bcm->stats.link_quality = 2;
1557                 else
1558                         bcm->stats.link_quality = 3;
1559 //              dprintk(KERN_INFO PFX "Link Quality: %u (avg was %d)\n", bcm->stats.link_quality, average);
1560 drop_calculation:
1561                 bcm->noisecalc.calculation_running = 0;
1562                 return;
1563         }
1564 generate_new:
1565         bcm43xx_generate_noise_sample(bcm);
1566 }
1567
1568 static void handle_irq_ps(struct bcm43xx_private *bcm)
1569 {
1570         if (bcm->ieee->iw_mode == IW_MODE_MASTER) {
1571                 ///TODO: PS TBTT
1572         } else {
1573                 if (1/*FIXME: the last PSpoll frame was sent successfully */)
1574                         bcm43xx_power_saving_ctl_bits(bcm, -1, -1);
1575         }
1576         if (bcm->ieee->iw_mode == IW_MODE_ADHOC)
1577                 bcm->reg124_set_0x4 = 1;
1578         //FIXME else set to false?
1579 }
1580
1581 static void handle_irq_reg124(struct bcm43xx_private *bcm)
1582 {
1583         if (!bcm->reg124_set_0x4)
1584                 return;
1585         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD,
1586                         bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD)
1587                         | 0x4);
1588         //FIXME: reset reg124_set_0x4 to false?
1589 }
1590
1591 static void handle_irq_pmq(struct bcm43xx_private *bcm)
1592 {
1593         u32 tmp;
1594
1595         //TODO: AP mode.
1596
1597         while (1) {
1598                 tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_PS_STATUS);
1599                 if (!(tmp & 0x00000008))
1600                         break;
1601         }
1602         /* 16bit write is odd, but correct. */
1603         bcm43xx_write16(bcm, BCM43xx_MMIO_PS_STATUS, 0x0002);
1604 }
1605
1606 static void bcm43xx_generate_beacon_template(struct bcm43xx_private *bcm,
1607                                              u16 ram_offset, u16 shm_size_offset)
1608 {
1609         u32 value;
1610         u16 size = 0;
1611
1612         /* Timestamp. */
1613         //FIXME: assumption: The chip sets the timestamp
1614         value = 0;
1615         bcm43xx_ram_write(bcm, ram_offset++, value);
1616         bcm43xx_ram_write(bcm, ram_offset++, value);
1617         size += 8;
1618
1619         /* Beacon Interval / Capability Information */
1620         value = 0x0000;//FIXME: Which interval?
1621         value |= (1 << 0) << 16; /* ESS */
1622         value |= (1 << 2) << 16; /* CF Pollable */      //FIXME?
1623         value |= (1 << 3) << 16; /* CF Poll Request */  //FIXME?
1624         if (!bcm->ieee->open_wep)
1625                 value |= (1 << 4) << 16; /* Privacy */
1626         bcm43xx_ram_write(bcm, ram_offset++, value);
1627         size += 4;
1628
1629         /* SSID */
1630         //TODO
1631
1632         /* FH Parameter Set */
1633         //TODO
1634
1635         /* DS Parameter Set */
1636         //TODO
1637
1638         /* CF Parameter Set */
1639         //TODO
1640
1641         /* TIM */
1642         //TODO
1643
1644         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, shm_size_offset, size);
1645 }
1646
1647 static void handle_irq_beacon(struct bcm43xx_private *bcm)
1648 {
1649         u32 status;
1650
1651         bcm->irq_savedstate &= ~BCM43xx_IRQ_BEACON;
1652         status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD);
1653
1654         if ((status & 0x1) && (status & 0x2)) {
1655                 /* ACK beacon IRQ. */
1656                 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON,
1657                                 BCM43xx_IRQ_BEACON);
1658                 bcm->irq_savedstate |= BCM43xx_IRQ_BEACON;
1659                 return;
1660         }
1661         if (!(status & 0x1)) {
1662                 bcm43xx_generate_beacon_template(bcm, 0x68, 0x18);
1663                 status |= 0x1;
1664                 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, status);
1665         }
1666         if (!(status & 0x2)) {
1667                 bcm43xx_generate_beacon_template(bcm, 0x468, 0x1A);
1668                 status |= 0x2;
1669                 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, status);
1670         }
1671 }
1672
1673 /* Interrupt handler bottom-half */
1674 static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1675 {
1676         u32 reason;
1677         u32 dma_reason[6];
1678         u32 merged_dma_reason = 0;
1679         int i, activity = 0;
1680         unsigned long flags;
1681
1682 #ifdef CONFIG_BCM43XX_DEBUG
1683         u32 _handled = 0x00000000;
1684 # define bcmirq_handled(irq)    do { _handled |= (irq); } while (0)
1685 #else
1686 # define bcmirq_handled(irq)    do { /* nothing */ } while (0)
1687 #endif /* CONFIG_BCM43XX_DEBUG*/
1688
1689         spin_lock_irqsave(&bcm->irq_lock, flags);
1690         reason = bcm->irq_reason;
1691         for (i = 5; i >= 0; i--) {
1692                 dma_reason[i] = bcm->dma_reason[i];
1693                 merged_dma_reason |= dma_reason[i];
1694         }
1695
1696         if (unlikely(reason & BCM43xx_IRQ_XMIT_ERROR)) {
1697                 /* TX error. We get this when Template Ram is written in wrong endianess
1698                  * in dummy_tx(). We also get this if something is wrong with the TX header
1699                  * on DMA or PIO queues.
1700                  * Maybe we get this in other error conditions, too.
1701                  */
1702                 printkl(KERN_ERR PFX "FATAL ERROR: BCM43xx_IRQ_XMIT_ERROR\n");
1703                 bcmirq_handled(BCM43xx_IRQ_XMIT_ERROR);
1704         }
1705         if (unlikely(merged_dma_reason & BCM43xx_DMAIRQ_FATALMASK)) {
1706                 printkl(KERN_ERR PFX "FATAL ERROR: Fatal DMA error: "
1707                                      "0x%08X, 0x%08X, 0x%08X, "
1708                                      "0x%08X, 0x%08X, 0x%08X\n",
1709                         dma_reason[0], dma_reason[1],
1710                         dma_reason[2], dma_reason[3],
1711                         dma_reason[4], dma_reason[5]);
1712                 bcm43xx_controller_restart(bcm, "DMA error");
1713                 mmiowb();
1714                 spin_unlock_irqrestore(&bcm->irq_lock, flags);
1715                 return;
1716         }
1717         if (unlikely(merged_dma_reason & BCM43xx_DMAIRQ_NONFATALMASK)) {
1718                 printkl(KERN_ERR PFX "DMA error: "
1719                                      "0x%08X, 0x%08X, 0x%08X, "
1720                                      "0x%08X, 0x%08X, 0x%08X\n",
1721                         dma_reason[0], dma_reason[1],
1722                         dma_reason[2], dma_reason[3],
1723                         dma_reason[4], dma_reason[5]);
1724         }
1725
1726         if (reason & BCM43xx_IRQ_PS) {
1727                 handle_irq_ps(bcm);
1728                 bcmirq_handled(BCM43xx_IRQ_PS);
1729         }
1730
1731         if (reason & BCM43xx_IRQ_REG124) {
1732                 handle_irq_reg124(bcm);
1733                 bcmirq_handled(BCM43xx_IRQ_REG124);
1734         }
1735
1736         if (reason & BCM43xx_IRQ_BEACON) {
1737                 if (bcm->ieee->iw_mode == IW_MODE_MASTER)
1738                         handle_irq_beacon(bcm);
1739                 bcmirq_handled(BCM43xx_IRQ_BEACON);
1740         }
1741
1742         if (reason & BCM43xx_IRQ_PMQ) {
1743                 handle_irq_pmq(bcm);
1744                 bcmirq_handled(BCM43xx_IRQ_PMQ);
1745         }
1746
1747         if (reason & BCM43xx_IRQ_SCAN) {
1748                 /*TODO*/
1749                 //bcmirq_handled(BCM43xx_IRQ_SCAN);
1750         }
1751
1752         if (reason & BCM43xx_IRQ_NOISE) {
1753                 handle_irq_noise(bcm);
1754                 bcmirq_handled(BCM43xx_IRQ_NOISE);
1755         }
1756
1757         /* Check the DMA reason registers for received data. */
1758         if (dma_reason[0] & BCM43xx_DMAIRQ_RX_DONE) {
1759                 if (bcm43xx_using_pio(bcm))
1760                         bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue0);
1761                 else
1762                         bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring0);
1763                 /* We intentionally don't set "activity" to 1, here. */
1764         }
1765         assert(!(dma_reason[1] & BCM43xx_DMAIRQ_RX_DONE));
1766         assert(!(dma_reason[2] & BCM43xx_DMAIRQ_RX_DONE));
1767         if (dma_reason[3] & BCM43xx_DMAIRQ_RX_DONE) {
1768                 if (bcm43xx_using_pio(bcm))
1769                         bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue3);
1770                 else
1771                         bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring3);
1772                 activity = 1;
1773         }
1774         assert(!(dma_reason[4] & BCM43xx_DMAIRQ_RX_DONE));
1775         assert(!(dma_reason[5] & BCM43xx_DMAIRQ_RX_DONE));
1776         bcmirq_handled(BCM43xx_IRQ_RX);
1777
1778         if (reason & BCM43xx_IRQ_XMIT_STATUS) {
1779                 handle_irq_transmit_status(bcm);
1780                 activity = 1;
1781                 //TODO: In AP mode, this also causes sending of powersave responses.
1782                 bcmirq_handled(BCM43xx_IRQ_XMIT_STATUS);
1783         }
1784
1785         /* IRQ_PIO_WORKAROUND is handled in the top-half. */
1786         bcmirq_handled(BCM43xx_IRQ_PIO_WORKAROUND);
1787 #ifdef CONFIG_BCM43XX_DEBUG
1788         if (unlikely(reason & ~_handled)) {
1789                 printkl(KERN_WARNING PFX
1790                         "Unhandled IRQ! Reason: 0x%08x,  Unhandled: 0x%08x,  "
1791                         "DMA: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
1792                         reason, (reason & ~_handled),
1793                         dma_reason[0], dma_reason[1],
1794                         dma_reason[2], dma_reason[3]);
1795         }
1796 #endif
1797 #undef bcmirq_handled
1798
1799         if (!modparam_noleds)
1800                 bcm43xx_leds_update(bcm, activity);
1801         bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
1802         mmiowb();
1803         spin_unlock_irqrestore(&bcm->irq_lock, flags);
1804 }
1805
1806 static void pio_irq_workaround(struct bcm43xx_private *bcm,
1807                                u16 base, int queueidx)
1808 {
1809         u16 rxctl;
1810
1811         rxctl = bcm43xx_read16(bcm, base + BCM43xx_PIO_RXCTL);
1812         if (rxctl & BCM43xx_PIO_RXCTL_DATAAVAILABLE)
1813                 bcm->dma_reason[queueidx] |= BCM43xx_DMAIRQ_RX_DONE;
1814         else
1815                 bcm->dma_reason[queueidx] &= ~BCM43xx_DMAIRQ_RX_DONE;
1816 }
1817
1818 static void bcm43xx_interrupt_ack(struct bcm43xx_private *bcm, u32 reason)
1819 {
1820         if (bcm43xx_using_pio(bcm) &&
1821             (bcm->current_core->rev < 3) &&
1822             (!(reason & BCM43xx_IRQ_PIO_WORKAROUND))) {
1823                 /* Apply a PIO specific workaround to the dma_reasons */
1824                 pio_irq_workaround(bcm, BCM43xx_MMIO_PIO1_BASE, 0);
1825                 pio_irq_workaround(bcm, BCM43xx_MMIO_PIO2_BASE, 1);
1826                 pio_irq_workaround(bcm, BCM43xx_MMIO_PIO3_BASE, 2);
1827                 pio_irq_workaround(bcm, BCM43xx_MMIO_PIO4_BASE, 3);
1828         }
1829
1830         bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, reason);
1831
1832         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA0_REASON,
1833                         bcm->dma_reason[0]);
1834         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_REASON,
1835                         bcm->dma_reason[1]);
1836         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_REASON,
1837                         bcm->dma_reason[2]);
1838         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_REASON,
1839                         bcm->dma_reason[3]);
1840         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_REASON,
1841                         bcm->dma_reason[4]);
1842         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA5_REASON,
1843                         bcm->dma_reason[5]);
1844 }
1845
1846 /* Interrupt handler top-half */
1847 static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_regs *regs)
1848 {
1849         irqreturn_t ret = IRQ_HANDLED;
1850         struct bcm43xx_private *bcm = dev_id;
1851         u32 reason;
1852
1853         if (!bcm)
1854                 return IRQ_NONE;
1855
1856         spin_lock(&bcm->irq_lock);
1857
1858         assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
1859         assert(bcm->current_core->id == BCM43xx_COREID_80211);
1860
1861         reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
1862         if (reason == 0xffffffff) {
1863                 /* irq not for us (shared irq) */
1864                 ret = IRQ_NONE;
1865                 goto out;
1866         }
1867         reason &= bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK);
1868         if (!reason)
1869                 goto out;
1870
1871         bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA0_REASON)
1872                              & 0x0001DC00;
1873         bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON)
1874                              & 0x0000DC00;
1875         bcm->dma_reason[2] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA2_REASON)
1876                              & 0x0000DC00;
1877         bcm->dma_reason[3] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA3_REASON)
1878                              & 0x0001DC00;
1879         bcm->dma_reason[4] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_REASON)
1880                              & 0x0000DC00;
1881         bcm->dma_reason[5] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA5_REASON)
1882                              & 0x0000DC00;
1883
1884         bcm43xx_interrupt_ack(bcm, reason);
1885
1886         /* disable all IRQs. They are enabled again in the bottom half. */
1887         bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
1888         /* save the reason code and call our bottom half. */
1889         bcm->irq_reason = reason;
1890         tasklet_schedule(&bcm->isr_tasklet);
1891
1892 out:
1893         mmiowb();
1894         spin_unlock(&bcm->irq_lock);
1895
1896         return ret;
1897 }
1898
1899 static void bcm43xx_release_firmware(struct bcm43xx_private *bcm, int force)
1900 {
1901         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1902
1903         if (bcm->firmware_norelease && !force)
1904                 return; /* Suspending or controller reset. */
1905         release_firmware(phy->ucode);
1906         phy->ucode = NULL;
1907         release_firmware(phy->pcm);
1908         phy->pcm = NULL;
1909         release_firmware(phy->initvals0);
1910         phy->initvals0 = NULL;
1911         release_firmware(phy->initvals1);
1912         phy->initvals1 = NULL;
1913 }
1914
1915 static int bcm43xx_request_firmware(struct bcm43xx_private *bcm)
1916 {
1917         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1918         u8 rev = bcm->current_core->rev;
1919         int err = 0;
1920         int nr;
1921         char buf[22 + sizeof(modparam_fwpostfix) - 1] = { 0 };
1922
1923         if (!phy->ucode) {
1924                 snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_microcode%d%s.fw",
1925                          (rev >= 5 ? 5 : rev),
1926                          modparam_fwpostfix);
1927                 err = request_firmware(&phy->ucode, buf, &bcm->pci_dev->dev);
1928                 if (err) {
1929                         printk(KERN_ERR PFX 
1930                                "Error: Microcode \"%s\" not available or load failed.\n",
1931                                 buf);
1932                         goto error;
1933                 }
1934         }
1935
1936         if (!phy->pcm) {
1937                 snprintf(buf, ARRAY_SIZE(buf),
1938                          "bcm43xx_pcm%d%s.fw",
1939                          (rev < 5 ? 4 : 5),
1940                          modparam_fwpostfix);
1941                 err = request_firmware(&phy->pcm, buf, &bcm->pci_dev->dev);
1942                 if (err) {
1943                         printk(KERN_ERR PFX
1944                                "Error: PCM \"%s\" not available or load failed.\n",
1945                                buf);
1946                         goto error;
1947                 }
1948         }
1949
1950         if (!phy->initvals0) {
1951                 if (rev == 2 || rev == 4) {
1952                         switch (phy->type) {
1953                         case BCM43xx_PHYTYPE_A:
1954                                 nr = 3;
1955                                 break;
1956                         case BCM43xx_PHYTYPE_B:
1957                         case BCM43xx_PHYTYPE_G:
1958                                 nr = 1;
1959                                 break;
1960                         default:
1961                                 goto err_noinitval;
1962                         }
1963                 
1964                 } else if (rev >= 5) {
1965                         switch (phy->type) {
1966                         case BCM43xx_PHYTYPE_A:
1967                                 nr = 7;
1968                                 break;
1969                         case BCM43xx_PHYTYPE_B:
1970                         case BCM43xx_PHYTYPE_G:
1971                                 nr = 5;
1972                                 break;
1973                         default:
1974                                 goto err_noinitval;
1975                         }
1976                 } else
1977                         goto err_noinitval;
1978                 snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_initval%02d%s.fw",
1979                          nr, modparam_fwpostfix);
1980
1981                 err = request_firmware(&phy->initvals0, buf, &bcm->pci_dev->dev);
1982                 if (err) {
1983                         printk(KERN_ERR PFX 
1984                                "Error: InitVals \"%s\" not available or load failed.\n",
1985                                 buf);
1986                         goto error;
1987                 }
1988                 if (phy->initvals0->size % sizeof(struct bcm43xx_initval)) {
1989                         printk(KERN_ERR PFX "InitVals fileformat error.\n");
1990                         goto error;
1991                 }
1992         }
1993
1994         if (!phy->initvals1) {
1995                 if (rev >= 5) {
1996                         u32 sbtmstatehigh;
1997
1998                         switch (phy->type) {
1999                         case BCM43xx_PHYTYPE_A:
2000                                 sbtmstatehigh = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH);
2001                                 if (sbtmstatehigh & 0x00010000)
2002                                         nr = 9;
2003                                 else
2004                                         nr = 10;
2005                                 break;
2006                         case BCM43xx_PHYTYPE_B:
2007                         case BCM43xx_PHYTYPE_G:
2008                                         nr = 6;
2009                                 break;
2010                         default:
2011                                 goto err_noinitval;
2012                         }
2013                         snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_initval%02d%s.fw",
2014                                  nr, modparam_fwpostfix);
2015
2016                         err = request_firmware(&phy->initvals1, buf, &bcm->pci_dev->dev);
2017                         if (err) {
2018                                 printk(KERN_ERR PFX 
2019                                        "Error: InitVals \"%s\" not available or load failed.\n",
2020                                         buf);
2021                                 goto error;
2022                         }
2023                         if (phy->initvals1->size % sizeof(struct bcm43xx_initval)) {
2024                                 printk(KERN_ERR PFX "InitVals fileformat error.\n");
2025                                 goto error;
2026                         }
2027                 }
2028         }
2029
2030 out:
2031         return err;
2032 error:
2033         bcm43xx_release_firmware(bcm, 1);
2034         goto out;
2035 err_noinitval:
2036         printk(KERN_ERR PFX "Error: No InitVals available!\n");
2037         err = -ENOENT;
2038         goto error;
2039 }
2040
2041 static void bcm43xx_upload_microcode(struct bcm43xx_private *bcm)
2042 {
2043         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
2044         const u32 *data;
2045         unsigned int i, len;
2046
2047         /* Upload Microcode. */
2048         data = (u32 *)(phy->ucode->data);
2049         len = phy->ucode->size / sizeof(u32);
2050         bcm43xx_shm_control_word(bcm, BCM43xx_SHM_UCODE, 0x0000);
2051         for (i = 0; i < len; i++) {
2052                 bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA,
2053                                 be32_to_cpu(data[i]));
2054                 udelay(10);
2055         }
2056
2057         /* Upload PCM data. */
2058         data = (u32 *)(phy->pcm->data);
2059         len = phy->pcm->size / sizeof(u32);
2060         bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01ea);
2061         bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, 0x00004000);
2062         bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01eb);
2063         for (i = 0; i < len; i++) {
2064                 bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA,
2065                                 be32_to_cpu(data[i]));
2066                 udelay(10);
2067         }
2068 }
2069
2070 static int bcm43xx_write_initvals(struct bcm43xx_private *bcm,
2071                                   const struct bcm43xx_initval *data,
2072                                   const unsigned int len)
2073 {
2074         u16 offset, size;
2075         u32 value;
2076         unsigned int i;
2077
2078         for (i = 0; i < len; i++) {
2079                 offset = be16_to_cpu(data[i].offset);
2080                 size = be16_to_cpu(data[i].size);
2081                 value = be32_to_cpu(data[i].value);
2082
2083                 if (unlikely(offset >= 0x1000))
2084                         goto err_format;
2085                 if (size == 2) {
2086                         if (unlikely(value & 0xFFFF0000))
2087                                 goto err_format;
2088                         bcm43xx_write16(bcm, offset, (u16)value);
2089                 } else if (size == 4) {
2090                         bcm43xx_write32(bcm, offset, value);
2091                 } else
2092                         goto err_format;
2093         }
2094
2095         return 0;
2096
2097 err_format:
2098         printk(KERN_ERR PFX "InitVals (bcm43xx_initvalXX.fw) file-format error. "
2099                             "Please fix your bcm43xx firmware files.\n");
2100         return -EPROTO;
2101 }
2102
2103 static int bcm43xx_upload_initvals(struct bcm43xx_private *bcm)
2104 {
2105         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
2106         int err;
2107
2108         err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)phy->initvals0->data,
2109                                      phy->initvals0->size / sizeof(struct bcm43xx_initval));
2110         if (err)
2111                 goto out;
2112         if (phy->initvals1) {
2113                 err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)phy->initvals1->data,
2114                                              phy->initvals1->size / sizeof(struct bcm43xx_initval));
2115                 if (err)
2116                         goto out;
2117         }
2118 out:
2119         return err;
2120 }
2121
2122 #ifdef CONFIG_BCM947XX
2123 static struct pci_device_id bcm43xx_47xx_ids[] = {
2124         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4324) },
2125         { 0 }
2126 };
2127 #endif
2128
2129 static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm)
2130 {
2131         int err;
2132
2133         bcm->irq = bcm->pci_dev->irq;
2134 #ifdef CONFIG_BCM947XX
2135         if (bcm->pci_dev->bus->number == 0) {
2136                 struct pci_dev *d;
2137                 struct pci_device_id *id;
2138                 for (id = bcm43xx_47xx_ids; id->vendor; id++) {
2139                         d = pci_get_device(id->vendor, id->device, NULL);
2140                         if (d != NULL) {
2141                                 bcm->irq = d->irq;
2142                                 pci_dev_put(d);
2143                                 break;
2144                         }
2145                 }
2146         }
2147 #endif
2148         err = request_irq(bcm->irq, bcm43xx_interrupt_handler,
2149                           IRQF_SHARED, KBUILD_MODNAME, bcm);
2150         if (err)
2151                 printk(KERN_ERR PFX "Cannot register IRQ%d\n", bcm->irq);
2152
2153         return err;
2154 }
2155
2156 /* Switch to the core used to write the GPIO register.
2157  * This is either the ChipCommon, or the PCI core.
2158  */
2159 static int switch_to_gpio_core(struct bcm43xx_private *bcm)
2160 {
2161         int err;
2162
2163         /* Where to find the GPIO register depends on the chipset.
2164          * If it has a ChipCommon, its register at offset 0x6c is the GPIO
2165          * control register. Otherwise the register at offset 0x6c in the
2166          * PCI core is the GPIO control register.
2167          */
2168         err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
2169         if (err == -ENODEV) {
2170                 err = bcm43xx_switch_core(bcm, &bcm->core_pci);
2171                 if (unlikely(err == -ENODEV)) {
2172                         printk(KERN_ERR PFX "gpio error: "
2173                                "Neither ChipCommon nor PCI core available!\n");
2174                 }
2175         }
2176
2177         return err;
2178 }
2179
2180 /* Initialize the GPIOs
2181  * http://bcm-specs.sipsolutions.net/GPIO
2182  */
2183 static int bcm43xx_gpio_init(struct bcm43xx_private *bcm)
2184 {
2185         struct bcm43xx_coreinfo *old_core;
2186         int err;
2187         u32 mask, set;
2188
2189         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
2190                         bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
2191                         & 0xFFFF3FFF);
2192
2193         bcm43xx_leds_switch_all(bcm, 0);
2194         bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_MASK,
2195                         bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_MASK) | 0x000F);
2196
2197         mask = 0x0000001F;
2198         set = 0x0000000F;
2199         if (bcm->chip_id == 0x4301) {
2200                 mask |= 0x0060;
2201                 set |= 0x0060;
2202         }
2203         if (0 /* FIXME: conditional unknown */) {
2204                 bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_MASK,
2205                                 bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_MASK)
2206                                 | 0x0100);
2207                 mask |= 0x0180;
2208                 set |= 0x0180;
2209         }
2210         if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) {
2211                 bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_MASK,
2212                                 bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_MASK)
2213                                 | 0x0200);
2214                 mask |= 0x0200;
2215                 set |= 0x0200;
2216         }
2217         if (bcm->current_core->rev >= 2)
2218                 mask  |= 0x0010; /* FIXME: This is redundant. */
2219
2220         old_core = bcm->current_core;
2221         err = switch_to_gpio_core(bcm);
2222         if (err)
2223                 goto out;
2224         bcm43xx_write32(bcm, BCM43xx_GPIO_CONTROL,
2225                         (bcm43xx_read32(bcm, BCM43xx_GPIO_CONTROL) & mask) | set);
2226         err = bcm43xx_switch_core(bcm, old_core);
2227 out:
2228         return err;
2229 }
2230
2231 /* Turn off all GPIO stuff. Call this on module unload, for example. */
2232 static int bcm43xx_gpio_cleanup(struct bcm43xx_private *bcm)
2233 {
2234         struct bcm43xx_coreinfo *old_core;
2235         int err;
2236
2237         old_core = bcm->current_core;
2238         err = switch_to_gpio_core(bcm);
2239         if (err)
2240                 return err;
2241         bcm43xx_write32(bcm, BCM43xx_GPIO_CONTROL, 0x00000000);
2242         err = bcm43xx_switch_core(bcm, old_core);
2243         assert(err == 0);
2244
2245         return 0;
2246 }
2247
2248 /* http://bcm-specs.sipsolutions.net/EnableMac */
2249 void bcm43xx_mac_enable(struct bcm43xx_private *bcm)
2250 {
2251         bcm->mac_suspended--;
2252         assert(bcm->mac_suspended >= 0);
2253         if (bcm->mac_suspended == 0) {
2254                 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
2255                                 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
2256                                 | BCM43xx_SBF_MAC_ENABLED);
2257                 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, BCM43xx_IRQ_READY);
2258                 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
2259                 bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
2260                 bcm43xx_power_saving_ctl_bits(bcm, -1, -1);
2261         }
2262 }
2263
2264 /* http://bcm-specs.sipsolutions.net/SuspendMAC */
2265 void bcm43xx_mac_suspend(struct bcm43xx_private *bcm)
2266 {
2267         int i;
2268         u32 tmp;
2269
2270         assert(bcm->mac_suspended >= 0);
2271         if (bcm->mac_suspended == 0) {
2272                 bcm43xx_power_saving_ctl_bits(bcm, -1, 1);
2273                 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
2274                                 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
2275                                 & ~BCM43xx_SBF_MAC_ENABLED);
2276                 bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
2277                 for (i = 10000; i; i--) {
2278                         tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
2279                         if (tmp & BCM43xx_IRQ_READY)
2280                                 goto out;
2281                         udelay(1);
2282                 }
2283                 printkl(KERN_ERR PFX "MAC suspend failed\n");
2284         }
2285 out:
2286         bcm->mac_suspended++;
2287 }
2288
2289 void bcm43xx_set_iwmode(struct bcm43xx_private *bcm,
2290                         int iw_mode)
2291 {
2292         unsigned long flags;
2293         struct net_device *net_dev = bcm->net_dev;
2294         u32 status;
2295         u16 value;
2296
2297         spin_lock_irqsave(&bcm->ieee->lock, flags);
2298         bcm->ieee->iw_mode = iw_mode;
2299         spin_unlock_irqrestore(&bcm->ieee->lock, flags);
2300         if (iw_mode == IW_MODE_MONITOR)
2301                 net_dev->type = ARPHRD_IEEE80211;
2302         else
2303                 net_dev->type = ARPHRD_ETHER;
2304
2305         status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2306         /* Reset status to infrastructured mode */
2307         status &= ~(BCM43xx_SBF_MODE_AP | BCM43xx_SBF_MODE_MONITOR);
2308         status &= ~BCM43xx_SBF_MODE_PROMISC;
2309         status |= BCM43xx_SBF_MODE_NOTADHOC;
2310
2311 /* FIXME: Always enable promisc mode, until we get the MAC filters working correctly. */
2312 status |= BCM43xx_SBF_MODE_PROMISC;
2313
2314         switch (iw_mode) {
2315         case IW_MODE_MONITOR:
2316                 status |= BCM43xx_SBF_MODE_MONITOR;
2317                 status |= BCM43xx_SBF_MODE_PROMISC;
2318                 break;
2319         case IW_MODE_ADHOC:
2320                 status &= ~BCM43xx_SBF_MODE_NOTADHOC;
2321                 break;
2322         case IW_MODE_MASTER:
2323                 status |= BCM43xx_SBF_MODE_AP;
2324                 break;
2325         case IW_MODE_SECOND:
2326         case IW_MODE_REPEAT:
2327                 TODO(); /* TODO */
2328                 break;
2329         case IW_MODE_INFRA:
2330                 /* nothing to be done here... */
2331                 break;
2332         default:
2333                 dprintk(KERN_ERR PFX "Unknown mode in set_iwmode: %d\n", iw_mode);
2334         }
2335         if (net_dev->flags & IFF_PROMISC)
2336                 status |= BCM43xx_SBF_MODE_PROMISC;
2337         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
2338
2339         value = 0x0002;
2340         if (iw_mode != IW_MODE_ADHOC && iw_mode != IW_MODE_MASTER) {
2341                 if (bcm->chip_id == 0x4306 && bcm->chip_rev == 3)
2342                         value = 0x0064;
2343                 else
2344                         value = 0x0032;
2345         }
2346         bcm43xx_write16(bcm, 0x0612, value);
2347 }
2348
2349 /* This is the opposite of bcm43xx_chip_init() */
2350 static void bcm43xx_chip_cleanup(struct bcm43xx_private *bcm)
2351 {
2352         bcm43xx_radio_turn_off(bcm);
2353         if (!modparam_noleds)
2354                 bcm43xx_leds_exit(bcm);
2355         bcm43xx_gpio_cleanup(bcm);
2356         bcm43xx_release_firmware(bcm, 0);
2357 }
2358
2359 /* Initialize the chip
2360  * http://bcm-specs.sipsolutions.net/ChipInit
2361  */
2362 static int bcm43xx_chip_init(struct bcm43xx_private *bcm)
2363 {
2364         struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
2365         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
2366         int err;
2367         int i, tmp;
2368         u32 value32;
2369         u16 value16;
2370
2371         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
2372                         BCM43xx_SBF_CORE_READY
2373                         | BCM43xx_SBF_400);
2374
2375         err = bcm43xx_request_firmware(bcm);
2376         if (err)
2377                 goto out;
2378         bcm43xx_upload_microcode(bcm);
2379
2380         bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0xFFFFFFFF);
2381         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, 0x00020402);
2382         i = 0;
2383         while (1) {
2384                 value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
2385                 if (value32 == BCM43xx_IRQ_READY)
2386                         break;
2387                 i++;
2388                 if (i >= BCM43xx_IRQWAIT_MAX_RETRIES) {
2389                         printk(KERN_ERR PFX "IRQ_READY timeout\n");
2390                         err = -ENODEV;
2391                         goto err_release_fw;
2392                 }
2393                 udelay(10);
2394         }
2395         bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
2396
2397         err = bcm43xx_gpio_init(bcm);
2398         if (err)
2399                 goto err_release_fw;
2400
2401         err = bcm43xx_upload_initvals(bcm);
2402         if (err)
2403                 goto err_gpio_cleanup;
2404         bcm43xx_radio_turn_on(bcm);
2405
2406         bcm43xx_write16(bcm, 0x03E6, 0x0000);
2407         err = bcm43xx_phy_init(bcm);
2408         if (err)
2409                 goto err_radio_off;
2410
2411         /* Select initial Interference Mitigation. */
2412         tmp = radio->interfmode;
2413         radio->interfmode = BCM43xx_RADIO_INTERFMODE_NONE;
2414         bcm43xx_radio_set_interference_mitigation(bcm, tmp);
2415
2416         bcm43xx_phy_set_antenna_diversity(bcm);
2417         bcm43xx_radio_set_txantenna(bcm, BCM43xx_RADIO_TXANTENNA_DEFAULT);
2418         if (phy->type == BCM43xx_PHYTYPE_B) {
2419                 value16 = bcm43xx_read16(bcm, 0x005E);
2420                 value16 |= 0x0004;
2421                 bcm43xx_write16(bcm, 0x005E, value16);
2422         }
2423         bcm43xx_write32(bcm, 0x0100, 0x01000000);
2424         if (bcm->current_core->rev < 5)
2425                 bcm43xx_write32(bcm, 0x010C, 0x01000000);
2426
2427         value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2428         value32 &= ~ BCM43xx_SBF_MODE_NOTADHOC;
2429         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32);
2430         value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2431         value32 |= BCM43xx_SBF_MODE_NOTADHOC;
2432         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32);
2433
2434         value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2435         value32 |= 0x100000;
2436         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32);
2437
2438         if (bcm43xx_using_pio(bcm)) {
2439                 bcm43xx_write32(bcm, 0x0210, 0x00000100);
2440                 bcm43xx_write32(bcm, 0x0230, 0x00000100);
2441                 bcm43xx_write32(bcm, 0x0250, 0x00000100);
2442                 bcm43xx_write32(bcm, 0x0270, 0x00000100);
2443                 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0034, 0x0000);
2444         }
2445
2446         /* Probe Response Timeout value */
2447         /* FIXME: Default to 0, has to be set by ioctl probably... :-/ */
2448         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0074, 0x0000);
2449
2450         /* Initially set the wireless operation mode. */
2451         bcm43xx_set_iwmode(bcm, bcm->ieee->iw_mode);
2452
2453         if (bcm->current_core->rev < 3) {
2454                 bcm43xx_write16(bcm, 0x060E, 0x0000);
2455                 bcm43xx_write16(bcm, 0x0610, 0x8000);
2456                 bcm43xx_write16(bcm, 0x0604, 0x0000);
2457                 bcm43xx_write16(bcm, 0x0606, 0x0200);
2458         } else {
2459                 bcm43xx_write32(bcm, 0x0188, 0x80000000);
2460                 bcm43xx_write32(bcm, 0x018C, 0x02000000);
2461         }
2462         bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0x00004000);
2463         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA0_IRQ_MASK, 0x0001DC00);
2464         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_IRQ_MASK, 0x0000DC00);
2465         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_IRQ_MASK, 0x0000DC00);
2466         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_IRQ_MASK, 0x0001DC00);
2467         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_IRQ_MASK, 0x0000DC00);
2468         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA5_IRQ_MASK, 0x0000DC00);
2469
2470         value32 = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
2471         value32 |= 0x00100000;
2472         bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, value32);
2473
2474         bcm43xx_write16(bcm, BCM43xx_MMIO_POWERUP_DELAY, bcm43xx_pctl_powerup_delay(bcm));
2475
2476         assert(err == 0);
2477         dprintk(KERN_INFO PFX "Chip initialized\n");
2478 out:
2479         return err;
2480
2481 err_radio_off:
2482         bcm43xx_radio_turn_off(bcm);
2483 err_gpio_cleanup:
2484         bcm43xx_gpio_cleanup(bcm);
2485 err_release_fw:
2486         bcm43xx_release_firmware(bcm, 1);
2487         goto out;
2488 }
2489         
2490 /* Validate chip access
2491  * http://bcm-specs.sipsolutions.net/ValidateChipAccess */
2492 static int bcm43xx_validate_chip(struct bcm43xx_private *bcm)
2493 {
2494         u32 value;
2495         u32 shm_backup;
2496
2497         shm_backup = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0000);
2498         bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, 0x0000, 0xAA5555AA);
2499         if (bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0000) != 0xAA5555AA)
2500                 goto error;
2501         bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, 0x0000, 0x55AAAA55);
2502         if (bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0000) != 0x55AAAA55)
2503                 goto error;
2504         bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, 0x0000, shm_backup);
2505
2506         value = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2507         if ((value | 0x80000000) != 0x80000400)
2508                 goto error;
2509
2510         value = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
2511         if (value != 0x00000000)
2512                 goto error;
2513
2514         return 0;
2515 error:
2516         printk(KERN_ERR PFX "Failed to validate the chipaccess\n");
2517         return -ENODEV;
2518 }
2519
2520 static void bcm43xx_init_struct_phyinfo(struct bcm43xx_phyinfo *phy)
2521 {
2522         /* Initialize a "phyinfo" structure. The structure is already
2523          * zeroed out.
2524          * This is called on insmod time to initialize members.
2525          */
2526         phy->savedpctlreg = 0xFFFF;
2527         spin_lock_init(&phy->lock);
2528 }
2529
2530 static void bcm43xx_init_struct_radioinfo(struct bcm43xx_radioinfo *radio)
2531 {
2532         /* Initialize a "radioinfo" structure. The structure is already
2533          * zeroed out.
2534          * This is called on insmod time to initialize members.
2535          */
2536         radio->interfmode = BCM43xx_RADIO_INTERFMODE_NONE;
2537         radio->channel = 0xFF;
2538         radio->initial_channel = 0xFF;
2539 }
2540
2541 static int bcm43xx_probe_cores(struct bcm43xx_private *bcm)
2542 {
2543         int err, i;
2544         int current_core;
2545         u32 core_vendor, core_id, core_rev;
2546         u32 sb_id_hi, chip_id_32 = 0;
2547         u16 pci_device, chip_id_16;
2548         u8 core_count;
2549
2550         memset(&bcm->core_chipcommon, 0, sizeof(struct bcm43xx_coreinfo));
2551         memset(&bcm->core_pci, 0, sizeof(struct bcm43xx_coreinfo));
2552         memset(&bcm->core_80211, 0, sizeof(struct bcm43xx_coreinfo)
2553                                     * BCM43xx_MAX_80211_CORES);
2554         memset(&bcm->core_80211_ext, 0, sizeof(struct bcm43xx_coreinfo_80211)
2555                                         * BCM43xx_MAX_80211_CORES);
2556         bcm->nr_80211_available = 0;
2557         bcm->current_core = NULL;
2558         bcm->active_80211_core = NULL;
2559
2560         /* map core 0 */
2561         err = _switch_core(bcm, 0);
2562         if (err)
2563                 goto out;
2564
2565         /* fetch sb_id_hi from core information registers */
2566         sb_id_hi = bcm43xx_read32(bcm, BCM43xx_CIR_SB_ID_HI);
2567
2568         core_id = (sb_id_hi & 0xFFF0) >> 4;
2569         core_rev = (sb_id_hi & 0xF);
2570         core_vendor = (sb_id_hi & 0xFFFF0000) >> 16;
2571
2572         /* if present, chipcommon is always core 0; read the chipid from it */
2573         if (core_id == BCM43xx_COREID_CHIPCOMMON) {
2574                 chip_id_32 = bcm43xx_read32(bcm, 0);
2575                 chip_id_16 = chip_id_32 & 0xFFFF;
2576                 bcm->core_chipcommon.available = 1;
2577                 bcm->core_chipcommon.id = core_id;
2578                 bcm->core_chipcommon.rev = core_rev;
2579                 bcm->core_chipcommon.index = 0;
2580                 /* While we are at it, also read the capabilities. */
2581                 bcm->chipcommon_capabilities = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_CAPABILITIES);
2582         } else {
2583                 /* without a chipCommon, use a hard coded table. */
2584                 pci_device = bcm->pci_dev->device;
2585                 if (pci_device == 0x4301)
2586                         chip_id_16 = 0x4301;
2587                 else if ((pci_device >= 0x4305) && (pci_device <= 0x4307))
2588                         chip_id_16 = 0x4307;
2589                 else if ((pci_device >= 0x4402) && (pci_device <= 0x4403))
2590                         chip_id_16 = 0x4402;
2591                 else if ((pci_device >= 0x4610) && (pci_device <= 0x4615))
2592                         chip_id_16 = 0x4610;
2593                 else if ((pci_device >= 0x4710) && (pci_device <= 0x4715))
2594                         chip_id_16 = 0x4710;
2595 #ifdef CONFIG_BCM947XX
2596                 else if ((pci_device >= 0x4320) && (pci_device <= 0x4325))
2597                         chip_id_16 = 0x4309;
2598 #endif
2599                 else {
2600                         printk(KERN_ERR PFX "Could not determine Chip ID\n");
2601                         return -ENODEV;
2602                 }
2603         }
2604
2605         /* ChipCommon with Core Rev >=4 encodes number of cores,
2606          * otherwise consult hardcoded table */
2607         if ((core_id == BCM43xx_COREID_CHIPCOMMON) && (core_rev >= 4)) {
2608                 core_count = (chip_id_32 & 0x0F000000) >> 24;
2609         } else {
2610                 switch (chip_id_16) {
2611                         case 0x4610:
2612                         case 0x4704:
2613                         case 0x4710:
2614                                 core_count = 9;
2615                                 break;
2616                         case 0x4310:
2617                                 core_count = 8;
2618                                 break;
2619                         case 0x5365:
2620                                 core_count = 7;
2621                                 break;
2622                         case 0x4306:
2623                                 core_count = 6;
2624                                 break;
2625                         case 0x4301:
2626                         case 0x4307:
2627                                 core_count = 5;
2628                                 break;
2629                         case 0x4402:
2630                                 core_count = 3;
2631                                 break;
2632                         default:
2633                                 /* SOL if we get here */
2634                                 assert(0);
2635                                 core_count = 1;
2636                 }
2637         }
2638
2639         bcm->chip_id = chip_id_16;
2640         bcm->chip_rev = (chip_id_32 & 0x000F0000) >> 16;
2641         bcm->chip_package = (chip_id_32 & 0x00F00000) >> 20;
2642
2643         dprintk(KERN_INFO PFX "Chip ID 0x%x, rev 0x%x\n",
2644                 bcm->chip_id, bcm->chip_rev);
2645         dprintk(KERN_INFO PFX "Number of cores: %d\n", core_count);
2646         if (bcm->core_chipcommon.available) {
2647                 dprintk(KERN_INFO PFX "Core 0: ID 0x%x, rev 0x%x, vendor 0x%x, %s\n",
2648                         core_id, core_rev, core_vendor,
2649                         bcm43xx_core_enabled(bcm) ? "enabled" : "disabled");
2650         }
2651
2652         if (bcm->core_chipcommon.available)
2653                 current_core = 1;
2654         else
2655                 current_core = 0;
2656         for ( ; current_core < core_count; current_core++) {
2657                 struct bcm43xx_coreinfo *core;
2658                 struct bcm43xx_coreinfo_80211 *ext_80211;
2659
2660                 err = _switch_core(bcm, current_core);
2661                 if (err)
2662                         goto out;
2663                 /* Gather information */
2664                 /* fetch sb_id_hi from core information registers */
2665                 sb_id_hi = bcm43xx_read32(bcm, BCM43xx_CIR_SB_ID_HI);
2666
2667                 /* extract core_id, core_rev, core_vendor */
2668                 core_id = (sb_id_hi & 0xFFF0) >> 4;
2669                 core_rev = (sb_id_hi & 0xF);
2670                 core_vendor = (sb_id_hi & 0xFFFF0000) >> 16;
2671
2672                 dprintk(KERN_INFO PFX "Core %d: ID 0x%x, rev 0x%x, vendor 0x%x, %s\n",
2673                         current_core, core_id, core_rev, core_vendor,
2674                         bcm43xx_core_enabled(bcm) ? "enabled" : "disabled" );
2675
2676                 core = NULL;
2677                 switch (core_id) {
2678                 case BCM43xx_COREID_PCI:
2679                         core = &bcm->core_pci;
2680                         if (core->available) {
2681                                 printk(KERN_WARNING PFX "Multiple PCI cores found.\n");
2682                                 continue;
2683                         }
2684                         break;
2685                 case BCM43xx_COREID_80211:
2686                         for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
2687                                 core = &(bcm->core_80211[i]);
2688                                 ext_80211 = &(bcm->core_80211_ext[i]);
2689                                 if (!core->available)
2690                                         break;
2691                                 core = NULL;
2692                         }
2693                         if (!core) {
2694                                 printk(KERN_WARNING PFX "More than %d cores of type 802.11 found.\n",
2695                                        BCM43xx_MAX_80211_CORES);
2696                                 continue;
2697                         }
2698                         if (i != 0) {
2699                                 /* More than one 80211 core is only supported
2700                                  * by special chips.
2701                                  * There are chips with two 80211 cores, but with
2702                                  * dangling pins on the second core. Be careful
2703                                  * and ignore these cores here.
2704                                  */
2705                                 if (bcm->pci_dev->device != 0x4324) {
2706                                         dprintk(KERN_INFO PFX "Ignoring additional 802.11 core.\n");
2707                                         continue;
2708                                 }
2709                         }
2710                         switch (core_rev) {
2711                         case 2:
2712                         case 4:
2713                         case 5:
2714                         case 6:
2715                         case 7:
2716                         case 9:
2717                                 break;
2718                         default:
2719                                 printk(KERN_ERR PFX "Error: Unsupported 80211 core revision %u\n",
2720                                        core_rev);
2721                                 err = -ENODEV;
2722                                 goto out;
2723                         }
2724                         bcm->nr_80211_available++;
2725                         core->priv = ext_80211;
2726                         bcm43xx_init_struct_phyinfo(&ext_80211->phy);
2727                         bcm43xx_init_struct_radioinfo(&ext_80211->radio);
2728                         break;
2729                 case BCM43xx_COREID_CHIPCOMMON:
2730                         printk(KERN_WARNING PFX "Multiple CHIPCOMMON cores found.\n");
2731                         break;
2732                 }
2733                 if (core) {
2734                         core->available = 1;
2735                         core->id = core_id;
2736                         core->rev = core_rev;
2737                         core->index = current_core;
2738                 }
2739         }
2740
2741         if (!bcm->core_80211[0].available) {
2742                 printk(KERN_ERR PFX "Error: No 80211 core found!\n");
2743                 err = -ENODEV;
2744                 goto out;
2745         }
2746
2747         err = bcm43xx_switch_core(bcm, &bcm->core_80211[0]);
2748
2749         assert(err == 0);
2750 out:
2751         return err;
2752 }
2753
2754 static void bcm43xx_gen_bssid(struct bcm43xx_private *bcm)
2755 {
2756         const u8 *mac = (const u8*)(bcm->net_dev->dev_addr);
2757         u8 *bssid = bcm->ieee->bssid;
2758
2759         switch (bcm->ieee->iw_mode) {
2760         case IW_MODE_ADHOC:
2761                 random_ether_addr(bssid);
2762                 break;
2763         case IW_MODE_MASTER:
2764         case IW_MODE_INFRA:
2765         case IW_MODE_REPEAT:
2766         case IW_MODE_SECOND:
2767         case IW_MODE_MONITOR:
2768                 memcpy(bssid, mac, ETH_ALEN);
2769                 break;
2770         default:
2771                 assert(0);
2772         }
2773 }
2774
2775 static void bcm43xx_rate_memory_write(struct bcm43xx_private *bcm,
2776                                       u16 rate,
2777                                       int is_ofdm)
2778 {
2779         u16 offset;
2780
2781         if (is_ofdm) {
2782                 offset = 0x480;
2783                 offset += (bcm43xx_plcp_get_ratecode_ofdm(rate) & 0x000F) * 2;
2784         }
2785         else {
2786                 offset = 0x4C0;
2787                 offset += (bcm43xx_plcp_get_ratecode_cck(rate) & 0x000F) * 2;
2788         }
2789         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, offset + 0x20,
2790                             bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, offset));
2791 }
2792
2793 static void bcm43xx_rate_memory_init(struct bcm43xx_private *bcm)
2794 {
2795         switch (bcm43xx_current_phy(bcm)->type) {
2796         case BCM43xx_PHYTYPE_A:
2797         case BCM43xx_PHYTYPE_G:
2798                 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_6MB, 1);
2799                 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_12MB, 1);
2800                 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_18MB, 1);
2801                 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_24MB, 1);
2802                 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_36MB, 1);
2803                 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_48MB, 1);
2804                 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_54MB, 1);
2805         case BCM43xx_PHYTYPE_B:
2806                 bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_1MB, 0);
2807                 bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_2MB, 0);
2808                 bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_5MB, 0);
2809                 bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_11MB, 0);
2810                 break;
2811         default:
2812                 assert(0);
2813         }
2814 }
2815
2816 static void bcm43xx_wireless_core_cleanup(struct bcm43xx_private *bcm)
2817 {
2818         bcm43xx_chip_cleanup(bcm);
2819         bcm43xx_pio_free(bcm);
2820         bcm43xx_dma_free(bcm);
2821
2822         bcm->current_core->initialized = 0;
2823 }
2824
2825 /* http://bcm-specs.sipsolutions.net/80211Init */
2826 static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm,
2827                                       int active_wlcore)
2828 {
2829         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
2830         struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
2831         u32 ucodeflags;
2832         int err;
2833         u32 sbimconfiglow;
2834         u8 limit;
2835
2836         if (bcm->chip_rev < 5) {
2837                 sbimconfiglow = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW);
2838                 sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK;
2839                 sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK;
2840                 if (bcm->bustype == BCM43xx_BUSTYPE_PCI)
2841                         sbimconfiglow |= 0x32;
2842                 else if (bcm->bustype == BCM43xx_BUSTYPE_SB)
2843                         sbimconfiglow |= 0x53;
2844                 else
2845                         assert(0);
2846                 bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, sbimconfiglow);
2847         }
2848
2849         bcm43xx_phy_calibrate(bcm);
2850         err = bcm43xx_chip_init(bcm);
2851         if (err)
2852                 goto out;
2853
2854         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0016, bcm->current_core->rev);
2855         ucodeflags = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, BCM43xx_UCODEFLAGS_OFFSET);
2856
2857         if (0 /*FIXME: which condition has to be used here? */)
2858                 ucodeflags |= 0x00000010;
2859
2860         /* HW decryption needs to be set now */
2861         ucodeflags |= 0x40000000;
2862         
2863         if (phy->type == BCM43xx_PHYTYPE_G) {
2864                 ucodeflags |= BCM43xx_UCODEFLAG_UNKBGPHY;
2865                 if (phy->rev == 1)
2866                         ucodeflags |= BCM43xx_UCODEFLAG_UNKGPHY;
2867                 if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL)
2868                         ucodeflags |= BCM43xx_UCODEFLAG_UNKPACTRL;
2869         } else if (phy->type == BCM43xx_PHYTYPE_B) {
2870                 ucodeflags |= BCM43xx_UCODEFLAG_UNKBGPHY;
2871                 if (phy->rev >= 2 && radio->version == 0x2050)
2872                         ucodeflags &= ~BCM43xx_UCODEFLAG_UNKGPHY;
2873         }
2874
2875         if (ucodeflags != bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED,
2876                                              BCM43xx_UCODEFLAGS_OFFSET)) {
2877                 bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED,
2878                                     BCM43xx_UCODEFLAGS_OFFSET, ucodeflags);
2879         }
2880
2881         /* Short/Long Retry Limit.
2882          * The retry-limit is a 4-bit counter. Enforce this to avoid overflowing
2883          * the chip-internal counter.
2884          */
2885         limit = limit_value(modparam_short_retry, 0, 0xF);
2886         bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0006, limit);
2887         limit = limit_value(modparam_long_retry, 0, 0xF);
2888         bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0007, limit);
2889
2890         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0044, 3);
2891         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0046, 2);
2892
2893         bcm43xx_rate_memory_init(bcm);
2894
2895         /* Minimum Contention Window */
2896         if (phy->type == BCM43xx_PHYTYPE_B)
2897                 bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0003, 0x0000001f);
2898         else
2899                 bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0003, 0x0000000f);
2900         /* Maximum Contention Window */
2901         bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0004, 0x000003ff);
2902
2903         bcm43xx_gen_bssid(bcm);
2904         bcm43xx_write_mac_bssid_templates(bcm);
2905
2906         if (bcm->current_core->rev >= 5)
2907                 bcm43xx_write16(bcm, 0x043C, 0x000C);
2908
2909         if (active_wlcore) {
2910                 if (bcm43xx_using_pio(bcm))
2911                         err = bcm43xx_pio_init(bcm);
2912                 else
2913                         err = bcm43xx_dma_init(bcm);
2914                 if (err)
2915                         goto err_chip_cleanup;
2916         }
2917         bcm43xx_write16(bcm, 0x0612, 0x0050);
2918         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0416, 0x0050);
2919         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0414, 0x01F4);
2920
2921         if (active_wlcore) {
2922                 if (radio->initial_channel != 0xFF)
2923                         bcm43xx_radio_selectchannel(bcm, radio->initial_channel, 0);
2924         }
2925
2926         /* Don't enable MAC/IRQ here, as it will race with the IRQ handler.
2927          * We enable it later.
2928          */
2929         bcm->current_core->initialized = 1;
2930 out:
2931         return err;
2932
2933 err_chip_cleanup:
2934         bcm43xx_chip_cleanup(bcm);
2935         goto out;
2936 }
2937
2938 static int bcm43xx_chipset_attach(struct bcm43xx_private *bcm)
2939 {
2940         int err;
2941         u16 pci_status;
2942
2943         err = bcm43xx_pctl_set_crystal(bcm, 1);
2944         if (err)
2945                 goto out;
2946         bcm43xx_pci_read_config16(bcm, PCI_STATUS, &pci_status);
2947         bcm43xx_pci_write_config16(bcm, PCI_STATUS, pci_status & ~PCI_STATUS_SIG_TARGET_ABORT);
2948
2949 out:
2950         return err;
2951 }
2952
2953 static void bcm43xx_chipset_detach(struct bcm43xx_private *bcm)
2954 {
2955         bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_SLOW);
2956         bcm43xx_pctl_set_crystal(bcm, 0);
2957 }
2958
2959 static void bcm43xx_pcicore_broadcast_value(struct bcm43xx_private *bcm,
2960                                             u32 address,
2961                                             u32 data)
2962 {
2963         bcm43xx_write32(bcm, BCM43xx_PCICORE_BCAST_ADDR, address);
2964         bcm43xx_write32(bcm, BCM43xx_PCICORE_BCAST_DATA, data);
2965 }
2966
2967 static int bcm43xx_pcicore_commit_settings(struct bcm43xx_private *bcm)
2968 {
2969         int err;
2970         struct bcm43xx_coreinfo *old_core;
2971
2972         old_core = bcm->current_core;
2973         err = bcm43xx_switch_core(bcm, &bcm->core_pci);
2974         if (err)
2975                 goto out;
2976
2977         bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000);
2978
2979         bcm43xx_switch_core(bcm, old_core);
2980         assert(err == 0);
2981 out:
2982         return err;
2983 }
2984
2985 /* Make an I/O Core usable. "core_mask" is the bitmask of the cores to enable.
2986  * To enable core 0, pass a core_mask of 1<<0
2987  */
2988 static int bcm43xx_setup_backplane_pci_connection(struct bcm43xx_private *bcm,
2989                                                   u32 core_mask)
2990 {
2991         u32 backplane_flag_nr;
2992         u32 value;
2993         struct bcm43xx_coreinfo *old_core;
2994         int err = 0;
2995
2996         value = bcm43xx_read32(bcm, BCM43xx_CIR_SBTPSFLAG);
2997         backplane_flag_nr = value & BCM43xx_BACKPLANE_FLAG_NR_MASK;
2998
2999         old_core = bcm->current_core;
3000         err = bcm43xx_switch_core(bcm, &bcm->core_pci);
3001         if (err)
3002                 goto out;
3003
3004         if (bcm->core_pci.rev < 6) {
3005                 value = bcm43xx_read32(bcm, BCM43xx_CIR_SBINTVEC);
3006                 value |= (1 << backplane_flag_nr);
3007                 bcm43xx_write32(bcm, BCM43xx_CIR_SBINTVEC, value);
3008         } else {
3009                 err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCICFG_ICR, &value);
3010                 if (err) {
3011                         printk(KERN_ERR PFX "Error: ICR setup failure!\n");
3012                         goto out_switch_back;
3013                 }
3014                 value |= core_mask << 8;
3015                 err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_ICR, value);
3016                 if (err) {
3017                         printk(KERN_ERR PFX "Error: ICR setup failure!\n");
3018                         goto out_switch_back;
3019                 }
3020         }
3021
3022         value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2);
3023         value |= BCM43xx_SBTOPCI2_PREFETCH | BCM43xx_SBTOPCI2_BURST;
3024         bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value);
3025
3026         if (bcm->core_pci.rev < 5) {
3027                 value = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW);
3028                 value |= (2 << BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT)
3029                          & BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK;
3030                 value |= (3 << BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT)
3031                          & BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK;
3032                 bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, value);
3033                 err = bcm43xx_pcicore_commit_settings(bcm);
3034                 assert(err == 0);
3035         }
3036
3037 out_switch_back:
3038         err = bcm43xx_switch_core(bcm, old_core);
3039 out:
3040         return err;
3041 }
3042
3043 static void bcm43xx_periodic_every120sec(struct bcm43xx_private *bcm)
3044 {
3045         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
3046
3047         if (phy->type != BCM43xx_PHYTYPE_G || phy->rev < 2)
3048                 return;
3049
3050         bcm43xx_mac_suspend(bcm);
3051         bcm43xx_phy_lo_g_measure(bcm);
3052         bcm43xx_mac_enable(bcm);
3053 }
3054
3055 static void bcm43xx_periodic_every60sec(struct bcm43xx_private *bcm)
3056 {
3057         bcm43xx_phy_lo_mark_all_unused(bcm);
3058         if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) {
3059                 bcm43xx_mac_suspend(bcm);
3060                 bcm43xx_calc_nrssi_slope(bcm);
3061                 bcm43xx_mac_enable(bcm);
3062         }
3063 }
3064
3065 static void bcm43xx_periodic_every30sec(struct bcm43xx_private *bcm)
3066 {
3067         /* Update device statistics. */
3068         bcm43xx_calculate_link_quality(bcm);
3069 }
3070
3071 static void bcm43xx_periodic_every15sec(struct bcm43xx_private *bcm)
3072 {
3073         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
3074         struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
3075
3076         if (phy->type == BCM43xx_PHYTYPE_G) {
3077                 //TODO: update_aci_moving_average
3078                 if (radio->aci_enable && radio->aci_wlan_automatic) {
3079                         bcm43xx_mac_suspend(bcm);
3080                         if (!radio->aci_enable && 1 /*TODO: not scanning? */) {
3081                                 if (0 /*TODO: bunch of conditions*/) {
3082                                         bcm43xx_radio_set_interference_mitigation(bcm,
3083                                                                                   BCM43xx_RADIO_INTERFMODE_MANUALWLAN);
3084                                 }
3085                         } else if (1/*TODO*/) {
3086                                 /*
3087                                 if ((aci_average > 1000) && !(bcm43xx_radio_aci_scan(bcm))) {
3088                                         bcm43xx_radio_set_interference_mitigation(bcm,
3089                                                                                   BCM43xx_RADIO_INTERFMODE_NONE);
3090                                 }
3091                                 */
3092                         }
3093                         bcm43xx_mac_enable(bcm);
3094                 } else if (radio->interfmode == BCM43xx_RADIO_INTERFMODE_NONWLAN &&
3095                            phy->rev == 1) {
3096                         //TODO: implement rev1 workaround
3097                 }
3098         }
3099         bcm43xx_phy_xmitpower(bcm); //FIXME: unless scanning?
3100         //TODO for APHY (temperature?)
3101 }
3102
3103 static void do_periodic_work(struct bcm43xx_private *bcm)
3104 {
3105         unsigned int state;
3106
3107         state = bcm->periodic_state;
3108         if (state % 8 == 0)
3109                 bcm43xx_periodic_every120sec(bcm);
3110         if (state % 4 == 0)
3111                 bcm43xx_periodic_every60sec(bcm);
3112         if (state % 2 == 0)
3113                 bcm43xx_periodic_every30sec(bcm);
3114         if (state % 1 == 0)
3115                 bcm43xx_periodic_every15sec(bcm);
3116         bcm->periodic_state = state + 1;
3117
3118         schedule_delayed_work(&bcm->periodic_work, HZ * 15);
3119 }
3120
3121 /* Estimate a "Badness" value based on the periodic work
3122  * state-machine state. "Badness" is worse (bigger), if the
3123  * periodic work will take longer.
3124  */
3125 static int estimate_periodic_work_badness(unsigned int state)
3126 {
3127         int badness = 0;
3128
3129         if (state % 8 == 0) /* every 120 sec */
3130                 badness += 10;
3131         if (state % 4 == 0) /* every 60 sec */
3132                 badness += 5;
3133         if (state % 2 == 0) /* every 30 sec */
3134                 badness += 1;
3135         if (state % 1 == 0) /* every 15 sec */
3136                 badness += 1;
3137
3138 #define BADNESS_LIMIT   4
3139         return badness;
3140 }
3141
3142 static void bcm43xx_periodic_work_handler(void *d)
3143 {
3144         struct bcm43xx_private *bcm = d;
3145         unsigned long flags;
3146         u32 savedirqs = 0;
3147         int badness;
3148
3149         badness = estimate_periodic_work_badness(bcm->periodic_state);
3150         if (badness > BADNESS_LIMIT) {
3151                 /* Periodic work will take a long time, so we want it to
3152                  * be preemtible.
3153                  */
3154                 mutex_lock(&bcm->mutex);
3155                 netif_stop_queue(bcm->net_dev);
3156                 synchronize_net();
3157                 spin_lock_irqsave(&bcm->irq_lock, flags);
3158                 bcm43xx_mac_suspend(bcm);
3159                 if (bcm43xx_using_pio(bcm))
3160                         bcm43xx_pio_freeze_txqueues(bcm);
3161                 savedirqs = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3162                 spin_unlock_irqrestore(&bcm->irq_lock, flags);
3163                 bcm43xx_synchronize_irq(bcm);
3164         } else {
3165                 /* Periodic work should take short time, so we want low
3166                  * locking overhead.
3167                  */
3168                 mutex_lock(&bcm->mutex);
3169                 spin_lock_irqsave(&bcm->irq_lock, flags);
3170         }
3171
3172         do_periodic_work(bcm);
3173
3174         if (badness > BADNESS_LIMIT) {
3175                 spin_lock_irqsave(&bcm->irq_lock, flags);
3176                 tasklet_enable(&bcm->isr_tasklet);
3177                 bcm43xx_interrupt_enable(bcm, savedirqs);
3178                 if (bcm43xx_using_pio(bcm))
3179                         bcm43xx_pio_thaw_txqueues(bcm);
3180                 bcm43xx_mac_enable(bcm);
3181                 netif_wake_queue(bcm->net_dev);
3182         }
3183         mmiowb();
3184         spin_unlock_irqrestore(&bcm->irq_lock, flags);
3185         mutex_unlock(&bcm->mutex);
3186 }
3187
3188 void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm)
3189 {
3190         cancel_rearming_delayed_work(&bcm->periodic_work);
3191 }
3192
3193 void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm)
3194 {
3195         struct work_struct *work = &(bcm->periodic_work);
3196
3197         assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
3198         INIT_WORK(work, bcm43xx_periodic_work_handler, bcm);
3199         schedule_work(work);
3200 }
3201
3202 static void bcm43xx_security_init(struct bcm43xx_private *bcm)
3203 {
3204         bcm->security_offset = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
3205                                                   0x0056) * 2;
3206         bcm43xx_clear_keys(bcm);
3207 }
3208
3209 static int bcm43xx_rng_read(struct hwrng *rng, u32 *data)
3210 {
3211         struct bcm43xx_private *bcm = (struct bcm43xx_private *)rng->priv;
3212         unsigned long flags;
3213
3214         spin_lock_irqsave(&(bcm)->irq_lock, flags);
3215         *data = bcm43xx_read16(bcm, BCM43xx_MMIO_RNG);
3216         spin_unlock_irqrestore(&(bcm)->irq_lock, flags);
3217
3218         return (sizeof(u16));
3219 }
3220
3221 static void bcm43xx_rng_exit(struct bcm43xx_private *bcm)
3222 {
3223         hwrng_unregister(&bcm->rng);
3224 }
3225
3226 static int bcm43xx_rng_init(struct bcm43xx_private *bcm)
3227 {
3228         int err;
3229
3230         snprintf(bcm->rng_name, ARRAY_SIZE(bcm->rng_name),
3231                  "%s_%s", KBUILD_MODNAME, bcm->net_dev->name);
3232         bcm->rng.name = bcm->rng_name;
3233         bcm->rng.data_read = bcm43xx_rng_read;
3234         bcm->rng.priv = (unsigned long)bcm;
3235         err = hwrng_register(&bcm->rng);
3236         if (err)
3237                 printk(KERN_ERR PFX "RNG init failed (%d)\n", err);
3238
3239         return err;
3240 }
3241
3242 static int bcm43xx_shutdown_all_wireless_cores(struct bcm43xx_private *bcm)
3243 {
3244         int ret = 0;
3245         int i, err;
3246         struct bcm43xx_coreinfo *core;
3247
3248         bcm43xx_set_status(bcm, BCM43xx_STAT_SHUTTINGDOWN);
3249         for (i = 0; i < bcm->nr_80211_available; i++) {
3250                 core = &(bcm->core_80211[i]);
3251                 assert(core->available);
3252                 if (!core->initialized)
3253                         continue;
3254                 err = bcm43xx_switch_core(bcm, core);
3255                 if (err) {
3256                         dprintk(KERN_ERR PFX "shutdown_all_wireless_cores "
3257                                              "switch_core failed (%d)\n", err);
3258                         ret = err;
3259                         continue;
3260                 }
3261                 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3262                 bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
3263                 bcm43xx_wireless_core_cleanup(bcm);
3264                 if (core == bcm->active_80211_core)
3265                         bcm->active_80211_core = NULL;
3266         }
3267         free_irq(bcm->irq, bcm);
3268         bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
3269
3270         return ret;
3271 }
3272
3273 /* This is the opposite of bcm43xx_init_board() */
3274 static void bcm43xx_free_board(struct bcm43xx_private *bcm)
3275 {
3276         bcm43xx_rng_exit(bcm);
3277         bcm43xx_sysfs_unregister(bcm);
3278         bcm43xx_periodic_tasks_delete(bcm);
3279
3280         mutex_lock(&(bcm)->mutex);
3281         bcm43xx_shutdown_all_wireless_cores(bcm);
3282         bcm43xx_pctl_set_crystal(bcm, 0);
3283         mutex_unlock(&(bcm)->mutex);
3284 }
3285
3286 static void prepare_phydata_for_init(struct bcm43xx_phyinfo *phy)
3287 {
3288         phy->antenna_diversity = 0xFFFF;
3289         memset(phy->minlowsig, 0xFF, sizeof(phy->minlowsig));
3290         memset(phy->minlowsigpos, 0, sizeof(phy->minlowsigpos));
3291
3292         /* Flags */
3293         phy->calibrated = 0;
3294         phy->is_locked = 0;
3295
3296         if (phy->_lo_pairs) {
3297                 memset(phy->_lo_pairs, 0,
3298                        sizeof(struct bcm43xx_lopair) * BCM43xx_LO_COUNT);
3299         }
3300         memset(phy->loopback_gain, 0, sizeof(phy->loopback_gain));
3301 }
3302
3303 static void prepare_radiodata_for_init(struct bcm43xx_private *bcm,
3304                                        struct bcm43xx_radioinfo *radio)
3305 {
3306         int i;
3307
3308         /* Set default attenuation values. */
3309         radio->baseband_atten = bcm43xx_default_baseband_attenuation(bcm);
3310         radio->radio_atten = bcm43xx_default_radio_attenuation(bcm);
3311         radio->txctl1 = bcm43xx_default_txctl1(bcm);
3312         radio->txctl2 = 0xFFFF;
3313         radio->txpwr_offset = 0;
3314
3315         /* NRSSI */
3316         radio->nrssislope = 0;
3317         for (i = 0; i < ARRAY_SIZE(radio->nrssi); i++)
3318                 radio->nrssi[i] = -1000;
3319         for (i = 0; i < ARRAY_SIZE(radio->nrssi_lt); i++)
3320                 radio->nrssi_lt[i] = i;
3321
3322         radio->lofcal = 0xFFFF;
3323         radio->initval = 0xFFFF;
3324
3325         radio->aci_enable = 0;
3326         radio->aci_wlan_automatic = 0;
3327         radio->aci_hw_rssi = 0;
3328 }
3329
3330 static void prepare_priv_for_init(struct bcm43xx_private *bcm)
3331 {
3332         int i;
3333         struct bcm43xx_coreinfo *core;
3334         struct bcm43xx_coreinfo_80211 *wlext;
3335
3336         assert(!bcm->active_80211_core);
3337
3338         bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING);
3339
3340         /* Flags */
3341         bcm->was_initialized = 0;
3342         bcm->reg124_set_0x4 = 0;
3343
3344         /* Stats */
3345         memset(&bcm->stats, 0, sizeof(bcm->stats));
3346
3347         /* Wireless core data */
3348         for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
3349                 core = &(bcm->core_80211[i]);
3350                 wlext = core->priv;
3351
3352                 if (!core->available)
3353                         continue;
3354                 assert(wlext == &(bcm->core_80211_ext[i]));
3355
3356                 prepare_phydata_for_init(&wlext->phy);
3357                 prepare_radiodata_for_init(bcm, &wlext->radio);
3358         }
3359
3360         /* IRQ related flags */
3361         bcm->irq_reason = 0;
3362         memset(bcm->dma_reason, 0, sizeof(bcm->dma_reason));
3363         bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
3364
3365         bcm->mac_suspended = 1;
3366
3367         /* Noise calculation context */
3368         memset(&bcm->noisecalc, 0, sizeof(bcm->noisecalc));
3369
3370         /* Periodic work context */
3371         bcm->periodic_state = 0;
3372 }
3373
3374 static int wireless_core_up(struct bcm43xx_private *bcm,
3375                             int active_wlcore)
3376 {
3377         int err;
3378
3379         if (!bcm43xx_core_enabled(bcm))
3380                 bcm43xx_wireless_core_reset(bcm, 1);
3381         if (!active_wlcore)
3382                 bcm43xx_wireless_core_mark_inactive(bcm);
3383         err = bcm43xx_wireless_core_init(bcm, active_wlcore);
3384         if (err)
3385                 goto out;
3386         if (!active_wlcore)
3387                 bcm43xx_radio_turn_off(bcm);
3388 out:
3389         return err;
3390 }
3391
3392 /* Select and enable the "to be used" wireless core.
3393  * Locking: bcm->mutex must be aquired before calling this.
3394  *          bcm->irq_lock must not be aquired.
3395  */
3396 int bcm43xx_select_wireless_core(struct bcm43xx_private *bcm,
3397                                  int phytype)
3398 {
3399         int i, err;
3400         struct bcm43xx_coreinfo *active_core = NULL;
3401         struct bcm43xx_coreinfo_80211 *active_wlext = NULL;
3402         struct bcm43xx_coreinfo *core;
3403         struct bcm43xx_coreinfo_80211 *wlext;
3404         int adjust_active_sbtmstatelow = 0;
3405
3406         might_sleep();
3407
3408         if (phytype < 0) {
3409                 /* If no phytype is requested, select the first core. */
3410                 assert(bcm->core_80211[0].available);
3411                 wlext = bcm->core_80211[0].priv;
3412                 phytype = wlext->phy.type;
3413         }
3414         /* Find the requested core. */
3415         for (i = 0; i < bcm->nr_80211_available; i++) {
3416                 core = &(bcm->core_80211[i]);
3417                 wlext = core->priv;
3418                 if (wlext->phy.type == phytype) {
3419                         active_core = core;
3420                         active_wlext = wlext;
3421                         break;
3422                 }
3423         }
3424         if (!active_core)
3425                 return -ESRCH; /* No such PHYTYPE on this board. */
3426
3427         if (bcm->active_80211_core) {
3428                 /* We already selected a wl core in the past.
3429                  * So first clean up everything.
3430                  */
3431                 dprintk(KERN_INFO PFX "select_wireless_core: cleanup\n");
3432                 ieee80211softmac_stop(bcm->net_dev);
3433                 bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZED);
3434                 err = bcm43xx_disable_interrupts_sync(bcm);
3435                 assert(!err);
3436                 tasklet_enable(&bcm->isr_tasklet);
3437                 err = bcm43xx_shutdown_all_wireless_cores(bcm);
3438                 if (err)
3439                         goto error;
3440                 /* Ok, everything down, continue to re-initialize. */
3441                 bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING);
3442         }
3443
3444         /* Reset all data structures. */
3445         prepare_priv_for_init(bcm);
3446
3447         err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_FAST);
3448         if (err)
3449                 goto error;
3450
3451         /* Mark all unused cores "inactive". */
3452         for (i = 0; i < bcm->nr_80211_available; i++) {
3453                 core = &(bcm->core_80211[i]);
3454                 wlext = core->priv;
3455
3456                 if (core == active_core)
3457                         continue;
3458                 err = bcm43xx_switch_core(bcm, core);
3459                 if (err) {
3460                         dprintk(KERN_ERR PFX "Could not switch to inactive "
3461                                              "802.11 core (%d)\n", err);
3462                         goto error;
3463                 }
3464                 err = wireless_core_up(bcm, 0);
3465                 if (err) {
3466                         dprintk(KERN_ERR PFX "core_up for inactive 802.11 core "
3467                                              "failed (%d)\n", err);
3468                         goto error;
3469                 }
3470                 adjust_active_sbtmstatelow = 1;
3471         }
3472
3473         /* Now initialize the active 802.11 core. */
3474         err = bcm43xx_switch_core(bcm, active_core);
3475         if (err) {
3476                 dprintk(KERN_ERR PFX "Could not switch to active "
3477                                      "802.11 core (%d)\n", err);
3478                 goto error;
3479         }
3480         if (adjust_active_sbtmstatelow &&
3481             active_wlext->phy.type == BCM43xx_PHYTYPE_G) {
3482                 u32 sbtmstatelow;
3483
3484                 sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
3485                 sbtmstatelow |= 0x20000000;
3486                 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
3487         }
3488         err = wireless_core_up(bcm, 1);
3489         if (err) {
3490                 dprintk(KERN_ERR PFX "core_up for active 802.11 core "
3491                                      "failed (%d)\n", err);
3492                 goto error;
3493         }
3494         err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_DYNAMIC);
3495         if (err)
3496                 goto error;
3497         bcm->active_80211_core = active_core;
3498
3499         bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC);
3500         bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 *)(bcm->net_dev->dev_addr));
3501         bcm43xx_security_init(bcm);
3502         ieee80211softmac_start(bcm->net_dev);
3503
3504         /* Let's go! Be careful after enabling the IRQs.
3505          * Don't switch cores, for example.
3506          */
3507         bcm43xx_mac_enable(bcm);
3508         bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZED);
3509         err = bcm43xx_initialize_irq(bcm);
3510         if (err)
3511                 goto error;
3512         bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
3513
3514         dprintk(KERN_INFO PFX "Selected 802.11 core (phytype %d)\n",
3515                 active_wlext->phy.type);
3516
3517         return 0;
3518
3519 error:
3520         bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
3521         bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_SLOW);
3522         return err;
3523 }
3524
3525 static int bcm43xx_init_board(struct bcm43xx_private *bcm)
3526 {
3527         int err;
3528
3529         mutex_lock(&(bcm)->mutex);
3530
3531         tasklet_enable(&bcm->isr_tasklet);
3532         err = bcm43xx_pctl_set_crystal(bcm, 1);
3533         if (err)
3534                 goto err_tasklet;
3535         err = bcm43xx_pctl_init(bcm);
3536         if (err)
3537                 goto err_crystal_off;
3538         err = bcm43xx_select_wireless_core(bcm, -1);
3539         if (err)
3540                 goto err_crystal_off;
3541         err = bcm43xx_sysfs_register(bcm);
3542         if (err)
3543                 goto err_wlshutdown;
3544         bcm43xx_periodic_tasks_setup(bcm);
3545         err = bcm43xx_rng_init(bcm);
3546         if (err)
3547                 goto err_sysfs_unreg;
3548
3549         /*FIXME: This should be handled by softmac instead. */
3550         schedule_work(&bcm->softmac->associnfo.work);
3551
3552 out:
3553         mutex_unlock(&(bcm)->mutex);
3554
3555         return err;
3556
3557 err_sysfs_unreg:
3558         bcm43xx_sysfs_unregister(bcm);
3559 err_wlshutdown:
3560         bcm43xx_shutdown_all_wireless_cores(bcm);
3561 err_crystal_off:
3562         bcm43xx_pctl_set_crystal(bcm, 0);
3563 err_tasklet:
3564         tasklet_disable(&bcm->isr_tasklet);
3565         goto out;
3566 }
3567
3568 static void bcm43xx_detach_board(struct bcm43xx_private *bcm)
3569 {
3570         struct pci_dev *pci_dev = bcm->pci_dev;
3571         int i;
3572
3573         bcm43xx_chipset_detach(bcm);
3574         /* Do _not_ access the chip, after it is detached. */
3575         pci_iounmap(pci_dev, bcm->mmio_addr);
3576         pci_release_regions(pci_dev);
3577         pci_disable_device(pci_dev);
3578
3579         /* Free allocated structures/fields */
3580         for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
3581                 kfree(bcm->core_80211_ext[i].phy._lo_pairs);
3582                 if (bcm->core_80211_ext[i].phy.dyn_tssi_tbl)
3583                         kfree(bcm->core_80211_ext[i].phy.tssi2dbm);
3584         }
3585 }       
3586
3587 static int bcm43xx_read_phyinfo(struct bcm43xx_private *bcm)
3588 {
3589         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
3590         u16 value;
3591         u8 phy_version;
3592         u8 phy_type;
3593         u8 phy_rev;
3594         int phy_rev_ok = 1;
3595         void *p;
3596
3597         value = bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_VER);
3598
3599         phy_version = (value & 0xF000) >> 12;
3600         phy_type = (value & 0x0F00) >> 8;
3601         phy_rev = (value & 0x000F);
3602
3603         dprintk(KERN_INFO PFX "Detected PHY: Version: %x, Type %x, Revision %x\n",
3604                 phy_version, phy_type, phy_rev);
3605
3606         switch (phy_type) {
3607         case BCM43xx_PHYTYPE_A:
3608                 if (phy_rev >= 4)
3609                         phy_rev_ok = 0;
3610                 /*FIXME: We need to switch the ieee->modulation, etc.. flags,
3611                  *       if we switch 80211 cores after init is done.
3612                  *       As we do not implement on the fly switching between
3613                  *       wireless cores, I will leave this as a future task.
3614                  */
3615                 bcm->ieee->modulation = IEEE80211_OFDM_MODULATION;
3616                 bcm->ieee->mode = IEEE_A;
3617                 bcm->ieee->freq_band = IEEE80211_52GHZ_BAND |
3618                                        IEEE80211_24GHZ_BAND;
3619                 break;
3620         case BCM43xx_PHYTYPE_B:
3621                 if (phy_rev != 2 && phy_rev != 4 && phy_rev != 6 && phy_rev != 7)
3622                         phy_rev_ok = 0;
3623                 bcm->ieee->modulation = IEEE80211_CCK_MODULATION;
3624                 bcm->ieee->mode = IEEE_B;
3625                 bcm->ieee->freq_band = IEEE80211_24GHZ_BAND;
3626                 break;
3627         case BCM43xx_PHYTYPE_G:
3628                 if (phy_rev > 7)
3629                         phy_rev_ok = 0;
3630                 bcm->ieee->modulation = IEEE80211_OFDM_MODULATION |
3631                                         IEEE80211_CCK_MODULATION;
3632                 bcm->ieee->mode = IEEE_G;
3633                 bcm->ieee->freq_band = IEEE80211_24GHZ_BAND;
3634                 break;
3635         default:
3636                 printk(KERN_ERR PFX "Error: Unknown PHY Type %x\n",
3637                        phy_type);
3638                 return -ENODEV;
3639         };
3640         if (!phy_rev_ok) {
3641                 printk(KERN_WARNING PFX "Invalid PHY Revision %x\n",
3642                        phy_rev);
3643         }
3644
3645         phy->version = phy_version;
3646         phy->type = phy_type;
3647         phy->rev = phy_rev;
3648         if ((phy_type == BCM43xx_PHYTYPE_B) || (phy_type == BCM43xx_PHYTYPE_G)) {
3649                 p = kzalloc(sizeof(struct bcm43xx_lopair) * BCM43xx_LO_COUNT,
3650                             GFP_KERNEL);
3651                 if (!p)
3652                         return -ENOMEM;
3653                 phy->_lo_pairs = p;
3654         }
3655
3656         return 0;
3657 }
3658
3659 static int bcm43xx_attach_board(struct bcm43xx_private *bcm)
3660 {
3661         struct pci_dev *pci_dev = bcm->pci_dev;
3662         struct net_device *net_dev = bcm->net_dev;
3663         int err;
3664         int i;
3665         u32 coremask;
3666
3667         err = pci_enable_device(pci_dev);
3668         if (err) {
3669                 printk(KERN_ERR PFX "pci_enable_device() failed\n");
3670                 goto out;
3671         }
3672         err = pci_request_regions(pci_dev, KBUILD_MODNAME);
3673         if (err) {
3674                 printk(KERN_ERR PFX "pci_request_regions() failed\n");
3675                 goto err_pci_disable;
3676         }
3677         /* enable PCI bus-mastering */
3678         pci_set_master(pci_dev);
3679         bcm->mmio_addr = pci_iomap(pci_dev, 0, ~0UL);
3680         if (!bcm->mmio_addr) {
3681                 printk(KERN_ERR PFX "pci_iomap() failed\n");
3682                 err = -EIO;
3683                 goto err_pci_release;
3684         }
3685         net_dev->base_addr = (unsigned long)bcm->mmio_addr;
3686
3687         bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_VENDOR_ID,
3688                                   &bcm->board_vendor);
3689         bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_ID,
3690                                   &bcm->board_type);
3691         bcm43xx_pci_read_config16(bcm, PCI_REVISION_ID,
3692                                   &bcm->board_revision);
3693
3694         err = bcm43xx_chipset_attach(bcm);
3695         if (err)
3696                 goto err_iounmap;
3697         err = bcm43xx_pctl_init(bcm);
3698         if (err)
3699                 goto err_chipset_detach;
3700         err = bcm43xx_probe_cores(bcm);
3701         if (err)
3702                 goto err_chipset_detach;
3703         
3704         /* Attach all IO cores to the backplane. */
3705         coremask = 0;
3706         for (i = 0; i < bcm->nr_80211_available; i++)
3707                 coremask |= (1 << bcm->core_80211[i].index);
3708         //FIXME: Also attach some non80211 cores?
3709         err = bcm43xx_setup_backplane_pci_connection(bcm, coremask);
3710         if (err) {
3711                 printk(KERN_ERR PFX "Backplane->PCI connection failed!\n");
3712                 goto err_chipset_detach;
3713         }
3714
3715         err = bcm43xx_sprom_extract(bcm);
3716         if (err)
3717                 goto err_chipset_detach;
3718         err = bcm43xx_leds_init(bcm);
3719         if (err)
3720                 goto err_chipset_detach;
3721
3722         for (i = 0; i < bcm->nr_80211_available; i++) {
3723                 err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]);
3724                 assert(err != -ENODEV);
3725                 if (err)
3726                         goto err_80211_unwind;
3727
3728                 /* Enable the selected wireless core.
3729                  * Connect PHY only on the first core.
3730                  */
3731                 bcm43xx_wireless_core_reset(bcm, (i == 0));
3732
3733                 err = bcm43xx_read_phyinfo(bcm);
3734                 if (err && (i == 0))
3735                         goto err_80211_unwind;
3736
3737                 err = bcm43xx_read_radioinfo(bcm);
3738                 if (err && (i == 0))
3739                         goto err_80211_unwind;
3740
3741                 err = bcm43xx_validate_chip(bcm);
3742                 if (err && (i == 0))
3743                         goto err_80211_unwind;
3744
3745                 bcm43xx_radio_turn_off(bcm);
3746                 err = bcm43xx_phy_init_tssi2dbm_table(bcm);
3747                 if (err)
3748                         goto err_80211_unwind;
3749                 bcm43xx_wireless_core_disable(bcm);
3750         }
3751         err = bcm43xx_geo_init(bcm);
3752         if (err)
3753                 goto err_80211_unwind;
3754         bcm43xx_pctl_set_crystal(bcm, 0);
3755
3756         /* Set the MAC address in the networking subsystem */
3757         if (is_valid_ether_addr(bcm->sprom.et1macaddr))
3758                 memcpy(bcm->net_dev->dev_addr, bcm->sprom.et1macaddr, 6);
3759         else
3760                 memcpy(bcm->net_dev->dev_addr, bcm->sprom.il0macaddr, 6);
3761
3762         snprintf(bcm->nick, IW_ESSID_MAX_SIZE,
3763                  "Broadcom %04X", bcm->chip_id);
3764
3765         assert(err == 0);
3766 out:
3767         return err;
3768
3769 err_80211_unwind:
3770         for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
3771                 kfree(bcm->core_80211_ext[i].phy._lo_pairs);
3772                 if (bcm->core_80211_ext[i].phy.dyn_tssi_tbl)
3773                         kfree(bcm->core_80211_ext[i].phy.tssi2dbm);
3774         }
3775 err_chipset_detach:
3776         bcm43xx_chipset_detach(bcm);
3777 err_iounmap:
3778         pci_iounmap(pci_dev, bcm->mmio_addr);
3779 err_pci_release:
3780         pci_release_regions(pci_dev);
3781 err_pci_disable:
3782         pci_disable_device(pci_dev);
3783         goto out;
3784 }
3785
3786 /* Do the Hardware IO operations to send the txb */
3787 static inline int bcm43xx_tx(struct bcm43xx_private *bcm,
3788                              struct ieee80211_txb *txb)
3789 {
3790         int err = -ENODEV;
3791
3792         if (bcm43xx_using_pio(bcm))
3793                 err = bcm43xx_pio_tx(bcm, txb);
3794         else
3795                 err = bcm43xx_dma_tx(bcm, txb);
3796         bcm->net_dev->trans_start = jiffies;
3797
3798         return err;
3799 }
3800
3801 static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev,
3802                                        u8 channel)
3803 {
3804         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3805         struct bcm43xx_radioinfo *radio;
3806         unsigned long flags;
3807
3808         mutex_lock(&bcm->mutex);
3809         spin_lock_irqsave(&bcm->irq_lock, flags);
3810         if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
3811                 bcm43xx_mac_suspend(bcm);
3812                 bcm43xx_radio_selectchannel(bcm, channel, 0);
3813                 bcm43xx_mac_enable(bcm);
3814         } else {
3815                 radio = bcm43xx_current_radio(bcm);
3816                 radio->initial_channel = channel;
3817         }
3818         spin_unlock_irqrestore(&bcm->irq_lock, flags);
3819         mutex_unlock(&bcm->mutex);
3820 }
3821
3822 /* set_security() callback in struct ieee80211_device */
3823 static void bcm43xx_ieee80211_set_security(struct net_device *net_dev,
3824                                            struct ieee80211_security *sec)
3825 {
3826         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3827         struct ieee80211_security *secinfo = &bcm->ieee->sec;
3828         unsigned long flags;
3829         int keyidx;
3830         
3831         dprintk(KERN_INFO PFX "set security called");
3832
3833         mutex_lock(&bcm->mutex);
3834         spin_lock_irqsave(&bcm->irq_lock, flags);
3835
3836         for (keyidx = 0; keyidx<WEP_KEYS; keyidx++)
3837                 if (sec->flags & (1<<keyidx)) {
3838                         secinfo->encode_alg[keyidx] = sec->encode_alg[keyidx];
3839                         secinfo->key_sizes[keyidx] = sec->key_sizes[keyidx];
3840                         memcpy(secinfo->keys[keyidx], sec->keys[keyidx], SCM_KEY_LEN);
3841                 }
3842         
3843         if (sec->flags & SEC_ACTIVE_KEY) {
3844                 secinfo->active_key = sec->active_key;
3845                 dprintk(", .active_key = %d", sec->active_key);
3846         }
3847         if (sec->flags & SEC_UNICAST_GROUP) {
3848                 secinfo->unicast_uses_group = sec->unicast_uses_group;
3849                 dprintk(", .unicast_uses_group = %d", sec->unicast_uses_group);
3850         }
3851         if (sec->flags & SEC_LEVEL) {
3852                 secinfo->level = sec->level;
3853                 dprintk(", .level = %d", sec->level);
3854         }
3855         if (sec->flags & SEC_ENABLED) {
3856                 secinfo->enabled = sec->enabled;
3857                 dprintk(", .enabled = %d", sec->enabled);
3858         }
3859         if (sec->flags & SEC_ENCRYPT) {
3860                 secinfo->encrypt = sec->encrypt;
3861                 dprintk(", .encrypt = %d", sec->encrypt);
3862         }
3863         if (sec->flags & SEC_AUTH_MODE) {
3864                 secinfo->auth_mode = sec->auth_mode;
3865                 dprintk(", .auth_mode = %d", sec->auth_mode);
3866         }
3867         dprintk("\n");
3868         if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED &&
3869             !bcm->ieee->host_encrypt) {
3870                 if (secinfo->enabled) {
3871                         /* upload WEP keys to hardware */
3872                         char null_address[6] = { 0 };
3873                         u8 algorithm = 0;
3874                         for (keyidx = 0; keyidx<WEP_KEYS; keyidx++) {
3875                                 if (!(sec->flags & (1<<keyidx)))
3876                                         continue;
3877                                 switch (sec->encode_alg[keyidx]) {
3878                                         case SEC_ALG_NONE: algorithm = BCM43xx_SEC_ALGO_NONE; break;
3879                                         case SEC_ALG_WEP:
3880                                                 algorithm = BCM43xx_SEC_ALGO_WEP;
3881                                                 if (secinfo->key_sizes[keyidx] == 13)
3882                                                         algorithm = BCM43xx_SEC_ALGO_WEP104;
3883                                                 break;
3884                                         case SEC_ALG_TKIP:
3885                                                 FIXME();
3886                                                 algorithm = BCM43xx_SEC_ALGO_TKIP;
3887                                                 break;
3888                                         case SEC_ALG_CCMP:
3889                                                 FIXME();
3890                                                 algorithm = BCM43xx_SEC_ALGO_AES;
3891                                                 break;
3892                                         default:
3893                                                 assert(0);
3894                                                 break;
3895                                 }
3896                                 bcm43xx_key_write(bcm, keyidx, algorithm, sec->keys[keyidx], secinfo->key_sizes[keyidx], &null_address[0]);
3897                                 bcm->key[keyidx].enabled = 1;
3898                                 bcm->key[keyidx].algorithm = algorithm;
3899                         }
3900                 } else
3901                                 bcm43xx_clear_keys(bcm);
3902         }
3903         spin_unlock_irqrestore(&bcm->irq_lock, flags);
3904         mutex_unlock(&bcm->mutex);
3905 }
3906
3907 /* hard_start_xmit() callback in struct ieee80211_device */
3908 static int bcm43xx_ieee80211_hard_start_xmit(struct ieee80211_txb *txb,
3909                                              struct net_device *net_dev,
3910                                              int pri)
3911 {
3912         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3913         int err = -ENODEV;
3914         unsigned long flags;
3915
3916         spin_lock_irqsave(&bcm->irq_lock, flags);
3917         if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED))
3918                 err = bcm43xx_tx(bcm, txb);
3919         spin_unlock_irqrestore(&bcm->irq_lock, flags);
3920
3921         if (unlikely(err))
3922                 return NETDEV_TX_BUSY;
3923         return NETDEV_TX_OK;
3924 }
3925
3926 static struct net_device_stats * bcm43xx_net_get_stats(struct net_device *net_dev)
3927 {
3928         return &(bcm43xx_priv(net_dev)->ieee->stats);
3929 }
3930
3931 static void bcm43xx_net_tx_timeout(struct net_device *net_dev)
3932 {
3933         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3934         unsigned long flags;
3935
3936         spin_lock_irqsave(&bcm->irq_lock, flags);
3937         bcm43xx_controller_restart(bcm, "TX timeout");
3938         spin_unlock_irqrestore(&bcm->irq_lock, flags);
3939 }
3940
3941 #ifdef CONFIG_NET_POLL_CONTROLLER
3942 static void bcm43xx_net_poll_controller(struct net_device *net_dev)
3943 {
3944         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3945         unsigned long flags;
3946
3947         local_irq_save(flags);
3948         if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
3949                 bcm43xx_interrupt_handler(bcm->irq, bcm, NULL);
3950         local_irq_restore(flags);
3951 }
3952 #endif /* CONFIG_NET_POLL_CONTROLLER */
3953
3954 static int bcm43xx_net_open(struct net_device *net_dev)
3955 {
3956         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3957
3958         return bcm43xx_init_board(bcm);
3959 }
3960
3961 static int bcm43xx_net_stop(struct net_device *net_dev)
3962 {
3963         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3964         int err;
3965
3966         ieee80211softmac_stop(net_dev);
3967         err = bcm43xx_disable_interrupts_sync(bcm);
3968         assert(!err);
3969         bcm43xx_free_board(bcm);
3970         flush_scheduled_work();
3971
3972         return 0;
3973 }
3974
3975 static int bcm43xx_init_private(struct bcm43xx_private *bcm,
3976                                 struct net_device *net_dev,
3977                                 struct pci_dev *pci_dev)
3978 {
3979         int err;
3980
3981         bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
3982         bcm->ieee = netdev_priv(net_dev);
3983         bcm->softmac = ieee80211_priv(net_dev);
3984         bcm->softmac->set_channel = bcm43xx_ieee80211_set_chan;
3985
3986         bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
3987         bcm->mac_suspended = 1;
3988         bcm->pci_dev = pci_dev;
3989         bcm->net_dev = net_dev;
3990         bcm->bad_frames_preempt = modparam_bad_frames_preempt;
3991         spin_lock_init(&bcm->irq_lock);
3992         spin_lock_init(&bcm->leds_lock);
3993         mutex_init(&bcm->mutex);
3994         tasklet_init(&bcm->isr_tasklet,
3995                      (void (*)(unsigned long))bcm43xx_interrupt_tasklet,
3996                      (unsigned long)bcm);
3997         tasklet_disable_nosync(&bcm->isr_tasklet);
3998         if (modparam_pio) {
3999                 bcm->__using_pio = 1;
4000         } else {
4001                 err = pci_set_dma_mask(pci_dev, DMA_30BIT_MASK);
4002                 err |= pci_set_consistent_dma_mask(pci_dev, DMA_30BIT_MASK);
4003                 if (err) {
4004 #ifdef CONFIG_BCM43XX_PIO
4005                         printk(KERN_WARNING PFX "DMA not supported. Falling back to PIO.\n");
4006                         bcm->__using_pio = 1;
4007 #else
4008                         printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. "
4009                                             "Recompile the driver with PIO support, please.\n");
4010                         return -ENODEV;
4011 #endif /* CONFIG_BCM43XX_PIO */
4012                 }
4013         }
4014         bcm->rts_threshold = BCM43xx_DEFAULT_RTS_THRESHOLD;
4015
4016         /* default to sw encryption for now */
4017         bcm->ieee->host_build_iv = 0;
4018         bcm->ieee->host_encrypt = 1;
4019         bcm->ieee->host_decrypt = 1;
4020         
4021         bcm->ieee->iw_mode = BCM43xx_INITIAL_IWMODE;
4022         bcm->ieee->tx_headroom = sizeof(struct bcm43xx_txhdr);
4023         bcm->ieee->set_security = bcm43xx_ieee80211_set_security;
4024         bcm->ieee->hard_start_xmit = bcm43xx_ieee80211_hard_start_xmit;
4025
4026         return 0;
4027 }
4028
4029 static int __devinit bcm43xx_init_one(struct pci_dev *pdev,
4030                                       const struct pci_device_id *ent)
4031 {
4032         struct net_device *net_dev;
4033         struct bcm43xx_private *bcm;
4034         int err;
4035
4036 #ifdef CONFIG_BCM947XX
4037         if ((pdev->bus->number == 0) && (pdev->device != 0x0800))
4038                 return -ENODEV;
4039 #endif
4040
4041 #ifdef DEBUG_SINGLE_DEVICE_ONLY
4042         if (strcmp(pci_name(pdev), DEBUG_SINGLE_DEVICE_ONLY))
4043                 return -ENODEV;
4044 #endif
4045
4046         net_dev = alloc_ieee80211softmac(sizeof(*bcm));
4047         if (!net_dev) {
4048                 printk(KERN_ERR PFX
4049                        "could not allocate ieee80211 device %s\n",
4050                        pci_name(pdev));
4051                 err = -ENOMEM;
4052                 goto out;
4053         }
4054         /* initialize the net_device struct */
4055         SET_MODULE_OWNER(net_dev);
4056         SET_NETDEV_DEV(net_dev, &pdev->dev);
4057
4058         net_dev->open = bcm43xx_net_open;
4059         net_dev->stop = bcm43xx_net_stop;
4060         net_dev->get_stats = bcm43xx_net_get_stats;
4061         net_dev->tx_timeout = bcm43xx_net_tx_timeout;
4062 #ifdef CONFIG_NET_POLL_CONTROLLER
4063         net_dev->poll_controller = bcm43xx_net_poll_controller;
4064 #endif
4065         net_dev->wireless_handlers = &bcm43xx_wx_handlers_def;
4066         net_dev->irq = pdev->irq;
4067         SET_ETHTOOL_OPS(net_dev, &bcm43xx_ethtool_ops);
4068
4069         /* initialize the bcm43xx_private struct */
4070         bcm = bcm43xx_priv(net_dev);
4071         memset(bcm, 0, sizeof(*bcm));
4072         err = bcm43xx_init_private(bcm, net_dev, pdev);
4073         if (err)
4074                 goto err_free_netdev;
4075
4076         pci_set_drvdata(pdev, net_dev);
4077
4078         err = bcm43xx_attach_board(bcm);
4079         if (err)
4080                 goto err_free_netdev;
4081
4082         err = register_netdev(net_dev);
4083         if (err) {
4084                 printk(KERN_ERR PFX "Cannot register net device, "
4085                        "aborting.\n");
4086                 err = -ENOMEM;
4087                 goto err_detach_board;
4088         }
4089
4090         bcm43xx_debugfs_add_device(bcm);
4091
4092         assert(err == 0);
4093 out:
4094         return err;
4095
4096 err_detach_board:
4097         bcm43xx_detach_board(bcm);
4098 err_free_netdev:
4099         free_ieee80211softmac(net_dev);
4100         goto out;
4101 }
4102
4103 static void __devexit bcm43xx_remove_one(struct pci_dev *pdev)
4104 {
4105         struct net_device *net_dev = pci_get_drvdata(pdev);
4106         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4107
4108         bcm43xx_debugfs_remove_device(bcm);
4109         unregister_netdev(net_dev);
4110         bcm43xx_detach_board(bcm);
4111         free_ieee80211softmac(net_dev);
4112 }
4113
4114 /* Hard-reset the chip. Do not call this directly.
4115  * Use bcm43xx_controller_restart()
4116  */
4117 static void bcm43xx_chip_reset(void *_bcm)
4118 {
4119         struct bcm43xx_private *bcm = _bcm;
4120         struct bcm43xx_phyinfo *phy;
4121         int err = -ENODEV;
4122
4123         mutex_lock(&(bcm)->mutex);
4124         if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
4125                 bcm43xx_periodic_tasks_delete(bcm);
4126                 phy = bcm43xx_current_phy(bcm);
4127                 err = bcm43xx_select_wireless_core(bcm, phy->type);
4128                 if (!err)
4129                         bcm43xx_periodic_tasks_setup(bcm);
4130         }
4131         mutex_unlock(&(bcm)->mutex);
4132
4133         printk(KERN_ERR PFX "Controller restart%s\n",
4134                (err == 0) ? "ed" : " failed");
4135 }
4136
4137 /* Hard-reset the chip.
4138  * This can be called from interrupt or process context.
4139  * bcm->irq_lock must be locked.
4140  */
4141 void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason)
4142 {
4143         if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)
4144                 return;
4145         printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason);
4146         INIT_WORK(&bcm->restart_work, bcm43xx_chip_reset, bcm);
4147         schedule_work(&bcm->restart_work);
4148 }
4149
4150 #ifdef CONFIG_PM
4151
4152 static int bcm43xx_suspend(struct pci_dev *pdev, pm_message_t state)
4153 {
4154         struct net_device *net_dev = pci_get_drvdata(pdev);
4155         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4156         int err;
4157
4158         dprintk(KERN_INFO PFX "Suspending...\n");
4159
4160         netif_device_detach(net_dev);
4161         bcm->was_initialized = 0;
4162         if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
4163                 bcm->was_initialized = 1;
4164                 ieee80211softmac_stop(net_dev);
4165                 err = bcm43xx_disable_interrupts_sync(bcm);
4166                 if (unlikely(err)) {
4167                         dprintk(KERN_ERR PFX "Suspend failed.\n");
4168                         return -EAGAIN;
4169                 }
4170                 bcm->firmware_norelease = 1;
4171                 bcm43xx_free_board(bcm);
4172                 bcm->firmware_norelease = 0;
4173         }
4174         bcm43xx_chipset_detach(bcm);
4175
4176         pci_save_state(pdev);
4177         pci_disable_device(pdev);
4178         pci_set_power_state(pdev, pci_choose_state(pdev, state));
4179
4180         dprintk(KERN_INFO PFX "Device suspended.\n");
4181
4182         return 0;
4183 }
4184
4185 static int bcm43xx_resume(struct pci_dev *pdev)
4186 {
4187         struct net_device *net_dev = pci_get_drvdata(pdev);
4188         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4189         int err = 0;
4190
4191         dprintk(KERN_INFO PFX "Resuming...\n");
4192
4193         pci_set_power_state(pdev, 0);
4194         pci_enable_device(pdev);
4195         pci_restore_state(pdev);
4196
4197         bcm43xx_chipset_attach(bcm);
4198         if (bcm->was_initialized)
4199                 err = bcm43xx_init_board(bcm);
4200         if (err) {
4201                 printk(KERN_ERR PFX "Resume failed!\n");
4202                 return err;
4203         }
4204         netif_device_attach(net_dev);
4205
4206         dprintk(KERN_INFO PFX "Device resumed.\n");
4207
4208         return 0;
4209 }
4210
4211 #endif                          /* CONFIG_PM */
4212
4213 static struct pci_driver bcm43xx_pci_driver = {
4214         .name = KBUILD_MODNAME,
4215         .id_table = bcm43xx_pci_tbl,
4216         .probe = bcm43xx_init_one,
4217         .remove = __devexit_p(bcm43xx_remove_one),
4218 #ifdef CONFIG_PM
4219         .suspend = bcm43xx_suspend,
4220         .resume = bcm43xx_resume,
4221 #endif                          /* CONFIG_PM */
4222 };
4223
4224 static int __init bcm43xx_init(void)
4225 {
4226         printk(KERN_INFO KBUILD_MODNAME " driver\n");
4227         bcm43xx_debugfs_init();
4228         return pci_register_driver(&bcm43xx_pci_driver);
4229 }
4230
4231 static void __exit bcm43xx_exit(void)
4232 {
4233         pci_unregister_driver(&bcm43xx_pci_driver);
4234         bcm43xx_debugfs_exit();
4235 }
4236
4237 module_init(bcm43xx_init)
4238 module_exit(bcm43xx_exit)