All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/12] iwlwifi: updates intended for v5.15 2021-08-05
@ 2021-08-05 10:19 Luca Coelho
  2021-08-05 10:19 ` [PATCH 01/12] iwlwifi: mvm: d3: separate TKIP data from key iteration Luca Coelho
                   ` (11 more replies)
  0 siblings, 12 replies; 14+ messages in thread
From: Luca Coelho @ 2021-08-05 10:19 UTC (permalink / raw)
  To: kvalo; +Cc: luca, linux-wireless

From: Luca Coelho <luciano.coelho@intel.com>

Hi,

Here's the fourth set of patches intended for v5.15.  It's the usual
development, new features, cleanups and bugfixes.

The changes are:

* A bunch of changes in the D3 code, including new FW API;
* Finalize the refactoring of 6GHz scan;
* Initial changes in the SAR profile code;
* Some other small fixes, clean-ups and improvements.

As usual, I'm pushing this to a pending branch, for kbuild bot, and
will send a pull-request later.

Please review.

Cheers,
Luca.


Avraham Stern (1):
  iwlwifi: mvm: silently drop encrypted frames for unknown station

Ilan Peer (1):
  iwlwifi: mvm: Refactor setting of SSIDs for 6GHz scan

Johannes Berg (7):
  iwlwifi: mvm: d3: separate TKIP data from key iteration
  iwlwifi: mvm: d3: remove fixed cmd_flags argument
  iwlwifi: mvm: d3: refactor TSC/RSC configuration
  iwlwifi: mvm: d3: add separate key iteration for GTK type
  iwlwifi: mvm: d3: make key reprogramming iteration optional
  iwlwifi: mvm: d3: implement RSC command version 5
  iwlwifi: mvm: fix access to BSS elements

Luca Coelho (3):
  iwlwifi: rename ACPI_SAR_NUM_CHAIN_LIMITS to ACPI_SAR_NUM_CHAINS
  iwlwifi: convert flat SAR profile table to a struct version
  iwlwifi: remove ACPI_SAR_NUM_TABLES definition

 drivers/net/wireless/intel/iwlwifi/fw/acpi.c  |  36 +-
 drivers/net/wireless/intel/iwlwifi/fw/acpi.h  |  16 +-
 .../wireless/intel/iwlwifi/fw/api/commands.h  |   3 +-
 .../net/wireless/intel/iwlwifi/fw/api/d3.h    |  22 +-
 drivers/net/wireless/intel/iwlwifi/mvm/d3.c   | 575 +++++++++++++-----
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c   |   3 +-
 .../net/wireless/intel/iwlwifi/mvm/mac80211.c |   8 +-
 drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c |   4 +-
 drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 104 +---
 9 files changed, 494 insertions(+), 277 deletions(-)

-- 
2.32.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 01/12] iwlwifi: mvm: d3: separate TKIP data from key iteration
  2021-08-05 10:19 [PATCH 00/12] iwlwifi: updates intended for v5.15 2021-08-05 Luca Coelho
@ 2021-08-05 10:19 ` Luca Coelho
  2021-08-26 20:35   ` Luca Coelho
  2021-08-05 10:19 ` [PATCH 02/12] iwlwifi: mvm: d3: remove fixed cmd_flags argument Luca Coelho
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 14+ messages in thread
From: Luca Coelho @ 2021-08-05 10:19 UTC (permalink / raw)
  To: kvalo; +Cc: luca, linux-wireless

From: Johannes Berg <johannes.berg@intel.com>

We do a key iteration to program the keys, and while at it
we also collect the data necessary for TKIP. This code has
all kinds of dependencies on the firmware API though, so
take out the TKIP phase 1 key generation and do that in a
separate key iteration only if necessary.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 132 ++++++++++++--------
 1 file changed, 83 insertions(+), 49 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index 6a259d867d90..14c24f3e0717 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -103,9 +103,8 @@ static const u8 *iwl_mvm_find_max_pn(struct ieee80211_key_conf *key,
 
 struct wowlan_key_data {
 	struct iwl_wowlan_rsc_tsc_params_cmd *rsc_tsc;
-	struct iwl_wowlan_tkip_params_cmd *tkip;
 	struct iwl_wowlan_kek_kck_material_cmd_v4 *kek_kck_cmd;
-	bool error, use_rsc_tsc, use_tkip, configure_keys;
+	bool error, use_rsc_tsc, configure_keys;
 	int wep_key_idx;
 };
 
@@ -120,11 +119,7 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
 	struct wowlan_key_data *data = _data;
 	struct aes_sc *aes_sc, *aes_tx_sc = NULL;
 	struct tkip_sc *tkip_sc, *tkip_tx_sc = NULL;
-	struct iwl_p1k_cache *rx_p1ks;
-	u8 *rx_mic_key;
 	struct ieee80211_key_seq seq;
-	u32 cur_rx_iv32 = 0;
-	u16 p1k[IWL_P1K_SIZE];
 	int ret, i;
 
 	switch (key->cipher) {
@@ -204,26 +199,12 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
 			tkip_tx_sc =
 				&data->rsc_tsc->params.all_tsc_rsc.tkip.tsc;
 
-			rx_p1ks = data->tkip->rx_uni;
-
 			pn64 = atomic64_read(&key->tx_pn);
 			tkip_tx_sc->iv16 = cpu_to_le16(TKIP_PN_TO_IV16(pn64));
 			tkip_tx_sc->iv32 = cpu_to_le32(TKIP_PN_TO_IV32(pn64));
-
-			ieee80211_get_tkip_p1k_iv(key, TKIP_PN_TO_IV32(pn64),
-						  p1k);
-			iwl_mvm_convert_p1k(p1k, data->tkip->tx.p1k);
-
-			memcpy(data->tkip->mic_keys.tx,
-			       &key->key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY],
-			       IWL_MIC_KEY_SIZE);
-
-			rx_mic_key = data->tkip->mic_keys.rx_unicast;
 		} else {
 			tkip_sc =
 			  data->rsc_tsc->params.all_tsc_rsc.tkip.multicast_rsc;
-			rx_p1ks = data->tkip->rx_multi;
-			rx_mic_key = data->tkip->mic_keys.rx_mcast;
 			data->kek_kck_cmd->gtk_cipher =
 				cpu_to_le32(STA_KEY_FLG_TKIP);
 		}
@@ -237,23 +218,8 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
 			ieee80211_get_key_rx_seq(key, i, &seq);
 			tkip_sc[i].iv16 = cpu_to_le16(seq.tkip.iv16);
 			tkip_sc[i].iv32 = cpu_to_le32(seq.tkip.iv32);
-			/* wrapping isn't allowed, AP must rekey */
-			if (seq.tkip.iv32 > cur_rx_iv32)
-				cur_rx_iv32 = seq.tkip.iv32;
 		}
 
-		ieee80211_get_tkip_rx_p1k(key, vif->bss_conf.bssid,
-					  cur_rx_iv32, p1k);
-		iwl_mvm_convert_p1k(p1k, rx_p1ks[0].p1k);
-		ieee80211_get_tkip_rx_p1k(key, vif->bss_conf.bssid,
-					  cur_rx_iv32 + 1, p1k);
-		iwl_mvm_convert_p1k(p1k, rx_p1ks[1].p1k);
-
-		memcpy(rx_mic_key,
-		       &key->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY],
-		       IWL_MIC_KEY_SIZE);
-
-		data->use_tkip = true;
 		data->use_rsc_tsc = true;
 		break;
 	case WLAN_CIPHER_SUITE_CCMP:
@@ -352,6 +318,72 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
 	}
 }
 
+struct wowlan_key_tkip_data {
+	struct iwl_wowlan_tkip_params_cmd tkip;
+	bool have_tkip_keys;
+};
+
+static void iwl_mvm_wowlan_get_tkip_data(struct ieee80211_hw *hw,
+					 struct ieee80211_vif *vif,
+					 struct ieee80211_sta *sta,
+					 struct ieee80211_key_conf *key,
+					 void *_data)
+{
+	struct wowlan_key_tkip_data *data = _data;
+	struct iwl_p1k_cache *rx_p1ks;
+	u8 *rx_mic_key;
+	struct ieee80211_key_seq seq;
+	u32 cur_rx_iv32 = 0;
+	u16 p1k[IWL_P1K_SIZE];
+	int i;
+
+	switch (key->cipher) {
+	default:
+		break;
+	case WLAN_CIPHER_SUITE_TKIP:
+		if (sta) {
+			u64 pn64;
+
+			rx_p1ks = data->tkip.rx_uni;
+
+			pn64 = atomic64_read(&key->tx_pn);
+
+			ieee80211_get_tkip_p1k_iv(key, TKIP_PN_TO_IV32(pn64),
+						  p1k);
+			iwl_mvm_convert_p1k(p1k, data->tkip.tx.p1k);
+
+			memcpy(data->tkip.mic_keys.tx,
+			       &key->key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY],
+			       IWL_MIC_KEY_SIZE);
+
+			rx_mic_key = data->tkip.mic_keys.rx_unicast;
+		} else {
+			rx_p1ks = data->tkip.rx_multi;
+			rx_mic_key = data->tkip.mic_keys.rx_mcast;
+		}
+
+		for (i = 0; i < IWL_NUM_RSC; i++) {
+			/* wrapping isn't allowed, AP must rekey */
+			if (seq.tkip.iv32 > cur_rx_iv32)
+				cur_rx_iv32 = seq.tkip.iv32;
+		}
+
+		ieee80211_get_tkip_rx_p1k(key, vif->bss_conf.bssid,
+					  cur_rx_iv32, p1k);
+		iwl_mvm_convert_p1k(p1k, rx_p1ks[0].p1k);
+		ieee80211_get_tkip_rx_p1k(key, vif->bss_conf.bssid,
+					  cur_rx_iv32 + 1, p1k);
+		iwl_mvm_convert_p1k(p1k, rx_p1ks[1].p1k);
+
+		memcpy(rx_mic_key,
+		       &key->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY],
+		       IWL_MIC_KEY_SIZE);
+
+		data->have_tkip_keys = true;
+		break;
+	}
+}
+
 static int iwl_mvm_send_patterns_v1(struct iwl_mvm *mvm,
 				    struct cfg80211_wowlan *wowlan)
 {
@@ -718,14 +750,11 @@ static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
 {
 	struct iwl_wowlan_kek_kck_material_cmd_v4 kek_kck_cmd = {};
 	struct iwl_wowlan_kek_kck_material_cmd_v4 *_kek_kck_cmd = &kek_kck_cmd;
-	struct iwl_wowlan_tkip_params_cmd tkip_cmd = {};
 	bool unified = fw_has_capa(&mvm->fw->ucode_capa,
 				   IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
 	struct wowlan_key_data key_data = {
 		.configure_keys = !unified,
 		.use_rsc_tsc = false,
-		.tkip = &tkip_cmd,
-		.use_tkip = false,
 		.kek_kck_cmd = _kek_kck_cmd,
 	};
 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
@@ -785,17 +814,17 @@ static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
 			goto out;
 	}
 
-	if (key_data.use_tkip &&
-	    !fw_has_api(&mvm->fw->ucode_capa,
+	if (!fw_has_api(&mvm->fw->ucode_capa,
 			IWL_UCODE_TLV_API_TKIP_MIC_KEYS)) {
 		int ver = iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP,
 						WOWLAN_TKIP_PARAM,
 						IWL_FW_CMD_VER_UNKNOWN);
+		struct wowlan_key_tkip_data tkip_data = {};
 		int size;
 
 		if (ver == 2) {
-			size = sizeof(tkip_cmd);
-			key_data.tkip->sta_id =
+			size = sizeof(tkip_data.tkip);
+			tkip_data.tkip.sta_id =
 				cpu_to_le32(mvmvif->ap_sta_id);
 		} else if (ver == 1 || ver == IWL_FW_CMD_VER_UNKNOWN) {
 			size = sizeof(struct iwl_wowlan_tkip_params_cmd_ver_1);
@@ -805,13 +834,18 @@ static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
 			goto out;
 		}
 
-		/* send relevant data according to CMD version */
-		ret = iwl_mvm_send_cmd_pdu(mvm,
-					   WOWLAN_TKIP_PARAM,
-					   cmd_flags, size,
-					   &tkip_cmd);
-		if (ret)
-			goto out;
+		ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_wowlan_get_tkip_data,
+				    &tkip_data);
+
+		if (tkip_data.have_tkip_keys) {
+			/* send relevant data according to CMD version */
+			ret = iwl_mvm_send_cmd_pdu(mvm,
+						   WOWLAN_TKIP_PARAM,
+						   cmd_flags, size,
+						   &tkip_data.tkip);
+			if (ret)
+				goto out;
+		}
 	}
 
 	/* configure rekey data only if offloaded rekey is supported (d3) */
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 02/12] iwlwifi: mvm: d3: remove fixed cmd_flags argument
  2021-08-05 10:19 [PATCH 00/12] iwlwifi: updates intended for v5.15 2021-08-05 Luca Coelho
  2021-08-05 10:19 ` [PATCH 01/12] iwlwifi: mvm: d3: separate TKIP data from key iteration Luca Coelho
