Commit ec1d9b79 authored by Muna Sinada's avatar Muna Sinada Committed by Jeff Johnson
Browse files

wifi: ath12k: add EHT rate handling to existing set rate functions



Add EHT rate handling to the existing rate functions that validate,
prepare and set rates.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1

Co-developed-by: default avatarAloka Dixit <aloka.dixit@oss.qualcomm.com>
Signed-off-by: default avatarAloka Dixit <aloka.dixit@oss.qualcomm.com>
Signed-off-by: default avatarMuna Sinada <muna.sinada@oss.qualcomm.com>
Reviewed-by: default avatarVasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Link: https://patch.msgid.link/20251024001928.257356-3-muna.sinada@oss.qualcomm.com


Signed-off-by: default avatarJeff Johnson <jeff.johnson@oss.qualcomm.com>
parent 770bff79
Loading
Loading
Loading
Loading
+173 −42
Original line number Diff line number Diff line
@@ -533,6 +533,18 @@ ath12k_mac_max_he_nss(const u16 he_mcs_mask[NL80211_HE_NSS_MAX])
	return 1;
}

static u32
ath12k_mac_max_eht_nss(const u16 eht_mcs_mask[NL80211_EHT_NSS_MAX])
{
	int nss;

	for (nss = NL80211_EHT_NSS_MAX - 1; nss >= 0; nss--)
		if (eht_mcs_mask[nss])
			return nss + 1;

	return 1;
}

