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:
@@ -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
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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:
|
||||||
|
@@ -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));
|
||||||
|
Reference in New Issue
Block a user