Explorar o código

qcacmn: Add lock to Set/clear WLAN_VDEV_FEXT2_MLO_STA_LINK flag

Currently, this MLO flag is being set/clear without regard for
concurrency. We need to lock the vdev when updating these values to
prevent race condition.

Change-Id: Ied90d62f10f6f12a35eeac3060dd0fae7d0c6cfd
CRs-Fixed: 3305558
David Oladunjoye %!s(int64=2) %!d(string=hai) anos
pai
achega
25cb050e32

+ 1 - 2
os_if/linux/mlme/src/osif_cm_req.c

@@ -501,8 +501,7 @@ void osif_update_partner_vdev_info(struct wlan_objmgr_vdev *vdev,
 		if (tmp_vdev) {
 			mlo_update_connect_req_links(tmp_vdev, 1);
 			wlan_vdev_mlme_set_mlo_vdev(tmp_vdev);
-			wlan_vdev_mlme_feat_ext2_cap_set(
-					tmp_vdev, WLAN_VDEV_FEXT2_MLO_STA_LINK);
+			wlan_vdev_mlme_set_mlo_link_vdev(tmp_vdev);
 			wlan_vdev_set_link_id(
 				tmp_vdev,
 				partner_info.partner_link_info[i].link_id);

+ 26 - 0
umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h

@@ -1603,6 +1603,22 @@ void wlan_vdev_mlme_set_mlo_vdev(struct wlan_objmgr_vdev *vdev);
  */
 void wlan_vdev_mlme_clear_mlo_vdev(struct wlan_objmgr_vdev *vdev);
 
+/**
+ * wlan_vdev_mlme_set_mlo_link_vdev() - Set vdev as an MLO link vdev
+ * @vdev: VDEV object
+ *
+ * Return: void
+ */
+void wlan_vdev_mlme_set_mlo_link_vdev(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * wlan_vdev_mlme_clear_mlo_link_vdev() - Mark that the vdev is no longer an
+ * MLO link vdev
+ * @vdev: VDEV object
+ *
+ * Return: void
+ */
+void wlan_vdev_mlme_clear_mlo_link_vdev(struct wlan_objmgr_vdev *vdev);
 #ifdef WLAN_MCAST_MLO
 /**
  * wlan_vdev_mlme_is_mlo_mcast_vdev() - whether it is mlo mcast vdev or not
@@ -1696,6 +1712,16 @@ void wlan_vdev_mlme_clear_mlo_vdev(struct wlan_objmgr_vdev *vdev)
 {
 }
 
+static inline
+void wlan_vdev_mlme_set_mlo_link_vdev(struct wlan_objmgr_vdev *vdev)
+{
+}
+
+static inline
+void wlan_vdev_mlme_clear_mlo_link_vdev(struct wlan_objmgr_vdev *vdev)
+{
+}
+
 static inline
 bool wlan_vdev_mlme_is_mlo_link_vdev(struct wlan_objmgr_vdev *vdev)
 {

+ 38 - 0
umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c

@@ -1551,4 +1551,42 @@ void wlan_vdev_mlme_clear_mlo_vdev(struct wlan_objmgr_vdev *vdev)
 
 	wlan_release_vdev_mlo_lock(vdev);
 }
+
+void wlan_vdev_mlme_set_mlo_link_vdev(struct wlan_objmgr_vdev *vdev)
+{
+	if (!vdev) {
+		obj_mgr_err("vdev is NULL");
+		return;
+	}
+
+	wlan_acquire_vdev_mlo_lock(vdev);
+
+	if (wlan_vdev_mlme_feat_ext2_cap_get(vdev,
+					     WLAN_VDEV_FEXT2_MLO_STA_LINK)) {
+		wlan_release_vdev_mlo_lock(vdev);
+		return;
+	}
+	wlan_vdev_mlme_feat_ext2_cap_set(vdev, WLAN_VDEV_FEXT2_MLO_STA_LINK);
+
+	wlan_release_vdev_mlo_lock(vdev);
+}
+
+void wlan_vdev_mlme_clear_mlo_link_vdev(struct wlan_objmgr_vdev *vdev)
+{
+	if (!vdev) {
+		obj_mgr_err("vdev is NULL");
+		return;
+	}
+
+	wlan_acquire_vdev_mlo_lock(vdev);
+
+	if (!wlan_vdev_mlme_feat_ext2_cap_get(vdev,
+					      WLAN_VDEV_FEXT2_MLO_STA_LINK)) {
+		wlan_release_vdev_mlo_lock(vdev);
+		return;
+	}
+	wlan_vdev_mlme_feat_ext2_cap_clear(vdev, WLAN_VDEV_FEXT2_MLO_STA_LINK);
+
+	wlan_release_vdev_mlo_lock(vdev);
+}
 #endif /* WLAN_FEATURE_11BE_MLO */

+ 4 - 10
umac/mlo_mgr/src/wlan_mlo_mgr_sta.c

@@ -269,9 +269,7 @@ void mlo_mld_clear_mlo_cap(struct wlan_objmgr_vdev *vdev)
 		if (!mlo_dev_ctx->wlan_vdev_list[i])
 			continue;
 		wlan_vdev_mlme_clear_mlo_vdev(mlo_dev_ctx->wlan_vdev_list[i]);
-		wlan_vdev_mlme_feat_ext2_cap_clear(
-				mlo_dev_ctx->wlan_vdev_list[i],
-				WLAN_VDEV_FEXT2_MLO_STA_LINK);
+		wlan_vdev_mlme_clear_mlo_link_vdev(mlo_dev_ctx->wlan_vdev_list[i]);
 	}
 }
 
@@ -612,8 +610,7 @@ mlo_send_link_connect(struct wlan_objmgr_vdev *vdev,
 		    (mlo_dev_ctx->wlan_vdev_list[i] == vdev))
 			continue;
 		wlan_vdev_mlme_set_mlo_vdev(mlo_dev_ctx->wlan_vdev_list[i]);
-		wlan_vdev_mlme_feat_ext2_cap_set(mlo_dev_ctx->wlan_vdev_list[i],
-						 WLAN_VDEV_FEXT2_MLO_STA_LINK);
+		wlan_vdev_mlme_set_mlo_link_vdev(mlo_dev_ctx->wlan_vdev_list[i]);
 		wlan_vdev_set_link_id(
 		      mlo_dev_ctx->wlan_vdev_list[i],
 		      ml_parnter_info->partner_link_info[partner_idx].link_id);
@@ -1223,8 +1220,7 @@ void mlo_sta_link_handle_pending_connect(struct wlan_objmgr_vdev *vdev)
 	if (sta_ctx->connect_req->ml_parnter_info.num_partner_links) {
 		partner_info = sta_ctx->connect_req->ml_parnter_info;
 		wlan_vdev_mlme_set_mlo_vdev(vdev);
-		wlan_vdev_mlme_feat_ext2_cap_clear(
-				vdev, WLAN_VDEV_FEXT2_MLO_STA_LINK);
+		wlan_vdev_mlme_clear_mlo_link_vdev(vdev);
 		mlo_clear_connect_req_links_bmap(vdev);
 		mlo_update_connect_req_links(vdev, 1);
 		for (i = 0; i < partner_info.num_partner_links; i++) {
@@ -1235,9 +1231,7 @@ void mlo_sta_link_handle_pending_connect(struct wlan_objmgr_vdev *vdev)
 			if (tmp_vdev) {
 				mlo_update_connect_req_links(tmp_vdev, 1);
 				wlan_vdev_mlme_set_mlo_vdev(tmp_vdev);
-				wlan_vdev_mlme_feat_ext2_cap_set(
-						tmp_vdev,
-						WLAN_VDEV_FEXT2_MLO_STA_LINK);
+				wlan_vdev_mlme_set_mlo_link_vdev(tmp_vdev);
 				wlan_vdev_set_link_id(
 					tmp_vdev,
 					partner_link_info.link_id);