dpaa2-eth: Move DPAA2 Ethernet driver from staging to drivers/net

The DPAA2 Ethernet driver supports Freescale/NXP SoCs with DPAA2
(DataPath Acceleration Architecture v2). The driver manages
network objects discovered on the fsl-mc bus.

Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Ioana Radulescu
2018-08-29 04:42:40 -05:00
committed by David S. Miller
parent 7f12c8a367
commit 34ff68465a
17 changed files with 13 additions and 29 deletions

View File

@@ -97,4 +97,12 @@ config GIANFAR
source "drivers/net/ethernet/freescale/dpaa/Kconfig"
config FSL_DPAA2_ETH
tristate "Freescale DPAA2 Ethernet"
depends on FSL_MC_BUS && FSL_MC_DPIO
depends on NETDEVICES && ETHERNET
---help---
Ethernet driver for Freescale DPAA2 SoCs, using the
Freescale MC bus driver
endif # NET_VENDOR_FREESCALE

View File

@@ -21,3 +21,5 @@ ucc_geth_driver-objs := ucc_geth.o ucc_geth_ethtool.o
obj-$(CONFIG_FSL_FMAN) += fman/
obj-$(CONFIG_FSL_DPAA_ETH) += dpaa/
obj-$(CONFIG_FSL_DPAA2_ETH) += dpaa2/

View File

@@ -0,0 +1,11 @@
# SPDX-License-Identifier: GPL-2.0
#
# Makefile for the Freescale DPAA2 Ethernet controller
#
obj-$(CONFIG_FSL_DPAA2_ETH) += fsl-dpaa2-eth.o
fsl-dpaa2-eth-objs := dpaa2-eth.o dpaa2-ethtool.o dpni.o
# Needed by the tracing framework
CFLAGS_dpaa2-eth.o := -I$(src)

View File

@@ -0,0 +1,158 @@
/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
/* Copyright 2014-2015 Freescale Semiconductor Inc.
*/
#undef TRACE_SYSTEM
#define TRACE_SYSTEM dpaa2_eth
#if !defined(_DPAA2_ETH_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
#define _DPAA2_ETH_TRACE_H
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include "dpaa2-eth.h"
#include <linux/tracepoint.h>
#define TR_FMT "[%s] fd: addr=0x%llx, len=%u, off=%u"
/* trace_printk format for raw buffer event class */
#define TR_BUF_FMT "[%s] vaddr=%p size=%zu dma_addr=%pad map_size=%zu bpid=%d"
/* This is used to declare a class of events.
* individual events of this type will be defined below.
*/
/* Store details about a frame descriptor */
DECLARE_EVENT_CLASS(dpaa2_eth_fd,
/* Trace function prototype */
TP_PROTO(struct net_device *netdev,
const struct dpaa2_fd *fd),
/* Repeat argument list here */
TP_ARGS(netdev, fd),
/* A structure containing the relevant information we want
* to record. Declare name and type for each normal element,
* name, type and size for arrays. Use __string for variable
* length strings.
*/
TP_STRUCT__entry(
__field(u64, fd_addr)
__field(u32, fd_len)
__field(u16, fd_offset)
__string(name, netdev->name)
),
/* The function that assigns values to the above declared
* fields
*/
TP_fast_assign(
__entry->fd_addr = dpaa2_fd_get_addr(fd);
__entry->fd_len = dpaa2_fd_get_len(fd);
__entry->fd_offset = dpaa2_fd_get_offset(fd);
__assign_str(name, netdev->name);
),
/* This is what gets printed when the trace event is
* triggered.
*/
TP_printk(TR_FMT,
__get_str(name),
__entry->fd_addr,
__entry->fd_len,
__entry->fd_offset)
);
/* Now declare events of the above type. Format is:
* DEFINE_EVENT(class, name, proto, args), with proto and args same as for class
*/
/* Tx (egress) fd */
DEFINE_EVENT(dpaa2_eth_fd, dpaa2_tx_fd,
TP_PROTO(struct net_device *netdev,
const struct dpaa2_fd *fd),
TP_ARGS(netdev, fd)
);
/* Rx fd */
DEFINE_EVENT(dpaa2_eth_fd, dpaa2_rx_fd,
TP_PROTO(struct net_device *netdev,
const struct dpaa2_fd *fd),
TP_ARGS(netdev, fd)
);
/* Tx confirmation fd */
DEFINE_EVENT(dpaa2_eth_fd, dpaa2_tx_conf_fd,
TP_PROTO(struct net_device *netdev,
const struct dpaa2_fd *fd),
TP_ARGS(netdev, fd)
);
/* Log data about raw buffers. Useful for tracing DPBP content. */
TRACE_EVENT(dpaa2_eth_buf_seed,
/* Trace function prototype */
TP_PROTO(struct net_device *netdev,
/* virtual address and size */
void *vaddr,
size_t size,
/* dma map address and size */
dma_addr_t dma_addr,
size_t map_size,
/* buffer pool id, if relevant */
u16 bpid),
/* Repeat argument list here */
TP_ARGS(netdev, vaddr, size, dma_addr, map_size, bpid),
/* A structure containing the relevant information we want
* to record. Declare name and type for each normal element,
* name, type and size for arrays. Use __string for variable
* length strings.
*/
TP_STRUCT__entry(
__field(void *, vaddr)
__field(size_t, size)
__field(dma_addr_t, dma_addr)
__field(size_t, map_size)
__field(u16, bpid)
__string(name, netdev->name)
),
/* The function that assigns values to the above declared
* fields
*/
TP_fast_assign(
__entry->vaddr = vaddr;
__entry->size = size;
__entry->dma_addr = dma_addr;
__entry->map_size = map_size;
__entry->bpid = bpid;
__assign_str(name, netdev->name);
),
/* This is what gets printed when the trace event is
* triggered.
*/
TP_printk(TR_BUF_FMT,
__get_str(name),
__entry->vaddr,
__entry->size,
&__entry->dma_addr,
__entry->map_size,
__entry->bpid)
);
/* If only one event of a certain type needs to be declared, use TRACE_EVENT().
* The syntax is the same as for DECLARE_EVENT_CLASS().
*/
#endif /* _DPAA2_ETH_TRACE_H */
/* This must be outside ifdef _DPAA2_ETH_TRACE_H */
#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH .
#undef TRACE_INCLUDE_FILE
#define TRACE_INCLUDE_FILE dpaa2-eth-trace
#include <trace/define_trace.h>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,412 @@
/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
/* Copyright 2014-2016 Freescale Semiconductor Inc.
* Copyright 2016 NXP
*/
#ifndef __DPAA2_ETH_H
#define __DPAA2_ETH_H
#include <linux/netdevice.h>
#include <linux/if_vlan.h>
#include <linux/fsl/mc.h>
#include <soc/fsl/dpaa2-io.h>
#include <soc/fsl/dpaa2-fd.h>
#include "dpni.h"
#include "dpni-cmd.h"
#include "dpaa2-eth-trace.h"
#define DPAA2_WRIOP_VERSION(x, y, z) ((x) << 10 | (y) << 5 | (z) << 0)
#define DPAA2_ETH_STORE_SIZE 16
/* Maximum number of scatter-gather entries in an ingress frame,
* considering the maximum receive frame size is 64K
*/
#define DPAA2_ETH_MAX_SG_ENTRIES ((64 * 1024) / DPAA2_ETH_RX_BUF_SIZE)
/* Maximum acceptable MTU value. It is in direct relation with the hardware
* enforced Max Frame Length (currently 10k).
*/
#define DPAA2_ETH_MFL (10 * 1024)
#define DPAA2_ETH_MAX_MTU (DPAA2_ETH_MFL - VLAN_ETH_HLEN)
/* Convert L3 MTU to L2 MFL */
#define DPAA2_ETH_L2_MAX_FRM(mtu) ((mtu) + VLAN_ETH_HLEN)
/* Set the taildrop threshold (in bytes) to allow the enqueue of several jumbo
* frames in the Rx queues (length of the current frame is not
* taken into account when making the taildrop decision)
*/
#define DPAA2_ETH_TAILDROP_THRESH (64 * 1024)
/* Buffer quota per queue. Must be large enough such that for minimum sized
* frames taildrop kicks in before the bpool gets depleted, so we compute
* how many 64B frames fit inside the taildrop threshold and add a margin
* to accommodate the buffer refill delay.
*/
#define DPAA2_ETH_MAX_FRAMES_PER_QUEUE (DPAA2_ETH_TAILDROP_THRESH / 64)
#define DPAA2_ETH_NUM_BUFS (DPAA2_ETH_MAX_FRAMES_PER_QUEUE + 256)
#define DPAA2_ETH_REFILL_THRESH DPAA2_ETH_MAX_FRAMES_PER_QUEUE
/* Maximum number of buffers that can be acquired/released through a single
* QBMan command
*/
#define DPAA2_ETH_BUFS_PER_CMD 7
/* Hardware requires alignment for ingress/egress buffer addresses */
#define DPAA2_ETH_TX_BUF_ALIGN 64
#define DPAA2_ETH_RX_BUF_SIZE 2048
#define DPAA2_ETH_SKB_SIZE \
(DPAA2_ETH_RX_BUF_SIZE + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
/* Hardware annotation area in RX/TX buffers */
#define DPAA2_ETH_RX_HWA_SIZE 64
#define DPAA2_ETH_TX_HWA_SIZE 128
/* PTP nominal frequency 1GHz */
#define DPAA2_PTP_CLK_PERIOD_NS 1
/* Due to a limitation in WRIOP 1.0.0, the RX buffer data must be aligned
* to 256B. For newer revisions, the requirement is only for 64B alignment
*/
#define DPAA2_ETH_RX_BUF_ALIGN_REV1 256
#define DPAA2_ETH_RX_BUF_ALIGN 64
/* We are accommodating a skb backpointer and some S/G info
* in the frame's software annotation. The hardware
* options are either 0 or 64, so we choose the latter.
*/
#define DPAA2_ETH_SWA_SIZE 64
/* Must keep this struct smaller than DPAA2_ETH_SWA_SIZE */
struct dpaa2_eth_swa {
struct sk_buff *skb;
struct scatterlist *scl;
int num_sg;
int sgt_size;
};
/* Annotation valid bits in FD FRC */
#define DPAA2_FD_FRC_FASV 0x8000
#define DPAA2_FD_FRC_FAEADV 0x4000
#define DPAA2_FD_FRC_FAPRV 0x2000
#define DPAA2_FD_FRC_FAIADV 0x1000
#define DPAA2_FD_FRC_FASWOV 0x0800
#define DPAA2_FD_FRC_FAICFDV 0x0400
/* Error bits in FD CTRL */
#define DPAA2_FD_RX_ERR_MASK (FD_CTRL_SBE | FD_CTRL_FAERR)
#define DPAA2_FD_TX_ERR_MASK (FD_CTRL_UFD | \
FD_CTRL_SBE | \
FD_CTRL_FSE | \
FD_CTRL_FAERR)
/* Annotation bits in FD CTRL */
#define DPAA2_FD_CTRL_ASAL 0x00020000 /* ASAL = 128B */
/* Frame annotation status */
struct dpaa2_fas {
u8 reserved;
u8 ppid;
__le16 ifpid;
__le32 status;
};
/* Frame annotation status word is located in the first 8 bytes
* of the buffer's hardware annoatation area
*/
#define DPAA2_FAS_OFFSET 0
#define DPAA2_FAS_SIZE (sizeof(struct dpaa2_fas))
/* Timestamp is located in the next 8 bytes of the buffer's
* hardware annotation area
*/
#define DPAA2_TS_OFFSET 0x8
/* Frame annotation egress action descriptor */
#define DPAA2_FAEAD_OFFSET 0x58
struct dpaa2_faead {
__le32 conf_fqid;
__le32 ctrl;
};
#define DPAA2_FAEAD_A2V 0x20000000
#define DPAA2_FAEAD_UPDV 0x00001000
#define DPAA2_FAEAD_UPD 0x00000010
/* Accessors for the hardware annotation fields that we use */
static inline void *dpaa2_get_hwa(void *buf_addr, bool swa)
{
return buf_addr + (swa ? DPAA2_ETH_SWA_SIZE : 0);
}
static inline struct dpaa2_fas *dpaa2_get_fas(void *buf_addr, bool swa)
{
return dpaa2_get_hwa(buf_addr, swa) + DPAA2_FAS_OFFSET;
}
static inline __le64 *dpaa2_get_ts(void *buf_addr, bool swa)
{
return dpaa2_get_hwa(buf_addr, swa) + DPAA2_TS_OFFSET;
}
static inline struct dpaa2_faead *dpaa2_get_faead(void *buf_addr, bool swa)
{
return dpaa2_get_hwa(buf_addr, swa) + DPAA2_FAEAD_OFFSET;
}
/* Error and status bits in the frame annotation status word */
/* Debug frame, otherwise supposed to be discarded */
#define DPAA2_FAS_DISC 0x80000000
/* MACSEC frame */
#define DPAA2_FAS_MS 0x40000000
#define DPAA2_FAS_PTP 0x08000000
/* Ethernet multicast frame */
#define DPAA2_FAS_MC 0x04000000
/* Ethernet broadcast frame */
#define DPAA2_FAS_BC 0x02000000
#define DPAA2_FAS_KSE 0x00040000
#define DPAA2_FAS_EOFHE 0x00020000
#define DPAA2_FAS_MNLE 0x00010000
#define DPAA2_FAS_TIDE 0x00008000
#define DPAA2_FAS_PIEE 0x00004000
/* Frame length error */
#define DPAA2_FAS_FLE 0x00002000
/* Frame physical error */
#define DPAA2_FAS_FPE 0x00001000
#define DPAA2_FAS_PTE 0x00000080
#define DPAA2_FAS_ISP 0x00000040
#define DPAA2_FAS_PHE 0x00000020
#define DPAA2_FAS_BLE 0x00000010
/* L3 csum validation performed */
#define DPAA2_FAS_L3CV 0x00000008
/* L3 csum error */
#define DPAA2_FAS_L3CE 0x00000004
/* L4 csum validation performed */
#define DPAA2_FAS_L4CV 0x00000002
/* L4 csum error */
#define DPAA2_FAS_L4CE 0x00000001
/* Possible errors on the ingress path */
#define DPAA2_FAS_RX_ERR_MASK (DPAA2_FAS_KSE | \
DPAA2_FAS_EOFHE | \
DPAA2_FAS_MNLE | \
DPAA2_FAS_TIDE | \
DPAA2_FAS_PIEE | \
DPAA2_FAS_FLE | \
DPAA2_FAS_FPE | \
DPAA2_FAS_PTE | \
DPAA2_FAS_ISP | \
DPAA2_FAS_PHE | \
DPAA2_FAS_BLE | \
DPAA2_FAS_L3CE | \
DPAA2_FAS_L4CE)
/* Time in milliseconds between link state updates */
#define DPAA2_ETH_LINK_STATE_REFRESH 1000
/* Number of times to retry a frame enqueue before giving up.
* Value determined empirically, in order to minimize the number
* of frames dropped on Tx
*/
#define DPAA2_ETH_ENQUEUE_RETRIES 10
/* Driver statistics, other than those in struct rtnl_link_stats64.
* These are usually collected per-CPU and aggregated by ethtool.
*/
struct dpaa2_eth_drv_stats {
__u64 tx_conf_frames;
__u64 tx_conf_bytes;
__u64 tx_sg_frames;
__u64 tx_sg_bytes;
__u64 tx_reallocs;
__u64 rx_sg_frames;
__u64 rx_sg_bytes;
/* Enqueues retried due to portal busy */
__u64 tx_portal_busy;
};
/* Per-FQ statistics */
struct dpaa2_eth_fq_stats {
/* Number of frames received on this queue */
__u64 frames;
};
/* Per-channel statistics */
struct dpaa2_eth_ch_stats {
/* Volatile dequeues retried due to portal busy */
__u64 dequeue_portal_busy;
/* Number of CDANs; useful to estimate avg NAPI len */
__u64 cdan;
/* Number of frames received on queues from this channel */
__u64 frames;
/* Pull errors */
__u64 pull_err;
};
/* Maximum number of queues associated with a DPNI */
#define DPAA2_ETH_MAX_RX_QUEUES 16
#define DPAA2_ETH_MAX_TX_QUEUES 16
#define DPAA2_ETH_MAX_QUEUES (DPAA2_ETH_MAX_RX_QUEUES + \
DPAA2_ETH_MAX_TX_QUEUES)
#define DPAA2_ETH_MAX_DPCONS 16
enum dpaa2_eth_fq_type {
DPAA2_RX_FQ = 0,
DPAA2_TX_CONF_FQ,
};
struct dpaa2_eth_priv;
struct dpaa2_eth_fq {
u32 fqid;
u32 tx_qdbin;
u16 flowid;
int target_cpu;
struct dpaa2_eth_channel *channel;
enum dpaa2_eth_fq_type type;
void (*consume)(struct dpaa2_eth_priv *priv,
struct dpaa2_eth_channel *ch,
const struct dpaa2_fd *fd,
struct napi_struct *napi,
u16 queue_id);
struct dpaa2_eth_fq_stats stats;
};
struct dpaa2_eth_channel {
struct dpaa2_io_notification_ctx nctx;
struct fsl_mc_device *dpcon;
int dpcon_id;
int ch_id;
struct napi_struct napi;
struct dpaa2_io *dpio;
struct dpaa2_io_store *store;
struct dpaa2_eth_priv *priv;
int buf_count;
struct dpaa2_eth_ch_stats stats;
};
struct dpaa2_eth_hash_fields {
u64 rxnfc_field;
enum net_prot cls_prot;
int cls_field;
int size;
};
/* Driver private data */
struct dpaa2_eth_priv {
struct net_device *net_dev;
u8 num_fqs;
struct dpaa2_eth_fq fq[DPAA2_ETH_MAX_QUEUES];
u8 num_channels;
struct dpaa2_eth_channel *channel[DPAA2_ETH_MAX_DPCONS];
struct dpni_attr dpni_attrs;
u16 dpni_ver_major;
u16 dpni_ver_minor;
u16 tx_data_offset;
struct fsl_mc_device *dpbp_dev;
u16 bpid;
struct iommu_domain *iommu_domain;
bool tx_tstamp; /* Tx timestamping enabled */
bool rx_tstamp; /* Rx timestamping enabled */
u16 tx_qdid;
u16 rx_buf_align;
struct fsl_mc_io *mc_io;
/* Cores which have an affine DPIO/DPCON.
* This is the cpu set on which Rx and Tx conf frames are processed
*/
struct cpumask dpio_cpumask;
/* Standard statistics */
struct rtnl_link_stats64 __percpu *percpu_stats;
/* Extra stats, in addition to the ones known by the kernel */
struct dpaa2_eth_drv_stats __percpu *percpu_extras;
u16 mc_token;
struct dpni_link_state link_state;
bool do_link_poll;
struct task_struct *poll_thread;
/* enabled ethtool hashing bits */
u64 rx_hash_fields;
};
#define DPAA2_RXH_SUPPORTED (RXH_L2DA | RXH_VLAN | RXH_L3_PROTO \
| RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 \
| RXH_L4_B_2_3)
/* default Rx hash options, set during probing */
#define DPAA2_RXH_DEFAULT (RXH_L3_PROTO | RXH_IP_SRC | RXH_IP_DST | \
RXH_L4_B_0_1 | RXH_L4_B_2_3)
#define dpaa2_eth_hash_enabled(priv) \
((priv)->dpni_attrs.num_queues > 1)
/* Required by struct dpni_rx_tc_dist_cfg::key_cfg_iova */
#define DPAA2_CLASSIFIER_DMA_SIZE 256
extern const struct ethtool_ops dpaa2_ethtool_ops;
extern int dpaa2_phc_index;
static inline int dpaa2_eth_cmp_dpni_ver(struct dpaa2_eth_priv *priv,
u16 ver_major, u16 ver_minor)
{
if (priv->dpni_ver_major == ver_major)
return priv->dpni_ver_minor - ver_minor;
return priv->dpni_ver_major - ver_major;
}
/* Hardware only sees DPAA2_ETH_RX_BUF_SIZE, but the skb built around
* the buffer also needs space for its shared info struct, and we need
* to allocate enough to accommodate hardware alignment restrictions
*/
static inline unsigned int dpaa2_eth_buf_raw_size(struct dpaa2_eth_priv *priv)
{
return DPAA2_ETH_SKB_SIZE + priv->rx_buf_align;
}
static inline
unsigned int dpaa2_eth_needed_headroom(struct dpaa2_eth_priv *priv,
struct sk_buff *skb)
{
unsigned int headroom = DPAA2_ETH_SWA_SIZE;
/* For non-linear skbs we have no headroom requirement, as we build a
* SG frame with a newly allocated SGT buffer
*/
if (skb_is_nonlinear(skb))
return 0;
/* If we have Tx timestamping, need 128B hardware annotation */
if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
headroom += DPAA2_ETH_TX_HWA_SIZE;
return headroom;
}
/* Extra headroom space requested to hardware, in order to make sure there's
* no realloc'ing in forwarding scenarios
*/
static inline unsigned int dpaa2_eth_rx_head_room(struct dpaa2_eth_priv *priv)
{
return priv->tx_data_offset + DPAA2_ETH_TX_BUF_ALIGN -
DPAA2_ETH_RX_HWA_SIZE;
}
static int dpaa2_eth_queue_count(struct dpaa2_eth_priv *priv)
{
return priv->dpni_attrs.num_queues;
}
#endif /* __DPAA2_H */

