|
@@ -831,6 +831,101 @@ QDF_STATUS wlan_send_tid_to_link_mapping(struct wlan_objmgr_vdev *vdev,
|
|
|
return status;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * wlan_get_vdev_t2lm_mapping_status() - API to get vdev level T2LM info
|
|
|
+ * @vdev: vdev object
|
|
|
+ * @t2lm: T2LM info
|
|
|
+ *
|
|
|
+ * Return: QDF_STATUS
|
|
|
+ */
|
|
|
+static
|
|
|
+QDF_STATUS wlan_get_vdev_t2lm_mapping_status(struct wlan_objmgr_vdev *vdev,
|
|
|
+ struct wlan_t2lm_info *t2lm)
|
|
|
+{
|
|
|
+ struct wlan_t2lm_context *t2lm_ctx;
|
|
|
+ int i = 0;
|
|
|
+
|
|
|
+ t2lm_ctx = &vdev->mlo_dev_ctx->t2lm_ctx;
|
|
|
+
|
|
|
+ t2lm_dev_lock_acquire(t2lm_ctx);
|
|
|
+ qdf_mem_copy(&t2lm[i++], &t2lm_ctx->established_t2lm.t2lm,
|
|
|
+ sizeof(struct wlan_t2lm_info));
|
|
|
+ t2lm_dev_lock_release(t2lm_ctx);
|
|
|
+
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * wlan_get_peer_t2lm_mapping_status() - API to get peer level T2LM info
|
|
|
+ * @peer: peer object
|
|
|
+ * @t2lm: T2LM info
|
|
|
+ *
|
|
|
+ * Return: QDF_STATUS
|
|
|
+ */
|
|
|
+static
|
|
|
+QDF_STATUS wlan_get_peer_t2lm_mapping_status(struct wlan_objmgr_peer *peer,
|
|
|
+ struct wlan_t2lm_info *t2lm)
|
|
|
+{
|
|
|
+ enum wlan_t2lm_direction dir = WLAN_T2LM_INVALID_DIRECTION;
|
|
|
+ struct wlan_mlo_peer_context *ml_peer;
|
|
|
+ struct wlan_prev_t2lm_negotiated_info *t2lm_req;
|
|
|
+ int i = 0;
|
|
|
+
|
|
|
+ ml_peer = peer->mlo_peer_ctx;
|
|
|
+ if (!ml_peer)
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
+
|
|
|
+ t2lm_req = &ml_peer->t2lm_policy.t2lm_negotiated_info;
|
|
|
+ if ((t2lm_req->t2lm_info[WLAN_T2LM_DL_DIRECTION].direction ==
|
|
|
+ WLAN_T2LM_DL_DIRECTION ||
|
|
|
+ t2lm_req->t2lm_info[WLAN_T2LM_UL_DIRECTION].direction ==
|
|
|
+ WLAN_T2LM_UL_DIRECTION) &&
|
|
|
+ t2lm_req->t2lm_info[WLAN_T2LM_BIDI_DIRECTION].direction ==
|
|
|
+ WLAN_T2LM_BIDI_DIRECTION) {
|
|
|
+ t2lm_err("Both DL/UL and BIDI T2LM IEs should not be present at the same time");
|
|
|
+ return QDF_STATUS_E_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (dir = 0; dir < WLAN_T2LM_MAX_DIRECTION; dir++) {
|
|
|
+ if (t2lm_req->t2lm_info[dir].direction !=
|
|
|
+ WLAN_T2LM_INVALID_DIRECTION)
|
|
|
+ qdf_mem_copy(&t2lm[i++], &t2lm_req->t2lm_info[dir],
|
|
|
+ sizeof(struct wlan_t2lm_info));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (i == 0)
|
|
|
+ return QDF_STATUS_E_EMPTY;
|
|
|
+
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+QDF_STATUS wlan_get_t2lm_mapping_status(struct wlan_objmgr_vdev *vdev,
|
|
|
+ struct wlan_t2lm_info *t2lm)
|
|
|
+{
|
|
|
+ struct wlan_objmgr_peer *peer;
|
|
|
+ QDF_STATUS status = QDF_STATUS_E_FAILURE;
|
|
|
+
|
|
|
+ peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_MLO_MGR_ID);
|
|
|
+ if (!peer) {
|
|
|
+ t2lm_err("peer not found");
|
|
|
+ return QDF_STATUS_E_NULL_VALUE;
|
|
|
+ }
|
|
|
+
|
|
|
+ status = wlan_get_peer_t2lm_mapping_status(peer, t2lm);
|
|
|
+ if (QDF_IS_STATUS_SUCCESS(status)) {
|
|
|
+ t2lm_debug("peer level T2LM info");
|
|
|
+ goto peer_release;
|
|
|
+ }
|
|
|
+
|
|
|
+ t2lm_debug("vdev level T2LM info");
|
|
|
+ status = wlan_get_vdev_t2lm_mapping_status(vdev, t2lm);
|
|
|
+
|
|
|
+peer_release:
|
|
|
+ wlan_objmgr_peer_release_ref(peer, WLAN_MLO_MGR_ID);
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
void wlan_mlo_t2lm_timer_expiry_handler(void *vdev)
|
|
|
{
|
|
|
struct wlan_objmgr_vdev *vdev_ctx = (struct wlan_objmgr_vdev *)vdev;
|