Browse Source

qcacld-3.0: Add mlme APIs and strutures to maintain roam sm

Add mlme APIs and structures to set and get roam
state, supplicant roam disabled flag and rso control
bitmap.

Change-Id: Ic97da49035462afffd9c86c1d9f9af08515e6747
CRs-Fixed: 2520824
Yeshwanth Sriram Guntuka 5 năm trước cách đây
mục cha
commit
ea2fb37ebc

+ 152 - 0
components/mlme/core/inc/wlan_mlme_main.h

@@ -75,6 +75,41 @@ enum vdev_assoc_type {
 	VDEV_FT_REASSOC
 };
 
+/**
+ * wlan_mlme_roam_state_info - Structure containing roaming
+ * state related details
+ * @state: Roaming module state.
+ * @mlme_operations_bitmap: Bitmap containing what mlme operations are in
+ *  progress where roaming should not be allowed.
+ */
+struct wlan_mlme_roam_state_info {
+	enum roam_offload_state state;
+	uint8_t mlme_operations_bitmap;
+};
+
+/**
+ * struct wlan_mlme_roaming_config - Roaming configurations structure
+ * @roam_trigger_bitmap: Master bitmap of roaming triggers. If the bitmap is
+ *  zero, roaming module will be deinitialized at firmware for this vdev.
+ * @supplicant_disabled_roaming: Enable/disable roam scan in firmware; will be
+ *  used by supplicant to do roam invoke after disabling roam scan in firmware
+ */
+struct wlan_mlme_roaming_config {
+	uint32_t roam_trigger_bitmap;
+	bool supplicant_disabled_roaming;
+};
+
+/**
+ * struct wlan_mlme_roam - Roam structure containing roam state and
+ *  roam config info
+ * @roam_sm: Structure containing roaming state related details
+ * @roam_config: Roaming configurations structure
+ */
+struct wlan_mlme_roam {
+	struct wlan_mlme_roam_state_info roam_sm;
+	struct wlan_mlme_roaming_config roam_cfg;
+};
+
 /**
  * struct mlme_legacy_priv - VDEV MLME legacy priv object
  * @chan_switch_in_progress: flag to indicate that channel switch is in progress
@@ -94,6 +129,7 @@ enum vdev_assoc_type {
  *			 from peer
  * @vdev_stop_type: vdev stop type request
  * @bss_params: Bss params to be used in add bss resp handler
+ * @roam_off_state: Roam offload state
  */
 struct mlme_legacy_priv {
 	bool chan_switch_in_progress;
@@ -110,6 +146,7 @@ struct mlme_legacy_priv {
 	struct wlan_ies peer_disconnect_ies;
 	uint32_t vdev_stop_type;
 	struct bss_params *bss_params;
+	struct wlan_mlme_roam mlme_roam;
 };
 
 #ifndef CRYPTO_SET_KEY_CONVERGED
@@ -362,4 +399,119 @@ void mlme_set_peer_pmf_status(struct wlan_objmgr_peer *peer,
  * Return: Value of is_pmf_enabled; True if PMF is enabled by peer
  */
 bool mlme_get_peer_pmf_status(struct wlan_objmgr_peer *peer);
+
+#if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
+/**
+ * mlme_get_supplicant_disabled_roaming() - Get supplicant disabled roaming
+ *  value for a given vdev.
+ * @psoc: PSOC pointer
+ * @vdev_id: Vdev for which the supplicant disabled roaming value is being
+ *  requested
+ *
+ * Return: True if supplicant disabled roaming else false
+ */
+bool
+mlme_get_supplicant_disabled_roaming(struct wlan_objmgr_psoc *psoc,
+				     uint8_t vdev_id);
+
+/**
+ * mlme_set_supplicant_disabled_roaming - Set the supplicant disabled
+ *  roaming flag.
+ * @psoc: PSOC pointer
+ * @vdev_id: Vdev for which the supplicant disabled roaming needs to
+ *  be set
+ * @val: value true is to disable RSO and false to enable RSO
+ *
+ * Return: None
+ */
+void mlme_set_supplicant_disabled_roaming(struct wlan_objmgr_psoc *psoc,
+					  uint8_t vdev_id, bool val);
+
+/**
+ * mlme_get_roam_trigger_bitmap() - Get roaming trigger bitmap value for a given
+ *  vdev.
+ * @psoc: PSOC pointer
+ * @vdev_id: Vdev for which the roam trigger bitmap is being requested
+ *
+ * Return: roaming trigger bitmap
+ */
+uint32_t
+mlme_get_roam_trigger_bitmap(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id);
+
+/**
+ * mlme_set_roam_trigger_bitmap() - Set the roaming trigger bitmap value for
+ *  the given vdev. If the bitmap is zero then roaming is completely disabled
+ *  on the vdev which means roam structure in firmware is not allocated and no
+ *  RSO start/stop commands can be sent
+ * @psoc: PSOC pointer
+ * @vdev_id: Vdev for which the roam trigger bitmap is to be set
+ * @val: bitmap value to set
+ *
+ * Return: None
+ */
+void mlme_set_roam_trigger_bitmap(struct wlan_objmgr_psoc *psoc,
+				  uint8_t vdev_id, uint32_t val);
+
+/**
+ * mlme_get_roam_state() - Get roam state from vdev object
+ * @psoc: psoc pointer
+ * @vdev_id: vdev id
+ *
+ * Return: Returns roam offload state
+ */
+enum roam_offload_state
+mlme_get_roam_state(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id);
+
+/**
+ * mlme_set_roam_state() - Set roam state in vdev object
+ * @psoc: psoc pointer
+ * @vdev_id: vdev id
+ * @val: roam offload state
+ *
+ * Return: None
+ */
+void mlme_set_roam_state(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
+			 enum roam_offload_state val);
+
+/**
+ * mlme_get_operations_bitmap() - Get the mlme operations bitmap which
+ *  contains the bitmap of mlme operations which have disabled roaming
+ *  temporarily
+ * @psoc: PSOC pointer
+ * @vdev_id: vdev for which the mlme operation bitmap is requested
+ *
+ * Return: bitmap value
+ */
+uint8_t
+mlme_get_operations_bitmap(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id);
+
+/**
+ * mlme_set_operations_bitmap() - Set the mlme operations bitmap which
+ *  indicates what mlme operations are in progress
+ * @psoc: PSOC pointer
+ * @vdev_id: vdev for which the mlme operation bitmap is requested
+ * @reqs: RSO stop requestor
+ * @clear: clear bit if true else set bit
+ *
+ * Return: bitmap value
+ */
+void
+mlme_set_operations_bitmap(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
+			   enum roam_control_requestor reqs, bool clear);
+
+#define MLME_IS_ROAM_STATE_RSO_STARTED(psoc, vdev_id) \
+	(mlme_get_roam_state(psoc, vdev_id) == ROAM_RSO_STARTED)
+
+#define MLME_IS_ROAM_STATE_DEINIT(psoc, vdev_id) \
+	(mlme_get_roam_state(psoc, vdev_id) == ROAM_DEINIT)
+
+#define MLME_IS_ROAM_STATE_INIT(psoc, vdev_id) \
+	(mlme_get_roam_state(psoc, vdev_id) == ROAM_INIT)
+
+#define MLME_IS_ROAM_STATE_STOPPED(psoc, vdev_id) \
+	(mlme_get_roam_state(psoc, vdev_id) == ROAM_RSO_STOPPED)
+
+#define MLME_IS_ROAM_INITIALIZED(psoc, vdev_id) \
+	(mlme_get_roam_state(psoc, vdev_id) >= ROAM_INIT)
+#endif
 #endif

+ 247 - 0
components/mlme/core/src/wlan_mlme_main.c

@@ -2509,3 +2509,250 @@ bool mlme_get_peer_pmf_status(struct wlan_objmgr_peer *peer)
 
 	return peer_priv->is_pmf_enabled;
 }
+
+#if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
+static
+const char *mlme_roam_state_to_string(enum roam_offload_state state)
+{
+	switch (state) {
+	case ROAM_INIT:
+		return "ROAM_INIT";
+	case ROAM_DEINIT:
+		return "ROAM_DEINIT";
+	case ROAM_RSO_STARTED:
+		return "ROAM_RSO_STARTED";
+	case ROAM_RSO_STOPPED:
+		return "ROAM_RSO_STOPPED";
+	default:
+		return "";
+	}
+}
+
+static void
+mlme_print_roaming_state(uint8_t vdev_id, enum roam_offload_state cur_state,
+			 enum roam_offload_state new_state)
+{
+	mlme_info("ROAM: vdev[%d] ROAM State Changed from [%s] to [%s]",
+		  vdev_id, mlme_roam_state_to_string(cur_state),
+		  mlme_roam_state_to_string(new_state));
+
+	/* TODO: Try to print the state change requestor also */
+}
+
+bool
+mlme_get_supplicant_disabled_roaming(struct wlan_objmgr_psoc *psoc,
+				     uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct mlme_legacy_priv *mlme_priv;
+	bool value;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_MLME_OBJMGR_ID);
+
+	if (!vdev) {
+		mlme_legacy_err("vdev object is NULL");
+		return 0;
+	}
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv) {
+		mlme_legacy_err("vdev legacy private object is NULL");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+		return 0;
+	}
+
+	value = mlme_priv->mlme_roam.roam_cfg.supplicant_disabled_roaming;
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+
+	return value;
+}
+
+void mlme_set_supplicant_disabled_roaming(struct wlan_objmgr_psoc *psoc,
+					  uint8_t vdev_id, bool val)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct mlme_legacy_priv *mlme_priv;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_MLME_OBJMGR_ID);
+
+	if (!vdev) {
+		mlme_legacy_err("vdev object is NULL");
+		return;
+	}
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv) {
+		mlme_legacy_err("vdev legacy private object is NULL");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+		return;
+	}
+
+	mlme_priv->mlme_roam.roam_cfg.supplicant_disabled_roaming = val;
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+}
+
+uint32_t
+mlme_get_roam_trigger_bitmap(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct mlme_legacy_priv *mlme_priv;
+	uint32_t roam_bitmap;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_MLME_OBJMGR_ID);
+
+	if (!vdev) {
+		mlme_legacy_err("vdev object is NULL");
+		return 0;
+	}
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv) {
+		mlme_legacy_err("vdev legacy private object is NULL");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+		return 0;
+	}
+
+	roam_bitmap = mlme_priv->mlme_roam.roam_cfg.roam_trigger_bitmap;
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+
+	return roam_bitmap;
+}
+
+void mlme_set_roam_trigger_bitmap(struct wlan_objmgr_psoc *psoc,
+				  uint8_t vdev_id, uint32_t val)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct mlme_legacy_priv *mlme_priv;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_MLME_OBJMGR_ID);
+	if (!vdev) {
+		mlme_legacy_err("vdev object is NULL");
+		return;
+	}
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv) {
+		mlme_legacy_err("vdev legacy private object is NULL");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+		return;
+	}
+
+	mlme_priv->mlme_roam.roam_cfg.roam_trigger_bitmap = val;
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+}
+
+uint8_t
+mlme_get_operations_bitmap(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct mlme_legacy_priv *mlme_priv;
+	uint8_t bitmap;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_MLME_OBJMGR_ID);
+
+	if (!vdev) {
+		mlme_legacy_err("vdev object is NULL");
+		return 0xFF;
+	}
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv) {
+		mlme_legacy_err("vdev legacy private object is NULL");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+		return 0xFF;
+	}
+
+	bitmap = mlme_priv->mlme_roam.roam_sm.mlme_operations_bitmap;
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+
+	return bitmap;
+}
+
+void
+mlme_set_operations_bitmap(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
+			   enum roam_control_requestor reqs, bool clear)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct mlme_legacy_priv *mlme_priv;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_MLME_OBJMGR_ID);
+	if (!vdev) {
+		mlme_legacy_err("vdev object is NULL");
+		return;
+	}
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv) {
+		mlme_legacy_err("vdev legacy private object is NULL");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+		return;
+	}
+
+	if (clear)
+		mlme_priv->mlme_roam.roam_sm.mlme_operations_bitmap &= ~reqs;
+	else
+		mlme_priv->mlme_roam.roam_sm.mlme_operations_bitmap |= reqs;
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+}
+
+enum roam_offload_state
+mlme_get_roam_state(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct mlme_legacy_priv *mlme_priv;
+	enum roam_offload_state roam_state;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_MLME_OBJMGR_ID);
+
+	if (!vdev) {
+		mlme_legacy_err("vdev object is NULL");
+		return ROAM_DEINIT;
+	}
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv) {
+		mlme_legacy_err("vdev legacy private object is NULL");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+		return ROAM_DEINIT;
+	}
+
+	roam_state = mlme_priv->mlme_roam.roam_sm.state;
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+
+	return roam_state;
+}
+
+void mlme_set_roam_state(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
+			 enum roam_offload_state new_state)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct mlme_legacy_priv *mlme_priv;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_MLME_OBJMGR_ID);
+
+	if (!vdev) {
+		mlme_legacy_err("vdev object is NULL");
+		return;
+	}
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv) {
+		mlme_legacy_err("vdev legacy private object is NULL");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+		return;
+	}
+
+	mlme_print_roaming_state(vdev_id, mlme_priv->mlme_roam.roam_sm.state,
+				 new_state);
+	mlme_priv->mlme_roam.roam_sm.state = new_state;
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+}
+#endif

