Procházet zdrojové kódy

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
Nandha Kishore Easwaran před 7 roky
rodič
revize
82ac62ecca
3 změnil soubory, kde provedl 95 přidání a 9 odebrání
  1. 6 8
      dp/wifi3.0/dp_main.c
  2. 77 0
      wlan_cfg/wlan_cfg.c
  3. 12 1
      wlan_cfg/wlan_cfg.h

+ 6 - 8
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;

+ 77 - 0
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];

+ 12 - 1
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