summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKalle Valo <kvalo@kernel.org>2023-08-03 21:16:27 +0300
committerKalle Valo <kvalo@kernel.org>2023-08-03 21:16:27 +0300
commit904b102f1ebb67b91f1e90783a480fc473c986dd (patch)
treeb481a2e5498f7de4b80abb7d101f2b7ede869c4a
parentdd59c6a32b7189f51947edc5b15939367729dd85 (diff)
parent8198950ccb7d311f8b4389441d8dcb597f926340 (diff)
Merge ath-next from git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
ath.git patches for v6.6. Major changes: ath12k * Extremely High Throughput (EHT) PHY support for Wi-Fi 7
-rw-r--r--drivers/net/wireless/ath/ath11k/ahb.c29
-rw-r--r--drivers/net/wireless/ath/ath11k/core.c38
-rw-r--r--drivers/net/wireless/ath/ath11k/core.h1
-rw-r--r--drivers/net/wireless/ath/ath11k/dp_rx.c2
-rw-r--r--drivers/net/wireless/ath/ath11k/hw.h3
-rw-r--r--drivers/net/wireless/ath/ath11k/mac.c4
-rw-r--r--drivers/net/wireless/ath/ath11k/pci.c2
-rw-r--r--drivers/net/wireless/ath/ath11k/qmi.c34
-rw-r--r--drivers/net/wireless/ath/ath11k/qmi.h3
-rw-r--r--drivers/net/wireless/ath/ath12k/core.h34
-rw-r--r--drivers/net/wireless/ath/ath12k/dp_rx.c11
-rw-r--r--drivers/net/wireless/ath/ath12k/dp_tx.c8
-rw-r--r--drivers/net/wireless/ath/ath12k/mac.c589
-rw-r--r--drivers/net/wireless/ath/ath12k/mac.h2
-rw-r--r--drivers/net/wireless/ath/ath12k/qmi.c2
-rw-r--r--drivers/net/wireless/ath/ath12k/wmi.c260
-rw-r--r--drivers/net/wireless/ath/ath12k/wmi.h119
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.c2
-rw-r--r--drivers/net/wireless/ath/ath6kl/debug.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ahb.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h6
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c6
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c2
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.h6
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx_edma.c2
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx_edma.h6
27 files changed, 991 insertions, 190 deletions
diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c
index 1cebba7889d7..b0a40970bada 100644
--- a/drivers/net/wireless/ath/ath11k/ahb.c
+++ b/drivers/net/wireless/ath/ath11k/ahb.c
@@ -14,6 +14,7 @@
#include "ahb.h"
#include "debug.h"
#include "hif.h"
+#include "qmi.h"
#include <linux/remoteproc.h>
#include "pcic.h"
#include <linux/soc/qcom/smem.h>
@@ -419,32 +420,6 @@ static void ath11k_ahb_power_down(struct ath11k_base *ab)
rproc_shutdown(ab_ahb->tgt_rproc);
}
-static int ath11k_ahb_fwreset_from_cold_boot(struct ath11k_base *ab)
-{
- int timeout;
-
- if (ath11k_cold_boot_cal == 0 || ab->qmi.cal_done ||
- ab->hw_params.cold_boot_calib == 0 ||
- ab->hw_params.cbcal_restart_fw == 0)
- return 0;
-
- ath11k_dbg(ab, ATH11K_DBG_AHB, "wait for cold boot done\n");
- timeout = wait_event_timeout(ab->qmi.cold_boot_waitq,
- (ab->qmi.cal_done == 1),
- ATH11K_COLD_BOOT_FW_RESET_DELAY);
- if (timeout <= 0) {
- ath11k_cold_boot_cal = 0;
- ath11k_warn(ab, "Coldboot Calibration failed timed out\n");
- }
-
- /* reset the firmware */
- ath11k_ahb_power_down(ab);
- ath11k_ahb_power_up(ab);
-
- ath11k_dbg(ab, ATH11K_DBG_AHB, "exited from cold boot mode\n");
- return 0;
-}
-
static void ath11k_ahb_init_qmi_ce_config(struct ath11k_base *ab)
{
struct ath11k_qmi_ce_cfg *cfg = &ab->qmi.ce_cfg;
@@ -1227,7 +1202,7 @@ static int ath11k_ahb_probe(struct platform_device *pdev)
goto err_ce_free;
}
- ath11k_ahb_fwreset_from_cold_boot(ab);
+ ath11k_qmi_fwreset_from_cold_boot(ab);
return 0;
diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
index bebfd342e28b..fc7c4564a715 100644
--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
@@ -86,7 +86,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.supports_shadow_regs = false,
.idle_ps = false,
.supports_sta_ps = false,
- .cold_boot_calib = true,
+ .coldboot_cal_mm = true,
+ .coldboot_cal_ftm = true,
.cbcal_restart_fw = true,
.fw_mem_mode = 0,
.num_vdevs = 16 + 1,
@@ -167,7 +168,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.supports_shadow_regs = false,
.idle_ps = false,
.supports_sta_ps = false,
- .cold_boot_calib = true,
+ .coldboot_cal_mm = true,
+ .coldboot_cal_ftm = true,
.cbcal_restart_fw = true,
.fw_mem_mode = 0,
.num_vdevs = 16 + 1,
@@ -248,7 +250,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.supports_shadow_regs = true,
.idle_ps = true,
.supports_sta_ps = true,
- .cold_boot_calib = false,
+ .coldboot_cal_mm = false,
+ .coldboot_cal_ftm = false,
.cbcal_restart_fw = false,
.fw_mem_mode = 0,
.num_vdevs = 16 + 1,
@@ -332,8 +335,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.supports_shadow_regs = false,
.idle_ps = false,
.supports_sta_ps = false,
- .cold_boot_calib = false,
- .cbcal_restart_fw = false,
+ .coldboot_cal_mm = false,
+ .coldboot_cal_ftm = true,
+ .cbcal_restart_fw = true,
.fw_mem_mode = 2,
.num_vdevs = 8,
.num_peers = 128,
@@ -413,7 +417,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.supports_shadow_regs = true,
.idle_ps = true,
.supports_sta_ps = true,
- .cold_boot_calib = false,
+ .coldboot_cal_mm = false,
+ .coldboot_cal_ftm = false,
.cbcal_restart_fw = false,
.fw_mem_mode = 0,
.num_vdevs = 16 + 1,
@@ -495,7 +500,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.supports_shadow_regs = true,
.idle_ps = true,
.supports_sta_ps = true,
- .cold_boot_calib = false,
+ .coldboot_cal_mm = false,
+ .coldboot_cal_ftm = false,
.cbcal_restart_fw = false,
.fw_mem_mode = 0,
.num_vdevs = 16 + 1,
@@ -578,7 +584,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.supports_shadow_regs = true,
.idle_ps = true,
.supports_sta_ps = true,
- .cold_boot_calib = true,
+ .coldboot_cal_mm = true,
+ .coldboot_cal_ftm = true,
.cbcal_restart_fw = false,
.fw_mem_mode = 0,
.num_vdevs = 16 + 1,
@@ -667,7 +674,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.supports_suspend = false,
.hal_params = &ath11k_hw_hal_params_ipq8074,
.single_pdev_only = false,
- .cold_boot_calib = true,
+ .coldboot_cal_mm = true,
+ .coldboot_cal_ftm = true,
.cbcal_restart_fw = true,
.fix_l1ss = true,
.supports_dynamic_smps_6ghz = false,
@@ -749,6 +757,18 @@ void ath11k_fw_stats_free(struct ath11k_fw_stats *stats)
ath11k_fw_stats_bcn_free(&stats->bcn);
}
+bool ath11k_core_coldboot_cal_support(struct ath11k_base *ab)
+{
+ if (!ath11k_cold_boot_cal)
+ return false;
+
+ if (ath11k_ftm_mode)
+ return ab->hw_params.coldboot_cal_ftm;
+
+ else
+ return ab->hw_params.coldboot_cal_mm;
+}
+
int ath11k_core_suspend(struct ath11k_base *ab)
{
int ret;
diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h
index 9d15b4390b9c..b04447762483 100644
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -1186,6 +1186,7 @@ void ath11k_core_halt(struct ath11k *ar);
int ath11k_core_resume(struct ath11k_base *ab);
int ath11k_core_suspend(struct ath11k_base *ab);
void ath11k_core_pre_reconfigure_recovery(struct ath11k_base *ab);
+bool ath11k_core_coldboot_cal_support(struct ath11k_base *ab);
const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab,
const char *filename);
diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
index 5c76664ba0dd..1e488eed282b 100644
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -2408,7 +2408,7 @@ static void ath11k_dp_rx_h_ppdu(struct ath11k *ar, struct hal_rx_desc *rx_desc,
rx_status->freq = center_freq;
} else if (channel_num >= 1 && channel_num <= 14) {
rx_status->band = NL80211_BAND_2GHZ;
- } else if (channel_num >= 36 && channel_num <= 173) {
+ } else if (channel_num >= 36 && channel_num <= 177) {
rx_status->band = NL80211_BAND_5GHZ;
} else {
spin_lock_bh(&ar->data_lock);
diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h
index f5533630a7f9..d51a99669dd6 100644
--- a/drivers/net/wireless/ath/ath11k/hw.h
+++ b/drivers/net/wireless/ath/ath11k/hw.h
@@ -187,7 +187,8 @@ struct ath11k_hw_params {
bool supports_shadow_regs;
bool idle_ps;
bool supports_sta_ps;
- bool cold_boot_calib;
+ bool coldboot_cal_mm;
+ bool coldboot_cal_ftm;
bool cbcal_restart_fw;
int fw_mem_mode;
u32 num_vdevs;
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index 8c77ade49437..2aadf2c387b6 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -8255,7 +8255,7 @@ ath11k_mac_validate_vht_he_fixed_rate_settings(struct ath11k *ar, enum nl80211_b
const struct cfg80211_bitrate_mask *mask)
{
bool he_fixed_rate = false, vht_fixed_rate = false;
- struct ath11k_peer *peer, *tmp;
+ struct ath11k_peer *peer;
const u16 *vht_mcs_mask, *he_mcs_mask;
struct ieee80211_link_sta *deflink;
u8 vht_nss, he_nss;
@@ -8278,7 +8278,7 @@ ath11k_mac_validate_vht_he_fixed_rate_settings(struct ath11k *ar, enum nl80211_b
rcu_read_lock();
spin_lock_bh(&ar->ab->base_lock);
- list_for_each_entry_safe(peer, tmp, &ar->ab->peers, list) {
+ list_for_each_entry(peer, &ar->ab->peers, list) {
if (peer->sta) {
deflink = &peer->sta->deflink;
diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c
index 79e2cbe82638..5fd08ffc2a9f 100644
--- a/drivers/net/wireless/ath/ath11k/pci.c
+++ b/drivers/net/wireless/ath/ath11k/pci.c
@@ -15,6 +15,7 @@
#include "mhi.h"
#include "debug.h"
#include "pcic.h"
+#include "qmi.h"
#define ATH11K_PCI_BAR_NUM 0
#define ATH11K_PCI_DMA_MASK 32
@@ -897,6 +898,7 @@ unsupported_wcn6855_soc:
ath11k_err(ab, "failed to init core: %d\n", ret);
goto err_irq_affinity_cleanup;
}
+ ath11k_qmi_fwreset_from_cold_boot(ab);
return 0;
err_irq_affinity_cleanup:
diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c
index 98efa0f299ca..41fad03a3025 100644
--- a/drivers/net/wireless/ath/ath11k/qmi.c
+++ b/drivers/net/wireless/ath/ath11k/qmi.c
@@ -9,6 +9,7 @@
#include "qmi.h"
#include "core.h"
#include "debug.h"
+#include "hif.h"
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/ioport.h>
@@ -2078,7 +2079,7 @@ static int ath11k_qmi_assign_target_mem_chunk(struct ath11k_base *ab)
return -EINVAL;
}
- if (ath11k_cold_boot_cal && ab->hw_params.cold_boot_calib) {
+ if (ath11k_core_coldboot_cal_support(ab)) {
if (hremote_node) {
ab->qmi.target_mem[idx].paddr =
res.start + host_ddr_sz;
@@ -2838,6 +2839,33 @@ int ath11k_qmi_firmware_start(struct ath11k_base *ab,
return 0;
}
+int ath11k_qmi_fwreset_from_cold_boot(struct ath11k_base *ab)
+{
+ int timeout;
+
+ if (!ath11k_core_coldboot_cal_support(ab) ||
+ ab->hw_params.cbcal_restart_fw == 0)
+ return 0;
+
+ ath11k_dbg(ab, ATH11K_DBG_QMI, "wait for cold boot done\n");
+
+ timeout = wait_event_timeout(ab->qmi.cold_boot_waitq,
+ (ab->qmi.cal_done == 1),
+ ATH11K_COLD_BOOT_FW_RESET_DELAY);
+
+ if (timeout <= 0) {
+ ath11k_warn(ab, "Coldboot Calibration timed out\n");
+ return -ETIMEDOUT;
+ }
+
+ /* reset the firmware */
+ ath11k_hif_power_down(ab);
+ ath11k_hif_power_up(ab);
+ ath11k_dbg(ab, ATH11K_DBG_QMI, "exit wait for cold boot done\n");
+ return 0;
+}
+EXPORT_SYMBOL(ath11k_qmi_fwreset_from_cold_boot);
+
static int ath11k_qmi_process_coldboot_calibration(struct ath11k_base *ab)
{
int timeout;
@@ -3208,8 +3236,8 @@ static void ath11k_qmi_driver_event_work(struct work_struct *work)
break;
}
- if (ath11k_cold_boot_cal && ab->qmi.cal_done == 0 &&
- ab->hw_params.cold_boot_calib) {
+ if (ab->qmi.cal_done == 0 &&
+ ath11k_core_coldboot_cal_support(ab)) {
ath11k_qmi_process_coldboot_calibration(ab);
} else {
clear_bit(ATH11K_FLAG_CRASH_FLUSH,
diff --git a/drivers/net/wireless/ath/ath11k/qmi.h b/drivers/net/wireless/ath/ath11k/qmi.h
index 0909d53cefeb..b0407abf90cd 100644
--- a/drivers/net/wireless/ath/ath11k/qmi.h
+++ b/drivers/net/wireless/ath/ath11k/qmi.h
@@ -37,7 +37,7 @@
#define QMI_WLANFW_MAX_DATA_SIZE_V01 6144
#define ATH11K_FIRMWARE_MODE_OFF 4
-#define ATH11K_COLD_BOOT_FW_RESET_DELAY (40 * HZ)
+#define ATH11K_COLD_BOOT_FW_RESET_DELAY (60 * HZ)
#define ATH11K_QMI_DEVICE_BAR_SIZE 0x200000
@@ -519,5 +519,6 @@ void ath11k_qmi_msg_recv_work(struct work_struct *work);
void ath11k_qmi_deinit_service(struct ath11k_base *ab);
int ath11k_qmi_init_service(struct ath11k_base *ab);
void ath11k_qmi_free_resource(struct ath11k_base *ab);
+int ath11k_qmi_fwreset_from_cold_boot(struct ath11k_base *ab);
#endif
diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h
index 2f93296db792..4389ff40b49d 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 {
@@ -580,6 +581,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 {
@@ -614,6 +623,12 @@ struct ath12k_pdev {
struct mlo_timestamp timestamp;
};
+struct ath12k_fw_pdev {
+ u32 pdev_id;
+ u32 phy_id;
+ u32 supported_bands;
+};
+
struct ath12k_board_data {
const struct firmware *fw;
const void *data;
@@ -669,7 +684,26 @@ struct ath12k_base {
struct mutex core_lock;
/* Protects data like peers */
spinlock_t base_lock;
+
+ /* Single pdev device (struct ath12k_hw_params::single_pdev_only):
+ *
+ * Firmware maintains data for all bands but advertises a single
+ * phy to the host which is stored as a single element in this
+ * array.
+ *
+ * Other devices:
+ *
+ * This array will contain as many elements as the number of
+ * radios.
+ */
struct ath12k_pdev pdevs[MAX_RADIOS];
+
+ /* struct ath12k_hw_params::single_pdev_only devices use this to
+ * store phy specific data
+ */
+ 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/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
index ffd9a2018610..67f8c140840f 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
@@ -2539,7 +2539,7 @@ static void ath12k_dp_rx_process_received_packets(struct ath12k_base *ab,
struct ath12k_skb_rxcb *rxcb;
struct sk_buff *msdu;
struct ath12k *ar;
- u8 mac_id;
+ u8 mac_id, pdev_id;
int ret;
if (skb_queue_empty(msdu_list))
@@ -2550,8 +2550,9 @@ static void ath12k_dp_rx_process_received_packets(struct ath12k_base *ab,
while ((msdu = __skb_dequeue(msdu_list))) {
rxcb = ATH12K_SKB_RXCB(msdu);
mac_id = rxcb->mac_id;
- ar = ab->pdevs[mac_id].ar;
- if (!rcu_dereference(ab->pdevs_active[mac_id])) {
+ pdev_id = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, mac_id);
+ ar = ab->pdevs[pdev_id].ar;
+ if (!rcu_dereference(ab->pdevs_active[pdev_id])) {
dev_kfree_skb_any(msdu);
continue;
}
@@ -3385,6 +3386,7 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi,
dma_addr_t paddr;
bool is_frag;
bool drop = false;
+ int pdev_id;
tot_n_bufs_reaped = 0;
quota = budget;
@@ -3440,7 +3442,8 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi,
mac_id = le32_get_bits(reo_desc->info0,
HAL_REO_DEST_RING_INFO0_SRC_LINK_ID);
- ar = ab->pdevs[mac_id].ar;
+ pdev_id = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, mac_id);
+ ar = ab->pdevs[pdev_id].ar;
if (!ath12k_dp_process_rx_err_buf(ar, reo_desc, drop,
msdu_cookies[i]))
diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c
index d3c7c76d6b75..d661fe586651 100644
--- a/drivers/net/wireless/ath/ath12k/dp_tx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_tx.c
@@ -347,6 +347,7 @@ static void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab,
{
struct ath12k *ar;
struct ath12k_skb_cb *skb_cb;
+ u8 pdev_id = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, mac_id);
skb_cb = ATH12K_SKB_CB(msdu);
@@ -357,7 +358,7 @@ static void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab,
dev_kfree_skb_any(msdu);
- ar = ab->pdevs[mac_id].ar;
+ ar = ab->pdevs[pdev_id].ar;
if (atomic_dec_and_test(&ar->dp.num_tx_pending))
wake_up(&ar->dp.tx_empty_waitq);
}
@@ -536,7 +537,7 @@ void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id)
struct hal_tx_status ts = { 0 };
struct dp_tx_ring *tx_ring = &dp->tx_ring[ring_id];
struct hal_wbm_release_ring *desc;
- u8 mac_id;
+ u8 mac_id, pdev_id;
u64 desc_va;
spin_lock_bh(&status_ring->lock);
@@ -605,7 +606,8 @@ void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id)
continue;
}
- ar = ab->pdevs[mac_id].ar;
+ pdev_id = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, mac_id);
+ ar = ab->pdevs[pdev_id].ar;
if (atomic_dec_and_test(&ar->dp.num_tx_pending))
wake_up(&ar->dp.tx_empty_waitq);
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index 1bb9802ef569..0f2af2f14ef7 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;
@@ -821,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);
@@ -1637,9 +1659,9 @@ static void ath12k_peer_assoc_h_he(struct ath12k *ar,
arg->peer_nss = min(sta->deflink.rx_nss, max_nss);
memcpy(&arg->peer_he_cap_macinfo, he_cap->he_cap_elem.mac_cap_info,
- sizeof(arg->peer_he_cap_macinfo));
+ sizeof(he_cap->he_cap_elem.mac_cap_info));
memcpy(&arg->peer_he_cap_phyinfo, he_cap->he_cap_elem.phy_cap_info,
- sizeof(arg->peer_he_cap_phyinfo));
+ sizeof(he_cap->he_cap_elem.phy_cap_info));
arg->peer_he_ops = vif->bss_conf.he_oper.params;
/* the top most byte is used to indicate BSS color info */
@@ -1929,6 +1951,41 @@ 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 capability info for 160 Mhz: %d\n",
+ sta->deflink.he_cap.he_cap_elem.phy_cap_info[0]);
+
+ 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 +2007,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 +2039,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)) {
@@ -2004,6 +2068,152 @@ 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;
+ 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)
+ 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;
+ }
+
+ arg->punct_bitmap = ~arvif->punct_bitmap;
+}
+
static void ath12k_peer_assoc_prepare(struct ath12k *ar,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
@@ -2023,6 +2233,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);
@@ -2554,6 +2765,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);
}
@@ -2755,9 +2969,12 @@ static int ath12k_mac_op_hw_scan(struct ieee80211_hw *hw,
arg.scan_id = ATH12K_SCAN_ID;
if (req->ie_len) {
+ arg.extraie.ptr = kmemdup(req->ie, req->ie_len, GFP_KERNEL);
+ if (!arg.extraie.ptr) {
+ ret = -ENOMEM;
+ goto exit;
+ }
arg.extraie.len = req->ie_len;
- arg.extraie.ptr = kzalloc(req->ie_len, GFP_KERNEL);
- memcpy(arg.extraie.ptr, req->ie, req->ie_len);
}
if (req->n_ssids) {
@@ -2770,6 +2987,14 @@ static int ath12k_mac_op_hw_scan(struct ieee80211_hw *hw,
if (req->n_channels) {
arg.num_chan = req->n_channels;
+ arg.chan_list = kcalloc(arg.num_chan, sizeof(*arg.chan_list),
+ GFP_KERNEL);
+
+ if (!arg.chan_list) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+
for (i = 0; i < arg.num_chan; i++)
arg.chan_list[i] = req->channels[i]->center_freq;
}
@@ -2788,6 +3013,8 @@ static int ath12k_mac_op_hw_scan(struct ieee80211_hw *hw,
ATH12K_MAC_SCAN_TIMEOUT_MSECS));
exit:
+ kfree(arg.chan_list);
+
if (req->ie_len)
kfree(arg.extraie.ptr);
@@ -4209,18 +4436,178 @@ 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 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 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_ppe_thresh(struct ath12k_wmi_ppe_threshold_arg *fw_ppet,
+ struct ieee80211_sta_eht_cap *cap)
+{
+ u16 bit = IEEE80211_EHT_PPE_THRES_INFO_HEADER_SIZE;
+ u8 i, nss, ru, ppet_bit_len_per_ru = IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE * 2;
+
+ 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 < hweight16(IEEE80211_EHT_PPE_THRES_RU_INDEX_BITMASK_MASK);
+ ru++) {
+ u32 val = 0;
+
+ if ((fw_ppet->ru_bit_mask & BIT(ru)) == 0)
+ continue;
+
+ u32p_replace_bits(&val, fw_ppet->ppet16_ppet8_ru3_ru0[nss] >>
+ (ru * ppet_bit_len_per_ru),
+ GENMASK(ppet_bit_len_per_ru - 1, 0));
+
+ for (i = 0; i < ppet_bit_len_per_ru; i++) {
+ cap->eht_ppe_thres[bit / 8] |=
+ (((val >> i) & 0x1) << ((bit % 8)));
+ bit++;
+ }
+ }
+ }
+}
+
+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,
+ 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,102 +4620,56 @@ static int ath12k_mac_copy_he_cap(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);
}
+ ath12k_mac_copy_eht_cap(band_cap, &he_cap->he_cap_elem, i,
+ &data[idx].eht_cap);
idx++;
}
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 +4714,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;
}
@@ -5201,7 +5542,7 @@ err:
static void ath12k_mac_vif_unref(struct ath12k_dp *dp, struct ieee80211_vif *vif)
{
- struct ath12k_tx_desc_info *tx_desc_info, *tmp1;
+ struct ath12k_tx_desc_info *tx_desc_info;
struct ath12k_skb_cb *skb_cb;
struct sk_buff *skb;
int i;
@@ -5209,8 +5550,8 @@ static void ath12k_mac_vif_unref(struct ath12k_dp *dp, struct ieee80211_vif *vif
for (i = 0; i < ATH12K_HW_MAX_QUEUES; i++) {
spin_lock_bh(&dp->tx_desc_lock[i]);
- list_for_each_entry_safe(tx_desc_info, tmp1, &dp->tx_desc_used_list[i],
- list) {
+ list_for_each_entry(tx_desc_info, &dp->tx_desc_used_list[i],
+ list) {
skb = tx_desc_info->skb;
if (!skb)
continue;
@@ -5466,6 +5807,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;
@@ -5508,9 +5850,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) {
@@ -5837,6 +6179,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 &&
@@ -6388,6 +6732,7 @@ ath12k_mac_op_reconfig_complete(struct ieee80211_hw *hw,
{
struct ath12k *ar = hw->priv;
struct ath12k_base *ab = ar->ab;
+ struct ath12k_vif *arvif;
int recovery_count;
if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)
@@ -6416,6 +6761,26 @@ ath12k_mac_op_reconfig_complete(struct ieee80211_hw *hw,
ath12k_dbg(ab, ATH12K_DBG_BOOT, "reset success\n");
}
}
+
+ list_for_each_entry(arvif, &ar->arvifs, list) {
+ ath12k_dbg(ab, ATH12K_DBG_BOOT,
+ "reconfig cipher %d up %d vdev type %d\n",
+ arvif->key_cipher,
+ arvif->is_up,
+ arvif->vdev_type);
+ /* After trigger disconnect, then upper layer will
+ * trigger connect again, then the PN number of
+ * upper layer will be reset to keep up with AP
+ * side, hence PN number mis-match will not happened.
+ */
+ if (arvif->is_up &&
+ arvif->vdev_type == WMI_VDEV_TYPE_STA &&
+ arvif->vdev_subtype == WMI_VDEV_SUBTYPE_NONE) {
+ ieee80211_hw_restart_disconnect(arvif->vif);
+ ath12k_dbg(ab, ATH12K_DBG_BOOT,
+ "restart disconnect\n");
+ }
+ }
}
mutex_unlock(&ar->conf_mutex);
@@ -6854,7 +7219,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) {
@@ -6943,6 +7308,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/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/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c
index b510c2de1bd4..b2db0436bdde 100644
--- a/drivers/net/wireless/ath/ath12k/qmi.c
+++ b/drivers/net/wireless/ath/ath12k/qmi.c
@@ -387,7 +387,7 @@ static struct qmi_elem_info qmi_wlanfw_host_cap_req_msg_v01_ei[] = {
mlo_capable_valid),
},
{
- .data_type = QMI_OPT_FLAG,
+ .data_type = QMI_UNSIGNED_1_BYTE,
.elem_len = 1,
.elem_size = sizeof(u8),
.array_type = NO_ARRAY,
diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index 6512267ae4ca..9ed33e2d6da0 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -62,9 +62,27 @@ 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;
+ bool mac_phy_caps_ext_done;
};
struct ath12k_wmi_rdy_parse {
@@ -445,8 +463,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 +495,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.
@@ -995,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) {
@@ -1791,6 +1818,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)
@@ -1805,6 +1833,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
@@ -1832,6 +1862,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
@@ -1876,6 +1908,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;
@@ -1892,7 +1925,9 @@ 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) +
+ TLV_HDR_SIZE + TLV_HDR_SIZE;
skb = ath12k_wmi_alloc_skb(wmi->wmi_ab, len);
if (!skb)
@@ -1908,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,
@@ -1939,6 +1975,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);
@@ -2005,8 +2051,36 @@ 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;
+ 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);
+ }
+
+ /* 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\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,
@@ -2016,7 +2090,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) {
@@ -3705,6 +3782,10 @@ static int ath12k_wmi_hw_mode_caps(struct ath12k_base *soc,
for (i = 0 ; i < svc_rdy_ext->n_hw_mode_caps; i++) {
hw_mode_caps = &svc_rdy_ext->hw_mode_caps[i];
mode = le32_to_cpu(hw_mode_caps->hw_mode_id);
+
+ if (mode >= WMI_HOST_HW_MODE_MAX)
+ continue;
+
pref = soc->wmi_ab.preferred_hw_mode;
if (ath12k_hw_mode_pri_map[mode] < ath12k_hw_mode_pri_map[pref]) {
@@ -3811,6 +3892,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,14 +4120,165 @@ err:
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,
+ const __le32 cap_mac_info[],
+ const __le32 cap_phy_info[],
+ const __le32 supp_mcs[],
+ const 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,
+ const struct ath12k_wmi_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)
+{
+ const struct ath12k_wmi_caps_ext_params *caps = 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 parse extended MAC PHY capabilities for pdev %d: %d\n",
+ ret, 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)
{
+ 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,
@@ -4054,6 +4287,23 @@ 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 extended MAC PHY capabilities WMI TLV: %d\n",
+ ret);
+ return ret;
+ }
+
+ parse->mac_phy_caps_ext_done = true;
}
break;
default:
@@ -5223,7 +5473,7 @@ static int ath12k_reg_chan_list_event(struct ath12k_base *ab, struct sk_buff *sk
ar = ab->pdevs[pdev_idx].ar;
kfree(ab->new_regd[pdev_idx]);
ab->new_regd[pdev_idx] = regd;
- ieee80211_queue_work(ar->hw, &ar->regd_update_work);
+ queue_work(ab->workqueue, &ar->regd_update_work);
} else {
/* Multiple events for the same *ar is not expected. But we
* can still clear any previously stored default_regd if we
@@ -5698,6 +5948,8 @@ static void ath12k_scan_event(struct ath12k_base *ab, struct sk_buff *skb)
ath12k_wmi_event_scan_start_failed(ar);
break;
case WMI_SCAN_EVENT_DEQUEUED:
+ __ath12k_mac_scan_finish(ar);
+ break;
case WMI_SCAN_EVENT_PREEMPTED:
case WMI_SCAN_EVENT_RESTARTED:
case WMI_SCAN_EVENT_FOREIGN_CHAN_EXIT:
diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h
index d89c12bfb009..8c047a9623f9 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.h
+++ b/drivers/net/wireless/ath/ath12k/wmi.h
@@ -1167,6 +1167,11 @@ enum wmi_tlv_peer_flags {
};
+enum wmi_tlv_peer_flags_ext {
+ WMI_PEER_EXT_EHT = BIT(0),
+ WMI_PEER_EXT_320MHZ = BIT(1),
+};
+
/** Enum list of TLV Tags for each parameter structure type. */
enum wmi_tlv_tag {
WMI_TAG_LAST_RESERVED = 15,
@@ -1920,10 +1925,12 @@ 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,
WMI_TAG_REG_CHAN_LIST_CC_EXT_EVENT,
+ WMI_TAG_EHT_RATE_SET = 0x3C4,
WMI_TAG_MAX
};
@@ -2581,6 +2588,69 @@ 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
+#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.
+ *
+ * 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
+
+#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 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_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];
@@ -2705,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
@@ -2758,8 +2833,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 {
@@ -2795,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 {
@@ -3034,7 +3122,6 @@ enum scan_dwelltime_adaptive_mode {
#define WLAN_SCAN_MAX_NUM_SSID 10
#define WLAN_SCAN_MAX_NUM_BSSID 10
-#define WLAN_SCAN_MAX_NUM_CHANNELS 40
struct ath12k_wmi_element_info_arg {
u32 len;
@@ -3243,7 +3330,7 @@ struct ath12k_wmi_scan_req_arg {
u32 num_bssid;
u32 num_ssids;
u32 n_probes;
- u32 chan_list[WLAN_SCAN_MAX_NUM_CHANNELS];
+ u32 *chan_list;
u32 notify_scan_events;
struct cfg80211_ssid ssid[WLAN_SCAN_MAX_NUM_SSID];
struct ath12k_wmi_mac_addr_params bssid_list[WLAN_SCAN_MAX_NUM_BSSID];
@@ -3491,6 +3578,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;
@@ -3518,6 +3606,14 @@ 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;
+ u32 punct_bitmap;
};
struct wmi_peer_assoc_complete_cmd {
@@ -3549,6 +3645,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 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;
+ struct ath12k_wmi_ppe_threshold_params peer_eht_ppet;
} __packed;
struct wmi_stop_scan_cmd {
@@ -3776,6 +3881,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
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
index 4b41160e5d38..ec130510aeb2 100644
--- a/drivers/net/wireless/ath/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
@@ -982,8 +982,6 @@ ath5k_debug_init_device(struct ath5k_hw *ah)
ah->debug.level = ath5k_debug;
phydir = debugfs_create_dir("ath5k", ah->hw->wiphy->debugfsdir);
- if (!phydir)
- return;
debugfs_create_file("debug", 0600, phydir, ah, &fops_debug);
debugfs_create_file("registers", 0400, phydir, ah, &registers_fops);
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index 433a047f3747..b837d31416df 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -1793,8 +1793,6 @@ int ath6kl_debug_init_fs(struct ath6kl *ar)
{
ar->debugfs_phy = debugfs_create_dir("ath6kl",
ar->wiphy->debugfsdir);
- if (!ar->debugfs_phy)
- return -ENOMEM;
debugfs_create_file("tgt_stats", 0400, ar->debugfs_phy, ar,
&fops_tgt_stats);
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
index 9cd12b20b18d..9bfaadfa6c00 100644
--- a/drivers/net/wireless/ath/ath9k/ahb.c
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
@@ -132,8 +132,8 @@ static int ath_ahb_probe(struct platform_device *pdev)
ah = sc->sc_ah;
ath9k_hw_name(ah, hw_name, sizeof(hw_name));
- wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n",
- hw_name, (unsigned long)mem, irq);
+ wiphy_info(hw->wiphy, "%s mem=0x%p, irq=%d\n",
+ hw_name, mem, irq);
return 0;
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index af44b33814dd..f03d792732da 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -115,8 +115,10 @@ struct ath_tx_status {
u8 qid;
u16 desc_id;
u8 tid;
- u32 ba_low;
- u32 ba_high;
+ struct_group(ba,
+ u32 ba_low;
+ u32 ba_high;
+ );
u32 evm0;
u32 evm1;
u32 evm2;
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index a09f9d223f3d..0633589b85c2 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -988,8 +988,8 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
sc->sc_ah->msi_reg = 0;
ath9k_hw_name(sc->sc_ah, hw_name, sizeof(hw_name));
- wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n",
- hw_name, (unsigned long)sc->mem, pdev->irq);
+ wiphy_info(hw->wiphy, "%s mem=0x%p, irq=%d\n",
+ hw_name, sc->mem, pdev->irq);
return 0;
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index f6f2ab7a63ff..4e939dcac1c9 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -466,9 +466,11 @@ static void ath_tx_count_frames(struct ath_softc *sc, struct ath_buf *bf,
*nframes = 0;
isaggr = bf_isaggr(bf);
+ memset(ba, 0, WME_BA_BMP_SIZE >> 3);
+
if (isaggr) {
seq_st = ts->ts_seqnum;
- memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3);
+ memcpy(ba, &ts->ba, WME_BA_BMP_SIZE >> 3);
}
while (bf) {
@@ -551,7 +553,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
if (isaggr && txok) {
if (ts->ts_flags & ATH9K_TX_BA) {
seq_st = ts->ts_seqnum;
- memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3);
+ memcpy(ba, &ts->ba, WME_BA_BMP_SIZE >> 3);
} else {
/*
* AR5416 can become deaf/mute when BA
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 237cbd5c5060..f29ac6de7139 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -666,7 +666,7 @@ static int wil_rx_crypto_check(struct wil6210_priv *wil, struct sk_buff *skb)
struct wil_tid_crypto_rx *c = mc ? &s->group_crypto_rx :
&s->tid_crypto_rx[tid];
struct wil_tid_crypto_rx_single *cc = &c->key_id[key_id];
- const u8 *pn = (u8 *)&d->mac.pn_15_0;
+ const u8 *pn = (u8 *)&d->mac.pn;
if (!cc->key_set) {
wil_err_ratelimited(wil,
diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h
index 1ae1bec1b97f..689f68d89a44 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.h
+++ b/drivers/net/wireless/ath/wil6210/txrx.h
@@ -343,8 +343,10 @@ struct vring_rx_mac {
u32 d0;
u32 d1;
u16 w4;
- u16 pn_15_0;
- u32 pn_47_16;
+ struct_group_attr(pn, __packed,
+ u16 pn_15_0;
+ u32 pn_47_16;
+ );
} __packed;
/* Rx descriptor - DMA part
diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.c b/drivers/net/wireless/ath/wil6210/txrx_edma.c
index 201c8c35e0c9..1ba1f21ebea2 100644
--- a/drivers/net/wireless/ath/wil6210/txrx_edma.c
+++ b/drivers/net/wireless/ath/wil6210/txrx_edma.c
@@ -548,7 +548,7 @@ static int wil_rx_crypto_check_edma(struct wil6210_priv *wil,
s = &wil->sta[cid];
c = mc ? &s->group_crypto_rx : &s->tid_crypto_rx[tid];
cc = &c->key_id[key_id];
- pn = (u8 *)&st->ext.pn_15_0;
+ pn = (u8 *)&st->ext.pn;
if (!cc->key_set) {
wil_err_ratelimited(wil,
diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.h b/drivers/net/wireless/ath/wil6210/txrx_edma.h
index c736f7413a35..ee90e225bb05 100644
--- a/drivers/net/wireless/ath/wil6210/txrx_edma.h
+++ b/drivers/net/wireless/ath/wil6210/txrx_edma.h
@@ -330,8 +330,10 @@ struct wil_rx_status_extension {
u32 d0;
u32 d1;
__le16 seq_num; /* only lower 12 bits */
- u16 pn_15_0;
- u32 pn_47_16;
+ struct_group_attr(pn, __packed,
+ u16 pn_15_0;
+ u32 pn_47_16;
+ );
} __packed;
struct wil_rx_status_extended {