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