@ 2021-08-05 10:19 ` Luca Coelho
  2021-08-05 10:19 ` [PATCH 03/12] iwlwifi: mvm: d3: refactor TSC/RSC configuration Luca Coelho
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Luca Coelho @ 2021-08-05 10:19 UTC (permalink / raw)
  To: kvalo; +Cc: luca, linux-wireless

From: Johannes Berg <johannes.berg@intel.com>

We only ever pass cmd_flags == CMD_ASYNC, so might as well
not have the argument. Remove it.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 23 ++++++++-------------
 1 file changed, 9 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index 14c24f3e0717..0d87de66bf8d 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -745,8 +745,7 @@ iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm,
 }
 
 static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
-					    struct ieee80211_vif *vif,
-					    u32 cmd_flags)
+					    struct ieee80211_vif *vif)
 {
 	struct iwl_wowlan_kek_kck_material_cmd_v4 kek_kck_cmd = {};
 	struct iwl_wowlan_kek_kck_material_cmd_v4 *_kek_kck_cmd = &kek_kck_cmd;
@@ -772,10 +771,9 @@ static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
 	 * required locks.
 	 */
 	/*
-	 * Note that currently we don't propagate cmd_flags
-	 * to the iterator. In case of key_data.configure_keys,
-	 * all the configured commands are SYNC, and
-	 * iwl_mvm_wowlan_program_keys() will take care of
+	 * Note that currently we don't use CMD_ASYNC in the iterator.
+	 * In case of key_data.configure_keys, all the configured commands
+	 * are SYNC, and iwl_mvm_wowlan_program_keys() will take care of
 	 * locking/unlocking mvm->mutex.
 	 */
 	ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_wowlan_program_keys,
@@ -806,8 +804,7 @@ static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
 		}
 
 		ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_TSC_RSC_PARAM,
-					   cmd_flags,
-					   size,
+					   CMD_ASYNC, size,
 					   key_data.rsc_tsc);
 
 		if (ret)
@@ -841,7 +838,7 @@ static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
 			/* send relevant data according to CMD version */
 			ret = iwl_mvm_send_cmd_pdu(mvm,
 						   WOWLAN_TKIP_PARAM,
-						   cmd_flags, size,
+						   CMD_ASYNC, size,
 						   &tkip_data.tkip);
 			if (ret)
 				goto out;
@@ -885,10 +882,8 @@ static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
 		IWL_DEBUG_WOWLAN(mvm, "setting akm %d\n",
 				 mvmvif->rekey_data.akm);
 
-		ret = iwl_mvm_send_cmd_pdu(mvm,
-					   WOWLAN_KEK_KCK_MATERIAL, cmd_flags,
-					   cmd_size,
-					   _kek_kck_cmd);
+		ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_KEK_KCK_MATERIAL,
+					   CMD_ASYNC, cmd_size, _kek_kck_cmd);
 		if (ret)
 			goto out;
 	}
@@ -927,7 +922,7 @@ iwl_mvm_wowlan_config(struct iwl_mvm *mvm,
 	 * that isn't really a problem though.
 	 */
 	mutex_unlock(&mvm->mutex);
-	ret = iwl_mvm_wowlan_config_key_params(mvm, vif, CMD_ASYNC);
+	ret = iwl_mvm_wowlan_config_key_params(mvm, vif);
 	mutex_lock(&mvm->mutex);
 	if (ret)
 		return ret;
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 03/12] iwlwifi: mvm: d3: refactor TSC/RSC configuration
  2021-08-05 10:19 [PATCH 00/12] iwlwifi: updates intended for v5.15 2021-08-05 Luca Coelho
  2021-08-05 10:19 ` [PATCH 01/12] iwlwifi: mvm: d3: separate TKIP data from key iteration Luca Coelho
  2021-08-05 10:19 ` [PATCH 02/12] iwlwifi: mvm: d3: remove fixed cmd_flags argument Luca Coelho
@ 2021-08-05 10:19 ` Luca Coelho
  2021-08-05 10:19 ` [PATCH 04/12] iwlwifi: mvm: d3: add separate key iteration for GTK type Luca Coelho
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Luca Coelho @ 2021-08-05 10:19 UTC (permalink / raw)
  To: kvalo; +Cc: luca, linux-wireless

From: Johannes Berg <johannes.berg@intel.com>

Refactor the TSC/RSC configuration out from the normal wowlan
key iteration so we can replace it later with a different one
adapted to a different firmware API.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 197 ++++++++++++--------
 1 file changed, 116 insertions(+), 81 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index 0d87de66bf8d..0979fc18d4fb 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -102,9 +102,8 @@ static const u8 *iwl_mvm_find_max_pn(struct ieee80211_key_conf *key,
 }
 
 struct wowlan_key_data {
-	struct iwl_wowlan_rsc_tsc_params_cmd *rsc_tsc;
 	struct iwl_wowlan_kek_kck_material_cmd_v4 *kek_kck_cmd;
-	bool error, use_rsc_tsc, configure_keys;
+	bool error, configure_keys;
 	int wep_key_idx;
 };
 
