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