فهرست منبع

qcacmn: Store crypto keys at PSOC instead of PDEV

Currently, host driver allocates the memory for crypto keys in
PDEV. But during SSR, driver destroys PDEV and VDEV and keys are
deleted. This results in SAP starting in open mode after SSR as
the keys are not plumbed.

So, fix this issue by allocating the memory for crypto keys in
PSOC.

Change-Id: Ie97d94b340df9abb258da703286ce16e62a44253
CRs-Fixed: 3663797
Rahul Gusain 1 سال پیش
والد
کامیت
bfd5bae251

+ 28 - 0
umac/cmn_services/crypto/inc/wlan_crypto_global_api.h

@@ -1245,4 +1245,32 @@ void wlan_crypto_aquire_lock(void);
  */
 void wlan_crypto_release_lock(void);
 #endif /* WLAN_FEATURE_FILS_SK */
+
+/**
+ * crypto_flush_entries - This API will flush crypto keys
+ * @psoc: psoc handler
+ *
+ * Return: None
+ */
+void crypto_flush_entries(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_crypto_flush_entries - wrapper API for "crypto_flush_entries"
+ * @psoc: psoc handler
+ *
+ * Return: None
+ */
+void ucfg_crypto_flush_entries(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_crypto_free_key_by_link_id - free key by link id
+ * @psoc: psoc handler
+ * @link_addr: link address
+ * @link_id: link id
+ *
+ * Return: None
+ */
+void ucfg_crypto_free_key_by_link_id(struct wlan_objmgr_psoc *psoc,
+				     struct qdf_mac_addr *link_addr,
+				     uint8_t link_id);
 #endif /* end of _WLAN_CRYPTO_GLOBAL_API_H_ */

+ 3 - 1
umac/cmn_services/crypto/inc/wlan_crypto_global_def.h

@@ -55,7 +55,9 @@
 #define WLAN_CRYPTO_MAX_VLANKEYIX    WLAN_CRYPTO_MAXKEYIDX
 #endif
 #define WLAN_CRYPTO_MAX_PMKID        (16)
-
+#define WLAN_CRYPTO_TOTAL_KEYIDX     (WLAN_CRYPTO_MAXKEYIDX + \
+					WLAN_CRYPTO_MAXIGTKKEYIDX + \
+					WLAN_CRYPTO_MAXBIGTKKEYIDX)
 /* 40 bit wep key len */
 #define WLAN_CRYPTO_KEY_WEP40_LEN    (5)
 /* 104 bit wep key len */

+ 28 - 11
umac/cmn_services/crypto/src/wlan_crypto_global_api.c

@@ -4409,9 +4409,17 @@ QDF_STATUS wlan_crypto_save_ml_sta_key(
 }
 #endif
 
-static QDF_STATUS wlan_crypto_save_key_sta(struct wlan_objmgr_vdev *vdev,
-					   uint8_t key_index,
-					   struct wlan_crypto_key *crypto_key)
+/**
+ * wlan_crypto_save_key_at_psoc() - Allocate memory for storing key in PSOC
+ * @vdev: vdev object
+ * @key_index: the index of the key that needs to be allocated
+ * @crypto_key: Pointer to crypto key
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+wlan_crypto_save_key_at_psoc(struct wlan_objmgr_vdev *vdev, uint8_t key_index,
+			     struct wlan_crypto_key *crypto_key)
 {
 	struct wlan_objmgr_psoc *psoc;
 	struct crypto_psoc_priv_obj *crypto_psoc_obj;
@@ -4469,10 +4477,11 @@ QDF_STATUS wlan_crypto_save_key(struct wlan_objmgr_vdev *vdev,
 		crypto_err("Invalid Key index %d", key_index);
 		return QDF_STATUS_E_FAILURE;
 	}
-	if (wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE &&
+	if ((wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE ||
+	     wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) &&
 	    wlan_vdev_mlme_is_mlo_vdev(vdev) &&
 	    is_mlo_adv_enable()) {
-		wlan_crypto_save_key_sta(vdev, key_index, crypto_key);
+		wlan_crypto_save_key_at_psoc(vdev, key_index, crypto_key);
 	} else {
 		priv_key = &crypto_priv->crypto_key;
 		if (key_index < WLAN_CRYPTO_MAXKEYIDX) {
@@ -4551,9 +4560,17 @@ struct wlan_crypto_key *wlan_crypto_get_ml_sta_link_key(
 }
 #endif
 
-static struct wlan_crypto_key *wlan_crypto_get_ml_key_sta(
-					struct wlan_objmgr_vdev *vdev,
-					uint8_t key_index)
+/**
+ * wlan_crypto_get_ml_keys_from_index() - Get the stored key information from
+ * key index
+ * @vdev: vdev object
+ * @key_index: the index of the key that needs to be retrieved
+ *
+ * Return: Key material
+ */
+static struct wlan_crypto_key *
+wlan_crypto_get_ml_keys_from_index(struct wlan_objmgr_vdev *vdev,
+				   uint8_t key_index)
 {
 	struct wlan_objmgr_psoc *psoc;
 	struct crypto_psoc_priv_obj *crypto_psoc_obj;
@@ -4623,11 +4640,11 @@ struct wlan_crypto_key *wlan_crypto_get_key(struct wlan_objmgr_vdev *vdev,
 		return NULL;
 	}
 
-	if (wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE &&
+	if ((wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE ||
+	     wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) &&
 	    wlan_vdev_mlme_is_mlo_vdev(vdev) &&
 	    is_mlo_adv_enable()) {
-		return wlan_crypto_get_ml_key_sta(vdev, key_index);
-
+		return wlan_crypto_get_ml_keys_from_index(vdev, key_index);
 	} else {
 		if (key_index < WLAN_CRYPTO_MAXKEYIDX)
 			return priv_key->key[key_index];

+ 52 - 163
umac/cmn_services/crypto/src/wlan_crypto_obj_mgr.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -340,45 +340,67 @@ static void crypto_free_list(struct crypto_psoc_priv_obj *psoc, void *ptr)
 	}
 }
 
-static void crypto_flush_entries(struct crypto_psoc_priv_obj *psoc)
+void crypto_flush_entries(struct wlan_objmgr_psoc *psoc)
 {
 	unsigned int index;
 	struct wlan_crypto_key_entry *hash_entry, *hash_entry_next;
+	struct crypto_psoc_priv_obj *crypto_priv;
 
 	TAILQ_HEAD(, wlan_crypto_key_entry) free_list;
 	TAILQ_INIT(&free_list);
 
-	if (!psoc->crypto_key_holder.mask)
+	crypto_priv = wlan_objmgr_psoc_get_comp_private_obj(psoc,
+							WLAN_UMAC_COMP_CRYPTO);
+
+	if (!crypto_priv)
 		return;
 
-	if (!psoc->crypto_key_holder.bins)
+	if (!crypto_priv->crypto_key_holder.mask)
 		return;
 
-	if (!qdf_atomic_read(&psoc->crypto_key_cnt))
+	if (!crypto_priv->crypto_key_holder.bins)
 		return;
 
-	qdf_mutex_acquire(&psoc->crypto_key_lock);
-	for (index = 0; index <= psoc->crypto_key_holder.mask; index++) {
-		if (!TAILQ_EMPTY(&psoc->crypto_key_holder.bins[index])) {
+	if (!qdf_atomic_read(&crypto_priv->crypto_key_cnt))
+		return;
+
+	qdf_mutex_acquire(&crypto_priv->crypto_key_lock);
+	for (index = 0; index <= crypto_priv->crypto_key_holder.mask; index++) {
+		if (!TAILQ_EMPTY(&crypto_priv->crypto_key_holder.bins[index])) {
 			TAILQ_FOREACH_SAFE(
 				hash_entry,
-				&psoc->crypto_key_holder.bins[index],
+				&crypto_priv->crypto_key_holder.bins[index],
 				hash_list_elem, hash_entry_next) {
-				crypto_remove_entry(psoc, hash_entry,
+				crypto_remove_entry(crypto_priv, hash_entry,
 						    &free_list);
 			}
 		}
 	}
-	crypto_free_list(psoc, &free_list);
-	qdf_mutex_release(&psoc->crypto_key_lock);
+	crypto_free_list(crypto_priv, &free_list);
+	qdf_mutex_release(&crypto_priv->crypto_key_lock);
 }
 
-static void crypto_hash_deinit(struct crypto_psoc_priv_obj *psoc)
+/**
+ * wlan_crypto_hash_deinit() - This API deinit hash mechanism
+ * @psoc: pointer to PSOC object
+ *
+ * Return: void
+ */
+static void wlan_crypto_hash_deinit(struct wlan_objmgr_psoc *psoc)
 {
+	struct crypto_psoc_priv_obj *crypto_priv;
+
+	crypto_priv = wlan_objmgr_psoc_get_comp_private_obj(psoc,
+							WLAN_UMAC_COMP_CRYPTO);
+	if (!crypto_priv) {
+		crypto_err("failed to get crypto obj in psoc");
+		return;
+	}
+
 	crypto_flush_entries(psoc);
-	qdf_mem_free(psoc->crypto_key_holder.bins);
-	psoc->crypto_key_holder.bins = NULL;
-	qdf_mutex_destroy(&psoc->crypto_key_lock);
+	qdf_mem_free(crypto_priv->crypto_key_holder.bins);
+	crypto_priv->crypto_key_holder.bins = NULL;
+	qdf_mutex_destroy(&crypto_priv->crypto_key_lock);
 }
 
 static QDF_STATUS wlan_crypto_psoc_obj_create_handler(
@@ -402,6 +424,16 @@ static QDF_STATUS wlan_crypto_psoc_obj_create_handler(
 		crypto_err("failed to attach crypto psoc priv object");
 		return status;
 	}
+
+	status = wlan_crypto_hash_init(crypto_psoc_obj);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		wlan_objmgr_psoc_component_obj_detach(psoc,
+						      WLAN_UMAC_COMP_CRYPTO,
+						      crypto_psoc_obj);
+		qdf_mem_free(crypto_psoc_obj);
+		crypto_err("failed to hash init");
+	}
+
 	return status;
 }
 
@@ -412,6 +444,8 @@ static QDF_STATUS wlan_crypto_psoc_obj_destroy_handler(
 	QDF_STATUS status;
 	struct crypto_psoc_priv_obj *crypto_psoc_obj;
 
+	wlan_crypto_hash_deinit(psoc);
+
 	crypto_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(
 						psoc,
 						WLAN_UMAC_COMP_CRYPTO);
@@ -429,67 +463,9 @@ static QDF_STATUS wlan_crypto_psoc_obj_destroy_handler(
 	qdf_mem_free(crypto_psoc_obj);
 	return status;
 }
-
-static QDF_STATUS
-wlan_crypto_pdev_obj_create_handler(
-struct wlan_objmgr_pdev *pdev, void *arg)
-{
-	struct pdev_crypto *pdev_priv = NULL;
-	struct crypto_psoc_priv_obj *crypto_psoc_obj;
-	struct wlan_objmgr_psoc *psoc;
-
-	if (!pdev) {
-		crypto_err("crypto pdev is NULL");
-		return QDF_STATUS_E_FAILURE;
-	}
-
-	pdev_priv = (struct pdev_crypto *)
-		 qdf_mem_malloc(sizeof(struct pdev_crypto));
-	if (!pdev_priv) {
-		crypto_err("failed to allocate crypto pdev object");
-		return QDF_STATUS_E_NOMEM;
-	}
-	psoc = wlan_pdev_get_psoc(pdev);
-	crypto_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(
-					psoc,
-					WLAN_UMAC_COMP_CRYPTO);
-	wlan_crypto_hash_init(crypto_psoc_obj);
-
-	pdev_priv->pdev_obj = pdev;
-	wlan_objmgr_pdev_component_obj_attach(pdev, WLAN_UMAC_COMP_CRYPTO,
-					      (void *)pdev_priv,
-					      QDF_STATUS_SUCCESS);
-
-	return QDF_STATUS_SUCCESS;
-}
-
-static QDF_STATUS
-wlan_crypto_pdev_obj_destroy_handler(
-struct wlan_objmgr_pdev *pdev, void *arg)
+#else
+void crypto_flush_entries(struct wlan_objmgr_psoc *psoc)
 {
-	struct pdev_crypto *pdev_priv = NULL;
-	struct crypto_psoc_priv_obj *crypto_psoc_obj;
-	struct wlan_objmgr_psoc *psoc;
-
-	if (!pdev) {
-		crypto_err("crypto pdev is NULL\n");
-		return QDF_STATUS_E_FAILURE;
-	}
-	psoc = wlan_pdev_get_psoc(pdev);
-	crypto_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(
-					psoc,
-					WLAN_UMAC_COMP_CRYPTO);
-
-	crypto_hash_deinit(crypto_psoc_obj);
-	pdev_priv =
-	wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CRYPTO);
-	if (pdev_priv) {
-		wlan_objmgr_pdev_component_obj_detach(
-		pdev, WLAN_UMAC_COMP_CRYPTO, (void *)pdev_priv);
-		qdf_mem_free(pdev_priv);
-	}
-
-	return QDF_STATUS_SUCCESS;
 }
 #endif
 
@@ -826,47 +802,6 @@ static int unregister_psoc_destroy_handler(void)
 	return status;
 }
 
-static int register_pdev_create_handler(void)
-{
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
-
-	status = wlan_objmgr_register_pdev_create_handler(
-			WLAN_UMAC_COMP_CRYPTO,
-			wlan_crypto_pdev_obj_create_handler, NULL);
-	return status;
-}
-
-static int register_pdev_destroy_handler(void)
-{
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
-
-	status = wlan_objmgr_register_pdev_destroy_handler(
-			WLAN_UMAC_COMP_CRYPTO,
-			wlan_crypto_pdev_obj_destroy_handler, NULL);
-	return status;
-}
-
-static int unregister_pdev_create_handler(void)
-{
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
-
-	status = wlan_objmgr_unregister_pdev_create_handler(
-			WLAN_UMAC_COMP_CRYPTO,
-			wlan_crypto_pdev_obj_create_handler,
-			NULL);
-	return status;
-}
-
-static int unregister_pdev_destroy_handler(void)
-{
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
-
-	status = wlan_objmgr_unregister_pdev_destroy_handler(
-			WLAN_UMAC_COMP_CRYPTO,
-			wlan_crypto_pdev_obj_destroy_handler,
-			NULL);
-	return status;
-}
 #else
 static int register_psoc_create_handler(void)
 {
@@ -888,25 +823,6 @@ static int unregister_psoc_destroy_handler(void)
 	return QDF_STATUS_SUCCESS;
 }
 
-static int register_pdev_create_handler(void)
-{
-	return QDF_STATUS_SUCCESS;
-}
-
-static int register_pdev_destroy_handler(void)
-{
-	return QDF_STATUS_SUCCESS;
-}
-
-static int unregister_pdev_create_handler(void)
-{
-	return QDF_STATUS_SUCCESS;
-}
-
-static int unregister_pdev_destroy_handler(void)
-{
-	return QDF_STATUS_SUCCESS;
-}
 #endif
 
 QDF_STATUS __wlan_crypto_init(void)
@@ -922,12 +838,6 @@ QDF_STATUS __wlan_crypto_init(void)
 		return status;
 	}
 
-	status = register_pdev_create_handler();
-	if (QDF_IS_STATUS_ERROR(status)) {
-		crypto_err("pdev creation failure");
-		goto err_pdev_create;
-	}
-
 	status = wlan_objmgr_register_vdev_create_handler(
 				WLAN_UMAC_COMP_CRYPTO,
 				wlan_crypto_vdev_obj_create_handler, NULL);
@@ -946,12 +856,6 @@ QDF_STATUS __wlan_crypto_init(void)
 		goto err_psoc_delete;
 	}
 
-	status = register_pdev_destroy_handler();
-	if (QDF_IS_STATUS_ERROR(status)) {
-		crypto_err("pdev destroy failure");
-		goto err_pdev_destroy;
-	}
-
 	status = wlan_objmgr_register_vdev_destroy_handler(
 				WLAN_UMAC_COMP_CRYPTO,
 				wlan_crypto_vdev_obj_destroy_handler, NULL);
@@ -969,8 +873,6 @@ err_peer_delete:
 	wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_CRYPTO,
 			wlan_crypto_vdev_obj_destroy_handler, NULL);
 err_vdev_delete:
