From 695468e069fe3161f317341d0d028d3bf902da79 Mon Sep 17 00:00:00 2001 From: "Edhar, Mahesh Kumar" Date: Mon, 19 Oct 2015 12:06:20 +0530 Subject: [PATCH] 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 --- core/hdd/inc/wlan_hdd_cfg.h | 2 +- core/hdd/inc/wlan_hdd_main.h | 6 ++++++ core/hdd/src/wlan_hdd_hostapd.c | 14 ++++++++++++-- core/hdd/src/wlan_hdd_main.c | 30 +++++++++++++++++++----------- core/sap/src/sap_module.c | 3 +++ core/wma/inc/wma_types.h | 2 +- core/wma/src/wma_features.c | 14 ++++++++++++-- 7 files changed, 54 insertions(+), 17 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index ae1a7c01da15..90a14b49ea72 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/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); diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 61a5f786ba22..dbe70b7da274 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/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; }; /*--------------------------------------------------------------------------- diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 30425346521f..658c636eb9d5 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/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; } diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 15aa4834ccf5..da721d1316f2 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/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); diff --git a/core/sap/src/sap_module.c b/core/sap/src/sap_module.c index dd4d05fd4ecf..8fe4ccb60d22 100644 --- a/core/sap/src/sap_module.c +++ b/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 diff --git a/core/wma/inc/wma_types.h b/core/wma/inc/wma_types.h index 5f0a1883caa9..17caf8f1de75 100644 --- a/core/wma/inc/wma_types.h +++ b/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 diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c index c1e7df5054bc..3a0ca154f4f3 100644 --- a/core/wma/src/wma_features.c +++ b/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