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