All of lore.kernel.org
 help / color / mirror / Atom feed
From: Horatiu Vultur <horatiu.vultur@microchip.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v2 3/8] net: mscc: Move ocelot_send and ocelot_recv in a different file.
Date: Wed, 30 Jan 2019 13:29:36 +0100	[thread overview]
Message-ID: <1548851381-21588-4-git-send-email-horatiu.vultur@microchip.com> (raw)
In-Reply-To: <1548851381-21588-1-git-send-email-horatiu.vultur@microchip.com>

This functions can be reused by other MSCC SoCs therefore,
make them more generic and move them in separate files.

Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
---
 drivers/net/mscc_eswitch/Makefile        |   2 +-
 drivers/net/mscc_eswitch/mscc_xfer.c     | 139 +++++++++++++++++++++++++++++++
 drivers/net/mscc_eswitch/mscc_xfer.h     |  20 +++++
 drivers/net/mscc_eswitch/ocelot_switch.c | 130 ++++-------------------------
 4 files changed, 175 insertions(+), 116 deletions(-)
 create mode 100644 drivers/net/mscc_eswitch/mscc_xfer.c
 create mode 100644 drivers/net/mscc_eswitch/mscc_xfer.h

diff --git a/drivers/net/mscc_eswitch/Makefile b/drivers/net/mscc_eswitch/Makefile
index 1ceb92a..20e8e4c 100644
--- a/drivers/net/mscc_eswitch/Makefile
+++ b/drivers/net/mscc_eswitch/Makefile
@@ -1,2 +1,2 @@
 
