blob: 58e34e5dcebf1786fc3c01a9aa64d544c6d4d738 [file] [log] [blame]
/* Copyright (c) 2019 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_ETH_H_
#define _IPA_ETH_H_
#include <linux/fs.h>
#include <linux/stat.h>
#include <linux/types.h>
#include <linux/bitops.h>
#include <linux/debugfs.h>
#include <linux/ipc_logging.h>
#include <linux/netdevice.h>
#include <linux/netdev_features.h>
#include <linux/msm_ipa.h>
#include <linux/msm_gsi.h>
#define IPA_ETH_API_VER 1
/**
* enum ipa_eth_dev_features - Features supported by an ethernet device or
* driver that may be requested via offload APIs
* @IPA_ETH_DEV_F_L2_CSUM_BIT: Ethernet L2 checksum offload
* @IPA_ETH_DEV_F_L3_CSUM_BIT: Ethernet L2 checksum offload
* @IPA_ETH_DEV_F_TCP_CSUM_BIT: TCP checksum offload
* @IPA_ETH_DEV_F_UDP_CSUM_BIT: UDP checksum offload
* @IPA_ETH_DEV_F_LSO_BIT: Large Send Offload / TCP Segmentation Offload
* @IPA_ETH_DEV_F_LRO_BIT: Large Receive Offload / Receive Side Coalescing
* @IPA_ETH_DEV_F_VLAN_BIT: VLAN Offload
* @IPA_ETH_DEV_F_MODC_BIT: Counter based event moderation
* @IPA_ETH_DEV_F_MODT_BIT: Timer based event moderation
*
* Ethernet hardware features represented as bit numbers below are used in
* IPA_ETH_DEV_F_* feature flags that are to be used in offload APIs.
*/
enum ipa_eth_dev_features {
IPA_ETH_DEV_F_L2_CSUM_BIT,
IPA_ETH_DEV_F_L3_CSUM_BIT,
IPA_ETH_DEV_F_TCP_CSUM_BIT,
IPA_ETH_DEV_F_UDP_CSUM_BIT,
IPA_ETH_DEV_F_LSO_BIT,
IPA_ETH_DEV_F_LRO_BIT,
IPA_ETH_DEV_F_VLAN_BIT,
IPA_ETH_DEV_F_MODC_BIT,
IPA_ETH_DEV_F_MODT_BIT,
};
#define ipa_eth_dev_f(f) BIT(IPA_ETH_DEV_F_##f##_BIT)
#define IPA_ETH_DEV_F_L2_CSUM ipa_eth_dev_f(L2_CSUM)
#define IPA_ETH_DEV_F_L3_CSUM ipa_eth_dev_f(L3_CSUM)
#define IPA_ETH_DEV_F_TCP_CSUM ipa_eth_dev_f(TCP_CSUM)
#define IPA_ETH_DEV_F_UDP_CSUM ipa_eth_dev_f(UDP_CSUM)
#define IPA_ETH_DEV_F_LSO ipa_eth_dev_f(LSO)
#define IPA_ETH_DEV_F_LRO ipa_eth_dev_f(LRO)
#define IPA_ETH_DEV_F_VLAN ipa_eth_dev_f(VLAN)
#define IPA_ETH_DEV_F_MODC ipa_eth_dev_f(MODC)
#define IPA_ETH_DEV_F_MODT ipa_eth_dev_f(MODT)
/**
* enum ipa_eth_dev_events - Events supported by an ethernet device that may be
* requested via offload APIs
* @IPA_ETH_DEV_EV_RX_INT_BIT: Rx interrupt
* @IPA_ETH_DEV_EV_TX_INT_BIT: Tx interrupt
* @IPA_ETH_DEV_EV_RX_PTR_BIT: Rx (head) pointer write-back
* @IPA_ETH_DEV_EV_TX_PTR_BIT: Tx (head) pointer write-back
*/
enum ipa_eth_dev_events {
IPA_ETH_DEV_EV_RX_INT_BIT,
IPA_ETH_DEV_EV_TX_INT_BIT,
IPA_ETH_DEV_EV_RX_PTR_BIT,
IPA_ETH_DEV_EV_TX_PTR_BIT
};
#define ipa_eth_dev_ev(ev) BIT(IPA_ETH_DEV_EV_##ev##_BIT)
#define IPA_ETH_DEV_EV_RX_INT ipa_eth_dev_ev(RX_INT)
#define IPA_ETH_DEV_EV_TX_INT ipa_eth_dev_ev(TX_INT)
#define IPA_ETH_DEV_EV_RX_PTR ipa_eth_dev_ev(RX_PTR)
#define IPA_ETH_DEV_EV_TX_PTR ipa_eth_dev_ev(TX_PTR)
/**
* enum ipa_eth_channel_dir - Direction of a ring / channel
* @IPA_ETH_CH_DIR_RX: Traffic flowing from device to IPA
* @IPA_ETH_CH_DIR_TX: Traffic flowing from IPA to device
*/
enum ipa_eth_channel_dir {
IPA_ETH_CH_DIR_RX,
IPA_ETH_CH_DIR_TX,
};
#define IPA_ETH_DIR_RX IPA_ETH_CH_DIR_RX
#define IPA_ETH_DIR_TX IPA_ETH_CH_DIR_TX
/**
* enum ipa_eth_offload_state - Offload state of an ethernet device
* @IPA_ETH_OF_ST_DEINITED: No offload path resources are allocated
* @IPA_ETH_OF_ST_INITED: Offload path resources are allocated, but not started
* @IPA_ETH_OF_ST_STARTED: Offload path is started and ready to handle traffic
* @IPA_ETH_OF_ST_ERROR: One or more offload path components are in error state
* @IPA_ETH_OF_ST_RECOVERY: Offload path is attempting to recover from error
*/
enum ipa_eth_offload_state {
IPA_ETH_OF_ST_DEINITED = 0,
IPA_ETH_OF_ST_INITED,
IPA_ETH_OF_ST_STARTED,
IPA_ETH_OF_ST_ERROR,
IPA_ETH_OF_ST_RECOVERY,
IPA_ETH_OF_ST_MAX,
};
/**
* enum ipa_eth_offload_state - States of the network interface
* @IPA_ETH_IF_ST_UP: Network interface is up in software/Linux
* @IPA_ETH_IF_ST_LOWER_UP: Network interface PHY link is up / cable connected
*/
enum ipa_eth_interface_states {
IPA_ETH_IF_ST_UP,
IPA_ETH_IF_ST_LOWER_UP,
IPA_ETH_IF_ST_MAX,
};
struct ipa_eth_device;
struct ipa_eth_net_driver;
/**
* struct ipa_eth_resource - Memory based resource info
* @size: Size of the memory accessible
* @vaddr: Kernel mapped address of the resource
* @daddr: DMA address of the resource
* @paddr: Physical address of the resource
*/
struct ipa_eth_resource {
size_t size;
void *vaddr;
dma_addr_t daddr;
phys_addr_t paddr;
};
/**
* struct ipa_eth_channel - Represents a network device channel
* @nd_priv: Private field for use by network driver
* @events: Events supported by the channel
* @features: Features enabled in the channel
* @direction: Channel direction
* @queue: Network device queue/ring number
* @desc_size: Size of each descriptor
* @desc_count: Number of descriptors in the ring
* @desc_mem: Descriptor ring memory base
* @buff_size: Size of each data buffer
* @buff_count: Number of data buffers
* @buff_mem: Data buffer memory base
* @od_priv: Private field for use by offload driver
* @eth_dev: Associated ipa_eth_device
* @ipa_client: IPA client type enum to be used for the channel
* @ipa_ep_num: IPA endpoint number configured for the client type
* @process_skb: Callback to be called for processing IPA exception
* packets received from the IPA endpoint
* @ipa_priv: Private field to be used by offload subsystem
* @exception_total: Total number of exception packets received
* @exception_drops: Total number of dropped exception packets
* @exception_loopback: Total number of exception packets looped back
* into IPA
*/
struct ipa_eth_channel {
/* fields managed by network driver */
void *nd_priv;
unsigned long events;
unsigned long features;
enum ipa_eth_channel_dir direction;
int queue;
u16 desc_size;
u32 desc_count;
struct ipa_eth_resource desc_mem;
u16 buff_size;
u32 buff_count;
struct ipa_eth_resource buff_mem;
/* fields managed by offload driver */
void *od_priv;
struct ipa_eth_device *eth_dev;
enum ipa_client_type ipa_client;
int ipa_ep_num;
int (*process_skb)(struct ipa_eth_channel *ch, struct sk_buff *skb);
/* fields managed by offload subsystem */
void *ipa_priv;
u64 exception_total;
u64 exception_drops;
u64 exception_loopback;
};
#define IPA_ETH_CH_IS_RX(ch) ((ch)->direction == IPA_ETH_CH_DIR_RX)
#define IPA_ETH_CH_IS_TX(ch) ((ch)->direction == IPA_ETH_CH_DIR_TX)
/**
* struct ipa_eth_device - Represents an ethernet device
* @net_dev: Netdev registered by the network driver
* @nd_priv: Private field for use by network driver
* @ch_rx: Rx channel allocated for the offload path
* @ch_tx: Tx channel allocated for the offload path
* @od_priv: Private field for use by offload driver
* @device_list: Entry in the global offload device list
* @bus_device_list: Entry in the per-bus offload device list
* @of_state: Offload state of the device
* @dev: Pointer to struct device
* @nd: IPA offload net driver associated with the device
* @od: IPA offload driver that is managing the device
* @netdevice_nb: Notifier block for receiving netdev events from the
* network device (to monitor link state changes)
* @init: Allowed to initialize offload path for the device
* @start: Allowed to start offload data path for the device
* @if_state: Interface state - one or more bit numbers IPA_ETH_IF_ST_*
* @pm_handle: IPA PM client handle for the device
* @bus_priv: Private field for use by offload subsystem bus layer
* @ipa_priv: Private field for use by offload subsystem
* @debugfs: Debugfs root for the device
* @refresh: Work struct used to perform device refresh
*/
struct ipa_eth_device {
/* fields managed by the network driver */
struct net_device *net_dev;
void *nd_priv;
/* fields managed by offload driver */
struct ipa_eth_channel *ch_rx;
struct ipa_eth_channel *ch_tx;
void *od_priv;
/* fields managed by offload subsystem */
struct list_head device_list;
struct list_head bus_device_list;
enum ipa_eth_offload_state of_state;
struct device *dev;
struct ipa_eth_net_driver *nd;
struct ipa_eth_offload_driver *od;
struct notifier_block netdevice_nb;
bool init;
bool start;
unsigned long if_state;
u32 pm_handle;
void *bus_priv;
void *ipa_priv;
struct dentry *debugfs;
struct work_struct refresh;
};
/**
* struct ipa_eth_net_ops - Network device operations required for IPA offload
*/
struct ipa_eth_net_ops {
/**
* .open_device() - Initialize the network device if needed before
* channels and events are configured.
* @eth_dev: Device to initialize
*
* Typically this is API is functionally equivalent to .ndo_open()
*
* Return: 0 on success, negative errno otherwise
*/
int (*open_device)(struct ipa_eth_device *eth_dev);
/**
* .close_device() Deinitialize the device if required
* @eth_dev: Device to deinitialize
*
* This is called when the offload data path is deinitialized and the
* offload subsystem do not see any offload drivers registered to
* handle the device anymore. Typically the device is maintained in
* the initialized state until both Linux and IPA data paths are
* deinitialized.
*
* Return: 0 on success, negative errno otherwise
*/
void (*close_device)(struct ipa_eth_device *eth_dev);
/**
* .request_channel() - Allocate a channel/ring for IPA offload data
* path to use
* @eth_dev: Device from which to allocate channel
* @dir: Requested channel direction
* @events: Device events requested for the channel. Value is zero or
* more IPA_ETH_DEV_EV_* flags.
* @features: Device featured requested for the channel. Value is zero
* or more IPA_ETH_DEV_F_* feature flags.
*
* Arguments @dir, @features and @events are used to inform the network
* driver about the capabilities of the offload subsystem/driver. The
* API implementation may choose to allocate a channel with only a
* subset of capablities enabled. Caller of this API need to check the
* corresponding values in returned the channel and proceed only if the
* allocated capability set is acceptable for data path operation.
*
* The allocated channel is expected to be in disabled state with no
* events allocated or enabled.
*
* Return: Channel object pointer, or NULL if the channel allocation
* failed
*/
struct ipa_eth_channel * (*request_channel)(
struct ipa_eth_device *eth_dev, enum ipa_eth_channel_dir dir,
unsigned long events, unsigned long features);
/**
* .release_channel() - Free a channel/ring previously allocated using
* .request_channel()
* @ch: Channel to be freed
*/
void (*release_channel)(struct ipa_eth_channel *ch);
/**
* .enable_channel() - Enable a channel, allowing data to flow
*
* @ch: Channel to be enabled
*
* Return: 0 on success, negative errno otherwise
*/
int (*enable_channel)(struct ipa_eth_channel *ch);
/**
* .disable_channel() - Disable a channel, stopping the data flow
*
* @ch: Channel to be disabled
*
* Return: 0 on success, negative errno otherwise
*/
int (*disable_channel)(struct ipa_eth_channel *ch);
/**
* .request_event() - Allocate an event for a channel
*
* @ch: Channel for which event need to be allocated
* @event: Event to be allocated
* @addr: Address to which the event need to be reported
* @data: Data value to be associated with the event
*
* The allocated event is expected to be unmoderated.
*
* Return: 0 on success, negative errno otherwise
*/
int (*request_event)(struct ipa_eth_channel *ch, unsigned long event,
phys_addr_t addr, u64 data);
/**
* .release_event() - Deallocate a channel event
*
* @ch: Channel for which event need to be deallocated
* @event: Event to be deallocated
*
* Return: 0 on success, negative errno otherwise
*/
void (*release_event)(struct ipa_eth_channel *ch, unsigned long event);
/**
* .enable_event() - Enable a channel event
*
* @ch: Channel for which event need to be enabled
* @event: Event to be enabled
*
* This API is called when IPA or GIC is ready to receive events from
* the network device.
*
* Return: 0 on success, negative errno otherwise
*/
int (*enable_event)(struct ipa_eth_channel *ch, unsigned long event);
/**
* .disable_event() - Disable a channel event
*
* @ch: Channel for which event need to be disabled
* @event: Event to be disabled
*
* Once this API is called, events may no more be reported to IPA/GIC
* although they may still be queued in the device for later delivery.
*
* Return: 0 on success, negative errno otherwise
*/
int (*disable_event)(struct ipa_eth_channel *ch, unsigned long event);
/**
* .moderate_event() - Moderate a channel event
*
* @ch: Channel for which event need to be disabled
* @event: Event to be disabled
* @min_count: Min threshold for counter based moderation
* @max_count: Max threshold for counter based moderation
* @min_usecs: Min microseconds for timer based moderation
* @max_usecs: Max microseconds for timer based moderation
*
* This API enables event moderation when supported by the device. A
* value of 0 in either of the @max_* arguments would disable moderation
* of that specific type. If both types of moderation are enabled, the
* event is triggered with either of them expires.
*
* It is expected from the device/driver to make sure there is always a
* default min_X value for each moderation type such that there would
* be no data stalls or queue overflow when a moderation target is not
* reached.
*
* Return: 0 on success, negative errno otherwise
*/
int (*moderate_event)(struct ipa_eth_channel *ch, unsigned long event,
u64 min_count, u64 max_count,
u64 min_usecs, u64 max_usecs);
/**
* .receive_skb() - Receive an skb from IPA and push it to Linux network
* stack
* @eth_dev: Device to which the skb need to belong
* @skb: Skb to be provided to Linux network stack
*
* When a network packet received by the IPA connected device queue can
* not be routed within IPA, it will be sent to Linux as an exception
* skb. Offload subsystem receives such packets and forwards to this API
* to be provided to Linux network stack to perform the necessary packet
* routing/filtering in the software path.
*
* Network packets received by this API is expected to emerge from the
* device's Linux network interface as it would have, had the packet
* arrived directly to the Linux connected queues.
*
* Return: 0 on success, negative errno otherwise. On error, skb is NOT
* expected to have been freed.
*/
int (*receive_skb)(struct ipa_eth_device *eth_dev,
struct sk_buff *skb);
/**
* .transmit_skb() - Transmit an skb given IPA
* @eth_dev: Device through which the packet need to be transmitted
* @skb: Skb to be transmitted
*
* Return: 0 on success, negative errno otherwise. On error, skb is NOT
* expected to have been freed.
*/
int (*transmit_skb)(struct ipa_eth_device *eth_dev,
struct sk_buff *skb);
};
/**
* struct ipa_eth_net_driver - Network driver to be registered with IPA offload
* subsystem
* @name: Name of the network driver
* @driver: Pointer to the device_driver object embedded within a PCI/plaform
* driver object used by the network driver
* @events: Events supported by the network device
* @features: Capabilities of the network device
* @bus: Pointer to the bus object. Must use &pci_bus_type for PCI and
* &platform_bus_type for platform drivers. This property is used by the
* offload subsystem to deduce the network driver's original pci_driver
* or plaform_driver object from the @driver argument during driver
* registration.
* Beyond registration, the bus type is also used to deduce a pci_dev or
* platform_device object from a `struct device` pointer.
* @ops: Network device operations
* @debugfs: Debugfs directory for the device
*/
struct ipa_eth_net_driver {
const char *name;
struct device_driver *driver;
unsigned long events;
unsigned long features;
struct bus_type *bus;
struct ipa_eth_net_ops *ops;
struct dentry *debugfs;
};
int ipa_eth_register_net_driver(struct ipa_eth_net_driver *nd);
void ipa_eth_unregister_net_driver(struct ipa_eth_net_driver *nd);
/**
* struct ipa_eth_bus_ops - Offload driver callbacks for bus operations
*
* These APIS are implemented by the offload driver for receiving bus level
* notifications like probe, remove, suspend, resume, etc.
*/
struct ipa_eth_bus_ops {
/**
* .probe() - Probe new device for offload ability
* @eth_dev: Device being probed
*
* This API is implemented by the offload driver and called immediately
* after the network driver (PCI/plaform) probe. Offload driver is
* expected to check if the device is compatible with the driver and
* that the driver has enough offload resources for offloading the
* device to IPA.
*
* The API implementation can expect the eth_dev->dev and eth_dev->nd
* to have been already initialized by the offload subsystem. The API
* is expected to perform at least the following:
*
* 1. Ensure the device is compatible with the offload driver. For
* plaform drivers, the .compatible DT property could be used while
* PCI IDs could be used for matching with a PCI device.
* 2. If multiple network devices of the same type can be managed by the
* offload driver, it may attempt to pair @eth_dev with an available
* resource set for a single instance.
* 3. Initialize the network device, typically by calling open_device()
* callback provided by the network driver.
*
* Return: 0 on success, negative errno otherwise
*/
int (*probe)(struct ipa_eth_device *eth_dev);
/**
* .remove() - Handle device removal
* @eth_dev: Device being removed
*
* The API implementation should assume the device to be no more
* physically connected.
*/
void (*remove)(struct ipa_eth_device *eth_dev);
/* dev_pm_ops go here */
};
/**
* struct ipa_eth_offload_link_stats - Stats for each link within an
* offload data path
* @valid: Stats are not available for the link
* @events: Number of events reported to the link
* @frames: Number of frames received by the link
* @packets: Number of packets received by the link
* @octets: Number of bytes received by the link
*/
struct ipa_eth_offload_link_stats {
bool valid;
u64 events;
u64 frames;
u64 packets;
u64 octets;
};
struct ipa_eth_offload_ch_stats {
struct ipa_eth_offload_link_stats ndev;
struct ipa_eth_offload_link_stats host;
struct ipa_eth_offload_link_stats uc;
struct ipa_eth_offload_link_stats gsi;
struct ipa_eth_offload_link_stats ipa;
};
struct ipa_eth_offload_stats {
struct ipa_eth_offload_ch_stats rx;
struct ipa_eth_offload_ch_stats tx;
};
/**
* struct ipa_eth_offload_ops - Offload operations provided by an offload driver
*/
struct ipa_eth_offload_ops {
/**
* .init_tx() - Initialize offload path in Tx direction
*
* Return: 0 on success, negative errno otherwise
*/
int (*init_tx)(struct ipa_eth_device *eth_dev);
/**
* .start_tx() - Start offload path in Tx direction
*
* Return: 0 on success, negative errno otherwise
*/
int (*start_tx)(struct ipa_eth_device *eth_dev);
/**
* .stop_tx() - Stop offload path in Tx direction
*
* Return: 0 on success, negative errno otherwise
*/
int (*stop_tx)(struct ipa_eth_device *eth_dev);
/**
* .deinit_tx() - Deinitialize offload path in Tx direction
*
* Return: 0 on success, negative errno otherwise
*/
int (*deinit_tx)(struct ipa_eth_device *eth_dev);
/**
* .init_rx() - Initialize offload path in Rx direction
*
* Return: 0 on success, negative errno otherwise
*/
int (*init_rx)(struct ipa_eth_device *eth_dev);
/**
* .start_rx() - Start offload path in Rx direction
*
* Return: 0 on success, negative errno otherwise
*/
int (*start_rx)(struct ipa_eth_device *eth_dev);
/**
* .stop_rx() - Stop offload path in Rx direction
*
* Return: 0 on success, negative errno otherwise
*/
int (*stop_rx)(struct ipa_eth_device *eth_dev);
/**
* .deinit_rx() - Deinitialize offload path in Rx direction
*
* Return: 0 on success, negative errno otherwise
*/
int (*deinit_rx)(struct ipa_eth_device *eth_dev);
/**
* .get_stats() - Get offload statistics
*
* Return: 0 on success, negative errno otherwise
*/
int (*get_stats)(struct ipa_eth_device *eth_dev,
struct ipa_eth_offload_stats *stats);
/**
* .clear_stats() - Clear offload statistics
*
* Return: 0 on success, negative errno otherwise
*/
int (*clear_stats)(struct ipa_eth_device *eth_dev);
};
/**
* struct ipa_eth_offload_driver - Offload driver to be registered with the
* offload sub-system
* @driver_list: Entry in the global offload driver list
* @name: Name of the offload driver
* @bus: Supported network device bus type
* @ops: Offload operations
* @bus_ops: Bus level callbacks and operations for the offload driver
* @debugfs: Debugfs directory for the offload driver
*/
struct ipa_eth_offload_driver {
struct list_head driver_list;
const char *name;
struct bus_type *bus;
struct ipa_eth_offload_ops *ops;
struct ipa_eth_bus_ops *bus_ops;
struct dentry *debugfs;
};
int ipa_eth_register_offload_driver(struct ipa_eth_offload_driver *od);
void ipa_eth_unregister_offload_driver(struct ipa_eth_offload_driver *od);
int ipa_eth_ep_init(struct ipa_eth_channel *ch);
int ipa_eth_ep_start(struct ipa_eth_channel *ch);
int ipa_eth_ep_stop(struct ipa_eth_channel *ch);
int ipa_eth_gsi_alloc(struct ipa_eth_channel *ch,
struct gsi_evt_ring_props *gsi_ev_props,
union gsi_evt_scratch *gsi_ev_scratch,
phys_addr_t *gsi_ev_db,
struct gsi_chan_props *gsi_ch_props,
union gsi_channel_scratch *gsi_ch_scratch,
phys_addr_t *gsi_ch_db);
int ipa_eth_gsi_dealloc(struct ipa_eth_channel *ch);
int ipa_eth_gsi_ring_evtring(struct ipa_eth_channel *ch, u64 value);
int ipa_eth_gsi_ring_channel(struct ipa_eth_channel *ch, u64 value);
int ipa_eth_gsi_start(struct ipa_eth_channel *ch);
int ipa_eth_gsi_stop(struct ipa_eth_channel *ch);
int ipa_eth_gsi_iommu_pamap(dma_addr_t daddr, phys_addr_t paddr,
size_t size, int prot, bool split);
int ipa_eth_gsi_iommu_vamap(dma_addr_t daddr, void *vaddr,
size_t size, int prot, bool split);
int ipa_eth_gsi_iommu_unmap(dma_addr_t daddr, size_t size, bool split);
/* IPA uC interface for ethernet devices */
enum ipa_eth_uc_op {
IPA_ETH_UC_OP_NOP = 0,
IPA_ETH_UC_OP_CH_SETUP = 1,
IPA_ETH_UC_OP_CH_TEARDOWN = 2,
IPA_ETH_UC_OP_PER_INIT = 3,
IPA_ETH_UC_OP_PER_DEINIT = 4,
IPA_ETH_UC_OP_MAX,
};
enum ipa_eth_uc_resp {
IPA_ETH_UC_RSP_SUCCESS = 0,
IPA_ETH_UC_RSP_MAX_TX_CHANNELS = 1,
IPA_ETH_UC_RSP_TX_RING_OVERRUN_POSSIBILITY = 2,
IPA_ETH_UC_RSP_TX_RING_SET_UP_FAILURE = 3,
IPA_ETH_UC_RSP_TX_RING_PARAMS_UNALIGNED = 4,
IPA_ETH_UC_RSP_UNKNOWN_TX_CHANNEL = 5,
IPA_ETH_UC_RSP_TX_INVALID_FSM_TRANSITION = 6,
IPA_ETH_UC_RSP_TX_FSM_TRANSITION_ERROR = 7,
IPA_ETH_UC_RSP_MAX_RX_CHANNELS = 8,
IPA_ETH_UC_RSP_RX_RING_PARAMS_UNALIGNED = 9,
IPA_ETH_UC_RSP_RX_RING_SET_UP_FAILURE = 10,
IPA_ETH_UC_RSP_UNKNOWN_RX_CHANNEL = 11,
IPA_ETH_UC_RSP_RX_INVALID_FSM_TRANSITION = 12,
IPA_ETH_UC_RSP_RX_FSM_TRANSITION_ERROR = 13,
IPA_ETH_UC_RSP_RX_RING_OVERRUN_POSSIBILITY = 14,
};
int ipa_eth_uc_send_cmd(enum ipa_eth_uc_op op, u32 protocol,
const void *prot_data, size_t datasz);
int ipa_eth_uc_iommu_pamap(dma_addr_t daddr, phys_addr_t paddr,
size_t size, int prot, bool split);
int ipa_eth_uc_iommu_vamap(dma_addr_t daddr, void *vaddr,
size_t size, int prot, bool split);
int ipa_eth_uc_iommu_unmap(dma_addr_t daddr, size_t size, bool split);
/* IPC logging interface */
#define ipa_eth_ipc_do_log(ipcbuf, fmt, args...) \
do { \
void *__buf = (ipcbuf); \
if (__buf) \
ipc_log_string(__buf, " %s:%d " fmt "\n", \
__func__, __LINE__, ## args); \
} while (0)
#define ipa_eth_ipc_log(fmt, args...) \
do { \
void *ipa_eth_get_ipc_logbuf(void); \
ipa_eth_ipc_do_log(ipa_eth_get_ipc_logbuf(), \
fmt, ## args); \
} while (0)
#define ipa_eth_ipc_dbg(fmt, args...) \
do { \
void *ipa_eth_get_ipc_logbuf_dbg(void); \
ipa_eth_ipc_do_log(ipa_eth_get_ipc_logbuf_dbg(), \
fmt, ## args); \
} while (0)
#endif // _IPA_ETH_H_