From 82ac62eccafd70f2e3e92959cebd2a09ebaf8bf9 Mon Sep 17 00:00:00 2001 From: Nandha Kishore Easwaran Date: Tue, 20 Jun 2017 17:55:07 +0530 Subject: [PATCH] qcacmn: Fix double free irq of external group interrupts The irq entry for rx_err, rx_wdm_release, and reo_status gets assigned for more than one context and this causes double free irq during driver unload time. Fix the same Change-Id: I197ee285e6eba5909dec3fa37677c13efce4765a CRs-fixed: 2063981 --- dp/wifi3.0/dp_main.c | 14 ++++---- wlan_cfg/wlan_cfg.c | 77 ++++++++++++++++++++++++++++++++++++++++++++ wlan_cfg/wlan_cfg.h | 13 +++++++- 3 files changed, 95 insertions(+), 9 deletions(-) diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 9c31016e9037..9e6b3132674e 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -421,14 +421,12 @@ static QDF_STATUS dp_soc_interrupt_attach(void *txrx_soc) wlan_cfg_get_rx_ring_mask(soc->wlan_cfg_ctx, i); int rx_mon_mask = wlan_cfg_get_rx_mon_ring_mask(soc->wlan_cfg_ctx, i); - - /* - * Mapping the exception/status rings to IRQ Group 0 (CPU 0). - * Later add wlan_cfg interface for these masks - */ - int rx_err_ring_mask = 0x1; - int rx_wbm_rel_ring_mask = 0x1; - int reo_status_ring_mask = 0x1; + int rx_err_ring_mask = + wlan_cfg_get_rx_err_ring_mask(soc->wlan_cfg_ctx, i); + int rx_wbm_rel_ring_mask = + wlan_cfg_get_rx_wbm_rel_ring_mask(soc->wlan_cfg_ctx, i); + int reo_status_ring_mask = + wlan_cfg_get_reo_status_ring_mask(soc->wlan_cfg_ctx, i); soc->intr_ctx[i].tx_ring_mask = tx_mask; soc->intr_ctx[i].rx_ring_mask = rx_mask; diff --git a/wlan_cfg/wlan_cfg.c b/wlan_cfg/wlan_cfg.c index 72a6a341af9d..6009e0573cc7 100644 --- a/wlan_cfg/wlan_cfg.c +++ b/wlan_cfg/wlan_cfg.c @@ -65,6 +65,21 @@ #define WLAN_CFG_RX_MON_RING_MASK_2 0x4 #define WLAN_CFG_RX_MON_RING_MASK_3 0x0 +#define WLAN_CFG_RX_ERR_RING_MASK_0 0x1 +#define WLAN_CFG_RX_ERR_RING_MASK_1 0x0 +#define WLAN_CFG_RX_ERR_RING_MASK_2 0x0 +#define WLAN_CFG_RX_ERR_RING_MASK_3 0x0 + +#define WLAN_CFG_RX_WBM_REL_RING_MASK_0 0x1 +#define WLAN_CFG_RX_WBM_REL_RING_MASK_1 0x0 +#define WLAN_CFG_RX_WBM_REL_RING_MASK_2 0x0 +#define WLAN_CFG_RX_WBM_REL_RING_MASK_3 0x0 + +#define WLAN_CFG_REO_STATUS_RING_MASK_0 0x1 +#define WLAN_CFG_REO_STATUS_RING_MASK_1 0x0 +#define WLAN_CFG_REO_STATUS_RING_MASK_2 0x0 +#define WLAN_CFG_REO_STATUS_RING_MASK_3 0x0 + #define WLAN_CFG_DP_TX_NUM_POOLS 3 /* Change this to a lower value to enforce scattered idle list mode */ #define WLAN_CFG_MAX_ALLOC_SIZE (2 << 20) @@ -112,6 +127,24 @@ static const int rx_mon_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { WLAN_CFG_RX_MON_RING_MASK_2, WLAN_CFG_RX_MON_RING_MASK_3}; +static const int rx_err_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { + WLAN_CFG_RX_ERR_RING_MASK_0, + WLAN_CFG_RX_ERR_RING_MASK_1, + WLAN_CFG_RX_ERR_RING_MASK_2, + WLAN_CFG_RX_ERR_RING_MASK_3}; + +static const int rx_wbm_rel_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { + WLAN_CFG_RX_WBM_REL_RING_MASK_0, + WLAN_CFG_RX_WBM_REL_RING_MASK_1, + WLAN_CFG_RX_WBM_REL_RING_MASK_2, + WLAN_CFG_RX_WBM_REL_RING_MASK_3}; + +static const int reo_status_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = { + WLAN_CFG_REO_STATUS_RING_MASK_0, + WLAN_CFG_REO_STATUS_RING_MASK_1, + WLAN_CFG_REO_STATUS_RING_MASK_2, + WLAN_CFG_REO_STATUS_RING_MASK_3}; + /** * struct wlan_cfg_dp_soc_ctxt - Configuration parameters for SoC (core TxRx) * @num_int_ctxts - Number of NAPI/Interrupt contexts to be registered for DP @@ -156,6 +189,9 @@ struct wlan_cfg_dp_soc_ctxt { int int_rx_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS]; int int_rx_mon_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS]; int int_ce_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS]; + int int_rx_err_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS]; + int int_rx_wbm_rel_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS]; + int int_reo_status_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS]; bool lro_enabled; bool rx_hash; int nss_cfg; @@ -210,6 +246,11 @@ struct wlan_cfg_dp_soc_ctxt *wlan_cfg_soc_attach() wlan_cfg_ctx->int_tx_ring_mask[i] = tx_ring_mask[i]; wlan_cfg_ctx->int_rx_ring_mask[i] = rx_ring_mask[i]; wlan_cfg_ctx->int_rx_mon_ring_mask[i] = rx_mon_ring_mask[i]; + wlan_cfg_ctx->int_rx_err_ring_mask[i] = rx_err_ring_mask[i]; + wlan_cfg_ctx->int_rx_wbm_rel_ring_mask[i] = + rx_wbm_rel_ring_mask[i]; + wlan_cfg_ctx->int_reo_status_ring_mask[i] = + reo_status_ring_mask[i]; } wlan_cfg_ctx->rx_hash = WLAN_RX_HASH_ENABLE; @@ -285,6 +326,24 @@ void wlan_cfg_set_rxbuf_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, int context, cfg->int_rx_ring_mask[context] = mask; } +int wlan_cfg_set_rx_err_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, + int context, int mask) +{ + return cfg->int_rx_err_ring_mask[context] = mask; +} + +int wlan_cfg_set_rx_wbm_rel_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, + int context, int mask) +{ + return cfg->int_rx_wbm_rel_ring_mask[context] = mask; +} + +int wlan_cfg_set_reo_status_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, + int context, int mask) +{ + return cfg->int_reo_status_ring_mask[context] = mask; +} + int wlan_cfg_get_num_contexts(struct wlan_cfg_dp_soc_ctxt *cfg) { return cfg->num_int_ctxts; @@ -300,6 +359,24 @@ int wlan_cfg_get_rx_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, int context) return cfg->int_rx_ring_mask[context]; } +int wlan_cfg_get_rx_err_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, + int context) +{ + return cfg->int_rx_err_ring_mask[context]; +} + +int wlan_cfg_get_rx_wbm_rel_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, + int context) +{ + return cfg->int_rx_wbm_rel_ring_mask[context]; +} + +int wlan_cfg_get_reo_status_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, + int context) +{ + return cfg->int_reo_status_ring_mask[context]; +} + int wlan_cfg_get_rx_mon_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, int context) { return cfg->int_rx_mon_ring_mask[context]; diff --git a/wlan_cfg/wlan_cfg.h b/wlan_cfg/wlan_cfg.h index 9d63cb14d31c..350e088bdc65 100644 --- a/wlan_cfg/wlan_cfg.h +++ b/wlan_cfg/wlan_cfg.h @@ -106,9 +106,20 @@ void wlan_cfg_set_ce_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, int context, int mask); void wlan_cfg_set_rxbuf_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, int context, int mask); - void wlan_cfg_set_max_peer_id(struct wlan_cfg_dp_soc_ctxt *cfg, uint32_t val); +int wlan_cfg_set_rx_err_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, + int context, int mask); +int wlan_cfg_set_rx_wbm_rel_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, + int context, int mask); +int wlan_cfg_set_reo_status_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, + int context, int mask); +int wlan_cfg_get_rx_err_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, + int context); +int wlan_cfg_get_rx_wbm_rel_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, + int context); +int wlan_cfg_get_reo_status_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg, + int context); /** * wlan_cfg_get_num_contexts() - Number of interrupt contexts to be registered * @wlan_cfg_ctx - Configuration Handle