netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Claudiu Manoil <claudiu.manoil@nxp.com>
To: "David S . Miller" <davem@davemloft.net>
Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>,
	Rob Herring <robh+dt@kernel.org>,
	Allan Nielsen <Allan.Nielsen@microsemi.com>,
	alexandru.marginean@nxp.com, netdev@vger.kernel.org,
	devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, UNGLinuxDriver@microchip.com,
	Catalin Horghidan <catalin.horghidan@gmail.com>
Subject: [PATCH net-next 6/6] net/mssc/ocelot: Add basic Felix switch driver
Date: Fri, 21 Jun 2019 18:38:52 +0300	[thread overview]
Message-ID: <1561131532-14860-7-git-send-email-claudiu.manoil@nxp.com> (raw)
In-Reply-To: <1561131532-14860-1-git-send-email-claudiu.manoil@nxp.com>

This supports a switch core ethernet device from Microsemi
(VSC9959) that can be integrated on different SoCs as a PCIe
endpoint device.

The switchdev functionality is provided by the core Ocelot
switch driver. In this regard, the current driver is an
instance of Microsemi's Ocelot core driver.

The patch adds the PCI device driver part and defines the
register map for the Felix switch core, as it has some
differences in register addresses and bitfield mappings
compared to the Ocelot switch.  Also some registers or
bitfields present on Ocelot are not available on Felix.
That's why this driver has its own register map instance.
Other than that, the common registers and bitfields have the
same functionality and share the same name.

In a few cases, some h/w operations have to be done differently
on Felix due to missing bitfields.  This is the case for the
switch core reset and init.  Because for this operation Ocelot
uses some bits that are not present on Felix, the later has to
use a register from the global registers block (GCB) instead.

Signed-off-by: Catalin Horghidan <catalin.horghidan@gmail.com>
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
---
 drivers/net/ethernet/mscc/Kconfig       |   8 +
 drivers/net/ethernet/mscc/Makefile      |   9 +-
 drivers/net/ethernet/mscc/felix_board.c | 392 +++++++++++++++++++++
 drivers/net/ethernet/mscc/felix_regs.c  | 448 ++++++++++++++++++++++++
 drivers/net/ethernet/mscc/ocelot.h      |   7 +
 5 files changed, 862 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ethernet/mscc/felix_board.c
 create mode 100644 drivers/net/ethernet/mscc/felix_regs.c

diff --git a/drivers/net/ethernet/mscc/Kconfig b/drivers/net/ethernet/mscc/Kconfig
index bcec0587cf61..e5a7fa69307e 100644
--- a/drivers/net/ethernet/mscc/Kconfig
+++ b/drivers/net/ethernet/mscc/Kconfig
@@ -29,4 +29,12 @@ config MSCC_OCELOT_SWITCH_OCELOT
 	  This driver supports the Ocelot network switch device as present on
 	  the Ocelot SoCs.
 
+config MSCC_FELIX_SWITCH
+	tristate "Felix switch driver"
+	depends on MSCC_OCELOT_SWITCH
+	depends on PCI
+	help
+	  This driver supports the Felix network switch device, connected as a
+	  PCI device.
+
 endif # NET_VENDOR_MICROSEMI
diff --git a/drivers/net/ethernet/mscc/Makefile b/drivers/net/ethernet/mscc/Makefile
index 9a36c26095c8..81593feb2ea1 100644
--- a/drivers/net/ethernet/mscc/Makefile
+++ b/drivers/net/ethernet/mscc/Makefile
@@ -1,5 +1,10 @@
 # SPDX-License-Identifier: (GPL-2.0 OR MIT)
 obj-$(CONFIG_MSCC_OCELOT_SWITCH) += mscc_ocelot_common.o
 mscc_ocelot_common-y := ocelot.o ocelot_io.o
