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