-obj-$(CONFIG_MSCC_OCELOT_SWITCH) += ocelot_switch.o mscc_miim.o
+obj-$(CONFIG_MSCC_OCELOT_SWITCH) += ocelot_switch.o mscc_miim.o mscc_xfer.o
diff --git a/drivers/net/mscc_eswitch/mscc_xfer.c b/drivers/net/mscc_eswitch/mscc_xfer.c
new file mode 100644
index 0000000..f412901
--- /dev/null
+++ b/drivers/net/mscc_eswitch/mscc_xfer.c
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#include <linux/io.h>
+#include "mscc_xfer.h"
+
+#define QS_XTR_FLUSH_FLUSH		GENMASK(1, 0)
+#define QS_INJ_CTRL_GAP_SIZE(x)		((x) << 21)
+#define QS_INJ_CTRL_EOF			BIT(19)
+#define QS_INJ_CTRL_SOF			BIT(18)
+#define QS_INJ_CTRL_VLD_BYTES(x)	((x) << 16)
+
+#define XTR_EOF_0     ntohl(0x80000000u)
+#define XTR_EOF_1     ntohl(0x80000001u)
+#define XTR_EOF_2     ntohl(0x80000002u)
+#define XTR_EOF_3     ntohl(0x80000003u)
+#define XTR_PRUNED    ntohl(0x80000004u)
+#define XTR_ABORT     ntohl(0x80000005u)
+#define XTR_ESCAPE    ntohl(0x80000006u)
+#define XTR_NOT_READY ntohl(0x80000007u)
+
+#define BUF_CELL_SZ		60
+#define XTR_VALID_BYTES(x)	(4 - ((x) & 3))
+
+int mscc_send(void __iomem *regs, const unsigned long *mscc_qs_offset,
+	      u32 *ifh, size_t ifh_len, u32 *buff, size_t buff_len)
+{
+	int i, count = (buff_len + 3) / 4, last = buff_len % 4;
+
+	writel(QS_INJ_CTRL_GAP_SIZE(1) | QS_INJ_CTRL_SOF,
+	       regs + mscc_qs_offset[MSCC_QS_INJ_CTRL]);
+
+	for (i = 0; i < ifh_len; i++)
+		writel(ifh[i], regs + mscc_qs_offset[MSCC_QS_INJ_WR]);
+
+	for (i = 0; i < count; i++)
+		writel(buff[i], regs + mscc_qs_offset[MSCC_QS_INJ_WR]);
+
+	/* Add padding */
+	while (i < (BUF_CELL_SZ / 4)) {
+		writel(0, regs + mscc_qs_offset[MSCC_QS_INJ_WR]);
+		i++;
+	}
+
+	/* Indicate EOF and valid bytes in last word */
+	writel(QS_INJ_CTRL_GAP_SIZE(1) |
+	       QS_INJ_CTRL_VLD_BYTES(buff_len < BUF_CELL_SZ ? 0 : last) |
+	       QS_INJ_CTRL_EOF, regs + mscc_qs_offset[MSCC_QS_INJ_CTRL]);
+
+	/* Add dummy CRC */
+	writel(0, regs + mscc_qs_offset[MSCC_QS_INJ_WR]);
+
+	return 0;
+}
+
+int mscc_recv(void __iomem *regs, const unsigned long *mscc_qs_offset,
+	      u32 *rxbuf, size_t ifh_len, bool byte_swap)
+{
+	u8 grp = 0; /* Recv everything on CPU group 0 */
+	int i, byte_cnt = 0;
+	bool eof_flag = false, pruned_flag = false, abort_flag = false;
+
+	if (!(readl(regs + mscc_qs_offset[MSCC_QS_XTR_DATA_PRESENT]) &
+	      BIT(grp)))
+		return -EAGAIN;
+
+	/* skip IFH */
+	for (i = 0; i < ifh_len; i++)
+		readl(regs + mscc_qs_offset[MSCC_QS_XTR_RD]);
+
+	while (!eof_flag) {
+		u32 val = readl(regs + mscc_qs_offset[MSCC_QS_XTR_RD]);
+		u32 cmp = val;
+
+		if (byte_swap)
+			cmp = ntohl(val);
+
+		switch (cmp) {
+		case XTR_NOT_READY:
+			debug("%d NOT_READY...?\n", byte_cnt);
+			break;
+		case XTR_ABORT:
+			*rxbuf = readl(regs + mscc_qs_offset[MSCC_QS_XTR_RD]);
+			abort_flag = true;
+			eof_flag = true;
+			debug("XTR_ABORT\n");
+			break;
+		case XTR_EOF_0:
+		case XTR_EOF_1:
+		case XTR_EOF_2:
+		case XTR_EOF_3:
+			byte_cnt += XTR_VALID_BYTES(val);
+			*rxbuf = readl(regs + mscc_qs_offset[MSCC_QS_XTR_RD]);
+			eof_flag = true;
+			debug("EOF\n");
+			break;
+		case XTR_PRUNED:
+			/* But get the last 4 bytes as well */
+			eof_flag = true;
+			pruned_flag = true;
+			debug("PRUNED\n");
+			/* fallthrough */
+		case XTR_ESCAPE:
+			*rxbuf = readl(regs + mscc_qs_offset[MSCC_QS_XTR_RD]);
+			byte_cnt += 4;
+			rxbuf++;
+			debug("ESCAPED\n");
+			break;
+		default:
+			*rxbuf = val;
+			byte_cnt += 4;
+			rxbuf++;
+		}
+	}
+
+	if (abort_flag || pruned_flag || !eof_flag) {
+		debug("Discarded frame: abort:%d pruned:%d eof:%d\n",
+		      abort_flag, pruned_flag, eof_flag);
+		return -EAGAIN;
+	}
+
+	return byte_cnt;
+}
+
+void mscc_flush(void __iomem *regs, const unsigned long *mscc_qs_offset)
+{
+	/* All Queues flush */
+	setbits_le32(regs + mscc_qs_offset[MSCC_QS_XTR_FLUSH],
+		     QS_XTR_FLUSH_FLUSH);
+
+	/* Allow to drain */
+	mdelay(1);
+
+	/* All Queues normal */
+	clrbits_le32(regs + mscc_qs_offset[MSCC_QS_XTR_FLUSH],
+		     QS_XTR_FLUSH_FLUSH);
+}
diff --git a/drivers/net/mscc_eswitch/mscc_xfer.h b/drivers/net/mscc_eswitch/mscc_xfer.h
new file mode 100644
index 0000000..c880a4e
--- /dev/null
+++ b/drivers/net/mscc_eswitch/mscc_xfer.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#include <common.h>
+
+enum mscc_regs_qs {
+	MSCC_QS_XTR_RD,
+	MSCC_QS_XTR_FLUSH,
+	MSCC_QS_XTR_DATA_PRESENT,
+	MSCC_QS_INJ_WR,
+	MSCC_QS_INJ_CTRL,
+};
+
+int mscc_send(void __iomem *regs, const unsigned long *mscc_qs_offset,
+	      u32 *ifh, size_t ifh_len, u32 *buff, size_t buff_len);
+int mscc_recv(void __iomem *regs, const unsigned long *mscc_qs_offset,
+	      u32 *rxbuf, size_t ifh_len, bool byte_swap);
+void mscc_flush(void __iomem *regs, const unsigned long *mscc_qs_offset);
diff --git a/drivers/net/mscc_eswitch/ocelot_switch.c b/drivers/net/mscc_eswitch/ocelot_switch.c
index a4361e8..c33ecd4 100644
--- a/drivers/net/mscc_eswitch/ocelot_switch.c
+++ b/drivers/net/mscc_eswitch/ocelot_switch.c
@@ -16,6 +16,7 @@
 #include <wait_bit.h>
 
 #include "mscc_miim.h"
