Forráskód Böngészése

qcacld-3.0: Get disconnect IEs and cache in vdev mgr object

Application sends disconnect IEs to driver through vendor command
SET_WIFI_CONFIGURATION by embeding in the attribute
QCA_WLAN_VENDOR_ATTR_DISCONNECT_IES. Extract the same and validate
to make sure it's not more than maximum IE length that can be
accomodated in deauth/disassoc frame. Cache the extracted IEs
in mlme vdev object.

Change-Id: I6c95aa1d4d8ef7d8ed3ad5be8832ef1f45c26a2f
CRs-Fixed: 2481908
Srinivas Dasari 6 éve
szülő
commit
19165744ea

+ 30 - 0
mlme/core/inc/wlan_mlme_main.h

@@ -43,6 +43,16 @@ struct wlan_mlme_psoc_obj {
 	struct wlan_mlme_cfg cfg;
 };
 
+/**
+ * struct wlan_ies - Generic WLAN Information Element(s) format
+ * @len: Total length of the IEs
+ * @data: IE data
+ */
+struct wlan_ies {
+	uint16_t len;
+	uint8_t *data;
+};
+
 /**
  * struct peer_mlme_priv_obj - peer MLME component object
  * @ucast_key_cipher: unicast crypto type.
@@ -76,6 +86,8 @@ enum vdev_assoc_type {
  * @ini_cfg: Max configuration of nss, chains supported for vdev.
  * @sta_dynamic_oce_value: Dyanmic oce flags value for sta
  * @roam_invoke_params: Roam invoke params
+ * @self_disconnect_ies: Disconnect IEs to be sent in deauth/disassoc frames
+ *			 originated from driver
  */
 struct mlme_legacy_priv {
 	bool chan_switch_in_progress;
@@ -88,6 +100,7 @@ struct mlme_legacy_priv {
 	struct wlan_mlme_nss_chains ini_cfg;
 	uint8_t sta_dynamic_oce_value;
 	struct mlme_roam_after_data_stall roam_invoke_params;
+	struct wlan_ies self_disconnect_ies;
 };
 
 #ifndef CRYPTO_SET_KEY_CONVERGED
@@ -270,4 +283,21 @@ struct wlan_mlme_psoc_obj *mlme_get_psoc_obj_fl(struct wlan_objmgr_psoc *psoc,
 QDF_STATUS mlme_init_ibss_cfg(struct wlan_objmgr_psoc *psoc,
 			      struct wlan_mlme_ibss_cfg *ibss_cfg);
 
+/**
+ * mlme_set_self_disconnect_ies() - Set diconnect IEs configured from userspace
+ * @vdev: vdev pointer
+ * @ie: pointer for disconnect IEs
+ *
+ * Return: None
+ */
+void mlme_set_self_disconnect_ies(struct wlan_objmgr_vdev *vdev,
+				  struct wlan_ies *ie);
+
+/**
+ * mlme_free_self_disconnect_ies() - Free the self diconnect IEs
+ * @vdev: vdev pointer
+ *
+ * Return: None
+ */
+void mlme_free_self_disconnect_ies(struct wlan_objmgr_vdev *vdev);
 #endif

+ 57 - 0
mlme/core/src/wlan_mlme_main.c

@@ -2362,3 +2362,60 @@ QDF_STATUS mlme_cfg_on_psoc_enable(struct wlan_objmgr_psoc *psoc)
 
 	return status;
 }
+
+void mlme_set_self_disconnect_ies(struct wlan_objmgr_vdev *vdev,
+				  struct wlan_ies *ie)
+{
+	struct vdev_mlme_obj *vdev_mlme;
+	struct mlme_legacy_priv *mlme_priv;
+
+	if (!ie || !ie->len || !ie->data) {
+		mlme_legacy_debug("disocnnect IEs are NULL");
+		return;
+	}
+
+	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
+	if (!vdev_mlme) {
+		mlme_legacy_err("vdev component object is NULL");
+		return;
+	}
+
+	mlme_priv = vdev_mlme->ext_vdev_ptr;
+
+	if (mlme_priv->self_disconnect_ies.data) {
+		qdf_mem_free(mlme_priv->self_disconnect_ies.data);
+		mlme_priv->self_disconnect_ies.len = 0;
+	}
+
+	mlme_priv->self_disconnect_ies.data = qdf_mem_malloc(ie->len);
+	if (!mlme_priv->self_disconnect_ies.data)
+		return;
+
+	qdf_mem_copy(mlme_priv->self_disconnect_ies.data, ie->data, ie->len);
+	mlme_priv->self_disconnect_ies.len = ie->len;
+
+	mlme_legacy_debug("Self disconnect IEs");
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_MLME, QDF_TRACE_LEVEL_DEBUG,
+			   mlme_priv->self_disconnect_ies.data,
+			   mlme_priv->self_disconnect_ies.len);
+}
+
+void mlme_free_self_disconnect_ies(struct wlan_objmgr_vdev *vdev)
+{
+	struct vdev_mlme_obj *vdev_mlme;
+	struct mlme_legacy_priv *mlme_priv;
+
+	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
+	if (!vdev_mlme) {
+		mlme_legacy_err("vdev component object is NULL");
+		return;
+	}
+
+	mlme_priv = vdev_mlme->ext_vdev_ptr;
+
+	if (mlme_priv->self_disconnect_ies.data) {
+		qdf_mem_free(mlme_priv->self_disconnect_ies.data);
+		mlme_priv->self_disconnect_ies.data = NULL;
+		mlme_priv->self_disconnect_ies.len = 0;
+	}
+}

+ 5 - 0
mlme/core/src/wlan_mlme_vdev_mgr_interface.c

@@ -823,6 +823,11 @@ QDF_STATUS vdevmgr_mlme_ext_hdl_destroy(struct vdev_mlme_obj *vdev_mlme)
 {
 	mlme_legacy_debug("vdev id = %d ",
 			  vdev_mlme->vdev->vdev_objmgr.vdev_id);
+
+	if (!vdev_mlme->ext_vdev_ptr)
+		return QDF_STATUS_E_FAILURE;
+
+	mlme_free_self_disconnect_ies(vdev_mlme->vdev);
 	qdf_mem_free(vdev_mlme->ext_vdev_ptr);
 	vdev_mlme->ext_vdev_ptr = NULL;