All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alex Marginean <alexm.osslist@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 1/2] drivers: net: add NXP ENETC ethernet driver
Date: Fri, 31 May 2019 19:33:07 +0300	[thread overview]
Message-ID: <20190531163308.30698-1-alexm.osslist@gmail.com> (raw)
In-Reply-To: <20190531162551.30541-2-alexm.osslist@gmail.com>

Adds a driver for NXP ENETC ethernet controller currently integrated in
LS1028a.  ENETC is a fairly straight-forward BD ring device and interfaces
are presented as PCI EPs on the SoC ECAM.

Signed-off-by: Catalin Horghidan <catalin.horghidan@nxp.com>
Signed-off-by: Alex Marginean <alexm.osslist@gmail.com>
---
 configs/ls1028aqds_tfa_defconfig |   1 +
 configs/ls1028ardb_tfa_defconfig |   1 +
 drivers/net/Kconfig              |   7 +
 drivers/net/Makefile             |   1 +
 drivers/net/fsl_enetc.c          | 345 +++++++++++++++++++++++++++++++
 drivers/net/fsl_enetc.h          | 176 ++++++++++++++++
 include/pci_ids.h                |   1 +
 7 files changed, 532 insertions(+)
 create mode 100644 drivers/net/fsl_enetc.c
 create mode 100644 drivers/net/fsl_enetc.h

diff --git a/configs/ls1028aqds_tfa_defconfig b/configs/ls1028aqds_tfa_defconfig
index 7982ce4157..11fe344b04 100644
--- a/configs/ls1028aqds_tfa_defconfig
+++ b/configs/ls1028aqds_tfa_defconfig
@@ -45,6 +45,7 @@ CONFIG_PHY_ATHEROS=y
 CONFIG_DM_ETH=y
 CONFIG_PHY_GIGE=y
 CONFIG_E1000=y
+CONFIG_FSL_ENETC=y
 CONFIG_PCI=y
 CONFIG_DM_PCI=y
 CONFIG_DM_PCI_COMPAT=y
diff --git a/configs/ls1028ardb_tfa_defconfig b/configs/ls1028ardb_tfa_defconfig
index c65e37df79..ab6f2a850c 100644
--- a/configs/ls1028ardb_tfa_defconfig
+++ b/configs/ls1028ardb_tfa_defconfig
@@ -45,6 +45,7 @@ CONFIG_PHY_ATHEROS=y
 CONFIG_DM_ETH=y
 CONFIG_PHY_GIGE=y
 CONFIG_E1000=y
+CONFIG_FSL_ENETC=y
 CONFIG_PCI=y
 CONFIG_DM_PCI=y
 CONFIG_DM_PCI_COMPAT=y
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 6fba5a84dd..4aa82261f8 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -556,4 +556,11 @@ config HIGMACV300_ETH
 	  This driver supports HIGMACV300 Ethernet controller found on
 	  HiSilicon SoCs.
 
+config FSL_ENETC
+	bool "NXP ENETC Ethernet controller"
+	depends on DM_PCI && DM_ETH
+	help
+	  This driver supports the NXP ENETC Ethernet controller found on some
+	  of the NXP SoCs.
+
 endif # NETDEVICES
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 8d02a37896..67b88ebae8 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -77,3 +77,4 @@ obj-y += ti/
 obj-$(CONFIG_MEDIATEK_ETH) += mtk_eth.o
 obj-y += mscc_eswitch/
 obj-$(CONFIG_HIGMACV300_ETH) += higmacv300.o
