aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2019-10-19 06:03:29 -0400
committerKalle Valo <kvalo@codeaurora.org>2019-10-23 06:31:33 -0400
commit91cf5dede57f9c4030c1378745d612eec2075652 (patch)
tree5f15163d1b519ebd5c121c8cde8b8f9aa00b5d2f
parente55890150a961944e861a46efc8599f80f25de76 (diff)
iwlwifi: mvm: handle iwl_mvm_tvqm_enable_txq() error return
iwl_mvm_tvqm_enable_txq() can return an error, notably if unable to allocate memory for the queue. Handle this error throughout, avoiding storing the invalid value into a u16 which later leads to a disable of an invalid queue ("queue 65524 not used", where 65524 is just -ENOMEM in a u16). Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/sta.c140
1 files changed, 83 insertions, 57 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index 0bedba4c61f2..b3768d5d852a 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -1482,6 +1482,13 @@ static void iwl_mvm_realloc_queues_after_restart(struct iwl_mvm *mvm,
1482 mvm_sta->sta_id, i); 1482 mvm_sta->sta_id, i);
1483 txq_id = iwl_mvm_tvqm_enable_txq(mvm, mvm_sta->sta_id, 1483 txq_id = iwl_mvm_tvqm_enable_txq(mvm, mvm_sta->sta_id,
1484 i, wdg); 1484 i, wdg);
1485 /*
1486 * on failures, just set it to IWL_MVM_INVALID_QUEUE
1487 * to try again later, we have no other good way of
1488 * failing here
1489 */
1490 if (txq_id < 0)
1491 txq_id = IWL_MVM_INVALID_QUEUE;
1485 tid_data->txq_id = txq_id; 1492 tid_data->txq_id = txq_id;
1486 1493
1487 /* 1494 /*
@@ -1950,30 +1957,73 @@ void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta)
1950 sta->sta_id = IWL_MVM_INVALID_STA; 1957 sta->sta_id = IWL_MVM_INVALID_STA;
1951} 1958}
1952 1959
1953static void iwl_mvm_enable_aux_snif_queue(struct iwl_mvm *mvm, u16 *queue, 1960static void iwl_mvm_enable_aux_snif_queue(struct iwl_mvm *mvm, u16 queue,
1954 u8 sta_id, u8 fifo) 1961 u8 sta_id, u8 fifo)
1955{ 1962{
1956 unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ? 1963 unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ?
1957 mvm->trans->trans_cfg->base_params->wd_timeout : 1964 mvm->trans->trans_cfg->base_params->wd_timeout :
1958 IWL_WATCHDOG_DISABLED; 1965 IWL_WATCHDOG_DISABLED;
1966 struct iwl_trans_txq_scd_cfg cfg = {
1967 .fifo = fifo,
1968 .sta_id = sta_id,
1969 .tid = IWL_MAX_TID_COUNT,
1970 .aggregate = false,
1971 .frame_limit = IWL_FRAME_LIMIT,
1972 };
1973
1974 WARN_ON(iwl_mvm_has_new_tx_api(mvm));
1975
1976 iwl_mvm_enable_txq(mvm, NULL, queue, 0, &cfg, wdg_timeout);
1977}
1978
1979static int iwl_mvm_enable_aux_snif_queue_tvqm(struct iwl_mvm *mvm, u8 sta_id)
1980{
1981 unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ?
1982 mvm->trans->trans_cfg->base_params->wd_timeout :
1983 IWL_WATCHDOG_DISABLED;
1984
1985 WARN_ON(!iwl_mvm_has_new_tx_api(mvm));
1986
1987 return iwl_mvm_tvqm_enable_txq(mvm, sta_id, IWL_MAX_TID_COUNT,
1988 wdg_timeout);
1989}
1959 1990
1991static int iwl_mvm_add_int_sta_with_queue(struct iwl_mvm *mvm, int macidx,
1992 int maccolor,
1993 struct iwl_mvm_int_sta *sta,
1994 u16 *queue, int fifo)
1995{
1996 int ret;
1997
1998 /* Map queue to fifo - needs to happen before adding station */
1999 if (!iwl_mvm_has_new_tx_api(mvm))
2000 iwl_mvm_enable_aux_snif_queue(mvm, *queue, sta->sta_id, fifo);
2001
2002 ret = iwl_mvm_add_int_sta_common(mvm, sta, NULL, macidx, maccolor);
2003 if (ret) {
2004 if (!iwl_mvm_has_new_tx_api(mvm))
2005 iwl_mvm_disable_txq(mvm, NULL, *queue,
2006 IWL_MAX_TID_COUNT, 0);
2007 return ret;
2008 }
2009
2010 /*
2011 * For 22000 firmware and on we cannot add queue to a station unknown
2012 * to firmware so enable queue here - after the station was added
2013 */
1960 if (iwl_mvm_has_new_tx_api(mvm)) { 2014 if (iwl_mvm_has_new_tx_api(mvm)) {
1961 int tvqm_queue = 2015 int txq;
1962 iwl_mvm_tvqm_enable_txq(mvm, sta_id,
1963 IWL_MAX_TID_COUNT,
1964 wdg_timeout);
1965 *queue = tvqm_queue;
1966 } else {
1967 struct iwl_trans_txq_scd_cfg cfg = {
1968 .fifo = fifo,
1969 .sta_id = sta_id,
1970 .tid = IWL_MAX_TID_COUNT,
1971 .aggregate = false,
1972 .frame_limit = IWL_FRAME_LIMIT,
1973 };
1974 2016
1975 iwl_mvm_enable_txq(mvm, NULL, *queue, 0, &cfg, wdg_timeout); 2017 txq = iwl_mvm_enable_aux_snif_queue_tvqm(mvm, sta->sta_id);
2018 if (txq < 0) {
2019 iwl_mvm_rm_sta_common(mvm, sta->sta_id);
2020 return txq;
2021 }
2022
2023 *queue = txq;
1976 } 2024 }
2025
2026 return 0;
1977} 2027}
1978 2028
1979int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm) 2029int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
@@ -1989,59 +2039,26 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
1989 if (ret) 2039 if (ret)
1990 return ret; 2040 return ret;
1991 2041
1992 /* Map Aux queue to fifo - needs to happen before adding Aux station */ 2042 ret = iwl_mvm_add_int_sta_with_queue(mvm, MAC_INDEX_AUX, 0,
1993 if (!iwl_mvm_has_new_tx_api(mvm)) 2043 &mvm->aux_sta, &mvm->aux_queue,
1994 iwl_mvm_enable_aux_snif_queue(mvm, &mvm->aux_queue, 2044 IWL_MVM_TX_FIFO_MCAST);
1995 mvm->aux_sta.sta_id,
1996 IWL_MVM_TX_FIFO_MCAST);
1997
1998 ret = iwl_mvm_add_int_sta_common(mvm, &mvm->aux_sta, NULL,
1999 MAC_INDEX_AUX, 0);
2000 if (ret) { 2045 if (ret) {
2001 iwl_mvm_dealloc_int_sta(mvm, &mvm->aux_sta); 2046 iwl_mvm_dealloc_int_sta(mvm, &mvm->aux_sta);
2002 return ret; 2047 return ret;
2003 } 2048 }
2004 2049
2005 /*
2006 * For 22000 firmware and on we cannot add queue to a station unknown
2007 * to firmware so enable queue here - after the station was added
2008 */
2009 if (iwl_mvm_has_new_tx_api(mvm))
2010 iwl_mvm_enable_aux_snif_queue(mvm, &mvm->aux_queue,
2011 mvm->aux_sta.sta_id,
2012 IWL_MVM_TX_FIFO_MCAST);
2013
2014 return 0; 2050 return 0;
2015} 2051}
2016 2052
2017int iwl_mvm_add_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 2053int iwl_mvm_add_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
2018{ 2054{
2019 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 2055 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
2020 int ret;
2021 2056
2022 lockdep_assert_held(&mvm->mutex); 2057 lockdep_assert_held(&mvm->mutex);
2023 2058
2024 /* Map snif queue to fifo - must happen before adding snif station */ 2059 return iwl_mvm_add_int_sta_with_queue(mvm, mvmvif->id, mvmvif->color,
2025 if (!iwl_mvm_has_new_tx_api(mvm)) 2060 &mvm->snif_sta, &mvm->snif_queue,
2026 iwl_mvm_enable_aux_snif_queue(mvm, &mvm->snif_queue,
2027 mvm->snif_sta.sta_id,
2028 IWL_MVM_TX_FIFO_BE); 2061 IWL_MVM_TX_FIFO_BE);
2029
2030 ret = iwl_mvm_add_int_sta_common(mvm, &mvm->snif_sta, vif->addr,
2031 mvmvif->id, 0);
2032 if (ret)
2033 return ret;
2034
2035 /*
2036 * For 22000 firmware and on we cannot add queue to a station unknown
2037 * to firmware so enable queue here - after the station was added
2038 */
2039 if (iwl_mvm_has_new_tx_api(mvm))
2040 iwl_mvm_enable_aux_snif_queue(mvm, &mvm->snif_queue,
2041 mvm->snif_sta.sta_id,
2042 IWL_MVM_TX_FIFO_BE);
2043
2044 return 0;
2045} 2062}
2046 2063
2047int iwl_mvm_rm_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 2064int iwl_mvm_rm_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
@@ -2133,6 +2150,10 @@ int iwl_mvm_send_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
2133 queue = iwl_mvm_tvqm_enable_txq(mvm, bsta->sta_id, 2150 queue = iwl_mvm_tvqm_enable_txq(mvm, bsta->sta_id,
2134 IWL_MAX_TID_COUNT, 2151 IWL_MAX_TID_COUNT,
2135 wdg_timeout); 2152 wdg_timeout);
2153 if (queue < 0) {
2154 iwl_mvm_rm_sta_common(mvm, bsta->sta_id);
2155 return queue;
2156 }
2136 2157
2137 if (vif->type == NL80211_IFTYPE_AP || 2158 if (vif->type == NL80211_IFTYPE_AP ||
2138 vif->type == NL80211_IFTYPE_ADHOC) 2159 vif->type == NL80211_IFTYPE_ADHOC)
@@ -2307,10 +2328,8 @@ int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
2307 } 2328 }
2308 ret = iwl_mvm_add_int_sta_common(mvm, msta, maddr, 2329 ret = iwl_mvm_add_int_sta_common(mvm, msta, maddr,
2309 mvmvif->id, mvmvif->color); 2330 mvmvif->id, mvmvif->color);
2310 if (ret) { 2331 if (ret)
2311 iwl_mvm_dealloc_int_sta(mvm, msta); 2332 goto err;
2312 return ret;
2313 }
2314 2333
2315 /* 2334 /*
2316 * Enable cab queue after the ADD_STA command is sent. 2335 * Enable cab queue after the ADD_STA command is sent.
@@ -2323,6 +2342,10 @@ int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
2323 int queue = iwl_mvm_tvqm_enable_txq(mvm, msta->sta_id, 2342 int queue = iwl_mvm_tvqm_enable_txq(mvm, msta->sta_id,
2324 0, 2343 0,
2325 timeout); 2344 timeout);
2345 if (queue < 0) {
2346 ret = queue;
2347 goto err;
2348 }
2326 mvmvif->cab_queue = queue; 2349 mvmvif->cab_queue = queue;
2327 } else if (!fw_has_api(&mvm->fw->ucode_capa, 2350 } else if (!fw_has_api(&mvm->fw->ucode_capa,
2328 IWL_UCODE_TLV_API_STA_TYPE)) 2351 IWL_UCODE_TLV_API_STA_TYPE))
@@ -2330,6 +2353,9 @@ int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
2330 timeout); 2353 timeout);
2331 2354
2332 return 0; 2355 return 0;
2356err:
2357 iwl_mvm_dealloc_int_sta(mvm, msta);
2358 return ret;
2333} 2359}
2334 2360
2335static int __iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, u8 sta_id, 2361static int __iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, u8 sta_id,