summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGanesh Kondabattini <ganeshk@codeaurora.org>2017-10-03 23:12:54 +0530
committerGanesh Kondabattini <ganeshk@codeaurora.org>2017-10-23 20:02:45 +0530
commitf11ae9be264664e7c6f7ec561042fe35deab56eb (patch)
treed00b8898ed1533b8fea90f5efa5e7378d8357696
parent310d50fbdc17da071ff86dd0a6a1a50ddd40eafc (diff)
qcacld-3.0: Skip CAC and ignore radar indication for SAP
If STA is already connected on DFS channel and SAP is going to start on the same channel then skip the CAC for SAP. If STA and SAP sessions are already operating on same DFS channel, then ignore radar indication received on SAP interface. CRs-Fixed: 2130000 Change-Id: Ife0ab6979a07c8773001a43f5a30c9a555dab37a
-rw-r--r--core/cds/inc/cds_api.h19
-rw-r--r--core/cds/inc/cds_concurrency.h3
-rw-r--r--core/cds/src/cds_api.c33
-rw-r--r--core/cds/src/cds_concurrency.c53
-rw-r--r--core/hdd/src/wlan_hdd_hostapd.c28
-rw-r--r--core/sap/src/sap_api_link_cntl.c17
-rw-r--r--core/sap/src/sap_fsm.c44
-rw-r--r--core/sap/src/sap_module.c8
8 files changed, 171 insertions, 34 deletions
diff --git a/core/cds/inc/cds_api.h b/core/cds/inc/cds_api.h
index d9e36a377298..fe5ba1891628 100644
--- a/core/cds/inc/cds_api.h
+++ b/core/cds/inc/cds_api.h
@@ -548,4 +548,23 @@ void cds_smmu_mem_map_setup(qdf_device_t osdev);
* Return: Status of map operation
*/
int cds_smmu_map_unmap(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr);
+
+/**
+ * cds_get_mcc_to_scc_switch_mode() - get mcc to scc swith mode
+ *
+ * Get the mcc to scc swith mode from ini
+ *
+ * Return: current mcc to scc swith mode
+ */
+uint32_t cds_get_mcc_to_scc_switch_mode(void);
+
+/**
+ * cds_is_sta_sap_scc_allowed_on_dfs_channel() - get the status sta, sap scc on
+ * dfs channel
+ *
+ * Get the status of sta, sap scc on dfs channel
+ *
+ * Return: true if sta, sap scc is allowed on dfs channel otherwise false
+ */
+bool cds_is_sta_sap_scc_allowed_on_dfs_channel(void);
#endif /* if !defined __CDS_API_H */
diff --git a/core/cds/inc/cds_concurrency.h b/core/cds/inc/cds_concurrency.h
index edc1561dd423..b71ec148ee04 100644
--- a/core/cds/inc/cds_concurrency.h
+++ b/core/cds/inc/cds_concurrency.h
@@ -885,6 +885,9 @@ void cds_dump_connection_status_info(void);
uint32_t cds_mode_specific_vdev_id(enum cds_con_mode mode);
uint32_t cds_mode_specific_connection_count(enum cds_con_mode mode,
uint32_t *list);
+
+uint8_t cds_mode_specific_get_channel(enum cds_con_mode mode);
+
/**
* cds_check_conn_with_mode_and_vdev_id() - checks if any active
* session with specific mode and vdev_id
diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c
index e4a50629d0bf..51a0181d2164 100644
--- a/core/cds/src/cds_api.c
+++ b/core/cds/src/cds_api.c
@@ -2851,3 +2851,36 @@ int cds_smmu_map_unmap(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr)
return 0;
}
#endif
+
+uint32_t cds_get_mcc_to_scc_switch_mode(void)
+{
+ hdd_context_t *hdd_ctx;
+
+ hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+ if (!hdd_ctx) {
+ cds_err("HDD context is NULL");
+ return false;
+ }
+
+ return hdd_ctx->config->WlanMccToSccSwitchMode;
+}
+
+bool cds_is_sta_sap_scc_allowed_on_dfs_channel(void)
+{
+ hdd_context_t *hdd_ctx;
+ bool ret = false;
+
+ hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+
+ if (!hdd_ctx) {
+ cds_err("HDD context is NULL");
+ return false;
+ }
+
+ if ((hdd_ctx->config->WlanMccToSccSwitchMode !=
+ QDF_MCC_TO_SCC_SWITCH_DISABLE) &&
+ (hdd_ctx->config->sta_sap_scc_on_dfs_chan))
+ ret = true;
+
+ return ret;
+}
diff --git a/core/cds/src/cds_concurrency.c b/core/cds/src/cds_concurrency.c
index 0ec4035c0a1b..630add0fceda 100644
--- a/core/cds/src/cds_concurrency.c
+++ b/core/cds/src/cds_concurrency.c
@@ -2263,7 +2263,7 @@ uint32_t cds_mode_specific_vdev_id(enum cds_con_mode mode)
return vdev_id;
}
-static uint8_t cds_mode_specific_get_channel(enum cds_con_mode mode)
+uint8_t cds_mode_specific_get_channel(enum cds_con_mode mode)
{
uint32_t conn_index;
uint8_t channel = 0;
@@ -5046,8 +5046,9 @@ void cds_remove_dfs_passive_channels_from_pcl(uint8_t *pcl_channels,
uint32_t orig_channel_count = 0;
qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
hdd_context_t *hdd_ctx;
- uint32_t mcc_to_scc_mode;
+ bool sta_sap_scc_on_dfs_chan;
uint32_t sap_count;
+ enum channel_state channel_state;
hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
if (!hdd_ctx) {
@@ -5060,14 +5061,13 @@ void cds_remove_dfs_passive_channels_from_pcl(uint8_t *pcl_channels,
return;
}
- mcc_to_scc_mode = hdd_ctx->config->WlanMccToSccSwitchMode;
+ sta_sap_scc_on_dfs_chan = cds_is_sta_sap_scc_allowed_on_dfs_channel();
sap_count = cds_mode_specific_connection_count(CDS_SAP_MODE, NULL);
- cds_debug("mcc_to_scc_mode %u, sap_count %u", mcc_to_scc_mode,
- sap_count);
+ cds_debug("sta_sap_scc_on_dfs_chan %u, sap_count %u",
+ sta_sap_scc_on_dfs_chan, sap_count);
- if ((mcc_to_scc_mode == QDF_MCC_TO_SCC_SWITCH_DISABLE) ||
- (sap_count == 0))
+ if (!sta_sap_scc_on_dfs_chan || !sap_count)
return;
if (len)
@@ -5080,11 +5080,12 @@ void cds_remove_dfs_passive_channels_from_pcl(uint8_t *pcl_channels,
cds_debug("Set weight of DFS/passive channels to 0");
for (i = 0; i < orig_channel_count; i++) {
- if (cds_get_channel_state(pcl_channels[i]) !=
- CHANNEL_STATE_ENABLE) {
+ channel_state = cds_get_channel_state(pcl_channels[i]);
+ if ((channel_state == CHANNEL_STATE_DISABLE) ||
+ (channel_state == CHANNEL_STATE_INVALID))
/* Set weight of inactive channels to 0 */
weight_list[i] = 0;
- }
+
cds_debug("chan[%d] - %d, weight[%d] - %d",
i, pcl_channels[i], i, weight_list[i]);
}
@@ -5123,6 +5124,7 @@ static QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl,
bool skip_dfs_channel = false;
hdd_context_t *hdd_ctx;
uint32_t i = 0, j = 0;
+ bool sta_sap_scc_on_dfs_chan;
hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
if (!hdd_ctx) {
@@ -5157,8 +5159,12 @@ static QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl,
* if you have atleast one STA connection then don't fill DFS channels
* in the preferred channel list
*/
- if (((mode == CDS_SAP_MODE) || (mode == CDS_P2P_GO_MODE)) &&
- (cds_mode_specific_connection_count(CDS_STA_MODE, NULL) > 0)) {
+ sta_sap_scc_on_dfs_chan = cds_is_sta_sap_scc_allowed_on_dfs_channel();
+ cds_debug("sta_sap_scc_on_dfs_chan %u", sta_sap_scc_on_dfs_chan);
+
+ if ((((mode == CDS_SAP_MODE) || (mode == CDS_P2P_GO_MODE)) &&
+ (cds_mode_specific_connection_count(CDS_STA_MODE, NULL) > 0)) ||
+ !sta_sap_scc_on_dfs_chan) {
cds_debug("STA present, skip DFS channels from pcl for SAP/Go");
skip_dfs_channel = true;
}
@@ -5891,6 +5897,8 @@ bool cds_allow_concurrency(enum cds_con_mode mode,
cds_context_type *cds_ctx;
QDF_STATUS ret;
struct sir_pcl_list pcl;
+ bool is_sta_sap_on_dfs_chan;
+
hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
if (!hdd_ctx) {
@@ -5948,7 +5956,10 @@ bool cds_allow_concurrency(enum cds_con_mode mode,
if (!cds_is_5g_channel_allowed(channel, list, CDS_SAP_MODE))
goto done;
- if ((CDS_P2P_GO_MODE == mode) || (CDS_SAP_MODE == mode)) {
+ is_sta_sap_on_dfs_chan =
+ cds_is_sta_sap_scc_allowed_on_dfs_channel();
+ if (!is_sta_sap_on_dfs_chan && ((mode == CDS_P2P_GO_MODE) ||
+ (mode == CDS_SAP_MODE))) {
if (CDS_IS_DFS_CH(channel))
match = cds_disallow_mcc(channel);
}
@@ -10521,10 +10532,11 @@ uint8_t cds_get_cur_conc_system_pref(void)
*/
bool cds_is_valid_channel_for_channel_switch(uint8_t channel)
{
- uint32_t mcc_to_scc_mode;
+ bool sta_sap_scc_on_dfs_chan;
uint32_t sap_count;
enum channel_state state;
hdd_context_t *hdd_ctx;
+ bool is_safe;
hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
@@ -10533,16 +10545,17 @@ bool cds_is_valid_channel_for_channel_switch(uint8_t channel)
return true;
}
- mcc_to_scc_mode = hdd_ctx->config->WlanMccToSccSwitchMode;
+ sta_sap_scc_on_dfs_chan = cds_is_sta_sap_scc_allowed_on_dfs_channel();
sap_count = cds_mode_specific_connection_count(CDS_SAP_MODE, NULL);
state = cds_get_channel_state(channel);
+ is_safe = cds_is_safe_channel(channel);
- cds_debug("mcc_to_scc_mode %u, sap_count %u, channel %u, state %u",
- mcc_to_scc_mode, sap_count, channel, state);
+ cds_debug("is_safe %u, sta_sap_scc_on_dfs_chan %u, sap_count %u, channel %u, state %u",
+ is_safe, sta_sap_scc_on_dfs_chan, sap_count, channel,
+ state);
- if ((state == CHANNEL_STATE_ENABLE) ||
- (mcc_to_scc_mode == QDF_MCC_TO_SCC_SWITCH_DISABLE) ||
- (sap_count == 0)) {
+ if (is_safe && ((state == CHANNEL_STATE_ENABLE) || (sap_count == 0) ||
+ ((state == CHANNEL_STATE_DFS) && sta_sap_scc_on_dfs_chan))) {
cds_debug("Valid channel for channel switch");
return true;
}
diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c
index 72949479c9fd..53bf9edf64e7 100644
--- a/core/hdd/src/wlan_hdd_hostapd.c
+++ b/core/hdd/src/wlan_hdd_hostapd.c
@@ -7725,6 +7725,7 @@ int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
uint16_t prev_rsn_length = 0;
enum dfs_mode mode;
bool disable_fw_tdls_state = false;
+ uint8_t ignore_cac = 0;
ENTER();
@@ -7865,7 +7866,15 @@ int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
goto error;
}
}
- wlansap_set_dfs_ignore_cac(hHal, iniConfig->ignoreCAC);
+
+ if (iniConfig->ignoreCAC ||
+ ((iniConfig->WlanMccToSccSwitchMode !=
+ QDF_MCC_TO_SCC_SWITCH_DISABLE) &&
+ iniConfig->sta_sap_scc_on_dfs_chan))
+ ignore_cac = 1;
+
+ wlansap_set_dfs_ignore_cac(hHal, ignore_cac);
+
wlansap_set_dfs_restrict_japan_w53(hHal,
iniConfig->gDisableDfsJapanW53);
wlansap_set_dfs_preferred_channel_location(hHal,
@@ -8708,6 +8717,8 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
int status;
struct sme_sta_inactivity_timeout *sta_inactivity_timer;
uint8_t channel;
+ bool sta_sap_scc_on_dfs_chan;
+ uint16_t sta_cnt;
ENTER();
@@ -8752,6 +8763,21 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
channel = ieee80211_frequency_to_channel(
params->chandef.chan->center_freq);
+ sta_sap_scc_on_dfs_chan = cds_is_sta_sap_scc_allowed_on_dfs_channel();
+ sta_cnt = cds_mode_specific_connection_count(CDS_STA_MODE, NULL);
+
+ hdd_debug("sta_sap_scc_on_dfs_chan %u, sta_cnt %u",
+ sta_sap_scc_on_dfs_chan, sta_cnt);
+
+ /* if sta_sap_scc_on_dfs_chan ini is set, DFS master capability is
+ * assumed disabled in the driver.
+ */
+ if (channel && (cds_get_channel_state(channel) == CHANNEL_STATE_DFS) &&
+ sta_sap_scc_on_dfs_chan && !sta_cnt) {
+ hdd_err("SAP not allowed on DFS channel!!");
+ return -EINVAL;
+ }
+
if (cds_is_sap_mandatory_chan_list_enabled()) {
if (!cds_get_sap_mandatory_chan_list_len())
cds_init_sap_mandatory_2g_chan();
diff --git a/core/sap/src/sap_api_link_cntl.c b/core/sap/src/sap_api_link_cntl.c
index eeb60d6b7ab1..b3f4f3132d60 100644
--- a/core/sap/src/sap_api_link_cntl.c
+++ b/core/sap/src/sap_api_link_cntl.c
@@ -54,6 +54,7 @@
/* SAP Internal API header file */
#include "sap_internal.h"
#include "cds_concurrency.h"
+#include "cds_api.h"
#include "wma.h"
/*----------------------------------------------------------------------------
@@ -876,6 +877,8 @@ wlansap_roam_callback(void *ctx, tCsrRoamInfo *csr_roam_info, uint32_t roamId,
tHalHandle hal;
tpAniSirGlobal mac_ctx = NULL;
uint8_t intf;
+ bool sta_sap_scc_on_dfs_chan;
+
if (QDF_IS_STATUS_ERROR(wlansap_context_get((ptSapContext)ctx)))
return QDF_STATUS_E_FAILURE;
@@ -892,6 +895,9 @@ wlansap_roam_callback(void *ctx, tCsrRoamInfo *csr_roam_info, uint32_t roamId,
mac_ctx = PMAC_STRUCT(hal);
QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
FL("Before switch on roam_status = %d"), roam_status);
+
+ sta_sap_scc_on_dfs_chan = cds_is_sta_sap_scc_allowed_on_dfs_channel();
+
switch (roam_status) {
case eCSR_ROAM_SESSION_OPENED:
QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
@@ -981,6 +987,13 @@ wlansap_roam_callback(void *ctx, tCsrRoamInfo *csr_roam_info, uint32_t roamId,
QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
FL("Received Radar Indication"));
+ if (sta_sap_scc_on_dfs_chan) {
+ QDF_TRACE(QDF_MODULE_ID_SAP,
+ QDF_TRACE_LEVEL_INFO_HIGH,
+ FL("Ignore the Radar indication"));
+ break;
+ }
+
if (sap_ctx->is_pre_cac_on) {
QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
FL("sapdfs: Radar detect on pre cac:%d"),
@@ -1251,8 +1264,10 @@ wlansap_roam_callback(void *ctx, tCsrRoamInfo *csr_roam_info, uint32_t roamId,
break;
case eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND:
+ if (sta_sap_scc_on_dfs_chan)
+ break;
wlansap_roam_process_dfs_radar_found(mac_ctx, sap_ctx,
- &qdf_ret_status);
+ &qdf_ret_status);
break;
case eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS:
wlansap_roam_process_dfs_chansw_update(hal, sap_ctx,
diff --git a/core/sap/src/sap_fsm.c b/core/sap/src/sap_fsm.c
index fa268c01aad3..c45834510b1a 100644
--- a/core/sap/src/sap_fsm.c
+++ b/core/sap/src/sap_fsm.c
@@ -2293,6 +2293,7 @@ QDF_STATUS sap_goto_channel_sel(ptSapContext sap_context,
#endif
tHalHandle h_hal;
uint8_t con_ch;
+ bool sta_sap_scc_on_dfs_chan;
h_hal = cds_get_context(QDF_MODULE_ID_SME);
if (NULL == h_hal) {
@@ -2383,11 +2384,20 @@ QDF_STATUS sap_goto_channel_sel(ptSapContext sap_context,
FL("SAP can't start (no MCC)"));
return QDF_STATUS_E_ABORTED;
}
- if (con_ch && !CDS_IS_DFS_CH(con_ch)) {
+
+ sta_sap_scc_on_dfs_chan =
+ cds_is_sta_sap_scc_allowed_on_dfs_channel();
+
+ if (con_ch && cds_is_safe_channel(con_ch) &&
+ (!CDS_IS_DFS_CH(con_ch) ||
+ (CDS_IS_DFS_CH(con_ch) &&
+ sta_sap_scc_on_dfs_chan))) {
+
QDF_TRACE(QDF_MODULE_ID_SAP,
- QDF_TRACE_LEVEL_ERROR,
- "%s: Override ch %d to %d due to CC Intf",
- __func__, sap_context->channel, con_ch);
+ QDF_TRACE_LEVEL_ERROR,
+ "%s: Override ch %d to %d due to CC Intf",
+ __func__, sap_context->channel,
+ con_ch);
sap_context->channel = con_ch;
cds_set_channel_params(sap_context->channel, 0,
&sap_context->ch_params);
@@ -4043,9 +4053,9 @@ static QDF_STATUS sap_fsm_state_starting(ptSapContext sap_ctx,
* (both without substates)
*/
QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
- FL("from state channel = %d %s => %s ch_width %d"),
- sap_ctx->channel, "eSAP_STARTING", "eSAP_STARTED",
- sap_ctx->ch_params.ch_width);
+ FL("from state channel = %d %s => %s ch_width %d"),
+ sap_ctx->channel, "eSAP_STARTING", "eSAP_STARTED",
+ sap_ctx->ch_params.ch_width);
sap_ctx->sapsMachine = eSAP_STARTED;
/* Action code for transition */
@@ -4053,6 +4063,10 @@ static QDF_STATUS sap_fsm_state_starting(ptSapContext sap_ctx,
eSAP_START_BSS_EVENT,
(void *) eSAP_STATUS_SUCCESS);
+ QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+ FL("ap_ctx->ch_params.ch_width %d, channel %d"),
+ sap_ctx->ch_params.ch_width,
+ cds_get_channel_state(sap_ctx->channel));
/*
* The upper layers have been informed that AP is up and
* running, however, the AP is still not beaconing, until
@@ -4074,12 +4088,19 @@ static QDF_STATUS sap_fsm_state_starting(ptSapContext sap_ctx,
is_dfs = true;
}
+ QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
+ FL("is_dfs %d"), is_dfs);
if (is_dfs) {
sap_dfs_info = &mac_ctx->sap.SapDfsInfo;
+
if ((false == sap_dfs_info->ignore_cac) &&
- (eSAP_DFS_DO_NOT_SKIP_CAC ==
- sap_dfs_info->cac_state) &&
- !sap_ctx->pre_cac_complete) {
+ (eSAP_DFS_DO_NOT_SKIP_CAC ==
+ sap_dfs_info->cac_state) &&
+ !sap_ctx->pre_cac_complete) {
+ QDF_TRACE(QDF_MODULE_ID_SAP,
+ QDF_TRACE_LEVEL_INFO_HIGH,
+ FL("start cac timer"));
+
/* Move the device in CAC_WAIT_STATE */
sap_ctx->sapsMachine = eSAP_DFS_CAC_WAIT;
@@ -4095,6 +4116,9 @@ static QDF_STATUS sap_fsm_state_starting(ptSapContext sap_ctx,
qdf_status = sap_cac_start_notify(hal);
} else {
+ QDF_TRACE(QDF_MODULE_ID_SAP,
+ QDF_TRACE_LEVEL_INFO_HIGH,
+ FL("skip cac timer"));
wlansap_start_beacon_req(sap_ctx);
}
}
diff --git a/core/sap/src/sap_module.c b/core/sap/src/sap_module.c
index 5870e0f40507..3e3fc0979850 100644
--- a/core/sap/src/sap_module.c
+++ b/core/sap/src/sap_module.c
@@ -1693,6 +1693,7 @@ wlansap_set_channel_change_with_csa(void *p_cds_gctx, uint32_t targetChannel,
void *hHal = NULL;
bool valid;
QDF_STATUS status;
+ bool sta_sap_scc_on_dfs_chan;
sapContext = CDS_GET_SAP_CB(p_cds_gctx);
if (NULL == sapContext) {
@@ -1722,6 +1723,7 @@ wlansap_set_channel_change_with_csa(void *p_cds_gctx, uint32_t targetChannel,
cds_is_any_mode_active_on_band_along_with_session(
sapContext->sessionId, CDS_BAND_5));
+ sta_sap_scc_on_dfs_chan = cds_is_sta_sap_scc_allowed_on_dfs_channel();
/*
* Now, validate if the passed channel is valid in the
* current regulatory domain.
@@ -1731,8 +1733,10 @@ wlansap_set_channel_change_with_csa(void *p_cds_gctx, uint32_t targetChannel,
CHANNEL_STATE_ENABLE) ||
(cds_get_channel_state(targetChannel) ==
CHANNEL_STATE_DFS &&
- !cds_is_any_mode_active_on_band_along_with_session(
- sapContext->sessionId, CDS_BAND_5)))) {
+ (!cds_is_any_mode_active_on_band_along_with_session(
+ sapContext->sessionId, CDS_BAND_5) ||
+ sta_sap_scc_on_dfs_chan)))) {
+
/*
* validate target channel switch w.r.t various concurrency
* rules set.