From e01ff34edca752ae45ee359896cdf8b97f216739 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 20 Dec 2011 10:46:08 -0800 Subject: ath9k_hw: fix sparse warnings on ar9003_rtt.c This fixes these sparse warnings: CHECK drivers/net/wireless/ath/ath9k/ar9003_rtt.c drivers/net/wireless/ath/ath9k/ar9003_rtt.c:36:6: warning: symbol 'ar9003_hw_rtt_enable' was not declared. Should it be static? drivers/net/wireless/ath/ath9k/ar9003_rtt.c:41:6: warning: symbol 'ar9003_hw_rtt_disable' was not declared. Should it be static? drivers/net/wireless/ath/ath9k/ar9003_rtt.c:46:6: warning: symbol 'ar9003_hw_rtt_set_mask' was not declared. Should it be static? drivers/net/wireless/ath/ath9k/ar9003_rtt.c:52:6: warning: symbol 'ar9003_hw_rtt_force_restore' was not declared. Should it be static? drivers/net/wireless/ath/ath9k/ar9003_rtt.c:102:6: warning: symbol 'ar9003_hw_rtt_load_hist' was not declared. Should it be static? drivers/net/wireless/ath/ath9k/ar9003_rtt.c:135:6: warning: symbol 'ar9003_hw_rtt_fill_hist' was not declared. Should it be static? drivers/net/wireless/ath/ath9k/ar9003_rtt.c:143:6: warning: symbol 'ar9003_hw_rtt_clear_hist' was not declared. Should it be stati Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_rtt.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_rtt.c b/drivers/net/wireless/ath/ath9k/ar9003_rtt.c index 48803ee9c0d6..458bedf0b0ae 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_rtt.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_rtt.c @@ -16,6 +16,7 @@ #include "hw.h" #include "ar9003_phy.h" +#include "ar9003_rtt.h" #define RTT_RESTORE_TIMEOUT 1000 #define RTT_ACCESS_TIMEOUT 100 -- cgit v1.2.1 From 1512a486569e039555907db36948d92b7fd32d7e Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 20 Dec 2011 10:46:09 -0800 Subject: ath9k: fix tx queue sparse complaint This fixes this rant from sparse: CHECK drivers/net/wireless/ath/ath9k/xmit.c drivers/net/wireless/ath/ath9k/xmit.c:107:13: warning: context imbalance in 'ath_txq_lock' - wrong count at exit drivers/net/wireless/ath/ath9k/xmit.c:112:13: warning: context imbalance in 'ath_txq_unlock' - unexpected unlock drivers/net/wireless/ath/ath9k/xmit.c:123:30: warning: context imbalance in 'ath_txq_unlock_complete' - unexpected unlock CC [M] drivers/net/wireless/ath/ath9k/xmit. Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index b092523caede..c8fc180f5218 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -105,16 +105,19 @@ static int ath_max_4ms_framelen[4][32] = { /*********************/ static void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq) + __acquires(&txq->axq_lock) { spin_lock_bh(&txq->axq_lock); } static void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq) + __releases(&txq->axq_lock) { spin_unlock_bh(&txq->axq_lock); } static void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq) + __releases(&txq->axq_lock) { struct sk_buff_head q; struct sk_buff *skb; -- cgit v1.2.1 From 76ff9a611d08d1fc03283c32cf16180e40cb6931 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 20 Dec 2011 10:46:10 -0800 Subject: ath5k: avoid sparse warnings on tracing Just skip the sparse checks on tracing. CHECK drivers/net/wireless/ath/ath5k/base.c include/trace/../../drivers/net/wireless/ath/ath5k/trace.h:19:1: error: incompatible types for operation (<) include/trace/../../drivers/net/wireless/ath/ath5k/trace.h:19:1: left side has type struct ath5k_hw * include/trace/../../drivers/net/wireless/ath/ath5k/trace.h:19:1: right side has type int include/trace/../../drivers/net/wireless/ath/ath5k/trace.h:37:1: error: incompatible types for operation (<) include/trace/../../drivers/net/wireless/ath/ath5k/trace.h:37:1: left side has type struct ath5k_hw * include/trace/../../drivers/net/wireless/ath/ath5k/trace.h:37:1: right side has type int include/trace/../../drivers/net/wireless/ath/ath5k/trace.h:63:1: error: incompatible types for operation (<) include/trace/../../drivers/net/wireless/ath/ath5k/trace.h:63:1: left side has type struct ath5k_hw * include/trace/../../drivers/net/wireless/ath/ath5k/trace.h:63:1: right side has type int /home/mcgrof/wireless-testing/arch/x86/include/asm/jump_label.h:16:9: error: bad asm output /home/mcgrof/wireless-testing/arch/x86/include/asm/jump_label.h:16:9: error: bad asm output /home/mcgrof/wireless-testing/arch/x86/include/asm/jump_label.h:16:9: error: bad asm output /home/mcgrof/wireless-testing/arch/x86/include/asm/jump_label.h:16:9: error: bad asm output CC [M] drivers/net/wireless/ath/ath5k/base.o Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/trace.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/ath/ath5k/trace.h b/drivers/net/wireless/ath/ath5k/trace.h index 39f002ed4a88..00f015819344 100644 --- a/drivers/net/wireless/ath/ath5k/trace.h +++ b/drivers/net/wireless/ath/ath5k/trace.h @@ -3,7 +3,8 @@ #include -#ifndef CONFIG_ATH5K_TRACER + +#if !defined(CONFIG_ATH5K_TRACER) || defined(__CHECKER__) #undef TRACE_EVENT #define TRACE_EVENT(name, proto, ...) \ static inline void trace_ ## name(proto) {} @@ -93,7 +94,7 @@ TRACE_EVENT(ath5k_tx_complete, #endif /* __TRACE_ATH5K_H */ -#ifdef CONFIG_ATH5K_TRACER +#if defined(CONFIG_ATH5K_TRACER) && !defined(__CHECKER__) #undef TRACE_INCLUDE_PATH #define TRACE_INCLUDE_PATH ../../drivers/net/wireless/ath/ath5k -- cgit v1.2.1 From a98aa7ae14529144527b64a54a9ecd828fa805a6 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 20 Dec 2011 10:46:11 -0800 Subject: ath9k_hw: fix sparse complaint on ar9003_switch_com_spdt_get() This fixes this sparse complaint: make C=2 CF="-D__CHECK_ENDIAN__" M=drivers/net/wireless/ath/ CHECK drivers/net/wireless/ath/ath9k/ar9003_eeprom.c drivers/net/wireless/ath/ath9k/ar9003_eeprom.c:3544:21: warning: incorrect type in assignment (different base types) drivers/net/wireless/ath/ath9k/ar9003_eeprom.c:3544:21: expected restricted __le32 [usertype] val drivers/net/wireless/ath/ath9k/ar9003_eeprom.c:3544:21: got restricted __le16 [usertype] switchcomspdt drivers/net/wireless/ath/ath9k/ar9003_eeprom.c:3546:21: warning: incorrect type in assignment (different base types) drivers/net/wireless/ath/ath9k/ar9003_eeprom.c:3546:21: expected restricted __le32 [usertype] val drivers/net/wireless/ath/ath9k/ar9003_eeprom.c:3546:21: got restricted __le16 [usertype] switchcomspdt The eep->modalHeader5G.switchcomspdt is a le16 and we return u16, so just return le16_to_cpu(). Cc: Felix Fietkau Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 391def99314c..9fbcbddea165 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3538,13 +3538,13 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz) static u16 ar9003_switch_com_spdt_get(struct ath_hw *ah, bool is_2ghz) { struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; - __le32 val; + __le16 val; if (is_2ghz) val = eep->modalHeader2G.switchcomspdt; else val = eep->modalHeader5G.switchcomspdt; - return le32_to_cpu(val); + return le16_to_cpu(val); } -- cgit v1.2.1 From 9dd4d9b99218b2bebbcfb4627b34145250deeb6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Tue, 20 Dec 2011 22:45:47 +0100 Subject: b43: N-PHY: move common TX/RX functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 218 ++++++++++++++++++++------------------- 1 file changed, 111 insertions(+), 107 deletions(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index e89b04bcd1f4..52503c699b2e 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -1928,6 +1928,117 @@ static void b43_nphy_workarounds(struct b43_wldev *dev) b43_nphy_stay_in_carrier_search(dev, 0); } +/************************************************** + * Tx/Rx common + **************************************************/ + +/* + * Transmits a known value for LO calibration + * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TXTone + */ +static int b43_nphy_tx_tone(struct b43_wldev *dev, u32 freq, u16 max_val, + bool iqmode, bool dac_test) +{ + u16 samp = b43_nphy_gen_load_samples(dev, freq, max_val, dac_test); + if (samp == 0) + return -1; + b43_nphy_run_samples(dev, samp, 0xFFFF, 0, iqmode, dac_test); + return 0; +} + +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Chains */ +static void b43_nphy_update_txrx_chain(struct b43_wldev *dev) +{ + struct b43_phy_n *nphy = dev->phy.n; + + bool override = false; + u16 chain = 0x33; + + if (nphy->txrx_chain == 0) { + chain = 0x11; + override = true; + } else if (nphy->txrx_chain == 1) { + chain = 0x22; + override = true; + } + + b43_phy_maskset(dev, B43_NPHY_RFSEQCA, + ~(B43_NPHY_RFSEQCA_TXEN | B43_NPHY_RFSEQCA_RXEN), + chain); + + if (override) + b43_phy_set(dev, B43_NPHY_RFSEQMODE, + B43_NPHY_RFSEQMODE_CAOVER); + else + b43_phy_mask(dev, B43_NPHY_RFSEQMODE, + ~B43_NPHY_RFSEQMODE_CAOVER); +} + +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/stop-playback */ +static void b43_nphy_stop_playback(struct b43_wldev *dev) +{ + struct b43_phy_n *nphy = dev->phy.n; + u16 tmp; + + if (nphy->hang_avoid) + b43_nphy_stay_in_carrier_search(dev, 1); + + tmp = b43_phy_read(dev, B43_NPHY_SAMP_STAT); + if (tmp & 0x1) + b43_phy_set(dev, B43_NPHY_SAMP_CMD, B43_NPHY_SAMP_CMD_STOP); + else if (tmp & 0x2) + b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x7FFF); + + b43_phy_mask(dev, B43_NPHY_SAMP_CMD, ~0x0004); + + if (nphy->bb_mult_save & 0x80000000) { + tmp = nphy->bb_mult_save & 0xFFFF; + b43_ntab_write(dev, B43_NTAB16(15, 87), tmp); + nphy->bb_mult_save = 0; + } + + if (nphy->hang_avoid) + b43_nphy_stay_in_carrier_search(dev, 0); +} + +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/IqCalGainParams */ +static void b43_nphy_iq_cal_gain_params(struct b43_wldev *dev, u16 core, + struct nphy_txgains target, + struct nphy_iqcal_params *params) +{ + int i, j, indx; + u16 gain; + + if (dev->phy.rev >= 3) { + params->txgm = target.txgm[core]; + params->pga = target.pga[core]; + params->pad = target.pad[core]; + params->ipa = target.ipa[core]; + params->cal_gain = (params->txgm << 12) | (params->pga << 8) | + (params->pad << 4) | (params->ipa); + for (j = 0; j < 5; j++) + params->ncorr[j] = 0x79; + } else { + gain = (target.pad[core]) | (target.pga[core] << 4) | + (target.txgm[core] << 8); + + indx = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ? + 1 : 0; + for (i = 0; i < 9; i++) + if (tbl_iqcal_gainparams[indx][i][0] == gain) + break; + i = min(i, 8); + + params->txgm = tbl_iqcal_gainparams[indx][i][1]; + params->pga = tbl_iqcal_gainparams[indx][i][2]; + params->pad = tbl_iqcal_gainparams[indx][i][3]; + params->cal_gain = (params->txgm << 7) | (params->pga << 4) | + (params->pad << 2); + for (j = 0; j < 4; j++) + params->ncorr[j] = tbl_iqcal_gainparams[indx][i][4 + j]; + } +} + /************************************************** * Tx and Rx **************************************************/ @@ -2290,34 +2401,6 @@ static void b43_nphy_tx_lp_fbw(struct b43_wldev *dev) } } -/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Chains */ -static void b43_nphy_update_txrx_chain(struct b43_wldev *dev) -{ - struct b43_phy_n *nphy = dev->phy.n; - - bool override = false; - u16 chain = 0x33; - - if (nphy->txrx_chain == 0) { - chain = 0x11; - override = true; - } else if (nphy->txrx_chain == 1) { - chain = 0x22; - override = true; - } - - b43_phy_maskset(dev, B43_NPHY_RFSEQCA, - ~(B43_NPHY_RFSEQCA_TXEN | B43_NPHY_RFSEQCA_RXEN), - chain); - - if (override) - b43_phy_set(dev, B43_NPHY_RFSEQMODE, - B43_NPHY_RFSEQMODE_CAOVER); - else - b43_phy_mask(dev, B43_NPHY_RFSEQMODE, - ~B43_NPHY_RFSEQMODE_CAOVER); -} - /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxIqEst */ static void b43_nphy_rx_iq_est(struct b43_wldev *dev, struct nphy_iq_est *est, u16 samps, u8 time, bool wait) @@ -2569,33 +2652,6 @@ static void b43_nphy_tx_iq_workaround(struct b43_wldev *dev) b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW3, array[3]); } -/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/stop-playback */ -static void b43_nphy_stop_playback(struct b43_wldev *dev) -{ - struct b43_phy_n *nphy = dev->phy.n; - u16 tmp; - - if (nphy->hang_avoid) - b43_nphy_stay_in_carrier_search(dev, 1); - - tmp = b43_phy_read(dev, B43_NPHY_SAMP_STAT); - if (tmp & 0x1) - b43_phy_set(dev, B43_NPHY_SAMP_CMD, B43_NPHY_SAMP_CMD_STOP); - else if (tmp & 0x2) - b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x7FFF); - - b43_phy_mask(dev, B43_NPHY_SAMP_CMD, ~0x0004); - - if (nphy->bb_mult_save & 0x80000000) { - tmp = nphy->bb_mult_save & 0xFFFF; - b43_ntab_write(dev, B43_NTAB16(15, 87), tmp); - nphy->bb_mult_save = 0; - } - - if (nphy->hang_avoid) - b43_nphy_stay_in_carrier_search(dev, 0); -} - /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SpurWar */ static void b43_nphy_spur_workaround(struct b43_wldev *dev) { @@ -2655,20 +2711,6 @@ static void b43_nphy_spur_workaround(struct b43_wldev *dev) b43_nphy_stay_in_carrier_search(dev, 0); } -/* - * Transmits a known value for LO calibration - * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TXTone - */ -static int b43_nphy_tx_tone(struct b43_wldev *dev, u32 freq, u16 max_val, - bool iqmode, bool dac_test) -{ - u16 samp = b43_nphy_gen_load_samples(dev, freq, max_val, dac_test); - if (samp == 0) - return -1; - b43_nphy_run_samples(dev, samp, 0xFFFF, 0, iqmode, dac_test); - return 0; -} - /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlCoefSetup */ static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev) { @@ -2872,44 +2914,6 @@ static void b43_nphy_tx_cal_radio_setup(struct b43_wldev *dev) } } -/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/IqCalGainParams */ -static void b43_nphy_iq_cal_gain_params(struct b43_wldev *dev, u16 core, - struct nphy_txgains target, - struct nphy_iqcal_params *params) -{ - int i, j, indx; - u16 gain; - - if (dev->phy.rev >= 3) { - params->txgm = target.txgm[core]; - params->pga = target.pga[core]; - params->pad = target.pad[core]; - params->ipa = target.ipa[core]; - params->cal_gain = (params->txgm << 12) | (params->pga << 8) | - (params->pad << 4) | (params->ipa); - for (j = 0; j < 5; j++) - params->ncorr[j] = 0x79; - } else { - gain = (target.pad[core]) | (target.pga[core] << 4) | - (target.txgm[core] << 8); - - indx = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ? - 1 : 0; - for (i = 0; i < 9; i++) - if (tbl_iqcal_gainparams[indx][i][0] == gain) - break; - i = min(i, 8); - - params->txgm = tbl_iqcal_gainparams[indx][i][1]; - params->pga = tbl_iqcal_gainparams[indx][i][2]; - params->pad = tbl_iqcal_gainparams[indx][i][3]; - params->cal_gain = (params->txgm << 7) | (params->pga << 4) | - (params->pad << 2); - for (j = 0; j < 4; j++) - params->ncorr[j] = tbl_iqcal_gainparams[indx][i][4 + j]; - } -} - /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/UpdateTxCalLadder */ static void b43_nphy_update_tx_cal_ladder(struct b43_wldev *dev, u16 core) { -- cgit v1.2.1 From 2c8ac7eb96e45997d99a5da6d0d5cdf265587437 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Tue, 20 Dec 2011 22:45:48 +0100 Subject: b43: N-PHY: fix success condition of running samples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 52503c699b2e..da6fa0360788 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -956,7 +956,7 @@ static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops, b43_phy_write(dev, B43_NPHY_SAMP_CMD, 1); } for (i = 0; i < 100; i++) { - if (b43_phy_read(dev, B43_NPHY_RFSEQST) & 1) { + if (!(b43_phy_read(dev, B43_NPHY_RFSEQST) & 1)) { i = 0; break; } -- cgit v1.2.1 From 3dda07b6f94b8f9777156be1bf37bf707ecea447 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Tue, 20 Dec 2011 22:45:49 +0100 Subject: b43: N-PHY: get idle TSSI values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 125 ++++++++++++++++++++++++++++++++++++++- drivers/net/wireless/b43/phy_n.h | 6 ++ 2 files changed, 130 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index da6fa0360788..d3222b8b594a 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -2297,6 +2297,129 @@ static void b43_nphy_tx_power_fix(struct b43_wldev *dev) b43_nphy_stay_in_carrier_search(dev, 0); } +static void b43_nphy_ipa_internal_tssi_setup(struct b43_wldev *dev) +{ + struct b43_phy *phy = &dev->phy; + + u8 core; + u16 r; /* routing */ + + if (phy->rev >= 7) { + for (core = 0; core < 2; core++) { + r = core ? 0x190 : 0x170; + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { + b43_radio_write(dev, r + 0x5, 0x5); + b43_radio_write(dev, r + 0x9, 0xE); + if (phy->rev != 5) + b43_radio_write(dev, r + 0xA, 0); + if (phy->rev != 7) + b43_radio_write(dev, r + 0xB, 1); + else + b43_radio_write(dev, r + 0xB, 0x31); + } else { + b43_radio_write(dev, r + 0x5, 0x9); + b43_radio_write(dev, r + 0x9, 0xC); + b43_radio_write(dev, r + 0xB, 0x0); + if (phy->rev != 5) + b43_radio_write(dev, r + 0xA, 1); + else + b43_radio_write(dev, r + 0xA, 0x31); + } + b43_radio_write(dev, r + 0x6, 0); + b43_radio_write(dev, r + 0x7, 0); + b43_radio_write(dev, r + 0x8, 3); + b43_radio_write(dev, r + 0xC, 0); + } + } else { + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) + b43_radio_write(dev, B2056_SYN_RESERVED_ADDR31, 0x128); + else + b43_radio_write(dev, B2056_SYN_RESERVED_ADDR31, 0x80); + b43_radio_write(dev, B2056_SYN_RESERVED_ADDR30, 0); + b43_radio_write(dev, B2056_SYN_GPIO_MASTER1, 0x29); + + for (core = 0; core < 2; core++) { + r = core ? B2056_TX1 : B2056_TX0; + + b43_radio_write(dev, r | B2056_TX_IQCAL_VCM_HG, 0); + b43_radio_write(dev, r | B2056_TX_IQCAL_IDAC, 0); + b43_radio_write(dev, r | B2056_TX_TSSI_VCM, 3); + b43_radio_write(dev, r | B2056_TX_TX_AMP_DET, 0); + b43_radio_write(dev, r | B2056_TX_TSSI_MISC1, 8); + b43_radio_write(dev, r | B2056_TX_TSSI_MISC2, 0); + b43_radio_write(dev, r | B2056_TX_TSSI_MISC3, 0); + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { + b43_radio_write(dev, r | B2056_TX_TX_SSI_MASTER, + 0x5); + if (phy->rev != 5) + b43_radio_write(dev, r | B2056_TX_TSSIA, + 0x00); + if (phy->rev >= 5) + b43_radio_write(dev, r | B2056_TX_TSSIG, + 0x31); + else + b43_radio_write(dev, r | B2056_TX_TSSIG, + 0x11); + b43_radio_write(dev, r | B2056_TX_TX_SSI_MUX, + 0xE); + } else { + b43_radio_write(dev, r | B2056_TX_TX_SSI_MASTER, + 0x9); + b43_radio_write(dev, r | B2056_TX_TSSIA, 0x31); + b43_radio_write(dev, r | B2056_TX_TSSIG, 0x0); + b43_radio_write(dev, r | B2056_TX_TX_SSI_MUX, + 0xC); + } + } + } +} + +/* + * Stop radio and transmit known signal. Then check received signal strength to + * get TSSI (Transmit Signal Strength Indicator). + * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlIdleTssi + */ +static void b43_nphy_tx_power_ctl_idle_tssi(struct b43_wldev *dev) +{ + struct b43_phy *phy = &dev->phy; + struct b43_phy_n *nphy = dev->phy.n; + + u32 tmp; + s32 rssi[4] = { }; + + /* TODO: check if we can transmit */ + + if (b43_nphy_ipa(dev)) + b43_nphy_ipa_internal_tssi_setup(dev); + + if (phy->rev >= 7) + ; /* TODO: Override Rev7 with 0x2000, 0, 3, 0, 0 as arguments */ + else if (phy->rev >= 3) + b43_nphy_rf_control_override(dev, 0x2000, 0, 3, false); + + b43_nphy_stop_playback(dev); + b43_nphy_tx_tone(dev, 0xFA0, 0, false, false); + udelay(20); + tmp = b43_nphy_poll_rssi(dev, 4, rssi, 1); + b43_nphy_stop_playback(dev); + b43_nphy_rssi_select(dev, 0, 0); + + if (phy->rev >= 7) + ; /* TODO: Override Rev7 with 0x2000, 0, 3, 1, 0 as arguments */ + else if (phy->rev >= 3) + b43_nphy_rf_control_override(dev, 0x2000, 0, 3, true); + + if (phy->rev >= 3) { + nphy->pwr_ctl_info[0].idle_tssi_5g = (tmp >> 24) & 0xFF; + nphy->pwr_ctl_info[1].idle_tssi_5g = (tmp >> 8) & 0xFF; + } else { + nphy->pwr_ctl_info[0].idle_tssi_5g = (tmp >> 16) & 0xFF; + nphy->pwr_ctl_info[1].idle_tssi_5g = tmp & 0xFF; + } + nphy->pwr_ctl_info[0].idle_tssi_2g = (tmp >> 24) & 0xFF; + nphy->pwr_ctl_info[1].idle_tssi_2g = (tmp >> 8) & 0xFF; +} + static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev) { struct b43_phy *phy = &dev->phy; @@ -3986,7 +4109,7 @@ int b43_phy_initn(struct b43_wldev *dev) tx_pwr_state = nphy->txpwrctrl; b43_nphy_tx_power_ctrl(dev, false); b43_nphy_tx_power_fix(dev); - /* TODO N PHY TX Power Control Idle TSSI */ + b43_nphy_tx_power_ctl_idle_tssi(dev); /* TODO N PHY TX Power Control Setup */ b43_nphy_tx_gain_table_upload(dev); diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h index 56ef97b5b815..5de8f74cc02f 100644 --- a/drivers/net/wireless/b43/phy_n.h +++ b/drivers/net/wireless/b43/phy_n.h @@ -765,6 +765,11 @@ struct b43_phy_n_txpwrindex { u16 locomp; }; +struct b43_phy_n_pwr_ctl_info { + u8 idle_tssi_2g; + u8 idle_tssi_5g; +}; + struct b43_phy_n { u8 antsel_type; u8 cal_orig_pwr_idx[2]; @@ -798,6 +803,7 @@ struct b43_phy_n { u16 txiqlocal_bestc[11]; bool txiqlocal_coeffsvalid; struct b43_phy_n_txpwrindex txpwrindex[2]; + struct b43_phy_n_pwr_ctl_info pwr_ctl_info[2]; struct b43_chanspec txiqlocal_chanspec; u8 txrx_chain; -- cgit v1.2.1 From 84c816dad5f5af90699ca12a520f25f9067bad79 Mon Sep 17 00:00:00 2001 From: Djalal Harouni Date: Wed, 21 Dec 2011 01:21:47 +0100 Subject: drivers/iwlwifi: use dma_zalloc_coherent() for DMA allocation Replace dma_alloc_coherent()+memset() with the new dma_zalloc_coherent() Signed-off-by: Djalal Harouni Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 409faea66b81..f7724d7f9287 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -88,18 +88,16 @@ static int iwl_trans_rx_alloc(struct iwl_trans *trans) return -EINVAL; /* Allocate the circular buffer of Read Buffer Descriptors (RBDs) */ - rxq->bd = dma_alloc_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE, - &rxq->bd_dma, GFP_KERNEL); + rxq->bd = dma_zalloc_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE, + &rxq->bd_dma, GFP_KERNEL); if (!rxq->bd) goto err_bd; - memset(rxq->bd, 0, sizeof(__le32) * RX_QUEUE_SIZE); /*Allocate the driver's pointer to receive buffer status */ - rxq->rb_stts = dma_alloc_coherent(dev, sizeof(*rxq->rb_stts), - &rxq->rb_stts_dma, GFP_KERNEL); + rxq->rb_stts = dma_zalloc_coherent(dev, sizeof(*rxq->rb_stts), + &rxq->rb_stts_dma, GFP_KERNEL); if (!rxq->rb_stts) goto err_rb_stts; - memset(rxq->rb_stts, 0, sizeof(*rxq->rb_stts)); return 0; -- cgit v1.2.1 From 6ec414fd123f847d590ba71e68b48e77bbdb3442 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 21 Dec 2011 09:27:01 -0800 Subject: ath9k: make ath_mci_duty_cycle static This fixes this sparse warning: CHECK drivers/net/wireless/ath/ath9k/mci.c drivers/net/wireless/ath/ath9k/mci.c:23:4: warning: symbol 'ath_mci_duty_cycle' was not declared. Should it be static? Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/mci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index fee8c6f0b251..05c23ea4c633 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c @@ -20,7 +20,7 @@ #include "ath9k.h" #include "mci.h" -u8 ath_mci_duty_cycle[] = { 0, 50, 60, 70, 80, 85, 90, 95, 98 }; +static const u8 ath_mci_duty_cycle[] = { 0, 50, 60, 70, 80, 85, 90, 95, 98 }; static struct ath_mci_profile_info* ath_mci_find_profile(struct ath_mci_profile *mci, -- cgit v1.2.1 From cc96adddbb04ead9ed9e844f6336f7cdfebbb407 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 22 Dec 2011 00:47:16 +0100 Subject: b43: add lacking boardflags defines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/b43.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index f19605e8eb4c..16e8f8058155 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -191,6 +191,9 @@ #define B43_BFH_BUCKBOOST 0x0020 /* has buck/booster */ #define B43_BFH_FEM_BT 0x0040 /* has FEM and switch to share antenna * with bluetooth */ +#define B43_BFH_NOCBUCK 0x0080 +#define B43_BFH_PALDO 0x0200 +#define B43_BFH_EXTLNA_5GHZ 0x1000 /* has an external LNA (5GHz mode) */ /* SPROM boardflags2_lo values */ #define B43_BFL2_RXBB_INT_REG_DIS 0x0001 /* external RX BB regulator present */ @@ -204,6 +207,14 @@ #define B43_BFL2_SKWRKFEM_BRD 0x0100 /* 4321mcm93 uses Skyworks FEM */ #define B43_BFL2_SPUR_WAR 0x0200 /* has a workaround for clock-harmonic spurs */ #define B43_BFL2_GPLL_WAR 0x0400 /* altenative G-band PLL settings implemented */ +#define B43_BFL2_SINGLEANT_CCK 0x1000 +#define B43_BFL2_2G_SPUR_WAR 0x2000 + +/* SPROM boardflags2_hi values */ +#define B43_BFH2_GPLL_WAR2 0x0001 +#define B43_BFH2_IPALVLSHIFT_3P3 0x0002 +#define B43_BFH2_INTERNDET_TXIQCAL 0x0004 +#define B43_BFH2_XTALBUFOUTEN 0x0008 /* GPIO register offset, in both ChipCommon and PCI core. */ #define B43_GPIO_CONTROL 0x6c -- cgit v1.2.1 From ed5103edc217aea9e2018178971ad4ff0d40a9b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 22 Dec 2011 00:47:17 +0100 Subject: b43: N-PHY: update gain ctl workarounds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Specs were updated, now we match wl according to MMIO dumps. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 4 +- drivers/net/wireless/b43/tables_nphy.c | 106 ++++++++++++++++++++++++++++----- 2 files changed, 92 insertions(+), 18 deletions(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index d3222b8b594a..38cf37d41ff5 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -1511,7 +1511,8 @@ static void b43_nphy_gain_ctl_workarounds_rev3plus(struct b43_wldev *dev) /* Prepare values */ ghz5 = b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ; - ext_lna = sprom->boardflags_lo & B43_BFL_EXTLNA; + ext_lna = ghz5 ? sprom->boardflags_hi & B43_BFH_EXTLNA_5GHZ : + sprom->boardflags_lo & B43_BFL_EXTLNA; e = b43_nphy_get_gain_ctl_workaround_ent(dev, ghz5, ext_lna); if (ghz5 && dev->phy.rev >= 5) rssi_gain = 0x90; @@ -1562,7 +1563,6 @@ static void b43_nphy_gain_ctl_workarounds_rev3plus(struct b43_wldev *dev) b43_phy_write(dev, 0x2A7, e->init_gain); b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x106), 2, e->rfseq_init); - b43_phy_write(dev, B43_NPHY_C1_INITGAIN, e->init_gain); /* TODO: check defines. Do not match variables names */ b43_phy_write(dev, B43_NPHY_C1_CLIP1_MEDGAIN, e->cliphi_gain); diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index 3252560e9fa1..f7def13524dd 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c @@ -2752,7 +2752,18 @@ const struct nphy_rf_control_override_rev3 tbl_rf_control_override_rev3[] = { { 0x00C0, 6, 0xE7, 0xF9, 0xEC, 0xFB } /* field == 0x4000 (fls 15) */ }; -struct nphy_gain_ctl_workaround_entry nphy_gain_ctl_workaround[2][3] = { +struct nphy_gain_ctl_workaround_entry nphy_gain_ctl_wa_phy6_radio11_ghz2 = { + { 10, 14, 19, 27 }, + { -5, 6, 10, 15 }, + { 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA }, + { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + 0x427E, + { 0x413F, 0x413F, 0x413F, 0x413F }, + 0x007E, 0x0066, 0x1074, + 0x18, 0x18, 0x18, + 0x01D0, 0x5, +}; +struct nphy_gain_ctl_workaround_entry nphy_gain_ctl_workaround[2][4] = { { /* 2GHz */ { /* PHY rev 3 */ { 7, 11, 16, 23 }, @@ -2776,15 +2787,26 @@ struct nphy_gain_ctl_workaround_entry nphy_gain_ctl_workaround[2][3] = { 0x18, 0x18, 0x18, 0x01A1, 0x5, }, - { /* PHY rev 5+ */ + { /* PHY rev 5 */ { 9, 13, 18, 26 }, { -3, 7, 11, 16 }, { 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA }, { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, 0x427E, /* invalid for external LNA! */ { 0x413F, 0x413F, 0x413F, 0x413F }, /* invalid for external LNA! */ - 0x1076, 0x0066, 0x106A, - 0xC, 0xC, 0xC, + 0x1076, 0x0066, 0x0000, /* low is invalid (the last one) */ + 0x18, 0x18, 0x18, + 0x01D0, 0x9, + }, + { /* PHY rev 6+ */ + { 8, 13, 18, 25 }, + { -5, 6, 10, 14 }, + { 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA }, + { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + 0x527E, /* invalid for external LNA! */ + { 0x513F, 0x513F, 0x513F, 0x513F }, /* invalid for external LNA! */ + 0x1076, 0x0066, 0x0000, /* low is invalid (the last one) */ + 0x18, 0x18, 0x18, 0x01D0, 0x5, }, }, @@ -2811,7 +2833,7 @@ struct nphy_gain_ctl_workaround_entry nphy_gain_ctl_workaround[2][3] = { 0x24, 0x24, 0x24, 0x0107, 25, }, - { /* PHY rev 5+ */ + { /* PHY rev 5 */ { 6, 10, 16, 21 }, { -7, 0, 4, 8 }, { 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD }, @@ -2822,6 +2844,17 @@ struct nphy_gain_ctl_workaround_entry nphy_gain_ctl_workaround[2][3] = { 0x24, 0x24, 0x24, 0x00A9, 25, }, + { /* PHY rev 6+ */ + { 6, 10, 16, 21 }, + { -7, 0, 4, 8 }, + { 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD }, + { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }, + 0x729E, + { 0x714F, 0x714F, 0x714F, 0x714F }, + 0x029E, 0x2084, 0x2086, + 0x24, 0x24, 0x24, /* low is invalid for radio rev 11! */ + 0x00F0, 25, + }, }, }; @@ -3098,26 +3131,67 @@ struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent( { struct nphy_gain_ctl_workaround_entry *e; u8 phy_idx; + u8 tr_iso = ghz5 ? dev->dev->bus_sprom->fem.ghz5.tr_iso : + dev->dev->bus_sprom->fem.ghz2.tr_iso; + + if (!ghz5 && dev->phy.rev >= 6 && dev->phy.radio_rev == 11) + return &nphy_gain_ctl_wa_phy6_radio11_ghz2; B43_WARN_ON(dev->phy.rev < 3); - if (dev->phy.rev >= 5) + if (dev->phy.rev >= 6) + phy_idx = 3; + else if (dev->phy.rev == 5) phy_idx = 2; else if (dev->phy.rev == 4) phy_idx = 1; else phy_idx = 0; - e = &nphy_gain_ctl_workaround[ghz5][phy_idx]; - /* Only one entry differs for external LNA, so instead making whole - * table 2 times bigger, hack is here - */ - if (!ghz5 && dev->phy.rev >= 5 && ext_lna) { - e->rfseq_init[0] &= 0x0FFF; - e->rfseq_init[1] &= 0x0FFF; - e->rfseq_init[2] &= 0x0FFF; - e->rfseq_init[3] &= 0x0FFF; - e->init_gain &= 0x0FFF; + /* Some workarounds to the workarounds... */ + if (ghz5 && dev->phy.rev >= 6) { + if (dev->phy.radio_rev == 11 && + !b43_channel_type_is_40mhz(dev->phy.channel_type)) + e->cliplo_gain = 0x2d; + } else if (!ghz5 && dev->phy.rev >= 5) { + if (ext_lna) { + e->rfseq_init[0] &= ~0x4000; + e->rfseq_init[1] &= ~0x4000; + e->rfseq_init[2] &= ~0x4000; + e->rfseq_init[3] &= ~0x4000; + e->init_gain &= ~0x4000; + } + switch (tr_iso) { + case 0: + e->cliplo_gain = 0x0062; + case 1: + e->cliplo_gain = 0x0064; + case 2: + e->cliplo_gain = 0x006a; + case 3: + e->cliplo_gain = 0x106a; + case 4: + e->cliplo_gain = 0x106c; + case 5: + e->cliplo_gain = 0x1074; + case 6: + e->cliplo_gain = 0x107c; + case 7: + e->cliplo_gain = 0x207c; + default: + e->cliplo_gain = 0x106a; + } + } else if (ghz5 && dev->phy.rev == 4 && ext_lna) { + e->rfseq_init[0] &= ~0x4000; + e->rfseq_init[1] &= ~0x4000; + e->rfseq_init[2] &= ~0x4000; + e->rfseq_init[3] &= ~0x4000; + e->init_gain &= ~0x4000; + e->rfseq_init[0] |= 0x1000; + e->rfseq_init[1] |= 0x1000; + e->rfseq_init[2] |= 0x1000; + e->rfseq_init[3] |= 0x1000; + e->init_gain |= 0x1000; } return e; -- cgit v1.2.1 From b97c071840ccc2c8016de87c21a95c9286415448 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 22 Dec 2011 00:47:18 +0100 Subject: b43: N-PHY: fix controling RF override MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 38cf37d41ff5..b8525cca410e 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -167,7 +167,7 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field, b43_phy_mask(dev, val_addr, ~(rf_ctrl->val_mask)); } else { - if (core == 0 || ((1 << core) & i) != 0) { + if (core == 0 || ((1 << i) & core)) { b43_phy_set(dev, en_addr, field); b43_phy_maskset(dev, val_addr, ~(rf_ctrl->val_mask), @@ -200,7 +200,7 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field, addr = B43_PHY_N((i == 0) ? rf_ctrl->addr0 : rf_ctrl->addr1); - if ((core & (1 << i)) != 0) + if ((1 << i) & core) b43_phy_maskset(dev, addr, ~(rf_ctrl->bmask), (value << rf_ctrl->shift)); -- cgit v1.2.1 From 9bd2857188d920f358cfb740fc6f88e1a17a837e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 22 Dec 2011 00:47:19 +0100 Subject: b43: N-PHY: fix typo in TX power fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index b8525cca410e..aadfed056204 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -2218,7 +2218,7 @@ static void b43_nphy_tx_power_fix(struct b43_wldev *dev) } } if (dev->phy.rev < 7 && - (txpi[0] < 40 || txpi[0] > 100 || txpi[1] < 40 || txpi[1] > 10)) + (txpi[0] < 40 || txpi[0] > 100 || txpi[1] < 40 || txpi[1] > 100)) txpi[0] = txpi[1] = 91; /* -- cgit v1.2.1 From 5d07a3d62f63f3a9ce769c37108f8411c014903e Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Wed, 21 Dec 2011 18:47:59 -0600 Subject: b43legacy: Avoid packet losses in the dma worker code This patch addresses a bug in the dma worker code that keeps draining packets even when the hardware queues are full. In such cases packets can not be passed down to the device and are erroneusly dropped by the code. It is based on commit bad6919469662b7c92bc6353642aaaa777b36bac, which fixes the same problem in b43. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/b43legacy/b43legacy.h | 20 +++++++ drivers/net/wireless/b43legacy/dma.c | 65 ++++++++++++---------- drivers/net/wireless/b43legacy/dma.h | 5 +- drivers/net/wireless/b43legacy/main.c | 86 +++++++++++++++++++++++------- 4 files changed, 126 insertions(+), 50 deletions(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h index 1d4fc9db7f5e..98e3d44400c6 100644 --- a/drivers/net/wireless/b43legacy/b43legacy.h +++ b/drivers/net/wireless/b43legacy/b43legacy.h @@ -560,8 +560,16 @@ struct b43legacy_key { u8 algorithm; }; +#define B43legacy_QOS_QUEUE_NUM 4 + struct b43legacy_wldev; +/* QOS parameters for a queue. */ +struct b43legacy_qos_params { + /* The QOS parameters */ + struct ieee80211_tx_queue_params p; +}; + /* Data structure for the WLAN parts (802.11 cores) of the b43legacy chip. */ struct b43legacy_wl { /* Pointer to the active wireless device on this chip */ @@ -611,6 +619,18 @@ struct b43legacy_wl { bool beacon1_uploaded; bool beacon_templates_virgin; /* Never wrote the templates? */ struct work_struct beacon_update_trigger; + /* The current QOS parameters for the 4 queues. */ + struct b43legacy_qos_params qos_params[B43legacy_QOS_QUEUE_NUM]; + + /* Packet transmit work */ + struct work_struct tx_work; + + /* Queue of packets to be transmitted. */ + struct sk_buff_head tx_queue[B43legacy_QOS_QUEUE_NUM]; + + /* Flag that implement the queues stopping. */ + bool tx_queue_stopped[B43legacy_QOS_QUEUE_NUM]; + }; /* Pointers to the firmware data and meta information about it. */ diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c index c5535adf6991..aebef75a2c62 100644 --- a/drivers/net/wireless/b43legacy/dma.c +++ b/drivers/net/wireless/b43legacy/dma.c @@ -727,7 +727,6 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, } else B43legacy_WARN_ON(1); } - spin_lock_init(&ring->lock); #ifdef CONFIG_B43LEGACY_DEBUG ring->last_injected_overflow = jiffies; #endif @@ -1144,10 +1143,8 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev, { struct b43legacy_dmaring *ring; int err = 0; - unsigned long flags; ring = priority_to_txring(dev, skb_get_queue_mapping(skb)); - spin_lock_irqsave(&ring->lock, flags); B43legacy_WARN_ON(!ring->tx); if (unlikely(ring->stopped)) { @@ -1157,16 +1154,14 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev, * For now, just refuse the transmit. */ if (b43legacy_debug(dev, B43legacy_DBG_DMAVERBOSE)) b43legacyerr(dev->wl, "Packet after queue stopped\n"); - err = -ENOSPC; - goto out_unlock; + return -ENOSPC; } if (unlikely(WARN_ON(free_slots(ring) < SLOTS_PER_PACKET))) { /* If we get here, we have a real error with the queue * full, but queues not stopped. */ b43legacyerr(dev->wl, "DMA queue overflow\n"); - err = -ENOSPC; - goto out_unlock; + return -ENOSPC; } /* dma_tx_fragment might reallocate the skb, so invalidate pointers pointing @@ -1176,25 +1171,23 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev, /* Drop this packet, as we don't have the encryption key * anymore and must not transmit it unencrypted. */ dev_kfree_skb_any(skb); - err = 0; - goto out_unlock; + return 0; } if (unlikely(err)) { b43legacyerr(dev->wl, "DMA tx mapping failure\n"); - goto out_unlock; + return err; } if ((free_slots(ring) < SLOTS_PER_PACKET) || should_inject_overflow(ring)) { /* This TX ring is full. */ - ieee80211_stop_queue(dev->wl->hw, txring_to_priority(ring)); + unsigned int skb_mapping = skb_get_queue_mapping(skb); + ieee80211_stop_queue(dev->wl->hw, skb_mapping); + dev->wl->tx_queue_stopped[skb_mapping] = 1; ring->stopped = 1; if (b43legacy_debug(dev, B43legacy_DBG_DMAVERBOSE)) b43legacydbg(dev->wl, "Stopped TX ring %d\n", ring->index); } -out_unlock: - spin_unlock_irqrestore(&ring->lock, flags); - return err; } @@ -1205,14 +1198,29 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev, struct b43legacy_dmadesc_meta *meta; int retry_limit; int slot; + int firstused; ring = parse_cookie(dev, status->cookie, &slot); if (unlikely(!ring)) return; - B43legacy_WARN_ON(!irqs_disabled()); - spin_lock(&ring->lock); - B43legacy_WARN_ON(!ring->tx); + + /* Sanity check: TX packets are processed in-order on one ring. + * Check if the slot deduced from the cookie really is the first + * used slot. */ + firstused = ring->current_slot - ring->used_slots + 1; + if (firstused < 0) + firstused = ring->nr_slots + firstused; + if (unlikely(slot != firstused)) { + /* This possibly is a firmware bug and will result in + * malfunction, memory leaks and/or stall of DMA functionality. + */ + b43legacydbg(dev->wl, "Out of order TX status report on DMA " + "ring %d. Expected %d, but got %d\n", + ring->index, firstused, slot); + return; + } + while (1) { B43legacy_WARN_ON(!(slot >= 0 && slot < ring->nr_slots)); op32_idx2desc(ring, slot, &meta); @@ -1285,14 +1293,21 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev, dev->stats.last_tx = jiffies; if (ring->stopped) { B43legacy_WARN_ON(free_slots(ring) < SLOTS_PER_PACKET); - ieee80211_wake_queue(dev->wl->hw, txring_to_priority(ring)); ring->stopped = 0; + } + + if (dev->wl->tx_queue_stopped[ring->queue_prio]) { + dev->wl->tx_queue_stopped[ring->queue_prio] = 0; + } else { + /* If the driver queue is running wake the corresponding + * mac80211 queue. */ + ieee80211_wake_queue(dev->wl->hw, ring->queue_prio); if (b43legacy_debug(dev, B43legacy_DBG_DMAVERBOSE)) b43legacydbg(dev->wl, "Woke up TX ring %d\n", - ring->index); + ring->index); } - - spin_unlock(&ring->lock); + /* Add work to the queue. */ + ieee80211_queue_work(dev->wl->hw, &dev->wl->tx_work); } static void dma_rx(struct b43legacy_dmaring *ring, @@ -1415,22 +1430,14 @@ void b43legacy_dma_rx(struct b43legacy_dmaring *ring) static void b43legacy_dma_tx_suspend_ring(struct b43legacy_dmaring *ring) { - unsigned long flags; - - spin_lock_irqsave(&ring->lock, flags); B43legacy_WARN_ON(!ring->tx); op32_tx_suspend(ring); - spin_unlock_irqrestore(&ring->lock, flags); } static void b43legacy_dma_tx_resume_ring(struct b43legacy_dmaring *ring) { - unsigned long flags; - - spin_lock_irqsave(&ring->lock, flags); B43legacy_WARN_ON(!ring->tx); op32_tx_resume(ring); - spin_unlock_irqrestore(&ring->lock, flags); } void b43legacy_dma_tx_suspend(struct b43legacy_wldev *dev) diff --git a/drivers/net/wireless/b43legacy/dma.h b/drivers/net/wireless/b43legacy/dma.h index 504a58767e95..c3282f906bc7 100644 --- a/drivers/net/wireless/b43legacy/dma.h +++ b/drivers/net/wireless/b43legacy/dma.h @@ -150,8 +150,9 @@ struct b43legacy_dmaring { enum b43legacy_dmatype type; /* Boolean. Is this ring stopped at ieee80211 level? */ bool stopped; - /* Lock, only used for TX. */ - spinlock_t lock; + /* The QOS priority assigned to this ring. Only used for TX rings. + * This is the mac80211 "queue" value. */ + u8 queue_prio; struct b43legacy_wldev *dev; #ifdef CONFIG_B43LEGACY_DEBUG /* Maximum number of used slots. */ diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 20f02437af8c..d9185633e82f 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -2440,30 +2440,64 @@ static int b43legacy_rng_init(struct b43legacy_wl *wl) return err; } +static void b43legacy_tx_work(struct work_struct *work) +{ + struct b43legacy_wl *wl = container_of(work, struct b43legacy_wl, + tx_work); + struct b43legacy_wldev *dev; + struct sk_buff *skb; + int queue_num; + int err = 0; + + mutex_lock(&wl->mutex); + dev = wl->current_dev; + if (unlikely(!dev || b43legacy_status(dev) < B43legacy_STAT_STARTED)) { + mutex_unlock(&wl->mutex); + return; + } + + for (queue_num = 0; queue_num < B43legacy_QOS_QUEUE_NUM; queue_num++) { + while (skb_queue_len(&wl->tx_queue[queue_num])) { + skb = skb_dequeue(&wl->tx_queue[queue_num]); + if (b43legacy_using_pio(dev)) + err = b43legacy_pio_tx(dev, skb); + else + err = b43legacy_dma_tx(dev, skb); + if (err == -ENOSPC) { + wl->tx_queue_stopped[queue_num] = 1; + ieee80211_stop_queue(wl->hw, queue_num); + skb_queue_head(&wl->tx_queue[queue_num], skb); + break; + } + if (unlikely(err)) + dev_kfree_skb(skb); /* Drop it */ + err = 0; + } + + if (!err) + wl->tx_queue_stopped[queue_num] = 0; + } + + mutex_unlock(&wl->mutex); +} + static void b43legacy_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); - struct b43legacy_wldev *dev = wl->current_dev; - int err = -ENODEV; - unsigned long flags; - if (unlikely(!dev)) - goto out; - if (unlikely(b43legacy_status(dev) < B43legacy_STAT_STARTED)) - goto out; - /* DMA-TX is done without a global lock. */ - if (b43legacy_using_pio(dev)) { - spin_lock_irqsave(&wl->irq_lock, flags); - err = b43legacy_pio_tx(dev, skb); - spin_unlock_irqrestore(&wl->irq_lock, flags); - } else - err = b43legacy_dma_tx(dev, skb); -out: - if (unlikely(err)) { - /* Drop the packet. */ + if (unlikely(skb->len < 2 + 2 + 6)) { + /* Too short, this can't be a valid frame. */ dev_kfree_skb_any(skb); + return; } + B43legacy_WARN_ON(skb_shinfo(skb)->nr_frags); + + skb_queue_tail(&wl->tx_queue[skb->queue_mapping], skb); + if (!wl->tx_queue_stopped[skb->queue_mapping]) + ieee80211_queue_work(wl->hw, &wl->tx_work); + else + ieee80211_stop_queue(wl->hw, skb->queue_mapping); } static int b43legacy_op_conf_tx(struct ieee80211_hw *hw, @@ -2879,6 +2913,7 @@ static void b43legacy_wireless_core_stop(struct b43legacy_wldev *dev) { struct b43legacy_wl *wl = dev->wl; unsigned long flags; + int queue_num; if (b43legacy_status(dev) < B43legacy_STAT_STARTED) return; @@ -2898,11 +2933,16 @@ static void b43legacy_wireless_core_stop(struct b43legacy_wldev *dev) /* Must unlock as it would otherwise deadlock. No races here. * Cancel the possibly running self-rearming periodic work. */ cancel_delayed_work_sync(&dev->periodic_work); + cancel_work_sync(&wl->tx_work); mutex_lock(&wl->mutex); - ieee80211_stop_queues(wl->hw); /* FIXME this could cause a deadlock */ + /* Drain all TX queues. */ + for (queue_num = 0; queue_num < B43legacy_QOS_QUEUE_NUM; queue_num++) { + while (skb_queue_len(&wl->tx_queue[queue_num])) + dev_kfree_skb(skb_dequeue(&wl->tx_queue[queue_num])); + } - b43legacy_mac_suspend(dev); +b43legacy_mac_suspend(dev); free_irq(dev->dev->irq, dev); b43legacydbg(wl, "Wireless interface stopped\n"); } @@ -3748,6 +3788,7 @@ static int b43legacy_wireless_init(struct ssb_device *dev) struct ieee80211_hw *hw; struct b43legacy_wl *wl; int err = -ENOMEM; + int queue_num; b43legacy_sprom_fixup(dev->bus); @@ -3782,6 +3823,13 @@ static int b43legacy_wireless_init(struct ssb_device *dev) mutex_init(&wl->mutex); INIT_LIST_HEAD(&wl->devlist); INIT_WORK(&wl->beacon_update_trigger, b43legacy_beacon_update_trigger_work); + INIT_WORK(&wl->tx_work, b43legacy_tx_work); + + /* Initialize queues and flags. */ + for (queue_num = 0; queue_num < B43legacy_QOS_QUEUE_NUM; queue_num++) { + skb_queue_head_init(&wl->tx_queue[queue_num]); + wl->tx_queue_stopped[queue_num] = 0; + } ssb_set_devtypedata(dev, wl); b43legacyinfo(wl, "Broadcom %04X WLAN found (core revision %u)\n", -- cgit v1.2.1 From 9931df2692ddb7db092550ce063e674730176ecf Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 22 Dec 2011 09:36:29 +0100 Subject: rt2x00: Mark active channel's survey data as "in use" This is just a cosmetical fix since we only return survey data for the active channel but it allows iw to show that the survey data is for the currently used channel. Signed-off-by: Helmut Schaa Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index e5df380d4fbe..4cae051daebb 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -4554,6 +4554,9 @@ int rt2800_get_survey(struct ieee80211_hw *hw, int idx, survey->channel_time_ext_busy = busy_ext / 1000; } + if (!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) + survey->filled |= SURVEY_INFO_IN_USE; + return 0; } -- cgit v1.2.1 From 2b20920d639da3ee275fcc691431b5b3daa9a3e7 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 23 Dec 2011 08:13:41 +0100 Subject: iwlegacy: remove iwl-sta.c I forgot to remove this file before. Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/iwl-sta.c | 817 -------------------------------- 1 file changed, 817 deletions(-) delete mode 100644 drivers/net/wireless/iwlegacy/iwl-sta.c (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/iwlegacy/iwl-sta.c b/drivers/net/wireless/iwlegacy/iwl-sta.c deleted file mode 100644 index 75fe315f66b4..000000000000 --- a/drivers/net/wireless/iwlegacy/iwl-sta.c +++ /dev/null @@ -1,817 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. - * - * Portions of this file are derived from the ipw3945 project, as well - * as portions of the ieee80211 subsystem header files. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#include -#include -#include -#include -#include - -#include "iwl-dev.h" -#include "iwl-core.h" -#include "iwl-sta.h" - -/* il->sta_lock must be held */ -static void il_sta_ucode_activate(struct il_priv *il, u8 sta_id) -{ - - if (!(il->stations[sta_id].used & IL_STA_DRIVER_ACTIVE)) - IL_ERR( - "ACTIVATE a non DRIVER active station id %u addr %pM\n", - sta_id, il->stations[sta_id].sta.sta.addr); - - if (il->stations[sta_id].used & IL_STA_UCODE_ACTIVE) { - D_ASSOC( - "STA id %u addr %pM already present" - " in uCode (according to driver)\n", - sta_id, il->stations[sta_id].sta.sta.addr); - } else { - il->stations[sta_id].used |= IL_STA_UCODE_ACTIVE; - D_ASSOC("Added STA id %u addr %pM to uCode\n", - sta_id, il->stations[sta_id].sta.sta.addr); - } -} - -static int il_process_add_sta_resp(struct il_priv *il, - struct il_addsta_cmd *addsta, - struct il_rx_pkt *pkt, - bool sync) -{ - u8 sta_id = addsta->sta.sta_id; - unsigned long flags; - int ret = -EIO; - - if (pkt->hdr.flags & IL_CMD_FAILED_MSK) { - IL_ERR("Bad return from C_ADD_STA (0x%08X)\n", - pkt->hdr.flags); - return ret; - } - - D_INFO("Processing response for adding station %u\n", - sta_id); - - spin_lock_irqsave(&il->sta_lock, flags); - - switch (pkt->u.add_sta.status) { - case ADD_STA_SUCCESS_MSK: - D_INFO("C_ADD_STA PASSED\n"); - il_sta_ucode_activate(il, sta_id); - ret = 0; - break; - case ADD_STA_NO_ROOM_IN_TBL: - IL_ERR("Adding station %d failed, no room in table.\n", - sta_id); - break; - case ADD_STA_NO_BLOCK_ACK_RESOURCE: - IL_ERR( - "Adding station %d failed, no block ack resource.\n", - sta_id); - break; - case ADD_STA_MODIFY_NON_EXIST_STA: - IL_ERR("Attempting to modify non-existing station %d\n", - sta_id); - break; - default: - D_ASSOC("Received C_ADD_STA:(0x%08X)\n", - pkt->u.add_sta.status); - break; - } - - D_INFO("%s station id %u addr %pM\n", - il->stations[sta_id].sta.mode == - STA_CONTROL_MODIFY_MSK ? "Modified" : "Added", - sta_id, il->stations[sta_id].sta.sta.addr); - - /* - * XXX: The MAC address in the command buffer is often changed from - * the original sent to the device. That is, the MAC address - * written to the command buffer often is not the same MAC address - * read from the command buffer when the command returns. This - * issue has not yet been resolved and this debugging is left to - * observe the problem. - */ - D_INFO("%s station according to cmd buffer %pM\n", - il->stations[sta_id].sta.mode == - STA_CONTROL_MODIFY_MSK ? "Modified" : "Added", - addsta->sta.addr); - spin_unlock_irqrestore(&il->sta_lock, flags); - - return ret; -} - -static void il_add_sta_callback(struct il_priv *il, - struct il_device_cmd *cmd, - struct il_rx_pkt *pkt) -{ - struct il_addsta_cmd *addsta = - (struct il_addsta_cmd *)cmd->cmd.payload; - - il_process_add_sta_resp(il, addsta, pkt, false); - -} - -int il_send_add_sta(struct il_priv *il, - struct il_addsta_cmd *sta, u8 flags) -{ - struct il_rx_pkt *pkt = NULL; - int ret = 0; - u8 data[sizeof(*sta)]; - struct il_host_cmd cmd = { - .id = C_ADD_STA, - .flags = flags, - .data = data, - }; - u8 sta_id __maybe_unused = sta->sta.sta_id; - - D_INFO("Adding sta %u (%pM) %ssynchronously\n", - sta_id, sta->sta.addr, flags & CMD_ASYNC ? "a" : ""); - - if (flags & CMD_ASYNC) - cmd.callback = il_add_sta_callback; - else { - cmd.flags |= CMD_WANT_SKB; - might_sleep(); - } - - cmd.len = il->cfg->ops->utils->build_addsta_hcmd(sta, data); - ret = il_send_cmd(il, &cmd); - - if (ret || (flags & CMD_ASYNC)) - return ret; - - if (ret == 0) { - pkt = (struct il_rx_pkt *)cmd.reply_page; - ret = il_process_add_sta_resp(il, sta, pkt, true); - } - il_free_pages(il, cmd.reply_page); - - return ret; -} -EXPORT_SYMBOL(il_send_add_sta); - -static void il_set_ht_add_station(struct il_priv *il, u8 idx, - struct ieee80211_sta *sta, - struct il_rxon_context *ctx) -{ - struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap; - __le32 sta_flags; - u8 mimo_ps_mode; - - if (!sta || !sta_ht_inf->ht_supported) - goto done; - - mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2; - D_ASSOC("spatial multiplexing power save mode: %s\n", - (mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ? - "static" : - (mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ? - "dynamic" : "disabled"); - - sta_flags = il->stations[idx].sta.station_flags; - - sta_flags &= ~(STA_FLG_RTS_MIMO_PROT_MSK | STA_FLG_MIMO_DIS_MSK); - - switch (mimo_ps_mode) { - case WLAN_HT_CAP_SM_PS_STATIC: - sta_flags |= STA_FLG_MIMO_DIS_MSK; - break; - case WLAN_HT_CAP_SM_PS_DYNAMIC: - sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK; - break; - case WLAN_HT_CAP_SM_PS_DISABLED: - break; - default: - IL_WARN("Invalid MIMO PS mode %d\n", mimo_ps_mode); - break; - } - - sta_flags |= cpu_to_le32( - (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS); - - sta_flags |= cpu_to_le32( - (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); - - if (il_is_ht40_tx_allowed(il, ctx, &sta->ht_cap)) - sta_flags |= STA_FLG_HT40_EN_MSK; - else - sta_flags &= ~STA_FLG_HT40_EN_MSK; - - il->stations[idx].sta.station_flags = sta_flags; - done: - return; -} - -/** - * il_prep_station - Prepare station information for addition - * - * should be called with sta_lock held - */ -u8 il_prep_station(struct il_priv *il, struct il_rxon_context *ctx, - const u8 *addr, bool is_ap, struct ieee80211_sta *sta) -{ - struct il_station_entry *station; - int i; - u8 sta_id = IL_INVALID_STATION; - u16 rate; - - if (is_ap) - sta_id = ctx->ap_sta_id; - else if (is_broadcast_ether_addr(addr)) - sta_id = ctx->bcast_sta_id; - else - for (i = IL_STA_ID; i < il->hw_params.max_stations; i++) { - if (!compare_ether_addr(il->stations[i].sta.sta.addr, - addr)) { - sta_id = i; - break; - } - - if (!il->stations[i].used && - sta_id == IL_INVALID_STATION) - sta_id = i; - } - - /* - * These two conditions have the same outcome, but keep them - * separate - */ - if (unlikely(sta_id == IL_INVALID_STATION)) - return sta_id; - - /* - * uCode is not able to deal with multiple requests to add a - * station. Keep track if one is in progress so that we do not send - * another. - */ - if (il->stations[sta_id].used & IL_STA_UCODE_INPROGRESS) { - D_INFO( - "STA %d already in process of being added.\n", - sta_id); - return sta_id; - } - - if ((il->stations[sta_id].used & IL_STA_DRIVER_ACTIVE) && - (il->stations[sta_id].used & IL_STA_UCODE_ACTIVE) && - !compare_ether_addr(il->stations[sta_id].sta.sta.addr, addr)) { - D_ASSOC( - "STA %d (%pM) already added, not adding again.\n", - sta_id, addr); - return sta_id; - } - - station = &il->stations[sta_id]; - station->used = IL_STA_DRIVER_ACTIVE; - D_ASSOC("Add STA to driver ID %d: %pM\n", - sta_id, addr); - il->num_stations++; - - /* Set up the C_ADD_STA command to send to device */ - memset(&station->sta, 0, sizeof(struct il_addsta_cmd)); - memcpy(station->sta.sta.addr, addr, ETH_ALEN); - station->sta.mode = 0; - station->sta.sta.sta_id = sta_id; - station->sta.station_flags = ctx->station_flags; - station->ctxid = ctx->ctxid; - - if (sta) { - struct il_station_priv_common *sta_priv; - - sta_priv = (void *)sta->drv_priv; - sta_priv->ctx = ctx; - } - - /* - * OK to call unconditionally, since local stations (IBSS BSSID - * STA and broadcast STA) pass in a NULL sta, and mac80211 - * doesn't allow HT IBSS. - */ - il_set_ht_add_station(il, sta_id, sta, ctx); - - /* 3945 only */ - rate = (il->band == IEEE80211_BAND_5GHZ) ? - RATE_6M_PLCP : RATE_1M_PLCP; - /* Turn on both antennas for the station... */ - station->sta.rate_n_flags = cpu_to_le16(rate | RATE_MCS_ANT_AB_MSK); - - return sta_id; - -} -EXPORT_SYMBOL_GPL(il_prep_station); - -#define STA_WAIT_TIMEOUT (HZ/2) - -/** - * il_add_station_common - - */ -int -il_add_station_common(struct il_priv *il, - struct il_rxon_context *ctx, - const u8 *addr, bool is_ap, - struct ieee80211_sta *sta, u8 *sta_id_r) -{ - unsigned long flags_spin; - int ret = 0; - u8 sta_id; - struct il_addsta_cmd sta_cmd; - - *sta_id_r = 0; - spin_lock_irqsave(&il->sta_lock, flags_spin); - sta_id = il_prep_station(il, ctx, addr, is_ap, sta); - if (sta_id == IL_INVALID_STATION) { - IL_ERR("Unable to prepare station %pM for addition\n", - addr); - spin_unlock_irqrestore(&il->sta_lock, flags_spin); - return -EINVAL; - } - - /* - * uCode is not able to deal with multiple requests to add a - * station. Keep track if one is in progress so that we do not send - * another. - */ - if (il->stations[sta_id].used & IL_STA_UCODE_INPROGRESS) { - D_INFO( - "STA %d already in process of being added.\n", - sta_id); - spin_unlock_irqrestore(&il->sta_lock, flags_spin); - return -EEXIST; - } - - if ((il->stations[sta_id].used & IL_STA_DRIVER_ACTIVE) && - (il->stations[sta_id].used & IL_STA_UCODE_ACTIVE)) { - D_ASSOC( - "STA %d (%pM) already added, not adding again.\n", - sta_id, addr); - spin_unlock_irqrestore(&il->sta_lock, flags_spin); - return -EEXIST; - } - - il->stations[sta_id].used |= IL_STA_UCODE_INPROGRESS; - memcpy(&sta_cmd, &il->stations[sta_id].sta, - sizeof(struct il_addsta_cmd)); - spin_unlock_irqrestore(&il->sta_lock, flags_spin); - - /* Add station to device's station table */ - ret = il_send_add_sta(il, &sta_cmd, CMD_SYNC); - if (ret) { - spin_lock_irqsave(&il->sta_lock, flags_spin); - IL_ERR("Adding station %pM failed.\n", - il->stations[sta_id].sta.sta.addr); - il->stations[sta_id].used &= ~IL_STA_DRIVER_ACTIVE; - il->stations[sta_id].used &= ~IL_STA_UCODE_INPROGRESS; - spin_unlock_irqrestore(&il->sta_lock, flags_spin); - } - *sta_id_r = sta_id; - return ret; -} -EXPORT_SYMBOL(il_add_station_common); - -/** - * il_sta_ucode_deactivate - deactivate ucode status for a station - * - * il->sta_lock must be held - */ -static void il_sta_ucode_deactivate(struct il_priv *il, u8 sta_id) -{ - /* Ucode must be active and driver must be non active */ - if ((il->stations[sta_id].used & - (IL_STA_UCODE_ACTIVE | IL_STA_DRIVER_ACTIVE)) != - IL_STA_UCODE_ACTIVE) - IL_ERR("removed non active STA %u\n", sta_id); - - il->stations[sta_id].used &= ~IL_STA_UCODE_ACTIVE; - - memset(&il->stations[sta_id], 0, sizeof(struct il_station_entry)); - D_ASSOC("Removed STA %u\n", sta_id); -} - -static int il_send_remove_station(struct il_priv *il, - const u8 *addr, int sta_id, - bool temporary) -{ - struct il_rx_pkt *pkt; - int ret; - - unsigned long flags_spin; - struct il_rem_sta_cmd rm_sta_cmd; - - struct il_host_cmd cmd = { - .id = C_REM_STA, - .len = sizeof(struct il_rem_sta_cmd), - .flags = CMD_SYNC, - .data = &rm_sta_cmd, - }; - - memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd)); - rm_sta_cmd.num_sta = 1; - memcpy(&rm_sta_cmd.addr, addr, ETH_ALEN); - - cmd.flags |= CMD_WANT_SKB; - - ret = il_send_cmd(il, &cmd); - - if (ret) - return ret; - - pkt = (struct il_rx_pkt *)cmd.reply_page; - if (pkt->hdr.flags & IL_CMD_FAILED_MSK) { - IL_ERR("Bad return from C_REM_STA (0x%08X)\n", - pkt->hdr.flags); - ret = -EIO; - } - - if (!ret) { - switch (pkt->u.rem_sta.status) { - case REM_STA_SUCCESS_MSK: - if (!temporary) { - spin_lock_irqsave(&il->sta_lock, flags_spin); - il_sta_ucode_deactivate(il, sta_id); - spin_unlock_irqrestore(&il->sta_lock, - flags_spin); - } - D_ASSOC("C_REM_STA PASSED\n"); - break; - default: - ret = -EIO; - IL_ERR("C_REM_STA failed\n"); - break; - } - } - il_free_pages(il, cmd.reply_page); - - return ret; -} - -/** - * il_remove_station - Remove driver's knowledge of station. - */ -int il_remove_station(struct il_priv *il, const u8 sta_id, - const u8 *addr) -{ - unsigned long flags; - - if (!il_is_ready(il)) { - D_INFO( - "Unable to remove station %pM, device not ready.\n", - addr); - /* - * It is typical for stations to be removed when we are - * going down. Return success since device will be down - * soon anyway - */ - return 0; - } - - D_ASSOC("Removing STA from driver:%d %pM\n", - sta_id, addr); - - if (WARN_ON(sta_id == IL_INVALID_STATION)) - return -EINVAL; - - spin_lock_irqsave(&il->sta_lock, flags); - - if (!(il->stations[sta_id].used & IL_STA_DRIVER_ACTIVE)) { - D_INFO("Removing %pM but non DRIVER active\n", - addr); - goto out_err; - } - - if (!(il->stations[sta_id].used & IL_STA_UCODE_ACTIVE)) { - D_INFO("Removing %pM but non UCODE active\n", - addr); - goto out_err; - } - - if (il->stations[sta_id].used & IL_STA_LOCAL) { - kfree(il->stations[sta_id].lq); - il->stations[sta_id].lq = NULL; - } - - il->stations[sta_id].used &= ~IL_STA_DRIVER_ACTIVE; - - il->num_stations--; - - BUG_ON(il->num_stations < 0); - - spin_unlock_irqrestore(&il->sta_lock, flags); - - return il_send_remove_station(il, addr, sta_id, false); -out_err: - spin_unlock_irqrestore(&il->sta_lock, flags); - return -EINVAL; -} -EXPORT_SYMBOL_GPL(il_remove_station); - -/** - * il_clear_ucode_stations - clear ucode station table bits - * - * This function clears all the bits in the driver indicating - * which stations are active in the ucode. Call when something - * other than explicit station management would cause this in - * the ucode, e.g. unassociated RXON. - */ -void il_clear_ucode_stations(struct il_priv *il, - struct il_rxon_context *ctx) -{ - int i; - unsigned long flags_spin; - bool cleared = false; - - D_INFO("Clearing ucode stations in driver\n"); - - spin_lock_irqsave(&il->sta_lock, flags_spin); - for (i = 0; i < il->hw_params.max_stations; i++) { - if (ctx && ctx->ctxid != il->stations[i].ctxid) - continue; - - if (il->stations[i].used & IL_STA_UCODE_ACTIVE) { - D_INFO( - "Clearing ucode active for station %d\n", i); - il->stations[i].used &= ~IL_STA_UCODE_ACTIVE; - cleared = true; - } - } - spin_unlock_irqrestore(&il->sta_lock, flags_spin); - - if (!cleared) - D_INFO( - "No active stations found to be cleared\n"); -} -EXPORT_SYMBOL(il_clear_ucode_stations); - -/** - * il_restore_stations() - Restore driver known stations to device - * - * All stations considered active by driver, but not present in ucode, is - * restored. - * - * Function sleeps. - */ -void -il_restore_stations(struct il_priv *il, struct il_rxon_context *ctx) -{ - struct il_addsta_cmd sta_cmd; - struct il_link_quality_cmd lq; - unsigned long flags_spin; - int i; - bool found = false; - int ret; - bool send_lq; - - if (!il_is_ready(il)) { - D_INFO( - "Not ready yet, not restoring any stations.\n"); - return; - } - - D_ASSOC("Restoring all known stations ... start.\n"); - spin_lock_irqsave(&il->sta_lock, flags_spin); - for (i = 0; i < il->hw_params.max_stations; i++) { - if (ctx->ctxid != il->stations[i].ctxid) - continue; - if ((il->stations[i].used & IL_STA_DRIVER_ACTIVE) && - !(il->stations[i].used & IL_STA_UCODE_ACTIVE)) { - D_ASSOC("Restoring sta %pM\n", - il->stations[i].sta.sta.addr); - il->stations[i].sta.mode = 0; - il->stations[i].used |= IL_STA_UCODE_INPROGRESS; - found = true; - } - } - - for (i = 0; i < il->hw_params.max_stations; i++) { - if ((il->stations[i].used & IL_STA_UCODE_INPROGRESS)) { - memcpy(&sta_cmd, &il->stations[i].sta, - sizeof(struct il_addsta_cmd)); - send_lq = false; - if (il->stations[i].lq) { - memcpy(&lq, il->stations[i].lq, - sizeof(struct il_link_quality_cmd)); - send_lq = true; - } - spin_unlock_irqrestore(&il->sta_lock, flags_spin); - ret = il_send_add_sta(il, &sta_cmd, CMD_SYNC); - if (ret) { - spin_lock_irqsave(&il->sta_lock, flags_spin); - IL_ERR("Adding station %pM failed.\n", - il->stations[i].sta.sta.addr); - il->stations[i].used &= - ~IL_STA_DRIVER_ACTIVE; - il->stations[i].used &= - ~IL_STA_UCODE_INPROGRESS; - spin_unlock_irqrestore(&il->sta_lock, - flags_spin); - } - /* - * Rate scaling has already been initialized, send - * current LQ command - */ - if (send_lq) - il_send_lq_cmd(il, ctx, &lq, - CMD_SYNC, true); - spin_lock_irqsave(&il->sta_lock, flags_spin); - il->stations[i].used &= ~IL_STA_UCODE_INPROGRESS; - } - } - - spin_unlock_irqrestore(&il->sta_lock, flags_spin); - if (!found) - D_INFO("Restoring all known stations" - " .... no stations to be restored.\n"); - else - D_INFO("Restoring all known stations" - " .... complete.\n"); -} -EXPORT_SYMBOL(il_restore_stations); - -int il_get_free_ucode_key_idx(struct il_priv *il) -{ - int i; - - for (i = 0; i < il->sta_key_max_num; i++) - if (!test_and_set_bit(i, &il->ucode_key_table)) - return i; - - return WEP_INVALID_OFFSET; -} -EXPORT_SYMBOL(il_get_free_ucode_key_idx); - -void il_dealloc_bcast_stations(struct il_priv *il) -{ - unsigned long flags; - int i; - - spin_lock_irqsave(&il->sta_lock, flags); - for (i = 0; i < il->hw_params.max_stations; i++) { - if (!(il->stations[i].used & IL_STA_BCAST)) - continue; - - il->stations[i].used &= ~IL_STA_UCODE_ACTIVE; - il->num_stations--; - BUG_ON(il->num_stations < 0); - kfree(il->stations[i].lq); - il->stations[i].lq = NULL; - } - spin_unlock_irqrestore(&il->sta_lock, flags); -} -EXPORT_SYMBOL_GPL(il_dealloc_bcast_stations); - -#ifdef CONFIG_IWLEGACY_DEBUG -static void il_dump_lq_cmd(struct il_priv *il, - struct il_link_quality_cmd *lq) -{ - int i; - D_RATE("lq station id 0x%x\n", lq->sta_id); - D_RATE("lq ant 0x%X 0x%X\n", - lq->general_params.single_stream_ant_msk, - lq->general_params.dual_stream_ant_msk); - - for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) - D_RATE("lq idx %d 0x%X\n", - i, lq->rs_table[i].rate_n_flags); -} -#else -static inline void il_dump_lq_cmd(struct il_priv *il, - struct il_link_quality_cmd *lq) -{ -} -#endif - -/** - * il_is_lq_table_valid() - Test one aspect of LQ cmd for validity - * - * It sometimes happens when a HT rate has been in use and we - * loose connectivity with AP then mac80211 will first tell us that the - * current channel is not HT anymore before removing the station. In such a - * scenario the RXON flags will be updated to indicate we are not - * communicating HT anymore, but the LQ command may still contain HT rates. - * Test for this to prevent driver from sending LQ command between the time - * RXON flags are updated and when LQ command is updated. - */ -static bool il_is_lq_table_valid(struct il_priv *il, - struct il_rxon_context *ctx, - struct il_link_quality_cmd *lq) -{ - int i; - - if (ctx->ht.enabled) - return true; - - D_INFO("Channel %u is not an HT channel\n", - ctx->active.channel); - for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) { - if (le32_to_cpu(lq->rs_table[i].rate_n_flags) & - RATE_MCS_HT_MSK) { - D_INFO( - "idx %d of LQ expects HT channel\n", - i); - return false; - } - } - return true; -} - -/** - * il_send_lq_cmd() - Send link quality command - * @init: This command is sent as part of station initialization right - * after station has been added. - * - * The link quality command is sent as the last step of station creation. - * This is the special case in which init is set and we call a callback in - * this case to clear the state indicating that station creation is in - * progress. - */ -int il_send_lq_cmd(struct il_priv *il, struct il_rxon_context *ctx, - struct il_link_quality_cmd *lq, u8 flags, bool init) -{ - int ret = 0; - unsigned long flags_spin; - - struct il_host_cmd cmd = { - .id = C_TX_LINK_QUALITY_CMD, - .len = sizeof(struct il_link_quality_cmd), - .flags = flags, - .data = lq, - }; - - if (WARN_ON(lq->sta_id == IL_INVALID_STATION)) - return -EINVAL; - - - spin_lock_irqsave(&il->sta_lock, flags_spin); - if (!(il->stations[lq->sta_id].used & IL_STA_DRIVER_ACTIVE)) { - spin_unlock_irqrestore(&il->sta_lock, flags_spin); - return -EINVAL; - } - spin_unlock_irqrestore(&il->sta_lock, flags_spin); - - il_dump_lq_cmd(il, lq); - BUG_ON(init && (cmd.flags & CMD_ASYNC)); - - if (il_is_lq_table_valid(il, ctx, lq)) - ret = il_send_cmd(il, &cmd); - else - ret = -EINVAL; - - if (cmd.flags & CMD_ASYNC) - return ret; - - if (init) { - D_INFO("init LQ command complete," - " clearing sta addition status for sta %d\n", - lq->sta_id); - spin_lock_irqsave(&il->sta_lock, flags_spin); - il->stations[lq->sta_id].used &= ~IL_STA_UCODE_INPROGRESS; - spin_unlock_irqrestore(&il->sta_lock, flags_spin); - } - return ret; -} -EXPORT_SYMBOL(il_send_lq_cmd); - -int il_mac_sta_remove(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) -{ - struct il_priv *il = hw->priv; - struct il_station_priv_common *sta_common = (void *)sta->drv_priv; - int ret; - - D_INFO("received request to remove station %pM\n", - sta->addr); - mutex_lock(&il->mutex); - D_INFO("proceeding to remove station %pM\n", - sta->addr); - ret = il_remove_station(il, sta_common->sta_id, sta->addr); - if (ret) - IL_ERR("Error removing station %pM\n", - sta->addr); - mutex_unlock(&il->mutex); - return ret; -} -EXPORT_SYMBOL(il_mac_sta_remove); -- cgit v1.2.1 From d71be937202853eda76562e9678073465d5c0fa8 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 23 Dec 2011 08:13:42 +0100 Subject: iwlegacy: off by one in iwl3945_hw_build_tx_cmd_rate() We use "rate_index" like this: rate = iwl3945_rates[rate_index].plcp; The iwl3945_rates[] array has IWL_RATE_COUNT_3945 elements so the limit here is off by one. Signed-off-by: Dan Carpenter Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/3945.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c index 863664f9ba8b..0b99deb48426 100644 --- a/drivers/net/wireless/iwlegacy/3945.c +++ b/drivers/net/wireless/iwlegacy/3945.c @@ -683,7 +683,7 @@ il3945_hw_build_tx_cmd_rate(struct il_priv *il, struct il_device_cmd *cmd, struct ieee80211_hdr *hdr, int sta_id, int tx_id) { u16 hw_value = ieee80211_get_tx_rate(il->hw, info)->hw_value; - u16 rate_idx = min(hw_value & 0xffff, RATE_COUNT_3945); + u16 rate_idx = min(hw_value & 0xffff, RATE_COUNT_3945 - 1); u16 rate_mask; int rate; u8 rts_retry_limit; -- cgit v1.2.1 From 17d4eca6432bb1d4753d7894b824271673a1640a Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 23 Dec 2011 08:13:43 +0100 Subject: iwlegacy: move some i/o helpers out of inline This save us about 20k of text size, and should have no impact on performance as hot paths do not use much I/O. Before: text data bss dec hex filename 108512 1784 168 110464 1af80 drivers/net/wireless/iwlegacy/iwl3945.ko 165730 2164 156 168050 29072 drivers/net/wireless/iwlegacy/iwl4965.ko 91942 328 48 92318 1689e drivers/net/wireless/iwlegacy/iwlegacy.ko After: text data bss dec hex filename 95556 1784 168 97508 17ce4 drivers/net/wireless/iwlegacy/iwl3945.ko 154853 2164 156 157173 265f5 drivers/net/wireless/iwlegacy/iwl4965.ko 91634 328 48 92010 1676a drivers/net/wireless/iwlegacy/iwlegacy.ko Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/common.c | 161 ++++++++++++++++++++++++++ drivers/net/wireless/iwlegacy/common.h | 206 +++------------------------------ 2 files changed, 175 insertions(+), 192 deletions(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index 881ba043770a..36454d0bbeed 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -42,6 +42,167 @@ #include "common.h" +int +_il_poll_bit(struct il_priv *il, u32 addr, u32 bits, u32 mask, int timeout) +{ + const int interval = 10; /* microseconds */ + int t = 0; + + do { + if ((_il_rd(il, addr) & mask) == (bits & mask)) + return t; + udelay(interval); + t += interval; + } while (t < timeout); + + return -ETIMEDOUT; +} +EXPORT_SYMBOL(_il_poll_bit); + +void +il_set_bit(struct il_priv *p, u32 r, u32 m) +{ + unsigned long reg_flags; + + spin_lock_irqsave(&p->reg_lock, reg_flags); + _il_set_bit(p, r, m); + spin_unlock_irqrestore(&p->reg_lock, reg_flags); +} +EXPORT_SYMBOL(il_set_bit); + +void +il_clear_bit(struct il_priv *p, u32 r, u32 m) +{ + unsigned long reg_flags; + + spin_lock_irqsave(&p->reg_lock, reg_flags); + _il_clear_bit(p, r, m); + spin_unlock_irqrestore(&p->reg_lock, reg_flags); +} +EXPORT_SYMBOL(il_clear_bit); + +int +_il_grab_nic_access(struct il_priv *il) +{ + int ret; + u32 val; + + /* this bit wakes up the NIC */ + _il_set_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + + /* + * These bits say the device is running, and should keep running for + * at least a short while (at least as long as MAC_ACCESS_REQ stays 1), + * but they do not indicate that embedded SRAM is restored yet; + * 3945 and 4965 have volatile SRAM, and must save/restore contents + * to/from host DRAM when sleeping/waking for power-saving. + * Each direction takes approximately 1/4 millisecond; with this + * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a + * series of register accesses are expected (e.g. reading Event Log), + * to keep device from sleeping. + * + * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that + * SRAM is okay/restored. We don't check that here because this call + * is just for hardware register access; but GP1 MAC_SLEEP check is a + * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log). + * + */ + ret = + _il_poll_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, + (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | + CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); + if (ret < 0) { + val = _il_rd(il, CSR_GP_CNTRL); + IL_ERR("MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val); + _il_wr(il, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI); + return -EIO; + } + + return 0; +} +EXPORT_SYMBOL_GPL(_il_grab_nic_access); + +int +il_poll_bit(struct il_priv *il, u32 addr, u32 mask, int timeout) +{ + const int interval = 10; /* microseconds */ + int t = 0; + + do { + if ((il_rd(il, addr) & mask) == mask) + return t; + udelay(interval); + t += interval; + } while (t < timeout); + + return -ETIMEDOUT; +} +EXPORT_SYMBOL(il_poll_bit); + +u32 +il_rd_prph(struct il_priv *il, u32 reg) +{ + unsigned long reg_flags; + u32 val; + + spin_lock_irqsave(&il->reg_lock, reg_flags); + _il_grab_nic_access(il); + val = _il_rd_prph(il, reg); + _il_release_nic_access(il); + spin_unlock_irqrestore(&il->reg_lock, reg_flags); + return val; +} +EXPORT_SYMBOL(il_rd_prph); + +void +il_wr_prph(struct il_priv *il, u32 addr, u32 val) +{ + unsigned long reg_flags; + + spin_lock_irqsave(&il->reg_lock, reg_flags); + if (!_il_grab_nic_access(il)) { + _il_wr_prph(il, addr, val); + _il_release_nic_access(il); + } + spin_unlock_irqrestore(&il->reg_lock, reg_flags); +} +EXPORT_SYMBOL(il_wr_prph); + +u32 +il_read_targ_mem(struct il_priv *il, u32 addr) +{ + unsigned long reg_flags; + u32 value; + + spin_lock_irqsave(&il->reg_lock, reg_flags); + _il_grab_nic_access(il); + + _il_wr(il, HBUS_TARG_MEM_RADDR, addr); + rmb(); + value = _il_rd(il, HBUS_TARG_MEM_RDAT); + + _il_release_nic_access(il); + spin_unlock_irqrestore(&il->reg_lock, reg_flags); + return value; +} +EXPORT_SYMBOL(il_read_targ_mem); + +void +il_write_targ_mem(struct il_priv *il, u32 addr, u32 val) +{ + unsigned long reg_flags; + + spin_lock_irqsave(&il->reg_lock, reg_flags); + if (!_il_grab_nic_access(il)) { + _il_wr(il, HBUS_TARG_MEM_WADDR, addr); + wmb(); + _il_wr(il, HBUS_TARG_MEM_WDAT, val); + _il_release_nic_access(il); + } + spin_unlock_irqrestore(&il->reg_lock, reg_flags); +} +EXPORT_SYMBOL(il_write_targ_mem); + const char * il_get_cmd_string(u8 cmd) { diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index 1bc0b02f559c..abfa388588be 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -2163,7 +2164,15 @@ void il_tx_cmd_protection(struct il_priv *il, struct ieee80211_tx_info *info, irqreturn_t il_isr(int irq, void *data); -#include +extern void il_set_bit(struct il_priv *p, u32 r, u32 m); +extern void il_clear_bit(struct il_priv *p, u32 r, u32 m); +extern int _il_grab_nic_access(struct il_priv *il); +extern int _il_poll_bit(struct il_priv *il, u32 addr, u32 bits, u32 mask, int timeout); +extern int il_poll_bit(struct il_priv *il, u32 addr, u32 mask, int timeout); +extern u32 il_rd_prph(struct il_priv *il, u32 reg); +extern void il_wr_prph(struct il_priv *il, u32 addr, u32 val); +extern u32 il_read_targ_mem(struct il_priv *il, u32 addr); +extern void il_write_targ_mem(struct il_priv *il, u32 addr, u32 val); static inline void _il_write8(struct il_priv *il, u32 ofs, u8 val) @@ -2184,38 +2193,6 @@ _il_rd(struct il_priv *il, u32 ofs) return ioread32(il->hw_base + ofs); } -#define IL_POLL_INTERVAL 10 /* microseconds */ -static inline int -_il_poll_bit(struct il_priv *il, u32 addr, u32 bits, u32 mask, int timeout) -{ - int t = 0; - - do { - if ((_il_rd(il, addr) & mask) == (bits & mask)) - return t; - udelay(IL_POLL_INTERVAL); - t += IL_POLL_INTERVAL; - } while (t < timeout); - - return -ETIMEDOUT; -} - -static inline void -_il_set_bit(struct il_priv *il, u32 reg, u32 mask) -{ - _il_wr(il, reg, _il_rd(il, reg) | mask); -} - -static inline void -il_set_bit(struct il_priv *p, u32 r, u32 m) -{ - unsigned long reg_flags; - - spin_lock_irqsave(&p->reg_lock, reg_flags); - _il_set_bit(p, r, m); - spin_unlock_irqrestore(&p->reg_lock, reg_flags); -} - static inline void _il_clear_bit(struct il_priv *il, u32 reg, u32 mask) { @@ -2223,53 +2200,9 @@ _il_clear_bit(struct il_priv *il, u32 reg, u32 mask) } static inline void -il_clear_bit(struct il_priv *p, u32 r, u32 m) -{ - unsigned long reg_flags; - - spin_lock_irqsave(&p->reg_lock, reg_flags); - _il_clear_bit(p, r, m); - spin_unlock_irqrestore(&p->reg_lock, reg_flags); -} - -static inline int -_il_grab_nic_access(struct il_priv *il) +_il_set_bit(struct il_priv *il, u32 reg, u32 mask) { - int ret; - u32 val; - - /* this bit wakes up the NIC */ - _il_set_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); - - /* - * These bits say the device is running, and should keep running for - * at least a short while (at least as long as MAC_ACCESS_REQ stays 1), - * but they do not indicate that embedded SRAM is restored yet; - * 3945 and 4965 have volatile SRAM, and must save/restore contents - * to/from host DRAM when sleeping/waking for power-saving. - * Each direction takes approximately 1/4 millisecond; with this - * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a - * series of register accesses are expected (e.g. reading Event Log), - * to keep device from sleeping. - * - * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that - * SRAM is okay/restored. We don't check that here because this call - * is just for hardware register access; but GP1 MAC_SLEEP check is a - * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log). - * - */ - ret = - _il_poll_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, - (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | - CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); - if (ret < 0) { - val = _il_rd(il, CSR_GP_CNTRL); - IL_ERR("MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val); - _il_wr(il, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI); - return -EIO; - } - - return 0; + _il_wr(il, reg, _il_rd(il, reg) | mask); } static inline void @@ -2290,7 +2223,6 @@ il_rd(struct il_priv *il, u32 reg) _il_release_nic_access(il); spin_unlock_irqrestore(&il->reg_lock, reg_flags); return value; - } static inline void @@ -2306,32 +2238,6 @@ il_wr(struct il_priv *il, u32 reg, u32 value) spin_unlock_irqrestore(&il->reg_lock, reg_flags); } -static inline void -il_write_reg_buf(struct il_priv *il, u32 reg, u32 len, u32 * values) -{ - u32 count = sizeof(u32); - - if (il != NULL && values != NULL) { - for (; 0 < len; len -= count, reg += count, values++) - il_wr(il, reg, *values); - } -} - -static inline int -il_poll_bit(struct il_priv *il, u32 addr, u32 mask, int timeout) -{ - int t = 0; - - do { - if ((il_rd(il, addr) & mask) == mask) - return t; - udelay(IL_POLL_INTERVAL); - t += IL_POLL_INTERVAL; - } while (t < timeout); - - return -ETIMEDOUT; -} - static inline u32 _il_rd_prph(struct il_priv *il, u32 reg) { @@ -2340,20 +2246,6 @@ _il_rd_prph(struct il_priv *il, u32 reg) return _il_rd(il, HBUS_TARG_PRPH_RDAT); } -static inline u32 -il_rd_prph(struct il_priv *il, u32 reg) -{ - unsigned long reg_flags; - u32 val; - - spin_lock_irqsave(&il->reg_lock, reg_flags); - _il_grab_nic_access(il); - val = _il_rd_prph(il, reg); - _il_release_nic_access(il); - spin_unlock_irqrestore(&il->reg_lock, reg_flags); - return val; -} - static inline void _il_wr_prph(struct il_priv *il, u32 addr, u32 val) { @@ -2362,22 +2254,6 @@ _il_wr_prph(struct il_priv *il, u32 addr, u32 val) _il_wr(il, HBUS_TARG_PRPH_WDAT, val); } -static inline void -il_wr_prph(struct il_priv *il, u32 addr, u32 val) -{ - unsigned long reg_flags; - - spin_lock_irqsave(&il->reg_lock, reg_flags); - if (!_il_grab_nic_access(il)) { - _il_wr_prph(il, addr, val); - _il_release_nic_access(il); - } - spin_unlock_irqrestore(&il->reg_lock, reg_flags); -} - -#define _il_set_bits_prph(il, reg, mask) \ -_il_wr_prph(il, reg, (_il_rd_prph(il, reg) | mask)) - static inline void il_set_bits_prph(struct il_priv *il, u32 reg, u32 mask) { @@ -2385,15 +2261,11 @@ il_set_bits_prph(struct il_priv *il, u32 reg, u32 mask) spin_lock_irqsave(&il->reg_lock, reg_flags); _il_grab_nic_access(il); - _il_set_bits_prph(il, reg, mask); + _il_wr_prph(il, reg, (_il_rd_prph(il, reg) | mask)); _il_release_nic_access(il); spin_unlock_irqrestore(&il->reg_lock, reg_flags); } -#define _il_set_bits_mask_prph(il, reg, bits, mask) \ -_il_wr_prph(il, reg, \ - ((_il_rd_prph(il, reg) & mask) | bits)) - static inline void il_set_bits_mask_prph(struct il_priv *il, u32 reg, u32 bits, u32 mask) { @@ -2401,7 +2273,7 @@ il_set_bits_mask_prph(struct il_priv *il, u32 reg, u32 bits, u32 mask) spin_lock_irqsave(&il->reg_lock, reg_flags); _il_grab_nic_access(il); - _il_set_bits_mask_prph(il, reg, bits, mask); + _il_wr_prph(il, reg, ((_il_rd_prph(il, reg) & mask) | bits)); _il_release_nic_access(il); spin_unlock_irqrestore(&il->reg_lock, reg_flags); } @@ -2420,56 +2292,6 @@ il_clear_bits_prph(struct il_priv *il, u32 reg, u32 mask) spin_unlock_irqrestore(&il->reg_lock, reg_flags); } -static inline u32 -il_read_targ_mem(struct il_priv *il, u32 addr) -{ - unsigned long reg_flags; - u32 value; - - spin_lock_irqsave(&il->reg_lock, reg_flags); - _il_grab_nic_access(il); - - _il_wr(il, HBUS_TARG_MEM_RADDR, addr); - rmb(); - value = _il_rd(il, HBUS_TARG_MEM_RDAT); - - _il_release_nic_access(il); - spin_unlock_irqrestore(&il->reg_lock, reg_flags); - return value; -} - -static inline void -il_write_targ_mem(struct il_priv *il, u32 addr, u32 val) -{ - unsigned long reg_flags; - - spin_lock_irqsave(&il->reg_lock, reg_flags); - if (!_il_grab_nic_access(il)) { - _il_wr(il, HBUS_TARG_MEM_WADDR, addr); - wmb(); - _il_wr(il, HBUS_TARG_MEM_WDAT, val); - _il_release_nic_access(il); - } - spin_unlock_irqrestore(&il->reg_lock, reg_flags); -} - -static inline void -il_write_targ_mem_buf(struct il_priv *il, u32 addr, u32 len, u32 * values) -{ - unsigned long reg_flags; - - spin_lock_irqsave(&il->reg_lock, reg_flags); - if (!_il_grab_nic_access(il)) { - _il_wr(il, HBUS_TARG_MEM_WADDR, addr); - wmb(); - for (; 0 < len; len -= sizeof(u32), values++) - _il_wr(il, HBUS_TARG_MEM_WDAT, *values); - - _il_release_nic_access(il); - } - spin_unlock_irqrestore(&il->reg_lock, reg_flags); -} - #define HW_KEY_DYNAMIC 0 #define HW_KEY_DEFAULT 1 -- cgit v1.2.1 From a0c1ef3b12f88c0ed7683472395145e491808b4b Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 23 Dec 2011 08:13:44 +0100 Subject: iwlegacy: 4965: toggle tx antenna inline Make function static and change antenna number inline. Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/4965-mac.c | 41 ++++++++++++++------------------ drivers/net/wireless/iwlegacy/4965.h | 2 -- 2 files changed, 18 insertions(+), 25 deletions(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 4aaef4135564..e1dfb2c4f832 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -825,6 +825,21 @@ il4965_ant_idx_to_flags(u8 ant_idx) return BIT(ant_idx) << RATE_MCS_ANT_POS; } +static void +il4965_toggle_tx_ant(struct il_priv *il, u8 *ant, u8 valid) +{ + int i; + u8 ind = *ant; + + for (i = 0; i < RATE_ANT_NUM - 1; i++) { + ind = (ind + 1) < RATE_ANT_NUM ? ind + 1 : 0; + if (valid & BIT(ind)) { + *ant = ind; + return; + } + } +} + int il4965_request_scan(struct il_priv *il, struct ieee80211_vif *vif) { @@ -960,8 +975,7 @@ il4965_request_scan(struct il_priv *il, struct ieee80211_vif *vif) if (il->cfg->scan_rx_antennas[band]) rx_ant = il->cfg->scan_rx_antennas[band]; - il->scan_tx_ant[band] = - il4965_toggle_tx_ant(il, il->scan_tx_ant[band], scan_tx_antennas); + il4965_toggle_tx_ant(il, &il->scan_tx_ant[band], scan_tx_antennas); rate_flags |= il4965_ant_idx_to_flags(il->scan_tx_ant[band]); scan->tx_cmd.rate_n_flags = il4965_hw_set_rate_n_flags(rate, rate_flags); @@ -1171,20 +1185,6 @@ il4965_set_rxon_chain(struct il_priv *il, struct il_rxon_context *ctx) active_rx_cnt < idle_rx_cnt); } -u8 -il4965_toggle_tx_ant(struct il_priv *il, u8 ant, u8 valid) -{ - int i; - u8 ind = ant; - - for (i = 0; i < RATE_ANT_NUM - 1; i++) { - ind = (ind + 1) < RATE_ANT_NUM ? ind + 1 : 0; - if (valid & BIT(ind)) - return ind; - } - return ant; -} - static const char * il4965_get_fh_string(int cmd) { @@ -1588,10 +1588,7 @@ il4965_tx_cmd_build_rate(struct il_priv *il, struct il_tx_cmd *tx_cmd, rate_flags |= RATE_MCS_CCK_MSK; /* Set up antennas */ - il->mgmt_tx_ant = - il4965_toggle_tx_ant(il, il->mgmt_tx_ant, - il->hw_params.valid_tx_ant); - + il4965_toggle_tx_ant(il, &il->mgmt_tx_ant, il->hw_params.valid_tx_ant); rate_flags |= il4965_ant_idx_to_flags(il->mgmt_tx_ant); /* Set the rate in the TX cmd */ @@ -3540,9 +3537,7 @@ il4965_hw_get_beacon_cmd(struct il_priv *il, struct il_frame *frame) /* Set up packet rate and flags */ rate = il_get_lowest_plcp(il, il->beacon_ctx); - il->mgmt_tx_ant = - il4965_toggle_tx_ant(il, il->mgmt_tx_ant, - il->hw_params.valid_tx_ant); + il4965_toggle_tx_ant(il, &il->mgmt_tx_ant, il->hw_params.valid_tx_ant); rate_flags = il4965_ant_idx_to_flags(il->mgmt_tx_ant); if ((rate >= IL_FIRST_CCK_RATE) && (rate <= IL_LAST_CCK_RATE)) rate_flags |= RATE_MCS_CCK_MSK; diff --git a/drivers/net/wireless/iwlegacy/4965.h b/drivers/net/wireless/iwlegacy/4965.h index 74472314bc37..ca254aa4fd35 100644 --- a/drivers/net/wireless/iwlegacy/4965.h +++ b/drivers/net/wireless/iwlegacy/4965.h @@ -107,8 +107,6 @@ void il4965_set_wr_ptrs(struct il_priv *il, int txq_id, u32 idx); void il4965_tx_queue_set_status(struct il_priv *il, struct il_tx_queue *txq, int tx_fifo_id, int scd_retry); -u8 il4965_toggle_tx_ant(struct il_priv *il, u8 ant_idx, u8 valid); - /* rx */ void il4965_hdl_missed_beacon(struct il_priv *il, struct il_rx_buf *rxb); bool il4965_good_plcp_health(struct il_priv *il, struct il_rx_pkt *pkt); -- cgit v1.2.1 From 616107ed818876076bc482d3a33f89c31297b86e Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 23 Dec 2011 08:13:45 +0100 Subject: iwlegacy: 4965: small tx_cmd build cleanup Get rid of two inline functions related and simplify a bit rts_retry_limit calculations. Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/4965-mac.c | 33 +++++++++----------------------- drivers/net/wireless/iwlegacy/4965.h | 6 ------ 2 files changed, 9 insertions(+), 30 deletions(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index e1dfb2c4f832..cefc623f19ea 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -819,12 +819,6 @@ il4965_get_channels_for_scan(struct il_priv *il, struct ieee80211_vif *vif, return added; } -static inline u32 -il4965_ant_idx_to_flags(u8 ant_idx) -{ - return BIT(ant_idx) << RATE_MCS_ANT_POS; -} - static void il4965_toggle_tx_ant(struct il_priv *il, u8 *ant, u8 valid) { @@ -976,9 +970,8 @@ il4965_request_scan(struct il_priv *il, struct ieee80211_vif *vif) rx_ant = il->cfg->scan_rx_antennas[band]; il4965_toggle_tx_ant(il, &il->scan_tx_ant[band], scan_tx_antennas); - rate_flags |= il4965_ant_idx_to_flags(il->scan_tx_ant[band]); - scan->tx_cmd.rate_n_flags = - il4965_hw_set_rate_n_flags(rate, rate_flags); + rate_flags |= BIT(il->scan_tx_ant[band]) << RATE_MCS_ANT_POS; + scan->tx_cmd.rate_n_flags = cpu_to_le32(rate | rate_flags); /* In power save mode use one chain, otherwise use all chains */ if (test_bit(S_POWER_PMI, &il->status)) { @@ -1530,15 +1523,13 @@ il4965_tx_cmd_build_basic(struct il_priv *il, struct sk_buff *skb, tx_cmd->next_frame_len = 0; } -#define RTS_DFAULT_RETRY_LIMIT 60 - static void il4965_tx_cmd_build_rate(struct il_priv *il, struct il_tx_cmd *tx_cmd, struct ieee80211_tx_info *info, __le16 fc) { + const u8 rts_retry_limit = 60; u32 rate_flags; int rate_idx; - u8 rts_retry_limit; u8 data_retry_limit; u8 rate_plcp; @@ -1548,12 +1539,8 @@ il4965_tx_cmd_build_rate(struct il_priv *il, struct il_tx_cmd *tx_cmd, else data_retry_limit = IL4965_DEFAULT_TX_RETRY; tx_cmd->data_retry_limit = data_retry_limit; - /* Set retry limit on RTS packets */ - rts_retry_limit = RTS_DFAULT_RETRY_LIMIT; - if (data_retry_limit < rts_retry_limit) - rts_retry_limit = data_retry_limit; - tx_cmd->rts_retry_limit = rts_retry_limit; + tx_cmd->rts_retry_limit = min(data_retry_limit, rts_retry_limit); /* DATA packets will use the uCode station table for rate/antenna * selection */ @@ -1589,11 +1576,10 @@ il4965_tx_cmd_build_rate(struct il_priv *il, struct il_tx_cmd *tx_cmd, /* Set up antennas */ il4965_toggle_tx_ant(il, &il->mgmt_tx_ant, il->hw_params.valid_tx_ant); - rate_flags |= il4965_ant_idx_to_flags(il->mgmt_tx_ant); + rate_flags |= BIT(il->mgmt_tx_ant) << RATE_MCS_ANT_POS; /* Set the rate in the TX cmd */ - tx_cmd->rate_n_flags = - il4965_hw_set_rate_n_flags(rate_plcp, rate_flags); + tx_cmd->rate_n_flags = cpu_to_le32(rate_plcp | rate_flags); } static void @@ -2753,7 +2739,7 @@ il4965_sta_alloc_lq(struct il_priv *il, u8 sta_id) rate_flags |= il4965_first_antenna(il->hw_params. valid_tx_ant) << RATE_MCS_ANT_POS; - rate_n_flags = il4965_hw_set_rate_n_flags(il_rates[r].plcp, rate_flags); + rate_n_flags = cpu_to_le32(il_rates[r].plcp | rate_flags); for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) link_cmd->rs_table[i].rate_n_flags = rate_n_flags; @@ -3538,11 +3524,10 @@ il4965_hw_get_beacon_cmd(struct il_priv *il, struct il_frame *frame) /* Set up packet rate and flags */ rate = il_get_lowest_plcp(il, il->beacon_ctx); il4965_toggle_tx_ant(il, &il->mgmt_tx_ant, il->hw_params.valid_tx_ant); - rate_flags = il4965_ant_idx_to_flags(il->mgmt_tx_ant); + rate_flags = BIT(il->mgmt_tx_ant) << RATE_MCS_ANT_POS; if ((rate >= IL_FIRST_CCK_RATE) && (rate <= IL_LAST_CCK_RATE)) rate_flags |= RATE_MCS_CCK_MSK; - tx_beacon_cmd->tx.rate_n_flags = - il4965_hw_set_rate_n_flags(rate, rate_flags); + tx_beacon_cmd->tx.rate_n_flags = cpu_to_le32(rate | rate_flags); return sizeof(*tx_beacon_cmd) + frame_size; } diff --git a/drivers/net/wireless/iwlegacy/4965.h b/drivers/net/wireless/iwlegacy/4965.h index ca254aa4fd35..f280e0161b17 100644 --- a/drivers/net/wireless/iwlegacy/4965.h +++ b/drivers/net/wireless/iwlegacy/4965.h @@ -167,12 +167,6 @@ il4965_hw_get_rate(__le32 rate_n_flags) return le32_to_cpu(rate_n_flags) & 0xFF; } -static inline __le32 -il4965_hw_set_rate_n_flags(u8 rate, u32 flags) -{ - return cpu_to_le32(flags | (u32) rate); -} - /* eeprom */ void il4965_eeprom_get_mac(const struct il_priv *il, u8 * mac); int il4965_eeprom_acquire_semaphore(struct il_priv *il); -- cgit v1.2.1 From 280ade5ea9555208716131765cc194069eaf97d9 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 23 Dec 2011 08:13:46 +0100 Subject: iwlegacy: 3945: get rid of hw_{set,get}_rate Remove these helpers, some are not unused at all, one can be unrolled in place of use. Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/3945.c | 3 +-- drivers/net/wireless/iwlegacy/3945.h | 18 ------------------ 2 files changed, 1 insertion(+), 20 deletions(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c index 0b99deb48426..44a121167806 100644 --- a/drivers/net/wireless/iwlegacy/3945.c +++ b/drivers/net/wireless/iwlegacy/3945.c @@ -2331,8 +2331,7 @@ il3945_init_hw_rate_table(struct il_priv *il) for (i = 0; i < ARRAY_SIZE(il3945_rates); i++) { idx = il3945_rates[i].table_rs_idx; - table[idx].rate_n_flags = - il3945_hw_set_rate_n_flags(il3945_rates[i].plcp, 0); + table[idx].rate_n_flags = cpu_to_le16(il3945_rates[i].plcp); table[idx].try_cnt = il->retry_rate; prev_idx = il3945_get_prev_ieee_rate(i); table[idx].next_rate_idx = il3945_rates[prev_idx].table_rs_idx; diff --git a/drivers/net/wireless/iwlegacy/3945.h b/drivers/net/wireless/iwlegacy/3945.h index 2b2895c544d7..970e5c3a410a 100644 --- a/drivers/net/wireless/iwlegacy/3945.h +++ b/drivers/net/wireless/iwlegacy/3945.h @@ -476,24 +476,6 @@ struct il3945_shared { __le32 tx_base_ptr[8]; } __packed; -static inline u8 -il3945_hw_get_rate(__le16 rate_n_flags) -{ - return le16_to_cpu(rate_n_flags) & 0xFF; -} - -static inline u16 -il3945_hw_get_rate_n_flags(__le16 rate_n_flags) -{ - return le16_to_cpu(rate_n_flags); -} - -static inline __le16 -il3945_hw_set_rate_n_flags(u8 rate, u16 flags) -{ - return cpu_to_le16((u16) rate | flags); -} - /************************************/ /* iwl3945 Flow Handler Definitions */ /************************************/ -- cgit v1.2.1 From 5bf0dac47fef5270bde3c20a734a3c69e51f9eff Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 23 Dec 2011 08:13:47 +0100 Subject: iwlegacy: 4965: remove one il4965_hdl_beacon We have two such functions. Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/4965-mac.c | 3 +-- drivers/net/wireless/iwlegacy/4965.c | 19 ------------------- 2 files changed, 1 insertion(+), 21 deletions(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index cefc623f19ea..1667232af647 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -3780,13 +3780,12 @@ il4965_hdl_beacon(struct il_priv *il, struct il_rx_buf *rxb) #ifdef CONFIG_IWLEGACY_DEBUG u8 rate = il4965_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); - D_RX("beacon status %x retries %d iss %d " "tsf %d %d rate %d\n", + D_RX("beacon status %x retries %d iss %d tsf:0x%.8x%.8x rate %d\n", le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK, beacon->beacon_notify_hdr.failure_frame, le32_to_cpu(beacon->ibss_mgr_status), le32_to_cpu(beacon->high_tsf), le32_to_cpu(beacon->low_tsf), rate); #endif - il->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status); } diff --git a/drivers/net/wireless/iwlegacy/4965.c b/drivers/net/wireless/iwlegacy/4965.c index 84c54dccf195..cacbc03880b0 100644 --- a/drivers/net/wireless/iwlegacy/4965.c +++ b/drivers/net/wireless/iwlegacy/4965.c @@ -2114,24 +2114,6 @@ il4965_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb) spin_unlock_irqrestore(&il->sta_lock, flags); } -static void -il4965_hdl_beacon(struct il_priv *il, struct il_rx_buf *rxb) -{ - struct il_rx_pkt *pkt = rxb_addr(rxb); - struct il4965_beacon_notif *beacon = (void *)pkt->u.raw; - u8 rate __maybe_unused = - il4965_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); - - D_RX("beacon status %#x, retries:%d ibssmgr:%d " - "tsf:0x%.8x%.8x rate:%d\n", - le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK, - beacon->beacon_notify_hdr.failure_frame, - le32_to_cpu(beacon->ibss_mgr_status), - le32_to_cpu(beacon->high_tsf), le32_to_cpu(beacon->low_tsf), rate); - - il->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status); -} - /* Set up 4965-specific Rx frame reply handlers */ static void il4965_handler_setup(struct il_priv *il) @@ -2140,7 +2122,6 @@ il4965_handler_setup(struct il_priv *il) il->handlers[N_RX] = il4965_hdl_rx; /* Tx response */ il->handlers[C_TX] = il4965_hdl_tx; - il->handlers[N_BEACON] = il4965_hdl_beacon; } static struct il_hcmd_ops il4965_hcmd = { -- cgit v1.2.1 From 5d0bef903abe8ac438b660c77d886e6b0394797c Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 23 Dec 2011 08:13:48 +0100 Subject: iwlegacy: random 3945-rs.c cleanups Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/3945-rs.c | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/iwlegacy/3945-rs.c b/drivers/net/wireless/iwlegacy/3945-rs.c index 30ad404f8df7..d7a83f229190 100644 --- a/drivers/net/wireless/iwlegacy/3945-rs.c +++ b/drivers/net/wireless/iwlegacy/3945-rs.c @@ -86,16 +86,16 @@ static struct il3945_tpt_entry il3945_tpt_table_g[] = { {-92, RATE_1M_IDX} }; -#define RATE_MAX_WINDOW 62 +#define RATE_MAX_WINDOW 62 #define RATE_FLUSH (3*HZ) -#define RATE_WIN_FLUSH (HZ/2) -#define IL39_RATE_HIGH_TH 11520 -#define IL_SUCCESS_UP_TH 8960 -#define IL_SUCCESS_DOWN_TH 10880 -#define RATE_MIN_FAILURE_TH 6 -#define RATE_MIN_SUCCESS_TH 8 -#define RATE_DECREASE_TH 1920 -#define RATE_RETRY_TH 15 +#define RATE_WIN_FLUSH (HZ/2) +#define IL39_RATE_HIGH_TH 11520 +#define IL_SUCCESS_UP_TH 8960 +#define IL_SUCCESS_DOWN_TH 10880 +#define RATE_MIN_FAILURE_TH 6 +#define RATE_MIN_SUCCESS_TH 8 +#define RATE_DECREASE_TH 1920 +#define RATE_RETRY_TH 15 static u8 il3945_get_rate_idx_by_rssi(s32 rssi, enum ieee80211_band band) @@ -112,12 +112,10 @@ il3945_get_rate_idx_by_rssi(s32 rssi, enum ieee80211_band band) tpt_table = il3945_tpt_table_g; table_size = ARRAY_SIZE(il3945_tpt_table_g); break; - case IEEE80211_BAND_5GHZ: tpt_table = il3945_tpt_table_a; table_size = ARRAY_SIZE(il3945_tpt_table_a); break; - default: BUG(); break; @@ -126,7 +124,7 @@ il3945_get_rate_idx_by_rssi(s32 rssi, enum ieee80211_band band) while (idx < table_size && rssi < tpt_table[idx].min_rssi) idx++; - idx = min(idx, (table_size - 1)); + idx = min(idx, table_size - 1); return tpt_table[idx].idx; } @@ -328,7 +326,6 @@ il3945_collect_tx_data(struct il3945_rs_sta *rs_sta, win->stamp = jiffies; spin_unlock_irqrestore(&rs_sta->lock, flags); - } /* @@ -386,8 +383,7 @@ il3945_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, u8 sta_id) /* For 5 GHz band it start at IL_FIRST_OFDM_RATE */ if (sband->band == IEEE80211_BAND_5GHZ) { rs_sta->last_txrate_idx += IL_FIRST_OFDM_RATE; - il->_3945.sta_supp_rates = - il->_3945.sta_supp_rates << IL_FIRST_OFDM_RATE; + il->_3945.sta_supp_rates <<= IL_FIRST_OFDM_RATE; } out: @@ -406,7 +402,6 @@ il3945_rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) static void il3945_rs_free(void *il) { - return; } static void * @@ -791,19 +786,16 @@ il3945_rs_get_rate(void *il_r, struct ieee80211_sta *sta, void *il_sta, switch (scale_action) { case -1: - /* Decrese rate */ if (low != RATE_INVALID) idx = low; break; - case 1: /* Increase rate */ if (high != RATE_INVALID) idx = high; break; - case 0: default: /* No change */ @@ -958,7 +950,6 @@ il3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) } else rs_sta->expected_tpt = il3945_expected_tpt_g; break; - case IEEE80211_BAND_5GHZ: rs_sta->expected_tpt = il3945_expected_tpt_a; break; -- cgit v1.2.1 From 81fb46139504f72a92243245df878e1a1af35f89 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 23 Dec 2011 08:13:49 +0100 Subject: iwlegacy: 3945: simplify calculations of retry limit Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/3945-mac.c | 3 +-- drivers/net/wireless/iwlegacy/3945.c | 15 ++++----------- drivers/net/wireless/iwlegacy/3945.h | 3 +-- 3 files changed, 6 insertions(+), 15 deletions(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c index daef6b58f6cc..c8179756bf3c 100644 --- a/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/iwlegacy/3945-mac.c @@ -570,8 +570,7 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb) /* TODO need this for burst mode later on */ il3945_build_tx_cmd_basic(il, out_cmd, info, hdr, sta_id); - /* set is_hcca to 0; it probably will never be implemented */ - il3945_hw_build_tx_cmd_rate(il, out_cmd, info, hdr, sta_id, 0); + il3945_hw_build_tx_cmd_rate(il, out_cmd, info, hdr, sta_id); /* Total # bytes to be transmitted */ len = (u16) skb->len; diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c index 44a121167806..1489b1573a6a 100644 --- a/drivers/net/wireless/iwlegacy/3945.c +++ b/drivers/net/wireless/iwlegacy/3945.c @@ -680,13 +680,13 @@ il3945_hw_txq_free_tfd(struct il_priv *il, struct il_tx_queue *txq) void il3945_hw_build_tx_cmd_rate(struct il_priv *il, struct il_device_cmd *cmd, struct ieee80211_tx_info *info, - struct ieee80211_hdr *hdr, int sta_id, int tx_id) + struct ieee80211_hdr *hdr, int sta_id) { u16 hw_value = ieee80211_get_tx_rate(il->hw, info)->hw_value; u16 rate_idx = min(hw_value & 0xffff, RATE_COUNT_3945 - 1); u16 rate_mask; int rate; - u8 rts_retry_limit; + const u8 rts_retry_limit = 7; u8 data_retry_limit; __le32 tx_flags; __le16 fc = hdr->frame_control; @@ -705,15 +705,8 @@ il3945_hw_build_tx_cmd_rate(struct il_priv *il, struct il_device_cmd *cmd, else data_retry_limit = IL_DEFAULT_TX_RETRY; tx_cmd->data_retry_limit = data_retry_limit; - - if (tx_id >= IL39_CMD_QUEUE_NUM) - rts_retry_limit = 3; - else - rts_retry_limit = 7; - - if (data_retry_limit < rts_retry_limit) - rts_retry_limit = data_retry_limit; - tx_cmd->rts_retry_limit = rts_retry_limit; + /* Set retry limit on RTS packets */ + tx_cmd->rts_retry_limit = min(data_retry_limit, rts_retry_limit); tx_cmd->rate = rate; tx_cmd->tx_flags = tx_flags; diff --git a/drivers/net/wireless/iwlegacy/3945.h b/drivers/net/wireless/iwlegacy/3945.h index 970e5c3a410a..9f42f79f8778 100644 --- a/drivers/net/wireless/iwlegacy/3945.h +++ b/drivers/net/wireless/iwlegacy/3945.h @@ -239,8 +239,7 @@ extern unsigned int il3945_hw_get_beacon_cmd(struct il_priv *il, u8 rate); void il3945_hw_build_tx_cmd_rate(struct il_priv *il, struct il_device_cmd *cmd, struct ieee80211_tx_info *info, - struct ieee80211_hdr *hdr, int sta_id, - int tx_id); + struct ieee80211_hdr *hdr, int sta_id); extern int il3945_hw_reg_send_txpower(struct il_priv *il); extern int il3945_hw_reg_set_txpower(struct il_priv *il, s8 power); extern void il3945_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb); -- cgit v1.2.1 From 68acc4afb040d98ddfd2cae0de09e2f4e1ee127f Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 23 Dec 2011 08:13:50 +0100 Subject: iwlegacy: 3945: fix hw passive scan on radar channels Patch fix firmware error on "iw dev wlan0 scan passive" for hardware scanning (with disable_hw_scan=0 module parameter). iwl3945 0000:03:00.0: Microcode SW error detected. Restarting 0x82000008. iwl3945 0000:03:00.0: Loaded firmware version: 15.32.2.9 iwl3945 0000:03:00.0: Start IWL Error Log Dump: iwl3945 0000:03:00.0: Status: 0x0002A2E4, count: 1 iwl3945 0000:03:00.0: Desc Time asrtPC blink2 ilink1 nmiPC Line iwl3945 0000:03:00.0: SYSASSERT (0x5) 0041263900 0x13756 0x0031C 0x00000 764 iwl3945 0000:03:00.0: Error Reply type 0x000002FC cmd C_SCAN (0x80) seq 0x443E ser 0x00340000 iwl3945 0000:03:00.0: Command C_SCAN failed: FW Error iwl3945 0000:03:00.0: Can't stop Rx DMA. We have disable ability to change passive scanning to active on particular channel when traffic is detected on that channel. Otherwise firmware will report error, when we try to do passive scan on radar channels. Reported-and-debugged-by: Pedro Francisco Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/3945-mac.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c index c8179756bf3c..54b2d391e91a 100644 --- a/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/iwlegacy/3945-mac.c @@ -2623,12 +2623,12 @@ il3945_request_scan(struct il_priv *il, struct ieee80211_vif *vif) } /* - * If active scaning is requested but a certain channel - * is marked passive, we can do active scanning if we - * detect transmissions. + * If active scaning is requested but a certain channel is marked + * passive, we can do active scanning if we detect transmissions. For + * passive only scanning disable switching to active on any channel. */ scan->good_CRC_th = - is_active ? IL_GOOD_CRC_TH_DEFAULT : IL_GOOD_CRC_TH_DISABLED; + is_active ? IL_GOOD_CRC_TH_DEFAULT : IL_GOOD_CRC_TH_NEVER; len = il_fill_probe_req(il, (struct ieee80211_mgmt *)scan->data, -- cgit v1.2.1 From 016c2177918301c9a2557c675c12ab88667a27bb Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 23 Dec 2011 21:27:02 +0530 Subject: ath9k_hw: increase tx status ring buffer size AR9003 chips read tx status from ring buffer whose max number of status descriptor is mininal compared to max number of tx buffers. On a stress condition, it can be easily overflown which might cause false tx hung detection. Though increasing number of max status descriptors consumes more memory, it helps to avoid false positive chip resets. Cc: Paul Stewart Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mac.c | 2 +- drivers/net/wireless/ath/ath9k/ar9003_mac.h | 2 +- drivers/net/wireless/ath/ath9k/ath9k.h | 2 +- drivers/net/wireless/ath/ath9k/hw.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 4a315155d779..88c81c5706b2 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -583,7 +583,7 @@ void ath9k_hw_reset_txstatus_ring(struct ath_hw *ah) void ath9k_hw_setup_statusring(struct ath_hw *ah, void *ts_start, u32 ts_paddr_start, - u8 size) + u16 size) { ah->ts_paddr_start = ts_paddr_start; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.h b/drivers/net/wireless/ath/ath9k/ar9003_mac.h index c50449387bf1..e203b51e968b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.h @@ -118,5 +118,5 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, void ath9k_hw_reset_txstatus_ring(struct ath_hw *ah); void ath9k_hw_setup_statusring(struct ath_hw *ah, void *ts_start, u32 ts_paddr_start, - u8 size); + u16 size); #endif diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 95276e914c1b..b30e9fc6433f 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -97,7 +97,7 @@ enum buffer_type { #define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU) #define bf_isaggr(bf) (bf->bf_state.bf_type & BUF_AGGR) -#define ATH_TXSTATUS_RING_SIZE 64 +#define ATH_TXSTATUS_RING_SIZE 512 #define DS2PHYS(_dd, _ds) \ ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc)) diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 48205c2960b5..6a29004a71b0 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -1016,7 +1016,7 @@ struct ath_hw { u32 ts_paddr_start; u32 ts_paddr_end; u16 ts_tail; - u8 ts_size; + u16 ts_size; u32 bb_watchdog_last_status; u32 bb_watchdog_timeout_ms; /* in ms, 0 to disable */ -- cgit v1.2.1 From f961e34ebef84b532ec6c477f73b66d9a8b0ddbc Mon Sep 17 00:00:00 2001 From: Stanislav Yakovlev Date: Mon, 26 Dec 2011 18:31:11 -0500 Subject: ipw2x00: remove reset_port functionality Removes reset_port since it isn't used anywhere as suggested by Johannes Berg. Signed-off-by: Stanislav Yakovlev Signed-off-by: John W. Linville --- drivers/net/wireless/ipw2x00/libipw.h | 4 ---- drivers/net/wireless/ipw2x00/libipw_wx.c | 25 ------------------------- 2 files changed, 29 deletions(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/ipw2x00/libipw.h b/drivers/net/wireless/ipw2x00/libipw.h index 3d5821eeb054..8874588fb929 100644 --- a/drivers/net/wireless/ipw2x00/libipw.h +++ b/drivers/net/wireless/ipw2x00/libipw.h @@ -805,9 +805,6 @@ struct libipw_device { /* WEP and other encryption related settings at the device level */ int open_wep; /* Set to 1 to allow unencrypted frames */ - int reset_on_keychange; /* Set to 1 if the HW needs to be reset on - * WEP key changes */ - /* If the host performs {en,de}cryption, then set to 1 */ int host_encrypt; int host_encrypt_msdu; @@ -860,7 +857,6 @@ struct libipw_device { struct libipw_security * sec); netdev_tx_t (*hard_start_xmit) (struct libipw_txb * txb, struct net_device * dev, int pri); - int (*reset_port) (struct net_device * dev); int (*is_queue_full) (struct net_device * dev, int pri); int (*handle_management) (struct net_device * dev, diff --git a/drivers/net/wireless/ipw2x00/libipw_wx.c b/drivers/net/wireless/ipw2x00/libipw_wx.c index 6623e5052254..1571505b1a38 100644 --- a/drivers/net/wireless/ipw2x00/libipw_wx.c +++ b/drivers/net/wireless/ipw2x00/libipw_wx.c @@ -474,17 +474,6 @@ int libipw_wx_set_encode(struct libipw_device *ieee, if (ieee->set_security) ieee->set_security(dev, &sec); - /* Do not reset port if card is in Managed mode since resetting will - * generate new IEEE 802.11 authentication which may end up in looping - * with IEEE 802.1X. If your hardware requires a reset after WEP - * configuration (for example... Prism2), implement the reset_port in - * the callbacks structures used to initialize the 802.11 stack. */ - if (ieee->reset_on_keychange && - ieee->iw_mode != IW_MODE_INFRA && - ieee->reset_port && ieee->reset_port(dev)) { - printk(KERN_DEBUG "%s: reset_port failed\n", dev->name); - return -EINVAL; - } return 0; } @@ -688,20 +677,6 @@ int libipw_wx_set_encodeext(struct libipw_device *ieee, if (ieee->set_security) ieee->set_security(ieee->dev, &sec); - /* - * Do not reset port if card is in Managed mode since resetting will - * generate new IEEE 802.11 authentication which may end up in looping - * with IEEE 802.1X. If your hardware requires a reset after WEP - * configuration (for example... Prism2), implement the reset_port in - * the callbacks structures used to initialize the 802.11 stack. - */ - if (ieee->reset_on_keychange && - ieee->iw_mode != IW_MODE_INFRA && - ieee->reset_port && ieee->reset_port(dev)) { - LIBIPW_DEBUG_WX("%s: reset_port failed\n", dev->name); - return -EINVAL; - } - return ret; } -- cgit v1.2.1 From 3f81f8f1524ccca24df1029b0cf825ecef5e5cdc Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Tue, 27 Dec 2011 12:22:51 -0600 Subject: rt2800usb: Move ID out of unknown Testing on the openSUSE wireless forum has shown that a Linksys WUSB54GC v3 with USB ID 1737:0077 works with rt2800usb when the ID is written to /sys/.../new_id. This ID can therefore be moved out of UNKNOWN. Signed-off-by: Larry Finger Cc: Stable Acked-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 7d1b6e4ef078..486fd4994ae1 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -976,6 +976,7 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x13b1, 0x0031) }, { USB_DEVICE(0x1737, 0x0070) }, { USB_DEVICE(0x1737, 0x0071) }, + { USB_DEVICE(0x1737, 0x0077) }, /* Logitec */ { USB_DEVICE(0x0789, 0x0162) }, { USB_DEVICE(0x0789, 0x0163) }, @@ -1173,7 +1174,6 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x1740, 0x0605) }, { USB_DEVICE(0x1740, 0x0615) }, /* Linksys */ - { USB_DEVICE(0x1737, 0x0077) }, { USB_DEVICE(0x1737, 0x0078) }, /* Logitec */ { USB_DEVICE(0x0789, 0x0168) }, -- cgit v1.2.1 From 65a692284d0343e1610eaf91a333a29769e989ef Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Tue, 27 Dec 2011 21:01:55 +0100 Subject: carl9170: move checksum and txseq into subfunctions Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/fw.c | 97 +++++++++++++++++++++------------- 1 file changed, 60 insertions(+), 37 deletions(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c index cba9d0435dc4..3de61adacd34 100644 --- a/drivers/net/wireless/ath/carl9170/fw.c +++ b/drivers/net/wireless/ath/carl9170/fw.c @@ -146,13 +146,15 @@ static bool valid_cpu_addr(const u32 address) return false; } -static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) +static int carl9170_fw_checksum(struct ar9170 *ar, const __u8 *data, + size_t len) { const struct carl9170fw_otus_desc *otus_desc; - const struct carl9170fw_chk_desc *chk_desc; const struct carl9170fw_last_desc *last_desc; - const struct carl9170fw_txsq_desc *txsq_desc; - u16 if_comb_types; + const struct carl9170fw_chk_desc *chk_desc; + unsigned long fin, diff; + unsigned int dsc_len; + u32 crc32; last_desc = carl9170_fw_find_desc(ar, LAST_MAGIC, sizeof(*last_desc), CARL9170FW_LAST_DESC_CUR_VER); @@ -170,36 +172,68 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) chk_desc = carl9170_fw_find_desc(ar, CHK_MAGIC, sizeof(*chk_desc), CARL9170FW_CHK_DESC_CUR_VER); - if (chk_desc) { - unsigned long fin, diff; - unsigned int dsc_len; - u32 crc32; + if (!chk_desc) { + dev_warn(&ar->udev->dev, "Unprotected firmware image.\n"); + return 0; + } - dsc_len = min_t(unsigned int, len, + dsc_len = min_t(unsigned int, len, (unsigned long)chk_desc - (unsigned long)otus_desc); - fin = (unsigned long) last_desc + sizeof(*last_desc); - diff = fin - (unsigned long) otus_desc; + fin = (unsigned long) last_desc + sizeof(*last_desc); + diff = fin - (unsigned long) otus_desc; - if (diff < len) - len -= diff; + if (diff < len) + len -= diff; - if (len < 256) - return -EIO; + if (len < 256) + return -EIO; - crc32 = crc32_le(~0, data, len); - if (cpu_to_le32(crc32) != chk_desc->fw_crc32) { - dev_err(&ar->udev->dev, "fw checksum test failed.\n"); - return -ENOEXEC; - } + crc32 = crc32_le(~0, data, len); + if (cpu_to_le32(crc32) != chk_desc->fw_crc32) { + dev_err(&ar->udev->dev, "fw checksum test failed.\n"); + return -ENOEXEC; + } + + crc32 = crc32_le(crc32, (void *)otus_desc, dsc_len); + if (cpu_to_le32(crc32) != chk_desc->hdr_crc32) { + dev_err(&ar->udev->dev, "descriptor check failed.\n"); + return -EINVAL; + } + return 0; +} - crc32 = crc32_le(crc32, (void *)otus_desc, dsc_len); - if (cpu_to_le32(crc32) != chk_desc->hdr_crc32) { - dev_err(&ar->udev->dev, "descriptor check failed.\n"); +static int carl9170_fw_tx_sequence(struct ar9170 *ar) +{ + const struct carl9170fw_txsq_desc *txsq_desc; + + txsq_desc = carl9170_fw_find_desc(ar, TXSQ_MAGIC, sizeof(*txsq_desc), + CARL9170FW_TXSQ_DESC_CUR_VER); + if (txsq_desc) { + ar->fw.tx_seq_table = le32_to_cpu(txsq_desc->seq_table_addr); + if (!valid_cpu_addr(ar->fw.tx_seq_table)) return -EINVAL; - } } else { - dev_warn(&ar->udev->dev, "Unprotected firmware image.\n"); + ar->fw.tx_seq_table = 0; + } + + return 0; +} + +static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) +{ + const struct carl9170fw_otus_desc *otus_desc; + int err; + u16 if_comb_types; + + err = carl9170_fw_checksum(ar, data, len); + if (err) + return err; + + otus_desc = carl9170_fw_find_desc(ar, OTUS_MAGIC, + sizeof(*otus_desc), CARL9170FW_OTUS_DESC_CUR_VER); + if (!otus_desc) { + return -ENODATA; } #define SUPP(feat) \ @@ -321,19 +355,8 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) ar->hw->wiphy->interface_modes |= if_comb_types; - txsq_desc = carl9170_fw_find_desc(ar, TXSQ_MAGIC, - sizeof(*txsq_desc), CARL9170FW_TXSQ_DESC_CUR_VER); - - if (txsq_desc) { - ar->fw.tx_seq_table = le32_to_cpu(txsq_desc->seq_table_addr); - if (!valid_cpu_addr(ar->fw.tx_seq_table)) - return -EINVAL; - } else { - ar->fw.tx_seq_table = 0; - } - #undef SUPPORTED - return 0; + return carl9170_fw_tx_sequence(ar); } static struct carl9170fw_desc_head * -- cgit v1.2.1 From bc93eda7e903ff75cefcb6e247ed9b8e9f8e9783 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Wed, 28 Dec 2011 01:53:18 +0100 Subject: rt2x00: Identify rt2800usb chipsets. According to the latest USB ID database these are all RT2770 / RT2870 / RT307x devices. Signed-off-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 486fd4994ae1..5bff4957a862 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -914,12 +914,14 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x050d, 0x8053) }, { USB_DEVICE(0x050d, 0x805c) }, { USB_DEVICE(0x050d, 0x815c) }, + { USB_DEVICE(0x050d, 0x825a) }, { USB_DEVICE(0x050d, 0x825b) }, { USB_DEVICE(0x050d, 0x935a) }, { USB_DEVICE(0x050d, 0x935b) }, /* Buffalo */ { USB_DEVICE(0x0411, 0x00e8) }, { USB_DEVICE(0x0411, 0x0158) }, + { USB_DEVICE(0x0411, 0x015d) }, { USB_DEVICE(0x0411, 0x016f) }, { USB_DEVICE(0x0411, 0x01a2) }, /* Corega */ @@ -934,6 +936,8 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x07d1, 0x3c0e) }, { USB_DEVICE(0x07d1, 0x3c0f) }, { USB_DEVICE(0x07d1, 0x3c11) }, + { USB_DEVICE(0x07d1, 0x3c13) }, + { USB_DEVICE(0x07d1, 0x3c15) }, { USB_DEVICE(0x07d1, 0x3c16) }, /* Draytek */ { USB_DEVICE(0x07fa, 0x7712) }, @@ -943,6 +947,7 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x7392, 0x7711) }, { USB_DEVICE(0x7392, 0x7717) }, { USB_DEVICE(0x7392, 0x7718) }, + { USB_DEVICE(0x7392, 0x7722) }, /* Encore */ { USB_DEVICE(0x203d, 0x1480) }, { USB_DEVICE(0x203d, 0x14a9) }, @@ -977,6 +982,7 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x1737, 0x0070) }, { USB_DEVICE(0x1737, 0x0071) }, { USB_DEVICE(0x1737, 0x0077) }, + { USB_DEVICE(0x1737, 0x0078) }, /* Logitec */ { USB_DEVICE(0x0789, 0x0162) }, { USB_DEVICE(0x0789, 0x0163) }, @@ -1000,9 +1006,13 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x0db0, 0x871b) }, { USB_DEVICE(0x0db0, 0x871c) }, { USB_DEVICE(0x0db0, 0x899a) }, + /* Ovislink */ + { USB_DEVICE(0x1b75, 0x3071) }, + { USB_DEVICE(0x1b75, 0x3072) }, /* Para */ { USB_DEVICE(0x20b8, 0x8888) }, /* Pegatron */ + { USB_DEVICE(0x1d4d, 0x0002) }, { USB_DEVICE(0x1d4d, 0x000c) }, { USB_DEVICE(0x1d4d, 0x000e) }, { USB_DEVICE(0x1d4d, 0x0011) }, @@ -1055,7 +1065,9 @@ static struct usb_device_id rt2800usb_device_table[] = { /* Sparklan */ { USB_DEVICE(0x15a9, 0x0006) }, /* Sweex */ + { USB_DEVICE(0x177f, 0x0153) }, { USB_DEVICE(0x177f, 0x0302) }, + { USB_DEVICE(0x177f, 0x0313) }, /* U-Media */ { USB_DEVICE(0x157e, 0x300e) }, { USB_DEVICE(0x157e, 0x3013) }, @@ -1139,25 +1151,20 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x13d3, 0x3322) }, /* Belkin */ { USB_DEVICE(0x050d, 0x1003) }, - { USB_DEVICE(0x050d, 0x825a) }, /* Buffalo */ { USB_DEVICE(0x0411, 0x012e) }, { USB_DEVICE(0x0411, 0x0148) }, { USB_DEVICE(0x0411, 0x0150) }, - { USB_DEVICE(0x0411, 0x015d) }, /* Corega */ { USB_DEVICE(0x07aa, 0x0041) }, { USB_DEVICE(0x07aa, 0x0042) }, { USB_DEVICE(0x18c5, 0x0008) }, /* D-Link */ { USB_DEVICE(0x07d1, 0x3c0b) }, - { USB_DEVICE(0x07d1, 0x3c13) }, - { USB_DEVICE(0x07d1, 0x3c15) }, { USB_DEVICE(0x07d1, 0x3c17) }, { USB_DEVICE(0x2001, 0x3c17) }, /* Edimax */ { USB_DEVICE(0x7392, 0x4085) }, - { USB_DEVICE(0x7392, 0x7722) }, /* Encore */ { USB_DEVICE(0x203d, 0x14a1) }, /* Fujitsu Stylistic 550 */ @@ -1173,19 +1180,13 @@ static struct usb_device_id rt2800usb_device_table[] = { /* LevelOne */ { USB_DEVICE(0x1740, 0x0605) }, { USB_DEVICE(0x1740, 0x0615) }, - /* Linksys */ - { USB_DEVICE(0x1737, 0x0078) }, /* Logitec */ { USB_DEVICE(0x0789, 0x0168) }, { USB_DEVICE(0x0789, 0x0169) }, /* Motorola */ { USB_DEVICE(0x100d, 0x9032) }, - /* Ovislink */ - { USB_DEVICE(0x1b75, 0x3071) }, - { USB_DEVICE(0x1b75, 0x3072) }, /* Pegatron */ { USB_DEVICE(0x05a6, 0x0101) }, - { USB_DEVICE(0x1d4d, 0x0002) }, { USB_DEVICE(0x1d4d, 0x0010) }, /* Planex */ { USB_DEVICE(0x2019, 0x5201) }, @@ -1204,9 +1205,6 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x083a, 0xc522) }, { USB_DEVICE(0x083a, 0xd522) }, { USB_DEVICE(0x083a, 0xf511) }, - /* Sweex */ - { USB_DEVICE(0x177f, 0x0153) }, - { USB_DEVICE(0x177f, 0x0313) }, /* Zyxel */ { USB_DEVICE(0x0586, 0x341a) }, #endif -- cgit v1.2.1 From 70127cb69418487cec223575a34148604f156397 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Wed, 28 Dec 2011 01:53:19 +0100 Subject: rt2x00: Whitespace cleanup. Signed-off-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 99ff12d0c29d..851b71767cdd 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -191,7 +191,7 @@ struct rt2x00_chip { #define RT3572 0x3572 #define RT3593 0x3593 /* PCIe */ #define RT3883 0x3883 /* WSOC */ -#define RT5390 0x5390 /* 2.4GHz */ +#define RT5390 0x5390 /* 2.4GHz */ u16 rf; u16 rev; -- cgit v1.2.1 From 5aa570159090b8bcf1357ef92386c24ff32d76d2 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Wed, 28 Dec 2011 01:53:20 +0100 Subject: rt2x00: Convert big if-statements to switch-statements. Signed-off-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 44 +++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 18 deletions(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 4cae051daebb..22a1a8fc6e02 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1944,19 +1944,24 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, info->default_power2 = TXPOWER_A_TO_DEV(info->default_power2); } - if (rt2x00_rf(rt2x00dev, RF2020) || - rt2x00_rf(rt2x00dev, RF3020) || - rt2x00_rf(rt2x00dev, RF3021) || - rt2x00_rf(rt2x00dev, RF3022) || - rt2x00_rf(rt2x00dev, RF3320)) + switch (rt2x00dev->chip.rf) { + case RF2020: + case RF3020: + case RF3021: + case RF3022: + case RF3320: rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info); - else if (rt2x00_rf(rt2x00dev, RF3052)) + break; + case RF3052: rt2800_config_channel_rf3052(rt2x00dev, conf, rf, info); - else if (rt2x00_rf(rt2x00dev, RF5370) || - rt2x00_rf(rt2x00dev, RF5390)) + break; + case RF5370: + case RF5390: rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info); - else + break; + default: rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); + } /* * Change BBP settings @@ -3932,15 +3937,18 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET), value, rt2x00_get_field32(reg, MAC_CSR0_REVISION)); - if (!rt2x00_rt(rt2x00dev, RT2860) && - !rt2x00_rt(rt2x00dev, RT2872) && - !rt2x00_rt(rt2x00dev, RT2883) && - !rt2x00_rt(rt2x00dev, RT3070) && - !rt2x00_rt(rt2x00dev, RT3071) && - !rt2x00_rt(rt2x00dev, RT3090) && - !rt2x00_rt(rt2x00dev, RT3390) && - !rt2x00_rt(rt2x00dev, RT3572) && - !rt2x00_rt(rt2x00dev, RT5390)) { + switch (rt2x00dev->chip.rt) { + case RT2860: + case RT2872: + case RT2883: + case RT3070: + case RT3071: + case RT3090: + case RT3390: + case RT3572: + case RT5390: + break; + default: ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); return -ENODEV; } -- cgit v1.2.1 From 4bcafac8c64e015775fcb844f643c2c70115bf46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Kici=C5=84ski?= Date: Wed, 28 Dec 2011 01:53:21 +0100 Subject: rt2800usb: Let rt2x00usb handle USB padding Older USB drivers does not append end padding to skb but instead report it in size of data to be transmitted to HW. rt2800usb should follow that behaviour. Custom write_tx_data callback which was adding pad to skb is not be needed any more. Thanks to this patch frames handed back from rt2800usb to mac80211 will no longer contain end padding. Signed-off-by: Jakub Kicinski Signed-off-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 37 +++++++++------------------------ 1 file changed, 10 insertions(+), 27 deletions(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 5bff4957a862..7f21005c1bb0 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -400,10 +400,10 @@ static void rt2800usb_write_tx_desc(struct queue_entry *entry, /* * The size of TXINFO_W0_USB_DMA_TX_PKT_LEN is * TXWI + 802.11 header + L2 pad + payload + pad, - * so need to decrease size of TXINFO and USB end pad. + * so need to decrease size of TXINFO. */ rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN, - entry->skb->len - TXINFO_DESC_SIZE - 4); + roundup(entry->skb->len, 4) - TXINFO_DESC_SIZE); rt2x00_set_field32(&word, TXINFO_W0_WIV, !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags)); rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2); @@ -421,37 +421,20 @@ static void rt2800usb_write_tx_desc(struct queue_entry *entry, skbdesc->desc_len = TXINFO_DESC_SIZE + TXWI_DESC_SIZE; } -static void rt2800usb_write_tx_data(struct queue_entry *entry, - struct txentry_desc *txdesc) +/* + * TX data initialization + */ +static int rt2800usb_get_tx_data_len(struct queue_entry *entry) { - unsigned int len; - int err; - - rt2800_write_tx_data(entry, txdesc); - /* - * pad(1~3 bytes) is added after each 802.11 payload. - * USB end pad(4 bytes) is added at each USB bulk out packet end. + * pad(1~3 bytes) is needed after each 802.11 payload. + * USB end pad(4 bytes) is needed at each USB bulk out packet end. * TX frame format is : * | TXINFO | TXWI | 802.11 header | L2 pad | payload | pad | USB end pad | * |<------------- tx_pkt_len ------------->| */ - len = roundup(entry->skb->len, 4) + 4; - err = skb_padto(entry->skb, len); - if (unlikely(err)) { - WARNING(entry->queue->rt2x00dev, "TX SKB padding error, out of memory\n"); - return; - } - entry->skb->len = len; -} - -/* - * TX data initialization - */ -static int rt2800usb_get_tx_data_len(struct queue_entry *entry) -{ - return entry->skb->len; + return roundup(entry->skb->len, 4) + 4; } /* @@ -807,7 +790,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { .flush_queue = rt2x00usb_flush_queue, .tx_dma_done = rt2800usb_tx_dma_done, .write_tx_desc = rt2800usb_write_tx_desc, - .write_tx_data = rt2800usb_write_tx_data, + .write_tx_data = rt2800_write_tx_data, .write_beacon = rt2800_write_beacon, .clear_beacon = rt2800_clear_beacon, .get_tx_data_len = rt2800usb_get_tx_data_len, -- cgit v1.2.1 From d823a50e55fade0eda3708b00dbf49c5476c82e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Kici=C5=84ski?= Date: Wed, 28 Dec 2011 01:53:22 +0100 Subject: rt2x00usb: Zero USB padding before sending URB When USB driver requires padding at the end of frame or URB it will report this need by increasing return value of get_tx_data_len callback. Common USB code uses that return value as desired URB length. Ensure that appropriate part of skb's tailroom exists and is zeroed. Signed-off-by: Jakub Kicinski Acked-by: Ivo van Doorn -- drivers/net/wireless/rt2x00/rt2x00usb.c | 16 +++++++++++++--- 1 files changed, 13 insertions(+), 3 deletions(-) Signed-off-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00usb.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 1e31050dafc9..2eea3866504d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -298,12 +298,22 @@ static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry, void* data) return false; /* - * USB devices cannot blindly pass the skb->len as the - * length of the data to usb_fill_bulk_urb. Pass the skb - * to the driver to determine what the length should be. + * USB devices require certain padding at the end of each frame + * and urb. Those paddings are not included in skbs. Pass entry + * to the driver to determine what the overall length should be. */ length = rt2x00dev->ops->lib->get_tx_data_len(entry); + status = skb_padto(entry->skb, length); + if (unlikely(status)) { + /* TODO: report something more appropriate than IO_FAILED. */ + WARNING(rt2x00dev, "TX SKB padding error, out of memory\n"); + set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); + rt2x00lib_dmadone(entry); + + return false; + } + usb_fill_bulk_urb(entry_priv->urb, usb_dev, usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint), entry->skb->data, length, -- cgit v1.2.1 From 5a87e7a706750c84b3b17943e55a9de77d40869d Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Wed, 28 Dec 2011 01:53:23 +0100 Subject: rt2x00: RT3593 is also applicable to USB. Signed-off-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 851b71767cdd..b03b22c47b18 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -189,7 +189,7 @@ struct rt2x00_chip { #define RT3090 0x3090 /* 2.4GHz PCIe */ #define RT3390 0x3390 #define RT3572 0x3572 -#define RT3593 0x3593 /* PCIe */ +#define RT3593 0x3593 #define RT3883 0x3883 /* WSOC */ #define RT5390 0x5390 /* 2.4GHz */ -- cgit v1.2.1 From 7fbaf3efb042871fce7c9cd706cf9f90d61b5e59 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Wed, 28 Dec 2011 01:53:24 +0100 Subject: rt2x00: Change RF3853 to RF3053. According to the latest Ralink vendor drivers, this seems to be the real RF chipset type. Signed-off-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 4778620347c4..2571a2fa3d09 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -50,7 +50,7 @@ * RF2853 2.4G/5G 3T3R * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390) * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392) - * RF3853 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662) + * RF3053 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662) * RF5370 2.4G 1T1R * RF5390 2.4G 1T1R */ @@ -66,7 +66,7 @@ #define RF2853 0x000a #define RF3320 0x000b #define RF3322 0x000c -#define RF3853 0x000d +#define RF3053 0x000d #define RF5370 0x5370 #define RF5390 0x5390 -- cgit v1.2.1 From 98f0a5eb02bbfff662664bf65f469dc4abd701fd Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Wed, 28 Dec 2011 19:09:54 +0530 Subject: ath9k: tx queue enable is read only for EDMA chipsets for EDMA chip AR_Q_TXE (tx enable for each queue) is read only Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/beacon.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index dc5fd569690f..b8967e482e6e 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -356,6 +356,7 @@ void ath_beacon_tasklet(unsigned long data) struct ath_buf *bf = NULL; struct ieee80211_vif *vif; struct ath_tx_status ts; + bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); int slot; u32 bfaddr, bc = 0; @@ -456,10 +457,12 @@ void ath_beacon_tasklet(unsigned long data) if (bfaddr != 0) { /* NB: cabq traffic should already be queued and primed */ ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr); - ath9k_hw_txstart(ah, sc->beacon.beaconq); + + if (!edma) + ath9k_hw_txstart(ah, sc->beacon.beaconq); sc->beacon.ast_be_xmit += bc; /* XXX per-vif? */ - if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { + if (edma) { spin_lock_bh(&sc->sc_pcu_lock); ath9k_hw_txprocdesc(ah, bf->bf_desc, (void *)&ts); spin_unlock_bh(&sc->sc_pcu_lock); -- cgit v1.2.1 From 6b6accc3832e5a124eeb144c6b3b1ff65b503d2b Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Fri, 30 Dec 2011 16:35:27 +0530 Subject: mwl8k: Recover from firmware crash In case of firmware crash, reload the firmware and reconfigure it by triggering ieee80211_hw_restart; mac80211 utility function. V2 Addressed following comments from Lennert: - Stop the queues during reload - Removed atomic_t declaration for hw_restart - Extend the firmware reload support for sta firmware as well - Other misc changes Signed-off-by: Nishant Sarmukadam Signed-off-by: Yogesh Ashok Powar Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 136 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 129 insertions(+), 7 deletions(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 901cd79a061e..cf6927189682 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -198,6 +198,7 @@ struct mwl8k_priv { /* firmware access */ struct mutex fw_mutex; struct task_struct *fw_mutex_owner; + struct task_struct *hw_restart_owner; int fw_mutex_depth; struct completion *hostcmd_wait; @@ -262,6 +263,10 @@ struct mwl8k_priv { */ struct ieee80211_tx_queue_params wmm_params[MWL8K_TX_WMM_QUEUES]; + /* To perform the task of reloading the firmware */ + struct work_struct fw_reload; + bool hw_restart_in_progress; + /* async firmware loading state */ unsigned fw_state; char *fw_pref; @@ -1498,6 +1503,18 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw) might_sleep(); + /* Since fw restart is in progress, allow only the firmware + * commands from the restart code and block the other + * commands since they are going to fail in any case since + * the firmware has crashed + */ + if (priv->hw_restart_in_progress) { + if (priv->hw_restart_owner == current) + return 0; + else + return -EBUSY; + } + /* * The TX queues are stopped at this point, so this test * doesn't need to take ->tx_lock. @@ -1541,6 +1558,8 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw) wiphy_err(hw->wiphy, "tx rings stuck for %d ms\n", MWL8K_TX_WAIT_TIMEOUT_MS); mwl8k_dump_tx_rings(hw); + priv->hw_restart_in_progress = true; + ieee80211_queue_work(hw, &priv->fw_reload); rc = -ETIMEDOUT; } @@ -2058,7 +2077,9 @@ static int mwl8k_fw_lock(struct ieee80211_hw *hw) rc = mwl8k_tx_wait_empty(hw); if (rc) { - ieee80211_wake_queues(hw); + if (!priv->hw_restart_in_progress) + ieee80211_wake_queues(hw); + mutex_unlock(&priv->fw_mutex); return rc; @@ -2077,7 +2098,9 @@ static void mwl8k_fw_unlock(struct ieee80211_hw *hw) struct mwl8k_priv *priv = hw->priv; if (!--priv->fw_mutex_depth) { - ieee80211_wake_queues(hw); + if (!priv->hw_restart_in_progress) + ieee80211_wake_queues(hw); + priv->fw_mutex_owner = NULL; mutex_unlock(&priv->fw_mutex); } @@ -4398,7 +4421,8 @@ static void mwl8k_stop(struct ieee80211_hw *hw) struct mwl8k_priv *priv = hw->priv; int i; - mwl8k_cmd_radio_disable(hw); + if (!priv->hw_restart_in_progress) + mwl8k_cmd_radio_disable(hw); ieee80211_stop_queues(hw); @@ -4499,6 +4523,16 @@ static int mwl8k_add_interface(struct ieee80211_hw *hw, return 0; } +static void mwl8k_remove_vif(struct mwl8k_priv *priv, struct mwl8k_vif *vif) +{ + /* Has ieee80211_restart_hw re-added the removed interfaces? */ + if (!priv->macids_used) + return; + + priv->macids_used &= ~(1 << vif->macid); + list_del(&vif->list); +} + static void mwl8k_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { @@ -4510,8 +4544,54 @@ static void mwl8k_remove_interface(struct ieee80211_hw *hw, mwl8k_cmd_set_mac_addr(hw, vif, "\x00\x00\x00\x00\x00\x00"); - priv->macids_used &= ~(1 << mwl8k_vif->macid); - list_del(&mwl8k_vif->list); + mwl8k_remove_vif(priv, mwl8k_vif); +} + +static void mwl8k_hw_restart_work(struct work_struct *work) +{ + struct mwl8k_priv *priv = + container_of(work, struct mwl8k_priv, fw_reload); + struct ieee80211_hw *hw = priv->hw; + struct mwl8k_device_info *di; + int rc; + + /* If some command is waiting for a response, clear it */ + if (priv->hostcmd_wait != NULL) { + complete(priv->hostcmd_wait); + priv->hostcmd_wait = NULL; + } + + priv->hw_restart_owner = current; + di = priv->device_info; + mwl8k_fw_lock(hw); + + if (priv->ap_fw) + rc = mwl8k_reload_firmware(hw, di->fw_image_ap); + else + rc = mwl8k_reload_firmware(hw, di->fw_image_sta); + + if (rc) + goto fail; + + priv->hw_restart_owner = NULL; + priv->hw_restart_in_progress = false; + + /* + * This unlock will wake up the queues and + * also opens the command path for other + * commands + */ + mwl8k_fw_unlock(hw); + + ieee80211_restart_hw(hw); + + wiphy_err(hw->wiphy, "Firmware restarted successfully\n"); + + return; +fail: + mwl8k_fw_unlock(hw); + + wiphy_err(hw->wiphy, "Firmware restart failed\n"); } static int mwl8k_config(struct ieee80211_hw *hw, u32 changed) @@ -5024,7 +5104,11 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, for (i = 0; i < MAX_AMPDU_ATTEMPTS; i++) { rc = mwl8k_check_ba(hw, stream); - if (!rc) + /* If HW restart is in progress mwl8k_post_cmd will + * return -EBUSY. Avoid retrying mwl8k_check_ba in + * such cases + */ + if (!rc || rc == -EBUSY) break; /* * HW queues take time to be flushed, give them @@ -5263,12 +5347,15 @@ fail: mwl8k_release_firmware(priv); } +#define MAX_RESTART_ATTEMPTS 1 static int mwl8k_init_firmware(struct ieee80211_hw *hw, char *fw_image, bool nowait) { struct mwl8k_priv *priv = hw->priv; int rc; + int count = MAX_RESTART_ATTEMPTS; +retry: /* Reset firmware and hardware */ mwl8k_hw_reset(priv); @@ -5290,6 +5377,16 @@ static int mwl8k_init_firmware(struct ieee80211_hw *hw, char *fw_image, /* Reclaim memory once firmware is successfully loaded */ mwl8k_release_firmware(priv); + if (rc && count) { + /* FW did not start successfully; + * lets try one more time + */ + count--; + wiphy_err(hw->wiphy, "Trying to reload the firmware again\n"); + msleep(20); + goto retry; + } + return rc; } @@ -5365,7 +5462,14 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw) goto err_free_queues; } - memset(priv->ampdu, 0, sizeof(priv->ampdu)); + /* + * When hw restart is requested, + * mac80211 will take care of clearing + * the ampdu streams, so do not clear + * the ampdu state here + */ + if (!priv->hw_restart_in_progress) + memset(priv->ampdu, 0, sizeof(priv->ampdu)); /* * Temporarily enable interrupts. Initial firmware host @@ -5439,10 +5543,20 @@ static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image) { int i, rc = 0; struct mwl8k_priv *priv = hw->priv; + struct mwl8k_vif *vif, *tmp_vif; mwl8k_stop(hw); mwl8k_rxq_deinit(hw, 0); + /* + * All the existing interfaces are re-added by the ieee80211_reconfig; + * which means driver should remove existing interfaces before calling + * ieee80211_restart_hw + */ + if (priv->hw_restart_in_progress) + list_for_each_entry_safe(vif, tmp_vif, &priv->vif_list, list) + mwl8k_remove_vif(priv, vif); + for (i = 0; i < mwl8k_tx_queues(priv); i++) mwl8k_txq_deinit(hw, i); @@ -5454,6 +5568,9 @@ static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image) if (rc) goto fail; + if (priv->hw_restart_in_progress) + return rc; + rc = mwl8k_start(hw); if (rc) goto fail; @@ -5524,6 +5641,8 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv) INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker); /* Handle watchdog ba events */ INIT_WORK(&priv->watchdog_ba_handle, mwl8k_watchdog_ba_events); + /* To reload the firmware if it crashes */ + INIT_WORK(&priv->fw_reload, mwl8k_hw_restart_work); /* TX reclaim and RX tasklets. */ tasklet_init(&priv->poll_tx_task, mwl8k_tx_poll, (unsigned long)hw); @@ -5667,6 +5786,9 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, rc = mwl8k_init_firmware(hw, priv->fw_pref, true); if (rc) goto err_stop_firmware; + + priv->hw_restart_in_progress = false; + return rc; err_stop_firmware: -- cgit v1.2.1 From 00e8e69270cc8d5b9db98dcb73d26f21c2539010 Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Tue, 20 Dec 2011 11:39:29 +0530 Subject: mwl8k: Changing the driver version to 0.13 Signed-off-by: Yogesh Ashok Powar Signed-off-by: Nishant Sarmukadam Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index cf6927189682..8ea701261c61 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -28,7 +28,7 @@ #define MWL8K_DESC "Marvell TOPDOG(R) 802.11 Wireless Network Driver" #define MWL8K_NAME KBUILD_MODNAME -#define MWL8K_VERSION "0.12" +#define MWL8K_VERSION "0.13" /* Module parameters */ static unsigned ap_mode_default; -- cgit v1.2.1 From cb00ec382b57d35b955c085198cd54a0c1fcdc94 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 5 Jan 2012 09:13:06 -0500 Subject: ath6kl: revert USB support The ath6kl driver is causing build failures when the ath6kl bits are not built as modules. A better fix is forthcoming in a future release, but for now lets revert the problematic code. This reverts the following commits: fde57764ef8751b9aca11b6f6221ac5555bda699 d70385a26ad9a122a5450d066550470107b6bc38 59d954dda4b9b3f3e61d4b87a2b26952b8c4c09d Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath6kl/Kconfig | 25 +- drivers/net/wireless/ath/ath6kl/Makefile | 37 +-- drivers/net/wireless/ath/ath6kl/bmi.c | 10 +- drivers/net/wireless/ath/ath6kl/debug.h | 1 - drivers/net/wireless/ath/ath6kl/hif.c | 5 - drivers/net/wireless/ath/ath6kl/htc.c | 10 +- drivers/net/wireless/ath/ath6kl/sdio.c | 2 +- drivers/net/wireless/ath/ath6kl/usb.c | 431 ------------------------------- 8 files changed, 20 insertions(+), 501 deletions(-) delete mode 100644 drivers/net/wireless/ath/ath6kl/usb.c (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/ath/ath6kl/Kconfig b/drivers/net/wireless/ath/ath6kl/Kconfig index d755a5e7ed20..3d5f8be20eac 100644 --- a/drivers/net/wireless/ath/ath6kl/Kconfig +++ b/drivers/net/wireless/ath/ath6kl/Kconfig @@ -1,29 +1,12 @@ config ATH6KL - tristate "Atheros mobile chipsets support" - -config ATH6KL_SDIO - tristate "Atheros ath6kl SDIO support" - depends on ATH6KL + tristate "Atheros ath6kl support" depends on MMC depends on CFG80211 ---help--- This module adds support for wireless adapters based on - Atheros AR6003 and AR6004 chipsets running over SDIO. If you - choose to build it as a module, it will be called ath6kl_sdio. - Please note that AR6002 and AR6001 are not supported by this - driver. - -config ATH6KL_USB - tristate "Atheros ath6kl USB support" - depends on ATH6KL - depends on USB - depends on CFG80211 - depends on EXPERIMENTAL - ---help--- - This module adds support for wireless adapters based on - Atheros AR6004 chipset running over USB. This is still under - implementation and it isn't functional. If you choose to - build it as a module, it will be called ath6kl_usb. + Atheros AR6003 chipset running over SDIO. If you choose to + build it as a module, it will be called ath6kl. Pls note + that AR6002 and AR6001 are not supported by this driver. config ATH6KL_DEBUG bool "Atheros ath6kl debugging" diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile index e14cef9c3c0e..707069303550 100644 --- a/drivers/net/wireless/ath/ath6kl/Makefile +++ b/drivers/net/wireless/ath/ath6kl/Makefile @@ -21,30 +21,17 @@ # Author(s): ="Atheros" #------------------------------------------------------------------------------ -obj-$(CONFIG_ATH6KL_SDIO) := ath6kl_sdio.o -ath6kl_sdio-y += debug.o -ath6kl_sdio-y += hif.o -ath6kl_sdio-y += htc.o -ath6kl_sdio-y += bmi.o -ath6kl_sdio-y += cfg80211.o -ath6kl_sdio-y += init.o -ath6kl_sdio-y += main.o -ath6kl_sdio-y += txrx.o -ath6kl_sdio-y += wmi.o -ath6kl_sdio-y += sdio.o -ath6kl_sdio-$(CONFIG_NL80211_TESTMODE) += testmode.o - -obj-$(CONFIG_ATH6KL_USB) += ath6kl_usb.o -ath6kl_usb-y += debug.o -ath6kl_usb-y += hif.o -ath6kl_usb-y += htc.o -ath6kl_usb-y += bmi.o -ath6kl_usb-y += cfg80211.o -ath6kl_usb-y += init.o -ath6kl_usb-y += main.o -ath6kl_usb-y += txrx.o -ath6kl_usb-y += wmi.o -ath6kl_usb-y += usb.o -ath6kl_usb-$(CONFIG_NL80211_TESTMODE) += testmode.o +obj-$(CONFIG_ATH6KL) := ath6kl.o +ath6kl-y += debug.o +ath6kl-y += hif.o +ath6kl-y += htc.o +ath6kl-y += bmi.o +ath6kl-y += cfg80211.o +ath6kl-y += init.o +ath6kl-y += main.o +ath6kl-y += txrx.o +ath6kl-y += wmi.o +ath6kl-y += sdio.o +ath6kl-$(CONFIG_NL80211_TESTMODE) += testmode.o ccflags-y += -D__CHECK_ENDIAN__ diff --git a/drivers/net/wireless/ath/ath6kl/bmi.c b/drivers/net/wireless/ath/ath6kl/bmi.c index aef00d5a1438..bce3575c310a 100644 --- a/drivers/net/wireless/ath/ath6kl/bmi.c +++ b/drivers/net/wireless/ath/ath6kl/bmi.c @@ -57,14 +57,8 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar, return ret; } - if (ar->hif_type == ATH6KL_HIF_TYPE_USB) { - ret = ath6kl_hif_bmi_read(ar, (u8 *)targ_info, - sizeof(*targ_info)); - } else { - ret = ath6kl_hif_bmi_read(ar, (u8 *)&targ_info->version, - sizeof(targ_info->version)); - } - + ret = ath6kl_hif_bmi_read(ar, (u8 *)&targ_info->version, + sizeof(targ_info->version)); if (ret) { ath6kl_err("Unable to recv target info: %d\n", ret); return ret; diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h index e569c652e35c..9853c9c125c1 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.h +++ b/drivers/net/wireless/ath/ath6kl/debug.h @@ -41,7 +41,6 @@ enum ATH6K_DEBUG_MASK { ATH6KL_DBG_BOOT = BIT(18), /* driver init and fw boot */ ATH6KL_DBG_WMI_DUMP = BIT(19), ATH6KL_DBG_SUSPEND = BIT(20), - ATH6KL_DBG_USB = BIT(21), ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */ }; diff --git a/drivers/net/wireless/ath/ath6kl/hif.c b/drivers/net/wireless/ath/ath6kl/hif.c index 0772ef650174..e57da35e59fa 100644 --- a/drivers/net/wireless/ath/ath6kl/hif.c +++ b/drivers/net/wireless/ath/ath6kl/hif.c @@ -689,11 +689,6 @@ int ath6kl_hif_setup(struct ath6kl_device *dev) ath6kl_dbg(ATH6KL_DBG_HIF, "hif block size %d mbox addr 0x%x\n", dev->htc_cnxt->block_sz, dev->ar->mbox_info.htc_addr); - /* usb doesn't support enabling interrupts */ - /* FIXME: remove check once USB support is implemented */ - if (dev->ar->hif_type == ATH6KL_HIF_TYPE_USB) - return 0; - status = ath6kl_hif_disable_intrs(dev); fail_setup: diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c index b01702258faf..f3b63ca25c7e 100644 --- a/drivers/net/wireless/ath/ath6kl/htc.c +++ b/drivers/net/wireless/ath/ath6kl/htc.c @@ -2543,12 +2543,6 @@ int ath6kl_htc_wait_target(struct htc_target *target) struct htc_service_connect_resp resp; int status; - /* FIXME: remove once USB support is implemented */ - if (target->dev->ar->hif_type == ATH6KL_HIF_TYPE_USB) { - ath6kl_err("HTC doesn't support USB yet. Patience!\n"); - return -EOPNOTSUPP; - } - /* we should be getting 1 control message that the target is ready */ packet = htc_wait_for_ctrl_msg(target); @@ -2778,9 +2772,7 @@ void ath6kl_htc_cleanup(struct htc_target *target) { struct htc_packet *packet, *tmp_packet; - /* FIXME: remove check once USB support is implemented */ - if (target->dev->ar->hif_type != ATH6KL_HIF_TYPE_USB) - ath6kl_hif_cleanup_scatter(target->dev->ar); + ath6kl_hif_cleanup_scatter(target->dev->ar); list_for_each_entry_safe(packet, tmp_packet, &target->free_ctrl_txbuf, list) { diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index 15c3f56caf4f..9475e2d0d0b7 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c @@ -1332,7 +1332,7 @@ static const struct sdio_device_id ath6kl_sdio_devices[] = { MODULE_DEVICE_TABLE(sdio, ath6kl_sdio_devices); static struct sdio_driver ath6kl_sdio_driver = { - .name = "ath6kl_sdio", + .name = "ath6kl", .id_table = ath6kl_sdio_devices, .probe = ath6kl_sdio_probe, .remove = ath6kl_sdio_remove, diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c deleted file mode 100644 index e3cf397fcafe..000000000000 --- a/drivers/net/wireless/ath/ath6kl/usb.c +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Copyright (c) 2007-2011 Atheros Communications Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include - -#include "debug.h" -#include "core.h" - -/* usb device object */ -struct ath6kl_usb { - struct usb_device *udev; - struct usb_interface *interface; - u8 *diag_cmd_buffer; - u8 *diag_resp_buffer; - struct ath6kl *ar; -}; - -/* diagnostic command defnitions */ -#define ATH6KL_USB_CONTROL_REQ_SEND_BMI_CMD 1 -#define ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP 2 -#define ATH6KL_USB_CONTROL_REQ_DIAG_CMD 3 -#define ATH6KL_USB_CONTROL_REQ_DIAG_RESP 4 - -#define ATH6KL_USB_CTRL_DIAG_CC_READ 0 -#define ATH6KL_USB_CTRL_DIAG_CC_WRITE 1 - -struct ath6kl_usb_ctrl_diag_cmd_write { - __le32 cmd; - __le32 address; - __le32 value; - __le32 _pad[1]; -} __packed; - -struct ath6kl_usb_ctrl_diag_cmd_read { - __le32 cmd; - __le32 address; -} __packed; - -struct ath6kl_usb_ctrl_diag_resp_read { - __le32 value; -} __packed; - -#define ATH6KL_USB_MAX_DIAG_CMD (sizeof(struct ath6kl_usb_ctrl_diag_cmd_write)) -#define ATH6KL_USB_MAX_DIAG_RESP (sizeof(struct ath6kl_usb_ctrl_diag_resp_read)) - -static void ath6kl_usb_destroy(struct ath6kl_usb *ar_usb) -{ - usb_set_intfdata(ar_usb->interface, NULL); - - kfree(ar_usb->diag_cmd_buffer); - kfree(ar_usb->diag_resp_buffer); - - kfree(ar_usb); -} - -static struct ath6kl_usb *ath6kl_usb_create(struct usb_interface *interface) -{ - struct ath6kl_usb *ar_usb = NULL; - struct usb_device *dev = interface_to_usbdev(interface); - int status = 0; - - ar_usb = kzalloc(sizeof(struct ath6kl_usb), GFP_KERNEL); - if (ar_usb == NULL) - goto fail_ath6kl_usb_create; - - memset(ar_usb, 0, sizeof(struct ath6kl_usb)); - usb_set_intfdata(interface, ar_usb); - ar_usb->udev = dev; - ar_usb->interface = interface; - - ar_usb->diag_cmd_buffer = kzalloc(ATH6KL_USB_MAX_DIAG_CMD, GFP_KERNEL); - if (ar_usb->diag_cmd_buffer == NULL) { - status = -ENOMEM; - goto fail_ath6kl_usb_create; - } - - ar_usb->diag_resp_buffer = kzalloc(ATH6KL_USB_MAX_DIAG_RESP, - GFP_KERNEL); - if (ar_usb->diag_resp_buffer == NULL) { - status = -ENOMEM; - goto fail_ath6kl_usb_create; - } - -fail_ath6kl_usb_create: - if (status != 0) { - ath6kl_usb_destroy(ar_usb); - ar_usb = NULL; - } - return ar_usb; -} - -static void ath6kl_usb_device_detached(struct usb_interface *interface) -{ - struct ath6kl_usb *ar_usb; - - ar_usb = usb_get_intfdata(interface); - if (ar_usb == NULL) - return; - - ath6kl_stop_txrx(ar_usb->ar); - - ath6kl_core_cleanup(ar_usb->ar); - - ath6kl_usb_destroy(ar_usb); -} - -static int ath6kl_usb_submit_ctrl_out(struct ath6kl_usb *ar_usb, - u8 req, u16 value, u16 index, void *data, - u32 size) -{ - u8 *buf = NULL; - int ret; - - if (size > 0) { - buf = kmalloc(size, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - - memcpy(buf, data, size); - } - - /* note: if successful returns number of bytes transfered */ - ret = usb_control_msg(ar_usb->udev, - usb_sndctrlpipe(ar_usb->udev, 0), - req, - USB_DIR_OUT | USB_TYPE_VENDOR | - USB_RECIP_DEVICE, value, index, buf, - size, 1000); - - if (ret < 0) { - ath6kl_dbg(ATH6KL_DBG_USB, "%s failed,result = %d\n", - __func__, ret); - } - - kfree(buf); - - return 0; -} - -static int ath6kl_usb_submit_ctrl_in(struct ath6kl_usb *ar_usb, - u8 req, u16 value, u16 index, void *data, - u32 size) -{ - u8 *buf = NULL; - int ret; - - if (size > 0) { - buf = kmalloc(size, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - } - - /* note: if successful returns number of bytes transfered */ - ret = usb_control_msg(ar_usb->udev, - usb_rcvctrlpipe(ar_usb->udev, 0), - req, - USB_DIR_IN | USB_TYPE_VENDOR | - USB_RECIP_DEVICE, value, index, buf, - size, 2 * HZ); - - if (ret < 0) { - ath6kl_dbg(ATH6KL_DBG_USB, "%s failed,result = %d\n", - __func__, ret); - } - - memcpy((u8 *) data, buf, size); - - kfree(buf); - - return 0; -} - -static int ath6kl_usb_ctrl_msg_exchange(struct ath6kl_usb *ar_usb, - u8 req_val, u8 *req_buf, u32 req_len, - u8 resp_val, u8 *resp_buf, u32 *resp_len) -{ - int ret; - - /* send command */ - ret = ath6kl_usb_submit_ctrl_out(ar_usb, req_val, 0, 0, - req_buf, req_len); - - if (ret != 0) - return ret; - - if (resp_buf == NULL) { - /* no expected response */ - return ret; - } - - /* get response */ - ret = ath6kl_usb_submit_ctrl_in(ar_usb, resp_val, 0, 0, - resp_buf, *resp_len); - - return ret; -} - -static int ath6kl_usb_diag_read32(struct ath6kl *ar, u32 address, u32 *data) -{ - struct ath6kl_usb *ar_usb = ar->hif_priv; - struct ath6kl_usb_ctrl_diag_resp_read *resp; - struct ath6kl_usb_ctrl_diag_cmd_read *cmd; - u32 resp_len; - int ret; - - cmd = (struct ath6kl_usb_ctrl_diag_cmd_read *) ar_usb->diag_cmd_buffer; - - memset(cmd, 0, sizeof(*cmd)); - cmd->cmd = ATH6KL_USB_CTRL_DIAG_CC_READ; - cmd->address = cpu_to_le32(address); - resp_len = sizeof(*resp); - - ret = ath6kl_usb_ctrl_msg_exchange(ar_usb, - ATH6KL_USB_CONTROL_REQ_DIAG_CMD, - (u8 *) cmd, - sizeof(struct ath6kl_usb_ctrl_diag_cmd_write), - ATH6KL_USB_CONTROL_REQ_DIAG_RESP, - ar_usb->diag_resp_buffer, &resp_len); - - if (ret) - return ret; - - resp = (struct ath6kl_usb_ctrl_diag_resp_read *) - ar_usb->diag_resp_buffer; - - *data = le32_to_cpu(resp->value); - - return ret; -} - -static int ath6kl_usb_diag_write32(struct ath6kl *ar, u32 address, __le32 data) -{ - struct ath6kl_usb *ar_usb = ar->hif_priv; - struct ath6kl_usb_ctrl_diag_cmd_write *cmd; - - cmd = (struct ath6kl_usb_ctrl_diag_cmd_write *) ar_usb->diag_cmd_buffer; - - memset(cmd, 0, sizeof(struct ath6kl_usb_ctrl_diag_cmd_write)); - cmd->cmd = cpu_to_le32(ATH6KL_USB_CTRL_DIAG_CC_WRITE); - cmd->address = cpu_to_le32(address); - cmd->value = data; - - return ath6kl_usb_ctrl_msg_exchange(ar_usb, - ATH6KL_USB_CONTROL_REQ_DIAG_CMD, - (u8 *) cmd, - sizeof(*cmd), - 0, NULL, NULL); - -} - -static int ath6kl_usb_bmi_read(struct ath6kl *ar, u8 *buf, u32 len) -{ - struct ath6kl_usb *ar_usb = ar->hif_priv; - int ret; - - /* get response */ - ret = ath6kl_usb_submit_ctrl_in(ar_usb, - ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP, - 0, 0, buf, len); - if (ret != 0) { - ath6kl_err("Unable to read the bmi data from the device: %d\n", - ret); - return ret; - } - - return 0; -} - -static int ath6kl_usb_bmi_write(struct ath6kl *ar, u8 *buf, u32 len) -{ - struct ath6kl_usb *ar_usb = ar->hif_priv; - int ret; - - /* send command */ - ret = ath6kl_usb_submit_ctrl_out(ar_usb, - ATH6KL_USB_CONTROL_REQ_SEND_BMI_CMD, - 0, 0, buf, len); - if (ret != 0) { - ath6kl_err("unable to send the bmi data to the device: %d\n", - ret); - return ret; - } - - return 0; -} - -static int ath6kl_usb_power_on(struct ath6kl *ar) -{ - return 0; -} - -static int ath6kl_usb_power_off(struct ath6kl *ar) -{ - return 0; -} - -static const struct ath6kl_hif_ops ath6kl_usb_ops = { - .diag_read32 = ath6kl_usb_diag_read32, - .diag_write32 = ath6kl_usb_diag_write32, - .bmi_read = ath6kl_usb_bmi_read, - .bmi_write = ath6kl_usb_bmi_write, - .power_on = ath6kl_usb_power_on, - .power_off = ath6kl_usb_power_off, -}; - -/* ath6kl usb driver registered functions */ -static int ath6kl_usb_probe(struct usb_interface *interface, - const struct usb_device_id *id) -{ - struct usb_device *dev = interface_to_usbdev(interface); - struct ath6kl *ar; - struct ath6kl_usb *ar_usb = NULL; - int vendor_id, product_id; - int ret = 0; - - usb_get_dev(dev); - - vendor_id = le16_to_cpu(dev->descriptor.idVendor); - product_id = le16_to_cpu(dev->descriptor.idProduct); - - ath6kl_dbg(ATH6KL_DBG_USB, "vendor_id = %04x\n", vendor_id); - ath6kl_dbg(ATH6KL_DBG_USB, "product_id = %04x\n", product_id); - - if (interface->cur_altsetting) - ath6kl_dbg(ATH6KL_DBG_USB, "USB Interface %d\n", - interface->cur_altsetting->desc.bInterfaceNumber); - - - if (dev->speed == USB_SPEED_HIGH) - ath6kl_dbg(ATH6KL_DBG_USB, "USB 2.0 Host\n"); - else - ath6kl_dbg(ATH6KL_DBG_USB, "USB 1.1 Host\n"); - - ar_usb = ath6kl_usb_create(interface); - - if (ar_usb == NULL) { - ret = -ENOMEM; - goto err_usb_put; - } - - ar = ath6kl_core_alloc(&ar_usb->udev->dev); - if (ar == NULL) { - ath6kl_err("Failed to alloc ath6kl core\n"); - ret = -ENOMEM; - goto err_usb_destroy; - } - - ar->hif_priv = ar_usb; - ar->hif_type = ATH6KL_HIF_TYPE_USB; - ar->hif_ops = &ath6kl_usb_ops; - ar->mbox_info.block_size = 16; - ar->bmi.max_data_size = 252; - - ar_usb->ar = ar; - - ret = ath6kl_core_init(ar); - if (ret) { - ath6kl_err("Failed to init ath6kl core: %d\n", ret); - goto err_core_free; - } - - return ret; - -err_core_free: - ath6kl_core_free(ar); -err_usb_destroy: - ath6kl_usb_destroy(ar_usb); -err_usb_put: - usb_put_dev(dev); - - return ret; -} - -static void ath6kl_usb_remove(struct usb_interface *interface) -{ - usb_put_dev(interface_to_usbdev(interface)); - ath6kl_usb_device_detached(interface); -} - -/* table of devices that work with this driver */ -static struct usb_device_id ath6kl_usb_ids[] = { - {USB_DEVICE(0x0cf3, 0x9374)}, - { /* Terminating entry */ }, -}; - -MODULE_DEVICE_TABLE(usb, ath6kl_usb_ids); - -static struct usb_driver ath6kl_usb_driver = { - .name = "ath6kl_usb", - .probe = ath6kl_usb_probe, - .disconnect = ath6kl_usb_remove, - .id_table = ath6kl_usb_ids, -}; - -static int ath6kl_usb_init(void) -{ - usb_register(&ath6kl_usb_driver); - return 0; -} - -static void ath6kl_usb_exit(void) -{ - usb_deregister(&ath6kl_usb_driver); -} - -module_init(ath6kl_usb_init); -module_exit(ath6kl_usb_exit); - -MODULE_AUTHOR("Atheros Communications, Inc."); -MODULE_DESCRIPTION("Driver support for Atheros AR600x USB devices"); -MODULE_LICENSE("Dual BSD/GPL"); -MODULE_FIRMWARE(AR6004_HW_1_0_FIRMWARE_FILE); -MODULE_FIRMWARE(AR6004_HW_1_0_BOARD_DATA_FILE); -MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE); -MODULE_FIRMWARE(AR6004_HW_1_1_FIRMWARE_FILE); -MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE); -MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE); -- cgit v1.2.1