1 /* 2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: cdp_txrx_peer_ops.h 22 * Define the host data path peer API functions 23 * called by the host control SW and the OS interface module 24 */ 25 #ifndef _CDP_TXRX_PEER_H_ 26 #define _CDP_TXRX_PEER_H_ 27 #include <cdp_txrx_ops.h> 28 #include "cdp_txrx_handle.h" 29 30 /** 31 * cdp_peer_register() - Register peer into physical device 32 * @soc: data path soc handle 33 * @pdev_id: data path device instance id 34 * @sta_desc: peer description 35 * 36 * Register peer into physical device 37 * 38 * Return: QDF_STATUS_SUCCESS registration success 39 * QDF_STATUS_E_NOSUPPORT not support this feature 40 */ 41 static inline QDF_STATUS 42 cdp_peer_register(ol_txrx_soc_handle soc, uint8_t pdev_id, 43 struct ol_txrx_desc_type *sta_desc) 44 { 45 if (!soc || !soc->ops || !soc->ops->peer_ops) { 46 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 47 "%s invalid instance", __func__); 48 return QDF_STATUS_E_INVAL; 49 } 50 51 if (soc->ops->peer_ops->register_peer) 52 return soc->ops->peer_ops->register_peer(soc, pdev_id, 53 sta_desc); 54 55 return QDF_STATUS_E_NOSUPPORT; 56 } 57 58 /** 59 * cdp_clear_peer() - remove peer from physical device 60 * @soc: data path soc handle 61 * @pdev_id: data path device instance id 62 * @peer_addr: peer mac address 63 * 64 * remove peer from physical device 65 * 66 * Return: QDF_STATUS_SUCCESS registration success 67 * QDF_STATUS_E_NOSUPPORT not support this feature 68 */ 69 static inline QDF_STATUS 70 cdp_clear_peer(ol_txrx_soc_handle soc, uint8_t pdev_id, 71 struct qdf_mac_addr peer_addr) 72 { 73 if (!soc || !soc->ops || !soc->ops->peer_ops) { 74 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 75 "%s invalid instance", __func__); 76 return QDF_STATUS_E_INVAL; 77 } 78 79 if (soc->ops->peer_ops->clear_peer) 80 return soc->ops->peer_ops->clear_peer(soc, pdev_id, peer_addr); 81 82 return QDF_STATUS_E_NOSUPPORT; 83 } 84 85 /** 86 * cdp_peer_register_ocb_peer() - register ocb peer from physical device 87 * @soc: data path soc handle 88 * @mac_addr: mac address for ocb self peer 89 * 90 * register ocb peer from physical device 91 * 92 * Return: QDF_STATUS_SUCCESS registration success 93 * QDF_STATUS_E_NOSUPPORT not support this feature 94 */ 95 static inline QDF_STATUS 96 cdp_peer_register_ocb_peer(ol_txrx_soc_handle soc, 97 uint8_t *mac_addr) 98 { 99 if (!soc || !soc->ops || !soc->ops->peer_ops) { 100 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 101 "%s invalid instance", __func__); 102 return QDF_STATUS_E_INVAL; 103 } 104 105 if (soc->ops->peer_ops->register_ocb_peer) 106 return soc->ops->peer_ops->register_ocb_peer(mac_addr); 107 108 return QDF_STATUS_E_NOSUPPORT; 109 } 110 111 /** 112 * cdp_find_peer_exist - Find if peer already exists 113 * @soc: data path soc handle 114 * @pdev_id: data path device instance id 115 * @peer_addr: peer mac address 116 * 117 * Return: true or false 118 */ 119 static inline bool 120 cdp_find_peer_exist(ol_txrx_soc_handle soc, uint8_t pdev_id, 121 uint8_t *peer_addr) 122 { 123 if (!soc || !soc->ops || !soc->ops->peer_ops) { 124 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 125 "%s invalid instance", __func__); 126 return false; 127 } 128 129 if (soc->ops->peer_ops->find_peer_exist) 130 return soc->ops->peer_ops->find_peer_exist(soc, pdev_id, 131 peer_addr); 132 133 return false; 134 } 135 136 /** 137 * cdp_find_peer_exist_on_vdev - Find if duplicate peer exists 138 * on the given vdev 139 * @soc: data path soc handle 140 * @vdev_id: data path virtual interface id 141 * @peer_addr: peer mac address 142 * 143 * Return: true or false 144 */ 145 static inline bool 146 cdp_find_peer_exist_on_vdev(ol_txrx_soc_handle soc, uint8_t vdev_id, 147 uint8_t *peer_addr) 148 { 149 if (!soc || !soc->ops || !soc->ops->peer_ops) { 150 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 151 "%s invalid instance", __func__); 152 return false; 153 } 154 155 if (soc->ops->peer_ops->find_peer_exist_on_vdev) 156 return soc->ops->peer_ops->find_peer_exist_on_vdev(soc, vdev_id, 157 peer_addr); 158 159 return false; 160 } 161 162 /** 163 * cdp_find_peer_exist_on_other_vdev - Find if duplicate peer exists 164 * on other than the given vdev 165 * @soc: data path soc handle 166 * @vdev_id: data path virtual interface id 167 * @peer_addr: peer mac address 168 * @max_bssid: max number of bssids 169 * 170 * Return: true or false 171 */ 172 static inline bool 173 cdp_find_peer_exist_on_other_vdev(ol_txrx_soc_handle soc, uint8_t vdev_id, 174 uint8_t *peer_addr, uint16_t max_bssid) 175 { 176 if (!soc || !soc->ops || !soc->ops->peer_ops) { 177 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 178 "%s invalid instance", __func__); 179 return false; 180 } 181 182 if (soc->ops->peer_ops->find_peer_exist_on_other_vdev) 183 return soc->ops->peer_ops->find_peer_exist_on_other_vdev( 184 soc, vdev_id, 185 peer_addr, 186 max_bssid); 187 188 return false; 189 } 190 191 /** 192 * cdp_peer_state_update() - update peer local state 193 * @soc: data path soc handle 194 * @peer_addr: peer mac address 195 * @state: new peer local state 196 * 197 * update peer local state 198 * 199 * Return: QDF_STATUS_SUCCESS registration success 200 * QDF_STATUS_E_NOSUPPORT not support this feature 201 */ 202 static inline QDF_STATUS 203 cdp_peer_state_update(ol_txrx_soc_handle soc, uint8_t *peer_addr, 204 enum ol_txrx_peer_state state) 205 { 206 if (!soc || !soc->ops || !soc->ops->peer_ops) { 207 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 208 "%s invalid instance", __func__); 209 return QDF_STATUS_E_INVAL; 210 } 211 212 if (soc->ops->peer_ops->peer_state_update) 213 return soc->ops->peer_ops->peer_state_update(soc, peer_addr, 214 state); 215 216 return QDF_STATUS_E_NOSUPPORT; 217 } 218 219 /** 220 * cdp_peer_state_get() - Get local peer state 221 * @soc: data path soc handle 222 * @vdev_id: virtual interface id 223 * @peer_mac: peer mac addr 224 * 225 * Get local peer state 226 * 227 * Return: peer status 228 */ 229 static inline int 230 cdp_peer_state_get(ol_txrx_soc_handle soc, uint8_t vdev_id, uint8_t *peer_mac) 231 { 232 if (!soc || !soc->ops || !soc->ops->peer_ops) { 233 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 234 "%s invalid instance", __func__); 235 return 0; 236 } 237 238 if (soc->ops->peer_ops->get_peer_state) 239 return soc->ops->peer_ops->get_peer_state(soc, vdev_id, 240 peer_mac); 241 242 return 0; 243 } 244 245 /** 246 * cdp_peer_get_vdevid() - Get virtual interface id which peer registered 247 * @soc: data path soc handle 248 * @peer_mac: peer mac address 249 * @vdev_id: virtual interface id which peer registered 250 * 251 * Get virtual interface id which peer registered 252 * 253 * Return: QDF_STATUS_SUCCESS registration success 254 * QDF_STATUS_E_NOSUPPORT not support this feature 255 */ 256 static inline QDF_STATUS 257 cdp_peer_get_vdevid(ol_txrx_soc_handle soc, 258 uint8_t *peer_mac, uint8_t *vdev_id) 259 { 260 if (!soc || !soc->ops || !soc->ops->peer_ops) { 261 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 262 "%s invalid instance", __func__); 263 return QDF_STATUS_E_INVAL; 264 } 265 266 if (soc->ops->peer_ops->get_vdevid) 267 return soc->ops->peer_ops->get_vdevid(soc, peer_mac, vdev_id); 268 269 return QDF_STATUS_E_NOSUPPORT; 270 } 271 272 /** 273 * cdp_peer_get_vdev_by_peer_addr() - Get vdev instance by local peer address 274 * @soc: data path soc handle 275 * @pdev: data path device instance 276 * @peer_addr: peer mac address 277 * 278 * Get virtual interface id by local peer id 279 * 280 * Return: Virtual interface instance 281 * NULL in case cannot find 282 */ 283 static inline struct cdp_vdev 284 *cdp_peer_get_vdev_by_peer_addr(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, 285 struct qdf_mac_addr peer_addr) 286 { 287 if (!soc || !soc->ops || !soc->ops->peer_ops) { 288 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 289 "%s invalid instance", __func__); 290 return NULL; 291 } 292 293 if (soc->ops->peer_ops->get_vdev_by_peer_addr) 294 return soc->ops->peer_ops->get_vdev_by_peer_addr(pdev, 295 peer_addr); 296 297 return NULL; 298 } 299 300 /** 301 * cdp_peer_get_peer_mac_addr() - Get peer mac address 302 * @soc: data path soc handle 303 * @peer: peer instance 304 * 305 * Get peer mac address 306 * 307 * Return: peer mac address pointer 308 * NULL in case cannot find 309 */ 310 static inline uint8_t 311 *cdp_peer_get_peer_mac_addr(ol_txrx_soc_handle soc, void *peer) 312 { 313 if (!soc || !soc->ops || !soc->ops->peer_ops) { 314 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 315 "%s invalid instance", __func__); 316 return NULL; 317 } 318 319 if (soc->ops->peer_ops->peer_get_peer_mac_addr) 320 return soc->ops->peer_ops->peer_get_peer_mac_addr(peer); 321 322 return NULL; 323 } 324 325 /** 326 * cdp_peer_update_ibss_add_peer_num_of_vdev() - update number of peer 327 * @soc: data path soc handle 328 * @vdev_id: virtual interface instance id 329 * @peer_num_delta: number of peer should be updated 330 * 331 * update number of peer 332 * 333 * Return: updated number of peer 334 * 0 fail 335 */ 336 static inline int16_t 337 cdp_peer_update_ibss_add_peer_num_of_vdev(ol_txrx_soc_handle soc, 338 uint8_t vdev_id, 339 int16_t peer_num_delta) 340 { 341 if (!soc || !soc->ops || !soc->ops->peer_ops) { 342 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 343 "%s invalid instance", __func__); 344 return 0; 345 } 346 347 if (soc->ops->peer_ops->update_ibss_add_peer_num_of_vdev) 348 return soc->ops->peer_ops->update_ibss_add_peer_num_of_vdev( 349 soc, vdev_id, 350 peer_num_delta); 351 352 return 0; 353 } 354 355 /** 356 * cdp_peer_copy_mac_addr_raw() - copy peer mac address 357 * @soc: data path soc handle 358 * @vdev_id: virtual interface instance id 359 * @bss_addr: mac address should be copied 360 * 361 * copy peer mac address 362 * 363 * Return: none 364 */ 365 static inline void 366 cdp_peer_copy_mac_addr_raw(ol_txrx_soc_handle soc, 367 uint8_t vdev_id, uint8_t *bss_addr) 368 { 369 if (!soc || !soc->ops || !soc->ops->peer_ops) { 370 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 371 "%s invalid instance", __func__); 372 return; 373 } 374 375 if (soc->ops->peer_ops->copy_mac_addr_raw) 376 return soc->ops->peer_ops->copy_mac_addr_raw(soc, vdev_id, 377 bss_addr); 378 379 return; 380 } 381 382 /** 383 * cdp_peer_add_last_real_peer() - Add peer with last peer marking 384 * @soc: data path soc handle 385 * @pdev_id: data path device instance id 386 * @vdev_id: virtual interface instance id 387 * 388 * copy peer mac address 389 * 390 * Return: none 391 */ 392 static inline void 393 cdp_peer_add_last_real_peer(ol_txrx_soc_handle soc, uint8_t pdev_id, 394 uint8_t vdev_id) 395 { 396 if (!soc || !soc->ops || !soc->ops->peer_ops) { 397 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 398 "%s invalid instance", __func__); 399 return; 400 } 401 402 if (soc->ops->peer_ops->add_last_real_peer) 403 return soc->ops->peer_ops->add_last_real_peer(soc, pdev_id, 404 vdev_id); 405 return; 406 } 407 408 /** 409 * cdp_peer_is_vdev_restore_last_peer() - restore last peer 410 * @soc: data path soc handle 411 * @vdev_id: virtual interface id 412 * @peer_mac: peer mac address 413 * 414 * restore last peer 415 * 416 * Return: true, restore success 417 * fasle, restore fail 418 */ 419 static inline bool 420 cdp_peer_is_vdev_restore_last_peer(ol_txrx_soc_handle soc, uint8_t vdev_id, 421 uint8_t *peer_mac) 422 { 423 if (!soc || !soc->ops || !soc->ops->peer_ops) { 424 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 425 "%s invalid instance", __func__); 426 return false; 427 } 428 429 if (soc->ops->peer_ops->is_vdev_restore_last_peer) 430 return soc->ops->peer_ops->is_vdev_restore_last_peer(soc, 431 vdev_id, 432 peer_mac); 433 434 return false; 435 } 436 437 /** 438 * cdp_peer_update_last_real_peer() - update last real peer 439 * @soc: data path soc handle 440 * @pdev_id: data path device instance id 441 * @vdev_id: virtual interface id 442 * @restore_last_peer: restore last peer or not 443 * 444 * update last real peer 445 * 446 * Return: none 447 */ 448 static inline void 449 cdp_peer_update_last_real_peer(ol_txrx_soc_handle soc, uint8_t pdev_id, 450 uint8_t vdev_id, bool restore_last_peer) 451 { 452 if (!soc || !soc->ops || !soc->ops->peer_ops) { 453 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 454 "%s invalid instance", __func__); 455 return; 456 } 457 458 if (soc->ops->peer_ops->update_last_real_peer) 459 return soc->ops->peer_ops->update_last_real_peer( 460 soc, pdev_id, vdev_id, 461 restore_last_peer); 462 463 return; 464 } 465 466 /** 467 * cdp_peer_detach_force_delete() - Detach and delete a peer's data object 468 * @soc: data path soc handle 469 * @vdev_id: data path virtual interface id 470 * @peer_mac: peer mac address 471 * 472 * Detach a peer and force the peer object to be removed. It is called during 473 * roaming scenario when the firmware has already deleted a peer. 474 * Peer object is freed immediately to avoid duplicate peers during roam sync 475 * indication processing. 476 * 477 * Return: None 478 */ 479 static inline void cdp_peer_detach_force_delete(ol_txrx_soc_handle soc, 480 uint8_t vdev_id, 481 uint8_t *peer_mac) 482 { 483 if (!soc || !soc->ops || !soc->ops->peer_ops) { 484 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 485 "%s invalid instance", __func__); 486 return; 487 } 488 489 if (soc->ops->peer_ops->peer_detach_force_delete) 490 return soc->ops->peer_ops->peer_detach_force_delete(soc, 491 vdev_id, 492 peer_mac); 493 494 return; 495 } 496 497 /** 498 * is_cdp_peer_detach_force_delete_supported() - To check if force delete 499 * operation is supported 500 * @soc: pointer to SOC handle 501 * 502 * Some of the platforms support force delete operation and some of them 503 * don't. This API returns true if API which handles force delete operation 504 * is registered and false otherwise. 505 * 506 * Return: true if API which handles force delete operation is registered 507 * false in all other cases 508 */ 509 static inline bool 510 is_cdp_peer_detach_force_delete_supported(ol_txrx_soc_handle soc) 511 { 512 if (!soc || !soc->ops || !soc->ops->peer_ops) { 513 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 514 "%s invalid instance", __func__); 515 return false; 516 } 517 518 if (soc->ops->peer_ops->peer_detach_force_delete) 519 return true; 520 521 return false; 522 } 523 524 /** 525 * cdp_peer_set_peer_as_tdls() - To set peer as tdls peer 526 * @soc: pointer to SOC handle 527 * @vdev_id: virtual interface id 528 * @peer_mac: peer mac address 529 * @val: true or false 530 * 531 * Return: void 532 */ 533 static inline void 534 cdp_peer_set_peer_as_tdls(ol_txrx_soc_handle soc, uint8_t vdev_id, 535 uint8_t *peer_mac, bool val) 536 { 537 if (!soc || !soc->ops || !soc->ops->peer_ops) { 538 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 539 "%s invalid instance", __func__); 540 return; 541 } 542 543 if (soc->ops->peer_ops->set_peer_as_tdls_peer) 544 soc->ops->peer_ops->set_peer_as_tdls_peer(soc, vdev_id, 545 peer_mac, val); 546 } 547 548 /** 549 * cdp_peer_set_tdls_offchan_enabled() - Set tdls offchan operation as enabled 550 * @soc: pointer to SOC handle 551 * @vdev_id: virtual interface id 552 * @peer_mac: peer mac address 553 * @val: true or false 554 * 555 * update tdls_offchan_enabled 556 * 557 * Return: none 558 */ 559 static inline void 560 cdp_peer_set_tdls_offchan_enabled(ol_txrx_soc_handle soc, uint8_t vdev_id, 561 uint8_t *peer_mac, bool val) 562 { 563 if (!soc || !soc->ops || !soc->ops->peer_ops) { 564 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 565 "%s invalid instance", __func__); 566 return; 567 } 568 569 if (soc->ops->peer_ops->set_tdls_offchan_enabled) 570 soc->ops->peer_ops->set_tdls_offchan_enabled(soc, vdev_id, 571 peer_mac, val); 572 } 573 574 /** 575 * cdp_peer_flush_frags() - Flush frags on peer 576 * @soc: data path soc handle 577 * @vdev_id: virtual interface id 578 * @peer_mac: peer mac addr 579 * 580 * Return: None 581 */ 582 static inline void 583 cdp_peer_flush_frags(ol_txrx_soc_handle soc, uint8_t vdev_id, uint8_t *peer_mac) 584 { 585 if (!soc || !soc->ops || !soc->ops->peer_ops) { 586 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 587 "%s invalid instance", __func__); 588 return; 589 } 590 591 if (soc->ops->peer_ops->peer_flush_frags) 592 soc->ops->peer_ops->peer_flush_frags(soc, vdev_id, peer_mac); 593 } 594 #endif /* _CDP_TXRX_PEER_H_ */ 595