]> err.no Git - linux-2.6/blob - drivers/net/wireless/bcm43xx/bcm43xx_main.c
[PATCH] bcm43xx: Remove the workaround in dummy_transmission,
[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 (bcm43xx_current_phy(bcm)->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 (bcm43xx_current_phy(bcm)->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 = bcm43xx_current_radio(bcm);
514         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
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 (phy->type == BCM43xx_PHYTYPE_A)
570                 radio->txpower_desired = bcm->sprom.maxpower_aphy;
571         else
572                 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;
933         u8 channel;
934         struct bcm43xx_phyinfo *phy;
935         const char *iso_country;
936
937         memset(&geo, 0, sizeof(geo));
938         for (i = 0; i < bcm->nr_80211_available; i++) {
939                 phy = &(bcm->core_80211_ext[i].phy);
940                 switch (phy->type) {
941                 case BCM43xx_PHYTYPE_B:
942                 case BCM43xx_PHYTYPE_G:
943                         have_bg = 1;
944                         break;
945                 case BCM43xx_PHYTYPE_A:
946                         have_a = 1;
947                         break;
948                 default:
949                         assert(0);
950                 }
951         }
952         iso_country = bcm43xx_locale_iso(bcm->sprom.locale);
953
954         if (have_a) {
955                 for (i = 0, channel = 0; channel < 201; channel++) {
956                         chan = &geo.a[i++];
957                         chan->freq = bcm43xx_channel_to_freq_a(channel);
958                         chan->channel = channel;
959                 }
960                 geo.a_channels = i;
961         }
962         if (have_bg) {
963                 for (i = 0, channel = 1; channel < 15; channel++) {
964                         chan = &geo.bg[i++];
965                         chan->freq = bcm43xx_channel_to_freq_bg(channel);
966                         chan->channel = channel;
967                 }
968                 geo.bg_channels = i;
969         }
970         memcpy(geo.name, iso_country, 2);
971         if (0 /*TODO: Outdoor use only */)
972                 geo.name[2] = 'O';
973         else if (0 /*TODO: Indoor use only */)
974                 geo.name[2] = 'I';
975         else
976                 geo.name[2] = ' ';
977         geo.name[3] = '\0';
978
979         ieee80211_set_geo(bcm->ieee, &geo);
980 }
981
982 /* DummyTransmission function, as documented on 
983  * http://bcm-specs.sipsolutions.net/DummyTransmission
984  */
985 void bcm43xx_dummy_transmission(struct bcm43xx_private *bcm)
986 {
987         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
988         struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
989         unsigned int i, max_loop;
990         u16 value = 0;
991         u32 buffer[5] = {
992                 0x00000000,
993                 0x0000D400,
994                 0x00000000,
995                 0x00000001,
996                 0x00000000,
997         };
998
999         switch (phy->type) {
1000         case BCM43xx_PHYTYPE_A:
1001                 max_loop = 0x1E;
1002                 buffer[0] = 0xCC010200;
1003                 break;
1004         case BCM43xx_PHYTYPE_B:
1005         case BCM43xx_PHYTYPE_G:
1006                 max_loop = 0xFA;
1007                 buffer[0] = 0x6E840B00; 
1008                 break;
1009         default:
1010                 assert(0);
1011                 return;
1012         }
1013
1014         for (i = 0; i < 5; i++)
1015                 bcm43xx_ram_write(bcm, i * 4, buffer[i]);
1016
1017         bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
1018
1019         bcm43xx_write16(bcm, 0x0568, 0x0000);
1020         bcm43xx_write16(bcm, 0x07C0, 0x0000);
1021         bcm43xx_write16(bcm, 0x050C, ((phy->type == BCM43xx_PHYTYPE_A) ? 1 : 0));
1022         bcm43xx_write16(bcm, 0x0508, 0x0000);
1023         bcm43xx_write16(bcm, 0x050A, 0x0000);
1024         bcm43xx_write16(bcm, 0x054C, 0x0000);
1025         bcm43xx_write16(bcm, 0x056A, 0x0014);
1026         bcm43xx_write16(bcm, 0x0568, 0x0826);
1027         bcm43xx_write16(bcm, 0x0500, 0x0000);
1028         bcm43xx_write16(bcm, 0x0502, 0x0030);
1029
1030         if (radio->version == 0x2050 && radio->revision <= 0x5)
1031                 bcm43xx_radio_write16(bcm, 0x0051, 0x0017);
1032         for (i = 0x00; i < max_loop; i++) {
1033                 value = bcm43xx_read16(bcm, 0x050E);
1034                 if (value & 0x0080)
1035                         break;
1036                 udelay(10);
1037         }
1038         for (i = 0x00; i < 0x0A; i++) {
1039                 value = bcm43xx_read16(bcm, 0x050E);
1040                 if (value & 0x0400)
1041                         break;
1042                 udelay(10);
1043         }
1044         for (i = 0x00; i < 0x0A; i++) {
1045                 value = bcm43xx_read16(bcm, 0x0690);
1046                 if (!(value & 0x0100))
1047                         break;
1048                 udelay(10);
1049         }
1050         if (radio->version == 0x2050 && radio->revision <= 0x5)
1051                 bcm43xx_radio_write16(bcm, 0x0051, 0x0037);
1052 }
1053
1054 static void key_write(struct bcm43xx_private *bcm,
1055                       u8 index, u8 algorithm, const u16 *key)
1056 {
1057         unsigned int i, basic_wep = 0;
1058         u32 offset;
1059         u16 value;
1060  
1061         /* Write associated key information */
1062         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x100 + (index * 2),
1063                             ((index << 4) | (algorithm & 0x0F)));
1064  
1065         /* The first 4 WEP keys need extra love */
1066         if (((algorithm == BCM43xx_SEC_ALGO_WEP) ||
1067             (algorithm == BCM43xx_SEC_ALGO_WEP104)) && (index < 4))
1068                 basic_wep = 1;
1069  
1070         /* Write key payload, 8 little endian words */
1071         offset = bcm->security_offset + (index * BCM43xx_SEC_KEYSIZE);
1072         for (i = 0; i < (BCM43xx_SEC_KEYSIZE / sizeof(u16)); i++) {
1073                 value = cpu_to_le16(key[i]);
1074                 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
1075                                     offset + (i * 2), value);
1076  
1077                 if (!basic_wep)
1078                         continue;
1079  
1080                 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
1081                                     offset + (i * 2) + 4 * BCM43xx_SEC_KEYSIZE,
1082                                     value);
1083         }
1084 }
1085
1086 static void keymac_write(struct bcm43xx_private *bcm,
1087                          u8 index, const u32 *addr)
1088 {
1089         /* for keys 0-3 there is no associated mac address */
1090         if (index < 4)
1091                 return;
1092
1093         index -= 4;
1094         if (bcm->current_core->rev >= 5) {
1095                 bcm43xx_shm_write32(bcm,
1096                                     BCM43xx_SHM_HWMAC,
1097                                     index * 2,
1098                                     cpu_to_be32(*addr));
1099                 bcm43xx_shm_write16(bcm,
1100                                     BCM43xx_SHM_HWMAC,
1101                                     (index * 2) + 1,
1102                                     cpu_to_be16(*((u16 *)(addr + 1))));
1103         } else {
1104                 if (index < 8) {
1105                         TODO(); /* Put them in the macaddress filter */
1106                 } else {
1107                         TODO();
1108                         /* Put them BCM43xx_SHM_SHARED, stating index 0x0120.
1109                            Keep in mind to update the count of keymacs in 0x003E as well! */
1110                 }
1111         }
1112 }
1113
1114 static int bcm43xx_key_write(struct bcm43xx_private *bcm,
1115                              u8 index, u8 algorithm,
1116                              const u8 *_key, int key_len,
1117                              const u8 *mac_addr)
1118 {
1119         u8 key[BCM43xx_SEC_KEYSIZE] = { 0 };
1120
1121         if (index >= ARRAY_SIZE(bcm->key))
1122                 return -EINVAL;
1123         if (key_len > ARRAY_SIZE(key))
1124                 return -EINVAL;
1125         if (algorithm < 1 || algorithm > 5)
1126                 return -EINVAL;
1127
1128         memcpy(key, _key, key_len);
1129         key_write(bcm, index, algorithm, (const u16 *)key);
1130         keymac_write(bcm, index, (const u32 *)mac_addr);
1131
1132         bcm->key[index].algorithm = algorithm;
1133
1134         return 0;
1135 }
1136
1137 static void bcm43xx_clear_keys(struct bcm43xx_private *bcm)
1138 {
1139         static const u32 zero_mac[2] = { 0 };
1140         unsigned int i,j, nr_keys = 54;
1141         u16 offset;
1142
1143         if (bcm->current_core->rev < 5)
1144                 nr_keys = 16;
1145         assert(nr_keys <= ARRAY_SIZE(bcm->key));
1146
1147         for (i = 0; i < nr_keys; i++) {
1148                 bcm->key[i].enabled = 0;
1149                 /* returns for i < 4 immediately */
1150                 keymac_write(bcm, i, zero_mac);
1151                 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
1152                                     0x100 + (i * 2), 0x0000);
1153                 for (j = 0; j < 8; j++) {
1154                         offset = bcm->security_offset + (j * 4) + (i * BCM43xx_SEC_KEYSIZE);
1155                         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
1156                                             offset, 0x0000);
1157                 }
1158         }
1159         dprintk(KERN_INFO PFX "Keys cleared\n");
1160 }
1161
1162 /* Lowlevel core-switch function. This is only to be used in
1163  * bcm43xx_switch_core() and bcm43xx_probe_cores()
1164  */
1165 static int _switch_core(struct bcm43xx_private *bcm, int core)
1166 {
1167         int err;
1168         int attempts = 0;
1169         u32 current_core;
1170
1171         assert(core >= 0);
1172         while (1) {
1173                 err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_ACTIVE_CORE,
1174                                                  (core * 0x1000) + 0x18000000);
1175                 if (unlikely(err))
1176                         goto error;
1177                 err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCICFG_ACTIVE_CORE,
1178                                                 &current_core);
1179                 if (unlikely(err))
1180                         goto error;
1181                 current_core = (current_core - 0x18000000) / 0x1000;
1182                 if (current_core == core)
1183                         break;
1184
1185                 if (unlikely(attempts++ > BCM43xx_SWITCH_CORE_MAX_RETRIES))
1186                         goto error;
1187                 udelay(10);
1188         }
1189 #ifdef CONFIG_BCM947XX
1190         if (bcm->pci_dev->bus->number == 0)
1191                 bcm->current_core_offset = 0x1000 * core;
1192         else
1193                 bcm->current_core_offset = 0;
1194 #endif
1195
1196         return 0;
1197 error:
1198         printk(KERN_ERR PFX "Failed to switch to core %d\n", core);
1199         return -ENODEV;
1200 }
1201
1202 int bcm43xx_switch_core(struct bcm43xx_private *bcm, struct bcm43xx_coreinfo *new_core)
1203 {
1204         int err;
1205
1206         if (unlikely(!new_core))
1207                 return 0;
1208         if (!new_core->available)
1209                 return -ENODEV;
1210         if (bcm->current_core == new_core)
1211                 return 0;
1212         err = _switch_core(bcm, new_core->index);
1213         if (unlikely(err))
1214                 goto out;
1215
1216         bcm->current_core = new_core;
1217         bcm->current_80211_core_idx = -1;
1218         if (new_core->id == BCM43xx_COREID_80211)
1219                 bcm->current_80211_core_idx = (int)(new_core - &(bcm->core_80211[0]));
1220
1221 out:
1222         return err;
1223 }
1224
1225 static int bcm43xx_core_enabled(struct bcm43xx_private *bcm)
1226 {
1227         u32 value;
1228
1229         value = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1230         value &= BCM43xx_SBTMSTATELOW_CLOCK | BCM43xx_SBTMSTATELOW_RESET
1231                  | BCM43xx_SBTMSTATELOW_REJECT;
1232
1233         return (value == BCM43xx_SBTMSTATELOW_CLOCK);
1234 }
1235
1236 /* disable current core */
1237 static int bcm43xx_core_disable(struct bcm43xx_private *bcm, u32 core_flags)
1238 {
1239         u32 sbtmstatelow;
1240         u32 sbtmstatehigh;
1241         int i;
1242
1243         /* fetch sbtmstatelow from core information registers */
1244         sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1245
1246         /* core is already in reset */
1247         if (sbtmstatelow & BCM43xx_SBTMSTATELOW_RESET)
1248                 goto out;
1249
1250         if (sbtmstatelow & BCM43xx_SBTMSTATELOW_CLOCK) {
1251                 sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK |
1252                                BCM43xx_SBTMSTATELOW_REJECT;
1253                 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1254
1255                 for (i = 0; i < 1000; i++) {
1256                         sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1257                         if (sbtmstatelow & BCM43xx_SBTMSTATELOW_REJECT) {
1258                                 i = -1;
1259                                 break;
1260                         }
1261                         udelay(10);
1262                 }
1263                 if (i != -1) {
1264                         printk(KERN_ERR PFX "Error: core_disable() REJECT timeout!\n");
1265                         return -EBUSY;
1266                 }
1267
1268                 for (i = 0; i < 1000; i++) {
1269                         sbtmstatehigh = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH);
1270                         if (!(sbtmstatehigh & BCM43xx_SBTMSTATEHIGH_BUSY)) {
1271                                 i = -1;
1272                                 break;
1273                         }
1274                         udelay(10);
1275                 }
1276                 if (i != -1) {
1277                         printk(KERN_ERR PFX "Error: core_disable() BUSY timeout!\n");
1278                         return -EBUSY;
1279                 }
1280
1281                 sbtmstatelow = BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK |
1282                                BCM43xx_SBTMSTATELOW_REJECT |
1283                                BCM43xx_SBTMSTATELOW_RESET |
1284                                BCM43xx_SBTMSTATELOW_CLOCK |
1285                                core_flags;
1286                 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1287                 udelay(10);
1288         }
1289
1290         sbtmstatelow = BCM43xx_SBTMSTATELOW_RESET |
1291                        BCM43xx_SBTMSTATELOW_REJECT |
1292                        core_flags;
1293         bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1294
1295 out:
1296         bcm->current_core->enabled = 0;
1297
1298         return 0;
1299 }
1300
1301 /* enable (reset) current core */
1302 static int bcm43xx_core_enable(struct bcm43xx_private *bcm, u32 core_flags)
1303 {
1304         u32 sbtmstatelow;
1305         u32 sbtmstatehigh;
1306         u32 sbimstate;
1307         int err;
1308
1309         err = bcm43xx_core_disable(bcm, core_flags);
1310         if (err)
1311                 goto out;
1312
1313         sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK |
1314                        BCM43xx_SBTMSTATELOW_RESET |
1315                        BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK |
1316                        core_flags;
1317         bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1318         udelay(1);
1319
1320         sbtmstatehigh = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH);
1321         if (sbtmstatehigh & BCM43xx_SBTMSTATEHIGH_SERROR) {
1322                 sbtmstatehigh = 0x00000000;
1323                 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATEHIGH, sbtmstatehigh);
1324         }
1325
1326         sbimstate = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMSTATE);
1327         if (sbimstate & (BCM43xx_SBIMSTATE_IB_ERROR | BCM43xx_SBIMSTATE_TIMEOUT)) {
1328                 sbimstate &= ~(BCM43xx_SBIMSTATE_IB_ERROR | BCM43xx_SBIMSTATE_TIMEOUT);
1329                 bcm43xx_write32(bcm, BCM43xx_CIR_SBIMSTATE, sbimstate);
1330         }
1331
1332         sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK |
1333                        BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK |
1334                        core_flags;
1335         bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1336         udelay(1);
1337
1338         sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK | core_flags;
1339         bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1340         udelay(1);
1341
1342         bcm->current_core->enabled = 1;
1343         assert(err == 0);
1344 out:
1345         return err;
1346 }
1347
1348 /* http://bcm-specs.sipsolutions.net/80211CoreReset */
1349 void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy)
1350 {
1351         u32 flags = 0x00040000;
1352
1353         if ((bcm43xx_core_enabled(bcm)) &&
1354             !bcm43xx_using_pio(bcm)) {
1355 //FIXME: Do we _really_ want #ifndef CONFIG_BCM947XX here?
1356 #ifndef CONFIG_BCM947XX
1357                 /* reset all used DMA controllers. */
1358                 bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA1_BASE);
1359                 bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA2_BASE);
1360                 bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA3_BASE);
1361                 bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA4_BASE);
1362                 bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA1_BASE);
1363                 if (bcm->current_core->rev < 5)
1364                         bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA4_BASE);
1365 #endif
1366         }
1367         if (bcm->shutting_down) {
1368                 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
1369                                 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
1370                                 & ~(BCM43xx_SBF_MAC_ENABLED | 0x00000002));
1371         } else {
1372                 if (connect_phy)
1373                         flags |= 0x20000000;
1374                 bcm43xx_phy_connect(bcm, connect_phy);
1375                 bcm43xx_core_enable(bcm, flags);
1376                 bcm43xx_write16(bcm, 0x03E6, 0x0000);
1377                 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
1378                                 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
1379                                 | BCM43xx_SBF_400);
1380         }
1381 }
1382
1383 static void bcm43xx_wireless_core_disable(struct bcm43xx_private *bcm)
1384 {
1385         bcm43xx_radio_turn_off(bcm);
1386         bcm43xx_write16(bcm, 0x03E6, 0x00F4);
1387         bcm43xx_core_disable(bcm, 0);
1388 }
1389
1390 /* Mark the current 80211 core inactive.
1391  * "active_80211_core" is the other 80211 core, which is used.
1392  */
1393 static int bcm43xx_wireless_core_mark_inactive(struct bcm43xx_private *bcm,
1394                                                struct bcm43xx_coreinfo *active_80211_core)
1395 {
1396         u32 sbtmstatelow;
1397         struct bcm43xx_coreinfo *old_core;
1398         int err = 0;
1399
1400         bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
1401         bcm43xx_radio_turn_off(bcm);
1402         sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1403         sbtmstatelow &= ~0x200a0000;
1404         sbtmstatelow |= 0xa0000;
1405         bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1406         udelay(1);
1407         sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1408         sbtmstatelow &= ~0xa0000;
1409         sbtmstatelow |= 0x80000;
1410         bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1411         udelay(1);
1412
1413         if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_G) {
1414                 old_core = bcm->current_core;
1415                 err = bcm43xx_switch_core(bcm, active_80211_core);
1416                 if (err)
1417                         goto out;
1418                 sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1419                 sbtmstatelow &= ~0x20000000;
1420                 sbtmstatelow |= 0x20000000;
1421                 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1422                 err = bcm43xx_switch_core(bcm, old_core);
1423         }
1424
1425 out:
1426         return err;
1427 }
1428
1429 static void handle_irq_transmit_status(struct bcm43xx_private *bcm)
1430 {
1431         u32 v0, v1;
1432         u16 tmp;
1433         struct bcm43xx_xmitstatus stat;
1434
1435         while (1) {
1436                 v0 = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_0);
1437                 if (!v0)
1438                         break;
1439                 v1 = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_1);
1440
1441                 stat.cookie = (v0 >> 16) & 0x0000FFFF;
1442                 tmp = (u16)((v0 & 0xFFF0) | ((v0 & 0xF) >> 1));
1443                 stat.flags = tmp & 0xFF;
1444                 stat.cnt1 = (tmp & 0x0F00) >> 8;
1445                 stat.cnt2 = (tmp & 0xF000) >> 12;
1446                 stat.seq = (u16)(v1 & 0xFFFF);
1447                 stat.unknown = (u16)((v1 >> 16) & 0xFF);
1448
1449                 bcm43xx_debugfs_log_txstat(bcm, &stat);
1450
1451                 if (stat.flags & BCM43xx_TXSTAT_FLAG_IGNORE)
1452                         continue;
1453                 if (!(stat.flags & BCM43xx_TXSTAT_FLAG_ACK)) {
1454                         //TODO: packet was not acked (was lost)
1455                 }
1456                 //TODO: There are more (unknown) flags to test. see bcm43xx_main.h
1457
1458                 if (bcm43xx_using_pio(bcm))
1459                         bcm43xx_pio_handle_xmitstatus(bcm, &stat);
1460                 else
1461                         bcm43xx_dma_handle_xmitstatus(bcm, &stat);
1462         }
1463 }
1464
1465 static void bcm43xx_generate_noise_sample(struct bcm43xx_private *bcm)
1466 {
1467         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x408, 0x7F7F);
1468         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x40A, 0x7F7F);
1469         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD,
1470                         bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD) | (1 << 4));
1471         assert(bcm->noisecalc.core_at_start == bcm->current_core);
1472         assert(bcm->noisecalc.channel_at_start == bcm43xx_current_radio(bcm)->channel);
1473 }
1474
1475 static void bcm43xx_calculate_link_quality(struct bcm43xx_private *bcm)
1476 {
1477         /* Top half of Link Quality calculation. */
1478
1479         if (bcm->noisecalc.calculation_running)
1480                 return;
1481         bcm->noisecalc.core_at_start = bcm->current_core;
1482         bcm->noisecalc.channel_at_start = bcm43xx_current_radio(bcm)->channel;
1483         bcm->noisecalc.calculation_running = 1;
1484         bcm->noisecalc.nr_samples = 0;
1485
1486         bcm43xx_generate_noise_sample(bcm);
1487 }
1488
1489 static void handle_irq_noise(struct bcm43xx_private *bcm)
1490 {
1491         struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
1492         u16 tmp;
1493         u8 noise[4];
1494         u8 i, j;
1495         s32 average;
1496
1497         /* Bottom half of Link Quality calculation. */
1498
1499         assert(bcm->noisecalc.calculation_running);
1500         if (bcm->noisecalc.core_at_start != bcm->current_core ||
1501             bcm->noisecalc.channel_at_start != radio->channel)
1502                 goto drop_calculation;
1503         tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x408);
1504         noise[0] = (tmp & 0x00FF);
1505         noise[1] = (tmp & 0xFF00) >> 8;
1506         tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x40A);
1507         noise[2] = (tmp & 0x00FF);
1508         noise[3] = (tmp & 0xFF00) >> 8;
1509         if (noise[0] == 0x7F || noise[1] == 0x7F ||
1510             noise[2] == 0x7F || noise[3] == 0x7F)
1511                 goto generate_new;
1512
1513         /* Get the noise samples. */
1514         assert(bcm->noisecalc.nr_samples <= 8);
1515         i = bcm->noisecalc.nr_samples;
1516         noise[0] = limit_value(noise[0], 0, ARRAY_SIZE(radio->nrssi_lt) - 1);
1517         noise[1] = limit_value(noise[1], 0, ARRAY_SIZE(radio->nrssi_lt) - 1);
1518         noise[2] = limit_value(noise[2], 0, ARRAY_SIZE(radio->nrssi_lt) - 1);
1519         noise[3] = limit_value(noise[3], 0, ARRAY_SIZE(radio->nrssi_lt) - 1);
1520         bcm->noisecalc.samples[i][0] = radio->nrssi_lt[noise[0]];
1521         bcm->noisecalc.samples[i][1] = radio->nrssi_lt[noise[1]];
1522         bcm->noisecalc.samples[i][2] = radio->nrssi_lt[noise[2]];
1523         bcm->noisecalc.samples[i][3] = radio->nrssi_lt[noise[3]];
1524         bcm->noisecalc.nr_samples++;
1525         if (bcm->noisecalc.nr_samples == 8) {
1526                 /* Calculate the Link Quality by the noise samples. */
1527                 average = 0;
1528                 for (i = 0; i < 8; i++) {
1529                         for (j = 0; j < 4; j++)
1530                                 average += bcm->noisecalc.samples[i][j];
1531                 }
1532                 average /= (8 * 4);
1533                 average *= 125;
1534                 average += 64;
1535                 average /= 128;
1536                 tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x40C);
1537                 tmp = (tmp / 128) & 0x1F;
1538                 if (tmp >= 8)
1539                         average += 2;
1540                 else
1541                         average -= 25;
1542                 if (tmp == 8)
1543                         average -= 72;
1544                 else
1545                         average -= 48;
1546
1547                 if (average > -65)
1548                         bcm->stats.link_quality = 0;
1549                 else if (average > -75)
1550                         bcm->stats.link_quality = 1;
1551                 else if (average > -85)
1552                         bcm->stats.link_quality = 2;
1553                 else
1554                         bcm->stats.link_quality = 3;
1555 //              dprintk(KERN_INFO PFX "Link Quality: %u (avg was %d)\n", bcm->stats.link_quality, average);
1556 drop_calculation:
1557                 bcm->noisecalc.calculation_running = 0;
1558                 return;
1559         }
1560 generate_new:
1561         bcm43xx_generate_noise_sample(bcm);
1562 }
1563
1564 static void handle_irq_ps(struct bcm43xx_private *bcm)
1565 {
1566         if (bcm->ieee->iw_mode == IW_MODE_MASTER) {
1567                 ///TODO: PS TBTT
1568         } else {
1569                 if (1/*FIXME: the last PSpoll frame was sent successfully */)
1570                         bcm43xx_power_saving_ctl_bits(bcm, -1, -1);
1571         }
1572         if (bcm->ieee->iw_mode == IW_MODE_ADHOC)
1573                 bcm->reg124_set_0x4 = 1;
1574         //FIXME else set to false?
1575 }
1576
1577 static void handle_irq_reg124(struct bcm43xx_private *bcm)
1578 {
1579         if (!bcm->reg124_set_0x4)
1580                 return;
1581         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD,
1582                         bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD)
1583                         | 0x4);
1584         //FIXME: reset reg124_set_0x4 to false?
1585 }
1586
1587 static void handle_irq_pmq(struct bcm43xx_private *bcm)
1588 {
1589         u32 tmp;
1590
1591         //TODO: AP mode.
1592
1593         while (1) {
1594                 tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_PS_STATUS);
1595                 if (!(tmp & 0x00000008))
1596                         break;
1597         }
1598         /* 16bit write is odd, but correct. */
1599         bcm43xx_write16(bcm, BCM43xx_MMIO_PS_STATUS, 0x0002);
1600 }
1601
1602 static void bcm43xx_generate_beacon_template(struct bcm43xx_private *bcm,
1603                                              u16 ram_offset, u16 shm_size_offset)
1604 {
1605         u32 value;
1606         u16 size = 0;
1607
1608         /* Timestamp. */
1609         //FIXME: assumption: The chip sets the timestamp
1610         value = 0;
1611         bcm43xx_ram_write(bcm, ram_offset++, value);
1612         bcm43xx_ram_write(bcm, ram_offset++, value);
1613         size += 8;
1614
1615         /* Beacon Interval / Capability Information */
1616         value = 0x0000;//FIXME: Which interval?
1617         value |= (1 << 0) << 16; /* ESS */
1618         value |= (1 << 2) << 16; /* CF Pollable */      //FIXME?
1619         value |= (1 << 3) << 16; /* CF Poll Request */  //FIXME?
1620         if (!bcm->ieee->open_wep)
1621                 value |= (1 << 4) << 16; /* Privacy */
1622         bcm43xx_ram_write(bcm, ram_offset++, value);
1623         size += 4;
1624
1625         /* SSID */
1626         //TODO
1627
1628         /* FH Parameter Set */
1629         //TODO
1630
1631         /* DS Parameter Set */
1632         //TODO
1633
1634         /* CF Parameter Set */
1635         //TODO
1636
1637         /* TIM */
1638         //TODO
1639
1640         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, shm_size_offset, size);
1641 }
1642
1643 static void handle_irq_beacon(struct bcm43xx_private *bcm)
1644 {
1645         u32 status;
1646
1647         bcm->irq_savedstate &= ~BCM43xx_IRQ_BEACON;
1648         status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD);
1649
1650         if ((status & 0x1) && (status & 0x2)) {
1651                 /* ACK beacon IRQ. */
1652                 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON,
1653                                 BCM43xx_IRQ_BEACON);
1654                 bcm->irq_savedstate |= BCM43xx_IRQ_BEACON;
1655                 return;
1656         }
1657         if (!(status & 0x1)) {
1658                 bcm43xx_generate_beacon_template(bcm, 0x68, 0x18);
1659                 status |= 0x1;
1660                 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, status);
1661         }
1662         if (!(status & 0x2)) {
1663                 bcm43xx_generate_beacon_template(bcm, 0x468, 0x1A);
1664                 status |= 0x2;
1665                 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, status);
1666         }
1667 }
1668
1669 /* Interrupt handler bottom-half */
1670 static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1671 {
1672         u32 reason;
1673         u32 dma_reason[4];
1674         int activity = 0;
1675         unsigned long flags;
1676
1677 #ifdef CONFIG_BCM43XX_DEBUG
1678         u32 _handled = 0x00000000;
1679 # define bcmirq_handled(irq)    do { _handled |= (irq); } while (0)
1680 #else
1681 # define bcmirq_handled(irq)    do { /* nothing */ } while (0)
1682 #endif /* CONFIG_BCM43XX_DEBUG*/
1683
1684         bcm43xx_lock_mmio(bcm, flags);
1685         reason = bcm->irq_reason;
1686         dma_reason[0] = bcm->dma_reason[0];
1687         dma_reason[1] = bcm->dma_reason[1];
1688         dma_reason[2] = bcm->dma_reason[2];
1689         dma_reason[3] = bcm->dma_reason[3];
1690
1691         if (unlikely(reason & BCM43xx_IRQ_XMIT_ERROR)) {
1692                 /* TX error. We get this when Template Ram is written in wrong endianess
1693                  * in dummy_tx(). We also get this if something is wrong with the TX header
1694                  * on DMA or PIO queues.
1695                  * Maybe we get this in other error conditions, too.
1696                  */
1697                 printkl(KERN_ERR PFX "FATAL ERROR: BCM43xx_IRQ_XMIT_ERROR\n");
1698                 bcmirq_handled(BCM43xx_IRQ_XMIT_ERROR);
1699         }
1700         if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_FATALMASK) |
1701                      (dma_reason[1] & BCM43xx_DMAIRQ_FATALMASK) |
1702                      (dma_reason[2] & BCM43xx_DMAIRQ_FATALMASK) |
1703                      (dma_reason[3] & BCM43xx_DMAIRQ_FATALMASK))) {
1704                 printkl(KERN_ERR PFX "FATAL ERROR: Fatal DMA error: "
1705                                      "0x%08X, 0x%08X, 0x%08X, 0x%08X\n",
1706                         dma_reason[0], dma_reason[1],
1707                         dma_reason[2], dma_reason[3]);
1708                 bcm43xx_controller_restart(bcm, "DMA error");
1709                 bcm43xx_unlock_mmio(bcm, flags);
1710                 return;
1711         }
1712         if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_NONFATALMASK) |
1713                      (dma_reason[1] & BCM43xx_DMAIRQ_NONFATALMASK) |
1714                      (dma_reason[2] & BCM43xx_DMAIRQ_NONFATALMASK) |
1715                      (dma_reason[3] & BCM43xx_DMAIRQ_NONFATALMASK))) {
1716                 printkl(KERN_ERR PFX "DMA error: "
1717                                      "0x%08X, 0x%08X, 0x%08X, 0x%08X\n",
1718                         dma_reason[0], dma_reason[1],
1719                         dma_reason[2], dma_reason[3]);
1720         }
1721
1722         if (reason & BCM43xx_IRQ_PS) {
1723                 handle_irq_ps(bcm);
1724                 bcmirq_handled(BCM43xx_IRQ_PS);
1725         }
1726
1727         if (reason & BCM43xx_IRQ_REG124) {
1728                 handle_irq_reg124(bcm);
1729                 bcmirq_handled(BCM43xx_IRQ_REG124);
1730         }
1731
1732         if (reason & BCM43xx_IRQ_BEACON) {
1733                 if (bcm->ieee->iw_mode == IW_MODE_MASTER)
1734                         handle_irq_beacon(bcm);
1735                 bcmirq_handled(BCM43xx_IRQ_BEACON);
1736         }
1737
1738         if (reason & BCM43xx_IRQ_PMQ) {
1739                 handle_irq_pmq(bcm);
1740                 bcmirq_handled(BCM43xx_IRQ_PMQ);
1741         }
1742
1743         if (reason & BCM43xx_IRQ_SCAN) {
1744                 /*TODO*/
1745                 //bcmirq_handled(BCM43xx_IRQ_SCAN);
1746         }
1747
1748         if (reason & BCM43xx_IRQ_NOISE) {
1749                 handle_irq_noise(bcm);
1750                 bcmirq_handled(BCM43xx_IRQ_NOISE);
1751         }
1752
1753         /* Check the DMA reason registers for received data. */
1754         assert(!(dma_reason[1] & BCM43xx_DMAIRQ_RX_DONE));
1755         assert(!(dma_reason[2] & BCM43xx_DMAIRQ_RX_DONE));
1756         if (dma_reason[0] & BCM43xx_DMAIRQ_RX_DONE) {
1757                 if (bcm43xx_using_pio(bcm))
1758                         bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue0);
1759                 else
1760                         bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring0);
1761                 /* We intentionally don't set "activity" to 1, here. */
1762         }
1763         if (dma_reason[3] & BCM43xx_DMAIRQ_RX_DONE) {
1764                 if (bcm43xx_using_pio(bcm))
1765                         bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue3);
1766                 else
1767                         bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring1);
1768                 activity = 1;
1769         }
1770         bcmirq_handled(BCM43xx_IRQ_RX);
1771
1772         if (reason & BCM43xx_IRQ_XMIT_STATUS) {
1773                 handle_irq_transmit_status(bcm);
1774                 activity = 1;
1775                 //TODO: In AP mode, this also causes sending of powersave responses.
1776                 bcmirq_handled(BCM43xx_IRQ_XMIT_STATUS);
1777         }
1778
1779         /* We get spurious IRQs, althought they are masked.
1780          * Assume they are void and ignore them.
1781          */
1782         bcmirq_handled(~(bcm->irq_savedstate));
1783         /* IRQ_PIO_WORKAROUND is handled in the top-half. */
1784         bcmirq_handled(BCM43xx_IRQ_PIO_WORKAROUND);
1785 #ifdef CONFIG_BCM43XX_DEBUG
1786         if (unlikely(reason & ~_handled)) {
1787                 printkl(KERN_WARNING PFX
1788                         "Unhandled IRQ! Reason: 0x%08x,  Unhandled: 0x%08x,  "
1789                         "DMA: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
1790                         reason, (reason & ~_handled),
1791                         dma_reason[0], dma_reason[1],
1792                         dma_reason[2], dma_reason[3]);
1793         }
1794 #endif
1795 #undef bcmirq_handled
1796
1797         if (!modparam_noleds)
1798                 bcm43xx_leds_update(bcm, activity);
1799         bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
1800         bcm43xx_unlock_mmio(bcm, flags);
1801 }
1802
1803 static void bcm43xx_interrupt_ack(struct bcm43xx_private *bcm,
1804                                   u32 reason, u32 mask)
1805 {
1806         bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON)
1807                              & 0x0001dc00;
1808         bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA2_REASON)
1809                              & 0x0000dc00;
1810         bcm->dma_reason[2] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA3_REASON)
1811                              & 0x0000dc00;
1812         bcm->dma_reason[3] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_REASON)
1813                              & 0x0001dc00;
1814
1815         if (bcm43xx_using_pio(bcm) &&
1816             (bcm->current_core->rev < 3) &&
1817             (!(reason & BCM43xx_IRQ_PIO_WORKAROUND))) {
1818                 /* Apply a PIO specific workaround to the dma_reasons */
1819
1820 #define apply_pio_workaround(BASE, QNUM) \
1821         do {                                                                                    \
1822         if (bcm43xx_read16(bcm, BASE + BCM43xx_PIO_RXCTL) & BCM43xx_PIO_RXCTL_DATAAVAILABLE)    \
1823                 bcm->dma_reason[QNUM] |= 0x00010000;                                            \
1824         else                                                                                    \
1825                 bcm->dma_reason[QNUM] &= ~0x00010000;                                           \
1826         } while (0)
1827
1828                 apply_pio_workaround(BCM43xx_MMIO_PIO1_BASE, 0);
1829                 apply_pio_workaround(BCM43xx_MMIO_PIO2_BASE, 1);
1830                 apply_pio_workaround(BCM43xx_MMIO_PIO3_BASE, 2);
1831                 apply_pio_workaround(BCM43xx_MMIO_PIO4_BASE, 3);
1832
1833 #undef apply_pio_workaround
1834         }
1835
1836         bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON,
1837                         reason & mask);
1838
1839         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_REASON,
1840                         bcm->dma_reason[0]);
1841         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_REASON,
1842                         bcm->dma_reason[1]);
1843         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_REASON,
1844                         bcm->dma_reason[2]);
1845         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_REASON,
1846                         bcm->dma_reason[3]);
1847 }
1848
1849 /* Interrupt handler top-half */
1850 static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_regs *regs)
1851 {
1852         irqreturn_t ret = IRQ_HANDLED;
1853         struct bcm43xx_private *bcm = dev_id;
1854         u32 reason, mask;
1855
1856         if (!bcm)
1857                 return IRQ_NONE;
1858
1859         spin_lock(&bcm->_lock);
1860
1861         reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
1862         if (reason == 0xffffffff) {
1863                 /* irq not for us (shared irq) */
1864                 ret = IRQ_NONE;
1865                 goto out;
1866         }
1867         mask = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK);
1868         if (!(reason & mask))
1869                 goto out;
1870
1871         bcm43xx_interrupt_ack(bcm, reason, mask);
1872
1873         /* Only accept IRQs, if we are initialized properly.
1874          * This avoids an RX race while initializing.
1875          * We should probably not enable IRQs before we are initialized
1876          * completely, but some careful work is needed to fix this. I think it
1877          * is best to stay with this cheap workaround for now... .
1878          */
1879         if (likely(bcm->initialized)) {
1880                 /* disable all IRQs. They are enabled again in the bottom half. */
1881                 bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
1882                 /* save the reason code and call our bottom half. */
1883                 bcm->irq_reason = reason;
1884                 tasklet_schedule(&bcm->isr_tasklet);
1885         }
1886
1887 out:
1888         mmiowb();
1889         spin_unlock(&bcm->_lock);
1890
1891         return ret;
1892 }
1893
1894 static void bcm43xx_release_firmware(struct bcm43xx_private *bcm, int force)
1895 {
1896         if (bcm->firmware_norelease && !force)
1897                 return; /* Suspending or controller reset. */
1898         release_firmware(bcm->ucode);
1899         bcm->ucode = NULL;
1900         release_firmware(bcm->pcm);
1901         bcm->pcm = NULL;
1902         release_firmware(bcm->initvals0);
1903         bcm->initvals0 = NULL;
1904         release_firmware(bcm->initvals1);
1905         bcm->initvals1 = NULL;
1906 }
1907
1908 static int bcm43xx_request_firmware(struct bcm43xx_private *bcm)
1909 {
1910         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1911         u8 rev = bcm->current_core->rev;
1912         int err = 0;
1913         int nr;
1914         char buf[22 + sizeof(modparam_fwpostfix) - 1] = { 0 };
1915
1916         if (!bcm->ucode) {
1917                 snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_microcode%d%s.fw",
1918                          (rev >= 5 ? 5 : rev),
1919                          modparam_fwpostfix);
1920                 err = request_firmware(&bcm->ucode, buf, &bcm->pci_dev->dev);
1921                 if (err) {
1922                         printk(KERN_ERR PFX 
1923                                "Error: Microcode \"%s\" not available or load failed.\n",
1924                                 buf);
1925                         goto error;
1926                 }
1927         }
1928
1929         if (!bcm->pcm) {
1930                 snprintf(buf, ARRAY_SIZE(buf),
1931                          "bcm43xx_pcm%d%s.fw",
1932                          (rev < 5 ? 4 : 5),
1933                          modparam_fwpostfix);
1934                 err = request_firmware(&bcm->pcm, buf, &bcm->pci_dev->dev);
1935                 if (err) {
1936                         printk(KERN_ERR PFX
1937                                "Error: PCM \"%s\" not available or load failed.\n",
1938                                buf);
1939                         goto error;
1940                 }
1941         }
1942
1943         if (!bcm->initvals0) {
1944                 if (rev == 2 || rev == 4) {
1945                         switch (phy->type) {
1946                         case BCM43xx_PHYTYPE_A:
1947                                 nr = 3;
1948                                 break;
1949                         case BCM43xx_PHYTYPE_B:
1950                         case BCM43xx_PHYTYPE_G:
1951                                 nr = 1;
1952                                 break;
1953                         default:
1954                                 goto err_noinitval;
1955                         }
1956                 
1957                 } else if (rev >= 5) {
1958                         switch (phy->type) {
1959                         case BCM43xx_PHYTYPE_A:
1960                                 nr = 7;
1961                                 break;
1962                         case BCM43xx_PHYTYPE_B:
1963                         case BCM43xx_PHYTYPE_G:
1964                                 nr = 5;
1965                                 break;
1966                         default:
1967                                 goto err_noinitval;
1968                         }
1969                 } else
1970                         goto err_noinitval;
1971                 snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_initval%02d%s.fw",
1972                          nr, modparam_fwpostfix);
1973
1974                 err = request_firmware(&bcm->initvals0, buf, &bcm->pci_dev->dev);
1975                 if (err) {
1976                         printk(KERN_ERR PFX 
1977                                "Error: InitVals \"%s\" not available or load failed.\n",
1978                                 buf);
1979                         goto error;
1980                 }
1981                 if (bcm->initvals0->size % sizeof(struct bcm43xx_initval)) {
1982                         printk(KERN_ERR PFX "InitVals fileformat error.\n");
1983                         goto error;
1984                 }
1985         }
1986
1987         if (!bcm->initvals1) {
1988                 if (rev >= 5) {
1989                         u32 sbtmstatehigh;
1990
1991                         switch (phy->type) {
1992                         case BCM43xx_PHYTYPE_A:
1993                                 sbtmstatehigh = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH);
1994                                 if (sbtmstatehigh & 0x00010000)
1995                                         nr = 9;
1996                                 else
1997                                         nr = 10;
1998                                 break;
1999                         case BCM43xx_PHYTYPE_B:
2000                         case BCM43xx_PHYTYPE_G:
2001                                         nr = 6;
2002                                 break;
2003                         default:
2004                                 goto err_noinitval;
2005                         }
2006                         snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_initval%02d%s.fw",
2007                                  nr, modparam_fwpostfix);
2008
2009                         err = request_firmware(&bcm->initvals1, buf, &bcm->pci_dev->dev);
2010                         if (err) {
2011                                 printk(KERN_ERR PFX 
2012                                        "Error: InitVals \"%s\" not available or load failed.\n",
2013                                         buf);
2014                                 goto error;
2015                         }
2016                         if (bcm->initvals1->size % sizeof(struct bcm43xx_initval)) {
2017                                 printk(KERN_ERR PFX "InitVals fileformat error.\n");
2018                                 goto error;
2019                         }
2020                 }
2021         }
2022
2023 out:
2024         return err;
2025 error:
2026         bcm43xx_release_firmware(bcm, 1);
2027         goto out;
2028 err_noinitval:
2029         printk(KERN_ERR PFX "Error: No InitVals available!\n");
2030         err = -ENOENT;
2031         goto error;
2032 }
2033
2034 static void bcm43xx_upload_microcode(struct bcm43xx_private *bcm)
2035 {
2036         const u32 *data;
2037         unsigned int i, len;
2038
2039         /* Upload Microcode. */
2040         data = (u32 *)(bcm->ucode->data);
2041         len = bcm->ucode->size / sizeof(u32);
2042         bcm43xx_shm_control_word(bcm, BCM43xx_SHM_UCODE, 0x0000);
2043         for (i = 0; i < len; i++) {
2044                 bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA,
2045                                 be32_to_cpu(data[i]));
2046                 udelay(10);
2047         }
2048
2049         /* Upload PCM data. */
2050         data = (u32 *)(bcm->pcm->data);
2051         len = bcm->pcm->size / sizeof(u32);
2052         bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01ea);
2053         bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, 0x00004000);
2054         bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01eb);
2055         for (i = 0; i < len; i++) {
2056                 bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA,
2057                                 be32_to_cpu(data[i]));
2058                 udelay(10);
2059         }
2060 }
2061
2062 static int bcm43xx_write_initvals(struct bcm43xx_private *bcm,
2063                                   const struct bcm43xx_initval *data,
2064                                   const unsigned int len)
2065 {
2066         u16 offset, size;
2067         u32 value;
2068         unsigned int i;
2069
2070         for (i = 0; i < len; i++) {
2071                 offset = be16_to_cpu(data[i].offset);
2072                 size = be16_to_cpu(data[i].size);
2073                 value = be32_to_cpu(data[i].value);
2074
2075                 if (unlikely(offset >= 0x1000))
2076                         goto err_format;
2077                 if (size == 2) {
2078                         if (unlikely(value & 0xFFFF0000))
2079                                 goto err_format;
2080                         bcm43xx_write16(bcm, offset, (u16)value);
2081                 } else if (size == 4) {
2082                         bcm43xx_write32(bcm, offset, value);
2083                 } else
2084                         goto err_format;
2085         }
2086
2087         return 0;
2088
2089 err_format:
2090         printk(KERN_ERR PFX "InitVals (bcm43xx_initvalXX.fw) file-format error. "
2091                             "Please fix your bcm43xx firmware files.\n");
2092         return -EPROTO;
2093 }
2094
2095 static int bcm43xx_upload_initvals(struct bcm43xx_private *bcm)
2096 {
2097         int err;
2098
2099         err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)bcm->initvals0->data,
2100                                      bcm->initvals0->size / sizeof(struct bcm43xx_initval));
2101         if (err)
2102                 goto out;
2103         if (bcm->initvals1) {
2104                 err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)bcm->initvals1->data,
2105                                              bcm->initvals1->size / sizeof(struct bcm43xx_initval));
2106                 if (err)
2107                         goto out;
2108         }
2109 out:
2110         return err;
2111 }
2112
2113 static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm)
2114 {
2115         int res;
2116         unsigned int i;
2117         u32 data;
2118
2119         bcm->irq = bcm->pci_dev->irq;
2120 #ifdef CONFIG_BCM947XX
2121         if (bcm->pci_dev->bus->number == 0) {
2122                 struct pci_dev *d = NULL;
2123                 /* FIXME: we will probably need more device IDs here... */
2124                 d = pci_find_device(PCI_VENDOR_ID_BROADCOM, 0x4324, NULL);
2125                 if (d != NULL) {
2126                         bcm->irq = d->irq;
2127                 }
2128         }
2129 #endif
2130         res = request_irq(bcm->irq, bcm43xx_interrupt_handler,
2131                           SA_SHIRQ, KBUILD_MODNAME, bcm);
2132         if (res) {
2133                 printk(KERN_ERR PFX "Cannot register IRQ%d\n", bcm->irq);
2134                 return -ENODEV;
2135         }
2136         bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0xffffffff);
2137         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, 0x00020402);
2138         i = 0;
2139         while (1) {
2140                 data = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
2141                 if (data == BCM43xx_IRQ_READY)
2142                         break;
2143                 i++;
2144                 if (i >= BCM43xx_IRQWAIT_MAX_RETRIES) {
2145                         printk(KERN_ERR PFX "Card IRQ register not responding. "
2146                                             "Giving up.\n");
2147                         free_irq(bcm->irq, bcm);
2148                         return -ENODEV;
2149                 }
2150                 udelay(10);
2151         }
2152         // dummy read
2153         bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
2154
2155         return 0;
2156 }
2157
2158 /* Switch to the core used to write the GPIO register.
2159  * This is either the ChipCommon, or the PCI core.
2160  */
2161 static int switch_to_gpio_core(struct bcm43xx_private *bcm)
2162 {
2163         int err;
2164
2165         /* Where to find the GPIO register depends on the chipset.
2166          * If it has a ChipCommon, its register at offset 0x6c is the GPIO
2167          * control register. Otherwise the register at offset 0x6c in the
2168          * PCI core is the GPIO control register.
2169          */
2170         err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
2171         if (err == -ENODEV) {
2172                 err = bcm43xx_switch_core(bcm, &bcm->core_pci);
2173                 if (unlikely(err == -ENODEV)) {
2174                         printk(KERN_ERR PFX "gpio error: "
2175                                "Neither ChipCommon nor PCI core available!\n");
2176                         return -ENODEV;
2177                 } else if (unlikely(err != 0))
2178                         return -ENODEV;
2179         } else if (unlikely(err != 0))
2180                 return -ENODEV;
2181
2182         return 0;
2183 }
2184
2185 /* Initialize the GPIOs
2186  * http://bcm-specs.sipsolutions.net/GPIO
2187  */
2188 static int bcm43xx_gpio_init(struct bcm43xx_private *bcm)
2189 {
2190         struct bcm43xx_coreinfo *old_core;
2191         int err;
2192         u32 mask, value;
2193
2194         value = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2195         value &= ~0xc000;
2196         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value);
2197
2198         mask = 0x0000001F;
2199         value = 0x0000000F;
2200         bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL,
2201                         bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL) & 0xFFF0);
2202         bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_MASK,
2203                         bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_MASK) | 0x000F);
2204
2205         old_core = bcm->current_core;
2206         
2207         err = switch_to_gpio_core(bcm);
2208         if (err)
2209                 return err;
2210
2211         if (bcm->current_core->rev >= 2){
2212                 mask  |= 0x10;
2213                 value |= 0x10;
2214         }
2215         if (bcm->chip_id == 0x4301) {
2216                 mask  |= 0x60;
2217                 value |= 0x60;
2218         }
2219         if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) {
2220                 mask  |= 0x200;
2221                 value |= 0x200;
2222         }
2223
2224         bcm43xx_write32(bcm, BCM43xx_GPIO_CONTROL,
2225                         (bcm43xx_read32(bcm, BCM43xx_GPIO_CONTROL) & mask) | value);
2226
2227         err = bcm43xx_switch_core(bcm, old_core);
2228         assert(err == 0);
2229
2230         return 0;
2231 }
2232
2233 /* Turn off all GPIO stuff. Call this on module unload, for example. */
2234 static int bcm43xx_gpio_cleanup(struct bcm43xx_private *bcm)
2235 {
2236         struct bcm43xx_coreinfo *old_core;
2237         int err;
2238
2239         old_core = bcm->current_core;
2240         err = switch_to_gpio_core(bcm);
2241         if (err)
2242                 return err;
2243         bcm43xx_write32(bcm, BCM43xx_GPIO_CONTROL, 0x00000000);
2244         err = bcm43xx_switch_core(bcm, old_core);
2245         assert(err == 0);
2246
2247         return 0;
2248 }
2249
2250 /* http://bcm-specs.sipsolutions.net/EnableMac */
2251 void bcm43xx_mac_enable(struct bcm43xx_private *bcm)
2252 {
2253         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
2254                         bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
2255                         | BCM43xx_SBF_MAC_ENABLED);
2256         bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, BCM43xx_IRQ_READY);
2257         bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
2258         bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
2259         bcm43xx_power_saving_ctl_bits(bcm, -1, -1);
2260 }
2261
2262 /* http://bcm-specs.sipsolutions.net/SuspendMAC */
2263 void bcm43xx_mac_suspend(struct bcm43xx_private *bcm)
2264 {
2265         int i;
2266         u32 tmp;
2267
2268         bcm43xx_power_saving_ctl_bits(bcm, -1, 1);
2269         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
2270                         bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
2271                         & ~BCM43xx_SBF_MAC_ENABLED);
2272         bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
2273         for (i = 100000; i; i--) {
2274                 tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
2275                 if (tmp & BCM43xx_IRQ_READY)
2276                         return;
2277                 udelay(10);
2278         }
2279         printkl(KERN_ERR PFX "MAC suspend failed\n");
2280 }
2281
2282 void bcm43xx_set_iwmode(struct bcm43xx_private *bcm,
2283                         int iw_mode)
2284 {
2285         unsigned long flags;
2286         u32 status;
2287
2288         spin_lock_irqsave(&bcm->ieee->lock, flags);
2289         bcm->ieee->iw_mode = iw_mode;
2290         spin_unlock_irqrestore(&bcm->ieee->lock, flags);
2291         if (iw_mode == IW_MODE_MONITOR)
2292                 bcm->net_dev->type = ARPHRD_IEEE80211;
2293         else
2294                 bcm->net_dev->type = ARPHRD_ETHER;
2295
2296         if (!bcm->initialized)
2297                 return;
2298
2299         bcm43xx_mac_suspend(bcm);
2300         status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2301         /* Reset status to infrastructured mode */
2302         status &= ~(BCM43xx_SBF_MODE_AP | BCM43xx_SBF_MODE_MONITOR);
2303         /*FIXME: We actually set promiscuous mode as well, until we don't
2304          * get the HW mac filter working */
2305         status |= BCM43xx_SBF_MODE_NOTADHOC | BCM43xx_SBF_MODE_PROMISC;
2306
2307         switch (iw_mode) {
2308         case IW_MODE_MONITOR:
2309                 status |= (BCM43xx_SBF_MODE_PROMISC |
2310                            BCM43xx_SBF_MODE_MONITOR);
2311                 break;
2312         case IW_MODE_ADHOC:
2313                 status &= ~BCM43xx_SBF_MODE_NOTADHOC;
2314                 break;
2315         case IW_MODE_MASTER:
2316         case IW_MODE_SECOND:
2317         case IW_MODE_REPEAT:
2318                 /* TODO: No AP/Repeater mode for now :-/ */
2319                 TODO();
2320                 break;
2321         case IW_MODE_INFRA:
2322                 /* nothing to be done here... */
2323                 break;
2324         default:
2325                 printk(KERN_ERR PFX "Unknown iwmode %d\n", iw_mode);
2326         }
2327
2328         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
2329         bcm43xx_mac_enable(bcm);
2330 }
2331
2332 /* This is the opposite of bcm43xx_chip_init() */
2333 static void bcm43xx_chip_cleanup(struct bcm43xx_private *bcm)
2334 {
2335         bcm43xx_radio_turn_off(bcm);
2336         if (!modparam_noleds)
2337                 bcm43xx_leds_exit(bcm);
2338         bcm43xx_gpio_cleanup(bcm);
2339         free_irq(bcm->irq, bcm);
2340         bcm43xx_release_firmware(bcm, 0);
2341 }
2342
2343 /* Initialize the chip
2344  * http://bcm-specs.sipsolutions.net/ChipInit
2345  */
2346 static int bcm43xx_chip_init(struct bcm43xx_private *bcm)
2347 {
2348         struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
2349         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
2350         int err;
2351         int iw_mode = bcm->ieee->iw_mode;
2352         int tmp;
2353         u32 value32;
2354         u16 value16;
2355
2356         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
2357                         BCM43xx_SBF_CORE_READY
2358                         | BCM43xx_SBF_400);
2359
2360         err = bcm43xx_request_firmware(bcm);
2361         if (err)
2362                 goto out;
2363         bcm43xx_upload_microcode(bcm);
2364
2365         err = bcm43xx_initialize_irq(bcm);
2366         if (err)
2367                 goto err_release_fw;
2368
2369         err = bcm43xx_gpio_init(bcm);
2370         if (err)
2371                 goto err_free_irq;
2372
2373         err = bcm43xx_upload_initvals(bcm);
2374         if (err)
2375                 goto err_gpio_cleanup;
2376         bcm43xx_radio_turn_on(bcm);
2377
2378         if (modparam_noleds)
2379                 bcm43xx_leds_turn_off(bcm);
2380         else
2381                 bcm43xx_leds_update(bcm, 0);
2382
2383         bcm43xx_write16(bcm, 0x03E6, 0x0000);
2384         err = bcm43xx_phy_init(bcm);
2385         if (err)
2386                 goto err_radio_off;
2387
2388         /* Select initial Interference Mitigation. */
2389         tmp = radio->interfmode;
2390         radio->interfmode = BCM43xx_RADIO_INTERFMODE_NONE;
2391         bcm43xx_radio_set_interference_mitigation(bcm, tmp);
2392
2393         bcm43xx_phy_set_antenna_diversity(bcm);
2394         bcm43xx_radio_set_txantenna(bcm, BCM43xx_RADIO_TXANTENNA_DEFAULT);
2395         if (phy->type == BCM43xx_PHYTYPE_B) {
2396                 value16 = bcm43xx_read16(bcm, 0x005E);
2397                 value16 |= 0x0004;
2398                 bcm43xx_write16(bcm, 0x005E, value16);
2399         }
2400         bcm43xx_write32(bcm, 0x0100, 0x01000000);
2401         if (bcm->current_core->rev < 5)
2402                 bcm43xx_write32(bcm, 0x010C, 0x01000000);
2403
2404         value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2405         value32 &= ~ BCM43xx_SBF_MODE_NOTADHOC;
2406         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32);
2407         value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2408         value32 |= BCM43xx_SBF_MODE_NOTADHOC;
2409         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32);
2410         /*FIXME: For now, use promiscuous mode at all times; otherwise we don't
2411            get broadcast or multicast packets */
2412         value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2413         value32 |= BCM43xx_SBF_MODE_PROMISC;
2414         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32);
2415
2416         if (iw_mode == IW_MODE_MONITOR) {
2417                 value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2418                 value32 |= BCM43xx_SBF_MODE_PROMISC;
2419                 value32 |= BCM43xx_SBF_MODE_MONITOR;
2420                 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32);
2421         }
2422         value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2423         value32 |= 0x100000; //FIXME: What's this? Is this correct?
2424         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32);
2425
2426         if (bcm43xx_using_pio(bcm)) {
2427                 bcm43xx_write32(bcm, 0x0210, 0x00000100);
2428                 bcm43xx_write32(bcm, 0x0230, 0x00000100);
2429                 bcm43xx_write32(bcm, 0x0250, 0x00000100);
2430                 bcm43xx_write32(bcm, 0x0270, 0x00000100);
2431                 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0034, 0x0000);
2432         }
2433
2434         /* Probe Response Timeout value */
2435         /* FIXME: Default to 0, has to be set by ioctl probably... :-/ */
2436         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0074, 0x0000);
2437
2438         if (iw_mode != IW_MODE_ADHOC && iw_mode != IW_MODE_MASTER) {
2439                 if ((bcm->chip_id == 0x4306) && (bcm->chip_rev == 3))
2440                         bcm43xx_write16(bcm, 0x0612, 0x0064);
2441                 else
2442                         bcm43xx_write16(bcm, 0x0612, 0x0032);
2443         } else
2444                 bcm43xx_write16(bcm, 0x0612, 0x0002);
2445
2446         if (bcm->current_core->rev < 3) {
2447                 bcm43xx_write16(bcm, 0x060E, 0x0000);
2448                 bcm43xx_write16(bcm, 0x0610, 0x8000);
2449                 bcm43xx_write16(bcm, 0x0604, 0x0000);
2450                 bcm43xx_write16(bcm, 0x0606, 0x0200);
2451         } else {
2452                 bcm43xx_write32(bcm, 0x0188, 0x80000000);
2453                 bcm43xx_write32(bcm, 0x018C, 0x02000000);
2454         }
2455         bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0x00004000);
2456         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_IRQ_MASK, 0x0001DC00);
2457         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_IRQ_MASK, 0x0000DC00);
2458         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_IRQ_MASK, 0x0000DC00);
2459         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_IRQ_MASK, 0x0001DC00);
2460
2461         value32 = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
2462         value32 |= 0x00100000;
2463         bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, value32);
2464
2465         bcm43xx_write16(bcm, BCM43xx_MMIO_POWERUP_DELAY, bcm43xx_pctl_powerup_delay(bcm));
2466
2467         assert(err == 0);
2468         dprintk(KERN_INFO PFX "Chip initialized\n");
2469 out:
2470         return err;
2471
2472 err_radio_off:
2473         bcm43xx_radio_turn_off(bcm);
2474 err_gpio_cleanup:
2475         bcm43xx_gpio_cleanup(bcm);
2476 err_free_irq:
2477         free_irq(bcm->irq, bcm);
2478 err_release_fw:
2479         bcm43xx_release_firmware(bcm, 1);
2480         goto out;
2481 }
2482         
2483 /* Validate chip access
2484  * http://bcm-specs.sipsolutions.net/ValidateChipAccess */
2485 static int bcm43xx_validate_chip(struct bcm43xx_private *bcm)
2486 {
2487         u32 value;
2488         u32 shm_backup;
2489
2490         shm_backup = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0000);
2491         bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, 0x0000, 0xAA5555AA);
2492         if (bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0000) != 0xAA5555AA)
2493                 goto error;
2494         bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, 0x0000, 0x55AAAA55);
2495         if (bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0000) != 0x55AAAA55)
2496                 goto error;
2497         bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, 0x0000, shm_backup);
2498
2499         value = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2500         if ((value | 0x80000000) != 0x80000400)
2501                 goto error;
2502
2503         value = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
2504         if (value != 0x00000000)
2505                 goto error;
2506
2507         return 0;
2508 error:
2509         printk(KERN_ERR PFX "Failed to validate the chipaccess\n");
2510         return -ENODEV;
2511 }
2512
2513 void bcm43xx_init_struct_phyinfo(struct bcm43xx_phyinfo *phy)
2514 {
2515         /* Initialize a "phyinfo" structure. The structure is already
2516          * zeroed out.
2517          */
2518         phy->antenna_diversity = 0xFFFF;
2519         phy->savedpctlreg = 0xFFFF;
2520         phy->minlowsig[0] = 0xFFFF;
2521         phy->minlowsig[1] = 0xFFFF;
2522         spin_lock_init(&phy->lock);
2523 }
2524
2525 void bcm43xx_init_struct_radioinfo(struct bcm43xx_radioinfo *radio)
2526 {
2527         /* Initialize a "radioinfo" structure. The structure is already
2528          * zeroed out.
2529          */
2530         radio->interfmode = BCM43xx_RADIO_INTERFMODE_NONE;
2531         radio->channel = 0xFF;
2532         radio->initial_channel = 0xFF;
2533         radio->lofcal = 0xFFFF;
2534         radio->initval = 0xFFFF;
2535         radio->nrssi[0] = -1000;
2536         radio->nrssi[1] = -1000;
2537 }
2538
2539 static int bcm43xx_probe_cores(struct bcm43xx_private *bcm)
2540 {
2541         int err, i;
2542         int current_core;
2543         u32 core_vendor, core_id, core_rev;
2544         u32 sb_id_hi, chip_id_32 = 0;
2545         u16 pci_device, chip_id_16;
2546         u8 core_count;
2547
2548         memset(&bcm->core_chipcommon, 0, sizeof(struct bcm43xx_coreinfo));
2549         memset(&bcm->core_pci, 0, sizeof(struct bcm43xx_coreinfo));
2550         memset(&bcm->core_80211, 0, sizeof(struct bcm43xx_coreinfo)
2551                                     * BCM43xx_MAX_80211_CORES);
2552         memset(&bcm->core_80211_ext, 0, sizeof(struct bcm43xx_coreinfo_80211)
2553                                         * BCM43xx_MAX_80211_CORES);
2554         bcm->current_80211_core_idx = -1;
2555         bcm->nr_80211_available = 0;
2556         bcm->current_core = NULL;
2557         bcm->active_80211_core = NULL;
2558
2559         /* map core 0 */
2560         err = _switch_core(bcm, 0);
2561         if (err)
2562                 goto out;
2563
2564         /* fetch sb_id_hi from core information registers */
2565         sb_id_hi = bcm43xx_read32(bcm, BCM43xx_CIR_SB_ID_HI);
2566
2567         core_id = (sb_id_hi & 0xFFF0) >> 4;
2568         core_rev = (sb_id_hi & 0xF);
2569         core_vendor = (sb_id_hi & 0xFFFF0000) >> 16;
2570
2571         /* if present, chipcommon is always core 0; read the chipid from it */
2572         if (core_id == BCM43xx_COREID_CHIPCOMMON) {
2573                 chip_id_32 = bcm43xx_read32(bcm, 0);
2574                 chip_id_16 = chip_id_32 & 0xFFFF;
2575                 bcm->core_chipcommon.available = 1;
2576                 bcm->core_chipcommon.id = core_id;
2577                 bcm->core_chipcommon.rev = core_rev;
2578                 bcm->core_chipcommon.index = 0;
2579                 /* While we are at it, also read the capabilities. */
2580                 bcm->chipcommon_capabilities = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_CAPABILITIES);
2581         } else {
2582                 /* without a chipCommon, use a hard coded table. */
2583                 pci_device = bcm->pci_dev->device;
2584                 if (pci_device == 0x4301)
2585                         chip_id_16 = 0x4301;
2586                 else if ((pci_device >= 0x4305) && (pci_device <= 0x4307))
2587                         chip_id_16 = 0x4307;
2588                 else if ((pci_device >= 0x4402) && (pci_device <= 0x4403))
2589                         chip_id_16 = 0x4402;
2590                 else if ((pci_device >= 0x4610) && (pci_device <= 0x4615))
2591                         chip_id_16 = 0x4610;
2592                 else if ((pci_device >= 0x4710) && (pci_device <= 0x4715))
2593                         chip_id_16 = 0x4710;
2594 #ifdef CONFIG_BCM947XX
2595                 else if ((pci_device >= 0x4320) && (pci_device <= 0x4325))
2596                         chip_id_16 = 0x4309;
2597 #endif
2598                 else {
2599                         printk(KERN_ERR PFX "Could not determine Chip ID\n");
2600                         return -ENODEV;
2601                 }
2602         }
2603
2604         /* ChipCommon with Core Rev >=4 encodes number of cores,
2605          * otherwise consult hardcoded table */
2606         if ((core_id == BCM43xx_COREID_CHIPCOMMON) && (core_rev >= 4)) {
2607                 core_count = (chip_id_32 & 0x0F000000) >> 24;
2608         } else {
2609                 switch (chip_id_16) {
2610                         case 0x4610:
2611                         case 0x4704:
2612                         case 0x4710:
2613                                 core_count = 9;
2614                                 break;
2615                         case 0x4310:
2616                                 core_count = 8;
2617                                 break;
2618                         case 0x5365:
2619                                 core_count = 7;
2620                                 break;
2621                         case 0x4306:
2622                                 core_count = 6;
2623                                 break;
2624                         case 0x4301:
2625                         case 0x4307:
2626                                 core_count = 5;
2627                                 break;
2628                         case 0x4402:
2629                                 core_count = 3;
2630                                 break;
2631                         default:
2632                                 /* SOL if we get here */
2633                                 assert(0);
2634                                 core_count = 1;
2635                 }
2636         }
2637
2638         bcm->chip_id = chip_id_16;
2639         bcm->chip_rev = (chip_id_32 & 0x000f0000) >> 16;
2640
2641         dprintk(KERN_INFO PFX "Chip ID 0x%x, rev 0x%x\n",
2642                 bcm->chip_id, bcm->chip_rev);
2643         dprintk(KERN_INFO PFX "Number of cores: %d\n", core_count);
2644         if (bcm->core_chipcommon.available) {
2645                 dprintk(KERN_INFO PFX "Core 0: ID 0x%x, rev 0x%x, vendor 0x%x, %s\n",
2646                         core_id, core_rev, core_vendor,
2647                         bcm43xx_core_enabled(bcm) ? "enabled" : "disabled");
2648         }
2649
2650         if (bcm->core_chipcommon.available)
2651                 current_core = 1;
2652         else
2653                 current_core = 0;
2654         for ( ; current_core < core_count; current_core++) {
2655                 struct bcm43xx_coreinfo *core;
2656                 struct bcm43xx_coreinfo_80211 *ext_80211;
2657
2658                 err = _switch_core(bcm, current_core);
2659                 if (err)
2660                         goto out;
2661                 /* Gather information */
2662                 /* fetch sb_id_hi from core information registers */
2663                 sb_id_hi = bcm43xx_read32(bcm, BCM43xx_CIR_SB_ID_HI);
2664
2665                 /* extract core_id, core_rev, core_vendor */
2666                 core_id = (sb_id_hi & 0xFFF0) >> 4;
2667                 core_rev = (sb_id_hi & 0xF);
2668                 core_vendor = (sb_id_hi & 0xFFFF0000) >> 16;
2669
2670                 dprintk(KERN_INFO PFX "Core %d: ID 0x%x, rev 0x%x, vendor 0x%x, %s\n",
2671                         current_core, core_id, core_rev, core_vendor,
2672                         bcm43xx_core_enabled(bcm) ? "enabled" : "disabled" );
2673
2674                 core = NULL;
2675                 switch (core_id) {
2676                 case BCM43xx_COREID_PCI:
2677                         core = &bcm->core_pci;
2678                         if (core->available) {
2679                                 printk(KERN_WARNING PFX "Multiple PCI cores found.\n");
2680                                 continue;
2681                         }
2682                         break;
2683                 case BCM43xx_COREID_80211:
2684                         for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
2685                                 core = &(bcm->core_80211[i]);
2686                                 ext_80211 = &(bcm->core_80211_ext[i]);
2687                                 if (!core->available)
2688                                         break;
2689                                 core = NULL;
2690                         }
2691                         if (!core) {
2692                                 printk(KERN_WARNING PFX "More than %d cores of type 802.11 found.\n",
2693                                        BCM43xx_MAX_80211_CORES);
2694                                 continue;
2695                         }
2696                         if (i != 0) {
2697                                 /* More than one 80211 core is only supported
2698                                  * by special chips.
2699                                  * There are chips with two 80211 cores, but with
2700                                  * dangling pins on the second core. Be careful
2701                                  * and ignore these cores here.
2702                                  */
2703                                 if (bcm->pci_dev->device != 0x4324) {
2704                                         dprintk(KERN_INFO PFX "Ignoring additional 802.11 core.\n");
2705                                         continue;
2706                                 }
2707                         }
2708                         switch (core_rev) {
2709                         case 2:
2710                         case 4:
2711                         case 5:
2712                         case 6:
2713                         case 7:
2714                         case 9:
2715                                 break;
2716                         default:
2717                                 printk(KERN_ERR PFX "Error: Unsupported 80211 core revision %u\n",
2718                                        core_rev);
2719                                 err = -ENODEV;
2720                                 goto out;
2721                         }
2722                         bcm->nr_80211_available++;
2723                         bcm43xx_init_struct_phyinfo(&ext_80211->phy);
2724                         bcm43xx_init_struct_radioinfo(&ext_80211->radio);
2725                         break;
2726                 case BCM43xx_COREID_CHIPCOMMON:
2727                         printk(KERN_WARNING PFX "Multiple CHIPCOMMON cores found.\n");
2728                         break;
2729                 }
2730                 if (core) {
2731                         core->available = 1;
2732                         core->id = core_id;
2733                         core->rev = core_rev;
2734                         core->index = current_core;
2735                 }
2736         }
2737
2738         if (!bcm->core_80211[0].available) {
2739                 printk(KERN_ERR PFX "Error: No 80211 core found!\n");
2740                 err = -ENODEV;
2741                 goto out;
2742         }
2743
2744         err = bcm43xx_switch_core(bcm, &bcm->core_80211[0]);
2745
2746         assert(err == 0);
2747 out:
2748         return err;
2749 }
2750
2751 static void bcm43xx_gen_bssid(struct bcm43xx_private *bcm)
2752 {
2753         const u8 *mac = (const u8*)(bcm->net_dev->dev_addr);
2754         u8 *bssid = bcm->ieee->bssid;
2755
2756         switch (bcm->ieee->iw_mode) {
2757         case IW_MODE_ADHOC:
2758                 random_ether_addr(bssid);
2759                 break;
2760         case IW_MODE_MASTER:
2761         case IW_MODE_INFRA:
2762         case IW_MODE_REPEAT:
2763         case IW_MODE_SECOND:
2764         case IW_MODE_MONITOR:
2765                 memcpy(bssid, mac, ETH_ALEN);
2766                 break;
2767         default:
2768                 assert(0);
2769         }
2770 }
2771
2772 static void bcm43xx_rate_memory_write(struct bcm43xx_private *bcm,
2773                                       u16 rate,
2774                                       int is_ofdm)
2775 {
2776         u16 offset;
2777
2778         if (is_ofdm) {
2779                 offset = 0x480;
2780                 offset += (bcm43xx_plcp_get_ratecode_ofdm(rate) & 0x000F) * 2;
2781         }
2782         else {
2783                 offset = 0x4C0;
2784                 offset += (bcm43xx_plcp_get_ratecode_cck(rate) & 0x000F) * 2;
2785         }
2786         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, offset + 0x20,
2787                             bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, offset));
2788 }
2789
2790 static void bcm43xx_rate_memory_init(struct bcm43xx_private *bcm)
2791 {
2792         switch (bcm43xx_current_phy(bcm)->type) {
2793         case BCM43xx_PHYTYPE_A:
2794         case BCM43xx_PHYTYPE_G:
2795                 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_6MB, 1);
2796                 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_12MB, 1);
2797                 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_18MB, 1);
2798                 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_24MB, 1);
2799                 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_36MB, 1);
2800                 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_48MB, 1);
2801                 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_54MB, 1);
2802         case BCM43xx_PHYTYPE_B:
2803                 bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_1MB, 0);
2804                 bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_2MB, 0);
2805                 bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_5MB, 0);
2806                 bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_11MB, 0);
2807                 break;
2808         default:
2809                 assert(0);
2810         }
2811 }
2812
2813 static void bcm43xx_wireless_core_cleanup(struct bcm43xx_private *bcm)
2814 {
2815         bcm43xx_chip_cleanup(bcm);
2816         bcm43xx_pio_free(bcm);
2817         bcm43xx_dma_free(bcm);
2818
2819         bcm->current_core->initialized = 0;
2820 }
2821
2822 /* http://bcm-specs.sipsolutions.net/80211Init */
2823 static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm)
2824 {
2825         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
2826         struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
2827         u32 ucodeflags;
2828         int err;
2829         u32 sbimconfiglow;
2830         u8 limit;
2831
2832         if (bcm->chip_rev < 5) {
2833                 sbimconfiglow = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW);
2834                 sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK;
2835                 sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK;
2836                 if (bcm->bustype == BCM43xx_BUSTYPE_PCI)
2837                         sbimconfiglow |= 0x32;
2838                 else if (bcm->bustype == BCM43xx_BUSTYPE_SB)
2839                         sbimconfiglow |= 0x53;
2840                 else
2841                         assert(0);
2842                 bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, sbimconfiglow);
2843         }
2844
2845         bcm43xx_phy_calibrate(bcm);
2846         err = bcm43xx_chip_init(bcm);
2847         if (err)
2848                 goto out;
2849
2850         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0016, bcm->current_core->rev);
2851         ucodeflags = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, BCM43xx_UCODEFLAGS_OFFSET);
2852
2853         if (0 /*FIXME: which condition has to be used here? */)
2854                 ucodeflags |= 0x00000010;
2855
2856         /* HW decryption needs to be set now */
2857         ucodeflags |= 0x40000000;
2858         
2859         if (phy->type == BCM43xx_PHYTYPE_G) {
2860                 ucodeflags |= BCM43xx_UCODEFLAG_UNKBGPHY;
2861                 if (phy->rev == 1)
2862                         ucodeflags |= BCM43xx_UCODEFLAG_UNKGPHY;
2863                 if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL)
2864                         ucodeflags |= BCM43xx_UCODEFLAG_UNKPACTRL;
2865         } else if (phy->type == BCM43xx_PHYTYPE_B) {
2866                 ucodeflags |= BCM43xx_UCODEFLAG_UNKBGPHY;
2867                 if (phy->rev >= 2 && radio->version == 0x2050)
2868                         ucodeflags &= ~BCM43xx_UCODEFLAG_UNKGPHY;
2869         }
2870
2871         if (ucodeflags != bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED,
2872                                              BCM43xx_UCODEFLAGS_OFFSET)) {
2873                 bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED,
2874                                     BCM43xx_UCODEFLAGS_OFFSET, ucodeflags);
2875         }
2876
2877         /* Short/Long Retry Limit.
2878          * The retry-limit is a 4-bit counter. Enforce this to avoid overflowing
2879          * the chip-internal counter.
2880          */
2881         limit = limit_value(modparam_short_retry, 0, 0xF);
2882         bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0006, limit);
2883         limit = limit_value(modparam_long_retry, 0, 0xF);
2884         bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0007, limit);
2885
2886         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0044, 3);
2887         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0046, 2);
2888
2889         bcm43xx_rate_memory_init(bcm);
2890
2891         /* Minimum Contention Window */
2892         if (phy->type == BCM43xx_PHYTYPE_B)
2893                 bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0003, 0x0000001f);
2894         else
2895                 bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0003, 0x0000000f);
2896         /* Maximum Contention Window */
2897         bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0004, 0x000003ff);
2898
2899         bcm43xx_gen_bssid(bcm);
2900         bcm43xx_write_mac_bssid_templates(bcm);
2901
2902         if (bcm->current_core->rev >= 5)
2903                 bcm43xx_write16(bcm, 0x043C, 0x000C);
2904
2905         if (bcm43xx_using_pio(bcm))
2906                 err = bcm43xx_pio_init(bcm);
2907         else
2908                 err = bcm43xx_dma_init(bcm);
2909         if (err)
2910                 goto err_chip_cleanup;
2911         bcm43xx_write16(bcm, 0x0612, 0x0050);
2912         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0416, 0x0050);
2913         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0414, 0x01F4);
2914
2915         bcm43xx_mac_enable(bcm);
2916         bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
2917
2918         bcm->current_core->initialized = 1;
2919 out:
2920         return err;
2921
2922 err_chip_cleanup:
2923         bcm43xx_chip_cleanup(bcm);
2924         goto out;
2925 }
2926
2927 static int bcm43xx_chipset_attach(struct bcm43xx_private *bcm)
2928 {
2929         int err;
2930         u16 pci_status;
2931
2932         err = bcm43xx_pctl_set_crystal(bcm, 1);
2933         if (err)
2934                 goto out;
2935         bcm43xx_pci_read_config16(bcm, PCI_STATUS, &pci_status);
2936         bcm43xx_pci_write_config16(bcm, PCI_STATUS, pci_status & ~PCI_STATUS_SIG_TARGET_ABORT);
2937
2938 out:
2939         return err;
2940 }
2941
2942 static void bcm43xx_chipset_detach(struct bcm43xx_private *bcm)
2943 {
2944         bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_SLOW);
2945         bcm43xx_pctl_set_crystal(bcm, 0);
2946 }
2947
2948 static void bcm43xx_pcicore_broadcast_value(struct bcm43xx_private *bcm,
2949                                             u32 address,
2950                                             u32 data)
2951 {
2952         bcm43xx_write32(bcm, BCM43xx_PCICORE_BCAST_ADDR, address);
2953         bcm43xx_write32(bcm, BCM43xx_PCICORE_BCAST_DATA, data);
2954 }
2955
2956 static int bcm43xx_pcicore_commit_settings(struct bcm43xx_private *bcm)
2957 {
2958         int err;
2959         struct bcm43xx_coreinfo *old_core;
2960
2961         old_core = bcm->current_core;
2962         err = bcm43xx_switch_core(bcm, &bcm->core_pci);
2963         if (err)
2964                 goto out;
2965
2966         bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000);
2967
2968         bcm43xx_switch_core(bcm, old_core);
2969         assert(err == 0);
2970 out:
2971         return err;
2972 }
2973
2974 /* Make an I/O Core usable. "core_mask" is the bitmask of the cores to enable.
2975  * To enable core 0, pass a core_mask of 1<<0
2976  */
2977 static int bcm43xx_setup_backplane_pci_connection(struct bcm43xx_private *bcm,
2978                                                   u32 core_mask)
2979 {
2980         u32 backplane_flag_nr;
2981         u32 value;
2982         struct bcm43xx_coreinfo *old_core;
2983         int err = 0;
2984
2985         value = bcm43xx_read32(bcm, BCM43xx_CIR_SBTPSFLAG);
2986         backplane_flag_nr = value & BCM43xx_BACKPLANE_FLAG_NR_MASK;
2987
2988         old_core = bcm->current_core;
2989         err = bcm43xx_switch_core(bcm, &bcm->core_pci);
2990         if (err)
2991                 goto out;
2992
2993         if (bcm->core_pci.rev < 6) {
2994                 value = bcm43xx_read32(bcm, BCM43xx_CIR_SBINTVEC);
2995                 value |= (1 << backplane_flag_nr);
2996                 bcm43xx_write32(bcm, BCM43xx_CIR_SBINTVEC, value);
2997         } else {
2998                 err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCICFG_ICR, &value);
2999                 if (err) {
3000                         printk(KERN_ERR PFX "Error: ICR setup failure!\n");
3001                         goto out_switch_back;
3002                 }
3003                 value |= core_mask << 8;
3004                 err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_ICR, value);
3005                 if (err) {
3006                         printk(KERN_ERR PFX "Error: ICR setup failure!\n");
3007                         goto out_switch_back;
3008                 }
3009         }
3010
3011         value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2);
3012         value |= BCM43xx_SBTOPCI2_PREFETCH | BCM43xx_SBTOPCI2_BURST;
3013         bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value);
3014
3015         if (bcm->core_pci.rev < 5) {
3016                 value = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW);
3017                 value |= (2 << BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT)
3018                          & BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK;
3019                 value |= (3 << BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT)
3020                          & BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK;
3021                 bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, value);
3022                 err = bcm43xx_pcicore_commit_settings(bcm);
3023                 assert(err == 0);
3024         }
3025
3026 out_switch_back:
3027         err = bcm43xx_switch_core(bcm, old_core);
3028 out:
3029         return err;
3030 }
3031
3032 static void bcm43xx_softmac_init(struct bcm43xx_private *bcm)
3033 {
3034         ieee80211softmac_start(bcm->net_dev);
3035 }
3036
3037 static void bcm43xx_periodic_every120sec(struct bcm43xx_private *bcm)
3038 {
3039         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
3040
3041         if (phy->type != BCM43xx_PHYTYPE_G || phy->rev < 2)
3042                 return;
3043
3044         bcm43xx_mac_suspend(bcm);
3045         bcm43xx_phy_lo_g_measure(bcm);
3046         bcm43xx_mac_enable(bcm);
3047 }
3048
3049 static void bcm43xx_periodic_every60sec(struct bcm43xx_private *bcm)
3050 {
3051         bcm43xx_phy_lo_mark_all_unused(bcm);
3052         if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) {
3053                 bcm43xx_mac_suspend(bcm);
3054                 bcm43xx_calc_nrssi_slope(bcm);
3055                 bcm43xx_mac_enable(bcm);
3056         }
3057 }
3058
3059 static void bcm43xx_periodic_every30sec(struct bcm43xx_private *bcm)
3060 {
3061         /* Update device statistics. */
3062         bcm43xx_calculate_link_quality(bcm);
3063 }
3064
3065 static void bcm43xx_periodic_every15sec(struct bcm43xx_private *bcm)
3066 {
3067         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
3068         struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
3069
3070         if (phy->type == BCM43xx_PHYTYPE_G) {
3071                 //TODO: update_aci_moving_average
3072                 if (radio->aci_enable && radio->aci_wlan_automatic) {
3073                         bcm43xx_mac_suspend(bcm);
3074                         if (!radio->aci_enable && 1 /*TODO: not scanning? */) {
3075                                 if (0 /*TODO: bunch of conditions*/) {
3076                                         bcm43xx_radio_set_interference_mitigation(bcm,
3077                                                                                   BCM43xx_RADIO_INTERFMODE_MANUALWLAN);
3078                                 }
3079                         } else if (1/*TODO*/) {
3080                                 /*
3081                                 if ((aci_average > 1000) && !(bcm43xx_radio_aci_scan(bcm))) {
3082                                         bcm43xx_radio_set_interference_mitigation(bcm,
3083                                                                                   BCM43xx_RADIO_INTERFMODE_NONE);
3084                                 }
3085                                 */
3086                         }
3087                         bcm43xx_mac_enable(bcm);
3088                 } else if (radio->interfmode == BCM43xx_RADIO_INTERFMODE_NONWLAN &&
3089                            phy->rev == 1) {
3090                         //TODO: implement rev1 workaround
3091                 }
3092         }
3093         bcm43xx_phy_xmitpower(bcm); //FIXME: unless scanning?
3094         //TODO for APHY (temperature?)
3095 }
3096
3097 static void bcm43xx_periodic_task_handler(unsigned long d)
3098 {
3099         struct bcm43xx_private *bcm = (struct bcm43xx_private *)d;
3100         unsigned long flags;
3101         unsigned int state;
3102
3103         bcm43xx_lock_mmio(bcm, flags);
3104
3105         assert(bcm->initialized);
3106         state = bcm->periodic_state;
3107         if (state % 8 == 0)
3108                 bcm43xx_periodic_every120sec(bcm);
3109         if (state % 4 == 0)
3110                 bcm43xx_periodic_every60sec(bcm);
3111         if (state % 2 == 0)
3112                 bcm43xx_periodic_every30sec(bcm);
3113         bcm43xx_periodic_every15sec(bcm);
3114         bcm->periodic_state = state + 1;
3115
3116         mod_timer(&bcm->periodic_tasks, jiffies + (HZ * 15));
3117
3118         bcm43xx_unlock_mmio(bcm, flags);
3119 }
3120
3121 static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm)
3122 {
3123         del_timer_sync(&bcm->periodic_tasks);
3124 }
3125
3126 static void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm)
3127 {
3128         struct timer_list *timer = &(bcm->periodic_tasks);
3129
3130         assert(bcm->initialized);
3131         setup_timer(timer,
3132                     bcm43xx_periodic_task_handler,
3133                     (unsigned long)bcm);
3134         timer->expires = jiffies;
3135         add_timer(timer);
3136 }
3137
3138 static void bcm43xx_security_init(struct bcm43xx_private *bcm)
3139 {
3140         bcm->security_offset = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
3141                                                   0x0056) * 2;
3142         bcm43xx_clear_keys(bcm);
3143 }
3144
3145 /* This is the opposite of bcm43xx_init_board() */
3146 static void bcm43xx_free_board(struct bcm43xx_private *bcm)
3147 {
3148         int i, err;
3149         unsigned long flags;
3150
3151         bcm43xx_sysfs_unregister(bcm);
3152
3153         bcm43xx_periodic_tasks_delete(bcm);
3154
3155         bcm43xx_lock(bcm, flags);
3156         bcm->initialized = 0;
3157         bcm->shutting_down = 1;
3158         bcm43xx_unlock(bcm, flags);
3159
3160         for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
3161                 if (!bcm->core_80211[i].available)
3162                         continue;
3163                 if (!bcm->core_80211[i].initialized)
3164                         continue;
3165
3166                 err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]);
3167                 assert(err == 0);
3168                 bcm43xx_wireless_core_cleanup(bcm);
3169         }
3170
3171         bcm43xx_pctl_set_crystal(bcm, 0);
3172
3173         bcm43xx_lock(bcm, flags);
3174         bcm->shutting_down = 0;
3175         bcm43xx_unlock(bcm, flags);
3176 }
3177
3178 static int bcm43xx_init_board(struct bcm43xx_private *bcm)
3179 {
3180         int i, err;
3181         int connect_phy;
3182         unsigned long flags;
3183
3184         might_sleep();
3185
3186         bcm43xx_lock(bcm, flags);
3187         bcm->initialized = 0;
3188         bcm->shutting_down = 0;
3189         bcm43xx_unlock(bcm, flags);
3190
3191         err = bcm43xx_pctl_set_crystal(bcm, 1);
3192         if (err)
3193                 goto out;
3194         err = bcm43xx_pctl_init(bcm);
3195         if (err)
3196                 goto err_crystal_off;
3197         err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_FAST);
3198         if (err)
3199                 goto err_crystal_off;
3200
3201         tasklet_enable(&bcm->isr_tasklet);
3202         for (i = 0; i < bcm->nr_80211_available; i++) {
3203                 err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]);
3204                 assert(err != -ENODEV);
3205                 if (err)
3206                         goto err_80211_unwind;
3207
3208                 /* Enable the selected wireless core.
3209                  * Connect PHY only on the first core.
3210                  */
3211                 if (!bcm43xx_core_enabled(bcm)) {
3212                         if (bcm->nr_80211_available == 1) {
3213                                 connect_phy = bcm43xx_current_phy(bcm)->connected;
3214                         } else {
3215                                 if (i == 0)
3216                                         connect_phy = 1;
3217                                 else
3218                                         connect_phy = 0;
3219                         }
3220                         bcm43xx_wireless_core_reset(bcm, connect_phy);
3221                 }
3222
3223                 if (i != 0)
3224                         bcm43xx_wireless_core_mark_inactive(bcm, &bcm->core_80211[0]);
3225
3226                 err = bcm43xx_wireless_core_init(bcm);
3227                 if (err)
3228                         goto err_80211_unwind;
3229
3230                 if (i != 0) {
3231                         bcm43xx_mac_suspend(bcm);
3232                         bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3233                         bcm43xx_radio_turn_off(bcm);
3234                 }
3235         }
3236         bcm->active_80211_core = &bcm->core_80211[0];
3237         if (bcm->nr_80211_available >= 2) {
3238                 bcm43xx_switch_core(bcm, &bcm->core_80211[0]);
3239                 bcm43xx_mac_enable(bcm);
3240         }
3241         bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC);
3242         bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 *)(bcm->net_dev->dev_addr));
3243         dprintk(KERN_INFO PFX "80211 cores initialized\n");
3244         bcm43xx_security_init(bcm);
3245         bcm43xx_softmac_init(bcm);
3246
3247         bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_DYNAMIC);
3248
3249         if (bcm43xx_current_radio(bcm)->initial_channel != 0xFF) {
3250                 bcm43xx_mac_suspend(bcm);
3251                 bcm43xx_radio_selectchannel(bcm, bcm43xx_current_radio(bcm)->initial_channel, 0);
3252                 bcm43xx_mac_enable(bcm);
3253         }
3254
3255         /* Initialization of the board is done. Flag it as such. */
3256         bcm43xx_lock(bcm, flags);
3257         bcm->initialized = 1;
3258         bcm43xx_unlock(bcm, flags);
3259
3260         bcm43xx_periodic_tasks_setup(bcm);
3261         bcm43xx_sysfs_register(bcm);
3262         //FIXME: check for bcm43xx_sysfs_register failure. This function is a bit messy regarding unwinding, though...
3263
3264         assert(err == 0);
3265 out:
3266         return err;
3267
3268 err_80211_unwind:
3269         tasklet_disable(&bcm->isr_tasklet);
3270         /* unwind all 80211 initialization */
3271         for (i = 0; i < bcm->nr_80211_available; i++) {
3272                 if (!bcm->core_80211[i].initialized)
3273                         continue;
3274                 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3275                 bcm43xx_wireless_core_cleanup(bcm);
3276         }
3277 err_crystal_off:
3278         bcm43xx_pctl_set_crystal(bcm, 0);
3279         goto out;
3280 }
3281
3282 static void bcm43xx_detach_board(struct bcm43xx_private *bcm)
3283 {
3284         struct pci_dev *pci_dev = bcm->pci_dev;
3285         int i;
3286
3287         bcm43xx_chipset_detach(bcm);
3288         /* Do _not_ access the chip, after it is detached. */
3289         iounmap(bcm->mmio_addr);
3290         
3291         pci_release_regions(pci_dev);
3292         pci_disable_device(pci_dev);
3293
3294         /* Free allocated structures/fields */
3295         for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
3296                 kfree(bcm->core_80211_ext[i].phy._lo_pairs);
3297                 if (bcm->core_80211_ext[i].phy.dyn_tssi_tbl)
3298                         kfree(bcm->core_80211_ext[i].phy.tssi2dbm);
3299         }
3300 }       
3301
3302 static int bcm43xx_read_phyinfo(struct bcm43xx_private *bcm)
3303 {
3304         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
3305         u16 value;
3306         u8 phy_version;
3307         u8 phy_type;
3308         u8 phy_rev;
3309         int phy_rev_ok = 1;
3310         void *p;
3311
3312         value = bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_VER);
3313
3314         phy_version = (value & 0xF000) >> 12;
3315         phy_type = (value & 0x0F00) >> 8;
3316         phy_rev = (value & 0x000F);
3317
3318         dprintk(KERN_INFO PFX "Detected PHY: Version: %x, Type %x, Revision %x\n",
3319                 phy_version, phy_type, phy_rev);
3320
3321         switch (phy_type) {
3322         case BCM43xx_PHYTYPE_A:
3323                 if (phy_rev >= 4)
3324                         phy_rev_ok = 0;
3325                 /*FIXME: We need to switch the ieee->modulation, etc.. flags,
3326                  *       if we switch 80211 cores after init is done.
3327                  *       As we do not implement on the fly switching between
3328                  *       wireless cores, I will leave this as a future task.
3329                  */
3330                 bcm->ieee->modulation = IEEE80211_OFDM_MODULATION;
3331                 bcm->ieee->mode = IEEE_A;
3332                 bcm->ieee->freq_band = IEEE80211_52GHZ_BAND |
3333                                        IEEE80211_24GHZ_BAND;
3334                 break;
3335         case BCM43xx_PHYTYPE_B:
3336                 if (phy_rev != 2 && phy_rev != 4 && phy_rev != 6 && phy_rev != 7)
3337                         phy_rev_ok = 0;
3338                 bcm->ieee->modulation = IEEE80211_CCK_MODULATION;
3339                 bcm->ieee->mode = IEEE_B;
3340                 bcm->ieee->freq_band = IEEE80211_24GHZ_BAND;
3341                 break;
3342         case BCM43xx_PHYTYPE_G:
3343                 if (phy_rev > 7)
3344                         phy_rev_ok = 0;
3345                 bcm->ieee->modulation = IEEE80211_OFDM_MODULATION |
3346                                         IEEE80211_CCK_MODULATION;
3347                 bcm->ieee->mode = IEEE_G;
3348                 bcm->ieee->freq_band = IEEE80211_24GHZ_BAND;
3349                 break;
3350         default:
3351                 printk(KERN_ERR PFX "Error: Unknown PHY Type %x\n",
3352                        phy_type);
3353                 return -ENODEV;
3354         };
3355         if (!phy_rev_ok) {
3356                 printk(KERN_WARNING PFX "Invalid PHY Revision %x\n",
3357                        phy_rev);
3358         }
3359
3360         phy->version = phy_version;
3361         phy->type = phy_type;
3362         phy->rev = phy_rev;
3363         if ((phy_type == BCM43xx_PHYTYPE_B) || (phy_type == BCM43xx_PHYTYPE_G)) {
3364                 p = kzalloc(sizeof(struct bcm43xx_lopair) * BCM43xx_LO_COUNT,
3365                             GFP_KERNEL);
3366                 if (!p)
3367                         return -ENOMEM;
3368                 phy->_lo_pairs = p;
3369         }
3370
3371         return 0;
3372 }
3373
3374 static int bcm43xx_attach_board(struct bcm43xx_private *bcm)
3375 {
3376         struct pci_dev *pci_dev = bcm->pci_dev;
3377         struct net_device *net_dev = bcm->net_dev;
3378         int err;
3379         int i;
3380         void __iomem *ioaddr;
3381         unsigned long mmio_start, mmio_end, mmio_flags, mmio_len;
3382         u32 coremask;
3383
3384         err = pci_enable_device(pci_dev);
3385         if (err) {
3386                 printk(KERN_ERR PFX "unable to wake up pci device (%i)\n", err);
3387                 err = -ENODEV;
3388                 goto out;
3389         }
3390
3391         mmio_start = pci_resource_start(pci_dev, 0);
3392         mmio_end = pci_resource_end(pci_dev, 0);
3393         mmio_flags = pci_resource_flags(pci_dev, 0);
3394         mmio_len = pci_resource_len(pci_dev, 0);
3395
3396         /* make sure PCI base addr is MMIO */
3397         if (!(mmio_flags & IORESOURCE_MEM)) {
3398                 printk(KERN_ERR PFX
3399                        "%s, region #0 not an MMIO resource, aborting\n",
3400                        pci_name(pci_dev));
3401                 err = -ENODEV;
3402                 goto err_pci_disable;
3403         }
3404 //FIXME: Why is this check disabled for BCM947XX? What is the IO_SIZE there?
3405 #ifndef CONFIG_BCM947XX
3406         if (mmio_len != BCM43xx_IO_SIZE) {
3407                 printk(KERN_ERR PFX
3408                        "%s: invalid PCI mem region size(s), aborting\n",
3409                        pci_name(pci_dev));
3410                 err = -ENODEV;
3411                 goto err_pci_disable;
3412         }
3413 #endif
3414
3415         err = pci_request_regions(pci_dev, KBUILD_MODNAME);
3416         if (err) {
3417                 printk(KERN_ERR PFX
3418                        "could not access PCI resources (%i)\n", err);
3419                 goto err_pci_disable;
3420         }
3421
3422         /* enable PCI bus-mastering */
3423         pci_set_master(pci_dev);
3424
3425         /* ioremap MMIO region */
3426         ioaddr = ioremap(mmio_start, mmio_len);
3427         if (!ioaddr) {
3428                 printk(KERN_ERR PFX "%s: cannot remap MMIO, aborting\n",
3429                        pci_name(pci_dev));
3430                 err = -EIO;
3431                 goto err_pci_release;
3432         }
3433
3434         net_dev->base_addr = (unsigned long)ioaddr;
3435         bcm->mmio_addr = ioaddr;
3436         bcm->mmio_len = mmio_len;
3437
3438         bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_VENDOR_ID,
3439                                   &bcm->board_vendor);
3440         bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_ID,
3441                                   &bcm->board_type);
3442         bcm43xx_pci_read_config16(bcm, PCI_REVISION_ID,
3443                                   &bcm->board_revision);
3444
3445         err = bcm43xx_chipset_attach(bcm);
3446         if (err)
3447                 goto err_iounmap;
3448         err = bcm43xx_pctl_init(bcm);
3449         if (err)
3450                 goto err_chipset_detach;
3451         err = bcm43xx_probe_cores(bcm);
3452         if (err)
3453                 goto err_chipset_detach;
3454         
3455         /* Attach all IO cores to the backplane. */
3456         coremask = 0;
3457         for (i = 0; i < bcm->nr_80211_available; i++)
3458                 coremask |= (1 << bcm->core_80211[i].index);
3459         //FIXME: Also attach some non80211 cores?
3460         err = bcm43xx_setup_backplane_pci_connection(bcm, coremask);
3461         if (err) {
3462                 printk(KERN_ERR PFX "Backplane->PCI connection failed!\n");
3463                 goto err_chipset_detach;
3464         }
3465
3466         err = bcm43xx_sprom_extract(bcm);
3467         if (err)
3468                 goto err_chipset_detach;
3469         err = bcm43xx_leds_init(bcm);
3470         if (err)
3471                 goto err_chipset_detach;
3472
3473         for (i = 0; i < bcm->nr_80211_available; i++) {
3474                 err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]);
3475                 assert(err != -ENODEV);
3476                 if (err)
3477                         goto err_80211_unwind;
3478
3479                 /* Enable the selected wireless core.
3480                  * Connect PHY only on the first core.
3481                  */
3482                 bcm43xx_wireless_core_reset(bcm, (i == 0));
3483
3484                 err = bcm43xx_read_phyinfo(bcm);
3485                 if (err && (i == 0))
3486                         goto err_80211_unwind;
3487
3488                 err = bcm43xx_read_radioinfo(bcm);
3489                 if (err && (i == 0))
3490                         goto err_80211_unwind;
3491
3492                 err = bcm43xx_validate_chip(bcm);
3493                 if (err && (i == 0))
3494                         goto err_80211_unwind;
3495
3496                 bcm43xx_radio_turn_off(bcm);
3497                 err = bcm43xx_phy_init_tssi2dbm_table(bcm);
3498                 if (err)
3499                         goto err_80211_unwind;
3500                 bcm43xx_wireless_core_disable(bcm);
3501         }
3502         bcm43xx_pctl_set_crystal(bcm, 0);
3503
3504         /* Set the MAC address in the networking subsystem */
3505         if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A)
3506                 memcpy(bcm->net_dev->dev_addr, bcm->sprom.et1macaddr, 6);
3507         else
3508                 memcpy(bcm->net_dev->dev_addr, bcm->sprom.il0macaddr, 6);
3509
3510         bcm43xx_geo_init(bcm);
3511
3512         snprintf(bcm->nick, IW_ESSID_MAX_SIZE,
3513                  "Broadcom %04X", bcm->chip_id);
3514
3515         assert(err == 0);
3516 out:
3517         return err;
3518
3519 err_80211_unwind:
3520         for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
3521                 kfree(bcm->core_80211_ext[i].phy._lo_pairs);
3522                 if (bcm->core_80211_ext[i].phy.dyn_tssi_tbl)
3523                         kfree(bcm->core_80211_ext[i].phy.tssi2dbm);
3524         }
3525 err_chipset_detach:
3526         bcm43xx_chipset_detach(bcm);
3527 err_iounmap:
3528         iounmap(bcm->mmio_addr);
3529 err_pci_release:
3530         pci_release_regions(pci_dev);
3531 err_pci_disable:
3532         pci_disable_device(pci_dev);
3533         goto out;
3534 }
3535
3536 /* Do the Hardware IO operations to send the txb */
3537 static inline int bcm43xx_tx(struct bcm43xx_private *bcm,
3538                              struct ieee80211_txb *txb)
3539 {
3540         int err = -ENODEV;
3541
3542         if (bcm43xx_using_pio(bcm))
3543                 err = bcm43xx_pio_tx(bcm, txb);
3544         else
3545                 err = bcm43xx_dma_tx(bcm, txb);
3546
3547         return err;
3548 }
3549
3550 static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev,
3551                                        u8 channel)
3552 {
3553         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3554         unsigned long flags;
3555
3556         bcm43xx_lock_mmio(bcm, flags);
3557         bcm43xx_mac_suspend(bcm);
3558         bcm43xx_radio_selectchannel(bcm, channel, 0);
3559         bcm43xx_mac_enable(bcm);
3560         bcm43xx_unlock_mmio(bcm, flags);
3561 }
3562
3563 /* set_security() callback in struct ieee80211_device */
3564 static void bcm43xx_ieee80211_set_security(struct net_device *net_dev,
3565                                            struct ieee80211_security *sec)
3566 {
3567         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3568         struct ieee80211_security *secinfo = &bcm->ieee->sec;
3569         unsigned long flags;
3570         int keyidx;
3571         
3572         dprintk(KERN_INFO PFX "set security called\n");
3573
3574         bcm43xx_lock_mmio(bcm, flags);
3575
3576         for (keyidx = 0; keyidx<WEP_KEYS; keyidx++)
3577                 if (sec->flags & (1<<keyidx)) {
3578                         secinfo->encode_alg[keyidx] = sec->encode_alg[keyidx];
3579                         secinfo->key_sizes[keyidx] = sec->key_sizes[keyidx];
3580                         memcpy(secinfo->keys[keyidx], sec->keys[keyidx], SCM_KEY_LEN);
3581                 }
3582         
3583         if (sec->flags & SEC_ACTIVE_KEY) {
3584                 secinfo->active_key = sec->active_key;
3585                 dprintk(KERN_INFO PFX "   .active_key = %d\n", sec->active_key);
3586         }
3587         if (sec->flags & SEC_UNICAST_GROUP) {
3588                 secinfo->unicast_uses_group = sec->unicast_uses_group;
3589                 dprintk(KERN_INFO PFX "   .unicast_uses_group = %d\n", sec->unicast_uses_group);
3590         }
3591         if (sec->flags & SEC_LEVEL) {
3592                 secinfo->level = sec->level;
3593                 dprintk(KERN_INFO PFX "   .level = %d\n", sec->level);
3594         }
3595         if (sec->flags & SEC_ENABLED) {
3596                 secinfo->enabled = sec->enabled;
3597                 dprintk(KERN_INFO PFX "   .enabled = %d\n", sec->enabled);
3598         }
3599         if (sec->flags & SEC_ENCRYPT) {
3600                 secinfo->encrypt = sec->encrypt;
3601                 dprintk(KERN_INFO PFX "   .encrypt = %d\n", sec->encrypt);
3602         }
3603         if (bcm->initialized && !bcm->ieee->host_encrypt) {
3604                 if (secinfo->enabled) {
3605                         /* upload WEP keys to hardware */
3606                         char null_address[6] = { 0 };
3607                         u8 algorithm = 0;
3608                         for (keyidx = 0; keyidx<WEP_KEYS; keyidx++) {
3609                                 if (!(sec->flags & (1<<keyidx)))
3610                                         continue;
3611                                 switch (sec->encode_alg[keyidx]) {
3612                                         case SEC_ALG_NONE: algorithm = BCM43xx_SEC_ALGO_NONE; break;
3613                                         case SEC_ALG_WEP:
3614                                                 algorithm = BCM43xx_SEC_ALGO_WEP;
3615                                                 if (secinfo->key_sizes[keyidx] == 13)
3616                                                         algorithm = BCM43xx_SEC_ALGO_WEP104;
3617                                                 break;
3618                                         case SEC_ALG_TKIP:
3619                                                 FIXME();
3620                                                 algorithm = BCM43xx_SEC_ALGO_TKIP;
3621                                                 break;
3622                                         case SEC_ALG_CCMP:
3623                                                 FIXME();
3624                                                 algorithm = BCM43xx_SEC_ALGO_AES;
3625                                                 break;
3626                                         default:
3627                                                 assert(0);
3628                                                 break;
3629                                 }
3630                                 bcm43xx_key_write(bcm, keyidx, algorithm, sec->keys[keyidx], secinfo->key_sizes[keyidx], &null_address[0]);
3631                                 bcm->key[keyidx].enabled = 1;
3632                                 bcm->key[keyidx].algorithm = algorithm;
3633                         }
3634                 } else
3635                                 bcm43xx_clear_keys(bcm);
3636         }
3637         bcm43xx_unlock_mmio(bcm, flags);
3638 }
3639
3640 /* hard_start_xmit() callback in struct ieee80211_device */
3641 static int bcm43xx_ieee80211_hard_start_xmit(struct ieee80211_txb *txb,
3642                                              struct net_device *net_dev,
3643                                              int pri)
3644 {
3645         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3646         int err = -ENODEV;
3647         unsigned long flags;
3648
3649         bcm43xx_lock_mmio(bcm, flags);
3650         if (likely(bcm->initialized))
3651                 err = bcm43xx_tx(bcm, txb);
3652         bcm43xx_unlock_mmio(bcm, flags);
3653
3654         return err;
3655 }
3656
3657 static struct net_device_stats * bcm43xx_net_get_stats(struct net_device *net_dev)
3658 {
3659         return &(bcm43xx_priv(net_dev)->ieee->stats);
3660 }
3661
3662 static void bcm43xx_net_tx_timeout(struct net_device *net_dev)
3663 {
3664         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3665         unsigned long flags;
3666
3667         bcm43xx_lock_mmio(bcm, flags);
3668         bcm43xx_controller_restart(bcm, "TX timeout");
3669         bcm43xx_unlock_mmio(bcm, flags);
3670 }
3671
3672 #ifdef CONFIG_NET_POLL_CONTROLLER
3673 static void bcm43xx_net_poll_controller(struct net_device *net_dev)
3674 {
3675         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3676         unsigned long flags;
3677
3678         local_irq_save(flags);
3679         bcm43xx_interrupt_handler(bcm->irq, bcm, NULL);
3680         local_irq_restore(flags);
3681 }
3682 #endif /* CONFIG_NET_POLL_CONTROLLER */
3683
3684 static int bcm43xx_net_open(struct net_device *net_dev)
3685 {
3686         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3687
3688         return bcm43xx_init_board(bcm);
3689 }
3690
3691 static int bcm43xx_net_stop(struct net_device *net_dev)
3692 {
3693         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3694
3695         ieee80211softmac_stop(net_dev);
3696         bcm43xx_disable_interrupts_sync(bcm, NULL);
3697         bcm43xx_free_board(bcm);
3698
3699         return 0;
3700 }
3701
3702 static int bcm43xx_init_private(struct bcm43xx_private *bcm,
3703                                 struct net_device *net_dev,
3704                                 struct pci_dev *pci_dev)
3705 {
3706         int err;
3707
3708         bcm->ieee = netdev_priv(net_dev);
3709         bcm->softmac = ieee80211_priv(net_dev);
3710         bcm->softmac->set_channel = bcm43xx_ieee80211_set_chan;
3711
3712         bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
3713         bcm->pci_dev = pci_dev;
3714         bcm->net_dev = net_dev;
3715         bcm->bad_frames_preempt = modparam_bad_frames_preempt;
3716         spin_lock_init(&bcm->_lock);
3717         tasklet_init(&bcm->isr_tasklet,
3718                      (void (*)(unsigned long))bcm43xx_interrupt_tasklet,
3719                      (unsigned long)bcm);
3720         tasklet_disable_nosync(&bcm->isr_tasklet);
3721         if (modparam_pio) {
3722                 bcm->__using_pio = 1;
3723         } else {
3724                 err = pci_set_dma_mask(pci_dev, DMA_30BIT_MASK);
3725                 err |= pci_set_consistent_dma_mask(pci_dev, DMA_30BIT_MASK);
3726                 if (err) {
3727 #ifdef CONFIG_BCM43XX_PIO
3728                         printk(KERN_WARNING PFX "DMA not supported. Falling back to PIO.\n");
3729                         bcm->__using_pio = 1;
3730 #else
3731                         printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. "
3732                                             "Recompile the driver with PIO support, please.\n");
3733                         return -ENODEV;
3734 #endif /* CONFIG_BCM43XX_PIO */
3735                 }
3736         }
3737         bcm->rts_threshold = BCM43xx_DEFAULT_RTS_THRESHOLD;
3738
3739         /* default to sw encryption for now */
3740         bcm->ieee->host_build_iv = 0;
3741         bcm->ieee->host_encrypt = 1;
3742         bcm->ieee->host_decrypt = 1;
3743         
3744         bcm->ieee->iw_mode = BCM43xx_INITIAL_IWMODE;
3745         bcm->ieee->tx_headroom = sizeof(struct bcm43xx_txhdr);
3746         bcm->ieee->set_security = bcm43xx_ieee80211_set_security;
3747         bcm->ieee->hard_start_xmit = bcm43xx_ieee80211_hard_start_xmit;
3748
3749         return 0;
3750 }
3751
3752 static int __devinit bcm43xx_init_one(struct pci_dev *pdev,
3753                                       const struct pci_device_id *ent)
3754 {
3755         struct net_device *net_dev;
3756         struct bcm43xx_private *bcm;
3757         int err;
3758
3759 #ifdef CONFIG_BCM947XX
3760         if ((pdev->bus->number == 0) && (pdev->device != 0x0800))
3761                 return -ENODEV;
3762 #endif
3763
3764 #ifdef DEBUG_SINGLE_DEVICE_ONLY
3765         if (strcmp(pci_name(pdev), DEBUG_SINGLE_DEVICE_ONLY))
3766                 return -ENODEV;
3767 #endif
3768
3769         net_dev = alloc_ieee80211softmac(sizeof(*bcm));
3770         if (!net_dev) {
3771                 printk(KERN_ERR PFX
3772                        "could not allocate ieee80211 device %s\n",
3773                        pci_name(pdev));
3774                 err = -ENOMEM;
3775                 goto out;
3776         }
3777         /* initialize the net_device struct */
3778         SET_MODULE_OWNER(net_dev);
3779         SET_NETDEV_DEV(net_dev, &pdev->dev);
3780
3781         net_dev->open = bcm43xx_net_open;
3782         net_dev->stop = bcm43xx_net_stop;
3783         net_dev->get_stats = bcm43xx_net_get_stats;
3784         net_dev->tx_timeout = bcm43xx_net_tx_timeout;
3785 #ifdef CONFIG_NET_POLL_CONTROLLER
3786         net_dev->poll_controller = bcm43xx_net_poll_controller;
3787 #endif
3788         net_dev->wireless_handlers = &bcm43xx_wx_handlers_def;
3789         net_dev->irq = pdev->irq;
3790         SET_ETHTOOL_OPS(net_dev, &bcm43xx_ethtool_ops);
3791
3792         /* initialize the bcm43xx_private struct */
3793         bcm = bcm43xx_priv(net_dev);
3794         memset(bcm, 0, sizeof(*bcm));
3795         err = bcm43xx_init_private(bcm, net_dev, pdev);
3796         if (err)
3797                 goto err_free_netdev;
3798
3799         pci_set_drvdata(pdev, net_dev);
3800
3801         err = bcm43xx_attach_board(bcm);
3802         if (err)
3803                 goto err_free_netdev;
3804
3805         err = register_netdev(net_dev);
3806         if (err) {
3807                 printk(KERN_ERR PFX "Cannot register net device, "
3808                        "aborting.\n");
3809                 err = -ENOMEM;
3810                 goto err_detach_board;
3811         }
3812
3813         bcm43xx_debugfs_add_device(bcm);
3814
3815         assert(err == 0);
3816 out:
3817         return err;
3818
3819 err_detach_board:
3820         bcm43xx_detach_board(bcm);
3821 err_free_netdev:
3822         free_ieee80211softmac(net_dev);
3823         goto out;
3824 }
3825
3826 static void __devexit bcm43xx_remove_one(struct pci_dev *pdev)
3827 {
3828         struct net_device *net_dev = pci_get_drvdata(pdev);
3829         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3830
3831         bcm43xx_debugfs_remove_device(bcm);
3832         unregister_netdev(net_dev);
3833         bcm43xx_detach_board(bcm);
3834         assert(bcm->ucode == NULL);
3835         free_ieee80211softmac(net_dev);
3836 }
3837
3838 /* Hard-reset the chip. Do not call this directly.
3839  * Use bcm43xx_controller_restart()
3840  */
3841 static void bcm43xx_chip_reset(void *_bcm)
3842 {
3843         struct bcm43xx_private *bcm = _bcm;
3844         struct net_device *net_dev = bcm->net_dev;
3845         struct pci_dev *pci_dev = bcm->pci_dev;
3846         int err;
3847         int was_initialized = bcm->initialized;
3848
3849         netif_stop_queue(bcm->net_dev);
3850         tasklet_disable(&bcm->isr_tasklet);
3851
3852         bcm->firmware_norelease = 1;
3853         if (was_initialized)
3854                 bcm43xx_free_board(bcm);
3855         bcm->firmware_norelease = 0;
3856         bcm43xx_detach_board(bcm);
3857         err = bcm43xx_init_private(bcm, net_dev, pci_dev);
3858         if (err)
3859                 goto failure;
3860         err = bcm43xx_attach_board(bcm);
3861         if (err)
3862                 goto failure;
3863         if (was_initialized) {
3864                 err = bcm43xx_init_board(bcm);
3865                 if (err)
3866                         goto failure;
3867         }
3868         netif_wake_queue(bcm->net_dev);
3869         printk(KERN_INFO PFX "Controller restarted\n");
3870
3871         return;
3872 failure:
3873         printk(KERN_ERR PFX "Controller restart failed\n");
3874 }
3875
3876 /* Hard-reset the chip.
3877  * This can be called from interrupt or process context.
3878  * Make sure to _not_ re-enable device interrupts after this has been called.
3879 */
3880 void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason)
3881 {
3882         bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3883         bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
3884         printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason);
3885         INIT_WORK(&bcm->restart_work, bcm43xx_chip_reset, bcm);
3886         schedule_work(&bcm->restart_work);
3887 }
3888
3889 #ifdef CONFIG_PM
3890
3891 static int bcm43xx_suspend(struct pci_dev *pdev, pm_message_t state)
3892 {
3893         struct net_device *net_dev = pci_get_drvdata(pdev);
3894         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3895         unsigned long flags;
3896         int try_to_shutdown = 0, err;
3897
3898         dprintk(KERN_INFO PFX "Suspending...\n");
3899
3900         bcm43xx_lock(bcm, flags);
3901         bcm->was_initialized = bcm->initialized;
3902         if (bcm->initialized)
3903                 try_to_shutdown = 1;
3904         bcm43xx_unlock(bcm, flags);
3905
3906         netif_device_detach(net_dev);
3907         if (try_to_shutdown) {
3908                 ieee80211softmac_stop(net_dev);
3909                 err = bcm43xx_disable_interrupts_sync(bcm, &bcm->irq_savedstate);
3910                 if (unlikely(err)) {
3911                         dprintk(KERN_ERR PFX "Suspend failed.\n");
3912                         return -EAGAIN;
3913                 }
3914                 bcm->firmware_norelease = 1;
3915                 bcm43xx_free_board(bcm);
3916                 bcm->firmware_norelease = 0;
3917         }
3918         bcm43xx_chipset_detach(bcm);
3919
3920         pci_save_state(pdev);
3921         pci_disable_device(pdev);
3922         pci_set_power_state(pdev, pci_choose_state(pdev, state));
3923
3924         dprintk(KERN_INFO PFX "Device suspended.\n");
3925
3926         return 0;
3927 }
3928
3929 static int bcm43xx_resume(struct pci_dev *pdev)
3930 {
3931         struct net_device *net_dev = pci_get_drvdata(pdev);
3932         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3933         int err = 0;
3934
3935         dprintk(KERN_INFO PFX "Resuming...\n");
3936
3937         pci_set_power_state(pdev, 0);
3938         pci_enable_device(pdev);
3939         pci_restore_state(pdev);
3940
3941         bcm43xx_chipset_attach(bcm);
3942         if (bcm->was_initialized) {
3943                 bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
3944                 err = bcm43xx_init_board(bcm);
3945         }
3946         if (err) {
3947                 printk(KERN_ERR PFX "Resume failed!\n");
3948                 return err;
3949         }
3950
3951         netif_device_attach(net_dev);
3952         
3953         /*FIXME: This should be handled by softmac instead. */
3954         schedule_work(&bcm->softmac->associnfo.work);
3955
3956         dprintk(KERN_INFO PFX "Device resumed.\n");
3957
3958         return 0;
3959 }
3960
3961 #endif                          /* CONFIG_PM */
3962
3963 static struct pci_driver bcm43xx_pci_driver = {
3964         .name = KBUILD_MODNAME,
3965         .id_table = bcm43xx_pci_tbl,
3966         .probe = bcm43xx_init_one,
3967         .remove = __devexit_p(bcm43xx_remove_one),
3968 #ifdef CONFIG_PM
3969         .suspend = bcm43xx_suspend,
3970         .resume = bcm43xx_resume,
3971 #endif                          /* CONFIG_PM */
3972 };
3973
3974 static int __init bcm43xx_init(void)
3975 {
3976         printk(KERN_INFO KBUILD_MODNAME " driver\n");
3977         bcm43xx_debugfs_init();
3978         return pci_register_driver(&bcm43xx_pci_driver);
3979 }
3980
3981 static void __exit bcm43xx_exit(void)
3982 {
3983         pci_unregister_driver(&bcm43xx_pci_driver);
3984         bcm43xx_debugfs_exit();
3985 }
3986
3987 module_init(bcm43xx_init)
3988 module_exit(bcm43xx_exit)
3989
3990 /* vim: set ts=8 sw=8 sts=8: */