]> err.no Git - linux-2.6/blob - drivers/net/wireless/bcm43xx/bcm43xx_main.c
[PATCH] bcm43xx: receive TX status on MMIO or DMA unconditionally regarding the 80211...
[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         mmiowb();
159         bcm43xx_write32(bcm, BCM43xx_MMIO_RAM_DATA, val);
160 }
161
162 static inline
163 void bcm43xx_shm_control_word(struct bcm43xx_private *bcm,
164                               u16 routing, u16 offset)
165 {
166         u32 control;
167
168         /* "offset" is the WORD offset. */
169
170         control = routing;
171         control <<= 16;
172         control |= offset;
173         bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_CONTROL, control);
174 }
175
176 u32 bcm43xx_shm_read32(struct bcm43xx_private *bcm,
177                        u16 routing, u16 offset)
178 {
179         u32 ret;
180
181         if (routing == BCM43xx_SHM_SHARED) {
182                 if (offset & 0x0003) {
183                         /* Unaligned access */
184                         bcm43xx_shm_control_word(bcm, routing, offset >> 2);
185                         ret = bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED);
186                         ret <<= 16;
187                         bcm43xx_shm_control_word(bcm, routing, (offset >> 2) + 1);
188                         ret |= bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA);
189
190                         return ret;
191                 }
192                 offset >>= 2;
193         }
194         bcm43xx_shm_control_word(bcm, routing, offset);
195         ret = bcm43xx_read32(bcm, BCM43xx_MMIO_SHM_DATA);
196
197         return ret;
198 }
199
200 u16 bcm43xx_shm_read16(struct bcm43xx_private *bcm,
201                        u16 routing, u16 offset)
202 {
203         u16 ret;
204
205         if (routing == BCM43xx_SHM_SHARED) {
206                 if (offset & 0x0003) {
207                         /* Unaligned access */
208                         bcm43xx_shm_control_word(bcm, routing, offset >> 2);
209                         ret = bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED);
210
211                         return ret;
212                 }
213                 offset >>= 2;
214         }
215         bcm43xx_shm_control_word(bcm, routing, offset);
216         ret = bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA);
217
218         return ret;
219 }
220
221 void bcm43xx_shm_write32(struct bcm43xx_private *bcm,
222                          u16 routing, u16 offset,
223                          u32 value)
224 {
225         if (routing == BCM43xx_SHM_SHARED) {
226                 if (offset & 0x0003) {
227                         /* Unaligned access */
228                         bcm43xx_shm_control_word(bcm, routing, offset >> 2);
229                         mmiowb();
230                         bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED,
231                                         (value >> 16) & 0xffff);
232                         mmiowb();
233                         bcm43xx_shm_control_word(bcm, routing, (offset >> 2) + 1);
234                         mmiowb();
235                         bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA,
236                                         value & 0xffff);
237                         return;
238                 }
239                 offset >>= 2;
240         }
241         bcm43xx_shm_control_word(bcm, routing, offset);
242         mmiowb();
243         bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, value);
244 }
245
246 void bcm43xx_shm_write16(struct bcm43xx_private *bcm,
247                          u16 routing, u16 offset,
248                          u16 value)
249 {
250         if (routing == BCM43xx_SHM_SHARED) {
251                 if (offset & 0x0003) {
252                         /* Unaligned access */
253                         bcm43xx_shm_control_word(bcm, routing, offset >> 2);
254                         mmiowb();
255                         bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED,
256                                         value);
257                         return;
258                 }
259                 offset >>= 2;
260         }
261         bcm43xx_shm_control_word(bcm, routing, offset);
262         mmiowb();
263         bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA, value);
264 }
265
266 void bcm43xx_tsf_read(struct bcm43xx_private *bcm, u64 *tsf)
267 {
268         /* We need to be careful. As we read the TSF from multiple
269          * registers, we should take care of register overflows.
270          * In theory, the whole tsf read process should be atomic.
271          * We try to be atomic here, by restaring the read process,
272          * if any of the high registers changed (overflew).
273          */
274         if (bcm->current_core->rev >= 3) {
275                 u32 low, high, high2;
276
277                 do {
278                         high = bcm43xx_read32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_HIGH);
279                         low = bcm43xx_read32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW);
280                         high2 = bcm43xx_read32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_HIGH);
281                 } while (unlikely(high != high2));
282
283                 *tsf = high;
284                 *tsf <<= 32;
285                 *tsf |= low;
286         } else {
287                 u64 tmp;
288                 u16 v0, v1, v2, v3;
289                 u16 test1, test2, test3;
290
291                 do {
292                         v3 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_3);
293                         v2 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_2);
294                         v1 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_1);
295                         v0 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_0);
296
297                         test3 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_3);
298                         test2 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_2);
299                         test1 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_1);
300                 } while (v3 != test3 || v2 != test2 || v1 != test1);
301
302                 *tsf = v3;
303                 *tsf <<= 48;
304                 tmp = v2;
305                 tmp <<= 32;
306                 *tsf |= tmp;
307                 tmp = v1;
308                 tmp <<= 16;
309                 *tsf |= tmp;
310                 *tsf |= v0;
311         }
312 }
313
314 void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf)
315 {
316         u32 status;
317
318         status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
319         status |= BCM43xx_SBF_TIME_UPDATE;
320         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
321         mmiowb();
322
323         /* Be careful with the in-progress timer.
324          * First zero out the low register, so we have a full
325          * register-overflow duration to complete the operation.
326          */
327         if (bcm->current_core->rev >= 3) {
328                 u32 lo = (tsf & 0x00000000FFFFFFFFULL);
329                 u32 hi = (tsf & 0xFFFFFFFF00000000ULL) >> 32;
330
331                 bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW, 0);
332                 mmiowb();
333                 bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_HIGH, hi);
334                 mmiowb();
335                 bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW, lo);
336         } else {
337                 u16 v0 = (tsf & 0x000000000000FFFFULL);
338                 u16 v1 = (tsf & 0x00000000FFFF0000ULL) >> 16;
339                 u16 v2 = (tsf & 0x0000FFFF00000000ULL) >> 32;
340                 u16 v3 = (tsf & 0xFFFF000000000000ULL) >> 48;
341
342                 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_0, 0);
343                 mmiowb();
344                 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_3, v3);
345                 mmiowb();
346                 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_2, v2);
347                 mmiowb();
348                 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_1, v1);
349                 mmiowb();
350                 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_0, v0);
351         }
352
353         status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
354         status &= ~BCM43xx_SBF_TIME_UPDATE;
355         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
356 }
357
358 static
359 void bcm43xx_macfilter_set(struct bcm43xx_private *bcm,
360                            u16 offset,
361                            const u8 *mac)
362 {
363         u16 data;
364
365         offset |= 0x0020;
366         bcm43xx_write16(bcm, BCM43xx_MMIO_MACFILTER_CONTROL, offset);
367
368         data = mac[0];
369         data |= mac[1] << 8;
370         bcm43xx_write16(bcm, BCM43xx_MMIO_MACFILTER_DATA, data);
371         data = mac[2];
372         data |= mac[3] << 8;
373         bcm43xx_write16(bcm, BCM43xx_MMIO_MACFILTER_DATA, data);
374         data = mac[4];
375         data |= mac[5] << 8;
376         bcm43xx_write16(bcm, BCM43xx_MMIO_MACFILTER_DATA, data);
377 }
378
379 static void bcm43xx_macfilter_clear(struct bcm43xx_private *bcm,
380                                     u16 offset)
381 {
382         const u8 zero_addr[ETH_ALEN] = { 0 };
383
384         bcm43xx_macfilter_set(bcm, offset, zero_addr);
385 }
386
387 static void bcm43xx_write_mac_bssid_templates(struct bcm43xx_private *bcm)
388 {
389         const u8 *mac = (const u8 *)(bcm->net_dev->dev_addr);
390         const u8 *bssid = (const u8 *)(bcm->ieee->bssid);
391         u8 mac_bssid[ETH_ALEN * 2];
392         int i;
393
394         memcpy(mac_bssid, mac, ETH_ALEN);
395         memcpy(mac_bssid + ETH_ALEN, bssid, ETH_ALEN);
396
397         /* Write our MAC address and BSSID to template ram */
398         for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32))
399                 bcm43xx_ram_write(bcm, 0x20 + i, *((u32 *)(mac_bssid + i)));
400         for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32))
401                 bcm43xx_ram_write(bcm, 0x78 + i, *((u32 *)(mac_bssid + i)));
402         for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32))
403                 bcm43xx_ram_write(bcm, 0x478 + i, *((u32 *)(mac_bssid + i)));
404 }
405
406 static void bcm43xx_set_slot_time(struct bcm43xx_private *bcm, u16 slot_time)
407 {
408         /* slot_time is in usec. */
409         if (bcm->current_core->phy->type != BCM43xx_PHYTYPE_G)
410                 return;
411         bcm43xx_write16(bcm, 0x684, 510 + slot_time);
412         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0010, slot_time);
413 }
414
415 static void bcm43xx_short_slot_timing_enable(struct bcm43xx_private *bcm)
416 {
417         bcm43xx_set_slot_time(bcm, 9);
418 }
419
420 static void bcm43xx_short_slot_timing_disable(struct bcm43xx_private *bcm)
421 {
422         bcm43xx_set_slot_time(bcm, 20);
423 }
424
425 //FIXME: rename this func?
426 static void bcm43xx_disassociate(struct bcm43xx_private *bcm)
427 {
428         bcm43xx_mac_suspend(bcm);
429         bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC);
430
431         bcm43xx_ram_write(bcm, 0x0026, 0x0000);
432         bcm43xx_ram_write(bcm, 0x0028, 0x0000);
433         bcm43xx_ram_write(bcm, 0x007E, 0x0000);
434         bcm43xx_ram_write(bcm, 0x0080, 0x0000);
435         bcm43xx_ram_write(bcm, 0x047E, 0x0000);
436         bcm43xx_ram_write(bcm, 0x0480, 0x0000);
437
438         if (bcm->current_core->rev < 3) {
439                 bcm43xx_write16(bcm, 0x0610, 0x8000);
440                 bcm43xx_write16(bcm, 0x060E, 0x0000);
441         } else
442                 bcm43xx_write32(bcm, 0x0188, 0x80000000);
443
444         bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0004, 0x000003ff);
445
446         if (bcm->current_core->phy->type == BCM43xx_PHYTYPE_G &&
447             ieee80211_is_ofdm_rate(bcm->softmac->txrates.default_rate))
448                 bcm43xx_short_slot_timing_enable(bcm);
449
450         bcm43xx_mac_enable(bcm);
451 }
452
453 //FIXME: rename this func?
454 static void bcm43xx_associate(struct bcm43xx_private *bcm,
455                               const u8 *mac)
456 {
457         memcpy(bcm->ieee->bssid, mac, ETH_ALEN);
458
459         bcm43xx_mac_suspend(bcm);
460         bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_ASSOC, mac);
461         bcm43xx_write_mac_bssid_templates(bcm);
462         bcm43xx_mac_enable(bcm);
463 }
464
465 /* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable.
466  * Returns the _previously_ enabled IRQ mask.
467  */
468 static inline u32 bcm43xx_interrupt_enable(struct bcm43xx_private *bcm, u32 mask)
469 {
470         u32 old_mask;
471
472         old_mask = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK);
473         bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK, old_mask | mask);
474
475         return old_mask;
476 }
477
478 /* Disable a Generic IRQ. "mask" is the mask of which IRQs to disable.
479  * Returns the _previously_ enabled IRQ mask.
480  */
481 static inline u32 bcm43xx_interrupt_disable(struct bcm43xx_private *bcm, u32 mask)
482 {
483         u32 old_mask;
484
485         old_mask = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK);
486         bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK, old_mask & ~mask);
487
488         return old_mask;
489 }
490
491 /* Make sure we don't receive more data from the device. */
492 static int bcm43xx_disable_interrupts_sync(struct bcm43xx_private *bcm, u32 *oldstate)
493 {
494         u32 old;
495         unsigned long flags;
496
497         bcm43xx_lock_mmio(bcm, flags);
498         if (bcm43xx_is_initializing(bcm) || bcm->shutting_down) {
499                 bcm43xx_unlock_mmio(bcm, flags);
500                 return -EBUSY;
501         }
502         old = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
503         tasklet_disable(&bcm->isr_tasklet);
504         bcm43xx_unlock_mmio(bcm, flags);
505         if (oldstate)
506                 *oldstate = old;
507
508         return 0;
509 }
510
511 static int bcm43xx_read_radioinfo(struct bcm43xx_private *bcm)
512 {
513         struct bcm43xx_radioinfo *radio = bcm->current_core->radio;
514         struct bcm43xx_phyinfo *phy = bcm->current_core->phy;
515         u32 radio_id;
516         u16 manufact;
517         u16 version;
518         u8 revision;
519         s8 i;
520
521         if (bcm->chip_id == 0x4317) {
522                 if (bcm->chip_rev == 0x00)
523                         radio_id = 0x3205017F;
524                 else if (bcm->chip_rev == 0x01)
525                         radio_id = 0x4205017F;
526                 else
527                         radio_id = 0x5205017F;
528         } else {
529                 bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_CONTROL, BCM43xx_RADIOCTL_ID);
530                 radio_id = bcm43xx_read16(bcm, BCM43xx_MMIO_RADIO_DATA_HIGH);
531                 radio_id <<= 16;
532                 bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_CONTROL, BCM43xx_RADIOCTL_ID);
533                 radio_id |= bcm43xx_read16(bcm, BCM43xx_MMIO_RADIO_DATA_LOW);
534         }
535
536         manufact = (radio_id & 0x00000FFF);
537         version = (radio_id & 0x0FFFF000) >> 12;
538         revision = (radio_id & 0xF0000000) >> 28;
539
540         dprintk(KERN_INFO PFX "Detected Radio: ID: %x (Manuf: %x Ver: %x Rev: %x)\n",
541                 radio_id, manufact, version, revision);
542
543         switch (phy->type) {
544         case BCM43xx_PHYTYPE_A:
545                 if ((version != 0x2060) || (revision != 1) || (manufact != 0x17f))
546                         goto err_unsupported_radio;
547                 break;
548         case BCM43xx_PHYTYPE_B:
549                 if ((version & 0xFFF0) != 0x2050)
550                         goto err_unsupported_radio;
551                 break;
552         case BCM43xx_PHYTYPE_G:
553                 if (version != 0x2050)
554                         goto err_unsupported_radio;
555                 break;
556         }
557
558         radio->manufact = manufact;
559         radio->version = version;
560         radio->revision = revision;
561
562         /* Set default attenuation values. */
563         radio->txpower[0] = 2;
564         radio->txpower[1] = 2;
565         if (revision == 1)
566                 radio->txpower[2] = 3;
567         else
568                 radio->txpower[2] = 0;
569         if (bcm->current_core->phy->type == BCM43xx_PHYTYPE_A)
570                 radio->txpower_desired = bcm->sprom.maxpower_aphy;
571         else
572                 bcm->current_core->radio->txpower_desired = bcm->sprom.maxpower_bgphy;
573
574         /* Initialize the in-memory nrssi Lookup Table. */
575         for (i = 0; i < 64; i++)
576                 radio->nrssi_lt[i] = i;
577
578         return 0;
579
580 err_unsupported_radio:
581         printk(KERN_ERR PFX "Unsupported Radio connected to the PHY!\n");
582         return -ENODEV;
583 }
584
585 static const char * bcm43xx_locale_iso(u8 locale)
586 {
587         /* ISO 3166-1 country codes.
588          * Note that there aren't ISO 3166-1 codes for
589          * all or locales. (Not all locales are countries)
590          */
591         switch (locale) {
592         case BCM43xx_LOCALE_WORLD:
593         case BCM43xx_LOCALE_ALL:
594                 return "XX";
595         case BCM43xx_LOCALE_THAILAND:
596                 return "TH";
597         case BCM43xx_LOCALE_ISRAEL:
598                 return "IL";
599         case BCM43xx_LOCALE_JORDAN:
600                 return "JO";
601         case BCM43xx_LOCALE_CHINA:
602                 return "CN";
603         case BCM43xx_LOCALE_JAPAN:
604         case BCM43xx_LOCALE_JAPAN_HIGH:
605                 return "JP";
606         case BCM43xx_LOCALE_USA_CANADA_ANZ:
607         case BCM43xx_LOCALE_USA_LOW:
608                 return "US";
609         case BCM43xx_LOCALE_EUROPE:
610                 return "EU";
611         case BCM43xx_LOCALE_NONE:
612                 return "  ";
613         }
614         assert(0);
615         return "  ";
616 }
617
618 static const char * bcm43xx_locale_string(u8 locale)
619 {
620         switch (locale) {
621         case BCM43xx_LOCALE_WORLD:
622                 return "World";
623         case BCM43xx_LOCALE_THAILAND:
624                 return "Thailand";
625         case BCM43xx_LOCALE_ISRAEL:
626                 return "Israel";
627         case BCM43xx_LOCALE_JORDAN:
628                 return "Jordan";
629         case BCM43xx_LOCALE_CHINA:
630                 return "China";
631         case BCM43xx_LOCALE_JAPAN:
632                 return "Japan";
633         case BCM43xx_LOCALE_USA_CANADA_ANZ:
634                 return "USA/Canada/ANZ";
635         case BCM43xx_LOCALE_EUROPE:
636                 return "Europe";
637         case BCM43xx_LOCALE_USA_LOW:
638                 return "USAlow";
639         case BCM43xx_LOCALE_JAPAN_HIGH:
640                 return "JapanHigh";
641         case BCM43xx_LOCALE_ALL:
642                 return "All";
643         case BCM43xx_LOCALE_NONE:
644                 return "None";
645         }
646         assert(0);
647         return "";
648 }
649
650 static inline u8 bcm43xx_crc8(u8 crc, u8 data)
651 {
652         static const u8 t[] = {
653                 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
654                 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
655                 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
656                 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
657                 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
658                 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
659                 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
660                 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
661                 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
662                 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
663                 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
664                 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
665                 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
666                 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
667                 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
668                 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
669                 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
670                 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
671                 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
672                 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
673                 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
674                 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
675                 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
676                 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
677                 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
678                 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
679                 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
680                 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
681                 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
682                 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
683                 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
684                 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F,
685         };
686         return t[crc ^ data];
687 }
688
689 static u8 bcm43xx_sprom_crc(const u16 *sprom)
690 {
691         int word;
692         u8 crc = 0xFF;
693
694         for (word = 0; word < BCM43xx_SPROM_SIZE - 1; word++) {
695                 crc = bcm43xx_crc8(crc, sprom[word] & 0x00FF);
696                 crc = bcm43xx_crc8(crc, (sprom[word] & 0xFF00) >> 8);
697         }
698         crc = bcm43xx_crc8(crc, sprom[BCM43xx_SPROM_VERSION] & 0x00FF);
699         crc ^= 0xFF;
700
701         return crc;
702 }
703
704 int bcm43xx_sprom_read(struct bcm43xx_private *bcm, u16 *sprom)
705 {
706         int i;
707         u8 crc, expected_crc;
708
709         for (i = 0; i < BCM43xx_SPROM_SIZE; i++)
710                 sprom[i] = bcm43xx_read16(bcm, BCM43xx_SPROM_BASE + (i * 2));
711         /* CRC-8 check. */
712         crc = bcm43xx_sprom_crc(sprom);
713         expected_crc = (sprom[BCM43xx_SPROM_VERSION] & 0xFF00) >> 8;
714         if (crc != expected_crc) {
715                 printk(KERN_WARNING PFX "WARNING: Invalid SPROM checksum "
716                                         "(0x%02X, expected: 0x%02X)\n",
717                        crc, expected_crc);
718                 return -EINVAL;
719         }
720
721         return 0;
722 }
723
724 int bcm43xx_sprom_write(struct bcm43xx_private *bcm, const u16 *sprom)
725 {
726         int i, err;
727         u8 crc, expected_crc;
728         u32 spromctl;
729
730         /* CRC-8 validation of the input data. */
731         crc = bcm43xx_sprom_crc(sprom);
732         expected_crc = (sprom[BCM43xx_SPROM_VERSION] & 0xFF00) >> 8;
733         if (crc != expected_crc) {
734                 printk(KERN_ERR PFX "SPROM input data: Invalid CRC\n");
735                 return -EINVAL;
736         }
737
738         printk(KERN_INFO PFX "Writing SPROM. Do NOT turn off the power! Please stand by...\n");
739         err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCICFG_SPROMCTL, &spromctl);
740         if (err)
741                 goto err_ctlreg;
742         spromctl |= 0x10; /* SPROM WRITE enable. */
743         bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl);
744         if (err)
745                 goto err_ctlreg;
746         /* We must burn lots of CPU cycles here, but that does not
747          * really matter as one does not write the SPROM every other minute...
748          */
749         printk(KERN_INFO PFX "[ 0%%");
750         mdelay(500);
751         for (i = 0; i < BCM43xx_SPROM_SIZE; i++) {
752                 if (i == 16)
753                         printk("25%%");
754                 else if (i == 32)
755                         printk("50%%");
756                 else if (i == 48)
757                         printk("75%%");
758                 else if (i % 2)
759                         printk(".");
760                 bcm43xx_write16(bcm, BCM43xx_SPROM_BASE + (i * 2), sprom[i]);
761                 mmiowb();
762                 mdelay(20);
763         }
764         spromctl &= ~0x10; /* SPROM WRITE enable. */
765         bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl);
766         if (err)
767                 goto err_ctlreg;
768         mdelay(500);
769         printk("100%% ]\n");
770         printk(KERN_INFO PFX "SPROM written.\n");
771         bcm43xx_controller_restart(bcm, "SPROM update");
772
773         return 0;
774 err_ctlreg:
775         printk(KERN_ERR PFX "Could not access SPROM control register.\n");
776         return -ENODEV;
777 }
778
779 static int bcm43xx_sprom_extract(struct bcm43xx_private *bcm)
780 {
781         u16 value;
782         u16 *sprom;
783 #ifdef CONFIG_BCM947XX
784         char *c;
785 #endif
786
787         sprom = kzalloc(BCM43xx_SPROM_SIZE * sizeof(u16),
788                         GFP_KERNEL);
789         if (!sprom) {
790                 printk(KERN_ERR PFX "sprom_extract OOM\n");
791                 return -ENOMEM;
792         }
793 #ifdef CONFIG_BCM947XX
794         sprom[BCM43xx_SPROM_BOARDFLAGS2] = atoi(nvram_get("boardflags2"));
795         sprom[BCM43xx_SPROM_BOARDFLAGS] = atoi(nvram_get("boardflags"));
796
797         if ((c = nvram_get("il0macaddr")) != NULL)
798                 e_aton(c, (char *) &(sprom[BCM43xx_SPROM_IL0MACADDR]));
799
800         if ((c = nvram_get("et1macaddr")) != NULL)
801                 e_aton(c, (char *) &(sprom[BCM43xx_SPROM_ET1MACADDR]));
802
803         sprom[BCM43xx_SPROM_PA0B0] = atoi(nvram_get("pa0b0"));
804         sprom[BCM43xx_SPROM_PA0B1] = atoi(nvram_get("pa0b1"));
805         sprom[BCM43xx_SPROM_PA0B2] = atoi(nvram_get("pa0b2"));
806
807         sprom[BCM43xx_SPROM_PA1B0] = atoi(nvram_get("pa1b0"));
808         sprom[BCM43xx_SPROM_PA1B1] = atoi(nvram_get("pa1b1"));
809         sprom[BCM43xx_SPROM_PA1B2] = atoi(nvram_get("pa1b2"));
810
811         sprom[BCM43xx_SPROM_BOARDREV] = atoi(nvram_get("boardrev"));
812 #else
813         bcm43xx_sprom_read(bcm, sprom);
814 #endif
815
816         /* boardflags2 */
817         value = sprom[BCM43xx_SPROM_BOARDFLAGS2];
818         bcm->sprom.boardflags2 = value;
819
820         /* il0macaddr */
821         value = sprom[BCM43xx_SPROM_IL0MACADDR + 0];
822         *(((u16 *)bcm->sprom.il0macaddr) + 0) = cpu_to_be16(value);
823         value = sprom[BCM43xx_SPROM_IL0MACADDR + 1];
824         *(((u16 *)bcm->sprom.il0macaddr) + 1) = cpu_to_be16(value);
825         value = sprom[BCM43xx_SPROM_IL0MACADDR + 2];
826         *(((u16 *)bcm->sprom.il0macaddr) + 2) = cpu_to_be16(value);
827
828         /* et0macaddr */
829         value = sprom[BCM43xx_SPROM_ET0MACADDR + 0];
830         *(((u16 *)bcm->sprom.et0macaddr) + 0) = cpu_to_be16(value);
831         value = sprom[BCM43xx_SPROM_ET0MACADDR + 1];
832         *(((u16 *)bcm->sprom.et0macaddr) + 1) = cpu_to_be16(value);
833         value = sprom[BCM43xx_SPROM_ET0MACADDR + 2];
834         *(((u16 *)bcm->sprom.et0macaddr) + 2) = cpu_to_be16(value);
835
836         /* et1macaddr */
837         value = sprom[BCM43xx_SPROM_ET1MACADDR + 0];
838         *(((u16 *)bcm->sprom.et1macaddr) + 0) = cpu_to_be16(value);
839         value = sprom[BCM43xx_SPROM_ET1MACADDR + 1];
840         *(((u16 *)bcm->sprom.et1macaddr) + 1) = cpu_to_be16(value);
841         value = sprom[BCM43xx_SPROM_ET1MACADDR + 2];
842         *(((u16 *)bcm->sprom.et1macaddr) + 2) = cpu_to_be16(value);
843
844         /* ethernet phy settings */
845         value = sprom[BCM43xx_SPROM_ETHPHY];
846         bcm->sprom.et0phyaddr = (value & 0x001F);
847         bcm->sprom.et1phyaddr = (value & 0x03E0) >> 5;
848         bcm->sprom.et0mdcport = (value & (1 << 14)) >> 14;
849         bcm->sprom.et1mdcport = (value & (1 << 15)) >> 15;
850
851         /* boardrev, antennas, locale */
852         value = sprom[BCM43xx_SPROM_BOARDREV];
853         bcm->sprom.boardrev = (value & 0x00FF);
854         bcm->sprom.locale = (value & 0x0F00) >> 8;
855         bcm->sprom.antennas_aphy = (value & 0x3000) >> 12;
856         bcm->sprom.antennas_bgphy = (value & 0xC000) >> 14;
857         if (modparam_locale != -1) {
858                 if (modparam_locale >= 0 && modparam_locale <= 11) {
859                         bcm->sprom.locale = modparam_locale;
860                         printk(KERN_WARNING PFX "Operating with modified "
861                                                 "LocaleCode %u (%s)\n",
862                                bcm->sprom.locale,
863                                bcm43xx_locale_string(bcm->sprom.locale));
864                 } else {
865                         printk(KERN_WARNING PFX "Module parameter \"locale\" "
866                                                 "invalid value. (0 - 11)\n");
867                 }
868         }
869
870         /* pa0b* */
871         value = sprom[BCM43xx_SPROM_PA0B0];
872         bcm->sprom.pa0b0 = value;
873         value = sprom[BCM43xx_SPROM_PA0B1];
874         bcm->sprom.pa0b1 = value;
875         value = sprom[BCM43xx_SPROM_PA0B2];
876         bcm->sprom.pa0b2 = value;
877
878         /* wl0gpio* */
879         value = sprom[BCM43xx_SPROM_WL0GPIO0];
880         if (value == 0x0000)
881                 value = 0xFFFF;
882         bcm->sprom.wl0gpio0 = value & 0x00FF;
883         bcm->sprom.wl0gpio1 = (value & 0xFF00) >> 8;
884         value = sprom[BCM43xx_SPROM_WL0GPIO2];
885         if (value == 0x0000)
886                 value = 0xFFFF;
887         bcm->sprom.wl0gpio2 = value & 0x00FF;
888         bcm->sprom.wl0gpio3 = (value & 0xFF00) >> 8;
889
890         /* maxpower */
891         value = sprom[BCM43xx_SPROM_MAXPWR];
892         bcm->sprom.maxpower_aphy = (value & 0xFF00) >> 8;
893         bcm->sprom.maxpower_bgphy = value & 0x00FF;
894
895         /* pa1b* */
896         value = sprom[BCM43xx_SPROM_PA1B0];
897         bcm->sprom.pa1b0 = value;
898         value = sprom[BCM43xx_SPROM_PA1B1];
899         bcm->sprom.pa1b1 = value;
900         value = sprom[BCM43xx_SPROM_PA1B2];
901         bcm->sprom.pa1b2 = value;
902
903         /* idle tssi target */
904         value = sprom[BCM43xx_SPROM_IDL_TSSI_TGT];
905         bcm->sprom.idle_tssi_tgt_aphy = value & 0x00FF;
906         bcm->sprom.idle_tssi_tgt_bgphy = (value & 0xFF00) >> 8;
907
908         /* boardflags */
909         value = sprom[BCM43xx_SPROM_BOARDFLAGS];
910         if (value == 0xFFFF)
911                 value = 0x0000;
912         bcm->sprom.boardflags = value;
913
914         /* antenna gain */
915         value = sprom[BCM43xx_SPROM_ANTENNA_GAIN];
916         if (value == 0x0000 || value == 0xFFFF)
917                 value = 0x0202;
918         /* convert values to Q5.2 */
919         bcm->sprom.antennagain_aphy = ((value & 0xFF00) >> 8) * 4;
920         bcm->sprom.antennagain_bgphy = (value & 0x00FF) * 4;
921
922         kfree(sprom);
923
924         return 0;
925 }
926
927 static void bcm43xx_geo_init(struct bcm43xx_private *bcm)
928 {
929         struct ieee80211_geo geo;
930         struct ieee80211_channel *chan;
931         int have_a = 0, have_bg = 0;
932         int i, num80211;
933         u8 channel;
934         struct bcm43xx_phyinfo *phy;
935         const char *iso_country;
936
937         memset(&geo, 0, sizeof(geo));
938         num80211 = bcm43xx_num_80211_cores(bcm);
939         for (i = 0; i < num80211; i++) {
940                 phy = bcm->phy + i;
941                 switch (phy->type) {
942                 case BCM43xx_PHYTYPE_B:
943                 case BCM43xx_PHYTYPE_G:
944                         have_bg = 1;
945                         break;
946                 case BCM43xx_PHYTYPE_A:
947                         have_a = 1;
948                         break;
949                 default:
950                         assert(0);
951                 }
952         }
953         iso_country = bcm43xx_locale_iso(bcm->sprom.locale);
954
955         if (have_a) {
956                 for (i = 0, channel = 0; channel < 201; channel++) {
957                         chan = &geo.a[i++];
958                         chan->freq = bcm43xx_channel_to_freq_a(channel);
959                         chan->channel = channel;
960                 }
961                 geo.a_channels = i;
962         }
963         if (have_bg) {
964                 for (i = 0, channel = 1; channel < 15; channel++) {
965                         chan = &geo.bg[i++];
966                         chan->freq = bcm43xx_channel_to_freq_bg(channel);
967                         chan->channel = channel;
968                 }
969                 geo.bg_channels = i;
970         }
971         memcpy(geo.name, iso_country, 2);
972         if (0 /*TODO: Outdoor use only */)
973                 geo.name[2] = 'O';
974         else if (0 /*TODO: Indoor use only */)
975                 geo.name[2] = 'I';
976         else
977                 geo.name[2] = ' ';
978         geo.name[3] = '\0';
979
980         ieee80211_set_geo(bcm->ieee, &geo);
981 }
982
983 /* DummyTransmission function, as documented on 
984  * http://bcm-specs.sipsolutions.net/DummyTransmission
985  */
986 void bcm43xx_dummy_transmission(struct bcm43xx_private *bcm)
987 {
988         struct bcm43xx_phyinfo *phy = bcm->current_core->phy;
989         struct bcm43xx_radioinfo *radio = bcm->current_core->radio;
990         unsigned int i, max_loop;
991         u16 value = 0;
992         u32 buffer[5] = {
993                 0x00000000,
994                 0x0000D400,
995                 0x00000000,
996                 0x00000001,
997                 0x00000000,
998         };
999
1000 /* FIXME: It seems like a dummy_transmission corrupts the DMA engines,
1001  *        once they are initialized. So avoid doing a dummy_transmission,
1002  *        if the DMA engines are running.
1003  */
1004 if (bcm->initialized)
1005 return;
1006
1007         switch (phy->type) {
1008         case BCM43xx_PHYTYPE_A:
1009                 max_loop = 0x1E;
1010                 buffer[0] = 0xCC010200;
1011                 break;
1012         case BCM43xx_PHYTYPE_B:
1013         case BCM43xx_PHYTYPE_G:
1014                 max_loop = 0xFA;
1015                 buffer[0] = 0x6E840B00; 
1016                 break;
1017         default:
1018                 assert(0);
1019                 return;
1020         }
1021
1022         for (i = 0; i < 5; i++)
1023                 bcm43xx_ram_write(bcm, i * 4, buffer[i]);
1024
1025         bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
1026
1027         bcm43xx_write16(bcm, 0x0568, 0x0000);
1028         bcm43xx_write16(bcm, 0x07C0, 0x0000);
1029         bcm43xx_write16(bcm, 0x050C, ((phy->type == BCM43xx_PHYTYPE_A) ? 1 : 0));
1030         bcm43xx_write16(bcm, 0x0508, 0x0000);
1031         bcm43xx_write16(bcm, 0x050A, 0x0000);
1032         bcm43xx_write16(bcm, 0x054C, 0x0000);
1033         bcm43xx_write16(bcm, 0x056A, 0x0014);
1034         bcm43xx_write16(bcm, 0x0568, 0x0826);
1035         bcm43xx_write16(bcm, 0x0500, 0x0000);
1036         bcm43xx_write16(bcm, 0x0502, 0x0030);
1037
1038         if (radio->version == 0x2050 && radio->revision <= 0x5)
1039                 bcm43xx_radio_write16(bcm, 0x0051, 0x0017);
1040         for (i = 0x00; i < max_loop; i++) {
1041                 value = bcm43xx_read16(bcm, 0x050E);
1042                 if (value & 0x0080)
1043                         break;
1044                 udelay(10);
1045         }
1046         for (i = 0x00; i < 0x0A; i++) {
1047                 value = bcm43xx_read16(bcm, 0x050E);
1048                 if (value & 0x0400)
1049                         break;
1050                 udelay(10);
1051         }
1052         for (i = 0x00; i < 0x0A; i++) {
1053                 value = bcm43xx_read16(bcm, 0x0690);
1054                 if (!(value & 0x0100))
1055                         break;
1056                 udelay(10);
1057         }
1058         if (radio->version == 0x2050 && radio->revision <= 0x5)
1059                 bcm43xx_radio_write16(bcm, 0x0051, 0x0037);
1060 }
1061
1062 static void key_write(struct bcm43xx_private *bcm,
1063                       u8 index, u8 algorithm, const u16 *key)
1064 {
1065         unsigned int i, basic_wep = 0;
1066         u32 offset;
1067         u16 value;
1068  
1069         /* Write associated key information */
1070         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x100 + (index * 2),
1071                             ((index << 4) | (algorithm & 0x0F)));
1072  
1073         /* The first 4 WEP keys need extra love */
1074         if (((algorithm == BCM43xx_SEC_ALGO_WEP) ||
1075             (algorithm == BCM43xx_SEC_ALGO_WEP104)) && (index < 4))
1076                 basic_wep = 1;
1077  
1078         /* Write key payload, 8 little endian words */
1079         offset = bcm->security_offset + (index * BCM43xx_SEC_KEYSIZE);
1080         for (i = 0; i < (BCM43xx_SEC_KEYSIZE / sizeof(u16)); i++) {
1081                 value = cpu_to_le16(key[i]);
1082                 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
1083                                     offset + (i * 2), value);
1084  
1085                 if (!basic_wep)
1086                         continue;
1087  
1088                 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
1089                                     offset + (i * 2) + 4 * BCM43xx_SEC_KEYSIZE,
1090                                     value);
1091         }
1092 }
1093
1094 static void keymac_write(struct bcm43xx_private *bcm,
1095                          u8 index, const u32 *addr)
1096 {
1097         /* for keys 0-3 there is no associated mac address */
1098         if (index < 4)
1099                 return;
1100
1101         index -= 4;
1102         if (bcm->current_core->rev >= 5) {
1103                 bcm43xx_shm_write32(bcm,
1104                                     BCM43xx_SHM_HWMAC,
1105                                     index * 2,
1106                                     cpu_to_be32(*addr));
1107                 bcm43xx_shm_write16(bcm,
1108                                     BCM43xx_SHM_HWMAC,
1109                                     (index * 2) + 1,
1110                                     cpu_to_be16(*((u16 *)(addr + 1))));
1111         } else {
1112                 if (index < 8) {
1113                         TODO(); /* Put them in the macaddress filter */
1114                 } else {
1115                         TODO();
1116                         /* Put them BCM43xx_SHM_SHARED, stating index 0x0120.
1117                            Keep in mind to update the count of keymacs in 0x003E as well! */
1118                 }
1119         }
1120 }
1121
1122 static int bcm43xx_key_write(struct bcm43xx_private *bcm,
1123                              u8 index, u8 algorithm,
1124                              const u8 *_key, int key_len,
1125                              const u8 *mac_addr)
1126 {
1127         u8 key[BCM43xx_SEC_KEYSIZE] = { 0 };
1128
1129         if (index >= ARRAY_SIZE(bcm->key))
1130                 return -EINVAL;
1131         if (key_len > ARRAY_SIZE(key))
1132                 return -EINVAL;
1133         if (algorithm < 1 || algorithm > 5)
1134                 return -EINVAL;
1135
1136         memcpy(key, _key, key_len);
1137         key_write(bcm, index, algorithm, (const u16 *)key);
1138         keymac_write(bcm, index, (const u32 *)mac_addr);
1139
1140         bcm->key[index].algorithm = algorithm;
1141
1142         return 0;
1143 }
1144
1145 static void bcm43xx_clear_keys(struct bcm43xx_private *bcm)
1146 {
1147         static const u32 zero_mac[2] = { 0 };
1148         unsigned int i,j, nr_keys = 54;
1149         u16 offset;
1150
1151         if (bcm->current_core->rev < 5)
1152                 nr_keys = 16;
1153         assert(nr_keys <= ARRAY_SIZE(bcm->key));
1154
1155         for (i = 0; i < nr_keys; i++) {
1156                 bcm->key[i].enabled = 0;
1157                 /* returns for i < 4 immediately */
1158                 keymac_write(bcm, i, zero_mac);
1159                 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
1160                                     0x100 + (i * 2), 0x0000);
1161                 for (j = 0; j < 8; j++) {
1162                         offset = bcm->security_offset + (j * 4) + (i * BCM43xx_SEC_KEYSIZE);
1163                         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
1164                                             offset, 0x0000);
1165                 }
1166         }
1167         dprintk(KERN_INFO PFX "Keys cleared\n");
1168 }
1169
1170 /* Lowlevel core-switch function. This is only to be used in
1171  * bcm43xx_switch_core() and bcm43xx_probe_cores()
1172  */
1173 static int _switch_core(struct bcm43xx_private *bcm, int core)
1174 {
1175         int err;
1176         int attempts = 0;
1177         u32 current_core;
1178
1179         assert(core >= 0);
1180         while (1) {
1181                 err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_ACTIVE_CORE,
1182                                                  (core * 0x1000) + 0x18000000);
1183                 if (unlikely(err))
1184                         goto error;
1185                 err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCICFG_ACTIVE_CORE,
1186                                                 &current_core);
1187                 if (unlikely(err))
1188                         goto error;
1189                 current_core = (current_core - 0x18000000) / 0x1000;
1190                 if (current_core == core)
1191                         break;
1192
1193                 if (unlikely(attempts++ > BCM43xx_SWITCH_CORE_MAX_RETRIES))
1194                         goto error;
1195                 udelay(10);
1196         }
1197 #ifdef CONFIG_BCM947XX
1198         if (bcm->pci_dev->bus->number == 0)
1199                 bcm->current_core_offset = 0x1000 * core;
1200         else
1201                 bcm->current_core_offset = 0;
1202 #endif
1203
1204         return 0;
1205 error:
1206         printk(KERN_ERR PFX "Failed to switch to core %d\n", core);
1207         return -ENODEV;
1208 }
1209
1210 int bcm43xx_switch_core(struct bcm43xx_private *bcm, struct bcm43xx_coreinfo *new_core)
1211 {
1212         int err;
1213
1214         if (unlikely(!new_core))
1215                 return 0;
1216         if (!(new_core->flags & BCM43xx_COREFLAG_AVAILABLE))
1217                 return -ENODEV;
1218         if (bcm->current_core == new_core)
1219                 return 0;
1220         err = _switch_core(bcm, new_core->index);
1221         if (likely(!err))
1222                 bcm->current_core = new_core;
1223
1224         return err;
1225 }
1226
1227 static int bcm43xx_core_enabled(struct bcm43xx_private *bcm)
1228 {
1229         u32 value;
1230
1231         value = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1232         value &= BCM43xx_SBTMSTATELOW_CLOCK | BCM43xx_SBTMSTATELOW_RESET
1233                  | BCM43xx_SBTMSTATELOW_REJECT;
1234
1235         return (value == BCM43xx_SBTMSTATELOW_CLOCK);
1236 }
1237
1238 /* disable current core */
1239 static int bcm43xx_core_disable(struct bcm43xx_private *bcm, u32 core_flags)
1240 {
1241         u32 sbtmstatelow;
1242         u32 sbtmstatehigh;
1243         int i;
1244
1245         /* fetch sbtmstatelow from core information registers */
1246         sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1247
1248         /* core is already in reset */
1249         if (sbtmstatelow & BCM43xx_SBTMSTATELOW_RESET)
1250                 goto out;
1251
1252         if (sbtmstatelow & BCM43xx_SBTMSTATELOW_CLOCK) {
1253                 sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK |
1254                                BCM43xx_SBTMSTATELOW_REJECT;
1255                 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1256
1257                 for (i = 0; i < 1000; i++) {
1258                         sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1259                         if (sbtmstatelow & BCM43xx_SBTMSTATELOW_REJECT) {
1260                                 i = -1;
1261                                 break;
1262                         }
1263                         udelay(10);
1264                 }
1265                 if (i != -1) {
1266                         printk(KERN_ERR PFX "Error: core_disable() REJECT timeout!\n");
1267                         return -EBUSY;
1268                 }
1269
1270                 for (i = 0; i < 1000; i++) {
1271                         sbtmstatehigh = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH);
1272                         if (!(sbtmstatehigh & BCM43xx_SBTMSTATEHIGH_BUSY)) {
1273                                 i = -1;
1274                                 break;
1275                         }
1276                         udelay(10);
1277                 }
1278                 if (i != -1) {
1279                         printk(KERN_ERR PFX "Error: core_disable() BUSY timeout!\n");
1280                         return -EBUSY;
1281                 }
1282
1283                 sbtmstatelow = BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK |
1284                                BCM43xx_SBTMSTATELOW_REJECT |
1285                                BCM43xx_SBTMSTATELOW_RESET |
1286                                BCM43xx_SBTMSTATELOW_CLOCK |
1287                                core_flags;
1288                 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1289                 udelay(10);
1290         }
1291
1292         sbtmstatelow = BCM43xx_SBTMSTATELOW_RESET |
1293                        BCM43xx_SBTMSTATELOW_REJECT |
1294                        core_flags;
1295         bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1296
1297 out:
1298         bcm->current_core->flags &= ~ BCM43xx_COREFLAG_ENABLED;
1299         return 0;
1300 }
1301
1302 /* enable (reset) current core */
1303 static int bcm43xx_core_enable(struct bcm43xx_private *bcm, u32 core_flags)
1304 {
1305         u32 sbtmstatelow;
1306         u32 sbtmstatehigh;
1307         u32 sbimstate;
1308         int err;
1309
1310         err = bcm43xx_core_disable(bcm, core_flags);
1311         if (err)
1312                 goto out;
1313
1314         sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK |
1315                        BCM43xx_SBTMSTATELOW_RESET |
1316                        BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK |
1317                        core_flags;
1318         bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1319         udelay(1);
1320
1321         sbtmstatehigh = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH);
1322         if (sbtmstatehigh & BCM43xx_SBTMSTATEHIGH_SERROR) {
1323                 sbtmstatehigh = 0x00000000;
1324                 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATEHIGH, sbtmstatehigh);
1325         }
1326
1327         sbimstate = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMSTATE);
1328         if (sbimstate & (BCM43xx_SBIMSTATE_IB_ERROR | BCM43xx_SBIMSTATE_TIMEOUT)) {
1329                 sbimstate &= ~(BCM43xx_SBIMSTATE_IB_ERROR | BCM43xx_SBIMSTATE_TIMEOUT);
1330                 bcm43xx_write32(bcm, BCM43xx_CIR_SBIMSTATE, sbimstate);
1331         }
1332
1333         sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK |
1334                        BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK |
1335                        core_flags;
1336         bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1337         udelay(1);
1338
1339         sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK | core_flags;
1340         bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1341         udelay(1);
1342
1343         bcm->current_core->flags |= BCM43xx_COREFLAG_ENABLED;
1344         assert(err == 0);
1345 out:
1346         return err;
1347 }
1348
1349 /* http://bcm-specs.sipsolutions.net/80211CoreReset */
1350 void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy)
1351 {
1352         u32 flags = 0x00040000;
1353
1354         if ((bcm43xx_core_enabled(bcm)) &&
1355             !bcm43xx_using_pio(bcm)) {
1356 //FIXME: Do we _really_ want #ifndef CONFIG_BCM947XX here?
1357 #ifndef CONFIG_BCM947XX
1358                 /* reset all used DMA controllers. */
1359                 bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA1_BASE);
1360                 bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA2_BASE);
1361                 bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA3_BASE);
1362                 bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA4_BASE);
1363                 bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA1_BASE);
1364                 if (bcm->current_core->rev < 5)
1365                         bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA4_BASE);
1366 #endif
1367         }
1368         if (bcm->shutting_down) {
1369                 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
1370                                 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
1371                                 & ~(BCM43xx_SBF_MAC_ENABLED | 0x00000002));
1372         } else {
1373                 if (connect_phy)
1374                         flags |= 0x20000000;
1375                 bcm43xx_phy_connect(bcm, connect_phy);
1376                 bcm43xx_core_enable(bcm, flags);
1377                 bcm43xx_write16(bcm, 0x03E6, 0x0000);
1378                 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
1379                                 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
1380                                 | BCM43xx_SBF_400);
1381         }
1382 }
1383
1384 static void bcm43xx_wireless_core_disable(struct bcm43xx_private *bcm)
1385 {
1386         bcm43xx_radio_turn_off(bcm);
1387         bcm43xx_write16(bcm, 0x03E6, 0x00F4);
1388         bcm43xx_core_disable(bcm, 0);
1389 }
1390
1391 /* Mark the current 80211 core inactive.
1392  * "active_80211_core" is the other 80211 core, which is used.
1393  */
1394 static int bcm43xx_wireless_core_mark_inactive(struct bcm43xx_private *bcm,
1395                                                struct bcm43xx_coreinfo *active_80211_core)
1396 {
1397         u32 sbtmstatelow;
1398         struct bcm43xx_coreinfo *old_core;
1399         int err = 0;
1400
1401         bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
1402         bcm43xx_radio_turn_off(bcm);
1403         sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1404         sbtmstatelow &= ~0x200a0000;
1405         sbtmstatelow |= 0xa0000;
1406         bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1407         udelay(1);
1408         sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1409         sbtmstatelow &= ~0xa0000;
1410         sbtmstatelow |= 0x80000;
1411         bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1412         udelay(1);
1413
1414         if (bcm->current_core->phy->type == BCM43xx_PHYTYPE_G) {
1415                 old_core = bcm->current_core;
1416                 err = bcm43xx_switch_core(bcm, active_80211_core);
1417                 if (err)
1418                         goto out;
1419                 sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1420                 sbtmstatelow &= ~0x20000000;
1421                 sbtmstatelow |= 0x20000000;
1422                 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1423                 err = bcm43xx_switch_core(bcm, old_core);
1424         }
1425
1426 out:
1427         return err;
1428 }
1429
1430 static void handle_irq_transmit_status(struct bcm43xx_private *bcm)
1431 {
1432         u32 v0, v1;
1433         u16 tmp;
1434         struct bcm43xx_xmitstatus stat;
1435
1436         assert(bcm->current_core->id == BCM43xx_COREID_80211);
1437         assert(bcm->current_core->rev >= 5);
1438
1439         while (1) {
1440                 v0 = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_0);
1441                 if (!v0)
1442                         break;
1443                 v1 = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_1);
1444
1445                 stat.cookie = (v0 >> 16) & 0x0000FFFF;
1446                 tmp = (u16)((v0 & 0xFFF0) | ((v0 & 0xF) >> 1));
1447                 stat.flags = tmp & 0xFF;
1448                 stat.cnt1 = (tmp & 0x0F00) >> 8;
1449                 stat.cnt2 = (tmp & 0xF000) >> 12;
1450                 stat.seq = (u16)(v1 & 0xFFFF);
1451                 stat.unknown = (u16)((v1 >> 16) & 0xFF);
1452
1453                 bcm43xx_debugfs_log_txstat(bcm, &stat);
1454
1455                 if (stat.flags & BCM43xx_TXSTAT_FLAG_IGNORE)
1456                         continue;
1457                 if (!(stat.flags & BCM43xx_TXSTAT_FLAG_ACK)) {
1458                         //TODO: packet was not acked (was lost)
1459                 }
1460                 //TODO: There are more (unknown) flags to test. see bcm43xx_main.h
1461
1462                 if (bcm43xx_using_pio(bcm))
1463                         bcm43xx_pio_handle_xmitstatus(bcm, &stat);
1464                 else
1465                         bcm43xx_dma_handle_xmitstatus(bcm, &stat);
1466         }
1467 }
1468
1469 static void bcm43xx_generate_noise_sample(struct bcm43xx_private *bcm)
1470 {
1471         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x408, 0x7F7F);
1472         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x40A, 0x7F7F);
1473         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD,
1474                         bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD) | (1 << 4));
1475         assert(bcm->noisecalc.core_at_start == bcm->current_core);
1476         assert(bcm->noisecalc.channel_at_start == bcm->current_core->radio->channel);
1477 }
1478
1479 static void bcm43xx_calculate_link_quality(struct bcm43xx_private *bcm)
1480 {
1481         /* Top half of Link Quality calculation. */
1482
1483         if (bcm->noisecalc.calculation_running)
1484                 return;
1485         bcm->noisecalc.core_at_start = bcm->current_core;
1486         bcm->noisecalc.channel_at_start = bcm->current_core->radio->channel;
1487         bcm->noisecalc.calculation_running = 1;
1488         bcm->noisecalc.nr_samples = 0;
1489
1490         bcm43xx_generate_noise_sample(bcm);
1491 }
1492
1493 static void handle_irq_noise(struct bcm43xx_private *bcm)
1494 {
1495         struct bcm43xx_radioinfo *radio = bcm->current_core->radio;
1496         u16 tmp;
1497         u8 noise[4];
1498         u8 i, j;
1499         s32 average;
1500
1501         /* Bottom half of Link Quality calculation. */
1502
1503         assert(bcm->noisecalc.calculation_running);
1504         if (bcm->noisecalc.core_at_start != bcm->current_core ||
1505             bcm->noisecalc.channel_at_start != radio->channel)
1506                 goto drop_calculation;
1507         tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x408);
1508         noise[0] = (tmp & 0x00FF);
1509         noise[1] = (tmp & 0xFF00) >> 8;
1510         tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x40A);
1511         noise[2] = (tmp & 0x00FF);
1512         noise[3] = (tmp & 0xFF00) >> 8;
1513         if (noise[0] == 0x7F || noise[1] == 0x7F ||
1514             noise[2] == 0x7F || noise[3] == 0x7F)
1515                 goto generate_new;
1516
1517         /* Get the noise samples. */
1518         assert(bcm->noisecalc.nr_samples <= 8);
1519         i = bcm->noisecalc.nr_samples;
1520         noise[0] = limit_value(noise[0], 0, ARRAY_SIZE(radio->nrssi_lt) - 1);
1521         noise[1] = limit_value(noise[1], 0, ARRAY_SIZE(radio->nrssi_lt) - 1);
1522         noise[2] = limit_value(noise[2], 0, ARRAY_SIZE(radio->nrssi_lt) - 1);
1523         noise[3] = limit_value(noise[3], 0, ARRAY_SIZE(radio->nrssi_lt) - 1);
1524         bcm->noisecalc.samples[i][0] = radio->nrssi_lt[noise[0]];
1525         bcm->noisecalc.samples[i][1] = radio->nrssi_lt[noise[1]];
1526         bcm->noisecalc.samples[i][2] = radio->nrssi_lt[noise[2]];
1527         bcm->noisecalc.samples[i][3] = radio->nrssi_lt[noise[3]];
1528         bcm->noisecalc.nr_samples++;
1529         if (bcm->noisecalc.nr_samples == 8) {
1530                 /* Calculate the Link Quality by the noise samples. */
1531                 average = 0;
1532                 for (i = 0; i < 8; i++) {
1533                         for (j = 0; j < 4; j++)
1534                                 average += bcm->noisecalc.samples[i][j];
1535                 }
1536                 average /= (8 * 4);
1537                 average *= 125;
1538                 average += 64;
1539                 average /= 128;
1540                 tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x40C);
1541                 tmp = (tmp / 128) & 0x1F;
1542                 if (tmp >= 8)
1543                         average += 2;
1544                 else
1545                         average -= 25;
1546                 if (tmp == 8)
1547                         average -= 72;
1548                 else
1549                         average -= 48;
1550
1551                 if (average > -65)
1552                         bcm->stats.link_quality = 0;
1553                 else if (average > -75)
1554                         bcm->stats.link_quality = 1;
1555                 else if (average > -85)
1556                         bcm->stats.link_quality = 2;
1557                 else
1558                         bcm->stats.link_quality = 3;
1559 //              dprintk(KERN_INFO PFX "Link Quality: %u (avg was %d)\n", bcm->stats.link_quality, average);
1560 drop_calculation:
1561                 bcm->noisecalc.calculation_running = 0;
1562                 return;
1563         }
1564 generate_new:
1565         bcm43xx_generate_noise_sample(bcm);
1566 }
1567
1568 static void handle_irq_ps(struct bcm43xx_private *bcm)
1569 {
1570         if (bcm->ieee->iw_mode == IW_MODE_MASTER) {
1571                 ///TODO: PS TBTT
1572         } else {
1573                 if (1/*FIXME: the last PSpoll frame was sent successfully */)
1574                         bcm43xx_power_saving_ctl_bits(bcm, -1, -1);
1575         }
1576         if (bcm->ieee->iw_mode == IW_MODE_ADHOC)
1577                 bcm->reg124_set_0x4 = 1;
1578         //FIXME else set to false?
1579 }
1580
1581 static void handle_irq_reg124(struct bcm43xx_private *bcm)
1582 {
1583         if (!bcm->reg124_set_0x4)
1584                 return;
1585         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD,
1586                         bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD)
1587                         | 0x4);
1588         //FIXME: reset reg124_set_0x4 to false?
1589 }
1590
1591 static void handle_irq_pmq(struct bcm43xx_private *bcm)
1592 {
1593         u32 tmp;
1594
1595         //TODO: AP mode.
1596
1597         while (1) {
1598                 tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_PS_STATUS);
1599                 if (!(tmp & 0x00000008))
1600                         break;
1601         }
1602         /* 16bit write is odd, but correct. */
1603         bcm43xx_write16(bcm, BCM43xx_MMIO_PS_STATUS, 0x0002);
1604 }
1605
1606 static void bcm43xx_generate_beacon_template(struct bcm43xx_private *bcm,
1607                                              u16 ram_offset, u16 shm_size_offset)
1608 {
1609         u32 value;
1610         u16 size = 0;
1611
1612         /* Timestamp. */
1613         //FIXME: assumption: The chip sets the timestamp
1614         value = 0;
1615         bcm43xx_ram_write(bcm, ram_offset++, value);
1616         bcm43xx_ram_write(bcm, ram_offset++, value);
1617         size += 8;
1618
1619         /* Beacon Interval / Capability Information */
1620         value = 0x0000;//FIXME: Which interval?
1621         value |= (1 << 0) << 16; /* ESS */
1622         value |= (1 << 2) << 16; /* CF Pollable */      //FIXME?
1623         value |= (1 << 3) << 16; /* CF Poll Request */  //FIXME?
1624         if (!bcm->ieee->open_wep)
1625                 value |= (1 << 4) << 16; /* Privacy */
1626         bcm43xx_ram_write(bcm, ram_offset++, value);
1627         size += 4;
1628
1629         /* SSID */
1630         //TODO
1631
1632         /* FH Parameter Set */
1633         //TODO
1634
1635         /* DS Parameter Set */
1636         //TODO
1637
1638         /* CF Parameter Set */
1639         //TODO
1640
1641         /* TIM */
1642         //TODO
1643
1644         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, shm_size_offset, size);
1645 }
1646
1647 static void handle_irq_beacon(struct bcm43xx_private *bcm)
1648 {
1649         u32 status;
1650
1651         bcm->irq_savedstate &= ~BCM43xx_IRQ_BEACON;
1652         status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD);
1653
1654         if ((status & 0x1) && (status & 0x2)) {
1655                 /* ACK beacon IRQ. */
1656                 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON,
1657                                 BCM43xx_IRQ_BEACON);
1658                 bcm->irq_savedstate |= BCM43xx_IRQ_BEACON;
1659                 return;
1660         }
1661         if (!(status & 0x1)) {
1662                 bcm43xx_generate_beacon_template(bcm, 0x68, 0x18);
1663                 status |= 0x1;
1664                 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, status);
1665         }
1666         if (!(status & 0x2)) {
1667                 bcm43xx_generate_beacon_template(bcm, 0x468, 0x1A);
1668                 status |= 0x2;
1669                 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, status);
1670         }
1671 }
1672
1673 /* Interrupt handler bottom-half */
1674 static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1675 {
1676         u32 reason;
1677         u32 dma_reason[4];
1678         int activity = 0;
1679         unsigned long flags;
1680
1681 #ifdef CONFIG_BCM43XX_DEBUG
1682         u32 _handled = 0x00000000;
1683 # define bcmirq_handled(irq)    do { _handled |= (irq); } while (0)
1684 #else
1685 # define bcmirq_handled(irq)    do { /* nothing */ } while (0)
1686 #endif /* CONFIG_BCM43XX_DEBUG*/
1687
1688         bcm43xx_lock_mmio(bcm, flags);
1689         reason = bcm->irq_reason;
1690         dma_reason[0] = bcm->dma_reason[0];
1691         dma_reason[1] = bcm->dma_reason[1];
1692         dma_reason[2] = bcm->dma_reason[2];
1693         dma_reason[3] = bcm->dma_reason[3];
1694
1695         if (unlikely(reason & BCM43xx_IRQ_XMIT_ERROR)) {
1696                 /* TX error. We get this when Template Ram is written in wrong endianess
1697                  * in dummy_tx(). We also get this if something is wrong with the TX header
1698                  * on DMA or PIO queues.
1699                  * Maybe we get this in other error conditions, too.
1700                  */
1701                 printkl(KERN_ERR PFX "FATAL ERROR: BCM43xx_IRQ_XMIT_ERROR\n");
1702                 bcmirq_handled(BCM43xx_IRQ_XMIT_ERROR);
1703         }
1704         if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_FATALMASK) |
1705                      (dma_reason[1] & BCM43xx_DMAIRQ_FATALMASK) |
1706                      (dma_reason[2] & BCM43xx_DMAIRQ_FATALMASK) |
1707                      (dma_reason[3] & BCM43xx_DMAIRQ_FATALMASK))) {
1708                 printkl(KERN_ERR PFX "FATAL ERROR: Fatal DMA error: "
1709                                      "0x%08X, 0x%08X, 0x%08X, 0x%08X\n",
1710                         dma_reason[0], dma_reason[1],
1711                         dma_reason[2], dma_reason[3]);
1712                 bcm43xx_controller_restart(bcm, "DMA error");
1713                 bcm43xx_unlock_mmio(bcm, flags);
1714                 return;
1715         }
1716         if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_NONFATALMASK) |
1717                      (dma_reason[1] & BCM43xx_DMAIRQ_NONFATALMASK) |
1718                      (dma_reason[2] & BCM43xx_DMAIRQ_NONFATALMASK) |
1719                      (dma_reason[3] & BCM43xx_DMAIRQ_NONFATALMASK))) {
1720                 printkl(KERN_ERR PFX "DMA error: "
1721                                      "0x%08X, 0x%08X, 0x%08X, 0x%08X\n",
1722                         dma_reason[0], dma_reason[1],
1723                         dma_reason[2], dma_reason[3]);
1724         }
1725
1726         if (reason & BCM43xx_IRQ_PS) {
1727                 handle_irq_ps(bcm);
1728                 bcmirq_handled(BCM43xx_IRQ_PS);
1729         }
1730
1731         if (reason & BCM43xx_IRQ_REG124) {
1732                 handle_irq_reg124(bcm);
1733                 bcmirq_handled(BCM43xx_IRQ_REG124);
1734         }
1735
1736         if (reason & BCM43xx_IRQ_BEACON) {
1737                 if (bcm->ieee->iw_mode == IW_MODE_MASTER)
1738                         handle_irq_beacon(bcm);
1739                 bcmirq_handled(BCM43xx_IRQ_BEACON);
1740         }
1741
1742         if (reason & BCM43xx_IRQ_PMQ) {
1743                 handle_irq_pmq(bcm);
1744                 bcmirq_handled(BCM43xx_IRQ_PMQ);
1745         }
1746
1747         if (reason & BCM43xx_IRQ_SCAN) {
1748                 /*TODO*/
1749                 //bcmirq_handled(BCM43xx_IRQ_SCAN);
1750         }
1751
1752         if (reason & BCM43xx_IRQ_NOISE) {
1753                 handle_irq_noise(bcm);
1754                 bcmirq_handled(BCM43xx_IRQ_NOISE);
1755         }
1756
1757         /* Check the DMA reason registers for received data. */
1758         assert(!(dma_reason[1] & BCM43xx_DMAIRQ_RX_DONE));
1759         assert(!(dma_reason[2] & BCM43xx_DMAIRQ_RX_DONE));
1760         if (dma_reason[0] & BCM43xx_DMAIRQ_RX_DONE) {
1761                 if (bcm43xx_using_pio(bcm))
1762                         bcm43xx_pio_rx(bcm->current_core->pio->queue0);
1763                 else
1764                         bcm43xx_dma_rx(bcm->current_core->dma->rx_ring0);
1765                 /* We intentionally don't set "activity" to 1, here. */
1766         }
1767         if (dma_reason[3] & BCM43xx_DMAIRQ_RX_DONE) {
1768                 if (bcm43xx_using_pio(bcm))
1769                         bcm43xx_pio_rx(bcm->current_core->pio->queue3);
1770                 else
1771                         bcm43xx_dma_rx(bcm->current_core->dma->rx_ring1);
1772                 activity = 1;
1773         }
1774         bcmirq_handled(BCM43xx_IRQ_RX);
1775
1776         if (reason & BCM43xx_IRQ_XMIT_STATUS) {
1777                 handle_irq_transmit_status(bcm);
1778                 activity = 1;
1779                 //TODO: In AP mode, this also causes sending of powersave responses.
1780                 bcmirq_handled(BCM43xx_IRQ_XMIT_STATUS);
1781         }
1782
1783         /* We get spurious IRQs, althought they are masked.
1784          * Assume they are void and ignore them.
1785          */
1786         bcmirq_handled(~(bcm->irq_savedstate));
1787         /* IRQ_PIO_WORKAROUND is handled in the top-half. */
1788         bcmirq_handled(BCM43xx_IRQ_PIO_WORKAROUND);
1789 #ifdef CONFIG_BCM43XX_DEBUG
1790         if (unlikely(reason & ~_handled)) {
1791                 printkl(KERN_WARNING PFX
1792                         "Unhandled IRQ! Reason: 0x%08x,  Unhandled: 0x%08x,  "
1793                         "DMA: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
1794                         reason, (reason & ~_handled),
1795                         dma_reason[0], dma_reason[1],
1796                         dma_reason[2], dma_reason[3]);
1797         }
1798 #endif
1799 #undef bcmirq_handled
1800
1801         if (!modparam_noleds)
1802                 bcm43xx_leds_update(bcm, activity);
1803         bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
1804         bcm43xx_unlock_mmio(bcm, flags);
1805 }
1806
1807 static void bcm43xx_interrupt_ack(struct bcm43xx_private *bcm,
1808                                   u32 reason, u32 mask)
1809 {
1810         bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON)
1811                              & 0x0001dc00;
1812         bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA2_REASON)
1813                              & 0x0000dc00;
1814         bcm->dma_reason[2] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA3_REASON)
1815                              & 0x0000dc00;
1816         bcm->dma_reason[3] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_REASON)
1817                              & 0x0001dc00;
1818
1819         if (bcm43xx_using_pio(bcm) &&
1820             (bcm->current_core->rev < 3) &&
1821             (!(reason & BCM43xx_IRQ_PIO_WORKAROUND))) {
1822                 /* Apply a PIO specific workaround to the dma_reasons */
1823
1824 #define apply_pio_workaround(BASE, QNUM) \
1825         do {                                                                                    \
1826         if (bcm43xx_read16(bcm, BASE + BCM43xx_PIO_RXCTL) & BCM43xx_PIO_RXCTL_DATAAVAILABLE)    \
1827                 bcm->dma_reason[QNUM] |= 0x00010000;                                            \
1828         else                                                                                    \
1829                 bcm->dma_reason[QNUM] &= ~0x00010000;                                           \
1830         } while (0)
1831
1832                 apply_pio_workaround(BCM43xx_MMIO_PIO1_BASE, 0);
1833                 apply_pio_workaround(BCM43xx_MMIO_PIO2_BASE, 1);
1834                 apply_pio_workaround(BCM43xx_MMIO_PIO3_BASE, 2);
1835                 apply_pio_workaround(BCM43xx_MMIO_PIO4_BASE, 3);
1836
1837 #undef apply_pio_workaround
1838         }
1839
1840         bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON,
1841                         reason & mask);
1842
1843         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_REASON,
1844                         bcm->dma_reason[0]);
1845         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_REASON,
1846                         bcm->dma_reason[1]);
1847         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_REASON,
1848                         bcm->dma_reason[2]);
1849         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_REASON,
1850                         bcm->dma_reason[3]);
1851 }
1852
1853 /* Interrupt handler top-half */
1854 static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_regs *regs)
1855 {
1856         irqreturn_t ret = IRQ_HANDLED;
1857         struct bcm43xx_private *bcm = dev_id;
1858         u32 reason, mask;
1859
1860         if (!bcm)
1861                 return IRQ_NONE;
1862
1863         spin_lock(&bcm->_lock);
1864
1865         reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
1866         if (reason == 0xffffffff) {
1867                 /* irq not for us (shared irq) */
1868                 ret = IRQ_NONE;
1869                 goto out;
1870         }
1871         mask = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK);
1872         if (!(reason & mask))
1873                 goto out;
1874
1875         bcm43xx_interrupt_ack(bcm, reason, mask);
1876
1877         /* Only accept IRQs, if we are initialized properly.
1878          * This avoids an RX race while initializing.
1879          * We should probably not enable IRQs before we are initialized
1880          * completely, but some careful work is needed to fix this. I think it
1881          * is best to stay with this cheap workaround for now... .
1882          */
1883         if (likely(bcm->initialized)) {
1884                 /* disable all IRQs. They are enabled again in the bottom half. */
1885                 bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
1886                 /* save the reason code and call our bottom half. */
1887                 bcm->irq_reason = reason;
1888                 tasklet_schedule(&bcm->isr_tasklet);
1889         }
1890
1891 out:
1892         mmiowb();
1893         spin_unlock(&bcm->_lock);
1894
1895         return ret;
1896 }
1897
1898 static void bcm43xx_release_firmware(struct bcm43xx_private *bcm, int force)
1899 {
1900         if (bcm->firmware_norelease && !force)
1901                 return; /* Suspending or controller reset. */
1902         release_firmware(bcm->ucode);
1903         bcm->ucode = NULL;
1904         release_firmware(bcm->pcm);
1905         bcm->pcm = NULL;
1906         release_firmware(bcm->initvals0);
1907         bcm->initvals0 = NULL;
1908         release_firmware(bcm->initvals1);
1909         bcm->initvals1 = NULL;
1910 }
1911
1912 static int bcm43xx_request_firmware(struct bcm43xx_private *bcm)
1913 {
1914         struct bcm43xx_phyinfo *phy = bcm->current_core->phy;
1915         u8 rev = bcm->current_core->rev;
1916         int err = 0;
1917         int nr;
1918         char buf[22 + sizeof(modparam_fwpostfix) - 1] = { 0 };
1919
1920         if (!bcm->ucode) {
1921                 snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_microcode%d%s.fw",
1922                          (rev >= 5 ? 5 : rev),
1923                          modparam_fwpostfix);
1924                 err = request_firmware(&bcm->ucode, buf, &bcm->pci_dev->dev);
1925                 if (err) {
1926                         printk(KERN_ERR PFX 
1927                                "Error: Microcode \"%s\" not available or load failed.\n",
1928                                 buf);
1929                         goto error;
1930                 }
1931         }
1932
1933         if (!bcm->pcm) {
1934                 snprintf(buf, ARRAY_SIZE(buf),
1935                          "bcm43xx_pcm%d%s.fw",
1936                          (rev < 5 ? 4 : 5),
1937                          modparam_fwpostfix);
1938                 err = request_firmware(&bcm->pcm, buf, &bcm->pci_dev->dev);
1939                 if (err) {
1940                         printk(KERN_ERR PFX
1941                                "Error: PCM \"%s\" not available or load failed.\n",
1942                                buf);
1943                         goto error;
1944                 }
1945         }
1946
1947         if (!bcm->initvals0) {
1948                 if (rev == 2 || rev == 4) {
1949                         switch (phy->type) {
1950                         case BCM43xx_PHYTYPE_A:
1951                                 nr = 3;
1952                                 break;
1953                         case BCM43xx_PHYTYPE_B:
1954                         case BCM43xx_PHYTYPE_G:
1955                                 nr = 1;
1956                                 break;
1957                         default:
1958                                 goto err_noinitval;
1959                         }
1960                 
1961                 } else if (rev >= 5) {
1962                         switch (phy->type) {
1963                         case BCM43xx_PHYTYPE_A:
1964                                 nr = 7;
1965                                 break;
1966                         case BCM43xx_PHYTYPE_B:
1967                         case BCM43xx_PHYTYPE_G:
1968                                 nr = 5;
1969                                 break;
1970                         default:
1971                                 goto err_noinitval;
1972                         }
1973                 } else
1974                         goto err_noinitval;
1975                 snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_initval%02d%s.fw",
1976                          nr, modparam_fwpostfix);
1977
1978                 err = request_firmware(&bcm->initvals0, buf, &bcm->pci_dev->dev);
1979                 if (err) {
1980                         printk(KERN_ERR PFX 
1981                                "Error: InitVals \"%s\" not available or load failed.\n",
1982                                 buf);
1983                         goto error;
1984                 }
1985                 if (bcm->initvals0->size % sizeof(struct bcm43xx_initval)) {
1986                         printk(KERN_ERR PFX "InitVals fileformat error.\n");
1987                         goto error;
1988                 }
1989         }
1990
1991         if (!bcm->initvals1) {
1992                 if (rev >= 5) {
1993                         u32 sbtmstatehigh;
1994
1995                         switch (phy->type) {
1996                         case BCM43xx_PHYTYPE_A:
1997                                 sbtmstatehigh = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH);
1998                                 if (sbtmstatehigh & 0x00010000)
1999                                         nr = 9;
2000                                 else
2001                                         nr = 10;
2002                                 break;
2003                         case BCM43xx_PHYTYPE_B:
2004                         case BCM43xx_PHYTYPE_G:
2005                                         nr = 6;
2006                                 break;
2007                         default:
2008                                 goto err_noinitval;
2009                         }
2010                         snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_initval%02d%s.fw",
2011                                  nr, modparam_fwpostfix);
2012
2013                         err = request_firmware(&bcm->initvals1, buf, &bcm->pci_dev->dev);
2014                         if (err) {
2015                                 printk(KERN_ERR PFX 
2016                                        "Error: InitVals \"%s\" not available or load failed.\n",
2017                                         buf);
2018                                 goto error;
2019                         }
2020                         if (bcm->initvals1->size % sizeof(struct bcm43xx_initval)) {
2021                                 printk(KERN_ERR PFX "InitVals fileformat error.\n");
2022                                 goto error;
2023                         }
2024                 }
2025         }
2026
2027 out:
2028         return err;
2029 error:
2030         bcm43xx_release_firmware(bcm, 1);
2031         goto out;
2032 err_noinitval:
2033         printk(KERN_ERR PFX "Error: No InitVals available!\n");
2034         err = -ENOENT;
2035         goto error;
2036 }
2037
2038 static void bcm43xx_upload_microcode(struct bcm43xx_private *bcm)
2039 {
2040         const u32 *data;
2041         unsigned int i, len;
2042
2043         /* Upload Microcode. */
2044         data = (u32 *)(bcm->ucode->data);
2045         len = bcm->ucode->size / sizeof(u32);
2046         bcm43xx_shm_control_word(bcm, BCM43xx_SHM_UCODE, 0x0000);
2047         for (i = 0; i < len; i++) {
2048                 bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA,
2049                                 be32_to_cpu(data[i]));
2050                 udelay(10);
2051         }
2052
2053         /* Upload PCM data. */
2054         data = (u32 *)(bcm->pcm->data);
2055         len = bcm->pcm->size / sizeof(u32);
2056         bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01ea);
2057         bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, 0x00004000);
2058         bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01eb);
2059         for (i = 0; i < len; i++) {
2060                 bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA,
2061                                 be32_to_cpu(data[i]));
2062                 udelay(10);
2063         }
2064 }
2065
2066 static int bcm43xx_write_initvals(struct bcm43xx_private *bcm,
2067                                   const struct bcm43xx_initval *data,
2068                                   const unsigned int len)
2069 {
2070         u16 offset, size;
2071         u32 value;
2072         unsigned int i;
2073
2074         for (i = 0; i < len; i++) {
2075                 offset = be16_to_cpu(data[i].offset);
2076                 size = be16_to_cpu(data[i].size);
2077                 value = be32_to_cpu(data[i].value);
2078
2079                 if (unlikely(offset >= 0x1000))
2080                         goto err_format;
2081                 if (size == 2) {
2082                         if (unlikely(value & 0xFFFF0000))
2083                                 goto err_format;
2084                         bcm43xx_write16(bcm, offset, (u16)value);
2085                 } else if (size == 4) {
2086                         bcm43xx_write32(bcm, offset, value);
2087                 } else
2088                         goto err_format;
2089         }
2090
2091         return 0;
2092
2093 err_format:
2094         printk(KERN_ERR PFX "InitVals (bcm43xx_initvalXX.fw) file-format error. "
2095                             "Please fix your bcm43xx firmware files.\n");
2096         return -EPROTO;
2097 }
2098
2099 static int bcm43xx_upload_initvals(struct bcm43xx_private *bcm)
2100 {
2101         int err;
2102
2103         err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)bcm->initvals0->data,
2104                                      bcm->initvals0->size / sizeof(struct bcm43xx_initval));
2105         if (err)
2106                 goto out;
2107         if (bcm->initvals1) {
2108                 err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)bcm->initvals1->data,
2109                                              bcm->initvals1->size / sizeof(struct bcm43xx_initval));
2110                 if (err)
2111                         goto out;
2112         }
2113 out:
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         bcm43xx_lock_mmio(bcm, 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         bcm43xx_unlock_mmio(bcm, 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         bcm43xx_lock(bcm, flags);
3168         bcm->initialized = 0;
3169         bcm->shutting_down = 1;
3170         bcm43xx_unlock(bcm, 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         bcm43xx_lock(bcm, flags);
3186         bcm->shutting_down = 0;
3187         bcm43xx_unlock(bcm, 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         bcm43xx_lock(bcm, flags);
3200         bcm->initialized = 0;
3201         bcm->shutting_down = 0;
3202         bcm43xx_unlock(bcm, 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         bcm43xx_lock(bcm, flags);
3271         bcm->initialized = 1;
3272         bcm43xx_unlock(bcm, 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         bcm43xx_lock_mmio(bcm, flags);
3574         bcm43xx_mac_suspend(bcm);
3575         bcm43xx_radio_selectchannel(bcm, channel, 0);
3576         bcm43xx_mac_enable(bcm);
3577         bcm43xx_unlock_mmio(bcm, 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         bcm43xx_lock_mmio(bcm, 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         bcm43xx_unlock_mmio(bcm, 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         bcm43xx_lock_mmio(bcm, flags);
3667         if (likely(bcm->initialized))
3668                 err = bcm43xx_tx(bcm, txb);
3669         bcm43xx_unlock_mmio(bcm, 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         unsigned long flags;
3683
3684         bcm43xx_lock_mmio(bcm, flags);
3685         bcm43xx_controller_restart(bcm, "TX timeout");
3686         bcm43xx_unlock_mmio(bcm, flags);
3687 }
3688
3689 #ifdef CONFIG_NET_POLL_CONTROLLER
3690 static void bcm43xx_net_poll_controller(struct net_device *net_dev)
3691 {
3692         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3693         unsigned long flags;
3694
3695         local_irq_save(flags);
3696         bcm43xx_interrupt_handler(bcm->irq, bcm, NULL);
3697         local_irq_restore(flags);
3698 }
3699 #endif /* CONFIG_NET_POLL_CONTROLLER */
3700
3701 static int bcm43xx_net_open(struct net_device *net_dev)
3702 {
3703         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3704
3705         return bcm43xx_init_board(bcm);
3706 }
3707
3708 static int bcm43xx_net_stop(struct net_device *net_dev)
3709 {
3710         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3711
3712         ieee80211softmac_stop(net_dev);
3713         bcm43xx_disable_interrupts_sync(bcm, NULL);
3714         bcm43xx_free_board(bcm);
3715
3716         return 0;
3717 }
3718
3719 static int bcm43xx_init_private(struct bcm43xx_private *bcm,
3720                                 struct net_device *net_dev,
3721                                 struct pci_dev *pci_dev)
3722 {
3723         int err;
3724
3725         bcm->ieee = netdev_priv(net_dev);
3726         bcm->softmac = ieee80211_priv(net_dev);
3727         bcm->softmac->set_channel = bcm43xx_ieee80211_set_chan;
3728
3729         bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
3730         bcm->pci_dev = pci_dev;
3731         bcm->net_dev = net_dev;
3732         bcm->bad_frames_preempt = modparam_bad_frames_preempt;
3733         spin_lock_init(&bcm->_lock);
3734         tasklet_init(&bcm->isr_tasklet,
3735                      (void (*)(unsigned long))bcm43xx_interrupt_tasklet,
3736                      (unsigned long)bcm);
3737         tasklet_disable_nosync(&bcm->isr_tasklet);
3738         if (modparam_pio) {
3739                 bcm->__using_pio = 1;
3740         } else {
3741                 err = pci_set_dma_mask(pci_dev, DMA_30BIT_MASK);
3742                 err |= pci_set_consistent_dma_mask(pci_dev, DMA_30BIT_MASK);
3743                 if (err) {
3744 #ifdef CONFIG_BCM43XX_PIO
3745                         printk(KERN_WARNING PFX "DMA not supported. Falling back to PIO.\n");
3746                         bcm->__using_pio = 1;
3747 #else
3748                         printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. "
3749                                             "Recompile the driver with PIO support, please.\n");
3750                         return -ENODEV;
3751 #endif /* CONFIG_BCM43XX_PIO */
3752                 }
3753         }
3754         bcm->rts_threshold = BCM43xx_DEFAULT_RTS_THRESHOLD;
3755
3756         /* default to sw encryption for now */
3757         bcm->ieee->host_build_iv = 0;
3758         bcm->ieee->host_encrypt = 1;
3759         bcm->ieee->host_decrypt = 1;
3760         
3761         bcm->ieee->iw_mode = BCM43xx_INITIAL_IWMODE;
3762         bcm->ieee->tx_headroom = sizeof(struct bcm43xx_txhdr);
3763         bcm->ieee->set_security = bcm43xx_ieee80211_set_security;
3764         bcm->ieee->hard_start_xmit = bcm43xx_ieee80211_hard_start_xmit;
3765
3766         return 0;
3767 }
3768
3769 static int __devinit bcm43xx_init_one(struct pci_dev *pdev,
3770                                       const struct pci_device_id *ent)
3771 {
3772         struct net_device *net_dev;
3773         struct bcm43xx_private *bcm;
3774         int err;
3775
3776 #ifdef CONFIG_BCM947XX
3777         if ((pdev->bus->number == 0) && (pdev->device != 0x0800))
3778                 return -ENODEV;
3779 #endif
3780
3781 #ifdef DEBUG_SINGLE_DEVICE_ONLY
3782         if (strcmp(pci_name(pdev), DEBUG_SINGLE_DEVICE_ONLY))
3783                 return -ENODEV;
3784 #endif
3785
3786         net_dev = alloc_ieee80211softmac(sizeof(*bcm));
3787         if (!net_dev) {
3788                 printk(KERN_ERR PFX
3789                        "could not allocate ieee80211 device %s\n",
3790                        pci_name(pdev));
3791                 err = -ENOMEM;
3792                 goto out;
3793         }
3794         /* initialize the net_device struct */
3795         SET_MODULE_OWNER(net_dev);
3796         SET_NETDEV_DEV(net_dev, &pdev->dev);
3797
3798         net_dev->open = bcm43xx_net_open;
3799         net_dev->stop = bcm43xx_net_stop;
3800         net_dev->get_stats = bcm43xx_net_get_stats;
3801         net_dev->tx_timeout = bcm43xx_net_tx_timeout;
3802 #ifdef CONFIG_NET_POLL_CONTROLLER
3803         net_dev->poll_controller = bcm43xx_net_poll_controller;
3804 #endif
3805         net_dev->wireless_handlers = &bcm43xx_wx_handlers_def;
3806         net_dev->irq = pdev->irq;
3807         SET_ETHTOOL_OPS(net_dev, &bcm43xx_ethtool_ops);
3808
3809         /* initialize the bcm43xx_private struct */
3810         bcm = bcm43xx_priv(net_dev);
3811         memset(bcm, 0, sizeof(*bcm));
3812         err = bcm43xx_init_private(bcm, net_dev, pdev);
3813         if (err)
3814                 goto err_free_netdev;
3815
3816         pci_set_drvdata(pdev, net_dev);
3817
3818         err = bcm43xx_attach_board(bcm);
3819         if (err)
3820                 goto err_free_netdev;
3821
3822         err = register_netdev(net_dev);
3823         if (err) {
3824                 printk(KERN_ERR PFX "Cannot register net device, "
3825                        "aborting.\n");
3826                 err = -ENOMEM;
3827                 goto err_detach_board;
3828         }
3829
3830         bcm43xx_debugfs_add_device(bcm);
3831
3832         assert(err == 0);
3833 out:
3834         return err;
3835
3836 err_detach_board:
3837         bcm43xx_detach_board(bcm);
3838 err_free_netdev:
3839         free_ieee80211softmac(net_dev);
3840         goto out;
3841 }
3842
3843 static void __devexit bcm43xx_remove_one(struct pci_dev *pdev)
3844 {
3845         struct net_device *net_dev = pci_get_drvdata(pdev);
3846         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3847
3848         bcm43xx_debugfs_remove_device(bcm);
3849         unregister_netdev(net_dev);
3850         bcm43xx_detach_board(bcm);
3851         assert(bcm->ucode == NULL);
3852         free_ieee80211softmac(net_dev);
3853 }
3854
3855 /* Hard-reset the chip. Do not call this directly.
3856  * Use bcm43xx_controller_restart()
3857  */
3858 static void bcm43xx_chip_reset(void *_bcm)
3859 {
3860         struct bcm43xx_private *bcm = _bcm;
3861         struct net_device *net_dev = bcm->net_dev;
3862         struct pci_dev *pci_dev = bcm->pci_dev;
3863         int err;
3864         int was_initialized = bcm->initialized;
3865
3866         netif_stop_queue(bcm->net_dev);
3867         tasklet_disable(&bcm->isr_tasklet);
3868
3869         bcm->firmware_norelease = 1;
3870         if (was_initialized)
3871                 bcm43xx_free_board(bcm);
3872         bcm->firmware_norelease = 0;
3873         bcm43xx_detach_board(bcm);
3874         err = bcm43xx_init_private(bcm, net_dev, pci_dev);
3875         if (err)
3876                 goto failure;
3877         err = bcm43xx_attach_board(bcm);
3878         if (err)
3879                 goto failure;
3880         if (was_initialized) {
3881                 err = bcm43xx_init_board(bcm);
3882                 if (err)
3883                         goto failure;
3884         }
3885         netif_wake_queue(bcm->net_dev);
3886         printk(KERN_INFO PFX "Controller restarted\n");
3887
3888         return;
3889 failure:
3890         printk(KERN_ERR PFX "Controller restart failed\n");
3891 }
3892
3893 /* Hard-reset the chip.
3894  * This can be called from interrupt or process context.
3895  * Make sure to _not_ re-enable device interrupts after this has been called.
3896 */
3897 void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason)
3898 {
3899         bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3900         bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
3901         printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason);
3902         INIT_WORK(&bcm->restart_work, bcm43xx_chip_reset, bcm);
3903         schedule_work(&bcm->restart_work);
3904 }
3905
3906 #ifdef CONFIG_PM
3907
3908 static int bcm43xx_suspend(struct pci_dev *pdev, pm_message_t state)
3909 {
3910         struct net_device *net_dev = pci_get_drvdata(pdev);
3911         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3912         unsigned long flags;
3913         int try_to_shutdown = 0, err;
3914
3915         dprintk(KERN_INFO PFX "Suspending...\n");
3916
3917         bcm43xx_lock(bcm, flags);
3918         bcm->was_initialized = bcm->initialized;
3919         if (bcm->initialized)
3920                 try_to_shutdown = 1;
3921         bcm43xx_unlock(bcm, flags);
3922
3923         netif_device_detach(net_dev);
3924         if (try_to_shutdown) {
3925                 ieee80211softmac_stop(net_dev);
3926                 err = bcm43xx_disable_interrupts_sync(bcm, &bcm->irq_savedstate);
3927                 if (unlikely(err)) {
3928                         dprintk(KERN_ERR PFX "Suspend failed.\n");
3929                         return -EAGAIN;
3930                 }
3931                 bcm->firmware_norelease = 1;
3932                 bcm43xx_free_board(bcm);
3933                 bcm->firmware_norelease = 0;
3934         }
3935         bcm43xx_chipset_detach(bcm);
3936
3937         pci_save_state(pdev);
3938         pci_disable_device(pdev);
3939         pci_set_power_state(pdev, pci_choose_state(pdev, state));
3940
3941         dprintk(KERN_INFO PFX "Device suspended.\n");
3942
3943         return 0;
3944 }
3945
3946 static int bcm43xx_resume(struct pci_dev *pdev)
3947 {
3948         struct net_device *net_dev = pci_get_drvdata(pdev);
3949         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3950         int err = 0;
3951
3952         dprintk(KERN_INFO PFX "Resuming...\n");
3953
3954         pci_set_power_state(pdev, 0);
3955         pci_enable_device(pdev);
3956         pci_restore_state(pdev);
3957
3958         bcm43xx_chipset_attach(bcm);
3959         if (bcm->was_initialized) {
3960                 bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
3961                 err = bcm43xx_init_board(bcm);
3962         }
3963         if (err) {
3964                 printk(KERN_ERR PFX "Resume failed!\n");
3965                 return err;
3966         }
3967
3968         netif_device_attach(net_dev);
3969         
3970         /*FIXME: This should be handled by softmac instead. */
3971         schedule_work(&bcm->softmac->associnfo.work);
3972
3973         dprintk(KERN_INFO PFX "Device resumed.\n");
3974
3975         return 0;
3976 }
3977
3978 #endif                          /* CONFIG_PM */
3979
3980 static struct pci_driver bcm43xx_pci_driver = {
3981         .name = KBUILD_MODNAME,
3982         .id_table = bcm43xx_pci_tbl,
3983         .probe = bcm43xx_init_one,
3984         .remove = __devexit_p(bcm43xx_remove_one),
3985 #ifdef CONFIG_PM
3986         .suspend = bcm43xx_suspend,
3987         .resume = bcm43xx_resume,
3988 #endif                          /* CONFIG_PM */
3989 };
3990
3991 static int __init bcm43xx_init(void)
3992 {
3993         printk(KERN_INFO KBUILD_MODNAME " driver\n");
3994         bcm43xx_debugfs_init();
3995         return pci_register_driver(&bcm43xx_pci_driver);
3996 }
3997
3998 static void __exit bcm43xx_exit(void)
3999 {
4000         pci_unregister_driver(&bcm43xx_pci_driver);
4001         bcm43xx_debugfs_exit();
4002 }
4003
4004 module_init(bcm43xx_init)
4005 module_exit(bcm43xx_exit)
4006
4007 /* vim: set ts=8 sw=8 sts=8: */