qcacld-3.0: Restart SAP / GO before STA
In STA + SAP / GO DFS SCC concurrency, switch SAP / GO's operating channel before STA's switch upon received very first CSA on STA interface from peer AP. Once STA moves to new channel, enforce SCC with existing SAP / GO if its in MCC. This is done to allow traffic on SAP / GO side during CSA period. Change-Id: Icb4a15ad21ae96faff1fe338985aa734a4398cd2 CRs-Fixed: 3431386
This commit is contained in:

committato da
Madan Koyyalamudi

parent
8c8aae44eb
commit
4eec1b8e78
@@ -850,6 +850,42 @@ policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* policy_mgr_sta_sap_dfs_scc_conc_check() - validate and Move SAP channel
|
||||||
|
* using (E)CSA
|
||||||
|
*
|
||||||
|
* @psoc: PSOC object information
|
||||||
|
* @vdev_id: Vdev id
|
||||||
|
* @csa_event: Pointer to CSA IE Received event data
|
||||||
|
*
|
||||||
|
* Invoke the function to change SAP channel using (E)CSA for STA+GO / SAP
|
||||||
|
* SCC scenario only. This function will move P2P-GO / SAP first and then STA
|
||||||
|
* will follow.
|
||||||
|
*
|
||||||
|
* Return: QDF_STATUS_SUCCESS on success
|
||||||
|
*/
|
||||||
|
QDF_STATUS
|
||||||
|
policy_mgr_sta_sap_dfs_scc_conc_check(struct wlan_objmgr_psoc *psoc,
|
||||||
|
uint8_t vdev_id,
|
||||||
|
struct csa_offload_params *csa_event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* policy_mgr_sta_sap_dfs_enforce_scc() - validate and enforce SCC
|
||||||
|
* using (E)CSA upon receiving 1st beacon
|
||||||
|
*
|
||||||
|
* @psoc: PSOC object information
|
||||||
|
* @vdev_id: Vdev id
|
||||||
|
*
|
||||||
|
* Invoke the function to enforce SCC upon receiving 1st beacon. SAP / GO
|
||||||
|
* movement will be triggered using (E)CSA for STA+GO / SAP DFS scenario only.
|
||||||
|
* The pre-requisite for this function is SAP / GO shall already moved to new
|
||||||
|
* channel by policy_mgr_sta_sap_dfs_scc_conc_check() function.
|
||||||
|
*
|
||||||
|
* Return: void
|
||||||
|
*/
|
||||||
|
void policy_mgr_sta_sap_dfs_enforce_scc(struct wlan_objmgr_psoc *psoc,
|
||||||
|
uint8_t vdev_id);
|
||||||
|
|
||||||
#ifdef WLAN_FEATURE_P2P_P2P_STA
|
#ifdef WLAN_FEATURE_P2P_P2P_STA
|
||||||
/**
|
/**
|
||||||
* policy_mgr_is_p2p_p2p_conc_supported() - p2p concurrency support
|
* policy_mgr_is_p2p_p2p_conc_supported() - p2p concurrency support
|
||||||
|
@@ -2879,6 +2879,176 @@ policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc,
|
|||||||
}
|
}
|
||||||
#endif /* FEATURE_WLAN_MCC_TO_SCC_SWITCH */
|
#endif /* FEATURE_WLAN_MCC_TO_SCC_SWITCH */
|
||||||
|
|
||||||
|
QDF_STATUS
|
||||||
|
policy_mgr_sta_sap_dfs_scc_conc_check(struct wlan_objmgr_psoc *psoc,
|
||||||
|
uint8_t vdev_id,
|
||||||
|
struct csa_offload_params *csa_event)
|
||||||
|
{
|
||||||
|
uint8_t concur_vdev_id, i;
|
||||||
|
bool move_sap_go_first;
|
||||||
|
enum hw_mode_bandwidth bw;
|
||||||
|
qdf_freq_t cur_freq, new_freq;
|
||||||
|
struct wlan_objmgr_vdev *vdev, *conc_vdev;
|
||||||
|
struct wlan_objmgr_pdev *pdev;
|
||||||
|
struct policy_mgr_psoc_priv_obj *pm_ctx;
|
||||||
|
enum policy_mgr_con_mode cur_mode;
|
||||||
|
enum policy_mgr_con_mode concur_mode = PM_MAX_NUM_OF_MODE;
|
||||||
|
|
||||||
|
pm_ctx = policy_mgr_get_context(psoc);
|
||||||
|
if (!pm_ctx) {
|
||||||
|
policy_mgr_err("Invalid context");
|
||||||
|
return QDF_STATUS_E_INVAL;
|
||||||
|
}
|
||||||
|
if (!csa_event) {
|
||||||
|
policy_mgr_err("CSA IE Received event is NULL");
|
||||||
|
return QDF_STATUS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
policy_mgr_get_dfs_sta_sap_go_scc_movement(psoc, &move_sap_go_first);
|
||||||
|
if (!move_sap_go_first) {
|
||||||
|
policy_mgr_err("g_move_sap_go_1st_on_dfs_sta_csa is disabled");
|
||||||
|
return QDF_STATUS_E_NOSUPPORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_mode = policy_mgr_get_mode_by_vdev_id(psoc, vdev_id);
|
||||||
|
if (cur_mode != PM_STA_MODE) {
|
||||||
|
policy_mgr_err("CSA received on non-STA connection");
|
||||||
|
return QDF_STATUS_E_INVAL;
|
||||||
|
}
|
||||||
|
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
|
||||||
|
WLAN_POLICY_MGR_ID);
|
||||||
|
if (!vdev) {
|
||||||
|
policy_mgr_err("vdev is NULL");
|
||||||
|
return QDF_STATUS_E_INVAL;
|
||||||
|
}
|
||||||
|
pdev = wlan_vdev_get_pdev(vdev);
|
||||||
|
cur_freq = wlan_get_operation_chan_freq_vdev_id(pdev, vdev_id);
|
||||||
|
|
||||||
|
if (!wlan_reg_is_dfs_for_freq(pdev, cur_freq) &&
|
||||||
|
!wlan_reg_is_freq_indoor(pdev, cur_freq)) {
|
||||||
|
policy_mgr_err("SAP / GO operating channel is non-DFS");
|
||||||
|
wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
|
||||||
|
return QDF_STATUS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if there is any SAP / GO operating on the same channel or not
|
||||||
|
* If yes, then get the current bandwidth and vdev_id of concurrent SAP
|
||||||
|
* or GO and trigger channel switch to new channel received in CSA on
|
||||||
|
* STA interface. If this new channel is DFS then trigger channel
|
||||||
|
* switch to non-DFS channel. Once STA moves to this new channel and
|
||||||
|
* when it receives very first beacon, it will then enforce SCC again
|
||||||
|
*/
|
||||||
|
for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
|
||||||
|
if (pm_conc_connection_list[i].in_use &&
|
||||||
|
pm_conc_connection_list[i].freq == cur_freq &&
|
||||||
|
pm_conc_connection_list[i].vdev_id != vdev_id &&
|
||||||
|
(pm_conc_connection_list[i].mode == PM_P2P_GO_MODE ||
|
||||||
|
pm_conc_connection_list[i].mode == PM_SAP_MODE)) {
|
||||||
|
concur_mode = pm_conc_connection_list[i].mode;
|
||||||
|
bw = pm_conc_connection_list[i].bw;
|
||||||
|
concur_vdev_id = pm_conc_connection_list[i].vdev_id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If there is no concurrent SAP / GO, then return */
|
||||||
|
if (concur_mode == PM_MAX_NUM_OF_MODE) {
|
||||||
|
wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
|
||||||
|
return QDF_STATUS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
conc_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, concur_vdev_id,
|
||||||
|
WLAN_POLICY_MGR_ID);
|
||||||
|
if (!conc_vdev) {
|
||||||
|
policy_mgr_err("conc_vdev is NULL");
|
||||||
|
wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
|
||||||
|
return QDF_STATUS_E_INVAL;
|
||||||
|
}
|
||||||
|
wlan_vdev_mlme_set_sap_go_move_before_sta(conc_vdev, true);
|
||||||
|
wlan_vdev_mlme_set_sap_go_move_before_sta(vdev, true);
|
||||||
|
wlan_objmgr_vdev_release_ref(conc_vdev, WLAN_POLICY_MGR_ID);
|
||||||
|
wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
|
||||||
|
|
||||||
|
/*Change the CSA count*/
|
||||||
|
if (pm_ctx->sme_cbacks.sme_change_sap_csa_count)
|
||||||
|
/* Total 4 CSA frames are allowed so that GO / SAP
|
||||||
|
* will move to new channel within 500ms
|
||||||
|
*/
|
||||||
|
pm_ctx->sme_cbacks.sme_change_sap_csa_count(4);
|
||||||
|
new_freq = csa_event->csa_chan_freq;
|
||||||
|
|
||||||
|
/* If the new channel is DFS or indoor, then select another channel
|
||||||
|
* and switch the SAP / GO to avoid CAC. This will resume traffic on
|
||||||
|
* SAP / GO interface immediately. Once STA moves to this new channel
|
||||||
|
* and receives the very first beacon, then it will enforece SCC
|
||||||
|
*/
|
||||||
|
if (wlan_reg_is_dfs_for_freq(pdev, new_freq) ||
|
||||||
|
wlan_reg_is_freq_indoor(pdev, new_freq)) {
|
||||||
|
if (wlan_reg_is_24ghz_ch_freq(new_freq)) {
|
||||||
|
new_freq = wlan_reg_min_24ghz_chan_freq();
|
||||||
|
} else if (wlan_reg_is_5ghz_ch_freq(new_freq)) {
|
||||||
|
new_freq = wlan_reg_min_5ghz_chan_freq();
|
||||||
|
/* if none of the 5G channel is non-DFS */
|
||||||
|
if (wlan_reg_is_dfs_for_freq(pdev, new_freq) ||
|
||||||
|
wlan_reg_is_freq_indoor(pdev, new_freq))
|
||||||
|
new_freq = policy_mgr_get_nondfs_preferred_channel(psoc,
|
||||||
|
concur_mode,
|
||||||
|
true,
|
||||||
|
concur_vdev_id);
|
||||||
|
} else {
|
||||||
|
new_freq = wlan_reg_min_6ghz_chan_freq();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
policy_mgr_debug("Restart vdev: %u on freq: %u",
|
||||||
|
concur_vdev_id, new_freq);
|
||||||
|
|
||||||
|
return policy_mgr_change_sap_channel_with_csa(psoc, concur_vdev_id,
|
||||||
|
new_freq, bw, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void policy_mgr_sta_sap_dfs_enforce_scc(struct wlan_objmgr_psoc *psoc,
|
||||||
|
uint8_t vdev_id)
|
||||||
|
{
|
||||||
|
bool is_sap_go_moved_before_sta, move_sap_go_first;
|
||||||
|
struct policy_mgr_psoc_priv_obj *pm_ctx;
|
||||||
|
struct wlan_objmgr_vdev *vdev;
|
||||||
|
struct wlan_objmgr_pdev *pdev;
|
||||||
|
enum policy_mgr_con_mode cur_mode;
|
||||||
|
|
||||||
|
pm_ctx = policy_mgr_get_context(psoc);
|
||||||
|
if (!pm_ctx) {
|
||||||
|
policy_mgr_err("Invalid context");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
|
||||||
|
WLAN_POLICY_MGR_ID);
|
||||||
|
if (!vdev) {
|
||||||
|
policy_mgr_err("vdev is NULL");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
is_sap_go_moved_before_sta =
|
||||||
|
wlan_vdev_mlme_is_sap_go_move_before_sta(vdev);
|
||||||
|
pdev = wlan_vdev_get_pdev(vdev);
|
||||||
|
wlan_vdev_mlme_set_sap_go_move_before_sta(vdev, false);
|
||||||
|
wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
|
||||||
|
|
||||||
|
policy_mgr_get_dfs_sta_sap_go_scc_movement(psoc, &move_sap_go_first);
|
||||||
|
if (!is_sap_go_moved_before_sta || !move_sap_go_first) {
|
||||||
|
policy_mgr_debug("SAP / GO moved before STA: %u INI g_move_sap_go_1st_on_dfs_sta_csa: %u",
|
||||||
|
is_sap_go_moved_before_sta, move_sap_go_first);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_mode = policy_mgr_get_mode_by_vdev_id(psoc, vdev_id);
|
||||||
|
if (cur_mode != PM_STA_MODE) {
|
||||||
|
policy_mgr_err("CSA received on non-STA connection");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
policy_mgr_debug("Enforce SCC");
|
||||||
|
policy_mgr_check_concurrent_intf_and_restart_sap(psoc, false);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef WLAN_FEATURE_P2P_P2P_STA
|
#ifdef WLAN_FEATURE_P2P_P2P_STA
|
||||||
void policy_mgr_do_go_plus_go_force_scc(struct wlan_objmgr_psoc *psoc,
|
void policy_mgr_do_go_plus_go_force_scc(struct wlan_objmgr_psoc *psoc,
|
||||||
uint8_t vdev_id, uint32_t ch_freq,
|
uint8_t vdev_id, uint32_t ch_freq,
|
||||||
|
@@ -2537,7 +2537,8 @@ lim_process_beacon_tx_success_ind(struct mac_context *mac_ctx, uint16_t msgType,
|
|||||||
void *event)
|
void *event)
|
||||||
{
|
{
|
||||||
struct pe_session *session;
|
struct pe_session *session;
|
||||||
bool csa_tx_offload;
|
struct wlan_objmgr_vdev *vdev;
|
||||||
|
bool csa_tx_offload, is_sap_go_moved_before_sta = false;
|
||||||
tpSirFirstBeaconTxCompleteInd bcn_ind =
|
tpSirFirstBeaconTxCompleteInd bcn_ind =
|
||||||
(tSirFirstBeaconTxCompleteInd *) event;
|
(tSirFirstBeaconTxCompleteInd *) event;
|
||||||
|
|
||||||
@@ -2547,11 +2548,21 @@ lim_process_beacon_tx_success_ind(struct mac_context *mac_ctx, uint16_t msgType,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pe_debug("role: %d swIe: %d opIe: %d switch cnt:%d",
|
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc,
|
||||||
|
session->vdev_id,
|
||||||
|
WLAN_LEGACY_MAC_ID);
|
||||||
|
if (vdev) {
|
||||||
|
is_sap_go_moved_before_sta =
|
||||||
|
wlan_vdev_mlme_is_sap_go_move_before_sta(vdev);
|
||||||
|
wlan_vdev_mlme_set_sap_go_move_before_sta(vdev, false);
|
||||||
|
wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
|
||||||
|
}
|
||||||
|
pe_debug("role: %d swIe: %d opIe: %d switch cnt:%d Is SAP / GO Moved before STA: %d",
|
||||||
GET_LIM_SYSTEM_ROLE(session),
|
GET_LIM_SYSTEM_ROLE(session),
|
||||||
session->dfsIncludeChanSwIe,
|
session->dfsIncludeChanSwIe,
|
||||||
session->gLimOperatingMode.present,
|
session->gLimOperatingMode.present,
|
||||||
session->gLimChannelSwitch.switchCount);
|
session->gLimChannelSwitch.switchCount,
|
||||||
|
is_sap_go_moved_before_sta);
|
||||||
|
|
||||||
if (!LIM_IS_AP_ROLE(session))
|
if (!LIM_IS_AP_ROLE(session))
|
||||||
return;
|
return;
|
||||||
@@ -2560,7 +2571,8 @@ lim_process_beacon_tx_success_ind(struct mac_context *mac_ctx, uint16_t msgType,
|
|||||||
if (session->dfsIncludeChanSwIe && !csa_tx_offload &&
|
if (session->dfsIncludeChanSwIe && !csa_tx_offload &&
|
||||||
((session->gLimChannelSwitch.switchCount ==
|
((session->gLimChannelSwitch.switchCount ==
|
||||||
mac_ctx->sap.SapDfsInfo.sap_ch_switch_beacon_cnt) ||
|
mac_ctx->sap.SapDfsInfo.sap_ch_switch_beacon_cnt) ||
|
||||||
(session->gLimChannelSwitch.switchCount == 1)))
|
(session->gLimChannelSwitch.switchCount == 1) ||
|
||||||
|
is_sap_go_moved_before_sta))
|
||||||
lim_process_ap_ecsa_timeout(session);
|
lim_process_ap_ecsa_timeout(session);
|
||||||
|
|
||||||
|
|
||||||
|
@@ -669,7 +669,7 @@ static void __sch_beacon_process_for_session(struct mac_context *mac_ctx,
|
|||||||
bool ap_constraint_change = false, tpe_change = false;
|
bool ap_constraint_change = false, tpe_change = false;
|
||||||
int8_t regMax = 0, maxTxPower = 0;
|
int8_t regMax = 0, maxTxPower = 0;
|
||||||
QDF_STATUS status;
|
QDF_STATUS status;
|
||||||
bool skip_tpe = false;
|
bool skip_tpe = false, is_sap_go_switched_ch;
|
||||||
uint8_t programmed_country[REG_ALPHA2_LEN + 1];
|
uint8_t programmed_country[REG_ALPHA2_LEN + 1];
|
||||||
enum reg_6g_ap_type pwr_type_6g = REG_INDOOR_AP;
|
enum reg_6g_ap_type pwr_type_6g = REG_INDOOR_AP;
|
||||||
bool ctry_code_match = false;
|
bool ctry_code_match = false;
|
||||||
@@ -691,6 +691,11 @@ static void __sch_beacon_process_for_session(struct mac_context *mac_ctx,
|
|||||||
beaconParams.paramChangeBitmap = 0;
|
beaconParams.paramChangeBitmap = 0;
|
||||||
|
|
||||||
if (LIM_IS_STA_ROLE(session)) {
|
if (LIM_IS_STA_ROLE(session)) {
|
||||||
|
is_sap_go_switched_ch =
|
||||||
|
wlan_vdev_mlme_is_sap_go_move_before_sta(session->vdev);
|
||||||
|
if (is_sap_go_switched_ch)
|
||||||
|
policy_mgr_sta_sap_dfs_enforce_scc(mac_ctx->psoc,
|
||||||
|
session->vdev_id);
|
||||||
if (false == sch_bcn_process_sta(mac_ctx, bcn, rx_pkt_info,
|
if (false == sch_bcn_process_sta(mac_ctx, bcn, rx_pkt_info,
|
||||||
session, &beaconParams,
|
session, &beaconParams,
|
||||||
&sendProbeReq, pMh))
|
&sendProbeReq, pMh))
|
||||||
|
Fai riferimento in un nuovo problema
Block a user