From 7d3c30995281573fe4bead6e30334470ae92636f Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Tue, 9 Jun 2020 11:44:47 +0530 Subject: [PATCH] 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 --- core/mac/src/pe/include/rrm_api.h | 18 ++++ core/mac/src/pe/include/rrm_global.h | 6 +- core/mac/src/pe/rrm/rrm_api.c | 141 ++++++++++++++++++--------- core/sme/src/rrm/sme_rrm.c | 54 +++++++++- 4 files changed, 166 insertions(+), 53 deletions(-) diff --git a/core/mac/src/pe/include/rrm_api.h b/core/mac/src/pe/include/rrm_api.h index 45f7ddab16..c874bf3786 100644 --- a/core/mac/src/pe/include/rrm_api.h +++ b/core/mac/src/pe/include/rrm_api.h @@ -90,6 +90,24 @@ QDF_STATUS rrm_process_beacon_report_xmit(struct mac_context *mac_ctx, 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, struct join_req *join_req); #endif diff --git a/core/mac/src/pe/include/rrm_global.h b/core/mac/src/pe/include/rrm_global.h index 3e23935db4..ebb3a18da7 100644 --- a/core/mac/src/pe/include/rrm_global.h +++ b/core/mac/src/pe/include/rrm_global.h @@ -27,7 +27,9 @@ ========================================================================*/ -#define MAX_MEASUREMENT_REQUEST 2 +#define MAX_MEASUREMENT_REQUEST 5 +#define MAX_NUM_CHANNELS 255 + #define DEFAULT_RRM_IDX 0 typedef enum eRrmRetStatus { @@ -219,6 +221,8 @@ typedef struct sRrmPEContext { uint8_t DialogToken; uint16_t prev_rrm_report_seq_num; tpRRMReq pCurrentReq[MAX_MEASUREMENT_REQUEST]; + uint32_t beacon_rpt_chan_list[MAX_NUM_CHANNELS]; + uint8_t beacon_rpt_chan_num; } tRrmPEContext, *tpRrmPEContext; /* 2008 11k spec reference: 18.4.8.5 RCPI Measurement */ diff --git a/core/mac/src/pe/rrm/rrm_api.c b/core/mac/src/pe/rrm/rrm_api.c index 4768e987ee..d474d29c84 100644 --- a/core/mac/src/pe/rrm/rrm_api.c +++ b/core/mac/src/pe/rrm/rrm_api.c @@ -1178,55 +1178,33 @@ QDF_STATUS rrm_process_beacon_req(struct mac_context *mac_ctx, tSirMacAddr peer, tRrmRetStatus rrm_status = eRRM_SUCCESS; tpSirMacRadioMeasureReport report; tpRRMReq curr_req; + QDF_STATUS status = QDF_STATUS_SUCCESS; - if (index >= MAX_MEASUREMENT_REQUEST || - mac_ctx->rrm.rrmPEContext.pCurrentReq[index]) { - 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 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; - } + if (index >= MAX_MEASUREMENT_REQUEST) { + status = rrm_reject_req(&report, rrm_req, num_report, index, + rrm_req->MeasurementRequest[index]. + measurement_type); + return status; + } - curr_req = qdf_mem_malloc(sizeof(*curr_req)); - if (!curr_req) { - qdf_mem_free(*radiomes_report); - mac_ctx->rrm.rrmPEContext.pCurrentReq[index] = NULL; - return QDF_STATUS_E_NOMEM; - } - pe_debug("Processing Beacon Report request %d", index); - curr_req->dialog_token = rrm_req->DialogToken.token; - curr_req->token = rrm_req-> - MeasurementRequest[index].measurement_token; - curr_req->sendEmptyBcnRpt = true; - curr_req->measurement_idx = index; - mac_ctx->rrm.rrmPEContext.pCurrentReq[index] = curr_req; - rrm_status = rrm_process_beacon_report_req(mac_ctx, curr_req, - &rrm_req->MeasurementRequest[index], session_entry); - if (eRRM_SUCCESS != rrm_status) { - rrm_process_beacon_request_failure(mac_ctx, - session_entry, peer, rrm_status, index); - rrm_cleanup(mac_ctx, index); - } + curr_req = qdf_mem_malloc(sizeof(*curr_req)); + if (!curr_req) { + mac_ctx->rrm.rrmPEContext.pCurrentReq[index] = NULL; + return QDF_STATUS_E_NOMEM; + } + pe_debug("Processing Beacon Report request %d", index); + curr_req->dialog_token = rrm_req->DialogToken.token; + curr_req->token = + rrm_req->MeasurementRequest[index].measurement_token; + curr_req->sendEmptyBcnRpt = true; + curr_req->measurement_idx = index; + mac_ctx->rrm.rrmPEContext.pCurrentReq[index] = curr_req; + rrm_status = rrm_process_beacon_report_req(mac_ctx, curr_req, + &rrm_req->MeasurementRequest[index], session_entry); + if (eRRM_SUCCESS != rrm_status) { + rrm_process_beacon_request_failure(mac_ctx, + session_entry, peer, rrm_status, index); + rrm_cleanup(mac_ctx, index); } return QDF_STATUS_SUCCESS; @@ -1273,6 +1251,37 @@ QDF_STATUS update_rrm_report(struct mac_context *mac_ctx, 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 @@ -1291,10 +1300,11 @@ rrm_process_radio_measurement_request(struct mac_context *mac_ctx, tDot11fRadioMeasurementRequest *rrm_req, struct pe_session *session_entry) { - uint8_t i; + uint8_t i, index; QDF_STATUS status = QDF_STATUS_SUCCESS; tpSirMacRadioMeasureReport report = NULL; uint8_t num_report = 0; + bool reject = false; if (!rrm_req->num_MeasurementRequest) { report = qdf_mem_malloc(sizeof(tSirMacRadioMeasureReport)); @@ -1326,6 +1336,41 @@ rrm_process_radio_measurement_request(struct mac_context *mac_ctx, 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++) { switch (rrm_req->MeasurementRequest[i].measurement_type) { case SIR_MAC_RRM_BEACON_TYPE: diff --git a/core/sme/src/rrm/sme_rrm.c b/core/sme/src/rrm/sme_rrm.c index b546308c18..46ef6cde69 100644 --- a/core/sme/src/rrm/sme_rrm.c +++ b/core/sme/src/rrm/sme_rrm.c @@ -1100,17 +1100,19 @@ QDF_STATUS sme_rrm_process_beacon_report_req_ind(struct mac_context *mac, { tpSirBeaconReportReqInd beacon_req = (tpSirBeaconReportReqInd)msg_buf; 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]; uint32_t session_id; struct csr_roam_session *session; QDF_STATUS status; - uint32_t num_chan; + uint32_t num_chan, local_num_channel; bool chan_valid; - uint32_t *rrm_freq_list; - uint32_t bcn_chan_freq; + uint32_t *rrm_freq_list, *local_rrm_freq_list; + uint32_t bcn_chan_freq, local_bcn_chan_freq; + tRrmPEContext rrm_context; 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 *) 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; } + 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 */ qdf_mem_copy(sme_rrm_ctx->sessionBssId.bytes, beacon_req->bssId, sizeof(tSirMacAddr));