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:
Rachit Kankane
2023-01-30 13:04:04 +05:30
committato da Madan Koyyalamudi
parent 8c8aae44eb
commit 4eec1b8e78
4 ha cambiato i file con 228 aggiunte e 5 eliminazioni

Vedi File

@@ -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

Vedi File

@@ -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,

Vedi File

@@ -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);

Vedi File

@@ -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))