diff --git a/hal/wifi3.0/hal_api.h b/hal/wifi3.0/hal_api.h index 1cda41320e..98f11383ca 100644 --- a/hal/wifi3.0/hal_api.h +++ b/hal/wifi3.0/hal_api.h @@ -3387,4 +3387,33 @@ uint16_t hal_srng_dst_get_hpidx(hal_ring_handle_t hal_ring_hdl) return hp / srng->entry_size; } + +#ifdef FEATURE_DIRECT_LINK +/** + * hal_srng_set_msi_irq_config() - Set the MSI irq configuration for srng + * @hal_soc_hdl: hal soc handle + * @hal_ring_hdl: srng handle + * @addr: MSI address + * @data: MSI data + * + * Return: QDF status + */ +static inline QDF_STATUS +hal_srng_set_msi_irq_config(hal_soc_handle_t hal_soc_hdl, + hal_ring_handle_t hal_ring_hdl, + struct hal_srng_params *ring_params) +{ + struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl; + + return hal_soc->ops->hal_srng_set_msi_config(hal_ring_hdl, ring_params); +} +#else +static inline QDF_STATUS +hal_srng_set_msi_irq_config(hal_soc_handle_t hal_soc_hdl, + hal_ring_handle_t hal_ring_hdl, + struct hal_srng_params *ring_params) +{ + return QDF_STATUS_E_NOSUPPORT; +} +#endif #endif /* _HAL_APIH_ */ diff --git a/hal/wifi3.0/hal_generic_api.h b/hal/wifi3.0/hal_generic_api.h index 8dea3921a6..93a6c5320b 100644 --- a/hal/wifi3.0/hal_generic_api.h +++ b/hal/wifi3.0/hal_generic_api.h @@ -571,4 +571,95 @@ static inline void hal_srng_hw_reg_offset_init_generic(struct hal_soc *hal_soc) #endif } +#ifdef FEATURE_DIRECT_LINK +/** + * hal_srng_set_msi_config() - Set the MSI config and enable the SRNG + * @hal_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->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_ */ diff --git a/hal/wifi3.0/hal_internal.h b/hal/wifi3.0/hal_internal.h index fba8d52f20..a040887a64 100644 --- a/hal/wifi3.0/hal_internal.h +++ b/hal/wifi3.0/hal_internal.h @@ -1213,6 +1213,10 @@ struct hal_hw_txrx_ops { uint8_t mac_id, uint64_t *value); void (*hal_get_tqm_scratch_reg)(hal_soc_handle_t hal_soc_hdl, uint64_t *value); +#ifdef FEATURE_DIRECT_LINK + QDF_STATUS (*hal_srng_set_msi_config)(hal_ring_handle_t ring_hdl, + void *ring_params); +#endif }; /** diff --git a/hal/wifi3.0/kiwi/hal_kiwi.c b/hal/wifi3.0/kiwi/hal_kiwi.c index 35af63478e..6318758b22 100644 --- a/hal/wifi3.0/kiwi/hal_kiwi.c +++ b/hal/wifi3.0/kiwi/hal_kiwi.c @@ -2303,6 +2303,9 @@ static void hal_hw_txrx_ops_attach_kiwi(struct hal_soc *hal_soc) hal_soc->ops->hal_get_tsf_time = hal_get_tsf_time_kiwi; hal_soc->ops->hal_rx_reo_ent_get_src_link_id = hal_rx_reo_ent_get_src_link_id_kiwi; +#ifdef FEATURE_DIRECT_LINK + hal_soc->ops->hal_srng_set_msi_config = hal_srng_set_msi_config; +#endif }; struct hal_hw_srng_config hw_srng_table_kiwi[] = { diff --git a/hif/inc/hif.h b/hif/inc/hif.h index ec7c4cbb6d..2b1f19dad8 100644 --- a/hif/inc/hif.h +++ b/hif/inc/hif.h @@ -2437,4 +2437,25 @@ QDF_STATUS hif_unregister_umac_reset_handler(struct hif_opaque_softc *hif_scn) #endif /* DP_UMAC_HW_RESET_SUPPORT */ +#ifdef FEATURE_DIRECT_LINK +/** + * hif_set_irq_config_by_ceid() - Set irq configuration for CE given by id + * @scn: hif opaque handle + * @ce_id: CE id + * @addr: irq trigger address + * @data: irq trigger data + * + * Return: QDF status + */ +QDF_STATUS +hif_set_irq_config_by_ceid(struct hif_opaque_softc *scn, uint8_t ce_id, + uint64_t addr, uint32_t data); +#else +static inline QDF_STATUS +hif_set_irq_config_by_ceid(struct hif_opaque_softc *scn, uint8_t ce_id, + uint64_t addr, uint32_t data) +{ + return QDF_STATUS_SUCCESS; +} +#endif #endif /* _HIF_H_ */ diff --git a/hif/src/ce/ce_api.h b/hif/src/ce/ce_api.h index a73b69c19f..a85f88080b 100644 --- a/hif/src/ce/ce_api.h +++ b/hif/src/ce/ce_api.h @@ -597,6 +597,11 @@ struct ce_ops { struct pld_shadow_reg_v3_cfg **shadow_config, int *num_shadow_registers_configured); #endif +#ifdef FEATURE_DIRECT_LINK + QDF_STATUS (*ce_set_irq_config_by_ceid)(struct hif_softc *scn, + uint8_t ce_id, uint64_t addr, + uint32_t data); +#endif }; int hif_ce_bus_early_suspend(struct hif_softc *scn); diff --git a/hif/src/ce/ce_assignment.h b/hif/src/ce/ce_assignment.h index 8632ca024b..4f78074313 100644 --- a/hif/src/ce/ce_assignment.h +++ b/hif/src/ce/ce_assignment.h @@ -1573,8 +1573,9 @@ static struct CE_pipe_config target_ce_config_wlan_qca6750[] = { #define KIWI_CE_COUNT 9 static struct CE_attr host_ce_config_wlan_kiwi[] = { /* host->target HTC control and raw streams */ -#ifdef FEATURE_XPAN - { /* CE0 */ CE_ATTR_FLAGS, 0, 8, 2048, 0, NULL,}, +#ifdef FEATURE_DIRECT_LINK + { /* CE0 */ (CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR), 0, 8, 2048, 0, + NULL,}, #else { /* CE0 */ CE_ATTR_FLAGS, 0, 16, 2048, 0, NULL,}, #endif @@ -1591,8 +1592,9 @@ static struct CE_attr host_ce_config_wlan_kiwi[] = { /* target -> host PKTLOG */ { /* CE5 */ CE_ATTR_FLAGS, 0, 0, 2048, 512, NULL,}, #else -#ifdef FEATURE_XPAN - { /* CE5 */ CE_ATTR_FLAGS, 0, 0, 256, 32, NULL,}, +#ifdef FEATURE_DIRECT_LINK + { /* CE5 */ (CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR), 0, 0, 256, 32, + NULL,}, #else { /* CE5 */ CE_ATTR_FLAGS, 0, 0, 2048, 0, NULL,}, #endif @@ -1632,7 +1634,7 @@ static struct CE_pipe_config target_ce_config_wlan_kiwi[] = { /* Target -> host PKTLOG */ { /* CE5 */ 5, PIPEDIR_IN, 32, 2048, CE_ATTR_FLAGS, 0,}, #else -#ifdef FEATURE_XPAN +#ifdef FEATURE_DIRECT_LINK { /* CE5 */ 5, PIPEDIR_IN, 16, 256, CE_ATTR_FLAGS, 0,}, #else { /* CE5 */ 5, PIPEDIR_IN, 0, 2048, CE_ATTR_FLAGS, 0,}, diff --git a/hif/src/ce/ce_main.c b/hif/src/ce/ce_main.c index 3126d81f1c..4f3dff1ac4 100644 --- a/hif/src/ce/ce_main.c +++ b/hif/src/ce/ce_main.c @@ -1133,7 +1133,7 @@ static struct service_to_pipe target_service_to_ce_map_kiwi[] = { { WMI_DATA_VI_SVC, PIPEDIR_IN, 2, }, { WMI_CONTROL_SVC, PIPEDIR_OUT, 3, }, { WMI_CONTROL_SVC, PIPEDIR_IN, 2, }, -#ifdef FEATURE_XPAN +#ifdef FEATURE_DIRECT_LINK { HTC_CTRL_RSVD_SVC, PIPEDIR_OUT, 4, }, #else { HTC_CTRL_RSVD_SVC, PIPEDIR_OUT, 0, }, @@ -1144,7 +1144,7 @@ static struct service_to_pipe target_service_to_ce_map_kiwi[] = { #ifdef WLAN_FEATURE_WMI_DIAG_OVER_CE7 { WMI_CONTROL_DIAG_SVC, PIPEDIR_IN, 7, }, #endif -#ifdef FEATURE_XPAN +#ifdef FEATURE_DIRECT_LINK { LPASS_DATA_MSG_SVC, PIPEDIR_OUT, 0, }, { LPASS_DATA_MSG_SVC, PIPEDIR_IN, 5, }, #endif @@ -5304,4 +5304,23 @@ void hif_log_ce_info(struct hif_softc *scn, uint8_t *data, qdf_mem_copy(data + *offset, &info, size); *offset = *offset + size; } + +#ifdef FEATURE_DIRECT_LINK +QDF_STATUS +hif_set_irq_config_by_ceid(struct hif_opaque_softc *scn, uint8_t ce_id, + uint64_t addr, uint32_t data) +{ + struct hif_softc *hif_ctx = HIF_GET_SOFTC(scn); + struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn); + + if (hif_state->ce_services->ce_set_irq_config_by_ceid) + return hif_state->ce_services->ce_set_irq_config_by_ceid( + hif_ctx, + ce_id, + addr, + data); + + return QDF_STATUS_E_NOSUPPORT; +} +#endif #endif diff --git a/hif/src/ce/ce_service_srng.c b/hif/src/ce/ce_service_srng.c index 0e9d03f78b..514712f432 100644 --- a/hif/src/ce/ce_service_srng.c +++ b/hif/src/ce/ce_service_srng.c @@ -1097,6 +1097,64 @@ int ce_get_index_info_srng(struct hif_softc *scn, void *ce_state, } #endif +#ifdef FEATURE_DIRECT_LINK +/** + * ce_set_srng_msi_irq_config_by_ceid(): Set srng MSI irq configuration for CE + * given by id + * @scn: HIF Context + * @ce_state: CE opaque handle + * @info: CE info + * + * Return: 0 for success and non zero for failure + */ +static QDF_STATUS +ce_set_srng_msi_irq_config_by_ceid(struct hif_softc *scn, uint8_t ce_id, + uint64_t addr, uint32_t data) +{ + struct CE_state *ce_state; + hal_ring_handle_t ring_hdl; + struct hal_srng_params ring_params = {0}; + + ce_state = scn->ce_id_to_state[ce_id]; + if (!ce_state) + return QDF_STATUS_E_NOSUPPORT; + + ring_params.msi_addr = addr; + ring_params.msi_data = data; + + if (ce_state->src_ring) { + ring_hdl = ce_state->src_ring->srng_ctx; + + ring_params.intr_timer_thres_us = 0; + ring_params.intr_batch_cntr_thres_entries = 1; + ring_params.prefetch_timer = HAL_SRNG_PREFETCH_TIMER; + } else if (ce_state->dest_ring) { + ring_hdl = ce_state->status_ring->srng_ctx; + + ce_status_ring_config_int_threshold(scn, &ring_params); + + hal_srng_set_msi_irq_config(scn->hal_soc, ring_hdl, + &ring_params); + + if (ce_is_status_ring_timer_thresh_war_needed()) { + ce_srng_initialize_dest_timer_interrupt_war( + ce_state->dest_ring, &ring_params); + } else { + ce_srng_initialize_dest_ring_thresh(ce_state->dest_ring, + &ring_params); + } + ring_params.prefetch_timer = HAL_SRNG_PREFETCH_TIMER; + ring_hdl = ce_state->dest_ring->srng_ctx; + } else { + return QDF_STATUS_E_FAILURE; + } + + hal_srng_set_msi_irq_config(scn->hal_soc, ring_hdl, &ring_params); + + return QDF_STATUS_SUCCESS; +} +#endif + static struct ce_ops ce_service_srng = { .ce_get_desc_size = ce_get_desc_size_srng, .ce_ring_setup = ce_ring_setup_srng, @@ -1122,6 +1180,9 @@ static struct ce_ops ce_service_srng = { .ce_get_index_info = ce_get_index_info_srng, #endif +#ifdef FEATURE_DIRECT_LINK + .ce_set_irq_config_by_ceid = ce_set_srng_msi_irq_config_by_ceid, +#endif }; struct ce_ops *ce_services_srng()