qcacld-3.0: dynamic channel switch implementation

When dynamic channel switch is enabled, trigger acs and switch to best
channel if wlan interference is found in 5g mac.

Change-Id: I56661f5c42a233a0dc0a6400d75cb8f5c0019706
CRs-Fixed: 2599176
This commit is contained in:
Huashan Qu
2019-12-24 11:04:18 +08:00
committed by nshrivas
parent 01c969852b
commit 1b3be2948e
13 changed files with 809 additions and 20 deletions

View File

@@ -72,6 +72,7 @@ typedef const enum policy_mgr_conc_next_action
* @CSA_REASON_LTE_COEX: LTE coex. * @CSA_REASON_LTE_COEX: LTE coex.
* @CSA_REASON_CONCURRENT_NAN_EVENT: NAN concurrency. * @CSA_REASON_CONCURRENT_NAN_EVENT: NAN concurrency.
* @CSA_REASON_BAND_RESTRICTED: band disabled or re-enabled * @CSA_REASON_BAND_RESTRICTED: band disabled or re-enabled
* @CSA_REASON_DCS: DCS
* *
*/ */
enum sap_csa_reason_code { enum sap_csa_reason_code {
@@ -84,7 +85,8 @@ enum sap_csa_reason_code {
CSA_REASON_UNSAFE_CHANNEL, CSA_REASON_UNSAFE_CHANNEL,
CSA_REASON_LTE_COEX, CSA_REASON_LTE_COEX,
CSA_REASON_CONCURRENT_NAN_EVENT, CSA_REASON_CONCURRENT_NAN_EVENT,
CSA_REASON_BAND_RESTRICTED CSA_REASON_BAND_RESTRICTED,
CSA_REASON_DCS,
}; };
/** /**
@@ -1878,6 +1880,33 @@ QDF_STATUS policy_mgr_get_chan_by_session_id(struct wlan_objmgr_psoc *psoc,
uint8_t session_id, uint8_t session_id,
uint32_t *ch_freq); uint32_t *ch_freq);
/**
* policy_mgr_get_sap_go_count_on_mac() - Provide the count of sap and go on
* given mac
* @psoc: PSOC object information
* @list: To provide the vdev_id of the satisfied sap and go (optional)
* @mac_id: MAC ID
*
* This function provides the count of the matched sap and go
*
* Return: count of the satisfied sap and go
*/
uint32_t policy_mgr_get_sap_go_count_on_mac(struct wlan_objmgr_psoc *psoc,
uint32_t *list, uint8_t mac_id);
/**
* policy_mgr_is_sta_gc_active_on_mac() - Is there active sta/gc for a
* given mac id
* @psoc: PSOC object information
* @mac_id: MAC ID
*
* Checks if there is active sta/gc for a given mac id
*
* Return: true if there is active sta/gc for a given mac id, false otherwise
*/
bool policy_mgr_is_sta_gc_active_on_mac(struct wlan_objmgr_psoc *psoc,
uint8_t mac_id);
/** /**
* policy_mgr_get_mac_id_by_session_id() - Get MAC ID for a given session ID * policy_mgr_get_mac_id_by_session_id() - Get MAC ID for a given session ID
* @psoc: PSOC object information * @psoc: PSOC object information

View File

@@ -2564,7 +2564,8 @@ policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc,
*/ */
qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
if (forced && reason == CSA_REASON_UNSAFE_CHANNEL) if (forced && (reason == CSA_REASON_UNSAFE_CHANNEL ||
reason == CSA_REASON_DCS))
policy_mgr_store_and_del_conn_info_by_chan_and_mode( policy_mgr_store_and_del_conn_info_by_chan_and_mode(
psoc, old_ch_freq, mode, info, &num_cxn_del); psoc, old_ch_freq, mode, info, &num_cxn_del);
else else
@@ -3065,6 +3066,44 @@ bool policy_mgr_is_multiple_active_sta_sessions(struct wlan_objmgr_psoc *psoc)
psoc, PM_STA_MODE, NULL) > 1; psoc, PM_STA_MODE, NULL) > 1;
} }
bool policy_mgr_is_sta_gc_active_on_mac(struct wlan_objmgr_psoc *psoc,
uint8_t mac_id)
{
uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
uint32_t index, count;
struct policy_mgr_psoc_priv_obj *pm_ctx;
pm_ctx = policy_mgr_get_context(psoc);
if (!pm_ctx) {
policy_mgr_err("Invalid Context");
return false;
}
count = policy_mgr_mode_specific_connection_count(
psoc, PM_STA_MODE, list);
qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
for (index = 0; index < count; index++) {
if (mac_id == pm_conc_connection_list[list[index]].mac) {
qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
return true;
}
}
qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
count = policy_mgr_mode_specific_connection_count(
psoc, PM_P2P_CLIENT_MODE, list);
qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
for (index = 0; index < count; index++) {
if (mac_id == pm_conc_connection_list[list[index]].mac) {
qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
return true;
}
}
qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
return false;
}
/** /**
* policy_mgr_is_sta_active_connection_exists() - Check if a STA * policy_mgr_is_sta_active_connection_exists() - Check if a STA
* connection is active * connection is active
@@ -3361,6 +3400,38 @@ QDF_STATUS policy_mgr_get_mac_id_by_session_id(struct wlan_objmgr_psoc *psoc,
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
uint32_t policy_mgr_get_sap_go_count_on_mac(struct wlan_objmgr_psoc *psoc,
uint32_t *list, uint8_t mac_id)
{
uint32_t conn_index;
uint32_t count = 0;
struct policy_mgr_psoc_priv_obj *pm_ctx;
pm_ctx = policy_mgr_get_context(psoc);
if (!pm_ctx) {
policy_mgr_err("Invalid Context");
return count;
}
qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
conn_index++) {
if (pm_conc_connection_list[conn_index].mac == mac_id &&
pm_conc_connection_list[conn_index].in_use &&
(pm_conc_connection_list[conn_index].mode == PM_SAP_MODE ||
pm_conc_connection_list[conn_index].mode ==
PM_P2P_GO_MODE)) {
if (list)
list[count] =
pm_conc_connection_list[conn_index].vdev_id;
count++;
}
}
qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
return count;
}
QDF_STATUS policy_mgr_get_mcc_session_id_on_mac(struct wlan_objmgr_psoc *psoc, QDF_STATUS policy_mgr_get_mcc_session_id_on_mac(struct wlan_objmgr_psoc *psoc,
uint8_t mac_id, uint8_t session_id, uint8_t mac_id, uint8_t session_id,
uint8_t *mcc_session_id) uint8_t *mcc_session_id)

View File

@@ -1950,6 +1950,9 @@ int wlan_hdd_cfg80211_start_acs(struct hdd_adapter *adapter)
if (status > 0) { if (status > 0) {
/*notify hostapd about channel override */ /*notify hostapd about channel override */
wlan_hdd_cfg80211_acs_ch_select_evt(adapter); wlan_hdd_cfg80211_acs_ch_select_evt(adapter);
wlansap_dcs_set_wlan_interference_mitigation_on_band(
WLAN_HDD_GET_SAP_CTX_PTR(adapter),
sap_config);
return 0; return 0;
} }
} }
@@ -2001,6 +2004,8 @@ int wlan_hdd_cfg80211_start_acs(struct hdd_adapter *adapter)
if (sap_is_auto_channel_select(WLAN_HDD_GET_SAP_CTX_PTR(adapter))) if (sap_is_auto_channel_select(WLAN_HDD_GET_SAP_CTX_PTR(adapter)))
sap_config->acs_cfg.acs_mode = true; sap_config->acs_cfg.acs_mode = true;
qdf_atomic_set(&adapter->session.ap.acs_in_progress, 1);
return 0; return 0;
} }
@@ -3141,6 +3146,9 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
sap_config->acs_cfg.vht_seg1_center_ch_freq; sap_config->acs_cfg.vht_seg1_center_ch_freq;
/*notify hostapd about channel override */ /*notify hostapd about channel override */
wlan_hdd_cfg80211_acs_ch_select_evt(adapter); wlan_hdd_cfg80211_acs_ch_select_evt(adapter);
wlansap_dcs_set_wlan_interference_mitigation_on_band(
WLAN_HDD_GET_SAP_CTX_PTR(adapter),
sap_config);
ret = 0; ret = 0;
goto out; goto out;
} }
@@ -3358,7 +3366,7 @@ static int hdd_get_acs_evt_data_len(void)
* @pri_channel: SAP ACS procedure selected Primary channel * @pri_channel: SAP ACS procedure selected Primary channel
* @sec_channel: SAP ACS procedure selected secondary channel * @sec_channel: SAP ACS procedure selected secondary channel
* *
* This is a callback function from SAP module on ACS procedure is completed. * This is a callback function on ACS procedure is completed.
* This function send the ACS selected channel information to hostapd * This function send the ACS selected channel information to hostapd
* *
* Return: None * Return: None

