1 /* 2 * Copyright (c) 2016-2018 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_ctrl.h 21 * @brief Define the host data path control API functions 22 * called by the host control SW and the OS interface module 23 */ 24 25 #ifndef _CDP_TXRX_CTRL_H_ 26 #define _CDP_TXRX_CTRL_H_ 27 #include "cdp_txrx_handle.h" 28 #include "cdp_txrx_cmn_struct.h" 29 #include "cdp_txrx_ops.h" 30 31 static inline int cdp_is_target_ar900b 32 (ol_txrx_soc_handle soc, struct cdp_vdev *vdev) 33 { 34 if (!soc || !soc->ops) { 35 QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, 36 "%s: Invalid Instance:", __func__); 37 QDF_BUG(0); 38 return 0; 39 } 40 41 if (!soc->ops->ctrl_ops || 42 !soc->ops->ctrl_ops->txrx_is_target_ar900b) 43 return 0; 44 45 return soc->ops->ctrl_ops->txrx_is_target_ar900b(vdev); 46 } 47 48 49 /* WIN */ 50 static inline int 51 cdp_mempools_attach(ol_txrx_soc_handle soc, void *ctrl_pdev) 52 { 53 if (!soc || !soc->ops) { 54 QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, 55 "%s: Invalid Instance:", __func__); 56 QDF_BUG(0); 57 return 0; 58 } 59 60 if (!soc->ops->ctrl_ops || 61 !soc->ops->ctrl_ops->txrx_mempools_attach) 62 return 0; 63 64 return soc->ops->ctrl_ops->txrx_mempools_attach(ctrl_pdev); 65 } 66 67 /** 68 * @brief set filter neighbour peers 69 * @details 70 * This defines interface function to set neighbour peer filtering. 71 * 72 * @param soc - the pointer to soc object 73 * @param pdev - the pointer physical device object 74 * @param val - the enable/disable value 75 * @return - int 76 */ 77 static inline int 78 cdp_set_filter_neighbour_peers(ol_txrx_soc_handle soc, 79 struct cdp_pdev *pdev, u_int32_t val) 80 { 81 if (!soc || !soc->ops) { 82 QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, 83 "%s: Invalid Instance:", __func__); 84 QDF_BUG(0); 85 return 0; 86 } 87 88 if (!soc->ops->ctrl_ops || 89 !soc->ops->ctrl_ops->txrx_set_filter_neighbour_peers) 90 return 0; 91 92 return soc->ops->ctrl_ops->txrx_set_filter_neighbour_peers 93 (pdev, val); 94 } 95 96 /** 97 * @brief update the neighbour peer addresses 98 * @details 99 * This defines interface function to update neighbour peers addresses 100 * which needs to be filtered 101 * 102 * @param soc - the pointer to soc object 103 * @param vdev - the pointer to vdev 104 * @param cmd - add/del entry into peer table 105 * @param macaddr - the address of neighbour peer 106 * @return - int 107 */ 108 static inline int 109 cdp_update_filter_neighbour_peers(ol_txrx_soc_handle soc, 110 struct cdp_vdev *vdev, uint32_t cmd, uint8_t *macaddr) 111 { 112 if (!soc || !soc->ops) { 113 QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, 114 "%s: Invalid Instance:", __func__); 115 QDF_BUG(0); 116 return 0; 117 } 118 119 if (!soc->ops->ctrl_ops || 120 !soc->ops->ctrl_ops->txrx_update_filter_neighbour_peers) 121 return 0; 122 123 return soc->ops->ctrl_ops->txrx_update_filter_neighbour_peers 124 (vdev, cmd, macaddr); 125 } 126 127 /** 128 * @brief set the safemode of the device 129 * @details 130 * This flag is used to bypass the encrypt and decrypt processes when send and 131 * receive packets. It works like open AUTH mode, HW will treate all packets 132 * as non-encrypt frames because no key installed. For rx fragmented frames, 133 * it bypasses all the rx defragmentaion. 134 * 135 * @param vdev - the data virtual device object 136 * @param val - the safemode state 137 * @return - void 138 */ 139 static inline void 140 cdp_set_safemode(ol_txrx_soc_handle soc, 141 struct cdp_vdev *vdev, u_int32_t val) 142 { 143 if (!soc || !soc->ops) { 144 QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, 145 "%s: Invalid Instance:", __func__); 146 QDF_BUG(0); 147 return; 148 } 149 150 if (!soc->ops->ctrl_ops || 151 !soc->ops->ctrl_ops->txrx_set_safemode) 152 return; 153 154 soc->ops->ctrl_ops->txrx_set_safemode(vdev, val); 155 } 156 /** 157 * @brief configure the drop unencrypted frame flag 158 * @details 159 * Rx related. When set this flag, all the unencrypted frames 160 * received over a secure connection will be discarded 161 * 162 * @param vdev - the data virtual device object 163 * @param val - flag 164 * @return - void 165 */ 166 static inline void 167 cdp_set_drop_unenc(ol_txrx_soc_handle soc, 168 struct cdp_vdev *vdev, u_int32_t val) 169 { 170 if (!soc || !soc->ops) { 171 QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, 172 "%s: Invalid Instance:", __func__); 173 QDF_BUG(0); 174 return; 175 } 176 177 if (!soc->ops->ctrl_ops || 178 !soc->ops->ctrl_ops->txrx_set_drop_unenc) 179 return; 180 181 soc->ops->ctrl_ops->txrx_set_drop_unenc(vdev, val); 182 } 183 184 185 /** 186 * @brief set the Tx encapsulation type of the VDEV 187 * @details 188 * This will be used to populate the HTT desc packet type field during Tx 189 * 190 * @param vdev - the data virtual device object 191 * @param val - the Tx encap type (htt_cmn_pkt_type) 192 * @return - void 193 */ 194 static inline void 195 cdp_set_tx_encap_type(ol_txrx_soc_handle soc, 196 struct cdp_vdev *vdev, enum htt_cmn_pkt_type val) 197 { 198 if (!soc || !soc->ops) { 199 QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, 200 "%s: Invalid Instance:", __func__); 201 QDF_BUG(0); 202 return; 203 } 204 205 if (!soc->ops->ctrl_ops || 206 !soc->ops->ctrl_ops->txrx_set_tx_encap_type) 207 return; 208 209 soc->ops->ctrl_ops->txrx_set_tx_encap_type(vdev, val); 210 } 211 212 /** 213 * @brief set the Rx decapsulation type of the VDEV 214 * @details 215 * This will be used to configure into firmware and hardware which format to 216 * decap all Rx packets into, for all peers under the VDEV. 217 * 218 * @param vdev - the data virtual device object 219 * @param val - the Rx decap mode (htt_cmn_pkt_type) 220 * @return - void 221 */ 222 static inline void 223 cdp_set_vdev_rx_decap_type(ol_txrx_soc_handle soc, 224 struct cdp_vdev *vdev, enum htt_cmn_pkt_type val) 225 { 226 if (!soc || !soc->ops) { 227 QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, 228 "%s: Invalid Instance:", __func__); 229 QDF_BUG(0); 230 return; 231 } 232 233 if (!soc->ops->ctrl_ops || 234 !soc->ops->ctrl_ops->txrx_set_vdev_rx_decap_type) 235 return; 236 237 soc->ops->ctrl_ops->txrx_set_vdev_rx_decap_type 238 (vdev, val); 239 } 240 241 /** 242 * @brief get the Rx decapsulation type of the VDEV 243 * 244 * @param vdev - the data virtual device object 245 * @return - the Rx decap type (htt_cmn_pkt_type) 246 */ 247 static inline enum htt_cmn_pkt_type 248 cdp_get_vdev_rx_decap_type(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) 249 { 250 if (!soc || !soc->ops) { 251 QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, 252 "%s: Invalid Instance:", __func__); 253 QDF_BUG(0); 254 return 0; 255 } 256 257 if (!soc->ops->ctrl_ops || 258 !soc->ops->ctrl_ops->txrx_get_vdev_rx_decap_type) 259 return 0; 260 261 return soc->ops->ctrl_ops->txrx_get_vdev_rx_decap_type(vdev); 262 } 263 264 /** 265 * @brief set the Reo Destination ring for the pdev 266 * @details 267 * This will be used to configure the Reo Destination ring for this pdev. 268 * 269 * @param soc - pointer to the soc 270 * @param pdev - the data physical device object 271 * @param val - the Reo destination ring index (1 to 4) 272 * @return - void 273 */ 274 static inline void 275 cdp_set_pdev_reo_dest(ol_txrx_soc_handle soc, 276 struct cdp_pdev *pdev, enum cdp_host_reo_dest_ring val) 277 { 278 if (!soc || !soc->ops) { 279 QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, 280 "%s: Invalid Instance:", __func__); 281 QDF_BUG(0); 282 return; 283 } 284 285 if (!soc->ops->ctrl_ops || 286 !soc->ops->ctrl_ops->txrx_set_pdev_reo_dest) 287 return; 288 289 soc->ops->ctrl_ops->txrx_set_pdev_reo_dest 290 (pdev, val); 291 } 292 293 /** 294 * @brief get the Reo Destination ring for the pdev 295 * 296 * @param soc - pointer to the soc 297 * @param pdev - the data physical device object 298 * @return - the Reo destination ring index (1 to 4), 0 if not supported. 299 */ 300 static inline enum cdp_host_reo_dest_ring 301 cdp_get_pdev_reo_dest(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) 302 { 303 if (!soc || !soc->ops) { 304 QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, 305 "%s: Invalid Instance:", __func__); 306 QDF_BUG(0); 307 return cdp_host_reo_dest_ring_unknown; 308 } 309 310 if (!soc->ops->ctrl_ops || 311 !soc->ops->ctrl_ops->txrx_get_pdev_reo_dest) 312 return cdp_host_reo_dest_ring_unknown; 313 314 return soc->ops->ctrl_ops->txrx_get_pdev_reo_dest(pdev); 315 } 316 317 /* Is this similar to ol_txrx_peer_state_update() in MCL */ 318 /** 319 * @brief Update the authorize peer object at association time 320 * @details 321 * For the host-based implementation of rate-control, it 322 * updates the peer/node-related parameters within rate-control 323 * context of the peer at association. 324 * 325 * @param peer - pointer to the node's object 326 * @authorize - either to authorize or unauthorize peer 327 * 328 * @return none 329 */ 330 static inline void 331 cdp_peer_authorize(ol_txrx_soc_handle soc, 332 struct cdp_peer *peer, u_int32_t authorize) 333 { 334 if (!soc || !soc->ops) { 335 QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, 336 "%s: Invalid Instance:", __func__); 337 QDF_BUG(0); 338 return; 339 } 340 341 if (!soc->ops->ctrl_ops || 342 !soc->ops->ctrl_ops->txrx_peer_authorize) 343 return; 344 345 soc->ops->ctrl_ops->txrx_peer_authorize 346 (peer, authorize); 347 } 348 349 /* Should be ol_txrx_ctrl_api.h */ 350 static inline void cdp_set_mesh_mode 351 (ol_txrx_soc_handle soc, struct cdp_vdev *vdev, u_int32_t val) 352 { 353 if (!soc || !soc->ops) { 354 QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, 355 "%s: Invalid Instance:", __func__); 356 QDF_BUG(0); 357 return; 358 } 359 360 if (!soc->ops->ctrl_ops || 361 !soc->ops->ctrl_ops->txrx_set_mesh_mode) 362 return; 363 364 soc->ops->ctrl_ops->txrx_set_mesh_mode(vdev, val); 365 } 366 367 /** 368 * @brief set mesh rx filter 369 * @details based on the bits enabled in the filter packets has to be dropped. 370 * 371 * @param soc - pointer to the soc 372 * @param vdev - the data virtual device object 373 * @param val - value to be set 374 * @return - void 375 */ 376 static inline 377 void cdp_set_mesh_rx_filter(ol_txrx_soc_handle soc, 378 struct cdp_vdev *vdev, uint32_t val) 379 { 380 if (!soc || !soc->ops) { 381 QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, 382 "%s: Invalid Instance:", __func__); 383 QDF_BUG(0); 384 return; 385 } 386 387 if (!soc->ops->ctrl_ops || 388 !soc->ops->ctrl_ops->txrx_set_mesh_rx_filter) 389 return; 390 391 soc->ops->ctrl_ops->txrx_set_mesh_rx_filter(vdev, val); 392 } 393 394 static inline void cdp_tx_flush_buffers 395 (ol_txrx_soc_handle soc, struct cdp_vdev *vdev) 396 { 397 if (!soc || !soc->ops) { 398 QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, 399 "%s: Invalid Instance:", __func__); 400 QDF_BUG(0); 401 return; 402 } 403 404 if (!soc->ops->ctrl_ops || 405 !soc->ops->ctrl_ops->tx_flush_buffers) 406 return; 407 408 soc->ops->ctrl_ops->tx_flush_buffers(vdev); 409 } 410 411 static inline void cdp_txrx_set_vdev_param(ol_txrx_soc_handle soc, 412 struct cdp_vdev *vdev, enum cdp_vdev_param_type type, 413 uint32_t val) 414 { 415 if (!soc || !soc->ops) { 416 QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, 417 "%s: Invalid Instance:", __func__); 418 QDF_BUG(0); 419 return; 420 } 421 422 if (!soc->ops->ctrl_ops || 423 !soc->ops->ctrl_ops->txrx_set_vdev_param) 424 return; 425 426 soc->ops->ctrl_ops->txrx_set_vdev_param(vdev, type, val); 427 } 428 429 static inline void 430 cdp_peer_set_nawds(ol_txrx_soc_handle soc, 431 struct cdp_peer *peer, uint8_t value) 432 { 433 if (!soc || !soc->ops) { 434 QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, 435 "%s: Invalid Instance:", __func__); 436 QDF_BUG(0); 437 return; 438 } 439 440 if (!soc->ops->ctrl_ops || 441 !soc->ops->ctrl_ops->txrx_peer_set_nawds) 442 return; 443 444 soc->ops->ctrl_ops->txrx_peer_set_nawds 445 (peer, value); 446 } 447 448 static inline void cdp_txrx_set_pdev_param(ol_txrx_soc_handle soc, 449 struct cdp_pdev *pdev, enum cdp_pdev_param_type type, 450 uint8_t val) 451 { 452 if (!soc || !soc->ops) { 453 QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, 454 "%s: Invalid Instance:", __func__); 455 QDF_BUG(0); 456 return; 457 } 458 459 if (!soc->ops->ctrl_ops || 460 !soc->ops->ctrl_ops->txrx_set_pdev_param) 461 return; 462 463 soc->ops->ctrl_ops->txrx_set_pdev_param 464 (pdev, type, val); 465 } 466 467 /** 468 * @brief Subscribe to a specified WDI event. 469 * @details 470 * This function adds the provided wdi_event_subscribe object to a list of 471 * subscribers for the specified WDI event. 472 * When the event in question happens, each subscriber for the event will 473 * have their callback function invoked. 474 * The order in which callback functions from multiple subscribers are 475 * invoked is unspecified. 476 * 477 * @param soc - pointer to the soc 478 * @param pdev - the data physical device object 479 * @param event_cb_sub - the callback and context for the event subscriber 480 * @param event - which event's notifications are being subscribed to 481 * @return - int 482 */ 483 static inline int 484 cdp_wdi_event_sub(ol_txrx_soc_handle soc, 485 struct cdp_pdev *pdev, void *event_cb_sub, uint32_t event) 486 { 487 488 if (!soc || !soc->ops) { 489 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 490 "%s invalid instance", __func__); 491 QDF_BUG(0); 492 return 0; 493 } 494 495 if (!soc->ops->ctrl_ops || 496 !soc->ops->ctrl_ops->txrx_wdi_event_sub) 497 return 0; 498 499 return soc->ops->ctrl_ops->txrx_wdi_event_sub 500 (pdev, event_cb_sub, event); 501 } 502 503 /** 504 * @brief Unsubscribe from a specified WDI event. 505 * @details 506 * This function removes the provided event subscription object from the 507 * list of subscribers for its event. 508 * This function shall only be called if there was a successful prior call 509 * to event_sub() on the same wdi_event_subscribe object. 510 * 511 * @param soc - pointer to the soc 512 * @param pdev - the data physical device object 513 * @param event_cb_sub - the callback and context for the event subscriber 514 * @param event - which event's notifications are being subscribed to 515 * @return - int 516 */ 517 static inline int 518 cdp_wdi_event_unsub(ol_txrx_soc_handle soc, 519 struct cdp_pdev *pdev, void *event_cb_sub, uint32_t event) 520 { 521 522 if (!soc || !soc->ops) { 523 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 524 "%s invalid instance", __func__); 525 QDF_BUG(0); 526 return 0; 527 } 528 529 if (!soc->ops->ctrl_ops || 530 !soc->ops->ctrl_ops->txrx_wdi_event_unsub) 531 return 0; 532 533 return soc->ops->ctrl_ops->txrx_wdi_event_unsub 534 (pdev, event_cb_sub, event); 535 } 536 537 /** 538 * @brief Get security type from the from peer. 539 * @details 540 * This function gets the Security information from the peer handler. 541 * The security information is got from the rx descriptor and filled in 542 * to the peer handler. 543 * 544 * @param soc - pointer to the soc 545 * @param peer - peer handler 546 * @param sec_idx - mcast or ucast frame type. 547 * @return - int 548 */ 549 static inline int 550 cdp_get_sec_type(ol_txrx_soc_handle soc, struct cdp_peer *peer, uint8_t sec_idx) 551 { 552 if (!soc || !soc->ops) { 553 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 554 "%s invalid instance", __func__); 555 QDF_BUG(0); 556 return A_ERROR; 557 } 558 559 if (!soc->ops->ctrl_ops || 560 !soc->ops->ctrl_ops->txrx_get_sec_type) 561 return A_ERROR; 562 563 return soc->ops->ctrl_ops->txrx_get_sec_type 564 (peer, sec_idx); 565 } 566 567 /** 568 * cdp_set_mgmt_tx_power(): function to set tx power for mgmt frames 569 * @vdev_handle: vdev handle 570 * @subtype_index: subtype 571 * @tx_power: Tx power 572 * Return: None 573 */ 574 static inline int cdp_set_mgmt_tx_power(ol_txrx_soc_handle soc, 575 struct cdp_vdev *vdev, uint8_t subtype, uint8_t tx_power) 576 { 577 if (!soc || !soc->ops) { 578 QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, 579 "%s: Invalid Instance:", __func__); 580 QDF_BUG(0); 581 return 0; 582 } 583 584 if (!soc->ops->ctrl_ops || 585 !soc->ops->ctrl_ops->txrx_update_mgmt_txpow_vdev) 586 return 0; 587 588 soc->ops->ctrl_ops->txrx_update_mgmt_txpow_vdev(vdev, 589 subtype, tx_power); 590 return 0; 591 } 592 593 static inline void * 594 cdp_get_pldev(ol_txrx_soc_handle soc, 595 struct cdp_pdev *pdev) 596 { 597 if (!soc || !soc->ops) { 598 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 599 "%s invalid instance", __func__); 600 QDF_BUG(0); 601 return NULL; 602 } 603 604 if (!soc->ops->ctrl_ops || !soc->ops->ctrl_ops->txrx_get_pldev) 605 return NULL; 606 607 return soc->ops->ctrl_ops->txrx_get_pldev(pdev); 608 } 609 610 #ifdef ATH_SUPPORT_NAC_RSSI 611 /** 612 * cdp_vdev_config_for_nac_rssi(): To invoke dp callback for nac rssi config 613 * @soc: soc pointer 614 * @vdev: vdev pointer 615 * @nac_cmd: specfies nac_rss config action add, del, list 616 * @bssid: Neighbour bssid 617 * @client_macaddr: Non-Associated client MAC 618 * @chan_num: channel number to scan 619 * 620 * Return: QDF_STATUS 621 */ 622 static inline QDF_STATUS cdp_vdev_config_for_nac_rssi(ol_txrx_soc_handle soc, 623 struct cdp_vdev *vdev, enum cdp_nac_param_cmd nac_cmd, 624 char *bssid, char *client_macaddr, uint8_t chan_num) 625 { 626 if (!soc || !soc->ops) { 627 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 628 "%s invalid instance", __func__); 629 QDF_BUG(0); 630 return QDF_STATUS_E_FAILURE; 631 } 632 633 if (!soc->ops->ctrl_ops || 634 !soc->ops->ctrl_ops->txrx_vdev_config_for_nac_rssi) 635 return QDF_STATUS_E_FAILURE; 636 637 return soc->ops->ctrl_ops->txrx_vdev_config_for_nac_rssi(vdev, 638 nac_cmd, bssid, client_macaddr, chan_num); 639 } 640 641 /* 642 * cdp_vdev_get_neighbour_rssi(): To invoke dp callback to get rssi value of nac 643 * @soc: soc pointer 644 * @vdev: vdev pointer 645 * @macaddr: Non-Associated client MAC 646 * @rssi: rssi 647 * 648 * Return: QDF_STATUS 649 */ 650 static inline QDF_STATUS cdp_vdev_get_neighbour_rssi(ol_txrx_soc_handle soc, 651 struct cdp_vdev *vdev, 652 char *macaddr, 653 uint8_t *rssi) 654 { 655 if (!soc || !soc->ops) { 656 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 657 "%s invalid instance", __func__); 658 QDF_BUG(0); 659 return QDF_STATUS_E_FAILURE; 660 } 661 662 if (!soc->ops->ctrl_ops || 663 !soc->ops->ctrl_ops->txrx_vdev_get_neighbour_rssi) 664 return QDF_STATUS_E_FAILURE; 665 666 return soc->ops->ctrl_ops->txrx_vdev_get_neighbour_rssi(vdev, macaddr, 667 rssi); 668 } 669 #endif 670 #endif 671