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_FATAL, 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 || !soc->ops->misc_ops) 184 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 185 "%s invalid instance", __func__); 186 187 if (soc->ops->misc_ops->txrx_post_data_stall_event) 188 soc->ops->misc_ops->txrx_post_data_stall_event( 189 indicator, data_stall_type, pdev_id, 190 vdev_id_bitmap, recovery_type); 191 } 192 193 /** 194 * cdp_set_wmm_param() - set wmm parameter 195 * @soc - data path soc handle 196 * @pdev - device instance pointer 197 * @wmm_param - wmm parameter 198 * 199 * Return: none 200 */ 201 static inline void 202 cdp_set_wmm_param(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, 203 struct ol_tx_wmm_param_t wmm_param) 204 { 205 if (!soc || !soc->ops || !soc->ops->misc_ops) { 206 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 207 "%s invalid instance", __func__); 208 return; 209 } 210 211 if (soc->ops->misc_ops->set_wmm_param) 212 return soc->ops->misc_ops->set_wmm_param( 213 pdev, wmm_param); 214 215 return; 216 } 217 218 /** 219 * cdp_runtime_suspend() - suspend 220 * @soc - data path soc handle 221 * @pdev - device instance pointer 222 * 223 * Return: QDF_STATUS_SUCCESS suspend success 224 */ 225 static inline QDF_STATUS cdp_runtime_suspend(ol_txrx_soc_handle soc, 226 struct cdp_pdev *pdev) 227 { 228 if (!soc || !soc->ops || !soc->ops->misc_ops) { 229 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 230 "%s invalid instance", __func__); 231 return QDF_STATUS_E_INVAL; 232 } 233 234 if (soc->ops->misc_ops->runtime_suspend) 235 return soc->ops->misc_ops->runtime_suspend(pdev); 236 237 return QDF_STATUS_SUCCESS; 238 } 239 240 /** 241 * cdp_runtime_resume() - resume 242 * @soc - data path soc handle 243 * @pdev - device instance pointer 244 * 245 * Return: QDF_STATUS_SUCCESS suspend success 246 */ 247 static inline QDF_STATUS cdp_runtime_resume(ol_txrx_soc_handle soc, 248 struct cdp_pdev *pdev) 249 { 250 if (!soc || !soc->ops || !soc->ops->misc_ops) { 251 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 252 "%s invalid instance", __func__); 253 return QDF_STATUS_E_INVAL; 254 } 255 256 if (soc->ops->misc_ops->runtime_resume) 257 return soc->ops->misc_ops->runtime_resume(pdev); 258 259 return QDF_STATUS_SUCCESS; 260 } 261 262 /** 263 * cdp_hl_tdls_flag_reset() - tdls flag reset 264 * @soc - data path soc handle 265 * @vdev - virtual interface handle pointer 266 * @flag 267 * 268 * Return: none 269 */ 270 static inline void 271 cdp_hl_tdls_flag_reset(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, bool flag) 272 { 273 if (!soc || !soc->ops || !soc->ops->misc_ops) { 274 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 275 "%s invalid instance", __func__); 276 return; 277 } 278 279 if (soc->ops->misc_ops->hl_tdls_flag_reset) 280 return soc->ops->misc_ops->hl_tdls_flag_reset(vdev, flag); 281 282 return; 283 } 284 285 /** 286 * cdp_get_opmode() - get vdev operation mode 287 * @soc - data path soc handle 288 * @vdev - virtual interface instance 289 * 290 * Return virtual device operational mode 291 * op_mode_ap, 292 * op_mode_ibss, 293 * op_mode_sta, 294 * op_mode_monitor, 295 * op_mode_ocb, 296 * 297 * return interface id 298 * 0 unknown interface 299 */ 300 static inline int 301 cdp_get_opmode(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) 302 { 303 if (!soc || !soc->ops || !soc->ops->misc_ops) { 304 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 305 "%s invalid instance", __func__); 306 return 0; 307 } 308 309 if (soc->ops->misc_ops->get_opmode) 310 return soc->ops->misc_ops->get_opmode(vdev); 311 return 0; 312 } 313 314 /** 315 * cdp_get_vdev_id() - get vdev id 316 * @soc - data path soc handle 317 * @vdev - virtual interface instance 318 * 319 * get virtual interface id 320 * 321 * return interface id 322 * 0 unknown interface 323 */ 324 static inline uint16_t 325 cdp_get_vdev_id(ol_txrx_soc_handle soc, struct cdp_vdev *vdev) 326 { 327 if (!soc || !soc->ops || !soc->ops->misc_ops) { 328 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 329 "%s invalid instance", __func__); 330 return 0; 331 } 332 333 if (soc->ops->misc_ops->get_vdev_id) 334 return soc->ops->misc_ops->get_vdev_id(vdev); 335 return 0; 336 } 337 338 /** 339 * cdp_bad_peer_txctl_set_setting() - TBD 340 * @soc - data path soc handle 341 * @pdev - data path device instance 342 * @enable - 343 * @period - 344 * @txq_limit - 345 * 346 * TBD 347 * 348 * Return: none 349 */ 350 static inline void 351 cdp_bad_peer_txctl_set_setting(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, 352 int enable, int period, int txq_limit) 353 { 354 if (!soc || !soc->ops || !soc->ops->misc_ops) { 355 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 356 "%s invalid instance", __func__); 357 return; 358 } 359 360 if (soc->ops->misc_ops->bad_peer_txctl_set_setting) 361 return soc->ops->misc_ops->bad_peer_txctl_set_setting(pdev, 362 enable, period, txq_limit); 363 return; 364 } 365 366 /** 367 * cdp_bad_peer_txctl_update_threshold() - TBD 368 * @soc - data path soc handle 369 * @pdev - data path device instance 370 * @level - 371 * @tput_thresh - 372 * @tx_limit - 373 * 374 * TBD 375 * 376 * Return: none 377 */ 378 static inline void 379 cdp_bad_peer_txctl_update_threshold(ol_txrx_soc_handle soc, 380 struct cdp_pdev *pdev, 381 int level, int tput_thresh, int tx_limit) 382 { 383 if (!soc || !soc->ops || !soc->ops->misc_ops) { 384 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 385 "%s invalid instance", __func__); 386 return; 387 } 388 389 if (soc->ops->misc_ops->bad_peer_txctl_update_threshold) 390 return soc->ops->misc_ops->bad_peer_txctl_update_threshold( 391 pdev, level, tput_thresh, tx_limit); 392 return; 393 } 394 395 /** 396 * cdp_mark_first_wakeup_packet() - set flag to indicate that 397 * fw is compatible for marking first packet after wow wakeup 398 * @soc - data path soc handle 399 * @value: 1 for enabled/ 0 for disabled 400 * 401 * Return: None 402 */ 403 static inline void cdp_mark_first_wakeup_packet(ol_txrx_soc_handle soc, 404 uint8_t value) 405 { 406 if (!soc || !soc->ops || !soc->ops->misc_ops) { 407 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 408 "%s invalid instance", __func__); 409 return; 410 } 411 412 if (soc->ops->misc_ops->mark_first_wakeup_packet) 413 return soc->ops->misc_ops->mark_first_wakeup_packet(value); 414 return; 415 } 416 417 418 /** 419 * cds_update_mac_id() - update mac_id for vdev 420 * @soc - data path soc handle 421 * @vdev_id: vdev id 422 * @mac_id: mac id 423 * 424 * Return: none 425 */ 426 static inline void cdp_update_mac_id(void *psoc, uint8_t vdev_id, 427 uint8_t mac_id) 428 { 429 ol_txrx_soc_handle soc = psoc; 430 431 if (!soc || !soc->ops || !soc->ops->misc_ops) { 432 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 433 "%s invalid instance", __func__); 434 return; 435 } 436 437 if (soc->ops->misc_ops->update_mac_id) 438 return soc->ops->misc_ops->update_mac_id(vdev_id, mac_id); 439 return; 440 } 441 442 /** 443 * cdp_flush_rx_frames() - flush cached rx frames 444 * @soc - data path soc handle 445 * @peer: peer 446 * @drop: set flag to drop frames 447 * 448 * Return: None 449 */ 450 static inline void cdp_flush_rx_frames(ol_txrx_soc_handle soc, void *peer, 451 bool drop) 452 { 453 if (!soc || !soc->ops || !soc->ops->misc_ops) { 454 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 455 "%s invalid instance", __func__); 456 return; 457 } 458 459 if (soc->ops->misc_ops->flush_rx_frames) 460 return soc->ops->misc_ops->flush_rx_frames(peer, drop); 461 return; 462 } 463 464 /* 465 * cdp_get_intra_bss_fwd_pkts_count() - to get the total tx and rx packets 466 * that has been forwarded from txrx layer without going to upper layers. 467 * @vdev_id: vdev id 468 * @fwd_tx_packets: pointer to forwarded tx packets count parameter 469 * @fwd_rx_packets: pointer to forwarded rx packets count parameter 470 * 471 * Return: status -> A_OK - success, A_ERROR - failure 472 */ 473 static inline A_STATUS cdp_get_intra_bss_fwd_pkts_count( 474 ol_txrx_soc_handle soc, uint8_t vdev_id, 475 uint64_t *fwd_tx_packets, uint64_t *fwd_rx_packets) 476 { 477 if (!soc || !soc->ops || !soc->ops->misc_ops) { 478 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 479 "%s invalid instance", __func__); 480 return 0; 481 } 482 483 if (soc->ops->misc_ops->get_intra_bss_fwd_pkts_count) 484 return soc->ops->misc_ops->get_intra_bss_fwd_pkts_count( 485 vdev_id, fwd_tx_packets, fwd_rx_packets); 486 487 return 0; 488 } 489 490 /** 491 * cdp_pkt_log_init() - API to initialize packet log 492 * @handle: pdev handle 493 * @scn: HIF context 494 * 495 * Return: void 496 */ 497 static inline void cdp_pkt_log_init(ol_txrx_soc_handle soc, 498 struct cdp_pdev *pdev, void *scn) 499 { 500 if (!soc || !soc->ops || !soc->ops->misc_ops) { 501 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 502 "%s invalid instance", __func__); 503 return; 504 } 505 506 if (soc->ops->misc_ops->pkt_log_init) 507 return soc->ops->misc_ops->pkt_log_init(pdev, scn); 508 509 return; 510 } 511 512 /** 513 * cdp_pkt_log_con_service() - API to connect packet log service 514 * @handle: pdev handle 515 * @scn: HIF context 516 * 517 * Return: void 518 */ 519 static inline void cdp_pkt_log_con_service(ol_txrx_soc_handle soc, 520 struct cdp_pdev *pdev, void *scn) 521 { 522 if (!soc || !soc->ops || !soc->ops->misc_ops) { 523 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 524 "%s invalid instance", __func__); 525 return; 526 } 527 528 if (soc->ops->misc_ops->pkt_log_con_service) 529 return soc->ops->misc_ops->pkt_log_con_service(pdev, scn); 530 531 return; 532 } 533 #endif /* _CDP_TXRX_MISC_H_ */ 534