Эх сурвалжийг харах

qcacld-3.0: Update roam stats by event to user space

When roam happened in F/W and send roam stats to host driver,
host driver send these roam stats info to user space by event
without cache them.

Change-Id: I772c0a5035896715204f6eee277090ed1f33e97c
CRs-Fixed: 3790270
Chunquan Luo 1 жил өмнө
parent
commit
e2660a5ccb

+ 16 - 0
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h

@@ -1343,6 +1343,22 @@ QDF_STATUS
 wlan_cm_roam_stats_info_get(struct wlan_objmgr_vdev *vdev,
 			    struct enhance_roam_info **roam_info,
 			    uint32_t  *roam_num);
+
+/**
+ * wlan_cm_roam_info_get() - get vdev roam info
+ *
+ * @vdev: pointer to vdev
+ * @roam_info: pointer to buffer to copy roam stats info
+ * @idx: index of roam stats cache buffer
+ *
+ * Return: QDF_STATUS
+ */
+
+QDF_STATUS
+wlan_cm_roam_info_get(struct wlan_objmgr_vdev *vdev,
+		      struct enhance_roam_info **roam_info,
+		      uint8_t idx);
+
 #else
 static inline
 void mlme_cm_alloc_roam_stats_info(struct vdev_mlme_obj *vdev_mlme)

+ 5 - 0
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h