@@ -117,10 +116,7 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 	struct wowlan_key_data *data = _data;
-	struct aes_sc *aes_sc, *aes_tx_sc = NULL;
-	struct tkip_sc *tkip_sc, *tkip_tx_sc = NULL;
-	struct ieee80211_key_seq seq;
-	int ret, i;
+	int ret;
 
 	switch (key->cipher) {
 	case WLAN_CIPHER_SUITE_WEP40:
@@ -190,6 +186,71 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
 		 * be deauthenticated, but that was considered acceptable.
 		 */
 		return;
+	case WLAN_CIPHER_SUITE_TKIP:
+		if (!sta)
+			data->kek_kck_cmd->gtk_cipher =
+				cpu_to_le32(STA_KEY_FLG_TKIP);
+		break;
+	case WLAN_CIPHER_SUITE_CCMP:
+	case WLAN_CIPHER_SUITE_GCMP:
+	case WLAN_CIPHER_SUITE_GCMP_256:
+		if (!sta)
+			data->kek_kck_cmd->gtk_cipher =
+				key->cipher == WLAN_CIPHER_SUITE_CCMP ?
+				cpu_to_le32(STA_KEY_FLG_CCM) :
+				cpu_to_le32(STA_KEY_FLG_GCMP);
+		break;
+	}
+
+	IWL_DEBUG_WOWLAN(mvm, "GTK cipher %d\n", data->kek_kck_cmd->gtk_cipher);
+
+	if (data->configure_keys) {
+		mutex_lock(&mvm->mutex);
+		/*
+		 * The D3 firmware hardcodes the key offset 0 as the key it
+		 * uses to transmit packets to the AP, i.e. the PTK.
+		 */
+		if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
+			mvm->ptk_ivlen = key->iv_len;
+			mvm->ptk_icvlen = key->icv_len;
+			ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, 0);
+		} else {
+			/*
+			 * firmware only supports TSC/RSC for a single key,
+			 * so if there are multiple keep overwriting them
+			 * with new ones -- this relies on mac80211 doing
+			 * list_add_tail().
+			 */
+			mvm->gtk_ivlen = key->iv_len;
+			mvm->gtk_icvlen = key->icv_len;
+			ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, 1);
+		}
+		mutex_unlock(&mvm->mutex);
+		data->error = ret != 0;
+	}
+}
+
+struct wowlan_key_rsc_tsc_data {
+	struct iwl_wowlan_rsc_tsc_params_cmd *rsc_tsc;
+	bool have_rsc_tsc;
+};
+
+static void iwl_mvm_wowlan_get_rsc_tsc_data(struct ieee80211_hw *hw,
+					    struct ieee80211_vif *vif,
+					    struct ieee80211_sta *sta,
+					    struct ieee80211_key_conf *key,
+					    void *_data)
+{
+	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+	struct wowlan_key_rsc_tsc_data *data = _data;
+	struct aes_sc *aes_sc;
+	struct tkip_sc *tkip_sc, *tkip_tx_sc = NULL;
+	struct ieee80211_key_seq seq;
+	int i;
+
+	switch (key->cipher) {
+	default:
+		break;
 	case WLAN_CIPHER_SUITE_TKIP:
 		if (sta) {
 			u64 pn64;
@@ -205,8 +266,6 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
 		} else {
 			tkip_sc =
 			  data->rsc_tsc->params.all_tsc_rsc.tkip.multicast_rsc;
-			data->kek_kck_cmd->gtk_cipher =
-				cpu_to_le32(STA_KEY_FLG_TKIP);
 		}
 
 		/*
@@ -220,12 +279,13 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
 			tkip_sc[i].iv32 = cpu_to_le32(seq.tkip.iv32);
 		}
 
-		data->use_rsc_tsc = true;
+		data->have_rsc_tsc = true;
 		break;
 	case WLAN_CIPHER_SUITE_CCMP:
 	case WLAN_CIPHER_SUITE_GCMP:
 	case WLAN_CIPHER_SUITE_GCMP_256:
 		if (sta) {
+			struct aes_sc *aes_tx_sc;
 			u64 pn64;
 
 			aes_sc =
@@ -238,10 +298,6 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
 		} else {
 			aes_sc =
 			   data->rsc_tsc->params.all_tsc_rsc.aes.multicast_rsc;
-			data->kek_kck_cmd->gtk_cipher =
-				key->cipher == WLAN_CIPHER_SUITE_CCMP ?
-				cpu_to_le32(STA_KEY_FLG_CCM) :
-				cpu_to_le32(STA_KEY_FLG_GCMP);
 		}
 
 		/*
@@ -286,36 +342,48 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
 							   ((u64)pn[0] << 40));
 			}
 		}
-		data->use_rsc_tsc = true;
+		data->have_rsc_tsc = true;
 		break;
 	}
+}
 
-	IWL_DEBUG_WOWLAN(mvm, "GTK cipher %d\n", data->kek_kck_cmd->gtk_cipher);
+static int iwl_mvm_wowlan_config_rsc_tsc(struct iwl_mvm *mvm,
+					 struct ieee80211_vif *vif)
+{
+	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+	int ver = iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP,
+					WOWLAN_TSC_RSC_PARAM,
+					IWL_FW_CMD_VER_UNKNOWN);
+	struct wowlan_key_rsc_tsc_data data = {};
+	int size;
+	int ret;
 
-	if (data->configure_keys) {
-		mutex_lock(&mvm->mutex);
-		/*
-		 * The D3 firmware hardcodes the key offset 0 as the key it
-		 * uses to transmit packets to the AP, i.e. the PTK.
-		 */
-		if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
-			mvm->ptk_ivlen = key->iv_len;
-			mvm->ptk_icvlen = key->icv_len;
-			ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, 0);
-		} else {
-			/*
-			 * firmware only supports TSC/RSC for a single key,
-			 * so if there are multiple keep overwriting them
-			 * with new ones -- this relies on mac80211 doing
-			 * list_add_tail().
-			 */
-			mvm->gtk_ivlen = key->iv_len;
-			mvm->gtk_icvlen = key->icv_len;
-			ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, 1);
-		}
-		mutex_unlock(&mvm->mutex);
-		data->error = ret != 0;
+	data.rsc_tsc = kzalloc(sizeof(*data.rsc_tsc), GFP_KERNEL);
+	if (!data.rsc_tsc)
+		return -ENOMEM;
+
+	if (ver == 4) {
+		size = sizeof(*data.rsc_tsc);
+		data.rsc_tsc->sta_id = cpu_to_le32(mvmvif->ap_sta_id);
+	} else if (ver == 2 || ver == IWL_FW_CMD_VER_UNKNOWN) {
+		size = sizeof(data.rsc_tsc->params);
+	} else {
+		ret = 0;
+		WARN_ON_ONCE(1);
+		goto out;
 	}
+
+	ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_wowlan_get_rsc_tsc_data,
+			    &data);
+
+	if (data.have_rsc_tsc)
+		ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_TSC_RSC_PARAM,
+					   CMD_ASYNC, size, data.rsc_tsc);
+	else
+		ret = 0;
+out:
+	kfree(data.rsc_tsc);
+	return ret;
 }
 
 struct wowlan_key_tkip_data {
@@ -753,7 +821,6 @@ static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
 				   IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
 	struct wowlan_key_data key_data = {
 		.configure_keys = !unified,
-		.use_rsc_tsc = false,
 		.kek_kck_cmd = _kek_kck_cmd,
 	};
 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
@@ -761,10 +828,6 @@ static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
 	u8 cmd_ver;
 	size_t cmd_size;
 
-	key_data.rsc_tsc = kzalloc(sizeof(*key_data.rsc_tsc), GFP_KERNEL);
-	if (!key_data.rsc_tsc)
-		return -ENOMEM;
-
 	/*
 	 * if we have to configure keys, call ieee80211_iter_keys(),
 	 * as we need non-atomic context in order to take the
@@ -779,37 +842,12 @@ static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
 	ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_wowlan_program_keys,
 			    &key_data);
 
-	if (key_data.error) {
-		ret = -EIO;
-		goto out;
-	}
-
-	if (key_data.use_rsc_tsc) {
-		int ver = iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP,
-						WOWLAN_TSC_RSC_PARAM,
-						IWL_FW_CMD_VER_UNKNOWN);
-		int size;
-
-		if (ver == 4) {
-			size = sizeof(*key_data.rsc_tsc);
-			key_data.rsc_tsc->sta_id =
-				cpu_to_le32(mvmvif->ap_sta_id);
-
-		} else if (ver == 2 || ver == IWL_FW_CMD_VER_UNKNOWN) {
-			size = sizeof(key_data.rsc_tsc->params);
-		} else {
-			ret = 0;
-			WARN_ON_ONCE(1);
-			goto out;
-		}
-
-		ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_TSC_RSC_PARAM,
-					   CMD_ASYNC, size,
-					   key_data.rsc_tsc);
+	if (key_data.error)
+		return -EIO;
 
-		if (ret)
-			goto out;
-	}
+	ret = iwl_mvm_wowlan_config_rsc_tsc(mvm, vif);
+	if (ret)
+		return ret;
 
 	if (!fw_has_api(&mvm->fw->ucode_capa,
 			IWL_UCODE_TLV_API_TKIP_MIC_KEYS)) {
@@ -826,9 +864,8 @@ static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
 		} else if (ver == 1 || ver == IWL_FW_CMD_VER_UNKNOWN) {
 			size = sizeof(struct iwl_wowlan_tkip_params_cmd_ver_1);
 		} else {
-			ret =  -EINVAL;
 			WARN_ON_ONCE(1);
-			goto out;
+			return -EINVAL;
 		}
 
 		ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_wowlan_get_tkip_data,
@@ -841,7 +878,7 @@ static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
 						   CMD_ASYNC, size,
 						   &tkip_data.tkip);
 			if (ret)
-				goto out;
+				return ret;
 		}
 	}
 
@@ -885,12 +922,10 @@ static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
 		ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_KEK_KCK_MATERIAL,
 					   CMD_ASYNC, cmd_size, _kek_kck_cmd);
 		if (ret)
-			goto out;
+			return ret;
 	}
-	ret = 0;
-out:
-	kfree(key_data.rsc_tsc);
-	return ret;
+
+	return 0;
 }
 
 static int
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 04/12] iwlwifi: mvm: d3: add separate key iteration for GTK type
  2021-08-05 10:19 [PATCH 00/12] iwlwifi: updates intended for v5.15 2021-08-05 Luca Coelho
                   ` (2 preceding siblings ...)
  2021-08-05 10:19 ` [PATCH 03/12] iwlwifi: mvm: d3: refactor TSC/RSC configuration Luca Coelho
@ 2021-08-05 10:19 ` Luca Coelho
  2021-08-05 10:19 ` [PATCH 05/12] iwlwifi: mvm: d3: make key reprogramming iteration optional Luca Coelho
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Luca Coelho @ 2021-08-05 10:19 UTC (permalink / raw)
  To: kvalo; +Cc: luca, linux-wireless

From: Johannes Berg <johannes.berg@intel.com>

If we're sending the KEK/KCK data we also need the GTK and
IGTK type, add a separate key iteration for that so we can
make the configure_key iteration optional later.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 63 +++++++++++++++------
 1 file changed, 46 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index 0979fc18d4fb..61490f17a1fa 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -102,7 +102,6 @@ static const u8 *iwl_mvm_find_max_pn(struct ieee80211_key_conf *key,
 }
 
 struct wowlan_key_data {
-	struct iwl_wowlan_kek_kck_material_cmd_v4 *kek_kck_cmd;
 	bool error, configure_keys;
 	int wep_key_idx;
 };
@@ -174,10 +173,8 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
 		return;
 	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
 	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
-		data->kek_kck_cmd->igtk_cipher = cpu_to_le32(STA_KEY_FLG_GCMP);
 		return;
 	case WLAN_CIPHER_SUITE_AES_CMAC:
-		data->kek_kck_cmd->igtk_cipher = cpu_to_le32(STA_KEY_FLG_CCM);
 		/*
 		 * Ignore CMAC keys -- the WoWLAN firmware doesn't support them
 		 * but we also shouldn't abort suspend due to that. It does have
@@ -187,23 +184,12 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
 		 */
 		return;
 	case WLAN_CIPHER_SUITE_TKIP:
-		if (!sta)
-			data->kek_kck_cmd->gtk_cipher =
-				cpu_to_le32(STA_KEY_FLG_TKIP);
-		break;
 	case WLAN_CIPHER_SUITE_CCMP:
 	case WLAN_CIPHER_SUITE_GCMP:
 	case WLAN_CIPHER_SUITE_GCMP_256:
-		if (!sta)
-			data->kek_kck_cmd->gtk_cipher =
-				key->cipher == WLAN_CIPHER_SUITE_CCMP ?
-				cpu_to_le32(STA_KEY_FLG_CCM) :
-				cpu_to_le32(STA_KEY_FLG_GCMP);
 		break;
 	}
 
