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