wifi: ath12k: ath12k_mac_op_ampdu_action(): MLO support

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
This commit is contained in:
Sriram R
2024-11-26 19:11:33 +02:00
committed by Kalle Valo
parent 2197feb024
commit 5419ef950d
3 changed files with 76 additions and 42 deletions

View File

@@ -1065,15 +1065,25 @@ int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_
}
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");

View 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,

View 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;
if (WARN_ON(!links_map))
return ret;
ar = ath12k_ah_to_ar(ah, 0);
arvif = &ahvif->deflink;
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;
}
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);
return ret;
return 0;
}
static int ath12k_mac_op_add_chanctx(struct ieee80211_hw *hw,