Commit 8ce5cd5e authored by David S. Miller's avatar David S. Miller

Merge branch 'dpaa2-eth-Driver-updates'

Ioana Ciocoi Radulescu says:

====================
dpaa2-eth: Driver updates

First patch moves the driver to a page-per-frame memory model.
The others are minor tweaks and optimizations.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents e37268eb 20fb0572
...@@ -86,16 +86,16 @@ static void free_rx_fd(struct dpaa2_eth_priv *priv, ...@@ -86,16 +86,16 @@ static void free_rx_fd(struct dpaa2_eth_priv *priv,
for (i = 1; i < DPAA2_ETH_MAX_SG_ENTRIES; i++) { for (i = 1; i < DPAA2_ETH_MAX_SG_ENTRIES; i++) {
addr = dpaa2_sg_get_addr(&sgt[i]); addr = dpaa2_sg_get_addr(&sgt[i]);
sg_vaddr = dpaa2_iova_to_virt(priv->iommu_domain, addr); sg_vaddr = dpaa2_iova_to_virt(priv->iommu_domain, addr);
dma_unmap_single(dev, addr, DPAA2_ETH_RX_BUF_SIZE, dma_unmap_page(dev, addr, DPAA2_ETH_RX_BUF_SIZE,
DMA_BIDIRECTIONAL); DMA_BIDIRECTIONAL);
skb_free_frag(sg_vaddr); free_pages((unsigned long)sg_vaddr, 0);
if (dpaa2_sg_is_final(&sgt[i])) if (dpaa2_sg_is_final(&sgt[i]))
break; break;
} }
free_buf: free_buf:
skb_free_frag(vaddr); free_pages((unsigned long)vaddr, 0);
} }
/* Build a linear skb based on a single-buffer frame descriptor */ /* Build a linear skb based on a single-buffer frame descriptor */
...@@ -109,7 +109,7 @@ static struct sk_buff *build_linear_skb(struct dpaa2_eth_channel *ch, ...@@ -109,7 +109,7 @@ static struct sk_buff *build_linear_skb(struct dpaa2_eth_channel *ch,
ch->buf_count--; ch->buf_count--;
skb = build_skb(fd_vaddr, DPAA2_ETH_SKB_SIZE); skb = build_skb(fd_vaddr, DPAA2_ETH_RX_BUF_RAW_SIZE);
if (unlikely(!skb)) if (unlikely(!skb))
return NULL; return NULL;
...@@ -144,19 +144,19 @@ static struct sk_buff *build_frag_skb(struct dpaa2_eth_priv *priv, ...@@ -144,19 +144,19 @@ static struct sk_buff *build_frag_skb(struct dpaa2_eth_priv *priv,
/* Get the address and length from the S/G entry */ /* Get the address and length from the S/G entry */
sg_addr = dpaa2_sg_get_addr(sge); sg_addr = dpaa2_sg_get_addr(sge);
sg_vaddr = dpaa2_iova_to_virt(priv->iommu_domain, sg_addr); sg_vaddr = dpaa2_iova_to_virt(priv->iommu_domain, sg_addr);
dma_unmap_single(dev, sg_addr, DPAA2_ETH_RX_BUF_SIZE, dma_unmap_page(dev, sg_addr, DPAA2_ETH_RX_BUF_SIZE,
DMA_BIDIRECTIONAL); DMA_BIDIRECTIONAL);
sg_length = dpaa2_sg_get_len(sge); sg_length = dpaa2_sg_get_len(sge);
if (i == 0) { if (i == 0) {
/* We build the skb around the first data buffer */ /* We build the skb around the first data buffer */
skb = build_skb(sg_vaddr, DPAA2_ETH_SKB_SIZE); skb = build_skb(sg_vaddr, DPAA2_ETH_RX_BUF_RAW_SIZE);
if (unlikely(!skb)) { if (unlikely(!skb)) {
/* Free the first SG entry now, since we already /* Free the first SG entry now, since we already
* unmapped it and obtained the virtual address * unmapped it and obtained the virtual address
*/ */
skb_free_frag(sg_vaddr); free_pages((unsigned long)sg_vaddr, 0);
/* We still need to subtract the buffers used /* We still need to subtract the buffers used
* by this FD from our software counter * by this FD from our software counter
...@@ -211,9 +211,9 @@ static void free_bufs(struct dpaa2_eth_priv *priv, u64 *buf_array, int count) ...@@ -211,9 +211,9 @@ static void free_bufs(struct dpaa2_eth_priv *priv, u64 *buf_array, int count)
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
vaddr = dpaa2_iova_to_virt(priv->iommu_domain, buf_array[i]); vaddr = dpaa2_iova_to_virt(priv->iommu_domain, buf_array[i]);
dma_unmap_single(dev, buf_array[i], DPAA2_ETH_RX_BUF_SIZE, dma_unmap_page(dev, buf_array[i], DPAA2_ETH_RX_BUF_SIZE,
DMA_BIDIRECTIONAL); DMA_BIDIRECTIONAL);
skb_free_frag(vaddr); free_pages((unsigned long)vaddr, 0);
} }
} }
...@@ -264,9 +264,7 @@ static int xdp_enqueue(struct dpaa2_eth_priv *priv, struct dpaa2_fd *fd, ...@@ -264,9 +264,7 @@ static int xdp_enqueue(struct dpaa2_eth_priv *priv, struct dpaa2_fd *fd,
fq = &priv->fq[queue_id]; fq = &priv->fq[queue_id];
for (i = 0; i < DPAA2_ETH_ENQUEUE_RETRIES; i++) { for (i = 0; i < DPAA2_ETH_ENQUEUE_RETRIES; i++) {
err = dpaa2_io_service_enqueue_qd(fq->channel->dpio, err = priv->enqueue(priv, fq, fd, 0);
priv->tx_qdid, 0,
fq->tx_qdbin, fd);
if (err != -EBUSY) if (err != -EBUSY)
break; break;
} }
...@@ -378,16 +376,16 @@ static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv, ...@@ -378,16 +376,16 @@ static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv,
return; return;
} }
dma_unmap_single(dev, addr, DPAA2_ETH_RX_BUF_SIZE, dma_unmap_page(dev, addr, DPAA2_ETH_RX_BUF_SIZE,
DMA_BIDIRECTIONAL); DMA_BIDIRECTIONAL);
skb = build_linear_skb(ch, fd, vaddr); skb = build_linear_skb(ch, fd, vaddr);
} else if (fd_format == dpaa2_fd_sg) { } else if (fd_format == dpaa2_fd_sg) {
WARN_ON(priv->xdp_prog); WARN_ON(priv->xdp_prog);
dma_unmap_single(dev, addr, DPAA2_ETH_RX_BUF_SIZE, dma_unmap_page(dev, addr, DPAA2_ETH_RX_BUF_SIZE,
DMA_BIDIRECTIONAL); DMA_BIDIRECTIONAL);
skb = build_frag_skb(priv, ch, buf_data); skb = build_frag_skb(priv, ch, buf_data);
skb_free_frag(vaddr); free_pages((unsigned long)vaddr, 0);
percpu_extras->rx_sg_frames++; percpu_extras->rx_sg_frames++;
percpu_extras->rx_sg_bytes += dpaa2_fd_get_len(fd); percpu_extras->rx_sg_bytes += dpaa2_fd_get_len(fd);
} else { } else {
...@@ -657,7 +655,7 @@ static int build_single_fd(struct dpaa2_eth_priv *priv, ...@@ -657,7 +655,7 @@ static int build_single_fd(struct dpaa2_eth_priv *priv,
* dpaa2_eth_tx(). * dpaa2_eth_tx().
*/ */
static void free_tx_fd(const struct dpaa2_eth_priv *priv, static void free_tx_fd(const struct dpaa2_eth_priv *priv,
const struct dpaa2_fd *fd) const struct dpaa2_fd *fd, bool in_napi)
{ {
struct device *dev = priv->net_dev->dev.parent; struct device *dev = priv->net_dev->dev.parent;
dma_addr_t fd_addr; dma_addr_t fd_addr;
...@@ -712,7 +710,7 @@ static void free_tx_fd(const struct dpaa2_eth_priv *priv, ...@@ -712,7 +710,7 @@ static void free_tx_fd(const struct dpaa2_eth_priv *priv,
skb_free_frag(skbh); skb_free_frag(skbh);
/* Move on with skb release */ /* Move on with skb release */
dev_kfree_skb(skb); napi_consume_skb(skb, in_napi);
} }
static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct net_device *net_dev) static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct net_device *net_dev)
...@@ -785,9 +783,7 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct net_device *net_dev) ...@@ -785,9 +783,7 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct net_device *net_dev)
queue_mapping = skb_get_queue_mapping(skb); queue_mapping = skb_get_queue_mapping(skb);
fq = &priv->fq[queue_mapping]; fq = &priv->fq[queue_mapping];
for (i = 0; i < DPAA2_ETH_ENQUEUE_RETRIES; i++) { for (i = 0; i < DPAA2_ETH_ENQUEUE_RETRIES; i++) {
err = dpaa2_io_service_enqueue_qd(fq->channel->dpio, err = priv->enqueue(priv, fq, &fd, 0);
priv->tx_qdid, 0,
fq->tx_qdbin, &fd);
if (err != -EBUSY) if (err != -EBUSY)
break; break;
} }
...@@ -795,7 +791,7 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct net_device *net_dev) ...@@ -795,7 +791,7 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct net_device *net_dev)
if (unlikely(err < 0)) { if (unlikely(err < 0)) {
percpu_stats->tx_errors++; percpu_stats->tx_errors++;
/* Clean up everything, including freeing the skb */ /* Clean up everything, including freeing the skb */
free_tx_fd(priv, &fd); free_tx_fd(priv, &fd, false);
} else { } else {
fd_len = dpaa2_fd_get_len(&fd); fd_len = dpaa2_fd_get_len(&fd);
percpu_stats->tx_packets++; percpu_stats->tx_packets++;
...@@ -837,7 +833,7 @@ static void dpaa2_eth_tx_conf(struct dpaa2_eth_priv *priv, ...@@ -837,7 +833,7 @@ static void dpaa2_eth_tx_conf(struct dpaa2_eth_priv *priv,
/* Check frame errors in the FD field */ /* Check frame errors in the FD field */
fd_errors = dpaa2_fd_get_ctrl(fd) & DPAA2_FD_TX_ERR_MASK; fd_errors = dpaa2_fd_get_ctrl(fd) & DPAA2_FD_TX_ERR_MASK;
free_tx_fd(priv, fd); free_tx_fd(priv, fd, true);
if (likely(!fd_errors)) if (likely(!fd_errors))
return; return;
...@@ -903,7 +899,7 @@ static int add_bufs(struct dpaa2_eth_priv *priv, ...@@ -903,7 +899,7 @@ static int add_bufs(struct dpaa2_eth_priv *priv,
{ {
struct device *dev = priv->net_dev->dev.parent; struct device *dev = priv->net_dev->dev.parent;
u64 buf_array[DPAA2_ETH_BUFS_PER_CMD]; u64 buf_array[DPAA2_ETH_BUFS_PER_CMD];
void *buf; struct page *page;
dma_addr_t addr; dma_addr_t addr;
int i, err; int i, err;
...@@ -911,14 +907,16 @@ static int add_bufs(struct dpaa2_eth_priv *priv, ...@@ -911,14 +907,16 @@ static int add_bufs(struct dpaa2_eth_priv *priv,
/* Allocate buffer visible to WRIOP + skb shared info + /* Allocate buffer visible to WRIOP + skb shared info +
* alignment padding * alignment padding
*/ */
buf = napi_alloc_frag(dpaa2_eth_buf_raw_size(priv)); /* allocate one page for each Rx buffer. WRIOP sees
if (unlikely(!buf)) * the entire page except for a tailroom reserved for
* skb shared info
*/
page = dev_alloc_pages(0);
if (!page)
goto err_alloc; goto err_alloc;
buf = PTR_ALIGN(buf, priv->rx_buf_align); addr = dma_map_page(dev, page, 0, DPAA2_ETH_RX_BUF_SIZE,
DMA_BIDIRECTIONAL);
addr = dma_map_single(dev, buf, DPAA2_ETH_RX_BUF_SIZE,
DMA_BIDIRECTIONAL);
if (unlikely(dma_mapping_error(dev, addr))) if (unlikely(dma_mapping_error(dev, addr)))
goto err_map; goto err_map;
...@@ -926,7 +924,7 @@ static int add_bufs(struct dpaa2_eth_priv *priv, ...@@ -926,7 +924,7 @@ static int add_bufs(struct dpaa2_eth_priv *priv,
/* tracing point */ /* tracing point */
trace_dpaa2_eth_buf_seed(priv->net_dev, trace_dpaa2_eth_buf_seed(priv->net_dev,
buf, dpaa2_eth_buf_raw_size(priv), page, DPAA2_ETH_RX_BUF_RAW_SIZE,
addr, DPAA2_ETH_RX_BUF_SIZE, addr, DPAA2_ETH_RX_BUF_SIZE,
bpid); bpid);
} }
...@@ -948,7 +946,7 @@ static int add_bufs(struct dpaa2_eth_priv *priv, ...@@ -948,7 +946,7 @@ static int add_bufs(struct dpaa2_eth_priv *priv,
return i; return i;
err_map: err_map:
skb_free_frag(buf); __free_pages(page, 0);
err_alloc: err_alloc:
/* If we managed to allocate at least some buffers, /* If we managed to allocate at least some buffers,
* release them to hardware * release them to hardware
...@@ -2134,6 +2132,7 @@ static int set_buffer_layout(struct dpaa2_eth_priv *priv) ...@@ -2134,6 +2132,7 @@ static int set_buffer_layout(struct dpaa2_eth_priv *priv)
{ {
struct device *dev = priv->net_dev->dev.parent; struct device *dev = priv->net_dev->dev.parent;
struct dpni_buffer_layout buf_layout = {0}; struct dpni_buffer_layout buf_layout = {0};
u16 rx_buf_align;
int err; int err;
/* We need to check for WRIOP version 1.0.0, but depending on the MC /* We need to check for WRIOP version 1.0.0, but depending on the MC
...@@ -2142,9 +2141,9 @@ static int set_buffer_layout(struct dpaa2_eth_priv *priv) ...@@ -2142,9 +2141,9 @@ static int set_buffer_layout(struct dpaa2_eth_priv *priv)
*/ */
if (priv->dpni_attrs.wriop_version == DPAA2_WRIOP_VERSION(0, 0, 0) || if (priv->dpni_attrs.wriop_version == DPAA2_WRIOP_VERSION(0, 0, 0) ||
priv->dpni_attrs.wriop_version == DPAA2_WRIOP_VERSION(1, 0, 0)) priv->dpni_attrs.wriop_version == DPAA2_WRIOP_VERSION(1, 0, 0))
priv->rx_buf_align = DPAA2_ETH_RX_BUF_ALIGN_REV1; rx_buf_align = DPAA2_ETH_RX_BUF_ALIGN_REV1;
else else
priv->rx_buf_align = DPAA2_ETH_RX_BUF_ALIGN; rx_buf_align = DPAA2_ETH_RX_BUF_ALIGN;
/* tx buffer */ /* tx buffer */
buf_layout.private_data_size = DPAA2_ETH_SWA_SIZE; buf_layout.private_data_size = DPAA2_ETH_SWA_SIZE;
...@@ -2184,7 +2183,7 @@ static int set_buffer_layout(struct dpaa2_eth_priv *priv) ...@@ -2184,7 +2183,7 @@ static int set_buffer_layout(struct dpaa2_eth_priv *priv)
/* rx buffer */ /* rx buffer */
buf_layout.pass_frame_status = true; buf_layout.pass_frame_status = true;
buf_layout.pass_parser_result = true; buf_layout.pass_parser_result = true;
buf_layout.data_align = priv->rx_buf_align; buf_layout.data_align = rx_buf_align;
buf_layout.data_head_room = dpaa2_eth_rx_head_room(priv); buf_layout.data_head_room = dpaa2_eth_rx_head_room(priv);
buf_layout.private_data_size = 0; buf_layout.private_data_size = 0;
buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT | buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT |
...@@ -2202,6 +2201,36 @@ static int set_buffer_layout(struct dpaa2_eth_priv *priv) ...@@ -2202,6 +2201,36 @@ static int set_buffer_layout(struct dpaa2_eth_priv *priv)
return 0; return 0;
} }
#define DPNI_ENQUEUE_FQID_VER_MAJOR 7
#define DPNI_ENQUEUE_FQID_VER_MINOR 9
static inline int dpaa2_eth_enqueue_qd(struct dpaa2_eth_priv *priv,
struct dpaa2_eth_fq *fq,
struct dpaa2_fd *fd, u8 prio)
{
return dpaa2_io_service_enqueue_qd(fq->channel->dpio,
priv->tx_qdid, prio,
fq->tx_qdbin, fd);
}
static inline int dpaa2_eth_enqueue_fq(struct dpaa2_eth_priv *priv,
struct dpaa2_eth_fq *fq,
struct dpaa2_fd *fd,
u8 prio __always_unused)
{
return dpaa2_io_service_enqueue_fq(fq->channel->dpio,
fq->tx_fqid, fd);
}
static void set_enqueue_mode(struct dpaa2_eth_priv *priv)
{
if (dpaa2_eth_cmp_dpni_ver(priv, DPNI_ENQUEUE_FQID_VER_MAJOR,
DPNI_ENQUEUE_FQID_VER_MINOR) < 0)
priv->enqueue = dpaa2_eth_enqueue_qd;
else
priv->enqueue = dpaa2_eth_enqueue_fq;
}
/* Configure the DPNI object this interface is associated with */ /* Configure the DPNI object this interface is associated with */
static int setup_dpni(struct fsl_mc_device *ls_dev) static int setup_dpni(struct fsl_mc_device *ls_dev)
{ {
...@@ -2255,6 +2284,8 @@ static int setup_dpni(struct fsl_mc_device *ls_dev) ...@@ -2255,6 +2284,8 @@ static int setup_dpni(struct fsl_mc_device *ls_dev)
if (err) if (err)
goto close; goto close;
set_enqueue_mode(priv);
priv->cls_rules = devm_kzalloc(dev, sizeof(struct dpaa2_eth_cls_rule) * priv->cls_rules = devm_kzalloc(dev, sizeof(struct dpaa2_eth_cls_rule) *
dpaa2_eth_fs_count(priv), GFP_KERNEL); dpaa2_eth_fs_count(priv), GFP_KERNEL);
if (!priv->cls_rules) if (!priv->cls_rules)
...@@ -2339,6 +2370,7 @@ static int setup_tx_flow(struct dpaa2_eth_priv *priv, ...@@ -2339,6 +2370,7 @@ static int setup_tx_flow(struct dpaa2_eth_priv *priv,
} }
fq->tx_qdbin = qid.qdbin; fq->tx_qdbin = qid.qdbin;
fq->tx_fqid = qid.fqid;
err = dpni_get_queue(priv->mc_io, 0, priv->mc_token, err = dpni_get_queue(priv->mc_io, 0, priv->mc_token,
DPNI_QUEUE_TX_CONFIRM, 0, fq->flowid, DPNI_QUEUE_TX_CONFIRM, 0, fq->flowid,
......
...@@ -53,7 +53,8 @@ ...@@ -53,7 +53,8 @@
*/ */
#define DPAA2_ETH_MAX_FRAMES_PER_QUEUE (DPAA2_ETH_TAILDROP_THRESH / 64) #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_NUM_BUFS (DPAA2_ETH_MAX_FRAMES_PER_QUEUE + 256)
#define DPAA2_ETH_REFILL_THRESH DPAA2_ETH_MAX_FRAMES_PER_QUEUE #define DPAA2_ETH_REFILL_THRESH \
(DPAA2_ETH_NUM_BUFS - DPAA2_ETH_BUFS_PER_CMD)
/* Maximum number of buffers that can be acquired/released through a single /* Maximum number of buffers that can be acquired/released through a single
* QBMan command * QBMan command
...@@ -63,9 +64,11 @@ ...@@ -63,9 +64,11 @@
/* Hardware requires alignment for ingress/egress buffer addresses */ /* Hardware requires alignment for ingress/egress buffer addresses */
#define DPAA2_ETH_TX_BUF_ALIGN 64 #define DPAA2_ETH_TX_BUF_ALIGN 64
#define DPAA2_ETH_RX_BUF_SIZE 2048 #define DPAA2_ETH_RX_BUF_RAW_SIZE PAGE_SIZE
#define DPAA2_ETH_SKB_SIZE \ #define DPAA2_ETH_RX_BUF_TAILROOM \
(DPAA2_ETH_RX_BUF_SIZE + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) SKB_DATA_ALIGN(sizeof(struct skb_shared_info))
#define DPAA2_ETH_RX_BUF_SIZE \
(DPAA2_ETH_RX_BUF_RAW_SIZE - DPAA2_ETH_RX_BUF_TAILROOM)
/* Hardware annotation area in RX/TX buffers */ /* Hardware annotation area in RX/TX buffers */
#define DPAA2_ETH_RX_HWA_SIZE 64 #define DPAA2_ETH_RX_HWA_SIZE 64
...@@ -274,6 +277,7 @@ struct dpaa2_eth_priv; ...@@ -274,6 +277,7 @@ struct dpaa2_eth_priv;
struct dpaa2_eth_fq { struct dpaa2_eth_fq {
u32 fqid; u32 fqid;
u32 tx_qdbin; u32 tx_qdbin;
u32 tx_fqid;
u16 flowid; u16 flowid;
int target_cpu; int target_cpu;
u32 dq_frames; u32 dq_frames;
...@@ -326,6 +330,9 @@ struct dpaa2_eth_priv { ...@@ -326,6 +330,9 @@ struct dpaa2_eth_priv {
u8 num_fqs; u8 num_fqs;
struct dpaa2_eth_fq fq[DPAA2_ETH_MAX_QUEUES]; struct dpaa2_eth_fq fq[DPAA2_ETH_MAX_QUEUES];
int (*enqueue)(struct dpaa2_eth_priv *priv,
struct dpaa2_eth_fq *fq,
struct dpaa2_fd *fd, u8 prio);
u8 num_channels; u8 num_channels;
struct dpaa2_eth_channel *channel[DPAA2_ETH_MAX_DPCONS]; struct dpaa2_eth_channel *channel[DPAA2_ETH_MAX_DPCONS];
...@@ -343,7 +350,6 @@ struct dpaa2_eth_priv { ...@@ -343,7 +350,6 @@ struct dpaa2_eth_priv {
bool rx_tstamp; /* Rx timestamping enabled */ bool rx_tstamp; /* Rx timestamping enabled */
u16 tx_qdid; u16 tx_qdid;
u16 rx_buf_align;
struct fsl_mc_io *mc_io; struct fsl_mc_io *mc_io;
/* Cores which have an affine DPIO/DPCON. /* Cores which have an affine DPIO/DPCON.
* This is the cpu set on which Rx and Tx conf frames are processed * This is the cpu set on which Rx and Tx conf frames are processed
...@@ -418,15 +424,6 @@ enum dpaa2_eth_rx_dist { ...@@ -418,15 +424,6 @@ enum dpaa2_eth_rx_dist {
DPAA2_ETH_RX_DIST_CLS DPAA2_ETH_RX_DIST_CLS
}; };
/* 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 static inline
unsigned int dpaa2_eth_needed_headroom(struct dpaa2_eth_priv *priv, unsigned int dpaa2_eth_needed_headroom(struct dpaa2_eth_priv *priv,
struct sk_buff *skb) struct sk_buff *skb)
...@@ -451,8 +448,7 @@ unsigned int dpaa2_eth_needed_headroom(struct dpaa2_eth_priv *priv, ...@@ -451,8 +448,7 @@ unsigned int dpaa2_eth_needed_headroom(struct dpaa2_eth_priv *priv,
*/ */
static inline unsigned int dpaa2_eth_rx_head_room(struct dpaa2_eth_priv *priv) static inline unsigned int dpaa2_eth_rx_head_room(struct dpaa2_eth_priv *priv)
{ {
return priv->tx_data_offset + DPAA2_ETH_TX_BUF_ALIGN - return priv->tx_data_offset - DPAA2_ETH_RX_HWA_SIZE;
DPAA2_ETH_RX_HWA_SIZE;
} }
int dpaa2_eth_set_hash(struct net_device *net_dev, u64 flags); int dpaa2_eth_set_hash(struct net_device *net_dev, u64 flags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment