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