فهرست منبع

qcacld-3.0: Fix roaming between different PMF option APs failure

Roaming between different PMF option APs has following issues:

1. Roaming between Optional -> Disabled -> Optional
When STA roam to optional, PMF is set to False from STA in reassoc
request and all management pkt not secured.

2. Roaming between Required -> Disabled -> Required
STA not able to find candidate AP when tried to roam to AP with PMF
Required.

Root cause: When LFR3 roam happens,  vdev_crypto_params will be reset
including rsn_caps 11w PMF, if new AP hasn't enabled PMF, vdev rsn_caps
11w PMF is disabled too, and  passed to F/W. Then F/W think DUT STA
doesn'tsupport PMF, then failed to roam to AP with PMF Required and
enabled.

Fix:
Get self-capability of 11w PMF from connected profile and pass to F/W in
WMI_ROAM_SCAN_MODE by wmi_fill_rso_tlvs after roaming.

Move target_if_cm_roam_fill_11w_params to csr_cm_roam_fill_11w_params,
put protocol part to csr connection manager.

Change-Id: I543799385ec8c0ec7afdf64e2310c24758305095
CRs-Fixed: 2807454
Jianmin Zhu 4 سال پیش
والد
کامیت
0837cb4583
2فایلهای تغییر یافته به همراه89 افزوده شده و 79 حذف شده
  1. 0 61
      components/target_if/connection_mgr/src/target_if_cm_roam_offload.c
  2. 89 18
      core/sme/src/csr/csr_api_roam.c

+ 0 - 61
components/target_if/connection_mgr/src/target_if_cm_roam_offload.c

@@ -516,65 +516,6 @@ target_if_cm_roam_scan_offload_scan_period(
 	return wmi_unified_roam_scan_offload_scan_period(wmi_handle, req);
 }
 