-	IWL_DEBUG_WOWLAN(mvm, "GTK cipher %d\n", data->kek_kck_cmd->gtk_cipher);
-
 	if (data->configure_keys) {
 		mutex_lock(&mvm->mutex);
 		/*
@@ -452,6 +438,42 @@ static void iwl_mvm_wowlan_get_tkip_data(struct ieee80211_hw *hw,
 	}
 }
 
+struct wowlan_key_gtk_type_iter {
+	struct iwl_wowlan_kek_kck_material_cmd_v4 *kek_kck_cmd;
+};
+
+static void iwl_mvm_wowlan_gtk_type_iter(struct ieee80211_hw *hw,
+					 struct ieee80211_vif *vif,
+					 struct ieee80211_sta *sta,
+					 struct ieee80211_key_conf *key,
+					 void *_data)
+{
+	struct wowlan_key_gtk_type_iter *data = _data;
+
+	switch (key->cipher) {
+	default:
+		return;
+	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+		data->kek_kck_cmd->igtk_cipher = cpu_to_le32(STA_KEY_FLG_GCMP);
+		return;
+	case WLAN_CIPHER_SUITE_AES_CMAC:
+		data->kek_kck_cmd->igtk_cipher = cpu_to_le32(STA_KEY_FLG_CCM);
+		return;
+	case WLAN_CIPHER_SUITE_CCMP:
+		if (!sta)
+			data->kek_kck_cmd->gtk_cipher =
+				cpu_to_le32(STA_KEY_FLG_CCM);
+		break;
+	case WLAN_CIPHER_SUITE_GCMP:
+	case WLAN_CIPHER_SUITE_GCMP_256:
+		if (!sta)
+			data->kek_kck_cmd->gtk_cipher =
+				cpu_to_le32(STA_KEY_FLG_GCMP);
+		break;
+	}
+}
+
 static int iwl_mvm_send_patterns_v1(struct iwl_mvm *mvm,
 				    struct cfg80211_wowlan *wowlan)
 {
@@ -815,13 +837,10 @@ iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm,
 static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
 					    struct ieee80211_vif *vif)
 {
-	struct iwl_wowlan_kek_kck_material_cmd_v4 kek_kck_cmd = {};
-	struct iwl_wowlan_kek_kck_material_cmd_v4 *_kek_kck_cmd = &kek_kck_cmd;
 	bool unified = fw_has_capa(&mvm->fw->ucode_capa,
 				   IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
 	struct wowlan_key_data key_data = {
 		.configure_keys = !unified,
-		.kek_kck_cmd = _kek_kck_cmd,
 	};
 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 	int ret;
@@ -884,6 +903,13 @@ static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
 
 	/* configure rekey data only if offloaded rekey is supported (d3) */
 	if (mvmvif->rekey_data.valid) {
+		struct iwl_wowlan_kek_kck_material_cmd_v4 kek_kck_cmd = {};
+		struct iwl_wowlan_kek_kck_material_cmd_v4 *_kek_kck_cmd =
+			&kek_kck_cmd;
+		struct wowlan_key_gtk_type_iter gtk_type_data = {
+			.kek_kck_cmd = _kek_kck_cmd,
+		};
+
 		cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw,
 						IWL_ALWAYS_LONG_GROUP,
 						WOWLAN_KEK_KCK_MATERIAL,
@@ -892,6 +918,9 @@ static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
 			    cmd_ver != IWL_FW_CMD_VER_UNKNOWN))
 			return -EINVAL;
 
+		ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_wowlan_gtk_type_iter,
+				    &gtk_type_data);
+
 		memcpy(kek_kck_cmd.kck, mvmvif->rekey_data.kck,
 		       mvmvif->rekey_data.kck_len);
 		kek_kck_cmd.kck_len = cpu_to_le16(mvmvif->rekey_data.kck_len);
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 05/12] iwlwifi: mvm: d3: make key reprogramming iteration optional
  2021-08-05 10:19 [PATCH 00/12] iwlwifi: updates intended for v5.15 2021-08-05 Luca Coelho
                   ` (3 preceding siblings ...)
  2021-08-05 10:19 ` [PATCH 04/12] iwlwifi: mvm: d3: add separate key iteration for GTK type Luca Coelho
@ 2021-08-05 10:19 ` Luca Coelho
  2021-08-05 10:19 ` [PATCH 06/12] iwlwifi: mvm: d3: implement RSC command version 5 Luca Coelho
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Luca Coelho @ 2021-08-05 10:19 UTC (permalink / raw)
  To: kvalo; +Cc: luca, linux-wireless

From: Johannes Berg <johannes.berg@intel.com>

Now that only reprogramming is left in the initial key iteration,
skip it entirely on unified firmware images instead of skipping
only the command sending inside of it.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 102 +++++++++-----------
 1 file changed, 48 insertions(+), 54 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index 61490f17a1fa..ad7308cc4b7f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -101,8 +101,8 @@ static const u8 *iwl_mvm_find_max_pn(struct ieee80211_key_conf *key,
 	return ret;
 }
 
-struct wowlan_key_data {
-	bool error, configure_keys;
+struct wowlan_key_reprogram_data {
+	bool error;
 	int wep_key_idx;
 };
 
@@ -114,7 +114,7 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
 {
 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
-	struct wowlan_key_data *data = _data;
+	struct wowlan_key_reprogram_data *data = _data;
 	int ret;
 
 	switch (key->cipher) {
@@ -152,18 +152,14 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
 			wkc.wep_key.key_offset = data->wep_key_idx;
 		}
 
-		if (data->configure_keys) {
-			mutex_lock(&mvm->mutex);
-			ret = iwl_mvm_send_cmd_pdu(mvm, WEP_KEY, 0,
-						   sizeof(wkc), &wkc);
-			data->error = ret != 0;
-
-			mvm->ptk_ivlen = key->iv_len;
-			mvm->ptk_icvlen = key->icv_len;
-			mvm->gtk_ivlen = key->iv_len;
-			mvm->gtk_icvlen = key->icv_len;
-			mutex_unlock(&mvm->mutex);
-		}
+		mutex_lock(&mvm->mutex);
+		ret = iwl_mvm_send_cmd_pdu(mvm, WEP_KEY, 0, sizeof(wkc), &wkc);
+		data->error = ret != 0;
+
+		mvm->ptk_ivlen = key->iv_len;
+		mvm->ptk_icvlen = key->icv_len;
+		mvm->gtk_ivlen = key->iv_len;
+		mvm->gtk_icvlen = key->icv_len;
 
 		/* don't upload key again */
 		return;
@@ -190,30 +186,28 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
 		break;
 	}
 
-	if (data->configure_keys) {
-		mutex_lock(&mvm->mutex);
+	mutex_lock(&mvm->mutex);
+	/*
+	 * The D3 firmware hardcodes the key offset 0 as the key it
+	 * uses to transmit packets to the AP, i.e. the PTK.
+	 */
+	if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
+		mvm->ptk_ivlen = key->iv_len;
+		mvm->ptk_icvlen = key->icv_len;
+		ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, 0);
+	} else {
 		/*
-		 * The D3 firmware hardcodes the key offset 0 as the key it
-		 * uses to transmit packets to the AP, i.e. the PTK.
+		 * firmware only supports TSC/RSC for a single key,
+		 * so if there are multiple keep overwriting them
+		 * with new ones -- this relies on mac80211 doing
+		 * list_add_tail().
 		 */
-		if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
-			mvm->ptk_ivlen = key->iv_len;
-			mvm->ptk_icvlen = key->icv_len;
-			ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, 0);
-		} else {
-			/*
-			 * firmware only supports TSC/RSC for a single key,
-			 * so if there are multiple keep overwriting them
-			 * with new ones -- this relies on mac80211 doing
-			 * list_add_tail().
-			 */
-			mvm->gtk_ivlen = key->iv_len;
-			mvm->gtk_icvlen = key->icv_len;
-			ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, 1);
-		}
-		mutex_unlock(&mvm->mutex);
-		data->error = ret != 0;
+		mvm->gtk_ivlen = key->iv_len;
+		mvm->gtk_icvlen = key->icv_len;
+		ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, 1);
 	}
+	mutex_unlock(&mvm->mutex);
+	data->error = ret != 0;
 }
 
 struct wowlan_key_rsc_tsc_data {
@@ -839,30 +833,30 @@ static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
 {
 	bool unified = fw_has_capa(&mvm->fw->ucode_capa,
 				   IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
-	struct wowlan_key_data key_data = {
-		.configure_keys = !unified,
-	};
+	struct wowlan_key_reprogram_data key_data = {};
 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 	int ret;
 	u8 cmd_ver;
 	size_t cmd_size;
 
-	/*
-	 * if we have to configure keys, call ieee80211_iter_keys(),
-	 * as we need non-atomic context in order to take the
-	 * required locks.
-	 */
-	/*
-	 * Note that currently we don't use CMD_ASYNC in the iterator.
-	 * In case of key_data.configure_keys, all the configured commands
-	 * are SYNC, and iwl_mvm_wowlan_program_keys() will take care of
-	 * locking/unlocking mvm->mutex.
-	 */
-	ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_wowlan_program_keys,
-			    &key_data);
+	if (!unified) {
+		/*
+		 * if we have to configure keys, call ieee80211_iter_keys(),
+		 * as we need non-atomic context in order to take the
+		 * required locks.
+		 */
+		/*
+		 * Note that currently we don't use CMD_ASYNC in the iterator.
+		 * In case of key_data.configure_keys, all the configured
+		 * commands are SYNC, and iwl_mvm_wowlan_program_keys() will
+		 * take care of locking/unlocking mvm->mutex.
+		 */
+		ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_wowlan_program_keys,
+				    &key_data);
 
-	if (key_data.error)
-		return -EIO;
+		if (key_data.error)
+			return -EIO;
+	}
 
 	ret = iwl_mvm_wowlan_config_rsc_tsc(mvm, vif);
 	if (ret)
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 06/12] iwlwifi: mvm: d3: implement RSC command version 5
  2021-08-05 10:19 [PATCH 00/12] iwlwifi: updates intended for v5.15 2021-08-05 Luca Coelho
                   ` (4 preceding siblings ...)
  2021-08-05 10:19 ` [PATCH 05/12] iwlwifi: mvm: d3: make key reprogramming iteration optional Luca Coelho