-	unregister_pdev_destroy_handler();
-err_pdev_destroy:
 	unregister_psoc_destroy_handler();
 err_psoc_delete:
 	wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_CRYPTO,
@@ -979,8 +881,6 @@ err_peer_create:
 	wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_CRYPTO,
 			wlan_crypto_vdev_obj_create_handler, NULL);
 err_vdev_create:
-	unregister_pdev_create_handler();
-err_pdev_create:
 	unregister_psoc_create_handler();
 register_success:
 	return status;
@@ -988,17 +888,11 @@ register_success:
 
 QDF_STATUS __wlan_crypto_deinit(void)
 {
-
 	if (unregister_psoc_create_handler()
 			!= QDF_STATUS_SUCCESS) {
 		return QDF_STATUS_E_FAILURE;
 	}
 
-	if (unregister_pdev_create_handler()
-			!= QDF_STATUS_SUCCESS) {
-		return QDF_STATUS_E_FAILURE;
-	}
-
 	if (wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_CRYPTO,
 			wlan_crypto_vdev_obj_create_handler, NULL)
 			!= QDF_STATUS_SUCCESS) {
@@ -1023,11 +917,6 @@ QDF_STATUS __wlan_crypto_deinit(void)
 		return QDF_STATUS_E_FAILURE;
 	}
 
