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