wifi: ath12k: prepare EHT peer assoc parameters
Add new parameters and prepare the association data for an EHT peer. MCS data uses the format described in IEEE P802.11be/D2.0, May 2022, 9.4.2.313.4, convert it into the format expected by the firmware. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com> Signed-off-by: Pradeep Kumar Chitrapu <quic_pradeepc@quicinc.com> Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com> Link: https://lore.kernel.org/r/20230725224034.14045-7-quic_alokad@quicinc.com
This commit is contained in:
@@ -2067,6 +2067,149 @@ static void ath12k_peer_assoc_h_phymode(struct ath12k *ar,
|
||||
WARN_ON(phymode == MODE_UNKNOWN);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void ath12k_mac_set_eht_ppe_threshold(const u8 *ppe_thres,
|
||||
struct ath12k_wmi_ppe_threshold_arg *ppet)
|
||||
{
|
||||
u32 bit_pos = IEEE80211_EHT_PPE_THRES_INFO_HEADER_SIZE, val;
|
||||
u8 nss, ru, i;
|
||||
u8 ppet_bit_len_per_ru = IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE * 2;
|
||||
|
||||
ppet->numss_m1 = u8_get_bits(ppe_thres[0], IEEE80211_EHT_PPE_THRES_NSS_MASK);
|
||||
ppet->ru_bit_mask = u16_get_bits(get_unaligned_le16(ppe_thres),
|
||||
IEEE80211_EHT_PPE_THRES_RU_INDEX_BITMASK_MASK);
|
||||
|
||||
for (nss = 0; nss <= ppet->numss_m1; nss++) {
|
||||
for (ru = 0;
|
||||
ru < hweight16(IEEE80211_EHT_PPE_THRES_RU_INDEX_BITMASK_MASK);
|
||||
ru++) {
|
||||
if ((ppet->ru_bit_mask & BIT(ru)) == 0)
|
||||
continue;
|
||||
|
||||
val = 0;
|
||||
for (i = 0; i < ppet_bit_len_per_ru; i++) {
|
||||
val |= (((ppe_thres[bit_pos / 8] >>
|
||||
(bit_pos % 8)) & 0x1) << i);
|
||||
bit_pos++;
|
||||
}
|
||||
ppet->ppet16_ppet8_ru3_ru0[nss] |=
|
||||
(val << (ru * ppet_bit_len_per_ru));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ath12k_peer_assoc_h_eht(struct ath12k *ar,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ath12k_wmi_peer_assoc_arg *arg)
|
||||
{
|
||||
const struct ieee80211_sta_eht_cap *eht_cap = &sta->deflink.eht_cap;
|
||||
const struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap;
|
||||
const struct ieee80211_eht_mcs_nss_supp_20mhz_only *bw_20;
|
||||
const struct ieee80211_eht_mcs_nss_supp_bw *bw;
|
||||
u32 *rx_mcs, *tx_mcs;
|
||||
|
||||
if (!sta->deflink.he_cap.has_he || !eht_cap->has_eht)
|
||||
return;
|
||||
|
||||
arg->eht_flag = true;
|
||||
|
||||
if ((eht_cap->eht_cap_elem.phy_cap_info[5] &
|
||||
IEEE80211_EHT_PHY_CAP5_PPE_THRESHOLD_PRESENT) &&
|
||||
eht_cap->eht_ppe_thres[0] != 0)
|
||||
ath12k_mac_set_eht_ppe_threshold(eht_cap->eht_ppe_thres,
|
||||
&arg->peer_eht_ppet);
|
||||
|
||||
memcpy(arg->peer_eht_cap_mac, eht_cap->eht_cap_elem.mac_cap_info,
|
||||
sizeof(eht_cap->eht_cap_elem.mac_cap_info));
|
||||
memcpy(arg->peer_eht_cap_phy, eht_cap->eht_cap_elem.phy_cap_info,
|
||||
sizeof(eht_cap->eht_cap_elem.phy_cap_info));
|
||||
|
||||
rx_mcs = arg->peer_eht_rx_mcs_set;
|
||||
tx_mcs = arg->peer_eht_tx_mcs_set;
|
||||
|
||||
switch (sta->deflink.bandwidth) {
|
||||
case IEEE80211_STA_RX_BW_320:
|
||||
bw = &eht_cap->eht_mcs_nss_supp.bw._320;
|
||||
ath12k_mac_set_eht_mcs(bw->rx_tx_mcs9_max_nss,
|
||||
bw->rx_tx_mcs9_max_nss,
|
||||
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]);
|
||||
arg->peer_eht_mcs_count++;
|
||||
fallthrough;
|
||||
case IEEE80211_STA_RX_BW_160:
|
||||
bw = &eht_cap->eht_mcs_nss_supp.bw._160;
|
||||
ath12k_mac_set_eht_mcs(bw->rx_tx_mcs9_max_nss,
|
||||
bw->rx_tx_mcs9_max_nss,
|
||||
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]);
|
||||
arg->peer_eht_mcs_count++;
|
||||
fallthrough;
|
||||
default:
|
||||
if ((he_cap->he_cap_elem.phy_cap_info[0] &
|
||||
(IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G |
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)) == 0) {
|
||||
bw_20 = &eht_cap->eht_mcs_nss_supp.only_20mhz;
|
||||
|
||||
ath12k_mac_set_eht_mcs(bw_20->rx_tx_mcs7_max_nss,
|
||||
bw_20->rx_tx_mcs9_max_nss,
|
||||
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]);
|
||||
} else {
|
||||
bw = &eht_cap->eht_mcs_nss_supp.bw._80;
|
||||
ath12k_mac_set_eht_mcs(bw->rx_tx_mcs9_max_nss,
|
||||
bw->rx_tx_mcs9_max_nss,
|
||||
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]);
|
||||
}
|
||||
|
||||
arg->peer_eht_mcs_count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void ath12k_peer_assoc_prepare(struct ath12k *ar,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
@@ -2086,6 +2229,7 @@ static void ath12k_peer_assoc_prepare(struct ath12k *ar,
|
||||
ath12k_peer_assoc_h_ht(ar, vif, sta, arg);
|
||||
ath12k_peer_assoc_h_vht(ar, vif, sta, arg);
|
||||
ath12k_peer_assoc_h_he(ar, vif, sta, arg);
|
||||
ath12k_peer_assoc_h_eht(ar, vif, sta, arg);
|
||||
ath12k_peer_assoc_h_qos(ar, vif, sta, arg);
|
||||
ath12k_peer_assoc_h_phymode(ar, vif, sta, arg);
|
||||
ath12k_peer_assoc_h_smps(sta, arg);
|
||||
|
@@ -2583,6 +2583,7 @@ struct ath12k_wmi_soc_hal_reg_caps_params {
|
||||
|
||||
#define WMI_MAX_EHTCAP_MAC_SIZE 2
|
||||
#define WMI_MAX_EHTCAP_PHY_SIZE 3
|
||||
#define WMI_MAX_EHTCAP_RATE_SET 3
|
||||
|
||||
/* Used for EHT MCS-NSS array. Data at each array index follows the format given
|
||||
* in IEEE P802.11be/D2.0, May 20229.4.2.313.4.
|
||||
@@ -2596,6 +2597,15 @@ struct ath12k_wmi_soc_hal_reg_caps_params {
|
||||
#define WMI_MAX_EHT_SUPP_MCS_2G_SIZE 2
|
||||
#define WMI_MAX_EHT_SUPP_MCS_5G_SIZE 4
|
||||
|
||||
#define WMI_EHTCAP_TXRX_MCS_NSS_IDX_80 0
|
||||
#define WMI_EHTCAP_TXRX_MCS_NSS_IDX_160 1
|
||||
#define WMI_EHTCAP_TXRX_MCS_NSS_IDX_320 2
|
||||
|
||||
#define WMI_EHT_MCS_NSS_0_7 GENMASK(3, 0)
|
||||
#define WMI_EHT_MCS_NSS_8_9 GENMASK(7, 4)
|
||||
#define WMI_EHT_MCS_NSS_10_11 GENMASK(11, 8)
|
||||
#define WMI_EHT_MCS_NSS_12_13 GENMASK(15, 12)
|
||||
|
||||
struct ath12k_wmi_caps_ext_params {
|
||||
__le32 hw_mode_id;
|
||||
union {
|
||||
@@ -3564,6 +3574,13 @@ struct ath12k_wmi_peer_assoc_arg {
|
||||
bool twt_responder;
|
||||
bool twt_requester;
|
||||
struct ath12k_wmi_ppe_threshold_arg peer_ppet;
|
||||
bool eht_flag;
|
||||
u32 peer_eht_cap_mac[WMI_MAX_EHTCAP_MAC_SIZE];
|
||||
u32 peer_eht_cap_phy[WMI_MAX_EHTCAP_PHY_SIZE];
|
||||
u32 peer_eht_mcs_count;
|
||||
u32 peer_eht_rx_mcs_set[WMI_MAX_EHTCAP_RATE_SET];
|
||||
u32 peer_eht_tx_mcs_set[WMI_MAX_EHTCAP_RATE_SET];
|
||||
struct ath12k_wmi_ppe_threshold_arg peer_eht_ppet;
|
||||
};
|
||||
|
||||
struct wmi_peer_assoc_complete_cmd {
|
||||
|
Reference in New Issue
Block a user