|
@@ -32,6 +32,7 @@
|
|
|
#include <wlan_mlo_mgr_cmn.h>
|
|
|
#include "wlan_mlme_ucfg_api.h"
|
|
|
#include "wifi_pos_ucfg_i.h"
|
|
|
+#include "wlan_mlo_mgr_sta.h"
|
|
|
|
|
|
#define NUM_OF_SOUNDING_DIMENSIONS 1 /*Nss - 1, (Nss = 2 for 2x2)*/
|
|
|
|
|
@@ -1768,6 +1769,148 @@ static void mlme_init_sta_mlo_cfg(struct wlan_objmgr_psoc *psoc,
|
|
|
sta->mlo_max_simultaneous_links =
|
|
|
cfg_default(CFG_MLO_MAX_SIMULTANEOUS_LINKS);
|
|
|
}
|
|
|
+
|
|
|
+static bool
|
|
|
+wlan_get_vdev_link_removed_flag(struct wlan_objmgr_vdev *vdev)
|
|
|
+{
|
|
|
+ struct mlme_legacy_priv *mlme_priv;
|
|
|
+ bool is_mlo_link_removed;
|
|
|
+
|
|
|
+ if (!mlo_is_mld_sta(vdev))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ wlan_vdev_obj_lock(vdev);
|
|
|
+ mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
|
|
|
+ if (!mlme_priv) {
|
|
|
+ wlan_vdev_obj_unlock(vdev);
|
|
|
+ mlme_legacy_err("vdev legacy private object is NULL");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ is_mlo_link_removed = mlme_priv->is_mlo_sta_link_removed;
|
|
|
+ wlan_vdev_obj_unlock(vdev);
|
|
|
+
|
|
|
+ return is_mlo_link_removed;
|
|
|
+}
|
|
|
+
|
|
|
+bool wlan_get_vdev_link_removed_flag_by_vdev_id(struct wlan_objmgr_psoc *psoc,
|
|
|
+ uint8_t vdev_id)
|
|
|
+{
|
|
|
+ struct wlan_objmgr_vdev *vdev;
|
|
|
+ bool is_mlo_link_removed;
|
|
|
+
|
|
|
+ vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
|
|
|
+ WLAN_MLME_OBJMGR_ID);
|
|
|
+ if (!vdev) {
|
|
|
+ mlme_legacy_err("get vdev failed for id %d", vdev_id);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ is_mlo_link_removed = wlan_get_vdev_link_removed_flag(vdev);
|
|
|
+ wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
|
|
|
+
|
|
|
+ return is_mlo_link_removed;
|
|
|
+}
|
|
|
+
|
|
|
+static QDF_STATUS
|
|
|
+wlan_set_vdev_link_removed_flag(struct wlan_objmgr_vdev *vdev, bool removed)
|
|
|
+{
|
|
|
+ struct mlme_legacy_priv *mlme_priv;
|
|
|
+
|
|
|
+ if (!vdev) {
|
|
|
+ mlme_legacy_err("vdev NULL");
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!mlo_is_mld_sta(vdev)) {
|
|
|
+ mlme_legacy_debug("vdev not mld sta");
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ wlan_vdev_obj_lock(vdev);
|
|
|
+ mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
|
|
|
+ if (!mlme_priv) {
|
|
|
+ wlan_vdev_obj_unlock(vdev);
|
|
|
+ mlme_legacy_err("vdev legacy private object is NULL");
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (removed == mlme_priv->is_mlo_sta_link_removed) {
|
|
|
+ wlan_vdev_obj_unlock(vdev);
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+ }
|
|
|
+
|
|
|
+ mlme_legacy_debug("mlo sta vdev %d link removed flag %d",
|
|
|
+ wlan_vdev_get_id(vdev), removed);
|
|
|
+ mlme_priv->is_mlo_sta_link_removed = removed;
|
|
|
+ wlan_vdev_obj_unlock(vdev);
|
|
|
+
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+QDF_STATUS
|
|
|
+wlan_set_vdev_link_removed_flag_by_vdev_id(struct wlan_objmgr_psoc *psoc,
|
|
|
+ uint8_t vdev_id, bool removed)
|
|
|
+{
|
|
|
+ struct wlan_objmgr_vdev *vdev;
|
|
|
+ QDF_STATUS status;
|
|
|
+
|
|
|
+ vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
|
|
|
+ WLAN_MLME_OBJMGR_ID);
|
|
|
+ if (!vdev) {
|
|
|
+ mlme_legacy_err("vdev null for id %d", vdev_id);
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!mlo_is_mld_sta(vdev)) {
|
|
|
+ mlme_legacy_debug("vdev %d not mld sta", vdev_id);
|
|
|
+ wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ status = wlan_set_vdev_link_removed_flag(vdev, removed);
|
|
|
+
|
|
|
+ wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+void wlan_clear_mlo_sta_link_removed_flag(struct wlan_objmgr_vdev *vdev)
|
|
|
+{
|
|
|
+ struct wlan_objmgr_vdev *wlan_vdev_list[WLAN_UMAC_MLO_MAX_VDEVS] = {0};
|
|
|
+ uint16_t vdev_count = 0;
|
|
|
+ uint8_t i;
|
|
|
+
|
|
|
+ if (!vdev || !mlo_is_mld_sta(vdev))
|
|
|
+ return;
|
|
|
+
|
|
|
+ mlo_get_ml_vdev_list(vdev, &vdev_count, wlan_vdev_list);
|
|
|
+ if (!vdev_count) {
|
|
|
+ mlme_legacy_err("vdev num 0 in mld dev");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (i = 0; i < vdev_count; i++) {
|
|
|
+ if (!wlan_vdev_list[i]) {
|
|
|
+ mlme_legacy_err("vdev is null in mld");
|
|
|
+ goto release_ref;
|
|
|
+ }
|
|
|
+
|
|
|
+ wlan_set_vdev_link_removed_flag(wlan_vdev_list[i], false);
|
|
|
+ }
|
|
|
+
|
|
|
+release_ref:
|
|
|
+ for (i = 0; i < vdev_count; i++)
|
|
|
+ mlo_release_vdev_ref(wlan_vdev_list[i]);
|
|
|
+}
|
|
|
+
|
|
|
+bool wlan_drop_mgmt_frame_on_link_removal(struct wlan_objmgr_vdev *vdev)
|
|
|
+{
|
|
|
+ if (!vdev || !mlo_is_mld_sta(vdev))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ return wlan_get_vdev_link_removed_flag(vdev);
|
|
|
+}
|
|
|
#else
|
|
|
static void mlme_init_sta_mlo_cfg(struct wlan_objmgr_psoc *psoc,
|
|
|
struct wlan_mlme_sta_cfg *sta)
|