|
@@ -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;
|