/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #ifndef _IPA_USB_H_ #define _IPA_USB_H_ enum ipa_usb_teth_prot { IPA_USB_RNDIS = 0, IPA_USB_ECM = 1, IPA_USB_RMNET = 2, IPA_USB_MBIM = 3, IPA_USB_DIAG = 4, IPA_USB_MAX_TETH_PROT_SIZE }; /** * ipa_usb_teth_params - parameters for RDNIS/ECM initialization API * * @host_ethaddr: host Ethernet address in network order * @device_ethaddr: device Ethernet address in network order */ struct ipa_usb_teth_params { u8 host_ethaddr[ETH_ALEN]; u8 device_ethaddr[ETH_ALEN]; }; enum ipa_usb_notify_event { IPA_USB_DEVICE_READY, IPA_USB_REMOTE_WAKEUP, IPA_USB_SUSPEND_COMPLETED }; enum ipa_usb_max_usb_packet_size { IPA_USB_HIGH_SPEED_512B = 512, IPA_USB_SUPER_SPEED_1024B = 1024 }; /** * ipa_usb_teth_prot_params - parameters for connecting RNDIS * * @max_xfer_size_bytes_to_dev: max size of UL packets in bytes * @max_packet_number_to_dev: max number of UL aggregated packets * @max_xfer_size_bytes_to_host: max size of DL packets in bytes * */ struct ipa_usb_teth_prot_params { u32 max_xfer_size_bytes_to_dev; u32 max_packet_number_to_dev; u32 max_xfer_size_bytes_to_host; }; /** * ipa_usb_xdci_connect_params - parameters required to start IN, OUT * channels, and connect RNDIS/ECM/teth_bridge * * @max_pkt_size: high speed or full speed * @ipa_to_usb_xferrscidx: Transfer Resource Index (XferRscIdx) for IN channel. * The hardware-assigned transfer resource index for the * transfer, which was returned in response to the * Start Transfer command. This field is used for * "Update Transfer" command. * Should be 0 =< ipa_to_usb_xferrscidx <= 127. * @ipa_to_usb_xferrscidx_valid: true if xferRscIdx should be updated for IN * channel * @usb_to_ipa_xferrscidx: Transfer Resource Index (XferRscIdx) for OUT channel * Should be 0 =< usb_to_ipa_xferrscidx <= 127. * @usb_to_ipa_xferrscidx_valid: true if xferRscIdx should be updated for OUT * channel * @teth_prot: tethering protocol * @teth_prot_params: parameters for connecting the tethering protocol. * @max_supported_bandwidth_mbps: maximum bandwidth need of the client in Mbps */ struct ipa_usb_xdci_connect_params { enum ipa_usb_max_usb_packet_size max_pkt_size; u8 ipa_to_usb_xferrscidx; bool ipa_to_usb_xferrscidx_valid; u8 usb_to_ipa_xferrscidx; bool usb_to_ipa_xferrscidx_valid; enum ipa_usb_teth_prot teth_prot; struct ipa_usb_teth_prot_params teth_prot_params; u32 max_supported_bandwidth_mbps; }; /** * ipa_usb_xdci_chan_scratch - xDCI protocol SW config area of * channel scratch * * @last_trb_addr_iova: Address (iova LSB - based on alignment restrictions) of * last TRB in queue. Used to identify roll over case * @const_buffer_size: TRB buffer size in KB (similar to IPA aggregation * configuration). Must be aligned to max USB Packet Size. * Should be 1 <= const_buffer_size <= 31. * @depcmd_low_addr: Used to generate "Update Transfer" command * @depcmd_hi_addr: Used to generate "Update Transfer" command. */ struct ipa_usb_xdci_chan_scratch { u16 last_trb_addr_iova; u8 const_buffer_size; u32 depcmd_low_addr; u8 depcmd_hi_addr; }; /** * ipa_usb_xdci_chan_params - xDCI channel related properties * * @client: type of "client" * @ipa_ep_cfg: IPA EP configuration * @keep_ipa_awake: when true, IPA will not be clock gated * @teth_prot: tethering protocol for which the channel is created * @gevntcount_low_addr: GEVNCOUNT low address for event scratch * @gevntcount_hi_addr: GEVNCOUNT high address for event scratch * @dir: channel direction * @xfer_ring_len: length of transfer ring in bytes (must be integral * multiple of transfer element size - 16B for xDCI) * @xfer_ring_base_addr: physical base address of transfer ring. Address must be * aligned to xfer_ring_len rounded to power of two * @xfer_scratch: parameters for xDCI channel scratch * @xfer_ring_base_addr_iova: IO virtual address mapped to xfer_ring_base_addr * @data_buff_base_len: length of data buffer allocated by USB driver * @data_buff_base_addr: physical base address for the data buffer (where TRBs * points) * @data_buff_base_addr_iova: IO virtual address mapped to data_buff_base_addr * */ struct ipa_usb_xdci_chan_params { /* IPA EP params */ enum ipa_client_type client; struct ipa_ep_cfg ipa_ep_cfg; bool keep_ipa_awake; enum ipa_usb_teth_prot teth_prot; /* event ring params */ u32 gevntcount_low_addr; u8 gevntcount_hi_addr; /* transfer ring params */ enum gsi_chan_dir dir; u16 xfer_ring_len; u64 xfer_ring_base_addr; struct ipa_usb_xdci_chan_scratch xfer_scratch; u64 xfer_ring_base_addr_iova; u32 data_buff_base_len; u64 data_buff_base_addr; u64 data_buff_base_addr_iova; }; /** * ipa_usb_chan_out_params - out parameters for channel request * * @clnt_hdl: opaque client handle assigned by IPA to client * @db_reg_phs_addr_lsb: Physical address of doorbell register where the 32 * LSBs of the doorbell value should be written * @db_reg_phs_addr_msb: Physical address of doorbell register where the 32 * MSBs of the doorbell value should be written * */ struct ipa_req_chan_out_params { u32 clnt_hdl; u32 db_reg_phs_addr_lsb; u32 db_reg_phs_addr_msb; }; #ifdef CONFIG_IPA3 /** * ipa_usb_init_teth_prot - Peripheral should call this function to initialize * RNDIS/ECM/teth_bridge/DPL, prior to calling ipa_usb_xdci_connect() * * @usb_teth_type: tethering protocol type * @teth_params: pointer to tethering protocol parameters. * Should be struct ipa_usb_teth_params for RNDIS/ECM, * or NULL for teth_bridge * @ipa_usb_notify_cb: will be called to notify USB driver on certain events * @user_data: cookie used for ipa_usb_notify_cb * * @Return 0 on success, negative on failure */ int ipa_usb_init_teth_prot(enum ipa_usb_teth_prot teth_prot, struct ipa_usb_teth_params *teth_params, int (*ipa_usb_notify_cb)(enum ipa_usb_notify_event, void *), void *user_data); /** * ipa_usb_xdci_connect - Peripheral should call this function to start IN & * OUT xDCI channels, and connect RNDIS/ECM/MBIM/RMNET. * For DPL, only starts IN channel. * * @ul_chan_params: parameters for allocating UL xDCI channel. containing * required info on event and transfer rings, and IPA EP * configuration * @ul_out_params: [out] opaque client handle assigned by IPA to client & DB * registers physical address for UL channel * @dl_chan_params: parameters for allocating DL xDCI channel. containing * required info on event and transfer rings, and IPA EP * configuration * @dl_out_params: [out] opaque client handle assigned by IPA to client & DB * registers physical address for DL channel * @connect_params: handles and scratch params of the required channels, * tethering protocol and the tethering protocol parameters. * * Note: Should not be called from atomic context * * @Return 0 on success, negative on failure */ int ipa_usb_xdci_connect(struct ipa_usb_xdci_chan_params *ul_chan_params, struct ipa_usb_xdci_chan_params *dl_chan_params, struct ipa_req_chan_out_params *ul_out_params, struct ipa_req_chan_out_params *dl_out_params, struct ipa_usb_xdci_connect_params *connect_params); /** * ipa_usb_xdci_disconnect - Peripheral should call this function to stop * IN & OUT xDCI channels * For DPL, only stops IN channel. * * @ul_clnt_hdl: client handle received from ipa_usb_xdci_connect() * for OUT channel * @dl_clnt_hdl: client handle received from ipa_usb_xdci_connect() * for IN channel * @teth_prot: tethering protocol * * Note: Should not be called from atomic context * * @Return 0 on success, negative on failure */ int ipa_usb_xdci_disconnect(u32 ul_clnt_hdl, u32 dl_clnt_hdl, enum ipa_usb_teth_prot teth_prot); /** * ipa_usb_deinit_teth_prot - Peripheral should call this function to deinit * RNDIS/ECM/MBIM/RMNET * * @teth_prot: tethering protocol * * @Return 0 on success, negative on failure */ int ipa_usb_deinit_teth_prot(enum ipa_usb_teth_prot teth_prot); /** * ipa_usb_xdci_suspend - Peripheral should call this function to suspend * IN & OUT or DPL xDCI channels * * @ul_clnt_hdl: client handle previously obtained from * ipa_usb_xdci_connect() for OUT channel * @dl_clnt_hdl: client handle previously obtained from * ipa_usb_xdci_connect() for IN channel * @teth_prot: tethering protocol * @with_remote_wakeup: Does host support remote wakeup? * * Note: Should not be called from atomic context * Note: for DPL, the ul will be ignored as irrelevant * * @Return 0 on success, negative on failure */ int ipa_usb_xdci_suspend(u32 ul_clnt_hdl, u32 dl_clnt_hdl, enum ipa_usb_teth_prot teth_prot, bool with_remote_wakeup); /** * ipa_usb_xdci_resume - Peripheral should call this function to resume * IN & OUT or DPL xDCI channels * * @ul_clnt_hdl: client handle received from ipa_usb_xdci_connect() * for OUT channel * @dl_clnt_hdl: client handle received from ipa_usb_xdci_connect() * for IN channel * @teth_prot: tethering protocol * * Note: Should not be called from atomic context * Note: for DPL, the ul will be ignored as irrelevant * * @Return 0 on success, negative on failure */ int ipa_usb_xdci_resume(u32 ul_clnt_hdl, u32 dl_clnt_hdl, enum ipa_usb_teth_prot teth_prot); #else /* CONFIG_IPA3 */ static inline int ipa_usb_init_teth_prot(enum ipa_usb_teth_prot teth_prot, struct ipa_usb_teth_params *teth_params, int (*ipa_usb_notify_cb)(enum ipa_usb_notify_event, void *), void *user_data) { return -EPERM; } static inline int ipa_usb_xdci_connect( struct ipa_usb_xdci_chan_params *ul_chan_params, struct ipa_usb_xdci_chan_params *dl_chan_params, struct ipa_req_chan_out_params *ul_out_params, struct ipa_req_chan_out_params *dl_out_params, struct ipa_usb_xdci_connect_params *connect_params) { return -EPERM; } static inline int ipa_usb_xdci_disconnect(u32 ul_clnt_hdl, u32 dl_clnt_hdl, enum ipa_usb_teth_prot teth_prot) { return -EPERM; } static inline int ipa_usb_deinit_teth_prot(enum ipa_usb_teth_prot teth_prot) { return -EPERM; } static inline int ipa_usb_xdci_suspend(u32 ul_clnt_hdl, u32 dl_clnt_hdl, enum ipa_usb_teth_prot teth_prot, bool with_remote_wakeup) { return -EPERM; } static inline int ipa_usb_xdci_resume(u32 ul_clnt_hdl, u32 dl_clnt_hdl, enum ipa_usb_teth_prot teth_prot) { return -EPERM; } #endif /* CONFIG_IPA3 */ #endif /* _IPA_USB_H_ */