View File

@@ -0,0 +1,280 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/* Copyright 2014-2016 Freescale Semiconductor Inc.
* Copyright 2016 NXP
*/
#include <linux/net_tstamp.h>
#include "dpni.h" /* DPNI_LINK_OPT_* */
#include "dpaa2-eth.h"
/* To be kept in sync with DPNI statistics */
static char dpaa2_ethtool_stats[][ETH_GSTRING_LEN] = {
"[hw] rx frames",
"[hw] rx bytes",
"[hw] rx mcast frames",
"[hw] rx mcast bytes",
"[hw] rx bcast frames",
"[hw] rx bcast bytes",
"[hw] tx frames",
"[hw] tx bytes",
"[hw] tx mcast frames",
"[hw] tx mcast bytes",
"[hw] tx bcast frames",
"[hw] tx bcast bytes",
"[hw] rx filtered frames",
"[hw] rx discarded frames",
"[hw] rx nobuffer discards",
"[hw] tx discarded frames",
"[hw] tx confirmed frames",
};
#define DPAA2_ETH_NUM_STATS ARRAY_SIZE(dpaa2_ethtool_stats)
static char dpaa2_ethtool_extras[][ETH_GSTRING_LEN] = {
/* per-cpu stats */
"[drv] tx conf frames",
"[drv] tx conf bytes",
"[drv] tx sg frames",
"[drv] tx sg bytes",
"[drv] tx realloc frames",
"[drv] rx sg frames",
"[drv] rx sg bytes",
"[drv] enqueue portal busy",
/* Channel stats */
"[drv] dequeue portal busy",
"[drv] channel pull errors",
"[drv] cdan",
};
#define DPAA2_ETH_NUM_EXTRA_STATS ARRAY_SIZE(dpaa2_ethtool_extras)
static void dpaa2_eth_get_drvinfo(struct net_device *net_dev,
struct ethtool_drvinfo *drvinfo)
{
struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
strlcpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
"%u.%u", priv->dpni_ver_major, priv->dpni_ver_minor);
strlcpy(drvinfo->bus_info, dev_name(net_dev->dev.parent->parent),
sizeof(drvinfo->bus_info));
}
static int
dpaa2_eth_get_link_ksettings(struct net_device *net_dev,
struct ethtool_link_ksettings *link_settings)
{
struct dpni_link_state state = {0};
int err = 0;
struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
err = dpni_get_link_state(priv->mc_io, 0, priv->mc_token, &state);
if (err) {
netdev_err(net_dev, "ERROR %d getting link state\n", err);
goto out;
}
/* At the moment, we have no way of interrogating the DPMAC
* from the DPNI side - and for that matter there may exist
* no DPMAC at all. So for now we just don't report anything
* beyond the DPNI attributes.
*/
if (state.options & DPNI_LINK_OPT_AUTONEG)
link_settings->base.autoneg = AUTONEG_ENABLE;
if (!(state.options & DPNI_LINK_OPT_HALF_DUPLEX))
link_settings->base.duplex = DUPLEX_FULL;
link_settings->base.speed = state.rate;
out:
return err;
}
#define DPNI_DYNAMIC_LINK_SET_VER_MAJOR 7
#define DPNI_DYNAMIC_LINK_SET_VER_MINOR 1
static int
dpaa2_eth_set_link_ksettings(struct net_device *net_dev,
const struct ethtool_link_ksettings *link_settings)
{
struct dpni_link_cfg cfg = {0};
struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
int err = 0;
/* If using an older MC version, the DPNI must be down
* in order to be able to change link settings. Taking steps to let
* the user know that.
*/
if (dpaa2_eth_cmp_dpni_ver(priv, DPNI_DYNAMIC_LINK_SET_VER_MAJOR,
DPNI_DYNAMIC_LINK_SET_VER_MINOR) < 0) {
if (netif_running(net_dev)) {
netdev_info(net_dev, "Interface must be brought down first.\n");
return -EACCES;
}
}
cfg.rate = link_settings->base.speed;
if (link_settings->base.autoneg == AUTONEG_ENABLE)
cfg.options |= DPNI_LINK_OPT_AUTONEG;
else
cfg.options &= ~DPNI_LINK_OPT_AUTONEG;
if (link_settings->base.duplex == DUPLEX_HALF)
cfg.options |= DPNI_LINK_OPT_HALF_DUPLEX;
else
cfg.options &= ~DPNI_LINK_OPT_HALF_DUPLEX;
err = dpni_set_link_cfg(priv->mc_io, 0, priv->mc_token, &cfg);
if (err)
/* ethtool will be loud enough if we return an error; no point
* in putting our own error message on the console by default
*/
netdev_dbg(net_dev, "ERROR %d setting link cfg\n", err);
return err;
}
static void dpaa2_eth_get_strings(struct net_device *netdev, u32 stringset,
u8 *data)
{
u8 *p = data;
int i;
switch (stringset) {
case ETH_SS_STATS:
for (i = 0; i < DPAA2_ETH_NUM_STATS; i++) {
strlcpy(p, dpaa2_ethtool_stats[i], ETH_GSTRING_LEN);
p += ETH_GSTRING_LEN;
}
for (i = 0; i < DPAA2_ETH_NUM_EXTRA_STATS; i++) {
strlcpy(p, dpaa2_ethtool_extras[i], ETH_GSTRING_LEN);
p += ETH_GSTRING_LEN;
}
break;
}
}
static int dpaa2_eth_get_sset_count(struct net_device *net_dev, int sset)
{
switch (sset) {
case ETH_SS_STATS: /* ethtool_get_stats(), ethtool_get_drvinfo() */
return DPAA2_ETH_NUM_STATS + DPAA2_ETH_NUM_EXTRA_STATS;
default:
return -EOPNOTSUPP;
}
}
/** Fill in hardware counters, as returned by MC.
*/
static void dpaa2_eth_get_ethtool_stats(struct net_device *net_dev,
struct ethtool_stats *stats,
u64 *data)
{
int i = 0;
int j, k, err;
int num_cnt;
union dpni_statistics dpni_stats;
u64 cdan = 0;
u64 portal_busy = 0, pull_err = 0;
struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
struct dpaa2_eth_drv_stats *extras;
struct dpaa2_eth_ch_stats *ch_stats;
memset(data, 0,
sizeof(u64) * (DPAA2_ETH_NUM_STATS + DPAA2_ETH_NUM_EXTRA_STATS));
/* Print standard counters, from DPNI statistics */
for (j = 0; j <= 2; j++) {
err = dpni_get_statistics(priv->mc_io, 0, priv->mc_token,
j, &dpni_stats);
if (err != 0)
netdev_warn(net_dev, "dpni_get_stats(%d) failed\n", j);
switch (j) {
case 0:
num_cnt = sizeof(dpni_stats.page_0) / sizeof(u64);
break;
case 1:
num_cnt = sizeof(dpni_stats.page_1) / sizeof(u64);
break;
case 2:
num_cnt = sizeof(dpni_stats.page_2) / sizeof(u64);
break;
}
for (k = 0; k < num_cnt; k++)
*(data + i++) = dpni_stats.raw.counter[k];
}
/* Print per-cpu extra stats */
for_each_online_cpu(k) {
extras = per_cpu_ptr(priv->percpu_extras, k);
for (j = 0; j < sizeof(*extras) / sizeof(__u64); j++)
*((__u64 *)data + i + j) += *((__u64 *)extras + j);
}
i += j;
for (j = 0; j < priv->num_channels; j++) {
ch_stats = &priv->channel[j]->stats;
cdan += ch_stats->cdan;
portal_busy += ch_stats->dequeue_portal_busy;
pull_err += ch_stats->pull_err;
}
*(data + i++) = portal_busy;
*(data + i++) = pull_err;
*(data + i++) = cdan;
}
static int dpaa2_eth_get_rxnfc(struct net_device *net_dev,
struct ethtool_rxnfc *rxnfc, u32 *rule_locs)
{
struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
switch (rxnfc->cmd) {
case ETHTOOL_GRXFH:
/* we purposely ignore cmd->flow_type for now, because the
* classifier only supports a single set of fields for all
* protocols
*/
rxnfc->data = priv->rx_hash_fields;
break;
case ETHTOOL_GRXRINGS:
rxnfc->data = dpaa2_eth_queue_count(priv);
break;
default:
return -EOPNOTSUPP;
}
return 0;
}
int dpaa2_phc_index = -1;
EXPORT_SYMBOL(dpaa2_phc_index);
static int dpaa2_eth_get_ts_info(struct net_device *dev,
struct ethtool_ts_info *info)
{
info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE |
SOF_TIMESTAMPING_RX_HARDWARE |
SOF_TIMESTAMPING_RAW_HARDWARE;
info->phc_index = dpaa2_phc_index;
info->tx_types = (1 << HWTSTAMP_TX_OFF) |
(1 << HWTSTAMP_TX_ON);
info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
(1 << HWTSTAMP_FILTER_ALL);
return 0;
}
const struct ethtool_ops dpaa2_ethtool_ops = {
.get_drvinfo = dpaa2_eth_get_drvinfo,
.get_link = ethtool_op_get_link,
.get_link_ksettings = dpaa2_eth_get_link_ksettings,
.set_link_ksettings = dpaa2_eth_set_link_ksettings,
.get_sset_count = dpaa2_eth_get_sset_count,
.get_ethtool_stats = dpaa2_eth_get_ethtool_stats,
.get_strings = dpaa2_eth_get_strings,
.get_rxnfc = dpaa2_eth_get_rxnfc,
.get_ts_info = dpaa2_eth_get_ts_info,
};