@ 2021-08-05 10:19 ` Luca Coelho
  2021-08-05 10:19 ` [PATCH 07/12] iwlwifi: mvm: silently drop encrypted frames for unknown station Luca Coelho
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Luca Coelho @ 2021-08-05 10:19 UTC (permalink / raw)
  To: kvalo; +Cc: luca, linux-wireless

From: Johannes Berg <johannes.berg@intel.com>

In later firmware we haven't needed the TSC anyway since
we have it already (and firmware image doesn't change),
but the new version adds the ability to send down replay
counters for more than one GTK. Implement that.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 .../wireless/intel/iwlwifi/fw/api/commands.h  |   3 +-
 .../net/wireless/intel/iwlwifi/fw/api/d3.h    |  22 +-
 drivers/net/wireless/intel/iwlwifi/mvm/d3.c   | 196 ++++++++++++++++--
 3 files changed, 191 insertions(+), 30 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
index ce060c3dfd7b..ee6b5844a871 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
@@ -550,7 +550,8 @@ enum iwl_legacy_cmds {
 	WOWLAN_CONFIGURATION = 0xe1,
 
 	/**
-	 * @WOWLAN_TSC_RSC_PARAM: &struct iwl_wowlan_rsc_tsc_params_cmd
+	 * @WOWLAN_TSC_RSC_PARAM: &struct iwl_wowlan_rsc_tsc_params_cmd_v4,
+	 *	&struct iwl_wowlan_rsc_tsc_params_cmd
 	 */
 	WOWLAN_TSC_RSC_PARAM = 0xe2,
 
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
index b2e7ef3ddc88..3ec82cae3981 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
@@ -6,6 +6,7 @@
  */
 #ifndef __iwl_fw_api_d3_h__
 #define __iwl_fw_api_d3_h__
+#include <iwl-trans.h>
 
 /**
  * enum iwl_d0i3_flags - d0i3 flags
@@ -389,11 +390,14 @@ struct iwl_wowlan_config_cmd {
 	u8 reserved;
 } __packed; /* WOWLAN_CONFIG_API_S_VER_5 */
 
+#define IWL_NUM_RSC	16
+#define WOWLAN_KEY_MAX_SIZE	32
+#define WOWLAN_GTK_KEYS_NUM     2
+#define WOWLAN_IGTK_KEYS_NUM	2
+
 /*
  * WOWLAN_TSC_RSC_PARAMS
  */
-#define IWL_NUM_RSC	16
-
 struct tkip_sc {
 	__le16 iv16;
 	__le16 pad;
@@ -425,11 +429,19 @@ struct iwl_wowlan_rsc_tsc_params_cmd_ver_2 {
 	union iwl_all_tsc_rsc all_tsc_rsc;
 } __packed; /* ALL_TSC_RSC_API_S_VER_2 */
 
-struct iwl_wowlan_rsc_tsc_params_cmd {
+struct iwl_wowlan_rsc_tsc_params_cmd_v4 {
 	struct iwl_wowlan_rsc_tsc_params_cmd_ver_2 params;
 	__le32 sta_id;
 } __packed; /* ALL_TSC_RSC_API_S_VER_4 */
 
+struct iwl_wowlan_rsc_tsc_params_cmd {
+	__le64 ucast_rsc[IWL_MAX_TID_COUNT];
+	__le64 mcast_rsc[WOWLAN_GTK_KEYS_NUM][IWL_MAX_TID_COUNT];
+	__le32 sta_id;
+#define IWL_MCAST_KEY_MAP_INVALID	0xff
+	u8 mcast_key_id_map[4];
+} __packed; /* ALL_TSC_RSC_API_S_VER_5 */
+
 #define IWL_MIC_KEY_SIZE	8
 struct iwl_mic_keys {
 	u8 tx[IWL_MIC_KEY_SIZE];
@@ -541,10 +553,6 @@ struct iwl_wowlan_gtk_status_v1 {
 	struct iwl_wowlan_rsc_tsc_params_cmd_ver_2 rsc;
 } __packed; /* WOWLAN_GTK_MATERIAL_VER_1 */
 
-#define WOWLAN_KEY_MAX_SIZE	32
-#define WOWLAN_GTK_KEYS_NUM     2
-#define WOWLAN_IGTK_KEYS_NUM	2
-
 /**
  * struct iwl_wowlan_gtk_status - GTK status
  * @key: GTK material
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index ad7308cc4b7f..00403b337060 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -211,7 +211,7 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
 }
 
 struct wowlan_key_rsc_tsc_data {
-	struct iwl_wowlan_rsc_tsc_params_cmd *rsc_tsc;
+	struct iwl_wowlan_rsc_tsc_params_cmd_v4 *rsc_tsc;
 	bool have_rsc_tsc;
 };
 
@@ -327,6 +327,127 @@ static void iwl_mvm_wowlan_get_rsc_tsc_data(struct ieee80211_hw *hw,
 	}
 }
 
+struct wowlan_key_rsc_v5_data {
+	struct iwl_wowlan_rsc_tsc_params_cmd *rsc;
+	bool have_rsc;
+	int gtks;
+	int gtk_ids[4];
+};
+
+static void iwl_mvm_wowlan_get_rsc_v5_data(struct ieee80211_hw *hw,
+					   struct ieee80211_vif *vif,
+					   struct ieee80211_sta *sta,
+					   struct ieee80211_key_conf *key,
+					   void *_data)
+{
+	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+	struct wowlan_key_rsc_v5_data *data = _data;
+	struct ieee80211_key_seq seq;
+	__le64 *rsc;
+	int i;
+
+	/* only for ciphers that can be PTK/GTK */
+	switch (key->cipher) {
+	default:
+		return;
+	case WLAN_CIPHER_SUITE_TKIP:
+	case WLAN_CIPHER_SUITE_CCMP:
+	case WLAN_CIPHER_SUITE_GCMP:
+	case WLAN_CIPHER_SUITE_GCMP_256:
+		break;
+	}
+
+	if (sta) {
+		rsc = data->rsc->ucast_rsc;
+	} else {
+		if (WARN_ON(data->gtks > ARRAY_SIZE(data->gtk_ids)))
+			return;
+		data->gtk_ids[data->gtks] = key->keyidx;
+		rsc = data->rsc->mcast_rsc[data->gtks % 2];
+		if (WARN_ON(key->keyidx >
+				ARRAY_SIZE(data->rsc->mcast_key_id_map)))
+			return;
+		data->rsc->mcast_key_id_map[key->keyidx] = data->gtks % 2;
+		if (data->gtks >= 2) {
+			int prev = data->gtks - 2;
+			int prev_idx = data->gtk_ids[prev];
+
+			data->rsc->mcast_key_id_map[prev_idx] =
+				IWL_MCAST_KEY_MAP_INVALID;
+		}
+		data->gtks++;
+	}
+
+	switch (key->cipher) {
+	default:
+		WARN_ON(1);
+		break;
+	case WLAN_CIPHER_SUITE_TKIP:
+
+		/*
+		 * For non-QoS this relies on the fact that both the uCode and
+		 * mac80211 use TID 0 (as they need to to avoid replay attacks)
+		 * for checking the IV in the frames.
+		 */
+		for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
+			ieee80211_get_key_rx_seq(key, i, &seq);
+
+			rsc[i] = cpu_to_le64(((u64)seq.tkip.iv32 << 16) |
+					     seq.tkip.iv16);
+		}
+
+		data->have_rsc = true;
+		break;
+	case WLAN_CIPHER_SUITE_CCMP:
+	case WLAN_CIPHER_SUITE_GCMP:
+	case WLAN_CIPHER_SUITE_GCMP_256:
+		/*
+		 * For non-QoS this relies on the fact that both the uCode and
+		 * mac80211/our RX code use TID 0 for checking the PN.
+		 */
+		if (sta) {
+			struct iwl_mvm_sta *mvmsta;
+			struct iwl_mvm_key_pn *ptk_pn;
+			const u8 *pn;
+
+			mvmsta = iwl_mvm_sta_from_mac80211(sta);
+			rcu_read_lock();
+			ptk_pn = rcu_dereference(mvmsta->ptk_pn[key->keyidx]);
+			if (WARN_ON(!ptk_pn)) {
+				rcu_read_unlock();
+				break;
+			}
+
+			for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
+				pn = iwl_mvm_find_max_pn(key, ptk_pn, &seq, i,
+						mvm->trans->num_rx_queues);
+				rsc[i] = cpu_to_le64((u64)pn[5] |
+						     ((u64)pn[4] << 8) |
+						     ((u64)pn[3] << 16) |
+						     ((u64)pn[2] << 24) |
+						     ((u64)pn[1] << 32) |
+						     ((u64)pn[0] << 40));
+			}
+
+			rcu_read_unlock();
+		} else {
+			for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
+				u8 *pn = seq.ccmp.pn;
+
+				ieee80211_get_key_rx_seq(key, i, &seq);
+				rsc[i] = cpu_to_le64((u64)pn[5] |
+						     ((u64)pn[4] << 8) |
+						     ((u64)pn[3] << 16) |
+						     ((u64)pn[2] << 24) |
+						     ((u64)pn[1] << 32) |
+						     ((u64)pn[0] << 40));
+			}
+		}
+		data->have_rsc = true;
+		break;
+	}
+}
+
 static int iwl_mvm_wowlan_config_rsc_tsc(struct iwl_mvm *mvm,
 					 struct ieee80211_vif *vif)
 {
@@ -334,35 +455,66 @@ static int iwl_mvm_wowlan_config_rsc_tsc(struct iwl_mvm *mvm,
 	int ver = iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP,
 					WOWLAN_TSC_RSC_PARAM,
 					IWL_FW_CMD_VER_UNKNOWN);
-	struct wowlan_key_rsc_tsc_data data = {};
-	int size;
 	int ret;
 
-	data.rsc_tsc = kzalloc(sizeof(*data.rsc_tsc), GFP_KERNEL);
-	if (!data.rsc_tsc)
-		return -ENOMEM;
+	if (ver == 5) {
+		struct wowlan_key_rsc_v5_data data = {};
+		int i;
+
+		data.rsc = kmalloc(sizeof(*data.rsc), GFP_KERNEL);
+		if (!data.rsc)
+			return -ENOMEM;
+
+		memset(data.rsc, 0xff, sizeof(*data.rsc));
+
+		for (i = 0; i < ARRAY_SIZE(data.rsc->mcast_key_id_map); i++)
+			data.rsc->mcast_key_id_map[i] =
+				IWL_MCAST_KEY_MAP_INVALID;
+		data.rsc->sta_id = cpu_to_le32(mvmvif->ap_sta_id);
+
+		ieee80211_iter_keys(mvm->hw, vif,
+				    iwl_mvm_wowlan_get_rsc_v5_data,
+				    &data);
+
+		if (data.have_rsc)
+			ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_TSC_RSC_PARAM,
+						   CMD_ASYNC, sizeof(*data.rsc),
+						   data.rsc);
+		else
+			ret = 0;
+		kfree(data.rsc);
+	} else if (ver == 4 || ver == 2 || ver == IWL_FW_CMD_VER_UNKNOWN) {
+		struct wowlan_key_rsc_tsc_data data = {};
+		int size;
 
-	if (ver == 4) {
-		size = sizeof(*data.rsc_tsc);
-		data.rsc_tsc->sta_id = cpu_to_le32(mvmvif->ap_sta_id);
-	} else if (ver == 2 || ver == IWL_FW_CMD_VER_UNKNOWN) {
-		size = sizeof(data.rsc_tsc->params);
+		data.rsc_tsc = kzalloc(sizeof(*data.rsc_tsc), GFP_KERNEL);
+		if (!data.rsc_tsc)
+			return -ENOMEM;
+
+		if (ver == 4) {
+			size = sizeof(*data.rsc_tsc);
+			data.rsc_tsc->sta_id = cpu_to_le32(mvmvif->ap_sta_id);
+		} else {
+			/* ver == 2 || ver == IWL_FW_CMD_VER_UNKNOWN */
+			size = sizeof(data.rsc_tsc->params);
+		}
+
+		ieee80211_iter_keys(mvm->hw, vif,
+				    iwl_mvm_wowlan_get_rsc_tsc_data,
+				    &data);
+
+		if (data.have_rsc_tsc)
+			ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_TSC_RSC_PARAM,
+						   CMD_ASYNC, size,
+						   data.rsc_tsc);
+		else
+			ret = 0;
+		kfree(data.rsc_tsc);
 	} else {
 		ret = 0;
 		WARN_ON_ONCE(1);
-		goto out;
 	}
 
-	ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_wowlan_get_rsc_tsc_data,
-			    &data);
-
-	if (data.have_rsc_tsc)
-		ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_TSC_RSC_PARAM,
-					   CMD_ASYNC, size, data.rsc_tsc);
-	else
-		ret = 0;
-out:
-	kfree(data.rsc_tsc);
 	return ret;
 }
 
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 07/12] iwlwifi: mvm: silently drop encrypted frames for unknown station
  2021-08-05 10:19 [PATCH 00/12] iwlwifi: updates intended for v5.15 2021-08-05 Luca Coelho
                   ` (5 preceding siblings ...)
  2021-08-05 10:19 ` [PATCH 06/12] iwlwifi: mvm: d3: implement RSC command version 5 Luca Coelho
