diff --git a/Kbuild b/Kbuild
index 48d74057f962..aea1c37772f0 100644
--- a/Kbuild
+++ b/Kbuild
@@ -2527,6 +2527,9 @@ cppflags-$(CONFIG_ENABLE_SMMU_S1_TRANSLATION) += -DENABLE_SMMU_S1_TRANSLATION
#Flag to enable/disable MTRACE feature
cppflags-$(CONFIG_ENABLE_MTRACE_LOG) += -DENABLE_MTRACE_LOG
+#Flag to enable/disable Adaptive 11r feature
+cppflags-$(CONFIG_ADAPTIVE_11R) += -DWLAN_ADAPTIVE_11R
+
#Flag to enable NUD tracking
cppflags-$(CONFIG_WLAN_NUD_TRACKING) += -DWLAN_NUD_TRACKING
diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c
index baed8b88571f..61a64f5e6a21 100644
--- a/components/mlme/core/src/wlan_mlme_main.c
+++ b/components/mlme/core/src/wlan_mlme_main.c
@@ -1513,6 +1513,30 @@ static void mlme_init_stats_cfg(struct wlan_objmgr_psoc *psoc,
cfg_get(psoc, CFG_REPORT_MAX_LINK_SPEED);
}
+#ifdef WLAN_ADAPTIVE_11R
+/**
+ * mlme_init_adaptive_11r_cfg() - initialize enable_adaptive_11r
+ * flag
+ * @psoc: Pointer to PSOC
+ * @lfr: pointer to mlme lfr config
+ *
+ * Return: None
+ */
+static void
+mlme_init_adaptive_11r_cfg(struct wlan_objmgr_psoc *psoc,
+ struct wlan_mlme_lfr_cfg *lfr)
+{
+ lfr->enable_adaptive_11r = cfg_get(psoc, CFG_ADAPTIVE_11R);
+}
+
+#else
+static inline void
+mlme_init_adaptive_11r_cfg(struct wlan_objmgr_psoc *psoc,
+ struct wlan_mlme_lfr_cfg *lfr)
+{
+}
+#endif
+
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
static void mlme_init_roam_offload_cfg(struct wlan_objmgr_psoc *psoc,
struct wlan_mlme_lfr_cfg *lfr)
@@ -1752,6 +1776,7 @@ static void mlme_init_lfr_cfg(struct wlan_objmgr_psoc *psoc,
mlme_init_roam_offload_cfg(psoc, lfr);
mlme_init_ese_cfg(psoc, lfr);
mlme_init_bss_load_trigger_params(psoc, &lfr->bss_load_trig);
+ mlme_init_adaptive_11r_cfg(psoc, lfr);
mlme_init_subnet_detection(psoc, lfr);
}
diff --git a/components/mlme/dispatcher/inc/cfg_mlme_lfr.h b/components/mlme/dispatcher/inc/cfg_mlme_lfr.h
index f20db59ff370..98ae5a5faa3e 100644
--- a/components/mlme/dispatcher/inc/cfg_mlme_lfr.h
+++ b/components/mlme/dispatcher/inc/cfg_mlme_lfr.h
@@ -2385,6 +2385,42 @@
#define LFR_SUBNET_DETECTION_ALL
#endif
+#ifdef WLAN_ADAPTIVE_11R
+/*
+ *
+ * adaptive_11r - Enable/disable adaptive 11r feature.
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * Adaptive 11r feature enables the AP to support FT-AKM without
+ * configuring the FT-AKM in the network. The AP will advertise non-FT akm
+ * with a vendor specific IE having Adaptive 11r bit set to 1 in the IE data.
+ * The AP also advertises the MDE in beacon/probe response.
+ *
+ * STA should check the adaptive 11r capability if the AP advertises MDE in
+ * beacon/probe and adaptive 11r capability in vendor specific IE. If adaptive
+ * 11r capability is found, STA can advertise the FT equivalent of the non-FT
+ * AKM and connect with 11r protocol.
+ *
+ * Related: None.
+ *
+ * Supported Feature: Fast BSS Transition
+ *
+ * Usage: External
+ *
+ *
+ */
+#define CFG_ADAPTIVE_11R CFG_INI_BOOL( \
+ "enable_adaptive_11r", \
+ false, \
+ "Enable/disable adaptive 11r support")
+
+#define ADAPTIVE_11R_ALL CFG(CFG_ADAPTIVE_11R)
+#else
+#define ADAPTIVE_11R_ALL
+#endif
+
/*
*
* roaming_scan_policy - To config roaming scan policy
@@ -2589,6 +2625,7 @@
CFG(CFG_POST_INACTIVITY_ROAM_SCAN_PERIOD) \
CFG(CFG_BSS_LOAD_TRIG_5G_RSSI_THRES) \
CFG(CFG_BSS_LOAD_TRIG_2G_RSSI_THRES) \
+ ADAPTIVE_11R_ALL \
ROAM_OFFLOAD_ALL \
LFR_ESE_ALL \
LFR_SUBNET_DETECTION_ALL
diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h
index 802f73eb9c87..0f3f929b7c06 100644
--- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h
+++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h
@@ -1352,6 +1352,9 @@ struct bss_load_trigger {
* @roam_scan_hi_rssi_ub: Upper bound after which 5GHz scan
* @roam_prefer_5ghz: Prefer roaming to 5GHz Bss
* @roam_intra_band: Prefer roaming within Band
+ * @enable_adaptive_11r Flag to check if adaptive 11r ini is enabled
+ * @tgt_adaptive_11r_cap: Flag to check if target supports adaptive
+ * 11r
* @roam_scan_home_away_time: The home away time to firmware
* @roam_scan_n_probes: The number of probes to be sent for firmware roaming
* @delay_before_vdev_stop:Wait time for tx complete before vdev stop
@@ -1450,6 +1453,10 @@ struct wlan_mlme_lfr_cfg {
uint32_t roam_scan_hi_rssi_ub;
bool roam_prefer_5ghz;
bool roam_intra_band;
+#ifdef WLAN_ADAPTIVE_11R
+ bool enable_adaptive_11r;
+ bool tgt_adaptive_11r_cap;
+#endif
uint16_t roam_scan_home_away_time;
uint32_t roam_scan_n_probes;
uint8_t delay_before_vdev_stop;
diff --git a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h
index 8dc5bf104be9..fa62cfb5e7a9 100644
--- a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h
+++ b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h
@@ -1156,6 +1156,27 @@ QDF_STATUS
ucfg_mlme_is_roam_scan_offload_enabled(struct wlan_objmgr_psoc *psoc,
bool *val);
+#ifdef WLAN_ADAPTIVE_11R
+/**
+ * ucfg_mlme_set_tgt_adaptive_11r_cap() - Set adaptive 11r target service
+ * capability
+ * @psoc: pointer to psoc object
+ * @val: Target capability of adaptive 11r
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+ucfg_mlme_set_tgt_adaptive_11r_cap(struct wlan_objmgr_psoc *psoc,
+ bool val);
+#else
+static inline QDF_STATUS
+ucfg_mlme_set_tgt_adaptive_11r_cap(struct wlan_objmgr_psoc *psoc,
+ bool val)
+{
+ return QDF_STATUS_SUCCESS;
+}
+#endif
+
/**
* ucfg_mlme_set_roam_scan_offload_enabled() - Set roam scan offload enable
* @psoc: pointer to psoc object
diff --git a/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c b/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c
index 3e33d846f9b6..aee44af97697 100644
--- a/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c
+++ b/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c
@@ -849,6 +849,23 @@ ucfg_mlme_set_fast_transition_enabled(struct wlan_objmgr_psoc *psoc,
return QDF_STATUS_SUCCESS;
}
+#ifdef WLAN_ADAPTIVE_11R
+QDF_STATUS
+ucfg_mlme_set_tgt_adaptive_11r_cap(struct wlan_objmgr_psoc *psoc,
+ bool val)
+{
+ struct wlan_mlme_psoc_obj *mlme_obj;
+
+ mlme_obj = mlme_get_psoc_obj(psoc);
+ if (!mlme_obj)
+ return QDF_STATUS_E_INVAL;
+
+ mlme_obj->cfg.lfr.tgt_adaptive_11r_cap = val;
+
+ return QDF_STATUS_SUCCESS;
+}
+#endif
+
QDF_STATUS
ucfg_mlme_is_roam_scan_offload_enabled(struct wlan_objmgr_psoc *psoc,
bool *val)
diff --git a/configs/default_defconfig b/configs/default_defconfig
index 56efc5dc4b15..e13ecb1c76e7 100644
--- a/configs/default_defconfig
+++ b/configs/default_defconfig
@@ -159,6 +159,9 @@ CONFIG_QCOM_VOWIFI_11R := y
#Flag to enable disable ACTION OUI feature
CONFIG_WLAN_FEATURE_ACTION_OUI := y
+#Flag to enable Adaptive 11r feature
+CONFIG_ADAPTIVE_11R := y
+
#Flag to enable FILS Feature (11ai)
CONFIG_WLAN_FEATURE_FILS := y
ifneq ($(CONFIG_QCA_CLD_WLAN),)
diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h
index 67c2741f1af5..83c3c2b76825 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -671,6 +671,7 @@ struct bss_description {
struct fils_ind_elements fils_info_element;
#endif
uint32_t assoc_disallowed;
+ uint32_t adaptive_11r_ap;
/* Please keep the structure 4 bytes aligned above the ieFields */
uint32_t ieFields[1];
};
@@ -912,6 +913,7 @@ struct join_req {
#endif
bool is11Rconnection;
+ bool is_adaptive_11r_connection;
#ifdef FEATURE_WLAN_ESE
bool isESEFeatureIniEnabled;
bool isESEconnection;
@@ -2249,6 +2251,7 @@ struct roam_offload_scan_req {
uint32_t R0KH_ID_Length;
uint8_t RoamKeyMgmtOffloadEnabled;
struct pmkid_mode_bits pmkid_modes;
+ bool is_adaptive_11r_connection;
/* Idle/Disconnect roam parameters */
struct wmi_idle_roam_params idle_roam_params;
diff --git a/core/sme/inc/csr_internal.h b/core/sme/inc/csr_internal.h
index c670de74d29c..8ac6c4699622 100644
--- a/core/sme/inc/csr_internal.h
+++ b/core/sme/inc/csr_internal.h
@@ -689,6 +689,7 @@ struct csr_roam_session {
bool is_fils_connection;
uint16_t fils_seq_num;
bool discon_in_progress;
+ bool is_adaptive_11r_connection;
struct csr_disconnect_stats disconnect_stats;
};
diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c
index d3273ba17987..efa2fc414dda 100644
--- a/core/sme/src/csr/csr_api_roam.c
+++ b/core/sme/src/csr/csr_api_roam.c
@@ -15208,6 +15208,27 @@ csr_update_he_caps_mcs(struct wlan_mlme_cfg *mlme_cfg,
}
#endif
+#ifdef WLAN_ADAPTIVE_11R
+/**
+ * csr_get_adaptive_11r_enabled() - Function to check if adaptive 11r
+ * ini is enabled or disabled
+ * @mac: pointer to mac context
+ *
+ * Return: true if adaptive 11r is enabled
+ */
+static bool
+csr_get_adaptive_11r_enabled(struct mac_context *mac)
+{
+ return mac->mlme_cfg->lfr.enable_adaptive_11r;
+}
+#else
+static inline bool
+csr_get_adaptive_11r_enabled(struct mac_context *mac)
+{
+ return false;
+}
+#endif
+
/**
* The communication between HDD and LIM is thru mailbox (MB).
* Both sides will access the data structure "struct join_req".
@@ -15525,6 +15546,16 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId,
csr_join_req->operationalRateSet.numRates = 0;
csr_join_req->extendedRateSet.numRates = 0;
}
+
+ if (pBssDescription->adaptive_11r_ap)
+ pSession->is_adaptive_11r_connection =
+ csr_get_adaptive_11r_enabled(mac);
+ else
+ pSession->is_adaptive_11r_connection = false;
+
+ csr_join_req->is_adaptive_11r_connection =
+ pSession->is_adaptive_11r_connection;
+
/* rsnIE */
if (csr_is_profile_wpa(pProfile)) {
/* Insert the Wpa IE into the join request */
@@ -17897,6 +17928,25 @@ void csr_update_roam_scan_ese_params(struct roam_offload_scan_req *req_buf,
}
#endif
+#ifdef WLAN_ADAPTIVE_11R
+static void
+csr_update_roam_req_adaptive_11r(struct csr_roam_session *session,
+ struct mac_context *mac_ctx,
+ struct roam_offload_scan_req *req_buf)
+{
+ req_buf->is_adaptive_11r_connection =
+ session->is_adaptive_11r_connection;
+}
+#else
+static void
+csr_update_roam_req_adaptive_11r(struct csr_roam_session *session,
+ struct mac_context *mac_ctx,
+ struct roam_offload_scan_req *req_buf)
+{
+ req_buf->is_adaptive_11r_connection = false;
+}
+#endif
+
/**
* csr_update_roam_scan_offload_request() - updates req msg with roam offload
* parameters
@@ -17942,6 +17992,7 @@ csr_update_roam_scan_offload_request(struct mac_context *mac_ctx,
mac_ctx->mlme_cfg->lfr.roam_trigger_reason_bitmask;
req_buf->roam_force_rssi_trigger =
mac_ctx->mlme_cfg->lfr.roam_force_rssi_trigger;
+ csr_update_roam_req_adaptive_11r(session, mac_ctx, req_buf);
/* fill bss load triggered roam related configs */
req_buf->bss_load_trig_enabled =
@@ -19460,6 +19511,24 @@ uint8_t csr_get_roam_enabled_sta_sessionid(struct mac_context *mac_ctx)
return WLAN_UMAC_VDEV_ID_MAX;
}
+#ifdef WLAN_ADAPTIVE_11R
+static bool
+csr_is_adaptive_11r_roam_supported(struct mac_context *mac_ctx,
+ struct csr_roam_session *session)
+{
+ return session->is_adaptive_11r_connection &&
+ mac_ctx->mlme_cfg->lfr.tgt_adaptive_11r_cap;
+}
+#else
+static bool
+csr_is_adaptive_11r_roam_supported(struct mac_context *mac_ctx,
+ struct csr_roam_session *session)
+
+{
+ return true;
+}
+#endif
+
/**
* csr_roam_offload_scan() - populates roam offload scan request and sends to
* WMA
@@ -19559,6 +19628,11 @@ csr_roam_offload_scan(struct mac_context *mac_ctx, uint8_t session_id,
return QDF_STATUS_SUCCESS;
}
+ if (!csr_is_adaptive_11r_roam_supported(mac_ctx, session)) {
+ sme_info("Adaptive 11r Roaming not suppprted by fw");
+ return QDF_STATUS_SUCCESS;
+ }
+
/* Roaming is not supported currently for OWE akm */
if (roam_profile_akm == eCSR_AUTH_TYPE_OWE) {
sme_info("OWE Roaming not suppprted by fw");
diff --git a/core/sme/src/csr/csr_api_scan.c b/core/sme/src/csr/csr_api_scan.c
index ac7d589cfb78..31eb8df56414 100644
--- a/core/sme/src/csr/csr_api_scan.c
+++ b/core/sme/src/csr/csr_api_scan.c
@@ -2354,6 +2354,31 @@ static enum wlan_phymode csr_convert_dotllmod_phymode(eCsrPhyMode dotllmode)
return con_phy_mode;
}
+#ifdef WLAN_ADAPTIVE_11R
+/**
+ * csr_update_adaptive_11r_scan_filter - Copy adaptive 11r ini to scan
+ * module
+ * @mac_ctx: Pointer to mac_context
+ * @scan_filter: Scan filter to be sent to scan module
+ *
+ * Return: None
+ */
+static void
+csr_update_adaptive_11r_scan_filter(struct mac_context *mac_ctx,
+ struct scan_filter *filter)
+{
+ filter->enable_adaptive_11r =
+ mac_ctx->mlme_cfg->lfr.enable_adaptive_11r;
+}
+#else
+static inline void
+csr_update_adaptive_11r_scan_filter(struct mac_context *mac_ctx,
+ struct scan_filter *filter)
+{
+ filter->enable_adaptive_11r = false;
+}
+#endif
+
static QDF_STATUS csr_prepare_scan_filter(struct mac_context *mac_ctx,
tCsrScanResultFilter *pFilter,
struct scan_filter *filter)
@@ -2463,6 +2488,9 @@ static QDF_STATUS csr_prepare_scan_filter(struct mac_context *mac_ctx,
filter->bss_scoring_required = true;
else
filter->bss_scoring_required = false;
+
+ csr_update_adaptive_11r_scan_filter(mac_ctx, filter);
+
if (!pFilter->BSSIDs.numOfBSSIDs) {
if (policy_mgr_map_concurrency_mode(
&pFilter->csrPersona, &new_mode)) {
@@ -2652,6 +2680,7 @@ static QDF_STATUS csr_fill_bss_from_scan_entry(struct mac_context *mac_ctx,
bss_desc->tsf_delta = scan_entry->tsf_delta;
bss_desc->assoc_disallowed = csr_is_assoc_disallowed(mac_ctx,
scan_entry);
+ bss_desc->adaptive_11r_ap = scan_entry->adaptive_11r_ap;
qdf_mem_copy(&bss_desc->mbssid_info, &scan_entry->mbssid_info,
sizeof(struct scan_mbssid_info));
diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c
index 43503a2b04f4..806b3464c588 100644
--- a/core/wma/src/wma_main.c
+++ b/core/wma/src/wma_main.c
@@ -5818,9 +5818,37 @@ static void wma_set_pmo_caps(struct wlan_objmgr_psoc *psoc)
WMA_LOGE("Failed to set PMO capabilities; status:%d", status);
}
+/**
+ * wma_set_mlme_caps() - Populate the MLME related target capabilities to the
+ * mlme component
+ * @psoc: Pointer to psoc object
+ *
+ * Return: None
+ */
+static void wma_set_mlme_caps(struct wlan_objmgr_psoc *psoc)
+{
+ tp_wma_handle wma;
+ bool tgt_cap;
+ QDF_STATUS status;
+
+ wma = cds_get_context(QDF_MODULE_ID_WMA);
+ if (!wma) {
+ WMA_LOGE("%s: wma handler is null", __func__);
+ return;
+ }
+
+ tgt_cap = wmi_service_enabled(wma->wmi_handle,
+ wmi_service_adaptive_11r_support);
+
+ status = ucfg_mlme_set_tgt_adaptive_11r_cap(psoc, tgt_cap);
+ if (QDF_IS_STATUS_ERROR(status))
+ WMA_LOGE("Failed to set adaptive 11r cap");
+}
+
static void wma_set_component_caps(struct wlan_objmgr_psoc *psoc)
{
wma_set_pmo_caps(psoc);
+ wma_set_mlme_caps(psoc);
}
#if defined(WLAN_FEATURE_GTK_OFFLOAD) && defined(WLAN_POWER_MANAGEMENT_OFFLOAD)
diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c
index 85da84bffd47..9f17abd2a39c 100644
--- a/core/wma/src/wma_scan_roam.c
+++ b/core/wma/src/wma_scan_roam.c
@@ -320,6 +320,7 @@ static void wma_roam_scan_offload_set_params(
params->fw_okc = roam_req->pmkid_modes.fw_okc;
params->fw_pmksa_cache = roam_req->pmkid_modes.fw_pmksa_cache;
params->rct_validity_timer = roam_req->rct_validity_timer;
+ params->is_adaptive_11r = roam_req->is_adaptive_11r_connection;
WMA_LOGD(FL("qos_caps: %d, qos_enabled: %d, ho_delay_for_rx: %d, roam_scan_mode: %d"),
params->roam_offload_params.qos_caps,
params->roam_offload_params.qos_enabled,