Browse Source

qcacld-3.0: Protect dfs_radar_found global variable using lock

qcacld-2.0 to qcacld-3.0 propagation

dfs_radar_found variable will be accessed in different context
so protect the same with mutex lock and synchronize the channel
switch triggered by application and dfs module.

Change-Id: I724d22cde9a77c187a17dffef13a9b4c9b2c27da
CRs-Fixed: 809527
Edhar, Mahesh Kumar 9 years ago
parent
commit
695468e069

+ 1 - 1
core/hdd/inc/wlan_hdd_cfg.h

@@ -3462,7 +3462,7 @@ bool hdd_is_okc_mode_enabled(hdd_context_t *pHddCtx);
 CDF_STATUS hdd_set_idle_ps_config(hdd_context_t *pHddCtx, uint32_t val);
 
 void hdd_update_tgt_cfg(void *context, void *param);
-void hdd_dfs_indicate_radar(void *context, void *param);
+bool hdd_dfs_indicate_radar(void *context, void *param);
 
 CDF_STATUS hdd_string_to_u8_array(char *str, uint8_t *intArray, uint8_t *len,
 				  uint8_t intArrayMaxLen);

+ 6 - 0
core/hdd/inc/wlan_hdd_main.h

@@ -1346,6 +1346,12 @@ struct hdd_context_s {
 
 	uint16_t hdd_txrx_hist_idx;
 	struct hdd_tx_rx_histogram hdd_txrx_hist[NUM_TX_RX_HISTOGRAM];
+	/*
+	 * Dfs lock used to syncronize on sap channel switch during
+	 * radar found indication and application triggered channel
+	 * switch.
+	 */
+	struct mutex dfs_lock;
 };
 
 /*---------------------------------------------------------------------------

+ 12 - 2
core/hdd/src/wlan_hdd_hostapd.c

@@ -955,7 +955,10 @@ CDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent,
 			}
 		}
 
+		mutex_lock(&pHddCtx->dfs_lock);
 		pHddCtx->dfs_radar_found = false;
+		mutex_unlock(&pHddCtx->dfs_lock);
+
 		wlansap_get_dfs_ignore_cac(pHddCtx->hHal, &ignoreCAC);
 
 		/* DFS requirement: DO NOT transmit during CAC. */
@@ -1062,6 +1065,10 @@ CDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent,
 		} else {
 			hdd_info("Sent CAC start to user space");
 		}
+
+		mutex_lock(&pHddCtx->dfs_lock);
+		pHddCtx->dfs_radar_found = false;
+		mutex_unlock(&pHddCtx->dfs_lock);
 		break;
 	case eSAP_DFS_CAC_INTERRUPTED:
 		/*
@@ -1927,7 +1934,9 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel)
 		}
 	}
 
+	mutex_lock(&pHddCtx->dfs_lock);
 	if (pHddCtx->dfs_radar_found == true) {
+		mutex_unlock(&pHddCtx->dfs_lock);
 		hddLog(LOGE, FL("Channel switch in progress!!"));
 		return -EBUSY;
 	}
@@ -1941,7 +1950,7 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel)
 	 * post eSAP_START_BSS_EVENT success event to HDD.
 	 */
 	pHddCtx->dfs_radar_found = true;
-
+	mutex_unlock(&pHddCtx->dfs_lock);
 	/*
 	 * Post the Channel Change request to SAP.
 	 */
@@ -1964,8 +1973,9 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel)
 		 * radar found flag and also restart the netif
 		 * queues.
 		 */
-
+		mutex_lock(&pHddCtx->dfs_lock);
 		pHddCtx->dfs_radar_found = false;
+		mutex_unlock(&pHddCtx->dfs_lock);
 
 		ret = -EINVAL;
 	}

+ 19 - 11
core/hdd/src/wlan_hdd_main.c

@@ -1227,9 +1227,9 @@ void hdd_update_tgt_cfg(void *context, void *param)
  * Actions: Stop the netif Tx queues,Indicate Radar present
  * in HDD context for future usage.
  *
- * Return: None
+ * Return: true to allow radar indication to host else false
  */
