wifi: iwlwifi: mvm: adjust csa notifications and commands to MLO
authorGregory Greenman <gregory.greenman@intel.com>
Wed, 24 May 2023 17:42:06 +0000 (20:42 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 6 Jun 2023 11:04:54 +0000 (13:04 +0200)
In the following notifications and commands mac_id was replaced
with link_id:
* CANCEL_CHANNEL_SWITCH_CMD
* CHANNEL_SWITCH_START_NOTIF
* CHANNEL_SWITCH_ERROR_NOTIF

The logic around was not changed, so only adjust handling
mac/link id.

Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230524203151.6aa6e394f5fe.Ie9e78918511ca901f9f3966d774fa74a71a186e3@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h
drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
drivers/net/wireless/intel/iwlwifi/mvm/sta.c
drivers/net/wireless/intel/iwlwifi/mvm/sta.h

index edf9ac52a6811953efbba707d24a84e90f90b56a..b4244fa0516b9aedd17a2de659555c118c7ad05f 100644 (file)
@@ -140,33 +140,53 @@ struct iwl_missed_vap_notif {
  *
  * @id_and_color: ID and color of the MAC
  */
-struct iwl_channel_switch_start_notif {
+struct iwl_channel_switch_start_notif_v1 {
        __le32 id_and_color;
 } __packed; /* CHANNEL_SWITCH_START_NTFY_API_S_VER_1 */
 
+/**
+ * struct iwl_channel_switch_start_notif - Channel switch start notification
+ *
+ * @link_id: FW link id
+ */
+struct iwl_channel_switch_start_notif {
+       __le32 link_id;
+} __packed; /* CHANNEL_SWITCH_START_NTFY_API_S_VER_3 */
+
 #define CS_ERR_COUNT_ERROR BIT(0)
 #define CS_ERR_LONG_DELAY_AFTER_CS BIT(1)
 #define CS_ERR_LONG_TX_BLOCK BIT(2)
 #define CS_ERR_TX_BLOCK_TIMER_EXPIRED BIT(3)
 
 /**
- * struct iwl_channel_switch_error_notif - Channel switch error notification
+ * struct iwl_channel_switch_error_notif_v1 - Channel switch error notification
  *
  * @mac_id: the mac for which the ucode sends the notification for
  * @csa_err_mask: mask of channel switch error that can occur
  */
-struct iwl_channel_switch_error_notif {
+struct iwl_channel_switch_error_notif_v1 {
        __le32 mac_id;
        __le32 csa_err_mask;
 } __packed; /* CHANNEL_SWITCH_ERROR_NTFY_API_S_VER_1 */
 
+/**
+ * struct iwl_channel_switch_error_notif - Channel switch error notification
+ *
+ * @link_id: FW link id
+ * @csa_err_mask: mask of channel switch error that can occur
+ */
+struct iwl_channel_switch_error_notif {
+       __le32 link_id;
+       __le32 csa_err_mask;
+} __packed; /* CHANNEL_SWITCH_ERROR_NTFY_API_S_VER_2 */
+
 /**
  * struct iwl_cancel_channel_switch_cmd - Cancel Channel Switch command
  *
- * @mac_id: the mac that should cancel the channel switch
+ * @id: the id of the link or mac that should cancel the channel switch
  */
 struct iwl_cancel_channel_switch_cmd {
-       __le32 mac_id;
+       __le32 id;
 } __packed; /* MAC_CANCEL_CHANNEL_SWITCH_S_VER_1 */
 
 /**
index f049ef6a8707c9d09dfa77876876eac62014ea96..059ede6f7b6594de54a9534d85bdd5fd00efa828 100644 (file)
@@ -1747,20 +1747,44 @@ void iwl_mvm_channel_switch_start_notif(struct iwl_mvm *mvm,
                                        struct iwl_rx_cmd_buffer *rxb)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwl_channel_switch_start_notif *notif = (void *)pkt->data;
        struct ieee80211_vif *csa_vif, *vif;
-       struct iwl_mvm_vif *mvmvif;
-       u32 id_n_color, csa_id, mac_id;
+       struct iwl_mvm_vif *mvmvif, *csa_mvmvif;
+       u32 id_n_color, csa_id;
+       /* save mac_id or link_id to use later to cancel csa if needed */
+       u32 id;
+       u8 notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, MAC_CONF_GROUP,
+                                              CHANNEL_SWITCH_START_NOTIF, 0);
 
-       id_n_color = le32_to_cpu(notif->id_and_color);
-       mac_id = id_n_color & FW_CTXT_ID_MSK;
+       rcu_read_lock();
 
-       if (WARN_ON_ONCE(mac_id >= NUM_MAC_INDEX_DRIVER))
-               return;
+       if (notif_ver < 3) {
+               struct iwl_channel_switch_start_notif_v1 *notif = (void *)pkt->data;
+               u32 mac_id;
+
+               id_n_color = le32_to_cpu(notif->id_and_color);
+               mac_id = id_n_color & FW_CTXT_ID_MSK;
+
+               vif = iwl_mvm_rcu_dereference_vif_id(mvm, mac_id, true);
+               if (!vif)
+                       goto out_unlock;
+
+               id = mac_id;
+       } else {
+               struct iwl_channel_switch_start_notif *notif = (void *)pkt->data;
+               u32 link_id = le32_to_cpu(notif->link_id);
+               struct ieee80211_bss_conf *bss_conf =
+                       iwl_mvm_rcu_fw_link_id_to_link_conf(mvm, link_id, true);
+
+               if (!bss_conf)
+                       goto out_unlock;
+
+               id = link_id;
+               vif = bss_conf->vif;
+       }
 
-       rcu_read_lock();
-       vif = rcu_dereference(mvm->vif_id_to_mac[mac_id]);
        mvmvif = iwl_mvm_vif_from_mac80211(vif);
+       if (notif_ver >= 3)
+               id_n_color = FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color);
 
        switch (vif->type) {
        case NL80211_IFTYPE_AP:
@@ -1769,7 +1793,8 @@ void iwl_mvm_channel_switch_start_notif(struct iwl_mvm *mvm,
                            csa_vif != vif))
                        goto out_unlock;
 
-               csa_id = FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color);
+               csa_mvmvif = iwl_mvm_vif_from_mac80211(csa_vif);
+               csa_id = FW_CMD_ID_AND_COLOR(csa_mvmvif->id, csa_mvmvif->color);
                if (WARN(csa_id != id_n_color,
                         "channel switch noa notification on unexpected vif (csa_vif=%d, notif=%d)",
                         csa_id, id_n_color))
@@ -1796,7 +1821,7 @@ void iwl_mvm_channel_switch_start_notif(struct iwl_mvm *mvm,
                                            CHANNEL_SWITCH_ERROR_NOTIF,
                                            0) && !vif->bss_conf.csa_active) {
                        IWL_DEBUG_INFO(mvm, "Channel Switch was canceled\n");
-                       iwl_mvm_cancel_channel_switch(mvm, vif, mac_id);
+                       iwl_mvm_cancel_channel_switch(mvm, vif, id);
                        break;
                }
 
