Commit 890d814b authored by Avraham Stern's avatar Avraham Stern Committed by Luca Coelho
Browse files

iwlwifi: mvm: location: set the HLTK when PASN station is added

parent b68bd2e3
Loading
Loading
Loading
Loading
+32 −11
Original line number Diff line number Diff line
@@ -306,6 +306,16 @@ iwl_mvm_ftm_responder_dyn_cfg_cmd(struct iwl_mvm *mvm,
	return ret;
}

static void iwl_mvm_resp_del_pasn_sta(struct iwl_mvm *mvm,
				      struct ieee80211_vif *vif,
				      struct iwl_mvm_pasn_sta *sta)
{
	list_del(&sta->list);
	iwl_mvm_rm_sta_id(mvm, vif, sta->int_sta.sta_id);
	iwl_mvm_dealloc_int_sta(mvm, &sta->int_sta);
	kfree(sta);
}

int iwl_mvm_ftm_respoder_add_pasn_sta(struct iwl_mvm *mvm,
				      struct ieee80211_vif *vif,
				      u8 *addr, u32 cipher, u8 *tk, u32 tk_len,
@@ -313,9 +323,26 @@ int iwl_mvm_ftm_respoder_add_pasn_sta(struct iwl_mvm *mvm,
{
	int ret;
	struct iwl_mvm_pasn_sta *sta;
	struct iwl_mvm_pasn_hltk_data hltk_data = {
		.addr = addr,
		.hltk = hltk,
	};
	u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, LOCATION_GROUP,
					   TOF_RESPONDER_DYN_CONFIG_CMD, 2);

	lockdep_assert_held(&mvm->mutex);

	if (cmd_ver < 3) {
		IWL_ERR(mvm, "Adding PASN station not supported by FW\n");
		return -ENOTSUPP;
	}

	hltk_data.cipher = iwl_mvm_cipher_to_location_cipher(cipher);
	if (hltk_data.cipher == IWL_LOCATION_CIPHER_INVALID) {
		IWL_ERR(mvm, "invalid cipher: %u\n", cipher);
		return -EINVAL;
	}

	sta = kmalloc(sizeof(*sta), GFP_KERNEL);
	if (!sta)
		return -ENOBUFS;
@@ -327,23 +354,17 @@ int iwl_mvm_ftm_respoder_add_pasn_sta(struct iwl_mvm *mvm,
		return ret;
	}

	// TODO: set the HLTK to fw
	ret = iwl_mvm_ftm_responder_dyn_cfg_v3(mvm, vif, NULL, &hltk_data);
	if (ret) {
		iwl_mvm_resp_del_pasn_sta(mvm, vif, sta);
		return ret;
	}

	memcpy(sta->addr, addr, ETH_ALEN);
	list_add_tail(&sta->list, &mvm->resp_pasn_list);
	return 0;
}

static void iwl_mvm_resp_del_pasn_sta(struct iwl_mvm *mvm,
				      struct ieee80211_vif *vif,
				      struct iwl_mvm_pasn_sta *sta)
{
	list_del(&sta->list);
	iwl_mvm_rm_sta_id(mvm, vif, sta->int_sta.sta_id);
	iwl_mvm_dealloc_int_sta(mvm, &sta->int_sta);
	kfree(sta);
}

int iwl_mvm_ftm_resp_remove_pasn_sta(struct iwl_mvm *mvm,
				     struct ieee80211_vif *vif, u8 *addr)
{
+15 −0
Original line number Diff line number Diff line
@@ -2161,4 +2161,19 @@ static inline int iwl_umac_scan_get_max_profiles(const struct iwl_fw *fw)
	return (ver == IWL_FW_CMD_VER_UNKNOWN || ver < 3) ?
		IWL_SCAN_MAX_PROFILES : IWL_SCAN_MAX_PROFILES_V2;
}

static inline
enum iwl_location_cipher iwl_mvm_cipher_to_location_cipher(u32 cipher)
{
	switch (cipher) {
	case WLAN_CIPHER_SUITE_CCMP:
		return IWL_LOCATION_CIPHER_CCMP_128;
	case WLAN_CIPHER_SUITE_GCMP:
		return IWL_LOCATION_CIPHER_GCMP_128;
	case WLAN_CIPHER_SUITE_GCMP_256:
		return IWL_LOCATION_CIPHER_GCMP_256;
	default:
		return IWL_LOCATION_CIPHER_INVALID;
	}
}
#endif /* __IWL_MVM_H__ */