Bläddra i källkod

qcacld-3.0: Enhance congestion report

Enhance congestion report by pdev extend stats.

Change-Id: Ica61112f95e6264db5b46db807e1f5df04b26c98
CRs-Fixed: 3234080
Paul Zhang 3 år sedan
förälder
incheckning
25e3dfc1ee

+ 32 - 4
components/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h

@@ -218,17 +218,21 @@ struct big_data_stats_event {
 
 /**
  * struct medium_assess_data - medium assess data from firmware
- * @part1_valid: the flag for part1 data
+ * @part1_valid: the flag for part1 data, include cycle_count,
+ *    rx_clear_count and tx_frame_count
  * @cycle_count: accumulative cycle count (total time)
  * @rx_clear_count: accumulative rx clear count (busy time)
  * @tx_frame_count: accumulative tx frame count (total time)
+ * @part2_valid: the flag for part2 data, include my_rx_count
+ * @my_rx_count: my RX count
  */
 struct medium_assess_data {
-	/* part1 data */
-	uint8_t part1_valid;
+	bool part1_valid;
 	uint32_t cycle_count;
 	uint32_t rx_clear_count;
 	uint32_t tx_frame_count;
+	bool part2_valid;
+	uint32_t my_rx_count;
 };
 
 /**
@@ -254,7 +258,8 @@ struct request_info {
 		void (*get_peer_stats_cb)(struct stats_event *ev,
 					  void *cookie);
 		void (*congestion_notif_cb)(uint8_t vdev_id,
-					  struct medium_assess_data *data);
+					  struct medium_assess_data *data,
+					  bool last);
 #ifdef WLAN_FEATURE_BIG_DATA_STATS
 		void (*get_big_data_stats_cb)(struct big_data_stats_event *ev,
 					      void *cookie);
@@ -306,6 +311,24 @@ struct psoc_mc_cp_stats {
 #endif
 };
 
+/**
+ * struct pdev_extd_stats - pdev extd stats
+ * @pdev_id: pdev id
+ * @my_rx_count: What portion of time, as measured by the MAC HW clock was
+ *               occupied, by receiving PPDUs addressed to one of the vdevs
+ *               within this pdev.
+ * @rx_matched_11ax_msdu_cnt: number of Rx 11ax MSDUs with matching BSS color
+ *                            counter updated at EOP (end of packet)
+ * @rx_other_11ax_msdu_cnt: number of Rx 11ax MSDUs with other BSS color counter
+ *                          updated at EOP (end of packet)
+ */
+struct pdev_mc_cp_extd_stats {
+	uint32_t pdev_id;
+	uint32_t my_rx_count;
+	uint32_t rx_matched_11ax_msdu_cnt;
+	uint32_t rx_other_11ax_msdu_cnt;
+};
+
 /**
  * struct pdev_mc_cp_stats: pdev specific stats
  * @max_pwr: max tx power for pdev
@@ -643,6 +666,9 @@ struct peer_stats_info_ext_event {
  * struct stats_event - parameters populated by stats event
  * @num_pdev_stats: num pdev stats
  * @pdev_stats: if populated array indicating pdev stats (index = pdev_id)
+ * @num_pdev_extd_stats: num pdev extended stats
+ * @pdev_extd_stats: if populated array indicating pdev extended stats
+ *                   (index = pdev_id)
  * @num_peer_stats: num peer stats
  * @peer_stats: if populated array indicating peer stats
  * @peer_adv_stats: if populated, indicates peer adv (extd2) stats
@@ -667,6 +693,8 @@ struct peer_stats_info_ext_event {
 struct stats_event {
 	uint32_t num_pdev_stats;
 	struct pdev_mc_cp_stats *pdev_stats;
+	uint32_t num_pdev_extd_stats;
+	struct pdev_mc_cp_extd_stats *pdev_extd_stats;
 	uint32_t num_peer_stats;
 	struct peer_mc_cp_stats *peer_stats;
 	uint32_t num_peer_adv_stats;

+ 17 - 3
components/cp_stats/dispatcher/src/wlan_cp_stats_mc_tgt_api.c

@@ -709,8 +709,10 @@ tgt_mc_cp_stats_extract_congestion_stats(struct wlan_objmgr_psoc *psoc,
 	uint8_t i, index;
 	struct request_info last_req = {0};
 	struct medium_assess_data data[WLAN_UMAC_MAX_RP_PID] = { {0} };
+	bool is_last_event = tgt_mc_cp_stats_is_last_event(ev,
+					TYPE_CONGESTION_STATS);
 
-	if (!ev->num_pdev_stats) {
+	if (!(ev->num_pdev_stats || ev->num_pdev_extd_stats)) {
 		cp_stats_err("no congestion sta for pdev");
 		return;
 	}
@@ -730,14 +732,26 @@ tgt_mc_cp_stats_extract_congestion_stats(struct wlan_objmgr_psoc *psoc,
 			cp_stats_err("part1 pdev id error");
 			continue;
 		}
-		data[index].part1_valid = 1;
+		data[index].part1_valid = true;
 		data[index].cycle_count = ev->pdev_stats[i].cycle_count;
 		data[index].rx_clear_count = ev->pdev_stats[i].rx_clear_count;
 		data[index].tx_frame_count = ev->pdev_stats[i].tx_frame_count;
 	}
 
+	for (i = 0; (i < ev->num_pdev_extd_stats) && (i < WLAN_UMAC_MAX_RP_PID);
+	     i++){
+		index = ev->pdev_extd_stats[i].pdev_id;
+		if (index >= WLAN_UMAC_MAX_RP_PID) {
+			cp_stats_err("part2 pdev id error");
+			continue;
+		}
+		data[index].part2_valid = true;
+		data[index].my_rx_count = ev->pdev_extd_stats[i].my_rx_count;
+	}
+
 	if (last_req.u.congestion_notif_cb)
-		last_req.u.congestion_notif_cb(last_req.vdev_id, data);
+		last_req.u.congestion_notif_cb(last_req.vdev_id, data,
+						is_last_event);
 
 }
 #else

+ 2 - 0
components/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -944,6 +945,7 @@ void ucfg_mc_cp_stats_free_stats_resources(struct stats_event *ev)
 		return;
 
 	qdf_mem_free(ev->pdev_stats);
+	qdf_mem_free(ev->pdev_extd_stats);
 	qdf_mem_free(ev->peer_adv_stats);
 	qdf_mem_free(ev->peer_stats);
 	qdf_mem_free(ev->cca_stats);

+ 61 - 11
components/target_if/cp_stats/src/target_if_mc_cp_stats.c

@@ -340,6 +340,8 @@ static void target_if_cp_stats_free_stats_event(struct stats_event *ev)
 {
 	qdf_mem_free(ev->pdev_stats);
 	ev->pdev_stats = NULL;
+	qdf_mem_free(ev->pdev_extd_stats);
+	ev->pdev_extd_stats = NULL;
 	qdf_mem_free(ev->peer_stats);
 	ev->peer_stats = NULL;
 	qdf_mem_free(ev->peer_adv_stats);
@@ -402,16 +404,7 @@ static QDF_STATUS target_if_cp_stats_extract_pdev_stats(
 		 */
 		ev->pdev_stats[i].max_pwr = pdev_stats->chan_tx_pwr >> 1;
 
-		/*
-		 * if pdev_stats->pdev_id is 0, then the event contains all
-		 * pdev info, else only contains 1 pdev with pdev id set.
-		 * minus 1: align fw pdev_id and driver
-		 */
-		if (pdev_stats->pdev_id)
-			ev->pdev_stats[i].pdev_id = pdev_stats->pdev_id - 1;
-		else
-			ev->pdev_stats[i].pdev_id = i;
-
+		ev->pdev_stats[i].pdev_id = pdev_stats->pdev_id;
 		ev->pdev_stats[i].rx_clear_count = pdev_stats->rx_clear_count;
 		ev->pdev_stats[i].tx_frame_count = pdev_stats->tx_frame_count;
 		ev->pdev_stats[i].cycle_count = pdev_stats->cycle_count;
@@ -456,6 +449,55 @@ static QDF_STATUS target_if_cp_stats_extract_pmf_bcn_protect_stats(
 	return QDF_STATUS_SUCCESS;
 }
 
+static QDF_STATUS
+target_if_cp_stats_extract_pdev_extd_stats(struct wmi_unified *wmi_hdl,
+					   wmi_host_stats_event *stats_param,
+					   struct stats_event *ev,
+					   uint8_t *data)
+{
+	uint32_t i;
+	QDF_STATUS status;
+	wmi_host_pdev_ext_stats *pdev_extd_stats;
+
+	if (!(stats_param->stats_id & WMI_REQUEST_PDEV_EXTD_STAT))
+		return QDF_STATUS_SUCCESS;
+
+	ev->pdev_extd_stats = qdf_mem_malloc(sizeof(*ev->pdev_extd_stats) *
+					     WLAN_UMAC_MAX_RP_PID);
+	if (!ev->pdev_extd_stats)
+		return QDF_STATUS_E_NOMEM;
+
+	pdev_extd_stats = qdf_mem_malloc(sizeof(*pdev_extd_stats));
+	if (!pdev_extd_stats)
+		return QDF_STATUS_E_NOMEM;
+
+	ev->num_pdev_extd_stats = 0;
+	for (i = 0; i < stats_param->num_pdev_ext_stats; i++) {
+		qdf_mem_set(pdev_extd_stats, sizeof(*pdev_extd_stats), 0);
+
+		status = wmi_extract_pdev_ext_stats(wmi_hdl, data, i,
+						    pdev_extd_stats);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			qdf_mem_free(pdev_extd_stats);
+			cp_stats_err("wmi_extract_pdev_ext_stats failed");
+			return status;
+		}
+
+		ev->num_pdev_extd_stats++;
+		ev->pdev_extd_stats[i].pdev_id =
+			pdev_extd_stats->pdev_id;
+		ev->pdev_extd_stats[i].my_rx_count =
+			pdev_extd_stats->my_rx_count;
+		ev->pdev_extd_stats[i].rx_matched_11ax_msdu_cnt =
+			pdev_extd_stats->rx_matched_11ax_msdu_cnt;
+		ev->pdev_extd_stats[i].rx_other_11ax_msdu_cnt =
+			pdev_extd_stats->rx_other_11ax_msdu_cnt;
+	}
+
+	qdf_mem_free(pdev_extd_stats);
+	return QDF_STATUS_SUCCESS;
+}
+
 static void target_if_cp_stats_extract_peer_extd_stats(
 	struct wmi_unified *wmi_hdl,
 	wmi_host_stats_event *stats_param,
@@ -858,6 +900,13 @@ static QDF_STATUS target_if_cp_stats_extract_event(struct wmi_unified *wmi_hdl,
 	status = target_if_cp_stats_extract_pmf_bcn_protect_stats(wmi_hdl,
 								  &stats_param,
 								  ev, data);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	status = target_if_cp_stats_extract_pdev_extd_stats(wmi_hdl,
+							    &stats_param,
+							    ev, data);
+
 	return status;
 }
 
@@ -1428,8 +1477,9 @@ static uint32_t get_stats_id(enum stats_req_type type)
 	default:
 		break;
 	case TYPE_CONNECTION_TX_POWER:
-	case TYPE_CONGESTION_STATS:
 		return WMI_REQUEST_PDEV_STAT;
+	case TYPE_CONGESTION_STATS:
+		return WMI_REQUEST_PDEV_STAT | WMI_REQUEST_PDEV_EXTD_STAT;
 	case TYPE_PEER_STATS:
 		return WMI_REQUEST_PEER_STAT | WMI_REQUEST_PEER_EXTD_STAT;
 	case TYPE_STATION_STATS:

+ 40 - 20
core/hdd/src/wlan_hdd_medium_assess.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -261,22 +261,22 @@ static int get_congestion_report_len(void)
 static void hdd_congestion_reset_data(uint8_t pdev_id)
 {
 	struct hdd_medium_assess_info *mdata;
-	uint8_t i;
 
 	mdata = &medium_assess_info[pdev_id];
-	for (i = 0; i < MEDIUM_ASSESS_NUM; i++)
-		mdata->data[i].part1_valid = 0;
+	qdf_mem_zero(mdata->data, sizeof(mdata->data));
 }
 
 /**
  * hdd_congestion_notification_cb() - congestion notification callback function
  * @vdev_id: vdev id
- * @congestion: congestion percentage
+ * @data: medium assess data from firmware
+ * @last: indicate whether the callback from final WMI_STATS_EVENT in a series
  *
  * Return: None
  */
 static void hdd_congestion_notification_cb(uint8_t vdev_id,
-					   struct medium_assess_data *data)
+					   struct medium_assess_data *data,
+					   bool last)
 {
 	struct hdd_medium_assess_info *mdata;
 	uint8_t i;
@@ -302,7 +302,7 @@ static void hdd_congestion_notification_cb(uint8_t vdev_id,
 		}
 
 		if (data[i].part1_valid) {
-			mdata->data[mdata->index].part1_valid = 1;
+			mdata->data[mdata->index].part1_valid = true;
 			mdata->data[mdata->index].cycle_count =
 						data[i].cycle_count;
 			mdata->data[mdata->index].rx_clear_count =
@@ -311,11 +311,18 @@ static void hdd_congestion_notification_cb(uint8_t vdev_id,
 						data[i].tx_frame_count;
 		}
 
-		if (mdata->data[mdata->index].part1_valid) {
+		if (data[i].part2_valid) {
+			mdata->data[mdata->index].part2_valid = true;
+			mdata->data[mdata->index].my_rx_count =
+						data[i].my_rx_count;
+		}
+
+		if (last) {
 			mdata->index++;
 			if (mdata->index >= MEDIUM_ASSESS_NUM)
 				mdata->index = 0;
-			mdata->data[mdata->index].part1_valid = 0;
+			mdata->data[mdata->index].part1_valid = false;
+			mdata->data[mdata->index].part2_valid = false;
 		}
 	}
 }
@@ -587,7 +594,7 @@ hdd_congestion_notification_calculation(struct hdd_medium_assess_info *info)
 	struct medium_assess_data *h_data, *t_data;
 	int32_t h_index, t_index;
 	uint32_t rx_clear_count_delta, tx_frame_count_delta;
-	uint32_t cycle_count_delta;
+	uint32_t cycle_count_delta, my_rx_count_delta;
 	uint32_t congestion = 0;
 	uint64_t diff;
 
@@ -609,7 +616,8 @@ hdd_congestion_notification_calculation(struct hdd_medium_assess_info *info)
 	h_data = &info->data[h_index];
 	t_data = &info->data[t_index];
 
-	if (!(h_data->part1_valid || t_data->part1_valid)) {
+	if (!(h_data->part1_valid || h_data->part2_valid ||
+	      t_data->part1_valid || t_data->part2_valid)) {
 		hdd_err("medium assess data is not valid.");
 		return;
 	}
@@ -630,6 +638,13 @@ hdd_congestion_notification_calculation(struct hdd_medium_assess_info *info)
 		tx_frame_count_delta += h_data->tx_frame_count;
 	}
 
+	if (h_data->my_rx_count >= t_data->my_rx_count) {
+		my_rx_count_delta = h_data->my_rx_count - t_data->my_rx_count;
+	} else {
+		my_rx_count_delta = U32_MAX - t_data->my_rx_count;
+		my_rx_count_delta += h_data->my_rx_count;
+	}
+
 	if (h_data->cycle_count >= t_data->cycle_count) {
 		cycle_count_delta = h_data->cycle_count - t_data->cycle_count;
 	} else {
@@ -637,16 +652,20 @@ hdd_congestion_notification_calculation(struct hdd_medium_assess_info *info)
 		cycle_count_delta += h_data->cycle_count;
 	}
 
-	diff = ((uint64_t)(rx_clear_count_delta - tx_frame_count_delta)) * 100;
-	if (cycle_count_delta)
-		congestion = qdf_do_div(diff, cycle_count_delta);
+	if (rx_clear_count_delta > tx_frame_count_delta &&
+	    rx_clear_count_delta - tx_frame_count_delta > my_rx_count_delta) {
+		diff = rx_clear_count_delta - tx_frame_count_delta
+		       - my_rx_count_delta;
+		if (cycle_count_delta)
+			congestion = qdf_do_div(diff * 100, cycle_count_delta);
 
-	if (congestion > 100)
-		congestion = 100;
+		if (congestion > 100)
+			congestion = 100;
+	}
 
-	hdd_debug("pdev: %d, rx_clear %u, tx_frame %u cycle %u congestion: %u",
+	hdd_debug("pdev: %d, rx_c %u, tx %u myrx %u cycle %u congestion: %u",
 		  info->pdev_id, rx_clear_count_delta, tx_frame_count_delta,
-		  cycle_count_delta, congestion);
+		  my_rx_count_delta, cycle_count_delta, congestion);
 	if (congestion >= info->config.threshold)
 		hdd_congestion_notification_report(info->vdev_id, congestion);
 }