+#include "mscc_xfer.h"
 
 #define PHY_CFG				0x0
 #define PHY_CFG_ENA				0xF
@@ -87,37 +88,16 @@
 #define QS_XTR_GRP_CFG_MODE(x)			((x) << 2)
 #define		QS_XTR_GRP_CFG_STATUS_WORD_POS	BIT(1)
 #define		QS_XTR_GRP_CFG_BYTE_SWAP	BIT(0)
-#define QS_XTR_RD(x)			(0x8 + 4 * (x))
-#define QS_XTR_FLUSH			0x18
-#define		QS_XTR_FLUSH_FLUSH		GENMASK(1, 0)
-#define QS_XTR_DATA_PRESENT		0x1c
 #define QS_INJ_GRP_CFG(x)		(0x24 + (x) * 4)
 #define		QS_INJ_GRP_CFG_MODE(x)		((x) << 2)
 #define		QS_INJ_GRP_CFG_BYTE_SWAP	BIT(0)
-#define QS_INJ_WR(x)			(0x2c + 4 * (x))
-#define QS_INJ_CTRL(x)			(0x34 + 4 * (x))
-#define		QS_INJ_CTRL_GAP_SIZE(x)		((x) << 21)
-#define		QS_INJ_CTRL_EOF			BIT(19)
-#define		QS_INJ_CTRL_SOF			BIT(18)
-#define		QS_INJ_CTRL_VLD_BYTES(x)	((x) << 16)
-
-#define XTR_EOF_0     ntohl(0x80000000u)
-#define XTR_EOF_1     ntohl(0x80000001u)
-#define XTR_EOF_2     ntohl(0x80000002u)
-#define XTR_EOF_3     ntohl(0x80000003u)
-#define XTR_PRUNED    ntohl(0x80000004u)
-#define XTR_ABORT     ntohl(0x80000005u)
-#define XTR_ESCAPE    ntohl(0x80000006u)
-#define XTR_NOT_READY ntohl(0x80000007u)
 
 #define IFH_INJ_BYPASS		BIT(31)
 #define	IFH_TAG_TYPE_C		0
-#define XTR_VALID_BYTES(x)	(4 - ((x) & 3))
 #define	MAC_VID			1
 #define CPU_PORT		11
 #define INTERNAL_PORT_MSK	0xF
 #define IFH_LEN			4
-#define OCELOT_BUF_CELL_SZ	60
 #define ETH_ALEN		6
 #define	PGID_BROADCAST		13
 #define	PGID_UNICAST		14
@@ -181,6 +161,14 @@ struct ocelot_private {
 	void *tx_adj_buf;
 };
 
