qcacmn: Add support for WMI_ROAM_STATS_EVENTID event

After every roam happens or when neighbor report is sent by the
firmware, it sends the WMI_ROAM_STATS_EVENTID to host.

Add support to handle WMI_ROAM_STATS_EVENTID event from target
after every roam.

Change-Id: I4474135ac64ebfb17109d503fbd1c3d637457a73
CRs-Fixed: 2576258
这个提交包含在:
Pragaspathi Thilagaraj
2019-11-21 19:36:14 +05:30
提交者 nshrivas
父节点 e54c584723
当前提交 ab6b497e6d
修改 5 个文件,包含 565 行新增0 行删除

查看文件

@@ -532,6 +532,67 @@ wmi_unified_extract_hw_mode_resp(wmi_unified_t wmi,
void *evt_buf,
uint32_t *cmd_status);
/**
* wmi_unified_extract_roam_trigger_stats() - Extract roam trigger related
* stats
* @wmi: wmi handle
* @evt_buf: Pointer to the event buffer
* @trig: Pointer to destination structure to fill data
* @idx: TLV id
*
* Return: QDF_STATUS
*/
QDF_STATUS
wmi_unified_extract_roam_trigger_stats(wmi_unified_t wmi, void *evt_buf,
struct wmi_roam_trigger_info *trig,
uint8_t idx);
/**
* wmi_unified_extract_roam_scan_stats() - Extract roam scan stats from
* firmware
* @wmi: wmi handle
* @evt_buf: Pointer to the event buffer
* @dst: Pointer to destination structure to fill data
* @idx: TLV id
* @chan_idx: Index of the channel frequency for this roam trigger
* @ap_idx: Index of the candidate AP for this roam trigger
*
* Return: QDF_STATUS
*/
QDF_STATUS
wmi_unified_extract_roam_scan_stats(wmi_unified_t wmi, void *evt_buf,
struct wmi_roam_scan_data *dst, uint8_t idx,
uint8_t chan_idx, uint8_t ap_idx);
/**
* wmi_unified_extract_roam_result_stats() - Extract roam result related stats
* @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_result_stats(wmi_unified_t wmi, void *evt_buf,
struct wmi_roam_result *dst,
uint8_t idx);
/**
* wmi_unified_extract_roam_11kv_stats() - Extract BTM/Neigh report stats
* @wmi: wmi handle
* @evt_buf: Pointer to the event buffer
* @dst: Pointer to destination structure to fill data
* @idx: TLV id
* @rpt_idx: index of the current channel
*
* Return: QDF_STATUS
*/
QDF_STATUS
wmi_unified_extract_roam_11kv_stats(wmi_unified_t wmi, void *evt_buf,
struct wmi_neighbor_report_data *dst,
uint8_t idx, uint8_t rpt_idx);
/**
* wmi_unified_vdev_create_send() - send VDEV create command to fw
* @wmi_handle: wmi handle

查看文件

@@ -4551,6 +4551,7 @@ typedef enum {
wmi_motion_det_base_line_host_eventid,
wmi_get_ani_level_event_id,
wmi_peer_tx_pn_response_event_id,
wmi_roam_stats_event_id,
wmi_events_max,
} wmi_conv_event_id;
@@ -7472,6 +7473,152 @@ struct wmi_roam_scan_stats_res {
struct wmi_roam_scan_stats_params roam_scan[0];
};
#define MAX_ROAM_CANDIDATE_AP 8
#define MAX_ROAM_SCAN_CHAN 38
/**
* struct wmi_roam_btm_trigger_data - BTM roam trigger related information
* @btm_request_mode: BTM request mode - solicited/unsolicited
* @disassoc_timer: Number of TBTT before AP disassociates the STA in ms
* @validity_interval: Preferred candidate list validity interval in ms
* @candidate_list_count: Number of candidates in BTM request.
* @btm_resp_status: Status code of the BTM response.
*/
struct wmi_roam_btm_trigger_data {
uint32_t btm_request_mode;
uint32_t disassoc_timer;
uint32_t validity_interval;
uint32_t candidate_list_count;
uint32_t btm_resp_status;
};
/**
* struct wmi_roam_cu_trigger_data - BSS Load roam trigger parameters
* @cu_load: Connected AP CU load percentage
*/
struct wmi_roam_cu_trigger_data {
uint32_t cu_load;
/* TODO: Add threshold value */
};
/**
* Struct wmi_roam_rssi_trigger_data - RSSI roam trigger related
* parameters
* @threshold: RSSI threshold value in dBm for LOW rssi roam trigger
*/
struct wmi_roam_rssi_trigger_data {
uint32_t threshold;
};
/**
* struct wmi_roam_deauth_trigger_data - Deauth roaming trigger related
* parameters
* @type: 1- Deauthentication 2- Disassociation
* @reason: Status code of the Deauth/Disassoc received
*/
struct wmi_roam_deauth_trigger_data {
uint32_t type;
uint32_t reason;
};
/**
* struct wmi_roam_candidate_info - Roam scan candidate APs related info
* @timestamp: Host timestamp in millisecs
* @type: 0 - Candidate AP; 1 - Current connected AP.
* @bssid: AP bssid.
* @freq: Channel frquency
* @cu_load: Channel utilization load of the AP.
* @cu_score: Channel Utilization score.
* @rssi: Candidate AP rssi
* @rssi_score: AP RSSI score
* @total_score: Total score of the candidate AP.
* @etp: Estimated throughput value of the AP in Mbps
*/
struct wmi_roam_candidate_info {
uint32_t timestamp;
uint8_t type;
struct qdf_mac_addr bssid;
uint16_t freq;
uint32_t cu_load;
uint32_t cu_score;
uint32_t rssi;
uint32_t rssi_score;
uint32_t total_score;
uint32_t etp;
};
/**
* struct wmi_roam_scan_data - Roam scan event details
* @type: 0 - Partial roam scan; 1 - Full roam scan
* @num_ap: Number of candidate APs.
* @num_chan: Number of channels.
* @next_rssi_threshold: Next roam can trigger rssi threshold
* @chan_freq: List of frequencies scanned as part of roam scan
* @ap: List of candidate AP info
*/
struct wmi_roam_scan_data {
uint16_t type;
uint16_t num_ap;
uint16_t num_chan;
uint32_t next_rssi_threshold;
uint16_t chan_freq[MAX_ROAM_SCAN_CHAN];
struct wmi_roam_candidate_info ap[MAX_ROAM_CANDIDATE_AP];
};
/**
* struct wmi_roam_result - Roam result related info.
* @timestamp: Host timestamp in millisecs
* @status: 0 - Roaming is success ; 1 - Roaming failed
* @fail_reason: One of WMI_ROAM_FAIL_REASON_ID
*/
struct wmi_roam_result {
uint32_t timestamp;
bool status;
uint32_t fail_reason;
};
/**
* struct wmi_neighbor_report_data - Neighbor report/BTM request related
* data.
* @timestamp: Host timestamp in millisecs
* @req_type: 1 - BTM query ; 2 - 11K neighbor report request
* @req_time: Request timestamp in ms
* @resp_time: Response timestamp in ms
* @freq: Channel frequency in Mhz
*/
struct wmi_neighbor_report_data {
uint32_t timestamp;
uint8_t req_type;
uint32_t req_time;
uint32_t resp_time;
uint8_t num_freq;
uint32_t freq[MAX_ROAM_SCAN_CHAN];
};
/**
* struct wmi_roam_trigger_info() - Roam trigger related details
* @trigger_reason: Roam trigger reason(enum WMI_ROAM_TRIGGER_REASON_ID)
* @trigger_sub_reason: Sub reason for roam trigger if multiple roam scans
* @current_rssi: Connected AP RSSI
* @timestamp: Host timestamp in millisecs when roam scan was triggered
* @btm_trig_data: BTM roam trigger parameters.
* @cu_trig_data: BSS Load roam trigger parameters.
* @rssi_trig_data: RSSI trigger related info.
* @deauth_trig_data: Deauth roam trigger related info
*/
struct wmi_roam_trigger_info {
uint32_t trigger_reason;
uint32_t trigger_sub_reason;
uint32_t current_rssi;
uint32_t timestamp;
union {
struct wmi_roam_btm_trigger_data btm_trig_data;
struct wmi_roam_cu_trigger_data cu_trig_data;
struct wmi_roam_rssi_trigger_data rssi_trig_data;
struct wmi_roam_deauth_trigger_data deauth_trig_data;
};
};
/* End of roam scan stats definitions */
/**

查看文件

@@ -1916,6 +1916,30 @@ QDF_STATUS
void *evt_buf, uint32_t *vdev_id,
uint32_t *tx_status);
QDF_STATUS
(*extract_roam_trigger_stats)(wmi_unified_t wmi_handle,
void *evt_buf,
struct wmi_roam_trigger_info *trig,
uint8_t idx);
QDF_STATUS
(*extract_roam_scan_stats)(wmi_unified_t wmi_handle,
void *evt_buf,
struct wmi_roam_scan_data *dst, uint8_t idx,
uint8_t chan_idx, uint8_t ap_idx);
QDF_STATUS
(*extract_roam_result_stats)(wmi_unified_t wmi_handle,
void *evt_buf,
struct wmi_roam_result *dst,
uint8_t idx);
QDF_STATUS
(*extract_roam_11kv_stats)(wmi_unified_t wmi_handle,
void *evt_buf,
struct wmi_neighbor_report_data *dst,
uint8_t idx, uint8_t rpt_idx);
void (*wmi_pdev_id_conversion_enable)(wmi_unified_t wmi_handle,
uint32_t *pdev_map, uint8_t size);
void (*send_time_stamp_sync_cmd)(wmi_unified_t wmi_handle);

查看文件

@@ -3062,3 +3062,51 @@ QDF_STATUS wmi_unified_extract_ani_level(wmi_unified_t wmi_handle,
return QDF_STATUS_E_FAILURE;
}
#endif /* FEATURE_ANI_LEVEL_REQUEST */
QDF_STATUS
wmi_unified_extract_roam_trigger_stats(wmi_unified_t wmi,
void *evt_buf,
struct wmi_roam_trigger_info *trig,
uint8_t idx)
{
if (wmi->ops->extract_roam_trigger_stats)
return wmi->ops->extract_roam_trigger_stats(wmi, evt_buf, trig,
idx);
return QDF_STATUS_E_FAILURE;
}
QDF_STATUS
wmi_unified_extract_roam_scan_stats(wmi_unified_t wmi, void *evt_buf,
struct wmi_roam_scan_data *dst, uint8_t idx,
uint8_t chan_idx, uint8_t ap_idx)
{
if (wmi->ops->extract_roam_scan_stats)
return wmi->ops->extract_roam_scan_stats(wmi, evt_buf, dst,
idx, chan_idx, ap_idx);
return QDF_STATUS_E_FAILURE;
}
QDF_STATUS
wmi_unified_extract_roam_result_stats(wmi_unified_t wmi, void *buf,
struct wmi_roam_result *dst,
uint8_t idx)
{
if (wmi->ops->extract_roam_result_stats)
return wmi->ops->extract_roam_result_stats(wmi, buf, dst, idx);
return QDF_STATUS_E_FAILURE;
}
QDF_STATUS
wmi_unified_extract_roam_11kv_stats(wmi_unified_t wmi, void *evt_buf,
struct wmi_neighbor_report_data *dst,
uint8_t idx, uint8_t rpt_idx)
{
if (wmi->ops->extract_roam_11kv_stats)
return wmi->ops->extract_roam_11kv_stats(wmi, evt_buf, dst, idx,
rpt_idx);
return QDF_STATUS_E_FAILURE;
}

