Commit 734223d7 authored by Baochen Qiang's avatar Baochen Qiang Committed by Kalle Valo

ath11k: change return buffer manager for QCA6390

QCA6390 firmware uses HAL_RX_BUF_RBM_SW1_BM, not HAL_RX_BUF_RBM_SW3_BM. This is
needed to fix a case where an A-MSDU has an unexpected LLC/SNAP header in the
first subframe (CVE-2020-24588).

Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
Signed-off-by: default avatarBaochen Qiang <bqiang@codeaurora.org>
Signed-off-by: default avatarJouni Malinen <jouni@codeaurora.org>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20210914163726.38604-2-jouni@codeaurora.org
parent 8347c806
...@@ -81,6 +81,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { ...@@ -81,6 +81,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
.fix_l1ss = true, .fix_l1ss = true,
.max_tx_ring = DP_TCL_NUM_RING_MAX, .max_tx_ring = DP_TCL_NUM_RING_MAX,
.hal_params = &ath11k_hw_hal_params_ipq8074,
}, },
{ {
.hw_rev = ATH11K_HW_IPQ6018_HW10, .hw_rev = ATH11K_HW_IPQ6018_HW10,
...@@ -129,6 +130,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { ...@@ -129,6 +130,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
.fix_l1ss = true, .fix_l1ss = true,
.max_tx_ring = DP_TCL_NUM_RING_MAX, .max_tx_ring = DP_TCL_NUM_RING_MAX,
.hal_params = &ath11k_hw_hal_params_ipq8074,
}, },
{ {
.name = "qca6390 hw2.0", .name = "qca6390 hw2.0",
...@@ -176,6 +178,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { ...@@ -176,6 +178,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
.fix_l1ss = true, .fix_l1ss = true,
.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390, .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
.hal_params = &ath11k_hw_hal_params_qca6390,
}, },
{ {
.name = "qcn9074 hw1.0", .name = "qcn9074 hw1.0",
...@@ -223,6 +226,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { ...@@ -223,6 +226,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074), .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074),
.fix_l1ss = true, .fix_l1ss = true,
.max_tx_ring = DP_TCL_NUM_RING_MAX, .max_tx_ring = DP_TCL_NUM_RING_MAX,
.hal_params = &ath11k_hw_hal_params_ipq8074,
}, },
{ {
.name = "wcn6855 hw2.0", .name = "wcn6855 hw2.0",
...@@ -270,6 +274,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { ...@@ -270,6 +274,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855), .hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),
.fix_l1ss = false, .fix_l1ss = false,
.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390, .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
.hal_params = &ath11k_hw_hal_params_qca6390,
}, },
}; };
......
...@@ -739,6 +739,7 @@ int ath11k_dp_service_srng(struct ath11k_base *ab, ...@@ -739,6 +739,7 @@ int ath11k_dp_service_srng(struct ath11k_base *ab,
int budget) int budget)
{ {
struct napi_struct *napi = &irq_grp->napi; struct napi_struct *napi = &irq_grp->napi;
const struct ath11k_hw_hal_params *hal_params;
int grp_id = irq_grp->grp_id; int grp_id = irq_grp->grp_id;
int work_done = 0; int work_done = 0;
int i = 0, j; int i = 0, j;
...@@ -821,8 +822,9 @@ int ath11k_dp_service_srng(struct ath11k_base *ab, ...@@ -821,8 +822,9 @@ int ath11k_dp_service_srng(struct ath11k_base *ab,
struct ath11k_pdev_dp *dp = &ar->dp; struct ath11k_pdev_dp *dp = &ar->dp;
struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring;
hal_params = ab->hw_params.hal_params;
ath11k_dp_rxbufs_replenish(ab, id, rx_ring, 0, ath11k_dp_rxbufs_replenish(ab, id, rx_ring, 0,
HAL_RX_BUF_RBM_SW3_BM); hal_params->rx_buf_rbm);
} }
} }
} }
......
...@@ -499,7 +499,7 @@ static int ath11k_dp_rxdma_ring_buf_setup(struct ath11k *ar, ...@@ -499,7 +499,7 @@ static int ath11k_dp_rxdma_ring_buf_setup(struct ath11k *ar,
rx_ring->bufs_max = num_entries; rx_ring->bufs_max = num_entries;
ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id, rx_ring, num_entries, ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id, rx_ring, num_entries,
HAL_RX_BUF_RBM_SW3_BM); ar->ab->hw_params.hal_params->rx_buf_rbm);
return 0; return 0;
} }
...@@ -2756,7 +2756,7 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id, ...@@ -2756,7 +2756,7 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
rx_ring = &ar->dp.rx_refill_buf_ring; rx_ring = &ar->dp.rx_refill_buf_ring;
ath11k_dp_rxbufs_replenish(ab, i, rx_ring, num_buffs_reaped[i], ath11k_dp_rxbufs_replenish(ab, i, rx_ring, num_buffs_reaped[i],
HAL_RX_BUF_RBM_SW3_BM); ab->hw_params.hal_params->rx_buf_rbm);
} }
ath11k_dp_rx_process_received_packets(ab, napi, &msdu_list, ath11k_dp_rx_process_received_packets(ab, napi, &msdu_list,
...@@ -2949,6 +2949,7 @@ static int ath11k_dp_rx_reap_mon_status_ring(struct ath11k_base *ab, int mac_id, ...@@ -2949,6 +2949,7 @@ static int ath11k_dp_rx_reap_mon_status_ring(struct ath11k_base *ab, int mac_id,
int *budget, struct sk_buff_head *skb_list) int *budget, struct sk_buff_head *skb_list)
{ {
struct ath11k *ar; struct ath11k *ar;
const struct ath11k_hw_hal_params *hal_params;
struct ath11k_pdev_dp *dp; struct ath11k_pdev_dp *dp;
struct dp_rxdma_ring *rx_ring; struct dp_rxdma_ring *rx_ring;
struct hal_srng *srng; struct hal_srng *srng;
...@@ -3019,8 +3020,9 @@ static int ath11k_dp_rx_reap_mon_status_ring(struct ath11k_base *ab, int mac_id, ...@@ -3019,8 +3020,9 @@ static int ath11k_dp_rx_reap_mon_status_ring(struct ath11k_base *ab, int mac_id,
&buf_id); &buf_id);
if (!skb) { if (!skb) {
hal_params = ab->hw_params.hal_params;
ath11k_hal_rx_buf_addr_info_set(rx_mon_status_desc, 0, 0, ath11k_hal_rx_buf_addr_info_set(rx_mon_status_desc, 0, 0,
HAL_RX_BUF_RBM_SW3_BM); hal_params->rx_buf_rbm);
num_buffs_reaped++; num_buffs_reaped++;
break; break;
} }
...@@ -3030,7 +3032,8 @@ static int ath11k_dp_rx_reap_mon_status_ring(struct ath11k_base *ab, int mac_id, ...@@ -3030,7 +3032,8 @@ static int ath11k_dp_rx_reap_mon_status_ring(struct ath11k_base *ab, int mac_id,
FIELD_PREP(DP_RXDMA_BUF_COOKIE_BUF_ID, buf_id); FIELD_PREP(DP_RXDMA_BUF_COOKIE_BUF_ID, buf_id);
ath11k_hal_rx_buf_addr_info_set(rx_mon_status_desc, rxcb->paddr, ath11k_hal_rx_buf_addr_info_set(rx_mon_status_desc, rxcb->paddr,
cookie, HAL_RX_BUF_RBM_SW3_BM); cookie,
ab->hw_params.hal_params->rx_buf_rbm);
ath11k_hal_srng_src_get_next_entry(ab, srng); ath11k_hal_srng_src_get_next_entry(ab, srng);
num_buffs_reaped++; num_buffs_reaped++;
} }
...@@ -3419,7 +3422,8 @@ static int ath11k_dp_rx_h_defrag_reo_reinject(struct ath11k *ar, struct dp_rx_ti ...@@ -3419,7 +3422,8 @@ static int ath11k_dp_rx_h_defrag_reo_reinject(struct ath11k *ar, struct dp_rx_ti
cookie = FIELD_PREP(DP_RXDMA_BUF_COOKIE_PDEV_ID, dp->mac_id) | cookie = FIELD_PREP(DP_RXDMA_BUF_COOKIE_PDEV_ID, dp->mac_id) |
FIELD_PREP(DP_RXDMA_BUF_COOKIE_BUF_ID, buf_id); FIELD_PREP(DP_RXDMA_BUF_COOKIE_BUF_ID, buf_id);
ath11k_hal_rx_buf_addr_info_set(msdu0, paddr, cookie, HAL_RX_BUF_RBM_SW3_BM); ath11k_hal_rx_buf_addr_info_set(msdu0, paddr, cookie,
ab->hw_params.hal_params->rx_buf_rbm);
/* Fill mpdu details into reo entrace ring */ /* Fill mpdu details into reo entrace ring */
srng = &ab->hal.srng_list[ab->dp.reo_reinject_ring.ring_id]; srng = &ab->hal.srng_list[ab->dp.reo_reinject_ring.ring_id];
...@@ -3796,7 +3800,7 @@ int ath11k_dp_process_rx_err(struct ath11k_base *ab, struct napi_struct *napi, ...@@ -3796,7 +3800,7 @@ int ath11k_dp_process_rx_err(struct ath11k_base *ab, struct napi_struct *napi,
ath11k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, msdu_cookies, ath11k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, msdu_cookies,
&rbm); &rbm);
if (rbm != HAL_RX_BUF_RBM_WBM_IDLE_DESC_LIST && if (rbm != HAL_RX_BUF_RBM_WBM_IDLE_DESC_LIST &&
rbm != HAL_RX_BUF_RBM_SW3_BM) { rbm != ab->hw_params.hal_params->rx_buf_rbm) {
ab->soc_stats.invalid_rbm++; ab->soc_stats.invalid_rbm++;
ath11k_warn(ab, "invalid return buffer manager %d\n", rbm); ath11k_warn(ab, "invalid return buffer manager %d\n", rbm);
ath11k_dp_rx_link_desc_return(ab, desc, ath11k_dp_rx_link_desc_return(ab, desc,
...@@ -3852,7 +3856,7 @@ int ath11k_dp_process_rx_err(struct ath11k_base *ab, struct napi_struct *napi, ...@@ -3852,7 +3856,7 @@ int ath11k_dp_process_rx_err(struct ath11k_base *ab, struct napi_struct *napi,
rx_ring = &ar->dp.rx_refill_buf_ring; rx_ring = &ar->dp.rx_refill_buf_ring;
ath11k_dp_rxbufs_replenish(ab, i, rx_ring, n_bufs_reaped[i], ath11k_dp_rxbufs_replenish(ab, i, rx_ring, n_bufs_reaped[i],
HAL_RX_BUF_RBM_SW3_BM); ab->hw_params.hal_params->rx_buf_rbm);
} }
return tot_n_bufs_reaped; return tot_n_bufs_reaped;
...@@ -4148,7 +4152,7 @@ int ath11k_dp_rx_process_wbm_err(struct ath11k_base *ab, ...@@ -4148,7 +4152,7 @@ int ath11k_dp_rx_process_wbm_err(struct ath11k_base *ab,
rx_ring = &ar->dp.rx_refill_buf_ring; rx_ring = &ar->dp.rx_refill_buf_ring;
ath11k_dp_rxbufs_replenish(ab, i, rx_ring, num_buffs_reaped[i], ath11k_dp_rxbufs_replenish(ab, i, rx_ring, num_buffs_reaped[i],
HAL_RX_BUF_RBM_SW3_BM); ab->hw_params.hal_params->rx_buf_rbm);
} }
rcu_read_lock(); rcu_read_lock();
...@@ -4257,7 +4261,7 @@ int ath11k_dp_process_rxdma_err(struct ath11k_base *ab, int mac_id, int budget) ...@@ -4257,7 +4261,7 @@ int ath11k_dp_process_rxdma_err(struct ath11k_base *ab, int mac_id, int budget)
if (num_buf_freed) if (num_buf_freed)
ath11k_dp_rxbufs_replenish(ab, mac_id, rx_ring, num_buf_freed, ath11k_dp_rxbufs_replenish(ab, mac_id, rx_ring, num_buf_freed,
HAL_RX_BUF_RBM_SW3_BM); ab->hw_params.hal_params->rx_buf_rbm);
return budget - quota; return budget - quota;
} }
...@@ -4976,6 +4980,7 @@ static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id, ...@@ -4976,6 +4980,7 @@ static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id,
{ {
struct ath11k_pdev_dp *dp = &ar->dp; struct ath11k_pdev_dp *dp = &ar->dp;
struct ath11k_mon_data *pmon = (struct ath11k_mon_data *)&dp->mon_data; struct ath11k_mon_data *pmon = (struct ath11k_mon_data *)&dp->mon_data;
const struct ath11k_hw_hal_params *hal_params;
void *ring_entry; void *ring_entry;
void *mon_dst_srng; void *mon_dst_srng;
u32 ppdu_id; u32 ppdu_id;
...@@ -5039,16 +5044,18 @@ static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id, ...@@ -5039,16 +5044,18 @@ static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id,
if (rx_bufs_used) { if (rx_bufs_used) {
rx_mon_stats->dest_ppdu_done++; rx_mon_stats->dest_ppdu_done++;
hal_params = ar->ab->hw_params.hal_params;
if (ar->ab->hw_params.rxdma1_enable) if (ar->ab->hw_params.rxdma1_enable)
ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id, ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id,
&dp->rxdma_mon_buf_ring, &dp->rxdma_mon_buf_ring,
rx_bufs_used, rx_bufs_used,
HAL_RX_BUF_RBM_SW3_BM); hal_params->rx_buf_rbm);
else else
ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id, ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id,
&dp->rx_refill_buf_ring, &dp->rx_refill_buf_ring,
rx_bufs_used, rx_bufs_used,
HAL_RX_BUF_RBM_SW3_BM); hal_params->rx_buf_rbm);
} }
} }
......
...@@ -356,6 +356,7 @@ int ath11k_hal_wbm_desc_parse_err(struct ath11k_base *ab, void *desc, ...@@ -356,6 +356,7 @@ int ath11k_hal_wbm_desc_parse_err(struct ath11k_base *ab, void *desc,
struct hal_wbm_release_ring *wbm_desc = desc; struct hal_wbm_release_ring *wbm_desc = desc;
enum hal_wbm_rel_desc_type type; enum hal_wbm_rel_desc_type type;
enum hal_wbm_rel_src_module rel_src; enum hal_wbm_rel_src_module rel_src;
enum hal_rx_buf_return_buf_manager ret_buf_mgr;
type = FIELD_GET(HAL_WBM_RELEASE_INFO0_DESC_TYPE, type = FIELD_GET(HAL_WBM_RELEASE_INFO0_DESC_TYPE,
wbm_desc->info0); wbm_desc->info0);
...@@ -371,8 +372,9 @@ int ath11k_hal_wbm_desc_parse_err(struct ath11k_base *ab, void *desc, ...@@ -371,8 +372,9 @@ int ath11k_hal_wbm_desc_parse_err(struct ath11k_base *ab, void *desc,
rel_src != HAL_WBM_REL_SRC_MODULE_REO) rel_src != HAL_WBM_REL_SRC_MODULE_REO)
return -EINVAL; return -EINVAL;
if (FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR, ret_buf_mgr = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR,
wbm_desc->buf_addr_info.info1) != HAL_RX_BUF_RBM_SW3_BM) { wbm_desc->buf_addr_info.info1);
if (ret_buf_mgr != ab->hw_params.hal_params->rx_buf_rbm) {
ab->soc_stats.invalid_rbm++; ab->soc_stats.invalid_rbm++;
return -EINVAL; return -EINVAL;
} }
......
...@@ -7,10 +7,11 @@ ...@@ -7,10 +7,11 @@
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/bitfield.h> #include <linux/bitfield.h>
#include "hw.h"
#include "core.h" #include "core.h"
#include "ce.h" #include "ce.h"
#include "hif.h" #include "hif.h"
#include "hal.h"
#include "hw.h"
/* Map from pdev index to hw mac index */ /* Map from pdev index to hw mac index */
static u8 ath11k_hw_ipq8074_mac_from_pdev_id(int pdev_idx) static u8 ath11k_hw_ipq8074_mac_from_pdev_id(int pdev_idx)
...@@ -2124,3 +2125,11 @@ const struct ath11k_hw_regs wcn6855_regs = { ...@@ -2124,3 +2125,11 @@ const struct ath11k_hw_regs wcn6855_regs = {
.pcie_qserdes_sysclk_en_sel = 0x01e0c0ac, .pcie_qserdes_sysclk_en_sel = 0x01e0c0ac,
.pcie_pcs_osc_dtct_config_base = 0x01e0c628, .pcie_pcs_osc_dtct_config_base = 0x01e0c628,
}; };
const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq8074 = {
.rx_buf_rbm = HAL_RX_BUF_RBM_SW3_BM,
};
const struct ath11k_hw_hal_params ath11k_hw_hal_params_qca6390 = {
.rx_buf_rbm = HAL_RX_BUF_RBM_SW1_BM,
};
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#ifndef ATH11K_HW_H #ifndef ATH11K_HW_H
#define ATH11K_HW_H #define ATH11K_HW_H
#include "hal.h"
#include "wmi.h" #include "wmi.h"
/* Target configuration defines */ /* Target configuration defines */
...@@ -119,6 +120,10 @@ struct ath11k_hw_ring_mask { ...@@ -119,6 +120,10 @@ struct ath11k_hw_ring_mask {
u8 host2rxdma[ATH11K_EXT_IRQ_GRP_NUM_MAX]; u8 host2rxdma[ATH11K_EXT_IRQ_GRP_NUM_MAX];
}; };
struct ath11k_hw_hal_params {
enum hal_rx_buf_return_buf_manager rx_buf_rbm;
};
struct ath11k_hw_params { struct ath11k_hw_params {
const char *name; const char *name;
u16 hw_rev; u16 hw_rev;
...@@ -170,6 +175,7 @@ struct ath11k_hw_params { ...@@ -170,6 +175,7 @@ struct ath11k_hw_params {
u32 hal_desc_sz; u32 hal_desc_sz;
bool fix_l1ss; bool fix_l1ss;
u8 max_tx_ring; u8 max_tx_ring;
const struct ath11k_hw_hal_params *hal_params;
}; };
struct ath11k_hw_ops { struct ath11k_hw_ops {
...@@ -223,6 +229,9 @@ extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_ipq8074; ...@@ -223,6 +229,9 @@ extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_ipq8074;
extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qca6390; extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qca6390;
extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qcn9074; extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qcn9074;
extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq8074;
extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_qca6390;
static inline static inline
int ath11k_hw_get_mac_from_pdev_id(struct ath11k_hw_params *hw, int ath11k_hw_get_mac_from_pdev_id(struct ath11k_hw_params *hw,
int pdev_idx) int pdev_idx)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment