diff --git a/hal/wifi3.0/hal_api.h b/hal/wifi3.0/hal_api.h index 4dee3827fc..ab7e1ad0b8 100644 --- a/hal/wifi3.0/hal_api.h +++ b/hal/wifi3.0/hal_api.h @@ -178,6 +178,12 @@ static inline void hal_select_window(struct hal_soc *hal_soc, uint32_t offset, } #endif +static inline qdf_iomem_t hal_get_window_address(struct hal_soc *hal_soc, + qdf_iomem_t addr) +{ + return hal_soc->ops->hal_get_window_address(hal_soc, addr); +} + /** * hal_write32_mb() - Access registers to update configuration * @hal_soc: hal soc handle @@ -209,12 +215,17 @@ static inline void hal_write32_mb(struct hal_soc *hal_soc, uint32_t offset, uint32_t value, bool ret_confirm) { unsigned long flags; + qdf_iomem_t new_addr; if (!hal_soc->use_register_windowing || offset < MAX_UNWINDOWED_ADDRESS) { qdf_iowrite32(hal_soc->dev_base_addr + offset, value); hal_reg_write_result_check(hal_soc, offset, value, ret_confirm); + } else if (hal_soc->static_window_map) { + new_addr = hal_get_window_address(hal_soc, + hal_soc->dev_base_addr + offset); + qdf_iowrite32(new_addr, value); } else { hal_lock_reg_access(hal_soc, &flags); hal_select_window(hal_soc, offset, ret_confirm); @@ -228,6 +239,28 @@ static inline void hal_write32_mb(struct hal_soc *hal_soc, uint32_t offset, hal_unlock_reg_access(hal_soc, &flags); } } + +/** + * hal_write_address_32_mb - write a value to a register + * + */ +static inline +void hal_write_address_32_mb(struct hal_soc *hal_soc, + qdf_iomem_t addr, uint32_t value) +{ + uint32_t offset; + qdf_iomem_t new_addr; + + if (!hal_soc->use_register_windowing) + return qdf_iowrite32(addr, value); + + offset = addr - hal_soc->dev_base_addr; + if (hal_soc->static_window_map) { + new_addr = hal_get_window_address(hal_soc, addr); + return qdf_iowrite32(new_addr, value); + } + hal_write32_mb(hal_soc, offset, value, false); +} #else static inline void hal_write32_mb(struct hal_soc *hal_soc, uint32_t offset, uint32_t value, bool ret_confirm) @@ -279,7 +312,6 @@ static inline void hal_write32_mb(struct hal_soc *hal_soc, uint32_t offset, } } } -#endif /** * hal_write_address_32_mb - write a value to a register @@ -287,7 +319,7 @@ static inline void hal_write32_mb(struct hal_soc *hal_soc, uint32_t offset, */ static inline void hal_write_address_32_mb(struct hal_soc *hal_soc, - void __iomem *addr, uint32_t value) + qdf_iomem_t addr, uint32_t value) { uint32_t offset; @@ -297,6 +329,14 @@ void hal_write_address_32_mb(struct hal_soc *hal_soc, offset = addr - hal_soc->dev_base_addr; hal_write32_mb(hal_soc, offset, value, false); } +#endif + +#ifdef DP_HAL_MULTIWINDOW_DIRECT_ACCESS +#define hal_srng_write_address_32_mb(_a, _b, _c) qdf_iowrite32(_b, _c) +#else +#define hal_srng_write_address_32_mb(_a, _b, _c) \ + hal_write_address_32_mb(_a, _b, _c) +#endif #if !defined(QCA_WIFI_QCA6390) && !defined(QCA_WIFI_QCA6490) /** @@ -325,10 +365,14 @@ uint32_t hal_read32_mb(struct hal_soc *hal_soc, uint32_t offset) { uint32_t ret; unsigned long flags; + qdf_iomem_t new_addr; if (!hal_soc->use_register_windowing || offset < MAX_UNWINDOWED_ADDRESS) { return qdf_ioread32(hal_soc->dev_base_addr + offset); + } else if (hal_soc->static_window_map) { + new_addr = hal_get_window_address(hal_soc, hal_soc->dev_base_addr + offset); + return qdf_ioread32(new_addr); } hal_lock_reg_access(hal_soc, &flags); @@ -388,15 +432,21 @@ uint32_t hal_read32_mb(struct hal_soc *hal_soc, uint32_t offset) */ static inline uint32_t hal_read_address_32_mb(struct hal_soc *soc, - void __iomem *addr) + qdf_iomem_t addr) { uint32_t offset; uint32_t ret; + qdf_iomem_t new_addr; if (!soc->use_register_windowing) return qdf_ioread32(addr); offset = addr - soc->dev_base_addr; + if (soc->static_window_map) { + new_addr = hal_get_window_address(soc, addr); + return qdf_ioread32(new_addr); + } + ret = hal_read32_mb(soc, offset); return ret; } @@ -1267,13 +1317,13 @@ hal_srng_access_end_unlocked(void *hal_soc, hal_ring_handle_t hal_ring_hdl) } } else { if (srng->ring_dir == HAL_SRNG_SRC_RING) - hal_write_address_32_mb(hal_soc, - srng->u.src_ring.hp_addr, - srng->u.src_ring.hp); + hal_srng_write_address_32_mb(hal_soc, + srng->u.src_ring.hp_addr, + srng->u.src_ring.hp); else - hal_write_address_32_mb(hal_soc, - srng->u.dst_ring.tp_addr, - srng->u.dst_ring.tp); + hal_srng_write_address_32_mb(hal_soc, + srng->u.dst_ring.tp_addr, + srng->u.dst_ring.tp); } } diff --git a/hal/wifi3.0/hal_internal.h b/hal/wifi3.0/hal_internal.h index 76f4c08233..c2773ff7c0 100644 --- a/hal/wifi3.0/hal_internal.h +++ b/hal/wifi3.0/hal_internal.h @@ -353,6 +353,8 @@ struct hal_hw_txrx_ops { uint32_t scatter_buf_size, uint32_t last_buf_end_offset, uint32_t num_entries); + qdf_iomem_t (*hal_get_window_address)(struct hal_soc *hal_soc, + qdf_iomem_t addr); /* tx */ void (*hal_tx_desc_set_dscp_tid_table_id)(void *desc, uint8_t id); @@ -498,6 +500,9 @@ struct hal_soc { uint32_t register_window; qdf_spinlock_t register_access_lock; + /* Static window map configuration for multiple window write*/ + bool static_window_map; + /* srng table */ struct hal_hw_srng_config *hw_srng_table; int32_t *hal_hw_reg_offset; diff --git a/hal/wifi3.0/hal_srng.c b/hal/wifi3.0/hal_srng.c index 30836e5fa4..be215f20ac 100644 --- a/hal/wifi3.0/hal_srng.c +++ b/hal/wifi3.0/hal_srng.c @@ -273,6 +273,11 @@ static void hal_target_based_configure(struct hal_soc *hal) #ifdef QCA_WIFI_QCN9000 case TARGET_TYPE_QCN9000: hal->use_register_windowing = true; + /* + * Static window map is enabled for qcn9000 to use 2mb bar + * size and use multiple windows to write into registers. + */ + hal->static_window_map = true; hal_qcn9000_attach(hal); break; #endif @@ -676,7 +681,9 @@ void *hal_srng_setup(void *hal_soc, int ring_type, int ring_num, HAL_SRNG_LMAC1_ID_START]); srng->flags |= HAL_SRNG_LMAC_RING; } else if (ignore_shadow || (srng->u.src_ring.hp_addr == 0)) { - srng->u.src_ring.hp_addr = SRNG_SRC_ADDR(srng, HP); + srng->u.src_ring.hp_addr = + hal_get_window_address(hal, + SRNG_SRC_ADDR(srng, HP)); if (CHECK_SHADOW_REGISTERS) { QDF_TRACE(QDF_MODULE_ID_TXRX, @@ -711,7 +718,9 @@ void *hal_srng_setup(void *hal_soc, int ring_type, int ring_num, HAL_SRNG_LMAC1_ID_START]); srng->flags |= HAL_SRNG_LMAC_RING; } else if (ignore_shadow || srng->u.dst_ring.tp_addr == 0) { - srng->u.dst_ring.tp_addr = SRNG_DST_ADDR(srng, TP); + srng->u.dst_ring.tp_addr = + hal_get_window_address(hal, + SRNG_DST_ADDR(srng, TP)); if (CHECK_SHADOW_REGISTERS) { QDF_TRACE(QDF_MODULE_ID_TXRX, diff --git a/hal/wifi3.0/qca6290/hal_6290.c b/hal/wifi3.0/qca6290/hal_6290.c index 024bcb869c..a848e15e53 100644 --- a/hal/wifi3.0/qca6290/hal_6290.c +++ b/hal/wifi3.0/qca6290/hal_6290.c @@ -977,6 +977,19 @@ uint16_t hal_rx_get_rx_sequence_6290(uint8_t *buf) return HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info); } +/** + * hal_get_window_address_6290(): Function to get hp/tp address + * @hal_soc: Pointer to hal_soc + * @addr: address offset of register + * + * Return: modified address offset of register + */ +static inline qdf_iomem_t hal_get_window_address_6290(struct hal_soc *hal_soc, + qdf_iomem_t addr) +{ + return addr; +} + struct hal_hw_txrx_ops qca6290_hal_hw_txrx_ops = { /* init and setup */ hal_srng_dst_hw_init_generic, @@ -984,6 +997,7 @@ struct hal_hw_txrx_ops qca6290_hal_hw_txrx_ops = { hal_get_hw_hptp_generic, hal_reo_setup_generic, hal_setup_link_idle_list_generic, + hal_get_window_address_6290, /* tx */ hal_tx_desc_set_dscp_tid_table_id_6290, diff --git a/hal/wifi3.0/qca6390/hal_6390.c b/hal/wifi3.0/qca6390/hal_6390.c index 9b747bdb4b..56e7f3d34e 100644 --- a/hal/wifi3.0/qca6390/hal_6390.c +++ b/hal/wifi3.0/qca6390/hal_6390.c @@ -973,6 +973,19 @@ uint16_t hal_rx_get_rx_sequence_6390(uint8_t *buf) return HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info); } +/** + * hal_get_window_address_6390(): Function to get hp/tp address + * @hal_soc: Pointer to hal_soc + * @addr: address offset of register + * + * Return: modified address offset of register + */ +static inline qdf_iomem_t hal_get_window_address_6390(struct hal_soc *hal_soc, + qdf_iomem_t addr) +{ + return addr; +} + struct hal_hw_txrx_ops qca6390_hal_hw_txrx_ops = { /* init and setup */ hal_srng_dst_hw_init_generic, @@ -980,6 +993,7 @@ struct hal_hw_txrx_ops qca6390_hal_hw_txrx_ops = { hal_get_hw_hptp_generic, hal_reo_setup_generic, hal_setup_link_idle_list_generic, + hal_get_window_address_6390, /* tx */ hal_tx_desc_set_dscp_tid_table_id_6390, diff --git a/hal/wifi3.0/qca6490/hal_6490.c b/hal/wifi3.0/qca6490/hal_6490.c index b06cb19274..7a349b0ff9 100644 --- a/hal/wifi3.0/qca6490/hal_6490.c +++ b/hal/wifi3.0/qca6490/hal_6490.c @@ -1291,6 +1291,19 @@ uint16_t hal_rx_get_rx_sequence_6490(uint8_t *buf) return HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info); } +/** + * hal_get_window_address_6490(): Function to get hp/tp address + * @hal_soc: Pointer to hal_soc + * @addr: address offset of register + * + * Return: modified address offset of register + */ +static inline qdf_iomem_t hal_get_window_address_6490(struct hal_soc *hal_soc, + qdf_iomem_t addr) +{ + return addr; +} + struct hal_hw_txrx_ops qca6490_hal_hw_txrx_ops = { /* init and setup */ hal_srng_dst_hw_init_generic, @@ -1298,6 +1311,7 @@ struct hal_hw_txrx_ops qca6490_hal_hw_txrx_ops = { hal_get_hw_hptp_generic, hal_reo_setup_generic, hal_setup_link_idle_list_generic, + hal_get_window_address_6490, /* tx */ hal_tx_desc_set_dscp_tid_table_id_6490, diff --git a/hal/wifi3.0/qca8074v1/hal_8074v1.c b/hal/wifi3.0/qca8074v1/hal_8074v1.c index a97473ff71..d758b1fd98 100644 --- a/hal/wifi3.0/qca8074v1/hal_8074v1.c +++ b/hal/wifi3.0/qca8074v1/hal_8074v1.c @@ -104,6 +104,18 @@ #include #include +/** + * hal_get_window_address_8074(): Function to get hp/tp address + * @hal_soc: Pointer to hal_soc + * @addr: address offset of register + * + * Return: modified address offset of register + */ +static inline qdf_iomem_t hal_get_window_address_8074(struct hal_soc *hal_soc, + qdf_iomem_t addr) +{ + return addr; +} /** * hal_rx_get_rx_fragment_number_8074v1(): Function to retrieve @@ -981,6 +993,7 @@ struct hal_hw_txrx_ops qca8074_hal_hw_txrx_ops = { hal_get_hw_hptp_generic, hal_reo_setup_generic, hal_setup_link_idle_list_generic, + hal_get_window_address_8074, /* tx */ hal_tx_desc_set_dscp_tid_table_id_8074, diff --git a/hal/wifi3.0/qca8074v2/hal_8074v2.c b/hal/wifi3.0/qca8074v2/hal_8074v2.c index f476cc7aa0..61f5cc7bbb 100644 --- a/hal/wifi3.0/qca8074v2/hal_8074v2.c +++ b/hal/wifi3.0/qca8074v2/hal_8074v2.c @@ -970,6 +970,19 @@ uint16_t hal_rx_get_rx_sequence_8074v2(uint8_t *buf) return HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info); } +/** + * hal_get_window_address_8074v2(): Function to get hp/tp address + * @hal_soc: Pointer to hal_soc + * @addr: address offset of register + * + * Return: modified address offset of register + */ +static inline qdf_iomem_t hal_get_window_address_8074v2(struct hal_soc *hal_soc, + qdf_iomem_t addr) +{ + return addr; +} + struct hal_hw_txrx_ops qca8074v2_hal_hw_txrx_ops = { /* init and setup */ @@ -978,6 +991,7 @@ struct hal_hw_txrx_ops qca8074v2_hal_hw_txrx_ops = { hal_get_hw_hptp_generic, hal_reo_setup_generic, hal_setup_link_idle_list_generic, + hal_get_window_address_8074v2, /* tx */ hal_tx_desc_set_dscp_tid_table_id_8074v2, diff --git a/hal/wifi3.0/qcn9000/hal_9000.c b/hal/wifi3.0/qcn9000/hal_9000.c index f9d2cebdd8..dcbd53e03a 100644 --- a/hal/wifi3.0/qcn9000/hal_9000.c +++ b/hal/wifi3.0/qcn9000/hal_9000.c @@ -101,6 +101,17 @@ #define UNIFIED_WBM_RELEASE_RING_6_TX_RATE_STATS_INFO_TX_RATE_STATS_LSB \ WBM_RELEASE_RING_6_TX_RATE_STATS_TSF_DIRECTLY_AFTER_PPDU_TRANSMISSION_LSB +#define CE_WINDOW_ADDRESS_9000 \ + ((CE_WFSS_CE_REG_BASE >> WINDOW_SHIFT) & WINDOW_VALUE_MASK) + +#define UMAC_WINDOW_ADDRESS_9000 \ + ((SEQ_WCSS_UMAC_OFFSET >> WINDOW_SHIFT) & WINDOW_VALUE_MASK) + +#define WINDOW_CONFIGURATION_VALUE_9000 \ + ((CE_WINDOW_ADDRESS_9000 << 6) |\ + (UMAC_WINDOW_ADDRESS_9000 << 12) | \ + WINDOW_ENABLE_BIT) + /* Including hkv2 files as the functions between hkv2 and pine are exactly * similar */ @@ -979,6 +990,49 @@ uint16_t hal_rx_get_rx_sequence_9000(uint8_t *buf) return HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info); } +/** + * hal_get_window_address_9000(): Function to get hp/tp address + * @hal_soc: Pointer to hal_soc + * @addr: address offset of register + * + * Return: modified address offset of register + */ +static inline qdf_iomem_t hal_get_window_address_9000(struct hal_soc *hal_soc, + qdf_iomem_t addr) +{ + uint32_t offset = addr - hal_soc->dev_base_addr; + qdf_iomem_t new_offset; + + /* + * If offset lies within DP register range, use 3rd window to write + * into DP region. + */ + if ((offset ^ SEQ_WCSS_UMAC_OFFSET) < WINDOW_RANGE_MASK) { + new_offset = (hal_soc->dev_base_addr + (3 * WINDOW_START) + + (offset & WINDOW_RANGE_MASK)); + /* + * If offset lies within CE register range, use 2nd window to write + * into CE region. + */ + } else if ((offset ^ CE_WFSS_CE_REG_BASE) < WINDOW_RANGE_MASK) { + new_offset = (hal_soc->dev_base_addr + (2 * WINDOW_START) + + (offset & WINDOW_RANGE_MASK)); + } else { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "%s: ERROR: Accessing Wrong register\n", __func__); + qdf_assert_always(0); + return 0; + } + return new_offset; +} + +static inline void hal_write_window_register(struct hal_soc *hal_soc) +{ + /* Write value into window configuration register */ + qdf_iowrite32(hal_soc->dev_base_addr + WINDOW_REG_ADDRESS, + WINDOW_CONFIGURATION_VALUE_9000); +} + struct hal_hw_txrx_ops qcn9000_hal_hw_txrx_ops = { /* init and setup */ @@ -987,6 +1041,7 @@ struct hal_hw_txrx_ops qcn9000_hal_hw_txrx_ops = { hal_get_hw_hptp_generic, hal_reo_setup_generic, hal_setup_link_idle_list_generic, + hal_get_window_address_9000, /* tx */ hal_tx_desc_set_dscp_tid_table_id_8074v2, @@ -1511,7 +1566,6 @@ int32_t hal_hw_reg_offset_qcn9000[] = { REG_OFFSET(SRC, CONSUMER_INT_SETUP_IX1), }; - /** * hal_qcn9000_attach()- Attach 9000 target specific hal_soc ops, * offset and srng table @@ -1522,4 +1576,6 @@ void hal_qcn9000_attach(struct hal_soc *hal_soc) hal_soc->hw_srng_table = hw_srng_table_9000; hal_soc->hal_hw_reg_offset = hal_hw_reg_offset_qcn9000; hal_soc->ops = &qcn9000_hal_hw_txrx_ops; + if (hal_soc->static_window_map) + hal_write_window_register(hal_soc); } diff --git a/qdf/inc/qdf_types.h b/qdf/inc/qdf_types.h index 1c5536ccd6..79ccbf203a 100644 --- a/qdf/inc/qdf_types.h +++ b/qdf/inc/qdf_types.h @@ -190,7 +190,7 @@ typedef struct qdf_shared_mem { qdf_dma_mem_context(memctx); } qdf_shared_mem_t; -#define qdf_iomem_t __qdf_iomem_t; +#define qdf_iomem_t __qdf_iomem_t /** * typedef enum QDF_TIMER_TYPE - QDF timer type diff --git a/qdf/linux/src/i_qdf_types.h b/qdf/linux/src/i_qdf_types.h index ac519dda5d..cb2a352a32 100644 --- a/qdf/linux/src/i_qdf_types.h +++ b/qdf/linux/src/i_qdf_types.h @@ -274,7 +274,7 @@ typedef struct __qdf_device *__qdf_device_t; typedef size_t __qdf_size_t; typedef off_t __qdf_off_t; -typedef uint8_t __iomem *__qdf_iomem_t; +typedef void __iomem* __qdf_iomem_t; typedef uint32_t ath_dma_addr_t;