-mscc_ocelot_common-y += ocelot_regs.o ocelot_tc.o ocelot_police.o ocelot_ace.o ocelot_flower.o
-obj-$(CONFIG_MSCC_OCELOT_SWITCH_OCELOT) += ocelot_board.o
+mscc_ocelot_common-y += ocelot_tc.o ocelot_police.o ocelot_ace.o ocelot_flower.o
+
+obj-$(CONFIG_MSCC_OCELOT_SWITCH_OCELOT) += mscc_ocelot.o
+mscc_ocelot-$(CONFIG_MSCC_OCELOT_SWITCH_OCELOT) := ocelot_regs.o ocelot_board.o
+
+obj-$(CONFIG_MSCC_FELIX_SWITCH) += mscc_felix.o
+mscc_felix-$(CONFIG_MSCC_FELIX_SWITCH) := felix_regs.o felix_board.o
diff --git a/drivers/net/ethernet/mscc/felix_board.c b/drivers/net/ethernet/mscc/felix_board.c
new file mode 100644
index 000000000000..57f7a897b3ae
--- /dev/null
+++ b/drivers/net/ethernet/mscc/felix_board.c
@@ -0,0 +1,392 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/* Felix Switch driver
+ *
+ * Copyright 2018-2019 NXP
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/phy_fixed.h>
+#include <linux/phy.h>
+#include <linux/of_mdio.h>
+#include <linux/of_net.h>
+#include <linux/iopoll.h>
+#include <net/switchdev.h>
+#include "ocelot.h"
+
+#define FELIX_DRV_VER_MAJ 1
+#define FELIX_DRV_VER_MIN 0
+
+#define FELIX_DRV_STR	"Felix Switch driver"
+#define FELIX_DRV_VER_STR __stringify(FELIX_DRV_VER_MAJ) "." \
+			  __stringify(FELIX_DRV_VER_MIN)
+
+#define PCI_DEVICE_ID_FELIX	0xEEF0
+
+/* Switch register block BAR */
+#define FELIX_SWITCH_BAR	4
+
+static struct pci_device_id felix_ids[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, PCI_DEVICE_ID_FELIX) },
+	{ 0, }
+};
+MODULE_DEVICE_TABLE(pci, felix_ids);
+
+static struct {
+	enum ocelot_target id;
+	struct resource res;
+} felix_io_res[] = {
+	{	.id = ANA,
+		{
+			.start = 0x0280000,
+			.end = 0x028ffff,
+			.name = "ana",
+		}
+	},
+	{	.id = QS,
+		{
+			.start = 0x0080000,
+			.end = 0x00800ff,
+			.name = "qs",
+		}
+	},
+	{	.id = QSYS,
+		{
+			.start = 0x0200000,
+			.end = 0x021ffff,
+			.name = "qsys",
+		}
+	},
+	{	.id = REW,
+		{
+			.start = 0x0030000,
+			.end = 0x003ffff,
+			.name = "rew",
+		}
+	},
+	{	.id = SYS,
+		{
+			.start = 0x0010000,
+			.end = 0x001ffff,
+			.name = "sys",
+		}
+	},
+	{	.id = S2,
+		{
+			.start = 0x0060000,
+			.end = 0x00603ff,
+			.name = "s2",
+		}
+	},
+	{	.id = GCB,
+		{
+			.start = 0x0070000,
+			.end = 0x00701ff,
+			.name = "devcpu_gcb",
+		}
+	}
+};
+
+#define FELIX_MAX_NUM_PHY_PORTS	6
+
+#define FELIX_PORT_RES_START	0x0100000
+#define FELIX_PORT_RES_SIZE	0x10000
+
+static void __iomem *regs;
+
+static void felix_release_ports(struct ocelot *ocelot)
+{
+	struct ocelot_port *ocelot_port;
+	struct phy_device *phydev;
+	struct device_node *dn;
+	int i;
+
+	for (i = 0; i < ocelot->num_phys_ports; i++) {
+		ocelot_port = ocelot->ports[i];
+		if (!ocelot_port || !ocelot_port->phy || !ocelot_port->dev)
+			continue;
+
+		phydev = ocelot_port->phy;
+		unregister_netdev(ocelot_port->dev);
+		free_netdev(ocelot_port->dev);
+
+		if (phy_is_pseudo_fixed_link(phydev)) {
+			dn = phydev->mdio.dev.of_node;
+			/* decr refcnt: of_phy_register_fixed_link */
+			of_phy_deregister_fixed_link(dn);
+		}
+		phy_device_free(phydev); /* decr refcnt: of_phy_find_device */
+	}
+}
+
+static int felix_ports_init(struct pci_dev *pdev)
+{
+	struct ocelot *ocelot = pci_get_drvdata(pdev);
+	struct device_node *np = ocelot->dev->of_node;
+	struct device_node *phy_node, *portnp;
+	struct phy_device *phydev;
+	void __iomem *port_regs;
+	resource_size_t base;
+	u32 port;
+	int err;
+
+	ocelot->num_phys_ports = FELIX_MAX_NUM_PHY_PORTS;
+
+	np = of_get_child_by_name(np, "ethernet-ports");
+	if (!np) {
+		dev_err(&pdev->dev, "ethernet-ports sub-node not found\n");
+		return -ENODEV;
+	}
+
+	/* alloc netdev for each port */
+	err = ocelot_init(ocelot);
+	if (err)
+		return err;
+
+	base = pci_resource_start(pdev, FELIX_SWITCH_BAR);
+	for_each_available_child_of_node(np, portnp) {
+		struct resource res = {};
+		int phy_mode;
+
+		if (!portnp || !portnp->name ||
+		    of_node_cmp(portnp->name, "port") ||
+		    of_property_read_u32(portnp, "reg", &port))
+			continue;
+
+		if (port >= FELIX_MAX_NUM_PHY_PORTS) {
+			dev_err(ocelot->dev, "invalid port num: %d\n", port);
+			continue;
+		}
+
+		res.start = base + FELIX_PORT_RES_START +
+			    FELIX_PORT_RES_SIZE * port;
+		res.end = res.start + FELIX_PORT_RES_SIZE - 1;
+		res.flags = IORESOURCE_MEM;
+		res.name = "port";
+
+		port_regs = devm_ioremap_resource(ocelot->dev, &res);
+		if (IS_ERR(port_regs)) {
+			dev_err(ocelot->dev,
+				"failed to map registers for port %d\n", port);
+			continue;
+		}
+
+		phy_node = of_parse_phandle(portnp, "phy-handle", 0);
+		if (!phy_node) {
+			if (!of_phy_is_fixed_link(portnp))
+				continue;
+
+			err = of_phy_register_fixed_link(portnp);
+			if (err < 0) {
+				dev_err(ocelot->dev,
+					"can't create fixed link for port:%d\n",
+					port);
+				continue;
+			}
+			phydev = of_phy_find_device(portnp);
+		} else {
+			phydev = of_phy_find_device(phy_node);
+		}
+
+		of_node_put(phy_node);
+
+		if (!phydev)
+			continue;
+
+		phy_mode = of_get_phy_mode(portnp);
+		if (phy_mode < 0)
+			phy_mode = PHY_INTERFACE_MODE_NA;
+
+		err = ocelot_probe_port(ocelot, port, port_regs, phydev);
+		if (err) {
+			dev_err(ocelot->dev, "failed to probe ports\n");
+			goto release_ports;
+		}
+
+		/* Felix configs */
+		ocelot->ports[port]->phy_mode = phy_mode;
+	}
+
+	return 0;
+
+release_ports:
+	felix_release_ports(ocelot);
+
+	return err;
+}
+
+#define FELIX_INIT_TIMEOUT	50000
+#define FELIX_GCB_RST_SLEEP	100
+#define FELIX_SYS_RAMINIT_SLEEP	80
+
+static int felix_gcb_soft_rst_status(struct ocelot *ocelot)
+{
+	int val;
+
+	regmap_field_read(ocelot->regfields[GCB_SOFT_RST_SWC_RST], &val);
+	return val;
+}
+
+static int felix_sys_ram_init_status(struct ocelot *ocelot)
+{
+	return ocelot_read(ocelot, SYS_RAM_INIT);
+}
+
+static int felix_init_switch_core(struct ocelot *ocelot)
+{
+	int val, err;
+
+	/* soft-reset the switch core */
+	regmap_field_write(ocelot->regfields[GCB_SOFT_RST_SWC_RST], 1);
+
+	err = readx_poll_timeout(felix_gcb_soft_rst_status, ocelot, val, !val,
+				 FELIX_GCB_RST_SLEEP, FELIX_INIT_TIMEOUT);
+	if (err) {
+		dev_err(ocelot->dev, "timeout: switch core reset\n");
+		return err;
+	}
+
+	/* initialize switch mem ~40us */
+	ocelot_write(ocelot, SYS_RAM_INIT_RAM_INIT, SYS_RAM_INIT);
+	err = readx_poll_timeout(felix_sys_ram_init_status, ocelot, val, !val,
+				 FELIX_SYS_RAMINIT_SLEEP, FELIX_INIT_TIMEOUT);
+	if (err) {
+		dev_err(ocelot->dev, "timeout: switch sram init\n");
+		return err;
+	}
+
+	/* enable switch core */
+	regmap_field_write(ocelot->regfields[SYS_RESET_CFG_CORE_ENA], 1);
+
+	return 0;
+}
+
+static int felix_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	struct ocelot *ocelot;
+	resource_size_t base;
+	size_t len;
+	int i, err;
+
+	err = pci_enable_device(pdev);
+	if (err) {
+		dev_err(&pdev->dev, "device enable failed\n");
+		return err;
+	}
+
+	/* set up for high or low dma */
+	err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+	if (err) {
+		err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+		if (err) {
+			dev_err(&pdev->dev,
+				"DMA configuration failed: 0x%x\n", err);
+			goto err_dma;
+		}
+	}
+
+	base = pci_resource_start(pdev, FELIX_SWITCH_BAR);
+
+	pci_set_master(pdev);
+
+	ocelot = devm_kzalloc(&pdev->dev, sizeof(*ocelot), GFP_KERNEL);
+	if (!ocelot) {
+		err = -ENOMEM;
+		goto err_alloc_ocelot;
+	}
+
+	pci_set_drvdata(pdev, ocelot);
+	ocelot->dev = &pdev->dev;
+
+	len = pci_resource_len(pdev, FELIX_SWITCH_BAR);
+	if (!len) {
+		err = -EINVAL;
+		goto err_resource_len;
+	}
+
+	regs = pci_iomap(pdev, FELIX_SWITCH_BAR, len);
+	if (!regs) {
+		err = -ENXIO;
+		dev_err(&pdev->dev, "ioremap() failed\n");
+		goto err_iomap;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(felix_io_res); i++) {
+		struct resource *res = &felix_io_res[i].res;
+		struct regmap *target;
+
+		res->flags = IORESOURCE_MEM;
+		res->start += base;
+		res->end += base;
+
+		target = ocelot_io_init(ocelot, res);
+		if (IS_ERR(target)) {
+			err = PTR_ERR(target);
+			goto err_iomap;
+		}
+
+		ocelot->targets[felix_io_res[i].id] = target;
+	}
+
+	err = felix_chip_init(ocelot);
+	if (err)
+		goto err_chip_init;
+
+	err = felix_init_switch_core(ocelot);
+	if (err)
+		goto err_sw_core_init;
+
+	err = felix_ports_init(pdev);
+	if (err)
+		goto err_ports_init;
+
+	register_netdevice_notifier(&ocelot_netdevice_nb);
+	register_switchdev_notifier(&ocelot_switchdev_nb);
+	register_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);
+
+	dev_info(&pdev->dev, "%s v%s\n", FELIX_DRV_STR, FELIX_DRV_VER_STR);
+	return 0;
+
+err_ports_init:
+err_chip_init:
+err_sw_core_init:
+	pci_iounmap(pdev, regs);
+err_iomap:
+err_resource_len:
+err_alloc_ocelot:
+err_dma:
+	pci_disable_device(pdev);
+
+	return err;
+}
+
+static void felix_pci_remove(struct pci_dev *pdev)
+{
+	struct ocelot *ocelot;
+
+	ocelot = pci_get_drvdata(pdev);
+
+	/* stop workqueue thread */
+	ocelot_deinit(ocelot);
+	unregister_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb);
+	unregister_switchdev_notifier(&ocelot_switchdev_nb);
+	unregister_netdevice_notifier(&ocelot_netdevice_nb);
+
+	felix_release_ports(ocelot);
+
+	pci_iounmap(pdev, regs);
+	pci_disable_device(pdev);
+}
+
+static struct pci_driver felix_pci_driver = {
+	.name = KBUILD_MODNAME,
+	.id_table = felix_ids,
+	.probe = felix_pci_probe,
+	.remove = felix_pci_remove,
+};
+
+module_pci_driver(felix_pci_driver);
+
+MODULE_DESCRIPTION(FELIX_DRV_STR);
+MODULE_LICENSE("Dual MIT/GPL");
diff --git a/drivers/net/ethernet/mscc/felix_regs.c b/drivers/net/ethernet/mscc/felix_regs.c
new file mode 100644
index 000000000000..33e545505b4e
--- /dev/null
+++ b/drivers/net/ethernet/mscc/felix_regs.c
@@ -0,0 +1,448 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/* Felix Switch driver
+ *
+ * Copyright 2017 Microsemi Corporation
+ * Copyright 2018-2019 NXP
+ */
+#include "ocelot.h"
+
+static const u32 felix_ana_regmap[] = {
+	REG(ANA_ADVLEARN,                  0x0089a0),
+	REG(ANA_VLANMASK,                  0x0089a4),
+	REG_RESERVED(ANA_PORT_B_DOMAIN),
+	REG(ANA_ANAGEFIL,                  0x0089ac),
+	REG(ANA_ANEVENTS,                  0x0089b0),
+	REG(ANA_STORMLIMIT_BURST,          0x0089b4),
+	REG(ANA_STORMLIMIT_CFG,            0x0089b8),
+	REG(ANA_ISOLATED_PORTS,            0x0089c8),
+	REG(ANA_COMMUNITY_PORTS,           0x0089cc),
+	REG(ANA_AUTOAGE,                   0x0089d0),
+	REG(ANA_MACTOPTIONS,               0x0089d4),
+	REG(ANA_LEARNDISC,                 0x0089d8),
+	REG(ANA_AGENCTRL,                  0x0089dc),
+	REG(ANA_MIRRORPORTS,               0x0089e0),
+	REG(ANA_EMIRRORPORTS,              0x0089e4),
+	REG(ANA_FLOODING,                  0x0089e8),
+	REG(ANA_FLOODING_IPMC,             0x008a08),
+	REG(ANA_SFLOW_CFG,                 0x008a0c),
+	REG(ANA_PORT_MODE,                 0x008a28),
+	REG(ANA_CUT_THRU_CFG,              0x008a48),
+	REG(ANA_PGID_PGID,                 0x008400),
+	REG(ANA_TABLES_ANMOVED,            0x007f1c),
+	REG(ANA_TABLES_MACHDATA,           0x007f20),
+	REG(ANA_TABLES_MACLDATA,           0x007f24),
+	REG(ANA_TABLES_STREAMDATA,         0x007f28),
+	REG(ANA_TABLES_MACACCESS,          0x007f2c),
+	REG(ANA_TABLES_MACTINDX,           0x007f30),
+	REG(ANA_TABLES_VLANACCESS,         0x007f34),
+	REG(ANA_TABLES_VLANTIDX,           0x007f38),
+	REG(ANA_TABLES_ISDXACCESS,         0x007f3c),
+	REG(ANA_TABLES_ISDXTIDX,           0x007f40),
+	REG(ANA_TABLES_ENTRYLIM,           0x007f00),
+	REG(ANA_TABLES_PTP_ID_HIGH,        0x007f44),
+	REG(ANA_TABLES_PTP_ID_LOW,         0x007f48),
+	REG(ANA_TABLES_STREAMACCESS,       0x007f4c),
+	REG(ANA_TABLES_STREAMTIDX,         0x007f50),
+	REG(ANA_TABLES_SEQ_HISTORY,        0x007f54),
+	REG(ANA_TABLES_SEQ_MASK,           0x007f58),
+	REG(ANA_TABLES_SFID_MASK,          0x007f5c),
+	REG(ANA_TABLES_SFIDACCESS,         0x007f60),
+	REG(ANA_TABLES_SFIDTIDX,           0x007f64),
+	REG(ANA_MSTI_STATE,                0x008600),
+	REG(ANA_OAM_UPM_LM_CNT,            0x008000),
+	REG(ANA_SG_ACCESS_CTRL,            0x008a64),
+	REG(ANA_SG_CONFIG_REG_1,           0x007fb0),
+	REG(ANA_SG_CONFIG_REG_2,           0x007fb4),
+	REG(ANA_SG_CONFIG_REG_3,           0x007fb8),
+	REG(ANA_SG_CONFIG_REG_4,           0x007fbc),
+	REG(ANA_SG_CONFIG_REG_5,           0x007fc0),
+	REG(ANA_SG_GCL_GS_CONFIG,          0x007f80),
+	REG(ANA_SG_GCL_TI_CONFIG,          0x007f90),
+	REG(ANA_SG_STATUS_REG_1,           0x008980),
+	REG(ANA_SG_STATUS_REG_2,           0x008984),
+	REG(ANA_SG_STATUS_REG_3,           0x008988),
+	REG(ANA_PORT_VLAN_CFG,             0x007800),
+	REG(ANA_PORT_DROP_CFG,             0x007804),
+	REG(ANA_PORT_QOS_CFG,              0x007808),
+	REG(ANA_PORT_VCAP_CFG,             0x00780c),
+	REG(ANA_PORT_VCAP_S1_KEY_CFG,      0x007810),
+	REG(ANA_PORT_VCAP_S2_CFG,          0x00781c),
+	REG(ANA_PORT_PCP_DEI_MAP,          0x007820),
+	REG(ANA_PORT_CPU_FWD_CFG,          0x007860),
+	REG(ANA_PORT_CPU_FWD_BPDU_CFG,     0x007864),
+	REG(ANA_PORT_CPU_FWD_GARP_CFG,     0x007868),
+	REG(ANA_PORT_CPU_FWD_CCM_CFG,      0x00786c),
+	REG(ANA_PORT_PORT_CFG,             0x007870),
+	REG(ANA_PORT_POL_CFG,              0x007874),
+	REG(ANA_PORT_PTP_CFG,              0x007878),
+	REG(ANA_PORT_PTP_DLY1_CFG,         0x00787c),
+	REG(ANA_PORT_PTP_DLY2_CFG,         0x007880),
+	REG(ANA_PORT_SFID_CFG,             0x007884),
+	REG(ANA_PFC_PFC_CFG,               0x008800),
+	REG_RESERVED(ANA_PFC_PFC_TIMER),
+	REG_RESERVED(ANA_IPT_OAM_MEP_CFG),
+	REG_RESERVED(ANA_IPT_IPT),
+	REG_RESERVED(ANA_PPT_PPT),
+	REG_RESERVED(ANA_FID_MAP_FID_MAP),
+	REG(ANA_AGGR_CFG,                  0x008a68),
+	REG(ANA_CPUQ_CFG,                  0x008a6c),
+	REG_RESERVED(ANA_CPUQ_CFG2),
+	REG(ANA_CPUQ_8021_CFG,             0x008a74),
+	REG(ANA_DSCP_CFG,                  0x008ab4),
+	REG(ANA_DSCP_REWR_CFG,             0x008bb4),
+	REG(ANA_VCAP_RNG_TYPE_CFG,         0x008bf4),
+	REG(ANA_VCAP_RNG_VAL_CFG,          0x008c14),
+	REG_RESERVED(ANA_VRAP_CFG),
+	REG_RESERVED(ANA_VRAP_HDR_DATA),
+	REG_RESERVED(ANA_VRAP_HDR_MASK),
+	REG(ANA_DISCARD_CFG,               0x008c40),
+	REG(ANA_FID_CFG,                   0x008c44),
+	REG(ANA_POL_PIR_CFG,               0x004000),
+	REG(ANA_POL_CIR_CFG,               0x004004),
+	REG(ANA_POL_MODE_CFG,              0x004008),
+	REG(ANA_POL_PIR_STATE,             0x00400c),
+	REG(ANA_POL_CIR_STATE,             0x004010),
+	REG_RESERVED(ANA_POL_STATE),
+	REG(ANA_POL_FLOWC,                 0x008c48),
+	REG(ANA_POL_HYST,                  0x008cb4),
+	REG_RESERVED(ANA_POL_MISC_CFG),
+};
+
+static const u32 felix_qs_regmap[] = {
+	REG(QS_XTR_GRP_CFG,                0x000000),
+	REG(QS_XTR_RD,                     0x000008),
+	REG(QS_XTR_FRM_PRUNING,            0x000010),
+	REG(QS_XTR_FLUSH,                  0x000018),
+	REG(QS_XTR_DATA_PRESENT,           0x00001c),
+	REG(QS_XTR_CFG,                    0x000020),
+	REG(QS_INJ_GRP_CFG,                0x000024),
+	REG(QS_INJ_WR,                     0x00002c),
+	REG(QS_INJ_CTRL,                   0x000034),
+	REG(QS_INJ_STATUS,                 0x00003c),
+	REG(QS_INJ_ERR,                    0x000040),
+	REG_RESERVED(QS_INH_DBG),
+};
+
+static const u32 felix_s2_regmap[] = {
+	REG(S2_CORE_UPDATE_CTRL,           0x000000),
+	REG(S2_CORE_MV_CFG,                0x000004),
+	REG(S2_CACHE_ENTRY_DAT,            0x000008),
+	REG(S2_CACHE_MASK_DAT,             0x000108),
+	REG(S2_CACHE_ACTION_DAT,           0x000208),
+	REG(S2_CACHE_CNT_DAT,              0x000308),
+	REG(S2_CACHE_TG_DAT,               0x000388),
+};
+
+static const u32 felix_qsys_regmap[] = {
+	REG(QSYS_PORT_MODE,                0x00f460),
+	REG(QSYS_SWITCH_PORT_MODE,         0x00f480),
+	REG(QSYS_STAT_CNT_CFG,             0x00f49c),
+	REG(QSYS_EEE_CFG,                  0x00f4a0),
+	REG(QSYS_EEE_THRES,                0x00f4b8),
+	REG(QSYS_IGR_NO_SHARING,           0x00f4bc),
+	REG(QSYS_EGR_NO_SHARING,           0x00f4c0),
+	REG(QSYS_SW_STATUS,                0x00f4c4),
+	REG(QSYS_EXT_CPU_CFG,              0x00f4e0),
+	REG_RESERVED(QSYS_PAD_CFG),
+	REG(QSYS_CPU_GROUP_MAP,            0x00f4e8),
+	REG_RESERVED(QSYS_QMAP),
+	REG_RESERVED(QSYS_ISDX_SGRP),
+	REG_RESERVED(QSYS_TIMED_FRAME_ENTRY),
+	REG(QSYS_TFRM_MISC,                0x00f50c),
+	REG(QSYS_TFRM_PORT_DLY,            0x00f510),
+	REG(QSYS_TFRM_TIMER_CFG_1,         0x00f514),
+	REG(QSYS_TFRM_TIMER_CFG_2,         0x00f518),
+	REG(QSYS_TFRM_TIMER_CFG_3,         0x00f51c),
+	REG(QSYS_TFRM_TIMER_CFG_4,         0x00f520),
+	REG(QSYS_TFRM_TIMER_CFG_5,         0x00f524),
+	REG(QSYS_TFRM_TIMER_CFG_6,         0x00f528),
+	REG(QSYS_TFRM_TIMER_CFG_7,         0x00f52c),
+	REG(QSYS_TFRM_TIMER_CFG_8,         0x00f530),
+	REG(QSYS_RED_PROFILE,              0x00f534),
+	REG(QSYS_RES_QOS_MODE,             0x00f574),
+	REG(QSYS_RES_CFG,                  0x00c000),
+	REG(QSYS_RES_STAT,                 0x00c004),
+	REG(QSYS_EGR_DROP_MODE,            0x00f578),
+	REG(QSYS_EQ_CTRL,                  0x00f57c),
+	REG_RESERVED(QSYS_EVENTS_CORE),
+	REG(QSYS_QMAXSDU_CFG_0,            0x00f584),
+	REG(QSYS_QMAXSDU_CFG_1,            0x00f5a0),
+	REG(QSYS_QMAXSDU_CFG_2,            0x00f5bc),
+	REG(QSYS_QMAXSDU_CFG_3,            0x00f5d8),
+	REG(QSYS_QMAXSDU_CFG_4,            0x00f5f4),
+	REG(QSYS_QMAXSDU_CFG_5,            0x00f610),
+	REG(QSYS_QMAXSDU_CFG_6,            0x00f62c),
+	REG(QSYS_QMAXSDU_CFG_7,            0x00f648),
+	REG(QSYS_PREEMPTION_CFG,           0x00f664),
+	REG_RESERVED(QSYS_CIR_CFG),
+	REG(QSYS_EIR_CFG,                  0x000004),
+	REG(QSYS_SE_CFG,                   0x000008),
+	REG(QSYS_SE_DWRR_CFG,              0x00000c),
+	REG_RESERVED(QSYS_SE_CONNECT),
+	REG(QSYS_SE_DLB_SENSE,             0x000040),
+	REG(QSYS_CIR_STATE,                0x000044),
+	REG(QSYS_EIR_STATE,                0x000048),
+	REG_RESERVED(QSYS_SE_STATE),
+	REG(QSYS_HSCH_MISC_CFG,            0x00f67c),
+	REG(QSYS_TAG_CONFIG,               0x00f680),
+	REG(QSYS_TAS_PARAM_CFG_CTRL,       0x00f698),
+	REG(QSYS_PORT_MAX_SDU,             0x00f69c),
+	REG(QSYS_PARAM_CFG_REG_1,          0x00f440),
+	REG(QSYS_PARAM_CFG_REG_2,          0x00f444),
+	REG(QSYS_PARAM_CFG_REG_3,          0x00f448),
+	REG(QSYS_PARAM_CFG_REG_4,          0x00f44c),
+	REG(QSYS_PARAM_CFG_REG_5,          0x00f450),
+	REG(QSYS_GCL_CFG_REG_1,            0x00f454),
+	REG(QSYS_GCL_CFG_REG_2,            0x00f458),
+	REG(QSYS_PARAM_STATUS_REG_1,       0x00f400),
+	REG(QSYS_PARAM_STATUS_REG_2,       0x00f404),
+	REG(QSYS_PARAM_STATUS_REG_3,       0x00f408),
+	REG(QSYS_PARAM_STATUS_REG_4,       0x00f40c),
+	REG(QSYS_PARAM_STATUS_REG_5,       0x00f410),
+	REG(QSYS_PARAM_STATUS_REG_6,       0x00f414),
+	REG(QSYS_PARAM_STATUS_REG_7,       0x00f418),
+	REG(QSYS_PARAM_STATUS_REG_8,       0x00f41c),
+	REG(QSYS_PARAM_STATUS_REG_9,       0x00f420),
+	REG(QSYS_GCL_STATUS_REG_1,         0x00f424),
+	REG(QSYS_GCL_STATUS_REG_2,         0x00f428),
+};
+
+static const u32 felix_rew_regmap[] = {
+	REG(REW_PORT_VLAN_CFG,             0x000000),
+	REG(REW_TAG_CFG,                   0x000004),
+	REG(REW_PORT_CFG,                  0x000008),
+	REG(REW_DSCP_CFG,                  0x00000c),
+	REG(REW_PCP_DEI_QOS_MAP_CFG,       0x000010),
+	REG(REW_PTP_CFG,                   0x000050),
+	REG(REW_PTP_DLY1_CFG,              0x000054),
+	REG(REW_RED_TAG_CFG,               0x000058),
+	REG(REW_DSCP_REMAP_DP1_CFG,        0x000410),
+	REG(REW_DSCP_REMAP_CFG,            0x000510),
+	REG_RESERVED(REW_STAT_CFG),
+	REG_RESERVED(REW_REW_STICKY),
+	REG_RESERVED(REW_PPT),
+};
+
+static const u32 felix_sys_regmap[] = {
+	REG(SYS_COUNT_RX_OCTETS,	   0x000000),
+	REG(SYS_COUNT_RX_MULTICAST,	   0x000008),
+	REG(SYS_COUNT_RX_SHORTS,	   0x000010),
+	REG(SYS_COUNT_RX_FRAGMENTS,	   0x000014),
+	REG(SYS_COUNT_RX_JABBERS,	   0x000018),
+	REG(SYS_COUNT_RX_64,		   0x000024),
+	REG(SYS_COUNT_RX_65_127,	   0x000028),
+	REG(SYS_COUNT_RX_128_255,	   0x00002c),
+	REG(SYS_COUNT_RX_256_1023,	   0x000030),
+	REG(SYS_COUNT_RX_1024_1526,	   0x000034),
+	REG(SYS_COUNT_RX_1527_MAX,	   0x000038),
+	REG(SYS_COUNT_RX_LONGS,		   0x000044),
+	REG(SYS_COUNT_TX_OCTETS,	   0x000200),
+	REG(SYS_COUNT_TX_COLLISION,	   0x000210),
+	REG(SYS_COUNT_TX_DROPS,		   0x000214),
+	REG(SYS_COUNT_TX_64,		   0x00021c),
+	REG(SYS_COUNT_TX_65_127,	   0x000220),
+	REG(SYS_COUNT_TX_128_511,	   0x000224),
+	REG(SYS_COUNT_TX_512_1023,	   0x000228),
+	REG(SYS_COUNT_TX_1024_1526,	   0x00022c),
+	REG(SYS_COUNT_TX_1527_MAX,	   0x000230),
+	REG(SYS_COUNT_TX_AGING,		   0x000278),
+	REG(SYS_RESET_CFG,                 0x000e00),
+	REG(SYS_SR_ETYPE_CFG,              0x000e04),
+	REG(SYS_VLAN_ETYPE_CFG,            0x000e08),
+	REG(SYS_PORT_MODE,                 0x000e0c),
+	REG(SYS_FRONT_PORT_MODE,           0x000e2c),
+	REG(SYS_FRM_AGING,                 0x000e44),
+	REG(SYS_STAT_CFG,                  0x000e48),
+	REG(SYS_SW_STATUS,                 0x000e4c),
+	REG_RESERVED(SYS_MISC_CFG),
+	REG(SYS_REW_MAC_HIGH_CFG,          0x000e6c),
+	REG(SYS_REW_MAC_LOW_CFG,           0x000e84),
+	REG(SYS_TIMESTAMP_OFFSET,          0x000e9c),
+	REG(SYS_PAUSE_CFG,                 0x000ea0),
+	REG(SYS_PAUSE_TOT_CFG,             0x000ebc),
+	REG(SYS_ATOP,                      0x000ec0),
+	REG(SYS_ATOP_TOT_CFG,              0x000edc),
+	REG(SYS_MAC_FC_CFG,                0x000ee0),
+	REG(SYS_MMGT,                      0x000ef8),
+	REG_RESERVED(SYS_MMGT_FAST),
+	REG_RESERVED(SYS_EVENTS_DIF),
+	REG_RESERVED(SYS_EVENTS_CORE),
+	REG_RESERVED(SYS_CNT),
+	REG(SYS_PTP_STATUS,                0x000f14),
+	REG(SYS_PTP_TXSTAMP,               0x000f18),
+	REG(SYS_PTP_NXT,                   0x000f1c),
+	REG(SYS_PTP_CFG,                   0x000f20),
+	REG(SYS_RAM_INIT,                  0x000f24),
+	REG_RESERVED(SYS_CM_ADDR),
+	REG_RESERVED(SYS_CM_DATA_WR),
+	REG_RESERVED(SYS_CM_DATA_RD),
+	REG_RESERVED(SYS_CM_OP),
+	REG_RESERVED(SYS_CM_DATA),
+};
+
+static const u32 felix_gcb_regmap[] = {
+	REG(GCB_SOFT_RST,                  0x000004),
+};
+
+static const u32 *felix_regmap[] = {
+	[ANA] = felix_ana_regmap,
+	[QS] = felix_qs_regmap,
+	[QSYS] = felix_qsys_regmap,
+	[REW] = felix_rew_regmap,
+	[SYS] = felix_sys_regmap,
+	[S2] = felix_s2_regmap,
+	[GCB] = felix_gcb_regmap,
+};
+
+static const struct reg_field felix_regfields[REGFIELD_MAX] = {
+	[ANA_ADVLEARN_VLAN_CHK] = REG_FIELD(ANA_ADVLEARN, 6, 6),
+	[ANA_ADVLEARN_LEARN_MIRROR] = REG_FIELD(ANA_ADVLEARN, 0, 5),
+	[ANA_ANEVENTS_FLOOD_DISCARD] = REG_FIELD(ANA_ANEVENTS, 30, 30),
+	[ANA_ANEVENTS_AUTOAGE] = REG_FIELD(ANA_ANEVENTS, 26, 26),
+	[ANA_ANEVENTS_STORM_DROP] = REG_FIELD(ANA_ANEVENTS, 24, 24),
+	[ANA_ANEVENTS_LEARN_DROP] = REG_FIELD(ANA_ANEVENTS, 23, 23),
+	[ANA_ANEVENTS_AGED_ENTRY] = REG_FIELD(ANA_ANEVENTS, 22, 22),
+	[ANA_ANEVENTS_CPU_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 21, 21),
+	[ANA_ANEVENTS_AUTO_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 20, 20),
+	[ANA_ANEVENTS_LEARN_REMOVE] = REG_FIELD(ANA_ANEVENTS, 19, 19),
+	[ANA_ANEVENTS_AUTO_LEARNED] = REG_FIELD(ANA_ANEVENTS, 18, 18),
+	[ANA_ANEVENTS_AUTO_MOVED] = REG_FIELD(ANA_ANEVENTS, 17, 17),
+	[ANA_ANEVENTS_CLASSIFIED_DROP] = REG_FIELD(ANA_ANEVENTS, 15, 15),
+	[ANA_ANEVENTS_CLASSIFIED_COPY] = REG_FIELD(ANA_ANEVENTS, 14, 14),
+	[ANA_ANEVENTS_VLAN_DISCARD] = REG_FIELD(ANA_ANEVENTS, 13, 13),
+	[ANA_ANEVENTS_FWD_DISCARD] = REG_FIELD(ANA_ANEVENTS, 12, 12),
+	[ANA_ANEVENTS_MULTICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 11, 11),
+	[ANA_ANEVENTS_UNICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 10, 10),
+	[ANA_ANEVENTS_DEST_KNOWN] = REG_FIELD(ANA_ANEVENTS, 9, 9),
+	[ANA_ANEVENTS_BUCKET3_MATCH] = REG_FIELD(ANA_ANEVENTS, 8, 8),
+	[ANA_ANEVENTS_BUCKET2_MATCH] = REG_FIELD(ANA_ANEVENTS, 7, 7),
+	[ANA_ANEVENTS_BUCKET1_MATCH] = REG_FIELD(ANA_ANEVENTS, 6, 6),
+	[ANA_ANEVENTS_BUCKET0_MATCH] = REG_FIELD(ANA_ANEVENTS, 5, 5),
+	[ANA_ANEVENTS_CPU_OPERATION] = REG_FIELD(ANA_ANEVENTS, 4, 4),
+	[ANA_ANEVENTS_DMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 3, 3),
+	[ANA_ANEVENTS_SMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 2, 2),
+	[ANA_ANEVENTS_SEQ_GEN_ERR_0] = REG_FIELD(ANA_ANEVENTS, 1, 1),
+	[ANA_ANEVENTS_SEQ_GEN_ERR_1] = REG_FIELD(ANA_ANEVENTS, 0, 0),
+	[ANA_TABLES_MACACCESS_B_DOM] = REG_FIELD(ANA_TABLES_MACACCESS, 16, 16),
+	[ANA_TABLES_MACTINDX_BUCKET] = REG_FIELD(ANA_TABLES_MACTINDX, 11, 12),
+	[ANA_TABLES_MACTINDX_M_INDEX] = REG_FIELD(ANA_TABLES_MACTINDX, 0, 10),
+	[SYS_RESET_CFG_CORE_ENA] = REG_FIELD(SYS_RESET_CFG, 0, 0),
+	[GCB_SOFT_RST_SWC_RST] = REG_FIELD(GCB_SOFT_RST, 0, 0),
+};
+
+static const struct ocelot_stat_layout felix_stats_layout[] = {
+	{ .name = "rx_octets", .offset = 0x00, },
+	{ .name = "rx_unicast", .offset = 0x01, },
+	{ .name = "rx_multicast", .offset = 0x02, },
+	{ .name = "rx_broadcast", .offset = 0x03, },
+	{ .name = "rx_shorts", .offset = 0x04, },
+	{ .name = "rx_fragments", .offset = 0x05, },
+	{ .name = "rx_jabbers", .offset = 0x06, },
+	{ .name = "rx_crc_align_errs", .offset = 0x07, },
+	{ .name = "rx_sym_errs", .offset = 0x08, },
+	{ .name = "rx_frames_below_65_octets", .offset = 0x09, },
+	{ .name = "rx_frames_65_to_127_octets", .offset = 0x0A, },
+	{ .name = "rx_frames_128_to_255_octets", .offset = 0x0B, },
+	{ .name = "rx_frames_256_to_511_octets", .offset = 0x0C, },
+	{ .name = "rx_frames_512_to_1023_octets", .offset = 0x0D, },
+	{ .name = "rx_frames_1024_to_1526_octets", .offset = 0x0E, },
+	{ .name = "rx_frames_over_1526_octets", .offset = 0x0F, },
+	{ .name = "rx_pause", .offset = 0x10, },
+	{ .name = "rx_control", .offset = 0x11, },
+	{ .name = "rx_longs", .offset = 0x12, },
+	{ .name = "rx_classified_drops", .offset = 0x13, },
+	{ .name = "rx_red_prio_0", .offset = 0x14, },
+	{ .name = "rx_red_prio_1", .offset = 0x15, },
+	{ .name = "rx_red_prio_2", .offset = 0x16, },
+	{ .name = "rx_red_prio_3", .offset = 0x17, },
+	{ .name = "rx_red_prio_4", .offset = 0x18, },
+	{ .name = "rx_red_prio_5", .offset = 0x19, },
+	{ .name = "rx_red_prio_6", .offset = 0x1A, },
+	{ .name = "rx_red_prio_7", .offset = 0x1B, },
+	{ .name = "rx_yellow_prio_0", .offset = 0x1C, },
+	{ .name = "rx_yellow_prio_1", .offset = 0x1D, },
+	{ .name = "rx_yellow_prio_2", .offset = 0x1E, },
+	{ .name = "rx_yellow_prio_3", .offset = 0x1F, },
+	{ .name = "rx_yellow_prio_4", .offset = 0x20, },
+	{ .name = "rx_yellow_prio_5", .offset = 0x21, },
+	{ .name = "rx_yellow_prio_6", .offset = 0x22, },
+	{ .name = "rx_yellow_prio_7", .offset = 0x23, },
+	{ .name = "rx_green_prio_0", .offset = 0x24, },
+	{ .name = "rx_green_prio_1", .offset = 0x25, },
+	{ .name = "rx_green_prio_2", .offset = 0x26, },
+	{ .name = "rx_green_prio_3", .offset = 0x27, },
+	{ .name = "rx_green_prio_4", .offset = 0x28, },
+	{ .name = "rx_green_prio_5", .offset = 0x29, },
+	{ .name = "rx_green_prio_6", .offset = 0x2A, },
+	{ .name = "rx_green_prio_7", .offset = 0x2B, },
+	{ .name = "tx_octets", .offset = 0x80, },
+	{ .name = "tx_unicast", .offset = 0x81, },
+	{ .name = "tx_multicast", .offset = 0x82, },
+	{ .name = "tx_broadcast", .offset = 0x83, },
+	{ .name = "tx_collision", .offset = 0x84, },
+	{ .name = "tx_drops", .offset = 0x85, },
+	{ .name = "tx_pause", .offset = 0x86, },
+	{ .name = "tx_frames_below_65_octets", .offset = 0x87, },
+	{ .name = "tx_frames_65_to_127_octets", .offset = 0x88, },
+	{ .name = "tx_frames_128_255_octets", .offset = 0x89, },
+	{ .name = "tx_frames_256_511_octets", .offset = 0x8A, },
+	{ .name = "tx_frames_512_1023_octets", .offset = 0x8B, },
+	{ .name = "tx_frames_1024_1526_octets", .offset = 0x8C, },
+	{ .name = "tx_frames_over_1526_octets", .offset = 0x8D, },
+	{ .name = "tx_yellow_prio_0", .offset = 0x8E, },
+	{ .name = "tx_yellow_prio_1", .offset = 0x8F, },
+	{ .name = "tx_yellow_prio_2", .offset = 0x90, },
+	{ .name = "tx_yellow_prio_3", .offset = 0x91, },
+	{ .name = "tx_yellow_prio_4", .offset = 0x92, },
+	{ .name = "tx_yellow_prio_5", .offset = 0x93, },
+	{ .name = "tx_yellow_prio_6", .offset = 0x94, },
+	{ .name = "tx_yellow_prio_7", .offset = 0x95, },
+	{ .name = "tx_green_prio_0", .offset = 0x96, },
+	{ .name = "tx_green_prio_1", .offset = 0x97, },
+	{ .name = "tx_green_prio_2", .offset = 0x98, },
+	{ .name = "tx_green_prio_3", .offset = 0x99, },
+	{ .name = "tx_green_prio_4", .offset = 0x9A, },
+	{ .name = "tx_green_prio_5", .offset = 0x9B, },
+	{ .name = "tx_green_prio_6", .offset = 0x9C, },
+	{ .name = "tx_green_prio_7", .offset = 0x9D, },
+	{ .name = "tx_aged", .offset = 0x9E, },
+	{ .name = "drop_local", .offset = 0x100, },
+	{ .name = "drop_tail", .offset = 0x101, },
+	{ .name = "drop_yellow_prio_0", .offset = 0x102, },
+	{ .name = "drop_yellow_prio_1", .offset = 0x103, },
+	{ .name = "drop_yellow_prio_2", .offset = 0x104, },
+	{ .name = "drop_yellow_prio_3", .offset = 0x105, },
+	{ .name = "drop_yellow_prio_4", .offset = 0x106, },
+	{ .name = "drop_yellow_prio_5", .offset = 0x107, },
+	{ .name = "drop_yellow_prio_6", .offset = 0x108, },
+	{ .name = "drop_yellow_prio_7", .offset = 0x109, },
+	{ .name = "drop_green_prio_0", .offset = 0x10A, },
+	{ .name = "drop_green_prio_1", .offset = 0x10B, },
+	{ .name = "drop_green_prio_2", .offset = 0x10C, },
+	{ .name = "drop_green_prio_3", .offset = 0x10D, },
+	{ .name = "drop_green_prio_4", .offset = 0x10E, },
+	{ .name = "drop_green_prio_5", .offset = 0x10F, },
+	{ .name = "drop_green_prio_6", .offset = 0x110, },
+	{ .name = "drop_green_prio_7", .offset = 0x111, },
+};
+
+int felix_chip_init(struct ocelot *ocelot)
+{
+	int ret;
+
+	ocelot->map = felix_regmap;
+	ocelot->stats_layout = felix_stats_layout;
+	ocelot->num_stats = ARRAY_SIZE(felix_stats_layout);
+	ocelot->shared_queue_sz = 128 * 1024;
+
+	ret = ocelot_regfields_init(ocelot, felix_regfields);
+	if (ret) {
+		dev_err(ocelot->dev, "failed to init reg fields map\n");
+		return ret;
+	}
+
+	eth_random_addr(ocelot->base_mac);
+	ocelot->base_mac[5] &= 0xf0;
+	return 0;
+}
+EXPORT_SYMBOL(felix_chip_init);
diff --git a/drivers/net/ethernet/mscc/ocelot.h b/drivers/net/ethernet/mscc/ocelot.h
index 4235d7294772..1d9e76584037 100644
--- a/drivers/net/ethernet/mscc/ocelot.h
+++ b/drivers/net/ethernet/mscc/ocelot.h
@@ -63,6 +63,9 @@ struct frame_info {
 #define REG_MASK GENMASK(TARGET_OFFSET - 1, 0)
 #define REG(reg, offset) [reg & REG_MASK] = offset
 
+#define REG_RESERVED_ADDR	0xffffffff
+#define REG_RESERVED(reg)	REG(reg, REG_RESERVED_ADDR)
+
 enum ocelot_target {
 	ANA = 1,
 	QS,
@@ -70,6 +73,7 @@ enum ocelot_target {
 	REW,
 	SYS,
 	S2,
+	GCB,
 	HSIO,
 	TARGET_MAX,
 };
@@ -343,6 +347,7 @@ enum ocelot_reg {
 	S2_CACHE_ACTION_DAT,
 	S2_CACHE_CNT_DAT,
 	S2_CACHE_TG_DAT,
+	GCB_SOFT_RST = GCB << TARGET_OFFSET,
 };
 
 enum ocelot_regfield {
@@ -390,6 +395,7 @@ enum ocelot_regfield {
 	SYS_RESET_CFG_CORE_ENA,
 	SYS_RESET_CFG_MEM_ENA,
 	SYS_RESET_CFG_MEM_INIT,
+	GCB_SOFT_RST_SWC_RST,
 	REGFIELD_MAX
 };
 
@@ -501,6 +507,7 @@ struct regmap *ocelot_io_init(struct ocelot *ocelot, struct resource *res);
 int ocelot_init(struct ocelot *ocelot);
 void ocelot_deinit(struct ocelot *ocelot);
 int ocelot_chip_init(struct ocelot *ocelot);
+int felix_chip_init(struct ocelot *ocelot);
 int ocelot_probe_port(struct ocelot *ocelot, u8 port,
 		      void __iomem *regs,
 		      struct phy_device *phy);
-- 
2.17.1


  parent reply	other threads:[~2019-06-21 15:39 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-21 15:38 [PATCH net-next 0/6] Microsemi Felix switch support Claudiu Manoil
2019-06-21 15:38 ` [PATCH net-next 1/6] ocelot: Filter out ocelot SoC specific PCS config from common path Claudiu Manoil
2019-06-21 15:38 ` [PATCH net-next 2/6] ocelot: Refactor common ocelot probing code to ocelot_init Claudiu Manoil
2019-06-21 15:38 ` [PATCH net-next 3/6] ocelot: Factor out resource ioremap and regmap init common code Claudiu Manoil
2019-06-21 15:38 ` [PATCH net-next 4/6] arm64: dts: fsl: ls1028a: Add Felix switch port DT node Claudiu Manoil
2019-06-21 16:49   ` Andrew Lunn
2019-06-24 11:45     ` Claudiu Manoil
2019-06-24 11:55       ` Alexandre Belloni
2019-06-24 14:26         ` Andrew Lunn
2019-06-24 15:23           ` Allan W. Nielsen
2019-06-24 16:24             ` Andrew Lunn
2019-06-24 18:26               ` Alexandre Belloni
2019-07-04 23:32                 ` Vladimir Oltean
2019-07-05  4:49                   ` Andrew Lunn
2019-07-05  8:37                     ` Claudiu Manoil
2019-07-05 13:19                       ` Andrew Lunn
2019-07-05  9:08                     ` Vladimir Oltean
2019-07-05 14:15                       ` Andrew Lunn
2019-07-05 16:03                       ` Florian Fainelli
2019-07-07 21:00                         ` Vladimir Oltean
2019-07-07 21:15                           ` Florian Fainelli
2019-06-21 15:38 ` [PATCH net-next 5/6] dt-bindings: net: Add DT bindings for Microsemi Felix Switch Claudiu Manoil
2019-06-21 15:38 ` Claudiu Manoil [this message]
2019-06-22 20:57   ` [PATCH net-next 6/6] net/mssc/ocelot: Add basic Felix switch driver Andrew Lunn
2019-06-24 13:19     ` Claudiu Manoil

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=1561131532-14860-7-git-send-email-claudiu.manoil@nxp.com \
    --to=claudiu.manoil@nxp.com \
    --cc=Allan.Nielsen@microsemi.com \
    --cc=UNGLinuxDriver@microchip.com \
    --cc=alexandre.belloni@bootlin.com \
    --cc=alexandru.marginean@nxp.com \
    --cc=catalin.horghidan@gmail.com \
    --cc=davem@davemloft.net \
    --cc=devicetree@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=robh+dt@kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).