Преглед изворни кода

qcacld-3.0: Avoid calling disconnect API while holding sme lock

Add RSO lock and use it to send RSO commands. Also
avoid calling the cm_disconnect API while holding
SME global lock to avoid race.

Change-Id: I588a56f4c96d137d3283b2dc57274de069ecb4ab
CRs-Fixed: 2870603
gaurank kathpalia пре 4 година
родитељ
комит
54195d40bd

+ 4 - 1
components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_api.h

@@ -480,7 +480,10 @@ QDF_STATUS cm_process_disconnect_req(struct scheduler_msg *msg);
  * @reason_code: disconnect reason
  * @bssid: bssid of AP to disconnect, can be null if not known
  *
- * Context: can be called from any context
+ * Context: can be called from any context, should not hold sme global lock
+ * while calling as can lead to deadlock (disconnect access sme lock holding CM
+ * lock and thus calling cm api (which will hold CM lock) while holding sme lock
+ * can lead to deadlock)
  *
  * Return: QDF_STATUS
  */

+ 15 - 16
components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_connect.c

@@ -776,23 +776,22 @@ static QDF_STATUS
 cm_copy_join_params(struct cm_vdev_join_req *join_req,
 		    struct wlan_cm_vdev_connect_req *req)
 {
-	join_req->assoc_ie.ptr = qdf_mem_malloc(req->assoc_ie.len);
-
-	if (!join_req->assoc_ie.ptr)
-		return QDF_STATUS_E_NOMEM;
-
-	qdf_mem_copy(join_req->assoc_ie.ptr, req->assoc_ie.ptr,
-		     req->assoc_ie.len);
-	join_req->assoc_ie.len = req->assoc_ie.len;
-
-	join_req->scan_ie.ptr = qdf_mem_malloc(req->scan_ie.len);
-
-	if (!join_req->scan_ie.ptr)
+	if (req->assoc_ie.len) {
+		join_req->assoc_ie.ptr = qdf_mem_malloc(req->assoc_ie.len);
+		if (!join_req->assoc_ie.ptr)
 		return QDF_STATUS_E_NOMEM;
-	join_req->scan_ie.len = req->scan_ie.len;
-	qdf_mem_copy(join_req->scan_ie.ptr, req->scan_ie.ptr,
-		     req->scan_ie.len);
-
+		qdf_mem_copy(join_req->assoc_ie.ptr, req->assoc_ie.ptr,
+			     req->assoc_ie.len);
+		join_req->assoc_ie.len = req->assoc_ie.len;
+	}
+	if (req->scan_ie.len) {
+		join_req->scan_ie.ptr = qdf_mem_malloc(req->scan_ie.len);
+		if (!join_req->scan_ie.ptr)
+			return QDF_STATUS_E_NOMEM;
+		join_req->scan_ie.len = req->scan_ie.len;
+		qdf_mem_copy(join_req->scan_ie.ptr, req->scan_ie.ptr,
+			     req->scan_ie.len);
+	}
 	join_req->entry = util_scan_copy_cache_entry(req->bss->entry);
 	if (!join_req->entry)
 		return QDF_STATUS_E_NOMEM;

+ 6 - 4
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h

@@ -199,18 +199,20 @@ bool wlan_cm_host_roam_in_progress(struct wlan_objmgr_psoc *psoc,
 				   uint8_t vdev_id);
 
 /**
- * cm_roam_acquire_lock() - Wrapper for sme_acquire_global_lock.
+ * cm_roam_acquire_lock() - Wrapper for rso lock.
+ * @vdev: Pointer to vdev
  *
  * Return: QDF_STATUS
  */
-QDF_STATUS cm_roam_acquire_lock(void);
+QDF_STATUS cm_roam_acquire_lock(struct wlan_objmgr_vdev *vdev);
 
 /**
- * cm_roam_release_lock() - Wrapper for sme_release_global_lock()
+ * cm_roam_release_lock() - Wrapper for rso lock
+ * @vdev: Pointer to vdev
  *
  * Return: QDF_STATUS
  */
-QDF_STATUS cm_roam_release_lock(void);
+QDF_STATUS cm_roam_release_lock(struct wlan_objmgr_vdev *vdev);
 
 /**
  * cm_roam_get_requestor_string() - RSO control requestor to string api

+ 2 - 0
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h

@@ -219,6 +219,7 @@ struct wlan_chan_list {
 /**
  * struct rso_config - connect config to be used to send info in
  * RSO. This is the info we dont have in VDEV or CM ctx
+ * @cm_rso_lock: RSO lock
  * @rsn_cap: original rsn caps from the connect req from supplicant
  * @disable_hi_rssi: disable high rssi
  * @roam_control_enable: Flag used to cache the status of roam control
@@ -254,6 +255,7 @@ struct wlan_chan_list {
  * @roam_scan_freq_lst: roam freq list
  */
 struct rso_config {
+	qdf_mutex_t cm_rso_lock;
 	uint8_t rsn_cap;
 	bool disable_hi_rssi;
 	bool roam_control_enable;

+ 122 - 28
components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c

@@ -136,14 +136,25 @@ wlan_cm_rso_set_roam_trigger(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
 			     struct wlan_roam_triggers *trigger)
 {
 	QDF_STATUS status;
+	struct wlan_objmgr_vdev *vdev;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id,
+						    WLAN_MLME_CM_ID);
+	if (!vdev) {
+		mlme_err("vdev object is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
 
-	status = cm_roam_acquire_lock();
+	status = cm_roam_acquire_lock(vdev);
 	if (QDF_IS_STATUS_ERROR(status))
-		return QDF_STATUS_E_FAILURE;
+		goto release_ref;
 
 	status = cm_rso_set_roam_trigger(pdev, vdev_id, trigger);
 
-	cm_roam_release_lock();
+	cm_roam_release_lock(vdev);
+
+release_ref:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
 
 	return status;
 }
@@ -154,10 +165,18 @@ QDF_STATUS wlan_cm_disable_rso(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
 {
 	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
 	QDF_STATUS status;
+	struct wlan_objmgr_vdev *vdev;
 
-	status = cm_roam_acquire_lock();
+	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id,
+						    WLAN_MLME_CM_ID);
+	if (!vdev) {
+		mlme_err("vdev object is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = cm_roam_acquire_lock(vdev);
 	if (QDF_IS_STATUS_ERROR(status))
-		return QDF_STATUS_E_FAILURE;
+		goto release_ref;
 
 	if (reason == REASON_DRIVER_DISABLED && requestor)
 		mlme_set_operations_bitmap(psoc, vdev_id, requestor, false);
@@ -167,7 +186,10 @@ QDF_STATUS wlan_cm_disable_rso(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
 
 	status = cm_roam_state_change(pdev, vdev_id, WLAN_ROAM_RSO_STOPPED,
 				      REASON_DRIVER_DISABLED);
-	cm_roam_release_lock();
+	cm_roam_release_lock(vdev);
+
+release_ref:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
 
 	return status;
 }
@@ -178,20 +200,31 @@ QDF_STATUS wlan_cm_enable_rso(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
 {
 	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
 	QDF_STATUS status;
+	struct wlan_objmgr_vdev *vdev;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id,
+						    WLAN_MLME_CM_ID);
+	if (!vdev) {
+		mlme_err("vdev object is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
 
 	if (reason == REASON_DRIVER_ENABLED && requestor)
 		mlme_set_operations_bitmap(psoc, vdev_id, requestor, true);
 
-	status = cm_roam_acquire_lock();
+	status = cm_roam_acquire_lock(vdev);
 	if (QDF_IS_STATUS_ERROR(status))
-		return QDF_STATUS_E_FAILURE;
+		goto release_ref;
 
 	mlme_debug("ROAM_CONFIG: vdev[%d] Enable roaming - requestor:%s",
 		   vdev_id, cm_roam_get_requestor_string(requestor));
 
 	status = cm_roam_state_change(pdev, vdev_id, WLAN_ROAM_RSO_ENABLED,
 				      REASON_DRIVER_ENABLED);
-	cm_roam_release_lock();
+	cm_roam_release_lock(vdev);
+
+release_ref:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
 
 	return status;
 }
@@ -224,15 +257,24 @@ QDF_STATUS wlan_cm_abort_rso(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id)
 {
 	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
 	QDF_STATUS status;
+	struct wlan_objmgr_vdev *vdev;
 
-	status = cm_roam_acquire_lock();
-	if (QDF_IS_STATUS_ERROR(status))
+	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id,
+						    WLAN_MLME_CM_ID);
+	if (!vdev) {
+		mlme_err("vdev object is NULL");
 		return QDF_STATUS_E_FAILURE;
+	}
+
+	status = cm_roam_acquire_lock(vdev);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto release_ref;
 
 	if (MLME_IS_ROAM_SYNCH_IN_PROGRESS(psoc, vdev_id) ||
 	    wlan_cm_host_roam_in_progress(psoc, vdev_id)) {
-		cm_roam_release_lock();
-		return QDF_STATUS_E_BUSY;
+		cm_roam_release_lock(vdev);
+		status = QDF_STATUS_E_FAILURE;
+		goto release_ref;
 	}
 
 	/* RSO stop cmd will be issued with lock held to avoid
@@ -241,7 +283,10 @@ QDF_STATUS wlan_cm_abort_rso(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id)
 	wlan_cm_disable_rso(pdev, vdev_id, REASON_DRIVER_DISABLED,
 			    RSO_INVALID_REQUESTOR);
 
-	cm_roam_release_lock();
+	cm_roam_release_lock(vdev);
+release_ref:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
+
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -249,22 +294,32 @@ bool wlan_cm_roaming_in_progress(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id)
 {
 	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
 	QDF_STATUS status;
+	bool roaming_in_progress = false;
+	struct wlan_objmgr_vdev *vdev;
 
-	status = cm_roam_acquire_lock();
+	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id,
+						    WLAN_MLME_CM_ID);
+	if (!vdev) {
+		mlme_err("vdev object is NULL");
+		return roaming_in_progress;
+	}
+
+	status = cm_roam_acquire_lock(vdev);
 	if (QDF_IS_STATUS_ERROR(status))
-		return false;
+		goto release_ref;
 
 	if (MLME_IS_ROAM_SYNCH_IN_PROGRESS(psoc, vdev_id) ||
 	    MLME_IS_ROAMING_IN_PROG(psoc, vdev_id) ||
 	    mlme_is_roam_invoke_in_progress(psoc, vdev_id) ||
-	    wlan_cm_host_roam_in_progress(psoc, vdev_id)) {
-		cm_roam_release_lock();
-		return true;
-	}
+	    wlan_cm_host_roam_in_progress(psoc, vdev_id))
+		roaming_in_progress = true;
 
-	cm_roam_release_lock();
+	cm_roam_release_lock(vdev);
 
-	return false;
+release_ref:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
+
+	return roaming_in_progress;
 }
 
 QDF_STATUS wlan_cm_roam_stop_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
@@ -752,19 +807,31 @@ cm_roam_update_cfg(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
 		   uint8_t reason)
 {
 	QDF_STATUS status;
+	struct wlan_objmgr_vdev *vdev;
 
-	status = cm_roam_acquire_lock();
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_MLME_CM_ID);
+	if (!vdev) {
+		mlme_err("vdev object is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = cm_roam_acquire_lock(vdev);
 	if (QDF_IS_STATUS_ERROR(status))
-		return status;
+		goto release_ref;
 	if (!MLME_IS_ROAM_STATE_RSO_ENABLED(psoc, vdev_id)) {
 		mlme_debug("Update cfg received while ROAM RSO not started");
-		cm_roam_release_lock();
-		return QDF_STATUS_E_INVAL;
+		cm_roam_release_lock(vdev);
+		status = QDF_STATUS_E_INVAL;
+		goto release_ref;
 	}
 
 	status = cm_roam_send_rso_cmd(psoc, vdev_id,
 				      ROAM_SCAN_OFFLOAD_UPDATE_CFG, reason);
-	cm_roam_release_lock();
+	cm_roam_release_lock(vdev);
+
+release_ref:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
 
 	return status;
 }
@@ -1175,7 +1242,9 @@ QDF_STATUS wlan_cm_rso_config_init(struct wlan_objmgr_vdev *vdev,
 		mlme_obj->cfg.lfr.roam_rssi_diff;
 	cfg_params->bg_rssi_threshold =
 		mlme_obj->cfg.lfr.bg_rssi_threshold;
-
+#ifdef FEATURE_CM_ENABLE
+	qdf_mutex_create(&rso_cfg->cm_rso_lock);
+#endif
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -1184,6 +1253,9 @@ void wlan_cm_rso_config_deinit(struct wlan_objmgr_vdev *vdev,
 {
 	struct rso_cfg_params *cfg_params;
 
+#ifdef FEATURE_CM_ENABLE
+	qdf_mutex_destroy(&rso_cfg->cm_rso_lock);
+#endif
 	cfg_params = &rso_cfg->cfg_param;
 	if (rso_cfg->assoc_ie.ptr) {
 		qdf_mem_free(rso_cfg->assoc_ie.ptr);
@@ -1212,6 +1284,28 @@ struct rso_config *wlan_cm_get_rso_config_fl(struct wlan_objmgr_vdev *vdev,
 
 	return &cm_ext_obj->rso_cfg;
 }
+
+QDF_STATUS cm_roam_acquire_lock(struct wlan_objmgr_vdev *vdev)
+{
+	static struct rso_config *rso_cfg;
+
+	rso_cfg = wlan_cm_get_rso_config(vdev);
+	if (!rso_cfg)
+		return QDF_STATUS_E_INVAL;
+
+	return qdf_mutex_acquire(&rso_cfg->cm_rso_lock);
+}
+
+QDF_STATUS cm_roam_release_lock(struct wlan_objmgr_vdev *vdev)
+{
+	static struct rso_config *rso_cfg;
+
+	rso_cfg = wlan_cm_get_rso_config(vdev);
+	if (!rso_cfg)
+		return QDF_STATUS_E_INVAL;
+
+	return qdf_mutex_release(&rso_cfg->cm_rso_lock);
+}
 #else
 struct rso_config *wlan_cm_get_rso_config_fl(struct wlan_objmgr_vdev *vdev,
 					     const char *func, uint32_t line)

+ 13 - 3
components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_ucfg_api.c

@@ -96,20 +96,30 @@ QDF_STATUS ucfg_cm_abort_roam_scan(struct wlan_objmgr_pdev *pdev,
 	QDF_STATUS status;
 	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
 	bool roam_scan_offload_enabled;
+	struct wlan_objmgr_vdev *vdev;
 
 	ucfg_mlme_is_roam_scan_offload_enabled(psoc,
 					       &roam_scan_offload_enabled);
 	if (!roam_scan_offload_enabled)
 		return QDF_STATUS_SUCCESS;
 
-	status = cm_roam_acquire_lock();
+	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id,
+						    WLAN_MLME_CM_ID);
+	if (!vdev) {
+		mlme_err("vdev object is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+	status = cm_roam_acquire_lock(vdev);
 	if (QDF_IS_STATUS_ERROR(status))
-		return status;
+		goto release_ref;
 
 	status = cm_roam_send_rso_cmd(psoc, vdev_id,
 				      ROAM_SCAN_OFFLOAD_ABORT_SCAN,
 				      REASON_ROAM_ABORT_ROAM_SCAN);
-	cm_roam_release_lock();
+	cm_roam_release_lock(vdev);
+
+release_ref:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
 
 	return status;
 }

+ 2 - 2
core/hdd/src/wlan_hdd_main.c

@@ -5747,9 +5747,9 @@ QDF_STATUS hdd_init_station_mode(struct hdd_adapter *adapter)
 	hdd_roam_profile_init(adapter);
 	hdd_register_wext(adapter->dev);
 
+#ifndef FEATURE_CM_ENABLE
 	hdd_conn_set_connection_state(adapter, eConnectionState_NotConnected);
-	sme_roam_reset_configs(mac_handle, adapter->vdev_id);
-
+#endif
 	/* set fast roaming capability in sme session */
 	status = ucfg_user_space_enable_disable_rso(hdd_ctx->pdev,
 						    adapter->vdev_id,

+ 0 - 51
core/mac/inc/sir_api.h

@@ -1074,29 +1074,6 @@ struct assoc_cnf {
 	bool need_assoc_rsp_tx_cb;
 };
 
-/* / Enum definition for  Wireless medium status change codes */
-typedef enum eSirSmeStatusChangeCode {
-	eSIR_SME_DEAUTH_FROM_PEER,
-	eSIR_SME_DISASSOC_FROM_PEER,
-	eSIR_SME_LOST_LINK_WITH_PEER,
-	eSIR_SME_CHANNEL_SWITCH,
-	eSIR_SME_RADAR_DETECTED,
-	eSIR_SME_AP_CAPS_CHANGED,
-} tSirSmeStatusChangeCode;
-
-struct new_bss_info {
-	struct qdf_mac_addr bssId;
-	uint32_t freq;
-	uint8_t reserved;
-	tSirMacSSid ssId;
-};
-
-struct ap_new_caps {
-	uint16_t capabilityInfo;
-	struct qdf_mac_addr bssId;
-	tSirMacSSid ssId;
-};
-
 /**
  * Table below indicates what information is passed for each of
  * the Wireless Media status change notifications:
@@ -1113,27 +1090,6 @@ struct ap_new_caps {
  *                                  have changed.
  */
 
-/* / Definition for Wireless medium status change notification */
-struct wm_status_change_ntf {
-	uint16_t messageType;   /* eWNI_SME_WM_STATUS_CHANGE_NTF */
-	uint16_t length;
-	uint8_t sessionId;      /* Session ID */
-	tSirSmeStatusChangeCode statusChangeCode;
-	struct qdf_mac_addr bssid;      /* Self BSSID */
-	union {
-		/* eSIR_SME_DEAUTH_FROM_PEER */
-		uint16_t deAuthReasonCode;
-		/* eSIR_SME_DISASSOC_FROM_PEER */
-		uint16_t disassocReasonCode;
-		/* none for eSIR_SME_LOST_LINK_WITH_PEER */
-		/* eSIR_SME_CHANNEL_SWITCH */
-		uint32_t new_freq;
-		/* none for eSIR_SME_RADAR_DETECTED */
-		/* eSIR_SME_AP_CAPS_CHANGED */
-		struct ap_new_caps apNewCaps;
-	} statusChangeInfo;
-};
-
 /* Definition for Disassociation request */
 struct disassoc_req {
 	uint16_t messageType;   /* eWNI_SME_DISASSOC_REQ */
@@ -2124,13 +2080,6 @@ struct sir_antenna_mode_resp {
 	enum set_antenna_mode_status status;
 };
 
-/* Reset AP Caps Changed */
-typedef struct sSirResetAPCapsChange {
-	uint16_t messageType;
-	uint16_t length;
-	struct qdf_mac_addr bssId;
-} tSirResetAPCapsChange, *tpSirResetAPCapsChange;
-
 /* / Definition for Candidate found indication from FW */
 typedef struct sSirSmeCandidateFoundInd {
 	uint16_t messageType;   /* eWNI_SME_CANDIDATE_FOUND_IND */

+ 0 - 7
core/mac/inc/wni_api.h

@@ -52,7 +52,6 @@ enum eWniMsgTypes {
 	eWNI_SME_DEAUTH_RSP = SIR_SME_MSG_TYPES_BEGIN + 13,
 	eWNI_SME_DEAUTH_IND = SIR_SME_MSG_TYPES_BEGIN + 14,
 	eWNI_SME_DISCONNECT_DONE_IND = SIR_SME_MSG_TYPES_BEGIN + 15,
-	eWNI_SME_WM_STATUS_CHANGE_NTF = SIR_SME_MSG_TYPES_BEGIN + 16,
 	eWNI_SME_START_BSS_REQ = SIR_SME_MSG_TYPES_BEGIN + 19,
 	eWNI_SME_START_BSS_RSP = SIR_SME_MSG_TYPES_BEGIN + 20,
 	eWNI_SME_ASSOC_IND = SIR_SME_MSG_TYPES_BEGIN + 21,
@@ -117,12 +116,6 @@ enum eWniMsgTypes {
 	eWNI_SME_TDLS_SHOULD_TEARDOWN = SIR_SME_MSG_TYPES_BEGIN + 70,
 	eWNI_SME_TDLS_PEER_DISCONNECTED = SIR_SME_MSG_TYPES_BEGIN + 71,
 #endif
-	/* NOTE: If you are planning to add more mesages, please make sure that */
-	/* SIR_LIM_ITC_MSG_TYPES_BEGIN is moved appropriately. It is set as */
-	/* SIR_LIM_MSG_TYPES_BEGIN+0xB0 = 12B0 (which means max of 176 messages and */
-	/* eWNI_SME_TDLS_DEL_STA_RSP = 175. */
-	/* Should fix above issue to enable TDLS_INTERNAL */
-	eWNI_SME_RESET_AP_CAPS_CHANGED = SIR_SME_MSG_TYPES_BEGIN + 73,
 #ifdef WLAN_FEATURE_11W
 	eWNI_SME_UNPROT_MGMT_FRM_IND = SIR_SME_MSG_TYPES_BEGIN + 74,
 #endif

+ 16 - 19
core/mac/src/pe/lim/lim_api.c

@@ -1517,13 +1517,12 @@ lim_detect_change_in_ap_capabilities(struct mac_context *mac,
 				     struct pe_session *pe_session)
 {
 	uint8_t len;
-	struct ap_new_caps apNewCaps;
 	uint32_t new_chan_freq;
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	bool security_caps_matched = true;
+	uint16_t ap_cap;
 
-	apNewCaps.capabilityInfo =
-		lim_get_u16((uint8_t *) &pBeacon->capabilityInfo);
+	ap_cap = lim_get_u16((uint8_t *) &pBeacon->capabilityInfo);
 	new_chan_freq = pBeacon->chan_freq;
 
 	security_caps_matched = lim_enc_type_matched(mac, pBeacon,
@@ -1531,11 +1530,11 @@ lim_detect_change_in_ap_capabilities(struct mac_context *mac,
 	if ((false == pe_session->limSentCapsChangeNtf) &&
 	    (((!lim_is_null_ssid(&pBeacon->ssId)) &&
 	       lim_cmp_ssid(&pBeacon->ssId, pe_session)) ||
-	     ((SIR_MAC_GET_ESS(apNewCaps.capabilityInfo) !=
+	     ((SIR_MAC_GET_ESS(ap_cap) !=
 	       SIR_MAC_GET_ESS(pe_session->limCurrentBssCaps)) ||
-	      (SIR_MAC_GET_PRIVACY(apNewCaps.capabilityInfo) !=
+	      (SIR_MAC_GET_PRIVACY(ap_cap) !=
 	       SIR_MAC_GET_PRIVACY(pe_session->limCurrentBssCaps)) ||
-	      (SIR_MAC_GET_QOS(apNewCaps.capabilityInfo) !=
+	      (SIR_MAC_GET_QOS(ap_cap) !=
 	       SIR_MAC_GET_QOS(pe_session->limCurrentBssCaps)) ||
 	      ((new_chan_freq != pe_session->curr_op_freq) &&
 		(new_chan_freq != 0)) ||
@@ -1573,8 +1572,6 @@ lim_detect_change_in_ap_capabilities(struct mac_context *mac,
 		len = sizeof(tSirMacCapabilityInfo) + sizeof(tSirMacAddr) + sizeof(uint8_t) + 3 * sizeof(uint8_t) + /* reserved fields */
 		      pBeacon->ssId.length + 1;
 
-		qdf_mem_copy(apNewCaps.bssId.bytes,
-			     pe_session->bssId, QDF_MAC_ADDR_SIZE);
 		if (new_chan_freq != pe_session->curr_op_freq) {
 			pe_err("Channel freq Change from %d --> %d Ignoring beacon!",
 			       pe_session->curr_op_freq, new_chan_freq);
@@ -1591,21 +1588,22 @@ lim_detect_change_in_ap_capabilities(struct mac_context *mac,
 		 * disconnect from the AP. The following check makes sure that we can
 		 * connect to such APs
 		 */
-		else if ((SIR_MAC_GET_PRIVACY(apNewCaps.capabilityInfo) == 0) &&
+		else if ((SIR_MAC_GET_PRIVACY(ap_cap) == 0) &&
 			 (pBeacon->rsnPresent || pBeacon->wpaPresent)) {
 			pe_err("BSS Caps (Privacy) bit 0 in beacon, but WPA or RSN IE present, Ignore Beacon!");
 			return;
 		}
-		qdf_mem_copy((uint8_t *) &apNewCaps.ssId,
-			     (uint8_t *) &pBeacon->ssId,
-			     pBeacon->ssId.length + 1);
 
 		pe_session->fIgnoreCapsChange = false;
 		pe_session->fWaitForProbeRsp = false;
 		pe_session->limSentCapsChangeNtf = true;
-		lim_send_sme_wm_status_change_ntf(mac, eSIR_SME_AP_CAPS_CHANGED,
-						  (uint32_t *) &apNewCaps,
-						  len, pe_session->smeSessionId);
+		pe_err("Disconnect as cap mismatch!");
+		lim_send_deauth_mgmt_frame(mac, REASON_UNSPEC_FAILURE,
+					   pe_session->bssId, pe_session,
+					   false);
+		lim_tear_down_link_with_ap(mac, pe_session->peSessionId,
+					   REASON_UNSPEC_FAILURE,
+					   eLIM_HOST_DISASSOC);
 	} else if (true == pe_session->fWaitForProbeRsp) {
 		/* Only for probe response frames and matching capabilities the control
 		 * will come here. If beacon is with broadcast ssid then fWaitForProbeRsp
@@ -1644,7 +1642,7 @@ QDF_STATUS lim_update_short_slot(struct mac_context *mac,
 				    struct pe_session *pe_session)
 {
 
-	struct ap_new_caps apNewCaps;
+	uint16_t ap_cap;
 	uint32_t nShortSlot;
 	uint32_t phyMode;
 
@@ -1658,8 +1656,7 @@ QDF_STATUS lim_update_short_slot(struct mac_context *mac,
 	    || (phyMode == WNI_CFG_PHY_MODE_11B))
 		return QDF_STATUS_SUCCESS;
 
-	apNewCaps.capabilityInfo =
-		lim_get_u16((uint8_t *) &pBeacon->capabilityInfo);
+	ap_cap = lim_get_u16((uint8_t *) &pBeacon->capabilityInfo);
 
 	/*  Earlier implementation: determine the appropriate short slot mode based on AP advertised modes */
 	/* when erp is present, apply short slot always unless, prot=on  && shortSlot=off */
@@ -1680,7 +1677,7 @@ QDF_STATUS lim_update_short_slot(struct mac_context *mac,
 	   Case7        0                                   0                       1                       1
 	   Case8        0                                   0                       0                       0
 	 */
-	nShortSlot = SIR_MAC_GET_SHORT_SLOT_TIME(apNewCaps.capabilityInfo);
+	nShortSlot = SIR_MAC_GET_SHORT_SLOT_TIME(ap_cap);
 
 	if (nShortSlot != pe_session->shortSlotTimeSupported) {
 		/* Short slot time capability of AP has changed. Adopt to it. */

+ 0 - 1
core/mac/src/pe/lim/lim_process_message_queue.c

@@ -1715,7 +1715,6 @@ static void lim_process_messages(struct mac_context *mac_ctx,
 	case eWNI_SME_TDLS_DEL_STA_REQ:
 	case eWNI_SME_TDLS_LINK_ESTABLISH_REQ:
 #endif
-	case eWNI_SME_RESET_AP_CAPS_CHANGED:
 	case eWNI_SME_SET_HW_MODE_REQ:
 	case eWNI_SME_SET_DUAL_MAC_CFG_REQ:
 	case eWNI_SME_SET_ANTENNA_MODE_REQ:

+ 0 - 29
core/mac/src/pe/lim/lim_process_sme_req_messages.c

@@ -6299,31 +6299,6 @@ skip_match:
 	return;
 }
 
-static void __lim_process_sme_reset_ap_caps_change(struct mac_context *mac,
-						   uint32_t *msg_buf)
-{
-	tpSirResetAPCapsChange pResetCapsChange;
-	struct pe_session *pe_session;
-	uint8_t sessionId = 0;
-
-	if (!msg_buf) {
-		pe_err("Buffer is Pointing to NULL");
-		return;
-	}
-
-	pResetCapsChange = (tpSirResetAPCapsChange)msg_buf;
-	pe_session =
-		pe_find_session_by_bssid(mac, pResetCapsChange->bssId.bytes,
-					 &sessionId);
-	if (!pe_session) {
-		pe_err("Session does not exist for given BSSID");
-		return;
-	}
-
-	pe_session->limSentCapsChangeNtf = false;
-	return;
-}
-
 /**
  * lim_register_mgmt_frame_ind_cb() - Save the Management frame
  * indication callback in PE.
@@ -6976,10 +6951,6 @@ bool lim_process_sme_req_messages(struct mac_context *mac,
 		lim_process_sme_tdls_del_sta_req(mac, msg_buf);
 		break;
 #endif
-	case eWNI_SME_RESET_AP_CAPS_CHANGED:
-		__lim_process_sme_reset_ap_caps_change(mac, msg_buf);
-		break;
-
 	case eWNI_SME_CHANNEL_CHANGE_REQ:
 		lim_process_sme_channel_change_request(mac, msg_buf);
 		break;

+ 0 - 65
core/mac/src/pe/lim/lim_send_sme_rsp_messages.c

@@ -1664,71 +1664,6 @@ void lim_send_sme_deauth_ntf(struct mac_context *mac, tSirMacAddr peerMacAddr,
 
 } /*** end lim_send_sme_deauth_ntf() ***/
 
-/**
- * lim_send_sme_wm_status_change_ntf() - Send Notification
- * @mac_ctx:             Global MAC Context
- * @status_change_code:  Indicates the change in the wireless medium.
- * @status_change_info:  Indicates the information associated with
- *                       change in the wireless medium.
- * @info_len:            Indicates the length of status change information
- *                       being sent.
- * @session_id           SessionID
- *
- * This function is called by limProcessSmeMessages() to send
- * eWNI_SME_WM_STATUS_CHANGE_NTF message to host.
- *
- * Return: None
- */
-void
-lim_send_sme_wm_status_change_ntf(struct mac_context *mac_ctx,
-	tSirSmeStatusChangeCode status_change_code,
-	uint32_t *status_change_info, uint16_t info_len, uint8_t session_id)
-{
-	struct scheduler_msg msg = {0};
-	struct wm_status_change_ntf *wm_status_change_ntf;
-	uint32_t max_info_len;
-
-	wm_status_change_ntf = qdf_mem_malloc(sizeof(*wm_status_change_ntf));
-	if (!wm_status_change_ntf)
-		return;
-
-	msg.type = eWNI_SME_WM_STATUS_CHANGE_NTF;
-	msg.bodyval = 0;
-	msg.bodyptr = wm_status_change_ntf;
-
-	switch (status_change_code) {
-	case eSIR_SME_AP_CAPS_CHANGED:
-		max_info_len = sizeof(struct ap_new_caps);
-		break;
-	default:
-		max_info_len = sizeof(wm_status_change_ntf->statusChangeInfo);
-		break;
-	}
-
-	switch (status_change_code) {
-	case eSIR_SME_RADAR_DETECTED:
-		break;
-	default:
-		wm_status_change_ntf->messageType =
-			eWNI_SME_WM_STATUS_CHANGE_NTF;
-		wm_status_change_ntf->statusChangeCode = status_change_code;
-		wm_status_change_ntf->length = sizeof(*wm_status_change_ntf);
-		wm_status_change_ntf->sessionId = session_id;
-		if (info_len <= max_info_len && status_change_info) {
-			qdf_mem_copy(
-			    (uint8_t *) &wm_status_change_ntf->statusChangeInfo,
-			    (uint8_t *) status_change_info, info_len);
-		}
-		pe_debug("StatusChg code: 0x%x length: %d",
-			status_change_code, info_len);
-		break;
-	}
-
-	MTRACE(mac_trace(mac_ctx, TRACE_CODE_TX_SME_MSG, session_id, msg.type));
-	lim_sys_process_mmh_msg_api(mac_ctx, &msg);
-
-} /*** end lim_send_sme_wm_status_change_ntf() ***/
-
 void lim_send_sme_set_context_rsp(struct mac_context *mac,
 				  struct qdf_mac_addr peer_macaddr,
 				  uint16_t aid,

+ 1 - 4
core/mac/src/pe/lim/lim_send_sme_rsp_messages.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2021 The Linux Foundation. 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
@@ -176,9 +176,6 @@ void lim_send_sme_deauth_ntf(struct mac_context *mac, tSirMacAddr peerMacAddr,
 void lim_send_sme_disassoc_ind(struct mac_context *, tpDphHashNode, struct pe_session *);
 void lim_send_sme_deauth_ind(struct mac_context *, tpDphHashNode,
 			     struct pe_session *pe_session);
-void lim_send_sme_wm_status_change_ntf(struct mac_context *, tSirSmeStatusChangeCode,
-				       uint32_t *, uint16_t, uint8_t);
-
 /**
  * lim_send_sme_set_context_rsp() - Send set context response to upper layer
  * @mac: Pointer to Global MAC structure

+ 8 - 4
core/mac/src/pe/lim/lim_utils.c

@@ -234,8 +234,6 @@ char *lim_msg_str(uint32_t msgType)
 		return "eWNI_SME_DEAUTH_RSP";
 	case eWNI_SME_DEAUTH_IND:
 		return "eWNI_SME_DEAUTH_IND";
-	case eWNI_SME_WM_STATUS_CHANGE_NTF:
-		return "eWNI_SME_WM_STATUS_CHANGE_NTF";
 	case eWNI_SME_START_BSS_REQ:
 		return "eWNI_SME_START_BSS_REQ";
 	case eWNI_SME_START_BSS_RSP:
@@ -2002,6 +2000,13 @@ void lim_switch_channel_cback(struct mac_context *mac, QDF_STATUS status,
 	struct wlan_channel *des_chan;
 	struct vdev_mlme_obj *mlme_obj;
 
+	if (QDF_IS_STATUS_ERROR(status)) {
+		lim_tear_down_link_with_ap(mac, pe_session->peSessionId,
+					   REASON_CHANNEL_SWITCH_FAILED,
+					   eLIM_HOST_DISASSOC);
+		return;
+	}
+
 	mlme_obj = wlan_vdev_mlme_get_cmpt_obj(pe_session->vdev);
 	if (!mlme_obj) {
 		pe_err("vdev component object is NULL");
@@ -2056,8 +2061,7 @@ void lim_switch_channel_cback(struct mac_context *mac, QDF_STATUS status,
 
 	sys_process_mmh_msg(mac, &mmhMsg);
 
-	if (QDF_IS_STATUS_SUCCESS(status))
-		lim_switch_channel_vdev_started(pe_session);
+	lim_switch_channel_vdev_started(pe_session);
 }
 
 void lim_switch_primary_channel(struct mac_context *mac,

+ 1 - 3
core/mac/src/sys/legacy/src/utils/src/mac_trace.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2021 The Linux Foundation. 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
@@ -228,7 +228,6 @@ uint8_t *mac_trace_get_sme_msg_string(uint16_t sme_msg)
 		CASE_RETURN_STRING(eWNI_SME_DEAUTH_RSP);
 		CASE_RETURN_STRING(eWNI_SME_DEAUTH_IND);
 		CASE_RETURN_STRING(eWNI_SME_DISCONNECT_DONE_IND);
-		CASE_RETURN_STRING(eWNI_SME_WM_STATUS_CHANGE_NTF);
 		CASE_RETURN_STRING(eWNI_SME_START_BSS_REQ);
 		CASE_RETURN_STRING(eWNI_SME_START_BSS_RSP);
 		CASE_RETURN_STRING(eWNI_SME_ASSOC_IND);
@@ -302,7 +301,6 @@ uint8_t *mac_trace_get_sme_msg_string(uint16_t sme_msg)
 		CASE_RETURN_STRING(eWNI_SME_TDLS_SHOULD_TEARDOWN);
 		CASE_RETURN_STRING(eWNI_SME_TDLS_PEER_DISCONNECTED);
 #endif
-		CASE_RETURN_STRING(eWNI_SME_RESET_AP_CAPS_CHANGED);
 #ifdef WLAN_FEATURE_11W
 		CASE_RETURN_STRING(eWNI_SME_UNPROT_MGMT_FRM_IND);
 #endif

+ 8 - 0
core/sme/inc/csr_neighbor_roam.h

@@ -96,9 +96,17 @@ typedef struct sCsrNeighborRoamControlInfo {
 QDF_STATUS csr_neighbor_roam_indicate_connect(struct mac_context *mac,
 		uint8_t sessionId, QDF_STATUS status);
 #if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
+QDF_STATUS csr_roam_control_restore_default_config(struct mac_context *mac,
+						   uint8_t vdev_id);
 void csr_roam_restore_default_config(struct mac_context *mac_ctx,
 				     uint8_t vdev_id);
 #else
+static inline
+QDF_STATUS csr_roam_control_restore_default_config(struct mac_context *mac,
+						   uint8_t vdev_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
 static inline void csr_roam_restore_default_config(struct mac_context *mac_ctx,
 						   uint8_t vdev_id)
 {

+ 0 - 9
core/sme/inc/sme_api.h

@@ -1107,15 +1107,6 @@ sme_modify_roam_cand_sel_criteria(mac_handle_t mac_handle,
 QDF_STATUS sme_roam_control_restore_default_config(mac_handle_t mac_handle,
 						   uint8_t vdev_id);
 
-/**
- * sme_roam_reset_configs() - API to reset roam config
- * @mac_handle: Opaque handle to the global MAC context
- * @vdev_id: vdev Identifier
- *
- * Return: void
- */
-void sme_roam_reset_configs(mac_handle_t mac_handle, uint8_t vdev_id);
-
 QDF_STATUS sme_set_neighbor_scan_min_chan_time(mac_handle_t mac_handle,
 		const uint16_t nNeighborScanMinChanTime,
 		uint8_t sessionId);

+ 13 - 118
core/sme/src/common/sme_api.c

@@ -111,7 +111,8 @@ QDF_STATUS sme_release_global_lock(struct sme_context *sme)
 	return qdf_mutex_release(&sme->sme_global_lock);
 }
 
-QDF_STATUS cm_roam_acquire_lock(void)
+#ifndef FEATURE_CM_ENABLE
+QDF_STATUS cm_roam_acquire_lock(struct wlan_objmgr_vdev *vdev)
 {
 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_SME);
 
@@ -121,7 +122,7 @@ QDF_STATUS cm_roam_acquire_lock(void)
 	return sme_acquire_global_lock(&mac->sme);
 }
 
-QDF_STATUS cm_roam_release_lock(void)
+QDF_STATUS cm_roam_release_lock(struct wlan_objmgr_vdev *vdev)
 {
 	struct mac_context *mac = cds_get_context(QDF_MODULE_ID_SME);
 
@@ -130,6 +131,7 @@ QDF_STATUS cm_roam_release_lock(void)
 
 	return sme_release_global_lock(&mac->sme);
 }
+#endif
 
 struct mac_context *sme_get_mac_context(void)
 {
@@ -5521,9 +5523,16 @@ QDF_STATUS sme_update_channel_list(mac_handle_t mac_handle)
 
 		csr_apply_channel_power_info_wrapper(mac_ctx);
 		csr_scan_filter_results(mac_ctx);
+#ifdef FEATURE_CM_ENABLE
+		sme_release_global_lock(&mac_ctx->sme);
+		/* release the sme lock before we call cm disconnect */
+		sme_disconnect_connected_sessions(mac_ctx,
+					REASON_OPER_CHANNEL_USER_DISABLED);
+#else
 		sme_disconnect_connected_sessions(mac_ctx,
 					REASON_OPER_CHANNEL_USER_DISABLED);
 		sme_release_global_lock(&mac_ctx->sme);
+#endif
 	}
 
 	return status;
@@ -5588,6 +5597,7 @@ static void sme_disconnect_connected_sessions(struct mac_context *mac_ctx,
 			sme_debug("Disconnect Session: %d", vdev_id);
 			/* This is temp ifdef will be removed in near future */
 #ifdef FEATURE_CM_ENABLE
+			/* do not call cm disconnect while holding Sme lock */
 			cm_disconnect(mac_ctx->psoc, vdev_id,
 				      CM_MLME_DISCONNECT, reason, NULL);
 #else
@@ -6835,132 +6845,17 @@ sme_modify_roam_cand_sel_criteria(mac_handle_t mac_handle,
 					  ENABLE_SCORING_FOR_ROAM, &src_config);
 }
 
-/**
- * sme_restore_default_roaming_params() - Restore neighbor roam config
- * @mac: mac context
- * @vdev_id: Vdev id
- *
- * Return: None
- */
-static void
-sme_restore_default_roaming_params(struct mac_context *mac, uint8_t vdev_id)
-{
-	struct wlan_objmgr_vdev *vdev;
-	struct rso_config *rso_cfg;
-	struct rso_cfg_params *cfg_params;
-	struct wlan_mlme_psoc_ext_obj *mlme_obj;
-
-	mlme_obj = mlme_get_psoc_ext_obj(mac->psoc);
-	if (!mlme_obj)
-		return;
-
-	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac->pdev, vdev_id,
-						    WLAN_LEGACY_SME_ID);
-	if (!vdev) {
-		sme_err("vdev object is NULL for vdev %d", vdev_id);
-		return;
-	}
-	rso_cfg = wlan_cm_get_rso_config(vdev);
-	if (!rso_cfg) {
-		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
-		return;
-	}
-	cfg_params = &rso_cfg->cfg_param;
-	cfg_params->enable_scoring_for_roam =
-			mlme_obj->cfg.roam_scoring.enable_scoring_for_roam;
-	cfg_params->empty_scan_refresh_period =
-			mlme_obj->cfg.lfr.empty_scan_refresh_period;
-	cfg_params->full_roam_scan_period =
-			mlme_obj->cfg.lfr.roam_full_scan_period;
-	cfg_params->neighbor_scan_period =
-			mlme_obj->cfg.lfr.neighbor_scan_timer_period;
-	cfg_params->neighbor_lookup_threshold =
-			mlme_obj->cfg.lfr.neighbor_lookup_rssi_threshold;
-	cfg_params->roam_rssi_diff =
-			mlme_obj->cfg.lfr.roam_rssi_diff;
-	cfg_params->bg_rssi_threshold =
-			mlme_obj->cfg.lfr.bg_rssi_threshold;
-
-	cfg_params->max_chan_scan_time =
-			mlme_obj->cfg.lfr.neighbor_scan_max_chan_time;
-	cfg_params->roam_scan_home_away_time =
-			mlme_obj->cfg.lfr.roam_scan_home_away_time;
-	cfg_params->roam_scan_n_probes =
-			mlme_obj->cfg.lfr.roam_scan_n_probes;
-	cfg_params->roam_scan_inactivity_time =
-			mlme_obj->cfg.lfr.roam_scan_inactivity_time;
-	cfg_params->roam_inactive_data_packet_count =
-			mlme_obj->cfg.lfr.roam_inactive_data_packet_count;
-	cfg_params->roam_scan_period_after_inactivity =
-			mlme_obj->cfg.lfr.roam_scan_period_after_inactivity;
-	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
-}
-
-void sme_roam_reset_configs(mac_handle_t mac_handle, uint8_t vdev_id)
-{
-	struct mac_context *mac = MAC_CONTEXT(mac_handle);
-
-	sme_restore_default_roaming_params(mac, vdev_id);
-}
-
 QDF_STATUS sme_roam_control_restore_default_config(mac_handle_t mac_handle,
 						   uint8_t vdev_id)
 {
 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
-	QDF_STATUS status;
-	struct rso_chan_info *chan_info;
-	struct wlan_objmgr_vdev *vdev;
-	struct rso_config *rso_cfg;
-	struct rso_cfg_params *cfg_params;
 
 	if (vdev_id >= WLAN_MAX_VDEVS) {
 		sme_err("Invalid vdev_id: %d", vdev_id);
 		return QDF_STATUS_E_INVAL;
 	}
 
-	status = sme_acquire_global_lock(&mac->sme);
-	if (QDF_IS_STATUS_ERROR(status))
-		return status;
-
-	if (!mac->mlme_cfg->lfr.roam_scan_offload_enabled) {
-		sme_err("roam_scan_offload_enabled is not supported");
-		status = QDF_STATUS_E_INVAL;
-		goto out;
-	}
-
-	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac->pdev, vdev_id,
-						    WLAN_LEGACY_SME_ID);
-	if (!vdev) {
-		sme_err("vdev object is NULL for vdev %d", vdev_id);
-		goto out;
-	}
-	rso_cfg = wlan_cm_get_rso_config(vdev);
-	if (!rso_cfg) {
-		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
-		goto out;
-	}
-	cfg_params = &rso_cfg->cfg_param;
-	mac->roam.configParam.nRoamScanControl = false;
-
-	chan_info = &cfg_params->pref_chan_info;
-	csr_flush_cfg_bg_scan_roam_channel_list(chan_info);
-
-	chan_info = &cfg_params->specific_chan_info;
-	csr_flush_cfg_bg_scan_roam_channel_list(chan_info);
-	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
-
-	mlme_reinit_control_config_lfr_params(mac->psoc, &mac->mlme_cfg->lfr);
-
-	sme_restore_default_roaming_params(mac, vdev_id);
-
-	/* Flush static and dynamic channels in ROAM scan list in firmware */
-	wlan_roam_update_cfg(mac->psoc, vdev_id, REASON_FLUSH_CHANNEL_LIST);
-	wlan_roam_update_cfg(mac->psoc, vdev_id, REASON_SCORING_CRITERIA_CHANGED);
-
-out:
-	sme_release_global_lock(&mac->sme);
-
-	return status;
+	return csr_roam_control_restore_default_config(mac, vdev_id);
 }
 
 /*

+ 24 - 139
core/sme/src/csr/csr_api_roam.c

@@ -211,7 +211,9 @@ static QDF_STATUS csr_init_channel_power_list(struct mac_context *mac,
 static QDF_STATUS csr_roam_free_connected_info(struct mac_context *mac,
 					       struct csr_roam_connectedinfo *
 					       pConnectedInfo);
+#ifndef FEATURE_CM_ENABLE
 static void csr_roam_link_up(struct mac_context *mac, struct qdf_mac_addr bssid);
+#endif
 static enum csr_cfgdot11mode
 csr_roam_get_phy_mode_band_for_bss(struct mac_context *mac,
 				   struct csr_roam_profile *pProfile,
@@ -10102,35 +10104,6 @@ static void csr_update_snr(struct mac_context *mac, void *pMsg)
 		sme_err("pGetSnrReq is NULL");
 }
 
-static QDF_STATUS csr_send_reset_ap_caps_changed(struct mac_context *mac,
-				struct qdf_mac_addr *bssId)
-{
-	tpSirResetAPCapsChange pMsg;
-	uint16_t len;
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
-
-	/* Create the message and send to lim */
-	len = sizeof(tSirResetAPCapsChange);
-	pMsg = qdf_mem_malloc(len);
-	if (!pMsg)
-		status = QDF_STATUS_E_NOMEM;
-	else
-		status = QDF_STATUS_SUCCESS;
-
-	if (QDF_IS_STATUS_SUCCESS(status)) {
-		pMsg->messageType = eWNI_SME_RESET_AP_CAPS_CHANGED;
-		pMsg->length = len;
-		qdf_copy_macaddr(&pMsg->bssId, bssId);
-		sme_debug(
-			"CSR reset caps change for Bssid= " QDF_MAC_ADDR_FMT,
-			QDF_MAC_ADDR_REF(pMsg->bssId.bytes));
-		status = umac_send_mb_message_to_mac(pMsg);
-	} else {
-		sme_err("Memory allocation failed");
-	}
-	return status;
-}
-
 #ifndef FEATURE_CM_ENABLE
 
 #ifdef FEATURE_WLAN_ESE
@@ -10841,16 +10814,6 @@ csr_roam_chk_lnk_swt_ch_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
 
 	if (QDF_IS_STATUS_ERROR(pSwitchChnInd->status)) {
 		sme_err("Channel switch failed");
-		/* This is temp ifdef will be removed in near future */
-#ifdef FEATURE_CM_ENABLE
-		cm_disconnect(mac_ctx->psoc, sessionId,
-			      CM_MLME_DISCONNECT,
-			      REASON_CHANNEL_SWITCH_FAILED, NULL);
-#else
-		csr_roam_disconnect(mac_ctx, sessionId,
-				    eCSR_DISCONNECT_REASON_DEAUTH,
-				    REASON_CHANNEL_SWITCH_FAILED);
-#endif
 		return;
 	}
 	session->connectedProfile.op_freq = pSwitchChnInd->freq;
@@ -11060,85 +11023,6 @@ csr_roam_chk_lnk_pbs_probe_req_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_
 	qdf_mem_free(roam_info);
 }
 
-static void
-csr_roam_chk_lnk_wm_status_change_ntf(struct mac_context *mac_ctx,
-				      tSirSmeRsp *msg_ptr)
-{
-	uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX;
-	QDF_STATUS status;
-	struct csr_roam_info *roam_info;
-	struct wm_status_change_ntf *pStatusChangeMsg;
-	struct ap_new_caps *pApNewCaps;
-	eCsrRoamResult result = eCSR_ROAM_RESULT_NONE;
-	eRoamCmdStatus roamStatus = eCSR_ROAM_FAILED;
-
-	roam_info = qdf_mem_malloc(sizeof(*roam_info));
-	if (!roam_info)
-		return;
-	pStatusChangeMsg = (struct wm_status_change_ntf *) msg_ptr;
-	switch (pStatusChangeMsg->statusChangeCode) {
-	/*
-	 * detection by LIM that the capabilities of the associated
-	 * AP have changed.
-	 */
-	case eSIR_SME_AP_CAPS_CHANGED:
-		pApNewCaps = &pStatusChangeMsg->statusChangeInfo.apNewCaps;
-		sme_debug("CSR handling eSIR_SME_AP_CAPS_CHANGED");
-		status = csr_roam_get_session_id_from_bssid(mac_ctx,
-					&pApNewCaps->bssId, &sessionId);
-		if (!QDF_IS_STATUS_SUCCESS(status))
-			break;
-		if (eCSR_ROAMING_STATE_JOINED ==
-		    sme_get_current_roam_state(MAC_HANDLE(mac_ctx), sessionId)
-		    && ((eCSR_ROAM_SUBSTATE_JOINED_REALTIME_TRAFFIC
-			== mac_ctx->roam.curSubState[sessionId])
-		    || (eCSR_ROAM_SUBSTATE_NONE ==
-			mac_ctx->roam.curSubState[sessionId])
-		    || (eCSR_ROAM_SUBSTATE_JOINED_NON_REALTIME_TRAFFIC
-			== mac_ctx->roam.curSubState[sessionId])
-		    || (eCSR_ROAM_SUBSTATE_JOINED_NO_TRAFFIC ==
-			 mac_ctx->roam.curSubState[sessionId]))) {
-			sme_warn("Calling csr_roam_disconnect");
-			/* This is temp ifdef will be removed in near future */
-#ifdef FEATURE_CM_ENABLE
-			cm_disconnect(mac_ctx->psoc, sessionId,
-				      CM_MLME_DISCONNECT,
-				      REASON_UNSPEC_FAILURE, NULL);
-#else
-			csr_roam_disconnect(mac_ctx, sessionId,
-					    eCSR_DISCONNECT_REASON_UNSPECIFIED,
-					    REASON_UNSPEC_FAILURE);
-#endif
-		} else {
-			sme_warn("Skipping the new scan as CSR is in state: %s and sub-state: %s",
-				mac_trace_getcsr_roam_state(
-					mac_ctx->roam.curState[sessionId]),
-				mac_trace_getcsr_roam_sub_state(
-					mac_ctx->roam.curSubState[sessionId]));
-			/* We ignore the caps change event if CSR is not in full
-			 * connected state. Send one event to PE to reset
-			 * limSentCapsChangeNtf Once limSentCapsChangeNtf set
-			 * 0, lim can send sub sequent CAPS change event
-			 * otherwise lim cannot send any CAPS change events to
-			 * SME
-			 */
-			csr_send_reset_ap_caps_changed(mac_ctx,
-						       &pApNewCaps->bssId);
-		}
-		break;
-
-	default:
-		roamStatus = eCSR_ROAM_FAILED;
-		result = eCSR_ROAM_RESULT_NONE;
-		break;
-	} /* end switch on statusChangeCode */
-	if (eCSR_ROAM_RESULT_NONE != result) {
-		csr_roam_call_callback(mac_ctx, sessionId, roam_info, 0,
-				       roamStatus, result);
-	}
-	qdf_mem_free(roam_info);
-}
-
 static void
 csr_roam_chk_lnk_max_assoc_exceeded(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
 {
@@ -11199,9 +11083,6 @@ void csr_roam_check_for_link_status_change(struct mac_context *mac,
 	case eWNI_SME_WPS_PBC_PROBE_REQ_IND:
 		csr_roam_chk_lnk_pbs_probe_req_ind(mac, pSirMsg);
 		break;
-	case eWNI_SME_WM_STATUS_CHANGE_NTF:
-		csr_roam_chk_lnk_wm_status_change_ntf(mac, pSirMsg);
-		break;
 	case eWNI_SME_SETCONTEXT_RSP:
 		csr_roam_chk_lnk_set_ctx_rsp(mac, pSirMsg);
 		break;
@@ -11471,7 +11352,9 @@ void csr_roam_wait_for_key_time_out_handler(void *pv)
 	struct mac_context *mac = info->mac;
 	uint8_t vdev_id = info->vdev_id;
 	struct csr_roam_session *pSession = CSR_GET_SESSION(mac, vdev_id);
+#ifndef FEATURE_CM_ENABLE
 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+#endif
 
 	if (!pSession) {
 		sme_err("session not found");
@@ -11510,35 +11393,27 @@ void csr_roam_wait_for_key_time_out_handler(void *pv)
 		}
 		sme_debug("SME pre-auth state timeout");
 
-		status = sme_acquire_global_lock(&mac->sme);
 		/* This is temp ifdef will be removed in near future */
 #ifdef FEATURE_CM_ENABLE
-		if (cm_is_vdevid_connected(mac->pdev, vdev_id))
+		/* do not call cm disconnect while holding Sme lock */
+		cm_disconnect(mac->psoc, vdev_id,
+			      CM_MLME_DISCONNECT,
+			      REASON_KEY_TIMEOUT, NULL);
 #else
-		if (csr_is_conn_state_connected_infra(mac, vdev_id))
-#endif
-		{
+		status = sme_acquire_global_lock(&mac->sme);
+		if (csr_is_conn_state_connected_infra(mac, vdev_id)) {
 			csr_roam_link_up(mac,
 					 pSession->connectedProfile.bssid);
 			if (QDF_IS_STATUS_SUCCESS(status)) {
-				/*
-				 * This is temp ifdef will be removed in near
-				 * future
-				 */
-#ifdef FEATURE_CM_ENABLE
-				cm_disconnect(mac->psoc, vdev_id,
-					      CM_MLME_DISCONNECT,
-					      REASON_KEY_TIMEOUT, NULL);
-#else
 				csr_roam_disconnect(mac, vdev_id,
 					eCSR_DISCONNECT_REASON_UNSPECIFIED,
 					REASON_KEY_TIMEOUT);
-#endif
 			}
 		} else {
 			sme_err("session not found");
 		}
 		sme_release_global_lock(&mac->sme);
+#endif
 	} else {
 		spin_unlock(&mac->roam.roam_state_lock);
 	}
@@ -15320,6 +15195,7 @@ QDF_STATUS csr_roam_get_session_id_from_bssid(struct mac_context *mac,
 	return status;
 }
 
+#ifndef FEATURE_CM_ENABLE
 static void csr_roam_link_up(struct mac_context *mac, struct qdf_mac_addr bssid)
 {
 	uint32_t sessionId = 0;
@@ -15338,7 +15214,6 @@ static void csr_roam_link_up(struct mac_context *mac, struct qdf_mac_addr bssid)
 					   QDF_STATUS_SUCCESS);
 }
 
-#ifndef FEATURE_CM_ENABLE
 static void csr_roam_link_down(struct mac_context *mac, uint32_t sessionId)
 {
 	struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId);
@@ -16721,9 +16596,12 @@ void csr_process_ho_fail_ind(struct mac_context *mac_ctx, void *msg_buf)
 			DIAG_REASON_ROAM_HO_FAIL);
 	/* This is temp ifdef will be removed in near future */
 #ifdef FEATURE_CM_ENABLE
+	sme_release_global_lock(&mac_ctx->sme);
+	/* do not call cm disconnect while holding Sme lock */
 	cm_disconnect(mac_ctx->psoc, sessionId,
 		      CM_MLME_DISCONNECT,
 		      REASON_FW_TRIGGERED_ROAM_FAILURE, NULL);
+	sme_acquire_global_lock(&mac_ctx->sme);
 #else
 	csr_roam_disconnect(mac_ctx, sessionId,
 			eCSR_DISCONNECT_REASON_ROAM_HO_FAIL,
@@ -17783,9 +17661,12 @@ csr_process_roam_sync_callback(struct mac_context *mac_ctx,
 		    mac_ctx->nud_fail_behaviour == DISCONNECT_AFTER_ROAM_FAIL) {
 			/* This is temp ifdef will be removed in near future */
 #ifdef FEATURE_CM_ENABLE
+			sme_release_global_lock(&mac_ctx->sme);
+			/* do not call cm disconnect while holding Sme lock */
 			cm_disconnect(mac_ctx->psoc, session_id,
 				      CM_ROAM_DISCONNECT,
 				      REASON_USER_TRIGGERED_ROAM_FAILURE, NULL);
+			sme_acquire_global_lock(&mac_ctx->sme);
 #else
 			csr_roam_disconnect(mac_ctx, session_id,
 				    eCSR_DISCONNECT_REASON_DEAUTH,
@@ -17812,9 +17693,12 @@ csr_process_roam_sync_callback(struct mac_context *mac_ctx,
 						 roam_synch_data->chan_freq)) {
 			/* This is temp ifdef will be removed in near future */
 #ifdef FEATURE_CM_ENABLE
+			sme_release_global_lock(&mac_ctx->sme);
+			/* do not call cm disconnect while holding Sme lock */
 			cm_disconnect(mac_ctx->psoc, session_id,
 				      CM_ROAM_DISCONNECT,
 				      REASON_OPER_CHANNEL_BAND_CHANGE, NULL);
+			sme_acquire_global_lock(&mac_ctx->sme);
 #else
 			csr_roam_disconnect(mac_ctx, session_id,
 					    eCSR_DISCONNECT_REASON_DEAUTH,
@@ -18234,7 +18118,8 @@ csr_process_roam_sync_callback(struct mac_context *mac_ctx,
 		sme_qos_csr_event_ind(mac_ctx, session_id,
 				      SME_QOS_CSR_DISCONNECT_ROAM_COMPLETE,
 				      NULL);
-
+	/* for cm enable copy to reassoc/connect resp */
+#ifndef FEATURE_CM_ENABLE
 	if (!CSR_IS_WAIT_FOR_KEY(mac_ctx, session_id)) {
 		QDF_TRACE(QDF_MODULE_ID_SME,
 				QDF_TRACE_LEVEL_DEBUG,
@@ -18242,7 +18127,7 @@ csr_process_roam_sync_callback(struct mac_context *mac_ctx,
 				("NO CSR_IS_WAIT_FOR_KEY -> csr_roam_link_up"));
 		csr_roam_link_up(mac_ctx, conn_profile->bssid);
 	}
-
+#endif
 	sme_free_join_rsp_fils_params(roam_info);
 	qdf_mem_free(roam_info->pbFrames);
 	qdf_mem_free(roam_info);

+ 102 - 4
core/sme/src/csr/csr_neighbor_roam.c

@@ -541,19 +541,117 @@ QDF_STATUS csr_neighbor_roam_merge_channel_lists(struct mac_context *mac,
 }
 
 #if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
+static void
+csr_restore_default_roaming_params(struct mac_context *mac,
+				   struct wlan_objmgr_vdev *vdev)
+{
+	struct rso_config *rso_cfg;
+	struct rso_cfg_params *cfg_params;
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+
+	mlme_obj = mlme_get_psoc_ext_obj(mac->psoc);
+	if (!mlme_obj)
+		return;
+
+	rso_cfg = wlan_cm_get_rso_config(vdev);
+	if (!rso_cfg)
+		return;
+	cfg_params = &rso_cfg->cfg_param;
+	cfg_params->enable_scoring_for_roam =
+			mlme_obj->cfg.roam_scoring.enable_scoring_for_roam;
+	cfg_params->empty_scan_refresh_period =
+			mlme_obj->cfg.lfr.empty_scan_refresh_period;
+	cfg_params->full_roam_scan_period =
+			mlme_obj->cfg.lfr.roam_full_scan_period;
+	cfg_params->neighbor_scan_period =
+			mlme_obj->cfg.lfr.neighbor_scan_timer_period;
+	cfg_params->neighbor_lookup_threshold =
+			mlme_obj->cfg.lfr.neighbor_lookup_rssi_threshold;
+	cfg_params->roam_rssi_diff =
+			mlme_obj->cfg.lfr.roam_rssi_diff;
+	cfg_params->bg_rssi_threshold =
+			mlme_obj->cfg.lfr.bg_rssi_threshold;
+
+	cfg_params->max_chan_scan_time =
+			mlme_obj->cfg.lfr.neighbor_scan_max_chan_time;
+	cfg_params->roam_scan_home_away_time =
+			mlme_obj->cfg.lfr.roam_scan_home_away_time;
+	cfg_params->roam_scan_n_probes =
+			mlme_obj->cfg.lfr.roam_scan_n_probes;
+	cfg_params->roam_scan_inactivity_time =
+			mlme_obj->cfg.lfr.roam_scan_inactivity_time;
+	cfg_params->roam_inactive_data_packet_count =
+			mlme_obj->cfg.lfr.roam_inactive_data_packet_count;
+	cfg_params->roam_scan_period_after_inactivity =
+			mlme_obj->cfg.lfr.roam_scan_period_after_inactivity;
+}
+
+QDF_STATUS csr_roam_control_restore_default_config(struct mac_context *mac,
+						   uint8_t vdev_id)
+{
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+	struct rso_chan_info *chan_info;
+	struct wlan_objmgr_vdev *vdev;
+	struct rso_config *rso_cfg;
+	struct rso_cfg_params *cfg_params;
+
+	if (!mac->mlme_cfg->lfr.roam_scan_offload_enabled) {
+		sme_err("roam_scan_offload_enabled is not supported");
+		goto out;
+	}
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac->pdev, vdev_id,
+						    WLAN_LEGACY_SME_ID);
+	if (!vdev) {
+		sme_err("vdev object is NULL for vdev %d", vdev_id);
+		goto out;
+	}
+	rso_cfg = wlan_cm_get_rso_config(vdev);
+	if (!rso_cfg) {
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
+		goto out;
+	}
+	cfg_params = &rso_cfg->cfg_param;
+	mac->roam.configParam.nRoamScanControl = false;
+
+	chan_info = &cfg_params->pref_chan_info;
+	csr_flush_cfg_bg_scan_roam_channel_list(chan_info);
+
+	chan_info = &cfg_params->specific_chan_info;
+	csr_flush_cfg_bg_scan_roam_channel_list(chan_info);
+
+	mlme_reinit_control_config_lfr_params(mac->psoc, &mac->mlme_cfg->lfr);
+
+	csr_restore_default_roaming_params(mac, vdev);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
+
+	/* Flush static and dynamic channels in ROAM scan list in firmware */
+	wlan_roam_update_cfg(mac->psoc, vdev_id, REASON_FLUSH_CHANNEL_LIST);
+	wlan_roam_update_cfg(mac->psoc, vdev_id, REASON_SCORING_CRITERIA_CHANGED);
+
+	status = QDF_STATUS_SUCCESS;
+out:
+	return status;
+}
+
 void csr_roam_restore_default_config(struct mac_context *mac_ctx,
 				     uint8_t vdev_id)
 {
 	struct wlan_roam_triggers triggers;
+	struct cm_roam_values_copy src_config;
 
-	sme_set_roam_config_enable(MAC_HANDLE(mac_ctx), vdev_id, 0);
+	if (mac_ctx->mlme_cfg->lfr.roam_scan_offload_enabled) {
+		src_config.bool_value = 0;
+		wlan_cm_roam_cfg_set_value(mac_ctx->psoc, vdev_id,
+				   ROAM_CONFIG_ENABLE,
+				   &src_config);
+	}
 
 	triggers.vdev_id = vdev_id;
 	triggers.trigger_bitmap = wlan_mlme_get_roaming_triggers(mac_ctx->psoc);
 	sme_debug("Reset roam trigger bitmap to 0x%x", triggers.trigger_bitmap);
-	wlan_cm_rso_set_roam_trigger(mac_ctx->pdev, vdev_id, &triggers);
-	sme_roam_control_restore_default_config(MAC_HANDLE(mac_ctx),
-						vdev_id);
+	cm_rso_set_roam_trigger(mac_ctx->pdev, vdev_id, &triggers);
+	csr_roam_control_restore_default_config(mac_ctx, vdev_id);
 }
 #endif