|
@@ -9506,6 +9506,68 @@ bool is_disconnect_pending(struct mac_context *pmac, uint8_t vdev_id)
|
|
|
return disconnect_cmd_exist;
|
|
|
}
|
|
|
|
|
|
+#if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD)
|
|
|
+static void
|
|
|
+csr_clear_other_bss_sae_single_pmk_entry(struct mac_context *mac,
|
|
|
+ struct bss_description *bss_desc,
|
|
|
+ uint8_t vdev_id)
|
|
|
+{
|
|
|
+ struct wlan_objmgr_vdev *vdev;
|
|
|
+
|
|
|
+ if (!bss_desc->is_single_pmk)
|
|
|
+ return;
|
|
|
+
|
|
|
+ vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id,
|
|
|
+ WLAN_LEGACY_SME_ID);
|
|
|
+ if (!vdev) {
|
|
|
+ sme_err("vdev is NULL");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ wlan_crypto_selective_clear_sae_single_pmk_entries(vdev,
|
|
|
+ (struct qdf_mac_addr *)bss_desc->bssId);
|
|
|
+
|
|
|
+ wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+csr_delete_current_bss_sae_single_pmk_entry(struct mac_context *mac,
|
|
|
+ struct bss_description *bss_desc,
|
|
|
+ uint8_t vdev_id)
|
|
|
+{
|
|
|
+ struct wlan_objmgr_vdev *vdev;
|
|
|
+ struct wlan_crypto_pmksa pmksa;
|
|
|
+
|
|
|
+ if (!bss_desc->is_single_pmk)
|
|
|
+ return;
|
|
|
+
|
|
|
+ vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id,
|
|
|
+ WLAN_LEGACY_SME_ID);
|
|
|
+ if (!vdev) {
|
|
|
+ sme_err("vdev is NULL");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ qdf_copy_macaddr(&pmksa.bssid,
|
|
|
+ (struct qdf_mac_addr *)bss_desc->bssId);
|
|
|
+ wlan_crypto_set_del_pmksa(vdev, &pmksa, false);
|
|
|
+
|
|
|
+ wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
|
|
|
+}
|
|
|
+#else
|
|
|
+static inline void
|
|
|
+csr_clear_other_bss_sae_single_pmk_entry(struct mac_context *mac,
|
|
|
+ struct bss_description *bss_desc,
|
|
|
+ uint8_t vdev_id)
|
|
|
+{}
|
|
|
+
|
|
|
+static inline void
|
|
|
+csr_delete_current_bss_sae_single_pmk_entry(struct mac_context *mac,
|
|
|
+ struct bss_description *bss_desc,
|
|
|
+ uint8_t vdev_id)
|
|
|
+{}
|
|
|
+#endif
|
|
|
+
|
|
|
static void csr_roam_join_rsp_processor(struct mac_context *mac,
|
|
|
struct join_rsp *pSmeJoinRsp)
|
|
|
{
|
|
@@ -9582,6 +9644,16 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac,
|
|
|
* the response to upper layers
|
|
|
*/
|
|
|
session_ptr->join_bssid_count = 0;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * On successful connection to sae single pmk AP,
|
|
|
+ * clear all the single pmk AP.
|
|
|
+ */
|
|
|
+ if (pCommand && pCommand->u.roamCmd.pLastRoamBss)
|
|
|
+ csr_clear_other_bss_sae_single_pmk_entry(mac,
|
|
|
+ pCommand->u.roamCmd.pLastRoamBss,
|
|
|
+ pSmeJoinRsp->vdev_id);
|
|
|
+
|
|
|
csr_roam_complete(mac, eCsrJoinSuccess, (void *)pSmeJoinRsp,
|
|
|
pSmeJoinRsp->vdev_id);
|
|
|
|
|
@@ -9602,6 +9674,14 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac,
|
|
|
pSmeJoinRsp->status_code, pSmeJoinRsp->status_code,
|
|
|
reason_code);
|
|
|
|
|
|
+ /*
|
|
|
+ * If connection fails with Single PMK bssid, clear this pmk
|
|
|
+ * entry.
|
|
|
+ */
|
|
|
+ if (pCommand && pCommand->u.roamCmd.pLastRoamBss)
|
|
|
+ csr_delete_current_bss_sae_single_pmk_entry(
|
|
|
+ mac, pCommand->u.roamCmd.pLastRoamBss,
|
|
|
+ pSmeJoinRsp->vdev_id);
|
|
|
/*
|
|
|
* Delete the PMKID of the BSSID for which the assoc reject is
|
|
|
* received from the AP due to invalid PMKID reason.
|
|
@@ -14712,7 +14792,8 @@ void csr_get_pmk_info(struct mac_context *mac_ctx, uint8_t session_id,
|
|
|
}
|
|
|
|
|
|
QDF_STATUS csr_roam_set_psk_pmk(struct mac_context *mac, uint32_t sessionId,
|
|
|
- uint8_t *pPSK_PMK, size_t pmk_len)
|
|
|
+ uint8_t *psk_pmk, size_t pmk_len,
|
|
|
+ bool update_to_fw)
|
|
|
{
|
|
|
struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId);
|
|
|
|
|
@@ -14720,7 +14801,7 @@ QDF_STATUS csr_roam_set_psk_pmk(struct mac_context *mac, uint32_t sessionId,
|
|
|
sme_err("session %d not found", sessionId);
|
|
|
return QDF_STATUS_E_FAILURE;
|
|
|
}
|
|
|
- qdf_mem_copy(pSession->psk_pmk, pPSK_PMK, sizeof(pSession->psk_pmk));
|
|
|
+ qdf_mem_copy(pSession->psk_pmk, psk_pmk, sizeof(pSession->psk_pmk));
|
|
|
pSession->pmk_len = pmk_len;
|
|
|
|
|
|
if (csr_is_auth_type_ese(mac->roam.roamSession[sessionId].
|
|
@@ -14729,7 +14810,9 @@ QDF_STATUS csr_roam_set_psk_pmk(struct mac_context *mac, uint32_t sessionId,
|
|
|
return QDF_STATUS_SUCCESS;
|
|
|
}
|
|
|
|
|
|
- csr_roam_update_cfg(mac, sessionId, REASON_ROAM_PSK_PMK_CHANGED);
|
|
|
+ if (update_to_fw)
|
|
|
+ csr_roam_update_cfg(mac, sessionId,
|
|
|
+ REASON_ROAM_PSK_PMK_CHANGED);
|
|
|
|
|
|
return QDF_STATUS_SUCCESS;
|
|
|
}
|
|
@@ -14776,6 +14859,50 @@ void csr_clear_sae_single_pmk(struct wlan_objmgr_psoc *psoc,
|
|
|
}
|
|
|
wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
|
|
|
}
|
|
|
+
|
|
|
+void
|
|
|
+csr_store_sae_single_pmk_to_global_cache(struct mac_context *mac,
|
|
|
+ struct csr_roam_session *session,
|
|
|
+ uint8_t vdev_id)
|
|
|
+{
|
|
|
+ struct wlan_objmgr_vdev *vdev;
|
|
|
+ struct mlme_pmk_info *pmk_info;
|
|
|
+
|
|
|
+ if (!session->pConnectBssDesc)
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (!session->pConnectBssDesc->is_single_pmk)
|
|
|
+ return;
|
|
|
+
|
|
|
+ vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id,
|
|
|
+ WLAN_LEGACY_SME_ID);
|
|
|
+ if (!vdev) {
|
|
|
+ sme_err("vdev is NULL");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Mark the AP as single PMK capable in Crypto Table
|
|
|
+ */
|
|
|
+ wlan_crypto_set_sae_single_pmk_bss_cap(vdev,
|
|
|
+ (struct qdf_mac_addr *)session->pConnectBssDesc->bssId,
|
|
|
+ true);
|
|
|
+
|
|
|
+ pmk_info = qdf_mem_malloc(sizeof(*pmk_info));
|
|
|
+ if (!pmk_info) {
|
|
|
+ wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ qdf_mem_copy(pmk_info->pmk, session->psk_pmk, session->pmk_len);
|
|
|
+ pmk_info->pmk_len = session->pmk_len;
|
|
|
+
|
|
|
+ wlan_mlme_update_sae_single_pmk(vdev, pmk_info);
|
|
|
+
|
|
|
+ wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
|
|
|
+ qdf_mem_zero(pmk_info, sizeof(*pmk_info));
|
|
|
+ qdf_mem_free(pmk_info);
|
|
|
+}
|
|
|
#endif
|
|
|
|
|
|
QDF_STATUS csr_roam_del_pmkid_from_cache(struct mac_context *mac,
|
|
@@ -21337,9 +21464,11 @@ csr_check_and_set_sae_single_pmk_cap(struct mac_context *mac_ctx,
|
|
|
struct csr_roam_session *session,
|
|
|
uint8_t vdev_id)
|
|
|
{
|
|
|
- bool val;
|
|
|
struct wlan_objmgr_vdev *vdev;
|
|
|
- uint32_t keymgmt;
|
|
|
+ struct mlme_pmk_info *pmk_info;
|
|
|
+ tPmkidCacheInfo *pmkid_cache;
|
|
|
+ uint32_t keymgmt, pmkid_index;
|
|
|
+ bool val, lookup_success;
|
|
|
|
|
|
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id,
|
|
|
WLAN_LEGACY_SME_ID);
|
|
@@ -21354,7 +21483,49 @@ csr_check_and_set_sae_single_pmk_cap(struct mac_context *mac_ctx,
|
|
|
val = csr_is_sae_single_pmk_vsie_ap(session->pConnectBssDesc);
|
|
|
wlan_mlme_set_sae_single_pmk_bss_cap(mac_ctx->psoc, vdev_id,
|
|
|
val);
|
|
|
+ if (!val)
|
|
|
+ goto end;
|
|
|
+
|
|
|
+ wlan_crypto_set_sae_single_pmk_bss_cap(vdev,
|
|
|
+ (struct qdf_mac_addr *)session->pConnectBssDesc->bssId,
|
|
|
+ true);
|
|
|
+
|
|
|
+ pmkid_cache = qdf_mem_malloc(sizeof(*pmkid_cache));
|
|
|
+ if (!pmkid_cache)
|
|
|
+ goto end;
|
|
|
+
|
|
|
+ qdf_copy_macaddr(&pmkid_cache->BSSID,
|
|
|
+ &session->connectedProfile.bssid);
|
|
|
+ /*
|
|
|
+ * In SAE single pmk roaming case, there will
|
|
|
+ * be no PMK entry found for the AP in pmk cache.
|
|
|
+ * So if the lookup is successful, then we have done
|
|
|
+ * a FULL sae here. In that case, clear all other
|
|
|
+ * single pmk entries.
|
|
|
+ */
|
|
|
+ lookup_success = csr_lookup_pmkid_using_bssid(mac_ctx, session,
|
|
|
+ pmkid_cache,
|
|
|
+ &pmkid_index);
|
|
|
+ qdf_mem_free(pmkid_cache);
|
|
|
+ if (lookup_success) {
|
|
|
+ wlan_crypto_selective_clear_sae_single_pmk_entries(vdev,
|
|
|
+ &session->connectedProfile.bssid);
|
|
|
+
|
|
|
+ pmk_info = qdf_mem_malloc(sizeof(*pmk_info));
|
|
|
+ if (!pmk_info)
|
|
|
+ goto end;
|
|
|
+
|
|
|
+ qdf_mem_copy(pmk_info->pmk, session->psk_pmk,
|
|
|
+ session->pmk_len);
|
|
|
+ pmk_info->pmk_len = session->pmk_len;
|
|
|
+ wlan_mlme_update_sae_single_pmk(vdev, pmk_info);
|
|
|
+
|
|
|
+ qdf_mem_zero(pmk_info, sizeof(*pmk_info));
|
|
|
+ qdf_mem_free(pmk_info);
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+end:
|
|
|
wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
|
|
|
}
|
|
|
#else
|
|
@@ -21506,6 +21677,7 @@ static QDF_STATUS csr_process_roam_sync_callback(struct mac_context *mac_ctx,
|
|
|
mac_ctx->psoc);
|
|
|
mac_ctx->sme.set_connection_info_cb(false);
|
|
|
session->roam_synch_in_progress = false;
|
|
|
+
|
|
|
csr_check_and_set_sae_single_pmk_cap(mac_ctx, session,
|
|
|
session_id);
|
|
|
|