struct sk_buff **skbh;
dma_addr_t addr;
- buffer_start = PTR_ALIGN(skb->data - dpaa2_eth_needed_headroom(priv),
+ buffer_start = PTR_ALIGN(skb->data -
+ dpaa2_eth_needed_headroom(priv, skb),
DPAA2_ETH_TX_BUF_ALIGN);
/* Store a backpointer to the skb at the beginning of the buffer
struct dpaa2_eth_drv_stats *percpu_extras;
struct dpaa2_eth_fq *fq;
u16 queue_mapping;
+ unsigned int needed_headroom;
int err, i;
percpu_stats = this_cpu_ptr(priv->percpu_stats);
percpu_extras = this_cpu_ptr(priv->percpu_extras);
- if (skb_headroom(skb) < dpaa2_eth_needed_headroom(priv)) {
+ needed_headroom = dpaa2_eth_needed_headroom(priv, skb);
+ if (skb_headroom(skb) < needed_headroom) {
struct sk_buff *ns;
- ns = skb_realloc_headroom(skb, dpaa2_eth_needed_headroom(priv));
+ ns = skb_realloc_headroom(skb, needed_headroom);
if (unlikely(!ns)) {
percpu_stats->tx_dropped++;
goto err_alloc_headroom;
}
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)
{
- return priv->tx_data_offset + DPAA2_ETH_TX_BUF_ALIGN;
+ if (skb_is_nonlinear(skb))
+ return 0;
+
+ return DPAA2_ETH_SWA_SIZE + DPAA2_ETH_TX_BUF_ALIGN;
}
/* Extra headroom space requested to hardware, in order to make sure there's
*/
static inline unsigned int dpaa2_eth_rx_head_room(struct dpaa2_eth_priv *priv)
{
- return dpaa2_eth_needed_headroom(priv) - DPAA2_ETH_RX_HWA_SIZE;
+ 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)