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