+static const unsigned long ocelot_regs_qs[] = {
+	[MSCC_QS_XTR_RD] = 0x8,
+	[MSCC_QS_XTR_FLUSH] = 0x18,
+	[MSCC_QS_XTR_DATA_PRESENT] = 0x1c,
+	[MSCC_QS_INJ_WR] = 0x2c,
+	[MSCC_QS_INJ_CTRL] = 0x34,
+};
+
 struct mscc_miim_dev miim[NUM_PHY];
 
 static int mscc_miim_reset(struct mii_dev *bus)
@@ -367,16 +355,6 @@ static int ocelot_switch_init(struct ocelot_private *priv)
 	return 0;
 }
 
-static void ocelot_switch_flush(struct ocelot_private *priv)
-{
-	/* All Queues flush */
-	setbits_le32(priv->regs[QS] + QS_XTR_FLUSH, QS_XTR_FLUSH_FLUSH);
-	/* Allow to drain */
-	mdelay(1);
-	/* All Queues normal */
-	clrbits_le32(priv->regs[QS] + QS_XTR_FLUSH, QS_XTR_FLUSH_FLUSH);
-}
-
 static int ocelot_initialize(struct ocelot_private *priv)
 {
 	int ret, i;
@@ -394,7 +372,7 @@ static int ocelot_initialize(struct ocelot_private *priv)
 		writel(0, priv->regs[ANA] + ANA_PGID(PGID_SRC + i));
 
 	/* Flush queues */
-	ocelot_switch_flush(priv);
+	mscc_flush(priv->regs[QS], ocelot_regs_qs);
 
 	/* Setup frame ageing - "2 sec" - The unit is 6.5us on Ocelot */
 	writel(SYS_FRM_AGING_ENA | (20000000 / 65),
@@ -503,13 +481,8 @@ static int ocelot_send(struct udevice *dev, void *packet, int length)
 	struct ocelot_private *priv = dev_get_priv(dev);
 	u32 ifh[IFH_LEN];
 	int port = BIT(0);	/* use port 0 */
-	u8 grp = 0;		/* Send everything on CPU group 0 */
-	int i, count = (length + 3) / 4, last = length % 4;
 	u32 *buf = packet;
 
-	writel(QS_INJ_CTRL_GAP_SIZE(1) | QS_INJ_CTRL_SOF,
-	       priv->regs[QS] + QS_INJ_CTRL(grp));
-
 	/*
 	 * Generate the IFH for frame injection
 	 *
@@ -526,91 +499,18 @@ static int ocelot_send(struct udevice *dev, void *packet, int length)
 	ifh[2] = (0xff & port) << 24;
 	ifh[3] = (IFH_TAG_TYPE_C << 16);
 
-	for (i = 0; i < IFH_LEN; i++)
-		writel(ifh[i], priv->regs[QS] + QS_INJ_WR(grp));
-
-	for (i = 0; i < count; i++)
-		writel(buf[i], priv->regs[QS] + QS_INJ_WR(grp));
-
-	/* Add padding */
-	while (i < (OCELOT_BUF_CELL_SZ / 4)) {
-		writel(0, priv->regs[QS] + QS_INJ_WR(grp));
-		i++;
-	}
-
-	/* Indicate EOF and valid bytes in last word */
-	writel(QS_INJ_CTRL_GAP_SIZE(1) |
-	       QS_INJ_CTRL_VLD_BYTES(length < OCELOT_BUF_CELL_SZ ? 0 : last) |
-	       QS_INJ_CTRL_EOF, priv->regs[QS] + QS_INJ_CTRL(grp));
-
-	/* Add dummy CRC */
-	writel(0, priv->regs[QS] + QS_INJ_WR(grp));
-
-	return 0;
+	return mscc_send(priv->regs[QS], ocelot_regs_qs,
+			 ifh, IFH_LEN, buf, length);
 }
 
 static int ocelot_recv(struct udevice *dev, int flags, uchar **packetp)
 {
 	struct ocelot_private *priv = dev_get_priv(dev);
-	u8 grp = 0;		/* Send everything on CPU group 0 */
 	u32 *rxbuf = (u32 *)net_rx_packets[0];
-	int i, byte_cnt = 0;
-	bool eof_flag = false, pruned_flag = false, abort_flag = false;
-
-	if (!(readl(priv->regs[QS] + QS_XTR_DATA_PRESENT) & BIT(grp)))
-		return -EAGAIN;
-
-	/* skip IFH */
-	for (i = 0; i < IFH_LEN; i++)
-		readl(priv->regs[QS] + QS_XTR_RD(grp));
-
-	while (!eof_flag) {
-		u32 val = readl(priv->regs[QS] + QS_XTR_RD(grp));
-
-		switch (val) {
-		case XTR_NOT_READY:
-			debug("%d NOT_READY...?\n", byte_cnt);
-			break;
-		case XTR_ABORT:
-			/* really nedeed?? not done in linux */
-			*rxbuf = readl(priv->regs[QS] + QS_XTR_RD(grp));
-			abort_flag = true;
-			eof_flag = true;
-			debug("XTR_ABORT\n");
-			break;
-		case XTR_EOF_0:
-		case XTR_EOF_1:
-		case XTR_EOF_2:
-		case XTR_EOF_3:
-			byte_cnt += XTR_VALID_BYTES(val);
-			*rxbuf = readl(priv->regs[QS] + QS_XTR_RD(grp));
-			eof_flag = true;
-			debug("EOF\n");
-			break;
-		case XTR_PRUNED:
-			/* But get the last 4 bytes as well */
-			eof_flag = true;
-			pruned_flag = true;
-			debug("PRUNED\n");
-			/* fallthrough */
-		case XTR_ESCAPE:
-			*rxbuf = readl(priv->regs[QS] + QS_XTR_RD(grp));
-			byte_cnt += 4;
-			rxbuf++;
-			debug("ESCAPED\n");
-			break;
-		default:
-			*rxbuf = val;
-			byte_cnt += 4;
-			rxbuf++;
-		}
-	}
+	int byte_cnt;
 
-	if (abort_flag || pruned_flag || !eof_flag) {
-		debug("Discarded frame: abort:%d pruned:%d eof:%d\n",
-		      abort_flag, pruned_flag, eof_flag);
-		return -EAGAIN;
-	}
+	byte_cnt = mscc_recv(priv->regs[QS], ocelot_regs_qs, rxbuf, IFH_LEN,
+			     false);
 
 	*packetp = net_rx_packets[0];
 
-- 
2.7.4

  parent reply	other threads:[~2019-01-30 12:29 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-30 12:29 [U-Boot] [PATCH v2 0/8] Add network support for Luton SoCs Horatiu Vultur
2019-01-30 12:29 ` [U-Boot] [PATCH v2 1/8] net: mscc: Move ocelot_switch to mscc_switch folder Horatiu Vultur
2019-01-30 12:29 ` [U-Boot] [PATCH v2 2/8] net: mscc: Move miim commands into separate file Horatiu Vultur
2019-01-30 12:29 ` Horatiu Vultur [this message]
2019-01-30 12:29 ` [U-Boot] [PATCH v2 4/8] net: mscc: Move mac_table_add function into different file Horatiu Vultur
2019-01-30 12:29 ` [U-Boot] [PATCH v2 5/8] net: mscc: Remove unused variables Horatiu Vultur
2019-01-30 12:29 ` [U-Boot] [PATCH v2 6/8] mips: mscc: luton: Add ethernet nodes for Luton Horatiu Vultur
2019-01-30 12:29 ` [U-Boot] [PATCH v2 7/8] net: Add MSCC Luton networkd driver Horatiu Vultur
2019-01-30 16:22   ` Daniel Schwierzeck
2019-01-30 12:29 ` [U-Boot] [PATCH v2 8/8] configs: mscc_luton: Add network support Horatiu Vultur

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1548851381-21588-4-git-send-email-horatiu.vultur@microchip.com \
    --to=horatiu.vultur@microchip.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.