aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
diff options
context:
space:
mode:
authorAvraham Stern <avraham.stern@intel.com>2018-05-03 08:02:16 -0400
committerLuca Coelho <luciano.coelho@intel.com>2018-08-31 04:38:32 -0400
commit3baf7528d6f832b28622d1ddadd2e47f6c2b5e08 (patch)
tree3f16dd258294a7105376024ef9865f31f9db8f61 /drivers/net/wireless/intel/iwlwifi/mvm/rs.c
parent1a19c139be18ed4d6d681049cc48586fae070120 (diff)
iwlwifi: mvm: Send LQ command as async when necessary
The parameter that indicated whether the LQ command should be sent as sync or async was removed, causing the LQ command to be sent as sync from interrupt context (e.g. from the RX path). This resulted in a kernel warning: "scheduling while atomic" and failing to send the LQ command, which ultimately leads to a queue hang. Fix it by adding back the required parameter to send the command as sync only when it is allowed. Fixes: d94c5a820d10 ("iwlwifi: mvm: open BA session only when sta is authorized") Signed-off-by: Avraham Stern <avraham.stern@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/rs.c')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rs.c18
1 files changed, 8 insertions, 10 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
index 30cfd7d50bc9..d3e389a99a8a 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
@@ -1276,7 +1276,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1276 (unsigned long)(lq_sta->last_tx + 1276 (unsigned long)(lq_sta->last_tx +
1277 (IWL_MVM_RS_IDLE_TIMEOUT * HZ)))) { 1277 (IWL_MVM_RS_IDLE_TIMEOUT * HZ)))) {
1278 IWL_DEBUG_RATE(mvm, "Tx idle for too long. reinit rs\n"); 1278 IWL_DEBUG_RATE(mvm, "Tx idle for too long. reinit rs\n");
1279 iwl_mvm_rs_rate_init(mvm, sta, info->band); 1279 iwl_mvm_rs_rate_init(mvm, sta, info->band, true);
1280 return; 1280 return;
1281 } 1281 }
1282 lq_sta->last_tx = jiffies; 1282 lq_sta->last_tx = jiffies;
@@ -2859,9 +2859,8 @@ void rs_update_last_rssi(struct iwl_mvm *mvm,
2859static void rs_initialize_lq(struct iwl_mvm *mvm, 2859static void rs_initialize_lq(struct iwl_mvm *mvm,
2860 struct ieee80211_sta *sta, 2860 struct ieee80211_sta *sta,
2861 struct iwl_lq_sta *lq_sta, 2861 struct iwl_lq_sta *lq_sta,
2862 enum nl80211_band band) 2862 enum nl80211_band band, bool update)
2863{ 2863{
2864 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
2865 struct iwl_scale_tbl_info *tbl; 2864 struct iwl_scale_tbl_info *tbl;
2866 struct rs_rate *rate; 2865 struct rs_rate *rate;
2867 u8 active_tbl = 0; 2866 u8 active_tbl = 0;
@@ -2890,8 +2889,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
2890 rs_set_expected_tpt_table(lq_sta, tbl); 2889 rs_set_expected_tpt_table(lq_sta, tbl);
2891 rs_fill_lq_cmd(mvm, sta, lq_sta, rate); 2890 rs_fill_lq_cmd(mvm, sta, lq_sta, rate);
2892 /* TODO restore station should remember the lq cmd */ 2891 /* TODO restore station should remember the lq cmd */
2893 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, 2892 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, !update);
2894 mvmsta->sta_state < IEEE80211_STA_AUTHORIZED);
2895} 2893}
2896 2894
2897static void rs_drv_get_rate(void *mvm_r, struct ieee80211_sta *sta, 2895static void rs_drv_get_rate(void *mvm_r, struct ieee80211_sta *sta,
@@ -3144,7 +3142,7 @@ void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg)
3144 * Called after adding a new station to initialize rate scaling 3142 * Called after adding a new station to initialize rate scaling
3145 */ 3143 */
3146static void rs_drv_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 3144static void rs_drv_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
3147 enum nl80211_band band) 3145 enum nl80211_band band, bool update)
3148{ 3146{
3149 int i, j; 3147 int i, j;
3150 struct ieee80211_hw *hw = mvm->hw; 3148 struct ieee80211_hw *hw = mvm->hw;
@@ -3224,7 +3222,7 @@ static void rs_drv_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
3224#ifdef CONFIG_IWLWIFI_DEBUGFS 3222#ifdef CONFIG_IWLWIFI_DEBUGFS
3225 iwl_mvm_reset_frame_stats(mvm); 3223 iwl_mvm_reset_frame_stats(mvm);
3226#endif 3224#endif
3227 rs_initialize_lq(mvm, sta, lq_sta, band); 3225 rs_initialize_lq(mvm, sta, lq_sta, band, update);
3228} 3226}
3229 3227
3230static void rs_drv_rate_update(void *mvm_r, 3228static void rs_drv_rate_update(void *mvm_r,
@@ -3244,7 +3242,7 @@ static void rs_drv_rate_update(void *mvm_r,
3244 for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) 3242 for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++)
3245 ieee80211_stop_tx_ba_session(sta, tid); 3243 ieee80211_stop_tx_ba_session(sta, tid);
3246 3244
3247 iwl_mvm_rs_rate_init(mvm, sta, sband->band); 3245 iwl_mvm_rs_rate_init(mvm, sta, sband->band, true);
3248} 3246}
3249 3247
3250#ifdef CONFIG_MAC80211_DEBUGFS 3248#ifdef CONFIG_MAC80211_DEBUGFS
@@ -4098,12 +4096,12 @@ static const struct rate_control_ops rs_mvm_ops_drv = {
4098}; 4096};
4099 4097
4100void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 4098void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
4101 enum nl80211_band band) 4099 enum nl80211_band band, bool update)
4102{ 4100{
4103 if (iwl_mvm_has_tlc_offload(mvm)) 4101 if (iwl_mvm_has_tlc_offload(mvm))
4104 rs_fw_rate_init(mvm, sta, band); 4102 rs_fw_rate_init(mvm, sta, band);
4105 else 4103 else
4106 rs_drv_rate_init(mvm, sta, band); 4104 rs_drv_rate_init(mvm, sta, band, update);
4107} 4105}
4108 4106
4109int iwl_mvm_rate_control_register(void) 4107int iwl_mvm_rate_control_register(void)