qcacld-3.0: Allow the driver to process multiple measurement req

As per requirement, the driver should able to process up to
MAX_MEASUREMENT_REQUEST (5) measurement request in a single
beacon report request.

Update driver logic to process up to 5 measurement request and
make sure the driver should not issue rrm scan for the duplicate
channel.

Change-Id: Iea3be8a0efef605852ac6b6b54dd06774ac0adac
CRs-Fixed: 2712112
This commit is contained in:
Abhinav Kumar
2020-06-09 11:44:47 +05:30
committed by nshrivas
parent 8ece9b14c2
commit 7d3c309952
4 changed files with 166 additions and 53 deletions

View File

@@ -90,6 +90,24 @@ QDF_STATUS
rrm_process_beacon_report_xmit(struct mac_context *mac_ctx, rrm_process_beacon_report_xmit(struct mac_context *mac_ctx,
tpSirBeaconReportXmitInd beacon_xmit_ind); tpSirBeaconReportXmitInd beacon_xmit_ind);
/**
* rrm_reject_req - Reject rrm request
* @radiomes_report: radio measurement report
* @rrm_req: Array of Measurement request IEs
* @num_report: Num of report
* @index: Measurement index
* @measurement_type: Measurement Type
*
* Reject the Radio Resource Measurement request, if one is
* already in progress
*
* Return: QDF_STATUS
*/
QDF_STATUS rrm_reject_req(tpSirMacRadioMeasureReport *radiomes_report,
tDot11fRadioMeasurementRequest *rrm_req,
uint8_t *num_report, uint8_t index,
uint8_t measurement_type);
void lim_update_rrm_capability(struct mac_context *mac_ctx, void lim_update_rrm_capability(struct mac_context *mac_ctx,
struct join_req *join_req); struct join_req *join_req);
#endif #endif

View File