查看文件

@@ -12535,6 +12535,286 @@ static QDF_STATUS extract_ani_level_tlv(uint8_t *evt_buf,
}
#endif /* FEATURE_ANI_LEVEL_REQUEST */
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
/**
* extract_roam_trigger_stats_tlv() - Extract the Roam trigger stats
* from the WMI_ROAM_STATS_EVENTID
* @wmi_handle: wmi handle
* @evt_buf: Pointer to the event buffer
* @trig: Pointer to destination structure to fill data
* @idx: TLV id
*/
static QDF_STATUS
extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf,
struct wmi_roam_trigger_info *trig, uint8_t idx)
{
WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf;
wmi_roam_trigger_reason *src_data = NULL;
param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf;
if (!param_buf)
return QDF_STATUS_E_FAILURE;
src_data = &param_buf->roam_trigger_reason[idx];
trig->trigger_reason = src_data->trigger_reason;
trig->trigger_sub_reason = src_data->trigger_sub_reason;
trig->current_rssi = src_data->current_rssi;
trig->timestamp = src_data->timestamp;
switch (trig->trigger_reason) {
case WMI_ROAM_TRIGGER_REASON_PER:
case WMI_ROAM_TRIGGER_REASON_BMISS:
case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI:
case WMI_ROAM_TRIGGER_REASON_PERIODIC:
case WMI_ROAM_TRIGGER_REASON_MAWC:
case WMI_ROAM_TRIGGER_REASON_DENSE:
case WMI_ROAM_TRIGGER_REASON_BACKGROUND:
case WMI_ROAM_TRIGGER_REASON_IDLE:
case WMI_ROAM_TRIGGER_REASON_FORCED:
case WMI_ROAM_TRIGGER_REASON_UNIT_TEST:
return QDF_STATUS_SUCCESS;
case WMI_ROAM_TRIGGER_REASON_BTM:
trig->btm_trig_data.btm_request_mode =
src_data->btm_request_mode;
trig->btm_trig_data.disassoc_timer =
src_data->disassoc_imminent_timer;
trig->btm_trig_data.validity_interval =
src_data->validity_internal;
trig->btm_trig_data.candidate_list_count =
src_data->candidate_list_count;
trig->btm_trig_data.btm_resp_status =
src_data->btm_response_status_code;
return QDF_STATUS_SUCCESS;
case WMI_ROAM_TRIGGER_REASON_BSS_LOAD:
trig->cu_trig_data.cu_load = src_data->cu_load;
return QDF_STATUS_SUCCESS;
case WMI_ROAM_TRIGGER_REASON_DEAUTH:
trig->deauth_trig_data.type = src_data->deauth_type;
trig->deauth_trig_data.reason = src_data->deauth_reason;
return QDF_STATUS_SUCCESS;
case WMI_ROAM_TRIGGER_REASON_LOW_RSSI:
trig->rssi_trig_data.threshold = src_data->roam_rssi_threshold;
return QDF_STATUS_SUCCESS;
default:
return QDF_STATUS_SUCCESS;
}
return QDF_STATUS_SUCCESS;
}
/**
* extract_roam_scan_ap_stats_tlv() - Extract the Roam trigger stats
* 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
* @ap_idx: TLV index for this roam scan
* @num_cand: number of candidates list in the roam scan
*/
static QDF_STATUS
extract_roam_scan_ap_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf,
struct wmi_roam_candidate_info *dst,
uint8_t ap_idx, uint16_t num_cand)
{
WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf;
wmi_roam_ap_info *src = NULL;
uint8_t i;
param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf;
if (!param_buf)
return QDF_STATUS_E_FAILURE;
src = &param_buf->roam_ap_info[ap_idx];
if (num_cand > MAX_ROAM_CANDIDATE_AP)
num_cand = MAX_ROAM_CANDIDATE_AP;
for (i = 0; i < num_cand; i++) {
WMI_MAC_ADDR_TO_CHAR_ARRAY(&src->bssid, dst->bssid.bytes);
dst->type = src->candidate_type;
dst->freq = src->channel;
dst->etp = src->etp;
dst->rssi = src->rssi;
dst->rssi_score = src->rssi_score;
dst->cu_load = src->cu_load;
dst->cu_score = src->cu_score;
dst->total_score = src->total_score;
dst->timestamp = src->timestamp;
src++;
dst++;
}
return QDF_STATUS_SUCCESS;
}
/**
* extract_roam_scan_stats_tlv() - Extract the Roam trigger stats
* 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
* @chan_idx: Index of the channel tlv for the current roam trigger
* @ap_idx: Index of the candidate AP TLV for the current roam trigger
*/
static QDF_STATUS
extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf,
struct wmi_roam_scan_data *dst, uint8_t idx,
uint8_t chan_idx, uint8_t ap_idx)
{
WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf;
wmi_roam_scan_info *src_data = NULL;
wmi_roam_scan_channel_info *src_chan = NULL;
QDF_STATUS status;
uint8_t i;
param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf;
if (!param_buf)
return QDF_STATUS_E_FAILURE;
src_data = &param_buf->roam_scan_info[idx];
dst->type = src_data->roam_scan_type;
dst->num_ap = src_data->roam_ap_count;
dst->num_chan = src_data->roam_scan_channel_count;
dst->next_rssi_threshold = src_data->next_rssi_trigger_threshold;
/* Read the channel data only for dst->type is 0 (partial scan) */
if (dst->num_chan && !dst->type) {
if (dst->num_chan > MAX_ROAM_SCAN_CHAN)
dst->num_chan = MAX_ROAM_SCAN_CHAN;
src_chan = &param_buf->roam_scan_chan_info[chan_idx];
for (i = 0; i < dst->num_chan; i++) {
dst->chan_freq[i] = src_chan->channel;
src_chan++;
}
}
if (!dst->num_ap)
return QDF_STATUS_SUCCESS;
status = extract_roam_scan_ap_stats_tlv(wmi_handle, evt_buf, dst->ap,
ap_idx, dst->num_ap);
if (QDF_IS_STATUS_ERROR(status)) {
WMI_LOGE("Extract candidate stats for tlv[%d] failed", idx);
return status;
}
return QDF_STATUS_SUCCESS;
}
/**
* extract_roam_scan_stats_tlv() - Extract the Roam trigger stats
* 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
*/
static QDF_STATUS
extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf,
struct wmi_roam_result *dst, uint8_t idx)
{
WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf;
wmi_roam_result *src_data = NULL;
param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf;
if (!param_buf)
return QDF_STATUS_E_FAILURE;
src_data = &param_buf->roam_result[idx];
dst->status = src_data->roam_status ? false : true;
dst->timestamp = src_data->timestamp;
dst->fail_reason = src_data->roam_fail_reason;
return QDF_STATUS_SUCCESS;
}
/**
* extract_roam_11kv_stats_tlv() - Extract the Roam trigger stats
* 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
* @rpt_idx: Neighbor report Channel index
*/
static QDF_STATUS
extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf,
struct wmi_neighbor_report_data *dst,
uint8_t idx, uint8_t rpt_idx)
{
WMI_ROAM_STATS_EVENTID_param_tlvs *param_buf;
wmi_roam_neighbor_report_info *src_data = NULL;
wmi_roam_neighbor_report_channel_info *src_freq = NULL;
uint8_t i;
param_buf = (WMI_ROAM_STATS_EVENTID_param_tlvs *)evt_buf;
if (!param_buf)
return QDF_STATUS_E_FAILURE;
src_data = &param_buf->roam_neighbor_report_info[idx];
dst->req_type = src_data->request_type;
dst->num_freq = src_data->neighbor_report_channel_count;
dst->req_time = src_data->neighbor_report_request_timestamp;
dst->resp_time = src_data->neighbor_report_response_timestamp;
if (!dst->num_freq)
return QDF_STATUS_SUCCESS;
src_freq = &param_buf->roam_neighbor_report_chan_info[rpt_idx];
if (dst->num_freq > MAX_ROAM_SCAN_CHAN)
dst->num_freq = MAX_ROAM_SCAN_CHAN;
for (i = 0; i < dst->num_freq; i++) {
dst->freq[i] = src_freq->channel;
src_freq++;
}
return QDF_STATUS_SUCCESS;
}
#else
static inline QDF_STATUS
extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf,
struct wmi_roam_trigger_info *trig, uint8_t idx)
{
return QDF_STATUS_E_NOSUPPORT;
}
static inline QDF_STATUS
extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf,
struct wmi_roam_result *dst, uint8_t idx)
{
return QDF_STATUS_E_NOSUPPORT;
}
static QDF_STATUS
extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf,
struct wmi_neighbor_report_data *dst,
uint8_t idx, uint8_t rpt_idx)
{
return QDF_STATUS_E_NOSUPPORT;
}
static QDF_STATUS
extract_roam_scan_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf,
struct wmi_roam_scan_data *dst, uint8_t idx,
uint8_t chan_idx, uint8_t ap_idx)
{
return QDF_STATUS_E_NOSUPPORT;
}
#endif
struct wmi_ops tlv_ops = {
.send_vdev_create_cmd = send_vdev_create_cmd_tlv,
.send_vdev_delete_cmd = send_vdev_delete_cmd_tlv,
@@ -12835,6 +13115,10 @@ struct wmi_ops tlv_ops = {
.send_ani_level_cmd = send_ani_level_cmd_tlv,
.extract_ani_level = extract_ani_level_tlv,
#endif /* FEATURE_ANI_LEVEL_REQUEST */
.extract_roam_trigger_stats = extract_roam_trigger_stats_tlv,
.extract_roam_scan_stats = extract_roam_scan_stats_tlv,
.extract_roam_result_stats = extract_roam_result_stats_tlv,
.extract_roam_11kv_stats = extract_roam_11kv_stats_tlv,
};
/**
@@ -13185,6 +13469,7 @@ static void populate_tlv_events_id(uint32_t *event_ids)
event_ids[wmi_get_ani_level_event_id] = WMI_GET_CHANNEL_ANI_EVENTID;
event_ids[wmi_peer_tx_pn_response_event_id] =
WMI_PEER_TX_PN_RESPONSE_EVENTID;
event_ids[wmi_roam_stats_event_id] = WMI_ROAM_STATS_EVENTID;
}
/**