-void hdd_dfs_indicate_radar(void *context, void *param)
+bool hdd_dfs_indicate_radar(void *context, void *param)
 {
 	hdd_context_t *hdd_ctx = (hdd_context_t *) context;
 	struct wma_dfs_radar_ind *hdd_radar_event =
@@ -1238,17 +1238,23 @@ void hdd_dfs_indicate_radar(void *context, void *param)
 	hdd_adapter_t *adapter;
 	CDF_STATUS status;
 
-	if (hdd_ctx == NULL)
-		return;
-
-	if (hdd_radar_event == NULL)
-		return;
-
-	if (hdd_ctx->config->disableDFSChSwitch)
-		return;
+	if (!hdd_ctx || !hdd_radar_event ||
+		 hdd_ctx->config->disableDFSChSwitch)
+		return true;
 
 	if (true == hdd_radar_event->dfs_radar_status) {
+		mutex_lock(&hdd_ctx->dfs_lock);
+		if (hdd_ctx->dfs_radar_found) {
+			/*
+			 * Application already triggered channel switch
+			 * on current channel, so return here.
+			 */
+			mutex_unlock(&hdd_ctx->dfs_lock);
+			return false;
+		}
+
 		hdd_ctx->dfs_radar_found = true;
+		mutex_unlock(&hdd_ctx->dfs_lock);
 
 		status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
 		while (NULL != adapterNode && CDF_STATUS_SUCCESS == status) {
@@ -1265,6 +1271,8 @@ void hdd_dfs_indicate_radar(void *context, void *param)
 			adapterNode = pNext;
 		}
 	}
+
+	return true;
 }
 #endif
 
@@ -4771,7 +4779,7 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc)
 	 */
 	mutex_init(&hdd_ctx->tdls_lock);
 #endif
-
+	mutex_init(&hdd_ctx->dfs_lock);
 	/* store target type and target version info in hdd ctx */
 	hdd_ctx->target_type = ((struct ol_softc *)hif_sc)->target_type;
 	hdd_init_offloaded_packets_ctx(hdd_ctx);

+ 3 - 0
core/sap/src/sap_module.c

@@ -1520,6 +1520,9 @@ wlansap_set_channel_change_with_csa(void *p_cds_gctx, uint32_t targetChannel)
 			 * request was issued.
 			 */
 			pMac->sap.SapDfsInfo.sap_radar_found_status = true;
+			pMac->sap.SapDfsInfo.cac_state =
+					eSAP_DFS_DO_NOT_SKIP_CAC;
+			sap_cac_reset_notify(hHal);
 
 			/*
 			 * Post the eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START

+ 1 - 1
core/wma/inc/wma_types.h

@@ -585,7 +585,7 @@ typedef void (*wma_tgt_cfg_cb)(void *context, void *param);
  * to stop accepting data Tx packets from netif as radar is
  * found on the current operating channel
  */
-typedef void (*wma_dfs_radar_indication_cb)(void *context, void *param);
+typedef bool (*wma_dfs_radar_indication_cb)(void *context, void *param);
 
 /**
  * struct wma_cli_set_cmd_t - set command parameters

+ 12 - 2
core/wma/src/wma_features.c

@@ -7029,6 +7029,7 @@ int wma_dfs_indicate_radar(struct ieee80211com *ic,
 	struct wma_dfs_radar_indication *radar_event;
 	struct wma_dfs_radar_ind wma_radar_event;
 	tpAniSirGlobal pmac = NULL;
+	bool indication_status;
 
 	wma = cds_get_context(CDF_MODULE_ID_WMA);
 	if (wma == NULL) {
@@ -7069,12 +7070,21 @@ int wma_dfs_indicate_radar(struct ieee80211com *ic,
 	    (pmac->sap.SapDfsInfo.disable_dfs_ch_switch == true)) {
 		wma->dfs_ic->last_radar_found_chan = ichan->ic_ieee;
 		/* Indicate the radar event to HDD to stop the netif Tx queues */
-		wma_radar_event.ieee_chan_number = ichan->ic_ieee;
 		wma_radar_event.chan_freq = ichan->ic_freq;
 		wma_radar_event.dfs_radar_status = WMA_DFS_RADAR_FOUND;
-		wma->dfs_radar_indication_cb(hdd_ctx, &wma_radar_event);
+		indication_status =
+			wma->dfs_radar_indication_cb(hdd_ctx, &wma_radar_event);
+		if (indication_status == false) {
+			WMA_LOGE("%s:Application triggered channel switch in progress!.. drop radar event indiaction to SAP",
+				__func__);
+			cdf_mem_free(radar_event);
+			cdf_spin_unlock_bh(&ic->chan_lock);
+			return 0;
+		}
+
 		WMA_LOGE("%s:DFS- RADAR INDICATED TO HDD", __func__);
 
+		wma_radar_event.ieee_chan_number = ichan->ic_ieee;
 		/*
 		 * Indicate to the radar event to SAP to
 		 * select a new channel and set CSA IE