Pārlūkot izejas kodu

qcacmn: Add debugfs support for iot_sim module

Following changes were done:
1. Adding debugfs functionality for iot_sim module
2. Changing the iot_sim context from psoc to pdev
3. Currently iot_sim support only bcast peer
4. Adding write handler to store user configured rules.

Change-Id: I4319bae3986874434f2a2e2397b1a8698c48d936
CRs-Fixed: 2657929
nakul kachhwaha 5 gadi atpakaļ
vecāks
revīzija
d20fe7aad4

+ 48 - 15
iot_sim/core/iot_sim_cmn_api_i.h

@@ -18,35 +18,50 @@
 #define _IOT_SIM_CMN_API_I_H_
 
 #include "iot_sim_defs_i.h"
+#include <qdf_net_types.h>
 
+#define MAX_BUFFER_SIZE 2048
 /*
- * wlan_iot_sim_psoc_obj_create_handler() - handler for psoc object create
- * @psoc: reference to global psoc object
+ *                   IOT SIM User Buf Format
+ *
+ * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * | FrmType/subtype |  Seq  | Offset | Length | content | Mac Addr |
+ * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * |     1Byte       | 2Byte | 2Bytes | 2Bytes | Length  | 6 Bytes  |
+ *
+ */
+#define USER_BUF_LEN (1 + 2 + 2 + 2 + MAX_BUFFER_SIZE + 6)
+#define IOT_SIM_SET_OP_BIT(bitmap, oper) ((bitmap) |= 1 << (oper))
+#define IOT_SIM_CLEAR_OP_BIT(bitmap, oper) (((bitmap) &= ~(1 << (oper))) == 0)
+
+/**
+ * wlan_iot_sim_pdev_obj_create_handler() - handler for pdev object create
+ * @pdev: reference to global pdev object
  * @arg:  reference to argument provided during registration of handler
  *
- * This is a handler to indicate psoc object created. Hence iot_sim_context
- * object can be created and attached to psoc component list.
+ * This is a handler to indicate pdev object created. Hence iot_sim_context
+ * object can be created and attached to pdev component list.
  *
  * Return: QDF_STATUS_SUCCESS on success
- *         QDF_STATUS_E_FAILURE if psoc is null
+ *         QDF_STATUS_E_FAILURE if pdev is null
  *         QDF_STATUS_E_NOMEM on failure of iot_sim object allocation
  */
