Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

staging: fsl-dpaa2/eth: Change RX buffer alignment

The WRIOP hardware block v1.0.0 (found on LS2080A board)
requires data in RX buffers to be aligned to 256B, but
newer revisions (e.g. on LS2088A, LS1088A) only require
64B alignment.

Check WRIOP version and decide at runtime which alignment
requirement to configure for ingress buffers.

Signed-off-by: Bogdan Purcareata <bogdan.purcareata@nxp.com>
Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Bogdan Purcareata and committed by
Greg Kroah-Hartman
8a4fd877 3c219286

+33 -12
+14 -4
drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
··· 766 766 /* Allocate buffer visible to WRIOP + skb shared info + 767 767 * alignment padding 768 768 */ 769 - buf = napi_alloc_frag(DPAA2_ETH_BUF_RAW_SIZE); 769 + buf = napi_alloc_frag(dpaa2_eth_buf_raw_size(priv)); 770 770 if (unlikely(!buf)) 771 771 goto err_alloc; 772 772 773 - buf = PTR_ALIGN(buf, DPAA2_ETH_RX_BUF_ALIGN); 773 + buf = PTR_ALIGN(buf, priv->rx_buf_align); 774 774 775 775 addr = dma_map_single(dev, buf, DPAA2_ETH_RX_BUF_SIZE, 776 776 DMA_FROM_DEVICE); ··· 781 781 782 782 /* tracing point */ 783 783 trace_dpaa2_eth_buf_seed(priv->net_dev, 784 - buf, DPAA2_ETH_BUF_RAW_SIZE, 784 + buf, dpaa2_eth_buf_raw_size(priv), 785 785 addr, DPAA2_ETH_RX_BUF_SIZE, 786 786 bpid); 787 787 } ··· 1782 1782 struct dpni_buffer_layout buf_layout = {0}; 1783 1783 int err; 1784 1784 1785 + /* We need to check for WRIOP version 1.0.0, but depending on the MC 1786 + * version, this number is not always provided correctly on rev1. 1787 + * We need to check for both alternatives in this situation. 1788 + */ 1789 + if (priv->dpni_attrs.wriop_version == DPAA2_WRIOP_VERSION(0, 0, 0) || 1790 + priv->dpni_attrs.wriop_version == DPAA2_WRIOP_VERSION(1, 0, 0)) 1791 + priv->rx_buf_align = DPAA2_ETH_RX_BUF_ALIGN_REV1; 1792 + else 1793 + priv->rx_buf_align = DPAA2_ETH_RX_BUF_ALIGN; 1794 + 1785 1795 /* rx buffer */ 1786 1796 buf_layout.pass_parser_result = true; 1787 1797 buf_layout.pass_frame_status = true; 1788 1798 buf_layout.private_data_size = DPAA2_ETH_SWA_SIZE; 1789 - buf_layout.data_align = DPAA2_ETH_RX_BUF_ALIGN; 1799 + buf_layout.data_align = priv->rx_buf_align; 1790 1800 buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT | 1791 1801 DPNI_BUF_LAYOUT_OPT_FRAME_STATUS | 1792 1802 DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE |
+19 -8
drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.h
··· 45 45 46 46 #include "dpaa2-eth-trace.h" 47 47 48 + #define DPAA2_WRIOP_VERSION(x, y, z) ((x) << 10 | (y) << 5 | (z) << 0) 49 + 48 50 #define DPAA2_ETH_STORE_SIZE 16 49 51 50 52 /* Maximum number of scatter-gather entries in an ingress frame, ··· 87 85 */ 88 86 #define DPAA2_ETH_RX_BUF_SIZE 2048 89 87 #define DPAA2_ETH_TX_BUF_ALIGN 64 90 - #define DPAA2_ETH_RX_BUF_ALIGN 256 88 + 91 89 #define DPAA2_ETH_NEEDED_HEADROOM(p_priv) \ 92 90 ((p_priv)->tx_data_offset + DPAA2_ETH_TX_BUF_ALIGN) 93 91 94 - /* Hardware only sees DPAA2_ETH_RX_BUF_SIZE, but we need to allocate ingress 95 - * buffers large enough to allow building an skb around them and also account 96 - * for alignment restrictions 92 + /* Due to a limitation in WRIOP 1.0.0, the RX buffer data must be aligned 93 + * to 256B. For newer revisions, the requirement is only for 64B alignment 97 94 */ 98 - #define DPAA2_ETH_BUF_RAW_SIZE \ 99 - (DPAA2_ETH_RX_BUF_SIZE + \ 100 - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) + \ 101 - DPAA2_ETH_RX_BUF_ALIGN) 95 + #define DPAA2_ETH_RX_BUF_ALIGN_REV1 256 96 + #define DPAA2_ETH_RX_BUF_ALIGN 64 102 97 103 98 /* We are accommodating a skb backpointer and some S/G info 104 99 * in the frame's software annotation. The hardware ··· 317 318 struct iommu_domain *iommu_domain; 318 319 319 320 u16 tx_qdid; 321 + u16 rx_buf_align; 320 322 struct fsl_mc_io *mc_io; 321 323 /* Cores which have an affine DPIO/DPCON. 322 324 * This is the cpu set on which Rx and Tx conf frames are processed ··· 352 352 353 353 extern const struct ethtool_ops dpaa2_ethtool_ops; 354 354 extern const char dpaa2_eth_drv_version[]; 355 + 356 + /* Hardware only sees DPAA2_ETH_RX_BUF_SIZE, but we need to allocate ingress 357 + * buffers large enough to allow building an skb around them and also account 358 + * for alignment restrictions 359 + */ 360 + static inline unsigned int dpaa2_eth_buf_raw_size(struct dpaa2_eth_priv *priv) 361 + { 362 + return DPAA2_ETH_RX_BUF_SIZE + 363 + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) + 364 + priv->rx_buf_align; 365 + } 355 366 356 367 static int dpaa2_eth_queue_count(struct dpaa2_eth_priv *priv) 357 368 {