Commit 4ac6cb59 authored by Johannes Berg's avatar Johannes Berg

iwlwifi: mvm: query firmware for non-QoS seqno

Instead of keeping track of the non-QoS seqno for each station,
query the firmware when suspending, that's more efficient. As
this can fail, move the station ID mangling later in the code.
Reviewed-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent f6c6ad42
...@@ -793,6 +793,31 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif, ...@@ -793,6 +793,31 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
return 0; return 0;
} }
static int iwl_mvm_get_last_nonqos_seq(struct iwl_mvm *mvm,
struct ieee80211_vif *vif)
{
struct iwl_host_cmd cmd = {
.id = NON_QOS_TX_COUNTER_CMD,
.flags = CMD_SYNC | CMD_WANT_SKB,
};
int err;
u32 size;
err = iwl_mvm_send_cmd(mvm, &cmd);
if (err)
return err;
size = le32_to_cpu(cmd.resp_pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
size -= sizeof(cmd.resp_pkt->hdr);
if (size != sizeof(__le32))
err = -EINVAL;
else
err = le32_to_cpup((__le32 *)cmd.resp_pkt->data);
iwl_free_resp(&cmd);
return err;
}
static int __iwl_mvm_suspend(struct ieee80211_hw *hw, static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
struct cfg80211_wowlan *wowlan, struct cfg80211_wowlan *wowlan,
bool test) bool test)
...@@ -829,7 +854,6 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, ...@@ -829,7 +854,6 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
}; };
int ret, i; int ret, i;
int len __maybe_unused; int len __maybe_unused;
u16 seq;
u8 old_aux_sta_id, old_ap_sta_id = IWL_MVM_STATION_COUNT; u8 old_aux_sta_id, old_ap_sta_id = IWL_MVM_STATION_COUNT;
if (!wowlan) { if (!wowlan) {
...@@ -872,26 +896,15 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, ...@@ -872,26 +896,15 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
mvm_ap_sta = (struct iwl_mvm_sta *)ap_sta->drv_priv; mvm_ap_sta = (struct iwl_mvm_sta *)ap_sta->drv_priv;
/*
* The D3 firmware still hardcodes the AP station ID for the
* BSS we're associated with as 0. Store the real STA ID here
* and assign 0. When we leave this function, we'll restore
* the original value for the resume code.
*/
old_ap_sta_id = mvm_ap_sta->sta_id;
mvm_ap_sta->sta_id = 0;
mvmvif->ap_sta_id = 0;
/* TODO: wowlan_config_cmd.wowlan_ba_teardown_tids */ /* TODO: wowlan_config_cmd.wowlan_ba_teardown_tids */
wowlan_config_cmd.is_11n_connection = ap_sta->ht_cap.ht_supported; wowlan_config_cmd.is_11n_connection = ap_sta->ht_cap.ht_supported;
/* /* Query the last used seqno and set it */
* We know the last used seqno, and the uCode expects to know that ret = iwl_mvm_get_last_nonqos_seq(mvm, vif);
* one, it will increment before TX. if (ret < 0)
*/ goto out_noreset;
seq = mvm_ap_sta->last_seq_ctl & IEEE80211_SCTL_SEQ; wowlan_config_cmd.non_qos_seq = cpu_to_le16(ret);
wowlan_config_cmd.non_qos_seq = cpu_to_le16(seq);
/* /*
* For QoS counters, we store the one to use next, so subtract 0x10 * For QoS counters, we store the one to use next, so subtract 0x10
...@@ -899,7 +912,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, ...@@ -899,7 +912,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
* increment after using the value (i.e. store the next value to use). * increment after using the value (i.e. store the next value to use).
*/ */
for (i = 0; i < IWL_MAX_TID_COUNT; i++) { for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
seq = mvm_ap_sta->tid_data[i].seq_number; u16 seq = mvm_ap_sta->tid_data[i].seq_number;
seq -= 0x10; seq -= 0x10;
wowlan_config_cmd.qos_seq[i] = cpu_to_le16(seq); wowlan_config_cmd.qos_seq[i] = cpu_to_le16(seq);
} }
...@@ -944,6 +957,16 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, ...@@ -944,6 +957,16 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
iwl_trans_stop_device(mvm->trans); iwl_trans_stop_device(mvm->trans);
/*
* The D3 firmware still hardcodes the AP station ID for the
* BSS we're associated with as 0. Store the real STA ID here
* and assign 0. When we leave this function, we'll restore
* the original value for the resume code.
*/
old_ap_sta_id = mvm_ap_sta->sta_id;
mvm_ap_sta->sta_id = 0;
mvmvif->ap_sta_id = 0;
/* /*
* Set the HW restart bit -- this is mostly true as we're * Set the HW restart bit -- this is mostly true as we're
* going to load new firmware and reprogram that, though * going to load new firmware and reprogram that, though
......
...@@ -114,6 +114,7 @@ enum { ...@@ -114,6 +114,7 @@ enum {
TIME_EVENT_NOTIFICATION = 0x2a, TIME_EVENT_NOTIFICATION = 0x2a,
BINDING_CONTEXT_CMD = 0x2b, BINDING_CONTEXT_CMD = 0x2b,
TIME_QUOTA_CMD = 0x2c, TIME_QUOTA_CMD = 0x2c,
NON_QOS_TX_COUNTER_CMD = 0x2d,
LQ_CMD = 0x4e, LQ_CMD = 0x4e,
......
...@@ -249,6 +249,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = { ...@@ -249,6 +249,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
CMD(TIME_EVENT_NOTIFICATION), CMD(TIME_EVENT_NOTIFICATION),
CMD(BINDING_CONTEXT_CMD), CMD(BINDING_CONTEXT_CMD),
CMD(TIME_QUOTA_CMD), CMD(TIME_QUOTA_CMD),
CMD(NON_QOS_TX_COUNTER_CMD),
CMD(RADIO_VERSION_NOTIFICATION), CMD(RADIO_VERSION_NOTIFICATION),
CMD(SCAN_REQUEST_CMD), CMD(SCAN_REQUEST_CMD),
CMD(SCAN_ABORT_CMD), CMD(SCAN_ABORT_CMD),
......
...@@ -293,10 +293,6 @@ struct iwl_mvm_sta { ...@@ -293,10 +293,6 @@ struct iwl_mvm_sta {
struct iwl_lq_sta lq_sta; struct iwl_lq_sta lq_sta;
struct ieee80211_vif *vif; struct ieee80211_vif *vif;
#ifdef CONFIG_PM_SLEEP
u16 last_seq_ctl;
#endif
/* Temporary, until the new TLC will control the Tx protection */ /* Temporary, until the new TLC will control the Tx protection */
s8 tx_protection; s8 tx_protection;
bool tt_tx_protection; bool tt_tx_protection;
......
...@@ -668,10 +668,6 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, ...@@ -668,10 +668,6 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
iwl_mvm_check_ratid_empty(mvm, sta, tid); iwl_mvm_check_ratid_empty(mvm, sta, tid);
spin_unlock_bh(&mvmsta->lock); spin_unlock_bh(&mvmsta->lock);
} }
#ifdef CONFIG_PM_SLEEP
mvmsta->last_seq_ctl = seq_ctl;
#endif
} else { } else {
sta = NULL; sta = NULL;
mvmsta = NULL; mvmsta = NULL;
......
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