浏览代码

qcacmn: Add callback api to send stored keys

For STA MLO connection, the AP can send M1 right after assoc
response on assoc link, which will trigger sending keys to FW
for mlo links, but it can happen that wmi_peer_assoc is not
sent for mlo link until this time.
Current code does not have handling for this case.

To solve this, store the link vdev keys and send them once
link vdev is connected.

Change-Id: I882da96280711ca9cfa4d6ba852fda4a8b6d7a77
CRs-Fixed: 3293692
Amruta Kulkarni 2 年之前
父节点
当前提交
319456fee7

+ 1 - 0
os_if/linux/crypto/src/wlan_cfg80211_crypto.c

@@ -50,6 +50,7 @@ void wlan_cfg80211_translate_key(struct wlan_objmgr_vdev *vdev,
 	qdf_mem_copy(&crypto_key->keyval[0], params->key, params->key_len);
 	qdf_mem_copy(&crypto_key->keyval[0], params->key, params->key_len);
 	qdf_mem_copy(&crypto_key->keyrsc[0], params->seq, params->seq_len);
 	qdf_mem_copy(&crypto_key->keyrsc[0], params->seq, params->seq_len);
 
 
+	crypto_key->key_type = key_type;
 	crypto_key->cipher_type = osif_nl_to_crypto_cipher_type(params->cipher);
 	crypto_key->cipher_type = osif_nl_to_crypto_cipher_type(params->cipher);
 	if (IS_WEP_CIPHER(crypto_key->cipher_type) && !mac_addr) {
 	if (IS_WEP_CIPHER(crypto_key->cipher_type) && !mac_addr) {
 		/*
 		/*

+ 35 - 0
os_if/linux/mlme/inc/osif_cm_util.h

@@ -245,6 +245,21 @@ typedef QDF_STATUS
 typedef QDF_STATUS
 typedef QDF_STATUS
 	(*os_if_cm_napi_serialize_ctrl_cb)(bool action);
 	(*os_if_cm_napi_serialize_ctrl_cb)(bool action);
 
 
+/**
+ * typedef osif_cm_send_vdev_keys_cb  - send vdev keys cb
+ * @vdev: vdev pointer
+ * @key_index: key index value
+ * @pairwise: pairwise boolean value
+ * @cipher_type: cipher type enum value
+ *
+ * return: none
+ */
+typedef QDF_STATUS
+(*osif_cm_send_vdev_keys_cb)(struct wlan_objmgr_vdev *vdev,
+			     uint8_t key_index,
+			     bool pairwise,
+			     enum wlan_crypto_cipher_type cipher_type);
+
 /**
 /**
  * osif_cm_unlink_bss() - function to unlink bss from kernel and scan database
  * osif_cm_unlink_bss() - function to unlink bss from kernel and scan database
  * on connect timeouts reasons
  * on connect timeouts reasons
@@ -316,6 +331,7 @@ typedef QDF_STATUS
  * @os_if_cm_napi_serialize_ctrl_cb: callback to legacy module to take
  * @os_if_cm_napi_serialize_ctrl_cb: callback to legacy module to take
  * actions on napi serialization
  * actions on napi serialization
  * @save_gtk_cb : callback to legacy module to save gtk
  * @save_gtk_cb : callback to legacy module to save gtk
+ * @send_vdev_keys_cb: callback to send vdev keys
  * @set_hlp_data_cb: callback to legacy module to save hlp data
  * @set_hlp_data_cb: callback to legacy module to save hlp data
  * @ft_preauth_complete_cb: callback to legacy module to send fast
  * @ft_preauth_complete_cb: callback to legacy module to send fast
  * transition event
  * transition event
@@ -331,6 +347,7 @@ struct osif_cm_ops {
 	osif_cm_netif_queue_ctrl_cb netif_queue_control_cb;
 	osif_cm_netif_queue_ctrl_cb netif_queue_control_cb;
 	os_if_cm_napi_serialize_ctrl_cb napi_serialize_control_cb;
 	os_if_cm_napi_serialize_ctrl_cb napi_serialize_control_cb;
 	osif_cm_save_gtk_cb save_gtk_cb;
 	osif_cm_save_gtk_cb save_gtk_cb;
+	osif_cm_send_vdev_keys_cb send_vdev_keys_cb;
 #endif
 #endif
 #ifdef WLAN_FEATURE_FILS_SK
 #ifdef WLAN_FEATURE_FILS_SK
 	osif_cm_set_hlp_data_cb set_hlp_data_cb;
 	osif_cm_set_hlp_data_cb set_hlp_data_cb;
@@ -432,6 +449,24 @@ QDF_STATUS osif_cm_napi_serialize(bool action);
  */
  */
 QDF_STATUS osif_cm_save_gtk(struct wlan_objmgr_vdev *vdev,
 QDF_STATUS osif_cm_save_gtk(struct wlan_objmgr_vdev *vdev,
 			    struct wlan_cm_connect_resp *rsp);
 			    struct wlan_cm_connect_resp *rsp);
+
+/**
+ * osif_cm_send_vdev_keys() - Function to send vdev keys
+ * @vdev: vdev pointer
+ * @key_index: key index value
+ * @pairwise: pairwise bool value
+ * @cipher_type: cipher type value
+ *
+ * This function to send vdev keys
+ *
+ * Context: Any context.
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+osif_cm_send_vdev_keys(struct wlan_objmgr_vdev *vdev,
+		       uint8_t key_index,
+		       bool pairwise,
+		       enum wlan_crypto_cipher_type cipher_type);
 #else
 #else
 static inline QDF_STATUS osif_cm_save_gtk(struct wlan_objmgr_vdev *vdev,
 static inline QDF_STATUS osif_cm_save_gtk(struct wlan_objmgr_vdev *vdev,
 					  struct wlan_cm_connect_resp *rsp)
 					  struct wlan_cm_connect_resp *rsp)

+ 36 - 0
os_if/linux/mlme/src/osif_cm_util.c

@@ -324,6 +324,25 @@ osif_pmksa_candidate_notify_cb(struct wlan_objmgr_vdev *vdev,
 {
 {
 	return osif_pmksa_candidate_notify(vdev, bssid, index, preauth);
 	return osif_pmksa_candidate_notify(vdev, bssid, index, preauth);
 }
 }
+
+/**
+ * osif_cm_send_keys_cb() - Send keys callback
+ * @vdev: vdev pointer
+ *
+ * This callback indicates os_if that
+ * so that os_if can stop all the activity on this connection
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+osif_cm_send_keys_cb(struct wlan_objmgr_vdev *vdev, uint8_t key_index,
+		     bool pairwise, enum wlan_crypto_cipher_type cipher_type)
+{
+	return osif_cm_send_vdev_keys(vdev,
+				       key_index,
+				       pairwise,
+				       cipher_type);
+}
 #else
 #else
 static inline QDF_STATUS
 static inline QDF_STATUS
 osif_cm_disable_netif_queue(struct wlan_objmgr_vdev *vdev)
 osif_cm_disable_netif_queue(struct wlan_objmgr_vdev *vdev)
@@ -468,6 +487,7 @@ static struct mlme_cm_ops cm_ops = {
 #ifdef CONN_MGR_ADV_FEATURE
 #ifdef CONN_MGR_ADV_FEATURE
 	.mlme_cm_roam_sync_cb = osif_cm_roam_sync_cb,
 	.mlme_cm_roam_sync_cb = osif_cm_roam_sync_cb,
 	.mlme_cm_pmksa_candidate_notify_cb = osif_pmksa_candidate_notify_cb,
 	.mlme_cm_pmksa_candidate_notify_cb = osif_pmksa_candidate_notify_cb,
+	.mlme_cm_send_keys_cb = osif_cm_send_keys_cb,
 #endif
 #endif
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 	.mlme_cm_roam_start_cb = osif_cm_roam_start_cb,
 	.mlme_cm_roam_start_cb = osif_cm_roam_start_cb,
@@ -625,6 +645,22 @@ QDF_STATUS osif_cm_save_gtk(struct wlan_objmgr_vdev *vdev,
 
 
 	return ret;
 	return ret;
 }
 }
+
+QDF_STATUS
+osif_cm_send_vdev_keys(struct wlan_objmgr_vdev *vdev,
+		       uint8_t key_index,
+		       bool pairwise,
+		       enum wlan_crypto_cipher_type cipher_type)
+{
+	osif_cm_send_vdev_keys_cb cb = NULL;
+
+	if (osif_cm_legacy_ops)
+		cb = osif_cm_legacy_ops->send_vdev_keys_cb;
+	if (cb)
+		return cb(vdev, key_index, pairwise, cipher_type);
+
+	return QDF_STATUS_E_FAILURE;
+}
 #endif
 #endif
 
 
 #ifdef WLAN_FEATURE_FILS_SK
 #ifdef WLAN_FEATURE_FILS_SK

+ 2 - 0
umac/cmn_services/crypto/inc/wlan_crypto_global_def.h

@@ -409,6 +409,7 @@ typedef enum wlan_crypto_param_type {
  * @flags:          key flags
  * @flags:          key flags
  * @keyix:          key id
  * @keyix:          key id
  * @cipher_type:    cipher type being used for this key
  * @cipher_type:    cipher type being used for this key
+ * @key_type:       unicast or broadcast key
  * @mac_addr:       MAC address of the peer
  * @mac_addr:       MAC address of the peer
  * @src_addr:       Source mac address associated with the key
  * @src_addr:       Source mac address associated with the key
  * @cipher_table:   table which stores cipher related info
  * @cipher_table:   table which stores cipher related info
@@ -431,6 +432,7 @@ struct wlan_crypto_key {
 	uint16_t    flags;
 	uint16_t    flags;
 	uint16_t    keyix;
 	uint16_t    keyix;
 	enum wlan_crypto_cipher_type cipher_type;
 	enum wlan_crypto_cipher_type cipher_type;
+	enum wlan_crypto_key_type key_type;
 	uint8_t     macaddr[QDF_MAC_ADDR_SIZE];
 	uint8_t     macaddr[QDF_MAC_ADDR_SIZE];
 	struct qdf_mac_addr src_addr;
 	struct qdf_mac_addr src_addr;
 	void        *cipher_table;
 	void        *cipher_table;

+ 23 - 0
umac/mlme/include/wlan_mlme_cmn.h

@@ -103,6 +103,9 @@ struct mlme_cm_ops {
 						struct wlan_objmgr_vdev *vdev,
 						struct wlan_objmgr_vdev *vdev,
 						struct qdf_mac_addr *bssid,
 						struct qdf_mac_addr *bssid,
 						int index, bool preauth);
 						int index, bool preauth);
+	QDF_STATUS (*mlme_cm_send_keys_cb)(struct wlan_objmgr_vdev *vdev,
+					   uint8_t key_index, bool pairwise,
+					   enum wlan_crypto_cipher_type cipher_type);
 #endif
 #endif
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 	QDF_STATUS (*mlme_cm_roam_start_cb)(struct wlan_objmgr_vdev *vdev);
 	QDF_STATUS (*mlme_cm_roam_start_cb)(struct wlan_objmgr_vdev *vdev);
@@ -846,12 +849,32 @@ QDF_STATUS mlme_cm_osif_roam_sync_ind(struct wlan_objmgr_vdev *vdev);
 QDF_STATUS mlme_cm_osif_pmksa_candidate_notify(struct wlan_objmgr_vdev *vdev,
 QDF_STATUS mlme_cm_osif_pmksa_candidate_notify(struct wlan_objmgr_vdev *vdev,
 					       struct qdf_mac_addr *bssid,
 					       struct qdf_mac_addr *bssid,
 					       int index, bool preauth);
 					       int index, bool preauth);
+/**
+ * mlme_cm_osif_send_keys() - send vdev keys
+ * @vdev: vdev pointer
+ * @key_index: key index value
+ * @pairwise: pairwise bool value
+ * @ciipher_type: cipher enum value
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS mlme_cm_osif_send_keys(struct wlan_objmgr_vdev *vdev,
+				  uint8_t key_index, bool pairwise,
+				  enum wlan_crypto_cipher_type cipher_type);
 #else
 #else
 static inline
 static inline
 QDF_STATUS mlme_cm_osif_roam_sync_ind(struct wlan_objmgr_vdev *vdev)
 QDF_STATUS mlme_cm_osif_roam_sync_ind(struct wlan_objmgr_vdev *vdev)
 {
 {
 	return QDF_STATUS_SUCCESS;
 	return QDF_STATUS_SUCCESS;
 }
 }
+
+static inline
+QDF_STATUS mlme_cm_osif_send_keys(struct wlan_objmgr_vdev *vdev,
+				  uint8_t key_index, bool pairwise,
+				  enum wlan_crypto_cipher_type cipher_type)
+{
+	return QDF_STATUS_SUCCESS;
+}
 #endif
 #endif
 
 
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD

+ 14 - 0
umac/mlme/mlme_objmgr/dispatcher/src/wlan_cmn_mlme_main.c

@@ -551,6 +551,20 @@ QDF_STATUS mlme_cm_osif_pmksa_candidate_notify(struct wlan_objmgr_vdev *vdev,
 
 
 	return ret;
 	return ret;
 }
 }
+
+QDF_STATUS mlme_cm_osif_send_keys(struct wlan_objmgr_vdev *vdev,
+				  uint8_t key_index, bool pairwise,
+				  enum wlan_crypto_cipher_type cipher_type)
+{
+	QDF_STATUS ret = QDF_STATUS_SUCCESS;
+
+	if (glbl_cm_ops && glbl_cm_ops->mlme_cm_send_keys_cb)
+		ret = glbl_cm_ops->mlme_cm_send_keys_cb(vdev, key_index,
+							pairwise,
+							cipher_type);
+
+	return ret;
+}
 #endif
 #endif
 
 
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD

+ 4 - 4
umac/mlo_mgr/inc/wlan_mlo_mgr_public_structs.h

@@ -181,13 +181,13 @@ struct wlan_ml_vdev_aid_mgr {
 /*
 /*
  * struct wlan_mlo_key_mgmt - MLO key management
  * struct wlan_mlo_key_mgmt - MLO key management
  * @link_mac_address: list of vdevs selected for connection with the MLAP
  * @link_mac_address: list of vdevs selected for connection with the MLAP
- * @ptk: Pairwise transition keys
- * @gtk: Group transition key
+ * @vdev_id: vdev id value
+ * @keys_saved: keys saved bool
  */
  */
 struct wlan_mlo_key_mgmt {
 struct wlan_mlo_key_mgmt {
 	struct qdf_mac_addr link_mac_address;
 	struct qdf_mac_addr link_mac_address;
-	uint32_t ptk;
-	uint32_t gtk;
+	uint8_t vdev_id;
+	bool keys_saved;
 };
 };
 
 
 /**
 /**

+ 44 - 36
umac/mlo_mgr/inc/wlan_mlo_mgr_sta.h

@@ -29,7 +29,6 @@
 
 
 /**
 /**
  * mlo_connect - Start the connection process
  * mlo_connect - Start the connection process
- *
  * @vdev: pointer to vdev
  * @vdev: pointer to vdev
  * @req: connection request
  * @req: connection request
  *
  *
@@ -41,7 +40,6 @@ QDF_STATUS mlo_connect(struct wlan_objmgr_vdev *vdev,
 /**
 /**
  * mlo_sta_link_connect_notify - Called by connection manager to notify the
  * mlo_sta_link_connect_notify - Called by connection manager to notify the
  * STA link connect is complete
  * STA link connect is complete
- *
  * @vdev: pointer to vdev
  * @vdev: pointer to vdev
  * @mlo_ie: MLO information element
  * @mlo_ie: MLO information element
  *
  *
@@ -56,7 +54,6 @@ mlo_sta_link_connect_notify(struct wlan_objmgr_vdev *vdev,
 
 
 /**
 /**
  * mlo_disconnect - Start the disconnection process
  * mlo_disconnect - Start the disconnection process
- *
  * @vdev: pointer to vdev
  * @vdev: pointer to vdev
  * @source: source of the request (can be connect or disconnect request)
  * @source: source of the request (can be connect or disconnect request)
  * @reason_code: reason for disconnect
  * @reason_code: reason for disconnect
@@ -71,7 +68,6 @@ QDF_STATUS mlo_disconnect(struct wlan_objmgr_vdev *vdev,
 
 
 /**
 /**
  * mlo_sync_disconnect - Start the sync disconnection process
  * mlo_sync_disconnect - Start the sync disconnection process
- *
  * @vdev: pointer to vdev
  * @vdev: pointer to vdev
  * @source: source of the request (can be connect or disconnect request)
  * @source: source of the request (can be connect or disconnect request)
  * @reason_code: reason for disconnect
  * @reason_code: reason for disconnect
@@ -86,7 +82,6 @@ QDF_STATUS mlo_sync_disconnect(struct wlan_objmgr_vdev *vdev,
 
 
 /**
 /**
  * mlo_sta_link_disconn_notify - Notifies that STA link disconnect completion
  * mlo_sta_link_disconn_notify - Notifies that STA link disconnect completion
- *
  * @vdev: pointer to vdev
  * @vdev: pointer to vdev
  * @resp: disconnect resp
  * @resp: disconnect resp
  *
  *
@@ -97,7 +92,6 @@ void mlo_sta_link_disconn_notify(struct wlan_objmgr_vdev *vdev,
 
 
 /**
 /**
  * mlo_is_mld_sta - Check if MLD associated with the vdev is a station
  * mlo_is_mld_sta - Check if MLD associated with the vdev is a station
- *
  * @vdev: pointer to vdev
  * @vdev: pointer to vdev
  *
  *
  * Return: true if MLD is a station, false otherwise
  * Return: true if MLD is a station, false otherwise
@@ -106,7 +100,6 @@ bool mlo_is_mld_sta(struct wlan_objmgr_vdev *vdev);
 
 
 /**
 /**
  * ucfg_mlo_is_mld_disconnected - Check whether MLD is disconnected
  * ucfg_mlo_is_mld_disconnected - Check whether MLD is disconnected
- *
  * @vdev: pointer to vdev
  * @vdev: pointer to vdev
  *
  *
  * Return: true if mld is disconnected, false otherwise
  * Return: true if mld is disconnected, false otherwise
@@ -116,7 +109,6 @@ bool ucfg_mlo_is_mld_disconnected(struct wlan_objmgr_vdev *vdev);
 #ifndef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
 #ifndef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
 /**
 /**
  * ucfg_mlo_is_mld_connected - Check whether MLD is connected
  * ucfg_mlo_is_mld_connected - Check whether MLD is connected
- *
  * @vdev: pointer to vdev
  * @vdev: pointer to vdev
  *
  *
  * Return: true if mld is connected, false otherwise
  * Return: true if mld is connected, false otherwise
@@ -125,7 +117,6 @@ bool ucfg_mlo_is_mld_connected(struct wlan_objmgr_vdev *vdev);
 
 
 /**
 /**
  * ucfg_mlo_mld_clear_mlo_cap - Clear MLO cap for all vdevs in MLD
  * ucfg_mlo_mld_clear_mlo_cap - Clear MLO cap for all vdevs in MLD
- *
  * @vdev: pointer to vdev
  * @vdev: pointer to vdev
  *
  *
  * Return: None
  * Return: None
@@ -133,9 +124,8 @@ bool ucfg_mlo_is_mld_connected(struct wlan_objmgr_vdev *vdev);
 void ucfg_mlo_mld_clear_mlo_cap(struct wlan_objmgr_vdev *vdev);
 void ucfg_mlo_mld_clear_mlo_cap(struct wlan_objmgr_vdev *vdev);
 #endif
 #endif
 
 
-/*
+/**
  * ucfg_mlo_get_assoc_link_vdev - API to get assoc link vdev
  * ucfg_mlo_get_assoc_link_vdev - API to get assoc link vdev
- *
  * @mlo_dev_ctx: mlo dev ctx
  * @mlo_dev_ctx: mlo dev ctx
  *
  *
  * Return: MLD assoc link vdev
  * Return: MLD assoc link vdev
@@ -143,9 +133,8 @@ void ucfg_mlo_mld_clear_mlo_cap(struct wlan_objmgr_vdev *vdev);
 struct wlan_objmgr_vdev *
 struct wlan_objmgr_vdev *
 ucfg_mlo_get_assoc_link_vdev(struct wlan_objmgr_vdev *vdev);
 ucfg_mlo_get_assoc_link_vdev(struct wlan_objmgr_vdev *vdev);
 
 
-/*
+/**
  * wlan_mlo_get_assoc_link_vdev - API to get assoc link vdev
  * wlan_mlo_get_assoc_link_vdev - API to get assoc link vdev
- *
  * @mlo_dev_ctx: mlo dev ctx
  * @mlo_dev_ctx: mlo dev ctx
  *
  *
  * Return: MLD assoc link vdev
  * Return: MLD assoc link vdev
@@ -153,9 +142,8 @@ ucfg_mlo_get_assoc_link_vdev(struct wlan_objmgr_vdev *vdev);
 struct wlan_objmgr_vdev *
 struct wlan_objmgr_vdev *
 wlan_mlo_get_assoc_link_vdev(struct wlan_objmgr_vdev *vdev);
 wlan_mlo_get_assoc_link_vdev(struct wlan_objmgr_vdev *vdev);
 
 
-/*
+/**
  * mlo_update_connected_links_bmap: update connected links bitmap
  * mlo_update_connected_links_bmap: update connected links bitmap
- *
  * @mlo_dev_ctx: mlo dev context ptr
  * @mlo_dev_ctx: mlo dev context ptr
  * @ml_partner_info: ml parnter info ptr
  * @ml_partner_info: ml parnter info ptr
  *
  *
@@ -165,15 +153,14 @@ void
 mlo_update_connected_links_bmap(struct wlan_mlo_dev_context *mlo_dev_ctx,
 mlo_update_connected_links_bmap(struct wlan_mlo_dev_context *mlo_dev_ctx,
 				struct mlo_partner_info ml_parnter_info);
 				struct mlo_partner_info ml_parnter_info);
 
 
-/*
+/**
  * API to have operation on ml vdevs
  * API to have operation on ml vdevs
  */
  */
 typedef void (*mlo_vdev_op_handler)(struct wlan_objmgr_vdev *vdev,
 typedef void (*mlo_vdev_op_handler)(struct wlan_objmgr_vdev *vdev,
 				    void *arg);
 				    void *arg);
 
 
-/*
+/**
  * mlo_iterate_connected_vdev_list: Iterate on connected ML links
  * mlo_iterate_connected_vdev_list: Iterate on connected ML links
- *
  * @vdev: vdev object
  * @vdev: vdev object
  * @handler: the handler will be called for each object in ML list
  * @handler: the handler will be called for each object in ML list
  * @arg: argument to be passed to handler
  * @arg: argument to be passed to handler
@@ -206,7 +193,7 @@ void mlo_iterate_connected_vdev_list(struct wlan_objmgr_vdev *vdev,
 	}
 	}
 }
 }
 
 
-/*
+/**
  * call_handler_for_standalone_ap: Iterate on all standalone ML vdevs in
  * call_handler_for_standalone_ap: Iterate on all standalone ML vdevs in
  * ML AP context and call handler only for standalone AP
  * ML AP context and call handler only for standalone AP
  *
  *
@@ -296,9 +283,8 @@ void mlo_iterate_ml_standalone_vdev_list(struct wlan_objmgr_vdev *vdev,
 	}
 	}
 }
 }
 
 
-/*
+/**
  * mlo_update_connect_req_links: update connect req links index
  * mlo_update_connect_req_links: update connect req links index
- *
  * @vdev: vdev object
  * @vdev: vdev object
  * @value: set/clear the bit
  * @value: set/clear the bit
  *
  *
@@ -332,9 +318,8 @@ mlo_update_connect_req_links(struct wlan_objmgr_vdev *vdev, uint8_t value)
 	}
 	}
 }
 }
 
 
-/*
+/**
  * mlo_is_vdev_connect_req_link: API to check if vdev is in active connection
  * mlo_is_vdev_connect_req_link: API to check if vdev is in active connection
- *
  * @vdev: vdev object
  * @vdev: vdev object
  *
  *
  * Return: true is vdev is participating in active connect else false
  * Return: true is vdev is participating in active connect else false
@@ -360,9 +345,8 @@ mlo_is_vdev_connect_req_link(struct wlan_objmgr_vdev *vdev)
 	return false;
 	return false;
 }
 }
 
 
-/*
+/**
  * mlo_clear_connect_req_links: clear connect req links bitmap
  * mlo_clear_connect_req_links: clear connect req links bitmap
- *
  * @vdev: vdev object
  * @vdev: vdev object
  *
  *
  * Return: none
  * Return: none
@@ -384,9 +368,8 @@ void mlo_clear_connect_req_links_bmap(struct wlan_objmgr_vdev *vdev)
 		     sizeof(sta_ctx->wlan_connect_req_links));
 		     sizeof(sta_ctx->wlan_connect_req_links));
 }
 }
 
 
-/*
+/**
  * mlo_update_connected_links: update connected links index
  * mlo_update_connected_links: update connected links index
- *
  * @vdev: vdev object
  * @vdev: vdev object
  * @value: set/clear the bit
  * @value: set/clear the bit
  *
  *
@@ -419,9 +402,8 @@ mlo_update_connected_links(struct wlan_objmgr_vdev *vdev, uint8_t value)
 	}
 	}
 }
 }
 
 
-/*
+/**
  * mlo_clear_connected_links: clear connected links bitmap
  * mlo_clear_connected_links: clear connected links bitmap
- *
  * @vdev: vdev object
  * @vdev: vdev object
  *
  *
  * Return: none
  * Return: none
@@ -445,9 +427,8 @@ void mlo_clear_connected_links_bmap(struct wlan_objmgr_vdev *vdev)
 }
 }
 
 
 #ifndef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
 #ifndef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
-/*
+/**
  * mlo_get_ml_vdev_by_mac: get ml vdev from mac
  * mlo_get_ml_vdev_by_mac: get ml vdev from mac
- *
  * @vdev: vdev object
  * @vdev: vdev object
  * @macaddr: mac of vdev to be returned
  * @macaddr: mac of vdev to be returned
  *
  *
@@ -458,9 +439,26 @@ mlo_get_ml_vdev_by_mac(struct wlan_objmgr_vdev *vdev,
 		       struct qdf_mac_addr *macaddr);
 		       struct qdf_mac_addr *macaddr);
 #endif
 #endif
 
 
-/*
+/**
+ * mlo_set_keys_saved: set mlo keys saved bool for vdev
+ * @vdev: vdev object
+ * @mac_address: peer mac address
+ * @value: bool true or false
+ * Return: none
+ */
+void mlo_set_keys_saved(struct wlan_objmgr_vdev *vdev,
+			struct qdf_mac_addr *mac_address, bool value);
+
+/**
+ * mlo_get_keys_saved: get if mlo keys are saved for vdev
+ * @vdev: vdev object
+ * @mac_address: peer mac address
+ * Return: boolean value true or false
+ */
+bool mlo_get_keys_saved(struct wlan_objmgr_vdev *vdev, uint8_t *mac_address);
+
+/**
  * mlo_get_chan_freq_by_bssid - Get channel freq by bssid
  * mlo_get_chan_freq_by_bssid - Get channel freq by bssid
- *
  * @pdev: pdev pointer
  * @pdev: pdev pointer
  * @bssid: link mac address
  * @bssid: link mac address
  *
  *
@@ -472,7 +470,6 @@ mlo_get_chan_freq_by_bssid(struct wlan_objmgr_pdev *pdev,
 
 
 /**
 /**
  * mlo_get_assoc_rsp - Get Assoc response from mlo manager
  * mlo_get_assoc_rsp - Get Assoc response from mlo manager
- *
  * @vdev: vdev obj mgr
  * @vdev: vdev obj mgr
  * @assoc_rsp_frame: association response frame ptr
  * @assoc_rsp_frame: association response frame ptr
  *
  *
@@ -524,7 +521,6 @@ bool mlo_is_sta_inactivity_allowed_with_quiet(struct wlan_objmgr_psoc *psoc,
 
 
 /**
 /**
  * mlo_is_sta_csa_synced - Is mlo sta csa parameters are synced or not
  * mlo_is_sta_csa_synced - Is mlo sta csa parameters are synced or not
- *
  * @mlo_dev_ctx: mlo context
  * @mlo_dev_ctx: mlo context
  * @link_id: link id
  * @link_id: link id
  *
  *
@@ -565,7 +561,6 @@ bool mlo_is_sta_csa_param_handled(struct wlan_objmgr_vdev *vdev,
 
 
 /**
 /**
  * mlo_internal_disconnect_links - Internal disconnect for connection manager
  * mlo_internal_disconnect_links - Internal disconnect for connection manager
- *
  * @vdev: vdev obj mgr
  * @vdev: vdev obj mgr
  *
  *
  * Return: none
  * Return: none
@@ -715,5 +710,18 @@ void mlo_sta_get_vdev_list(struct wlan_objmgr_vdev *vdev,
 			   struct wlan_objmgr_vdev **wlan_vdev_list)
 			   struct wlan_objmgr_vdev **wlan_vdev_list)
 {
 {
 }
 }
+
+static inline
+void mlo_set_keys_saved(struct wlan_objmgr_vdev *vdev,
+			struct qdf_mac_addr *mac_address, bool value)
+{
+}
+
+static inline
+bool mlo_get_keys_saved(struct wlan_objmgr_vdev *vdev,
+			uint8_t *mac_address)
+{
+	return false;
+}
 #endif
 #endif
 #endif
 #endif

+ 37 - 0
umac/mlo_mgr/src/wlan_mlo_mgr_sta.c

@@ -1790,4 +1790,41 @@ void mlo_sta_get_vdev_list(struct wlan_objmgr_vdev *vdev, uint16_t *vdev_count,
 	mlo_dev_lock_release(dev_ctx);
 	mlo_dev_lock_release(dev_ctx);
 }
 }
 
 
+void mlo_set_keys_saved(struct wlan_objmgr_vdev *vdev,
+			struct qdf_mac_addr *mac_address, bool value)
+{
+	struct wlan_mlo_sta *sta_ctx;
+
+	if (!vdev || !vdev->mlo_dev_ctx)
+		return;
+
+	sta_ctx = vdev->mlo_dev_ctx->sta_ctx;
+	if (!sta_ctx)
+		return;
+
+	sta_ctx->key_mgmt[0].vdev_id = wlan_vdev_get_id(vdev);
+	sta_ctx->key_mgmt[0].keys_saved = value;
+	qdf_copy_macaddr(&sta_ctx->key_mgmt[0].link_mac_address,
+			 mac_address);
+}
+
+bool mlo_get_keys_saved(struct wlan_objmgr_vdev *vdev,
+			uint8_t *mac_address)
+{
+	struct wlan_mlo_sta *sta_ctx;
+
+	if (!vdev || !vdev->mlo_dev_ctx)
+		return false;
+
+	sta_ctx = vdev->mlo_dev_ctx->sta_ctx;
+	if (!sta_ctx)
+		return false;
+
+	if ((qdf_is_macaddr_equal(&sta_ctx->key_mgmt[0].link_mac_address,
+				  (struct qdf_mac_addr *)mac_address)) &&
+	     (wlan_vdev_get_id(vdev) == sta_ctx->key_mgmt[0].vdev_id))
+		return sta_ctx->key_mgmt[0].keys_saved;
+
+	return false;
+}
 #endif
 #endif