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