diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 7252222261..3587d70798 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -1221,20 +1221,271 @@ static int dp_srng_find_ring_in_mask(int ring_num, uint8_t *grp_mask) return -QDF_STATUS_E_NOENT; } +/** + * dp_is_msi_group_number_invalid() - check msi_group_number valid or not + * @msi_group_number: MSI group number. + * @msi_data_count: MSI data count. + * + * Return: true if msi_group_number is invalid. + */ +#ifdef WLAN_ONE_MSI_VECTOR +static bool dp_is_msi_group_number_invalid(int msi_group_number, + int msi_data_count) +{ + return false; +} +#else +static bool dp_is_msi_group_number_invalid(int msi_group_number, + int msi_data_count) +{ + return msi_group_number > msi_data_count; +} +#endif + +#ifdef WLAN_FEATURE_NEAR_FULL_IRQ +/** + * dp_is_reo_ring_num_in_nf_grp1() - Check if the current reo ring is part of + * rx_near_full_grp1 mask + * @soc: Datapath SoC Handle + * @ring_num: REO ring number + * + * Return: 1 if the ring_num belongs to reo_nf_grp1, + * 0, otherwise. + */ +static inline int +dp_is_reo_ring_num_in_nf_grp1(struct dp_soc *soc, int ring_num) +{ + return (WLAN_CFG_RX_NEAR_FULL_IRQ_MASK_1 & (1 << ring_num)); +} + +/** + * dp_is_reo_ring_num_in_nf_grp2() - Check if the current reo ring is part of + * rx_near_full_grp2 mask + * @soc: Datapath SoC Handle + * @ring_num: REO ring number + * + * Return: 1 if the ring_num belongs to reo_nf_grp2, + * 0, otherwise. + */ +static inline int +dp_is_reo_ring_num_in_nf_grp2(struct dp_soc *soc, int ring_num) +{ + return (WLAN_CFG_RX_NEAR_FULL_IRQ_MASK_2 & (1 << ring_num)); +} + +/** + * dp_srng_get_near_full_irq_mask() - Get near-full irq mask for a particular + * ring type and number + * @soc: Datapath SoC handle + * @ring_type: SRNG type + * @ring_num: ring num + * + * Return: near ful irq mask pointer + */ +static inline +uint8_t *dp_srng_get_near_full_irq_mask(struct dp_soc *soc, + enum hal_ring_type ring_type, + int ring_num) +{ + uint8_t *nf_irq_mask = NULL; + + switch (ring_type) { + case WBM2SW_RELEASE: + if (ring_num < 3) { + nf_irq_mask = &soc->wlan_cfg_ctx-> + int_tx_ring_near_full_irq_mask[0]; + } + break; + case REO_DST: + if (dp_is_reo_ring_num_in_nf_grp1(soc, ring_num)) + nf_irq_mask = + &soc->wlan_cfg_ctx->int_rx_ring_near_full_irq_1_mask[0]; + else if (dp_is_reo_ring_num_in_nf_grp2(soc, ring_num)) + nf_irq_mask = + &soc->wlan_cfg_ctx->int_rx_ring_near_full_irq_2_mask[0]; + else + qdf_assert(0); + break; + default: + break; + } + + return nf_irq_mask; +} + +/** + * dp_srng_set_msi2_ring_params() - Set the msi2 addr/data in the ring params + * @soc: Datapath SoC handle + * @ring_params: srng params handle + * @msi2_addr: MSI2 addr to be set for the SRNG + * @msi2_data: MSI2 data to be set for the SRNG + * + * Return: None + */ +static inline +void dp_srng_set_msi2_ring_params(struct dp_soc *soc, + struct hal_srng_params *ring_params, + qdf_dma_addr_t msi2_addr, + uint32_t msi2_data) +{ + ring_params->msi2_addr = msi2_addr; + ring_params->msi2_data = msi2_data; +} + +/** + * dp_srng_msi2_setup() - Setup MSI2 details for near full IRQ of an SRNG + * @soc: Datapath SoC handle + * @ring_params: ring_params for SRNG + * @ring_type: SENG type + * @ring_num: ring number for the SRNG + * @nf_msi_grp_num: near full msi group number + * + * Return: None + */ +static inline void +dp_srng_msi2_setup(struct dp_soc *soc, + struct hal_srng_params *ring_params, + int ring_type, int ring_num, int nf_msi_grp_num) +{ + uint32_t msi_data_start, msi_irq_start, addr_low, addr_high; + int msi_data_count, ret; + + ret = pld_get_user_msi_assignment(soc->osdev->dev, "DP", + &msi_data_count, &msi_data_start, + &msi_irq_start); + if (ret) + return; + + if (nf_msi_grp_num < 0) { + dp_init_info("%pK: ring near full IRQ not part of an ext_group; ring_type: %d,ring_num %d", + soc, ring_type, ring_num); + ring_params->msi2_addr = 0; + ring_params->msi2_data = 0; + return; + } + + if (dp_is_msi_group_number_invalid(nf_msi_grp_num, msi_data_count)) { + dp_init_warn("%pK: 2 msi_groups will share an msi for near full IRQ; msi_group_num %d", + soc, nf_msi_grp_num); + QDF_ASSERT(0); + } + + pld_get_msi_address(soc->osdev->dev, &addr_low, &addr_high); + + ring_params->nf_irq_support = 1; + ring_params->msi2_addr = addr_low; + ring_params->msi2_addr |= (qdf_dma_addr_t)(((uint64_t)addr_high) << 32); + ring_params->msi2_data = (nf_msi_grp_num % msi_data_count) + + msi_data_start; + ring_params->flags |= HAL_SRNG_MSI_INTR; +} + +/* Percentage of ring entries considered as nearly full */ +#define DP_NF_HIGH_THRESH_PERCENTAGE 75 +/* Percentage of ring entries considered as critically full */ +#define DP_NF_CRIT_THRESH_PERCENTAGE 90 +/* Percentage of ring entries considered as safe threshold */ +#define DP_NF_SAFE_THRESH_PERCENTAGE 50 + +/** + * dp_srng_configure_nf_interrupt_thresholds() - Configure the thresholds for + * near full irq + * @soc: Datapath SoC handle + * @ring_params: ring params for SRNG + * @ring_type: ring type + */ +static inline void +dp_srng_configure_nf_interrupt_thresholds(struct dp_soc *soc, + struct hal_srng_params *ring_params, + int ring_type) +{ + if (ring_params->nf_irq_support) { + ring_params->high_thresh = (ring_params->num_entries * + DP_NF_HIGH_THRESH_PERCENTAGE) / 100; + ring_params->crit_thresh = (ring_params->num_entries * + DP_NF_CRIT_THRESH_PERCENTAGE) / 100; + ring_params->safe_thresh = (ring_params->num_entries * + DP_NF_SAFE_THRESH_PERCENTAGE) /100; + } +} + +/** + * dp_srng_set_nf_thresholds() - Set the near full thresholds to srng data + * structure from the ring params + * @soc: Datapath SoC handle + * @srng: SRNG handle + * @ring_params: ring params for a SRNG + * + * Return: None + */ +static inline void +dp_srng_set_nf_thresholds(struct dp_soc *soc, struct dp_srng *srng, + struct hal_srng_params *ring_params) +{ + srng->crit_thresh = ring_params->crit_thresh; + srng->safe_thresh = ring_params->safe_thresh; +} + +#else +static inline +uint8_t *dp_srng_get_near_full_irq_mask(struct dp_soc *soc, + enum hal_ring_type ring_type, + int ring_num) +{ + return NULL; +} + +static inline +void dp_srng_set_msi2_ring_params(struct dp_soc *soc, + struct hal_srng_params *ring_params, + qdf_dma_addr_t msi2_addr, + uint32_t msi2_data) +{ +} + +static inline void +dp_srng_msi2_setup(struct dp_soc *soc, + struct hal_srng_params *ring_params, + int ring_type, int ring_num, int nf_msi_grp_num) +{ +} + +static inline void +dp_srng_configure_nf_interrupt_thresholds(struct dp_soc *soc, + struct hal_srng_params *ring_params, + int ring_type) +{ +} + +static inline void +dp_srng_set_nf_thresholds(struct dp_soc *soc, struct dp_srng *srng, + struct hal_srng_params *ring_params) +{ +} +#endif + static int dp_srng_calculate_msi_group(struct dp_soc *soc, enum hal_ring_type ring_type, - int ring_num) + int ring_num, + int *reg_msi_grp_num, + bool nf_irq_support, + int *nf_msi_grp_num) { - uint8_t *grp_mask; + uint8_t *grp_mask, *nf_irq_mask = NULL; + bool nf_irq_enabled = false; switch (ring_type) { case WBM2SW_RELEASE: /* dp_tx_comp_handler - soc->tx_comp_ring */ - if (ring_num < 3) + if (ring_num < 3) { grp_mask = &soc->wlan_cfg_ctx->int_tx_ring_mask[0]; - + nf_irq_mask = dp_srng_get_near_full_irq_mask(soc, + ring_type, + ring_num); + if (nf_irq_mask) + nf_irq_enabled = true; /* dp_rx_wbm_err_process - soc->rx_rel_ring */ - else if (ring_num == 3) { + } else if (ring_num == 3) { /* sw treats this as a separate ring type */ grp_mask = &soc->wlan_cfg_ctx-> int_rx_wbm_rel_ring_mask[0]; @@ -1253,6 +1504,10 @@ static int dp_srng_calculate_msi_group(struct dp_soc *soc, case REO_DST: /* dp_rx_process - soc->reo_dest_ring */ grp_mask = &soc->wlan_cfg_ctx->int_rx_ring_mask[0]; + nf_irq_mask = dp_srng_get_near_full_irq_mask(soc, ring_type, + ring_num); + if (nf_irq_mask) + nf_irq_enabled = true; break; case REO_STATUS: @@ -1305,7 +1560,14 @@ static int dp_srng_calculate_msi_group(struct dp_soc *soc, break; } - return dp_srng_find_ring_in_mask(ring_num, grp_mask); + *reg_msi_grp_num = dp_srng_find_ring_in_mask(ring_num, grp_mask); + + if (nf_irq_support && nf_irq_enabled) { + *nf_msi_grp_num = dp_srng_find_ring_in_mask(ring_num, + nf_irq_mask); + } + + return QDF_STATUS_SUCCESS; } /* @@ -1355,34 +1617,19 @@ static int dp_get_num_msi_available(struct dp_soc *soc, int interrupt_mode) } #endif -/** - * dp_is_msi_group_number_invalid() - check msi_group_number valid or not - * @msi_group_number: MSI group number. - * @msi_data_count: MSI data count. - * - * Return: true if msi_group_number is valid. - */ -#ifdef WLAN_ONE_MSI_VECTOR -static bool dp_is_msi_group_number_invalid(int msi_group_number, - int msi_data_count) -{ - return false; -} -#else -static bool dp_is_msi_group_number_invalid(int msi_group_number, - int msi_data_count) -{ - return msi_group_number > msi_data_count; -} -#endif - static void dp_srng_msi_setup(struct dp_soc *soc, struct hal_srng_params *ring_params, int ring_type, int ring_num) { - int msi_group_number; + int reg_msi_grp_num; + /* + * nf_msi_grp_num needs to be initialized with negative value, + * to avoid configuring near-full msi for WBM2SW3 ring + */ + int nf_msi_grp_num = -1; int msi_data_count; int ret; uint32_t msi_data_start, msi_irq_start, addr_low, addr_high; + bool nf_irq_support; ret = pld_get_user_msi_assignment(soc->osdev->dev, "DP", &msi_data_count, &msi_data_start, @@ -1391,20 +1638,33 @@ static void dp_srng_msi_setup(struct dp_soc *soc, struct hal_srng_params if (ret) return; - msi_group_number = dp_srng_calculate_msi_group(soc, ring_type, - ring_num); - if (msi_group_number < 0) { + nf_irq_support = hal_srng_is_near_full_irq_supported(soc->hal_soc, + ring_type, + ring_num); + ret = dp_srng_calculate_msi_group(soc, ring_type, ring_num, + ®_msi_grp_num, + nf_irq_support, + &nf_msi_grp_num); + if (ret < 0) { dp_init_info("%pK: ring not part of an ext_group; ring_type: %d,ring_num %d", soc, ring_type, ring_num); ring_params->msi_addr = 0; ring_params->msi_data = 0; + dp_srng_set_msi2_ring_params(soc, ring_params, 0, 0); return; } - if (dp_is_msi_group_number_invalid(msi_group_number, msi_data_count)) { - dp_init_warn("%pK: 2 msi_groups will share an msi; msi_group_num %d", - soc, msi_group_number); + if (reg_msi_grp_num < 0) { + dp_init_info("%pK: ring not part of an ext_group; ring_type: %d,ring_num %d", + soc, ring_type, ring_num); + ring_params->msi_addr = 0; + ring_params->msi_data = 0; + goto configure_msi2; + } + if (dp_is_msi_group_number_invalid(reg_msi_grp_num, msi_data_count)) { + dp_init_warn("%pK: 2 msi_groups will share an msi; msi_group_num %d", + soc, reg_msi_grp_num); QDF_ASSERT(0); } @@ -1412,9 +1672,18 @@ static void dp_srng_msi_setup(struct dp_soc *soc, struct hal_srng_params ring_params->msi_addr = addr_low; ring_params->msi_addr |= (qdf_dma_addr_t)(((uint64_t)addr_high) << 32); - ring_params->msi_data = (msi_group_number % msi_data_count) + ring_params->msi_data = (reg_msi_grp_num % msi_data_count) + msi_data_start; ring_params->flags |= HAL_SRNG_MSI_INTR; + +configure_msi2: + if (!nf_irq_support) { + dp_srng_set_msi2_ring_params(soc, ring_params, 0, 0); + return; + } + + dp_srng_msi2_setup(soc, ring_params, ring_type, ring_num, + nf_msi_grp_num); } #ifdef FEATURE_AST @@ -1576,6 +1845,8 @@ dp_srng_configure_interrupt_thresholds(struct dp_soc *soc, soc->wlan_srng_cfg[ring_type].low_threshold; if (ring_params->low_threshold) ring_params->flags |= HAL_SRNG_LOW_THRES_INTR_ENABLE; + + dp_srng_configure_nf_interrupt_thresholds(soc, ring_params, ring_type); } #else static void @@ -1886,6 +2157,7 @@ static QDF_STATUS dp_srng_init(struct dp_soc *soc, struct dp_srng *srng, } else { ring_params.msi_data = 0; ring_params.msi_addr = 0; + dp_srng_set_msi2_ring_params(soc, &ring_params, 0, 0); dp_verbose_debug("Skipping MSI for ring_type: %d, ring_num %d", ring_type, ring_num); } @@ -1894,6 +2166,8 @@ static QDF_STATUS dp_srng_init(struct dp_soc *soc, struct dp_srng *srng, ring_type, ring_num, srng->num_entries); + dp_srng_set_nf_thresholds(soc, srng, &ring_params); + if (srng->cached) ring_params.flags |= HAL_SRNG_CACHED_DESC; @@ -2147,6 +2421,22 @@ budget_done: return total_budget - budget; } +#ifdef WLAN_FEATURE_NEAR_FULL_IRQ +/** + * dp_service_near_full_srngs() - Bottom half handler to process the near + * full IRQ on a SRNG + * @dp_ctx: Datapath SoC handle + * @dp_budget: Number of SRNGs which can be processed in a single attempt + * without rescheduling + * + * Return: remaining budget/quota for the soc device + */ +static uint32_t dp_service_near_full_srngs(void *dp_ctx, uint32_t dp_budget) +{ + return 0; +} +#endif + #ifndef QCA_HOST_MODE_WIFI_DISABLED /* @@ -2722,6 +3012,15 @@ static void dp_soc_interrupt_map_calculate_msi(struct dp_soc *soc, soc->wlan_cfg_ctx, intr_ctx_num); int host2rxdma_mon_ring_mask = wlan_cfg_get_host2rxdma_mon_ring_mask( soc->wlan_cfg_ctx, intr_ctx_num); + int rx_near_full_grp_1_mask = + wlan_cfg_get_rx_near_full_grp_1_mask(soc->wlan_cfg_ctx, + intr_ctx_num); + int rx_near_full_grp_2_mask = + wlan_cfg_get_rx_near_full_grp_2_mask(soc->wlan_cfg_ctx, + intr_ctx_num); + int tx_ring_near_full_mask = + wlan_cfg_get_tx_ring_near_full_mask(soc->wlan_cfg_ctx, + intr_ctx_num); unsigned int vector = (intr_ctx_num % msi_vector_count) + msi_vector_start; @@ -2731,7 +3030,9 @@ static void dp_soc_interrupt_map_calculate_msi(struct dp_soc *soc, if (tx_mask | rx_mask | rx_mon_mask | rx_err_ring_mask | rx_wbm_rel_ring_mask | reo_status_ring_mask | rxdma2host_ring_mask | - host2rxdma_ring_mask | host2rxdma_mon_ring_mask) + host2rxdma_ring_mask | host2rxdma_mon_ring_mask | + rx_near_full_grp_1_mask | rx_near_full_grp_2_mask | + tx_ring_near_full_mask) irq_id_map[num_irq++] = pld_get_msi_irq(soc->osdev->dev, vector); @@ -2758,6 +3059,36 @@ static void dp_soc_interrupt_map_calculate(struct dp_soc *soc, int intr_ctx_num, msi_vector_count, msi_vector_start); } +#ifdef WLAN_FEATURE_NEAR_FULL_IRQ +/** + * dp_soc_near_full_interrupt_attach() - Register handler for DP near fill irq + * @soc: DP soc handle + * @num_irq: IRQ number + * @irq_id_map: IRQ map + * intr_id: interrupt context ID + * + * Return: 0 for success. nonzero for failure. + */ +static inline int +dp_soc_near_full_interrupt_attach(struct dp_soc *soc, int num_irq, + int irq_id_map[], int intr_id) +{ + return hif_register_ext_group(soc->hif_handle, + num_irq, irq_id_map, + dp_service_near_full_srngs, + &soc->intr_ctx[intr_id], "dp_nf_intr", + HIF_EXEC_NAPI_TYPE, + QCA_NAPI_DEF_SCALE_BIN_SHIFT); +} +#else +static inline int +dp_soc_near_full_interrupt_attach(struct dp_soc *soc, int num_irq, + int *irq_id_map, int intr_id) +{ + return 0; +} +#endif + /* * dp_soc_interrupt_attach() - Register handlers for DP interrupts * @txrx_soc: DP SOC handle @@ -2803,6 +3134,15 @@ static QDF_STATUS dp_soc_interrupt_attach(struct cdp_soc_t *txrx_soc) int host2rxdma_mon_ring_mask = wlan_cfg_get_host2rxdma_mon_ring_mask( soc->wlan_cfg_ctx, i); + int rx_near_full_grp_1_mask = + wlan_cfg_get_rx_near_full_grp_1_mask(soc->wlan_cfg_ctx, + i); + int rx_near_full_grp_2_mask = + wlan_cfg_get_rx_near_full_grp_2_mask(soc->wlan_cfg_ctx, + i); + int tx_ring_near_full_mask = + wlan_cfg_get_tx_ring_near_full_mask(soc->wlan_cfg_ctx, + i); soc->intr_ctx[i].dp_intr_id = i; soc->intr_ctx[i].tx_ring_mask = tx_mask; @@ -2815,6 +3155,12 @@ static QDF_STATUS dp_soc_interrupt_attach(struct cdp_soc_t *txrx_soc) soc->intr_ctx[i].reo_status_ring_mask = reo_status_ring_mask; soc->intr_ctx[i].host2rxdma_mon_ring_mask = host2rxdma_mon_ring_mask; + soc->intr_ctx[i].rx_near_full_grp_1_mask = + rx_near_full_grp_1_mask; + soc->intr_ctx[i].rx_near_full_grp_2_mask = + rx_near_full_grp_2_mask; + soc->intr_ctx[i].tx_ring_near_full_mask = + tx_ring_near_full_mask; soc->intr_ctx[i].soc = soc; @@ -2823,10 +3169,17 @@ static QDF_STATUS dp_soc_interrupt_attach(struct cdp_soc_t *txrx_soc) dp_soc_interrupt_map_calculate(soc, i, &irq_id_map[0], &num_irq); - ret = hif_register_ext_group(soc->hif_handle, + if (rx_near_full_grp_1_mask | rx_near_full_grp_2_mask | + tx_ring_near_full_mask) { + dp_soc_near_full_interrupt_attach(soc, num_irq, + irq_id_map, i); + } else { + ret = hif_register_ext_group(soc->hif_handle, num_irq, irq_id_map, dp_service_srngs, &soc->intr_ctx[i], "dp_intr", - HIF_EXEC_NAPI_TYPE, QCA_NAPI_DEF_SCALE_BIN_SHIFT); + HIF_EXEC_NAPI_TYPE, + QCA_NAPI_DEF_SCALE_BIN_SHIFT); + } if (ret) { dp_init_err("%pK: failed, ret = %d", soc, ret); @@ -2859,6 +3212,7 @@ static void dp_soc_interrupt_detach(struct cdp_soc_t *txrx_soc) } else { hif_deconfigure_ext_group_interrupts(soc->hif_handle); hif_deregister_exec_group(soc->hif_handle, "dp_intr"); + hif_deregister_exec_group(soc->hif_handle, "dp_nf_intr"); } for (i = 0; i < wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx); i++) { @@ -2871,6 +3225,9 @@ static void dp_soc_interrupt_detach(struct cdp_soc_t *txrx_soc) soc->intr_ctx[i].rxdma2host_ring_mask = 0; soc->intr_ctx[i].host2rxdma_ring_mask = 0; soc->intr_ctx[i].host2rxdma_mon_ring_mask = 0; + soc->intr_ctx[i].rx_near_full_grp_1_mask = 0; + soc->intr_ctx[i].rx_near_full_grp_2_mask = 0; + soc->intr_ctx[i].tx_ring_near_full_mask = 0; hif_event_history_deinit(soc->hif_handle, i); qdf_lro_deinit(soc->intr_ctx[i].lro_ctx); diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 3dd4ca25fa..b692183be7 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -668,6 +668,9 @@ struct dp_txrx_pool_stats { * @cached: is the srng ring memory cached or un-cached memory * @irq: irq number of the srng ring * @num_entries: number of entries in the srng ring + * @is_mem_prealloc: Is this srng memeory pre-allocated + * @crit_thresh: Critical threshold for near-full processing of this srng + * @safe_thresh: Safe threshold for near-full processing of this srng */ struct dp_srng { hal_ring_handle_t hal_srng; @@ -682,6 +685,10 @@ struct dp_srng { #ifdef DP_MEM_PRE_ALLOC uint8_t is_mem_prealloc; #endif +#ifdef WLAN_FEATURE_NEAR_FULL_IRQ + uint16_t crit_thresh; + uint16_t safe_thresh; +#endif }; struct dp_rx_reorder_array_elem { @@ -831,6 +838,12 @@ struct dp_intr { uint8_t host2rxdma_ring_mask; /* Host to RXDMA buffer ring */ /* Host to RXDMA monitor buffer ring */ uint8_t host2rxdma_mon_ring_mask; + /* RX REO rings near full interrupt mask */ + uint8_t rx_near_full_grp_1_mask; + /* RX REO rings near full interrupt mask */ + uint8_t rx_near_full_grp_2_mask; + /* WBM TX completion rings near full interrupt mask */ + uint8_t tx_ring_near_full_mask; struct dp_soc *soc; /* Reference to SoC structure , to get DMA ring handles */ qdf_lro_ctx_t lro_ctx; diff --git a/hal/wifi3.0/hal_api.h b/hal/wifi3.0/hal_api.h index d01119d438..b6157631ab 100644 --- a/hal/wifi3.0/hal_api.h +++ b/hal/wifi3.0/hal_api.h @@ -989,6 +989,20 @@ struct hal_srng_params { void *hwreg_base[MAX_SRNG_REG_GROUPS]; /* prefetch timer config - in micro seconds */ uint32_t prefetch_timer; +#ifdef WLAN_FEATURE_NEAR_FULL_IRQ + /* Near full IRQ support flag */ + uint32_t nf_irq_support; + /* MSI2 Address */ + qdf_dma_addr_t msi2_addr; + /* MSI2 data */ + uint32_t msi2_data; + /* Critical threshold */ + uint16_t crit_thresh; + /* High threshold */ + uint16_t high_thresh; + /* Safe threshold */ + uint16_t safe_thresh; +#endif }; /* hal_construct_srng_shadow_regs() - initialize the shadow @@ -1025,6 +1039,28 @@ QDF_STATUS hal_set_one_shadow_config(void *hal_soc, int ring_type, extern void hal_get_shadow_config(void *hal_soc, struct pld_shadow_reg_v2_cfg **shadow_config, int *num_shadow_registers_configured); + +#ifdef WLAN_FEATURE_NEAR_FULL_IRQ +/** + * hal_srng_is_near_full_irq_supported() - Check if srng supports near full irq + * @hal_soc: HAL SoC handle [To be validated by caller] + * @ring_type: srng type + * @ring_num: The index of the srng (of the same type) + * + * Return: true, if srng support near full irq trigger + * false, if the srng does not support near full irq support. + */ +bool hal_srng_is_near_full_irq_supported(hal_soc_handle_t hal_soc, + int ring_type, int ring_num); +#else +static inline +bool hal_srng_is_near_full_irq_supported(hal_soc_handle_t hal_soc, + int ring_type, int ring_num) +{ + return false; +} +#endif + /** * hal_srng_setup - Initialize HW SRNG ring. * diff --git a/hal/wifi3.0/hal_generic_api.h b/hal/wifi3.0/hal_generic_api.h index 887c7424ff..d90b6a78eb 100644 --- a/hal/wifi3.0/hal_generic_api.h +++ b/hal/wifi3.0/hal_generic_api.h @@ -292,6 +292,65 @@ void hal_srng_src_hw_init_generic(struct hal_soc *hal, 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 - Private function to initialize SRNG * destination ring HW @@ -317,6 +376,8 @@ void hal_srng_dst_hw_init_generic(struct hal_soc *hal, 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); @@ -351,6 +412,14 @@ void hal_srng_dst_hw_init_generic(struct hal_soc *hal, } 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))); diff --git a/hal/wifi3.0/hal_hw_headers.h b/hal/wifi3.0/hal_hw_headers.h index c14bbc7c23..68b73d44ec 100644 --- a/hal/wifi3.0/hal_hw_headers.h +++ b/hal/wifi3.0/hal_hw_headers.h @@ -86,6 +86,12 @@ #define HAL_REO_R0_REO2SW1_RING_MSI1_BASE_MSB_MSI1_ENABLE_SHFT 0x8 #define HAL_REO_R0_REO2SW1_RING_MSI1_BASE_MSB_MSI1_ENABLE_BMSK 0x100 +#define HAL_REO_R0_REO2SW1_RING_MSI2_BASE_MSB_ADDR_SHFT 0x0 +#define HAL_REO_R0_REO2SW1_RING_MSI2_BASE_MSB_ADDR_BMSK 0xff + +#define HAL_REO_R0_REO2SW1_RING_MSI2_BASE_MSB_MSI2_ENABLE_SHFT 0x8 +#define HAL_REO_R0_REO2SW1_RING_MSI2_BASE_MSB_MSI2_ENABLE_BMSK 0x100 + #define HAL_REO_R0_REO2SW1_RING_BASE_MSB_RING_BASE_ADDR_MSB_SHFT 0x0 #define HAL_REO_R0_REO2SW1_RING_BASE_MSB_RING_BASE_ADDR_MSB_BMSK 0xff @@ -104,6 +110,12 @@ #define HAL_REO_R0_REO2SW1_RING_PRODUCER_INT_SETUP_BATCH_COUNTER_THRESHOLD_SHFT 0x0 #define HAL_REO_R0_REO2SW1_RING_PRODUCER_INT_SETUP_BATCH_COUNTER_THRESHOLD_BMSK 0x00007fff +#define HAL_REO_R0_REO2SW1_RING_PRODUCER_INT2_SETUP_INTERRUPT2_TIMER_THRESHOLD_SHFT 24 +#define HAL_REO_R0_REO2SW1_RING_PRODUCER_INT2_SETUP_INTERRUPT2_TIMER_THRESHOLD_BMSK 0xff000000 + +#define HAL_REO_R0_REO2SW1_RING_PRODUCER_INT2_SETUP_HIGH_THRESHOLD_SHFT 0 +#define HAL_REO_R0_REO2SW1_RING_PRODUCER_INT2_SETUP_HIGH_THRESHOLD_BMSK 0xfffff + #define HAL_REO_R0_REO2SW1_RING_MISC_DATA_TLV_SWAP_BIT_SHFT 0x5 #define HAL_REO_R0_REO2SW1_RING_MISC_DATA_TLV_SWAP_BIT_BMSK 0x20 @@ -183,11 +195,15 @@ #define HP_ADDR_LSB_GROUP R0 #define HP_ADDR_MSB_GROUP R0 #define PRODUCER_INT_SETUP_GROUP R0 +#define PRODUCER_INT2_SETUP_GROUP R0 #define PRODUCER_INT_STATUS_GROUP R0 #define PRODUCER_FULL_COUNTER_GROUP R0 #define MSI1_BASE_LSB_GROUP R0 #define MSI1_BASE_MSB_GROUP R0 #define MSI1_DATA_GROUP R0 +#define MSI2_BASE_LSB_GROUP R0 +#define MSI2_BASE_MSB_GROUP R0 +#define MSI2_DATA_GROUP R0 #define HP_TP_SW_OFFSET_GROUP R0 #define TP_ADDR_LSB_GROUP R0 #define TP_ADDR_MSB_GROUP R0 @@ -314,35 +330,6 @@ #define HAL_SRNG_CONFIG(_hal_soc, _ring_type) \ (&_hal_soc->hw_srng_table[_ring_type]) -enum SRNG_REGISTERS { -DST_HP = 0, -DST_TP, -DST_ID, -DST_MISC, -DST_HP_ADDR_LSB, -DST_HP_ADDR_MSB, -DST_MSI1_BASE_LSB, -DST_MSI1_BASE_MSB, -DST_MSI1_DATA, -DST_BASE_LSB, -DST_BASE_MSB, -DST_PRODUCER_INT_SETUP, - -SRC_HP, -SRC_TP, -SRC_ID, -SRC_MISC, -SRC_TP_ADDR_LSB, -SRC_TP_ADDR_MSB, -SRC_MSI1_BASE_LSB, -SRC_MSI1_BASE_MSB, -SRC_MSI1_DATA, -SRC_BASE_LSB, -SRC_BASE_MSB, -SRC_CONSUMER_INT_SETUP_IX0, -SRC_CONSUMER_INT_SETUP_IX1, -}; - /** * hal_set_link_desc_addr - Setup link descriptor in a buffer_addr_info * HW structure diff --git a/hal/wifi3.0/hal_internal.h b/hal/wifi3.0/hal_internal.h index 79203ce19e..eaaeb4667c 100644 --- a/hal/wifi3.0/hal_internal.h +++ b/hal/wifi3.0/hal_internal.h @@ -272,6 +272,44 @@ enum hal_ring_type { MAX_RING_TYPES }; +enum SRNG_REGISTERS { + DST_HP = 0, + DST_TP, + DST_ID, + DST_MISC, + DST_HP_ADDR_LSB, + DST_HP_ADDR_MSB, + DST_MSI1_BASE_LSB, + DST_MSI1_BASE_MSB, + DST_MSI1_DATA, +#ifdef CONFIG_BERYLLIUM + DST_MSI2_BASE_LSB, + DST_MSI2_BASE_MSB, + DST_MSI2_DATA, +#endif + DST_BASE_LSB, + DST_BASE_MSB, + DST_PRODUCER_INT_SETUP, +#ifdef CONFIG_BERYLLIUM + DST_PRODUCER_INT2_SETUP, +#endif + + SRC_HP, + SRC_TP, + SRC_ID, + SRC_MISC, + SRC_TP_ADDR_LSB, + SRC_TP_ADDR_MSB, + SRC_MSI1_BASE_LSB, + SRC_MSI1_BASE_MSB, + SRC_MSI1_DATA, + SRC_BASE_LSB, + SRC_BASE_MSB, + SRC_CONSUMER_INT_SETUP_IX0, + SRC_CONSUMER_INT_SETUP_IX1, + SRNG_REGISTER_MAX, +}; + #define HAL_RXDMA_MAX_RING_SIZE 0xFFFF #define HAL_MAX_LMACS 3 #define HAL_MAX_RINGS_PER_LMAC (HAL_SRNG_LMAC1_ID_END - HAL_SRNG_LMAC1_ID_START) @@ -475,6 +513,14 @@ struct hal_srng { /* MSI data */ uint32_t msi_data; +#ifdef WLAN_FEATURE_NEAR_FULL_IRQ + /* MSI2 Address */ + qdf_dma_addr_t msi2_addr; + + /* MSI2 data */ + uint32_t msi2_data; +#endif + /* Misc flags */ uint32_t flags; @@ -514,6 +560,14 @@ struct hal_srng { /* max transfer size */ uint16_t max_buffer_length; + +#ifdef WLAN_FEATURE_NEAR_FULL_IRQ + /* near full IRQ supported */ + uint16_t nf_irq_support; + + /* High threshold for Near full IRQ */ + uint16_t high_thresh; +#endif } dst_ring; struct { @@ -571,6 +625,7 @@ struct hal_hw_srng_config { uint8_t lmac_ring; enum hal_srng_dir ring_dir; uint32_t max_size; + bool nf_irq_support; }; #define MAX_SHADOW_REGISTERS 40 diff --git a/hal/wifi3.0/hal_srng.c b/hal/wifi3.0/hal_srng.c index ce08bf9076..8043005482 100644 --- a/hal/wifi3.0/hal_srng.c +++ b/hal/wifi3.0/hal_srng.c @@ -1767,6 +1767,92 @@ static inline void hal_srng_hw_init(struct hal_soc *hal, #define CHECK_SHADOW_REGISTERS false #endif +#ifdef WLAN_FEATURE_NEAR_FULL_IRQ +/** + * hal_srng_is_near_full_irq_supported() - Check if near full irq is + * supported on this SRNG + * @hal_soc: HAL SoC handle + * @ring_type: SRNG type + * @ring_num: ring number + * + * Return: true, if near full irq is supported for this SRNG + * false, if near full irq is not supported for this SRNG + */ +bool hal_srng_is_near_full_irq_supported(hal_soc_handle_t hal_soc, + int ring_type, int ring_num) +{ + struct hal_soc *hal = (struct hal_soc *)hal_soc; + struct hal_hw_srng_config *ring_config = + HAL_SRNG_CONFIG(hal, ring_type); + + return ring_config->nf_irq_support; +} + +/** + * hal_srng_set_msi2_params() - Set MSI2 params to SRNG data structure from + * ring params + * @srng: SRNG handle + * @ring_params: ring params for this SRNG + * + * Return: None + */ +static inline void +hal_srng_set_msi2_params(struct hal_srng *srng, + struct hal_srng_params *ring_params) +{ + srng->msi2_addr = ring_params->msi2_addr; + srng->msi2_data = ring_params->msi2_data; +} + +/** + * hal_srng_get_nf_params() - Get the near full MSI2 params from srng + * @srng: SRNG handle + * @ring_params: ring params for this SRNG + * + * Return: None + */ +static inline void +hal_srng_get_nf_params(struct hal_srng *srng, + struct hal_srng_params *ring_params) +{ + ring_params->msi2_addr = srng->msi2_addr; + ring_params->msi2_data = srng->msi2_data; +} + +/** + * hal_srng_set_nf_thresholds() - Set the near full thresholds in SRNG + * @srng: SRNG handle where the params are to be set + * @ring_params: ring params, from where threshold is to be fetched + * + * Return: None + */ +static inline void +hal_srng_set_nf_thresholds(struct hal_srng *srng, + struct hal_srng_params *ring_params) +{ + srng->u.dst_ring.nf_irq_support = ring_params->nf_irq_support; + srng->u.dst_ring.high_thresh = ring_params->high_thresh; +} +#else +static inline void +hal_srng_set_msi2_params(struct hal_srng *srng, + struct hal_srng_params *ring_params) +{ +} + +static inline void +hal_srng_get_nf_params(struct hal_srng *srng, + struct hal_srng_params *ring_params) +{ +} + +static inline void +hal_srng_set_nf_thresholds(struct hal_srng *srng, + struct hal_srng_params *ring_params) +{ +} +#endif + /** * hal_srng_setup - Initialize HW SRNG ring. * @hal_soc: Opaque HAL SOC handle @@ -1827,6 +1913,7 @@ void *hal_srng_setup(void *hal_soc, int ring_type, int ring_num, ring_params->intr_batch_cntr_thres_entries; srng->prefetch_timer = ring_params->prefetch_timer; srng->hal_soc = hal_soc; + hal_srng_set_msi2_params(srng, ring_params); for (i = 0 ; i < MAX_SRNG_REG_GROUPS; i++) { srng->hwreg_base[i] = dev_base_addr + ring_config->reg_start[i] @@ -1886,6 +1973,7 @@ void *hal_srng_setup(void *hal_soc, int ring_type, int ring_num, * loop count in descriptors updated by HW (to be processed * by SW). */ + hal_srng_set_nf_thresholds(srng, ring_params); srng->u.dst_ring.loop_cnt = 1; srng->u.dst_ring.tp = 0; srng->u.dst_ring.hp_addr = @@ -2042,6 +2130,8 @@ extern void hal_get_srng_params(hal_soc_handle_t hal_soc_hdl, ring_params->ring_id = srng->ring_id; for (i = 0 ; i < MAX_SRNG_REG_GROUPS; i++) ring_params->hwreg_base[i] = srng->hwreg_base[i]; + + hal_srng_get_nf_params(srng, ring_params); } qdf_export_symbol(hal_get_srng_params); diff --git a/hal/wifi3.0/wcn7850/hal_7850.c b/hal/wifi3.0/wcn7850/hal_7850.c index 0e3524445e..fcf8ec84f5 100644 --- a/hal/wifi3.0/wcn7850/hal_7850.c +++ b/hal/wifi3.0/wcn7850/hal_7850.c @@ -1449,6 +1449,7 @@ struct hal_hw_srng_config hw_srng_table_7850[] = { .entry_size = sizeof(struct reo_destination_ring) >> 2, .lmac_ring = FALSE, .ring_dir = HAL_SRNG_DST_RING, + .nf_irq_support = true, .reg_start = { HWIO_REO_R0_REO2SW1_RING_BASE_LSB_ADDR( REO_REG_REG_BASE), @@ -1716,6 +1717,7 @@ struct hal_hw_srng_config hw_srng_table_7850[] = { .entry_size = sizeof(struct wbm_release_ring) >> 2, .lmac_ring = FALSE, .ring_dir = HAL_SRNG_DST_RING, + .nf_irq_support = true, .reg_start = { HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_LSB_ADDR(WBM_REG_REG_BASE), HWIO_WBM_R2_WBM2SW0_RELEASE_RING_HP_ADDR(WBM_REG_REG_BASE), @@ -1857,9 +1859,13 @@ int32_t hal_hw_reg_offset_wcn7850[] = { REG_OFFSET(DST, MSI1_BASE_LSB), REG_OFFSET(DST, MSI1_BASE_MSB), REG_OFFSET(DST, MSI1_DATA), + REG_OFFSET(DST, MSI2_BASE_LSB), + REG_OFFSET(DST, MSI2_BASE_MSB), + REG_OFFSET(DST, MSI2_DATA), REG_OFFSET(DST, BASE_LSB), REG_OFFSET(DST, BASE_MSB), REG_OFFSET(DST, PRODUCER_INT_SETUP), + REG_OFFSET(DST, PRODUCER_INT2_SETUP), /* src */ REG_OFFSET(SRC, HP), REG_OFFSET(SRC, TP), diff --git a/hif/inc/hif.h b/hif/inc/hif.h index 8eee89bfcc..8b57b0039a 100644 --- a/hif/inc/hif.h +++ b/hif/inc/hif.h @@ -134,8 +134,8 @@ struct CE_state; #ifndef HIF_MAX_GROUP #ifdef CONFIG_BERYLLIUM -#define HIF_MAX_GROUP 11 -#define HIF_MAX_GRP_IRQ 20 +#define HIF_MAX_GROUP 14 +#define HIF_MAX_GRP_IRQ 23 #else #define HIF_MAX_GROUP 7 #define HIF_MAX_GRP_IRQ 16 diff --git a/wlan_cfg/wlan_cfg.c b/wlan_cfg/wlan_cfg.c index 66759532e9..a7015733e9 100644 --- a/wlan_cfg/wlan_cfg.c +++ b/wlan_cfg/wlan_cfg.c @@ -48,15 +48,6 @@ #define WLAN_CFG_TX_RING_MASK_2 0x4 #define WLAN_CFG_TX_RING_MASK_3 0x0 -#define WLAN_CFG_RX_RING_MASK_0 0x1 -#define WLAN_CFG_RX_RING_MASK_1 0x2 -#define WLAN_CFG_RX_RING_MASK_2 0x4 -#define WLAN_CFG_RX_RING_MASK_3 0x8 -#define WLAN_CFG_RX_RING_MASK_4 0x10 -#define WLAN_CFG_RX_RING_MASK_5 0x20 -#define WLAN_CFG_RX_RING_MASK_6 0x40 -#define WLAN_CFG_RX_RING_MASK_7 0x80 - #define WLAN_CFG_RX_MON_RING_MASK_0 0x1 #define WLAN_CFG_RX_MON_RING_MASK_1 0x2 @@ -107,6 +98,9 @@ struct dp_int_mask_assignment { uint8_t rx_err_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS]; uint8_t rx_wbm_rel_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS]; uint8_t reo_status_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS]; + uint8_t rx_ring_near_full_irq_1_mask[WLAN_CFG_INT_NUM_CONTEXTS]; + uint8_t rx_ring_near_full_irq_2_mask[WLAN_CFG_INT_NUM_CONTEXTS]; + uint8_t tx_ring_near_full_irq_mask[WLAN_CFG_INT_NUM_CONTEXTS]; }; #if defined(WLAN_MAX_PDEVS) && (WLAN_MAX_PDEVS == 1) @@ -185,6 +179,28 @@ static struct dp_int_mask_assignment dp_mask_assignment[NUM_INTERRUPT_COMBINATIO /* reo status ring masks */ { 0, 0, 0, 0, 0, 0, WLAN_CFG_REO_STATUS_RING_MASK_0}, +#ifdef CONFIG_BERYLLIUM + /* rx near full irq1 mask */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + WLAN_CFG_RX_NEAR_FULL_IRQ_MASK_1, + 0, 0}, + /* rx near full irq2 mask */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, + WLAN_CFG_RX_NEAR_FULL_IRQ_MASK_2, + 0}, + /* tx near full irq mask */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, + WLAN_CFG_TX_RING_NEAR_FULL_IRQ_MASK}, +#else /* CONFIG_BERYLLIUM */ + /* rx near full irq1 mask */ + { 0, 0, 0, 0, 0, 0, 0}, + /* rx near full irq2 mask */ + { 0, 0, 0, 0, 0, 0, 0}, + /* tx near full irq mask */ + { 0, 0, 0, 0, 0, 0, 0}, +#endif /* CONFIG_BERYLLIUM */ }, }; @@ -889,32 +905,38 @@ void wlan_cfg_fill_interrupt_mask(struct wlan_cfg_dp_soc_ctxt *wlan_cfg_ctx, for (i = 0; i < WLAN_CFG_INT_NUM_CONTEXTS; i++) { - wlan_cfg_ctx->int_tx_ring_mask[i] = - dp_mask_assignment[interrupt_index].tx_ring_mask[i]; - wlan_cfg_ctx->int_rx_mon_ring_mask[i] = - dp_mask_assignment[interrupt_index].rx_mon_ring_mask[i]; - wlan_cfg_ctx->int_rx_err_ring_mask[i] = - dp_mask_assignment[interrupt_index].rx_err_ring_mask[i]; - wlan_cfg_ctx->int_rx_wbm_rel_ring_mask[i] = - dp_mask_assignment[interrupt_index].rx_wbm_rel_ring_mask[i]; - wlan_cfg_ctx->int_reo_status_ring_mask[i] = - dp_mask_assignment[interrupt_index].reo_status_ring_mask[i]; - if (is_monitor_mode) { - wlan_cfg_ctx->int_rx_ring_mask[i] = 0; - wlan_cfg_ctx->int_rxdma2host_ring_mask[i] = 0; - } else { - wlan_cfg_ctx->int_rx_ring_mask[i] = - dp_mask_assignment[interrupt_index].rx_ring_mask[i]; - wlan_cfg_ctx->int_rxdma2host_ring_mask[i] = - dp_mask_assignment[interrupt_index].rxdma2host_ring_mask[i]; - } - wlan_cfg_ctx->int_host2rxdma_ring_mask[i] = - dp_mask_assignment[interrupt_index].host2rxdma_ring_mask[i]; - wlan_cfg_ctx->int_host2rxdma_mon_ring_mask[i] = - dp_mask_assignment[interrupt_index].host2rxdma_mon_ring_mask[i]; - wlan_cfg_ctx->int_rxdma2host_mon_ring_mask[i] = - dp_mask_assignment[interrupt_index].rxdma2host_mon_ring_mask[i]; + wlan_cfg_ctx->int_tx_ring_mask[i] = + dp_mask_assignment[interrupt_index].tx_ring_mask[i]; + wlan_cfg_ctx->int_rx_mon_ring_mask[i] = + dp_mask_assignment[interrupt_index].rx_mon_ring_mask[i]; + wlan_cfg_ctx->int_rx_err_ring_mask[i] = + dp_mask_assignment[interrupt_index].rx_err_ring_mask[i]; + wlan_cfg_ctx->int_rx_wbm_rel_ring_mask[i] = + dp_mask_assignment[interrupt_index].rx_wbm_rel_ring_mask[i]; + wlan_cfg_ctx->int_reo_status_ring_mask[i] = + dp_mask_assignment[interrupt_index].reo_status_ring_mask[i]; + if (is_monitor_mode) { + wlan_cfg_ctx->int_rx_ring_mask[i] = 0; + wlan_cfg_ctx->int_rxdma2host_ring_mask[i] = 0; + } else { + wlan_cfg_ctx->int_rx_ring_mask[i] = + dp_mask_assignment[interrupt_index].rx_ring_mask[i]; + wlan_cfg_ctx->int_rxdma2host_ring_mask[i] = + dp_mask_assignment[interrupt_index].rxdma2host_ring_mask[i]; } + wlan_cfg_ctx->int_host2rxdma_ring_mask[i] = + dp_mask_assignment[interrupt_index].host2rxdma_ring_mask[i]; + wlan_cfg_ctx->int_host2rxdma_mon_ring_mask[i] = + dp_mask_assignment[interrupt_index].host2rxdma_mon_ring_mask[i]; + wlan_cfg_ctx->int_rxdma2host_mon_ring_mask[i] = + dp_mask_assignment[interrupt_index].rxdma2host_mon_ring_mask[i]; + wlan_cfg_ctx->int_rx_ring_near_full_irq_1_mask[i] = + dp_mask_assignment[interrupt_index].rx_ring_near_full_irq_1_mask[i]; + wlan_cfg_ctx->int_rx_ring_near_full_irq_2_mask[i] = + dp_mask_assignment[interrupt_index].rx_ring_near_full_irq_2_mask[i]; + wlan_cfg_ctx->int_tx_ring_near_full_irq_mask[i] = + dp_mask_assignment[interrupt_index].tx_ring_near_full_irq_mask[i]; + } } #ifdef IPA_OFFLOAD @@ -1280,6 +1302,24 @@ int wlan_cfg_get_host2rxdma_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, return cfg->int_host2rxdma_ring_mask[context]; } +int wlan_cfg_get_rx_near_full_grp_1_mask(struct wlan_cfg_dp_soc_ctxt *cfg, + int context) +{ + return cfg->int_rx_ring_near_full_irq_1_mask[context]; +} + +int wlan_cfg_get_rx_near_full_grp_2_mask(struct wlan_cfg_dp_soc_ctxt *cfg, + int context) +{ + return cfg->int_rx_ring_near_full_irq_2_mask[context]; +} + +int wlan_cfg_get_tx_ring_near_full_mask(struct wlan_cfg_dp_soc_ctxt *cfg, + int context) +{ + return cfg->int_tx_ring_near_full_irq_mask[context]; +} + void wlan_cfg_set_hw_mac_idx(struct wlan_cfg_dp_soc_ctxt *cfg, int pdev_idx, int hw_macid) { diff --git a/wlan_cfg/wlan_cfg.h b/wlan_cfg/wlan_cfg.h index c902c353cf..ab0b1b748c 100644 --- a/wlan_cfg/wlan_cfg.h +++ b/wlan_cfg/wlan_cfg.h @@ -27,7 +27,7 @@ #define WLAN_CFG_DST_RING_CACHED_DESC 0 #define MAX_PDEV_CNT 1 #ifdef CONFIG_BERYLLIUM -#define WLAN_CFG_INT_NUM_CONTEXTS 11 +#define WLAN_CFG_INT_NUM_CONTEXTS 14 #else #define WLAN_CFG_INT_NUM_CONTEXTS 7 #endif @@ -54,7 +54,7 @@ #endif -#define WLAN_CFG_INT_NUM_CONTEXTS_MAX 11 +#define WLAN_CFG_INT_NUM_CONTEXTS_MAX 14 /* Tx configuration */ #define MAX_LINK_DESC_BANKS 8 @@ -92,6 +92,41 @@ #define INVALID_PDEV_ID 0xFF +#define WLAN_CFG_RX_RING_MASK_0 0x1 +#define WLAN_CFG_RX_RING_MASK_1 0x2 +#define WLAN_CFG_RX_RING_MASK_2 0x4 +#define WLAN_CFG_RX_RING_MASK_3 0x8 +#define WLAN_CFG_RX_RING_MASK_4 0x10 +#define WLAN_CFG_RX_RING_MASK_5 0x20 +#define WLAN_CFG_RX_RING_MASK_6 0x40 +#define WLAN_CFG_RX_RING_MASK_7 0x80 + +#ifdef WLAN_FEATURE_NEAR_FULL_IRQ +#ifdef IPA_OFFLOAD +#define WLAN_CFG_RX_NEAR_FULL_IRQ_MASK_1 (WLAN_CFG_RX_RING_MASK_0 | \ + WLAN_CFG_RX_RING_MASK_1 | \ + WLAN_CFG_RX_RING_MASK_2) + +#define WLAN_CFG_RX_NEAR_FULL_IRQ_MASK_2 (WLAN_CFG_RX_RING_MASK_4 | \ + WLAN_CFG_RX_RING_MASK_5 | \ + WLAN_CFG_RX_RING_MASK_6) + +#define WLAN_CFG_TX_RING_NEAR_FULL_IRQ_MASK (WLAN_CFG_TX_RING_MASK_0) +#else +#define WLAN_CFG_RX_NEAR_FULL_IRQ_MASK_1 (WLAN_CFG_RX_RING_MASK_0 | \ + WLAN_CFG_RX_RING_MASK_1 | \ + WLAN_CFG_RX_RING_MASK_2 | \ + WLAN_CFG_RX_RING_MASK_3) + +#define WLAN_CFG_RX_NEAR_FULL_IRQ_MASK_2 (WLAN_CFG_RX_RING_MASK_4 | \ + WLAN_CFG_RX_RING_MASK_5 | \ + WLAN_CFG_RX_RING_MASK_6 | \ + WLAN_CFG_RX_RING_MASK_7) + +#define WLAN_CFG_TX_RING_NEAR_FULL_IRQ_MASK (WLAN_CFG_TX_RING_MASK_0) +#endif +#endif + struct wlan_cfg_dp_pdev_ctxt; /** @@ -135,6 +170,14 @@ struct wlan_srng_cfg { * NAPI/Intr context * @int_reo_status_ring_mask: Bitmap of reo status ring interrupts mapped to * each NAPI/Intr context + * @int_rxdma2host_ring_mask: + * @int_host2rxdma_ring_mask: + * @int_rx_ring_near_full_irq_1_mask: Bitmap of REO DST ring near full interrupt + * mapped to each NAPI/INTR context + * @int_rx_ring_near_full_irq_2_mask: Bitmap of REO DST ring near full interrupt + * mapped to each NAPI/INTR context + * @int_tx_ring_near_full_irq_mask: Bitmap of Tx completion ring near full + * interrupt mapped to each NAPI/INTR context * @int_ce_ring_mask: Bitmap of CE interrupts mapped to each NAPI/Intr context * @lro_enabled: enable/disable lro feature * @rx_hash: Enable hash based steering of rx packets @@ -246,6 +289,9 @@ struct wlan_cfg_dp_soc_ctxt { uint8_t int_reo_status_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS]; uint8_t int_rxdma2host_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS]; uint8_t int_host2rxdma_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS]; + uint8_t int_rx_ring_near_full_irq_1_mask[WLAN_CFG_INT_NUM_CONTEXTS]; + uint8_t int_rx_ring_near_full_irq_2_mask[WLAN_CFG_INT_NUM_CONTEXTS]; + uint8_t int_tx_ring_near_full_irq_mask[WLAN_CFG_INT_NUM_CONTEXTS]; int hw_macid[MAX_PDEV_CNT]; int hw_macid_pdev_id_map[MAX_NUM_LMAC_HW]; int base_hw_macid; @@ -527,6 +573,38 @@ void wlan_cfg_set_host2rxdma_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, int wlan_cfg_get_host2rxdma_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, int context); +/** + * wlan_cfg_get_rx_near_full_grp_1_mask() - Return REO near full interrupt mask + * mapped to an interrupt context + * @cfg: Configuration Handle + * @context - Numerical ID identifying the Interrupt/NAPI context + * + * Return: REO near full interrupt mask[context] + */ +int wlan_cfg_get_rx_near_full_grp_1_mask(struct wlan_cfg_dp_soc_ctxt *cfg, + int context); + +/** + * wlan_cfg_get_rx_near_full_grp_2_mask() - Return REO near full interrupt mask + * mapped to an interrupt context + * @cfg: Configuration Handle + * @context - Numerical ID identifying the Interrupt/NAPI context + * + * Return: REO near full interrupt mask[context] + */ +int wlan_cfg_get_rx_near_full_grp_2_mask(struct wlan_cfg_dp_soc_ctxt *cfg, + int context); + +/** + * wlan_cfg_get_tx_ring_near_full_mask() - Return tx completion ring near full + * interrupt mask mapped to an interrupt context + * @cfg: Configuration Handle + * @context - Numerical ID identifying the Interrupt/NAPI context + * + * Return: tx completion near full interrupt mask[context] + */ +int wlan_cfg_get_tx_ring_near_full_mask(struct wlan_cfg_dp_soc_ctxt *cfg, + int context); /** * wlan_cfg_set_host2rxdma_mon_ring_mask() - Set host2rxdma monitor ring * interrupt mask for the given interrupt context