Browse Source

qcacmn: Add EPCS state machine support

Add EPCS state machine support per peer.
Based on user command trigger or EPCS action frame
EPCS state will change.

Change-Id: Ib516543cec6a7007f12680b0e86b9edbe223b68d
CRs-Fixed: 3491941
Venkateswara Swamy Bandaru 2 years ago
parent
commit
eddd2583fb

+ 44 - 6
umac/mlo_mgr/inc/wlan_mlo_epcs.h

@@ -27,6 +27,8 @@
 #include <wlan_cmn.h>
 #include <wlan_cmn.h>
 #endif
 #endif
 
 
+struct wlan_mlo_peer_context;
+
 /**
 /**
  * enum wlan_epcs_category - epcs category
  * enum wlan_epcs_category - epcs category
  *
  *
@@ -57,15 +59,23 @@ struct wlan_epcs_info {
 };
 };
 
 
 /**
 /**
- * struct wlan_mlo_peer_epcs_policy - Peer EPCS information
- * @enable: EPCS enable status
+ * enum peer_epcs_state - epcs stat of peer
+ * @EPCS_DOWN: EPCS state down
+ * @EPCS_ENABLE: EPCS state enabled
+ */
+enum peer_epcs_state {
+	EPCS_DOWN,
+	EPCS_ENABLE
+};
+
+/**
+ * struct wlan_mlo_peer_epcs_info - Peer EPCS information
+ * @state: EPCS state of peer
  * @self_gen_dialog_token: selfgenerated dialog token
  * @self_gen_dialog_token: selfgenerated dialog token
- * @status: status
  */
  */
-struct wlan_mlo_peer_epcs_policy {
-	uint8_t enable;
+struct wlan_mlo_peer_epcs_info {
+	enum peer_epcs_state state;
 	uint8_t self_gen_dialog_token;
 	uint8_t self_gen_dialog_token;
-	uint8_t status;
 };
 };
 
 
 /**
 /**
@@ -142,4 +152,32 @@ wlan_mlo_parse_epcs_action_frame(struct wlan_epcs_info *epcs,
 				 struct wlan_action_frame *action_frm,
 				 struct wlan_action_frame *action_frm,
 				 uint32_t frm_len);
 				 uint32_t frm_len);
 
 
+/**
+ * wlan_mlo_peer_rcv_cmd() - API to process EPCS command
+ * @ml_peer: Pointer to ML peer received
+ * @epcs: Pointer to EPCS information
+ * @updparam: pointer to fill update parameters
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wlan_mlo_peer_rcv_cmd(struct wlan_mlo_peer_context *ml_peer,
+		      struct wlan_epcs_info *epcs,
+		      bool *updparam);
+
+/**
+ * wlan_mlo_peer_rcv_action_frame() - API to process EPCS frame receive event
+ * @ml_peer: Pointer to ML peer received
+ * @epcs: Pointer to EPCS information
+ * @respond: pointer to fill response required or not
+ * @updparam: pointer to fill update parameters
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wlan_mlo_peer_rcv_action_frame(struct wlan_mlo_peer_context *ml_peer,
+			       struct wlan_epcs_info *epcs,
+			       bool *respond,
+			       bool *updparam);
+
 #endif /* _WLAN_MLO_EPCS_H_ */
 #endif /* _WLAN_MLO_EPCS_H_ */

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

@@ -38,6 +38,8 @@
 #define WLAN_UMAC_MLO_MAX_VDEVS 2
 #define WLAN_UMAC_MLO_MAX_VDEVS 2
 #endif
 #endif
 
 
+#include <wlan_mlo_epcs.h>
+
 /* MAX instances of ML devices */
 /* MAX instances of ML devices */
 #ifndef WLAN_UMAC_MLO_MAX_DEV
 #ifndef WLAN_UMAC_MLO_MAX_DEV
 #define WLAN_UMAC_MLO_MAX_DEV 2
 #define WLAN_UMAC_MLO_MAX_DEV 2
