qcacld-3.0: Enhance g_enable_go_force_scc for liberal mode

INI g_enable_go_force_scc states the force MCC to SCC mode.
Mode 1-strict: Implement force scc strictly as part of start bss
Mode 2-liberal: Turn on p2p go on provided channel and move
first p2p go to the new p2p go channel after set key.

Currently for p2p-GO forceSCC, support is present where no matter
what is the GO negotiated channel in start_bss, driver will force
the other GO/STA/GC channel (on the same band) to the current GO
channel. This is force SCC strict mode where value 1 is used for
g_enable_go_force_scc ini. In this mode GC will have to do full
scan as the GO channel may be different from actual negotiated
channel. DUT may see some issues if GC dosent do full scan in
this mode.

As part of this change, add support for value 2(Liberal mode)
in g_enable_go_force_scc ini. As part of this liberal mode,
driver will allow the GO to start in MCC mode and after set key,
it will check any other concurrent GO and will do forceSCC for
that GO to the newly formed GO channel.

Change-Id: Ifc7beb06335616c51dc064f48a78b825dbdbda25
CRs-Fixed: 2992098
This commit is contained in:
Vinod Kumar Myadam 2021-08-27 13:32:11 +05:30 committed by Madan Koyyalamudi
parent eb48431ea7
commit f4a551d19e
10 changed files with 405 additions and 9 deletions

View file