@ 2021-08-05 10:19 ` Luca Coelho
  2021-08-05 10:19 ` [PATCH 08/12] iwlwifi: mvm: Refactor setting of SSIDs for 6GHz scan Luca Coelho
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Luca Coelho @ 2021-08-05 10:19 UTC (permalink / raw)
  To: kvalo; +Cc: luca, linux-wireless

From: Avraham Stern <avraham.stern@intel.com>

When a station is removed, the driver-mac80211 station mapping is removed
before the station is actually deleted from the FW. As a result, it is
reasonable that the FW will continue to pass frames although the driver
doesn't have a station for them anymore. Thus change the message
severity level from ERR to DEBUG_DROP.

Signed-off-by: Avraham Stern <avraham.stern@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index c0babb8d5b5c..06cc03820dd5 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -69,8 +69,8 @@ static inline int iwl_mvm_check_pn(struct iwl_mvm *mvm, struct sk_buff *skb,
 
 	/* if we are here - this for sure is either CCMP or GCMP */
 	if (IS_ERR_OR_NULL(sta)) {
-		IWL_ERR(mvm,
-			"expected hw-decrypted unicast frame for station\n");
+		IWL_DEBUG_DROP(mvm,
+			       "expected hw-decrypted unicast frame for station\n");
 		return -1;
 	}
 
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 08/12] iwlwifi: mvm: Refactor setting of SSIDs for 6GHz scan
  2021-08-05 10:19 [PATCH 00/12] iwlwifi: updates intended for v5.15 2021-08-05 Luca Coelho
                   ` (6 preceding siblings ...)
  2021-08-05 10:19 ` [PATCH 07/12] iwlwifi: mvm: silently drop encrypted frames for unknown station Luca Coelho
@ 2021-08-05 10:19 ` Luca Coelho
  2021-08-05 10:19 ` [PATCH 09/12] iwlwifi: mvm: fix access to BSS elements Luca Coelho
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Luca Coelho @ 2021-08-05 10:19 UTC (permalink / raw)
  To: kvalo; +Cc: luca, linux-wireless

From: Ilan Peer <ilan.peer@intel.com>

- Short SSIDs should always be added for direct SSIDs included
  in the scan request. However, this was not done in case that
  information for collocated APs was included. Fix this.
- With the above fix, if the FW also supports discovery of hidden
  APs over the 6GHz band, also set the corresponding full SSID
  information.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 104 +++++-------------
 1 file changed, 28 insertions(+), 76 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
index 82ab08af0e21..e1b436e805b1 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
@@ -1661,22 +1661,32 @@ iwl_mvm_umac_scan_cfg_channels_v6(struct iwl_mvm *mvm,
 }
 
 static int
