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
This commit is contained in:
Abhinav Kumar
2023-09-25 08:38:44 -07:00
committad av Rahul Choudhary
förälder c1f0eebf5d
incheckning 453fb17648
6 ändrade filer med 223 tillägg och 46 borttagningar

Visa fil

@@ -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;
};
/**

Visa fil

@@ -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);
}
}