qcacld-3.0: Add RRM beacon request support for MBSSID feature

Add RRM beacon request support for MBSSID feature.

Change-Id: Ibe0ce7c2b11b5ee4ee0b9bbe10c8c191e2d40897
CRs-Fixed: 2715104
This commit is contained in:
Kiran Kumar Lokere 2020-06-20 01:42:45 -07:00 committed by snandini
parent be109fb59c
commit 701a6b6358
8 changed files with 90 additions and 134 deletions

View File

@ -60,7 +60,7 @@ struct mac_context;
#define SIR_MAX_ELEMENT_ID 255
#define SIR_BCN_REPORT_MAX_BSS_DESC 4
#define SIR_BCN_REPORT_MAX_BSS_DESC 8
#define SIR_NUM_11B_RATES 4 /* 1,2,5.5,11 */
#define SIR_NUM_11A_RATES 8 /* 6,9,12,18,24,36,48,54 */

View File

@ -1481,9 +1481,9 @@ typedef struct sSirMacLinkReport {
uint8_t rsni;
} tSirMacLinkReport, *tpSirMacLinkReport;
#define BEACON_REPORT_MAX_IES 224 /* Refer IEEE 802.11k-2008, Table 7-31d */
#define BEACON_REPORT_MAX_IES 215
/* Max number of beacon reports per channel supported in the driver */
#define MAX_BEACON_REPORTS 8
#define MAX_BEACON_REPORTS 32
/* Offset of IEs after Fixed Fields in Beacon Frame */
#define BEACON_FRAME_IES_OFFSET 12
@ -1539,7 +1539,7 @@ typedef struct sSirMacBeaconReport {
} tSirMacBeaconReport, *tpSirMacBeaconReport;
#define RADIO_REPORTS_MAX_IN_A_FRAME 4
#define RADIO_REPORTS_MAX_IN_A_FRAME 7
typedef struct sSirMacRadioMeasureReport {
uint8_t token;
uint8_t refused;

View File

@ -454,6 +454,7 @@ typedef struct sSirAssocRsp {
#ifdef WLAN_FEATURE_11W
tDot11fIETimeoutInterval TimeoutInterval;
#endif
tDot11fIERRMEnabledCap rrm_caps;
tDot11fIEvendor_vht_ie vendor_vht_ie;
tDot11fIEOBSSScanParameters obss_scanparams;
tDot11fTLVrssi_assoc_rej rssi_assoc_rej;

View File

@ -622,6 +622,7 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
uint8_t ap_nss;
int8_t rssi;
QDF_STATUS status;
tpRRMCaps rrm_caps = &mac_ctx->rrm.rrmPEContext.rrmEnabledCaps;
assoc_cnf.resultCode = eSIR_SME_SUCCESS;
/* Update PE session Id */
@ -1095,6 +1096,12 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
session_entry->beaconParams.fShortPreamble = true;
}
if (assoc_rsp->rrm_caps.present) {
rrm_caps->nonOperatingChanMax =
assoc_rsp->rrm_caps.nonOperatinChanMax;
rrm_caps->operatingChanMax =
assoc_rsp->rrm_caps.operatingChanMax;
}
#ifdef FEATURE_WLAN_DIAG_SUPPORT
lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_CONNECTED, session_entry,
QDF_STATUS_SUCCESS, QDF_STATUS_SUCCESS);

View File