187
core/hdd/src/wlan_hdd_dcs.c Normal file
View File

@@ -0,0 +1,187 @@
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: wlan_hdd_dcs.c
*
* DCS implementation.
*
*/
#include <wlan_hdd_hostapd.h>
#include <wlan_hdd_dcs.h>
#include <wlan_hdd_includes.h>
#include <wlan_dcs_ucfg_api.h>
/**
* hdd_dcs_cb() - hdd dcs specific callback
* @psoc: psoc
* @mac_id: mac_id
* @interference_type: wlan or continuous wave interference type
* @arg: List of arguments
*
* This callback is registered with dcs component to start acs operation
*
* Return: None
*/
static void hdd_dcs_cb(struct wlan_objmgr_psoc *psoc, uint8_t mac_id,
uint8_t interference_type, void *arg)
{
struct hdd_context *hdd_ctx = (struct hdd_context *)arg;
struct hdd_adapter *adapter;
uint32_t count;
uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
uint32_t index;
/*
* so far CAP_DCS_CWIM interference mitigation is not supported
*/
if (interference_type == CAP_DCS_CWIM) {
hdd_debug("CW interference mitigation is not supported");
return;
}
if (policy_mgr_is_force_scc(psoc) &&
policy_mgr_is_sta_gc_active_on_mac(psoc, mac_id)) {
hdd_debug("force scc %d, mac id %d sta gc count %d",
policy_mgr_is_force_scc(psoc), mac_id,
policy_mgr_is_sta_gc_active_on_mac(psoc, mac_id));
return;
}
count = policy_mgr_get_sap_go_count_on_mac(psoc, list, mac_id);
for (index = 0; index < count; index++) {
adapter = hdd_get_adapter_by_vdev(hdd_ctx, list[index]);
if (wlansap_dcs_is_wlan_interference_mitigation_enabled(
WLAN_HDD_GET_SAP_CTX_PTR(adapter))) {
hdd_debug("DCS triggers ACS on vdev_id=%u, mac_id=%u",
list[index], mac_id);
wlan_hdd_cfg80211_start_acs(adapter);
return;
}
}
}
void hdd_dcs_register_cb(struct hdd_context *hdd_ctx)
{
ucfg_dcs_register_cb(hdd_ctx->psoc, hdd_dcs_cb, hdd_ctx);
}
void hdd_dcs_hostapd_set_chan(struct hdd_context *hdd_ctx,
uint8_t vdev_id,
qdf_freq_t dcs_ch_freq)
{
QDF_STATUS status;
uint8_t mac_id;
uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
uint32_t conn_index, count;
struct hdd_adapter *adapter;
uint32_t dcs_ch = wlan_reg_freq_to_chan(hdd_ctx->pdev, dcs_ch_freq);
status = policy_mgr_get_mac_id_by_session_id(hdd_ctx->psoc, vdev_id,
&mac_id);
if (QDF_IS_STATUS_ERROR(status)) {
hdd_err("get mac id failed");
return;
}
count = policy_mgr_get_sap_go_count_on_mac(hdd_ctx->psoc, list, mac_id);
/*
* Dcs can only be enabled after all vdev finish csa.
* Set vdev starting for every vdev before doing csa.
* The CSA triggered by DCS will be done in serial.
*/
for (conn_index = 0; conn_index < count; conn_index++) {
adapter = hdd_get_adapter_by_vdev(hdd_ctx, list[conn_index]);
if (adapter->session.ap.operating_chan_freq != dcs_ch_freq)
wlansap_dcs_set_vdev_starting(
WLAN_HDD_GET_SAP_CTX_PTR(adapter), true);
else
wlansap_dcs_set_vdev_starting(
WLAN_HDD_GET_SAP_CTX_PTR(adapter), false);
}
for (conn_index = 0; conn_index < count; conn_index++) {
adapter = hdd_get_adapter_by_vdev(hdd_ctx, list[conn_index]);
if (adapter->session.ap.operating_chan_freq != dcs_ch_freq) {
hdd_ctx->acs_policy.acs_chan_freq = AUTO_CHANNEL_SELECT;
hdd_debug("dcs triggers old ch:%d new ch:%d",
adapter->session.ap.operating_chan_freq,
dcs_ch_freq);
wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc,
adapter->vdev_id,
CSA_REASON_DCS);
hdd_switch_sap_channel(adapter, dcs_ch, true);
return;
}
}
}
/**
* hdd_dcs_hostapd_enable_wlan_interference_mitigation() - enable wlan
* interference mitigation
* @hdd_ctx: hdd ctx
* @vdev_id: vdev id
*
* This function is used to enable wlan interference mitigation through
* send dcs command.
*
* Return: None
*/
static void hdd_dcs_hostapd_enable_wlan_interference_mitigation(
struct hdd_context *hdd_ctx,
uint8_t vdev_id)
{
QDF_STATUS status;
uint8_t mac_id;
struct hdd_adapter *adapter;
status = policy_mgr_get_mac_id_by_session_id(hdd_ctx->psoc, vdev_id,
&mac_id);
if (QDF_IS_STATUS_ERROR(status)) {
hdd_err("get mac id failed");
return;
}
adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
if (wlansap_dcs_is_wlan_interference_mitigation_enabled(
WLAN_HDD_GET_SAP_CTX_PTR(adapter)) &&
wlan_reg_is_5ghz_ch_freq(adapter->session.ap.operating_chan_freq))
ucfg_config_dcs_enable(hdd_ctx->psoc, mac_id, CAP_DCS_WLANIM);
ucfg_wlan_dcs_cmd(hdd_ctx->psoc, mac_id, true);
}
void hdd_dcs_chan_select_complete(struct hdd_adapter *adapter)
{
qdf_freq_t dcs_freq;
struct hdd_context *hdd_ctx;
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
if (!hdd_ctx) {
hdd_err("Invalid HDD context pointer");
return;
}
dcs_freq = wlansap_dcs_get_freq(WLAN_HDD_GET_SAP_CTX_PTR(adapter));
if (dcs_freq && dcs_freq != adapter->session.ap.operating_chan_freq)
hdd_dcs_hostapd_set_chan(hdd_ctx, adapter->vdev_id, dcs_freq);
else
hdd_dcs_hostapd_enable_wlan_interference_mitigation(
hdd_ctx,
adapter->vdev_id);
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: wlan_hdd_dcs.h
*
* WLAN Host Device Driver dcs related implementation
*
*/
#if !defined(WLAN_HDD_DCS_H)
#define WLAN_HDD_DCS_H
#include <wlan_hdd_main.h>
#ifdef DCS_INTERFERENCE_DETECTION
/**
* hdd_dcs_register_cb() - register dcs callback
* @hdd_ctx: hdd ctx
*
* This function is used to register the HDD callbacks with dcs component
*
* Return: None
*/
void hdd_dcs_register_cb(struct hdd_context *hdd_ctx);
/**
* hdd_dcs_hostapd_set_chan() - switch sap channel to dcs channel
* @hdd_ctx: hdd ctx
* @vdev_id: vdev id
* @dcs_ch_freq: dcs channel freq
*
* This function is used to switch sap channel to dcs channel using (E)CSA
*
* Return: None
*/
void hdd_dcs_hostapd_set_chan(struct hdd_context *hdd_ctx,
uint8_t vdev_id,
qdf_freq_t dcs_ch_freq);
/**
* hdd_dcs_chan_select_complete() - dcs triggered channel select
* complete handling
* @adapter: hdd adapter pointer
*
* When dcs triggered channel select complete, this function is used to do
* switch sap to new dcs channel or just to enable interference mitigation
*
* Return: None
*/
void hdd_dcs_chan_select_complete(struct hdd_adapter *adapter);
#else
static inline void hdd_dcs_register_cb(struct hdd_context *hdd_ctx)
{
}
static inline void hdd_dcs_hostapd_set_chan(struct hdd_context *hdd_ctx,
uint8_t vdev_id,
qdf_freq_t dcs_ch_freq)
{
}
static inline void hdd_dcs_chan_select_complete(struct hdd_adapter *adapter)
{
}
#endif
#endif /* end #if !defined(WLAN_HDD_DCS_H) */

View File

@@ -93,6 +93,7 @@
#include <wlan_reg_services_api.h> #include <wlan_reg_services_api.h>
#include "wlan_hdd_sta_info.h" #include "wlan_hdd_sta_info.h"
#include "ftm_time_sync_ucfg_api.h" #include "ftm_time_sync_ucfg_api.h"
#include <wlan_hdd_dcs.h>
#define ACS_SCAN_EXPIRY_TIMEOUT_S 4 #define ACS_SCAN_EXPIRY_TIMEOUT_S 4
@@ -2586,7 +2587,15 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event,
ap_ctx->sap_config.acs_cfg.pri_ch_freq, ap_ctx->sap_config.acs_cfg.pri_ch_freq,
ap_ctx->sap_config.acs_cfg.ch_width); ap_ctx->sap_config.acs_cfg.ch_width);
wlan_hdd_cfg80211_acs_ch_select_evt(adapter); if (qdf_atomic_read(&adapter->session.ap.acs_in_progress) &&
test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
hdd_dcs_chan_select_complete(adapter);
} else {
wlan_hdd_cfg80211_acs_ch_select_evt(adapter);
wlansap_dcs_set_wlan_interference_mitigation_on_band(
WLAN_HDD_GET_SAP_CTX_PTR(adapter),
&ap_ctx->sap_config);
}
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
case eSAP_ECSA_CHANGE_CHAN_IND: case eSAP_ECSA_CHANGE_CHAN_IND:
@@ -2630,6 +2639,11 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event,
if (ap_ctx->sap_context->csa_reason == if (ap_ctx->sap_context->csa_reason ==
CSA_REASON_UNSAFE_CHANNEL) CSA_REASON_UNSAFE_CHANNEL)
hdd_unsafe_channel_restart_sap(hdd_ctx); hdd_unsafe_channel_restart_sap(hdd_ctx);
else if (ap_ctx->sap_context->csa_reason == CSA_REASON_DCS)
hdd_dcs_hostapd_set_chan(
hdd_ctx, adapter->vdev_id,
adapter->session.ap.operating_chan_freq);
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
default: default:
@@ -2883,6 +2897,7 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_chan_freq,
uint8_t scc_on_lte_coex = 0; uint8_t scc_on_lte_coex = 0;
bool is_p2p_go_session = false; bool is_p2p_go_session = false;
struct wlan_objmgr_vdev *vdev; struct wlan_objmgr_vdev *vdev;
bool strict;
hdd_ctx = WLAN_HDD_GET_CTX(adapter); hdd_ctx = WLAN_HDD_GET_CTX(adapter);
ret = wlan_hdd_validate_context(hdd_ctx); ret = wlan_hdd_validate_context(hdd_ctx);
@@ -3004,11 +3019,20 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_chan_freq,
is_p2p_go_session = true; is_p2p_go_session = true;
hdd_objmgr_put_vdev(vdev); hdd_objmgr_put_vdev(vdev);
strict = is_p2p_go_session;
/*
* scc_on_lte_coex should be considered only when csa is triggered
* by unsafe channel.
*/
if (sap_ctx->csa_reason == CSA_REASON_UNSAFE_CHANNEL)
strict = strict || (forced && !scc_on_lte_coex);
else
strict = strict || forced;
status = wlansap_set_channel_change_with_csa( status = wlansap_set_channel_change_with_csa(
WLAN_HDD_GET_SAP_CTX_PTR(adapter), WLAN_HDD_GET_SAP_CTX_PTR(adapter),
target_chan_freq, target_chan_freq,
target_bw, target_bw,
(forced && !scc_on_lte_coex) || is_p2p_go_session); strict);
if (QDF_STATUS_SUCCESS != status) { if (QDF_STATUS_SUCCESS != status) {
hdd_err("SAP set channel failed for channel freq: %d, bw: %d", hdd_err("SAP set channel failed for channel freq: %d, bw: %d",
@@ -3372,7 +3396,7 @@ QDF_STATUS hdd_init_ap_mode(struct hdd_adapter *adapter, bool reinit)
struct hdd_hostapd_state *phostapdBuf; struct hdd_hostapd_state *phostapdBuf;
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
QDF_STATUS status = QDF_STATUS_E_FAILURE; QDF_STATUS status = QDF_STATUS_E_FAILURE;
struct sap_context *sap_context = NULL; struct sap_context *sap_ctx;
int ret; int ret;
enum dfs_mode acs_dfs_mode; enum dfs_mode acs_dfs_mode;
bool acs_with_more_param = 0; bool acs_with_more_param = 0;
@@ -3384,8 +3408,8 @@ QDF_STATUS hdd_init_ap_mode(struct hdd_adapter *adapter, bool reinit)
hdd_debug("SSR in progress: %d", reinit); hdd_debug("SSR in progress: %d", reinit);
qdf_atomic_init(&adapter->session.ap.acs_in_progress); qdf_atomic_init(&adapter->session.ap.acs_in_progress);
sap_context = hdd_hostapd_init_sap_session(adapter, reinit); sap_ctx = hdd_hostapd_init_sap_session(adapter, reinit);
if (!sap_context) { if (!sap_ctx) {
hdd_err("Invalid sap_ctx"); hdd_err("Invalid sap_ctx");
goto error_release_vdev; goto error_release_vdev;
} }
@@ -3474,6 +3498,9 @@ QDF_STATUS hdd_init_ap_mode(struct hdd_adapter *adapter, bool reinit)
if (!reinit) { if (!reinit) {
adapter->session.ap.sap_config.acs_cfg.acs_mode = false; adapter->session.ap.sap_config.acs_cfg.acs_mode = false;
wlansap_dcs_set_vdev_wlan_interference_mitigation(sap_ctx,
false);
wlansap_dcs_set_vdev_starting(sap_ctx, false);
qdf_mem_zero(&adapter->session.ap.sap_config.acs_cfg, qdf_mem_zero(&adapter->session.ap.sap_config.acs_cfg,
sizeof(struct sap_acs_cfg)); sizeof(struct sap_acs_cfg));
} }
@@ -5746,6 +5773,7 @@ static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
tSirUpdateIE update_ie; tSirUpdateIE update_ie;
int ret; int ret;
mac_handle_t mac_handle; mac_handle_t mac_handle;
struct sap_context *sap_ctx;
hdd_enter(); hdd_enter();
@@ -5811,6 +5839,9 @@ static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
cds_flush_work(&adapter->sap_stop_bss_work); cds_flush_work(&adapter->sap_stop_bss_work);
adapter->session.ap.sap_config.acs_cfg.acs_mode = false; adapter->session.ap.sap_config.acs_cfg.acs_mode = false;
sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter);
wlansap_dcs_set_vdev_wlan_interference_mitigation(sap_ctx, false);
wlansap_dcs_set_vdev_starting(sap_ctx, false);
qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0); qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0);
hdd_debug("Disabling queues"); hdd_debug("Disabling queues");
wlan_hdd_netif_queue_control(adapter, wlan_hdd_netif_queue_control(adapter,

View File

@@ -180,6 +180,7 @@
#include <wlan_hdd_sar_limits.h> #include <wlan_hdd_sar_limits.h>
#include "cfg_nan_api.h" #include "cfg_nan_api.h"
#include "wlan_hdd_btc_chain_mode.h" #include "wlan_hdd_btc_chain_mode.h"
#include <wlan_hdd_dcs.h>
#ifdef MODULE #ifdef MODULE
#define WLAN_MODULE_NAME module_name(THIS_MODULE) #define WLAN_MODULE_NAME module_name(THIS_MODULE)
@@ -342,6 +343,7 @@ static const struct category_info cinfo[MAX_SUPPORTED_CATEGORY] = {
[QDF_MODULE_ID_CMN_MLME] = {QDF_TRACE_LEVEL_ALL}, [QDF_MODULE_ID_CMN_MLME] = {QDF_TRACE_LEVEL_ALL},
[QDF_MODULE_ID_NAN] = {QDF_TRACE_LEVEL_ALL}, [QDF_MODULE_ID_NAN] = {QDF_TRACE_LEVEL_ALL},
[QDF_MODULE_ID_CP_STATS] = {QDF_TRACE_LEVEL_ALL}, [QDF_MODULE_ID_CP_STATS] = {QDF_TRACE_LEVEL_ALL},
[QDF_MODULE_ID_DCS] = {QDF_TRACE_LEVEL_ALL},
[QDF_MODULE_ID_INTEROP_ISSUES_AP] = {QDF_TRACE_LEVEL_ALL}, [QDF_MODULE_ID_INTEROP_ISSUES_AP] = {QDF_TRACE_LEVEL_ALL},
[QDF_MODULE_ID_BLACKLIST_MGR] = {QDF_TRACE_LEVEL_ALL}, [QDF_MODULE_ID_BLACKLIST_MGR] = {QDF_TRACE_LEVEL_ALL},
[QDF_MODULE_ID_DIRECT_BUF_RX] = {QDF_TRACE_LEVEL_ALL}, [QDF_MODULE_ID_DIRECT_BUF_RX] = {QDF_TRACE_LEVEL_ALL},
@@ -13396,6 +13398,7 @@ int hdd_register_cb(struct hdd_context *hdd_ctx)
hdd_lost_link_info_cb); hdd_lost_link_info_cb);
wlan_hdd_register_cp_stats_cb(hdd_ctx); wlan_hdd_register_cp_stats_cb(hdd_ctx);
hdd_dcs_register_cb(hdd_ctx);
/* print error and not block the startup process */ /* print error and not block the startup process */
if (!QDF_IS_STATUS_SUCCESS(status)) if (!QDF_IS_STATUS_SUCCESS(status))

View File

@@ -619,6 +619,19 @@ typedef struct sSapDfsInfo {
uint16_t reduced_beacon_interval; uint16_t reduced_beacon_interval;
} tSapDfsInfo; } tSapDfsInfo;
#ifdef DCS_INTERFERENCE_DETECTION
/**
* struct sap_dcs_info - record sap dcs information.
* @wlan_interference_mitigation_enable: wlan interference mitigation
* is enabled per vdev.
* @is_vdev_starting: is vdev doing restart because of dcs.
*/
struct sap_dcs_info {
bool wlan_interference_mitigation_enable[WLAN_MAX_VDEVS];
bool is_vdev_starting[WLAN_MAX_VDEVS];
};
#endif
struct sap_ctx_list { struct sap_ctx_list {
void *sap_context; void *sap_context;
enum QDF_OPMODE sapPersona; enum QDF_OPMODE sapPersona;
@@ -633,6 +646,9 @@ typedef struct tagSapStruct {
#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
bool acs_with_more_param; bool acs_with_more_param;
bool enable_dfs_phy_error_logs; bool enable_dfs_phy_error_logs;
#ifdef DCS_INTERFERENCE_DETECTION
struct sap_dcs_info dcs_info;
#endif
} tSapStruct, *tpSapStruct; } tSapStruct, *tpSapStruct;
/** /**
@@ -1469,6 +1485,127 @@ wlansap_get_safe_channel_from_pcl_and_acs_range(struct sap_context *sap_ctx);
*/ */
qdf_freq_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx); qdf_freq_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx);
#ifdef DCS_INTERFERENCE_DETECTION
/**
* wlansap_dcs_set_vdev_wlan_interference_mitigation() - set wlan
* interference mitigation enable information per vdev
* @sap_context: sap context
* @wlan_interference_mitigation_enable: wlan interference mitigation
* enable or not
*
* This function is used to set whether wlan interference mitigation
* enable or not
*
* Return: QDF_STATUS
*/
QDF_STATUS wlansap_dcs_set_vdev_wlan_interference_mitigation(
struct sap_context *sap_context,
bool wlan_interference_mitigation_enable);
/**
* wlansap_dcs_set_wlan_interference_mitigation_on_band() - set wlan
* interference mitigation enable information based on band information
* @sap_context: sap context
* @sap_cfg: sap config
*
* This function is used to set whether wlan interference mitigation
* enable or not based on band information
*
* Return: QDF_STATUS
*/
QDF_STATUS wlansap_dcs_set_wlan_interference_mitigation_on_band(
struct sap_context *sap_context,
struct sap_config *sap_cfg);
/**
* wlansap_dcs_set_vdev_starting() - set vdev starting
* @sap_context: sap context
* @vdev_starting: vdev in starting states
*
* This function is used to set whether vdev starting or not
*
* Return: QDF_STATUS
*/
QDF_STATUS wlansap_dcs_set_vdev_starting(struct sap_context *sap_context,
bool vdev_starting);
/**
* wlansap_dcs_is_wlan_interference_mitigation_enabled() - get wlan interference
* mitigation enabled information
* @sap_context: sap context
*
* This function is used to get wlan interference mitigation enabled information
* with given sap
*
* Return: true if wlan interference mitigation is enabled with given sap
*/
bool wlansap_dcs_is_wlan_interference_mitigation_enabled(
struct sap_context *sap_context);
/**
* wlansap_dcs_get_freq() - get dcs channel frequency
* @sap_context: sap context
*
* This function is used to get dcs channel frequency with give sap
*
* Return: sap dcs channel frequency
*/
qdf_freq_t wlansap_dcs_get_freq(struct sap_context *sap_context);
#else
static inline QDF_STATUS wlansap_dcs_set_vdev_wlan_interference_mitigation(
struct sap_context *sap_context,
bool wlan_interference_mitigation_enable)
{
return QDF_STATUS_SUCCESS;
}
static inline QDF_STATUS wlansap_dcs_set_wlan_interference_mitigation_on_band(
struct sap_context *sap_context,
struct sap_config *sap_cfg)
{
return QDF_STATUS_SUCCESS;
}
static inline QDF_STATUS wlansap_dcs_set_vdev_starting(
struct sap_context *sap_context, bool vdev_starting)
{
return QDF_STATUS_SUCCESS;
}
static inline bool wlansap_dcs_is_wlan_interference_mitigation_enabled(
struct sap_context *sap_context)
{
return false;
}
static inline qdf_freq_t wlansap_dcs_get_freq(struct sap_context *sap_context)
{
return 0;
}
#endif
/**
* wlansap_dump_acs_ch_freq() - print acs channel frequency
* @sap_ctx: sap context
*
* This function is used to print acs channel frequecny
*
* Return: None
*/
void wlansap_dump_acs_ch_freq(struct sap_context *sap_context);
/**
* wlansap_set_acs_ch_freq() - set acs channel frequency
* @sap_ctx: sap context
* @ch_freq: ch_freq to be set
*
* This function is used to set acs channel frequency
*
* Return: None
*/
void wlansap_set_acs_ch_freq(struct sap_context *sap_context,
qdf_freq_t ch_freq);
/** /**
* sap_acquire_vdev_ref() - Increment reference count for vdev object * sap_acquire_vdev_ref() - Increment reference count for vdev object
* @psoc: Object Manager PSoC object * @psoc: Object Manager PSoC object

View File

@@ -334,7 +334,7 @@ QDF_STATUS wlansap_pre_start_bss_acs_scan_callback(mac_handle_t mac_handle,
scan_status); scan_status);
oper_channel = oper_channel =
sap_select_default_oper_chan(sap_ctx->acs_cfg); sap_select_default_oper_chan(sap_ctx->acs_cfg);
sap_ctx->chan_freq = oper_channel; wlansap_set_acs_ch_freq(sap_ctx, oper_channel);
sap_ctx->acs_cfg->pri_ch_freq = oper_channel; sap_ctx->acs_cfg->pri_ch_freq = oper_channel;
sap_config_acs_result(mac_handle, sap_ctx, sap_config_acs_result(mac_handle, sap_ctx,
sap_ctx->acs_cfg->ht_sec_ch_freq); sap_ctx->acs_cfg->ht_sec_ch_freq);
@@ -354,11 +354,13 @@ QDF_STATUS wlansap_pre_start_bss_acs_scan_callback(mac_handle_t mac_handle,
oper_channel = sap_select_default_oper_chan(sap_ctx->acs_cfg); oper_channel = sap_select_default_oper_chan(sap_ctx->acs_cfg);
} }
sap_ctx->chan_freq = oper_channel; wlansap_set_acs_ch_freq(sap_ctx, oper_channel);
sap_ctx->acs_cfg->pri_ch_freq = oper_channel; sap_ctx->acs_cfg->pri_ch_freq = oper_channel;
sap_config_acs_result(mac_handle, sap_ctx, sap_config_acs_result(mac_handle, sap_ctx,
sap_ctx->acs_cfg->ht_sec_ch_freq); sap_ctx->acs_cfg->ht_sec_ch_freq);
wlansap_dump_acs_ch_freq(sap_ctx);
sap_ctx->sap_state = eSAP_ACS_CHANNEL_SELECTED; sap_ctx->sap_state = eSAP_ACS_CHANNEL_SELECTED;
sap_ctx->sap_status = eSAP_STATUS_SUCCESS; sap_ctx->sap_status = eSAP_STATUS_SUCCESS;
close_session: close_session:

View File

@@ -846,6 +846,7 @@ QDF_STATUS sap_channel_sel(struct sap_context *sap_context)
uint8_t vdev_id; uint8_t vdev_id;
uint32_t scan_id; uint32_t scan_id;
uint8_t *self_mac; uint8_t *self_mac;
uint32_t default_op_freq;
mac_handle = cds_get_context(QDF_MODULE_ID_SME); mac_handle = cds_get_context(QDF_MODULE_ID_SME);
if (!mac_handle) { if (!mac_handle) {
@@ -861,7 +862,7 @@ QDF_STATUS sap_channel_sel(struct sap_context *sap_context)
FL("Invalid MAC context")); FL("Invalid MAC context"));
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
if (sap_context->chan_freq) if (sap_context->fsm_state != SAP_STARTED && sap_context->chan_freq)
return sap_validate_chan(sap_context, true, false); return sap_validate_chan(sap_context, true, false);
if (policy_mgr_concurrent_beaconing_sessions_running(mac_ctx->psoc) || if (policy_mgr_concurrent_beaconing_sessions_running(mac_ctx->psoc) ||
@@ -956,12 +957,13 @@ QDF_STATUS sap_channel_sel(struct sap_context *sap_context)
QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
FL("SAP Configuring default ch, Ch_freq=%d"), FL("SAP Configuring default ch, Ch_freq=%d"),
sap_context->chan_freq); sap_context->chan_freq);
sap_context->chan_freq = sap_select_default_oper_chan( default_op_freq = sap_select_default_oper_chan(
sap_context->acs_cfg); sap_context->acs_cfg);
wlansap_set_acs_ch_freq(sap_context, default_op_freq);
if (sap_context->freq_list) { if (sap_context->freq_list) {
sap_context->chan_freq = wlansap_set_acs_ch_freq(
sap_context->freq_list[0]; sap_context, sap_context->freq_list[0]);
qdf_mem_free(sap_context->freq_list); qdf_mem_free(sap_context->freq_list);
sap_context->freq_list = NULL; sap_context->freq_list = NULL;
sap_context->num_of_channel = 0; sap_context->num_of_channel = 0;
@@ -974,6 +976,7 @@ QDF_STATUS sap_channel_sel(struct sap_context *sap_context)
qdf_ret_status = QDF_STATUS_E_FAILURE; qdf_ret_status = QDF_STATUS_E_FAILURE;
goto release_vdev_ref; goto release_vdev_ref;
} else { } else {
wlansap_dump_acs_ch_freq(sap_context);
host_log_acs_scan_start(scan_id, vdev_id); host_log_acs_scan_start(scan_id, vdev_id);
} }
#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
@@ -990,6 +993,8 @@ QDF_STATUS sap_channel_sel(struct sap_context *sap_context)
} }
#endif #endif
wlansap_dump_acs_ch_freq(sap_context);
qdf_ret_status = QDF_STATUS_SUCCESS; qdf_ret_status = QDF_STATUS_SUCCESS;
release_vdev_ref: release_vdev_ref:

View File

@@ -126,6 +126,10 @@ struct sap_context {
uint32_t chan_freq; uint32_t chan_freq;
uint32_t sec_ch_freq; uint32_t sec_ch_freq;
#ifdef DCS_INTERFERENCE_DETECTION
qdf_freq_t dcs_ch_freq;
#endif
/* Include the SME(CSR) sessionId here */ /* Include the SME(CSR) sessionId here */
uint8_t sessionId; uint8_t sessionId;

