]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: ath12k: ath12k_mac_op_ampdu_action(): MLO support
authorSriram R <quic_srirrama@quicinc.com>
Tue, 26 Nov 2024 17:11:33 +0000 (19:11 +0200)
committerKalle Valo <quic_kvalo@quicinc.com>
Fri, 29 Nov 2024 11:17:45 +0000 (13:17 +0200)
Apply tid queue setup based on all link stations on receiving ampdu action
params for an ML Station.

Modify ath12k_get_ar_by_vif() to fetch ar based on link arvif inside ahvif.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3

Signed-off-by: Sriram R <quic_srirrama@quicinc.com>
Signed-off-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://patch.msgid.link/20241126171139.2350704-5-kvalo@kernel.org
drivers/net/wireless/ath/ath12k/dp_rx.c
drivers/net/wireless/ath/ath12k/dp_rx.h
drivers/net/wireless/ath/ath12k/mac.c

index 70680f2124e5201eef9c97d486ebcedf894f7c12..b24d1de4aabb9fc50be62f278e413042b85064a3 100644 (file)
@@ -1065,15 +1065,25 @@ err_mem_free:
 }
 
 int ath12k_dp_rx_ampdu_start(struct ath12k *ar,
-                            struct ieee80211_ampdu_params *params)
+                            struct ieee80211_ampdu_params *params,
+                            u8 link_id)
 {
        struct ath12k_base *ab = ar->ab;
        struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(params->sta);
-       struct ath12k_link_sta *arsta = &ahsta->deflink;
-       int vdev_id = arsta->arvif->vdev_id;
+       struct ath12k_link_sta *arsta;
+       int vdev_id;
        int ret;
 
-       ret = ath12k_dp_rx_peer_tid_setup(ar, params->sta->addr, vdev_id,
+       lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
+
+       arsta = wiphy_dereference(ath12k_ar_to_hw(ar)->wiphy,
+                                 ahsta->link[link_id]);
+       if (!arsta)
+               return -ENOLINK;
+
+       vdev_id = arsta->arvif->vdev_id;
+
+       ret = ath12k_dp_rx_peer_tid_setup(ar, arsta->addr, vdev_id,
                                          params->tid, params->buf_size,
                                          params->ssn, arsta->ahsta->pn_type);
        if (ret)
@@ -1083,19 +1093,29 @@ int ath12k_dp_rx_ampdu_start(struct ath12k *ar,
 }
 
 int ath12k_dp_rx_ampdu_stop(struct ath12k *ar,
-                           struct ieee80211_ampdu_params *params)
+                           struct ieee80211_ampdu_params *params,
+                           u8 link_id)
 {
        struct ath12k_base *ab = ar->ab;
        struct ath12k_peer *peer;
        struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(params->sta);
-       struct ath12k_link_sta *arsta = &ahsta->deflink;
-       int vdev_id = arsta->arvif->vdev_id;
+       struct ath12k_link_sta *arsta;
+       int vdev_id;
        bool active;
        int ret;
 
+       lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
+
+       arsta = wiphy_dereference(ath12k_ar_to_hw(ar)->wiphy,
+                                 ahsta->link[link_id]);
+       if (!arsta)
+               return -ENOLINK;
+
+       vdev_id = arsta->arvif->vdev_id;
+
        spin_lock_bh(&ab->base_lock);
 
-       peer = ath12k_peer_find(ab, vdev_id, params->sta->addr);
+       peer = ath12k_peer_find(ab, vdev_id, arsta->addr);
        if (!peer) {
                spin_unlock_bh(&ab->base_lock);
                ath12k_warn(ab, "failed to find the peer to stop rx aggregation\n");
index bfd4f814553e766bdd56def032f62a2e8649d8b0..1ce82088c9540925fb085cadaa38b3e67ff2828b 100644 (file)
@@ -85,9 +85,11 @@ static inline u32 ath12k_he_gi_to_nl80211_he_gi(u8 sgi)
 }
 
 int ath12k_dp_rx_ampdu_start(struct ath12k *ar,
-                            struct ieee80211_ampdu_params *params);
+                            struct ieee80211_ampdu_params *params,
+                            u8 link_id);
 int ath12k_dp_rx_ampdu_stop(struct ath12k *ar,
-                           struct ieee80211_ampdu_params *params);
+                           struct ieee80211_ampdu_params *params,
+                           u8 link_id);
 int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif,
                                       const u8 *peer_addr,
                                       enum set_key_cmd key_cmd,
index 595e8110ab86c403c3f68c6db197f2b854a4733f..ec8209f172613b98a36885be2ee7cd36ecef63a9 100644 (file)
@@ -725,11 +725,14 @@ static struct ath12k *ath12k_get_ar_by_ctx(struct ieee80211_hw *hw,
 }
 
 static struct ath12k *ath12k_get_ar_by_vif(struct ieee80211_hw *hw,
-                                          struct ieee80211_vif *vif)
+                                          struct ieee80211_vif *vif,
+                                          u8 link_id)
 {
        struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif);
-       struct ath12k_link_vif *arvif = &ahvif->deflink;
        struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
