Ver código fonte

qcacld-3.0: Allow add peer on same ML dev context

A 802.11be MLD device can have one of the links
address same as MLD address. On add peer for this
MLD peer the validation for existing peers with same
MAC address may fail as a match with existing peer
will be found.

If an existing peer with new peer's MLD address
is found, then allow new peer if both existing peer
and new peer are in same ML dev context, if both
are on different ML dev context, reject the peer
add request.

Change-Id: I30c53032f228f166a1011b330ca245581dfe468b
CRs-Fixed: 3381720
Vinod Kumar Pirla 2 anos atrás
pai
commit
80f1799d9b
2 arquivos alterados com 107 adições e 22 exclusões
  1. 3 2
      core/mac/src/pe/lim/lim_process_auth_frame.c
  2. 104 20
      core/wma/src/wma_dev_if.c

+ 3 - 2
core/mac/src/pe/lim/lim_process_auth_frame.c

@@ -654,10 +654,11 @@ lim_validate_mac_address_in_auth_frame(struct mac_context *mac_ctx,
 		return QDF_STATUS_E_ALREADY;
 	}
 
-	if (mlo_mgr_ml_peer_exist(mac_hdr->sa))
+	if (mlo_mgr_ml_peer_exist_on_diff_ml_ctx(mac_hdr->sa, NULL))
 		return QDF_STATUS_E_ALREADY;
 
-	if (mlo_mgr_ml_peer_exist(rx_auth_frm_body->peer_mld.bytes))
+	if (mlo_mgr_ml_peer_exist_on_diff_ml_ctx(
+				rx_auth_frm_body->peer_mld.bytes, NULL))
 		return QDF_STATUS_E_ALREADY;
 
 	return QDF_STATUS_SUCCESS;

+ 104 - 20
core/wma/src/wma_dev_if.c

@@ -1765,53 +1765,137 @@ static int wma_get_obj_mgr_peer_type(tp_wma_handle wma, uint8_t vdev_id,
 
 }
 
