Browse Source

qcacld-3.0: Select a different channel than self for SAP restart

Scenario of the issue is :-
1. Keep sta+sap_scc_dfs_ch as 0 to disable the dfs concurrency
2. Start a SAP on any 5ghz channel(NON-DFS).
3. Start a STA on a DFS channel.

Expectation: The SAP should not do MCC, SCC as the above
mentioned ini is 0, also MCC is not prefereed in a HW
solution where DFS is preferred, hence the SAP should go
to 2.4ghz and DBS should be the expectation.

Observation: The SAP does not do a DBS operation, and falls to
MCC here.

Reason: When the SAP gets a PCL in the path of SAP restart,
the PCL feels that a new SAP is going to come up, and hence
gives the best channel (first element of PCL ) as its own,
which leads to restart being rejected, as the SAP cannot start
on a channel which is the same as existing.
The final channel then selected is the STA channel, leading to
DFS SCC which is also not allowed. Hence the SAP is now stuck
in MCC(STA+SAP , one on DFS, and the other on NON-DFS channel).

Fix: The fix is to get an alternate channel for SAP restart, other
than the channel on which the SAP is already up, to lead to DBS,
if the STA channel is not suitable for SCC operaion.

Change-Id: Iab3ad22b2f970ca26ce3e6bc7a9b5ee34bc7e7ba
CRs-Fixed: 2443718
gaurank kathpalia 6 years ago
parent
commit
b8db936cfe

+ 7 - 2
components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h

@@ -2555,24 +2555,29 @@ bool policy_mgr_is_force_scc(struct wlan_objmgr_psoc *psoc);
  * @psoc: PSOC object information
  * @con_ch: pointer to the channel on which sap will come up
  * @sap_ch: initial channel for SAP
+ * @sap_vdev_id: sap vdev id.
  *
  * This function checks & updates the channel SAP to come up on in
  * case of STA+SAP concurrency
  * Return: Success if SAP can come up on a channel
  */
 QDF_STATUS policy_mgr_valid_sap_conc_channel_check(
-	struct wlan_objmgr_psoc *psoc, uint8_t *con_ch, uint8_t sap_ch);
+	struct wlan_objmgr_psoc *psoc, uint8_t *con_ch, uint8_t sap_ch,
+	uint8_t sap_vdev_id);
 
 /**
  * policy_mgr_get_alternate_channel_for_sap() - Get an alternate
  * channel to move the SAP to
  * @psoc: PSOC object information
+ * @sap_vdev_id: sap vdev id.
+ * @sap_channel: sap channel.
  *
  * This function returns an alternate channel for SAP to move to
  * Return: The new channel for SAP
  */
 uint8_t policy_mgr_get_alternate_channel_for_sap(
-	struct wlan_objmgr_psoc *psoc);
+	struct wlan_objmgr_psoc *psoc, uint8_t sap_vdev_id,
+	uint8_t sap_channel);
 
 /**
  * policy_mgr_disallow_mcc() - Check for mcc

+ 5 - 2
components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c

@@ -1742,7 +1742,8 @@ static bool policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc *psoc,
 }
 
 QDF_STATUS policy_mgr_valid_sap_conc_channel_check(
-	struct wlan_objmgr_psoc *psoc, uint8_t *con_ch, uint8_t sap_ch)
+	struct wlan_objmgr_psoc *psoc, uint8_t *con_ch, uint8_t sap_ch,
+	uint8_t sap_vdev_id)
 {
 	uint8_t channel = *con_ch;
 	uint8_t temp_channel = 0;
@@ -1795,7 +1796,9 @@ QDF_STATUS policy_mgr_valid_sap_conc_channel_check(
 
 			if (policy_mgr_is_hw_dbs_capable(psoc)) {
 				temp_channel =
-				policy_mgr_get_alternate_channel_for_sap(psoc);
+				policy_mgr_get_alternate_channel_for_sap(psoc,
+								sap_vdev_id,
+								sap_ch);
 				policy_mgr_debug("temp_channel is %d",
 					temp_channel);
 				if (temp_channel) {

+ 34 - 3
components/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c

@@ -1997,18 +1997,49 @@ uint8_t policy_mgr_mode_specific_get_channel(
 }
 
 uint8_t policy_mgr_get_alternate_channel_for_sap(
-	struct wlan_objmgr_psoc *psoc)
+	struct wlan_objmgr_psoc *psoc, uint8_t sap_vdev_id,
+	uint8_t sap_channel)
 {
 	uint8_t pcl_channels[QDF_MAX_NUM_CHAN];
 	uint8_t pcl_weight[QDF_MAX_NUM_CHAN];
 	uint8_t channel = 0;
 	uint32_t pcl_len = 0;
+	struct policy_mgr_conc_connection_info info;
+	uint8_t num_cxn_del = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	uint8_t i;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return 0;
+	}
+
+	/*
+	 * Store the connection's parameter and temporarily delete it
+	 * from the concurrency table. This way the get pcl can be used as a
+	 * new connection is coming up, after check, restore the connection to
+	 * concurrency table.
+	 */
+	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
+	policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, sap_vdev_id,
+						      &info, &num_cxn_del);
 
 	if (QDF_STATUS_SUCCESS == policy_mgr_get_pcl(psoc, PM_SAP_MODE,
-		&pcl_channels[0], &pcl_len,
+		pcl_channels, &pcl_len,
 		pcl_weight, QDF_ARRAY_SIZE(pcl_weight))) {
-		channel = pcl_channels[0];
+		for (i = 0; i < pcl_len; i++) {
+			if (pcl_channels[i] == sap_channel)
+				continue;
+			channel = pcl_channels[i];
+			break;
+		}
 	}
