Ver Fonte

qcacld-3.0: Send disconnect IEs received in deauth/disassoc to kernel

AP may send IEs in deauth/disassoc frames as part of disconnection.
Extract the same and forward to kernel through
cfg80211_disconnected().

Change-Id: I4ef339dcd1ecff64d6bed1de35621ecce5d8030a
CRs-Fixed: 2481912
Srinivas Dasari há 6 anos atrás
pai
commit
f70a2c4e2f

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

@@ -88,6 +88,8 @@ enum vdev_assoc_type {
  * @roam_invoke_params: Roam invoke params
  * @self_disconnect_ies: Disconnect IEs to be sent in deauth/disassoc frames
  *			 originated from driver
+ * @peer_disconnect_ies: Disconnect IEs received in deauth/disassoc frames
+ *			 from peer
  */
 struct mlme_legacy_priv {
 	bool chan_switch_in_progress;
@@ -101,6 +103,7 @@ struct mlme_legacy_priv {
 	uint8_t sta_dynamic_oce_value;
 	struct mlme_roam_after_data_stall roam_invoke_params;
 	struct wlan_ies self_disconnect_ies;
+	struct wlan_ies peer_disconnect_ies;
 };
 
 #ifndef CRYPTO_SET_KEY_CONVERGED
@@ -308,4 +311,30 @@ void mlme_free_self_disconnect_ies(struct wlan_objmgr_vdev *vdev);
  * Return: Returns a pointer to the self disconnect IEs present in vdev object
  */
 struct wlan_ies *mlme_get_self_disconnect_ies(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * mlme_set_peer_disconnect_ies() - Cache disconnect IEs received from peer
+ * @vdev: vdev pointer
+ * @ie: pointer for disconnect IEs
+ *
+ * Return: None
+ */
+void mlme_set_peer_disconnect_ies(struct wlan_objmgr_vdev *vdev,
+				  struct wlan_ies *ie);
+
+/**
+ * mlme_free_peer_disconnect_ies() - Free the peer diconnect IEs
+ * @vdev: vdev pointer
+ *
+ * Return: None
+ */
+void mlme_free_peer_disconnect_ies(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * mlme_get_peer_disconnect_ies() - Get diconnect IEs from vdev object
+ * @vdev: vdev pointer
+ *
+ * Return: Returns a pointer to the peer disconnect IEs present in vdev object
+ */
+struct wlan_ies *mlme_get_peer_disconnect_ies(struct wlan_objmgr_vdev *vdev);
 #endif

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

@@ -2435,3 +2435,76 @@ struct wlan_ies *mlme_get_self_disconnect_ies(struct wlan_objmgr_vdev *vdev)
 
 	return &mlme_priv->self_disconnect_ies;
 }
+
+void mlme_set_peer_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->peer_disconnect_ies.data) {
+		qdf_mem_free(mlme_priv->peer_disconnect_ies.data);
+		mlme_priv->peer_disconnect_ies.len = 0;
+	}
+
+	mlme_priv->peer_disconnect_ies.data = qdf_mem_malloc(ie->len);
+	if (!mlme_priv->peer_disconnect_ies.data)
+		return;
+
+	qdf_mem_copy(mlme_priv->peer_disconnect_ies.data, ie->data, ie->len);
+	mlme_priv->peer_disconnect_ies.len = ie->len;
+
+	mlme_legacy_debug("peer disconnect IEs");
+	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_MLME, QDF_TRACE_LEVEL_DEBUG,
+			   mlme_priv->peer_disconnect_ies.data,
+			   mlme_priv->peer_disconnect_ies.len);
+}
+
+void mlme_free_peer_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->peer_disconnect_ies.data) {
+		qdf_mem_free(mlme_priv->peer_disconnect_ies.data);
+		mlme_priv->peer_disconnect_ies.data = NULL;
+		mlme_priv->peer_disconnect_ies.len = 0;
+	}
+}
+
+struct wlan_ies *mlme_get_peer_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 NULL;
+	}
+
+	mlme_priv = vdev_mlme->ext_vdev_ptr;
+
+	return &mlme_priv->peer_disconnect_ies;
+}

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

@@ -828,6 +828,7 @@ QDF_STATUS vdevmgr_mlme_ext_hdl_destroy(struct vdev_mlme_obj *vdev_mlme)
 		return QDF_STATUS_E_FAILURE;
 
 	mlme_free_self_disconnect_ies(vdev_mlme->vdev);
+	mlme_free_peer_disconnect_ies(vdev_mlme->vdev);
 	qdf_mem_free(vdev_mlme->ext_vdev_ptr);
 	vdev_mlme->ext_vdev_ptr = NULL;