Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless

John W. Linville says:

====================
Please pull this batch of fixes intended for the 3.14 stream...

For the iwlwifi one, Emmanuel says:

"As explicitly written in the commit message, we prefer to disable Tx
AMPDU on NICs supported by iwldvm. This feature gives a big boost in
Tx performance, but the firmware is buggy and we can't rely on it.
Our hope is that most of the users out there want wifi to surf on
the web which means that they care more for Rx traffic than for Tx.
People who want to enable it can do so with the help of a module
parameter."

On top of that...

Dan Carpenter fixes a typo/thinko in ath5k.

Olivier Langlois fixes a couple of rtlwifi issues, one which leaves
IRQs disabled too long (causing a variety of problems elsewhere),
and one which fixes an incorrect return code when failing to enable
the NIC.

Russell King fixes a NULL pointer dereference in hostap.

Stanislaw Gruszka fixes a DMA coherence issue in the rtl8187 driver.

Please let me know if there are problems!
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2014-02-18 16:57:42 -05:00
commit d3ec67c0e2
9 changed files with 75 additions and 16 deletions

View File

@ -110,7 +110,7 @@ ath5k_hw_radio_revision(struct ath5k_hw *ah, enum ieee80211_band band)
ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20)); ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20));
if (ah->ah_version == AR5K_AR5210) { if (ah->ah_version == AR5K_AR5210) {
srev = ath5k_hw_reg_read(ah, AR5K_PHY(256) >> 28) & 0xf; srev = (ath5k_hw_reg_read(ah, AR5K_PHY(256)) >> 28) & 0xf;
ret = (u16)ath5k_hw_bitswap(srev, 4) + 1; ret = (u16)ath5k_hw_bitswap(srev, 4) + 1;
} else { } else {
srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff; srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff;

View File

@ -496,7 +496,7 @@ void hostap_init_proc(local_info_t *local)
void hostap_remove_proc(local_info_t *local) void hostap_remove_proc(local_info_t *local)
{ {
remove_proc_subtree(local->ddev->name, hostap_proc); proc_remove(local->proc);
} }

View File

@ -696,6 +696,24 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
return ret; return ret;
} }
static inline bool iwl_enable_rx_ampdu(const struct iwl_cfg *cfg)
{
if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG)
return false;
return true;
}
static inline bool iwl_enable_tx_ampdu(const struct iwl_cfg *cfg)
{
if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG)
return false;
if (iwlwifi_mod_params.disable_11n & IWL_ENABLE_HT_TXAGG)
return true;
/* disabled by default */
return false;
}
static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
enum ieee80211_ampdu_mlme_action action, enum ieee80211_ampdu_mlme_action action,
@ -717,7 +735,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
switch (action) { switch (action) {
case IEEE80211_AMPDU_RX_START: case IEEE80211_AMPDU_RX_START:
if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG) if (!iwl_enable_rx_ampdu(priv->cfg))
break; break;
IWL_DEBUG_HT(priv, "start Rx\n"); IWL_DEBUG_HT(priv, "start Rx\n");
ret = iwl_sta_rx_agg_start(priv, sta, tid, *ssn); ret = iwl_sta_rx_agg_start(priv, sta, tid, *ssn);
@ -729,7 +747,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
case IEEE80211_AMPDU_TX_START: case IEEE80211_AMPDU_TX_START:
if (!priv->trans->ops->txq_enable) if (!priv->trans->ops->txq_enable)
break; break;
if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) if (!iwl_enable_tx_ampdu(priv->cfg))
break; break;
IWL_DEBUG_HT(priv, "start Tx\n"); IWL_DEBUG_HT(priv, "start Tx\n");
ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn);

View File

@ -1286,7 +1286,7 @@ module_param_named(swcrypto, iwlwifi_mod_params.sw_crypto, int, S_IRUGO);
MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
module_param_named(11n_disable, iwlwifi_mod_params.disable_11n, uint, S_IRUGO); module_param_named(11n_disable, iwlwifi_mod_params.disable_11n, uint, S_IRUGO);
MODULE_PARM_DESC(11n_disable, MODULE_PARM_DESC(11n_disable,
"disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX"); "disable 11n functionality, bitmap: 1: full, 2: disable agg TX, 4: disable agg RX, 8 enable agg TX");
module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K, module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K,
int, S_IRUGO); int, S_IRUGO);
MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0)"); MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0)");

View File

