Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8a4fd877 authored by Bogdan Purcareata's avatar Bogdan Purcareata Committed by Greg Kroah-Hartman
Browse files

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: default avatarBogdan Purcareata <bogdan.purcareata@nxp.com>
Signed-off-by: default avatarIoana Radulescu <ruxandra.radulescu@nxp.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 3c219286
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -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 |
+19 −8
Original line number Diff line number Diff line
@@ -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;