Browse Source

qcacmn: Add support for Auth defer framework

This change adds framework for deferring auth request
while link peers are in the process of deletion

Change-Id: Ic96daf7d994c65b10e15f72e4a676b8156573cf2
CRs-Fixed: 3113557
Srinivas Pitla 3 years ago
parent
commit
3ceae2fe28

+ 15 - 0
umac/mlo_mgr/inc/wlan_mlo_mgr_cmn.h

@@ -238,6 +238,21 @@ qdf_nbuf_t mlo_mlme_get_link_assoc_req(struct wlan_objmgr_peer *peer,
  */
 void mlo_mlme_peer_deauth(struct wlan_objmgr_peer *peer);
 
+#ifdef UMAC_MLO_AUTH_DEFER
+/**
+ * mlo_mlme_peer_process_auth() - Process deferred auth request
+ * @auth_params: deferred auth params
+ *
+ * Return: void
+ */
+void mlo_mlme_peer_process_auth(struct mlpeer_auth_params *auth_param);
+#else
+static inline void
+mlo_mlme_peer_process_auth(struct mlpeer_auth_params *auth_param)
+{
+}
+#endif
+
 /**
  * mlo_get_link_vdev_ix() - Get index of link VDEV in MLD
  * @ml_dev: ML device context

+ 13 - 1
umac/mlo_mgr/inc/wlan_mlo_mgr_msgq.h

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022 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 above
@@ -46,6 +46,7 @@ struct ctxt_switch_mgr {
  * @MLO_PEER_ASSOC_FAIL:  Partner peer ASSOC failure
  * @MLO_PEER_DISCONNECT:  Partner peer Disconnect
  * @MLO_PEER_DEAUTH:  Initiate Deauth for ML connection
+ * @MLO_PEER_PENDING_AUTH:  Initiate process of pending auth
  */
 enum mlo_msg_type {
 	MLO_PEER_CREATE,
@@ -53,6 +54,7 @@ enum mlo_msg_type {
 	MLO_PEER_ASSOC_FAIL,
 	MLO_PEER_DISCONNECT,
 	MLO_PEER_DEAUTH,
+	MLO_PEER_PENDING_AUTH,
 };
 
 /*
@@ -101,6 +103,14 @@ struct peer_deauth_notify_s {
 	struct wlan_objmgr_peer *peer;
 };
 
+/*
+ * struct peer_auth_process_notif_s - MLO peer pending auth notification
+ * @auth_params: Auth param structure
+ */
+struct peer_auth_process_notif_s {
+	struct mlpeer_auth_params *auth_params;
+};
+
 /*
  * union msg_payload - MLO message payload
  * @peer_create: peer create notification structure
@@ -108,6 +118,7 @@ struct peer_deauth_notify_s {
  * @peer_assoc_fail: peer assoc fail notification structure
  * @peer_disconn: peer disconnect notification structure
  * @peer_deauth: peer deauth notification structure
+ * @peer_auth_process: Peer Auth process notification structure
  */
 union msg_payload {
 	struct peer_create_notif_s peer_create;
@@ -115,6 +126,7 @@ union msg_payload {
 	struct peer_assoc_fail_notify_s peer_assoc_fail;
 	struct peer_discon_notify_s peer_disconn;
 	struct peer_deauth_notify_s peer_deauth;
+	struct peer_auth_process_notif_s peer_auth;
 };
 
 #define MLO_MAX_MSGQ_SIZE 256

+ 34 - 2
umac/mlo_mgr/inc/wlan_mlo_mgr_peer.h

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022 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 above
@@ -335,7 +335,8 @@ void wlan_mlo_peer_free_all_link_assoc_resp_buf(struct wlan_objmgr_peer *peer);
  * @peer: Link peer
  * @ml_links: structure to be filled with partner link info
  *
- * This function retrieves partner link info of link peer
+ * This function retrieves partner link info of link peer such as hw link id,
+ * vdev id
  *
  * Return: void
  */
@@ -534,4 +535,35 @@ bool wlan_mlo_peer_is_nawds(struct wlan_mlo_peer_context *ml_peer)
 	return false;
 }
 #endif
+#ifdef UMAC_MLO_AUTH_DEFER
+/**
+ * mlo_peer_link_auth_defer() - Auth request defer for MLO peer
+ * @ml_peer: ML peer
+ * @link_mac:  Link peer MAC address
+ * @auth_params: Defer Auth param
+ *
+ * This function saves Auth request params in MLO peer
+ *
+ * Return: SUCCESS if MAC address matches one of the link peers
+ *         FAILURE, if MAC address doesn't match
+ */
+QDF_STATUS mlo_peer_link_auth_defer(struct wlan_mlo_peer_context *ml_peer,
+				    struct qdf_mac_addr *link_mac,
+				    struct mlpeer_auth_params *auth_params);
+
+/**
+ * mlo_peer_free_auth_param() - Free deferred Auth request params
+ * @auth_params: Defer Auth param
+ *
+ * This function frees Auth request params
+ *
+ * Return: void
+ */
+void mlo_peer_free_auth_param(struct mlpeer_auth_params *auth_params);
+#else
+static inline void
+mlo_peer_free_auth_param(struct mlpeer_auth_params *auth_params)
+{
+}
+#endif
 #endif

+ 35 - 0
umac/mlo_mgr/inc/wlan_mlo_mgr_public_structs.h

@@ -304,6 +304,32 @@ struct mlnawds_config {
 };
 #endif
 
+/*
+ * struct mlpeer_auth_params - Deferred Auth params
+ * @vdev_id:  VDEV ID
+ * @psoc_id:  PSOC ID
+ * @link_addr: MAC address
+ * @algo:  Auth algorithm
+ * @seq: Auth sequence number
+ * @status_code: Auth status
+ * @challenge: Auth Challenge
+ * @challenge_length: Auth Challenge length
+ * @wbuf:  Auth wbuf
+ * @rs: Rx stats
+ */
+struct mlpeer_auth_params {
+	uint8_t vdev_id;
+	uint8_t psoc_id;
+	struct qdf_mac_addr link_addr;
+	uint16_t algo;
+	uint16_t seq;
+	uint16_t status_code;
+	uint8_t *challenge;
+	uint8_t challenge_length;
+	qdf_nbuf_t wbuf;
+	void *rs;
+};
+
 /*
  * struct wlan_mlo_peer_context - MLO peer context
  *
@@ -322,6 +348,7 @@ struct mlnawds_config {
  * @avg_link_rssi: avg RSSI of ML peer
  * @is_nawds_ml_peer: flag to indicate if ml_peer is NAWDS configured
  * @nawds_config: eack link peer's NAWDS configuration
+ * @pending_auth: Holds pending auth request
  */
 struct wlan_mlo_peer_context {
 	qdf_list_node_t peer_node;
@@ -346,6 +373,9 @@ struct wlan_mlo_peer_context {
 	bool is_nawds_ml_peer;
 	struct mlnawds_config nawds_config[MAX_MLO_LINK_PEERS];
 #endif
+#ifdef UMAC_MLO_AUTH_DEFER
+	struct mlpeer_auth_params *pending_auth[MAX_MLO_LINK_PEERS];
+#endif
 };
 
 /*
@@ -406,6 +436,7 @@ struct mlo_tgt_partner_info {
  * @mlo_mlme_get_link_assoc_req: Calback to get link assoc req buffer
  * @mlo_mlme_ext_deauth: Callback to initiate deauth
  * @mlo_mlme_ext_clone_security_param: Callback to clone mlo security params
+ * @mlo_mlme_ext_peer_process_auth: Callback to process pending auth
  */
 struct mlo_mlme_ext_ops {
 	QDF_STATUS (*mlo_mlme_ext_validate_conn_req)(
@@ -426,6 +457,10 @@ struct mlo_mlme_ext_ops {
 	QDF_STATUS (*mlo_mlme_ext_clone_security_param)(
 		    struct vdev_mlme_obj *vdev_mlme,
 		    struct wlan_cm_connect_req *req);
+#ifdef UMAC_MLO_AUTH_DEFER
+	void (*mlo_mlme_ext_peer_process_auth)(
+	      struct mlpeer_auth_params *auth_param);
+#endif
 };
 
 /* maximum size of vdev bitmap array for MLO link set active command */

+ 7 - 1
umac/mlo_mgr/src/wlan_mlo_mgr_ap.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022 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 above
@@ -315,6 +315,12 @@ void mlo_ap_ml_peerid_free(uint16_t mlo_peer_id)
 	if (mlo_peer_id == MLO_INVALID_PEER_ID)
 		return;
 
+	if (mlo_peer_id > mlo_ctx->max_mlo_peer_id) {
+		mlo_err(" ML peee id %d is invalid", mlo_peer_id);
+		QDF_BUG(0);
+		return;
+	}
+
 	ml_peerid_lock_acquire(mlo_ctx);
 	if (qdf_test_bit(mlo_peer_id - 1, mlo_ctx->mlo_peer_id_bmap))
 		qdf_clear_bit(mlo_peer_id - 1, mlo_ctx->mlo_peer_id_bmap);

+ 14 - 1
umac/mlo_mgr/src/wlan_mlo_mgr_cmn.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022 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 above
@@ -245,6 +245,19 @@ void mlo_mlme_peer_deauth(struct wlan_objmgr_peer *peer)
 	mlo_ctx->mlme_ops->mlo_mlme_ext_deauth(peer);
 }
 
+#ifdef UMAC_MLO_AUTH_DEFER
+void mlo_mlme_peer_process_auth(struct mlpeer_auth_params *auth_param)
+{
+	struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx();
+
+	if (!mlo_ctx || !mlo_ctx->mlme_ops ||
+	    !mlo_ctx->mlme_ops->mlo_mlme_ext_peer_process_auth)
+		return;
+
+	mlo_ctx->mlme_ops->mlo_mlme_ext_peer_process_auth(auth_param);
+}
+#endif
+
 uint8_t mlo_get_link_vdev_ix(struct wlan_mlo_dev_context *ml_dev,
 			     struct wlan_objmgr_vdev *vdev)
 {

+ 25 - 1
umac/mlo_mgr/src/wlan_mlo_mgr_msgq.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022 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 above
@@ -31,6 +31,7 @@ QDF_STATUS mlo_msgq_post(enum mlo_msg_type type,
 	struct peer_assoc_fail_notify_s *peer_assoc_fail;
 	struct peer_discon_notify_s *peer_disconn;
 	struct peer_deauth_notify_s *peer_deauth;
+	struct peer_auth_process_notif_s *peer_auth;
 
 	switch (type) {
 	case MLO_PEER_CREATE:
@@ -73,6 +74,11 @@ QDF_STATUS mlo_msgq_post(enum mlo_msg_type type,
 					     WLAN_MLO_MGR_ID);
 		break;
 
+	case MLO_PEER_PENDING_AUTH:
+		peer_auth = (struct peer_auth_process_notif_s *)payload;
+		mlo_mlme_peer_process_auth(peer_auth->auth_params);
+		break;
+
 	default:
 		break;
 	}
@@ -137,6 +143,7 @@ QDF_STATUS mlo_msgq_post(enum mlo_msg_type type,
 	struct peer_assoc_fail_notify_s *peer_assoc_fail, *peer_assoc_fail_l;
 	struct peer_discon_notify_s *peer_disconn, *peer_disconn_l;
 	struct peer_deauth_notify_s *peer_deauth, *peer_deauth_l;
+	struct peer_auth_process_notif_s *peer_auth, *peer_auth_l;
 	struct ctxt_switch_mgr *msgq_ctx;
 	struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx();
 
@@ -189,6 +196,12 @@ QDF_STATUS mlo_msgq_post(enum mlo_msg_type type,
 		peer_deauth->peer = peer_deauth_l->peer;
 		break;
 
+	case MLO_PEER_PENDING_AUTH:
+		peer_auth = &msg->m.peer_auth;
+		peer_auth_l = (struct peer_auth_process_notif_s *)payload;
+		peer_auth->auth_params = peer_auth_l->auth_params;
+		break;
+
 	default:
 		break;
 	}
@@ -209,6 +222,7 @@ static void mlo_msgq_msg_process_hdlr(struct mlo_ctxt_switch_msg_s *msg)
 	struct peer_assoc_fail_notify_s *peer_assoc_fail;
 	struct peer_discon_notify_s *peer_disconn;
 	struct peer_deauth_notify_s *peer_deauth;
+	struct peer_auth_process_notif_s *peer_auth;
 
 	type = msg->type;
 	switch (type) {
@@ -251,6 +265,11 @@ static void mlo_msgq_msg_process_hdlr(struct mlo_ctxt_switch_msg_s *msg)
 					     WLAN_MLO_MGR_ID);
 		break;
 
+	case MLO_PEER_PENDING_AUTH:
+		peer_auth = &msg->m.peer_auth;
+		mlo_mlme_peer_process_auth(peer_auth->auth_params);
+		break;
+
 	default:
 		break;
 	}
@@ -300,6 +319,11 @@ static void mlo_msgq_msg_flush_hdlr(struct mlo_ctxt_switch_msg_s *msg)
 					     WLAN_MLO_MGR_ID);
 		break;
 
+	case MLO_PEER_PENDING_AUTH:
+		peer_auth = &msg->m.peer_auth;
+		mlo_peer_free_auth_param(peer_auth->auth_params);
+		break;
+
 	default:
 		break;
 	}

+ 94 - 1
umac/mlo_mgr/src/wlan_mlo_mgr_peer.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022 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 above
@@ -131,6 +131,40 @@ static void mlo_link_peer_deauth_init(struct wlan_mlo_dev_context *ml_dev,
 		wlan_objmgr_peer_release_ref(peer, WLAN_MLO_MGR_ID);
 }
 
+#ifdef UMAC_MLO_AUTH_DEFER
+static void mlo_peer_process_pending_auth(struct wlan_mlo_dev_context *ml_dev,
+					  struct wlan_mlo_peer_context *ml_peer)
+{
+	struct peer_auth_process_notif_s peer_auth;
+	struct mlpeer_auth_params *recv_auth;
+	uint8_t i;
+	QDF_STATUS status;
+
+	for (i = 0; i < MAX_MLO_LINK_PEERS; i++) {
+		mlo_peer_lock_acquire(ml_peer);
+		recv_auth = ml_peer->pending_auth[i];
+		if (!recv_auth) {
+			mlo_peer_lock_release(ml_peer);
+			continue;
+		}
+		peer_auth.auth_params = recv_auth;
+		ml_peer->pending_auth[i] = NULL;
+
+		mlo_peer_lock_release(ml_peer);
+
+		status = mlo_msgq_post(MLO_PEER_PENDING_AUTH, ml_dev,
+				       &peer_auth);
+		if (QDF_IS_STATUS_ERROR(status))
+			mlo_peer_free_auth_param(peer_auth.auth_params);
+	}
+}
+#else
+static void mlo_peer_process_pending_auth(struct wlan_mlo_dev_context *ml_dev,
+					  struct wlan_mlo_peer_context *ml_peer)
+{
+}
+#endif
+
 QDF_STATUS
 wlan_mlo_peer_is_disconnect_progress(struct wlan_mlo_peer_context *ml_peer)
 {
@@ -471,6 +505,8 @@ void mlo_peer_cleanup(struct wlan_mlo_peer_context *ml_peer)
 	}
 
 	mlo_dev_mlpeer_detach(ml_dev, ml_peer);
+	/* If any Auth req is received during ML peer delete */
+	mlo_peer_process_pending_auth(ml_dev, ml_peer);
 	mlo_peer_free(ml_peer);
 }
 
@@ -1040,3 +1076,60 @@ bool wlan_mlo_peer_is_nawds(struct wlan_mlo_peer_context *ml_peer)
 
 qdf_export_symbol(wlan_mlo_peer_is_nawds);
 #endif
+
+#ifdef UMAC_MLO_AUTH_DEFER
+void mlo_peer_free_auth_param(struct mlpeer_auth_params *auth_params)
+{
+	if (auth_params->rs)
+		qdf_mem_free(auth_params->rs);
+
+	if (auth_params->wbuf)
+		qdf_nbuf_free(auth_params->wbuf);
+
+	qdf_mem_free(auth_params);
+}
+
+QDF_STATUS mlo_peer_link_auth_defer(struct wlan_mlo_peer_context *ml_peer,
+				    struct qdf_mac_addr *link_mac,
+				    struct mlpeer_auth_params *auth_params)
+{
+	uint8_t i;
+	uint8_t free_entries = 0;
+	struct mlpeer_auth_params *recv_auth;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	mlo_peer_lock_acquire(ml_peer);
+	for (i = 0; i < MAX_MLO_LINK_PEERS; i++) {
+		recv_auth = ml_peer->pending_auth[i];
+		if (!recv_auth) {
+			free_entries++;
+			continue;
+		}
+		/* overwrite the entry with latest entry */
+		if (qdf_is_macaddr_equal(link_mac, &recv_auth->link_addr)) {
+			mlo_peer_free_auth_param(recv_auth);
+			ml_peer->pending_auth[i] = auth_params;
+			mlo_peer_lock_release(ml_peer);
+
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+
+	if (!free_entries) {
+		mlo_peer_lock_release(ml_peer);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	for (i = 0; i < MAX_MLO_LINK_PEERS; i++) {
+		recv_auth = ml_peer->pending_auth[i];
+		if (!recv_auth) {
+			ml_peer->pending_auth[i] = auth_params;
+			status = QDF_STATUS_SUCCESS;
+			break;
+		}
+	}
+	mlo_peer_lock_release(ml_peer);
+
+	return status;
+}
+#endif