Commit 7636c9a6 authored by Manikanta Pubbisetty's avatar Manikanta Pubbisetty Committed by Kalle Valo
Browse files

wifi: ath11k: Add multi TX ring support for WCN6750



Currently in the case of WCN6750, only one TCL ring is used for TX,
this is limiting the TX throughput in 160 MHz case, enabling multiple
TCL rings on WCN6750 has shown an improvement of nearly 300 Mbps in
the case of TCP TX, therefore add the support of multi TX ring for
WCN6750.

Currently TCL ring is selected based on CPU ID, this logic cannot be
applied for WCN6750 as there is chance of out of order TX of packets
and to avoid this, choose TCL ring based on flow hash so that packets
of the same flow will end up on same TCL ring. For the same reason,
TCL ring retry logic is also not applicable for WCN6750.

Also the mapping of TCL, WBM & RBM IDs for WCN6750 is different from
existing devices. Create a new TCM/WBM/RBM mapping for WCN6750.

Change does not impact existing ath11k devices.

Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1

Signed-off-by: default avatarManikanta Pubbisetty <quic_mpubbise@quicinc.com>
Signed-off-by: default avatarKalle Valo <quic_kvalo@quicinc.com>
Link: https://lore.kernel.org/r/20220905071805.31625-3-quic_mpubbise@quicinc.com
parent 13aa2fb6
Loading
Loading
Loading
Loading
+17 −3
Original line number Diff line number Diff line
@@ -110,6 +110,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
		.supports_multi_bssid = false,

		.sram_dump = {},

		.tcl_ring_retry = true,
	},
	{
		.hw_rev = ATH11K_HW_IPQ6018_HW10,
@@ -185,6 +187,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
		.supports_multi_bssid = false,

		.sram_dump = {},

		.tcl_ring_retry = true,
	},
	{
		.name = "qca6390 hw2.0",
@@ -262,6 +266,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
			.start = 0x01400000,
			.end = 0x0171ffff,
		},

		.tcl_ring_retry = true,
	},
	{
		.name = "qcn9074 hw1.0",
@@ -336,6 +342,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
		.supports_multi_bssid = false,

		.sram_dump = {},

		.tcl_ring_retry = true,
	},
	{
		.name = "wcn6855 hw2.0",
@@ -413,6 +421,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
			.start = 0x01400000,
			.end = 0x0177ffff,
		},

		.tcl_ring_retry = true,
	},
	{
		.name = "wcn6855 hw2.1",
@@ -489,6 +499,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
			.start = 0x01400000,
			.end = 0x0177ffff,
		},

		.tcl_ring_retry = true,
	},
	{
		.name = "wcn6750 hw1.0",
@@ -501,7 +513,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
		.max_radios = 1,
		.bdf_addr = 0x4B0C0000,
		.hw_ops = &wcn6750_ops,
		.ring_mask = &ath11k_hw_ring_mask_qca6390,
		.ring_mask = &ath11k_hw_ring_mask_wcn6750,
		.internal_sleep_clock = false,
		.regs = &wcn6750_regs,
		.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_WCN6750,
@@ -542,8 +554,8 @@ 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,
		.max_tx_ring = DP_TCL_NUM_RING_MAX,
		.hal_params = &ath11k_hw_hal_params_wcn6750,
		.supports_dynamic_smps_6ghz = false,
		.alloc_cacheable_memory = false,
		.supports_rssi_stats = true,
@@ -562,6 +574,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
		.supports_multi_bssid = true,

		.sram_dump = {},

		.tcl_ring_retry = false,
	},
};

+14 −10
Original line number Diff line number Diff line
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 */