-#ifdef WLAN_FEATURE_11W
-/**
- * target_if_roam_fill_11w_params() - Fill the 11w related parameters
- * for ap profile
- * @vdev: vdev object
- * @req: roam ap profile parameters
- *
- * Return: None
- */
-static void
-target_if_cm_roam_fill_11w_params(struct wlan_objmgr_vdev *vdev,
-				  struct ap_profile_params *req)
-{
-	uint32_t group_mgmt_cipher;
-	uint16_t rsn_caps;
-	bool peer_rmf_capable = false;
-	uint32_t keymgmt;
-
-	if (!vdev) {
-		target_if_err("Invalid vdev");
-		return;
-	}
-
-	rsn_caps = (uint16_t)wlan_crypto_get_param(vdev,
-						   WLAN_CRYPTO_PARAM_RSN_CAP);
-	if (wlan_crypto_vdev_has_mgmtcipher(
-					vdev,
-					(1 << WLAN_CRYPTO_CIPHER_AES_GMAC) |
-					(1 << WLAN_CRYPTO_CIPHER_AES_GMAC_256) |
-					(1 << WLAN_CRYPTO_CIPHER_AES_CMAC)) &&
-					(rsn_caps &
-					 WLAN_CRYPTO_RSN_CAP_MFP_ENABLED))
-		peer_rmf_capable = true;
-
-	keymgmt = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_MGMT_CIPHER);
-
-	if (keymgmt & (1 << WLAN_CRYPTO_CIPHER_AES_CMAC))
-		group_mgmt_cipher = WMI_CIPHER_AES_CMAC;
-	else if (keymgmt & (1 << WLAN_CRYPTO_CIPHER_AES_GMAC))
-		group_mgmt_cipher = WMI_CIPHER_AES_GMAC;
-	else if (keymgmt & (1 << WLAN_CRYPTO_CIPHER_AES_GMAC_256))
-		group_mgmt_cipher = WMI_CIPHER_BIP_GMAC_256;
-	 else
-		group_mgmt_cipher = WMI_CIPHER_NONE;
-
-	if (peer_rmf_capable) {
-		req->profile.rsn_mcastmgmtcipherset = group_mgmt_cipher;
-		req->profile.flags |= WMI_AP_PROFILE_FLAG_PMF;
-	} else {
-		req->profile.rsn_mcastmgmtcipherset = WMI_CIPHER_NONE;
-	}
-}
-#else
-static inline
-void target_if_cm_roam_fill_11w_params(struct wlan_objmgr_vdev *vdev,
-				       struct ap_profile_params *req)
-{}
-#endif
-
 /**
  * target_if_cm_roam_scan_offload_ap_profile() - send roam ap profile to
  * firmware
@@ -606,8 +547,6 @@ target_if_cm_roam_scan_offload_ap_profile(
 		req->profile.rsn_authmode =
 		target_if_cm_roam_scan_get_cckm_mode(vdev, rsn_authmode);
 
-	target_if_cm_roam_fill_11w_params(vdev, req);
-
 	db2dbm_enabled = wmi_service_enabled(wmi_handle,
 					     wmi_service_hw_db2dbm_support);
 	if (!req->profile.rssi_abs_thresh) {

+ 89 - 18
core/sme/src/csr/csr_api_roam.c

@@ -10915,11 +10915,94 @@ static void csr_update_pmf_cap_from_profile(struct csr_roam_profile *profile,
 	if (profile->MFPRequired)
 		filter->pmf_cap = WLAN_PMF_REQUIRED;
 }
+
+static void
+csr_cm_roam_fill_11w_params(struct mac_context *mac_ctx,
+			    uint8_t vdev_id,
+			    struct ap_profile_params *req)
+{
+	uint32_t group_mgmt_cipher;
+	bool peer_rmf_capable = false;
+	uint32_t keymgmt;
+	struct wlan_objmgr_vdev *vdev;
+	uint16_t rsn_caps;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id,
+						    WLAN_LEGACY_SME_ID);
+	if (!vdev) {
+		sme_err("Invalid vdev");
+		return;
+	}
+
+	/*
+	 * Get rsn cap of link, intersection of self cap and bss cap,
+	 * Only set PMF flags when both STA and current AP has MFP enabled
+	 */
+	rsn_caps = (uint16_t)wlan_crypto_get_param(vdev,
+						   WLAN_CRYPTO_PARAM_RSN_CAP);
+	if (wlan_crypto_vdev_has_mgmtcipher(vdev,
+					(1 << WLAN_CRYPTO_CIPHER_AES_GMAC) |
+					(1 << WLAN_CRYPTO_CIPHER_AES_GMAC_256) |
+					(1 << WLAN_CRYPTO_CIPHER_AES_CMAC)) &&
+					(rsn_caps &
+					 WLAN_CRYPTO_RSN_CAP_MFP_ENABLED))
+		peer_rmf_capable = true;
+
+	keymgmt = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_MGMT_CIPHER);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
+
+	if (keymgmt & (1 << WLAN_CRYPTO_CIPHER_AES_CMAC))
+		group_mgmt_cipher = WMI_CIPHER_AES_CMAC;
+	else if (keymgmt & (1 << WLAN_CRYPTO_CIPHER_AES_GMAC))
+		group_mgmt_cipher = WMI_CIPHER_AES_GMAC;
+	else if (keymgmt & (1 << WLAN_CRYPTO_CIPHER_AES_GMAC_256))
+		group_mgmt_cipher = WMI_CIPHER_BIP_GMAC_256;
+	else
+		group_mgmt_cipher = WMI_CIPHER_NONE;
+
+	if (peer_rmf_capable) {
+		req->profile.rsn_mcastmgmtcipherset = group_mgmt_cipher;
+		req->profile.flags |= WMI_AP_PROFILE_FLAG_PMF;
+	} else {
+		req->profile.rsn_mcastmgmtcipherset = WMI_CIPHER_NONE;
+	}
+}
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+static void
+csr_cm_roam_fill_rsn_caps(struct mac_context *mac, uint8_t vdev_id,
+			  uint16_t *rsn_caps)
+{
+	tCsrRoamConnectedProfile *profile;
+
+	/* Copy the self RSN capabilities in roam offload request */
+	profile = &mac->roam.roamSession[vdev_id].connectedProfile;
+	*rsn_caps &= ~WLAN_CRYPTO_RSN_CAP_MFP_ENABLED;
+	*rsn_caps &= ~WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED;
+	if (profile->MFPRequired)
+		*rsn_caps |= WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED;
+	if (profile->MFPCapable)
+		*rsn_caps |= WLAN_CRYPTO_RSN_CAP_MFP_ENABLED;
+}
+#endif
 #else
 static inline
 void csr_update_pmf_cap_from_profile(struct csr_roam_profile *profile,
 				     struct scan_filter *filter)
 {}