-iwl_mvm_umac_scan_fill_6g_chan_list(struct iwl_mvm_scan_params *params,
-				    __le32 *cmd_short_ssid, u8 *cmd_bssid,
-				    u8 *scan_ssid_num, u8 *bssid_num)
+iwl_mvm_umac_scan_fill_6g_chan_list(struct iwl_mvm *mvm,
+				    struct iwl_mvm_scan_params *params,
+				     struct iwl_scan_probe_params_v4 *pp)
 {
 	int j, idex_s = 0, idex_b = 0;
 	struct cfg80211_scan_6ghz_params *scan_6ghz_params =
 		params->scan_6ghz_params;
+	bool hidden_supported = fw_has_capa(&mvm->fw->ucode_capa,
+					    IWL_UCODE_TLV_CAPA_HIDDEN_6GHZ_SCAN);
 
-	if (!params->n_6ghz_params) {
-		for (j = 0; j < params->n_ssids; j++) {
-			cmd_short_ssid[idex_s++] =
-				cpu_to_le32(~crc32_le(~0, params->ssids[j].ssid,
-						      params->ssids[j].ssid_len));
-			(*scan_ssid_num)++;
+	for (j = 0; j < params->n_ssids && idex_s < SCAN_SHORT_SSID_MAX_SIZE;
+	     j++) {
+		if (!params->ssids[j].ssid_len)
+			continue;
+
+		pp->short_ssid[idex_s] =
+			cpu_to_le32(~crc32_le(~0, params->ssids[j].ssid,
+					      params->ssids[j].ssid_len));
+
+		if (hidden_supported) {
+			pp->direct_scan[idex_s].id = WLAN_EID_SSID;
+			pp->direct_scan[idex_s].len = params->ssids[j].ssid_len;
+			memcpy(pp->direct_scan[idex_s].ssid, params->ssids[j].ssid,
+			       params->ssids[j].ssid_len);
 		}
-		return 0;
+		idex_s++;
 	}
 
 	/*
@@ -1693,31 +1703,32 @@ iwl_mvm_umac_scan_fill_6g_chan_list(struct iwl_mvm_scan_params *params,
 		/* First, try to place the short SSID */
 		if (scan_6ghz_params[j].short_ssid_valid) {
 			for (k = 0; k < idex_s; k++) {
-				if (cmd_short_ssid[k] ==
+				if (pp->short_ssid[k] ==
 				    cpu_to_le32(scan_6ghz_params[j].short_ssid))
 					break;
 			}
 
 			if (k == idex_s && idex_s < SCAN_SHORT_SSID_MAX_SIZE) {
-				cmd_short_ssid[idex_s++] =
+				pp->short_ssid[idex_s++] =
 					cpu_to_le32(scan_6ghz_params[j].short_ssid);
-				(*scan_ssid_num)++;
 			}
 		}
 
 		/* try to place BSSID for the same entry */
 		for (k = 0; k < idex_b; k++) {
-			if (!memcmp(&cmd_bssid[ETH_ALEN * k],
+			if (!memcmp(&pp->bssid_array[k],
 				    scan_6ghz_params[j].bssid, ETH_ALEN))
 				break;
 		}
 
 		if (k == idex_b && idex_b < SCAN_BSSID_MAX_SIZE) {
-			memcpy(&cmd_bssid[ETH_ALEN * idex_b++],
+			memcpy(&pp->bssid_array[idex_b++],
 			       scan_6ghz_params[j].bssid, ETH_ALEN);
-			(*bssid_num)++;
 		}
 	}
+
+	pp->short_ssid_num = idex_s;
+	pp->bssid_num = idex_b;
 	return 0;
 }
 
@@ -1865,60 +1876,6 @@ iwl_mvm_umac_scan_cfg_channels_v6_6g(struct iwl_mvm_scan_params *params,
 	}
 }
 
-static void
-iwl_mvm_umac_scan_cfg_6g_direct_ssids(struct iwl_mvm *mvm,
-				      struct iwl_mvm_scan_params *params,
-				      struct iwl_scan_probe_params_v4 *pp)
-{
-	u8 next_free_idx = pp->short_ssid_num;
-	int i;
-
-	if (!fw_has_capa(&mvm->fw->ucode_capa,
-			 IWL_UCODE_TLV_CAPA_HIDDEN_6GHZ_SCAN)) {
-		IWL_DEBUG_SCAN(mvm,
-			       "6GHz hidden scan: Not supported by FW\n");
-		return;
-	}
-
-	for (i = params->n_ssids - 1; i >= 0; i--) {
-		__le32 short_ssid;
-		u8 ssid_idx, j;
-
-		if (!params->ssids[i].ssid_len)
-			continue;
-
-		short_ssid = cpu_to_le32(~crc32_le(~0, params->ssids[i].ssid,
-						   params->ssids[i].ssid_len));
-
-		for (j = 0; j < pp->short_ssid_num; j++)
-			if (short_ssid == pp->short_ssid[j])
-				break;
-
-		if (j == pp->short_ssid_num) {
-			/*
-			 * If there are no available slots for the short SSID, do not
-			 * place it.
-			 */
-			if (next_free_idx < SCAN_SHORT_SSID_MAX_SIZE)
-				ssid_idx = next_free_idx++;
-			else
-				continue;
-		} else {
-			ssid_idx = j;
-		}
-
-		if (ssid_idx >= PROBE_OPTION_MAX)
-			continue;
-
-		pp->direct_scan[ssid_idx].id = WLAN_EID_SSID;
-		pp->direct_scan[ssid_idx].len = params->ssids[i].ssid_len;
-		memcpy(pp->direct_scan[ssid_idx].ssid, params->ssids[i].ssid,
-		       params->ssids[i].ssid_len);
-	}
-
-	pp->short_ssid_num = next_free_idx;
-}
-
 static u8 iwl_mvm_scan_umac_chan_flags_v2(struct iwl_mvm *mvm,
 					  struct iwl_mvm_scan_params *params,
 					  struct ieee80211_vif *vif)
@@ -2445,15 +2402,10 @@ static int iwl_mvm_scan_umac_v14(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 	cp->n_aps_override[0] = IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY;
 	cp->n_aps_override[1] = IWL_SCAN_ADWELL_N_APS_SOCIAL_CHS;
 
-	ret = iwl_mvm_umac_scan_fill_6g_chan_list(params, pb->short_ssid,
-						  pb->bssid_array[0],
-						  &pb->short_ssid_num,
-						  &pb->bssid_num);
+	ret = iwl_mvm_umac_scan_fill_6g_chan_list(mvm, params, pb);
 	if (ret)
 		return ret;
 
-	iwl_mvm_umac_scan_cfg_6g_direct_ssids(mvm, params, pb);
-
 	iwl_mvm_umac_scan_cfg_channels_v6_6g(params,
 					     params->n_channels,
 					     pb, cp, vif->type);
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 09/12] iwlwifi: mvm: fix access to BSS elements
  2021-08-05 10:19 [PATCH 00/12] iwlwifi: updates intended for v5.15 2021-08-05 Luca Coelho
                   ` (7 preceding siblings ...)
  2021-08-05 10:19 ` [PATCH 08/12] iwlwifi: mvm: Refactor setting of SSIDs for 6GHz scan Luca Coelho
@ 2021-08-05 10:19 ` Luca Coelho
  2021-08-05 10:19 ` [PATCH 10/12] iwlwifi: rename ACPI_SAR_NUM_CHAIN_LIMITS to ACPI_SAR_NUM_CHAINS Luca Coelho
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Luca Coelho @ 2021-08-05 10:19 UTC (permalink / raw)
  To: kvalo; +Cc: luca, linux-wireless

From: Johannes Berg <johannes.berg@intel.com>

BSS elements are protected using RCU, so we need to use
RCU properly to access them, fix that.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index c60c0b49d7f7..3a4585222d6d 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -2990,16 +2990,20 @@ static void iwl_mvm_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy,
 						    void *_data)
 {
 	struct iwl_mvm_he_obss_narrow_bw_ru_data *data = _data;
+	const struct cfg80211_bss_ies *ies;
 	const struct element *elem;
 
-	elem = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY, bss->ies->data,
-				  bss->ies->len);
+	rcu_read_lock();
+	ies = rcu_dereference(bss->ies);
+	elem = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY, ies->data,
+				  ies->len);
 
 	if (!elem || elem->datalen < 10 ||
 	    !(elem->data[10] &
 	      WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT)) {
 		data->tolerated = false;
 	}
+	rcu_read_unlock();
 }
 
 static void iwl_mvm_check_he_obss_narrow_bw_ru(struct ieee80211_hw *hw,
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 10/12] iwlwifi: rename ACPI_SAR_NUM_CHAIN_LIMITS to ACPI_SAR_NUM_CHAINS
  2021-08-05 10:19 [PATCH 00/12] iwlwifi: updates intended for v5.15 2021-08-05 Luca Coelho
                   ` (8 preceding siblings ...)
  2021-08-05 10:19 ` [PATCH 09/12] iwlwifi: mvm: fix access to BSS elements Luca Coelho
@ 2021-08-05 10:19 ` Luca Coelho
  2021-08-05 10:19 ` [PATCH 11/12] iwlwifi: convert flat SAR profile table to a struct version Luca Coelho
  2021-08-05 10:19 ` [PATCH 12/12] iwlwifi: remove ACPI_SAR_NUM_TABLES definition Luca Coelho
  11 siblings, 0 replies; 14+ messages in thread
From: Luca Coelho @ 2021-08-05 10:19 UTC (permalink / raw)
  To: kvalo; +Cc: luca, linux-wireless

From: Luca Coelho <luciano.coelho@intel.com>

The "LIMITS" in the macro name don't have much meaning, so remove it
to make the macro shorter and better reflect that this is the number
of chains that we have limits for.

Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/acpi.c | 6 +++---
 drivers/net/wireless/intel/iwlwifi/fw/acpi.h | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
index 34933f133a0a..dff792653a24 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
@@ -433,10 +433,10 @@ static int iwl_sar_fill_table(struct iwl_fw_runtime *fwrt,
 			      __le16 *per_chain, u32 n_subbands,
 			      int prof_a, int prof_b)
 {
-	int profs[ACPI_SAR_NUM_CHAIN_LIMITS] = { prof_a, prof_b };
+	int profs[ACPI_SAR_NUM_CHAINS] = { prof_a, prof_b };
 	int i, j, idx;
 
-	for (i = 0; i < ACPI_SAR_NUM_CHAIN_LIMITS; i++) {
+	for (i = 0; i < ACPI_SAR_NUM_CHAINS; i++) {
 		struct iwl_sar_profile *prof;
 
 		/* don't allow SAR to be disabled (profile 0 means disable) */
@@ -486,7 +486,7 @@ int iwl_sar_select_profile(struct iwl_fw_runtime *fwrt,
 
 	for (i = 0; i < n_tables; i++) {
 		ret = iwl_sar_fill_table(fwrt,
-			 &per_chain[i * n_subbands * ACPI_SAR_NUM_CHAIN_LIMITS],
+			 &per_chain[i * n_subbands * ACPI_SAR_NUM_CHAINS],
 			 n_subbands, prof_a, prof_b);
 		if (ret)
 			break;
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
index b858e998999c..24e94430e5d9 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
@@ -33,7 +33,7 @@
 #define ACPI_NUM_GEO_PROFILES		3
 #define ACPI_GEO_PER_CHAIN_SIZE		3
 
-#define ACPI_SAR_NUM_CHAIN_LIMITS	2
+#define ACPI_SAR_NUM_CHAINS		2
 #define ACPI_SAR_NUM_SUB_BANDS		5
 #define ACPI_SAR_NUM_TABLES		1
 
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 11/12] iwlwifi: convert flat SAR profile table to a struct version
  2021-08-05 10:19 [PATCH 00/12] iwlwifi: updates intended for v5.15 2021-08-05 Luca Coelho
                   ` (9 preceding siblings ...)
  2021-08-05 10:19 ` [PATCH 10/12] iwlwifi: rename ACPI_SAR_NUM_CHAIN_LIMITS to ACPI_SAR_NUM_CHAINS Luca Coelho
@ 2021-08-05 10:19 ` Luca Coelho
  2021-08-05 10:19 ` [PATCH 12/12] iwlwifi: remove ACPI_SAR_NUM_TABLES definition Luca Coelho
  11 siblings, 0 replies; 14+ messages in thread
From: Luca Coelho @ 2021-08-05 10:19 UTC (permalink / raw)
  To: kvalo; +Cc: luca, linux-wireless

From: Luca Coelho <luciano.coelho@intel.com>

The SAR profiles have been stored in single-dimension arrays and the
access has been done via a single index.  We will soon need to support
different revisions of this table, which will make the flat array even
harder to handle.  To prepare for that, convert the single-dimension
array to a struct with substructures.

Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/acpi.c | 30 +++++++++++++-------
 drivers/net/wireless/intel/iwlwifi/fw/acpi.h | 13 ++++++---
 2 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
index dff792653a24..f20f0150f407 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
@@ -414,16 +414,25 @@ static int iwl_sar_set_profile(union acpi_object *table,
 			       struct iwl_sar_profile *profile,
 			       bool enabled)
 {
-	int i;
+	int i, j, idx = 0;
 
 	profile->enabled = enabled;
 
-	for (i = 0; i < ACPI_SAR_TABLE_SIZE; i++) {
-		if (table[i].type != ACPI_TYPE_INTEGER ||
-		    table[i].integer.value > U8_MAX)
-			return -EINVAL;
+	/*
+	 * The table from ACPI is flat, but we store it in a
+	 * structured array.
+	 */
+	for (i = 0; i < ACPI_SAR_NUM_CHAINS; i++) {
+		for (j = 0; j < ACPI_SAR_NUM_SUB_BANDS; j++) {
+			if (table[idx].type != ACPI_TYPE_INTEGER ||
+			    table[idx].integer.value > U8_MAX)
+				return -EINVAL;
+
+			profile->chains[i].subbands[j] =
+				table[idx].integer.value;
 
-		profile->table[i] = table[i].integer.value;
+			idx++;
+		}
 	}
 
 	return 0;
@@ -434,7 +443,7 @@ static int iwl_sar_fill_table(struct iwl_fw_runtime *fwrt,
 			      int prof_a, int prof_b)
 {
 	int profs[ACPI_SAR_NUM_CHAINS] = { prof_a, prof_b };
-	int i, j, idx;
+	int i, j;
 
 	for (i = 0; i < ACPI_SAR_NUM_CHAINS; i++) {
 		struct iwl_sar_profile *prof;
@@ -467,11 +476,10 @@ static int iwl_sar_fill_table(struct iwl_fw_runtime *fwrt,
 			       i, profs[i]);
 		IWL_DEBUG_RADIO(fwrt, "  Chain[%d]:\n", i);
 		for (j = 0; j < n_subbands; j++) {
-			idx = i * ACPI_SAR_NUM_SUB_BANDS + j;
 			per_chain[i * n_subbands + j] =
-				cpu_to_le16(prof->table[idx]);
+				cpu_to_le16(prof->chains[i].subbands[j]);
 			IWL_DEBUG_RADIO(fwrt, "    Band[%d] = %d * .125dBm\n",
-					j, prof->table[idx]);
+					j, prof->chains[i].subbands[j]);
 		}
 	}
 
@@ -595,7 +603,7 @@ int iwl_sar_get_ewrd_table(struct iwl_fw_runtime *fwrt)
 			break;
 
 		/* go to the next table */
-		pos += ACPI_SAR_TABLE_SIZE;
+		pos += ACPI_SAR_NUM_CHAINS * ACPI_SAR_NUM_SUB_BANDS;
 	}
 
 out_free:
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
index 24e94430e5d9..cd26a155baf7 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
@@ -26,7 +26,6 @@
 
 #define ACPI_WIFI_DOMAIN	(0x07)
 
-#define ACPI_SAR_TABLE_SIZE		10
 #define ACPI_SAR_PROFILE_NUM		4
 
 #define ACPI_GEO_TABLE_SIZE		6
@@ -37,9 +36,11 @@
 #define ACPI_SAR_NUM_SUB_BANDS		5
 #define ACPI_SAR_NUM_TABLES		1
 
-#define ACPI_WRDS_WIFI_DATA_SIZE	(ACPI_SAR_TABLE_SIZE + 2)
+#define ACPI_WRDS_WIFI_DATA_SIZE	(ACPI_SAR_NUM_CHAINS * \
+					 ACPI_SAR_NUM_SUB_BANDS + 2)
 #define ACPI_EWRD_WIFI_DATA_SIZE	((ACPI_SAR_PROFILE_NUM - 1) * \
-					 ACPI_SAR_TABLE_SIZE + 3)
+					 ACPI_SAR_NUM_CHAINS * \
+					 ACPI_SAR_NUM_SUB_BANDS + 3)
 #define ACPI_WGDS_WIFI_DATA_SIZE	19
 #define ACPI_WRDD_WIFI_DATA_SIZE	2
 #define ACPI_SPLC_WIFI_DATA_SIZE	2
@@ -64,9 +65,13 @@
 #define ACPI_PPAG_MIN_HB -16
 #define ACPI_PPAG_MAX_HB 40
 
+struct iwl_sar_profile_chain {
+	u8 subbands[ACPI_SAR_NUM_SUB_BANDS];
+};
+
 struct iwl_sar_profile {
 	bool enabled;
-	u8 table[ACPI_SAR_TABLE_SIZE];
+	struct iwl_sar_profile_chain chains[ACPI_SAR_NUM_CHAINS];
 };
 
 struct iwl_geo_profile {
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 12/12] iwlwifi: remove ACPI_SAR_NUM_TABLES definition
  2021-08-05 10:19 [PATCH 00/12] iwlwifi: updates intended for v5.15 2021-08-05 Luca Coelho
                   ` (10 preceding siblings ...)
  2021-08-05 10:19 ` [PATCH 11/12] iwlwifi: convert flat SAR profile table to a struct version Luca Coelho
@ 2021-08-05 10:19 ` Luca Coelho
  11 siblings, 0 replies; 14+ messages in thread
From: Luca Coelho @ 2021-08-05 10:19 UTC (permalink / raw)
  To: kvalo; +Cc: luca, linux-wireless

From: Luca Coelho <luciano.coelho@intel.com>

This definition was only used to pass the size of the tables in the FW
API to the iwl_sar_select_profile() function, but we should actually
pass the definition from the FW API file.  We don't have the concept
of tables in the ACPI definition, so we can remove it.

Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/acpi.h | 1 -
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c  | 3 ++-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
index cd26a155baf7..245f0646c8f8 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
@@ -34,7 +34,6 @@
 
 #define ACPI_SAR_NUM_CHAINS		2
 #define ACPI_SAR_NUM_SUB_BANDS		5
-#define ACPI_SAR_NUM_TABLES		1
 
 #define ACPI_WRDS_WIFI_DATA_SIZE	(ACPI_SAR_NUM_CHAINS * \
 					 ACPI_SAR_NUM_SUB_BANDS + 2)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 38fd5886af2d..0b769aac0b02 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -743,7 +743,8 @@ int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b)
 	/* all structs have the same common part, add it */
 	len += sizeof(cmd.common);
 
