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