@@ -27,7 +27,9 @@
========================================================================*/ ========================================================================*/
#define MAX_MEASUREMENT_REQUEST 2 #define MAX_MEASUREMENT_REQUEST 5
#define MAX_NUM_CHANNELS 255
#define DEFAULT_RRM_IDX 0 #define DEFAULT_RRM_IDX 0
typedef enum eRrmRetStatus { typedef enum eRrmRetStatus {
@@ -219,6 +221,8 @@ typedef struct sRrmPEContext {
uint8_t DialogToken; uint8_t DialogToken;
uint16_t prev_rrm_report_seq_num; uint16_t prev_rrm_report_seq_num;
tpRRMReq pCurrentReq[MAX_MEASUREMENT_REQUEST]; tpRRMReq pCurrentReq[MAX_MEASUREMENT_REQUEST];
uint32_t beacon_rpt_chan_list[MAX_NUM_CHANNELS];
uint8_t beacon_rpt_chan_num;
} tRrmPEContext, *tpRrmPEContext; } tRrmPEContext, *tpRrmPEContext;
/* 2008 11k spec reference: 18.4.8.5 RCPI Measurement */ /* 2008 11k spec reference: 18.4.8.5 RCPI Measurement */

View File

@@ -1178,55 +1178,33 @@ QDF_STATUS rrm_process_beacon_req(struct mac_context *mac_ctx, tSirMacAddr peer,
tRrmRetStatus rrm_status = eRRM_SUCCESS; tRrmRetStatus rrm_status = eRRM_SUCCESS;
tpSirMacRadioMeasureReport report; tpSirMacRadioMeasureReport report;
tpRRMReq curr_req; tpRRMReq curr_req;
QDF_STATUS status = QDF_STATUS_SUCCESS;
if (index >= MAX_MEASUREMENT_REQUEST || if (index >= MAX_MEASUREMENT_REQUEST) {
mac_ctx->rrm.rrmPEContext.pCurrentReq[index]) { status = rrm_reject_req(&report, rrm_req, num_report, index,
if (!*radiomes_report) { rrm_req->MeasurementRequest[index].
/* measurement_type);
* Allocate memory to send reports for return status;
* any subsequent requests. }
*/
*radiomes_report = qdf_mem_malloc(sizeof(*report) *
(rrm_req->num_MeasurementRequest - index));
if (!*radiomes_report)
return QDF_STATUS_E_NOMEM;
pe_debug("rrm beacon type refused of %d report in beacon table",
*num_report);
}
report = *radiomes_report;
report[*num_report].refused = 1;
report[*num_report].type = SIR_MAC_RRM_BEACON_TYPE;
report[*num_report].token =
rrm_req->MeasurementRequest[index].measurement_token;
(*num_report)++;
return QDF_STATUS_SUCCESS;
} else {
curr_req = mac_ctx->rrm.rrmPEContext.pCurrentReq[index];
if (curr_req) {
qdf_mem_free(curr_req);
mac_ctx->rrm.rrmPEContext.pCurrentReq[index] = NULL;
}
curr_req = qdf_mem_malloc(sizeof(*curr_req)); curr_req = qdf_mem_malloc(sizeof(*curr_req));
if (!curr_req) { if (!curr_req) {
qdf_mem_free(*radiomes_report); mac_ctx->rrm.rrmPEContext.pCurrentReq[index] = NULL;
mac_ctx->rrm.rrmPEContext.pCurrentReq[index] = NULL; return QDF_STATUS_E_NOMEM;
return QDF_STATUS_E_NOMEM; }
} pe_debug("Processing Beacon Report request %d", index);
pe_debug("Processing Beacon Report request %d", index); curr_req->dialog_token = rrm_req->DialogToken.token;
curr_req->dialog_token = rrm_req->DialogToken.token; curr_req->token =
curr_req->token = rrm_req-> rrm_req->MeasurementRequest[index].measurement_token;
MeasurementRequest[index].measurement_token; curr_req->sendEmptyBcnRpt = true;
curr_req->sendEmptyBcnRpt = true; curr_req->measurement_idx = index;
curr_req->measurement_idx = index; mac_ctx->rrm.rrmPEContext.pCurrentReq[index] = curr_req;
mac_ctx->rrm.rrmPEContext.pCurrentReq[index] = curr_req; rrm_status = rrm_process_beacon_report_req(mac_ctx, curr_req,
rrm_status = rrm_process_beacon_report_req(mac_ctx, curr_req, &rrm_req->MeasurementRequest[index], session_entry);
&rrm_req->MeasurementRequest[index], session_entry); if (eRRM_SUCCESS != rrm_status) {
if (eRRM_SUCCESS != rrm_status) { rrm_process_beacon_request_failure(mac_ctx,
rrm_process_beacon_request_failure(mac_ctx, session_entry, peer, rrm_status, index);
session_entry, peer, rrm_status, index); rrm_cleanup(mac_ctx, index);
rrm_cleanup(mac_ctx, index);
}
} }
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
@@ -1273,6 +1251,37 @@ QDF_STATUS update_rrm_report(struct mac_context *mac_ctx,
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }
QDF_STATUS rrm_reject_req(tpSirMacRadioMeasureReport *radiomes_report,
tDot11fRadioMeasurementRequest *rrm_req,
uint8_t *num_report, uint8_t index,
uint8_t measurement_type)
{
tpSirMacRadioMeasureReport report;
if (!*radiomes_report) {
/*
* Allocate memory to send reports for
* any subsequent requests.
*/
*radiomes_report = qdf_mem_malloc(sizeof(*report) *
(rrm_req->num_MeasurementRequest - index));
if (!*radiomes_report)
return QDF_STATUS_E_NOMEM;
pe_debug("rrm beacon refused of %d report, index: %d in beacon table",
*num_report, index);
}
report = *radiomes_report;
report[*num_report].refused = 1;
report[*num_report].type = measurement_type;
report[*num_report].token =
rrm_req->MeasurementRequest[index].measurement_token;
(*num_report)++;
return QDF_STATUS_SUCCESS;
}
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
/** /**
* rrm_process_radio_measurement_request - Process rrm request * rrm_process_radio_measurement_request - Process rrm request
@@ -1291,10 +1300,11 @@ rrm_process_radio_measurement_request(struct mac_context *mac_ctx,
tDot11fRadioMeasurementRequest *rrm_req, tDot11fRadioMeasurementRequest *rrm_req,
struct pe_session *session_entry) struct pe_session *session_entry)
{ {
uint8_t i; uint8_t i, index;
QDF_STATUS status = QDF_STATUS_SUCCESS; QDF_STATUS status = QDF_STATUS_SUCCESS;
tpSirMacRadioMeasureReport report = NULL; tpSirMacRadioMeasureReport report = NULL;
uint8_t num_report = 0; uint8_t num_report = 0;
bool reject = false;
if (!rrm_req->num_MeasurementRequest) { if (!rrm_req->num_MeasurementRequest) {
report = qdf_mem_malloc(sizeof(tSirMacRadioMeasureReport)); report = qdf_mem_malloc(sizeof(tSirMacRadioMeasureReport));
@@ -1326,6 +1336,41 @@ rrm_process_radio_measurement_request(struct mac_context *mac_ctx,
goto end; goto end;
} }
for(index = 0; index < MAX_MEASUREMENT_REQUEST; index++)
{
if ( mac_ctx->rrm.rrmPEContext.pCurrentReq[index]) {
reject = true;
pe_debug("RRM req for index: %d is already in progress",
index);
break;
}
}
if (reject == true)
{
for (i = 0; i < rrm_req->num_MeasurementRequest; i++) {
status =
rrm_reject_req(&report, rrm_req, &num_report, i,
rrm_req->MeasurementRequest[i].
measurement_type);
if (QDF_IS_STATUS_ERROR(status)) {
pe_debug("Fail to Reject rrm req for index: %d",
i);
return status;
}
}
goto end;
}
/*
* Clear global beacon_rpt_chan_list before processing every new
* beacon report request.
*/
qdf_mem_zero(mac_ctx->rrm.rrmPEContext.beacon_rpt_chan_list,
sizeof(uint8_t) * MAX_NUM_CHANNELS);
mac_ctx->rrm.rrmPEContext.beacon_rpt_chan_num = 0;
for (i = 0; i < rrm_req->num_MeasurementRequest; i++) { for (i = 0; i < rrm_req->num_MeasurementRequest; i++) {
switch (rrm_req->MeasurementRequest[i].measurement_type) { switch (rrm_req->MeasurementRequest[i].measurement_type) {
case SIR_MAC_RRM_BEACON_TYPE: case SIR_MAC_RRM_BEACON_TYPE:

View File

@@ -1100,17 +1100,19 @@ QDF_STATUS sme_rrm_process_beacon_report_req_ind(struct mac_context *mac,
{ {
tpSirBeaconReportReqInd beacon_req = (tpSirBeaconReportReqInd)msg_buf; tpSirBeaconReportReqInd beacon_req = (tpSirBeaconReportReqInd)msg_buf;
tpRrmSMEContext sme_rrm_ctx; tpRrmSMEContext sme_rrm_ctx;
uint32_t len = 0, i = 0; uint32_t len = 0, i = 0, j = 0;
uint8_t country[WNI_CFG_COUNTRY_CODE_LEN]; uint8_t country[WNI_CFG_COUNTRY_CODE_LEN];
uint32_t session_id; uint32_t session_id;
struct csr_roam_session *session; struct csr_roam_session *session;
QDF_STATUS status; QDF_STATUS status;
uint32_t num_chan; uint32_t num_chan, local_num_channel;
bool chan_valid; bool chan_valid;
uint32_t *rrm_freq_list; uint32_t *rrm_freq_list, *local_rrm_freq_list;
uint32_t bcn_chan_freq; uint32_t bcn_chan_freq, local_bcn_chan_freq;
tRrmPEContext rrm_context;
sme_rrm_ctx = &mac->rrm.rrmSmeContext[beacon_req->measurement_idx]; sme_rrm_ctx = &mac->rrm.rrmSmeContext[beacon_req->measurement_idx];
rrm_context = mac->rrm.rrmPEContext;
status = csr_roam_get_session_id_from_bssid(mac, (struct qdf_mac_addr *) status = csr_roam_get_session_id_from_bssid(mac, (struct qdf_mac_addr *)
beacon_req->bssId, beacon_req->bssId,
@@ -1235,6 +1237,50 @@ QDF_STATUS sme_rrm_process_beacon_report_req_ind(struct mac_context *mac,
sme_rrm_ctx->channelList.numOfChannels = num_chan; sme_rrm_ctx->channelList.numOfChannels = num_chan;
} }
local_rrm_freq_list = sme_rrm_ctx->channelList.freq_list;
local_num_channel = 0;
for (i = 0; i < sme_rrm_ctx->channelList.numOfChannels; i++) {
local_bcn_chan_freq = local_rrm_freq_list[i];
chan_valid = true;
if (beacon_req->measurement_idx > 0) {
for (j = 0; j < rrm_context.beacon_rpt_chan_num; j ++) {
if (rrm_context.beacon_rpt_chan_list[j] ==
local_bcn_chan_freq) {
/*
* Ignore this channel, As this is already
* included in previous request
*/
chan_valid = false;
break;
}
}
}
if (chan_valid) {
rrm_context.
beacon_rpt_chan_list[rrm_context.beacon_rpt_chan_num] =
local_bcn_chan_freq;
rrm_context.beacon_rpt_chan_num++;
if (rrm_context.beacon_rpt_chan_num >=
MAX_NUM_CHANNELS) {
/* this should never happen */
sme_err("Reset beacon_rpt_chan_num : %d",
rrm_context.beacon_rpt_chan_num);
rrm_context.beacon_rpt_chan_num = 0;
}
local_rrm_freq_list[local_num_channel] =
local_bcn_chan_freq;
local_num_channel++;
}
}
if (local_num_channel == 0)
goto cleanup;
sme_rrm_ctx->channelList.numOfChannels = local_num_channel;
/* Copy session bssid */ /* Copy session bssid */
qdf_mem_copy(sme_rrm_ctx->sessionBssId.bytes, beacon_req->bssId, qdf_mem_copy(sme_rrm_ctx->sessionBssId.bytes, beacon_req->bssId,
sizeof(tSirMacAddr)); sizeof(tSirMacAddr));