1d8899132SKalle Valo // SPDX-License-Identifier: BSD-3-Clause-Clear 2d8899132SKalle Valo /* 3d8899132SKalle Valo * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. 4d8899132SKalle Valo * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. 5d8899132SKalle Valo */ 6d8899132SKalle Valo #include <linux/dma-mapping.h> 7d8899132SKalle Valo #include "hal_tx.h" 8d8899132SKalle Valo #include "hal_rx.h" 9d8899132SKalle Valo #include "debug.h" 10d8899132SKalle Valo #include "hal_desc.h" 11d8899132SKalle Valo #include "hif.h" 12d8899132SKalle Valo 13d8899132SKalle Valo static const struct hal_srng_config hw_srng_config_template[] = { 14d8899132SKalle Valo /* TODO: max_rings can populated by querying HW capabilities */ 15d8899132SKalle Valo [HAL_REO_DST] = { 16d8899132SKalle Valo .start_ring_id = HAL_SRNG_RING_ID_REO2SW1, 17d8899132SKalle Valo .max_rings = 8, 18d8899132SKalle Valo .entry_size = sizeof(struct hal_reo_dest_ring) >> 2, 19d8899132SKalle Valo .mac_type = ATH12K_HAL_SRNG_UMAC, 20d8899132SKalle Valo .ring_dir = HAL_SRNG_DIR_DST, 21d8899132SKalle Valo .max_size = HAL_REO_REO2SW1_RING_BASE_MSB_RING_SIZE, 22d8899132SKalle Valo }, 23d8899132SKalle Valo [HAL_REO_EXCEPTION] = { 24d8899132SKalle Valo /* Designating REO2SW0 ring as exception ring. 25d8899132SKalle Valo * Any of theREO2SW rings can be used as exception ring. 26d8899132SKalle Valo */ 27d8899132SKalle Valo .start_ring_id = HAL_SRNG_RING_ID_REO2SW0, 28d8899132SKalle Valo .max_rings = 1, 29d8899132SKalle Valo .entry_size = sizeof(struct hal_reo_dest_ring) >> 2, 30d8899132SKalle Valo .mac_type = ATH12K_HAL_SRNG_UMAC, 31d8899132SKalle Valo .ring_dir = HAL_SRNG_DIR_DST, 32d8899132SKalle Valo .max_size = HAL_REO_REO2SW0_RING_BASE_MSB_RING_SIZE, 33d8899132SKalle Valo }, 34d8899132SKalle Valo [HAL_REO_REINJECT] = { 35d8899132SKalle Valo .start_ring_id = HAL_SRNG_RING_ID_SW2REO, 36d8899132SKalle Valo .max_rings = 4, 37d8899132SKalle Valo .entry_size = sizeof(struct hal_reo_entrance_ring) >> 2, 38d8899132SKalle Valo .mac_type = ATH12K_HAL_SRNG_UMAC, 39d8899132SKalle Valo .ring_dir = HAL_SRNG_DIR_SRC, 40d8899132SKalle Valo .max_size = HAL_REO_SW2REO_RING_BASE_MSB_RING_SIZE, 41d8899132SKalle Valo }, 42d8899132SKalle Valo [HAL_REO_CMD] = { 43d8899132SKalle Valo .start_ring_id = HAL_SRNG_RING_ID_REO_CMD, 44d8899132SKalle Valo .max_rings = 1, 45d8899132SKalle Valo .entry_size = (sizeof(struct hal_tlv_64_hdr) + 46d8899132SKalle Valo sizeof(struct hal_reo_get_queue_stats)) >> 2, 47d8899132SKalle Valo .mac_type = ATH12K_HAL_SRNG_UMAC, 48d8899132SKalle Valo .ring_dir = HAL_SRNG_DIR_SRC, 49d8899132SKalle Valo .max_size = HAL_REO_CMD_RING_BASE_MSB_RING_SIZE, 50d8899132SKalle Valo }, 51d8899132SKalle Valo [HAL_REO_STATUS] = { 52d8899132SKalle Valo .start_ring_id = HAL_SRNG_RING_ID_REO_STATUS, 53d8899132SKalle Valo .max_rings = 1, 54d8899132SKalle Valo .entry_size = (sizeof(struct hal_tlv_64_hdr) + 55d8899132SKalle Valo sizeof(struct hal_reo_get_queue_stats_status)) >> 2, 56d8899132SKalle Valo .mac_type = ATH12K_HAL_SRNG_UMAC, 57d8899132SKalle Valo .ring_dir = HAL_SRNG_DIR_DST, 58d8899132SKalle Valo .max_size = HAL_REO_STATUS_RING_BASE_MSB_RING_SIZE, 59d8899132SKalle Valo }, 60d8899132SKalle Valo [HAL_TCL_DATA] = { 61d8899132SKalle Valo .start_ring_id = HAL_SRNG_RING_ID_SW2TCL1, 62d8899132SKalle Valo .max_rings = 6, 63d8899132SKalle Valo .entry_size = sizeof(struct hal_tcl_data_cmd) >> 2, 64d8899132SKalle Valo .mac_type = ATH12K_HAL_SRNG_UMAC, 65d8899132SKalle Valo .ring_dir = HAL_SRNG_DIR_SRC, 66d8899132SKalle Valo .max_size = HAL_SW2TCL1_RING_BASE_MSB_RING_SIZE, 67d8899132SKalle Valo }, 68d8899132SKalle Valo [HAL_TCL_CMD] = { 69d8899132SKalle Valo .start_ring_id = HAL_SRNG_RING_ID_SW2TCL_CMD, 70d8899132SKalle Valo .max_rings = 1, 71d8899132SKalle Valo .entry_size = sizeof(struct hal_tcl_gse_cmd) >> 2, 72d8899132SKalle Valo .mac_type = ATH12K_HAL_SRNG_UMAC, 73d8899132SKalle Valo .ring_dir = HAL_SRNG_DIR_SRC, 74d8899132SKalle Valo .max_size = HAL_SW2TCL1_CMD_RING_BASE_MSB_RING_SIZE, 75d8899132SKalle Valo }, 76d8899132SKalle Valo [HAL_TCL_STATUS] = { 77d8899132SKalle Valo .start_ring_id = HAL_SRNG_RING_ID_TCL_STATUS, 78d8899132SKalle Valo .max_rings = 1, 79d8899132SKalle Valo .entry_size = (sizeof(struct hal_tlv_hdr) + 80d8899132SKalle Valo sizeof(struct hal_tcl_status_ring)) >> 2, 81d8899132SKalle Valo .mac_type = ATH12K_HAL_SRNG_UMAC, 82d8899132SKalle Valo .ring_dir = HAL_SRNG_DIR_DST, 83d8899132SKalle Valo .max_size = HAL_TCL_STATUS_RING_BASE_MSB_RING_SIZE, 84d8899132SKalle Valo }, 85d8899132SKalle Valo [HAL_CE_SRC] = { 86d8899132SKalle Valo .start_ring_id = HAL_SRNG_RING_ID_CE0_SRC, 87d8899132SKalle Valo .max_rings = 16, 88d8899132SKalle Valo .entry_size = sizeof(struct hal_ce_srng_src_desc) >> 2, 89d8899132SKalle Valo .mac_type = ATH12K_HAL_SRNG_UMAC, 90d8899132SKalle Valo .ring_dir = HAL_SRNG_DIR_SRC, 91d8899132SKalle Valo .max_size = HAL_CE_SRC_RING_BASE_MSB_RING_SIZE, 92d8899132SKalle Valo }, 93d8899132SKalle Valo [HAL_CE_DST] = { 94d8899132SKalle Valo .start_ring_id = HAL_SRNG_RING_ID_CE0_DST, 95d8899132SKalle Valo .max_rings = 16, 96d8899132SKalle Valo .entry_size = sizeof(struct hal_ce_srng_dest_desc) >> 2, 97d8899132SKalle Valo .mac_type = ATH12K_HAL_SRNG_UMAC, 98d8899132SKalle Valo .ring_dir = HAL_SRNG_DIR_SRC, 99d8899132SKalle Valo .max_size = HAL_CE_DST_RING_BASE_MSB_RING_SIZE, 100d8899132SKalle Valo }, 101d8899132SKalle Valo [HAL_CE_DST_STATUS] = { 102d8899132SKalle Valo .start_ring_id = HAL_SRNG_RING_ID_CE0_DST_STATUS, 103d8899132SKalle Valo .max_rings = 16, 104d8899132SKalle Valo .entry_size = sizeof(struct hal_ce_srng_dst_status_desc) >> 2, 105d8899132SKalle Valo .mac_type = ATH12K_HAL_SRNG_UMAC, 106d8899132SKalle Valo .ring_dir = HAL_SRNG_DIR_DST, 107d8899132SKalle Valo .max_size = HAL_CE_DST_STATUS_RING_BASE_MSB_RING_SIZE, 108d8899132SKalle Valo }, 109d8899132SKalle Valo [HAL_WBM_IDLE_LINK] = { 110d8899132SKalle Valo .start_ring_id = HAL_SRNG_RING_ID_WBM_IDLE_LINK, 111d8899132SKalle Valo .max_rings = 1, 112d8899132SKalle Valo .entry_size = sizeof(struct hal_wbm_link_desc) >> 2, 113d8899132SKalle Valo .mac_type = ATH12K_HAL_SRNG_UMAC, 114d8899132SKalle Valo .ring_dir = HAL_SRNG_DIR_SRC, 115d8899132SKalle Valo .max_size = HAL_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE, 116d8899132SKalle Valo }, 117d8899132SKalle Valo [HAL_SW2WBM_RELEASE] = { 118d8899132SKalle Valo .start_ring_id = HAL_SRNG_RING_ID_WBM_SW0_RELEASE, 119d8899132SKalle Valo .max_rings = 2, 120d8899132SKalle Valo .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, 121d8899132SKalle Valo .mac_type = ATH12K_HAL_SRNG_UMAC, 122d8899132SKalle Valo .ring_dir = HAL_SRNG_DIR_SRC, 123d8899132SKalle Valo .max_size = HAL_SW2WBM_RELEASE_RING_BASE_MSB_RING_SIZE, 124d8899132SKalle Valo }, 125d8899132SKalle Valo [HAL_WBM2SW_RELEASE] = { 126d8899132SKalle Valo .start_ring_id = HAL_SRNG_RING_ID_WBM2SW0_RELEASE, 127d8899132SKalle Valo .max_rings = 8, 128d8899132SKalle Valo .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, 129d8899132SKalle Valo .mac_type = ATH12K_HAL_SRNG_UMAC, 130d8899132SKalle Valo .ring_dir = HAL_SRNG_DIR_DST, 131d8899132SKalle Valo .max_size = HAL_WBM2SW_RELEASE_RING_BASE_MSB_RING_SIZE, 132d8899132SKalle Valo }, 133d8899132SKalle Valo [HAL_RXDMA_BUF] = { 134d8899132SKalle Valo .start_ring_id = HAL_SRNG_SW2RXDMA_BUF0, 135d8899132SKalle Valo .max_rings = 1, 136d8899132SKalle Valo .entry_size = sizeof(struct hal_wbm_buffer_ring) >> 2, 137d8899132SKalle Valo .mac_type = ATH12K_HAL_SRNG_DMAC, 138d8899132SKalle Valo .ring_dir = HAL_SRNG_DIR_SRC, 139d8899132SKalle Valo .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, 140d8899132SKalle Valo }, 141d8899132SKalle Valo [HAL_RXDMA_DST] = { 142d8899132SKalle Valo .start_ring_id = HAL_SRNG_RING_ID_WMAC1_RXDMA2SW0, 143d8899132SKalle Valo .max_rings = 0, 144d8899132SKalle Valo .entry_size = 0, 145d8899132SKalle Valo .mac_type = ATH12K_HAL_SRNG_PMAC, 146d8899132SKalle Valo .ring_dir = HAL_SRNG_DIR_DST, 147d8899132SKalle Valo .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, 148d8899132SKalle Valo }, 149d8899132SKalle Valo [HAL_RXDMA_MONITOR_BUF] = { 150d8899132SKalle Valo .start_ring_id = HAL_SRNG_SW2RXMON_BUF0, 151d8899132SKalle Valo .max_rings = 1, 152d8899132SKalle Valo .entry_size = sizeof(struct hal_mon_buf_ring) >> 2, 153d8899132SKalle Valo .mac_type = ATH12K_HAL_SRNG_PMAC, 154d8899132SKalle Valo .ring_dir = HAL_SRNG_DIR_SRC, 155d8899132SKalle Valo .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, 156d8899132SKalle Valo }, 157d8899132SKalle Valo [HAL_RXDMA_MONITOR_STATUS] = { 0, }, 158d8899132SKalle Valo [HAL_RXDMA_MONITOR_DESC] = { 0, }, 159d8899132SKalle Valo [HAL_RXDMA_DIR_BUF] = { 160d8899132SKalle Valo .start_ring_id = HAL_SRNG_RING_ID_RXDMA_DIR_BUF, 161d8899132SKalle Valo .max_rings = 2, 162d8899132SKalle Valo .entry_size = 8 >> 2, /* TODO: Define the struct */ 163d8899132SKalle Valo .mac_type = ATH12K_HAL_SRNG_PMAC, 164d8899132SKalle Valo .ring_dir = HAL_SRNG_DIR_SRC, 165d8899132SKalle Valo .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, 166d8899132SKalle Valo }, 167d8899132SKalle Valo [HAL_PPE2TCL] = { 168d8899132SKalle Valo .start_ring_id = HAL_SRNG_RING_ID_PPE2TCL1, 169d8899132SKalle Valo .max_rings = 1, 170d8899132SKalle Valo .entry_size = sizeof(struct hal_tcl_entrance_from_ppe_ring) >> 2, 171d8899132SKalle Valo .mac_type = ATH12K_HAL_SRNG_PMAC, 172d8899132SKalle Valo .ring_dir = HAL_SRNG_DIR_SRC, 173d8899132SKalle Valo .max_size = HAL_SW2TCL1_RING_BASE_MSB_RING_SIZE, 174d8899132SKalle Valo }, 175d8899132SKalle Valo [HAL_PPE_RELEASE] = { 176d8899132SKalle Valo .start_ring_id = HAL_SRNG_RING_ID_WBM_PPE_RELEASE, 177d8899132SKalle Valo .max_rings = 1, 178d8899132SKalle Valo .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, 179d8899132SKalle Valo .mac_type = ATH12K_HAL_SRNG_PMAC, 180d8899132SKalle Valo .ring_dir = HAL_SRNG_DIR_SRC, 181d8899132SKalle Valo .max_size = HAL_WBM2PPE_RELEASE_RING_BASE_MSB_RING_SIZE, 182d8899132SKalle Valo }, 183d8899132SKalle Valo [HAL_TX_MONITOR_BUF] = { 184d8899132SKalle Valo .start_ring_id = HAL_SRNG_SW2TXMON_BUF0, 185d8899132SKalle Valo .max_rings = 1, 186d8899132SKalle Valo .entry_size = sizeof(struct hal_mon_buf_ring) >> 2, 187d8899132SKalle Valo .mac_type = ATH12K_HAL_SRNG_PMAC, 188d8899132SKalle Valo .ring_dir = HAL_SRNG_DIR_SRC, 189d8899132SKalle Valo .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, 190d8899132SKalle Valo }, 191d8899132SKalle Valo [HAL_RXDMA_MONITOR_DST] = { 192d8899132SKalle Valo .start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXMON_BUF0, 193d8899132SKalle Valo .max_rings = 1, 194d8899132SKalle Valo .entry_size = sizeof(struct hal_mon_dest_desc) >> 2, 195d8899132SKalle Valo .mac_type = ATH12K_HAL_SRNG_PMAC, 196d8899132SKalle Valo .ring_dir = HAL_SRNG_DIR_DST, 197d8899132SKalle Valo .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, 198d8899132SKalle Valo }, 199d8899132SKalle Valo [HAL_TX_MONITOR_DST] = { 200d8899132SKalle Valo .start_ring_id = HAL_SRNG_RING_ID_WMAC1_TXMON2SW0_BUF0, 201d8899132SKalle Valo .max_rings = 1, 202d8899132SKalle Valo .entry_size = sizeof(struct hal_mon_dest_desc) >> 2, 203d8899132SKalle Valo .mac_type = ATH12K_HAL_SRNG_PMAC, 204d8899132SKalle Valo .ring_dir = HAL_SRNG_DIR_DST, 205d8899132SKalle Valo .max_size = HAL_RXDMA_RING_MAX_SIZE_BE, 206d8899132SKalle Valo } 207d8899132SKalle Valo }; 208d8899132SKalle Valo 209d8899132SKalle Valo static const struct ath12k_hal_tcl_to_wbm_rbm_map 210d8899132SKalle Valo ath12k_hal_qcn9274_tcl_to_wbm_rbm_map[DP_TCL_NUM_RING_MAX] = { 211d8899132SKalle Valo { 212d8899132SKalle Valo .wbm_ring_num = 0, 213d8899132SKalle Valo .rbm_id = HAL_RX_BUF_RBM_SW0_BM, 214d8899132SKalle Valo }, 215d8899132SKalle Valo { 216d8899132SKalle Valo .wbm_ring_num = 1, 217d8899132SKalle Valo .rbm_id = HAL_RX_BUF_RBM_SW1_BM, 218d8899132SKalle Valo }, 219d8899132SKalle Valo { 220d8899132SKalle Valo .wbm_ring_num = 2, 221d8899132SKalle Valo .rbm_id = HAL_RX_BUF_RBM_SW2_BM, 222d8899132SKalle Valo }, 223d8899132SKalle Valo { 224d8899132SKalle Valo .wbm_ring_num = 4, 225d8899132SKalle Valo .rbm_id = HAL_RX_BUF_RBM_SW4_BM, 226d8899132SKalle Valo } 227d8899132SKalle Valo }; 228d8899132SKalle Valo 229d8899132SKalle Valo static const struct ath12k_hal_tcl_to_wbm_rbm_map 230d8899132SKalle Valo ath12k_hal_wcn7850_tcl_to_wbm_rbm_map[DP_TCL_NUM_RING_MAX] = { 231d8899132SKalle Valo { 232d8899132SKalle Valo .wbm_ring_num = 0, 233d8899132SKalle Valo .rbm_id = HAL_RX_BUF_RBM_SW0_BM, 234d8899132SKalle Valo }, 235d8899132SKalle Valo { 236d8899132SKalle Valo .wbm_ring_num = 2, 237d8899132SKalle Valo .rbm_id = HAL_RX_BUF_RBM_SW2_BM, 238d8899132SKalle Valo }, 239d8899132SKalle Valo { 240d8899132SKalle Valo .wbm_ring_num = 4, 241d8899132SKalle Valo .rbm_id = HAL_RX_BUF_RBM_SW4_BM, 242d8899132SKalle Valo }, 243d8899132SKalle Valo }; 244d8899132SKalle Valo 245*f8209eefSKalle Valo static unsigned int ath12k_hal_reo1_ring_id_offset(struct ath12k_base *ab) 246*f8209eefSKalle Valo { 247*f8209eefSKalle Valo return HAL_REO1_RING_ID(ab) - HAL_REO1_RING_BASE_LSB(ab); 248*f8209eefSKalle Valo } 249*f8209eefSKalle Valo 250*f8209eefSKalle Valo static unsigned int ath12k_hal_reo1_ring_msi1_base_lsb_offset(struct ath12k_base *ab) 251*f8209eefSKalle Valo { 252*f8209eefSKalle Valo return HAL_REO1_RING_MSI1_BASE_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab); 253*f8209eefSKalle Valo } 254*f8209eefSKalle Valo 255*f8209eefSKalle Valo static unsigned int ath12k_hal_reo1_ring_msi1_base_msb_offset(struct ath12k_base *ab) 256*f8209eefSKalle Valo { 257*f8209eefSKalle Valo return HAL_REO1_RING_MSI1_BASE_MSB(ab) - HAL_REO1_RING_BASE_LSB(ab); 258*f8209eefSKalle Valo } 259*f8209eefSKalle Valo 260*f8209eefSKalle Valo static unsigned int ath12k_hal_reo1_ring_msi1_data_offset(struct ath12k_base *ab) 261*f8209eefSKalle Valo { 262*f8209eefSKalle Valo return HAL_REO1_RING_MSI1_DATA(ab) - HAL_REO1_RING_BASE_LSB(ab); 263*f8209eefSKalle Valo } 264*f8209eefSKalle Valo 265*f8209eefSKalle Valo static unsigned int ath12k_hal_reo1_ring_base_msb_offset(struct ath12k_base *ab) 266*f8209eefSKalle Valo { 267*f8209eefSKalle Valo return HAL_REO1_RING_BASE_MSB(ab) - HAL_REO1_RING_BASE_LSB(ab); 268*f8209eefSKalle Valo } 269*f8209eefSKalle Valo 270*f8209eefSKalle Valo static unsigned int ath12k_hal_reo1_ring_producer_int_setup_offset(struct ath12k_base *ab) 271*f8209eefSKalle Valo { 272*f8209eefSKalle Valo return HAL_REO1_RING_PRODUCER_INT_SETUP(ab) - HAL_REO1_RING_BASE_LSB(ab); 273*f8209eefSKalle Valo } 274*f8209eefSKalle Valo 275*f8209eefSKalle Valo static unsigned int ath12k_hal_reo1_ring_hp_addr_lsb_offset(struct ath12k_base *ab) 276*f8209eefSKalle Valo { 277*f8209eefSKalle Valo return HAL_REO1_RING_HP_ADDR_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab); 278*f8209eefSKalle Valo } 279*f8209eefSKalle Valo 280*f8209eefSKalle Valo static unsigned int ath12k_hal_reo1_ring_hp_addr_msb_offset(struct ath12k_base *ab) 281*f8209eefSKalle Valo { 282*f8209eefSKalle Valo return HAL_REO1_RING_HP_ADDR_MSB(ab) - HAL_REO1_RING_BASE_LSB(ab); 283*f8209eefSKalle Valo } 284*f8209eefSKalle Valo 285*f8209eefSKalle Valo static unsigned int ath12k_hal_reo1_ring_misc_offset(struct ath12k_base *ab) 286*f8209eefSKalle Valo { 287*f8209eefSKalle Valo return HAL_REO1_RING_MISC(ab) - HAL_REO1_RING_BASE_LSB(ab); 288*f8209eefSKalle Valo } 289*f8209eefSKalle Valo 290d8899132SKalle Valo static bool ath12k_hw_qcn9274_rx_desc_get_first_msdu(struct hal_rx_desc *desc) 291d8899132SKalle Valo { 292d8899132SKalle Valo return !!le16_get_bits(desc->u.qcn9274.msdu_end.info5, 293d8899132SKalle Valo RX_MSDU_END_INFO5_FIRST_MSDU); 294d8899132SKalle Valo } 295d8899132SKalle Valo 296d8899132SKalle Valo static bool ath12k_hw_qcn9274_rx_desc_get_last_msdu(struct hal_rx_desc *desc) 297d8899132SKalle Valo { 298d8899132SKalle Valo return !!le16_get_bits(desc->u.qcn9274.msdu_end.info5, 299d8899132SKalle Valo RX_MSDU_END_INFO5_LAST_MSDU); 300d8899132SKalle Valo } 301d8899132SKalle Valo 302d8899132SKalle Valo static u8 ath12k_hw_qcn9274_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc) 303d8899132SKalle Valo { 304d8899132SKalle Valo return le16_get_bits(desc->u.qcn9274.msdu_end.info5, 305d8899132SKalle Valo RX_MSDU_END_INFO5_L3_HDR_PADDING); 306d8899132SKalle Valo } 307d8899132SKalle Valo 308d8899132SKalle Valo static bool ath12k_hw_qcn9274_rx_desc_encrypt_valid(struct hal_rx_desc *desc) 309d8899132SKalle Valo { 310d8899132SKalle Valo return !!le32_get_bits(desc->u.qcn9274.mpdu_start.info4, 311d8899132SKalle Valo RX_MPDU_START_INFO4_ENCRYPT_INFO_VALID); 312d8899132SKalle Valo } 313d8899132SKalle Valo 314d8899132SKalle Valo static u32 ath12k_hw_qcn9274_rx_desc_get_encrypt_type(struct hal_rx_desc *desc) 315d8899132SKalle Valo { 316d8899132SKalle Valo return le32_get_bits(desc->u.qcn9274.mpdu_start.info2, 317d8899132SKalle Valo RX_MPDU_START_INFO2_ENC_TYPE); 318d8899132SKalle Valo } 319d8899132SKalle Valo 320d8899132SKalle Valo static u8 ath12k_hw_qcn9274_rx_desc_get_decap_type(struct hal_rx_desc *desc) 321d8899132SKalle Valo { 322d8899132SKalle Valo return le32_get_bits(desc->u.qcn9274.msdu_end.info11, 323d8899132SKalle Valo RX_MSDU_END_INFO11_DECAP_FORMAT); 324d8899132SKalle Valo } 325d8899132SKalle Valo 326d8899132SKalle Valo static u8 ath12k_hw_qcn9274_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc) 327d8899132SKalle Valo { 328d8899132SKalle Valo return le32_get_bits(desc->u.qcn9274.msdu_end.info11, 329d8899132SKalle Valo RX_MSDU_END_INFO11_MESH_CTRL_PRESENT); 330d8899132SKalle Valo } 331d8899132SKalle Valo 332d8899132SKalle Valo static bool ath12k_hw_qcn9274_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc) 333d8899132SKalle Valo { 334d8899132SKalle Valo return !!le32_get_bits(desc->u.qcn9274.mpdu_start.info4, 335d8899132SKalle Valo RX_MPDU_START_INFO4_MPDU_SEQ_CTRL_VALID); 336d8899132SKalle Valo } 337d8899132SKalle Valo 338d8899132SKalle Valo static bool ath12k_hw_qcn9274_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc) 339d8899132SKalle Valo { 340d8899132SKalle Valo return !!le32_get_bits(desc->u.qcn9274.mpdu_start.info4, 341d8899132SKalle Valo RX_MPDU_START_INFO4_MPDU_FCTRL_VALID); 342d8899132SKalle Valo } 343d8899132SKalle Valo 344d8899132SKalle Valo static u16 ath12k_hw_qcn9274_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc) 345d8899132SKalle Valo { 346d8899132SKalle Valo return le32_get_bits(desc->u.qcn9274.mpdu_start.info4, 347d8899132SKalle Valo RX_MPDU_START_INFO4_MPDU_SEQ_NUM); 348d8899132SKalle Valo } 349d8899132SKalle Valo 350d8899132SKalle Valo static u16 ath12k_hw_qcn9274_rx_desc_get_msdu_len(struct hal_rx_desc *desc) 351d8899132SKalle Valo { 352d8899132SKalle Valo return le32_get_bits(desc->u.qcn9274.msdu_end.info10, 353d8899132SKalle Valo RX_MSDU_END_INFO10_MSDU_LENGTH); 354d8899132SKalle Valo } 355d8899132SKalle Valo 356d8899132SKalle Valo static u8 ath12k_hw_qcn9274_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc) 357d8899132SKalle Valo { 358d8899132SKalle Valo return le32_get_bits(desc->u.qcn9274.msdu_end.info12, 359d8899132SKalle Valo RX_MSDU_END_INFO12_SGI); 360d8899132SKalle Valo } 361d8899132SKalle Valo 362d8899132SKalle Valo static u8 ath12k_hw_qcn9274_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc) 363d8899132SKalle Valo { 364d8899132SKalle Valo return le32_get_bits(desc->u.qcn9274.msdu_end.info12, 365d8899132SKalle Valo RX_MSDU_END_INFO12_RATE_MCS); 366d8899132SKalle Valo } 367d8899132SKalle Valo 368d8899132SKalle Valo static u8 ath12k_hw_qcn9274_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc) 369d8899132SKalle Valo { 370d8899132SKalle Valo return le32_get_bits(desc->u.qcn9274.msdu_end.info12, 371d8899132SKalle Valo RX_MSDU_END_INFO12_RECV_BW); 372d8899132SKalle Valo } 373d8899132SKalle Valo 374d8899132SKalle Valo static u32 ath12k_hw_qcn9274_rx_desc_get_msdu_freq(struct hal_rx_desc *desc) 375d8899132SKalle Valo { 376d8899132SKalle Valo return __le32_to_cpu(desc->u.qcn9274.msdu_end.phy_meta_data); 377d8899132SKalle Valo } 378d8899132SKalle Valo 379d8899132SKalle Valo static u8 ath12k_hw_qcn9274_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc) 380d8899132SKalle Valo { 381d8899132SKalle Valo return le32_get_bits(desc->u.qcn9274.msdu_end.info12, 382d8899132SKalle Valo RX_MSDU_END_INFO12_PKT_TYPE); 383d8899132SKalle Valo } 384d8899132SKalle Valo 385d8899132SKalle Valo static u8 ath12k_hw_qcn9274_rx_desc_get_msdu_nss(struct hal_rx_desc *desc) 386d8899132SKalle Valo { 387d8899132SKalle Valo return le32_get_bits(desc->u.qcn9274.msdu_end.info12, 388d8899132SKalle Valo RX_MSDU_END_INFO12_MIMO_SS_BITMAP); 389d8899132SKalle Valo } 390d8899132SKalle Valo 391d8899132SKalle Valo static u8 ath12k_hw_qcn9274_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc) 392d8899132SKalle Valo { 393d8899132SKalle Valo return le16_get_bits(desc->u.qcn9274.msdu_end.info5, 394d8899132SKalle Valo RX_MSDU_END_INFO5_TID); 395d8899132SKalle Valo } 396d8899132SKalle Valo 397d8899132SKalle Valo static u16 ath12k_hw_qcn9274_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc) 398d8899132SKalle Valo { 399d8899132SKalle Valo return __le16_to_cpu(desc->u.qcn9274.mpdu_start.sw_peer_id); 400d8899132SKalle Valo } 401d8899132SKalle Valo 402d8899132SKalle Valo static void ath12k_hw_qcn9274_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc, 403d8899132SKalle Valo struct hal_rx_desc *ldesc) 404d8899132SKalle Valo { 405d8899132SKalle Valo memcpy(&fdesc->u.qcn9274.msdu_end, &ldesc->u.qcn9274.msdu_end, 406d8899132SKalle Valo sizeof(struct rx_msdu_end_qcn9274)); 407d8899132SKalle Valo } 408d8899132SKalle Valo 409d8899132SKalle Valo static u32 ath12k_hw_qcn9274_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc) 410d8899132SKalle Valo { 411d8899132SKalle Valo return __le16_to_cpu(desc->u.qcn9274.mpdu_start.phy_ppdu_id); 412d8899132SKalle Valo } 413d8899132SKalle Valo 414d8899132SKalle Valo static void ath12k_hw_qcn9274_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len) 415d8899132SKalle Valo { 416d8899132SKalle Valo u32 info = __le32_to_cpu(desc->u.qcn9274.msdu_end.info10); 417d8899132SKalle Valo 418d8899132SKalle Valo info &= ~RX_MSDU_END_INFO10_MSDU_LENGTH; 419d8899132SKalle Valo info |= u32_encode_bits(len, RX_MSDU_END_INFO10_MSDU_LENGTH); 420d8899132SKalle Valo 421d8899132SKalle Valo desc->u.qcn9274.msdu_end.info10 = __cpu_to_le32(info); 422d8899132SKalle Valo } 423d8899132SKalle Valo 424d8899132SKalle Valo static u8 *ath12k_hw_qcn9274_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) 425d8899132SKalle Valo { 426d8899132SKalle Valo return &desc->u.qcn9274.msdu_payload[0]; 427d8899132SKalle Valo } 428d8899132SKalle Valo 429d8899132SKalle Valo static u32 ath12k_hw_qcn9274_rx_desc_get_mpdu_start_offset(void) 430d8899132SKalle Valo { 431d8899132SKalle Valo return offsetof(struct hal_rx_desc_qcn9274, mpdu_start); 432d8899132SKalle Valo } 433d8899132SKalle Valo 434d8899132SKalle Valo static u32 ath12k_hw_qcn9274_rx_desc_get_msdu_end_offset(void) 435d8899132SKalle Valo { 436d8899132SKalle Valo return offsetof(struct hal_rx_desc_qcn9274, msdu_end); 437d8899132SKalle Valo } 438d8899132SKalle Valo 439d8899132SKalle Valo static bool ath12k_hw_qcn9274_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) 440d8899132SKalle Valo { 441d8899132SKalle Valo return __le32_to_cpu(desc->u.qcn9274.mpdu_start.info4) & 442d8899132SKalle Valo RX_MPDU_START_INFO4_MAC_ADDR2_VALID; 443d8899132SKalle Valo } 444d8899132SKalle Valo 445d8899132SKalle Valo static u8 *ath12k_hw_qcn9274_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) 446d8899132SKalle Valo { 447d8899132SKalle Valo return desc->u.qcn9274.mpdu_start.addr2; 448d8899132SKalle Valo } 449d8899132SKalle Valo 450d8899132SKalle Valo static bool ath12k_hw_qcn9274_rx_desc_is_mcbc(struct hal_rx_desc *desc) 451d8899132SKalle Valo { 452d8899132SKalle Valo return __le32_to_cpu(desc->u.qcn9274.mpdu_start.info6) & 453d8899132SKalle Valo RX_MPDU_START_INFO6_MCAST_BCAST; 454d8899132SKalle Valo } 455d8899132SKalle Valo 456d8899132SKalle Valo static void ath12k_hw_qcn9274_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, 457d8899132SKalle Valo struct ieee80211_hdr *hdr) 458d8899132SKalle Valo { 459d8899132SKalle Valo hdr->frame_control = desc->u.qcn9274.mpdu_start.frame_ctrl; 460d8899132SKalle Valo hdr->duration_id = desc->u.qcn9274.mpdu_start.duration; 461d8899132SKalle Valo ether_addr_copy(hdr->addr1, desc->u.qcn9274.mpdu_start.addr1); 462d8899132SKalle Valo ether_addr_copy(hdr->addr2, desc->u.qcn9274.mpdu_start.addr2); 463d8899132SKalle Valo ether_addr_copy(hdr->addr3, desc->u.qcn9274.mpdu_start.addr3); 464d8899132SKalle Valo if (__le32_to_cpu(desc->u.qcn9274.mpdu_start.info4) & 465d8899132SKalle Valo RX_MPDU_START_INFO4_MAC_ADDR4_VALID) { 466d8899132SKalle Valo ether_addr_copy(hdr->addr4, desc->u.qcn9274.mpdu_start.addr4); 467d8899132SKalle Valo } 468d8899132SKalle Valo hdr->seq_ctrl = desc->u.qcn9274.mpdu_start.seq_ctrl; 469d8899132SKalle Valo } 470d8899132SKalle Valo 471d8899132SKalle Valo static void ath12k_hw_qcn9274_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, 472d8899132SKalle Valo u8 *crypto_hdr, 473d8899132SKalle Valo enum hal_encrypt_type enctype) 474d8899132SKalle Valo { 475d8899132SKalle Valo unsigned int key_id; 476d8899132SKalle Valo 477d8899132SKalle Valo switch (enctype) { 478d8899132SKalle Valo case HAL_ENCRYPT_TYPE_OPEN: 479d8899132SKalle Valo return; 480d8899132SKalle Valo case HAL_ENCRYPT_TYPE_TKIP_NO_MIC: 481d8899132SKalle Valo case HAL_ENCRYPT_TYPE_TKIP_MIC: 482d8899132SKalle Valo crypto_hdr[0] = 483d8899132SKalle Valo HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274.mpdu_start.pn[0]); 484d8899132SKalle Valo crypto_hdr[1] = 0; 485d8899132SKalle Valo crypto_hdr[2] = 486d8899132SKalle Valo HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274.mpdu_start.pn[0]); 487d8899132SKalle Valo break; 488d8899132SKalle Valo case HAL_ENCRYPT_TYPE_CCMP_128: 489d8899132SKalle Valo case HAL_ENCRYPT_TYPE_CCMP_256: 490d8899132SKalle Valo case HAL_ENCRYPT_TYPE_GCMP_128: 491d8899132SKalle Valo case HAL_ENCRYPT_TYPE_AES_GCMP_256: 492d8899132SKalle Valo crypto_hdr[0] = 493d8899132SKalle Valo HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274.mpdu_start.pn[0]); 494d8899132SKalle Valo crypto_hdr[1] = 495d8899132SKalle Valo HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274.mpdu_start.pn[0]); 496d8899132SKalle Valo crypto_hdr[2] = 0; 497d8899132SKalle Valo break; 498d8899132SKalle Valo case HAL_ENCRYPT_TYPE_WEP_40: 499d8899132SKalle Valo case HAL_ENCRYPT_TYPE_WEP_104: 500d8899132SKalle Valo case HAL_ENCRYPT_TYPE_WEP_128: 501d8899132SKalle Valo case HAL_ENCRYPT_TYPE_WAPI_GCM_SM4: 502d8899132SKalle Valo case HAL_ENCRYPT_TYPE_WAPI: 503d8899132SKalle Valo return; 504d8899132SKalle Valo } 505d8899132SKalle Valo key_id = le32_get_bits(desc->u.qcn9274.mpdu_start.info5, 506d8899132SKalle Valo RX_MPDU_START_INFO5_KEY_ID); 507d8899132SKalle Valo crypto_hdr[3] = 0x20 | (key_id << 6); 508d8899132SKalle Valo crypto_hdr[4] = HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.qcn9274.mpdu_start.pn[0]); 509d8899132SKalle Valo crypto_hdr[5] = HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.qcn9274.mpdu_start.pn[0]); 510d8899132SKalle Valo crypto_hdr[6] = HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274.mpdu_start.pn[1]); 511d8899132SKalle Valo crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274.mpdu_start.pn[1]); 512d8899132SKalle Valo } 513d8899132SKalle Valo 514d8899132SKalle Valo static u16 ath12k_hw_qcn9274_rx_desc_get_mpdu_frame_ctl(struct hal_rx_desc *desc) 515d8899132SKalle Valo { 516d8899132SKalle Valo return __le16_to_cpu(desc->u.qcn9274.mpdu_start.frame_ctrl); 517d8899132SKalle Valo } 518d8899132SKalle Valo 519d8899132SKalle Valo static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab) 520d8899132SKalle Valo { 521d8899132SKalle Valo struct ath12k_hal *hal = &ab->hal; 522d8899132SKalle Valo struct hal_srng_config *s; 523d8899132SKalle Valo 524d8899132SKalle Valo hal->srng_config = kmemdup(hw_srng_config_template, 525d8899132SKalle Valo sizeof(hw_srng_config_template), 526d8899132SKalle Valo GFP_KERNEL); 527d8899132SKalle Valo if (!hal->srng_config) 528d8899132SKalle Valo return -ENOMEM; 529d8899132SKalle Valo 530d8899132SKalle Valo s = &hal->srng_config[HAL_REO_DST]; 531d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_BASE_LSB(ab); 532d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_HP; 533d8899132SKalle Valo s->reg_size[0] = HAL_REO2_RING_BASE_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab); 534d8899132SKalle Valo s->reg_size[1] = HAL_REO2_RING_HP - HAL_REO1_RING_HP; 535d8899132SKalle Valo 536d8899132SKalle Valo s = &hal->srng_config[HAL_REO_EXCEPTION]; 537d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_BASE_LSB(ab); 538d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_HP; 539d8899132SKalle Valo 540d8899132SKalle Valo s = &hal->srng_config[HAL_REO_REINJECT]; 541d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_BASE_LSB(ab); 542d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_HP; 543d8899132SKalle Valo s->reg_size[0] = HAL_SW2REO1_RING_BASE_LSB(ab) - HAL_SW2REO_RING_BASE_LSB(ab); 544d8899132SKalle Valo s->reg_size[1] = HAL_SW2REO1_RING_HP - HAL_SW2REO_RING_HP; 545d8899132SKalle Valo 546d8899132SKalle Valo s = &hal->srng_config[HAL_REO_CMD]; 547d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_RING_BASE_LSB(ab); 548d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_HP; 549d8899132SKalle Valo 550d8899132SKalle Valo s = &hal->srng_config[HAL_REO_STATUS]; 551d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_RING_BASE_LSB(ab); 552d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_HP; 553d8899132SKalle Valo 554d8899132SKalle Valo s = &hal->srng_config[HAL_TCL_DATA]; 555d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_BASE_LSB; 556d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_HP; 557d8899132SKalle Valo s->reg_size[0] = HAL_TCL2_RING_BASE_LSB - HAL_TCL1_RING_BASE_LSB; 558d8899132SKalle Valo s->reg_size[1] = HAL_TCL2_RING_HP - HAL_TCL1_RING_HP; 559d8899132SKalle Valo 560d8899132SKalle Valo s = &hal->srng_config[HAL_TCL_CMD]; 561d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_BASE_LSB(ab); 562d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_HP; 563d8899132SKalle Valo 564d8899132SKalle Valo s = &hal->srng_config[HAL_TCL_STATUS]; 565d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_BASE_LSB(ab); 566d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP; 567d8899132SKalle Valo 568d8899132SKalle Valo s = &hal->srng_config[HAL_CE_SRC]; 569d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG + HAL_CE_DST_RING_BASE_LSB; 570d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG + HAL_CE_DST_RING_HP; 571d8899132SKalle Valo s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG - 572d8899132SKalle Valo HAL_SEQ_WCSS_UMAC_CE0_SRC_REG; 573d8899132SKalle Valo s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG - 574d8899132SKalle Valo HAL_SEQ_WCSS_UMAC_CE0_SRC_REG; 575d8899132SKalle Valo 576d8899132SKalle Valo s = &hal->srng_config[HAL_CE_DST]; 577d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG + HAL_CE_DST_RING_BASE_LSB; 578d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG + HAL_CE_DST_RING_HP; 579d8899132SKalle Valo s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG - 580d8899132SKalle Valo HAL_SEQ_WCSS_UMAC_CE0_DST_REG; 581d8899132SKalle Valo s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG - 582d8899132SKalle Valo HAL_SEQ_WCSS_UMAC_CE0_DST_REG; 583d8899132SKalle Valo 584d8899132SKalle Valo s = &hal->srng_config[HAL_CE_DST_STATUS]; 585d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG + 586d8899132SKalle Valo HAL_CE_DST_STATUS_RING_BASE_LSB; 587d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG + HAL_CE_DST_STATUS_RING_HP; 588d8899132SKalle Valo s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG - 589d8899132SKalle Valo HAL_SEQ_WCSS_UMAC_CE0_DST_REG; 590d8899132SKalle Valo s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG - 591d8899132SKalle Valo HAL_SEQ_WCSS_UMAC_CE0_DST_REG; 592d8899132SKalle Valo 593d8899132SKalle Valo s = &hal->srng_config[HAL_WBM_IDLE_LINK]; 594d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_BASE_LSB(ab); 595d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_HP; 596d8899132SKalle Valo 597d8899132SKalle Valo s = &hal->srng_config[HAL_SW2WBM_RELEASE]; 598d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + 599d8899132SKalle Valo HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab); 600d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SW_RELEASE_RING_HP; 601d8899132SKalle Valo s->reg_size[0] = HAL_WBM_SW1_RELEASE_RING_BASE_LSB(ab) - 602d8899132SKalle Valo HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab); 603d8899132SKalle Valo s->reg_size[1] = HAL_WBM_SW1_RELEASE_RING_HP - HAL_WBM_SW_RELEASE_RING_HP; 604d8899132SKalle Valo 605d8899132SKalle Valo s = &hal->srng_config[HAL_WBM2SW_RELEASE]; 606d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_BASE_LSB(ab); 607d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_HP; 608d8899132SKalle Valo s->reg_size[0] = HAL_WBM1_RELEASE_RING_BASE_LSB(ab) - 609d8899132SKalle Valo HAL_WBM0_RELEASE_RING_BASE_LSB(ab); 610d8899132SKalle Valo s->reg_size[1] = HAL_WBM1_RELEASE_RING_HP - HAL_WBM0_RELEASE_RING_HP; 611d8899132SKalle Valo 612d8899132SKalle Valo /* Some LMAC rings are not accesed from the host: 613d8899132SKalle Valo * RXDMA_BUG, RXDMA_DST, RXDMA_MONITOR_BUF, RXDMA_MONITOR_STATUS, 614d8899132SKalle Valo * RXDMA_MONITOR_DST, RXDMA_MONITOR_DESC, RXDMA_DIR_BUF_SRC, 615d8899132SKalle Valo * RXDMA_RX_MONITOR_BUF, TX_MONITOR_BUF, TX_MONITOR_DST, SW2RXDMA 616d8899132SKalle Valo */ 617d8899132SKalle Valo s = &hal->srng_config[HAL_PPE2TCL]; 618d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_PPE2TCL1_RING_BASE_LSB; 619d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_PPE2TCL1_RING_HP; 620d8899132SKalle Valo 621d8899132SKalle Valo s = &hal->srng_config[HAL_PPE_RELEASE]; 622d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + 623d8899132SKalle Valo HAL_WBM_PPE_RELEASE_RING_BASE_LSB(ab); 624d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_PPE_RELEASE_RING_HP; 625d8899132SKalle Valo 626d8899132SKalle Valo return 0; 627d8899132SKalle Valo } 628d8899132SKalle Valo 629d8899132SKalle Valo static bool ath12k_hw_qcn9274_dp_rx_h_msdu_done(struct hal_rx_desc *desc) 630d8899132SKalle Valo { 631d8899132SKalle Valo return !!le32_get_bits(desc->u.qcn9274.msdu_end.info14, 632d8899132SKalle Valo RX_MSDU_END_INFO14_MSDU_DONE); 633d8899132SKalle Valo } 634d8899132SKalle Valo 635d8899132SKalle Valo static bool ath12k_hw_qcn9274_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc) 636d8899132SKalle Valo { 637d8899132SKalle Valo return !!le32_get_bits(desc->u.qcn9274.msdu_end.info13, 638d8899132SKalle Valo RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL); 639d8899132SKalle Valo } 640d8899132SKalle Valo 641d8899132SKalle Valo static bool ath12k_hw_qcn9274_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc) 642d8899132SKalle Valo { 643d8899132SKalle Valo return !!le32_get_bits(desc->u.qcn9274.msdu_end.info13, 644d8899132SKalle Valo RX_MSDU_END_INFO13_IP_CKSUM_FAIL); 645d8899132SKalle Valo } 646d8899132SKalle Valo 647d8899132SKalle Valo static bool ath12k_hw_qcn9274_dp_rx_h_is_decrypted(struct hal_rx_desc *desc) 648d8899132SKalle Valo { 649d8899132SKalle Valo return (le32_get_bits(desc->u.qcn9274.msdu_end.info14, 650d8899132SKalle Valo RX_MSDU_END_INFO14_DECRYPT_STATUS_CODE) == 651d8899132SKalle Valo RX_DESC_DECRYPT_STATUS_CODE_OK); 652d8899132SKalle Valo } 653d8899132SKalle Valo 654d8899132SKalle Valo static u32 ath12k_hw_qcn9274_dp_rx_h_mpdu_err(struct hal_rx_desc *desc) 655d8899132SKalle Valo { 656d8899132SKalle Valo u32 info = __le32_to_cpu(desc->u.qcn9274.msdu_end.info13); 657d8899132SKalle Valo u32 errmap = 0; 658d8899132SKalle Valo 659d8899132SKalle Valo if (info & RX_MSDU_END_INFO13_FCS_ERR) 660d8899132SKalle Valo errmap |= HAL_RX_MPDU_ERR_FCS; 661d8899132SKalle Valo 662d8899132SKalle Valo if (info & RX_MSDU_END_INFO13_DECRYPT_ERR) 663d8899132SKalle Valo errmap |= HAL_RX_MPDU_ERR_DECRYPT; 664d8899132SKalle Valo 665d8899132SKalle Valo if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR) 666d8899132SKalle Valo errmap |= HAL_RX_MPDU_ERR_TKIP_MIC; 667d8899132SKalle Valo 668d8899132SKalle Valo if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR) 669d8899132SKalle Valo errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR; 670d8899132SKalle Valo 671d8899132SKalle Valo if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR) 672d8899132SKalle Valo errmap |= HAL_RX_MPDU_ERR_OVERFLOW; 673d8899132SKalle Valo 674d8899132SKalle Valo if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR) 675d8899132SKalle Valo errmap |= HAL_RX_MPDU_ERR_MSDU_LEN; 676d8899132SKalle Valo 677d8899132SKalle Valo if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR) 678d8899132SKalle Valo errmap |= HAL_RX_MPDU_ERR_MPDU_LEN; 679d8899132SKalle Valo 680d8899132SKalle Valo return errmap; 681d8899132SKalle Valo } 682d8899132SKalle Valo 683d8899132SKalle Valo const struct hal_ops hal_qcn9274_ops = { 684d8899132SKalle Valo .rx_desc_get_first_msdu = ath12k_hw_qcn9274_rx_desc_get_first_msdu, 685d8899132SKalle Valo .rx_desc_get_last_msdu = ath12k_hw_qcn9274_rx_desc_get_last_msdu, 686d8899132SKalle Valo .rx_desc_get_l3_pad_bytes = ath12k_hw_qcn9274_rx_desc_get_l3_pad_bytes, 687d8899132SKalle Valo .rx_desc_encrypt_valid = ath12k_hw_qcn9274_rx_desc_encrypt_valid, 688d8899132SKalle Valo .rx_desc_get_encrypt_type = ath12k_hw_qcn9274_rx_desc_get_encrypt_type, 689d8899132SKalle Valo .rx_desc_get_decap_type = ath12k_hw_qcn9274_rx_desc_get_decap_type, 690d8899132SKalle Valo .rx_desc_get_mesh_ctl = ath12k_hw_qcn9274_rx_desc_get_mesh_ctl, 691d8899132SKalle Valo .rx_desc_get_mpdu_seq_ctl_vld = ath12k_hw_qcn9274_rx_desc_get_mpdu_seq_ctl_vld, 692d8899132SKalle Valo .rx_desc_get_mpdu_fc_valid = ath12k_hw_qcn9274_rx_desc_get_mpdu_fc_valid, 693d8899132SKalle Valo .rx_desc_get_mpdu_start_seq_no = ath12k_hw_qcn9274_rx_desc_get_mpdu_start_seq_no, 694d8899132SKalle Valo .rx_desc_get_msdu_len = ath12k_hw_qcn9274_rx_desc_get_msdu_len, 695d8899132SKalle Valo .rx_desc_get_msdu_sgi = ath12k_hw_qcn9274_rx_desc_get_msdu_sgi, 696d8899132SKalle Valo .rx_desc_get_msdu_rate_mcs = ath12k_hw_qcn9274_rx_desc_get_msdu_rate_mcs, 697d8899132SKalle Valo .rx_desc_get_msdu_rx_bw = ath12k_hw_qcn9274_rx_desc_get_msdu_rx_bw, 698d8899132SKalle Valo .rx_desc_get_msdu_freq = ath12k_hw_qcn9274_rx_desc_get_msdu_freq, 699d8899132SKalle Valo .rx_desc_get_msdu_pkt_type = ath12k_hw_qcn9274_rx_desc_get_msdu_pkt_type, 700d8899132SKalle Valo .rx_desc_get_msdu_nss = ath12k_hw_qcn9274_rx_desc_get_msdu_nss, 701d8899132SKalle Valo .rx_desc_get_mpdu_tid = ath12k_hw_qcn9274_rx_desc_get_mpdu_tid, 702d8899132SKalle Valo .rx_desc_get_mpdu_peer_id = ath12k_hw_qcn9274_rx_desc_get_mpdu_peer_id, 703d8899132SKalle Valo .rx_desc_copy_end_tlv = ath12k_hw_qcn9274_rx_desc_copy_end_tlv, 704d8899132SKalle Valo .rx_desc_get_mpdu_ppdu_id = ath12k_hw_qcn9274_rx_desc_get_mpdu_ppdu_id, 705d8899132SKalle Valo .rx_desc_set_msdu_len = ath12k_hw_qcn9274_rx_desc_set_msdu_len, 706d8899132SKalle Valo .rx_desc_get_msdu_payload = ath12k_hw_qcn9274_rx_desc_get_msdu_payload, 707d8899132SKalle Valo .rx_desc_get_mpdu_start_offset = ath12k_hw_qcn9274_rx_desc_get_mpdu_start_offset, 708d8899132SKalle Valo .rx_desc_get_msdu_end_offset = ath12k_hw_qcn9274_rx_desc_get_msdu_end_offset, 709d8899132SKalle Valo .rx_desc_mac_addr2_valid = ath12k_hw_qcn9274_rx_desc_mac_addr2_valid, 710d8899132SKalle Valo .rx_desc_mpdu_start_addr2 = ath12k_hw_qcn9274_rx_desc_mpdu_start_addr2, 711d8899132SKalle Valo .rx_desc_is_mcbc = ath12k_hw_qcn9274_rx_desc_is_mcbc, 712d8899132SKalle Valo .rx_desc_get_dot11_hdr = ath12k_hw_qcn9274_rx_desc_get_dot11_hdr, 713d8899132SKalle Valo .rx_desc_get_crypto_header = ath12k_hw_qcn9274_rx_desc_get_crypto_hdr, 714d8899132SKalle Valo .rx_desc_get_mpdu_frame_ctl = ath12k_hw_qcn9274_rx_desc_get_mpdu_frame_ctl, 715d8899132SKalle Valo .create_srng_config = ath12k_hal_srng_create_config_qcn9274, 716d8899132SKalle Valo .tcl_to_wbm_rbm_map = ath12k_hal_qcn9274_tcl_to_wbm_rbm_map, 717d8899132SKalle Valo .dp_rx_h_msdu_done = ath12k_hw_qcn9274_dp_rx_h_msdu_done, 718d8899132SKalle Valo .dp_rx_h_l4_cksum_fail = ath12k_hw_qcn9274_dp_rx_h_l4_cksum_fail, 719d8899132SKalle Valo .dp_rx_h_ip_cksum_fail = ath12k_hw_qcn9274_dp_rx_h_ip_cksum_fail, 720d8899132SKalle Valo .dp_rx_h_is_decrypted = ath12k_hw_qcn9274_dp_rx_h_is_decrypted, 721d8899132SKalle Valo .dp_rx_h_mpdu_err = ath12k_hw_qcn9274_dp_rx_h_mpdu_err, 722d8899132SKalle Valo }; 723d8899132SKalle Valo 724d8899132SKalle Valo static bool ath12k_hw_wcn7850_rx_desc_get_first_msdu(struct hal_rx_desc *desc) 725d8899132SKalle Valo { 726d8899132SKalle Valo return !!le16_get_bits(desc->u.wcn7850.msdu_end.info5, 727d8899132SKalle Valo RX_MSDU_END_INFO5_FIRST_MSDU); 728d8899132SKalle Valo } 729d8899132SKalle Valo 730d8899132SKalle Valo static bool ath12k_hw_wcn7850_rx_desc_get_last_msdu(struct hal_rx_desc *desc) 731d8899132SKalle Valo { 732d8899132SKalle Valo return !!le16_get_bits(desc->u.wcn7850.msdu_end.info5, 733d8899132SKalle Valo RX_MSDU_END_INFO5_LAST_MSDU); 734d8899132SKalle Valo } 735d8899132SKalle Valo 736d8899132SKalle Valo static u8 ath12k_hw_wcn7850_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc) 737d8899132SKalle Valo { 738d8899132SKalle Valo return le16_get_bits(desc->u.wcn7850.msdu_end.info5, 739d8899132SKalle Valo RX_MSDU_END_INFO5_L3_HDR_PADDING); 740d8899132SKalle Valo } 741d8899132SKalle Valo 742d8899132SKalle Valo static bool ath12k_hw_wcn7850_rx_desc_encrypt_valid(struct hal_rx_desc *desc) 743d8899132SKalle Valo { 744d8899132SKalle Valo return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4, 745d8899132SKalle Valo RX_MPDU_START_INFO4_ENCRYPT_INFO_VALID); 746d8899132SKalle Valo } 747d8899132SKalle Valo 748d8899132SKalle Valo static u32 ath12k_hw_wcn7850_rx_desc_get_encrypt_type(struct hal_rx_desc *desc) 749d8899132SKalle Valo { 750d8899132SKalle Valo return le32_get_bits(desc->u.wcn7850.mpdu_start.info2, 751d8899132SKalle Valo RX_MPDU_START_INFO2_ENC_TYPE); 752d8899132SKalle Valo } 753d8899132SKalle Valo 754d8899132SKalle Valo static u8 ath12k_hw_wcn7850_rx_desc_get_decap_type(struct hal_rx_desc *desc) 755d8899132SKalle Valo { 756d8899132SKalle Valo return le32_get_bits(desc->u.wcn7850.msdu_end.info11, 757d8899132SKalle Valo RX_MSDU_END_INFO11_DECAP_FORMAT); 758d8899132SKalle Valo } 759d8899132SKalle Valo 760d8899132SKalle Valo static u8 ath12k_hw_wcn7850_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc) 761d8899132SKalle Valo { 762d8899132SKalle Valo return le32_get_bits(desc->u.wcn7850.msdu_end.info11, 763d8899132SKalle Valo RX_MSDU_END_INFO11_MESH_CTRL_PRESENT); 764d8899132SKalle Valo } 765d8899132SKalle Valo 766d8899132SKalle Valo static bool ath12k_hw_wcn7850_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc) 767d8899132SKalle Valo { 768d8899132SKalle Valo return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4, 769d8899132SKalle Valo RX_MPDU_START_INFO4_MPDU_SEQ_CTRL_VALID); 770d8899132SKalle Valo } 771d8899132SKalle Valo 772d8899132SKalle Valo static bool ath12k_hw_wcn7850_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc) 773d8899132SKalle Valo { 774d8899132SKalle Valo return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4, 775d8899132SKalle Valo RX_MPDU_START_INFO4_MPDU_FCTRL_VALID); 776d8899132SKalle Valo } 777d8899132SKalle Valo 778d8899132SKalle Valo static u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc) 779d8899132SKalle Valo { 780d8899132SKalle Valo return le32_get_bits(desc->u.wcn7850.mpdu_start.info4, 781d8899132SKalle Valo RX_MPDU_START_INFO4_MPDU_SEQ_NUM); 782d8899132SKalle Valo } 783d8899132SKalle Valo 784d8899132SKalle Valo static u16 ath12k_hw_wcn7850_rx_desc_get_msdu_len(struct hal_rx_desc *desc) 785d8899132SKalle Valo { 786d8899132SKalle Valo return le32_get_bits(desc->u.wcn7850.msdu_end.info10, 787d8899132SKalle Valo RX_MSDU_END_INFO10_MSDU_LENGTH); 788d8899132SKalle Valo } 789d8899132SKalle Valo 790d8899132SKalle Valo static u8 ath12k_hw_wcn7850_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc) 791d8899132SKalle Valo { 792d8899132SKalle Valo return le32_get_bits(desc->u.wcn7850.msdu_end.info12, 793d8899132SKalle Valo RX_MSDU_END_INFO12_SGI); 794d8899132SKalle Valo } 795d8899132SKalle Valo 796d8899132SKalle Valo static u8 ath12k_hw_wcn7850_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc) 797d8899132SKalle Valo { 798d8899132SKalle Valo return le32_get_bits(desc->u.wcn7850.msdu_end.info12, 799d8899132SKalle Valo RX_MSDU_END_INFO12_RATE_MCS); 800d8899132SKalle Valo } 801d8899132SKalle Valo 802d8899132SKalle Valo static u8 ath12k_hw_wcn7850_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc) 803d8899132SKalle Valo { 804d8899132SKalle Valo return le32_get_bits(desc->u.wcn7850.msdu_end.info12, 805d8899132SKalle Valo RX_MSDU_END_INFO12_RECV_BW); 806d8899132SKalle Valo } 807d8899132SKalle Valo 808d8899132SKalle Valo static u32 ath12k_hw_wcn7850_rx_desc_get_msdu_freq(struct hal_rx_desc *desc) 809d8899132SKalle Valo { 810d8899132SKalle Valo return __le32_to_cpu(desc->u.wcn7850.msdu_end.phy_meta_data); 811d8899132SKalle Valo } 812d8899132SKalle Valo 813d8899132SKalle Valo static u8 ath12k_hw_wcn7850_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc) 814d8899132SKalle Valo { 815d8899132SKalle Valo return le32_get_bits(desc->u.wcn7850.msdu_end.info12, 816d8899132SKalle Valo RX_MSDU_END_INFO12_PKT_TYPE); 817d8899132SKalle Valo } 818d8899132SKalle Valo 819d8899132SKalle Valo static u8 ath12k_hw_wcn7850_rx_desc_get_msdu_nss(struct hal_rx_desc *desc) 820d8899132SKalle Valo { 821d8899132SKalle Valo return le32_get_bits(desc->u.wcn7850.msdu_end.info12, 822d8899132SKalle Valo RX_MSDU_END_INFO12_MIMO_SS_BITMAP); 823d8899132SKalle Valo } 824d8899132SKalle Valo 825d8899132SKalle Valo static u8 ath12k_hw_wcn7850_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc) 826d8899132SKalle Valo { 827d8899132SKalle Valo return le16_get_bits(desc->u.wcn7850.msdu_end.info5, 828d8899132SKalle Valo RX_MSDU_END_INFO5_TID); 829d8899132SKalle Valo } 830d8899132SKalle Valo 831d8899132SKalle Valo static u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc) 832d8899132SKalle Valo { 833d8899132SKalle Valo return __le16_to_cpu(desc->u.wcn7850.mpdu_start.sw_peer_id); 834d8899132SKalle Valo } 835d8899132SKalle Valo 836d8899132SKalle Valo static void ath12k_hw_wcn7850_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc, 837d8899132SKalle Valo struct hal_rx_desc *ldesc) 838d8899132SKalle Valo { 839d8899132SKalle Valo memcpy(&fdesc->u.wcn7850.msdu_end, &ldesc->u.wcn7850.msdu_end, 840d8899132SKalle Valo sizeof(struct rx_msdu_end_qcn9274)); 841d8899132SKalle Valo } 842d8899132SKalle Valo 843d8899132SKalle Valo static u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_tag(struct hal_rx_desc *desc) 844d8899132SKalle Valo { 845d8899132SKalle Valo return le64_get_bits(desc->u.wcn7850.mpdu_start_tag, 846d8899132SKalle Valo HAL_TLV_HDR_TAG); 847d8899132SKalle Valo } 848d8899132SKalle Valo 849d8899132SKalle Valo static u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc) 850d8899132SKalle Valo { 851d8899132SKalle Valo return __le16_to_cpu(desc->u.wcn7850.mpdu_start.phy_ppdu_id); 852d8899132SKalle Valo } 853d8899132SKalle Valo 854d8899132SKalle Valo static void ath12k_hw_wcn7850_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len) 855d8899132SKalle Valo { 856d8899132SKalle Valo u32 info = __le32_to_cpu(desc->u.wcn7850.msdu_end.info10); 857d8899132SKalle Valo 858d8899132SKalle Valo info &= ~RX_MSDU_END_INFO10_MSDU_LENGTH; 859d8899132SKalle Valo info |= u32_encode_bits(len, RX_MSDU_END_INFO10_MSDU_LENGTH); 860d8899132SKalle Valo 861d8899132SKalle Valo desc->u.wcn7850.msdu_end.info10 = __cpu_to_le32(info); 862d8899132SKalle Valo } 863d8899132SKalle Valo 864d8899132SKalle Valo static u8 *ath12k_hw_wcn7850_rx_desc_get_msdu_payload(struct hal_rx_desc *desc) 865d8899132SKalle Valo { 866d8899132SKalle Valo return &desc->u.wcn7850.msdu_payload[0]; 867d8899132SKalle Valo } 868d8899132SKalle Valo 869d8899132SKalle Valo static u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_offset(void) 870d8899132SKalle Valo { 871d8899132SKalle Valo return offsetof(struct hal_rx_desc_wcn7850, mpdu_start_tag); 872d8899132SKalle Valo } 873d8899132SKalle Valo 874d8899132SKalle Valo static u32 ath12k_hw_wcn7850_rx_desc_get_msdu_end_offset(void) 875d8899132SKalle Valo { 876d8899132SKalle Valo return offsetof(struct hal_rx_desc_wcn7850, msdu_end_tag); 877d8899132SKalle Valo } 878d8899132SKalle Valo 879d8899132SKalle Valo static bool ath12k_hw_wcn7850_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) 880d8899132SKalle Valo { 881d8899132SKalle Valo return __le32_to_cpu(desc->u.wcn7850.mpdu_start.info4) & 882d8899132SKalle Valo RX_MPDU_START_INFO4_MAC_ADDR2_VALID; 883d8899132SKalle Valo } 884d8899132SKalle Valo 885d8899132SKalle Valo static u8 *ath12k_hw_wcn7850_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) 886d8899132SKalle Valo { 887d8899132SKalle Valo return desc->u.wcn7850.mpdu_start.addr2; 888d8899132SKalle Valo } 889d8899132SKalle Valo 890d8899132SKalle Valo static bool ath12k_hw_wcn7850_rx_desc_is_mcbc(struct hal_rx_desc *desc) 891d8899132SKalle Valo { 892d8899132SKalle Valo return __le32_to_cpu(desc->u.wcn7850.mpdu_start.info6) & 893d8899132SKalle Valo RX_MPDU_START_INFO6_MCAST_BCAST; 894d8899132SKalle Valo } 895d8899132SKalle Valo 896d8899132SKalle Valo static void ath12k_hw_wcn7850_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, 897d8899132SKalle Valo struct ieee80211_hdr *hdr) 898d8899132SKalle Valo { 899d8899132SKalle Valo hdr->frame_control = desc->u.wcn7850.mpdu_start.frame_ctrl; 900d8899132SKalle Valo hdr->duration_id = desc->u.wcn7850.mpdu_start.duration; 901d8899132SKalle Valo ether_addr_copy(hdr->addr1, desc->u.wcn7850.mpdu_start.addr1); 902d8899132SKalle Valo ether_addr_copy(hdr->addr2, desc->u.wcn7850.mpdu_start.addr2); 903d8899132SKalle Valo ether_addr_copy(hdr->addr3, desc->u.wcn7850.mpdu_start.addr3); 904d8899132SKalle Valo if (__le32_to_cpu(desc->u.wcn7850.mpdu_start.info4) & 905d8899132SKalle Valo RX_MPDU_START_INFO4_MAC_ADDR4_VALID) { 906d8899132SKalle Valo ether_addr_copy(hdr->addr4, desc->u.wcn7850.mpdu_start.addr4); 907d8899132SKalle Valo } 908d8899132SKalle Valo hdr->seq_ctrl = desc->u.wcn7850.mpdu_start.seq_ctrl; 909d8899132SKalle Valo } 910d8899132SKalle Valo 911d8899132SKalle Valo static void ath12k_hw_wcn7850_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, 912d8899132SKalle Valo u8 *crypto_hdr, 913d8899132SKalle Valo enum hal_encrypt_type enctype) 914d8899132SKalle Valo { 915d8899132SKalle Valo unsigned int key_id; 916d8899132SKalle Valo 917d8899132SKalle Valo switch (enctype) { 918d8899132SKalle Valo case HAL_ENCRYPT_TYPE_OPEN: 919d8899132SKalle Valo return; 920d8899132SKalle Valo case HAL_ENCRYPT_TYPE_TKIP_NO_MIC: 921d8899132SKalle Valo case HAL_ENCRYPT_TYPE_TKIP_MIC: 922d8899132SKalle Valo crypto_hdr[0] = 923d8899132SKalle Valo HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.wcn7850.mpdu_start.pn[0]); 924d8899132SKalle Valo crypto_hdr[1] = 0; 925d8899132SKalle Valo crypto_hdr[2] = 926d8899132SKalle Valo HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.wcn7850.mpdu_start.pn[0]); 927d8899132SKalle Valo break; 928d8899132SKalle Valo case HAL_ENCRYPT_TYPE_CCMP_128: 929d8899132SKalle Valo case HAL_ENCRYPT_TYPE_CCMP_256: 930d8899132SKalle Valo case HAL_ENCRYPT_TYPE_GCMP_128: 931d8899132SKalle Valo case HAL_ENCRYPT_TYPE_AES_GCMP_256: 932d8899132SKalle Valo crypto_hdr[0] = 933d8899132SKalle Valo HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.wcn7850.mpdu_start.pn[0]); 934d8899132SKalle Valo crypto_hdr[1] = 935d8899132SKalle Valo HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.wcn7850.mpdu_start.pn[0]); 936d8899132SKalle Valo crypto_hdr[2] = 0; 937d8899132SKalle Valo break; 938d8899132SKalle Valo case HAL_ENCRYPT_TYPE_WEP_40: 939d8899132SKalle Valo case HAL_ENCRYPT_TYPE_WEP_104: 940d8899132SKalle Valo case HAL_ENCRYPT_TYPE_WEP_128: 941d8899132SKalle Valo case HAL_ENCRYPT_TYPE_WAPI_GCM_SM4: 942d8899132SKalle Valo case HAL_ENCRYPT_TYPE_WAPI: 943d8899132SKalle Valo return; 944d8899132SKalle Valo } 945d8899132SKalle Valo key_id = u32_get_bits(__le32_to_cpu(desc->u.wcn7850.mpdu_start.info5), 946d8899132SKalle Valo RX_MPDU_START_INFO5_KEY_ID); 947d8899132SKalle Valo crypto_hdr[3] = 0x20 | (key_id << 6); 948d8899132SKalle Valo crypto_hdr[4] = HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.wcn7850.mpdu_start.pn[0]); 949d8899132SKalle Valo crypto_hdr[5] = HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.wcn7850.mpdu_start.pn[0]); 950d8899132SKalle Valo crypto_hdr[6] = HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.wcn7850.mpdu_start.pn[1]); 951d8899132SKalle Valo crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.wcn7850.mpdu_start.pn[1]); 952d8899132SKalle Valo } 953d8899132SKalle Valo 954d8899132SKalle Valo static u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_frame_ctl(struct hal_rx_desc *desc) 955d8899132SKalle Valo { 956d8899132SKalle Valo return __le16_to_cpu(desc->u.wcn7850.mpdu_start.frame_ctrl); 957d8899132SKalle Valo } 958d8899132SKalle Valo 959d8899132SKalle Valo static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_base *ab) 960d8899132SKalle Valo { 961d8899132SKalle Valo struct ath12k_hal *hal = &ab->hal; 962d8899132SKalle Valo struct hal_srng_config *s; 963d8899132SKalle Valo 964d8899132SKalle Valo hal->srng_config = kmemdup(hw_srng_config_template, 965d8899132SKalle Valo sizeof(hw_srng_config_template), 966d8899132SKalle Valo GFP_KERNEL); 967d8899132SKalle Valo if (!hal->srng_config) 968d8899132SKalle Valo return -ENOMEM; 969d8899132SKalle Valo 970d8899132SKalle Valo s = &hal->srng_config[HAL_REO_DST]; 971d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_BASE_LSB(ab); 972d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_HP; 973d8899132SKalle Valo s->reg_size[0] = HAL_REO2_RING_BASE_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab); 974d8899132SKalle Valo s->reg_size[1] = HAL_REO2_RING_HP - HAL_REO1_RING_HP; 975d8899132SKalle Valo 976d8899132SKalle Valo s = &hal->srng_config[HAL_REO_EXCEPTION]; 977d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_BASE_LSB(ab); 978d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_HP; 979d8899132SKalle Valo 980d8899132SKalle Valo s = &hal->srng_config[HAL_REO_REINJECT]; 981d8899132SKalle Valo s->max_rings = 1; 982d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_BASE_LSB(ab); 983d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_HP; 984d8899132SKalle Valo 985d8899132SKalle Valo s = &hal->srng_config[HAL_REO_CMD]; 986d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_RING_BASE_LSB(ab); 987d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_HP; 988d8899132SKalle Valo 989d8899132SKalle Valo s = &hal->srng_config[HAL_REO_STATUS]; 990d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_RING_BASE_LSB(ab); 991d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_HP; 992d8899132SKalle Valo 993d8899132SKalle Valo s = &hal->srng_config[HAL_TCL_DATA]; 994d8899132SKalle Valo s->max_rings = 5; 995d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_BASE_LSB; 996d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_HP; 997d8899132SKalle Valo s->reg_size[0] = HAL_TCL2_RING_BASE_LSB - HAL_TCL1_RING_BASE_LSB; 998d8899132SKalle Valo s->reg_size[1] = HAL_TCL2_RING_HP - HAL_TCL1_RING_HP; 999d8899132SKalle Valo 1000d8899132SKalle Valo s = &hal->srng_config[HAL_TCL_CMD]; 1001d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_BASE_LSB(ab); 1002d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_HP; 1003d8899132SKalle Valo 1004d8899132SKalle Valo s = &hal->srng_config[HAL_TCL_STATUS]; 1005d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_BASE_LSB(ab); 1006d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP; 1007d8899132SKalle Valo 1008d8899132SKalle Valo s = &hal->srng_config[HAL_CE_SRC]; 1009d8899132SKalle Valo s->max_rings = 12; 1010d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG + HAL_CE_DST_RING_BASE_LSB; 1011d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG + HAL_CE_DST_RING_HP; 1012d8899132SKalle Valo s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG - 1013d8899132SKalle Valo HAL_SEQ_WCSS_UMAC_CE0_SRC_REG; 1014d8899132SKalle Valo s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG - 1015d8899132SKalle Valo HAL_SEQ_WCSS_UMAC_CE0_SRC_REG; 1016d8899132SKalle Valo 1017d8899132SKalle Valo s = &hal->srng_config[HAL_CE_DST]; 1018d8899132SKalle Valo s->max_rings = 12; 1019d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG + HAL_CE_DST_RING_BASE_LSB; 1020d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG + HAL_CE_DST_RING_HP; 1021d8899132SKalle Valo s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG - 1022d8899132SKalle Valo HAL_SEQ_WCSS_UMAC_CE0_DST_REG; 1023d8899132SKalle Valo s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG - 1024d8899132SKalle Valo HAL_SEQ_WCSS_UMAC_CE0_DST_REG; 1025d8899132SKalle Valo 1026d8899132SKalle Valo s = &hal->srng_config[HAL_CE_DST_STATUS]; 1027d8899132SKalle Valo s->max_rings = 12; 1028d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG + 1029d8899132SKalle Valo HAL_CE_DST_STATUS_RING_BASE_LSB; 1030d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG + HAL_CE_DST_STATUS_RING_HP; 1031d8899132SKalle Valo s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG - 1032d8899132SKalle Valo HAL_SEQ_WCSS_UMAC_CE0_DST_REG; 1033d8899132SKalle Valo s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG - 1034d8899132SKalle Valo HAL_SEQ_WCSS_UMAC_CE0_DST_REG; 1035d8899132SKalle Valo 1036d8899132SKalle Valo s = &hal->srng_config[HAL_WBM_IDLE_LINK]; 1037d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_BASE_LSB(ab); 1038d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_HP; 1039d8899132SKalle Valo 1040d8899132SKalle Valo s = &hal->srng_config[HAL_SW2WBM_RELEASE]; 1041d8899132SKalle Valo s->max_rings = 1; 1042d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + 1043d8899132SKalle Valo HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab); 1044d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SW_RELEASE_RING_HP; 1045d8899132SKalle Valo 1046d8899132SKalle Valo s = &hal->srng_config[HAL_WBM2SW_RELEASE]; 1047d8899132SKalle Valo s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_BASE_LSB(ab); 1048d8899132SKalle Valo s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_HP; 1049d8899132SKalle Valo s->reg_size[0] = HAL_WBM1_RELEASE_RING_BASE_LSB(ab) - 1050d8899132SKalle Valo HAL_WBM0_RELEASE_RING_BASE_LSB(ab); 1051d8899132SKalle Valo s->reg_size[1] = HAL_WBM1_RELEASE_RING_HP - HAL_WBM0_RELEASE_RING_HP; 1052d8899132SKalle Valo 1053d8899132SKalle Valo s = &hal->srng_config[HAL_RXDMA_BUF]; 1054d8899132SKalle Valo s->max_rings = 2; 1055d8899132SKalle Valo s->mac_type = ATH12K_HAL_SRNG_PMAC; 1056d8899132SKalle Valo 1057d8899132SKalle Valo s = &hal->srng_config[HAL_RXDMA_DST]; 1058d8899132SKalle Valo s->max_rings = 1; 1059d8899132SKalle Valo s->entry_size = sizeof(struct hal_reo_entrance_ring) >> 2; 1060d8899132SKalle Valo 1061d8899132SKalle Valo /* below rings are not used */ 1062d8899132SKalle Valo s = &hal->srng_config[HAL_RXDMA_DIR_BUF]; 1063d8899132SKalle Valo s->max_rings = 0; 1064d8899132SKalle Valo 1065d8899132SKalle Valo s = &hal->srng_config[HAL_PPE2TCL]; 1066d8899132SKalle Valo s->max_rings = 0; 1067d8899132SKalle Valo 1068d8899132SKalle Valo s = &hal->srng_config[HAL_PPE_RELEASE]; 1069d8899132SKalle Valo s->max_rings = 0; 1070d8899132SKalle Valo 1071d8899132SKalle Valo s = &hal->srng_config[HAL_TX_MONITOR_BUF]; 1072d8899132SKalle Valo s->max_rings = 0; 1073d8899132SKalle Valo 1074d8899132SKalle Valo s = &hal->srng_config[HAL_TX_MONITOR_DST]; 1075d8899132SKalle Valo s->max_rings = 0; 1076d8899132SKalle Valo 1077d8899132SKalle Valo s = &hal->srng_config[HAL_PPE2TCL]; 1078d8899132SKalle Valo s->max_rings = 0; 1079d8899132SKalle Valo 1080d8899132SKalle Valo return 0; 1081d8899132SKalle Valo } 1082d8899132SKalle Valo 1083d8899132SKalle Valo static bool ath12k_hw_wcn7850_dp_rx_h_msdu_done(struct hal_rx_desc *desc) 1084d8899132SKalle Valo { 1085d8899132SKalle Valo return !!le32_get_bits(desc->u.wcn7850.msdu_end.info14, 1086d8899132SKalle Valo RX_MSDU_END_INFO14_MSDU_DONE); 1087d8899132SKalle Valo } 1088d8899132SKalle Valo 1089d8899132SKalle Valo static bool ath12k_hw_wcn7850_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc) 1090d8899132SKalle Valo { 1091d8899132SKalle Valo return !!le32_get_bits(desc->u.wcn7850.msdu_end.info13, 1092d8899132SKalle Valo RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL); 1093d8899132SKalle Valo } 1094d8899132SKalle Valo 1095d8899132SKalle Valo static bool ath12k_hw_wcn7850_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc) 1096d8899132SKalle Valo { 1097d8899132SKalle Valo return !!le32_get_bits(desc->u.wcn7850.msdu_end.info13, 1098d8899132SKalle Valo RX_MSDU_END_INFO13_IP_CKSUM_FAIL); 1099d8899132SKalle Valo } 1100d8899132SKalle Valo 1101d8899132SKalle Valo static bool ath12k_hw_wcn7850_dp_rx_h_is_decrypted(struct hal_rx_desc *desc) 1102d8899132SKalle Valo { 1103d8899132SKalle Valo return (le32_get_bits(desc->u.wcn7850.msdu_end.info14, 1104d8899132SKalle Valo RX_MSDU_END_INFO14_DECRYPT_STATUS_CODE) == 1105d8899132SKalle Valo RX_DESC_DECRYPT_STATUS_CODE_OK); 1106d8899132SKalle Valo } 1107d8899132SKalle Valo 1108d8899132SKalle Valo static u32 ath12k_hw_wcn7850_dp_rx_h_mpdu_err(struct hal_rx_desc *desc) 1109d8899132SKalle Valo { 1110d8899132SKalle Valo u32 info = __le32_to_cpu(desc->u.wcn7850.msdu_end.info13); 1111d8899132SKalle Valo u32 errmap = 0; 1112d8899132SKalle Valo 1113d8899132SKalle Valo if (info & RX_MSDU_END_INFO13_FCS_ERR) 1114d8899132SKalle Valo errmap |= HAL_RX_MPDU_ERR_FCS; 1115d8899132SKalle Valo 1116d8899132SKalle Valo if (info & RX_MSDU_END_INFO13_DECRYPT_ERR) 1117d8899132SKalle Valo errmap |= HAL_RX_MPDU_ERR_DECRYPT; 1118d8899132SKalle Valo 1119d8899132SKalle Valo if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR) 1120d8899132SKalle Valo errmap |= HAL_RX_MPDU_ERR_TKIP_MIC; 1121d8899132SKalle Valo 1122d8899132SKalle Valo if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR) 1123d8899132SKalle Valo errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR; 1124d8899132SKalle Valo 1125d8899132SKalle Valo if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR) 1126d8899132SKalle Valo errmap |= HAL_RX_MPDU_ERR_OVERFLOW; 1127d8899132SKalle Valo 1128d8899132SKalle Valo if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR) 1129d8899132SKalle Valo errmap |= HAL_RX_MPDU_ERR_MSDU_LEN; 1130d8899132SKalle Valo 1131d8899132SKalle Valo if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR) 1132d8899132SKalle Valo errmap |= HAL_RX_MPDU_ERR_MPDU_LEN; 1133d8899132SKalle Valo 1134d8899132SKalle Valo return errmap; 1135d8899132SKalle Valo } 1136d8899132SKalle Valo 1137d8899132SKalle Valo const struct hal_ops hal_wcn7850_ops = { 1138d8899132SKalle Valo .rx_desc_get_first_msdu = ath12k_hw_wcn7850_rx_desc_get_first_msdu, 1139d8899132SKalle Valo .rx_desc_get_last_msdu = ath12k_hw_wcn7850_rx_desc_get_last_msdu, 1140d8899132SKalle Valo .rx_desc_get_l3_pad_bytes = ath12k_hw_wcn7850_rx_desc_get_l3_pad_bytes, 1141d8899132SKalle Valo .rx_desc_encrypt_valid = ath12k_hw_wcn7850_rx_desc_encrypt_valid, 1142d8899132SKalle Valo .rx_desc_get_encrypt_type = ath12k_hw_wcn7850_rx_desc_get_encrypt_type, 1143d8899132SKalle Valo .rx_desc_get_decap_type = ath12k_hw_wcn7850_rx_desc_get_decap_type, 1144d8899132SKalle Valo .rx_desc_get_mesh_ctl = ath12k_hw_wcn7850_rx_desc_get_mesh_ctl, 1145d8899132SKalle Valo .rx_desc_get_mpdu_seq_ctl_vld = ath12k_hw_wcn7850_rx_desc_get_mpdu_seq_ctl_vld, 1146d8899132SKalle Valo .rx_desc_get_mpdu_fc_valid = ath12k_hw_wcn7850_rx_desc_get_mpdu_fc_valid, 1147d8899132SKalle Valo .rx_desc_get_mpdu_start_seq_no = ath12k_hw_wcn7850_rx_desc_get_mpdu_start_seq_no, 1148d8899132SKalle Valo .rx_desc_get_msdu_len = ath12k_hw_wcn7850_rx_desc_get_msdu_len, 1149d8899132SKalle Valo .rx_desc_get_msdu_sgi = ath12k_hw_wcn7850_rx_desc_get_msdu_sgi, 1150d8899132SKalle Valo .rx_desc_get_msdu_rate_mcs = ath12k_hw_wcn7850_rx_desc_get_msdu_rate_mcs, 1151d8899132SKalle Valo .rx_desc_get_msdu_rx_bw = ath12k_hw_wcn7850_rx_desc_get_msdu_rx_bw, 1152d8899132SKalle Valo .rx_desc_get_msdu_freq = ath12k_hw_wcn7850_rx_desc_get_msdu_freq, 1153d8899132SKalle Valo .rx_desc_get_msdu_pkt_type = ath12k_hw_wcn7850_rx_desc_get_msdu_pkt_type, 1154d8899132SKalle Valo .rx_desc_get_msdu_nss = ath12k_hw_wcn7850_rx_desc_get_msdu_nss, 1155d8899132SKalle Valo .rx_desc_get_mpdu_tid = ath12k_hw_wcn7850_rx_desc_get_mpdu_tid, 1156d8899132SKalle Valo .rx_desc_get_mpdu_peer_id = ath12k_hw_wcn7850_rx_desc_get_mpdu_peer_id, 1157d8899132SKalle Valo .rx_desc_copy_end_tlv = ath12k_hw_wcn7850_rx_desc_copy_end_tlv, 1158d8899132SKalle Valo .rx_desc_get_mpdu_start_tag = ath12k_hw_wcn7850_rx_desc_get_mpdu_start_tag, 1159d8899132SKalle Valo .rx_desc_get_mpdu_ppdu_id = ath12k_hw_wcn7850_rx_desc_get_mpdu_ppdu_id, 1160d8899132SKalle Valo .rx_desc_set_msdu_len = ath12k_hw_wcn7850_rx_desc_set_msdu_len, 1161d8899132SKalle Valo .rx_desc_get_msdu_payload = ath12k_hw_wcn7850_rx_desc_get_msdu_payload, 1162d8899132SKalle Valo .rx_desc_get_mpdu_start_offset = ath12k_hw_wcn7850_rx_desc_get_mpdu_start_offset, 1163d8899132SKalle Valo .rx_desc_get_msdu_end_offset = ath12k_hw_wcn7850_rx_desc_get_msdu_end_offset, 1164d8899132SKalle Valo .rx_desc_mac_addr2_valid = ath12k_hw_wcn7850_rx_desc_mac_addr2_valid, 1165d8899132SKalle Valo .rx_desc_mpdu_start_addr2 = ath12k_hw_wcn7850_rx_desc_mpdu_start_addr2, 1166d8899132SKalle Valo .rx_desc_is_mcbc = ath12k_hw_wcn7850_rx_desc_is_mcbc, 1167d8899132SKalle Valo .rx_desc_get_dot11_hdr = ath12k_hw_wcn7850_rx_desc_get_dot11_hdr, 1168d8899132SKalle Valo .rx_desc_get_crypto_header = ath12k_hw_wcn7850_rx_desc_get_crypto_hdr, 1169d8899132SKalle Valo .rx_desc_get_mpdu_frame_ctl = ath12k_hw_wcn7850_rx_desc_get_mpdu_frame_ctl, 1170d8899132SKalle Valo .create_srng_config = ath12k_hal_srng_create_config_wcn7850, 1171d8899132SKalle Valo .tcl_to_wbm_rbm_map = ath12k_hal_wcn7850_tcl_to_wbm_rbm_map, 1172d8899132SKalle Valo .dp_rx_h_msdu_done = ath12k_hw_wcn7850_dp_rx_h_msdu_done, 1173d8899132SKalle Valo .dp_rx_h_l4_cksum_fail = ath12k_hw_wcn7850_dp_rx_h_l4_cksum_fail, 1174d8899132SKalle Valo .dp_rx_h_ip_cksum_fail = ath12k_hw_wcn7850_dp_rx_h_ip_cksum_fail, 1175d8899132SKalle Valo .dp_rx_h_is_decrypted = ath12k_hw_wcn7850_dp_rx_h_is_decrypted, 1176d8899132SKalle Valo .dp_rx_h_mpdu_err = ath12k_hw_wcn7850_dp_rx_h_mpdu_err, 1177d8899132SKalle Valo }; 1178d8899132SKalle Valo 1179d8899132SKalle Valo static int ath12k_hal_alloc_cont_rdp(struct ath12k_base *ab) 1180d8899132SKalle Valo { 1181d8899132SKalle Valo struct ath12k_hal *hal = &ab->hal; 1182d8899132SKalle Valo size_t size; 1183d8899132SKalle Valo 1184d8899132SKalle Valo size = sizeof(u32) * HAL_SRNG_RING_ID_MAX; 1185d8899132SKalle Valo hal->rdp.vaddr = dma_alloc_coherent(ab->dev, size, &hal->rdp.paddr, 1186d8899132SKalle Valo GFP_KERNEL); 1187d8899132SKalle Valo if (!hal->rdp.vaddr) 1188d8899132SKalle Valo return -ENOMEM; 1189d8899132SKalle Valo 1190d8899132SKalle Valo return 0; 1191d8899132SKalle Valo } 1192d8899132SKalle Valo 1193d8899132SKalle Valo static void ath12k_hal_free_cont_rdp(struct ath12k_base *ab) 1194d8899132SKalle Valo { 1195d8899132SKalle Valo struct ath12k_hal *hal = &ab->hal; 1196d8899132SKalle Valo size_t size; 1197d8899132SKalle Valo 1198d8899132SKalle Valo if (!hal->rdp.vaddr) 1199d8899132SKalle Valo return; 1200d8899132SKalle Valo 1201d8899132SKalle Valo size = sizeof(u32) * HAL_SRNG_RING_ID_MAX; 1202d8899132SKalle Valo dma_free_coherent(ab->dev, size, 1203d8899132SKalle Valo hal->rdp.vaddr, hal->rdp.paddr); 1204d8899132SKalle Valo hal->rdp.vaddr = NULL; 1205d8899132SKalle Valo } 1206d8899132SKalle Valo 1207d8899132SKalle Valo static int ath12k_hal_alloc_cont_wrp(struct ath12k_base *ab) 1208d8899132SKalle Valo { 1209d8899132SKalle Valo struct ath12k_hal *hal = &ab->hal; 1210d8899132SKalle Valo size_t size; 1211d8899132SKalle Valo 1212d8899132SKalle Valo size = sizeof(u32) * (HAL_SRNG_NUM_PMAC_RINGS + HAL_SRNG_NUM_DMAC_RINGS); 1213d8899132SKalle Valo hal->wrp.vaddr = dma_alloc_coherent(ab->dev, size, &hal->wrp.paddr, 1214d8899132SKalle Valo GFP_KERNEL); 1215d8899132SKalle Valo if (!hal->wrp.vaddr) 1216d8899132SKalle Valo return -ENOMEM; 1217d8899132SKalle Valo 1218d8899132SKalle Valo return 0; 1219d8899132SKalle Valo } 1220d8899132SKalle Valo 1221d8899132SKalle Valo static void ath12k_hal_free_cont_wrp(struct ath12k_base *ab) 1222d8899132SKalle Valo { 1223d8899132SKalle Valo struct ath12k_hal *hal = &ab->hal; 1224d8899132SKalle Valo size_t size; 1225d8899132SKalle Valo 1226d8899132SKalle Valo if (!hal->wrp.vaddr) 1227d8899132SKalle Valo return; 1228d8899132SKalle Valo 1229d8899132SKalle Valo size = sizeof(u32) * (HAL_SRNG_NUM_PMAC_RINGS + HAL_SRNG_NUM_DMAC_RINGS); 1230d8899132SKalle Valo dma_free_coherent(ab->dev, size, 1231d8899132SKalle Valo hal->wrp.vaddr, hal->wrp.paddr); 1232d8899132SKalle Valo hal->wrp.vaddr = NULL; 1233d8899132SKalle Valo } 1234d8899132SKalle Valo 1235d8899132SKalle Valo static void ath12k_hal_ce_dst_setup(struct ath12k_base *ab, 1236d8899132SKalle Valo struct hal_srng *srng, int ring_num) 1237d8899132SKalle Valo { 1238d8899132SKalle Valo struct hal_srng_config *srng_config = &ab->hal.srng_config[HAL_CE_DST]; 1239d8899132SKalle Valo u32 addr; 1240d8899132SKalle Valo u32 val; 1241d8899132SKalle Valo 1242d8899132SKalle Valo addr = HAL_CE_DST_RING_CTRL + 1243d8899132SKalle Valo srng_config->reg_start[HAL_SRNG_REG_GRP_R0] + 1244d8899132SKalle Valo ring_num * srng_config->reg_size[HAL_SRNG_REG_GRP_R0]; 1245d8899132SKalle Valo 1246d8899132SKalle Valo val = ath12k_hif_read32(ab, addr); 1247d8899132SKalle Valo val &= ~HAL_CE_DST_R0_DEST_CTRL_MAX_LEN; 1248d8899132SKalle Valo val |= u32_encode_bits(srng->u.dst_ring.max_buffer_length, 1249d8899132SKalle Valo HAL_CE_DST_R0_DEST_CTRL_MAX_LEN); 1250d8899132SKalle Valo ath12k_hif_write32(ab, addr, val); 1251d8899132SKalle Valo } 1252d8899132SKalle Valo 1253d8899132SKalle Valo static void ath12k_hal_srng_dst_hw_init(struct ath12k_base *ab, 1254d8899132SKalle Valo struct hal_srng *srng) 1255d8899132SKalle Valo { 1256d8899132SKalle Valo struct ath12k_hal *hal = &ab->hal; 1257d8899132SKalle Valo u32 val; 1258d8899132SKalle Valo u64 hp_addr; 1259d8899132SKalle Valo u32 reg_base; 1260d8899132SKalle Valo 1261d8899132SKalle Valo reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; 1262d8899132SKalle Valo 1263d8899132SKalle Valo if (srng->flags & HAL_SRNG_FLAGS_MSI_INTR) { 1264d8899132SKalle Valo ath12k_hif_write32(ab, reg_base + 1265*f8209eefSKalle Valo ath12k_hal_reo1_ring_msi1_base_lsb_offset(ab), 1266d8899132SKalle Valo srng->msi_addr); 1267d8899132SKalle Valo 1268d8899132SKalle Valo val = u32_encode_bits(((u64)srng->msi_addr >> HAL_ADDR_MSB_REG_SHIFT), 1269d8899132SKalle Valo HAL_REO1_RING_MSI1_BASE_MSB_ADDR) | 1270d8899132SKalle Valo HAL_REO1_RING_MSI1_BASE_MSB_MSI1_ENABLE; 1271d8899132SKalle Valo ath12k_hif_write32(ab, reg_base + 1272*f8209eefSKalle Valo ath12k_hal_reo1_ring_msi1_base_msb_offset(ab), val); 1273d8899132SKalle Valo 1274d8899132SKalle Valo ath12k_hif_write32(ab, 1275*f8209eefSKalle Valo reg_base + ath12k_hal_reo1_ring_msi1_data_offset(ab), 1276d8899132SKalle Valo srng->msi_data); 1277d8899132SKalle Valo } 1278d8899132SKalle Valo 1279d8899132SKalle Valo ath12k_hif_write32(ab, reg_base, srng->ring_base_paddr); 1280d8899132SKalle Valo 1281d8899132SKalle Valo val = u32_encode_bits(((u64)srng->ring_base_paddr >> HAL_ADDR_MSB_REG_SHIFT), 1282d8899132SKalle Valo HAL_REO1_RING_BASE_MSB_RING_BASE_ADDR_MSB) | 1283d8899132SKalle Valo u32_encode_bits((srng->entry_size * srng->num_entries), 1284d8899132SKalle Valo HAL_REO1_RING_BASE_MSB_RING_SIZE); 1285*f8209eefSKalle Valo ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_base_msb_offset(ab), val); 1286d8899132SKalle Valo 1287d8899132SKalle Valo val = u32_encode_bits(srng->ring_id, HAL_REO1_RING_ID_RING_ID) | 1288d8899132SKalle Valo u32_encode_bits(srng->entry_size, HAL_REO1_RING_ID_ENTRY_SIZE); 1289*f8209eefSKalle Valo ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_id_offset(ab), val); 1290d8899132SKalle Valo 1291d8899132SKalle Valo /* interrupt setup */ 1292d8899132SKalle Valo val = u32_encode_bits((srng->intr_timer_thres_us >> 3), 1293d8899132SKalle Valo HAL_REO1_RING_PRDR_INT_SETUP_INTR_TMR_THOLD); 1294d8899132SKalle Valo 1295d8899132SKalle Valo val |= u32_encode_bits((srng->intr_batch_cntr_thres_entries * srng->entry_size), 1296d8899132SKalle Valo HAL_REO1_RING_PRDR_INT_SETUP_BATCH_COUNTER_THOLD); 1297d8899132SKalle Valo 1298d8899132SKalle Valo ath12k_hif_write32(ab, 1299*f8209eefSKalle Valo reg_base + ath12k_hal_reo1_ring_producer_int_setup_offset(ab), 1300d8899132SKalle Valo val); 1301d8899132SKalle Valo 1302d8899132SKalle Valo hp_addr = hal->rdp.paddr + 1303d8899132SKalle Valo ((unsigned long)srng->u.dst_ring.hp_addr - 1304d8899132SKalle Valo (unsigned long)hal->rdp.vaddr); 1305*f8209eefSKalle Valo ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_hp_addr_lsb_offset(ab), 1306d8899132SKalle Valo hp_addr & HAL_ADDR_LSB_REG_MASK); 1307*f8209eefSKalle Valo ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_hp_addr_msb_offset(ab), 1308d8899132SKalle Valo hp_addr >> HAL_ADDR_MSB_REG_SHIFT); 1309d8899132SKalle Valo 1310d8899132SKalle Valo /* Initialize head and tail pointers to indicate ring is empty */ 1311d8899132SKalle Valo reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2]; 1312d8899132SKalle Valo ath12k_hif_write32(ab, reg_base, 0); 1313d8899132SKalle Valo ath12k_hif_write32(ab, reg_base + HAL_REO1_RING_TP_OFFSET, 0); 1314d8899132SKalle Valo *srng->u.dst_ring.hp_addr = 0; 1315d8899132SKalle Valo 1316d8899132SKalle Valo reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; 1317d8899132SKalle Valo val = 0; 1318d8899132SKalle Valo if (srng->flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP) 1319d8899132SKalle Valo val |= HAL_REO1_RING_MISC_DATA_TLV_SWAP; 1320d8899132SKalle Valo if (srng->flags & HAL_SRNG_FLAGS_RING_PTR_SWAP) 1321d8899132SKalle Valo val |= HAL_REO1_RING_MISC_HOST_FW_SWAP; 1322d8899132SKalle Valo if (srng->flags & HAL_SRNG_FLAGS_MSI_SWAP) 1323d8899132SKalle Valo val |= HAL_REO1_RING_MISC_MSI_SWAP; 1324d8899132SKalle Valo val |= HAL_REO1_RING_MISC_SRNG_ENABLE; 1325d8899132SKalle Valo 1326*f8209eefSKalle Valo ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_misc_offset(ab), val); 1327d8899132SKalle Valo } 1328d8899132SKalle Valo 1329d8899132SKalle Valo static void ath12k_hal_srng_src_hw_init(struct ath12k_base *ab, 1330d8899132SKalle Valo struct hal_srng *srng) 1331d8899132SKalle Valo { 1332d8899132SKalle Valo struct ath12k_hal *hal = &ab->hal; 1333d8899132SKalle Valo u32 val; 1334d8899132SKalle Valo u64 tp_addr; 1335d8899132SKalle Valo u32 reg_base; 1336d8899132SKalle Valo 1337d8899132SKalle Valo reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; 1338d8899132SKalle Valo 1339d8899132SKalle Valo if (srng->flags & HAL_SRNG_FLAGS_MSI_INTR) { 1340d8899132SKalle Valo ath12k_hif_write32(ab, reg_base + 1341d8899132SKalle Valo HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET(ab), 1342d8899132SKalle Valo srng->msi_addr); 1343d8899132SKalle Valo 1344d8899132SKalle Valo val = u32_encode_bits(((u64)srng->msi_addr >> HAL_ADDR_MSB_REG_SHIFT), 1345d8899132SKalle Valo HAL_TCL1_RING_MSI1_BASE_MSB_ADDR) | 1346d8899132SKalle Valo HAL_TCL1_RING_MSI1_BASE_MSB_MSI1_ENABLE; 1347d8899132SKalle Valo ath12k_hif_write32(ab, reg_base + 1348d8899132SKalle Valo HAL_TCL1_RING_MSI1_BASE_MSB_OFFSET(ab), 1349d8899132SKalle Valo val); 1350d8899132SKalle Valo 1351d8899132SKalle Valo ath12k_hif_write32(ab, reg_base + 1352d8899132SKalle Valo HAL_TCL1_RING_MSI1_DATA_OFFSET(ab), 1353d8899132SKalle Valo srng->msi_data); 1354d8899132SKalle Valo } 1355d8899132SKalle Valo 1356d8899132SKalle Valo ath12k_hif_write32(ab, reg_base, srng->ring_base_paddr); 1357d8899132SKalle Valo 1358d8899132SKalle Valo val = u32_encode_bits(((u64)srng->ring_base_paddr >> HAL_ADDR_MSB_REG_SHIFT), 1359d8899132SKalle Valo HAL_TCL1_RING_BASE_MSB_RING_BASE_ADDR_MSB) | 1360d8899132SKalle Valo u32_encode_bits((srng->entry_size * srng->num_entries), 1361d8899132SKalle Valo HAL_TCL1_RING_BASE_MSB_RING_SIZE); 1362d8899132SKalle Valo ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_BASE_MSB_OFFSET, val); 1363d8899132SKalle Valo 1364d8899132SKalle Valo val = u32_encode_bits(srng->entry_size, HAL_REO1_RING_ID_ENTRY_SIZE); 1365d8899132SKalle Valo ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_ID_OFFSET(ab), val); 1366d8899132SKalle Valo 1367d8899132SKalle Valo val = u32_encode_bits(srng->intr_timer_thres_us, 1368d8899132SKalle Valo HAL_TCL1_RING_CONSR_INT_SETUP_IX0_INTR_TMR_THOLD); 1369d8899132SKalle Valo 1370d8899132SKalle Valo val |= u32_encode_bits((srng->intr_batch_cntr_thres_entries * srng->entry_size), 1371d8899132SKalle Valo HAL_TCL1_RING_CONSR_INT_SETUP_IX0_BATCH_COUNTER_THOLD); 1372d8899132SKalle Valo 1373d8899132SKalle Valo ath12k_hif_write32(ab, 1374d8899132SKalle Valo reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX0_OFFSET(ab), 1375d8899132SKalle Valo val); 1376d8899132SKalle Valo 1377d8899132SKalle Valo val = 0; 1378d8899132SKalle Valo if (srng->flags & HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN) { 1379d8899132SKalle Valo val |= u32_encode_bits(srng->u.src_ring.low_threshold, 1380d8899132SKalle Valo HAL_TCL1_RING_CONSR_INT_SETUP_IX1_LOW_THOLD); 1381d8899132SKalle Valo } 1382d8899132SKalle Valo ath12k_hif_write32(ab, 1383d8899132SKalle Valo reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX1_OFFSET(ab), 1384d8899132SKalle Valo val); 1385d8899132SKalle Valo 1386d8899132SKalle Valo if (srng->ring_id != HAL_SRNG_RING_ID_WBM_IDLE_LINK) { 1387d8899132SKalle Valo tp_addr = hal->rdp.paddr + 1388d8899132SKalle Valo ((unsigned long)srng->u.src_ring.tp_addr - 1389d8899132SKalle Valo (unsigned long)hal->rdp.vaddr); 1390d8899132SKalle Valo ath12k_hif_write32(ab, 1391d8899132SKalle Valo reg_base + HAL_TCL1_RING_TP_ADDR_LSB_OFFSET(ab), 1392d8899132SKalle Valo tp_addr & HAL_ADDR_LSB_REG_MASK); 1393d8899132SKalle Valo ath12k_hif_write32(ab, 1394d8899132SKalle Valo reg_base + HAL_TCL1_RING_TP_ADDR_MSB_OFFSET(ab), 1395d8899132SKalle Valo tp_addr >> HAL_ADDR_MSB_REG_SHIFT); 1396d8899132SKalle Valo } 1397d8899132SKalle Valo 1398d8899132SKalle Valo /* Initialize head and tail pointers to indicate ring is empty */ 1399d8899132SKalle Valo reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2]; 1400d8899132SKalle Valo ath12k_hif_write32(ab, reg_base, 0); 1401d8899132SKalle Valo ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_TP_OFFSET, 0); 1402d8899132SKalle Valo *srng->u.src_ring.tp_addr = 0; 1403d8899132SKalle Valo 1404d8899132SKalle Valo reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; 1405d8899132SKalle Valo val = 0; 1406d8899132SKalle Valo if (srng->flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP) 1407d8899132SKalle Valo val |= HAL_TCL1_RING_MISC_DATA_TLV_SWAP; 1408d8899132SKalle Valo if (srng->flags & HAL_SRNG_FLAGS_RING_PTR_SWAP) 1409d8899132SKalle Valo val |= HAL_TCL1_RING_MISC_HOST_FW_SWAP; 1410d8899132SKalle Valo if (srng->flags & HAL_SRNG_FLAGS_MSI_SWAP) 1411d8899132SKalle Valo val |= HAL_TCL1_RING_MISC_MSI_SWAP; 1412d8899132SKalle Valo 1413d8899132SKalle Valo /* Loop count is not used for SRC rings */ 1414d8899132SKalle Valo val |= HAL_TCL1_RING_MISC_MSI_LOOPCNT_DISABLE; 1415d8899132SKalle Valo 1416d8899132SKalle Valo val |= HAL_TCL1_RING_MISC_SRNG_ENABLE; 1417d8899132SKalle Valo 1418d8899132SKalle Valo if (srng->ring_id == HAL_SRNG_RING_ID_WBM_IDLE_LINK) 1419d8899132SKalle Valo val |= HAL_TCL1_RING_MISC_MSI_RING_ID_DISABLE; 1420d8899132SKalle Valo 1421d8899132SKalle Valo ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_MISC_OFFSET(ab), val); 1422d8899132SKalle Valo } 1423d8899132SKalle Valo 1424d8899132SKalle Valo static void ath12k_hal_srng_hw_init(struct ath12k_base *ab, 1425d8899132SKalle Valo struct hal_srng *srng) 1426d8899132SKalle Valo { 1427d8899132SKalle Valo if (srng->ring_dir == HAL_SRNG_DIR_SRC) 1428d8899132SKalle Valo ath12k_hal_srng_src_hw_init(ab, srng); 1429d8899132SKalle Valo else 1430d8899132SKalle Valo ath12k_hal_srng_dst_hw_init(ab, srng); 1431d8899132SKalle Valo } 1432d8899132SKalle Valo 1433d8899132SKalle Valo static int ath12k_hal_srng_get_ring_id(struct ath12k_base *ab, 1434d8899132SKalle Valo enum hal_ring_type type, 1435d8899132SKalle Valo int ring_num, int mac_id) 1436d8899132SKalle Valo { 1437d8899132SKalle Valo struct hal_srng_config *srng_config = &ab->hal.srng_config[type]; 1438d8899132SKalle Valo int ring_id; 1439d8899132SKalle Valo 1440d8899132SKalle Valo if (ring_num >= srng_config->max_rings) { 1441d8899132SKalle Valo ath12k_warn(ab, "invalid ring number :%d\n", ring_num); 1442d8899132SKalle Valo return -EINVAL; 1443d8899132SKalle Valo } 1444d8899132SKalle Valo 1445d8899132SKalle Valo ring_id = srng_config->start_ring_id + ring_num; 1446d8899132SKalle Valo if (srng_config->mac_type == ATH12K_HAL_SRNG_PMAC) 1447d8899132SKalle Valo ring_id += mac_id * HAL_SRNG_RINGS_PER_PMAC; 1448d8899132SKalle Valo 1449d8899132SKalle Valo if (WARN_ON(ring_id >= HAL_SRNG_RING_ID_MAX)) 1450d8899132SKalle Valo return -EINVAL; 1451d8899132SKalle Valo 1452d8899132SKalle Valo return ring_id; 1453d8899132SKalle Valo } 1454d8899132SKalle Valo 1455d8899132SKalle Valo int ath12k_hal_srng_get_entrysize(struct ath12k_base *ab, u32 ring_type) 1456d8899132SKalle Valo { 1457d8899132SKalle Valo struct hal_srng_config *srng_config; 1458d8899132SKalle Valo 1459d8899132SKalle Valo if (WARN_ON(ring_type >= HAL_MAX_RING_TYPES)) 1460d8899132SKalle Valo return -EINVAL; 1461d8899132SKalle Valo 1462d8899132SKalle Valo srng_config = &ab->hal.srng_config[ring_type]; 1463d8899132SKalle Valo 1464d8899132SKalle Valo return (srng_config->entry_size << 2); 1465d8899132SKalle Valo } 1466d8899132SKalle Valo 1467d8899132SKalle Valo int ath12k_hal_srng_get_max_entries(struct ath12k_base *ab, u32 ring_type) 1468d8899132SKalle Valo { 1469d8899132SKalle Valo struct hal_srng_config *srng_config; 1470d8899132SKalle Valo 1471d8899132SKalle Valo if (WARN_ON(ring_type >= HAL_MAX_RING_TYPES)) 1472d8899132SKalle Valo return -EINVAL; 1473d8899132SKalle Valo 1474d8899132SKalle Valo srng_config = &ab->hal.srng_config[ring_type]; 1475d8899132SKalle Valo 1476d8899132SKalle Valo return (srng_config->max_size / srng_config->entry_size); 1477d8899132SKalle Valo } 1478d8899132SKalle Valo 1479d8899132SKalle Valo void ath12k_hal_srng_get_params(struct ath12k_base *ab, struct hal_srng *srng, 1480d8899132SKalle Valo struct hal_srng_params *params) 1481d8899132SKalle Valo { 1482d8899132SKalle Valo params->ring_base_paddr = srng->ring_base_paddr; 1483d8899132SKalle Valo params->ring_base_vaddr = srng->ring_base_vaddr; 1484d8899132SKalle Valo params->num_entries = srng->num_entries; 1485d8899132SKalle Valo params->intr_timer_thres_us = srng->intr_timer_thres_us; 1486d8899132SKalle Valo params->intr_batch_cntr_thres_entries = 1487d8899132SKalle Valo srng->intr_batch_cntr_thres_entries; 1488d8899132SKalle Valo params->low_threshold = srng->u.src_ring.low_threshold; 1489d8899132SKalle Valo params->msi_addr = srng->msi_addr; 1490d8899132SKalle Valo params->msi2_addr = srng->msi2_addr; 1491d8899132SKalle Valo params->msi_data = srng->msi_data; 1492d8899132SKalle Valo params->msi2_data = srng->msi2_data; 1493d8899132SKalle Valo params->flags = srng->flags; 1494d8899132SKalle Valo } 1495d8899132SKalle Valo 1496d8899132SKalle Valo dma_addr_t ath12k_hal_srng_get_hp_addr(struct ath12k_base *ab, 1497d8899132SKalle Valo struct hal_srng *srng) 1498d8899132SKalle Valo { 1499d8899132SKalle Valo if (!(srng->flags & HAL_SRNG_FLAGS_LMAC_RING)) 1500d8899132SKalle Valo return 0; 1501d8899132SKalle Valo 1502d8899132SKalle Valo if (srng->ring_dir == HAL_SRNG_DIR_SRC) 1503d8899132SKalle Valo return ab->hal.wrp.paddr + 1504d8899132SKalle Valo ((unsigned long)srng->u.src_ring.hp_addr - 1505d8899132SKalle Valo (unsigned long)ab->hal.wrp.vaddr); 1506d8899132SKalle Valo else 1507d8899132SKalle Valo return ab->hal.rdp.paddr + 1508d8899132SKalle Valo ((unsigned long)srng->u.dst_ring.hp_addr - 1509d8899132SKalle Valo (unsigned long)ab->hal.rdp.vaddr); 1510d8899132SKalle Valo } 1511d8899132SKalle Valo 1512d8899132SKalle Valo dma_addr_t ath12k_hal_srng_get_tp_addr(struct ath12k_base *ab, 1513d8899132SKalle Valo struct hal_srng *srng) 1514d8899132SKalle Valo { 1515d8899132SKalle Valo if (!(srng->flags & HAL_SRNG_FLAGS_LMAC_RING)) 1516d8899132SKalle Valo return 0; 1517d8899132SKalle Valo 1518d8899132SKalle Valo if (srng->ring_dir == HAL_SRNG_DIR_SRC) 1519d8899132SKalle Valo return ab->hal.rdp.paddr + 1520d8899132SKalle Valo ((unsigned long)srng->u.src_ring.tp_addr - 1521d8899132SKalle Valo (unsigned long)ab->hal.rdp.vaddr); 1522d8899132SKalle Valo else 1523d8899132SKalle Valo return ab->hal.wrp.paddr + 1524d8899132SKalle Valo ((unsigned long)srng->u.dst_ring.tp_addr - 1525d8899132SKalle Valo (unsigned long)ab->hal.wrp.vaddr); 1526d8899132SKalle Valo } 1527d8899132SKalle Valo 1528d8899132SKalle Valo u32 ath12k_hal_ce_get_desc_size(enum hal_ce_desc type) 1529d8899132SKalle Valo { 1530d8899132SKalle Valo switch (type) { 1531d8899132SKalle Valo case HAL_CE_DESC_SRC: 1532d8899132SKalle Valo return sizeof(struct hal_ce_srng_src_desc); 1533d8899132SKalle Valo case HAL_CE_DESC_DST: 1534d8899132SKalle Valo return sizeof(struct hal_ce_srng_dest_desc); 1535d8899132SKalle Valo case HAL_CE_DESC_DST_STATUS: 1536d8899132SKalle Valo return sizeof(struct hal_ce_srng_dst_status_desc); 1537d8899132SKalle Valo } 1538d8899132SKalle Valo 1539d8899132SKalle Valo return 0; 1540d8899132SKalle Valo } 1541d8899132SKalle Valo 1542d8899132SKalle Valo void ath12k_hal_ce_src_set_desc(struct hal_ce_srng_src_desc *desc, dma_addr_t paddr, 1543d8899132SKalle Valo u32 len, u32 id, u8 byte_swap_data) 1544d8899132SKalle Valo { 1545d8899132SKalle Valo desc->buffer_addr_low = cpu_to_le32(paddr & HAL_ADDR_LSB_REG_MASK); 1546d8899132SKalle Valo desc->buffer_addr_info = 1547d8899132SKalle Valo le32_encode_bits(((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT), 1548d8899132SKalle Valo HAL_CE_SRC_DESC_ADDR_INFO_ADDR_HI) | 1549d8899132SKalle Valo le32_encode_bits(byte_swap_data, 1550d8899132SKalle Valo HAL_CE_SRC_DESC_ADDR_INFO_BYTE_SWAP) | 1551d8899132SKalle Valo le32_encode_bits(0, HAL_CE_SRC_DESC_ADDR_INFO_GATHER) | 1552d8899132SKalle Valo le32_encode_bits(len, HAL_CE_SRC_DESC_ADDR_INFO_LEN); 1553d8899132SKalle Valo desc->meta_info = le32_encode_bits(id, HAL_CE_SRC_DESC_META_INFO_DATA); 1554d8899132SKalle Valo } 1555d8899132SKalle Valo 1556d8899132SKalle Valo void ath12k_hal_ce_dst_set_desc(struct hal_ce_srng_dest_desc *desc, dma_addr_t paddr) 1557d8899132SKalle Valo { 1558d8899132SKalle Valo desc->buffer_addr_low = cpu_to_le32(paddr & HAL_ADDR_LSB_REG_MASK); 1559d8899132SKalle Valo desc->buffer_addr_info = 1560d8899132SKalle Valo le32_encode_bits(((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT), 1561d8899132SKalle Valo HAL_CE_DEST_DESC_ADDR_INFO_ADDR_HI); 1562d8899132SKalle Valo } 1563d8899132SKalle Valo 1564d8899132SKalle Valo u32 ath12k_hal_ce_dst_status_get_length(struct hal_ce_srng_dst_status_desc *desc) 1565d8899132SKalle Valo { 1566d8899132SKalle Valo u32 len; 1567d8899132SKalle Valo 1568d8899132SKalle Valo len = le32_get_bits(desc->flags, HAL_CE_DST_STATUS_DESC_FLAGS_LEN); 1569d8899132SKalle Valo desc->flags &= ~cpu_to_le32(HAL_CE_DST_STATUS_DESC_FLAGS_LEN); 1570d8899132SKalle Valo 1571d8899132SKalle Valo return len; 1572d8899132SKalle Valo } 1573d8899132SKalle Valo 1574d8899132SKalle Valo void ath12k_hal_set_link_desc_addr(struct hal_wbm_link_desc *desc, u32 cookie, 1575d8899132SKalle Valo dma_addr_t paddr) 1576d8899132SKalle Valo { 1577d8899132SKalle Valo desc->buf_addr_info.info0 = le32_encode_bits((paddr & HAL_ADDR_LSB_REG_MASK), 1578d8899132SKalle Valo BUFFER_ADDR_INFO0_ADDR); 1579d8899132SKalle Valo desc->buf_addr_info.info1 = 1580d8899132SKalle Valo le32_encode_bits(((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT), 1581d8899132SKalle Valo BUFFER_ADDR_INFO1_ADDR) | 1582d8899132SKalle Valo le32_encode_bits(1, BUFFER_ADDR_INFO1_RET_BUF_MGR) | 1583d8899132SKalle Valo le32_encode_bits(cookie, BUFFER_ADDR_INFO1_SW_COOKIE); 1584d8899132SKalle Valo } 1585d8899132SKalle Valo 1586d8899132SKalle Valo void *ath12k_hal_srng_dst_peek(struct ath12k_base *ab, struct hal_srng *srng) 1587d8899132SKalle Valo { 1588d8899132SKalle Valo lockdep_assert_held(&srng->lock); 1589d8899132SKalle Valo 1590d8899132SKalle Valo if (srng->u.dst_ring.tp != srng->u.dst_ring.cached_hp) 1591d8899132SKalle Valo return (srng->ring_base_vaddr + srng->u.dst_ring.tp); 1592d8899132SKalle Valo 1593d8899132SKalle Valo return NULL; 1594d8899132SKalle Valo } 1595d8899132SKalle Valo 1596d8899132SKalle Valo void *ath12k_hal_srng_dst_get_next_entry(struct ath12k_base *ab, 1597d8899132SKalle Valo struct hal_srng *srng) 1598d8899132SKalle Valo { 1599d8899132SKalle Valo void *desc; 1600d8899132SKalle Valo 1601d8899132SKalle Valo lockdep_assert_held(&srng->lock); 1602d8899132SKalle Valo 1603d8899132SKalle Valo if (srng->u.dst_ring.tp == srng->u.dst_ring.cached_hp) 1604d8899132SKalle Valo return NULL; 1605d8899132SKalle Valo 1606d8899132SKalle Valo desc = srng->ring_base_vaddr + srng->u.dst_ring.tp; 1607d8899132SKalle Valo 1608d8899132SKalle Valo srng->u.dst_ring.tp = (srng->u.dst_ring.tp + srng->entry_size) % 1609d8899132SKalle Valo srng->ring_size; 1610d8899132SKalle Valo 1611d8899132SKalle Valo return desc; 1612d8899132SKalle Valo } 1613d8899132SKalle Valo 1614d8899132SKalle Valo int ath12k_hal_srng_dst_num_free(struct ath12k_base *ab, struct hal_srng *srng, 1615d8899132SKalle Valo bool sync_hw_ptr) 1616d8899132SKalle Valo { 1617d8899132SKalle Valo u32 tp, hp; 1618d8899132SKalle Valo 1619d8899132SKalle Valo lockdep_assert_held(&srng->lock); 1620d8899132SKalle Valo 1621d8899132SKalle Valo tp = srng->u.dst_ring.tp; 1622d8899132SKalle Valo 1623d8899132SKalle Valo if (sync_hw_ptr) { 1624d8899132SKalle Valo hp = *srng->u.dst_ring.hp_addr; 1625d8899132SKalle Valo srng->u.dst_ring.cached_hp = hp; 1626d8899132SKalle Valo } else { 1627d8899132SKalle Valo hp = srng->u.dst_ring.cached_hp; 1628d8899132SKalle Valo } 1629d8899132SKalle Valo 1630d8899132SKalle Valo if (hp >= tp) 1631d8899132SKalle Valo return (hp - tp) / srng->entry_size; 1632d8899132SKalle Valo else 1633d8899132SKalle Valo return (srng->ring_size - tp + hp) / srng->entry_size; 1634d8899132SKalle Valo } 1635d8899132SKalle Valo 1636d8899132SKalle Valo /* Returns number of available entries in src ring */ 1637d8899132SKalle Valo int ath12k_hal_srng_src_num_free(struct ath12k_base *ab, struct hal_srng *srng, 1638d8899132SKalle Valo bool sync_hw_ptr) 1639d8899132SKalle Valo { 1640d8899132SKalle Valo u32 tp, hp; 1641d8899132SKalle Valo 1642d8899132SKalle Valo lockdep_assert_held(&srng->lock); 1643d8899132SKalle Valo 1644d8899132SKalle Valo hp = srng->u.src_ring.hp; 1645d8899132SKalle Valo 1646d8899132SKalle Valo if (sync_hw_ptr) { 1647d8899132SKalle Valo tp = *srng->u.src_ring.tp_addr; 1648d8899132SKalle Valo srng->u.src_ring.cached_tp = tp; 1649d8899132SKalle Valo } else { 1650d8899132SKalle Valo tp = srng->u.src_ring.cached_tp; 1651d8899132SKalle Valo } 1652d8899132SKalle Valo 1653d8899132SKalle Valo if (tp > hp) 1654d8899132SKalle Valo return ((tp - hp) / srng->entry_size) - 1; 1655d8899132SKalle Valo else 1656d8899132SKalle Valo return ((srng->ring_size - hp + tp) / srng->entry_size) - 1; 1657d8899132SKalle Valo } 1658d8899132SKalle Valo 1659d8899132SKalle Valo void *ath12k_hal_srng_src_get_next_entry(struct ath12k_base *ab, 1660d8899132SKalle Valo struct hal_srng *srng) 1661d8899132SKalle Valo { 1662d8899132SKalle Valo void *desc; 1663d8899132SKalle Valo u32 next_hp; 1664d8899132SKalle Valo 1665d8899132SKalle Valo lockdep_assert_held(&srng->lock); 1666d8899132SKalle Valo 1667d8899132SKalle Valo /* TODO: Using % is expensive, but we have to do this since size of some 1668d8899132SKalle Valo * SRNG rings is not power of 2 (due to descriptor sizes). Need to see 1669d8899132SKalle Valo * if separate function is defined for rings having power of 2 ring size 1670d8899132SKalle Valo * (TCL2SW, REO2SW, SW2RXDMA and CE rings) so that we can avoid the 1671d8899132SKalle Valo * overhead of % by using mask (with &). 1672d8899132SKalle Valo */ 1673d8899132SKalle Valo next_hp = (srng->u.src_ring.hp + srng->entry_size) % srng->ring_size; 1674d8899132SKalle Valo 1675d8899132SKalle Valo if (next_hp == srng->u.src_ring.cached_tp) 1676d8899132SKalle Valo return NULL; 1677d8899132SKalle Valo 1678d8899132SKalle Valo desc = srng->ring_base_vaddr + srng->u.src_ring.hp; 1679d8899132SKalle Valo srng->u.src_ring.hp = next_hp; 1680d8899132SKalle Valo 1681d8899132SKalle Valo /* TODO: Reap functionality is not used by all rings. If particular 1682d8899132SKalle Valo * ring does not use reap functionality, we need not update reap_hp 1683d8899132SKalle Valo * with next_hp pointer. Need to make sure a separate function is used 1684d8899132SKalle Valo * before doing any optimization by removing below code updating 1685d8899132SKalle Valo * reap_hp. 1686d8899132SKalle Valo */ 1687d8899132SKalle Valo srng->u.src_ring.reap_hp = next_hp; 1688d8899132SKalle Valo 1689d8899132SKalle Valo return desc; 1690d8899132SKalle Valo } 1691d8899132SKalle Valo 1692d8899132SKalle Valo void *ath12k_hal_srng_src_reap_next(struct ath12k_base *ab, 1693d8899132SKalle Valo struct hal_srng *srng) 1694d8899132SKalle Valo { 1695d8899132SKalle Valo void *desc; 1696d8899132SKalle Valo u32 next_reap_hp; 1697d8899132SKalle Valo 1698d8899132SKalle Valo lockdep_assert_held(&srng->lock); 1699d8899132SKalle Valo 1700d8899132SKalle Valo next_reap_hp = (srng->u.src_ring.reap_hp + srng->entry_size) % 1701d8899132SKalle Valo srng->ring_size; 1702d8899132SKalle Valo 1703d8899132SKalle Valo if (next_reap_hp == srng->u.src_ring.cached_tp) 1704d8899132SKalle Valo return NULL; 1705d8899132SKalle Valo 1706d8899132SKalle Valo desc = srng->ring_base_vaddr + next_reap_hp; 1707d8899132SKalle Valo srng->u.src_ring.reap_hp = next_reap_hp; 1708d8899132SKalle Valo 1709d8899132SKalle Valo return desc; 1710d8899132SKalle Valo } 1711d8899132SKalle Valo 1712d8899132SKalle Valo void *ath12k_hal_srng_src_get_next_reaped(struct ath12k_base *ab, 1713d8899132SKalle Valo struct hal_srng *srng) 1714d8899132SKalle Valo { 1715d8899132SKalle Valo void *desc; 1716d8899132SKalle Valo 1717d8899132SKalle Valo lockdep_assert_held(&srng->lock); 1718d8899132SKalle Valo 1719d8899132SKalle Valo if (srng->u.src_ring.hp == srng->u.src_ring.reap_hp) 1720d8899132SKalle Valo return NULL; 1721d8899132SKalle Valo 1722d8899132SKalle Valo desc = srng->ring_base_vaddr + srng->u.src_ring.hp; 1723d8899132SKalle Valo srng->u.src_ring.hp = (srng->u.src_ring.hp + srng->entry_size) % 1724d8899132SKalle Valo srng->ring_size; 1725d8899132SKalle Valo 1726d8899132SKalle Valo return desc; 1727d8899132SKalle Valo } 1728d8899132SKalle Valo 1729d8899132SKalle Valo void ath12k_hal_srng_access_begin(struct ath12k_base *ab, struct hal_srng *srng) 1730d8899132SKalle Valo { 1731d8899132SKalle Valo lockdep_assert_held(&srng->lock); 1732d8899132SKalle Valo 1733d8899132SKalle Valo if (srng->ring_dir == HAL_SRNG_DIR_SRC) 1734d8899132SKalle Valo srng->u.src_ring.cached_tp = 1735d8899132SKalle Valo *(volatile u32 *)srng->u.src_ring.tp_addr; 1736d8899132SKalle Valo else 1737d8899132SKalle Valo srng->u.dst_ring.cached_hp = *srng->u.dst_ring.hp_addr; 1738d8899132SKalle Valo } 1739d8899132SKalle Valo 1740d8899132SKalle Valo /* Update cached ring head/tail pointers to HW. ath12k_hal_srng_access_begin() 1741d8899132SKalle Valo * should have been called before this. 1742d8899132SKalle Valo */ 1743d8899132SKalle Valo void ath12k_hal_srng_access_end(struct ath12k_base *ab, struct hal_srng *srng) 1744d8899132SKalle Valo { 1745d8899132SKalle Valo lockdep_assert_held(&srng->lock); 1746d8899132SKalle Valo 1747d8899132SKalle Valo /* TODO: See if we need a write memory barrier here */ 1748d8899132SKalle Valo if (srng->flags & HAL_SRNG_FLAGS_LMAC_RING) { 1749d8899132SKalle Valo /* For LMAC rings, ring pointer updates are done through FW and 1750d8899132SKalle Valo * hence written to a shared memory location that is read by FW 1751d8899132SKalle Valo */ 1752d8899132SKalle Valo if (srng->ring_dir == HAL_SRNG_DIR_SRC) { 1753d8899132SKalle Valo srng->u.src_ring.last_tp = 1754d8899132SKalle Valo *(volatile u32 *)srng->u.src_ring.tp_addr; 1755d8899132SKalle Valo *srng->u.src_ring.hp_addr = srng->u.src_ring.hp; 1756d8899132SKalle Valo } else { 1757d8899132SKalle Valo srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr; 1758d8899132SKalle Valo *srng->u.dst_ring.tp_addr = srng->u.dst_ring.tp; 1759d8899132SKalle Valo } 1760d8899132SKalle Valo } else { 1761d8899132SKalle Valo if (srng->ring_dir == HAL_SRNG_DIR_SRC) { 1762d8899132SKalle Valo srng->u.src_ring.last_tp = 1763d8899132SKalle Valo *(volatile u32 *)srng->u.src_ring.tp_addr; 1764d8899132SKalle Valo ath12k_hif_write32(ab, 1765d8899132SKalle Valo (unsigned long)srng->u.src_ring.hp_addr - 1766d8899132SKalle Valo (unsigned long)ab->mem, 1767d8899132SKalle Valo srng->u.src_ring.hp); 1768d8899132SKalle Valo } else { 1769d8899132SKalle Valo srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr; 1770d8899132SKalle Valo ath12k_hif_write32(ab, 1771d8899132SKalle Valo (unsigned long)srng->u.dst_ring.tp_addr - 1772d8899132SKalle Valo (unsigned long)ab->mem, 1773d8899132SKalle Valo srng->u.dst_ring.tp); 1774d8899132SKalle Valo } 1775d8899132SKalle Valo } 1776d8899132SKalle Valo 1777d8899132SKalle Valo srng->timestamp = jiffies; 1778d8899132SKalle Valo } 1779d8899132SKalle Valo 1780d8899132SKalle Valo void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab, 1781d8899132SKalle Valo struct hal_wbm_idle_scatter_list *sbuf, 1782d8899132SKalle Valo u32 nsbufs, u32 tot_link_desc, 1783d8899132SKalle Valo u32 end_offset) 1784d8899132SKalle Valo { 1785d8899132SKalle Valo struct ath12k_buffer_addr *link_addr; 1786d8899132SKalle Valo int i; 1787d8899132SKalle Valo u32 reg_scatter_buf_sz = HAL_WBM_IDLE_SCATTER_BUF_SIZE / 64; 1788d8899132SKalle Valo u32 val; 1789d8899132SKalle Valo 1790d8899132SKalle Valo link_addr = (void *)sbuf[0].vaddr + HAL_WBM_IDLE_SCATTER_BUF_SIZE; 1791d8899132SKalle Valo 1792d8899132SKalle Valo for (i = 1; i < nsbufs; i++) { 1793d8899132SKalle Valo link_addr->info0 = cpu_to_le32(sbuf[i].paddr & HAL_ADDR_LSB_REG_MASK); 1794d8899132SKalle Valo 1795d8899132SKalle Valo link_addr->info1 = 1796d8899132SKalle Valo le32_encode_bits((u64)sbuf[i].paddr >> HAL_ADDR_MSB_REG_SHIFT, 1797d8899132SKalle Valo HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32) | 1798d8899132SKalle Valo le32_encode_bits(BASE_ADDR_MATCH_TAG_VAL, 1799d8899132SKalle Valo HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_MATCH_TAG); 1800d8899132SKalle Valo 1801d8899132SKalle Valo link_addr = (void *)sbuf[i].vaddr + 1802d8899132SKalle Valo HAL_WBM_IDLE_SCATTER_BUF_SIZE; 1803d8899132SKalle Valo } 1804d8899132SKalle Valo 1805d8899132SKalle Valo val = u32_encode_bits(reg_scatter_buf_sz, HAL_WBM_SCATTER_BUFFER_SIZE) | 1806d8899132SKalle Valo u32_encode_bits(0x1, HAL_WBM_LINK_DESC_IDLE_LIST_MODE); 1807d8899132SKalle Valo 1808d8899132SKalle Valo ath12k_hif_write32(ab, 1809d8899132SKalle Valo HAL_SEQ_WCSS_UMAC_WBM_REG + 1810d8899132SKalle Valo HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR(ab), 1811d8899132SKalle Valo val); 1812d8899132SKalle Valo 1813d8899132SKalle Valo val = u32_encode_bits(reg_scatter_buf_sz * nsbufs, 1814d8899132SKalle Valo HAL_WBM_SCATTER_RING_SIZE_OF_IDLE_LINK_DESC_LIST); 1815d8899132SKalle Valo ath12k_hif_write32(ab, 1816d8899132SKalle Valo HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_R0_IDLE_LIST_SIZE_ADDR(ab), 1817d8899132SKalle Valo val); 1818d8899132SKalle Valo 1819d8899132SKalle Valo val = u32_encode_bits(sbuf[0].paddr & HAL_ADDR_LSB_REG_MASK, 1820d8899132SKalle Valo BUFFER_ADDR_INFO0_ADDR); 1821d8899132SKalle Valo ath12k_hif_write32(ab, 1822d8899132SKalle Valo HAL_SEQ_WCSS_UMAC_WBM_REG + 1823d8899132SKalle Valo HAL_WBM_SCATTERED_RING_BASE_LSB(ab), 1824d8899132SKalle Valo val); 1825d8899132SKalle Valo 1826d8899132SKalle Valo val = u32_encode_bits(BASE_ADDR_MATCH_TAG_VAL, 1827d8899132SKalle Valo HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_MATCH_TAG) | 1828d8899132SKalle Valo u32_encode_bits((u64)sbuf[0].paddr >> HAL_ADDR_MSB_REG_SHIFT, 1829d8899132SKalle Valo HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32); 1830d8899132SKalle Valo ath12k_hif_write32(ab, 1831d8899132SKalle Valo HAL_SEQ_WCSS_UMAC_WBM_REG + 1832d8899132SKalle Valo HAL_WBM_SCATTERED_RING_BASE_MSB(ab), 1833d8899132SKalle Valo val); 1834d8899132SKalle Valo 1835d8899132SKalle Valo /* Setup head and tail pointers for the idle list */ 1836d8899132SKalle Valo val = u32_encode_bits(sbuf[nsbufs - 1].paddr, BUFFER_ADDR_INFO0_ADDR); 1837d8899132SKalle Valo ath12k_hif_write32(ab, 1838d8899132SKalle Valo HAL_SEQ_WCSS_UMAC_WBM_REG + 1839d8899132SKalle Valo HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(ab), 1840d8899132SKalle Valo val); 1841d8899132SKalle Valo 1842d8899132SKalle Valo val = u32_encode_bits(((u64)sbuf[nsbufs - 1].paddr >> HAL_ADDR_MSB_REG_SHIFT), 1843d8899132SKalle Valo HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32) | 1844d8899132SKalle Valo u32_encode_bits((end_offset >> 2), 1845d8899132SKalle Valo HAL_WBM_SCATTERED_DESC_HEAD_P_OFFSET_IX1); 1846d8899132SKalle Valo ath12k_hif_write32(ab, 1847d8899132SKalle Valo HAL_SEQ_WCSS_UMAC_WBM_REG + 1848d8899132SKalle Valo HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1(ab), 1849d8899132SKalle Valo val); 1850d8899132SKalle Valo 1851d8899132SKalle Valo val = u32_encode_bits(sbuf[0].paddr, BUFFER_ADDR_INFO0_ADDR); 1852d8899132SKalle Valo ath12k_hif_write32(ab, 1853d8899132SKalle Valo HAL_SEQ_WCSS_UMAC_WBM_REG + 1854d8899132SKalle Valo HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(ab), 1855d8899132SKalle Valo val); 1856d8899132SKalle Valo 1857d8899132SKalle Valo val = u32_encode_bits(sbuf[0].paddr, BUFFER_ADDR_INFO0_ADDR); 1858d8899132SKalle Valo ath12k_hif_write32(ab, 1859d8899132SKalle Valo HAL_SEQ_WCSS_UMAC_WBM_REG + 1860d8899132SKalle Valo HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0(ab), 1861d8899132SKalle Valo val); 1862d8899132SKalle Valo 1863d8899132SKalle Valo val = u32_encode_bits(((u64)sbuf[0].paddr >> HAL_ADDR_MSB_REG_SHIFT), 1864d8899132SKalle Valo HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32) | 1865d8899132SKalle Valo u32_encode_bits(0, HAL_WBM_SCATTERED_DESC_TAIL_P_OFFSET_IX1); 1866d8899132SKalle Valo ath12k_hif_write32(ab, 1867d8899132SKalle Valo HAL_SEQ_WCSS_UMAC_WBM_REG + 1868d8899132SKalle Valo HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1(ab), 1869d8899132SKalle Valo val); 1870d8899132SKalle Valo 1871d8899132SKalle Valo val = 2 * tot_link_desc; 1872d8899132SKalle Valo ath12k_hif_write32(ab, 1873d8899132SKalle Valo HAL_SEQ_WCSS_UMAC_WBM_REG + 1874d8899132SKalle Valo HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR(ab), 1875d8899132SKalle Valo val); 1876d8899132SKalle Valo 1877d8899132SKalle Valo /* Enable the SRNG */ 1878d8899132SKalle Valo val = u32_encode_bits(1, HAL_WBM_IDLE_LINK_RING_MISC_SRNG_ENABLE) | 1879d8899132SKalle Valo u32_encode_bits(1, HAL_WBM_IDLE_LINK_RING_MISC_RIND_ID_DISABLE); 1880d8899132SKalle Valo ath12k_hif_write32(ab, 1881d8899132SKalle Valo HAL_SEQ_WCSS_UMAC_WBM_REG + 1882d8899132SKalle Valo HAL_WBM_IDLE_LINK_RING_MISC_ADDR(ab), 1883d8899132SKalle Valo val); 1884d8899132SKalle Valo } 1885d8899132SKalle Valo 1886d8899132SKalle Valo int ath12k_hal_srng_setup(struct ath12k_base *ab, enum hal_ring_type type, 1887d8899132SKalle Valo int ring_num, int mac_id, 1888d8899132SKalle Valo struct hal_srng_params *params) 1889d8899132SKalle Valo { 1890d8899132SKalle Valo struct ath12k_hal *hal = &ab->hal; 1891d8899132SKalle Valo struct hal_srng_config *srng_config = &ab->hal.srng_config[type]; 1892d8899132SKalle Valo struct hal_srng *srng; 1893d8899132SKalle Valo int ring_id; 1894d8899132SKalle Valo u32 idx; 1895d8899132SKalle Valo int i; 1896d8899132SKalle Valo u32 reg_base; 1897d8899132SKalle Valo 1898d8899132SKalle Valo ring_id = ath12k_hal_srng_get_ring_id(ab, type, ring_num, mac_id); 1899d8899132SKalle Valo if (ring_id < 0) 1900d8899132SKalle Valo return ring_id; 1901d8899132SKalle Valo 1902d8899132SKalle Valo srng = &hal->srng_list[ring_id]; 1903d8899132SKalle Valo 1904d8899132SKalle Valo srng->ring_id = ring_id; 1905d8899132SKalle Valo srng->ring_dir = srng_config->ring_dir; 1906d8899132SKalle Valo srng->ring_base_paddr = params->ring_base_paddr; 1907d8899132SKalle Valo srng->ring_base_vaddr = params->ring_base_vaddr; 1908d8899132SKalle Valo srng->entry_size = srng_config->entry_size; 1909d8899132SKalle Valo srng->num_entries = params->num_entries; 1910d8899132SKalle Valo srng->ring_size = srng->entry_size * srng->num_entries; 1911d8899132SKalle Valo srng->intr_batch_cntr_thres_entries = 1912d8899132SKalle Valo params->intr_batch_cntr_thres_entries; 1913d8899132SKalle Valo srng->intr_timer_thres_us = params->intr_timer_thres_us; 1914d8899132SKalle Valo srng->flags = params->flags; 1915d8899132SKalle Valo srng->msi_addr = params->msi_addr; 1916d8899132SKalle Valo srng->msi2_addr = params->msi2_addr; 1917d8899132SKalle Valo srng->msi_data = params->msi_data; 1918d8899132SKalle Valo srng->msi2_data = params->msi2_data; 1919d8899132SKalle Valo srng->initialized = 1; 1920d8899132SKalle Valo spin_lock_init(&srng->lock); 1921d8899132SKalle Valo lockdep_set_class(&srng->lock, &srng->lock_key); 1922d8899132SKalle Valo 1923d8899132SKalle Valo for (i = 0; i < HAL_SRNG_NUM_REG_GRP; i++) { 1924d8899132SKalle Valo srng->hwreg_base[i] = srng_config->reg_start[i] + 1925d8899132SKalle Valo (ring_num * srng_config->reg_size[i]); 1926d8899132SKalle Valo } 1927d8899132SKalle Valo 1928d8899132SKalle Valo memset(srng->ring_base_vaddr, 0, 1929d8899132SKalle Valo (srng->entry_size * srng->num_entries) << 2); 1930d8899132SKalle Valo 1931d8899132SKalle Valo reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2]; 1932d8899132SKalle Valo 1933d8899132SKalle Valo if (srng->ring_dir == HAL_SRNG_DIR_SRC) { 1934d8899132SKalle Valo srng->u.src_ring.hp = 0; 1935d8899132SKalle Valo srng->u.src_ring.cached_tp = 0; 1936d8899132SKalle Valo srng->u.src_ring.reap_hp = srng->ring_size - srng->entry_size; 1937d8899132SKalle Valo srng->u.src_ring.tp_addr = (void *)(hal->rdp.vaddr + ring_id); 1938d8899132SKalle Valo srng->u.src_ring.low_threshold = params->low_threshold * 1939d8899132SKalle Valo srng->entry_size; 1940d8899132SKalle Valo if (srng_config->mac_type == ATH12K_HAL_SRNG_UMAC) { 1941d8899132SKalle Valo if (!ab->hw_params->supports_shadow_regs) 1942d8899132SKalle Valo srng->u.src_ring.hp_addr = 1943d8899132SKalle Valo (u32 *)((unsigned long)ab->mem + reg_base); 1944d8899132SKalle Valo else 1945d8899132SKalle Valo ath12k_dbg(ab, ATH12K_DBG_HAL, 1946d8899132SKalle Valo "hal type %d ring_num %d reg_base 0x%x shadow 0x%lx\n", 1947d8899132SKalle Valo type, ring_num, 1948d8899132SKalle Valo reg_base, 1949d8899132SKalle Valo (unsigned long)srng->u.src_ring.hp_addr - 1950d8899132SKalle Valo (unsigned long)ab->mem); 1951d8899132SKalle Valo } else { 1952d8899132SKalle Valo idx = ring_id - HAL_SRNG_RING_ID_DMAC_CMN_ID_START; 1953d8899132SKalle Valo srng->u.src_ring.hp_addr = (void *)(hal->wrp.vaddr + 1954d8899132SKalle Valo idx); 1955d8899132SKalle Valo srng->flags |= HAL_SRNG_FLAGS_LMAC_RING; 1956d8899132SKalle Valo } 1957d8899132SKalle Valo } else { 1958d8899132SKalle Valo /* During initialization loop count in all the descriptors 1959d8899132SKalle Valo * will be set to zero, and HW will set it to 1 on completing 1960d8899132SKalle Valo * descriptor update in first loop, and increments it by 1 on 1961d8899132SKalle Valo * subsequent loops (loop count wraps around after reaching 1962d8899132SKalle Valo * 0xffff). The 'loop_cnt' in SW ring state is the expected 1963d8899132SKalle Valo * loop count in descriptors updated by HW (to be processed 1964d8899132SKalle Valo * by SW). 1965d8899132SKalle Valo */ 1966d8899132SKalle Valo srng->u.dst_ring.loop_cnt = 1; 1967d8899132SKalle Valo srng->u.dst_ring.tp = 0; 1968d8899132SKalle Valo srng->u.dst_ring.cached_hp = 0; 1969d8899132SKalle Valo srng->u.dst_ring.hp_addr = (void *)(hal->rdp.vaddr + ring_id); 1970d8899132SKalle Valo if (srng_config->mac_type == ATH12K_HAL_SRNG_UMAC) { 1971d8899132SKalle Valo if (!ab->hw_params->supports_shadow_regs) 1972d8899132SKalle Valo srng->u.dst_ring.tp_addr = 1973d8899132SKalle Valo (u32 *)((unsigned long)ab->mem + reg_base + 1974d8899132SKalle Valo (HAL_REO1_RING_TP - HAL_REO1_RING_HP)); 1975d8899132SKalle Valo else 1976d8899132SKalle Valo ath12k_dbg(ab, ATH12K_DBG_HAL, 1977d8899132SKalle Valo "type %d ring_num %d target_reg 0x%x shadow 0x%lx\n", 1978d8899132SKalle Valo type, ring_num, 1979d8899132SKalle Valo reg_base + HAL_REO1_RING_TP - HAL_REO1_RING_HP, 1980d8899132SKalle Valo (unsigned long)srng->u.dst_ring.tp_addr - 1981d8899132SKalle Valo (unsigned long)ab->mem); 1982d8899132SKalle Valo } else { 1983d8899132SKalle Valo /* For PMAC & DMAC rings, tail pointer updates will be done 1984d8899132SKalle Valo * through FW by writing to a shared memory location 1985d8899132SKalle Valo */ 1986d8899132SKalle Valo idx = ring_id - HAL_SRNG_RING_ID_DMAC_CMN_ID_START; 1987d8899132SKalle Valo srng->u.dst_ring.tp_addr = (void *)(hal->wrp.vaddr + 1988d8899132SKalle Valo idx); 1989d8899132SKalle Valo srng->flags |= HAL_SRNG_FLAGS_LMAC_RING; 1990d8899132SKalle Valo } 1991d8899132SKalle Valo } 1992d8899132SKalle Valo 1993d8899132SKalle Valo if (srng_config->mac_type != ATH12K_HAL_SRNG_UMAC) 1994d8899132SKalle Valo return ring_id; 1995d8899132SKalle Valo 1996d8899132SKalle Valo ath12k_hal_srng_hw_init(ab, srng); 1997d8899132SKalle Valo 1998d8899132SKalle Valo if (type == HAL_CE_DST) { 1999d8899132SKalle Valo srng->u.dst_ring.max_buffer_length = params->max_buffer_len; 2000d8899132SKalle Valo ath12k_hal_ce_dst_setup(ab, srng, ring_num); 2001d8899132SKalle Valo } 2002d8899132SKalle Valo 2003d8899132SKalle Valo return ring_id; 2004d8899132SKalle Valo } 2005d8899132SKalle Valo 2006d8899132SKalle Valo static void ath12k_hal_srng_update_hp_tp_addr(struct ath12k_base *ab, 2007d8899132SKalle Valo int shadow_cfg_idx, 2008d8899132SKalle Valo enum hal_ring_type ring_type, 2009d8899132SKalle Valo int ring_num) 2010d8899132SKalle Valo { 2011d8899132SKalle Valo struct hal_srng *srng; 2012d8899132SKalle Valo struct ath12k_hal *hal = &ab->hal; 2013d8899132SKalle Valo int ring_id; 2014d8899132SKalle Valo struct hal_srng_config *srng_config = &hal->srng_config[ring_type]; 2015d8899132SKalle Valo 2016d8899132SKalle Valo ring_id = ath12k_hal_srng_get_ring_id(ab, ring_type, ring_num, 0); 2017d8899132SKalle Valo if (ring_id < 0) 2018d8899132SKalle Valo return; 2019d8899132SKalle Valo 2020d8899132SKalle Valo srng = &hal->srng_list[ring_id]; 2021d8899132SKalle Valo 2022d8899132SKalle Valo if (srng_config->ring_dir == HAL_SRNG_DIR_DST) 2023d8899132SKalle Valo srng->u.dst_ring.tp_addr = (u32 *)(HAL_SHADOW_REG(shadow_cfg_idx) + 2024d8899132SKalle Valo (unsigned long)ab->mem); 2025d8899132SKalle Valo else 2026d8899132SKalle Valo srng->u.src_ring.hp_addr = (u32 *)(HAL_SHADOW_REG(shadow_cfg_idx) + 2027d8899132SKalle Valo (unsigned long)ab->mem); 2028d8899132SKalle Valo } 2029d8899132SKalle Valo 2030d8899132SKalle Valo int ath12k_hal_srng_update_shadow_config(struct ath12k_base *ab, 2031d8899132SKalle Valo enum hal_ring_type ring_type, 2032d8899132SKalle Valo int ring_num) 2033d8899132SKalle Valo { 2034d8899132SKalle Valo struct ath12k_hal *hal = &ab->hal; 2035d8899132SKalle Valo struct hal_srng_config *srng_config = &hal->srng_config[ring_type]; 2036d8899132SKalle Valo int shadow_cfg_idx = hal->num_shadow_reg_configured; 2037d8899132SKalle Valo u32 target_reg; 2038d8899132SKalle Valo 2039d8899132SKalle Valo if (shadow_cfg_idx >= HAL_SHADOW_NUM_REGS) 2040d8899132SKalle Valo return -EINVAL; 2041d8899132SKalle Valo 2042d8899132SKalle Valo hal->num_shadow_reg_configured++; 2043d8899132SKalle Valo 2044d8899132SKalle Valo target_reg = srng_config->reg_start[HAL_HP_OFFSET_IN_REG_START]; 2045d8899132SKalle Valo target_reg += srng_config->reg_size[HAL_HP_OFFSET_IN_REG_START] * 2046d8899132SKalle Valo ring_num; 2047d8899132SKalle Valo 2048d8899132SKalle Valo /* For destination ring, shadow the TP */ 2049d8899132SKalle Valo if (srng_config->ring_dir == HAL_SRNG_DIR_DST) 2050d8899132SKalle Valo target_reg += HAL_OFFSET_FROM_HP_TO_TP; 2051d8899132SKalle Valo 2052d8899132SKalle Valo hal->shadow_reg_addr[shadow_cfg_idx] = target_reg; 2053d8899132SKalle Valo 2054d8899132SKalle Valo /* update hp/tp addr to hal structure*/ 2055d8899132SKalle Valo ath12k_hal_srng_update_hp_tp_addr(ab, shadow_cfg_idx, ring_type, 2056d8899132SKalle Valo ring_num); 2057d8899132SKalle Valo 2058d8899132SKalle Valo ath12k_dbg(ab, ATH12K_DBG_HAL, 2059d8899132SKalle Valo "target_reg %x, shadow reg 0x%x shadow_idx 0x%x, ring_type %d, ring num %d", 2060d8899132SKalle Valo target_reg, 2061d8899132SKalle Valo HAL_SHADOW_REG(shadow_cfg_idx), 2062d8899132SKalle Valo shadow_cfg_idx, 2063d8899132SKalle Valo ring_type, ring_num); 2064d8899132SKalle Valo 2065d8899132SKalle Valo return 0; 2066d8899132SKalle Valo } 2067d8899132SKalle Valo 2068d8899132SKalle Valo void ath12k_hal_srng_shadow_config(struct ath12k_base *ab) 2069d8899132SKalle Valo { 2070d8899132SKalle Valo struct ath12k_hal *hal = &ab->hal; 2071d8899132SKalle Valo int ring_type, ring_num; 2072d8899132SKalle Valo 2073d8899132SKalle Valo /* update all the non-CE srngs. */ 2074d8899132SKalle Valo for (ring_type = 0; ring_type < HAL_MAX_RING_TYPES; ring_type++) { 2075d8899132SKalle Valo struct hal_srng_config *srng_config = &hal->srng_config[ring_type]; 2076d8899132SKalle Valo 2077d8899132SKalle Valo if (ring_type == HAL_CE_SRC || 2078d8899132SKalle Valo ring_type == HAL_CE_DST || 2079d8899132SKalle Valo ring_type == HAL_CE_DST_STATUS) 2080d8899132SKalle Valo continue; 2081d8899132SKalle Valo 2082d8899132SKalle Valo if (srng_config->mac_type == ATH12K_HAL_SRNG_DMAC || 2083d8899132SKalle Valo srng_config->mac_type == ATH12K_HAL_SRNG_PMAC) 2084d8899132SKalle Valo continue; 2085d8899132SKalle Valo 2086d8899132SKalle Valo for (ring_num = 0; ring_num < srng_config->max_rings; ring_num++) 2087d8899132SKalle Valo ath12k_hal_srng_update_shadow_config(ab, ring_type, ring_num); 2088d8899132SKalle Valo } 2089d8899132SKalle Valo } 2090d8899132SKalle Valo 2091d8899132SKalle Valo void ath12k_hal_srng_get_shadow_config(struct ath12k_base *ab, 2092d8899132SKalle Valo u32 **cfg, u32 *len) 2093d8899132SKalle Valo { 2094d8899132SKalle Valo struct ath12k_hal *hal = &ab->hal; 2095d8899132SKalle Valo 2096d8899132SKalle Valo *len = hal->num_shadow_reg_configured; 2097d8899132SKalle Valo *cfg = hal->shadow_reg_addr; 2098d8899132SKalle Valo } 2099d8899132SKalle Valo 2100d8899132SKalle Valo void ath12k_hal_srng_shadow_update_hp_tp(struct ath12k_base *ab, 2101d8899132SKalle Valo struct hal_srng *srng) 2102d8899132SKalle Valo { 2103d8899132SKalle Valo lockdep_assert_held(&srng->lock); 2104d8899132SKalle Valo 2105d8899132SKalle Valo /* check whether the ring is empty. Update the shadow 2106d8899132SKalle Valo * HP only when then ring isn't' empty. 2107d8899132SKalle Valo */ 2108d8899132SKalle Valo if (srng->ring_dir == HAL_SRNG_DIR_SRC && 2109d8899132SKalle Valo *srng->u.src_ring.tp_addr != srng->u.src_ring.hp) 2110d8899132SKalle Valo ath12k_hal_srng_access_end(ab, srng); 2111d8899132SKalle Valo } 2112d8899132SKalle Valo 2113d8899132SKalle Valo static void ath12k_hal_register_srng_lock_keys(struct ath12k_base *ab) 2114d8899132SKalle Valo { 2115d8899132SKalle Valo struct ath12k_hal *hal = &ab->hal; 2116d8899132SKalle Valo u32 ring_id; 2117d8899132SKalle Valo 2118d8899132SKalle Valo for (ring_id = 0; ring_id < HAL_SRNG_RING_ID_MAX; ring_id++) 2119d8899132SKalle Valo lockdep_register_key(&hal->srng_list[ring_id].lock_key); 2120d8899132SKalle Valo } 2121d8899132SKalle Valo 2122d8899132SKalle Valo static void ath12k_hal_unregister_srng_lock_keys(struct ath12k_base *ab) 2123d8899132SKalle Valo { 2124d8899132SKalle Valo struct ath12k_hal *hal = &ab->hal; 2125d8899132SKalle Valo u32 ring_id; 2126d8899132SKalle Valo 2127d8899132SKalle Valo for (ring_id = 0; ring_id < HAL_SRNG_RING_ID_MAX; ring_id++) 2128d8899132SKalle Valo lockdep_unregister_key(&hal->srng_list[ring_id].lock_key); 2129d8899132SKalle Valo } 2130d8899132SKalle Valo 2131d8899132SKalle Valo int ath12k_hal_srng_init(struct ath12k_base *ab) 2132d8899132SKalle Valo { 2133d8899132SKalle Valo struct ath12k_hal *hal = &ab->hal; 2134d8899132SKalle Valo int ret; 2135d8899132SKalle Valo 2136d8899132SKalle Valo memset(hal, 0, sizeof(*hal)); 2137d8899132SKalle Valo 2138d8899132SKalle Valo ret = ab->hw_params->hal_ops->create_srng_config(ab); 2139d8899132SKalle Valo if (ret) 2140d8899132SKalle Valo goto err_hal; 2141d8899132SKalle Valo 2142d8899132SKalle Valo ret = ath12k_hal_alloc_cont_rdp(ab); 2143d8899132SKalle Valo if (ret) 2144d8899132SKalle Valo goto err_hal; 2145d8899132SKalle Valo 2146d8899132SKalle Valo ret = ath12k_hal_alloc_cont_wrp(ab); 2147d8899132SKalle Valo if (ret) 2148d8899132SKalle Valo goto err_free_cont_rdp; 2149d8899132SKalle Valo 2150d8899132SKalle Valo ath12k_hal_register_srng_lock_keys(ab); 2151d8899132SKalle Valo 2152d8899132SKalle Valo return 0; 2153d8899132SKalle Valo 2154d8899132SKalle Valo err_free_cont_rdp: 2155d8899132SKalle Valo ath12k_hal_free_cont_rdp(ab); 2156d8899132SKalle Valo 2157d8899132SKalle Valo err_hal: 2158d8899132SKalle Valo return ret; 2159d8899132SKalle Valo } 2160d8899132SKalle Valo 2161d8899132SKalle Valo void ath12k_hal_srng_deinit(struct ath12k_base *ab) 2162d8899132SKalle Valo { 2163d8899132SKalle Valo struct ath12k_hal *hal = &ab->hal; 2164d8899132SKalle Valo 2165d8899132SKalle Valo ath12k_hal_unregister_srng_lock_keys(ab); 2166d8899132SKalle Valo ath12k_hal_free_cont_rdp(ab); 2167d8899132SKalle Valo ath12k_hal_free_cont_wrp(ab); 2168d8899132SKalle Valo kfree(hal->srng_config); 2169d8899132SKalle Valo hal->srng_config = NULL; 2170d8899132SKalle Valo } 2171d8899132SKalle Valo 2172d8899132SKalle Valo void ath12k_hal_dump_srng_stats(struct ath12k_base *ab) 2173d8899132SKalle Valo { 2174d8899132SKalle Valo struct hal_srng *srng; 2175d8899132SKalle Valo struct ath12k_ext_irq_grp *irq_grp; 2176d8899132SKalle Valo struct ath12k_ce_pipe *ce_pipe; 2177d8899132SKalle Valo int i; 2178d8899132SKalle Valo 2179d8899132SKalle Valo ath12k_err(ab, "Last interrupt received for each CE:\n"); 2180d8899132SKalle Valo for (i = 0; i < ab->hw_params->ce_count; i++) { 2181d8899132SKalle Valo ce_pipe = &ab->ce.ce_pipe[i]; 2182d8899132SKalle Valo 2183d8899132SKalle Valo if (ath12k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) 2184d8899132SKalle Valo continue; 2185d8899132SKalle Valo 2186d8899132SKalle Valo ath12k_err(ab, "CE_id %d pipe_num %d %ums before\n", 2187d8899132SKalle Valo i, ce_pipe->pipe_num, 2188d8899132SKalle Valo jiffies_to_msecs(jiffies - ce_pipe->timestamp)); 2189d8899132SKalle Valo } 2190d8899132SKalle Valo 2191d8899132SKalle Valo ath12k_err(ab, "\nLast interrupt received for each group:\n"); 2192d8899132SKalle Valo for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) { 2193d8899132SKalle Valo irq_grp = &ab->ext_irq_grp[i]; 2194d8899132SKalle Valo ath12k_err(ab, "group_id %d %ums before\n", 2195d8899132SKalle Valo irq_grp->grp_id, 2196d8899132SKalle Valo jiffies_to_msecs(jiffies - irq_grp->timestamp)); 2197d8899132SKalle Valo } 2198d8899132SKalle Valo 2199d8899132SKalle Valo for (i = 0; i < HAL_SRNG_RING_ID_MAX; i++) { 2200d8899132SKalle Valo srng = &ab->hal.srng_list[i]; 2201d8899132SKalle Valo 2202d8899132SKalle Valo if (!srng->initialized) 2203d8899132SKalle Valo continue; 2204d8899132SKalle Valo 2205d8899132SKalle Valo if (srng->ring_dir == HAL_SRNG_DIR_SRC) 2206d8899132SKalle Valo ath12k_err(ab, 2207d8899132SKalle Valo "src srng id %u hp %u, reap_hp %u, cur tp %u, cached tp %u last tp %u napi processed before %ums\n", 2208d8899132SKalle Valo srng->ring_id, srng->u.src_ring.hp, 2209d8899132SKalle Valo srng->u.src_ring.reap_hp, 2210d8899132SKalle Valo *srng->u.src_ring.tp_addr, srng->u.src_ring.cached_tp, 2211d8899132SKalle Valo srng->u.src_ring.last_tp, 2212d8899132SKalle Valo jiffies_to_msecs(jiffies - srng->timestamp)); 2213d8899132SKalle Valo else if (srng->ring_dir == HAL_SRNG_DIR_DST) 2214d8899132SKalle Valo ath12k_err(ab, 2215d8899132SKalle Valo "dst srng id %u tp %u, cur hp %u, cached hp %u last hp %u napi processed before %ums\n", 2216d8899132SKalle Valo srng->ring_id, srng->u.dst_ring.tp, 2217d8899132SKalle Valo *srng->u.dst_ring.hp_addr, 2218d8899132SKalle Valo srng->u.dst_ring.cached_hp, 2219d8899132SKalle Valo srng->u.dst_ring.last_hp, 2220d8899132SKalle Valo jiffies_to_msecs(jiffies - srng->timestamp)); 2221d8899132SKalle Valo } 2222d8899132SKalle Valo } 2223