View File

@@ -0,0 +1,480 @@
/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
/* Copyright 2013-2015 Freescale Semiconductor Inc.
*/
#ifndef __FSL_DPKG_H_
#define __FSL_DPKG_H_
#include <linux/types.h>
/* Data Path Key Generator API
* Contains initialization APIs and runtime APIs for the Key Generator
*/
/** Key Generator properties */
/**
* Number of masks per key extraction
*/
#define DPKG_NUM_OF_MASKS 4
/**
* Number of extractions per key profile
*/
#define DPKG_MAX_NUM_OF_EXTRACTS 10
/**
* enum dpkg_extract_from_hdr_type - Selecting extraction by header types
* @DPKG_FROM_HDR: Extract selected bytes from header, by offset
* @DPKG_FROM_FIELD: Extract selected bytes from header, by offset from field
* @DPKG_FULL_FIELD: Extract a full field
*/
enum dpkg_extract_from_hdr_type {
DPKG_FROM_HDR = 0,
DPKG_FROM_FIELD = 1,
DPKG_FULL_FIELD = 2
};
/**
* enum dpkg_extract_type - Enumeration for selecting extraction type
* @DPKG_EXTRACT_FROM_HDR: Extract from the header
* @DPKG_EXTRACT_FROM_DATA: Extract from data not in specific header
* @DPKG_EXTRACT_FROM_PARSE: Extract from parser-result;
* e.g. can be used to extract header existence;
* please refer to 'Parse Result definition' section in the parser BG
*/
enum dpkg_extract_type {
DPKG_EXTRACT_FROM_HDR = 0,
DPKG_EXTRACT_FROM_DATA = 1,
DPKG_EXTRACT_FROM_PARSE = 3
};
/**
* struct dpkg_mask - A structure for defining a single extraction mask
* @mask: Byte mask for the extracted content
* @offset: Offset within the extracted content
*/
struct dpkg_mask {
u8 mask;
u8 offset;
};
/* Protocol fields */
/* Ethernet fields */
#define NH_FLD_ETH_DA BIT(0)
#define NH_FLD_ETH_SA BIT(1)
#define NH_FLD_ETH_LENGTH BIT(2)
#define NH_FLD_ETH_TYPE BIT(3)
#define NH_FLD_ETH_FINAL_CKSUM BIT(4)
#define NH_FLD_ETH_PADDING BIT(5)
#define NH_FLD_ETH_ALL_FIELDS (BIT(6) - 1)
/* VLAN fields */
#define NH_FLD_VLAN_VPRI BIT(0)
#define NH_FLD_VLAN_CFI BIT(1)
#define NH_FLD_VLAN_VID BIT(2)
#define NH_FLD_VLAN_LENGTH BIT(3)
#define NH_FLD_VLAN_TYPE BIT(4)
#define NH_FLD_VLAN_ALL_FIELDS (BIT(5) - 1)
#define NH_FLD_VLAN_TCI (NH_FLD_VLAN_VPRI | \
NH_FLD_VLAN_CFI | \
NH_FLD_VLAN_VID)
/* IP (generic) fields */
#define NH_FLD_IP_VER BIT(0)
#define NH_FLD_IP_DSCP BIT(2)
#define NH_FLD_IP_ECN BIT(3)
#define NH_FLD_IP_PROTO BIT(4)
#define NH_FLD_IP_SRC BIT(5)
#define NH_FLD_IP_DST BIT(6)
#define NH_FLD_IP_TOS_TC BIT(7)
#define NH_FLD_IP_ID BIT(8)
#define NH_FLD_IP_ALL_FIELDS (BIT(9) - 1)
/* IPV4 fields */
#define NH_FLD_IPV4_VER BIT(0)
#define NH_FLD_IPV4_HDR_LEN BIT(1)
#define NH_FLD_IPV4_TOS BIT(2)
#define NH_FLD_IPV4_TOTAL_LEN BIT(3)
#define NH_FLD_IPV4_ID BIT(4)
#define NH_FLD_IPV4_FLAG_D BIT(5)
#define NH_FLD_IPV4_FLAG_M BIT(6)
#define NH_FLD_IPV4_OFFSET BIT(7)
#define NH_FLD_IPV4_TTL BIT(8)
#define NH_FLD_IPV4_PROTO BIT(9)
#define NH_FLD_IPV4_CKSUM BIT(10)
#define NH_FLD_IPV4_SRC_IP BIT(11)
#define NH_FLD_IPV4_DST_IP BIT(12)
#define NH_FLD_IPV4_OPTS BIT(13)
#define NH_FLD_IPV4_OPTS_COUNT BIT(14)
#define NH_FLD_IPV4_ALL_FIELDS (BIT(15) - 1)
/* IPV6 fields */
#define NH_FLD_IPV6_VER BIT(0)
#define NH_FLD_IPV6_TC BIT(1)
#define NH_FLD_IPV6_SRC_IP BIT(2)
#define NH_FLD_IPV6_DST_IP BIT(3)
#define NH_FLD_IPV6_NEXT_HDR BIT(4)
#define NH_FLD_IPV6_FL BIT(5)
#define NH_FLD_IPV6_HOP_LIMIT BIT(6)
#define NH_FLD_IPV6_ID BIT(7)
#define NH_FLD_IPV6_ALL_FIELDS (BIT(8) - 1)
/* ICMP fields */
#define NH_FLD_ICMP_TYPE BIT(0)
#define NH_FLD_ICMP_CODE BIT(1)
#define NH_FLD_ICMP_CKSUM BIT(2)
#define NH_FLD_ICMP_ID BIT(3)
#define NH_FLD_ICMP_SQ_NUM BIT(4)
#define NH_FLD_ICMP_ALL_FIELDS (BIT(5) - 1)
/* IGMP fields */
#define NH_FLD_IGMP_VERSION BIT(0)
#define NH_FLD_IGMP_TYPE BIT(1)
#define NH_FLD_IGMP_CKSUM BIT(2)
#define NH_FLD_IGMP_DATA BIT(3)
#define NH_FLD_IGMP_ALL_FIELDS (BIT(4) - 1)
/* TCP fields */
#define NH_FLD_TCP_PORT_SRC BIT(0)
#define NH_FLD_TCP_PORT_DST BIT(1)
#define NH_FLD_TCP_SEQ BIT(2)
#define NH_FLD_TCP_ACK BIT(3)
#define NH_FLD_TCP_OFFSET BIT(4)
#define NH_FLD_TCP_FLAGS BIT(5)
#define NH_FLD_TCP_WINDOW BIT(6)
#define NH_FLD_TCP_CKSUM BIT(7)
#define NH_FLD_TCP_URGPTR BIT(8)
#define NH_FLD_TCP_OPTS BIT(9)
#define NH_FLD_TCP_OPTS_COUNT BIT(10)
#define NH_FLD_TCP_ALL_FIELDS (BIT(11) - 1)
/* UDP fields */
#define NH_FLD_UDP_PORT_SRC BIT(0)
#define NH_FLD_UDP_PORT_DST BIT(1)
#define NH_FLD_UDP_LEN BIT(2)
#define NH_FLD_UDP_CKSUM BIT(3)
#define NH_FLD_UDP_ALL_FIELDS (BIT(4) - 1)
/* UDP-lite fields */
#define NH_FLD_UDP_LITE_PORT_SRC BIT(0)
#define NH_FLD_UDP_LITE_PORT_DST BIT(1)
#define NH_FLD_UDP_LITE_ALL_FIELDS (BIT(2) - 1)
/* UDP-encap-ESP fields */
#define NH_FLD_UDP_ENC_ESP_PORT_SRC BIT(0)
#define NH_FLD_UDP_ENC_ESP_PORT_DST BIT(1)
#define NH_FLD_UDP_ENC_ESP_LEN BIT(2)
#define NH_FLD_UDP_ENC_ESP_CKSUM BIT(3)
#define NH_FLD_UDP_ENC_ESP_SPI BIT(4)
#define NH_FLD_UDP_ENC_ESP_SEQUENCE_NUM BIT(5)
#define NH_FLD_UDP_ENC_ESP_ALL_FIELDS (BIT(6) - 1)
/* SCTP fields */
#define NH_FLD_SCTP_PORT_SRC BIT(0)
#define NH_FLD_SCTP_PORT_DST BIT(1)
#define NH_FLD_SCTP_VER_TAG BIT(2)
#define NH_FLD_SCTP_CKSUM BIT(3)
#define NH_FLD_SCTP_ALL_FIELDS (BIT(4) - 1)
/* DCCP fields */
#define NH_FLD_DCCP_PORT_SRC BIT(0)
#define NH_FLD_DCCP_PORT_DST BIT(1)
#define NH_FLD_DCCP_ALL_FIELDS (BIT(2) - 1)
/* IPHC fields */
#define NH_FLD_IPHC_CID BIT(0)
#define NH_FLD_IPHC_CID_TYPE BIT(1)
#define NH_FLD_IPHC_HCINDEX BIT(2)
#define NH_FLD_IPHC_GEN BIT(3)
#define NH_FLD_IPHC_D_BIT BIT(4)
#define NH_FLD_IPHC_ALL_FIELDS (BIT(5) - 1)
/* SCTP fields */
#define NH_FLD_SCTP_CHUNK_DATA_TYPE BIT(0)
#define NH_FLD_SCTP_CHUNK_DATA_FLAGS BIT(1)
#define NH_FLD_SCTP_CHUNK_DATA_LENGTH BIT(2)
#define NH_FLD_SCTP_CHUNK_DATA_TSN BIT(3)
#define NH_FLD_SCTP_CHUNK_DATA_STREAM_ID BIT(4)
#define NH_FLD_SCTP_CHUNK_DATA_STREAM_SQN BIT(5)
#define NH_FLD_SCTP_CHUNK_DATA_PAYLOAD_PID BIT(6)
#define NH_FLD_SCTP_CHUNK_DATA_UNORDERED BIT(7)
#define NH_FLD_SCTP_CHUNK_DATA_BEGGINING BIT(8)
#define NH_FLD_SCTP_CHUNK_DATA_END BIT(9)
#define NH_FLD_SCTP_CHUNK_DATA_ALL_FIELDS (BIT(10) - 1)
/* L2TPV2 fields */
#define NH_FLD_L2TPV2_TYPE_BIT BIT(0)
#define NH_FLD_L2TPV2_LENGTH_BIT BIT(1)
#define NH_FLD_L2TPV2_SEQUENCE_BIT BIT(2)
#define NH_FLD_L2TPV2_OFFSET_BIT BIT(3)
#define NH_FLD_L2TPV2_PRIORITY_BIT BIT(4)
#define NH_FLD_L2TPV2_VERSION BIT(5)
#define NH_FLD_L2TPV2_LEN BIT(6)
#define NH_FLD_L2TPV2_TUNNEL_ID BIT(7)
#define NH_FLD_L2TPV2_SESSION_ID BIT(8)
#define NH_FLD_L2TPV2_NS BIT(9)
#define NH_FLD_L2TPV2_NR BIT(10)
#define NH_FLD_L2TPV2_OFFSET_SIZE BIT(11)
#define NH_FLD_L2TPV2_FIRST_BYTE BIT(12)
#define NH_FLD_L2TPV2_ALL_FIELDS (BIT(13) - 1)
/* L2TPV3 fields */
#define NH_FLD_L2TPV3_CTRL_TYPE_BIT BIT(0)
#define NH_FLD_L2TPV3_CTRL_LENGTH_BIT BIT(1)
#define NH_FLD_L2TPV3_CTRL_SEQUENCE_BIT BIT(2)
#define NH_FLD_L2TPV3_CTRL_VERSION BIT(3)
#define NH_FLD_L2TPV3_CTRL_LENGTH BIT(4)
#define NH_FLD_L2TPV3_CTRL_CONTROL BIT(5)
#define NH_FLD_L2TPV3_CTRL_SENT BIT(6)
#define NH_FLD_L2TPV3_CTRL_RECV BIT(7)
#define NH_FLD_L2TPV3_CTRL_FIRST_BYTE BIT(8)
#define NH_FLD_L2TPV3_CTRL_ALL_FIELDS (BIT(9) - 1)
#define NH_FLD_L2TPV3_SESS_TYPE_BIT BIT(0)
#define NH_FLD_L2TPV3_SESS_VERSION BIT(1)
#define NH_FLD_L2TPV3_SESS_ID BIT(2)
#define NH_FLD_L2TPV3_SESS_COOKIE BIT(3)
#define NH_FLD_L2TPV3_SESS_ALL_FIELDS (BIT(4) - 1)
/* PPP fields */
#define NH_FLD_PPP_PID BIT(0)
#define NH_FLD_PPP_COMPRESSED BIT(1)
#define NH_FLD_PPP_ALL_FIELDS (BIT(2) - 1)
/* PPPoE fields */
#define NH_FLD_PPPOE_VER BIT(0)
#define NH_FLD_PPPOE_TYPE BIT(1)
#define NH_FLD_PPPOE_CODE BIT(2)
#define NH_FLD_PPPOE_SID BIT(3)
#define NH_FLD_PPPOE_LEN BIT(4)
#define NH_FLD_PPPOE_SESSION BIT(5)
#define NH_FLD_PPPOE_PID BIT(6)
#define NH_FLD_PPPOE_ALL_FIELDS (BIT(7) - 1)
/* PPP-Mux fields */
#define NH_FLD_PPPMUX_PID BIT(0)
#define NH_FLD_PPPMUX_CKSUM BIT(1)
#define NH_FLD_PPPMUX_COMPRESSED BIT(2)
#define NH_FLD_PPPMUX_ALL_FIELDS (BIT(3) - 1)
/* PPP-Mux sub-frame fields */
#define NH_FLD_PPPMUX_SUBFRM_PFF BIT(0)
#define NH_FLD_PPPMUX_SUBFRM_LXT BIT(1)
#define NH_FLD_PPPMUX_SUBFRM_LEN BIT(2)
#define NH_FLD_PPPMUX_SUBFRM_PID BIT(3)
#define NH_FLD_PPPMUX_SUBFRM_USE_PID BIT(4)
#define NH_FLD_PPPMUX_SUBFRM_ALL_FIELDS (BIT(5) - 1)
/* LLC fields */
#define NH_FLD_LLC_DSAP BIT(0)
#define NH_FLD_LLC_SSAP BIT(1)
#define NH_FLD_LLC_CTRL BIT(2)
#define NH_FLD_LLC_ALL_FIELDS (BIT(3) - 1)
/* NLPID fields */
#define NH_FLD_NLPID_NLPID BIT(0)
#define NH_FLD_NLPID_ALL_FIELDS (BIT(1) - 1)
/* SNAP fields */
#define NH_FLD_SNAP_OUI BIT(0)
#define NH_FLD_SNAP_PID BIT(1)
#define NH_FLD_SNAP_ALL_FIELDS (BIT(2) - 1)
/* LLC SNAP fields */
#define NH_FLD_LLC_SNAP_TYPE BIT(0)
#define NH_FLD_LLC_SNAP_ALL_FIELDS (BIT(1) - 1)
/* ARP fields */
#define NH_FLD_ARP_HTYPE BIT(0)
#define NH_FLD_ARP_PTYPE BIT(1)
#define NH_FLD_ARP_HLEN BIT(2)
#define NH_FLD_ARP_PLEN BIT(3)
#define NH_FLD_ARP_OPER BIT(4)
#define NH_FLD_ARP_SHA BIT(5)
#define NH_FLD_ARP_SPA BIT(6)
#define NH_FLD_ARP_THA BIT(7)
#define NH_FLD_ARP_TPA BIT(8)
#define NH_FLD_ARP_ALL_FIELDS (BIT(9) - 1)
/* RFC2684 fields */
#define NH_FLD_RFC2684_LLC BIT(0)
#define NH_FLD_RFC2684_NLPID BIT(1)
#define NH_FLD_RFC2684_OUI BIT(2)
#define NH_FLD_RFC2684_PID BIT(3)
#define NH_FLD_RFC2684_VPN_OUI BIT(4)
#define NH_FLD_RFC2684_VPN_IDX BIT(5)
#define NH_FLD_RFC2684_ALL_FIELDS (BIT(6) - 1)
/* User defined fields */
#define NH_FLD_USER_DEFINED_SRCPORT BIT(0)
#define NH_FLD_USER_DEFINED_PCDID BIT(1)
#define NH_FLD_USER_DEFINED_ALL_FIELDS (BIT(2) - 1)
/* Payload fields */
#define NH_FLD_PAYLOAD_BUFFER BIT(0)
#define NH_FLD_PAYLOAD_SIZE BIT(1)
#define NH_FLD_MAX_FRM_SIZE BIT(2)
#define NH_FLD_MIN_FRM_SIZE BIT(3)
#define NH_FLD_PAYLOAD_TYPE BIT(4)
#define NH_FLD_FRAME_SIZE BIT(5)
#define NH_FLD_PAYLOAD_ALL_FIELDS (BIT(6) - 1)
/* GRE fields */
#define NH_FLD_GRE_TYPE BIT(0)
#define NH_FLD_GRE_ALL_FIELDS (BIT(1) - 1)
/* MINENCAP fields */
#define NH_FLD_MINENCAP_SRC_IP BIT(0)
#define NH_FLD_MINENCAP_DST_IP BIT(1)
#define NH_FLD_MINENCAP_TYPE BIT(2)
#define NH_FLD_MINENCAP_ALL_FIELDS (BIT(3) - 1)
/* IPSEC AH fields */
#define NH_FLD_IPSEC_AH_SPI BIT(0)
#define NH_FLD_IPSEC_AH_NH BIT(1)
#define NH_FLD_IPSEC_AH_ALL_FIELDS (BIT(2) - 1)
/* IPSEC ESP fields */
#define NH_FLD_IPSEC_ESP_SPI BIT(0)
#define NH_FLD_IPSEC_ESP_SEQUENCE_NUM BIT(1)
#define NH_FLD_IPSEC_ESP_ALL_FIELDS (BIT(2) - 1)
/* MPLS fields */
#define NH_FLD_MPLS_LABEL_STACK BIT(0)
#define NH_FLD_MPLS_LABEL_STACK_ALL_FIELDS (BIT(1) - 1)
/* MACSEC fields */
#define NH_FLD_MACSEC_SECTAG BIT(0)
#define NH_FLD_MACSEC_ALL_FIELDS (BIT(1) - 1)
/* GTP fields */
#define NH_FLD_GTP_TEID BIT(0)
/* Supported protocols */
enum net_prot {
NET_PROT_NONE = 0,
NET_PROT_PAYLOAD,
NET_PROT_ETH,
NET_PROT_VLAN,
NET_PROT_IPV4,
NET_PROT_IPV6,
NET_PROT_IP,
NET_PROT_TCP,
NET_PROT_UDP,
NET_PROT_UDP_LITE,
NET_PROT_IPHC,
NET_PROT_SCTP,
NET_PROT_SCTP_CHUNK_DATA,
NET_PROT_PPPOE,
NET_PROT_PPP,
NET_PROT_PPPMUX,
NET_PROT_PPPMUX_SUBFRM,
NET_PROT_L2TPV2,
NET_PROT_L2TPV3_CTRL,
NET_PROT_L2TPV3_SESS,
NET_PROT_LLC,
NET_PROT_LLC_SNAP,
NET_PROT_NLPID,
NET_PROT_SNAP,
NET_PROT_MPLS,
NET_PROT_IPSEC_AH,
NET_PROT_IPSEC_ESP,
NET_PROT_UDP_ENC_ESP, /* RFC 3948 */
NET_PROT_MACSEC,
NET_PROT_GRE,
NET_PROT_MINENCAP,
NET_PROT_DCCP,
NET_PROT_ICMP,
NET_PROT_IGMP,
NET_PROT_ARP,
NET_PROT_CAPWAP_DATA,
NET_PROT_CAPWAP_CTRL,
NET_PROT_RFC2684,
NET_PROT_ICMPV6,
NET_PROT_FCOE,
NET_PROT_FIP,
NET_PROT_ISCSI,
NET_PROT_GTP,
NET_PROT_USER_DEFINED_L2,
NET_PROT_USER_DEFINED_L3,
NET_PROT_USER_DEFINED_L4,
NET_PROT_USER_DEFINED_L5,
NET_PROT_USER_DEFINED_SHIM1,
NET_PROT_USER_DEFINED_SHIM2,
NET_PROT_DUMMY_LAST
};
/**
* struct dpkg_extract - A structure for defining a single extraction
* @type: Determines how the union below is interpreted:
* DPKG_EXTRACT_FROM_HDR: selects 'from_hdr';
* DPKG_EXTRACT_FROM_DATA: selects 'from_data';
* DPKG_EXTRACT_FROM_PARSE: selects 'from_parse'
* @extract: Selects extraction method
* @extract.from_hdr: Used when 'type = DPKG_EXTRACT_FROM_HDR'
* @extract.from_data: Used when 'type = DPKG_EXTRACT_FROM_DATA'
* @extract.from_parse: Used when 'type = DPKG_EXTRACT_FROM_PARSE'
* @extract.from_hdr.prot: Any of the supported headers
* @extract.from_hdr.type: Defines the type of header extraction:
* DPKG_FROM_HDR: use size & offset below;
* DPKG_FROM_FIELD: use field, size and offset below;
* DPKG_FULL_FIELD: use field below
* @extract.from_hdr.field: One of the supported fields (NH_FLD_)
* @extract.from_hdr.size: Size in bytes
* @extract.from_hdr.offset: Byte offset
* @extract.from_hdr.hdr_index: Clear for cases not listed below;
* Used for protocols that may have more than a single
* header, 0 indicates an outer header;
* Supported protocols (possible values):
* NET_PROT_VLAN (0, HDR_INDEX_LAST);
* NET_PROT_MPLS (0, 1, HDR_INDEX_LAST);
* NET_PROT_IP(0, HDR_INDEX_LAST);
* NET_PROT_IPv4(0, HDR_INDEX_LAST);
* NET_PROT_IPv6(0, HDR_INDEX_LAST);
* @extract.from_data.size: Size in bytes
* @extract.from_data.offset: Byte offset
* @extract.from_parse.size: Size in bytes
* @extract.from_parse.offset: Byte offset
* @num_of_byte_masks: Defines the number of valid entries in the array below;
* This is also the number of bytes to be used as masks
* @masks: Masks parameters
*/
struct dpkg_extract {
enum dpkg_extract_type type;
union {
struct {
enum net_prot prot;
enum dpkg_extract_from_hdr_type type;
u32 field;
u8 size;
u8 offset;
u8 hdr_index;
} from_hdr;
struct {
u8 size;
u8 offset;
} from_data;
struct {
u8 size;
u8 offset;
} from_parse;
} extract;
u8 num_of_byte_masks;
struct dpkg_mask masks[DPKG_NUM_OF_MASKS];
};
/**
* struct dpkg_profile_cfg - A structure for defining a full Key Generation
* profile (rule)
* @num_extracts: Defines the number of valid entries in the array below
* @extracts: Array of required extractions
*/
struct dpkg_profile_cfg {
u8 num_extracts;
struct dpkg_extract extracts[DPKG_MAX_NUM_OF_EXTRACTS];
};
#endif /* __FSL_DPKG_H_ */