View File

@@ -518,7 +518,7 @@ wlansap_set_scan_acs_channel_params(struct sap_config *config,
} }
/* Channel selection is auto or configured */ /* Channel selection is auto or configured */
psap_ctx->chan_freq = config->chan_freq; wlansap_set_acs_ch_freq(psap_ctx, config->chan_freq);
psap_ctx->dfs_mode = config->acs_dfs_mode; psap_ctx->dfs_mode = config->acs_dfs_mode;
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
psap_ctx->cc_switch_mode = config->cc_switch_mode; psap_ctx->cc_switch_mode = config->cc_switch_mode;
@@ -1317,6 +1317,8 @@ static char *sap_get_csa_reason_str(enum sap_csa_reason_code reason)
return "CONCURRENT_NAN_EVENT"; return "CONCURRENT_NAN_EVENT";
case CSA_REASON_BAND_RESTRICTED: case CSA_REASON_BAND_RESTRICTED:
return "BAND_RESTRICTED"; return "BAND_RESTRICTED";
case CSA_REASON_DCS:
return "DCS";
default: default:
return "UNKNOWN"; return "UNKNOWN";
} }
@@ -2385,6 +2387,7 @@ void sap_undo_acs(struct sap_context *sap_ctx, struct sap_config *sap_cfg)
acs_cfg->master_ch_list_count = 0; acs_cfg->master_ch_list_count = 0;
acs_cfg->acs_mode = false; acs_cfg->acs_mode = false;
sap_ctx->num_of_channel = 0; sap_ctx->num_of_channel = 0;
wlansap_dcs_set_vdev_wlan_interference_mitigation(sap_ctx, false);
} }
QDF_STATUS wlansap_acs_chselect(struct sap_context *sap_context, QDF_STATUS wlansap_acs_chselect(struct sap_context *sap_context,
@@ -3036,3 +3039,150 @@ qdf_freq_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx)
return restart_freq; return restart_freq;
} }
#ifdef DCS_INTERFERENCE_DETECTION
QDF_STATUS wlansap_dcs_set_vdev_wlan_interference_mitigation(
struct sap_context *sap_context,
bool wlan_interference_mitigation_enable)
{
struct mac_context *mac;
if (!sap_context) {
sap_err("Invalid SAP context pointer");
return QDF_STATUS_E_FAULT;
}
mac = sap_get_mac_context();
if (!mac) {
sap_err("Invalid MAC context");
return QDF_STATUS_E_FAULT;
}
mac->sap.dcs_info.
wlan_interference_mitigation_enable[sap_context->sessionId] =
wlan_interference_mitigation_enable;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS wlansap_dcs_set_wlan_interference_mitigation_on_band(
struct sap_context *sap_context,
struct sap_config *sap_cfg)
{
QDF_STATUS status = QDF_STATUS_SUCCESS;
bool wlan_interference_mitigation_enable = false;
if (WLAN_REG_IS_5GHZ_CH_FREQ(sap_cfg->acs_cfg.pri_ch_freq))
wlan_interference_mitigation_enable = true;
status = wlansap_dcs_set_vdev_wlan_interference_mitigation(
sap_context,
wlan_interference_mitigation_enable);
return status;
}
QDF_STATUS wlansap_dcs_set_vdev_starting(struct sap_context *sap_context,
bool vdev_starting)
{
struct mac_context *mac;
if (!sap_context) {
sap_err("Invalid SAP context pointer");
return QDF_STATUS_E_FAULT;
}
mac = sap_get_mac_context();
if (!mac) {
sap_err("Invalid MAC context");
return QDF_STATUS_E_FAULT;
}
mac->sap.dcs_info.is_vdev_starting[sap_context->sessionId] =
vdev_starting;
return QDF_STATUS_SUCCESS;
}
bool wlansap_dcs_is_wlan_interference_mitigation_enabled(
struct sap_context *sap_context)
{
struct mac_context *mac;
if (!sap_context) {
sap_err("Invalid SAP context pointer");
return false;
}
mac = sap_get_mac_context();
if (!mac) {
sap_err("Invalid MAC context");
return false;
}
return mac->sap.dcs_info.
wlan_interference_mitigation_enable[sap_context->sessionId];
}
qdf_freq_t wlansap_dcs_get_freq(struct sap_context *sap_context)
{
if (!sap_context) {
sap_err("Invalid SAP context pointer");
return false;
}
return sap_context->dcs_ch_freq;
}
void wlansap_dump_acs_ch_freq(struct sap_context *sap_context)
{
if (!sap_context) {
sap_err("Invalid sap_debug");
return;
}
if (sap_context->fsm_state == SAP_STARTED)
sap_info("ACS dump DCS freq=%d", sap_context->dcs_ch_freq);
else
sap_info("ACS dump ch_freq=%d", sap_context->chan_freq);
}
void wlansap_set_acs_ch_freq(struct sap_context *sap_context,
qdf_freq_t ch_freq)
{
if (!sap_context) {
sap_err("Invalid sap_debug");
return;
}
if (sap_context->fsm_state == SAP_STARTED) {
sap_context->dcs_ch_freq = ch_freq;
sap_debug("ACS configuring dcs_ch_freq=%d",
sap_context->dcs_ch_freq);
} else {
sap_context->chan_freq = ch_freq;
sap_debug("ACS configuring ch_freq=%d",
sap_context->chan_freq);
}
}
#else
void wlansap_dump_acs_ch_freq(struct sap_context *sap_context)
{
if (!sap_context) {
sap_err("Invalid sap_debug");
return;
}
sap_info("ACS dump ch_freq=%d", sap_context->chan_freq);
}
void wlansap_set_acs_ch_freq(struct sap_context *sap_context,
qdf_freq_t ch_freq)
{
if (!sap_context) {
sap_err("Invalid sap_debug");
return;
}
sap_context->chan_freq = ch_freq;
sap_debug("ACS configuring ch_freq=%d", sap_context->chan_freq);
}
#endif

View File

@@ -87,6 +87,10 @@
#include "wlan_utility.h" #include "wlan_utility.h"
#include "wlan_coex_ucfg_api.h" #include "wlan_coex_ucfg_api.h"
#ifdef DCS_INTERFERENCE_DETECTION
#include <wlan_dcs_ucfg_api.h>
#endif
QDF_STATUS wma_find_vdev_id_by_addr(tp_wma_handle wma, uint8_t *addr, QDF_STATUS wma_find_vdev_id_by_addr(tp_wma_handle wma, uint8_t *addr,
uint8_t *vdev_id) uint8_t *vdev_id)
{ {
@@ -1183,6 +1187,81 @@ QDF_STATUS wma_handle_channel_switch_resp(tp_wma_handle wma,
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }
#ifdef DCS_INTERFERENCE_DETECTION
/**
* wma_dcs_clear_vdev_starting() - clear vdev starting within dcs information
* @mac_ctx: mac context
* @vdev_id: vdev id
*
* This function is used to clear vdev starting within dcs information
*
* Return: None
*/
static void wma_dcs_clear_vdev_starting(struct mac_context *mac_ctx,
uint32_t vdev_id)
{
mac_ctx->sap.dcs_info.is_vdev_starting[vdev_id] = false;
}
/**
* wma_dcs_wlan_interference_mitigation_enable() - enable wlan
* interference mitigation
* @mac_ctx: mac context
* @mac_id: mac id
* @vdev_id: vdev id
*
* This function is used to enable wlan interference mitigation through
* send dcs command
*
* Return: None
*/
static void wma_dcs_wlan_interference_mitigation_enable(
struct mac_context *mac_ctx,
uint32_t mac_id,
uint32_t vdev_id)
{
int vdev_index;
uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
uint32_t count;
bool wlan_interference_mitigation_enable =
mac_ctx->sap.dcs_info.
wlan_interference_mitigation_enable[vdev_id];
count = policy_mgr_get_sap_go_count_on_mac(
mac_ctx->psoc, list, mac_id);
for (vdev_index = 0; vdev_index < count; vdev_index++) {
if (mac_ctx->sap.dcs_info.is_vdev_starting[list[vdev_index]]) {
WMA_LOGE("vdev %d: does not finish restart",
list[vdev_index]);
return;
}
wlan_interference_mitigation_enable =
wlan_interference_mitigation_enable ||
mac_ctx->sap.dcs_info.
wlan_interference_mitigation_enable[list[vdev_index]];
}
if (wlan_interference_mitigation_enable)
ucfg_config_dcs_enable(
mac_ctx->psoc, mac_id, CAP_DCS_WLANIM);
ucfg_wlan_dcs_cmd(mac_ctx->psoc, mac_id, true);
}
#else
static void wma_dcs_wlan_interference_mitigation_enable(
struct mac_context *mac_ctx,
uint32_t mac_id,
uint32_t vdev_id)
{
}
static void wma_dcs_clear_vdev_starting(struct mac_context *mac_ctx,
uint32_t vdev_id)
{
}
#endif
QDF_STATUS wma_vdev_start_resp_handler(struct vdev_mlme_obj *vdev_mlme, QDF_STATUS wma_vdev_start_resp_handler(struct vdev_mlme_obj *vdev_mlme,
struct vdev_start_response *rsp) struct vdev_start_response *rsp)
{ {
@@ -1190,9 +1269,7 @@ QDF_STATUS wma_vdev_start_resp_handler(struct vdev_mlme_obj *vdev_mlme,
struct wma_txrx_node *iface; struct wma_txrx_node *iface;
target_resource_config *wlan_res_cfg; target_resource_config *wlan_res_cfg;
struct wlan_objmgr_psoc *psoc; struct wlan_objmgr_psoc *psoc;
#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
struct mac_context *mac_ctx = cds_get_context(QDF_MODULE_ID_PE); struct mac_context *mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
#endif
QDF_STATUS status; QDF_STATUS status;
enum vdev_assoc_type assoc_type = VDEV_ASSOC; enum vdev_assoc_type assoc_type = VDEV_ASSOC;
struct vdev_mlme_obj *mlme_obj; struct vdev_mlme_obj *mlme_obj;
@@ -1208,14 +1285,12 @@ QDF_STATUS wma_vdev_start_resp_handler(struct vdev_mlme_obj *vdev_mlme,
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
if (!mac_ctx) { if (!mac_ctx) {
WMA_LOGE("%s: Failed to get mac_ctx", __func__); WMA_LOGE("%s: Failed to get mac_ctx", __func__);
policy_mgr_set_do_hw_mode_change_flag( policy_mgr_set_do_hw_mode_change_flag(
psoc, false); psoc, false);
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
wlan_res_cfg = lmac_get_tgt_res_cfg(psoc); wlan_res_cfg = lmac_get_tgt_res_cfg(psoc);
if (!wlan_res_cfg) { if (!wlan_res_cfg) {
@@ -1257,6 +1332,12 @@ QDF_STATUS wma_vdev_start_resp_handler(struct vdev_mlme_obj *vdev_mlme,
} }
iface = &wma->interfaces[rsp->vdev_id]; iface = &wma->interfaces[rsp->vdev_id];
if (wma_is_vdev_in_ap_mode(wma, rsp->vdev_id)) {
wma_dcs_clear_vdev_starting(mac_ctx, rsp->vdev_id);
wma_dcs_wlan_interference_mitigation_enable(mac_ctx,
iface->mac_id,
rsp->vdev_id);
}
#ifdef FEATURE_AP_MCC_CH_AVOIDANCE #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
if (rsp->status == QDF_STATUS_SUCCESS if (rsp->status == QDF_STATUS_SUCCESS