From c983d7ee09ab3f02915f79aeafbd9ec7d69f9752 Mon Sep 17 00:00:00 2001 From: psimha Date: Wed, 26 Jul 2017 15:20:07 -0700 Subject: [PATCH] qcacmn: Use interrupt polling only for monitor mode Add logic to use MSI interrupts for mission & polling for monitor mode Change-Id: Ieb824c2eb370040a125f743ec699954bdca9c83d CRs-Fixed: 2051911 --- dp/wifi3.0/dp_main.c | 100 +++++++++++++++++++++--------------- dp/wifi3.0/dp_rx_mon_dest.c | 2 +- dp/wifi3.0/dp_types.h | 16 +++++- 3 files changed, 74 insertions(+), 44 deletions(-) diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index bfeac0311f90..66b66d5b405f 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -341,7 +341,19 @@ static int dp_srng_setup(struct dp_soc *soc, struct dp_srng *srng, (unsigned long)srng->base_vaddr_unaligned); ring_params.num_entries = num_entries; - dp_srng_msi_setup(soc, &ring_params, ring_type, ring_num); + if (soc->intr_mode == DP_INTR_MSI) { + dp_srng_msi_setup(soc, &ring_params, ring_type, ring_num); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + FL("Using MSI for ring_type: %d, ring_num %d"), + ring_type, ring_num); + + } else { + ring_params.msi_data = 0; + ring_params.msi_addr = 0; + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + FL("Skipping MSI for ring_type: %d, ring_num %d"), + ring_type, ring_num); + } /* * Setup interrupt timer and batch counter thresholds for @@ -525,6 +537,7 @@ budget_done: return dp_budget - budget; } +#ifdef DP_INTR_POLL_BASED /* dp_interrupt_timer()- timer poll for interrupts * * @arg: SoC Handle @@ -532,7 +545,6 @@ budget_done: * Return: * */ -#ifdef DP_INTR_POLL_BASED static void dp_interrupt_timer(void *arg) { struct dp_soc *soc = (struct dp_soc *) arg; @@ -548,7 +560,7 @@ static void dp_interrupt_timer(void *arg) } /* - * dp_soc_interrupt_attach() - Register handlers for DP interrupts + * dp_soc_interrupt_attach_poll() - Register handlers for DP interrupts * @txrx_soc: DP SOC handle * * Host driver will register for “DP_NUM_INTERRUPT_CONTEXTS” number of NAPI @@ -557,11 +569,13 @@ static void dp_interrupt_timer(void *arg) * * Return: 0 for success. nonzero for failure. */ -static QDF_STATUS dp_soc_interrupt_attach(void *txrx_soc) +static QDF_STATUS dp_soc_interrupt_attach_poll(void *txrx_soc) { struct dp_soc *soc = (struct dp_soc *)txrx_soc; int i; + soc->intr_mode = DP_INTR_POLL; + for (i = 0; i < wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx); i++) { soc->intr_ctx[i].dp_intr_id = i; soc->intr_ctx[i].tx_ring_mask = 0xF; @@ -582,32 +596,38 @@ static QDF_STATUS dp_soc_interrupt_attach(void *txrx_soc) return QDF_STATUS_SUCCESS; } +#ifdef CONFIG_MCL +extern int con_mode_monitor; +static QDF_STATUS dp_soc_interrupt_attach(void *txrx_soc); + /* - * dp_soc_interrupt_detach() - Deregister any allocations done for interrupts + * dp_soc_interrupt_attach_wrapper() - Register handlers for DP interrupts * @txrx_soc: DP SOC handle * - * Return: void + * Call the appropriate attach function based on the mode of operation. + * This is a WAR for enabling monitor mode. + * + * Return: 0 for success. nonzero for failure. */ -static void dp_soc_interrupt_detach(void *txrx_soc) +static QDF_STATUS dp_soc_interrupt_attach_wrapper(void *txrx_soc) { - struct dp_soc *soc = (struct dp_soc *)txrx_soc; - int i; - - qdf_timer_stop(&soc->int_timer); - - qdf_timer_free(&soc->int_timer); - - for (i = 0; i < wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx); i++) { - soc->intr_ctx[i].tx_ring_mask = 0; - soc->intr_ctx[i].rx_ring_mask = 0; - soc->intr_ctx[i].rx_mon_ring_mask = 0; - soc->intr_ctx[i].rx_err_ring_mask = 0; - soc->intr_ctx[i].rx_wbm_rel_ring_mask = 0; - soc->intr_ctx[i].reo_status_ring_mask = 0; - qdf_lro_deinit(soc->intr_ctx[i].lro_ctx); + if (con_mode_monitor == QDF_GLOBAL_MONITOR_MODE) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + FL("Attach interrupts in Poll mode")); + return dp_soc_interrupt_attach_poll(txrx_soc); + } else { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + FL("Attach interrupts in MSI mode")); + return dp_soc_interrupt_attach(txrx_soc); } } #else +static QDF_STATUS dp_soc_interrupt_attach_wrapper(void *txrx_soc) +{ + return dp_soc_interrupt_attach_poll(txrx_soc); +} +#endif +#endif static void dp_soc_interrupt_map_calculate_integrated(struct dp_soc *soc, int intr_ctx_num, int *irq_id_map, int *num_irq_r) @@ -678,6 +698,8 @@ static void dp_soc_interrupt_map_calculate_msi(struct dp_soc *soc, (intr_ctx_num % msi_vector_count) + msi_vector_start; int num_irq = 0; + soc->intr_mode = DP_INTR_MSI; + if (tx_mask | rx_mask | rx_mon_mask | rx_err_ring_mask | rx_wbm_rel_ring_mask | reo_status_ring_mask) irq_id_map[num_irq++] = @@ -723,7 +745,6 @@ static QDF_STATUS dp_soc_interrupt_attach(void *txrx_soc) int i = 0; int num_irq = 0; - for (i = 0; i < wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx); i++) { int ret = 0; @@ -791,6 +812,11 @@ static void dp_soc_interrupt_detach(void *txrx_soc) struct dp_soc *soc = (struct dp_soc *)txrx_soc; int i; + if (soc->intr_mode == DP_INTR_POLL) { + qdf_timer_stop(&soc->int_timer); + qdf_timer_free(&soc->int_timer); + } + for (i = 0; i < wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx); i++) { soc->intr_ctx[i].tx_ring_mask = 0; soc->intr_ctx[i].rx_ring_mask = 0; @@ -802,7 +828,6 @@ static void dp_soc_interrupt_detach(void *txrx_soc) qdf_lro_deinit(soc->intr_ctx[i].lro_ctx); } } -#endif #define AVG_MAX_MPDUS_PER_TID 128 #define AVG_TIDS_PER_CLIENT 2 @@ -2224,12 +2249,11 @@ static struct cdp_vdev *dp_vdev_attach_wifi3(struct cdp_pdev *txrx_pdev, goto fail1; -#ifdef DP_INTR_POLL_BASED - if (wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx) != 0) { + if ((soc->intr_mode == DP_INTR_POLL) && + wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx) != 0) { if (pdev->vdev_count == 1) qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS); } -#endif dp_lro_hash_setup(soc); @@ -4410,7 +4434,11 @@ static struct cdp_cmn_ops dp_ops_cmn = { .display_stats = dp_txrx_dump_stats, .txrx_soc_set_nss_cfg = dp_soc_set_nss_cfg_wifi3, .txrx_soc_get_nss_cfg = dp_soc_get_nss_cfg_wifi3, +#ifdef DP_INTR_POLL_BASED + .txrx_intr_attach = dp_soc_interrupt_attach_wrapper, +#else .txrx_intr_attach = dp_soc_interrupt_attach, +#endif .txrx_intr_detach = dp_soc_interrupt_detach, .set_pn_check = dp_set_pn_check_wifi3, /* TODO: Add other functions */ @@ -4472,13 +4500,13 @@ static struct cdp_pflow_ops dp_ops_pflow = { }; #endif /* CONFIG_WIN */ -#ifdef DP_INTR_POLL_BASED static QDF_STATUS dp_bus_suspend(struct cdp_pdev *opaque_pdev) { struct dp_pdev *pdev = (struct dp_pdev *)opaque_pdev; struct dp_soc *soc = pdev->soc; - qdf_timer_stop(&soc->int_timer); + if (soc->intr_mode == DP_INTR_POLL) + qdf_timer_stop(&soc->int_timer); return QDF_STATUS_SUCCESS; } @@ -4488,21 +4516,11 @@ static QDF_STATUS dp_bus_resume(struct cdp_pdev *opaque_pdev) struct dp_pdev *pdev = (struct dp_pdev *)opaque_pdev; struct dp_soc *soc = pdev->soc; - qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS); + if (soc->intr_mode == DP_INTR_POLL) + qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS); return QDF_STATUS_SUCCESS; } -#else -static QDF_STATUS dp_bus_suspend(struct cdp_pdev *opaque_pdev) -{ - return QDF_STATUS_SUCCESS; -} - -static QDF_STATUS dp_bus_resume(struct cdp_pdev *opaque_pdev) -{ - return QDF_STATUS_SUCCESS; -} -#endif /* DP_INTR_POLL_BASED */ #ifndef CONFIG_WIN static struct cdp_misc_ops dp_ops_misc = { diff --git a/dp/wifi3.0/dp_rx_mon_dest.c b/dp/wifi3.0/dp_rx_mon_dest.c index b77ae63284ec..41e5e8905639 100644 --- a/dp/wifi3.0/dp_rx_mon_dest.c +++ b/dp/wifi3.0/dp_rx_mon_dest.c @@ -742,7 +742,7 @@ void dp_rx_mon_dest_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) pdev_id = pdev->pdev_id; mon_dst_srng = pdev->rxdma_mon_dst_ring.hal_srng; - if (!mon_dst_srng || hal_srng_initialized(mon_dst_srng)) { + if (!mon_dst_srng || !hal_srng_initialized(mon_dst_srng)) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, "%s %d : HAL Monitor Destination Ring Init Failed -- %p\n", __func__, __LINE__, mon_dst_srng); diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 94e96fbf1e67..fea0eb91ca9d 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -147,6 +147,18 @@ union dp_rx_desc_list_elem_t; #define DP_HW2SW_MACID(id) ((id) > 0 ? ((id) - 1) : 0) #define DP_MAC_ADDR_LEN 6 +/** + * enum dp_intr_mode + * @DP_INTR_LEGACY: Legacy/Line interrupts, for WIN + * @DP_INTR_MSI: MSI interrupts, for MCL + * @DP_INTR_POLL: Polling + */ +enum dp_intr_mode { + DP_INTR_LEGACY = 0, + DP_INTR_MSI, + DP_INTR_POLL, +}; + /** * enum dp_tx_frm_type * @dp_tx_frm_std: Regular frame, no added header fragments @@ -722,10 +734,10 @@ struct dp_soc { qdf_spinlock_t ast_lock; qdf_timer_t wds_aging_timer; -#ifdef DP_INTR_POLL_BASED /*interrupt timer*/ qdf_timer_t int_timer; -#endif + uint8_t intr_mode; + qdf_list_t reo_desc_freelist; qdf_spinlock_t reo_desc_freelist_lock; struct mect_entry mect_table[DP_MAX_MECT_ENTRIES];