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