瀏覽代碼

qcacmn: Add support for frame delay operation

Add frame delay support for IOT Simulation.

Change-Id: I1ae2f681cde5d3e4092bf65a34f48290af6877d3
CRs-Fixed: 2734410
Jayachandran Sreekumaran 5 年之前
父節點
當前提交
d2c1b38caa

+ 12 - 1
iot_sim/core/iot_sim_cmn_api_i.h

@@ -40,6 +40,15 @@
  *
  */
 #define USER_BUF_LEN_DROP (2 + 2 + 2 + 2 + 1 + 17)
+/*
+ *		IOT SIM User Buf Format for Drop
+ * ++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * |FrmType/subtype| Seq |category|action| delay |MacAddr|
+ * ++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * |   2Characters |2char| 2chars |2chars| 4char|17chars|
+ *
+ */
+#define USER_BUF_LEN_DELAY (2 + 2 + 2 + 2 + 4 + 17)
 
 /**
  * wlan_iot_sim_pdev_obj_create_handler() - handler for pdev object create
@@ -103,6 +112,7 @@ iot_sim_find_peer_from_mac(struct iot_sim_context *isc,
  * @pdev: reference to global pdev object
  * @nbuf: frame buffer
  * @tx: TRUE in case of tx
+ * @rx_param: mgmt_rx_event_params
  *
  * This function updates the outgoing management frame with
  * the content stored in iot_sim_context.
@@ -113,7 +123,8 @@ iot_sim_find_peer_from_mac(struct iot_sim_context *isc,
 QDF_STATUS iot_sim_frame_update(struct wlan_objmgr_pdev *pdev,
 				qdf_nbuf_t nbuf,
 				struct beacon_tmpl_params *param,
-				bool tx);
+				bool tx,
+				struct mgmt_rx_event_params *rx_param);
 
 /*
  * iot_sim_get_ctx_from_pdev() - API to get iot_sim context object

+ 288 - 12
iot_sim/core/iot_sim_common.c

@@ -21,8 +21,10 @@
 #include <qdf_types.h>
 #include <qdf_util.h>
 #include <qdf_str.h>
+#include <qdf_delayed_work.h>
 #include <wmi_unified_param.h>
 #include <wlan_iot_sim_utils_api.h>
+#include <wlan_lmac_if_api.h>
 
 /*
  * iot_sim_oper_to_str - function to return iot sim operation string
@@ -164,7 +166,7 @@ iot_sim_find_peer_from_mac(struct iot_sim_context *isc,
 			 qdf_list_peek_next(&isc->peer_list, node, &next_node));
 
 		qdf_spin_unlock_bh(&isc->iot_sim_lock);
-		iot_sim_err("Failed to find peer");
+		iot_sim_debug("Failed to find peer");
 	}
 
 	return NULL;
@@ -686,7 +688,7 @@ iot_sim_send_rule_to_fw(struct iot_sim_context *isc,
 {
 	struct simulation_test_params param;
 
-	if (FRAME_TYPE_IS_BEACON(type, subtype) && offset) {
+	if (oper != DELAY && FRAME_TYPE_IS_BEACON(type, subtype) && offset) {
 		iot_sim_info("Beacon update from offset:%d", offset);
 		return QDF_STATUS_E_NOSUPPORT;
 	}
@@ -740,7 +742,8 @@ iot_sim_send_rule_to_fw(struct iot_sim_context *isc,
 QDF_STATUS
 iot_sim_del_rule(struct iot_sim_rule_per_seq **s_e,
 		 struct iot_sim_rule **f_e,
-		 enum iot_sim_operations oper)
+		 enum iot_sim_operations oper,
+		 struct iot_sim_context *isc)
 {
 	if (oper == CONTENT_CHANGE) {
 		qdf_mem_free((*f_e)->frm_content);
@@ -748,7 +751,31 @@ iot_sim_del_rule(struct iot_sim_rule_per_seq **s_e,
 	} else if (oper == DROP) {
 		(*f_e)->drop = false;
 	} else if (oper == DELAY) {
-		/* TBD */
+		if (!qdf_delayed_work_stop((*f_e)->dwork)) {
+			iot_sim_err("delayed work is in running state");
+			/* iot_sim_lock need to be released for the delay */
+			/* work callback to complete execution */
+			/* Hence releasing the lock */
+			qdf_spin_unlock_bh(&isc->iot_sim_lock);
+			/* iot_sim_delay_lock will be freed only after delay */
+			/* work callback execution completion */
+			qdf_spin_lock_bh(&(*f_e)->iot_sim_delay_lock);
+			qdf_spin_lock_bh(&isc->iot_sim_lock);
+			qdf_delayed_work_stop_sync((*f_e)->dwork);
+			qdf_spin_unlock_bh(&(*f_e)->iot_sim_delay_lock);
+		}
+
+		qdf_delayed_work_destroy((*f_e)->dwork);
+		qdf_spinlock_destroy(&(*f_e)->iot_sim_delay_lock);
+		qdf_mem_free((*f_e)->dwork->context);
+		qdf_mem_free((*f_e)->dwork);
+		qdf_nbuf_free((*f_e)->nbuf_list[0]);
+		(*f_e)->nbuf_list[0] = NULL;
+		qdf_nbuf_free((*f_e)->nbuf_list[1]);
+		(*f_e)->nbuf_list[1] = NULL;
+		(*f_e)->sec_buf = NULL;
+		qdf_mem_free((*f_e)->rx_param);
+		(*f_e)->rx_param = NULL;
 	}
 
 	if (qdf_test_bit(oper, (unsigned long *)
@@ -835,7 +862,7 @@ iot_sim_delete_rule_for_mac(struct iot_sim_context *isc,
 			f_e = &((*s_e)->rule_per_type[type][subtype]);
 
 		if (*f_e)
-			status = iot_sim_del_rule(s_e, f_e, oper);
+			status = iot_sim_del_rule(s_e, f_e, oper, isc);
 
 		for (i = 0; i < MAX_SEQ; i++)
 			if (peer->rule_per_seq[i])
@@ -850,6 +877,53 @@ iot_sim_delete_rule_for_mac(struct iot_sim_context *isc,
 	return status;
 }
 
+/*
+ * iot_sim_delay_cb - Delayed work callback function
+ *                    to process delayed frames
+ *
+ * @context: Delayed work callback context
+ *
+ * Return: void
+ */
+static void iot_sim_delay_cb(void *ctxt)
+{
+	struct wlan_objmgr_psoc *psoc = NULL;
+	struct iot_sim_cb_context *context = ctxt;
+
+	qdf_spin_lock_bh(&context->piot_sim_rule->iot_sim_delay_lock);
+	qdf_spin_lock_bh(&context->isc->iot_sim_lock);
+	psoc = wlan_pdev_get_psoc(context->isc->pdev_obj);
+	context->piot_sim_rule->sec_buf = context->piot_sim_rule->nbuf_list[0];
+	qdf_spin_unlock_bh(&context->isc->iot_sim_lock);
+	mgmt_txrx_rx_handler(psoc, context->piot_sim_rule->sec_buf,
+			     context->piot_sim_rule->rx_param);
+	qdf_spin_lock_bh(&context->isc->iot_sim_lock);
+	if (context->piot_sim_rule->nbuf_list[1]) {
+		context->piot_sim_rule->nbuf_list[0] =
+					context->piot_sim_rule->nbuf_list[1];
+		if (!qdf_delayed_work_start(context->piot_sim_rule->dwork,
+					    context->
+					    piot_sim_rule->delay_dur)) {
+			iot_sim_err("delayed_work_start failed");
+			qdf_nbuf_free(context->piot_sim_rule->nbuf_list[0]);
+			qdf_mem_free(context->piot_sim_rule->
+				     rx_param->rx_params);
+			qdf_mem_free(context->piot_sim_rule->rx_param);
+			context->piot_sim_rule->nbuf_list[0] = NULL;
+			context->piot_sim_rule->rx_param = NULL;
+		}
+		context->piot_sim_rule->nbuf_list[1] = NULL;
+	} else {
+		context->piot_sim_rule->nbuf_list[0] = NULL;
+		qdf_mem_free(context->piot_sim_rule->rx_param->rx_params);
+		qdf_mem_free(context->piot_sim_rule->rx_param);
+		context->piot_sim_rule->rx_param = NULL;
+	}
+
+	qdf_spin_unlock_bh(&context->isc->iot_sim_lock);
+	qdf_spin_unlock_bh(&context->piot_sim_rule->iot_sim_delay_lock);
+}
+
 /*
  * iot_sim_add_rule - function to add iot_sim rule
  *
@@ -859,6 +933,7 @@ iot_sim_delete_rule_for_mac(struct iot_sim_context *isc,
  * @frm: user provided frame content
  * @offset: user provided offset
  * @len: length of the user provided frame content
+ * @isc: iot sim context
  *
  * Return: QDF_STATUS_SUCCESS
  */
@@ -866,8 +941,11 @@ QDF_STATUS
 iot_sim_add_rule(struct iot_sim_rule_per_seq **s_e,
 		 struct iot_sim_rule **f_e,
 		 enum iot_sim_operations oper,
-		 uint8_t *frm, uint16_t offset, uint16_t len)
+		 uint8_t *frm, uint16_t offset, uint16_t len,
+		 struct iot_sim_context *isc)
 {
+	struct iot_sim_cb_context *cb_context;
+
 	if (!*f_e) {
 		*f_e = qdf_mem_malloc(sizeof(struct iot_sim_rule));
 		if (!*f_e) {
@@ -886,7 +964,35 @@ iot_sim_add_rule(struct iot_sim_rule_per_seq **s_e,
 	} else if (oper == DROP) {
 		(*f_e)->drop = true;
 	} else if (oper == DELAY) {
-		/* TBD */
+		(*f_e)->delay_dur = offset;
+		(*f_e)->dwork = qdf_mem_malloc(sizeof(struct qdf_delayed_work));
+		if (!(*f_e)->dwork) {
+			iot_sim_err("can't allocate dwork");
+			return QDF_STATUS_E_NOMEM;
+		}
+
+		cb_context = qdf_mem_malloc(sizeof(struct iot_sim_cb_context));
+		if (!cb_context) {
+			iot_sim_err("can't allocate cb_context");
+			qdf_mem_free((*f_e)->dwork);
+			return QDF_STATUS_E_NOMEM;
+		}
+
+		cb_context->isc = isc;
+		cb_context->piot_sim_rule = *f_e;
+		if (QDF_STATUS_SUCCESS !=
+		    qdf_delayed_work_create((*f_e)->dwork, iot_sim_delay_cb,
+					    cb_context)) {
+			iot_sim_err("delayed_work_create failed");
+			qdf_mem_free(cb_context);
+			qdf_mem_free((*f_e)->dwork);
+			return QDF_STATUS_E_NOMEM;
+		}
+
+		(*f_e)->nbuf_list[0] = NULL;
+		(*f_e)->nbuf_list[1] = NULL;
+		iot_sim_err("delayed_work_created");
+		qdf_spinlock_create(&((*f_e)->iot_sim_delay_lock));
 	}
 
 	(*s_e)->use_count++;
@@ -919,7 +1025,7 @@ iot_sim_add_rule_for_mac(struct iot_sim_context *isc,
 			 uint8_t type, uint8_t subtype,
 			 uint16_t seq, uint16_t offset,
 			 uint8_t *frm, uint16_t len,
-			 uint8_t drop, bool action)
+			 uint16_t drop, bool action)
 {
 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
 	struct iot_sim_rule_per_peer *peer;
@@ -969,12 +1075,16 @@ iot_sim_add_rule_for_mac(struct iot_sim_context *isc,
 			iot_sim_info("Rule addition for " QDF_MAC_ADDR_STR,
 				     QDF_MAC_ADDR_ARRAY(mac->bytes));
 
-		iot_sim_info("oper:%s seq: %hu %s:%hu/%hu",
+		iot_sim_info("oper:%s seq: %hu %s:%hu/%hu delay:%hu",
 			     iot_sim_oper_to_str(oper), seq,
 			     action ? "category/action code" : "type/subtype",
-			     type, subtype);
+			     type, subtype, drop);
+
+		if (oper == DELAY)
+			offset = drop;
 
-		status = iot_sim_add_rule(s_e, f_e, oper, frm, offset, len);
+		status = iot_sim_add_rule(s_e, f_e, oper, frm,
+					  offset, len, isc);
 		qdf_spin_unlock_bh(&isc->iot_sim_lock);
 	} else {
 		/* TBD: clear the rules for peer with address 'mac'*/
@@ -1101,6 +1211,93 @@ free:
 	return count;
 }
 
+/*
+ * iot_sim_parse_user_input_delay - function to parse user input into
+ *				   predefined format for delay operation.
+ *				   All arguments passed will be filled
+ *				   upon success
+ * @isc: iot sim context
+ * @userbuf: local copy of user input
+ * @count: length of userbuf
+ * @t_st: address of type variable
+ * @seq: address of seq variable
+ * @cat_type: 802.11 action frame category code
+ * @act_type: 802.11 action frame action code
+ * @delay: address of delay variable
+ * @addr: pointer to mac address
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ *	   QDF_STATUS_E_FAILURE otherwise
+ */
+QDF_STATUS
+iot_sim_parse_user_input_delay(struct iot_sim_context *isc,
+			       char *userbuf, ssize_t count,
+			       uint8_t *t_st, uint16_t *seq,
+			       uint8_t *cat_type, uint8_t *act_type,
+			       uint16_t *delay, struct qdf_mac_addr *addr)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	char *argv[6], *delim = " ", *substr;
+	int argc = -1, ret = 0;
+
+	qdf_mem_zero(argv, sizeof(argv));
+	userbuf = qdf_str_trim(userbuf);
+
+	while ((substr = qdf_str_sep(&userbuf, delim)) != NULL) {
+		if (!isspace(*substr) && *substr != '\0')
+			argv[++argc] = substr;
+		if (argc >= 5)
+			break;
+	}
+
+	if (argc < 3) {
+		iot_sim_err("Invalid argument count %d", (argc + 1));
+		return status;
+	}
+
+	if (!argv[0] || !argv[1] || !argv[2] || !argv[3] || !argv[4]) {
+		iot_sim_err("One or more arguments are null");
+		return status;
+	}
+	/*
+	 * User can send delay data in following format:
+	 * 1. Add delay rule for specific peer
+	 *	<t_st> <seq> <category_type> <action_type> <delay> <MAC>
+	 * 2. Remove delay rule for specific peer
+	 *	<t_st> <seq> <category_type> <action_type> <delay> <MAC>
+	 */
+
+	ret = kstrtou8(argv[0], 16, t_st);
+	if (ret)
+		goto err;
+	ret = kstrtou16(argv[1], 10, seq);
+	if (ret)
+		goto err;
+	ret = kstrtou8(argv[2], 10, cat_type);
+	if (ret)
+		goto err;
+	ret = kstrtou8(argv[3], 10, act_type);
+	if (ret)
+		goto err;
+	ret = kstrtou16(argv[4], 10, delay);
+	if (ret)
+		goto err;
+
+	/*
+	 * If argv[5] is valid, this must be mac address
+	 */
+	if (argv[5])
+		status = qdf_mac_parse(argv[5], addr);
+
+	iot_sim_err("delay rule mac address " QDF_MAC_ADDR_STR,
+		    QDF_MAC_ADDR_ARRAY(addr->bytes));
+
+	return status;
+err:
+	iot_sim_err("kstrtoXX failed: %d", ret);
+	return QDF_STATUS_E_FAILURE;
+}
+
 /*
  * iot_sim_debug_delay_write - Write Handler for delay operation
  * @file: debugfs file pointer
@@ -1115,7 +1312,86 @@ iot_sim_debug_delay_write(struct file *file,
 			  const char __user *buf,
 			  size_t count, loff_t *ppos)
 {
-	iot_sim_err("delay iot sim ops called");
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	unsigned char t_st, type, subtype;
+	uint16_t seq = 0;
+	char *locbuf = NULL;
+	enum iot_sim_operations oper = DELAY;
+	struct qdf_mac_addr mac_addr = QDF_MAC_ADDR_BCAST_INIT;
+	struct iot_sim_context *isc =
+			((struct seq_file *)file->private_data)->private;
+	uint8_t action = 0, category = 0, tmp[2];
+	bool is_action = false, clear = false;
+	uint16_t delay = 0;
+
+	if ((!buf) || (count > USER_BUF_LEN_DELAY) || (count < 6))
+		return -EFAULT;
+
+	locbuf = qdf_mem_malloc(USER_BUF_LEN_DELAY + 1);
+	if (!locbuf)
+		return -ENOMEM;
+
+	if (copy_from_user(locbuf, buf, count)) {
+		qdf_mem_free(locbuf);
+		return -EFAULT;
+	}
+
+	status = iot_sim_parse_user_input_delay(isc, locbuf, count,
+						&t_st, &seq, &category,
+						&action, &delay, &mac_addr);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		iot_sim_err("iot_sim_parse_user_input_delay failed");
+		goto free;
+	}
+	iot_sim_err("Delay rule t_st:%d, seq:%hu cat_type:%d, act_type:%d, delay:%hu",
+		    t_st, seq, category, action, delay);
+
+	type = (t_st & IEEE80211_FC0_TYPE_MASK) >> IEEE80211_FC0_TYPE_SHIFT;
+	subtype = (t_st & IEEE80211_FC0_SUBTYPE_MASK);
+	subtype >>= IEEE80211_FC0_SUBTYPE_SHIFT;
+
+	if (type > N_FRAME_TYPE || subtype > N_FRAME_SUBTYPE || seq > MAX_SEQ)
+		goto free;
+
+	if (FRAME_TYPE_IS_ACTION(type, subtype)) {
+		tmp[0] = category;
+		tmp[1] = action;
+		/*
+		 * convert 802.11 category and action code to iot sim codes
+		 */
+		status = iot_sim_get_index_for_action_frm(tmp, &category,
+							  &action, false);
+		if (QDF_IS_STATUS_ERROR(status))
+			goto free;
+
+		is_action = 1;
+		type = category;
+		subtype = action;
+	}
+
+	clear = delay ? false : true;
+	status = iot_sim_send_rule_to_fw(isc, oper, &mac_addr, type, subtype,
+					 seq, delay, NULL, 0, is_action, clear);
+	if (QDF_IS_STATUS_SUCCESS(status))
+		goto free;
+
+	/* check for rule removal */
+	if (!delay) {
+		status = iot_sim_delete_rule_for_mac(isc, oper, seq,
+						     type, subtype,
+						     &mac_addr,
+						     is_action);
+	} else {
+		status = iot_sim_add_rule_for_mac(isc, oper, &mac_addr,
+						  type, subtype, seq, 0,
+						  NULL, 0, delay, is_action);
+	}
+	if (QDF_IS_STATUS_SUCCESS(status))
+		iot_sim_debug("iot_sim: Rule update Delay Operation - Success");
+	else
+		iot_sim_err("iot_sim: Rule update Delay Operation - Fail");
+free:
+	qdf_mem_free(locbuf);
 	return count;
 }
 

+ 11 - 0
iot_sim/core/iot_sim_defs_i.h

@@ -77,6 +77,7 @@
 #define MAX_SEQ 0x4
 #define MAX_PEER_COUNT 0x2
 #define MAX_ACTION 0x3
+#define RX_STATUS_SIZE 0x96
 #define IOT_SIM_DEBUGFS_FILE_NUM 3
 #define FRAME_TYPE_IS_BEACON(type, subtype) ((type) == 0 && (subtype) == 8)
 #define FRAME_TYPE_IS_ACTION(type, subtype) ((type) == 0 && (subtype) == 13)
@@ -113,6 +114,11 @@ struct iot_sim_rule {
 	bool drop;
 	uint16_t delay_dur;
 	uint8_t rule_bitmap;
+	qdf_nbuf_t nbuf_list[2];
+	qdf_nbuf_t sec_buf;
+	struct qdf_delayed_work *dwork;
+	struct mgmt_rx_event_params *rx_param;
+	qdf_spinlock_t iot_sim_delay_lock;
 };
 
 /*
@@ -190,4 +196,9 @@ enum iot_sim_subcmd {
 	IOT_SIM_MAX_SUBCMD,
 };
 
+struct iot_sim_cb_context {
+	struct iot_sim_context *isc;
+	struct iot_sim_rule *piot_sim_rule;
+};
+
 #endif /* _IOT_SIM_DEFS_I_H_ */

+ 69 - 10
iot_sim/core/iot_sim_utils.c

@@ -16,6 +16,7 @@
 
 #include <wlan_iot_sim_utils_api.h>
 #include <qdf_module.h>
+#include <qdf_delayed_work.h>
 #include "../../core/iot_sim_cmn_api_i.h"
 #include <wlan_objmgr_pdev_obj.h>
 #include <wlan_objmgr_vdev_obj.h>
@@ -198,9 +199,12 @@ iot_sim_apply_content_change_rule(struct wlan_objmgr_pdev *pdev,
 }
 
 /*
- * iot_sim_apply_drop_rule - function to apply drop rule. If set buffer will be
- *			     freed here and proper return value will be sent to
- *			     tgt layer.
+ * iot_sim_apply_delay_drop_rule - function to apply delay or drop rule.
+ *                                 If drop rule is set, buffer will be freed
+ *                                 here and proper return value will be sent to
+ *			           tgt layer. In case of delay rule, delayed
+ *                                 workqueue will be scheduled for rx frame
+ *                                 processing
  *
  * @piot_sim_rule: iot_sim rule structure
  * @nbuf: skb coming from upper stack
@@ -209,16 +213,67 @@ iot_sim_apply_content_change_rule(struct wlan_objmgr_pdev *pdev,
  *	   QDF_STATUS_E_NULL_VALUE, when drop rule is applied
  */
 QDF_STATUS
-iot_sim_apply_drop_rule(struct iot_sim_rule *piot_sim_rule,
-			qdf_nbuf_t nbuf)
+iot_sim_apply_delay_drop_rule(struct iot_sim_rule *piot_sim_rule,
+			      qdf_nbuf_t nbuf,
+			      struct mgmt_rx_event_params *param)
 {
-	if (!piot_sim_rule->drop)
+	struct mgmt_rx_event_params *rx_param;
+
+	if (!piot_sim_rule->drop &&
+	    !piot_sim_rule->delay_dur)
 		return QDF_STATUS_E_NOSUPPORT;
 
-	if (nbuf)
+	if (piot_sim_rule->drop && nbuf) {
 		qdf_nbuf_free(nbuf);
+		iot_sim_debug("iot_sim: Drop rule applied");
+	} else if (piot_sim_rule->delay_dur) {
+		if (nbuf == piot_sim_rule->sec_buf) {
+			iot_sim_debug("iot_sim: rx frame process after delay");
+			return QDF_STATUS_E_NOSUPPORT;
+		}
+
+		if (piot_sim_rule->nbuf_list[0]) {
+			if (!qdf_delayed_work_stop(piot_sim_rule->
+						   dwork)) {
+				piot_sim_rule->nbuf_list[1] = nbuf;
+				return QDF_STATUS_SUCCESS;
+			}
+
+			qdf_nbuf_free(piot_sim_rule->nbuf_list[0]);
+			qdf_mem_free(piot_sim_rule->rx_param->rx_params);
+			qdf_mem_free(piot_sim_rule->rx_param);
+		}
+
+		rx_param = qdf_mem_malloc(sizeof(struct mgmt_rx_event_params));
+		if (!rx_param) {
+			iot_sim_err("rx_param alloc failed");
+			return QDF_STATUS_E_NOSUPPORT;
+		}
+
+		qdf_mem_copy(rx_param, param,
+			     sizeof(struct mgmt_rx_event_params));
+		rx_param->rx_params = qdf_mem_malloc(RX_STATUS_SIZE);
+		if (!rx_param->rx_params) {
+			iot_sim_err("rx_param->rx_params alloc failed");
+			qdf_mem_free(rx_param);
+			return QDF_STATUS_E_NOSUPPORT;
+		}
+
+		qdf_mem_copy(rx_param->rx_params,
+			     param->rx_params, RX_STATUS_SIZE);
+		piot_sim_rule->rx_param = rx_param;
+		piot_sim_rule->nbuf_list[0] = nbuf;
+		if (!qdf_delayed_work_start(piot_sim_rule->dwork,
+					    piot_sim_rule->delay_dur)) {
+			iot_sim_err("delayed_work_start failed");
+			qdf_mem_free(rx_param->rx_params);
+			qdf_mem_free(rx_param);
+			return QDF_STATUS_E_NOSUPPORT;
+		}
+
+		iot_sim_err("iot_sim: Delay rule applied");
+	}
 
-	iot_sim_debug("iot_sim: Drop rule applied");
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -233,13 +288,14 @@ iot_sim_apply_drop_rule(struct iot_sim_rule *piot_sim_rule,
  * @nbuf: input packet
  * @param: beacon template cmd parameter
  * @tx: tx or not
+ * @rx_param: mgmt_rx_event_params
  *
  * Return: QDF_STATUS_SUCCESS in general
  *	   QDF_STATUS_E_NOSUPPORT, no content change rule found for this frame
  */
 QDF_STATUS iot_sim_frame_update(struct wlan_objmgr_pdev *pdev, qdf_nbuf_t nbuf,
 				struct beacon_tmpl_params *param,
-				bool tx)
+				bool tx, struct mgmt_rx_event_params *rx_param)
 {
 	uint8_t type, subtype, seq = 0;
 	struct iot_sim_context *isc;
@@ -347,9 +403,12 @@ QDF_STATUS iot_sim_frame_update(struct wlan_objmgr_pdev *pdev, qdf_nbuf_t nbuf,
 		if (status == QDF_STATUS_E_NOSUPPORT)
 			goto norule;
 	} else {
-		status = iot_sim_apply_drop_rule(piot_sim_rule, nbuf);
+		status = iot_sim_apply_delay_drop_rule(piot_sim_rule,
+						       nbuf, rx_param);
 		if (QDF_IS_STATUS_SUCCESS(status))
 			status = QDF_STATUS_E_NULL_VALUE;
+		else
+			status = QDF_STATUS_SUCCESS;
 	}
 
 	qdf_spin_unlock_bh(&isc->iot_sim_lock);

+ 3 - 1
iot_sim/dispatcher/inc/wlan_iot_sim_utils_api.h

@@ -39,11 +39,13 @@ struct iot_sim_cbacks {
  * @vdev - vdev object.
  * @buf - skb
  * @tx - TRUE in case of Tx
+ * @rx_param - mgmt_rx_event_params
  *
  * Return : QDF_STATUS_E_SUCCESS/QDF_STATUS_E_FAILURE.
  */
 QDF_STATUS iot_sim_cmd_handler(struct wlan_objmgr_vdev *vdev, qdf_nbuf_t buf,
-			       struct beacon_tmpl_params *param, bool tx);
+			       struct beacon_tmpl_params *bcn_param, bool tx,
+			       struct mgmt_rx_event_params *param);
 
 /**
  * wlan_iot_sim_init() - API to init iot_sim component

+ 3 - 2
iot_sim/dispatcher/src/wlan_iot_sim_utils_api.c

@@ -24,11 +24,12 @@
 #define IEEE80211_FRAME_BODY_OFFSET 0x18
 
 QDF_STATUS iot_sim_cmd_handler(struct wlan_objmgr_vdev *vdev, qdf_nbuf_t nbuf,
-			       struct beacon_tmpl_params *param, bool tx)
+			       struct beacon_tmpl_params *bcn_param, bool tx,
+			       struct mgmt_rx_event_params *param)
 {
 	struct wlan_objmgr_pdev *pdev = vdev->vdev_objmgr.wlan_pdev;
 
-	return iot_sim_frame_update(pdev, nbuf, param, tx);
+	return iot_sim_frame_update(pdev, nbuf, bcn_param, tx, param);
 }
 
 QDF_STATUS iot_sim_register_callbacks(struct wlan_objmgr_pdev *pdev,

+ 2 - 1
umac/cmn_services/mgmt_txrx/core/src/wlan_mgmt_txrx_main.c

@@ -194,7 +194,8 @@ QDF_STATUS iot_sim_mgmt_tx_update(struct wlan_objmgr_psoc *psoc,
 		status = rx_ops->iot_sim_rx_ops.iot_sim_cmd_handler(vdev,
 								    buf,
 								    NULL,
-								    true);
+								    true,
+								    NULL);
 		if (QDF_IS_STATUS_ERROR(status))
 			mgmt_txrx_err("iot_sim_cmd_handler returned failure");
 	}

+ 2 - 1
umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_tgt_api.c

@@ -946,7 +946,8 @@ static QDF_STATUS simulation_frame_update(struct wlan_objmgr_psoc *psoc,
 		if (vdev) {
 			status = rx_ops->iot_sim_rx_ops.
 					iot_sim_cmd_handler(vdev, buf,
-							    NULL, false);
+							    NULL, false,
+							    rx_param);
 			if (status == QDF_STATUS_E_NULL_VALUE) {
 				wlan_objmgr_vdev_release_ref(vdev, dbgid);
 				mgmt_txrx_debug("iot_sim:Pkt processed at RX");

+ 3 - 2
umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h

@@ -1447,8 +1447,9 @@ struct iot_sim_cbacks;
 struct wlan_lmac_if_iot_sim_rx_ops {
 	QDF_STATUS (*iot_sim_cmd_handler)(struct wlan_objmgr_vdev *vdev,
 					  qdf_nbuf_t n_buf,
-					  struct beacon_tmpl_params *param,
-					  bool tx);
+					  struct beacon_tmpl_params *bcn_param,
+					  bool tx,
+					  struct mgmt_rx_event_params *param);
 	QDF_STATUS (*iot_sim_register_cb)(struct wlan_objmgr_pdev *pdev,
 					  struct iot_sim_cbacks *cb);
 };