@ -630,6 +630,106 @@ policy_mgr_is_p2p_p2p_conc_supported(struct wlan_objmgr_psoc *psoc)
}
#endif
#define GO_FORCE_SCC_DISABLE 0
#define GO_FORCE_SCC_STRICT 1
#define GO_FORCE_SCC_LIBERAL 2
#ifdef WLAN_FEATURE_P2P_P2P_STA
/**
* Stay in MCC for 1 second, in case of first p2p go channel
* needs to be moved to curr go channel
*/
#define WAIT_BEFORE_GO_FORCESCC_RESTART (1000)
/**
* policy_mgr_is_go_scc_strict() - Get GO force SCC enabled or not
* @psoc: psoc object
*
* This function checks if force SCC logic should be used on GO interface
* as a strict mode.
*
* Return: True if p2p needs o be start on provided channel only.
*/
bool policy_mgr_is_go_scc_strict(struct wlan_objmgr_psoc *psoc);
/**
* policy_mgr_check_forcescc_for_other_go() - check if another p2pgo
* is present and find vdev id.
*
* @psoc: psoc object
* @vdev: vdev id
* @freq: frequency
*
* This function checks if another p2p go is there.
*
* Return: vdev_id
*/
uint8_t
policy_mgr_check_forcescc_for_other_go(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id, uint32_t curr_go_freq);
/**
* policy_mgr_process_forcescc_for_go () - start work queue to move first p2p go
* to new p2p go's channel
*
* @psoc: PSOC object information
* @vdev_id: Vdev id
* @ch_freq: Channel frequency to change
* @ch_width: channel width to change
*
* starts delayed work queue of 1 second to move first p2p go to new
* p2p go's channel.
*
* Return: None
*/
void policy_mgr_process_forcescc_for_go(
struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
uint32_t ch_freq, uint32_t ch_width);
/**
* policy_mgr_do_go_plus_go_force_scc() - First p2p go
* to new p2p go's channel
*
* @psoc: PSOC object information
* @vdev_id: Vdev id
* @ch_freq: Channel frequency to change
* @ch_width: channel width to change
*
* Move first p2p go to new
* p2p go's channel.
*
* Return: None
*/
void policy_mgr_do_go_plus_go_force_scc(
struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
uint32_t ch_freq, uint32_t ch_width);
#else
static inline
bool policy_mgr_is_go_scc_strict(struct wlan_objmgr_psoc *psoc)
{
return false;
}
static inline
uint8_t policy_mgr_check_forcescc_for_other_go(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id,
uint32_t curr_go_freq)
{
return WLAN_UMAC_VDEV_ID_MAX;
}
static inline
void policy_mgr_process_forcescc_for_go(
struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
uint32_t ch_freq, uint32_t ch_width)
{}
static inline
void policy_mgr_do_go_plus_go_force_scc(
struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
uint32_t ch_freq, uint32_t ch_width)
{}
#endif
/**
* policy_mgr_set_pcl_for_existing_combo() - SET PCL for existing combo
* @psoc: PSOC object information

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. 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
@ -548,12 +549,19 @@ CFG_INI_UINT("g_mark_sap_indoor_as_disable", 0, 1, 0, CFG_VALUE_OR_DEFAULT, \
* <ini>
* g_enable_go_force_scc - Enable/Disable force SCC on P2P GO
* @Min: 0
* @Max: 1
* @Max: 2
* @Default: 0
*
* This ini and along with "gWlanMccToSccSwitchMode" is used to enable
* force SCC on P2P GO interface.
*
* GO_FORCE_SCC_DISABLED (value 0): GO force scc disabled and GO can come up
* in MCC mode
* GO_FORCE_SCC_STRICT (value 1): New GO will be forced to form on existing
* GO/STA/GC channel in start bss itself.
* GO_FORCE_SCC_LIBERAL (value 2): After SET KEY is done, do force SCC for the
* first GO to move to new GO channel.
*
* Supported Feature: P2P GO
*
* Usage: External
@ -562,7 +570,7 @@ CFG_INI_UINT("g_mark_sap_indoor_as_disable", 0, 1, 0, CFG_VALUE_OR_DEFAULT, \
*/
#define CFG_P2P_GO_ENABLE_FORCE_SCC \
CFG_INI_UINT("g_enable_go_force_scc", 0, 1, 0, CFG_VALUE_OR_DEFAULT, \
CFG_INI_UINT("g_enable_go_force_scc", 0, 2, 0, CFG_VALUE_OR_DEFAULT, \
"Enable/Disable P2P GO force SCC")
/**

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. 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
@ -1284,12 +1285,30 @@ struct connection_info {
uint32_t ch_freq;
};
/**
* struct go_plus_go_force_scc - structure to hold p2p go
* params for forcescc restart
*
* @vdev_id: vdev id of first p2p go which needs to do csa
* @ch_freq: ch freq of curr p2p go
* @ch_width: ch width of curr p2p go
*/
struct go_plus_go_force_scc {
uint8_t vdev_id;
uint32_t ch_freq;
uint32_t ch_width;
};
/**
* struct sta_ap_intf_check_work_ctx - sta_ap_intf_check_work
* related info
* @psoc: pointer to PSOC object information
* @go_plus_go_force_scc: structure to hold params of
* curr and first p2p go ctx
*/
struct sta_ap_intf_check_work_ctx {
struct wlan_objmgr_psoc *psoc;
struct go_plus_go_force_scc go_plus_go_force_scc;
};
#endif /* __WLAN_POLICY_MGR_PUBLIC_STRUCT_H */

View file

@ -1988,6 +1988,22 @@ static void __policy_mgr_check_sta_ap_concurrent_ch_intf(
policy_mgr_err("Invalid context");
return;
}
/*
* Check if force scc is required for GO + GO case. vdev id will be
* valid in case of GO+GO force scc only. So, for valid vdev id move
* first GO to newly formed GO channel.
*/
policy_mgr_debug("p2p go vdev id: %d",
pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.vdev_id);
if (pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.vdev_id <
WLAN_UMAC_VDEV_ID_MAX) {
policy_mgr_do_go_plus_go_force_scc(
pm_ctx->psoc, pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.vdev_id,
pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.ch_freq,
pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.ch_width);
pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.vdev_id = WLAN_UMAC_VDEV_ID_MAX;
return;
}
mcc_to_scc_switch =
policy_mgr_get_mcc_to_scc_switch_mode(pm_ctx->psoc);
@ -2498,6 +2514,56 @@ void policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc,
}
#endif
#ifdef WLAN_FEATURE_P2P_P2P_STA
void policy_mgr_do_go_plus_go_force_scc(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id, uint32_t ch_freq,
uint32_t ch_width)
{
uint8_t total_connection;
total_connection = policy_mgr_mode_specific_connection_count(
psoc, PM_P2P_GO_MODE, NULL);
policy_mgr_debug("Total p2p go connection %d", total_connection);
/* If any p2p disconnected, don't do csa */
if (total_connection > 1) {
policy_mgr_change_sap_channel_with_csa(psoc, vdev_id,
ch_freq, ch_width, true);
}
}
void policy_mgr_process_forcescc_for_go(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id, uint32_t ch_freq,
uint32_t ch_width)
{
struct policy_mgr_psoc_priv_obj *pm_ctx;
pm_ctx = policy_mgr_get_context(psoc);
if (!pm_ctx) {
policy_mgr_err("Invalid Context");
return;
}
if (!pm_ctx->sta_ap_intf_check_work_info) {
policy_mgr_err("invalid work info");
return;
}
pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.vdev_id =
vdev_id;
pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.ch_freq =
ch_freq;
pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.ch_width =
ch_width;
if (!qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work,
WAIT_BEFORE_GO_FORCESCC_RESTART)) {
policy_mgr_err("change interface request failure");
pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.vdev_id =
WLAN_UMAC_VDEV_ID_MAX;
}
}
#endif
QDF_STATUS policy_mgr_wait_for_connection_update(struct wlan_objmgr_psoc *psoc)
{
QDF_STATUS status;

View file

@ -4628,6 +4628,63 @@ bool policy_mgr_go_scc_enforced(struct wlan_objmgr_psoc *psoc)
return false;
}
#ifdef WLAN_FEATURE_P2P_P2P_STA
uint8_t
policy_mgr_check_forcescc_for_other_go(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id, uint32_t freq)
{
struct policy_mgr_psoc_priv_obj *pm_ctx;
uint32_t conn_index;
pm_ctx = policy_mgr_get_context(psoc);
if (!pm_ctx) {
policy_mgr_err("Invalid Context");
return WLAN_UMAC_VDEV_ID_MAX;
}
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].mode ==
PM_P2P_GO_MODE &&
pm_conc_connection_list[conn_index].in_use &&
wlan_reg_is_same_band_freqs(
freq,
pm_conc_connection_list[conn_index].freq) &&
freq != pm_conc_connection_list[conn_index].freq &&
vdev_id != pm_conc_connection_list[conn_index].vdev_id) {
qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
policy_mgr_debug(
"Existing p2p go vdev_id is %d",
pm_conc_connection_list[conn_index].vdev_id);
return pm_conc_connection_list[conn_index].vdev_id;
}
}
qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
return WLAN_UMAC_VDEV_ID_MAX;
}
bool policy_mgr_is_go_scc_strict(struct wlan_objmgr_psoc *psoc)
{
struct policy_mgr_psoc_priv_obj *pm_ctx;
bool ret = false;
pm_ctx = policy_mgr_get_context(psoc);
if (!pm_ctx) {
ret = false;
goto return_val;
}
if (pm_ctx->cfg.go_force_scc & GO_FORCE_SCC_STRICT) {
ret = true;
goto return_val;
}
ret = false;
return_val:
policy_mgr_debug("ret val is %d", ret);
return ret;
}
#endif
QDF_STATUS policy_mgr_update_nan_vdev_mac_info(struct wlan_objmgr_psoc *psoc,
uint8_t nan_vdev_id,
uint8_t mac_id)

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. 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
@ -339,6 +339,8 @@ QDF_STATUS policy_mgr_psoc_open(struct wlan_objmgr_psoc *psoc)
return QDF_STATUS_E_FAILURE;
}
pm_ctx->sta_ap_intf_check_work_info->psoc = psoc;
pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.vdev_id =
WLAN_UMAC_VDEV_ID_MAX;
if (QDF_IS_STATUS_ERROR(qdf_delayed_work_create(
&pm_ctx->sta_ap_intf_check_work,
policy_mgr_check_sta_ap_concurrent_ch_intf,

View file

@ -6361,6 +6361,9 @@ wlan_hdd_ap_ap_force_scc_override(struct hdd_adapter *adapter,
return false;
}
if (adapter->device_mode == QDF_P2P_GO_MODE &&
policy_mgr_is_p2p_p2p_conc_supported(hdd_ctx->psoc))
return false;
if (!policy_mgr_concurrent_beaconing_sessions_running(hdd_ctx->psoc))
return false;
if (policy_mgr_dual_beacon_on_single_mac_mcc_capable(hdd_ctx->psoc))

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. 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
@ -829,6 +830,51 @@ static void wlansap_update_vendor_acs_chan(struct mac_context *mac_ctx,
}
}
#ifdef WLAN_FEATURE_P2P_P2P_STA
/**
* sap_check_and_process_forcescc_for_other_go() - find if other p2p go is there
* and needs to be moved to current p2p go's channel.
*
* @cur_sap_ctx: current sap context
*
* Return: None
*/
static void
sap_check_and_process_forcescc_for_other_go(struct sap_context *cur_sap_ctx)
{
struct sap_context *sap_ctx;
struct mac_context *mac_ctx;
uint8_t i;
mac_ctx = sap_get_mac_context();
if (!mac_ctx) {
sap_err("Invalid MAC context");
return;
}
for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
sap_ctx = mac_ctx->sap.sapCtxList[i].sap_context;
if (sap_ctx &&
QDF_P2P_GO_MODE == mac_ctx->sap.sapCtxList[i].sapPersona &&
sap_ctx->is_forcescc_restart_required) {
sap_debug("sessionId %d chan_freq %d chan_width %d",
sap_ctx->sessionId, cur_sap_ctx->chan_freq,
cur_sap_ctx->ch_params.ch_width);
policy_mgr_process_forcescc_for_go(
mac_ctx->psoc, sap_ctx->sessionId,
cur_sap_ctx->chan_freq,
cur_sap_ctx->ch_params.ch_width);
sap_ctx->is_forcescc_restart_required = false;
break;
}
}
}
#else
static void
sap_check_and_process_forcescc_for_other_go(struct sap_context *cur_sap_ctx)
{}
#endif
QDF_STATUS wlansap_roam_callback(void *ctx,
struct csr_roam_info *csr_roam_info,
uint32_t roam_id,
@ -1157,10 +1203,25 @@ QDF_STATUS wlansap_roam_callback(void *ctx,
* disassoc event
* Fill in the event structure
*/
if (roam_status == eCSR_ROAM_SET_KEY_COMPLETE)
if (roam_status == eCSR_ROAM_SET_KEY_COMPLETE) {
sap_signal_hdd_event(sap_ctx, csr_roam_info,
eSAP_STA_SET_KEY_EVENT,
(void *) eSAP_STATUS_SUCCESS);
/*
* After set key if this is the first peer connecting to new GO
* then check for peer count (which is self peer + peer count)
* and take decision for GO+GO force SCC
*/
if (sap_ctx->vdev->vdev_mlme.vdev_opmode ==
QDF_P2P_GO_MODE &&
wlan_vdev_get_peer_count(sap_ctx->vdev) == 2 &&
policy_mgr_mode_specific_connection_count(
mac_ctx->psoc, PM_P2P_GO_MODE,
NULL) > 1)
sap_check_and_process_forcescc_for_other_go(
sap_ctx);
}
break;
case eCSR_ROAM_RESULT_MAX_ASSOC_EXCEEDED:
/* Fill in the event structure */

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. 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
@ -784,6 +784,41 @@ static bool is_mcc_preferred(struct sap_context *sap_context,
return false;
}
#ifdef WLAN_FEATURE_P2P_P2P_STA
/**
* sap_set_forcescc_required - set force scc flag for provided p2p go vdev
*
* vdev_id - vdev_id for which flag needs to be set
*
* Return: None
*/
static void sap_set_forcescc_required(uint8_t vdev_id)
{
struct mac_context *mac_ctx;
struct sap_context *sap_ctx;
uint8_t i = 0;
mac_ctx = sap_get_mac_context();
if (!mac_ctx) {
sap_err("Invalid MAC context");
return;
}
for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
sap_ctx = mac_ctx->sap.sapCtxList[i].sap_context;
if (QDF_P2P_GO_MODE == mac_ctx->sap.sapCtxList[i].sapPersona &&
sap_ctx->sessionId == vdev_id) {
sap_debug("update forcescc restart for vdev %d",
vdev_id);
sap_ctx->is_forcescc_restart_required = true;
}
}
}
#else
static void sap_set_forcescc_required(uint8_t vdev_id)
{}
#endif
QDF_STATUS
sap_validate_chan(struct sap_context *sap_context,
bool pre_start_bss,
@ -799,6 +834,8 @@ sap_validate_chan(struct sap_context *sap_context,
uint32_t concurrent_state;
bool go_force_scc;
struct ch_params ch_params = {0};
bool is_go_scc_strict = false;
uint8_t first_p2p_go_vdev_id = WLAN_UMAC_VDEV_ID_MAX;
mac_handle = cds_get_context(QDF_MODULE_ID_SME);
mac_ctx = MAC_CONTEXT(mac_handle);
@ -812,10 +849,45 @@ sap_validate_chan(struct sap_context *sap_context,
sap_err("Invalid channel");
return QDF_STATUS_E_FAILURE;
}
go_force_scc = policy_mgr_go_scc_enforced(mac_ctx->psoc);
if (sap_context->vdev && !go_force_scc &&
(wlan_vdev_mlme_get_opmode(sap_context->vdev) == QDF_P2P_GO_MODE))
goto validation_done;
if (sap_context->vdev &&
sap_context->vdev->vdev_mlme.vdev_opmode == QDF_P2P_GO_MODE) {
/*
* check whether go_force_scc is enabled or not.
* If it not enabled then don't any force scc on existing and new
* p2p go vdevs.
* Otherwise, if it is enabled then check whether it's in strict
* mode or liberal mode.
* For strict mode, do force scc on newly p2p go to existing p2p
* go channel.
* For liberal mode, first form new p2p go on requested channel.
* Once set key is done, do force scc on existing p2p go to new
* p2p go channel.
*/
go_force_scc = policy_mgr_go_scc_enforced(mac_ctx->psoc);
sap_debug("go force scc value %d", go_force_scc);
if (go_force_scc) {
is_go_scc_strict =
policy_mgr_is_go_scc_strict(mac_ctx->psoc);
if (!is_go_scc_strict) {
sap_debug("liberal mode is enabled");
first_p2p_go_vdev_id =
policy_mgr_check_forcescc_for_other_go(
mac_ctx->psoc,
sap_context->sessionId,
sap_context->chan_freq);
if (first_p2p_go_vdev_id <
WLAN_UMAC_VDEV_ID_MAX) {
sap_set_forcescc_required(
first_p2p_go_vdev_id);
goto validation_done;
}
}
} else {
goto validation_done;
}
}
concurrent_state = policy_mgr_get_concurrency_mode(mac_ctx->psoc);
if (policy_mgr_concurrent_beaconing_sessions_running(mac_ctx->psoc) ||

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. 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
@ -230,6 +231,13 @@ struct sap_context {
bool is_chan_change_inprogress;
qdf_list_t owe_pending_assoc_ind_list;
uint32_t freq_before_ch_switch;
#ifdef WLAN_FEATURE_P2P_P2P_STA
/*
*This param is used for GO+GO force scc logic where after
*setkey first GO will move to latest GO's channel
*/
bool is_forcescc_restart_required;
#endif
};
/*----------------------------------------------------------------------------