aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ath/ar9170/usb.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c23
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_def.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c202
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c16
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h3
-rw-r--r--drivers/net/wireless/b43/Kconfig21
-rw-r--r--drivers/net/wireless/b43/Makefile1
-rw-r--r--drivers/net/wireless/b43/b43.h23
-rw-r--r--drivers/net/wireless/b43/debugfs.c1
-rw-r--r--drivers/net/wireless/b43/debugfs.h1
-rw-r--r--drivers/net/wireless/b43/dma.c4
-rw-r--r--drivers/net/wireless/b43/leds.c266
-rw-r--r--drivers/net/wireless/b43/leds.h33
-rw-r--r--drivers/net/wireless/b43/main.c224
-rw-r--r--drivers/net/wireless/b43/phy_lp.c12
-rw-r--r--drivers/net/wireless/b43/pio.c2
-rw-r--r--drivers/net/wireless/b43/rfkill.c2
-rw-r--r--drivers/net/wireless/b43/sdio.c202
-rw-r--r--drivers/net/wireless/b43/sdio.h45
-rw-r--r--drivers/net/wireless/b43/xmit.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c9
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h2
-rw-r--r--drivers/net/wireless/wl12xx/Kconfig2
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c2
31 files changed, 832 insertions, 304 deletions
diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c
index e0138ac8bf50..e974e5829e1a 100644
--- a/drivers/net/wireless/ath/ar9170/usb.c
+++ b/drivers/net/wireless/ath/ar9170/usb.c
@@ -64,6 +64,8 @@ static struct usb_device_id ar9170_usb_ids[] = {
64 { USB_DEVICE(0x0cf3, 0x9170) }, 64 { USB_DEVICE(0x0cf3, 0x9170) },
65 /* Atheros TG121N */ 65 /* Atheros TG121N */
66 { USB_DEVICE(0x0cf3, 0x1001) }, 66 { USB_DEVICE(0x0cf3, 0x1001) },
67 /* TP-Link TL-WN821N v2 */
68 { USB_DEVICE(0x0cf3, 0x1002) },
67 /* Cace Airpcap NX */ 69 /* Cace Airpcap NX */
68 { USB_DEVICE(0xcace, 0x0300) }, 70 { USB_DEVICE(0xcace, 0x0300) },
69 /* D-Link DWA 160A */ 71 /* D-Link DWA 160A */
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 3234995e8881..0ad6d0b76e9e 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -609,14 +609,24 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
609 AR_PHY_CH1_EXT_CCA, 609 AR_PHY_CH1_EXT_CCA,
610 AR_PHY_CH2_EXT_CCA 610 AR_PHY_CH2_EXT_CCA
611 }; 611 };
612 u8 chainmask; 612 u8 chainmask, rx_chain_status;
613 613
614 rx_chain_status = REG_READ(ah, AR_PHY_RX_CHAINMASK);
614 if (AR_SREV_9285(ah)) 615 if (AR_SREV_9285(ah))
615 chainmask = 0x9; 616 chainmask = 0x9;
616 else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) 617 else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) {
617 chainmask = 0x1B; 618 if ((rx_chain_status & 0x2) || (rx_chain_status & 0x4))
618 else 619 chainmask = 0x1B;
619 chainmask = 0x3F; 620 else
621 chainmask = 0x09;
622 } else {
623 if (rx_chain_status & 0x4)
624 chainmask = 0x3F;
625 else if (rx_chain_status & 0x2)
626 chainmask = 0x1B;
627 else
628 chainmask = 0x09;
629 }
620 630
621 h = ah->nfCalHist; 631 h = ah->nfCalHist;
622 632
@@ -697,6 +707,8 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah)
697 noise_floor = AR_PHY_CCA_MAX_AR9280_GOOD_VALUE; 707 noise_floor = AR_PHY_CCA_MAX_AR9280_GOOD_VALUE;
698 else if (AR_SREV_9285(ah)) 708 else if (AR_SREV_9285(ah))
699 noise_floor = AR_PHY_CCA_MAX_AR9285_GOOD_VALUE; 709 noise_floor = AR_PHY_CCA_MAX_AR9285_GOOD_VALUE;
710 else if (AR_SREV_9287(ah))
711 noise_floor = AR_PHY_CCA_MAX_AR9287_GOOD_VALUE;
700 else 712 else
701 noise_floor = AR_PHY_CCA_MAX_AR5416_GOOD_VALUE; 713 noise_floor = AR_PHY_CCA_MAX_AR5416_GOOD_VALUE;
702 714
@@ -924,6 +936,7 @@ static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah, bool is_reset)
924 regVal |= (1 << (19 + i)); 936 regVal |= (1 << (19 + i));
925 REG_WRITE(ah, 0x7834, regVal); 937 REG_WRITE(ah, 0x7834, regVal);
926 udelay(1); 938 udelay(1);
939 regVal = REG_READ(ah, 0x7834);
927 regVal &= (~(0x1 << (19 + i))); 940 regVal &= (~(0x1 << (19 + i)));
928 reg_field = MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9); 941 reg_field = MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9);
929 regVal |= (reg_field << (19 + i)); 942 regVal |= (reg_field << (19 + i));
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
index 019bcbba40ed..9028ab193e42 100644
--- a/drivers/net/wireless/ath/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -28,6 +28,7 @@ extern const struct ath9k_percal_data adc_init_dc_cal;
28#define AR_PHY_CCA_MAX_AR5416_GOOD_VALUE -85 28#define AR_PHY_CCA_MAX_AR5416_GOOD_VALUE -85
29#define AR_PHY_CCA_MAX_AR9280_GOOD_VALUE -112 29#define AR_PHY_CCA_MAX_AR9280_GOOD_VALUE -112
30#define AR_PHY_CCA_MAX_AR9285_GOOD_VALUE -118 30#define AR_PHY_CCA_MAX_AR9285_GOOD_VALUE -118
31#define AR_PHY_CCA_MAX_AR9287_GOOD_VALUE -118
31#define AR_PHY_CCA_MAX_HIGH_VALUE -62 32#define AR_PHY_CCA_MAX_HIGH_VALUE -62
32#define AR_PHY_CCA_MIN_BAD_VALUE -140 33#define AR_PHY_CCA_MIN_BAD_VALUE -140
33#define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT 3 34#define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT 3
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index ae7fb5dcb266..4071fc91da0a 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -509,6 +509,8 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
509 REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 509 REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
510 eep->baseEepHeader.dacLpMode); 510 eep->baseEepHeader.dacLpMode);
511 511
512 udelay(100);
513
512 REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP, 514 REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP,
513 pModal->miscBits >> 2); 515 pModal->miscBits >> 2);
514 516
@@ -902,7 +904,7 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
902 u16 powerLimit) 904 u16 powerLimit)
903{ 905{
904#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */ 906#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
905#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */ 907#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 9 /* 10*log10(3)*2 */
906 908
907 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 909 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
908 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def; 910 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index b6c6cca07812..ca7694caf364 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -842,7 +842,7 @@ static void ath9k_hw_init_mode_regs(struct ath_hw *ah)
842 842
843static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah) 843static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah)
844{ 844{
845 if (AR_SREV_9287_11(ah)) 845 if (AR_SREV_9287_11_OR_LATER(ah))
846 INIT_INI_ARRAY(&ah->iniModesRxGain, 846 INIT_INI_ARRAY(&ah->iniModesRxGain,
847 ar9287Modes_rx_gain_9287_1_1, 847 ar9287Modes_rx_gain_9287_1_1,
848 ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1), 6); 848 ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1), 6);
@@ -853,7 +853,7 @@ static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah)
853 else if (AR_SREV_9280_20(ah)) 853 else if (AR_SREV_9280_20(ah))
854 ath9k_hw_init_rxgain_ini(ah); 854 ath9k_hw_init_rxgain_ini(ah);
855 855
856 if (AR_SREV_9287_11(ah)) { 856 if (AR_SREV_9287_11_OR_LATER(ah)) {
857 INIT_INI_ARRAY(&ah->iniModesTxGain, 857 INIT_INI_ARRAY(&ah->iniModesTxGain,
858 ar9287Modes_tx_gain_9287_1_1, 858 ar9287Modes_tx_gain_9287_1_1,
859 ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 6); 859 ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 6);
@@ -965,7 +965,7 @@ int ath9k_hw_init(struct ath_hw *ah)
965 ath9k_hw_init_mode_regs(ah); 965 ath9k_hw_init_mode_regs(ah);
966 966
967 if (ah->is_pciexpress) 967 if (ah->is_pciexpress)
968 ath9k_hw_configpcipowersave(ah, 0); 968 ath9k_hw_configpcipowersave(ah, 0, 0);
969 else 969 else
970 ath9k_hw_disablepcie(ah); 970 ath9k_hw_disablepcie(ah);
971 971
@@ -1273,6 +1273,15 @@ static void ath9k_hw_override_ini(struct ath_hw *ah,
1273 */ 1273 */
1274 REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); 1274 REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
1275 1275
1276 if (AR_SREV_9280_10_OR_LATER(ah)) {
1277 val = REG_READ(ah, AR_PCU_MISC_MODE2) &
1278 (~AR_PCU_MISC_MODE2_HWWAR1);
1279
1280 if (AR_SREV_9287_10_OR_LATER(ah))
1281 val = val & (~AR_PCU_MISC_MODE2_HWWAR2);
1282
1283 REG_WRITE(ah, AR_PCU_MISC_MODE2, val);
1284 }
1276 1285
1277 if (!AR_SREV_5416_20_OR_LATER(ah) || 1286 if (!AR_SREV_5416_20_OR_LATER(ah) ||
1278 AR_SREV_9280_10_OR_LATER(ah)) 1287 AR_SREV_9280_10_OR_LATER(ah))
@@ -1784,7 +1793,7 @@ static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan,
1784static bool ath9k_hw_chip_reset(struct ath_hw *ah, 1793static bool ath9k_hw_chip_reset(struct ath_hw *ah,
1785 struct ath9k_channel *chan) 1794 struct ath9k_channel *chan)
1786{ 1795{
1787 if (OLC_FOR_AR9280_20_LATER) { 1796 if (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) {
1788 if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) 1797 if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON))
1789 return false; 1798 return false;
1790 } else if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM)) 1799 } else if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
@@ -2338,6 +2347,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2338 struct ath9k_channel *curchan = ah->curchan; 2347 struct ath9k_channel *curchan = ah->curchan;
2339 u32 saveDefAntenna; 2348 u32 saveDefAntenna;
2340 u32 macStaId1; 2349 u32 macStaId1;
2350 u64 tsf = 0;
2341 int i, rx_chainmask, r; 2351 int i, rx_chainmask, r;
2342 2352
2343 ah->extprotspacing = sc->ht_extprotspacing; 2353 ah->extprotspacing = sc->ht_extprotspacing;
@@ -2347,7 +2357,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2347 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) 2357 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
2348 return -EIO; 2358 return -EIO;
2349 2359
2350 if (curchan) 2360 if (curchan && !ah->chip_fullsleep)
2351 ath9k_hw_getnf(ah, curchan); 2361 ath9k_hw_getnf(ah, curchan);
2352 2362
2353 if (bChannelChange && 2363 if (bChannelChange &&
@@ -2356,8 +2366,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2356 (chan->channel != ah->curchan->channel) && 2366 (chan->channel != ah->curchan->channel) &&
2357 ((chan->channelFlags & CHANNEL_ALL) == 2367 ((chan->channelFlags & CHANNEL_ALL) ==
2358 (ah->curchan->channelFlags & CHANNEL_ALL)) && 2368 (ah->curchan->channelFlags & CHANNEL_ALL)) &&
2359 (!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) && 2369 !(AR_SREV_9280(ah) || IS_CHAN_A_5MHZ_SPACED(chan) ||
2360 !IS_CHAN_A_5MHZ_SPACED(ah->curchan)))) { 2370 IS_CHAN_A_5MHZ_SPACED(ah->curchan))) {
2361 2371
2362 if (ath9k_hw_channel_change(ah, chan, sc->tx_chan_width)) { 2372 if (ath9k_hw_channel_change(ah, chan, sc->tx_chan_width)) {
2363 ath9k_hw_loadnf(ah, ah->curchan); 2373 ath9k_hw_loadnf(ah, ah->curchan);
@@ -2372,6 +2382,10 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2372 2382
2373 macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B; 2383 macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
2374 2384
2385 /* For chips on which RTC reset is done, save TSF before it gets cleared */
2386 if (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
2387 tsf = ath9k_hw_gettsf64(ah);
2388
2375 saveLedState = REG_READ(ah, AR_CFG_LED) & 2389 saveLedState = REG_READ(ah, AR_CFG_LED) &
2376 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL | 2390 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
2377 AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW); 2391 AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW);
@@ -2398,6 +2412,10 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2398 udelay(50); 2412 udelay(50);
2399 } 2413 }
2400 2414
2415 /* Restore TSF */
2416 if (tsf && AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
2417 ath9k_hw_settsf64(ah, tsf);
2418
2401 if (AR_SREV_9280_10_OR_LATER(ah)) 2419 if (AR_SREV_9280_10_OR_LATER(ah))
2402 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); 2420 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
2403 2421
@@ -3005,9 +3023,10 @@ void ath9k_ps_restore(struct ath_softc *sc)
3005 * Programming the SerDes must go through the same 288 bit serial shift 3023 * Programming the SerDes must go through the same 288 bit serial shift
3006 * register as the other analog registers. Hence the 9 writes. 3024 * register as the other analog registers. Hence the 9 writes.
3007 */ 3025 */
3008void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore) 3026void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore, int power_off)
3009{ 3027{
3010 u8 i; 3028 u8 i;
3029 u32 val;
3011 3030
3012 if (ah->is_pciexpress != true) 3031 if (ah->is_pciexpress != true)
3013 return; 3032 return;
@@ -3017,84 +3036,113 @@ void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore)
3017 return; 3036 return;
3018 3037
3019 /* Nothing to do on restore for 11N */ 3038 /* Nothing to do on restore for 11N */
3020 if (restore) 3039 if (!restore) {
3021 return; 3040 if (AR_SREV_9280_20_OR_LATER(ah)) {
3041 /*
3042 * AR9280 2.0 or later chips use SerDes values from the
3043 * initvals.h initialized depending on chipset during
3044 * ath9k_hw_init()
3045 */
3046 for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) {
3047 REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0),
3048 INI_RA(&ah->iniPcieSerdes, i, 1));
3049 }
3050 } else if (AR_SREV_9280(ah) &&
3051 (ah->hw_version.macRev == AR_SREV_REVISION_9280_10)) {
3052 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
3053 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3054
3055 /* RX shut off when elecidle is asserted */
3056 REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
3057 REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
3058 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
3059
3060 /* Shut off CLKREQ active in L1 */
3061 if (ah->config.pcie_clock_req)
3062 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
3063 else
3064 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
3022 3065
3023 if (AR_SREV_9280_20_OR_LATER(ah)) { 3066 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3024 /* 3067 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3025 * AR9280 2.0 or later chips use SerDes values from the 3068 REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
3026 * initvals.h initialized depending on chipset during
3027 * ath9k_hw_init()
3028 */
3029 for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) {
3030 REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0),
3031 INI_RA(&ah->iniPcieSerdes, i, 1));
3032 }
3033 } else if (AR_SREV_9280(ah) &&
3034 (ah->hw_version.macRev == AR_SREV_REVISION_9280_10)) {
3035 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
3036 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3037 3069
3038 /* RX shut off when elecidle is asserted */ 3070 /* Load the new settings */
3039 REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019); 3071 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3040 REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
3041 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
3042 3072
3043 /* Shut off CLKREQ active in L1 */ 3073 } else {
3044 if (ah->config.pcie_clock_req) 3074 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
3045 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc); 3075 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3046 else
3047 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
3048
3049 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3050 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3051 REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
3052 3076
3053 /* Load the new settings */ 3077 /* RX shut off when elecidle is asserted */
3054 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); 3078 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
3079 REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
3080 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
3055 3081
3056 } else { 3082 /*
3057 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00); 3083 * Ignore ah->ah_config.pcie_clock_req setting for
3058 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); 3084 * pre-AR9280 11n
3085 */
3086 REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
3059 3087
3060 /* RX shut off when elecidle is asserted */ 3088 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3061 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039); 3089 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3062 REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824); 3090 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
3063 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
3064 3091
3065 /* 3092 /* Load the new settings */
3066 * Ignore ah->ah_config.pcie_clock_req setting for 3093 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3067 * pre-AR9280 11n 3094 }
3068 */
3069 REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
3070 3095
3071 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40); 3096 udelay(1000);
3072 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3073 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
3074 3097
3075 /* Load the new settings */ 3098 /* set bit 19 to allow forcing of pcie core into L1 state */
3076 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); 3099 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
3077 }
3078 3100
3079 udelay(1000); 3101 /* Several PCIe massages to ensure proper behaviour */
3102 if (ah->config.pcie_waen) {
3103 val = ah->config.pcie_waen;
3104 if (!power_off)
3105 val &= (~AR_WA_D3_L1_DISABLE);
3106 } else {
3107 if (AR_SREV_9285(ah) || AR_SREV_9271(ah) ||
3108 AR_SREV_9287(ah)) {
3109 val = AR9285_WA_DEFAULT;
3110 if (!power_off)
3111 val &= (~AR_WA_D3_L1_DISABLE);
3112 } else if (AR_SREV_9280(ah)) {
3113 /*
3114 * On AR9280 chips bit 22 of 0x4004 needs to be
3115 * set otherwise card may disappear.
3116 */
3117 val = AR9280_WA_DEFAULT;
3118 if (!power_off)
3119 val &= (~AR_WA_D3_L1_DISABLE);
3120 } else
3121 val = AR_WA_DEFAULT;
3122 }
3080 3123
3081 /* set bit 19 to allow forcing of pcie core into L1 state */ 3124 REG_WRITE(ah, AR_WA, val);
3082 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA); 3125 }
3083 3126
3084 /* Several PCIe massages to ensure proper behaviour */ 3127 if (power_off) {
3085 if (ah->config.pcie_waen) {
3086 REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
3087 } else {
3088 if (AR_SREV_9285(ah) || AR_SREV_9271(ah) || AR_SREV_9287(ah))
3089 REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT);
3090 /* 3128 /*
3091 * On AR9280 chips bit 22 of 0x4004 needs to be set to 3129 * Set PCIe workaround bits
3092 * otherwise card may disappear. 3130 * bit 14 in WA register (disable L1) should only
3131 * be set when device enters D3 and be cleared
3132 * when device comes back to D0.
3093 */ 3133 */
3094 else if (AR_SREV_9280(ah)) 3134 if (ah->config.pcie_waen) {
3095 REG_WRITE(ah, AR_WA, AR9280_WA_DEFAULT); 3135 if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE)
3096 else 3136 REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE);
3097 REG_WRITE(ah, AR_WA, AR_WA_DEFAULT); 3137 } else {
3138 if (((AR_SREV_9285(ah) || AR_SREV_9271(ah) ||
3139 AR_SREV_9287(ah)) &&
3140 (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)) ||
3141 (AR_SREV_9280(ah) &&
3142 (AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE))) {
3143 REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE);
3144 }
3145 }
3098 } 3146 }
3099} 3147}
3100 3148
@@ -3652,15 +3700,7 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah)
3652 } 3700 }
3653#endif 3701#endif
3654 3702
3655 if ((ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || 3703 pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP;
3656 (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE) ||
3657 (ah->hw_version.macVersion == AR_SREV_VERSION_9160) ||
3658 (ah->hw_version.macVersion == AR_SREV_VERSION_9100) ||
3659 (ah->hw_version.macVersion == AR_SREV_VERSION_9280) ||
3660 (ah->hw_version.macVersion == AR_SREV_VERSION_9285))
3661 pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP;
3662 else
3663 pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP;
3664 3704
3665 if (AR_SREV_9280(ah) || AR_SREV_9285(ah)) 3705 if (AR_SREV_9280(ah) || AR_SREV_9285(ah))
3666 pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS; 3706 pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 9106a0b537dd..b89234571829 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -106,7 +106,7 @@
106#define AH_TSF_WRITE_TIMEOUT 100 /* (us) */ 106#define AH_TSF_WRITE_TIMEOUT 100 /* (us) */
107#define AH_TIME_QUANTUM 10 107#define AH_TIME_QUANTUM 10
108#define AR_KEYTABLE_SIZE 128 108#define AR_KEYTABLE_SIZE 128
109#define POWER_UP_TIME 200000 109#define POWER_UP_TIME 10000
110#define SPUR_RSSI_THRESH 40 110#define SPUR_RSSI_THRESH 40
111 111
112#define CAB_TIMEOUT_VAL 10 112#define CAB_TIMEOUT_VAL 10
@@ -650,7 +650,7 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
650 const struct ath9k_beacon_state *bs); 650 const struct ath9k_beacon_state *bs);
651bool ath9k_hw_setpower(struct ath_hw *ah, 651bool ath9k_hw_setpower(struct ath_hw *ah,
652 enum ath9k_power_mode mode); 652 enum ath9k_power_mode mode);
653void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore); 653void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore, int power_off);
654 654
655/* Interrupt Handling */ 655/* Interrupt Handling */
656bool ath9k_hw_intrpend(struct ath_hw *ah); 656bool ath9k_hw_intrpend(struct ath_hw *ah);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 3dc7b5a13e64..52bed89063d4 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1131,7 +1131,7 @@ void ath_radio_enable(struct ath_softc *sc)
1131 int r; 1131 int r;
1132 1132
1133 ath9k_ps_wakeup(sc); 1133 ath9k_ps_wakeup(sc);
1134 ath9k_hw_configpcipowersave(ah, 0); 1134 ath9k_hw_configpcipowersave(ah, 0, 0);
1135 1135
1136 if (!ah->curchan) 1136 if (!ah->curchan)
1137 ah->curchan = ath_get_curchannel(sc, sc->hw); 1137 ah->curchan = ath_get_curchannel(sc, sc->hw);
@@ -1202,7 +1202,7 @@ void ath_radio_disable(struct ath_softc *sc)
1202 spin_unlock_bh(&sc->sc_resetlock); 1202 spin_unlock_bh(&sc->sc_resetlock);
1203 1203
1204 ath9k_hw_phy_disable(ah); 1204 ath9k_hw_phy_disable(ah);
1205 ath9k_hw_configpcipowersave(ah, 1); 1205 ath9k_hw_configpcipowersave(ah, 1, 1);
1206 ath9k_ps_restore(sc); 1206 ath9k_ps_restore(sc);
1207 ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP); 1207 ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
1208} 1208}
@@ -1226,11 +1226,6 @@ static void ath9k_rfkill_poll_state(struct ieee80211_hw *hw)
1226 bool blocked = !!ath_is_rfkill_set(sc); 1226 bool blocked = !!ath_is_rfkill_set(sc);
1227 1227
1228 wiphy_rfkill_set_hw_state(hw->wiphy, blocked); 1228 wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
1229
1230 if (blocked)
1231 ath_radio_disable(sc);
1232 else
1233 ath_radio_enable(sc);
1234} 1229}
1235 1230
1236static void ath_start_rfkill_poll(struct ath_softc *sc) 1231static void ath_start_rfkill_poll(struct ath_softc *sc)
@@ -1260,6 +1255,7 @@ void ath_detach(struct ath_softc *sc)
1260 DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n"); 1255 DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n");
1261 1256
1262 ath_deinit_leds(sc); 1257 ath_deinit_leds(sc);
1258 wiphy_rfkill_stop_polling(sc->hw->wiphy);
1263 1259
1264 for (i = 0; i < sc->num_sec_wiphy; i++) { 1260 for (i = 0; i < sc->num_sec_wiphy; i++) {
1265 struct ath_wiphy *aphy = sc->sec_wiphy[i]; 1261 struct ath_wiphy *aphy = sc->sec_wiphy[i];
@@ -1942,7 +1938,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
1942 init_channel = ath_get_curchannel(sc, hw); 1938 init_channel = ath_get_curchannel(sc, hw);
1943 1939
1944 /* Reset SERDES registers */ 1940 /* Reset SERDES registers */
1945 ath9k_hw_configpcipowersave(sc->sc_ah, 0); 1941 ath9k_hw_configpcipowersave(sc->sc_ah, 0, 0);
1946 1942
1947 /* 1943 /*
1948 * The basic interface to setting the hardware in a good 1944 * The basic interface to setting the hardware in a good
@@ -2166,11 +2162,9 @@ static void ath9k_stop(struct ieee80211_hw *hw)
2166 } else 2162 } else
2167 sc->rx.rxlink = NULL; 2163 sc->rx.rxlink = NULL;
2168 2164
2169 wiphy_rfkill_stop_polling(sc->hw->wiphy);
2170
2171 /* disable HAL and put h/w to sleep */ 2165 /* disable HAL and put h/w to sleep */
2172 ath9k_hw_disable(sc->sc_ah); 2166 ath9k_hw_disable(sc->sc_ah);
2173 ath9k_hw_configpcipowersave(sc->sc_ah, 1); 2167 ath9k_hw_configpcipowersave(sc->sc_ah, 1, 1);
2174 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP); 2168 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
2175 2169
2176 sc->sc_flags |= SC_OP_INVALID; 2170 sc->sc_flags |= SC_OP_INVALID;
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index e5c29eb86e80..d83b77f821e9 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -676,8 +676,9 @@
676#define AR_RC_HOSTIF 0x00000100 676#define AR_RC_HOSTIF 0x00000100
677 677
678#define AR_WA 0x4004 678#define AR_WA 0x4004
679#define AR_WA_D3_L1_DISABLE (1 << 14)
679#define AR9285_WA_DEFAULT 0x004a05cb 680#define AR9285_WA_DEFAULT 0x004a05cb
680#define AR9280_WA_DEFAULT 0x0040073f 681#define AR9280_WA_DEFAULT 0x0040073b
681#define AR_WA_DEFAULT 0x0000073f 682#define AR_WA_DEFAULT 0x0000073f
682 683
683 684
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index 83e38134accb..54ea61c15d8b 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -61,11 +61,28 @@ config B43_PCMCIA
61 61
62 If unsure, say N. 62 If unsure, say N.
63 63
64config B43_SDIO
65 bool "Broadcom 43xx SDIO device support (EXPERIMENTAL)"
66 depends on B43 && SSB_SDIOHOST_POSSIBLE && EXPERIMENTAL
67 select SSB_SDIOHOST
68 ---help---
69 Broadcom 43xx device support for Soft-MAC SDIO devices.
70
71 With this config option you can drive Soft-MAC b43 cards with a
72 Secure Digital I/O interface.
73 This includes the WLAN daughter card found on the Nintendo Wii
74 video game console.
75 Note that this does not support Broadcom 43xx Full-MAC devices.
76
77 It's safe to select Y here, even if you don't have a B43 SDIO device.
78
79 If unsure, say N.
80
64# Data transfers to the device via PIO 81# Data transfers to the device via PIO
65# This is only needed on PCMCIA devices. All others can do DMA properly. 82# This is only needed on PCMCIA and SDIO devices. All others can do DMA properly.
66config B43_PIO 83config B43_PIO
67 bool 84 bool
68 depends on B43 && (B43_PCMCIA || B43_FORCE_PIO) 85 depends on B43 && (B43_SDIO || B43_PCMCIA || B43_FORCE_PIO)
69 select SSB_BLOCKIO 86 select SSB_BLOCKIO
70 default y 87 default y
71 88
diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile
index da379f4b0c3a..84772a2542dc 100644
--- a/drivers/net/wireless/b43/Makefile
+++ b/drivers/net/wireless/b43/Makefile
@@ -16,6 +16,7 @@ b43-$(CONFIG_B43_PIO) += pio.o
16b43-y += rfkill.o 16b43-y += rfkill.o
17b43-$(CONFIG_B43_LEDS) += leds.o 17b43-$(CONFIG_B43_LEDS) += leds.o
18b43-$(CONFIG_B43_PCMCIA) += pcmcia.o 18b43-$(CONFIG_B43_PCMCIA) += pcmcia.o
19b43-$(CONFIG_B43_SDIO) += sdio.o
19b43-$(CONFIG_B43_DEBUG) += debugfs.o 20b43-$(CONFIG_B43_DEBUG) += debugfs.o
20 21
21obj-$(CONFIG_B43) += b43.o 22obj-$(CONFIG_B43) += b43.o
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 09cfe68537b6..fa1549a03c71 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -629,13 +629,6 @@ struct b43_wl {
629 * from the mac80211 subsystem. */ 629 * from the mac80211 subsystem. */
630 u16 mac80211_initially_registered_queues; 630 u16 mac80211_initially_registered_queues;
631 631
632 /* R/W lock for data transmission.
633 * Transmissions on 2+ queues can run concurrently, but somebody else
634 * might sync with TX by write_lock_irqsave()'ing. */
635 rwlock_t tx_lock;
636 /* Lock for LEDs access. */
637 spinlock_t leds_lock;
638
639 /* We can only have one operating interface (802.11 core) 632 /* We can only have one operating interface (802.11 core)
640 * at a time. General information about this interface follows. 633 * at a time. General information about this interface follows.
641 */ 634 */
@@ -686,6 +679,9 @@ struct b43_wl {
686 struct work_struct tx_work; 679 struct work_struct tx_work;
687 /* Queue of packets to be transmitted. */ 680 /* Queue of packets to be transmitted. */
688 struct sk_buff_head tx_queue; 681 struct sk_buff_head tx_queue;
682
683 /* The device LEDs. */
684 struct b43_leds leds;
689}; 685};
690 686
691/* The type of the firmware file. */ 687/* The type of the firmware file. */
@@ -768,13 +764,10 @@ struct b43_wldev {
768 /* The device initialization status. 764 /* The device initialization status.
769 * Use b43_status() to query. */ 765 * Use b43_status() to query. */
770 atomic_t __init_status; 766 atomic_t __init_status;
771 /* Saved init status for handling suspend. */
772 int suspend_init_status;
773 767
774 bool bad_frames_preempt; /* Use "Bad Frames Preemption" (default off) */ 768 bool bad_frames_preempt; /* Use "Bad Frames Preemption" (default off) */
775 bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM) */ 769 bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM) */
776 bool radio_hw_enable; /* saved state of radio hardware enabled state */ 770 bool radio_hw_enable; /* saved state of radio hardware enabled state */
777 bool suspend_in_progress; /* TRUE, if we are in a suspend/resume cycle */
778 bool qos_enabled; /* TRUE, if QoS is used. */ 771 bool qos_enabled; /* TRUE, if QoS is used. */
779 bool hwcrypto_enabled; /* TRUE, if HW crypto acceleration is enabled. */ 772 bool hwcrypto_enabled; /* TRUE, if HW crypto acceleration is enabled. */
780 773
@@ -794,12 +787,6 @@ struct b43_wldev {
794 /* Various statistics about the physical device. */ 787 /* Various statistics about the physical device. */
795 struct b43_stats stats; 788 struct b43_stats stats;
796 789
797 /* The device LEDs. */
798 struct b43_led led_tx;
799 struct b43_led led_rx;
800 struct b43_led led_assoc;
801 struct b43_led led_radio;
802
803 /* Reason code of the last interrupt. */ 790 /* Reason code of the last interrupt. */
804 u32 irq_reason; 791 u32 irq_reason;
805 u32 dma_reason[6]; 792 u32 dma_reason[6];
@@ -830,6 +817,10 @@ struct b43_wldev {
830 /* Debugging stuff follows. */ 817 /* Debugging stuff follows. */
831#ifdef CONFIG_B43_DEBUG 818#ifdef CONFIG_B43_DEBUG
832 struct b43_dfsentry *dfsentry; 819 struct b43_dfsentry *dfsentry;
820 unsigned int irq_count;
821 unsigned int irq_bit_count[32];
822 unsigned int tx_count;
823 unsigned int rx_count;
833#endif 824#endif
834}; 825};
835 826
diff --git a/drivers/net/wireless/b43/debugfs.c b/drivers/net/wireless/b43/debugfs.c
index 8f64943e3f60..80b19a44a407 100644
--- a/drivers/net/wireless/b43/debugfs.c
+++ b/drivers/net/wireless/b43/debugfs.c
@@ -689,6 +689,7 @@ static void b43_add_dynamic_debug(struct b43_wldev *dev)
689 add_dyn_dbg("debug_lo", B43_DBG_LO, 0); 689 add_dyn_dbg("debug_lo", B43_DBG_LO, 0);
690 add_dyn_dbg("debug_firmware", B43_DBG_FIRMWARE, 0); 690 add_dyn_dbg("debug_firmware", B43_DBG_FIRMWARE, 0);
691 add_dyn_dbg("debug_keys", B43_DBG_KEYS, 0); 691 add_dyn_dbg("debug_keys", B43_DBG_KEYS, 0);
692 add_dyn_dbg("debug_verbose_stats", B43_DBG_VERBOSESTATS, 0);
692 693
693#undef add_dyn_dbg 694#undef add_dyn_dbg
694} 695}
diff --git a/drivers/net/wireless/b43/debugfs.h b/drivers/net/wireless/b43/debugfs.h
index e47b4b488b04..822aad8842f4 100644
--- a/drivers/net/wireless/b43/debugfs.h
+++ b/drivers/net/wireless/b43/debugfs.h
@@ -13,6 +13,7 @@ enum b43_dyndbg { /* Dynamic debugging features */
13 B43_DBG_LO, 13 B43_DBG_LO,
14 B43_DBG_FIRMWARE, 14 B43_DBG_FIRMWARE,
15 B43_DBG_KEYS, 15 B43_DBG_KEYS,
16 B43_DBG_VERBOSESTATS,
16 __B43_NR_DYNDBG, 17 __B43_NR_DYNDBG,
17}; 18};
18 19
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index a467ee260a19..8701034569fa 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -1428,9 +1428,9 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
1428 ring->nr_failed_tx_packets++; 1428 ring->nr_failed_tx_packets++;
1429 ring->nr_total_packet_tries += status->frame_count; 1429 ring->nr_total_packet_tries += status->frame_count;
1430#endif /* DEBUG */ 1430#endif /* DEBUG */
1431 ieee80211_tx_status_irqsafe(dev->wl->hw, meta->skb); 1431 ieee80211_tx_status(dev->wl->hw, meta->skb);
1432 1432
1433 /* skb is freed by ieee80211_tx_status_irqsafe() */ 1433 /* skb is freed by ieee80211_tx_status() */
1434 meta->skb = NULL; 1434 meta->skb = NULL;
1435 } else { 1435 } else {
1436 /* No need to call free_descriptor_buffer here, as 1436 /* No need to call free_descriptor_buffer here, as
diff --git a/drivers/net/wireless/b43/leds.c b/drivers/net/wireless/b43/leds.c
index c8b317094c31..fbe3d4f62ce2 100644
--- a/drivers/net/wireless/b43/leds.c
+++ b/drivers/net/wireless/b43/leds.c
@@ -34,57 +34,88 @@
34static void b43_led_turn_on(struct b43_wldev *dev, u8 led_index, 34static void b43_led_turn_on(struct b43_wldev *dev, u8 led_index,
35 bool activelow) 35 bool activelow)
36{ 36{
37 struct b43_wl *wl = dev->wl;
38 unsigned long flags;
39 u16 ctl; 37 u16 ctl;
40 38
41 spin_lock_irqsave(&wl->leds_lock, flags);
42 ctl = b43_read16(dev, B43_MMIO_GPIO_CONTROL); 39 ctl = b43_read16(dev, B43_MMIO_GPIO_CONTROL);
43 if (activelow) 40 if (activelow)
44 ctl &= ~(1 << led_index); 41 ctl &= ~(1 << led_index);
45 else 42 else
46 ctl |= (1 << led_index); 43 ctl |= (1 << led_index);
47 b43_write16(dev, B43_MMIO_GPIO_CONTROL, ctl); 44 b43_write16(dev, B43_MMIO_GPIO_CONTROL, ctl);
48 spin_unlock_irqrestore(&wl->leds_lock, flags);
49} 45}
50 46
51static void b43_led_turn_off(struct b43_wldev *dev, u8 led_index, 47static void b43_led_turn_off(struct b43_wldev *dev, u8 led_index,
52 bool activelow) 48 bool activelow)
53{ 49{
54 struct b43_wl *wl = dev->wl;
55 unsigned long flags;
56 u16 ctl; 50 u16 ctl;
57 51
58 spin_lock_irqsave(&wl->leds_lock, flags);
59 ctl = b43_read16(dev, B43_MMIO_GPIO_CONTROL); 52 ctl = b43_read16(dev, B43_MMIO_GPIO_CONTROL);
60 if (activelow) 53 if (activelow)
61 ctl |= (1 << led_index); 54 ctl |= (1 << led_index);
62 else 55 else
63 ctl &= ~(1 << led_index); 56 ctl &= ~(1 << led_index);
64 b43_write16(dev, B43_MMIO_GPIO_CONTROL, ctl); 57 b43_write16(dev, B43_MMIO_GPIO_CONTROL, ctl);
65 spin_unlock_irqrestore(&wl->leds_lock, flags);
66} 58}
67 59
68/* Callback from the LED subsystem. */ 60static void b43_led_update(struct b43_wldev *dev,
69static void b43_led_brightness_set(struct led_classdev *led_dev, 61 struct b43_led *led)
70 enum led_brightness brightness)
71{ 62{
72 struct b43_led *led = container_of(led_dev, struct b43_led, led_dev);
73 struct b43_wldev *dev = led->dev;
74 bool radio_enabled; 63 bool radio_enabled;
64 bool turn_on;
75 65
76 if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) 66 if (!led->wl)
77 return; 67 return;
78 68
79 /* Checking the radio-enabled status here is slightly racy,
80 * but we want to avoid the locking overhead and we don't care
81 * whether the LED has the wrong state for a second. */
82 radio_enabled = (dev->phy.radio_on && dev->radio_hw_enable); 69 radio_enabled = (dev->phy.radio_on && dev->radio_hw_enable);
83 70
84 if (brightness == LED_OFF || !radio_enabled) 71 /* The led->state read is racy, but we don't care. In case we raced
85 b43_led_turn_off(dev, led->index, led->activelow); 72 * with the brightness_set handler, we will be called again soon
73 * to fixup our state. */
74 if (radio_enabled)
75 turn_on = atomic_read(&led->state) != LED_OFF;
86 else 76 else
77 turn_on = 0;
78 if (turn_on == led->hw_state)
79 return;
80 led->hw_state = turn_on;
81
82 if (turn_on)
87 b43_led_turn_on(dev, led->index, led->activelow); 83 b43_led_turn_on(dev, led->index, led->activelow);
84 else
85 b43_led_turn_off(dev, led->index, led->activelow);
86}
87
88static void b43_leds_work(struct work_struct *work)
89{
90 struct b43_leds *leds = container_of(work, struct b43_leds, work);
91 struct b43_wl *wl = container_of(leds, struct b43_wl, leds);
92 struct b43_wldev *dev;
93
94 mutex_lock(&wl->mutex);
95 dev = wl->current_dev;
96 if (unlikely(!dev || b43_status(dev) < B43_STAT_STARTED))
97 goto out_unlock;
98
99 b43_led_update(dev, &wl->leds.led_tx);
100 b43_led_update(dev, &wl->leds.led_rx);
101 b43_led_update(dev, &wl->leds.led_radio);
102 b43_led_update(dev, &wl->leds.led_assoc);
103
104out_unlock:
105 mutex_unlock(&wl->mutex);
106}
107
108/* Callback from the LED subsystem. */
109static void b43_led_brightness_set(struct led_classdev *led_dev,
110 enum led_brightness brightness)
111{
112 struct b43_led *led = container_of(led_dev, struct b43_led, led_dev);
113 struct b43_wl *wl = led->wl;
114
115 if (likely(!wl->leds.stop)) {
116 atomic_set(&led->state, brightness);
117 ieee80211_queue_work(wl->hw, &wl->leds.work);
118 }
88} 119}
89 120
90static int b43_register_led(struct b43_wldev *dev, struct b43_led *led, 121static int b43_register_led(struct b43_wldev *dev, struct b43_led *led,
@@ -93,15 +124,15 @@ static int b43_register_led(struct b43_wldev *dev, struct b43_led *led,
93{ 124{
94 int err; 125 int err;
95 126
96 b43_led_turn_off(dev, led_index, activelow); 127 if (led->wl)
97 if (led->dev)
98 return -EEXIST; 128 return -EEXIST;
99 if (!default_trigger) 129 if (!default_trigger)
100 return -EINVAL; 130 return -EINVAL;
101 led->dev = dev; 131 led->wl = dev->wl;
102 led->index = led_index; 132 led->index = led_index;
103 led->activelow = activelow; 133 led->activelow = activelow;
104 strncpy(led->name, name, sizeof(led->name)); 134 strncpy(led->name, name, sizeof(led->name));
135 atomic_set(&led->state, 0);
105 136
106 led->led_dev.name = led->name; 137 led->led_dev.name = led->name;
107 led->led_dev.default_trigger = default_trigger; 138 led->led_dev.default_trigger = default_trigger;
@@ -110,19 +141,19 @@ static int b43_register_led(struct b43_wldev *dev, struct b43_led *led,
110 err = led_classdev_register(dev->dev->dev, &led->led_dev); 141 err = led_classdev_register(dev->dev->dev, &led->led_dev);
111 if (err) { 142 if (err) {
112 b43warn(dev->wl, "LEDs: Failed to register %s\n", name); 143 b43warn(dev->wl, "LEDs: Failed to register %s\n", name);
113 led->dev = NULL; 144 led->wl = NULL;
114 return err; 145 return err;
115 } 146 }
147
116 return 0; 148 return 0;
117} 149}
118 150
119static void b43_unregister_led(struct b43_led *led) 151static void b43_unregister_led(struct b43_led *led)
120{ 152{
121 if (!led->dev) 153 if (!led->wl)
122 return; 154 return;
123 led_classdev_unregister(&led->led_dev); 155 led_classdev_unregister(&led->led_dev);
124 b43_led_turn_off(led->dev, led->index, led->activelow); 156 led->wl = NULL;
125 led->dev = NULL;
126} 157}
127 158
128static void b43_map_led(struct b43_wldev *dev, 159static void b43_map_led(struct b43_wldev *dev,
@@ -137,24 +168,20 @@ static void b43_map_led(struct b43_wldev *dev,
137 * generic LED triggers. */ 168 * generic LED triggers. */
138 switch (behaviour) { 169 switch (behaviour) {
139 case B43_LED_INACTIVE: 170 case B43_LED_INACTIVE:
140 break;
141 case B43_LED_OFF: 171 case B43_LED_OFF:
142 b43_led_turn_off(dev, led_index, activelow);
143 break;
144 case B43_LED_ON: 172 case B43_LED_ON:
145 b43_led_turn_on(dev, led_index, activelow);
146 break; 173 break;
147 case B43_LED_ACTIVITY: 174 case B43_LED_ACTIVITY:
148 case B43_LED_TRANSFER: 175 case B43_LED_TRANSFER:
149 case B43_LED_APTRANSFER: 176 case B43_LED_APTRANSFER:
150 snprintf(name, sizeof(name), 177 snprintf(name, sizeof(name),
151 "b43-%s::tx", wiphy_name(hw->wiphy)); 178 "b43-%s::tx", wiphy_name(hw->wiphy));
152 b43_register_led(dev, &dev->led_tx, name, 179 b43_register_led(dev, &dev->wl->leds.led_tx, name,
153 ieee80211_get_tx_led_name(hw), 180 ieee80211_get_tx_led_name(hw),
154 led_index, activelow); 181 led_index, activelow);
155 snprintf(name, sizeof(name), 182 snprintf(name, sizeof(name),
156 "b43-%s::rx", wiphy_name(hw->wiphy)); 183 "b43-%s::rx", wiphy_name(hw->wiphy));
157 b43_register_led(dev, &dev->led_rx, name, 184 b43_register_led(dev, &dev->wl->leds.led_rx, name,
158 ieee80211_get_rx_led_name(hw), 185 ieee80211_get_rx_led_name(hw),
159 led_index, activelow); 186 led_index, activelow);
160 break; 187 break;
@@ -164,18 +191,15 @@ static void b43_map_led(struct b43_wldev *dev,
164 case B43_LED_MODE_BG: 191 case B43_LED_MODE_BG:
165 snprintf(name, sizeof(name), 192 snprintf(name, sizeof(name),
166 "b43-%s::radio", wiphy_name(hw->wiphy)); 193 "b43-%s::radio", wiphy_name(hw->wiphy));
167 b43_register_led(dev, &dev->led_radio, name, 194 b43_register_led(dev, &dev->wl->leds.led_radio, name,
168 ieee80211_get_radio_led_name(hw), 195 ieee80211_get_radio_led_name(hw),
169 led_index, activelow); 196 led_index, activelow);
170 /* Sync the RF-kill LED state with radio and switch states. */
171 if (dev->phy.radio_on && b43_is_hw_radio_enabled(dev))
172 b43_led_turn_on(dev, led_index, activelow);
173 break; 197 break;
174 case B43_LED_WEIRD: 198 case B43_LED_WEIRD:
175 case B43_LED_ASSOC: 199 case B43_LED_ASSOC:
176 snprintf(name, sizeof(name), 200 snprintf(name, sizeof(name),
177 "b43-%s::assoc", wiphy_name(hw->wiphy)); 201 "b43-%s::assoc", wiphy_name(hw->wiphy));
178 b43_register_led(dev, &dev->led_assoc, name, 202 b43_register_led(dev, &dev->wl->leds.led_assoc, name,
179 ieee80211_get_assoc_led_name(hw), 203 ieee80211_get_assoc_led_name(hw),
180 led_index, activelow); 204 led_index, activelow);
181 break; 205 break;
@@ -186,58 +210,150 @@ static void b43_map_led(struct b43_wldev *dev,
186 } 210 }
187} 211}
188 212
189void b43_leds_init(struct b43_wldev *dev) 213static void b43_led_get_sprominfo(struct b43_wldev *dev,
214 unsigned int led_index,
215 enum b43_led_behaviour *behaviour,
216 bool *activelow)
190{ 217{
191 struct ssb_bus *bus = dev->dev->bus; 218 struct ssb_bus *bus = dev->dev->bus;
192 u8 sprom[4]; 219 u8 sprom[4];
193 int i;
194 enum b43_led_behaviour behaviour;
195 bool activelow;
196 220
197 sprom[0] = bus->sprom.gpio0; 221 sprom[0] = bus->sprom.gpio0;
198 sprom[1] = bus->sprom.gpio1; 222 sprom[1] = bus->sprom.gpio1;
199 sprom[2] = bus->sprom.gpio2; 223 sprom[2] = bus->sprom.gpio2;
200 sprom[3] = bus->sprom.gpio3; 224 sprom[3] = bus->sprom.gpio3;
201 225
202 for (i = 0; i < 4; i++) { 226 if (sprom[led_index] == 0xFF) {
203 if (sprom[i] == 0xFF) { 227 /* There is no LED information in the SPROM
204 /* There is no LED information in the SPROM 228 * for this LED. Hardcode it here. */
205 * for this LED. Hardcode it here. */ 229 *activelow = 0;
206 activelow = 0; 230 switch (led_index) {
207 switch (i) { 231 case 0:
208 case 0: 232 *behaviour = B43_LED_ACTIVITY;
209 behaviour = B43_LED_ACTIVITY; 233 *activelow = 1;
210 activelow = 1; 234 if (bus->boardinfo.vendor == PCI_VENDOR_ID_COMPAQ)
211 if (bus->boardinfo.vendor == PCI_VENDOR_ID_COMPAQ) 235 *behaviour = B43_LED_RADIO_ALL;
212 behaviour = B43_LED_RADIO_ALL; 236 break;
213 break; 237 case 1:
214 case 1: 238 *behaviour = B43_LED_RADIO_B;
215 behaviour = B43_LED_RADIO_B; 239 if (bus->boardinfo.vendor == PCI_VENDOR_ID_ASUSTEK)
216 if (bus->boardinfo.vendor == PCI_VENDOR_ID_ASUSTEK) 240 *behaviour = B43_LED_ASSOC;
217 behaviour = B43_LED_ASSOC; 241 break;
218 break; 242 case 2:
219 case 2: 243 *behaviour = B43_LED_RADIO_A;
220 behaviour = B43_LED_RADIO_A; 244 break;
221 break; 245 case 3:
222 case 3: 246 *behaviour = B43_LED_OFF;
223 behaviour = B43_LED_OFF; 247 break;
224 break; 248 default:
225 default: 249 B43_WARN_ON(1);
226 B43_WARN_ON(1); 250 return;
227 return; 251 }
228 } 252 } else {
253 *behaviour = sprom[led_index] & B43_LED_BEHAVIOUR;
254 *activelow = !!(sprom[led_index] & B43_LED_ACTIVELOW);
255 }
256}
257
258void b43_leds_init(struct b43_wldev *dev)
259{
260 struct b43_led *led;
261 unsigned int i;
262 enum b43_led_behaviour behaviour;
263 bool activelow;
264
265 /* Sync the RF-kill LED state (if we have one) with radio and switch states. */
266 led = &dev->wl->leds.led_radio;
267 if (led->wl) {
268 if (dev->phy.radio_on && b43_is_hw_radio_enabled(dev)) {
269 b43_led_turn_on(dev, led->index, led->activelow);
270 led->hw_state = 1;
271 atomic_set(&led->state, 1);
229 } else { 272 } else {
230 behaviour = sprom[i] & B43_LED_BEHAVIOUR; 273 b43_led_turn_off(dev, led->index, led->activelow);
231 activelow = !!(sprom[i] & B43_LED_ACTIVELOW); 274 led->hw_state = 0;
275 atomic_set(&led->state, 0);
232 } 276 }
233 b43_map_led(dev, i, behaviour, activelow);
234 } 277 }
278
279 /* Initialize TX/RX/ASSOC leds */
280 led = &dev->wl->leds.led_tx;
281 if (led->wl) {
282 b43_led_turn_off(dev, led->index, led->activelow);
283 led->hw_state = 0;
284 atomic_set(&led->state, 0);
285 }
286 led = &dev->wl->leds.led_rx;
287 if (led->wl) {
288 b43_led_turn_off(dev, led->index, led->activelow);
289 led->hw_state = 0;
290 atomic_set(&led->state, 0);
291 }
292 led = &dev->wl->leds.led_assoc;
293 if (led->wl) {
294 b43_led_turn_off(dev, led->index, led->activelow);
295 led->hw_state = 0;
296 atomic_set(&led->state, 0);
297 }
298
299 /* Initialize other LED states. */
300 for (i = 0; i < B43_MAX_NR_LEDS; i++) {
301 b43_led_get_sprominfo(dev, i, &behaviour, &activelow);
302 switch (behaviour) {
303 case B43_LED_OFF:
304 b43_led_turn_off(dev, i, activelow);
305 break;
306 case B43_LED_ON:
307 b43_led_turn_on(dev, i, activelow);
308 break;
309 default:
310 /* Leave others as-is. */
311 break;
312 }
313 }
314
315 dev->wl->leds.stop = 0;
235} 316}
236 317
237void b43_leds_exit(struct b43_wldev *dev) 318void b43_leds_exit(struct b43_wldev *dev)
238{ 319{
239 b43_unregister_led(&dev->led_tx); 320 struct b43_leds *leds = &dev->wl->leds;
240 b43_unregister_led(&dev->led_rx); 321
241 b43_unregister_led(&dev->led_assoc); 322 b43_led_turn_off(dev, leds->led_tx.index, leds->led_tx.activelow);
242 b43_unregister_led(&dev->led_radio); 323 b43_led_turn_off(dev, leds->led_rx.index, leds->led_rx.activelow);
324 b43_led_turn_off(dev, leds->led_assoc.index, leds->led_assoc.activelow);
325 b43_led_turn_off(dev, leds->led_radio.index, leds->led_radio.activelow);
326}
327
328void b43_leds_stop(struct b43_wldev *dev)
329{
330 struct b43_leds *leds = &dev->wl->leds;
331
332 leds->stop = 1;
333 cancel_work_sync(&leds->work);
334}
335
336void b43_leds_register(struct b43_wldev *dev)
337{
338 unsigned int i;
339 enum b43_led_behaviour behaviour;
340 bool activelow;
341
342 INIT_WORK(&dev->wl->leds.work, b43_leds_work);
343
344 /* Register the LEDs to the LED subsystem. */
345 for (i = 0; i < B43_MAX_NR_LEDS; i++) {
346 b43_led_get_sprominfo(dev, i, &behaviour, &activelow);
347 b43_map_led(dev, i, behaviour, activelow);
348 }
349}
350
351void b43_leds_unregister(struct b43_wldev *dev)
352{
353 struct b43_leds *leds = &dev->wl->leds;
354
355 b43_unregister_led(&leds->led_tx);
356 b43_unregister_led(&leds->led_rx);
357 b43_unregister_led(&leds->led_assoc);
358 b43_unregister_led(&leds->led_radio);
243} 359}
diff --git a/drivers/net/wireless/b43/leds.h b/drivers/net/wireless/b43/leds.h
index b8b1dd521243..9592e4c5a5f5 100644
--- a/drivers/net/wireless/b43/leds.h
+++ b/drivers/net/wireless/b43/leds.h
@@ -7,12 +7,13 @@ struct b43_wldev;
7 7
8#include <linux/types.h> 8#include <linux/types.h>
9#include <linux/leds.h> 9#include <linux/leds.h>
10#include <linux/workqueue.h>
10 11
11 12
12#define B43_LED_MAX_NAME_LEN 31 13#define B43_LED_MAX_NAME_LEN 31
13 14
14struct b43_led { 15struct b43_led {
15 struct b43_wldev *dev; 16 struct b43_wl *wl;
16 /* The LED class device */ 17 /* The LED class device */
17 struct led_classdev led_dev; 18 struct led_classdev led_dev;
18 /* The index number of the LED. */ 19 /* The index number of the LED. */
@@ -22,8 +23,24 @@ struct b43_led {
22 bool activelow; 23 bool activelow;
23 /* The unique name string for this LED device. */ 24 /* The unique name string for this LED device. */
24 char name[B43_LED_MAX_NAME_LEN + 1]; 25 char name[B43_LED_MAX_NAME_LEN + 1];
26 /* The current status of the LED. This is updated locklessly. */
27 atomic_t state;
28 /* The active state in hardware. */
29 bool hw_state;
25}; 30};
26 31
32struct b43_leds {
33 struct b43_led led_tx;
34 struct b43_led led_rx;
35 struct b43_led led_radio;
36 struct b43_led led_assoc;
37
38 bool stop;
39 struct work_struct work;
40};
41
42#define B43_MAX_NR_LEDS 4
43
27#define B43_LED_BEHAVIOUR 0x7F 44#define B43_LED_BEHAVIOUR 0x7F
28#define B43_LED_ACTIVELOW 0x80 45#define B43_LED_ACTIVELOW 0x80
29/* LED behaviour values */ 46/* LED behaviour values */
@@ -42,23 +59,35 @@ enum b43_led_behaviour {
42 B43_LED_INACTIVE, 59 B43_LED_INACTIVE,
43}; 60};
44 61
62void b43_leds_register(struct b43_wldev *dev);
63void b43_leds_unregister(struct b43_wldev *dev);
45void b43_leds_init(struct b43_wldev *dev); 64void b43_leds_init(struct b43_wldev *dev);
46void b43_leds_exit(struct b43_wldev *dev); 65void b43_leds_exit(struct b43_wldev *dev);
66void b43_leds_stop(struct b43_wldev *dev);
47 67
48 68
49#else /* CONFIG_B43_LEDS */ 69#else /* CONFIG_B43_LEDS */
50/* LED support disabled */ 70/* LED support disabled */
51 71
52struct b43_led { 72struct b43_leds {
53 /* empty */ 73 /* empty */
54}; 74};
55 75
76static inline void b43_leds_register(struct b43_wldev *dev)
77{
78}
79static inline void b43_leds_unregister(struct b43_wldev *dev)
80{
81}
56static inline void b43_leds_init(struct b43_wldev *dev) 82static inline void b43_leds_init(struct b43_wldev *dev)
57{ 83{
58} 84}
59static inline void b43_leds_exit(struct b43_wldev *dev) 85static inline void b43_leds_exit(struct b43_wldev *dev)
60{ 86{
61} 87}
88static inline void b43_leds_stop(struct b43_wldev *dev)
89{
90}
62#endif /* CONFIG_B43_LEDS */ 91#endif /* CONFIG_B43_LEDS */
63 92
64#endif /* B43_LEDS_H_ */ 93#endif /* B43_LEDS_H_ */
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index e789792a36bc..9b907a36bb8c 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -8,6 +8,9 @@
8 Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org> 8 Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org>
9 Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch> 9 Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
10 10
11 SDIO support
12 Copyright (c) 2009 Albert Herranz <albert_herranz@yahoo.es>
13
11 Some parts of the code in this file are derived from the ipw2200 14 Some parts of the code in this file are derived from the ipw2200
12 driver Copyright(c) 2003 - 2004 Intel Corporation. 15 driver Copyright(c) 2003 - 2004 Intel Corporation.
13 16
@@ -53,6 +56,8 @@
53#include "xmit.h" 56#include "xmit.h"
54#include "lo.h" 57#include "lo.h"
55#include "pcmcia.h" 58#include "pcmcia.h"
59#include "sdio.h"
60#include <linux/mmc/sdio_func.h>
56 61
57MODULE_DESCRIPTION("Broadcom B43 wireless driver"); 62MODULE_DESCRIPTION("Broadcom B43 wireless driver");
58MODULE_AUTHOR("Martin Langer"); 63MODULE_AUTHOR("Martin Langer");
@@ -1587,7 +1592,7 @@ static void b43_beacon_update_trigger_work(struct work_struct *work)
1587 mutex_lock(&wl->mutex); 1592 mutex_lock(&wl->mutex);
1588 dev = wl->current_dev; 1593 dev = wl->current_dev;
1589 if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) { 1594 if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) {
1590 if (0 /*FIXME dev->dev->bus->bustype == SSB_BUSTYPE_SDIO*/) { 1595 if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) {
1591 /* wl->mutex is enough. */ 1596 /* wl->mutex is enough. */
1592 b43_do_beacon_update_trigger_work(dev); 1597 b43_do_beacon_update_trigger_work(dev);
1593 mmiowb(); 1598 mmiowb();
@@ -1825,6 +1830,16 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev)
1825 1830
1826 /* Re-enable interrupts on the device by restoring the current interrupt mask. */ 1831 /* Re-enable interrupts on the device by restoring the current interrupt mask. */
1827 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask); 1832 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
1833
1834#if B43_DEBUG
1835 if (b43_debug(dev, B43_DBG_VERBOSESTATS)) {
1836 dev->irq_count++;
1837 for (i = 0; i < ARRAY_SIZE(dev->irq_bit_count); i++) {
1838 if (reason & (1 << i))
1839 dev->irq_bit_count[i]++;
1840 }
1841 }
1842#endif
1828} 1843}
1829 1844
1830/* Interrupt thread handler. Handles device interrupts in thread context. */ 1845/* Interrupt thread handler. Handles device interrupts in thread context. */
@@ -1905,6 +1920,21 @@ static irqreturn_t b43_interrupt_handler(int irq, void *dev_id)
1905 return ret; 1920 return ret;
1906} 1921}
1907 1922
1923/* SDIO interrupt handler. This runs in process context. */
1924static void b43_sdio_interrupt_handler(struct b43_wldev *dev)
1925{
1926 struct b43_wl *wl = dev->wl;
1927 irqreturn_t ret;
1928
1929 mutex_lock(&wl->mutex);
1930
1931 ret = b43_do_interrupt(dev);
1932 if (ret == IRQ_WAKE_THREAD)
1933 b43_do_interrupt_thread(dev);
1934
1935 mutex_unlock(&wl->mutex);
1936}
1937
1908void b43_do_release_fw(struct b43_firmware_file *fw) 1938void b43_do_release_fw(struct b43_firmware_file *fw)
1909{ 1939{
1910 release_firmware(fw->data); 1940 release_firmware(fw->data);
@@ -2645,6 +2675,20 @@ static void b43_adjust_opmode(struct b43_wldev *dev)
2645 cfp_pretbtt = 50; 2675 cfp_pretbtt = 50;
2646 } 2676 }
2647 b43_write16(dev, 0x612, cfp_pretbtt); 2677 b43_write16(dev, 0x612, cfp_pretbtt);
2678
2679 /* FIXME: We don't currently implement the PMQ mechanism,
2680 * so always disable it. If we want to implement PMQ,
2681 * we need to enable it here (clear DISCPMQ) in AP mode.
2682 */
2683 if (0 /* ctl & B43_MACCTL_AP */) {
2684 b43_write32(dev, B43_MMIO_MACCTL,
2685 b43_read32(dev, B43_MMIO_MACCTL)
2686 & ~B43_MACCTL_DISCPMQ);
2687 } else {
2688 b43_write32(dev, B43_MMIO_MACCTL,
2689 b43_read32(dev, B43_MMIO_MACCTL)
2690 | B43_MACCTL_DISCPMQ);
2691 }
2648} 2692}
2649 2693
2650static void b43_rate_memory_write(struct b43_wldev *dev, u16 rate, int is_ofdm) 2694static void b43_rate_memory_write(struct b43_wldev *dev, u16 rate, int is_ofdm)
@@ -2873,6 +2917,27 @@ static void b43_periodic_every15sec(struct b43_wldev *dev)
2873 2917
2874 atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT); 2918 atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT);
2875 wmb(); 2919 wmb();
2920
2921#if B43_DEBUG
2922 if (b43_debug(dev, B43_DBG_VERBOSESTATS)) {
2923 unsigned int i;
2924
2925 b43dbg(dev->wl, "Stats: %7u IRQs/sec, %7u TX/sec, %7u RX/sec\n",
2926 dev->irq_count / 15,
2927 dev->tx_count / 15,
2928 dev->rx_count / 15);
2929 dev->irq_count = 0;
2930 dev->tx_count = 0;
2931 dev->rx_count = 0;
2932 for (i = 0; i < ARRAY_SIZE(dev->irq_bit_count); i++) {
2933 if (dev->irq_bit_count[i]) {
2934 b43dbg(dev->wl, "Stats: %7u IRQ-%02u/sec (0x%08X)\n",
2935 dev->irq_bit_count[i] / 15, i, (1 << i));
2936 dev->irq_bit_count[i] = 0;
2937 }
2938 }
2939 }
2940#endif
2876} 2941}
2877 2942
2878static void do_periodic_work(struct b43_wldev *dev) 2943static void do_periodic_work(struct b43_wldev *dev)
@@ -3002,14 +3067,18 @@ static void b43_security_init(struct b43_wldev *dev)
3002static int b43_rng_read(struct hwrng *rng, u32 *data) 3067static int b43_rng_read(struct hwrng *rng, u32 *data)
3003{ 3068{
3004 struct b43_wl *wl = (struct b43_wl *)rng->priv; 3069 struct b43_wl *wl = (struct b43_wl *)rng->priv;
3070 struct b43_wldev *dev;
3071 int count = -ENODEV;
3005 3072
3006 /* FIXME: We need to take wl->mutex here to make sure the device 3073 mutex_lock(&wl->mutex);
3007 * is not going away from under our ass. However it could deadlock 3074 dev = wl->current_dev;
3008 * with hwrng internal locking. */ 3075 if (likely(dev && b43_status(dev) >= B43_STAT_INITIALIZED)) {
3009 3076 *data = b43_read16(dev, B43_MMIO_RNG);
3010 *data = b43_read16(wl->current_dev, B43_MMIO_RNG); 3077 count = sizeof(u16);
3078 }
3079 mutex_unlock(&wl->mutex);
3011 3080
3012 return (sizeof(u16)); 3081 return count;
3013} 3082}
3014#endif /* CONFIG_B43_HWRNG */ 3083#endif /* CONFIG_B43_HWRNG */
3015 3084
@@ -3068,6 +3137,9 @@ static void b43_tx_work(struct work_struct *work)
3068 dev_kfree_skb(skb); /* Drop it */ 3137 dev_kfree_skb(skb); /* Drop it */
3069 } 3138 }
3070 3139
3140#if B43_DEBUG
3141 dev->tx_count++;
3142#endif
3071 mutex_unlock(&wl->mutex); 3143 mutex_unlock(&wl->mutex);
3072} 3144}
3073 3145
@@ -3820,7 +3892,7 @@ redo:
3820 3892
3821 /* Disable interrupts on the device. */ 3893 /* Disable interrupts on the device. */
3822 b43_set_status(dev, B43_STAT_INITIALIZED); 3894 b43_set_status(dev, B43_STAT_INITIALIZED);
3823 if (0 /*FIXME dev->dev->bus->bustype == SSB_BUSTYPE_SDIO*/) { 3895 if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) {
3824 /* wl->mutex is locked. That is enough. */ 3896 /* wl->mutex is locked. That is enough. */
3825 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0); 3897 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
3826 b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* Flush */ 3898 b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* Flush */
@@ -3830,10 +3902,15 @@ redo:
3830 b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* Flush */ 3902 b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* Flush */
3831 spin_unlock_irq(&wl->hardirq_lock); 3903 spin_unlock_irq(&wl->hardirq_lock);
3832 } 3904 }
3833 /* Synchronize the interrupt handlers. Unlock to avoid deadlocks. */ 3905 /* Synchronize and free the interrupt handlers. Unlock to avoid deadlocks. */
3834 orig_dev = dev; 3906 orig_dev = dev;
3835 mutex_unlock(&wl->mutex); 3907 mutex_unlock(&wl->mutex);
3836 synchronize_irq(dev->dev->irq); 3908 if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) {
3909 b43_sdio_free_irq(dev);
3910 } else {
3911 synchronize_irq(dev->dev->irq);
3912 free_irq(dev->dev->irq, dev);
3913 }
3837 mutex_lock(&wl->mutex); 3914 mutex_lock(&wl->mutex);
3838 dev = wl->current_dev; 3915 dev = wl->current_dev;
3839 if (!dev) 3916 if (!dev)
@@ -3850,7 +3927,7 @@ redo:
3850 dev_kfree_skb(skb_dequeue(&wl->tx_queue)); 3927 dev_kfree_skb(skb_dequeue(&wl->tx_queue));
3851 3928
3852 b43_mac_suspend(dev); 3929 b43_mac_suspend(dev);
3853 free_irq(dev->dev->irq, dev); 3930 b43_leds_exit(dev);
3854 b43dbg(wl, "Wireless interface stopped\n"); 3931 b43dbg(wl, "Wireless interface stopped\n");
3855 3932
3856 return dev; 3933 return dev;
@@ -3864,12 +3941,20 @@ static int b43_wireless_core_start(struct b43_wldev *dev)
3864 B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED); 3941 B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED);
3865 3942
3866 drain_txstatus_queue(dev); 3943 drain_txstatus_queue(dev);
3867 err = request_threaded_irq(dev->dev->irq, b43_interrupt_handler, 3944 if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) {
3868 b43_interrupt_thread_handler, 3945 err = b43_sdio_request_irq(dev, b43_sdio_interrupt_handler);
3869 IRQF_SHARED, KBUILD_MODNAME, dev); 3946 if (err) {
3870 if (err) { 3947 b43err(dev->wl, "Cannot request SDIO IRQ\n");
3871 b43err(dev->wl, "Cannot request IRQ-%d\n", dev->dev->irq); 3948 goto out;
3872 goto out; 3949 }
3950 } else {
3951 err = request_threaded_irq(dev->dev->irq, b43_interrupt_handler,
3952 b43_interrupt_thread_handler,
3953 IRQF_SHARED, KBUILD_MODNAME, dev);
3954 if (err) {
3955 b43err(dev->wl, "Cannot request IRQ-%d\n", dev->dev->irq);
3956 goto out;
3957 }
3873 } 3958 }
3874 3959
3875 /* We are ready to run. */ 3960 /* We are ready to run. */
@@ -3882,8 +3967,10 @@ static int b43_wireless_core_start(struct b43_wldev *dev)
3882 /* Start maintainance work */ 3967 /* Start maintainance work */
3883 b43_periodic_tasks_setup(dev); 3968 b43_periodic_tasks_setup(dev);
3884 3969
3970 b43_leds_init(dev);
3971
3885 b43dbg(dev->wl, "Wireless interface started\n"); 3972 b43dbg(dev->wl, "Wireless interface started\n");
3886 out: 3973out:
3887 return err; 3974 return err;
3888} 3975}
3889 3976
@@ -4160,10 +4247,6 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)
4160 macctl |= B43_MACCTL_PSM_JMP0; 4247 macctl |= B43_MACCTL_PSM_JMP0;
4161 b43_write32(dev, B43_MMIO_MACCTL, macctl); 4248 b43_write32(dev, B43_MMIO_MACCTL, macctl);
4162 4249
4163 if (!dev->suspend_in_progress) {
4164 b43_leds_exit(dev);
4165 b43_rng_exit(dev->wl);
4166 }
4167 b43_dma_free(dev); 4250 b43_dma_free(dev);
4168 b43_pio_free(dev); 4251 b43_pio_free(dev);
4169 b43_chip_exit(dev); 4252 b43_chip_exit(dev);
@@ -4180,7 +4263,6 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)
4180/* Initialize a wireless core */ 4263/* Initialize a wireless core */
4181static int b43_wireless_core_init(struct b43_wldev *dev) 4264static int b43_wireless_core_init(struct b43_wldev *dev)
4182{ 4265{
4183 struct b43_wl *wl = dev->wl;
4184 struct ssb_bus *bus = dev->dev->bus; 4266 struct ssb_bus *bus = dev->dev->bus;
4185 struct ssb_sprom *sprom = &bus->sprom; 4267 struct ssb_sprom *sprom = &bus->sprom;
4186 struct b43_phy *phy = &dev->phy; 4268 struct b43_phy *phy = &dev->phy;
@@ -4264,7 +4346,9 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4264 /* Maximum Contention Window */ 4346 /* Maximum Contention Window */
4265 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF); 4347 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF);
4266 4348
4267 if ((dev->dev->bus->bustype == SSB_BUSTYPE_PCMCIA) || B43_FORCE_PIO) { 4349 if ((dev->dev->bus->bustype == SSB_BUSTYPE_PCMCIA) ||
4350 (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) ||
4351 B43_FORCE_PIO) {
4268 dev->__using_pio_transfers = 1; 4352 dev->__using_pio_transfers = 1;
4269 err = b43_pio_init(dev); 4353 err = b43_pio_init(dev);
4270 } else { 4354 } else {
@@ -4280,15 +4364,13 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4280 ssb_bus_powerup(bus, !(sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)); 4364 ssb_bus_powerup(bus, !(sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW));
4281 b43_upload_card_macaddress(dev); 4365 b43_upload_card_macaddress(dev);
4282 b43_security_init(dev); 4366 b43_security_init(dev);
4283 if (!dev->suspend_in_progress) 4367
4284 b43_rng_init(wl); 4368 ieee80211_wake_queues(dev->wl->hw);
4285 4369
4286 ieee80211_wake_queues(dev->wl->hw); 4370 ieee80211_wake_queues(dev->wl->hw);
4287 4371
4288 b43_set_status(dev, B43_STAT_INITIALIZED); 4372 b43_set_status(dev, B43_STAT_INITIALIZED);
4289 4373
4290 if (!dev->suspend_in_progress)
4291 b43_leds_init(dev);
4292out: 4374out:
4293 return err; 4375 return err;
4294 4376
@@ -4837,7 +4919,6 @@ static int b43_wireless_init(struct ssb_device *dev)
4837 4919
4838 /* Initialize struct b43_wl */ 4920 /* Initialize struct b43_wl */
4839 wl->hw = hw; 4921 wl->hw = hw;
4840 spin_lock_init(&wl->leds_lock);
4841 mutex_init(&wl->mutex); 4922 mutex_init(&wl->mutex);
4842 spin_lock_init(&wl->hardirq_lock); 4923 spin_lock_init(&wl->hardirq_lock);
4843 INIT_LIST_HEAD(&wl->devlist); 4924 INIT_LIST_HEAD(&wl->devlist);
@@ -4878,6 +4959,8 @@ static int b43_probe(struct ssb_device *dev, const struct ssb_device_id *id)
4878 err = ieee80211_register_hw(wl->hw); 4959 err = ieee80211_register_hw(wl->hw);
4879 if (err) 4960 if (err)
4880 goto err_one_core_detach; 4961 goto err_one_core_detach;
4962 b43_leds_register(wl->current_dev);
4963 b43_rng_init(wl);
4881 } 4964 }
4882 4965
4883 out: 4966 out:
@@ -4906,12 +4989,15 @@ static void b43_remove(struct ssb_device *dev)
4906 * might have modified it. Restoring is important, so the networking 4989 * might have modified it. Restoring is important, so the networking
4907 * stack can properly free resources. */ 4990 * stack can properly free resources. */
4908 wl->hw->queues = wl->mac80211_initially_registered_queues; 4991 wl->hw->queues = wl->mac80211_initially_registered_queues;
4992 b43_leds_stop(wldev);
4909 ieee80211_unregister_hw(wl->hw); 4993 ieee80211_unregister_hw(wl->hw);
4910 } 4994 }
4911 4995
4912 b43_one_core_detach(dev); 4996 b43_one_core_detach(dev);
4913 4997
4914 if (list_empty(&wl->devlist)) { 4998 if (list_empty(&wl->devlist)) {
4999 b43_rng_exit(wl);
5000 b43_leds_unregister(wldev);
4915 /* Last core on the chip unregistered. 5001 /* Last core on the chip unregistered.
4916 * We can destroy common struct b43_wl. 5002 * We can destroy common struct b43_wl.
4917 */ 5003 */
@@ -4929,80 +5015,17 @@ void b43_controller_restart(struct b43_wldev *dev, const char *reason)
4929 ieee80211_queue_work(dev->wl->hw, &dev->restart_work); 5015 ieee80211_queue_work(dev->wl->hw, &dev->restart_work);
4930} 5016}
4931 5017
4932#ifdef CONFIG_PM
4933
4934static int b43_suspend(struct ssb_device *dev, pm_message_t state)
4935{
4936 struct b43_wldev *wldev = ssb_get_drvdata(dev);
4937 struct b43_wl *wl = wldev->wl;
4938
4939 b43dbg(wl, "Suspending...\n");
4940
4941 mutex_lock(&wl->mutex);
4942 wldev->suspend_in_progress = true;
4943 wldev->suspend_init_status = b43_status(wldev);
4944 if (wldev->suspend_init_status >= B43_STAT_STARTED)
4945 wldev = b43_wireless_core_stop(wldev);
4946 if (wldev && wldev->suspend_init_status >= B43_STAT_INITIALIZED)
4947 b43_wireless_core_exit(wldev);
4948 mutex_unlock(&wl->mutex);
4949
4950 b43dbg(wl, "Device suspended.\n");
4951
4952 return 0;
4953}
4954
4955static int b43_resume(struct ssb_device *dev)
4956{
4957 struct b43_wldev *wldev = ssb_get_drvdata(dev);
4958 struct b43_wl *wl = wldev->wl;
4959 int err = 0;
4960
4961 b43dbg(wl, "Resuming...\n");
4962
4963 mutex_lock(&wl->mutex);
4964 if (wldev->suspend_init_status >= B43_STAT_INITIALIZED) {
4965 err = b43_wireless_core_init(wldev);
4966 if (err) {
4967 b43err(wl, "Resume failed at core init\n");
4968 goto out;
4969 }
4970 }
4971 if (wldev->suspend_init_status >= B43_STAT_STARTED) {
4972 err = b43_wireless_core_start(wldev);
4973 if (err) {
4974 b43_leds_exit(wldev);
4975 b43_rng_exit(wldev->wl);
4976 b43_wireless_core_exit(wldev);
4977 b43err(wl, "Resume failed at core start\n");
4978 goto out;
4979 }
4980 }
4981 b43dbg(wl, "Device resumed.\n");
4982 out:
4983 wldev->suspend_in_progress = false;
4984 mutex_unlock(&wl->mutex);
4985 return err;
4986}
4987
4988#else /* CONFIG_PM */
4989# define b43_suspend NULL
4990# define b43_resume NULL
4991#endif /* CONFIG_PM */
4992
4993static struct ssb_driver b43_ssb_driver = { 5018static struct ssb_driver b43_ssb_driver = {
4994 .name = KBUILD_MODNAME, 5019 .name = KBUILD_MODNAME,
4995 .id_table = b43_ssb_tbl, 5020 .id_table = b43_ssb_tbl,
4996 .probe = b43_probe, 5021 .probe = b43_probe,
4997 .remove = b43_remove, 5022 .remove = b43_remove,
4998 .suspend = b43_suspend,
4999 .resume = b43_resume,
5000}; 5023};
5001 5024
5002static void b43_print_driverinfo(void) 5025static void b43_print_driverinfo(void)
5003{ 5026{
5004 const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "", 5027 const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "",
5005 *feat_leds = ""; 5028 *feat_leds = "", *feat_sdio = "";
5006 5029
5007#ifdef CONFIG_B43_PCI_AUTOSELECT 5030#ifdef CONFIG_B43_PCI_AUTOSELECT
5008 feat_pci = "P"; 5031 feat_pci = "P";
@@ -5016,11 +5039,14 @@ static void b43_print_driverinfo(void)
5016#ifdef CONFIG_B43_LEDS 5039#ifdef CONFIG_B43_LEDS
5017 feat_leds = "L"; 5040 feat_leds = "L";
5018#endif 5041#endif
5042#ifdef CONFIG_B43_SDIO
5043 feat_sdio = "S";
5044#endif
5019 printk(KERN_INFO "Broadcom 43xx driver loaded " 5045 printk(KERN_INFO "Broadcom 43xx driver loaded "
5020 "[ Features: %s%s%s%s, Firmware-ID: " 5046 "[ Features: %s%s%s%s%s, Firmware-ID: "
5021 B43_SUPPORTED_FIRMWARE_ID " ]\n", 5047 B43_SUPPORTED_FIRMWARE_ID " ]\n",
5022 feat_pci, feat_pcmcia, feat_nphy, 5048 feat_pci, feat_pcmcia, feat_nphy,
5023 feat_leds); 5049 feat_leds, feat_sdio);
5024} 5050}
5025 5051
5026static int __init b43_init(void) 5052static int __init b43_init(void)
@@ -5031,13 +5057,18 @@ static int __init b43_init(void)
5031 err = b43_pcmcia_init(); 5057 err = b43_pcmcia_init();
5032 if (err) 5058 if (err)
5033 goto err_dfs_exit; 5059 goto err_dfs_exit;
5034 err = ssb_driver_register(&b43_ssb_driver); 5060 err = b43_sdio_init();
5035 if (err) 5061 if (err)
5036 goto err_pcmcia_exit; 5062 goto err_pcmcia_exit;
5063 err = ssb_driver_register(&b43_ssb_driver);
5064 if (err)
5065 goto err_sdio_exit;
5037 b43_print_driverinfo(); 5066 b43_print_driverinfo();
5038 5067
5039 return err; 5068 return err;
5040 5069
5070err_sdio_exit:
5071 b43_sdio_exit();
5041err_pcmcia_exit: 5072err_pcmcia_exit:
5042 b43_pcmcia_exit(); 5073 b43_pcmcia_exit();
5043err_dfs_exit: 5074err_dfs_exit:
@@ -5048,6 +5079,7 @@ err_dfs_exit:
5048static void __exit b43_exit(void) 5079static void __exit b43_exit(void)
5049{ 5080{
5050 ssb_driver_unregister(&b43_ssb_driver); 5081 ssb_driver_unregister(&b43_ssb_driver);
5082 b43_sdio_exit();
5051 b43_pcmcia_exit(); 5083 b43_pcmcia_exit();
5052 b43_debugfs_exit(); 5084 b43_debugfs_exit();
5053} 5085}
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index 3e02d969f683..1e318d815a5b 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -2228,6 +2228,16 @@ static enum b43_txpwr_result b43_lpphy_op_recalc_txpower(struct b43_wldev *dev,
2228 return B43_TXPWR_RES_DONE; 2228 return B43_TXPWR_RES_DONE;
2229} 2229}
2230 2230
2231void b43_lpphy_op_switch_analog(struct b43_wldev *dev, bool on)
2232{
2233 if (on) {
2234 b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVR, 0xfff8);
2235 } else {
2236 b43_phy_set(dev, B43_LPPHY_AFE_CTL_OVRVAL, 0x0007);
2237 b43_phy_set(dev, B43_LPPHY_AFE_CTL_OVR, 0x0007);
2238 }
2239}
2240
2231const struct b43_phy_operations b43_phyops_lp = { 2241const struct b43_phy_operations b43_phyops_lp = {
2232 .allocate = b43_lpphy_op_allocate, 2242 .allocate = b43_lpphy_op_allocate,
2233 .free = b43_lpphy_op_free, 2243 .free = b43_lpphy_op_free,
@@ -2239,7 +2249,7 @@ const struct b43_phy_operations b43_phyops_lp = {
2239 .radio_read = b43_lpphy_op_radio_read, 2249 .radio_read = b43_lpphy_op_radio_read,
2240 .radio_write = b43_lpphy_op_radio_write, 2250 .radio_write = b43_lpphy_op_radio_write,
2241 .software_rfkill = b43_lpphy_op_software_rfkill, 2251 .software_rfkill = b43_lpphy_op_software_rfkill,
2242 .switch_analog = b43_phyop_switch_analog_generic, 2252 .switch_analog = b43_lpphy_op_switch_analog,
2243 .switch_channel = b43_lpphy_op_switch_channel, 2253 .switch_channel = b43_lpphy_op_switch_channel,
2244 .get_default_chan = b43_lpphy_op_get_default_chan, 2254 .get_default_chan = b43_lpphy_op_get_default_chan,
2245 .set_rx_antenna = b43_lpphy_op_set_rx_antenna, 2255 .set_rx_antenna = b43_lpphy_op_set_rx_antenna,
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
index 3498b68385e7..e96091b31499 100644
--- a/drivers/net/wireless/b43/pio.c
+++ b/drivers/net/wireless/b43/pio.c
@@ -574,7 +574,7 @@ void b43_pio_handle_txstatus(struct b43_wldev *dev,
574 q->buffer_used -= total_len; 574 q->buffer_used -= total_len;
575 q->free_packet_slots += 1; 575 q->free_packet_slots += 1;
576 576
577 ieee80211_tx_status_irqsafe(dev->wl->hw, pack->skb); 577 ieee80211_tx_status(dev->wl->hw, pack->skb);
578 pack->skb = NULL; 578 pack->skb = NULL;
579 list_add(&pack->list, &q->packets_list); 579 list_add(&pack->list, &q->packets_list);
580 580
diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c
index 31e55999893f..7a3218c5ba7d 100644
--- a/drivers/net/wireless/b43/rfkill.c
+++ b/drivers/net/wireless/b43/rfkill.c
@@ -28,7 +28,7 @@
28/* Returns TRUE, if the radio is enabled in hardware. */ 28/* Returns TRUE, if the radio is enabled in hardware. */
29bool b43_is_hw_radio_enabled(struct b43_wldev *dev) 29bool b43_is_hw_radio_enabled(struct b43_wldev *dev)
30{ 30{
31 if (dev->phy.rev >= 3) { 31 if (dev->phy.rev >= 3 || dev->phy.type == B43_PHYTYPE_LP) {
32 if (!(b43_read32(dev, B43_MMIO_RADIO_HWENABLED_HI) 32 if (!(b43_read32(dev, B43_MMIO_RADIO_HWENABLED_HI)
33 & B43_MMIO_RADIO_HWENABLED_HI_MASK)) 33 & B43_MMIO_RADIO_HWENABLED_HI_MASK))
34 return 1; 34 return 1;
diff --git a/drivers/net/wireless/b43/sdio.c b/drivers/net/wireless/b43/sdio.c
new file mode 100644
index 000000000000..0d3ac64147a5
--- /dev/null
+++ b/drivers/net/wireless/b43/sdio.c
@@ -0,0 +1,202 @@
1/*
2 * Broadcom B43 wireless driver
3 *
4 * SDIO over Sonics Silicon Backplane bus glue for b43.
5 *
6 * Copyright (C) 2009 Albert Herranz
7 * Copyright (C) 2009 Michael Buesch <mb@bu3sch.de>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or (at
12 * your option) any later version.
13 */
14
15#include <linux/kernel.h>
16#include <linux/mmc/card.h>
17#include <linux/mmc/sdio_func.h>
18#include <linux/mmc/sdio_ids.h>
19#include <linux/ssb/ssb.h>
20
21#include "sdio.h"
22#include "b43.h"
23
24
25#define HNBU_CHIPID 0x01 /* vendor & device id */
26
27#define B43_SDIO_BLOCK_SIZE 64 /* rx fifo max size in bytes */
28
29
30static const struct b43_sdio_quirk {
31 u16 vendor;
32 u16 device;
33 unsigned int quirks;
34} b43_sdio_quirks[] = {
35 { 0x14E4, 0x4318, SSB_QUIRK_SDIO_READ_AFTER_WRITE32, },
36 { },
37};
38
39
40static unsigned int b43_sdio_get_quirks(u16 vendor, u16 device)
41{
42 const struct b43_sdio_quirk *q;
43
44 for (q = b43_sdio_quirks; q->quirks; q++) {
45 if (vendor == q->vendor && device == q->device)
46 return q->quirks;
47 }
48
49 return 0;
50}
51
52static void b43_sdio_interrupt_dispatcher(struct sdio_func *func)
53{
54 struct b43_sdio *sdio = sdio_get_drvdata(func);
55 struct b43_wldev *dev = sdio->irq_handler_opaque;
56
57 if (unlikely(b43_status(dev) < B43_STAT_STARTED))
58 return;
59
60 sdio_release_host(func);
61 sdio->irq_handler(dev);
62 sdio_claim_host(func);
63}
64
65int b43_sdio_request_irq(struct b43_wldev *dev,
66 void (*handler)(struct b43_wldev *dev))
67{
68 struct ssb_bus *bus = dev->dev->bus;
69 struct sdio_func *func = bus->host_sdio;
70 struct b43_sdio *sdio = sdio_get_drvdata(func);
71 int err;
72
73 sdio->irq_handler_opaque = dev;
74 sdio->irq_handler = handler;
75 sdio_claim_host(func);
76 err = sdio_claim_irq(func, b43_sdio_interrupt_dispatcher);
77 sdio_release_host(func);
78
79 return err;
80}
81
82void b43_sdio_free_irq(struct b43_wldev *dev)
83{
84 struct ssb_bus *bus = dev->dev->bus;
85 struct sdio_func *func = bus->host_sdio;
86 struct b43_sdio *sdio = sdio_get_drvdata(func);
87
88 sdio_claim_host(func);
89 sdio_release_irq(func);
90 sdio_release_host(func);
91 sdio->irq_handler_opaque = NULL;
92 sdio->irq_handler = NULL;
93}
94
95static int b43_sdio_probe(struct sdio_func *func,
96 const struct sdio_device_id *id)
97{
98 struct b43_sdio *sdio;
99 struct sdio_func_tuple *tuple;
100 u16 vendor = 0, device = 0;
101 int error;
102
103 /* Look for the card chip identifier. */
104 tuple = func->tuples;
105 while (tuple) {
106 switch (tuple->code) {
107 case 0x80:
108 switch (tuple->data[0]) {
109 case HNBU_CHIPID:
110 if (tuple->size != 5)
111 break;
112 vendor = tuple->data[1] | (tuple->data[2]<<8);
113 device = tuple->data[3] | (tuple->data[4]<<8);
114 dev_info(&func->dev, "Chip ID %04x:%04x\n",
115 vendor, device);
116 break;
117 default:
118 break;
119 }
120 break;
121 default:
122 break;
123 }
124 tuple = tuple->next;
125 }
126 if (!vendor || !device) {
127 error = -ENODEV;
128 goto out;
129 }
130
131 sdio_claim_host(func);
132 error = sdio_set_block_size(func, B43_SDIO_BLOCK_SIZE);
133 if (error) {
134 dev_err(&func->dev, "failed to set block size to %u bytes,"
135 " error %d\n", B43_SDIO_BLOCK_SIZE, error);
136 goto err_release_host;
137 }
138 error = sdio_enable_func(func);
139 if (error) {
140 dev_err(&func->dev, "failed to enable func, error %d\n", error);
141 goto err_release_host;
142 }
143 sdio_release_host(func);
144
145 sdio = kzalloc(sizeof(*sdio), GFP_KERNEL);
146 if (!sdio) {
147 error = -ENOMEM;
148 dev_err(&func->dev, "failed to allocate ssb bus\n");
149 goto err_disable_func;
150 }
151 error = ssb_bus_sdiobus_register(&sdio->ssb, func,
152 b43_sdio_get_quirks(vendor, device));
153 if (error) {
154 dev_err(&func->dev, "failed to register ssb sdio bus,"
155 " error %d\n", error);
156 goto err_free_ssb;
157 }
158 sdio_set_drvdata(func, sdio);
159
160 return 0;
161
162err_free_ssb:
163 kfree(sdio);
164err_disable_func:
165 sdio_disable_func(func);
166err_release_host:
167 sdio_release_host(func);
168out:
169 return error;
170}
171
172static void b43_sdio_remove(struct sdio_func *func)
173{
174 struct b43_sdio *sdio = sdio_get_drvdata(func);
175
176 ssb_bus_unregister(&sdio->ssb);
177 sdio_disable_func(func);
178 kfree(sdio);
179 sdio_set_drvdata(func, NULL);
180}
181
182static const struct sdio_device_id b43_sdio_ids[] = {
183 { SDIO_DEVICE(0x02d0, 0x044b) }, /* Nintendo Wii WLAN daughter card */
184 { },
185};
186
187static struct sdio_driver b43_sdio_driver = {
188 .name = "b43-sdio",
189 .id_table = b43_sdio_ids,
190 .probe = b43_sdio_probe,
191 .remove = b43_sdio_remove,
192};
193
194int b43_sdio_init(void)
195{
196 return sdio_register_driver(&b43_sdio_driver);
197}
198
199void b43_sdio_exit(void)
200{
201 sdio_unregister_driver(&b43_sdio_driver);
202}
diff --git a/drivers/net/wireless/b43/sdio.h b/drivers/net/wireless/b43/sdio.h
new file mode 100644
index 000000000000..fb633094403a
--- /dev/null
+++ b/drivers/net/wireless/b43/sdio.h
@@ -0,0 +1,45 @@
1#ifndef B43_SDIO_H_
2#define B43_SDIO_H_
3
4#include <linux/ssb/ssb.h>
5
6struct b43_wldev;
7
8
9#ifdef CONFIG_B43_SDIO
10
11struct b43_sdio {
12 struct ssb_bus ssb;
13 void *irq_handler_opaque;
14 void (*irq_handler)(struct b43_wldev *dev);
15};
16
17int b43_sdio_request_irq(struct b43_wldev *dev,
18 void (*handler)(struct b43_wldev *dev));
19void b43_sdio_free_irq(struct b43_wldev *dev);
20
21int b43_sdio_init(void);
22void b43_sdio_exit(void);
23
24
25#else /* CONFIG_B43_SDIO */
26
27
28int b43_sdio_request_irq(struct b43_wldev *dev,
29 void (*handler)(struct b43_wldev *dev))
30{
31 return -ENODEV;
32}
33void b43_sdio_free_irq(struct b43_wldev *dev)
34{
35}
36static inline int b43_sdio_init(void)
37{
38 return 0;
39}
40static inline void b43_sdio_exit(void)
41{
42}
43
44#endif /* CONFIG_B43_SDIO */
45#endif /* B43_SDIO_H_ */
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 14f541248b5c..ac9f600995e4 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -690,8 +690,11 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
690 } 690 }
691 691
692 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); 692 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
693 ieee80211_rx_irqsafe(dev->wl->hw, skb); 693 ieee80211_rx(dev->wl->hw, skb);
694 694
695#if B43_DEBUG
696 dev->rx_count++;
697#endif
695 return; 698 return;
696drop: 699drop:
697 b43dbg(dev->wl, "RX: Packet dropped\n"); 700 b43dbg(dev->wl, "RX: Packet dropped\n");
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index ca61d3796cef..3259b8841544 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2021,6 +2021,12 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
2021 agg->frame_count, txq_id, idx); 2021 agg->frame_count, txq_id, idx);
2022 2022
2023 hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx); 2023 hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx);
2024 if (!hdr) {
2025 IWL_ERR(priv,
2026 "BUG_ON idx doesn't point to valid skb"
2027 " idx=%d, txq_id=%d\n", idx, txq_id);
2028 return -1;
2029 }
2024 2030
2025 sc = le16_to_cpu(hdr->seq_ctrl); 2031 sc = le16_to_cpu(hdr->seq_ctrl);
2026 if (idx != (SEQ_TO_SN(sc) & 0xff)) { 2032 if (idx != (SEQ_TO_SN(sc) & 0xff)) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 1d539e3b8db1..a6391c7fea53 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1163,6 +1163,12 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
1163 agg->frame_count, txq_id, idx); 1163 agg->frame_count, txq_id, idx);
1164 1164
1165 hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx); 1165 hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx);
1166 if (!hdr) {
1167 IWL_ERR(priv,
1168 "BUG_ON idx doesn't point to valid skb"
1169 " idx=%d, txq_id=%d\n", idx, txq_id);
1170 return -1;
1171 }
1166 1172
1167 sc = le16_to_cpu(hdr->seq_ctrl); 1173 sc = le16_to_cpu(hdr->seq_ctrl);
1168 if (idx != (SEQ_TO_SN(sc) & 0xff)) { 1174 if (idx != (SEQ_TO_SN(sc) & 0xff)) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index b90adcb73b06..8e1bb53c0aa3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -250,12 +250,20 @@ void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority)
250 } 250 }
251 spin_unlock_irqrestore(&rxq->lock, flags); 251 spin_unlock_irqrestore(&rxq->lock, flags);
252 252
253 if (rxq->free_count > RX_LOW_WATERMARK)
254 priority |= __GFP_NOWARN;
253 /* Alloc a new receive buffer */ 255 /* Alloc a new receive buffer */
254 skb = alloc_skb(priv->hw_params.rx_buf_size + 256, 256 skb = alloc_skb(priv->hw_params.rx_buf_size + 256,
255 priority); 257 priority);
256 258
257 if (!skb) { 259 if (!skb) {
258 IWL_CRIT(priv, "Can not allocate SKB buffers\n"); 260 if (net_ratelimit())
261 IWL_DEBUG_INFO(priv, "Failed to allocate SKB buffer.\n");
262 if ((rxq->free_count <= RX_LOW_WATERMARK) &&
263 net_ratelimit())
264 IWL_CRIT(priv, "Failed to allocate SKB buffer with %s. Only %u free buffers remaining.\n",
265 priority == GFP_ATOMIC ? "GFP_ATOMIC" : "GFP_KERNEL",
266 rxq->free_count);
259 /* We don't reschedule replenish work here -- we will 267 /* We don't reschedule replenish work here -- we will
260 * call the restock method and if it still needs 268 * call the restock method and if it still needs
261 * more buffers it will schedule replenish */ 269 * more buffers it will schedule replenish */
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index a2b9ec82b965..c6633fec8216 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -520,7 +520,7 @@ int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
520 struct iwl_host_cmd cmd = { 520 struct iwl_host_cmd cmd = {
521 .id = REPLY_WEPKEY, 521 .id = REPLY_WEPKEY,
522 .data = wep_cmd, 522 .data = wep_cmd,
523 .flags = CMD_SYNC, 523 .flags = CMD_ASYNC,
524 }; 524 };
525 525
526 memset(wep_cmd, 0, cmd_size + 526 memset(wep_cmd, 0, cmd_size +
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 090966837f3c..4f2d43937283 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1146,11 +1146,18 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority)
1146 } 1146 }
1147 spin_unlock_irqrestore(&rxq->lock, flags); 1147 spin_unlock_irqrestore(&rxq->lock, flags);
1148 1148
1149 if (rxq->free_count > RX_LOW_WATERMARK)
1150 priority |= __GFP_NOWARN;
1149 /* Alloc a new receive buffer */ 1151 /* Alloc a new receive buffer */
1150 skb = alloc_skb(priv->hw_params.rx_buf_size, priority); 1152 skb = alloc_skb(priv->hw_params.rx_buf_size, priority);
1151 if (!skb) { 1153 if (!skb) {
1152 if (net_ratelimit()) 1154 if (net_ratelimit())
1153 IWL_CRIT(priv, ": Can not allocate SKB buffers\n"); 1155 IWL_DEBUG_INFO(priv, "Failed to allocate SKB buffer.\n");
1156 if ((rxq->free_count <= RX_LOW_WATERMARK) &&
1157 net_ratelimit())
1158 IWL_CRIT(priv, "Failed to allocate SKB buffer with %s. Only %u free buffers remaining.\n",
1159 priority == GFP_ATOMIC ? "GFP_ATOMIC" : "GFP_KERNEL",
1160 rxq->free_count);
1154 /* We don't reschedule replenish work here -- we will 1161 /* We don't reschedule replenish work here -- we will
1155 * call the restock method and if it still needs 1162 * call the restock method and if it still needs
1156 * more buffers it will schedule replenish */ 1163 * more buffers it will schedule replenish */
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index 5462cb5ad994..567f029a8cda 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -380,7 +380,7 @@ static inline void rt2x00crypto_tx_insert_iv(struct sk_buff *skb,
380{ 380{
381} 381}
382 382
383static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, bool l2pad, 383static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb,
384 unsigned int header_length, 384 unsigned int header_length,
385 struct rxdone_entry_desc *rxdesc) 385 struct rxdone_entry_desc *rxdesc)
386{ 386{
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig
index 7b14d5bc63d6..88060e117541 100644
--- a/drivers/net/wireless/wl12xx/Kconfig
+++ b/drivers/net/wireless/wl12xx/Kconfig
@@ -1,5 +1,5 @@
1menuconfig WL12XX 1menuconfig WL12XX
2 boolean "TI wl12xx driver support" 2 tristate "TI wl12xx driver support"
3 depends on MAC80211 && WLAN_80211 && EXPERIMENTAL 3 depends on MAC80211 && WLAN_80211 && EXPERIMENTAL
4 ---help--- 4 ---help---
5 This will enable TI wl12xx driver support. The drivers make 5 This will enable TI wl12xx driver support. The drivers make
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 38688847d568..23a6a6d4863b 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -1070,7 +1070,7 @@ static int eject_installer(struct usb_interface *intf)
1070 1070
1071 /* Find bulk out endpoint */ 1071 /* Find bulk out endpoint */
1072 endpoint = &iface_desc->endpoint[1].desc; 1072 endpoint = &iface_desc->endpoint[1].desc;
1073 if ((endpoint->bEndpointAddress & USB_TYPE_MASK) == USB_DIR_OUT && 1073 if (usb_endpoint_dir_out(endpoint) &&
1074 usb_endpoint_xfer_bulk(endpoint)) { 1074 usb_endpoint_xfer_bulk(endpoint)) {
1075 bulk_out_ep = endpoint->bEndpointAddress; 1075 bulk_out_ep = endpoint->bEndpointAddress;
1076 } else { 1076 } else {