Commit 1591ab67 authored by David S. Miller's avatar David S. Miller

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

John W. Linville says:

====================
This is a batch of fixes intende for the 3.8 stream.

Regarding the iwlwifi bits, Johannes says this:

"Please pull to get a single fix from Emmanuel for a bug I introduced due
to misunderstanding the code."

Regarding the mac80211 bits, Johannes says this:

"I have a few small fixes for you:
 * some mesh frames would cause encryption warnings -- fixes from Bob
 * scanning would pretty much break an association if we transmitted
   anything to the AP while scanning -- fix from Stanislaw
 * mode injection was broken by channel contexts -- fix from Felix
 * FT roaming was broken: hardware crypto would get disabled by it"

Along with that, a handful of other fixes confined to specific drivers.

Avinash Patil fixes a typo in a NULL check in mwifiex.

Larry Finger fixes a build warning in rtlwifi.  Seems safe...

Stanislaw Gruszka fixes iwlegacy to prevent microcode errors when
switching from IBSS mode to STA mode.

Felix Fietkau provides a trio of ath9k fixes related to proper tuning.

Please let me know if there are problems!
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 794ed393 e91d1694
...@@ -976,6 +976,8 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, ...@@ -976,6 +976,8 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
AR_PHY_CL_TAB_1, AR_PHY_CL_TAB_1,
AR_PHY_CL_TAB_2 }; AR_PHY_CL_TAB_2 };
ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
if (rtt) { if (rtt) {
if (!ar9003_hw_rtt_restore(ah, chan)) if (!ar9003_hw_rtt_restore(ah, chan))
run_rtt_cal = true; run_rtt_cal = true;
......
...@@ -586,32 +586,19 @@ static void ar9003_hw_init_bb(struct ath_hw *ah, ...@@ -586,32 +586,19 @@ static void ar9003_hw_init_bb(struct ath_hw *ah,
ath9k_hw_synth_delay(ah, chan, synthDelay); ath9k_hw_synth_delay(ah, chan, synthDelay);
} }
static void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx) void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)
{ {
switch (rx) { if (ah->caps.tx_chainmask == 5 || ah->caps.rx_chainmask == 5)
case 0x5:
REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
AR_PHY_SWAP_ALT_CHAIN); AR_PHY_SWAP_ALT_CHAIN);
case 0x3:
case 0x1:
case 0x2:
case 0x7:
REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx); REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx);
REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx); REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx);
break;
default:
break;
}
if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7)) if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7))
REG_WRITE(ah, AR_SELFGEN_MASK, 0x3); tx = 3;
else
REG_WRITE(ah, AR_SELFGEN_MASK, tx);
if (tx == 0x5) { REG_WRITE(ah, AR_SELFGEN_MASK, tx);
REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
AR_PHY_SWAP_ALT_CHAIN);
}
} }
/* /*
......
...@@ -1066,6 +1066,7 @@ void ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain); ...@@ -1066,6 +1066,7 @@ void ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain);
int ar9003_paprd_init_table(struct ath_hw *ah); int ar9003_paprd_init_table(struct ath_hw *ah);
bool ar9003_paprd_is_done(struct ath_hw *ah); bool ar9003_paprd_is_done(struct ath_hw *ah);
bool ar9003_is_paprd_enabled(struct ath_hw *ah); bool ar9003_is_paprd_enabled(struct ath_hw *ah);
void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx);
/* Hardware family op attach helpers */ /* Hardware family op attach helpers */
void ar5008_hw_attach_phy_ops(struct ath_hw *ah); void ar5008_hw_attach_phy_ops(struct ath_hw *ah);
......
...@@ -1826,6 +1826,9 @@ static u32 fill_chainmask(u32 cap, u32 new) ...@@ -1826,6 +1826,9 @@ static u32 fill_chainmask(u32 cap, u32 new)
static bool validate_antenna_mask(struct ath_hw *ah, u32 val) static bool validate_antenna_mask(struct ath_hw *ah, u32 val)
{ {
if (AR_SREV_9300_20_OR_LATER(ah))
return true;
switch (val & 0x7) { switch (val & 0x7) {
case 0x1: case 0x1:
case 0x3: case 0x3:
......
...@@ -3958,17 +3958,21 @@ il_connection_init_rx_config(struct il_priv *il) ...@@ -3958,17 +3958,21 @@ il_connection_init_rx_config(struct il_priv *il)
memset(&il->staging, 0, sizeof(il->staging)); memset(&il->staging, 0, sizeof(il->staging));
if (!il->vif) { switch (il->iw_mode) {
case NL80211_IFTYPE_UNSPECIFIED:
il->staging.dev_type = RXON_DEV_TYPE_ESS; il->staging.dev_type = RXON_DEV_TYPE_ESS;
} else if (il->vif->type == NL80211_IFTYPE_STATION) { break;
case NL80211_IFTYPE_STATION:
il->staging.dev_type = RXON_DEV_TYPE_ESS; il->staging.dev_type = RXON_DEV_TYPE_ESS;
il->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; il->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
} else if (il->vif->type == NL80211_IFTYPE_ADHOC) { break;
case NL80211_IFTYPE_ADHOC:
il->staging.dev_type = RXON_DEV_TYPE_IBSS; il->staging.dev_type = RXON_DEV_TYPE_IBSS;
il->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK; il->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
il->staging.filter_flags = il->staging.filter_flags =
RXON_FILTER_BCON_AWARE_MSK | RXON_FILTER_ACCEPT_GRP_MSK; RXON_FILTER_BCON_AWARE_MSK | RXON_FILTER_ACCEPT_GRP_MSK;
} else { break;
default:
IL_ERR("Unsupported interface type %d\n", il->vif->type); IL_ERR("Unsupported interface type %d\n", il->vif->type);
return; return;
} }
...@@ -4550,8 +4554,7 @@ il_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) ...@@ -4550,8 +4554,7 @@ il_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
EXPORT_SYMBOL(il_mac_add_interface); EXPORT_SYMBOL(il_mac_add_interface);
static void static void
il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif, il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif)
bool mode_change)
{ {
lockdep_assert_held(&il->mutex); lockdep_assert_held(&il->mutex);
...@@ -4560,9 +4563,7 @@ il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif, ...@@ -4560,9 +4563,7 @@ il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif,
il_force_scan_end(il); il_force_scan_end(il);
} }
if (!mode_change)
il_set_mode(il); il_set_mode(il);
} }
void void
...@@ -4575,8 +4576,8 @@ il_mac_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) ...@@ -4575,8 +4576,8 @@ il_mac_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
WARN_ON(il->vif != vif); WARN_ON(il->vif != vif);
il->vif = NULL; il->vif = NULL;
il->iw_mode = NL80211_IFTYPE_UNSPECIFIED;
il_teardown_interface(il, vif, false); il_teardown_interface(il, vif);
memset(il->bssid, 0, ETH_ALEN); memset(il->bssid, 0, ETH_ALEN);
D_MAC80211("leave\n"); D_MAC80211("leave\n");
...@@ -4685,18 +4686,10 @@ il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ...@@ -4685,18 +4686,10 @@ il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
} }
/* success */ /* success */
il_teardown_interface(il, vif, true);
vif->type = newtype; vif->type = newtype;
vif->p2p = false; vif->p2p = false;
err = il_set_mode(il); il->iw_mode = newtype;
WARN_ON(err); il_teardown_interface(il, vif);
/*
* We've switched internally, but submitting to the
* device may have failed for some reason. Mask this
* error, because otherwise mac80211 will not switch
* (and set the interface type back) and we'll be
* out of sync with it.
*/
err = 0; err = 0;
out: out:
......
...@@ -1079,6 +1079,8 @@ static void iwlagn_set_tx_status(struct iwl_priv *priv, ...@@ -1079,6 +1079,8 @@ static void iwlagn_set_tx_status(struct iwl_priv *priv,
{ {
u16 status = le16_to_cpu(tx_resp->status.status); u16 status = le16_to_cpu(tx_resp->status.status);
info->flags &= ~IEEE80211_TX_CTL_AMPDU;
info->status.rates[0].count = tx_resp->failure_frame + 1; info->status.rates[0].count = tx_resp->failure_frame + 1;
info->flags |= iwl_tx_status_to_mac80211(status); info->flags |= iwl_tx_status_to_mac80211(status);
iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags), iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags),
......
...@@ -161,7 +161,7 @@ static int mwifiex_pcie_suspend(struct pci_dev *pdev, pm_message_t state) ...@@ -161,7 +161,7 @@ static int mwifiex_pcie_suspend(struct pci_dev *pdev, pm_message_t state)
if (pdev) { if (pdev) {
card = (struct pcie_service_card *) pci_get_drvdata(pdev); card = (struct pcie_service_card *) pci_get_drvdata(pdev);
if (!card || card->adapter) { if (!card || !card->adapter) {
pr_err("Card or adapter structure is not valid\n"); pr_err("Card or adapter structure is not valid\n");
return 0; return 0;
} }
......
...@@ -57,12 +57,12 @@ config RTL8192CU ...@@ -57,12 +57,12 @@ config RTL8192CU
config RTLWIFI config RTLWIFI
tristate tristate
depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE || RTL8723AE
default m default m
config RTLWIFI_DEBUG config RTLWIFI_DEBUG
bool "Additional debugging output" bool "Additional debugging output"
depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE || RTL8723AE
default y default y
config RTL8192C_COMMON config RTL8192C_COMMON
......
...@@ -164,7 +164,17 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, ...@@ -164,7 +164,17 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
sta = sta_info_get(sdata, mac_addr); sta = sta_info_get(sdata, mac_addr);
else else
sta = sta_info_get_bss(sdata, mac_addr); sta = sta_info_get_bss(sdata, mac_addr);
if (!sta) { /*
* The ASSOC test makes sure the driver is ready to
* receive the key. When wpa_supplicant has roamed
* using FT, it attempts to set the key before
* association has completed, this rejects that attempt
* so it will set the key again after assocation.
*
* TODO: accept the key if we have a station entry and
* add it to the device after the station.
*/
if (!sta || !test_sta_flag(sta, WLAN_STA_ASSOC)) {
ieee80211_key_free(sdata->local, key); ieee80211_key_free(sdata->local, key);
err = -ENOENT; err = -ENOENT;
goto out_unlock; goto out_unlock;
......
...@@ -1358,10 +1358,8 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata); ...@@ -1358,10 +1358,8 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata);
void ieee80211_sched_scan_stopped_work(struct work_struct *work); void ieee80211_sched_scan_stopped_work(struct work_struct *work);
/* off-channel helpers */ /* off-channel helpers */
void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local);
bool offchannel_ps_enable); void ieee80211_offchannel_return(struct ieee80211_local *local);
void ieee80211_offchannel_return(struct ieee80211_local *local,
bool offchannel_ps_disable);
void ieee80211_roc_setup(struct ieee80211_local *local); void ieee80211_roc_setup(struct ieee80211_local *local);
void ieee80211_start_next_roc(struct ieee80211_local *local); void ieee80211_start_next_roc(struct ieee80211_local *local);
void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata); void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata);
......
...@@ -215,6 +215,7 @@ static void prepare_frame_for_deferred_tx(struct ieee80211_sub_if_data *sdata, ...@@ -215,6 +215,7 @@ static void prepare_frame_for_deferred_tx(struct ieee80211_sub_if_data *sdata,
skb->priority = 7; skb->priority = 7;
info->control.vif = &sdata->vif; info->control.vif = &sdata->vif;
info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
ieee80211_set_qos_hdr(sdata, skb); ieee80211_set_qos_hdr(sdata, skb);
} }
...@@ -246,11 +247,13 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, ...@@ -246,11 +247,13 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn,
return -EAGAIN; return -EAGAIN;
skb = dev_alloc_skb(local->tx_headroom + skb = dev_alloc_skb(local->tx_headroom +
IEEE80211_ENCRYPT_HEADROOM +
IEEE80211_ENCRYPT_TAILROOM +
hdr_len + hdr_len +
2 + 15 /* PERR IE */); 2 + 15 /* PERR IE */);
if (!skb) if (!skb)
return -1; return -1;
skb_reserve(skb, local->tx_headroom); skb_reserve(skb, local->tx_headroom + IEEE80211_ENCRYPT_HEADROOM);
mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len);
memset(mgmt, 0, hdr_len); memset(mgmt, 0, hdr_len);
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
......
...@@ -102,8 +102,7 @@ static void ieee80211_offchannel_ps_disable(struct ieee80211_sub_if_data *sdata) ...@@ -102,8 +102,7 @@ static void ieee80211_offchannel_ps_disable(struct ieee80211_sub_if_data *sdata)
ieee80211_sta_reset_conn_monitor(sdata); ieee80211_sta_reset_conn_monitor(sdata);
} }
void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local)
bool offchannel_ps_enable)
{ {
struct ieee80211_sub_if_data *sdata; struct ieee80211_sub_if_data *sdata;
...@@ -134,8 +133,7 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, ...@@ -134,8 +133,7 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local,
if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { if (sdata->vif.type != NL80211_IFTYPE_MONITOR) {
netif_tx_stop_all_queues(sdata->dev); netif_tx_stop_all_queues(sdata->dev);
if (offchannel_ps_enable && if (sdata->vif.type == NL80211_IFTYPE_STATION &&
(sdata->vif.type == NL80211_IFTYPE_STATION) &&
sdata->u.mgd.associated) sdata->u.mgd.associated)
ieee80211_offchannel_ps_enable(sdata); ieee80211_offchannel_ps_enable(sdata);
} }
...@@ -143,8 +141,7 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, ...@@ -143,8 +141,7 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local,
mutex_unlock(&local->iflist_mtx); mutex_unlock(&local->iflist_mtx);
} }
void ieee80211_offchannel_return(struct ieee80211_local *local, void ieee80211_offchannel_return(struct ieee80211_local *local)
bool offchannel_ps_disable)
{ {
struct ieee80211_sub_if_data *sdata; struct ieee80211_sub_if_data *sdata;
...@@ -163,11 +160,9 @@ void ieee80211_offchannel_return(struct ieee80211_local *local, ...@@ -163,11 +160,9 @@ void ieee80211_offchannel_return(struct ieee80211_local *local,
continue; continue;
/* Tell AP we're back */ /* Tell AP we're back */
if (offchannel_ps_disable && if (sdata->vif.type == NL80211_IFTYPE_STATION &&
sdata->vif.type == NL80211_IFTYPE_STATION) { sdata->u.mgd.associated)
if (sdata->u.mgd.associated)
ieee80211_offchannel_ps_disable(sdata); ieee80211_offchannel_ps_disable(sdata);
}
if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { if (sdata->vif.type != NL80211_IFTYPE_MONITOR) {
/* /*
...@@ -385,7 +380,7 @@ void ieee80211_sw_roc_work(struct work_struct *work) ...@@ -385,7 +380,7 @@ void ieee80211_sw_roc_work(struct work_struct *work)
local->tmp_channel = NULL; local->tmp_channel = NULL;
ieee80211_hw_config(local, 0); ieee80211_hw_config(local, 0);
ieee80211_offchannel_return(local, true); ieee80211_offchannel_return(local);
} }
ieee80211_recalc_idle(local); ieee80211_recalc_idle(local);
......
...@@ -292,7 +292,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted, ...@@ -292,7 +292,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted,
if (!was_hw_scan) { if (!was_hw_scan) {
ieee80211_configure_filter(local); ieee80211_configure_filter(local);
drv_sw_scan_complete(local); drv_sw_scan_complete(local);
ieee80211_offchannel_return(local, true); ieee80211_offchannel_return(local);
} }
ieee80211_recalc_idle(local); ieee80211_recalc_idle(local);
...@@ -341,7 +341,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local) ...@@ -341,7 +341,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
local->next_scan_state = SCAN_DECISION; local->next_scan_state = SCAN_DECISION;
local->scan_channel_idx = 0; local->scan_channel_idx = 0;
ieee80211_offchannel_stop_vifs(local, true); ieee80211_offchannel_stop_vifs(local);
ieee80211_configure_filter(local); ieee80211_configure_filter(local);
...@@ -678,12 +678,8 @@ static void ieee80211_scan_state_suspend(struct ieee80211_local *local, ...@@ -678,12 +678,8 @@ static void ieee80211_scan_state_suspend(struct ieee80211_local *local,
local->scan_channel = NULL; local->scan_channel = NULL;
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
/* /* disable PS */
* Re-enable vifs and beaconing. Leave PS ieee80211_offchannel_return(local);
* in off-channel state..will put that back
* on-channel at the end of scanning.
*/
ieee80211_offchannel_return(local, false);
*next_delay = HZ / 5; *next_delay = HZ / 5;
/* afterwards, resume scan & go to next channel */ /* afterwards, resume scan & go to next channel */
...@@ -693,8 +689,7 @@ static void ieee80211_scan_state_suspend(struct ieee80211_local *local, ...@@ -693,8 +689,7 @@ static void ieee80211_scan_state_suspend(struct ieee80211_local *local,
static void ieee80211_scan_state_resume(struct ieee80211_local *local, static void ieee80211_scan_state_resume(struct ieee80211_local *local,
unsigned long *next_delay) unsigned long *next_delay)
{ {
/* PS already is in off-channel mode */ ieee80211_offchannel_stop_vifs(local);
ieee80211_offchannel_stop_vifs(local, false);
if (local->ops->flush) { if (local->ops->flush) {
drv_flush(local, false); drv_flush(local, false);
......
...@@ -1673,10 +1673,13 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, ...@@ -1673,10 +1673,13 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
chanctx_conf = chanctx_conf =
rcu_dereference(tmp_sdata->vif.chanctx_conf); rcu_dereference(tmp_sdata->vif.chanctx_conf);
} }
if (!chanctx_conf)
goto fail_rcu;
if (chanctx_conf)
chan = chanctx_conf->def.chan; chan = chanctx_conf->def.chan;
else if (!local->use_chanctx)
chan = local->_oper_channel;
else
goto fail_rcu;
/* /*
* Frame injection is not allowed if beaconing is not allowed * Frame injection is not allowed if beaconing is not allowed
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment