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