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 *
iot_sim_oper_to_str(enum iot_sim_operations oper)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
iot_sim_convert_offset_to_hex_str(uint16_t offset,uint8_t * hex,int8_t count)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
iot_sim_parse_action_frame(uint16_t length,uint16_t offset,uint8_t * content,uint8_t * category,uint8_t * action)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 *
iot_sim_find_peer_from_mac(struct iot_sim_context * isc,struct qdf_mac_addr * mac)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 *
iot_sim_add_peer(struct iot_sim_context * isc,struct qdf_mac_addr * mac)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   */
iot_sim_remove_peer(struct iot_sim_context * isc,struct iot_sim_rule_per_peer * peer_rule)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
iot_sim_validate_content(uint8_t * buf,uint16_t total_len,uint16_t offset)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
iot_sim_handle_frame_content(struct iot_sim_context * isc,const char * pos,uint8_t ** storage,uint16_t offset,uint16_t len)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
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)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
iot_sim_get_index_for_action_frm(uint8_t * frm,uint8_t * cat_type,uint8_t * act_type,bool rx)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
iot_sim_action_frame_supported_by_fw(uint8_t category,uint8_t action)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
iot_sim_frame_supported_by_fw(uint8_t type,uint8_t subtype,bool action)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
iot_sim_remap_type_subtype(uint8_t * type,uint8_t * subtype,uint16_t * seq,bool action)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
iot_sim_send_rule_to_fw(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,bool action,bool clear)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
iot_sim_del_rule(struct iot_sim_rule_per_seq ** s_e,struct iot_sim_rule ** f_e,enum iot_sim_operations oper,struct iot_sim_context * isc)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
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,bool action)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   */
iot_sim_delay_cb(void * ctxt)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
iot_sim_add_rule(struct iot_sim_rule_per_seq ** s_e,struct iot_sim_rule ** f_e,enum iot_sim_operations oper,uint8_t * frm,uint16_t offset,uint16_t len,struct iot_sim_context * isc)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
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,uint16_t drop,bool action)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
iot_sim_debug_content_change_write(struct file * file,const char __user * buf,size_t count,loff_t * ppos)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
iot_sim_parse_user_input_delay(struct iot_sim_context * isc,char * userbuf,ssize_t count,uint8_t * t_st,uint16_t * seq,uint8_t * cat_type,uint8_t * act_type,uint16_t * delay,struct qdf_mac_addr * addr)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
iot_sim_debug_delay_write(struct file * file,const char __user * buf,size_t count,loff_t * ppos)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
iot_sim_parse_user_input_drop(struct iot_sim_context * isc,char * userbuf,ssize_t count,uint8_t * t_st,uint16_t * seq,uint8_t * cat_type,uint8_t * act_type,uint8_t * drop,struct qdf_mac_addr * addr)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
iot_sim_debug_drop_write(struct file * file,const char __user * buf,size_t count,loff_t * ppos)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
iot_sim_debugfs_deinit(struct iot_sim_context * isc)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
iot_sim_remove_all_oper_rules(struct iot_sim_context * isc,enum iot_sim_operations oper)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
iot_sim_remove_all_rules(struct iot_sim_context * isc)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
iot_sim_debugfs_init(struct iot_sim_context * isc)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
wlan_iot_sim_pdev_obj_create_handler(struct wlan_objmgr_pdev * pdev,void * arg)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
wlan_iot_sim_pdev_obj_destroy_handler(struct wlan_objmgr_pdev * pdev,void * arg)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