qcacld-3.0: Enhance congestion report
Enhance congestion report by pdev extend stats. Change-Id: Ica61112f95e6264db5b46db807e1f5df04b26c98 CRs-Fixed: 3234080
This commit is contained in:

committed by
Madan Koyyalamudi

parent
45cfd4b5fc
commit
25e3dfc1ee
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
@@ -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:
|
||||
|
@@ -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,
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user