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
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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]))
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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, ®isters_fops);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user