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