@@ -1819,7 +1844,7 @@ void iwl_mvm_channel_switch_error_notif(struct iwl_mvm *mvm,
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl_channel_switch_error_notif *notif = (void *)pkt->data;
        struct ieee80211_vif *vif;
-       u32 id = le32_to_cpu(notif->mac_id);
+       u32 id = le32_to_cpu(notif->link_id);
        u32 csa_err_mask = le32_to_cpu(notif->csa_err_mask);
 
        rcu_read_lock();
@@ -1829,7 +1854,7 @@ void iwl_mvm_channel_switch_error_notif(struct iwl_mvm *mvm,
                return;
        }
 
-       IWL_DEBUG_INFO(mvm, "FW reports CSA error: mac_id=%u, csa_err_mask=%u\n",
+       IWL_DEBUG_INFO(mvm, "FW reports CSA error: id=%u, csa_err_mask=%u\n",
                       id, csa_err_mask);
        if (csa_err_mask & (CS_ERR_COUNT_ERROR |
                            CS_ERR_LONG_DELAY_AFTER_CS |
index afccbd916a65c3ad79c2d856077d2ca83667cb34..4e3f994654c9d23f9127df4675eb2a95e2c84555 100644 (file)
@@ -4360,10 +4360,10 @@ out:
 
 void iwl_mvm_cancel_channel_switch(struct iwl_mvm *mvm,
                                   struct ieee80211_vif *vif,
-                                  u32 mac_id)
+                                  u32 id)
 {
        struct iwl_cancel_channel_switch_cmd cancel_channel_switch_cmd = {
-               .mac_id = cpu_to_le32(mac_id),
+               .id = cpu_to_le32(id),
        };
        int ret;
 
index e396034b8795563a4ad8aff18fee306307f2af12..9acc01b7a4c9e0b553f4774352b27ddf4d1393e1 100644 (file)
@@ -365,6 +365,7 @@ struct iwl_mvm_link_sta {
  * and from Tx response flow, it needs a spinlock.
  * @tid_data: per tid data + mgmt. Look at %iwl_mvm_tid_data.
  * @tid_to_baid: a simple map of TID to baid
+ * @vif: a vif pointer
  * @reserved_queue: the queue reserved for this STA for DQA purposes
  *     Every STA has is given one reserved queue to allow it to operate. If no
  *     such queue can be guaranteed, the STA addition will fail.
@@ -378,6 +379,7 @@ struct iwl_mvm_link_sta {
  *      debugfs.  If it's set to 0, it means that it is it's not set via
  *      debugfs.
  * @agg_tids: bitmap of tids whose status is operational aggregated (IWL_AGG_ON)
+ * @sleeping: sta sleep transitions in power management
  * @sleep_tx_count: the number of frames that we told the firmware to let out
  *     even when that station is asleep. This is useful in case the queue
  *     gets empty before all the frames were sent, which can happen when
@@ -580,7 +582,7 @@ int iwl_mvm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
                         u8 *key, u32 key_len);
 void iwl_mvm_cancel_channel_switch(struct iwl_mvm *mvm,
                                   struct ieee80211_vif *vif,
-                                  u32 mac_id);
+                                  u32 id);
 /* Queues */
 int iwl_mvm_tvqm_enable_txq(struct iwl_mvm *mvm,
                            struct ieee80211_sta *sta,