1 /* 2 * Copyright (c) 2016-2021 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 * @file cdp_txrx_peer.h 21 * @brief Define the host data path peer API functions 22 * called by the host control SW and the OS interface module 23 */ 24 #ifndef _CDP_TXRX_PEER_H_ 25 #define _CDP_TXRX_PEER_H_ 26 #include <cdp_txrx_ops.h> 27 #include "cdp_txrx_handle.h" 28 29 /** 30 * cdp_peer_register() - Register peer into physical device 31 * @soc - data path soc handle 32 * @pdev_id - data path device instance id 33 * @sta_desc - peer description 34 * 35 * Register peer into physical device 36 * 37 * Return: QDF_STATUS_SUCCESS registration success 38 * QDF_STATUS_E_NOSUPPORT not support this feature 39 */ 40 static inline QDF_STATUS 41 cdp_peer_register(ol_txrx_soc_handle soc, uint8_t pdev_id, 42 struct ol_txrx_desc_type *sta_desc) 43 { 44 if (!soc || !soc->ops || !soc->ops->peer_ops) { 45 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 46 "%s invalid instance", __func__); 47 return QDF_STATUS_E_INVAL; 48 } 49 50 if (soc->ops->peer_ops->register_peer) 51 return soc->ops->peer_ops->register_peer(soc, pdev_id, 52 sta_desc); 53 54 return QDF_STATUS_E_NOSUPPORT; 55 } 56 57 /** 58 * cdp_clear_peer() - remove peer from physical device 59 * @soc - data path soc handle 60 * @pdev_id - data path device instance id 61 * @peer_addr - peer mac address 62 * 63 * remove peer from physical device 64 * 65 * Return: QDF_STATUS_SUCCESS registration success 66 * QDF_STATUS_E_NOSUPPORT not support this feature 67 */ 68 static inline QDF_STATUS 69 cdp_clear_peer(ol_txrx_soc_handle soc, uint8_t pdev_id, 70 struct qdf_mac_addr peer_addr) 71 { 72 if (!soc || !soc->ops || !soc->ops->peer_ops) { 73 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 74 "%s invalid instance", __func__); 75 return QDF_STATUS_E_INVAL; 76 } 77 78 if (soc->ops->peer_ops->clear_peer) 79 return soc->ops->peer_ops->clear_peer(soc, pdev_id, peer_addr); 80 81 return QDF_STATUS_E_NOSUPPORT; 82 } 83 84 /** 85 * cdp_peer_register_ocb_peer() - register ocb peer from physical device 86 * @soc - data path soc handle 87 * @cds_ctx - cds void context 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_sta_id() - Get vdev instance by local peer id 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 * ol_txrx_peer_detach_force_delete() - Detach and delete a peer's data object 468 * @peer - the object to detach 469 * 470 * Detach a peer and force the peer object to be removed. It is called during 471 * roaming scenario when the firmware has already deleted a peer. 472 * Peer object is freed immediately to avoid duplicate peers during roam sync 473 * indication processing. 474 * 475 * Return: None 476 */ 477 static inline void cdp_peer_detach_force_delete(ol_txrx_soc_handle soc, 478 uint8_t vdev_id, 479 uint8_t *peer_mac) 480 { 481 if (!soc || !soc->ops || !soc->ops->peer_ops) { 482 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 483 "%s invalid instance", __func__); 484 return; 485 } 486 487 if (soc->ops->peer_ops->peer_detach_force_delete) 488 return soc->ops->peer_ops->peer_detach_force_delete(soc, 489 vdev_id, 490 peer_mac); 491 492 return; 493 } 494 495 /** 496 * is_cdp_peer_detach_force_delete_supported() - To check if force delete 497 * operation is supported 498 * @soc: pointer to SOC handle 499 * 500 * Some of the platforms support force delete operation and some of them 501 * don't. This API returns true if API which handles force delete operation 502 * is registered and false otherwise. 503 * 504 * Return: true if API which handles force delete operation is registered 505 * false in all other cases 506 */ 507 static inline bool 508 is_cdp_peer_detach_force_delete_supported(ol_txrx_soc_handle soc) 509 { 510 if (!soc || !soc->ops || !soc->ops->peer_ops) { 511 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 512 "%s invalid instance", __func__); 513 return false; 514 } 515 516 if (soc->ops->peer_ops->peer_detach_force_delete) 517 return true; 518 519 return false; 520 } 521 522 /* 523 * cdp_peer_set_peer_as_tdls() - To set peer as tdls peer 524 * @soc: pointer to SOC handle 525 * @vdev_id: virtual interface id 526 * @peer_mac: peer mac address 527 * @var: true or false 528 * 529 * Return: void 530 */ 531 static inline void 532 cdp_peer_set_peer_as_tdls(ol_txrx_soc_handle soc, uint8_t vdev_id, 533 uint8_t *peer_mac, bool val) 534 { 535 if (!soc || !soc->ops || !soc->ops->peer_ops) { 536 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 537 "%s invalid instance", __func__); 538 return; 539 } 540 541 if (soc->ops->peer_ops->set_peer_as_tdls_peer) 542 soc->ops->peer_ops->set_peer_as_tdls_peer(soc, vdev_id, 543 peer_mac, val); 544 } 545 546 /** 547 * cdp_peer_set_tdls_offchan_enabled() - Set tdls offchan operation as enabled 548 * @soc: pointer to SOC handle 549 * @vdev_id: virtual interface id 550 * @peer_mac: peer mac address 551 * @val: true or false 552 * 553 * update tdls_offchan_enabled 554 * 555 * Return: none 556 */ 557 static inline void 558 cdp_peer_set_tdls_offchan_enabled(ol_txrx_soc_handle soc, uint8_t vdev_id, 559 uint8_t *peer_mac, bool val) 560 { 561 if (!soc || !soc->ops || !soc->ops->peer_ops) { 562 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 563 "%s invalid instance", __func__); 564 return; 565 } 566 567 if (soc->ops->peer_ops->set_tdls_offchan_enabled) 568 soc->ops->peer_ops->set_tdls_offchan_enabled(soc, vdev_id, 569 peer_mac, val); 570 } 571 572 /** 573 * cdp_peer_flush_frags() - Flush frags on peer 574 * @soc - data path soc handle 575 * @vdev_id - virtual interface id 576 * @peer_mac - peer mac addr 577 * 578 * Return: None 579 */ 580 static inline void 581 cdp_peer_flush_frags(ol_txrx_soc_handle soc, uint8_t vdev_id, uint8_t *peer_mac) 582 { 583 if (!soc || !soc->ops || !soc->ops->peer_ops) { 584 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 585 "%s invalid instance", __func__); 586 return; 587 } 588 589 if (soc->ops->peer_ops->peer_flush_frags) 590 soc->ops->peer_ops->peer_flush_frags(soc, vdev_id, peer_mac); 591 } 592 #endif /* _CDP_TXRX_PEER_H_ */ 593