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