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