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_misc.h 21 * @brief Define the host data path miscelleneous API functions 22 * called by the host control SW and the OS interface module 23 */ 24 #ifndef _CDP_TXRX_MISC_H_ 25 #define _CDP_TXRX_MISC_H_ 26 27 #include "cdp_txrx_handle.h" 28 /** 29 * cdp_tx_non_std() - Allow the control-path SW to send data frames 30 * 31 * @soc - data path soc handle 32 * @data_vdev - which vdev should transmit the tx data frames 33 * @tx_spec - what non-standard handling to apply to the tx data frames 34 * @msdu_list - NULL-terminated list of tx MSDUs 35 * 36 * Generally, all tx data frames come from the OS shim into the txrx layer. 37 * However, there are rare cases such as TDLS messaging where the UMAC 38 * control-path SW creates tx data frames. 39 * This UMAC SW can call this function to provide the tx data frames to 40 * the txrx layer. 41 * The UMAC SW can request a callback for these data frames after their 42 * transmission completes, by using the ol_txrx_data_tx_cb_set function 43 * to register a tx completion callback, and by specifying 44 * ol_tx_spec_no_free as the tx_spec arg when giving the frames to 45 * ol_tx_non_std. 46 * The MSDUs need to have the appropriate L2 header type (802.3 vs. 802.11), 47 * as specified by ol_cfg_frame_type(). 48 * 49 * Return: null - success, skb - failure 50 */ 51 static inline qdf_nbuf_t 52 cdp_tx_non_std(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, 53 enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list) 54 { 55 if (!soc || !soc->ops || !soc->ops->misc_ops) { 56 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, 57 "%s invalid instance", __func__); 58 return NULL; 59 } 60 61 if (soc->ops->misc_ops->tx_non_std) 62 return soc->ops->misc_ops->tx_non_std( 63 vdev, tx_spec, msdu_list); 64 return NULL; 65 } 66 67 /** 68 * cdp_set_ibss_vdev_heart_beat_timer() - Update ibss vdev heart 69 * beat timer 70 * @soc - data path soc handle 71 * @vdev - vdev handle 72 * @timer_value_sec - new heart beat timer value 73 * 74 * Return: Old timer value set in vdev. 75 */ 76 static inline uint16_t 77 cdp_set_ibss_vdev_heart_beat_timer(ol_txrx_soc_handle soc, 78 struct cdp_vdev *vdev, uint16_t timer_value_sec) 79 { 80 if (!soc || !soc->ops || !soc->ops->misc_ops) { 81 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 82 "%s invalid instance", __func__); 83 return 0; 84 } 85 86 if (soc->ops->misc_ops->set_ibss_vdev_heart_beat_timer) 87 return soc->ops->misc_ops->set_ibss_vdev_heart_beat_timer( 88 vdev, timer_value_sec); 89 90 return 0; 91 } 92 93 /** 94 * cdp_set_wisa_mode() - set wisa mode 95 * @soc - data path soc handle 96 * @vdev - vdev handle 97 * @enable - enable or disable 98 * 99 * Return: QDF_STATUS_SUCCESS mode enable success 100 */ 101 static inline QDF_STATUS 102 cdp_set_wisa_mode(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, bool enable) 103 { 104 if (!soc || !soc->ops || !soc->ops->misc_ops) { 105 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 106 "%s invalid instance", __func__); 107 return QDF_STATUS_E_INVAL; 108 } 109 110 if (soc->ops->misc_ops->set_wisa_mode) 111 return soc->ops->misc_ops->set_wisa_mode(vdev, enable); 112 return QDF_STATUS_SUCCESS; 113 } 114 115 /** 116 * cdp_data_stall_cb_register() - register data stall callback 117 * @soc - data path soc handle 118 * @cb - callback function 119 * 120 * Return: QDF_STATUS_SUCCESS register success 121 */ 122 static inline QDF_STATUS cdp_data_stall_cb_register(ol_txrx_soc_handle soc, 123 data_stall_detect_cb cb) 124 { 125 if (!soc || !soc->ops || !soc->ops->misc_ops) { 126 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 127 "%s invalid instance", __func__); 128 return QDF_STATUS_E_INVAL; 129 } 130 131 if (soc->ops->misc_ops->txrx_data_stall_cb_register) 132 return soc->ops->misc_ops->txrx_data_stall_cb_register(cb); 133 return QDF_STATUS_SUCCESS; 134 } 135 136 /** 137 * cdp_data_stall_cb_deregister() - de-register data stall callback 138 * @soc - data path soc handle 139 * @cb - callback function 140 * 141 * Return: QDF_STATUS_SUCCESS de-register success 142 */ 143 static inline QDF_STATUS cdp_data_stall_cb_deregister(ol_txrx_soc_handle soc, 144 data_stall_detect_cb cb) 145 { 146 if (!soc || !soc->ops || !soc->ops->misc_ops) { 147 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 148 "%s invalid instance", __func__); 149 return QDF_STATUS_E_INVAL; 150 } 151 152 if (soc->ops->misc_ops->txrx_data_stall_cb_deregister) 153 return soc->ops->misc_ops->txrx_data_stall_cb_deregister(cb); 154 return QDF_STATUS_SUCCESS; 155 } 156 157 /** 158 * cdp_post_data_stall_event() - post data stall event 159 * @soc - data path soc handle 160 * @indicator: Module triggering data stall 161 * @data_stall_type: data stall event type 162 * @pdev_id: pdev id 163 * @vdev_id_bitmap: vdev id bitmap 164 * @recovery_type: data stall recovery type 165 * 166 * Return: None 167 */ 168 static inline void 169 cdp_post_data_stall_event(ol_txrx_soc_handle soc, 170 enum data_stall_log_event_indicator indicator, 171 enum data_stall_log_event_type data_stall_type, 172 uint32_t pdev_id, uint32_t vdev_id_bitmap, 173 enum data_stall_log_recovery_type recovery_type) 174 { 175 if (!soc || !soc->ops) { 176 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 177 "%s invalid instance", __func__); 178 QDF_BUG(0); 179 return; 180 } 181 182 if (!soc->ops->misc_ops || 183 !soc->ops->misc_ops->txrx_post_data_stall_event) 184 return; 185 186 soc->ops->misc_ops->txrx_post_data_stall_event( 187 indicator, data_stall_type, pdev_id, 188 vdev_id_bitmap, recovery_type); 189 } 190 191 /** 192 * cdp_set_wmm_param() - set wmm parameter 193 * @soc - data path soc handle 194 * @pdev - device instance pointer 195 * @wmm_param - wmm parameter 196 * 197 * Return: none 198 */ 199 static inline void 200 cdp_set_wmm_param(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, 201 struct ol_tx_wmm_param_t wmm_param) 202 { 203 if (!soc || !soc->ops || !soc->ops->misc_ops) { 204 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 205 "%s invalid instance", __func__); 206 return; 207 } 208 209 if (soc->ops->misc_ops->set_wmm_param) 210 return soc->ops->misc_ops->set_wmm_param( 211 pdev, wmm_param); 212 213 return; 214 } 215 216 /** 217 * cdp_runtime_suspend() - suspend 218 * @soc - data path soc handle 219 * @pdev - device instance pointer 220 * 221 * Return: QDF_STATUS_SUCCESS suspend success 222 */ 223 static inline QDF_STATUS cdp_runtime_suspend(ol_txrx_soc_handle soc, 224 struct cdp_pdev *pdev) 225 { 226 if (!soc || !soc->ops || !soc->ops->misc_ops) { 227 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 228 "%s invalid instance", __func__); 229 return QDF_STATUS_E_INVAL; 230 } 231 232 if (soc->ops->misc_ops->runtime_suspend) 233 return soc->ops->misc_ops->runtime_suspend(pdev); 234 235 return QDF_STATUS_SUCCESS; 236 } 237 238 /** 239 * cdp_runtime_resume() - resume 240 * @soc - data path soc handle 241 * @pdev - device instance pointer 242 * 243 * Return: QDF_STATUS_SUCCESS suspend success 244 */ 245 static inline QDF_STATUS cdp_runtime_resume(ol_txrx_soc_handle soc, 246 struct cdp_pdev *pdev) 247 { 248 if (!soc || !soc->ops || !soc->ops->misc_ops) { 249 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 250 "%s invalid instance", __func__); 251 return QDF_STATUS_E_INVAL; 252 } 253 254 if (soc->ops->misc_ops->runtime_resume) 255 return soc->ops->misc_ops->runtime_resume(pdev); 256 257 return QDF_STATUS_SUCCESS; 258 } 259 260 /** 261 * cdp_hl_tdls_flag_reset() - tdls flag reset 262 * @soc - data path soc handle 263 * @vdev - virtual interface handle pointer 264 * @flag 265 * 266 * Return: none 267 */ 268 static inline void 269 cdp_hl_tdls_flag_reset(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, bool flag) 270 { 271 if (!soc || !soc->ops || !soc->ops->misc_ops) { 272 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 273 "%s invalid instance", __func__); 274 return; 275 } 276 277 if (soc->ops->misc_ops->hl_tdls_flag_reset) 278 return soc->ops->misc_ops->hl_tdls_flag_reset(vdev, flag); 279 280 return; 281 } 282 283 /** 284 * cdp_get_opmode() - get vdev operation mode 285 * @soc - data path soc handle 286 * @vdev - virtual interface instance 287 * 288 * Return virtual device operational mode 289 * op_mode_ap, 290 * op_mode_ibss, 291 * op_mode_sta, 292 * op_mode_monitor, 293 * op_mode_ocb, 294 * 295 * return interface id 296 * 0 unknown interface 297 */ 298 static inline int 299 cdp_get_opmode(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) 300 { 301 if (!soc || !soc->ops || !soc->ops->misc_ops) { 302 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 303 "%s invalid instance", __func__); 304 return 0; 305 } 306 307 if (soc->ops->misc_ops->get_opmode) 308 return soc->ops->misc_ops->get_opmode(vdev); 309 return 0; 310 } 311 312 /** 313 * cdp_get_vdev_id() - get vdev id 314 * @soc - data path soc handle 315 * @vdev - virtual interface instance 316 * 317 * get virtual interface id 318 * 319 * return interface id 320 * 0 unknown interface 321 */ 322 static inline uint16_t 323 cdp_get_vdev_id(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) 324 { 325 if (!soc || !soc->ops || !soc->ops->misc_ops) { 326 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 327 "%s invalid instance", __func__); 328 return 0; 329 } 330 331 if (soc->ops->misc_ops->get_vdev_id) 332 return soc->ops->misc_ops->get_vdev_id(vdev); 333 return 0; 334 } 335 336 /** 337 * cdp_get_tx_ack_stats() - get tx ack count for vdev 338 * @soc - data path soc handle 339 * @vdev_id - vdev id 340 * 341 * return tx ack count 342 * 0 invalid count 343 */ 344 static inline uint32_t 345 cdp_get_tx_ack_stats(ol_txrx_soc_handle soc, uint8_t vdev_id) 346 { 347 if (!soc || !soc->ops || !soc->ops->misc_ops) { 348 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 349 "%s invalid instance", __func__); 350 return 0; 351 } 352 353 if (soc->ops->misc_ops->get_tx_ack_stats) 354 return soc->ops->misc_ops->get_tx_ack_stats(vdev_id); 355 return 0; 356 } 357 358 /** 359 * cdp_bad_peer_txctl_set_setting() - TBD 360 * @soc - data path soc handle 361 * @pdev - data path device instance 362 * @enable - 363 * @period - 364 * @txq_limit - 365 * 366 * TBD 367 * 368 * Return: none 369 */ 370 static inline void 371 cdp_bad_peer_txctl_set_setting(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, 372 int enable, int period, int txq_limit) 373 { 374 if (!soc || !soc->ops || !soc->ops->misc_ops) { 375 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 376 "%s invalid instance", __func__); 377 return; 378 } 379 380 if (soc->ops->misc_ops->bad_peer_txctl_set_setting) 381 return soc->ops->misc_ops->bad_peer_txctl_set_setting(pdev, 382 enable, period, txq_limit); 383 return; 384 } 385 386 /** 387 * cdp_bad_peer_txctl_update_threshold() - TBD 388 * @soc - data path soc handle 389 * @pdev - data path device instance 390 * @level - 391 * @tput_thresh - 392 * @tx_limit - 393 * 394 * TBD 395 * 396 * Return: none 397 */ 398 static inline void 399 cdp_bad_peer_txctl_update_threshold(ol_txrx_soc_handle soc, 400 struct cdp_pdev *pdev, 401 int level, int tput_thresh, int tx_limit) 402 { 403 if (!soc || !soc->ops || !soc->ops->misc_ops) { 404 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 405 "%s invalid instance", __func__); 406 return; 407 } 408 409 if (soc->ops->misc_ops->bad_peer_txctl_update_threshold) 410 return soc->ops->misc_ops->bad_peer_txctl_update_threshold( 411 pdev, level, tput_thresh, tx_limit); 412 return; 413 } 414 415 /** 416 * cdp_mark_first_wakeup_packet() - set flag to indicate that 417 * fw is compatible for marking first packet after wow wakeup 418 * @soc - data path soc handle 419 * @value: 1 for enabled/ 0 for disabled 420 * 421 * Return: None 422 */ 423 static inline void cdp_mark_first_wakeup_packet(ol_txrx_soc_handle soc, 424 uint8_t value) 425 { 426 if (!soc || !soc->ops || !soc->ops->misc_ops) { 427 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 428 "%s invalid instance", __func__); 429 return; 430 } 431 432 if (soc->ops->misc_ops->mark_first_wakeup_packet) 433 return soc->ops->misc_ops->mark_first_wakeup_packet(value); 434 return; 435 } 436 437 438 /** 439 * cds_update_mac_id() - update mac_id for vdev 440 * @soc - data path soc handle 441 * @vdev_id: vdev id 442 * @mac_id: mac id 443 * 444 * Return: none 445 */ 446 static inline void cdp_update_mac_id(void *psoc, uint8_t vdev_id, 447 uint8_t mac_id) 448 { 449 ol_txrx_soc_handle soc = psoc; 450 451 if (!soc || !soc->ops || !soc->ops->misc_ops) { 452 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 453 "%s invalid instance", __func__); 454 return; 455 } 456 457 if (soc->ops->misc_ops->update_mac_id) 458 return soc->ops->misc_ops->update_mac_id(vdev_id, mac_id); 459 return; 460 } 461 462 /** 463 * cdp_flush_rx_frames() - flush cached rx frames 464 * @soc - data path soc handle 465 * @peer: peer 466 * @drop: set flag to drop frames 467 * 468 * Return: None 469 */ 470 static inline void cdp_flush_rx_frames(ol_txrx_soc_handle soc, void *peer, 471 bool drop) 472 { 473 if (!soc || !soc->ops || !soc->ops->misc_ops) { 474 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 475 "%s invalid instance", __func__); 476 return; 477 } 478 479 if (soc->ops->misc_ops->flush_rx_frames) 480 return soc->ops->misc_ops->flush_rx_frames(peer, drop); 481 return; 482 } 483 484 /* 485 * cdp_get_intra_bss_fwd_pkts_count() - to get the total tx and rx packets 486 * that has been forwarded from txrx layer without going to upper layers. 487 * @vdev_id: vdev id 488 * @fwd_tx_packets: pointer to forwarded tx packets count parameter 489 * @fwd_rx_packets: pointer to forwarded rx packets count parameter 490 * 491 * Return: status -> A_OK - success, A_ERROR - failure 492 */ 493 static inline A_STATUS cdp_get_intra_bss_fwd_pkts_count( 494 ol_txrx_soc_handle soc, uint8_t vdev_id, 495 uint64_t *fwd_tx_packets, uint64_t *fwd_rx_packets) 496 { 497 if (!soc || !soc->ops || !soc->ops->misc_ops) { 498 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 499 "%s invalid instance", __func__); 500 return 0; 501 } 502 503 if (soc->ops->misc_ops->get_intra_bss_fwd_pkts_count) 504 return soc->ops->misc_ops->get_intra_bss_fwd_pkts_count( 505 vdev_id, fwd_tx_packets, fwd_rx_packets); 506 507 return 0; 508 } 509 510 /** 511 * cdp_pkt_log_init() - API to initialize packet log 512 * @handle: pdev handle 513 * @scn: HIF context 514 * 515 * Return: void 516 */ 517 static inline void cdp_pkt_log_init(ol_txrx_soc_handle soc, 518 struct cdp_pdev *pdev, void *scn) 519 { 520 if (!soc || !soc->ops || !soc->ops->misc_ops) { 521 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 522 "%s invalid instance", __func__); 523 return; 524 } 525 526 if (soc->ops->misc_ops->pkt_log_init) 527 return soc->ops->misc_ops->pkt_log_init(pdev, scn); 528 529 return; 530 } 531 532 /** 533 * cdp_pkt_log_con_service() - API to connect packet log service 534 * @handle: pdev handle 535 * @scn: HIF context 536 * 537 * Return: void 538 */ 539 static inline void cdp_pkt_log_con_service(ol_txrx_soc_handle soc, 540 struct cdp_pdev *pdev, void *scn) 541 { 542 if (!soc || !soc->ops || !soc->ops->misc_ops) { 543 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 544 "%s invalid instance", __func__); 545 return; 546 } 547 548 if (soc->ops->misc_ops->pkt_log_con_service) 549 return soc->ops->misc_ops->pkt_log_con_service(pdev, scn); 550 551 return; 552 } 553 #endif /* _CDP_TXRX_MISC_H_ */ 554