1 /* 2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 #ifndef _DP_PEER_H_ 20 #define _DP_PEER_H_ 21 22 #include <qdf_types.h> 23 #include <qdf_lock.h> 24 #include "dp_types.h" 25 #include "dp_internal.h" 26 27 #ifdef DUMP_REO_QUEUE_INFO_IN_DDR 28 #include "hal_reo.h" 29 #endif 30 31 #define DP_INVALID_PEER_ID 0xffff 32 33 #define DP_PEER_MAX_MEC_IDX 1024 /* maximum index for MEC table */ 34 #define DP_PEER_MAX_MEC_ENTRY 4096 /* maximum MEC entries in MEC table */ 35 36 #define DP_FW_PEER_STATS_CMP_TIMEOUT_MSEC 5000 37 38 #define DP_PEER_HASH_LOAD_MULT 2 39 #define DP_PEER_HASH_LOAD_SHIFT 0 40 41 /* Threshold for peer's cached buf queue beyond which frames are dropped */ 42 #define DP_RX_CACHED_BUFQ_THRESH 64 43 44 #define dp_peer_alert(params...) QDF_TRACE_FATAL(QDF_MODULE_ID_DP_PEER, params) 45 #define dp_peer_err(params...) QDF_TRACE_ERROR(QDF_MODULE_ID_DP_PEER, params) 46 #define dp_peer_warn(params...) QDF_TRACE_WARN(QDF_MODULE_ID_DP_PEER, params) 47 #define dp_peer_info(params...) \ 48 __QDF_TRACE_FL(QDF_TRACE_LEVEL_INFO_HIGH, QDF_MODULE_ID_DP_PEER, ## params) 49 #define dp_peer_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_DP_PEER, params) 50 51 #if defined(WLAN_FEATURE_11BE_MLO) && defined(DP_MLO_LINK_STATS_SUPPORT) 52 /** 53 * enum dp_bands - WiFi Band 54 * 55 * @DP_BAND_INVALID: Invalid band 56 * @DP_BAND_2GHZ: 2GHz link 57 * @DP_BAND_5GHZ: 5GHz link 58 * @DP_BAND_6GHZ: 6GHz link 59 * @DP_BAND_UNKNOWN: Unknown band 60 */ 61 enum dp_bands { 62 DP_BAND_INVALID = 0, 63 DP_BAND_2GHZ = 1, 64 DP_BAND_5GHZ = 2, 65 DP_BAND_6GHZ = 3, 66 DP_BAND_UNKNOWN = 4, 67 }; 68 69 /** 70 * dp_freq_to_band() - Convert frequency to band 71 * @freq: peer frequency 72 * 73 * Return: band for input frequency 74 */ 75 enum dp_bands dp_freq_to_band(qdf_freq_t freq); 76 #endif 77 78 void check_free_list_for_invalid_flush(struct dp_soc *soc); 79 80 static inline 81 void add_entry_alloc_list(struct dp_soc *soc, struct dp_rx_tid *rx_tid, 82 struct dp_peer *peer, void *hw_qdesc_vaddr) 83 { 84 uint32_t max_list_size; 85 unsigned long curr_ts = qdf_get_system_timestamp(); 86 uint32_t qref_index = soc->free_addr_list_idx; 87 88 max_list_size = soc->wlan_cfg_ctx->qref_control_size; 89 90 if (max_list_size == 0) 91 return; 92 93 soc->list_qdesc_addr_alloc[qref_index].hw_qdesc_paddr = 94 rx_tid->hw_qdesc_paddr; 95 soc->list_qdesc_addr_alloc[qref_index].ts_qdesc_mem_hdl = curr_ts; 96 soc->list_qdesc_addr_alloc[qref_index].hw_qdesc_vaddr_align = 97 hw_qdesc_vaddr; 98 soc->list_qdesc_addr_alloc[qref_index].hw_qdesc_vaddr_unalign = 99 rx_tid->hw_qdesc_vaddr_unaligned; 100 soc->list_qdesc_addr_alloc[qref_index].peer_id = peer->peer_id; 101 soc->list_qdesc_addr_alloc[qref_index].tid = rx_tid->tid; 102 soc->alloc_addr_list_idx++; 103 104 if (soc->alloc_addr_list_idx == max_list_size) 105 soc->alloc_addr_list_idx = 0; 106 } 107 108 static inline 109 void add_entry_free_list(struct dp_soc *soc, struct dp_rx_tid *rx_tid) 110 { 111 uint32_t max_list_size; 112 unsigned long curr_ts = qdf_get_system_timestamp(); 113 uint32_t qref_index = soc->free_addr_list_idx; 114 115 max_list_size = soc->wlan_cfg_ctx->qref_control_size; 116 117 if (max_list_size == 0) 118 return; 119 120 soc->list_qdesc_addr_free[qref_index].ts_qdesc_mem_hdl = curr_ts; 121 soc->list_qdesc_addr_free[qref_index].hw_qdesc_paddr = 122 rx_tid->hw_qdesc_paddr; 123 soc->list_qdesc_addr_free[qref_index].hw_qdesc_vaddr_align = 124 rx_tid->hw_qdesc_vaddr_aligned; 125 soc->list_qdesc_addr_free[qref_index].hw_qdesc_vaddr_unalign = 126 rx_tid->hw_qdesc_vaddr_unaligned; 127 soc->free_addr_list_idx++; 128 129 if (soc->free_addr_list_idx == max_list_size) 130 soc->free_addr_list_idx = 0; 131 } 132 133 static inline 134 void add_entry_write_list(struct dp_soc *soc, struct dp_peer *peer, 135 uint32_t tid) 136 { 137 uint32_t max_list_size; 138 unsigned long curr_ts = qdf_get_system_timestamp(); 139 140 max_list_size = soc->wlan_cfg_ctx->qref_control_size; 141 142 if (max_list_size == 0) 143 return; 144 145 soc->reo_write_list[soc->write_paddr_list_idx].ts_qaddr_del = curr_ts; 146 soc->reo_write_list[soc->write_paddr_list_idx].peer_id = peer->peer_id; 147 soc->reo_write_list[soc->write_paddr_list_idx].paddr = 148 peer->rx_tid[tid].hw_qdesc_paddr; 149 soc->reo_write_list[soc->write_paddr_list_idx].tid = tid; 150 soc->write_paddr_list_idx++; 151 152 if (soc->write_paddr_list_idx == max_list_size) 153 soc->write_paddr_list_idx = 0; 154 } 155 156 #ifdef REO_QDESC_HISTORY 157 enum reo_qdesc_event_type { 158 REO_QDESC_UPDATE_CB = 0, 159 REO_QDESC_FREE, 160 }; 161 162 struct reo_qdesc_event { 163 qdf_dma_addr_t qdesc_addr; 164 uint64_t ts; 165 enum reo_qdesc_event_type type; 166 uint8_t peer_mac[QDF_MAC_ADDR_SIZE]; 167 }; 168 #endif 169 170 struct ast_del_ctxt { 171 bool age; 172 int del_count; 173 }; 174 175 #ifdef QCA_SUPPORT_WDS_EXTENDED 176 /** 177 * dp_peer_is_wds_ext_peer() - peer is WDS_EXT peer 178 * 179 * @peer: DP peer context 180 * 181 * This API checks whether the peer is WDS_EXT peer or not 182 * 183 * Return: true in the wds_ext peer else flase 184 */ 185 static inline bool dp_peer_is_wds_ext_peer(struct dp_txrx_peer *peer) 186 { 187 return qdf_atomic_test_bit(WDS_EXT_PEER_INIT_BIT, &peer->wds_ext.init); 188 } 189 #else 190 static inline bool dp_peer_is_wds_ext_peer(struct dp_txrx_peer *peer) 191 { 192 return false; 193 } 194 #endif 195 196 typedef void dp_peer_iter_func(struct dp_soc *soc, struct dp_peer *peer, 197 void *arg); 198 /** 199 * dp_peer_unref_delete() - unref and delete peer 200 * @peer: Datapath peer handle 201 * @id: ID of module releasing reference 202 * 203 */ 204 void dp_peer_unref_delete(struct dp_peer *peer, enum dp_mod_id id); 205 206 /** 207 * dp_txrx_peer_unref_delete() - unref and delete peer 208 * @handle: Datapath txrx ref handle 209 * @id: Module ID of the caller 210 * 211 */ 212 void dp_txrx_peer_unref_delete(dp_txrx_ref_handle handle, enum dp_mod_id id); 213 214 /** 215 * dp_peer_find_hash_find() - returns legacy or mlo link peer from 216 * peer_hash_table matching vdev_id and mac_address 217 * @soc: soc handle 218 * @peer_mac_addr: peer mac address 219 * @mac_addr_is_aligned: is mac addr aligned 220 * @vdev_id: vdev_id 221 * @mod_id: id of module requesting reference 222 * 223 * return: peer in success 224 * NULL in failure 225 */ 226 struct dp_peer *dp_peer_find_hash_find(struct dp_soc *soc, 227 uint8_t *peer_mac_addr, 228 int mac_addr_is_aligned, 229 uint8_t vdev_id, 230 enum dp_mod_id mod_id); 231 232 /** 233 * dp_peer_find_by_id_valid - check if peer exists for given id 234 * @soc: core DP soc context 235 * @peer_id: peer id from peer object can be retrieved 236 * 237 * Return: true if peer exists of false otherwise 238 */ 239 bool dp_peer_find_by_id_valid(struct dp_soc *soc, uint16_t peer_id); 240 241 /** 242 * dp_peer_get_ref() - Returns peer object given the peer id 243 * 244 * @soc: core DP soc context 245 * @peer: DP peer 246 * @mod_id: id of module requesting the reference 247 * 248 * Return: QDF_STATUS_SUCCESS if reference held successfully 249 * else QDF_STATUS_E_INVAL 250 */ 251 static inline 252 QDF_STATUS dp_peer_get_ref(struct dp_soc *soc, 253 struct dp_peer *peer, 254 enum dp_mod_id mod_id) 255 { 256 if (!qdf_atomic_inc_not_zero(&peer->ref_cnt)) 257 return QDF_STATUS_E_INVAL; 258 259 if (mod_id > DP_MOD_ID_RX) 260 qdf_atomic_inc(&peer->mod_refs[mod_id]); 261 262 return QDF_STATUS_SUCCESS; 263 } 264 265 /** 266 * __dp_peer_get_ref_by_id() - Returns peer object given the peer id 267 * 268 * @soc: core DP soc context 269 * @peer_id: peer id from peer object can be retrieved 270 * @mod_id: module id 271 * 272 * Return: struct dp_peer*: Pointer to DP peer object 273 */ 274 static inline struct dp_peer * 275 __dp_peer_get_ref_by_id(struct dp_soc *soc, 276 uint16_t peer_id, 277 enum dp_mod_id mod_id) 278 279 { 280 struct dp_peer *peer; 281 282 qdf_spin_lock_bh(&soc->peer_map_lock); 283 peer = (peer_id >= soc->max_peer_id) ? NULL : 284 soc->peer_id_to_obj_map[peer_id]; 285 if (!peer || 286 (dp_peer_get_ref(soc, peer, mod_id) != QDF_STATUS_SUCCESS)) { 287 qdf_spin_unlock_bh(&soc->peer_map_lock); 288 return NULL; 289 } 290 291 qdf_spin_unlock_bh(&soc->peer_map_lock); 292 return peer; 293 } 294 295 /** 296 * dp_peer_get_ref_by_id() - Returns peer object given the peer id 297 * if peer state is active 298 * 299 * @soc: core DP soc context 300 * @peer_id: peer id from peer object can be retrieved 301 * @mod_id: ID of module requesting reference 302 * 303 * Return: struct dp_peer*: Pointer to DP peer object 304 */ 305 static inline 306 struct dp_peer *dp_peer_get_ref_by_id(struct dp_soc *soc, 307 uint16_t peer_id, 308 enum dp_mod_id mod_id) 309 { 310 struct dp_peer *peer; 311 312 qdf_spin_lock_bh(&soc->peer_map_lock); 313 peer = (peer_id >= soc->max_peer_id) ? NULL : 314 soc->peer_id_to_obj_map[peer_id]; 315 316 if (!peer || peer->peer_state >= DP_PEER_STATE_LOGICAL_DELETE || 317 (dp_peer_get_ref(soc, peer, mod_id) != QDF_STATUS_SUCCESS)) { 318 qdf_spin_unlock_bh(&soc->peer_map_lock); 319 return NULL; 320 } 321 322 qdf_spin_unlock_bh(&soc->peer_map_lock); 323 324 return peer; 325 } 326 327 /** 328 * dp_txrx_peer_get_ref_by_id() - Returns txrx peer object given the peer id 329 * 330 * @soc: core DP soc context 331 * @peer_id: peer id from peer object can be retrieved 332 * @handle: reference handle 333 * @mod_id: ID of module requesting reference 334 * 335 * Return: struct dp_txrx_peer*: Pointer to txrx DP peer object 336 */ 337 static inline struct dp_txrx_peer * 338 dp_txrx_peer_get_ref_by_id(struct dp_soc *soc, 339 uint16_t peer_id, 340 dp_txrx_ref_handle *handle, 341 enum dp_mod_id mod_id) 342 343 { 344 struct dp_peer *peer; 345 346 peer = dp_peer_get_ref_by_id(soc, peer_id, mod_id); 347 if (!peer) 348 return NULL; 349 350 if (!peer->txrx_peer) { 351 dp_peer_unref_delete(peer, mod_id); 352 return NULL; 353 } 354 355 *handle = (dp_txrx_ref_handle)peer; 356 return peer->txrx_peer; 357 } 358 359 #ifdef PEER_CACHE_RX_PKTS 360 /** 361 * dp_rx_flush_rx_cached() - flush cached rx frames 362 * @peer: peer 363 * @drop: set flag to drop frames 364 * 365 * Return: None 366 */ 367 void dp_rx_flush_rx_cached(struct dp_peer *peer, bool drop); 368 #else 369 static inline void dp_rx_flush_rx_cached(struct dp_peer *peer, bool drop) 370 { 371 } 372 #endif 373 374 static inline void 375 dp_clear_peer_internal(struct dp_soc *soc, struct dp_peer *peer) 376 { 377 qdf_spin_lock_bh(&peer->peer_info_lock); 378 peer->state = OL_TXRX_PEER_STATE_DISC; 379 qdf_spin_unlock_bh(&peer->peer_info_lock); 380 381 dp_rx_flush_rx_cached(peer, true); 382 } 383 384 /** 385 * dp_vdev_iterate_peer() - API to iterate through vdev peer list 386 * 387 * @vdev: DP vdev context 388 * @func: function to be called for each peer 389 * @arg: argument need to be passed to func 390 * @mod_id: module_id 391 * 392 * Return: void 393 */ 394 static inline void 395 dp_vdev_iterate_peer(struct dp_vdev *vdev, dp_peer_iter_func *func, void *arg, 396 enum dp_mod_id mod_id) 397 { 398 struct dp_peer *peer; 399 struct dp_peer *tmp_peer; 400 struct dp_soc *soc = NULL; 401 402 if (!vdev || !vdev->pdev || !vdev->pdev->soc) 403 return; 404 405 soc = vdev->pdev->soc; 406 407 qdf_spin_lock_bh(&vdev->peer_list_lock); 408 TAILQ_FOREACH_SAFE(peer, &vdev->peer_list, 409 peer_list_elem, 410 tmp_peer) { 411 if (dp_peer_get_ref(soc, peer, mod_id) == 412 QDF_STATUS_SUCCESS) { 413 (*func)(soc, peer, arg); 414 dp_peer_unref_delete(peer, mod_id); 415 } 416 } 417 qdf_spin_unlock_bh(&vdev->peer_list_lock); 418 } 419 420 /** 421 * dp_pdev_iterate_peer() - API to iterate through all peers of pdev 422 * 423 * @pdev: DP pdev context 424 * @func: function to be called for each peer 425 * @arg: argument need to be passed to func 426 * @mod_id: module_id 427 * 428 * Return: void 429 */ 430 static inline void 431 dp_pdev_iterate_peer(struct dp_pdev *pdev, dp_peer_iter_func *func, void *arg, 432 enum dp_mod_id mod_id) 433 { 434 struct dp_vdev *vdev; 435 436 if (!pdev) 437 return; 438 439 qdf_spin_lock_bh(&pdev->vdev_list_lock); 440 DP_PDEV_ITERATE_VDEV_LIST(pdev, vdev) 441 dp_vdev_iterate_peer(vdev, func, arg, mod_id); 442 qdf_spin_unlock_bh(&pdev->vdev_list_lock); 443 } 444 445 /** 446 * dp_soc_iterate_peer() - API to iterate through all peers of soc 447 * 448 * @soc: DP soc context 449 * @func: function to be called for each peer 450 * @arg: argument need to be passed to func 451 * @mod_id: module_id 452 * 453 * Return: void 454 */ 455 static inline void 456 dp_soc_iterate_peer(struct dp_soc *soc, dp_peer_iter_func *func, void *arg, 457 enum dp_mod_id mod_id) 458 { 459 struct dp_pdev *pdev; 460 int i; 461 462 if (!soc) 463 return; 464 465 for (i = 0; i < MAX_PDEV_CNT && soc->pdev_list[i]; i++) { 466 pdev = soc->pdev_list[i]; 467 dp_pdev_iterate_peer(pdev, func, arg, mod_id); 468 } 469 } 470 471 /** 472 * dp_vdev_iterate_peer_lock_safe() - API to iterate through vdev list 473 * 474 * This API will cache the peers in local allocated memory and calls 475 * iterate function outside the lock. 476 * 477 * As this API is allocating new memory it is suggested to use this 478 * only when lock cannot be held 479 * 480 * @vdev: DP vdev context 481 * @func: function to be called for each peer 482 * @arg: argument need to be passed to func 483 * @mod_id: module_id 484 * 485 * Return: void 486 */ 487 static inline void 488 dp_vdev_iterate_peer_lock_safe(struct dp_vdev *vdev, 489 dp_peer_iter_func *func, 490 void *arg, 491 enum dp_mod_id mod_id) 492 { 493 struct dp_peer *peer; 494 struct dp_peer *tmp_peer; 495 struct dp_soc *soc = NULL; 496 struct dp_peer **peer_array = NULL; 497 int i = 0; 498 uint32_t num_peers = 0; 499 500 if (!vdev || !vdev->pdev || !vdev->pdev->soc) 501 return; 502 503 num_peers = vdev->num_peers; 504 505 soc = vdev->pdev->soc; 506 507 peer_array = qdf_mem_malloc(num_peers * sizeof(struct dp_peer *)); 508 if (!peer_array) 509 return; 510 511 qdf_spin_lock_bh(&vdev->peer_list_lock); 512 TAILQ_FOREACH_SAFE(peer, &vdev->peer_list, 513 peer_list_elem, 514 tmp_peer) { 515 if (i >= num_peers) 516 break; 517 518 if (dp_peer_get_ref(soc, peer, mod_id) == QDF_STATUS_SUCCESS) { 519 peer_array[i] = peer; 520 i = (i + 1); 521 } 522 } 523 qdf_spin_unlock_bh(&vdev->peer_list_lock); 524 525 for (i = 0; i < num_peers; i++) { 526 peer = peer_array[i]; 527 528 if (!peer) 529 continue; 530 531 (*func)(soc, peer, arg); 532 dp_peer_unref_delete(peer, mod_id); 533 } 534 535 qdf_mem_free(peer_array); 536 } 537 538 /** 539 * dp_pdev_iterate_peer_lock_safe() - API to iterate through all peers of pdev 540 * 541 * This API will cache the peers in local allocated memory and calls 542 * iterate function outside the lock. 543 * 544 * As this API is allocating new memory it is suggested to use this 545 * only when lock cannot be held 546 * 547 * @pdev: DP pdev context 548 * @func: function to be called for each peer 549 * @arg: argument need to be passed to func 550 * @mod_id: module_id 551 * 552 * Return: void 553 */ 554 static inline void 555 dp_pdev_iterate_peer_lock_safe(struct dp_pdev *pdev, 556 dp_peer_iter_func *func, 557 void *arg, 558 enum dp_mod_id mod_id) 559 { 560 struct dp_peer *peer; 561 struct dp_peer *tmp_peer; 562 struct dp_soc *soc = NULL; 563 struct dp_vdev *vdev = NULL; 564 struct dp_peer **peer_array[DP_PDEV_MAX_VDEVS] = {0}; 565 int i = 0; 566 int j = 0; 567 uint32_t num_peers[DP_PDEV_MAX_VDEVS] = {0}; 568 569 if (!pdev || !pdev->soc) 570 return; 571 572 soc = pdev->soc; 573 574 qdf_spin_lock_bh(&pdev->vdev_list_lock); 575 DP_PDEV_ITERATE_VDEV_LIST(pdev, vdev) { 576 num_peers[i] = vdev->num_peers; 577 peer_array[i] = qdf_mem_malloc(num_peers[i] * 578 sizeof(struct dp_peer *)); 579 if (!peer_array[i]) 580 break; 581 582 qdf_spin_lock_bh(&vdev->peer_list_lock); 583 TAILQ_FOREACH_SAFE(peer, &vdev->peer_list, 584 peer_list_elem, 585 tmp_peer) { 586 if (j >= num_peers[i]) 587 break; 588 589 if (dp_peer_get_ref(soc, peer, mod_id) == 590 QDF_STATUS_SUCCESS) { 591 peer_array[i][j] = peer; 592 593 j = (j + 1); 594 } 595 } 596 qdf_spin_unlock_bh(&vdev->peer_list_lock); 597 i = (i + 1); 598 } 599 qdf_spin_unlock_bh(&pdev->vdev_list_lock); 600 601 for (i = 0; i < DP_PDEV_MAX_VDEVS; i++) { 602 if (!peer_array[i]) 603 break; 604 605 for (j = 0; j < num_peers[i]; j++) { 606 peer = peer_array[i][j]; 607 608 if (!peer) 609 continue; 610 611 (*func)(soc, peer, arg); 612 dp_peer_unref_delete(peer, mod_id); 613 } 614 615 qdf_mem_free(peer_array[i]); 616 } 617 } 618 619 /** 620 * dp_soc_iterate_peer_lock_safe() - API to iterate through all peers of soc 621 * 622 * This API will cache the peers in local allocated memory and calls 623 * iterate function outside the lock. 624 * 625 * As this API is allocating new memory it is suggested to use this 626 * only when lock cannot be held 627 * 628 * @soc: DP soc context 629 * @func: function to be called for each peer 630 * @arg: argument need to be passed to func 631 * @mod_id: module_id 632 * 633 * Return: void 634 */ 635 static inline void 636 dp_soc_iterate_peer_lock_safe(struct dp_soc *soc, 637 dp_peer_iter_func *func, 638 void *arg, 639 enum dp_mod_id mod_id) 640 { 641 struct dp_pdev *pdev; 642 int i; 643 644 if (!soc) 645 return; 646 647 for (i = 0; i < MAX_PDEV_CNT && soc->pdev_list[i]; i++) { 648 pdev = soc->pdev_list[i]; 649 dp_pdev_iterate_peer_lock_safe(pdev, func, arg, mod_id); 650 } 651 } 652 653 #ifdef DP_PEER_STATE_DEBUG 654 #define DP_PEER_STATE_ASSERT(_peer, _new_state, _condition) \ 655 do { \ 656 if (!(_condition)) { \ 657 dp_alert("Invalid state shift from %u to %u peer " \ 658 QDF_MAC_ADDR_FMT, \ 659 (_peer)->peer_state, (_new_state), \ 660 QDF_MAC_ADDR_REF((_peer)->mac_addr.raw)); \ 661 QDF_ASSERT(0); \ 662 } \ 663 } while (0) 664 665 #else 666 #define DP_PEER_STATE_ASSERT(_peer, _new_state, _condition) \ 667 do { \ 668 if (!(_condition)) { \ 669 dp_alert("Invalid state shift from %u to %u peer " \ 670 QDF_MAC_ADDR_FMT, \ 671 (_peer)->peer_state, (_new_state), \ 672 QDF_MAC_ADDR_REF((_peer)->mac_addr.raw)); \ 673 } \ 674 } while (0) 675 #endif 676 677 /** 678 * dp_peer_state_cmp() - compare dp peer state 679 * 680 * @peer: DP peer 681 * @state: state 682 * 683 * Return: true if state matches with peer state 684 * false if it does not match 685 */ 686 static inline bool 687 dp_peer_state_cmp(struct dp_peer *peer, 688 enum dp_peer_state state) 689 { 690 bool is_status_equal = false; 691 692 qdf_spin_lock_bh(&peer->peer_state_lock); 693 is_status_equal = (peer->peer_state == state); 694 qdf_spin_unlock_bh(&peer->peer_state_lock); 695 696 return is_status_equal; 697 } 698 699 /** 700 * dp_print_ast_stats() - Dump AST table contents 701 * @soc: Datapath soc handle 702 * 703 * Return: void 704 */ 705 void dp_print_ast_stats(struct dp_soc *soc); 706 707 /** 708 * dp_rx_peer_map_handler() - handle peer map event from firmware 709 * @soc: generic soc handle 710 * @peer_id: peer_id from firmware 711 * @hw_peer_id: ast index for this peer 712 * @vdev_id: vdev ID 713 * @peer_mac_addr: mac address of the peer 714 * @ast_hash: ast hash value 715 * @is_wds: flag to indicate peer map event for WDS ast entry 716 * 717 * associate the peer_id that firmware provided with peer entry 718 * and update the ast table in the host with the hw_peer_id. 719 * 720 * Return: QDF_STATUS code 721 */ 722 723 QDF_STATUS dp_rx_peer_map_handler(struct dp_soc *soc, uint16_t peer_id, 724 uint16_t hw_peer_id, uint8_t vdev_id, 725 uint8_t *peer_mac_addr, uint16_t ast_hash, 726 uint8_t is_wds); 727 728 /** 729 * dp_rx_peer_unmap_handler() - handle peer unmap event from firmware 730 * @soc: generic soc handle 731 * @peer_id: peer_id from firmware 732 * @vdev_id: vdev ID 733 * @peer_mac_addr: mac address of the peer or wds entry 734 * @is_wds: flag to indicate peer map event for WDS ast entry 735 * @free_wds_count: number of wds entries freed by FW with peer delete 736 * 737 * Return: none 738 */ 739 void dp_rx_peer_unmap_handler(struct dp_soc *soc, uint16_t peer_id, 740 uint8_t vdev_id, uint8_t *peer_mac_addr, 741 uint8_t is_wds, uint32_t free_wds_count); 742 743 #if defined(WLAN_FEATURE_11BE_MLO) && defined(DP_MLO_LINK_STATS_SUPPORT) 744 /** 745 * dp_rx_peer_ext_evt() - handle peer extended event from firmware 746 * @soc: DP soc handle 747 * @info: extended evt info 748 * 749 * 750 * Return: QDF_STATUS 751 */ 752 753 QDF_STATUS 754 dp_rx_peer_ext_evt(struct dp_soc *soc, struct dp_peer_ext_evt_info *info); 755 #endif 756 #ifdef DP_RX_UDP_OVER_PEER_ROAM 757 /** 758 * dp_rx_reset_roaming_peer() - Reset the roamed peer in vdev 759 * @soc: dp soc pointer 760 * @vdev_id: vdev id 761 * @peer_mac_addr: mac address of the peer 762 * 763 * This function resets the roamed peer auth status and mac address 764 * after peer map indication of same peer is received from firmware. 765 * 766 * Return: None 767 */ 768 void dp_rx_reset_roaming_peer(struct dp_soc *soc, uint8_t vdev_id, 769 uint8_t *peer_mac_addr); 770 #else 771 static inline void dp_rx_reset_roaming_peer(struct dp_soc *soc, uint8_t vdev_id, 772 uint8_t *peer_mac_addr) 773 { 774 } 775 #endif 776 777 #ifdef WLAN_FEATURE_11BE_MLO 778 /** 779 * dp_rx_mlo_peer_map_handler() - handle MLO peer map event from firmware 780 * @soc: generic soc handle 781 * @peer_id: ML peer_id from firmware 782 * @peer_mac_addr: mac address of the peer 783 * @mlo_flow_info: MLO AST flow info 784 * @mlo_link_info: MLO link info 785 * 786 * associate the ML peer_id that firmware provided with peer entry 787 * and update the ast table in the host with the hw_peer_id. 788 * 789 * Return: QDF_STATUS code 790 */ 791 QDF_STATUS 792 dp_rx_mlo_peer_map_handler(struct dp_soc *soc, uint16_t peer_id, 793 uint8_t *peer_mac_addr, 794 struct dp_mlo_flow_override_info *mlo_flow_info, 795 struct dp_mlo_link_info *mlo_link_info); 796 797 /** 798 * dp_rx_mlo_peer_unmap_handler() - handle MLO peer unmap event from firmware 799 * @soc: generic soc handle 800 * @peer_id: peer_id from firmware 801 * 802 * Return: none 803 */ 804 void dp_rx_mlo_peer_unmap_handler(struct dp_soc *soc, uint16_t peer_id); 805 #endif 806 807 void dp_rx_sec_ind_handler(struct dp_soc *soc, uint16_t peer_id, 808 enum cdp_sec_type sec_type, int is_unicast, 809 u_int32_t *michael_key, u_int32_t *rx_pn); 810 811 uint8_t dp_get_peer_mac_addr_frm_id(struct cdp_soc_t *soc_handle, 812 uint16_t peer_id, uint8_t *peer_mac); 813 814 /** 815 * dp_peer_add_ast() - Allocate and add AST entry into peer list 816 * @soc: SoC handle 817 * @peer: peer to which ast node belongs 818 * @mac_addr: MAC address of ast node 819 * @type: AST entry type 820 * @flags: AST configuration flags 821 * 822 * This API is used by WDS source port learning function to 823 * add a new AST entry into peer AST list 824 * 825 * Return: QDF_STATUS code 826 */ 827 QDF_STATUS dp_peer_add_ast(struct dp_soc *soc, struct dp_peer *peer, 828 uint8_t *mac_addr, enum cdp_txrx_ast_entry_type type, 829 uint32_t flags); 830 831 /** 832 * dp_peer_del_ast() - Delete and free AST entry 833 * @soc: SoC handle 834 * @ast_entry: AST entry of the node 835 * 836 * This function removes the AST entry from peer and soc tables 837 * It assumes caller has taken the ast lock to protect the access to these 838 * tables 839 * 840 * Return: None 841 */ 842 void dp_peer_del_ast(struct dp_soc *soc, struct dp_ast_entry *ast_entry); 843 844 void dp_peer_ast_unmap_handler(struct dp_soc *soc, 845 struct dp_ast_entry *ast_entry); 846 847 /** 848 * dp_peer_update_ast() - Delete and free AST entry 849 * @soc: SoC handle 850 * @peer: peer to which ast node belongs 851 * @ast_entry: AST entry of the node 852 * @flags: wds or hmwds 853 * 854 * This function update the AST entry to the roamed peer and soc tables 855 * It assumes caller has taken the ast lock to protect the access to these 856 * tables 857 * 858 * Return: 0 if ast entry is updated successfully 859 * -1 failure 860 */ 861 int dp_peer_update_ast(struct dp_soc *soc, struct dp_peer *peer, 862 struct dp_ast_entry *ast_entry, uint32_t flags); 863 864 /** 865 * dp_peer_ast_hash_find_by_pdevid() - Find AST entry by MAC address 866 * @soc: SoC handle 867 * @ast_mac_addr: Mac address 868 * @pdev_id: pdev Id 869 * 870 * It assumes caller has taken the ast lock to protect the access to 871 * AST hash table 872 * 873 * Return: AST entry 874 */ 875 struct dp_ast_entry *dp_peer_ast_hash_find_by_pdevid(struct dp_soc *soc, 876 uint8_t *ast_mac_addr, 877 uint8_t pdev_id); 878 879 /** 880 * dp_peer_ast_hash_find_by_vdevid() - Find AST entry by MAC address 881 * @soc: SoC handle 882 * @ast_mac_addr: Mac address 883 * @vdev_id: vdev Id 884 * 885 * It assumes caller has taken the ast lock to protect the access to 886 * AST hash table 887 * 888 * Return: AST entry 889 */ 890 struct dp_ast_entry *dp_peer_ast_hash_find_by_vdevid(struct dp_soc *soc, 891 uint8_t *ast_mac_addr, 892 uint8_t vdev_id); 893 894 /** 895 * dp_peer_ast_hash_find_soc() - Find AST entry by MAC address 896 * @soc: SoC handle 897 * @ast_mac_addr: Mac address 898 * 899 * It assumes caller has taken the ast lock to protect the access to 900 * AST hash table 901 * 902 * Return: AST entry 903 */ 904 struct dp_ast_entry *dp_peer_ast_hash_find_soc(struct dp_soc *soc, 905 uint8_t *ast_mac_addr); 906 907 /** 908 * dp_peer_ast_hash_find_soc_by_type() - Find AST entry by MAC address 909 * and AST type 910 * @soc: SoC handle 911 * @ast_mac_addr: Mac address 912 * @type: AST entry type 913 * 914 * It assumes caller has taken the ast lock to protect the access to 915 * AST hash table 916 * 917 * Return: AST entry 918 */ 919 struct dp_ast_entry *dp_peer_ast_hash_find_soc_by_type( 920 struct dp_soc *soc, 921 uint8_t *ast_mac_addr, 922 enum cdp_txrx_ast_entry_type type); 923 924 /** 925 * dp_peer_ast_get_pdev_id() - get pdev_id from the ast entry 926 * @soc: SoC handle 927 * @ast_entry: AST entry of the node 928 * 929 * This function gets the pdev_id from the ast entry. 930 * 931 * Return: (uint8_t) pdev_id 932 */ 933 uint8_t dp_peer_ast_get_pdev_id(struct dp_soc *soc, 934 struct dp_ast_entry *ast_entry); 935 936 937 /** 938 * dp_peer_ast_get_next_hop() - get next_hop from the ast entry 939 * @soc: SoC handle 940 * @ast_entry: AST entry of the node 941 * 942 * This function gets the next hop from the ast entry. 943 * 944 * Return: (uint8_t) next_hop 945 */ 946 uint8_t dp_peer_ast_get_next_hop(struct dp_soc *soc, 947 struct dp_ast_entry *ast_entry); 948 949 /** 950 * dp_peer_ast_set_type() - set type from the ast entry 951 * @soc: SoC handle 952 * @ast_entry: AST entry of the node 953 * @type: AST entry type 954 * 955 * This function sets the type in the ast entry. 956 * 957 * Return: 958 */ 959 void dp_peer_ast_set_type(struct dp_soc *soc, 960 struct dp_ast_entry *ast_entry, 961 enum cdp_txrx_ast_entry_type type); 962 963 void dp_peer_ast_send_wds_del(struct dp_soc *soc, 964 struct dp_ast_entry *ast_entry, 965 struct dp_peer *peer); 966 967 #ifdef WLAN_FEATURE_MULTI_AST_DEL 968 void dp_peer_ast_send_multi_wds_del( 969 struct dp_soc *soc, uint8_t vdev_id, 970 struct peer_del_multi_wds_entries *wds_list); 971 #endif 972 973 void dp_peer_free_hmwds_cb(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, 974 struct cdp_soc *dp_soc, 975 void *cookie, 976 enum cdp_ast_free_status status); 977 978 /** 979 * dp_peer_ast_hash_remove() - Look up and remove AST entry from hash table 980 * @soc: SoC handle 981 * @ase: Address search entry 982 * 983 * This function removes the AST entry from soc AST hash table 984 * It assumes caller has taken the ast lock to protect the access to this table 985 * 986 * Return: None 987 */ 988 void dp_peer_ast_hash_remove(struct dp_soc *soc, 989 struct dp_ast_entry *ase); 990 991 /** 992 * dp_peer_free_ast_entry() - Free up the ast entry memory 993 * @soc: SoC handle 994 * @ast_entry: Address search entry 995 * 996 * This API is used to free up the memory associated with 997 * AST entry. 998 * 999 * Return: None 1000 */ 1001 void dp_peer_free_ast_entry(struct dp_soc *soc, 1002 struct dp_ast_entry *ast_entry); 1003 1004 /** 1005 * dp_peer_unlink_ast_entry() - Free up the ast entry memory 1006 * @soc: SoC handle 1007 * @ast_entry: Address search entry 1008 * @peer: peer 1009 * 1010 * This API is used to remove/unlink AST entry from the peer list 1011 * and hash list. 1012 * 1013 * Return: None 1014 */ 1015 void dp_peer_unlink_ast_entry(struct dp_soc *soc, 1016 struct dp_ast_entry *ast_entry, 1017 struct dp_peer *peer); 1018 1019 /** 1020 * dp_peer_mec_detach_entry() - Detach the MEC entry 1021 * @soc: SoC handle 1022 * @mecentry: MEC entry of the node 1023 * @ptr: pointer to free list 1024 * 1025 * The MEC entry is detached from MEC table and added to free_list 1026 * to free the object outside lock 1027 * 1028 * Return: None 1029 */ 1030 void dp_peer_mec_detach_entry(struct dp_soc *soc, struct dp_mec_entry *mecentry, 1031 void *ptr); 1032 1033 /** 1034 * dp_peer_mec_free_list() - free the MEC entry from free_list 1035 * @soc: SoC handle 1036 * @ptr: pointer to free list 1037 * 1038 * Return: None 1039 */ 1040 void dp_peer_mec_free_list(struct dp_soc *soc, void *ptr); 1041 1042 /** 1043 * dp_peer_mec_add_entry() 1044 * @soc: SoC handle 1045 * @vdev: vdev to which mec node belongs 1046 * @mac_addr: MAC address of mec node 1047 * 1048 * This function allocates and adds MEC entry to MEC table. 1049 * It assumes caller has taken the mec lock to protect the access to these 1050 * tables 1051 * 1052 * Return: QDF_STATUS 1053 */ 1054 QDF_STATUS dp_peer_mec_add_entry(struct dp_soc *soc, 1055 struct dp_vdev *vdev, 1056 uint8_t *mac_addr); 1057 1058 /** 1059 * dp_peer_mec_hash_find_by_pdevid() - Find MEC entry by PDEV Id 1060 * within pdev 1061 * @soc: SoC handle 1062 * @pdev_id: pdev Id 1063 * @mec_mac_addr: MAC address of mec node 1064 * 1065 * It assumes caller has taken the mec_lock to protect the access to 1066 * MEC hash table 1067 * 1068 * Return: MEC entry 1069 */ 1070 struct dp_mec_entry *dp_peer_mec_hash_find_by_pdevid(struct dp_soc *soc, 1071 uint8_t pdev_id, 1072 uint8_t *mec_mac_addr); 1073 1074 #define DP_AST_ASSERT(_condition) \ 1075 do { \ 1076 if (!(_condition)) { \ 1077 dp_print_ast_stats(soc);\ 1078 QDF_BUG(_condition); \ 1079 } \ 1080 } while (0) 1081 1082 /** 1083 * dp_peer_update_inactive_time() - Update inactive time for peer 1084 * @pdev: pdev object 1085 * @tag_type: htt_tlv_tag type 1086 * @tag_buf: buf message 1087 */ 1088 void 1089 dp_peer_update_inactive_time(struct dp_pdev *pdev, uint32_t tag_type, 1090 uint32_t *tag_buf); 1091 1092 #ifndef QCA_MULTIPASS_SUPPORT 1093 static inline 1094 /** 1095 * dp_peer_set_vlan_id() - set vlan_id for this peer 1096 * @cdp_soc: soc handle 1097 * @vdev_id: id of vdev object 1098 * @peer_mac: mac address 1099 * @vlan_id: vlan id for peer 1100 * 1101 * Return: void 1102 */ 1103 void dp_peer_set_vlan_id(struct cdp_soc_t *cdp_soc, 1104 uint8_t vdev_id, uint8_t *peer_mac, 1105 uint16_t vlan_id) 1106 { 1107 } 1108 1109 /** 1110 * dp_set_vlan_groupkey() - set vlan map for vdev 1111 * @soc_hdl: pointer to soc 1112 * @vdev_id: id of vdev handle 1113 * @vlan_id: vlan_id 1114 * @group_key: group key for vlan 1115 * 1116 * Return: set success/failure 1117 */ 1118 static inline 1119 QDF_STATUS dp_set_vlan_groupkey(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, 1120 uint16_t vlan_id, uint16_t group_key) 1121 { 1122 return QDF_STATUS_SUCCESS; 1123 } 1124 1125 /** 1126 * dp_peer_multipass_list_init() - initialize multipass peer list 1127 * @vdev: pointer to vdev 1128 * 1129 * Return: void 1130 */ 1131 static inline 1132 void dp_peer_multipass_list_init(struct dp_vdev *vdev) 1133 { 1134 } 1135 1136 /** 1137 * dp_peer_multipass_list_remove() - remove peer from special peer list 1138 * @peer: peer handle 1139 * 1140 * Return: void 1141 */ 1142 static inline 1143 void dp_peer_multipass_list_remove(struct dp_peer *peer) 1144 { 1145 } 1146 #else 1147 void dp_peer_set_vlan_id(struct cdp_soc_t *cdp_soc, 1148 uint8_t vdev_id, uint8_t *peer_mac, 1149 uint16_t vlan_id); 1150 QDF_STATUS dp_set_vlan_groupkey(struct cdp_soc_t *soc, uint8_t vdev_id, 1151 uint16_t vlan_id, uint16_t group_key); 1152 void dp_peer_multipass_list_init(struct dp_vdev *vdev); 1153 void dp_peer_multipass_list_remove(struct dp_peer *peer); 1154 #endif 1155 1156 1157 #ifndef QCA_PEER_MULTIQ_SUPPORT 1158 /** 1159 * dp_peer_reset_flowq_map() - reset peer flowq map table 1160 * @peer: dp peer handle 1161 * 1162 * Return: none 1163 */ 1164 static inline 1165 void dp_peer_reset_flowq_map(struct dp_peer *peer) 1166 { 1167 } 1168 1169 /** 1170 * dp_peer_ast_index_flow_queue_map_create() - create ast index flow queue map 1171 * @soc_hdl: generic soc handle 1172 * @is_wds: flag to indicate if peer is wds 1173 * @peer_id: peer_id from htt peer map message 1174 * @peer_mac_addr: mac address of the peer 1175 * @ast_info: ast flow override information from peer map 1176 * 1177 * Return: none 1178 */ 1179 static inline 1180 void dp_peer_ast_index_flow_queue_map_create(void *soc_hdl, 1181 bool is_wds, uint16_t peer_id, uint8_t *peer_mac_addr, 1182 struct dp_ast_flow_override_info *ast_info) 1183 { 1184 } 1185 #else 1186 void dp_peer_reset_flowq_map(struct dp_peer *peer); 1187 1188 void dp_peer_ast_index_flow_queue_map_create(void *soc_hdl, 1189 bool is_wds, uint16_t peer_id, uint8_t *peer_mac_addr, 1190 struct dp_ast_flow_override_info *ast_info); 1191 #endif 1192 1193 #ifdef QCA_PEER_EXT_STATS 1194 /** 1195 * dp_peer_delay_stats_ctx_alloc() - Allocate peer delay stats content 1196 * @soc: DP SoC context 1197 * @txrx_peer: DP txrx peer context 1198 * 1199 * Allocate the peer delay stats context 1200 * 1201 * Return: QDF_STATUS_SUCCESS if allocation is 1202 * successful 1203 */ 1204 QDF_STATUS dp_peer_delay_stats_ctx_alloc(struct dp_soc *soc, 1205 struct dp_txrx_peer *txrx_peer); 1206 1207 /** 1208 * dp_peer_delay_stats_ctx_dealloc() - Dealloc the peer delay stats context 1209 * @soc: DP SoC context 1210 * @txrx_peer: txrx DP peer context 1211 * 1212 * Free the peer delay stats context 1213 * 1214 * Return: Void 1215 */ 1216 void dp_peer_delay_stats_ctx_dealloc(struct dp_soc *soc, 1217 struct dp_txrx_peer *txrx_peer); 1218 1219 /** 1220 * dp_peer_delay_stats_ctx_clr() - Clear delay stats context of peer 1221 * @txrx_peer: dp_txrx_peer handle 1222 * 1223 * Return: void 1224 */ 1225 void dp_peer_delay_stats_ctx_clr(struct dp_txrx_peer *txrx_peer); 1226 #else 1227 static inline 1228 QDF_STATUS dp_peer_delay_stats_ctx_alloc(struct dp_soc *soc, 1229 struct dp_txrx_peer *txrx_peer) 1230 { 1231 return QDF_STATUS_SUCCESS; 1232 } 1233 1234 static inline 1235 void dp_peer_delay_stats_ctx_dealloc(struct dp_soc *soc, 1236 struct dp_txrx_peer *txrx_peer) 1237 { 1238 } 1239 1240 static inline 1241 void dp_peer_delay_stats_ctx_clr(struct dp_txrx_peer *txrx_peer) 1242 { 1243 } 1244 #endif 1245 1246 #ifdef WLAN_PEER_JITTER 1247 /** 1248 * dp_peer_jitter_stats_ctx_alloc() - Allocate jitter stats context for peer 1249 * @pdev: Datapath pdev handle 1250 * @txrx_peer: dp_txrx_peer handle 1251 * 1252 * Return: QDF_STATUS 1253 */ 1254 QDF_STATUS dp_peer_jitter_stats_ctx_alloc(struct dp_pdev *pdev, 1255 struct dp_txrx_peer *txrx_peer); 1256 1257 /** 1258 * dp_peer_jitter_stats_ctx_dealloc() - Deallocate jitter stats context 1259 * @pdev: Datapath pdev handle 1260 * @txrx_peer: dp_txrx_peer handle 1261 * 1262 * Return: void 1263 */ 1264 void dp_peer_jitter_stats_ctx_dealloc(struct dp_pdev *pdev, 1265 struct dp_txrx_peer *txrx_peer); 1266 1267 /** 1268 * dp_peer_jitter_stats_ctx_clr() - Clear jitter stats context of peer 1269 * @txrx_peer: dp_txrx_peer handle 1270 * 1271 * Return: void 1272 */ 1273 void dp_peer_jitter_stats_ctx_clr(struct dp_txrx_peer *txrx_peer); 1274 #else 1275 static inline 1276 QDF_STATUS dp_peer_jitter_stats_ctx_alloc(struct dp_pdev *pdev, 1277 struct dp_txrx_peer *txrx_peer) 1278 { 1279 return QDF_STATUS_SUCCESS; 1280 } 1281 1282 static inline 1283 void dp_peer_jitter_stats_ctx_dealloc(struct dp_pdev *pdev, 1284 struct dp_txrx_peer *txrx_peer) 1285 { 1286 } 1287 1288 static inline 1289 void dp_peer_jitter_stats_ctx_clr(struct dp_txrx_peer *txrx_peer) 1290 { 1291 } 1292 #endif 1293 1294 #ifndef CONFIG_SAWF_DEF_QUEUES 1295 static inline QDF_STATUS dp_peer_sawf_ctx_alloc(struct dp_soc *soc, 1296 struct dp_peer *peer) 1297 { 1298 return QDF_STATUS_SUCCESS; 1299 } 1300 1301 static inline QDF_STATUS dp_peer_sawf_ctx_free(struct dp_soc *soc, 1302 struct dp_peer *peer) 1303 { 1304 return QDF_STATUS_SUCCESS; 1305 } 1306 1307 #endif 1308 1309 #ifndef CONFIG_SAWF 1310 static inline 1311 QDF_STATUS dp_peer_sawf_stats_ctx_alloc(struct dp_soc *soc, 1312 struct dp_txrx_peer *txrx_peer) 1313 { 1314 return QDF_STATUS_SUCCESS; 1315 } 1316 1317 static inline 1318 QDF_STATUS dp_peer_sawf_stats_ctx_free(struct dp_soc *soc, 1319 struct dp_txrx_peer *txrx_peer) 1320 { 1321 return QDF_STATUS_SUCCESS; 1322 } 1323 #endif 1324 1325 /** 1326 * dp_vdev_bss_peer_ref_n_get: Get bss peer of a vdev 1327 * @soc: DP soc 1328 * @vdev: vdev 1329 * @mod_id: id of module requesting reference 1330 * 1331 * Return: VDEV BSS peer 1332 */ 1333 struct dp_peer *dp_vdev_bss_peer_ref_n_get(struct dp_soc *soc, 1334 struct dp_vdev *vdev, 1335 enum dp_mod_id mod_id); 1336 1337 /** 1338 * dp_sta_vdev_self_peer_ref_n_get: Get self peer of sta vdev 1339 * @soc: DP soc 1340 * @vdev: vdev 1341 * @mod_id: id of module requesting reference 1342 * 1343 * Return: VDEV self peer 1344 */ 1345 struct dp_peer *dp_sta_vdev_self_peer_ref_n_get(struct dp_soc *soc, 1346 struct dp_vdev *vdev, 1347 enum dp_mod_id mod_id); 1348 1349 void dp_peer_ast_table_detach(struct dp_soc *soc); 1350 1351 /** 1352 * dp_peer_find_map_detach() - cleanup memory for peer_id_to_obj_map 1353 * @soc: soc handle 1354 * 1355 * Return: none 1356 */ 1357 void dp_peer_find_map_detach(struct dp_soc *soc); 1358 1359 void dp_soc_wds_detach(struct dp_soc *soc); 1360 QDF_STATUS dp_peer_ast_table_attach(struct dp_soc *soc); 1361 1362 /** 1363 * dp_find_peer_by_macaddr() - Finding the peer from mac address provided. 1364 * @soc: soc handle 1365 * @mac_addr: MAC address to be used to find peer 1366 * @vdev_id: VDEV id 1367 * @mod_id: MODULE ID 1368 * 1369 * Return: struct dp_peer 1370 */ 1371 struct dp_peer *dp_find_peer_by_macaddr(struct dp_soc *soc, uint8_t *mac_addr, 1372 uint8_t vdev_id, enum dp_mod_id mod_id); 1373 /** 1374 * dp_peer_ast_hash_attach() - Allocate and initialize AST Hash Table 1375 * @soc: SoC handle 1376 * 1377 * Return: QDF_STATUS 1378 */ 1379 QDF_STATUS dp_peer_ast_hash_attach(struct dp_soc *soc); 1380 1381 /** 1382 * dp_peer_mec_hash_attach() - Allocate and initialize MEC Hash Table 1383 * @soc: SoC handle 1384 * 1385 * Return: QDF_STATUS 1386 */ 1387 QDF_STATUS dp_peer_mec_hash_attach(struct dp_soc *soc); 1388 1389 /** 1390 * dp_del_wds_entry_wrapper() - delete a WDS AST entry 1391 * @soc: DP soc structure pointer 1392 * @vdev_id: vdev_id 1393 * @wds_macaddr: MAC address of ast node 1394 * @type: type from enum cdp_txrx_ast_entry_type 1395 * @delete_in_fw: Flag to indicate if entry needs to be deleted in fw 1396 * 1397 * This API is used to delete an AST entry from fw 1398 * 1399 * Return: None 1400 */ 1401 void dp_del_wds_entry_wrapper(struct dp_soc *soc, uint8_t vdev_id, 1402 uint8_t *wds_macaddr, uint8_t type, 1403 uint8_t delete_in_fw); 1404 1405 void dp_soc_wds_attach(struct dp_soc *soc); 1406 1407 /** 1408 * dp_peer_mec_hash_detach() - Free MEC Hash table 1409 * @soc: SoC handle 1410 * 1411 * Return: None 1412 */ 1413 void dp_peer_mec_hash_detach(struct dp_soc *soc); 1414 1415 /** 1416 * dp_peer_ast_hash_detach() - Free AST Hash table 1417 * @soc: SoC handle 1418 * 1419 * Return: None 1420 */ 1421 void dp_peer_ast_hash_detach(struct dp_soc *soc); 1422 1423 #ifdef FEATURE_AST 1424 /** 1425 * dp_peer_delete_ast_entries(): Delete all AST entries for a peer 1426 * @soc: datapath soc handle 1427 * @peer: datapath peer handle 1428 * 1429 * Delete the AST entries belonging to a peer 1430 */ 1431 static inline void dp_peer_delete_ast_entries(struct dp_soc *soc, 1432 struct dp_peer *peer) 1433 { 1434 struct dp_ast_entry *ast_entry, *temp_ast_entry; 1435 1436 dp_peer_debug("peer: %pK, self_ast: %pK", peer, peer->self_ast_entry); 1437 /* 1438 * Delete peer self ast entry. This is done to handle scenarios 1439 * where peer is freed before peer map is received(for ex in case 1440 * of auth disallow due to ACL) in such cases self ast is not added 1441 * to peer->ast_list. 1442 */ 1443 if (peer->self_ast_entry) { 1444 dp_peer_del_ast(soc, peer->self_ast_entry); 1445 peer->self_ast_entry = NULL; 1446 } 1447 1448 DP_PEER_ITERATE_ASE_LIST(peer, ast_entry, temp_ast_entry) 1449 dp_peer_del_ast(soc, ast_entry); 1450 } 1451 1452 /** 1453 * dp_print_peer_ast_entries() - Dump AST entries of peer 1454 * @soc: Datapath soc handle 1455 * @peer: Datapath peer 1456 * @arg: argument to iterate function 1457 * 1458 * Return: void 1459 */ 1460 void dp_print_peer_ast_entries(struct dp_soc *soc, struct dp_peer *peer, 1461 void *arg); 1462 #else 1463 static inline void dp_print_peer_ast_entries(struct dp_soc *soc, 1464 struct dp_peer *peer, void *arg) 1465 { 1466 } 1467 1468 static inline void dp_peer_delete_ast_entries(struct dp_soc *soc, 1469 struct dp_peer *peer) 1470 { 1471 } 1472 #endif 1473 1474 #ifdef FEATURE_MEC 1475 /** 1476 * dp_peer_mec_spinlock_create() - Create the MEC spinlock 1477 * @soc: SoC handle 1478 * 1479 * Return: none 1480 */ 1481 void dp_peer_mec_spinlock_create(struct dp_soc *soc); 1482 1483 /** 1484 * dp_peer_mec_spinlock_destroy() - Destroy the MEC spinlock 1485 * @soc: SoC handle 1486 * 1487 * Return: none 1488 */ 1489 void dp_peer_mec_spinlock_destroy(struct dp_soc *soc); 1490 1491 /** 1492 * dp_peer_mec_flush_entries() - Delete all mec entries in table 1493 * @soc: Datapath SOC 1494 * 1495 * Return: None 1496 */ 1497 void dp_peer_mec_flush_entries(struct dp_soc *soc); 1498 #else 1499 static inline void dp_peer_mec_spinlock_create(struct dp_soc *soc) 1500 { 1501 } 1502 1503 static inline void dp_peer_mec_spinlock_destroy(struct dp_soc *soc) 1504 { 1505 } 1506 1507 static inline void dp_peer_mec_flush_entries(struct dp_soc *soc) 1508 { 1509 } 1510 #endif 1511 1512 static inline int dp_peer_find_mac_addr_cmp( 1513 union dp_align_mac_addr *mac_addr1, 1514 union dp_align_mac_addr *mac_addr2) 1515 { 1516 /* 1517 * Intentionally use & rather than &&. 1518 * because the operands are binary rather than generic boolean, 1519 * the functionality is equivalent. 1520 * Using && has the advantage of short-circuited evaluation, 1521 * but using & has the advantage of no conditional branching, 1522 * which is a more significant benefit. 1523 */ 1524 return !((mac_addr1->align4.bytes_abcd == mac_addr2->align4.bytes_abcd) 1525 & (mac_addr1->align4.bytes_ef == mac_addr2->align4.bytes_ef)); 1526 } 1527 1528 /** 1529 * dp_peer_delete() - delete DP peer 1530 * 1531 * @soc: Datatpath soc 1532 * @peer: Datapath peer 1533 * @arg: argument to iter function 1534 * 1535 * Return: void 1536 */ 1537 void dp_peer_delete(struct dp_soc *soc, 1538 struct dp_peer *peer, 1539 void *arg); 1540 1541 /** 1542 * dp_mlo_peer_delete() - delete MLO DP peer 1543 * 1544 * @soc: Datapath soc 1545 * @peer: Datapath peer 1546 * @arg: argument to iter function 1547 * 1548 * Return: void 1549 */ 1550 void dp_mlo_peer_delete(struct dp_soc *soc, struct dp_peer *peer, void *arg); 1551 1552 #ifdef WLAN_FEATURE_11BE_MLO 1553 1554 /* is MLO connection mld peer */ 1555 #define IS_MLO_DP_MLD_TXRX_PEER(_peer) ((_peer)->mld_peer) 1556 1557 /* set peer type */ 1558 #define DP_PEER_SET_TYPE(_peer, _type_val) \ 1559 ((_peer)->peer_type = (_type_val)) 1560 1561 /* is legacy peer */ 1562 #define IS_DP_LEGACY_PEER(_peer) \ 1563 ((_peer)->peer_type == CDP_LINK_PEER_TYPE && !((_peer)->mld_peer)) 1564 /* is MLO connection link peer */ 1565 #define IS_MLO_DP_LINK_PEER(_peer) \ 1566 ((_peer)->peer_type == CDP_LINK_PEER_TYPE && (_peer)->mld_peer) 1567 /* is MLO connection mld peer */ 1568 #define IS_MLO_DP_MLD_PEER(_peer) \ 1569 ((_peer)->peer_type == CDP_MLD_PEER_TYPE) 1570 /* Get Mld peer from link peer */ 1571 #define DP_GET_MLD_PEER_FROM_PEER(link_peer) \ 1572 ((link_peer)->mld_peer) 1573 1574 #ifdef WLAN_MLO_MULTI_CHIP 1575 static inline uint8_t dp_get_chip_id(struct dp_soc *soc) 1576 { 1577 if (soc->arch_ops.mlo_get_chip_id) 1578 return soc->arch_ops.mlo_get_chip_id(soc); 1579 1580 return 0; 1581 } 1582 1583 static inline struct dp_peer * 1584 dp_link_peer_hash_find_by_chip_id(struct dp_soc *soc, 1585 uint8_t *peer_mac_addr, 1586 int mac_addr_is_aligned, 1587 uint8_t vdev_id, 1588 uint8_t chip_id, 1589 enum dp_mod_id mod_id) 1590 { 1591 if (soc->arch_ops.mlo_link_peer_find_hash_find_by_chip_id) 1592 return soc->arch_ops.mlo_link_peer_find_hash_find_by_chip_id 1593 (soc, peer_mac_addr, 1594 mac_addr_is_aligned, 1595 vdev_id, chip_id, 1596 mod_id); 1597 1598 return NULL; 1599 } 1600 #else 1601 static inline uint8_t dp_get_chip_id(struct dp_soc *soc) 1602 { 1603 return 0; 1604 } 1605 1606 static inline struct dp_peer * 1607 dp_link_peer_hash_find_by_chip_id(struct dp_soc *soc, 1608 uint8_t *peer_mac_addr, 1609 int mac_addr_is_aligned, 1610 uint8_t vdev_id, 1611 uint8_t chip_id, 1612 enum dp_mod_id mod_id) 1613 { 1614 return dp_peer_find_hash_find(soc, peer_mac_addr, 1615 mac_addr_is_aligned, 1616 vdev_id, mod_id); 1617 } 1618 #endif 1619 1620 /** 1621 * dp_mld_peer_find_hash_find() - returns mld peer from mld peer_hash_table 1622 * matching mac_address 1623 * @soc: soc handle 1624 * @peer_mac_addr: mld peer mac address 1625 * @mac_addr_is_aligned: is mac addr aligned 1626 * @vdev_id: vdev_id 1627 * @mod_id: id of module requesting reference 1628 * 1629 * Return: peer in success 1630 * NULL in failure 1631 */ 1632 static inline 1633 struct dp_peer *dp_mld_peer_find_hash_find(struct dp_soc *soc, 1634 uint8_t *peer_mac_addr, 1635 int mac_addr_is_aligned, 1636 uint8_t vdev_id, 1637 enum dp_mod_id mod_id) 1638 { 1639 if (soc->arch_ops.mlo_peer_find_hash_find) 1640 return soc->arch_ops.mlo_peer_find_hash_find(soc, 1641 peer_mac_addr, 1642 mac_addr_is_aligned, 1643 mod_id, vdev_id); 1644 return NULL; 1645 } 1646 1647 /** 1648 * dp_peer_hash_find_wrapper() - find link peer or mld per according to 1649 * peer_type 1650 * @soc: DP SOC handle 1651 * @peer_info: peer information for hash find 1652 * @mod_id: ID of module requesting reference 1653 * 1654 * Return: peer handle 1655 */ 1656 static inline 1657 struct dp_peer *dp_peer_hash_find_wrapper(struct dp_soc *soc, 1658 struct cdp_peer_info *peer_info, 1659 enum dp_mod_id mod_id) 1660 { 1661 struct dp_peer *peer = NULL; 1662 1663 if (peer_info->peer_type == CDP_LINK_PEER_TYPE || 1664 peer_info->peer_type == CDP_WILD_PEER_TYPE) { 1665 peer = dp_peer_find_hash_find(soc, peer_info->mac_addr, 1666 peer_info->mac_addr_is_aligned, 1667 peer_info->vdev_id, 1668 mod_id); 1669 if (peer) 1670 return peer; 1671 } 1672 if (peer_info->peer_type == CDP_MLD_PEER_TYPE || 1673 peer_info->peer_type == CDP_WILD_PEER_TYPE) 1674 peer = dp_mld_peer_find_hash_find( 1675 soc, peer_info->mac_addr, 1676 peer_info->mac_addr_is_aligned, 1677 peer_info->vdev_id, 1678 mod_id); 1679 return peer; 1680 } 1681 1682 /** 1683 * dp_link_peer_add_mld_peer() - add mld peer pointer to link peer, 1684 * increase mld peer ref_cnt 1685 * @link_peer: link peer pointer 1686 * @mld_peer: mld peer pointer 1687 * 1688 * Return: none 1689 */ 1690 static inline 1691 void dp_link_peer_add_mld_peer(struct dp_peer *link_peer, 1692 struct dp_peer *mld_peer) 1693 { 1694 /* increase mld_peer ref_cnt */ 1695 dp_peer_get_ref(NULL, mld_peer, DP_MOD_ID_CDP); 1696 link_peer->mld_peer = mld_peer; 1697 } 1698 1699 /** 1700 * dp_link_peer_del_mld_peer() - delete mld peer pointer from link peer, 1701 * decrease mld peer ref_cnt 1702 * @link_peer: link peer pointer 1703 * 1704 * Return: None 1705 */ 1706 static inline 1707 void dp_link_peer_del_mld_peer(struct dp_peer *link_peer) 1708 { 1709 dp_peer_unref_delete(link_peer->mld_peer, DP_MOD_ID_CDP); 1710 link_peer->mld_peer = NULL; 1711 } 1712 1713 /** 1714 * dp_mld_peer_init_link_peers_info() - init link peers info in mld peer 1715 * @mld_peer: mld peer pointer 1716 * 1717 * Return: None 1718 */ 1719 static inline 1720 void dp_mld_peer_init_link_peers_info(struct dp_peer *mld_peer) 1721 { 1722 int i; 1723 1724 qdf_spinlock_create(&mld_peer->link_peers_info_lock); 1725 mld_peer->num_links = 0; 1726 for (i = 0; i < DP_MAX_MLO_LINKS; i++) 1727 mld_peer->link_peers[i].is_valid = false; 1728 } 1729 1730 /** 1731 * dp_mld_peer_deinit_link_peers_info() - Deinit link peers info in mld peer 1732 * @mld_peer: mld peer pointer 1733 * 1734 * Return: None 1735 */ 1736 static inline 1737 void dp_mld_peer_deinit_link_peers_info(struct dp_peer *mld_peer) 1738 { 1739 qdf_spinlock_destroy(&mld_peer->link_peers_info_lock); 1740 } 1741 1742 /** 1743 * dp_mld_peer_add_link_peer() - add link peer info to mld peer 1744 * @mld_peer: mld dp peer pointer 1745 * @link_peer: link dp peer pointer 1746 * @is_bridge_peer: flag to indicate if peer is bridge peer 1747 * 1748 * Return: None 1749 */ 1750 static inline 1751 void dp_mld_peer_add_link_peer(struct dp_peer *mld_peer, 1752 struct dp_peer *link_peer, 1753 uint8_t is_bridge_peer) 1754 { 1755 int i; 1756 struct dp_peer_link_info *link_peer_info; 1757 struct dp_soc *soc = mld_peer->vdev->pdev->soc; 1758 1759 qdf_spin_lock_bh(&mld_peer->link_peers_info_lock); 1760 for (i = 0; i < DP_MAX_MLO_LINKS; i++) { 1761 link_peer_info = &mld_peer->link_peers[i]; 1762 if (!link_peer_info->is_valid) { 1763 qdf_mem_copy(link_peer_info->mac_addr.raw, 1764 link_peer->mac_addr.raw, 1765 QDF_MAC_ADDR_SIZE); 1766 link_peer_info->is_valid = true; 1767 link_peer_info->vdev_id = link_peer->vdev->vdev_id; 1768 link_peer_info->chip_id = 1769 dp_get_chip_id(link_peer->vdev->pdev->soc); 1770 link_peer_info->is_bridge_peer = is_bridge_peer; 1771 mld_peer->num_links++; 1772 break; 1773 } 1774 } 1775 qdf_spin_unlock_bh(&mld_peer->link_peers_info_lock); 1776 1777 dp_peer_info("%s addition of link peer %pK (" QDF_MAC_ADDR_FMT ") " 1778 "to MLD peer %pK (" QDF_MAC_ADDR_FMT "), " 1779 "idx %u num_links %u", 1780 (i != DP_MAX_MLO_LINKS) ? "Successful" : "Failed", 1781 link_peer, QDF_MAC_ADDR_REF(link_peer->mac_addr.raw), 1782 mld_peer, QDF_MAC_ADDR_REF(mld_peer->mac_addr.raw), 1783 i, mld_peer->num_links); 1784 1785 dp_cfg_event_record_mlo_link_delink_evt(soc, DP_CFG_EVENT_MLO_ADD_LINK, 1786 mld_peer, link_peer, i, 1787 (i != DP_MAX_MLO_LINKS) ? 1 : 0); 1788 } 1789 1790 /** 1791 * dp_mld_peer_del_link_peer() - Delete link peer info from MLD peer 1792 * @mld_peer: MLD dp peer pointer 1793 * @link_peer: link dp peer pointer 1794 * 1795 * Return: number of links left after deletion 1796 */ 1797 static inline 1798 uint8_t dp_mld_peer_del_link_peer(struct dp_peer *mld_peer, 1799 struct dp_peer *link_peer) 1800 { 1801 int i; 1802 struct dp_peer_link_info *link_peer_info; 1803 uint8_t num_links; 1804 struct dp_soc *soc = mld_peer->vdev->pdev->soc; 1805 1806 qdf_spin_lock_bh(&mld_peer->link_peers_info_lock); 1807 for (i = 0; i < DP_MAX_MLO_LINKS; i++) { 1808 link_peer_info = &mld_peer->link_peers[i]; 1809 if (link_peer_info->is_valid && 1810 !dp_peer_find_mac_addr_cmp(&link_peer->mac_addr, 1811 &link_peer_info->mac_addr)) { 1812 link_peer_info->is_valid = false; 1813 mld_peer->num_links--; 1814 break; 1815 } 1816 } 1817 num_links = mld_peer->num_links; 1818 qdf_spin_unlock_bh(&mld_peer->link_peers_info_lock); 1819 1820 dp_peer_info("%s deletion of link peer %pK (" QDF_MAC_ADDR_FMT ") " 1821 "from MLD peer %pK (" QDF_MAC_ADDR_FMT "), " 1822 "idx %u num_links %u", 1823 (i != DP_MAX_MLO_LINKS) ? "Successful" : "Failed", 1824 link_peer, QDF_MAC_ADDR_REF(link_peer->mac_addr.raw), 1825 mld_peer, QDF_MAC_ADDR_REF(mld_peer->mac_addr.raw), 1826 i, mld_peer->num_links); 1827 1828 dp_cfg_event_record_mlo_link_delink_evt(soc, DP_CFG_EVENT_MLO_DEL_LINK, 1829 mld_peer, link_peer, i, 1830 (i != DP_MAX_MLO_LINKS) ? 1 : 0); 1831 1832 return num_links; 1833 } 1834 1835 /** 1836 * dp_get_link_peers_ref_from_mld_peer() - get link peers pointer and 1837 * increase link peers ref_cnt 1838 * @soc: dp_soc handle 1839 * @mld_peer: dp mld peer pointer 1840 * @mld_link_peers: structure that hold links peers pointer array and number 1841 * @mod_id: id of module requesting reference 1842 * 1843 * Return: None 1844 */ 1845 static inline 1846 void dp_get_link_peers_ref_from_mld_peer( 1847 struct dp_soc *soc, 1848 struct dp_peer *mld_peer, 1849 struct dp_mld_link_peers *mld_link_peers, 1850 enum dp_mod_id mod_id) 1851 { 1852 struct dp_peer *peer; 1853 uint8_t i = 0, j = 0; 1854 struct dp_peer_link_info *link_peer_info; 1855 1856 qdf_mem_zero(mld_link_peers, sizeof(*mld_link_peers)); 1857 qdf_spin_lock_bh(&mld_peer->link_peers_info_lock); 1858 for (i = 0; i < DP_MAX_MLO_LINKS; i++) { 1859 link_peer_info = &mld_peer->link_peers[i]; 1860 if (link_peer_info->is_valid) { 1861 peer = dp_link_peer_hash_find_by_chip_id( 1862 soc, 1863 link_peer_info->mac_addr.raw, 1864 true, 1865 link_peer_info->vdev_id, 1866 link_peer_info->chip_id, 1867 mod_id); 1868 if (peer) 1869 mld_link_peers->link_peers[j++] = peer; 1870 } 1871 } 1872 qdf_spin_unlock_bh(&mld_peer->link_peers_info_lock); 1873 1874 mld_link_peers->num_links = j; 1875 } 1876 1877 /** 1878 * dp_release_link_peers_ref() - release all link peers reference 1879 * @mld_link_peers: structure that hold links peers pointer array and number 1880 * @mod_id: id of module requesting reference 1881 * 1882 * Return: None. 1883 */ 1884 static inline 1885 void dp_release_link_peers_ref( 1886 struct dp_mld_link_peers *mld_link_peers, 1887 enum dp_mod_id mod_id) 1888 { 1889 struct dp_peer *peer; 1890 uint8_t i; 1891 1892 for (i = 0; i < mld_link_peers->num_links; i++) { 1893 peer = mld_link_peers->link_peers[i]; 1894 if (peer) 1895 dp_peer_unref_delete(peer, mod_id); 1896 mld_link_peers->link_peers[i] = NULL; 1897 } 1898 1899 mld_link_peers->num_links = 0; 1900 } 1901 1902 /** 1903 * dp_get_link_peer_id_by_lmac_id() - Get link peer id using peer id and lmac id 1904 * @soc: Datapath soc handle 1905 * @peer_id: peer id 1906 * @lmac_id: lmac id to find the link peer on given lmac 1907 * 1908 * Return: peer_id of link peer if found 1909 * else return HTT_INVALID_PEER 1910 */ 1911 static inline 1912 uint16_t dp_get_link_peer_id_by_lmac_id(struct dp_soc *soc, uint16_t peer_id, 1913 uint8_t lmac_id) 1914 { 1915 uint8_t i; 1916 struct dp_peer *peer; 1917 struct dp_peer *link_peer; 1918 struct dp_soc *link_peer_soc; 1919 struct dp_mld_link_peers link_peers_info; 1920 uint16_t link_peer_id = HTT_INVALID_PEER; 1921 1922 peer = dp_peer_get_ref_by_id(soc, peer_id, DP_MOD_ID_CDP); 1923 1924 if (!peer) 1925 return HTT_INVALID_PEER; 1926 1927 if (IS_MLO_DP_MLD_PEER(peer)) { 1928 /* get link peers with reference */ 1929 dp_get_link_peers_ref_from_mld_peer(soc, peer, &link_peers_info, 1930 DP_MOD_ID_CDP); 1931 1932 for (i = 0; i < link_peers_info.num_links; i++) { 1933 link_peer = link_peers_info.link_peers[i]; 1934 link_peer_soc = link_peer->vdev->pdev->soc; 1935 if ((link_peer_soc == soc) && 1936 (link_peer->vdev->pdev->lmac_id == lmac_id)) { 1937 link_peer_id = link_peer->peer_id; 1938 break; 1939 } 1940 } 1941 /* release link peers reference */ 1942 dp_release_link_peers_ref(&link_peers_info, DP_MOD_ID_CDP); 1943 } else { 1944 link_peer_id = peer_id; 1945 } 1946 1947 dp_peer_unref_delete(peer, DP_MOD_ID_CDP); 1948 1949 return link_peer_id; 1950 } 1951 1952 /** 1953 * dp_peer_get_tgt_peer_hash_find() - get dp_peer handle 1954 * @soc: soc handle 1955 * @peer_mac: peer mac address 1956 * @mac_addr_is_aligned: is mac addr aligned 1957 * @vdev_id: vdev_id 1958 * @mod_id: id of module requesting reference 1959 * 1960 * for MLO connection, get corresponding MLD peer, 1961 * otherwise get link peer for non-MLO case. 1962 * 1963 * Return: peer in success 1964 * NULL in failure 1965 */ 1966 static inline 1967 struct dp_peer *dp_peer_get_tgt_peer_hash_find(struct dp_soc *soc, 1968 uint8_t *peer_mac, 1969 int mac_addr_is_aligned, 1970 uint8_t vdev_id, 1971 enum dp_mod_id mod_id) 1972 { 1973 struct dp_peer *ta_peer = NULL; 1974 struct dp_peer *peer = dp_peer_find_hash_find(soc, 1975 peer_mac, 0, vdev_id, 1976 mod_id); 1977 1978 if (peer) { 1979 /* mlo connection link peer, get mld peer with reference */ 1980 if (IS_MLO_DP_LINK_PEER(peer)) { 1981 /* increase mld peer ref_cnt */ 1982 if (QDF_STATUS_SUCCESS == 1983 dp_peer_get_ref(soc, peer->mld_peer, mod_id)) 1984 ta_peer = peer->mld_peer; 1985 else 1986 ta_peer = NULL; 1987 1988 /* release peer reference that added by hash find */ 1989 dp_peer_unref_delete(peer, mod_id); 1990 } else { 1991 /* mlo MLD peer or non-mlo link peer */ 1992 ta_peer = peer; 1993 } 1994 } else { 1995 dp_peer_err("fail to find peer:" QDF_MAC_ADDR_FMT " vdev_id: %u", 1996 QDF_MAC_ADDR_REF(peer_mac), vdev_id); 1997 } 1998 1999 return ta_peer; 2000 } 2001 2002 /** 2003 * dp_peer_get_tgt_peer_by_id() - Returns target peer object given the peer id 2004 * @soc: core DP soc context 2005 * @peer_id: peer id from peer object can be retrieved 2006 * @mod_id: ID of module requesting reference 2007 * 2008 * for MLO connection, get corresponding MLD peer, 2009 * otherwise get link peer for non-MLO case. 2010 * 2011 * Return: peer in success 2012 * NULL in failure 2013 */ 2014 static inline 2015 struct dp_peer *dp_peer_get_tgt_peer_by_id(struct dp_soc *soc, 2016 uint16_t peer_id, 2017 enum dp_mod_id mod_id) 2018 { 2019 struct dp_peer *ta_peer = NULL; 2020 struct dp_peer *peer = dp_peer_get_ref_by_id(soc, peer_id, mod_id); 2021 2022 if (peer) { 2023 /* mlo connection link peer, get mld peer with reference */ 2024 if (IS_MLO_DP_LINK_PEER(peer)) { 2025 /* increase mld peer ref_cnt */ 2026 if (QDF_STATUS_SUCCESS == 2027 dp_peer_get_ref(soc, peer->mld_peer, mod_id)) 2028 ta_peer = peer->mld_peer; 2029 else 2030 ta_peer = NULL; 2031 2032 /* release peer reference that added by hash find */ 2033 dp_peer_unref_delete(peer, mod_id); 2034 } else { 2035 /* mlo MLD peer or non-mlo link peer */ 2036 ta_peer = peer; 2037 } 2038 } 2039 2040 return ta_peer; 2041 } 2042 2043 /** 2044 * dp_peer_mlo_delete() - peer MLO related delete operation 2045 * @peer: DP peer handle 2046 * Return: None 2047 */ 2048 static inline 2049 void dp_peer_mlo_delete(struct dp_peer *peer) 2050 { 2051 struct dp_peer *ml_peer; 2052 struct dp_soc *soc; 2053 2054 dp_info("peer " QDF_MAC_ADDR_FMT " type %d", 2055 QDF_MAC_ADDR_REF(peer->mac_addr.raw), peer->peer_type); 2056 2057 /* MLO connection link peer */ 2058 if (IS_MLO_DP_LINK_PEER(peer)) { 2059 ml_peer = peer->mld_peer; 2060 soc = ml_peer->vdev->pdev->soc; 2061 2062 /* if last link peer deletion, delete MLD peer */ 2063 if (dp_mld_peer_del_link_peer(peer->mld_peer, peer) == 0) 2064 dp_peer_delete(soc, peer->mld_peer, NULL); 2065 } 2066 } 2067 2068 /** 2069 * dp_peer_mlo_setup() - create MLD peer and MLO related initialization 2070 * @soc: Soc handle 2071 * @peer: DP peer handle 2072 * @vdev_id: Vdev ID 2073 * @setup_info: peer setup information for MLO 2074 */ 2075 QDF_STATUS dp_peer_mlo_setup( 2076 struct dp_soc *soc, 2077 struct dp_peer *peer, 2078 uint8_t vdev_id, 2079 struct cdp_peer_setup_info *setup_info); 2080 2081 /** 2082 * dp_get_tgt_peer_from_peer() - Get target peer from the given peer 2083 * @peer: datapath peer 2084 * 2085 * Return: MLD peer in case of MLO Link peer 2086 * Peer itself in other cases 2087 */ 2088 static inline 2089 struct dp_peer *dp_get_tgt_peer_from_peer(struct dp_peer *peer) 2090 { 2091 return IS_MLO_DP_LINK_PEER(peer) ? peer->mld_peer : peer; 2092 } 2093 2094 /** 2095 * dp_get_primary_link_peer_by_id(): Get primary link peer from the given 2096 * peer id 2097 * @soc: core DP soc context 2098 * @peer_id: peer id 2099 * @mod_id: ID of module requesting reference 2100 * 2101 * Return: primary link peer for the MLO peer 2102 * legacy peer itself in case of legacy peer 2103 */ 2104 static inline 2105 struct dp_peer *dp_get_primary_link_peer_by_id(struct dp_soc *soc, 2106 uint16_t peer_id, 2107 enum dp_mod_id mod_id) 2108 { 2109 uint8_t i; 2110 struct dp_mld_link_peers link_peers_info; 2111 struct dp_peer *peer; 2112 struct dp_peer *link_peer; 2113 struct dp_peer *primary_peer = NULL; 2114 2115 peer = dp_peer_get_ref_by_id(soc, peer_id, mod_id); 2116 2117 if (!peer) 2118 return NULL; 2119 2120 if (IS_MLO_DP_MLD_PEER(peer)) { 2121 /* get link peers with reference */ 2122 dp_get_link_peers_ref_from_mld_peer(soc, peer, &link_peers_info, 2123 mod_id); 2124 2125 for (i = 0; i < link_peers_info.num_links; i++) { 2126 link_peer = link_peers_info.link_peers[i]; 2127 if (link_peer->primary_link) { 2128 /* 2129 * Take additional reference over 2130 * primary link peer. 2131 */ 2132 if (QDF_STATUS_SUCCESS == 2133 dp_peer_get_ref(NULL, link_peer, mod_id)) 2134 primary_peer = link_peer; 2135 break; 2136 } 2137 } 2138 /* release link peers reference */ 2139 dp_release_link_peers_ref(&link_peers_info, mod_id); 2140 dp_peer_unref_delete(peer, mod_id); 2141 } else { 2142 primary_peer = peer; 2143 } 2144 2145 return primary_peer; 2146 } 2147 2148 /** 2149 * dp_get_txrx_peer() - Get dp_txrx_peer from passed dp_peer 2150 * @peer: Datapath peer 2151 * 2152 * Return: dp_txrx_peer from MLD peer if peer type is link peer 2153 * dp_txrx_peer from peer itself for other cases 2154 */ 2155 static inline 2156 struct dp_txrx_peer *dp_get_txrx_peer(struct dp_peer *peer) 2157 { 2158 return IS_MLO_DP_LINK_PEER(peer) ? 2159 peer->mld_peer->txrx_peer : peer->txrx_peer; 2160 } 2161 2162 /** 2163 * dp_peer_is_primary_link_peer() - Check if peer is primary link peer 2164 * @peer: Datapath peer 2165 * 2166 * Return: true if peer is primary link peer or legacy peer 2167 * false otherwise 2168 */ 2169 static inline 2170 bool dp_peer_is_primary_link_peer(struct dp_peer *peer) 2171 { 2172 if (IS_MLO_DP_LINK_PEER(peer) && peer->primary_link) 2173 return true; 2174 else if (IS_DP_LEGACY_PEER(peer)) 2175 return true; 2176 else 2177 return false; 2178 } 2179 2180 /** 2181 * dp_tgt_txrx_peer_get_ref_by_id() - Gets tgt txrx peer for given the peer id 2182 * 2183 * @soc: core DP soc context 2184 * @peer_id: peer id from peer object can be retrieved 2185 * @handle: reference handle 2186 * @mod_id: ID of module requesting reference 2187 * 2188 * Return: struct dp_txrx_peer*: Pointer to txrx DP peer object 2189 */ 2190 static inline struct dp_txrx_peer * 2191 dp_tgt_txrx_peer_get_ref_by_id(struct dp_soc *soc, 2192 uint16_t peer_id, 2193 dp_txrx_ref_handle *handle, 2194 enum dp_mod_id mod_id) 2195 2196 { 2197 struct dp_peer *peer; 2198 struct dp_txrx_peer *txrx_peer; 2199 2200 peer = dp_peer_get_ref_by_id(soc, peer_id, mod_id); 2201 if (!peer) 2202 return NULL; 2203 2204 txrx_peer = dp_get_txrx_peer(peer); 2205 if (txrx_peer) { 2206 *handle = (dp_txrx_ref_handle)peer; 2207 return txrx_peer; 2208 } 2209 2210 dp_peer_unref_delete(peer, mod_id); 2211 return NULL; 2212 } 2213 2214 /** 2215 * dp_print_mlo_ast_stats_be() - Print AST stats for MLO peers 2216 * 2217 * @soc: core DP soc context 2218 * 2219 * Return: void 2220 */ 2221 void dp_print_mlo_ast_stats_be(struct dp_soc *soc); 2222 2223 /** 2224 * dp_get_peer_link_id() - Get Link peer Link ID 2225 * @peer: Datapath peer 2226 * 2227 * Return: Link peer Link ID 2228 */ 2229 uint8_t dp_get_peer_link_id(struct dp_peer *peer); 2230 #else 2231 2232 #define IS_MLO_DP_MLD_TXRX_PEER(_peer) false 2233 2234 #define DP_PEER_SET_TYPE(_peer, _type_val) /* no op */ 2235 /* is legacy peer */ 2236 #define IS_DP_LEGACY_PEER(_peer) true 2237 #define IS_MLO_DP_LINK_PEER(_peer) false 2238 #define IS_MLO_DP_MLD_PEER(_peer) false 2239 #define DP_GET_MLD_PEER_FROM_PEER(link_peer) NULL 2240 2241 static inline 2242 struct dp_peer *dp_peer_hash_find_wrapper(struct dp_soc *soc, 2243 struct cdp_peer_info *peer_info, 2244 enum dp_mod_id mod_id) 2245 { 2246 return dp_peer_find_hash_find(soc, peer_info->mac_addr, 2247 peer_info->mac_addr_is_aligned, 2248 peer_info->vdev_id, 2249 mod_id); 2250 } 2251 2252 static inline 2253 struct dp_peer *dp_peer_get_tgt_peer_hash_find(struct dp_soc *soc, 2254 uint8_t *peer_mac, 2255 int mac_addr_is_aligned, 2256 uint8_t vdev_id, 2257 enum dp_mod_id mod_id) 2258 { 2259 return dp_peer_find_hash_find(soc, peer_mac, 2260 mac_addr_is_aligned, vdev_id, 2261 mod_id); 2262 } 2263 2264 static inline 2265 struct dp_peer *dp_peer_get_tgt_peer_by_id(struct dp_soc *soc, 2266 uint16_t peer_id, 2267 enum dp_mod_id mod_id) 2268 { 2269 return dp_peer_get_ref_by_id(soc, peer_id, mod_id); 2270 } 2271 2272 static inline 2273 QDF_STATUS dp_peer_mlo_setup( 2274 struct dp_soc *soc, 2275 struct dp_peer *peer, 2276 uint8_t vdev_id, 2277 struct cdp_peer_setup_info *setup_info) 2278 { 2279 return QDF_STATUS_SUCCESS; 2280 } 2281 2282 static inline 2283 void dp_mld_peer_init_link_peers_info(struct dp_peer *mld_peer) 2284 { 2285 } 2286 2287 static inline 2288 void dp_mld_peer_deinit_link_peers_info(struct dp_peer *mld_peer) 2289 { 2290 } 2291 2292 static inline 2293 void dp_link_peer_del_mld_peer(struct dp_peer *link_peer) 2294 { 2295 } 2296 2297 static inline 2298 void dp_peer_mlo_delete(struct dp_peer *peer) 2299 { 2300 } 2301 2302 static inline 2303 void dp_mlo_peer_authorize(struct dp_soc *soc, 2304 struct dp_peer *link_peer) 2305 { 2306 } 2307 2308 static inline uint8_t dp_get_chip_id(struct dp_soc *soc) 2309 { 2310 return 0; 2311 } 2312 2313 static inline struct dp_peer * 2314 dp_link_peer_hash_find_by_chip_id(struct dp_soc *soc, 2315 uint8_t *peer_mac_addr, 2316 int mac_addr_is_aligned, 2317 uint8_t vdev_id, 2318 uint8_t chip_id, 2319 enum dp_mod_id mod_id) 2320 { 2321 return dp_peer_find_hash_find(soc, peer_mac_addr, 2322 mac_addr_is_aligned, 2323 vdev_id, mod_id); 2324 } 2325 2326 static inline 2327 struct dp_peer *dp_get_tgt_peer_from_peer(struct dp_peer *peer) 2328 { 2329 return peer; 2330 } 2331 2332 static inline 2333 struct dp_peer *dp_get_primary_link_peer_by_id(struct dp_soc *soc, 2334 uint16_t peer_id, 2335 enum dp_mod_id mod_id) 2336 { 2337 return dp_peer_get_ref_by_id(soc, peer_id, mod_id); 2338 } 2339 2340 static inline 2341 struct dp_txrx_peer *dp_get_txrx_peer(struct dp_peer *peer) 2342 { 2343 return peer->txrx_peer; 2344 } 2345 2346 static inline 2347 bool dp_peer_is_primary_link_peer(struct dp_peer *peer) 2348 { 2349 return true; 2350 } 2351 2352 /** 2353 * dp_tgt_txrx_peer_get_ref_by_id() - Gets tgt txrx peer for given the peer id 2354 * 2355 * @soc: core DP soc context 2356 * @peer_id: peer id from peer object can be retrieved 2357 * @handle: reference handle 2358 * @mod_id: ID of module requesting reference 2359 * 2360 * Return: struct dp_txrx_peer*: Pointer to txrx DP peer object 2361 */ 2362 static inline struct dp_txrx_peer * 2363 dp_tgt_txrx_peer_get_ref_by_id(struct dp_soc *soc, 2364 uint16_t peer_id, 2365 dp_txrx_ref_handle *handle, 2366 enum dp_mod_id mod_id) 2367 2368 { 2369 return dp_txrx_peer_get_ref_by_id(soc, peer_id, handle, mod_id); 2370 } 2371 2372 static inline 2373 uint16_t dp_get_link_peer_id_by_lmac_id(struct dp_soc *soc, uint16_t peer_id, 2374 uint8_t lmac_id) 2375 { 2376 return peer_id; 2377 } 2378 2379 static inline void dp_print_mlo_ast_stats_be(struct dp_soc *soc) 2380 { 2381 } 2382 2383 static inline uint8_t dp_get_peer_link_id(struct dp_peer *peer) 2384 { 2385 return 0; 2386 } 2387 #endif /* WLAN_FEATURE_11BE_MLO */ 2388 2389 static inline 2390 void dp_peer_defrag_rx_tids_init(struct dp_txrx_peer *txrx_peer) 2391 { 2392 uint8_t i; 2393 2394 qdf_mem_zero(&txrx_peer->rx_tid, DP_MAX_TIDS * 2395 sizeof(struct dp_rx_tid_defrag)); 2396 2397 for (i = 0; i < DP_MAX_TIDS; i++) 2398 qdf_spinlock_create(&txrx_peer->rx_tid[i].defrag_tid_lock); 2399 } 2400 2401 static inline 2402 void dp_peer_defrag_rx_tids_deinit(struct dp_txrx_peer *txrx_peer) 2403 { 2404 uint8_t i; 2405 2406 for (i = 0; i < DP_MAX_TIDS; i++) 2407 qdf_spinlock_destroy(&txrx_peer->rx_tid[i].defrag_tid_lock); 2408 } 2409 2410 #ifdef PEER_CACHE_RX_PKTS 2411 static inline 2412 void dp_peer_rx_bufq_resources_init(struct dp_txrx_peer *txrx_peer) 2413 { 2414 qdf_spinlock_create(&txrx_peer->bufq_info.bufq_lock); 2415 txrx_peer->bufq_info.thresh = DP_RX_CACHED_BUFQ_THRESH; 2416 qdf_list_create(&txrx_peer->bufq_info.cached_bufq, 2417 DP_RX_CACHED_BUFQ_THRESH); 2418 } 2419 2420 static inline 2421 void dp_peer_rx_bufq_resources_deinit(struct dp_txrx_peer *txrx_peer) 2422 { 2423 qdf_list_destroy(&txrx_peer->bufq_info.cached_bufq); 2424 qdf_spinlock_destroy(&txrx_peer->bufq_info.bufq_lock); 2425 } 2426 2427 #else 2428 static inline 2429 void dp_peer_rx_bufq_resources_init(struct dp_txrx_peer *txrx_peer) 2430 { 2431 } 2432 2433 static inline 2434 void dp_peer_rx_bufq_resources_deinit(struct dp_txrx_peer *txrx_peer) 2435 { 2436 } 2437 #endif 2438 2439 /** 2440 * dp_peer_update_state() - update dp peer state 2441 * 2442 * @soc: core DP soc context 2443 * @peer: DP peer 2444 * @state: new state 2445 * 2446 * Return: None 2447 */ 2448 static inline void 2449 dp_peer_update_state(struct dp_soc *soc, 2450 struct dp_peer *peer, 2451 enum dp_peer_state state) 2452 { 2453 uint8_t peer_state; 2454 2455 qdf_spin_lock_bh(&peer->peer_state_lock); 2456 peer_state = peer->peer_state; 2457 2458 switch (state) { 2459 case DP_PEER_STATE_INIT: 2460 DP_PEER_STATE_ASSERT 2461 (peer, state, (peer_state != DP_PEER_STATE_ACTIVE) && 2462 (peer_state != DP_PEER_STATE_LOGICAL_DELETE)); 2463 break; 2464 2465 case DP_PEER_STATE_ACTIVE: 2466 DP_PEER_STATE_ASSERT(peer, state, 2467 (peer_state == DP_PEER_STATE_INIT)); 2468 break; 2469 2470 case DP_PEER_STATE_LOGICAL_DELETE: 2471 DP_PEER_STATE_ASSERT(peer, state, 2472 (peer_state == DP_PEER_STATE_ACTIVE) || 2473 (peer_state == DP_PEER_STATE_INIT)); 2474 break; 2475 2476 case DP_PEER_STATE_INACTIVE: 2477 if (IS_MLO_DP_MLD_PEER(peer)) 2478 DP_PEER_STATE_ASSERT 2479 (peer, state, 2480 (peer_state == DP_PEER_STATE_ACTIVE)); 2481 else 2482 DP_PEER_STATE_ASSERT 2483 (peer, state, 2484 (peer_state == DP_PEER_STATE_LOGICAL_DELETE)); 2485 break; 2486 2487 case DP_PEER_STATE_FREED: 2488 if (peer->sta_self_peer) 2489 DP_PEER_STATE_ASSERT 2490 (peer, state, (peer_state == DP_PEER_STATE_INIT)); 2491 else 2492 DP_PEER_STATE_ASSERT 2493 (peer, state, 2494 (peer_state == DP_PEER_STATE_INACTIVE) || 2495 (peer_state == DP_PEER_STATE_LOGICAL_DELETE)); 2496 break; 2497 2498 default: 2499 qdf_spin_unlock_bh(&peer->peer_state_lock); 2500 dp_alert("Invalid peer state %u for peer " QDF_MAC_ADDR_FMT, 2501 state, QDF_MAC_ADDR_REF(peer->mac_addr.raw)); 2502 return; 2503 } 2504 peer->peer_state = state; 2505 qdf_spin_unlock_bh(&peer->peer_state_lock); 2506 dp_info("Updating peer state from %u to %u mac " QDF_MAC_ADDR_FMT "\n", 2507 peer_state, state, 2508 QDF_MAC_ADDR_REF(peer->mac_addr.raw)); 2509 } 2510 2511 /** 2512 * dp_vdev_iterate_specific_peer_type() - API to iterate through vdev peer 2513 * list based on type of peer (Legacy or MLD peer) 2514 * 2515 * @vdev: DP vdev context 2516 * @func: function to be called for each peer 2517 * @arg: argument need to be passed to func 2518 * @mod_id: module_id 2519 * @peer_type: type of peer - MLO Link Peer or Legacy Peer 2520 * 2521 * Return: void 2522 */ 2523 static inline void 2524 dp_vdev_iterate_specific_peer_type(struct dp_vdev *vdev, 2525 dp_peer_iter_func *func, 2526 void *arg, enum dp_mod_id mod_id, 2527 enum dp_peer_type peer_type) 2528 { 2529 struct dp_peer *peer; 2530 struct dp_peer *tmp_peer; 2531 struct dp_soc *soc = NULL; 2532 2533 if (!vdev || !vdev->pdev || !vdev->pdev->soc) 2534 return; 2535 2536 soc = vdev->pdev->soc; 2537 2538 qdf_spin_lock_bh(&vdev->peer_list_lock); 2539 TAILQ_FOREACH_SAFE(peer, &vdev->peer_list, 2540 peer_list_elem, 2541 tmp_peer) { 2542 if (dp_peer_get_ref(soc, peer, mod_id) == 2543 QDF_STATUS_SUCCESS) { 2544 if ((peer_type == DP_PEER_TYPE_LEGACY && 2545 (IS_DP_LEGACY_PEER(peer))) || 2546 (peer_type == DP_PEER_TYPE_MLO_LINK && 2547 (IS_MLO_DP_LINK_PEER(peer)))) { 2548 (*func)(soc, peer, arg); 2549 } 2550 dp_peer_unref_delete(peer, mod_id); 2551 } 2552 } 2553 qdf_spin_unlock_bh(&vdev->peer_list_lock); 2554 } 2555 2556 #ifdef REO_SHARED_QREF_TABLE_EN 2557 void dp_peer_rx_reo_shared_qaddr_delete(struct dp_soc *soc, 2558 struct dp_peer *peer); 2559 #else 2560 static inline void dp_peer_rx_reo_shared_qaddr_delete(struct dp_soc *soc, 2561 struct dp_peer *peer) {} 2562 #endif 2563 2564 /** 2565 * dp_peer_check_wds_ext_peer() - Check WDS ext peer 2566 * 2567 * @peer: DP peer 2568 * 2569 * Return: True for WDS ext peer, false otherwise 2570 */ 2571 bool dp_peer_check_wds_ext_peer(struct dp_peer *peer); 2572 2573 /** 2574 * dp_gen_ml_peer_id() - Generate MLD peer id for DP 2575 * 2576 * @soc: DP soc context 2577 * @peer_id: mld peer id 2578 * 2579 * Return: DP MLD peer id 2580 */ 2581 uint16_t dp_gen_ml_peer_id(struct dp_soc *soc, uint16_t peer_id); 2582 2583 #ifdef FEATURE_AST 2584 /** 2585 * dp_peer_host_add_map_ast() - Add ast entry with HW AST Index 2586 * @soc: SoC handle 2587 * @peer_id: peer id from firmware 2588 * @mac_addr: MAC address of ast node 2589 * @hw_peer_id: HW AST Index returned by target in peer map event 2590 * @vdev_id: vdev id for VAP to which the peer belongs to 2591 * @ast_hash: ast hash value in HW 2592 * @is_wds: flag to indicate peer map event for WDS ast entry 2593 * 2594 * Return: QDF_STATUS code 2595 */ 2596 QDF_STATUS dp_peer_host_add_map_ast(struct dp_soc *soc, uint16_t peer_id, 2597 uint8_t *mac_addr, uint16_t hw_peer_id, 2598 uint8_t vdev_id, uint16_t ast_hash, 2599 uint8_t is_wds); 2600 #endif 2601 2602 #if defined(WLAN_FEATURE_11BE_MLO) && defined(DP_MLO_LINK_STATS_SUPPORT) 2603 /** 2604 * dp_map_link_id_band: Set link id to band mapping in txrx_peer 2605 * @peer: dp peer pointer 2606 * 2607 * Return: None 2608 */ 2609 void dp_map_link_id_band(struct dp_peer *peer); 2610 #else 2611 static inline 2612 void dp_map_link_id_band(struct dp_peer *peer) 2613 { 2614 } 2615 #endif 2616 #endif /* _DP_PEER_H_ */ 2617