xref: /wlan-dirver/qca-wifi-host-cmn/iot_sim/core/iot_sim_common.c (revision 54ab05a36f58e470e5b322a774385b90ea47f785)
1 /*
2  * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
3  * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include "iot_sim_cmn_api_i.h"
19 #include "iot_sim_defs_i.h"
20 #include "wlan_iot_sim_tgt_api.h"
21 #include <qdf_mem.h>
22 #include <qdf_types.h>
23 #include <qdf_util.h>
24 #include <qdf_str.h>
25 #include <qdf_delayed_work.h>
26 #include <wmi_unified_param.h>
27 #include <wlan_iot_sim_utils_api.h>
28 #include <wlan_lmac_if_api.h>
29 #include <wlan_objmgr_peer_obj.h>
30 
31 /*
32  * iot_sim_oper_to_str - function to return iot sim operation string
33  * @oper: iot sim operation
34  *
35  * Return: string pointer
36  */
37 uint8_t *
38 iot_sim_oper_to_str(enum iot_sim_operations oper)
39 {
40 	switch (oper) {
41 	case CONTENT_CHANGE:
42 		return "content change";
43 	case DELAY:
44 		return "delay";
45 	case DROP:
46 		return "drop";
47 	default:
48 		return "invalid";
49 	}
50 }
51 
52 /*
53  * iot_sim_convert_offset_to_hex_str - function to convert offset into binary
54  * @offset: user provided offset value while action frame rule deletion
55  * @hex: buffer to store converted value
56  * @count: size of hex buffer
57  *
58  * Return: string pointer
59  */
60 QDF_STATUS
61 iot_sim_convert_offset_to_hex_str(uint16_t offset, uint8_t *hex, int8_t count)
62 {
63 	uint8_t temp[5];
64 	int ret;
65 
66 	snprintf(temp, sizeof(temp), "%04u", offset);
67 
68 	ret = qdf_hex_str_to_binary(hex, temp, count);
69 	if (ret == -1) {
70 		iot_sim_err("offset to hex conversion failed");
71 		return QDF_STATUS_E_FAILURE;
72 	}
73 
74 	return QDF_STATUS_SUCCESS;
75 }
76 
77 /*
78  * iot_sim_parse_action_frame - function to parse action frame to decode
79  *                              category and action code
80  *
81  * @length: length for content provided by user
82  * @offset: offset provided by user
83  * @content: user provided content
84  * @category: buffer to store iot specific category code
85  * @action: buffer to store iot specific action code
86  *
87  * Return: QDF_STATUS_SUCCESS on success otherwise failure
88  */
89 QDF_STATUS
90 iot_sim_parse_action_frame(uint16_t length, uint16_t offset, uint8_t *content,
91 			   uint8_t *category, uint8_t *action)
92 {
93 	QDF_STATUS status = QDF_STATUS_SUCCESS;
94 	uint8_t hex[2], *ptr = NULL;
95 
96 	if (!length) {
97 		status = iot_sim_convert_offset_to_hex_str(offset, hex,
98 							   sizeof(hex));
99 		if (QDF_IS_STATUS_ERROR(status))
100 			return status;
101 
102 		/* Offset represet category type and action type */
103 		status = iot_sim_get_index_for_action_frm(hex, category,
104 							  action, false);
105 		if (status == QDF_STATUS_E_FAULT) {
106 			iot_sim_err("Get indices for action failed");
107 			return status;
108 		}
109 	} else if (length && content) {
110 		/* if offset is zero, move ptr post header */
111 		if (offset == 0) {
112 			ptr = content + sizeof(struct ieee80211_frame);
113 		} else if (offset == sizeof(struct ieee80211_frame)) {
114 			ptr = content;
115 		} else {
116 			iot_sim_err("wrong offset for action frame content");
117 			return QDF_STATUS_E_FAILURE;
118 		}
119 		status = iot_sim_get_index_for_action_frm(ptr, category,
120 							  action, false);
121 	}
122 	return status;
123 }
124 
125 /*
126  * iot_sim_find_peer_from_mac - function to find the iot sim peer data
127  *                                    based on the mac address provided
128  *
129  * @isc: iot_sim pdev private object
130  * @mac: mac address of the peer
131  *
132  * Return: iot_sim_rule_per_peer reference if exists else NULL
133  */
134 struct iot_sim_rule_per_peer *
135 iot_sim_find_peer_from_mac(struct iot_sim_context *isc,
136 			   struct qdf_mac_addr *mac)
137 {
138 	struct iot_sim_rule_per_peer *peer_rule = NULL;
139 	qdf_list_node_t *node = NULL, *next_node = NULL;
140 
141 	if (qdf_is_macaddr_zero(mac) || qdf_is_macaddr_broadcast(mac))
142 		return &isc->bcast_peer;
143 	else {
144 		if (qdf_list_empty(&isc->peer_list)) {
145 			iot_sim_debug("peer_list empty");
146 			return NULL;
147 		}
148 
149 		qdf_spin_lock_bh(&isc->iot_sim_lock);
150 		if (QDF_STATUS_SUCCESS !=
151 		    qdf_list_peek_front(&isc->peer_list, &next_node)) {
152 			qdf_spin_unlock_bh(&isc->iot_sim_lock);
153 			iot_sim_err("Failed to get peer rule from peer_list");
154 			return NULL;
155 		}
156 
157 		do {
158 			node = next_node;
159 			peer_rule =
160 				qdf_container_of(node,
161 						 struct iot_sim_rule_per_peer,
162 						 node);
163 			if (qdf_is_macaddr_equal(&peer_rule->addr, mac)) {
164 				qdf_spin_unlock_bh(&isc->iot_sim_lock);
165 				return peer_rule;
166 			}
167 		} while (QDF_STATUS_SUCCESS ==
168 			 qdf_list_peek_next(&isc->peer_list, node, &next_node));
169 
170 		qdf_spin_unlock_bh(&isc->iot_sim_lock);
171 		iot_sim_debug("Failed to find peer");
172 	}
173 
174 	return NULL;
175 }
176 
177 /*
178  * iot_sim_add_peer - function to add the iot sim peer data
179  *
180  * @isc: iot_sim pdev private object
181  * @mac: mac address of the peer
182  *
183  * Return: iot_sim_rule_per_peer reference
184  */
185 struct iot_sim_rule_per_peer *
186 iot_sim_add_peer(struct iot_sim_context *isc, struct qdf_mac_addr *mac)
187 {
188 	struct iot_sim_rule_per_peer *peer_rule = NULL;
189 	QDF_STATUS status;
190 
191 	if (qdf_is_macaddr_zero(mac) || qdf_is_macaddr_broadcast(mac)) {
192 		iot_sim_err("called iot_sim_add_peer for broadcast address");
193 		return &isc->bcast_peer;
194 	}
195 
196 	qdf_spin_lock_bh(&isc->iot_sim_lock);
197 	if (qdf_list_size(&isc->peer_list) < MAX_PEER_COUNT) {
198 		peer_rule = qdf_mem_malloc(sizeof
199 					   (struct iot_sim_rule_per_peer));
200 		if (!peer_rule) {
201 			iot_sim_err("Memory alloc failed for peer: "
202 				    QDF_MAC_ADDR_FMT,
203 				    QDF_MAC_ADDR_REF(mac->bytes));
204 			goto rel_lock;
205 		}
206 
207 		qdf_copy_macaddr(&peer_rule->addr, mac);
208 		status = qdf_list_insert_back(&isc->peer_list,
209 					      &peer_rule->node);
210 		if (QDF_IS_STATUS_ERROR(status)) {
211 			iot_sim_err("peer_list enqueue failed for peer "
212 				    QDF_MAC_ADDR_FMT,
213 				    QDF_MAC_ADDR_REF(mac->bytes));
214 			qdf_mem_free(peer_rule);
215 			peer_rule = NULL;
216 		}
217 	} else {
218 		iot_sim_err("peer_list  already reached max limit");
219 	}
220 
221 rel_lock:
222 	qdf_spin_unlock_bh(&isc->iot_sim_lock);
223 	return peer_rule;
224 }
225 
226 /*
227  * iot_sim_remove_peer - function to remove the iot sim peer data
228  *
229  * @isc: iot_sim pdev private object
230  * @mac: mac address of the peer
231  *
232  * Return: void
233  */
234 void iot_sim_remove_peer(struct iot_sim_context *isc,
235 			 struct iot_sim_rule_per_peer *peer_rule)
236 {
237 	qdf_spin_lock_bh(&isc->iot_sim_lock);
238 	qdf_list_remove_node(&isc->peer_list, &peer_rule->node);
239 	qdf_spin_unlock_bh(&isc->iot_sim_lock);
240 }
241 
242 /*
243  * iot_sim_validate_content - function to validate frame content. User provided
244  *			      content must be either full frame or full frame
245  *			      body or valid TLV formatted data.
246  * @buf: pointer to frame content in binary format
247  * @total_len: length of content
248  * @offset: offset provided by user
249  *
250  * Return: QDF_STATUS_SUCCESS on success
251  *	   QDF_STATUS_E_FAULT on failure
252  */
253 static QDF_STATUS
254 iot_sim_validate_content(uint8_t *buf,
255 			 uint16_t total_len,
256 			 uint16_t offset)
257 {
258 	char *ie = buf;
259 	uint32_t len = 0, i = 0;
260 	uint32_t fb = sizeof(struct ieee80211_frame);
261 
262 	if (offset == 0 || offset == fb) {
263 		/* Replace the entire content set by user */
264 		return QDF_STATUS_SUCCESS;
265 	}
266 
267 	/* Check for malformed IEs and proper IE
268 	 * boundaries in user content
269 	 */
270 	for (i = 0; i < total_len;) {
271 		/* TLV: T(1) + L(1) + V(L)*/
272 		len = (1 + 1 + ie[1]);
273 		i += len;
274 		ie += len;
275 	}
276 
277 	if (i == total_len)
278 		return QDF_STATUS_SUCCESS;
279 
280 	iot_sim_err("iot_sim: cnt(bin) len:%u IE Parsed len:%u",
281 		    total_len,
282 		    i);
283 
284 	return QDF_STATUS_E_INVAL;
285 }
286 
287 /*
288  * iot_sim_handle_frame_content - function to process frame content provided
289  *				  by user. This function will convert the ascii
290  *				  string into binary string and validate the
291  *				  content.
292  * @isc: iot sim context
293  * @pos: position to the frame content in the user buffer
294  * @storage: storage to store frame content after processing
295  * @offset: user provided offset
296  * @len: length of the user provided content in bytes
297  *
298  * Return: QDF_STATUS_SUCCESS on success
299  *	   QDF_STATUS_E_FAULT on hex str to binary conversion failure
300  *	   QDF_STATUS_E_NOMEM on memory allocation failure
301  */
302 QDF_STATUS
303 iot_sim_handle_frame_content(struct iot_sim_context *isc,
304 			     const char *pos,
305 			     uint8_t **storage,
306 			     uint16_t offset,
307 			     uint16_t len)
308 {
309 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
310 	int ret;
311 
312 	*storage = qdf_mem_malloc(len);
313 	if (!*storage) {
314 		iot_sim_err("iot_sim:storage allocation failed");
315 		return QDF_STATUS_E_NOMEM;
316 	}
317 
318 	ret = qdf_hex_str_to_binary(*storage, pos, len);
319 	if (ret == -1) {
320 		iot_sim_err("iot_sim:hex2bin conversion failed");
321 		status = QDF_STATUS_E_FAULT;
322 		goto error;
323 	}
324 
325 	status = iot_sim_validate_content(*storage, len, offset);
326 	if (QDF_IS_STATUS_ERROR(status)) {
327 		iot_sim_err("iot_sim:User Content Invalid");
328 		goto error;
329 	}
330 
331 	return QDF_STATUS_SUCCESS;
332 
333 error:
334 	qdf_mem_free(*storage);
335 	*storage = NULL;
336 	return status;
337 }
338 
339 /*
340  * iot_sim_parse_user_input_content_change - function to parse user input into
341  *					     predefined format for content
342  *					     change operation. All arguments
343  *					     passed will be filled upon success
344  * @isc: iot sim context
345  * @userbuf: local copy of user input
346  * @count: length of userbuf
347  * @t_st: address of type variable
348  * @seq: address of seq variable
349  * @offset: address of offset variable
350  * @length: address of length variable
351  * @content: double pointer to storage to store frame content after processing
352  * @addr: pointer to mac address
353  *
354  * @storage: storage to store frame content after processing
355  * @offset: user provided offset
356  * @len: length of the user provided content in bytes
357  *
358  * Return: QDF_STATUS_SUCCESS on success
359  *	   QDF_STATUS_E_FAILURE otherwise
360  */
361 QDF_STATUS
362 iot_sim_parse_user_input_content_change(struct iot_sim_context *isc,
363 					char *userbuf, ssize_t count,
364 					uint8_t *t_st, uint16_t *seq,
365 					uint16_t *offset, uint16_t *length,
366 					uint8_t **content,
367 					struct qdf_mac_addr *addr)
368 {
369 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
370 	char *argv[6], *delim = " ", *substr;
371 	int argc = -1, ret = 0;
372 
373 	qdf_mem_zero(argv, sizeof(argv));
374 	userbuf = qdf_str_trim(userbuf);
375 
376 	while ((substr = qdf_str_sep(&userbuf, delim)) != NULL) {
377 		if (!isspace(*substr) && *substr != '\0')
378 			argv[++argc] = substr;
379 		if (argc >= 5)
380 			break;
381 	}
382 
383 	if (argc < 3) {
384 		iot_sim_err("Invalid argument count %d", (argc + 1));
385 		return status;
386 	}
387 
388 	if (!argv[0] || !argv[1] || !argv[2] || !argv[3]) {
389 		iot_sim_err("One or more arguments are null");
390 		return status;
391 	}
392 
393 	ret = kstrtou8(argv[0], 16, t_st);
394 	if (ret)
395 		goto err;
396 	ret = kstrtou16(argv[1], 10, seq);
397 	if (ret)
398 		goto err;
399 	ret = kstrtou16(argv[2], 10, offset);
400 	if (ret)
401 		goto err;
402 	ret = kstrtou16(argv[3], 10, length);
403 	if (ret)
404 		goto err;
405 	/*
406 	 * User can send content change data in following format:
407 	 * 1. Add rule for specific peer
408 	 *	<t_st> <seq> <offset> <length> <content> <MAC>
409 	 * 2. Add rule for broadcast peer
410 	 *	<t_st> <seq> <offset> <length> <content>
411 	 * 3. Remove rule for specific peer
412 	 *	<t_st> <seq> <offset> <length> <MAC>
413 	 * 4. Remove rule for broadcast peer
414 	 *	<t_st> <seq> <offset> <length>
415 	 */
416 
417 	/*
418 	 * If length is 0, this implies remove the rule
419 	 */
420 	if (!*length) {
421 		/*
422 		 * 1. Ignore the frame content
423 		 * 2. argv[4] is not null, then it must be a valid mac
424 		 *    If argv[4] is null, then set 'addr' as null
425 		 */
426 		*content = NULL;
427 		if (argv[4]) {
428 			status = qdf_mac_parse(argv[4], addr);
429 			if (QDF_IS_STATUS_ERROR(status))
430 				iot_sim_err("iot_sim: argv4 is invalid mac for 0 len");
431 		} else {
432 			qdf_mem_zero(addr, QDF_MAC_ADDR_SIZE);
433 			status = QDF_STATUS_SUCCESS;
434 		}
435 		/*
436 		 * No need to parse further just return.
437 		 */
438 		return status;
439 	}
440 
441 	/*
442 	 * If argv[4] is valid, this implies frame content
443 	 */
444 	if (argv[4]) {
445 		status = iot_sim_handle_frame_content(isc, argv[4],
446 						      content, *offset,
447 						      *length);
448 		if (QDF_IS_STATUS_ERROR(status))
449 			return status;
450 	}
451 
452 	/*
453 	 * If argv[5] is valid, this must be mac address
454 	 */
455 	if (argv[5]) {
456 		status = qdf_mac_parse(argv[5], addr);
457 		if (QDF_IS_STATUS_ERROR(status))
458 			qdf_mem_free(content);
459 	}
460 
461 	return status;
462 err:
463 	iot_sim_err("kstrtoXX failed: %d", ret);
464 	return status;
465 }
466 
467 /*
468  * iot_sim_get_index_for_action_frm - function to convert 802.11 action frame
469  *				      category and action code into iot sim
470  *				      specific code.
471  *
472  * @frm: buf containing 802.11 action/category codes
473  * @cat_type: buf to hold converted category code
474  * @act_type: buf to hold converted action code
475  * @rx: TRUE if its getting called in the rx path
476  *
477  * Return: QDF_STATUS_SUCCESS on success, failure otherwise
478  */
479 QDF_STATUS
480 iot_sim_get_index_for_action_frm(uint8_t *frm, uint8_t *cat_type,
481 				 uint8_t *act_type, bool rx)
482 {
483 	uint8_t category, action;
484 
485 	category = ((struct ieee80211_action *)(frm))->ia_category;
486 	action = ((struct ieee80211_action *)(frm))->ia_action;
487 
488 	iot_sim_info("category %x action %x", category, action);
489 
490 	switch (category) {
491 	case IEEE80211_ACTION_CAT_BA:
492 		switch (action) {
493 		case IEEE80211_ACTION_BA_ADDBA_REQUEST:
494 			if (rx) {
495 				*cat_type = CAT_BA;
496 				*act_type = action;
497 
498 			} else {
499 				*cat_type = category;
500 				*act_type = action;
501 			}
502 			break;
503 		case IEEE80211_ACTION_BA_ADDBA_RESPONSE:
504 		case IEEE80211_ACTION_BA_DELBA:
505 			*cat_type = CAT_BA;
506 			*act_type = action;
507 			break;
508 		default:
509 			return QDF_STATUS_E_FAULT;
510 		}
511 		break;
512 	case IEEE80211_ACTION_CAT_SA_QUERY:
513 		switch (action) {
514 		case IEEE80211_ACTION_SA_QUERY_REQUEST:
515 		case IEEE80211_ACTION_SA_QUERY_RESPONSE:
516 			*cat_type = CAT_SA_QUERY;
517 			*act_type = action;
518 			break;
519 		default:
520 			return QDF_STATUS_E_FAULT;
521 		}
522 		break;
523 	case IEEE80211_ACTION_CAT_RADIO:
524 		*cat_type = CAT_RADIO;
525 		*act_type = action;
526 		break;
527 	case IEEE80211_ACTION_CAT_FAST_BSS_TRNST:
528 		*cat_type = CAT_FAST_BSS_TRNST;
529 		*act_type = action;
530 		break;
531 	case IEEE80211_ACTION_CAT_SPECTRUM:
532 		*cat_type = CAT_SPECTRUM;
533 		*act_type = action;
534 		break;
535 	case IEEE80211_ACTION_CAT_QOS:
536 		*cat_type = CAT_QOS;
537 		*act_type = action;
538 		break;
539 	case IEEE80211_ACTION_CAT_DLS:
540 		*cat_type = CAT_DLS;
541 		*act_type = action;
542 		break;
543 	case IEEE80211_ACTION_CAT_HT:
544 		*cat_type = CAT_HT;
545 		*act_type = action;
546 		break;
547 	case IEEE80211_ACTION_CAT_WNM:
548 		*cat_type = CAT_WNM;
549 		*act_type = action;
550 		break;
551 	case IEEE80211_ACTION_CAT_VHT:
552 		*cat_type = CAT_VHT;
553 		*act_type = action;
554 		break;
555 	default:
556 		return QDF_STATUS_E_FAULT;
557 	}
558 
559 	return QDF_STATUS_SUCCESS;
560 }
561 
562 /*
563  * iot_sim_action_frame_supported_by_fw - function to find if action frame is
564  *					  supported by fw or not
565  * @category: iot_sim specific category code
566  * @action: iot_sim specific action code
567  *
568  * Return: true if supported else false
569  */
570 bool
571 iot_sim_action_frame_supported_by_fw(uint8_t category, uint8_t action)
572 {
573 	switch (category) {
574 	case IEEE80211_ACTION_CAT_BA:
575 		switch (action) {
576 		case IEEE80211_ACTION_BA_ADDBA_REQUEST:
577 			return true;
578 		default:
579 			return false;
580 		}
581 	default:
582 		return false;
583 	}
584 }
585 
586 /*
587  * iot_sim_frame_supported_by_fw - function to find if frame is supported by fw
588  * @type: 802.11 frame type
589  * @subtype: 802.11 frame subtype
590  *
591  * Return: true if supported else false
592  */
593 bool
594 iot_sim_frame_supported_by_fw(uint8_t type, uint8_t subtype, bool action)
595 {
596 	if (action)
597 		return iot_sim_action_frame_supported_by_fw(type, subtype);
598 
599 	switch (type << IEEE80211_FC0_TYPE_SHIFT) {
600 	case IEEE80211_FC0_TYPE_MGT:
601 		switch (subtype << IEEE80211_FC0_SUBTYPE_SHIFT) {
602 		case IEEE80211_FC0_SUBTYPE_BEACON:
603 				return true;
604 		default:
605 				return false;
606 		}
607 	case IEEE80211_FC0_TYPE_CTL:
608 		switch (subtype << IEEE80211_FC0_SUBTYPE_SHIFT) {
609 		case IEEE80211_FC0_SUBTYPE_TRIGGER:
610 		case IEEE80211_FC0_SUBTYPE_BAR:
611 		case IEEE80211_FC0_SUBTYPE_CTS:
612 		case IEEE80211_FC0_SUBTYPE_ACK:
613 		case IEEE80211_FC0_SUBTYPE_NDPA:
614 			return true;
615 		default:
616 			return false;
617 		}
618 	case IEEE80211_FC0_TYPE_DATA:
619 		switch (subtype << IEEE80211_FC0_SUBTYPE_SHIFT) {
620 		default:
621 			return true;
622 		}
623 	default:
624 		return false;
625 	}
626 }
627 
628 /*
629  * iot_sim_remap_type_subtype - function to convert rules for response
630  *				type frame into request type. This is
631  *				used for drop/delay operation. This function
632  *				will update the passed type and subtype value.
633  *
634  * @type: 802.11 frame type
635  * @subtype: 802.11 frame subtype
636  * @seq: authentication sequence number, mostly 0 for non-authentication frame
637  * @action: flag to indicate action frame
638  *
639  * Return: QDF_STATUS_SUCCESS
640  */
641 QDF_STATUS
642 iot_sim_remap_type_subtype(uint8_t *type, uint8_t *subtype,
643 			   uint16_t *seq, bool action)
644 {
645 	if (action) {
646 		switch (*type) {
647 		case CAT_BA:
648 			switch (*subtype) {
649 			case IEEE80211_ACTION_BA_ADDBA_RESPONSE:
650 				*subtype = IEEE80211_ACTION_BA_ADDBA_REQUEST;
651 				break;
652 			default:
653 				break;
654 			}
655 			break;
656 		default:
657 			break;
658 		}
659 		return QDF_STATUS_SUCCESS;
660 	}
661 
662 	switch (*type << IEEE80211_FC0_TYPE_SHIFT) {
663 	case IEEE80211_FC0_TYPE_MGT:
664 		switch (*subtype << IEEE80211_FC0_SUBTYPE_SHIFT) {
665 		case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
666 			*subtype = IEEE80211_FC0_SUBTYPE_ASSOC_REQ;
667 			*subtype >>= IEEE80211_FC0_SUBTYPE_SHIFT;
668 			break;
669 		case IEEE80211_FC0_SUBTYPE_REASSOC_RESP:
670 			*subtype = IEEE80211_FC0_SUBTYPE_REASSOC_REQ;
671 			*subtype >>= IEEE80211_FC0_SUBTYPE_SHIFT;
672 			break;
673 		case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
674 			*subtype = IEEE80211_FC0_SUBTYPE_PROBE_REQ;
675 			*subtype >>= IEEE80211_FC0_SUBTYPE_SHIFT;
676 			break;
677 		case IEEE80211_FC0_SUBTYPE_AUTH:
678 			*subtype = IEEE80211_FC0_SUBTYPE_AUTH;
679 			*subtype >>= IEEE80211_FC0_SUBTYPE_SHIFT;
680 			/* If auth response (auth seq num 2) is marked as
681 			 * drop, then drop the auth request (auth seq num 1)
682 			 */
683 			if (*seq == IEEE80211_AUTH_OPEN_RESPONSE)
684 				*seq = IEEE80211_AUTH_OPEN_REQUEST;
685 			break;
686 		default:
687 			break;
688 		}
689 	default:
690 		break;
691 	}
692 
693 	return QDF_STATUS_SUCCESS;
694 }
695 
696 /*
697  * iot_sim_send_rule_to_fw - function to send iot_sim rule to fw
698  *
699  * @isc: iot sim context
700  * @oper: iot sim operation
701  * @mac: peer mac address
702  * @type: 802.11 frame type
703  * @subtype: 802.11 frame subtype
704  * @seq: authentication sequence number, mostly 0 for non-authentication frame
705  * @offset: user provided offset
706  * @frm: user provided frame content
707  * @length: length of frm
708  * @action: flag to indicate action frame
709  * @drop: flag to indicate set drop rule
710  * @clear: flag to indicate set rule or clear
711  *
712  * Return: QDF_STATUS_SUCCESS
713  */
714 QDF_STATUS
715 iot_sim_send_rule_to_fw(struct iot_sim_context *isc,
716 			enum iot_sim_operations oper,
717 			struct qdf_mac_addr *mac,
718 			uint8_t type, uint8_t subtype,
719 			uint16_t seq, uint16_t offset,
720 			uint8_t *frm, uint16_t len,
721 			bool action, bool clear)
722 {
723 	struct simulation_test_params param;
724 
725 	if (oper != DELAY && FRAME_TYPE_IS_BEACON(type, subtype) && offset) {
726 		iot_sim_info("Beacon update from offset:%d", offset);
727 		return QDF_STATUS_E_NOSUPPORT;
728 	}
729 
730 	if (iot_sim_frame_supported_by_fw(type, subtype, action)) {
731 		qdf_mem_zero(&param, sizeof(struct simulation_test_params));
732 		param.pdev_id = wlan_objmgr_pdev_get_pdev_id(isc->pdev_obj);
733 		qdf_mem_copy(param.peer_mac, mac, QDF_MAC_ADDR_SIZE);
734 		param.test_cmd_type = oper;
735 		/* subtype_cmd: Set subcmd based on action and clear flag */
736 		if (action) {
737 			if (clear)
738 				param.test_subcmd_type = DEL_RULE_ACTION;
739 			else
740 				param.test_subcmd_type = ADD_RULE_ACTION;
741 		} else {
742 			if (clear)
743 				param.test_subcmd_type = DEL_RULE;
744 			else
745 				param.test_subcmd_type = ADD_RULE;
746 		}
747 		param.frame_type = type;
748 		param.frame_subtype = subtype;
749 		param.seq = seq;
750 		param.offset = offset;
751 		param.frame_length = len;
752 		param.buf_len = len;
753 		param.bufp = frm;
754 		if (QDF_IS_STATUS_ERROR(tgt_send_simulation_cmd(isc->pdev_obj,
755 								&param)))
756 			iot_sim_err("Sending del rule to fw failed!");
757 
758 		if (FRAME_TYPE_IS_BEACON(type, subtype) && clear)
759 			return QDF_STATUS_E_NOSUPPORT;
760 
761 		return QDF_STATUS_SUCCESS;
762 	}
763 
764 	return QDF_STATUS_E_NOSUPPORT;
765 }
766 
767 /*
768  * iot_sim_del_rule - function to delete iot_sim rule
769  *
770  * @s_e: address of seq for which rule to be removed
771  * @f_e: address of the rule present in s_e to be removed
772  * @oper: iot sim operation
773  *
774  * Return: QDF_STATUS_SUCCESS
775  */
776 QDF_STATUS
777 iot_sim_del_rule(struct iot_sim_rule_per_seq **s_e,
778 		 struct iot_sim_rule **f_e,
779 		 enum iot_sim_operations oper,
780 		 struct iot_sim_context *isc)
781 {
782 	if (oper == CONTENT_CHANGE) {
783 		qdf_mem_free((*f_e)->frm_content);
784 		(*f_e)->frm_content = NULL;
785 	} else if (oper == DROP) {
786 		(*f_e)->drop = false;
787 	} else if (oper == DELAY) {
788 		if (!qdf_delayed_work_stop((*f_e)->dwork)) {
789 			iot_sim_err("delayed work is in running state");
790 			/* iot_sim_lock need to be released for the delay */
791 			/* work callback to complete execution */
792 			/* Hence releasing the lock */
793 			qdf_spin_unlock_bh(&isc->iot_sim_lock);
794 			/* iot_sim_delay_lock will be freed only after delay */
795 			/* work callback execution completion */
796 			qdf_spin_lock_bh(&(*f_e)->iot_sim_delay_lock);
797 			qdf_spin_lock_bh(&isc->iot_sim_lock);
798 			qdf_delayed_work_stop_sync((*f_e)->dwork);
799 			qdf_spin_unlock_bh(&(*f_e)->iot_sim_delay_lock);
800 		}
801 
802 		qdf_delayed_work_destroy((*f_e)->dwork);
803 		qdf_spinlock_destroy(&(*f_e)->iot_sim_delay_lock);
804 		qdf_mem_free((*f_e)->dwork->context);
805 		qdf_mem_free((*f_e)->dwork);
806 		qdf_nbuf_free((*f_e)->nbuf_list[0]);
807 		(*f_e)->nbuf_list[0] = NULL;
808 		if ((*f_e)->peer) {
809 			wlan_objmgr_peer_release_ref((*f_e)->peer,
810 						     WLAN_IOT_SIM_ID);
811 			(*f_e)->peer = NULL;
812 		}
813 		qdf_nbuf_free((*f_e)->nbuf_list[1]);
814 		(*f_e)->nbuf_list[1] = NULL;
815 		(*f_e)->sec_buf = NULL;
816 		qdf_mem_free((*f_e)->rx_param);
817 		(*f_e)->rx_param = NULL;
818 	}
819 
820 	if (qdf_test_bit(oper, (unsigned long *)
821 			       &(*f_e)->rule_bitmap)) {
822 		(*s_e)->use_count--;
823 		qdf_clear_bit(oper, (unsigned long *)
824 				    &(*f_e)->rule_bitmap);
825 	}
826 
827 	if (!(*f_e)->rule_bitmap) {
828 		qdf_mem_free(*f_e);
829 		*f_e = NULL;
830 	}
831 	if ((*s_e)->use_count == 0) {
832 		qdf_mem_free(*s_e);
833 		*s_e = NULL;
834 	}
835 	return QDF_STATUS_SUCCESS;
836 }
837 
838 /*
839  * iot_sim_delete_rule_for_mac - function to delete content change rule
840  *                               for given peer mac
841  * @isc: iot sim context
842  * @oper: iot sim operation
843  * @seq: authentication sequence number, mostly 0 for non-authentication frame
844  * @type: 802.11 frame type
845  * @subtype: 802.11 frame subtype
846  * @mac: peer mac address
847  * @action: action frame or not
848  *
849  * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE otherwise
850  */
851 QDF_STATUS
852 iot_sim_delete_rule_for_mac(struct iot_sim_context *isc,
853 			    enum iot_sim_operations oper,
854 			    uint16_t seq, uint8_t type,
855 			    uint8_t subtype,
856 			    struct qdf_mac_addr *mac,
857 			    bool action)
858 {
859 	QDF_STATUS status = QDF_STATUS_SUCCESS;
860 	struct iot_sim_rule_per_seq **s_e;
861 	struct iot_sim_rule **f_e;
862 	struct iot_sim_rule_per_peer *peer;
863 	bool peer_remove = 1, broadcast_peer = 0;
864 	uint8_t i;
865 
866 	if (qdf_is_macaddr_zero(mac))
867 		iot_sim_info("Rule deletion for all peers");
868 	else
869 		iot_sim_info("Rule deletion for " QDF_MAC_ADDR_FMT,
870 			     QDF_MAC_ADDR_REF(mac->bytes));
871 
872 	iot_sim_debug("oper:%s seq: %hu %s:%hu/%hu",
873 		      iot_sim_oper_to_str(oper), seq,
874 		      action ? "category/action code" : "type/subtype",
875 		      type, subtype);
876 
877 	if (!isc) {
878 		iot_sim_err("iot_sim: isc is null");
879 		return QDF_STATUS_E_FAILURE;
880 	}
881 
882 	if (oper == DROP || oper == DELAY)
883 		iot_sim_remap_type_subtype(&type, &subtype, &seq, action);
884 
885 	if (qdf_is_macaddr_zero(mac) || qdf_is_macaddr_broadcast(mac)) {
886 		peer = &isc->bcast_peer;
887 		broadcast_peer = 1;
888 	} else
889 		peer = iot_sim_find_peer_from_mac(isc, mac);
890 	if (peer) {
891 		qdf_spin_lock_bh(&isc->iot_sim_lock);
892 		s_e = &peer->rule_per_seq[seq];
893 		if (!*s_e) {
894 			qdf_spin_unlock_bh(&isc->iot_sim_lock);
895 			return QDF_STATUS_SUCCESS;
896 		}
897 
898 		if (action)
899 			f_e = &((*s_e)->rule_per_action_frm[type][subtype]);
900 		else
901 			f_e = &((*s_e)->rule_per_type[type][subtype]);
902 
903 		if (*f_e)
904 			status = iot_sim_del_rule(s_e, f_e, oper, isc);
905 
906 		for (i = 0; i < MAX_SEQ; i++)
907 			if (peer->rule_per_seq[i])
908 				peer_remove = 0;
909 		qdf_spin_unlock_bh(&isc->iot_sim_lock);
910 		if (!broadcast_peer && peer_remove) {
911 			iot_sim_remove_peer(isc, peer);
912 			qdf_mem_free(peer);
913 		}
914 	}
915 
916 	return status;
917 }
918 
919 /*
920  * iot_sim_delay_cb - Delayed work callback function
921  *                    to process delayed frames
922  *
923  * @context: Delayed work callback context
924  *
925  * Return: void
926  */
927 static void iot_sim_delay_cb(void *ctxt)
928 {
929 	struct wlan_objmgr_psoc *psoc = NULL;
930 	struct iot_sim_cb_context *context = ctxt;
931 	uint8_t *buf;
932 	struct ieee80211_frame *wh;
933 	struct qdf_mac_addr *mac_addr;
934 	struct mgmt_rx_event_params *param = context->piot_sim_rule->rx_param;
935 	struct wlan_objmgr_peer **peer = &context->piot_sim_rule->peer;
936 
937 	qdf_spin_lock_bh(&context->piot_sim_rule->iot_sim_delay_lock);
938 	qdf_spin_lock_bh(&context->isc->iot_sim_lock);
939 	psoc = wlan_pdev_get_psoc(context->isc->pdev_obj);
940 	context->piot_sim_rule->sec_buf = context->piot_sim_rule->nbuf_list[0];
941 	qdf_spin_unlock_bh(&context->isc->iot_sim_lock);
942 	mgmt_txrx_rx_handler(psoc, context->piot_sim_rule->sec_buf,
943 			     context->piot_sim_rule->rx_param);
944 	qdf_spin_lock_bh(&context->isc->iot_sim_lock);
945 	if (*peer) {
946 		wlan_objmgr_peer_release_ref(*peer, WLAN_IOT_SIM_ID);
947 		*peer = NULL;
948 	}
949 	if (context->piot_sim_rule->nbuf_list[1]) {
950 		context->piot_sim_rule->nbuf_list[0] =
951 					context->piot_sim_rule->nbuf_list[1];
952 		buf = qdf_nbuf_data(context->piot_sim_rule->nbuf_list[0]);
953 		wh = (struct ieee80211_frame *)buf;
954 		mac_addr = (struct qdf_mac_addr *)wh->i_addr2;
955 		*peer = wlan_objmgr_get_peer(psoc, param->pdev_id,
956 					     (uint8_t *)mac_addr,
957 					     WLAN_IOT_SIM_ID);
958 
959 		if (!qdf_delayed_work_start(context->piot_sim_rule->dwork,
960 					    context->
961 					    piot_sim_rule->delay_dur)) {
962 			iot_sim_err("delayed_work_start failed");
963 			qdf_nbuf_free(context->piot_sim_rule->nbuf_list[0]);
964 			if (*peer) {
965 				wlan_objmgr_peer_release_ref(*peer,
966 							     WLAN_IOT_SIM_ID);
967 				*peer = NULL;
968 			}
969 			qdf_mem_free(context->piot_sim_rule->
970 				     rx_param->rx_params);
971 			qdf_mem_free(context->piot_sim_rule->rx_param);
972 			context->piot_sim_rule->nbuf_list[0] = NULL;
973 			context->piot_sim_rule->rx_param = NULL;
974 		}
975 		context->piot_sim_rule->nbuf_list[1] = NULL;
976 	} else {
977 		context->piot_sim_rule->nbuf_list[0] = NULL;
978 		qdf_mem_free(context->piot_sim_rule->rx_param->rx_params);
979 		qdf_mem_free(context->piot_sim_rule->rx_param);
980 		context->piot_sim_rule->rx_param = NULL;
981 	}
982 
983 	qdf_spin_unlock_bh(&context->isc->iot_sim_lock);
984 	qdf_spin_unlock_bh(&context->piot_sim_rule->iot_sim_delay_lock);
985 }
986 
987 /*
988  * iot_sim_add_rule - function to add iot_sim rule
989  *
990  * @s_e: address of seq for which rule to be added
991  * @f_e: address of the rule present in s_e to be added
992  * @oper: iot sim operation
993  * @frm: user provided frame content
994  * @offset: user provided offset
995  * @len: length of the user provided frame content
996  * @isc: iot sim context
997  *
998  * Return: QDF_STATUS_SUCCESS
999  */
1000 QDF_STATUS
1001 iot_sim_add_rule(struct iot_sim_rule_per_seq **s_e,
1002 		 struct iot_sim_rule **f_e,
1003 		 enum iot_sim_operations oper,
1004 		 uint8_t *frm, uint16_t offset, uint16_t len,
1005 		 struct iot_sim_context *isc)
1006 {
1007 	struct iot_sim_cb_context *cb_context;
1008 
1009 	if (!*f_e) {
1010 		*f_e = qdf_mem_malloc(sizeof(struct iot_sim_rule));
1011 		if (!*f_e) {
1012 			iot_sim_err("can't allocate f_e");
1013 			return QDF_STATUS_E_NOMEM;
1014 		}
1015 	}
1016 
1017 	if (oper == CONTENT_CHANGE) {
1018 		(*f_e)->frm_content = qdf_mem_malloc(len);
1019 		if (!((*f_e)->frm_content))
1020 			return QDF_STATUS_E_NOMEM;
1021 		qdf_mem_copy((*f_e)->frm_content, frm, len);
1022 		(*f_e)->len = len;
1023 		(*f_e)->offset = offset;
1024 	} else if (oper == DROP) {
1025 		(*f_e)->drop = true;
1026 	} else if (oper == DELAY) {
1027 		(*f_e)->delay_dur = offset;
1028 		(*f_e)->dwork = qdf_mem_malloc(sizeof(struct qdf_delayed_work));
1029 		if (!(*f_e)->dwork) {
1030 			iot_sim_err("can't allocate dwork");
1031 			return QDF_STATUS_E_NOMEM;
1032 		}
1033 
1034 		cb_context = qdf_mem_malloc(sizeof(struct iot_sim_cb_context));
1035 		if (!cb_context) {
1036 			iot_sim_err("can't allocate cb_context");
1037 			qdf_mem_free((*f_e)->dwork);
1038 			return QDF_STATUS_E_NOMEM;
1039 		}
1040 
1041 		cb_context->isc = isc;
1042 		cb_context->piot_sim_rule = *f_e;
1043 		if (QDF_STATUS_SUCCESS !=
1044 		    qdf_delayed_work_create((*f_e)->dwork, iot_sim_delay_cb,
1045 					    cb_context)) {
1046 			iot_sim_err("delayed_work_create failed");
1047 			qdf_mem_free(cb_context);
1048 			qdf_mem_free((*f_e)->dwork);
1049 			return QDF_STATUS_E_NOMEM;
1050 		}
1051 
1052 		(*f_e)->nbuf_list[0] = NULL;
1053 		(*f_e)->nbuf_list[1] = NULL;
1054 		(*f_e)->peer = NULL;
1055 		iot_sim_err("delayed_work_created");
1056 		qdf_spinlock_create(&((*f_e)->iot_sim_delay_lock));
1057 	}
1058 
1059 	(*s_e)->use_count++;
1060 	qdf_set_bit(oper, (unsigned long *)
1061 			  &(*f_e)->rule_bitmap);
1062 
1063 	return QDF_STATUS_SUCCESS;
1064 }
1065 
1066 /*
1067  * iot_sim_add_rule_for_mac - function to add content change rule
1068  *			      for given peer mac
1069  * @isc: iot sim context
1070  * @oper: iot sim operation
1071  * @mac: peer mac address
1072  * @type: 802.11 frame type
1073  * @subtype: 802.11 frame subtype
1074  * @seq: authentication sequence number, mostly 0 for non-authentication frame
1075  * @offset: user provided offset
1076  * @frm: user provided frame content
1077  * @len: length of frm
1078  * @action: boolean to indicate action frame
1079  *
1080  * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE otherwise
1081  */
1082 QDF_STATUS
1083 iot_sim_add_rule_for_mac(struct iot_sim_context *isc,
1084 			 enum iot_sim_operations oper,
1085 			 struct qdf_mac_addr *mac,
1086 			 uint8_t type, uint8_t subtype,
1087 			 uint16_t seq, uint16_t offset,
1088 			 uint8_t *frm, uint16_t len,
1089 			 uint16_t drop, bool action)
1090 {
1091 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
1092 	struct iot_sim_rule_per_peer *peer;
1093 	struct iot_sim_rule_per_seq **s_e = NULL;
1094 	struct iot_sim_rule **f_e = NULL;
1095 
1096 	if (!isc) {
1097 		iot_sim_err("iot_sim: isc is null");
1098 		return status;
1099 	}
1100 
1101 	status = iot_sim_delete_rule_for_mac(isc, oper, seq,
1102 					     type, subtype, mac,
1103 					     action);
1104 	if (status == QDF_STATUS_E_FAILURE) {
1105 		iot_sim_err("iot_sim: Rule removed - Fail");
1106 		return status;
1107 	}
1108 
1109 	if (oper == DROP || oper == DELAY)
1110 		iot_sim_remap_type_subtype(&type, &subtype, &seq, action);
1111 
1112 	peer = iot_sim_find_peer_from_mac(isc, mac);
1113 	if (!peer)
1114 		peer = iot_sim_add_peer(isc, mac);
1115 	if (peer) {
1116 		qdf_spin_lock_bh(&isc->iot_sim_lock);
1117 		s_e = &peer->rule_per_seq[seq];
1118 		if (!*s_e) {
1119 			*s_e = qdf_mem_malloc(sizeof(struct
1120 					      iot_sim_rule_per_seq));
1121 			if (!*s_e) {
1122 				iot_sim_err("can't allocate s_e");
1123 				qdf_spin_unlock_bh(&isc->iot_sim_lock);
1124 				return QDF_STATUS_E_NOMEM;
1125 			}
1126 		}
1127 
1128 		if (action)
1129 			f_e = &((*s_e)->rule_per_action_frm[type][subtype]);
1130 		else
1131 			f_e = &((*s_e)->rule_per_type[type][subtype]);
1132 
1133 		if (qdf_is_macaddr_zero(mac))
1134 			iot_sim_info("Rule addition for all peers");
1135 		else
1136 			iot_sim_info("Rule addition for " QDF_MAC_ADDR_FMT,
1137 				     QDF_MAC_ADDR_REF(mac->bytes));
1138 
1139 		iot_sim_info("oper:%s seq: %hu %s:%hu/%hu delay:%hu",
1140 			     iot_sim_oper_to_str(oper), seq,
1141 			     action ? "category/action code" : "type/subtype",
1142 			     type, subtype, drop);
1143 
1144 		if (oper == DELAY)
1145 			offset = drop;
1146 
1147 		status = iot_sim_add_rule(s_e, f_e, oper, frm,
1148 					  offset, len, isc);
1149 		qdf_spin_unlock_bh(&isc->iot_sim_lock);
1150 	} else {
1151 		/* TBD: clear the rules for peer with address 'mac'*/
1152 	}
1153 
1154 	return status;
1155 }
1156 
1157 /*
1158  *                   IOT SIM User Command Format
1159  *
1160  * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1161  * | FrmType/subtype |  Seq  | Offset | Length | content | Mac Addr |
1162  * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1163  * |     1Byte       | 2Byte | 2Bytes | 2Bytes | Length  | 6 Bytes  |
1164  *
1165  */
1166 
1167 /*
1168  * iot_sim_debug_content_change_write - Write Handler for content change
1169  *					operation
1170  * @file: debugfs file pointer
1171  * @buf: buf of user input
1172  * @count: buf count
1173  * @ppos: offset on file
1174  *
1175  * Return: character read on success, failure otherwise
1176  */
1177 static ssize_t
1178 iot_sim_debug_content_change_write(struct file *file,
1179 				   const char __user *buf,
1180 				   size_t count, loff_t *ppos)
1181 {
1182 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1183 	unsigned char t_st, type, subtype, *content = NULL;
1184 	uint16_t offset = 0, length = 0, seq = 0;
1185 	char *locbuf = NULL;
1186 	enum iot_sim_operations oper = CONTENT_CHANGE;
1187 	struct qdf_mac_addr mac_addr = QDF_MAC_ADDR_BCAST_INIT;
1188 	struct iot_sim_context *isc =
1189 			((struct seq_file *)file->private_data)->private;
1190 	uint8_t action = 0, category = 0;
1191 	bool is_action = 0, clear = false;
1192 	mlme_pdev_ext_t *ext = NULL;
1193 
1194 	if ((!buf) || (count > USER_BUF_LEN) || (count < 7))
1195 		return -EFAULT;
1196 
1197 	locbuf = qdf_mem_malloc(USER_BUF_LEN + 1);
1198 	if (!locbuf)
1199 		return -ENOMEM;
1200 
1201 	if (copy_from_user(locbuf, buf, count)) {
1202 		qdf_mem_free(locbuf);
1203 		return -EFAULT;
1204 	}
1205 
1206 	status = iot_sim_parse_user_input_content_change(isc, locbuf, count,
1207 							 &t_st, &seq, &offset,
1208 							 &length, &content,
1209 							 &mac_addr);
1210 	if (QDF_IS_STATUS_ERROR(status))
1211 		goto free;
1212 
1213 	type = (t_st & IEEE80211_FC0_TYPE_MASK) >> IEEE80211_FC0_TYPE_SHIFT;
1214 	subtype = (t_st & IEEE80211_FC0_SUBTYPE_MASK);
1215 	subtype >>= IEEE80211_FC0_SUBTYPE_SHIFT;
1216 
1217 	if (type > N_FRAME_TYPE || subtype > N_FRAME_SUBTYPE || seq > MAX_SEQ)
1218 		goto free;
1219 
1220 	if (FRAME_TYPE_IS_ACTION(type, subtype)) {
1221 		status = iot_sim_parse_action_frame(length, offset, content,
1222 						    &category, &action);
1223 		if (QDF_IS_STATUS_ERROR(status))
1224 			goto free;
1225 
1226 		is_action = 1;
1227 		type = category;
1228 		subtype = action;
1229 	}
1230 
1231 	clear = length ? false : true;
1232 	status = iot_sim_send_rule_to_fw(isc, oper, &mac_addr, type, subtype,
1233 					 seq, offset, content, length,
1234 					 is_action, clear);
1235 	if (QDF_IS_STATUS_SUCCESS(status))
1236 		goto free;
1237 
1238 	/* check for rule removal */
1239 	if (!length || !content) {
1240 		status = iot_sim_delete_rule_for_mac(isc, oper, seq,
1241 						     type, subtype,
1242 						     &mac_addr,
1243 						     is_action);
1244 
1245 	} else {
1246 		status = iot_sim_add_rule_for_mac(isc, oper, &mac_addr,
1247 						  type, subtype, seq, offset,
1248 						  content, length, 0,
1249 						  is_action);
1250 	}
1251 	if (QDF_IS_STATUS_SUCCESS(status)) {
1252 		iot_sim_err("iot_sim: Content Change Operation - success");
1253 		if (FRAME_TYPE_IS_BEACON(type, subtype)) {
1254 			if (isc->bcn_buf && (!length || !content)) {
1255 				qdf_nbuf_free(isc->bcn_buf);
1256 				isc->bcn_buf = NULL;
1257 			}
1258 			ext = wlan_pdev_mlme_get_ext_hdl(isc->pdev_obj);
1259 			if (ext) {
1260 				isc->iot_sim_update_beacon_trigger(ext);
1261 				iot_sim_info("Beacon update triggered");
1262 			} else {
1263 				iot_sim_err("mlme_pdev_ext is null");
1264 			}
1265 		}
1266 	} else {
1267 		iot_sim_err("iot_sim: Content Change Operation - Fail");
1268 	}
1269 free:
1270 	qdf_mem_free(content);
1271 	qdf_mem_free(locbuf);
1272 	return count;
1273 }
1274 
1275 /*
1276  * iot_sim_parse_user_input_delay - function to parse user input into
1277  *				   predefined format for delay operation.
1278  *				   All arguments passed will be filled
1279  *				   upon success
1280  * @isc: iot sim context
1281  * @userbuf: local copy of user input
1282  * @count: length of userbuf
1283  * @t_st: address of type variable
1284  * @seq: address of seq variable
1285  * @cat_type: 802.11 action frame category code
1286  * @act_type: 802.11 action frame action code
1287  * @delay: address of delay variable
1288  * @addr: pointer to mac address
1289  *
1290  * Return: QDF_STATUS_SUCCESS on success
1291  *	   QDF_STATUS_E_FAILURE otherwise
1292  */
1293 QDF_STATUS
1294 iot_sim_parse_user_input_delay(struct iot_sim_context *isc,
1295 			       char *userbuf, ssize_t count,
1296 			       uint8_t *t_st, uint16_t *seq,
1297 			       uint8_t *cat_type, uint8_t *act_type,
1298 			       uint16_t *delay, struct qdf_mac_addr *addr)
1299 {
1300 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1301 	char *argv[6], *delim = " ", *substr;
1302 	int argc = -1, ret = 0;
1303 
1304 	qdf_mem_zero(argv, sizeof(argv));
1305 	userbuf = qdf_str_trim(userbuf);
1306 
1307 	while ((substr = qdf_str_sep(&userbuf, delim)) != NULL) {
1308 		if (!isspace(*substr) && *substr != '\0')
1309 			argv[++argc] = substr;
1310 		if (argc >= 5)
1311 			break;
1312 	}
1313 
1314 	if (argc < 3) {
1315 		iot_sim_err("Invalid argument count %d", (argc + 1));
1316 		return status;
1317 	}
1318 
1319 	if (!argv[0] || !argv[1] || !argv[2] || !argv[3] || !argv[4]) {
1320 		iot_sim_err("One or more arguments are null");
1321 		return status;
1322 	}
1323 	/*
1324 	 * User can send delay data in following format:
1325 	 * 1. Add delay rule for specific peer
1326 	 *	<t_st> <seq> <category_type> <action_type> <delay> <MAC>
1327 	 * 2. Remove delay rule for specific peer
1328 	 *	<t_st> <seq> <category_type> <action_type> <delay> <MAC>
1329 	 */
1330 
1331 	ret = kstrtou8(argv[0], 16, t_st);
1332 	if (ret)
1333 		goto err;
1334 	ret = kstrtou16(argv[1], 10, seq);
1335 	if (ret)
1336 		goto err;
1337 	ret = kstrtou8(argv[2], 10, cat_type);
1338 	if (ret)
1339 		goto err;
1340 	ret = kstrtou8(argv[3], 10, act_type);
1341 	if (ret)
1342 		goto err;
1343 	ret = kstrtou16(argv[4], 10, delay);
1344 	if (ret)
1345 		goto err;
1346 
1347 	/*
1348 	 * If argv[5] is valid, this must be mac address
1349 	 */
1350 	if (argv[5])
1351 		status = qdf_mac_parse(argv[5], addr);
1352 
1353 	iot_sim_err("delay rule mac address " QDF_MAC_ADDR_FMT,
1354 		    QDF_MAC_ADDR_REF(addr->bytes));
1355 
1356 	return status;
1357 err:
1358 	iot_sim_err("kstrtoXX failed: %d", ret);
1359 	return QDF_STATUS_E_FAILURE;
1360 }
1361 
1362 /*
1363  * iot_sim_debug_delay_write - Write Handler for delay operation
1364  * @file: debugfs file pointer
1365  * @buf: buf of user input
1366  * @count: buf count
1367  * @ppos: offset on file
1368  *
1369  * Return: character read
1370  */
1371 static ssize_t
1372 iot_sim_debug_delay_write(struct file *file,
1373 			  const char __user *buf,
1374 			  size_t count, loff_t *ppos)
1375 {
1376 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1377 	unsigned char t_st, type, subtype;
1378 	uint16_t seq = 0;
1379 	char *locbuf = NULL;
1380 	enum iot_sim_operations oper = DELAY;
1381 	struct qdf_mac_addr mac_addr = QDF_MAC_ADDR_BCAST_INIT;
1382 	struct iot_sim_context *isc =
1383 			((struct seq_file *)file->private_data)->private;
1384 	uint8_t action = 0, category = 0, tmp[2];
1385 	bool is_action = false, clear = false;
1386 	uint16_t delay = 0;
1387 
1388 	if ((!buf) || (count > USER_BUF_LEN_DELAY) || (count < 6))
1389 		return -EFAULT;
1390 
1391 	locbuf = qdf_mem_malloc(USER_BUF_LEN_DELAY + 1);
1392 	if (!locbuf)
1393 		return -ENOMEM;
1394 
1395 	if (copy_from_user(locbuf, buf, count)) {
1396 		qdf_mem_free(locbuf);
1397 		return -EFAULT;
1398 	}
1399 
1400 	status = iot_sim_parse_user_input_delay(isc, locbuf, count,
1401 						&t_st, &seq, &category,
1402 						&action, &delay, &mac_addr);
1403 	if (QDF_IS_STATUS_ERROR(status)) {
1404 		iot_sim_err("iot_sim_parse_user_input_delay failed");
1405 		goto free;
1406 	}
1407 	iot_sim_err("Delay rule t_st:%d, seq:%hu cat_type:%d, act_type:%d, delay:%hu",
1408 		    t_st, seq, category, action, delay);
1409 
1410 	type = (t_st & IEEE80211_FC0_TYPE_MASK) >> IEEE80211_FC0_TYPE_SHIFT;
1411 	subtype = (t_st & IEEE80211_FC0_SUBTYPE_MASK);
1412 	subtype >>= IEEE80211_FC0_SUBTYPE_SHIFT;
1413 
1414 	if (type > N_FRAME_TYPE || subtype > N_FRAME_SUBTYPE || seq > MAX_SEQ)
1415 		goto free;
1416 
1417 	if (FRAME_TYPE_IS_ACTION(type, subtype)) {
1418 		tmp[0] = category;
1419 		tmp[1] = action;
1420 		/*
1421 		 * convert 802.11 category and action code to iot sim codes
1422 		 */
1423 		status = iot_sim_get_index_for_action_frm(tmp, &category,
1424 							  &action, false);
1425 		if (QDF_IS_STATUS_ERROR(status))
1426 			goto free;
1427 
1428 		is_action = 1;
1429 		type = category;
1430 		subtype = action;
1431 	}
1432 
1433 	clear = delay ? false : true;
1434 	status = iot_sim_send_rule_to_fw(isc, oper, &mac_addr, type, subtype,
1435 					 seq, delay, NULL, 0, is_action, clear);
1436 	if (QDF_IS_STATUS_SUCCESS(status))
1437 		goto free;
1438 
1439 	/* check for rule removal */
1440 	if (!delay) {
1441 		status = iot_sim_delete_rule_for_mac(isc, oper, seq,
1442 						     type, subtype,
1443 						     &mac_addr,
1444 						     is_action);
1445 	} else {
1446 		status = iot_sim_add_rule_for_mac(isc, oper, &mac_addr,
1447 						  type, subtype, seq, 0,
1448 						  NULL, 0, delay, is_action);
1449 	}
1450 	if (QDF_IS_STATUS_SUCCESS(status))
1451 		iot_sim_debug("iot_sim: Rule update Delay Operation - Success");
1452 	else
1453 		iot_sim_err("iot_sim: Rule update Delay Operation - Fail");
1454 free:
1455 	qdf_mem_free(locbuf);
1456 	return count;
1457 }
1458 
1459 /*
1460  * iot_sim_parse_user_input_drop - function to parse user input into
1461  *				   predefined format for drop operation.
1462  *				   All arguments passed will be filled
1463  *				   upon success
1464  * @isc: iot sim context
1465  * @userbuf: local copy of user input
1466  * @count: length of userbuf
1467  * @t_st: address of type variable
1468  * @seq: address of seq variable
1469  * @cat_type: 802.11 action frame category code
1470  * @act_type: 802.11 action frame action code
1471  * @drop: address of drop variable to specify drop the frame or not
1472  * @addr: pointer to mac address
1473  *
1474  * Return: QDF_STATUS_SUCCESS on success
1475  *	   QDF_STATUS_E_FAILURE otherwise
1476  */
1477 QDF_STATUS
1478 iot_sim_parse_user_input_drop(struct iot_sim_context *isc,
1479 			      char *userbuf, ssize_t count,
1480 			      uint8_t *t_st, uint16_t *seq,
1481 			      uint8_t *cat_type, uint8_t *act_type,
1482 			      uint8_t *drop, struct qdf_mac_addr *addr)
1483 {
1484 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1485 	char *argv[6], *delim = " ", *substr;
1486 	int argc = -1, ret = 0;
1487 
1488 	qdf_mem_zero(argv, sizeof(argv));
1489 	userbuf = qdf_str_trim(userbuf);
1490 
1491 	while ((substr = qdf_str_sep(&userbuf, delim)) != NULL) {
1492 		if (!isspace(*substr) && *substr != '\0')
1493 			argv[++argc] = substr;
1494 		if (argc >= 5)
1495 			break;
1496 	}
1497 
1498 	if (argc < 3) {
1499 		iot_sim_err("Invalid argument count %d", (argc + 1));
1500 		return status;
1501 	}
1502 
1503 	if (!argv[0] || !argv[1] || !argv[2] || !argv[3] || !argv[4]) {
1504 		iot_sim_err("One or more arguments are null");
1505 		return status;
1506 	}
1507 	/*
1508 	 * User can send drop data in following format:
1509 	 * 1. Add drop rule for specific peer
1510 	 *	<t_st> <seq> <category_type> <action_type> <drop> <MAC>
1511 	 * 2. Add drop rule for broadcast peer
1512 	 *	<t_st> <seq> <category_type> <action_type> <drop>
1513 	 * 3. Remove drop rule for specific peer
1514 	 *	<t_st> <seq> <category_type> <action_type> <drop> <MAC>
1515 	 * 4. Remove drop rule for broadcast peer
1516 	 *	<t_st> <seq> <category_type> <action_type> <drop> <BCAST_MAC>
1517 	 * 5. Remove drop rule for all peer
1518 	 *	<t_st> <seq> <category_type> <action_type> <drop>
1519 	 */
1520 
1521 	ret = kstrtou8(argv[0], 16, t_st);
1522 	if (ret)
1523 		goto err;
1524 	ret = kstrtou16(argv[1], 10, seq);
1525 	if (ret)
1526 		goto err;
1527 	ret = kstrtou8(argv[2], 10, cat_type);
1528 	if (ret)
1529 		goto err;
1530 	ret = kstrtou8(argv[3], 10, act_type);
1531 	if (ret)
1532 		goto err;
1533 	ret = kstrtou8(argv[4], 10, drop);
1534 	if (ret)
1535 		goto err;
1536 
1537 	/*
1538 	 * If argv[5] is valid, this must be mac address
1539 	 */
1540 	if (argv[5])
1541 		status = qdf_mac_parse(argv[5], addr);
1542 
1543 	iot_sim_err("drop rule mac address " QDF_MAC_ADDR_FMT,
1544 		    QDF_MAC_ADDR_REF(addr->bytes));
1545 
1546 	return status;
1547 err:
1548 	iot_sim_err("kstrtoXX failed: %d", ret);
1549 	return QDF_STATUS_E_FAILURE;
1550 }
1551 
1552 /*
1553  * iot_sim_debug_drop_write - Write Handler for drop operation
1554  * @file: debugfs file pointer
1555  * @buf: buf of user input
1556  * @count: buf count
1557  * @ppos: offset on file
1558  *
1559  * Return: character read
1560  */
1561 static ssize_t
1562 iot_sim_debug_drop_write(struct file *file,
1563 			 const char __user *buf,
1564 			 size_t count, loff_t *ppos)
1565 {
1566 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1567 	unsigned char t_st, type, subtype;
1568 	uint16_t seq = 0;
1569 	char *locbuf = NULL;
1570 	enum iot_sim_operations oper = DROP;
1571 	struct qdf_mac_addr mac_addr = QDF_MAC_ADDR_BCAST_INIT;
1572 	struct iot_sim_context *isc =
1573 			((struct seq_file *)file->private_data)->private;
1574 	uint8_t action = 0, category = 0, tmp[2], drop = 0;
1575 	bool is_action = false, clear = false;
1576 
1577 	if ((!buf) || (count > USER_BUF_LEN_DROP) || (count < 6))
1578 		return -EFAULT;
1579 
1580 	locbuf = qdf_mem_malloc(USER_BUF_LEN_DROP + 1);
1581 	if (!locbuf)
1582 		return -ENOMEM;
1583 
1584 	if (copy_from_user(locbuf, buf, count)) {
1585 		qdf_mem_free(locbuf);
1586 		return -EFAULT;
1587 	}
1588 
1589 	status = iot_sim_parse_user_input_drop(isc, locbuf, count,
1590 					       &t_st, &seq, &category,
1591 					       &action, &drop, &mac_addr);
1592 	if (QDF_IS_STATUS_ERROR(status))
1593 		goto free;
1594 
1595 	type = (t_st & IEEE80211_FC0_TYPE_MASK) >> IEEE80211_FC0_TYPE_SHIFT;
1596 	subtype = (t_st & IEEE80211_FC0_SUBTYPE_MASK);
1597 	subtype >>= IEEE80211_FC0_SUBTYPE_SHIFT;
1598 
1599 	if (type > N_FRAME_TYPE || subtype > N_FRAME_SUBTYPE || seq > MAX_SEQ)
1600 		goto free;
1601 
1602 	if (FRAME_TYPE_IS_ACTION(type, subtype)) {
1603 		tmp[0] = category;
1604 		tmp[1] = action;
1605 		/*
1606 		 * convert 802.11 category and action code to iot sim codes
1607 		 */
1608 		status = iot_sim_get_index_for_action_frm(tmp, &category,
1609 							  &action, false);
1610 		if (QDF_IS_STATUS_ERROR(status))
1611 			goto free;
1612 
1613 		is_action = 1;
1614 		type = category;
1615 		subtype = action;
1616 	}
1617 
1618 	clear = drop ? false : true;
1619 	status = iot_sim_send_rule_to_fw(isc, oper, &mac_addr, type, subtype,
1620 					 seq, 0, NULL, 0, is_action, clear);
1621 	if (QDF_IS_STATUS_SUCCESS(status))
1622 		goto free;
1623 
1624 	/* check for rule removal */
1625 	if (!drop) {
1626 		status = iot_sim_delete_rule_for_mac(isc, oper, seq,
1627 						     type, subtype,
1628 						     &mac_addr,
1629 						     is_action);
1630 	} else {
1631 		status = iot_sim_add_rule_for_mac(isc, oper, &mac_addr,
1632 						  type, subtype, seq, 0,
1633 						  NULL, 0, drop, is_action);
1634 	}
1635 	if (QDF_IS_STATUS_SUCCESS(status))
1636 		iot_sim_debug("iot_sim: Rule update Drop Operation - Success");
1637 	else
1638 		iot_sim_err("iot_sim: Rule update Drop Operation - Fail");
1639 free:
1640 	qdf_mem_free(locbuf);
1641 	return count;
1642 }
1643 
1644 /*
1645  * debug_iot_sim_##func_base##_show() - debugfs functions to display content
1646  *                                      dummy function
1647  * Return: success
1648  */
1649 #define GENERATE_IOT_SIM_DEBUG_SHOW_FUNCS(func_base)			\
1650 	static int iot_sim_debug_##func_base##_show(struct seq_file *m,	\
1651 						    void *v)		\
1652 {									\
1653 	return qdf_status_to_os_return(QDF_STATUS_SUCCESS);		\
1654 }
1655 
1656 GENERATE_IOT_SIM_DEBUG_SHOW_FUNCS(content_change);
1657 GENERATE_IOT_SIM_DEBUG_SHOW_FUNCS(delay);
1658 GENERATE_IOT_SIM_DEBUG_SHOW_FUNCS(drop);
1659 
1660 /*
1661  * debug_##func_base##_open() - Open debugfs entry for respective command
1662  * and event buffer.
1663  *
1664  * @inode: node for debug dir entry
1665  * @file: file handler
1666  *
1667  * Return: open status
1668  */
1669 #define GENERATE_DEBUG_IOT_SIM_STRUCTS(func_base)			\
1670 	static int debug_##func_base##_open(struct inode *inode,	\
1671 					    struct file *file)		\
1672 {									\
1673 	return single_open(file, iot_sim_debug_##func_base##_show,	\
1674 			   inode->i_private);				\
1675 }									\
1676 									\
1677 static const struct file_operations debug_##func_base##_ops = {		\
1678 	.open           = debug_##func_base##_open,			\
1679 	.read           = seq_read,					\
1680 	.llseek         = seq_lseek,					\
1681 	.write          = iot_sim_debug_##func_base##_write,		\
1682 	.release        = single_release,				\
1683 }
1684 
1685 GENERATE_DEBUG_IOT_SIM_STRUCTS(content_change);
1686 GENERATE_DEBUG_IOT_SIM_STRUCTS(drop);
1687 GENERATE_DEBUG_IOT_SIM_STRUCTS(delay);
1688 
1689 /* Structure to maintain debug information */
1690 struct iot_sim_dbgfs_file {
1691 	const char *name;
1692 	const struct file_operations *ops;
1693 };
1694 
1695 #define DEBUG_IOT_SIM(func_base) {	.name = #func_base,		\
1696 					.ops = &debug_##func_base##_ops	\
1697 }
1698 
1699 struct iot_sim_dbgfs_file iot_sim_dbgfs_files[IOT_SIM_DEBUGFS_FILE_NUM] = {
1700 	DEBUG_IOT_SIM(content_change),
1701 	DEBUG_IOT_SIM(drop),
1702 	DEBUG_IOT_SIM(delay),
1703 };
1704 
1705 /**
1706  * iot_sim_debugfs_deinit() - Deinit functions to remove debugfs directory and
1707  *			      it's file enteries.
1708  * @isc: iot_sim context
1709  *
1710  * Return: init status
1711  */
1712 static QDF_STATUS
1713 iot_sim_debugfs_deinit(struct iot_sim_context *isc)
1714 {
1715 	qdf_debugfs_remove_dir_recursive(isc->iot_sim_dbgfs_ctx.iot_sim_dir_de);
1716 
1717 	return QDF_STATUS_SUCCESS;
1718 }
1719 
1720 /*
1721  * iot_sim_remove_all_oper_rules - Function to remove all configured rules
1722  *				   for given operation
1723  *
1724  * @isc: iot sim context
1725  * @oper: iot sim operation
1726  *
1727  * Return: void
1728  */
1729 static void
1730 iot_sim_remove_all_oper_rules(struct iot_sim_context *isc,
1731 			      enum iot_sim_operations oper)
1732 {
1733 	uint16_t seq;
1734 	uint8_t type, subtype, category = 0, action = 0;
1735 	struct qdf_mac_addr zero_mac_addr = QDF_MAC_ADDR_ZERO_INIT;
1736 
1737 	for (seq = 0; seq < MAX_SEQ; seq++) {
1738 		/* Remove rules for non-action type frames */
1739 		for (type = 0; type < N_FRAME_TYPE; type++)
1740 			for (subtype = 0; subtype < N_FRAME_SUBTYPE; subtype++)
1741 				iot_sim_delete_rule_for_mac(isc, oper, seq,
1742 							    type, subtype,
1743 							    &zero_mac_addr, 0);
1744 		/* Remove rules for action frames */
1745 		for (category = 0; category < IOT_SIM_MAX_CAT; category++)
1746 			for (action = 0; action < MAX_ACTION; action++)
1747 				iot_sim_delete_rule_for_mac(isc, oper, seq,
1748 							    category, action,
1749 							    &zero_mac_addr, 1);
1750 	}
1751 }
1752 
1753 /*
1754  * iot_sim_remove_all_rules - Function to remove all configured rules
1755  *
1756  * @isc: iot sim context
1757  *
1758  * Return: void
1759  */
1760 static void
1761 iot_sim_remove_all_rules(struct iot_sim_context *isc)
1762 {
1763 	enum iot_sim_operations oper;
1764 
1765 	if (!isc)
1766 		return;
1767 
1768 	for (oper = CONTENT_CHANGE; oper < IOT_SIM_MAX_OPERATION; oper++)
1769 		iot_sim_remove_all_oper_rules(isc, oper);
1770 }
1771 
1772 /**
1773  * iot_sim_debugfs_init() - debugfs functions to create debugfs directory and to
1774  *			    create debugfs enteries.
1775  * @isc: iot_sim context
1776  *
1777  * Return: init status
1778  */
1779 static QDF_STATUS
1780 iot_sim_debugfs_init(struct iot_sim_context *isc)
1781 {
1782 	struct dentry *dbgfs_dir = NULL;
1783 	struct dentry *de = NULL;
1784 	uint8_t i, pdev_id;
1785 	char buf[32];
1786 
1787 	if (!isc)
1788 		return QDF_STATUS_E_FAILURE;
1789 
1790 	pdev_id = wlan_objmgr_pdev_get_pdev_id(isc->pdev_obj);
1791 
1792 	qdf_mem_zero(buf, sizeof(buf));
1793 	snprintf(buf, sizeof(buf), "iot_sim_pdev%u", pdev_id);
1794 
1795 	dbgfs_dir = qdf_debugfs_create_dir(buf, NULL);
1796 	isc->iot_sim_dbgfs_ctx.iot_sim_dir_de = dbgfs_dir;
1797 
1798 	if (!isc->iot_sim_dbgfs_ctx.iot_sim_dir_de) {
1799 		iot_sim_err("dbgfs dir creation failed for pdev%u", pdev_id);
1800 		return QDF_STATUS_E_FAILURE;
1801 	}
1802 
1803 	for (i = 0; i < IOT_SIM_DEBUGFS_FILE_NUM; ++i) {
1804 		de = qdf_debugfs_create_entry(iot_sim_dbgfs_files[i].name,
1805 					      IOT_SIM_DBG_FILE_PERM,
1806 					      dbgfs_dir, isc,
1807 					      iot_sim_dbgfs_files[i].ops);
1808 
1809 		if (!de) {
1810 			iot_sim_err("dbgfs file creation failed for pdev%u",
1811 				    pdev_id);
1812 			goto out;
1813 		}
1814 		isc->iot_sim_dbgfs_ctx.iot_sim_file_de[i] = de;
1815 	}
1816 
1817 	return QDF_STATUS_SUCCESS;
1818 
1819 out:
1820 	qdf_debugfs_remove_dir_recursive(dbgfs_dir);
1821 	qdf_mem_set(isc->iot_sim_dbgfs_ctx.iot_sim_file_de,
1822 		    sizeof(isc->iot_sim_dbgfs_ctx.iot_sim_file_de), 0);
1823 
1824 	return QDF_STATUS_E_FAILURE;
1825 }
1826 
1827 QDF_STATUS
1828 wlan_iot_sim_pdev_obj_create_handler(struct wlan_objmgr_pdev *pdev, void *arg)
1829 {
1830 	struct iot_sim_context *isc = NULL;
1831 
1832 	if (!pdev) {
1833 		iot_sim_err("pdev is NULL");
1834 		return QDF_STATUS_E_NULL_VALUE;
1835 	}
1836 
1837 	isc = qdf_mem_malloc(sizeof(struct iot_sim_context));
1838 	if (!isc)
1839 		return QDF_STATUS_E_NOMEM;
1840 
1841 	isc->pdev_obj = pdev;
1842 
1843 	if (QDF_IS_STATUS_ERROR(iot_sim_debugfs_init(isc))) {
1844 		qdf_mem_free(isc);
1845 		iot_sim_info("iot_sim debugfs file creation failed");
1846 		return QDF_STATUS_E_FAILURE;
1847 	}
1848 
1849 	qdf_set_macaddr_broadcast(&isc->bcast_peer.addr);
1850 	qdf_spinlock_create(&isc->iot_sim_lock);
1851 	qdf_list_create(&isc->peer_list, 2);
1852 	isc->bcn_buf = NULL;
1853 
1854 	wlan_objmgr_pdev_component_obj_attach(pdev, WLAN_IOT_SIM_COMP,
1855 					      (void *)isc, QDF_STATUS_SUCCESS);
1856 
1857 	iot_sim_debug("iot_sim component pdev%u object created",
1858 		      wlan_objmgr_pdev_get_pdev_id(isc->pdev_obj));
1859 
1860 	return QDF_STATUS_SUCCESS;
1861 }
1862 
1863 QDF_STATUS
1864 wlan_iot_sim_pdev_obj_destroy_handler(struct wlan_objmgr_pdev *pdev,
1865 				      void *arg)
1866 {
1867 	struct iot_sim_context *isc = NULL;
1868 
1869 	if (!pdev) {
1870 		iot_sim_err("pdev is NULL");
1871 		return QDF_STATUS_E_NULL_VALUE;
1872 	}
1873 
1874 	isc = wlan_objmgr_pdev_get_comp_private_obj(pdev,
1875 						    WLAN_IOT_SIM_COMP);
1876 	if (isc) {
1877 		wlan_objmgr_pdev_component_obj_detach(pdev,
1878 						      WLAN_IOT_SIM_COMP,
1879 						      (void *)isc);
1880 		/* Deinitilise function pointers from iot_sim context */
1881 		iot_sim_debugfs_deinit(isc);
1882 		iot_sim_remove_all_rules(isc);
1883 		qdf_list_destroy(&isc->peer_list);
1884 		if (isc->bcn_buf)
1885 			qdf_nbuf_free(isc->bcn_buf);
1886 		qdf_spinlock_destroy(&isc->iot_sim_lock);
1887 		qdf_mem_free(isc);
1888 	}
1889 	iot_sim_debug("iot_sim component pdev%u object destroyed",
1890 		      wlan_objmgr_pdev_get_pdev_id(isc->pdev_obj));
1891 
1892 	return QDF_STATUS_SUCCESS;
1893 }
1894 
1895