xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_tgt_api.c (revision 901120c066e139c7f8a2c8e4820561fdd83c67ef)
1 /*
2  * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /**
21  *  DOC:    wlan_mgmt_txrx_tgt_api.c
22  *  This file contains mgmt txrx public API definitions for
23  *  southbound interface.
24  */
25 
26 #include <wmi_unified_param.h>
27 
28 #include "wlan_mgmt_txrx_tgt_api.h"
29 #include "wlan_mgmt_txrx_utils_api.h"
30 #include "../../core/src/wlan_mgmt_txrx_main_i.h"
31 #include "wlan_objmgr_psoc_obj.h"
32 #include "wlan_objmgr_peer_obj.h"
33 #include "wlan_objmgr_pdev_obj.h"
34 #include "wlan_mgmt_txrx_rx_reo_tgt_api.h"
35 
36 /**
37  * mgmt_get_spec_mgmt_action_subtype() - gets spec mgmt action subtype
38  * @action_code: action code
39  *
40  * This function returns the subtype for spectrum management action
41  * category.
42  *
43  * Return: mgmt frame type
44  */
45 static enum mgmt_frame_type
46 mgmt_get_spec_mgmt_action_subtype(uint8_t action_code)
47 {
48 	enum mgmt_frame_type frm_type;
49 
50 	switch (action_code) {
51 	case ACTION_SPCT_MSR_REQ:
52 		frm_type = MGMT_ACTION_MEAS_REQUEST;
53 		break;
54 	case ACTION_SPCT_MSR_RPRT:
55 		frm_type = MGMT_ACTION_MEAS_REPORT;
56 		break;
57 	case ACTION_SPCT_TPC_REQ:
58 		frm_type = MGMT_ACTION_TPC_REQUEST;
59 		break;
60 	case ACTION_SPCT_TPC_RPRT:
61 		frm_type = MGMT_ACTION_TPC_REPORT;
62 		break;
63 	case ACTION_SPCT_CHL_SWITCH:
64 		frm_type = MGMT_ACTION_CHAN_SWITCH;
65 		break;
66 	default:
67 		frm_type = MGMT_FRM_UNSPECIFIED;
68 		break;
69 	}
70 
71 	return frm_type;
72 }
73 
74 /**
75  * mgmt_get_qos_action_subtype() - gets qos action subtype
76  * @action_code: action code
77  *
78  * This function returns the subtype for qos action
79  * category.
80  *
81  * Return: mgmt frame type
82  */
83 static enum mgmt_frame_type
84 mgmt_get_qos_action_subtype(uint8_t action_code)
85 {
86 	enum mgmt_frame_type frm_type;
87 
88 	switch (action_code) {
89 	case QOS_ADD_TS_REQ:
90 		frm_type = MGMT_ACTION_QOS_ADD_TS_REQ;
91 		break;
92 	case QOS_ADD_TS_RSP:
93 		frm_type = MGMT_ACTION_QOS_ADD_TS_RSP;
94 		break;
95 	case QOS_DEL_TS_REQ:
96 		frm_type = MGMT_ACTION_QOS_DEL_TS_REQ;
97 		break;
98 	case QOS_SCHEDULE:
99 		frm_type = MGMT_ACTION_QOS_SCHEDULE;
100 		break;
101 	case QOS_MAP_CONFIGURE:
102 		frm_type = MGMT_ACTION_QOS_MAP_CONFIGURE;
103 		break;
104 	default:
105 		frm_type = MGMT_FRM_UNSPECIFIED;
106 		break;
107 	}
108 
109 	return frm_type;
110 }
111 
112 /**
113  * mgmt_get_dls_action_subtype() - gets dls action subtype
114  * @action_code: action code
115  *
116  * This function returns the subtype for dls action
117  * category.
118  *
119  * Return: mgmt frame type
120  */
121 static enum mgmt_frame_type
122 mgmt_get_dls_action_subtype(uint8_t action_code)
123 {
124 	enum mgmt_frame_type frm_type;
125 
126 	switch (action_code) {
127 	case DLS_REQUEST:
128 		frm_type = MGMT_ACTION_DLS_REQUEST;
129 		break;
130 	case DLS_RESPONSE:
131 		frm_type = MGMT_ACTION_DLS_RESPONSE;
132 		break;
133 	case DLS_TEARDOWN:
134 		frm_type = MGMT_ACTION_DLS_TEARDOWN;
135 		break;
136 	default:
137 		frm_type = MGMT_FRM_UNSPECIFIED;
138 		break;
139 	}
140 
141 	return frm_type;
142 }
143 
144 /**
145  * mgmt_get_back_action_subtype() - gets block ack action subtype
146  * @action_code: action code
147  *
148  * This function returns the subtype for block ack action
149  * category.
150  *
151  * Return: mgmt frame type
152  */
153 static enum mgmt_frame_type
154 mgmt_get_back_action_subtype(uint8_t action_code)
155 {
156 	enum mgmt_frame_type frm_type;
157 
158 	switch (action_code) {
159 	case ADDBA_REQUEST:
160 		frm_type = MGMT_ACTION_BA_ADDBA_REQUEST;
161 		break;
162 	case ADDBA_RESPONSE:
163 		frm_type = MGMT_ACTION_BA_ADDBA_RESPONSE;
164 		break;
165 	case DELBA:
166 		frm_type = MGMT_ACTION_BA_DELBA;
167 		break;
168 	default:
169 		frm_type = MGMT_FRM_UNSPECIFIED;
170 		break;
171 	}
172 
173 	return frm_type;
174 }
175 
176 /**
177  * mgmt_get_public_action_subtype() - gets public action subtype
178  * @action_code: action code
179  *
180  * This function returns the subtype for public action
181  * category.
182  *
183  * Return: mgmt frame type
184  */
185 static enum mgmt_frame_type
186 mgmt_get_public_action_subtype(uint8_t action_code)
187 {
188 	enum mgmt_frame_type frm_type;
189 
190 	switch (action_code) {
191 	case PUB_ACTION_2040_BSS_COEXISTENCE:
192 		frm_type = MGMT_ACTION_2040_BSS_COEXISTENCE;
193 		break;
194 	case PUB_ACTION_EXT_CHANNEL_SWITCH_ID:
195 		frm_type = MGMT_ACTION_EXT_CHANNEL_SWITCH_ID;
196 		break;
197 	case PUB_ACTION_VENDOR_SPECIFIC:
198 		frm_type = MGMT_ACTION_VENDOR_SPECIFIC;
199 		break;
200 	case PUB_ACTION_TDLS_DISCRESP:
201 		frm_type = MGMT_ACTION_TDLS_DISCRESP;
202 		break;
203 	case PUB_ACTION_GAS_INITIAL_REQUEST:
204 		frm_type = MGMT_ACTION_GAS_INITIAL_REQUEST;
205 		break;
206 	case PUB_ACTION_GAS_INITIAL_RESPONSE:
207 		frm_type = MGMT_ACTION_GAS_INITIAL_RESPONSE;
208 		break;
209 	case PUB_ACTION_GAS_COMEBACK_REQUEST:
210 		frm_type = MGMT_ACTION_GAS_COMEBACK_REQUEST;
211 		break;
212 	case PUB_ACTION_GAS_COMEBACK_RESPONSE:
213 		frm_type = MGMT_ACTION_GAS_COMEBACK_RESPONSE;
214 		break;
215 	case PUB_ACTION_FTM_REQUEST:
216 		frm_type = MGMT_ACTION_FTM_REQUEST;
217 		break;
218 	case PUB_ACTION_FTM_RESPONSE:
219 		frm_type = MGMT_ACTION_FTM_RESPONSE;
220 		break;
221 	default:
222 		frm_type = MGMT_FRM_UNSPECIFIED;
223 		break;
224 	}
225 
226 	return frm_type;
227 }
228 
229 /**
230  * mgmt_get_rrm_action_subtype() - gets rrm action subtype
231  * @action_code: action code
232  *
233  * This function returns the subtype for rrm action
234  * category.
235  *
236  * Return: mgmt frame type
237  */
238 static enum mgmt_frame_type
239 mgmt_get_rrm_action_subtype(uint8_t action_code)
240 {
241 	enum mgmt_frame_type frm_type;
242 
243 	switch (action_code) {
244 	case RRM_RADIO_MEASURE_REQ:
245 		frm_type = MGMT_ACTION_RRM_RADIO_MEASURE_REQ;
246 		break;
247 	case RRM_RADIO_MEASURE_RPT:
248 		frm_type = MGMT_ACTION_RRM_RADIO_MEASURE_RPT;
249 		break;
250 	case RRM_LINK_MEASUREMENT_REQ:
251 		frm_type = MGMT_ACTION_RRM_LINK_MEASUREMENT_REQ;
252 		break;
253 	case RRM_LINK_MEASUREMENT_RPT:
254 		frm_type = MGMT_ACTION_RRM_LINK_MEASUREMENT_RPT;
255 		break;
256 	case RRM_NEIGHBOR_REQ:
257 		frm_type = MGMT_ACTION_RRM_NEIGHBOR_REQ;
258 		break;
259 	case RRM_NEIGHBOR_RPT:
260 		frm_type = MGMT_ACTION_RRM_NEIGHBOR_RPT;
261 		break;
262 	default:
263 		frm_type = MGMT_FRM_UNSPECIFIED;
264 		break;
265 	}
266 
267 	return frm_type;
268 }
269 
270 static enum mgmt_frame_type
271 mgmt_get_ft_action_subtype(uint8_t action_code)
272 {
273 	enum mgmt_frame_type frm_type;
274 
275 	switch (action_code) {
276 	case FT_FAST_BSS_TRNST_REQ:
277 		frm_type = MGMT_ACTION_FT_REQUEST;
278 		break;
279 	case FT_FAST_BSS_TRNST_RES:
280 		frm_type = MGMT_ACTION_FT_RESPONSE;
281 		break;
282 	case FT_FAST_BSS_TRNST_CONFIRM:
283 		frm_type = MGMT_ACTION_FT_CONFIRM;
284 		break;
285 	case FT_FAST_BSS_TRNST_ACK:
286 		frm_type = MGMT_ACTION_FT_ACK;
287 		break;
288 	default:
289 		frm_type = MGMT_FRM_UNSPECIFIED;
290 		break;
291 	}
292 
293 	return frm_type;
294 }
295 
296 /**
297  * mgmt_get_ht_action_subtype() - gets ht action subtype
298  * @action_code: action code
299  *
300  * This function returns the subtype for ht action
301  * category.
302  *
303  * Return: mgmt frame type
304  */
305 static enum mgmt_frame_type
306 mgmt_get_ht_action_subtype(uint8_t action_code)
307 {
308 	enum mgmt_frame_type frm_type;
309 
310 	switch (action_code) {
311 	case HT_ACTION_NOTIFY_CHANWIDTH:
312 		frm_type = MGMT_ACTION_HT_NOTIFY_CHANWIDTH;
313 		break;
314 	case HT_ACTION_SMPS:
315 		frm_type = MGMT_ACTION_HT_SMPS;
316 		break;
317 	case HT_ACTION_PSMP:
318 		frm_type = MGMT_ACTION_HT_PSMP;
319 		break;
320 	case HT_ACTION_PCO_PHASE:
321 		frm_type = MGMT_ACTION_HT_PCO_PHASE;
322 		break;
323 	case HT_ACTION_CSI:
324 		frm_type = MGMT_ACTION_HT_CSI;
325 		break;
326 	case HT_ACTION_NONCOMPRESSED_BF:
327 		frm_type = MGMT_ACTION_HT_NONCOMPRESSED_BF;
328 		break;
329 	case HT_ACTION_COMPRESSED_BF:
330 		frm_type = MGMT_ACTION_HT_COMPRESSED_BF;
331 		break;
332 	case HT_ACTION_ASEL_IDX_FEEDBACK:
333 		frm_type = MGMT_ACTION_HT_ASEL_IDX_FEEDBACK;
334 		break;
335 	default:
336 		frm_type = MGMT_FRM_UNSPECIFIED;
337 		break;
338 	}
339 
340 	return frm_type;
341 }
342 
343 /**
344  * mgmt_get_sa_query_action_subtype() - gets sa query action subtype
345  * @action_code: action code
346  *
347  * This function returns the subtype for sa query action
348  * category.
349  *
350  * Return: mgmt frame type
351  */
352 static enum mgmt_frame_type
353 mgmt_get_sa_query_action_subtype(uint8_t action_code)
354 {
355 	enum mgmt_frame_type frm_type;
356 
357 	switch (action_code) {
358 	case SA_QUERY_REQUEST:
359 		frm_type = MGMT_ACTION_SA_QUERY_REQUEST;
360 		break;
361 	case SA_QUERY_RESPONSE:
362 		frm_type = MGMT_ACTION_SA_QUERY_RESPONSE;
363 		break;
364 	default:
365 		frm_type = MGMT_FRM_UNSPECIFIED;
366 		break;
367 	}
368 
369 	return frm_type;
370 }
371 
372 /**
373  * mgmt_get_pdpa_action_subtype() - gets pdpa action subtype
374  * @action_code: action code
375  *
376  * This function returns the subtype for protected dual public
377  * action category.
378  *
379  * Return: mgmt frame type
380  */
381 static enum mgmt_frame_type
382 mgmt_get_pdpa_action_subtype(uint8_t action_code)
383 {
384 	enum mgmt_frame_type frm_type;
385 
386 	switch (action_code) {
387 	case PDPA_GAS_INIT_REQ:
388 		frm_type = MGMT_ACTION_PDPA_GAS_INIT_REQ;
389 		break;
390 	case PDPA_GAS_INIT_RSP:
391 		frm_type = MGMT_ACTION_PDPA_GAS_INIT_RSP;
392 		break;
393 	case PDPA_GAS_COMEBACK_REQ:
394 		frm_type = MGMT_ACTION_PDPA_GAS_COMEBACK_REQ;
395 		break;
396 	case PDPA_GAS_COMEBACK_RSP:
397 		frm_type = MGMT_ACTION_PDPA_GAS_COMEBACK_RSP;
398 		break;
399 	default:
400 		frm_type = MGMT_FRM_UNSPECIFIED;
401 		break;
402 	}
403 
404 	return frm_type;
405 }
406 
407 /**
408  * mgmt_get_wnm_action_subtype() - gets wnm action subtype
409  * @action_code: action code
410  *
411  * This function returns the subtype for wnm action
412  * category.
413  *
414  * Return: mgmt frame type
415  */
416 static enum mgmt_frame_type
417 mgmt_get_wnm_action_subtype(uint8_t action_code)
418 {
419 	enum mgmt_frame_type frm_type;
420 
421 	switch (action_code) {
422 	case WNM_BSS_TM_QUERY:
423 		frm_type = MGMT_ACTION_WNM_BSS_TM_QUERY;
424 		break;
425 	case WNM_BSS_TM_REQUEST:
426 		frm_type = MGMT_ACTION_WNM_BSS_TM_REQUEST;
427 		break;
428 	case WNM_BSS_TM_RESPONSE:
429 		frm_type = MGMT_ACTION_WNM_BSS_TM_RESPONSE;
430 		break;
431 	case WNM_NOTIF_REQUEST:
432 		frm_type = MGMT_ACTION_WNM_NOTIF_REQUEST;
433 		break;
434 	case WNM_NOTIF_RESPONSE:
435 		frm_type = MGMT_ACTION_WNM_NOTIF_RESPONSE;
436 		break;
437 	case WNM_FMS_REQ:
438 		frm_type = MGMT_ACTION_WNM_FMS_REQ;
439 		break;
440 	case WNM_FMS_RESP:
441 		frm_type = MGMT_ACTION_WNM_FMS_RESP;
442 		break;
443 	case WNM_TFS_REQ:
444 		frm_type = MGMT_ACTION_WNM_TFS_REQ;
445 		break;
446 	case WNM_TFS_RESP:
447 		frm_type = MGMT_ACTION_WNM_TFS_RESP;
448 		break;
449 	case WNM_TFS_NOTIFY:
450 		frm_type = MGMT_ACTION_WNM_TFS_NOTIFY;
451 		break;
452 	case WNM_SLEEP_REQ:
453 		frm_type = MGMT_ACTION_WNM_SLEEP_REQ;
454 		break;
455 	case WNM_SLEEP_RESP:
456 		frm_type = MGMT_ACTION_WNM_SLEEP_RESP;
457 		break;
458 	case WNM_TIM_REQ:
459 		frm_type = MGMT_ACTION_WNM_TFS_REQ;
460 		break;
461 	case WNM_TIM_RESP:
462 		frm_type = MGMT_ACTION_WNM_TFS_RESP;
463 		break;
464 	default:
465 		frm_type = MGMT_FRM_UNSPECIFIED;
466 		break;
467 	}
468 
469 	return frm_type;
470 }
471 
472 /**
473  * mgmt_get_wnm_action_subtype() - gets tdls action subtype
474  * @action_code: action code
475  *
476  * This function returns the subtype for tdls action
477  * category.
478  *
479  * Return: mgmt frame type
480  */
481 static enum mgmt_frame_type
482 mgmt_get_tdls_action_subtype(uint8_t action_code)
483 {
484 	enum mgmt_frame_type frm_type;
485 
486 	switch (action_code) {
487 	case TDLS_SETUP_REQUEST:
488 		frm_type = MGMT_ACTION_TDLS_SETUP_REQ;
489 		break;
490 	case TDLS_SETUP_RESPONSE:
491 		frm_type = MGMT_ACTION_TDLS_SETUP_RSP;
492 		break;
493 	case TDLS_SETUP_CONFIRM:
494 		frm_type = MGMT_ACTION_TDLS_SETUP_CNF;
495 		break;
496 	case TDLS_TEARDOWN:
497 		frm_type = MGMT_ACTION_TDLS_TEARDOWN;
498 		break;
499 	case TDLS_PEER_TRAFFIC_INDICATION:
500 		frm_type = MGMT_ACTION_TDLS_PEER_TRAFFIC_IND;
501 		break;
502 	case TDLS_CHANNEL_SWITCH_REQUEST:
503 		frm_type = MGMT_ACTION_TDLS_CH_SWITCH_REQ;
504 		break;
505 	case TDLS_CHANNEL_SWITCH_RESPONSE:
506 		frm_type = MGMT_ACTION_TDLS_CH_SWITCH_RSP;
507 		break;
508 	case TDLS_PEER_PSM_REQUEST:
509 		frm_type = MGMT_ACTION_TDLS_PEER_PSM_REQUEST;
510 		break;
511 	case TDLS_PEER_PSM_RESPONSE:
512 		frm_type = MGMT_ACTION_TDLS_PEER_PSM_RESPONSE;
513 		break;
514 	case TDLS_PEER_TRAFFIC_RESPONSE:
515 		frm_type = MGMT_ACTION_TDLS_PEER_TRAFFIC_RSP;
516 		break;
517 	case TDLS_DISCOVERY_REQUEST:
518 		frm_type = MGMT_ACTION_TDLS_DIS_REQ;
519 		break;
520 	default:
521 		frm_type = MGMT_FRM_UNSPECIFIED;
522 		break;
523 	}
524 
525 	return frm_type;
526 }
527 
528 /**
529  * mgmt_get_mesh_action_subtype() - gets mesh action subtype
530  * @action_code: action code
531  *
532  * This function returns the subtype for mesh action
533  * category.
534  *
535  * Return: mgmt frame type
536  */
537 static enum mgmt_frame_type
538 mgmt_get_mesh_action_subtype(uint8_t action_code)
539 {
540 	enum mgmt_frame_type frm_type;
541 
542 	switch (action_code) {
543 	case MESH_ACTION_LINK_METRIC_REPORT:
544 		frm_type = MGMT_ACTION_MESH_LINK_METRIC_REPORT;
545 		break;
546 	case MESH_ACTION_HWMP_PATH_SELECTION:
547 		frm_type = MGMT_ACTION_MESH_HWMP_PATH_SELECTION;
548 		break;
549 	case MESH_ACTION_GATE_ANNOUNCEMENT:
550 		frm_type = MGMT_ACTION_MESH_GATE_ANNOUNCEMENT;
551 		break;
552 	case MESH_ACTION_CONGESTION_CONTROL_NOTIFICATION:
553 		frm_type = MGMT_ACTION_MESH_CONGESTION_CONTROL_NOTIFICATION;
554 		break;
555 	case MESH_ACTION_MCCA_SETUP_REQUEST:
556 		frm_type = MGMT_ACTION_MESH_MCCA_SETUP_REQUEST;
557 		break;
558 	case MESH_ACTION_MCCA_SETUP_REPLY:
559 		frm_type = MGMT_ACTION_MESH_MCCA_SETUP_REPLY;
560 		break;
561 	case MESH_ACTION_MCCA_ADVERTISEMENT_REQUEST:
562 		frm_type = MGMT_ACTION_MESH_MCCA_ADVERTISEMENT_REQUEST;
563 		break;
564 	case MESH_ACTION_MCCA_ADVERTISEMENT:
565 		frm_type = MGMT_ACTION_MESH_MCCA_ADVERTISEMENT;
566 		break;
567 	case MESH_ACTION_MCCA_TEARDOWN:
568 		frm_type = MGMT_ACTION_MESH_MCCA_TEARDOWN;
569 		break;
570 	case MESH_ACTION_TBTT_ADJUSTMENT_REQUEST:
571 		frm_type = MGMT_ACTION_MESH_TBTT_ADJUSTMENT_REQUEST;
572 		break;
573 	case MESH_ACTION_TBTT_ADJUSTMENT_RESPONSE:
574 		frm_type = MGMT_ACTION_MESH_TBTT_ADJUSTMENT_RESPONSE;
575 		break;
576 	default:
577 		frm_type = MGMT_FRM_UNSPECIFIED;
578 		break;
579 	}
580 
581 	return frm_type;
582 }
583 
584 /**
585  * mgmt_get_self_prot_action_subtype() - gets self prot. action subtype
586  * @action_code: action code
587  *
588  * This function returns the subtype for self protected action
589  * category.
590  *
591  * Return: mgmt frame type
592  */
593 static enum mgmt_frame_type
594 mgmt_get_self_prot_action_subtype(uint8_t action_code)
595 {
596 	enum mgmt_frame_type frm_type;
597 
598 	switch (action_code) {
599 	case SP_MESH_PEERING_OPEN:
600 		frm_type = MGMT_ACTION_SP_MESH_PEERING_OPEN;
601 		break;
602 	case SP_MESH_PEERING_CONFIRM:
603 		frm_type = MGMT_ACTION_SP_MESH_PEERING_CONFIRM;
604 		break;
605 	case SP_MESH_PEERING_CLOSE:
606 		frm_type = MGMT_ACTION_SP_MESH_PEERING_CLOSE;
607 		break;
608 	case SP_MGK_INFORM:
609 		frm_type = MGMT_ACTION_SP_MGK_INFORM;
610 		break;
611 	case SP_MGK_ACK:
612 		frm_type = MGMT_ACTION_SP_MGK_ACK;
613 		break;
614 	default:
615 		frm_type = MGMT_FRM_UNSPECIFIED;
616 		break;
617 	}
618 
619 	return frm_type;
620 }
621 
622 /**
623  * mgmt_get_wmm_action_subtype() - gets wmm action subtype
624  * @action_code: action code
625  *
626  * This function returns the subtype for wmm action
627  * category.
628  *
629  * Return: mgmt frame type
630  */
631 static enum mgmt_frame_type
632 mgmt_get_wmm_action_subtype(uint8_t action_code)
633 {
634 	enum mgmt_frame_type frm_type;
635 
636 	switch (action_code) {
637 	case WMM_QOS_SETUP_REQ:
638 		frm_type = MGMT_ACTION_WMM_QOS_SETUP_REQ;
639 		break;
640 	case WMM_QOS_SETUP_RESP:
641 		frm_type = MGMT_ACTION_WMM_QOS_SETUP_RESP;
642 		break;
643 	case WMM_QOS_TEARDOWN:
644 		frm_type = MGMT_ACTION_WMM_QOS_TEARDOWN;
645 		break;
646 	default:
647 		frm_type = MGMT_FRM_UNSPECIFIED;
648 		break;
649 	}
650 
651 	return frm_type;
652 }
653 
654 /**
655  * mgmt_get_vht_action_subtype() - gets vht action subtype
656  * @action_code: action code
657  *
658  * This function returns the subtype for vht action
659  * category.
660  *
661  * Return: mgmt frame type
662  */
663 static enum mgmt_frame_type
664 mgmt_get_vht_action_subtype(uint8_t action_code)
665 {
666 	enum mgmt_frame_type frm_type;
667 
668 	switch (action_code) {
669 	case VHT_ACTION_COMPRESSED_BF:
670 		frm_type = MGMT_ACTION_VHT_COMPRESSED_BF;
671 		break;
672 	case VHT_ACTION_GID_NOTIF:
673 		frm_type = MGMT_ACTION_VHT_GID_NOTIF;
674 		break;
675 	case VHT_ACTION_OPMODE_NOTIF:
676 		frm_type = MGMT_ACTION_VHT_OPMODE_NOTIF;
677 		break;
678 	default:
679 		frm_type = MGMT_FRM_UNSPECIFIED;
680 		break;
681 	}
682 
683 	return frm_type;
684 }
685 
686 /**
687  * mgmt_get_fst_action_subtype() - gets fst action subtype
688  * @action_code: action code
689  *
690  * This function returns the subtype for fst action
691  * category.
692  *
693  * Return: mgmt frame type
694  */
695 static enum mgmt_frame_type
696 mgmt_get_fst_action_subtype(uint8_t action_code)
697 {
698 	enum mgmt_frame_type frm_type;
699 
700 	switch (action_code) {
701 	case FST_SETUP_REQ:
702 		frm_type = MGMT_ACTION_FST_SETUP_REQ;
703 		break;
704 	case FST_SETUP_RSP:
705 		frm_type = MGMT_ACTION_FST_SETUP_RSP;
706 		break;
707 	case FST_TEAR_DOWN:
708 		frm_type = MGMT_ACTION_FST_TEAR_DOWN;
709 		break;
710 	case FST_ACK_REQ:
711 		frm_type = MGMT_ACTION_FST_ACK_REQ;
712 		break;
713 	case FST_ACK_RSP:
714 		frm_type = MGMT_ACTION_FST_ACK_RSP;
715 		break;
716 	case FST_ON_CHANNEL_TUNNEL:
717 		frm_type = MGMT_ACTION_FST_ON_CHANNEL_TUNNEL;
718 		break;
719 	default:
720 		frm_type = MGMT_FRM_UNSPECIFIED;
721 		break;
722 	}
723 
724 	return frm_type;
725 }
726 
727 /**
728  * mgmt_get_rvs_action_subtype() - gets rvs action subtype
729  * @action_code: action code
730  *
731  * This function returns the subtype for rvs action
732  * category.
733  *
734  * Return: mgmt frame type
735  */
736 static enum mgmt_frame_type
737 mgmt_get_rvs_action_subtype(uint8_t action_code)
738 {
739 	enum mgmt_frame_type frm_type;
740 
741 	switch (action_code) {
742 	case SCS_REQ:
743 		frm_type = MGMT_ACTION_SCS_REQ;
744 		break;
745 	case SCS_RSP:
746 		frm_type = MGMT_ACTION_SCS_RSP;
747 		break;
748 	case GROUP_MEMBERSHIP_REQ:
749 		frm_type = MGMT_ACTION_GROUP_MEMBERSHIP_REQ;
750 		break;
751 	case GROUP_MEMBERSHIP_RSP:
752 		frm_type = MGMT_ACTION_GROUP_MEMBERSHIP_RSP;
753 		break;
754 	case MCSC_REQ:
755 		frm_type = MGMT_ACTION_MCSC_REQ;
756 		break;
757 	case MCSC_RSP:
758 		frm_type = MGMT_ACTION_MCSC_RSP;
759 		break;
760 	default:
761 		frm_type = MGMT_FRM_UNSPECIFIED;
762 		break;
763 	}
764 
765 	return frm_type;
766 }
767 
768 /**
769  * mgmt_get_twt_action_subtype() - gets twt action subtype
770  * @action_code: action code
771  *
772  * This function returns the subtype for twt action
773  * category.
774  *
775  * Return: mgmt frame type
776  */
777 static enum mgmt_frame_type
778 mgmt_get_twt_action_subtype(uint8_t action_code)
779 {
780 	enum mgmt_frame_type frm_type;
781 
782 	switch (action_code) {
783 	case TWT_SETUP:
784 		frm_type = MGMT_ACTION_TWT_SETUP;
785 		break;
786 	case TWT_TEARDOWN:
787 		frm_type = MGMT_ACTION_TWT_TEARDOWN;
788 		break;
789 	case TWT_INFORMATION:
790 		frm_type = MGMT_ACTION_TWT_INFORMATION;
791 		break;
792 	default:
793 		frm_type = MGMT_FRM_UNSPECIFIED;
794 		break;
795 	}
796 
797 	return frm_type;
798 }
799 
800 #ifdef WLAN_FEATURE_11BE
801 /**
802  * mgmt_get_protected_eht_action_subtype() - gets protected EHT action subtype
803  * @action_code: action code
804  *
805  * This function returns the subtype for protected EHT action category.
806  *
807  * Return: mgmt frame type
808  */
809 static enum mgmt_frame_type
810 mgmt_get_protected_eht_action_subtype(uint8_t action_code)
811 {
812 	enum mgmt_frame_type frm_type;
813 
814 	switch (action_code) {
815 	case EHT_T2LM_REQUEST:
816 		frm_type = MGMT_ACTION_EHT_T2LM_REQUEST;
817 		break;
818 	case EHT_T2LM_RESPONSE:
819 		frm_type = MGMT_ACTION_EHT_T2LM_RESPONSE;
820 		break;
821 	case EHT_T2LM_TEARDOWN:
822 		frm_type = MGMT_ACTION_EHT_T2LM_TEARDOWN;
823 		break;
824 	default:
825 		frm_type = MGMT_FRM_UNSPECIFIED;
826 		break;
827 	}
828 
829 	return frm_type;
830 }
831 #else
832 static enum mgmt_frame_type
833 mgmt_get_protected_eht_action_subtype(uint8_t action_code)
834 {
835 	return MGMT_FRM_UNSPECIFIED;
836 }
837 #endif /* WLAN_FEATURE_11BE */
838 
839 /**
840  * mgmt_txrx_get_action_frm_subtype() - gets action frm subtype
841  * @mpdu_data_ptr: pointer to mpdu data
842  *
843  * This function determines the action category of the frame
844  * and calls respective function to get mgmt frame type.
845  *
846  * Return: mgmt frame type
847  */
848 static enum mgmt_frame_type
849 mgmt_txrx_get_action_frm_subtype(uint8_t *mpdu_data_ptr)
850 {
851 	struct action_frm_hdr *action_hdr =
852 			(struct action_frm_hdr *)mpdu_data_ptr;
853 	enum mgmt_frame_type frm_type;
854 
855 	switch (action_hdr->action_category) {
856 	case ACTION_CATEGORY_SPECTRUM_MGMT:
857 		frm_type = mgmt_get_spec_mgmt_action_subtype(
858 						action_hdr->action_code);
859 		break;
860 	case ACTION_FAST_BSS_TRNST:
861 		frm_type = mgmt_get_ft_action_subtype(action_hdr->action_code);
862 		break;
863 	case ACTION_CATEGORY_QOS:
864 		frm_type = mgmt_get_qos_action_subtype(action_hdr->action_code);
865 		break;
866 	case ACTION_CATEGORY_DLS:
867 		frm_type = mgmt_get_dls_action_subtype(action_hdr->action_code);
868 		break;
869 	case ACTION_CATEGORY_BACK:
870 		frm_type = mgmt_get_back_action_subtype(
871 						action_hdr->action_code);
872 		break;
873 	case ACTION_CATEGORY_PUBLIC:
874 		frm_type = mgmt_get_public_action_subtype(
875 						action_hdr->action_code);
876 		break;
877 	case ACTION_CATEGORY_RRM:
878 		frm_type = mgmt_get_rrm_action_subtype(action_hdr->action_code);
879 		break;
880 	case ACTION_CATEGORY_HT:
881 		frm_type = mgmt_get_ht_action_subtype(action_hdr->action_code);
882 		break;
883 	case ACTION_CATEGORY_SA_QUERY:
884 		frm_type = mgmt_get_sa_query_action_subtype(
885 						action_hdr->action_code);
886 		break;
887 	case ACTION_CATEGORY_PROTECTED_DUAL_OF_PUBLIC_ACTION:
888 		frm_type = mgmt_get_pdpa_action_subtype(
889 						action_hdr->action_code);
890 		break;
891 	case ACTION_CATEGORY_WNM:
892 		frm_type = mgmt_get_wnm_action_subtype(action_hdr->action_code);
893 		break;
894 	case ACTION_CATEGORY_TDLS:
895 		frm_type = mgmt_get_tdls_action_subtype(
896 						action_hdr->action_code);
897 		break;
898 	case ACTION_CATEGORY_MESH_ACTION:
899 		frm_type = mgmt_get_mesh_action_subtype(
900 						action_hdr->action_code);
901 		break;
902 	case ACTION_CATEGORY_SELF_PROTECTED:
903 		frm_type = mgmt_get_self_prot_action_subtype(
904 						action_hdr->action_code);
905 		break;
906 	case ACTION_CATEGORY_WMM:
907 		frm_type = mgmt_get_wmm_action_subtype(action_hdr->action_code);
908 		break;
909 	case ACTION_CATEGORY_VHT:
910 		frm_type = mgmt_get_vht_action_subtype(action_hdr->action_code);
911 		break;
912 	case ACTION_CATEGORY_VENDOR_SPECIFIC:
913 		frm_type = MGMT_ACTION_CATEGORY_VENDOR_SPECIFIC;
914 		break;
915 	case ACTION_CATEGORY_VENDOR_SPECIFIC_PROTECTED:
916 		frm_type = MGMT_ACTION_CATEGORY_VENDOR_SPECIFIC_PROTECTED;
917 		break;
918 	case ACTION_CATEGORY_FST:
919 		frm_type = mgmt_get_fst_action_subtype(action_hdr->action_code);
920 		break;
921 	case ACTION_CATEGORY_RVS:
922 		frm_type =
923 			mgmt_get_rvs_action_subtype(action_hdr->action_code);
924 		break;
925 	case ACTION_CATEGORY_USIG:
926 		frm_type =
927 			mgmt_get_twt_action_subtype(action_hdr->action_code);
928 		break;
929 	case ACTION_CATEGORY_PROTECTED_EHT:
930 		frm_type = mgmt_get_protected_eht_action_subtype(
931 				action_hdr->action_code);
932 		break;
933 	default:
934 		frm_type = MGMT_FRM_UNSPECIFIED;
935 		break;
936 	}
937 
938 	return frm_type;
939 }
940 
941 /**
942  * mgmt_txrx_get_frm_type() - gets mgmt frm type
943  * @mgmt_subtype: mgmt subtype
944  * @mpdu_data_ptr: pointer to mpdu data
945  *
946  * This function returns mgmt frame type of the frame
947  * based on the mgmt subtype.
948  *
949  * Return: mgmt frame type
950  */
951 static enum mgmt_frame_type
952 mgmt_txrx_get_frm_type(uint8_t mgmt_subtype, uint8_t *mpdu_data_ptr)
953 {
954 	enum mgmt_frame_type frm_type;
955 
956 	switch (mgmt_subtype) {
957 	case MGMT_SUBTYPE_ASSOC_REQ:
958 		frm_type = MGMT_ASSOC_REQ;
959 		break;
960 	case MGMT_SUBTYPE_ASSOC_RESP:
961 		frm_type = MGMT_ASSOC_RESP;
962 		break;
963 	case MGMT_SUBTYPE_REASSOC_REQ:
964 		frm_type = MGMT_ASSOC_REQ;
965 		break;
966 	case MGMT_SUBTYPE_REASSOC_RESP:
967 		frm_type = MGMT_REASSOC_RESP;
968 		break;
969 	case MGMT_SUBTYPE_PROBE_REQ:
970 		frm_type = MGMT_PROBE_REQ;
971 		break;
972 	case MGMT_SUBTYPE_PROBE_RESP:
973 		frm_type = MGMT_PROBE_RESP;
974 		break;
975 	case MGMT_SUBTYPE_BEACON:
976 		frm_type = MGMT_BEACON;
977 		break;
978 	case MGMT_SUBTYPE_ATIM:
979 		frm_type = MGMT_ATIM;
980 		break;
981 	case MGMT_SUBTYPE_DISASSOC:
982 		frm_type = MGMT_DISASSOC;
983 		break;
984 	case MGMT_SUBTYPE_AUTH:
985 		frm_type = MGMT_AUTH;
986 		break;
987 	case MGMT_SUBTYPE_DEAUTH:
988 		frm_type = MGMT_DEAUTH;
989 		break;
990 	case MGMT_SUBTYPE_ACTION:
991 	case MGMT_SUBTYPE_ACTION_NO_ACK:
992 		frm_type = mgmt_txrx_get_action_frm_subtype(mpdu_data_ptr);
993 		break;
994 	default:
995 		frm_type = MGMT_FRM_UNSPECIFIED;
996 		break;
997 	}
998 
999 	return frm_type;
1000 }
1001 
1002 #ifdef WLAN_IOT_SIM_SUPPORT
1003 static QDF_STATUS simulation_frame_update(struct wlan_objmgr_psoc *psoc,
1004 					  qdf_nbuf_t buf,
1005 					  struct mgmt_rx_event_params *rx_param)
1006 {
1007 	uint8_t *addr = NULL;
1008 	struct wlan_objmgr_vdev *vdev = NULL;
1009 	uint8_t pdevid = 0;
1010 	wlan_objmgr_ref_dbgid dbgid;
1011 	struct wlan_lmac_if_rx_ops *rx_ops = NULL;
1012 	struct wlan_objmgr_pdev *pdev;
1013 	struct ieee80211_frame *wh;
1014 	u_int8_t *data;
1015 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1016 
1017 	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
1018 	if (rx_ops && rx_ops->iot_sim_rx_ops.iot_sim_cmd_handler) {
1019 		data = (uint8_t *)qdf_nbuf_data(buf);
1020 		wh = (struct ieee80211_frame *)data;
1021 		addr = (uint8_t *)wh->i_addr3;
1022 		pdevid = rx_param->pdev_id;
1023 		dbgid = WLAN_IOT_SIM_ID;
1024 		if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)addr)) {
1025 			pdev = wlan_objmgr_get_pdev_by_id(psoc, pdevid,
1026 							  dbgid);
1027 			if (pdev) {
1028 				vdev = wlan_objmgr_pdev_get_first_vdev(pdev,
1029 								       dbgid);
1030 				wlan_objmgr_pdev_release_ref(pdev, dbgid);
1031 			}
1032 		} else
1033 			vdev = wlan_objmgr_get_vdev_by_macaddr_from_psoc(psoc,
1034 									 pdevid,
1035 									 addr,
1036 									 dbgid);
1037 		if (vdev) {
1038 			status = rx_ops->iot_sim_rx_ops.
1039 					iot_sim_cmd_handler(vdev, buf,
1040 							    NULL, false,
1041 							    rx_param);
1042 			if (status == QDF_STATUS_E_NULL_VALUE) {
1043 				wlan_objmgr_vdev_release_ref(vdev, dbgid);
1044 				mgmt_txrx_debug("iot_sim:Pkt processed at RX");
1045 				return status;
1046 			}
1047 			wlan_objmgr_vdev_release_ref(vdev, dbgid);
1048 		}
1049 	}
1050 	return status;
1051 }
1052 #else
1053 static QDF_STATUS simulation_frame_update(struct wlan_objmgr_psoc *psoc,
1054 					  qdf_nbuf_t buf,
1055 					  struct mgmt_rx_event_params *rx_param)
1056 {
1057 	return QDF_STATUS_SUCCESS;
1058 }
1059 #endif
1060 
1061 /**
1062  * wlan_mgmt_rx_beacon_rate_limit() - rate limiting mgmt beacons
1063  * @psoc - pointer to psoc struct
1064  * @mgmt_rx_params - rx params
1065  *
1066  * This function will drop the beacons if the number of beacons
1067  * received is greater than the percentage of limit of beacons to max
1068  * count of beacons, when beacon rate limiting is enabled
1069  *
1070  * Return : QDF_STATUS if success, else QDF_STATUS_E_RESOURCES
1071  */
1072 static QDF_STATUS wlan_mgmt_rx_beacon_rate_limit(struct wlan_objmgr_psoc *psoc,
1073 						 struct mgmt_rx_event_params
1074 						 *mgmt_rx_params)
1075 {
1076 	struct wlan_objmgr_pdev *pdev = NULL;
1077 
1078 	pdev = wlan_objmgr_get_pdev_by_id(psoc, mgmt_rx_params->pdev_id,
1079 					  WLAN_MGMT_SB_ID);
1080 
1081 	if (pdev && pdev->pdev_objmgr.bcn.bcn_rate_limit) {
1082 		uint64_t b_limit = qdf_do_div(
1083 				(wlan_pdev_get_max_beacon_count(pdev) *
1084 				 wlan_pdev_get_max_beacon_limit(pdev)), 100);
1085 		wlan_pdev_incr_wlan_beacon_count(pdev);
1086 
1087 		if (wlan_pdev_get_wlan_beacon_count(pdev) >=
1088 					wlan_pdev_get_max_beacon_count(pdev))
1089 			wlan_pdev_set_wlan_beacon_count(pdev, 0);
1090 
1091 		if (wlan_pdev_get_wlan_beacon_count(pdev) >= b_limit) {
1092 			wlan_pdev_incr_dropped_beacon_count(pdev);
1093 			wlan_objmgr_pdev_release_ref(pdev, WLAN_MGMT_SB_ID);
1094 			return QDF_STATUS_E_RESOURCES;
1095 		}
1096 	}
1097 
1098 	if (pdev)
1099 		wlan_objmgr_pdev_release_ref(pdev, WLAN_MGMT_SB_ID);
1100 
1101 	return QDF_STATUS_SUCCESS;
1102 }
1103 
1104 /**
1105  * wlan_mgmt_txrx_rx_handler_list_copy() - copies rx handler list
1106  * @rx_handler: pointer to rx handler list
1107  * @rx_handler_head: pointer to head of the copies list
1108  * @rx_handler_tail: pointer to tail of the copies list
1109  *
1110  * This function copies the rx handler linked list into a local
1111  * linked list.
1112  *
1113  * Return: QDF_STATUS_SUCCESS in case of success
1114  */
1115 static QDF_STATUS wlan_mgmt_txrx_rx_handler_list_copy(
1116 			struct mgmt_rx_handler *rx_handler,
1117 			struct mgmt_rx_handler **rx_handler_head,
1118 			struct mgmt_rx_handler **rx_handler_tail)
1119 {
1120 	struct mgmt_rx_handler *rx_handler_node;
1121 
1122 	while (rx_handler) {
1123 		rx_handler_node =
1124 				qdf_mem_malloc_atomic(sizeof(*rx_handler_node));
1125 		if (!rx_handler_node) {
1126 			mgmt_txrx_err_rl("Couldn't allocate memory for rx handler node");
1127 			return QDF_STATUS_E_NOMEM;
1128 		}
1129 
1130 		rx_handler_node->comp_id = rx_handler->comp_id;
1131 		rx_handler_node->rx_cb = rx_handler->rx_cb;
1132 		rx_handler_node->next = NULL;
1133 
1134 		if (!(*rx_handler_head)) {
1135 			*rx_handler_head = rx_handler_node;
1136 			*rx_handler_tail = *rx_handler_head;
1137 		} else {
1138 			(*rx_handler_tail)->next = rx_handler_node;
1139 			*rx_handler_tail = (*rx_handler_tail)->next;
1140 		}
1141 		rx_handler = rx_handler->next;
1142 	}
1143 
1144 	return QDF_STATUS_SUCCESS;
1145 }
1146 
1147 static bool
1148 mgmt_rx_is_bssid_valid(struct qdf_mac_addr *mac_addr)
1149 {
1150 	if (qdf_is_macaddr_group(mac_addr) ||
1151 	    qdf_is_macaddr_zero(mac_addr))
1152 		return false;
1153 
1154 	return true;
1155 }
1156 
1157 QDF_STATUS tgt_mgmt_txrx_rx_frame_handler(
1158 			struct wlan_objmgr_psoc *psoc,
1159 			qdf_nbuf_t buf,
1160 			struct mgmt_rx_event_params *mgmt_rx_params)
1161 {
1162 	struct mgmt_txrx_priv_psoc_context *mgmt_txrx_psoc_ctx;
1163 	struct ieee80211_frame *wh;
1164 	qdf_nbuf_t copy_buf;
1165 	struct wlan_objmgr_peer *peer = NULL;
1166 	uint8_t mgmt_type, mgmt_subtype;
1167 	uint8_t *mac_addr, *mpdu_data_ptr;
1168 	enum mgmt_frame_type frm_type;
1169 	struct mgmt_rx_handler *rx_handler;
1170 	struct mgmt_rx_handler *rx_handler_head = NULL, *rx_handler_tail = NULL;
1171 	u_int8_t *data, *ivp = NULL;
1172 	uint16_t buflen;
1173 	uint16_t len = 0;
1174 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1175 	bool is_from_addr_valid, is_bssid_valid;
1176 
1177 	if (!buf) {
1178 		mgmt_txrx_err("buffer passed is NULL");
1179 		return QDF_STATUS_E_INVAL;
1180 	}
1181 
1182 	if (!psoc) {
1183 		mgmt_txrx_err("psoc_ctx passed is NULL");
1184 		qdf_nbuf_free(buf);
1185 		return QDF_STATUS_E_INVAL;
1186 	}
1187 
1188 	data = (uint8_t *)qdf_nbuf_data(buf);
1189 	wh = (struct ieee80211_frame *)data;
1190 	buflen = qdf_nbuf_len(buf);
1191 
1192 	/**
1193 	 * TO DO (calculate pdev)
1194 	 * Waiting for a new parameter: pdev id to get added in rx event
1195 	 */
1196 
1197 	mgmt_type = (wh)->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1198 	mgmt_subtype = (wh)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1199 
1200 	if (mgmt_type != IEEE80211_FC0_TYPE_MGT &&
1201 	    mgmt_type != IEEE80211_FC0_TYPE_CTL) {
1202 		mgmt_txrx_err("Rx event doesn't contain a mgmt/ctrl packet, %d",
1203 			      mgmt_type);
1204 		qdf_nbuf_free(buf);
1205 		return QDF_STATUS_E_FAILURE;
1206 	}
1207 
1208 	is_from_addr_valid = mgmt_rx_is_bssid_valid((struct qdf_mac_addr *)
1209 							      wh->i_addr2);
1210 	is_bssid_valid = mgmt_rx_is_bssid_valid((struct qdf_mac_addr *)
1211 							      wh->i_addr3);
1212 
1213 	if (!is_from_addr_valid && !is_bssid_valid) {
1214 		mgmt_txrx_debug_rl("from addr "QDF_MAC_ADDR_FMT" bssid addr "QDF_MAC_ADDR_FMT" both not valid, dropping them",
1215 				   QDF_MAC_ADDR_REF(wh->i_addr2),
1216 				   QDF_MAC_ADDR_REF(wh->i_addr3));
1217 		qdf_nbuf_free(buf);
1218 		return QDF_STATUS_E_FAILURE;
1219 	}
1220 
1221 	if (mgmt_type == IEEE80211_FC0_TYPE_MGT &&
1222 	    (mgmt_subtype == MGMT_SUBTYPE_BEACON ||
1223 	     mgmt_subtype == MGMT_SUBTYPE_PROBE_RESP) &&
1224 	    !(is_from_addr_valid && is_bssid_valid)) {
1225 		mgmt_txrx_debug_rl("from addr "QDF_MAC_ADDR_FMT" bssid addr "QDF_MAC_ADDR_FMT" not valid, modifying them",
1226 				   QDF_MAC_ADDR_REF(wh->i_addr2),
1227 				   QDF_MAC_ADDR_REF(wh->i_addr3));
1228 		if (!is_from_addr_valid)
1229 			qdf_mem_copy(wh->i_addr2, wh->i_addr3,
1230 				     QDF_MAC_ADDR_SIZE);
1231 		else
1232 			qdf_mem_copy(wh->i_addr3, wh->i_addr2,
1233 				     QDF_MAC_ADDR_SIZE);
1234 	}
1235 
1236 	/* mpdu_data_ptr is pointer to action header */
1237 	mpdu_data_ptr = (uint8_t *)qdf_nbuf_data(buf) +
1238 			sizeof(struct ieee80211_frame);
1239 
1240 	if (wh->i_fc[1] & IEEE80211_FC1_ORDER) {
1241 		/* Adjust the offset taking into consideration HT control field
1242 		 * length, in the case when peer sends a frame with HT/VHT/HE
1243 		 * ctrl field in the header(when frame is transmitted in TB
1244 		 * PPDU format).
1245 		 */
1246 		mpdu_data_ptr += IEEE80211_HT_CTRL_LEN;
1247 		len = IEEE80211_HT_CTRL_LEN;
1248 		mgmt_txrx_debug_rl("HT control field present!");
1249 	}
1250 
1251 	if ((wh->i_fc[1] & IEEE80211_FC1_WEP) &&
1252 	    !qdf_is_macaddr_group((struct qdf_mac_addr *)wh->i_addr1) &&
1253 	    !qdf_is_macaddr_broadcast((struct qdf_mac_addr *)wh->i_addr1)) {
1254 
1255 		if (buflen > (sizeof(struct ieee80211_frame) +
1256 			WLAN_HDR_EXT_IV_LEN))
1257 			ivp = data + sizeof(struct ieee80211_frame) + len;
1258 
1259 		/* Set mpdu_data_ptr based on EXT IV bit
1260 		 * if EXT IV bit set, CCMP using PMF 8 bytes of IV is present
1261 		 * else for WEP using PMF, 4 bytes of IV is present
1262 		 */
1263 		if (ivp && (ivp[WLAN_HDR_IV_LEN] & WLAN_HDR_EXT_IV_BIT)) {
1264 			if (buflen <= (sizeof(struct ieee80211_frame)
1265 					+ IEEE80211_CCMP_HEADERLEN)) {
1266 				qdf_nbuf_free(buf);
1267 				return QDF_STATUS_E_FAILURE;
1268 			}
1269 			mpdu_data_ptr += IEEE80211_CCMP_HEADERLEN;
1270 		} else {
1271 			if (buflen <= (sizeof(struct ieee80211_frame)
1272 					+ WLAN_HDR_EXT_IV_LEN)) {
1273 				qdf_nbuf_free(buf);
1274 				return QDF_STATUS_E_FAILURE;
1275 			}
1276 			mpdu_data_ptr += WLAN_HDR_EXT_IV_LEN;
1277 		}
1278 	}
1279 
1280 	if (mgmt_type == IEEE80211_FC0_TYPE_MGT) {
1281 		frm_type = mgmt_txrx_get_frm_type(mgmt_subtype, mpdu_data_ptr);
1282 		if (frm_type == MGMT_FRM_UNSPECIFIED) {
1283 			mgmt_txrx_debug_rl(
1284 			"Unspecified mgmt frame type fc: %x %x", wh->i_fc[0],
1285 								wh->i_fc[1]);
1286 			qdf_nbuf_free(buf);
1287 			return QDF_STATUS_E_FAILURE;
1288 		}
1289 	} else {
1290 		frm_type = MGMT_CTRL_FRAME;
1291 	}
1292 
1293 	if (mgmt_type == IEEE80211_FC0_TYPE_MGT &&
1294 	    !(mgmt_subtype == MGMT_SUBTYPE_BEACON ||
1295 	      mgmt_subtype == MGMT_SUBTYPE_PROBE_RESP ||
1296 	      mgmt_subtype == MGMT_SUBTYPE_PROBE_REQ))
1297 		mgmt_txrx_debug("Rcvd mgmt frame subtype %x (frame type %u) from "QDF_MAC_ADDR_FMT", seq_num = %d, rssi = %d tsf_delta: %u",
1298 				mgmt_subtype, frm_type,
1299 				QDF_MAC_ADDR_REF(wh->i_addr2),
1300 				(le16toh(*(uint16_t *)wh->i_seq) >>
1301 				WLAN_SEQ_SEQ_SHIFT), mgmt_rx_params->rssi,
1302 				mgmt_rx_params->tsf_delta);
1303 
1304 	/* Print a hexdump of packet for host debug */
1305 	if (mgmt_type == IEEE80211_FC0_TYPE_MGT &&
1306 	    ((mgmt_rx_params->status & WMI_HOST_RXERR_PN) ||
1307 	     (mgmt_rx_params->status & WMI_HOST_RXERR_CRC) ||
1308 	     (mgmt_rx_params->status & WMI_HOST_RXERR_DECRYPT) ||
1309 	     (mgmt_rx_params->status & WMI_HOST_RXERR_MIC) ||
1310 	     (mgmt_rx_params->status & WMI_HOST_RXERR_KEY_CACHE_MISS))) {
1311 		uint64_t curr_pn, prev_pn;
1312 		uint8_t *pn = NULL;
1313 
1314 		pn = mgmt_rx_params->pn_params.curr_pn;
1315 		curr_pn = qdf_le64_to_cpu(*((uint64_t *)pn));
1316 
1317 		pn = mgmt_rx_params->pn_params.prev_pn;
1318 		prev_pn = qdf_le64_to_cpu(*((uint64_t *)pn));
1319 
1320 		mgmt_txrx_debug("Current PN=0x%llx Previous PN=0x%llx. Packet dumped below",
1321 				curr_pn, prev_pn);
1322 		qdf_trace_hex_dump(QDF_MODULE_ID_MGMT_TXRX,
1323 				   QDF_TRACE_LEVEL_DEBUG, data, buflen);
1324 	}
1325 
1326 	if (simulation_frame_update(psoc, buf, mgmt_rx_params))
1327 		return QDF_STATUS_E_FAILURE;
1328 
1329 	mgmt_txrx_psoc_ctx = (struct mgmt_txrx_priv_psoc_context *)
1330 			wlan_objmgr_psoc_get_comp_private_obj(psoc,
1331 				WLAN_UMAC_COMP_MGMT_TXRX);
1332 
1333 	qdf_spin_lock_bh(&mgmt_txrx_psoc_ctx->mgmt_txrx_psoc_ctx_lock);
1334 	rx_handler = mgmt_txrx_psoc_ctx->mgmt_rx_comp_cb[frm_type];
1335 	if (rx_handler) {
1336 		status = wlan_mgmt_txrx_rx_handler_list_copy(rx_handler,
1337 				&rx_handler_head, &rx_handler_tail);
1338 		if (status != QDF_STATUS_SUCCESS) {
1339 			qdf_spin_unlock_bh(&mgmt_txrx_psoc_ctx->mgmt_txrx_psoc_ctx_lock);
1340 			qdf_nbuf_free(buf);
1341 			goto rx_handler_mem_free;
1342 		}
1343 	}
1344 
1345 	if (mgmt_type == IEEE80211_FC0_TYPE_MGT) {
1346 		rx_handler =
1347 		mgmt_txrx_psoc_ctx->mgmt_rx_comp_cb[MGMT_FRAME_TYPE_ALL];
1348 		if (rx_handler) {
1349 			status = wlan_mgmt_txrx_rx_handler_list_copy(
1350 				rx_handler, &rx_handler_head, &rx_handler_tail);
1351 			if (status != QDF_STATUS_SUCCESS) {
1352 				qdf_spin_unlock_bh(
1353 				  &mgmt_txrx_psoc_ctx->mgmt_txrx_psoc_ctx_lock);
1354 				qdf_nbuf_free(buf);
1355 				goto rx_handler_mem_free;
1356 			}
1357 		}
1358 	}
1359 
1360 	if (!rx_handler_head) {
1361 		qdf_spin_unlock_bh(&mgmt_txrx_psoc_ctx->mgmt_txrx_psoc_ctx_lock);
1362 		mgmt_txrx_debug("No rx callback registered for frm_type: %d",
1363 				frm_type);
1364 		qdf_nbuf_free(buf);
1365 		return QDF_STATUS_E_FAILURE;
1366 	}
1367 	qdf_spin_unlock_bh(&mgmt_txrx_psoc_ctx->mgmt_txrx_psoc_ctx_lock);
1368 
1369 	if (mgmt_subtype == MGMT_SUBTYPE_BEACON &&
1370 	    mgmt_rx_params->is_conn_ap.is_conn_ap_frm == 0) {
1371 		status = wlan_mgmt_rx_beacon_rate_limit(psoc, mgmt_rx_params);
1372 		if (QDF_IS_STATUS_ERROR(status)) {
1373 			qdf_nbuf_free(buf);
1374 			goto rx_handler_mem_free;
1375 		}
1376 	}
1377 
1378 	mac_addr = (uint8_t *)wh->i_addr2;
1379 	/*
1380 	 * peer can be NULL in following 2 scenarios:
1381 	 * 1. broadcast frame received
1382 	 * 2. operating in monitor mode
1383 	 *
1384 	 * and in both scenarios, the receiver of frame
1385 	 * is expected to do processing accordingly considerng
1386 	 * the fact that peer = NULL can be received and is a valid
1387 	 * scenario.
1388 	 */
1389 	peer = wlan_objmgr_get_peer(psoc, mgmt_rx_params->pdev_id,
1390 				    mac_addr, WLAN_MGMT_SB_ID);
1391 	if (!peer && !qdf_is_macaddr_broadcast(
1392 	    (struct qdf_mac_addr *)wh->i_addr1)) {
1393 		mac_addr = (uint8_t *)wh->i_addr1;
1394 		peer = wlan_objmgr_get_peer(psoc,
1395 					    mgmt_rx_params->pdev_id,
1396 					    mac_addr, WLAN_MGMT_SB_ID);
1397 	}
1398 
1399 	rx_handler = rx_handler_head;
1400 	while (rx_handler->next) {
1401 		copy_buf = qdf_nbuf_clone(buf);
1402 
1403 		if (!copy_buf) {
1404 			rx_handler = rx_handler->next;
1405 			continue;
1406 		}
1407 
1408 		rx_handler->rx_cb(psoc, peer, copy_buf,
1409 					mgmt_rx_params, frm_type);
1410 		rx_handler = rx_handler->next;
1411 	}
1412 	rx_handler->rx_cb(psoc, peer, buf,
1413 				mgmt_rx_params, frm_type);
1414 
1415 	if (peer)
1416 		wlan_objmgr_peer_release_ref(peer, WLAN_MGMT_SB_ID);
1417 
1418 rx_handler_mem_free:
1419 	while (rx_handler_head) {
1420 		rx_handler = rx_handler_head;
1421 		rx_handler_head = rx_handler_head->next;
1422 		qdf_mem_free(rx_handler);
1423 	}
1424 
1425 	return status;
1426 }
1427 
1428 QDF_STATUS tgt_mgmt_txrx_tx_completion_handler(
1429 			struct wlan_objmgr_pdev *pdev,
1430 			uint32_t desc_id, uint32_t status,
1431 			void *tx_compl_params)
1432 {
1433 	struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx;
1434 	struct mgmt_txrx_desc_elem_t *mgmt_desc;
1435 	void *cb_context;
1436 	mgmt_tx_download_comp_cb tx_compl_cb;
1437 	mgmt_ota_comp_cb  ota_comp_cb;
1438 	qdf_nbuf_t nbuf;
1439 
1440 	mgmt_txrx_pdev_ctx = (struct mgmt_txrx_priv_pdev_context *)
1441 			wlan_objmgr_pdev_get_comp_private_obj(pdev,
1442 				WLAN_UMAC_COMP_MGMT_TXRX);
1443 	if (!mgmt_txrx_pdev_ctx) {
1444 		mgmt_txrx_err("Mgmt txrx context empty for pdev %pK", pdev);
1445 		return QDF_STATUS_E_NULL_VALUE;
1446 	}
1447 	if (desc_id >= MGMT_DESC_POOL_MAX) {
1448 		mgmt_txrx_err("desc_id:%u is out of bounds", desc_id);
1449 		return QDF_STATUS_E_INVAL;
1450 	}
1451 	mgmt_desc = &mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool[desc_id];
1452 	if (!mgmt_desc || !mgmt_desc->in_use) {
1453 		mgmt_txrx_err("Mgmt desc empty for id %d pdev %pK ",
1454 				desc_id, pdev);
1455 		return QDF_STATUS_E_NULL_VALUE;
1456 	}
1457 	tx_compl_cb = mgmt_desc->tx_dwnld_cmpl_cb;
1458 	ota_comp_cb = mgmt_desc->tx_ota_cmpl_cb;
1459 	nbuf = mgmt_desc->nbuf;
1460 
1461 	/*
1462 	 *      TO DO
1463 	 * Make the API more generic to handle tx download completion as well
1464 	 * as OTA completion separately.
1465 	 */
1466 
1467 	/*
1468 	 * 1. If the tx frame is sent by any UMAC converged component then it
1469 	 *    passes the context as NULL while calling mgmt txrx API for
1470 	 *    sending mgmt frame. If context is NULL, peer will be passed as
1471 	 *    cb_context in completion callbacks.
1472 	 * 2. If the tx frame is sent by legacy MLME then it passes the context
1473 	 *    as its specific context (for ex- mac context in case of MCL) while
1474 	 *    calling mgmt txrx API for sending mgmt frame. This caller specific
1475 	 *    context is passed as cb_context in completion callbacks.
1476 	 */
1477 	if (mgmt_desc->context)
1478 		cb_context = mgmt_desc->context;
1479 	else
1480 		cb_context = (void *)mgmt_desc->peer;
1481 
1482 	if (!tx_compl_cb && !ota_comp_cb) {
1483 		qdf_nbuf_free(nbuf);
1484 		goto no_registered_cb;
1485 	}
1486 
1487 	if (tx_compl_cb)
1488 		tx_compl_cb(cb_context, nbuf, status);
1489 
1490 	if (ota_comp_cb)
1491 		ota_comp_cb(cb_context, nbuf, status, tx_compl_params);
1492 
1493 no_registered_cb:
1494 	/*
1495 	 * decrementing the peer ref count that was incremented while
1496 	 * accessing peer in wlan_mgmt_txrx_mgmt_frame_tx
1497 	 */
1498 	wlan_objmgr_peer_release_ref(mgmt_desc->peer, WLAN_MGMT_NB_ID);
1499 	wlan_mgmt_txrx_desc_put(mgmt_txrx_pdev_ctx, desc_id);
1500 	return QDF_STATUS_SUCCESS;
1501 }
1502 
1503 qdf_nbuf_t tgt_mgmt_txrx_get_nbuf_from_desc_id(
1504 			struct wlan_objmgr_pdev *pdev,
1505 			uint32_t desc_id)
1506 {
1507 	struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx;
1508 	struct mgmt_txrx_desc_elem_t *mgmt_desc;
1509 	qdf_nbuf_t buf;
1510 
1511 	mgmt_txrx_pdev_ctx = (struct mgmt_txrx_priv_pdev_context *)
1512 			wlan_objmgr_pdev_get_comp_private_obj(pdev,
1513 				WLAN_UMAC_COMP_MGMT_TXRX);
1514 	if (!mgmt_txrx_pdev_ctx) {
1515 		mgmt_txrx_err("Mgmt txrx context empty for pdev %pK", pdev);
1516 		goto fail;
1517 	}
1518 	if (desc_id >= MGMT_DESC_POOL_MAX) {
1519 		mgmt_txrx_err("desc_id:%u is out of bounds", desc_id);
1520 		goto fail;
1521 	}
1522 
1523 	mgmt_desc = &mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool[desc_id];
1524 	if (!mgmt_desc || !mgmt_desc->in_use) {
1525 		mgmt_txrx_err("Mgmt descriptor unavailable for id %d pdev %pK",
1526 				desc_id, pdev);
1527 		goto fail;
1528 	}
1529 	buf = mgmt_desc->nbuf;
1530 	return buf;
1531 
1532 fail:
1533 	return NULL;
1534 }
1535 
1536 struct wlan_objmgr_peer *
1537 tgt_mgmt_txrx_get_peer_from_desc_id(
1538 			struct wlan_objmgr_pdev *pdev,
1539 			uint32_t desc_id)
1540 {
1541 	struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx;
1542 	struct mgmt_txrx_desc_elem_t *mgmt_desc;
1543 	struct wlan_objmgr_peer *peer;
1544 
1545 	mgmt_txrx_pdev_ctx = (struct mgmt_txrx_priv_pdev_context *)
1546 			wlan_objmgr_pdev_get_comp_private_obj(pdev,
1547 				WLAN_UMAC_COMP_MGMT_TXRX);
1548 	if (!mgmt_txrx_pdev_ctx) {
1549 		mgmt_txrx_err("Mgmt txrx context empty for pdev %pK", pdev);
1550 		goto fail;
1551 	}
1552 
1553 	mgmt_desc = &mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool[desc_id];
1554 	if (!mgmt_desc || !mgmt_desc->in_use) {
1555 		mgmt_txrx_err("Mgmt descriptor unavailable for id %d pdev %pK",
1556 				desc_id, pdev);
1557 		goto fail;
1558 	}
1559 
1560 	peer = mgmt_desc->peer;
1561 	return peer;
1562 
1563 fail:
1564 	return NULL;
1565 }
1566 
1567 uint8_t tgt_mgmt_txrx_get_vdev_id_from_desc_id(
1568 			struct wlan_objmgr_pdev *pdev,
1569 			uint32_t desc_id)
1570 {
1571 	struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx;
1572 	struct mgmt_txrx_desc_elem_t *mgmt_desc;
1573 	uint8_t vdev_id;
1574 
1575 	mgmt_txrx_pdev_ctx = (struct mgmt_txrx_priv_pdev_context *)
1576 			wlan_objmgr_pdev_get_comp_private_obj(pdev,
1577 				WLAN_UMAC_COMP_MGMT_TXRX);
1578 	if (!mgmt_txrx_pdev_ctx) {
1579 		mgmt_txrx_err("Mgmt txrx context empty for pdev %pK", pdev);
1580 		goto fail;
1581 	}
1582 	if (desc_id >= MGMT_DESC_POOL_MAX) {
1583 		mgmt_txrx_err("desc_id:%u is out of bounds", desc_id);
1584 		goto fail;
1585 	}
1586 
1587 	mgmt_desc = &mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool[desc_id];
1588 	if (!mgmt_desc || !mgmt_desc->in_use) {
1589 		mgmt_txrx_err("Mgmt descriptor unavailable for id %d pdev %pK",
1590 				desc_id, pdev);
1591 		goto fail;
1592 	}
1593 
1594 	vdev_id = mgmt_desc->vdev_id;
1595 	return vdev_id;
1596 
1597 fail:
1598 	return WLAN_UMAC_VDEV_ID_MAX;
1599 }
1600 
1601 uint32_t tgt_mgmt_txrx_get_free_desc_pool_count(
1602 			struct wlan_objmgr_pdev *pdev)
1603 {
1604 	struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx;
1605 	uint32_t free_desc_count = WLAN_INVALID_MGMT_DESC_COUNT;
1606 
1607 	mgmt_txrx_pdev_ctx = (struct mgmt_txrx_priv_pdev_context *)
1608 			wlan_objmgr_pdev_get_comp_private_obj(pdev,
1609 			WLAN_UMAC_COMP_MGMT_TXRX);
1610 	if (!mgmt_txrx_pdev_ctx) {
1611 		mgmt_txrx_err("Mgmt txrx context empty for pdev %pK", pdev);
1612 		goto fail;
1613 	}
1614 
1615 	free_desc_count = qdf_list_size(
1616 		&(mgmt_txrx_pdev_ctx->mgmt_desc_pool.free_list));
1617 
1618 fail:
1619 	return free_desc_count;
1620 }
1621 
1622 QDF_STATUS
1623 tgt_mgmt_txrx_register_ev_handler(struct wlan_objmgr_psoc *psoc)
1624 {
1625 	struct wlan_lmac_if_mgmt_txrx_tx_ops *mgmt_txrx_tx_ops;
1626 
1627 	mgmt_txrx_tx_ops = wlan_psoc_get_mgmt_txrx_txops(psoc);
1628 	if (!mgmt_txrx_tx_ops) {
1629 		mgmt_txrx_err("txops is null for mgmt txrx module");
1630 		return QDF_STATUS_E_NULL_VALUE;
1631 	}
1632 
1633 	if (mgmt_txrx_tx_ops->reg_ev_handler)
1634 		return mgmt_txrx_tx_ops->reg_ev_handler(psoc);
1635 
1636 	return QDF_STATUS_SUCCESS;
1637 }
1638 
1639 QDF_STATUS
1640 tgt_mgmt_txrx_unregister_ev_handler(struct wlan_objmgr_psoc *psoc)
1641 {
1642 	struct wlan_lmac_if_mgmt_txrx_tx_ops *mgmt_txrx_tx_ops;
1643 
1644 	mgmt_txrx_tx_ops = wlan_psoc_get_mgmt_txrx_txops(psoc);
1645 	if (!mgmt_txrx_tx_ops) {
1646 		mgmt_txrx_err("txops is null for mgmt txrx module");
1647 		return QDF_STATUS_E_NULL_VALUE;
1648 	}
1649 
1650 	if (mgmt_txrx_tx_ops->unreg_ev_handler)
1651 		return mgmt_txrx_tx_ops->unreg_ev_handler(psoc);
1652 
1653 	return QDF_STATUS_SUCCESS;
1654 }
1655 
1656 QDF_STATUS tgt_mgmt_txrx_process_rx_frame(
1657 			struct wlan_objmgr_pdev *pdev,
1658 			qdf_nbuf_t buf,
1659 			struct mgmt_rx_event_params *mgmt_rx_params)
1660 {
1661 	QDF_STATUS status;
1662 	struct wlan_lmac_if_mgmt_txrx_tx_ops *mgmt_txrx_tx_ops;
1663 
1664 	mgmt_txrx_tx_ops = wlan_pdev_get_mgmt_txrx_txops(pdev);
1665 	if (!mgmt_txrx_tx_ops) {
1666 		mgmt_txrx_err("txops is null for mgmt txrx module");
1667 		qdf_nbuf_free(buf);
1668 		free_mgmt_rx_event_params(mgmt_rx_params);
1669 		return QDF_STATUS_E_NULL_VALUE;
1670 	}
1671 
1672 	/* Call the legacy handler to actually process and deliver frames */
1673 	status = mgmt_txrx_tx_ops->rx_frame_legacy_handler(pdev, buf,
1674 							   mgmt_rx_params);
1675 	/**
1676 	 * Free up the mgmt rx params.
1677 	 * nbuf shouldn't be freed here as it is taken care by
1678 	 * rx_frame_legacy_handler.
1679 	 */
1680 	free_mgmt_rx_event_params(mgmt_rx_params);
1681 
1682 	return status;
1683 }
1684 
1685 QDF_STATUS tgt_mgmt_txrx_rx_frame_entry(
1686 			struct wlan_objmgr_pdev *pdev,
1687 			qdf_nbuf_t buf,
1688 			struct mgmt_rx_event_params *mgmt_rx_params)
1689 {
1690 	/* Call the MGMT Rx REO handler */
1691 	return tgt_mgmt_rx_reo_frame_handler(pdev, buf, mgmt_rx_params);
1692 }
1693