@@ -694,7 +713,8 @@ static void hdd_medium_assess_expire_handler(void *arg)
 
 			/* ensure events are reveived at the 'same' time */
 			index = medium_assess_info[i].index;
-			medium_assess_info[i].data[index].part1_valid = 0;
+			medium_assess_info[i].data[index].part1_valid = false;
+			medium_assess_info[i].data[index].part2_valid = false;
 		}
 
 	if (vdev_id == INVALID_VDEV_ID)
@@ -711,7 +731,7 @@ static void hdd_medium_assess_expire_handler(void *arg)
 		return;
 
 	info.vdev_id = vdev_id;
-	info.pdev_id = 0;
+	info.pdev_id = WMI_HOST_PDEV_ID_SOC;
 	info.u.congestion_notif_cb = hdd_congestion_notification_cb;
 	stime = jiffies + msecs_to_jiffies(40);
 	ucfg_mc_cp_stats_send_stats_request(vdev,

+ 1 - 0
os_if/cp_stats/src/wlan_cfg80211_mc_cp_stats.c

@@ -123,6 +123,7 @@ static void wlan_cfg80211_mc_cp_stats_dealloc(void *priv)
 	}
 
 	qdf_mem_free(stats->pdev_stats);
+	qdf_mem_free(stats->pdev_extd_stats);
 	qdf_mem_free(stats->peer_stats);
 	qdf_mem_free(stats->cca_stats);
 	qdf_mem_free(stats->vdev_summary_stats);