static u8 ath12k_parse_mpdudensity(u8 mpdudensity)
{
/*  From IEEE Std 802.11-2020 defined values for "Minimum MPDU Start Spacing":
@@ -3102,37 +3114,50 @@ static void ath12k_peer_assoc_h_phymode(struct ath12k *ar,
	WARN_ON(phymode == MODE_UNKNOWN);
}

#define ATH12K_EHT_MCS_7_ENABLED	0x00FF
#define ATH12K_EHT_MCS_9_ENABLED	0x0300
#define ATH12K_EHT_MCS_11_ENABLED	0x0C00
#define ATH12K_EHT_MCS_13_ENABLED	0x3000

static void ath12k_mac_set_eht_mcs(u8 rx_tx_mcs7, u8 rx_tx_mcs9,
				   u8 rx_tx_mcs11, u8 rx_tx_mcs13,
				   u32 *rx_mcs, u32 *tx_mcs)
{
	*rx_mcs = 0;
	u32p_replace_bits(rx_mcs,
			  u8_get_bits(rx_tx_mcs7, IEEE80211_EHT_MCS_NSS_RX),
			  WMI_EHT_MCS_NSS_0_7);
	u32p_replace_bits(rx_mcs,
			  u8_get_bits(rx_tx_mcs9, IEEE80211_EHT_MCS_NSS_RX),
			  WMI_EHT_MCS_NSS_8_9);
	u32p_replace_bits(rx_mcs,
			  u8_get_bits(rx_tx_mcs11, IEEE80211_EHT_MCS_NSS_RX),
			  WMI_EHT_MCS_NSS_10_11);
	u32p_replace_bits(rx_mcs,
			  u8_get_bits(rx_tx_mcs13, IEEE80211_EHT_MCS_NSS_RX),
			  WMI_EHT_MCS_NSS_12_13);

	*tx_mcs = 0;
	u32p_replace_bits(tx_mcs,
			  u8_get_bits(rx_tx_mcs7, IEEE80211_EHT_MCS_NSS_TX),
			  WMI_EHT_MCS_NSS_0_7);
	u32p_replace_bits(tx_mcs,
			  u8_get_bits(rx_tx_mcs9, IEEE80211_EHT_MCS_NSS_TX),
			  WMI_EHT_MCS_NSS_8_9);
	u32p_replace_bits(tx_mcs,
			  u8_get_bits(rx_tx_mcs11, IEEE80211_EHT_MCS_NSS_TX),
			  WMI_EHT_MCS_NSS_10_11);
	u32p_replace_bits(tx_mcs,
			  u8_get_bits(rx_tx_mcs13, IEEE80211_EHT_MCS_NSS_TX),
			  WMI_EHT_MCS_NSS_12_13);
				   u32 *rx_mcs, u32 *tx_mcs,
				   const u16 eht_mcs_limit[NL80211_EHT_NSS_MAX])
{
	int nss;
	u8 mcs_7 = 0, mcs_9 = 0, mcs_11 = 0, mcs_13 = 0;
	u8 peer_mcs_7, peer_mcs_9, peer_mcs_11, peer_mcs_13;

	for (nss = 0; nss < NL80211_EHT_NSS_MAX; nss++) {
		if (eht_mcs_limit[nss] & ATH12K_EHT_MCS_7_ENABLED)
			mcs_7++;
		if (eht_mcs_limit[nss] & ATH12K_EHT_MCS_9_ENABLED)
			mcs_9++;
		if (eht_mcs_limit[nss] & ATH12K_EHT_MCS_11_ENABLED)
			mcs_11++;
		if (eht_mcs_limit[nss] & ATH12K_EHT_MCS_13_ENABLED)
			mcs_13++;
	}

	peer_mcs_7 = u8_get_bits(rx_tx_mcs7, IEEE80211_EHT_MCS_NSS_RX);
	peer_mcs_9 = u8_get_bits(rx_tx_mcs9, IEEE80211_EHT_MCS_NSS_RX);
	peer_mcs_11 = u8_get_bits(rx_tx_mcs11, IEEE80211_EHT_MCS_NSS_RX);
	peer_mcs_13 = u8_get_bits(rx_tx_mcs13, IEEE80211_EHT_MCS_NSS_RX);

	*rx_mcs = u32_encode_bits(min(peer_mcs_7, mcs_7), WMI_EHT_MCS_NSS_0_7) |
		  u32_encode_bits(min(peer_mcs_9, mcs_9), WMI_EHT_MCS_NSS_8_9) |
		  u32_encode_bits(min(peer_mcs_11, mcs_11), WMI_EHT_MCS_NSS_10_11) |
		  u32_encode_bits(min(peer_mcs_13, mcs_13), WMI_EHT_MCS_NSS_12_13);

	peer_mcs_7 = u8_get_bits(rx_tx_mcs7, IEEE80211_EHT_MCS_NSS_TX);
	peer_mcs_9 = u8_get_bits(rx_tx_mcs9, IEEE80211_EHT_MCS_NSS_TX);
	peer_mcs_11 = u8_get_bits(rx_tx_mcs11, IEEE80211_EHT_MCS_NSS_TX);
	peer_mcs_13 = u8_get_bits(rx_tx_mcs13, IEEE80211_EHT_MCS_NSS_TX);

	*tx_mcs = u32_encode_bits(min(peer_mcs_7, mcs_7), WMI_EHT_MCS_NSS_0_7) |
		  u32_encode_bits(min(peer_mcs_9, mcs_9), WMI_EHT_MCS_NSS_8_9) |
		  u32_encode_bits(min(peer_mcs_11, mcs_11), WMI_EHT_MCS_NSS_10_11) |
		  u32_encode_bits(min(peer_mcs_13, mcs_13), WMI_EHT_MCS_NSS_12_13);
}

static void ath12k_mac_set_eht_ppe_threshold(const u8 *ppe_thres,
@@ -3171,13 +3196,17 @@ static void ath12k_peer_assoc_h_eht(struct ath12k *ar,
				    struct ath12k_wmi_peer_assoc_arg *arg)
{
	struct ieee80211_sta *sta = ath12k_ahsta_to_sta(arsta->ahsta);
	struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif);
	const struct ieee80211_eht_mcs_nss_supp_20mhz_only *bw_20;
	const struct ieee80211_eht_mcs_nss_supp_bw *bw;
	const struct ieee80211_sta_eht_cap *eht_cap;
	const struct ieee80211_sta_he_cap *he_cap;
	struct ieee80211_link_sta *link_sta;
	struct ieee80211_bss_conf *link_conf;
	struct cfg80211_chan_def def;
	enum nl80211_band band;
	u32 *rx_mcs, *tx_mcs;
	u16 *eht_mcs_mask;

	lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);

@@ -3199,6 +3228,12 @@ static void ath12k_peer_assoc_h_eht(struct ath12k *ar,
	if (!he_cap->has_he || !eht_cap->has_eht)
		return;

	if (WARN_ON(ath12k_mac_vif_link_chan(vif, arvif->link_id, &def)))
		return;

	band = def.chan->band;
	eht_mcs_mask = arvif->bitrate_mask.control[band].eht_mcs;

	arg->eht_flag = true;

	if ((eht_cap->eht_cap_elem.phy_cap_info[5] &
@@ -3223,7 +3258,8 @@ static void ath12k_peer_assoc_h_eht(struct ath12k *ar,
				       bw->rx_tx_mcs11_max_nss,
				       bw->rx_tx_mcs13_max_nss,
				       &rx_mcs[WMI_EHTCAP_TXRX_MCS_NSS_IDX_320],
				       &tx_mcs[WMI_EHTCAP_TXRX_MCS_NSS_IDX_320]);
				       &tx_mcs[WMI_EHTCAP_TXRX_MCS_NSS_IDX_320],
				       eht_mcs_mask);
		arg->peer_eht_mcs_count++;
		fallthrough;
	case IEEE80211_STA_RX_BW_160:
@@ -3233,7 +3269,8 @@ static void ath12k_peer_assoc_h_eht(struct ath12k *ar,
				       bw->rx_tx_mcs11_max_nss,
				       bw->rx_tx_mcs13_max_nss,
				       &rx_mcs[WMI_EHTCAP_TXRX_MCS_NSS_IDX_160],
				       &tx_mcs[WMI_EHTCAP_TXRX_MCS_NSS_IDX_160]);
				       &tx_mcs[WMI_EHTCAP_TXRX_MCS_NSS_IDX_160],
				       eht_mcs_mask);
		arg->peer_eht_mcs_count++;
		fallthrough;
	default:
@@ -3249,7 +3286,8 @@ static void ath12k_peer_assoc_h_eht(struct ath12k *ar,
					       bw_20->rx_tx_mcs11_max_nss,
					       bw_20->rx_tx_mcs13_max_nss,
					       &rx_mcs[WMI_EHTCAP_TXRX_MCS_NSS_IDX_80],
					       &tx_mcs[WMI_EHTCAP_TXRX_MCS_NSS_IDX_80]);
					       &tx_mcs[WMI_EHTCAP_TXRX_MCS_NSS_IDX_80],
					       eht_mcs_mask);
		} else {
			bw = &eht_cap->eht_mcs_nss_supp.bw._80;
			ath12k_mac_set_eht_mcs(bw->rx_tx_mcs9_max_nss,
@@ -3257,7 +3295,8 @@ static void ath12k_peer_assoc_h_eht(struct ath12k *ar,
					       bw->rx_tx_mcs11_max_nss,
					       bw->rx_tx_mcs13_max_nss,
					       &rx_mcs[WMI_EHTCAP_TXRX_MCS_NSS_IDX_80],
					       &tx_mcs[WMI_EHTCAP_TXRX_MCS_NSS_IDX_80]);
					       &tx_mcs[WMI_EHTCAP_TXRX_MCS_NSS_IDX_80],
					       eht_mcs_mask);
		}

		arg->peer_eht_mcs_count++;
@@ -3908,6 +3947,8 @@ static void ath12k_mac_init_arvif(struct ath12k_vif *ahvif,
		       sizeof(arvif->bitrate_mask.control[i].vht_mcs));
		memset(arvif->bitrate_mask.control[i].he_mcs, 0xff,
		       sizeof(arvif->bitrate_mask.control[i].he_mcs));
		memset(arvif->bitrate_mask.control[i].eht_mcs, 0xff,
		       sizeof(arvif->bitrate_mask.control[i].eht_mcs));
	}

	/* Handle MLO related assignments */
@@ -5835,6 +5876,20 @@ ath12k_mac_bitrate_mask_num_he_rates(struct ath12k *ar,
	return num_rates;
}

static int
ath12k_mac_bitrate_mask_num_eht_rates(struct ath12k *ar,
				      enum nl80211_band band,
				      const struct cfg80211_bitrate_mask *mask)
{
	int num_rates = 0;
	int i;

	for (i = 0; i < ARRAY_SIZE(mask->control[band].eht_mcs); i++)
		num_rates += hweight16(mask->control[band].eht_mcs[i]);

	return num_rates;
}

static int
ath12k_mac_set_peer_vht_fixed_rate(struct ath12k_link_vif *arvif,
				   struct ath12k_link_sta *arsta,
@@ -11976,6 +12031,9 @@ ath12k_mac_has_single_legacy_rate(struct ath12k *ar,
	if (ath12k_mac_bitrate_mask_num_he_rates(ar, band, mask))
		return false;

	if (ath12k_mac_bitrate_mask_num_eht_rates(ar, band, mask))
		return false;

	return num_rates == 1;
}

@@ -11998,11 +12056,15 @@ ath12k_mac_bitrate_mask_get_single_nss(struct ath12k *ar,
{
	struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
	u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
	const struct ieee80211_sband_iftype_data *data;
	const struct ieee80211_sta_he_cap *he_cap;
	u16 he_mcs_map = 0;
	u16 eht_mcs_map = 0;
	u8 ht_nss_mask = 0;
	u8 vht_nss_mask = 0;
	u8 he_nss_mask = 0;
	u8 eht_nss_mask = 0;
	u8 mcs_nss_len;
	int i;

	/* No need to consider legacy here. Basic rates are always present
@@ -12046,7 +12108,60 @@ ath12k_mac_bitrate_mask_get_single_nss(struct ath12k *ar,
			return false;
	}

	if (ht_nss_mask != vht_nss_mask || ht_nss_mask != he_nss_mask)
	data = ieee80211_get_sband_iftype_data(sband, vif->type);

	mcs_nss_len = ieee80211_eht_mcs_nss_size(&data->he_cap.he_cap_elem,
						 &data->eht_cap.eht_cap_elem,
						 false);
	if (mcs_nss_len == 4) {
		/* 20 MHz only STA case */
		const struct ieee80211_eht_mcs_nss_supp_20mhz_only *eht_mcs_nss =
			&data->eht_cap.eht_mcs_nss_supp.only_20mhz;
		if (eht_mcs_nss->rx_tx_mcs13_max_nss)
			eht_mcs_map = 0x1fff;
		else if (eht_mcs_nss->rx_tx_mcs11_max_nss)
			eht_mcs_map = 0x07ff;
		else if (eht_mcs_nss->rx_tx_mcs9_max_nss)
			eht_mcs_map = 0x01ff;
		else
			eht_mcs_map = 0x007f;
	} else {
		const struct ieee80211_eht_mcs_nss_supp_bw *eht_mcs_nss;

		switch (mcs_nss_len) {
		case 9:
			eht_mcs_nss = &data->eht_cap.eht_mcs_nss_supp.bw._320;
			break;
		case 6:
			eht_mcs_nss = &data->eht_cap.eht_mcs_nss_supp.bw._160;
			break;
		case 3:
			eht_mcs_nss = &data->eht_cap.eht_mcs_nss_supp.bw._80;
			break;
		default:
			return false;
		}

		if (eht_mcs_nss->rx_tx_mcs13_max_nss)
			eht_mcs_map = 0x1fff;
		else if (eht_mcs_nss->rx_tx_mcs11_max_nss)
			eht_mcs_map = 0x7ff;
		else
			eht_mcs_map = 0x1ff;
	}

	for (i = 0; i < ARRAY_SIZE(mask->control[band].eht_mcs); i++) {
		if (mask->control[band].eht_mcs[i] == 0)
			continue;

		if (mask->control[band].eht_mcs[i] < eht_mcs_map)
			eht_nss_mask |= BIT(i);
		else
			return false;
	}

	if (ht_nss_mask != vht_nss_mask || ht_nss_mask != he_nss_mask ||
	    ht_nss_mask != eht_nss_mask)
		return false;

	if (ht_nss_mask == 0)
@@ -12198,11 +12313,12 @@ static u32 ath12k_mac_nlgi_to_wmigi(enum nl80211_txrate_gi gi)

static int ath12k_mac_set_rate_params(struct ath12k_link_vif *arvif,
				      u32 rate, u8 nss, u8 sgi, u8 ldpc,
				      u8 he_gi, u8 he_ltf, bool he_fixed_rate)
				      u8 he_gi, u8 he_ltf, bool he_fixed_rate,
				      bool eht_fixed_rate)
{
	struct ieee80211_bss_conf *link_conf;
	struct ath12k *ar = arvif->ar;
	bool he_support, gi_ltf_set = false;
	bool he_support, eht_support, gi_ltf_set = false;
	u32 vdev_param;
	u32 param_value;
	int ret;
@@ -12214,6 +12330,7 @@ static int ath12k_mac_set_rate_params(struct ath12k_link_vif *arvif,
		return -EINVAL;

	he_support = link_conf->he_support;
	eht_support = link_conf->eht_support;

	ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
		   "mac set rate params vdev %i rate 0x%02x nss 0x%02x sgi 0x%02x ldpc 0x%02x\n",
@@ -12223,7 +12340,10 @@ static int ath12k_mac_set_rate_params(struct ath12k_link_vif *arvif,
		   "he_gi 0x%02x he_ltf 0x%02x he_fixed_rate %d\n", he_gi,
		   he_ltf, he_fixed_rate);

	if (!he_support) {
	ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "eht_fixed_rate %d\n",
		   eht_fixed_rate);

	if (!he_support && !eht_support) {
		vdev_param = WMI_VDEV_PARAM_FIXED_RATE;
		ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
						    vdev_param, rate);
@@ -12381,15 +12501,16 @@ ath12k_mac_validate_fixed_rate_settings(struct ath12k *ar, enum nl80211_band ban
					const struct cfg80211_bitrate_mask *mask,
					unsigned int link_id)
{
	bool he_fixed_rate = false, vht_fixed_rate = false;
	const u16 *vht_mcs_mask, *he_mcs_mask;
	bool eht_fixed_rate = false, he_fixed_rate = false, vht_fixed_rate = false;
	const u16 *vht_mcs_mask, *he_mcs_mask, *eht_mcs_mask;
	struct ieee80211_link_sta *link_sta;
	struct ath12k_peer *peer, *tmp;
	u8 vht_nss, he_nss;
	u8 vht_nss, he_nss, eht_nss;
	int ret = true;

	vht_mcs_mask = mask->control[band].vht_mcs;
	he_mcs_mask = mask->control[band].he_mcs;
	eht_mcs_mask = mask->control[band].eht_mcs;

	if (ath12k_mac_bitrate_mask_num_vht_rates(ar, band, mask) == 1)
		vht_fixed_rate = true;
@@ -12397,11 +12518,15 @@ ath12k_mac_validate_fixed_rate_settings(struct ath12k *ar, enum nl80211_band ban
	if (ath12k_mac_bitrate_mask_num_he_rates(ar, band, mask) == 1)
		he_fixed_rate = true;

	if (!vht_fixed_rate && !he_fixed_rate)
	if (ath12k_mac_bitrate_mask_num_eht_rates(ar, band, mask) == 1)
		eht_fixed_rate = true;

	if (!vht_fixed_rate && !he_fixed_rate && !eht_fixed_rate)
		return true;

	vht_nss = ath12k_mac_max_vht_nss(vht_mcs_mask);
	he_nss =  ath12k_mac_max_he_nss(he_mcs_mask);
	eht_nss = ath12k_mac_max_eht_nss(eht_mcs_mask);

	rcu_read_lock();
	spin_lock_bh(&ar->ab->base_lock);
@@ -12423,6 +12548,11 @@ ath12k_mac_validate_fixed_rate_settings(struct ath12k *ar, enum nl80211_band ban
				ret = false;
				goto exit;
			}
			if (eht_fixed_rate && (!link_sta->eht_cap.has_eht ||
					       link_sta->rx_nss < eht_nss)) {
				ret = false;
				goto exit;
			}
		}
	}
exit:
@@ -12454,6 +12584,7 @@ ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
	int ret;
	int num_rates;
	bool he_fixed_rate = false;
	bool eht_fixed_rate = false;

	lockdep_assert_wiphy(hw->wiphy);

@@ -12578,7 +12709,7 @@ ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
	}

	ret = ath12k_mac_set_rate_params(arvif, rate, nss, sgi, ldpc, he_gi,
					 he_ltf, he_fixed_rate);
					 he_ltf, he_fixed_rate, eht_fixed_rate);
	if (ret) {
		ath12k_warn(ar->ab, "failed to set rate params on vdev %i: %d\n",
			    arvif->vdev_id, ret);