Commit 5419ef95 authored by Sriram R's avatar Sriram R Committed by Kalle Valo
Browse files

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: default avatarSriram R <quic_srirrama@quicinc.com>
Signed-off-by: default avatarRameshkumar Sundaram <quic_ramess@quicinc.com>
Signed-off-by: default avatarKalle Valo <quic_kvalo@quicinc.com>
Link: https://patch.msgid.link/20241126171139.2350704-5-kvalo@kernel.org
parent 2197feb0
Loading
Loading
Loading
Loading
+28 −8
Original line number Diff line number Diff line
@@ -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");
+4 −2
Original line number Diff line number Diff line
@@ -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,
+44 −32
Original line number Diff line number Diff line
@@ -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",
		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,29 +8337,26 @@ 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);
	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)
		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,
				     struct ieee80211_chanctx_conf *ctx)
{