diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c index d68c1f5f8746..d65950d7f06b 100644 --- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c +++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c @@ -766,11 +766,11 @@ static int add_bufs(struct dpaa2_eth_priv *priv, u16 bpid) /* Allocate buffer visible to WRIOP + skb shared info + * alignment padding */ - buf = napi_alloc_frag(DPAA2_ETH_BUF_RAW_SIZE); + buf = napi_alloc_frag(dpaa2_eth_buf_raw_size(priv)); if (unlikely(!buf)) goto err_alloc; - buf = PTR_ALIGN(buf, DPAA2_ETH_RX_BUF_ALIGN); + buf = PTR_ALIGN(buf, priv->rx_buf_align); addr = dma_map_single(dev, buf, DPAA2_ETH_RX_BUF_SIZE, DMA_FROM_DEVICE); @@ -781,7 +781,7 @@ static int add_bufs(struct dpaa2_eth_priv *priv, u16 bpid) /* tracing point */ trace_dpaa2_eth_buf_seed(priv->net_dev, - buf, DPAA2_ETH_BUF_RAW_SIZE, + buf, dpaa2_eth_buf_raw_size(priv), addr, DPAA2_ETH_RX_BUF_SIZE, bpid); } @@ -1782,11 +1782,21 @@ static int set_buffer_layout(struct dpaa2_eth_priv *priv) struct dpni_buffer_layout buf_layout = {0}; int err; + /* We need to check for WRIOP version 1.0.0, but depending on the MC + * version, this number is not always provided correctly on rev1. + * We need to check for both alternatives in this situation. + */ + if (priv->dpni_attrs.wriop_version == DPAA2_WRIOP_VERSION(0, 0, 0) || + priv->dpni_attrs.wriop_version == DPAA2_WRIOP_VERSION(1, 0, 0)) + priv->rx_buf_align = DPAA2_ETH_RX_BUF_ALIGN_REV1; + else + priv->rx_buf_align = DPAA2_ETH_RX_BUF_ALIGN; + /* rx buffer */ buf_layout.pass_parser_result = true; buf_layout.pass_frame_status = true; buf_layout.private_data_size = DPAA2_ETH_SWA_SIZE; - buf_layout.data_align = DPAA2_ETH_RX_BUF_ALIGN; + buf_layout.data_align = priv->rx_buf_align; buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT | DPNI_BUF_LAYOUT_OPT_FRAME_STATUS | DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE | diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.h b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.h index bfbabae1aad8..749bd6be39c1 100644 --- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.h +++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.h @@ -45,6 +45,8 @@ #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, @@ -85,18 +87,15 @@ */ #define DPAA2_ETH_RX_BUF_SIZE 2048 #define DPAA2_ETH_TX_BUF_ALIGN 64 -#define DPAA2_ETH_RX_BUF_ALIGN 256 + #define DPAA2_ETH_NEEDED_HEADROOM(p_priv) \ ((p_priv)->tx_data_offset + DPAA2_ETH_TX_BUF_ALIGN) -/* Hardware only sees DPAA2_ETH_RX_BUF_SIZE, but we need to allocate ingress - * buffers large enough to allow building an skb around them and also account - * for alignment restrictions +/* 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_BUF_RAW_SIZE \ - (DPAA2_ETH_RX_BUF_SIZE + \ - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) + \ - DPAA2_ETH_RX_BUF_ALIGN) +#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 @@ -318,6 +317,7 @@ struct dpaa2_eth_priv { struct iommu_domain *iommu_domain; 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 @@ -353,6 +353,17 @@ struct dpaa2_eth_priv { extern const struct ethtool_ops dpaa2_ethtool_ops; extern const char dpaa2_eth_drv_version[]; +/* Hardware only sees DPAA2_ETH_RX_BUF_SIZE, but we need to allocate ingress + * buffers large enough to allow building an skb around them and also account + * for alignment restrictions + */ +static inline unsigned int dpaa2_eth_buf_raw_size(struct dpaa2_eth_priv *priv) +{ + return DPAA2_ETH_RX_BUF_SIZE + + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) + + priv->rx_buf_align; +} + static int dpaa2_eth_queue_count(struct dpaa2_eth_priv *priv) { return priv->dpni_attrs.num_queues;