-	if (unregister_pdev_destroy_handler()
-			!= QDF_STATUS_SUCCESS) {
-		return QDF_STATUS_E_FAILURE;
-	}
-
 	if (unregister_psoc_destroy_handler()
 			!= QDF_STATUS_SUCCESS) {
 		return QDF_STATUS_E_FAILURE;

+ 14 - 0
umac/cmn_services/crypto/src/wlan_crypto_ucfg_api.c

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -24,6 +25,8 @@
 #include <wlan_crypto_global_def.h>
 #include <wlan_objmgr_vdev_obj.h>
 #include <wlan_crypto_global_api.h>
+#include "wlan_crypto_def_i.h"
+
 QDF_STATUS ucfg_crypto_set_key_req(struct wlan_objmgr_vdev *vdev,
 				   struct wlan_crypto_key *req,
 				   enum wlan_crypto_key_type key_type)
@@ -41,3 +44,14 @@ QDF_STATUS ucfg_crypto_set_key_req(struct wlan_objmgr_vdev *vdev,
 	return wlan_crypto_set_key_req(vdev, req, key_type);
 }
 
+void ucfg_crypto_flush_entries(struct wlan_objmgr_psoc *psoc)
+{
+	crypto_flush_entries(psoc);
+}
+
+void ucfg_crypto_free_key_by_link_id(struct wlan_objmgr_psoc *psoc,
+				     struct qdf_mac_addr *link_addr,
+				     uint8_t link_id)
+{
+	wlan_crypto_free_key_by_link_id(psoc, link_addr, link_id);
+}