-QDF_STATUS wlan_iot_sim_psoc_obj_create_handler(struct wlan_objmgr_psoc *psoc,
+QDF_STATUS wlan_iot_sim_pdev_obj_create_handler(struct wlan_objmgr_pdev *pdev,
 						void *arg);
 
-/*
- * wlan_iot_sim_psoc_obj_destroy_handler() - handler for psoc object delete
- * @psoc: reference to global psoc object
+/**
+ * wlan_iot_sim_pdev_obj_destroy_handler() - handler for pdev object delete
+ * @pdev: reference to global pdev object
  * @arg:  reference to argument provided during registration of handler
  *
- * This is a handler to indicate psoc object going to be deleted.
- * Hence iot_sim_context object can be detached from psoc component list.
+ * This is a handler to indicate pdev object going to be deleted.
+ * Hence iot_sim_context object can be detached from pdev component list.
  * Then iot_sim_context object can be deleted.
  *
  * Return: QDF_STATUS_SUCCESS on success
  *         QDF_STATUS_E_FAILURE on failure
  */
-QDF_STATUS wlan_iot_sim_psoc_obj_destroy_handler(struct wlan_objmgr_psoc *psoc,
+QDF_STATUS wlan_iot_sim_pdev_obj_destroy_handler(struct wlan_objmgr_pdev *pdev,
 						 void *arg);
 
 /*
@@ -61,16 +76,34 @@ QDF_STATUS wlan_iot_sim_psoc_obj_destroy_handler(struct wlan_objmgr_psoc *psoc,
  *
  */
 static inline struct iot_sim_context *
-iot_sim_get_ctx_from_psoc(struct wlan_objmgr_psoc *psoc)
+iot_sim_get_ctx_from_pdev(struct wlan_objmgr_pdev *pdev)
 {
 	struct iot_sim_context *isc = NULL;
 
-	if (psoc) {
-		isc = wlan_objmgr_psoc_get_comp_private_obj(psoc,
+	if (pdev) {
+		isc = wlan_objmgr_pdev_get_comp_private_obj(pdev,
 							    WLAN_IOT_SIM_COMP);
 	}
 
 	return isc;
 }
 
+char*
+iot_sim_print_mac(struct qdf_mac_addr *mac);
+
+QDF_STATUS
+iot_sim_delete_rule_for_mac(struct iot_sim_context *isc,
+			    enum iot_sim_operations oper,
+			    unsigned short seq,
+			    unsigned char type,
+			    unsigned char subtype,
+			    struct qdf_mac_addr *mac);
+
+QDF_STATUS
+iot_sim_parse_user_input_content_change(struct iot_sim_context *isc,
+					char *userbuf, ssize_t count,
+					uint8_t *t_st, uint16_t *seq,
+					uint16_t *offset, uint16_t *length,
+					uint8_t **content,
+					struct qdf_mac_addr *mac);
 #endif /* _IOT_SIM_CMN_API_I_H_ */

+ 805 - 18
iot_sim/core/iot_sim_common.c

@@ -15,21 +15,680 @@
  */
 
 #include "iot_sim_cmn_api_i.h"
+#include "iot_sim_defs_i.h"
 #include <qdf_mem.h>
 #include <qdf_types.h>
+#include <qdf_util.h>
 
+/*
+ * iot_sim_validate_content - function to validate frame content. User provided
+ *			      content must be either full frame or full frame
+ *			      body or valid TLV formatted data.
+ * @buf: pointer to frame content in binary format
+ * @total_len: length of content
+ * @offset: offset provided by user
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ *	   QDF_STATUS_E_FAULT on failure
+ */
+static QDF_STATUS
+iot_sim_validate_content(uint8_t *buf,
+			 uint16_t total_len,
+			 uint16_t offset)
+{
+	char *ie = buf;
+	uint32_t len = 0, i = 0;
+	uint32_t fb = sizeof(struct ieee80211_frame);
+
+	if (offset == 0 || offset == fb) {
+		/* Replace the entire content set by user */
+		return QDF_STATUS_SUCCESS;
+	}
+
+	/* Check for malformed IEs and proper IE
+	 * boundaries in user content
+	 */
+	for (i = 0; i < total_len;) {
+		/* TLV: T(1) + L(1) + V(L)*/
+		len = (1 + 1 + ie[1]);
+		i += len;
+		ie += len;
+	}
+
+	if (i == total_len)
+		return QDF_STATUS_SUCCESS;
+
+	iot_sim_err("iot_sim: cnt(bin) len:%u IE Parsed len:%u",
+		    total_len,
+		    i);
+
+	return QDF_STATUS_E_INVAL;
+}
+
+/*
+ * iot_sim_handle_frame_content - function to process frame content provided
+ *				  by user. This function will convert the ascii
+ *				  string into binary string and validate the
+ *				  content.
+ * @isc: iot sim context
+ * @pos: position to the frame content in the user buffer
+ * @storage: storage to store frame content after processing
+ * @offset: user provided offset
+ * @len: length of the user provided content in bytes
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ *	   QDF_STATUS_E_FAULT on hex str to binary conversion failure
+ *	   QDF_STATUS_E_NOMEM on memory allocation failure
+ */
 QDF_STATUS
-iot_sim_control_cmn(struct wlan_objmgr_psoc *psoc, wbuf_t wbuf)
+iot_sim_handle_frame_content(struct iot_sim_context *isc,
+			     const char *pos,
+			     uint8_t **storage,
+			     uint16_t offset,
+			     uint16_t len)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	int ret;
+
+	*storage = qdf_mem_malloc(len);
+	if (!*storage) {
+		iot_sim_err("iot_sim:storage allocation failed");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	ret = qdf_hex_str_to_binary(*storage, pos, len);
+	if (ret == -1) {
+		iot_sim_err("iot_sim:hex2bin conversion failed");
+		status = QDF_STATUS_E_FAULT;
+		goto error2;
+	}
+
+	status = iot_sim_validate_content(*storage, len, offset);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		iot_sim_err("iot_sim:User Content Invalid");
+		goto error2;
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+error2:
+	qdf_mem_free(*storage);
+	*storage = NULL;
+	return status;
+}
+
+/*
+ * iot_sim_parse_user_input_content_change - function to parse user input into
+ *					     predefined format for content
+ *					     change 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
+ * @offset: address of offset variable
+ * @length: address of length variable
+ * @content: double pointer to storage to store frame content after processing
+ * @addr: pointer to mac address
+ *
+ * @storage: storage to store frame content after processing
+ * @offset: user provided offset
+ * @len: length of the user provided content in bytes
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ *	   QDF_STATUS_E_FAILURE otherwise
+ */
+QDF_STATUS
+iot_sim_parse_user_input_content_change(struct iot_sim_context *isc,
+					char *userbuf, ssize_t count,
+					uint8_t *t_st, uint16_t *seq,
+					uint16_t *offset, uint16_t *length,
+					uint8_t **content,
+					struct qdf_mac_addr *addr)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	char *argv[6], *delim = " ", *substr;
+	int argc = -1, ret = 0;
+
+	qdf_mem_zero(argv, sizeof(argv));
+	userbuf = strim(userbuf);
+
+	while ((substr = strsep(&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]) {
+		iot_sim_err("One or more arguments are null");
+		return status;
+	}
+
+	ret = kstrtou8(argv[0], 16, t_st);
+	if (ret)
+		goto err;
+	ret = kstrtou16(argv[1], 10, seq);
+	if (ret)
+		goto err;
+	ret = kstrtou16(argv[2], 10, offset);
+	if (ret)
+		goto err;
+	ret = kstrtou16(argv[3], 10, length);
+	if (ret)
+		goto err;
+	/*
+	 * User can send content change data in following format:
+	 * 1. Add rule for specific peer
+	 *	<t_st> <seq> <offset> <length> <content> <MAC>
+	 * 2. Add rule for broadcast peer
+	 *	<t_st> <seq> <offset> <length> <content>
+	 * 3. Remove rule for specific peer
+	 *	<t_st> <seq> <offset> <length> <MAC>
+	 * 4. Remove rule for broadcast peer
+	 *	<t_st> <seq> <offset> <length>
+	 */
+
+	/*
+	 * If length is 0, this implies remove the rule
+	 */
+	if (!*length) {
+		/*
+		 * 1. Ignore the frame content
+		 * 2. argv[4] is not null, then it must be a valid mac
+		 *    If argv[4] is null, then set 'addr' as null
+		 */
+		*content = NULL;
+		if (argv[4]) {
+			status = qdf_mac_parse(argv[4], addr);
+			if (QDF_IS_STATUS_ERROR(status))
+				iot_sim_err("iot_sim: argv4 is invalid mac for 0 len");
+		} else {
+			qdf_mem_zero(addr, QDF_MAC_ADDR_SIZE);
+			status = QDF_STATUS_SUCCESS;
+		}
+		/*
+		 * No need to parse further just return.
+		 */
+		return status;
+	}
+
+	/*
+	 * If argv[4] is valid, this implies frame content
+	 */
+	if (argv[4]) {
+		status = iot_sim_handle_frame_content(isc, argv[4],
+						      content, *offset,
+						      *length);
+		if (QDF_IS_STATUS_ERROR(status))
+			return status;
+	}
+
+	/*
+	 * If argv[5] is valid, this must be mac address
+	 */
+	if (argv[5])
+		status = qdf_mac_parse(argv[5], addr);
+
+	return status;
+err:
+	iot_sim_err("kstrtoXX failed: %d", ret);
+	return status;
+}
+
+/*
+ * iot_sim_del_cnt_cng_rule_peer - function to delete content change rule
+ * @peer: iot sim peer
+ * @type: 802.11 frame type
+ * @subtype: 802.11 frame subtype
+ * @seq: authentication sequence number, mostly 0 for non-authentication frame
+ * @oper: iot sim operation
+ *
+ * Return: QDF_STATUS_SUCCESS
+ */
+QDF_STATUS
+iot_sim_del_cnt_cng_rule_peer(struct iot_sim_rule_per_peer *peer,
+			      uint8_t type, uint8_t subtype,
+			      uint16_t seq, enum iot_sim_operations oper)
+{
+	/* seq entries and frame entries */
+	struct iot_sim_rule_per_seq *s_e;
+	struct iot_sim_rule *f_e;
+	uint8_t bm;
+
+	qdf_spin_lock(&peer->iot_sim_lock);
+	s_e = peer->rule_per_seq[seq];
+	if (!s_e) {
+		qdf_spin_unlock(&peer->iot_sim_lock);
+		iot_sim_info("s_e is null");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	f_e = s_e->rule_per_type[type][subtype];
+	if (f_e && f_e->frm_content) {
+		qdf_mem_free(f_e->frm_content);
+		f_e->frm_content = NULL;
+		bm = f_e->rule_bitmap;
+		s_e->use_count--;
+		if (IOT_SIM_CLEAR_OP_BIT(bm, oper)) {
+			qdf_mem_free(f_e);
+			s_e->rule_per_type[type][subtype] = NULL;
+		}
+		if (s_e->use_count == 0) {
+			qdf_mem_free(s_e);
+			peer->rule_per_seq[seq] = NULL;
+		}
+	}
+	qdf_spin_unlock(&peer->iot_sim_lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * iot_sim_delete_rule_for_mac - function to delete content change rule
+ *				 for given peer mac
+ * @isc: iot sim context
+ * @oper: iot sim operation
+ * @seq: authentication sequence number, mostly 0 for non-authentication frame
+ * @type: 802.11 frame type
+ * @subtype: 802.11 frame subtype
+ * @mac: peer mac address
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE otherwise
+ */
+QDF_STATUS
+iot_sim_delete_rule_for_mac(struct iot_sim_context *isc,
+			    enum iot_sim_operations oper,
+			    uint16_t seq, uint8_t type,
+			    uint8_t subtype,
+			    struct qdf_mac_addr *mac)
+{
+	QDF_STATUS ret = QDF_STATUS_SUCCESS;
+
+	if (qdf_is_macaddr_zero(mac))
+		iot_sim_info("Rule deletion for all peers");
+	else
+		iot_sim_info("Rule deletion for " QDF_MAC_ADDR_STR,
+			     QDF_MAC_ADDR_ARRAY(mac->bytes));
+	iot_sim_info("oper:%u type:%hu subtype:%hu seq:%hu", oper, type,
+		     subtype, seq);
+
+	if (!isc) {
+		iot_sim_err("iot_sim: isc is null");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (oper == CONTENT_CHANGE) {
+		if (qdf_is_macaddr_broadcast(mac)) {
+			/*
+			 * Clear rules for bcast peer
+			 */
+			ret = iot_sim_del_cnt_cng_rule_peer(&isc->bcast_peer,
+							    type, subtype,
+							    seq, oper);
+		} else if (qdf_is_macaddr_zero(mac)) {
+			/*
+			 * Zero mac address, rules will be deleted
+			 * for all peer and including for bcast peer
+			 */
+
+			/*
+			 * Clear rules for bcast peer
+			 */
+			ret = iot_sim_del_cnt_cng_rule_peer(&isc->bcast_peer,
+							    type, subtype,
+							    seq, oper);
+			/* Clear rules for individual peer
+			 * TBD
+			 */
+		} else {
+			/* TBD: clear the rules for peer with address 'mac'*/
+		}
+	} else if (oper == DROP) {
+		/* TBD */
+	} else if (oper == DELAY) {
+		/* TBD */
+	}
+	return ret;
+}
+
+/*
+ * iot_sim_add_cnt_cng_rule_peer - function to add content change rule on peer
+ * @peer: iot sim peer
+ * @type: 802.11 frame type
+ * @subtype: 802.11 frame subtype
+ * @seq: authentication sequence number, mostly 0 for non-authentication frame
+ * @frm: frame content to store
+ * @offset: offset value
+ * @len: length of frame content
+ * @oper: iot sim operation
+ *
+ * Return: QDF_STATUS_SUCCESS on success, failure otherwise
+ */
+QDF_STATUS
+iot_sim_add_cnt_cng_rule_peer(struct iot_sim_rule_per_peer *peer,
+			      uint8_t type, uint8_t subtype,
+			      uint16_t seq, uint8_t *frm,
+			      uint16_t offset, uint16_t len,
+			      enum iot_sim_operations oper)
+{
+	struct iot_sim_rule_per_seq *s_e = NULL;
+	struct iot_sim_rule *f_e = NULL;
+
+	qdf_spin_lock(&peer->iot_sim_lock);
+	s_e = peer->rule_per_seq[seq];
+	if (s_e) {
+		f_e = s_e->rule_per_type[type][subtype];
+		if (!f_e) {
+			f_e = qdf_mem_malloc(sizeof(struct iot_sim_rule));
+			if (!f_e) {
+				iot_sim_err("can't allocate f_e");
+				qdf_spin_unlock(&peer->iot_sim_lock);
+				return QDF_STATUS_E_NOMEM;
+			}
+			s_e->rule_per_type[type][subtype] = f_e;
+		}
+	} else {
+		s_e = qdf_mem_malloc(sizeof(struct iot_sim_rule_per_seq));
+		if (!s_e) {
+			qdf_spin_unlock(&peer->iot_sim_lock);
+			iot_sim_err("iot_sim: s_e is null");
+			return QDF_STATUS_E_NOMEM;
+		}
+
+		f_e = qdf_mem_malloc(sizeof(struct iot_sim_rule));
+		if (!f_e) {
+			qdf_mem_free(s_e);
+			peer->rule_per_seq[seq] = NULL;
+			qdf_spin_unlock(&peer->iot_sim_lock);
+			iot_sim_err("iot_sim: f_e is null");
+			return QDF_STATUS_E_NOMEM;
+		}
+
+		s_e->rule_per_type[type][subtype] = f_e;
+		peer->rule_per_seq[seq] = s_e;
+	}
+
+	f_e->frm_content = qdf_mem_malloc(len);
+	qdf_mem_copy(f_e->frm_content, frm, len);
+	f_e->len = len;
+	f_e->offset = offset;
+	s_e->use_count++;
+	IOT_SIM_SET_OP_BIT(f_e->rule_bitmap, oper);
+	qdf_spin_unlock(&peer->iot_sim_lock);
+
+	iot_sim_info("iot_sim:Rule added for mac: " QDF_MAC_ADDR_STR " oper:%u",
+		     QDF_MAC_ADDR_ARRAY(peer->addr.bytes), oper);
+	iot_sim_info("type:%x stype:%x sq:%hu off:%hu len:%hu",
+		     type, subtype, seq, offset, len);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * iot_sim_add_rule_for_mac - function to add content change rule
+ *			      for given peer mac
+ * @isc: iot sim context
+ * @oper: iot sim operation
+ * @mac: peer mac address
+ * @type: 802.11 frame type
+ * @subtype: 802.11 frame subtype
+ * @seq: authentication sequence number, mostly 0 for non-authentication frame
+ * @offset: user provided offset
+ * @frm: user provided frame content
+ * @length: length of frm
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE otherwise
+ */
+QDF_STATUS
+iot_sim_add_rule_for_mac(struct iot_sim_context *isc,
+			 enum iot_sim_operations oper,
+			 struct qdf_mac_addr *mac,
+			 uint8_t type, uint8_t subtype,
+			 uint16_t seq, uint16_t offset,
+			 uint8_t *frm, uint16_t len)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	if (!isc) {
+		iot_sim_err("iot_sim: isc is null");
+		return status;
+	}
+
+	if (oper == CONTENT_CHANGE) {
+		if (!frm)
+			return status;
+
+		status = iot_sim_delete_rule_for_mac(isc, oper, seq,
+						     type, subtype, mac);
+		if (status == QDF_STATUS_E_FAILURE) {
+			iot_sim_err("iot_sim: Rule removed - Fail");
+			return status;
+		}
+
+		if (qdf_is_macaddr_broadcast(mac)) {
+			iot_sim_add_cnt_cng_rule_peer(&isc->bcast_peer, type,
+						      subtype, seq, frm,
+						      offset, len, oper);
+		} else {
+			/*
+			 * Add entry to peer with MAC 'mac'
+			 */
+			/* TBD */
+		}
+	} else if (oper == DROP) {
+		/* TBD */
+	} else if (oper == DELAY) {
+		/* TBD */
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ *                   IOT SIM User Command Format
+ *
+ * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * | FrmType/subtype |  Seq  | Offset | Length | content | Mac Addr |
+ * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * |     1Byte       | 2Byte | 2Bytes | 2Bytes | Length  | 6 Bytes  |
+ *
+ */
+
+/*
+ * iot_sim_debug_content_change_write - Write Handler for content change
+ *					operation
+ * @file: debugfs file pointer
+ * @buf: buf of user input
+ * @count: buf count
+ * @ppos: offset on file
+ *
+ * Return: character read on success, failure otherwise
+ */
+static ssize_t
+iot_sim_debug_content_change_write(struct file *file,
+				   const char __user *buf,
+				   size_t count, loff_t *ppos)
+{
+	QDF_STATUS status;
+	unsigned char t_st, type, subtype, *content = NULL;
+	uint16_t offset = 0, length = 0, seq = 0;
+	char *locbuf;
+	enum iot_sim_operations oper = CONTENT_CHANGE;
+	struct qdf_mac_addr mac_addr = QDF_MAC_ADDR_BCAST_INIT;
+	struct iot_sim_context *isc =
+			((struct seq_file *)file->private_data)->private;
+
+	if ((!buf) || (count > USER_BUF_LEN) || (count < 7))
+		return -EFAULT;
+
+	locbuf = qdf_mem_malloc(USER_BUF_LEN + 1);
+	if (!locbuf)
+		return -ENOMEM;
+
+	if (copy_from_user(locbuf, buf, count)) {
+		qdf_mem_free(locbuf);
+		return -EFAULT;
+	}
+
+	status = iot_sim_parse_user_input_content_change(isc, locbuf, count,
+							 &t_st, &seq, &offset,
+							 &length, &content,
+							 &mac_addr);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		qdf_mem_free(locbuf);
+		return count;
+	}
+
+	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) {
+		qdf_mem_free(locbuf);
+		return -EFAULT;
+	}
+
+	/* check for rule removal */
+	if (!length || !content) {
+		status = iot_sim_delete_rule_for_mac(isc, oper, seq,
+						     type, subtype,
+						     &mac_addr);
+		if (QDF_IS_STATUS_ERROR(status))
+			iot_sim_err("iot_sim: Rule removed - Fail");
+		else
+			iot_sim_err("iot_sim: Rule removed - success");
+
+		qdf_mem_free(locbuf);
+		return count;
+	}
+
+	status = iot_sim_add_rule_for_mac(isc, oper, &mac_addr, type, subtype,
+					  seq, offset, content, length);
+
+	if (QDF_IS_STATUS_ERROR(status))
+		iot_sim_err("iot_sim: Rule Add - Fail");
+
+	qdf_mem_free(content);
+	qdf_mem_free(locbuf);
+	return count;
+}
+
+/*
+ * iot_sim_debug_delay_write - Write Handler for delay operation
+ * @file: debugfs file pointer
+ * @buf: buf of user input
+ * @count: buf count
+ * @ppos: offset on file
+ *
+ * Return: character read
+ */
+static ssize_t
+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");
+	return count;
+}
+
+/*
+ * iot_sim_debug_drop_write - Write Handler for drop operation
+ * @file: debugfs file pointer
+ * @buf: buf of user input
+ * @count: buf count
+ * @ppos: offset on file
+ *
+ * Return: character read
+ */
+static ssize_t
+iot_sim_debug_drop_write(struct file *file,
+			 const char __user *buf,
+			 size_t count, loff_t *ppos)
+{
+	iot_sim_err("drop iot sim ops called");
+	return count;
+}
+
+/*
+ * debug_iot_sim_##func_base##_show() - debugfs functions to display content
+ *                                      dummy function
+ * Return: success
+ */
+#define GENERATE_IOT_SIM_DEBUG_SHOW_FUNCS(func_base)			\
+	static int iot_sim_debug_##func_base##_show(struct seq_file *m,	\
+						    void *v)		\
+{									\
+	return qdf_status_to_os_return(QDF_STATUS_SUCCESS);		\
+}
+
+GENERATE_IOT_SIM_DEBUG_SHOW_FUNCS(content_change);
+GENERATE_IOT_SIM_DEBUG_SHOW_FUNCS(delay);
+GENERATE_IOT_SIM_DEBUG_SHOW_FUNCS(drop);
+
+/*
+ * debug_##func_base##_open() - Open debugfs entry for respective command
+ * and event buffer.
+ *
+ * @inode: node for debug dir entry
+ * @file: file handler
+ *
+ * Return: open status
+ */
+#define GENERATE_DEBUG_IOT_SIM_STRUCTS(func_base)			\
+	static int debug_##func_base##_open(struct inode *inode,	\
+					    struct file *file)		\
+{									\
+	return single_open(file, iot_sim_debug_##func_base##_show,	\
+			   inode->i_private);				\
+}									\
+									\
+static const struct file_operations debug_##func_base##_ops = {		\
+	.open           = debug_##func_base##_open,			\
+	.read           = seq_read,					\
+	.llseek         = seq_lseek,					\
+	.write          = iot_sim_debug_##func_base##_write,		\
+	.release        = single_release,				\
+}
+
+GENERATE_DEBUG_IOT_SIM_STRUCTS(content_change);
+GENERATE_DEBUG_IOT_SIM_STRUCTS(drop);
+GENERATE_DEBUG_IOT_SIM_STRUCTS(delay);
+
+/* Structure to maintain debug information */
+struct iot_sim_dbgfs_file {
+	const char *name;
+	const struct file_operations *ops;
+};
+
+#define DEBUG_IOT_SIM(func_base) {	.name = #func_base,		\
+					.ops = &debug_##func_base##_ops	\
+}
+
+struct iot_sim_dbgfs_file iot_sim_dbgfs_files[IOT_SIM_DEBUGFS_FILE_NUM] = {
+	DEBUG_IOT_SIM(content_change),
+	DEBUG_IOT_SIM(drop),
+	DEBUG_IOT_SIM(delay),
+};
+
+QDF_STATUS
+iot_sim_control_cmn(struct wlan_objmgr_pdev *pdev, wbuf_t wbuf)
 {
 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
 	struct iot_sim_context *isc;
 
-	if (!psoc) {
+	if (!pdev) {
 		iot_sim_err("PDEV is NULL!");
 		goto bad;
 	}
 
-	isc = iot_sim_get_ctx_from_psoc(psoc);
+	isc = iot_sim_get_ctx_from_pdev(pdev);
 	if (!isc) {
 		iot_sim_err("iot_sim context is NULL!");
 		goto bad;
@@ -53,52 +712,180 @@ iot_sim_ctx_deinit(struct iot_sim_context *isc)
 		isc->iot_sim_operation_handler = NULL;
 }
 
+/**
+ * iot_sim_debugfs_deinit() - Deinit functions to remove debugfs directory and
+ *			      it's file enteries.
+ * @isc: iot_sim context
+ *
+ * Return: init status
+ */
+static QDF_STATUS
+iot_sim_debugfs_deinit(struct iot_sim_context *isc)
+{
+	debugfs_remove_recursive(isc->iot_sim_dbgfs_ctx.iot_sim_dir_de);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/*
+ * iot_sim_remove_all_oper_rules - Function to remove all configured rules
+ *				   for given operation
+ *
+ * @isc: iot sim context
+ * @oper: iot sim operation
+ *
+ * Return: void
+ */
+static void
+iot_sim_remove_all_oper_rules(struct iot_sim_context *isc,
+			      enum iot_sim_operations oper)
+{
+	uint16_t seq;
+	uint8_t type, subtype;
+	struct qdf_mac_addr zero_mac_addr = QDF_MAC_ADDR_ZERO_INIT;
+
+	for (seq = 0; seq < MAX_SEQ; seq++)
+		for (type = 0; type < N_FRAME_TYPE; type++)
+			for (subtype = 0; subtype < N_FRAME_SUBTYPE; subtype++)
+				iot_sim_delete_rule_for_mac(isc, oper, seq,
+							    type, subtype,
+							    &zero_mac_addr);
+}
+
+/*
+ * iot_sim_remove_all_rules - Function to remove all configured rules
+ *
+ * @isc: iot sim context
+ *
+ * Return: void
+ */
+static void
+iot_sim_remove_all_rules(struct iot_sim_context *isc)
+{
+	enum iot_sim_operations oper;
+
+	if (!isc)
+		return;
+
+	for (oper = CONTENT_CHANGE; oper < IOT_SIM_MAX_OPERATION; oper++)
+		iot_sim_remove_all_oper_rules(isc, oper);
+}
+
+/**
+ * iot_sim_debugfs_init() - debugfs functions to create debugfs directory and to
+ *			    create debugfs enteries.
+ * @isc: iot_sim context
+ *
+ * Return: init status
+ */
+static QDF_STATUS
+iot_sim_debugfs_init(struct iot_sim_context *isc)
+{
+	struct dentry *dbgfs_dir = NULL;
+	struct dentry *de = NULL;
+	uint8_t i, pdev_id;
+	char buf[32];
+
+	if (!isc)
+		return QDF_STATUS_E_FAILURE;
+
+	pdev_id = wlan_objmgr_pdev_get_pdev_id(isc->pdev_obj);
+
+	qdf_mem_zero(buf, sizeof(buf));
+	snprintf(buf, sizeof(buf), "iot_sim_pdev%u", pdev_id);
+
+	dbgfs_dir = debugfs_create_dir(buf, NULL);
+	isc->iot_sim_dbgfs_ctx.iot_sim_dir_de = dbgfs_dir;
+
+	if (!isc->iot_sim_dbgfs_ctx.iot_sim_dir_de) {
+		iot_sim_err("dbgfs dir creation failed for pdev%u", pdev_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	for (i = 0; i < IOT_SIM_DEBUGFS_FILE_NUM; ++i) {
+		de = debugfs_create_file(iot_sim_dbgfs_files[i].name,
+					 0644,
+					 dbgfs_dir, isc,
+					 iot_sim_dbgfs_files[i].ops);
+
+		if (!de) {
+			iot_sim_err("dbgfs file creation failed for pdev%u",
+				    pdev_id);
+			goto out;
+		}
+		isc->iot_sim_dbgfs_ctx.iot_sim_file_de[i] = de;
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+out:
+	debugfs_remove_recursive(dbgfs_dir);
+	qdf_mem_set(isc->iot_sim_dbgfs_ctx.iot_sim_file_de,
+		    sizeof(isc->iot_sim_dbgfs_ctx.iot_sim_file_de), 0);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
 QDF_STATUS
-wlan_iot_sim_psoc_obj_create_handler(struct wlan_objmgr_psoc *psoc, void *arg)
+wlan_iot_sim_pdev_obj_create_handler(struct wlan_objmgr_pdev *pdev, void *arg)
 {
 	struct iot_sim_context *isc = NULL;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
 
-	if (!psoc) {
-		iot_sim_err("PSOC is NULL");
+	if (!pdev) {
+		iot_sim_err("pdev is NULL");
 		return QDF_STATUS_E_NULL_VALUE;
 	}
 
-	isc = (struct iot_sim_context *)
-	    qdf_mem_malloc(sizeof(struct iot_sim_context));
+	isc = qdf_mem_malloc(sizeof(struct iot_sim_context));
 	if (!isc)
 		return QDF_STATUS_E_NOMEM;
 
-	isc->psoc_obj = psoc;
-	wlan_objmgr_psoc_component_obj_attach(psoc, WLAN_IOT_SIM_COMP,
+	isc->pdev_obj = pdev;
+
+	if (QDF_IS_STATUS_ERROR(iot_sim_debugfs_init(isc))) {
+		qdf_mem_free(isc);
+		iot_sim_info("iot_sim debugfs file creation failed");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_set_macaddr_broadcast(&isc->bcast_peer.addr);
+	qdf_spinlock_create(&isc->bcast_peer.iot_sim_lock);
+	qdf_list_create(&isc->bcast_peer.p_list, 0);
+
+	wlan_objmgr_pdev_component_obj_attach(pdev, WLAN_IOT_SIM_COMP,
 					      (void *)isc, QDF_STATUS_SUCCESS);
 
-	iot_sim_info("iot_sim component psoc object created");
+	iot_sim_err("iot_sim component pdev object created");
 
-	return QDF_STATUS_SUCCESS;
+	return status;
 }
 
 QDF_STATUS
-wlan_iot_sim_psoc_obj_destroy_handler(struct wlan_objmgr_psoc *psoc,
+wlan_iot_sim_pdev_obj_destroy_handler(struct wlan_objmgr_pdev *pdev,
 				      void *arg)
 {
 	struct iot_sim_context *isc = NULL;
 
-	if (!psoc) {
-		iot_sim_err("PSOC is NULL");
+	if (!pdev) {
+		iot_sim_err("pdev is NULL");
 		return QDF_STATUS_E_NULL_VALUE;
 	}
 
-	isc = wlan_objmgr_psoc_get_comp_private_obj(psoc,
+	isc = wlan_objmgr_pdev_get_comp_private_obj(pdev,
 						    WLAN_IOT_SIM_COMP);
 	if (isc) {
-		wlan_objmgr_psoc_component_obj_detach(psoc,
+		wlan_objmgr_pdev_component_obj_detach(pdev,
 						      WLAN_IOT_SIM_COMP,
 						      (void *)isc);
 		/* Deinitilise function pointers from iot_sim context */
 		iot_sim_ctx_deinit(isc);
+		iot_sim_debugfs_deinit(isc);
+		iot_sim_remove_all_rules(isc);
+		qdf_spinlock_destroy(&isc->bcast_peer.iot_sim_lock);
 		qdf_mem_free(isc);
 	}
-	iot_sim_info("iot_sim component psoc object destroyed");
+	iot_sim_err("iot_sim component pdev object destroyed");
 
 	return QDF_STATUS_SUCCESS;
 }

+ 68 - 19
iot_sim/core/iot_sim_defs_i.h

@@ -19,7 +19,7 @@
 
 #include <wlan_objmgr_cmn.h>
 #include <wlan_objmgr_global_obj.h>
-#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_objmgr_pdev_obj.h>
 #include <qdf_list.h>
 #include <qdf_util.h>
 #include <qdf_types.h>
@@ -74,46 +74,95 @@
 #define N_FRAME_TYPE 0x4
 #define N_FRAME_SUBTYPE 0xF
 #define MAX_SEQ 0x4
+#define IOT_SIM_DEBUGFS_FILE_NUM 3
 
-/* struct iot_sim_content - represent user content
+/*
+ * struct iot_sim_debugfs - contains dentry pointer for opened
+ *			    iot sim files and directory
+ * @iot_sim_dir_de - dentry pointer to pdev specific folder
+ * @iot_sim_file_de - dentry pointer representing operation specific files
+ */
+struct iot_sim_debugfs {
+	struct dentry *iot_sim_dir_de;
+	struct dentry *iot_sim_file_de[IOT_SIM_DEBUGFS_FILE_NUM];
+};
+
+/*
+ * struct iot_sim_rule - represent user configured rules
  * @len - Length of the content provided by user
  * @offset - offset at which modification done in capture frame
  * @frm_content - actual user data in hex
  * @drop - frame marked for drop
  * @delay_dur - duration of delay
  */
-struct iot_sim_content {
+struct iot_sim_rule {
 	uint16_t len;
 	uint16_t offset;
 	uint8_t *frm_content;
 	bool drop;
 	uint16_t delay_dur;
+	uint8_t rule_bitmap;
 };
 
-/* Per Peer iot_sim data per frame type/subtype */
-struct iot_sim_fb_array_peer {
-	struct qdf_mac_addr peer_addr;
-	struct iot_sim_content iot_sim_fb_array[N_FRAME_TYPE][N_FRAME_SUBTYPE];
-	qdf_list_t p_list;
+/*
+ * struct iot_sim_rule_per_seq - rule structure per sequence iot sim files
+ *				 and directory
+ *
+ * @rule_per_type - 2d array of iot_sim_rule per type subtype
+ * @use_count - usage reference
+ */
+struct iot_sim_rule_per_seq {
+	struct iot_sim_rule *rule_per_type[N_FRAME_TYPE][N_FRAME_SUBTYPE];
+	uint8_t use_count;
 };
 
-/**
- * struct iot_sim_context - iot_sim psoc private object
- * @psoc_obj:Reference to psoc global object
- * @iot_sim_lock: spinlock for synchronization
+/*
+ * struct iot_sim_rule_per_peer - peer specific structure for iot sim ops
  *
- * Call back functions
- * @iot_sim_opertion_handler: iot sim operations handler
+ * @addr - address of peer
+ * @iot_sim_lock - spinlock
+ * @rule_per_seq - array of iot_sim_rule_per_seq
+ * @p_list - list variable
  */
+struct iot_sim_rule_per_peer {
+	struct qdf_mac_addr addr;
+	qdf_spinlock_t iot_sim_lock;
+	struct iot_sim_rule_per_seq *rule_per_seq[MAX_SEQ];
+	qdf_list_t p_list;
+};
 
+/**
+ * struct iot_sim_context - iot_sim pdev private object
+ * @pdev_obj:Reference to pdev global object
+ * @iot_sim_peer_list: peer list for peer specific rules
+ * @bcast_peer: broadcast peer entry for storing rules for all peers
+ * @p_iot_sim_target_handle: handle to iot_sim target_if
+ * @iot_sim_operation_handler: callback for iot sim operation handler
+ */
 struct iot_sim_context {
-	struct wlan_objmgr_psoc *psoc_obj;
-	qdf_spinlock_t iot_sim_lock;
-	/* IOT_SIM Peer list */
-	struct iot_sim_fb_arrary_peer *iot_sim_peer_list;
+	struct wlan_objmgr_pdev *pdev_obj;
+	/* IOT_SIM Peer list & Bcast Peer */
+	struct iot_sim_rule_per_peer *iot_sim_peer_list, bcast_peer;
 	void *p_iot_sim_target_handle;
-	QDF_STATUS (*iot_sim_operation_handler)(struct wlan_objmgr_psoc *psoc,
+	struct iot_sim_debugfs iot_sim_dbgfs_ctx;
+	QDF_STATUS (*iot_sim_operation_handler)(struct wlan_objmgr_pdev *pdev,
 						wbuf_t wbuf);
 };
 
+/* enum iot_sim_operations - iot sim operations
+ *
+ * @INVALID_OPERATION - invalid operation
+ * @CONTENT_CHANGE - Frame Content Change operation
+ * @DROP - Frame drop operation
+ * @DELAY - Frame delay operation
+ * @IOT_SIM_MAX_OPERATION - iot sim max operation
+ */
+enum iot_sim_operations {
+	INVALID_OPERATION,
+	CONTENT_CHANGE = 1,
+	DROP,
+	DELAY,
+	IOT_SIM_MAX_OPERATION
+};
+
 #endif /* _IOT_SIM_DEFS_I_H_ */

+ 5 - 5
iot_sim/dispatcher/src/wlan_iot_sim_tgt_api.c

@@ -18,18 +18,18 @@
 #include <wlan_iot_sim_utils_api.h>
 
 void *
-tgt_get_target_handle(struct wlan_objmgr_psoc *psoc)
+tgt_get_target_handle(struct wlan_objmgr_pdev *pdev)
 {
 	struct iot_sim_context *isc;
 
-	if (!psoc) {
-		iot_sim_err("psoc is NULL!");
+	if (!pdev) {
+		iot_sim_err("pdev is NULL!");
 		return NULL;
 	}
-	isc = wlan_objmgr_psoc_get_comp_private_obj(psoc,
+	isc = wlan_objmgr_pdev_get_comp_private_obj(pdev,
 						    WLAN_IOT_SIM_COMP);
 	if (!isc) {
-		iot_sim_err("psoc IOT_SIM object is NULL!");
+		iot_sim_err("pdev IOT_SIM object is NULL!");
 		return NULL;
 	}
 	return isc->p_iot_sim_target_handle;

+ 8 - 8
iot_sim/dispatcher/src/wlan_iot_sim_utils_api.c

@@ -22,16 +22,16 @@
 QDF_STATUS
 wlan_iot_sim_init(void)
 {
-	if (wlan_objmgr_register_psoc_create_handler(
+	if (wlan_objmgr_register_pdev_create_handler(
 		WLAN_IOT_SIM_COMP,
-		wlan_iot_sim_psoc_obj_create_handler,
+		wlan_iot_sim_pdev_obj_create_handler,
 		NULL) !=
 	    QDF_STATUS_SUCCESS) {
 		return QDF_STATUS_E_FAILURE;
 	}
-	if (wlan_objmgr_register_psoc_destroy_handler(
+	if (wlan_objmgr_register_pdev_destroy_handler(
 		WLAN_IOT_SIM_COMP,
-		wlan_iot_sim_psoc_obj_destroy_handler,
+		wlan_iot_sim_pdev_obj_destroy_handler,
 		NULL) !=
 	    QDF_STATUS_SUCCESS) {
 		return QDF_STATUS_E_FAILURE;
@@ -43,16 +43,16 @@ wlan_iot_sim_init(void)
 QDF_STATUS
 wlan_iot_sim_deinit(void)
 {
-	if (wlan_objmgr_unregister_psoc_create_handler(
+	if (wlan_objmgr_unregister_pdev_create_handler(
 		WLAN_IOT_SIM_COMP,
-		wlan_iot_sim_psoc_obj_create_handler,
+		wlan_iot_sim_pdev_obj_create_handler,
 		NULL) !=
 	    QDF_STATUS_SUCCESS) {
 		return QDF_STATUS_E_FAILURE;
 	}
-	if (wlan_objmgr_unregister_psoc_destroy_handler(
+	if (wlan_objmgr_unregister_pdev_destroy_handler(
 		WLAN_IOT_SIM_COMP,
-		wlan_iot_sim_psoc_obj_destroy_handler,
+		wlan_iot_sim_pdev_obj_destroy_handler,
 		NULL) !=
 	    QDF_STATUS_SUCCESS) {
 		return QDF_STATUS_E_FAILURE;