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_ipa.h 21 * @brief Define the host data path IP Acceleraor API functions 22 */ 23 #ifndef _CDP_TXRX_IPA_H_ 24 #define _CDP_TXRX_IPA_H_ 25 26 #ifdef IPA_OFFLOAD 27 #ifdef CONFIG_IPA_WDI_UNIFIED_API 28 #include <qdf_ipa_wdi3.h> 29 #else 30 #include <qdf_ipa.h> 31 #endif 32 #include <cdp_txrx_cmn.h> 33 #include "cdp_txrx_handle.h" 34 35 /** 36 * cdp_ipa_get_resource() - Get allocated WLAN resources for IPA data path 37 * @soc - data path soc handle 38 * @pdev - device instance pointer 39 * 40 * Get allocated WLAN resources for IPA data path 41 * 42 * return QDF_STATUS_SUCCESS 43 */ 44 static inline QDF_STATUS 45 cdp_ipa_get_resource(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) 46 { 47 if (!soc || !soc->ops || !soc->ops->ipa_ops || !pdev) { 48 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 49 "%s invalid instance", __func__); 50 return QDF_STATUS_E_FAILURE; 51 } 52 53 if (soc->ops->ipa_ops->ipa_get_resource) 54 return soc->ops->ipa_ops->ipa_get_resource(pdev); 55 56 return QDF_STATUS_SUCCESS; 57 } 58 59 /** 60 * cdp_ipa_set_doorbell_paddr() - give IPA db paddr to FW 61 * @soc - data path soc handle 62 * @pdev - device instance pointer 63 * 64 * give IPA db paddr to FW 65 * 66 * return QDF_STATUS_SUCCESS 67 */ 68 static inline QDF_STATUS 69 cdp_ipa_set_doorbell_paddr(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) 70 { 71 if (!soc || !soc->ops || !soc->ops->ipa_ops || !pdev) { 72 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 73 "%s invalid instance", __func__); 74 return QDF_STATUS_E_FAILURE; 75 } 76 77 if (soc->ops->ipa_ops->ipa_set_doorbell_paddr) 78 return soc->ops->ipa_ops->ipa_set_doorbell_paddr(pdev); 79 80 return QDF_STATUS_SUCCESS; 81 } 82 83 /** 84 * cdp_ipa_set_active() - activate/de-ctivate IPA offload path 85 * @soc - data path soc handle 86 * @pdev - device instance pointer 87 * @uc_active - activate or de-activate 88 * @is_tx - toggle tx or rx data path 89 * 90 * activate/de-ctivate IPA offload path 91 * 92 * return QDF_STATUS_SUCCESS 93 */ 94 static inline QDF_STATUS 95 cdp_ipa_set_active(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, 96 bool uc_active, bool is_tx) 97 { 98 if (!soc || !soc->ops || !soc->ops->ipa_ops || !pdev) { 99 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 100 "%s invalid instance", __func__); 101 return QDF_STATUS_E_FAILURE; 102 } 103 104 if (soc->ops->ipa_ops->ipa_set_active) 105 return soc->ops->ipa_ops->ipa_set_active(pdev, uc_active, 106 is_tx); 107 108 return QDF_STATUS_SUCCESS; 109 } 110 111 /** 112 * cdp_ipa_op_response() - event handler from FW 113 * @soc - data path soc handle 114 * @pdev - device instance pointer 115 * @op_msg - event contents from firmware 116 * 117 * event handler from FW 118 * 119 * return QDF_STATUS_SUCCESS 120 */ 121 static inline QDF_STATUS 122 cdp_ipa_op_response(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, 123 uint8_t *op_msg) 124 { 125 if (!soc || !soc->ops || !soc->ops->ipa_ops || !pdev) { 126 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 127 "%s invalid instance", __func__); 128 return QDF_STATUS_E_FAILURE; 129 } 130 131 if (soc->ops->ipa_ops->ipa_op_response) 132 return soc->ops->ipa_ops->ipa_op_response(pdev, op_msg); 133 134 return QDF_STATUS_SUCCESS; 135 } 136 137 /** 138 * cdp_ipa_register_op_cb() - register event handler function pointer 139 * @soc - data path soc handle 140 * @pdev - device instance pointer 141 * @op_cb - event handler callback function pointer 142 * @usr_ctxt - user context to registered 143 * 144 * register event handler function pointer 145 * 146 * return QDF_STATUS_SUCCESS 147 */ 148 static inline QDF_STATUS 149 cdp_ipa_register_op_cb(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, 150 ipa_uc_op_cb_type op_cb, void *usr_ctxt) 151 { 152 if (!soc || !soc->ops || !soc->ops->ipa_ops || !pdev) { 153 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 154 "%s invalid instance", __func__); 155 return QDF_STATUS_E_FAILURE; 156 } 157 158 if (soc->ops->ipa_ops->ipa_register_op_cb) 159 return soc->ops->ipa_ops->ipa_register_op_cb(pdev, op_cb, 160 usr_ctxt); 161 162 return QDF_STATUS_SUCCESS; 163 } 164 165 /** 166 * cdp_ipa_get_stat() - get IPA data path stats from FW 167 * @soc - data path soc handle 168 * @pdev - device instance pointer 169 * 170 * get IPA data path stats from FW async 171 * 172 * return QDF_STATUS_SUCCESS 173 */ 174 static inline QDF_STATUS 175 cdp_ipa_get_stat(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) 176 { 177 if (!soc || !soc->ops || !soc->ops->ipa_ops || !pdev) { 178 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 179 "%s invalid instance", __func__); 180 return QDF_STATUS_E_FAILURE; 181 } 182 183 if (soc->ops->ipa_ops->ipa_get_stat) 184 return soc->ops->ipa_ops->ipa_get_stat(pdev); 185 186 return QDF_STATUS_SUCCESS; 187 } 188 189 /** 190 * cdp_tx_send_ipa_data_frame() - send IPA data frame 191 * @vdev: vdev 192 * @skb: skb 193 * 194 * Return: skb/ NULL is for success 195 */ 196 static inline qdf_nbuf_t cdp_ipa_tx_send_data_frame(ol_txrx_soc_handle soc, 197 struct cdp_vdev *vdev, qdf_nbuf_t skb) 198 { 199 if (!soc || !soc->ops || !soc->ops->ipa_ops || !vdev) { 200 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 201 "%s invalid instance", __func__); 202 return skb; 203 } 204 205 if (soc->ops->ipa_ops->ipa_tx_data_frame) 206 return soc->ops->ipa_ops->ipa_tx_data_frame(vdev, skb); 207 208 return skb; 209 } 210 211 /** 212 * cdp_ipa_set_uc_tx_partition_base() - set tx packet partition base 213 * @pdev: physical device instance 214 * @value: partition base value 215 * 216 * Return: QDF_STATUS 217 */ 218 static inline QDF_STATUS 219 cdp_ipa_set_uc_tx_partition_base(ol_txrx_soc_handle soc, 220 struct cdp_cfg *cfg_pdev, uint32_t value) 221 { 222 if (!soc || !soc->ops || !soc->ops->ipa_ops || !cfg_pdev) { 223 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 224 "%s invalid instance", __func__); 225 return QDF_STATUS_E_FAILURE; 226 } 227 228 if (soc->ops->ipa_ops->ipa_set_uc_tx_partition_base) 229 soc->ops->ipa_ops->ipa_set_uc_tx_partition_base(cfg_pdev, 230 value); 231 232 return QDF_STATUS_SUCCESS; 233 } 234 235 #ifdef FEATURE_METERING 236 /** 237 * cdp_ipa_uc_get_share_stats() - get Tx/Rx byte stats from FW 238 * @pdev: physical device instance 239 * @value: reset stats 240 * 241 * Return: QDF_STATUS 242 */ 243 static inline QDF_STATUS 244 cdp_ipa_uc_get_share_stats(ol_txrx_soc_handle soc, 245 struct cdp_pdev *pdev, uint8_t value) 246 { 247 if (!soc || !soc->ops || !soc->ops->ipa_ops || !pdev) { 248 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 249 "%s invalid instance", __func__); 250 return QDF_STATUS_E_FAILURE; 251 } 252 253 if (soc->ops->ipa_ops->ipa_uc_get_share_stats) 254 return soc->ops->ipa_ops->ipa_uc_get_share_stats(pdev, 255 value); 256 257 return QDF_STATUS_SUCCESS; 258 } 259 260 /** 261 * cdp_ipa_uc_set_quota() - set quota limit to FW 262 * @pdev: physical device instance 263 * @value: quota limit bytes 264 * 265 * Return: QDF_STATUS 266 */ 267 static inline QDF_STATUS 268 cdp_ipa_uc_set_quota(ol_txrx_soc_handle soc, 269 struct cdp_pdev *pdev, uint64_t value) 270 { 271 if (!soc || !soc->ops || !soc->ops->ipa_ops || !pdev) { 272 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 273 "%s invalid instance", __func__); 274 return QDF_STATUS_E_FAILURE; 275 } 276 277 if (soc->ops->ipa_ops->ipa_uc_set_quota) 278 return soc->ops->ipa_ops->ipa_uc_set_quota(pdev, 279 value); 280 281 return QDF_STATUS_SUCCESS; 282 } 283 #endif 284 285 /** 286 * cdp_ipa_enable_autonomy() - Enable autonomy RX data path 287 * @soc: data path soc handle 288 * @pdev: handle to the device instance 289 * 290 * IPA Data path is enabled and resumed. 291 * All autonomy data path elements are ready to deliver packet 292 * All RX packet should routed to IPA_REO ring, then IPA can receive packet 293 * from WLAN 294 * 295 * Return: QDF_STATUS 296 */ 297 static inline QDF_STATUS 298 cdp_ipa_enable_autonomy(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) 299 { 300 if (!soc || !soc->ops || !soc->ops->ipa_ops || !pdev) { 301 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 302 "%s invalid instance", __func__); 303 return QDF_STATUS_E_FAILURE; 304 } 305 306 if (soc->ops->ipa_ops->ipa_enable_autonomy) 307 return soc->ops->ipa_ops->ipa_enable_autonomy(pdev); 308 309 return QDF_STATUS_SUCCESS; 310 } 311 312 /** 313 * cdp_ipa_disable_autonomy() - Disable autonomy RX data path 314 * @soc: data path soc handle 315 * @pdev: handle to the device instance 316 * 317 * IPA Data path is enabled and resumed. 318 * All autonomy datapath elements are ready to deliver packet 319 * All RX packet should routed to IPA_REO ring, then IPA can receive packet 320 * from WLAN 321 * 322 * Return: QDF_STATUS 323 */ 324 static inline QDF_STATUS 325 cdp_ipa_disable_autonomy(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) 326 { 327 if (!soc || !soc->ops || !soc->ops->ipa_ops || !pdev) { 328 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 329 "%s invalid instance", __func__); 330 return QDF_STATUS_E_FAILURE; 331 } 332 if (soc->ops->ipa_ops->ipa_enable_autonomy) 333 return soc->ops->ipa_ops->ipa_disable_autonomy(pdev); 334 335 return QDF_STATUS_SUCCESS; 336 } 337 338 #ifdef CONFIG_IPA_WDI_UNIFIED_API 339 /** 340 * cdp_ipa_setup() - Setup and connect IPA pipes 341 * @soc: data path soc handle 342 * @pdev: handle to the device instance 343 * @ipa_i2w_cb: IPA to WLAN callback 344 * @ipa_w2i_cb: WLAN to IPA callback 345 * @ipa_wdi_meter_notifier_cb: IPA WDI metering callback 346 * @ipa_desc_size: IPA descriptor size 347 * @ipa_priv: handle to the HTT instance 348 * @is_rm_enabled: Is IPA RM enabled or not 349 * @tx_pipe_handle: pointer to Tx pipe handle 350 * @rx_pipe_handle: pointer to Rx pipe handle 351 * @is_smmu_enabled: Is SMMU enabled or not 352 * @sys_in: parameters to setup sys pipe in mcc mode 353 * 354 * Return: QDF_STATUS 355 */ 356 static inline QDF_STATUS 357 cdp_ipa_setup(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, void *ipa_i2w_cb, 358 void *ipa_w2i_cb, void *ipa_wdi_meter_notifier_cb, 359 uint32_t ipa_desc_size, void *ipa_priv, bool is_rm_enabled, 360 uint32_t *tx_pipe_handle, uint32_t *rx_pipe_handle, 361 bool is_smmu_enabled, qdf_ipa_sys_connect_params_t *sys_in) 362 { 363 if (!soc || !soc->ops || !soc->ops->ipa_ops || !pdev) { 364 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 365 "%s invalid instance", __func__); 366 return QDF_STATUS_E_FAILURE; 367 } 368 369 if (soc->ops->ipa_ops->ipa_setup) 370 return soc->ops->ipa_ops->ipa_setup(pdev, ipa_i2w_cb, 371 ipa_w2i_cb, 372 ipa_wdi_meter_notifier_cb, 373 ipa_desc_size, ipa_priv, 374 is_rm_enabled, 375 tx_pipe_handle, 376 rx_pipe_handle, 377 is_smmu_enabled, 378 sys_in); 379 380 return QDF_STATUS_SUCCESS; 381 } 382 #else /* CONFIG_IPA_WDI_UNIFIED_API */ 383 /** 384 * cdp_ipa_setup() - Setup and connect IPA pipes 385 * @soc: data path soc handle 386 * @pdev: handle to the device instance 387 * @ipa_i2w_cb: IPA to WLAN callback 388 * @ipa_w2i_cb: WLAN to IPA callback 389 * @ipa_wdi_meter_notifier_cb: IPA WDI metering callback 390 * @ipa_desc_size: IPA descriptor size 391 * @ipa_priv: handle to the HTT instance 392 * @is_rm_enabled: Is IPA RM enabled or not 393 * @tx_pipe_handle: pointer to Tx pipe handle 394 * @rx_pipe_handle: pointer to Rx pipe handle 395 * 396 * Return: QDF_STATUS 397 */ 398 static inline QDF_STATUS 399 cdp_ipa_setup(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, void *ipa_i2w_cb, 400 void *ipa_w2i_cb, void *ipa_wdi_meter_notifier_cb, 401 uint32_t ipa_desc_size, void *ipa_priv, bool is_rm_enabled, 402 uint32_t *tx_pipe_handle, uint32_t *rx_pipe_handle) 403 { 404 if (!soc || !soc->ops || !soc->ops->ipa_ops || !pdev) { 405 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 406 "%s invalid instance", __func__); 407 return QDF_STATUS_E_FAILURE; 408 } 409 410 if (soc->ops->ipa_ops->ipa_setup) 411 return soc->ops->ipa_ops->ipa_setup(pdev, ipa_i2w_cb, 412 ipa_w2i_cb, 413 ipa_wdi_meter_notifier_cb, 414 ipa_desc_size, ipa_priv, 415 is_rm_enabled, 416 tx_pipe_handle, 417 rx_pipe_handle); 418 419 return QDF_STATUS_SUCCESS; 420 } 421 #endif /* CONFIG_IPA_WDI_UNIFIED_API */ 422 423 /** 424 * cdp_ipa_cleanup() - Disconnect IPA pipes 425 * @soc: data path soc handle 426 * @tx_pipe_handle: Tx pipe handle 427 * @rx_pipe_handle: Rx pipe handle 428 * 429 * Return: QDF_STATUS 430 */ 431 static inline QDF_STATUS 432 cdp_ipa_cleanup(ol_txrx_soc_handle soc, uint32_t tx_pipe_handle, 433 uint32_t rx_pipe_handle) 434 { 435 if (!soc || !soc->ops || !soc->ops->ipa_ops) { 436 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 437 "%s invalid instance", __func__); 438 return QDF_STATUS_E_FAILURE; 439 } 440 441 if (soc->ops->ipa_ops->ipa_cleanup) 442 return soc->ops->ipa_ops->ipa_cleanup(tx_pipe_handle, 443 rx_pipe_handle); 444 445 return QDF_STATUS_SUCCESS; 446 } 447 448 /** 449 * cdp_ipa_setup_iface() - Setup IPA header and register interface 450 * @soc: data path soc handle 451 * @ifname: Interface name 452 * @mac_addr: Interface MAC address 453 * @prod_client: IPA prod client type 454 * @cons_client: IPA cons client type 455 * @session_id: Session ID 456 * @is_ipv6_enabled: Is IPV6 enabled or not 457 * 458 * Return: QDF_STATUS 459 */ 460 static inline QDF_STATUS 461 cdp_ipa_setup_iface(ol_txrx_soc_handle soc, char *ifname, uint8_t *mac_addr, 462 qdf_ipa_client_type_t prod_client, 463 qdf_ipa_client_type_t cons_client, 464 uint8_t session_id, bool is_ipv6_enabled) 465 { 466 if (!soc || !soc->ops || !soc->ops->ipa_ops) { 467 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 468 "%s invalid instance", __func__); 469 return QDF_STATUS_E_FAILURE; 470 } 471 472 if (soc->ops->ipa_ops->ipa_setup_iface) 473 return soc->ops->ipa_ops->ipa_setup_iface(ifname, mac_addr, 474 prod_client, 475 cons_client, 476 session_id, 477 is_ipv6_enabled); 478 479 return QDF_STATUS_SUCCESS; 480 } 481 482 /** 483 * cdp_ipa_cleanup_iface() - Cleanup IPA header and deregister interface 484 * @soc: data path soc handle 485 * @ifname: Interface name 486 * @is_ipv6_enabled: Is IPV6 enabled or not 487 * 488 * Return: QDF_STATUS 489 */ 490 static inline QDF_STATUS 491 cdp_ipa_cleanup_iface(ol_txrx_soc_handle soc, char *ifname, 492 bool is_ipv6_enabled) 493 { 494 if (!soc || !soc->ops || !soc->ops->ipa_ops) { 495 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 496 "%s invalid instance", __func__); 497 return QDF_STATUS_E_FAILURE; 498 } 499 500 if (soc->ops->ipa_ops->ipa_cleanup_iface) 501 return soc->ops->ipa_ops->ipa_cleanup_iface(ifname, 502 is_ipv6_enabled); 503 504 return QDF_STATUS_SUCCESS; 505 } 506 507 /** 508 * cdp_ipa_uc_enable_pipes() - Enable and resume traffic on Tx/Rx pipes 509 * @soc: data path soc handle 510 * @pdev: handle to the device instance 511 * 512 * Return: QDF_STATUS 513 */ 514 static inline QDF_STATUS 515 cdp_ipa_enable_pipes(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) 516 { 517 if (!soc || !soc->ops || !soc->ops->ipa_ops || !pdev) { 518 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 519 "%s invalid instance", __func__); 520 return QDF_STATUS_E_FAILURE; 521 } 522 523 if (soc->ops->ipa_ops->ipa_enable_pipes) 524 return soc->ops->ipa_ops->ipa_enable_pipes(pdev); 525 526 return QDF_STATUS_SUCCESS; 527 } 528 529 /** 530 * cdp_ipa_uc_disable_pipes() - Suspend traffic and disable Tx/Rx pipes 531 * @soc: data path soc handle 532 * @pdev: handle to the device instance 533 * 534 * Return: QDF_STATUS 535 */ 536 static inline QDF_STATUS 537 cdp_ipa_disable_pipes(ol_txrx_soc_handle soc, struct cdp_pdev *pdev) 538 { 539 if (!soc || !soc->ops || !soc->ops->ipa_ops || !pdev) { 540 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 541 "%s invalid instance", __func__); 542 return QDF_STATUS_E_FAILURE; 543 } 544 545 if (soc->ops->ipa_ops->ipa_disable_pipes) 546 return soc->ops->ipa_ops->ipa_disable_pipes(pdev); 547 548 return QDF_STATUS_SUCCESS; 549 } 550 551 /** 552 * cdp_ipa_set_perf_level() - Set IPA clock bandwidth based on data rates 553 * @soc: data path soc handle 554 * @client: WLAN Client ID 555 * @max_supported_bw_mbps: Maximum bandwidth needed (in Mbps) 556 * 557 * Return: 0 on success, negative errno on error 558 */ 559 static inline QDF_STATUS 560 cdp_ipa_set_perf_level(ol_txrx_soc_handle soc, int client, 561 uint32_t max_supported_bw_mbps) 562 { 563 if (!soc || !soc->ops || !soc->ops->ipa_ops) { 564 QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, 565 "%s invalid instance", __func__); 566 return QDF_STATUS_E_FAILURE; 567 } 568 569 if (soc->ops->ipa_ops->ipa_set_perf_level) 570 return soc->ops->ipa_ops->ipa_set_perf_level(client, 571 max_supported_bw_mbps); 572 573 return QDF_STATUS_SUCCESS; 574 } 575 #endif /* IPA_OFFLOAD */ 576 577 #endif /* _CDP_TXRX_IPA_H_ */ 578 579