View File

@@ -0,0 +1,518 @@
/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
/* Copyright 2013-2016 Freescale Semiconductor Inc.
* Copyright 2016 NXP
*/
#ifndef _FSL_DPNI_CMD_H
#define _FSL_DPNI_CMD_H
#include "dpni.h"
/* DPNI Version */
#define DPNI_VER_MAJOR 7
#define DPNI_VER_MINOR 0
#define DPNI_CMD_BASE_VERSION 1
#define DPNI_CMD_ID_OFFSET 4
#define DPNI_CMD(id) (((id) << DPNI_CMD_ID_OFFSET) | DPNI_CMD_BASE_VERSION)
#define DPNI_CMDID_OPEN DPNI_CMD(0x801)
#define DPNI_CMDID_CLOSE DPNI_CMD(0x800)
#define DPNI_CMDID_CREATE DPNI_CMD(0x901)
#define DPNI_CMDID_DESTROY DPNI_CMD(0x900)
#define DPNI_CMDID_GET_API_VERSION DPNI_CMD(0xa01)
#define DPNI_CMDID_ENABLE DPNI_CMD(0x002)
#define DPNI_CMDID_DISABLE DPNI_CMD(0x003)
#define DPNI_CMDID_GET_ATTR DPNI_CMD(0x004)
#define DPNI_CMDID_RESET DPNI_CMD(0x005)
#define DPNI_CMDID_IS_ENABLED DPNI_CMD(0x006)
#define DPNI_CMDID_SET_IRQ DPNI_CMD(0x010)
#define DPNI_CMDID_GET_IRQ DPNI_CMD(0x011)
#define DPNI_CMDID_SET_IRQ_ENABLE DPNI_CMD(0x012)
#define DPNI_CMDID_GET_IRQ_ENABLE DPNI_CMD(0x013)
#define DPNI_CMDID_SET_IRQ_MASK DPNI_CMD(0x014)
#define DPNI_CMDID_GET_IRQ_MASK DPNI_CMD(0x015)
#define DPNI_CMDID_GET_IRQ_STATUS DPNI_CMD(0x016)
#define DPNI_CMDID_CLEAR_IRQ_STATUS DPNI_CMD(0x017)
#define DPNI_CMDID_SET_POOLS DPNI_CMD(0x200)
#define DPNI_CMDID_SET_ERRORS_BEHAVIOR DPNI_CMD(0x20B)
#define DPNI_CMDID_GET_QDID DPNI_CMD(0x210)
#define DPNI_CMDID_GET_TX_DATA_OFFSET DPNI_CMD(0x212)
#define DPNI_CMDID_GET_LINK_STATE DPNI_CMD(0x215)
#define DPNI_CMDID_SET_MAX_FRAME_LENGTH DPNI_CMD(0x216)
#define DPNI_CMDID_GET_MAX_FRAME_LENGTH DPNI_CMD(0x217)
#define DPNI_CMDID_SET_LINK_CFG DPNI_CMD(0x21A)
#define DPNI_CMDID_SET_TX_SHAPING DPNI_CMD(0x21B)
#define DPNI_CMDID_SET_MCAST_PROMISC DPNI_CMD(0x220)
#define DPNI_CMDID_GET_MCAST_PROMISC DPNI_CMD(0x221)
#define DPNI_CMDID_SET_UNICAST_PROMISC DPNI_CMD(0x222)
#define DPNI_CMDID_GET_UNICAST_PROMISC DPNI_CMD(0x223)
#define DPNI_CMDID_SET_PRIM_MAC DPNI_CMD(0x224)
#define DPNI_CMDID_GET_PRIM_MAC DPNI_CMD(0x225)
#define DPNI_CMDID_ADD_MAC_ADDR DPNI_CMD(0x226)
#define DPNI_CMDID_REMOVE_MAC_ADDR DPNI_CMD(0x227)
#define DPNI_CMDID_CLR_MAC_FILTERS DPNI_CMD(0x228)
#define DPNI_CMDID_SET_RX_TC_DIST DPNI_CMD(0x235)
#define DPNI_CMDID_ADD_FS_ENT DPNI_CMD(0x244)
#define DPNI_CMDID_REMOVE_FS_ENT DPNI_CMD(0x245)
#define DPNI_CMDID_CLR_FS_ENT DPNI_CMD(0x246)
#define DPNI_CMDID_GET_STATISTICS DPNI_CMD(0x25D)
#define DPNI_CMDID_GET_QUEUE DPNI_CMD(0x25F)
#define DPNI_CMDID_SET_QUEUE DPNI_CMD(0x260)
#define DPNI_CMDID_GET_TAILDROP DPNI_CMD(0x261)
#define DPNI_CMDID_SET_TAILDROP DPNI_CMD(0x262)
#define DPNI_CMDID_GET_PORT_MAC_ADDR DPNI_CMD(0x263)
#define DPNI_CMDID_GET_BUFFER_LAYOUT DPNI_CMD(0x264)
#define DPNI_CMDID_SET_BUFFER_LAYOUT DPNI_CMD(0x265)
#define DPNI_CMDID_SET_TX_CONFIRMATION_MODE DPNI_CMD(0x266)
#define DPNI_CMDID_SET_CONGESTION_NOTIFICATION DPNI_CMD(0x267)
#define DPNI_CMDID_GET_CONGESTION_NOTIFICATION DPNI_CMD(0x268)
#define DPNI_CMDID_SET_EARLY_DROP DPNI_CMD(0x269)
#define DPNI_CMDID_GET_EARLY_DROP DPNI_CMD(0x26A)
#define DPNI_CMDID_GET_OFFLOAD DPNI_CMD(0x26B)
#define DPNI_CMDID_SET_OFFLOAD DPNI_CMD(0x26C)
/* Macros for accessing command fields smaller than 1byte */
#define DPNI_MASK(field) \
GENMASK(DPNI_##field##_SHIFT + DPNI_##field##_SIZE - 1, \
DPNI_##field##_SHIFT)
#define dpni_set_field(var, field, val) \
((var) |= (((val) << DPNI_##field##_SHIFT) & DPNI_MASK(field)))
#define dpni_get_field(var, field) \
(((var) & DPNI_MASK(field)) >> DPNI_##field##_SHIFT)
struct dpni_cmd_open {
__le32 dpni_id;
};
#define DPNI_BACKUP_POOL(val, order) (((val) & 0x1) << (order))
struct dpni_cmd_set_pools {
/* cmd word 0 */
u8 num_dpbp;
u8 backup_pool_mask;
__le16 pad;
/* cmd word 0..4 */
__le32 dpbp_id[DPNI_MAX_DPBP];
/* cmd word 4..6 */
__le16 buffer_size[DPNI_MAX_DPBP];
};
/* The enable indication is always the least significant bit */
#define DPNI_ENABLE_SHIFT 0
#define DPNI_ENABLE_SIZE 1
struct dpni_rsp_is_enabled {
u8 enabled;
};
struct dpni_rsp_get_irq {
/* response word 0 */
__le32 irq_val;
__le32 pad;
/* response word 1 */
__le64 irq_addr;
/* response word 2 */
__le32 irq_num;
__le32 type;
};
struct dpni_cmd_set_irq_enable {
u8 enable;
u8 pad[3];
u8 irq_index;
};
struct dpni_cmd_get_irq_enable {
__le32 pad;
u8 irq_index;
};
struct dpni_rsp_get_irq_enable {
u8 enabled;
};
struct dpni_cmd_set_irq_mask {
__le32 mask;
u8 irq_index;
};
struct dpni_cmd_get_irq_mask {
__le32 pad;
u8 irq_index;
};
struct dpni_rsp_get_irq_mask {
__le32 mask;
};
struct dpni_cmd_get_irq_status {
__le32 status;
u8 irq_index;
};
struct dpni_rsp_get_irq_status {
__le32 status;
};
struct dpni_cmd_clear_irq_status {
__le32 status;
u8 irq_index;
};
struct dpni_rsp_get_attr {
/* response word 0 */
__le32 options;
u8 num_queues;
u8 num_tcs;
u8 mac_filter_entries;
u8 pad0;
/* response word 1 */
u8 vlan_filter_entries;
u8 pad1;
u8 qos_entries;
u8 pad2;
__le16 fs_entries;
__le16 pad3;
/* response word 2 */
u8 qos_key_size;
u8 fs_key_size;
__le16 wriop_version;
};
#define DPNI_ERROR_ACTION_SHIFT 0
#define DPNI_ERROR_ACTION_SIZE 4
#define DPNI_FRAME_ANN_SHIFT 4
#define DPNI_FRAME_ANN_SIZE 1
struct dpni_cmd_set_errors_behavior {
__le32 errors;
/* from least significant bit: error_action:4, set_frame_annotation:1 */
u8 flags;
};
/* There are 3 separate commands for configuring Rx, Tx and Tx confirmation
* buffer layouts, but they all share the same parameters.
* If one of the functions changes, below structure needs to be split.
*/
#define DPNI_PASS_TS_SHIFT 0
#define DPNI_PASS_TS_SIZE 1
#define DPNI_PASS_PR_SHIFT 1
#define DPNI_PASS_PR_SIZE 1
#define DPNI_PASS_FS_SHIFT 2
#define DPNI_PASS_FS_SIZE 1
struct dpni_cmd_get_buffer_layout {
u8 qtype;
};
struct dpni_rsp_get_buffer_layout {
/* response word 0 */
u8 pad0[6];
/* from LSB: pass_timestamp:1, parser_result:1, frame_status:1 */
u8 flags;
u8 pad1;
/* response word 1 */
__le16 private_data_size;
__le16 data_align;
__le16 head_room;
__le16 tail_room;
};
struct dpni_cmd_set_buffer_layout {
/* cmd word 0 */
u8 qtype;
u8 pad0[3];
__le16 options;
/* from LSB: pass_timestamp:1, parser_result:1, frame_status:1 */
u8 flags;
u8 pad1;
/* cmd word 1 */
__le16 private_data_size;
__le16 data_align;
__le16 head_room;
__le16 tail_room;
};
struct dpni_cmd_set_offload {
u8 pad[3];
u8 dpni_offload;
__le32 config;
};
struct dpni_cmd_get_offload {
u8 pad[3];
u8 dpni_offload;
};
struct dpni_rsp_get_offload {
__le32 pad;
__le32 config;
};
struct dpni_cmd_get_qdid {
u8 qtype;
};
struct dpni_rsp_get_qdid {
__le16 qdid;
};
struct dpni_rsp_get_tx_data_offset {
__le16 data_offset;
};
struct dpni_cmd_get_statistics {
u8 page_number;
};
struct dpni_rsp_get_statistics {
__le64 counter[DPNI_STATISTICS_CNT];
};
struct dpni_cmd_set_link_cfg {
/* cmd word 0 */
__le64 pad0;
/* cmd word 1 */
__le32 rate;
__le32 pad1;
/* cmd word 2 */
__le64 options;
};
#define DPNI_LINK_STATE_SHIFT 0
#define DPNI_LINK_STATE_SIZE 1
struct dpni_rsp_get_link_state {
/* response word 0 */
__le32 pad0;
/* from LSB: up:1 */
u8 flags;
u8 pad1[3];
/* response word 1 */
__le32 rate;
__le32 pad2;
/* response word 2 */
__le64 options;
};
struct dpni_cmd_set_max_frame_length {
__le16 max_frame_length;
};
struct dpni_rsp_get_max_frame_length {
__le16 max_frame_length;
};
struct dpni_cmd_set_multicast_promisc {
u8 enable;
};
struct dpni_rsp_get_multicast_promisc {
u8 enabled;
};
struct dpni_cmd_set_unicast_promisc {
u8 enable;
};
struct dpni_rsp_get_unicast_promisc {
u8 enabled;
};
struct dpni_cmd_set_primary_mac_addr {
__le16 pad;
u8 mac_addr[6];
};
struct dpni_rsp_get_primary_mac_addr {
__le16 pad;
u8 mac_addr[6];
};
struct dpni_rsp_get_port_mac_addr {
__le16 pad;
u8 mac_addr[6];
};
struct dpni_cmd_add_mac_addr {
__le16 pad;
u8 mac_addr[6];
};
struct dpni_cmd_remove_mac_addr {
__le16 pad;
u8 mac_addr[6];
};
#define DPNI_UNICAST_FILTERS_SHIFT 0
#define DPNI_UNICAST_FILTERS_SIZE 1
#define DPNI_MULTICAST_FILTERS_SHIFT 1
#define DPNI_MULTICAST_FILTERS_SIZE 1
struct dpni_cmd_clear_mac_filters {
/* from LSB: unicast:1, multicast:1 */
u8 flags;
};
#define DPNI_DIST_MODE_SHIFT 0
#define DPNI_DIST_MODE_SIZE 4
#define DPNI_MISS_ACTION_SHIFT 4
#define DPNI_MISS_ACTION_SIZE 4
struct dpni_cmd_set_rx_tc_dist {
/* cmd word 0 */
__le16 dist_size;
u8 tc_id;
/* from LSB: dist_mode:4, miss_action:4 */
u8 flags;
__le16 pad0;
__le16 default_flow_id;
/* cmd word 1..5 */
__le64 pad1[5];
/* cmd word 6 */
__le64 key_cfg_iova;
};
/* dpni_set_rx_tc_dist extension (structure of the DMA-able memory at
* key_cfg_iova)
*/
struct dpni_mask_cfg {
u8 mask;
u8 offset;
};
#define DPNI_EFH_TYPE_SHIFT 0
#define DPNI_EFH_TYPE_SIZE 4
#define DPNI_EXTRACT_TYPE_SHIFT 0
#define DPNI_EXTRACT_TYPE_SIZE 4
struct dpni_dist_extract {
/* word 0 */
u8 prot;
/* EFH type stored in the 4 least significant bits */
u8 efh_type;
u8 size;
u8 offset;
__le32 field;
/* word 1 */
u8 hdr_index;
u8 constant;
u8 num_of_repeats;
u8 num_of_byte_masks;
/* Extraction type is stored in the 4 LSBs */
u8 extract_type;
u8 pad[3];
/* word 2 */
struct dpni_mask_cfg masks[4];
};
struct dpni_ext_set_rx_tc_dist {
/* extension word 0 */
u8 num_extracts;
u8 pad[7];
/* words 1..25 */
struct dpni_dist_extract extracts[DPKG_MAX_NUM_OF_EXTRACTS];
};
struct dpni_cmd_get_queue {
u8 qtype;
u8 tc;
u8 index;
};
#define DPNI_DEST_TYPE_SHIFT 0
#define DPNI_DEST_TYPE_SIZE 4
#define DPNI_STASH_CTRL_SHIFT 6
#define DPNI_STASH_CTRL_SIZE 1
#define DPNI_HOLD_ACTIVE_SHIFT 7
#define DPNI_HOLD_ACTIVE_SIZE 1
struct dpni_rsp_get_queue {
/* response word 0 */
__le64 pad0;
/* response word 1 */
__le32 dest_id;
__le16 pad1;
u8 dest_prio;
/* From LSB: dest_type:4, pad:2, flc_stash_ctrl:1, hold_active:1 */
u8 flags;
/* response word 2 */
__le64 flc;
/* response word 3 */
__le64 user_context;
/* response word 4 */
__le32 fqid;
__le16 qdbin;
};
struct dpni_cmd_set_queue {
/* cmd word 0 */
u8 qtype;
u8 tc;
u8 index;
u8 options;
__le32 pad0;
/* cmd word 1 */
__le32 dest_id;
__le16 pad1;
u8 dest_prio;
u8 flags;
/* cmd word 2 */
__le64 flc;
/* cmd word 3 */
__le64 user_context;
};
struct dpni_cmd_set_taildrop {
/* cmd word 0 */
u8 congestion_point;
u8 qtype;
u8 tc;
u8 index;
__le32 pad0;
/* cmd word 1 */
/* Only least significant bit is relevant */
u8 enable;
u8 pad1;
u8 units;
u8 pad2;
__le32 threshold;
};
struct dpni_cmd_get_taildrop {
u8 congestion_point;
u8 qtype;
u8 tc;
u8 index;
};
struct dpni_rsp_get_taildrop {
/* cmd word 0 */
__le64 pad0;
/* cmd word 1 */
/* only least significant bit is relevant */
u8 enable;
u8 pad1;
u8 units;
u8 pad2;
__le32 threshold;
};
struct dpni_rsp_get_api_version {
__le16 major;
__le16 minor;
};
#endif /* _FSL_DPNI_CMD_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,824 @@
/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
/* Copyright 2013-2016 Freescale Semiconductor Inc.
* Copyright 2016 NXP
*/
#ifndef __FSL_DPNI_H
#define __FSL_DPNI_H
#include "dpkg.h"
struct fsl_mc_io;
/**
* Data Path Network Interface API
* Contains initialization APIs and runtime control APIs for DPNI
*/
/** General DPNI macros */
/**
* Maximum number of traffic classes
*/
#define DPNI_MAX_TC 8
/**
* Maximum number of buffer pools per DPNI
*/
#define DPNI_MAX_DPBP 8
/**
* All traffic classes considered; see dpni_set_queue()
*/
#define DPNI_ALL_TCS (u8)(-1)
/**
* All flows within traffic class considered; see dpni_set_queue()
*/
#define DPNI_ALL_TC_FLOWS (u16)(-1)
/**
* Generate new flow ID; see dpni_set_queue()
*/
#define DPNI_NEW_FLOW_ID (u16)(-1)
/**
* Tx traffic is always released to a buffer pool on transmit, there are no
* resources allocated to have the frames confirmed back to the source after
* transmission.
*/
#define DPNI_OPT_TX_FRM_RELEASE 0x000001
/**
* Disables support for MAC address filtering for addresses other than primary
* MAC address. This affects both unicast and multicast. Promiscuous mode can
* still be enabled/disabled for both unicast and multicast. If promiscuous mode
* is disabled, only traffic matching the primary MAC address will be accepted.
*/
#define DPNI_OPT_NO_MAC_FILTER 0x000002
/**
* Allocate policers for this DPNI. They can be used to rate-limit traffic per
* traffic class (TC) basis.
*/
#define DPNI_OPT_HAS_POLICING 0x000004
/**
* Congestion can be managed in several ways, allowing the buffer pool to
* deplete on ingress, taildrop on each queue or use congestion groups for sets
* of queues. If set, it configures a single congestion groups across all TCs.
* If reset, a congestion group is allocated for each TC. Only relevant if the
* DPNI has multiple traffic classes.
*/
#define DPNI_OPT_SHARED_CONGESTION 0x000008
/**
* Enables TCAM for Flow Steering and QoS look-ups. If not specified, all
* look-ups are exact match. Note that TCAM is not available on LS1088 and its
* variants. Setting this bit on these SoCs will trigger an error.
*/
#define DPNI_OPT_HAS_KEY_MASKING 0x000010
/**
* Disables the flow steering table.
*/
#define DPNI_OPT_NO_FS 0x000020
int dpni_open(struct fsl_mc_io *mc_io,
u32 cmd_flags,
int dpni_id,
u16 *token);
int dpni_close(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token);
/**
* struct dpni_pools_cfg - Structure representing buffer pools configuration
* @num_dpbp: Number of DPBPs
* @pools: Array of buffer pools parameters; The number of valid entries
* must match 'num_dpbp' value
* @pools.dpbp_id: DPBP object ID
* @pools.buffer_size: Buffer size
* @pools.backup_pool: Backup pool
*/
struct dpni_pools_cfg {
u8 num_dpbp;
struct {
int dpbp_id;
u16 buffer_size;
int backup_pool;
} pools[DPNI_MAX_DPBP];
};
int dpni_set_pools(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
const struct dpni_pools_cfg *cfg);
int dpni_enable(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token);
int dpni_disable(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token);
int dpni_is_enabled(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
int *en);
int dpni_reset(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token);
/**
* DPNI IRQ Index and Events
*/
/**
* IRQ index
*/
#define DPNI_IRQ_INDEX 0
/**
* IRQ event - indicates a change in link state
*/
#define DPNI_IRQ_EVENT_LINK_CHANGED 0x00000001
int dpni_set_irq_enable(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u8 irq_index,
u8 en);
int dpni_get_irq_enable(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u8 irq_index,
u8 *en);
int dpni_set_irq_mask(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u8 irq_index,
u32 mask);
int dpni_get_irq_mask(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u8 irq_index,
u32 *mask);
int dpni_get_irq_status(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u8 irq_index,
u32 *status);
int dpni_clear_irq_status(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u8 irq_index,
u32 status);
/**
* struct dpni_attr - Structure representing DPNI attributes
* @options: Any combination of the following options:
* DPNI_OPT_TX_FRM_RELEASE
* DPNI_OPT_NO_MAC_FILTER
* DPNI_OPT_HAS_POLICING
* DPNI_OPT_SHARED_CONGESTION
* DPNI_OPT_HAS_KEY_MASKING
* DPNI_OPT_NO_FS
* @num_queues: Number of Tx and Rx queues used for traffic distribution.
* @num_tcs: Number of traffic classes (TCs), reserved for the DPNI.
* @mac_filter_entries: Number of entries in the MAC address filtering table.
* @vlan_filter_entries: Number of entries in the VLAN address filtering table.
* @qos_entries: Number of entries in the QoS classification table.
* @fs_entries: Number of entries in the flow steering table.
* @qos_key_size: Size, in bytes, of the QoS look-up key. Defining a key larger
* than this when adding QoS entries will result in an error.
* @fs_key_size: Size, in bytes, of the flow steering look-up key. Defining a
* key larger than this when composing the hash + FS key will
* result in an error.
* @wriop_version: Version of WRIOP HW block. The 3 version values are stored
* on 6, 5, 5 bits respectively.
*/
struct dpni_attr {
u32 options;
u8 num_queues;
u8 num_tcs;
u8 mac_filter_entries;
u8 vlan_filter_entries;
u8 qos_entries;
u16 fs_entries;
u8 qos_key_size;
u8 fs_key_size;
u16 wriop_version;
};
int dpni_get_attributes(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
struct dpni_attr *attr);
/**
* DPNI errors
*/
/**
* Extract out of frame header error
*/
#define DPNI_ERROR_EOFHE 0x00020000
/**
* Frame length error
*/
#define DPNI_ERROR_FLE 0x00002000
/**
* Frame physical error
*/
#define DPNI_ERROR_FPE 0x00001000
/**
* Parsing header error
*/
#define DPNI_ERROR_PHE 0x00000020
/**
* Parser L3 checksum error
*/
#define DPNI_ERROR_L3CE 0x00000004
/**
* Parser L3 checksum error
*/
#define DPNI_ERROR_L4CE 0x00000001
/**
* enum dpni_error_action - Defines DPNI behavior for errors
* @DPNI_ERROR_ACTION_DISCARD: Discard the frame
* @DPNI_ERROR_ACTION_CONTINUE: Continue with the normal flow
* @DPNI_ERROR_ACTION_SEND_TO_ERROR_QUEUE: Send the frame to the error queue
*/
enum dpni_error_action {
DPNI_ERROR_ACTION_DISCARD = 0,
DPNI_ERROR_ACTION_CONTINUE = 1,
DPNI_ERROR_ACTION_SEND_TO_ERROR_QUEUE = 2
};
/**
* struct dpni_error_cfg - Structure representing DPNI errors treatment
* @errors: Errors mask; use 'DPNI_ERROR__<X>
* @error_action: The desired action for the errors mask
* @set_frame_annotation: Set to '1' to mark the errors in frame annotation
* status (FAS); relevant only for the non-discard action
*/
struct dpni_error_cfg {
u32 errors;
enum dpni_error_action error_action;
int set_frame_annotation;
};
int dpni_set_errors_behavior(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
struct dpni_error_cfg *cfg);
/**
* DPNI buffer layout modification options
*/
/**
* Select to modify the time-stamp setting
*/
#define DPNI_BUF_LAYOUT_OPT_TIMESTAMP 0x00000001
/**
* Select to modify the parser-result setting; not applicable for Tx
*/
#define DPNI_BUF_LAYOUT_OPT_PARSER_RESULT 0x00000002
/**
* Select to modify the frame-status setting
*/
#define DPNI_BUF_LAYOUT_OPT_FRAME_STATUS 0x00000004
/**
* Select to modify the private-data-size setting
*/
#define DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE 0x00000008
/**
* Select to modify the data-alignment setting
*/
#define DPNI_BUF_LAYOUT_OPT_DATA_ALIGN 0x00000010
/**
* Select to modify the data-head-room setting
*/
#define DPNI_BUF_LAYOUT_OPT_DATA_HEAD_ROOM 0x00000020
/**
* Select to modify the data-tail-room setting
*/
#define DPNI_BUF_LAYOUT_OPT_DATA_TAIL_ROOM 0x00000040
/**
* struct dpni_buffer_layout - Structure representing DPNI buffer layout
* @options: Flags representing the suggested modifications to the buffer
* layout; Use any combination of 'DPNI_BUF_LAYOUT_OPT_<X>' flags
* @pass_timestamp: Pass timestamp value
* @pass_parser_result: Pass parser results
* @pass_frame_status: Pass frame status
* @private_data_size: Size kept for private data (in bytes)
* @data_align: Data alignment
* @data_head_room: Data head room
* @data_tail_room: Data tail room
*/
struct dpni_buffer_layout {
u32 options;
int pass_timestamp;
int pass_parser_result;
int pass_frame_status;
u16 private_data_size;
u16 data_align;
u16 data_head_room;
u16 data_tail_room;
};
/**
* enum dpni_queue_type - Identifies a type of queue targeted by the command
* @DPNI_QUEUE_RX: Rx queue
* @DPNI_QUEUE_TX: Tx queue
* @DPNI_QUEUE_TX_CONFIRM: Tx confirmation queue
* @DPNI_QUEUE_RX_ERR: Rx error queue
*/enum dpni_queue_type {
DPNI_QUEUE_RX,
DPNI_QUEUE_TX,
DPNI_QUEUE_TX_CONFIRM,
DPNI_QUEUE_RX_ERR,
};
int dpni_get_buffer_layout(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
enum dpni_queue_type qtype,
struct dpni_buffer_layout *layout);
int dpni_set_buffer_layout(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
enum dpni_queue_type qtype,
const struct dpni_buffer_layout *layout);
/**
* enum dpni_offload - Identifies a type of offload targeted by the command
* @DPNI_OFF_RX_L3_CSUM: Rx L3 checksum validation
* @DPNI_OFF_RX_L4_CSUM: Rx L4 checksum validation
* @DPNI_OFF_TX_L3_CSUM: Tx L3 checksum generation
* @DPNI_OFF_TX_L4_CSUM: Tx L4 checksum generation
*/
enum dpni_offload {
DPNI_OFF_RX_L3_CSUM,
DPNI_OFF_RX_L4_CSUM,
DPNI_OFF_TX_L3_CSUM,
DPNI_OFF_TX_L4_CSUM,
};
int dpni_set_offload(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
enum dpni_offload type,
u32 config);
int dpni_get_offload(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
enum dpni_offload type,
u32 *config);
int dpni_get_qdid(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
enum dpni_queue_type qtype,
u16 *qdid);
int dpni_get_tx_data_offset(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 *data_offset);
#define DPNI_STATISTICS_CNT 7
/**
* union dpni_statistics - Union describing the DPNI statistics
* @page_0: Page_0 statistics structure
* @page_0.ingress_all_frames: Ingress frame count
* @page_0.ingress_all_bytes: Ingress byte count
* @page_0.ingress_multicast_frames: Ingress multicast frame count
* @page_0.ingress_multicast_bytes: Ingress multicast byte count
* @page_0.ingress_broadcast_frames: Ingress broadcast frame count
* @page_0.ingress_broadcast_bytes: Ingress broadcast byte count
* @page_1: Page_1 statistics structure
* @page_1.egress_all_frames: Egress frame count
* @page_1.egress_all_bytes: Egress byte count
* @page_1.egress_multicast_frames: Egress multicast frame count
* @page_1.egress_multicast_bytes: Egress multicast byte count
* @page_1.egress_broadcast_frames: Egress broadcast frame count
* @page_1.egress_broadcast_bytes: Egress broadcast byte count
* @page_2: Page_2 statistics structure
* @page_2.ingress_filtered_frames: Ingress filtered frame count
* @page_2.ingress_discarded_frames: Ingress discarded frame count
* @page_2.ingress_nobuffer_discards: Ingress discarded frame count due to
* lack of buffers
* @page_2.egress_discarded_frames: Egress discarded frame count
* @page_2.egress_confirmed_frames: Egress confirmed frame count
* @raw: raw statistics structure, used to index counters
*/
union dpni_statistics {
struct {
u64 ingress_all_frames;
u64 ingress_all_bytes;
u64 ingress_multicast_frames;
u64 ingress_multicast_bytes;
u64 ingress_broadcast_frames;
u64 ingress_broadcast_bytes;
} page_0;
struct {
u64 egress_all_frames;
u64 egress_all_bytes;
u64 egress_multicast_frames;
u64 egress_multicast_bytes;
u64 egress_broadcast_frames;
u64 egress_broadcast_bytes;
} page_1;
struct {
u64 ingress_filtered_frames;
u64 ingress_discarded_frames;
u64 ingress_nobuffer_discards;
u64 egress_discarded_frames;
u64 egress_confirmed_frames;
} page_2;
struct {
u64 counter[DPNI_STATISTICS_CNT];
} raw;
};
int dpni_get_statistics(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u8 page,
union dpni_statistics *stat);
/**
* Enable auto-negotiation
*/
#define DPNI_LINK_OPT_AUTONEG 0x0000000000000001ULL
/**
* Enable half-duplex mode
*/
#define DPNI_LINK_OPT_HALF_DUPLEX 0x0000000000000002ULL
/**
* Enable pause frames
*/
#define DPNI_LINK_OPT_PAUSE 0x0000000000000004ULL
/**
* Enable a-symmetric pause frames
*/
#define DPNI_LINK_OPT_ASYM_PAUSE 0x0000000000000008ULL
/**
* struct - Structure representing DPNI link configuration
* @rate: Rate
* @options: Mask of available options; use 'DPNI_LINK_OPT_<X>' values
*/
struct dpni_link_cfg {
u32 rate;
u64 options;
};
int dpni_set_link_cfg(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
const struct dpni_link_cfg *cfg);
/**
* struct dpni_link_state - Structure representing DPNI link state
* @rate: Rate
* @options: Mask of available options; use 'DPNI_LINK_OPT_<X>' values
* @up: Link state; '0' for down, '1' for up
*/
struct dpni_link_state {
u32 rate;
u64 options;
int up;
};
int dpni_get_link_state(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
struct dpni_link_state *state);
int dpni_set_max_frame_length(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 max_frame_length);
int dpni_get_max_frame_length(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 *max_frame_length);
int dpni_set_multicast_promisc(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
int en);
int dpni_get_multicast_promisc(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
int *en);
int dpni_set_unicast_promisc(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
int en);
int dpni_get_unicast_promisc(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
int *en);
int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
const u8 mac_addr[6]);
int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u8 mac_addr[6]);
int dpni_get_port_mac_addr(struct fsl_mc_io *mc_io,
u32 cm_flags,
u16 token,
u8 mac_addr[6]);
int dpni_add_mac_addr(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
const u8 mac_addr[6]);
int dpni_remove_mac_addr(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
const u8 mac_addr[6]);
int dpni_clear_mac_filters(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
int unicast,
int multicast);
/**
* enum dpni_dist_mode - DPNI distribution mode
* @DPNI_DIST_MODE_NONE: No distribution
* @DPNI_DIST_MODE_HASH: Use hash distribution; only relevant if
* the 'DPNI_OPT_DIST_HASH' option was set at DPNI creation
* @DPNI_DIST_MODE_FS: Use explicit flow steering; only relevant if
* the 'DPNI_OPT_DIST_FS' option was set at DPNI creation
*/
enum dpni_dist_mode {
DPNI_DIST_MODE_NONE = 0,
DPNI_DIST_MODE_HASH = 1,
DPNI_DIST_MODE_FS = 2
};
/**
* enum dpni_fs_miss_action - DPNI Flow Steering miss action
* @DPNI_FS_MISS_DROP: In case of no-match, drop the frame
* @DPNI_FS_MISS_EXPLICIT_FLOWID: In case of no-match, use explicit flow-id
* @DPNI_FS_MISS_HASH: In case of no-match, distribute using hash
*/
enum dpni_fs_miss_action {
DPNI_FS_MISS_DROP = 0,
DPNI_FS_MISS_EXPLICIT_FLOWID = 1,
DPNI_FS_MISS_HASH = 2
};
/**
* struct dpni_fs_tbl_cfg - Flow Steering table configuration
* @miss_action: Miss action selection
* @default_flow_id: Used when 'miss_action = DPNI_FS_MISS_EXPLICIT_FLOWID'
*/
struct dpni_fs_tbl_cfg {
enum dpni_fs_miss_action miss_action;
u16 default_flow_id;
};
int dpni_prepare_key_cfg(const struct dpkg_profile_cfg *cfg,
u8 *key_cfg_buf);
/**
* struct dpni_rx_tc_dist_cfg - Rx traffic class distribution configuration
* @dist_size: Set the distribution size;
* supported values: 1,2,3,4,6,7,8,12,14,16,24,28,32,48,56,64,96,
* 112,128,192,224,256,384,448,512,768,896,1024
* @dist_mode: Distribution mode
* @key_cfg_iova: I/O virtual address of 256 bytes DMA-able memory filled with
* the extractions to be used for the distribution key by calling
* dpni_prepare_key_cfg() relevant only when
* 'dist_mode != DPNI_DIST_MODE_NONE', otherwise it can be '0'
* @fs_cfg: Flow Steering table configuration; only relevant if
* 'dist_mode = DPNI_DIST_MODE_FS'
*/
struct dpni_rx_tc_dist_cfg {
u16 dist_size;
enum dpni_dist_mode dist_mode;
u64 key_cfg_iova;
struct dpni_fs_tbl_cfg fs_cfg;
};
int dpni_set_rx_tc_dist(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u8 tc_id,
const struct dpni_rx_tc_dist_cfg *cfg);
/**
* enum dpni_dest - DPNI destination types
* @DPNI_DEST_NONE: Unassigned destination; The queue is set in parked mode and
* does not generate FQDAN notifications; user is expected to
* dequeue from the queue based on polling or other user-defined
* method
* @DPNI_DEST_DPIO: The queue is set in schedule mode and generates FQDAN
* notifications to the specified DPIO; user is expected to dequeue
* from the queue only after notification is received
* @DPNI_DEST_DPCON: The queue is set in schedule mode and does not generate
* FQDAN notifications, but is connected to the specified DPCON
* object; user is expected to dequeue from the DPCON channel
*/
enum dpni_dest {
DPNI_DEST_NONE = 0,
DPNI_DEST_DPIO = 1,
DPNI_DEST_DPCON = 2
};
/**
* struct dpni_queue - Queue structure
* @destination - Destination structure
* @destination.id: ID of the destination, only relevant if DEST_TYPE is > 0.
* Identifies either a DPIO or a DPCON object.
* Not relevant for Tx queues.
* @destination.type: May be one of the following:
* 0 - No destination, queue can be manually
* queried, but will not push traffic or
* notifications to a DPIO;
* 1 - The destination is a DPIO. When traffic
* becomes available in the queue a FQDAN
* (FQ data available notification) will be
* generated to selected DPIO;
* 2 - The destination is a DPCON. The queue is
* associated with a DPCON object for the
* purpose of scheduling between multiple
* queues. The DPCON may be independently
* configured to generate notifications.
* Not relevant for Tx queues.
* @destination.hold_active: Hold active, maintains a queue scheduled for longer
* in a DPIO during dequeue to reduce spread of traffic.
* Only relevant if queues are
* not affined to a single DPIO.
* @user_context: User data, presented to the user along with any frames
* from this queue. Not relevant for Tx queues.
* @flc: FD FLow Context structure
* @flc.value: Default FLC value for traffic dequeued from
* this queue. Please check description of FD
* structure for more information.
* Note that FLC values set using dpni_add_fs_entry,
* if any, take precedence over values per queue.
* @flc.stash_control: Boolean, indicates whether the 6 lowest
* - significant bits are used for stash control.
* significant bits are used for stash control. If set, the 6
* least significant bits in value are interpreted as follows:
* - bits 0-1: indicates the number of 64 byte units of context
* that are stashed. FLC value is interpreted as a memory address
* in this case, excluding the 6 LS bits.
* - bits 2-3: indicates the number of 64 byte units of frame
* annotation to be stashed. Annotation is placed at FD[ADDR].
* - bits 4-5: indicates the number of 64 byte units of frame
* data to be stashed. Frame data is placed at FD[ADDR] +
* FD[OFFSET].
* For more details check the Frame Descriptor section in the
* hardware documentation.
*/
struct dpni_queue {
struct {
u16 id;
enum dpni_dest type;
char hold_active;
u8 priority;
} destination;
u64 user_context;
struct {
u64 value;
char stash_control;
} flc;
};
/**
* struct dpni_queue_id - Queue identification, used for enqueue commands
* or queue control
* @fqid: FQID used for enqueueing to and/or configuration of this specific FQ
* @qdbin: Queueing bin, used to enqueue using QDID, DQBIN, QPRI. Only relevant
* for Tx queues.
*/
struct dpni_queue_id {
u32 fqid;
u16 qdbin;
};
/**
* Set User Context
*/
#define DPNI_QUEUE_OPT_USER_CTX 0x00000001
#define DPNI_QUEUE_OPT_DEST 0x00000002
#define DPNI_QUEUE_OPT_FLC 0x00000004
#define DPNI_QUEUE_OPT_HOLD_ACTIVE 0x00000008
int dpni_set_queue(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
enum dpni_queue_type qtype,
u8 tc,
u8 index,
u8 options,
const struct dpni_queue *queue);
int dpni_get_queue(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
enum dpni_queue_type qtype,
u8 tc,
u8 index,
struct dpni_queue *queue,
struct dpni_queue_id *qid);
/**
* enum dpni_congestion_unit - DPNI congestion units
* @DPNI_CONGESTION_UNIT_BYTES: bytes units
* @DPNI_CONGESTION_UNIT_FRAMES: frames units
*/
enum dpni_congestion_unit {
DPNI_CONGESTION_UNIT_BYTES = 0,
DPNI_CONGESTION_UNIT_FRAMES
};
/**
* enum dpni_congestion_point - Structure representing congestion point
* @DPNI_CP_QUEUE: Set taildrop per queue, identified by QUEUE_TYPE, TC and
* QUEUE_INDEX
* @DPNI_CP_GROUP: Set taildrop per queue group. Depending on options used to
* define the DPNI this can be either per TC (default) or per
* interface (DPNI_OPT_SHARED_CONGESTION set at DPNI create).
* QUEUE_INDEX is ignored if this type is used.
*/
enum dpni_congestion_point {
DPNI_CP_QUEUE,
DPNI_CP_GROUP,
};
/**
* struct dpni_taildrop - Structure representing the taildrop
* @enable: Indicates whether the taildrop is active or not.
* @units: Indicates the unit of THRESHOLD. Queue taildrop only supports
* byte units, this field is ignored and assumed = 0 if
* CONGESTION_POINT is 0.
* @threshold: Threshold value, in units identified by UNITS field. Value 0
* cannot be used as a valid taildrop threshold, THRESHOLD must
* be > 0 if the taildrop is enabled.
*/
struct dpni_taildrop {
char enable;
enum dpni_congestion_unit units;
u32 threshold;
};
int dpni_set_taildrop(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
enum dpni_congestion_point cg_point,
enum dpni_queue_type q_type,
u8 tc,
u8 q_index,
struct dpni_taildrop *taildrop);
int dpni_get_taildrop(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
enum dpni_congestion_point cg_point,
enum dpni_queue_type q_type,
u8 tc,
u8 q_index,
struct dpni_taildrop *taildrop);
/**
* struct dpni_rule_cfg - Rule configuration for table lookup
* @key_iova: I/O virtual address of the key (must be in DMA-able memory)
* @mask_iova: I/O virtual address of the mask (must be in DMA-able memory)
* @key_size: key and mask size (in bytes)
*/
struct dpni_rule_cfg {
u64 key_iova;
u64 mask_iova;
u8 key_size;
};
int dpni_get_api_version(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 *major_ver,
u16 *minor_ver);
#endif /* __FSL_DPNI_H */