@@ -1069,6 +1069,7 @@ enum roam_scan_dwell_type {
 /**
  * enum eroam_frame_subtype - Enhanced roam frame subtypes.
  *
+ * @WLAN_ROAM_STATS_FRAME_SUBTYPE_INVALID: Invalid subtype
  * @WLAN_ROAM_STATS_FRAME_SUBTYPE_AUTH_RESP: Authentication resp frame
  * @WLAN_ROAM_STATS_FRAME_SUBTYPE_REASSOC_RESP: Reassociation resp frame
  * @WLAN_ROAM_STATS_FRAME_SUBTYPE_EAPOL_M1: EAPOL-Key M1 frame
@@ -1081,6 +1082,7 @@ enum roam_scan_dwell_type {
  * @WLAN_ROAM_STATS_FRAME_SUBTYPE_REASSOC_REQ: Reassociation req frame
  */
 enum eroam_frame_subtype {
+	WLAN_ROAM_STATS_FRAME_SUBTYPE_INVALID = 0,
 	WLAN_ROAM_STATS_FRAME_SUBTYPE_AUTH_RESP = 1,
 	WLAN_ROAM_STATS_FRAME_SUBTYPE_REASSOC_RESP = 2,
 	WLAN_ROAM_STATS_FRAME_SUBTYPE_EAPOL_M1 = 3,
@@ -2553,6 +2555,8 @@ struct roam_frame_stats {
  * @vdev_id: vdev id
  * @num_tlv: Number of roam scans triggered
  * @num_roam_msg_info: Number of roam_msg_info present in event
+ * @enhance_roam_rt_event:  flag of whether we need send event for
+ *  real time enhance roam stats info to user space
  * @trigger: Roam trigger related details
  * @scan: Roam scan event details
  * @result: Roam result related info
@@ -2567,6 +2571,7 @@ struct roam_stats_event {
 	uint8_t vdev_id;
 	uint8_t num_tlv;
 	uint8_t num_roam_msg_info;
+	bool enhance_roam_rt_event;
 	struct wmi_roam_trigger_info trigger[MAX_ROAM_SCAN_STATS_TLV];
 	struct wmi_roam_scan_data scan[MAX_ROAM_SCAN_STATS_TLV];
 	struct wmi_roam_result result[MAX_ROAM_SCAN_STATS_TLV];

+ 18 - 0
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_ucfg_api.h

@@ -777,6 +777,24 @@ ucfg_cm_roam_stats_info_put(struct enhance_roam_info *roam_info)
 {
 	qdf_mem_free(roam_info);
 }
+
+/**
+ * ucfg_cm_roam_info_get() - get vdev roam info
+ *
+ * @vdev: pointer to vdev
+ * @roam_info: pointer to buffer to copy roam stats info
+ * @idx: index of roam stats cache buffer
+ *
+ * Return: QDF_STATUS
+ */
+static inline QDF_STATUS
+ucfg_cm_roam_info_get(struct wlan_objmgr_vdev *vdev,
+		      struct enhance_roam_info **roam_info,
+		      uint8_t idx)
+{
+	return wlan_cm_roam_info_get(vdev, roam_info, idx);
+}
+
 #else
 static inline QDF_STATUS
 ucfg_cm_roam_stats_info_get(struct wlan_objmgr_vdev *vdev,

+ 28 - 1
components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c

@@ -4185,7 +4185,7 @@ wlan_cm_update_roam_frame_info(struct mlme_legacy_priv *mlme_priv,
 	for (i = 0; i < frame_data->num_frame; i++) {
 		if (!wlan_cm_get_valid_frame_type(&frame_data->frame_info[i]))
 			continue;
-		j++;
+
 		if (j >= WLAN_ROAM_MAX_FRAME_INFO)
 			break;
 		/*
@@ -4210,6 +4210,7 @@ wlan_cm_update_roam_frame_info(struct mlme_legacy_priv *mlme_priv,
 			   info->timestamp[j].timestamp,
 			   info->timestamp[j].status,
 			   QDF_MAC_ADDR_REF(info->timestamp[j].bssid.bytes));
+		j++;
 	}
 }
 
@@ -4337,6 +4338,10 @@ wlan_cm_update_roam_stats_info(struct wlan_objmgr_psoc *psoc,
 			wlan_cm_update_roam_bssid(mlme_priv,
 						  &stats_info->scan[index]);
 
+		stats_info->enhance_roam_rt_event = true;
+		mlme_cm_osif_roam_rt_stats(stats_info,
+					   mlme_priv->roam_write_index);
+
 		mlme_priv->roam_write_index += 1;
 		if (mlme_priv->roam_write_index == mlme_priv->roam_cache_num)
 			mlme_priv->roam_write_index = 0;
@@ -4423,6 +4428,28 @@ wlan_cm_roam_stats_info_get(struct wlan_objmgr_vdev *vdev,
 
 	return QDF_STATUS_SUCCESS;
 }
+
+QDF_STATUS
+wlan_cm_roam_info_get(struct wlan_objmgr_vdev *vdev,
+		      struct enhance_roam_info **roam_info,
+		      uint8_t idx)
+{
+	struct mlme_legacy_priv *mlme_priv;
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv) {
+		mlme_err("vdev legacy private object is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (mlme_priv->roam_cache_num == 0) {
+		mlme_debug("Enhanced roam stats not supported");
+		return QDF_STATUS_E_NOSUPPORT;
+	}
+	*roam_info = &mlme_priv->roam_info[idx];
+	return QDF_STATUS_SUCCESS;
+}
+
 #else
 static void
 wlan_cm_update_roam_stats_info(struct wlan_objmgr_psoc *psoc,

+ 108 - 22
core/hdd/src/wlan_hdd_stats.c

@@ -5576,34 +5576,20 @@ roam_rt_stats_fill_cand_info(struct sk_buff *vendor_event, uint8_t idx,
 	nla_nest_end(vendor_event, nl_array);
 }
 
-void
-wlan_hdd_cfg80211_roam_events_callback(struct roam_stats_event *roam_stats,
-				       uint8_t idx)
+static void
+wlan_hdd_cfg80211_typical_roam_events_callback(struct wlan_hdd_link_info *link_info,
+					       struct roam_stats_event *roam_stats,
+					       uint8_t idx)
 {
-	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
-	int status;
 	uint32_t data_size, roam_event_type = 0;
 	struct sk_buff *vendor_event;
-	struct wlan_hdd_link_info *link_info;
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
 
-	status = wlan_hdd_validate_context(hdd_ctx);
-	if (status) {
+	if (wlan_hdd_validate_context(hdd_ctx)) {
 		hdd_err("Invalid hdd_ctx");
 		return;
 	}
 
-	if (!roam_stats) {
-		hdd_err("msg received here is null");
-		return;
-	}
-
-	link_info = hdd_get_link_info_by_vdev(hdd_ctx, roam_stats->vdev_id);
-	if (!link_info) {
-		hdd_err("vdev_id %d does not exist with host",
-			roam_stats->vdev_id);
-		return;
-	}
-
 	data_size = hdd_get_roam_rt_stats_event_len(roam_stats, idx);
 	if (!data_size) {
 		hdd_err("No data requested");
@@ -9639,6 +9625,8 @@ void wlan_hdd_register_cp_stats_cb(struct hdd_context *hdd_ctx)
 	QCA_WLAN_VENDOR_ATTR_ROAM_STATS_FRAME_STATUS
 #define ROAM_STATS_FRAME_TIMESTAMP \
 	QCA_WLAN_VENDOR_ATTR_ROAM_STATS_FRAME_TIMESTAMP
+#define ROAM_STATS_EVENT_INDEX \
+	QCA_NL80211_VENDOR_SUBCMD_ROAM_STATS_INDEX
 
 static enum qca_roam_reason
 hdd_convert_roam_trigger_reason(enum roam_trigger_reason reason)
@@ -9921,8 +9909,9 @@ hdd_convert_roam_failures_reason(enum wlan_roam_failure_reason_code fail)
  *
  * Return: required length of an individual record of roaming stats
  */
-static uint32_t hdd_get_roam_stats_individual_record_len(struct enhance_roam_info *roam_info,
-							 uint32_t index)
+static uint32_t
+hdd_get_roam_stats_individual_record_len(struct enhance_roam_info *roam_info,
+					 uint32_t index)
 {
 	struct enhance_roam_info *info;
 	enum qca_roam_reason vendor_trigger_reason;
@@ -10452,6 +10441,9 @@ static int hdd_nla_put_roam_stats_info(struct sk_buff *skb,
 	}
 
 	for (i = 0; i < WLAN_ROAM_MAX_FRAME_INFO; i++) {
+		if (info->timestamp[i].frame_type ==
+				WLAN_ROAM_STATS_FRAME_SUBTYPE_INVALID)
+			break;
 		roam_frame = nla_nest_start(skb, i);
 		if (!roam_frame) {
 			hdd_err("nla_nest_start fail");
@@ -10690,6 +10682,100 @@ int wlan_hdd_cfg80211_get_roam_stats(struct wiphy *wiphy,
 }
 #endif
 
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+#ifdef WLAN_FEATURE_ROAM_INFO_STATS
+static void
+wlan_hdd_cfg80211_enhance_roam_events_callback(struct wlan_hdd_link_info *link_info,
+					       struct roam_stats_event *roam_stats,
+					       uint8_t idx)
+{
+	int status;
+	uint32_t data_size = 0;
+	struct sk_buff *vendor_event;
+	struct wlan_objmgr_vdev *vdev = NULL;
+	struct enhance_roam_info *roam_info = NULL;
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (status) {
+		hdd_err("Invalid hdd_ctx");
+		return;
+	}
+
+	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_STATS_ID);
+	if (!vdev)
+		return;
+	ucfg_cm_roam_info_get(vdev, &roam_info, idx);
+	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_STATS_ID);
+
+	/* QCA_WLAN_VENDOR_ATTR_ROAM_STATS_INFO */
+	data_size += nla_total_size(0);
+	/* nest attribute */
+	data_size += nla_total_size(0);
+
+	data_size += hdd_get_roam_stats_individual_record_len(roam_info, idx);
+
+	data_size += NLMSG_HDRLEN;
+
+	vendor_event =
+		wlan_cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
+						 &link_info->adapter->wdev,
+						 data_size,
+						 ROAM_STATS_EVENT_INDEX,
+						 GFP_KERNEL);
+
+	if (hdd_nla_put_roam_stats_info(vendor_event, roam_info, 0)) {
+		wlan_cfg80211_vendor_free_skb(vendor_event);
+		hdd_err("nla put failure");
+		return;
+	}
+
+	roam_stats->enhance_roam_rt_event = false;
+
+	wlan_cfg80211_vendor_event(vendor_event, GFP_KERNEL);
+}
+#else
+static void
+wlan_hdd_cfg80211_enhance_roam_events_callback(struct wlan_hdd_link_info *link_info,
+					       struct roam_stats_event *roam_stats,
+					       uint8_t idx)
+{
+}
+#endif
+void
+wlan_hdd_cfg80211_roam_events_callback(struct roam_stats_event *roam_stats,
+				       uint8_t idx)
+{
+	int status;
+	struct wlan_hdd_link_info *link_info;
+	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (status) {
+		hdd_err("Invalid hdd_ctx");
+		return;
+	}
+
+	if (!roam_stats) {
+		hdd_err("msg received here is null");
+		return;
+	}
+
+	link_info = hdd_get_link_info_by_vdev(hdd_ctx, roam_stats->vdev_id);
+	if (!link_info) {
+		hdd_err("vdev_id %d does not exist with host",
+			roam_stats->vdev_id);
+		return;
+	}
+	if (roam_stats->enhance_roam_rt_event)
+		wlan_hdd_cfg80211_enhance_roam_events_callback(link_info,
+							       roam_stats, idx);
+	else
+		wlan_hdd_cfg80211_typical_roam_events_callback(link_info,
+							       roam_stats, idx);
+}
+#endif
+
 #ifdef WLAN_FEATURE_TX_LATENCY_STATS
 #define TX_LATENCY_BUCKET_DISTRIBUTION_LEN \
 	(sizeof(uint32_t) * CDP_TX_LATENCY_TYPE_MAX)