@@ -634,6 +636,7 @@ struct wlan_mlo_mld_cap {
  * @nawds_config: eack link peer's NAWDS configuration
  * @nawds_config: eack link peer's NAWDS configuration
  * @pending_auth: Holds pending auth request
  * @pending_auth: Holds pending auth request
  * @t2lm_policy: TID-to-link mapping information
  * @t2lm_policy: TID-to-link mapping information
+ * @epcs_info: EPCS information
  * @msd_cap_present: Medium Sync Capability present bit
  * @msd_cap_present: Medium Sync Capability present bit
  * @mlpeer_emlcap: EML capability information for ML peer
  * @mlpeer_emlcap: EML capability information for ML peer
  * @mlpeer_msdcap: Medium Sync Delay capability information for ML peer
  * @mlpeer_msdcap: Medium Sync Delay capability information for ML peer
@@ -669,6 +672,7 @@ struct wlan_mlo_peer_context {
 #endif
 #endif
 #ifdef WLAN_FEATURE_11BE
 #ifdef WLAN_FEATURE_11BE
 	struct wlan_mlo_peer_t2lm_policy t2lm_policy;
 	struct wlan_mlo_peer_t2lm_policy t2lm_policy;
+	struct wlan_mlo_peer_epcs_info epcs_info;
 #endif
 #endif
 	bool msd_cap_present;
 	bool msd_cap_present;
 	struct wlan_mlo_eml_cap mlpeer_emlcap;
 	struct wlan_mlo_eml_cap mlpeer_emlcap;

+ 130 - 0
umac/mlo_mgr/src/wlan_mlo_epcs.c

@@ -234,3 +234,133 @@ wlan_mlo_add_epcs_action_frame(uint8_t *frm,
 
 
 	return frm;
 	return frm;
 }
 }
+
+QDF_STATUS
+wlan_mlo_peer_rcv_cmd(struct wlan_mlo_peer_context *ml_peer,
+		      struct wlan_epcs_info *epcs,
+		      bool *updparam)
+{
+	uint32_t cur_state;
+	uint32_t new_state;
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+
+	if (!ml_peer) {
+		epcs_err("Null MLO peer");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	*updparam = false;
+
+	cur_state = ml_peer->epcs_info.state;
+	switch (ml_peer->epcs_info.state) {
+	case EPCS_DOWN:
+		if (epcs->cat == WLAN_EPCS_CATEGORY_REQUEST) {
+		/* check authorization */
+			if (1) {
+				status = QDF_STATUS_SUCCESS;
+				epcs->dialog_token =
+				  ++ml_peer->epcs_info.self_gen_dialog_token;
+			} else {
+				epcs_info("peer not authorized to enable EPCS");
+			}
+		} else if (epcs->cat == WLAN_EPCS_CATEGORY_TEARDOWN) {
+			epcs_info("peer already in EPCS down state");
+		} else if (epcs->cat == WLAN_EPCS_CATEGORY_RESPONSE) {
+			epcs_err("Invalid command");
+		}
+		break;
+	case EPCS_ENABLE:
+		if (epcs->cat == WLAN_EPCS_CATEGORY_TEARDOWN) {
+			ml_peer->epcs_info.state = EPCS_DOWN;
+			status = QDF_STATUS_SUCCESS;
+			*updparam = true;
+		} else if (epcs->cat == WLAN_EPCS_CATEGORY_REQUEST) {
+			epcs_info("peer already in EPCS enable state");
+		} else if (epcs->cat == WLAN_EPCS_CATEGORY_RESPONSE) {
+			epcs_err("Invalid command");
+		}
+		break;
+	default:
+		epcs_err("Invalid peer state %d",
+			 ml_peer->epcs_info.state);
+	}
+
+	new_state = ml_peer->epcs_info.state;
+	epcs_debug("cmd:old state %d new state %d ev cat %d dialog token %d status %d",
+		   cur_state, new_state, epcs->cat,
+		   epcs->dialog_token, epcs->status);
+
+	return status;
+}
+
+QDF_STATUS
+wlan_mlo_peer_rcv_action_frame(struct wlan_mlo_peer_context *ml_peer,
+			       struct wlan_epcs_info *epcs,
+			       bool *respond,
+			       bool *updparam)
+{
+	uint32_t cur_state;
+	uint32_t new_state;
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+
+	if (!ml_peer) {
+		epcs_err("Null MLO peer");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	*respond = false;
+	*updparam = false;
+
+	cur_state = ml_peer->epcs_info.state;
+	switch (ml_peer->epcs_info.state) {
+	case EPCS_DOWN:
+		if (epcs->cat == WLAN_EPCS_CATEGORY_RESPONSE) {
+			if (epcs->status == STATUS_SUCCESS) {
+				if (epcs->dialog_token ==
+				    ml_peer->epcs_info.self_gen_dialog_token) {
+					ml_peer->epcs_info.state = EPCS_ENABLE;
+					status = QDF_STATUS_SUCCESS;
+					*updparam = true;
+				} else {
+					epcs_err("Response dialog token mismatch self_gen_dialog_token %d response token %d", ml_peer->epcs_info.self_gen_dialog_token, epcs->dialog_token);
+				}
+			} else {
+				epcs_info("epcs rejected with status code %d",
+					  epcs->status);
+			}
+		} else if (epcs->cat == WLAN_EPCS_CATEGORY_REQUEST) {
+			/* check authorization */
+			if (1) {
+				ml_peer->epcs_info.state = EPCS_ENABLE;
+				status = QDF_STATUS_SUCCESS;
+				*respond = true;
+				*updparam = true;
+			} else {
+				epcs_info("peer not authorized to enable EPCS");
+			}
+		} else if (epcs->cat == WLAN_EPCS_CATEGORY_TEARDOWN) {
+			epcs_info("peer not in EPCS enable state");
+		}
+		break;
+	case EPCS_ENABLE:
+		if (epcs->cat == WLAN_EPCS_CATEGORY_TEARDOWN) {
+			ml_peer->epcs_info.state = EPCS_DOWN;
+			status = QDF_STATUS_SUCCESS;
+			*updparam = true;
+		} else if (epcs->cat == WLAN_EPCS_CATEGORY_REQUEST) {
+			epcs_info("peer already in EPCS enable state");
+		} else if (epcs->cat == WLAN_EPCS_CATEGORY_RESPONSE) {
+			epcs_info("peer already in EPCS enable state");
+		}
+		break;
+	default:
+		epcs_err("Invalid peer state %d", ml_peer->epcs_info.state);
+	}
+
+	new_state = ml_peer->epcs_info.state;
+	epcs_debug("action:old state %d new state %d ev cat %d dialog token %d status %d",
+		   cur_state, new_state, epcs->cat,
+		   epcs->dialog_token, epcs->status);
+
+	return status;
+}

+ 14 - 0
umac/mlo_mgr/src/wlan_mlo_mgr_peer.c

@@ -26,6 +26,7 @@
 #include "wlan_crypto_global_api.h"
 #include "wlan_crypto_global_api.h"
 #include "wlan_mlo_mgr_setup.h"
 #include "wlan_mlo_mgr_setup.h"
 #include "wlan_utility.h"
 #include "wlan_utility.h"
+#include "wlan_mlo_epcs.h"
 
 
 static void mlo_partner_peer_create_post(struct wlan_mlo_dev_context *ml_dev,
 static void mlo_partner_peer_create_post(struct wlan_mlo_dev_context *ml_dev,
 					 struct wlan_objmgr_vdev *vdev_link,
 					 struct wlan_objmgr_vdev *vdev_link,
@@ -972,11 +973,23 @@ wlan_mlo_peer_set_t2lm_enable_val(struct wlan_mlo_peer_context *ml_peer,
 {
 {
 	ml_peer->t2lm_policy.t2lm_enable_val = ml_info->t2lm_enable_val;
 	ml_peer->t2lm_policy.t2lm_enable_val = ml_info->t2lm_enable_val;
 }
 }
+
+static void
+wlan_mlo_peer_initialize_epcs_info(struct wlan_mlo_peer_context *ml_peer)
+{
+	ml_peer->epcs_info.state = EPCS_DOWN;
+	ml_peer->epcs_info.self_gen_dialog_token = 0;
+}
+
 #else
 #else
 static void
 static void
 wlan_mlo_peer_set_t2lm_enable_val(struct wlan_mlo_peer_context *ml_peer,
 wlan_mlo_peer_set_t2lm_enable_val(struct wlan_mlo_peer_context *ml_peer,
 				  struct mlo_partner_info *ml_info)
 				  struct mlo_partner_info *ml_info)
 {}
 {}
+
+static void
+wlan_mlo_peer_initialize_epcs_info(struct wlan_mlo_peer_context *ml_peer)
+{}
 #endif /* WLAN_FEATURE_11BE */
 #endif /* WLAN_FEATURE_11BE */
 
 
 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP)
 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP)
@@ -1435,6 +1448,7 @@ QDF_STATUS wlan_mlo_peer_create(struct wlan_objmgr_vdev *vdev,
 		qdf_copy_macaddr((struct qdf_mac_addr *)&ml_peer->peer_mld_addr,
 		qdf_copy_macaddr((struct qdf_mac_addr *)&ml_peer->peer_mld_addr,
 				 (struct qdf_mac_addr *)&link_peer->mldaddr[0]);
 				 (struct qdf_mac_addr *)&link_peer->mldaddr[0]);
 		wlan_mlo_peer_set_t2lm_enable_val(ml_peer, ml_info);
 		wlan_mlo_peer_set_t2lm_enable_val(ml_peer, ml_info);
+		wlan_mlo_peer_initialize_epcs_info(ml_peer);
 
 
 		/* Allocate AID */
 		/* Allocate AID */
 		if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) {
 		if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) {