#include <crypto/hash.h>
@@ -131,13 +132,11 @@ static int ath11k_dp_srng_calculate_msi_group(struct ath11k_base *ab,

	switch (type) {
	case HAL_WBM2SW_RELEASE:
		if (ring_num < 3) {
			grp_mask = &ab->hw_params.ring_mask->tx[0];
		} else if (ring_num == 3) {
		if (ring_num == DP_RX_RELEASE_RING_NUM) {
			grp_mask = &ab->hw_params.ring_mask->rx_wbm_rel[0];
			ring_num = 0;
		} else {
			return -ENOENT;
			grp_mask = &ab->hw_params.ring_mask->tx[0];
		}
		break;
	case HAL_REO_EXCEPTION:
@@ -371,6 +370,7 @@ static int ath11k_dp_srng_common_setup(struct ath11k_base *ab)
	struct ath11k_dp *dp = &ab->dp;
	struct hal_srng *srng;
	int i, ret;
	u8 tcl_num, wbm_num;

	ret = ath11k_dp_srng_setup(ab, &dp->wbm_desc_rel_ring,
				   HAL_SW2WBM_RELEASE, 0, 0,
@@ -396,8 +396,11 @@ static int ath11k_dp_srng_common_setup(struct ath11k_base *ab)
	}

	for (i = 0; i < ab->hw_params.max_tx_ring; 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;

		ret = ath11k_dp_srng_setup(ab, &dp->tx_ring[i].tcl_data_ring,
					   HAL_TCL_DATA, i, 0,
					   HAL_TCL_DATA, tcl_num, 0,
					   DP_TCL_DATA_RING_SIZE);
		if (ret) {
			ath11k_warn(ab, "failed to set up tcl_data ring (%d) :%d\n",
@@ -406,7 +409,7 @@ static int ath11k_dp_srng_common_setup(struct ath11k_base *ab)
		}

		ret = ath11k_dp_srng_setup(ab, &dp->tx_ring[i].tcl_comp_ring,
					   HAL_WBM2SW_RELEASE, i, 0,
					   HAL_WBM2SW_RELEASE, wbm_num, 0,
					   DP_TX_COMP_RING_SIZE);
		if (ret) {
			ath11k_warn(ab, "failed to set up tcl_comp ring (%d) :%d\n",
@@ -431,7 +434,7 @@ static int ath11k_dp_srng_common_setup(struct ath11k_base *ab)
	}

	ret = ath11k_dp_srng_setup(ab, &dp->rx_rel_ring, HAL_WBM2SW_RELEASE,
				   3, 0, DP_RX_RELEASE_RING_SIZE);
				   DP_RX_RELEASE_RING_NUM, 0, DP_RX_RELEASE_RING_SIZE);
	if (ret) {
		ath11k_warn(ab, "failed to set up rx_rel ring :%d\n", ret);
		goto err;
@@ -774,8 +777,9 @@ int ath11k_dp_service_srng(struct ath11k_base *ab,
	int i, j;
	int tot_work_done = 0;

	if (ab->hw_params.ring_mask->tx[grp_id]) {
		i = __fls(ab->hw_params.ring_mask->tx[grp_id]);
	for (i = 0; i < ab->hw_params.max_tx_ring; 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);
	}

+2 −0
Original line number Diff line number Diff line
@@ -222,6 +222,8 @@ struct ath11k_pdev_dp {
#define DP_RXDMA_MONITOR_DST_RING_SIZE	2048
#define DP_RXDMA_MONITOR_DESC_RING_SIZE	4096

#define DP_RX_RELEASE_RING_NUM	3

#define DP_RX_BUFFER_SIZE	2048
#define	DP_RX_BUFFER_SIZE_LITE  1024
#define DP_RX_BUFFER_ALIGN_SIZE	128
+8 −11
Original line number Diff line number Diff line
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 */

#include "core.h"
@@ -93,7 +94,8 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
	u8 pool_id;
	u8 hal_ring_id;
	int ret;
	u8 ring_selector = 0, ring_map = 0;
	u32 ring_selector = 0;
	u8 ring_map = 0;
	bool tcl_ring_retry;

	if (unlikely(test_bit(ATH11K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags)))
@@ -105,19 +107,13 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,

	pool_id = skb_get_queue_mapping(skb) & (ATH11K_HW_MAX_QUEUES - 1);

	/* Let the default ring selection be based on current processor
	 * number, where one of the 3 tcl rings are selected based on
	 * the smp_processor_id(). In case that ring
	 * is full/busy, we resort to other available rings.
	 * If all rings are full, we drop the packet.
	 * //TODO Add throttling logic when all rings are full
	 */
	ring_selector = smp_processor_id();
	ring_selector = ab->hw_params.hw_ops->get_ring_selector(skb);

tcl_ring_sel:
	tcl_ring_retry = false;

	ti.ring_id = ring_selector % ab->hw_params.max_tx_ring;
	ti.rbm_id = ab->hw_params.hal_params->tcl2wbm_rbm_map[ti.ring_id].rbm_id;

	ring_map |= BIT(ti.ring_id);

@@ -129,7 +125,8 @@ 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(ab->hw_params.max_tx_ring) - 1) ||
		    !ab->hw_params.tcl_ring_retry) {
			atomic_inc(&ab->soc_stats.tx_err.misc_fail);
			return -ENOSPC;
		}
@@ -247,7 +244,7 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
		 * 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.max_tx_ring > 1) {
		    ab->hw_params.tcl_ring_retry && ab->hw_params.max_tx_ring > 1) {
			tcl_ring_retry = true;
			ring_selector++;
		}
+1 −1
Original line number Diff line number Diff line
@@ -126,7 +126,7 @@ static const struct hal_srng_config hw_srng_config_template[] = {
	},
	{ /* WBM2SW_RELEASE */
		.start_ring_id = HAL_SRNG_RING_ID_WBM2SW0_RELEASE,
		.max_rings = 4,
		.max_rings = 5,
		.entry_size = sizeof(struct hal_wbm_release_ring) >> 2,
		.lmac_ring = false,
		.ring_dir = HAL_SRNG_DIR_DST,
Loading