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