فهرست منبع

qcacmn: Release link peer ref if MLO peer attach fails

MLO peer attach fails if MLO peer with same MLD address gets
created. While freeing MLO peer, releasing of link peer ref
is missed

Fixed some of the corner cases handling with ml peer id, AID

Change-Id: Ia3ff13a3840083bfe389b39086a6c5aa1f709fca
CRs-Fixed: 3185069
Srinivas Pitla 3 سال پیش
والد
کامیت
feb53a95ee
3فایلهای تغییر یافته به همراه48 افزوده شده و 14 حذف شده
  1. 7 0
      umac/mlo_mgr/src/wlan_mlo_mgr_aid.c
  2. 6 4
      umac/mlo_mgr/src/wlan_mlo_mgr_ap.c
  3. 35 10
      umac/mlo_mgr/src/wlan_mlo_mgr_peer.c

+ 7 - 0
umac/mlo_mgr/src/wlan_mlo_mgr_aid.c

@@ -404,6 +404,13 @@ QDF_STATUS mlo_peer_free_aid(struct wlan_mlo_dev_context *ml_dev,
 	if (!ml_aid_mgr)
 		return QDF_STATUS_E_INVAL;
 
+	if (!ml_peer->assoc_id) {
+		mlo_info("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " ML assoc id is 0",
+			 ml_dev->mld_id,
+			 QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes));
+		return status;
+	}
+
 	wlan_mlo_peer_free_aid(ml_aid_mgr, 0xff, ml_peer->assoc_id);
 
 	return status;

+ 6 - 4
umac/mlo_mgr/src/wlan_mlo_mgr_ap.c

@@ -303,7 +303,7 @@ uint16_t mlo_ap_ml_peerid_alloc(void)
 	if (i == mlo_ctx->max_mlo_peer_id)
 		return MLO_INVALID_PEER_ID;
 
-	mlo_debug(" ML peee id %d is allocated", i + 1);
+	mlo_debug(" ML peer id %d is allocated", i + 1);
 
 	return i + 1;
 }
@@ -312,11 +312,13 @@ void mlo_ap_ml_peerid_free(uint16_t mlo_peer_id)
 {
 	struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx();
 
-	if (mlo_peer_id == MLO_INVALID_PEER_ID)
+	if ((mlo_peer_id == 0) || (mlo_peer_id == MLO_INVALID_PEER_ID)) {
+		mlo_err(" ML peer id %d is invalid", mlo_peer_id);
 		return;
+	}
 
 	if (mlo_peer_id > mlo_ctx->max_mlo_peer_id) {
-		mlo_err(" ML peee id %d is invalid", mlo_peer_id);
+		mlo_err(" ML peer id %d is invalid", mlo_peer_id);
 		QDF_BUG(0);
 		return;
 	}
@@ -327,7 +329,7 @@ void mlo_ap_ml_peerid_free(uint16_t mlo_peer_id)
 
 	ml_peerid_lock_release(mlo_ctx);
 
-	mlo_debug(" ML peee id %d is freed", mlo_peer_id);
+	mlo_debug(" ML peer id %d is freed", mlo_peer_id);
 }
 
 void mlo_ap_vdev_quiet_set(struct wlan_objmgr_vdev *vdev)

+ 35 - 10
umac/mlo_mgr/src/wlan_mlo_mgr_peer.c

@@ -325,6 +325,14 @@ wlan_mlo_peer_deauth_init(struct wlan_mlo_peer_context *ml_peer)
 			continue;
 
 		link_peer = peer_entry->link_peer;
+		/* Skip Deauth if PMF is enabled for the station */
+		if ((i == 0) &&
+		    (wlan_crypto_is_pmf_enabled(wlan_peer_get_vdev(link_peer),
+					       link_peer))) {
+			mlo_peer_lock_release(ml_peer);
+			return;
+		}
+
 		if (wlan_objmgr_peer_try_get_ref(link_peer, WLAN_MLO_MGR_ID) !=
 						QDF_STATUS_SUCCESS)
 			continue;
@@ -338,18 +346,13 @@ wlan_mlo_peer_deauth_init(struct wlan_mlo_peer_context *ml_peer)
 			continue;
 
 		/* Prepare and queue message */
-		if (i == 0) {
-			/* Skip Deauth if PMF is enabled for the station */
-			if (wlan_crypto_is_pmf_enabled(
-					wlan_peer_get_vdev(link_peers[i]),
-					link_peers[i]))
-				break;
-
+		if (i == 0)
 			mlo_link_peer_deauth_init(ml_dev, link_peers[i]);
-		} else {
+		else
 			mlo_link_peer_disconnect_notify(ml_dev, link_peers[i]);
-		}
 	}
+
+	return;
 }
 
 void
@@ -825,7 +828,18 @@ QDF_STATUS wlan_mlo_peer_create(struct wlan_objmgr_vdev *vdev,
 		ml_peer->mlpeer_state = ML_PEER_CREATED;
 		ml_peer->max_links = ml_info->num_partner_links;
 		ml_peer->primary_umac_psoc_id = ML_PRIMARY_UMAC_ID_INVAL;
+
 		ml_peer->mlo_peer_id = mlo_ap_ml_peerid_alloc();
+		if (ml_peer->mlo_peer_id == MLO_INVALID_PEER_ID) {
+			mlo_err("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " invalid ml peer id",
+				ml_dev->mld_id,
+				QDF_MAC_ADDR_REF
+				(ml_peer->peer_mld_addr.bytes));
+			mlo_peer_free(ml_peer);
+			mlo_dev_release_link_vdevs(link_vdevs);
+			return QDF_STATUS_E_RESOURCES;
+		}
+
 		qdf_copy_macaddr((struct qdf_mac_addr *)&ml_peer->peer_mld_addr,
 				 (struct qdf_mac_addr *)&link_peer->mldaddr[0]);
 		/* Allocate AID */
@@ -850,7 +864,16 @@ QDF_STATUS wlan_mlo_peer_create(struct wlan_objmgr_vdev *vdev,
 	/* Populate Link peer pointer, peer MAC address,
 	 * MLD address. HW link ID, update ref count
 	 */
-	mlo_peer_attach_link_peer(ml_peer, link_peer, NULL);
+	status = mlo_peer_attach_link_peer(ml_peer, link_peer, NULL);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		mlo_err("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " link peer attach failed",
+			ml_dev->mld_id,
+			QDF_MAC_ADDR_REF
+			(ml_peer->peer_mld_addr.bytes));
+		mlo_peer_free(ml_peer);
+		mlo_dev_release_link_vdevs(link_vdevs);
+		return status;
+	}
 
 	/* Allocate Primary UMAC */
 	mlo_peer_allocate_primary_umac(ml_dev, ml_peer, link_vdevs);
@@ -870,6 +893,8 @@ QDF_STATUS wlan_mlo_peer_create(struct wlan_objmgr_vdev *vdev,
 				ml_dev->mld_id,
 				QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes));
 			mlo_reset_link_peer(ml_peer, link_peer);
+			wlan_objmgr_peer_release_ref(link_peer,
+						     WLAN_MLO_MGR_ID);
 			mlo_peer_free(ml_peer);
 			mlo_dev_release_link_vdevs(link_vdevs);
 			return status;