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

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
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -81,6 +81,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
		.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
		.fix_l1ss = true,
		.max_tx_ring = DP_TCL_NUM_RING_MAX,
		.hal_params = &ath11k_hw_hal_params_ipq8074,
	},
	{
		.hw_rev = ATH11K_HW_IPQ6018_HW10,
@@ -129,6 +130,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
		.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
		.fix_l1ss = true,
		.max_tx_ring = DP_TCL_NUM_RING_MAX,
		.hal_params = &ath11k_hw_hal_params_ipq8074,
	},
	{
		.name = "qca6390 hw2.0",
@@ -176,6 +178,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
		.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
		.fix_l1ss = true,
		.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
		.hal_params = &ath11k_hw_hal_params_qca6390,
	},
	{
		.name = "qcn9074 hw1.0",
@@ -223,6 +226,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
		.hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074),
		.fix_l1ss = true,
		.max_tx_ring = DP_TCL_NUM_RING_MAX,
		.hal_params = &ath11k_hw_hal_params_ipq8074,
	},
	{
		.name = "wcn6855 hw2.0",
@@ -270,6 +274,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
		.hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),
		.fix_l1ss = false,
		.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
		.hal_params = &ath11k_hw_hal_params_qca6390,
	},
};

+3 −1
Original line number Diff line number Diff line
@@ -739,6 +739,7 @@ int ath11k_dp_service_srng(struct ath11k_base *ab,
			   int budget)
{
	struct napi_struct *napi = &irq_grp->napi;
	const struct ath11k_hw_hal_params *hal_params;
	int grp_id = irq_grp->grp_id;
	int work_done = 0;
	int i = 0, j;
@@ -821,8 +822,9 @@ int ath11k_dp_service_srng(struct ath11k_base *ab,
				struct ath11k_pdev_dp *dp = &ar->dp;
				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,
							   HAL_RX_BUF_RBM_SW3_BM);
							   hal_params->rx_buf_rbm);
			}
		}
	}
+18 −11
Original line number Diff line number Diff line
@@ -499,7 +499,7 @@ static int ath11k_dp_rxdma_ring_buf_setup(struct ath11k *ar,

	rx_ring->bufs_max = 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;
}

@@ -2756,7 +2756,7 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
		rx_ring = &ar->dp.rx_refill_buf_ring;

		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,
@@ -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)
{
	struct ath11k *ar;
	const struct ath11k_hw_hal_params *hal_params;
	struct ath11k_pdev_dp *dp;
	struct dp_rxdma_ring *rx_ring;
	struct hal_srng *srng;
@@ -3019,8 +3020,9 @@ static int ath11k_dp_rx_reap_mon_status_ring(struct ath11k_base *ab, int mac_id,
							&buf_id);

		if (!skb) {
			hal_params = ab->hw_params.hal_params;
			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++;
			break;
		}
@@ -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);

		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);
		num_buffs_reaped++;
	}
@@ -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) |
		 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 */
	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,
		ath11k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, msdu_cookies,
						 &rbm);
		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++;
			ath11k_warn(ab, "invalid return buffer manager %d\n", rbm);
			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,
		rx_ring = &ar->dp.rx_refill_buf_ring;

		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;
@@ -4148,7 +4152,7 @@ int ath11k_dp_rx_process_wbm_err(struct ath11k_base *ab,
		rx_ring = &ar->dp.rx_refill_buf_ring;

		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();
@@ -4257,7 +4261,7 @@ int ath11k_dp_process_rxdma_err(struct ath11k_base *ab, int mac_id, int budget)

	if (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;
}
@@ -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_mon_data *pmon = (struct ath11k_mon_data *)&dp->mon_data;
	const struct ath11k_hw_hal_params *hal_params;
	void *ring_entry;
	void *mon_dst_srng;
	u32 ppdu_id;
@@ -5039,16 +5044,18 @@ static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id,

	if (rx_bufs_used) {
		rx_mon_stats->dest_ppdu_done++;
		hal_params = ar->ab->hw_params.hal_params;

		if (ar->ab->hw_params.rxdma1_enable)
			ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id,
						   &dp->rxdma_mon_buf_ring,
						   rx_bufs_used,
						   HAL_RX_BUF_RBM_SW3_BM);
						   hal_params->rx_buf_rbm);
		else
			ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id,
						   &dp->rx_refill_buf_ring,
						   rx_bufs_used,
						   HAL_RX_BUF_RBM_SW3_BM);
						   hal_params->rx_buf_rbm);
	}
}

+4 −2
Original line number Diff line number Diff line
@@ -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;
	enum hal_wbm_rel_desc_type type;
	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,
			 wbm_desc->info0);
@@ -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)
		return -EINVAL;

	if (FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR,
		      wbm_desc->buf_addr_info.info1) != HAL_RX_BUF_RBM_SW3_BM) {
	ret_buf_mgr = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR,
				wbm_desc->buf_addr_info.info1);
	if (ret_buf_mgr != ab->hw_params.hal_params->rx_buf_rbm) {
		ab->soc_stats.invalid_rbm++;
		return -EINVAL;
	}
+10 −1
Original line number Diff line number Diff line
@@ -7,10 +7,11 @@
#include <linux/bitops.h>
#include <linux/bitfield.h>

#include "hw.h"
#include "core.h"
#include "ce.h"
#include "hif.h"
#include "hal.h"
#include "hw.h"

/* Map from pdev index to hw mac index */
static u8 ath11k_hw_ipq8074_mac_from_pdev_id(int pdev_idx)
@@ -2124,3 +2125,11 @@ const struct ath11k_hw_regs wcn6855_regs = {
	.pcie_qserdes_sysclk_en_sel = 0x01e0c0ac,
	.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,
};
Loading