+#ifdef WLAN_FEATURE_11BE_MLO
+static QDF_STATUS
+wma_create_peer_validate_mld_address(tp_wma_handle wma,
+				     uint8_t *peer_mld_addr,
+				     struct wlan_objmgr_vdev *vdev)
+{
+	uint8_t peer_vdev_id, vdev_id;
+	struct wlan_objmgr_vdev *dup_vdev;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct wlan_objmgr_psoc *psoc = wma->psoc;
+
+	vdev_id = wlan_vdev_get_id(vdev);
+	/* Check if the @peer_mld_addr matches any other
+	 * peer's link address.
+	 * We may find a match if one of the peers added
+	 * has same MLD and link, in such case check if
+	 * both are in same ML dev context.
+	 */
+	if (wma_objmgr_peer_exist(wma, peer_mld_addr, &peer_vdev_id)) {
+		if (peer_vdev_id != vdev_id) {
+			dup_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
+						psoc, peer_vdev_id,
+						WLAN_LEGACY_WMA_ID);
+			if (!dup_vdev)
+				return QDF_STATUS_E_INVAL;
+
+			/* If ML dev context is NULL then the matching
+			 * peer exist on non ML VDEV, so reject the peer.
+			 */
+			if (!dup_vdev->mlo_dev_ctx) {
+				wlan_objmgr_vdev_release_ref(
+						dup_vdev, WLAN_LEGACY_WMA_ID);
+				return QDF_STATUS_E_ALREADY;
+			} else if (dup_vdev->mlo_dev_ctx != vdev->mlo_dev_ctx) {
+				wma_debug("Peer " QDF_MAC_ADDR_FMT " already exists on vdev %d, current vdev %d",
+					  QDF_MAC_ADDR_REF(peer_mld_addr),
+					  peer_vdev_id, vdev_id);
+				wlan_objmgr_vdev_release_ref(
+						dup_vdev, WLAN_LEGACY_WMA_ID);
+				status = QDF_STATUS_E_ALREADY;
+			} else {
+				wlan_objmgr_vdev_release_ref(
+						dup_vdev, WLAN_LEGACY_WMA_ID);
+				wma_debug("Allow ML peer on same ML dev context");
+				status = QDF_STATUS_SUCCESS;
+			}
+		} else {
+			wma_debug("Allow ML peer on same ML dev context");
+			status = QDF_STATUS_SUCCESS;
+		}
+	} else if (mlo_mgr_ml_peer_exist_on_diff_ml_ctx(peer_mld_addr,
+							&vdev_id)) {
+		/* Reject if MLD exists on different ML dev context,
+		 */
+		wma_debug("ML Peer " QDF_MAC_ADDR_FMT " already exists on different ML dev context",
+			  QDF_MAC_ADDR_REF(peer_mld_addr));
+		status = QDF_STATUS_E_ALREADY;
+	}
+
+	return status;
+}
+#else
+static QDF_STATUS
+wma_create_peer_validate_mld_address(tp_wma_handle wma,
+				     uint8_t *peer_mld_addr,
+				     struct wlan_objmgr_vdev *vdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
 struct wlan_objmgr_peer *wma_create_objmgr_peer(tp_wma_handle wma,
 						uint8_t vdev_id,
 						uint8_t *peer_addr,
 						uint32_t wma_peer_type,
 						uint8_t *peer_mld_addr)
 {
-	uint32_t obj_peer_type = 0;
+	QDF_STATUS status;
+	uint8_t peer_vdev_id;
+	uint32_t obj_peer_type;
+	struct wlan_objmgr_vdev *obj_vdev;
 	struct wlan_objmgr_peer *obj_peer = NULL;
-	struct wlan_objmgr_vdev *obj_vdev = NULL;
 	struct wlan_objmgr_psoc *psoc = wma->psoc;
-	uint8_t peer_vdev_id;
+
+	obj_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+							WLAN_LEGACY_WMA_ID);
+
+	if (!obj_vdev) {
+		wma_err("Invalid obj vdev. Unable to create peer");
+		return NULL;
+	}
 
 	/*
 	 * Check if peer with same MAC exist on any Vdev, If so avoid
 	 * adding this peer.
 	 */
 	if (wma_objmgr_peer_exist(wma, peer_addr, &peer_vdev_id)) {
-		wma_info("Peer " QDF_MAC_ADDR_FMT " already exist on vdev %d, current vdev %d",
-			 QDF_MAC_ADDR_REF(peer_addr), peer_vdev_id, vdev_id);
-		return NULL;
+		wma_debug("Peer " QDF_MAC_ADDR_FMT " already exists on vdev %d, current vdev %d",
+			  QDF_MAC_ADDR_REF(peer_addr), peer_vdev_id, vdev_id);
+		goto vdev_ref;
 	}
 
-	if (wma_objmgr_peer_exist(wma, peer_mld_addr, &peer_vdev_id)) {
-		wma_info("Peer " QDF_MAC_ADDR_FMT " already exist on vdev %d, current vdev %d",
-			 QDF_MAC_ADDR_REF(peer_mld_addr), peer_vdev_id, vdev_id);
-		return NULL;
+	/* Reject if same MAC exists on different ML dev context */
+	if (mlo_mgr_ml_peer_exist_on_diff_ml_ctx(peer_addr,
+						 &vdev_id)) {
+		wma_debug("Peer " QDF_MAC_ADDR_FMT " already exists on different ML dev context",
+			  QDF_MAC_ADDR_REF(peer_addr));
+		goto vdev_ref;
 	}
+
+	status = wma_create_peer_validate_mld_address(wma, peer_mld_addr,
+						      obj_vdev);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		wma_debug("MLD " QDF_MAC_ADDR_FMT " matches with peer on different MLD context",
+			  QDF_MAC_ADDR_REF(peer_mld_addr));
+		goto vdev_ref;
+	}
+
 	obj_peer_type = wma_get_obj_mgr_peer_type(wma, vdev_id, peer_addr,
 						  wma_peer_type);
 	if (!obj_peer_type) {
 		wma_err("Invalid obj peer type. Unable to create peer %d",
 			obj_peer_type);
-		return NULL;
+		goto vdev_ref;
 	}
 
 	/* Create obj_mgr peer */
-	obj_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
-						    WLAN_LEGACY_WMA_ID);
-
-	if (!obj_vdev) {
-		wma_err("Invalid obj vdev. Unable to create peer %d",
-			obj_peer_type);
-		return NULL;
-	}
-
 	obj_peer = wlan_objmgr_peer_obj_create(obj_vdev, obj_peer_type,
 						peer_addr);
+
+vdev_ref:
 	wlan_objmgr_vdev_release_ref(obj_vdev, WLAN_LEGACY_WMA_ID);
 
 	return obj_peer;