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
next prev 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.