mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 16:44:58 +02:00
wifi: ath11k: move .max_tx_ring to struct ath11k_hw_hal_params
".max_tx_ring" is an upper bounds to indexing ".tcl2wbm_rbm_map". It is initialized in, core.c, a different file than the array. This spaghetti-like relation is fragile and not obvious. Accidentally setting ".max_tx_ring" too high leads to a hard to track out-of- bounds access and memory corruption. There is a small ambiguity on the meaning of "max_tx_ring": - The highest ring, max=3 implies there are 4 rings (0, 1, 2, 3) - The highest number to use for array indexing (there are 3 rings) Clarify this dependency by moving ".max_tx_ring" adjacent to the array ".tcl2wbm_rbm_map", and name it "num_tx_rings". Use ARRAY_SIZE() instead of #defines to initialize the length field. The intent is to make the code easier to understand rather than fix an existing bug. Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com> Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com> Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com> Link: https://patch.msgid.link/20251228151408.2116108-1-mr.nuke.me@gmail.com Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
This commit is contained in:
parent
ca765beda7
commit
b515730ec3
|
|
@ -99,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,
|
||||
|
|
@ -186,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,
|
||||
|
|
@ -276,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,
|
||||
|
|
@ -366,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,
|
||||
|
|
@ -456,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,
|
||||
|
|
@ -547,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,
|
||||
|
|
@ -636,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,
|
||||
|
|
@ -682,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,
|
||||
|
|
@ -718,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,
|
||||
|
|
@ -812,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,
|
||||
|
|
@ -902,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,
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
||||
|
|
|
|||
|
|
@ -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++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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[] = {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -294,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;
|
||||
|
|
|
|||
|
|
@ -7407,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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user