Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+41 −18
Original line number Original line Diff line number Diff line
@@ -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,
	};
	};
	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,


	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,
	 * 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,


	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
+1 −0
Original line number Original line Diff line number Diff line
@@ -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,


+1 −0
Original line number Original line Diff line number Diff line
@@ -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),
+0 −4
Original line number Original line Diff line number Diff line
@@ -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;
+0 −4
Original line number Original line Diff line number Diff line
@@ -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;