+
+static inline
+void csr_cm_roam_fill_11w_params(struct mac_context *mac_ctx,
+				 uint8_t vdev_id,
+				 struct ap_profile_params *req)
+{}
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+static inline
+void csr_cm_roam_fill_rsn_caps(struct mac_context *mac, uint8_t vdev_id,
+			       uint16_t *rsn_caps)
+{}
+#endif
 #endif
 
 QDF_STATUS csr_fill_filter_from_vdev_crypto(struct mac_context *mac_ctx,
@@ -17630,6 +17713,7 @@ csr_cm_roam_scan_offload_ap_profile(struct mac_context *mac_ctx,
 	tpCsrNeighborRoamControlInfo roam_info =
 			&mac_ctx->roam.neighborRoamInfo[session->vdev_id];
 
+	csr_cm_roam_fill_11w_params(mac_ctx, session->vdev_id, params);
 	params->vdev_id = session->vdev_id;
 	profile->ssid.length = session->connectedProfile.SSID.length;
 	qdf_mem_copy(profile->ssid.ssid, session->connectedProfile.SSID.ssId,
@@ -18136,7 +18220,6 @@ static QDF_STATUS csr_cm_roam_scan_offload_fill_lfr3_config(
 			struct wlan_roam_scan_offload_params *rso_config,
 			uint8_t command, uint32_t *mode)
 {
-	struct wlan_objmgr_vdev *vdev;
 	tSirMacCapabilityInfo self_caps;
 	tSirMacQosInfoStation sta_qos_info;
 	enum csr_akm_type akm;
@@ -18148,6 +18231,7 @@ static QDF_STATUS csr_cm_roam_scan_offload_fill_lfr3_config(
 	uint16_t vdev_id = session->vdev_id;
 	qdf_size_t val_len;
 	QDF_STATUS status;
+	uint16_t rsn_caps = 0;
 	tpCsrNeighborRoamControlInfo roam_info =
 		&mac->roam.neighborRoamInfo[vdev_id];
 
@@ -18156,14 +18240,6 @@ static QDF_STATUS csr_cm_roam_scan_offload_fill_lfr3_config(
 	if (!rso_config->roam_offload_enabled)
 		return QDF_STATUS_SUCCESS;
 
-	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc,
-						    vdev_id,
-						    WLAN_LEGACY_SME_ID);
-	if (!vdev) {
-		sme_err("Vdev:%d is NULL", vdev_id);
-		return QDF_STATUS_E_FAILURE;
-	}
-
 	/* FILL LFR3 specific roam scan mode TLV parameters */
 	rso_config->rso_lfr3_params.roam_rssi_cat_gap =
 		mac->roam.configParam.bCatRssiOffset;
@@ -18223,21 +18299,17 @@ static QDF_STATUS csr_cm_roam_scan_offload_fill_lfr3_config(
 	final_caps_val = (uint16_t *)&self_caps;
 
 	/*
-	 * RSN caps arent been sent to firmware, so in case of PMF required,
+	 * Self rsn caps aren't sent to firmware, so in case of PMF required,
 	 * the firmware connects to a non PMF AP advertising PMF not required
 	 * in the re-assoc request which violates protocol.
-	 * So send this to firmware in the roam SCAN offload command to
+	 * So send self RSN caps to firmware in roam SCAN offload command to
 	 * let it configure the params in the re-assoc request too.
 	 * Instead of making another infra, send the RSN-CAPS in MSB of
 	 * beacon Caps.
 	 */
+	csr_cm_roam_fill_rsn_caps(mac, vdev_id, &rsn_caps);
 	rso_config->rso_lfr3_caps.capability =
-		(uint16_t)wlan_crypto_get_param(vdev,
-						WLAN_CRYPTO_PARAM_RSN_CAP);
-	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
-
-	rso_config->rso_lfr3_caps.capability <<= RSN_CAPS_SHIFT;
-	rso_config->rso_lfr3_caps.capability |= ((*final_caps_val) & 0xFFFF);
+		(rsn_caps << RSN_CAPS_SHIFT) | ((*final_caps_val) & 0xFFFF);
 
 	rso_config->rso_lfr3_caps.ht_caps_info =
 		*(uint16_t *)&mac->mlme_cfg->ht_caps.ht_cap_info;
@@ -18862,7 +18934,6 @@ wlan_cm_roam_fill_update_config_req(struct wlan_objmgr_psoc *psoc,
 						  &req->rso_chan_info,
 						  ROAM_SCAN_OFFLOAD_UPDATE_CFG,
 						  reason);
-
 	csr_cm_roam_scan_offload_ap_profile(mac_ctx, session,
 					    &req->profile_params);