Przeglądaj źródła

qcacmn: Send disconnect to kernel upon reassoc failure

DUT is in connected state, and a connect request(reassoc)
to a new BSSID is issued from userspace. Host triggers
disconnect of the existing connection, but the candidate
is not found for the new bssid hint even after scan and this
leads to connection failure.

Host does not indicate the disconnect of the previous BSSID
connection, and only connect result with status failure is
sent to the userspace for the reassoc connection. As a result
of this kernel fails to reset wdev->connected flag, and leads
to out-of-sync issues between kernel and host driver.

To fix this, extend the current disconnect indication logic on
non-init & non-connected state to all non-init states. Upon
connect failure, this ensures to send the disconnect indication
to the kernel, to clear the previous connection info.

Change-Id: I917b6a187d76c80a68cb56c7e1f33ca1805cbe55
CRs-Fixed: 3604338
Surya Prakash Sivaraj 1 rok temu
rodzic
commit
4daee5289b

+ 22 - 10
umac/mlme/connection_mgr/core/src/wlan_cm_connect.c

@@ -1672,9 +1672,22 @@ cm_handle_connect_req_in_non_init_state(struct cnx_mgr *cm_ctx,
 {
 	uint8_t vdev_id = wlan_vdev_get_id(cm_ctx->vdev);
 
-	if (cm_state_substate != WLAN_CM_S_CONNECTED &&
-	    cm_is_connect_req_reassoc(&cm_req->req)) {
-		cm_req->req.reassoc_in_non_connected = true;
+	/*
+	 * Connect re-assoc req should have been received in one of the
+	 * following states:
+	 * a) SB disconnect in progress
+	 * b) Roam start/Roam sync in progress
+	 * c) Reassoc
+	 * d) Connected state with LFR3 disabled
+	 * e) Invalid Roam request
+	 *
+	 * In this case, set reassoc_in_non_init flag, so that disconnect can
+	 * be notified to the upper layers if connect request fails. This is
+	 * required by upper layers to clear the connection state of the
+	 * previous connection.
+	 */
+	if (cm_is_connect_req_reassoc(&cm_req->req)) {
+		cm_req->req.reassoc_in_non_init = true;
 		mlme_debug(CM_PREFIX_FMT "Reassoc received in %d state",
 			   CM_PREFIX_REF(vdev_id, cm_req->cm_id),
 			   cm_state_substate);
@@ -2799,17 +2812,17 @@ cm_clear_vdev_mlo_cap(struct wlan_objmgr_vdev *vdev)
 #endif /*WLAN_FEATURE_11BE_MLO*/
 
 /**
- * cm_is_connect_id_reassoc_in_non_connected()
+ * cm_is_connect_id_reassoc_in_non_init()
  * @cm_ctx: connection manager context
  * @cm_id: cm id
  *
- * If connect req is a reassoc req and received in not connected state.
+ * If connect req is a reassoc req and received in non init state.
  * Caller should take cm_ctx lock.
  *
  * Return: bool
  */
-static bool cm_is_connect_id_reassoc_in_non_connected(struct cnx_mgr *cm_ctx,
-						      wlan_cm_id cm_id)
+static bool cm_is_connect_id_reassoc_in_non_init(struct cnx_mgr *cm_ctx,
+						 wlan_cm_id cm_id)
 {
 	qdf_list_node_t *cur_node = NULL, *next_node = NULL;
 	struct cm_req *cm_req;
@@ -2825,7 +2838,7 @@ static bool cm_is_connect_id_reassoc_in_non_connected(struct cnx_mgr *cm_ctx,
 		cm_req = qdf_container_of(cur_node, struct cm_req, node);
 
 		if (cm_req->cm_id == cm_id) {
-			if (cm_req->connect_req.req.reassoc_in_non_connected)
+			if (cm_req->connect_req.req.reassoc_in_non_init)
 				is_reassoc = true;
 			return is_reassoc;
 		}
@@ -2894,8 +2907,7 @@ QDF_STATUS cm_notify_connect_complete(struct cnx_mgr *cm_ctx,
 	    sm_state == WLAN_CM_S_INIT) {
 		if (acquire_lock)
 			cm_req_lock_acquire(cm_ctx);
-		if (cm_is_connect_id_reassoc_in_non_connected(cm_ctx,
-							      resp->cm_id)) {
+		if (cm_is_connect_id_reassoc_in_non_init(cm_ctx, resp->cm_id)) {
 			resp->send_disconnect = true;
 			mlme_debug(CM_PREFIX_FMT "Set send disconnect to true to indicate disconnect instead of connect resp",
 				   CM_PREFIX_REF(wlan_vdev_get_id(cm_ctx->vdev),

+ 2 - 2
umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_public_struct.h

@@ -204,7 +204,7 @@ enum wlan_cm_source {
  * for production.
  * @is_wps_connection: if its wps connection
  * @is_osen_connection: if its osen connection
- * @reassoc_in_non_connected: if reassoc received in non connected
+ * @reassoc_in_non_init: if reassoc received in non init state
  * @dot11mode_filter: dot11mode filter used to restrict connection to
  * 11n/11ac/11ax.
  * @sae_pwe: SAE mechanism for PWE derivation
@@ -234,7 +234,7 @@ struct wlan_cm_connect_req {
 	uint8_t force_rsne_override:1,
 		is_wps_connection:1,
 		is_osen_connection:1,
-		reassoc_in_non_connected:1;
+		reassoc_in_non_init:1;
 	enum dot11_mode_filter dot11mode_filter;
 	uint8_t sae_pwe;
 	uint16_t ht_caps;