mirror of
https://github.com/torvalds/linux.git
synced 2026-05-26 08:02:27 +02:00
ath.git patches for v6.20 (#2)
Highlights for some specific drivers include: ath11k: Add support for Channel Frequency Response measurement. ath12k: Add support for the QCC2072 chipset. And of course there is the usual set of cleanups and bug fixes across the entire family of "ath" drivers. -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQQ/mtSHzPUi16IfDEksFbugiYzLewUCaW+dBQAKCRAsFbugiYzL e1/sAP0fkZQaEECdvUz3VZQuiWQK/+P5wBtXggrjnPDTGkGUowEAs66hradqoKqK LQA0pwfT9f1BKvQj1MVnc6o74O+6HAA= =AP4S -----END PGP SIGNATURE----- Merge tag 'ath-next-20260120' of git://git.kernel.org/pub/scm/linux/kernel/git/ath/ath Jeff Johnson says: ================== ath.git patches for v6.20 (#2) Highlights for some specific drivers include: ath11k: Add support for Channel Frequency Response measurement. ath12k: Add support for the QCC2072 chipset. And of course there is the usual set of cleanups and bug fixes across the entire family of "ath" drivers. ================== Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
commit
a410d3fb30
|
|
@ -214,15 +214,6 @@ allOf:
|
|||
- const: wbm2host-tx-completions-ring2
|
||||
- const: wbm2host-tx-completions-ring1
|
||||
- const: tcl2host-status-ring
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,ipq8074-wifi
|
||||
- qcom,ipq6018-wifi
|
||||
then:
|
||||
required:
|
||||
- interrupt-names
|
||||
|
||||
|
|
|
|||
|
|
@ -58,3 +58,14 @@ config ATH11K_SPECTRAL
|
|||
Enable ath11k spectral scan support
|
||||
|
||||
Say Y to enable access to the FFT/spectral data via debugfs.
|
||||
|
||||
config ATH11K_CFR
|
||||
bool "ath11k channel frequency response support"
|
||||
depends on ATH11K_DEBUGFS
|
||||
depends on RELAY
|
||||
help
|
||||
Enable ath11k channel frequency response dump support.
|
||||
This option exposes debugfs nodes that will allow the user
|
||||
to enable, disable, and dump data.
|
||||
|
||||
Say Y to enable CFR data dump collection via debugfs.
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ ath11k-$(CONFIG_THERMAL) += thermal.o
|
|||
ath11k-$(CONFIG_ATH11K_SPECTRAL) += spectral.o
|
||||
ath11k-$(CONFIG_PM) += wow.o
|
||||
ath11k-$(CONFIG_DEV_COREDUMP) += coredump.o
|
||||
ath11k-$(CONFIG_ATH11K_CFR) += cfr.o
|
||||
|
||||
obj-$(CONFIG_ATH11K_AHB) += ath11k_ahb.o
|
||||
ath11k_ahb-y += ahb.o
|
||||
|
|
|
|||
1023
drivers/net/wireless/ath/ath11k/cfr.c
Normal file
1023
drivers/net/wireless/ath/ath11k/cfr.c
Normal file
File diff suppressed because it is too large
Load Diff
308
drivers/net/wireless/ath/ath11k/cfr.h
Normal file
308
drivers/net/wireless/ath/ath11k/cfr.h
Normal file
|
|
@ -0,0 +1,308 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#ifndef ATH11K_CFR_H
|
||||
#define ATH11K_CFR_H
|
||||
|
||||
#include "dbring.h"
|
||||
#include "wmi.h"
|
||||
|
||||
#define ATH11K_CFR_NUM_RESP_PER_EVENT 1
|
||||
#define ATH11K_CFR_EVENT_TIMEOUT_MS 1
|
||||
#define ATH11K_CFR_NUM_RING_ENTRIES 1
|
||||
|
||||
#define ATH11K_MAX_CFR_ENABLED_CLIENTS 10
|
||||
#define CFR_MAX_LUT_ENTRIES 136
|
||||
|
||||
#define HOST_MAX_CHAINS 8
|
||||
|
||||
enum ath11k_cfr_correlate_event_type {
|
||||
ATH11K_CORRELATE_DBR_EVENT,
|
||||
ATH11K_CORRELATE_TX_EVENT,
|
||||
};
|
||||
|
||||
struct ath11k_sta;
|
||||
struct ath11k_per_peer_cfr_capture;
|
||||
|
||||
#define ATH11K_CFR_START_MAGIC 0xDEADBEAF
|
||||
#define ATH11K_CFR_END_MAGIC 0xBEAFDEAD
|
||||
|
||||
#define VENDOR_QCA 0x8cfdf0
|
||||
#define PLATFORM_TYPE_ARM 2
|
||||
|
||||
enum ath11k_cfr_meta_version {
|
||||
ATH11K_CFR_META_VERSION_NONE,
|
||||
ATH11K_CFR_META_VERSION_1,
|
||||
ATH11K_CFR_META_VERSION_2,
|
||||
ATH11K_CFR_META_VERSION_3,
|
||||
ATH11K_CFR_META_VERSION_4,
|
||||
ATH11K_CFR_META_VERSION_MAX = 0xFF,
|
||||
};
|
||||
|
||||
enum ath11k_cfr_data_version {
|
||||
ATH11K_CFR_DATA_VERSION_NONE,
|
||||
ATH11K_CFR_DATA_VERSION_1,
|
||||
ATH11K_CFR_DATA_VERSION_MAX = 0xFF,
|
||||
};
|
||||
|
||||
enum ath11k_cfr_capture_ack_mode {
|
||||
ATH11K_CFR_CAPTURE_LEGACY_ACK,
|
||||
ATH11K_CFR_CAPTURE_DUP_LEGACY_ACK,
|
||||
ATH11K_CFR_CAPTURE_HT_ACK,
|
||||
ATH11K_CFR_CAPTURE_VHT_ACK,
|
||||
|
||||
/*Always keep this at last*/
|
||||
ATH11K_CFR_CAPTURE_INVALID_ACK
|
||||
};
|
||||
|
||||
enum ath11k_cfr_correlate_status {
|
||||
ATH11K_CORRELATE_STATUS_RELEASE,
|
||||
ATH11K_CORRELATE_STATUS_HOLD,
|
||||
ATH11K_CORRELATE_STATUS_ERR,
|
||||
};
|
||||
|
||||
enum ath11k_cfr_preamble_type {
|
||||
ATH11K_CFR_PREAMBLE_TYPE_LEGACY,
|
||||
ATH11K_CFR_PREAMBLE_TYPE_HT,
|
||||
ATH11K_CFR_PREAMBLE_TYPE_VHT,
|
||||
};
|
||||
|
||||
struct ath11k_cfr_peer_tx_param {
|
||||
u32 capture_method;
|
||||
u32 vdev_id;
|
||||
u8 peer_mac_addr[ETH_ALEN];
|
||||
u32 primary_20mhz_chan;
|
||||
u32 bandwidth;
|
||||
u32 phy_mode;
|
||||
u32 band_center_freq1;
|
||||
u32 band_center_freq2;
|
||||
u32 spatial_streams;
|
||||
u32 correlation_info_1;
|
||||
u32 correlation_info_2;
|
||||
u32 status;
|
||||
u32 timestamp_us;
|
||||
u32 counter;
|
||||
u32 chain_rssi[WMI_MAX_CHAINS];
|
||||
u16 chain_phase[WMI_MAX_CHAINS];
|
||||
u32 cfo_measurement;
|
||||
u8 agc_gain[HOST_MAX_CHAINS];
|
||||
u32 rx_start_ts;
|
||||
};
|
||||
|
||||
struct cfr_metadata {
|
||||
u8 peer_addr[ETH_ALEN];
|
||||
u8 status;
|
||||
u8 capture_bw;
|
||||
u8 channel_bw;
|
||||
u8 phy_mode;
|
||||
u16 prim20_chan;
|
||||
u16 center_freq1;
|
||||
u16 center_freq2;
|
||||
u8 capture_mode;
|
||||
u8 capture_type;
|
||||
u8 sts_count;
|
||||
u8 num_rx_chain;
|
||||
u32 timestamp;
|
||||
u32 length;
|
||||
u32 chain_rssi[HOST_MAX_CHAINS];
|
||||
u16 chain_phase[HOST_MAX_CHAINS];
|
||||
u32 cfo_measurement;
|
||||
u8 agc_gain[HOST_MAX_CHAINS];
|
||||
u32 rx_start_ts;
|
||||
} __packed;
|
||||
|
||||
struct ath11k_csi_cfr_header {
|
||||
u32 start_magic_num;
|
||||
u32 vendorid;
|
||||
u8 cfr_metadata_version;
|
||||
u8 cfr_data_version;
|
||||
u8 chip_type;
|
||||
u8 platform_type;
|
||||
u32 cfr_metadata_len;
|
||||
struct cfr_metadata meta_data;
|
||||
} __packed;
|
||||
|
||||
#define TONES_IN_20MHZ 256
|
||||
#define TONES_IN_40MHZ 512
|
||||
#define TONES_IN_80MHZ 1024
|
||||
#define TONES_IN_160MHZ 2048 /* 160 MHz isn't supported yet */
|
||||
#define TONES_INVALID 0
|
||||
|
||||
#define CFIR_DMA_HDR_INFO0_TAG GENMASK(7, 0)
|
||||
#define CFIR_DMA_HDR_INFO0_LEN GENMASK(13, 8)
|
||||
|
||||
#define CFIR_DMA_HDR_INFO1_UPLOAD_DONE GENMASK(0, 0)
|
||||
#define CFIR_DMA_HDR_INFO1_CAPTURE_TYPE GENMASK(3, 1)
|
||||
#define CFIR_DMA_HDR_INFO1_PREAMBLE_TYPE GENMASK(5, 4)
|
||||
#define CFIR_DMA_HDR_INFO1_NSS GENMASK(8, 6)
|
||||
#define CFIR_DMA_HDR_INFO1_NUM_CHAINS GENMASK(11, 9)
|
||||
#define CFIR_DMA_HDR_INFO1_UPLOAD_PKT_BW GENMASK(14, 12)
|
||||
#define CFIR_DMA_HDR_INFO1_SW_PEER_ID_VALID GENMASK(15, 15)
|
||||
|
||||
struct ath11k_cfr_dma_hdr {
|
||||
u16 info0;
|
||||
u16 info1;
|
||||
u16 sw_peer_id;
|
||||
u16 phy_ppdu_id;
|
||||
};
|
||||
|
||||
struct ath11k_look_up_table {
|
||||
bool dbr_recv;
|
||||
bool tx_recv;
|
||||
u8 *data;
|
||||
u32 data_len;
|
||||
u16 dbr_ppdu_id;
|
||||
u16 tx_ppdu_id;
|
||||
dma_addr_t dbr_address;
|
||||
struct ath11k_csi_cfr_header header;
|
||||
struct ath11k_cfr_dma_hdr hdr;
|
||||
u64 txrx_tstamp;
|
||||
u64 dbr_tstamp;
|
||||
u32 header_length;
|
||||
u32 payload_length;
|
||||
struct ath11k_dbring_element *buff;
|
||||
};
|
||||
|
||||
struct cfr_unassoc_pool_entry {
|
||||
u8 peer_mac[ETH_ALEN];
|
||||
u32 period;
|
||||
bool is_valid;
|
||||
};
|
||||
|
||||
struct ath11k_cfr {
|
||||
struct ath11k_dbring rx_ring;
|
||||
/* Protects cfr data */
|
||||
spinlock_t lock;
|
||||
/* Protect for lut entries */
|
||||
spinlock_t lut_lock;
|
||||
struct ath11k_look_up_table *lut;
|
||||
struct dentry *enable_cfr;
|
||||
struct dentry *cfr_unassoc;
|
||||
struct rchan *rfs_cfr_capture;
|
||||
u8 cfr_enabled_peer_cnt;
|
||||
u32 lut_num;
|
||||
u64 tx_evt_cnt;
|
||||
u64 dbr_evt_cnt;
|
||||
u64 release_cnt;
|
||||
u64 tx_peer_status_cfr_fail;
|
||||
u64 tx_evt_status_cfr_fail;
|
||||
u64 tx_dbr_lookup_fail;
|
||||
u64 last_success_tstamp;
|
||||
u64 flush_dbr_cnt;
|
||||
u64 clear_txrx_event;
|
||||
u64 cfr_dma_aborts;
|
||||
bool enabled;
|
||||
enum wmi_phy_mode phymode;
|
||||
struct cfr_unassoc_pool_entry unassoc_pool[ATH11K_MAX_CFR_ENABLED_CLIENTS];
|
||||
};
|
||||
|
||||
enum ath11k_cfr_capture_method {
|
||||
ATH11K_CFR_CAPTURE_METHOD_NULL_FRAME,
|
||||
ATH11K_CFR_CAPTURE_METHOD_NULL_FRAME_WITH_PHASE,
|
||||
ATH11K_CFR_CAPTURE_METHOD_PROBE_RESP,
|
||||
ATH11K_CFR_CAPTURE_METHOD_MAX,
|
||||
};
|
||||
|
||||
enum ath11k_cfr_capture_bw {
|
||||
ATH11K_CFR_CAPTURE_BW_20,
|
||||
ATH11K_CFR_CAPTURE_BW_40,
|
||||
ATH11K_CFR_CAPTURE_BW_80,
|
||||
ATH11K_CFR_CAPTURE_BW_MAX,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ATH11K_CFR
|
||||
int ath11k_cfr_init(struct ath11k_base *ab);
|
||||
void ath11k_cfr_deinit(struct ath11k_base *ab);
|
||||
void ath11k_cfr_lut_update_paddr(struct ath11k *ar, dma_addr_t paddr,
|
||||
u32 buf_id);
|
||||
void ath11k_cfr_decrement_peer_count(struct ath11k *ar,
|
||||
struct ath11k_sta *arsta);
|
||||
void ath11k_cfr_update_unassoc_pool_entry(struct ath11k *ar,
|
||||
const u8 *peer_mac);
|
||||
bool ath11k_cfr_peer_is_in_cfr_unassoc_pool(struct ath11k *ar,
|
||||
const u8 *peer_mac);
|
||||
void ath11k_cfr_update_unassoc_pool(struct ath11k *ar,
|
||||
struct ath11k_per_peer_cfr_capture *params,
|
||||
u8 *peer_mac);
|
||||
int ath11k_cfr_send_peer_cfr_capture_cmd(struct ath11k *ar,
|
||||
struct ath11k_sta *arsta,
|
||||
struct ath11k_per_peer_cfr_capture *params,
|
||||
const u8 *peer_mac);
|
||||
struct ath11k_dbring *ath11k_cfr_get_dbring(struct ath11k *ar);
|
||||
void ath11k_cfr_release_lut_entry(struct ath11k_look_up_table *lut);
|
||||
int ath11k_process_cfr_capture_event(struct ath11k_base *ab,
|
||||
struct ath11k_cfr_peer_tx_param *params);
|
||||
void ath11k_cfr_update_phymode(struct ath11k *ar, enum wmi_phy_mode phymode);
|
||||
#else
|
||||
static inline void ath11k_cfr_update_phymode(struct ath11k *ar,
|
||||
enum wmi_phy_mode phymode)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int ath11k_cfr_init(struct ath11k_base *ab)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void ath11k_cfr_deinit(struct ath11k_base *ab)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void ath11k_cfr_lut_update_paddr(struct ath11k *ar,
|
||||
dma_addr_t paddr, u32 buf_id)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void ath11k_cfr_decrement_peer_count(struct ath11k *ar,
|
||||
struct ath11k_sta *arsta)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void ath11k_cfr_update_unassoc_pool_entry(struct ath11k *ar,
|
||||
const u8 *peer_mac)
|
||||
{
|
||||
}
|
||||
|
||||
static inline bool
|
||||
ath11k_cfr_peer_is_in_cfr_unassoc_pool(struct ath11k *ar, const u8 *peer_mac)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void
|
||||
ath11k_cfr_update_unassoc_pool(struct ath11k *ar,
|
||||
struct ath11k_per_peer_cfr_capture *params,
|
||||
u8 *peer_mac)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath11k_cfr_send_peer_cfr_capture_cmd(struct ath11k *ar,
|
||||
struct ath11k_sta *arsta,
|
||||
struct ath11k_per_peer_cfr_capture *params,
|
||||
const u8 *peer_mac)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void ath11k_cfr_release_lut_entry(struct ath11k_look_up_table *lut)
|
||||
{
|
||||
}
|
||||
|
||||
static inline
|
||||
struct ath11k_dbring *ath11k_cfr_get_dbring(struct ath11k *ar)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline
|
||||
int ath11k_process_cfr_capture_event(struct ath11k_base *ab,
|
||||
struct ath11k_cfr_peer_tx_param *params)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_ATH11K_CFR */
|
||||
#endif /* ATH11K_CFR_H */
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
|
|
@ -100,7 +99,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.supports_regdb = false,
|
||||
.fix_l1ss = true,
|
||||
.credit_flow = false,
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX,
|
||||
.hal_params = &ath11k_hw_hal_params_ipq8074,
|
||||
.supports_dynamic_smps_6ghz = false,
|
||||
.alloc_cacheable_memory = true,
|
||||
|
|
@ -126,6 +124,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.smp2p_wow_exit = false,
|
||||
.support_dual_stations = false,
|
||||
.pdev_suspend = false,
|
||||
.cfr_support = true,
|
||||
.cfr_num_stream_bufs = 255,
|
||||
.cfr_stream_buf_size = 8200,
|
||||
},
|
||||
{
|
||||
.hw_rev = ATH11K_HW_IPQ6018_HW10,
|
||||
|
|
@ -184,7 +185,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.supports_regdb = false,
|
||||
.fix_l1ss = true,
|
||||
.credit_flow = false,
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX,
|
||||
.hal_params = &ath11k_hw_hal_params_ipq8074,
|
||||
.supports_dynamic_smps_6ghz = false,
|
||||
.alloc_cacheable_memory = true,
|
||||
|
|
@ -211,6 +211,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.support_fw_mac_sequence = false,
|
||||
.support_dual_stations = false,
|
||||
.pdev_suspend = false,
|
||||
.cfr_support = false,
|
||||
.cfr_num_stream_bufs = 0,
|
||||
.cfr_stream_buf_size = 0,
|
||||
},
|
||||
{
|
||||
.name = "qca6390 hw2.0",
|
||||
|
|
@ -271,7 +274,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.supports_regdb = false,
|
||||
.fix_l1ss = true,
|
||||
.credit_flow = true,
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
|
||||
.hal_params = &ath11k_hw_hal_params_qca6390,
|
||||
.supports_dynamic_smps_6ghz = false,
|
||||
.alloc_cacheable_memory = false,
|
||||
|
|
@ -301,6 +303,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.support_fw_mac_sequence = true,
|
||||
.support_dual_stations = true,
|
||||
.pdev_suspend = false,
|
||||
.cfr_support = false,
|
||||
.cfr_num_stream_bufs = 0,
|
||||
.cfr_stream_buf_size = 0,
|
||||
},
|
||||
{
|
||||
.name = "qcn9074 hw1.0",
|
||||
|
|
@ -358,7 +363,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.supports_regdb = false,
|
||||
.fix_l1ss = true,
|
||||
.credit_flow = false,
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX,
|
||||
.hal_params = &ath11k_hw_hal_params_ipq8074,
|
||||
.supports_dynamic_smps_6ghz = true,
|
||||
.alloc_cacheable_memory = true,
|
||||
|
|
@ -385,6 +389,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.support_fw_mac_sequence = false,
|
||||
.support_dual_stations = false,
|
||||
.pdev_suspend = false,
|
||||
.cfr_support = false,
|
||||
.cfr_num_stream_bufs = 0,
|
||||
.cfr_stream_buf_size = 0,
|
||||
},
|
||||
{
|
||||
.name = "wcn6855 hw2.0",
|
||||
|
|
@ -445,7 +452,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.supports_regdb = true,
|
||||
.fix_l1ss = false,
|
||||
.credit_flow = true,
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
|
||||
.hal_params = &ath11k_hw_hal_params_qca6390,
|
||||
.supports_dynamic_smps_6ghz = false,
|
||||
.alloc_cacheable_memory = false,
|
||||
|
|
@ -475,6 +481,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.support_fw_mac_sequence = true,
|
||||
.support_dual_stations = true,
|
||||
.pdev_suspend = false,
|
||||
.cfr_support = false,
|
||||
.cfr_num_stream_bufs = 0,
|
||||
.cfr_stream_buf_size = 0,
|
||||
},
|
||||
{
|
||||
.name = "wcn6855 hw2.1",
|
||||
|
|
@ -533,7 +542,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.supports_regdb = true,
|
||||
.fix_l1ss = false,
|
||||
.credit_flow = true,
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
|
||||
.hal_params = &ath11k_hw_hal_params_qca6390,
|
||||
.supports_dynamic_smps_6ghz = false,
|
||||
.alloc_cacheable_memory = false,
|
||||
|
|
@ -563,6 +571,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.support_fw_mac_sequence = true,
|
||||
.support_dual_stations = true,
|
||||
.pdev_suspend = false,
|
||||
.cfr_support = true,
|
||||
.cfr_num_stream_bufs = 255,
|
||||
.cfr_stream_buf_size = 8200,
|
||||
},
|
||||
{
|
||||
.name = "wcn6750 hw1.0",
|
||||
|
|
@ -619,7 +630,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.supports_regdb = true,
|
||||
.fix_l1ss = false,
|
||||
.credit_flow = true,
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX,
|
||||
.hal_params = &ath11k_hw_hal_params_wcn6750,
|
||||
.supports_dynamic_smps_6ghz = false,
|
||||
.alloc_cacheable_memory = false,
|
||||
|
|
@ -646,6 +656,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.support_fw_mac_sequence = true,
|
||||
.support_dual_stations = false,
|
||||
.pdev_suspend = true,
|
||||
.cfr_support = false,
|
||||
.cfr_num_stream_bufs = 0,
|
||||
.cfr_stream_buf_size = 0,
|
||||
},
|
||||
{
|
||||
.hw_rev = ATH11K_HW_IPQ5018_HW10,
|
||||
|
|
@ -662,7 +675,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074,
|
||||
.ring_mask = &ath11k_hw_ring_mask_ipq8074,
|
||||
.credit_flow = false,
|
||||
.max_tx_ring = 1,
|
||||
.spectral = {
|
||||
.fft_sz = 2,
|
||||
.fft_pad_sz = 0,
|
||||
|
|
@ -698,7 +710,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.supports_regdb = false,
|
||||
.idle_ps = false,
|
||||
.supports_suspend = false,
|
||||
.hal_params = &ath11k_hw_hal_params_ipq8074,
|
||||
.hal_params = &ath11k_hw_hal_params_ipq5018,
|
||||
.single_pdev_only = false,
|
||||
.coldboot_cal_mm = true,
|
||||
.coldboot_cal_ftm = true,
|
||||
|
|
@ -729,6 +741,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.support_fw_mac_sequence = false,
|
||||
.support_dual_stations = false,
|
||||
.pdev_suspend = false,
|
||||
.cfr_support = false,
|
||||
.cfr_num_stream_bufs = 0,
|
||||
.cfr_stream_buf_size = 0,
|
||||
},
|
||||
{
|
||||
.name = "qca2066 hw2.1",
|
||||
|
|
@ -789,7 +804,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.supports_regdb = true,
|
||||
.fix_l1ss = false,
|
||||
.credit_flow = true,
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
|
||||
.hal_params = &ath11k_hw_hal_params_qca6390,
|
||||
.supports_dynamic_smps_6ghz = false,
|
||||
.alloc_cacheable_memory = false,
|
||||
|
|
@ -818,6 +832,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.smp2p_wow_exit = false,
|
||||
.support_fw_mac_sequence = true,
|
||||
.support_dual_stations = true,
|
||||
.cfr_support = false,
|
||||
.cfr_num_stream_bufs = 0,
|
||||
.cfr_stream_buf_size = 0,
|
||||
},
|
||||
{
|
||||
.name = "qca6698aq hw2.1",
|
||||
|
|
@ -876,7 +893,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.supports_regdb = true,
|
||||
.fix_l1ss = false,
|
||||
.credit_flow = true,
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
|
||||
.hal_params = &ath11k_hw_hal_params_qca6390,
|
||||
.supports_dynamic_smps_6ghz = false,
|
||||
.alloc_cacheable_memory = false,
|
||||
|
|
@ -906,6 +922,9 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.support_fw_mac_sequence = true,
|
||||
.support_dual_stations = true,
|
||||
.pdev_suspend = false,
|
||||
.cfr_support = true,
|
||||
.cfr_num_stream_bufs = 255,
|
||||
.cfr_stream_buf_size = 8200,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -994,6 +1013,34 @@ static const struct dmi_system_id ath11k_pm_quirk_table[] = {
|
|||
DMI_MATCH(DMI_PRODUCT_NAME, "21F9"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.driver_data = (void *)ATH11K_PM_WOW,
|
||||
.matches = { /* Z13 G1 */
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21D2"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.driver_data = (void *)ATH11K_PM_WOW,
|
||||
.matches = { /* Z13 G1 */
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21D3"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.driver_data = (void *)ATH11K_PM_WOW,
|
||||
.matches = { /* Z16 G1 */
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21D4"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.driver_data = (void *)ATH11K_PM_WOW,
|
||||
.matches = { /* Z16 G1 */
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21D5"),
|
||||
},
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
@ -1987,8 +2034,16 @@ static int ath11k_core_pdev_create(struct ath11k_base *ab)
|
|||
goto err_thermal_unregister;
|
||||
}
|
||||
|
||||
ret = ath11k_cfr_init(ab);
|
||||
if (ret) {
|
||||
ath11k_err(ab, "failed to init cfr %d\n", ret);
|
||||
goto err_spectral_unregister;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_spectral_unregister:
|
||||
ath11k_spectral_deinit(ab);
|
||||
err_thermal_unregister:
|
||||
ath11k_thermal_unregister(ab);
|
||||
err_mac_unregister:
|
||||
|
|
@ -2038,6 +2093,7 @@ static void ath11k_core_pdev_suspend_target(struct ath11k_base *ab)
|
|||
|
||||
static void ath11k_core_pdev_destroy(struct ath11k_base *ab)
|
||||
{
|
||||
ath11k_cfr_deinit(ab);
|
||||
ath11k_spectral_deinit(ab);
|
||||
ath11k_thermal_unregister(ab);
|
||||
ath11k_mac_unregister(ab);
|
||||
|
|
@ -2250,6 +2306,7 @@ static int ath11k_core_reconfigure_on_crash(struct ath11k_base *ab)
|
|||
mutex_lock(&ab->core_lock);
|
||||
ath11k_thermal_unregister(ab);
|
||||
ath11k_dp_pdev_free(ab);
|
||||
ath11k_cfr_deinit(ab);
|
||||
ath11k_spectral_deinit(ab);
|
||||
ath11k_ce_cleanup_pipes(ab);
|
||||
ath11k_wmi_detach(ab);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#ifndef ATH11K_CORE_H
|
||||
|
|
@ -35,6 +35,7 @@
|
|||
#include "wow.h"
|
||||
#include "fw.h"
|
||||
#include "coredump.h"
|
||||
#include "cfr.h"
|
||||
|
||||
#define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK)
|
||||
|
||||
|
|
@ -531,6 +532,13 @@ struct ath11k_per_ppdu_tx_stats {
|
|||
|
||||
DECLARE_EWMA(avg_rssi, 10, 8)
|
||||
|
||||
struct ath11k_per_peer_cfr_capture {
|
||||
enum ath11k_cfr_capture_method cfr_method;
|
||||
enum ath11k_cfr_capture_bw cfr_bw;
|
||||
u32 cfr_enable;
|
||||
u32 cfr_period;
|
||||
};
|
||||
|
||||
struct ath11k_sta {
|
||||
struct ath11k_vif *arvif;
|
||||
|
||||
|
|
@ -571,6 +579,10 @@ struct ath11k_sta {
|
|||
bool peer_current_ps_valid;
|
||||
|
||||
u32 bw_prev;
|
||||
|
||||
#ifdef CONFIG_ATH11K_CFR
|
||||
struct ath11k_per_peer_cfr_capture cfr_capture;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define ATH11K_MIN_5G_FREQ 4150
|
||||
|
|
@ -795,6 +807,11 @@ struct ath11k {
|
|||
bool ps_state_enable;
|
||||
bool ps_timekeeper_enable;
|
||||
s8 max_allowed_tx_power;
|
||||
|
||||
#ifdef CONFIG_ATH11K_CFR
|
||||
struct ath11k_cfr cfr;
|
||||
#endif
|
||||
bool cfr_enabled;
|
||||
};
|
||||
|
||||
struct ath11k_band_cap {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
|
|
@ -37,10 +36,10 @@ static void ath11k_dbring_fill_magic_value(struct ath11k *ar,
|
|||
memset32(buffer, ATH11K_DB_MAGIC_VALUE, size);
|
||||
}
|
||||
|
||||
static int ath11k_dbring_bufs_replenish(struct ath11k *ar,
|
||||
struct ath11k_dbring *ring,
|
||||
struct ath11k_dbring_element *buff,
|
||||
enum wmi_direct_buffer_module id)
|
||||
int ath11k_dbring_bufs_replenish(struct ath11k *ar,
|
||||
struct ath11k_dbring *ring,
|
||||
struct ath11k_dbring_element *buff,
|
||||
enum wmi_direct_buffer_module id)
|
||||
{
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
struct hal_srng *srng;
|
||||
|
|
@ -80,6 +79,9 @@ static int ath11k_dbring_bufs_replenish(struct ath11k *ar,
|
|||
goto err_idr_remove;
|
||||
}
|
||||
|
||||
if (id == WMI_DIRECT_BUF_CFR)
|
||||
ath11k_cfr_lut_update_paddr(ar, paddr, buf_id);
|
||||
|
||||
buff->paddr = paddr;
|
||||
|
||||
cookie = FIELD_PREP(DP_RXDMA_BUF_COOKIE_PDEV_ID, ar->pdev_idx) |
|
||||
|
|
@ -155,12 +157,11 @@ int ath11k_dbring_wmi_cfg_setup(struct ath11k *ar,
|
|||
enum wmi_direct_buffer_module id)
|
||||
{
|
||||
struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd param = {};
|
||||
int ret;
|
||||
int ret, i;
|
||||
|
||||
if (id >= WMI_DIRECT_BUF_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
param.pdev_id = DP_SW2HW_MACID(ring->pdev_id);
|
||||
param.module_id = id;
|
||||
param.base_paddr_lo = lower_32_bits(ring->refill_srng.paddr);
|
||||
param.base_paddr_hi = upper_32_bits(ring->refill_srng.paddr);
|
||||
|
|
@ -173,10 +174,23 @@ int ath11k_dbring_wmi_cfg_setup(struct ath11k *ar,
|
|||
param.num_resp_per_event = ring->num_resp_per_event;
|
||||
param.event_timeout_ms = ring->event_timeout_ms;
|
||||
|
||||
ret = ath11k_wmi_pdev_dma_ring_cfg(ar, ¶m);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to setup db ring cfg\n");
|
||||
return ret;
|
||||
/* For single pdev, 2GHz and 5GHz use one DBR. */
|
||||
if (ar->ab->hw_params.single_pdev_only) {
|
||||
for (i = 0; i < ar->ab->target_pdev_count; i++) {
|
||||
param.pdev_id = ar->ab->target_pdev_ids[i].pdev_id;
|
||||
ret = ath11k_wmi_pdev_dma_ring_cfg(ar, ¶m);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to setup db ring cfg\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
param.pdev_id = DP_SW2HW_MACID(ring->pdev_id);
|
||||
ret = ath11k_wmi_pdev_dma_ring_cfg(ar, ¶m);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to setup db ring cfg\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -281,10 +295,15 @@ int ath11k_dbring_buffer_release_event(struct ath11k_base *ab,
|
|||
int size;
|
||||
dma_addr_t paddr;
|
||||
int ret = 0;
|
||||
int status;
|
||||
|
||||
pdev_idx = ev->fixed.pdev_id;
|
||||
module_id = ev->fixed.module_id;
|
||||
|
||||
if (ab->hw_params.single_pdev_only &&
|
||||
pdev_idx < ab->target_pdev_count)
|
||||
pdev_idx = 0;
|
||||
|
||||
if (pdev_idx >= ab->num_radios) {
|
||||
ath11k_warn(ab, "Invalid pdev id %d\n", pdev_idx);
|
||||
return -EINVAL;
|
||||
|
|
@ -310,6 +329,9 @@ int ath11k_dbring_buffer_release_event(struct ath11k_base *ab,
|
|||
case WMI_DIRECT_BUF_SPECTRAL:
|
||||
ring = ath11k_spectral_get_dbring(ar);
|
||||
break;
|
||||
case WMI_DIRECT_BUF_CFR:
|
||||
ring = ath11k_cfr_get_dbring(ar);
|
||||
break;
|
||||
default:
|
||||
ring = NULL;
|
||||
ath11k_warn(ab, "Recv dma buffer release ev on unsupp module %d\n",
|
||||
|
|
@ -360,8 +382,12 @@ int ath11k_dbring_buffer_release_event(struct ath11k_base *ab,
|
|||
handler_data.data = PTR_ALIGN(vaddr_unalign,
|
||||
ring->buf_align);
|
||||
handler_data.data_sz = ring->buf_sz;
|
||||
handler_data.buff = buff;
|
||||
handler_data.buf_id = buf_id;
|
||||
|
||||
ring->handler(ar, &handler_data);
|
||||
status = ring->handler(ar, &handler_data);
|
||||
if (status == ATH11K_CORRELATE_STATUS_HOLD)
|
||||
continue;
|
||||
}
|
||||
|
||||
buff->paddr = 0;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#ifndef ATH11K_DBRING_H
|
||||
|
|
@ -21,6 +21,8 @@ struct ath11k_dbring_data {
|
|||
void *data;
|
||||
u32 data_sz;
|
||||
struct wmi_dma_buf_release_meta_data meta;
|
||||
struct ath11k_dbring_element *buff;
|
||||
u32 buf_id;
|
||||
};
|
||||
|
||||
struct ath11k_dbring_buf_release_event {
|
||||
|
|
@ -61,6 +63,10 @@ int ath11k_dbring_set_cfg(struct ath11k *ar,
|
|||
u32 event_timeout_ms,
|
||||
int (*handler)(struct ath11k *,
|
||||
struct ath11k_dbring_data *));
|
||||
int ath11k_dbring_bufs_replenish(struct ath11k *ar,
|
||||
struct ath11k_dbring *ring,
|
||||
struct ath11k_dbring_element *buff,
|
||||
enum wmi_direct_buffer_module id);
|
||||
int ath11k_dbring_wmi_cfg_setup(struct ath11k *ar,
|
||||
struct ath11k_dbring *ring,
|
||||
enum wmi_direct_buffer_module id);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#ifndef _ATH11K_DEBUG_H_
|
||||
|
|
@ -27,6 +27,8 @@ enum ath11k_debug_mask {
|
|||
ATH11K_DBG_DP_TX = 0x00002000,
|
||||
ATH11K_DBG_DP_RX = 0x00004000,
|
||||
ATH11K_DBG_CE = 0x00008000,
|
||||
ATH11K_DBG_CFR = 0x00010000,
|
||||
ATH11K_DBG_CFR_DUMP = 0x00020000,
|
||||
};
|
||||
|
||||
static inline const char *ath11k_dbg_str(enum ath11k_debug_mask mask)
|
||||
|
|
@ -64,6 +66,10 @@ static inline const char *ath11k_dbg_str(enum ath11k_debug_mask mask)
|
|||
return "dp_rx";
|
||||
case ATH11K_DBG_CE:
|
||||
return "ce";
|
||||
case ATH11K_DBG_CFR:
|
||||
return "cfr";
|
||||
case ATH11K_DBG_CFR_DUMP:
|
||||
return "cfr_dump";
|
||||
|
||||
/* no default handler to allow compiler to check that the
|
||||
* enum is fully handled
|
||||
|
|
|
|||
|
|
@ -707,7 +707,7 @@ static ssize_t ath11k_debugfs_dump_soc_dp_stats(struct file *file,
|
|||
len += scnprintf(buf + len, size - len, "\nSOC TX STATS:\n");
|
||||
len += scnprintf(buf + len, size - len, "\nTCL Ring Full Failures:\n");
|
||||
|
||||
for (i = 0; i < ab->hw_params.max_tx_ring; i++)
|
||||
for (i = 0; i < ab->hw_params.hal_params->num_tx_rings; i++)
|
||||
len += scnprintf(buf + len, size - len, "ring%d: %u\n",
|
||||
i, soc_stats->tx_err.desc_na[i]);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
|
|
@ -240,6 +239,140 @@ static const struct file_operations fops_tx_stats = {
|
|||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ATH11K_CFR
|
||||
static ssize_t ath11k_dbg_sta_write_cfr_capture(struct file *file,
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ieee80211_sta *sta = file->private_data;
|
||||
struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
|
||||
struct ath11k *ar = arsta->arvif->ar;
|
||||
struct ath11k_cfr *cfr = &ar->cfr;
|
||||
struct wmi_peer_cfr_capture_conf_arg arg;
|
||||
u32 cfr_capture_enable = 0, cfr_capture_bw = 0;
|
||||
u32 cfr_capture_method = 0, cfr_capture_period = 0;
|
||||
char buf[64] = {};
|
||||
int ret;
|
||||
|
||||
simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
|
||||
|
||||
guard(mutex)(&ar->conf_mutex);
|
||||
|
||||
if (ar->state != ATH11K_STATE_ON)
|
||||
return -ENETDOWN;
|
||||
|
||||
if (!ar->cfr_enabled)
|
||||
return -EINVAL;
|
||||
|
||||
ret = sscanf(buf, "%u %u %u %u", &cfr_capture_enable, &cfr_capture_bw,
|
||||
&cfr_capture_period, &cfr_capture_method);
|
||||
|
||||
if (ret < 1 || (cfr_capture_enable && ret != 4))
|
||||
return -EINVAL;
|
||||
|
||||
if (cfr_capture_enable == arsta->cfr_capture.cfr_enable &&
|
||||
(cfr_capture_period &&
|
||||
cfr_capture_period == arsta->cfr_capture.cfr_period) &&
|
||||
cfr_capture_bw == arsta->cfr_capture.cfr_bw &&
|
||||
cfr_capture_method == arsta->cfr_capture.cfr_method)
|
||||
return count;
|
||||
|
||||
if (!cfr_capture_enable &&
|
||||
cfr_capture_enable == arsta->cfr_capture.cfr_enable)
|
||||
return count;
|
||||
|
||||
if (cfr_capture_enable > WMI_PEER_CFR_CAPTURE_ENABLE ||
|
||||
cfr_capture_bw > WMI_PEER_CFR_CAPTURE_BW_80 ||
|
||||
cfr_capture_method > ATH11K_CFR_CAPTURE_METHOD_NULL_FRAME_WITH_PHASE ||
|
||||
cfr_capture_period > WMI_PEER_CFR_PERIODICITY_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
/* Target expects cfr period in multiple of 10 */
|
||||
if (cfr_capture_period % 10) {
|
||||
ath11k_err(ar->ab, "periodicity should be 10x\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ar->cfr.cfr_enabled_peer_cnt >= ATH11K_MAX_CFR_ENABLED_CLIENTS &&
|
||||
!arsta->cfr_capture.cfr_enable) {
|
||||
ath11k_err(ar->ab, "CFR enable peer threshold reached %u\n",
|
||||
ar->cfr.cfr_enabled_peer_cnt);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!cfr_capture_enable) {
|
||||
cfr_capture_bw = arsta->cfr_capture.cfr_bw;
|
||||
cfr_capture_period = arsta->cfr_capture.cfr_period;
|
||||
cfr_capture_method = arsta->cfr_capture.cfr_method;
|
||||
}
|
||||
|
||||
arg.request = cfr_capture_enable;
|
||||
arg.periodicity = cfr_capture_period;
|
||||
arg.bw = cfr_capture_bw;
|
||||
arg.method = cfr_capture_method;
|
||||
|
||||
ret = ath11k_wmi_peer_set_cfr_capture_conf(ar, arsta->arvif->vdev_id,
|
||||
sta->addr, &arg);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab,
|
||||
"failed to send cfr capture info: vdev_id %u peer %pM: %d\n",
|
||||
arsta->arvif->vdev_id, sta->addr, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
spin_lock_bh(&ar->cfr.lock);
|
||||
|
||||
if (cfr_capture_enable &&
|
||||
cfr_capture_enable != arsta->cfr_capture.cfr_enable)
|
||||
cfr->cfr_enabled_peer_cnt++;
|
||||
else if (!cfr_capture_enable)
|
||||
cfr->cfr_enabled_peer_cnt--;
|
||||
|
||||
spin_unlock_bh(&ar->cfr.lock);
|
||||
|
||||
arsta->cfr_capture.cfr_enable = cfr_capture_enable;
|
||||
arsta->cfr_capture.cfr_period = cfr_capture_period;
|
||||
arsta->cfr_capture.cfr_bw = cfr_capture_bw;
|
||||
arsta->cfr_capture.cfr_method = cfr_capture_method;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t ath11k_dbg_sta_read_cfr_capture(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ieee80211_sta *sta = file->private_data;
|
||||
struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
|
||||
struct ath11k *ar = arsta->arvif->ar;
|
||||
char buf[512] = {};
|
||||
int len = 0;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
len += scnprintf(buf + len, sizeof(buf) - len, "cfr_enabled = %d\n",
|
||||
arsta->cfr_capture.cfr_enable);
|
||||
len += scnprintf(buf + len, sizeof(buf) - len, "bandwidth = %d\n",
|
||||
arsta->cfr_capture.cfr_bw);
|
||||
len += scnprintf(buf + len, sizeof(buf) - len, "period = %d\n",
|
||||
arsta->cfr_capture.cfr_period);
|
||||
len += scnprintf(buf + len, sizeof(buf) - len, "cfr_method = %d\n",
|
||||
arsta->cfr_capture.cfr_method);
|
||||
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
}
|
||||
|
||||
static const struct file_operations fops_peer_cfr_capture = {
|
||||
.write = ath11k_dbg_sta_write_cfr_capture,
|
||||
.read = ath11k_dbg_sta_read_cfr_capture,
|
||||
.open = simple_open,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
#endif /* CONFIG_ATH11K_CFR */
|
||||
|
||||
static ssize_t ath11k_dbg_sta_dump_rx_stats(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
|
|
@ -877,6 +1010,13 @@ void ath11k_debugfs_sta_op_add(struct ieee80211_hw *hw, struct ieee80211_vif *vi
|
|||
debugfs_create_file("htt_peer_stats_reset", 0600, dir, sta,
|
||||
&fops_htt_peer_stats_reset);
|
||||
|
||||
#ifdef CONFIG_ATH11K_CFR
|
||||
if (test_bit(WMI_TLV_SERVICE_CFR_CAPTURE_SUPPORT,
|
||||
ar->ab->wmi_ab.svc_map))
|
||||
debugfs_create_file("cfr_capture", 0600, dir, sta,
|
||||
&fops_peer_cfr_capture);
|
||||
#endif/* CONFIG_ATH11K_CFR */
|
||||
|
||||
debugfs_create_file("peer_ps_state", 0400, dir, sta,
|
||||
&fops_peer_ps_state);
|
||||
|
||||
|
|
|
|||
|
|
@ -344,7 +344,7 @@ void ath11k_dp_stop_shadow_timers(struct ath11k_base *ab)
|
|||
if (!ab->hw_params.supports_shadow_regs)
|
||||
return;
|
||||
|
||||
for (i = 0; i < ab->hw_params.max_tx_ring; i++)
|
||||
for (i = 0; i < ab->hw_params.hal_params->num_tx_rings; i++)
|
||||
ath11k_dp_shadow_stop_timer(ab, &ab->dp.tx_ring_timer[i]);
|
||||
|
||||
ath11k_dp_shadow_stop_timer(ab, &ab->dp.reo_cmd_timer);
|
||||
|
|
@ -359,7 +359,7 @@ static void ath11k_dp_srng_common_cleanup(struct ath11k_base *ab)
|
|||
ath11k_dp_srng_cleanup(ab, &dp->wbm_desc_rel_ring);
|
||||
ath11k_dp_srng_cleanup(ab, &dp->tcl_cmd_ring);
|
||||
ath11k_dp_srng_cleanup(ab, &dp->tcl_status_ring);
|
||||
for (i = 0; i < ab->hw_params.max_tx_ring; i++) {
|
||||
for (i = 0; i < ab->hw_params.hal_params->num_tx_rings; i++) {
|
||||
ath11k_dp_srng_cleanup(ab, &dp->tx_ring[i].tcl_data_ring);
|
||||
ath11k_dp_srng_cleanup(ab, &dp->tx_ring[i].tcl_comp_ring);
|
||||
}
|
||||
|
|
@ -400,7 +400,7 @@ static int ath11k_dp_srng_common_setup(struct ath11k_base *ab)
|
|||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < ab->hw_params.max_tx_ring; i++) {
|
||||
for (i = 0; i < ab->hw_params.hal_params->num_tx_rings; i++) {
|
||||
tcl_num = ab->hw_params.hal_params->tcl2wbm_rbm_map[i].tcl_ring_num;
|
||||
wbm_num = ab->hw_params.hal_params->tcl2wbm_rbm_map[i].wbm_ring_num;
|
||||
|
||||
|
|
@ -782,7 +782,7 @@ int ath11k_dp_service_srng(struct ath11k_base *ab,
|
|||
int i, j;
|
||||
int tot_work_done = 0;
|
||||
|
||||
for (i = 0; i < ab->hw_params.max_tx_ring; i++) {
|
||||
for (i = 0; i < ab->hw_params.hal_params->num_tx_rings; i++) {
|
||||
if (BIT(ab->hw_params.hal_params->tcl2wbm_rbm_map[i].wbm_ring_num) &
|
||||
ab->hw_params.ring_mask->tx[grp_id])
|
||||
ath11k_dp_tx_completion_handler(ab, i);
|
||||
|
|
@ -1035,7 +1035,7 @@ void ath11k_dp_free(struct ath11k_base *ab)
|
|||
|
||||
ath11k_dp_reo_cmd_list_cleanup(ab);
|
||||
|
||||
for (i = 0; i < ab->hw_params.max_tx_ring; i++) {
|
||||
for (i = 0; i < ab->hw_params.hal_params->num_tx_rings; i++) {
|
||||
spin_lock_bh(&dp->tx_ring[i].tx_idr_lock);
|
||||
idr_for_each(&dp->tx_ring[i].txbuf_idr,
|
||||
ath11k_dp_tx_pending_cleanup, ab);
|
||||
|
|
@ -1086,7 +1086,7 @@ int ath11k_dp_alloc(struct ath11k_base *ab)
|
|||
|
||||
size = sizeof(struct hal_wbm_release_ring) * DP_TX_COMP_RING_SIZE;
|
||||
|
||||
for (i = 0; i < ab->hw_params.max_tx_ring; i++) {
|
||||
for (i = 0; i < ab->hw_params.hal_params->num_tx_rings; i++) {
|
||||
idr_init(&dp->tx_ring[i].txbuf_idr);
|
||||
spin_lock_init(&dp->tx_ring[i].tx_idr_lock);
|
||||
dp->tx_ring[i].tcl_data_ring_id = i;
|
||||
|
|
|
|||
|
|
@ -199,7 +199,6 @@ struct ath11k_pdev_dp {
|
|||
#define DP_BA_WIN_SZ_MAX 256
|
||||
|
||||
#define DP_TCL_NUM_RING_MAX 3
|
||||
#define DP_TCL_NUM_RING_MAX_QCA6390 1
|
||||
|
||||
#define DP_IDLE_SCATTER_BUFS_MAX 16
|
||||
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
|
|||
struct hal_srng *tcl_ring;
|
||||
struct ieee80211_hdr *hdr = (void *)skb->data;
|
||||
struct dp_tx_ring *tx_ring;
|
||||
size_t num_tx_rings = ab->hw_params.hal_params->num_tx_rings;
|
||||
void *hal_tcl_desc;
|
||||
u8 pool_id;
|
||||
u8 hal_ring_id;
|
||||
|
|
@ -113,7 +114,7 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
|
|||
tcl_ring_sel:
|
||||
tcl_ring_retry = false;
|
||||
|
||||
ti.ring_id = ring_selector % ab->hw_params.max_tx_ring;
|
||||
ti.ring_id = ring_selector % num_tx_rings;
|
||||
ti.rbm_id = ab->hw_params.hal_params->tcl2wbm_rbm_map[ti.ring_id].rbm_id;
|
||||
|
||||
ring_map |= BIT(ti.ring_id);
|
||||
|
|
@ -126,7 +127,7 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
|
|||
spin_unlock_bh(&tx_ring->tx_idr_lock);
|
||||
|
||||
if (unlikely(ret < 0)) {
|
||||
if (ring_map == (BIT(ab->hw_params.max_tx_ring) - 1) ||
|
||||
if (ring_map == (BIT(num_tx_rings) - 1) ||
|
||||
!ab->hw_params.tcl_ring_retry) {
|
||||
atomic_inc(&ab->soc_stats.tx_err.misc_fail);
|
||||
return -ENOSPC;
|
||||
|
|
@ -244,8 +245,8 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
|
|||
* checking this ring earlier for each pkt tx.
|
||||
* Restart ring selection if some rings are not checked yet.
|
||||
*/
|
||||
if (unlikely(ring_map != (BIT(ab->hw_params.max_tx_ring)) - 1) &&
|
||||
ab->hw_params.tcl_ring_retry && ab->hw_params.max_tx_ring > 1) {
|
||||
if (unlikely(ring_map != (BIT(num_tx_rings)) - 1) &&
|
||||
ab->hw_params.tcl_ring_retry && num_tx_rings > 1) {
|
||||
tcl_ring_retry = true;
|
||||
ring_selector++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
#include <linux/dma-mapping.h>
|
||||
|
|
@ -184,7 +183,7 @@ static const struct hal_srng_config hw_srng_config_template[] = {
|
|||
},
|
||||
{ /* RXDMA DIR BUF */
|
||||
.start_ring_id = HAL_SRNG_RING_ID_RXDMA_DIR_BUF,
|
||||
.max_rings = 1,
|
||||
.max_rings = 2,
|
||||
.entry_size = 8 >> 2, /* TODO: Define the struct */
|
||||
.lmac_ring = true,
|
||||
.ring_dir = HAL_SRNG_DIR_SRC,
|
||||
|
|
|
|||
|
|
@ -2707,6 +2707,14 @@ const struct ath11k_hw_regs wcn6750_regs = {
|
|||
.hal_reo1_misc_ctl = 0x000005d8,
|
||||
};
|
||||
|
||||
static const struct ath11k_hw_tcl2wbm_rbm_map ath11k_hw_tcl2wbm_rbm_map_ipq5018[] = {
|
||||
{
|
||||
.tcl_ring_num = 0,
|
||||
.wbm_ring_num = 0,
|
||||
.rbm_id = HAL_RX_BUF_RBM_SW0_BM,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct ath11k_hw_tcl2wbm_rbm_map ath11k_hw_tcl2wbm_rbm_map_ipq8074[] = {
|
||||
{
|
||||
.tcl_ring_num = 0,
|
||||
|
|
@ -2822,19 +2830,28 @@ const struct ath11k_hw_regs ipq5018_regs = {
|
|||
.hal_wbm1_release_ring_base_lsb = 0x0000097c,
|
||||
};
|
||||
|
||||
const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq5018 = {
|
||||
.rx_buf_rbm = HAL_RX_BUF_RBM_SW3_BM,
|
||||
.tcl2wbm_rbm_map = ath11k_hw_tcl2wbm_rbm_map_ipq5018,
|
||||
.num_tx_rings = ARRAY_SIZE(ath11k_hw_tcl2wbm_rbm_map_ipq5018),
|
||||
};
|
||||
|
||||
const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq8074 = {
|
||||
.rx_buf_rbm = HAL_RX_BUF_RBM_SW3_BM,
|
||||
.tcl2wbm_rbm_map = ath11k_hw_tcl2wbm_rbm_map_ipq8074,
|
||||
.num_tx_rings = ARRAY_SIZE(ath11k_hw_tcl2wbm_rbm_map_ipq8074),
|
||||
};
|
||||
|
||||
const struct ath11k_hw_hal_params ath11k_hw_hal_params_qca6390 = {
|
||||
.rx_buf_rbm = HAL_RX_BUF_RBM_SW1_BM,
|
||||
.tcl2wbm_rbm_map = ath11k_hw_tcl2wbm_rbm_map_ipq8074,
|
||||
.tcl2wbm_rbm_map = ath11k_hw_tcl2wbm_rbm_map_ipq5018,
|
||||
.num_tx_rings = ARRAY_SIZE(ath11k_hw_tcl2wbm_rbm_map_ipq5018),
|
||||
};
|
||||
|
||||
const struct ath11k_hw_hal_params ath11k_hw_hal_params_wcn6750 = {
|
||||
.rx_buf_rbm = HAL_RX_BUF_RBM_SW1_BM,
|
||||
.tcl2wbm_rbm_map = ath11k_hw_tcl2wbm_rbm_map_wcn6750,
|
||||
.num_tx_rings = ARRAY_SIZE(ath11k_hw_tcl2wbm_rbm_map_wcn6750),
|
||||
};
|
||||
|
||||
static const struct cfg80211_sar_freq_ranges ath11k_hw_sar_freq_ranges_wcn6855[] = {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#ifndef ATH11K_HW_H
|
||||
|
|
@ -134,6 +134,7 @@ struct ath11k_hw_tcl2wbm_rbm_map {
|
|||
struct ath11k_hw_hal_params {
|
||||
enum hal_rx_buf_return_buf_manager rx_buf_rbm;
|
||||
const struct ath11k_hw_tcl2wbm_rbm_map *tcl2wbm_rbm_map;
|
||||
size_t num_tx_rings;
|
||||
};
|
||||
|
||||
struct ath11k_hw_params {
|
||||
|
|
@ -198,7 +199,6 @@ struct ath11k_hw_params {
|
|||
bool supports_regdb;
|
||||
bool fix_l1ss;
|
||||
bool credit_flow;
|
||||
u8 max_tx_ring;
|
||||
const struct ath11k_hw_hal_params *hal_params;
|
||||
bool supports_dynamic_smps_6ghz;
|
||||
bool alloc_cacheable_memory;
|
||||
|
|
@ -228,6 +228,9 @@ struct ath11k_hw_params {
|
|||
bool support_fw_mac_sequence;
|
||||
bool support_dual_stations;
|
||||
bool pdev_suspend;
|
||||
bool cfr_support;
|
||||
u32 cfr_num_stream_bufs;
|
||||
u32 cfr_stream_buf_size;
|
||||
};
|
||||
|
||||
struct ath11k_hw_ops {
|
||||
|
|
@ -291,6 +294,7 @@ extern const struct ce_ie_addr ath11k_ce_ie_addr_ipq5018;
|
|||
|
||||
extern const struct ce_remap ath11k_ce_remap_ipq5018;
|
||||
|
||||
extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq5018;
|
||||
extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq8074;
|
||||
extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_qca6390;
|
||||
extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_wcn6750;
|
||||
|
|
|
|||
|
|
@ -2911,6 +2911,8 @@ static void ath11k_peer_assoc_h_phymode(struct ath11k *ar,
|
|||
|
||||
arg->peer_phymode = phymode;
|
||||
WARN_ON(phymode == MODE_UNKNOWN);
|
||||
|
||||
ath11k_cfr_update_phymode(ar, phymode);
|
||||
}
|
||||
|
||||
static void ath11k_peer_assoc_prepare(struct ath11k *ar,
|
||||
|
|
@ -6186,6 +6188,8 @@ static int ath11k_mac_mgmt_tx_wmi(struct ath11k *ar, struct ath11k_vif *arvif,
|
|||
dma_addr_t paddr;
|
||||
int buf_id;
|
||||
int ret;
|
||||
bool tx_params_valid = false;
|
||||
bool peer_in_unassoc_pool;
|
||||
|
||||
ATH11K_SKB_CB(skb)->ar = ar;
|
||||
|
||||
|
|
@ -6224,7 +6228,18 @@ static int ath11k_mac_mgmt_tx_wmi(struct ath11k *ar, struct ath11k_vif *arvif,
|
|||
|
||||
ATH11K_SKB_CB(skb)->paddr = paddr;
|
||||
|
||||
ret = ath11k_wmi_mgmt_send(ar, arvif->vdev_id, buf_id, skb);
|
||||
peer_in_unassoc_pool = ath11k_cfr_peer_is_in_cfr_unassoc_pool(ar, hdr->addr1);
|
||||
|
||||
if (ar->cfr_enabled &&
|
||||
ieee80211_is_probe_resp(hdr->frame_control) &&
|
||||
peer_in_unassoc_pool)
|
||||
tx_params_valid = true;
|
||||
|
||||
if (peer_in_unassoc_pool)
|
||||
ath11k_cfr_update_unassoc_pool_entry(ar, hdr->addr1);
|
||||
|
||||
ret = ath11k_wmi_mgmt_send(ar, arvif->vdev_id, buf_id, skb,
|
||||
tx_params_valid);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to send mgmt frame: %d\n", ret);
|
||||
goto err_unmap_buf;
|
||||
|
|
@ -7392,7 +7407,7 @@ static void ath11k_mac_op_remove_interface(struct ieee80211_hw *hw,
|
|||
idr_for_each(&ar->txmgmt_idr,
|
||||
ath11k_mac_vif_txmgmt_idr_remove, vif);
|
||||
|
||||
for (i = 0; i < ab->hw_params.max_tx_ring; i++) {
|
||||
for (i = 0; i < ab->hw_params.hal_params->num_tx_rings; i++) {
|
||||
spin_lock_bh(&ab->dp.tx_ring[i].tx_idr_lock);
|
||||
idr_for_each(&ab->dp.tx_ring[i].txbuf_idr,
|
||||
ath11k_mac_vif_unref, vif);
|
||||
|
|
@ -9979,6 +9994,8 @@ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw,
|
|||
}
|
||||
spin_unlock_bh(&ar->ab->base_lock);
|
||||
mutex_unlock(&ar->ab->tbl_mtx_lock);
|
||||
|
||||
ath11k_cfr_decrement_peer_count(ar, arsta);
|
||||
} else if (old_state == IEEE80211_STA_AUTH &&
|
||||
new_state == IEEE80211_STA_ASSOC &&
|
||||
(vif->type == NL80211_IFTYPE_AP ||
|
||||
|
|
@ -10640,7 +10657,7 @@ static int __ath11k_mac_register(struct ath11k *ar)
|
|||
if (!ab->hw_params.supports_monitor)
|
||||
/* There's a race between calling ieee80211_register_hw()
|
||||
* and here where the monitor mode is enabled for a little
|
||||
* while. But that time is so short and in practise it make
|
||||
* while. But that time is so short and in practice it doesn't make
|
||||
* a difference in real life.
|
||||
*/
|
||||
ar->hw->wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MONITOR);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
#include <linux/rtnetlink.h>
|
||||
|
||||
|
|
@ -926,8 +926,11 @@ int ath11k_reg_handle_chan_list(struct ath11k_base *ab,
|
|||
*/
|
||||
if (ab->default_regd[pdev_idx] && !ab->new_regd[pdev_idx] &&
|
||||
!memcmp((char *)ab->default_regd[pdev_idx]->alpha2,
|
||||
(char *)reg_info->alpha2, 2))
|
||||
goto retfail;
|
||||
(char *)reg_info->alpha2, 2) &&
|
||||
power_type == IEEE80211_REG_UNSET_AP) {
|
||||
ath11k_reg_reset_info(reg_info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Intersect new rules with default regd if a new country setting was
|
||||
* requested, i.e a default regd was already set during initialization
|
||||
|
|
|
|||
|
|
@ -651,11 +651,12 @@ static u32 ath11k_wmi_mgmt_get_freq(struct ath11k *ar,
|
|||
}
|
||||
|
||||
int ath11k_wmi_mgmt_send(struct ath11k *ar, u32 vdev_id, u32 buf_id,
|
||||
struct sk_buff *frame)
|
||||
struct sk_buff *frame, bool tx_params_valid)
|
||||
{
|
||||
struct ath11k_pdev_wmi *wmi = ar->wmi;
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(frame);
|
||||
struct wmi_mgmt_send_cmd *cmd;
|
||||
struct wmi_mgmt_send_params *params;
|
||||
struct wmi_tlv *frame_tlv;
|
||||
struct sk_buff *skb;
|
||||
u32 buf_len;
|
||||
|
|
@ -665,6 +666,8 @@ int ath11k_wmi_mgmt_send(struct ath11k *ar, u32 vdev_id, u32 buf_id,
|
|||
frame->len : WMI_MGMT_SEND_DOWNLD_LEN;
|
||||
|
||||
len = sizeof(*cmd) + sizeof(*frame_tlv) + roundup(buf_len, 4);
|
||||
if (tx_params_valid)
|
||||
len += sizeof(*params);
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
||||
if (!skb)
|
||||
|
|
@ -680,7 +683,7 @@ int ath11k_wmi_mgmt_send(struct ath11k *ar, u32 vdev_id, u32 buf_id,
|
|||
cmd->paddr_hi = upper_32_bits(ATH11K_SKB_CB(frame)->paddr);
|
||||
cmd->frame_len = frame->len;
|
||||
cmd->buf_len = buf_len;
|
||||
cmd->tx_params_valid = 0;
|
||||
cmd->tx_params_valid = !!tx_params_valid;
|
||||
|
||||
frame_tlv = (struct wmi_tlv *)(skb->data + sizeof(*cmd));
|
||||
frame_tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) |
|
||||
|
|
@ -690,6 +693,15 @@ int ath11k_wmi_mgmt_send(struct ath11k *ar, u32 vdev_id, u32 buf_id,
|
|||
|
||||
ath11k_ce_byte_swap(frame_tlv->value, buf_len);
|
||||
|
||||
if (tx_params_valid) {
|
||||
params =
|
||||
(struct wmi_mgmt_send_params *)(skb->data + (len - sizeof(*params)));
|
||||
params->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_TX_SEND_PARAMS) |
|
||||
FIELD_PREP(WMI_TLV_LEN,
|
||||
sizeof(*params) - TLV_HDR_SIZE);
|
||||
params->tx_params_dword1 |= WMI_TX_PARAMS_DWORD1_CFR_CAPTURE;
|
||||
}
|
||||
|
||||
ret = ath11k_wmi_cmd_send(wmi, skb, WMI_MGMT_TX_SEND_CMDID);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab,
|
||||
|
|
@ -3941,6 +3953,47 @@ int ath11k_wmi_fils_discovery_tmpl(struct ath11k *ar, u32 vdev_id,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ath11k_wmi_peer_set_cfr_capture_conf(struct ath11k *ar,
|
||||
u32 vdev_id, const u8 *mac_addr,
|
||||
struct wmi_peer_cfr_capture_conf_arg *arg)
|
||||
{
|
||||
struct ath11k_pdev_wmi *wmi = ar->wmi;
|
||||
struct wmi_peer_cfr_capture_cmd_fixed_param *cmd;
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (struct wmi_peer_cfr_capture_cmd_fixed_param *)skb->data;
|
||||
cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
|
||||
WMI_TAG_PEER_CFR_CAPTURE_CMD) |
|
||||
FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
|
||||
|
||||
memcpy(&cmd->mac_addr, mac_addr, ETH_ALEN);
|
||||
cmd->request = arg->request;
|
||||
cmd->vdev_id = vdev_id;
|
||||
cmd->periodicity = arg->periodicity;
|
||||
cmd->bandwidth = arg->bw;
|
||||
cmd->capture_method = arg->method;
|
||||
|
||||
ret = ath11k_wmi_cmd_send(ar->wmi, skb, WMI_PEER_CFR_CAPTURE_CMDID);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab,
|
||||
"WMI vdev %d failed to send peer cfr capture cmd: %d\n",
|
||||
vdev_id, ret);
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
|
||||
"WMI peer CFR capture cmd req %u id %u period %u bw %u mode %u\n",
|
||||
arg->request, vdev_id, arg->periodicity,
|
||||
arg->bw, arg->method);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath11k_wmi_probe_resp_tmpl(struct ath11k *ar, u32 vdev_id,
|
||||
struct sk_buff *tmpl)
|
||||
{
|
||||
|
|
@ -8752,6 +8805,93 @@ static void ath11k_wmi_p2p_noa_event(struct ath11k_base *ab,
|
|||
kfree(tb);
|
||||
}
|
||||
|
||||
static void ath11k_wmi_tlv_cfr_capture_event_fixed_param(const void *ptr,
|
||||
void *data)
|
||||
{
|
||||
struct ath11k_cfr_peer_tx_param *tx_params = data;
|
||||
const struct ath11k_wmi_cfr_peer_tx_event_param *params = ptr;
|
||||
|
||||
tx_params->capture_method = params->capture_method;
|
||||
tx_params->vdev_id = params->vdev_id;
|
||||
ether_addr_copy(tx_params->peer_mac_addr, params->mac_addr.addr);
|
||||
tx_params->primary_20mhz_chan = params->chan_mhz;
|
||||
tx_params->bandwidth = params->bandwidth;
|
||||
tx_params->phy_mode = params->phy_mode;
|
||||
tx_params->band_center_freq1 = params->band_center_freq1;
|
||||
tx_params->band_center_freq2 = params->band_center_freq2;
|
||||
tx_params->spatial_streams = params->sts_count;
|
||||
tx_params->correlation_info_1 = params->correlation_info_1;
|
||||
tx_params->correlation_info_2 = params->correlation_info_2;
|
||||
tx_params->status = params->status;
|
||||
tx_params->timestamp_us = params->timestamp_us;
|
||||
tx_params->counter = params->counter;
|
||||
tx_params->rx_start_ts = params->rx_start_ts;
|
||||
|
||||
memcpy(tx_params->chain_rssi, params->chain_rssi,
|
||||
sizeof(tx_params->chain_rssi));
|
||||
|
||||
if (WMI_CFR_CFO_MEASUREMENT_VALID & params->cfo_measurement)
|
||||
tx_params->cfo_measurement = FIELD_GET(WMI_CFR_CFO_MEASUREMENT_RAW_DATA,
|
||||
params->cfo_measurement);
|
||||
}
|
||||
|
||||
static void ath11k_wmi_tlv_cfr_capture_phase_fixed_param(const void *ptr,
|
||||
void *data)
|
||||
{
|
||||
struct ath11k_cfr_peer_tx_param *tx_params = data;
|
||||
const struct ath11k_wmi_cfr_peer_tx_event_phase_param *params = ptr;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < WMI_MAX_CHAINS; i++) {
|
||||
tx_params->chain_phase[i] = params->chain_phase[i];
|
||||
tx_params->agc_gain[i] = params->agc_gain[i];
|
||||
}
|
||||
}
|
||||
|
||||
static int ath11k_wmi_tlv_cfr_capture_evt_parse(struct ath11k_base *ab,
|
||||
u16 tag, u16 len,
|
||||
const void *ptr, void *data)
|
||||
{
|
||||
switch (tag) {
|
||||
case WMI_TAG_PEER_CFR_CAPTURE_EVENT:
|
||||
ath11k_wmi_tlv_cfr_capture_event_fixed_param(ptr, data);
|
||||
break;
|
||||
case WMI_TAG_CFR_CAPTURE_PHASE_PARAM:
|
||||
ath11k_wmi_tlv_cfr_capture_phase_fixed_param(ptr, data);
|
||||
break;
|
||||
default:
|
||||
ath11k_warn(ab, "Invalid tag received tag %d len %d\n",
|
||||
tag, len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ath11k_wmi_parse_cfr_capture_event(struct ath11k_base *ab,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct ath11k_cfr_peer_tx_param params = {};
|
||||
int ret;
|
||||
|
||||
ath11k_dbg_dump(ab, ATH11K_DBG_CFR_DUMP, "cfr_dump:", "",
|
||||
skb->data, skb->len);
|
||||
|
||||
ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len,
|
||||
ath11k_wmi_tlv_cfr_capture_evt_parse,
|
||||
¶ms);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed to parse cfr capture event tlv %d\n",
|
||||
ret);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = ath11k_process_cfr_capture_event(ab, ¶ms);
|
||||
if (ret)
|
||||
ath11k_dbg(ab, ATH11K_DBG_CFR,
|
||||
"failed to process cfr capture ret = %d\n", ret);
|
||||
}
|
||||
|
||||
static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb)
|
||||
{
|
||||
struct wmi_cmd_hdr *cmd_hdr;
|
||||
|
|
@ -8882,6 +9022,9 @@ static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb)
|
|||
case WMI_P2P_NOA_EVENTID:
|
||||
ath11k_wmi_p2p_noa_event(ab, skb);
|
||||
break;
|
||||
case WMI_PEER_CFR_CAPTURE_EVENTID:
|
||||
ath11k_wmi_parse_cfr_capture_event(ab, skb);
|
||||
break;
|
||||
default:
|
||||
ath11k_dbg(ab, ATH11K_DBG_WMI, "unsupported event id 0x%x\n", id);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -362,6 +362,10 @@ enum wmi_tlv_cmd_id {
|
|||
WMI_PEER_REORDER_QUEUE_REMOVE_CMDID,
|
||||
WMI_PEER_SET_RX_BLOCKSIZE_CMDID,
|
||||
WMI_PEER_ANTDIV_INFO_REQ_CMDID,
|
||||
WMI_PEER_RESERVED0_CMDID,
|
||||
WMI_PEER_TID_MSDUQ_QDEPTH_THRESH_UPDATE_CMDID,
|
||||
WMI_PEER_TID_CONFIGURATIONS_CMDID,
|
||||
WMI_PEER_CFR_CAPTURE_CMDID,
|
||||
WMI_BCN_TX_CMDID = WMI_TLV_CMD(WMI_GRP_MGMT),
|
||||
WMI_PDEV_SEND_BCN_CMDID,
|
||||
WMI_BCN_TMPL_CMDID,
|
||||
|
|
@ -981,6 +985,7 @@ enum wmi_tlv_pdev_param {
|
|||
WMI_PDEV_PARAM_RADIO_CHAN_STATS_ENABLE,
|
||||
WMI_PDEV_PARAM_RADIO_DIAGNOSIS_ENABLE,
|
||||
WMI_PDEV_PARAM_MESH_MCAST_ENABLE,
|
||||
WMI_PDEV_PARAM_PER_PEER_CFR_ENABLE = 0xa8,
|
||||
WMI_PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD = 0xbc,
|
||||
WMI_PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC = 0xbe,
|
||||
WMI_PDEV_PARAM_ENABLE_SR_PROHIBIT = 0xc6,
|
||||
|
|
@ -1884,6 +1889,8 @@ enum wmi_tlv_tag {
|
|||
WMI_TAG_NDP_EVENT,
|
||||
WMI_TAG_PDEV_PEER_PKTLOG_FILTER_CMD = 0x301,
|
||||
WMI_TAG_PDEV_PEER_PKTLOG_FILTER_INFO,
|
||||
WMI_TAG_PEER_CFR_CAPTURE_EVENT = 0x317,
|
||||
WMI_TAG_CFR_CAPTURE_PHASE_PARAM = 0x33b,
|
||||
WMI_TAG_FILS_DISCOVERY_TMPL_CMD = 0x344,
|
||||
WMI_TAG_PDEV_SRG_BSS_COLOR_BITMAP_CMD = 0x37b,
|
||||
WMI_TAG_PDEV_SRG_PARTIAL_BSSID_BITMAP_CMD,
|
||||
|
|
@ -3832,7 +3839,8 @@ struct wmi_scan_prob_req_oui_cmd {
|
|||
#define WMI_TX_PARAMS_DWORD1_BW_MASK GENMASK(14, 8)
|
||||
#define WMI_TX_PARAMS_DWORD1_PREAMBLE_TYPE GENMASK(19, 15)
|
||||
#define WMI_TX_PARAMS_DWORD1_FRAME_TYPE BIT(20)
|
||||
#define WMI_TX_PARAMS_DWORD1_RSVD GENMASK(31, 21)
|
||||
#define WMI_TX_PARAMS_DWORD1_CFR_CAPTURE BIT(21)
|
||||
#define WMI_TX_PARAMS_DWORD1_RSVD GENMASK(31, 22)
|
||||
|
||||
struct wmi_mgmt_send_params {
|
||||
u32 tlv_header;
|
||||
|
|
@ -4217,6 +4225,87 @@ enum cc_setting_code {
|
|||
*/
|
||||
};
|
||||
|
||||
enum ath11k_wmi_cfr_capture_bw {
|
||||
WMI_PEER_CFR_CAPTURE_BW_20,
|
||||
WMI_PEER_CFR_CAPTURE_BW_40,
|
||||
WMI_PEER_CFR_CAPTURE_BW_80,
|
||||
WMI_PEER_CFR_CAPTURE_BW_MAX,
|
||||
};
|
||||
|
||||
enum ath11k_wmi_cfr_capture_method {
|
||||
WMI_CFR_CAPTURE_METHOD_NULL_FRAME,
|
||||
WMI_CFR_CAPTURE_METHOD_NULL_FRAME_WITH_PHASE,
|
||||
WMI_CFR_CAPTURE_METHOD_PROBE_RESP,
|
||||
WMI_CFR_CAPTURE_METHOD_MAX,
|
||||
};
|
||||
|
||||
#define WMI_CFR_FRAME_TX_STATUS GENMASK(1, 0)
|
||||
#define WMI_CFR_CAPTURE_STATUS_PEER_PS BIT(30)
|
||||
#define WMI_CFR_PEER_CAPTURE_STATUS BIT(31)
|
||||
|
||||
#define WMI_CFR_CORRELATION_INFO2_BUF_ADDR_HIGH GENMASK(3, 0)
|
||||
#define WMI_CFR_CORRELATION_INFO2_PPDU_ID GENMASK(31, 16)
|
||||
|
||||
#define WMI_CFR_CFO_MEASUREMENT_VALID BIT(0)
|
||||
#define WMI_CFR_CFO_MEASUREMENT_RAW_DATA GENMASK(14, 1)
|
||||
|
||||
struct ath11k_wmi_cfr_peer_tx_event_param {
|
||||
u32 capture_method;
|
||||
u32 vdev_id;
|
||||
struct wmi_mac_addr mac_addr;
|
||||
u32 chan_mhz;
|
||||
u32 bandwidth;
|
||||
u32 phy_mode;
|
||||
u32 band_center_freq1;
|
||||
u32 band_center_freq2;
|
||||
u32 sts_count;
|
||||
u32 correlation_info_1;
|
||||
u32 correlation_info_2;
|
||||
u32 status;
|
||||
u32 timestamp_us;
|
||||
u32 counter;
|
||||
u32 chain_rssi[WMI_MAX_CHAINS];
|
||||
u32 cfo_measurement;
|
||||
u32 rx_start_ts;
|
||||
} __packed;
|
||||
|
||||
struct ath11k_wmi_cfr_peer_tx_event_phase_param {
|
||||
u32 chain_phase[WMI_MAX_CHAINS];
|
||||
u8 agc_gain[WMI_MAX_CHAINS];
|
||||
} __packed;
|
||||
|
||||
enum ath11k_wmi_frame_tx_status {
|
||||
WMI_FRAME_TX_STATUS_OK,
|
||||
WMI_FRAME_TX_STATUS_XRETRY,
|
||||
WMI_FRAME_TX_STATUS_DROP,
|
||||
WMI_FRAME_TX_STATUS_FILTERED,
|
||||
};
|
||||
|
||||
struct wmi_peer_cfr_capture_conf_arg {
|
||||
enum ath11k_wmi_cfr_capture_bw bw;
|
||||
enum ath11k_wmi_cfr_capture_method method;
|
||||
u32 request;
|
||||
u32 periodicity;
|
||||
};
|
||||
|
||||
struct wmi_peer_cfr_capture_cmd_fixed_param {
|
||||
u32 tlv_header;
|
||||
u32 request;
|
||||
struct wmi_mac_addr mac_addr;
|
||||
u32 vdev_id;
|
||||
u32 periodicity;
|
||||
/* BW of measurement - of type enum ath11k_wmi_cfr_capture_bw */
|
||||
u32 bandwidth;
|
||||
/* Method used to capture CFR - of type enum ath11k_wmi_cfr_capture_method */
|
||||
u32 capture_method;
|
||||
} __packed;
|
||||
|
||||
#define WMI_PEER_CFR_CAPTURE_ENABLE 1
|
||||
#define WMI_PEER_CFR_CAPTURE_DISABLE 0
|
||||
|
||||
/*periodicity in ms */
|
||||
#define WMI_PEER_CFR_PERIODICITY_MAX 600000
|
||||
|
||||
static inline enum cc_setting_code
|
||||
ath11k_wmi_cc_setting_code_to_reg(enum wmi_reg_cc_setting_code status_code)
|
||||
{
|
||||
|
|
@ -6346,7 +6435,7 @@ int ath11k_wmi_cmd_send(struct ath11k_pdev_wmi *wmi, struct sk_buff *skb,
|
|||
u32 cmd_id);
|
||||
struct sk_buff *ath11k_wmi_alloc_skb(struct ath11k_wmi_base *wmi_sc, u32 len);
|
||||
int ath11k_wmi_mgmt_send(struct ath11k *ar, u32 vdev_id, u32 buf_id,
|
||||
struct sk_buff *frame);
|
||||
struct sk_buff *frame, bool tx_params_valid);
|
||||
int ath11k_wmi_p2p_go_bcn_ie(struct ath11k *ar, u32 vdev_id,
|
||||
const u8 *p2p_ie);
|
||||
int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id,
|
||||
|
|
@ -6531,5 +6620,7 @@ bool ath11k_wmi_supports_6ghz_cc_ext(struct ath11k *ar);
|
|||
int ath11k_wmi_send_vdev_set_tpc_power(struct ath11k *ar,
|
||||
u32 vdev_id,
|
||||
struct ath11k_reg_tpc_power_info *param);
|
||||
|
||||
int ath11k_wmi_peer_set_cfr_capture_conf(struct ath11k *ar,
|
||||
u32 vdev_id, const u8 *mac,
|
||||
struct wmi_peer_cfr_capture_conf_arg *arg);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -155,6 +155,7 @@ enum ath12k_hw_rev {
|
|||
ATH12K_HW_QCN9274_HW20,
|
||||
ATH12K_HW_WCN7850_HW20,
|
||||
ATH12K_HW_IPQ5332_HW10,
|
||||
ATH12K_HW_QCC2072_HW10,
|
||||
};
|
||||
|
||||
enum ath12k_firmware_mode {
|
||||
|
|
@ -1081,6 +1082,8 @@ struct ath12k_base {
|
|||
size_t amss_dualmac_len;
|
||||
const u8 *m3_data;
|
||||
size_t m3_len;
|
||||
const u8 *aux_uc_data;
|
||||
size_t aux_uc_len;
|
||||
|
||||
DECLARE_BITMAP(fw_features, ATH12K_FW_FEATURE_COUNT);
|
||||
bool fw_features_valid;
|
||||
|
|
|
|||
|
|
@ -1513,7 +1513,7 @@ static int ath12k_dp_setup(struct ath12k_base *ab)
|
|||
HAL_WBM_IDLE_LINK, srng, n_link_desc);
|
||||
if (ret) {
|
||||
ath12k_warn(ab, "failed to setup link desc: %d\n", ret);
|
||||
return ret;
|
||||
goto rhash_destroy;
|
||||
}
|
||||
|
||||
ret = ath12k_dp_cc_init(ab);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include "core.h"
|
||||
|
|
@ -121,6 +121,14 @@ static int ath12k_fw_request_firmware_api_n(struct ath12k_base *ab,
|
|||
ab->fw.m3_data = data;
|
||||
ab->fw.m3_len = ie_len;
|
||||
break;
|
||||
case ATH12K_FW_IE_AUX_UC_IMAGE:
|
||||
ath12k_dbg(ab, ATH12K_DBG_BOOT,
|
||||
"found aux_uc image ie (%zd B)\n",
|
||||
ie_len);
|
||||
|
||||
ab->fw.aux_uc_data = data;
|
||||
ab->fw.aux_uc_len = ie_len;
|
||||
break;
|
||||
case ATH12K_FW_IE_AMSS_DUALMAC_IMAGE:
|
||||
ath12k_dbg(ab, ATH12K_DBG_BOOT,
|
||||
"found dualmac fw image ie (%zd B)\n",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#ifndef ATH12K_FW_H
|
||||
|
|
@ -15,6 +15,7 @@ enum ath12k_fw_ie_type {
|
|||
ATH12K_FW_IE_AMSS_IMAGE = 2,
|
||||
ATH12K_FW_IE_M3_IMAGE = 3,
|
||||
ATH12K_FW_IE_AMSS_DUALMAC_IMAGE = 4,
|
||||
ATH12K_FW_IE_AUX_UC_IMAGE = 5,
|
||||
};
|
||||
|
||||
enum ath12k_fw_features {
|
||||
|
|
|
|||
|
|
@ -823,3 +823,49 @@ void ath12k_hal_dump_srng_stats(struct ath12k_base *ab)
|
|||
jiffies_to_msecs(jiffies - srng->timestamp));
|
||||
}
|
||||
}
|
||||
|
||||
void *ath12k_hal_encode_tlv64_hdr(void *tlv, u64 tag, u64 len)
|
||||
{
|
||||
struct hal_tlv_64_hdr *tlv64 = tlv;
|
||||
|
||||
tlv64->tl = le64_encode_bits(tag, HAL_TLV_HDR_TAG) |
|
||||
le64_encode_bits(len, HAL_TLV_HDR_LEN);
|
||||
|
||||
return tlv64->value;
|
||||
}
|
||||
EXPORT_SYMBOL(ath12k_hal_encode_tlv64_hdr);
|
||||
|
||||
void *ath12k_hal_encode_tlv32_hdr(void *tlv, u64 tag, u64 len)
|
||||
{
|
||||
struct hal_tlv_hdr *tlv32 = tlv;
|
||||
|
||||
tlv32->tl = le32_encode_bits(tag, HAL_TLV_HDR_TAG) |
|
||||
le32_encode_bits(len, HAL_TLV_HDR_LEN);
|
||||
|
||||
return tlv32->value;
|
||||
}
|
||||
EXPORT_SYMBOL(ath12k_hal_encode_tlv32_hdr);
|
||||
|
||||
u16 ath12k_hal_decode_tlv64_hdr(void *tlv, void **desc)
|
||||
{
|
||||
struct hal_tlv_64_hdr *tlv64 = tlv;
|
||||
u16 tag;
|
||||
|
||||
tag = le64_get_bits(tlv64->tl, HAL_SRNG_TLV_HDR_TAG);
|
||||
*desc = tlv64->value;
|
||||
|
||||
return tag;
|
||||
}
|
||||
EXPORT_SYMBOL(ath12k_hal_decode_tlv64_hdr);
|
||||
|
||||
u16 ath12k_hal_decode_tlv32_hdr(void *tlv, void **desc)
|
||||
{
|
||||
struct hal_tlv_hdr *tlv32 = tlv;
|
||||
u16 tag;
|
||||
|
||||
tag = le32_get_bits(tlv32->tl, HAL_SRNG_TLV_HDR_TAG);
|
||||
*desc = tlv32->value;
|
||||
|
||||
return tag;
|
||||
}
|
||||
EXPORT_SYMBOL(ath12k_hal_decode_tlv32_hdr);
|
||||
|
|
|
|||
|
|
@ -1121,6 +1121,8 @@ struct ath12k_hw_hal_params {
|
|||
u32 wbm2sw_cc_enable;
|
||||
};
|
||||
|
||||
#define ATH12K_HW_REG_UNDEFINED 0xdeadbeaf
|
||||
|
||||
struct ath12k_hw_regs {
|
||||
u32 tcl1_ring_id;
|
||||
u32 tcl1_ring_misc;
|
||||
|
|
@ -1199,6 +1201,8 @@ struct ath12k_hw_regs {
|
|||
u32 reo_status_ring_base;
|
||||
|
||||
u32 gcc_gcc_pcie_hot_rst;
|
||||
|
||||
u32 qrtr_node_id;
|
||||
};
|
||||
|
||||
/* HAL context to be used to access SRNG APIs (currently used by data path
|
||||
|
|
@ -1426,8 +1430,34 @@ struct hal_ops {
|
|||
u32 *sw_cookie,
|
||||
struct ath12k_buffer_addr **pp_buf_addr,
|
||||
u8 *rbm, u32 *msdu_cnt);
|
||||
void *(*reo_cmd_enc_tlv_hdr)(void *tlv, u64 tag, u64 len);
|
||||
u16 (*reo_status_dec_tlv_hdr)(void *tlv, void **desc);
|
||||
};
|
||||
|
||||
#define HAL_TLV_HDR_TAG GENMASK(9, 1)
|
||||
#define HAL_TLV_HDR_LEN GENMASK(25, 10)
|
||||
#define HAL_TLV_USR_ID GENMASK(31, 26)
|
||||
|
||||
#define HAL_TLV_ALIGN 4
|
||||
|
||||
struct hal_tlv_hdr {
|
||||
__le32 tl;
|
||||
u8 value[];
|
||||
} __packed;
|
||||
|
||||
#define HAL_TLV_64_HDR_TAG GENMASK(9, 1)
|
||||
#define HAL_TLV_64_HDR_LEN GENMASK(21, 10)
|
||||
#define HAL_TLV_64_USR_ID GENMASK(31, 26)
|
||||
#define HAL_TLV_64_ALIGN 8
|
||||
|
||||
struct hal_tlv_64_hdr {
|
||||
__le64 tl;
|
||||
u8 value[];
|
||||
} __packed;
|
||||
|
||||
#define HAL_SRNG_TLV_HDR_TAG GENMASK(9, 1)
|
||||
#define HAL_SRNG_TLV_HDR_LEN GENMASK(25, 10)
|
||||
|
||||
dma_addr_t ath12k_hal_srng_get_tp_addr(struct ath12k_base *ab,
|
||||
struct hal_srng *srng);
|
||||
dma_addr_t ath12k_hal_srng_get_hp_addr(struct ath12k_base *ab,
|
||||
|
|
@ -1515,4 +1545,8 @@ void ath12k_hal_rx_reo_ent_buf_paddr_get(struct ath12k_hal *hal, void *rx_desc,
|
|||
dma_addr_t *paddr, u32 *sw_cookie,
|
||||
struct ath12k_buffer_addr **pp_buf_addr,
|
||||
u8 *rbm, u32 *msdu_cnt);
|
||||
void *ath12k_hal_encode_tlv64_hdr(void *tlv, u64 tag, u64 len);
|
||||
void *ath12k_hal_encode_tlv32_hdr(void *tlv, u64 tag, u64 len);
|
||||
u16 ath12k_hal_decode_tlv64_hdr(void *tlv, void **desc);
|
||||
u16 ath12k_hal_decode_tlv32_hdr(void *tlv, void **desc);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@
|
|||
#define ATH12K_DEFAULT_CAL_FILE "caldata.bin"
|
||||
#define ATH12K_AMSS_FILE "amss.bin"
|
||||
#define ATH12K_M3_FILE "m3.bin"
|
||||
#define ATH12K_AUX_UC_FILE "aux_ucode.bin"
|
||||
#define ATH12K_REGDB_FILE_NAME "regdb.bin"
|
||||
|
||||
#define ATH12K_PCIE_MAX_PAYLOAD_SIZE 128
|
||||
|
|
@ -142,6 +143,7 @@ struct ath12k_hw_params {
|
|||
size_t board_size;
|
||||
size_t cal_offset;
|
||||
enum ath12k_m3_fw_loaders m3_loader;
|
||||
bool download_aux_ucode:1;
|
||||
} fw;
|
||||
|
||||
u8 max_radios;
|
||||
|
|
|
|||
|
|
@ -14530,7 +14530,7 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)
|
|||
if (is_monitor_disable)
|
||||
/* There's a race between calling ieee80211_register_hw()
|
||||
* and here where the monitor mode is enabled for a little
|
||||
* while. But that time is so short and in practise it make
|
||||
* while. But that time is so short and in practice it doesn't make
|
||||
* a difference in real life.
|
||||
*/
|
||||
wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MONITOR);
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
#define ATH12K_PCI_IRQ_CE0_OFFSET 3
|
||||
|
||||
#define WINDOW_ENABLE_BIT 0x40000000
|
||||
#define WINDOW_REG_ADDRESS 0x310c
|
||||
#define WINDOW_VALUE_MASK GENMASK(24, 19)
|
||||
#define WINDOW_START 0x80000
|
||||
#define WINDOW_RANGE_MASK GENMASK(18, 0)
|
||||
|
|
@ -35,10 +34,6 @@
|
|||
*/
|
||||
#define ACCESS_ALWAYS_OFF 0xFE0
|
||||
|
||||
#define PCIE_LOCAL_REG_QRTR_NODE_ID 0x1E03164
|
||||
#define DOMAIN_NUMBER_MASK GENMASK(7, 4)
|
||||
#define BUS_NUMBER_MASK GENMASK(3, 0)
|
||||
|
||||
static struct ath12k_pci_driver *ath12k_pci_family_drivers[ATH12K_DEVICE_FAMILY_MAX];
|
||||
static const struct ath12k_msi_config msi_config_one_msi = {
|
||||
.total_vectors = 1,
|
||||
|
|
@ -125,8 +120,8 @@ static void ath12k_pci_select_window(struct ath12k_pci *ab_pci, u32 offset)
|
|||
|
||||
if (window != ab_pci->register_window) {
|
||||
iowrite32(WINDOW_ENABLE_BIT | window,
|
||||
ab->mem + WINDOW_REG_ADDRESS);
|
||||
ioread32(ab->mem + WINDOW_REG_ADDRESS);
|
||||
ab->mem + ab_pci->window_reg_addr);
|
||||
ioread32(ab->mem + ab_pci->window_reg_addr);
|
||||
ab_pci->register_window = window;
|
||||
}
|
||||
}
|
||||
|
|
@ -145,7 +140,7 @@ static void ath12k_pci_select_static_window(struct ath12k_pci *ab_pci)
|
|||
ab_pci->register_window = window;
|
||||
spin_unlock_bh(&ab_pci->window_lock);
|
||||
|
||||
iowrite32(WINDOW_ENABLE_BIT | window, ab_pci->ab->mem + WINDOW_REG_ADDRESS);
|
||||
iowrite32(WINDOW_ENABLE_BIT | window, ab_pci->ab->mem + ab_pci->window_reg_addr);
|
||||
}
|
||||
|
||||
static u32 ath12k_pci_get_window_start(struct ath12k_base *ab,
|
||||
|
|
@ -178,8 +173,8 @@ static void ath12k_pci_restore_window(struct ath12k_base *ab)
|
|||
spin_lock_bh(&ab_pci->window_lock);
|
||||
|
||||
iowrite32(WINDOW_ENABLE_BIT | ab_pci->register_window,
|
||||
ab->mem + WINDOW_REG_ADDRESS);
|
||||
ioread32(ab->mem + WINDOW_REG_ADDRESS);
|
||||
ab->mem + ab_pci->window_reg_addr);
|
||||
ioread32(ab->mem + ab_pci->window_reg_addr);
|
||||
|
||||
spin_unlock_bh(&ab_pci->window_lock);
|
||||
}
|
||||
|
|
@ -919,7 +914,7 @@ static void ath12k_pci_update_qrtr_node_id(struct ath12k_base *ab)
|
|||
* writes to the given register, it is available for firmware when the QMI service
|
||||
* is spawned.
|
||||
*/
|
||||
reg = PCIE_LOCAL_REG_QRTR_NODE_ID & WINDOW_RANGE_MASK;
|
||||
reg = PCIE_LOCAL_REG_QRTR_NODE_ID(ab) & WINDOW_RANGE_MASK;
|
||||
ath12k_pci_write32(ab, reg, ab_pci->qmi_instance);
|
||||
|
||||
ath12k_dbg(ab, ATH12K_DBG_PCI, "pci reg 0x%x instance 0x%x read val 0x%x\n",
|
||||
|
|
@ -1541,7 +1536,6 @@ static int ath12k_pci_probe(struct pci_dev *pdev,
|
|||
}
|
||||
|
||||
ab->dev = &pdev->dev;
|
||||
pci_set_drvdata(pdev, ab);
|
||||
ab_pci = ath12k_pci_priv(ab);
|
||||
ab_pci->dev_id = pci_dev->device;
|
||||
ab_pci->ab = ab;
|
||||
|
|
|
|||
|
|
@ -59,6 +59,11 @@
|
|||
#define QCN9274_QFPROM_RAW_RFA_PDET_ROW13_LSB 0x1E20338
|
||||
#define OTP_BOARD_ID_MASK GENMASK(15, 0)
|
||||
|
||||
#define PCIE_LOCAL_REG_QRTR_NODE_ID(ab) \
|
||||
((ab)->hal.regs->qrtr_node_id)
|
||||
#define DOMAIN_NUMBER_MASK GENMASK(7, 4)
|
||||
#define BUS_NUMBER_MASK GENMASK(3, 0)
|
||||
|
||||
#define PCI_BAR_WINDOW0_BASE 0x1E00000
|
||||
#define PCI_BAR_WINDOW0_END 0x1E7FFFC
|
||||
#define PCI_SOC_RANGE_MASK 0x3FFF
|
||||
|
|
@ -130,6 +135,8 @@ struct ath12k_pci {
|
|||
u64 dma_mask;
|
||||
const struct ath12k_pci_device_family_ops *device_family_ops;
|
||||
const struct ath12k_pci_reg_base *reg_base;
|
||||
|
||||
u32 window_reg_addr;
|
||||
};
|
||||
|
||||
struct ath12k_pci_driver {
|
||||
|
|
|
|||
|
|
@ -1623,6 +1623,47 @@ static const struct qmi_elem_info qmi_wlanfw_m3_info_resp_msg_v01_ei[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static const struct qmi_elem_info qmi_wlanfw_aux_uc_info_req_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_8_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u64),
|
||||
.array_type = NO_ARRAY,
|
||||
.tlv_type = 0x01,
|
||||
.offset = offsetof(struct qmi_wlanfw_aux_uc_info_req_msg_v01, addr),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u32),
|
||||
.array_type = NO_ARRAY,
|
||||
.tlv_type = 0x02,
|
||||
.offset = offsetof(struct qmi_wlanfw_aux_uc_info_req_msg_v01, size),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.array_type = NO_ARRAY,
|
||||
.tlv_type = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct qmi_elem_info qmi_wlanfw_aux_uc_info_resp_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_STRUCT,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(struct qmi_response_type_v01),
|
||||
.array_type = NO_ARRAY,
|
||||
.tlv_type = 0x02,
|
||||
.offset = offsetof(struct qmi_wlanfw_aux_uc_info_resp_msg_v01, resp),
|
||||
.ei_array = qmi_response_type_v01_ei,
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.array_type = NO_ARRAY,
|
||||
.tlv_type = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct qmi_elem_info qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
|
|
@ -2609,6 +2650,7 @@ static int ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base *ab)
|
|||
case M3_DUMP_REGION_TYPE:
|
||||
case PAGEABLE_MEM_REGION_TYPE:
|
||||
case CALDB_MEM_REGION_TYPE:
|
||||
case LPASS_SHARED_V01_REGION_TYPE:
|
||||
ret = ath12k_qmi_alloc_chunk(ab, chunk);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
|
@ -3236,6 +3278,131 @@ int ath12k_qmi_wlanfw_m3_info_send(struct ath12k_base *ab)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void ath12k_qmi_aux_uc_free(struct ath12k_base *ab)
|
||||
{
|
||||
struct m3_mem_region *aux_uc_mem = &ab->qmi.aux_uc_mem;
|
||||
|
||||
if (!aux_uc_mem->vaddr)
|
||||
return;
|
||||
|
||||
dma_free_coherent(ab->dev, aux_uc_mem->total_size,
|
||||
aux_uc_mem->vaddr, aux_uc_mem->paddr);
|
||||
aux_uc_mem->vaddr = NULL;
|
||||
aux_uc_mem->total_size = 0;
|
||||
aux_uc_mem->size = 0;
|
||||
}
|
||||
|
||||
static int ath12k_qmi_aux_uc_load(struct ath12k_base *ab)
|
||||
{
|
||||
struct m3_mem_region *aux_uc_mem = &ab->qmi.aux_uc_mem;
|
||||
const struct firmware *fw = NULL;
|
||||
const void *aux_uc_data;
|
||||
char path[100];
|
||||
size_t aux_uc_len;
|
||||
int ret;
|
||||
|
||||
if (ab->fw.aux_uc_data && ab->fw.aux_uc_len > 0) {
|
||||
/* firmware-N.bin had a aux_uc firmware file so use that */
|
||||
aux_uc_data = ab->fw.aux_uc_data;
|
||||
aux_uc_len = ab->fw.aux_uc_len;
|
||||
} else {
|
||||
/*
|
||||
* No aux_uc file in firmware-N.bin so try to request old
|
||||
* separate aux_ucode.bin.
|
||||
*/
|
||||
fw = ath12k_core_firmware_request(ab, ATH12K_AUX_UC_FILE);
|
||||
if (IS_ERR(fw)) {
|
||||
ret = PTR_ERR(fw);
|
||||
ath12k_core_create_firmware_path(ab, ATH12K_AUX_UC_FILE,
|
||||
path, sizeof(path));
|
||||
ath12k_err(ab, "failed to load %s: %d\n", path, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
aux_uc_data = fw->data;
|
||||
aux_uc_len = fw->size;
|
||||
}
|
||||
|
||||
/* In recovery/resume cases, AUX_UC buffer is not freed, try to reuse that */
|
||||
if (aux_uc_mem->vaddr) {
|
||||
if (aux_uc_mem->total_size >= aux_uc_len)
|
||||
goto copy;
|
||||
|
||||
/* Old buffer is too small, free and reallocate */
|
||||
ath12k_qmi_aux_uc_free(ab);
|
||||
}
|
||||
|
||||
aux_uc_mem->vaddr = dma_alloc_coherent(ab->dev, aux_uc_len,
|
||||
&aux_uc_mem->paddr, GFP_KERNEL);
|
||||
if (!aux_uc_mem->vaddr) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
aux_uc_mem->total_size = aux_uc_len;
|
||||
|
||||
copy:
|
||||
memcpy(aux_uc_mem->vaddr, aux_uc_data, aux_uc_len);
|
||||
aux_uc_mem->size = aux_uc_len;
|
||||
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
release_firmware(fw);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static noinline_for_stack
|
||||
int ath12k_qmi_wlanfw_aux_uc_info_send(struct ath12k_base *ab)
|
||||
{
|
||||
struct m3_mem_region *aux_uc_mem = &ab->qmi.aux_uc_mem;
|
||||
struct qmi_wlanfw_aux_uc_info_req_msg_v01 req = {};
|
||||
struct qmi_wlanfw_aux_uc_info_resp_msg_v01 resp = {};
|
||||
struct qmi_txn txn;
|
||||
int ret = 0;
|
||||
|
||||
ret = ath12k_qmi_aux_uc_load(ab);
|
||||
if (ret) {
|
||||
ath12k_err(ab, "failed to load aux_uc firmware: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
req.addr = aux_uc_mem->paddr;
|
||||
req.size = aux_uc_mem->size;
|
||||
|
||||
ret = qmi_txn_init(&ab->qmi.handle, &txn,
|
||||
qmi_wlanfw_aux_uc_info_resp_msg_v01_ei, &resp);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
|
||||
QMI_WLANFW_AUX_UC_INFO_REQ_V01,
|
||||
QMI_WLANFW_AUX_UC_INFO_REQ_MSG_V01_MAX_MSG_LEN,
|
||||
qmi_wlanfw_aux_uc_info_req_msg_v01_ei, &req);
|
||||
if (ret < 0) {
|
||||
qmi_txn_cancel(&txn);
|
||||
ath12k_warn(ab, "qmi failed to send AUX_UC information request, err = %d\n",
|
||||
ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
|
||||
if (ret < 0) {
|
||||
ath12k_warn(ab, "qmi failed AUX_UC information request %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
|
||||
ath12k_warn(ab, "qmi AUX_UC info request failed, result: %d, err: %d\n",
|
||||
resp.resp.result, resp.resp.error);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath12k_qmi_wlanfw_mode_send(struct ath12k_base *ab,
|
||||
u32 mode)
|
||||
{
|
||||
|
|
@ -3600,6 +3767,7 @@ static noinline_for_stack
|
|||
int ath12k_qmi_event_load_bdf(struct ath12k_qmi *qmi)
|
||||
{
|
||||
struct ath12k_base *ab = qmi->ab;
|
||||
const struct ath12k_hw_params *hw_params = ab->hw_params;
|
||||
int ret;
|
||||
|
||||
ret = ath12k_qmi_request_target_cap(ab);
|
||||
|
|
@ -3620,7 +3788,7 @@ int ath12k_qmi_event_load_bdf(struct ath12k_qmi *qmi)
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (ab->hw_params->download_calib) {
|
||||
if (hw_params->download_calib) {
|
||||
ret = ath12k_qmi_load_bdf_qmi(ab, ATH12K_QMI_BDF_TYPE_CALIBRATION);
|
||||
if (ret < 0)
|
||||
ath12k_warn(ab, "qmi failed to load calibrated data :%d\n", ret);
|
||||
|
|
@ -3632,6 +3800,14 @@ int ath12k_qmi_event_load_bdf(struct ath12k_qmi *qmi)
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (hw_params->fw.download_aux_ucode) {
|
||||
ret = ath12k_qmi_wlanfw_aux_uc_info_send(ab);
|
||||
if (ret < 0) {
|
||||
ath12k_warn(ab, "qmi failed to send aux_uc info req: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -3905,6 +4081,7 @@ void ath12k_qmi_deinit_service(struct ath12k_base *ab)
|
|||
qmi_handle_release(&ab->qmi.handle);
|
||||
cancel_work_sync(&ab->qmi.event_work);
|
||||
destroy_workqueue(ab->qmi.event_wq);
|
||||
ath12k_qmi_aux_uc_free(ab);
|
||||
ath12k_qmi_m3_free(ab);
|
||||
ath12k_qmi_free_target_mem_chunk(ab);
|
||||
ab->qmi.ab = NULL;
|
||||
|
|
@ -3913,5 +4090,6 @@ void ath12k_qmi_deinit_service(struct ath12k_base *ab)
|
|||
void ath12k_qmi_free_resource(struct ath12k_base *ab)
|
||||
{
|
||||
ath12k_qmi_free_target_mem_chunk(ab);
|
||||
ath12k_qmi_aux_uc_free(ab);
|
||||
ath12k_qmi_m3_free(ab);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,6 +154,7 @@ struct ath12k_qmi {
|
|||
u8 num_radios;
|
||||
struct target_info target;
|
||||
struct m3_mem_region m3_mem;
|
||||
struct m3_mem_region aux_uc_mem;
|
||||
unsigned int service_ins_id;
|
||||
struct dev_mem_info dev_mem[ATH12K_QMI_WLFW_MAX_DEV_MEM_NUM_V01];
|
||||
};
|
||||
|
|
@ -178,6 +179,7 @@ enum ath12k_qmi_target_mem {
|
|||
CALDB_MEM_REGION_TYPE = 0x4,
|
||||
MLO_GLOBAL_MEM_REGION_TYPE = 0x8,
|
||||
PAGEABLE_MEM_REGION_TYPE = 0x9,
|
||||
LPASS_SHARED_V01_REGION_TYPE = 0xb,
|
||||
};
|
||||
|
||||
enum qmi_wlanfw_host_build_type {
|
||||
|
|
@ -202,6 +204,7 @@ enum ath12k_qmi_cnss_feature {
|
|||
CNSS_FEATURE_MIN_ENUM_VAL_V01 = INT_MIN,
|
||||
CNSS_QDSS_CFG_MISS_V01 = 3,
|
||||
CNSS_PCIE_PERST_NO_PULL_V01 = 4,
|
||||
CNSS_AUX_UC_SUPPORT_V01 = 6,
|
||||
CNSS_MAX_FEATURE_V01 = 64,
|
||||
CNSS_FEATURE_MAX_ENUM_VAL_V01 = INT_MAX,
|
||||
};
|
||||
|
|
@ -540,6 +543,19 @@ struct qmi_wlanfw_m3_info_resp_msg_v01 {
|
|||
struct qmi_response_type_v01 resp;
|
||||
};
|
||||
|
||||
#define QMI_WLANFW_AUX_UC_INFO_REQ_MSG_V01_MAX_MSG_LEN 18
|
||||
#define QMI_WLANFW_AUX_UC_INFO_RESP_MSG_V01_MAX_MSG_LEN 7
|
||||
#define QMI_WLANFW_AUX_UC_INFO_REQ_V01 0x005A
|
||||
|
||||
struct qmi_wlanfw_aux_uc_info_req_msg_v01 {
|
||||
u64 addr;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
struct qmi_wlanfw_aux_uc_info_resp_msg_v01 {
|
||||
struct qmi_response_type_v01 resp;
|
||||
};
|
||||
|
||||
#define QMI_WLANFW_WLAN_MODE_REQ_MSG_V01_MAX_LEN 11
|
||||
#define QMI_WLANFW_WLAN_MODE_RESP_MSG_V01_MAX_LEN 7
|
||||
#define QMI_WLANFW_WLAN_CFG_REQ_MSG_V01_MAX_LEN 803
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ ath12k_wifi7-y += core.o \
|
|||
dp_mon.o \
|
||||
hal.o \
|
||||
hal_qcn9274.o \
|
||||
hal_wcn7850.o
|
||||
hal_wcn7850.o \
|
||||
hal_qcc2072.o
|
||||
|
||||
ath12k_wifi7-$(CONFIG_ATH12K_AHB) += ahb.o
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include "../peer.h"
|
||||
#include "hal_qcn9274.h"
|
||||
#include "hal_wcn7850.h"
|
||||
#include "hal_qcc2072.h"
|
||||
|
||||
static u16 ath12k_wifi7_dp_rx_get_peer_id(struct ath12k_dp *dp,
|
||||
enum ath12k_peer_metadata_version ver,
|
||||
|
|
@ -2110,16 +2111,59 @@ int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int ath12k_dp_rxdma_ring_sel_config_qcc2072(struct ath12k_base *ab)
|
||||
{
|
||||
struct ath12k_dp *dp = ath12k_ab_to_dp(ab);
|
||||
struct htt_rx_ring_tlv_filter tlv_filter = {};
|
||||
u32 ring_id;
|
||||
int ret = 0;
|
||||
u32 hal_rx_desc_sz = ab->hal.hal_desc_sz;
|
||||
int i;
|
||||
|
||||
ring_id = dp->rx_refill_buf_ring.refill_buf_ring.ring_id;
|
||||
|
||||
tlv_filter.rx_filter = HTT_RX_TLV_FLAGS_RXDMA_RING;
|
||||
tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_PKT_FILTER_TLV_FLAGS2_BAR;
|
||||
tlv_filter.pkt_filter_flags3 = HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_MCAST |
|
||||
HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_UCAST |
|
||||
HTT_RX_FP_DATA_PKT_FILTER_TLV_FLASG3_NULL_DATA;
|
||||
tlv_filter.offset_valid = true;
|
||||
tlv_filter.rx_packet_offset = hal_rx_desc_sz;
|
||||
|
||||
tlv_filter.rx_header_offset = offsetof(struct hal_rx_desc_qcc2072, pkt_hdr_tlv);
|
||||
|
||||
tlv_filter.rx_mpdu_start_offset =
|
||||
ath12k_hal_rx_desc_get_mpdu_start_offset_qcc2072();
|
||||
tlv_filter.rx_msdu_end_offset =
|
||||
ath12k_hal_rx_desc_get_msdu_end_offset_qcc2072();
|
||||
|
||||
/*
|
||||
* TODO: Selectively subscribe to required qwords within msdu_end
|
||||
* and mpdu_start and setup the mask in below msg
|
||||
* and modify the rx_desc struct
|
||||
*/
|
||||
|
||||
for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
|
||||
ring_id = dp->rx_mac_buf_ring[i].ring_id;
|
||||
ret = ath12k_dp_tx_htt_rx_filter_setup(ab, ring_id, i,
|
||||
HAL_RXDMA_BUF,
|
||||
DP_RXDMA_REFILL_RING_SIZE,
|
||||
&tlv_filter);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_dp *dp)
|
||||
{
|
||||
struct ath12k_base *ab = dp->ab;
|
||||
struct ath12k_hal *hal = dp->hal;
|
||||
struct hal_tlv_64_hdr *hdr;
|
||||
struct hal_srng *srng;
|
||||
struct ath12k_dp_rx_reo_cmd *cmd, *tmp;
|
||||
bool found = false;
|
||||
u16 tag;
|
||||
struct hal_reo_status reo_status;
|
||||
void *hdr, *desc;
|
||||
|
||||
srng = &hal->srng_list[dp->reo_status_ring.ring_id];
|
||||
|
||||
|
|
@ -2130,35 +2174,35 @@ void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_dp *dp)
|
|||
ath12k_hal_srng_access_begin(ab, srng);
|
||||
|
||||
while ((hdr = ath12k_hal_srng_dst_get_next_entry(ab, srng))) {
|
||||
tag = le64_get_bits(hdr->tl, HAL_SRNG_TLV_HDR_TAG);
|
||||
tag = hal->ops->reo_status_dec_tlv_hdr(hdr, &desc);
|
||||
|
||||
switch (tag) {
|
||||
case HAL_REO_GET_QUEUE_STATS_STATUS:
|
||||
ath12k_wifi7_hal_reo_status_queue_stats(ab, hdr,
|
||||
ath12k_wifi7_hal_reo_status_queue_stats(ab, desc,
|
||||
&reo_status);
|
||||
break;
|
||||
case HAL_REO_FLUSH_QUEUE_STATUS:
|
||||
ath12k_wifi7_hal_reo_flush_queue_status(ab, hdr,
|
||||
ath12k_wifi7_hal_reo_flush_queue_status(ab, desc,
|
||||
&reo_status);
|
||||
break;
|
||||
case HAL_REO_FLUSH_CACHE_STATUS:
|
||||
ath12k_wifi7_hal_reo_flush_cache_status(ab, hdr,
|
||||
ath12k_wifi7_hal_reo_flush_cache_status(ab, desc,
|
||||
&reo_status);
|
||||
break;
|
||||
case HAL_REO_UNBLOCK_CACHE_STATUS:
|
||||
ath12k_wifi7_hal_reo_unblk_cache_status(ab, hdr,
|
||||
ath12k_wifi7_hal_reo_unblk_cache_status(ab, desc,
|
||||
&reo_status);
|
||||
break;
|
||||
case HAL_REO_FLUSH_TIMEOUT_LIST_STATUS:
|
||||
ath12k_wifi7_hal_reo_flush_timeout_list_status(ab, hdr,
|
||||
ath12k_wifi7_hal_reo_flush_timeout_list_status(ab, desc,
|
||||
&reo_status);
|
||||
break;
|
||||
case HAL_REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS:
|
||||
ath12k_wifi7_hal_reo_desc_thresh_reached_status(ab, hdr,
|
||||
ath12k_wifi7_hal_reo_desc_thresh_reached_status(ab, desc,
|
||||
&reo_status);
|
||||
break;
|
||||
case HAL_REO_UPDATE_RX_REO_QUEUE_STATUS:
|
||||
ath12k_wifi7_hal_reo_update_rx_reo_queue_status(ab, hdr,
|
||||
ath12k_wifi7_hal_reo_update_rx_reo_queue_status(ab, desc,
|
||||
&reo_status);
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_dp *dp, int mac_id,
|
|||
void ath12k_wifi7_dp_rx_process_reo_status(struct ath12k_dp *dp);
|
||||
int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab);
|
||||
int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab);
|
||||
int ath12k_dp_rxdma_ring_sel_config_qcc2072(struct ath12k_base *ab);
|
||||
void ath12k_wifi7_dp_setup_pn_check_reo_cmd(struct ath12k_hal_reo_cmd *cmd,
|
||||
struct ath12k_dp_rx_tid *rx_tid,
|
||||
u32 cipher, enum set_key_cmd key_cmd);
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include "../hif.h"
|
||||
#include "hal_qcn9274.h"
|
||||
#include "hal_wcn7850.h"
|
||||
#include "hal_qcc2072.h"
|
||||
|
||||
static const struct ath12k_hw_version_map ath12k_wifi7_hw_ver_map[] = {
|
||||
[ATH12K_HW_QCN9274_HW10] = {
|
||||
|
|
@ -42,6 +43,13 @@ static const struct ath12k_hw_version_map ath12k_wifi7_hw_ver_map[] = {
|
|||
.hal_params = &ath12k_hw_hal_params_ipq5332,
|
||||
.hw_regs = &ipq5332_regs,
|
||||
},
|
||||
[ATH12K_HW_QCC2072_HW10] = {
|
||||
.hal_ops = &hal_qcc2072_ops,
|
||||
.hal_desc_sz = sizeof(struct hal_rx_desc_qcc2072),
|
||||
.tcl_to_wbm_rbm_map = ath12k_hal_tcl_to_wbm_rbm_map_wcn7850,
|
||||
.hal_params = &ath12k_hw_hal_params_wcn7850,
|
||||
.hw_regs = &qcc2072_regs,
|
||||
},
|
||||
};
|
||||
|
||||
int ath12k_wifi7_hal_init(struct ath12k_base *ab)
|
||||
|
|
|
|||
|
|
@ -369,9 +369,6 @@
|
|||
#define HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_USEC (100 * 1000)
|
||||
#define HAL_DEFAULT_VO_REO_TIMEOUT_USEC (40 * 1000)
|
||||
|
||||
#define HAL_SRNG_TLV_HDR_TAG GENMASK(9, 1)
|
||||
#define HAL_SRNG_TLV_HDR_LEN GENMASK(25, 10)
|
||||
|
||||
#define HAL_SRNG_DESC_LOOP_CNT 0xf0000000
|
||||
|
||||
#define HAL_REO_CMD_FLG_NEED_STATUS BIT(0)
|
||||
|
|
|
|||
|
|
@ -487,27 +487,6 @@ enum hal_tlv_tag {
|
|||
HAL_TLV_BASE = 511 /* 0x1ff */,
|
||||
};
|
||||
|
||||
#define HAL_TLV_HDR_TAG GENMASK(9, 1)
|
||||
#define HAL_TLV_HDR_LEN GENMASK(25, 10)
|
||||
#define HAL_TLV_USR_ID GENMASK(31, 26)
|
||||
|
||||
#define HAL_TLV_ALIGN 4
|
||||
|
||||
struct hal_tlv_hdr {
|
||||
__le32 tl;
|
||||
u8 value[];
|
||||
} __packed;
|
||||
|
||||
#define HAL_TLV_64_HDR_TAG GENMASK(9, 1)
|
||||
#define HAL_TLV_64_HDR_LEN GENMASK(21, 10)
|
||||
#define HAL_TLV_64_USR_ID GENMASK(31, 26)
|
||||
#define HAL_TLV_64_ALIGN 8
|
||||
|
||||
struct hal_tlv_64_hdr {
|
||||
__le64 tl;
|
||||
u8 value[];
|
||||
} __packed;
|
||||
|
||||
#define RX_MPDU_DESC_INFO0_MSDU_COUNT GENMASK(7, 0)
|
||||
#define RX_MPDU_DESC_INFO0_FRAG_FLAG BIT(8)
|
||||
#define RX_MPDU_DESC_INFO0_MPDU_RETRY BIT(9)
|
||||
|
|
@ -1070,6 +1049,13 @@ struct hal_reo_get_queue_stats {
|
|||
* Hole_count
|
||||
*/
|
||||
|
||||
struct hal_reo_get_queue_stats_qcc2072 {
|
||||
struct hal_reo_cmd_hdr cmd;
|
||||
__le32 queue_addr_lo;
|
||||
__le32 info0;
|
||||
__le32 rsvd0[6];
|
||||
} __packed;
|
||||
|
||||
#define HAL_REO_FLUSH_QUEUE_INFO0_DESC_ADDR_HI GENMASK(7, 0)
|
||||
#define HAL_REO_FLUSH_QUEUE_INFO0_BLOCK_DESC_ADDR BIT(8)
|
||||
#define HAL_REO_FLUSH_QUEUE_INFO0_BLOCK_RESRC_IDX GENMASK(10, 9)
|
||||
|
|
@ -2453,6 +2439,11 @@ struct hal_reo_get_queue_stats_status {
|
|||
* entries into this Ring has looped around the ring.
|
||||
*/
|
||||
|
||||
struct hal_reo_get_queue_stats_status_qcc2072 {
|
||||
__le32 tlv32_padding;
|
||||
struct hal_reo_get_queue_stats_status status;
|
||||
} __packed;
|
||||
|
||||
#define HAL_REO_STATUS_LOOP_CNT GENMASK(31, 28)
|
||||
|
||||
#define HAL_REO_FLUSH_QUEUE_INFO0_ERR_DETECTED BIT(0)
|
||||
|
|
|
|||
503
drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c
Normal file
503
drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c
Normal file
|
|
@ -0,0 +1,503 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
/*
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include "hal_qcc2072.h"
|
||||
#include "hal_wcn7850.h"
|
||||
|
||||
const struct ath12k_hw_regs qcc2072_regs = {
|
||||
/* SW2TCL(x) R0 ring configuration address */
|
||||
.tcl1_ring_id = 0x00000920,
|
||||
.tcl1_ring_misc = 0x00000928,
|
||||
.tcl1_ring_tp_addr_lsb = 0x00000934,
|
||||
.tcl1_ring_tp_addr_msb = 0x00000938,
|
||||
.tcl1_ring_consumer_int_setup_ix0 = 0x00000948,
|
||||
.tcl1_ring_consumer_int_setup_ix1 = 0x0000094c,
|
||||
.tcl1_ring_msi1_base_lsb = 0x00000960,
|
||||
.tcl1_ring_msi1_base_msb = 0x00000964,
|
||||
.tcl1_ring_msi1_data = 0x00000968,
|
||||
.tcl_ring_base_lsb = 0x00000b70,
|
||||
.tcl1_ring_base_lsb = 0x00000918,
|
||||
.tcl1_ring_base_msb = 0x0000091c,
|
||||
.tcl2_ring_base_lsb = 0x00000990,
|
||||
|
||||
/* TCL STATUS ring address */
|
||||
.tcl_status_ring_base_lsb = 0x00000d50,
|
||||
|
||||
.wbm_idle_ring_base_lsb = 0x00000d3c,
|
||||
.wbm_idle_ring_misc_addr = 0x00000d4c,
|
||||
.wbm_r0_idle_list_cntl_addr = 0x00000240,
|
||||
.wbm_r0_idle_list_size_addr = 0x00000244,
|
||||
.wbm_scattered_ring_base_lsb = 0x00000250,
|
||||
.wbm_scattered_ring_base_msb = 0x00000254,
|
||||
.wbm_scattered_desc_head_info_ix0 = 0x00000260,
|
||||
.wbm_scattered_desc_head_info_ix1 = 0x00000264,
|
||||
.wbm_scattered_desc_tail_info_ix0 = 0x00000270,
|
||||
.wbm_scattered_desc_tail_info_ix1 = 0x00000274,
|
||||
.wbm_scattered_desc_ptr_hp_addr = 0x00000027c,
|
||||
|
||||
.wbm_sw_release_ring_base_lsb = 0x0000037c,
|
||||
.wbm_sw1_release_ring_base_lsb = ATH12K_HW_REG_UNDEFINED,
|
||||
.wbm0_release_ring_base_lsb = 0x00000e08,
|
||||
.wbm1_release_ring_base_lsb = 0x00000e80,
|
||||
|
||||
/* PCIe base address */
|
||||
.pcie_qserdes_sysclk_en_sel = 0x01e0c0ac,
|
||||
.pcie_pcs_osc_dtct_config_base = 0x01e0cc58,
|
||||
|
||||
/* PPE release ring address */
|
||||
.ppe_rel_ring_base = 0x0000046c,
|
||||
|
||||
/* REO DEST ring address */
|
||||
.reo2_ring_base = 0x00000578,
|
||||
.reo1_misc_ctrl_addr = 0x00000ba0,
|
||||
.reo1_sw_cookie_cfg0 = 0x0000006c,
|
||||
.reo1_sw_cookie_cfg1 = 0x00000070,
|
||||
.reo1_qdesc_lut_base0 = ATH12K_HW_REG_UNDEFINED,
|
||||
.reo1_qdesc_lut_base1 = ATH12K_HW_REG_UNDEFINED,
|
||||
|
||||
.reo1_ring_base_lsb = 0x00000500,
|
||||
.reo1_ring_base_msb = 0x00000504,
|
||||
.reo1_ring_id = 0x00000508,
|
||||
.reo1_ring_misc = 0x00000510,
|
||||
.reo1_ring_hp_addr_lsb = 0x00000514,
|
||||
.reo1_ring_hp_addr_msb = 0x00000518,
|
||||
.reo1_ring_producer_int_setup = 0x00000524,
|
||||
.reo1_ring_msi1_base_lsb = 0x00000548,
|
||||
.reo1_ring_msi1_base_msb = 0x0000054c,
|
||||
.reo1_ring_msi1_data = 0x00000550,
|
||||
.reo1_aging_thres_ix0 = 0x00000b2c,
|
||||
.reo1_aging_thres_ix1 = 0x00000b30,
|
||||
.reo1_aging_thres_ix2 = 0x00000b34,
|
||||
.reo1_aging_thres_ix3 = 0x00000b38,
|
||||
|
||||
/* REO Exception ring address */
|
||||
.reo2_sw0_ring_base = 0x000008c0,
|
||||
|
||||
/* REO Reinject ring address */
|
||||
.sw2reo_ring_base = 0x00000320,
|
||||
.sw2reo1_ring_base = 0x00000398,
|
||||
|
||||
/* REO cmd ring address */
|
||||
.reo_cmd_ring_base = 0x000002a8,
|
||||
|
||||
/* REO status ring address */
|
||||
.reo_status_ring_base = 0x00000aa0,
|
||||
|
||||
/* CE base address */
|
||||
.umac_ce0_src_reg_base = 0x01b80000,
|
||||
.umac_ce0_dest_reg_base = 0x01b81000,
|
||||
.umac_ce1_src_reg_base = 0x01b82000,
|
||||
.umac_ce1_dest_reg_base = 0x01b83000,
|
||||
|
||||
.gcc_gcc_pcie_hot_rst = 0x1e65304,
|
||||
|
||||
.qrtr_node_id = 0x1e03300,
|
||||
};
|
||||
|
||||
static void ath12k_hal_rx_desc_set_msdu_len_qcc2072(struct hal_rx_desc *desc, u16 len)
|
||||
{
|
||||
u32 info = __le32_to_cpu(desc->u.qcc2072.msdu_end.info10);
|
||||
|
||||
info &= ~RX_MSDU_END_INFO10_MSDU_LENGTH;
|
||||
info |= u32_encode_bits(len, RX_MSDU_END_INFO10_MSDU_LENGTH);
|
||||
|
||||
desc->u.qcc2072.msdu_end.info10 = __cpu_to_le32(info);
|
||||
}
|
||||
|
||||
static void ath12k_hal_rx_desc_get_dot11_hdr_qcc2072(struct hal_rx_desc *desc,
|
||||
struct ieee80211_hdr *hdr)
|
||||
{
|
||||
hdr->frame_control = desc->u.qcc2072.mpdu_start.frame_ctrl;
|
||||
hdr->duration_id = desc->u.qcc2072.mpdu_start.duration;
|
||||
ether_addr_copy(hdr->addr1, desc->u.qcc2072.mpdu_start.addr1);
|
||||
ether_addr_copy(hdr->addr2, desc->u.qcc2072.mpdu_start.addr2);
|
||||
ether_addr_copy(hdr->addr3, desc->u.qcc2072.mpdu_start.addr3);
|
||||
|
||||
if (__le32_to_cpu(desc->u.qcc2072.mpdu_start.info4) &
|
||||
RX_MPDU_START_INFO4_MAC_ADDR4_VALID)
|
||||
ether_addr_copy(hdr->addr4, desc->u.qcc2072.mpdu_start.addr4);
|
||||
|
||||
hdr->seq_ctrl = desc->u.qcc2072.mpdu_start.seq_ctrl;
|
||||
}
|
||||
|
||||
static void ath12k_hal_rx_desc_get_crypto_hdr_qcc2072(struct hal_rx_desc *desc,
|
||||
u8 *crypto_hdr,
|
||||
enum hal_encrypt_type enctype)
|
||||
{
|
||||
unsigned int key_id;
|
||||
|
||||
switch (enctype) {
|
||||
case HAL_ENCRYPT_TYPE_OPEN:
|
||||
return;
|
||||
case HAL_ENCRYPT_TYPE_TKIP_NO_MIC:
|
||||
case HAL_ENCRYPT_TYPE_TKIP_MIC:
|
||||
crypto_hdr[0] =
|
||||
HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcc2072.mpdu_start.pn[0]);
|
||||
crypto_hdr[1] = 0;
|
||||
crypto_hdr[2] =
|
||||
HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcc2072.mpdu_start.pn[0]);
|
||||
break;
|
||||
case HAL_ENCRYPT_TYPE_CCMP_128:
|
||||
case HAL_ENCRYPT_TYPE_CCMP_256:
|
||||
case HAL_ENCRYPT_TYPE_GCMP_128:
|
||||
case HAL_ENCRYPT_TYPE_AES_GCMP_256:
|
||||
crypto_hdr[0] =
|
||||
HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcc2072.mpdu_start.pn[0]);
|
||||
crypto_hdr[1] =
|
||||
HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcc2072.mpdu_start.pn[0]);
|
||||
crypto_hdr[2] = 0;
|
||||
break;
|
||||
case HAL_ENCRYPT_TYPE_WEP_40:
|
||||
case HAL_ENCRYPT_TYPE_WEP_104:
|
||||
case HAL_ENCRYPT_TYPE_WEP_128:
|
||||
case HAL_ENCRYPT_TYPE_WAPI_GCM_SM4:
|
||||
case HAL_ENCRYPT_TYPE_WAPI:
|
||||
return;
|
||||
}
|
||||
|
||||
key_id = u32_get_bits(__le32_to_cpu(desc->u.qcc2072.mpdu_start.info5),
|
||||
RX_MPDU_START_INFO5_KEY_ID);
|
||||
crypto_hdr[3] = 0x20 | (key_id << 6);
|
||||
crypto_hdr[4] = HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.qcc2072.mpdu_start.pn[0]);
|
||||
crypto_hdr[5] = HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.qcc2072.mpdu_start.pn[0]);
|
||||
crypto_hdr[6] = HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcc2072.mpdu_start.pn[1]);
|
||||
crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcc2072.mpdu_start.pn[1]);
|
||||
}
|
||||
|
||||
static void ath12k_hal_rx_desc_copy_end_tlv_qcc2072(struct hal_rx_desc *fdesc,
|
||||
struct hal_rx_desc *ldesc)
|
||||
{
|
||||
memcpy(&fdesc->u.qcc2072.msdu_end, &ldesc->u.qcc2072.msdu_end,
|
||||
sizeof(struct rx_msdu_end_qcn9274));
|
||||
}
|
||||
|
||||
static u8 ath12k_hal_rx_desc_get_msdu_src_link_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u8 ath12k_hal_rx_desc_get_l3_pad_bytes_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return le16_get_bits(desc->u.qcc2072.msdu_end.info5,
|
||||
RX_MSDU_END_INFO5_L3_HDR_PADDING);
|
||||
}
|
||||
|
||||
static u32 ath12k_hal_rx_desc_get_mpdu_start_tag_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return le32_get_bits(desc->u.qcc2072.mpdu_start_tag,
|
||||
HAL_TLV_HDR_TAG);
|
||||
}
|
||||
|
||||
static u32 ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return __le16_to_cpu(desc->u.qcc2072.mpdu_start.phy_ppdu_id);
|
||||
}
|
||||
|
||||
static u8 *ath12k_hal_rx_desc_get_msdu_payload_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return &desc->u.qcc2072.msdu_payload[0];
|
||||
}
|
||||
|
||||
static bool ath12k_hal_rx_desc_get_first_msdu_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return !!le16_get_bits(desc->u.qcc2072.msdu_end.info5,
|
||||
RX_MSDU_END_INFO5_FIRST_MSDU);
|
||||
}
|
||||
|
||||
static bool ath12k_hal_rx_desc_get_last_msdu_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return !!le16_get_bits(desc->u.qcc2072.msdu_end.info5,
|
||||
RX_MSDU_END_INFO5_LAST_MSDU);
|
||||
}
|
||||
|
||||
static bool ath12k_hal_rx_desc_encrypt_valid_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return !!le32_get_bits(desc->u.qcc2072.mpdu_start.info4,
|
||||
RX_MPDU_START_INFO4_ENCRYPT_INFO_VALID);
|
||||
}
|
||||
|
||||
static u32 ath12k_hal_rx_desc_get_encrypt_type_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
if (!ath12k_hal_rx_desc_encrypt_valid_qcc2072(desc))
|
||||
return HAL_ENCRYPT_TYPE_OPEN;
|
||||
|
||||
return le32_get_bits(desc->u.qcc2072.mpdu_start.info2,
|
||||
RX_MPDU_START_INFO2_ENC_TYPE);
|
||||
}
|
||||
|
||||
static u8 ath12k_hal_rx_desc_get_decap_type_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return le32_get_bits(desc->u.qcc2072.msdu_end.info11,
|
||||
RX_MSDU_END_INFO11_DECAP_FORMAT);
|
||||
}
|
||||
|
||||
static u8 ath12k_hal_rx_desc_get_mesh_ctl_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return le32_get_bits(desc->u.qcc2072.msdu_end.info11,
|
||||
RX_MSDU_END_INFO11_MESH_CTRL_PRESENT);
|
||||
}
|
||||
|
||||
static bool ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return !!le32_get_bits(desc->u.qcc2072.mpdu_start.info4,
|
||||
RX_MPDU_START_INFO4_MPDU_SEQ_CTRL_VALID);
|
||||
}
|
||||
|
||||
static bool ath12k_hal_rx_desc_get_mpdu_fc_valid_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return !!le32_get_bits(desc->u.qcc2072.mpdu_start.info4,
|
||||
RX_MPDU_START_INFO4_MPDU_FCTRL_VALID);
|
||||
}
|
||||
|
||||
static u16 ath12k_hal_rx_desc_get_mpdu_start_seq_no_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return le32_get_bits(desc->u.qcc2072.mpdu_start.info4,
|
||||
RX_MPDU_START_INFO4_MPDU_SEQ_NUM);
|
||||
}
|
||||
|
||||
static u16 ath12k_hal_rx_desc_get_msdu_len_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return le32_get_bits(desc->u.qcc2072.msdu_end.info10,
|
||||
RX_MSDU_END_INFO10_MSDU_LENGTH);
|
||||
}
|
||||
|
||||
static u8 ath12k_hal_rx_desc_get_msdu_sgi_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return le32_get_bits(desc->u.qcc2072.msdu_end.info12,
|
||||
RX_MSDU_END_INFO12_SGI);
|
||||
}
|
||||
|
||||
static u8 ath12k_hal_rx_desc_get_msdu_rate_mcs_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return le32_get_bits(desc->u.qcc2072.msdu_end.info12,
|
||||
RX_MSDU_END_INFO12_RATE_MCS);
|
||||
}
|
||||
|
||||
static u8 ath12k_hal_rx_desc_get_msdu_rx_bw_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return le32_get_bits(desc->u.qcc2072.msdu_end.info12,
|
||||
RX_MSDU_END_INFO12_RECV_BW);
|
||||
}
|
||||
|
||||
static u32 ath12k_hal_rx_desc_get_msdu_freq_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return __le32_to_cpu(desc->u.qcc2072.msdu_end.phy_meta_data);
|
||||
}
|
||||
|
||||
static u8 ath12k_hal_rx_desc_get_msdu_pkt_type_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return le32_get_bits(desc->u.qcc2072.msdu_end.info12,
|
||||
RX_MSDU_END_INFO12_PKT_TYPE);
|
||||
}
|
||||
|
||||
static u8 ath12k_hal_rx_desc_get_msdu_nss_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return le32_get_bits(desc->u.qcc2072.msdu_end.info12,
|
||||
RX_MSDU_END_INFO12_MIMO_SS_BITMAP);
|
||||
}
|
||||
|
||||
static u8 ath12k_hal_rx_desc_get_mpdu_tid_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return le32_get_bits(desc->u.qcc2072.mpdu_start.info2,
|
||||
RX_MPDU_START_INFO2_TID);
|
||||
}
|
||||
|
||||
static u16 ath12k_hal_rx_desc_get_mpdu_peer_id_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return __le16_to_cpu(desc->u.qcc2072.mpdu_start.sw_peer_id);
|
||||
}
|
||||
|
||||
static bool ath12k_hal_rx_desc_mac_addr2_valid_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return __le32_to_cpu(desc->u.qcc2072.mpdu_start.info4) &
|
||||
RX_MPDU_START_INFO4_MAC_ADDR2_VALID;
|
||||
}
|
||||
|
||||
static u8 *ath12k_hal_rx_desc_mpdu_start_addr2_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return desc->u.qcc2072.mpdu_start.addr2;
|
||||
}
|
||||
|
||||
static bool ath12k_hal_rx_desc_is_da_mcbc_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return __le32_to_cpu(desc->u.qcc2072.msdu_end.info13) &
|
||||
RX_MSDU_END_INFO13_MCAST_BCAST;
|
||||
}
|
||||
|
||||
static bool ath12k_hal_rx_h_msdu_done_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return !!le32_get_bits(desc->u.qcc2072.msdu_end.info14,
|
||||
RX_MSDU_END_INFO14_MSDU_DONE);
|
||||
}
|
||||
|
||||
static bool ath12k_hal_rx_h_l4_cksum_fail_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return !!le32_get_bits(desc->u.qcc2072.msdu_end.info13,
|
||||
RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL);
|
||||
}
|
||||
|
||||
static bool ath12k_hal_rx_h_ip_cksum_fail_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return !!le32_get_bits(desc->u.qcc2072.msdu_end.info13,
|
||||
RX_MSDU_END_INFO13_IP_CKSUM_FAIL);
|
||||
}
|
||||
|
||||
static bool ath12k_hal_rx_h_is_decrypted_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
return (le32_get_bits(desc->u.qcc2072.msdu_end.info14,
|
||||
RX_MSDU_END_INFO14_DECRYPT_STATUS_CODE) ==
|
||||
RX_DESC_DECRYPT_STATUS_CODE_OK);
|
||||
}
|
||||
|
||||
static u32 ath12k_hal_rx_h_mpdu_err_qcc2072(struct hal_rx_desc *desc)
|
||||
{
|
||||
u32 info = __le32_to_cpu(desc->u.qcc2072.msdu_end.info13);
|
||||
u32 errmap = 0;
|
||||
|
||||
if (info & RX_MSDU_END_INFO13_FCS_ERR)
|
||||
errmap |= HAL_RX_MPDU_ERR_FCS;
|
||||
|
||||
if (info & RX_MSDU_END_INFO13_DECRYPT_ERR)
|
||||
errmap |= HAL_RX_MPDU_ERR_DECRYPT;
|
||||
|
||||
if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR)
|
||||
errmap |= HAL_RX_MPDU_ERR_TKIP_MIC;
|
||||
|
||||
if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR)
|
||||
errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR;
|
||||
|
||||
if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR)
|
||||
errmap |= HAL_RX_MPDU_ERR_OVERFLOW;
|
||||
|
||||
if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR)
|
||||
errmap |= HAL_RX_MPDU_ERR_MSDU_LEN;
|
||||
|
||||
if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR)
|
||||
errmap |= HAL_RX_MPDU_ERR_MPDU_LEN;
|
||||
|
||||
return errmap;
|
||||
}
|
||||
|
||||
static void ath12k_hal_extract_rx_desc_data_qcc2072(struct hal_rx_desc_data *rx_desc_data,
|
||||
struct hal_rx_desc *rx_desc,
|
||||
struct hal_rx_desc *ldesc)
|
||||
{
|
||||
rx_desc_data->is_first_msdu = ath12k_hal_rx_desc_get_first_msdu_qcc2072(ldesc);
|
||||
rx_desc_data->is_last_msdu = ath12k_hal_rx_desc_get_last_msdu_qcc2072(ldesc);
|
||||
rx_desc_data->l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_qcc2072(ldesc);
|
||||
rx_desc_data->enctype = ath12k_hal_rx_desc_get_encrypt_type_qcc2072(rx_desc);
|
||||
rx_desc_data->decap_type = ath12k_hal_rx_desc_get_decap_type_qcc2072(rx_desc);
|
||||
rx_desc_data->mesh_ctrl_present =
|
||||
ath12k_hal_rx_desc_get_mesh_ctl_qcc2072(rx_desc);
|
||||
rx_desc_data->seq_ctl_valid =
|
||||
ath12k_hal_rx_desc_get_mpdu_seq_ctl_vld_qcc2072(rx_desc);
|
||||
rx_desc_data->fc_valid = ath12k_hal_rx_desc_get_mpdu_fc_valid_qcc2072(rx_desc);
|
||||
rx_desc_data->seq_no = ath12k_hal_rx_desc_get_mpdu_start_seq_no_qcc2072(rx_desc);
|
||||
rx_desc_data->msdu_len = ath12k_hal_rx_desc_get_msdu_len_qcc2072(ldesc);
|
||||
rx_desc_data->sgi = ath12k_hal_rx_desc_get_msdu_sgi_qcc2072(rx_desc);
|
||||
rx_desc_data->rate_mcs = ath12k_hal_rx_desc_get_msdu_rate_mcs_qcc2072(rx_desc);
|
||||
rx_desc_data->bw = ath12k_hal_rx_desc_get_msdu_rx_bw_qcc2072(rx_desc);
|
||||
rx_desc_data->phy_meta_data = ath12k_hal_rx_desc_get_msdu_freq_qcc2072(rx_desc);
|
||||
rx_desc_data->pkt_type = ath12k_hal_rx_desc_get_msdu_pkt_type_qcc2072(rx_desc);
|
||||
rx_desc_data->nss = hweight8(ath12k_hal_rx_desc_get_msdu_nss_qcc2072(rx_desc));
|
||||
rx_desc_data->tid = ath12k_hal_rx_desc_get_mpdu_tid_qcc2072(rx_desc);
|
||||
rx_desc_data->peer_id = ath12k_hal_rx_desc_get_mpdu_peer_id_qcc2072(rx_desc);
|
||||
rx_desc_data->addr2_present = ath12k_hal_rx_desc_mac_addr2_valid_qcc2072(rx_desc);
|
||||
rx_desc_data->addr2 = ath12k_hal_rx_desc_mpdu_start_addr2_qcc2072(rx_desc);
|
||||
rx_desc_data->is_mcbc = ath12k_hal_rx_desc_is_da_mcbc_qcc2072(rx_desc);
|
||||
rx_desc_data->msdu_done = ath12k_hal_rx_h_msdu_done_qcc2072(ldesc);
|
||||
rx_desc_data->l4_csum_fail = ath12k_hal_rx_h_l4_cksum_fail_qcc2072(rx_desc);
|
||||
rx_desc_data->ip_csum_fail = ath12k_hal_rx_h_ip_cksum_fail_qcc2072(rx_desc);
|
||||
rx_desc_data->is_decrypted = ath12k_hal_rx_h_is_decrypted_qcc2072(rx_desc);
|
||||
rx_desc_data->err_bitmap = ath12k_hal_rx_h_mpdu_err_qcc2072(rx_desc);
|
||||
}
|
||||
|
||||
static int ath12k_hal_srng_create_config_qcc2072(struct ath12k_hal *hal)
|
||||
{
|
||||
struct hal_srng_config *s;
|
||||
int ret;
|
||||
|
||||
ret = ath12k_hal_srng_create_config_wcn7850(hal);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
s = &hal->srng_config[HAL_REO_CMD];
|
||||
s->entry_size = (sizeof(struct hal_tlv_hdr) +
|
||||
sizeof(struct hal_reo_get_queue_stats_qcc2072)) >> 2;
|
||||
|
||||
s = &hal->srng_config[HAL_REO_STATUS];
|
||||
s->entry_size = (sizeof(struct hal_tlv_hdr) +
|
||||
sizeof(struct hal_reo_get_queue_stats_status_qcc2072)) >> 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u16 ath12k_hal_reo_status_dec_tlv_hdr_qcc2072(void *tlv, void **desc)
|
||||
{
|
||||
struct hal_reo_get_queue_stats_status_qcc2072 *status_tlv;
|
||||
u16 tag;
|
||||
|
||||
tag = ath12k_hal_decode_tlv32_hdr(tlv, (void **)&status_tlv);
|
||||
/*
|
||||
* actual desc of REO status entry starts after tlv32_padding,
|
||||
* see hal_reo_get_queue_stats_status_qcc2072
|
||||
*/
|
||||
*desc = &status_tlv->status;
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
const struct hal_ops hal_qcc2072_ops = {
|
||||
.create_srng_config = ath12k_hal_srng_create_config_qcc2072,
|
||||
.rx_desc_set_msdu_len = ath12k_hal_rx_desc_set_msdu_len_qcc2072,
|
||||
.rx_desc_get_dot11_hdr = ath12k_hal_rx_desc_get_dot11_hdr_qcc2072,
|
||||
.rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_qcc2072,
|
||||
.rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_qcc2072,
|
||||
.rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_qcc2072,
|
||||
.extract_rx_desc_data = ath12k_hal_extract_rx_desc_data_qcc2072,
|
||||
.rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_qcc2072,
|
||||
.rx_desc_get_mpdu_start_tag = ath12k_hal_rx_desc_get_mpdu_start_tag_qcc2072,
|
||||
.rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcc2072,
|
||||
.rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_qcc2072,
|
||||
.ce_dst_setup = ath12k_wifi7_hal_ce_dst_setup,
|
||||
.srng_src_hw_init = ath12k_wifi7_hal_srng_src_hw_init,
|
||||
.srng_dst_hw_init = ath12k_wifi7_hal_srng_dst_hw_init,
|
||||
.set_umac_srng_ptr_addr = ath12k_wifi7_hal_set_umac_srng_ptr_addr,
|
||||
.srng_update_shadow_config = ath12k_wifi7_hal_srng_update_shadow_config,
|
||||
.srng_get_ring_id = ath12k_wifi7_hal_srng_get_ring_id,
|
||||
.ce_get_desc_size = ath12k_wifi7_hal_ce_get_desc_size,
|
||||
.ce_src_set_desc = ath12k_wifi7_hal_ce_src_set_desc,
|
||||
.ce_dst_set_desc = ath12k_wifi7_hal_ce_dst_set_desc,
|
||||
.ce_dst_status_get_length = ath12k_wifi7_hal_ce_dst_status_get_length,
|
||||
.set_link_desc_addr = ath12k_wifi7_hal_set_link_desc_addr,
|
||||
.tx_set_dscp_tid_map = ath12k_wifi7_hal_tx_set_dscp_tid_map,
|
||||
.tx_configure_bank_register =
|
||||
ath12k_wifi7_hal_tx_configure_bank_register,
|
||||
.reoq_lut_addr_read_enable = ath12k_wifi7_hal_reoq_lut_addr_read_enable,
|
||||
.reoq_lut_set_max_peerid = ath12k_wifi7_hal_reoq_lut_set_max_peerid,
|
||||
.write_reoq_lut_addr = ath12k_wifi7_hal_write_reoq_lut_addr,
|
||||
.write_ml_reoq_lut_addr = ath12k_wifi7_hal_write_ml_reoq_lut_addr,
|
||||
.setup_link_idle_list = ath12k_wifi7_hal_setup_link_idle_list,
|
||||
.reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring_tlv32,
|
||||
.reo_hw_setup = ath12k_wifi7_hal_reo_hw_setup,
|
||||
.rx_buf_addr_info_set = ath12k_wifi7_hal_rx_buf_addr_info_set,
|
||||
.rx_buf_addr_info_get = ath12k_wifi7_hal_rx_buf_addr_info_get,
|
||||
.cc_config = ath12k_wifi7_hal_cc_config,
|
||||
.get_idle_link_rbm = ath12k_wifi7_hal_get_idle_link_rbm,
|
||||
.rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get,
|
||||
.rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get,
|
||||
.reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv32_hdr,
|
||||
.reo_status_dec_tlv_hdr = ath12k_hal_reo_status_dec_tlv_hdr_qcc2072,
|
||||
};
|
||||
|
||||
u32 ath12k_hal_rx_desc_get_mpdu_start_offset_qcc2072(void)
|
||||
{
|
||||
return offsetof(struct hal_rx_desc_qcc2072, mpdu_start_tag);
|
||||
}
|
||||
|
||||
u32 ath12k_hal_rx_desc_get_msdu_end_offset_qcc2072(void)
|
||||
{
|
||||
return offsetof(struct hal_rx_desc_qcc2072, msdu_end_tag);
|
||||
}
|
||||
13
drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.h
Normal file
13
drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
||||
/*
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include "../hal.h"
|
||||
#include "hal.h"
|
||||
|
||||
extern const struct ath12k_hw_regs qcc2072_regs;
|
||||
extern const struct hal_ops hal_qcc2072_ops;
|
||||
|
||||
u32 ath12k_hal_rx_desc_get_mpdu_start_offset_qcc2072(void);
|
||||
u32 ath12k_hal_rx_desc_get_msdu_end_offset_qcc2072(void);
|
||||
|
|
@ -297,6 +297,8 @@ const struct ath12k_hw_regs qcn9274_v1_regs = {
|
|||
.umac_ce1_dest_reg_base = 0x01b83000,
|
||||
|
||||
.gcc_gcc_pcie_hot_rst = 0x1e38338,
|
||||
|
||||
.qrtr_node_id = 0x1e03164,
|
||||
};
|
||||
|
||||
const struct ath12k_hw_regs qcn9274_v2_regs = {
|
||||
|
|
@ -390,6 +392,8 @@ const struct ath12k_hw_regs qcn9274_v2_regs = {
|
|||
.umac_ce1_dest_reg_base = 0x01b83000,
|
||||
|
||||
.gcc_gcc_pcie_hot_rst = 0x1e38338,
|
||||
|
||||
.qrtr_node_id = 0x1e03164,
|
||||
};
|
||||
|
||||
const struct ath12k_hw_regs ipq5332_regs = {
|
||||
|
|
@ -1020,7 +1024,7 @@ const struct hal_ops hal_qcn9274_ops = {
|
|||
.write_reoq_lut_addr = ath12k_wifi7_hal_write_reoq_lut_addr,
|
||||
.write_ml_reoq_lut_addr = ath12k_wifi7_hal_write_ml_reoq_lut_addr,
|
||||
.setup_link_idle_list = ath12k_wifi7_hal_setup_link_idle_list,
|
||||
.reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring,
|
||||
.reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring_tlv64,
|
||||
.reo_hw_setup = ath12k_wifi7_hal_reo_hw_setup,
|
||||
.reo_shared_qaddr_cache_clear = ath12k_wifi7_hal_reo_shared_qaddr_cache_clear,
|
||||
.rx_buf_addr_info_set = ath12k_wifi7_hal_rx_buf_addr_info_set,
|
||||
|
|
@ -1029,4 +1033,6 @@ const struct hal_ops hal_qcn9274_ops = {
|
|||
.get_idle_link_rbm = ath12k_wifi7_hal_get_idle_link_rbm,
|
||||
.rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get,
|
||||
.rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get,
|
||||
.reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv64_hdr,
|
||||
.reo_status_dec_tlv_hdr = ath12k_hal_decode_tlv64_hdr,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -23,15 +23,13 @@ void ath12k_wifi7_hal_reo_set_desc_hdr(struct hal_desc_header *hdr,
|
|||
hdr->info0 |= le32_encode_bits(magic, HAL_DESC_HDR_INFO0_DBG_RESERVED);
|
||||
}
|
||||
|
||||
static int ath12k_wifi7_hal_reo_cmd_queue_stats(struct hal_tlv_64_hdr *tlv,
|
||||
static int ath12k_wifi7_hal_reo_cmd_queue_stats(struct ath12k_hal *hal, void *tlv,
|
||||
struct ath12k_hal_reo_cmd *cmd)
|
||||
{
|
||||
struct hal_reo_get_queue_stats *desc;
|
||||
|
||||
tlv->tl = le64_encode_bits(HAL_REO_GET_QUEUE_STATS, HAL_TLV_HDR_TAG) |
|
||||
le64_encode_bits(sizeof(*desc), HAL_TLV_HDR_LEN);
|
||||
|
||||
desc = (struct hal_reo_get_queue_stats *)tlv->value;
|
||||
desc = hal->ops->reo_cmd_enc_tlv_hdr(tlv, HAL_REO_GET_QUEUE_STATS,
|
||||
sizeof(*desc));
|
||||
memset_startat(desc, 0, queue_addr_lo);
|
||||
|
||||
desc->cmd.info0 &= ~cpu_to_le32(HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED);
|
||||
|
|
@ -47,8 +45,7 @@ static int ath12k_wifi7_hal_reo_cmd_queue_stats(struct hal_tlv_64_hdr *tlv,
|
|||
return le32_get_bits(desc->cmd.info0, HAL_REO_CMD_HDR_INFO0_CMD_NUMBER);
|
||||
}
|
||||
|
||||
static int ath12k_wifi7_hal_reo_cmd_flush_cache(struct ath12k_hal *hal,
|
||||
struct hal_tlv_64_hdr *tlv,
|
||||
static int ath12k_wifi7_hal_reo_cmd_flush_cache(struct ath12k_hal *hal, void *tlv,
|
||||
struct ath12k_hal_reo_cmd *cmd)
|
||||
{
|
||||
struct hal_reo_flush_cache *desc;
|
||||
|
|
@ -61,10 +58,8 @@ static int ath12k_wifi7_hal_reo_cmd_flush_cache(struct ath12k_hal *hal,
|
|||
hal->current_blk_index = avail_slot;
|
||||
}
|
||||
|
||||
tlv->tl = le64_encode_bits(HAL_REO_FLUSH_CACHE, HAL_TLV_HDR_TAG) |
|
||||
le64_encode_bits(sizeof(*desc), HAL_TLV_HDR_LEN);
|
||||
|
||||
desc = (struct hal_reo_flush_cache *)tlv->value;
|
||||
desc = hal->ops->reo_cmd_enc_tlv_hdr(tlv, HAL_REO_FLUSH_CACHE,
|
||||
sizeof(*desc));
|
||||
memset_startat(desc, 0, cache_addr_lo);
|
||||
|
||||
desc->cmd.info0 &= ~cpu_to_le32(HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED);
|
||||
|
|
@ -98,15 +93,13 @@ static int ath12k_wifi7_hal_reo_cmd_flush_cache(struct ath12k_hal *hal,
|
|||
}
|
||||
|
||||
static int
|
||||
ath12k_wifi7_hal_reo_cmd_update_rx_queue(struct hal_tlv_64_hdr *tlv,
|
||||
ath12k_wifi7_hal_reo_cmd_update_rx_queue(struct ath12k_hal *hal, void *tlv,
|
||||
struct ath12k_hal_reo_cmd *cmd)
|
||||
{
|
||||
struct hal_reo_update_rx_queue *desc;
|
||||
|
||||
tlv->tl = le64_encode_bits(HAL_REO_UPDATE_RX_REO_QUEUE, HAL_TLV_HDR_TAG) |
|
||||
le64_encode_bits(sizeof(*desc), HAL_TLV_HDR_LEN);
|
||||
|
||||
desc = (struct hal_reo_update_rx_queue *)tlv->value;
|
||||
desc = hal->ops->reo_cmd_enc_tlv_hdr(tlv, HAL_REO_UPDATE_RX_REO_QUEUE,
|
||||
sizeof(*desc));
|
||||
memset_startat(desc, 0, queue_addr_lo);
|
||||
|
||||
desc->cmd.info0 &= ~cpu_to_le32(HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED);
|
||||
|
|
@ -227,7 +220,8 @@ int ath12k_wifi7_hal_reo_cmd_send(struct ath12k_base *ab, struct hal_srng *srng,
|
|||
enum hal_reo_cmd_type type,
|
||||
struct ath12k_hal_reo_cmd *cmd)
|
||||
{
|
||||
struct hal_tlv_64_hdr *reo_desc;
|
||||
struct ath12k_hal *hal = &ab->hal;
|
||||
void *reo_desc;
|
||||
int ret;
|
||||
|
||||
spin_lock_bh(&srng->lock);
|
||||
|
|
@ -241,14 +235,13 @@ int ath12k_wifi7_hal_reo_cmd_send(struct ath12k_base *ab, struct hal_srng *srng,
|
|||
|
||||
switch (type) {
|
||||
case HAL_REO_CMD_GET_QUEUE_STATS:
|
||||
ret = ath12k_wifi7_hal_reo_cmd_queue_stats(reo_desc, cmd);
|
||||
ret = ath12k_wifi7_hal_reo_cmd_queue_stats(hal, reo_desc, cmd);
|
||||
break;
|
||||
case HAL_REO_CMD_FLUSH_CACHE:
|
||||
ret = ath12k_wifi7_hal_reo_cmd_flush_cache(&ab->hal, reo_desc,
|
||||
cmd);
|
||||
ret = ath12k_wifi7_hal_reo_cmd_flush_cache(hal, reo_desc, cmd);
|
||||
break;
|
||||
case HAL_REO_CMD_UPDATE_RX_QUEUE:
|
||||
ret = ath12k_wifi7_hal_reo_cmd_update_rx_queue(reo_desc, cmd);
|
||||
ret = ath12k_wifi7_hal_reo_cmd_update_rx_queue(hal, reo_desc, cmd);
|
||||
break;
|
||||
case HAL_REO_CMD_FLUSH_QUEUE:
|
||||
case HAL_REO_CMD_UNBLOCK_CACHE:
|
||||
|
|
@ -550,12 +543,9 @@ ath12k_wifi7_hal_rx_msdu_link_desc_set(struct ath12k_base *ab,
|
|||
}
|
||||
|
||||
void ath12k_wifi7_hal_reo_status_queue_stats(struct ath12k_base *ab,
|
||||
struct hal_tlv_64_hdr *tlv,
|
||||
struct hal_reo_get_queue_stats_status *desc,
|
||||
struct hal_reo_status *status)
|
||||
{
|
||||
struct hal_reo_get_queue_stats_status *desc =
|
||||
(struct hal_reo_get_queue_stats_status *)tlv->value;
|
||||
|
||||
status->uniform_hdr.cmd_num =
|
||||
le32_get_bits(desc->hdr.info0,
|
||||
HAL_REO_STATUS_HDR_INFO0_STATUS_NUM);
|
||||
|
|
@ -614,12 +604,9 @@ void ath12k_wifi7_hal_reo_status_queue_stats(struct ath12k_base *ab,
|
|||
}
|
||||
|
||||
void ath12k_wifi7_hal_reo_flush_queue_status(struct ath12k_base *ab,
|
||||
struct hal_tlv_64_hdr *tlv,
|
||||
struct hal_reo_flush_queue_status *desc,
|
||||
struct hal_reo_status *status)
|
||||
{
|
||||
struct hal_reo_flush_queue_status *desc =
|
||||
(struct hal_reo_flush_queue_status *)tlv->value;
|
||||
|
||||
status->uniform_hdr.cmd_num =
|
||||
le32_get_bits(desc->hdr.info0,
|
||||
HAL_REO_STATUS_HDR_INFO0_STATUS_NUM);
|
||||
|
|
@ -633,12 +620,10 @@ void ath12k_wifi7_hal_reo_flush_queue_status(struct ath12k_base *ab,
|
|||
|
||||
void
|
||||
ath12k_wifi7_hal_reo_flush_cache_status(struct ath12k_base *ab,
|
||||
struct hal_tlv_64_hdr *tlv,
|
||||
struct hal_reo_flush_cache_status *desc,
|
||||
struct hal_reo_status *status)
|
||||
{
|
||||
struct ath12k_hal *hal = &ab->hal;
|
||||
struct hal_reo_flush_cache_status *desc =
|
||||
(struct hal_reo_flush_cache_status *)tlv->value;
|
||||
|
||||
status->uniform_hdr.cmd_num =
|
||||
le32_get_bits(desc->hdr.info0,
|
||||
|
|
@ -675,12 +660,10 @@ ath12k_wifi7_hal_reo_flush_cache_status(struct ath12k_base *ab,
|
|||
}
|
||||
|
||||
void ath12k_wifi7_hal_reo_unblk_cache_status(struct ath12k_base *ab,
|
||||
struct hal_tlv_64_hdr *tlv,
|
||||
struct hal_reo_unblock_cache_status *desc,
|
||||
struct hal_reo_status *status)
|
||||
{
|
||||
struct ath12k_hal *hal = &ab->hal;
|
||||
struct hal_reo_unblock_cache_status *desc =
|
||||
(struct hal_reo_unblock_cache_status *)tlv->value;
|
||||
|
||||
status->uniform_hdr.cmd_num =
|
||||
le32_get_bits(desc->hdr.info0,
|
||||
|
|
@ -704,12 +687,9 @@ void ath12k_wifi7_hal_reo_unblk_cache_status(struct ath12k_base *ab,
|
|||
|
||||
void
|
||||
ath12k_wifi7_hal_reo_flush_timeout_list_status(struct ath12k_base *ab,
|
||||
struct hal_tlv_64_hdr *tlv,
|
||||
struct hal_reo_flush_timeout_list_status *desc,
|
||||
struct hal_reo_status *status)
|
||||
{
|
||||
struct hal_reo_flush_timeout_list_status *desc =
|
||||
(struct hal_reo_flush_timeout_list_status *)tlv->value;
|
||||
|
||||
status->uniform_hdr.cmd_num =
|
||||
le32_get_bits(desc->hdr.info0,
|
||||
HAL_REO_STATUS_HDR_INFO0_STATUS_NUM);
|
||||
|
|
@ -734,12 +714,9 @@ ath12k_wifi7_hal_reo_flush_timeout_list_status(struct ath12k_base *ab,
|
|||
|
||||
void
|
||||
ath12k_wifi7_hal_reo_desc_thresh_reached_status(struct ath12k_base *ab,
|
||||
struct hal_tlv_64_hdr *tlv,
|
||||
struct hal_reo_desc_thresh_reached_status *desc,
|
||||
struct hal_reo_status *status)
|
||||
{
|
||||
struct hal_reo_desc_thresh_reached_status *desc =
|
||||
(struct hal_reo_desc_thresh_reached_status *)tlv->value;
|
||||
|
||||
status->uniform_hdr.cmd_num =
|
||||
le32_get_bits(desc->hdr.info0,
|
||||
HAL_REO_STATUS_HDR_INFO0_STATUS_NUM);
|
||||
|
|
@ -769,12 +746,9 @@ ath12k_wifi7_hal_reo_desc_thresh_reached_status(struct ath12k_base *ab,
|
|||
}
|
||||
|
||||
void ath12k_wifi7_hal_reo_update_rx_reo_queue_status(struct ath12k_base *ab,
|
||||
struct hal_tlv_64_hdr *tlv,
|
||||
struct hal_reo_status_hdr *desc,
|
||||
struct hal_reo_status *status)
|
||||
{
|
||||
struct hal_reo_status_hdr *desc =
|
||||
(struct hal_reo_status_hdr *)tlv->value;
|
||||
|
||||
status->uniform_hdr.cmd_num =
|
||||
le32_get_bits(desc->info0,
|
||||
HAL_REO_STATUS_HDR_INFO0_STATUS_NUM);
|
||||
|
|
@ -891,8 +865,8 @@ void ath12k_wifi7_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc,
|
|||
REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_3);
|
||||
}
|
||||
|
||||
void ath12k_wifi7_hal_reo_init_cmd_ring(struct ath12k_base *ab,
|
||||
struct hal_srng *srng)
|
||||
void ath12k_wifi7_hal_reo_init_cmd_ring_tlv64(struct ath12k_base *ab,
|
||||
struct hal_srng *srng)
|
||||
{
|
||||
struct hal_srng_params params;
|
||||
struct hal_tlv_64_hdr *tlv;
|
||||
|
|
@ -916,6 +890,31 @@ void ath12k_wifi7_hal_reo_init_cmd_ring(struct ath12k_base *ab,
|
|||
}
|
||||
}
|
||||
|
||||
void ath12k_wifi7_hal_reo_init_cmd_ring_tlv32(struct ath12k_base *ab,
|
||||
struct hal_srng *srng)
|
||||
{
|
||||
struct hal_reo_get_queue_stats *desc;
|
||||
struct hal_srng_params params;
|
||||
struct hal_tlv_hdr *tlv;
|
||||
int i, cmd_num = 1;
|
||||
int entry_size;
|
||||
u8 *entry;
|
||||
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
|
||||
entry_size = ath12k_hal_srng_get_entrysize(ab, HAL_REO_CMD);
|
||||
ath12k_hal_srng_get_params(ab, srng, ¶ms);
|
||||
entry = (u8 *)params.ring_base_vaddr;
|
||||
|
||||
for (i = 0; i < params.num_entries; i++) {
|
||||
tlv = (struct hal_tlv_hdr *)entry;
|
||||
desc = (struct hal_reo_get_queue_stats *)tlv->value;
|
||||
desc->cmd.info0 = le32_encode_bits(cmd_num++,
|
||||
HAL_REO_CMD_HDR_INFO0_CMD_NUMBER);
|
||||
entry += entry_size;
|
||||
}
|
||||
}
|
||||
|
||||
void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map)
|
||||
{
|
||||
struct ath12k_hal *hal = &ab->hal;
|
||||
|
|
|
|||
|
|
@ -813,25 +813,27 @@ enum hal_mon_reception_type {
|
|||
(HAL_RU(ru_per80, num_80mhz, ru_idx_per80mhz))
|
||||
|
||||
void ath12k_wifi7_hal_reo_status_queue_stats(struct ath12k_base *ab,
|
||||
struct hal_tlv_64_hdr *tlv,
|
||||
struct hal_reo_get_queue_stats_status *desc,
|
||||
struct hal_reo_status *status);
|
||||
void ath12k_wifi7_hal_reo_flush_queue_status(struct ath12k_base *ab,
|
||||
struct hal_tlv_64_hdr *tlv,
|
||||
struct hal_reo_flush_queue_status *desc,
|
||||
struct hal_reo_status *status);
|
||||
void ath12k_wifi7_hal_reo_flush_cache_status(struct ath12k_base *ab,
|
||||
struct hal_tlv_64_hdr *tlv,
|
||||
struct hal_reo_flush_cache_status *desc,
|
||||
struct hal_reo_status *status);
|
||||
void ath12k_wifi7_hal_reo_unblk_cache_status(struct ath12k_base *ab,
|
||||
struct hal_tlv_64_hdr *tlv,
|
||||
struct hal_reo_unblock_cache_status *desc,
|
||||
struct hal_reo_status *status);
|
||||
void ath12k_wifi7_hal_reo_flush_timeout_list_status(struct ath12k_base *ab,
|
||||
struct hal_tlv_64_hdr *tlv,
|
||||
struct hal_reo_status *status);
|
||||
void ath12k_wifi7_hal_reo_desc_thresh_reached_status(struct ath12k_base *ab,
|
||||
struct hal_tlv_64_hdr *tlv,
|
||||
struct hal_reo_status *status);
|
||||
void
|
||||
ath12k_wifi7_hal_reo_flush_timeout_list_status(struct ath12k_base *ab,
|
||||
struct hal_reo_flush_timeout_list_status *desc,
|
||||
struct hal_reo_status *status);
|
||||
void
|
||||
ath12k_wifi7_hal_reo_desc_thresh_reached_status(struct ath12k_base *ab,
|
||||
struct hal_reo_desc_thresh_reached_status *desc,
|
||||
struct hal_reo_status *status);
|
||||
void ath12k_wifi7_hal_reo_update_rx_reo_queue_status(struct ath12k_base *ab,
|
||||
struct hal_tlv_64_hdr *tlv,
|
||||
struct hal_reo_status_hdr *desc,
|
||||
struct hal_reo_status *status);
|
||||
void ath12k_wifi7_hal_rx_msdu_link_info_get(struct hal_rx_msdu_link *link, u32 *num_msdus,
|
||||
u32 *msdu_cookies,
|
||||
|
|
@ -860,8 +862,10 @@ void ath12k_wifi7_hal_rx_msdu_list_get(struct ath12k *ar,
|
|||
void *link_desc,
|
||||
void *msdu_list_opaque,
|
||||
u16 *num_msdus);
|
||||
void ath12k_wifi7_hal_reo_init_cmd_ring(struct ath12k_base *ab,
|
||||
struct hal_srng *srng);
|
||||
void ath12k_wifi7_hal_reo_init_cmd_ring_tlv64(struct ath12k_base *ab,
|
||||
struct hal_srng *srng);
|
||||
void ath12k_wifi7_hal_reo_init_cmd_ring_tlv32(struct ath12k_base *ab,
|
||||
struct hal_srng *srng);
|
||||
void ath12k_wifi7_hal_reo_shared_qaddr_cache_clear(struct ath12k_base *ab);
|
||||
void ath12k_wifi7_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map);
|
||||
void ath12k_wifi7_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc,
|
||||
|
|
|
|||
|
|
@ -1481,10 +1481,27 @@ struct hal_rx_desc_wcn7850 {
|
|||
u8 msdu_payload[];
|
||||
};
|
||||
|
||||
struct rx_pkt_hdr_tlv_qcc2072 {
|
||||
__le32 tag;
|
||||
__le64 phy_ppdu_id;
|
||||
u8 rx_pkt_hdr[HAL_RX_BE_PKT_HDR_TLV_LEN];
|
||||
};
|
||||
|
||||
struct hal_rx_desc_qcc2072 {
|
||||
__le32 msdu_end_tag;
|
||||
struct rx_msdu_end_qcn9274 msdu_end;
|
||||
u8 rx_padding0[RX_BE_PADDING0_BYTES];
|
||||
__le32 mpdu_start_tag;
|
||||
struct rx_mpdu_start_qcn9274 mpdu_start;
|
||||
struct rx_pkt_hdr_tlv_qcc2072 pkt_hdr_tlv;
|
||||
u8 msdu_payload[];
|
||||
};
|
||||
|
||||
struct hal_rx_desc {
|
||||
union {
|
||||
struct hal_rx_desc_qcn9274_compact qcn9274_compact;
|
||||
struct hal_rx_desc_wcn7850 wcn7850;
|
||||
struct hal_rx_desc_qcc2072 qcc2072;
|
||||
} u;
|
||||
} __packed;
|
||||
|
||||
|
|
|
|||
|
|
@ -256,6 +256,8 @@ const struct ath12k_hw_regs wcn7850_regs = {
|
|||
.umac_ce1_dest_reg_base = 0x01b83000,
|
||||
|
||||
.gcc_gcc_pcie_hot_rst = 0x1e40304,
|
||||
|
||||
.qrtr_node_id = 0x1e03164,
|
||||
};
|
||||
|
||||
static inline
|
||||
|
|
@ -614,7 +616,7 @@ void ath12k_hal_extract_rx_desc_data_wcn7850(struct hal_rx_desc_data *rx_desc_da
|
|||
rx_desc_data->err_bitmap = ath12k_hal_rx_h_mpdu_err_wcn7850(rx_desc);
|
||||
}
|
||||
|
||||
static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_hal *hal)
|
||||
int ath12k_hal_srng_create_config_wcn7850(struct ath12k_hal *hal)
|
||||
{
|
||||
struct hal_srng_config *s;
|
||||
|
||||
|
|
@ -793,7 +795,7 @@ const struct hal_ops hal_wcn7850_ops = {
|
|||
.write_reoq_lut_addr = ath12k_wifi7_hal_write_reoq_lut_addr,
|
||||
.write_ml_reoq_lut_addr = ath12k_wifi7_hal_write_ml_reoq_lut_addr,
|
||||
.setup_link_idle_list = ath12k_wifi7_hal_setup_link_idle_list,
|
||||
.reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring,
|
||||
.reo_init_cmd_ring = ath12k_wifi7_hal_reo_init_cmd_ring_tlv64,
|
||||
.reo_shared_qaddr_cache_clear = ath12k_wifi7_hal_reo_shared_qaddr_cache_clear,
|
||||
.reo_hw_setup = ath12k_wifi7_hal_reo_hw_setup,
|
||||
.rx_buf_addr_info_set = ath12k_wifi7_hal_rx_buf_addr_info_set,
|
||||
|
|
@ -802,4 +804,6 @@ const struct hal_ops hal_wcn7850_ops = {
|
|||
.get_idle_link_rbm = ath12k_wifi7_hal_get_idle_link_rbm,
|
||||
.rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get,
|
||||
.rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get,
|
||||
.reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv64_hdr,
|
||||
.reo_status_dec_tlv_hdr = ath12k_hal_decode_tlv64_hdr,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -36,4 +36,5 @@ void ath12k_hal_rx_desc_get_dot11_hdr_wcn7850(struct hal_rx_desc *desc,
|
|||
void ath12k_hal_extract_rx_desc_data_wcn7850(struct hal_rx_desc_data *rx_desc_data,
|
||||
struct hal_rx_desc *rx_desc,
|
||||
struct hal_rx_desc *ldesc);
|
||||
int ath12k_hal_srng_create_config_wcn7850(struct ath12k_hal *hal);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -170,6 +170,16 @@ static const struct ath12k_hw_ops wcn7850_ops = {
|
|||
.is_frame_link_agnostic = ath12k_wifi7_is_frame_link_agnostic_wcn7850,
|
||||
};
|
||||
|
||||
static const struct ath12k_hw_ops qcc2072_ops = {
|
||||
.get_hw_mac_from_pdev_id = ath12k_wifi7_hw_qcn9274_mac_from_pdev_id,
|
||||
.mac_id_to_pdev_id = ath12k_wifi7_hw_mac_id_to_pdev_id_wcn7850,
|
||||
.mac_id_to_srng_id = ath12k_wifi7_hw_mac_id_to_srng_id_wcn7850,
|
||||
.rxdma_ring_sel_config = ath12k_dp_rxdma_ring_sel_config_qcc2072,
|
||||
.get_ring_selector = ath12k_wifi7_hw_get_ring_selector_wcn7850,
|
||||
.dp_srng_is_tx_comp_ring = ath12k_wifi7_dp_srng_is_comp_ring_wcn7850,
|
||||
.is_frame_link_agnostic = ath12k_wifi7_is_frame_link_agnostic_wcn7850,
|
||||
};
|
||||
|
||||
#define ATH12K_TX_RING_MASK_0 0x1
|
||||
#define ATH12K_TX_RING_MASK_1 0x2
|
||||
#define ATH12K_TX_RING_MASK_2 0x4
|
||||
|
|
@ -339,6 +349,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
|
|||
.board_size = 256 * 1024,
|
||||
.cal_offset = 128 * 1024,
|
||||
.m3_loader = ath12k_m3_fw_loader_driver,
|
||||
.download_aux_ucode = false,
|
||||
},
|
||||
.max_radios = 1,
|
||||
.single_pdev_only = false,
|
||||
|
|
@ -421,6 +432,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
|
|||
.board_size = 256 * 1024,
|
||||
.cal_offset = 256 * 1024,
|
||||
.m3_loader = ath12k_m3_fw_loader_driver,
|
||||
.download_aux_ucode = false,
|
||||
},
|
||||
|
||||
.max_radios = 1,
|
||||
|
|
@ -505,6 +517,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
|
|||
.board_size = 256 * 1024,
|
||||
.cal_offset = 128 * 1024,
|
||||
.m3_loader = ath12k_m3_fw_loader_driver,
|
||||
.download_aux_ucode = false,
|
||||
},
|
||||
.max_radios = 2,
|
||||
.single_pdev_only = false,
|
||||
|
|
@ -586,6 +599,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
|
|||
.board_size = 256 * 1024,
|
||||
.cal_offset = 128 * 1024,
|
||||
.m3_loader = ath12k_m3_fw_loader_remoteproc,
|
||||
.download_aux_ucode = false,
|
||||
},
|
||||
.max_radios = 1,
|
||||
.single_pdev_only = false,
|
||||
|
|
@ -652,6 +666,93 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
|
|||
|
||||
.dp_primary_link_only = true,
|
||||
},
|
||||
{
|
||||
.name = "qcc2072 hw1.0",
|
||||
.hw_rev = ATH12K_HW_QCC2072_HW10,
|
||||
|
||||
.fw = {
|
||||
.dir = "QCC2072/hw1.0",
|
||||
.board_size = 256 * 1024,
|
||||
.cal_offset = 256 * 1024,
|
||||
.m3_loader = ath12k_m3_fw_loader_driver,
|
||||
.download_aux_ucode = true,
|
||||
},
|
||||
|
||||
.max_radios = 1,
|
||||
.single_pdev_only = true,
|
||||
.qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_WCN7850,
|
||||
.internal_sleep_clock = true,
|
||||
|
||||
.hw_ops = &qcc2072_ops,
|
||||
.ring_mask = &ath12k_wifi7_hw_ring_mask_wcn7850,
|
||||
|
||||
.host_ce_config = ath12k_wifi7_host_ce_config_wcn7850,
|
||||
.ce_count = 9,
|
||||
.target_ce_config = ath12k_wifi7_target_ce_config_wlan_wcn7850,
|
||||
.target_ce_count = 9,
|
||||
.svc_to_ce_map =
|
||||
ath12k_wifi7_target_service_to_ce_map_wlan_wcn7850,
|
||||
.svc_to_ce_map_len = 14,
|
||||
|
||||
.rxdma1_enable = false,
|
||||
.num_rxdma_per_pdev = 2,
|
||||
.num_rxdma_dst_ring = 1,
|
||||
.rx_mac_buf_ring = true,
|
||||
.vdev_start_delay = true,
|
||||
|
||||
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_AP) |
|
||||
BIT(NL80211_IFTYPE_P2P_DEVICE) |
|
||||
BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||
BIT(NL80211_IFTYPE_P2P_GO),
|
||||
.supports_monitor = true,
|
||||
|
||||
.idle_ps = true,
|
||||
.download_calib = false,
|
||||
.supports_suspend = true,
|
||||
.tcl_ring_retry = false,
|
||||
.reoq_lut_support = false,
|
||||
.supports_shadow_regs = true,
|
||||
|
||||
.num_tcl_banks = 7,
|
||||
.max_tx_ring = 3,
|
||||
|
||||
.mhi_config = &ath12k_wifi7_mhi_config_wcn7850,
|
||||
|
||||
.wmi_init = ath12k_wifi7_wmi_init_wcn7850,
|
||||
|
||||
.qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01) |
|
||||
BIT(CNSS_PCIE_PERST_NO_PULL_V01) |
|
||||
BIT(CNSS_AUX_UC_SUPPORT_V01),
|
||||
|
||||
.rfkill_pin = 0,
|
||||
.rfkill_cfg = 0,
|
||||
.rfkill_on_level = 0,
|
||||
|
||||
.rddm_size = 0x780000,
|
||||
|
||||
.def_num_link = 2,
|
||||
.max_mlo_peer = 32,
|
||||
|
||||
.otp_board_id_register = 0,
|
||||
|
||||
.supports_sta_ps = true,
|
||||
|
||||
.acpi_guid = &wcn7850_uuid,
|
||||
.supports_dynamic_smps_6ghz = false,
|
||||
|
||||
.iova_mask = 0,
|
||||
|
||||
.supports_aspm = true,
|
||||
|
||||
.ce_ie_addr = NULL,
|
||||
.ce_remap = NULL,
|
||||
.bdf_addr_offset = 0,
|
||||
|
||||
.current_cc_support = true,
|
||||
|
||||
.dp_primary_link_only = false,
|
||||
},
|
||||
};
|
||||
|
||||
/* Note: called under rcu_read_lock() */
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#define QCN9274_DEVICE_ID 0x1109
|
||||
#define WCN7850_DEVICE_ID 0x1107
|
||||
#define QCC2072_DEVICE_ID 0x1112
|
||||
|
||||
#define ATH12K_PCI_W7_SOC_HW_VERSION_1 1
|
||||
#define ATH12K_PCI_W7_SOC_HW_VERSION_2 2
|
||||
|
|
@ -27,9 +28,13 @@
|
|||
#define TCSR_SOC_HW_VERSION_MAJOR_MASK GENMASK(11, 8)
|
||||
#define TCSR_SOC_HW_VERSION_MINOR_MASK GENMASK(7, 4)
|
||||
|
||||
#define WINDOW_REG_ADDRESS 0x310c
|
||||
#define WINDOW_REG_ADDRESS_QCC2072 0x3278
|
||||
|
||||
static const struct pci_device_id ath12k_wifi7_pci_id_table[] = {
|
||||
{ PCI_VDEVICE(QCOM, QCN9274_DEVICE_ID) },
|
||||
{ PCI_VDEVICE(QCOM, WCN7850_DEVICE_ID) },
|
||||
{ PCI_VDEVICE(QCOM, QCC2072_DEVICE_ID) },
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
@ -104,6 +109,11 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev,
|
|||
ab_pci->msi_config = &ath12k_wifi7_msi_config[0];
|
||||
ab->static_window_map = true;
|
||||
ab_pci->pci_ops = &ath12k_wifi7_pci_ops_qcn9274;
|
||||
/*
|
||||
* init window reg addr before reading hardware version
|
||||
* as it will be used there
|
||||
*/
|
||||
ab_pci->window_reg_addr = WINDOW_REG_ADDRESS;
|
||||
ath12k_wifi7_pci_read_hw_version(ab, &soc_hw_version_major,
|
||||
&soc_hw_version_minor);
|
||||
ab->target_mem_mode = ath12k_core_get_memory_mode(ab);
|
||||
|
|
@ -126,6 +136,11 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev,
|
|||
ab_pci->msi_config = &ath12k_wifi7_msi_config[0];
|
||||
ab->static_window_map = false;
|
||||
ab_pci->pci_ops = &ath12k_wifi7_pci_ops_wcn7850;
|
||||
/*
|
||||
* init window reg addr before reading hardware version
|
||||
* as it will be used there
|
||||
*/
|
||||
ab_pci->window_reg_addr = WINDOW_REG_ADDRESS;
|
||||
ath12k_wifi7_pci_read_hw_version(ab, &soc_hw_version_major,
|
||||
&soc_hw_version_minor);
|
||||
ab->target_mem_mode = ATH12K_QMI_MEMORY_MODE_DEFAULT;
|
||||
|
|
@ -140,7 +155,16 @@ static int ath12k_wifi7_pci_probe(struct pci_dev *pdev,
|
|||
return -EOPNOTSUPP;
|
||||
}
|
||||
break;
|
||||
|
||||
case QCC2072_DEVICE_ID:
|
||||
ab->id.bdf_search = ATH12K_BDF_SEARCH_BUS_AND_BOARD;
|
||||
ab_pci->msi_config = &ath12k_wifi7_msi_config[0];
|
||||
ab->static_window_map = false;
|
||||
ab_pci->pci_ops = &ath12k_wifi7_pci_ops_wcn7850;
|
||||
ab_pci->window_reg_addr = WINDOW_REG_ADDRESS_QCC2072;
|
||||
ab->target_mem_mode = ATH12K_QMI_MEMORY_MODE_DEFAULT;
|
||||
/* there is only one version till now */
|
||||
ab->hw_rev = ATH12K_HW_QCC2072_HW10;
|
||||
break;
|
||||
default:
|
||||
dev_err(&pdev->dev, "Unknown Wi-Fi 7 PCI device found: 0x%x\n",
|
||||
pci_dev->device);
|
||||
|
|
|
|||
|
|
@ -102,4 +102,9 @@ void ath12k_wifi7_wmi_init_wcn7850(struct ath12k_base *ab,
|
|||
config->num_multicast_filter_entries = 0x20;
|
||||
config->num_wow_filters = 0x16;
|
||||
config->num_keep_alive_pattern = 0;
|
||||
|
||||
if (test_bit(WMI_TLV_SERVICE_PEER_METADATA_V1A_V1B_SUPPORT, ab->wmi_ab.svc_map))
|
||||
config->peer_metadata_ver = ATH12K_PEER_METADATA_V1A;
|
||||
else
|
||||
config->peer_metadata_ver = ab->wmi_ab.dp_peer_meta_data_ver;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -399,6 +399,7 @@ ath12k_pull_mac_phy_cap_svc_ready_ext(struct ath12k_wmi_pdev *wmi_handle,
|
|||
struct ath12k_band_cap *cap_band;
|
||||
struct ath12k_pdev_cap *pdev_cap = &pdev->cap;
|
||||
struct ath12k_fw_pdev *fw_pdev;
|
||||
u32 supported_bands;
|
||||
u32 phy_map;
|
||||
u32 hw_idx, phy_idx = 0;
|
||||
int i;
|
||||
|
|
@ -422,14 +423,19 @@ ath12k_pull_mac_phy_cap_svc_ready_ext(struct ath12k_wmi_pdev *wmi_handle,
|
|||
return -EINVAL;
|
||||
|
||||
mac_caps = wmi_mac_phy_caps + phy_idx;
|
||||
supported_bands = le32_to_cpu(mac_caps->supported_bands);
|
||||
|
||||
if (!(supported_bands & WMI_HOST_WLAN_2GHZ_CAP) &&
|
||||
!(supported_bands & WMI_HOST_WLAN_5GHZ_CAP))
|
||||
return -EINVAL;
|
||||
|
||||
pdev->pdev_id = ath12k_wmi_mac_phy_get_pdev_id(mac_caps);
|
||||
pdev->hw_link_id = ath12k_wmi_mac_phy_get_hw_link_id(mac_caps);
|
||||
pdev_cap->supported_bands |= le32_to_cpu(mac_caps->supported_bands);
|
||||
pdev_cap->supported_bands |= 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->supported_bands = supported_bands;
|
||||
fw_pdev->pdev_id = ath12k_wmi_mac_phy_get_pdev_id(mac_caps);
|
||||
fw_pdev->phy_id = le32_to_cpu(mac_caps->phy_id);
|
||||
ab->fw_pdev_count++;
|
||||
|
|
@ -438,10 +444,12 @@ ath12k_pull_mac_phy_cap_svc_ready_ext(struct ath12k_wmi_pdev *wmi_handle,
|
|||
* band to band for a single radio, need to see how this should be
|
||||
* handled.
|
||||
*/
|
||||
if (le32_to_cpu(mac_caps->supported_bands) & WMI_HOST_WLAN_2GHZ_CAP) {
|
||||
if (supported_bands & WMI_HOST_WLAN_2GHZ_CAP) {
|
||||
pdev_cap->tx_chain_mask = le32_to_cpu(mac_caps->tx_chain_mask_2g);
|
||||
pdev_cap->rx_chain_mask = le32_to_cpu(mac_caps->rx_chain_mask_2g);
|
||||
} else if (le32_to_cpu(mac_caps->supported_bands) & WMI_HOST_WLAN_5GHZ_CAP) {
|
||||
}
|
||||
|
||||
if (supported_bands & WMI_HOST_WLAN_5GHZ_CAP) {
|
||||
pdev_cap->vht_cap = le32_to_cpu(mac_caps->vht_cap_info_5g);
|
||||
pdev_cap->vht_mcs = le32_to_cpu(mac_caps->vht_supp_mcs_5g);
|
||||
pdev_cap->he_mcs = le32_to_cpu(mac_caps->he_supp_mcs_5g);
|
||||
|
|
@ -451,8 +459,6 @@ ath12k_pull_mac_phy_cap_svc_ready_ext(struct ath12k_wmi_pdev *wmi_handle,
|
|||
WMI_NSS_RATIO_EN_DIS_GET(mac_caps->nss_ratio);
|
||||
pdev_cap->nss_ratio_info =
|
||||
WMI_NSS_RATIO_INFO_GET(mac_caps->nss_ratio);
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* tx/rx chainmask reported from fw depends on the actual hw chains used,
|
||||
|
|
@ -468,7 +474,7 @@ ath12k_pull_mac_phy_cap_svc_ready_ext(struct ath12k_wmi_pdev *wmi_handle,
|
|||
pdev_cap->rx_chain_mask_shift =
|
||||
find_first_bit((unsigned long *)&pdev_cap->rx_chain_mask, 32);
|
||||
|
||||
if (le32_to_cpu(mac_caps->supported_bands) & WMI_HOST_WLAN_2GHZ_CAP) {
|
||||
if (supported_bands & WMI_HOST_WLAN_2GHZ_CAP) {
|
||||
cap_band = &pdev_cap->band[NL80211_BAND_2GHZ];
|
||||
cap_band->phy_id = le32_to_cpu(mac_caps->phy_id);
|
||||
cap_band->max_bw_supported = le32_to_cpu(mac_caps->max_bw_supported_2g);
|
||||
|
|
@ -488,7 +494,7 @@ ath12k_pull_mac_phy_cap_svc_ready_ext(struct ath12k_wmi_pdev *wmi_handle,
|
|||
le32_to_cpu(mac_caps->he_ppet2g.ppet16_ppet8_ru3_ru0[i]);
|
||||
}
|
||||
|
||||
if (le32_to_cpu(mac_caps->supported_bands) & WMI_HOST_WLAN_5GHZ_CAP) {
|
||||
if (supported_bands & WMI_HOST_WLAN_5GHZ_CAP) {
|
||||
cap_band = &pdev_cap->band[NL80211_BAND_5GHZ];
|
||||
cap_band->phy_id = le32_to_cpu(mac_caps->phy_id);
|
||||
cap_band->max_bw_supported =
|
||||
|
|
@ -2800,7 +2806,8 @@ int ath12k_wmi_send_scan_chan_list_cmd(struct ath12k *ar,
|
|||
max_chan_limit = (wmi->wmi_ab->max_msg_len[ar->pdev_idx] - len) /
|
||||
sizeof(*chan_info);
|
||||
|
||||
num_send_chans = min(arg->nallchans, max_chan_limit);
|
||||
num_send_chans = min3(arg->nallchans, max_chan_limit,
|
||||
ATH12K_WMI_MAX_NUM_CHAN_PER_CMD);
|
||||
|
||||
arg->nallchans -= num_send_chans;
|
||||
len += sizeof(*chan_info) * num_send_chans;
|
||||
|
|
@ -4449,7 +4456,7 @@ static int ath12k_wmi_hw_mode_caps(struct ath12k_base *soc,
|
|||
|
||||
pref = soc->wmi_ab.preferred_hw_mode;
|
||||
|
||||
if (ath12k_hw_mode_pri_map[mode] < ath12k_hw_mode_pri_map[pref]) {
|
||||
if (ath12k_hw_mode_pri_map[mode] <= ath12k_hw_mode_pri_map[pref]) {
|
||||
svc_rdy_ext->pref_hw_mode_caps = *hw_mode_caps;
|
||||
soc->wmi_ab.preferred_hw_mode = mode;
|
||||
}
|
||||
|
|
@ -4918,19 +4925,10 @@ ath12k_wmi_tlv_mac_phy_caps_ext_parse(struct ath12k_base *ab,
|
|||
const struct ath12k_wmi_caps_ext_params *caps,
|
||||
struct ath12k_pdev *pdev)
|
||||
{
|
||||
struct ath12k_band_cap *cap_band;
|
||||
u32 bands, support_320mhz;
|
||||
u32 bands;
|
||||
int i;
|
||||
|
||||
if (ab->hw_params->single_pdev_only) {
|
||||
if (caps->hw_mode_id == WMI_HOST_HW_MODE_SINGLE) {
|
||||
support_320mhz = le32_to_cpu(caps->eht_cap_phy_info_5ghz[0]) &
|
||||
IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ;
|
||||
cap_band = &pdev->cap.band[NL80211_BAND_6GHZ];
|
||||
cap_band->eht_cap_phy_info[0] |= support_320mhz;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < ab->fw_pdev_count; i++) {
|
||||
struct ath12k_fw_pdev *fw_pdev = &ab->fw_pdev[i];
|
||||
|
||||
|
|
@ -4983,14 +4981,22 @@ static int ath12k_wmi_tlv_mac_phy_caps_ext(struct ath12k_base *ab, u16 tag,
|
|||
void *data)
|
||||
{
|
||||
const struct ath12k_wmi_caps_ext_params *caps = ptr;
|
||||
struct ath12k_band_cap *cap_band;
|
||||
u32 support_320mhz;
|
||||
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) &&
|
||||
caps->hw_mode_id != WMI_HOST_HW_MODE_SINGLE)
|
||||
if (caps->hw_mode_id == WMI_HOST_HW_MODE_SINGLE) {
|
||||
support_320mhz = le32_to_cpu(caps->eht_cap_phy_info_5ghz[0]) &
|
||||
IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ;
|
||||
cap_band = &ab->pdevs[0].cap.band[NL80211_BAND_6GHZ];
|
||||
cap_band->eht_cap_phy_info[0] |= support_320mhz;
|
||||
}
|
||||
|
||||
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++) {
|
||||
|
|
@ -5471,6 +5477,10 @@ static int ath12k_wmi_svc_rdy_ext2_parse(struct ath12k_base *ab,
|
|||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ab->wmi_ab.dp_peer_meta_data_ver =
|
||||
u32_get_bits(parse->arg.target_cap_flags,
|
||||
WMI_TARGET_CAP_FLAGS_RX_PEER_METADATA_VERSION);
|
||||
break;
|
||||
|
||||
case WMI_TAG_ARRAY_STRUCT:
|
||||
|
|
|
|||
|
|
@ -2783,6 +2783,8 @@ enum wmi_channel_width {
|
|||
#define WMI_EHT_MCS_NSS_10_11 GENMASK(11, 8)
|
||||
#define WMI_EHT_MCS_NSS_12_13 GENMASK(15, 12)
|
||||
|
||||
#define WMI_TARGET_CAP_FLAGS_RX_PEER_METADATA_VERSION GENMASK(1, 0)
|
||||
|
||||
struct wmi_service_ready_ext2_event {
|
||||
__le32 reg_db_version;
|
||||
__le32 hw_min_max_tx_power_2ghz;
|
||||
|
|
@ -5230,6 +5232,8 @@ struct ath12k_wmi_base {
|
|||
struct ath12k_svc_ext_info svc_ext_info;
|
||||
u32 sbs_lower_band_end_freq;
|
||||
struct ath12k_hw_mode_info hw_mode_info;
|
||||
|
||||
u8 dp_peer_meta_data_ver;
|
||||
};
|
||||
|
||||
struct wmi_pdev_set_bios_interface_cmd {
|
||||
|
|
@ -6322,6 +6326,9 @@ struct ath12k_wmi_rssi_dbm_conv_info_arg {
|
|||
s8 min_nf_dbm;
|
||||
};
|
||||
|
||||
/* each WMI cmd can hold 58 channel entries at most */
|
||||
#define ATH12K_WMI_MAX_NUM_CHAN_PER_CMD 58
|
||||
|
||||
int ath12k_wmi_cmd_send(struct ath12k_wmi_pdev *wmi, struct sk_buff *skb,
|
||||
u32 cmd_id);
|
||||
struct sk_buff *ath12k_wmi_alloc_skb(struct ath12k_wmi_base *wmi_sc, u32 len);
|
||||
|
|
|
|||
|
|
@ -135,6 +135,9 @@ static int ath12k_wow_cleanup(struct ath12k *ar)
|
|||
lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
|
||||
|
||||
list_for_each_entry(arvif, &ar->arvifs, list) {
|
||||
if (arvif != &arvif->ahvif->deflink)
|
||||
continue;
|
||||
|
||||
ret = ath12k_wow_vif_cleanup(arvif);
|
||||
if (ret) {
|
||||
ath12k_warn(ar->ab, "failed to clean wow wakeups on vdev %i: %d\n",
|
||||
|
|
@ -479,8 +482,12 @@ static int ath12k_wow_set_wakeups(struct ath12k *ar,
|
|||
lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
|
||||
|
||||
list_for_each_entry(arvif, &ar->arvifs, list) {
|
||||
if (arvif != &arvif->ahvif->deflink)
|
||||
continue;
|
||||
|
||||
if (ath12k_wow_is_p2p_vdev(arvif->ahvif))
|
||||
continue;
|
||||
|
||||
ret = ath12k_wow_vif_set_wakeups(arvif, wowlan);
|
||||
if (ret) {
|
||||
ath12k_warn(ar->ab, "failed to set wow wakeups on vdev %i: %d\n",
|
||||
|
|
@ -538,6 +545,9 @@ static int ath12k_wow_nlo_cleanup(struct ath12k *ar)
|
|||
lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
|
||||
|
||||
list_for_each_entry(arvif, &ar->arvifs, list) {
|
||||
if (arvif != &arvif->ahvif->deflink)
|
||||
continue;
|
||||
|
||||
if (ath12k_wow_is_p2p_vdev(arvif->ahvif))
|
||||
continue;
|
||||
|
||||
|
|
@ -745,6 +755,9 @@ static int ath12k_wow_arp_ns_offload(struct ath12k *ar, bool enable)
|
|||
list_for_each_entry(arvif, &ar->arvifs, list) {
|
||||
ahvif = arvif->ahvif;
|
||||
|
||||
if (arvif != &ahvif->deflink)
|
||||
continue;
|
||||
|
||||
if (ahvif->vdev_type != WMI_VDEV_TYPE_STA)
|
||||
continue;
|
||||
|
||||
|
|
@ -776,6 +789,9 @@ static int ath12k_gtk_rekey_offload(struct ath12k *ar, bool enable)
|
|||
lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
|
||||
|
||||
list_for_each_entry(arvif, &ar->arvifs, list) {
|
||||
if (arvif != &arvif->ahvif->deflink)
|
||||
continue;
|
||||
|
||||
if (arvif->ahvif->vdev_type != WMI_VDEV_TYPE_STA ||
|
||||
!arvif->is_up ||
|
||||
!arvif->rekey_data.enable_offload)
|
||||
|
|
|
|||
|
|
@ -80,11 +80,9 @@ struct ath5k_dbg_info {
|
|||
* @ATH5K_DEBUG_CALIBRATE: periodic calibration
|
||||
* @ATH5K_DEBUG_TXPOWER: transmit power setting
|
||||
* @ATH5K_DEBUG_LED: led management
|
||||
* @ATH5K_DEBUG_DUMP_RX: print received skb content
|
||||
* @ATH5K_DEBUG_DUMP_TX: print transmit skb content
|
||||
* @ATH5K_DEBUG_DUMPBANDS: dump bands
|
||||
* @ATH5K_DEBUG_DMA: debug dma start/stop
|
||||
* @ATH5K_DEBUG_TRACE: trace function calls
|
||||
* @ATH5K_DEBUG_ANI: debug Adaptive Noise Immunity
|
||||
* @ATH5K_DEBUG_DESC: descriptor setup
|
||||
* @ATH5K_DEBUG_ANY: show at any debug level
|
||||
*
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ config ATH9K_PCI
|
|||
|
||||
config ATH9K_AHB
|
||||
bool "Atheros ath9k AHB bus support"
|
||||
depends on ATH9K
|
||||
depends on ATH9K && OF
|
||||
default n
|
||||
help
|
||||
This option enables the AHB bus support in ath9k.
|
||||
|
|
|
|||
|
|
@ -19,14 +19,14 @@
|
|||
/**
|
||||
* struct ath_rx_stats - RX Statistics
|
||||
* @rx_pkts_all: No. of total frames received, including ones that
|
||||
may have had errors.
|
||||
* may have had errors.
|
||||
* @rx_bytes_all: No. of total bytes received, including ones that
|
||||
may have had errors.
|
||||
* may have had errors.
|
||||
* @crc_err: No. of frames with incorrect CRC value
|
||||
* @decrypt_crc_err: No. of frames whose CRC check failed after
|
||||
decryption process completed
|
||||
* decryption process completed
|
||||
* @phy_err: No. of frames whose reception failed because the PHY
|
||||
encountered an error
|
||||
* encountered an error
|
||||
* @mic_err: No. of frames with incorrect TKIP MIC verification failure
|
||||
* @pre_delim_crc_err: Pre-Frame delimiter CRC error detections
|
||||
* @post_delim_crc_err: Post-Frame delimiter CRC error detections
|
||||
|
|
|
|||
|
|
@ -142,11 +142,12 @@ struct ath_interrupt_stats {
|
|||
/**
|
||||
* struct ath_tx_stats - Statistics about TX
|
||||
* @tx_pkts_all: No. of total frames transmitted, including ones that
|
||||
may have had errors.
|
||||
* may have had errors.
|
||||
* @tx_bytes_all: No. of total bytes transmitted, including ones that
|
||||
may have had errors.
|
||||
* may have had errors.
|
||||
* @queued: Total MPDUs (non-aggr) queued
|
||||
* @completed: Total MPDUs (non-aggr) completed
|
||||
* @xretries: Total MPDUs with xretries
|
||||
* @a_aggr: Total no. of aggregates queued
|
||||
* @a_queued_hw: Total AMPDUs queued to hardware
|
||||
* @a_completed: Total AMPDUs completed
|
||||
|
|
@ -154,14 +155,14 @@ struct ath_interrupt_stats {
|
|||
* @a_xretries: No. of AMPDUs dropped due to xretries
|
||||
* @txerr_filtered: No. of frames with TXERR_FILT flag set.
|
||||
* @fifo_underrun: FIFO underrun occurrences
|
||||
Valid only for:
|
||||
- non-aggregate condition.
|
||||
- first packet of aggregate.
|
||||
* Valid only for:
|
||||
* - non-aggregate condition.
|
||||
* - first packet of aggregate.
|
||||
* @xtxop: No. of frames filtered because of TXOP limit
|
||||
* @timer_exp: Transmit timer expiry
|
||||
* @desc_cfg_err: Descriptor configuration errors
|
||||
* @data_urn: TX data underrun errors
|
||||
* @delim_urn: TX delimiter underrun errors
|
||||
* @data_underrun: TX data underrun errors
|
||||
* @delim_underrun: TX delimiter underrun errors
|
||||
* @puttxbuf: Number of times hardware was given txbuf to write.
|
||||
* @txstart: Number of times hardware was told to start tx.
|
||||
* @txprocdesc: Number of times tx descriptor was processed
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ union wil_tx_desc;
|
|||
*/
|
||||
#define WIL_MAX_VIFS 4
|
||||
|
||||
/**
|
||||
/*
|
||||
* extract bits [@b0:@b1] (inclusive) from the value @x
|
||||
* it should be @b0 <= @b1, or result is incorrect
|
||||
*/
|
||||
|
|
@ -433,7 +433,7 @@ extern struct fw_map fw_mapping[MAX_FW_MAPPING_TABLE_SIZE];
|
|||
* @cid: CID value
|
||||
* @tid: TID value
|
||||
*
|
||||
* @cidxtid field encoded as bits 0..3 - CID; 4..7 - TID
|
||||
* Returns: @cidxtid field encoded as bits 0..3 - CID; 4..7 - TID
|
||||
*/
|
||||
static inline u8 mk_cidxtid(u8 cid, u8 tid)
|
||||
{
|
||||
|
|
@ -444,8 +444,7 @@ static inline u8 mk_cidxtid(u8 cid, u8 tid)
|
|||
* parse_cidxtid - parse @cidxtid field
|
||||
* @cid: store CID value here
|
||||
* @tid: store TID value here
|
||||
*
|
||||
* @cidxtid field encoded as bits 0..3 - CID; 4..7 - TID
|
||||
* @cidxtid: field encoded as bits 0..3 - CID; 4..7 - TID
|
||||
*/
|
||||
static inline void parse_cidxtid(u8 cidxtid, u8 *cid, u8 *tid)
|
||||
{
|
||||
|
|
@ -500,7 +499,7 @@ enum { /* for wil_ctx.mapped_as */
|
|||
wil_mapped_as_page = 2,
|
||||
};
|
||||
|
||||
/**
|
||||
/*
|
||||
* struct wil_ctx - software context for ring descriptor
|
||||
*/
|
||||
struct wil_ctx {
|
||||
|
|
@ -514,7 +513,7 @@ struct wil_desc_ring_rx_swtail { /* relevant for enhanced DMA only */
|
|||
dma_addr_t pa;
|
||||
};
|
||||
|
||||
/**
|
||||
/*
|
||||
* A general ring structure, used for RX and TX.
|
||||
* In legacy DMA it represents the vring,
|
||||
* In enahnced DMA it represents the descriptor ring (vrings are handled by FW)
|
||||
|
|
@ -531,7 +530,7 @@ struct wil_ring {
|
|||
bool is_rx;
|
||||
};
|
||||
|
||||
/**
|
||||
/*
|
||||
* Additional data for Rx ring.
|
||||
* Used for enhanced DMA RX chaining.
|
||||
*/
|
||||
|
|
@ -543,7 +542,7 @@ struct wil_ring_rx_data {
|
|||
u16 buff_size;
|
||||
};
|
||||
|
||||
/**
|
||||
/*
|
||||
* Status ring structure, used for enhanced DMA completions for RX and TX.
|
||||
*/
|
||||
struct wil_status_ring {
|
||||
|
|
@ -586,8 +585,8 @@ struct wil_net_stats {
|
|||
u32 ft_roams; /* relevant in STA mode */
|
||||
};
|
||||
|
||||
/**
|
||||
* struct tx_rx_ops - different TX/RX ops for legacy and enhanced
|
||||
/*
|
||||
* struct wil_txrx_ops - different TX/RX ops for legacy and enhanced
|
||||
* DMA flow
|
||||
*/
|
||||
struct wil_txrx_ops {
|
||||
|
|
@ -627,7 +626,7 @@ struct wil_txrx_ops {
|
|||
irqreturn_t (*irq_rx)(int irq, void *cookie);
|
||||
};
|
||||
|
||||
/**
|
||||
/*
|
||||
* Additional data for Tx ring
|
||||
*/
|
||||
struct wil_ring_tx_data {
|
||||
|
|
@ -658,7 +657,7 @@ enum { /* for wil6210_priv.status */
|
|||
struct pci_dev;
|
||||
|
||||
/**
|
||||
* struct tid_ampdu_rx - TID aggregation information (Rx).
|
||||
* struct wil_tid_ampdu_rx - TID aggregation information (Rx).
|
||||
*
|
||||
* @reorder_buf: buffer to reorder incoming aggregated MPDUs
|
||||
* @last_rx: jiffies of last rx activity
|
||||
|
|
@ -728,7 +727,7 @@ enum wil_rekey_state {
|
|||
WIL_REKEY_WAIT_M4_SENT = 2,
|
||||
};
|
||||
|
||||
/**
|
||||
/*
|
||||
* struct wil_sta_info - data for peer
|
||||
*
|
||||
* Peer identified by its CID (connection ID)
|
||||
|
|
@ -741,7 +740,7 @@ struct wil_sta_info {
|
|||
u8 mid;
|
||||
enum wil_sta_status status;
|
||||
struct wil_net_stats stats;
|
||||
/**
|
||||
/*
|
||||
* 20 latency bins. 1st bin counts packets with latency
|
||||
* of 0..tx_latency_res, last bin counts packets with latency
|
||||
* of 19*tx_latency_res and above.
|
||||
|
|
@ -882,7 +881,7 @@ struct wil6210_vif {
|
|||
struct work_struct enable_tx_key_worker;
|
||||
};
|
||||
|
||||
/**
|
||||
/*
|
||||
* RX buffer allocated for enhanced DMA RX descriptors
|
||||
*/
|
||||
struct wil_rx_buff {
|
||||
|
|
@ -891,7 +890,7 @@ struct wil_rx_buff {
|
|||
int id;
|
||||
};
|
||||
|
||||
/**
|
||||
/*
|
||||
* During Rx completion processing, the driver extracts a buffer ID which
|
||||
* is used as an index to the rx_buff_mgmt.buff_arr array and then the SKB
|
||||
* is given to the network stack and the buffer is moved from the 'active'
|
||||
|
|
@ -1147,7 +1146,7 @@ static inline void wil_c(struct wil6210_priv *wil, u32 reg, u32 val)
|
|||
wil_w(wil, reg, wil_r(wil, reg) & ~val);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* wil_cid_valid - check cid is valid
|
||||
*/
|
||||
static inline bool wil_cid_valid(struct wil6210_priv *wil, int cid)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user