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