From: Pavankumar Nandeshwar Move the hardware specific HAL APIs to hal.c file inside wifi7 directory. These APIs will be called through the hal_ops mechanism, which are registered separately by qcn and wcn Handling following APIs: ath12k_wifi7_hal_ce_dst_setup ath12k_wifi7_hal_srng_src_hw_init ath12k_wifi7_hal_srng_dst_hw_init ath12k_wifi7_hal_set_umac_srng_ptr_addr Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Pavankumar Nandeshwar Signed-off-by: Ripan Deuri --- drivers/net/wireless/ath/ath12k/hal.c | 260 +--------------- drivers/net/wireless/ath/ath12k/hal.h | 6 + drivers/net/wireless/ath/ath12k/wifi7/hal.c | 277 ++++++++++++++++++ drivers/net/wireless/ath/ath12k/wifi7/hal.h | 8 + .../wireless/ath/ath12k/wifi7/hal_qcn9274.c | 4 + .../wireless/ath/ath12k/wifi7/hal_wcn7850.c | 4 + 6 files changed, 313 insertions(+), 246 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index fb369f464b2d..67a7285dc769 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -12,49 +12,28 @@ #include "wifi7/hal_qcn9274.h" #include "wifi7/hal_wcn7850.h" -static unsigned int ath12k_hal_reo1_ring_id_offset(struct ath12k_hal *hal) -{ - return HAL_REO1_RING_ID(hal) - HAL_REO1_RING_BASE_LSB(hal); -} - -static unsigned int ath12k_hal_reo1_ring_msi1_base_lsb_offset(struct ath12k_hal *hal) -{ - return HAL_REO1_RING_MSI1_BASE_LSB(hal) - HAL_REO1_RING_BASE_LSB(hal); -} - -static unsigned int ath12k_hal_reo1_ring_msi1_base_msb_offset(struct ath12k_hal *hal) -{ - return HAL_REO1_RING_MSI1_BASE_MSB(hal) - HAL_REO1_RING_BASE_LSB(hal); -} - -static unsigned int ath12k_hal_reo1_ring_msi1_data_offset(struct ath12k_hal *hal) -{ - return HAL_REO1_RING_MSI1_DATA(hal) - HAL_REO1_RING_BASE_LSB(hal); -} - -static unsigned int ath12k_hal_reo1_ring_base_msb_offset(struct ath12k_hal *hal) -{ - return HAL_REO1_RING_BASE_MSB(hal) - HAL_REO1_RING_BASE_LSB(hal); -} - -static unsigned int ath12k_hal_reo1_ring_producer_int_setup_offset(struct ath12k_hal *hal) +static void ath12k_hal_ce_dst_setup(struct ath12k_base *ab, + struct hal_srng *srng, int ring_num) { - return HAL_REO1_RING_PRODUCER_INT_SETUP(hal) - HAL_REO1_RING_BASE_LSB(hal); + ab->hal.hal_ops->ce_dst_setup(ab, srng, ring_num); } -static unsigned int ath12k_hal_reo1_ring_hp_addr_lsb_offset(struct ath12k_hal *hal) +static void ath12k_hal_srng_src_hw_init(struct ath12k_base *ab, + struct hal_srng *srng) { - return HAL_REO1_RING_HP_ADDR_LSB(hal) - HAL_REO1_RING_BASE_LSB(hal); + ab->hal.hal_ops->srng_src_hw_init(ab, srng); } -static unsigned int ath12k_hal_reo1_ring_hp_addr_msb_offset(struct ath12k_hal *hal) +static void ath12k_hal_srng_dst_hw_init(struct ath12k_base *ab, + struct hal_srng *srng) { - return HAL_REO1_RING_HP_ADDR_MSB(hal) - HAL_REO1_RING_BASE_LSB(hal); + ab->hal.hal_ops->srng_dst_hw_init(ab, srng); } -static unsigned int ath12k_hal_reo1_ring_misc_offset(struct ath12k_hal *hal) +static void ath12k_hal_set_umac_srng_ptr_addr(struct ath12k_base *ab, + struct hal_srng *srng) { - return HAL_REO1_RING_MISC(hal) - HAL_REO1_RING_BASE_LSB(hal); + ab->hal.hal_ops->set_umac_srng_ptr_addr(ab, srng); } static int ath12k_hal_alloc_cont_rdp(struct ath12k_hal *hal) @@ -109,195 +88,6 @@ static void ath12k_hal_free_cont_wrp(struct ath12k_hal *hal) hal->wrp.vaddr = NULL; } -static void ath12k_hal_ce_dst_setup(struct ath12k_base *ab, - struct hal_srng *srng, int ring_num) -{ - struct hal_srng_config *srng_config = &ab->hal.srng_config[HAL_CE_DST]; - u32 addr; - u32 val; - - addr = HAL_CE_DST_RING_CTRL + - srng_config->reg_start[HAL_SRNG_REG_GRP_R0] + - ring_num * srng_config->reg_size[HAL_SRNG_REG_GRP_R0]; - - val = ath12k_hif_read32(ab, addr); - val &= ~HAL_CE_DST_R0_DEST_CTRL_MAX_LEN; - val |= u32_encode_bits(srng->u.dst_ring.max_buffer_length, - HAL_CE_DST_R0_DEST_CTRL_MAX_LEN); - ath12k_hif_write32(ab, addr, val); -} - -static void ath12k_hal_srng_dst_hw_init(struct ath12k_base *ab, - struct hal_srng *srng) -{ - struct ath12k_hal *hal = &ab->hal; - u32 val; - u64 hp_addr; - u32 reg_base; - - reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; - - if (srng->flags & HAL_SRNG_FLAGS_MSI_INTR) { - ath12k_hif_write32(ab, reg_base + - ath12k_hal_reo1_ring_msi1_base_lsb_offset(hal), - srng->msi_addr); - - val = u32_encode_bits(((u64)srng->msi_addr >> HAL_ADDR_MSB_REG_SHIFT), - HAL_REO1_RING_MSI1_BASE_MSB_ADDR) | - HAL_REO1_RING_MSI1_BASE_MSB_MSI1_ENABLE; - ath12k_hif_write32(ab, reg_base + - ath12k_hal_reo1_ring_msi1_base_msb_offset(hal), val); - - ath12k_hif_write32(ab, - reg_base + ath12k_hal_reo1_ring_msi1_data_offset(hal), - srng->msi_data); - } - - ath12k_hif_write32(ab, reg_base, srng->ring_base_paddr); - - val = u32_encode_bits(((u64)srng->ring_base_paddr >> HAL_ADDR_MSB_REG_SHIFT), - HAL_REO1_RING_BASE_MSB_RING_BASE_ADDR_MSB) | - u32_encode_bits((srng->entry_size * srng->num_entries), - HAL_REO1_RING_BASE_MSB_RING_SIZE); - ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_base_msb_offset(hal), val); - - val = u32_encode_bits(srng->ring_id, HAL_REO1_RING_ID_RING_ID) | - u32_encode_bits(srng->entry_size, HAL_REO1_RING_ID_ENTRY_SIZE); - ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_id_offset(hal), val); - - /* interrupt setup */ - val = u32_encode_bits((srng->intr_timer_thres_us >> 3), - HAL_REO1_RING_PRDR_INT_SETUP_INTR_TMR_THOLD); - - val |= u32_encode_bits((srng->intr_batch_cntr_thres_entries * srng->entry_size), - HAL_REO1_RING_PRDR_INT_SETUP_BATCH_COUNTER_THOLD); - - ath12k_hif_write32(ab, - reg_base + ath12k_hal_reo1_ring_producer_int_setup_offset(hal), - val); - - hp_addr = hal->rdp.paddr + - ((unsigned long)srng->u.dst_ring.hp_addr - - (unsigned long)hal->rdp.vaddr); - ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_hp_addr_lsb_offset(hal), - hp_addr & HAL_ADDR_LSB_REG_MASK); - ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_hp_addr_msb_offset(hal), - hp_addr >> HAL_ADDR_MSB_REG_SHIFT); - - /* Initialize head and tail pointers to indicate ring is empty */ - reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2]; - ath12k_hif_write32(ab, reg_base, 0); - ath12k_hif_write32(ab, reg_base + HAL_REO1_RING_TP_OFFSET, 0); - *srng->u.dst_ring.hp_addr = 0; - - reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; - val = 0; - if (srng->flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP) - val |= HAL_REO1_RING_MISC_DATA_TLV_SWAP; - if (srng->flags & HAL_SRNG_FLAGS_RING_PTR_SWAP) - val |= HAL_REO1_RING_MISC_HOST_FW_SWAP; - if (srng->flags & HAL_SRNG_FLAGS_MSI_SWAP) - val |= HAL_REO1_RING_MISC_MSI_SWAP; - val |= HAL_REO1_RING_MISC_SRNG_ENABLE; - - ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_misc_offset(hal), val); -} - -static void ath12k_hal_srng_src_hw_init(struct ath12k_base *ab, - struct hal_srng *srng) -{ - struct ath12k_hal *hal = &ab->hal; - u32 val; - u64 tp_addr; - u32 reg_base; - - reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; - - if (srng->flags & HAL_SRNG_FLAGS_MSI_INTR) { - ath12k_hif_write32(ab, reg_base + - HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET(hal), - srng->msi_addr); - - val = u32_encode_bits(((u64)srng->msi_addr >> HAL_ADDR_MSB_REG_SHIFT), - HAL_TCL1_RING_MSI1_BASE_MSB_ADDR) | - HAL_TCL1_RING_MSI1_BASE_MSB_MSI1_ENABLE; - ath12k_hif_write32(ab, reg_base + - HAL_TCL1_RING_MSI1_BASE_MSB_OFFSET(hal), - val); - - ath12k_hif_write32(ab, reg_base + - HAL_TCL1_RING_MSI1_DATA_OFFSET(hal), - srng->msi_data); - } - - ath12k_hif_write32(ab, reg_base, srng->ring_base_paddr); - - val = u32_encode_bits(((u64)srng->ring_base_paddr >> HAL_ADDR_MSB_REG_SHIFT), - HAL_TCL1_RING_BASE_MSB_RING_BASE_ADDR_MSB) | - u32_encode_bits((srng->entry_size * srng->num_entries), - HAL_TCL1_RING_BASE_MSB_RING_SIZE); - ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_BASE_MSB_OFFSET(hal), val); - - val = u32_encode_bits(srng->entry_size, HAL_REO1_RING_ID_ENTRY_SIZE); - ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_ID_OFFSET(hal), val); - - val = u32_encode_bits(srng->intr_timer_thres_us, - HAL_TCL1_RING_CONSR_INT_SETUP_IX0_INTR_TMR_THOLD); - - val |= u32_encode_bits((srng->intr_batch_cntr_thres_entries * srng->entry_size), - HAL_TCL1_RING_CONSR_INT_SETUP_IX0_BATCH_COUNTER_THOLD); - - ath12k_hif_write32(ab, - reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX0_OFFSET(hal), - val); - - val = 0; - if (srng->flags & HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN) { - val |= u32_encode_bits(srng->u.src_ring.low_threshold, - HAL_TCL1_RING_CONSR_INT_SETUP_IX1_LOW_THOLD); - } - ath12k_hif_write32(ab, - reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX1_OFFSET(hal), - val); - - if (srng->ring_id != HAL_SRNG_RING_ID_WBM_IDLE_LINK) { - tp_addr = hal->rdp.paddr + - ((unsigned long)srng->u.src_ring.tp_addr - - (unsigned long)hal->rdp.vaddr); - ath12k_hif_write32(ab, - reg_base + HAL_TCL1_RING_TP_ADDR_LSB_OFFSET(hal), - tp_addr & HAL_ADDR_LSB_REG_MASK); - ath12k_hif_write32(ab, - reg_base + HAL_TCL1_RING_TP_ADDR_MSB_OFFSET(hal), - tp_addr >> HAL_ADDR_MSB_REG_SHIFT); - } - - /* Initialize head and tail pointers to indicate ring is empty */ - reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2]; - ath12k_hif_write32(ab, reg_base, 0); - ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_TP_OFFSET, 0); - *srng->u.src_ring.tp_addr = 0; - - reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; - val = 0; - if (srng->flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP) - val |= HAL_TCL1_RING_MISC_DATA_TLV_SWAP; - if (srng->flags & HAL_SRNG_FLAGS_RING_PTR_SWAP) - val |= HAL_TCL1_RING_MISC_HOST_FW_SWAP; - if (srng->flags & HAL_SRNG_FLAGS_MSI_SWAP) - val |= HAL_TCL1_RING_MISC_MSI_SWAP; - - /* Loop count is not used for SRC rings */ - val |= HAL_TCL1_RING_MISC_MSI_LOOPCNT_DISABLE; - - val |= HAL_TCL1_RING_MISC_SRNG_ENABLE; - - if (srng->ring_id == HAL_SRNG_RING_ID_WBM_IDLE_LINK) - val |= HAL_TCL1_RING_MISC_MSI_RING_ID_DISABLE; - - ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_MISC_OFFSET(hal), val); -} - static void ath12k_hal_srng_hw_init(struct ath12k_base *ab, struct hal_srng *srng) { @@ -828,7 +618,6 @@ int ath12k_hal_srng_setup(struct ath12k_base *ab, enum hal_ring_type type, int ring_id; u32 idx; int i; - u32 reg_base; ring_id = ath12k_hal_srng_get_ring_id(ab, type, ring_num, mac_id); if (ring_id < 0) @@ -863,8 +652,6 @@ int ath12k_hal_srng_setup(struct ath12k_base *ab, enum hal_ring_type type, memset(srng->ring_base_vaddr, 0, (srng->entry_size * srng->num_entries) << 2); - reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2]; - if (srng->ring_dir == HAL_SRNG_DIR_SRC) { srng->u.src_ring.hp = 0; srng->u.src_ring.cached_tp = 0; @@ -873,16 +660,7 @@ int ath12k_hal_srng_setup(struct ath12k_base *ab, enum hal_ring_type type, srng->u.src_ring.low_threshold = params->low_threshold * srng->entry_size; if (srng_config->mac_type == ATH12K_HAL_SRNG_UMAC) { - if (!ab->hw_params->supports_shadow_regs) - srng->u.src_ring.hp_addr = - (u32 *)((unsigned long)ab->mem + reg_base); - else - ath12k_dbg(ab, ATH12K_DBG_HAL, - "hal type %d ring_num %d reg_base 0x%x shadow 0x%lx\n", - type, ring_num, - reg_base, - (unsigned long)srng->u.src_ring.hp_addr - - (unsigned long)ab->mem); + ath12k_hal_set_umac_srng_ptr_addr(ab, srng); } else { idx = ring_id - HAL_SRNG_RING_ID_DMAC_CMN_ID_START; srng->u.src_ring.hp_addr = (void *)(hal->wrp.vaddr + @@ -903,17 +681,7 @@ int ath12k_hal_srng_setup(struct ath12k_base *ab, enum hal_ring_type type, srng->u.dst_ring.cached_hp = 0; srng->u.dst_ring.hp_addr = (void *)(hal->rdp.vaddr + ring_id); if (srng_config->mac_type == ATH12K_HAL_SRNG_UMAC) { - if (!ab->hw_params->supports_shadow_regs) - srng->u.dst_ring.tp_addr = - (u32 *)((unsigned long)ab->mem + reg_base + - (HAL_REO1_RING_TP - HAL_REO1_RING_HP)); - else - ath12k_dbg(ab, ATH12K_DBG_HAL, - "type %d ring_num %d target_reg 0x%x shadow 0x%lx\n", - type, ring_num, - reg_base + HAL_REO1_RING_TP - HAL_REO1_RING_HP, - (unsigned long)srng->u.dst_ring.tp_addr - - (unsigned long)ab->mem); + ath12k_hal_set_umac_srng_ptr_addr(ab, srng); } else { /* For PMAC & DMAC rings, tail pointer updates will be done * through FW by writing to a shared memory location diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 087e9a08f628..32c6a7d5ea99 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1696,6 +1696,12 @@ struct hal_ops { u32 (*rx_desc_get_mpdu_ppdu_id)(struct hal_rx_desc *desc); u8 (*rx_desc_get_l3_pad_bytes)(struct hal_rx_desc *desc); u8 *(*rx_desc_get_msdu_payload)(struct hal_rx_desc *desc); + void (*ce_dst_setup)(struct ath12k_base *ab, + struct hal_srng *srng, int ring_num); + void (*set_umac_srng_ptr_addr)(struct ath12k_base *ab, + struct hal_srng *srng); + void (*srng_src_hw_init)(struct ath12k_base *ab, struct hal_srng *srng); + void (*srng_dst_hw_init)(struct ath12k_base *ab, struct hal_srng *srng); }; u32 ath12k_wifi7_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c index 25963ac18cb9..2b81d70e60df 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c @@ -7,6 +7,8 @@ #include "hal_desc.h" #include "../hal.h" #include "hal.h" +#include "../debug.h" +#include "../hif.h" #include "hal_qcn9274.h" #include "hal_wcn7850.h" @@ -56,3 +58,278 @@ int ath12k_wifi7_hal_init(struct ath12k_base *ab) return 0; } EXPORT_SYMBOL(ath12k_wifi7_hal_init); + +static unsigned int ath12k_wifi7_hal_reo1_ring_id_offset(struct ath12k_hal *hal) +{ + return HAL_REO1_RING_ID(hal) - HAL_REO1_RING_BASE_LSB(hal); +} + +static unsigned +int ath12k_wifi7_hal_reo1_ring_msi1_base_lsb_offset(struct ath12k_hal *hal) +{ + return HAL_REO1_RING_MSI1_BASE_LSB(hal) - HAL_REO1_RING_BASE_LSB(hal); +} + +static unsigned +int ath12k_wifi7_hal_reo1_ring_msi1_base_msb_offset(struct ath12k_hal *hal) +{ + return HAL_REO1_RING_MSI1_BASE_MSB(hal) - HAL_REO1_RING_BASE_LSB(hal); +} + +static unsigned int ath12k_wifi7_hal_reo1_ring_msi1_data_offset(struct ath12k_hal *hal) +{ + return HAL_REO1_RING_MSI1_DATA(hal) - HAL_REO1_RING_BASE_LSB(hal); +} + +static unsigned int ath12k_wifi7_hal_reo1_ring_base_msb_offset(struct ath12k_hal *hal) +{ + return HAL_REO1_RING_BASE_MSB(hal) - HAL_REO1_RING_BASE_LSB(hal); +} + +static unsigned +int ath12k_wifi7_hal_reo1_ring_producer_int_setup_offset(struct ath12k_hal *hal) +{ + return HAL_REO1_RING_PRODUCER_INT_SETUP(hal) - HAL_REO1_RING_BASE_LSB(hal); +} + +static unsigned int ath12k_wifi7_hal_reo1_ring_hp_addr_lsb_offset(struct ath12k_hal *hal) +{ + return HAL_REO1_RING_HP_ADDR_LSB(hal) - HAL_REO1_RING_BASE_LSB(hal); +} + +static unsigned int ath12k_wifi7_hal_reo1_ring_hp_addr_msb_offset(struct ath12k_hal *hal) +{ + return HAL_REO1_RING_HP_ADDR_MSB(hal) - HAL_REO1_RING_BASE_LSB(hal); +} + +static unsigned int ath12k_wifi7_hal_reo1_ring_misc_offset(struct ath12k_hal *hal) +{ + return HAL_REO1_RING_MISC(hal) - HAL_REO1_RING_BASE_LSB(hal); +} + +void ath12k_wifi7_hal_ce_dst_setup(struct ath12k_base *ab, + struct hal_srng *srng, int ring_num) +{ + struct hal_srng_config *srng_config = &ab->hal.srng_config[HAL_CE_DST]; + u32 addr; + u32 val; + + addr = HAL_CE_DST_RING_CTRL + + srng_config->reg_start[HAL_SRNG_REG_GRP_R0] + + ring_num * srng_config->reg_size[HAL_SRNG_REG_GRP_R0]; + + val = ath12k_hif_read32(ab, addr); + val &= ~HAL_CE_DST_R0_DEST_CTRL_MAX_LEN; + val |= u32_encode_bits(srng->u.dst_ring.max_buffer_length, + HAL_CE_DST_R0_DEST_CTRL_MAX_LEN); + ath12k_hif_write32(ab, addr, val); +} + +void ath12k_wifi7_hal_srng_dst_hw_init(struct ath12k_base *ab, + struct hal_srng *srng) +{ + struct ath12k_hal *hal = &ab->hal; + u32 val; + u64 hp_addr; + u32 reg_base; + + reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; + + if (srng->flags & HAL_SRNG_FLAGS_MSI_INTR) { + ath12k_hif_write32(ab, reg_base + + ath12k_wifi7_hal_reo1_ring_msi1_base_lsb_offset(hal), + srng->msi_addr); + + val = u32_encode_bits(((u64)srng->msi_addr >> HAL_ADDR_MSB_REG_SHIFT), + HAL_REO1_RING_MSI1_BASE_MSB_ADDR) | + HAL_REO1_RING_MSI1_BASE_MSB_MSI1_ENABLE; + ath12k_hif_write32(ab, reg_base + + ath12k_wifi7_hal_reo1_ring_msi1_base_msb_offset(hal), + val); + + ath12k_hif_write32(ab, + reg_base + + ath12k_wifi7_hal_reo1_ring_msi1_data_offset(hal), + srng->msi_data); + } + + ath12k_hif_write32(ab, reg_base, srng->ring_base_paddr); + + val = u32_encode_bits(((u64)srng->ring_base_paddr >> HAL_ADDR_MSB_REG_SHIFT), + HAL_REO1_RING_BASE_MSB_RING_BASE_ADDR_MSB) | + u32_encode_bits((srng->entry_size * srng->num_entries), + HAL_REO1_RING_BASE_MSB_RING_SIZE); + ath12k_hif_write32(ab, reg_base + ath12k_wifi7_hal_reo1_ring_base_msb_offset(hal), + val); + + val = u32_encode_bits(srng->ring_id, HAL_REO1_RING_ID_RING_ID) | + u32_encode_bits(srng->entry_size, HAL_REO1_RING_ID_ENTRY_SIZE); + ath12k_hif_write32(ab, reg_base + ath12k_wifi7_hal_reo1_ring_id_offset(hal), val); + + /* interrupt setup */ + val = u32_encode_bits((srng->intr_timer_thres_us >> 3), + HAL_REO1_RING_PRDR_INT_SETUP_INTR_TMR_THOLD); + + val |= u32_encode_bits((srng->intr_batch_cntr_thres_entries * srng->entry_size), + HAL_REO1_RING_PRDR_INT_SETUP_BATCH_COUNTER_THOLD); + + ath12k_hif_write32(ab, + reg_base + + ath12k_wifi7_hal_reo1_ring_producer_int_setup_offset(hal), + val); + + hp_addr = hal->rdp.paddr + + ((unsigned long)srng->u.dst_ring.hp_addr - + (unsigned long)hal->rdp.vaddr); + ath12k_hif_write32(ab, reg_base + + ath12k_wifi7_hal_reo1_ring_hp_addr_lsb_offset(hal), + hp_addr & HAL_ADDR_LSB_REG_MASK); + ath12k_hif_write32(ab, reg_base + + ath12k_wifi7_hal_reo1_ring_hp_addr_msb_offset(hal), + hp_addr >> HAL_ADDR_MSB_REG_SHIFT); + + /* Initialize head and tail pointers to indicate ring is empty */ + reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2]; + ath12k_hif_write32(ab, reg_base, 0); + ath12k_hif_write32(ab, reg_base + HAL_REO1_RING_TP_OFFSET, 0); + *srng->u.dst_ring.hp_addr = 0; + + reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; + val = 0; + if (srng->flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP) + val |= HAL_REO1_RING_MISC_DATA_TLV_SWAP; + if (srng->flags & HAL_SRNG_FLAGS_RING_PTR_SWAP) + val |= HAL_REO1_RING_MISC_HOST_FW_SWAP; + if (srng->flags & HAL_SRNG_FLAGS_MSI_SWAP) + val |= HAL_REO1_RING_MISC_MSI_SWAP; + val |= HAL_REO1_RING_MISC_SRNG_ENABLE; + + ath12k_hif_write32(ab, reg_base + ath12k_wifi7_hal_reo1_ring_misc_offset(hal), + val); +} + +void ath12k_wifi7_hal_srng_src_hw_init(struct ath12k_base *ab, + struct hal_srng *srng) +{ + struct ath12k_hal *hal = &ab->hal; + u32 val; + u64 tp_addr; + u32 reg_base; + + reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; + + if (srng->flags & HAL_SRNG_FLAGS_MSI_INTR) { + ath12k_hif_write32(ab, reg_base + + HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET(hal), + srng->msi_addr); + + val = u32_encode_bits(((u64)srng->msi_addr >> HAL_ADDR_MSB_REG_SHIFT), + HAL_TCL1_RING_MSI1_BASE_MSB_ADDR) | + HAL_TCL1_RING_MSI1_BASE_MSB_MSI1_ENABLE; + ath12k_hif_write32(ab, reg_base + + HAL_TCL1_RING_MSI1_BASE_MSB_OFFSET(hal), + val); + + ath12k_hif_write32(ab, reg_base + + HAL_TCL1_RING_MSI1_DATA_OFFSET(hal), + srng->msi_data); + } + + ath12k_hif_write32(ab, reg_base, srng->ring_base_paddr); + + val = u32_encode_bits(((u64)srng->ring_base_paddr >> HAL_ADDR_MSB_REG_SHIFT), + HAL_TCL1_RING_BASE_MSB_RING_BASE_ADDR_MSB) | + u32_encode_bits((srng->entry_size * srng->num_entries), + HAL_TCL1_RING_BASE_MSB_RING_SIZE); + ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_BASE_MSB_OFFSET(hal), val); + + val = u32_encode_bits(srng->entry_size, HAL_REO1_RING_ID_ENTRY_SIZE); + ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_ID_OFFSET(hal), val); + + val = u32_encode_bits(srng->intr_timer_thres_us, + HAL_TCL1_RING_CONSR_INT_SETUP_IX0_INTR_TMR_THOLD); + + val |= u32_encode_bits((srng->intr_batch_cntr_thres_entries * srng->entry_size), + HAL_TCL1_RING_CONSR_INT_SETUP_IX0_BATCH_COUNTER_THOLD); + + ath12k_hif_write32(ab, + reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX0_OFFSET(hal), + val); + + val = 0; + if (srng->flags & HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN) { + val |= u32_encode_bits(srng->u.src_ring.low_threshold, + HAL_TCL1_RING_CONSR_INT_SETUP_IX1_LOW_THOLD); + } + ath12k_hif_write32(ab, + reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX1_OFFSET(hal), + val); + + if (srng->ring_id != HAL_SRNG_RING_ID_WBM_IDLE_LINK) { + tp_addr = hal->rdp.paddr + + ((unsigned long)srng->u.src_ring.tp_addr - + (unsigned long)hal->rdp.vaddr); + ath12k_hif_write32(ab, + reg_base + HAL_TCL1_RING_TP_ADDR_LSB_OFFSET(hal), + tp_addr & HAL_ADDR_LSB_REG_MASK); + ath12k_hif_write32(ab, + reg_base + HAL_TCL1_RING_TP_ADDR_MSB_OFFSET(hal), + tp_addr >> HAL_ADDR_MSB_REG_SHIFT); + } + + /* Initialize head and tail pointers to indicate ring is empty */ + reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2]; + ath12k_hif_write32(ab, reg_base, 0); + ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_TP_OFFSET, 0); + *srng->u.src_ring.tp_addr = 0; + + reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0]; + val = 0; + if (srng->flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP) + val |= HAL_TCL1_RING_MISC_DATA_TLV_SWAP; + if (srng->flags & HAL_SRNG_FLAGS_RING_PTR_SWAP) + val |= HAL_TCL1_RING_MISC_HOST_FW_SWAP; + if (srng->flags & HAL_SRNG_FLAGS_MSI_SWAP) + val |= HAL_TCL1_RING_MISC_MSI_SWAP; + + /* Loop count is not used for SRC rings */ + val |= HAL_TCL1_RING_MISC_MSI_LOOPCNT_DISABLE; + + val |= HAL_TCL1_RING_MISC_SRNG_ENABLE; + + if (srng->ring_id == HAL_SRNG_RING_ID_WBM_IDLE_LINK) + val |= HAL_TCL1_RING_MISC_MSI_RING_ID_DISABLE; + + ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_MISC_OFFSET(hal), val); +} + +void ath12k_wifi7_hal_set_umac_srng_ptr_addr(struct ath12k_base *ab, + struct hal_srng *srng) +{ + u32 reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2]; + + if (srng->ring_dir == HAL_SRNG_DIR_SRC) { + if (!ab->hw_params->supports_shadow_regs) { + srng->u.src_ring.hp_addr = + (u32 *)((unsigned long)ab->mem + reg_base); + } else { + ath12k_dbg(ab, ATH12K_DBG_HAL, + "hal reg_base 0x%x shadow 0x%lx\n", + reg_base, + (unsigned long)srng->u.src_ring.hp_addr - + (unsigned long)ab->mem); + } + } else { + if (!ab->hw_params->supports_shadow_regs) { + srng->u.dst_ring.tp_addr = + (u32 *)((unsigned long)ab->mem + reg_base + + (HAL_REO1_RING_TP - HAL_REO1_RING_HP)); + } else { + ath12k_dbg(ab, ATH12K_DBG_HAL, + "target_reg 0x%x shadow 0x%lx\n", + reg_base + HAL_REO1_RING_TP - HAL_REO1_RING_HP, + (unsigned long)srng->u.dst_ring.tp_addr - + (unsigned long)ab->mem); + } + } +} diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.h b/drivers/net/wireless/ath/ath12k/wifi7/hal.h index 1a8a720c4923..044ed1dce323 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.h @@ -8,4 +8,12 @@ #define ATH12K_HAL_WIFI7_H int ath12k_wifi7_hal_init(struct ath12k_base *ab); +void ath12k_wifi7_hal_ce_dst_setup(struct ath12k_base *ab, + struct hal_srng *srng, int ring_num); +void ath12k_wifi7_hal_srng_dst_hw_init(struct ath12k_base *ab, + struct hal_srng *srng); +void ath12k_wifi7_hal_srng_src_hw_init(struct ath12k_base *ab, + struct hal_srng *srng); +void ath12k_wifi7_hal_set_umac_srng_ptr_addr(struct ath12k_base *ab, + struct hal_srng *srng); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index 592007f1cad6..070e28a38a70 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -1000,5 +1000,9 @@ const struct hal_ops hal_qcn9274_ops = { .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274, .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcn9274, .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_qcn9274, + .ce_dst_setup = ath12k_wifi7_hal_ce_dst_setup, + .srng_src_hw_init = ath12k_wifi7_hal_srng_src_hw_init, + .srng_dst_hw_init = ath12k_wifi7_hal_srng_dst_hw_init, + .set_umac_srng_ptr_addr = ath12k_wifi7_hal_set_umac_srng_ptr_addr, }; EXPORT_SYMBOL(hal_qcn9274_ops); diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index 8949b6fc833a..9d1f94db60bd 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -815,5 +815,9 @@ const struct hal_ops hal_wcn7850_ops = { .rx_desc_get_mpdu_start_tag = ath12k_hal_rx_desc_get_mpdu_start_tag_wcn7850, .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_wcn7850, .rx_desc_get_msdu_payload = ath12k_hal_rx_desc_get_msdu_payload_wcn7850, + .ce_dst_setup = ath12k_wifi7_hal_ce_dst_setup, + .srng_src_hw_init = ath12k_wifi7_hal_srng_src_hw_init, + .srng_dst_hw_init = ath12k_wifi7_hal_srng_dst_hw_init, + .set_umac_srng_ptr_addr = ath12k_wifi7_hal_set_umac_srng_ptr_addr, }; EXPORT_SYMBOL(hal_wcn7850_ops); -- 2.34.1