diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-05-05 08:47:39 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-10-23 09:23:59 +0200 |
commit | cd089b9e05aad31244059ba88988afbe1db02e5e (patch) | |
tree | 81d344bb292ff39e60f74ac4df5f1621eca77c05 /linux/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h | |
parent | Import DPAA driver snapshot (diff) | |
download | rtems-libbsd-cd089b9e05aad31244059ba88988afbe1db02e5e.tar.bz2 |
Linux update to 4.11-rc5
Linux baseline a71c9a1c779f2499fb2afc0553e543f18aff6edf (4.11-rc5).
Diffstat (limited to 'linux/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h')
-rw-r--r-- | linux/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h | 440 |
1 files changed, 65 insertions, 375 deletions
diff --git a/linux/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h b/linux/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h index 11b11e65..8a2b1189 100644 --- a/linux/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h +++ b/linux/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h @@ -1,4 +1,4 @@ -/* Copyright 2008 - 2015 Freescale Semiconductor Inc. +/* Copyright 2008 - 2016 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -28,131 +28,36 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __DPA_H -#define __DPA_H +#ifndef __DPAA_H +#define __DPAA_H #include <linux/netdevice.h> #include <soc/fsl/qman.h> +#include <soc/fsl/bman.h> #include "fman.h" #include "mac.h" #include "dpaa_eth_trace.h" -#ifndef __rtems__ -extern int dpa_rx_extra_headroom; -extern int dpa_max_frm; - -#define dpa_get_rx_extra_headroom() dpa_rx_extra_headroom -#define dpa_get_max_frm() dpa_max_frm -#else /* __rtems__ */ -#define dpa_get_rx_extra_headroom fman_get_rx_extra_headroom -#define dpa_get_max_frm fman_get_max_frm -#endif /* __rtems__ */ - -#define dpa_get_max_mtu() \ - (dpa_get_max_frm() - (VLAN_ETH_HLEN + ETH_FCS_LEN)) - -/* Simple enum of FQ types - used for array indexing */ -enum port_type {RX, TX}; - -struct dpa_buffer_layout_s { - u16 priv_data_size; - bool parse_results; - bool time_stamp; - bool hash_results; - u16 data_align; -}; - -#define DPA_ERR_ON(cond) - -#define DPA_TX_PRIV_DATA_SIZE 16 -#define DPA_PARSE_RESULTS_SIZE sizeof(struct fman_prs_result) -#define DPA_TIME_STAMP_SIZE 8 -#define DPA_HASH_RESULTS_SIZE 8 -#define DPA_RX_PRIV_DATA_SIZE (DPA_TX_PRIV_DATA_SIZE + \ - dpa_get_rx_extra_headroom()) - -#define FM_FD_STAT_RX_ERRORS \ - (FM_FD_ERR_DMA | FM_FD_ERR_PHYSICAL | \ - FM_FD_ERR_SIZE | FM_FD_ERR_CLS_DISCARD | \ - FM_FD_ERR_EXTRACTION | FM_FD_ERR_NO_SCHEME | \ - FM_FD_ERR_PRS_TIMEOUT | FM_FD_ERR_PRS_ILL_INSTRUCT | \ - FM_FD_ERR_PRS_HDR_ERR) +#define DPAA_ETH_TXQ_NUM NR_CPUS -#define FM_FD_STAT_TX_ERRORS \ - (FM_FD_ERR_UNSUPPORTED_FORMAT | \ - FM_FD_ERR_LENGTH | FM_FD_ERR_DMA) - -/* The raw buffer size must be cacheline aligned. - * Normally we use 2K buffers. - */ -#define DPA_BP_RAW_SIZE 2048 - -/* This is what FMan is ever allowed to use. - * FMan-DMA requires 16-byte alignment for Rx buffers, but SKB_DATA_ALIGN is - * even stronger (SMP_CACHE_BYTES-aligned), so we just get away with that, - * via SKB_WITH_OVERHEAD(). We can't rely on netdev_alloc_frag() giving us - * half-page-aligned buffers (can we?), so we reserve some more space - * for start-of-buffer alignment. - */ #ifndef __rtems__ -#define dpa_bp_size(buffer_layout) (SKB_WITH_OVERHEAD(DPA_BP_RAW_SIZE) - \ - SMP_CACHE_BYTES) +#define DPAA_BPS_NUM 3 /* number of bpools per interface */ #else /* __rtems__ */ -/* - * FIXME: 4 bytes would be enough for the mbuf pointer. However, jumbo receive - * frames overwrite this area if < 64 bytes. - */ -#define DPA_OUT_OF_BAND_SIZE 64 -#define DPA_MBUF_POINTER_OFFSET (DPA_BP_RAW_SIZE - DPA_OUT_OF_BAND_SIZE) -#define dpa_bp_size(buffer_layout) DPA_MBUF_POINTER_OFFSET +#define DPAA_BPS_NUM 1 #endif /* __rtems__ */ -/* We must ensure that skb_shinfo is always cacheline-aligned. */ -#define DPA_SKB_SIZE(size) ((size) & ~(SMP_CACHE_BYTES - 1)) - -/* Largest value that the FQD's OAL field can hold. - * This is DPAA-1.x specific. - */ -#define FSL_QMAN_MAX_OAL 127 - -/* Default alignment for start of data in an Rx FD */ -#define DPA_FD_DATA_ALIGNMENT 16 - -/* Values for the L3R field of the FM Parse Results - */ -/* L3 Type field: First IP Present IPv4 */ -#define FM_L3_PARSE_RESULT_IPV4 0x8000 -/* L3 Type field: First IP Present IPv6 */ -#define FM_L3_PARSE_RESULT_IPV6 0x4000 - -/* Values for the L4R field of the FM Parse Results - * See $8.8.4.7.20 - L4 HXS - L4 Results from DPAA-Rev2 Reference Manual. - */ -/* L4 Type field: UDP */ -#define FM_L4_PARSE_RESULT_UDP 0x40 -/* L4 Type field: TCP */ -#define FM_L4_PARSE_RESULT_TCP 0x20 - -/* number of Tx queues to FMan */ -#define DPAA_ETH_TX_QUEUES NR_CPUS - -#define DPAA_ETH_RX_QUEUES 128 - -#define FSL_DPAA_ETH_MAX_BUF_COUNT 128 -#define FSL_DPAA_ETH_REFILL_THRESHOLD 80 /* More detailed FQ types - used for fine-grained WQ assignments */ -enum dpa_fq_type { +enum dpaa_fq_type { FQ_TYPE_RX_DEFAULT = 1, /* Rx Default FQs */ FQ_TYPE_RX_ERROR, /* Rx Error FQs */ - FQ_TYPE_RX_PCD, /* User-defined PCDs */ FQ_TYPE_TX, /* "Real" Tx FQs */ FQ_TYPE_TX_CONFIRM, /* Tx default Conf FQ (actually an Rx FQ) */ FQ_TYPE_TX_CONF_MQ, /* Tx conf FQs (one for each Tx FQ) */ FQ_TYPE_TX_ERROR, /* Tx Error FQs (these are actually Rx FQs) */ }; -struct dpa_fq { +struct dpaa_fq { struct qman_fq fq_base; struct list_head list; struct net_device *net_dev; @@ -161,10 +66,10 @@ struct dpa_fq { u32 flags; u16 channel; u8 wq; - enum dpa_fq_type fq_type; + enum dpaa_fq_type fq_type; }; -struct dpa_fq_cbs_t { +struct dpaa_fq_cbs { struct qman_fq rx_defq; struct qman_fq tx_defq; struct qman_fq rx_errq; @@ -172,45 +77,30 @@ struct dpa_fq_cbs_t { struct qman_fq egress_ern; }; -struct fqid_cell { - u32 start; - u32 count; -}; - -struct dpa_bp { - struct bman_pool *pool; - u8 bpid; -#ifndef __rtems__ +struct dpaa_bp { + /* device used in the DMA mapping operations */ struct device *dev; -#endif /* __rtems__ */ - /* the buffer pools used for the private ports are initialized - * with config_count buffers for each CPU; at runtime the - * number of buffers per CPU is constantly brought back to this - * level - */ - int config_count; + /* current number of buffers in the buffer pool alloted to each CPU */ + int __percpu *percpu_count; + /* all buffers allocated for this pool have this raw size */ + size_t raw_size; + /* all buffers in this pool have this same usable size */ size_t size; - bool seed_pool; - /* physical address of the contiguous memory used by the pool to store - * the buffers - */ - dma_addr_t paddr; - /* virtual address of the contiguous memory used by the pool to store - * the buffers + /* the buffer pools are initialized with config_count buffers for each + * CPU; at runtime the number of buffers per CPU is constantly brought + * back to this level */ - void __iomem *vaddr; - /* current number of buffers in the bpool alloted to this CPU */ - int __percpu *percpu_count; + u16 config_count; + u8 bpid; + struct bman_pool *pool; + /* bpool can be seeded before use by this cb */ + int (*seed_cb)(struct dpaa_bp *); + /* bpool can be emptied before freeing by this cb */ + void (*free_buf_cb)(const struct dpaa_bp *, struct bm_buffer *); atomic_t refs; - /* some bpools need to be seeded before use by this cb */ - int (*seed_cb)(struct dpa_bp *); - /* some bpools need to be emptied before freeing; this cb is used - * for freeing of individual buffers taken from the pool - */ - void (*free_buf_cb)(void *addr); }; -struct dpa_rx_errors { +struct dpaa_rx_errors { u64 dme; /* DMA Error */ u64 fpe; /* Frame Physical Error */ u64 fse; /* Frame Size Error */ @@ -218,7 +108,7 @@ struct dpa_rx_errors { }; /* Counters for QMan ERN frames - one counter per rejection code */ -struct dpa_ern_cnt { +struct dpaa_ern_cnt { u64 cg_tdrop; /* Congestion group taildrop */ u64 wred; /* WRED congestion */ u64 err_cond; /* Error condition */ @@ -229,16 +119,17 @@ struct dpa_ern_cnt { u64 orp_zero; /* ORP disabled */ }; -struct dpa_napi_portal { +struct dpaa_napi_portal { #ifndef __rtems__ struct napi_struct napi; #endif /* __rtems__ */ struct qman_portal *p; + bool down; }; -struct dpa_percpu_priv_s { +struct dpaa_percpu_priv { struct net_device *net_dev; - struct dpa_napi_portal *np; + struct dpaa_napi_portal np; u64 in_interrupt; u64 tx_confirm; /* fragmented (non-linear) skbuffs received from the stack */ @@ -246,26 +137,28 @@ struct dpa_percpu_priv_s { #ifndef __rtems__ struct rtnl_link_stats64 stats; #endif /* __rtems__ */ - struct dpa_rx_errors rx_errors; - struct dpa_ern_cnt ern_cnt; + struct dpaa_rx_errors rx_errors; + struct dpaa_ern_cnt ern_cnt; }; -struct dpa_priv_s { - struct dpa_percpu_priv_s __percpu *percpu_priv; - struct dpa_bp *dpa_bp; +struct dpaa_buffer_layout { + u16 priv_data_size; +}; + +struct dpaa_priv { + struct dpaa_percpu_priv __percpu *percpu_priv; + struct dpaa_bp *dpaa_bps[DPAA_BPS_NUM]; /* Store here the needed Tx headroom for convenience and speed * (even though it can be computed based on the fields of buf_layout) */ u16 tx_headroom; struct net_device *net_dev; struct mac_device *mac_dev; - struct qman_fq *egress_fqs[DPAA_ETH_TX_QUEUES]; - struct qman_fq *conf_fqs[DPAA_ETH_TX_QUEUES]; - - size_t bp_count; + struct qman_fq *egress_fqs[DPAA_ETH_TXQ_NUM]; + struct qman_fq *conf_fqs[DPAA_ETH_TXQ_NUM]; - u16 channel; /* "fsl,qman-channel-id" */ - struct list_head dpa_fq_list; + u16 channel; + struct list_head dpaa_fq_list; #ifndef __rtems__ u32 msg_enable; /* net_device message level */ @@ -289,231 +182,28 @@ struct dpa_priv_s { bool use_ingress_cgr; struct qman_cgr ingress_cgr; - struct dpa_buffer_layout_s *buf_layout; + struct dpaa_buffer_layout buf_layout[2]; u16 rx_headroom; }; -struct fm_port_fqs { - struct dpa_fq *tx_defq; - struct dpa_fq *tx_errq; - struct dpa_fq *rx_defq; - struct dpa_fq *rx_errq; -}; +/* from dpaa_ethtool.c */ +extern const struct ethtool_ops dpaa_ethtool_ops; -int dpa_bp_priv_seed(struct dpa_bp *dpa_bp); -int dpaa_eth_refill_bpools(struct dpa_bp *dpa_bp, int *count_ptr); -void _dpa_rx(struct net_device *net_dev, - struct qman_portal *portal, - const struct dpa_priv_s *priv, - struct dpa_percpu_priv_s *percpu_priv, - const struct qm_fd *fd, - u32 fqid, - int *count_ptr); -#ifndef __rtems__ -int dpa_tx(struct sk_buff *skb, struct net_device *net_dev); -struct sk_buff *_dpa_cleanup_tx_fd(const struct dpa_priv_s *priv, - const struct qm_fd *fd); - -/* Turn on HW checksum computation for this outgoing frame. - * If the current protocol is not something we support in this regard - * (or if the stack has already computed the SW checksum), we do nothing. - * - * Returns 0 if all goes well (or HW csum doesn't apply), and a negative value - * otherwise. - * - * Note that this function may modify the fd->cmd field and the skb data buffer - * (the Parse Results area). - */ -int dpa_enable_tx_csum(struct dpa_priv_s *priv, struct sk_buff *skb, - struct qm_fd *fd, char *parse_results); -#else /* __rtems__ */ -void _dpa_cleanup_tx_fd(struct ifnet *ifp, const struct qm_fd *fd); -#endif /* __rtems__ */ - -static inline int dpaa_eth_napi_schedule(struct dpa_percpu_priv_s *percpu_priv, - struct qman_portal *portal) -{ -#ifndef __rtems__ - /* In case of threaded ISR for RT enable kernel, - * in_irq() does not return appropriate value, so use - * in_serving_softirq to distinguish softirq or irq context. - */ - if (unlikely(in_irq() || !in_serving_softirq())) { - /* Disable QMan IRQ and invoke NAPI */ - int ret = qman_p_irqsource_remove(portal, QM_PIRQ_DQRI); - - if (likely(!ret)) { - const struct qman_portal_config *pc = - qman_p_get_portal_config(portal); - struct dpa_napi_portal *np = - &percpu_priv->np[pc->channel]; - - np->p = portal; - napi_schedule(&np->napi); - percpu_priv->in_interrupt++; - return 1; - } - } -#else /* __rtems__ */ - /* FIXME */ -#endif /* __rtems__ */ - return 0; -} - -static inline ssize_t __const dpa_fd_length(const struct qm_fd *fd) -{ - return fd->length20; -} - -static inline ssize_t __const dpa_fd_offset(const struct qm_fd *fd) -{ - return fd->offset; -} - -#ifndef __rtems__ -/* Verifies if the skb length is below the interface MTU */ -static inline int dpa_check_rx_mtu(struct sk_buff *skb, int mtu) -{ - if (unlikely(skb->len > mtu)) - if ((skb->protocol != htons(ETH_P_8021Q)) || - (skb->len > mtu + 4)) - return -1; - - return 0; -} -#endif /* __rtems__ */ - -static inline u16 dpa_get_headroom(struct dpa_buffer_layout_s *bl) -{ - u16 headroom; - /* The frame headroom must accommodate: - * - the driver private data area - * - parse results, hash results, timestamp if selected - * If either hash results or time stamp are selected, both will - * be copied to/from the frame headroom, as TS is located between PR and - * HR in the IC and IC copy size has a granularity of 16bytes - * (see description of FMBM_RICP and FMBM_TICP registers in DPAARM) - * - * Also make sure the headroom is a multiple of data_align bytes - */ - headroom = (u16)(bl->priv_data_size + - (bl->parse_results ? DPA_PARSE_RESULTS_SIZE : 0) + - (bl->hash_results || bl->time_stamp ? - DPA_TIME_STAMP_SIZE + DPA_HASH_RESULTS_SIZE : 0)); - - return bl->data_align ? ALIGN(headroom, bl->data_align) : headroom; -} - -#ifndef __rtems__ +/* from dpaa_eth_sysfs.c */ void dpaa_eth_sysfs_remove(struct device *dev); void dpaa_eth_sysfs_init(struct device *dev); - -void dpa_private_napi_del(struct net_device *net_dev); +#ifdef __rtems__ +#include <sys/mbuf.h> + +#define DPAA_ENQUEUE_RETRIES 100000 +#define DPAA_SGT_MAX_ENTRIES 16 +#define DPAA_TX_PRIV_DATA_SIZE 16 +#define FM_L3_PARSE_RESULT_IPV4 0x8000 +#define FM_L3_PARSE_RESULT_IPV6 0x4000 +#define FM_L4_PARSE_RESULT_UDP 0x40 +#define FM_L4_PARSE_RESULT_TCP 0x20 +#define FSL_DPAA_BPID_INV 0xff + +void dpaa_cleanup_tx_fd(struct ifnet *ifp, const struct qm_fd *fd); #endif /* __rtems__ */ - -static inline void clear_fd(struct qm_fd *fd) -{ - fd->opaque_addr = 0; - fd->opaque = 0; - fd->cmd = 0; -} - -static inline int _dpa_tx_fq_to_id(const struct dpa_priv_s *priv, - struct qman_fq *tx_fq) -{ - int i; - - for (i = 0; i < DPAA_ETH_TX_QUEUES; i++) - if (priv->egress_fqs[i] == tx_fq) - return i; - - return -EINVAL; -} - -#ifndef __rtems__ -static inline int dpa_xmit(struct dpa_priv_s *priv, - struct rtnl_link_stats64 *percpu_stats, - int queue, - struct qm_fd *fd) -{ - int err, i; - struct qman_fq *egress_fq; - - egress_fq = priv->egress_fqs[queue]; - if (fd->bpid == 0xff) - fd->cmd |= qman_fq_fqid(priv->conf_fqs[queue]); - - /* Trace this Tx fd */ - trace_dpa_tx_fd(priv->net_dev, egress_fq, fd); - - for (i = 0; i < 100000; i++) { - err = qman_enqueue(egress_fq, fd, 0); - if (err != -EBUSY) - break; - } - - if (unlikely(err < 0)) { - percpu_stats->tx_errors++; - percpu_stats->tx_fifo_errors++; - return err; - } - - percpu_stats->tx_packets++; - percpu_stats->tx_bytes += dpa_fd_length(fd); - - return 0; -} -#endif /* __rtems__ */ - -/* Use multiple WQs for FQ assignment: - * - Tx Confirmation queues go to WQ1. - * - Rx Default and Tx queues go to WQ3 (no differentiation between - * Rx and Tx traffic). - * - Rx Error and Tx Error queues go to WQ2 (giving them a better chance - * to be scheduled, in case there are many more FQs in WQ3). - * This ensures that Tx-confirmed buffers are timely released. In particular, - * it avoids congestion on the Tx Confirm FQs, which can pile up PFDRs if they - * are greatly outnumbered by other FQs in the system, while - * dequeue scheduling is round-robin. - */ -static inline void _dpa_assign_wq(struct dpa_fq *fq) -{ - switch (fq->fq_type) { - case FQ_TYPE_TX_CONFIRM: - case FQ_TYPE_TX_CONF_MQ: - fq->wq = 1; - break; - case FQ_TYPE_RX_DEFAULT: - case FQ_TYPE_TX: - fq->wq = 3; - break; - case FQ_TYPE_RX_ERROR: - case FQ_TYPE_TX_ERROR: - fq->wq = 2; - break; - default: - WARN(1, "Invalid FQ type %d for FQID %d!\n", - fq->fq_type, fq->fqid); - } -} - -#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE -/* Use in lieu of skb_get_queue_mapping() */ -#define dpa_get_queue_mapping(skb) \ - raw_smp_processor_id() -#else -/* Use the queue selected by XPS */ -#define dpa_get_queue_mapping(skb) \ - skb_get_queue_mapping(skb) -#endif - -static inline void _dpa_bp_free_pf(void *addr) -{ -#ifndef __rtems__ - put_page(virt_to_head_page(addr)); -#else /* __rtems__ */ - BSD_ASSERT(0); -#endif /* __rtems__ */ -} - -#endif /* __DPA_H */ +#endif /* __DPAA_H */ |