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