162306a36Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause-Clear
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
462306a36Sopenharmony_ci * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci#include <linux/dma-mapping.h>
762306a36Sopenharmony_ci#include "hal_tx.h"
862306a36Sopenharmony_ci#include "hal_rx.h"
962306a36Sopenharmony_ci#include "debug.h"
1062306a36Sopenharmony_ci#include "hal_desc.h"
1162306a36Sopenharmony_ci#include "hif.h"
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_cistatic const struct hal_srng_config hw_srng_config_template[] = {
1462306a36Sopenharmony_ci	/* TODO: max_rings can populated by querying HW capabilities */
1562306a36Sopenharmony_ci	[HAL_REO_DST] = {
1662306a36Sopenharmony_ci		.start_ring_id = HAL_SRNG_RING_ID_REO2SW1,
1762306a36Sopenharmony_ci		.max_rings = 8,
1862306a36Sopenharmony_ci		.entry_size = sizeof(struct hal_reo_dest_ring) >> 2,
1962306a36Sopenharmony_ci		.mac_type = ATH12K_HAL_SRNG_UMAC,
2062306a36Sopenharmony_ci		.ring_dir = HAL_SRNG_DIR_DST,
2162306a36Sopenharmony_ci		.max_size = HAL_REO_REO2SW1_RING_BASE_MSB_RING_SIZE,
2262306a36Sopenharmony_ci	},
2362306a36Sopenharmony_ci	[HAL_REO_EXCEPTION] = {
2462306a36Sopenharmony_ci		/* Designating REO2SW0 ring as exception ring.
2562306a36Sopenharmony_ci		 * Any of theREO2SW rings can be used as exception ring.
2662306a36Sopenharmony_ci		 */
2762306a36Sopenharmony_ci		.start_ring_id = HAL_SRNG_RING_ID_REO2SW0,
2862306a36Sopenharmony_ci		.max_rings = 1,
2962306a36Sopenharmony_ci		.entry_size = sizeof(struct hal_reo_dest_ring) >> 2,
3062306a36Sopenharmony_ci		.mac_type = ATH12K_HAL_SRNG_UMAC,
3162306a36Sopenharmony_ci		.ring_dir = HAL_SRNG_DIR_DST,
3262306a36Sopenharmony_ci		.max_size = HAL_REO_REO2SW0_RING_BASE_MSB_RING_SIZE,
3362306a36Sopenharmony_ci	},
3462306a36Sopenharmony_ci	[HAL_REO_REINJECT] = {
3562306a36Sopenharmony_ci		.start_ring_id = HAL_SRNG_RING_ID_SW2REO,
3662306a36Sopenharmony_ci		.max_rings = 4,
3762306a36Sopenharmony_ci		.entry_size = sizeof(struct hal_reo_entrance_ring) >> 2,
3862306a36Sopenharmony_ci		.mac_type = ATH12K_HAL_SRNG_UMAC,
3962306a36Sopenharmony_ci		.ring_dir = HAL_SRNG_DIR_SRC,
4062306a36Sopenharmony_ci		.max_size = HAL_REO_SW2REO_RING_BASE_MSB_RING_SIZE,
4162306a36Sopenharmony_ci	},
4262306a36Sopenharmony_ci	[HAL_REO_CMD] = {
4362306a36Sopenharmony_ci		.start_ring_id = HAL_SRNG_RING_ID_REO_CMD,
4462306a36Sopenharmony_ci		.max_rings = 1,
4562306a36Sopenharmony_ci		.entry_size = (sizeof(struct hal_tlv_64_hdr) +
4662306a36Sopenharmony_ci			sizeof(struct hal_reo_get_queue_stats)) >> 2,
4762306a36Sopenharmony_ci		.mac_type = ATH12K_HAL_SRNG_UMAC,
4862306a36Sopenharmony_ci		.ring_dir = HAL_SRNG_DIR_SRC,
4962306a36Sopenharmony_ci		.max_size = HAL_REO_CMD_RING_BASE_MSB_RING_SIZE,
5062306a36Sopenharmony_ci	},
5162306a36Sopenharmony_ci	[HAL_REO_STATUS] = {
5262306a36Sopenharmony_ci		.start_ring_id = HAL_SRNG_RING_ID_REO_STATUS,
5362306a36Sopenharmony_ci		.max_rings = 1,
5462306a36Sopenharmony_ci		.entry_size = (sizeof(struct hal_tlv_64_hdr) +
5562306a36Sopenharmony_ci			sizeof(struct hal_reo_get_queue_stats_status)) >> 2,
5662306a36Sopenharmony_ci		.mac_type = ATH12K_HAL_SRNG_UMAC,
5762306a36Sopenharmony_ci		.ring_dir = HAL_SRNG_DIR_DST,
5862306a36Sopenharmony_ci		.max_size = HAL_REO_STATUS_RING_BASE_MSB_RING_SIZE,
5962306a36Sopenharmony_ci	},
6062306a36Sopenharmony_ci	[HAL_TCL_DATA] = {
6162306a36Sopenharmony_ci		.start_ring_id = HAL_SRNG_RING_ID_SW2TCL1,
6262306a36Sopenharmony_ci		.max_rings = 6,
6362306a36Sopenharmony_ci		.entry_size = sizeof(struct hal_tcl_data_cmd) >> 2,
6462306a36Sopenharmony_ci		.mac_type = ATH12K_HAL_SRNG_UMAC,
6562306a36Sopenharmony_ci		.ring_dir = HAL_SRNG_DIR_SRC,
6662306a36Sopenharmony_ci		.max_size = HAL_SW2TCL1_RING_BASE_MSB_RING_SIZE,
6762306a36Sopenharmony_ci	},
6862306a36Sopenharmony_ci	[HAL_TCL_CMD] = {
6962306a36Sopenharmony_ci		.start_ring_id = HAL_SRNG_RING_ID_SW2TCL_CMD,
7062306a36Sopenharmony_ci		.max_rings = 1,
7162306a36Sopenharmony_ci		.entry_size = sizeof(struct hal_tcl_gse_cmd) >> 2,
7262306a36Sopenharmony_ci		.mac_type = ATH12K_HAL_SRNG_UMAC,
7362306a36Sopenharmony_ci		.ring_dir = HAL_SRNG_DIR_SRC,
7462306a36Sopenharmony_ci		.max_size = HAL_SW2TCL1_CMD_RING_BASE_MSB_RING_SIZE,
7562306a36Sopenharmony_ci	},
7662306a36Sopenharmony_ci	[HAL_TCL_STATUS] = {
7762306a36Sopenharmony_ci		.start_ring_id = HAL_SRNG_RING_ID_TCL_STATUS,
7862306a36Sopenharmony_ci		.max_rings = 1,
7962306a36Sopenharmony_ci		.entry_size = (sizeof(struct hal_tlv_hdr) +
8062306a36Sopenharmony_ci			     sizeof(struct hal_tcl_status_ring)) >> 2,
8162306a36Sopenharmony_ci		.mac_type = ATH12K_HAL_SRNG_UMAC,
8262306a36Sopenharmony_ci		.ring_dir = HAL_SRNG_DIR_DST,
8362306a36Sopenharmony_ci		.max_size = HAL_TCL_STATUS_RING_BASE_MSB_RING_SIZE,
8462306a36Sopenharmony_ci	},
8562306a36Sopenharmony_ci	[HAL_CE_SRC] = {
8662306a36Sopenharmony_ci		.start_ring_id = HAL_SRNG_RING_ID_CE0_SRC,
8762306a36Sopenharmony_ci		.max_rings = 16,
8862306a36Sopenharmony_ci		.entry_size = sizeof(struct hal_ce_srng_src_desc) >> 2,
8962306a36Sopenharmony_ci		.mac_type = ATH12K_HAL_SRNG_UMAC,
9062306a36Sopenharmony_ci		.ring_dir = HAL_SRNG_DIR_SRC,
9162306a36Sopenharmony_ci		.max_size = HAL_CE_SRC_RING_BASE_MSB_RING_SIZE,
9262306a36Sopenharmony_ci	},
9362306a36Sopenharmony_ci	[HAL_CE_DST] = {
9462306a36Sopenharmony_ci		.start_ring_id = HAL_SRNG_RING_ID_CE0_DST,
9562306a36Sopenharmony_ci		.max_rings = 16,
9662306a36Sopenharmony_ci		.entry_size = sizeof(struct hal_ce_srng_dest_desc) >> 2,
9762306a36Sopenharmony_ci		.mac_type = ATH12K_HAL_SRNG_UMAC,
9862306a36Sopenharmony_ci		.ring_dir = HAL_SRNG_DIR_SRC,
9962306a36Sopenharmony_ci		.max_size = HAL_CE_DST_RING_BASE_MSB_RING_SIZE,
10062306a36Sopenharmony_ci	},
10162306a36Sopenharmony_ci	[HAL_CE_DST_STATUS] = {
10262306a36Sopenharmony_ci		.start_ring_id = HAL_SRNG_RING_ID_CE0_DST_STATUS,
10362306a36Sopenharmony_ci		.max_rings = 16,
10462306a36Sopenharmony_ci		.entry_size = sizeof(struct hal_ce_srng_dst_status_desc) >> 2,
10562306a36Sopenharmony_ci		.mac_type = ATH12K_HAL_SRNG_UMAC,
10662306a36Sopenharmony_ci		.ring_dir = HAL_SRNG_DIR_DST,
10762306a36Sopenharmony_ci		.max_size = HAL_CE_DST_STATUS_RING_BASE_MSB_RING_SIZE,
10862306a36Sopenharmony_ci	},
10962306a36Sopenharmony_ci	[HAL_WBM_IDLE_LINK] = {
11062306a36Sopenharmony_ci		.start_ring_id = HAL_SRNG_RING_ID_WBM_IDLE_LINK,
11162306a36Sopenharmony_ci		.max_rings = 1,
11262306a36Sopenharmony_ci		.entry_size = sizeof(struct hal_wbm_link_desc) >> 2,
11362306a36Sopenharmony_ci		.mac_type = ATH12K_HAL_SRNG_UMAC,
11462306a36Sopenharmony_ci		.ring_dir = HAL_SRNG_DIR_SRC,
11562306a36Sopenharmony_ci		.max_size = HAL_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE,
11662306a36Sopenharmony_ci	},
11762306a36Sopenharmony_ci	[HAL_SW2WBM_RELEASE] = {
11862306a36Sopenharmony_ci		.start_ring_id = HAL_SRNG_RING_ID_WBM_SW0_RELEASE,
11962306a36Sopenharmony_ci		.max_rings = 2,
12062306a36Sopenharmony_ci		.entry_size = sizeof(struct hal_wbm_release_ring) >> 2,
12162306a36Sopenharmony_ci		.mac_type = ATH12K_HAL_SRNG_UMAC,
12262306a36Sopenharmony_ci		.ring_dir = HAL_SRNG_DIR_SRC,
12362306a36Sopenharmony_ci		.max_size = HAL_SW2WBM_RELEASE_RING_BASE_MSB_RING_SIZE,
12462306a36Sopenharmony_ci	},
12562306a36Sopenharmony_ci	[HAL_WBM2SW_RELEASE] = {
12662306a36Sopenharmony_ci		.start_ring_id = HAL_SRNG_RING_ID_WBM2SW0_RELEASE,
12762306a36Sopenharmony_ci		.max_rings = 8,
12862306a36Sopenharmony_ci		.entry_size = sizeof(struct hal_wbm_release_ring) >> 2,
12962306a36Sopenharmony_ci		.mac_type = ATH12K_HAL_SRNG_UMAC,
13062306a36Sopenharmony_ci		.ring_dir = HAL_SRNG_DIR_DST,
13162306a36Sopenharmony_ci		.max_size = HAL_WBM2SW_RELEASE_RING_BASE_MSB_RING_SIZE,
13262306a36Sopenharmony_ci	},
13362306a36Sopenharmony_ci	[HAL_RXDMA_BUF] = {
13462306a36Sopenharmony_ci		.start_ring_id = HAL_SRNG_SW2RXDMA_BUF0,
13562306a36Sopenharmony_ci		.max_rings = 1,
13662306a36Sopenharmony_ci		.entry_size = sizeof(struct hal_wbm_buffer_ring) >> 2,
13762306a36Sopenharmony_ci		.mac_type = ATH12K_HAL_SRNG_DMAC,
13862306a36Sopenharmony_ci		.ring_dir = HAL_SRNG_DIR_SRC,
13962306a36Sopenharmony_ci		.max_size = HAL_RXDMA_RING_MAX_SIZE_BE,
14062306a36Sopenharmony_ci	},
14162306a36Sopenharmony_ci	[HAL_RXDMA_DST] = {
14262306a36Sopenharmony_ci		.start_ring_id = HAL_SRNG_RING_ID_WMAC1_RXDMA2SW0,
14362306a36Sopenharmony_ci		.max_rings = 0,
14462306a36Sopenharmony_ci		.entry_size = 0,
14562306a36Sopenharmony_ci		.mac_type = ATH12K_HAL_SRNG_PMAC,
14662306a36Sopenharmony_ci		.ring_dir = HAL_SRNG_DIR_DST,
14762306a36Sopenharmony_ci		.max_size = HAL_RXDMA_RING_MAX_SIZE_BE,
14862306a36Sopenharmony_ci	},
14962306a36Sopenharmony_ci	[HAL_RXDMA_MONITOR_BUF] = {
15062306a36Sopenharmony_ci		.start_ring_id = HAL_SRNG_SW2RXMON_BUF0,
15162306a36Sopenharmony_ci		.max_rings = 1,
15262306a36Sopenharmony_ci		.entry_size = sizeof(struct hal_mon_buf_ring) >> 2,
15362306a36Sopenharmony_ci		.mac_type = ATH12K_HAL_SRNG_PMAC,
15462306a36Sopenharmony_ci		.ring_dir = HAL_SRNG_DIR_SRC,
15562306a36Sopenharmony_ci		.max_size = HAL_RXDMA_RING_MAX_SIZE_BE,
15662306a36Sopenharmony_ci	},
15762306a36Sopenharmony_ci	[HAL_RXDMA_MONITOR_STATUS] = { 0, },
15862306a36Sopenharmony_ci	[HAL_RXDMA_MONITOR_DESC] = { 0, },
15962306a36Sopenharmony_ci	[HAL_RXDMA_DIR_BUF] = {
16062306a36Sopenharmony_ci		.start_ring_id = HAL_SRNG_RING_ID_RXDMA_DIR_BUF,
16162306a36Sopenharmony_ci		.max_rings = 2,
16262306a36Sopenharmony_ci		.entry_size = 8 >> 2, /* TODO: Define the struct */
16362306a36Sopenharmony_ci		.mac_type = ATH12K_HAL_SRNG_PMAC,
16462306a36Sopenharmony_ci		.ring_dir = HAL_SRNG_DIR_SRC,
16562306a36Sopenharmony_ci		.max_size = HAL_RXDMA_RING_MAX_SIZE_BE,
16662306a36Sopenharmony_ci	},
16762306a36Sopenharmony_ci	[HAL_PPE2TCL] = {
16862306a36Sopenharmony_ci		.start_ring_id = HAL_SRNG_RING_ID_PPE2TCL1,
16962306a36Sopenharmony_ci		.max_rings = 1,
17062306a36Sopenharmony_ci		.entry_size = sizeof(struct hal_tcl_entrance_from_ppe_ring) >> 2,
17162306a36Sopenharmony_ci		.mac_type = ATH12K_HAL_SRNG_PMAC,
17262306a36Sopenharmony_ci		.ring_dir = HAL_SRNG_DIR_SRC,
17362306a36Sopenharmony_ci		.max_size = HAL_SW2TCL1_RING_BASE_MSB_RING_SIZE,
17462306a36Sopenharmony_ci	},
17562306a36Sopenharmony_ci	[HAL_PPE_RELEASE] = {
17662306a36Sopenharmony_ci		.start_ring_id = HAL_SRNG_RING_ID_WBM_PPE_RELEASE,
17762306a36Sopenharmony_ci		.max_rings = 1,
17862306a36Sopenharmony_ci		.entry_size = sizeof(struct hal_wbm_release_ring) >> 2,
17962306a36Sopenharmony_ci		.mac_type = ATH12K_HAL_SRNG_PMAC,
18062306a36Sopenharmony_ci		.ring_dir = HAL_SRNG_DIR_SRC,
18162306a36Sopenharmony_ci		.max_size = HAL_WBM2PPE_RELEASE_RING_BASE_MSB_RING_SIZE,
18262306a36Sopenharmony_ci	},
18362306a36Sopenharmony_ci	[HAL_TX_MONITOR_BUF] = {
18462306a36Sopenharmony_ci		.start_ring_id = HAL_SRNG_SW2TXMON_BUF0,
18562306a36Sopenharmony_ci		.max_rings = 1,
18662306a36Sopenharmony_ci		.entry_size = sizeof(struct hal_mon_buf_ring) >> 2,
18762306a36Sopenharmony_ci		.mac_type = ATH12K_HAL_SRNG_PMAC,
18862306a36Sopenharmony_ci		.ring_dir = HAL_SRNG_DIR_SRC,
18962306a36Sopenharmony_ci		.max_size = HAL_RXDMA_RING_MAX_SIZE_BE,
19062306a36Sopenharmony_ci	},
19162306a36Sopenharmony_ci	[HAL_RXDMA_MONITOR_DST] = {
19262306a36Sopenharmony_ci		.start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXMON_BUF0,
19362306a36Sopenharmony_ci		.max_rings = 1,
19462306a36Sopenharmony_ci		.entry_size = sizeof(struct hal_mon_dest_desc) >> 2,
19562306a36Sopenharmony_ci		.mac_type = ATH12K_HAL_SRNG_PMAC,
19662306a36Sopenharmony_ci		.ring_dir = HAL_SRNG_DIR_DST,
19762306a36Sopenharmony_ci		.max_size = HAL_RXDMA_RING_MAX_SIZE_BE,
19862306a36Sopenharmony_ci	},
19962306a36Sopenharmony_ci	[HAL_TX_MONITOR_DST] = {
20062306a36Sopenharmony_ci		.start_ring_id = HAL_SRNG_RING_ID_WMAC1_TXMON2SW0_BUF0,
20162306a36Sopenharmony_ci		.max_rings = 1,
20262306a36Sopenharmony_ci		.entry_size = sizeof(struct hal_mon_dest_desc) >> 2,
20362306a36Sopenharmony_ci		.mac_type = ATH12K_HAL_SRNG_PMAC,
20462306a36Sopenharmony_ci		.ring_dir = HAL_SRNG_DIR_DST,
20562306a36Sopenharmony_ci		.max_size = HAL_RXDMA_RING_MAX_SIZE_BE,
20662306a36Sopenharmony_ci	}
20762306a36Sopenharmony_ci};
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_cistatic const struct ath12k_hal_tcl_to_wbm_rbm_map
21062306a36Sopenharmony_ciath12k_hal_qcn9274_tcl_to_wbm_rbm_map[DP_TCL_NUM_RING_MAX] = {
21162306a36Sopenharmony_ci	{
21262306a36Sopenharmony_ci		.wbm_ring_num = 0,
21362306a36Sopenharmony_ci		.rbm_id = HAL_RX_BUF_RBM_SW0_BM,
21462306a36Sopenharmony_ci	},
21562306a36Sopenharmony_ci	{
21662306a36Sopenharmony_ci		.wbm_ring_num = 1,
21762306a36Sopenharmony_ci		.rbm_id = HAL_RX_BUF_RBM_SW1_BM,
21862306a36Sopenharmony_ci	},
21962306a36Sopenharmony_ci	{
22062306a36Sopenharmony_ci		.wbm_ring_num = 2,
22162306a36Sopenharmony_ci		.rbm_id = HAL_RX_BUF_RBM_SW2_BM,
22262306a36Sopenharmony_ci	},
22362306a36Sopenharmony_ci	{
22462306a36Sopenharmony_ci		.wbm_ring_num = 4,
22562306a36Sopenharmony_ci		.rbm_id = HAL_RX_BUF_RBM_SW4_BM,
22662306a36Sopenharmony_ci	}
22762306a36Sopenharmony_ci};
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_cistatic const struct ath12k_hal_tcl_to_wbm_rbm_map
23062306a36Sopenharmony_ciath12k_hal_wcn7850_tcl_to_wbm_rbm_map[DP_TCL_NUM_RING_MAX] = {
23162306a36Sopenharmony_ci	{
23262306a36Sopenharmony_ci		.wbm_ring_num = 0,
23362306a36Sopenharmony_ci		.rbm_id = HAL_RX_BUF_RBM_SW0_BM,
23462306a36Sopenharmony_ci	},
23562306a36Sopenharmony_ci	{
23662306a36Sopenharmony_ci		.wbm_ring_num = 2,
23762306a36Sopenharmony_ci		.rbm_id = HAL_RX_BUF_RBM_SW2_BM,
23862306a36Sopenharmony_ci	},
23962306a36Sopenharmony_ci	{
24062306a36Sopenharmony_ci		.wbm_ring_num = 4,
24162306a36Sopenharmony_ci		.rbm_id = HAL_RX_BUF_RBM_SW4_BM,
24262306a36Sopenharmony_ci	},
24362306a36Sopenharmony_ci};
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_cistatic unsigned int ath12k_hal_reo1_ring_id_offset(struct ath12k_base *ab)
24662306a36Sopenharmony_ci{
24762306a36Sopenharmony_ci	return HAL_REO1_RING_ID(ab) - HAL_REO1_RING_BASE_LSB(ab);
24862306a36Sopenharmony_ci}
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_cistatic unsigned int ath12k_hal_reo1_ring_msi1_base_lsb_offset(struct ath12k_base *ab)
25162306a36Sopenharmony_ci{
25262306a36Sopenharmony_ci	return HAL_REO1_RING_MSI1_BASE_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab);
25362306a36Sopenharmony_ci}
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_cistatic unsigned int ath12k_hal_reo1_ring_msi1_base_msb_offset(struct ath12k_base *ab)
25662306a36Sopenharmony_ci{
25762306a36Sopenharmony_ci	return HAL_REO1_RING_MSI1_BASE_MSB(ab) - HAL_REO1_RING_BASE_LSB(ab);
25862306a36Sopenharmony_ci}
25962306a36Sopenharmony_ci
26062306a36Sopenharmony_cistatic unsigned int ath12k_hal_reo1_ring_msi1_data_offset(struct ath12k_base *ab)
26162306a36Sopenharmony_ci{
26262306a36Sopenharmony_ci	return HAL_REO1_RING_MSI1_DATA(ab) - HAL_REO1_RING_BASE_LSB(ab);
26362306a36Sopenharmony_ci}
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_cistatic unsigned int ath12k_hal_reo1_ring_base_msb_offset(struct ath12k_base *ab)
26662306a36Sopenharmony_ci{
26762306a36Sopenharmony_ci	return HAL_REO1_RING_BASE_MSB(ab) - HAL_REO1_RING_BASE_LSB(ab);
26862306a36Sopenharmony_ci}
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_cistatic unsigned int ath12k_hal_reo1_ring_producer_int_setup_offset(struct ath12k_base *ab)
27162306a36Sopenharmony_ci{
27262306a36Sopenharmony_ci	return HAL_REO1_RING_PRODUCER_INT_SETUP(ab) - HAL_REO1_RING_BASE_LSB(ab);
27362306a36Sopenharmony_ci}
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_cistatic unsigned int ath12k_hal_reo1_ring_hp_addr_lsb_offset(struct ath12k_base *ab)
27662306a36Sopenharmony_ci{
27762306a36Sopenharmony_ci	return HAL_REO1_RING_HP_ADDR_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab);
27862306a36Sopenharmony_ci}
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_cistatic unsigned int ath12k_hal_reo1_ring_hp_addr_msb_offset(struct ath12k_base *ab)
28162306a36Sopenharmony_ci{
28262306a36Sopenharmony_ci	return HAL_REO1_RING_HP_ADDR_MSB(ab) - HAL_REO1_RING_BASE_LSB(ab);
28362306a36Sopenharmony_ci}
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_cistatic unsigned int ath12k_hal_reo1_ring_misc_offset(struct ath12k_base *ab)
28662306a36Sopenharmony_ci{
28762306a36Sopenharmony_ci	return HAL_REO1_RING_MISC(ab) - HAL_REO1_RING_BASE_LSB(ab);
28862306a36Sopenharmony_ci}
28962306a36Sopenharmony_ci
29062306a36Sopenharmony_cistatic bool ath12k_hw_qcn9274_rx_desc_get_first_msdu(struct hal_rx_desc *desc)
29162306a36Sopenharmony_ci{
29262306a36Sopenharmony_ci	return !!le16_get_bits(desc->u.qcn9274.msdu_end.info5,
29362306a36Sopenharmony_ci			       RX_MSDU_END_INFO5_FIRST_MSDU);
29462306a36Sopenharmony_ci}
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_cistatic bool ath12k_hw_qcn9274_rx_desc_get_last_msdu(struct hal_rx_desc *desc)
29762306a36Sopenharmony_ci{
29862306a36Sopenharmony_ci	return !!le16_get_bits(desc->u.qcn9274.msdu_end.info5,
29962306a36Sopenharmony_ci			       RX_MSDU_END_INFO5_LAST_MSDU);
30062306a36Sopenharmony_ci}
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_cistatic u8 ath12k_hw_qcn9274_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc)
30362306a36Sopenharmony_ci{
30462306a36Sopenharmony_ci	return le16_get_bits(desc->u.qcn9274.msdu_end.info5,
30562306a36Sopenharmony_ci			     RX_MSDU_END_INFO5_L3_HDR_PADDING);
30662306a36Sopenharmony_ci}
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_cistatic bool ath12k_hw_qcn9274_rx_desc_encrypt_valid(struct hal_rx_desc *desc)
30962306a36Sopenharmony_ci{
31062306a36Sopenharmony_ci	return !!le32_get_bits(desc->u.qcn9274.mpdu_start.info4,
31162306a36Sopenharmony_ci			       RX_MPDU_START_INFO4_ENCRYPT_INFO_VALID);
31262306a36Sopenharmony_ci}
31362306a36Sopenharmony_ci
31462306a36Sopenharmony_cistatic u32 ath12k_hw_qcn9274_rx_desc_get_encrypt_type(struct hal_rx_desc *desc)
31562306a36Sopenharmony_ci{
31662306a36Sopenharmony_ci	return le32_get_bits(desc->u.qcn9274.mpdu_start.info2,
31762306a36Sopenharmony_ci			     RX_MPDU_START_INFO2_ENC_TYPE);
31862306a36Sopenharmony_ci}
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_cistatic u8 ath12k_hw_qcn9274_rx_desc_get_decap_type(struct hal_rx_desc *desc)
32162306a36Sopenharmony_ci{
32262306a36Sopenharmony_ci	return le32_get_bits(desc->u.qcn9274.msdu_end.info11,
32362306a36Sopenharmony_ci			     RX_MSDU_END_INFO11_DECAP_FORMAT);
32462306a36Sopenharmony_ci}
32562306a36Sopenharmony_ci
32662306a36Sopenharmony_cistatic u8 ath12k_hw_qcn9274_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc)
32762306a36Sopenharmony_ci{
32862306a36Sopenharmony_ci	return le32_get_bits(desc->u.qcn9274.msdu_end.info11,
32962306a36Sopenharmony_ci			     RX_MSDU_END_INFO11_MESH_CTRL_PRESENT);
33062306a36Sopenharmony_ci}
33162306a36Sopenharmony_ci
33262306a36Sopenharmony_cistatic bool ath12k_hw_qcn9274_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc)
33362306a36Sopenharmony_ci{
33462306a36Sopenharmony_ci	return !!le32_get_bits(desc->u.qcn9274.mpdu_start.info4,
33562306a36Sopenharmony_ci			       RX_MPDU_START_INFO4_MPDU_SEQ_CTRL_VALID);
33662306a36Sopenharmony_ci}
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_cistatic bool ath12k_hw_qcn9274_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc)
33962306a36Sopenharmony_ci{
34062306a36Sopenharmony_ci	return !!le32_get_bits(desc->u.qcn9274.mpdu_start.info4,
34162306a36Sopenharmony_ci			       RX_MPDU_START_INFO4_MPDU_FCTRL_VALID);
34262306a36Sopenharmony_ci}
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_cistatic u16 ath12k_hw_qcn9274_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc)
34562306a36Sopenharmony_ci{
34662306a36Sopenharmony_ci	return le32_get_bits(desc->u.qcn9274.mpdu_start.info4,
34762306a36Sopenharmony_ci			     RX_MPDU_START_INFO4_MPDU_SEQ_NUM);
34862306a36Sopenharmony_ci}
34962306a36Sopenharmony_ci
35062306a36Sopenharmony_cistatic u16 ath12k_hw_qcn9274_rx_desc_get_msdu_len(struct hal_rx_desc *desc)
35162306a36Sopenharmony_ci{
35262306a36Sopenharmony_ci	return le32_get_bits(desc->u.qcn9274.msdu_end.info10,
35362306a36Sopenharmony_ci			     RX_MSDU_END_INFO10_MSDU_LENGTH);
35462306a36Sopenharmony_ci}
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_cistatic u8 ath12k_hw_qcn9274_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc)
35762306a36Sopenharmony_ci{
35862306a36Sopenharmony_ci	return le32_get_bits(desc->u.qcn9274.msdu_end.info12,
35962306a36Sopenharmony_ci			     RX_MSDU_END_INFO12_SGI);
36062306a36Sopenharmony_ci}
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_cistatic u8 ath12k_hw_qcn9274_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc)
36362306a36Sopenharmony_ci{
36462306a36Sopenharmony_ci	return le32_get_bits(desc->u.qcn9274.msdu_end.info12,
36562306a36Sopenharmony_ci			     RX_MSDU_END_INFO12_RATE_MCS);
36662306a36Sopenharmony_ci}
36762306a36Sopenharmony_ci
36862306a36Sopenharmony_cistatic u8 ath12k_hw_qcn9274_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc)
36962306a36Sopenharmony_ci{
37062306a36Sopenharmony_ci	return le32_get_bits(desc->u.qcn9274.msdu_end.info12,
37162306a36Sopenharmony_ci			     RX_MSDU_END_INFO12_RECV_BW);
37262306a36Sopenharmony_ci}
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_cistatic u32 ath12k_hw_qcn9274_rx_desc_get_msdu_freq(struct hal_rx_desc *desc)
37562306a36Sopenharmony_ci{
37662306a36Sopenharmony_ci	return __le32_to_cpu(desc->u.qcn9274.msdu_end.phy_meta_data);
37762306a36Sopenharmony_ci}
37862306a36Sopenharmony_ci
37962306a36Sopenharmony_cistatic u8 ath12k_hw_qcn9274_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc)
38062306a36Sopenharmony_ci{
38162306a36Sopenharmony_ci	return le32_get_bits(desc->u.qcn9274.msdu_end.info12,
38262306a36Sopenharmony_ci			     RX_MSDU_END_INFO12_PKT_TYPE);
38362306a36Sopenharmony_ci}
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_cistatic u8 ath12k_hw_qcn9274_rx_desc_get_msdu_nss(struct hal_rx_desc *desc)
38662306a36Sopenharmony_ci{
38762306a36Sopenharmony_ci	return le32_get_bits(desc->u.qcn9274.msdu_end.info12,
38862306a36Sopenharmony_ci			     RX_MSDU_END_INFO12_MIMO_SS_BITMAP);
38962306a36Sopenharmony_ci}
39062306a36Sopenharmony_ci
39162306a36Sopenharmony_cistatic u8 ath12k_hw_qcn9274_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc)
39262306a36Sopenharmony_ci{
39362306a36Sopenharmony_ci	return le16_get_bits(desc->u.qcn9274.msdu_end.info5,
39462306a36Sopenharmony_ci			    RX_MSDU_END_INFO5_TID);
39562306a36Sopenharmony_ci}
39662306a36Sopenharmony_ci
39762306a36Sopenharmony_cistatic u16 ath12k_hw_qcn9274_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc)
39862306a36Sopenharmony_ci{
39962306a36Sopenharmony_ci	return __le16_to_cpu(desc->u.qcn9274.mpdu_start.sw_peer_id);
40062306a36Sopenharmony_ci}
40162306a36Sopenharmony_ci
40262306a36Sopenharmony_cistatic void ath12k_hw_qcn9274_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc,
40362306a36Sopenharmony_ci						   struct hal_rx_desc *ldesc)
40462306a36Sopenharmony_ci{
40562306a36Sopenharmony_ci	memcpy(&fdesc->u.qcn9274.msdu_end, &ldesc->u.qcn9274.msdu_end,
40662306a36Sopenharmony_ci	       sizeof(struct rx_msdu_end_qcn9274));
40762306a36Sopenharmony_ci}
40862306a36Sopenharmony_ci
40962306a36Sopenharmony_cistatic u32 ath12k_hw_qcn9274_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc)
41062306a36Sopenharmony_ci{
41162306a36Sopenharmony_ci	return __le16_to_cpu(desc->u.qcn9274.mpdu_start.phy_ppdu_id);
41262306a36Sopenharmony_ci}
41362306a36Sopenharmony_ci
41462306a36Sopenharmony_cistatic void ath12k_hw_qcn9274_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len)
41562306a36Sopenharmony_ci{
41662306a36Sopenharmony_ci	u32 info = __le32_to_cpu(desc->u.qcn9274.msdu_end.info10);
41762306a36Sopenharmony_ci
41862306a36Sopenharmony_ci	info &= ~RX_MSDU_END_INFO10_MSDU_LENGTH;
41962306a36Sopenharmony_ci	info |= u32_encode_bits(len, RX_MSDU_END_INFO10_MSDU_LENGTH);
42062306a36Sopenharmony_ci
42162306a36Sopenharmony_ci	desc->u.qcn9274.msdu_end.info10 = __cpu_to_le32(info);
42262306a36Sopenharmony_ci}
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_cistatic u8 *ath12k_hw_qcn9274_rx_desc_get_msdu_payload(struct hal_rx_desc *desc)
42562306a36Sopenharmony_ci{
42662306a36Sopenharmony_ci	return &desc->u.qcn9274.msdu_payload[0];
42762306a36Sopenharmony_ci}
42862306a36Sopenharmony_ci
42962306a36Sopenharmony_cistatic u32 ath12k_hw_qcn9274_rx_desc_get_mpdu_start_offset(void)
43062306a36Sopenharmony_ci{
43162306a36Sopenharmony_ci	return offsetof(struct hal_rx_desc_qcn9274, mpdu_start);
43262306a36Sopenharmony_ci}
43362306a36Sopenharmony_ci
43462306a36Sopenharmony_cistatic u32 ath12k_hw_qcn9274_rx_desc_get_msdu_end_offset(void)
43562306a36Sopenharmony_ci{
43662306a36Sopenharmony_ci	return offsetof(struct hal_rx_desc_qcn9274, msdu_end);
43762306a36Sopenharmony_ci}
43862306a36Sopenharmony_ci
43962306a36Sopenharmony_cistatic bool ath12k_hw_qcn9274_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc)
44062306a36Sopenharmony_ci{
44162306a36Sopenharmony_ci	return __le32_to_cpu(desc->u.qcn9274.mpdu_start.info4) &
44262306a36Sopenharmony_ci	       RX_MPDU_START_INFO4_MAC_ADDR2_VALID;
44362306a36Sopenharmony_ci}
44462306a36Sopenharmony_ci
44562306a36Sopenharmony_cistatic u8 *ath12k_hw_qcn9274_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc)
44662306a36Sopenharmony_ci{
44762306a36Sopenharmony_ci	return desc->u.qcn9274.mpdu_start.addr2;
44862306a36Sopenharmony_ci}
44962306a36Sopenharmony_ci
45062306a36Sopenharmony_cistatic bool ath12k_hw_qcn9274_rx_desc_is_da_mcbc(struct hal_rx_desc *desc)
45162306a36Sopenharmony_ci{
45262306a36Sopenharmony_ci	return __le32_to_cpu(desc->u.qcn9274.mpdu_start.info6) &
45362306a36Sopenharmony_ci	       RX_MPDU_START_INFO6_MCAST_BCAST;
45462306a36Sopenharmony_ci}
45562306a36Sopenharmony_ci
45662306a36Sopenharmony_cistatic void ath12k_hw_qcn9274_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc,
45762306a36Sopenharmony_ci						    struct ieee80211_hdr *hdr)
45862306a36Sopenharmony_ci{
45962306a36Sopenharmony_ci	hdr->frame_control = desc->u.qcn9274.mpdu_start.frame_ctrl;
46062306a36Sopenharmony_ci	hdr->duration_id = desc->u.qcn9274.mpdu_start.duration;
46162306a36Sopenharmony_ci	ether_addr_copy(hdr->addr1, desc->u.qcn9274.mpdu_start.addr1);
46262306a36Sopenharmony_ci	ether_addr_copy(hdr->addr2, desc->u.qcn9274.mpdu_start.addr2);
46362306a36Sopenharmony_ci	ether_addr_copy(hdr->addr3, desc->u.qcn9274.mpdu_start.addr3);
46462306a36Sopenharmony_ci	if (__le32_to_cpu(desc->u.qcn9274.mpdu_start.info4) &
46562306a36Sopenharmony_ci			RX_MPDU_START_INFO4_MAC_ADDR4_VALID) {
46662306a36Sopenharmony_ci		ether_addr_copy(hdr->addr4, desc->u.qcn9274.mpdu_start.addr4);
46762306a36Sopenharmony_ci	}
46862306a36Sopenharmony_ci	hdr->seq_ctrl = desc->u.qcn9274.mpdu_start.seq_ctrl;
46962306a36Sopenharmony_ci}
47062306a36Sopenharmony_ci
47162306a36Sopenharmony_cistatic void ath12k_hw_qcn9274_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc,
47262306a36Sopenharmony_ci						     u8 *crypto_hdr,
47362306a36Sopenharmony_ci						     enum hal_encrypt_type enctype)
47462306a36Sopenharmony_ci{
47562306a36Sopenharmony_ci	unsigned int key_id;
47662306a36Sopenharmony_ci
47762306a36Sopenharmony_ci	switch (enctype) {
47862306a36Sopenharmony_ci	case HAL_ENCRYPT_TYPE_OPEN:
47962306a36Sopenharmony_ci		return;
48062306a36Sopenharmony_ci	case HAL_ENCRYPT_TYPE_TKIP_NO_MIC:
48162306a36Sopenharmony_ci	case HAL_ENCRYPT_TYPE_TKIP_MIC:
48262306a36Sopenharmony_ci		crypto_hdr[0] =
48362306a36Sopenharmony_ci			HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274.mpdu_start.pn[0]);
48462306a36Sopenharmony_ci		crypto_hdr[1] = 0;
48562306a36Sopenharmony_ci		crypto_hdr[2] =
48662306a36Sopenharmony_ci			HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274.mpdu_start.pn[0]);
48762306a36Sopenharmony_ci		break;
48862306a36Sopenharmony_ci	case HAL_ENCRYPT_TYPE_CCMP_128:
48962306a36Sopenharmony_ci	case HAL_ENCRYPT_TYPE_CCMP_256:
49062306a36Sopenharmony_ci	case HAL_ENCRYPT_TYPE_GCMP_128:
49162306a36Sopenharmony_ci	case HAL_ENCRYPT_TYPE_AES_GCMP_256:
49262306a36Sopenharmony_ci		crypto_hdr[0] =
49362306a36Sopenharmony_ci			HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274.mpdu_start.pn[0]);
49462306a36Sopenharmony_ci		crypto_hdr[1] =
49562306a36Sopenharmony_ci			HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274.mpdu_start.pn[0]);
49662306a36Sopenharmony_ci		crypto_hdr[2] = 0;
49762306a36Sopenharmony_ci		break;
49862306a36Sopenharmony_ci	case HAL_ENCRYPT_TYPE_WEP_40:
49962306a36Sopenharmony_ci	case HAL_ENCRYPT_TYPE_WEP_104:
50062306a36Sopenharmony_ci	case HAL_ENCRYPT_TYPE_WEP_128:
50162306a36Sopenharmony_ci	case HAL_ENCRYPT_TYPE_WAPI_GCM_SM4:
50262306a36Sopenharmony_ci	case HAL_ENCRYPT_TYPE_WAPI:
50362306a36Sopenharmony_ci		return;
50462306a36Sopenharmony_ci	}
50562306a36Sopenharmony_ci	key_id = le32_get_bits(desc->u.qcn9274.mpdu_start.info5,
50662306a36Sopenharmony_ci			       RX_MPDU_START_INFO5_KEY_ID);
50762306a36Sopenharmony_ci	crypto_hdr[3] = 0x20 | (key_id << 6);
50862306a36Sopenharmony_ci	crypto_hdr[4] = HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.qcn9274.mpdu_start.pn[0]);
50962306a36Sopenharmony_ci	crypto_hdr[5] = HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.qcn9274.mpdu_start.pn[0]);
51062306a36Sopenharmony_ci	crypto_hdr[6] = HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274.mpdu_start.pn[1]);
51162306a36Sopenharmony_ci	crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274.mpdu_start.pn[1]);
51262306a36Sopenharmony_ci}
51362306a36Sopenharmony_ci
51462306a36Sopenharmony_cistatic u16 ath12k_hw_qcn9274_rx_desc_get_mpdu_frame_ctl(struct hal_rx_desc *desc)
51562306a36Sopenharmony_ci{
51662306a36Sopenharmony_ci	return __le16_to_cpu(desc->u.qcn9274.mpdu_start.frame_ctrl);
51762306a36Sopenharmony_ci}
51862306a36Sopenharmony_ci
51962306a36Sopenharmony_cistatic int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab)
52062306a36Sopenharmony_ci{
52162306a36Sopenharmony_ci	struct ath12k_hal *hal = &ab->hal;
52262306a36Sopenharmony_ci	struct hal_srng_config *s;
52362306a36Sopenharmony_ci
52462306a36Sopenharmony_ci	hal->srng_config = kmemdup(hw_srng_config_template,
52562306a36Sopenharmony_ci				   sizeof(hw_srng_config_template),
52662306a36Sopenharmony_ci				   GFP_KERNEL);
52762306a36Sopenharmony_ci	if (!hal->srng_config)
52862306a36Sopenharmony_ci		return -ENOMEM;
52962306a36Sopenharmony_ci
53062306a36Sopenharmony_ci	s = &hal->srng_config[HAL_REO_DST];
53162306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_BASE_LSB(ab);
53262306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_HP;
53362306a36Sopenharmony_ci	s->reg_size[0] = HAL_REO2_RING_BASE_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab);
53462306a36Sopenharmony_ci	s->reg_size[1] = HAL_REO2_RING_HP - HAL_REO1_RING_HP;
53562306a36Sopenharmony_ci
53662306a36Sopenharmony_ci	s = &hal->srng_config[HAL_REO_EXCEPTION];
53762306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_BASE_LSB(ab);
53862306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_HP;
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_ci	s = &hal->srng_config[HAL_REO_REINJECT];
54162306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_BASE_LSB(ab);
54262306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_HP;
54362306a36Sopenharmony_ci	s->reg_size[0] = HAL_SW2REO1_RING_BASE_LSB(ab) - HAL_SW2REO_RING_BASE_LSB(ab);
54462306a36Sopenharmony_ci	s->reg_size[1] = HAL_SW2REO1_RING_HP - HAL_SW2REO_RING_HP;
54562306a36Sopenharmony_ci
54662306a36Sopenharmony_ci	s = &hal->srng_config[HAL_REO_CMD];
54762306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_RING_BASE_LSB(ab);
54862306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_HP;
54962306a36Sopenharmony_ci
55062306a36Sopenharmony_ci	s = &hal->srng_config[HAL_REO_STATUS];
55162306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_RING_BASE_LSB(ab);
55262306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_HP;
55362306a36Sopenharmony_ci
55462306a36Sopenharmony_ci	s = &hal->srng_config[HAL_TCL_DATA];
55562306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_BASE_LSB;
55662306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_HP;
55762306a36Sopenharmony_ci	s->reg_size[0] = HAL_TCL2_RING_BASE_LSB - HAL_TCL1_RING_BASE_LSB;
55862306a36Sopenharmony_ci	s->reg_size[1] = HAL_TCL2_RING_HP - HAL_TCL1_RING_HP;
55962306a36Sopenharmony_ci
56062306a36Sopenharmony_ci	s = &hal->srng_config[HAL_TCL_CMD];
56162306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_BASE_LSB(ab);
56262306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_HP;
56362306a36Sopenharmony_ci
56462306a36Sopenharmony_ci	s = &hal->srng_config[HAL_TCL_STATUS];
56562306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_BASE_LSB(ab);
56662306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP;
56762306a36Sopenharmony_ci
56862306a36Sopenharmony_ci	s = &hal->srng_config[HAL_CE_SRC];
56962306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG + HAL_CE_DST_RING_BASE_LSB;
57062306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG + HAL_CE_DST_RING_HP;
57162306a36Sopenharmony_ci	s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG -
57262306a36Sopenharmony_ci		HAL_SEQ_WCSS_UMAC_CE0_SRC_REG;
57362306a36Sopenharmony_ci	s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG -
57462306a36Sopenharmony_ci		HAL_SEQ_WCSS_UMAC_CE0_SRC_REG;
57562306a36Sopenharmony_ci
57662306a36Sopenharmony_ci	s = &hal->srng_config[HAL_CE_DST];
57762306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG + HAL_CE_DST_RING_BASE_LSB;
57862306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG + HAL_CE_DST_RING_HP;
57962306a36Sopenharmony_ci	s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG -
58062306a36Sopenharmony_ci		HAL_SEQ_WCSS_UMAC_CE0_DST_REG;
58162306a36Sopenharmony_ci	s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG -
58262306a36Sopenharmony_ci		HAL_SEQ_WCSS_UMAC_CE0_DST_REG;
58362306a36Sopenharmony_ci
58462306a36Sopenharmony_ci	s = &hal->srng_config[HAL_CE_DST_STATUS];
58562306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG +
58662306a36Sopenharmony_ci		HAL_CE_DST_STATUS_RING_BASE_LSB;
58762306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG + HAL_CE_DST_STATUS_RING_HP;
58862306a36Sopenharmony_ci	s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG -
58962306a36Sopenharmony_ci		HAL_SEQ_WCSS_UMAC_CE0_DST_REG;
59062306a36Sopenharmony_ci	s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG -
59162306a36Sopenharmony_ci		HAL_SEQ_WCSS_UMAC_CE0_DST_REG;
59262306a36Sopenharmony_ci
59362306a36Sopenharmony_ci	s = &hal->srng_config[HAL_WBM_IDLE_LINK];
59462306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_BASE_LSB(ab);
59562306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_HP;
59662306a36Sopenharmony_ci
59762306a36Sopenharmony_ci	s = &hal->srng_config[HAL_SW2WBM_RELEASE];
59862306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG +
59962306a36Sopenharmony_ci		HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab);
60062306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SW_RELEASE_RING_HP;
60162306a36Sopenharmony_ci	s->reg_size[0] = HAL_WBM_SW1_RELEASE_RING_BASE_LSB(ab) -
60262306a36Sopenharmony_ci			 HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab);
60362306a36Sopenharmony_ci	s->reg_size[1] = HAL_WBM_SW1_RELEASE_RING_HP - HAL_WBM_SW_RELEASE_RING_HP;
60462306a36Sopenharmony_ci
60562306a36Sopenharmony_ci	s = &hal->srng_config[HAL_WBM2SW_RELEASE];
60662306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_BASE_LSB(ab);
60762306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_HP;
60862306a36Sopenharmony_ci	s->reg_size[0] = HAL_WBM1_RELEASE_RING_BASE_LSB(ab) -
60962306a36Sopenharmony_ci		HAL_WBM0_RELEASE_RING_BASE_LSB(ab);
61062306a36Sopenharmony_ci	s->reg_size[1] = HAL_WBM1_RELEASE_RING_HP - HAL_WBM0_RELEASE_RING_HP;
61162306a36Sopenharmony_ci
61262306a36Sopenharmony_ci	/* Some LMAC rings are not accessed from the host:
61362306a36Sopenharmony_ci	 * RXDMA_BUG, RXDMA_DST, RXDMA_MONITOR_BUF, RXDMA_MONITOR_STATUS,
61462306a36Sopenharmony_ci	 * RXDMA_MONITOR_DST, RXDMA_MONITOR_DESC, RXDMA_DIR_BUF_SRC,
61562306a36Sopenharmony_ci	 * RXDMA_RX_MONITOR_BUF, TX_MONITOR_BUF, TX_MONITOR_DST, SW2RXDMA
61662306a36Sopenharmony_ci	 */
61762306a36Sopenharmony_ci	s = &hal->srng_config[HAL_PPE2TCL];
61862306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_PPE2TCL1_RING_BASE_LSB;
61962306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_PPE2TCL1_RING_HP;
62062306a36Sopenharmony_ci
62162306a36Sopenharmony_ci	s = &hal->srng_config[HAL_PPE_RELEASE];
62262306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG +
62362306a36Sopenharmony_ci				HAL_WBM_PPE_RELEASE_RING_BASE_LSB(ab);
62462306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_PPE_RELEASE_RING_HP;
62562306a36Sopenharmony_ci
62662306a36Sopenharmony_ci	return 0;
62762306a36Sopenharmony_ci}
62862306a36Sopenharmony_ci
62962306a36Sopenharmony_cistatic bool ath12k_hw_qcn9274_dp_rx_h_msdu_done(struct hal_rx_desc *desc)
63062306a36Sopenharmony_ci{
63162306a36Sopenharmony_ci	return !!le32_get_bits(desc->u.qcn9274.msdu_end.info14,
63262306a36Sopenharmony_ci			       RX_MSDU_END_INFO14_MSDU_DONE);
63362306a36Sopenharmony_ci}
63462306a36Sopenharmony_ci
63562306a36Sopenharmony_cistatic bool ath12k_hw_qcn9274_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc)
63662306a36Sopenharmony_ci{
63762306a36Sopenharmony_ci	return !!le32_get_bits(desc->u.qcn9274.msdu_end.info13,
63862306a36Sopenharmony_ci			       RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL);
63962306a36Sopenharmony_ci}
64062306a36Sopenharmony_ci
64162306a36Sopenharmony_cistatic bool ath12k_hw_qcn9274_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc)
64262306a36Sopenharmony_ci{
64362306a36Sopenharmony_ci	return !!le32_get_bits(desc->u.qcn9274.msdu_end.info13,
64462306a36Sopenharmony_ci			       RX_MSDU_END_INFO13_IP_CKSUM_FAIL);
64562306a36Sopenharmony_ci}
64662306a36Sopenharmony_ci
64762306a36Sopenharmony_cistatic bool ath12k_hw_qcn9274_dp_rx_h_is_decrypted(struct hal_rx_desc *desc)
64862306a36Sopenharmony_ci{
64962306a36Sopenharmony_ci	return (le32_get_bits(desc->u.qcn9274.msdu_end.info14,
65062306a36Sopenharmony_ci			      RX_MSDU_END_INFO14_DECRYPT_STATUS_CODE) ==
65162306a36Sopenharmony_ci			      RX_DESC_DECRYPT_STATUS_CODE_OK);
65262306a36Sopenharmony_ci}
65362306a36Sopenharmony_ci
65462306a36Sopenharmony_cistatic u32 ath12k_hw_qcn9274_dp_rx_h_mpdu_err(struct hal_rx_desc *desc)
65562306a36Sopenharmony_ci{
65662306a36Sopenharmony_ci	u32 info = __le32_to_cpu(desc->u.qcn9274.msdu_end.info13);
65762306a36Sopenharmony_ci	u32 errmap = 0;
65862306a36Sopenharmony_ci
65962306a36Sopenharmony_ci	if (info & RX_MSDU_END_INFO13_FCS_ERR)
66062306a36Sopenharmony_ci		errmap |= HAL_RX_MPDU_ERR_FCS;
66162306a36Sopenharmony_ci
66262306a36Sopenharmony_ci	if (info & RX_MSDU_END_INFO13_DECRYPT_ERR)
66362306a36Sopenharmony_ci		errmap |= HAL_RX_MPDU_ERR_DECRYPT;
66462306a36Sopenharmony_ci
66562306a36Sopenharmony_ci	if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR)
66662306a36Sopenharmony_ci		errmap |= HAL_RX_MPDU_ERR_TKIP_MIC;
66762306a36Sopenharmony_ci
66862306a36Sopenharmony_ci	if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR)
66962306a36Sopenharmony_ci		errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR;
67062306a36Sopenharmony_ci
67162306a36Sopenharmony_ci	if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR)
67262306a36Sopenharmony_ci		errmap |= HAL_RX_MPDU_ERR_OVERFLOW;
67362306a36Sopenharmony_ci
67462306a36Sopenharmony_ci	if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR)
67562306a36Sopenharmony_ci		errmap |= HAL_RX_MPDU_ERR_MSDU_LEN;
67662306a36Sopenharmony_ci
67762306a36Sopenharmony_ci	if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR)
67862306a36Sopenharmony_ci		errmap |= HAL_RX_MPDU_ERR_MPDU_LEN;
67962306a36Sopenharmony_ci
68062306a36Sopenharmony_ci	return errmap;
68162306a36Sopenharmony_ci}
68262306a36Sopenharmony_ci
68362306a36Sopenharmony_ciconst struct hal_ops hal_qcn9274_ops = {
68462306a36Sopenharmony_ci	.rx_desc_get_first_msdu = ath12k_hw_qcn9274_rx_desc_get_first_msdu,
68562306a36Sopenharmony_ci	.rx_desc_get_last_msdu = ath12k_hw_qcn9274_rx_desc_get_last_msdu,
68662306a36Sopenharmony_ci	.rx_desc_get_l3_pad_bytes = ath12k_hw_qcn9274_rx_desc_get_l3_pad_bytes,
68762306a36Sopenharmony_ci	.rx_desc_encrypt_valid = ath12k_hw_qcn9274_rx_desc_encrypt_valid,
68862306a36Sopenharmony_ci	.rx_desc_get_encrypt_type = ath12k_hw_qcn9274_rx_desc_get_encrypt_type,
68962306a36Sopenharmony_ci	.rx_desc_get_decap_type = ath12k_hw_qcn9274_rx_desc_get_decap_type,
69062306a36Sopenharmony_ci	.rx_desc_get_mesh_ctl = ath12k_hw_qcn9274_rx_desc_get_mesh_ctl,
69162306a36Sopenharmony_ci	.rx_desc_get_mpdu_seq_ctl_vld = ath12k_hw_qcn9274_rx_desc_get_mpdu_seq_ctl_vld,
69262306a36Sopenharmony_ci	.rx_desc_get_mpdu_fc_valid = ath12k_hw_qcn9274_rx_desc_get_mpdu_fc_valid,
69362306a36Sopenharmony_ci	.rx_desc_get_mpdu_start_seq_no = ath12k_hw_qcn9274_rx_desc_get_mpdu_start_seq_no,
69462306a36Sopenharmony_ci	.rx_desc_get_msdu_len = ath12k_hw_qcn9274_rx_desc_get_msdu_len,
69562306a36Sopenharmony_ci	.rx_desc_get_msdu_sgi = ath12k_hw_qcn9274_rx_desc_get_msdu_sgi,
69662306a36Sopenharmony_ci	.rx_desc_get_msdu_rate_mcs = ath12k_hw_qcn9274_rx_desc_get_msdu_rate_mcs,
69762306a36Sopenharmony_ci	.rx_desc_get_msdu_rx_bw = ath12k_hw_qcn9274_rx_desc_get_msdu_rx_bw,
69862306a36Sopenharmony_ci	.rx_desc_get_msdu_freq = ath12k_hw_qcn9274_rx_desc_get_msdu_freq,
69962306a36Sopenharmony_ci	.rx_desc_get_msdu_pkt_type = ath12k_hw_qcn9274_rx_desc_get_msdu_pkt_type,
70062306a36Sopenharmony_ci	.rx_desc_get_msdu_nss = ath12k_hw_qcn9274_rx_desc_get_msdu_nss,
70162306a36Sopenharmony_ci	.rx_desc_get_mpdu_tid = ath12k_hw_qcn9274_rx_desc_get_mpdu_tid,
70262306a36Sopenharmony_ci	.rx_desc_get_mpdu_peer_id = ath12k_hw_qcn9274_rx_desc_get_mpdu_peer_id,
70362306a36Sopenharmony_ci	.rx_desc_copy_end_tlv = ath12k_hw_qcn9274_rx_desc_copy_end_tlv,
70462306a36Sopenharmony_ci	.rx_desc_get_mpdu_ppdu_id = ath12k_hw_qcn9274_rx_desc_get_mpdu_ppdu_id,
70562306a36Sopenharmony_ci	.rx_desc_set_msdu_len = ath12k_hw_qcn9274_rx_desc_set_msdu_len,
70662306a36Sopenharmony_ci	.rx_desc_get_msdu_payload = ath12k_hw_qcn9274_rx_desc_get_msdu_payload,
70762306a36Sopenharmony_ci	.rx_desc_get_mpdu_start_offset = ath12k_hw_qcn9274_rx_desc_get_mpdu_start_offset,
70862306a36Sopenharmony_ci	.rx_desc_get_msdu_end_offset = ath12k_hw_qcn9274_rx_desc_get_msdu_end_offset,
70962306a36Sopenharmony_ci	.rx_desc_mac_addr2_valid = ath12k_hw_qcn9274_rx_desc_mac_addr2_valid,
71062306a36Sopenharmony_ci	.rx_desc_mpdu_start_addr2 = ath12k_hw_qcn9274_rx_desc_mpdu_start_addr2,
71162306a36Sopenharmony_ci	.rx_desc_is_da_mcbc = ath12k_hw_qcn9274_rx_desc_is_da_mcbc,
71262306a36Sopenharmony_ci	.rx_desc_get_dot11_hdr = ath12k_hw_qcn9274_rx_desc_get_dot11_hdr,
71362306a36Sopenharmony_ci	.rx_desc_get_crypto_header = ath12k_hw_qcn9274_rx_desc_get_crypto_hdr,
71462306a36Sopenharmony_ci	.rx_desc_get_mpdu_frame_ctl = ath12k_hw_qcn9274_rx_desc_get_mpdu_frame_ctl,
71562306a36Sopenharmony_ci	.create_srng_config = ath12k_hal_srng_create_config_qcn9274,
71662306a36Sopenharmony_ci	.tcl_to_wbm_rbm_map = ath12k_hal_qcn9274_tcl_to_wbm_rbm_map,
71762306a36Sopenharmony_ci	.dp_rx_h_msdu_done = ath12k_hw_qcn9274_dp_rx_h_msdu_done,
71862306a36Sopenharmony_ci	.dp_rx_h_l4_cksum_fail = ath12k_hw_qcn9274_dp_rx_h_l4_cksum_fail,
71962306a36Sopenharmony_ci	.dp_rx_h_ip_cksum_fail = ath12k_hw_qcn9274_dp_rx_h_ip_cksum_fail,
72062306a36Sopenharmony_ci	.dp_rx_h_is_decrypted = ath12k_hw_qcn9274_dp_rx_h_is_decrypted,
72162306a36Sopenharmony_ci	.dp_rx_h_mpdu_err = ath12k_hw_qcn9274_dp_rx_h_mpdu_err,
72262306a36Sopenharmony_ci};
72362306a36Sopenharmony_ci
72462306a36Sopenharmony_cistatic bool ath12k_hw_wcn7850_rx_desc_get_first_msdu(struct hal_rx_desc *desc)
72562306a36Sopenharmony_ci{
72662306a36Sopenharmony_ci	return !!le16_get_bits(desc->u.wcn7850.msdu_end.info5,
72762306a36Sopenharmony_ci			       RX_MSDU_END_INFO5_FIRST_MSDU);
72862306a36Sopenharmony_ci}
72962306a36Sopenharmony_ci
73062306a36Sopenharmony_cistatic bool ath12k_hw_wcn7850_rx_desc_get_last_msdu(struct hal_rx_desc *desc)
73162306a36Sopenharmony_ci{
73262306a36Sopenharmony_ci	return !!le16_get_bits(desc->u.wcn7850.msdu_end.info5,
73362306a36Sopenharmony_ci			       RX_MSDU_END_INFO5_LAST_MSDU);
73462306a36Sopenharmony_ci}
73562306a36Sopenharmony_ci
73662306a36Sopenharmony_cistatic u8 ath12k_hw_wcn7850_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc)
73762306a36Sopenharmony_ci{
73862306a36Sopenharmony_ci	return le16_get_bits(desc->u.wcn7850.msdu_end.info5,
73962306a36Sopenharmony_ci			    RX_MSDU_END_INFO5_L3_HDR_PADDING);
74062306a36Sopenharmony_ci}
74162306a36Sopenharmony_ci
74262306a36Sopenharmony_cistatic bool ath12k_hw_wcn7850_rx_desc_encrypt_valid(struct hal_rx_desc *desc)
74362306a36Sopenharmony_ci{
74462306a36Sopenharmony_ci	return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4,
74562306a36Sopenharmony_ci			       RX_MPDU_START_INFO4_ENCRYPT_INFO_VALID);
74662306a36Sopenharmony_ci}
74762306a36Sopenharmony_ci
74862306a36Sopenharmony_cistatic u32 ath12k_hw_wcn7850_rx_desc_get_encrypt_type(struct hal_rx_desc *desc)
74962306a36Sopenharmony_ci{
75062306a36Sopenharmony_ci	return le32_get_bits(desc->u.wcn7850.mpdu_start.info2,
75162306a36Sopenharmony_ci			     RX_MPDU_START_INFO2_ENC_TYPE);
75262306a36Sopenharmony_ci}
75362306a36Sopenharmony_ci
75462306a36Sopenharmony_cistatic u8 ath12k_hw_wcn7850_rx_desc_get_decap_type(struct hal_rx_desc *desc)
75562306a36Sopenharmony_ci{
75662306a36Sopenharmony_ci	return le32_get_bits(desc->u.wcn7850.msdu_end.info11,
75762306a36Sopenharmony_ci			     RX_MSDU_END_INFO11_DECAP_FORMAT);
75862306a36Sopenharmony_ci}
75962306a36Sopenharmony_ci
76062306a36Sopenharmony_cistatic u8 ath12k_hw_wcn7850_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc)
76162306a36Sopenharmony_ci{
76262306a36Sopenharmony_ci	return le32_get_bits(desc->u.wcn7850.msdu_end.info11,
76362306a36Sopenharmony_ci			     RX_MSDU_END_INFO11_MESH_CTRL_PRESENT);
76462306a36Sopenharmony_ci}
76562306a36Sopenharmony_ci
76662306a36Sopenharmony_cistatic bool ath12k_hw_wcn7850_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc)
76762306a36Sopenharmony_ci{
76862306a36Sopenharmony_ci	return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4,
76962306a36Sopenharmony_ci			       RX_MPDU_START_INFO4_MPDU_SEQ_CTRL_VALID);
77062306a36Sopenharmony_ci}
77162306a36Sopenharmony_ci
77262306a36Sopenharmony_cistatic bool ath12k_hw_wcn7850_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc)
77362306a36Sopenharmony_ci{
77462306a36Sopenharmony_ci	return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4,
77562306a36Sopenharmony_ci			       RX_MPDU_START_INFO4_MPDU_FCTRL_VALID);
77662306a36Sopenharmony_ci}
77762306a36Sopenharmony_ci
77862306a36Sopenharmony_cistatic u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc)
77962306a36Sopenharmony_ci{
78062306a36Sopenharmony_ci	return le32_get_bits(desc->u.wcn7850.mpdu_start.info4,
78162306a36Sopenharmony_ci			     RX_MPDU_START_INFO4_MPDU_SEQ_NUM);
78262306a36Sopenharmony_ci}
78362306a36Sopenharmony_ci
78462306a36Sopenharmony_cistatic u16 ath12k_hw_wcn7850_rx_desc_get_msdu_len(struct hal_rx_desc *desc)
78562306a36Sopenharmony_ci{
78662306a36Sopenharmony_ci	return le32_get_bits(desc->u.wcn7850.msdu_end.info10,
78762306a36Sopenharmony_ci			     RX_MSDU_END_INFO10_MSDU_LENGTH);
78862306a36Sopenharmony_ci}
78962306a36Sopenharmony_ci
79062306a36Sopenharmony_cistatic u8 ath12k_hw_wcn7850_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc)
79162306a36Sopenharmony_ci{
79262306a36Sopenharmony_ci	return le32_get_bits(desc->u.wcn7850.msdu_end.info12,
79362306a36Sopenharmony_ci			     RX_MSDU_END_INFO12_SGI);
79462306a36Sopenharmony_ci}
79562306a36Sopenharmony_ci
79662306a36Sopenharmony_cistatic u8 ath12k_hw_wcn7850_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc)
79762306a36Sopenharmony_ci{
79862306a36Sopenharmony_ci	return le32_get_bits(desc->u.wcn7850.msdu_end.info12,
79962306a36Sopenharmony_ci			     RX_MSDU_END_INFO12_RATE_MCS);
80062306a36Sopenharmony_ci}
80162306a36Sopenharmony_ci
80262306a36Sopenharmony_cistatic u8 ath12k_hw_wcn7850_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc)
80362306a36Sopenharmony_ci{
80462306a36Sopenharmony_ci	return le32_get_bits(desc->u.wcn7850.msdu_end.info12,
80562306a36Sopenharmony_ci			     RX_MSDU_END_INFO12_RECV_BW);
80662306a36Sopenharmony_ci}
80762306a36Sopenharmony_ci
80862306a36Sopenharmony_cistatic u32 ath12k_hw_wcn7850_rx_desc_get_msdu_freq(struct hal_rx_desc *desc)
80962306a36Sopenharmony_ci{
81062306a36Sopenharmony_ci	return __le32_to_cpu(desc->u.wcn7850.msdu_end.phy_meta_data);
81162306a36Sopenharmony_ci}
81262306a36Sopenharmony_ci
81362306a36Sopenharmony_cistatic u8 ath12k_hw_wcn7850_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc)
81462306a36Sopenharmony_ci{
81562306a36Sopenharmony_ci	return le32_get_bits(desc->u.wcn7850.msdu_end.info12,
81662306a36Sopenharmony_ci			     RX_MSDU_END_INFO12_PKT_TYPE);
81762306a36Sopenharmony_ci}
81862306a36Sopenharmony_ci
81962306a36Sopenharmony_cistatic u8 ath12k_hw_wcn7850_rx_desc_get_msdu_nss(struct hal_rx_desc *desc)
82062306a36Sopenharmony_ci{
82162306a36Sopenharmony_ci	return le32_get_bits(desc->u.wcn7850.msdu_end.info12,
82262306a36Sopenharmony_ci			     RX_MSDU_END_INFO12_MIMO_SS_BITMAP);
82362306a36Sopenharmony_ci}
82462306a36Sopenharmony_ci
82562306a36Sopenharmony_cistatic u8 ath12k_hw_wcn7850_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc)
82662306a36Sopenharmony_ci{
82762306a36Sopenharmony_ci	return le16_get_bits(desc->u.wcn7850.msdu_end.info5,
82862306a36Sopenharmony_ci			     RX_MSDU_END_INFO5_TID);
82962306a36Sopenharmony_ci}
83062306a36Sopenharmony_ci
83162306a36Sopenharmony_cistatic u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc)
83262306a36Sopenharmony_ci{
83362306a36Sopenharmony_ci	return __le16_to_cpu(desc->u.wcn7850.mpdu_start.sw_peer_id);
83462306a36Sopenharmony_ci}
83562306a36Sopenharmony_ci
83662306a36Sopenharmony_cistatic void ath12k_hw_wcn7850_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc,
83762306a36Sopenharmony_ci						   struct hal_rx_desc *ldesc)
83862306a36Sopenharmony_ci{
83962306a36Sopenharmony_ci	memcpy(&fdesc->u.wcn7850.msdu_end, &ldesc->u.wcn7850.msdu_end,
84062306a36Sopenharmony_ci	       sizeof(struct rx_msdu_end_qcn9274));
84162306a36Sopenharmony_ci}
84262306a36Sopenharmony_ci
84362306a36Sopenharmony_cistatic u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_tag(struct hal_rx_desc *desc)
84462306a36Sopenharmony_ci{
84562306a36Sopenharmony_ci	return le64_get_bits(desc->u.wcn7850.mpdu_start_tag,
84662306a36Sopenharmony_ci			    HAL_TLV_HDR_TAG);
84762306a36Sopenharmony_ci}
84862306a36Sopenharmony_ci
84962306a36Sopenharmony_cistatic u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc)
85062306a36Sopenharmony_ci{
85162306a36Sopenharmony_ci	return __le16_to_cpu(desc->u.wcn7850.mpdu_start.phy_ppdu_id);
85262306a36Sopenharmony_ci}
85362306a36Sopenharmony_ci
85462306a36Sopenharmony_cistatic void ath12k_hw_wcn7850_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len)
85562306a36Sopenharmony_ci{
85662306a36Sopenharmony_ci	u32 info = __le32_to_cpu(desc->u.wcn7850.msdu_end.info10);
85762306a36Sopenharmony_ci
85862306a36Sopenharmony_ci	info &= ~RX_MSDU_END_INFO10_MSDU_LENGTH;
85962306a36Sopenharmony_ci	info |= u32_encode_bits(len, RX_MSDU_END_INFO10_MSDU_LENGTH);
86062306a36Sopenharmony_ci
86162306a36Sopenharmony_ci	desc->u.wcn7850.msdu_end.info10 = __cpu_to_le32(info);
86262306a36Sopenharmony_ci}
86362306a36Sopenharmony_ci
86462306a36Sopenharmony_cistatic u8 *ath12k_hw_wcn7850_rx_desc_get_msdu_payload(struct hal_rx_desc *desc)
86562306a36Sopenharmony_ci{
86662306a36Sopenharmony_ci	return &desc->u.wcn7850.msdu_payload[0];
86762306a36Sopenharmony_ci}
86862306a36Sopenharmony_ci
86962306a36Sopenharmony_cistatic u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_offset(void)
87062306a36Sopenharmony_ci{
87162306a36Sopenharmony_ci	return offsetof(struct hal_rx_desc_wcn7850, mpdu_start_tag);
87262306a36Sopenharmony_ci}
87362306a36Sopenharmony_ci
87462306a36Sopenharmony_cistatic u32 ath12k_hw_wcn7850_rx_desc_get_msdu_end_offset(void)
87562306a36Sopenharmony_ci{
87662306a36Sopenharmony_ci	return offsetof(struct hal_rx_desc_wcn7850, msdu_end_tag);
87762306a36Sopenharmony_ci}
87862306a36Sopenharmony_ci
87962306a36Sopenharmony_cistatic bool ath12k_hw_wcn7850_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc)
88062306a36Sopenharmony_ci{
88162306a36Sopenharmony_ci	return __le32_to_cpu(desc->u.wcn7850.mpdu_start.info4) &
88262306a36Sopenharmony_ci	       RX_MPDU_START_INFO4_MAC_ADDR2_VALID;
88362306a36Sopenharmony_ci}
88462306a36Sopenharmony_ci
88562306a36Sopenharmony_cistatic u8 *ath12k_hw_wcn7850_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc)
88662306a36Sopenharmony_ci{
88762306a36Sopenharmony_ci	return desc->u.wcn7850.mpdu_start.addr2;
88862306a36Sopenharmony_ci}
88962306a36Sopenharmony_ci
89062306a36Sopenharmony_cistatic bool ath12k_hw_wcn7850_rx_desc_is_da_mcbc(struct hal_rx_desc *desc)
89162306a36Sopenharmony_ci{
89262306a36Sopenharmony_ci	return __le32_to_cpu(desc->u.wcn7850.msdu_end.info13) &
89362306a36Sopenharmony_ci	       RX_MSDU_END_INFO13_MCAST_BCAST;
89462306a36Sopenharmony_ci}
89562306a36Sopenharmony_ci
89662306a36Sopenharmony_cistatic void ath12k_hw_wcn7850_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc,
89762306a36Sopenharmony_ci						    struct ieee80211_hdr *hdr)
89862306a36Sopenharmony_ci{
89962306a36Sopenharmony_ci	hdr->frame_control = desc->u.wcn7850.mpdu_start.frame_ctrl;
90062306a36Sopenharmony_ci	hdr->duration_id = desc->u.wcn7850.mpdu_start.duration;
90162306a36Sopenharmony_ci	ether_addr_copy(hdr->addr1, desc->u.wcn7850.mpdu_start.addr1);
90262306a36Sopenharmony_ci	ether_addr_copy(hdr->addr2, desc->u.wcn7850.mpdu_start.addr2);
90362306a36Sopenharmony_ci	ether_addr_copy(hdr->addr3, desc->u.wcn7850.mpdu_start.addr3);
90462306a36Sopenharmony_ci	if (__le32_to_cpu(desc->u.wcn7850.mpdu_start.info4) &
90562306a36Sopenharmony_ci			RX_MPDU_START_INFO4_MAC_ADDR4_VALID) {
90662306a36Sopenharmony_ci		ether_addr_copy(hdr->addr4, desc->u.wcn7850.mpdu_start.addr4);
90762306a36Sopenharmony_ci	}
90862306a36Sopenharmony_ci	hdr->seq_ctrl = desc->u.wcn7850.mpdu_start.seq_ctrl;
90962306a36Sopenharmony_ci}
91062306a36Sopenharmony_ci
91162306a36Sopenharmony_cistatic void ath12k_hw_wcn7850_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc,
91262306a36Sopenharmony_ci						     u8 *crypto_hdr,
91362306a36Sopenharmony_ci						     enum hal_encrypt_type enctype)
91462306a36Sopenharmony_ci{
91562306a36Sopenharmony_ci	unsigned int key_id;
91662306a36Sopenharmony_ci
91762306a36Sopenharmony_ci	switch (enctype) {
91862306a36Sopenharmony_ci	case HAL_ENCRYPT_TYPE_OPEN:
91962306a36Sopenharmony_ci		return;
92062306a36Sopenharmony_ci	case HAL_ENCRYPT_TYPE_TKIP_NO_MIC:
92162306a36Sopenharmony_ci	case HAL_ENCRYPT_TYPE_TKIP_MIC:
92262306a36Sopenharmony_ci		crypto_hdr[0] =
92362306a36Sopenharmony_ci			HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.wcn7850.mpdu_start.pn[0]);
92462306a36Sopenharmony_ci		crypto_hdr[1] = 0;
92562306a36Sopenharmony_ci		crypto_hdr[2] =
92662306a36Sopenharmony_ci			HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.wcn7850.mpdu_start.pn[0]);
92762306a36Sopenharmony_ci		break;
92862306a36Sopenharmony_ci	case HAL_ENCRYPT_TYPE_CCMP_128:
92962306a36Sopenharmony_ci	case HAL_ENCRYPT_TYPE_CCMP_256:
93062306a36Sopenharmony_ci	case HAL_ENCRYPT_TYPE_GCMP_128:
93162306a36Sopenharmony_ci	case HAL_ENCRYPT_TYPE_AES_GCMP_256:
93262306a36Sopenharmony_ci		crypto_hdr[0] =
93362306a36Sopenharmony_ci			HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.wcn7850.mpdu_start.pn[0]);
93462306a36Sopenharmony_ci		crypto_hdr[1] =
93562306a36Sopenharmony_ci			HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.wcn7850.mpdu_start.pn[0]);
93662306a36Sopenharmony_ci		crypto_hdr[2] = 0;
93762306a36Sopenharmony_ci		break;
93862306a36Sopenharmony_ci	case HAL_ENCRYPT_TYPE_WEP_40:
93962306a36Sopenharmony_ci	case HAL_ENCRYPT_TYPE_WEP_104:
94062306a36Sopenharmony_ci	case HAL_ENCRYPT_TYPE_WEP_128:
94162306a36Sopenharmony_ci	case HAL_ENCRYPT_TYPE_WAPI_GCM_SM4:
94262306a36Sopenharmony_ci	case HAL_ENCRYPT_TYPE_WAPI:
94362306a36Sopenharmony_ci		return;
94462306a36Sopenharmony_ci	}
94562306a36Sopenharmony_ci	key_id = u32_get_bits(__le32_to_cpu(desc->u.wcn7850.mpdu_start.info5),
94662306a36Sopenharmony_ci			      RX_MPDU_START_INFO5_KEY_ID);
94762306a36Sopenharmony_ci	crypto_hdr[3] = 0x20 | (key_id << 6);
94862306a36Sopenharmony_ci	crypto_hdr[4] = HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.wcn7850.mpdu_start.pn[0]);
94962306a36Sopenharmony_ci	crypto_hdr[5] = HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.wcn7850.mpdu_start.pn[0]);
95062306a36Sopenharmony_ci	crypto_hdr[6] = HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.wcn7850.mpdu_start.pn[1]);
95162306a36Sopenharmony_ci	crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.wcn7850.mpdu_start.pn[1]);
95262306a36Sopenharmony_ci}
95362306a36Sopenharmony_ci
95462306a36Sopenharmony_cistatic u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_frame_ctl(struct hal_rx_desc *desc)
95562306a36Sopenharmony_ci{
95662306a36Sopenharmony_ci	return __le16_to_cpu(desc->u.wcn7850.mpdu_start.frame_ctrl);
95762306a36Sopenharmony_ci}
95862306a36Sopenharmony_ci
95962306a36Sopenharmony_cistatic int ath12k_hal_srng_create_config_wcn7850(struct ath12k_base *ab)
96062306a36Sopenharmony_ci{
96162306a36Sopenharmony_ci	struct ath12k_hal *hal = &ab->hal;
96262306a36Sopenharmony_ci	struct hal_srng_config *s;
96362306a36Sopenharmony_ci
96462306a36Sopenharmony_ci	hal->srng_config = kmemdup(hw_srng_config_template,
96562306a36Sopenharmony_ci				   sizeof(hw_srng_config_template),
96662306a36Sopenharmony_ci				   GFP_KERNEL);
96762306a36Sopenharmony_ci	if (!hal->srng_config)
96862306a36Sopenharmony_ci		return -ENOMEM;
96962306a36Sopenharmony_ci
97062306a36Sopenharmony_ci	s = &hal->srng_config[HAL_REO_DST];
97162306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_BASE_LSB(ab);
97262306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_HP;
97362306a36Sopenharmony_ci	s->reg_size[0] = HAL_REO2_RING_BASE_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab);
97462306a36Sopenharmony_ci	s->reg_size[1] = HAL_REO2_RING_HP - HAL_REO1_RING_HP;
97562306a36Sopenharmony_ci
97662306a36Sopenharmony_ci	s = &hal->srng_config[HAL_REO_EXCEPTION];
97762306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_BASE_LSB(ab);
97862306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_HP;
97962306a36Sopenharmony_ci
98062306a36Sopenharmony_ci	s = &hal->srng_config[HAL_REO_REINJECT];
98162306a36Sopenharmony_ci	s->max_rings = 1;
98262306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_BASE_LSB(ab);
98362306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_HP;
98462306a36Sopenharmony_ci
98562306a36Sopenharmony_ci	s = &hal->srng_config[HAL_REO_CMD];
98662306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_RING_BASE_LSB(ab);
98762306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_HP;
98862306a36Sopenharmony_ci
98962306a36Sopenharmony_ci	s = &hal->srng_config[HAL_REO_STATUS];
99062306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_RING_BASE_LSB(ab);
99162306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_HP;
99262306a36Sopenharmony_ci
99362306a36Sopenharmony_ci	s = &hal->srng_config[HAL_TCL_DATA];
99462306a36Sopenharmony_ci	s->max_rings = 5;
99562306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_BASE_LSB;
99662306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_HP;
99762306a36Sopenharmony_ci	s->reg_size[0] = HAL_TCL2_RING_BASE_LSB - HAL_TCL1_RING_BASE_LSB;
99862306a36Sopenharmony_ci	s->reg_size[1] = HAL_TCL2_RING_HP - HAL_TCL1_RING_HP;
99962306a36Sopenharmony_ci
100062306a36Sopenharmony_ci	s = &hal->srng_config[HAL_TCL_CMD];
100162306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_BASE_LSB(ab);
100262306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_HP;
100362306a36Sopenharmony_ci
100462306a36Sopenharmony_ci	s = &hal->srng_config[HAL_TCL_STATUS];
100562306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_BASE_LSB(ab);
100662306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP;
100762306a36Sopenharmony_ci
100862306a36Sopenharmony_ci	s = &hal->srng_config[HAL_CE_SRC];
100962306a36Sopenharmony_ci	s->max_rings = 12;
101062306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG + HAL_CE_DST_RING_BASE_LSB;
101162306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG + HAL_CE_DST_RING_HP;
101262306a36Sopenharmony_ci	s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG -
101362306a36Sopenharmony_ci		HAL_SEQ_WCSS_UMAC_CE0_SRC_REG;
101462306a36Sopenharmony_ci	s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG -
101562306a36Sopenharmony_ci		HAL_SEQ_WCSS_UMAC_CE0_SRC_REG;
101662306a36Sopenharmony_ci
101762306a36Sopenharmony_ci	s = &hal->srng_config[HAL_CE_DST];
101862306a36Sopenharmony_ci	s->max_rings = 12;
101962306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG + HAL_CE_DST_RING_BASE_LSB;
102062306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG + HAL_CE_DST_RING_HP;
102162306a36Sopenharmony_ci	s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG -
102262306a36Sopenharmony_ci		HAL_SEQ_WCSS_UMAC_CE0_DST_REG;
102362306a36Sopenharmony_ci	s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG -
102462306a36Sopenharmony_ci		HAL_SEQ_WCSS_UMAC_CE0_DST_REG;
102562306a36Sopenharmony_ci
102662306a36Sopenharmony_ci	s = &hal->srng_config[HAL_CE_DST_STATUS];
102762306a36Sopenharmony_ci	s->max_rings = 12;
102862306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG +
102962306a36Sopenharmony_ci		HAL_CE_DST_STATUS_RING_BASE_LSB;
103062306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG + HAL_CE_DST_STATUS_RING_HP;
103162306a36Sopenharmony_ci	s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG -
103262306a36Sopenharmony_ci		HAL_SEQ_WCSS_UMAC_CE0_DST_REG;
103362306a36Sopenharmony_ci	s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG -
103462306a36Sopenharmony_ci		HAL_SEQ_WCSS_UMAC_CE0_DST_REG;
103562306a36Sopenharmony_ci
103662306a36Sopenharmony_ci	s = &hal->srng_config[HAL_WBM_IDLE_LINK];
103762306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_BASE_LSB(ab);
103862306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_HP;
103962306a36Sopenharmony_ci
104062306a36Sopenharmony_ci	s = &hal->srng_config[HAL_SW2WBM_RELEASE];
104162306a36Sopenharmony_ci	s->max_rings = 1;
104262306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG +
104362306a36Sopenharmony_ci		HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab);
104462306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SW_RELEASE_RING_HP;
104562306a36Sopenharmony_ci
104662306a36Sopenharmony_ci	s = &hal->srng_config[HAL_WBM2SW_RELEASE];
104762306a36Sopenharmony_ci	s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_BASE_LSB(ab);
104862306a36Sopenharmony_ci	s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_HP;
104962306a36Sopenharmony_ci	s->reg_size[0] = HAL_WBM1_RELEASE_RING_BASE_LSB(ab) -
105062306a36Sopenharmony_ci		HAL_WBM0_RELEASE_RING_BASE_LSB(ab);
105162306a36Sopenharmony_ci	s->reg_size[1] = HAL_WBM1_RELEASE_RING_HP - HAL_WBM0_RELEASE_RING_HP;
105262306a36Sopenharmony_ci
105362306a36Sopenharmony_ci	s = &hal->srng_config[HAL_RXDMA_BUF];
105462306a36Sopenharmony_ci	s->max_rings = 2;
105562306a36Sopenharmony_ci	s->mac_type = ATH12K_HAL_SRNG_PMAC;
105662306a36Sopenharmony_ci
105762306a36Sopenharmony_ci	s = &hal->srng_config[HAL_RXDMA_DST];
105862306a36Sopenharmony_ci	s->max_rings = 1;
105962306a36Sopenharmony_ci	s->entry_size = sizeof(struct hal_reo_entrance_ring) >> 2;
106062306a36Sopenharmony_ci
106162306a36Sopenharmony_ci	/* below rings are not used */
106262306a36Sopenharmony_ci	s = &hal->srng_config[HAL_RXDMA_DIR_BUF];
106362306a36Sopenharmony_ci	s->max_rings = 0;
106462306a36Sopenharmony_ci
106562306a36Sopenharmony_ci	s = &hal->srng_config[HAL_PPE2TCL];
106662306a36Sopenharmony_ci	s->max_rings = 0;
106762306a36Sopenharmony_ci
106862306a36Sopenharmony_ci	s = &hal->srng_config[HAL_PPE_RELEASE];
106962306a36Sopenharmony_ci	s->max_rings = 0;
107062306a36Sopenharmony_ci
107162306a36Sopenharmony_ci	s = &hal->srng_config[HAL_TX_MONITOR_BUF];
107262306a36Sopenharmony_ci	s->max_rings = 0;
107362306a36Sopenharmony_ci
107462306a36Sopenharmony_ci	s = &hal->srng_config[HAL_TX_MONITOR_DST];
107562306a36Sopenharmony_ci	s->max_rings = 0;
107662306a36Sopenharmony_ci
107762306a36Sopenharmony_ci	s = &hal->srng_config[HAL_PPE2TCL];
107862306a36Sopenharmony_ci	s->max_rings = 0;
107962306a36Sopenharmony_ci
108062306a36Sopenharmony_ci	return 0;
108162306a36Sopenharmony_ci}
108262306a36Sopenharmony_ci
108362306a36Sopenharmony_cistatic bool ath12k_hw_wcn7850_dp_rx_h_msdu_done(struct hal_rx_desc *desc)
108462306a36Sopenharmony_ci{
108562306a36Sopenharmony_ci	return !!le32_get_bits(desc->u.wcn7850.msdu_end.info14,
108662306a36Sopenharmony_ci			       RX_MSDU_END_INFO14_MSDU_DONE);
108762306a36Sopenharmony_ci}
108862306a36Sopenharmony_ci
108962306a36Sopenharmony_cistatic bool ath12k_hw_wcn7850_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc)
109062306a36Sopenharmony_ci{
109162306a36Sopenharmony_ci	return !!le32_get_bits(desc->u.wcn7850.msdu_end.info13,
109262306a36Sopenharmony_ci			       RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL);
109362306a36Sopenharmony_ci}
109462306a36Sopenharmony_ci
109562306a36Sopenharmony_cistatic bool ath12k_hw_wcn7850_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc)
109662306a36Sopenharmony_ci{
109762306a36Sopenharmony_ci	return !!le32_get_bits(desc->u.wcn7850.msdu_end.info13,
109862306a36Sopenharmony_ci			      RX_MSDU_END_INFO13_IP_CKSUM_FAIL);
109962306a36Sopenharmony_ci}
110062306a36Sopenharmony_ci
110162306a36Sopenharmony_cistatic bool ath12k_hw_wcn7850_dp_rx_h_is_decrypted(struct hal_rx_desc *desc)
110262306a36Sopenharmony_ci{
110362306a36Sopenharmony_ci	return (le32_get_bits(desc->u.wcn7850.msdu_end.info14,
110462306a36Sopenharmony_ci			      RX_MSDU_END_INFO14_DECRYPT_STATUS_CODE) ==
110562306a36Sopenharmony_ci			      RX_DESC_DECRYPT_STATUS_CODE_OK);
110662306a36Sopenharmony_ci}
110762306a36Sopenharmony_ci
110862306a36Sopenharmony_cistatic u32 ath12k_hw_wcn7850_dp_rx_h_mpdu_err(struct hal_rx_desc *desc)
110962306a36Sopenharmony_ci{
111062306a36Sopenharmony_ci	u32 info = __le32_to_cpu(desc->u.wcn7850.msdu_end.info13);
111162306a36Sopenharmony_ci	u32 errmap = 0;
111262306a36Sopenharmony_ci
111362306a36Sopenharmony_ci	if (info & RX_MSDU_END_INFO13_FCS_ERR)
111462306a36Sopenharmony_ci		errmap |= HAL_RX_MPDU_ERR_FCS;
111562306a36Sopenharmony_ci
111662306a36Sopenharmony_ci	if (info & RX_MSDU_END_INFO13_DECRYPT_ERR)
111762306a36Sopenharmony_ci		errmap |= HAL_RX_MPDU_ERR_DECRYPT;
111862306a36Sopenharmony_ci
111962306a36Sopenharmony_ci	if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR)
112062306a36Sopenharmony_ci		errmap |= HAL_RX_MPDU_ERR_TKIP_MIC;
112162306a36Sopenharmony_ci
112262306a36Sopenharmony_ci	if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR)
112362306a36Sopenharmony_ci		errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR;
112462306a36Sopenharmony_ci
112562306a36Sopenharmony_ci	if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR)
112662306a36Sopenharmony_ci		errmap |= HAL_RX_MPDU_ERR_OVERFLOW;
112762306a36Sopenharmony_ci
112862306a36Sopenharmony_ci	if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR)
112962306a36Sopenharmony_ci		errmap |= HAL_RX_MPDU_ERR_MSDU_LEN;
113062306a36Sopenharmony_ci
113162306a36Sopenharmony_ci	if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR)
113262306a36Sopenharmony_ci		errmap |= HAL_RX_MPDU_ERR_MPDU_LEN;
113362306a36Sopenharmony_ci
113462306a36Sopenharmony_ci	return errmap;
113562306a36Sopenharmony_ci}
113662306a36Sopenharmony_ci
113762306a36Sopenharmony_ciconst struct hal_ops hal_wcn7850_ops = {
113862306a36Sopenharmony_ci	.rx_desc_get_first_msdu = ath12k_hw_wcn7850_rx_desc_get_first_msdu,
113962306a36Sopenharmony_ci	.rx_desc_get_last_msdu = ath12k_hw_wcn7850_rx_desc_get_last_msdu,
114062306a36Sopenharmony_ci	.rx_desc_get_l3_pad_bytes = ath12k_hw_wcn7850_rx_desc_get_l3_pad_bytes,
114162306a36Sopenharmony_ci	.rx_desc_encrypt_valid = ath12k_hw_wcn7850_rx_desc_encrypt_valid,
114262306a36Sopenharmony_ci	.rx_desc_get_encrypt_type = ath12k_hw_wcn7850_rx_desc_get_encrypt_type,
114362306a36Sopenharmony_ci	.rx_desc_get_decap_type = ath12k_hw_wcn7850_rx_desc_get_decap_type,
114462306a36Sopenharmony_ci	.rx_desc_get_mesh_ctl = ath12k_hw_wcn7850_rx_desc_get_mesh_ctl,
114562306a36Sopenharmony_ci	.rx_desc_get_mpdu_seq_ctl_vld = ath12k_hw_wcn7850_rx_desc_get_mpdu_seq_ctl_vld,
114662306a36Sopenharmony_ci	.rx_desc_get_mpdu_fc_valid = ath12k_hw_wcn7850_rx_desc_get_mpdu_fc_valid,
114762306a36Sopenharmony_ci	.rx_desc_get_mpdu_start_seq_no = ath12k_hw_wcn7850_rx_desc_get_mpdu_start_seq_no,
114862306a36Sopenharmony_ci	.rx_desc_get_msdu_len = ath12k_hw_wcn7850_rx_desc_get_msdu_len,
114962306a36Sopenharmony_ci	.rx_desc_get_msdu_sgi = ath12k_hw_wcn7850_rx_desc_get_msdu_sgi,
115062306a36Sopenharmony_ci	.rx_desc_get_msdu_rate_mcs = ath12k_hw_wcn7850_rx_desc_get_msdu_rate_mcs,
115162306a36Sopenharmony_ci	.rx_desc_get_msdu_rx_bw = ath12k_hw_wcn7850_rx_desc_get_msdu_rx_bw,
115262306a36Sopenharmony_ci	.rx_desc_get_msdu_freq = ath12k_hw_wcn7850_rx_desc_get_msdu_freq,
115362306a36Sopenharmony_ci	.rx_desc_get_msdu_pkt_type = ath12k_hw_wcn7850_rx_desc_get_msdu_pkt_type,
115462306a36Sopenharmony_ci	.rx_desc_get_msdu_nss = ath12k_hw_wcn7850_rx_desc_get_msdu_nss,
115562306a36Sopenharmony_ci	.rx_desc_get_mpdu_tid = ath12k_hw_wcn7850_rx_desc_get_mpdu_tid,
115662306a36Sopenharmony_ci	.rx_desc_get_mpdu_peer_id = ath12k_hw_wcn7850_rx_desc_get_mpdu_peer_id,
115762306a36Sopenharmony_ci	.rx_desc_copy_end_tlv = ath12k_hw_wcn7850_rx_desc_copy_end_tlv,
115862306a36Sopenharmony_ci	.rx_desc_get_mpdu_start_tag = ath12k_hw_wcn7850_rx_desc_get_mpdu_start_tag,
115962306a36Sopenharmony_ci	.rx_desc_get_mpdu_ppdu_id = ath12k_hw_wcn7850_rx_desc_get_mpdu_ppdu_id,
116062306a36Sopenharmony_ci	.rx_desc_set_msdu_len = ath12k_hw_wcn7850_rx_desc_set_msdu_len,
116162306a36Sopenharmony_ci	.rx_desc_get_msdu_payload = ath12k_hw_wcn7850_rx_desc_get_msdu_payload,
116262306a36Sopenharmony_ci	.rx_desc_get_mpdu_start_offset = ath12k_hw_wcn7850_rx_desc_get_mpdu_start_offset,
116362306a36Sopenharmony_ci	.rx_desc_get_msdu_end_offset = ath12k_hw_wcn7850_rx_desc_get_msdu_end_offset,
116462306a36Sopenharmony_ci	.rx_desc_mac_addr2_valid = ath12k_hw_wcn7850_rx_desc_mac_addr2_valid,
116562306a36Sopenharmony_ci	.rx_desc_mpdu_start_addr2 = ath12k_hw_wcn7850_rx_desc_mpdu_start_addr2,
116662306a36Sopenharmony_ci	.rx_desc_is_da_mcbc = ath12k_hw_wcn7850_rx_desc_is_da_mcbc,
116762306a36Sopenharmony_ci	.rx_desc_get_dot11_hdr = ath12k_hw_wcn7850_rx_desc_get_dot11_hdr,
116862306a36Sopenharmony_ci	.rx_desc_get_crypto_header = ath12k_hw_wcn7850_rx_desc_get_crypto_hdr,
116962306a36Sopenharmony_ci	.rx_desc_get_mpdu_frame_ctl = ath12k_hw_wcn7850_rx_desc_get_mpdu_frame_ctl,
117062306a36Sopenharmony_ci	.create_srng_config = ath12k_hal_srng_create_config_wcn7850,
117162306a36Sopenharmony_ci	.tcl_to_wbm_rbm_map = ath12k_hal_wcn7850_tcl_to_wbm_rbm_map,
117262306a36Sopenharmony_ci	.dp_rx_h_msdu_done = ath12k_hw_wcn7850_dp_rx_h_msdu_done,
117362306a36Sopenharmony_ci	.dp_rx_h_l4_cksum_fail = ath12k_hw_wcn7850_dp_rx_h_l4_cksum_fail,
117462306a36Sopenharmony_ci	.dp_rx_h_ip_cksum_fail = ath12k_hw_wcn7850_dp_rx_h_ip_cksum_fail,
117562306a36Sopenharmony_ci	.dp_rx_h_is_decrypted = ath12k_hw_wcn7850_dp_rx_h_is_decrypted,
117662306a36Sopenharmony_ci	.dp_rx_h_mpdu_err = ath12k_hw_wcn7850_dp_rx_h_mpdu_err,
117762306a36Sopenharmony_ci};
117862306a36Sopenharmony_ci
117962306a36Sopenharmony_cistatic int ath12k_hal_alloc_cont_rdp(struct ath12k_base *ab)
118062306a36Sopenharmony_ci{
118162306a36Sopenharmony_ci	struct ath12k_hal *hal = &ab->hal;
118262306a36Sopenharmony_ci	size_t size;
118362306a36Sopenharmony_ci
118462306a36Sopenharmony_ci	size = sizeof(u32) * HAL_SRNG_RING_ID_MAX;
118562306a36Sopenharmony_ci	hal->rdp.vaddr = dma_alloc_coherent(ab->dev, size, &hal->rdp.paddr,
118662306a36Sopenharmony_ci					    GFP_KERNEL);
118762306a36Sopenharmony_ci	if (!hal->rdp.vaddr)
118862306a36Sopenharmony_ci		return -ENOMEM;
118962306a36Sopenharmony_ci
119062306a36Sopenharmony_ci	return 0;
119162306a36Sopenharmony_ci}
119262306a36Sopenharmony_ci
119362306a36Sopenharmony_cistatic void ath12k_hal_free_cont_rdp(struct ath12k_base *ab)
119462306a36Sopenharmony_ci{
119562306a36Sopenharmony_ci	struct ath12k_hal *hal = &ab->hal;
119662306a36Sopenharmony_ci	size_t size;
119762306a36Sopenharmony_ci
119862306a36Sopenharmony_ci	if (!hal->rdp.vaddr)
119962306a36Sopenharmony_ci		return;
120062306a36Sopenharmony_ci
120162306a36Sopenharmony_ci	size = sizeof(u32) * HAL_SRNG_RING_ID_MAX;
120262306a36Sopenharmony_ci	dma_free_coherent(ab->dev, size,
120362306a36Sopenharmony_ci			  hal->rdp.vaddr, hal->rdp.paddr);
120462306a36Sopenharmony_ci	hal->rdp.vaddr = NULL;
120562306a36Sopenharmony_ci}
120662306a36Sopenharmony_ci
120762306a36Sopenharmony_cistatic int ath12k_hal_alloc_cont_wrp(struct ath12k_base *ab)
120862306a36Sopenharmony_ci{
120962306a36Sopenharmony_ci	struct ath12k_hal *hal = &ab->hal;
121062306a36Sopenharmony_ci	size_t size;
121162306a36Sopenharmony_ci
121262306a36Sopenharmony_ci	size = sizeof(u32) * (HAL_SRNG_NUM_PMAC_RINGS + HAL_SRNG_NUM_DMAC_RINGS);
121362306a36Sopenharmony_ci	hal->wrp.vaddr = dma_alloc_coherent(ab->dev, size, &hal->wrp.paddr,
121462306a36Sopenharmony_ci					    GFP_KERNEL);
121562306a36Sopenharmony_ci	if (!hal->wrp.vaddr)
121662306a36Sopenharmony_ci		return -ENOMEM;
121762306a36Sopenharmony_ci
121862306a36Sopenharmony_ci	return 0;
121962306a36Sopenharmony_ci}
122062306a36Sopenharmony_ci
122162306a36Sopenharmony_cistatic void ath12k_hal_free_cont_wrp(struct ath12k_base *ab)
122262306a36Sopenharmony_ci{
122362306a36Sopenharmony_ci	struct ath12k_hal *hal = &ab->hal;
122462306a36Sopenharmony_ci	size_t size;
122562306a36Sopenharmony_ci
122662306a36Sopenharmony_ci	if (!hal->wrp.vaddr)
122762306a36Sopenharmony_ci		return;
122862306a36Sopenharmony_ci
122962306a36Sopenharmony_ci	size = sizeof(u32) * (HAL_SRNG_NUM_PMAC_RINGS + HAL_SRNG_NUM_DMAC_RINGS);
123062306a36Sopenharmony_ci	dma_free_coherent(ab->dev, size,
123162306a36Sopenharmony_ci			  hal->wrp.vaddr, hal->wrp.paddr);
123262306a36Sopenharmony_ci	hal->wrp.vaddr = NULL;
123362306a36Sopenharmony_ci}
123462306a36Sopenharmony_ci
123562306a36Sopenharmony_cistatic void ath12k_hal_ce_dst_setup(struct ath12k_base *ab,
123662306a36Sopenharmony_ci				    struct hal_srng *srng, int ring_num)
123762306a36Sopenharmony_ci{
123862306a36Sopenharmony_ci	struct hal_srng_config *srng_config = &ab->hal.srng_config[HAL_CE_DST];
123962306a36Sopenharmony_ci	u32 addr;
124062306a36Sopenharmony_ci	u32 val;
124162306a36Sopenharmony_ci
124262306a36Sopenharmony_ci	addr = HAL_CE_DST_RING_CTRL +
124362306a36Sopenharmony_ci	       srng_config->reg_start[HAL_SRNG_REG_GRP_R0] +
124462306a36Sopenharmony_ci	       ring_num * srng_config->reg_size[HAL_SRNG_REG_GRP_R0];
124562306a36Sopenharmony_ci
124662306a36Sopenharmony_ci	val = ath12k_hif_read32(ab, addr);
124762306a36Sopenharmony_ci	val &= ~HAL_CE_DST_R0_DEST_CTRL_MAX_LEN;
124862306a36Sopenharmony_ci	val |= u32_encode_bits(srng->u.dst_ring.max_buffer_length,
124962306a36Sopenharmony_ci			       HAL_CE_DST_R0_DEST_CTRL_MAX_LEN);
125062306a36Sopenharmony_ci	ath12k_hif_write32(ab, addr, val);
125162306a36Sopenharmony_ci}
125262306a36Sopenharmony_ci
125362306a36Sopenharmony_cistatic void ath12k_hal_srng_dst_hw_init(struct ath12k_base *ab,
125462306a36Sopenharmony_ci					struct hal_srng *srng)
125562306a36Sopenharmony_ci{
125662306a36Sopenharmony_ci	struct ath12k_hal *hal = &ab->hal;
125762306a36Sopenharmony_ci	u32 val;
125862306a36Sopenharmony_ci	u64 hp_addr;
125962306a36Sopenharmony_ci	u32 reg_base;
126062306a36Sopenharmony_ci
126162306a36Sopenharmony_ci	reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0];
126262306a36Sopenharmony_ci
126362306a36Sopenharmony_ci	if (srng->flags & HAL_SRNG_FLAGS_MSI_INTR) {
126462306a36Sopenharmony_ci		ath12k_hif_write32(ab, reg_base +
126562306a36Sopenharmony_ci				   ath12k_hal_reo1_ring_msi1_base_lsb_offset(ab),
126662306a36Sopenharmony_ci				   srng->msi_addr);
126762306a36Sopenharmony_ci
126862306a36Sopenharmony_ci		val = u32_encode_bits(((u64)srng->msi_addr >> HAL_ADDR_MSB_REG_SHIFT),
126962306a36Sopenharmony_ci				      HAL_REO1_RING_MSI1_BASE_MSB_ADDR) |
127062306a36Sopenharmony_ci				      HAL_REO1_RING_MSI1_BASE_MSB_MSI1_ENABLE;
127162306a36Sopenharmony_ci		ath12k_hif_write32(ab, reg_base +
127262306a36Sopenharmony_ci				   ath12k_hal_reo1_ring_msi1_base_msb_offset(ab), val);
127362306a36Sopenharmony_ci
127462306a36Sopenharmony_ci		ath12k_hif_write32(ab,
127562306a36Sopenharmony_ci				   reg_base + ath12k_hal_reo1_ring_msi1_data_offset(ab),
127662306a36Sopenharmony_ci				   srng->msi_data);
127762306a36Sopenharmony_ci	}
127862306a36Sopenharmony_ci
127962306a36Sopenharmony_ci	ath12k_hif_write32(ab, reg_base, srng->ring_base_paddr);
128062306a36Sopenharmony_ci
128162306a36Sopenharmony_ci	val = u32_encode_bits(((u64)srng->ring_base_paddr >> HAL_ADDR_MSB_REG_SHIFT),
128262306a36Sopenharmony_ci			      HAL_REO1_RING_BASE_MSB_RING_BASE_ADDR_MSB) |
128362306a36Sopenharmony_ci	      u32_encode_bits((srng->entry_size * srng->num_entries),
128462306a36Sopenharmony_ci			      HAL_REO1_RING_BASE_MSB_RING_SIZE);
128562306a36Sopenharmony_ci	ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_base_msb_offset(ab), val);
128662306a36Sopenharmony_ci
128762306a36Sopenharmony_ci	val = u32_encode_bits(srng->ring_id, HAL_REO1_RING_ID_RING_ID) |
128862306a36Sopenharmony_ci	      u32_encode_bits(srng->entry_size, HAL_REO1_RING_ID_ENTRY_SIZE);
128962306a36Sopenharmony_ci	ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_id_offset(ab), val);
129062306a36Sopenharmony_ci
129162306a36Sopenharmony_ci	/* interrupt setup */
129262306a36Sopenharmony_ci	val = u32_encode_bits((srng->intr_timer_thres_us >> 3),
129362306a36Sopenharmony_ci			      HAL_REO1_RING_PRDR_INT_SETUP_INTR_TMR_THOLD);
129462306a36Sopenharmony_ci
129562306a36Sopenharmony_ci	val |= u32_encode_bits((srng->intr_batch_cntr_thres_entries * srng->entry_size),
129662306a36Sopenharmony_ci				HAL_REO1_RING_PRDR_INT_SETUP_BATCH_COUNTER_THOLD);
129762306a36Sopenharmony_ci
129862306a36Sopenharmony_ci	ath12k_hif_write32(ab,
129962306a36Sopenharmony_ci			   reg_base + ath12k_hal_reo1_ring_producer_int_setup_offset(ab),
130062306a36Sopenharmony_ci			   val);
130162306a36Sopenharmony_ci
130262306a36Sopenharmony_ci	hp_addr = hal->rdp.paddr +
130362306a36Sopenharmony_ci		  ((unsigned long)srng->u.dst_ring.hp_addr -
130462306a36Sopenharmony_ci		   (unsigned long)hal->rdp.vaddr);
130562306a36Sopenharmony_ci	ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_hp_addr_lsb_offset(ab),
130662306a36Sopenharmony_ci			   hp_addr & HAL_ADDR_LSB_REG_MASK);
130762306a36Sopenharmony_ci	ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_hp_addr_msb_offset(ab),
130862306a36Sopenharmony_ci			   hp_addr >> HAL_ADDR_MSB_REG_SHIFT);
130962306a36Sopenharmony_ci
131062306a36Sopenharmony_ci	/* Initialize head and tail pointers to indicate ring is empty */
131162306a36Sopenharmony_ci	reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2];
131262306a36Sopenharmony_ci	ath12k_hif_write32(ab, reg_base, 0);
131362306a36Sopenharmony_ci	ath12k_hif_write32(ab, reg_base + HAL_REO1_RING_TP_OFFSET, 0);
131462306a36Sopenharmony_ci	*srng->u.dst_ring.hp_addr = 0;
131562306a36Sopenharmony_ci
131662306a36Sopenharmony_ci	reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0];
131762306a36Sopenharmony_ci	val = 0;
131862306a36Sopenharmony_ci	if (srng->flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP)
131962306a36Sopenharmony_ci		val |= HAL_REO1_RING_MISC_DATA_TLV_SWAP;
132062306a36Sopenharmony_ci	if (srng->flags & HAL_SRNG_FLAGS_RING_PTR_SWAP)
132162306a36Sopenharmony_ci		val |= HAL_REO1_RING_MISC_HOST_FW_SWAP;
132262306a36Sopenharmony_ci	if (srng->flags & HAL_SRNG_FLAGS_MSI_SWAP)
132362306a36Sopenharmony_ci		val |= HAL_REO1_RING_MISC_MSI_SWAP;
132462306a36Sopenharmony_ci	val |= HAL_REO1_RING_MISC_SRNG_ENABLE;
132562306a36Sopenharmony_ci
132662306a36Sopenharmony_ci	ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_misc_offset(ab), val);
132762306a36Sopenharmony_ci}
132862306a36Sopenharmony_ci
132962306a36Sopenharmony_cistatic void ath12k_hal_srng_src_hw_init(struct ath12k_base *ab,
133062306a36Sopenharmony_ci					struct hal_srng *srng)
133162306a36Sopenharmony_ci{
133262306a36Sopenharmony_ci	struct ath12k_hal *hal = &ab->hal;
133362306a36Sopenharmony_ci	u32 val;
133462306a36Sopenharmony_ci	u64 tp_addr;
133562306a36Sopenharmony_ci	u32 reg_base;
133662306a36Sopenharmony_ci
133762306a36Sopenharmony_ci	reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0];
133862306a36Sopenharmony_ci
133962306a36Sopenharmony_ci	if (srng->flags & HAL_SRNG_FLAGS_MSI_INTR) {
134062306a36Sopenharmony_ci		ath12k_hif_write32(ab, reg_base +
134162306a36Sopenharmony_ci				   HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET(ab),
134262306a36Sopenharmony_ci				   srng->msi_addr);
134362306a36Sopenharmony_ci
134462306a36Sopenharmony_ci		val = u32_encode_bits(((u64)srng->msi_addr >> HAL_ADDR_MSB_REG_SHIFT),
134562306a36Sopenharmony_ci				      HAL_TCL1_RING_MSI1_BASE_MSB_ADDR) |
134662306a36Sopenharmony_ci				      HAL_TCL1_RING_MSI1_BASE_MSB_MSI1_ENABLE;
134762306a36Sopenharmony_ci		ath12k_hif_write32(ab, reg_base +
134862306a36Sopenharmony_ci				       HAL_TCL1_RING_MSI1_BASE_MSB_OFFSET(ab),
134962306a36Sopenharmony_ci				   val);
135062306a36Sopenharmony_ci
135162306a36Sopenharmony_ci		ath12k_hif_write32(ab, reg_base +
135262306a36Sopenharmony_ci				       HAL_TCL1_RING_MSI1_DATA_OFFSET(ab),
135362306a36Sopenharmony_ci				   srng->msi_data);
135462306a36Sopenharmony_ci	}
135562306a36Sopenharmony_ci
135662306a36Sopenharmony_ci	ath12k_hif_write32(ab, reg_base, srng->ring_base_paddr);
135762306a36Sopenharmony_ci
135862306a36Sopenharmony_ci	val = u32_encode_bits(((u64)srng->ring_base_paddr >> HAL_ADDR_MSB_REG_SHIFT),
135962306a36Sopenharmony_ci			      HAL_TCL1_RING_BASE_MSB_RING_BASE_ADDR_MSB) |
136062306a36Sopenharmony_ci	      u32_encode_bits((srng->entry_size * srng->num_entries),
136162306a36Sopenharmony_ci			      HAL_TCL1_RING_BASE_MSB_RING_SIZE);
136262306a36Sopenharmony_ci	ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_BASE_MSB_OFFSET, val);
136362306a36Sopenharmony_ci
136462306a36Sopenharmony_ci	val = u32_encode_bits(srng->entry_size, HAL_REO1_RING_ID_ENTRY_SIZE);
136562306a36Sopenharmony_ci	ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_ID_OFFSET(ab), val);
136662306a36Sopenharmony_ci
136762306a36Sopenharmony_ci	val = u32_encode_bits(srng->intr_timer_thres_us,
136862306a36Sopenharmony_ci			      HAL_TCL1_RING_CONSR_INT_SETUP_IX0_INTR_TMR_THOLD);
136962306a36Sopenharmony_ci
137062306a36Sopenharmony_ci	val |= u32_encode_bits((srng->intr_batch_cntr_thres_entries * srng->entry_size),
137162306a36Sopenharmony_ci			       HAL_TCL1_RING_CONSR_INT_SETUP_IX0_BATCH_COUNTER_THOLD);
137262306a36Sopenharmony_ci
137362306a36Sopenharmony_ci	ath12k_hif_write32(ab,
137462306a36Sopenharmony_ci			   reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX0_OFFSET(ab),
137562306a36Sopenharmony_ci			   val);
137662306a36Sopenharmony_ci
137762306a36Sopenharmony_ci	val = 0;
137862306a36Sopenharmony_ci	if (srng->flags & HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN) {
137962306a36Sopenharmony_ci		val |= u32_encode_bits(srng->u.src_ring.low_threshold,
138062306a36Sopenharmony_ci				       HAL_TCL1_RING_CONSR_INT_SETUP_IX1_LOW_THOLD);
138162306a36Sopenharmony_ci	}
138262306a36Sopenharmony_ci	ath12k_hif_write32(ab,
138362306a36Sopenharmony_ci			   reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX1_OFFSET(ab),
138462306a36Sopenharmony_ci			   val);
138562306a36Sopenharmony_ci
138662306a36Sopenharmony_ci	if (srng->ring_id != HAL_SRNG_RING_ID_WBM_IDLE_LINK) {
138762306a36Sopenharmony_ci		tp_addr = hal->rdp.paddr +
138862306a36Sopenharmony_ci			  ((unsigned long)srng->u.src_ring.tp_addr -
138962306a36Sopenharmony_ci			   (unsigned long)hal->rdp.vaddr);
139062306a36Sopenharmony_ci		ath12k_hif_write32(ab,
139162306a36Sopenharmony_ci				   reg_base + HAL_TCL1_RING_TP_ADDR_LSB_OFFSET(ab),
139262306a36Sopenharmony_ci				   tp_addr & HAL_ADDR_LSB_REG_MASK);
139362306a36Sopenharmony_ci		ath12k_hif_write32(ab,
139462306a36Sopenharmony_ci				   reg_base + HAL_TCL1_RING_TP_ADDR_MSB_OFFSET(ab),
139562306a36Sopenharmony_ci				   tp_addr >> HAL_ADDR_MSB_REG_SHIFT);
139662306a36Sopenharmony_ci	}
139762306a36Sopenharmony_ci
139862306a36Sopenharmony_ci	/* Initialize head and tail pointers to indicate ring is empty */
139962306a36Sopenharmony_ci	reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2];
140062306a36Sopenharmony_ci	ath12k_hif_write32(ab, reg_base, 0);
140162306a36Sopenharmony_ci	ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_TP_OFFSET, 0);
140262306a36Sopenharmony_ci	*srng->u.src_ring.tp_addr = 0;
140362306a36Sopenharmony_ci
140462306a36Sopenharmony_ci	reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0];
140562306a36Sopenharmony_ci	val = 0;
140662306a36Sopenharmony_ci	if (srng->flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP)
140762306a36Sopenharmony_ci		val |= HAL_TCL1_RING_MISC_DATA_TLV_SWAP;
140862306a36Sopenharmony_ci	if (srng->flags & HAL_SRNG_FLAGS_RING_PTR_SWAP)
140962306a36Sopenharmony_ci		val |= HAL_TCL1_RING_MISC_HOST_FW_SWAP;
141062306a36Sopenharmony_ci	if (srng->flags & HAL_SRNG_FLAGS_MSI_SWAP)
141162306a36Sopenharmony_ci		val |= HAL_TCL1_RING_MISC_MSI_SWAP;
141262306a36Sopenharmony_ci
141362306a36Sopenharmony_ci	/* Loop count is not used for SRC rings */
141462306a36Sopenharmony_ci	val |= HAL_TCL1_RING_MISC_MSI_LOOPCNT_DISABLE;
141562306a36Sopenharmony_ci
141662306a36Sopenharmony_ci	val |= HAL_TCL1_RING_MISC_SRNG_ENABLE;
141762306a36Sopenharmony_ci
141862306a36Sopenharmony_ci	if (srng->ring_id == HAL_SRNG_RING_ID_WBM_IDLE_LINK)
141962306a36Sopenharmony_ci		val |= HAL_TCL1_RING_MISC_MSI_RING_ID_DISABLE;
142062306a36Sopenharmony_ci
142162306a36Sopenharmony_ci	ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_MISC_OFFSET(ab), val);
142262306a36Sopenharmony_ci}
142362306a36Sopenharmony_ci
142462306a36Sopenharmony_cistatic void ath12k_hal_srng_hw_init(struct ath12k_base *ab,
142562306a36Sopenharmony_ci				    struct hal_srng *srng)
142662306a36Sopenharmony_ci{
142762306a36Sopenharmony_ci	if (srng->ring_dir == HAL_SRNG_DIR_SRC)
142862306a36Sopenharmony_ci		ath12k_hal_srng_src_hw_init(ab, srng);
142962306a36Sopenharmony_ci	else
143062306a36Sopenharmony_ci		ath12k_hal_srng_dst_hw_init(ab, srng);
143162306a36Sopenharmony_ci}
143262306a36Sopenharmony_ci
143362306a36Sopenharmony_cistatic int ath12k_hal_srng_get_ring_id(struct ath12k_base *ab,
143462306a36Sopenharmony_ci				       enum hal_ring_type type,
143562306a36Sopenharmony_ci				       int ring_num, int mac_id)
143662306a36Sopenharmony_ci{
143762306a36Sopenharmony_ci	struct hal_srng_config *srng_config = &ab->hal.srng_config[type];
143862306a36Sopenharmony_ci	int ring_id;
143962306a36Sopenharmony_ci
144062306a36Sopenharmony_ci	if (ring_num >= srng_config->max_rings) {
144162306a36Sopenharmony_ci		ath12k_warn(ab, "invalid ring number :%d\n", ring_num);
144262306a36Sopenharmony_ci		return -EINVAL;
144362306a36Sopenharmony_ci	}
144462306a36Sopenharmony_ci
144562306a36Sopenharmony_ci	ring_id = srng_config->start_ring_id + ring_num;
144662306a36Sopenharmony_ci	if (srng_config->mac_type == ATH12K_HAL_SRNG_PMAC)
144762306a36Sopenharmony_ci		ring_id += mac_id * HAL_SRNG_RINGS_PER_PMAC;
144862306a36Sopenharmony_ci
144962306a36Sopenharmony_ci	if (WARN_ON(ring_id >= HAL_SRNG_RING_ID_MAX))
145062306a36Sopenharmony_ci		return -EINVAL;
145162306a36Sopenharmony_ci
145262306a36Sopenharmony_ci	return ring_id;
145362306a36Sopenharmony_ci}
145462306a36Sopenharmony_ci
145562306a36Sopenharmony_ciint ath12k_hal_srng_get_entrysize(struct ath12k_base *ab, u32 ring_type)
145662306a36Sopenharmony_ci{
145762306a36Sopenharmony_ci	struct hal_srng_config *srng_config;
145862306a36Sopenharmony_ci
145962306a36Sopenharmony_ci	if (WARN_ON(ring_type >= HAL_MAX_RING_TYPES))
146062306a36Sopenharmony_ci		return -EINVAL;
146162306a36Sopenharmony_ci
146262306a36Sopenharmony_ci	srng_config = &ab->hal.srng_config[ring_type];
146362306a36Sopenharmony_ci
146462306a36Sopenharmony_ci	return (srng_config->entry_size << 2);
146562306a36Sopenharmony_ci}
146662306a36Sopenharmony_ci
146762306a36Sopenharmony_ciint ath12k_hal_srng_get_max_entries(struct ath12k_base *ab, u32 ring_type)
146862306a36Sopenharmony_ci{
146962306a36Sopenharmony_ci	struct hal_srng_config *srng_config;
147062306a36Sopenharmony_ci
147162306a36Sopenharmony_ci	if (WARN_ON(ring_type >= HAL_MAX_RING_TYPES))
147262306a36Sopenharmony_ci		return -EINVAL;
147362306a36Sopenharmony_ci
147462306a36Sopenharmony_ci	srng_config = &ab->hal.srng_config[ring_type];
147562306a36Sopenharmony_ci
147662306a36Sopenharmony_ci	return (srng_config->max_size / srng_config->entry_size);
147762306a36Sopenharmony_ci}
147862306a36Sopenharmony_ci
147962306a36Sopenharmony_civoid ath12k_hal_srng_get_params(struct ath12k_base *ab, struct hal_srng *srng,
148062306a36Sopenharmony_ci				struct hal_srng_params *params)
148162306a36Sopenharmony_ci{
148262306a36Sopenharmony_ci	params->ring_base_paddr = srng->ring_base_paddr;
148362306a36Sopenharmony_ci	params->ring_base_vaddr = srng->ring_base_vaddr;
148462306a36Sopenharmony_ci	params->num_entries = srng->num_entries;
148562306a36Sopenharmony_ci	params->intr_timer_thres_us = srng->intr_timer_thres_us;
148662306a36Sopenharmony_ci	params->intr_batch_cntr_thres_entries =
148762306a36Sopenharmony_ci		srng->intr_batch_cntr_thres_entries;
148862306a36Sopenharmony_ci	params->low_threshold = srng->u.src_ring.low_threshold;
148962306a36Sopenharmony_ci	params->msi_addr = srng->msi_addr;
149062306a36Sopenharmony_ci	params->msi2_addr = srng->msi2_addr;
149162306a36Sopenharmony_ci	params->msi_data = srng->msi_data;
149262306a36Sopenharmony_ci	params->msi2_data = srng->msi2_data;
149362306a36Sopenharmony_ci	params->flags = srng->flags;
149462306a36Sopenharmony_ci}
149562306a36Sopenharmony_ci
149662306a36Sopenharmony_cidma_addr_t ath12k_hal_srng_get_hp_addr(struct ath12k_base *ab,
149762306a36Sopenharmony_ci				       struct hal_srng *srng)
149862306a36Sopenharmony_ci{
149962306a36Sopenharmony_ci	if (!(srng->flags & HAL_SRNG_FLAGS_LMAC_RING))
150062306a36Sopenharmony_ci		return 0;
150162306a36Sopenharmony_ci
150262306a36Sopenharmony_ci	if (srng->ring_dir == HAL_SRNG_DIR_SRC)
150362306a36Sopenharmony_ci		return ab->hal.wrp.paddr +
150462306a36Sopenharmony_ci		       ((unsigned long)srng->u.src_ring.hp_addr -
150562306a36Sopenharmony_ci			(unsigned long)ab->hal.wrp.vaddr);
150662306a36Sopenharmony_ci	else
150762306a36Sopenharmony_ci		return ab->hal.rdp.paddr +
150862306a36Sopenharmony_ci		       ((unsigned long)srng->u.dst_ring.hp_addr -
150962306a36Sopenharmony_ci			 (unsigned long)ab->hal.rdp.vaddr);
151062306a36Sopenharmony_ci}
151162306a36Sopenharmony_ci
151262306a36Sopenharmony_cidma_addr_t ath12k_hal_srng_get_tp_addr(struct ath12k_base *ab,
151362306a36Sopenharmony_ci				       struct hal_srng *srng)
151462306a36Sopenharmony_ci{
151562306a36Sopenharmony_ci	if (!(srng->flags & HAL_SRNG_FLAGS_LMAC_RING))
151662306a36Sopenharmony_ci		return 0;
151762306a36Sopenharmony_ci
151862306a36Sopenharmony_ci	if (srng->ring_dir == HAL_SRNG_DIR_SRC)
151962306a36Sopenharmony_ci		return ab->hal.rdp.paddr +
152062306a36Sopenharmony_ci		       ((unsigned long)srng->u.src_ring.tp_addr -
152162306a36Sopenharmony_ci			(unsigned long)ab->hal.rdp.vaddr);
152262306a36Sopenharmony_ci	else
152362306a36Sopenharmony_ci		return ab->hal.wrp.paddr +
152462306a36Sopenharmony_ci		       ((unsigned long)srng->u.dst_ring.tp_addr -
152562306a36Sopenharmony_ci			(unsigned long)ab->hal.wrp.vaddr);
152662306a36Sopenharmony_ci}
152762306a36Sopenharmony_ci
152862306a36Sopenharmony_ciu32 ath12k_hal_ce_get_desc_size(enum hal_ce_desc type)
152962306a36Sopenharmony_ci{
153062306a36Sopenharmony_ci	switch (type) {
153162306a36Sopenharmony_ci	case HAL_CE_DESC_SRC:
153262306a36Sopenharmony_ci		return sizeof(struct hal_ce_srng_src_desc);
153362306a36Sopenharmony_ci	case HAL_CE_DESC_DST:
153462306a36Sopenharmony_ci		return sizeof(struct hal_ce_srng_dest_desc);
153562306a36Sopenharmony_ci	case HAL_CE_DESC_DST_STATUS:
153662306a36Sopenharmony_ci		return sizeof(struct hal_ce_srng_dst_status_desc);
153762306a36Sopenharmony_ci	}
153862306a36Sopenharmony_ci
153962306a36Sopenharmony_ci	return 0;
154062306a36Sopenharmony_ci}
154162306a36Sopenharmony_ci
154262306a36Sopenharmony_civoid ath12k_hal_ce_src_set_desc(struct hal_ce_srng_src_desc *desc, dma_addr_t paddr,
154362306a36Sopenharmony_ci				u32 len, u32 id, u8 byte_swap_data)
154462306a36Sopenharmony_ci{
154562306a36Sopenharmony_ci	desc->buffer_addr_low = cpu_to_le32(paddr & HAL_ADDR_LSB_REG_MASK);
154662306a36Sopenharmony_ci	desc->buffer_addr_info =
154762306a36Sopenharmony_ci		le32_encode_bits(((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT),
154862306a36Sopenharmony_ci				 HAL_CE_SRC_DESC_ADDR_INFO_ADDR_HI) |
154962306a36Sopenharmony_ci		le32_encode_bits(byte_swap_data,
155062306a36Sopenharmony_ci				 HAL_CE_SRC_DESC_ADDR_INFO_BYTE_SWAP) |
155162306a36Sopenharmony_ci		le32_encode_bits(0, HAL_CE_SRC_DESC_ADDR_INFO_GATHER) |
155262306a36Sopenharmony_ci		le32_encode_bits(len, HAL_CE_SRC_DESC_ADDR_INFO_LEN);
155362306a36Sopenharmony_ci	desc->meta_info = le32_encode_bits(id, HAL_CE_SRC_DESC_META_INFO_DATA);
155462306a36Sopenharmony_ci}
155562306a36Sopenharmony_ci
155662306a36Sopenharmony_civoid ath12k_hal_ce_dst_set_desc(struct hal_ce_srng_dest_desc *desc, dma_addr_t paddr)
155762306a36Sopenharmony_ci{
155862306a36Sopenharmony_ci	desc->buffer_addr_low = cpu_to_le32(paddr & HAL_ADDR_LSB_REG_MASK);
155962306a36Sopenharmony_ci	desc->buffer_addr_info =
156062306a36Sopenharmony_ci		le32_encode_bits(((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT),
156162306a36Sopenharmony_ci				 HAL_CE_DEST_DESC_ADDR_INFO_ADDR_HI);
156262306a36Sopenharmony_ci}
156362306a36Sopenharmony_ci
156462306a36Sopenharmony_ciu32 ath12k_hal_ce_dst_status_get_length(struct hal_ce_srng_dst_status_desc *desc)
156562306a36Sopenharmony_ci{
156662306a36Sopenharmony_ci	u32 len;
156762306a36Sopenharmony_ci
156862306a36Sopenharmony_ci	len = le32_get_bits(desc->flags, HAL_CE_DST_STATUS_DESC_FLAGS_LEN);
156962306a36Sopenharmony_ci	desc->flags &= ~cpu_to_le32(HAL_CE_DST_STATUS_DESC_FLAGS_LEN);
157062306a36Sopenharmony_ci
157162306a36Sopenharmony_ci	return len;
157262306a36Sopenharmony_ci}
157362306a36Sopenharmony_ci
157462306a36Sopenharmony_civoid ath12k_hal_set_link_desc_addr(struct hal_wbm_link_desc *desc, u32 cookie,
157562306a36Sopenharmony_ci				   dma_addr_t paddr)
157662306a36Sopenharmony_ci{
157762306a36Sopenharmony_ci	desc->buf_addr_info.info0 = le32_encode_bits((paddr & HAL_ADDR_LSB_REG_MASK),
157862306a36Sopenharmony_ci						     BUFFER_ADDR_INFO0_ADDR);
157962306a36Sopenharmony_ci	desc->buf_addr_info.info1 =
158062306a36Sopenharmony_ci			le32_encode_bits(((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT),
158162306a36Sopenharmony_ci					 BUFFER_ADDR_INFO1_ADDR) |
158262306a36Sopenharmony_ci			le32_encode_bits(1, BUFFER_ADDR_INFO1_RET_BUF_MGR) |
158362306a36Sopenharmony_ci			le32_encode_bits(cookie, BUFFER_ADDR_INFO1_SW_COOKIE);
158462306a36Sopenharmony_ci}
158562306a36Sopenharmony_ci
158662306a36Sopenharmony_civoid *ath12k_hal_srng_dst_peek(struct ath12k_base *ab, struct hal_srng *srng)
158762306a36Sopenharmony_ci{
158862306a36Sopenharmony_ci	lockdep_assert_held(&srng->lock);
158962306a36Sopenharmony_ci
159062306a36Sopenharmony_ci	if (srng->u.dst_ring.tp != srng->u.dst_ring.cached_hp)
159162306a36Sopenharmony_ci		return (srng->ring_base_vaddr + srng->u.dst_ring.tp);
159262306a36Sopenharmony_ci
159362306a36Sopenharmony_ci	return NULL;
159462306a36Sopenharmony_ci}
159562306a36Sopenharmony_ci
159662306a36Sopenharmony_civoid *ath12k_hal_srng_dst_get_next_entry(struct ath12k_base *ab,
159762306a36Sopenharmony_ci					 struct hal_srng *srng)
159862306a36Sopenharmony_ci{
159962306a36Sopenharmony_ci	void *desc;
160062306a36Sopenharmony_ci
160162306a36Sopenharmony_ci	lockdep_assert_held(&srng->lock);
160262306a36Sopenharmony_ci
160362306a36Sopenharmony_ci	if (srng->u.dst_ring.tp == srng->u.dst_ring.cached_hp)
160462306a36Sopenharmony_ci		return NULL;
160562306a36Sopenharmony_ci
160662306a36Sopenharmony_ci	desc = srng->ring_base_vaddr + srng->u.dst_ring.tp;
160762306a36Sopenharmony_ci
160862306a36Sopenharmony_ci	srng->u.dst_ring.tp = (srng->u.dst_ring.tp + srng->entry_size) %
160962306a36Sopenharmony_ci			      srng->ring_size;
161062306a36Sopenharmony_ci
161162306a36Sopenharmony_ci	return desc;
161262306a36Sopenharmony_ci}
161362306a36Sopenharmony_ci
161462306a36Sopenharmony_ciint ath12k_hal_srng_dst_num_free(struct ath12k_base *ab, struct hal_srng *srng,
161562306a36Sopenharmony_ci				 bool sync_hw_ptr)
161662306a36Sopenharmony_ci{
161762306a36Sopenharmony_ci	u32 tp, hp;
161862306a36Sopenharmony_ci
161962306a36Sopenharmony_ci	lockdep_assert_held(&srng->lock);
162062306a36Sopenharmony_ci
162162306a36Sopenharmony_ci	tp = srng->u.dst_ring.tp;
162262306a36Sopenharmony_ci
162362306a36Sopenharmony_ci	if (sync_hw_ptr) {
162462306a36Sopenharmony_ci		hp = *srng->u.dst_ring.hp_addr;
162562306a36Sopenharmony_ci		srng->u.dst_ring.cached_hp = hp;
162662306a36Sopenharmony_ci	} else {
162762306a36Sopenharmony_ci		hp = srng->u.dst_ring.cached_hp;
162862306a36Sopenharmony_ci	}
162962306a36Sopenharmony_ci
163062306a36Sopenharmony_ci	if (hp >= tp)
163162306a36Sopenharmony_ci		return (hp - tp) / srng->entry_size;
163262306a36Sopenharmony_ci	else
163362306a36Sopenharmony_ci		return (srng->ring_size - tp + hp) / srng->entry_size;
163462306a36Sopenharmony_ci}
163562306a36Sopenharmony_ci
163662306a36Sopenharmony_ci/* Returns number of available entries in src ring */
163762306a36Sopenharmony_ciint ath12k_hal_srng_src_num_free(struct ath12k_base *ab, struct hal_srng *srng,
163862306a36Sopenharmony_ci				 bool sync_hw_ptr)
163962306a36Sopenharmony_ci{
164062306a36Sopenharmony_ci	u32 tp, hp;
164162306a36Sopenharmony_ci
164262306a36Sopenharmony_ci	lockdep_assert_held(&srng->lock);
164362306a36Sopenharmony_ci
164462306a36Sopenharmony_ci	hp = srng->u.src_ring.hp;
164562306a36Sopenharmony_ci
164662306a36Sopenharmony_ci	if (sync_hw_ptr) {
164762306a36Sopenharmony_ci		tp = *srng->u.src_ring.tp_addr;
164862306a36Sopenharmony_ci		srng->u.src_ring.cached_tp = tp;
164962306a36Sopenharmony_ci	} else {
165062306a36Sopenharmony_ci		tp = srng->u.src_ring.cached_tp;
165162306a36Sopenharmony_ci	}
165262306a36Sopenharmony_ci
165362306a36Sopenharmony_ci	if (tp > hp)
165462306a36Sopenharmony_ci		return ((tp - hp) / srng->entry_size) - 1;
165562306a36Sopenharmony_ci	else
165662306a36Sopenharmony_ci		return ((srng->ring_size - hp + tp) / srng->entry_size) - 1;
165762306a36Sopenharmony_ci}
165862306a36Sopenharmony_ci
165962306a36Sopenharmony_civoid *ath12k_hal_srng_src_get_next_entry(struct ath12k_base *ab,
166062306a36Sopenharmony_ci					 struct hal_srng *srng)
166162306a36Sopenharmony_ci{
166262306a36Sopenharmony_ci	void *desc;
166362306a36Sopenharmony_ci	u32 next_hp;
166462306a36Sopenharmony_ci
166562306a36Sopenharmony_ci	lockdep_assert_held(&srng->lock);
166662306a36Sopenharmony_ci
166762306a36Sopenharmony_ci	/* TODO: Using % is expensive, but we have to do this since size of some
166862306a36Sopenharmony_ci	 * SRNG rings is not power of 2 (due to descriptor sizes). Need to see
166962306a36Sopenharmony_ci	 * if separate function is defined for rings having power of 2 ring size
167062306a36Sopenharmony_ci	 * (TCL2SW, REO2SW, SW2RXDMA and CE rings) so that we can avoid the
167162306a36Sopenharmony_ci	 * overhead of % by using mask (with &).
167262306a36Sopenharmony_ci	 */
167362306a36Sopenharmony_ci	next_hp = (srng->u.src_ring.hp + srng->entry_size) % srng->ring_size;
167462306a36Sopenharmony_ci
167562306a36Sopenharmony_ci	if (next_hp == srng->u.src_ring.cached_tp)
167662306a36Sopenharmony_ci		return NULL;
167762306a36Sopenharmony_ci
167862306a36Sopenharmony_ci	desc = srng->ring_base_vaddr + srng->u.src_ring.hp;
167962306a36Sopenharmony_ci	srng->u.src_ring.hp = next_hp;
168062306a36Sopenharmony_ci
168162306a36Sopenharmony_ci	/* TODO: Reap functionality is not used by all rings. If particular
168262306a36Sopenharmony_ci	 * ring does not use reap functionality, we need not update reap_hp
168362306a36Sopenharmony_ci	 * with next_hp pointer. Need to make sure a separate function is used
168462306a36Sopenharmony_ci	 * before doing any optimization by removing below code updating
168562306a36Sopenharmony_ci	 * reap_hp.
168662306a36Sopenharmony_ci	 */
168762306a36Sopenharmony_ci	srng->u.src_ring.reap_hp = next_hp;
168862306a36Sopenharmony_ci
168962306a36Sopenharmony_ci	return desc;
169062306a36Sopenharmony_ci}
169162306a36Sopenharmony_ci
169262306a36Sopenharmony_civoid *ath12k_hal_srng_src_reap_next(struct ath12k_base *ab,
169362306a36Sopenharmony_ci				    struct hal_srng *srng)
169462306a36Sopenharmony_ci{
169562306a36Sopenharmony_ci	void *desc;
169662306a36Sopenharmony_ci	u32 next_reap_hp;
169762306a36Sopenharmony_ci
169862306a36Sopenharmony_ci	lockdep_assert_held(&srng->lock);
169962306a36Sopenharmony_ci
170062306a36Sopenharmony_ci	next_reap_hp = (srng->u.src_ring.reap_hp + srng->entry_size) %
170162306a36Sopenharmony_ci		       srng->ring_size;
170262306a36Sopenharmony_ci
170362306a36Sopenharmony_ci	if (next_reap_hp == srng->u.src_ring.cached_tp)
170462306a36Sopenharmony_ci		return NULL;
170562306a36Sopenharmony_ci
170662306a36Sopenharmony_ci	desc = srng->ring_base_vaddr + next_reap_hp;
170762306a36Sopenharmony_ci	srng->u.src_ring.reap_hp = next_reap_hp;
170862306a36Sopenharmony_ci
170962306a36Sopenharmony_ci	return desc;
171062306a36Sopenharmony_ci}
171162306a36Sopenharmony_ci
171262306a36Sopenharmony_civoid *ath12k_hal_srng_src_get_next_reaped(struct ath12k_base *ab,
171362306a36Sopenharmony_ci					  struct hal_srng *srng)
171462306a36Sopenharmony_ci{
171562306a36Sopenharmony_ci	void *desc;
171662306a36Sopenharmony_ci
171762306a36Sopenharmony_ci	lockdep_assert_held(&srng->lock);
171862306a36Sopenharmony_ci
171962306a36Sopenharmony_ci	if (srng->u.src_ring.hp == srng->u.src_ring.reap_hp)
172062306a36Sopenharmony_ci		return NULL;
172162306a36Sopenharmony_ci
172262306a36Sopenharmony_ci	desc = srng->ring_base_vaddr + srng->u.src_ring.hp;
172362306a36Sopenharmony_ci	srng->u.src_ring.hp = (srng->u.src_ring.hp + srng->entry_size) %
172462306a36Sopenharmony_ci			      srng->ring_size;
172562306a36Sopenharmony_ci
172662306a36Sopenharmony_ci	return desc;
172762306a36Sopenharmony_ci}
172862306a36Sopenharmony_ci
172962306a36Sopenharmony_civoid ath12k_hal_srng_access_begin(struct ath12k_base *ab, struct hal_srng *srng)
173062306a36Sopenharmony_ci{
173162306a36Sopenharmony_ci	lockdep_assert_held(&srng->lock);
173262306a36Sopenharmony_ci
173362306a36Sopenharmony_ci	if (srng->ring_dir == HAL_SRNG_DIR_SRC)
173462306a36Sopenharmony_ci		srng->u.src_ring.cached_tp =
173562306a36Sopenharmony_ci			*(volatile u32 *)srng->u.src_ring.tp_addr;
173662306a36Sopenharmony_ci	else
173762306a36Sopenharmony_ci		srng->u.dst_ring.cached_hp = *srng->u.dst_ring.hp_addr;
173862306a36Sopenharmony_ci}
173962306a36Sopenharmony_ci
174062306a36Sopenharmony_ci/* Update cached ring head/tail pointers to HW. ath12k_hal_srng_access_begin()
174162306a36Sopenharmony_ci * should have been called before this.
174262306a36Sopenharmony_ci */
174362306a36Sopenharmony_civoid ath12k_hal_srng_access_end(struct ath12k_base *ab, struct hal_srng *srng)
174462306a36Sopenharmony_ci{
174562306a36Sopenharmony_ci	lockdep_assert_held(&srng->lock);
174662306a36Sopenharmony_ci
174762306a36Sopenharmony_ci	/* TODO: See if we need a write memory barrier here */
174862306a36Sopenharmony_ci	if (srng->flags & HAL_SRNG_FLAGS_LMAC_RING) {
174962306a36Sopenharmony_ci		/* For LMAC rings, ring pointer updates are done through FW and
175062306a36Sopenharmony_ci		 * hence written to a shared memory location that is read by FW
175162306a36Sopenharmony_ci		 */
175262306a36Sopenharmony_ci		if (srng->ring_dir == HAL_SRNG_DIR_SRC) {
175362306a36Sopenharmony_ci			srng->u.src_ring.last_tp =
175462306a36Sopenharmony_ci				*(volatile u32 *)srng->u.src_ring.tp_addr;
175562306a36Sopenharmony_ci			*srng->u.src_ring.hp_addr = srng->u.src_ring.hp;
175662306a36Sopenharmony_ci		} else {
175762306a36Sopenharmony_ci			srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr;
175862306a36Sopenharmony_ci			*srng->u.dst_ring.tp_addr = srng->u.dst_ring.tp;
175962306a36Sopenharmony_ci		}
176062306a36Sopenharmony_ci	} else {
176162306a36Sopenharmony_ci		if (srng->ring_dir == HAL_SRNG_DIR_SRC) {
176262306a36Sopenharmony_ci			srng->u.src_ring.last_tp =
176362306a36Sopenharmony_ci				*(volatile u32 *)srng->u.src_ring.tp_addr;
176462306a36Sopenharmony_ci			ath12k_hif_write32(ab,
176562306a36Sopenharmony_ci					   (unsigned long)srng->u.src_ring.hp_addr -
176662306a36Sopenharmony_ci					   (unsigned long)ab->mem,
176762306a36Sopenharmony_ci					   srng->u.src_ring.hp);
176862306a36Sopenharmony_ci		} else {
176962306a36Sopenharmony_ci			srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr;
177062306a36Sopenharmony_ci			ath12k_hif_write32(ab,
177162306a36Sopenharmony_ci					   (unsigned long)srng->u.dst_ring.tp_addr -
177262306a36Sopenharmony_ci					   (unsigned long)ab->mem,
177362306a36Sopenharmony_ci					   srng->u.dst_ring.tp);
177462306a36Sopenharmony_ci		}
177562306a36Sopenharmony_ci	}
177662306a36Sopenharmony_ci
177762306a36Sopenharmony_ci	srng->timestamp = jiffies;
177862306a36Sopenharmony_ci}
177962306a36Sopenharmony_ci
178062306a36Sopenharmony_civoid ath12k_hal_setup_link_idle_list(struct ath12k_base *ab,
178162306a36Sopenharmony_ci				     struct hal_wbm_idle_scatter_list *sbuf,
178262306a36Sopenharmony_ci				     u32 nsbufs, u32 tot_link_desc,
178362306a36Sopenharmony_ci				     u32 end_offset)
178462306a36Sopenharmony_ci{
178562306a36Sopenharmony_ci	struct ath12k_buffer_addr *link_addr;
178662306a36Sopenharmony_ci	int i;
178762306a36Sopenharmony_ci	u32 reg_scatter_buf_sz = HAL_WBM_IDLE_SCATTER_BUF_SIZE / 64;
178862306a36Sopenharmony_ci	u32 val;
178962306a36Sopenharmony_ci
179062306a36Sopenharmony_ci	link_addr = (void *)sbuf[0].vaddr + HAL_WBM_IDLE_SCATTER_BUF_SIZE;
179162306a36Sopenharmony_ci
179262306a36Sopenharmony_ci	for (i = 1; i < nsbufs; i++) {
179362306a36Sopenharmony_ci		link_addr->info0 = cpu_to_le32(sbuf[i].paddr & HAL_ADDR_LSB_REG_MASK);
179462306a36Sopenharmony_ci
179562306a36Sopenharmony_ci		link_addr->info1 =
179662306a36Sopenharmony_ci			le32_encode_bits((u64)sbuf[i].paddr >> HAL_ADDR_MSB_REG_SHIFT,
179762306a36Sopenharmony_ci					 HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32) |
179862306a36Sopenharmony_ci			le32_encode_bits(BASE_ADDR_MATCH_TAG_VAL,
179962306a36Sopenharmony_ci					 HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_MATCH_TAG);
180062306a36Sopenharmony_ci
180162306a36Sopenharmony_ci		link_addr = (void *)sbuf[i].vaddr +
180262306a36Sopenharmony_ci			     HAL_WBM_IDLE_SCATTER_BUF_SIZE;
180362306a36Sopenharmony_ci	}
180462306a36Sopenharmony_ci
180562306a36Sopenharmony_ci	val = u32_encode_bits(reg_scatter_buf_sz, HAL_WBM_SCATTER_BUFFER_SIZE) |
180662306a36Sopenharmony_ci	      u32_encode_bits(0x1, HAL_WBM_LINK_DESC_IDLE_LIST_MODE);
180762306a36Sopenharmony_ci
180862306a36Sopenharmony_ci	ath12k_hif_write32(ab,
180962306a36Sopenharmony_ci			   HAL_SEQ_WCSS_UMAC_WBM_REG +
181062306a36Sopenharmony_ci			   HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR(ab),
181162306a36Sopenharmony_ci			   val);
181262306a36Sopenharmony_ci
181362306a36Sopenharmony_ci	val = u32_encode_bits(reg_scatter_buf_sz * nsbufs,
181462306a36Sopenharmony_ci			      HAL_WBM_SCATTER_RING_SIZE_OF_IDLE_LINK_DESC_LIST);
181562306a36Sopenharmony_ci	ath12k_hif_write32(ab,
181662306a36Sopenharmony_ci			   HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_R0_IDLE_LIST_SIZE_ADDR(ab),
181762306a36Sopenharmony_ci			   val);
181862306a36Sopenharmony_ci
181962306a36Sopenharmony_ci	val = u32_encode_bits(sbuf[0].paddr & HAL_ADDR_LSB_REG_MASK,
182062306a36Sopenharmony_ci			      BUFFER_ADDR_INFO0_ADDR);
182162306a36Sopenharmony_ci	ath12k_hif_write32(ab,
182262306a36Sopenharmony_ci			   HAL_SEQ_WCSS_UMAC_WBM_REG +
182362306a36Sopenharmony_ci			   HAL_WBM_SCATTERED_RING_BASE_LSB(ab),
182462306a36Sopenharmony_ci			   val);
182562306a36Sopenharmony_ci
182662306a36Sopenharmony_ci	val = u32_encode_bits(BASE_ADDR_MATCH_TAG_VAL,
182762306a36Sopenharmony_ci			      HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_MATCH_TAG) |
182862306a36Sopenharmony_ci	      u32_encode_bits((u64)sbuf[0].paddr >> HAL_ADDR_MSB_REG_SHIFT,
182962306a36Sopenharmony_ci			      HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32);
183062306a36Sopenharmony_ci	ath12k_hif_write32(ab,
183162306a36Sopenharmony_ci			   HAL_SEQ_WCSS_UMAC_WBM_REG +
183262306a36Sopenharmony_ci			   HAL_WBM_SCATTERED_RING_BASE_MSB(ab),
183362306a36Sopenharmony_ci			   val);
183462306a36Sopenharmony_ci
183562306a36Sopenharmony_ci	/* Setup head and tail pointers for the idle list */
183662306a36Sopenharmony_ci	val = u32_encode_bits(sbuf[nsbufs - 1].paddr, BUFFER_ADDR_INFO0_ADDR);
183762306a36Sopenharmony_ci	ath12k_hif_write32(ab,
183862306a36Sopenharmony_ci			   HAL_SEQ_WCSS_UMAC_WBM_REG +
183962306a36Sopenharmony_ci			   HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(ab),
184062306a36Sopenharmony_ci			   val);
184162306a36Sopenharmony_ci
184262306a36Sopenharmony_ci	val = u32_encode_bits(((u64)sbuf[nsbufs - 1].paddr >> HAL_ADDR_MSB_REG_SHIFT),
184362306a36Sopenharmony_ci			      HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32) |
184462306a36Sopenharmony_ci	       u32_encode_bits((end_offset >> 2),
184562306a36Sopenharmony_ci			       HAL_WBM_SCATTERED_DESC_HEAD_P_OFFSET_IX1);
184662306a36Sopenharmony_ci	ath12k_hif_write32(ab,
184762306a36Sopenharmony_ci			   HAL_SEQ_WCSS_UMAC_WBM_REG +
184862306a36Sopenharmony_ci			   HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1(ab),
184962306a36Sopenharmony_ci			   val);
185062306a36Sopenharmony_ci
185162306a36Sopenharmony_ci	val = u32_encode_bits(sbuf[0].paddr, BUFFER_ADDR_INFO0_ADDR);
185262306a36Sopenharmony_ci	ath12k_hif_write32(ab,
185362306a36Sopenharmony_ci			   HAL_SEQ_WCSS_UMAC_WBM_REG +
185462306a36Sopenharmony_ci			   HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(ab),
185562306a36Sopenharmony_ci			   val);
185662306a36Sopenharmony_ci
185762306a36Sopenharmony_ci	val = u32_encode_bits(sbuf[0].paddr, BUFFER_ADDR_INFO0_ADDR);
185862306a36Sopenharmony_ci	ath12k_hif_write32(ab,
185962306a36Sopenharmony_ci			   HAL_SEQ_WCSS_UMAC_WBM_REG +
186062306a36Sopenharmony_ci			   HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0(ab),
186162306a36Sopenharmony_ci			   val);
186262306a36Sopenharmony_ci
186362306a36Sopenharmony_ci	val = u32_encode_bits(((u64)sbuf[0].paddr >> HAL_ADDR_MSB_REG_SHIFT),
186462306a36Sopenharmony_ci			      HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32) |
186562306a36Sopenharmony_ci	      u32_encode_bits(0, HAL_WBM_SCATTERED_DESC_TAIL_P_OFFSET_IX1);
186662306a36Sopenharmony_ci	ath12k_hif_write32(ab,
186762306a36Sopenharmony_ci			   HAL_SEQ_WCSS_UMAC_WBM_REG +
186862306a36Sopenharmony_ci			   HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1(ab),
186962306a36Sopenharmony_ci			   val);
187062306a36Sopenharmony_ci
187162306a36Sopenharmony_ci	val = 2 * tot_link_desc;
187262306a36Sopenharmony_ci	ath12k_hif_write32(ab,
187362306a36Sopenharmony_ci			   HAL_SEQ_WCSS_UMAC_WBM_REG +
187462306a36Sopenharmony_ci			   HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR(ab),
187562306a36Sopenharmony_ci			   val);
187662306a36Sopenharmony_ci
187762306a36Sopenharmony_ci	/* Enable the SRNG */
187862306a36Sopenharmony_ci	val = u32_encode_bits(1, HAL_WBM_IDLE_LINK_RING_MISC_SRNG_ENABLE) |
187962306a36Sopenharmony_ci	      u32_encode_bits(1, HAL_WBM_IDLE_LINK_RING_MISC_RIND_ID_DISABLE);
188062306a36Sopenharmony_ci	ath12k_hif_write32(ab,
188162306a36Sopenharmony_ci			   HAL_SEQ_WCSS_UMAC_WBM_REG +
188262306a36Sopenharmony_ci			   HAL_WBM_IDLE_LINK_RING_MISC_ADDR(ab),
188362306a36Sopenharmony_ci			   val);
188462306a36Sopenharmony_ci}
188562306a36Sopenharmony_ci
188662306a36Sopenharmony_ciint ath12k_hal_srng_setup(struct ath12k_base *ab, enum hal_ring_type type,
188762306a36Sopenharmony_ci			  int ring_num, int mac_id,
188862306a36Sopenharmony_ci			  struct hal_srng_params *params)
188962306a36Sopenharmony_ci{
189062306a36Sopenharmony_ci	struct ath12k_hal *hal = &ab->hal;
189162306a36Sopenharmony_ci	struct hal_srng_config *srng_config = &ab->hal.srng_config[type];
189262306a36Sopenharmony_ci	struct hal_srng *srng;
189362306a36Sopenharmony_ci	int ring_id;
189462306a36Sopenharmony_ci	u32 idx;
189562306a36Sopenharmony_ci	int i;
189662306a36Sopenharmony_ci	u32 reg_base;
189762306a36Sopenharmony_ci
189862306a36Sopenharmony_ci	ring_id = ath12k_hal_srng_get_ring_id(ab, type, ring_num, mac_id);
189962306a36Sopenharmony_ci	if (ring_id < 0)
190062306a36Sopenharmony_ci		return ring_id;
190162306a36Sopenharmony_ci
190262306a36Sopenharmony_ci	srng = &hal->srng_list[ring_id];
190362306a36Sopenharmony_ci
190462306a36Sopenharmony_ci	srng->ring_id = ring_id;
190562306a36Sopenharmony_ci	srng->ring_dir = srng_config->ring_dir;
190662306a36Sopenharmony_ci	srng->ring_base_paddr = params->ring_base_paddr;
190762306a36Sopenharmony_ci	srng->ring_base_vaddr = params->ring_base_vaddr;
190862306a36Sopenharmony_ci	srng->entry_size = srng_config->entry_size;
190962306a36Sopenharmony_ci	srng->num_entries = params->num_entries;
191062306a36Sopenharmony_ci	srng->ring_size = srng->entry_size * srng->num_entries;
191162306a36Sopenharmony_ci	srng->intr_batch_cntr_thres_entries =
191262306a36Sopenharmony_ci				params->intr_batch_cntr_thres_entries;
191362306a36Sopenharmony_ci	srng->intr_timer_thres_us = params->intr_timer_thres_us;
191462306a36Sopenharmony_ci	srng->flags = params->flags;
191562306a36Sopenharmony_ci	srng->msi_addr = params->msi_addr;
191662306a36Sopenharmony_ci	srng->msi2_addr = params->msi2_addr;
191762306a36Sopenharmony_ci	srng->msi_data = params->msi_data;
191862306a36Sopenharmony_ci	srng->msi2_data = params->msi2_data;
191962306a36Sopenharmony_ci	srng->initialized = 1;
192062306a36Sopenharmony_ci	spin_lock_init(&srng->lock);
192162306a36Sopenharmony_ci	lockdep_set_class(&srng->lock, &srng->lock_key);
192262306a36Sopenharmony_ci
192362306a36Sopenharmony_ci	for (i = 0; i < HAL_SRNG_NUM_REG_GRP; i++) {
192462306a36Sopenharmony_ci		srng->hwreg_base[i] = srng_config->reg_start[i] +
192562306a36Sopenharmony_ci				      (ring_num * srng_config->reg_size[i]);
192662306a36Sopenharmony_ci	}
192762306a36Sopenharmony_ci
192862306a36Sopenharmony_ci	memset(srng->ring_base_vaddr, 0,
192962306a36Sopenharmony_ci	       (srng->entry_size * srng->num_entries) << 2);
193062306a36Sopenharmony_ci
193162306a36Sopenharmony_ci	reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2];
193262306a36Sopenharmony_ci
193362306a36Sopenharmony_ci	if (srng->ring_dir == HAL_SRNG_DIR_SRC) {
193462306a36Sopenharmony_ci		srng->u.src_ring.hp = 0;
193562306a36Sopenharmony_ci		srng->u.src_ring.cached_tp = 0;
193662306a36Sopenharmony_ci		srng->u.src_ring.reap_hp = srng->ring_size - srng->entry_size;
193762306a36Sopenharmony_ci		srng->u.src_ring.tp_addr = (void *)(hal->rdp.vaddr + ring_id);
193862306a36Sopenharmony_ci		srng->u.src_ring.low_threshold = params->low_threshold *
193962306a36Sopenharmony_ci						 srng->entry_size;
194062306a36Sopenharmony_ci		if (srng_config->mac_type == ATH12K_HAL_SRNG_UMAC) {
194162306a36Sopenharmony_ci			if (!ab->hw_params->supports_shadow_regs)
194262306a36Sopenharmony_ci				srng->u.src_ring.hp_addr =
194362306a36Sopenharmony_ci					(u32 *)((unsigned long)ab->mem + reg_base);
194462306a36Sopenharmony_ci			else
194562306a36Sopenharmony_ci				ath12k_dbg(ab, ATH12K_DBG_HAL,
194662306a36Sopenharmony_ci					   "hal type %d ring_num %d reg_base 0x%x shadow 0x%lx\n",
194762306a36Sopenharmony_ci					   type, ring_num,
194862306a36Sopenharmony_ci					   reg_base,
194962306a36Sopenharmony_ci					   (unsigned long)srng->u.src_ring.hp_addr -
195062306a36Sopenharmony_ci					   (unsigned long)ab->mem);
195162306a36Sopenharmony_ci		} else {
195262306a36Sopenharmony_ci			idx = ring_id - HAL_SRNG_RING_ID_DMAC_CMN_ID_START;
195362306a36Sopenharmony_ci			srng->u.src_ring.hp_addr = (void *)(hal->wrp.vaddr +
195462306a36Sopenharmony_ci						   idx);
195562306a36Sopenharmony_ci			srng->flags |= HAL_SRNG_FLAGS_LMAC_RING;
195662306a36Sopenharmony_ci		}
195762306a36Sopenharmony_ci	} else {
195862306a36Sopenharmony_ci		/* During initialization loop count in all the descriptors
195962306a36Sopenharmony_ci		 * will be set to zero, and HW will set it to 1 on completing
196062306a36Sopenharmony_ci		 * descriptor update in first loop, and increments it by 1 on
196162306a36Sopenharmony_ci		 * subsequent loops (loop count wraps around after reaching
196262306a36Sopenharmony_ci		 * 0xffff). The 'loop_cnt' in SW ring state is the expected
196362306a36Sopenharmony_ci		 * loop count in descriptors updated by HW (to be processed
196462306a36Sopenharmony_ci		 * by SW).
196562306a36Sopenharmony_ci		 */
196662306a36Sopenharmony_ci		srng->u.dst_ring.loop_cnt = 1;
196762306a36Sopenharmony_ci		srng->u.dst_ring.tp = 0;
196862306a36Sopenharmony_ci		srng->u.dst_ring.cached_hp = 0;
196962306a36Sopenharmony_ci		srng->u.dst_ring.hp_addr = (void *)(hal->rdp.vaddr + ring_id);
197062306a36Sopenharmony_ci		if (srng_config->mac_type == ATH12K_HAL_SRNG_UMAC) {
197162306a36Sopenharmony_ci			if (!ab->hw_params->supports_shadow_regs)
197262306a36Sopenharmony_ci				srng->u.dst_ring.tp_addr =
197362306a36Sopenharmony_ci					(u32 *)((unsigned long)ab->mem + reg_base +
197462306a36Sopenharmony_ci					(HAL_REO1_RING_TP - HAL_REO1_RING_HP));
197562306a36Sopenharmony_ci			else
197662306a36Sopenharmony_ci				ath12k_dbg(ab, ATH12K_DBG_HAL,
197762306a36Sopenharmony_ci					   "type %d ring_num %d target_reg 0x%x shadow 0x%lx\n",
197862306a36Sopenharmony_ci					   type, ring_num,
197962306a36Sopenharmony_ci					   reg_base + HAL_REO1_RING_TP - HAL_REO1_RING_HP,
198062306a36Sopenharmony_ci					   (unsigned long)srng->u.dst_ring.tp_addr -
198162306a36Sopenharmony_ci					   (unsigned long)ab->mem);
198262306a36Sopenharmony_ci		} else {
198362306a36Sopenharmony_ci			/* For PMAC & DMAC rings, tail pointer updates will be done
198462306a36Sopenharmony_ci			 * through FW by writing to a shared memory location
198562306a36Sopenharmony_ci			 */
198662306a36Sopenharmony_ci			idx = ring_id - HAL_SRNG_RING_ID_DMAC_CMN_ID_START;
198762306a36Sopenharmony_ci			srng->u.dst_ring.tp_addr = (void *)(hal->wrp.vaddr +
198862306a36Sopenharmony_ci						   idx);
198962306a36Sopenharmony_ci			srng->flags |= HAL_SRNG_FLAGS_LMAC_RING;
199062306a36Sopenharmony_ci		}
199162306a36Sopenharmony_ci	}
199262306a36Sopenharmony_ci
199362306a36Sopenharmony_ci	if (srng_config->mac_type != ATH12K_HAL_SRNG_UMAC)
199462306a36Sopenharmony_ci		return ring_id;
199562306a36Sopenharmony_ci
199662306a36Sopenharmony_ci	ath12k_hal_srng_hw_init(ab, srng);
199762306a36Sopenharmony_ci
199862306a36Sopenharmony_ci	if (type == HAL_CE_DST) {
199962306a36Sopenharmony_ci		srng->u.dst_ring.max_buffer_length = params->max_buffer_len;
200062306a36Sopenharmony_ci		ath12k_hal_ce_dst_setup(ab, srng, ring_num);
200162306a36Sopenharmony_ci	}
200262306a36Sopenharmony_ci
200362306a36Sopenharmony_ci	return ring_id;
200462306a36Sopenharmony_ci}
200562306a36Sopenharmony_ci
200662306a36Sopenharmony_cistatic void ath12k_hal_srng_update_hp_tp_addr(struct ath12k_base *ab,
200762306a36Sopenharmony_ci					      int shadow_cfg_idx,
200862306a36Sopenharmony_ci					      enum hal_ring_type ring_type,
200962306a36Sopenharmony_ci					      int ring_num)
201062306a36Sopenharmony_ci{
201162306a36Sopenharmony_ci	struct hal_srng *srng;
201262306a36Sopenharmony_ci	struct ath12k_hal *hal = &ab->hal;
201362306a36Sopenharmony_ci	int ring_id;
201462306a36Sopenharmony_ci	struct hal_srng_config *srng_config = &hal->srng_config[ring_type];
201562306a36Sopenharmony_ci
201662306a36Sopenharmony_ci	ring_id = ath12k_hal_srng_get_ring_id(ab, ring_type, ring_num, 0);
201762306a36Sopenharmony_ci	if (ring_id < 0)
201862306a36Sopenharmony_ci		return;
201962306a36Sopenharmony_ci
202062306a36Sopenharmony_ci	srng = &hal->srng_list[ring_id];
202162306a36Sopenharmony_ci
202262306a36Sopenharmony_ci	if (srng_config->ring_dir == HAL_SRNG_DIR_DST)
202362306a36Sopenharmony_ci		srng->u.dst_ring.tp_addr = (u32 *)(HAL_SHADOW_REG(shadow_cfg_idx) +
202462306a36Sopenharmony_ci						   (unsigned long)ab->mem);
202562306a36Sopenharmony_ci	else
202662306a36Sopenharmony_ci		srng->u.src_ring.hp_addr = (u32 *)(HAL_SHADOW_REG(shadow_cfg_idx) +
202762306a36Sopenharmony_ci						   (unsigned long)ab->mem);
202862306a36Sopenharmony_ci}
202962306a36Sopenharmony_ci
203062306a36Sopenharmony_ciint ath12k_hal_srng_update_shadow_config(struct ath12k_base *ab,
203162306a36Sopenharmony_ci					 enum hal_ring_type ring_type,
203262306a36Sopenharmony_ci					 int ring_num)
203362306a36Sopenharmony_ci{
203462306a36Sopenharmony_ci	struct ath12k_hal *hal = &ab->hal;
203562306a36Sopenharmony_ci	struct hal_srng_config *srng_config = &hal->srng_config[ring_type];
203662306a36Sopenharmony_ci	int shadow_cfg_idx = hal->num_shadow_reg_configured;
203762306a36Sopenharmony_ci	u32 target_reg;
203862306a36Sopenharmony_ci
203962306a36Sopenharmony_ci	if (shadow_cfg_idx >= HAL_SHADOW_NUM_REGS)
204062306a36Sopenharmony_ci		return -EINVAL;
204162306a36Sopenharmony_ci
204262306a36Sopenharmony_ci	hal->num_shadow_reg_configured++;
204362306a36Sopenharmony_ci
204462306a36Sopenharmony_ci	target_reg = srng_config->reg_start[HAL_HP_OFFSET_IN_REG_START];
204562306a36Sopenharmony_ci	target_reg += srng_config->reg_size[HAL_HP_OFFSET_IN_REG_START] *
204662306a36Sopenharmony_ci		ring_num;
204762306a36Sopenharmony_ci
204862306a36Sopenharmony_ci	/* For destination ring, shadow the TP */
204962306a36Sopenharmony_ci	if (srng_config->ring_dir == HAL_SRNG_DIR_DST)
205062306a36Sopenharmony_ci		target_reg += HAL_OFFSET_FROM_HP_TO_TP;
205162306a36Sopenharmony_ci
205262306a36Sopenharmony_ci	hal->shadow_reg_addr[shadow_cfg_idx] = target_reg;
205362306a36Sopenharmony_ci
205462306a36Sopenharmony_ci	/* update hp/tp addr to hal structure*/
205562306a36Sopenharmony_ci	ath12k_hal_srng_update_hp_tp_addr(ab, shadow_cfg_idx, ring_type,
205662306a36Sopenharmony_ci					  ring_num);
205762306a36Sopenharmony_ci
205862306a36Sopenharmony_ci	ath12k_dbg(ab, ATH12K_DBG_HAL,
205962306a36Sopenharmony_ci		   "target_reg %x, shadow reg 0x%x shadow_idx 0x%x, ring_type %d, ring num %d",
206062306a36Sopenharmony_ci		  target_reg,
206162306a36Sopenharmony_ci		  HAL_SHADOW_REG(shadow_cfg_idx),
206262306a36Sopenharmony_ci		  shadow_cfg_idx,
206362306a36Sopenharmony_ci		  ring_type, ring_num);
206462306a36Sopenharmony_ci
206562306a36Sopenharmony_ci	return 0;
206662306a36Sopenharmony_ci}
206762306a36Sopenharmony_ci
206862306a36Sopenharmony_civoid ath12k_hal_srng_shadow_config(struct ath12k_base *ab)
206962306a36Sopenharmony_ci{
207062306a36Sopenharmony_ci	struct ath12k_hal *hal = &ab->hal;
207162306a36Sopenharmony_ci	int ring_type, ring_num;
207262306a36Sopenharmony_ci
207362306a36Sopenharmony_ci	/* update all the non-CE srngs. */
207462306a36Sopenharmony_ci	for (ring_type = 0; ring_type < HAL_MAX_RING_TYPES; ring_type++) {
207562306a36Sopenharmony_ci		struct hal_srng_config *srng_config = &hal->srng_config[ring_type];
207662306a36Sopenharmony_ci
207762306a36Sopenharmony_ci		if (ring_type == HAL_CE_SRC ||
207862306a36Sopenharmony_ci		    ring_type == HAL_CE_DST ||
207962306a36Sopenharmony_ci			ring_type == HAL_CE_DST_STATUS)
208062306a36Sopenharmony_ci			continue;
208162306a36Sopenharmony_ci
208262306a36Sopenharmony_ci		if (srng_config->mac_type == ATH12K_HAL_SRNG_DMAC ||
208362306a36Sopenharmony_ci		    srng_config->mac_type == ATH12K_HAL_SRNG_PMAC)
208462306a36Sopenharmony_ci			continue;
208562306a36Sopenharmony_ci
208662306a36Sopenharmony_ci		for (ring_num = 0; ring_num < srng_config->max_rings; ring_num++)
208762306a36Sopenharmony_ci			ath12k_hal_srng_update_shadow_config(ab, ring_type, ring_num);
208862306a36Sopenharmony_ci	}
208962306a36Sopenharmony_ci}
209062306a36Sopenharmony_ci
209162306a36Sopenharmony_civoid ath12k_hal_srng_get_shadow_config(struct ath12k_base *ab,
209262306a36Sopenharmony_ci				       u32 **cfg, u32 *len)
209362306a36Sopenharmony_ci{
209462306a36Sopenharmony_ci	struct ath12k_hal *hal = &ab->hal;
209562306a36Sopenharmony_ci
209662306a36Sopenharmony_ci	*len = hal->num_shadow_reg_configured;
209762306a36Sopenharmony_ci	*cfg = hal->shadow_reg_addr;
209862306a36Sopenharmony_ci}
209962306a36Sopenharmony_ci
210062306a36Sopenharmony_civoid ath12k_hal_srng_shadow_update_hp_tp(struct ath12k_base *ab,
210162306a36Sopenharmony_ci					 struct hal_srng *srng)
210262306a36Sopenharmony_ci{
210362306a36Sopenharmony_ci	lockdep_assert_held(&srng->lock);
210462306a36Sopenharmony_ci
210562306a36Sopenharmony_ci	/* check whether the ring is empty. Update the shadow
210662306a36Sopenharmony_ci	 * HP only when then ring isn't' empty.
210762306a36Sopenharmony_ci	 */
210862306a36Sopenharmony_ci	if (srng->ring_dir == HAL_SRNG_DIR_SRC &&
210962306a36Sopenharmony_ci	    *srng->u.src_ring.tp_addr != srng->u.src_ring.hp)
211062306a36Sopenharmony_ci		ath12k_hal_srng_access_end(ab, srng);
211162306a36Sopenharmony_ci}
211262306a36Sopenharmony_ci
211362306a36Sopenharmony_cistatic void ath12k_hal_register_srng_lock_keys(struct ath12k_base *ab)
211462306a36Sopenharmony_ci{
211562306a36Sopenharmony_ci	struct ath12k_hal *hal = &ab->hal;
211662306a36Sopenharmony_ci	u32 ring_id;
211762306a36Sopenharmony_ci
211862306a36Sopenharmony_ci	for (ring_id = 0; ring_id < HAL_SRNG_RING_ID_MAX; ring_id++)
211962306a36Sopenharmony_ci		lockdep_register_key(&hal->srng_list[ring_id].lock_key);
212062306a36Sopenharmony_ci}
212162306a36Sopenharmony_ci
212262306a36Sopenharmony_cistatic void ath12k_hal_unregister_srng_lock_keys(struct ath12k_base *ab)
212362306a36Sopenharmony_ci{
212462306a36Sopenharmony_ci	struct ath12k_hal *hal = &ab->hal;
212562306a36Sopenharmony_ci	u32 ring_id;
212662306a36Sopenharmony_ci
212762306a36Sopenharmony_ci	for (ring_id = 0; ring_id < HAL_SRNG_RING_ID_MAX; ring_id++)
212862306a36Sopenharmony_ci		lockdep_unregister_key(&hal->srng_list[ring_id].lock_key);
212962306a36Sopenharmony_ci}
213062306a36Sopenharmony_ci
213162306a36Sopenharmony_ciint ath12k_hal_srng_init(struct ath12k_base *ab)
213262306a36Sopenharmony_ci{
213362306a36Sopenharmony_ci	struct ath12k_hal *hal = &ab->hal;
213462306a36Sopenharmony_ci	int ret;
213562306a36Sopenharmony_ci
213662306a36Sopenharmony_ci	memset(hal, 0, sizeof(*hal));
213762306a36Sopenharmony_ci
213862306a36Sopenharmony_ci	ret = ab->hw_params->hal_ops->create_srng_config(ab);
213962306a36Sopenharmony_ci	if (ret)
214062306a36Sopenharmony_ci		goto err_hal;
214162306a36Sopenharmony_ci
214262306a36Sopenharmony_ci	ret = ath12k_hal_alloc_cont_rdp(ab);
214362306a36Sopenharmony_ci	if (ret)
214462306a36Sopenharmony_ci		goto err_hal;
214562306a36Sopenharmony_ci
214662306a36Sopenharmony_ci	ret = ath12k_hal_alloc_cont_wrp(ab);
214762306a36Sopenharmony_ci	if (ret)
214862306a36Sopenharmony_ci		goto err_free_cont_rdp;
214962306a36Sopenharmony_ci
215062306a36Sopenharmony_ci	ath12k_hal_register_srng_lock_keys(ab);
215162306a36Sopenharmony_ci
215262306a36Sopenharmony_ci	return 0;
215362306a36Sopenharmony_ci
215462306a36Sopenharmony_cierr_free_cont_rdp:
215562306a36Sopenharmony_ci	ath12k_hal_free_cont_rdp(ab);
215662306a36Sopenharmony_ci
215762306a36Sopenharmony_cierr_hal:
215862306a36Sopenharmony_ci	return ret;
215962306a36Sopenharmony_ci}
216062306a36Sopenharmony_ci
216162306a36Sopenharmony_civoid ath12k_hal_srng_deinit(struct ath12k_base *ab)
216262306a36Sopenharmony_ci{
216362306a36Sopenharmony_ci	struct ath12k_hal *hal = &ab->hal;
216462306a36Sopenharmony_ci
216562306a36Sopenharmony_ci	ath12k_hal_unregister_srng_lock_keys(ab);
216662306a36Sopenharmony_ci	ath12k_hal_free_cont_rdp(ab);
216762306a36Sopenharmony_ci	ath12k_hal_free_cont_wrp(ab);
216862306a36Sopenharmony_ci	kfree(hal->srng_config);
216962306a36Sopenharmony_ci	hal->srng_config = NULL;
217062306a36Sopenharmony_ci}
217162306a36Sopenharmony_ci
217262306a36Sopenharmony_civoid ath12k_hal_dump_srng_stats(struct ath12k_base *ab)
217362306a36Sopenharmony_ci{
217462306a36Sopenharmony_ci	struct hal_srng *srng;
217562306a36Sopenharmony_ci	struct ath12k_ext_irq_grp *irq_grp;
217662306a36Sopenharmony_ci	struct ath12k_ce_pipe *ce_pipe;
217762306a36Sopenharmony_ci	int i;
217862306a36Sopenharmony_ci
217962306a36Sopenharmony_ci	ath12k_err(ab, "Last interrupt received for each CE:\n");
218062306a36Sopenharmony_ci	for (i = 0; i < ab->hw_params->ce_count; i++) {
218162306a36Sopenharmony_ci		ce_pipe = &ab->ce.ce_pipe[i];
218262306a36Sopenharmony_ci
218362306a36Sopenharmony_ci		if (ath12k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
218462306a36Sopenharmony_ci			continue;
218562306a36Sopenharmony_ci
218662306a36Sopenharmony_ci		ath12k_err(ab, "CE_id %d pipe_num %d %ums before\n",
218762306a36Sopenharmony_ci			   i, ce_pipe->pipe_num,
218862306a36Sopenharmony_ci			   jiffies_to_msecs(jiffies - ce_pipe->timestamp));
218962306a36Sopenharmony_ci	}
219062306a36Sopenharmony_ci
219162306a36Sopenharmony_ci	ath12k_err(ab, "\nLast interrupt received for each group:\n");
219262306a36Sopenharmony_ci	for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) {
219362306a36Sopenharmony_ci		irq_grp = &ab->ext_irq_grp[i];
219462306a36Sopenharmony_ci		ath12k_err(ab, "group_id %d %ums before\n",
219562306a36Sopenharmony_ci			   irq_grp->grp_id,
219662306a36Sopenharmony_ci			   jiffies_to_msecs(jiffies - irq_grp->timestamp));
219762306a36Sopenharmony_ci	}
219862306a36Sopenharmony_ci
219962306a36Sopenharmony_ci	for (i = 0; i < HAL_SRNG_RING_ID_MAX; i++) {
220062306a36Sopenharmony_ci		srng = &ab->hal.srng_list[i];
220162306a36Sopenharmony_ci
220262306a36Sopenharmony_ci		if (!srng->initialized)
220362306a36Sopenharmony_ci			continue;
220462306a36Sopenharmony_ci
220562306a36Sopenharmony_ci		if (srng->ring_dir == HAL_SRNG_DIR_SRC)
220662306a36Sopenharmony_ci			ath12k_err(ab,
220762306a36Sopenharmony_ci				   "src srng id %u hp %u, reap_hp %u, cur tp %u, cached tp %u last tp %u napi processed before %ums\n",
220862306a36Sopenharmony_ci				   srng->ring_id, srng->u.src_ring.hp,
220962306a36Sopenharmony_ci				   srng->u.src_ring.reap_hp,
221062306a36Sopenharmony_ci				   *srng->u.src_ring.tp_addr, srng->u.src_ring.cached_tp,
221162306a36Sopenharmony_ci				   srng->u.src_ring.last_tp,
221262306a36Sopenharmony_ci				   jiffies_to_msecs(jiffies - srng->timestamp));
221362306a36Sopenharmony_ci		else if (srng->ring_dir == HAL_SRNG_DIR_DST)
221462306a36Sopenharmony_ci			ath12k_err(ab,
221562306a36Sopenharmony_ci				   "dst srng id %u tp %u, cur hp %u, cached hp %u last hp %u napi processed before %ums\n",
221662306a36Sopenharmony_ci				   srng->ring_id, srng->u.dst_ring.tp,
221762306a36Sopenharmony_ci				   *srng->u.dst_ring.hp_addr,
221862306a36Sopenharmony_ci				   srng->u.dst_ring.cached_hp,
221962306a36Sopenharmony_ci				   srng->u.dst_ring.last_hp,
222062306a36Sopenharmony_ci				   jiffies_to_msecs(jiffies - srng->timestamp));
222162306a36Sopenharmony_ci	}
222262306a36Sopenharmony_ci}
2223