Add driver support for EHT bring-up, association and
preamble puncturing.
v4: Modified patch 3 to support WCN7850.
v3: Modified patches 6 and 9 to fix some issues,
changelog included in the respective patches.
v2: This version modifies only few commit descriptions,
changelog included in the respective patches.
Following list gives the details for each patch.
1-4: Propagation of EHT capabilities from target to userspace.
5: Addition of EHT phy modes.
6-9: EHT related additions in peer association.
10: Process the new WMI service ready ext2 event.
11: Preamble puncturing support.
Aloka Dixit (9):
wifi: ath12k: rename HE capabilities setup/copy functions
wifi: ath12k: move HE capabilities processing to a new function
wifi: ath12k: WMI support to process EHT capabilities
wifi: ath12k: propagate EHT capabilities to userspace
wifi: ath12k: prepare EHT peer assoc parameters
wifi: ath12k: add WMI support for EHT peer
wifi: ath12k: peer assoc for 320 MHz
wifi: ath12k: parse WMI service ready ext2 event
wifi: ath12k: configure puncturing bitmap
Muna Sinada (1):
wifi: ath12k: add EHT PHY modes
Pradeep Kumar Chitrapu (1):
wifi: ath12k: add MLO header in peer association
drivers/net/wireless/ath/ath12k/core.h | 17 +
drivers/net/wireless/ath/ath12k/mac.c | 556 ++++++++++++++++++++-----
drivers/net/wireless/ath/ath12k/mac.h | 2 +-
drivers/net/wireless/ath/ath12k/wmi.c | 252 ++++++++++-
drivers/net/wireless/ath/ath12k/wmi.h | 116 +++++-
5 files changed, 833 insertions(+), 110 deletions(-)
base-commit: a4756ac34a7002861c9bdf8cf45aec53a77fb78d
--
2.39.0
Add required peer association definitions and processing if the
bandwidth is 320 MHz.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Signed-off-by: Aloka Dixit <[email protected]>
Signed-off-by: Pradeep Kumar Chitrapu<[email protected]>
---
v4: No change from v3.
v3: No change from v2.
v2: No change from v1.
drivers/net/wireless/ath/ath12k/wmi.c | 2 ++
drivers/net/wireless/ath/ath12k/wmi.h | 2 ++
2 files changed, 4 insertions(+)
diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index 358aac5802bc..7debd2461e1a 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -1816,6 +1816,8 @@ static void ath12k_wmi_copy_peer_flags(struct wmi_peer_assoc_complete_cmd *cmd,
cmd->peer_flags |= cpu_to_le32(WMI_PEER_80MHZ);
if (arg->bw_160)
cmd->peer_flags |= cpu_to_le32(WMI_PEER_160MHZ);
+ if (arg->bw_320)
+ cmd->peer_flags |= cpu_to_le32(WMI_PEER_EXT_320MHZ);
/* Typically if STBC is enabled for VHT it should be enabled
* for HT as well
diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h
index f0877dbfc5fd..9d0f74122bc6 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.h
+++ b/drivers/net/wireless/ath/ath12k/wmi.h
@@ -1169,6 +1169,7 @@ enum wmi_tlv_peer_flags {
enum wmi_tlv_peer_flags_ext {
WMI_PEER_EXT_EHT = 0x00000001,
+ WMI_PEER_EXT_320MHZ = 0x00000002,
};
/** Enum list of TLV Tags for each parameter structure type. */
@@ -3553,6 +3554,7 @@ struct ath12k_wmi_peer_assoc_arg {
bool bw_40;
bool bw_80;
bool bw_160;
+ bool bw_320;
bool stbc_flag;
bool ldpc_flag;
bool static_mimops_flag;
--
2.39.0
Add WMI support to process the EHT capabilities passed by
the firmware. Add required EHT specific definitions in
structures ath12k_band_cap and ath12k_wmi_svc_rdy_ext_parse.
For single_pdev chip such as WCN7850, only one pdev is created
and only one hardware is registered to mac80211. This one pdev
manages both 2.4 GHz radio and 5 GHz/6 GHz radio.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
Signed-off-by: Aloka Dixit <[email protected]>
Co-developed-by: Pradeep Kumar Chitrapu <[email protected]>
Signed-off-by: Pradeep Kumar Chitrapu <[email protected]>
Co-developed-by: Wen Gong <[email protected]>
Signed-off-by: Wen Gong <[email protected]>
---
v4: Add support for WCN7850.
v3: No change from v2.
v2: Changed 'target' to 'firmware' in the description.
drivers/net/wireless/ath/ath12k/core.h | 16 +++
drivers/net/wireless/ath/ath12k/wmi.c | 147 +++++++++++++++++++++++++
drivers/net/wireless/ath/ath12k/wmi.h | 38 +++++++
3 files changed, 201 insertions(+)
diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h
index 2f93296db792..df762cabacc2 100644
--- a/drivers/net/wireless/ath/ath12k/core.h
+++ b/drivers/net/wireless/ath/ath12k/core.h
@@ -580,6 +580,14 @@ struct ath12k_band_cap {
u32 he_cap_phy_info[PSOC_HOST_MAX_PHY_SIZE];
struct ath12k_wmi_ppe_threshold_arg he_ppet;
u16 he_6ghz_capa;
+ u32 eht_cap_mac_info[WMI_MAX_EHTCAP_MAC_SIZE];
+ u32 eht_cap_phy_info[WMI_MAX_EHTCAP_PHY_SIZE];
+ u32 eht_mcs_20_only;
+ u32 eht_mcs_80;
+ u32 eht_mcs_160;
+ u32 eht_mcs_320;
+ struct ath12k_wmi_ppe_threshold_arg eht_ppet;
+ u32 eht_cap_info_internal;
};
struct ath12k_pdev_cap {
@@ -638,6 +646,12 @@ struct ath12k_soc_dp_stats {
struct ath12k_soc_dp_tx_err_stats tx_err;
};
+struct ath12k_fw_pdev {
+ u32 pdev_id;
+ u32 phy_id;
+ u32 supported_bands;
+};
+
/* Master structure to hold the hw data which may be used in core module */
struct ath12k_base {
enum ath12k_hw_rev hw_rev;
@@ -670,6 +684,8 @@ struct ath12k_base {
/* Protects data like peers */
spinlock_t base_lock;
struct ath12k_pdev pdevs[MAX_RADIOS];
+ struct ath12k_fw_pdev fw_pdev[MAX_RADIOS];
+ u8 fw_pdev_count;
struct ath12k_pdev __rcu *pdevs_active[MAX_RADIOS];
struct ath12k_wmi_hal_reg_capabilities_ext_arg hal_reg_cap[MAX_RADIOS];
unsigned long long free_vdev_map;
diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index 6512267ae4ca..7b82e7240594 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -65,6 +65,8 @@ struct ath12k_wmi_svc_rdy_ext_parse {
struct ath12k_wmi_svc_rdy_ext2_parse {
struct ath12k_wmi_dma_ring_caps_parse dma_caps_parse;
bool dma_ring_cap_done;
+ bool spectral_bin_scaling_done;
+ bool mac_phy_caps_ext_done;
};
struct ath12k_wmi_rdy_parse {
@@ -445,8 +447,10 @@ ath12k_pull_mac_phy_cap_svc_ready_ext(struct ath12k_wmi_pdev *wmi_handle,
const struct ath12k_wmi_soc_mac_phy_hw_mode_caps_params *hw_caps = svc->hw_caps;
const struct ath12k_wmi_hw_mode_cap_params *wmi_hw_mode_caps = svc->hw_mode_caps;
const struct ath12k_wmi_mac_phy_caps_params *wmi_mac_phy_caps = svc->mac_phy_caps;
+ struct ath12k_base *ab = wmi_handle->wmi_ab->ab;
struct ath12k_band_cap *cap_band;
struct ath12k_pdev_cap *pdev_cap = &pdev->cap;
+ struct ath12k_fw_pdev *fw_pdev;
u32 phy_map;
u32 hw_idx, phy_idx = 0;
int i;
@@ -475,6 +479,12 @@ ath12k_pull_mac_phy_cap_svc_ready_ext(struct ath12k_wmi_pdev *wmi_handle,
pdev_cap->supported_bands |= le32_to_cpu(mac_caps->supported_bands);
pdev_cap->ampdu_density = le32_to_cpu(mac_caps->ampdu_density);
+ fw_pdev = &ab->fw_pdev[ab->fw_pdev_count];
+ fw_pdev->supported_bands = le32_to_cpu(mac_caps->supported_bands);
+ fw_pdev->pdev_id = le32_to_cpu(mac_caps->pdev_id);
+ fw_pdev->phy_id = le32_to_cpu(mac_caps->phy_id);
+ ab->fw_pdev_count++;
+
/* Take non-zero tx/rx chainmask. If tx/rx chainmask differs from
* band to band for a single radio, need to see how this should be
* handled.
@@ -3811,6 +3821,7 @@ static int ath12k_wmi_ext_soc_hal_reg_caps_parse(struct ath12k_base *soc,
soc->num_radios = 0;
phy_id_map = le32_to_cpu(svc_rdy_ext->pref_hw_mode_caps.phy_id_map);
+ soc->fw_pdev_count = 0;
while (phy_id_map && soc->num_radios < MAX_RADIOS) {
ret = ath12k_pull_mac_phy_cap_svc_ready_ext(wmi_handle,
@@ -4038,6 +4049,126 @@ static int ath12k_service_ready_ext_event(struct ath12k_base *ab,
return ret;
}
+static void ath12k_wmi_eht_caps_parse(struct ath12k_pdev *pdev, u32 band,
+ __le32 cap_mac_info[],
+ __le32 cap_phy_info[],
+ __le32 supp_mcs[],
+ struct ath12k_wmi_ppe_threshold_params *ppet,
+ __le32 cap_info_internal)
+{
+ struct ath12k_band_cap *cap_band = &pdev->cap.band[band];
+ u8 i;
+
+ for (i = 0; i < WMI_MAX_EHTCAP_MAC_SIZE; i++)
+ cap_band->eht_cap_mac_info[i] = le32_to_cpu(cap_mac_info[i]);
+
+ for (i = 0; i < WMI_MAX_EHTCAP_PHY_SIZE; i++)
+ cap_band->eht_cap_phy_info[i] = le32_to_cpu(cap_phy_info[i]);
+
+ cap_band->eht_mcs_20_only = le32_to_cpu(supp_mcs[0]);
+ cap_band->eht_mcs_80 = le32_to_cpu(supp_mcs[1]);
+ if (band != NL80211_BAND_2GHZ) {
+ cap_band->eht_mcs_160 = le32_to_cpu(supp_mcs[2]);
+ cap_band->eht_mcs_320 = le32_to_cpu(supp_mcs[3]);
+ }
+
+ cap_band->eht_ppet.numss_m1 = le32_to_cpu(ppet->numss_m1);
+ cap_band->eht_ppet.ru_bit_mask = le32_to_cpu(ppet->ru_info);
+ for (i = 0; i < WMI_MAX_NUM_SS; i++)
+ cap_band->eht_ppet.ppet16_ppet8_ru3_ru0[i] =
+ le32_to_cpu(ppet->ppet16_ppet8_ru3_ru0[i]);
+
+ cap_band->eht_cap_info_internal = le32_to_cpu(cap_info_internal);
+}
+
+static int
+ath12k_wmi_tlv_mac_phy_caps_ext_parse(struct ath12k_base *ab,
+ struct ath12k_wmi_mac_phy_caps_ext_params *caps,
+ struct ath12k_pdev *pdev)
+{
+ u32 bands;
+ int i;
+
+ if (ab->hw_params->single_pdev_only) {
+ for (i = 0; i < ab->fw_pdev_count; i++) {
+ struct ath12k_fw_pdev *fw_pdev = &ab->fw_pdev[i];
+
+ if (fw_pdev->pdev_id == le32_to_cpu(caps->pdev_id) &&
+ fw_pdev->phy_id == le32_to_cpu(caps->phy_id)) {
+ bands = fw_pdev->supported_bands;
+ break;
+ }
+ }
+
+ if (i == ab->fw_pdev_count)
+ return -EINVAL;
+ } else {
+ bands = pdev->cap.supported_bands;
+ }
+
+ if (bands & WMI_HOST_WLAN_2G_CAP) {
+ ath12k_wmi_eht_caps_parse(pdev, NL80211_BAND_2GHZ,
+ caps->eht_cap_mac_info_2ghz,
+ caps->eht_cap_phy_info_2ghz,
+ caps->eht_supp_mcs_ext_2ghz,
+ &caps->eht_ppet_2ghz,
+ caps->eht_cap_info_internal);
+ }
+
+ if (bands & WMI_HOST_WLAN_5G_CAP) {
+ ath12k_wmi_eht_caps_parse(pdev, NL80211_BAND_5GHZ,
+ caps->eht_cap_mac_info_5ghz,
+ caps->eht_cap_phy_info_5ghz,
+ caps->eht_supp_mcs_ext_5ghz,
+ &caps->eht_ppet_5ghz,
+ caps->eht_cap_info_internal);
+
+ ath12k_wmi_eht_caps_parse(pdev, NL80211_BAND_6GHZ,
+ caps->eht_cap_mac_info_5ghz,
+ caps->eht_cap_phy_info_5ghz,
+ caps->eht_supp_mcs_ext_5ghz,
+ &caps->eht_ppet_5ghz,
+ caps->eht_cap_info_internal);
+ }
+
+ return 0;
+}
+
+static int ath12k_wmi_tlv_mac_phy_caps_ext(struct ath12k_base *ab, u16 tag,
+ u16 len, const void *ptr,
+ void *data)
+{
+ struct ath12k_wmi_mac_phy_caps_ext_params *caps =
+ (struct ath12k_wmi_mac_phy_caps_ext_params *)ptr;
+ int i = 0, ret;
+
+ if (tag != WMI_TAG_MAC_PHY_CAPABILITIES_EXT)
+ return -EPROTO;
+
+ if (ab->hw_params->single_pdev_only) {
+ if (ab->wmi_ab.preferred_hw_mode != le32_to_cpu(caps->hw_mode_id))
+ return 0;
+ } else {
+ for (i = 0; i < ab->num_radios; i++) {
+ if (ab->pdevs[i].pdev_id == le32_to_cpu(caps->pdev_id))
+ break;
+ }
+
+ if (i == ab->num_radios)
+ return -EINVAL;
+ }
+
+ ret = ath12k_wmi_tlv_mac_phy_caps_ext_parse(ab, caps, &ab->pdevs[i]);
+ if (ret) {
+ ath12k_warn(ab,
+ "failed to extract mac phy caps ext, pdev_id:%d\n",
+ ab->pdevs[i].pdev_id);
+ return ret;
+ }
+
+ return 0;
+}
+
static int ath12k_wmi_svc_rdy_ext2_parse(struct ath12k_base *ab,
u16 tag, u16 len,
const void *ptr, void *data)
@@ -4054,6 +4185,22 @@ static int ath12k_wmi_svc_rdy_ext2_parse(struct ath12k_base *ab,
return ret;
parse->dma_ring_cap_done = true;
+ } else if (!parse->spectral_bin_scaling_done) {
+ /* TODO: This is a place-holder as WMI tag for
+ * spectral scaling is before
+ * WMI_TAG_MAC_PHY_CAPABILITIES_EXT
+ */
+ parse->spectral_bin_scaling_done = true;
+ } else if (!parse->mac_phy_caps_ext_done) {
+ ret = ath12k_wmi_tlv_iter(ab, ptr, len,
+ ath12k_wmi_tlv_mac_phy_caps_ext,
+ parse);
+ if (ret) {
+ ath12k_warn(ab, "failed to parse tlv %d\n", ret);
+ return ret;
+ }
+
+ parse->mac_phy_caps_ext_done = true;
}
break;
default:
diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h
index d89c12bfb009..b722eab281c3 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.h
+++ b/drivers/net/wireless/ath/ath12k/wmi.h
@@ -2581,6 +2581,44 @@ struct ath12k_wmi_soc_hal_reg_caps_params {
__le32 num_phy;
} __packed;
+#define WMI_MAX_EHTCAP_MAC_SIZE 2
+#define WMI_MAX_EHTCAP_PHY_SIZE 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.
+ *
+ * Index interpretation:
+ * 0 - 20 MHz only sta, all 4 bytes valid
+ * 1 - index for bandwidths <= 80 MHz except 20 MHz-only, first 3 bytes valid
+ * 2 - index for 160 MHz, first 3 bytes valid
+ * 3 - index for 320 MHz, first 3 bytes valid
+ */
+#define WMI_MAX_EHT_SUPP_MCS_2G_SIZE 2
+#define WMI_MAX_EHT_SUPP_MCS_5G_SIZE 4
+
+struct ath12k_wmi_mac_phy_caps_ext_params {
+ __le32 hw_mode_id;
+ union {
+ struct {
+ __le16 pdev_id;
+ __le16 hw_link_id;
+ } __packed ath12k_wmi_pdev_to_link_map;
+ __le32 pdev_id;
+ };
+ __le32 phy_id;
+ __le32 wireless_modes_ext;
+ __le32 eht_cap_mac_info_2ghz[WMI_MAX_EHTCAP_MAC_SIZE];
+ __le32 eht_cap_mac_info_5ghz[WMI_MAX_EHTCAP_MAC_SIZE];
+ __le32 rsvd0[2];
+ __le32 eht_cap_phy_info_2ghz[WMI_MAX_EHTCAP_PHY_SIZE];
+ __le32 eht_cap_phy_info_5ghz[WMI_MAX_EHTCAP_PHY_SIZE];
+ struct ath12k_wmi_ppe_threshold_params eht_ppet_2ghz;
+ struct ath12k_wmi_ppe_threshold_params eht_ppet_5ghz;
+ __le32 eht_cap_info_internal;
+ __le32 eht_supp_mcs_ext_2ghz[WMI_MAX_EHT_SUPP_MCS_2G_SIZE];
+ __le32 eht_supp_mcs_ext_5ghz[WMI_MAX_EHT_SUPP_MCS_5G_SIZE];
+} __packed;
+
/* 2 word representation of MAC addr */
struct ath12k_wmi_mac_addr_params {
u8 addr[ETH_ALEN];
--
2.39.0
Functions ath12k_mac_setup_he_cap() and ath12k_mac_copy_he_cap()
propagate HE and 6GHz capabilities to the userspace using an instance
of struct ieee80211_sband_iftype_data. This structure now has a new
member 'eht_cap' to include EHT capabilities as well.
Rename the above mentioned functions to indicate that their use is not
limited to HE.
Also, replace the local variable 'band' with 'sband' and reuse
'band' for the type enum nl80211_band.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Signed-off-by: Aloka Dixit <[email protected]>
---
v4: No change from v3.
v3: No change from v2.
v2: No change from v1.
drivers/net/wireless/ath/ath12k/mac.c | 58 ++++++++++++++-------------
1 file changed, 31 insertions(+), 27 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index d814d74bc168..ddc293ebbd75 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -4209,10 +4209,10 @@ static __le16 ath12k_mac_setup_he_6ghz_cap(struct ath12k_pdev_cap *pcap,
return cpu_to_le16(bcap->he_6ghz_capa);
}
-static int ath12k_mac_copy_he_cap(struct ath12k *ar,
- struct ath12k_pdev_cap *cap,
- struct ieee80211_sband_iftype_data *data,
- int band)
+static int ath12k_mac_copy_sband_iftype_data(struct ath12k *ar,
+ struct ath12k_pdev_cap *cap,
+ struct ieee80211_sband_iftype_data *data,
+ int band)
{
int i, idx = 0;
@@ -4297,38 +4297,42 @@ static int ath12k_mac_copy_he_cap(struct ath12k *ar,
return idx;
}
-static void ath12k_mac_setup_he_cap(struct ath12k *ar,
- struct ath12k_pdev_cap *cap)
+static void ath12k_mac_setup_sband_iftype_data(struct ath12k *ar,
+ struct ath12k_pdev_cap *cap)
{
- struct ieee80211_supported_band *band;
+ struct ieee80211_supported_band *sband;
+ enum nl80211_band band;
int count;
if (cap->supported_bands & WMI_HOST_WLAN_2G_CAP) {
- count = ath12k_mac_copy_he_cap(ar, cap,
- ar->mac.iftype[NL80211_BAND_2GHZ],
- NL80211_BAND_2GHZ);
- band = &ar->mac.sbands[NL80211_BAND_2GHZ];
- band->iftype_data = ar->mac.iftype[NL80211_BAND_2GHZ];
- band->n_iftype_data = count;
+ band = NL80211_BAND_2GHZ;
+ count = ath12k_mac_copy_sband_iftype_data(ar, cap,
+ ar->mac.iftype[band],
+ band);
+ sband = &ar->mac.sbands[band];
+ sband->iftype_data = ar->mac.iftype[band];
+ sband->n_iftype_data = count;
}
if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP) {
- count = ath12k_mac_copy_he_cap(ar, cap,
- ar->mac.iftype[NL80211_BAND_5GHZ],
- NL80211_BAND_5GHZ);
- band = &ar->mac.sbands[NL80211_BAND_5GHZ];
- band->iftype_data = ar->mac.iftype[NL80211_BAND_5GHZ];
- band->n_iftype_data = count;
+ band = NL80211_BAND_5GHZ;
+ count = ath12k_mac_copy_sband_iftype_data(ar, cap,
+ ar->mac.iftype[band],
+ band);
+ sband = &ar->mac.sbands[band];
+ sband->iftype_data = ar->mac.iftype[band];
+ sband->n_iftype_data = count;
}
if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP &&
ar->supports_6ghz) {
- count = ath12k_mac_copy_he_cap(ar, cap,
- ar->mac.iftype[NL80211_BAND_6GHZ],
- NL80211_BAND_6GHZ);
- band = &ar->mac.sbands[NL80211_BAND_6GHZ];
- band->iftype_data = ar->mac.iftype[NL80211_BAND_6GHZ];
- band->n_iftype_data = count;
+ band = NL80211_BAND_6GHZ;
+ count = ath12k_mac_copy_sband_iftype_data(ar, cap,
+ ar->mac.iftype[band],
+ band);
+ sband = &ar->mac.sbands[band];
+ sband->iftype_data = ar->mac.iftype[band];
+ sband->n_iftype_data = count;
}
}
@@ -4373,7 +4377,7 @@ static int __ath12k_set_antenna(struct ath12k *ar, u32 tx_ant, u32 rx_ant)
/* Reload HT/VHT/HE capability */
ath12k_mac_setup_ht_vht_cap(ar, &ar->pdev->cap, NULL);
- ath12k_mac_setup_he_cap(ar, &ar->pdev->cap);
+ ath12k_mac_setup_sband_iftype_data(ar, &ar->pdev->cap);
return 0;
}
@@ -6854,7 +6858,7 @@ static int __ath12k_mac_register(struct ath12k *ar)
goto err;
ath12k_mac_setup_ht_vht_cap(ar, cap, &ht_cap);
- ath12k_mac_setup_he_cap(ar, cap);
+ ath12k_mac_setup_sband_iftype_data(ar, cap);
ret = ath12k_mac_setup_iface_combinations(ar);
if (ret) {
--
2.39.0
Enable the feature flag to indicate the driver support for
preamble puncturing. Firmware will support this feature
by default from IEEE 802.11be onwards.
Configure the bitmap as part of VDEV start/restart and
peer association commands.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Signed-off-by: Aloka Dixit <[email protected]>
Signed-off-by: Muna Sinada <[email protected]>
---
v4: No change from v3.
v3: No change from v2.
v2: No change from v1.
drivers/net/wireless/ath/ath12k/core.h | 1 +
drivers/net/wireless/ath/ath12k/mac.c | 16 ++++++++++++++--
drivers/net/wireless/ath/ath12k/wmi.c | 2 ++
drivers/net/wireless/ath/ath12k/wmi.h | 12 +++++++++++-
4 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h
index df762cabacc2..5ecf535cce53 100644
--- a/drivers/net/wireless/ath/ath12k/core.h
+++ b/drivers/net/wireless/ath/ath12k/core.h
@@ -238,6 +238,7 @@ struct ath12k_vif {
u32 key_cipher;
u8 tx_encap_type;
u8 vdev_stats_id;
+ u32 punct_bitmap;
};
struct ath12k_vif_iter {
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index 446a0db67516..c2f488cbc70e 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -842,6 +842,7 @@ static int ath12k_mac_monitor_vdev_start(struct ath12k *ar, int vdev_id,
arg.pref_tx_streams = ar->num_tx_chains;
arg.pref_rx_streams = ar->num_rx_chains;
+ arg.punct_bitmap = 0xFFFFFFFF;
arg.passive |= !!(chandef->chan->flags & IEEE80211_CHAN_NO_IR);
@@ -2141,6 +2142,7 @@ static void ath12k_peer_assoc_h_eht(struct ath12k *ar,
{
const struct ieee80211_sta_eht_cap *eht_cap = &sta->deflink.eht_cap;
const struct ieee80211_eht_mcs_nss_supp_bw *bw;
+ struct ath12k_vif *arvif = (struct ath12k_vif *)vif->drv_priv;
u32 *rx_mcs, *tx_mcs;
if (!sta->deflink.he_cap.has_he || !eht_cap->has_eht)
@@ -2206,6 +2208,8 @@ static void ath12k_peer_assoc_h_eht(struct ath12k *ar,
arg->peer_eht_mcs_count++;
break;
}
+
+ arg->punct_bitmap = ~arvif->punct_bitmap;
}
static void ath12k_peer_assoc_prepare(struct ath12k *ar,
@@ -2759,6 +2763,9 @@ static void ath12k_mac_op_bss_info_changed(struct ieee80211_hw *hw,
changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP)
ath12k_mac_fils_discovery(arvif, info);
+ if (changed & BSS_CHANGED_EHT_PUNCTURING)
+ arvif->punct_bitmap = info->eht_puncturing;
+
mutex_unlock(&ar->conf_mutex);
}
@@ -5801,6 +5808,7 @@ ath12k_mac_vdev_start_restart(struct ath12k_vif *arvif,
arg.vdev_id = arvif->vdev_id;
arg.dtim_period = arvif->dtim_period;
arg.bcn_intval = arvif->beacon_interval;
+ arg.punct_bitmap = ~arvif->punct_bitmap;
arg.freq = chandef->chan->center_freq;
arg.band_center_freq1 = chandef->center_freq1;
@@ -5843,9 +5851,9 @@ ath12k_mac_vdev_start_restart(struct ath12k_vif *arvif,
arg.passive |= !!(chandef->chan->flags & IEEE80211_CHAN_NO_IR);
ath12k_dbg(ab, ATH12K_DBG_MAC,
- "mac vdev %d start center_freq %d phymode %s\n",
+ "mac vdev %d start center_freq %d phymode %s punct_bitmap 0x%x\n",
arg.vdev_id, arg.freq,
- ath12k_mac_phymode_str(arg.mode));
+ ath12k_mac_phymode_str(arg.mode), arg.punct_bitmap);
ret = ath12k_wmi_vdev_start(ar, &arg, restart);
if (ret) {
@@ -6172,6 +6180,8 @@ ath12k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
"mac chanctx assign ptr %pK vdev_id %i\n",
ctx, arvif->vdev_id);
+ arvif->punct_bitmap = link_conf->eht_puncturing;
+
/* for some targets bss peer must be created before vdev_start */
if (ab->hw_params->vdev_start_delay &&
arvif->vdev_type != WMI_VDEV_TYPE_AP &&
@@ -7279,6 +7289,8 @@ static int __ath12k_mac_register(struct ath12k *ar)
NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP);
}
+ wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_PUNCT);
+
ath12k_reg_init(ar);
if (!test_bit(ATH12K_FLAG_RAW_MODE, &ab->dev_flags)) {
diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index df7609b4adda..8914d5780f94 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -1021,6 +1021,7 @@ int ath12k_wmi_vdev_start(struct ath12k *ar, struct wmi_vdev_start_req_arg *arg,
cmd->cac_duration_ms = cpu_to_le32(arg->cac_duration_ms);
cmd->regdomain = cpu_to_le32(arg->regdomain);
cmd->he_ops = cpu_to_le32(arg->he_ops);
+ cmd->punct_bitmap = cpu_to_le32(arg->punct_bitmap);
if (!restart) {
if (arg->ssid) {
@@ -1942,6 +1943,7 @@ int ath12k_wmi_send_peer_assoc_cmd(struct ath12k *ar,
cmd->peer_new_assoc = cpu_to_le32(arg->peer_new_assoc);
cmd->peer_associd = cpu_to_le32(arg->peer_associd);
+ cmd->punct_bitmap = cpu_to_le32(arg->punct_bitmap);
ath12k_wmi_copy_peer_flags(cmd, arg,
test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED,
diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h
index f41092137565..9ebae5467250 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.h
+++ b/drivers/net/wireless/ath/ath12k/wmi.h
@@ -2775,6 +2775,11 @@ struct wmi_vdev_start_request_cmd {
__le32 he_ops;
__le32 cac_duration_ms;
__le32 regdomain;
+ __le32 min_data_rate;
+ __le32 mbssid_flags;
+ __le32 mbssid_tx_vdev_id;
+ __le32 eht_ops;
+ __le32 punct_bitmap;
} __packed;
#define MGMT_TX_DL_FRM_LEN 64
@@ -2874,6 +2879,10 @@ struct wmi_vdev_start_req_arg {
u32 pref_rx_streams;
u32 pref_tx_streams;
u32 num_noa_descriptors;
+ u32 min_data_rate;
+ u32 mbssid_flags;
+ u32 mbssid_tx_vdev_id;
+ u32 punct_bitmap;
};
struct ath12k_wmi_peer_create_arg {
@@ -3605,6 +3614,7 @@ struct ath12k_wmi_peer_assoc_arg {
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;
+ u32 punct_bitmap;
};
struct wmi_peer_assoc_complete_cmd {
@@ -3640,7 +3650,7 @@ struct wmi_peer_assoc_complete_cmd {
__le32 bss_max_idle_option;
__le32 auth_mode;
__le32 peer_flags_ext;
- __le32 puncture_20mhz_bitmap;
+ __le32 punct_bitmap;
__le32 peer_eht_cap_mac[WMI_MAX_EHTCAP_MAC_SIZE];
__le32 peer_eht_cap_phy[WMI_MAX_EHTCAP_PHY_SIZE];
__le32 peer_eht_ops;
--
2.39.0
The function ath12k_mac_copy_sband_iftype_data() is currently
used HE capabilities propagation but it can be extended to
include EHT data. Move the HE specific functionality from to
ath12k_mac_copy_he_cap() to make EHT additions easier.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Signed-off-by: Aloka Dixit <[email protected]>
---
v4: No change from v3.
v3: No change from v2.
v2: No change from v1.
drivers/net/wireless/ath/ath12k/mac.c | 111 +++++++++++++-------------
1 file changed, 55 insertions(+), 56 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index ddc293ebbd75..2eec7e114196 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -4209,18 +4209,69 @@ static __le16 ath12k_mac_setup_he_6ghz_cap(struct ath12k_pdev_cap *pcap,
return cpu_to_le16(bcap->he_6ghz_capa);
}
+static void ath12k_mac_copy_he_cap(struct ath12k_band_cap *band_cap,
+ int iftype, u8 num_tx_chains,
+ struct ieee80211_sta_he_cap *he_cap)
+{
+ struct ieee80211_he_cap_elem *he_cap_elem = &he_cap->he_cap_elem;
+ struct ieee80211_he_mcs_nss_supp *mcs_nss = &he_cap->he_mcs_nss_supp;
+
+ he_cap->has_he = true;
+ memcpy(he_cap_elem->mac_cap_info, band_cap->he_cap_info,
+ sizeof(he_cap_elem->mac_cap_info));
+ memcpy(he_cap_elem->phy_cap_info, band_cap->he_cap_phy_info,
+ sizeof(he_cap_elem->phy_cap_info));
+
+ he_cap_elem->mac_cap_info[1] &=
+ IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_MASK;
+
+ he_cap_elem->phy_cap_info[5] &=
+ ~IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK;
+ he_cap_elem->phy_cap_info[5] &=
+ ~IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_MASK;
+ he_cap_elem->phy_cap_info[5] |= num_tx_chains - 1;
+
+ switch (iftype) {
+ case NL80211_IFTYPE_AP:
+ he_cap_elem->phy_cap_info[3] &=
+ ~IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_MASK;
+ he_cap_elem->phy_cap_info[9] |=
+ IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU;
+ break;
+ case NL80211_IFTYPE_STATION:
+ he_cap_elem->mac_cap_info[0] &= ~IEEE80211_HE_MAC_CAP0_TWT_RES;
+ he_cap_elem->mac_cap_info[0] |= IEEE80211_HE_MAC_CAP0_TWT_REQ;
+ he_cap_elem->phy_cap_info[9] |=
+ IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU;
+ break;
+ case NL80211_IFTYPE_MESH_POINT:
+ ath12k_mac_filter_he_cap_mesh(he_cap_elem);
+ break;
+ }
+
+ mcs_nss->rx_mcs_80 = cpu_to_le16(band_cap->he_mcs & 0xffff);
+ mcs_nss->tx_mcs_80 = cpu_to_le16(band_cap->he_mcs & 0xffff);
+ mcs_nss->rx_mcs_160 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
+ mcs_nss->tx_mcs_160 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
+ mcs_nss->rx_mcs_80p80 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
+ mcs_nss->tx_mcs_80p80 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
+
+ memset(he_cap->ppe_thres, 0, sizeof(he_cap->ppe_thres));
+ if (he_cap_elem->phy_cap_info[6] &
+ IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT)
+ ath12k_gen_ppe_thresh(&band_cap->he_ppet, he_cap->ppe_thres);
+}
+
static int ath12k_mac_copy_sband_iftype_data(struct ath12k *ar,
struct ath12k_pdev_cap *cap,
struct ieee80211_sband_iftype_data *data,
int band)
{
+ struct ath12k_band_cap *band_cap = &cap->band[band];
int i, idx = 0;
for (i = 0; i < NUM_NL80211_IFTYPES; i++) {
struct ieee80211_sta_he_cap *he_cap = &data[idx].he_cap;
- struct ath12k_band_cap *band_cap = &cap->band[band];
- struct ieee80211_he_cap_elem *he_cap_elem =
- &he_cap->he_cap_elem;
switch (i) {
case NL80211_IFTYPE_STATION:
@@ -4233,60 +4284,8 @@ static int ath12k_mac_copy_sband_iftype_data(struct ath12k *ar,
}
data[idx].types_mask = BIT(i);
- he_cap->has_he = true;
- memcpy(he_cap_elem->mac_cap_info, band_cap->he_cap_info,
- sizeof(he_cap_elem->mac_cap_info));
- memcpy(he_cap_elem->phy_cap_info, band_cap->he_cap_phy_info,
- sizeof(he_cap_elem->phy_cap_info));
-
- he_cap_elem->mac_cap_info[1] &=
- IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_MASK;
-
- he_cap_elem->phy_cap_info[5] &=
- ~IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK;
- he_cap_elem->phy_cap_info[5] &=
- ~IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_MASK;
- he_cap_elem->phy_cap_info[5] |= ar->num_tx_chains - 1;
-
- switch (i) {
- case NL80211_IFTYPE_AP:
- he_cap_elem->phy_cap_info[3] &=
- ~IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_MASK;
- he_cap_elem->phy_cap_info[9] |=
- IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU;
- break;
- case NL80211_IFTYPE_STATION:
- he_cap_elem->mac_cap_info[0] &=
- ~IEEE80211_HE_MAC_CAP0_TWT_RES;
- he_cap_elem->mac_cap_info[0] |=
- IEEE80211_HE_MAC_CAP0_TWT_REQ;
- he_cap_elem->phy_cap_info[9] |=
- IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU;
- break;
- case NL80211_IFTYPE_MESH_POINT:
- ath12k_mac_filter_he_cap_mesh(he_cap_elem);
- break;
- }
-
- he_cap->he_mcs_nss_supp.rx_mcs_80 =
- cpu_to_le16(band_cap->he_mcs & 0xffff);
- he_cap->he_mcs_nss_supp.tx_mcs_80 =
- cpu_to_le16(band_cap->he_mcs & 0xffff);
- he_cap->he_mcs_nss_supp.rx_mcs_160 =
- cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
- he_cap->he_mcs_nss_supp.tx_mcs_160 =
- cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
- he_cap->he_mcs_nss_supp.rx_mcs_80p80 =
- cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
- he_cap->he_mcs_nss_supp.tx_mcs_80p80 =
- cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
-
- memset(he_cap->ppe_thres, 0, sizeof(he_cap->ppe_thres));
- if (he_cap_elem->phy_cap_info[6] &
- IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT)
- ath12k_gen_ppe_thresh(&band_cap->he_ppet,
- he_cap->ppe_thres);
+ ath12k_mac_copy_he_cap(band_cap, i, ar->num_tx_chains, he_cap);
if (band == NL80211_BAND_6GHZ) {
data[idx].he_6ghz_capa.capa =
ath12k_mac_setup_he_6ghz_cap(cap, band_cap);
--
2.39.0
Propagate EHT capabilities to the userspace using a new member
'eht_cap' in structure ieee80211_sband_iftype_data.
MCS-NSS capabilities are copied depending on the supported bandwidths
for the given band.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Signed-off-by: Aloka Dixit <[email protected]>
Signed-off-by: Pradeep Kumar Chitrapu<[email protected]>
---
v4: No change from v3.
v3: No change from v2.
v2: No change from v1.
drivers/net/wireless/ath/ath12k/mac.c | 128 ++++++++++++++++++++++++++
1 file changed, 128 insertions(+)
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index 2eec7e114196..d4e97424dbc1 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -4262,6 +4262,132 @@ static void ath12k_mac_copy_he_cap(struct ath12k_band_cap *band_cap,
ath12k_gen_ppe_thresh(&band_cap->he_ppet, he_cap->ppe_thres);
}
+static void
+ath12k_mac_copy_eht_mcs_nss(struct ath12k_band_cap *band_cap,
+ struct ieee80211_eht_mcs_nss_supp *mcs_nss,
+ const struct ieee80211_he_cap_elem *he_cap,
+ const struct ieee80211_eht_cap_elem_fixed *eht_cap)
+{
+ if ((he_cap->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)
+ memcpy(&mcs_nss->only_20mhz, &band_cap->eht_mcs_20_only,
+ sizeof(struct ieee80211_eht_mcs_nss_supp_20mhz_only));
+
+ if (he_cap->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))
+ memcpy(&mcs_nss->bw._80, &band_cap->eht_mcs_80,
+ sizeof(struct ieee80211_eht_mcs_nss_supp_bw));
+
+ if (he_cap->phy_cap_info[0] &
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G)
+ memcpy(&mcs_nss->bw._160, &band_cap->eht_mcs_160,
+ sizeof(struct ieee80211_eht_mcs_nss_supp_bw));
+
+ if (eht_cap->phy_cap_info[0] & IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ)
+ memcpy(&mcs_nss->bw._320, &band_cap->eht_mcs_320,
+ sizeof(struct ieee80211_eht_mcs_nss_supp_bw));
+}
+
+static void ath12k_mac_copy_eht_ppet_ru(u32 ppet, u8 ppe_thres[], int ru)
+{
+ int i;
+ u32 val = 0;
+ u8 ppet_size_ru = IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE * 2;
+ u8 bit = IEEE80211_EHT_PPE_THRES_INFO_HEADER_SIZE;
+
+ u32p_replace_bits(&val, ppet >> (ru * ppet_size_ru),
+ GENMASK(ppet_size_ru - 1, 0));
+
+ val = ((val >> IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE) & GENMASK(2, 0)) |
+ ((val & GENMASK(2, 0)) << IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE);
+
+ for (i = ppet_size_ru - 1; i >= 0; i--) {
+ ppe_thres[bit / 8] |= (((val >> i) & 0x1) << ((bit % 8)));
+ bit++;
+ }
+}
+
+static void ath12k_mac_copy_eht_ppe_thresh(struct ath12k_wmi_ppe_threshold_arg *fw_ppet,
+ struct ieee80211_sta_eht_cap *cap)
+{
+ int nss, ru;
+ u8 len = 0;
+
+ len = hweight8(fw_ppet->ru_bit_mask);
+ len *= (1 + fw_ppet->numss_m1);
+
+ len = (len * IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE) +
+ IEEE80211_EHT_PPE_THRES_INFO_HEADER_SIZE;
+ len = DIV_ROUND_UP(len, 8);
+
+ u8p_replace_bits(&cap->eht_ppe_thres[0], fw_ppet->numss_m1,
+ IEEE80211_EHT_PPE_THRES_NSS_MASK);
+
+ u16p_replace_bits((u16 *)&cap->eht_ppe_thres[0], fw_ppet->ru_bit_mask,
+ IEEE80211_EHT_PPE_THRES_RU_INDEX_BITMASK_MASK);
+
+ for (nss = 0; nss <= fw_ppet->numss_m1; nss++) {
+ for (ru = 0;
+ ru < hweight8(IEEE80211_EHT_PPE_THRES_RU_INDEX_BITMASK_MASK);
+ ru++) {
+ if ((fw_ppet->ru_bit_mask & BIT(ru)) == 0)
+ continue;
+
+ ath12k_mac_copy_eht_ppet_ru(fw_ppet->ppet16_ppet8_ru3_ru0[nss],
+ cap->eht_ppe_thres, ru);
+ }
+ }
+}
+
+static void ath12k_mac_copy_eht_cap(struct ath12k_band_cap *band_cap,
+ struct ieee80211_he_cap_elem *he_cap_elem,
+ int iftype,
+ struct ieee80211_sta_eht_cap *eht_cap)
+{
+ struct ieee80211_eht_cap_elem_fixed *eht_cap_elem = &eht_cap->eht_cap_elem;
+
+ memset(eht_cap, 0, sizeof(struct ieee80211_sta_eht_cap));
+ eht_cap->has_eht = true;
+ memcpy(eht_cap_elem->mac_cap_info, band_cap->eht_cap_mac_info,
+ sizeof(eht_cap_elem->mac_cap_info));
+ memcpy(eht_cap_elem->phy_cap_info, band_cap->eht_cap_phy_info,
+ sizeof(eht_cap_elem->phy_cap_info));
+
+ switch (iftype) {
+ case NL80211_IFTYPE_AP:
+ eht_cap_elem->phy_cap_info[0] &=
+ ~IEEE80211_EHT_PHY_CAP0_242_TONE_RU_GT20MHZ;
+ eht_cap_elem->phy_cap_info[4] &=
+ ~IEEE80211_EHT_PHY_CAP4_PART_BW_DL_MU_MIMO;
+ eht_cap_elem->phy_cap_info[5] &=
+ ~IEEE80211_EHT_PHY_CAP5_TX_LESS_242_TONE_RU_SUPP;
+ break;
+ case NL80211_IFTYPE_STATION:
+ eht_cap_elem->phy_cap_info[7] &=
+ ~(IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_80MHZ |
+ IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_160MHZ |
+ IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_320MHZ);
+ eht_cap_elem->phy_cap_info[7] &=
+ ~(IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_80MHZ |
+ IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_160MHZ |
+ IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_320MHZ);
+ break;
+ default:
+ break;
+ }
+
+ ath12k_mac_copy_eht_mcs_nss(band_cap, &eht_cap->eht_mcs_nss_supp,
+ he_cap_elem, eht_cap_elem);
+
+ if (eht_cap_elem->phy_cap_info[5] &
+ IEEE80211_EHT_PHY_CAP5_PPE_THRESHOLD_PRESENT)
+ ath12k_mac_copy_eht_ppe_thresh(&band_cap->eht_ppet, eht_cap);
+}
+
static int ath12k_mac_copy_sband_iftype_data(struct ath12k *ar,
struct ath12k_pdev_cap *cap,
struct ieee80211_sband_iftype_data *data,
@@ -4290,6 +4416,8 @@ static int ath12k_mac_copy_sband_iftype_data(struct ath12k *ar,
data[idx].he_6ghz_capa.capa =
ath12k_mac_setup_he_6ghz_cap(cap, band_cap);
}
+ ath12k_mac_copy_eht_cap(band_cap, &he_cap->he_cap_elem, i,
+ &data[idx].eht_cap);
idx++;
}
--
2.39.0
From: Muna Sinada <[email protected]>
Add support to retrieve and configure the phy modes supported
by the hardware.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Signed-off-by: Muna Sinada <[email protected]>
Signed-off-by: Aloka Dixit <[email protected]>
---
v4: No change from v3.
v3: No change from v2.
v2: Changed 'target' to 'hardware' in the description.
drivers/net/wireless/ath/ath12k/mac.c | 98 +++++++++++++++++++++------
drivers/net/wireless/ath/ath12k/mac.h | 2 +-
drivers/net/wireless/ath/ath12k/wmi.h | 13 +++-
3 files changed, 91 insertions(+), 22 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index d4e97424dbc1..4f61c8993c87 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -182,32 +182,35 @@ ath12k_phymodes[NUM_NL80211_BANDS][ATH12K_CHAN_WIDTH_NUM] = {
[NL80211_BAND_2GHZ] = {
[NL80211_CHAN_WIDTH_5] = MODE_UNKNOWN,
[NL80211_CHAN_WIDTH_10] = MODE_UNKNOWN,
- [NL80211_CHAN_WIDTH_20_NOHT] = MODE_11AX_HE20_2G,
- [NL80211_CHAN_WIDTH_20] = MODE_11AX_HE20_2G,
- [NL80211_CHAN_WIDTH_40] = MODE_11AX_HE40_2G,
- [NL80211_CHAN_WIDTH_80] = MODE_11AX_HE80_2G,
+ [NL80211_CHAN_WIDTH_20_NOHT] = MODE_11BE_EHT20_2G,
+ [NL80211_CHAN_WIDTH_20] = MODE_11BE_EHT20_2G,
+ [NL80211_CHAN_WIDTH_40] = MODE_11BE_EHT40_2G,
+ [NL80211_CHAN_WIDTH_80] = MODE_UNKNOWN,
[NL80211_CHAN_WIDTH_80P80] = MODE_UNKNOWN,
[NL80211_CHAN_WIDTH_160] = MODE_UNKNOWN,
+ [NL80211_CHAN_WIDTH_320] = MODE_UNKNOWN,
},
[NL80211_BAND_5GHZ] = {
[NL80211_CHAN_WIDTH_5] = MODE_UNKNOWN,
[NL80211_CHAN_WIDTH_10] = MODE_UNKNOWN,
- [NL80211_CHAN_WIDTH_20_NOHT] = MODE_11AX_HE20,
- [NL80211_CHAN_WIDTH_20] = MODE_11AX_HE20,
- [NL80211_CHAN_WIDTH_40] = MODE_11AX_HE40,
- [NL80211_CHAN_WIDTH_80] = MODE_11AX_HE80,
- [NL80211_CHAN_WIDTH_160] = MODE_11AX_HE160,
- [NL80211_CHAN_WIDTH_80P80] = MODE_11AX_HE80_80,
+ [NL80211_CHAN_WIDTH_20_NOHT] = MODE_11BE_EHT20,
+ [NL80211_CHAN_WIDTH_20] = MODE_11BE_EHT20,
+ [NL80211_CHAN_WIDTH_40] = MODE_11BE_EHT40,
+ [NL80211_CHAN_WIDTH_80] = MODE_11BE_EHT80,
+ [NL80211_CHAN_WIDTH_160] = MODE_11BE_EHT160,
+ [NL80211_CHAN_WIDTH_80P80] = MODE_11BE_EHT80_80,
+ [NL80211_CHAN_WIDTH_320] = MODE_11BE_EHT320,
},
[NL80211_BAND_6GHZ] = {
[NL80211_CHAN_WIDTH_5] = MODE_UNKNOWN,
[NL80211_CHAN_WIDTH_10] = MODE_UNKNOWN,
- [NL80211_CHAN_WIDTH_20_NOHT] = MODE_11AX_HE20,
- [NL80211_CHAN_WIDTH_20] = MODE_11AX_HE20,
- [NL80211_CHAN_WIDTH_40] = MODE_11AX_HE40,
- [NL80211_CHAN_WIDTH_80] = MODE_11AX_HE80,
- [NL80211_CHAN_WIDTH_160] = MODE_11AX_HE160,
- [NL80211_CHAN_WIDTH_80P80] = MODE_11AX_HE80_80,
+ [NL80211_CHAN_WIDTH_20_NOHT] = MODE_11BE_EHT20,
+ [NL80211_CHAN_WIDTH_20] = MODE_11BE_EHT20,
+ [NL80211_CHAN_WIDTH_40] = MODE_11BE_EHT40,
+ [NL80211_CHAN_WIDTH_80] = MODE_11BE_EHT80,
+ [NL80211_CHAN_WIDTH_160] = MODE_11BE_EHT160,
+ [NL80211_CHAN_WIDTH_80P80] = MODE_11BE_EHT80_80,
+ [NL80211_CHAN_WIDTH_320] = MODE_11BE_EHT320,
},
};
@@ -292,6 +295,24 @@ static const char *ath12k_mac_phymode_str(enum wmi_phy_mode mode)
return "11ax-he40-2g";
case MODE_11AX_HE80_2G:
return "11ax-he80-2g";
+ case MODE_11BE_EHT20:
+ return "11be-eht20";
+ case MODE_11BE_EHT40:
+ return "11be-eht40";
+ case MODE_11BE_EHT80:
+ return "11be-eht80";
+ case MODE_11BE_EHT80_80:
+ return "11be-eht80+80";
+ case MODE_11BE_EHT160:
+ return "11be-eht160";
+ case MODE_11BE_EHT160_160:
+ return "11be-eht160+160";
+ case MODE_11BE_EHT320:
+ return "11be-eht320";
+ case MODE_11BE_EHT20_2G:
+ return "11be-eht20-2g";
+ case MODE_11BE_EHT40_2G:
+ return "11be-eht40-2g";
case MODE_UNKNOWN:
/* skip */
break;
@@ -1929,6 +1950,38 @@ static enum wmi_phy_mode ath12k_mac_get_phymode_he(struct ath12k *ar,
return MODE_UNKNOWN;
}
+static enum wmi_phy_mode ath12k_mac_get_phymode_eht(struct ath12k *ar,
+ struct ieee80211_sta *sta)
+{
+ if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_320)
+ if (sta->deflink.eht_cap.eht_cap_elem.phy_cap_info[0] &
+ IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ)
+ return MODE_11BE_EHT320;
+ if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160) {
+ if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[0] &
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G)
+ return MODE_11BE_EHT160;
+
+ if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[0] &
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
+ return MODE_11BE_EHT80_80;
+
+ ath12k_warn(ar->ab, "invalid eht phy cap info for 160 Mhz\n");
+ return MODE_11BE_EHT160;
+ }
+
+ if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80)
+ return MODE_11BE_EHT80;
+
+ if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40)
+ return MODE_11BE_EHT40;
+
+ if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_20)
+ return MODE_11BE_EHT20;
+
+ return MODE_UNKNOWN;
+}
+
static void ath12k_peer_assoc_h_phymode(struct ath12k *ar,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
@@ -1950,7 +2003,12 @@ static void ath12k_peer_assoc_h_phymode(struct ath12k *ar,
switch (band) {
case NL80211_BAND_2GHZ:
- if (sta->deflink.he_cap.has_he) {
+ if (sta->deflink.eht_cap.has_eht) {
+ if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40)
+ phymode = MODE_11BE_EHT40_2G;
+ else
+ phymode = MODE_11BE_EHT20_2G;
+ } else if (sta->deflink.he_cap.has_he) {
if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_80)
phymode = MODE_11AX_HE80_2G;
else if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_40)
@@ -1977,8 +2035,10 @@ static void ath12k_peer_assoc_h_phymode(struct ath12k *ar,
break;
case NL80211_BAND_5GHZ:
case NL80211_BAND_6GHZ:
- /* Check HE first */
- if (sta->deflink.he_cap.has_he) {
+ /* Check EHT first */
+ if (sta->deflink.eht_cap.has_eht) {
+ phymode = ath12k_mac_get_phymode_eht(ar, sta);
+ } else if (sta->deflink.he_cap.has_he) {
phymode = ath12k_mac_get_phymode_he(ar, sta);
} else if (sta->deflink.vht_cap.vht_supported &&
!ath12k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
diff --git a/drivers/net/wireless/ath/ath12k/mac.h b/drivers/net/wireless/ath/ath12k/mac.h
index 57f4295420bb..7b16b70df4fa 100644
--- a/drivers/net/wireless/ath/ath12k/mac.h
+++ b/drivers/net/wireless/ath/ath12k/mac.h
@@ -33,7 +33,7 @@ struct ath12k_generic_iter {
#define IEEE80211_VHT_MCS_SUPPORT_0_11_MASK GENMASK(23, 16)
#define IEEE80211_DISABLE_VHT_MCS_SUPPORT_0_11 BIT(24)
-#define ATH12K_CHAN_WIDTH_NUM 8
+#define ATH12K_CHAN_WIDTH_NUM 14
#define ATH12K_TX_POWER_MAX_VAL 70
#define ATH12K_TX_POWER_MIN_VAL 0
diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h
index b722eab281c3..aecc739164ae 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.h
+++ b/drivers/net/wireless/ath/ath12k/wmi.h
@@ -2796,8 +2796,17 @@ enum wmi_phy_mode {
MODE_11AX_HE20_2G = 21,
MODE_11AX_HE40_2G = 22,
MODE_11AX_HE80_2G = 23,
- MODE_UNKNOWN = 24,
- MODE_MAX = 24
+ MODE_11BE_EHT20 = 24,
+ MODE_11BE_EHT40 = 25,
+ MODE_11BE_EHT80 = 26,
+ MODE_11BE_EHT80_80 = 27,
+ MODE_11BE_EHT160 = 28,
+ MODE_11BE_EHT160_160 = 29,
+ MODE_11BE_EHT320 = 30,
+ MODE_11BE_EHT20_2G = 31,
+ MODE_11BE_EHT40_2G = 32,
+ MODE_UNKNOWN = 33,
+ MODE_MAX = 33,
};
struct wmi_vdev_start_req_arg {
--
2.39.0
Add new WMI tag and pass the EHT parameters for peer association
to firmware.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Signed-off-by: Aloka Dixit <[email protected]>
Signed-off-by: Pradeep Kumar Chitrapu <[email protected]>
---
v4: No change from v3.
v3: No change from v2.
v2: No change from v1.
drivers/net/wireless/ath/ath12k/wmi.c | 40 +++++++++++++++++++++++++--
drivers/net/wireless/ath/ath12k/wmi.h | 20 ++++++++++++++
2 files changed, 57 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index 7b82e7240594..358aac5802bc 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -1801,6 +1801,7 @@ static void ath12k_wmi_copy_peer_flags(struct wmi_peer_assoc_complete_cmd *cmd,
bool hw_crypto_disabled)
{
cmd->peer_flags = 0;
+ cmd->peer_flags_ext = 0;
if (arg->is_wme_set) {
if (arg->qos_flag)
@@ -1842,6 +1843,8 @@ static void ath12k_wmi_copy_peer_flags(struct wmi_peer_assoc_complete_cmd *cmd,
cmd->peer_flags |= cpu_to_le32(WMI_PEER_TWT_REQ);
if (arg->twt_responder)
cmd->peer_flags |= cpu_to_le32(WMI_PEER_TWT_RESP);
+ if (arg->eht_flag)
+ cmd->peer_flags_ext |= cpu_to_le32(WMI_PEER_EXT_EHT);
}
/* Suppress authorization for all AUTH modes that need 4-way handshake
@@ -1886,6 +1889,7 @@ int ath12k_wmi_send_peer_assoc_cmd(struct ath12k *ar,
struct wmi_peer_assoc_complete_cmd *cmd;
struct ath12k_wmi_vht_rate_set_params *mcs;
struct ath12k_wmi_he_rate_set_params *he_mcs;
+ struct ath12k_wmi_eht_rate_set_params *eht_mcs;
struct sk_buff *skb;
struct wmi_tlv *tlv;
void *ptr;
@@ -1902,7 +1906,8 @@ int ath12k_wmi_send_peer_assoc_cmd(struct ath12k *ar,
TLV_HDR_SIZE + (peer_legacy_rates_align * sizeof(u8)) +
TLV_HDR_SIZE + (peer_ht_rates_align * sizeof(u8)) +
sizeof(*mcs) + TLV_HDR_SIZE +
- (sizeof(*he_mcs) * arg->peer_he_mcs_count);
+ (sizeof(*he_mcs) * arg->peer_he_mcs_count) +
+ TLV_HDR_SIZE + (sizeof(*eht_mcs) * arg->peer_eht_mcs_count);
skb = ath12k_wmi_alloc_skb(wmi->wmi_ab, len);
if (!skb)
@@ -1949,6 +1954,16 @@ int ath12k_wmi_send_peer_assoc_cmd(struct ath12k *ar,
cmd->peer_ppet.ppet16_ppet8_ru3_ru0[i] =
cpu_to_le32(arg->peer_ppet.ppet16_ppet8_ru3_ru0[i]);
+ /* Update 11be capabilities */
+ memcpy_and_pad(cmd->peer_eht_cap_mac, sizeof(cmd->peer_eht_cap_mac),
+ arg->peer_eht_cap_mac, sizeof(arg->peer_eht_cap_mac),
+ 0);
+ memcpy_and_pad(cmd->peer_eht_cap_phy, sizeof(cmd->peer_eht_cap_phy),
+ arg->peer_eht_cap_phy, sizeof(arg->peer_eht_cap_phy),
+ 0);
+ memcpy_and_pad(&cmd->peer_eht_ppet, sizeof(cmd->peer_eht_ppet),
+ &arg->peer_eht_ppet, sizeof(arg->peer_eht_ppet), 0);
+
/* Update peer legacy rate information */
ptr += sizeof(*cmd);
@@ -2015,8 +2030,24 @@ int ath12k_wmi_send_peer_assoc_cmd(struct ath12k *ar,
ptr += sizeof(*he_mcs);
}
+ /* Loop through the EHT rate set */
+ len = arg->peer_eht_mcs_count * sizeof(*eht_mcs);
+ tlv = ptr;
+ tlv->header = ath12k_wmi_tlv_hdr(WMI_TAG_ARRAY_STRUCT, len);
+ ptr += TLV_HDR_SIZE;
+
+ for (i = 0; i < arg->peer_eht_mcs_count; i++) {
+ eht_mcs = ptr;
+ eht_mcs->tlv_header = ath12k_wmi_tlv_cmd_hdr(WMI_TAG_HE_RATE_SET,
+ sizeof(*eht_mcs));
+
+ eht_mcs->rx_mcs_set = cpu_to_le32(arg->peer_eht_rx_mcs_set[i]);
+ eht_mcs->tx_mcs_set = cpu_to_le32(arg->peer_eht_tx_mcs_set[i]);
+ ptr += sizeof(*eht_mcs);
+ }
+
ath12k_dbg(ar->ab, ATH12K_DBG_WMI,
- "wmi peer assoc vdev id %d assoc id %d peer mac %pM peer_flags %x rate_caps %x peer_caps %x listen_intval %d ht_caps %x max_mpdu %d nss %d phymode %d peer_mpdu_density %d vht_caps %x he cap_info %x he ops %x he cap_info_ext %x he phy %x %x %x peer_bw_rxnss_override %x\n",
+ "wmi peer assoc vdev id %d assoc id %d peer mac %pM peer_flags %x rate_caps %x peer_caps %x listen_intval %d ht_caps %x max_mpdu %d nss %d phymode %d peer_mpdu_density %d vht_caps %x he cap_info %x he ops %x he cap_info_ext %x he phy %x %x %x peer_bw_rxnss_override %x peer_flags_ext %x eht mac_cap %x %x eht phy_cap %x %x %x\n",
cmd->vdev_id, cmd->peer_associd, arg->peer_mac,
cmd->peer_flags, cmd->peer_rate_caps, cmd->peer_caps,
cmd->peer_listen_intval, cmd->peer_ht_caps,
@@ -2026,7 +2057,10 @@ int ath12k_wmi_send_peer_assoc_cmd(struct ath12k *ar,
cmd->peer_he_ops, cmd->peer_he_cap_info_ext,
cmd->peer_he_cap_phy[0], cmd->peer_he_cap_phy[1],
cmd->peer_he_cap_phy[2],
- cmd->peer_bw_rxnss_override);
+ cmd->peer_bw_rxnss_override, cmd->peer_flags_ext,
+ cmd->peer_eht_cap_mac[0], cmd->peer_eht_cap_mac[1],
+ cmd->peer_eht_cap_phy[0], cmd->peer_eht_cap_phy[1],
+ cmd->peer_eht_cap_phy[2]);
ret = ath12k_wmi_cmd_send(wmi, skb, WMI_PEER_ASSOC_CMDID);
if (ret) {
diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h
index d88d1575443d..f0877dbfc5fd 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.h
+++ b/drivers/net/wireless/ath/ath12k/wmi.h
@@ -1167,6 +1167,10 @@ enum wmi_tlv_peer_flags {
};
+enum wmi_tlv_peer_flags_ext {
+ WMI_PEER_EXT_EHT = 0x00000001,
+};
+
/** Enum list of TLV Tags for each parameter structure type. */
enum wmi_tlv_tag {
WMI_TAG_LAST_RESERVED = 15,
@@ -1924,6 +1928,7 @@ enum wmi_tlv_tag {
WMI_TAG_MAC_PHY_CAPABILITIES_EXT = 0x36F,
WMI_TAG_REGULATORY_RULE_EXT_STRUCT = 0x3A9,
WMI_TAG_REG_CHAN_LIST_CC_EXT_EVENT,
+ WMI_TAG_EHT_RATE_SET = 0x3C4,
WMI_TAG_MAX
};
@@ -3613,6 +3618,15 @@ struct wmi_peer_assoc_complete_cmd {
__le32 peer_he_cap_info_internal;
__le32 min_data_rate;
__le32 peer_he_caps_6ghz;
+ __le32 sta_type;
+ __le32 bss_max_idle_option;
+ __le32 auth_mode;
+ __le32 peer_flags_ext;
+ __le32 puncture_20mhz_bitmap;
+ __le32 peer_eht_cap_mac[WMI_MAX_EHTCAP_MAC_SIZE];
+ __le32 peer_eht_cap_phy[WMI_MAX_EHTCAP_PHY_SIZE];
+ __le32 peer_eht_ops;
+ struct ath12k_wmi_ppe_threshold_params peer_eht_ppet;
} __packed;
struct wmi_stop_scan_cmd {
@@ -3840,6 +3854,12 @@ struct ath12k_wmi_he_rate_set_params {
__le32 tx_mcs_set;
} __packed;
+struct ath12k_wmi_eht_rate_set_params {
+ __le32 tlv_header;
+ __le32 rx_mcs_set;
+ __le32 tx_mcs_set;
+} __packed;
+
#define MAX_REG_RULES 10
#define REG_ALPHA2_LEN 2
#define MAX_6G_REG_RULES 5
--
2.39.0
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 <[email protected]>
Signed-off-by: Pradeep Kumar Chitrapu <[email protected]>
---
v4: No change from v3.
v3: Incremented peer_eht_mcs_count for IEEE80211_STA_RX_BW_160 in
ath12k_peer_assoc_h_eht().
v2: No change from v1.
drivers/net/wireless/ath/ath12k/mac.c | 145 ++++++++++++++++++++++++++
drivers/net/wireless/ath/ath12k/wmi.h | 17 +++
2 files changed, 162 insertions(+)
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index 4f61c8993c87..446a0db67516 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -2064,6 +2064,150 @@ 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;
+ u8 nss;
+
+ 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++) {
+ u8 ru;
+
+ for (ru = 0;
+ ru < hweight8(IEEE80211_EHT_PPE_THRES_RU_INDEX_BITMASK_MASK);
+ ru++) {
+ u32 val = 0;
+ u8 i;
+
+ if ((ppet->ru_bit_mask & BIT(ru)) == 0)
+ continue;
+
+ for (i = 0;
+ i < IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE;
+ i++) {
+ val >>= 1;
+ val |= ((ppe_thres[bit_pos / 8] >>
+ (bit_pos % 8)) & 0x1) << 5;
+ bit_pos++;
+ }
+ ppet->ppet16_ppet8_ru3_ru0[nss] |=
+ (val <<
+ (ru * IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE));
+ }
+ }
+}
+
+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_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 (arg->peer_phymode == MODE_11BE_EHT20) {
+ const struct ieee80211_eht_mcs_nss_supp_20mhz_only *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,
@@ -2083,6 +2227,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);
diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h
index aecc739164ae..d88d1575443d 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.h
+++ b/drivers/net/wireless/ath/ath12k/wmi.h
@@ -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_mac_phy_caps_ext_params {
__le32 hw_mode_id;
union {
@@ -3565,6 +3575,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 {
--
2.39.0
From: Pradeep Kumar Chitrapu <[email protected]>
Add tags with length 0 for MLO header and partner links which
are required by the firmware for a successful association.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Signed-off-by: Pradeep Kumar Chitrapu <[email protected]>
Signed-off-by: Aloka Dixit <[email protected]>
---
v4: No change from v3.
v3: Moved MLO header tag addition before EHT rates to match firmware order.
v2: Corrected 'witout' to 'without' in the description.
drivers/net/wireless/ath/ath12k/wmi.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index 7debd2461e1a..9e48e1bce549 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -1909,7 +1909,8 @@ int ath12k_wmi_send_peer_assoc_cmd(struct ath12k *ar,
TLV_HDR_SIZE + (peer_ht_rates_align * sizeof(u8)) +
sizeof(*mcs) + TLV_HDR_SIZE +
(sizeof(*he_mcs) * arg->peer_he_mcs_count) +
- TLV_HDR_SIZE + (sizeof(*eht_mcs) * arg->peer_eht_mcs_count);
+ TLV_HDR_SIZE + (sizeof(*eht_mcs) * arg->peer_eht_mcs_count) +
+ TLV_HDR_SIZE + TLV_HDR_SIZE;
skb = ath12k_wmi_alloc_skb(wmi->wmi_ab, len);
if (!skb)
@@ -2032,6 +2033,12 @@ int ath12k_wmi_send_peer_assoc_cmd(struct ath12k *ar,
ptr += sizeof(*he_mcs);
}
+ /* MLO header tag with 0 length */
+ len = 0;
+ tlv = ptr;
+ tlv->header = ath12k_wmi_tlv_hdr(WMI_TAG_ARRAY_STRUCT, len);
+ ptr += TLV_HDR_SIZE;
+
/* Loop through the EHT rate set */
len = arg->peer_eht_mcs_count * sizeof(*eht_mcs);
tlv = ptr;
@@ -2048,6 +2055,12 @@ int ath12k_wmi_send_peer_assoc_cmd(struct ath12k *ar,
ptr += sizeof(*eht_mcs);
}
+ /* ML partner links tag with 0 length */
+ len = 0;
+ tlv = ptr;
+ tlv->header = ath12k_wmi_tlv_hdr(WMI_TAG_ARRAY_STRUCT, len);
+ ptr += TLV_HDR_SIZE;
+
ath12k_dbg(ar->ab, ATH12K_DBG_WMI,
"wmi peer assoc vdev id %d assoc id %d peer mac %pM peer_flags %x rate_caps %x peer_caps %x listen_intval %d ht_caps %x max_mpdu %d nss %d phymode %d peer_mpdu_density %d vht_caps %x he cap_info %x he ops %x he cap_info_ext %x he phy %x %x %x peer_bw_rxnss_override %x peer_flags_ext %x eht mac_cap %x %x eht phy_cap %x %x %x\n",
cmd->vdev_id, cmd->peer_associd, arg->peer_mac,
--
2.39.0
Parse WMI service ready ext2 event.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Signed-off-by: Aloka Dixit <[email protected]>
---
v4: No change from v3.
v3: No change from v2.
v2: No change from v1.
drivers/net/wireless/ath/ath12k/wmi.c | 48 +++++++++++++++++++++++++++
drivers/net/wireless/ath/ath12k/wmi.h | 16 +++++++++
2 files changed, 64 insertions(+)
diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index 9e48e1bce549..df7609b4adda 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -62,7 +62,23 @@ struct ath12k_wmi_svc_rdy_ext_parse {
bool dma_ring_cap_done;
};
+struct ath12k_wmi_svc_rdy_ext2_arg {
+ u32 reg_db_version;
+ u32 hw_min_max_tx_power_2ghz;
+ u32 hw_min_max_tx_power_5ghz;
+ u32 chwidth_num_peer_caps;
+ u32 preamble_puncture_bw;
+ u32 max_user_per_ppdu_ofdma;
+ u32 max_user_per_ppdu_mumimo;
+ u32 target_cap_flags;
+ u32 eht_cap_mac_info[WMI_MAX_EHTCAP_MAC_SIZE];
+ u32 max_num_linkview_peers;
+ u32 max_num_msduq_supported_per_tid;
+ u32 default_num_msduq_supported_per_tid;
+};
+
struct ath12k_wmi_svc_rdy_ext2_parse {
+ struct ath12k_wmi_svc_rdy_ext2_arg arg;
struct ath12k_wmi_dma_ring_caps_parse dma_caps_parse;
bool dma_ring_cap_done;
bool spectral_bin_scaling_done;
@@ -4098,6 +4114,26 @@ static int ath12k_service_ready_ext_event(struct ath12k_base *ab,
return ret;
}
+static int ath12k_pull_svc_ready_ext2(struct ath12k_wmi_pdev *wmi_handle,
+ const void *ptr,
+ struct ath12k_wmi_svc_rdy_ext2_arg *arg)
+{
+ const struct wmi_service_ready_ext2_event *ev = ptr;
+
+ if (!ev)
+ return -EINVAL;
+
+ arg->reg_db_version = le32_to_cpu(ev->reg_db_version);
+ arg->hw_min_max_tx_power_2ghz = le32_to_cpu(ev->hw_min_max_tx_power_2ghz);
+ arg->hw_min_max_tx_power_5ghz = le32_to_cpu(ev->hw_min_max_tx_power_5ghz);
+ arg->chwidth_num_peer_caps = le32_to_cpu(ev->chwidth_num_peer_caps);
+ arg->preamble_puncture_bw = le32_to_cpu(ev->preamble_puncture_bw);
+ arg->max_user_per_ppdu_ofdma = le32_to_cpu(ev->max_user_per_ppdu_ofdma);
+ arg->max_user_per_ppdu_mumimo = le32_to_cpu(ev->max_user_per_ppdu_mumimo);
+ arg->target_cap_flags = le32_to_cpu(ev->target_cap_flags);
+ return 0;
+}
+
static void ath12k_wmi_eht_caps_parse(struct ath12k_pdev *pdev, u32 band,
__le32 cap_mac_info[],
__le32 cap_phy_info[],
@@ -4222,10 +4258,22 @@ static int ath12k_wmi_svc_rdy_ext2_parse(struct ath12k_base *ab,
u16 tag, u16 len,
const void *ptr, void *data)
{
+ struct ath12k_wmi_pdev *wmi_handle = &ab->wmi_ab.wmi[0];
struct ath12k_wmi_svc_rdy_ext2_parse *parse = data;
int ret;
switch (tag) {
+ case WMI_TAG_SERVICE_READY_EXT2_EVENT:
+ ret = ath12k_pull_svc_ready_ext2(wmi_handle, ptr,
+ &parse->arg);
+ if (ret) {
+ ath12k_warn(ab,
+ "failed to extract wmi service ready ext2 parameters: %d\n",
+ ret);
+ return ret;
+ }
+ break;
+
case WMI_TAG_ARRAY_STRUCT:
if (!parse->dma_ring_cap_done) {
ret = ath12k_wmi_dma_ring_caps(ab, len, ptr,
diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h
index 9d0f74122bc6..f41092137565 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.h
+++ b/drivers/net/wireless/ath/ath12k/wmi.h
@@ -1925,6 +1925,7 @@ enum wmi_tlv_tag {
/* TODO add all the missing cmds */
WMI_TAG_PDEV_PEER_PKTLOG_FILTER_CMD = 0x301,
WMI_TAG_PDEV_PEER_PKTLOG_FILTER_INFO,
+ WMI_TAG_SERVICE_READY_EXT2_EVENT = 0x334,
WMI_TAG_FILS_DISCOVERY_TMPL_CMD = 0x344,
WMI_TAG_MAC_PHY_CAPABILITIES_EXT = 0x36F,
WMI_TAG_REGULATORY_RULE_EXT_STRUCT = 0x3A9,
@@ -2612,6 +2613,21 @@ struct ath12k_wmi_soc_hal_reg_caps_params {
#define WMI_EHT_MCS_NSS_10_11 GENMASK(11, 8)
#define WMI_EHT_MCS_NSS_12_13 GENMASK(15, 12)
+struct wmi_service_ready_ext2_event {
+ __le32 reg_db_version;
+ __le32 hw_min_max_tx_power_2ghz;
+ __le32 hw_min_max_tx_power_5ghz;
+ __le32 chwidth_num_peer_caps;
+ __le32 preamble_puncture_bw;
+ __le32 max_user_per_ppdu_ofdma;
+ __le32 max_user_per_ppdu_mumimo;
+ __le32 target_cap_flags;
+ __le32 eht_cap_mac_info[WMI_MAX_EHTCAP_MAC_SIZE];
+ __le32 max_num_linkview_peers;
+ __le32 max_num_msduq_supported_per_tid;
+ __le32 default_num_msduq_supported_per_tid;
+} __packed;
+
struct ath12k_wmi_mac_phy_caps_ext_params {
__le32 hw_mode_id;
union {
--
2.39.0
Aloka Dixit <[email protected]> writes:
> Add WMI support to process the EHT capabilities passed by
> the firmware. Add required EHT specific definitions in
> structures ath12k_band_cap and ath12k_wmi_svc_rdy_ext_parse.
>
> For single_pdev chip such as WCN7850, only one pdev is created
> and only one hardware is registered to mac80211. This one pdev
> manages both 2.4 GHz radio and 5 GHz/6 GHz radio.
>
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
> Signed-off-by: Aloka Dixit <[email protected]>
> Co-developed-by: Pradeep Kumar Chitrapu <[email protected]>
> Signed-off-by: Pradeep Kumar Chitrapu <[email protected]>
> Co-developed-by: Wen Gong <[email protected]>
> Signed-off-by: Wen Gong <[email protected]>
[...]
> +struct ath12k_fw_pdev {
> + u32 pdev_id;
> + u32 phy_id;
> + u32 supported_bands;
> +};
So we have now two very similar structures, ath12k_pdev and
ath12k_fw_pdev. It would be good to document above the structs their
purpose. Any ideas what I could add?
--
https://patchwork.kernel.org/project/linux-wireless/list/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
Aloka Dixit <[email protected]> writes:
> Propagate EHT capabilities to the userspace using a new member
> 'eht_cap' in structure ieee80211_sband_iftype_data.
>
> MCS-NSS capabilities are copied depending on the supported bandwidths
> for the given band.
>
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
> Signed-off-by: Aloka Dixit <[email protected]>
> Signed-off-by: Pradeep Kumar Chitrapu<[email protected]>
[...]
> +static void ath12k_mac_copy_eht_ppet_ru(u32 ppet, u8 ppe_thres[], int ru)
> +{
> + int i;
> + u32 val = 0;
> + u8 ppet_size_ru = IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE * 2;
> + u8 bit = IEEE80211_EHT_PPE_THRES_INFO_HEADER_SIZE;
> +
> + u32p_replace_bits(&val, ppet >> (ru * ppet_size_ru),
> + GENMASK(ppet_size_ru - 1, 0));
> +
> + val = ((val >> IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE) & GENMASK(2, 0)) |
> + ((val & GENMASK(2, 0)) << IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE);
This shifting of val looks weird. I didn't check the spec, what does it
do? Is there any cleaner way to do this? And should have a define for
GENMASK(2, 0)?
--
https://patchwork.kernel.org/project/linux-wireless/list/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
Aloka Dixit <[email protected]> writes:
> Add driver support for EHT bring-up, association and
> preamble puncturing.
>
> v4: Modified patch 3 to support WCN7850.
> v3: Modified patches 6 and 9 to fix some issues,
> changelog included in the respective patches.
> v2: This version modifies only few commit descriptions,
> changelog included in the respective patches.
I did some minor changes to these patches in the pending branch, here's
a list:
* patch 3: ath12k_wmi_tlv_mac_phy_caps_ext(): remove unncessary cast and add const
* patch 3: shorten struct ath12k_wmi_mac_phy_caps_ext_params due to
long line warning
* patch 3: improve error messages
* patch 3: move struct ath12k_fw_pdev after struct ath12k_pdev
* patch 5: ath12k_mac_get_phymode_eht(): add extra spaces, improve error messages
* patch 6: cosmetic cleanup, extra lines etc
* patch 6: ath12k_mac_set_eht_ppe_threshold(): move declarations
to the beginning of the function
* patch 7&8: use BIT() for enum wmi_tlv_peer_flags_ext
I have two more comments which I'll send as a reply to patches. I'm
hoping to fix those in my pending branch as well so there would no need
to resend anything.
The changes are now in the pending branch, under tag
ath-pending-202306151144. Here's a link to few of those commits:
https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=master-pending&id=974310a085acad9cee462b3f343e8c05185abc67
https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=master-pending&id=e4b7f51541b4ae79baa1ab9a8389fd4d9e0fe219
https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=master-pending&id=ae4b76c40bc7350d52d42de6e8633f6e52d905fb
https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=master-pending&id=3594ef351ae29788c00fad6c69d60b9a41dc1bbb
--
https://patchwork.kernel.org/project/linux-wireless/list/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
On 6/15/2023 7:49 PM, Kalle Valo wrote:
> Aloka Dixit <[email protected]> writes:
>
>> Add WMI support to process the EHT capabilities passed by
>> the firmware. Add required EHT specific definitions in
>> structures ath12k_band_cap and ath12k_wmi_svc_rdy_ext_parse.
>>
>> For single_pdev chip such as WCN7850, only one pdev is created
>> and only one hardware is registered to mac80211. This one pdev
>> manages both 2.4 GHz radio and 5 GHz/6 GHz radio.
>>
>> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
>> Signed-off-by: Aloka Dixit <[email protected]>
>> Co-developed-by: Pradeep Kumar Chitrapu <[email protected]>
>> Signed-off-by: Pradeep Kumar Chitrapu <[email protected]>
>> Co-developed-by: Wen Gong <[email protected]>
>> Signed-off-by: Wen Gong <[email protected]>
> [...]
>
>> +struct ath12k_fw_pdev {
>> + u32 pdev_id;
>> + u32 phy_id;
>> + u32 supported_bands;
>> +};
> So we have now two very similar structures, ath12k_pdev and
> ath12k_fw_pdev. It would be good to document above the structs their
> purpose. Any ideas what I could add?
For single_pdev, the ath12k_pdev is always one pdev.
and ath12k_fw_pdev is more than one for single_pdev.
>
On 6/3/2023 7:58 AM, Aloka Dixit wrote:
> ...
> + default:
> + if (arg->peer_phymode == MODE_11BE_EHT20) {
> + const struct ieee80211_eht_mcs_nss_supp_20mhz_only *bw_20 =
> + &eht_cap->eht_mcs_nss_supp.only_20mhz;
When ath12k used as station mode, it entered here as well as AP mode.
But remote is AP device for station mode, then remote AP device do not
have the only_20mhz data(EHT-MCS Map (20 MHz-Only Non-AP STA)).
Also 20 MHz should be same for 5 GHz/6 GHz(MODE_11BE_EHT20) and 2.4
GHz(MODE_11BE_EHT20_2G), right?
> +
> + 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;
> + }
> +}
> +
...
On 6/16/2023 3:50 AM, Wen Gong wrote:
> On 6/15/2023 7:49 PM, Kalle Valo wrote:
>> Aloka Dixit <[email protected]> writes:
>>
>>> Add WMI support to process the EHT capabilities passed by
>>> the firmware. Add required EHT specific definitions in
>>> structures ath12k_band_cap and ath12k_wmi_svc_rdy_ext_parse.
>>>
>>> For single_pdev chip such as WCN7850, only one pdev is created
>>> and only one hardware is registered to mac80211. This one pdev
>>> manages both 2.4 GHz radio and 5 GHz/6 GHz radio.
>>>
>>> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>>> Tested-on: WCN7850 hw2.0 PCI
>>> WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
>>> Signed-off-by: Aloka Dixit <[email protected]>
>>> Co-developed-by: Pradeep Kumar Chitrapu <[email protected]>
>>> Signed-off-by: Pradeep Kumar Chitrapu <[email protected]>
>>> Co-developed-by: Wen Gong <[email protected]>
>>> Signed-off-by: Wen Gong <[email protected]>
>> [...]
>>
>>> +struct ath12k_fw_pdev {
>>> + u32 pdev_id;
>>> + u32 phy_id;
>>> + u32 supported_bands;
>>> +};
>> So we have now two very similar structures, ath12k_pdev and
>> ath12k_fw_pdev. It would be good to document above the structs their
>> purpose. Any ideas what I could add?
>
> For single_pdev, the ath12k_pdev is always one pdev.
>
> and ath12k_fw_pdev is more than one for single_pdev.
>
>>
Okay will add a comment in the next version.
On 6/15/2023 4:47 AM, Kalle Valo wrote:
> Aloka Dixit <[email protected]> writes:
>
>> Add driver support for EHT bring-up, association and
>> preamble puncturing.
>>
>> v4: Modified patch 3 to support WCN7850.
>> v3: Modified patches 6 and 9 to fix some issues,
>> changelog included in the respective patches.
>> v2: This version modifies only few commit descriptions,
>> changelog included in the respective patches.
>
> I did some minor changes to these patches in the pending branch, here's
> a list:
>
> * patch 3: ath12k_wmi_tlv_mac_phy_caps_ext(): remove unncessary cast and add const
>
> * patch 3: shorten struct ath12k_wmi_mac_phy_caps_ext_params due to
> long line warning
>
> * patch 3: improve error messages
>
> * patch 3: move struct ath12k_fw_pdev after struct ath12k_pdev
>
> * patch 5: ath12k_mac_get_phymode_eht(): add extra spaces, improve error messages
>
> * patch 6: cosmetic cleanup, extra lines etc
>
> * patch 6: ath12k_mac_set_eht_ppe_threshold(): move declarations
> to the beginning of the function
>
> * patch 7&8: use BIT() for enum wmi_tlv_peer_flags_ext
>
> I have two more comments which I'll send as a reply to patches. I'm
> hoping to fix those in my pending branch as well so there would no need
> to resend anything.
>
> The changes are now in the pending branch, under tag
> ath-pending-202306151144. Here's a link to few of those commits:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=master-pending&id=974310a085acad9cee462b3f343e8c05185abc67
>
> https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=master-pending&id=e4b7f51541b4ae79baa1ab9a8389fd4d9e0fe219
>
> https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=master-pending&id=ae4b76c40bc7350d52d42de6e8633f6e52d905fb
>
> https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=master-pending&id=3594ef351ae29788c00fad6c69d60b9a41dc1bbb
>
Hi Kalle,
I have created a new version which fixes the comments you added
separately for 2 patches.
Should I send those now?
Thanks.
On 7/24/2023 3:16 AM, Wen Gong wrote:
> On 6/3/2023 7:58 AM, Aloka Dixit wrote:
>> ...
>> + default:
>> + if (arg->peer_phymode == MODE_11BE_EHT20) {
>> + const struct ieee80211_eht_mcs_nss_supp_20mhz_only *bw_20 =
>> + &eht_cap->eht_mcs_nss_supp.only_20mhz;
>
> When ath12k used as station mode, it entered here as well as AP mode.
>
> But remote is AP device for station mode, then remote AP device do not
> have the only_20mhz data(EHT-MCS Map (20 MHz-Only Non-AP STA)).
>
What issue are you seeing? Please elaborate.
The default case will be entered for both AP and non-AP STA modes for
all bandwidths.
If the device is a 20-MHz-only device, it will skip 320, 160 and
directly enter the default case where 'if' condition will be true.
If the device is not a 20-MHZ-only device then it will enter the 'else'
condition after processing 320 and 160 as applicable.
> Also 20 MHz should be same for 5 GHz/6 GHz(MODE_11BE_EHT20) and 2.4
> GHz(MODE_11BE_EHT20_2G), right?
>
Good point, I will add a check for MODE_11BE_EHT20_2G as well here.
>> +
>> + 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;
>> + }
>> +}
>> +
>
> ...
On 6/15/2023 4:51 AM, Kalle Valo wrote:
> Aloka Dixit <[email protected]> writes:
>
>> Propagate EHT capabilities to the userspace using a new member
>> 'eht_cap' in structure ieee80211_sband_iftype_data.
>>
>> MCS-NSS capabilities are copied depending on the supported bandwidths
>> for the given band.
>>
>> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>> Signed-off-by: Aloka Dixit <[email protected]>
>> Signed-off-by: Pradeep Kumar Chitrapu<[email protected]>
>
> [...]
>
>> +static void ath12k_mac_copy_eht_ppet_ru(u32 ppet, u8 ppe_thres[], int ru)
>> +{
>> + int i;
>> + u32 val = 0;
>> + u8 ppet_size_ru = IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE * 2;
>> + u8 bit = IEEE80211_EHT_PPE_THRES_INFO_HEADER_SIZE;
>> +
>> + u32p_replace_bits(&val, ppet >> (ru * ppet_size_ru),
>> + GENMASK(ppet_size_ru - 1, 0));
>> +
>> + val = ((val >> IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE) & GENMASK(2, 0)) |
>> + ((val & GENMASK(2, 0)) << IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE);
>
> This shifting of val looks weird. I didn't check the spec, what does it
> do? Is there any cleaner way to do this? And should have a define for
> GENMASK(2, 0)?
>
I have a follow-up ready, based on top of the fixes you already made in
the master pending branch, which cleans this up.
Also noticed that need to use hweight16 instead of hweight8 for
IEEE80211_EHT_PPE_THRES_RU_INDEX_BITMASK_MASK. The new version fixes it
in this patch as well as in patch #6.
Should I send the next version?
On 7/25/2023 2:24 AM, Aloka Dixit wrote:
> On 7/24/2023 3:16 AM, Wen Gong wrote:
>> On 6/3/2023 7:58 AM, Aloka Dixit wrote:
>>> ...
>>> + default:
>>> + if (arg->peer_phymode == MODE_11BE_EHT20) {
>>> + const struct ieee80211_eht_mcs_nss_supp_20mhz_only
>>> *bw_20 =
>>> + &eht_cap->eht_mcs_nss_supp.only_20mhz;
>>
>> When ath12k used as station mode, it entered here as well as AP mode.
>>
>> But remote is AP device for station mode, then remote AP device do
>> not have the only_20mhz data(EHT-MCS Map (20 MHz-Only Non-AP STA)).
>>
>
> What issue are you seeing? Please elaborate.
>
> The default case will be entered for both AP and non-AP STA modes for
> all bandwidths.
>
> If the device is a 20-MHz-only device, it will skip 320, 160 and
> directly enter the default case where 'if' condition will be true.
>
> If the device is not a 20-MHZ-only device then it will enter the
> 'else' condition after processing 320 and 160 as applicable.
When I configured AP with 11BE-EHT mode for 20 MHz bandwidth on 5 GHz/6
GHz band,
and then connect to the AP with ath12k for station mode. Then the
peer_phymode
is MODE_11BE_EHT20, and then ath12k entered the default in function
ath12k_peer_assoc_h_eht() and use the bw_20 which is assigned with
eht_cap->eht_mcs_nss_supp.only_20mhz.
For station mode of ath12k, the eht_cap->eht_mcs_nss_supp is from the IE
"Supported
EHT-MCS and NSS Set" in assoc resp of AP in function
ieee80211_eht_cap_ie_to_sta_eht_cap().
Now it is "EHT-MCS Map (BW <= 80MHz): 0x222222" for the AP(11BE-EHT mode
for 20 MHz
bandwidth on 6 GHz band) in my test as below IEs.
The field only_20mhz and field _80 are union in struct
ieee80211_eht_mcs_nss_supp, the
value of field _80 is 0x222222 for this AP, then the value of field
only_20mhz is like this:
rx_tx_mcs7_max_nss=0x22,
rx_tx_mcs9_max_nss=0x22,
rx_tx_mcs11_max_nss=0x22,
rx_tx_mcs13_max_nss=0.
Then ath12k_mac_set_eht_mcs() will get value 0 fro mcs13 because it used
the field only_20mhz
passed by ath12k_peer_assoc_h_eht().
ieee80211_eht_cap_ie_to_sta_eht_cap()
{
...
/* Copy MCS/NSS which depends on the peer capabilities */
memset(&eht_cap->eht_mcs_nss_supp, 0,
sizeof(eht_cap->eht_mcs_nss_supp));
memcpy(&eht_cap->eht_mcs_nss_supp, pos, mcs_nss_size);
...
}
struct ieee80211_eht_mcs_nss_supp {
union {
struct ieee80211_eht_mcs_nss_supp_20mhz_only only_20mhz;
struct {
struct ieee80211_eht_mcs_nss_supp_bw _80;
struct ieee80211_eht_mcs_nss_supp_bw _160;
struct ieee80211_eht_mcs_nss_supp_bw _320;
} __packed bw;
} __packed;
} __packed;
struct ieee80211_eht_mcs_nss_supp_20mhz_only {
u8 rx_tx_mcs7_max_nss;
u8 rx_tx_mcs9_max_nss;
u8 rx_tx_mcs11_max_nss;
u8 rx_tx_mcs13_max_nss;
};
struct ieee80211_eht_mcs_nss_supp_bw {
u8 rx_tx_mcs9_max_nss;
u8 rx_tx_mcs11_max_nss;
u8 rx_tx_mcs13_max_nss;
};
IEs of the AP:
Ext Tag: HE Capabilities (IEEE Std 802.11ax/D3.0)
Tag Number: Element ID Extension (255)
Ext Tag length: 29
Ext Tag Number: HE Capabilities (IEEE Std 802.11ax/D3.0) (35)
HE MAC Capabilities Information: 0x10401a08010d
HE Phy Capabilities Information
.... ...0 = Reserved: 0x0
0000 000. = Channel Width Set: 0x00
.... ..0. = 40MHz in 2.4GHz band: Not supported
.... .0.. = 40 & 80MHz in the 5GHz or 6GHz band: Not
supported //20 MHz
.... 0... = 160MHz in the 5GHz or 6GHz band: Not supported
...0 .... = 160/80+80MHz in the 5GHz or 6GHz band: Not
supported
..0. .... = 242 tone RUs in the 2.4GHz band: Not supported
.0.. .... = 242 tone RUs in the 5GHz or 6GHz band: Not
supported
0... .... = Reserved: 0x0
Bits 8 to 23: 0x4063
Bits 24 to 39: 0x1f88
Bits 40 to 55: 0x8141
Bits 56 to 71: 0x111c
Bits 72 to 87: 0x0008
Supported HE-MCS and NSS Set
PPE Thresholds
Ext Tag: HE Operation (IEEE Std 802.11ax/D3.0)
Tag Number: Element ID Extension (255)
Ext Tag length: 12
Ext Tag Number: HE Operation (IEEE Std 802.11ax/D3.0) (36)
HE Operation Parameters: 0x023ff4
BSS Color Information: 0x0c
Basic HE-MCS and NSS Set: 0xfffc
6GHz Operation Information
Primary Channel: 37
6GHz Operation Information Control Field
.... ..00 = Channel Width: 20 MHz (0) //20 MHz
.... .0.. = Duplicate Beacon: False
0000 0... = Reserved: 0x00
Channel Center Frequency Segment0: 37
Channel Center Frequency Segment1: 0
Minimum rate: 1
Ext Tag: EHT Capabilities (IEEE Std 802.11be/D2.0)
Tag Number: Element ID Extension (255)
Ext Tag length: 15
Ext Tag Number: EHT Capabilities (IEEE Std 802.11be/D2.0) (108)
EHT MAC Capabilities Information: 0x0000
EHT PHY Capabilities Information
Supported EHT-MCS and NSS Set
EHT-MCS Map (BW <= 80MHz): 0x222222
.... .... .... .... .... 0010 = Rx Max Nss That Supports
EHT-MCS 0-9: 2
.... .... .... .... 0010 .... = Tx Max Nss That Supports
EHT-MCS 0-9: 2
.... .... .... 0010 .... .... = Rx Max Nss That Supports
EHT-MCS 10-11: 2
.... .... 0010 .... .... .... = Tx Max Nss That Supports
EHT-MCS 10-11: 2
.... 0010 .... .... .... .... = Rx Max Nss That Supports
EHT-MCS 12-13: 2
0010 .... .... .... .... .... = Tx Max Nss That Supports
EHT-MCS 12-13: 2
EHT PPE Thresholds: <MISSING>
call stack of ieee80211_eht_cap_ie_to_sta_eht_cap():
RIP: 0010:ieee80211_eht_cap_ie_to_sta_eht_cap+0x5a/0x110 [mac80211]
[86593.088253] RSP: 0018:ffffb5fcc1f8f990 EFLAGS: 00010206
[86593.088254] RAX: 0000000000000000 RBX: ffff8c45c2fd6b70 RCX:
0000000000000000
[86593.088256] RDX: ffff8c45c2fd710e RSI: ffff8c44cba0a408 RDI:
ffff8c45c2fd6c30
[86593.088257] RBP: ffffb5fcc1f8f9c8 R08: ffff8c45c2fd7147 R09:
000000000000000e
[86593.088258] R10: ffff8c44cba0a408 R11: ffff8c45c2fd6bd8 R12:
ffff8c45cd0989c0
[86593.088259] R13: 0000000000000000 R14: ffff8c45c2fd7147 R15:
ffff8c45c8198000
[86593.088261] FS: 0000000000000000(0000) GS:ffff8c46d6200000(0000)
knlGS:0000000000000000
[86593.088262] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[86593.088264] CR2: 0000032d89c60000 CR3: 000000000800a006 CR4:
00000000001706f0
[86593.088265] Call Trace:
[86593.088267] <TASK>
[86593.088270] ieee80211_rx_mgmt_assoc_resp.cold+0xed8/0x1b9b [mac80211]
[86593.088336] ieee80211_sta_rx_queued_mgmt+0x351/0xdd0 [mac80211]
[86593.088394] ? newidle_balance+0x252/0x410
[86593.088399] ? dequeue_entity+0x125/0x400
[86593.088402] ? preempt_count_add+0x7c/0xc0
[86593.088406] ? _raw_spin_lock_irqsave+0x28/0x60
[86593.088410] ieee80211_iface_work+0x30a/0x410 [mac80211]
[86593.088459] ? __schedule+0x319/0x9b0
[86593.088461] process_one_work+0x227/0x440
[86593.088465] worker_thread+0x31/0x3e0
[86593.088467] ? process_one_work+0x440/0x440
[86593.088469] kthread+0xfe/0x130
[86593.088471] ? kthread_complete_and_exit+0x20/0x20
[86593.088473] ret_from_fork+0x22/0x30
[86593.088479] </TASK>
>
>> Also 20 MHz should be same for 5 GHz/6 GHz(MODE_11BE_EHT20) and 2.4
>> GHz(MODE_11BE_EHT20_2G), right?
>>
>
> Good point, I will add a check for MODE_11BE_EHT20_2G as well here.
>
>>> +
>>> + 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;
>>> + }
>>> +}
>>> +
>>
>> ...
>
On 6/15/2023 7:49 PM, Kalle Valo wrote:
> Aloka Dixit <[email protected]> writes:
>
[...]
> [...]
>
>> +struct ath12k_fw_pdev {
>> + u32 pdev_id;
>> + u32 phy_id;
>> + u32 supported_bands;
>> +};
> So we have now two very similar structures, ath12k_pdev and
> ath12k_fw_pdev. It would be good to document above the structs their
> purpose. Any ideas what I could add?
Currently ath12k has single_pdev parameter, it impact the interface
number of wifi.
For single_pdev=ture, ab->num_radios is set to 1 and all capbility of
2.4 GHz/
5 GHz/6 GHz is saved into ab->pdevs[0] in
ath12k_wmi_ext_soc_hal_reg_caps_parse().
ath12k_mac_register() will call only one time into
__ath12k_mac_register(), and
ieee80211_register_hw() is called only one time, and only one wifi
interface in
the result of "iw dev/ifconfig", the interface support 2.4 GHz/5 GHz/6
GHz. Actually
there hare more than one PHY in firmware, firmware maintain the all PHY
data and
provide a single pdev/soc interface to ath12k, then ath12k do not need
to consider
the PHY info such as channel/BAND<->PHY mapping relationship, it is
convenient for
ath12k to support 2.4 GHz/5 GHz/6 GHz.
For single_pdev=false, ab->num_radios is more than 1, ab->pdevs[] has
muti valid
element, each element only support one BAND. Firmware do not provide a
single
pdev/soc interface, so ath12k need to maintain the PHY data such as
channel/BAND<->
PHY mapping relationship, and ath12k_mac_register() will call muti-time
into
__ath12k_mac_register(), and ieee80211_register_hw() is called
muti-time, and muti
wifi interface in the result of "iw dev/ifconfig", and each interface
only support
one BAND, for example, wlan0 only support 2.4 GHz, wlan1 only support 5
GHz, and
wlan2 only support 6 GHz.
For single_pdev=ture, ath12k also need to know some info about the PHYs
sush as
pdev_id/phy_id/supported_bands in this patch, so ab->fw_pdev is used to
store the
PHY data.
On 7/25/2023 3:51 AM, Wen Gong wrote:
> On 6/15/2023 7:49 PM, Kalle Valo wrote:
>> Aloka Dixit <[email protected]> writes:
>>
> [...]
>> [...]
>>
>>> +struct ath12k_fw_pdev {
>>> + u32 pdev_id;
>>> + u32 phy_id;
>>> + u32 supported_bands;
>>> +};
>> So we have now two very similar structures, ath12k_pdev and
>> ath12k_fw_pdev. It would be good to document above the structs their
>> purpose. Any ideas what I could add?
> Currently ath12k has single_pdev parameter, it impact the interface
> number of wifi.
>
> For single_pdev=ture, ab->num_radios is set to 1 and all capbility of
> 2.4 GHz/
> 5 GHz/6 GHz is saved into ab->pdevs[0] in
> ath12k_wmi_ext_soc_hal_reg_caps_parse().
> ath12k_mac_register() will call only one time into
> __ath12k_mac_register(), and
> ieee80211_register_hw() is called only one time, and only one wifi
> interface in
> the result of "iw dev/ifconfig", the interface support 2.4 GHz/5 GHz/6
> GHz. Actually
> there hare more than one PHY in firmware, firmware maintain the all PHY
> data and
> provide a single pdev/soc interface to ath12k, then ath12k do not need
> to consider
> the PHY info such as channel/BAND<->PHY mapping relationship, it is
> convenient for
> ath12k to support 2.4 GHz/5 GHz/6 GHz.
>
> For single_pdev=false, ab->num_radios is more than 1, ab->pdevs[] has
> muti valid
> element, each element only support one BAND. Firmware do not provide a
> single
> pdev/soc interface, so ath12k need to maintain the PHY data such as
> channel/BAND<->
> PHY mapping relationship, and ath12k_mac_register() will call muti-time
> into
> __ath12k_mac_register(), and ieee80211_register_hw() is called
> muti-time, and muti
> wifi interface in the result of "iw dev/ifconfig", and each interface
> only support
> one BAND, for example, wlan0 only support 2.4 GHz, wlan1 only support 5
> GHz, and
> wlan2 only support 6 GHz.
>
> For single_pdev=ture, ath12k also need to know some info about the PHYs
> sush as
> pdev_id/phy_id/supported_bands in this patch, so ab->fw_pdev is used to
> store the
> PHY data.
The new struct ath12k_fw_pdev is anyway going to have as many elements
as the num_radio, right? Then there must be a way to reuse the common
struct ath12k_pdev instead as it done for QCN devices. I understand this
it will need changes to all the existing code for the single-pdev where
it might have hard-coded pdev[0] for the original structure. Something
to think about in a separate patch-set.
For now I will send new version with comments (as far as I understood
it) because without this patch WCN devices show a crash during boot-up.
Thanks.
On 7/25/2023 3:07 AM, Wen Gong wrote:
>
> For station mode of ath12k, the eht_cap->eht_mcs_nss_supp is from the IE
> "Supported
> EHT-MCS and NSS Set" in assoc resp of AP in function
> ieee80211_eht_cap_ie_to_sta_eht_cap().
> Now it is "EHT-MCS Map (BW <= 80MHz): 0x222222" for the AP(11BE-EHT mode
> for 20 MHz
> bandwidth on 6 GHz band) in my test as below IEs.
>
> The field only_20mhz and field _80 are union in struct
> ieee80211_eht_mcs_nss_supp, the
> value of field _80 is 0x222222 for this AP, then the value of field
> only_20mhz is like this:
> rx_tx_mcs7_max_nss=0x22,
> rx_tx_mcs9_max_nss=0x22,
> rx_tx_mcs11_max_nss=0x22,
> rx_tx_mcs13_max_nss=0.
>
> Then ath12k_mac_set_eht_mcs() will get value 0 fro mcs13 because it used
> the field only_20mhz
> passed by ath12k_peer_assoc_h_eht().
>
Understood, I fixed the default case to check for the he_cap field for
the bandwidth support instead of peer_phymode in v5.