@ -79,9 +79,12 @@ enum iwl_power_level {
IWL_POWER_NUM IWL_POWER_NUM
}; };
#define IWL_DISABLE_HT_ALL BIT(0) enum iwl_disable_11n {
#define IWL_DISABLE_HT_TXAGG BIT(1) IWL_DISABLE_HT_ALL = BIT(0),
#define IWL_DISABLE_HT_RXAGG BIT(2) IWL_DISABLE_HT_TXAGG = BIT(1),
IWL_DISABLE_HT_RXAGG = BIT(2),
IWL_ENABLE_HT_TXAGG = BIT(3),
};
/** /**
* struct iwl_mod_params * struct iwl_mod_params
@ -90,7 +93,7 @@ enum iwl_power_level {
* *
* @sw_crypto: using hardware encryption, default = 0 * @sw_crypto: using hardware encryption, default = 0
* @disable_11n: disable 11n capabilities, default = 0, * @disable_11n: disable 11n capabilities, default = 0,
* use IWL_DISABLE_HT_* constants * use IWL_[DIS,EN]ABLE_HT_* constants
* @amsdu_size_8K: enable 8K amsdu size, default = 0 * @amsdu_size_8K: enable 8K amsdu size, default = 0
* @restart_fw: restart firmware, default = 1 * @restart_fw: restart firmware, default = 1
* @wd_disable: enable stuck queue check, default = 0 * @wd_disable: enable stuck queue check, default = 0

View File

@ -328,6 +328,24 @@ static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
ieee80211_free_txskb(hw, skb); ieee80211_free_txskb(hw, skb);
} }
static inline bool iwl_enable_rx_ampdu(const struct iwl_cfg *cfg)
{
if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG)
return false;
return true;
}
static inline bool iwl_enable_tx_ampdu(const struct iwl_cfg *cfg)
{
if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG)
return false;
if (iwlwifi_mod_params.disable_11n & IWL_ENABLE_HT_TXAGG)
return true;
/* enabled by default */
return true;
}
static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw, static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
enum ieee80211_ampdu_mlme_action action, enum ieee80211_ampdu_mlme_action action,
@ -347,7 +365,7 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
switch (action) { switch (action) {
case IEEE80211_AMPDU_RX_START: case IEEE80211_AMPDU_RX_START:
if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG) { if (!iwl_enable_rx_ampdu(mvm->cfg)) {
ret = -EINVAL; ret = -EINVAL;
break; break;
} }
@ -357,7 +375,7 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false); ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false);
break; break;
case IEEE80211_AMPDU_TX_START: case IEEE80211_AMPDU_TX_START:
if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) { if (!iwl_enable_tx_ampdu(mvm->cfg)) {
ret = -EINVAL; ret = -EINVAL;
break; break;
} }

View File

@ -15,6 +15,8 @@
#ifndef RTL8187_H #ifndef RTL8187_H
#define RTL8187_H #define RTL8187_H
#include <linux/cache.h>
#include "rtl818x.h" #include "rtl818x.h"
#include "leds.h" #include "leds.h"
@ -139,7 +141,10 @@ struct rtl8187_priv {
u8 aifsn[4]; u8 aifsn[4];
u8 rfkill_mask; u8 rfkill_mask;
struct { struct {
__le64 buf; union {
__le64 buf;
u8 dummy1[L1_CACHE_BYTES];
} ____cacheline_aligned;
struct sk_buff_head queue; struct sk_buff_head queue;
} b_tx_status; /* This queue is used by both -b and non-b devices */ } b_tx_status; /* This queue is used by both -b and non-b devices */
struct mutex io_mutex; struct mutex io_mutex;
@ -147,7 +152,8 @@ struct rtl8187_priv {
u8 bits8; u8 bits8;
__le16 bits16; __le16 bits16;
__le32 bits32; __le32 bits32;
} *io_dmabuf; u8 dummy2[L1_CACHE_BYTES];
} *io_dmabuf ____cacheline_aligned;
bool rfkill_off; bool rfkill_off;
u16 seqno; u16 seqno;
}; };

View File

@ -48,7 +48,7 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw)
/*<2> Enable Adapter */ /*<2> Enable Adapter */
if (rtlpriv->cfg->ops->hw_init(hw)) if (rtlpriv->cfg->ops->hw_init(hw))
return 1; return false;
RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
/*<3> Enable Interrupt */ /*<3> Enable Interrupt */

View File

@ -937,14 +937,26 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw)
bool is92c; bool is92c;
int err; int err;
u8 tmp_u1b; u8 tmp_u1b;
unsigned long flags;
rtlpci->being_init_adapter = true; rtlpci->being_init_adapter = true;
/* Since this function can take a very long time (up to 350 ms)
* and can be called with irqs disabled, reenable the irqs
* to let the other devices continue being serviced.
*
* It is safe doing so since our own interrupts will only be enabled
* in a subsequent step.
*/
local_save_flags(flags);
local_irq_enable();
rtlpriv->intf_ops->disable_aspm(hw); rtlpriv->intf_ops->disable_aspm(hw);
rtstatus = _rtl92ce_init_mac(hw); rtstatus = _rtl92ce_init_mac(hw);
if (!rtstatus) { if (!rtstatus) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n"); RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n");
err = 1; err = 1;
return err; goto exit;
} }
err = rtl92c_download_fw(hw); err = rtl92c_download_fw(hw);
@ -952,7 +964,7 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw)
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
"Failed to download FW. Init HW without FW now..\n"); "Failed to download FW. Init HW without FW now..\n");
err = 1; err = 1;
return err; goto exit;
} }
rtlhal->last_hmeboxnum = 0; rtlhal->last_hmeboxnum = 0;
@ -1032,6 +1044,8 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw)
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n"); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n");
} }
rtl92c_dm_init(hw); rtl92c_dm_init(hw);
exit:
local_irq_restore(flags);
rtlpci->being_init_adapter = false; rtlpci->being_init_adapter = false;
return err; return err;
} }