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