qcacld-3.0: Add support to handle RRM sta stats req
Add support to handle RRM Station statistics request (type == 7) from AP. Based on the received group id, collect the corresponding stats and send the RRM station statistics response to AP. Send Report with incapable/Refused bit in below cases: a.) Meas duration > threshold which is 10 seconds b.) Groupid apart from 0, 1 or 10. c.) Failure to start Timer. d.) Response not received from FW for previous request. e.) Another RRM STA STATS Request in progress. f.) Another CP stats request in progress. Change-Id: If93e9c51363daf9704a14df5822c8f7bfbd4b216 CRs-Fixed: 3583973
This commit is contained in:

zatwierdzone przez
Rahul Choudhary

rodzic
f89f0e2de0
commit
7aa3e49d6d
@@ -672,8 +672,8 @@ tgt_mc_infra_cp_stats_extract_twt_stats(struct wlan_objmgr_psoc *psoc,
|
||||
struct infra_cp_stats_event *ev)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
get_infra_cp_stats_cb resp_cb;
|
||||
void *context;
|
||||
get_infra_cp_stats_cb resp_cb = NULL;
|
||||
void *context = NULL;
|
||||
|
||||
status = wlan_cp_stats_infra_cp_get_context(psoc, &resp_cb, &context);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
|
@@ -285,6 +285,8 @@ typedef struct sLimTimers {
|
||||
/* SAE authentication related timer */
|
||||
TX_TIMER sae_auth_timer;
|
||||
|
||||
/* RRM sta stats response related timer */
|
||||
TX_TIMER rrm_sta_stats_resp_timer;
|
||||
/* ********************TIMER SECTION ENDS************************************************** */
|
||||
/* ALL THE FIELDS BELOW THIS CAN BE ZEROED OUT in lim_initialize */
|
||||
/* **************************************************************************************** */
|
||||
|
@@ -1363,6 +1363,102 @@ struct chan_load_report {
|
||||
uint8_t chan_load;
|
||||
};
|
||||
|
||||
/**
|
||||
* sta_statistics_group_id - RRM STA STATISTICS TYPE related Refer IEEE
|
||||
* P802.11-REVme/D2.1, January 2023, Table 9-144
|
||||
* @STA_STAT_GROUP_ID_COUNTER_STATS: group id for counter stats
|
||||
* @STA_STAT_GROUP_ID_MAC_STATS: group id for mac stats
|
||||
* @STA_STAT_GROUP_ID_QOS_STATS: group id for qos stats
|
||||
* @STA_STAT_GROUP_ID_DELAY_STATS: group id delay stats
|
||||
*/
|
||||
enum sta_statistics_group_id {
|
||||
STA_STAT_GROUP_ID_COUNTER_STATS = 0,
|
||||
STA_STAT_GROUP_ID_MAC_STATS = 1,
|
||||
STA_STAT_GROUP_ID_QOS_STATS = 2,
|
||||
STA_STAT_GROUP_ID_DELAY_STATS = 10,
|
||||
};
|
||||
|
||||
/**
|
||||
* counter_stats - structure to hold stats of group id 0
|
||||
* @transmitted_fragment_count: transmitted fragment count
|
||||
* @group_transmitted_frame_count: group transmitted frame count
|
||||
* @failed_count: failed count
|
||||
* @group_received_frame_count: group received frame count
|
||||
* @fcs_error_count: face error count
|
||||
* @transmitted_frame_count: transmitted frame count
|
||||
* @received_fragment_count: received fragment count
|
||||
*/
|
||||
struct counter_stats {
|
||||
uint32_t transmitted_fragment_count;
|
||||
uint32_t group_transmitted_frame_count;
|
||||
uint32_t failed_count;
|
||||
uint32_t group_received_frame_count;
|
||||
uint32_t fcs_error_count;
|
||||
uint32_t transmitted_frame_count;
|
||||
uint32_t received_fragment_count;
|
||||
};
|
||||
|
||||
/**
|
||||
* mac_stats - struct to hold group id 1 stats
|
||||
* @retry_count: retry count
|
||||
* @multiple_retry_count: multiple retry count
|
||||
* @frame_duplicate_count: frame duplicate count
|
||||
* @rts_success_count: rts success count
|
||||
* @rts_failure_count: rts failure count
|
||||
* @ack_failure_count: ack failure count
|
||||
*/
|
||||
struct mac_stats {
|
||||
uint32_t retry_count;
|
||||
uint32_t multiple_retry_count;
|
||||
uint32_t frame_duplicate_count;
|
||||
uint32_t rts_success_count;
|
||||
uint32_t rts_failure_count;
|
||||
uint32_t ack_failure_count;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct access_delay_stats - struct for group id 10 stats
|
||||
* @ap_average_access_delay: ap average access delay
|
||||
* @average_access_delay_besteffort: access delay best effort
|
||||
* @average_access_delay_background: average access delay background
|
||||
* @average_access_delay_video: average access delay video
|
||||
* @average_access_delay_voice: average access delay voice
|
||||
* station_count: station count
|
||||
* channel_utilization: channel utilization
|
||||
*/
|
||||
struct access_delay_stats {
|
||||
uint8_t ap_average_access_delay;
|
||||
uint8_t average_access_delay_besteffort;
|
||||
uint8_t average_access_delay_background;
|
||||
uint8_t average_access_delay_video;
|
||||
uint8_t average_access_delay_voice;
|
||||
uint16_t station_count;
|
||||
uint8_t channel_utilization;
|
||||
};
|
||||
|
||||
/**
|
||||
* union stats_group_data - stats data for provided group id
|
||||
* @counter stats - stats for group id 0
|
||||
* @mac_stats - stats for group id 1
|
||||
*/
|
||||
union stats_group_data {
|
||||
struct counter_stats counter_stats;
|
||||
struct mac_stats mac_stats;
|
||||
struct access_delay_stats access_delay_stats;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct statistics_report - To store sta statistics report
|
||||
* @meas_duration: measurement duration
|
||||
* @group id: stats group id
|
||||
* @group stats: stats data
|
||||
*/
|
||||
struct statistics_report {
|
||||
uint8_t meas_duration;
|
||||
uint8_t group_id;
|
||||
union stats_group_data group_stats;
|
||||
};
|
||||
|
||||
typedef struct sSirMacRadioMeasureReport {
|
||||
uint8_t token;
|
||||
uint8_t refused;
|
||||
@@ -1371,6 +1467,7 @@ typedef struct sSirMacRadioMeasureReport {
|
||||
union {
|
||||
tSirMacBeaconReport beaconReport;
|
||||
struct chan_load_report channel_load_report;
|
||||
struct statistics_report statistics_report;
|
||||
} report;
|
||||
|
||||
} tSirMacRadioMeasureReport, *tpSirMacRadioMeasureReport;
|
||||
|
@@ -823,7 +823,7 @@ populate_dot11f_ext_supp_rates(struct mac_context *mac,
|
||||
* @pBeaconReport: Pointer to the Beacon Report structure
|
||||
* @is_last_frame: is the current report last or more reports to follow
|
||||
*
|
||||
* Return: Ret Status
|
||||
* Return: QDF Status
|
||||
*/
|
||||
QDF_STATUS
|
||||
populate_dot11f_beacon_report(struct mac_context *mac,
|
||||
@@ -844,6 +844,19 @@ populate_dot11f_chan_load_report(struct mac_context *mac,
|
||||
tDot11fIEMeasurementReport *dot11f,
|
||||
struct chan_load_report *channel_load_report);
|
||||
|
||||
/**
|
||||
* populate_dot11f_rrm_sta_stats_report() - Populate RRM STA STATS Report IE
|
||||
* @mac: Pointer to the global MAC context
|
||||
* @pdot11f: Pointer to the measurement report structure
|
||||
* @statistics_report: Pointer to the RRM STA STATS Report structure
|
||||
*
|
||||
* Return: QDF Status
|
||||
*/
|
||||
QDF_STATUS
|
||||
populate_dot11f_rrm_sta_stats_report(
|
||||
struct mac_context *mac, tDot11fIEMeasurementReport *pdot11f,
|
||||
struct statistics_report *statistics_report);
|
||||
|
||||
/**
|
||||
* \brief Populate a tDot11fIEExtSuppRates
|
||||
*
|
||||
|
@@ -709,7 +709,7 @@ enum halmsgtype {
|
||||
#define SIR_LIM_WPS_OVERLAP_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x1D)
|
||||
#define SIR_LIM_FT_PREAUTH_RSP_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x1E)
|
||||
|
||||
/* currently unused (SIR_LIM_TIMEOUT_MSG_START + 0x24) */
|
||||
#define SIR_LIM_RRM_STA_STATS_RSP_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x24)
|
||||
/* currently unused (SIR_LIM_TIMEOUT_MSG_START + 0x25) */
|
||||
|
||||
#define SIR_LIM_DISASSOC_ACK_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x26)
|
||||
|
@@ -133,4 +133,44 @@ QDF_STATUS rrm_reject_req(tpSirMacRadioMeasureReport *radiomes_report,
|
||||
uint8_t measurement_type);
|
||||
|
||||
void lim_update_rrm_capability(struct mac_context *mac_ctx);
|
||||
|
||||
#ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS
|
||||
/**
|
||||
* rrm_send_sta_stats_req - Send RRM STA STATS request
|
||||
* @mac: mac context
|
||||
* @session: pe session
|
||||
* @peer_mac: peer mac
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS
|
||||
rrm_send_sta_stats_req(struct mac_context *mac,
|
||||
struct pe_session *session,
|
||||
tSirMacAddr peer_mac);
|
||||
#else
|
||||
static inline QDF_STATUS
|
||||
rrm_send_sta_stats_req(struct mac_context *mac,
|
||||
struct pe_session *session,
|
||||
tSirMacAddr peer_mac)
|
||||
{
|
||||
return QDF_STATUS_E_NOSUPPORT;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* rrm_process_rrm_sta_stats_request_failure: send RRM STA Stats report with
|
||||
* failure
|
||||
* @mac: mac context
|
||||
* @pe_session: pe session
|
||||
* @peer: peer mac
|
||||
* @status: failure status
|
||||
* @index: index of report
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
void
|
||||
rrm_process_rrm_sta_stats_request_failure(struct mac_context *mac,
|
||||
struct pe_session *pe_session,
|
||||
tSirMacAddr peer,
|
||||
tRrmRetStatus status, uint8_t index);
|
||||
#endif
|
||||
|
@@ -259,6 +259,22 @@ typedef struct sRRMCaps {
|
||||
uint8_t reserved:4;
|
||||
} tRRMCaps, *tpRRMCaps;
|
||||
|
||||
/**
|
||||
* struct rrm_sta_stats - RRM sta stats structure
|
||||
* @rrm_report: rrm_report
|
||||
* @peer: peer address
|
||||
* @index: current req index
|
||||
* @rrm_sta_stats_res_count: sta stats response count
|
||||
* @vdev_id: vdev_id
|
||||
*/
|
||||
struct rrm_sta_stats {
|
||||
tSirMacRadioMeasureReport rrm_report;
|
||||
tSirMacAddr peer;
|
||||
uint8_t index;
|
||||
uint8_t rrm_sta_stats_res_count;
|
||||
uint8_t vdev_id;
|
||||
};
|
||||
|
||||
typedef struct sRrmPEContext {
|
||||
uint8_t rrmEnable;
|
||||
/*
|
||||
@@ -279,6 +295,7 @@ typedef struct sRrmPEContext {
|
||||
tpRRMReq pCurrentReq[MAX_MEASUREMENT_REQUEST];
|
||||
uint32_t beacon_rpt_chan_list[MAX_NUM_CHANNELS];
|
||||
uint8_t beacon_rpt_chan_num;
|
||||
struct rrm_sta_stats rrm_sta_stats;
|
||||
} tRrmPEContext, *tpRrmPEContext;
|
||||
|
||||
/* 2008 11k spec reference: 18.4.8.5 RCPI Measurement */
|
||||
|
@@ -1855,6 +1855,7 @@ static void lim_process_messages(struct mac_context *mac_ctx,
|
||||
case SIR_LIM_DISASSOC_ACK_TIMEOUT:
|
||||
case SIR_LIM_AUTH_RETRY_TIMEOUT:
|
||||
case SIR_LIM_AUTH_SAE_TIMEOUT:
|
||||
case SIR_LIM_RRM_STA_STATS_RSP_TIMEOUT:
|
||||
/* These timeout messages are handled by MLM sub module */
|
||||
lim_process_mlm_req_messages(mac_ctx, msg);
|
||||
break;
|
||||
|
@@ -43,12 +43,15 @@
|
||||
#include "wlan_mlme_public_struct.h"
|
||||
#include "../../core/src/vdev_mgr_ops.h"
|
||||
#include "wlan_pmo_ucfg_api.h"
|
||||
#include "wlan_cp_stats_utils_api.h"
|
||||
#include "wlan_objmgr_vdev_obj.h"
|
||||
#include <wlan_cm_api.h>
|
||||
#include <lim_mlo.h>
|
||||
#include "wlan_mlo_mgr_peer.h"
|
||||
#include <son_api.h>
|
||||
#include "wifi_pos_pasn_api.h"
|
||||
#include "rrm_api.h"
|
||||
#include "../../core/src/wlan_cp_stats_obj_mgr_handler.h"
|
||||
|
||||
static void lim_process_mlm_auth_req(struct mac_context *, uint32_t *);
|
||||
static void lim_process_mlm_assoc_req(struct mac_context *, uint32_t *);
|
||||
@@ -96,6 +99,75 @@ static void lim_fill_status_code(uint8_t frame_type,
|
||||
}
|
||||
}
|
||||
|
||||
void lim_process_rrm_sta_stats_rsp_timeout(struct mac_context *mac)
|
||||
{
|
||||
struct pe_session *session;
|
||||
tSirMacRadioMeasureReport rrm_report;
|
||||
QDF_STATUS status;
|
||||
uint8_t index;
|
||||
tpRRMReq pcurrent_req = NULL;
|
||||
tRrmRetStatus rrm_status;
|
||||
|
||||
session = pe_find_session_by_session_id(mac,
|
||||
mac->lim.lim_timers.rrm_sta_stats_resp_timer.sessionId);
|
||||
if (!session) {
|
||||
pe_err("Session does not exist for given session id %d",
|
||||
mac->lim.lim_timers.rrm_sta_stats_resp_timer.sessionId);
|
||||
rrm_cleanup(mac, mac->rrm.rrmPEContext.rrm_sta_stats.index);
|
||||
return;
|
||||
}
|
||||
|
||||
pe_warn("STA STATS RSP timeout vdev_id %d", session->vdev_id);
|
||||
index = mac->rrm.rrmPEContext.rrm_sta_stats.index;
|
||||
pcurrent_req = mac->rrm.rrmPEContext.pCurrentReq[index];
|
||||
if (!pcurrent_req) {
|
||||
pe_err("Current request is NULL for index %d", index);
|
||||
qdf_mem_zero(&mac->rrm.rrmPEContext.rrm_sta_stats,
|
||||
sizeof(mac->rrm.rrmPEContext.rrm_sta_stats));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mac->rrm.rrmPEContext.rrm_sta_stats.rrm_sta_stats_res_count) {
|
||||
pe_err("response not received for previous req");
|
||||
rrm_status = eRRM_INCAPABLE;
|
||||
goto err;
|
||||
}
|
||||
|
||||
rrm_report = mac->rrm.rrmPEContext.rrm_sta_stats.rrm_report;
|
||||
switch (rrm_report.report.statistics_report.group_id) {
|
||||
/*
|
||||
* For Counter stats and Mac stats some stats will be received
|
||||
* via FW and some via DP. So, same handling is required for both
|
||||
* cases.
|
||||
*/
|
||||
case STA_STAT_GROUP_ID_COUNTER_STATS:
|
||||
case STA_STAT_GROUP_ID_MAC_STATS:
|
||||
status = wlan_cp_stats_infra_cp_deregister_resp_cb(mac->psoc);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
pe_err("failed to deregister callback %d", status);
|
||||
|
||||
status =
|
||||
rrm_send_sta_stats_req(
|
||||
mac, session,
|
||||
mac->rrm.rrmPEContext.rrm_sta_stats.peer);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
pe_err("fail to send stats req");
|
||||
rrm_status = eRRM_FAILURE;
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
case STA_STAT_GROUP_ID_DELAY_STATS:
|
||||
/* TOdo: fetch from scan ie */
|
||||
break;
|
||||
}
|
||||
return;
|
||||
err:
|
||||
rrm_process_rrm_sta_stats_request_failure(
|
||||
mac, session, mac->rrm.rrmPEContext.rrm_sta_stats.peer,
|
||||
rrm_status, mac->rrm.rrmPEContext.rrm_sta_stats.index);
|
||||
rrm_cleanup(mac, mac->rrm.rrmPEContext.rrm_sta_stats.index);
|
||||
}
|
||||
|
||||
void lim_process_sae_auth_timeout(struct mac_context *mac_ctx)
|
||||
{
|
||||
struct pe_session *session;
|
||||
@@ -194,6 +266,9 @@ void lim_process_mlm_req_messages(struct mac_context *mac_ctx,
|
||||
case SIR_LIM_AUTH_SAE_TIMEOUT:
|
||||
lim_process_sae_auth_timeout(mac_ctx);
|
||||
break;
|
||||
case SIR_LIM_RRM_STA_STATS_RSP_TIMEOUT:
|
||||
lim_process_rrm_sta_stats_rsp_timeout(mac_ctx);
|
||||
break;
|
||||
case LIM_MLM_TSPEC_REQ:
|
||||
default:
|
||||
break;
|
||||
|
@@ -5686,6 +5686,16 @@ lim_send_radio_measure_report_action_frame(struct mac_context *mac,
|
||||
pRRMReport[i].refused;
|
||||
frm->MeasurementReport[i].present = 1;
|
||||
break;
|
||||
case SIR_MAC_RRM_STA_STATISTICS_TYPE:
|
||||
populate_dot11f_rrm_sta_stats_report(
|
||||
mac, &frm->MeasurementReport[i],
|
||||
&pRRMReport[i].report.statistics_report);
|
||||
frm->MeasurementReport[i].incapable =
|
||||
pRRMReport[i].incapable;
|
||||
frm->MeasurementReport[i].refused =
|
||||
pRRMReport[i].refused;
|
||||
frm->MeasurementReport[i].present = 1;
|
||||
break;
|
||||
default:
|
||||
frm->MeasurementReport[i].incapable =
|
||||
pRRMReport[i].incapable;
|
||||
|
@@ -49,6 +49,12 @@
|
||||
*/
|
||||
#define LIM_AUTH_SAE_TIMER_MS 5000
|
||||
|
||||
/*
|
||||
* STA stats resp timer of 10secs. This is required for duration of RRM
|
||||
* STA STATS report response from report request.
|
||||
*/
|
||||
#define LIM_RRM_STA_STATS_RSP_TIMER_MS 10000
|
||||
|
||||
static bool lim_create_non_ap_timers(struct mac_context *mac)
|
||||
{
|
||||
uint32_t cfgValue;
|
||||
@@ -235,10 +241,21 @@ uint32_t lim_create_timers(struct mac_context *mac)
|
||||
goto err_timer;
|
||||
}
|
||||
|
||||
if ((tx_timer_create(mac,
|
||||
&mac->lim.lim_timers.rrm_sta_stats_resp_timer,
|
||||
"STA STATS RSP timer",
|
||||
lim_timer_handler,
|
||||
SIR_LIM_RRM_STA_STATS_RSP_TIMEOUT,
|
||||
SYS_MS_TO_TICKS(LIM_RRM_STA_STATS_RSP_TIMER_MS), 0,
|
||||
TX_NO_ACTIVATE)) != TX_SUCCESS) {
|
||||
pe_err("could not create STA STATS RSP Timer");
|
||||
goto err_timer;
|
||||
}
|
||||
return TX_SUCCESS;
|
||||
|
||||
err_timer:
|
||||
lim_delete_timers_host_roam(mac);
|
||||
tx_timer_delete(&mac->lim.lim_timers.rrm_sta_stats_resp_timer);
|
||||
tx_timer_delete(&mac->lim.lim_timers.gLimDeauthAckTimer);
|
||||
tx_timer_delete(&mac->lim.lim_timers.gLimDisassocAckTimer);
|
||||
tx_timer_delete(&mac->lim.lim_timers.gLimUpdateOlbcCacheTimer);
|
||||
@@ -677,6 +694,21 @@ void lim_deactivate_and_change_timer(struct mac_context *mac, uint32_t timerId)
|
||||
pe_err("unable to change SAE auth timer");
|
||||
|
||||
break;
|
||||
case eLIM_RRM_STA_STATS_RSP_TIMER:
|
||||
if (tx_timer_deactivate
|
||||
(&mac->lim.lim_timers.rrm_sta_stats_resp_timer)
|
||||
!= TX_SUCCESS)
|
||||
pe_err("Unable to deactivate STA STATS RSP timer");
|
||||
|
||||
/* Change timer to reactivate it in future */
|
||||
val = SYS_MS_TO_TICKS(LIM_RRM_STA_STATS_RSP_TIMER_MS);
|
||||
|
||||
if (tx_timer_change(
|
||||
&mac->lim.lim_timers.rrm_sta_stats_resp_timer,
|
||||
val, 0) != TX_SUCCESS)
|
||||
pe_err("unable to change STA STATS RSP timer");
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Invalid timerId. Log error */
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2014, 2016-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@@ -55,7 +55,8 @@ enum limtimertype {
|
||||
eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER,
|
||||
eLIM_INSERT_SINGLESHOT_NOA_TIMER,
|
||||
eLIM_AUTH_RETRY_TIMER,
|
||||
eLIM_AUTH_SAE_TIMER
|
||||
eLIM_AUTH_SAE_TIMER,
|
||||
eLIM_RRM_STA_STATS_RSP_TIMER
|
||||
};
|
||||
|
||||
#define LIM_DISASSOC_DEAUTH_ACK_TIMEOUT 500
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@@ -64,6 +64,7 @@ static uint8_t *__lim_trace_get_timer_string(uint16_t timerId)
|
||||
CASE_RETURN_STRING(eLIM_DEAUTH_ACK_TIMER);
|
||||
CASE_RETURN_STRING(eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER);
|
||||
CASE_RETURN_STRING(eLIM_AUTH_RETRY_TIMER);
|
||||
CASE_RETURN_STRING(eLIM_RRM_STA_STATS_RSP_TIMER);
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
break;
|
||||
|
@@ -1624,6 +1624,15 @@ void lim_process_assoc_failure_timeout(struct mac_context *mac_ctx,
|
||||
*/
|
||||
void lim_process_sae_auth_timeout(struct mac_context *mac_ctx);
|
||||
|
||||
/**
|
||||
* lim_process_rrm_sta_stats_rsp_timeout() - This function is called to process
|
||||
* sta stats response timeout
|
||||
* @mac_ctx: Pointer to Global MAC structure
|
||||
*
|
||||
* @Return: None
|
||||
*/
|
||||
void lim_process_rrm_sta_stats_rsp_timeout(struct mac_context *mac_ctx);
|
||||
|
||||
/**
|
||||
* lim_send_frame() - API to send frame
|
||||
* @mac_ctx Pointer to Global MAC structure
|
||||
|
@@ -496,8 +496,13 @@ void lim_deactivate_timers(struct mac_context *mac_ctx)
|
||||
/* Cleanup as if SAE auth timer expired */
|
||||
lim_timer_handler(mac_ctx, SIR_LIM_AUTH_SAE_TIMEOUT);
|
||||
}
|
||||
|
||||
tx_timer_deactivate(&lim_timer->sae_auth_timer);
|
||||
|
||||
if (tx_timer_running(&lim_timer->rrm_sta_stats_resp_timer)) {
|
||||
pe_err("sta stats resp timer running call the timeout API");
|
||||
lim_timer_handler(mac_ctx, SIR_LIM_RRM_STA_STATS_RSP_TIMEOUT);
|
||||
}
|
||||
tx_timer_deactivate(&lim_timer->rrm_sta_stats_resp_timer);
|
||||
}
|
||||
|
||||
void lim_deactivate_timers_for_vdev(struct mac_context *mac_ctx,
|
||||
@@ -663,6 +668,7 @@ void lim_cleanup_mlm(struct mac_context *mac_ctx)
|
||||
tx_timer_delete(&lim_timer->gLimDeauthAckTimer);
|
||||
|
||||
tx_timer_delete(&lim_timer->sae_auth_timer);
|
||||
tx_timer_delete(&lim_timer->rrm_sta_stats_resp_timer);
|
||||
|
||||
mac_ctx->lim.gLimTimersCreated = 0;
|
||||
}
|
||||
|
@@ -45,6 +45,15 @@
|
||||
#include "rrm_api.h"
|
||||
#include "wlan_lmac_if_def.h"
|
||||
#include "wlan_reg_services_api.h"
|
||||
#include "wlan_cp_stats_utils_api.h"
|
||||
#include "../../core/src/wlan_cp_stats_obj_mgr_handler.h"
|
||||
#include "../../core/src/wlan_cp_stats_defs.h"
|
||||
#include "cdp_txrx_host_stats.h"
|
||||
|
||||
#define MAX_CTRL_STAT_VDEV_ENTRIES 1
|
||||
#define MAX_CTRL_STAT_MAC_ADDR_ENTRIES 1
|
||||
#define MAX_RMM_STA_STATS_REQUESTED 2
|
||||
#define MAX_MEAS_DURATION_FOR_STA_STATS 10
|
||||
|
||||
/* Max passive scan dwell for wide band rrm scan, in milliseconds */
|
||||
#define RRM_SCAN_MAX_DWELL_TIME 110
|
||||
@@ -611,6 +620,506 @@ wlan_diag_log_beacon_rpt_req_event(uint8_t token, uint8_t mode,
|
||||
#endif
|
||||
|
||||
#define ABS(x) ((x < 0) ? -x : x)
|
||||
|
||||
#ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS
|
||||
/**
|
||||
* rrm_update_mac_cp_stats: update stats of rrm structure of mac
|
||||
* @ev: cp stats event
|
||||
* @mac_ctx: mac context
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static inline void
|
||||
rrm_update_mac_cp_stats(struct infra_cp_stats_event *ev,
|
||||
struct mac_context *mac_ctx)
|
||||
{
|
||||
tpSirMacRadioMeasureReport rrm_report;
|
||||
struct counter_stats *counter_stats;
|
||||
struct group_id_0 ev_counter_stats;
|
||||
struct mac_stats *mac_stats;
|
||||
struct group_id_1 ev_mac_stats;
|
||||
|
||||
rrm_report = &mac_ctx->rrm.rrmPEContext.rrm_sta_stats.rrm_report;
|
||||
|
||||
counter_stats =
|
||||
&rrm_report->report.statistics_report.group_stats.counter_stats;
|
||||
mac_stats =
|
||||
&rrm_report->report.statistics_report.group_stats.mac_stats;
|
||||
|
||||
ev_counter_stats = ev->sta_stats->group.counter_stats;
|
||||
ev_mac_stats = ev->sta_stats->group.mac_stats;
|
||||
|
||||
switch (rrm_report->report.statistics_report.group_id) {
|
||||
/*
|
||||
* Assign count diff in mac rrm sta stats report.
|
||||
* For first event callback stats will be same as
|
||||
* send by FW because memset is done for mac rrm sta
|
||||
* stats before sending rrm sta stats request to FW and
|
||||
* for second request stats will be the diff of stats send
|
||||
* by FW and previous stats.
|
||||
*/
|
||||
case STA_STAT_GROUP_ID_COUNTER_STATS:
|
||||
counter_stats->group_transmitted_frame_count =
|
||||
ev_counter_stats.group_transmitted_frame_count -
|
||||
counter_stats->group_transmitted_frame_count;
|
||||
counter_stats->failed_count =
|
||||
ev_counter_stats.failed_count -
|
||||
counter_stats->failed_count;
|
||||
counter_stats->group_received_frame_count =
|
||||
ev_counter_stats.group_received_frame_count -
|
||||
counter_stats->group_received_frame_count;
|
||||
counter_stats->fcs_error_count =
|
||||
ev_counter_stats.fcs_error_count -
|
||||
counter_stats->fcs_error_count;
|
||||
counter_stats->transmitted_frame_count =
|
||||
ev_counter_stats.transmitted_frame_count -
|
||||
counter_stats->transmitted_frame_count;
|
||||
break;
|
||||
case STA_STAT_GROUP_ID_MAC_STATS:
|
||||
mac_stats->rts_success_count =
|
||||
ev_mac_stats.rts_success_count -
|
||||
mac_stats->rts_success_count;
|
||||
mac_stats->rts_failure_count =
|
||||
ev_mac_stats.rts_failure_count -
|
||||
mac_stats->rts_failure_count;
|
||||
mac_stats->ack_failure_count =
|
||||
ev_mac_stats.ack_failure_count -
|
||||
mac_stats->ack_failure_count;
|
||||
break;
|
||||
default:
|
||||
pe_debug("group id not supported");
|
||||
}
|
||||
pe_nofl_debug("counter stats: group frame count ( tx %d rx %d ) failed_count %d fcs_error %d tx frame count %d mac stats: rts success count %d rts fail count %d ack fail count %d",
|
||||
counter_stats->group_transmitted_frame_count,
|
||||
counter_stats->group_received_frame_count,
|
||||
counter_stats->failed_count,
|
||||
counter_stats->fcs_error_count,
|
||||
counter_stats->transmitted_frame_count,
|
||||
mac_stats->rts_success_count,
|
||||
mac_stats->rts_failure_count,
|
||||
mac_stats->ack_failure_count);
|
||||
}
|
||||
|
||||
/**
|
||||
* rmm_sta_stats_response_cb: RRM sta stats response callback
|
||||
* @ev: cp stats event
|
||||
* @cookie: NULL
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static inline
|
||||
void rmm_sta_stats_response_cb(struct infra_cp_stats_event *ev, void *cookie)
|
||||
{
|
||||
struct mac_context *mac;
|
||||
struct pe_session *session;
|
||||
uint8_t vdev_id, index;
|
||||
QDF_STATUS status;
|
||||
tpRRMReq pcurrent_req;
|
||||
tSirMacRadioMeasureReport *rrm_report;
|
||||
|
||||
mac = cds_get_context(QDF_MODULE_ID_PE);
|
||||
if (!mac)
|
||||
return;
|
||||
index = mac->rrm.rrmPEContext.rrm_sta_stats.index;
|
||||
|
||||
/* Deregister callback registered in request */
|
||||
status = wlan_cp_stats_infra_cp_deregister_resp_cb(mac->psoc);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
pe_err("failed to deregister callback %d", status);
|
||||
|
||||
pcurrent_req = mac->rrm.rrmPEContext.pCurrentReq[index];
|
||||
if (!pcurrent_req) {
|
||||
pe_err("Current request is NULL");
|
||||
qdf_mem_zero(&mac->rrm.rrmPEContext.rrm_sta_stats,
|
||||
sizeof(mac->rrm.rrmPEContext.rrm_sta_stats));
|
||||
return;
|
||||
}
|
||||
|
||||
vdev_id = mac->rrm.rrmPEContext.rrm_sta_stats.vdev_id;
|
||||
session = pe_find_session_by_vdev_id(mac, vdev_id);
|
||||
if (!session) {
|
||||
pe_err("Session does not exist for given vdev id %d", vdev_id);
|
||||
rrm_cleanup(mac, mac->rrm.rrmPEContext.rrm_sta_stats.index);
|
||||
return;
|
||||
}
|
||||
|
||||
rrm_report = &mac->rrm.rrmPEContext.rrm_sta_stats.rrm_report;
|
||||
rrm_update_mac_cp_stats(ev, mac);
|
||||
|
||||
/* Update resp counter for every response to find second resp*/
|
||||
mac->rrm.rrmPEContext.rrm_sta_stats.rrm_sta_stats_res_count++;
|
||||
/* Send current stats if meas duration is 0. */
|
||||
if (mac->rrm.rrmPEContext.rrm_sta_stats.rrm_sta_stats_res_count ==
|
||||
MAX_RMM_STA_STATS_REQUESTED ||
|
||||
!rrm_report->report.statistics_report.meas_duration) {
|
||||
lim_send_radio_measure_report_action_frame(
|
||||
mac, pcurrent_req->dialog_token, 1, true,
|
||||
&mac->rrm.rrmPEContext.rrm_sta_stats.rrm_report,
|
||||
mac->rrm.rrmPEContext.rrm_sta_stats.peer, session);
|
||||
|
||||
rrm_cleanup(mac, index);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* rrm_update_vdev_stats: Update RRM stats from DP
|
||||
* @rrm_report: RRM Measurement Report
|
||||
* @vdev_id: vdev_id
|
||||
*
|
||||
* Return: QDF STATUS
|
||||
*/
|
||||
static QDF_STATUS
|
||||
rrm_update_vdev_stats(tpSirMacRadioMeasureReport rrm_report, uint8_t vdev_id)
|
||||
{
|
||||
struct cdp_vdev_stats *stats;
|
||||
QDF_STATUS status;
|
||||
struct counter_stats *counter_stats;
|
||||
struct mac_stats *mac_stats;
|
||||
|
||||
counter_stats =
|
||||
&rrm_report->report.statistics_report.group_stats.counter_stats;
|
||||
mac_stats =
|
||||
&rrm_report->report.statistics_report.group_stats.mac_stats;
|
||||
|
||||
stats = qdf_mem_malloc(sizeof(*stats));
|
||||
if (!stats)
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
|
||||
status =
|
||||
cdp_host_get_vdev_stats(cds_get_context(QDF_MODULE_ID_SOC),
|
||||
vdev_id, stats, true);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
pe_err("Failed to get stats %d", status);
|
||||
qdf_mem_free(stats);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
pe_nofl_debug("counter stats count: fragment (tx: %d rx: %d) mac stats count: retry : %d multiple retry: %d frame duplicate %d",
|
||||
stats->tx.fragment_count, stats->rx.fragment_count,
|
||||
stats->tx.retry_count, stats->tx.multiple_retry_count,
|
||||
stats->rx.duplicate_count);
|
||||
|
||||
switch (rrm_report->report.statistics_report.group_id) {
|
||||
case STA_STAT_GROUP_ID_COUNTER_STATS:
|
||||
counter_stats->transmitted_fragment_count =
|
||||
stats->tx.fragment_count -
|
||||
counter_stats->transmitted_fragment_count;
|
||||
counter_stats->received_fragment_count =
|
||||
stats->rx.fragment_count -
|
||||
counter_stats->received_fragment_count;
|
||||
break;
|
||||
case STA_STAT_GROUP_ID_MAC_STATS:
|
||||
mac_stats->retry_count =
|
||||
stats->tx.retry_count - mac_stats->retry_count;
|
||||
mac_stats->multiple_retry_count =
|
||||
stats->tx.multiple_retry_count -
|
||||
mac_stats->multiple_retry_count;
|
||||
mac_stats->frame_duplicate_count =
|
||||
stats->rx.duplicate_count -
|
||||
mac_stats->frame_duplicate_count;
|
||||
break;
|
||||
}
|
||||
qdf_mem_free(stats);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
rrm_send_sta_stats_req(struct mac_context *mac,
|
||||
struct pe_session *session,
|
||||
tSirMacAddr peer_mac)
|
||||
{
|
||||
struct infra_cp_stats_cmd_info info = {0};
|
||||
get_infra_cp_stats_cb resp_cb = NULL;
|
||||
void *context;
|
||||
QDF_STATUS status;
|
||||
tpSirMacRadioMeasureReport report;
|
||||
|
||||
status = wlan_cp_stats_infra_cp_get_context(mac->psoc, &resp_cb,
|
||||
&context);
|
||||
if (resp_cb) {
|
||||
pe_err("another request already in progress");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
info.request_cookie = NULL;
|
||||
info.stats_id = TYPE_REQ_CTRL_PATH_RRM_STA_STAT;
|
||||
info.action = ACTION_REQ_CTRL_PATH_STAT_GET;
|
||||
info.infra_cp_stats_resp_cb = rmm_sta_stats_response_cb;
|
||||
info.num_pdev_ids = 0;
|
||||
info.num_vdev_ids = MAX_CTRL_STAT_VDEV_ENTRIES;
|
||||
info.vdev_id[0] = wlan_vdev_get_id(session->vdev);
|
||||
info.num_mac_addr_list = MAX_CTRL_STAT_MAC_ADDR_ENTRIES;
|
||||
info.num_pdev_ids = 0;
|
||||
/*
|
||||
* FW doesn't send vdev id in response path.
|
||||
* So, vdev id will be used to get session
|
||||
* in callback.
|
||||
*/
|
||||
mac->rrm.rrmPEContext.rrm_sta_stats.vdev_id =
|
||||
wlan_vdev_get_id(session->vdev);
|
||||
qdf_mem_copy(&info.peer_mac_addr[0], peer_mac, QDF_MAC_ADDR_SIZE);
|
||||
report = &mac->rrm.rrmPEContext.rrm_sta_stats.rrm_report;
|
||||
|
||||
status = rrm_update_vdev_stats(report, wlan_vdev_get_id(session->vdev));
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
pe_err("Failed to register resp callback: %d", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = wlan_cp_stats_infra_cp_register_resp_cb(mac->psoc, &info);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
pe_err("Failed to register resp callback: %d", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = wlan_cp_stats_send_infra_cp_req(mac->psoc, &info);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
pe_err("Failed to send stats request status: %d", status);
|
||||
goto get_stats_fail;
|
||||
}
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
get_stats_fail:
|
||||
status = wlan_cp_stats_infra_cp_deregister_resp_cb(mac->psoc);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
pe_err("failed to deregister callback %d", status);
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* rrm_process_sta_stats_report_req: Process RRM sta stats request
|
||||
* @mac: mac context
|
||||
* @pCurrentReq: Current RRM request
|
||||
* @pStaStatsReq: RRM Measurement Request
|
||||
* @pe_session: pe session
|
||||
*
|
||||
* Return: rrm status
|
||||
*/
|
||||
static tRrmRetStatus
|
||||
rrm_process_sta_stats_report_req(struct mac_context *mac,
|
||||
tpRRMReq pCurrentReq,
|
||||
tDot11fIEMeasurementRequest *sta_stats_req,
|
||||
struct pe_session *pe_session)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
uint8_t meas_duration = 1;
|
||||
struct rrm_sta_stats *rrm_sta_statistics;
|
||||
|
||||
if (sta_stats_req->measurement_request.sta_stats.meas_duration >
|
||||
MAX_MEAS_DURATION_FOR_STA_STATS) {
|
||||
pe_err("Dropping req measurement duration > threshold %d",
|
||||
sta_stats_req->measurement_request.sta_stats.meas_duration);
|
||||
return eRRM_INCAPABLE;
|
||||
}
|
||||
|
||||
if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)
|
||||
sta_stats_req->measurement_request.sta_stats.peer_mac_addr)) {
|
||||
pe_err("Dropping req: broadcast address not supported");
|
||||
return eRRM_INCAPABLE;
|
||||
}
|
||||
|
||||
rrm_sta_statistics = &mac->rrm.rrmPEContext.rrm_sta_stats;
|
||||
if (sta_stats_req->measurement_request.sta_stats.meas_duration)
|
||||
meas_duration =
|
||||
sta_stats_req->measurement_request.sta_stats.meas_duration;
|
||||
|
||||
rrm_sta_statistics->rrm_report.token = pCurrentReq->token;
|
||||
rrm_sta_statistics->rrm_report.type = pCurrentReq->type;
|
||||
rrm_sta_statistics->rrm_report.refused = 0;
|
||||
rrm_sta_statistics->rrm_report.incapable = 0;
|
||||
rrm_sta_statistics->rrm_report.report.statistics_report.group_id =
|
||||
sta_stats_req->measurement_request.sta_stats.group_identity;
|
||||
rrm_sta_statistics->rrm_report.report.statistics_report.meas_duration
|
||||
= sta_stats_req->measurement_request.sta_stats.meas_duration;
|
||||
|
||||
switch (sta_stats_req->measurement_request.sta_stats.group_identity) {
|
||||
case STA_STAT_GROUP_ID_COUNTER_STATS:
|
||||
case STA_STAT_GROUP_ID_MAC_STATS:
|
||||
status =
|
||||
rrm_send_sta_stats_req(
|
||||
mac, pe_session,
|
||||
sta_stats_req->measurement_request.sta_stats.peer_mac_addr);
|
||||
if (!QDF_IS_STATUS_SUCCESS(status))
|
||||
return eRRM_REFUSED;
|
||||
mac->lim.lim_timers.rrm_sta_stats_resp_timer.sessionId =
|
||||
pe_session->peSessionId;
|
||||
/*
|
||||
* Start timer of 1 sec even if meas duration is 0.
|
||||
* To get stats from FW.
|
||||
*/
|
||||
tx_timer_change(&mac->lim.lim_timers.rrm_sta_stats_resp_timer,
|
||||
SYS_MS_TO_TICKS(meas_duration * 1000), 0);
|
||||
/* Activate sta stats resp timer */
|
||||
if (tx_timer_activate(
|
||||
&mac->lim.lim_timers.rrm_sta_stats_resp_timer) !=
|
||||
TX_SUCCESS) {
|
||||
pe_err("failed to start sta stats timer");
|
||||
return eRRM_REFUSED;
|
||||
}
|
||||
break;
|
||||
case STA_STAT_GROUP_ID_DELAY_STATS:
|
||||
/* TODO: update access delay from scan IE */
|
||||
default:
|
||||
pe_nofl_err("group id %d not supported",
|
||||
sta_stats_req->measurement_request.sta_stats.group_identity);
|
||||
return eRRM_INCAPABLE;
|
||||
}
|
||||
return eRRM_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
rrm_process_rrm_sta_stats_request_failure(struct mac_context *mac,
|
||||
struct pe_session *pe_session,
|
||||
tSirMacAddr peer,
|
||||
tRrmRetStatus status, uint8_t index)
|
||||
{
|
||||
tpSirMacRadioMeasureReport p_report = NULL;
|
||||
tpRRMReq p_current_req = mac->rrm.rrmPEContext.pCurrentReq[index];
|
||||
|
||||
if (!p_current_req) {
|
||||
pe_err("Current request is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
p_report = qdf_mem_malloc(sizeof(tSirMacRadioMeasureReport));
|
||||
if (!p_report)
|
||||
return;
|
||||
p_report->token = p_current_req->token;
|
||||
p_report->type = SIR_MAC_RRM_STA_STATISTICS_TYPE;
|
||||
|
||||
pe_debug("Measurement index:%d status %d token %d", index, status,
|
||||
p_report->token);
|
||||
|
||||
switch (status) {
|
||||
case eRRM_FAILURE: /* fallthrough */
|
||||
case eRRM_REFUSED:
|
||||
p_report->refused = 1;
|
||||
break;
|
||||
case eRRM_INCAPABLE:
|
||||
p_report->incapable = 1;
|
||||
break;
|
||||
default:
|
||||
pe_err("Invalid RRM status, failed to send report");
|
||||
qdf_mem_free(p_report);
|
||||
return;
|
||||
}
|
||||
|
||||
lim_send_radio_measure_report_action_frame(mac,
|
||||
p_current_req->dialog_token,
|
||||
1, true,
|
||||
p_report, peer,
|
||||
pe_session);
|
||||
|
||||
qdf_mem_free(p_report);
|
||||
}
|
||||
|
||||
/**
|
||||
* rrm_check_other_sta_sats_req_in_progress: To check if any other sta stats req
|
||||
* in progress
|
||||
* @rrm_req: measurement request
|
||||
*
|
||||
* To avoid any conflict between multiple sta stats request at time of callback
|
||||
* response from FW handle one sta stats request at a time.
|
||||
*
|
||||
* Return: true/false
|
||||
*/
|
||||
static bool
|
||||
rrm_check_other_sta_sats_req_in_progress(
|
||||
tDot11fRadioMeasurementRequest *rrm_req)
|
||||
{
|
||||
uint8_t count = 0, i = 0;
|
||||
|
||||
for (i = 0; i < MAX_MEASUREMENT_REQUEST; i++) {
|
||||
if (rrm_req->MeasurementRequest[i].measurement_type ==
|
||||
SIR_MAC_RRM_STA_STATISTICS_TYPE)
|
||||
count++;
|
||||
if (count > 1)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* rrm_process_sta_stats_req: Process RRM sta stats request
|
||||
* @mac: mac context
|
||||
* @session_entry: pe session
|
||||
* @radiomes_report: measurement report
|
||||
* @rrm_req: measurement request
|
||||
* @num_report: no of reports
|
||||
* @index: index of request
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static
|
||||
QDF_STATUS rrm_process_sta_stats_req(
|
||||
struct mac_context *mac, tSirMacAddr peer,
|
||||
struct pe_session *session_entry,
|
||||
tpSirMacRadioMeasureReport *radiomes_report,
|
||||
tDot11fRadioMeasurementRequest *rrm_req,
|
||||
uint8_t *num_report, int index)
|
||||
{
|
||||
tRrmRetStatus rrm_status = eRRM_SUCCESS;
|
||||
tpRRMReq curr_req;
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
|
||||
if (index >= MAX_MEASUREMENT_REQUEST) {
|
||||
status = rrm_reject_req(radiomes_report,
|
||||
rrm_req, num_report, index,
|
||||
rrm_req->MeasurementRequest[0].
|
||||
measurement_type);
|
||||
return status;
|
||||
}
|
||||
|
||||
if (rrm_check_other_sta_sats_req_in_progress(rrm_req)) {
|
||||
pe_debug("another sta stats request already in progress");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
curr_req = qdf_mem_malloc(sizeof(*curr_req));
|
||||
if (!curr_req) {
|
||||
mac->rrm.rrmPEContext.pCurrentReq[index] = NULL;
|
||||
qdf_mem_zero(&mac->rrm.rrmPEContext.rrm_sta_stats,
|
||||
sizeof(mac->rrm.rrmPEContext.rrm_sta_stats));
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
|
||||
curr_req->dialog_token = rrm_req->DialogToken.token;
|
||||
curr_req->token =
|
||||
rrm_req->MeasurementRequest[index].measurement_token;
|
||||
curr_req->measurement_idx = index;
|
||||
curr_req->type = rrm_req->MeasurementRequest[index].measurement_type;
|
||||
|
||||
|
||||
qdf_mem_set(&mac->rrm.rrmPEContext.rrm_sta_stats,
|
||||
sizeof(mac->rrm.rrmPEContext.rrm_sta_stats), 0);
|
||||
|
||||
mac->rrm.rrmPEContext.rrm_sta_stats.index = index;
|
||||
mac->rrm.rrmPEContext.pCurrentReq[index] = curr_req;
|
||||
mac->rrm.rrmPEContext.num_active_request++;
|
||||
qdf_mem_copy(mac->rrm.rrmPEContext.rrm_sta_stats.peer,
|
||||
peer,
|
||||
QDF_MAC_ADDR_SIZE);
|
||||
|
||||
pe_debug("Processing sta stats Report req %d num_active_req:%d",
|
||||
index, mac->rrm.rrmPEContext.num_active_request);
|
||||
|
||||
rrm_status = rrm_process_sta_stats_report_req(mac, curr_req,
|
||||
&rrm_req->MeasurementRequest[index], session_entry);
|
||||
if (eRRM_SUCCESS != rrm_status)
|
||||
goto failure;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
failure:
|
||||
rrm_process_rrm_sta_stats_request_failure(
|
||||
mac, session_entry, peer, rrm_status, index);
|
||||
|
||||
rrm_cleanup(mac, index);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/**
|
||||
* rrm_get_max_meas_duration() - calculate max measurement duration for a
|
||||
@@ -1849,6 +2358,12 @@ rrm_process_radio_measurement_request(struct mac_context *mac_ctx,
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return status;
|
||||
break;
|
||||
case SIR_MAC_RRM_STA_STATISTICS_TYPE:
|
||||
status = rrm_process_sta_stats_req(mac_ctx, peer,
|
||||
session_entry, &report,
|
||||
rrm_req, &num_report,
|
||||
i);
|
||||
break;
|
||||
case SIR_MAC_RRM_LCI_TYPE:
|
||||
case SIR_MAC_RRM_LOCATION_CIVIC_TYPE:
|
||||
case SIR_MAC_RRM_FINE_TIME_MEAS_TYPE:
|
||||
@@ -1958,17 +2473,25 @@ void rrm_cleanup(struct mac_context *mac, uint8_t idx)
|
||||
{
|
||||
tpRRMReq cur_rrm_req = NULL;
|
||||
|
||||
mac->rrm.rrmPEContext.num_active_request--;
|
||||
if (mac->rrm.rrmPEContext.num_active_request)
|
||||
mac->rrm.rrmPEContext.num_active_request--;
|
||||
|
||||
cur_rrm_req = mac->rrm.rrmPEContext.pCurrentReq[idx];
|
||||
if (!cur_rrm_req)
|
||||
return;
|
||||
|
||||
if (cur_rrm_req->request.Beacon.reqIes.num) {
|
||||
qdf_mem_free(cur_rrm_req->request.Beacon.reqIes.pElementIds);
|
||||
cur_rrm_req->request.Beacon.reqIes.pElementIds = NULL;
|
||||
cur_rrm_req->request.Beacon.reqIes.num = 0;
|
||||
}
|
||||
|
||||
if (cur_rrm_req->type == SIR_MAC_RRM_STA_STATISTICS_TYPE) {
|
||||
pe_debug("deactivate rrm sta stats timer");
|
||||
lim_deactivate_and_change_timer(mac,
|
||||
eLIM_RRM_STA_STATS_RSP_TIMER);
|
||||
qdf_mem_zero(&mac->rrm.rrmPEContext.rrm_sta_stats,
|
||||
sizeof(mac->rrm.rrmPEContext.rrm_sta_stats));
|
||||
}
|
||||
qdf_mem_free(cur_rrm_req);
|
||||
mac->rrm.rrmPEContext.pCurrentReq[idx] = NULL;
|
||||
|
||||
|
@@ -588,6 +588,7 @@ uint8_t *mac_trace_get_lim_msg_string(uint16_t lim_msg)
|
||||
CASE_RETURN_STRING(SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT);
|
||||
CASE_RETURN_STRING(SIR_LIM_AUTH_RETRY_TIMEOUT);
|
||||
CASE_RETURN_STRING(SIR_LIM_AUTH_SAE_TIMEOUT);
|
||||
CASE_RETURN_STRING(SIR_LIM_RRM_STA_STATS_RSP_TIMEOUT);
|
||||
CASE_RETURN_STRING(SIR_LIM_MSG_TYPES_END);
|
||||
CASE_RETURN_STRING(LIM_MLM_SCAN_REQ);
|
||||
CASE_RETURN_STRING(LIM_MLM_SCAN_CNF);
|
||||
|
@@ -7086,6 +7086,15 @@ populate_dot11f_chan_load_report(struct mac_context *mac,
|
||||
dot11f->report.channel_load_report.chan_load);
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
populate_dot11f_rrm_sta_stats_report(
|
||||
struct mac_context *mac, tDot11fIEMeasurementReport *pdot11f,
|
||||
struct statistics_report *statistics_report)
|
||||
{
|
||||
/* TODO: populate measurement report */
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
populate_dot11f_beacon_report(struct mac_context *mac,
|
||||
tDot11fIEMeasurementReport *pDot11f,
|
||||
|
Reference in New Issue
Block a user