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