qcacld-3.0: Add support to parse roam frame info TLV

Add support to parse roam frame info TLV.
Add changes to send the BTM request logging event.

Change-Id: I24fab5fc0ec204fce74cf822742b5a44b0e7774f
CRs-Fixed: 3013489
This commit is contained in:
Pragaspathi Thilagaraj
2021-09-07 13:07:35 +05:30
committed by Madan Koyyalamudi
parent 1b47a5b316
commit db383df8c9
8 changed files with 637 additions and 14 deletions

View File

@@ -2603,6 +2603,7 @@ struct wlan_mlme_sae_single_pmk {
struct mlme_pmk_info pmk_info;
};
#define ROAM_FRAME_INFO_FRAME_TYPE_EXT 3
/**
* struct mlme_roam_debug_info - Roam debug information storage structure.
* @trigger: Roam trigger related data
@@ -2612,6 +2613,8 @@ struct wlan_mlme_sae_single_pmk {
* @btm_rsp: BTM response information
* @roam_init_info: Roam initial info
* @roam_msg_info: roam related message information
* @frame_info: Information related to mgmt/eapol frames exchanged
* during roaming.
*/
struct mlme_roam_debug_info {
struct wmi_roam_trigger_info trigger;
@@ -2621,6 +2624,7 @@ struct mlme_roam_debug_info {
struct roam_btm_response_data btm_rsp;
struct roam_initial_data roam_init_info;
struct roam_msg_info roam_msg_info;
struct roam_frame_info frame_info[WLAN_ROAM_MAX_FRAME_INFO];
};
/**

View File

@@ -41,6 +41,7 @@
#include "connection_mgr/core/src/wlan_cm_main.h"
#include "connection_mgr/core/src/wlan_cm_sm.h"
#include "wlan_reg_ucfg_api.h"
#include "wlan_connectivity_logging.h"
#ifdef WLAN_FEATURE_SAE
#define CM_IS_FW_FT_SAE_SUPPORTED(fw_akm_bitmap) \
@@ -4927,4 +4928,218 @@ bool cm_roam_offload_enabled(struct wlan_objmgr_psoc *psoc)
return val;
}
#ifdef WLAN_FEATURE_CONNECTIVITY_LOGGING
static enum wlan_main_tag
cm_roam_get_tag(enum mgmt_subtype subtype, bool is_tx)
{
switch (subtype) {
case MGMT_SUBTYPE_ASSOC_REQ:
return WLAN_ASSOC_REQ;
case MGMT_SUBTYPE_ASSOC_RESP:
return WLAN_ASSOC_RSP;
case MGMT_SUBTYPE_REASSOC_REQ:
return WLAN_ASSOC_REQ;
case MGMT_SUBTYPE_REASSOC_RESP:
return WLAN_ASSOC_RSP;
case MGMT_SUBTYPE_DISASSOC:
if (is_tx)
return WLAN_DISASSOC_TX;
else
return WLAN_DISASSOC_RX;
break;
case MGMT_SUBTYPE_AUTH:
if (is_tx)
return WLAN_AUTH_REQ;
else
return WLAN_AUTH_RESP;
break;
case MGMT_SUBTYPE_DEAUTH:
if (is_tx)
return WLAN_DEAUTH_TX;
else
return WLAN_DEAUTH_RX;
default:
break;
}
return WLAN_TAG_MAX;
}
static enum wlan_main_tag
cm_roam_get_eapol_tag(enum wlan_roam_frame_subtype subtype)
{
switch (subtype) {
case ROAM_FRAME_SUBTYPE_M1:
return WLAN_EAPOL_M1;
case ROAM_FRAME_SUBTYPE_M2:
return WLAN_EAPOL_M2;
case ROAM_FRAME_SUBTYPE_M3:
return WLAN_EAPOL_M3;
case ROAM_FRAME_SUBTYPE_M4:
return WLAN_EAPOL_M4;
case ROAM_FRAME_SUBTYPE_GTK_M1:
return WLAN_GTK_M1;
case ROAM_FRAME_SUBTYPE_GTK_M2:
return WLAN_GTK_M2;
default:
break;
}
return WLAN_TAG_MAX;
}
QDF_STATUS
cm_roam_btm_query_event(struct wmi_neighbor_report_data *btm_data,
uint8_t vdev_id)
{
struct wlan_log_record *log_record = NULL;
QDF_STATUS status = QDF_STATUS_SUCCESS;
log_record = qdf_mem_malloc(sizeof(*log_record));
if (!log_record)
return QDF_STATUS_E_NOMEM;
log_record->log_subtype = WLAN_BTM_QUERY;
log_record->timestamp_us = qdf_get_time_of_the_day_ms() * 1000;
log_record->fw_timestamp_us = btm_data->timestamp * 1000;
log_record->vdev_id = vdev_id;
status = wlan_connectivity_log_enqueue(log_record);
qdf_mem_free(log_record);
return status;
}
QDF_STATUS
cm_roam_btm_resp_event(struct roam_btm_response_data *btm_data,
uint8_t vdev_id, bool is_wtc)
{
struct wlan_log_record *log_record = NULL;
QDF_STATUS status = QDF_STATUS_SUCCESS;
log_record = qdf_mem_malloc(sizeof(*log_record));
if (!log_record)
return QDF_STATUS_E_NOMEM;
if (is_wtc)
log_record->log_subtype = WLAN_ROAM_WTC;
else
log_record->log_subtype = WLAN_BTM_RESP;
log_record->timestamp_us = qdf_get_time_of_the_day_ms() * 1000;
log_record->fw_timestamp_us = btm_data->timestamp * 1000;
log_record->vdev_id = vdev_id;
log_record->btm_info.token = btm_data->btm_resp_dialog_token;
log_record->btm_info.btm_status_code = btm_data->btm_status;
log_record->btm_info.btm_delay = btm_data->btm_delay;
log_record->btm_info.target_bssid = btm_data->target_bssid;
if (is_wtc) {
log_record->btm_info.reason = btm_data->vsie_reason;
log_record->btm_info.wtc_duration = btm_data->btm_delay;
}
status = wlan_connectivity_log_enqueue(log_record);
qdf_mem_free(log_record);
return status;
}
/**
* cm_roam_btm_candidate_event() - Send BTM roam candidate logging event
* @btm_data: BTM data
* @vdev_id: Vdev id
*
* Return: QDF_STATUS
*/
static QDF_STATUS
cm_roam_btm_candidate_event(struct wmi_btm_req_candidate_info *btm_data,
uint8_t vdev_id)
{
struct wlan_log_record *log_record = NULL;
QDF_STATUS status = QDF_STATUS_SUCCESS;
log_record = qdf_mem_malloc(sizeof(*log_record));
if (!log_record)
return QDF_STATUS_E_NOMEM;
log_record->log_subtype = WLAN_BTM_REQ_CANDI;
log_record->timestamp_us = qdf_get_time_of_the_day_ms() * 1000;
log_record->fw_timestamp_us = btm_data->timestamp * 1000;
log_record->vdev_id = vdev_id;
log_record->btm_cand.preference = btm_data->preference;
log_record->btm_cand.bssid = btm_data->candidate_bssid;
status = wlan_connectivity_log_enqueue(log_record);
qdf_mem_free(log_record);
return status;
}
QDF_STATUS
cm_roam_btm_req_event(struct wmi_roam_btm_trigger_data *btm_data,
uint8_t vdev_id)
{
struct wlan_log_record *log_record = NULL;
QDF_STATUS status = QDF_STATUS_SUCCESS;
uint8_t i;
log_record = qdf_mem_malloc(sizeof(*log_record));
if (!log_record)
return QDF_STATUS_E_NOMEM;
log_record->log_subtype = WLAN_BTM_REQ;
log_record->timestamp_us = qdf_get_time_of_the_day_ms() * 1000;
log_record->fw_timestamp_us = btm_data->timestamp * 1000;
log_record->vdev_id = vdev_id;
log_record->btm_info.token = btm_data->token;
log_record->btm_info.mode = btm_data->btm_request_mode;
log_record->btm_info.disassoc_timer = btm_data->disassoc_timer;
log_record->btm_info.validity_timer = btm_data->validity_interval;
log_record->btm_info.candidate_list_count =
btm_data->candidate_list_count;
status = wlan_connectivity_log_enqueue(log_record);
for (i = 0; i < log_record->btm_info.candidate_list_count; i++)
cm_roam_btm_candidate_event(&btm_data->btm_cand[i], vdev_id);
qdf_mem_free(log_record);
return status;
}
QDF_STATUS
cm_roam_mgmt_frame_event(struct roam_frame_info *frame_data, uint8_t vdev_id)
{
struct wlan_log_record *log_record = NULL;
QDF_STATUS status = QDF_STATUS_SUCCESS;
log_record = qdf_mem_malloc(sizeof(*log_record));
if (!log_record)
return QDF_STATUS_E_NOMEM;
log_record->timestamp_us = qdf_get_time_of_the_day_ms() * 1000;
log_record->fw_timestamp_us = frame_data->timestamp * 1000;
log_record->vdev_id = vdev_id;
log_record->pkt_info.seq_num = frame_data->seq_num;
log_record->pkt_info.rssi = frame_data->rssi;
log_record->pkt_info.tx_status = frame_data->tx_status;
log_record->pkt_info.frame_status_code = frame_data->status_code;
if (frame_data->type == ROAM_FRAME_INFO_FRAME_TYPE_EXT)
log_record->log_subtype =
cm_roam_get_eapol_tag(frame_data->subtype);
else
log_record->log_subtype = cm_roam_get_tag(frame_data->subtype,
frame_data->is_req);
status = wlan_connectivity_log_enqueue(log_record);
qdf_mem_free(log_record);
return status;
}
#endif /* WLAN_FEATURE_CONNECTIVITY_LOGGING */
#endif /* WLAN_FEATURE_ROAM_OFFLOAD */

View File

@@ -255,4 +255,79 @@ bool cm_is_auth_type_11r(struct wlan_mlme_psoc_ext_obj *mlme_obj,
void cm_update_owe_info(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_connect_resp *rsp, uint8_t vdev_id);
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
#ifdef WLAN_FEATURE_CONNECTIVITY_LOGGING
/**
* cm_roam_mgmt_frame_event() - Roam management frame event
* @frame_data: frame_data
* @vdev_id: vdev_id
*
* Return: QDF_STATUS
*/
QDF_STATUS
cm_roam_mgmt_frame_event(struct roam_frame_info *frame_data, uint8_t vdev_id);
/**
* cm_roam_btm_req_event - Send BTM request related logging event
* @btm_data: BTM trigger related data
* @vdev_id: Vdev id
*
* Return: QDF_STATUS
*/
QDF_STATUS
cm_roam_btm_req_event(struct wmi_roam_btm_trigger_data *btm_data,
uint8_t vdev_id);
/**
* cm_roam_btm_resp_event() - Send BTM response logging event
* @btm_data: BTM response data
* @vdev_id: Vdev id
* @is_wtc: Is WTC or BTM response
*
* Return: QDF_STATUS
*/
QDF_STATUS
cm_roam_btm_resp_event(struct roam_btm_response_data *btm_data,
uint8_t vdev_id, bool is_wtc);
/**
* cm_roam_btm_query_event() - Send BTM query logging event
* @btm_data: BTM data
* @vdev_id: Vdev id
*
* Return: QDF_STATUS
*/
QDF_STATUS
cm_roam_btm_query_event(struct wmi_neighbor_report_data *btm_data,
uint8_t vdev_id);
#else
static inline QDF_STATUS
cm_roam_mgmt_frame_event(struct roam_frame_info *frame_data, uint8_t vdev_id)
{
return QDF_STATUS_E_NOSUPPORT;
}
static inline QDF_STATUS
cm_roam_btm_req_event(struct wmi_roam_btm_trigger_data *btm_data,
uint8_t vdev_id)
{
return QDF_STATUS_E_NOSUPPORT;
}
static inline QDF_STATUS
cm_roam_btm_resp_event(struct roam_btm_response_data *btm_data,
uint8_t vdev_id, bool is_wtc)
{
return QDF_STATUS_E_NOSUPPORT;
}
static inline QDF_STATUS
cm_roam_btm_query_event(struct wmi_neighbor_report_data *btm_data,
uint8_t vdev_id)
{
return QDF_STATUS_E_NOSUPPORT;
}
#endif /* FEATURE_CONNECTIVITY_LOGGING */
#endif /* FEATURE_ROAM_OFFLOAD */
#endif /* _WLAN_CM_ROAM_OFFLOAD_H_ */

View File

@@ -762,6 +762,21 @@ wlan_cm_roam_extract_roam_msg_info(wmi_unified_t wmi, void *evt_buf,
uint32_t wlan_cm_get_roam_band_value(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id);
/**
* wlan_cm_roam_extract_frame_info - Extract the roam frame info TLV
* @wmi: wmi handle
* @evt_buf: Pointer to the event buffer
* @dst: Destination buffer
* @idx: TLV index
* @num_frames: Number of frame info TLVs
*
* Return: QDF_STATUS
*/
QDF_STATUS
wlan_cm_roam_extract_frame_info(wmi_unified_t wmi, void *evt_buf,
struct roam_frame_info *dst, uint8_t idx,
uint8_t num_frames);
/**
* wlan_cm_roam_activate_pcl_per_vdev() - Set the PCL command to be sent per
* vdev instead of pdev.
@@ -1105,6 +1120,13 @@ wlan_cm_roam_extract_btm_response(wmi_unified_t wmi, void *evt_buf,
return QDF_STATUS_E_NOSUPPORT;
}
static inline QDF_STATUS
wlan_cm_roam_extract_frame_info(wmi_unified_t wmi, void *evt_buf,
struct roam_frame_info *dst, uint8_t idx)
{
return QDF_STATUS_E_NOSUPPORT;
}
static inline QDF_STATUS
wlan_cm_roam_extract_roam_initial_info(wmi_unified_t wmi, void *evt_buf,
struct roam_initial_data *dst,

View File

@@ -168,6 +168,60 @@
#define MIN_RSSI_2G_TO_5G_ROAM 2
#define CM_CFG_VALID_CHANNEL_LIST_LEN 100
/**
* enum roam_trigger_sub_reason - Roam trigger sub reasons
* @ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER: Roam scan triggered due to
* periodic timer expiry
* @ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER: Roam scan triggered due to
* inactivity detection and connected AP RSSI falls below a certain threshold
* @ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER: Roam scan triggered due to BTM
* Disassoc Imminent timeout
* @ROAM_TRIGGER_SUB_REASON_FULL_SCAN: Roam scan triggered due to partial scan
* failure
* @ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC: Roam scan triggered due to Low
* rssi periodic timer
* @ROAM_TRIGGER_SUB_REASON_CU_PERIODIC: Roam scan triggered due to CU periodic
* timer
* @ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY: Roam scan
* triggered due to periodic timer after device inactivity after low rssi
* trigger
* @ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU: Roam scan
* triggered due to first periodic timer exiry when full scan count is not 0
* and roam scan trigger is CU load
* @ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU: Roam scan triggered due to
* first periodic timer exiry when full scan count is 0 and roam scan trigger
* is CU load
*/
enum roam_trigger_sub_reason {
ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER = 1,
ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_LOW_RSSI,
ROAM_TRIGGER_SUB_REASON_BTM_DI_TIMER,
ROAM_TRIGGER_SUB_REASON_FULL_SCAN,
ROAM_TRIGGER_SUB_REASON_LOW_RSSI_PERIODIC,
ROAM_TRIGGER_SUB_REASON_CU_PERIODIC,
ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY,
ROAM_TRIGGER_SUB_REASON_PERIODIC_TIMER_AFTER_INACTIVITY_CU,
ROAM_TRIGGER_SUB_REASON_INACTIVITY_TIMER_CU,
};
/**
* enum wlan_roam_frame_subtype - Roam frame subtypes
* @ROAM_FRAME_SUBTYPE_M1: EAPOL M1 Frame
* @ROAM_FRAME_SUBTYPE_M2: EAPOL M2 Frame
* @ROAM_FRAME_SUBTYPE_M3: EAPOL M3 Frame
* @ROAM_FRAME_SUBTYPE_M4: EAPOL M4 Frame
* @ROAM_FRAME_SUBTYPE_GTK_M1: GTK M1 Frame
* @ROAM_FRAME_SUBTYPE_GTK_M2: GTK M2 Frame
*/
enum wlan_roam_frame_subtype {
ROAM_FRAME_SUBTYPE_M1 = 1,
ROAM_FRAME_SUBTYPE_M2,
ROAM_FRAME_SUBTYPE_M3,
ROAM_FRAME_SUBTYPE_M4,
ROAM_FRAME_SUBTYPE_GTK_M1,
ROAM_FRAME_SUBTYPE_GTK_M2,
};
/**
* struct cm_roam_neighbor_report_offload_params - neighbor report offload
* parameters
@@ -1638,6 +1692,8 @@ enum roam_offload_state {
* @target_bssid: AP MAC address
* @vsie_reason: Vsie_reason value
* @timestamp: This timestamp indicates the time when btm rsp is sent
* @btm_resp_dialog_token: Dialog token
* @btm_delay: BTM bss termination delay
*/
struct roam_btm_response_data {
bool present;
@@ -1645,6 +1701,8 @@ struct roam_btm_response_data {
struct qdf_mac_addr target_bssid;
uint32_t vsie_reason;
uint32_t timestamp;
uint16_t btm_resp_dialog_token;
uint8_t btm_delay;
};
/**
@@ -1682,6 +1740,34 @@ struct roam_msg_info {
uint32_t msg_param2;
};
/**
* struct roam_frame_info - Structure to hold the mgmt frame/eapol frame
* related info exchanged during roaming.
* @present: Flag to indicate if roam frame info TLV is present
* @timestamp: Fw timestamp at which the frame was Tx/Rx'ed
* @type: Frame Type
* @subtype: Frame subtype
* @is_req: Frame is request frame or response frame
* @seq_num: Frame sequence number from the 802.11 header
* @status_code: Status code from 802.11 spec, section 9.4.1.9
* @tx_status: Frame TX status defined by enum qdf_dp_tx_rx_status
* applicable only for tx frames
* @rssi: Frame rssi
* @retry_count: Frame retry count
*/
struct roam_frame_info {
bool present;
uint32_t timestamp;
uint8_t type;
uint8_t subtype;
uint8_t is_req;
enum qdf_dp_tx_rx_status tx_status;
uint16_t seq_num;
uint16_t status_code;
int32_t rssi;
uint16_t retry_count;
};
/**
* enum wlan_cm_rso_control_requestor - Driver disabled roaming requestor that
* will request the roam module to disable roaming based on the mlme operation

View File

@@ -379,6 +379,18 @@ uint32_t wlan_cm_get_roam_band_value(struct wlan_objmgr_psoc *psoc,
return band_mask;
}
QDF_STATUS
wlan_cm_roam_extract_frame_info(wmi_unified_t wmi, void *evt_buf,
struct roam_frame_info *dst, uint8_t idx,
uint8_t num_frames)
{
if (wmi->ops->extract_roam_msg_info)
return wmi->ops->extract_roam_frame_info(wmi, evt_buf,
dst, idx, num_frames);
return QDF_STATUS_E_FAILURE;
}
void wlan_cm_roam_activate_pcl_per_vdev(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id, bool pcl_per_vdev)
{
@@ -2687,7 +2699,7 @@ cm_roam_stats_print_trigger_info(struct wmi_roam_trigger_info *data,
*/
static void
cm_roam_stats_print_btm_rsp_info(struct roam_btm_response_data *data,
uint8_t vdev_id)
uint8_t vdev_id, bool is_wtc)
{
char time[TIME_STRING_LEN];
@@ -2696,6 +2708,7 @@ cm_roam_stats_print_btm_rsp_info(struct roam_btm_response_data *data,
QDF_MAC_ADDR_FMT, time, vdev_id, data->btm_status,
data->vsie_reason,
QDF_MAC_ADDR_REF(data->target_bssid.bytes));
cm_roam_btm_resp_event(data, vdev_id, is_wtc);
}
/**
@@ -2993,10 +3006,16 @@ cm_roam_stats_event_handler(struct wlan_objmgr_psoc *psoc,
(stats_info->trigger[i].trigger_reason ==
ROAM_TRIGGER_REASON_WTC_BTM ||
stats_info->trigger[i].trigger_reason ==
ROAM_TRIGGER_REASON_BTM)))
ROAM_TRIGGER_REASON_BTM))) {
bool is_wtc =
(stats_info->trigger[i].trigger_reason ==
ROAM_TRIGGER_REASON_WTC_BTM);
cm_roam_stats_print_btm_rsp_info(
&stats_info->btm_rsp[i],
stats_info->vdev_id);
&stats_info->btm_rsp[i],
stats_info->vdev_id,
is_wtc);
}
if (stats_info->roam_init_info[i].present)
cm_roam_stats_print_roam_initial_info(

View File

@@ -1618,6 +1618,8 @@ extract_roam_btm_response_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf,
dst->target_bssid.bytes);
dst->vsie_reason = src_data->vsie_reason;
dst->timestamp = src_data->timestamp;
dst->btm_resp_dialog_token = src_data->btm_resp_dialog_token;
dst->btm_delay = src_data->btm_resp_bss_termination_delay;
return QDF_STATUS_SUCCESS;
}
@@ -1690,6 +1692,112 @@ extract_roam_msg_info_tlv(wmi_unified_t wmi_handle, void *evt_buf,
return QDF_STATUS_SUCCESS;
}
static enum wlan_roam_frame_subtype
wmi_get_converted_roam_eapol_subtype(
WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_SUBTYPE eapol_subtype)
{
switch (eapol_subtype) {
case WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_SUBTYPE_M1:
return ROAM_FRAME_SUBTYPE_M1;
case WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_SUBTYPE_M2:
return ROAM_FRAME_SUBTYPE_M2;
case WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_SUBTYPE_M3:
return ROAM_FRAME_SUBTYPE_M3;
case WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_SUBTYPE_M4:
return ROAM_FRAME_SUBTYPE_M4;
case WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_SUBTYPE_GTK_M1:
return ROAM_FRAME_SUBTYPE_GTK_M1;
case WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_SUBTYPE_GTK_M2:
return ROAM_FRAME_SUBTYPE_GTK_M2;
default:
break;
}
return 0;
}
static enum qdf_dp_tx_rx_status
wmi_get_converted_tx_status(
WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS roam_tx_status)
{
switch (roam_tx_status) {
case WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_ACK:
return QDF_TX_RX_STATUS_OK;
case WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_NO_ACK:
return QDF_TX_RX_STATUS_NO_ACK;
case WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT_STATUS_TX_FAIL:
return QDF_TX_RX_STATUS_DROP;
default:
break;
}
return QDF_TX_RX_STATUS_INVALID;
}
/**
* extract_roam_frame_info_tlv() - Extract the frame exchanges during roaming
* info from the WMI_ROAM_STATS_EVENTID
* @wmi_handle: wmi handle
* @evt_buf: Pointer to the event buffer
* @dst: Pointer to destination structure to fill data
* @idx: TLV id
* @num_frames: Number of Frame TLVs to be extracted
*/
static QDF_STATUS
extract_roam_frame_info_tlv(wmi_unified_t wmi_handle, void *evt_buf,
struct roam_frame_info *dst, uint8_t frame_idx,
uint8_t num_frames)
{
WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf;
wmi_roam_frame_info *src_data = NULL;
uint8_t i, subtype;
param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf;
if (!param_buf || !param_buf->roam_frame_info ||
!param_buf->num_roam_frame_info ||
(frame_idx + num_frames) >= param_buf->num_roam_frame_info) {
wmi_debug("Empty roam_frame_info param buf frame_idx:%d num_frames:%d",
frame_idx, num_frames);
return QDF_STATUS_SUCCESS;
}
src_data = &param_buf->roam_frame_info[frame_idx];
if (num_frames > WLAN_ROAM_MAX_FRAME_INFO)
num_frames = WLAN_ROAM_MAX_FRAME_INFO;
for (i = 0; i < num_frames; i++) {
dst->present = true;
dst->timestamp = src_data->timestamp;
dst->type = WMI_GET_BITS(src_data->frame_info, 0, 2);
subtype = WMI_GET_BITS(src_data->frame_info, 2, 4);
if (dst->type == WMI_ROAM_FRAME_INFO_FRAME_TYPE_EXT) {
dst->type = ROAM_FRAME_INFO_FRAME_TYPE_EXT;
dst->subtype =
wmi_get_converted_roam_eapol_subtype(subtype);
} else {
dst->subtype = subtype;
}
dst->is_req = WMI_GET_BITS(src_data->frame_info, 6, 1);
dst->seq_num = WMI_GET_BITS(src_data->frame_info, 7, 16);
dst->status_code = src_data->status_code;
if (dst->is_req)
dst->tx_status = wmi_get_converted_tx_status(
src_data->status_code);
dst->retry_count = src_data->retry_count;
dst->rssi = (-1) * src_data->rssi_dbm_abs;
dst++;
src_data++;
}
return QDF_STATUS_SUCCESS;
}
#ifdef ROAM_TARGET_IF_CONVERGENCE
static void
wmi_extract_pdev_hw_mode_trans_ind(
@@ -3145,6 +3253,7 @@ void wmi_roam_offload_attach_tlv(wmi_unified_t wmi_handle)
extract_roam_btm_response_stats_tlv;
ops->extract_roam_initial_info = extract_roam_initial_info_tlv;
ops->extract_roam_msg_info = extract_roam_msg_info_tlv;
ops->extract_roam_frame_info = extract_roam_frame_info_tlv;
#ifdef ROAM_TARGET_IF_CONVERGENCE
ops->extract_roam_sync_event = extract_roam_sync_event_tlv;
ops->extract_roam_sync_frame_event = extract_roam_sync_frame_event_tlv;

View File

@@ -67,6 +67,7 @@
#include "wlan_reg_services_api.h"
#include "wlan_roam_debug.h"
#include "wlan_mlme_public_struct.h"
#include "wlan_mgmt_txrx_utils_api.h"
/* This is temporary, should be removed */
#include "ol_htt_api.h"
@@ -1566,7 +1567,8 @@ int wma_roam_scan_chan_list_event_handler(WMA_HANDLE handle,
* Return: None
*/
static void
wma_get_trigger_detail_str(struct wmi_roam_trigger_info *roam_info, char *buf)
wma_get_trigger_detail_str(struct wmi_roam_trigger_info *roam_info, char *buf,
uint8_t vdev_id)
{
uint16_t buf_cons, buf_left = MAX_ROAM_DEBUG_BUF_SIZE;
char *temp = buf;
@@ -1597,6 +1599,9 @@ wma_get_trigger_detail_str(struct wmi_roam_trigger_info *roam_info, char *buf)
case WMI_ROAM_TRIGGER_REASON_BTC:
return;
case WMI_ROAM_TRIGGER_REASON_BTM:
roam_info->btm_trig_data.timestamp = roam_info->timestamp;
cm_roam_btm_req_event(&roam_info->btm_trig_data, vdev_id);
buf_cons = qdf_snprint(temp, buf_left,
"Req_mode: %d Disassoc_timer: %d",
roam_info->btm_trig_data.btm_request_mode,
@@ -1696,7 +1701,7 @@ wma_rso_print_trigger_info(struct wmi_roam_trigger_info *data, uint8_t vdev_id)
if (!buf)
return;
wma_get_trigger_detail_str(data, buf);
wma_get_trigger_detail_str(data, buf, vdev_id);
mlme_get_converted_timestamp(data->timestamp, time);
wma_nofl_info("%s [ROAM_TRIGGER]: VDEV[%d] %s", time, vdev_id, buf);
@@ -1707,6 +1712,7 @@ wma_rso_print_trigger_info(struct wmi_roam_trigger_info *data, uint8_t vdev_id)
* wma_rso_print_btm_rsp_info - BTM RSP related details
* @data: Pointer to the btm rsp data
* @vdev_id: vdev id
* @is_wtc: is wtc or btm response frame
*
* Prints the vdev, btm status, target_bssid and vsie reason
*
@@ -1714,7 +1720,7 @@ wma_rso_print_trigger_info(struct wmi_roam_trigger_info *data, uint8_t vdev_id)
*/
static void
wma_rso_print_btm_rsp_info(struct roam_btm_response_data *data,
uint8_t vdev_id)
uint8_t vdev_id, uint8_t is_wtc)
{
char time[TIME_STRING_LEN];
@@ -1722,6 +1728,7 @@ wma_rso_print_btm_rsp_info(struct roam_btm_response_data *data,
wma_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_btm_resp_event(data, vdev_id, is_wtc);
}
/**
@@ -1955,6 +1962,8 @@ wma_rso_print_11kv_info(struct wmi_neighbor_report_data *neigh_rpt,
mlme_get_converted_timestamp(neigh_rpt->req_time, time);
wma_nofl_info("%s [%s] VDEV[%d]", time,
(type == 1) ? "BTM_QUERY" : "NEIGH_RPT_REQ", vdev_id);
if (type == 1)
cm_roam_btm_query_event(neigh_rpt, vdev_id);
if (neigh_rpt->resp_time) {
mlme_get_converted_timestamp(neigh_rpt->resp_time, time1);
@@ -1969,6 +1978,47 @@ wma_rso_print_11kv_info(struct wmi_neighbor_report_data *neigh_rpt,
qdf_mem_free(buf);
}
static char *
wma_get_frame_subtype_str(enum mgmt_subtype frame_subtype)
{
switch (frame_subtype) {
case MGMT_SUBTYPE_ASSOC_REQ:
return "ASSOC";
case MGMT_SUBTYPE_ASSOC_RESP:
return "ASSOC";
case MGMT_SUBTYPE_REASSOC_REQ:
return "REASSOC";
case MGMT_SUBTYPE_REASSOC_RESP:
return "REASSOC";
case MGMT_SUBTYPE_DISASSOC:
return "DISASSOC";
case MGMT_SUBTYPE_AUTH:
return "AUTH";
case MGMT_SUBTYPE_DEAUTH:
return "DEAUTH";
default:
break;
}
return "Invalid frm";
}
static void
wma_rso_print_frame_info(struct roam_frame_info *frame_data, uint8_t vdev_id)
{
char time[TIME_STRING_LEN];
if (!frame_data->present)
return;
mlme_get_converted_timestamp(frame_data->timestamp, time);
wma_nofl_info("%s [%s %s] VDEV[%d] status:%d seq_num:%d", time,
wma_get_frame_subtype_str(frame_data->subtype),
frame_data->is_req ? "REQ" : "RESP", vdev_id,
frame_data->status_code, frame_data->seq_num);
cm_roam_mgmt_frame_event(frame_data, vdev_id);
}
int wma_roam_stats_event_handler(WMA_HANDLE handle, uint8_t *event,
uint32_t len)
{
@@ -1976,8 +2026,9 @@ int wma_roam_stats_event_handler(WMA_HANDLE handle, uint8_t *event,
WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf;
wmi_roam_stats_event_fixed_param *fixed_param;
struct mlme_roam_debug_info *roam_info = NULL;
uint8_t vdev_id, i;
uint8_t vdev_id, i, k;
uint8_t num_tlv = 0, num_chan = 0, num_ap = 0, num_rpt = 0, rem_tlv = 0;
uint8_t num_frames = 0, num_btm = 0;
uint32_t rem_len;
QDF_STATUS status;
@@ -2079,6 +2130,14 @@ int wma_roam_stats_event_handler(WMA_HANDLE handle, uint8_t *event,
goto err;
}
rem_len -= param_buf->num_roam_msg_info *
sizeof(wmi_roam_msg_info);
if (rem_len < param_buf->num_roam_frame_info *
sizeof(wmi_roam_frame_info)) {
wma_err_rl("Invalid roam frm info");
goto err;
}
for (i = 0; i < num_tlv; i++) {
roam_info = qdf_mem_malloc(sizeof(*roam_info));
if (!roam_info)
@@ -2090,7 +2149,8 @@ int wma_roam_stats_event_handler(WMA_HANDLE handle, uint8_t *event,
*/
status = wmi_unified_extract_roam_trigger_stats(
wma->wmi_handle, event,
&roam_info->trigger, i);
&roam_info->trigger, i,
num_btm);
if (QDF_IS_STATUS_ERROR(status)) {
wma_debug_rl("Extract roam trigger stats failed vdev %d at %d iteration",
vdev_id, i);
@@ -2098,6 +2158,10 @@ int wma_roam_stats_event_handler(WMA_HANDLE handle, uint8_t *event,
return -EINVAL;
}
if (roam_info->trigger.trigger_reason ==
WMI_ROAM_TRIGGER_REASON_BTM)
num_btm += roam_info->trigger.btm_trig_data.candidate_list_count;
if (roam_info->trigger.present) {
wma_rso_print_trigger_info(&roam_info->trigger,
vdev_id);
@@ -2141,6 +2205,26 @@ int wma_roam_stats_event_handler(WMA_HANDLE handle, uint8_t *event,
roam_info->result.fail_reason,
ROAM_FAIL_REASON);
}
status = wlan_cm_roam_extract_frame_info(
wma->wmi_handle, event,
roam_info->frame_info, num_frames,
roam_info->scan.frame_info_count);
if (QDF_IS_STATUS_ERROR(status)) {
wma_debug_rl("Roam frame extract failed vdev %d at %d iteration",
vdev_id, i);
qdf_mem_free(roam_info);
return -EINVAL;
}
num_frames += roam_info->scan.frame_info_count;
if (roam_info->scan.frame_info_count) {
for (k = 0; k <= roam_info->scan.frame_info_count; k++)
wma_rso_print_frame_info(
&roam_info->frame_info[k],
vdev_id);
}
/* BTM resp info */
status = wlan_cm_roam_extract_btm_response(wma->wmi_handle,
event,
@@ -2163,9 +2247,13 @@ int wma_roam_stats_event_handler(WMA_HANDLE handle, uint8_t *event,
(roam_info->trigger.trigger_reason ==
WMI_ROAM_TRIGGER_REASON_WTC_BTM ||
roam_info->trigger.trigger_reason ==
WMI_ROAM_TRIGGER_REASON_BTM)))
WMI_ROAM_TRIGGER_REASON_BTM))) {
bool is_wtc =
(roam_info->trigger.trigger_reason ==
ROAM_TRIGGER_REASON_WTC_BTM);
wma_rso_print_btm_rsp_info(&roam_info->btm_rsp,
vdev_id);
vdev_id, is_wtc);
}
/* Initial Roam info */
status = wlan_cm_roam_extract_roam_initial_info(
@@ -2234,7 +2322,7 @@ int wma_roam_stats_event_handler(WMA_HANDLE handle, uint8_t *event,
status = wmi_unified_extract_roam_trigger_stats(
wma->wmi_handle, event,
&roam_info->trigger, 0);
&roam_info->trigger, 0, 0);
if (QDF_IS_STATUS_ERROR(status)) {
wma_debug_rl("Extract roam trigger stats failed vdev %d",
vdev_id);
@@ -2273,9 +2361,14 @@ int wma_roam_stats_event_handler(WMA_HANDLE handle, uint8_t *event,
return -EINVAL;
}
if (roam_info->btm_rsp.present)
if (roam_info->btm_rsp.present) {
bool is_wtc =
(roam_info->trigger.present &&
roam_info->trigger.trigger_reason ==
ROAM_TRIGGER_REASON_WTC_BTM);
wma_rso_print_btm_rsp_info(&roam_info->btm_rsp,
vdev_id);
vdev_id, is_wtc);
}
qdf_mem_free(roam_info);
}