From 701a6b63586380bdbdce3899cfba9fb47a9655f4 Mon Sep 17 00:00:00 2001 From: Kiran Kumar Lokere Date: Sat, 20 Jun 2020 01:42:45 -0700 Subject: [PATCH] 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 --- core/mac/inc/sir_api.h | 2 +- core/mac/inc/sir_mac_prot_def.h | 6 +- core/mac/src/include/parser_api.h | 1 + .../src/pe/lim/lim_process_assoc_rsp_frame.c | 7 + core/mac/src/pe/rrm/rrm_api.c | 49 +++--- .../src/sys/legacy/src/utils/src/parser_api.c | 4 + core/sme/inc/sme_rrm_internal.h | 11 +- core/sme/src/rrm/sme_rrm.c | 144 ++++-------------- 8 files changed, 90 insertions(+), 134 deletions(-) diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index f2a10866ef86..8bff87c15174 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -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 */ diff --git a/core/mac/inc/sir_mac_prot_def.h b/core/mac/inc/sir_mac_prot_def.h index 78c13525d10d..2ce1142557bd 100644 --- a/core/mac/inc/sir_mac_prot_def.h +++ b/core/mac/inc/sir_mac_prot_def.h @@ -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; diff --git a/core/mac/src/include/parser_api.h b/core/mac/src/include/parser_api.h index 2a51a643a241..cb3784cdf0d4 100644 --- a/core/mac/src/include/parser_api.h +++ b/core/mac/src/include/parser_api.h @@ -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; diff --git a/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c b/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c index 30a207c34b8f..ba5b0a30e072 100644 --- a/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c +++ b/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c @@ -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); diff --git a/core/mac/src/pe/rrm/rrm_api.c b/core/mac/src/pe/rrm/rrm_api.c index d474d29c84d3..7d134c886845 100644 --- a/core/mac/src/pe/rrm/rrm_api.c +++ b/core/mac/src/pe/rrm/rrm_api.c @@ -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; diff --git a/core/mac/src/sys/legacy/src/utils/src/parser_api.c b/core/mac/src/sys/legacy/src/utils/src/parser_api.c index 79b033947f8f..e118d47e4d51 100644 --- a/core/mac/src/sys/legacy/src/utils/src/parser_api.c +++ b/core/mac/src/sys/legacy/src/utils/src/parser_api.c @@ -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; diff --git a/core/sme/inc/sme_rrm_internal.h b/core/sme/inc/sme_rrm_internal.h index 8545ec908866..f355d51ba0a8 100644 --- a/core/sme/inc/sme_rrm_internal.h +++ b/core/sme/inc/sme_rrm_internal.h @@ -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 ) */ diff --git a/core/sme/src/rrm/sme_rrm.c b/core/sme/src/rrm/sme_rrm.c index f8af929b409e..3333bbd2a551 100644 --- a/core/sme/src/rrm/sme_rrm.c +++ b/core/sme/src/rrm/sme_rrm.c @@ -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.