qcacld-3.0: wma to target_if migration of roam_stats_event

Currently, wmi_roam_stats_event_id data is extracted and
processing is also done in wma. This is not inline with component
model where target_if takes care of data extraction and handover
the extracted data to corresponding component(connection mgr in
this case). Add changes to support the same.

Change-Id: I5e336b01e1a2183e49b3e6eeb125c7c9fd0fd73c
CRs-Fixed: 3003125
This commit is contained in:
Sai Pavan Akhil Remella
2021-08-16 02:04:47 +05:30
committed by Madan Koyyalamudi
parent b60d36df43
commit b35419136e
10 changed files with 1031 additions and 6 deletions

View File

@@ -66,6 +66,17 @@ target_if_cm_roam_sync_frame_event(ol_scn_t scn,
*/
int target_if_cm_roam_event(ol_scn_t scn, uint8_t *event, uint32_t len);
/**
* target_if_cm_roam_stats_event() - Target IF handler for roam stats event
* @scn: target handle
* @event: event buffer
* @len: event buffer length
*
* Return: int for success or error code
*/
int
target_if_cm_roam_stats_event(ol_scn_t scn, uint8_t *event, uint32_t len);
/**
* target_if_roam_offload_register_events() - register roam events
* @psoc: pointer to psoc object

View File

@@ -60,6 +60,7 @@ target_if_cm_roam_register_rx_ops(struct wlan_cm_roam_rx_ops *rx_ops)
rx_ops->btm_blacklist_event = cm_btm_blacklist_event_handler;
rx_ops->vdev_disconnect_event = cm_vdev_disconnect_event_handler;
rx_ops->roam_scan_chan_list_event = cm_roam_scan_ch_list_event_handler;
rx_ops->roam_stats_event_rx = cm_roam_stats_event_handler;
#endif
}
@@ -346,6 +347,55 @@ target_if_cm_roam_scan_chan_list_event_handler(ol_scn_t scn, uint8_t *event,
return status;
}
int
target_if_cm_roam_stats_event(ol_scn_t scn, uint8_t *event, uint32_t len)
{
QDF_STATUS qdf_status;
int status = 0;
struct wmi_unified *wmi_handle;
struct wlan_objmgr_psoc *psoc;
struct wlan_cm_roam_rx_ops *roam_rx_ops;
struct roam_stats_event *stats_info = NULL;
psoc = target_if_get_psoc_from_scn_hdl(scn);
if (!psoc) {
target_if_err("psoc is null");
return -EINVAL;
}
wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
if (!wmi_handle) {
target_if_err("wmi_handle is null");
return -EINVAL;
}
qdf_status = wmi_extract_roam_stats_event(wmi_handle, event, len,
&stats_info);
if (QDF_IS_STATUS_ERROR(qdf_status)) {
target_if_err("parsing of event failed, %d", qdf_status);
return -EINVAL;
}
roam_rx_ops = target_if_cm_get_roam_rx_ops(psoc);
if (!roam_rx_ops || !roam_rx_ops->roam_stats_event_rx) {
target_if_err("No valid roam rx ops");
status = -EINVAL;
if (stats_info) {
if (stats_info->roam_msg_info)
qdf_mem_free(stats_info->roam_msg_info);
qdf_mem_free(stats_info);
}
goto err;
}
qdf_status = roam_rx_ops->roam_stats_event_rx(psoc, stats_info);
if (QDF_IS_STATUS_ERROR(qdf_status))
status = -EINVAL;
err:
return status;
}
QDF_STATUS
target_if_roam_offload_register_events(struct wlan_objmgr_psoc *psoc)
{
@@ -414,6 +464,15 @@ target_if_roam_offload_register_events(struct wlan_objmgr_psoc *psoc)
return QDF_STATUS_E_FAILURE;
}
ret = wmi_unified_register_event_handler(handle,
wmi_roam_stats_event_id,
target_if_cm_roam_stats_event,
WMI_RX_SERIALIZER_CTX);
if (QDF_IS_STATUS_ERROR(ret)) {
target_if_err("wmi event registration failed, ret: %d", ret);
return QDF_STATUS_E_FAILURE;
}
return QDF_STATUS_SUCCESS;
}

View File

@@ -1309,6 +1309,17 @@ cm_handle_disconnect_reason(struct vdev_disconnect_event_data *data);
QDF_STATUS
cm_roam_scan_ch_list_event_handler(struct cm_roam_scan_ch_resp *data);
/**
* cm_roam_stats_event_handler() - Carries extracted roam stats info
* @psoc: PSOC pointer
* @stats_info: stats data carried by roam_stats_event
*
* Return: QDF_STATUS
*/
QDF_STATUS
cm_roam_stats_event_handler(struct wlan_objmgr_psoc *psoc,
struct roam_stats_event *stats_info);
/**
* cm_roam_update_vdev() - Update the STA and BSS
* @sync_ind: Information needed for roam sync propagation

View File

@@ -1876,6 +1876,32 @@ struct roam_offload_roam_event {
uint8_t *deauth_disassoc_frame;
};
/**
* struct roam_stats_event - Data carried by stats event
* @vdev_id: vdev id
* @num_tlv: Number of roam scans triggered
* @num_roam_msg_info: Number of roam_msg_info present in event
* @trigger: Roam trigger related details
* @scan: Roam scan event details
* @result: Roam result related info
* @data_11kv: Neighbor report/BTM request related data
* @btm_rsp: BTM response related data
* @roam_init_info: Roam initial related data
* @roam_msg_info: Roam message related information
*/
struct roam_stats_event {
uint8_t vdev_id;
uint8_t num_tlv;
uint8_t num_roam_msg_info;
struct wmi_roam_trigger_info trigger[MAX_ROAM_SCAN_STATS_TLV];
struct wmi_roam_scan_data scan[MAX_ROAM_SCAN_STATS_TLV];
struct wmi_roam_result result[MAX_ROAM_SCAN_STATS_TLV];
struct wmi_neighbor_report_data data_11kv[MAX_ROAM_SCAN_STATS_TLV];
struct roam_btm_response_data btm_rsp[MAX_ROAM_SCAN_STATS_TLV];
struct roam_initial_data roam_init_info[MAX_ROAM_SCAN_STATS_TLV];
struct roam_msg_info *roam_msg_info;
};
/**
* wlan_cm_roam_tx_ops - structure of tx function pointers for
* roaming related commands
@@ -2067,6 +2093,7 @@ struct roam_offload_synch_ind {
* @btm_blacklist_event: Rx ops function pointer for btm blacklist event
* @vdev_disconnect_event: Rx ops function pointer for vdev disconnect event
* @roam_scan_chan_list_event: Rx ops function pointer for roam scan ch event
* @roam_stats_event_rx: Rx ops function pointer for roam stats event
*/
struct wlan_cm_roam_rx_ops {
QDF_STATUS (*roam_sync_event)(struct wlan_objmgr_psoc *psoc,
@@ -2083,6 +2110,9 @@ struct wlan_cm_roam_rx_ops {
(*vdev_disconnect_event)(struct vdev_disconnect_event_data *data);
QDF_STATUS
(*roam_scan_chan_list_event)(struct cm_roam_scan_ch_resp *data);
QDF_STATUS
(*roam_stats_event_rx)(struct wlan_objmgr_psoc *psoc,
struct roam_stats_event *stats_info);
#endif
};
#endif

View File

@@ -2306,4 +2306,530 @@ cm_roam_scan_ch_list_event_handler(struct cm_roam_scan_ch_resp *data)
{
return cm_handle_scan_ch_list_data(data);
}
/**
* cm_roam_stats_get_trigger_detail_str - Return roam trigger string from the
* enum roam_trigger_reason
* @ptr: Pointer to the roam trigger info
* @buf: Destination buffer to write the reason string
*
* Return: None
*/
static void
cm_roam_stats_get_trigger_detail_str(struct wmi_roam_trigger_info *ptr,
char *buf)
{
uint16_t buf_cons, buf_left = MAX_ROAM_DEBUG_BUF_SIZE;
char *temp = buf;
buf_cons = qdf_snprint(temp, buf_left, "Reason: \"%s\" ",
mlme_get_roam_trigger_str(ptr->trigger_reason));
temp += buf_cons;
buf_left -= buf_cons;
if (ptr->trigger_sub_reason) {
buf_cons = qdf_snprint(temp, buf_left, "Sub-Reason: %s",
mlme_get_sub_reason_str(ptr->trigger_sub_reason));
temp += buf_cons;
buf_left -= buf_cons;
}
switch (ptr->trigger_reason) {
case ROAM_TRIGGER_REASON_PER:
case ROAM_TRIGGER_REASON_BMISS:
case ROAM_TRIGGER_REASON_HIGH_RSSI:
case ROAM_TRIGGER_REASON_MAWC:
case ROAM_TRIGGER_REASON_DENSE:
case ROAM_TRIGGER_REASON_BACKGROUND:
case ROAM_TRIGGER_REASON_IDLE:
case ROAM_TRIGGER_REASON_FORCED:
case ROAM_TRIGGER_REASON_UNIT_TEST:
break;
case ROAM_TRIGGER_REASON_BTM:
buf_cons = qdf_snprint(temp, buf_left,
"Req_mode: %d Disassoc_timer: %d",
ptr->btm_trig_data.btm_request_mode,
ptr->btm_trig_data.disassoc_timer);
temp += buf_cons;
buf_left -= buf_cons;
buf_cons = qdf_snprint(temp, buf_left,
"validity_interval: %d candidate_list_cnt: %d resp_status: %d, bss_termination_timeout: %d, mbo_assoc_retry_timeout: %d",
ptr->btm_trig_data.validity_interval,
ptr->btm_trig_data.candidate_list_count,
ptr->btm_trig_data.btm_resp_status,
ptr->btm_trig_data.btm_bss_termination_timeout,
ptr->btm_trig_data.btm_mbo_assoc_retry_timeout);
buf_left -= buf_cons;
temp += buf_cons;
break;
case ROAM_TRIGGER_REASON_BSS_LOAD:
buf_cons = qdf_snprint(temp, buf_left, "CU: %d %% ",
ptr->cu_trig_data.cu_load);
temp += buf_cons;
buf_left -= buf_cons;
break;
case ROAM_TRIGGER_REASON_DEAUTH:
buf_cons = qdf_snprint(temp, buf_left, "Type: %d Reason: %d ",
ptr->deauth_trig_data.type,
ptr->deauth_trig_data.reason);
temp += buf_cons;
buf_left -= buf_cons;
break;
case ROAM_TRIGGER_REASON_LOW_RSSI:
case ROAM_TRIGGER_REASON_PERIODIC:
/*
* Use ptr->current_rssi get the RSSI of current AP after
* roam scan is triggered. This avoids discrepency with the
* next rssi threshold value printed in roam scan details.
* ptr->rssi_trig_data.threshold gives the rssi threshold
* for the Low Rssi/Periodic scan trigger.
*/
buf_cons = qdf_snprint(temp, buf_left,
"Cur_Rssi threshold:%d Current AP RSSI: %d",
ptr->rssi_trig_data.threshold,
ptr->current_rssi);
temp += buf_cons;
buf_left -= buf_cons;
break;
case ROAM_TRIGGER_REASON_WTC_BTM:
if (ptr->wtc_btm_trig_data.wtc_candi_rssi_ext_present) {
buf_cons = qdf_snprint(temp, buf_left,
"Roaming Mode: %d, Trigger Reason: %d, Sub code:%d, wtc mode:%d, wtc scan mode:%d, wtc rssi th:%d, wtc candi rssi th_2g:%d, wtc_candi_rssi_th_5g:%d, wtc_candi_rssi_th_6g:%d",
ptr->wtc_btm_trig_data.roaming_mode,
ptr->wtc_btm_trig_data.vsie_trigger_reason,
ptr->wtc_btm_trig_data.sub_code,
ptr->wtc_btm_trig_data.wtc_mode,
ptr->wtc_btm_trig_data.wtc_scan_mode,
ptr->wtc_btm_trig_data.wtc_rssi_th,
ptr->wtc_btm_trig_data.wtc_candi_rssi_th,
ptr->wtc_btm_trig_data.wtc_candi_rssi_th_5g,
ptr->wtc_btm_trig_data.wtc_candi_rssi_th_6g);
} else {
buf_cons = qdf_snprint(temp, buf_left,
"Roaming Mode: %d, Trigger Reason: %d, Sub code:%d, wtc mode:%d, wtc scan mode:%d, wtc rssi th:%d, wtc candi rssi th:%d",
ptr->wtc_btm_trig_data.roaming_mode,
ptr->wtc_btm_trig_data.vsie_trigger_reason,
ptr->wtc_btm_trig_data.sub_code,
ptr->wtc_btm_trig_data.wtc_mode,
ptr->wtc_btm_trig_data.wtc_scan_mode,
ptr->wtc_btm_trig_data.wtc_rssi_th,
ptr->wtc_btm_trig_data.wtc_candi_rssi_th);
}
temp += buf_cons;
buf_left -= buf_cons;
break;
default:
break;
}
}
/**
* cm_roam_stats_print_trigger_info - Roam trigger related details
* @data: Pointer to the roam trigger data
* @vdev_id: Vdev ID
*
* Prints the vdev, roam trigger reason, time of the day at which roaming
* was triggered.
*
* Return: None
*/
static void
cm_roam_stats_print_trigger_info(struct wmi_roam_trigger_info *data,
uint8_t vdev_id)
{
char *buf;
char time[TIME_STRING_LEN];
buf = qdf_mem_malloc(MAX_ROAM_DEBUG_BUF_SIZE);
if (!buf)
return;
cm_roam_stats_get_trigger_detail_str(data, buf);
mlme_get_converted_timestamp(data->timestamp, time);
mlme_nofl_info("%s [ROAM_TRIGGER]: VDEV[%d] %s", time, vdev_id, buf);
qdf_mem_free(buf);
}
/**
* cm_roam_stats_print_btm_rsp_info - BTM RSP related details
* @data: Pointer to the btm rsp data
* @vdev_id: vdev id
*
* Prints the vdev, btm status, target_bssid and vsie reason
*
* Return: None
*/
static void
cm_roam_stats_print_btm_rsp_info(struct roam_btm_response_data *data,
uint8_t vdev_id)
{
char time[TIME_STRING_LEN];
mlme_get_converted_timestamp(data->timestamp, time);
mlme_nofl_info("%s [BTM RSP]:VDEV[%d], Status:%d, VSIE reason:%d, BSSID: "
QDF_MAC_ADDR_FMT, time, vdev_id, data->btm_status,
data->vsie_reason,
QDF_MAC_ADDR_REF(data->target_bssid.bytes));
}
/**
* cm_roam_stats_print_roam_initial_info - Roaming related initial details
* @data: Pointer to the btm rsp data
* @vdev_id: vdev id
*
* Prints the vdev, roam_full_scan_count, channel and rssi
* utilization threhold and timer
*
* Return: None
*/
static void
cm_roam_stats_print_roam_initial_info(struct roam_initial_data *data,
uint8_t vdev_id)
{
mlme_nofl_info("[ROAM INIT INFO]: VDEV[%d], roam_full_scan_count: %d, rssi_th: %d, cu_th: %d, fw_cancel_timer_bitmap: %d",
vdev_id, data->roam_full_scan_count, data->rssi_th,
data->cu_th, data->fw_cancel_timer_bitmap);
}
/**
* cm_roam_stats_print_roam_msg_info - Roaming related message details
* @data: Pointer to the btm rsp data
* @vdev_id: vdev id
*
* Prints the vdev, msg_id, msg_param1, msg_param2 and timer
*
* Return: None
*/
static void cm_roam_stats_print_roam_msg_info(struct roam_msg_info *data,
uint8_t vdev_id)
{
char time[TIME_STRING_LEN];
static const char msg_id1_str[] = "Roam RSSI TH Reset";
if (data->msg_id == WMI_ROAM_MSG_RSSI_RECOVERED) {
mlme_get_converted_timestamp(data->timestamp, time);
mlme_nofl_info("%s [ROAM MSG INFO]: VDEV[%d] %s, Current rssi: %d dbm, next_rssi_threshold: %d dbm",
time, vdev_id, msg_id1_str, data->msg_param1,
data->msg_param2);
}
}
/**
* cm_stats_log_roam_scan_candidates - Print roam scan candidate AP info
* @ap: Pointer to the candidate AP list
* @num_entries: Number of candidate APs
*
* Print the RSSI, CU load, Cu score, RSSI score, total score, BSSID
* and time stamp at which the candidate was found details.
*
* Return: None
*/
static void
cm_stats_log_roam_scan_candidates(struct wmi_roam_candidate_info *ap,
uint8_t num_entries)
{
uint16_t i;
char time[TIME_STRING_LEN], time2[TIME_STRING_LEN];
mlme_nofl_info("%62s%62s", LINE_STR, LINE_STR);
mlme_nofl_info("%13s %16s %8s %4s %4s %5s/%3s %3s/%3s %7s %7s %6s %12s %20s",
"AP BSSID", "TSTAMP", "CH", "TY", "ETP", "RSSI",
"SCR", "CU%", "SCR", "TOT_SCR", "BL_RSN", "BL_SRC",
"BL_TSTAMP", "BL_TIMEOUT(ms)");
mlme_nofl_info("%62s%62s", LINE_STR, LINE_STR);
if (num_entries > MAX_ROAM_CANDIDATE_AP)
num_entries = MAX_ROAM_CANDIDATE_AP;
for (i = 0; i < num_entries; i++) {
mlme_get_converted_timestamp(ap->timestamp, time);
mlme_get_converted_timestamp(ap->bl_timestamp, time2);
mlme_nofl_info(QDF_MAC_ADDR_FMT " %17s %4d %-4s %4d %3d/%-4d %2d/%-4d %5d %7d %7d %17s %9d",
QDF_MAC_ADDR_REF(ap->bssid.bytes), time,
ap->freq,
((ap->type == 0) ? "C_AP" :
((ap->type == 2) ? "R_AP" : "P_AP")),
ap->etp, ap->rssi, ap->rssi_score, ap->cu_load,
ap->cu_score, ap->total_score, ap->bl_reason,
ap->bl_source, time2, ap->bl_original_timeout);
ap++;
}
}
/**
* cm_roam_stats_print_scan_info - Print the roam scan details and candidate AP
* details
* @scan: Pointer to the received tlv after sanitization
* @vdev_id: Vdev ID
* @trigger: Roam scan trigger reason
* @timestamp: Host timestamp in millisecs
*
* Prinst the roam scan details with time of the day when the scan was
* triggered and roam candidate AP with score details
*
* Return: None
*/
static void
cm_roam_stats_print_scan_info(struct wmi_roam_scan_data *scan, uint8_t vdev_id,
uint32_t trigger, uint32_t timestamp)
{
uint16_t num_ch = scan->num_chan;
uint16_t buf_cons = 0, buf_left = ROAM_CHANNEL_BUF_SIZE;
uint8_t i;
char *buf, *buf1, *tmp;
char time[TIME_STRING_LEN];
buf = qdf_mem_malloc(ROAM_CHANNEL_BUF_SIZE);
if (!buf)
return;
tmp = buf;
/* For partial scans, print the channel info */
if (!scan->type) {
buf_cons = qdf_snprint(tmp, buf_left, "{");
buf_left -= buf_cons;
tmp += buf_cons;
for (i = 0; i < num_ch; i++) {
buf_cons = qdf_snprint(tmp, buf_left, "%d ",
scan->chan_freq[i]);
buf_left -= buf_cons;
tmp += buf_cons;
}
buf_cons = qdf_snprint(tmp, buf_left, "}");
buf_left -= buf_cons;
tmp += buf_cons;
}
buf1 = qdf_mem_malloc(ROAM_FAILURE_BUF_SIZE);
if (!buf1) {
qdf_mem_free(buf);
return;
}
if (trigger == ROAM_TRIGGER_REASON_LOW_RSSI ||
trigger == ROAM_TRIGGER_REASON_PERIODIC)
qdf_snprint(buf1, ROAM_FAILURE_BUF_SIZE,
"next_rssi_threshold: %d dBm",
scan->next_rssi_threshold);
mlme_get_converted_timestamp(timestamp, time);
mlme_nofl_info("%s [ROAM_SCAN]: VDEV[%d] Scan_type: %s %s %s",
time, vdev_id, mlme_get_roam_scan_type_str(scan->type),
buf1, buf);
cm_stats_log_roam_scan_candidates(scan->ap, scan->num_ap);
qdf_mem_free(buf);
qdf_mem_free(buf1);
}
/**
* cm_roam_stats_print_roam_result() - Print roam result related info
* @res: Roam result strucure pointer
* @vdev_id: Vdev id
*
* Print roam result and failure reason if roaming failed.
*
* Return: None
*/
static void
cm_roam_stats_print_roam_result(struct wmi_roam_result *res,
uint8_t vdev_id)
{
char *buf;
char time[TIME_STRING_LEN];
buf = qdf_mem_malloc(ROAM_FAILURE_BUF_SIZE);
if (!buf)
return;
if (res->status == 1)
qdf_snprint(buf, ROAM_FAILURE_BUF_SIZE, "Reason: %s",
mlme_get_roam_fail_reason_str(res->fail_reason));
mlme_get_converted_timestamp(res->timestamp, time);
mlme_nofl_info("%s [ROAM_RESULT]: VDEV[%d] %s %s",
time, vdev_id, mlme_get_roam_status_str(res->status),
buf);
qdf_mem_free(buf);
}
/**
* cm_roam_stats_print_11kv_info - Print neighbor report/BTM related data
* @neigh_rpt: Pointer to the extracted TLV structure
* @vdev_id: Vdev ID
*
* Print BTM/neighbor report info that is sent by firmware after
* connection/roaming to an AP.
*
* Return: none
*/
static void
cm_roam_stats_print_11kv_info(struct wmi_neighbor_report_data *neigh_rpt,
uint8_t vdev_id)
{
char time[TIME_STRING_LEN], time1[TIME_STRING_LEN];
char *buf, *tmp;
uint8_t type = neigh_rpt->req_type, i;
uint16_t buf_left = ROAM_CHANNEL_BUF_SIZE, buf_cons;
uint8_t num_ch = neigh_rpt->num_freq;
if (!type)
return;
buf = qdf_mem_malloc(ROAM_CHANNEL_BUF_SIZE);
if (!buf)
return;
tmp = buf;
if (num_ch) {
buf_cons = qdf_snprint(tmp, buf_left, "{ ");
buf_left -= buf_cons;
tmp += buf_cons;
for (i = 0; i < num_ch; i++) {
buf_cons = qdf_snprint(tmp, buf_left, "%d ",
neigh_rpt->freq[i]);
buf_left -= buf_cons;
tmp += buf_cons;
}
buf_cons = qdf_snprint(tmp, buf_left, "}");
buf_left -= buf_cons;
tmp += buf_cons;
}
mlme_get_converted_timestamp(neigh_rpt->req_time, time);
mlme_nofl_info("%s [%s] VDEV[%d]", time,
(type == 1) ? "BTM_QUERY" : "NEIGH_RPT_REQ", vdev_id);
if (neigh_rpt->resp_time) {
mlme_get_converted_timestamp(neigh_rpt->resp_time, time1);
mlme_nofl_info("%s [%s] VDEV[%d] %s", time1,
(type == 1) ? "BTM_REQ" : "NEIGH_RPT_RSP",
vdev_id,
(num_ch > 0) ? buf : "NO Ch update");
} else {
mlme_nofl_info("%s No response received from AP",
(type == 1) ? "BTM" : "NEIGH_RPT");
}
qdf_mem_free(buf);
}
QDF_STATUS
cm_roam_stats_event_handler(struct wlan_objmgr_psoc *psoc,
struct roam_stats_event *stats_info)
{
uint8_t i, rem_tlv = 0;
QDF_STATUS status = QDF_STATUS_SUCCESS;
if (!stats_info)
return QDF_STATUS_E_FAILURE;
for (i = 0; i < stats_info->num_tlv; i++) {
if (stats_info->trigger[i].present) {
cm_roam_stats_print_trigger_info(
&stats_info->trigger[i],
stats_info->vdev_id);
status = wlan_cm_update_roam_states(psoc,
stats_info->vdev_id,
stats_info->trigger[i].trigger_reason,
ROAM_TRIGGER_REASON);
if (QDF_IS_STATUS_ERROR(status))
goto err;
}
if (stats_info->scan[i].present &&
stats_info->trigger[i].present)
cm_roam_stats_print_scan_info(&stats_info->scan[i],
stats_info->vdev_id,
stats_info->trigger[i].trigger_reason,
stats_info->trigger[i].timestamp);
if (stats_info->result[i].present) {
cm_roam_stats_print_roam_result(&stats_info->result[i],
stats_info->vdev_id);
status = wlan_cm_update_roam_states(psoc,
stats_info->vdev_id,
stats_info->result[i].fail_reason,
ROAM_FAIL_REASON);
if (QDF_IS_STATUS_ERROR(status))
goto err;
}
/*
* Print BTM resp TLV info (wmi_roam_btm_response_info) only
* when trigger reason is BTM or WTC_BTM. As for other roam
* triggers this TLV contains zeros, so host should not print.
*/
if (stats_info->btm_rsp[i].present &&
(stats_info->trigger[i].present &&
(stats_info->trigger[i].trigger_reason ==
ROAM_TRIGGER_REASON_WTC_BTM ||
stats_info->trigger[i].trigger_reason ==
ROAM_TRIGGER_REASON_BTM)))
cm_roam_stats_print_btm_rsp_info(
&stats_info->btm_rsp[i],
stats_info->vdev_id);
if (stats_info->roam_init_info[i].present)
cm_roam_stats_print_roam_initial_info(
&stats_info->roam_init_info[i],
stats_info->vdev_id);
if (stats_info->roam_msg_info &&
i < stats_info->num_roam_msg_info &&
stats_info->roam_msg_info[i].present) {
rem_tlv++;
cm_roam_stats_print_roam_msg_info(
&stats_info->roam_msg_info[i],
stats_info->vdev_id);
if (stats_info->data_11kv[i].present)
cm_roam_stats_print_11kv_info(
&stats_info->data_11kv[i],
stats_info->vdev_id);
}
}
if (!stats_info->num_tlv) {
if (stats_info->data_11kv[0].present)
cm_roam_stats_print_11kv_info(&stats_info->data_11kv[0],
stats_info->vdev_id);
if (stats_info->trigger[0].present)
cm_roam_stats_print_trigger_info(
&stats_info->trigger[0],
stats_info->vdev_id);
if (stats_info->scan[0].present &&
stats_info->trigger[0].present)
cm_roam_stats_print_scan_info(&stats_info->scan[0],
stats_info->vdev_id,
stats_info->trigger[0].trigger_reason,
stats_info->trigger[0].timestamp);
if (stats_info->btm_rsp[0].present)
cm_roam_stats_print_btm_rsp_info(
&stats_info->btm_rsp[0],
stats_info->vdev_id);
}
if (stats_info->roam_msg_info && stats_info->num_roam_msg_info &&
stats_info->num_roam_msg_info - rem_tlv) {
for (i = 0; i < (stats_info->num_roam_msg_info-rem_tlv); i++) {
if (stats_info->roam_msg_info[rem_tlv + i].present)
cm_roam_stats_print_roam_msg_info(
&stats_info->roam_msg_info[rem_tlv + i],
stats_info->vdev_id);
}
}
err:
if (stats_info->roam_msg_info)
qdf_mem_free(stats_info->roam_msg_info);
qdf_mem_free(stats_info);
return status;
}
#endif

View File

@@ -326,6 +326,61 @@ QDF_STATUS
wmi_extract_roam_scan_chan_list(wmi_unified_t wmi_handle,
uint8_t *event, uint32_t data_len,
struct cm_roam_scan_ch_resp **data);
/**
* wmi_unified_extract_roam_btm_response() - Extract BTM response
* @wmi: wmi handle
* @evt_buf: Pointer to the event buffer
* @dst: Pointer to destination structure to fill data
* @idx: TLV id
*
* Return: QDF_STATUS
*/
QDF_STATUS
wmi_unified_extract_roam_btm_response(wmi_unified_t wmi, void *evt_buf,
struct roam_btm_response_data *dst,
uint8_t idx);
/**
* wmi_unified_extract_roam_initial_info() - Extract initial info
* @wmi: wmi handle
* @evt_buf: Pointer to the event buffer
* @dst: Pointer to destination structure to fill data
* @idx: TLV id
*
* Return: QDF_STATUS
*/
QDF_STATUS
wmi_unified_extract_roam_initial_info(wmi_unified_t wmi, void *evt_buf,
struct roam_initial_data *dst,
uint8_t idx);
/**
* wmi_unified_extract_roam_msg_info() - Extract roam msg info
* @wmi: wmi handle
* @evt_buf: Pointer to the event buffer
* @dst: Pointer to destination structure to fill data
* @idx: TLV id
*
* Return: QDF_STATUS
*/
QDF_STATUS
wmi_unified_extract_roam_msg_info(wmi_unified_t wmi, void *evt_buf,
struct roam_msg_info *dst, uint8_t idx);
/**
* wmi_extract_roam_stats_event - Extract roam stats event
* @wmi_handle: WMI handle
* @event: Event data received from firmware
* @data_len: Event data length received from firmware
* @stats_info: Extract the event and fill in stats_info
*
* Return: QDF_STATUS
*/
QDF_STATUS
wmi_extract_roam_stats_event(wmi_unified_t wmi_handle,
uint8_t *event, uint32_t data_len,
struct roam_stats_event **stats_info);
#endif /* ROAM_TARGET_IF_CONVERGENCE */
#endif /* WLAN_FEATURE_ROAM_OFFLOAD */

View File

@@ -413,5 +413,53 @@ wmi_extract_roam_scan_chan_list(wmi_unified_t wmi_handle,
wmi_handle, event, data_len, data);
return QDF_STATUS_E_FAILURE;
}
QDF_STATUS
wmi_unified_extract_roam_btm_response(wmi_unified_t wmi, void *evt_buf,
struct roam_btm_response_data *dst,
uint8_t idx)
{
if (wmi->ops->extract_roam_btm_response_stats)
return wmi->ops->extract_roam_btm_response_stats(wmi, evt_buf,
dst, idx);
return QDF_STATUS_E_FAILURE;
}
QDF_STATUS
wmi_unified_extract_roam_initial_info(wmi_unified_t wmi, void *evt_buf,
struct roam_initial_data *dst,
uint8_t idx)
{
if (wmi->ops->extract_roam_initial_info)
return wmi->ops->extract_roam_initial_info(wmi, evt_buf,
dst, idx);
return QDF_STATUS_E_FAILURE;
}
QDF_STATUS
wmi_unified_extract_roam_msg_info(wmi_unified_t wmi, void *evt_buf,
struct roam_msg_info *dst, uint8_t idx)
{
if (wmi->ops->extract_roam_msg_info)
return wmi->ops->extract_roam_msg_info(wmi, evt_buf, dst, idx);
return QDF_STATUS_E_FAILURE;
}
QDF_STATUS
wmi_extract_roam_stats_event(wmi_unified_t wmi_handle,
uint8_t *event, uint32_t data_len,
struct roam_stats_event **stats_info)
{
if (wmi_handle->ops->extract_roam_stats_event)
return wmi_handle->ops->extract_roam_stats_event(wmi_handle,
event,
data_len,
stats_info);
return QDF_STATUS_E_FAILURE;
}
#endif /* ROAM_TARGET_IF_CONVERGENCE */
#endif

View File

@@ -2658,6 +2658,289 @@ extract_roam_scan_chan_list_tlv(wmi_unified_t wmi_handle,
*list = data;
return QDF_STATUS_SUCCESS;
}
/**
* extract_roam_stats_event_tlv() - Extract the roam stats event
* from the wmi_roam_stats_event_id
* @wmi_handle: wmi handle
* @evt_buf: Pointer to the event buffer
* @len: Data length
* @data: Double pointer to roam stats data
*/
static QDF_STATUS
extract_roam_stats_event_tlv(wmi_unified_t wmi_handle, uint8_t *evt_buf,
uint32_t len,
struct roam_stats_event **data)
{
WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf;
wmi_roam_stats_event_fixed_param *fixed_param;
struct roam_stats_event *stats_info;
struct roam_msg_info *roam_msg_info = NULL;
uint8_t vdev_id, i;
uint8_t num_tlv = 0, num_chan = 0, num_ap = 0, num_rpt = 0;
uint32_t rem_len;
QDF_STATUS status;
param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf;
if (!param_buf) {
wmi_err_rl("NULL event received from target");
return QDF_STATUS_E_INVAL;
}
fixed_param = param_buf->fixed_param;
if (!fixed_param) {
wmi_err_rl(" NULL fixed param");
return QDF_STATUS_E_INVAL;
}
vdev_id = fixed_param->vdev_id;
if (vdev_id >= WLAN_MAX_VDEVS) {
wmi_err_rl("Invalid vdev_id %d", vdev_id);
return QDF_STATUS_E_INVAL;
}
num_tlv = fixed_param->roam_scan_trigger_count;
if (num_tlv > MAX_ROAM_SCAN_STATS_TLV) {
wmi_err_rl("Limiting roam triggers to 5");
num_tlv = MAX_ROAM_SCAN_STATS_TLV;
}
rem_len = WMI_SVC_MSG_MAX_SIZE - sizeof(*fixed_param);
if (rem_len < num_tlv * sizeof(wmi_roam_trigger_reason)) {
wmi_err_rl("Invalid roam trigger data");
return QDF_STATUS_E_INVAL;
}
rem_len -= num_tlv * sizeof(wmi_roam_trigger_reason);
if (rem_len < num_tlv * sizeof(wmi_roam_scan_info)) {
wmi_err_rl("Invalid roam scan data");
return QDF_STATUS_E_INVAL;
}
rem_len -= num_tlv * sizeof(wmi_roam_scan_info);
if (rem_len < num_tlv * sizeof(wmi_roam_result)) {
wmi_err_rl("Invalid roam result data");
return QDF_STATUS_E_INVAL;
}
rem_len -= num_tlv * sizeof(wmi_roam_result);
if (rem_len < (num_tlv * sizeof(wmi_roam_neighbor_report_info))) {
wmi_err_rl("Invalid roam neighbor report data");
return QDF_STATUS_E_INVAL;
}
rem_len -= num_tlv * sizeof(wmi_roam_neighbor_report_info);
if (rem_len < (param_buf->num_roam_scan_chan_info *
sizeof(wmi_roam_scan_channel_info))) {
wmi_err_rl("Invalid roam chan data num_tlv:%d",
param_buf->num_roam_scan_chan_info);
return QDF_STATUS_E_INVAL;
}
rem_len -= param_buf->num_roam_scan_chan_info *
sizeof(wmi_roam_scan_channel_info);
if (rem_len < (param_buf->num_roam_ap_info *
sizeof(wmi_roam_ap_info))) {
wmi_err_rl("Invalid roam ap data num_tlv:%d",
param_buf->num_roam_ap_info);
return QDF_STATUS_E_INVAL;
}
rem_len -= param_buf->num_roam_ap_info * sizeof(wmi_roam_ap_info);
if (rem_len < (param_buf->num_roam_neighbor_report_chan_info *
sizeof(wmi_roam_neighbor_report_channel_info))) {
wmi_err_rl("Invalid roam neigb rpt chan data num_tlv:%d",
param_buf->num_roam_neighbor_report_chan_info);
return QDF_STATUS_E_INVAL;
}
rem_len -= param_buf->num_roam_neighbor_report_chan_info *
sizeof(wmi_roam_neighbor_report_channel_info);
if (rem_len < param_buf->num_roam_btm_response_info *
sizeof(wmi_roam_btm_response_info)) {
wmi_err_rl("Invalid btm rsp data");
return QDF_STATUS_E_INVAL;
}
rem_len -= param_buf->num_roam_btm_response_info *
sizeof(wmi_roam_btm_response_info);
if (rem_len < param_buf->num_roam_initial_info *
sizeof(wmi_roam_initial_info)) {
wmi_err_rl("Invalid Initial roam info");
return QDF_STATUS_E_INVAL;
}
rem_len -= param_buf->num_roam_initial_info *
sizeof(wmi_roam_initial_info);
if (rem_len < param_buf->num_roam_msg_info *
sizeof(wmi_roam_msg_info)) {
wmi_err_rl("Invalid roam msg info");
return QDF_STATUS_E_INVAL;
}
stats_info = qdf_mem_malloc(sizeof(struct roam_stats_event));
if (!stats_info) {
status = QDF_STATUS_E_NOMEM;
goto err;
}
*data = stats_info;
qdf_mem_set(stats_info, sizeof(struct roam_stats_event), 0);
stats_info->vdev_id = vdev_id;
stats_info->num_roam_msg_info = param_buf->num_roam_msg_info;
stats_info->num_tlv = num_tlv;
for (i = 0; i < num_tlv; i++) {
/*
* Roam Trigger id and that specific roam trigger related
* details.
*/
status = wmi_unified_extract_roam_trigger_stats(wmi_handle,
evt_buf,
&stats_info->trigger[i], i);
if (QDF_IS_STATUS_ERROR(status)) {
wmi_debug_rl("Extract roam trigger stats failed vdev %d at %d iteration",
vdev_id, i);
status = QDF_STATUS_E_INVAL;
goto err;
}
/* Roam scan related details - Scan channel, scan type .. */
status = wmi_unified_extract_roam_scan_stats(wmi_handle,
evt_buf,
&stats_info->scan[i], i,
num_chan, num_ap);
if (QDF_IS_STATUS_ERROR(status)) {
wmi_debug_rl("Roam scan stats extract failed vdev %d at %d iteration",
vdev_id, i);
status = QDF_STATUS_E_INVAL;
goto err;
}
num_chan += stats_info->scan[i].num_chan;
num_ap += stats_info->scan[i].num_ap;
/* Roam result - Success/Failure status, failure reason */
status = wmi_unified_extract_roam_result_stats(wmi_handle,
evt_buf,
&stats_info->result[i], i);
if (QDF_IS_STATUS_ERROR(status)) {
wmi_debug_rl("Roam result stats extract failed vdev %d at %d iteration",
vdev_id, i);
status = QDF_STATUS_E_INVAL;
goto err;
}
/* BTM resp info */
status = wmi_unified_extract_roam_btm_response(wmi_handle,
evt_buf,
&stats_info->btm_rsp[i],
i);
if (QDF_IS_STATUS_ERROR(status)) {
wmi_debug_rl("Roam btm rsp stats extract fail vdev %d at %d iteration",
vdev_id, i);
status = QDF_STATUS_E_INVAL;
goto err;
}
/* Initial Roam info */
status = wmi_unified_extract_roam_initial_info(wmi_handle,
evt_buf,
&stats_info->roam_init_info[i], i);
if (QDF_IS_STATUS_ERROR(status)) {
wmi_debug_rl("Initial roam stats extract fail vdev %d at %d iteration",
vdev_id, i);
status = QDF_STATUS_E_INVAL;
goto err;
}
}
if (!num_tlv) {
status = wmi_unified_extract_roam_11kv_stats(wmi_handle,
evt_buf,
&stats_info->data_11kv[0], 0, 0);
if (QDF_IS_STATUS_ERROR(status)) {
wmi_err("Roam 11kv stats extract failed vdev %d",
vdev_id);
status = QDF_STATUS_E_INVAL;
goto err;
}
status = wmi_unified_extract_roam_trigger_stats(wmi_handle,
evt_buf,
&stats_info->trigger[0], 0);
if (QDF_IS_STATUS_ERROR(status)) {
wmi_debug_rl("Extract roamtrigger stats failed vdev %d",
vdev_id);
status = QDF_STATUS_E_INVAL;
goto err;
}
status = wmi_unified_extract_roam_scan_stats(wmi_handle,
evt_buf,
&stats_info->scan[0],
0, 0, 0);
if (QDF_IS_STATUS_ERROR(status)) {
wmi_debug_rl("Roam scan stats extract failed vdev %d",
vdev_id);
status = QDF_STATUS_E_INVAL;
goto err;
}
status = wmi_unified_extract_roam_btm_response(wmi_handle,
evt_buf,
&stats_info->btm_rsp[0],
0);
if (QDF_IS_STATUS_ERROR(status)) {
wmi_debug_rl("Roam btm rsp stats extract fail vdev %d",
vdev_id);
status = QDF_STATUS_E_INVAL;
goto err;
}
}
if (param_buf->roam_msg_info && param_buf->num_roam_msg_info) {
roam_msg_info = qdf_mem_malloc(param_buf->num_roam_msg_info *
sizeof(*roam_msg_info));
if (!roam_msg_info) {
status = QDF_STATUS_E_NOMEM;
goto err;
}
stats_info->roam_msg_info = roam_msg_info;
for (i = 0; i < param_buf->num_roam_msg_info; i++) {
status = wmi_unified_extract_roam_msg_info(wmi_handle,
evt_buf,
&roam_msg_info[i], i);
if (QDF_IS_STATUS_ERROR(status)) {
wmi_err("roam msg stats extract fail vdev %d",
vdev_id);
status = QDF_STATUS_E_INVAL;
goto err;
}
if (roam_msg_info[i].present && i < num_tlv) {
/* BTM req/resp or Neighbor report/response info */
status = wmi_unified_extract_roam_11kv_stats(
wmi_handle,
evt_buf,
&stats_info->data_11kv[i],
i, num_rpt);
if (QDF_IS_STATUS_ERROR(status)) {
wmi_debug_rl("Roam 11kv stats extract fail vdev %d iter %d",
vdev_id, i);
status = QDF_STATUS_E_INVAL;
goto err;
}
num_rpt += stats_info->data_11kv[i].num_freq;
}
}
}
return QDF_STATUS_SUCCESS;
err:
if (stats_info) {
if (roam_msg_info)
qdf_mem_free(roam_msg_info);
qdf_mem_free(stats_info);
}
return status;
}
#endif
void wmi_roam_offload_attach_tlv(wmi_unified_t wmi_handle)
@@ -2675,6 +2958,7 @@ void wmi_roam_offload_attach_tlv(wmi_unified_t wmi_handle)
ops->extract_btm_bl_event = extract_btm_blacklist_event;
ops->extract_vdev_disconnect_event = extract_vdev_disconnect_event_tlv;
ops->extract_roam_scan_chan_list = extract_roam_scan_chan_list_tlv;
ops->extract_roam_stats_event = extract_roam_stats_event_tlv;
#endif /* ROAM_TARGET_IF_CONVERGENCE */
ops->send_set_ric_req_cmd = send_set_ric_req_cmd_tlv;
ops->send_process_roam_synch_complete_cmd =

View File

@@ -3363,17 +3363,18 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc,
wmi_roam_scan_chan_list_id,
wma_roam_scan_chan_list_event_handler,
WMA_RX_SERIALIZER_CTX);
#endif /* ROAM_TARGET_IF_CONVERGENCE */
wmi_unified_register_event_handler(wma_handle->wmi_handle,
wmi_roam_auth_offload_event_id,
wma_roam_auth_offload_event_handler,
WMA_RX_SERIALIZER_CTX);
wmi_unified_register_event_handler(wma_handle->wmi_handle,
wmi_roam_stats_event_id,
wma_roam_stats_event_handler,
WMA_RX_SERIALIZER_CTX);
#endif /* ROAM_TARGET_IF_CONVERGENCE */
wmi_unified_register_event_handler(wma_handle->wmi_handle,
wmi_roam_auth_offload_event_id,
wma_roam_auth_offload_event_handler,
WMA_RX_SERIALIZER_CTX);
wma_register_pmkid_req_event_handler(wma_handle);
#endif /* WLAN_FEATURE_ROAM_OFFLOAD */

View File

@@ -1525,7 +1525,6 @@ int wma_roam_scan_chan_list_event_handler(WMA_HANDLE handle,
return 0;
}
#endif
/**
* wma_get_trigger_detail_str - Return roam trigger string from the
@@ -2279,6 +2278,7 @@ err:
return -EINVAL;
}
#endif
#endif
/**
* wma_set_ric_req() - set ric request element