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>
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
);
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.");
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 },
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 */
152 MODULE_DEVICE_TABLE(pci
, bcm43xx_pci_tbl
);
154 static void bcm43xx_ram_write(struct bcm43xx_private
*bcm
, u16 offset
, u32 val
)
158 status
= bcm43xx_read32(bcm
, BCM43xx_MMIO_STATUS_BITFIELD
);
159 if (!(status
& BCM43xx_SBF_XFER_REG_BYTESWAP
))
162 bcm43xx_write32(bcm
, BCM43xx_MMIO_RAM_CONTROL
, offset
);
163 bcm43xx_write32(bcm
, BCM43xx_MMIO_RAM_DATA
, val
);
167 void bcm43xx_shm_control_word(struct bcm43xx_private
*bcm
,
168 u16 routing
, u16 offset
)
172 /* "offset" is the WORD offset. */
177 bcm43xx_write32(bcm
, BCM43xx_MMIO_SHM_CONTROL
, control
);
180 u32
bcm43xx_shm_read32(struct bcm43xx_private
*bcm
,
181 u16 routing
, u16 offset
)
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
);
191 bcm43xx_shm_control_word(bcm
, routing
, (offset
>> 2) + 1);
192 ret
|= bcm43xx_read16(bcm
, BCM43xx_MMIO_SHM_DATA
);
198 bcm43xx_shm_control_word(bcm
, routing
, offset
);
199 ret
= bcm43xx_read32(bcm
, BCM43xx_MMIO_SHM_DATA
);
204 u16
bcm43xx_shm_read16(struct bcm43xx_private
*bcm
,
205 u16 routing
, u16 offset
)
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
);
219 bcm43xx_shm_control_word(bcm
, routing
, offset
);
220 ret
= bcm43xx_read16(bcm
, BCM43xx_MMIO_SHM_DATA
);
225 void bcm43xx_shm_write32(struct bcm43xx_private
*bcm
,
226 u16 routing
, u16 offset
,
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
,
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
,
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
,
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
;
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
));
287 u16 test1
, test2
, test3
;
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
);
312 void bcm43xx_tsf_write(struct bcm43xx_private
*bcm
, u64 tsf
)
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;
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
);
333 u16 v0
= (tsf
& 0x000000000000FFFFULL
);
334 u16 v1
= (tsf
& 0x00000000FFFF0000ULL
) >> 16;
335 u16 v2
= (tsf
& 0x0000FFFF00000000ULL
) >> 32;
336 u16 v3
= (tsf
& 0xFFFF000000000000ULL
) >> 48;
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
);
352 u8
bcm43xx_plcp_get_bitrate(struct bcm43xx_plcp_hdr4
*plcp
,
353 const int ofdm_modulation
)
357 if (ofdm_modulation
) {
358 switch (plcp
->raw
[0] & 0xF) {
360 rate
= IEEE80211_OFDM_RATE_6MB
;
363 rate
= IEEE80211_OFDM_RATE_9MB
;
366 rate
= IEEE80211_OFDM_RATE_12MB
;
369 rate
= IEEE80211_OFDM_RATE_18MB
;
372 rate
= IEEE80211_OFDM_RATE_24MB
;
375 rate
= IEEE80211_OFDM_RATE_36MB
;
378 rate
= IEEE80211_OFDM_RATE_48MB
;
381 rate
= IEEE80211_OFDM_RATE_54MB
;
388 switch (plcp
->raw
[0]) {
390 rate
= IEEE80211_CCK_RATE_1MB
;
393 rate
= IEEE80211_CCK_RATE_2MB
;
396 rate
= IEEE80211_CCK_RATE_5MB
;
399 rate
= IEEE80211_CCK_RATE_11MB
;
411 u8
bcm43xx_plcp_get_ratecode_cck(const u8 bitrate
)
414 case IEEE80211_CCK_RATE_1MB
:
416 case IEEE80211_CCK_RATE_2MB
:
418 case IEEE80211_CCK_RATE_5MB
:
420 case IEEE80211_CCK_RATE_11MB
:
428 u8
bcm43xx_plcp_get_ratecode_ofdm(const u8 bitrate
)
431 case IEEE80211_OFDM_RATE_6MB
:
433 case IEEE80211_OFDM_RATE_9MB
:
435 case IEEE80211_OFDM_RATE_12MB
:
437 case IEEE80211_OFDM_RATE_18MB
:
439 case IEEE80211_OFDM_RATE_24MB
:
441 case IEEE80211_OFDM_RATE_36MB
:
443 case IEEE80211_OFDM_RATE_48MB
:
445 case IEEE80211_OFDM_RATE_54MB
:
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
);
470 plen
= octets
* 16 / bitrate
;
471 if ((octets
* 16 % bitrate
) > 0) {
473 if ((bitrate
== IEEE80211_CCK_RATE_11MB
)
474 && ((octets
* 8 % 11) < 4)) {
480 *data
|= cpu_to_le32(plen
<< 16);
481 raw
[0] = bcm43xx_plcp_get_ratecode_cck(bitrate
);
484 //bcm43xx_printk_bitdump(raw, 4, 0, "PLCP");
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
,
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
;
501 int fallback_ofdm_modulation
;
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.
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");
536 memcpy(txhdr
->wep_iv
, hdr
->payload
, 4);
537 /* Hardware appends ICV. */
541 /* Generate the PLCP header and the fallback PLCP header. */
542 bcm43xx_generate_plcp_hdr((struct bcm43xx_plcp_hdr4
*)(&txhdr
->plcp
),
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 */
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 */
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");
584 void bcm43xx_macfilter_set(struct bcm43xx_private
*bcm
,
591 bcm43xx_write16(bcm
, BCM43xx_MMIO_MACFILTER_CONTROL
, offset
);
595 bcm43xx_write16(bcm
, BCM43xx_MMIO_MACFILTER_DATA
, data
);
598 bcm43xx_write16(bcm
, BCM43xx_MMIO_MACFILTER_DATA
, data
);
601 bcm43xx_write16(bcm
, BCM43xx_MMIO_MACFILTER_DATA
, data
);
605 void bcm43xx_macfilter_clear(struct bcm43xx_private
*bcm
,
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];
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
)));
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
)
638 bcm43xx_write16(bcm
, 0x684, 510 + slot_time
);
639 bcm43xx_shm_write16(bcm
, BCM43xx_SHM_SHARED
, 0x0010, slot_time
);
643 void bcm43xx_short_slot_timing_enable(struct bcm43xx_private
*bcm
)
645 bcm43xx_set_slot_time(bcm
, 9);
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);
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
,
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
)
701 old_mask
= bcm43xx_read32(bcm
, BCM43xx_MMIO_GEN_IRQ_MASK
);
702 bcm43xx_write32(bcm
, BCM43xx_MMIO_GEN_IRQ_MASK
, old_mask
| 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
)
714 old_mask
= bcm43xx_read32(bcm
, BCM43xx_MMIO_GEN_IRQ_MASK
);
715 bcm43xx_write32(bcm
, BCM43xx_MMIO_GEN_IRQ_MASK
, old_mask
& ~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
)
726 spin_lock_irqsave(&bcm
->lock
, flags
);
727 if (bcm43xx_is_initializing(bcm
) || bcm
->shutting_down
) {
728 spin_unlock_irqrestore(&bcm
->lock
, flags
);
731 old
= bcm43xx_interrupt_disable(bcm
, BCM43xx_IRQ_ALL
);
732 tasklet_disable(&bcm
->isr_tasklet
);
733 spin_unlock_irqrestore(&bcm
->lock
, flags
);
740 static int bcm43xx_read_radioinfo(struct bcm43xx_private
*bcm
)
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;
754 radio_id
= 0x5205017F;
756 bcm43xx_write16(bcm
, BCM43xx_MMIO_RADIO_CONTROL
, BCM43xx_RADIOCTL_ID
);
757 radio_id
= bcm43xx_read16(bcm
, BCM43xx_MMIO_RADIO_DATA_HIGH
);
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
;
775 case BCM43xx_PHYTYPE_B
:
776 if ((version
& 0xFFF0) != 0x2050)
777 goto err_unsupported_radio
;
779 case BCM43xx_PHYTYPE_G
:
780 if (version
!= 0x2050)
781 goto err_unsupported_radio
;
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;
793 bcm
->current_core
->radio
->txpower
[2] = 3;
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
;
803 err_unsupported_radio
:
804 printk(KERN_ERR PFX
"Unsupported Radio connected to the PHY!\n");
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)
815 case BCM43xx_LOCALE_WORLD
:
816 case BCM43xx_LOCALE_ALL
:
818 case BCM43xx_LOCALE_THAILAND
:
820 case BCM43xx_LOCALE_ISRAEL
:
822 case BCM43xx_LOCALE_JORDAN
:
824 case BCM43xx_LOCALE_CHINA
:
826 case BCM43xx_LOCALE_JAPAN
:
827 case BCM43xx_LOCALE_JAPAN_HIGH
:
829 case BCM43xx_LOCALE_USA_CANADA_ANZ
:
830 case BCM43xx_LOCALE_USA_LOW
:
832 case BCM43xx_LOCALE_EUROPE
:
834 case BCM43xx_LOCALE_NONE
:
841 static const char * bcm43xx_locale_string(u8 locale
)
844 case BCM43xx_LOCALE_WORLD
:
846 case BCM43xx_LOCALE_THAILAND
:
848 case BCM43xx_LOCALE_ISRAEL
:
850 case BCM43xx_LOCALE_JORDAN
:
852 case BCM43xx_LOCALE_CHINA
:
854 case BCM43xx_LOCALE_JAPAN
:
856 case BCM43xx_LOCALE_USA_CANADA_ANZ
:
857 return "USA/Canada/ANZ";
858 case BCM43xx_LOCALE_EUROPE
:
860 case BCM43xx_LOCALE_USA_LOW
:
862 case BCM43xx_LOCALE_JAPAN_HIGH
:
864 case BCM43xx_LOCALE_ALL
:
866 case BCM43xx_LOCALE_NONE
:
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
)
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);
928 static int bcm43xx_read_sprom(struct bcm43xx_private
*bcm
)
933 u8 crc
, expected_crc
;
934 #ifdef CONFIG_BCM947XX
938 sprom
= kzalloc(BCM43xx_SPROM_SIZE
* sizeof(u16
),
941 printk(KERN_ERR PFX
"read_sprom OOM\n");
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"));
964 for (i
= 0; i
< BCM43xx_SPROM_SIZE
; i
++)
965 sprom
[i
] = bcm43xx_read16(bcm
, BCM43xx_SPROM_BASE
+ (i
* 2));
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",
978 value
= sprom
[BCM43xx_SPROM_BOARDFLAGS2
];
979 bcm
->sprom
.boardflags2
= value
;
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
);
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
);
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",
1024 bcm43xx_locale_string(bcm
->sprom
.locale
));
1026 printk(KERN_WARNING PFX
"Module parameter \"locale\" "
1027 "invalid value. (0 - 11)\n");
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
;
1040 value
= sprom
[BCM43xx_SPROM_WL0GPIO0
];
1041 if (value
== 0x0000)
1043 bcm
->sprom
.wl0gpio0
= value
& 0x00FF;
1044 bcm
->sprom
.wl0gpio1
= (value
& 0xFF00) >> 8;
1045 value
= sprom
[BCM43xx_SPROM_WL0GPIO2
];
1046 if (value
== 0x0000)
1048 bcm
->sprom
.wl0gpio2
= value
& 0x00FF;
1049 bcm
->sprom
.wl0gpio3
= (value
& 0xFF00) >> 8;
1052 value
= sprom
[BCM43xx_SPROM_MAXPWR
];
1053 bcm
->sprom
.maxpower_aphy
= (value
& 0xFF00) >> 8;
1054 bcm
->sprom
.maxpower_bgphy
= value
& 0x00FF;
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;
1070 value
= sprom
[BCM43xx_SPROM_BOARDFLAGS
];
1071 if (value
== 0xFFFF)
1073 bcm
->sprom
.boardflags
= value
;
1076 value
= sprom
[BCM43xx_SPROM_ANTENNA_GAIN
];
1077 if (value
== 0x0000 || value
== 0xFFFF)
1079 /* convert values to Q5.2 */
1080 bcm
->sprom
.antennagain_aphy
= ((value
& 0xFF00) >> 8) * 4;
1081 bcm
->sprom
.antennagain_bgphy
= (value
& 0x00FF) * 4;
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;
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
++) {
1102 switch (phy
->type
) {
1103 case BCM43xx_PHYTYPE_B
:
1104 case BCM43xx_PHYTYPE_G
:
1107 case BCM43xx_PHYTYPE_A
:
1114 iso_country
= bcm43xx_locale_iso(bcm
->sprom
.locale
);
1117 for (i
= 0, channel
= 0; channel
< 201; channel
++) {
1119 chan
->freq
= bcm43xx_channel_to_freq(bcm
, channel
);
1120 chan
->channel
= channel
;
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 */)
1135 else if (0 /*TODO: Indoor use only */)
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
;
1159 switch (bcm
->current_core
->phy
->type
) {
1160 case BCM43xx_PHYTYPE_A
:
1162 buffer
[0] = 0xCC010200;
1164 case BCM43xx_PHYTYPE_B
:
1165 case BCM43xx_PHYTYPE_G
:
1167 buffer
[0] = 0x6E840B00;
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)
1196 for (i
= 0x00; i
< 0x0A; i
++) {
1197 value
= bcm43xx_read16(bcm
, 0x050E);
1198 if ((value
& 0x0400) != 0)
1202 for (i
= 0x00; i
< 0x0A; i
++) {
1203 value
= bcm43xx_read16(bcm
, 0x0690);
1204 if ((value
& 0x0100) == 0)
1210 static void key_write(struct bcm43xx_private
*bcm
,
1211 u8 index
, u8 algorithm
, const u16
*key
)
1213 unsigned int i
, basic_wep
= 0;
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))
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
);
1236 bcm43xx_shm_write16(bcm
, BCM43xx_SHM_SHARED
,
1237 offset
+ (i
* 2) + 4 * BCM43xx_SEC_KEYSIZE
,
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 */
1250 if (bcm
->current_core
->rev
>= 5) {
1251 bcm43xx_shm_write32(bcm
,
1254 cpu_to_be32(*addr
));
1255 bcm43xx_shm_write16(bcm
,
1258 cpu_to_be16(*((u16
*)(addr
+ 1))));
1261 TODO(); /* Put them in the macaddress filter */
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
,
1275 u8 key
[BCM43xx_SEC_KEYSIZE
] = { 0 };
1277 if (index
>= ARRAY_SIZE(bcm
->key
))
1279 if (key_len
> ARRAY_SIZE(key
))
1281 if (algorithm
< 1 || algorithm
> 5)
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
;
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;
1299 if (bcm
->current_core
->rev
< 5)
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
,
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
1323 int _get_current_core(struct bcm43xx_private
*bcm
, int *core
)
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");
1332 *core
= (*core
- 0x18000000) / 0x1000;
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
)
1344 int current_core
= -1;
1348 err
= _get_current_core(bcm
, ¤t_core
);
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
)) {
1358 "unable to switch to core %u, retried %i times\n",
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");
1368 _get_current_core(bcm
, ¤t_core
);
1369 #ifdef CONFIG_BCM947XX
1370 if (bcm
->pci_dev
->bus
->number
== 0)
1371 bcm
->current_core_offset
= 0x1000 * core
;
1373 bcm
->current_core_offset
= 0;
1382 int bcm43xx_switch_core(struct bcm43xx_private
*bcm
, struct bcm43xx_coreinfo
*new_core
)
1389 if (!(new_core
->flags
& BCM43xx_COREFLAG_AVAILABLE
))
1391 if (bcm
->current_core
== new_core
)
1393 err
= _switch_core(bcm
, new_core
->index
);
1395 bcm
->current_core
= new_core
;
1400 static inline int bcm43xx_core_enabled(struct bcm43xx_private
*bcm
)
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
)
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
)
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
) {
1439 printk(KERN_ERR PFX
"Error: core_disable() REJECT timeout!\n");
1443 for (i
= 0; i
< 1000; i
++) {
1444 sbtmstatehigh
= bcm43xx_read32(bcm
, BCM43xx_CIR_SBTMSTATEHIGH
);
1445 if (!(sbtmstatehigh
& BCM43xx_SBTMSTATEHIGH_BUSY
)) {
1452 printk(KERN_ERR PFX
"Error: core_disable() BUSY timeout!\n");
1456 sbtmstatelow
= BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK
|
1457 BCM43xx_SBTMSTATELOW_REJECT
|
1458 BCM43xx_SBTMSTATELOW_RESET
|
1459 BCM43xx_SBTMSTATELOW_CLOCK
|
1461 bcm43xx_write32(bcm
, BCM43xx_CIR_SBTMSTATELOW
, sbtmstatelow
);
1465 sbtmstatelow
= BCM43xx_SBTMSTATELOW_RESET
|
1466 BCM43xx_SBTMSTATELOW_REJECT
|
1468 bcm43xx_write32(bcm
, BCM43xx_CIR_SBTMSTATELOW
, sbtmstatelow
);
1471 bcm
->current_core
->flags
&= ~ BCM43xx_COREFLAG_ENABLED
;
1475 /* enable (reset) current core */
1476 static int bcm43xx_core_enable(struct bcm43xx_private
*bcm
, u32 core_flags
)
1483 err
= bcm43xx_core_disable(bcm
, core_flags
);
1487 sbtmstatelow
= BCM43xx_SBTMSTATELOW_CLOCK
|
1488 BCM43xx_SBTMSTATELOW_RESET
|
1489 BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK
|
1491 bcm43xx_write32(bcm
, BCM43xx_CIR_SBTMSTATELOW
, sbtmstatelow
);
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
|
1509 bcm43xx_write32(bcm
, BCM43xx_CIR_SBTMSTATELOW
, sbtmstatelow
);
1512 sbtmstatelow
= BCM43xx_SBTMSTATELOW_CLOCK
| core_flags
;
1513 bcm43xx_write32(bcm
, BCM43xx_CIR_SBTMSTATELOW
, sbtmstatelow
);
1516 bcm
->current_core
->flags
|= BCM43xx_COREFLAG_ENABLED
;
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
);
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));
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
)
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
)
1570 struct bcm43xx_coreinfo
*old_core
;
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
);
1580 sbtmstatelow
= bcm43xx_read32(bcm
, BCM43xx_CIR_SBTMSTATELOW
);
1581 sbtmstatelow
&= ~0xa0000;
1582 sbtmstatelow
|= 0x80000;
1583 bcm43xx_write32(bcm
, BCM43xx_CIR_SBTMSTATELOW
, sbtmstatelow
);
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
);
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
);
1602 static inline void handle_irq_transmit_status(struct bcm43xx_private
*bcm
)
1606 struct bcm43xx_xmitstatus stat
;
1608 assert(bcm
->current_core
->id
== BCM43xx_COREID_80211
);
1609 assert(bcm
->current_core
->rev
>= 5);
1612 v0
= bcm43xx_read32(bcm
, BCM43xx_MMIO_XMITSTAT_0
);
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
)
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
1635 bcm43xx_pio_handle_xmitstatus(bcm
, &stat
);
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
)
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
;
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)
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. */
1704 for (i
= 0; i
< 8; i
++) {
1705 for (j
= 0; j
< 4; j
++)
1706 average
+= bcm
->noisecalc
.samples
[i
][j
];
1712 tmp
= bcm43xx_shm_read16(bcm
, BCM43xx_SHM_SHARED
, 0x40C);
1713 tmp
= (tmp
/ 128) & 0x1F;
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;
1730 bcm
->stats
.link_quality
= 3;
1731 // dprintk(KERN_INFO PFX "Link Quality: %u (avg was %d)\n", bcm->stats.link_quality, average);
1733 bcm
->noisecalc
.calculation_running
= 0;
1737 bcm43xx_generate_noise_sample(bcm
);
1741 void handle_irq_ps(struct bcm43xx_private
*bcm
)
1743 if (bcm
->ieee
->iw_mode
== IW_MODE_MASTER
) {
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?
1755 void handle_irq_reg124(struct bcm43xx_private
*bcm
)
1757 if (!bcm
->reg124_set_0x4
)
1759 bcm43xx_write32(bcm
, BCM43xx_MMIO_STATUS2_BITFIELD
,
1760 bcm43xx_read32(bcm
, BCM43xx_MMIO_STATUS2_BITFIELD
)
1762 //FIXME: reset reg124_set_0x4 to false?
1766 void handle_irq_pmq(struct bcm43xx_private
*bcm
)
1773 tmp
= bcm43xx_read32(bcm
, BCM43xx_MMIO_PS_STATUS
);
1774 if (!(tmp
& 0x00000008))
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
)
1788 //FIXME: assumption: The chip sets the timestamp
1790 bcm43xx_ram_write(bcm
, ram_offset
++, value
);
1791 bcm43xx_ram_write(bcm
, ram_offset
++, value
);
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
);
1807 /* FH Parameter Set */
1810 /* DS Parameter Set */
1813 /* CF Parameter Set */
1819 bcm43xx_shm_write16(bcm
, BCM43xx_SHM_SHARED
, shm_size_offset
, size
);
1823 void handle_irq_beacon(struct bcm43xx_private
*bcm
)
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
;
1837 if (!(status
& 0x1)) {
1838 bcm43xx_generate_beacon_template(bcm
, 0x68, 0x18);
1840 bcm43xx_write32(bcm
, BCM43xx_MMIO_STATUS2_BITFIELD
, status
);
1842 if (!(status
& 0x2)) {
1843 bcm43xx_generate_beacon_template(bcm
, 0x468, 0x1A);
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) \
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", \
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)); \
1865 /* Interrupt handler bottom-half */
1866 static void bcm43xx_interrupt_tasklet(struct bcm43xx_private
*bcm
)
1871 unsigned long flags
;
1873 #ifdef CONFIG_BCM43XX_DEBUG
1874 u32 _handled
= 0x00000000;
1875 # define bcmirq_handled(irq) do { _handled |= (irq); } while (0)
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
) {
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
) {
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
) {
1933 bcm43xx_pio_rx(bcm
->current_core
->pio
->queue0
);
1935 bcm43xx_dma_rx(bcm
->current_core
->dma
->rx_ring0
);
1938 if (dma_reason
[3] & BCM43xx_DMAIRQ_RX_DONE
) {
1939 if (likely(bcm
->current_core
->rev
< 5)) {
1941 bcm43xx_pio_rx(bcm
->current_core
->pio
->queue3
);
1943 bcm43xx_dma_rx(bcm
->current_core
->dma
->rx_ring1
);
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
);
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]);
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
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
)
1991 bcm
->dma_reason
[1] = bcm43xx_read32(bcm
, BCM43xx_MMIO_DMA2_REASON
)
1993 bcm
->dma_reason
[2] = bcm43xx_read32(bcm
, BCM43xx_MMIO_DMA3_REASON
)
1995 bcm
->dma_reason
[3] = bcm43xx_read32(bcm
, BCM43xx_MMIO_DMA4_REASON
)
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) \
2005 if (bcm43xx_read16(bcm, BASE + BCM43xx_PIO_RXCTL) & BCM43xx_PIO_RXCTL_DATAAVAILABLE) \
2006 bcm->dma_reason[QNUM] |= 0x00010000; \
2008 bcm->dma_reason[QNUM] &= ~0x00010000; \
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
,
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
;
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
);
2049 mask
= bcm43xx_read32(bcm
, BCM43xx_MMIO_GEN_IRQ_MASK
);
2050 if (!(reason
& mask
)) {
2051 spin_unlock(&bcm
->lock
);
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
);
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
);
2075 release_firmware(bcm
->pcm
);
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
;
2089 char buf
[22 + sizeof(modparam_fwpostfix
) - 1] = { 0 };
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
);
2098 "Error: Microcode \"%s\" not available or load failed.\n",
2105 snprintf(buf
, ARRAY_SIZE(buf
),
2106 "bcm43xx_pcm%d%s.fw",
2108 modparam_fwpostfix
);
2109 err
= request_firmware(&bcm
->pcm
, buf
, &bcm
->pci_dev
->dev
);
2112 "Error: PCM \"%s\" not available or load failed.\n",
2118 if (!bcm
->initvals0
) {
2119 if (rev
== 2 || rev
== 4) {
2120 switch (phy
->type
) {
2121 case BCM43xx_PHYTYPE_A
:
2124 case BCM43xx_PHYTYPE_B
:
2125 case BCM43xx_PHYTYPE_G
:
2132 } else if (rev
>= 5) {
2133 switch (phy
->type
) {
2134 case BCM43xx_PHYTYPE_A
:
2137 case BCM43xx_PHYTYPE_B
:
2138 case BCM43xx_PHYTYPE_G
:
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
);
2152 "Error: InitVals \"%s\" not available or load failed.\n",
2156 if (bcm
->initvals0
->size
% sizeof(struct bcm43xx_initval
)) {
2157 printk(KERN_ERR PFX
"InitVals fileformat error.\n");
2162 if (!bcm
->initvals1
) {
2166 switch (phy
->type
) {
2167 case BCM43xx_PHYTYPE_A
:
2168 sbtmstatehigh
= bcm43xx_read32(bcm
, BCM43xx_CIR_SBTMSTATEHIGH
);
2169 if (sbtmstatehigh
& 0x00010000)
2174 case BCM43xx_PHYTYPE_B
:
2175 case BCM43xx_PHYTYPE_G
:
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
);
2187 "Error: InitVals \"%s\" not available or load failed.\n",
2191 if (bcm
->initvals1
->size
% sizeof(struct bcm43xx_initval
)) {
2192 printk(KERN_ERR PFX
"InitVals fileformat error.\n");
2201 bcm43xx_release_firmware(bcm
, 1);
2204 printk(KERN_ERR PFX
"Error: No InitVals available!\n");
2209 static void bcm43xx_upload_microcode(struct bcm43xx_private
*bcm
)
2212 unsigned int i
, len
;
2214 #ifdef DEBUG_ENABLE_UCODE_MMIO_PRINT
2215 bcm43xx_mmioprint_enable(bcm
);
2217 bcm43xx_mmioprint_disable(bcm
);
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
]));
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
]));
2242 #ifdef DEBUG_ENABLE_UCODE_MMIO_PRINT
2243 bcm43xx_mmioprint_disable(bcm
);
2245 bcm43xx_mmioprint_enable(bcm
);
2249 static int bcm43xx_write_initvals(struct bcm43xx_private
*bcm
,
2250 const struct bcm43xx_initval
*data
,
2251 const unsigned int len
)
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))
2265 if (unlikely(value
& 0xFFFF0000))
2267 bcm43xx_write16(bcm
, offset
, (u16
)value
);
2268 } else if (size
== 4) {
2269 bcm43xx_write32(bcm
, offset
, value
);
2277 printk(KERN_ERR PFX
"InitVals (bcm43xx_initvalXX.fw) file-format error. "
2278 "Please fix your bcm43xx firmware files.\n");
2282 static int bcm43xx_upload_initvals(struct bcm43xx_private
*bcm
)
2286 #ifdef DEBUG_ENABLE_UCODE_MMIO_PRINT
2287 bcm43xx_mmioprint_enable(bcm
);
2289 bcm43xx_mmioprint_disable(bcm
);
2292 err
= bcm43xx_write_initvals(bcm
, (struct bcm43xx_initval
*)bcm
->initvals0
->data
,
2293 bcm
->initvals0
->size
/ sizeof(struct bcm43xx_initval
));
2296 if (bcm
->initvals1
) {
2297 err
= bcm43xx_write_initvals(bcm
, (struct bcm43xx_initval
*)bcm
->initvals1
->data
,
2298 bcm
->initvals1
->size
/ sizeof(struct bcm43xx_initval
));
2304 #ifdef DEBUG_ENABLE_UCODE_MMIO_PRINT
2305 bcm43xx_mmioprint_disable(bcm
);
2307 bcm43xx_mmioprint_enable(bcm
);
2312 static int bcm43xx_initialize_irq(struct bcm43xx_private
*bcm
)
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
);
2329 res
= request_irq(bcm
->irq
, bcm43xx_interrupt_handler
,
2330 SA_SHIRQ
, KBUILD_MODNAME
, bcm
);
2332 printk(KERN_ERR PFX
"Cannot register IRQ%d\n", bcm
->irq
);
2335 bcm43xx_write32(bcm
, BCM43xx_MMIO_GEN_IRQ_REASON
, 0xffffffff);
2336 bcm43xx_write32(bcm
, BCM43xx_MMIO_STATUS_BITFIELD
, 0x00020402);
2339 data
= bcm43xx_read32(bcm
, BCM43xx_MMIO_GEN_IRQ_REASON
);
2340 if (data
== BCM43xx_IRQ_READY
)
2343 if (i
>= BCM43xx_IRQWAIT_MAX_RETRIES
) {
2344 printk(KERN_ERR PFX
"Card IRQ register not responding. "
2346 free_irq(bcm
->irq
, bcm
);
2352 bcm43xx_read32(bcm
, BCM43xx_MMIO_GEN_IRQ_REASON
);
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
)
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");
2376 } else if (err
!= 0)
2378 } else if (err
!= 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
;
2393 value
= bcm43xx_read32(bcm
, BCM43xx_MMIO_STATUS_BITFIELD
);
2395 bcm43xx_write32(bcm
, BCM43xx_MMIO_STATUS_BITFIELD
, value
);
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
);
2410 if (bcm
->current_core
->rev
>= 2){
2414 if (bcm
->chip_id
== 0x4301) {
2418 if (bcm
->sprom
.boardflags
& BCM43xx_BFL_PACTRL
) {
2423 bcm43xx_write32(bcm
, BCM43xx_GPIO_CONTROL
,
2424 (bcm43xx_read32(bcm
, BCM43xx_GPIO_CONTROL
) & mask
) | value
);
2426 err
= bcm43xx_switch_core(bcm
, old_core
);
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
;
2438 old_core
= bcm
->current_core
;
2439 err
= switch_to_gpio_core(bcm
);
2442 bcm43xx_write32(bcm
, BCM43xx_GPIO_CONTROL
, 0x00000000);
2443 err
= bcm43xx_switch_core(bcm
, old_core
);
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
)
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
) {
2481 printkl(KERN_ERR PFX
"Failed to suspend mac!\n");
2484 void bcm43xx_set_iwmode(struct bcm43xx_private
*bcm
,
2487 unsigned long flags
;
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
;
2496 bcm
->net_dev
->type
= ARPHRD_ETHER
;
2498 if (!bcm
->initialized
)
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
;
2510 case IW_MODE_MONITOR
:
2511 status
|= (BCM43xx_SBF_MODE_PROMISC
|
2512 BCM43xx_SBF_MODE_MONITOR
);
2515 status
&= ~BCM43xx_SBF_MODE_NOTADHOC
;
2517 case IW_MODE_MASTER
:
2518 case IW_MODE_SECOND
:
2519 case IW_MODE_REPEAT
:
2520 /* TODO: No AP/Repeater mode for now :-/ */
2524 /* nothing to be done here... */
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
)
2551 int iw_mode
= bcm
->ieee
->iw_mode
;
2556 bcm43xx_write32(bcm
, BCM43xx_MMIO_STATUS_BITFIELD
,
2557 BCM43xx_SBF_CORE_READY
2560 err
= bcm43xx_request_firmware(bcm
);
2563 bcm43xx_upload_microcode(bcm
);
2565 err
= bcm43xx_initialize_irq(bcm
);
2567 goto err_release_fw
;
2569 err
= bcm43xx_gpio_init(bcm
);
2573 err
= bcm43xx_upload_initvals(bcm
);
2575 goto err_gpio_cleanup
;
2576 bcm43xx_radio_turn_on(bcm
);
2578 if (modparam_noleds
)
2579 bcm43xx_leds_turn_off(bcm
);
2581 bcm43xx_leds_update(bcm
, 0);
2583 bcm43xx_write16(bcm
, 0x03E6, 0x0000);
2584 err
= bcm43xx_phy_init(bcm
);
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);
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);
2642 bcm43xx_write16(bcm
, 0x0612, 0x0032);
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);
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
));
2668 dprintk(KERN_INFO PFX
"Chip initialized\n");
2673 bcm43xx_radio_turn_off(bcm
);
2675 bcm43xx_gpio_cleanup(bcm
);
2677 free_irq(bcm
->irq
, bcm
);
2679 bcm43xx_release_firmware(bcm
, 1);
2683 /* Validate chip access
2684 * http://bcm-specs.sipsolutions.net/ValidateChipAccess */
2685 static int bcm43xx_validate_chip(struct bcm43xx_private
*bcm
)
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");
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");
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");
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");
2723 static int bcm43xx_probe_cores(struct bcm43xx_private
*bcm
)
2727 u32 core_vendor
, core_id
, core_rev
;
2728 u32 sb_id_hi
, chip_id_32
= 0;
2729 u16 pci_device
, chip_id_16
;
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
);
2745 err
= _switch_core(bcm
, 0);
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
);
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;
2784 printk(KERN_ERR PFX
"Could not determine Chip ID\n");
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;
2794 switch (chip_id_16
) {
2817 /* SOL if we get here */
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
)
2839 for ( ; current_core
< core_count
; current_core
++) {
2840 struct bcm43xx_coreinfo
*core
;
2842 err
= _switch_core(bcm
, current_core
);
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" );
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");
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");
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");
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");
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
))
2896 printk(KERN_WARNING PFX
"More than %d cores of type 802.11 found.\n",
2897 BCM43xx_MAX_80211_CORES
);
2901 /* More than one 80211 core is only supported
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");
2921 printk(KERN_ERR PFX
"Error: Unsupported 80211 core revision %u\n",
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
];
2945 case BCM43xx_COREID_CHIPCOMMON
:
2946 printk(KERN_WARNING PFX
"Multiple CHIPCOMMON cores found.\n");
2949 printk(KERN_WARNING PFX
"Unknown core found (ID 0x%x)\n", core_id
);
2952 core
->flags
|= BCM43xx_COREFLAG_AVAILABLE
;
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");
2965 err
= bcm43xx_switch_core(bcm
, &bcm
->core_80211
[0]);
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
) {
2979 random_ether_addr(bssid
);
2981 case IW_MODE_MASTER
:
2983 case IW_MODE_REPEAT
:
2984 case IW_MODE_SECOND
:
2985 case IW_MODE_MONITOR
:
2986 memcpy(bssid
, mac
, ETH_ALEN
);
2993 static void bcm43xx_rate_memory_write(struct bcm43xx_private
*bcm
,
3001 offset
+= (bcm43xx_plcp_get_ratecode_ofdm(rate
) & 0x000F) * 2;
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);
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
)
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;
3061 bcm43xx_write32(bcm
, BCM43xx_CIR_SBIMCONFIGLOW
, sbimconfiglow
);
3064 bcm43xx_phy_calibrate(bcm
);
3065 err
= bcm43xx_chip_init(bcm
);
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);
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
);
3128 goto err_chip_cleanup
;
3130 err
= bcm43xx_pio_init(bcm
);
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
;
3146 bcm43xx_chip_cleanup(bcm
);
3150 static int bcm43xx_chipset_attach(struct bcm43xx_private
*bcm
)
3155 err
= bcm43xx_pctl_set_crystal(bcm
, 1);
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
);
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
,
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
)
3182 struct bcm43xx_coreinfo
*old_core
;
3184 old_core
= bcm
->current_core
;
3185 err
= bcm43xx_switch_core(bcm
, &bcm
->core_pci
);
3189 bcm43xx_pcicore_broadcast_value(bcm
, 0xfd8, 0x00000000);
3191 bcm43xx_switch_core(bcm
, old_core
);
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
,
3203 u32 backplane_flag_nr
;
3205 struct bcm43xx_coreinfo
*old_core
;
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
);
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
);
3221 err
= bcm43xx_pci_read_config32(bcm
, BCM43xx_PCICFG_ICR
, &value
);
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
);
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
);
3250 err
= bcm43xx_switch_core(bcm
, old_core
);
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
,
3404 bcm43xx_clear_keys(bcm
);
3407 /* This is the opposite of bcm43xx_init_board() */
3408 static void bcm43xx_free_board(struct bcm43xx_private
*bcm
)
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
))
3423 if (!(bcm
->core_80211
[i
].flags
& BCM43xx_COREFLAG_INITIALIZED
))
3426 err
= bcm43xx_switch_core(bcm
, &bcm
->core_80211
[i
]);
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
)
3441 int num_80211_cores
;
3443 unsigned long flags
;
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);
3455 err
= bcm43xx_pctl_init(bcm
);
3457 goto err_crystal_off
;
3458 err
= bcm43xx_pctl_set_clock(bcm
, BCM43xx_PCTL_CLK_FAST
);
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
);
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
;
3482 bcm43xx_wireless_core_reset(bcm
, connect_phy
);
3486 bcm43xx_wireless_core_mark_inactive(bcm
, &bcm
->core_80211
[0]);
3488 err
= bcm43xx_wireless_core_init(bcm
);
3490 goto err_80211_unwind
;
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
);
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
))
3532 bcm43xx_interrupt_disable(bcm
, BCM43xx_IRQ_ALL
);
3533 bcm43xx_wireless_core_cleanup(bcm
);
3536 bcm43xx_pctl_set_crystal(bcm
, 0);
3540 static void bcm43xx_detach_board(struct bcm43xx_private
*bcm
)
3542 struct pci_dev
*pci_dev
= bcm
->pci_dev
;
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
)
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
);
3579 case BCM43xx_PHYTYPE_A
:
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
;
3592 case BCM43xx_PHYTYPE_B
:
3593 if (phy_rev
!= 2 && phy_rev
!= 4 && phy_rev
!= 6 && phy_rev
!= 7)
3595 bcm
->ieee
->modulation
= IEEE80211_CCK_MODULATION
;
3596 bcm
->ieee
->mode
= IEEE_B
;
3597 bcm
->ieee
->freq_band
= IEEE80211_24GHZ_BAND
;
3599 case BCM43xx_PHYTYPE_G
:
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
;
3608 printk(KERN_ERR PFX
"Error: Unknown PHY Type %x\n",
3613 printk(KERN_WARNING PFX
"Invalid PHY Revision %x\n",
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
,
3625 bcm
->current_core
->phy
->_lo_pairs
= p
;
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
;
3637 void __iomem
*ioaddr
;
3638 unsigned long mmio_start
, mmio_end
, mmio_flags
, mmio_len
;
3639 int num_80211_cores
;
3642 err
= pci_enable_device(pci_dev
);
3644 printk(KERN_ERR PFX
"unable to wake up pci device (%i)\n", err
);
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
)) {
3657 "%s, region #0 not an MMIO resource, aborting\n",
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
) {
3666 "%s: invalid PCI mem region size(s), aborting\n",
3669 goto err_pci_disable
;
3673 err
= pci_request_regions(pci_dev
, KBUILD_MODNAME
);
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
);
3686 printk(KERN_ERR PFX
"%s: cannot remap MMIO, aborting\n",
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
,
3700 bcm43xx_pci_read_config16(bcm
, PCI_REVISION_ID
,
3701 &bcm
->board_revision
);
3703 err
= bcm43xx_chipset_attach(bcm
);
3706 err
= bcm43xx_pctl_init(bcm
);
3708 goto err_chipset_detach
;
3709 err
= bcm43xx_probe_cores(bcm
);
3711 goto err_chipset_detach
;
3713 num_80211_cores
= bcm43xx_num_80211_cores(bcm
);
3715 /* Attach all IO cores to the backplane. */
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
);
3722 printk(KERN_ERR PFX
"Backplane->PCI connection failed!\n");
3723 goto err_chipset_detach
;
3726 err
= bcm43xx_read_sprom(bcm
);
3728 goto err_chipset_detach
;
3729 err
= bcm43xx_leds_init(bcm
);
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
);
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
);
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);
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
);
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
);
3786 bcm43xx_chipset_detach(bcm
);
3788 iounmap(bcm
->mmio_addr
);
3790 pci_release_regions(pci_dev
);
3792 pci_disable_device(pci_dev
);
3797 s8
bcm43xx_rssi_postprocess(struct bcm43xx_private
*bcm
, u8 in_rssi
,
3798 int ofdm
, int adjust_2053
, int adjust_2050
)
3802 switch (bcm
->current_core
->radio
->version
) {
3815 if (bcm
->sprom
.boardflags
& BCM43xx_BFL_RSSI
) {
3818 tmp
= bcm
->current_core
->radio
->nrssi_lt
[in_rssi
];
3830 if (bcm
->current_core
->phy
->type
== BCM43xx_PHYTYPE_G
&&
3837 tmp
= in_rssi
- 256;
3856 s8
bcm43xx_rssinoise_postprocess(struct bcm43xx_private
*bcm
, u8 in_rssi
)
3860 if (bcm
->current_core
->phy
->type
== BCM43xx_PHYTYPE_A
) {
3861 //TODO: Incomplete specs.
3864 ret
= bcm43xx_rssi_postprocess(bcm
, in_rssi
, 0, 1, 1);
3870 int bcm43xx_rx_packet(struct bcm43xx_private
*bcm
,
3871 struct sk_buff
*skb
,
3872 struct ieee80211_rx_stats
*stats
)
3876 err
= ieee80211_rx(bcm
->ieee
, skb
, stats
);
3877 if (unlikely(err
== 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
;
3890 int is_packet_for_us
= 0;
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
));
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
;
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
) {
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;
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;
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");
3971 memmove(skb
->data
+ 4, skb
->data
, 24);
3973 skb_trim(skb
, skb
->len
- 4);
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
);
3983 case IEEE80211_FTYPE_DATA
:
3984 if (is_packet_for_us
)
3985 err
= bcm43xx_rx_packet(bcm
, skb
, &stats
);
3987 case IEEE80211_FTYPE_CTL
:
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
)
4004 err
= bcm43xx_pio_transfer_txb(bcm
, txb
);
4006 err
= bcm43xx_dma_tx(bcm
, txb
);
4011 static void bcm43xx_ieee80211_set_chan(struct net_device
*net_dev
,
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
;
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 };
4069 for (keyidx
= 0; keyidx
<WEP_KEYS
; keyidx
++) {
4070 if (!(sec
->flags
& (1<<keyidx
)))
4072 switch (sec
->encode_alg
[keyidx
]) {
4073 case SEC_ALG_NONE
: algorithm
= BCM43xx_SEC_ALGO_NONE
; break;
4075 algorithm
= BCM43xx_SEC_ALGO_WEP
;
4076 if (secinfo
->key_sizes
[keyidx
] == 13)
4077 algorithm
= BCM43xx_SEC_ALGO_WEP104
;
4081 algorithm
= BCM43xx_SEC_ALGO_TKIP
;
4085 algorithm
= BCM43xx_SEC_ALGO_AES
;
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
;
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
,
4106 struct bcm43xx_private
*bcm
= bcm43xx_priv(net_dev
);
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
);
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
);
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);
4173 bcm43xx_mmioprint_initial(bcm
, 0);
4175 #ifdef DEBUG_ENABLE_PCILOG
4176 bcm43xx_pciprint_initial(bcm
, 1);
4178 bcm43xx_pciprint_initial(bcm
, 0);
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
);
4194 if (pci_set_dma_mask(pci_dev
, DMA_30BIT_MASK
) == 0) {
4197 printk(KERN_WARNING PFX
"DMA not supported. Falling back to PIO.\n");
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
;
4222 #ifdef CONFIG_BCM947XX
4223 if ((pdev
->bus
->number
== 0) && (pdev
->device
!= 0x0800))
4227 #ifdef DEBUG_SINGLE_DEVICE_ONLY
4228 if (strcmp(pci_name(pdev
), DEBUG_SINGLE_DEVICE_ONLY
))
4232 net_dev
= alloc_ieee80211softmac(sizeof(*bcm
));
4235 "could not allocate ieee80211 device %s\n",
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
;
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");
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
);
4269 goto err_destroy_wq
;
4271 err
= register_netdev(net_dev
);
4273 printk(KERN_ERR PFX
"Cannot register net device, "
4276 goto err_detach_board
;
4279 bcm43xx_debugfs_add_device(bcm
);
4286 bcm43xx_detach_board(bcm
);
4288 destroy_workqueue(wq
);
4290 free_ieee80211softmac(net_dev
);
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
;
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
);
4331 if (was_initialized
) {
4332 err
= bcm43xx_init_board(bcm
);
4336 netif_wake_queue(bcm
->net_dev
);
4337 printk(KERN_INFO PFX
"Controller restarted\n");
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
);
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");
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");
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
);
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
);
4414 printk(KERN_ERR PFX
"Resume failed!\n");
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");
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
),
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: */