-	ret = iwl_sar_select_profile(&mvm->fwrt, per_chain, ACPI_SAR_NUM_TABLES,
+	ret = iwl_sar_select_profile(&mvm->fwrt, per_chain,
+				     IWL_NUM_CHAIN_TABLES,
 				     n_subbands, prof_a, prof_b);
 
 	/* return on error or if the profile is disabled (positive number) */
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH 01/12] iwlwifi: mvm: d3: separate TKIP data from key iteration
  2021-08-05 10:19 ` [PATCH 01/12] iwlwifi: mvm: d3: separate TKIP data from key iteration Luca Coelho
@ 2021-08-26 20:35   ` Luca Coelho
  0 siblings, 0 replies; 14+ messages in thread
From: Luca Coelho @ 2021-08-26 20:35 UTC (permalink / raw)
  To: Luca Coelho; +Cc: kvalo, linux-wireless

Luca Coelho <luca@coelho.fi> wrote:

> From: Johannes Berg <johannes.berg@intel.com>
> 
> We do a key iteration to program the keys, and while at it
> we also collect the data necessary for TKIP. This code has
> all kinds of dependencies on the firmware API though, so
> take out the TKIP phase 1 key generation and do that in a
> separate key iteration only if necessary.
> 
> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
> Signed-off-by: Luca Coelho <luciano.coelho@intel.com>

12 patches applied to iwlwifi-next.git, thanks.

0419e5e672d6 iwlwifi: mvm: d3: separate TKIP data from key iteration
398760aa9679 iwlwifi: mvm: d3: remove fixed cmd_flags argument
631ee5120285 iwlwifi: mvm: d3: refactor TSC/RSC configuration
be05fae23d03 iwlwifi: mvm: d3: add separate key iteration for GTK type
af3aab9ce298 iwlwifi: mvm: d3: make key reprogramming iteration optional
79e561f0f05a iwlwifi: mvm: d3: implement RSC command version 5
3df5c0ddcf81 iwlwifi: mvm: silently drop encrypted frames for unknown station
967a39832ebe iwlwifi: mvm: Refactor setting of SSIDs for 6GHz scan
6c608cd6962e iwlwifi: mvm: fix access to BSS elements
248e7e2a1d8d iwlwifi: rename ACPI_SAR_NUM_CHAIN_LIMITS to ACPI_SAR_NUM_CHAINS
81870d138dfe iwlwifi: convert flat SAR profile table to a struct version
dac7171c8132 iwlwifi: remove ACPI_SAR_NUM_TABLES definition


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2021-08-26 20:35 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-05 10:19 [PATCH 00/12] iwlwifi: updates intended for v5.15 2021-08-05 Luca Coelho
2021-08-05 10:19 ` [PATCH 01/12] iwlwifi: mvm: d3: separate TKIP data from key iteration Luca Coelho
2021-08-26 20:35   ` Luca Coelho
2021-08-05 10:19 ` [PATCH 02/12] iwlwifi: mvm: d3: remove fixed cmd_flags argument Luca Coelho
2021-08-05 10:19 ` [PATCH 03/12] iwlwifi: mvm: d3: refactor TSC/RSC configuration Luca Coelho
2021-08-05 10:19 ` [PATCH 04/12] iwlwifi: mvm: d3: add separate key iteration for GTK type Luca Coelho
2021-08-05 10:19 ` [PATCH 05/12] iwlwifi: mvm: d3: make key reprogramming iteration optional Luca Coelho
2021-08-05 10:19 ` [PATCH 06/12] iwlwifi: mvm: d3: implement RSC command version 5 Luca Coelho
2021-08-05 10:19 ` [PATCH 07/12] iwlwifi: mvm: silently drop encrypted frames for unknown station Luca Coelho
2021-08-05 10:19 ` [PATCH 08/12] iwlwifi: mvm: Refactor setting of SSIDs for 6GHz scan Luca Coelho
2021-08-05 10:19 ` [PATCH 09/12] iwlwifi: mvm: fix access to BSS elements Luca Coelho
2021-08-05 10:19 ` [PATCH 10/12] iwlwifi: rename ACPI_SAR_NUM_CHAIN_LIMITS to ACPI_SAR_NUM_CHAINS Luca Coelho
2021-08-05 10:19 ` [PATCH 11/12] iwlwifi: convert flat SAR profile table to a struct version Luca Coelho
2021-08-05 10:19 ` [PATCH 12/12] iwlwifi: remove ACPI_SAR_NUM_TABLES definition Luca Coelho

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.