+       struct ath12k_link_vif *arvif;
+
+       lockdep_assert_wiphy(hw->wiphy);
 
        /* If there is one pdev within ah, then we return
         * ar directly.
@@ -737,7 +740,11 @@ static struct ath12k *ath12k_get_ar_by_vif(struct ieee80211_hw *hw,
        if (ah->num_radio == 1)
                return ah->radio;
 
-       if (arvif->is_created)
+       if (!(ahvif->links_map & BIT(link_id)))
+               return NULL;
+
+       arvif = wiphy_dereference(hw->wiphy, ahvif->link[link_id]);
+       if (arvif && arvif->is_created)
                return arvif->ar;
 
        return NULL;
@@ -5667,6 +5674,7 @@ static void ath12k_mac_op_sta_rc_update(struct ieee80211_hw *hw,
        struct ath12k *ar;
        struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(sta);
        struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif);
+       struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
        struct ath12k_link_sta *arsta;
        struct ath12k_link_vif *arvif;
        struct ath12k_peer *peer;
@@ -5676,20 +5684,17 @@ static void ath12k_mac_op_sta_rc_update(struct ieee80211_hw *hw,
         */
        u8 link_id = ATH12K_DEFAULT_LINK_ID;
 
-       ar = ath12k_get_ar_by_vif(hw, vif);
-       if (!ar) {
-               WARN_ON_ONCE(1);
-               return;
-       }
-
        rcu_read_lock();
        arvif = rcu_dereference(ahvif->link[link_id]);
        if (!arvif) {
-               ath12k_warn(ar->ab, "mac sta rc update failed to fetch link vif on link id %u for peer %pM\n",
-                           link_id, sta->addr);
+               ath12k_hw_warn(ah, "mac sta rc update failed to fetch link vif on link id %u for peer %pM\n",
+                              link_id, sta->addr);
                rcu_read_unlock();
                return;
        }
+
+       ar = arvif->ar;
+
        arsta = rcu_dereference(ahsta->link[link_id]);
        if (!arsta) {
                rcu_read_unlock();
@@ -8288,20 +8293,26 @@ static int ath12k_mac_op_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx
        return ret;
 }
 
-static int ath12k_mac_ampdu_action(struct ath12k_link_vif *arvif,
-                                  struct ieee80211_ampdu_params *params)
+static int ath12k_mac_ampdu_action(struct ieee80211_hw *hw,
+                                  struct ieee80211_vif *vif,
+                                  struct ieee80211_ampdu_params *params,
+                                  u8 link_id)
 {
-       struct ath12k *ar = arvif->ar;
+       struct ath12k *ar;
        int ret = -EINVAL;
 
-       lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
+       lockdep_assert_wiphy(hw->wiphy);
+
+       ar = ath12k_get_ar_by_vif(hw, vif, link_id);
+       if (!ar)
+               return -EINVAL;
 
        switch (params->action) {
        case IEEE80211_AMPDU_RX_START:
-               ret = ath12k_dp_rx_ampdu_start(ar, params);
+               ret = ath12k_dp_rx_ampdu_start(ar, params, link_id);
                break;
        case IEEE80211_AMPDU_RX_STOP:
-               ret = ath12k_dp_rx_ampdu_stop(ar, params);
+               ret = ath12k_dp_rx_ampdu_stop(ar, params, link_id);
                break;
        case IEEE80211_AMPDU_TX_START:
        case IEEE80211_AMPDU_TX_STOP_CONT:
@@ -8315,6 +8326,10 @@ static int ath12k_mac_ampdu_action(struct ath12k_link_vif *arvif,
                break;
        }
 
+       if (ret)
+               ath12k_warn(ar->ab, "unable to perform ampdu action %d for vif %pM link %u ret %d\n",
+                           params->action, vif->addr, link_id, ret);
+
        return ret;
 }
 
@@ -8322,27 +8337,24 @@ static int ath12k_mac_op_ampdu_action(struct ieee80211_hw *hw,
                                      struct ieee80211_vif *vif,
                                      struct ieee80211_ampdu_params *params)
 {
-       struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
-       struct ath12k *ar;
-       struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif);
-       struct ath12k_link_vif *arvif;
+       struct ieee80211_sta *sta = params->sta;
+       struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(sta);
+       unsigned long links_map = ahsta->links_map;
        int ret = -EINVAL;
+       u8 link_id;
 
        lockdep_assert_wiphy(hw->wiphy);
 
-       ar = ath12k_get_ar_by_vif(hw, vif);
-       if (!ar)
-               return -EINVAL;
-
-       ar = ath12k_ah_to_ar(ah, 0);
-       arvif = &ahvif->deflink;
+       if (WARN_ON(!links_map))
+               return ret;
 
-       ret = ath12k_mac_ampdu_action(arvif, params);
-       if (ret)
-               ath12k_warn(ar->ab, "pdev idx %d unable to perform ampdu action %d ret %d\n",
-                           ar->pdev_idx, params->action, ret);
+       for_each_set_bit(link_id, &links_map, IEEE80211_MLD_MAX_NUM_LINKS) {
+               ret = ath12k_mac_ampdu_action(hw, vif, params, link_id);
+               if (ret)
+                       return ret;
+       }
 
-       return ret;
+       return 0;
 }
 
 static int ath12k_mac_op_add_chanctx(struct ieee80211_hw *hw,