+obj-$(CONFIG_FSL_ENETC) += fsl_enetc.o
diff --git a/drivers/net/fsl_enetc.c b/drivers/net/fsl_enetc.c
new file mode 100644
index 0000000000..b253292bc0
--- /dev/null
+++ b/drivers/net/fsl_enetc.c
@@ -0,0 +1,345 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * ENETC ethernet controller driver
+ * Copyright 2017-2019 NXP
+ */
+
+#include "fsl_enetc.h"
+
+#include <dm.h>
+#include <errno.h>
+#include <memalign.h>
+#include <asm/io.h>
+#include <pci.h>
+
+static int enetc_bind(struct udevice *dev)
+{
+	static int eth_num_devices;
+	char name[16];
+
+	/* prefer using PCI function numbers, if not available use #idx */
+	if (ofnode_valid(dev->node))
+		sprintf(name, "enetc%u", PCI_FUNC(pci_get_devfn(dev)));
+	else
+		sprintf(name, "enetc#%u", eth_num_devices++);
+
+	device_set_name(dev, name);
+
+	return 0;
+}
+
+/*
+ * Probe ENETC driver:
+ * - initialize port and station interface BARs
+ */
+static int enetc_probe(struct udevice *dev)
+{
+	struct enetc_devfn *hw = dev_get_priv(dev);
+	int err = 0;
+
+	if (ofnode_valid(dev->node) && !ofnode_is_available(dev->node)) {
+		ENETC_DBG(dev, "interface disabled\n");
+		return -ENODEV;
+	}
+
+	/* initialize register */
+	hw->regs_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0);
+	if (!hw->regs_base) {
+		ENETC_DBG(dev, "failed to map BAR0\n");
+		return -EINVAL;
+	}
+	hw->port_regs = hw->regs_base + 0x10000;
+
+	dm_pci_clrset_config16(dev, PCI_COMMAND, 0, PCI_COMMAND_MEMORY);
+
+	return err;
+}
+
+/* ENETC Port MAC address registers accept big-endian format */
+static void enetc_set_primary_mac_addr(struct enetc_devfn *hw, const u8 *addr)
+{
+	u16 lower = *(const u16 *)(addr + 4);
+	u32 upper = *(const u32 *)addr;
+
+	enetc_write_port(hw, ENETC_PSIPMAR0, upper);
+	enetc_write_port(hw, ENETC_PSIPMAR1, lower);
+}
+
+int enetc_enable_si_port(struct enetc_devfn *hw)
+{
+	u32 val;
+
+	/* set Rx/Tx BDR count */
+	val = ENETC_PSICFGR_SET_TXBDR(ENETC_TX_BDR_CNT);
+	val |= ENETC_PSICFGR_SET_RXBDR(ENETC_RX_BDR_CNT);
+	enetc_write_port(hw, ENETC_PSICFGR(0), val);
+	/* set Rx max frame size */
+	enetc_write_port(hw, ENETC_PM_MAXFRM, ENETC_RX_MAXFRM_SIZE);
+	/* enable MAC port */
+	enetc_write_port(hw, ENETC_PM_CC, ENETC_PM_CC_RX_TX_EN);
+	/* enable port */
+	enetc_write_port(hw, ENETC_PMR, ENETC_PMR_SI0_EN);
+	/* set SI cache policy */
+	enetc_write(hw, ENETC_SICAR0, ENETC_SICAR_RD_CFG | ENETC_SICAR_WR_CFG);
+	/* enable SI */
+	enetc_write(hw, ENETC_SIMR, ENETC_SIMR_EN);
+
+	return 0;
+}
+
+/* Use a single set of BDs and buffers.  It's functionally OK as u-boot doesn't
+ * use multiple interfaces at once.
+ */
+DEFINE_ALIGN_BUFFER(struct enetc_tx_bd, enetc_txbd, ENETC_BD_CNT, ENETC_ALIGN);
+DEFINE_ALIGN_BUFFER(union enetc_rx_bd, enetc_rxbd, ENETC_BD_CNT, ENETC_ALIGN);
+DEFINE_ALIGN_BUFFER(u8, enetc_rx_buff, ENETC_RX_MBUFF_SIZE, ENETC_ALIGN);
+
+static inline u64 enetc_rxb_address(struct udevice *dev, int i)
+{
+	int off = i * ENETC_RX_MAXFRM_SIZE;
+
+	return cpu_to_le64(dm_pci_virt_to_mem(dev, enetc_rx_buff + off));
+}
+
+/**
+ * Setup a single Tx BD Ring (ID = 0):
+ * - set Tx buffer descriptor address
+ * - set the BD count
+ * - initialize the producer and consumer index
+ */
+static void enetc_setup_tx_bdr(struct enetc_devfn *hw)
+{
+	struct bd_ring *tx_bdr = &hw->tx_bdr;
+	u64 tx_bd_add = (u64)enetc_txbd;
+
+	/* used later to advance to the next Tx BD */
+	tx_bdr->bd_count = ENETC_BD_CNT;
+	tx_bdr->next_prod_idx = 0;
+	tx_bdr->next_cons_idx = 0;
+	tx_bdr->cons_idx = hw->regs_base +
+				ENETC_BDR(TX, ENETC_TX_BDR_ID, ENETC_TBCIR);
+	tx_bdr->prod_idx = hw->regs_base +
+				ENETC_BDR(TX, ENETC_TX_BDR_ID, ENETC_TBPIR);
+
+	/* set Tx BD address */
+	enetc_bdr_write(hw, TX, ENETC_TX_BDR_ID, ENETC_TBBAR0,
+			lower_32_bits(tx_bd_add));
+	enetc_bdr_write(hw, TX, ENETC_TX_BDR_ID, ENETC_TBBAR1,
+			upper_32_bits(tx_bd_add));
+	/* set Tx 8 BD count */
+	enetc_bdr_write(hw, TX, ENETC_TX_BDR_ID, ENETC_TBLENR,
+			tx_bdr->bd_count);
+
+	/* reset both producer/consumer indexes */
+	enetc_write_reg(tx_bdr->cons_idx, tx_bdr->next_cons_idx);
+	enetc_write_reg(tx_bdr->prod_idx, tx_bdr->next_prod_idx);
+
+	/* enable TX ring */
+	enetc_bdr_write(hw, TX, ENETC_TX_BDR_ID, ENETC_TBMR, ENETC_TBMR_EN);
+}
+
+/**
+ * Setup a single Rx BD Ring (ID = 0):
+ * - set Rx buffer descriptors address (one descriptor per buffer)
+ * - set buffer size as max frame size
+ * - enable Rx ring
+ * - reset consumer and producer indexes
+ * - set buffer for each descriptor
+ */
+static void enetc_setup_rx_bdr(struct udevice *dev, struct enetc_devfn *hw)
+{
+	struct bd_ring *rx_bdr = &hw->rx_bdr;
+	u64 rx_bd_add = (u64)enetc_rxbd;
+	int i;
+
+	/* used later to advance to the next BD produced by ENETC HW */
+	rx_bdr->bd_count = ENETC_BD_CNT;
+	rx_bdr->next_prod_idx = 0;
+	rx_bdr->next_cons_idx = ENETC_RBCI_INIT;
+	rx_bdr->cons_idx = hw->regs_base +
+				ENETC_BDR(RX, ENETC_RX_BDR_ID, ENETC_RBCIR);
+	rx_bdr->prod_idx = hw->regs_base +
+				ENETC_BDR(RX, ENETC_RX_BDR_ID, ENETC_RBPIR);
+
+	/* set Rx BD address */
+	enetc_bdr_write(hw, RX, ENETC_RX_BDR_ID, ENETC_RBBAR0,
+			lower_32_bits(rx_bd_add));
+	enetc_bdr_write(hw, RX, ENETC_RX_BDR_ID, ENETC_RBBAR1,
+			upper_32_bits(rx_bd_add));
+	/* set Rx BD count (multiple of 8) */
+	enetc_bdr_write(hw, RX, ENETC_RX_BDR_ID, ENETC_RBLENR,
+			rx_bdr->bd_count);
+	/* set Rx buffer  size */
+	enetc_bdr_write(hw, RX, ENETC_RX_BDR_ID, ENETC_RBBSR, ENETC_BUFF_SIZE);
+
+	/* reset producer (ENETC owned) and consumer (SW owned) index */
+	enetc_write_reg(rx_bdr->cons_idx, rx_bdr->next_cons_idx);
+	enetc_write_reg(rx_bdr->prod_idx, rx_bdr->next_prod_idx);
+
+	/* fill Rx BD */
+	memset(enetc_rxbd, 0, rx_bdr->bd_count * sizeof(union enetc_rx_bd));
+	for (i = 0; i < rx_bdr->bd_count; i++) {
+		enetc_rxbd[i].w.addr = enetc_rxb_address(dev, i);
+		/* each RX buffer must be aligned to 64B */
+		WARN_ON(enetc_rxbd[i].w.addr & (ENETC_ALIGN - 1));
+	}
+	/* enable Rx ring */
+	enetc_bdr_write(hw, RX, ENETC_RX_BDR_ID, ENETC_RBMR, ENETC_RBMR_EN);
+}
+
+/**
+ * Start ENETC interface:
+ * - perform FLR
+ * - enable access to port and SI registers
+ * - set mac address
+ * - setup TX/RX buffer descriptors
+ * - enable Tx/Rx rings
+ */
+static int enetc_start(struct udevice *dev)
+{
+	struct eth_pdata *plat = dev_get_platdata(dev);
+	struct enetc_devfn *hw = dev_get_priv(dev);
+	u32 if_mode;
+
+	/* reset and enable the PCI device */
+	dm_pci_flr(dev);
+	dm_pci_clrset_config16(dev, PCI_COMMAND, 0,
+			       PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+
+	if_mode = enetc_read_port(hw, ENETC_PM_IF_MODE);
+	if (if_mode & ENETC_PM_IF_MODE_RG)
+		if_mode |= ENETC_PM_IF_MODE_AN_ENA;
+	enetc_write_port(hw, ENETC_PM_IF_MODE, if_mode);
+
+	if (!is_valid_ethaddr(plat->enetaddr)) {
+		ENETC_DBG(dev, "invalid MAC address, generate random ...\n");
+		net_random_ethaddr(plat->enetaddr);
+	}
+	enetc_set_primary_mac_addr(hw, plat->enetaddr);
+
+	enetc_enable_si_port(hw);
+
+	/* setup Tx/Rx buffer descriptors */
+	enetc_setup_tx_bdr(hw);
+	enetc_setup_rx_bdr(dev, hw);
+
+	return 0;
+}
+
+/* FLR is sufficient to quiesce the device */
+static void enetc_stop(struct udevice *dev)
+{
+	/* reset device */
+	dm_pci_flr(dev);
+}
+
+/**
+ * ENETC transmit packet:
+ * - check if Tx BD ring is full
+ * - set buffer/packet address (dma address)
+ * - set final fragment flag
+ * - try while producer index equals consumer index or timeout
+ */
+static int enetc_send(struct udevice *dev, void *packet, int length)
+{
+	struct enetc_devfn *hw = dev_get_priv(dev);
+	struct bd_ring *txr = &hw->tx_bdr;
+	void *nv_packet = (void *)packet;
+	int tries = ENETC_POLL_TRIES;
+	u32 pi, ci;
+
+	pi = txr->next_prod_idx;
+	ci = enetc_read_reg(txr->cons_idx) & ENETC_BDR_IDX_MASK;
+	/* Tx ring is full when */
+	if (((pi + 1) % txr->bd_count) == ci) {
+		ENETC_DBG(dev, "Tx BDR full\n");
+		return -ETIMEDOUT;
+	}
+	ENETC_DBG(dev, "TxBD[%d]send: pkt_len=%d, buff @0x%x%08x\n", pi, length,
+		  upper_32_bits((u64)nv_packet), lower_32_bits((u64)nv_packet));
+
+	/* prepare Tx BD */
+	memset(&enetc_txbd[pi], 0x0, sizeof(struct enetc_tx_bd));
+	enetc_txbd[pi].addr =  cpu_to_le64(dm_pci_virt_to_mem(dev, nv_packet));
+	enetc_txbd[pi].buf_len = cpu_to_le16(length);
+	enetc_txbd[pi].frm_len = cpu_to_le16(length);
+	enetc_txbd[pi].flags = cpu_to_le16(ENETC_TXBD_FLAGS_F);
+	dmb();
+	/* send frame: increment producer index */
+	pi = (pi + 1) % txr->bd_count;
+	txr->next_prod_idx = pi;
+	enetc_write_reg(txr->prod_idx, pi);
+	while ((--tries >= 0) &&
+	       (pi != (enetc_read_reg(txr->cons_idx) & ENETC_BDR_IDX_MASK)))
+		udelay(10);
+
+	return tries > 0 ? 0 : -ETIMEDOUT;
+}
+
+/**
+ * Handles frame receive and cleans up the BD slot on the Rx ring.
+ */
+static int enetc_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+	struct enetc_devfn *hw = dev_get_priv(dev);
+	struct bd_ring *rxr = &hw->rx_bdr;
+	int tries = ENETC_POLL_TRIES;
+	int pi = rxr->next_prod_idx;
+	int ci = rxr->next_cons_idx;
+	u32 status;
+	int len;
+	u8 rdy;
+
+	do {
+		dmb();
+		status = le32_to_cpu(enetc_rxbd[pi].r.lstatus);
+		/* check if current BD is ready to be consumed */
+		rdy = ENETC_RXBD_STATUS_R(status);
+	} while (--tries >= 0 && !rdy);
+
+	if (!rdy)
+		return -EAGAIN;
+
+	dmb();
+	len = le16_to_cpu(enetc_rxbd[pi].r.buf_len);
+	*packetp = (uchar *)enetc_rxb_address(dev, pi);
+	ENETC_DBG(dev, "RxBD[%d]: len=%d err=%d pkt=0x%x%08x\n", pi, len,
+		  ENETC_RXBD_STATUS_ERRORS(status),
+		  upper_32_bits((u64)*packetp), lower_32_bits((u64)*packetp));
+
+	/* BD clean up and advance to next in ring */
+	memset(&enetc_rxbd[pi], 0, sizeof(union enetc_rx_bd));
+	enetc_rxbd[pi].w.addr = enetc_rxb_address(dev, pi);
+	rxr->next_prod_idx = (pi + 1) % rxr->bd_count;
+	ci = (ci + 1) % rxr->bd_count;
+	rxr->next_cons_idx = ci;
+	dmb();
+	/* free up the slot in the ring for HW */
+	enetc_write_reg(rxr->cons_idx, ci);
+
+	return len;
+}
+
+static const struct eth_ops enetc_ops = {
+	.start	= enetc_start,
+	.send	= enetc_send,
+	.recv	= enetc_recv,
+	.stop	= enetc_stop,
+};
+
+U_BOOT_DRIVER(eth_enetc) = {
+	.name	= "enetc_eth",
+	.id	= UCLASS_ETH,
+	.bind	= enetc_bind,
+	.probe	= enetc_probe,
+	.ops	= &enetc_ops,
+	.priv_auto_alloc_size = sizeof(struct enetc_devfn),
+	.platdata_auto_alloc_size = sizeof(struct eth_pdata),
+};
+
+static struct pci_device_id enetc_ids[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, PCI_DEVICE_ID_ENETC_PF_V1) },
+	{}
+};
+
+U_BOOT_PCI_DEVICE(eth_enetc, enetc_ids);
diff --git a/drivers/net/fsl_enetc.h b/drivers/net/fsl_enetc.h
new file mode 100644
index 0000000000..4ebf03a61a
--- /dev/null
+++ b/drivers/net/fsl_enetc.h
@@ -0,0 +1,176 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * ENETC ethernet controller driver
+ * Copyright 2017-2019 NXP
+ */
+
+#ifndef _ENETC_H
+#define _ENETC_H
+
+#include <common.h>
+
+#ifdef ENETC_DEBUG
+#define ENETC_DBG(udev, fmt, args...) \
+	printf("enetc[%s]: " fmt, udev->name, ##args)
+#else
+#define ENETC_DBG(devno, args...)	do { } while (0)
+#endif
+/* ENETC controller registers */
+
+/* Station interface register offsets */
+#define ENETC_SIMR	0
+#define ENETC_SIMR_EN	BIT(31)
+#define ENETC_SICAR0	0x40
+/* write cache cfg: snoop, no allocate, update full (data), partial (BD) */
+#define ENETC_SICAR_WR_CFG	0x6767
+/* read cache cfg: coherent copy, look up, no allocate */
+#define ENETC_SICAR_RD_CFG	0x27270000
+
+#define ENETC_SIROCT	0x300
+#define ENETC_SIRFRM	0x308
+#define ENETC_SITOCT	0x320
+#define ENETC_SITFRM	0x328
+
+/* Station Interface Rx/Tx Buffer Descriptor Ring registers */
+enum enetc_bdr_type {TX, RX};
+#define ENETC_BDR(type, n, off)	(0x8000 + (type) * 0x100 + (n) * 0x200 + (off))
+#define ENETC_BDR_IDX_MASK	0xffff
+
+/* Rx BDR reg offsets */
+#define ENETC_RBMR	0
+#define ENETC_RBMR_EN	BIT(31)
+#define ENETC_RBBSR	0x8
+#define ENETC_RBCIR	0xc
+/* initial consumer index for Rx BDR */
+#define ENETC_RBCI_INIT 4
+#define ENETC_RBBAR0	0x10
+#define ENETC_RBBAR1	0x14
+#define ENETC_RBPIR	0x18
+#define ENETC_RBLENR	0x20
+
+/* Tx BDR reg offsets */
+#define ENETC_TBMR	0
+#define ENETC_TBMR_EN	BIT(31)
+#define ENETC_TBBAR0	0x10
+#define ENETC_TBBAR1	0x14
+#define ENETC_TBPIR	0x18
+#define ENETC_TBCIR	0x1c
+#define ENETC_TBLENR	0x20
+
+/* Port registers offset */
+#define ENETC_PORT_REGS_OFF 0x10000
+#define ENETC_PMR	0x00000
+
+#define ENETC_PMR_SI0_EN	BIT(16)
+#define ENETC_PSIPMMR	0x18
+#define ENETC_PSIPMAR0		0x00100
+#define ENETC_PSIPMAR1		0x00104
+#define ENETC_PSICFGR(n)	(0x00940 + (n) * 0x10)
+#define ENETC_PSICFGR_SET_TXBDR(val)	((val) & 0xff)
+#define ENETC_PSICFGR_SET_RXBDR(val)	(((val) & 0xff) << 16)
+#define ENETC_EMDIO_CFG 0x1c00
+#define ENETC_PM_CC	0x8008
+/* Port config: enable MAC Tx/Rx, Tx padding, MAC promisc */
+#define ENETC_PM_CC_DEFAULT 0x810
+#define ENETC_PM_CC_RX_TX_EN 0x8813
+#define ENETC_PM_MAXFRM	0x8014
+#define ENETC_RX_MAXFRM_SIZE	PKTSIZE_ALIGN
+#define ENETC_BUFF_SIZE	PKTSIZE_ALIGN
+#define ENETC_PM_IF_MODE	0x8300
+#define ENETC_PM_IF_MODE_RG		0x00000004
+#define ENETC_PM_IF_MODE_AN_ENA		0x00008000
+#define ENETC_PM_IF_STATUS		0x8304
+#define ENETC_PM_IF_STATUS_RGL		0x00008000
+#define ENETC_PM_IF_STATUS_RGFD		0x00001000
+/* buffer descriptors count must be multiple of 8 and aligned to 128 bytes */
+#define ENETC_BD_CNT 16
+#define ENETC_ALIGN 128
+#define ENETC_RX_MBUFF_SIZE (ENETC_BD_CNT * ENETC_RX_MAXFRM_SIZE)
+
+/* single pair of Rx/Tx rings */
+#define ENETC_RX_BDR_CNT 1
+#define ENETC_TX_BDR_CNT 1
+#define ENETC_RX_BDR_ID 0
+#define ENETC_TX_BDR_ID 0
+
+/* Tx buffer descriptor */
+struct enetc_tx_bd {
+	__le64 addr;
+	__le16 buf_len;
+	__le16 frm_len;
+	__le16 err_csum;
+	__le16 flags;
+};
+
+#define ENETC_TXBD_FLAGS_F	BIT(15)
+#define ENETC_POLL_TRIES 0x8000
+
+/* Rx buffer descriptor */
+union enetc_rx_bd {
+	/* SW provided BD format */
+	struct {
+		__le64 addr;
+		u8 reserved[8];
+	} w;
+
+	/* ENETC returned BD format */
+	struct {
+		__le16 inet_csum;
+		__le16 parse_summary;
+		__le32 rss_hash;
+		__le16 buf_len;
+		__le16 vlan_opt;
+		union {
+			struct {
+				__le16 flags;
+				__le16 error;
+			};
+			__le32 lstatus;
+		};
+	} r;
+};
+
+#define ENETC_RXBD_STATUS_R(status)	(((status) >> 30) & 0x1)
+#define ENETC_RXBD_STATUS_F(status)	(((status) >> 31) & 0x1)
+#define ENETC_RXBD_STATUS_ERRORS(status)	(((status) >> 16) & 0xff)
+#define ENETC_RXBD_STATUS(flags)	((flags) << 16)
+
+/* Tx/Rx ring info */
+struct bd_ring {
+	void *cons_idx;
+	void *prod_idx;
+	/* next BD index to use */
+	int next_prod_idx;
+	int next_cons_idx;
+	int bd_count;
+};
+
+/* ENETC HW access info */
+struct enetc_devfn {
+	void *regs_base; /* base ENETC registers */
+	void *port_regs; /* base ENETC port registers */
+
+	/* Rx/Tx buffer descriptor rings info */
+	struct bd_ring tx_bdr;
+	struct bd_ring rx_bdr;
+};
+
+/* register accessors */
+#define enetc_read_reg(x)	readl((x))
+#define enetc_write_reg(x, val)	writel((val), (x))
+#define enetc_read(hw, off)	enetc_read_reg((hw)->regs_base + (off))
+#define enetc_write(hw, off, v)	enetc_write_reg((hw)->regs_base + (off), v)
+
+/* port register accessors */
+#define enetc_port_regs(hw, off) ((hw)->port_regs + (off))
+#define enetc_read_port(hw, off) enetc_read_reg(enetc_port_regs((hw), (off)))
+#define enetc_write_port(hw, off, v) \
+				enetc_write_reg(enetc_port_regs((hw), (off)), v)
+
+/* BDR register accessors, see ENETC_BDR() */
+#define enetc_bdr_read(hw, t, n, off) \
+				enetc_read(hw, ENETC_BDR(t, n, off))
+#define enetc_bdr_write(hw, t, n, off, val) \
+				enetc_write(hw, ENETC_BDR(t, n, off), val)
+
+#endif /* _ENETC_H */
diff --git a/include/pci_ids.h b/include/pci_ids.h
index bd59578ccb..06e1319366 100644
--- a/include/pci_ids.h
+++ b/include/pci_ids.h
@@ -2483,6 +2483,7 @@
 #define PCI_DEVICE_ID_MPC8641		0x7010
 #define PCI_DEVICE_ID_MPC8641D		0x7011
 #define PCI_DEVICE_ID_MPC8610		0x7018
+#define PCI_DEVICE_ID_ENETC_PF_V1	0xE100
 
 #define PCI_VENDOR_ID_PASEMI		0x1959
 
-- 
2.17.1

  reply	other threads:[~2019-05-31 16:33 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-31 16:25 [U-Boot] [PATCH 1/2] drivers: pci: add map_bar support for Enhanced Allocation Alex Marginean
2019-05-31 16:25 ` [U-Boot] [PATCH 2/2] drivers: pci: add API to issue FLR on a PCI function, if supported Alex Marginean
2019-05-31 16:33   ` Alex Marginean [this message]
2019-05-31 16:33     ` [U-Boot] [PATCH 2/2] drivers: net: add NXP ENETC MDIO driver Alex Marginean
2019-06-02 13:48   ` [U-Boot] [PATCH 2/2] drivers: pci: add API to issue FLR on a PCI function, if supported Bin Meng
2019-06-02 13:15 ` [U-Boot] [PATCH 1/2] drivers: pci: add map_bar support for Enhanced Allocation Bin Meng
2019-06-03 12:49   ` Alex Marginean
2019-06-03 13:01     ` Bin Meng
2019-06-04 12:46   ` [U-Boot] [PATCH 1/4 v2] pci: fixed dm_pci_map_bar comment Alex Marginean
2019-06-04 12:46     ` [U-Boot] [PATCH 2/4 v2] drivers: pci: add map_bar support for Enhanced Allocation Alex Marginean
2019-06-05 10:05       ` Bin Meng
2019-06-04 12:46     ` [U-Boot] [PATCH 3/4 v2] test: dm: Add a test for PCI " Alex Marginean
2019-06-05 10:05       ` Bin Meng
2019-06-06  7:38         ` Alexandru Marginean
2019-06-06 10:27           ` Bin Meng
2019-06-07  8:24             ` [U-Boot] [PATCH 1/4 v3] pci: fixed dm_pci_map_bar comment Alex Marginean
2019-06-07  8:24               ` [U-Boot] [PATCH 2/4 v3] drivers: pci: add map_bar support for Enhanced Allocation Alex Marginean
2019-06-28 13:55                 ` Simon Glass
2019-06-07  8:24               ` [U-Boot] [PATCH 3/4 v3] test: dm: Add a test for PCI " Alex Marginean
2019-06-28 13:55                 ` Simon Glass
2019-06-07  8:24               ` [U-Boot] [PATCH 4/4 v3] drivers: pci: add API to issue FLR on a PCI function if supported Alex Marginean
2019-06-28 13:55                 ` Simon Glass
2019-06-04 12:46     ` [U-Boot] [PATCH 4/4 v2] " Alex Marginean
2019-06-05 10:05       ` Bin Meng
2019-06-05 10:05     ` [U-Boot] [PATCH 1/4 v2] pci: fixed dm_pci_map_bar comment Bin Meng
2019-06-28 13:55       ` Simon Glass

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=20190531163308.30698-1-alexm.osslist@gmail.com \
    --to=alexm.osslist@gmail.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.