wifi: iwlwifi: mvm: support PASN for MLO
authorAvraham Stern <avraham.stern@intel.com>
Wed, 24 May 2023 17:42:02 +0000 (20:42 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 6 Jun 2023 11:03:31 +0000 (13:03 +0200)
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: Avraham Stern <avraham.stern@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230524203151.7c35dccc8a12.I7bc78cd16d7c750f42fdd60e07e839a860d279d2@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/intel/iwlwifi/mvm/mld-key.c
drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
drivers/net/wireless/intel/iwlwifi/mvm/sta.c
drivers/net/wireless/intel/iwlwifi/mvm/sta.h

index 8853821b3716817b1b45cc6f4ad1b6e01d6acd07..3e6f86f644b581252e4a63594532798256c7bce9 100644 (file)
@@ -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,
index 0bfdf446275508a1c82b8a3335048af2a1591c3a..401f94bd1f9c62461b7a54e825022fedbd00badb 100644 (file)
@@ -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 :
index 0f278a73a997412d83f1dea37cd0d1bd2e6dae3a..5f7469cfd092952d7c99edd92972f4409bfe1586 100644 (file)
@@ -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);
index 5469d634e28998a12b2c9bd2fefde11dbddbdd0a..afccbd916a65c3ad79c2d856077d2ca83667cb34 100644 (file)
@@ -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:
index f5f8d41f51346d686735d4b4014fbcec4d1bd799..e396034b8795563a4ad8aff18fee306307f2af12 100644 (file)
@@ -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,