+ 38 - 0
components/mlme/dispatcher/inc/wlan_mlme_public_struct.h

@@ -60,6 +60,8 @@
 #define MAX_VENDOR_IES_LEN 1532
 
 #define CFG_VALID_CHANNEL_LIST_STRING_LEN (CFG_VALID_CHANNEL_LIST_LEN * 4)
+
+#define DEFAULT_ROAM_TRIGGER_BITMAP 0xFFFFFFFF
 /**
  * struct mlme_cfg_str - generic structure for all mlme CFG string items
  *
@@ -259,6 +261,42 @@ enum mlme_ts_info_ack_policy {
 	TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK = 1,
 };
 
+#if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
+/**
+ * enum roam_control_requestor - Driver disabled roaming requestor that will
+ *  request the roam module to disable roaming based on the mlme operation
+ * @RSO_INVALID_REQUESTOR: invalid requestor
+ * @RSO_START_BSS: disable roaming temporarily due to start bss
+ * @RSO_CHANNEL_SWITCH: disable roaming due to STA channel switch
+ * @RSO_CONNECT_START: disable roaming temporarily due to connect
+ * @RSO_SAP_CHANNEL_CHANGE: disable roaming due to SAP channel change
+ */
+enum roam_control_requestor {
+	RSO_INVALID_REQUESTOR,
+	RSO_START_BSS          = BIT(0),
+	RSO_CHANNEL_SWITCH     = BIT(1),
+	RSO_CONNECT_START      = BIT(2),
+	RSO_SAP_CHANNEL_CHANGE = BIT(3),
+};
+
+/**
+ * enum roam_offload_state - Roaming module state for each STA vdev.
+ * @ROAM_DEINIT: Roaming module is not initialized at the
+ *  firmware.
+ * @ROAM_INIT: Roaming module initialized at the firmware.
+ * @ROAM_RSO_STARTED: RSO started, firmware can roam to different AP.
+ * @ROAM_RSO_STOPPED: RSO stopped - roaming module is initialized at firmware,
+ *  but firmware cannot do roaming due to supplicant disabled roaming/driver
+ * disabled roaming.
+ */
+enum roam_offload_state {
+	ROAM_DEINIT,
+	ROAM_INIT,
+	ROAM_RSO_STARTED,
+	ROAM_RSO_STOPPED
+};
+#endif
+
 /**
  * struct mlme_edca_params - EDCA pramaters related config items
  *