qcacld-3.0: Enhance congestion report

Enhance congestion report by pdev extend stats.

Change-Id: Ica61112f95e6264db5b46db807e1f5df04b26c98
CRs-Fixed: 3234080
This commit is contained in:
Paul Zhang
2021-06-24 15:48:53 +08:00
committed by Madan Koyyalamudi
parent 45cfd4b5fc
commit 25e3dfc1ee
6 changed files with 153 additions and 38 deletions

View File

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

View File

@@ -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

View File

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

View File

@@ -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:

View File

@@ -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,

View File

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