summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVarun Reddy Yeturu <varunreddy.yeturu@codeaurora.org>2016-02-22 10:07:02 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2016-04-17 18:10:26 -0700
commit86459d63ca6d141bf3045af9166f8a3fc1bcb3a1 (patch)
treec0e2a9fef75990b0fee20e5a930ce8eb5892e82b
parent883c4f20f9f3073e49d1a68c1b4d2e91c55d3d3c (diff)
qcacld-3.0: Isolate roaming related scan functionality
Move the scanning related code which is pertinent to roaming into a separate file so that any future maintenace would be easy across different projects CRs-Fixed: 978905 Change-Id: Ia8c81726eb843d0a5aa89affa89d84d77994932e
-rwxr-xr-xKbuild3
-rw-r--r--core/sme/inc/csr_internal.h3
-rw-r--r--core/sme/inc/csr_neighbor_roam.h14
-rw-r--r--core/sme/src/csr/csr_api_roam.c83
-rw-r--r--core/sme/src/csr/csr_host_scan_roam.c816
-rw-r--r--core/sme/src/csr/csr_neighbor_roam.c676
6 files changed, 835 insertions, 760 deletions
diff --git a/Kbuild b/Kbuild
index fbae71cd533e..f14e5a9c2952 100755
--- a/Kbuild
+++ b/Kbuild
@@ -505,7 +505,8 @@ SME_CSR_OBJS := $(SME_SRC_DIR)/csr/csr_api_roam.o \
$(SME_SRC_DIR)/csr/csr_cmd_process.o \
$(SME_SRC_DIR)/csr/csr_link_list.o \
$(SME_SRC_DIR)/csr/csr_neighbor_roam.o \
- $(SME_SRC_DIR)/csr/csr_util.o
+ $(SME_SRC_DIR)/csr/csr_util.o \
+ $(SME_SRC_DIR)/csr/csr_host_scan_roam.o
ifeq ($(CONFIG_QCOM_TDLS),y)
SME_CSR_OBJS += $(SME_SRC_DIR)/csr/csr_tdls_process.o
diff --git a/core/sme/inc/csr_internal.h b/core/sme/inc/csr_internal.h
index 3b5616280317..a476d8d493aa 100644
--- a/core/sme/inc/csr_internal.h
+++ b/core/sme/inc/csr_internal.h
@@ -1383,4 +1383,7 @@ bool csr_wait_for_connection_update(tpAniSirGlobal mac,
bool do_release_reacquire_lock);
enum tQDF_ADAPTER_MODE csr_get_session_persona(tpAniSirGlobal pmac,
uint32_t session_id);
+void csr_roam_substate_change(tpAniSirGlobal pMac, eCsrRoamSubState NewSubstate,
+ uint32_t sessionId);
+
#endif
diff --git a/core/sme/inc/csr_neighbor_roam.h b/core/sme/inc/csr_neighbor_roam.h
index 00fc97725f9a..5bae53f64cf1 100644
--- a/core/sme/inc/csr_neighbor_roam.h
+++ b/core/sme/inc/csr_neighbor_roam.h
@@ -320,5 +320,19 @@ static inline void csr_neighbor_roam_send_lfr_metric_event(
tSirMacAddr bssid, eRoamCmdStatus status)
{}
#endif
+void csr_neighbor_roam_free_roamable_bss_list(tpAniSirGlobal mac_ctx,
+ tDblLinkList * llist);
+QDF_STATUS csr_neighbor_roam_process_scan_complete(tpAniSirGlobal pMac,
+ uint8_t sessionId);
+QDF_STATUS csr_roam_stop_wait_for_key_timer(tpAniSirGlobal pMac);
+uint32_t csr_get_current_ap_rssi(tpAniSirGlobal pMac,
+ tScanResultHandle *pScanResultList, uint8_t sessionId);
+QDF_STATUS csr_roam_issue_reassociate(tpAniSirGlobal pMac,
+ uint32_t sessionId, tSirBssDescription *pSirBssDesc,
+ tDot11fBeaconIEs *pIes, tCsrRoamProfile *pProfile);
+QDF_STATUS csr_roam_issue_reassociate_cmd(tpAniSirGlobal pMac,
+ uint32_t sessionId);
+QDF_STATUS csr_roam_copy_connected_profile(tpAniSirGlobal pMac,
+ uint32_t sessionId, tCsrRoamProfile *pDstProfile);
#endif /* CSR_NEIGHBOR_ROAM_H */
diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c
index 800a28d71f84..310dd9a251f0 100644
--- a/core/sme/src/csr/csr_api_roam.c
+++ b/core/sme/src/csr/csr_api_roam.c
@@ -204,7 +204,6 @@ static QDF_STATUS csr_roam_stop_roaming_timer(tpAniSirGlobal pMac,
uint32_t sessionId);
static void csr_roam_roaming_timer_handler(void *pv);
QDF_STATUS csr_roam_start_wait_for_key_timer(tpAniSirGlobal pMac, uint32_t interval);
-QDF_STATUS csr_roam_stop_wait_for_key_timer(tpAniSirGlobal pMac);
static void csr_roam_wait_for_key_time_out_handler(void *pv);
static QDF_STATUS csr_init11d_info(tpAniSirGlobal pMac, tCsr11dinfo *ps11dinfo);
static QDF_STATUS csr_init_channel_power_list(tpAniSirGlobal pMac,
@@ -220,11 +219,6 @@ QDF_STATUS csr_send_mb_set_context_req_msg(tpAniSirGlobal pMac, uint32_t session
uint8_t keyId, uint8_t keyLength,
uint8_t *pKey, uint8_t paeRole,
uint8_t *pKeyRsc);
-static QDF_STATUS csr_roam_issue_reassociate(tpAniSirGlobal pMac,
- uint32_t sessionId,
- tSirBssDescription *pSirBssDesc,
- tDot11fBeaconIEs *pIes,
- tCsrRoamProfile *pProfile);
void csr_roamStatisticsTimerHandler(void *pv);
void csr_roamStatsGlobalClassDTimerHandler(void *pv);
static void csr_roam_link_up(tpAniSirGlobal pMac, struct qdf_mac_addr bssid);
@@ -8316,22 +8310,6 @@ QDF_STATUS csr_roam_issue_join(tpAniSirGlobal pMac, uint32_t sessionId,
return status;
}
-static QDF_STATUS csr_roam_issue_reassociate(tpAniSirGlobal pMac,
- uint32_t sessionId,
- tSirBssDescription *pSirBssDesc,
- tDot11fBeaconIEs *pIes,
- tCsrRoamProfile *pProfile)
-{
- csr_roam_state_change(pMac, eCSR_ROAMING_STATE_JOINING, sessionId);
- /* Set the roaming substate to 'join attempt'... */
- csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_REASSOC_REQ, sessionId);
- QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
- FL(" calling csr_send_join_req_msg (eWNI_SME_REASSOC_REQ)"));
- /* attempt to Join this BSS... */
- return csr_send_join_req_msg(pMac, sessionId, pSirBssDesc, pProfile, pIes,
- eWNI_SME_REASSOC_REQ);
-}
-
void csr_roam_reissue_roam_command(tpAniSirGlobal pMac)
{
tListElem *pEntry;
@@ -8501,67 +8479,6 @@ bool csr_is_scan_for_roam_command_active(tpAniSirGlobal pMac)
return fRet;
}
-QDF_STATUS csr_roam_issue_reassociate_cmd(tpAniSirGlobal pMac, uint32_t sessionId)
-{
- QDF_STATUS status = QDF_STATUS_SUCCESS;
- tSmeCmd *pCommand = NULL;
- bool fHighPriority = true;
- bool fRemoveCmd = false;
- tListElem *pEntry;
- /* Delete the old assoc command. All is setup for reassoc to be serialized */
- pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
- if (pEntry) {
- pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
- if (!pCommand) {
- sms_log(pMac, LOGE, FL(" fail to get command buffer"));
- return QDF_STATUS_E_RESOURCES;
- }
- if (eSmeCommandRoam == pCommand->command) {
- if (pCommand->u.roamCmd.roamReason ==
- eCsrSmeIssuedAssocToSimilarAP) {
- fRemoveCmd =
- csr_ll_remove_entry(&pMac->sme.
- smeCmdActiveList, pEntry,
- LL_ACCESS_LOCK);
- } else {
- sms_log(pMac, LOGE,
- FL
- (" Unexpected active roam command present "));
- }
- if (fRemoveCmd == false) {
- /* Implies we did not get the serialized assoc command we */
- /* were expecting */
- pCommand = NULL;
- }
- }
- }
- if (NULL == pCommand) {
- sms_log(pMac, LOGE,
- FL
- (" fail to get command buffer as expected based on previous connect roam command"));
- return QDF_STATUS_E_RESOURCES;
- }
- do {
- /* Change the substate in case it is wait-for-key */
- if (CSR_IS_WAIT_FOR_KEY(pMac, sessionId)) {
- csr_roam_stop_wait_for_key_timer(pMac);
- csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_NONE,
- sessionId);
- }
- pCommand->command = eSmeCommandRoam;
- pCommand->sessionId = (uint8_t) sessionId;
- pCommand->u.roamCmd.roamReason = eCsrSmeIssuedFTReassoc;
- status = csr_queue_sme_command(pMac, pCommand, fHighPriority);
- if (!QDF_IS_STATUS_SUCCESS(status)) {
- sms_log(pMac, LOGE,
- FL(" fail to send message status = %d"), status);
- csr_release_command_roam(pMac, pCommand);
- }
- } while (0);
-
- return status;
-}
-
static void
csr_roaming_state_config_cnf_processor(tpAniSirGlobal mac_ctx,
uint32_t result)
diff --git a/core/sme/src/csr/csr_host_scan_roam.c b/core/sme/src/csr/csr_host_scan_roam.c
new file mode 100644
index 000000000000..fb29ee10db7f
--- /dev/null
+++ b/core/sme/src/csr/csr_host_scan_roam.c
@@ -0,0 +1,816 @@
+/*
+ * Copyright (c) 2016 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: csr_host_scan_roam.c
+ *
+ * Host based roaming processing scan results and initiating the roaming
+ */
+
+#include "wma_types.h"
+#include "cds_mq.h"
+#include "csr_inside_api.h"
+#include "sms_debug.h"
+#include "sme_qos_internal.h"
+#include "sme_inside.h"
+#include "host_diag_core_event.h"
+#include "host_diag_core_log.h"
+#include "csr_api.h"
+#include "sme_api.h"
+#include "csr_neighbor_roam.h"
+#include "mac_trace.h"
+#include "cds_concurrency.h"
+
+/**
+ * csr_roam_issue_reassociate() - Issue Reassociate
+ * @pMac: Global MAC Context
+ * @sessionId: SME Session ID
+ * @pSirBssDesc: BSS Descriptor
+ * @pIes: Pointer to the IE's
+ * @pProfile: Roaming profile
+ *
+ * Return: Success or Failure
+ */
+QDF_STATUS csr_roam_issue_reassociate(tpAniSirGlobal pMac,
+ uint32_t sessionId, tSirBssDescription *pSirBssDesc,
+ tDot11fBeaconIEs *pIes, tCsrRoamProfile *pProfile)
+{
+ csr_roam_state_change(pMac, eCSR_ROAMING_STATE_JOINING, sessionId);
+ /* Set the roaming substate to 'join attempt'... */
+ csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_REASSOC_REQ,
+ sessionId);
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
+ FL(" calling csr_send_join_req_msg (eWNI_SME_REASSOC_REQ)"));
+ /* attempt to Join this BSS... */
+ return csr_send_join_req_msg(pMac, sessionId, pSirBssDesc, pProfile,
+ pIes, eWNI_SME_REASSOC_REQ);
+}
+
+/**
+ * csr_roam_issue_reassociate_cmd() - Issue the reassociate command
+ * @pMac: Global MAC Context
+ * @sessionId: SME Session ID
+ *
+ * Return: Success or Failure status
+ */
+QDF_STATUS csr_roam_issue_reassociate_cmd(tpAniSirGlobal pMac,
+ uint32_t sessionId)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+ tSmeCmd *pCommand = NULL;
+ bool fHighPriority = true;
+ bool fRemoveCmd = false;
+ tListElem *pEntry;
+ pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
+ if (pEntry) {
+ pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
+ if (!pCommand) {
+ sms_log(pMac, LOGE, FL(" fail to get command buffer"));
+ return QDF_STATUS_E_RESOURCES;
+ }
+ if (eSmeCommandRoam == pCommand->command) {
+ if (pCommand->u.roamCmd.roamReason ==
+ eCsrSmeIssuedAssocToSimilarAP)
+ fRemoveCmd =
+ csr_ll_remove_entry(&pMac->sme.
+ smeCmdActiveList,
+ pEntry,
+ LL_ACCESS_LOCK);
+ else
+ sms_log(pMac, LOGE,
+ FL(" Unexpected roam cmd present"));
+ if (fRemoveCmd == false)
+ pCommand = NULL;
+ }
+ }
+ if (NULL == pCommand) {
+ sms_log(pMac, LOGE,
+ FL(" fail to get cmd buf based on prev roam command"));
+ return QDF_STATUS_E_RESOURCES;
+ }
+ do {
+ /* Change the substate in case it is wait-for-key */
+ if (CSR_IS_WAIT_FOR_KEY(pMac, sessionId)) {
+ csr_roam_stop_wait_for_key_timer(pMac);
+ csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_NONE,
+ sessionId);
+ }
+ pCommand->command = eSmeCommandRoam;
+ pCommand->sessionId = (uint8_t) sessionId;
+ pCommand->u.roamCmd.roamReason = eCsrSmeIssuedFTReassoc;
+ status = csr_queue_sme_command(pMac, pCommand, fHighPriority);
+ if (!QDF_IS_STATUS_SUCCESS(status)) {
+ sms_log(pMac, LOGE,
+ FL("fail to send message status=%d"), status);
+ csr_release_command_roam(pMac, pCommand);
+ }
+ } while (0);
+
+ return status;
+}
+
+/**
+ * csr_neighbor_roam_process_scan_results() - build roaming candidate list
+ *
+ * @mac_ctx: The handle returned by mac_open.
+ * @sessionid: Session information
+ * @scan_results_list: List obtained from csr_scan_get_result()
+ *
+ * This function applies various candidate checks like LFR, 11r, preauth, ESE
+ * and builds a roamable AP list. It applies age limit only if no suitable
+ * recent candidates are found.
+ *
+ * Output list is built in mac_ctx->roam.neighborRoamInfo[sessionid].
+ *
+ * Return: void
+ */
+
+static void
+csr_neighbor_roam_process_scan_results(tpAniSirGlobal mac_ctx,
+ uint8_t sessionid,
+ tScanResultHandle *scan_results_list)
+{
+ tCsrScanResultInfo *scan_result;
+ tpCsrNeighborRoamControlInfo n_roam_info =
+ &mac_ctx->roam.neighborRoamInfo[sessionid];
+ tpCsrNeighborRoamBSSInfo bss_info;
+ uint32_t cur_ap_rssi;
+ uint32_t age_ticks = 0;
+ uint32_t limit_ticks =
+ qdf_system_msecs_to_ticks(ROAM_AP_AGE_LIMIT_MS);
+ uint8_t num_candidates = 0;
+ uint8_t num_dropped = 0;
+ /*
+ * first iteration of scan list should consider
+ * age constraint for candidates
+ */
+ bool age_constraint = true;
+#ifdef FEATURE_WLAN_ESE
+ uint16_t qpresent;
+ uint16_t qavail;
+ bool voadmitted;
+#endif
+ /*
+ * Find out the Current AP RSSI and keep it handy to check if
+ * it is better than the RSSI of the AP which we are
+ * going to roam.If so, we are going to continue with the
+ * current AP.
+ */
+ cur_ap_rssi = csr_get_current_ap_rssi(mac_ctx, scan_results_list,
+ sessionid);
+
+ /*
+ * Expecting the scan result already to be in the sorted order based on
+ * RSSI. Based on the previous state we need to check whether the list
+ * should be sorted again taking neighbor score into consideration. If
+ * previous state is CFG_CHAN_LIST_SCAN, there should not be a neighbor
+ * score associated with any of the BSS. If the previous state is
+ * REPORT_QUERY, then there will be neighbor score for each of the APs.
+ * For now, let us take top of the list provided as it is by CSR Scan
+ * result API. Hence it is assumed that neighbor score and rssi score
+ * are in the same order. This will be taken care later.
+ */
+
+ do {
+ while (true) {
+ tSirBssDescription *descr;
+
+ scan_result = csr_scan_result_get_next(
+ mac_ctx, *scan_results_list);
+ if (NULL == scan_result)
+ break;
+ descr = &scan_result->BssDescriptor;
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+ FL("Scan result: BSSID " MAC_ADDRESS_STR
+ " (Rssi %ld, Ch:%d)"),
+ MAC_ADDR_ARRAY(descr->bssId),
+ abs(descr->rssi), descr->channelId);
+
+ if (!qdf_mem_cmp(descr->bssId,
+ n_roam_info->currAPbssid.bytes,
+ sizeof(tSirMacAddr))) {
+ /*
+ * currently associated AP. Do not have this
+ * in the roamable AP list
+ */
+ QDF_TRACE(QDF_MODULE_ID_SME,
+ QDF_TRACE_LEVEL_INFO,
+ "SKIP-currently associated AP");
+ continue;
+ }
+ /*
+ * In case of reassoc requested by upper layer, look
+ * for exact match of bssid & channel. csr cache might
+ * have duplicates
+ */
+ if ((n_roam_info->uOsRequestedHandoff) &&
+ ((qdf_mem_cmp(descr->bssId,
+ n_roam_info->handoffReqInfo.bssid.bytes,
+ sizeof(tSirMacAddr)))
+ || (descr->channelId !=
+ n_roam_info->handoffReqInfo.channel))) {
+ QDF_TRACE(QDF_MODULE_ID_SME,
+ QDF_TRACE_LEVEL_INFO,
+ "SKIP-not a candidate AP for OS requested roam");
+ continue;
+ }
+
+ if ((n_roam_info->is11rAssoc) &&
+ (!csr_neighbor_roam_is_preauth_candidate(mac_ctx,
+ sessionid, descr->bssId))) {
+ sms_log(mac_ctx, LOGE,
+ FL("BSSID in preauth faillist.Ignore"));
+ continue;
+ }
+
+#ifdef FEATURE_WLAN_ESE
+ if (!csr_roam_is_roam_offload_scan_enabled(mac_ctx) &&
+ (n_roam_info->isESEAssoc) &&
+ !csr_neighbor_roam_is_preauth_candidate(mac_ctx,
+ sessionid, descr->bssId)) {
+ sms_log(mac_ctx, LOGE,
+ FL("BSSID in preauth faillist.Ignore"));
+ continue;
+ }
+
+ qpresent = descr->QBSSLoad_present;
+ qavail = descr->QBSSLoad_avail;
+ voadmitted = n_roam_info->isVOAdmitted;
+ if (voadmitted)
+ sms_log(mac_ctx, LOG1,
+ FL("New QBSS=%s,BWavail=0x%x,req=0x%x"),
+ ((qpresent) ? "yes" : "no"), qavail,
+ n_roam_info->MinQBssLoadRequired);
+ if (voadmitted && qpresent &&
+ (qavail < n_roam_info->MinQBssLoadRequired)) {
+ QDF_TRACE(QDF_MODULE_ID_SME,
+ QDF_TRACE_LEVEL_INFO,
+ "BSSID:" MAC_ADDRESS_STR "has no BW",
+ MAC_ADDR_ARRAY(descr->bssId));
+ continue;
+ }
+ if (voadmitted && !qpresent) {
+ QDF_TRACE(QDF_MODULE_ID_SME,
+ QDF_TRACE_LEVEL_INFO,
+ "BSSID:" MAC_ADDRESS_STR "no LOAD IE",
+ MAC_ADDR_ARRAY(descr->bssId));
+ continue;
+ }
+#endif /* FEATURE_WLAN_ESE */
+
+ /*
+ * If we are supporting legacy roaming, and
+ * if the candidate is on the "pre-auth failed" list,
+ * ignore it.
+ */
+ if (csr_roam_is_fast_roam_enabled(mac_ctx, sessionid) &&
+ !csr_neighbor_roam_is_preauth_candidate(mac_ctx,
+ sessionid, descr->bssId)) {
+ sms_log(mac_ctx, LOGE,
+ FL("BSSID in preauth faillist Ignore"));
+ continue;
+ }
+
+ /* check the age of the AP */
+ age_ticks = (uint32_t) qdf_mc_timer_get_system_ticks() -
+ descr->nReceivedTime;
+ if (age_constraint == true && age_ticks > limit_ticks) {
+ num_dropped++;
+ QDF_TRACE(QDF_MODULE_ID_SME,
+ QDF_TRACE_LEVEL_WARN,
+ FL("Old AP (probe rsp/beacon) skipped.")
+ );
+ continue;
+ }
+
+ /* Finished all checks, now add it to candidate list */
+ bss_info =
+ qdf_mem_malloc(sizeof(tCsrNeighborRoamBSSInfo));
+ if (NULL == bss_info) {
+ sms_log(mac_ctx, LOGE,
+ FL("Memory alloc fail. Ignored cnd."));
+ continue;
+ }
+ bss_info->pBssDescription =
+ qdf_mem_malloc(descr->length +
+ sizeof(descr->length));
+ if (bss_info->pBssDescription != NULL) {
+ qdf_mem_copy(bss_info->pBssDescription, descr,
+ descr->length + sizeof(descr->length));
+ } else {
+ sms_log(mac_ctx, LOGE,
+ FL("Mem alloc failed. Ignore cand."));
+ qdf_mem_free(bss_info);
+ continue;
+ }
+ /*
+ * Assign some preference value for now. Need to
+ * calculate theactual score based on RSSI and neighbor
+ * AP score
+ */
+ bss_info->apPreferenceVal = 10;
+ num_candidates++;
+ csr_ll_insert_tail(&n_roam_info->roamableAPList,
+ &bss_info->List, LL_ACCESS_LOCK);
+ } /* end of while (csr_scan_result_get_next) */
+
+ /* if some candidates were found, then no need to repeat */
+ if (num_candidates)
+ break;
+ /*
+ * if age_constraint is already false, we have done two
+ * iterations and no candidate were found
+ */
+ if (age_constraint == false) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ "%s: No roam able candidates found",
+ __func__);
+ break;
+ }
+ /*
+ * if all candidates were dropped rescan the scan
+ * list but this time without age constraint.
+ */
+ age_constraint = false;
+ /* if no candidates were dropped no need to repeat */
+ } while (num_dropped);
+
+ /*
+ * Now we have all the scan results in our local list. Good time to free
+ * up the the list we got as a part of csrGetScanResult
+ */
+ csr_scan_result_purge(mac_ctx, *scan_results_list);
+}
+
+/**
+ * csr_neighbor_roam_trigger_handoff() - Start roaming
+ * @mac_ctx: Global MAC Context
+ * @session_id: SME Session ID
+ *
+ * Return: None
+ */
+static void csr_neighbor_roam_trigger_handoff(tpAniSirGlobal mac_ctx,
+ uint8_t session_id)
+{
+ if (csr_roam_is_fast_roam_enabled(mac_ctx, session_id))
+ csr_neighbor_roam_issue_preauth_req(mac_ctx, session_id);
+ else
+ sms_log(mac_ctx, LOGE, FL("Roaming is disabled"));
+}
+
+/**
+ * csr_neighbor_roam_process_scan_complete() - Post process the scan results
+ * @pMac: Global MAC Context
+ * @sessionId: SME Session ID
+ *
+ * Return: Success or Failure
+ */
+QDF_STATUS csr_neighbor_roam_process_scan_complete(tpAniSirGlobal pMac,
+ uint8_t sessionId)
+{
+ tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+ &pMac->roam.neighborRoamInfo[sessionId];
+ tCsrScanResultFilter scanFilter;
+ tScanResultHandle scanResult;
+ uint32_t tempVal = 0;
+ QDF_STATUS hstatus;
+
+ hstatus = csr_neighbor_roam_prepare_scan_profile_filter(pMac,
+ &scanFilter,
+ sessionId);
+ sms_log(pMac, LOGW,
+ FL("Prepare scan to find neighbor AP filter status = %d"),
+ hstatus);
+ if (QDF_STATUS_SUCCESS != hstatus) {
+ sms_log(pMac, LOGE,
+ FL("Scan Filter prep fail for Assoc %d Bail out"),
+ tempVal);
+ return QDF_STATUS_E_FAILURE;
+ }
+ hstatus = csr_scan_get_result(pMac, &scanFilter, &scanResult);
+ if (hstatus != QDF_STATUS_SUCCESS) {
+ sms_log(pMac, LOGE,
+ FL("Get Scan Result status code %d"),
+ hstatus);
+ }
+ /* Process the scan results and update roamable AP list */
+ csr_neighbor_roam_process_scan_results(pMac, sessionId, &scanResult);
+
+ /* Free the scan filter */
+ csr_free_scan_filter(pMac, &scanFilter);
+
+ tempVal = csr_ll_count(&pNeighborRoamInfo->roamableAPList);
+
+ if (tempVal) {
+ csr_neighbor_roam_trigger_handoff(pMac, sessionId);
+ return QDF_STATUS_SUCCESS;
+ }
+
+ if (csr_roam_is_roam_offload_scan_enabled(pMac)) {
+ if (pNeighborRoamInfo->uOsRequestedHandoff) {
+ csr_roam_offload_scan(pMac, sessionId,
+ ROAM_SCAN_OFFLOAD_START,
+ REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW);
+ pNeighborRoamInfo->uOsRequestedHandoff = 0;
+ } else {
+ /* There is no candidate or We are not roaming Now.
+ * Inform the FW to restart Roam Offload Scan */
+ csr_roam_offload_scan(pMac, sessionId,
+ ROAM_SCAN_OFFLOAD_RESTART,
+ REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW);
+ }
+ csr_neighbor_roam_state_transition(pMac,
+ eCSR_NEIGHBOR_ROAM_STATE_CONNECTED, sessionId);
+ }
+ return QDF_STATUS_SUCCESS;
+
+}
+
+/**
+ * csr_neighbor_roam_candidate_found_ind_hdlr()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: pointer to msg buff
+ *
+ * This function is called by CSR as soon as TL posts the candidate
+ * found indication to SME via MC thread
+ *
+ * Return: QDF_STATUS_SUCCESS on success, corresponding error code otherwise
+ */
+QDF_STATUS csr_neighbor_roam_candidate_found_ind_hdlr(tpAniSirGlobal pMac,
+ void *pMsg)
+{
+ tSirSmeCandidateFoundInd *pSirSmeCandidateFoundInd =
+ (tSirSmeCandidateFoundInd *) pMsg;
+ uint32_t sessionId = pSirSmeCandidateFoundInd->sessionId;
+ tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
+ &pMac->roam.neighborRoamInfo[sessionId];
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+ sms_log(pMac, LOG1, FL("Received indication from firmware"));
+
+ /* we must be in connected state, if not ignore it */
+ if ((eCSR_NEIGHBOR_ROAM_STATE_CONNECTED !=
+ pNeighborRoamInfo->neighborRoamState)
+ || (pNeighborRoamInfo->uOsRequestedHandoff)) {
+ sms_log(pMac, LOGE,
+ FL("Recvd in NotCONNECTED or OsReqHandoff. Ignore"));
+ status = QDF_STATUS_E_FAILURE;
+ } else {
+ /* Firmware indicated that roaming candidate is found. Beacons
+ * are already in the SME scan results table.
+ * Process the results for choosing best roaming candidate.
+ */
+ csr_save_scan_results(pMac, eCsrScanCandidateFound,
+ sessionId);
+ /* Future enhancements:
+ * If firmware tags candidate beacons, give them preference
+ * for roaming.
+ * Age out older entries so that new candidate beacons
+ * will get preference.
+ */
+ status = csr_neighbor_roam_process_scan_complete(pMac,
+ sessionId);
+ if (QDF_STATUS_SUCCESS != status) {
+ sms_log(pMac, LOGE,
+ FL("scan process complete failed, status %d"),
+ status);
+ return QDF_STATUS_E_FAILURE;
+ }
+ }
+
+ return status;
+}
+
+/**
+ * csr_neighbor_roam_free_roamable_bss_list() - Frees roamable APs list
+ * @mac_ctx: The handle returned by mac_open.
+ * @llist: Neighbor Roam BSS List to be emptied
+ *
+ * Empties and frees all the nodes in the roamable AP list
+ *
+ * Return: none
+ */
+void csr_neighbor_roam_free_roamable_bss_list(tpAniSirGlobal mac_ctx,
+ tDblLinkList *llist)
+{
+ tpCsrNeighborRoamBSSInfo result = NULL;
+
+ sms_log(mac_ctx, LOG2,
+ FL("Emptying the BSS list. Current count = %d"),
+ csr_ll_count(llist));
+
+ /*
+ * Pick up the head, remove and free the node till
+ * the list becomes empty
+ */
+ while ((result = csr_neighbor_roam_next_roamable_ap(mac_ctx, llist,
+ NULL)) != NULL) {
+ csr_neighbor_roam_remove_roamable_ap_list_entry(mac_ctx,
+ llist, result);
+ csr_neighbor_roam_free_neighbor_roam_bss_node(mac_ctx, result);
+ }
+ return;
+}
+
+/**
+ * csr_neighbor_roam_remove_roamable_ap_list_entry()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @pList: The list from which the entry should be removed
+ * @pNeighborEntry: Neighbor Roam BSS Node to be removed
+ *
+ * This function removes a given entry from the given list
+ *
+ * Return: true if successfully removed, else false
+ */
+bool csr_neighbor_roam_remove_roamable_ap_list_entry(tpAniSirGlobal pMac,
+ tDblLinkList *pList,
+ tpCsrNeighborRoamBSSInfo
+ pNeighborEntry)
+{
+ if (pList) {
+ return csr_ll_remove_entry(pList, &pNeighborEntry->List,
+ LL_ACCESS_LOCK);
+ }
+
+ sms_log(pMac, LOGE,
+ FL("Remove neigh BSS node from fail list. Current count = %d"),
+ csr_ll_count(pList));
+
+ return false;
+}
+
+/**
+ * csr_neighbor_roam_next_roamable_ap() - Get next AP from roamable AP list
+ * @mac_ctx - The handle returned by mac_open.
+ * @plist - The list from which the entry should be returned
+ * @neighbor_entry - Neighbor Roam BSS Node whose next entry should be returned
+ *
+ * Gets the entry next to passed entry. If NULL is passed, return the entry
+ * in the head of the list
+ *
+ * Return: Neighbor Roam BSS Node to be returned
+ */
+tpCsrNeighborRoamBSSInfo csr_neighbor_roam_next_roamable_ap(
+ tpAniSirGlobal mac_ctx, tDblLinkList *llist,
+ tpCsrNeighborRoamBSSInfo neighbor_entry)
+{
+ tListElem *entry = NULL;
+ tpCsrNeighborRoamBSSInfo result = NULL;
+
+ if (llist) {
+ if (NULL == neighbor_entry)
+ entry = csr_ll_peek_head(llist, LL_ACCESS_LOCK);
+ else
+ entry = csr_ll_next(llist, &neighbor_entry->List,
+ LL_ACCESS_LOCK);
+ if (entry)
+ result = GET_BASE_ADDR(entry, tCsrNeighborRoamBSSInfo,
+ List);
+ }
+
+ return result;
+}
+
+
+/**
+ * csr_neighbor_roam_request_handoff() - Handoff to a different AP
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session_id: Session ID
+ *
+ * This function triggers actual switching from one AP to the new AP.
+ * It issues disassociate with reason code as Handoff and CSR as a part of
+ * handling disassoc rsp, issues reassociate to the new AP
+ *
+ * Return: none
+ */
+void csr_neighbor_roam_request_handoff(tpAniSirGlobal mac_ctx,
+ uint8_t session_id)
+{
+ tCsrRoamInfo roam_info;
+ tpCsrNeighborRoamControlInfo neighbor_roam_info =
+ &mac_ctx->roam.neighborRoamInfo[session_id];
+ tCsrNeighborRoamBSSInfo handoff_node;
+ uint32_t roamid = 0;
+ QDF_STATUS status;
+
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, "%s session_id=%d",
+ __func__, session_id);
+
+ if (neighbor_roam_info->neighborRoamState !=
+ eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE) {
+ sms_log(mac_ctx, LOGE,
+ FL("Roam requested when Neighbor roam is in %s state"),
+ mac_trace_get_neighbour_roam_state(
+ neighbor_roam_info->neighborRoamState));
+ return;
+ }
+
+ if (false == csr_neighbor_roam_get_handoff_ap_info(mac_ctx,
+ &handoff_node, session_id)) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("failed to obtain handoff AP"));
+ return;
+ }
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+ FL("HANDOFF CANDIDATE BSSID "MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(handoff_node.pBssDescription->bssId));
+
+ qdf_mem_zero(&roam_info, sizeof(tCsrRoamInfo));
+ csr_roam_call_callback(mac_ctx, session_id, &roam_info, roamid,
+ eCSR_ROAM_FT_START, eSIR_SME_SUCCESS);
+
+ qdf_mem_zero(&roam_info, sizeof(tCsrRoamInfo));
+ csr_neighbor_roam_state_transition(mac_ctx,
+ eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING, session_id);
+
+ csr_neighbor_roam_send_lfr_metric_event(mac_ctx, session_id,
+ handoff_node.pBssDescription->bssId,
+ eCSR_ROAM_HANDOVER_SUCCESS);
+ /* Free the profile.. Just to make sure we dont leak memory here */
+ csr_release_profile(mac_ctx,
+ &neighbor_roam_info->csrNeighborRoamProfile);
+ /*
+ * Create the Handoff AP profile. Copy the currently connected profile
+ * and update only the BSSID and channel number. This should happen
+ * before issuing disconnect
+ */
+ status = csr_roam_copy_connected_profile(mac_ctx, session_id,
+ &neighbor_roam_info->csrNeighborRoamProfile);
+ if (QDF_STATUS_SUCCESS != status) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("csr_roam_copy_connected_profile failed %d"),
+ status);
+ return;
+ }
+ qdf_mem_copy(neighbor_roam_info->csrNeighborRoamProfile.BSSIDs.bssid,
+ handoff_node.pBssDescription->bssId, sizeof(tSirMacAddr));
+ neighbor_roam_info->csrNeighborRoamProfile.ChannelInfo.ChannelList[0] =
+ handoff_node.pBssDescription->channelId;
+
+ sms_log(mac_ctx, LOGW,
+ " csr_roamHandoffRequested: disassociating with current AP");
+
+ if (!QDF_IS_STATUS_SUCCESS
+ (csr_roam_issue_disassociate_cmd
+ (mac_ctx, session_id,
+ eCSR_DISCONNECT_REASON_HANDOFF))) {
+ sms_log(mac_ctx, LOGW,
+ "csr_roamHandoffRequested: fail to issue disassoc");
+ return;
+ }
+ /* notify HDD for handoff, providing the BSSID too */
+ roam_info.reasonCode = eCsrRoamReasonBetterAP;
+
+ qdf_mem_copy(roam_info.bssid.bytes,
+ handoff_node.pBssDescription->bssId,
+ sizeof(struct qdf_mac_addr));
+
+ csr_roam_call_callback(mac_ctx, session_id, &roam_info, 0,
+ eCSR_ROAM_ROAMING_START, eCSR_ROAM_RESULT_NONE);
+
+ return;
+}
+
+
+/**
+ * csr_neighbor_roam_get_handoff_ap_info - Identifies the best AP for roaming
+ *
+ * @pMac: mac context
+ * @session_id: Session Id
+ * @hand_off_node: AP node that is the handoff candidate returned
+ *
+ * This function returns the best possible AP for handoff. For 11R case, it
+ * returns the 1st entry from pre-auth done list. For non-11r case, it returns
+ * the 1st entry from roamable AP list
+ *
+ * Return: true if able find handoff AP, false otherwise
+ */
+
+bool csr_neighbor_roam_get_handoff_ap_info(tpAniSirGlobal pMac,
+ tpCsrNeighborRoamBSSInfo hand_off_node,
+ uint8_t session_id)
+{
+ tpCsrNeighborRoamControlInfo ngbr_roam_info =
+ &pMac->roam.neighborRoamInfo[session_id];
+ tpCsrNeighborRoamBSSInfo bss_node = NULL;
+
+ if (NULL == hand_off_node) {
+ QDF_ASSERT(NULL != hand_off_node);
+ return false;
+ }
+ if (ngbr_roam_info->is11rAssoc) {
+ /* Always the BSS info in the head is the handoff candidate */
+ bss_node = csr_neighbor_roam_next_roamable_ap(
+ pMac,
+ &ngbr_roam_info->FTRoamInfo.preAuthDoneList,
+ NULL);
+ sms_log(pMac, LOG1,
+ FL("Number of Handoff candidates = %d"),
+ csr_ll_count(&
+ ngbr_roam_info->FTRoamInfo.preAuthDoneList));
+ } else
+#ifdef FEATURE_WLAN_ESE
+ if (ngbr_roam_info->isESEAssoc) {
+ /* Always the BSS info in the head is the handoff candidate */
+ bss_node =
+ csr_neighbor_roam_next_roamable_ap(pMac,
+ &ngbr_roam_info->FTRoamInfo.preAuthDoneList,
+ NULL);
+ sms_log(pMac, LOG1,
+ FL("Number of Handoff candidates = %d"),
+ csr_ll_count(&ngbr_roam_info->FTRoamInfo.
+ preAuthDoneList));
+ } else
+#endif
+ if (csr_roam_is_fast_roam_enabled(pMac, session_id)) {
+ /* Always the BSS info in the head is the handoff candidate */
+ bss_node =
+ csr_neighbor_roam_next_roamable_ap(pMac,
+ &ngbr_roam_info->FTRoamInfo.preAuthDoneList,
+ NULL);
+ sms_log(pMac, LOG1,
+ FL("Number of Handoff candidates = %d"),
+ csr_ll_count(
+ &ngbr_roam_info->FTRoamInfo.preAuthDoneList));
+ } else {
+ bss_node =
+ csr_neighbor_roam_next_roamable_ap(pMac,
+ &ngbr_roam_info->roamableAPList,
+ NULL);
+ sms_log(pMac, LOG1,
+ FL("Number of Handoff candidates = %d"),
+ csr_ll_count(&ngbr_roam_info->roamableAPList));
+ }
+ if (NULL == bss_node)
+ return false;
+ qdf_mem_copy(hand_off_node, bss_node, sizeof(tCsrNeighborRoamBSSInfo));
+ return true;
+}
+
+/**
+ * csr_neighbor_roam_is_handoff_in_progress()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session_id: Session ID
+ *
+ * This function returns whether handoff is in progress or not based on
+ * the current neighbor roam state
+ *
+ * Return: true if reassoc in progress, false otherwise
+ */
+bool csr_neighbor_roam_is_handoff_in_progress(tpAniSirGlobal pMac,
+ uint8_t sessionId)
+{
+ if (eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING ==
+ pMac->roam.neighborRoamInfo[sessionId].neighborRoamState)
+ return true;
+
+ return false;
+}
+
+/**
+ * csr_neighbor_roam_free_neighbor_roam_bss_node()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @neighborRoamBSSNode: Neighbor Roam BSS Node to be freed
+ *
+ * This function frees all the internal pointers CSR NeighborRoam BSS Info
+ * and also frees the node itself
+ *
+ * Return: None
+ */
+void csr_neighbor_roam_free_neighbor_roam_bss_node(tpAniSirGlobal pMac,
+ tpCsrNeighborRoamBSSInfo
+ neighborRoamBSSNode)
+{
+ if (neighborRoamBSSNode) {
+ if (neighborRoamBSSNode->pBssDescription) {
+ qdf_mem_free(neighborRoamBSSNode->pBssDescription);
+ neighborRoamBSSNode->pBssDescription = NULL;
+ }
+ qdf_mem_free(neighborRoamBSSNode);
+ neighborRoamBSSNode = NULL;
+ }
+
+ return;
+}
+
diff --git a/core/sme/src/csr/csr_neighbor_roam.c b/core/sme/src/csr/csr_neighbor_roam.c
index 76781a8bb692..469e788c76af 100644
--- a/core/sme/src/csr/csr_neighbor_roam.c
+++ b/core/sme/src/csr/csr_neighbor_roam.c
@@ -119,135 +119,6 @@ void csr_neighbor_roam_send_lfr_metric_event(
}
#endif
-/**
- * csr_neighbor_roam_free_neighbor_roam_bss_node()
- *
- * @mac_ctx: Pointer to Global MAC structure
- * @neighborRoamBSSNode: Neighbor Roam BSS Node to be freed
- *
- * This function frees all the internal pointers CSR NeighborRoam BSS Info
- * and also frees the node itself
- *
- * Return: None
- */
-void csr_neighbor_roam_free_neighbor_roam_bss_node(tpAniSirGlobal pMac,
- tpCsrNeighborRoamBSSInfo
- neighborRoamBSSNode)
-{
- if (neighborRoamBSSNode) {
- if (neighborRoamBSSNode->pBssDescription) {
- qdf_mem_free(neighborRoamBSSNode->pBssDescription);
- neighborRoamBSSNode->pBssDescription = NULL;
- }
- qdf_mem_free(neighborRoamBSSNode);
- neighborRoamBSSNode = NULL;
- }
-
- return;
-}
-
-/**
- * csr_neighbor_roam_remove_roamable_ap_list_entry()
- *
- * @mac_ctx: Pointer to Global MAC structure
- * @pList: The list from which the entry should be removed
- * @pNeighborEntry: Neighbor Roam BSS Node to be removed
- *
- * This function removes a given entry from the given list
- *
- * Return: true if successfully removed, else false
- */
-bool csr_neighbor_roam_remove_roamable_ap_list_entry(tpAniSirGlobal pMac,
- tDblLinkList *pList,
- tpCsrNeighborRoamBSSInfo
- pNeighborEntry)
-{
- if (pList) {
- return csr_ll_remove_entry(pList, &pNeighborEntry->List,
- LL_ACCESS_LOCK);
- }
-
- sms_log(pMac, LOGE,
- FL
- ("Removing neighbor BSS node from list failed. Current count = %d"),
- csr_ll_count(pList));
-
- return false;
-}
-
-/**
- * csr_neighbor_roam_next_roamable_ap() - Get next AP from roamable AP list
- * @mac_ctx - The handle returned by mac_open.
- * @plist - The list from which the entry should be returned
- * @neighbor_entry - Neighbor Roam BSS Node whose next entry should be returned
- *
- * Gets the entry next to passed entry. If NULL is passed, return the entry
- * in the head of the list
- *
- * Return: Neighbor Roam BSS Node to be returned
- */
-tpCsrNeighborRoamBSSInfo csr_neighbor_roam_next_roamable_ap(
- tpAniSirGlobal mac_ctx, tDblLinkList *llist,
- tpCsrNeighborRoamBSSInfo neighbor_entry)
-{
- tListElem *entry = NULL;
- tpCsrNeighborRoamBSSInfo result = NULL;
-
- if (llist) {
- if (NULL == neighbor_entry)
- entry = csr_ll_peek_head(llist, LL_ACCESS_LOCK);
- else
- entry = csr_ll_next(llist, &neighbor_entry->List,
- LL_ACCESS_LOCK);
- if (entry)
- result = GET_BASE_ADDR(entry, tCsrNeighborRoamBSSInfo,
- List);
- }
-
- return result;
-}
-
-/**
- * csr_neighbor_roam_free_roamable_bss_list() - Frees roamable APs list
- * @mac_ctx: The handle returned by mac_open.
- * @llist: Neighbor Roam BSS List to be emptied
- *
- * Empties and frees all the nodes in the roamable AP list
- *
- * Return: none
- */
-void csr_neighbor_roam_free_roamable_bss_list(tpAniSirGlobal mac_ctx,
- tDblLinkList *llist)
-{
- tpCsrNeighborRoamBSSInfo result = NULL;
-
- NEIGHBOR_ROAM_DEBUG(mac_ctx, LOG2,
- FL("Emptying the BSS list. Current count = %d"),
- csr_ll_count(llist));
-
- /*
- * Pick up the head, remove and free the node till
- * the list becomes empty
- */
- while ((result = csr_neighbor_roam_next_roamable_ap(mac_ctx, llist,
- NULL)) != NULL) {
- csr_neighbor_roam_remove_roamable_ap_list_entry(mac_ctx,
- llist, result);
- csr_neighbor_roam_free_neighbor_roam_bss_node(mac_ctx, result);
- }
- return;
-}
-
-static void csr_neighbor_roam_trigger_handoff(tpAniSirGlobal pMac,
- uint8_t sessionId)
-{
- if (csr_roam_is_fast_roam_enabled(pMac, sessionId)) {
- csr_neighbor_roam_issue_preauth_req(pMac, sessionId);
- } else {
- sms_log(pMac, LOGE, FL("Roaming is diisabled"));
- }
-}
-
QDF_STATUS
csr_neighbor_roam_update_fast_roaming_enabled(tpAniSirGlobal pMac,
uint8_t sessionId,
@@ -956,303 +827,6 @@ uint32_t csr_get_current_ap_rssi(tpAniSirGlobal pMac,
}
/**
- * csr_neighbor_roam_process_scan_results() - build roaming candidate list
- *
- * @mac_ctx: The handle returned by mac_open.
- * @sessionid: Session information
- * @scan_results_list: List obtained from csr_scan_get_result()
- *
- * This function applies various candidate checks like LFR, 11r, preauth, ESE
- * and builds a roamable AP list. It applies age limit only if no suitable
- * recent candidates are found.
- *
- * Output list is built in mac_ctx->roam.neighborRoamInfo[sessionid].
- *
- * Return: void
- */
-
-static void
-csr_neighbor_roam_process_scan_results(tpAniSirGlobal mac_ctx,
- uint8_t sessionid,
- tScanResultHandle *scan_results_list)
-{
- tCsrScanResultInfo *scan_result;
- tpCsrNeighborRoamControlInfo n_roam_info =
- &mac_ctx->roam.neighborRoamInfo[sessionid];
- tpCsrNeighborRoamBSSInfo bss_info;
- uint32_t cur_ap_rssi;
- uint32_t age_ticks = 0;
- uint32_t limit_ticks =
- qdf_system_msecs_to_ticks(ROAM_AP_AGE_LIMIT_MS);
- uint8_t num_candidates = 0;
- uint8_t num_dropped = 0;
- /*
- * first iteration of scan list should consider
- * age constraint for candidates
- */
- bool age_constraint = true;
-#ifdef FEATURE_WLAN_ESE
- uint16_t qpresent;
- uint16_t qavail;
- bool voadmitted;
-#endif
- /*
- * Find out the Current AP RSSI and keep it handy to check if
- * it is better than the RSSI of the AP which we are
- * going to roam.If so, we are going to continue with the
- * current AP.
- */
- cur_ap_rssi = csr_get_current_ap_rssi(mac_ctx, scan_results_list,
- sessionid);
-
- /*
- * Expecting the scan result already to be in the sorted order based on
- * RSSI. Based on the previous state we need to check whether the list
- * should be sorted again taking neighbor score into consideration. If
- * previous state is CFG_CHAN_LIST_SCAN, there should not be a neighbor
- * score associated with any of the BSS. If the previous state is
- * REPORT_QUERY, then there will be neighbor score for each of the APs.
- * For now, let us take top of the list provided as it is by CSR Scan
- * result API. Hence it is assumed that neighbor score and rssi score
- * are in the same order. This will be taken care later.
- */
-
- do {
- while (true) {
- tSirBssDescription *descr;
-
- scan_result = csr_scan_result_get_next(
- mac_ctx, *scan_results_list);
- if (NULL == scan_result)
- break;
- descr = &scan_result->BssDescriptor;
- QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
- FL("Scan result: BSSID " MAC_ADDRESS_STR
- " (Rssi %ld, Ch:%d)"),
- MAC_ADDR_ARRAY(descr->bssId),
- abs(descr->rssi), descr->channelId);
-
- if (true != qdf_mem_cmp(descr->bssId,
- n_roam_info->currAPbssid.bytes,
- sizeof(tSirMacAddr))) {
- /*
- * currently associated AP. Do not have this
- * in the roamable AP list
- */
- QDF_TRACE(QDF_MODULE_ID_SME,
- QDF_TRACE_LEVEL_INFO,
- "SKIP-currently associated AP");
- continue;
- }
- /*
- * In case of reassoc requested by upper layer, look
- * for exact match of bssid & channel. csr cache might
- * have duplicates
- */
- if ((n_roam_info->uOsRequestedHandoff) &&
- ((false != qdf_mem_cmp(descr->bssId,
- n_roam_info->handoffReqInfo.bssid.bytes,
- sizeof(tSirMacAddr)))
- || (descr->channelId !=
- n_roam_info->handoffReqInfo.channel))) {
- QDF_TRACE(QDF_MODULE_ID_SME,
- QDF_TRACE_LEVEL_INFO,
- "SKIP-not a candidate AP for OS requested roam");
- continue;
- }
-
- if ((n_roam_info->is11rAssoc) &&
- (!csr_neighbor_roam_is_preauth_candidate(mac_ctx,
- sessionid, descr->bssId))) {
- sms_log(mac_ctx, LOGE,
- FL("BSSID present in pre-auth fail list.. Ignoring"));
- continue;
- }
-
-#ifdef FEATURE_WLAN_ESE
- if (!csr_roam_is_roam_offload_scan_enabled(mac_ctx) &&
- (n_roam_info->isESEAssoc) &&
- !csr_neighbor_roam_is_preauth_candidate(mac_ctx,
- sessionid, descr->bssId)) {
- sms_log(mac_ctx, LOGE,
- FL("BSSID present in pre-auth fail list.. Ignoring"));
- continue;
- }
-
- qpresent = descr->QBSSLoad_present;
- qavail = descr->QBSSLoad_avail;
- voadmitted = n_roam_info->isVOAdmitted;
- if (voadmitted)
- sms_log(mac_ctx, LOG1,
- FL("New AP QBSS present = %s, BW available = 0x%x, required = 0x%x"),
- ((qpresent) ? "yes" : "no"), qavail,
- n_roam_info->MinQBssLoadRequired);
- if (voadmitted && qpresent &&
- (qavail < n_roam_info->MinQBssLoadRequired)) {
- QDF_TRACE(QDF_MODULE_ID_SME,
- QDF_TRACE_LEVEL_INFO,
- "BSSID : " MAC_ADDRESS_STR " has no bandwidth, ignoring",
- MAC_ADDR_ARRAY(descr->bssId));
- continue;
- }
- if (voadmitted && !qpresent) {
- QDF_TRACE(QDF_MODULE_ID_SME,
- QDF_TRACE_LEVEL_INFO,
- "BSSID : " MAC_ADDRESS_STR " has no QBSS LOAD IE, ignoring",
- MAC_ADDR_ARRAY(descr->bssId));
- continue;
- }
-#endif /* FEATURE_WLAN_ESE */
-
- /*
- * If we are supporting legacy roaming, and
- * if the candidate is on the "pre-auth failed" list,
- * ignore it.
- */
- if (csr_roam_is_fast_roam_enabled(mac_ctx, sessionid) &&
- !csr_neighbor_roam_is_preauth_candidate(mac_ctx,
- sessionid, descr->bssId)) {
- sms_log(mac_ctx, LOGE,
- FL("BSSID present in pre-auth fail list.. Ignoring"));
- continue;
- }
-
- /* check the age of the AP */
- age_ticks = (uint32_t) qdf_mc_timer_get_system_ticks() -
- descr->nReceivedTime;
- if (age_constraint == true && age_ticks > limit_ticks) {
- num_dropped++;
- QDF_TRACE(QDF_MODULE_ID_SME,
- QDF_TRACE_LEVEL_WARN,
- FL("Old AP (probe rsp/beacon) skipped.")
- );
- continue;
- }
-
- /* Finished all checks, now add it to candidate list */
- bss_info =
- qdf_mem_malloc(sizeof(tCsrNeighborRoamBSSInfo));
- if (NULL == bss_info) {
- sms_log(mac_ctx, LOGE,
- FL("Memory allocation failed. Ignored candidate."));
- continue;
- }
- bss_info->pBssDescription =
- qdf_mem_malloc(descr->length +
- sizeof(descr->length));
- if (bss_info->pBssDescription != NULL) {
- qdf_mem_copy(bss_info->pBssDescription, descr,
- descr->length + sizeof(descr->length));
- } else {
- sms_log(mac_ctx, LOGE,
- FL("Memory allocation failed. Ignored candidate."));
- qdf_mem_free(bss_info);
- continue;
- }
- /*
- * Assign some preference value for now. Need to
- * calculate theactual score based on RSSI and neighbor
- * AP score
- */
- bss_info->apPreferenceVal = 10;
- num_candidates++;
- csr_ll_insert_tail(&n_roam_info->roamableAPList,
- &bss_info->List, LL_ACCESS_LOCK);
- } /* end of while (csr_scan_result_get_next) */
-
- /* if some candidates were found, then no need to repeat */
- if (num_candidates)
- break;
- /*
- * if age_constraint is already false, we have done two
- * iterations and no candidate were found
- */
- if (age_constraint == false) {
- QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
- "%s: No roam able candidates found",
- __func__);
- break;
- }
- /*
- * if all candidates were dropped rescan the scan
- * list but this time without age constraint.
- */
- age_constraint = false;
- /* if no candidates were dropped no need to repeat */
- } while (num_dropped);
-
- /*
- * Now we have all the scan results in our local list. Good time to free
- * up the the list we got as a part of csrGetScanResult
- */
- csr_scan_result_purge(mac_ctx, *scan_results_list);
-}
-
-static QDF_STATUS csr_neighbor_roam_process_scan_complete(tpAniSirGlobal pMac,
- uint8_t sessionId)
-{
- tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
- &pMac->roam.neighborRoamInfo[sessionId];
- tCsrScanResultFilter scanFilter;
- tScanResultHandle scanResult;
- uint32_t tempVal = 0;
- QDF_STATUS hstatus;
-
- hstatus = csr_neighbor_roam_prepare_scan_profile_filter(pMac,
- &scanFilter,
- sessionId);
- NEIGHBOR_ROAM_DEBUG(pMac, LOGW,
- FL
- ("11R/ESE/Other Association: Prepare scan to find neighbor AP filter status = %d"),
- hstatus);
- if (QDF_STATUS_SUCCESS != hstatus) {
- sms_log(pMac, LOGE,
- FL
- ("Scan Filter preparation failed for Assoc type %d.. Bailing out.."),
- tempVal);
- return QDF_STATUS_E_FAILURE;
- }
- hstatus = csr_scan_get_result(pMac, &scanFilter, &scanResult);
- if (hstatus != QDF_STATUS_SUCCESS) {
- NEIGHBOR_ROAM_DEBUG(pMac, LOGE,
- FL("Get Scan Result status code %d"),
- hstatus);
- }
- /* Process the scan results and update roamable AP list */
- csr_neighbor_roam_process_scan_results(pMac, sessionId, &scanResult);
-
- /* Free the scan filter */
- csr_free_scan_filter(pMac, &scanFilter);
-
- tempVal = csr_ll_count(&pNeighborRoamInfo->roamableAPList);
-
- if (tempVal) {
- csr_neighbor_roam_trigger_handoff(pMac, sessionId);
- return QDF_STATUS_SUCCESS;
- }
-
- if (csr_roam_is_roam_offload_scan_enabled(pMac)) {
- if (pNeighborRoamInfo->uOsRequestedHandoff) {
- csr_roam_offload_scan(pMac, sessionId,
- ROAM_SCAN_OFFLOAD_START,
- REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW);
- pNeighborRoamInfo->uOsRequestedHandoff = 0;
- } else {
- /* There is no candidate or We are not roaming Now.
- * Inform the FW to restart Roam Offload Scan */
- csr_roam_offload_scan(pMac, sessionId,
- ROAM_SCAN_OFFLOAD_RESTART,
- REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW);
- }
- csr_neighbor_roam_state_transition(pMac,
- eCSR_NEIGHBOR_ROAM_STATE_CONNECTED, sessionId);
- }
- return QDF_STATUS_SUCCESS;
-
-}
-
-
-/**
* csr_neighbor_roam_channels_filter_by_current_band()
*
* @mac_ctx: Pointer to Global MAC structure
@@ -2430,124 +2004,6 @@ void csr_neighbor_roam_close(tpAniSirGlobal pMac, uint8_t sessionId)
}
/**
- * csr_neighbor_roam_request_handoff() - Handoff to a different AP
- * @mac_ctx: Pointer to Global MAC structure
- * @session_id: Session ID
- *
- * This function triggers actual switching from one AP to the new AP.
- * It issues disassociate with reason code as Handoff and CSR as a part of
- * handling disassoc rsp, issues reassociate to the new AP
- *
- * Return: none
- */
-void csr_neighbor_roam_request_handoff(tpAniSirGlobal mac_ctx,
- uint8_t session_id)
-{
- tCsrRoamInfo roam_info;
- tpCsrNeighborRoamControlInfo neighbor_roam_info =
- &mac_ctx->roam.neighborRoamInfo[session_id];
- tCsrNeighborRoamBSSInfo handoff_node;
- uint32_t roamid = 0;
- QDF_STATUS status;
-
- QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, "%s session_id=%d",
- __func__, session_id);
-
- if (neighbor_roam_info->neighborRoamState !=
- eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE) {
- sms_log(mac_ctx, LOGE,
- FL("Roam requested when Neighbor roam is in %s state"),
- mac_trace_get_neighbour_roam_state(
- neighbor_roam_info->neighborRoamState));
- return;
- }
-
- if (false == csr_neighbor_roam_get_handoff_ap_info(mac_ctx,
- &handoff_node, session_id)) {
- QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
- FL("failed to obtain handoff AP"));
- return;
- }
- QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
- FL("HANDOFF CANDIDATE BSSID "MAC_ADDRESS_STR),
- MAC_ADDR_ARRAY(handoff_node.pBssDescription->bssId));
-
- qdf_mem_zero(&roam_info, sizeof(tCsrRoamInfo));
- csr_roam_call_callback(mac_ctx, session_id, &roam_info, roamid,
- eCSR_ROAM_FT_START, eSIR_SME_SUCCESS);
-
- qdf_mem_zero(&roam_info, sizeof(tCsrRoamInfo));
- csr_neighbor_roam_state_transition(mac_ctx,
- eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING, session_id);
-
- csr_neighbor_roam_send_lfr_metric_event(mac_ctx, session_id,
- handoff_node.pBssDescription->bssId,
- eCSR_ROAM_HANDOVER_SUCCESS);
- /* Free the profile.. Just to make sure we dont leak memory here */
- csr_release_profile(mac_ctx,
- &neighbor_roam_info->csrNeighborRoamProfile);
- /*
- * Create the Handoff AP profile. Copy the currently connected profile
- * and update only the BSSID and channel number. This should happen
- * before issuing disconnect
- */
- status = csr_roam_copy_connected_profile(mac_ctx, session_id,
- &neighbor_roam_info->csrNeighborRoamProfile);
- if (QDF_STATUS_SUCCESS != status) {
- QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
- FL("csr_roam_copy_connected_profile failed %d"),
- status);
- return;
- }
- qdf_mem_copy(neighbor_roam_info->csrNeighborRoamProfile.BSSIDs.bssid,
- handoff_node.pBssDescription->bssId, sizeof(tSirMacAddr));
- neighbor_roam_info->csrNeighborRoamProfile.ChannelInfo.ChannelList[0] =
- handoff_node.pBssDescription->channelId;
-
- NEIGHBOR_ROAM_DEBUG(mac_ctx, LOGW,
- " csr_roamHandoffRequested: disassociating with current AP");
-
- if (!QDF_IS_STATUS_SUCCESS
- (csr_roam_issue_disassociate_cmd
- (mac_ctx, session_id,
- eCSR_DISCONNECT_REASON_HANDOFF))) {
- sms_log(mac_ctx, LOGW,
- "csr_roamHandoffRequested: fail to issue disassociate");
- return;
- }
- /* notify HDD for handoff, providing the BSSID too */
- roam_info.reasonCode = eCsrRoamReasonBetterAP;
-
- qdf_mem_copy(roam_info.bssid.bytes,
- handoff_node.pBssDescription->bssId,
- sizeof(struct qdf_mac_addr));
-
- csr_roam_call_callback(mac_ctx, session_id, &roam_info, 0,
- eCSR_ROAM_ROAMING_START, eCSR_ROAM_RESULT_NONE);
-
- return;
-}
-
-/**
- * csr_neighbor_roam_is_handoff_in_progress()
- *
- * @mac_ctx: Pointer to Global MAC structure
- * @session_id: Session ID
- *
- * This function returns whether handoff is in progress or not based on
- * the current neighbor roam state
- *
- * Return: true if reassoc in progress, false otherwise
- */
-bool csr_neighbor_roam_is_handoff_in_progress(tpAniSirGlobal pMac, uint8_t sessionId)
-{
- if (eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING ==
- pMac->roam.neighborRoamInfo[sessionId].neighborRoamState)
- return true;
-
- return false;
-}
-/**
* csr_neighbor_roam_is11r_assoc() - Check if association type is 11R
* @mac_ctx: MAC Global context
* @session_id: Session ID
@@ -2559,82 +2015,6 @@ bool csr_neighbor_roam_is11r_assoc(tpAniSirGlobal mac_ctx, uint8_t session_id)
return mac_ctx->roam.neighborRoamInfo[session_id].is11rAssoc;
}
-/**
- * csr_neighbor_roam_get_handoff_ap_info - Identifies the best AP for roaming
- *
- * @pMac: mac context
- * @session_id: Session Id
- * @hand_off_node: AP node that is the handoff candidate returned
- *
- * This function returns the best possible AP for handoff. For 11R case, it
- * returns the 1st entry from pre-auth done list. For non-11r case, it returns
- * the 1st entry from roamable AP list
- *
- * Return: true if able find handoff AP, false otherwise
- */
-
-bool csr_neighbor_roam_get_handoff_ap_info(tpAniSirGlobal pMac,
- tpCsrNeighborRoamBSSInfo hand_off_node,
- uint8_t session_id)
-{
- tpCsrNeighborRoamControlInfo ngbr_roam_info =
- &pMac->roam.neighborRoamInfo[session_id];
- tpCsrNeighborRoamBSSInfo bss_node = NULL;
-
- if (NULL == hand_off_node) {
- QDF_ASSERT(NULL != hand_off_node);
- return false;
- }
- if (ngbr_roam_info->is11rAssoc) {
- /* Always the BSS info in the head is the handoff candidate */
- bss_node = csr_neighbor_roam_next_roamable_ap(
- pMac,
- &ngbr_roam_info->FTRoamInfo.preAuthDoneList,
- NULL);
- NEIGHBOR_ROAM_DEBUG(pMac, LOG1,
- FL("Number of Handoff candidates = %d"),
- csr_ll_count(&
- ngbr_roam_info->FTRoamInfo.preAuthDoneList));
- } else
-#ifdef FEATURE_WLAN_ESE
- if (ngbr_roam_info->isESEAssoc) {
- /* Always the BSS info in the head is the handoff candidate */
- bss_node =
- csr_neighbor_roam_next_roamable_ap(pMac,
- &ngbr_roam_info->FTRoamInfo.preAuthDoneList,
- NULL);
- NEIGHBOR_ROAM_DEBUG(pMac, LOG1,
- FL("Number of Handoff candidates = %d"),
- csr_ll_count(&ngbr_roam_info->FTRoamInfo.
- preAuthDoneList));
- } else
-#endif
- if (csr_roam_is_fast_roam_enabled(pMac, session_id)) {
- /* Always the BSS info in the head is the handoff candidate */
- bss_node =
- csr_neighbor_roam_next_roamable_ap(pMac,
- &ngbr_roam_info->FTRoamInfo.preAuthDoneList,
- NULL);
- NEIGHBOR_ROAM_DEBUG(pMac, LOG1,
- FL("Number of Handoff candidates = %d"),
- csr_ll_count(
- &ngbr_roam_info->FTRoamInfo.preAuthDoneList));
- } else {
- bss_node =
- csr_neighbor_roam_next_roamable_ap(pMac,
- &ngbr_roam_info->roamableAPList,
- NULL);
- NEIGHBOR_ROAM_DEBUG(pMac, LOG1,
- FL("Number of Handoff candidates = %d"),
- csr_ll_count(&ngbr_roam_info->roamableAPList));
- }
- if (NULL == bss_node)
- return false;
- qdf_mem_copy(hand_off_node, bss_node, sizeof(tCsrNeighborRoamBSSInfo));
- return true;
-}
-
-
/* ---------------------------------------------------------------------------
\brief This function returns true if STA is in the middle of roaming states
@@ -2658,62 +2038,6 @@ bool csr_neighbor_middle_of_roaming(tpAniSirGlobal pMac, uint8_t sessionId)
}
/**
- * csr_neighbor_roam_candidate_found_ind_hdlr()
- *
- * @mac_ctx: Pointer to Global MAC structure
- * @msg_buf: pointer to msg buff
- *
- * This function is called by CSR as soon as TL posts the candidate
- * found indication to SME via MC thread
- *
- * Return: QDF_STATUS_SUCCESS on success, corresponding error code otherwise
- */
-QDF_STATUS csr_neighbor_roam_candidate_found_ind_hdlr(tpAniSirGlobal pMac, void *pMsg)
-{
- tSirSmeCandidateFoundInd *pSirSmeCandidateFoundInd =
- (tSirSmeCandidateFoundInd *) pMsg;
- uint32_t sessionId = pSirSmeCandidateFoundInd->sessionId;
- tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
- &pMac->roam.neighborRoamInfo[sessionId];
- QDF_STATUS status = QDF_STATUS_SUCCESS;
-
- sms_log(pMac, LOG1, FL("Received indication from firmware"));
-
- /* we must be in connected state, if not ignore it */
- if ((eCSR_NEIGHBOR_ROAM_STATE_CONNECTED !=
- pNeighborRoamInfo->neighborRoamState)
- || (pNeighborRoamInfo->uOsRequestedHandoff)) {
- sms_log(pMac, LOGE,
- FL
- ("Received in not CONNECTED state OR uOsRequestedHandoff is set. Ignore it"));
- status = QDF_STATUS_E_FAILURE;
- } else {
- /* Firmware indicated that roaming candidate is found. Beacons
- * are already in the SME scan results table.
- * Process the results for choosing best roaming candidate.
- */
- csr_save_scan_results(pMac, eCsrScanCandidateFound,
- sessionId);
- /* Future enhancements:
- * If firmware tags candidate beacons, give them preference
- * for roaming.
- * Age out older entries so that new candidate beacons
- * will get preference.
- */
- status = csr_neighbor_roam_process_scan_complete(pMac,
- sessionId);
- if (QDF_STATUS_SUCCESS != status) {
- sms_log(pMac, LOGE,
- FL("Neighbor scan process complete failed with status %d"),
- status);
- return QDF_STATUS_E_FAILURE;
- }
- }
-
- return status;
-}
-
-/**
* csr_neighbor_roam_process_handoff_req - Processes handoff request
*
* @mac_ctx Pointer to mac context