Jelajahi Sumber

qcacld-3.0: Update chan load for chan load req of 320 MHz

In case of wide band scan, FW sends cca_busy_subband_info
tlvs via WMI_CHAN_INFO_EVENTID, which contains value of
rx_clear_count for each 20 MHz freq space.

Fix is to updates rx_clear_count per channel to cp stats
component.

Change-Id: Iff26087da4ffa3e1147c5ffe4127e5aa078f406f
CRs-Fixed: 3626725
Abhinav Kumar 1 tahun lalu
induk
melakukan
453fb17648

+ 20 - 0
components/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h

@@ -332,6 +332,24 @@ struct pdev_mc_cp_extd_stats {
 	uint32_t rx_other_11ax_msdu_cnt;
 };
 
+/* Max supported bandwidth is 320Mhz, so max 16 subbands for 20Mhz */
+#define MAX_WIDE_BAND_SCAN_CHAN 16
+
+/**
+ * struct wide_band_scan_chan_info - wide band scan channel info
+ * @vdev_id: vdev id
+ * @num_chan: number of channels (for each subbands fo 20Mhz)
+ * @is_wide_band_scan: wide band scan or not
+ * @cca_busy_subband_info: CCA busy for each possible 20Mhz subbands
+ * of the wideband scan channel
+ */
+struct wide_band_scan_chan_info {
+	uint32_t vdev_id;
+	uint8_t num_chan;
+	bool is_wide_band_scan;
+	uint32_t cca_busy_subband_info[MAX_WIDE_BAND_SCAN_CHAN];
+};
+
 /**
  * struct channel_status
  * @channel_freq: Channel freq
@@ -347,6 +365,7 @@ struct pdev_mc_cp_extd_stats {
  * @mac_clk_mhz: sample frequency
  * @channel_id: channel index
  * @cmd_flags: indicate which stat event is this status coming from
+ * @subband_info: wide band scan channel info
  */
 struct channel_status {
 	uint32_t    channel_freq;
@@ -362,6 +381,7 @@ struct channel_status {
 	uint32_t    mac_clk_mhz;
 	uint32_t    channel_id;
 	uint32_t    cmd_flags;
+	struct wide_band_scan_chan_info subband_info;
 };
 
 /**

+ 176 - 12
components/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c

@@ -1175,8 +1175,162 @@ void ucfg_mc_cp_stats_register_pmo_handler(void)
 				    ucfg_mc_cp_stats_resume_handler, NULL);
 }
 
+/**
+ * wlan_cp_stats_get_ch_width_from_chan_info - get ch_width as per num channel
+ * present in scan event
+ * @channel_stat: struct scan_chan_info
+ *
+ * Return: phy_ch_width.
+ */
+static enum phy_ch_width
+wlan_cp_stats_get_ch_width_from_chan_info(struct channel_status *channel_stat)
+{
+	enum phy_ch_width scanned_ch_width;
+
+	switch (channel_stat->subband_info.num_chan) {
+	case 1:
+		scanned_ch_width = CH_WIDTH_20MHZ;
+		break;
+	case 2:
+		scanned_ch_width = CH_WIDTH_40MHZ;
+		break;
+	case 4:
+		scanned_ch_width = CH_WIDTH_80MHZ;
+		break;
+	case 8:
+		scanned_ch_width = CH_WIDTH_160MHZ;
+		break;
+	default:
+		scanned_ch_width = CH_WIDTH_INVALID;
+		break;
+	}
+
+	return scanned_ch_width;
+}
+
+/**
+ * wlan_cp_stats_update_per_channel_stats - update per channel stats as per
+ * data present in scan event
+ * @channel_stats: per channel stats
+ * @ev_channel_stat: channel stats per scan event
+ * @freq: freq to update channel stats
+ * @rx_clear_count: rx clear count for a freq
+ *
+ * Return: none.
+ */
+static void
+wlan_cp_stats_update_per_channel_stats(struct per_channel_stats *channel_stats,
+				       struct channel_status *ev_channel_stat,
+				       uint32_t freq, uint32_t rx_clear_count)
+{
+	struct channel_status *channel_status_list;
+	uint8_t total_channel, i;
+	bool found = false;
+
+	channel_status_list = channel_stats->channel_status_list;
+	total_channel = channel_stats->total_channel;
+
+	for (i = 0; i < total_channel; i++) {
+		if (channel_status_list[i].channel_freq == freq) {
+			cp_stats_debug("update rcc: %d, cc:%d at index: %d, freq: %d",
+				       ev_channel_stat->rx_clear_count,
+				       ev_channel_stat->cycle_count, i, freq);
+
+			channel_status_list[i].rx_clear_count = rx_clear_count;
+			channel_status_list[i].cycle_count =
+					ev_channel_stat->cycle_count;
+			found = true;
+			break;
+		}
+	}
+
+	if (!found) {
+		if (total_channel < NUM_CHANNELS) {
+			ev_channel_stat->rx_clear_count = rx_clear_count;
+			ev_channel_stat->channel_freq = freq;
+
+			cp_stats_debug("Add rcc: %d cc: %d, at index: %d, freq: %d",
+				       ev_channel_stat->rx_clear_count,
+				       ev_channel_stat->rx_clear_count,
+				       total_channel, freq);
+
+			qdf_mem_copy(&channel_status_list[total_channel++],
+				     ev_channel_stat,
+				     sizeof(*channel_status_list));
+			channel_stats->total_channel = total_channel;
+		} else {
+			cp_stats_debug("Chan cnt exceed, channel_id: %d",
+				       ev_channel_stat->channel_id);
+		}
+	}
+}
+
+/**
+ * wlan_cp_stats_update_channel_stats - wrapper api to update per channel stats
+ * as per data present in scan event
+ * @channel_stats: per channel stats
+ * @ev_channel_stat: channel stats per scan event
+ *
+ * Return: none.
+ */
+static void
+wlan_cp_stats_update_channel_stats(struct per_channel_stats *channel_stats,
+				   struct channel_status *ev_channel_stat)
+{
+	uint8_t index, freq_info_num;
+	enum phy_ch_width scanned_ch_width;
+	const struct bonded_channel_freq *range = NULL;
+	uint16_t start_freq, end_freq;
+	uint32_t rx_clear_count;
+
+	scanned_ch_width =
+		wlan_cp_stats_get_ch_width_from_chan_info(ev_channel_stat);
+	if (scanned_ch_width == CH_WIDTH_INVALID) {
+		cp_stats_debug("Invalid scanned_ch_width");
+		return;
+	}
+
+	if (scanned_ch_width == CH_WIDTH_20MHZ) {
+		start_freq = ev_channel_stat->channel_freq;
+		end_freq = ev_channel_stat->channel_freq;
+	} else {
+		range =
+		   wlan_reg_get_bonded_chan_entry(ev_channel_stat->channel_freq,
+						  scanned_ch_width, 0);
+		if (!range) {
+			cp_stats_debug("range is NULL for freq %d, ch_width %d",
+				       ev_channel_stat->channel_freq,
+				       scanned_ch_width);
+			return;
+		}
+		start_freq = range->start_freq;
+		end_freq = range->end_freq;
+	}
+
+	freq_info_num = ev_channel_stat->subband_info.num_chan;
+	index = 0;
+
+	cp_stats_debug("freq :%d bw %d, range [%d-%d], num_freq:%d",
+		       ev_channel_stat->channel_freq, scanned_ch_width,
+		       start_freq, end_freq, freq_info_num);
+
+	for (; start_freq <= end_freq;) {
+		if (index >= freq_info_num || index >= MAX_WIDE_BAND_SCAN_CHAN)
+			break;
+		rx_clear_count =
+		    ev_channel_stat->subband_info.cca_busy_subband_info[index];
+		wlan_cp_stats_update_per_channel_stats(channel_stats,
+						       ev_channel_stat,
+						       start_freq,
+						       rx_clear_count);
+
+		start_freq += BW_20_MHZ;
+		index++;
+	}
+}
+
 void wlan_cp_stats_update_chan_info(struct wlan_objmgr_psoc *psoc,
-				    struct channel_status *channel_stat,
+				    struct channel_status *ev_channel_stat,
 				    uint8_t vdev_id)
 {
 	struct wlan_objmgr_pdev *pdev;
@@ -1194,8 +1348,11 @@ void wlan_cp_stats_update_chan_info(struct wlan_objmgr_psoc *psoc,
 		return;
 
 	pdev = wlan_vdev_get_pdev(vdev);
-	if (!pdev)
+	if (!pdev) {
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
+		cp_stats_err("pdev object is null");
 		return;
+	}
 
 	pdev_cp_stats_priv = wlan_cp_stats_get_pdev_stats_obj(pdev);
 	if (!pdev_cp_stats_priv) {
@@ -1208,26 +1365,33 @@ void wlan_cp_stats_update_chan_info(struct wlan_objmgr_psoc *psoc,
 	channel_status_list = channel_stats->channel_status_list;
 	total_channel = channel_stats->total_channel;
 
+	if (ev_channel_stat->subband_info.is_wide_band_scan) {
+		wlan_cp_stats_update_channel_stats(channel_stats,
+						   ev_channel_stat);
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_CP_STATS_ID);
+		return;
+	}
+
 	for (i = 0; i < total_channel; i++) {
 		if (channel_status_list[i].channel_id ==
-		    channel_stat->channel_id) {
-			if (channel_stat->cmd_flags ==
+		    ev_channel_stat->channel_id) {
+			if (ev_channel_stat->cmd_flags ==
 			    WMI_CHAN_InFO_END_RESP &&
 			    channel_status_list[i].cmd_flags ==
 			    WMI_CHAN_InFO_START_RESP) {
 				/* adjust to delta value for counts */
-				channel_stat->rx_clear_count -=
+				ev_channel_stat->rx_clear_count -=
 				    channel_status_list[i].rx_clear_count;
-				channel_stat->cycle_count -=
+				ev_channel_stat->cycle_count -=
 				    channel_status_list[i].cycle_count;
-				channel_stat->rx_frame_count -=
+				ev_channel_stat->rx_frame_count -=
 				    channel_status_list[i].rx_frame_count;
-				channel_stat->tx_frame_count -=
+				ev_channel_stat->tx_frame_count -=
 				    channel_status_list[i].tx_frame_count;
-				channel_stat->bss_rx_cycle_count -=
+				ev_channel_stat->bss_rx_cycle_count -=
 				    channel_status_list[i].bss_rx_cycle_count;
 			}
-			qdf_mem_copy(&channel_status_list[i], channel_stat,
+			qdf_mem_copy(&channel_status_list[i], ev_channel_stat,
 				     sizeof(*channel_status_list));
 			found = true;
 			break;
@@ -1237,12 +1401,12 @@ void wlan_cp_stats_update_chan_info(struct wlan_objmgr_psoc *psoc,
 	if (!found) {
 		if (total_channel < NUM_CHANNELS) {
 			qdf_mem_copy(&channel_status_list[total_channel++],
-				     channel_stat,
+				     ev_channel_stat,
 				     sizeof(*channel_status_list));
 			channel_stats->total_channel = total_channel;
 		} else {
 			cp_stats_err("Chan cnt exceed, channel_id=%d",
-				     channel_stat->channel_id);
+				     ev_channel_stat->channel_id);
 		}
 	}
 

+ 2 - 0
core/hdd/src/wlan_hdd_cfg80211.c

@@ -211,6 +211,8 @@
 #include <wlan_ll_sap_ucfg_api.h>
 #include <wlan_mlo_mgr_link_switch.h>
 #include <wlan_hdd_ll_lt_sap.h>
+#include "wlan_cp_stats_mc_defs.h"
+
 /*
  * A value of 100 (milliseconds) can be sent to FW.
  * FW would enable Tx beamforming based on this.

+ 0 - 18
core/mac/inc/sir_api.h

@@ -4370,24 +4370,6 @@ struct wow_pulse_mode {
  */
 QDF_STATUS umac_send_mb_message_to_mac(void *msg);
 
-/* Max supported bandwidth is 320Mhz, so max 16 subbands fo 20Mhz */
-#define MAX_WIDE_BAND_SCAN_CHAN 16
-
-/**
- * struct wide_band_scan_chan_info - wide band scan channel info
- * @vdev_id: vdev id
- * @num_chan: number of channels (for each subbands fo 20Mhz)
- * @is_wide_band_scan: wide band scan or not
- * @cca_busy_subband_info: CCA busy for each possible 20Mhz subbands
- * of the wideband scan channel
- */
-struct wide_band_scan_chan_info {
-	uint32_t vdev_id;
-	uint8_t num_chan;
-	bool is_wide_band_scan;
-	uint32_t cca_busy_subband_info[MAX_WIDE_BAND_SCAN_CHAN];
-};
-
 /**
  * struct scan_chan_info - channel info
  * @freq: radio frequence

+ 1 - 2
core/sme/src/common/sme_api.c

@@ -2656,8 +2656,7 @@ static void sme_process_chan_info_event(struct mac_context *mac,
 		return;
 	}
 
-	if (mac->sap.acs_with_more_param || sap_is_acs_scan_optimize_enable())
-		wlan_cp_stats_update_chan_info(mac->psoc, chan_stats, vdev_id);
+	wlan_cp_stats_update_chan_info(mac->psoc, chan_stats, vdev_id);
 
 	sme_indicate_chan_info_event(mac, chan_stats, vdev_id);
 }

+ 24 - 14
core/wma/src/wma_features.c

@@ -80,6 +80,8 @@
 #include "wlan_mlo_mgr_cmn.h"
 #include "wlan_mlo_mgr_peer.h"
 #include "wlan_mlo_mgr_sta.h"
+#include "wlan_cp_stats_mc_defs.h"
+
 
 /**
  * WMA_SET_VDEV_IE_SOURCE_HOST - Flag to identify the source of VDEV SET IE
@@ -5431,7 +5433,7 @@ wma_vdev_bcn_latency_event_handler(void *handle,
 #endif
 
 static void
-wma_update_sacn_channel_info_buf(wmi_unified_t wmi_handle,
+wma_update_scan_channel_info_buf(wmi_unified_t wmi_handle,
 				 wmi_chan_info_event_fixed_param *event,
 				 struct scan_chan_info *buf,
 				 wmi_cca_busy_subband_info *cca_info,
@@ -5456,19 +5458,27 @@ wma_update_sacn_channel_info_buf(wmi_unified_t wmi_handle,
 }
 
 static void
-wma_get_scan_max_rx_clear_count(wmi_cca_busy_subband_info *cca_info,
-				uint32_t num_tlvs, uint32_t *rx_clear_count)
+wma_update_scan_channel_subband_info(wmi_chan_info_event_fixed_param *event,
+				     struct channel_status *channel_status,
+				     wmi_cca_busy_subband_info *cca_info,
+				     uint32_t num_tlvs)
 {
-	uint32_t i, max_rx_clear_count = 0;
+	uint32_t i;
 
-	for (i = 0; i < num_tlvs && i < MAX_WIDE_BAND_SCAN_CHAN; i++) {
-		if (max_rx_clear_count < cca_info->rx_clear_count)
-			max_rx_clear_count = cca_info->rx_clear_count;
-		cca_info++;
-	}
+	if (cca_info && num_tlvs > 0) {
+		channel_status->subband_info.num_chan = 0;
+		for (i = 0; i < num_tlvs && i < MAX_WIDE_BAND_SCAN_CHAN; i++) {
+			channel_status->subband_info.cca_busy_subband_info[i] =
+						cca_info->rx_clear_count;
+			wma_debug("cca_info->rx_clear_count[%d]: %d", i,
+				  cca_info->rx_clear_count);
+			channel_status->subband_info.num_chan++;
+			cca_info++;
+		}
 
-	*rx_clear_count = max_rx_clear_count;
-	wma_debug("max rx_clear_count : %d", *rx_clear_count);
+		channel_status->subband_info.is_wide_band_scan = true;
+		channel_status->subband_info.vdev_id = event->vdev_id;
+	}
 }
 
 int wma_chan_info_event_handler(void *handle, uint8_t *event_buf, uint32_t len)
@@ -5527,7 +5537,7 @@ int wma_chan_info_event_handler(void *handle, uint8_t *event_buf, uint32_t len)
 		buf.rx_clear_count = event->rx_clear_count;
 		/* wide band scan case */
 		if (is_cca_busy_info && num_tlvs)
-			wma_update_sacn_channel_info_buf(wma->wmi_handle,
+			wma_update_scan_channel_info_buf(wma->wmi_handle,
 							 event, &buf,
 							 cca_info, num_tlvs);
 		mac->chan_info_cb(&buf);
@@ -5541,8 +5551,8 @@ int wma_chan_info_event_handler(void *handle, uint8_t *event_buf, uint32_t len)
 	channel_status->noise_floor = event->noise_floor;
 
 	if (is_cca_busy_info && num_tlvs)
-		wma_get_scan_max_rx_clear_count(cca_info, num_tlvs,
-					&channel_status->rx_clear_count);
+		wma_update_scan_channel_subband_info(event, channel_status,
+						     cca_info, num_tlvs);
 	else
 		channel_status->rx_clear_count = event->rx_clear_count;