123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708 |
- /*
- * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
- *
- * Permission to use, copy, modify, and/or distribute this software for
- * any purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all
- * copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
- * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
- #ifndef _HAL_GENERIC_API_H_
- #define _HAL_GENERIC_API_H_
- #include <hal_rx.h>
- #define SRNG_ENABLE_BIT 0x40
- #define SRNG_IDLE_STATE_BIT 0x80
- /**
- * hal_get_radiotap_he_gi_ltf() - Convert HE ltf and GI value
- * from stats enum to radiotap enum
- * @he_gi: HE GI value used in stats
- * @he_ltf: HE LTF value used in stats
- *
- * Return: void
- */
- static inline void hal_get_radiotap_he_gi_ltf(uint16_t *he_gi, uint16_t *he_ltf)
- {
- switch (*he_gi) {
- case HE_GI_0_8:
- *he_gi = HE_GI_RADIOTAP_0_8;
- break;
- case HE_GI_1_6:
- *he_gi = HE_GI_RADIOTAP_1_6;
- break;
- case HE_GI_3_2:
- *he_gi = HE_GI_RADIOTAP_3_2;
- break;
- default:
- *he_gi = HE_GI_RADIOTAP_RESERVED;
- }
- switch (*he_ltf) {
- case HE_LTF_1_X:
- *he_ltf = HE_LTF_RADIOTAP_1_X;
- break;
- case HE_LTF_2_X:
- *he_ltf = HE_LTF_RADIOTAP_2_X;
- break;
- case HE_LTF_4_X:
- *he_ltf = HE_LTF_RADIOTAP_4_X;
- break;
- default:
- *he_ltf = HE_LTF_RADIOTAP_UNKNOWN;
- }
- }
- /* channel number to freq conversion */
- #define CHANNEL_NUM_14 14
- #define CHANNEL_NUM_15 15
- #define CHANNEL_NUM_27 27
- #define CHANNEL_NUM_35 35
- #define CHANNEL_NUM_182 182
- #define CHANNEL_NUM_197 197
- #define CHANNEL_FREQ_2484 2484
- #define CHANNEL_FREQ_2407 2407
- #define CHANNEL_FREQ_2512 2512
- #define CHANNEL_FREQ_5000 5000
- #define CHANNEL_FREQ_5950 5950
- #define CHANNEL_FREQ_4000 4000
- #define CHANNEL_FREQ_5150 5150
- #define CHANNEL_FREQ_5920 5920
- #define CHANNEL_FREQ_5935 5935
- #define FREQ_MULTIPLIER_CONST_5MHZ 5
- #define FREQ_MULTIPLIER_CONST_20MHZ 20
- /**
- * hal_rx_radiotap_num_to_freq() - Get frequency from chan number
- * @chan_num: Input channel number
- * @center_freq: Input Channel Center frequency
- *
- * Return - Channel frequency in Mhz
- */
- static inline uint16_t
- hal_rx_radiotap_num_to_freq(uint16_t chan_num, qdf_freq_t center_freq)
- {
- if (center_freq > CHANNEL_FREQ_5920 && center_freq < CHANNEL_FREQ_5950)
- return CHANNEL_FREQ_5935;
- if (center_freq < CHANNEL_FREQ_5950) {
- if (chan_num == CHANNEL_NUM_14)
- return CHANNEL_FREQ_2484;
- if (chan_num < CHANNEL_NUM_14)
- return CHANNEL_FREQ_2407 +
- (chan_num * FREQ_MULTIPLIER_CONST_5MHZ);
- if (chan_num < CHANNEL_NUM_27)
- return CHANNEL_FREQ_2512 +
- ((chan_num - CHANNEL_NUM_15) *
- FREQ_MULTIPLIER_CONST_20MHZ);
- if (chan_num > CHANNEL_NUM_182 &&
- chan_num < CHANNEL_NUM_197)
- return ((chan_num * FREQ_MULTIPLIER_CONST_5MHZ) +
- CHANNEL_FREQ_4000);
- return CHANNEL_FREQ_5000 +
- (chan_num * FREQ_MULTIPLIER_CONST_5MHZ);
- } else {
- return CHANNEL_FREQ_5950 +
- (chan_num * FREQ_MULTIPLIER_CONST_5MHZ);
- }
- }
- /**
- * hal_get_hw_hptp_generic() - Get HW head and tail pointer value for any ring
- * @hal_soc: Opaque HAL SOC handle
- * @hal_ring_hdl: Source ring pointer
- * @headp: Head Pointer
- * @tailp: Tail Pointer
- * @ring: Ring type
- *
- * Return: Update tail pointer and head pointer in arguments.
- */
- static inline
- void hal_get_hw_hptp_generic(struct hal_soc *hal_soc,
- hal_ring_handle_t hal_ring_hdl,
- uint32_t *headp, uint32_t *tailp,
- uint8_t ring)
- {
- struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
- struct hal_hw_srng_config *ring_config;
- enum hal_ring_type ring_type = (enum hal_ring_type)ring;
- if (!hal_soc || !srng) {
- QDF_TRACE(QDF_MODULE_ID_HAL, QDF_TRACE_LEVEL_ERROR,
- "%s: Context is Null", __func__);
- return;
- }
- ring_config = HAL_SRNG_CONFIG(hal_soc, ring_type);
- if (!ring_config->lmac_ring) {
- if (srng->ring_dir == HAL_SRNG_SRC_RING) {
- *headp = SRNG_SRC_REG_READ(srng, HP);
- *tailp = SRNG_SRC_REG_READ(srng, TP);
- } else {
- *headp = SRNG_DST_REG_READ(srng, HP);
- *tailp = SRNG_DST_REG_READ(srng, TP);
- }
- }
- }
- #ifdef DP_UMAC_HW_RESET_SUPPORT
- /**
- * hal_srng_src_hw_write_cons_prefetch_timer() - Write cons prefetch timer reg
- * @srng: srng handle
- * @value: value to set
- *
- * Return: None
- */
- static inline
- void hal_srng_src_hw_write_cons_prefetch_timer(struct hal_srng *srng,
- uint32_t value)
- {
- SRNG_SRC_REG_WRITE(srng, CONSUMER_PREFETCH_TIMER, value);
- }
- /**
- * hal_srng_hw_disable_generic() - Private function to disable SRNG
- * source ring HW
- * @hal: HAL SOC handle
- * @srng: SRNG ring pointer
- */
- static inline
- void hal_srng_hw_disable_generic(struct hal_soc *hal, struct hal_srng *srng)
- {
- uint32_t reg_val = 0;
- struct hal_hw_srng_config *ring_config =
- HAL_SRNG_CONFIG(hal, srng->ring_type);
- if (ring_config->lmac_ring)
- return;
- if (srng->ring_dir == HAL_SRNG_DST_RING) {
- reg_val = SRNG_DST_REG_READ(srng, MISC) & ~(SRNG_ENABLE_BIT);
- SRNG_DST_REG_WRITE(srng, MISC, reg_val);
- } else {
- reg_val = SRNG_SRC_REG_READ(srng, MISC) & ~(SRNG_ENABLE_BIT);
- SRNG_SRC_REG_WRITE(srng, MISC, reg_val);
- srng->prefetch_timer =
- SRNG_SRC_REG_READ(srng, CONSUMER_PREFETCH_TIMER);
- hal_srng_src_hw_write_cons_prefetch_timer(srng, 0);
- }
- }
- #else
- static inline
- void hal_srng_hw_disable_generic(struct hal_soc *hal, struct hal_srng *srng)
- {
- }
- static inline
- void hal_srng_src_hw_write_cons_prefetch_timer(struct hal_srng *srng,
- uint32_t value)
- {
- }
- #endif
- #ifndef WLAN_SOFTUMAC_SUPPORT
- #if defined(WBM_IDLE_LSB_WRITE_CONFIRM_WAR)
- /**
- * hal_wbm_idle_lsb_write_confirm() - Check and update WBM_IDLE_LINK ring LSB
- * @srng: srng handle
- *
- * Return: None
- */
- static void hal_wbm_idle_lsb_write_confirm(struct hal_srng *srng)
- {
- if (srng->ring_id == HAL_SRNG_WBM_IDLE_LINK) {
- while (SRNG_SRC_REG_READ(srng, BASE_LSB) !=
- ((unsigned int)srng->ring_base_paddr & 0xffffffff))
- SRNG_SRC_REG_WRITE(srng, BASE_LSB,
- srng->ring_base_paddr &
- 0xffffffff);
- }
- }
- #else
- static void hal_wbm_idle_lsb_write_confirm(struct hal_srng *srng)
- {
- }
- #endif
- /**
- * hal_srng_src_hw_init_generic() - Private function to initialize SRNG
- * source ring HW
- * @hal: HAL SOC handle
- * @srng: SRNG ring pointer
- * @idle_check: Check if ring is idle
- * @idx: ring index
- */
- static inline
- void hal_srng_src_hw_init_generic(struct hal_soc *hal,
- struct hal_srng *srng, bool idle_check,
- uint32_t idx)
- {
- uint32_t reg_val = 0;
- uint64_t tp_addr = 0;
- hal_debug("hw_init srng %d", srng->ring_id);
- if (idle_check) {
- reg_val = SRNG_SRC_REG_READ(srng, MISC);
- if (!(reg_val & SRNG_IDLE_STATE_BIT)) {
- hal_err("ring_id %d not in idle state", srng->ring_id);
- qdf_assert_always(0);
- }
- hal_srng_src_hw_write_cons_prefetch_timer(srng,
- srng->prefetch_timer);
- } else {
- reg_val = SRNG_SRC_REG_READ(srng, MISC) & ~(SRNG_ENABLE_BIT);
- SRNG_SRC_REG_WRITE(srng, MISC, reg_val);
- }
- reg_val = 0;
- if (srng->flags & HAL_SRNG_MSI_INTR) {
- SRNG_SRC_REG_WRITE(srng, MSI1_BASE_LSB,
- srng->msi_addr & 0xffffffff);
- reg_val = SRNG_SM(SRNG_SRC_FLD(MSI1_BASE_MSB, ADDR),
- (uint64_t)(srng->msi_addr) >> 32) |
- SRNG_SM(SRNG_SRC_FLD(MSI1_BASE_MSB,
- MSI1_ENABLE), 1);
- SRNG_SRC_REG_WRITE(srng, MSI1_BASE_MSB, reg_val);
- SRNG_SRC_REG_WRITE(srng, MSI1_DATA,
- qdf_cpu_to_le32(srng->msi_data));
- }
- SRNG_SRC_REG_WRITE(srng, BASE_LSB, srng->ring_base_paddr & 0xffffffff);
- hal_wbm_idle_lsb_write_confirm(srng);
- reg_val = SRNG_SM(SRNG_SRC_FLD(BASE_MSB, RING_BASE_ADDR_MSB),
- ((uint64_t)(srng->ring_base_paddr) >> 32)) |
- SRNG_SM(SRNG_SRC_FLD(BASE_MSB, RING_SIZE),
- srng->entry_size * srng->num_entries);
- SRNG_SRC_REG_WRITE(srng, BASE_MSB, reg_val);
- reg_val = SRNG_SM(SRNG_SRC_FLD(ID, ENTRY_SIZE), srng->entry_size);
- SRNG_SRC_REG_WRITE(srng, ID, reg_val);
- /**
- * Interrupt setup:
- * Default interrupt mode is 'pulse'. Need to setup SW_INTERRUPT_MODE
- * if level mode is required
- */
- reg_val = 0;
- /*
- * WAR - Hawkeye v1 has a hardware bug which requires timer value to be
- * programmed in terms of 1us resolution instead of 8us resolution as
- * given in MLD.
- */
- if (srng->intr_timer_thres_us) {
- reg_val |= SRNG_SM(SRNG_SRC_FLD(CONSUMER_INT_SETUP_IX0,
- INTERRUPT_TIMER_THRESHOLD),
- srng->intr_timer_thres_us >> 3);
- /* For HK v2 this should be (srng->intr_timer_thres_us >> 3) */
- }
- if (srng->intr_batch_cntr_thres_entries) {
- reg_val |= SRNG_SM(SRNG_SRC_FLD(CONSUMER_INT_SETUP_IX0,
- BATCH_COUNTER_THRESHOLD),
- srng->intr_batch_cntr_thres_entries *
- srng->entry_size);
- }
- SRNG_SRC_REG_WRITE(srng, CONSUMER_INT_SETUP_IX0, reg_val);
- reg_val = 0;
- if (srng->flags & HAL_SRNG_LOW_THRES_INTR_ENABLE) {
- reg_val |= SRNG_SM(SRNG_SRC_FLD(CONSUMER_INT_SETUP_IX1,
- LOW_THRESHOLD), srng->u.src_ring.low_threshold);
- }
- SRNG_SRC_REG_WRITE(srng, CONSUMER_INT_SETUP_IX1, reg_val);
- /* As per HW team, TP_ADDR and HP_ADDR for Idle link ring should
- * remain 0 to avoid some WBM stability issues. Remote head/tail
- * pointers are not required since this ring is completely managed
- * by WBM HW
- */
- reg_val = 0;
- if (srng->ring_id != HAL_SRNG_WBM_IDLE_LINK) {
- tp_addr = (uint64_t)(hal->shadow_rdptr_mem_paddr +
- ((unsigned long)(srng->u.src_ring.tp_addr) -
- (unsigned long)(hal->shadow_rdptr_mem_vaddr)));
- SRNG_SRC_REG_WRITE(srng, TP_ADDR_LSB, tp_addr & 0xffffffff);
- SRNG_SRC_REG_WRITE(srng, TP_ADDR_MSB, tp_addr >> 32);
- } else {
- reg_val |= SRNG_SM(SRNG_SRC_FLD(MISC, RING_ID_DISABLE), 1);
- }
- /* Initilaize head and tail pointers to indicate ring is empty */
- SRNG_SRC_REG_WRITE(srng, HP, idx * srng->entry_size);
- SRNG_SRC_REG_WRITE(srng, TP, idx * srng->entry_size);
- *srng->u.src_ring.tp_addr = idx * srng->entry_size;
- srng->u.src_ring.hp = idx * srng->entry_size;
- reg_val |= ((srng->flags & HAL_SRNG_DATA_TLV_SWAP) ?
- SRNG_SM(SRNG_SRC_FLD(MISC, DATA_TLV_SWAP_BIT), 1) : 0) |
- ((srng->flags & HAL_SRNG_RING_PTR_SWAP) ?
- SRNG_SM(SRNG_SRC_FLD(MISC, HOST_FW_SWAP_BIT), 1) : 0) |
- ((srng->flags & HAL_SRNG_MSI_SWAP) ?
- SRNG_SM(SRNG_SRC_FLD(MISC, MSI_SWAP_BIT), 1) : 0);
- /* Loop count is not used for SRC rings */
- reg_val |= SRNG_SM(SRNG_SRC_FLD(MISC, LOOPCNT_DISABLE), 1);
- /*
- * reg_val |= SRNG_SM(SRNG_SRC_FLD(MISC, SRNG_ENABLE), 1);
- * todo: update fw_api and replace with above line
- * (when SRNG_ENABLE field for the MISC register is available in fw_api)
- * (WCSS_UMAC_CE_0_SRC_WFSS_CE_CHANNEL_SRC_R0_SRC_RING_MISC)
- */
- reg_val |= SRNG_ENABLE_BIT;
- SRNG_SRC_REG_WRITE(srng, MISC, reg_val);
- }
- #ifdef WLAN_FEATURE_NEAR_FULL_IRQ
- /**
- * hal_srng_dst_msi2_setup() - Configure MSI2 register for a SRNG
- * @srng: SRNG handle
- *
- * Return: None
- */
- static inline void hal_srng_dst_msi2_setup(struct hal_srng *srng)
- {
- uint32_t reg_val = 0;
- if (srng->u.dst_ring.nf_irq_support) {
- SRNG_DST_REG_WRITE(srng, MSI2_BASE_LSB,
- srng->msi2_addr & 0xffffffff);
- reg_val = SRNG_SM(SRNG_DST_FLD(MSI2_BASE_MSB, ADDR),
- (uint64_t)(srng->msi2_addr) >> 32) |
- SRNG_SM(SRNG_DST_FLD(MSI2_BASE_MSB,
- MSI2_ENABLE), 1);
- SRNG_DST_REG_WRITE(srng, MSI2_BASE_MSB, reg_val);
- SRNG_DST_REG_WRITE(srng, MSI2_DATA,
- qdf_cpu_to_le32(srng->msi2_data));
- }
- }
- /**
- * hal_srng_dst_near_full_int_setup() - Configure near-full params for SRNG
- * @srng: SRNG handle
- *
- * Return: None
- */
- static inline void hal_srng_dst_near_full_int_setup(struct hal_srng *srng)
- {
- uint32_t reg_val = 0;
- if (srng->u.dst_ring.nf_irq_support) {
- if (srng->intr_timer_thres_us) {
- reg_val |= SRNG_SM(SRNG_DST_FLD(PRODUCER_INT2_SETUP,
- INTERRUPT2_TIMER_THRESHOLD),
- srng->intr_timer_thres_us >> 3);
- }
- reg_val |= SRNG_SM(SRNG_DST_FLD(PRODUCER_INT2_SETUP,
- HIGH_THRESHOLD),
- srng->u.dst_ring.high_thresh *
- srng->entry_size);
- }
- SRNG_DST_REG_WRITE(srng, PRODUCER_INT2_SETUP, reg_val);
- }
- #else
- static inline void hal_srng_dst_msi2_setup(struct hal_srng *srng)
- {
- }
- static inline void hal_srng_dst_near_full_int_setup(struct hal_srng *srng)
- {
- }
- #endif
- /**
- * hal_srng_dst_hw_init_generic() - Private function to initialize SRNG
- * destination ring HW
- * @hal: HAL SOC handle
- * @srng: SRNG ring pointer
- * @idle_check: Check if ring is idle
- * @idx: Ring index
- */
- static inline
- void hal_srng_dst_hw_init_generic(struct hal_soc *hal,
- struct hal_srng *srng, bool idle_check,
- uint32_t idx)
- {
- uint32_t reg_val = 0;
- uint64_t hp_addr = 0;
- hal_debug("hw_init srng %d", srng->ring_id);
- if (idle_check) {
- reg_val = SRNG_DST_REG_READ(srng, MISC);
- if (!(reg_val & SRNG_IDLE_STATE_BIT)) {
- hal_err("ring_id %d not in idle state", srng->ring_id);
- qdf_assert_always(0);
- }
- } else {
- reg_val = SRNG_DST_REG_READ(srng, MISC) & ~(SRNG_ENABLE_BIT);
- SRNG_DST_REG_WRITE(srng, MISC, reg_val);
- }
- reg_val = 0;
- if (srng->flags & HAL_SRNG_MSI_INTR) {
- SRNG_DST_REG_WRITE(srng, MSI1_BASE_LSB,
- srng->msi_addr & 0xffffffff);
- reg_val = SRNG_SM(SRNG_DST_FLD(MSI1_BASE_MSB, ADDR),
- (uint64_t)(srng->msi_addr) >> 32) |
- SRNG_SM(SRNG_DST_FLD(MSI1_BASE_MSB,
- MSI1_ENABLE), 1);
- SRNG_DST_REG_WRITE(srng, MSI1_BASE_MSB, reg_val);
- SRNG_DST_REG_WRITE(srng, MSI1_DATA,
- qdf_cpu_to_le32(srng->msi_data));
- hal_srng_dst_msi2_setup(srng);
- }
- SRNG_DST_REG_WRITE(srng, BASE_LSB, srng->ring_base_paddr & 0xffffffff);
- reg_val = SRNG_SM(SRNG_DST_FLD(BASE_MSB, RING_BASE_ADDR_MSB),
- ((uint64_t)(srng->ring_base_paddr) >> 32)) |
- SRNG_SM(SRNG_DST_FLD(BASE_MSB, RING_SIZE),
- srng->entry_size * srng->num_entries);
- SRNG_DST_REG_WRITE(srng, BASE_MSB, reg_val);
- reg_val = SRNG_SM(SRNG_DST_FLD(ID, RING_ID), srng->ring_id) |
- SRNG_SM(SRNG_DST_FLD(ID, ENTRY_SIZE), srng->entry_size);
- SRNG_DST_REG_WRITE(srng, ID, reg_val);
- /**
- * Interrupt setup:
- * Default interrupt mode is 'pulse'. Need to setup SW_INTERRUPT_MODE
- * if level mode is required
- */
- reg_val = 0;
- if (srng->intr_timer_thres_us) {
- reg_val |= SRNG_SM(SRNG_DST_FLD(PRODUCER_INT_SETUP,
- INTERRUPT_TIMER_THRESHOLD),
- srng->intr_timer_thres_us >> 3);
- }
- if (srng->intr_batch_cntr_thres_entries) {
- reg_val |= SRNG_SM(SRNG_DST_FLD(PRODUCER_INT_SETUP,
- BATCH_COUNTER_THRESHOLD),
- srng->intr_batch_cntr_thres_entries *
- srng->entry_size);
- }
- SRNG_DST_REG_WRITE(srng, PRODUCER_INT_SETUP, reg_val);
- /**
- * Near-Full Interrupt setup:
- * Default interrupt mode is 'pulse'. Need to setup SW_INTERRUPT_MODE
- * if level mode is required
- */
- hal_srng_dst_near_full_int_setup(srng);
- hp_addr = (uint64_t)(hal->shadow_rdptr_mem_paddr +
- ((unsigned long)(srng->u.dst_ring.hp_addr) -
- (unsigned long)(hal->shadow_rdptr_mem_vaddr)));
- SRNG_DST_REG_WRITE(srng, HP_ADDR_LSB, hp_addr & 0xffffffff);
- SRNG_DST_REG_WRITE(srng, HP_ADDR_MSB, hp_addr >> 32);
- /* Initilaize head and tail pointers to indicate ring is empty */
- SRNG_DST_REG_WRITE(srng, HP, idx * srng->entry_size);
- SRNG_DST_REG_WRITE(srng, TP, idx * srng->entry_size);
- *srng->u.dst_ring.hp_addr = idx * srng->entry_size;
- srng->u.dst_ring.tp = idx * srng->entry_size;
- reg_val = ((srng->flags & HAL_SRNG_DATA_TLV_SWAP) ?
- SRNG_SM(SRNG_DST_FLD(MISC, DATA_TLV_SWAP_BIT), 1) : 0) |
- ((srng->flags & HAL_SRNG_RING_PTR_SWAP) ?
- SRNG_SM(SRNG_DST_FLD(MISC, HOST_FW_SWAP_BIT), 1) : 0) |
- ((srng->flags & HAL_SRNG_MSI_SWAP) ?
- SRNG_SM(SRNG_DST_FLD(MISC, MSI_SWAP_BIT), 1) : 0);
- /*
- * reg_val |= SRNG_SM(SRNG_SRC_FLD(MISC, SRNG_ENABLE), 1);
- * todo: update fw_api and replace with above line
- * (when SRNG_ENABLE field for the MISC register is available in fw_api)
- * (WCSS_UMAC_CE_0_SRC_WFSS_CE_CHANNEL_SRC_R0_SRC_RING_MISC)
- */
- reg_val |= SRNG_ENABLE_BIT;
- SRNG_DST_REG_WRITE(srng, MISC, reg_val);
- }
- /**
- * hal_srng_hw_reg_offset_init_generic() - Initialize the HW srng reg offset
- * @hal_soc: HAL Soc handle
- *
- * Return: None
- */
- static inline void hal_srng_hw_reg_offset_init_generic(struct hal_soc *hal_soc)
- {
- int32_t *hw_reg_offset = hal_soc->hal_hw_reg_offset;
- /* dst */
- hw_reg_offset[DST_HP] = REG_OFFSET(DST, HP);
- hw_reg_offset[DST_TP] = REG_OFFSET(DST, TP);
- hw_reg_offset[DST_ID] = REG_OFFSET(DST, ID);
- hw_reg_offset[DST_MISC] = REG_OFFSET(DST, MISC);
- hw_reg_offset[DST_HP_ADDR_LSB] = REG_OFFSET(DST, HP_ADDR_LSB);
- hw_reg_offset[DST_HP_ADDR_MSB] = REG_OFFSET(DST, HP_ADDR_MSB);
- hw_reg_offset[DST_MSI1_BASE_LSB] = REG_OFFSET(DST, MSI1_BASE_LSB);
- hw_reg_offset[DST_MSI1_BASE_MSB] = REG_OFFSET(DST, MSI1_BASE_MSB);
- hw_reg_offset[DST_MSI1_DATA] = REG_OFFSET(DST, MSI1_DATA);
- hw_reg_offset[DST_BASE_LSB] = REG_OFFSET(DST, BASE_LSB);
- hw_reg_offset[DST_BASE_MSB] = REG_OFFSET(DST, BASE_MSB);
- hw_reg_offset[DST_PRODUCER_INT_SETUP] =
- REG_OFFSET(DST, PRODUCER_INT_SETUP);
- /* src */
- hw_reg_offset[SRC_HP] = REG_OFFSET(SRC, HP);
- hw_reg_offset[SRC_TP] = REG_OFFSET(SRC, TP);
- hw_reg_offset[SRC_ID] = REG_OFFSET(SRC, ID);
- hw_reg_offset[SRC_MISC] = REG_OFFSET(SRC, MISC);
- hw_reg_offset[SRC_TP_ADDR_LSB] = REG_OFFSET(SRC, TP_ADDR_LSB);
- hw_reg_offset[SRC_TP_ADDR_MSB] = REG_OFFSET(SRC, TP_ADDR_MSB);
- hw_reg_offset[SRC_MSI1_BASE_LSB] = REG_OFFSET(SRC, MSI1_BASE_LSB);
- hw_reg_offset[SRC_MSI1_BASE_MSB] = REG_OFFSET(SRC, MSI1_BASE_MSB);
- hw_reg_offset[SRC_MSI1_DATA] = REG_OFFSET(SRC, MSI1_DATA);
- hw_reg_offset[SRC_BASE_LSB] = REG_OFFSET(SRC, BASE_LSB);
- hw_reg_offset[SRC_BASE_MSB] = REG_OFFSET(SRC, BASE_MSB);
- hw_reg_offset[SRC_CONSUMER_INT_SETUP_IX0] =
- REG_OFFSET(SRC, CONSUMER_INT_SETUP_IX0);
- hw_reg_offset[SRC_CONSUMER_INT_SETUP_IX1] =
- REG_OFFSET(SRC, CONSUMER_INT_SETUP_IX1);
- #ifdef DP_UMAC_HW_RESET_SUPPORT
- hw_reg_offset[SRC_CONSUMER_PREFETCH_TIMER] =
- REG_OFFSET(SRC, CONSUMER_PREFETCH_TIMER);
- #endif
- }
- #else
- static inline
- void hal_srng_src_hw_init_generic(struct hal_soc *hal,
- struct hal_srng *srng, bool idle_check,
- uint32_t idx) {}
- static inline
- void hal_srng_dst_hw_init_generic(struct hal_soc *hal,
- struct hal_srng *srng, bool idle_check,
- uint32_t idx) {}
- #endif
- #ifdef FEATURE_DIRECT_LINK
- /**
- * hal_srng_set_msi_config() - Set the MSI config and enable the SRNG
- * @ring_hdl: srng handle
- * @params: ring parameters
- *
- * Return: QDF status
- */
- static inline
- QDF_STATUS hal_srng_set_msi_config(hal_ring_handle_t ring_hdl,
- void *params)
- {
- struct hal_srng *srng = (struct hal_srng *)ring_hdl;
- struct hal_srng_params *ring_params = (struct hal_srng_params *)params;
- uint32_t reg_val;
- srng->intr_timer_thres_us = ring_params->intr_timer_thres_us;
- srng->intr_batch_cntr_thres_entries =
- ring_params->intr_batch_cntr_thres_entries;
- srng->msi_addr = ring_params->msi_addr;
- srng->msi_data = ring_params->msi_data;
- if (!srng->msi_addr && !srng->msi_data) {
- if (srng->ring_dir == HAL_SRNG_SRC_RING)
- SRNG_SRC_REG_WRITE(srng, MSI1_BASE_MSB, 0);
- else
- SRNG_DST_REG_WRITE(srng, MSI1_BASE_MSB, 0);
- return QDF_STATUS_SUCCESS;
- }
- if (srng->ring_dir == HAL_SRNG_SRC_RING) {
- reg_val = 0;
- SRNG_SRC_REG_WRITE(srng, MSI1_BASE_LSB,
- srng->msi_addr & 0xffffffff);
- reg_val = SRNG_SM(SRNG_SRC_FLD(MSI1_BASE_MSB, ADDR),
- (uint64_t)(srng->msi_addr) >> 32) |
- SRNG_SM(SRNG_SRC_FLD(MSI1_BASE_MSB,
- MSI1_ENABLE), 1);
- SRNG_SRC_REG_WRITE(srng, MSI1_BASE_MSB, reg_val);
- SRNG_SRC_REG_WRITE(srng, MSI1_DATA,
- qdf_cpu_to_le32(srng->msi_data));
- reg_val = 0;
- if (srng->intr_timer_thres_us) {
- reg_val |= SRNG_SM(SRNG_SRC_FLD(CONSUMER_INT_SETUP_IX0,
- INTERRUPT_TIMER_THRESHOLD),
- srng->intr_timer_thres_us);
- }
- if (srng->intr_batch_cntr_thres_entries) {
- reg_val |= SRNG_SM(SRNG_SRC_FLD(CONSUMER_INT_SETUP_IX0,
- BATCH_COUNTER_THRESHOLD),
- srng->intr_batch_cntr_thres_entries *
- srng->entry_size);
- }
- SRNG_SRC_REG_WRITE(srng, CONSUMER_INT_SETUP_IX0, reg_val);
- } else {
- reg_val = 0;
- SRNG_DST_REG_WRITE(srng, MSI1_BASE_LSB,
- srng->msi_addr & 0xffffffff);
- reg_val = SRNG_SM(SRNG_DST_FLD(MSI1_BASE_MSB, ADDR),
- (uint64_t)(srng->msi_addr) >> 32) |
- SRNG_SM(SRNG_DST_FLD(MSI1_BASE_MSB,
- MSI1_ENABLE), 1);
- SRNG_DST_REG_WRITE(srng, MSI1_BASE_MSB, reg_val);
- SRNG_DST_REG_WRITE(srng, MSI1_DATA,
- qdf_cpu_to_le32(srng->msi_data));
- reg_val = 0;
- if (srng->intr_timer_thres_us) {
- reg_val |= SRNG_SM(SRNG_DST_FLD(PRODUCER_INT_SETUP,
- INTERRUPT_TIMER_THRESHOLD),
- srng->intr_timer_thres_us >> 3);
- }
- if (srng->intr_batch_cntr_thres_entries) {
- reg_val |= SRNG_SM(SRNG_DST_FLD(PRODUCER_INT_SETUP,
- BATCH_COUNTER_THRESHOLD),
- srng->intr_batch_cntr_thres_entries *
- srng->entry_size);
- }
- SRNG_DST_REG_WRITE(srng, PRODUCER_INT_SETUP, reg_val);
- }
- return QDF_STATUS_SUCCESS;
- }
- #else
- static inline
- QDF_STATUS hal_srng_set_msi_config(hal_ring_handle_t ring_hdl,
- void *params)
- {
- return QDF_STATUS_E_NOSUPPORT;
- }
- #endif
- #endif /* HAL_GENERIC_API_H_ */
|