@ -576,16 +576,24 @@ rrm_process_beacon_report_req(struct mac_context *mac,
maxMeasurementDuration = 2^(nonOperatingChanMax - 4) * BeaconInterval
*/
maxDuration =
if (mac->rrm.rrmPEContext.rrmEnabledCaps.nonOperatingChanMax) {
maxDuration =
mac->rrm.rrmPEContext.rrmEnabledCaps.nonOperatingChanMax - 4;
sign = (maxDuration < 0) ? 1 : 0;
maxDuration = (1L << ABS(maxDuration));
if (!sign)
maxMeasduration =
sign = (maxDuration < 0) ? 1 : 0;
maxDuration = (1L << ABS(maxDuration));
if (!sign)
maxMeasduration =
maxDuration * pe_session->beaconParams.beaconInterval;
else
maxMeasduration =
else
maxMeasduration =
pe_session->beaconParams.beaconInterval / maxDuration;
} else {
maxMeasduration =
pBeaconReq->measurement_request.Beacon.meas_duration;
maxDuration =
mac->rrm.rrmPEContext.rrmEnabledCaps.nonOperatingChanMax;
sign = 0;
}
measDuration = pBeaconReq->measurement_request.Beacon.meas_duration;
@ -607,13 +615,16 @@ rrm_process_beacon_report_req(struct mac_context *mac,
return eRRM_REFUSED;
}
if (maxMeasduration < measDuration) {
if (pBeaconReq->durationMandatory) {
pe_nofl_err("RX: [802.11 BCN_RPT] Dropping the req: duration mandatory & maxduration > measduration");
if (pBeaconReq->durationMandatory) {
if (maxDuration && maxMeasduration < measDuration) {
pe_err("RX: [802.11 BCN_RPT] Dropping the req");
return eRRM_REFUSED;
} else
measDuration = maxMeasduration;
}
} else if (maxDuration) {
measDuration = QDF_MIN(maxMeasduration, measDuration);
}
pe_debug("measurement duration %d", measDuration);
/* Cache the data required for sending report. */
pCurrentReq->request.Beacon.reportingDetail =
pBeaconReq->measurement_request.Beacon.BcnReportingDetail.
@ -790,15 +801,15 @@ rrm_process_beacon_report_req(struct mac_context *mac,
* Return: Remaining length of IEs in current bss_desc which are not included
* in pIes.
*/
static uint8_t
static uint16_t
rrm_fill_beacon_ies(struct mac_context *mac, uint8_t *pIes,
uint8_t *pNumIes, uint8_t pIesMaxSize, uint8_t *eids,
uint8_t numEids, uint8_t start_offset,
uint8_t numEids, uint16_t start_offset,
struct bss_description *bss_desc)
{
uint8_t *pBcnIes, count = 0, i;
uint16_t BcnNumIes, total_ies_len, len;
uint8_t rem_len = 0;
uint16_t rem_len = 0;
if ((!pIes) || (!pNumIes) || (!bss_desc)) {
pe_err("Invalid parameters");
@ -868,7 +879,8 @@ rrm_fill_beacon_ies(struct mac_context *mac, uint8_t *pIes,
* break. For first fragment, account
* for the fixed fields also.
*/
rem_len = total_ies_len - *pNumIes;
rem_len = total_ies_len - *pNumIes -
start_offset;
if (start_offset == 0)
rem_len = rem_len +
BEACON_FRAME_IES_OFFSET;
@ -914,10 +926,11 @@ rrm_process_beacon_report_xmit(struct mac_context *mac_ctx,
pCurrentReq[beacon_xmit_ind->measurement_idx];
struct pe_session *session_entry;
uint8_t session_id, counter;
uint8_t i, j, offset = 0;
uint8_t i, j;
uint8_t bss_desc_count = 0;
uint8_t report_index = 0;
uint8_t rem_len = 0;
uint16_t rem_len = 0;
uint16_t offset = 0;
uint8_t frag_id = 0;
uint8_t num_frames, num_reports_in_frame;

View File

@ -3136,6 +3136,10 @@ sir_convert_assoc_resp_frame2_struct(struct mac_context *mac,
qdf_mem_copy(&pAssocRsp->HTInfo, &ar->HTInfo,
sizeof(tDot11fIEHTInfo));
}
if (ar->RRMEnabledCap.present) {
qdf_mem_copy(&pAssocRsp->rrm_caps, &ar->RRMEnabledCap,
sizeof(tDot11fIERRMEnabledCap));
}
if (ar->MobilityDomain.present) {
/* MobilityDomain */
pAssocRsp->mdiePresent = 1;

View File

@ -76,7 +76,6 @@ typedef struct sRrmSMEContext {
uint16_t duration[SIR_ESE_MAX_MEAS_IE_REQS];
uint8_t measMode[SIR_ESE_MAX_MEAS_IE_REQS];
uint32_t scan_id;
qdf_mc_timer_t IterMeasTimer;
tDblLinkList neighborReportCache;
tRrmNeighborRequestControlInfo neighborReqControlInfo;
@ -94,4 +93,14 @@ typedef struct sRrmNeighborReq {
bool neighbor_report_offload;
} tRrmNeighborReq, *tpRrmNeighborReq;
/**
* sme_rrm_issue_scan_req() - To issue rrm scan request
* @mac_ctx: pointer to mac context
*
* This routine is called to issue rrm scan request
*
* Return: QDF_STATUS
*/
QDF_STATUS sme_rrm_issue_scan_req(struct mac_context *mac_ctx, uint8_t idx);
#endif /* #if !defined( __SMERRMINTERNAL_H ) */

View File

@ -590,28 +590,37 @@ static QDF_STATUS sme_rrm_send_scan_result(struct mac_context *mac_ctx,
while (scan_results) {
/*
* In passive scan, sta listens beacon. Connected AP beacon
* is offloaded to firmware. Firmware will discard
* connected AP beacon except that special IE exists.
* Connected AP beacon will not be sent to host. Hence, timer
* of connected AP in scan results is not updated and can
* not meet "pScanResult->timer >= RRM_scan_timer".
* Connected AP beacon is offloaded to firmware.
* Firmware will discard connected AP beacon except that
* special IE exists Connected AP beacon will not be sent
* to host. Hence, timer of connected AP in scan results is
* not updated and can not meet
* "pScanResult->timer >= RRM_scan_timer".
*/
uint8_t is_conn_bss_found = false;
uint8_t is_nontx_of_conn_bss = false;
if ((scan_type == eSIR_PASSIVE_SCAN) &&
(!qdf_mem_cmp(scan_results->BssDescriptor.bssId,
session->pConnectBssDesc->bssId,
sizeof(struct qdf_mac_addr)))) {
if (!qdf_mem_cmp(scan_results->BssDescriptor.bssId,
session->pConnectBssDesc->bssId,
sizeof(struct qdf_mac_addr))) {
is_conn_bss_found = true;
sme_debug("Connected BSS in scan results");
}
if (scan_results->BssDescriptor.mbssid_info.profile_num) {
if (!qdf_mem_cmp(scan_results->BssDescriptor.
mbssid_info.trans_bssid,
session->pConnectBssDesc->bssId,
QDF_MAC_ADDR_SIZE)) {
is_nontx_of_conn_bss = true;
sme_debug("Non Tx BSS of Conn AP in results");
}
}
next_result = sme_scan_result_get_next(mac_handle,
result_handle);
sme_debug("Scan res timer:%lu, rrm scan timer:%llu",
scan_results->timer, rrm_scan_timer);
if ((scan_results->timer >= rrm_scan_timer) ||
(is_conn_bss_found == true)) {
(is_conn_bss_found == true) || is_nontx_of_conn_bss) {
roam_info->bss_desc = &scan_results->BssDescriptor;
csr_roam_call_callback(mac_ctx, session_id, roam_info,
0, eCSR_ROAM_UPDATE_SCAN_RESULT,
@ -677,8 +686,6 @@ static QDF_STATUS sme_rrm_scan_request_callback(struct mac_context *mac,
uint32_t scanId,
eCsrScanStatus status)
{
uint16_t interval;
uint32_t time_tick;
QDF_STATUS qdf_status;
uint32_t session_id;
bool valid_result = true;
@ -711,28 +718,6 @@ static QDF_STATUS sme_rrm_scan_request_callback(struct mac_context *mac,
ch_idx = pSmeRrmContext->currentIndex;
num_chan = pSmeRrmContext->channelList.numOfChannels;
if (((ch_idx + 1) < num_chan) && valid_result) {
if (QDF_TIMER_STATE_RUNNING ==
qdf_mc_timer_get_current_state(
&pSmeRrmContext->IterMeasTimer)) {
/*
* Measurement random timer is already running, this
* should not happen because the driver doesn't support
* multiple measurements simultaneously. Also for
* multiple measurements on a single report, the
* channels in op class should be appended to the global
* frequency list
*/
sme_err("[802.11 RRM]: meas timer is already running");
sme_rrm_send_scan_result(mac,
pSmeRrmContext->measurement_idx,
1, &freq_list[ch_idx], true);
qdf_mem_free(pSmeRrmContext->channelList.freq_list);
pSmeRrmContext->channelList.freq_list = NULL;
pSmeRrmContext->channelList.numOfChannels = 0;
sme_reset_ese_bcn_req_in_progress(pSmeRrmContext);
return QDF_STATUS_E_FAILURE;
}
sme_rrm_send_scan_result(mac, pSmeRrmContext->measurement_idx,
1, &freq_list[ch_idx], false);
@ -742,19 +727,10 @@ static QDF_STATUS sme_rrm_scan_request_callback(struct mac_context *mac,
/* From timer tick get a random number within 10ms and max
* randmization interval.
*/
time_tick = qdf_mc_timer_get_system_ticks();
interval =
time_tick % (pSmeRrmContext->randnIntvl - 10 + 1) + 10;
sme_debug("Set timer for interval %d ", interval);
qdf_status = qdf_mc_timer_start(&pSmeRrmContext->IterMeasTimer,
interval);
if (QDF_IS_STATUS_ERROR(qdf_status)) {
qdf_mem_free(pSmeRrmContext->channelList.freq_list);
pSmeRrmContext->channelList.freq_list = NULL;
pSmeRrmContext->channelList.numOfChannels = 0;
sme_reset_ese_bcn_req_in_progress(pSmeRrmContext);
}
qdf_status = sme_rrm_issue_scan_req(mac,
pSmeRrmContext->measurement_idx);
if (QDF_IS_STATUS_ERROR(qdf_status))
sme_debug("RRM scan req Failed");
} else {
/* Done with the measurement. Clean up all context and send a
@ -814,16 +790,7 @@ static void sme_rrm_scan_event_callback(struct wlan_objmgr_vdev *vdev,
scan_id, scan_status);
}
/**
* sme_rrm_issue_scan_req() - To issue rrm scan request
* @mac_ctx: pointer to mac context
*
* This routine is called to issue rrm scan request
*
* Return: QDF_STATUS
*/
static QDF_STATUS
sme_rrm_issue_scan_req(struct mac_context *mac_ctx, uint8_t idx)
QDF_STATUS sme_rrm_issue_scan_req(struct mac_context *mac_ctx, uint8_t idx)
{
QDF_STATUS status = QDF_STATUS_SUCCESS;
tpRrmSMEContext sme_rrm_ctx = &mac_ctx->rrm.rrmSmeContext[idx];
@ -916,15 +883,21 @@ sme_rrm_issue_scan_req(struct mac_context *mac_ctx, uint8_t idx)
* depending on type of scan.
*/
if (req->scan_req.scan_f_passive) {
if (max_chan_time >= RRM_SCAN_MIN_DWELL_TIME)
if (max_chan_time >= RRM_SCAN_MIN_DWELL_TIME) {
req->scan_req.dwell_time_passive =
max_chan_time;
req->scan_req.dwell_time_passive_6g =
max_chan_time;
}
sme_debug("Passive Max Dwell Time(%d)",
req->scan_req.dwell_time_passive);
} else {
if (max_chan_time >= RRM_SCAN_MIN_DWELL_TIME) {
req->scan_req.dwell_time_active = max_chan_time;
req->scan_req.dwell_time_active_2g = max_chan_time;
req->scan_req.dwell_time_active_2g =
max_chan_time;
req->scan_req.dwell_time_active_6g =
max_chan_time;
}
sme_debug("Active Max Dwell Time(%d) 2G Dwell time %d",
req->scan_req.dwell_time_active,
@ -1684,34 +1657,6 @@ QDF_STATUS sme_rrm_msg_processor(struct mac_context *mac, uint16_t msg_type,
return QDF_STATUS_SUCCESS;
}
/**
* rrm_iter_meas_timer_handle() - Timer handler to handlet the timeout
* @ mac - The handle returned by mac_open.
*
* Timer handler to handlet the timeout condition when a specific BT
* stop event does not come back, in which case to restore back the
* heartbeat timer.
*
* Return: NULL
*/
static void rrm_iter_meas_timer_handle(void *data)
{
struct mac_context *mac;
mac_handle_t mac_handle = cds_get_context(QDF_MODULE_ID_SME);
tpRrmSMEContext sme_rrm_ctx = (tpRrmSMEContext)data;
mac = MAC_CONTEXT(mac_handle);
if (!mac) {
sme_err("Mac ctx is NULL");
return;
}
sme_debug("Randomization timer expired...send on next channel");
/* Issue a scan req for next channel. */
sme_rrm_issue_scan_req(mac, sme_rrm_ctx->measurement_idx);
}
/**
* rrm_neighbor_rsp_timeout_handler() - Timer handler to handlet the timeout
* @mac - The handle returned by mac_open.
@ -1770,16 +1715,6 @@ QDF_STATUS rrm_open(struct mac_context *mac)
for (i = 0; i < MAX_MEASUREMENT_REQUEST; i++) {
pSmeRrmContext = &mac->rrm.rrmSmeContext[i];
qdf_status = qdf_mc_timer_init(&pSmeRrmContext->IterMeasTimer,
QDF_TIMER_TYPE_SW,
rrm_iter_meas_timer_handle,
(void *)pSmeRrmContext);
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
sme_err("Fail to init measurement timer");
return QDF_STATUS_E_FAILURE;
}
qdf_status =
qdf_mc_timer_init(&pSmeRrmContext->neighborReqControlInfo.
neighborRspWaitTimer, QDF_TIMER_TYPE_SW,
@ -1827,14 +1762,6 @@ QDF_STATUS rrm_close(struct mac_context *mac)
for (i = 0; i < MAX_MEASUREMENT_REQUEST; i++) {
pSmeRrmContext = &mac->rrm.rrmSmeContext[i];
if (QDF_TIMER_STATE_RUNNING ==
qdf_mc_timer_get_current_state(
&pSmeRrmContext->IterMeasTimer)) {
qdf_status = qdf_mc_timer_stop(
&pSmeRrmContext->IterMeasTimer);
if (QDF_IS_STATUS_ERROR(qdf_status))
sme_err("Timer stop fail");
}
if (pSmeRrmContext->channelList.freq_list) {
qdf_mem_free(pSmeRrmContext->channelList.freq_list);
@ -1842,11 +1769,6 @@ QDF_STATUS rrm_close(struct mac_context *mac)
pSmeRrmContext->channelList.numOfChannels = 0;
}
qdf_status =
qdf_mc_timer_destroy(&pSmeRrmContext->IterMeasTimer);
if (QDF_IS_STATUS_ERROR(qdf_status))
sme_err("Fail to destroy timer");
if (QDF_TIMER_STATE_RUNNING ==
qdf_mc_timer_get_current_state(&pSmeRrmContext->
neighborReqControlInfo.