qcacld-3.0: Add logic to handle country code change
Update the HDD callback to check for phymode change or channel change when country code updates and stop/restart the adapter accordingly. Include cases for STA mode, SAP mode, P2P-CLI mode, and P2P-GO mode. Add conditional compilation flag for MCC specific API in qcacmn. Change-Id: I88edb401146e3cef48d757393f89fa48cb6ac895 CRs-fixed: 2658294
This commit is contained in:
parent
745f9e7d1f
commit
e4f18a9065
3
Kbuild
3
Kbuild
@ -3445,6 +3445,9 @@ cppflags-y += -DTGT_IF_VDEV_MGR_CONV
|
||||
cppflags-y += -DCONFIG_CHAN_NUM_API
|
||||
cppflags-y += -DCONFIG_CHAN_FREQ_API
|
||||
|
||||
#Flag to enable/disable MCC specific feature regarding unallowed phymodes
|
||||
cppflags-y += -DCHECK_REG_PHYMODE
|
||||
|
||||
cppflags-$(CONFIG_BAND_6GHZ) += -DCONFIG_BAND_6GHZ
|
||||
cppflags-$(CONFIG_6G_SCAN_CHAN_SORT_ALGO) += -DFEATURE_6G_SCAN_CHAN_SORT_ALGO
|
||||
|
||||
|
@ -1276,4 +1276,13 @@ struct connection_info {
|
||||
uint8_t channel;
|
||||
uint32_t ch_freq;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sta_ap_intf_check_work_ctx - sta_ap_intf_check_work
|
||||
* related info
|
||||
* @psoc: pointer to PSOC object information
|
||||
*/
|
||||
struct sta_ap_intf_check_work_ctx {
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
};
|
||||
#endif /* __WLAN_POLICY_MGR_PUBLIC_STRUCT_H */
|
||||
|
@ -222,15 +222,6 @@ extern enum policy_mgr_conc_next_action
|
||||
(*policy_mgr_get_current_pref_hw_mode_ptr)
|
||||
(struct wlan_objmgr_psoc *psoc);
|
||||
|
||||
/**
|
||||
* struct sta_ap_intf_check_work_ctx - sta_ap_intf_check_work
|
||||
* related info
|
||||
* @psoc: pointer to PSOC object information
|
||||
*/
|
||||
struct sta_ap_intf_check_work_ctx {
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct policy_mgr_cfg - all the policy manager owned configs
|
||||
* @mcc_to_scc_switch: switch to indicate MCC to SCC config
|
||||
|
@ -1648,6 +1648,7 @@ struct hdd_fw_ver_info {
|
||||
* @psoc_idle_timeout_work: delayed work for psoc idle shutdown
|
||||
* @dynamic_nss_chains_support: Per vdev dynamic nss chains update capability
|
||||
* @sar_cmd_params: SAR command params to be configured to the FW
|
||||
* @country_change_work: work for updating vdev when country changes
|
||||
*/
|
||||
struct hdd_context {
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
@ -1972,6 +1973,7 @@ struct hdd_context {
|
||||
#ifdef FW_THERMAL_THROTTLE_SUPPORT
|
||||
uint8_t dutycycle_off_percent;
|
||||
#endif
|
||||
qdf_work_t country_change_work;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -40,6 +40,15 @@ struct hdd_context;
|
||||
int hdd_update_regulatory_config(struct hdd_context *hdd_ctx);
|
||||
|
||||
int hdd_regulatory_init(struct hdd_context *hdd_ctx, struct wiphy *wiphy);
|
||||
|
||||
/**
|
||||
* hdd_regulatory_deinit() - cleanup all components of regulatory
|
||||
* @hdd_ctx: HDD context
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void hdd_regulatory_deinit(struct hdd_context *hdd_ctx);
|
||||
|
||||
void hdd_program_country_code(struct hdd_context *hdd_ctx);
|
||||
void hdd_reset_global_reg_params(void);
|
||||
|
||||
|
@ -8375,6 +8375,7 @@ void hdd_wlan_exit(struct hdd_context *hdd_ctx)
|
||||
hdd_debugfs_ini_config_deinit(hdd_ctx);
|
||||
hdd_debugfs_mws_coex_info_deinit(hdd_ctx);
|
||||
hdd_psoc_idle_timer_stop(hdd_ctx);
|
||||
hdd_regulatory_deinit(hdd_ctx);
|
||||
|
||||
/*
|
||||
* Powersave Offload Case
|
||||
|
@ -33,6 +33,9 @@
|
||||
#include "pld_common.h"
|
||||
#include <net/cfg80211.h>
|
||||
#include "wlan_policy_mgr_ucfg.h"
|
||||
#include "sap_api.h"
|
||||
#include "wlan_hdd_hostapd.h"
|
||||
#include "osif_psoc_sync.h"
|
||||
|
||||
#define REG_RULE_2412_2462 REG_RULE(2412-10, 2462+10, 40, 0, 20, 0)
|
||||
|
||||
@ -1401,6 +1404,239 @@ static void hdd_regulatory_chanlist_dump(struct regulatory_channel *chan_list)
|
||||
hdd_debug("end total_count %d", count);
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_country_change_update_sta() - handle country code change for STA
|
||||
* @hdd_ctx: Global HDD context
|
||||
*
|
||||
* This function handles the stop/start/restart of STA/P2P_CLI adapters when
|
||||
* the country code changes
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static void hdd_country_change_update_sta(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
struct hdd_adapter *adapter = NULL;
|
||||
struct hdd_station_ctx *sta_ctx = NULL;
|
||||
struct csr_roam_profile *roam_profile = NULL;
|
||||
struct wlan_objmgr_pdev *pdev = NULL;
|
||||
uint32_t new_phy_mode;
|
||||
bool freq_changed, phy_changed;
|
||||
qdf_freq_t oper_freq;
|
||||
eCsrPhyMode csr_phy_mode;
|
||||
|
||||
pdev = hdd_ctx->pdev;
|
||||
|
||||
hdd_for_each_adapter_dev_held(hdd_ctx, adapter) {
|
||||
oper_freq = hdd_get_adapter_home_channel(adapter);
|
||||
freq_changed = wlan_reg_is_disable_for_freq(pdev, oper_freq);
|
||||
|
||||
switch (adapter->device_mode) {
|
||||
case QDF_P2P_CLIENT_MODE:
|
||||
/*
|
||||
* P2P client is the same as STA
|
||||
* continue to next statement
|
||||
*/
|
||||
case QDF_STA_MODE:
|
||||
sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
|
||||
roam_profile = &sta_ctx->roam_profile;
|
||||
new_phy_mode = wlan_reg_get_max_phymode(pdev,
|
||||
REG_PHYMODE_MAX,
|
||||
oper_freq);
|
||||
csr_phy_mode =
|
||||
csr_convert_from_reg_phy_mode(new_phy_mode);
|
||||
phy_changed = (roam_profile->phyMode != csr_phy_mode);
|
||||
|
||||
if (phy_changed || freq_changed) {
|
||||
sme_roam_disconnect(
|
||||
hdd_ctx->mac_handle,
|
||||
adapter->vdev_id,
|
||||
eCSR_DISCONNECT_REASON_UNSPECIFIED,
|
||||
eSIR_MAC_UNSPEC_FAILURE_REASON);
|
||||
roam_profile->phyMode = csr_phy_mode;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* dev_put has to be done here */
|
||||
dev_put(adapter->dev);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_restart_sap_with_new_phymode() - restart the SAP with the new phymode
|
||||
* @hdd_ctx: Global HDD context
|
||||
* @adapter: HDD vdev context
|
||||
* @sap_config: sap configuration pointer
|
||||
* @csr_phy_mode: phymode to restart SAP with
|
||||
* @freq_changed: flag to set freq update on restart
|
||||
*
|
||||
* This function handles the stop/start/restart of SAP/P2P_GO adapters when the
|
||||
* country code changes
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static void hdd_restart_sap_with_new_phymode(struct hdd_context *hdd_ctx,
|
||||
struct hdd_adapter *adapter,
|
||||
struct sap_config *sap_config,
|
||||
eCsrPhyMode csr_phy_mode,
|
||||
bool freq_changed)
|
||||
{
|
||||
struct hdd_hostapd_state *hostapd_state = NULL;
|
||||
struct sap_context *sap_ctx = NULL;
|
||||
QDF_STATUS status;
|
||||
|
||||
hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
|
||||
sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter);
|
||||
|
||||
qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
|
||||
status = wlansap_stop_bss(sap_ctx);
|
||||
if (!QDF_IS_STATUS_SUCCESS(status)) {
|
||||
hdd_err("SAP Stop Bss fail");
|
||||
return;
|
||||
}
|
||||
status = qdf_wait_for_event_completion(
|
||||
&hostapd_state->qdf_stop_bss_event,
|
||||
SME_CMD_STOP_BSS_TIMEOUT);
|
||||
if (!QDF_IS_STATUS_SUCCESS(status)) {
|
||||
hdd_err("SAP Stop timeout");
|
||||
return;
|
||||
}
|
||||
|
||||
if (freq_changed) {
|
||||
sap_config->chan_freq =
|
||||
wlansap_get_safe_channel_from_pcl_and_acs_range(sap_ctx);
|
||||
}
|
||||
|
||||
sap_config->sap_orig_hw_mode = sap_config->SapHw_mode;
|
||||
sap_config->SapHw_mode = csr_phy_mode;
|
||||
|
||||
mutex_lock(&hdd_ctx->sap_lock);
|
||||
qdf_event_reset(&hostapd_state->qdf_event);
|
||||
status = wlansap_start_bss(sap_ctx, hdd_hostapd_sap_event_cb,
|
||||
sap_config, adapter->dev);
|
||||
if (!QDF_IS_STATUS_SUCCESS(status)) {
|
||||
mutex_unlock(&hdd_ctx->sap_lock);
|
||||
hdd_err("SAP Start Bss fail");
|
||||
return;
|
||||
}
|
||||
status = qdf_wait_for_event_completion(&hostapd_state->qdf_event,
|
||||
SME_CMD_START_BSS_TIMEOUT);
|
||||
if (!QDF_IS_STATUS_SUCCESS(status)) {
|
||||
mutex_unlock(&hdd_ctx->sap_lock);
|
||||
hdd_err("SAP Start timeout");
|
||||
return;
|
||||
}
|
||||
mutex_unlock(&hdd_ctx->sap_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_country_change_update_sap() - handle country code change for SAP
|
||||
* @hdd_ctx: Global HDD context
|
||||
*
|
||||
* This function handles the stop/start/restart of SAP/P2P_GO adapters when the
|
||||
* country code changes
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static void hdd_country_change_update_sap(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
struct hdd_adapter *adapter = NULL;
|
||||
struct sap_config *sap_config = NULL;
|
||||
struct sap_context *sap_ctx = NULL;
|
||||
struct wlan_objmgr_pdev *pdev = NULL;
|
||||
uint32_t reg_phy_mode, new_phy_mode;
|
||||
bool freq_changed, phy_changed;
|
||||
qdf_freq_t oper_freq;
|
||||
eCsrPhyMode csr_phy_mode;
|
||||
struct sta_ap_intf_check_work_ctx intf_work;
|
||||
QDF_STATUS status;
|
||||
|
||||
pdev = hdd_ctx->pdev;
|
||||
|
||||
hdd_for_each_adapter_dev_held(hdd_ctx, adapter) {
|
||||
oper_freq = hdd_get_adapter_home_channel(adapter);
|
||||
freq_changed = wlan_reg_is_disable_for_freq(pdev, oper_freq);
|
||||
|
||||
switch (adapter->device_mode) {
|
||||
case QDF_P2P_GO_MODE:
|
||||
sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter);
|
||||
if (freq_changed) {
|
||||
status = wlansap_stop_bss(sap_ctx);
|
||||
if (QDF_IS_STATUS_SUCCESS(status))
|
||||
hdd_debug("Deleting SAP/P2P link!!");
|
||||
}
|
||||
break;
|
||||
case QDF_SAP_MODE:
|
||||
sap_config = &adapter->session.ap.sap_config;
|
||||
reg_phy_mode = csr_convert_to_reg_phy_mode(
|
||||
sap_config->sap_orig_hw_mode,
|
||||
oper_freq);
|
||||
new_phy_mode = wlan_reg_get_max_phymode(pdev,
|
||||
reg_phy_mode,
|
||||
oper_freq);
|
||||
csr_phy_mode =
|
||||
csr_convert_from_reg_phy_mode(new_phy_mode);
|
||||
phy_changed = (csr_phy_mode != sap_config->SapHw_mode);
|
||||
if (freq_changed) {
|
||||
intf_work.psoc = wlan_pdev_get_psoc(pdev);
|
||||
policy_mgr_check_sta_ap_concurrent_ch_intf(
|
||||
&intf_work);
|
||||
}
|
||||
|
||||
if (phy_changed)
|
||||
hdd_restart_sap_with_new_phymode(hdd_ctx,
|
||||
adapter,
|
||||
sap_config,
|
||||
csr_phy_mode,
|
||||
freq_changed);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* dev_put has to be done here */
|
||||
dev_put(adapter->dev);
|
||||
}
|
||||
}
|
||||
|
||||
static void __hdd_country_change_work_handle(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
/*
|
||||
* Loop over STAs first since it may lead to different channel
|
||||
* selection for SAPs
|
||||
*/
|
||||
hdd_country_change_update_sta(hdd_ctx);
|
||||
hdd_country_change_update_sap(hdd_ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_country_change_work_handle() - handle country code change
|
||||
* @arg: Global HDD context
|
||||
*
|
||||
* This function handles the stop/start/restart of all adapters when the
|
||||
* country code changes
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static void hdd_country_change_work_handle(void *arg)
|
||||
{
|
||||
struct hdd_context *hdd_ctx = (struct hdd_context *)arg;
|
||||
struct osif_psoc_sync *psoc_sync;
|
||||
int errno;
|
||||
|
||||
errno = wlan_hdd_validate_context(hdd_ctx);
|
||||
if (errno)
|
||||
return;
|
||||
|
||||
errno = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync);
|
||||
if (errno)
|
||||
return;
|
||||
|
||||
__hdd_country_change_work_handle(hdd_ctx);
|
||||
|
||||
osif_psoc_sync_op_stop(psoc_sync);
|
||||
}
|
||||
|
||||
static void hdd_regulatory_dyn_cbk(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_objmgr_pdev *pdev,
|
||||
struct regulatory_channel *chan_list,
|
||||
@ -1445,8 +1681,7 @@ static void hdd_regulatory_dyn_cbk(struct wlan_objmgr_psoc *psoc,
|
||||
|
||||
sme_generic_change_country_code(hdd_ctx->mac_handle,
|
||||
hdd_ctx->reg.alpha2);
|
||||
/*Check whether need restart SAP/P2p Go*/
|
||||
policy_mgr_check_concurrent_intf_and_restart_sap(hdd_ctx->psoc);
|
||||
qdf_sched_work(0, &hdd_ctx->country_change_work);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1471,6 +1706,8 @@ int hdd_regulatory_init(struct hdd_context *hdd_ctx, struct wiphy *wiphy)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
qdf_create_work(0, &hdd_ctx->country_change_work,
|
||||
hdd_country_change_work_handle, hdd_ctx);
|
||||
ucfg_reg_register_chan_change_callback(hdd_ctx->psoc,
|
||||
hdd_regulatory_dyn_cbk,
|
||||
NULL);
|
||||
@ -1534,6 +1771,12 @@ int hdd_regulatory_init(struct hdd_context *hdd_ctx, struct wiphy *wiphy)
|
||||
}
|
||||
#endif
|
||||
|
||||
void hdd_regulatory_deinit(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
qdf_flush_work(&hdd_ctx->country_change_work);
|
||||
qdf_destroy_work(0, &hdd_ctx->country_change_work);
|
||||
}
|
||||
|
||||
void hdd_update_regdb_offload_config(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
|
@ -5268,9 +5268,6 @@ sme_handle_generic_change_country_code(struct mac_context *mac_ctx,
|
||||
|
||||
mac_ctx->reg_hint_src = SOURCE_UNKNOWN;
|
||||
|
||||
sme_disconnect_connected_sessions(mac_ctx,
|
||||
eSIR_MAC_UNSPEC_FAILURE_REASON);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user