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:
parent
be109fb59c
commit
701a6b6358
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 ) */
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user