Commit 0945f976 authored by Avraham Stern's avatar Avraham Stern Committed by Johannes Berg

wifi: iwlwifi: mvm: support PASN for MLO

When adding a PASN station, the non MLD API was used. This results
in assert when operating as MLD. Fix it to use the MLD API when
operating as MLD. For now, the default link is used for the added
station.
Signed-off-by: default avatarAvraham Stern <avraham.stern@intel.com>
Signed-off-by: default avatarGregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230524203151.7c35dccc8a12.I7bc78cd16d7c750f42fdd60e07e839a860d279d2@changeidSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 1be4858e
......@@ -51,10 +51,10 @@ static u32 iwl_mvm_get_sec_sta_mask(struct iwl_mvm *mvm,
return iwl_mvm_sta_fw_id_mask(mvm, sta, keyconf->link_id);
}
static u32 iwl_mvm_get_sec_flags(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct ieee80211_key_conf *keyconf)
u32 iwl_mvm_get_sec_flags(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct ieee80211_key_conf *keyconf)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
u32 flags = 0;
......@@ -164,13 +164,9 @@ static int __iwl_mvm_sec_key_del(struct iwl_mvm *mvm, u32 sta_mask,
return iwl_mvm_send_cmd_pdu(mvm, cmd_id, flags, sizeof(cmd), &cmd);
}
int iwl_mvm_sec_key_add(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct ieee80211_key_conf *keyconf)
int iwl_mvm_mld_send_key(struct iwl_mvm *mvm, u32 sta_mask, u32 key_flags,
struct ieee80211_key_conf *keyconf)
{
u32 sta_mask = iwl_mvm_get_sec_sta_mask(mvm, vif, sta, keyconf);
u32 key_flags = iwl_mvm_get_sec_flags(mvm, vif, sta, keyconf);
u32 cmd_id = WIDE_ID(DATA_PATH_GROUP, SEC_KEY_CMD);
struct iwl_sec_key_cmd cmd = {
.action = cpu_to_le32(FW_CTXT_ACTION_ADD),
......@@ -223,6 +219,17 @@ int iwl_mvm_sec_key_add(struct iwl_mvm *mvm,
return ret;
}
int iwl_mvm_sec_key_add(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct ieee80211_key_conf *keyconf)
{
u32 sta_mask = iwl_mvm_get_sec_sta_mask(mvm, vif, sta, keyconf);
u32 key_flags = iwl_mvm_get_sec_flags(mvm, vif, sta, keyconf);
return iwl_mvm_mld_send_key(mvm, sta_mask, key_flags, keyconf);
}
static int _iwl_mvm_sec_key_del(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
......
......@@ -128,11 +128,11 @@ static int iwl_mvm_add_aux_sta_to_fw(struct iwl_mvm *mvm,
/*
* Adds an internal sta to the FW table with its queues
*/
static int iwl_mvm_mld_add_int_sta_with_queue(struct iwl_mvm *mvm,
struct iwl_mvm_int_sta *sta,
const u8 *addr, int link_id,
u16 *queue, u8 tid,
unsigned int *_wdg_timeout)
int iwl_mvm_mld_add_int_sta_with_queue(struct iwl_mvm *mvm,
struct iwl_mvm_int_sta *sta,
const u8 *addr, int link_id,
u16 *queue, u8 tid,
unsigned int *_wdg_timeout)
{
int ret, txq;
unsigned int wdg_timeout = _wdg_timeout ? *_wdg_timeout :
......
......@@ -2361,6 +2361,12 @@ int iwl_mvm_mld_update_sta_keys(struct iwl_mvm *mvm,
struct ieee80211_sta *sta,
u32 old_sta_mask,
u32 new_sta_mask);
int iwl_mvm_mld_send_key(struct iwl_mvm *mvm, u32 sta_mask, u32 key_flags,
struct ieee80211_key_conf *keyconf);
u32 iwl_mvm_get_sec_flags(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct ieee80211_key_conf *keyconf);
int iwl_rfi_send_config_cmd(struct iwl_mvm *mvm,
struct iwl_rfi_lut_entry *rfi_table);
......
......@@ -4301,16 +4301,27 @@ int iwl_mvm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
u16 queue;
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct ieee80211_key_conf *keyconf;
unsigned int wdg_timeout =
iwl_mvm_get_wd_timeout(mvm, vif, false, false);
bool mld = iwl_mvm_has_mld_api(mvm->fw);
u32 type = mld ? STATION_TYPE_PEER : IWL_STA_LINK;
ret = iwl_mvm_allocate_int_sta(mvm, sta, 0,
NL80211_IFTYPE_UNSPECIFIED,
IWL_STA_LINK);
NL80211_IFTYPE_UNSPECIFIED, type);
if (ret)
return ret;
ret = iwl_mvm_add_int_sta_with_queue(mvm, mvmvif->id, mvmvif->color,
addr, sta, &queue,
IWL_MVM_TX_FIFO_BE);
if (mld)
ret = iwl_mvm_mld_add_int_sta_with_queue(mvm, sta, addr,
mvmvif->deflink.fw_link_id,
&queue,
IWL_MAX_TID_COUNT,
&wdg_timeout);
else
ret = iwl_mvm_add_int_sta_with_queue(mvm, mvmvif->id,
mvmvif->color, addr, sta,
&queue,
IWL_MVM_TX_FIFO_BE);
if (ret)
goto out;
......@@ -4323,9 +4334,23 @@ int iwl_mvm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
keyconf->cipher = cipher;
memcpy(keyconf->key, key, key_len);
keyconf->keylen = key_len;
keyconf->flags = IEEE80211_KEY_FLAG_PAIRWISE;
if (mld) {
/* The MFP flag is set according to the station mfp field. Since
* we don't have a station, set it manually.
*/
u32 key_flags =
iwl_mvm_get_sec_flags(mvm, vif, NULL, keyconf) |
IWL_SEC_KEY_FLAG_MFP;
u32 sta_mask = BIT(sta->sta_id);
ret = iwl_mvm_mld_send_key(mvm, sta_mask, key_flags, keyconf);
} else {
ret = iwl_mvm_send_sta_key(mvm, sta->sta_id, keyconf, false,
0, NULL, 0, 0, true);
}
ret = iwl_mvm_send_sta_key(mvm, sta->sta_id, keyconf, false,
0, NULL, 0, 0, true);
kfree(keyconf);
return 0;
out:
......
......@@ -646,6 +646,11 @@ int iwl_mvm_mld_update_sta_links(struct iwl_mvm *mvm,
u16 old_links, u16 new_links);
u32 iwl_mvm_sta_fw_id_mask(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
int filter_link_id);
int iwl_mvm_mld_add_int_sta_with_queue(struct iwl_mvm *mvm,
struct iwl_mvm_int_sta *sta,
const u8 *addr, int link_id,
u16 *queue, u8 tid,
unsigned int *_wdg_timeout);
/* Queues */
void iwl_mvm_mld_modify_all_sta_disable_tx(struct iwl_mvm *mvm,
......
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