+	/* Restore the connection entry */
+	if (num_cxn_del > 0)
+		policy_mgr_restore_deleted_conn_info(psoc, &info, num_cxn_del);
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
 
 	return channel;
 }
+

+ 4 - 5
core/hdd/src/wlan_hdd_hostapd.c

@@ -3045,7 +3045,7 @@ QDF_STATUS wlan_hdd_get_channel_for_sap_restart(
 {
 	mac_handle_t mac_handle;
 	struct hdd_ap_ctx *hdd_ap_ctx;
-	uint8_t intf_ch = 0;
+	uint8_t intf_ch = 0, sap_ch = 0;
 	struct hdd_context *hdd_ctx;
 	struct hdd_station_ctx *hdd_sta_ctx;
 	struct hdd_adapter *sta_adapter;
@@ -3053,6 +3053,7 @@ QDF_STATUS wlan_hdd_get_channel_for_sap_restart(
 	struct ch_params ch_params;
 	struct hdd_adapter *ap_adapter = wlan_hdd_get_adapter_from_vdev(
 					psoc, vdev_id);
+
 	if (!ap_adapter) {
 		hdd_err("ap_adapter is NULL");
 		return QDF_STATUS_E_FAILURE;
@@ -3115,12 +3116,10 @@ QDF_STATUS wlan_hdd_get_channel_for_sap_restart(
 	hdd_info("intf_ch: %d", intf_ch);
 	if (QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION !=
 		mcc_to_scc_switch) {
+		policy_mgr_get_chan_by_session_id(psoc, vdev_id, &sap_ch);
 		if (QDF_IS_STATUS_ERROR(
 			policy_mgr_valid_sap_conc_channel_check(
-				hdd_ctx->psoc,
-				&intf_ch,
-				policy_mgr_mode_specific_get_channel(
-					hdd_ctx->psoc, PM_SAP_MODE)))) {
+				hdd_ctx->psoc, &intf_ch, sap_ch, vdev_id))) {
 			hdd_debug("can't move sap to %d",
 				hdd_sta_ctx->conn_info.channel);
 			return QDF_STATUS_E_FAILURE;

+ 2 - 1
core/sap/src/sap_fsm.c

@@ -854,7 +854,8 @@ sap_validate_chan(struct sap_context *sap_context,
 				if (QDF_IS_STATUS_ERROR(
 					policy_mgr_valid_sap_conc_channel_check(
 						mac_ctx->psoc, &con_ch,
-						sap_context->channel)))	{
+						sap_context->channel,
+						sap_context->sessionId))) {
 					QDF_TRACE(QDF_MODULE_ID_SAP,
 						QDF_TRACE_LEVEL_WARN,
 						FL("SAP can't start (no MCC)"));