[U-Boot] [PATCH 0/4] x86: Add Intel Topcliff PCH Gigabit Ethernet support

This series adds a new ethernet driver for the GMAC found on Intel Topcliff Platform Controller Hub and enable its support on Intel Crown Bay board.
The series also did some clean up work below: - Introduce ETH_FCS_LEN macro as it is often used by some ethernet drivers - Remove any local version of ETH_FCS_LEN from various places - Update README.drivers.eth for up-to-date mdio APIs
Bin Meng (4): net: Add ethernet FCS length macro in net.h net: Update README.drivers.eth to mention latest APIs net: Add Intel Topcliff GMAC driver x86: crownbay: Enable Intel Topcliff GMAC support
doc/README.drivers.eth | 51 +++-- drivers/net/Makefile | 1 + drivers/net/e1000.h | 7 +- drivers/net/pch_gbe.c | 466 +++++++++++++++++++++++++++++++++++++++++++++ drivers/net/pch_gbe.h | 300 +++++++++++++++++++++++++++++ drivers/usb/gadget/ether.c | 1 - drivers/usb/gadget/rndis.c | 1 - include/configs/crownbay.h | 4 + include/net.h | 2 + include/netdev.h | 4 + include/usb_ether.h | 1 - 11 files changed, 815 insertions(+), 23 deletions(-) create mode 100644 drivers/net/pch_gbe.c create mode 100644 drivers/net/pch_gbe.h

Some ethernet drivers use their own version of ethernet FCS length macro which is really common. We define ETH_FCS_LEN in net.h and replace those custom versions in various places.
Signed-off-by: Bin Meng bmeng.cn@gmail.com ---
drivers/net/e1000.h | 7 +++---- drivers/usb/gadget/ether.c | 1 - drivers/usb/gadget/rndis.c | 1 - include/net.h | 2 ++ include/usb_ether.h | 1 - 5 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/net/e1000.h b/drivers/net/e1000.h index 6d110eb..f3b77b1 100644 --- a/drivers/net/e1000.h +++ b/drivers/net/e1000.h @@ -430,12 +430,11 @@ struct e1000_phy_stats { #define ENET_HEADER_SIZE 14 #define MAXIMUM_ETHERNET_FRAME_SIZE 1518 /* With FCS */ #define MINIMUM_ETHERNET_FRAME_SIZE 64 /* With FCS */ -#define ETHERNET_FCS_SIZE 4 #define MAXIMUM_ETHERNET_PACKET_SIZE \ - (MAXIMUM_ETHERNET_FRAME_SIZE - ETHERNET_FCS_SIZE) + (MAXIMUM_ETHERNET_FRAME_SIZE - ETH_FCS_LEN) #define MINIMUM_ETHERNET_PACKET_SIZE \ - (MINIMUM_ETHERNET_FRAME_SIZE - ETHERNET_FCS_SIZE) -#define CRC_LENGTH ETHERNET_FCS_SIZE + (MINIMUM_ETHERNET_FRAME_SIZE - ETH_FCS_LEN) +#define CRC_LENGTH ETH_FCS_LEN #define MAX_JUMBO_FRAME_SIZE 0x3F00
/* 802.1q VLAN Packet Sizes */ diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index ba442d5..8f03a6b 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -68,7 +68,6 @@ unsigned packet_received, packet_sent; #define ETH_ZLEN 60 /* Min. octets in frame sans FCS */ #define ETH_DATA_LEN 1500 /* Max. octets in payload */ #define ETH_FRAME_LEN PKTSIZE_ALIGN /* Max. octets in frame sans FCS */ -#define ETH_FCS_LEN 4 /* Octets in the FCS */
#define DRIVER_DESC "Ethernet Gadget" /* Based on linux 2.6.27 version */ diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index 404a7b9..62c9b2e 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c @@ -43,7 +43,6 @@ #define ETH_ZLEN 60 /* Min. octets in frame sans FCS */ #define ETH_DATA_LEN 1500 /* Max. octets in payload */ #define ETH_FRAME_LEN PKTSIZE_ALIGN /* Max. octets in frame sans FCS */ -#define ETH_FCS_LEN 4 /* Octets in the FCS */ #define ENOTSUPP 524 /* Operation is not supported */
diff --git a/include/net.h b/include/net.h index 73ea88b..b9a5c41 100644 --- a/include/net.h +++ b/include/net.h @@ -191,6 +191,8 @@ struct ethernet_hdr { /* Ethernet header size */ #define ETHER_HDR_SIZE (sizeof(struct ethernet_hdr))
+#define ETH_FCS_LEN 4 /* Octets in the FCS */ + struct e802_hdr { uchar et_dest[6]; /* Destination node */ uchar et_src[6]; /* Source node */ diff --git a/include/usb_ether.h b/include/usb_ether.h index b38d037..23507e1 100644 --- a/include/usb_ether.h +++ b/include/usb_ether.h @@ -18,7 +18,6 @@ #define ETH_ZLEN 60 /* Min. octets in frame sans FCS */ #define ETH_DATA_LEN 1500 /* Max. octets in payload */ #define ETH_FRAME_LEN PKTSIZE_ALIGN /* Max. octets in frame sans FCS */ -#define ETH_FCS_LEN 4 /* Octets in the FCS */
struct ueth_data { /* eth info */

On Fri, Mar 20, 2015 at 4:12 AM, Bin Meng bmeng.cn@gmail.com wrote:
Some ethernet drivers use their own version of ethernet FCS length macro which is really common. We define ETH_FCS_LEN in net.h and replace those custom versions in various places.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Acked-by: Joe Hershberger joe.hershberger@ni.com

On 20 March 2015 at 13:18, Joe Hershberger joe.hershberger@gmail.com wrote:
On Fri, Mar 20, 2015 at 4:12 AM, Bin Meng bmeng.cn@gmail.com wrote:
Some ethernet drivers use their own version of ethernet FCS length macro which is really common. We define ETH_FCS_LEN in net.h and replace those custom versions in various places.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Acked-by: Joe Hershberger joe.hershberger@ni.com
I'll pick this up to get this board into better shape.
Applied to u-boot-x86, thanks!

README.drivers.eth still refers to the deprecated miiphy_register(). Update the doc to mention new APIs mdio_alloc() and mdio_register().
Signed-off-by: Bin Meng bmeng.cn@gmail.com ---
doc/README.drivers.eth | 51 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 16 deletions(-)
diff --git a/doc/README.drivers.eth b/doc/README.drivers.eth index eb83038..42af442 100644 --- a/doc/README.drivers.eth +++ b/doc/README.drivers.eth @@ -43,15 +43,16 @@ int ape_register(bd_t *bis, int iobase) { struct ape_priv *priv; struct eth_device *dev; + struct mii_dev *bus;
priv = malloc(sizeof(*priv)); if (priv == NULL) - return 1; + return -ENOMEM;
dev = malloc(sizeof(*dev)); if (dev == NULL) { free(priv); - return 1; + return -ENOMEM; }
/* setup whatever private state you need */ @@ -59,7 +60,8 @@ int ape_register(bd_t *bis, int iobase) memset(dev, 0, sizeof(*dev)); sprintf(dev->name, "APE");
- /* if your device has dedicated hardware storage for the + /* + * if your device has dedicated hardware storage for the * MAC, read it and initialize dev->enetaddr with it */ ape_mac_read(dev->enetaddr); @@ -74,8 +76,17 @@ int ape_register(bd_t *bis, int iobase)
eth_register(dev);
-#ifdef CONFIG_CMD_MII) - miiphy_register(dev->name, ape_mii_read, ape_mii_write); +#ifdef CONFIG_PHYLIB + bus = mdio_alloc(); + if (!bus) { + free(priv); + free(dev); + return -ENOMEM; + } + + bus->read = ape_mii_read; + bus->write = ape_mii_write; + mdio_register(bus); #endif
return 1; @@ -166,25 +177,33 @@ some net operation (ping / tftp / whatever...) eth_halt() dev->halt()
------------------------------ - CONFIG_MII / CONFIG_CMD_MII ------------------------------ +-------------------------------- + CONFIG_PHYLIB / CONFIG_CMD_MII +--------------------------------
If your device supports banging arbitrary values on the MII bus (pretty much every device does), you should add support for the mii command. Doing so is fairly trivial and makes debugging mii issues a lot easier at runtime.
After you have called eth_register() in your driver's register function, add -a call to miiphy_register() like so: -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) - miiphy_register(dev->name, mii_read, mii_write); -#endif +a call to mdio_alloc() and mdio_register() like so: + bus = mdio_alloc(); + if (!bus) { + free(priv); + free(dev); + return -ENOMEM; + } + + bus->read = ape_mii_read; + bus->write = ape_mii_write; + mdio_register(bus);
And then define the mii_read and mii_write functions if you haven't already. Their syntax is straightforward: - int mii_read(char *devname, uchar addr, uchar reg, ushort *val); - int mii_write(char *devname, uchar addr, uchar reg, ushort val); + int mii_read(struct mii_dev *bus, int addr, int devad, int reg); + int mii_write(struct mii_dev *bus, int addr, int devad, int reg, + u16 val);
The read function should read the register 'reg' from the phy at address 'addr' -and store the result in the pointer 'val'. The implementation for the write -function should logically follow. +and return the result to its caller. The implementation for the write function +should logically follow.

On Fri, Mar 20, 2015 at 4:12 AM, Bin Meng bmeng.cn@gmail.com wrote:
README.drivers.eth still refers to the deprecated miiphy_register(). Update the doc to mention new APIs mdio_alloc() and mdio_register().
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Acked-by: Joe Hershberger joe.hershberger@ni.com

On 20 March 2015 at 13:18, Joe Hershberger joe.hershberger@gmail.com wrote:
On Fri, Mar 20, 2015 at 4:12 AM, Bin Meng bmeng.cn@gmail.com wrote:
README.drivers.eth still refers to the deprecated miiphy_register(). Update the doc to mention new APIs mdio_alloc() and mdio_register().
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Acked-by: Joe Hershberger joe.hershberger@ni.com
Applied to u-boot-x86, thanks!

Add a new driver for the Gigabit Ethernet MAC found on Intel Topcliff Platform Controller Hub. Tested under 10/100 half/full duplex and 1000 full duplex modes using ping and tftpboot commands.
Signed-off-by: Bin Meng bmeng.cn@gmail.com ---
drivers/net/Makefile | 1 + drivers/net/pch_gbe.c | 466 ++++++++++++++++++++++++++++++++++++++++++++++++++ drivers/net/pch_gbe.h | 300 ++++++++++++++++++++++++++++++++ include/netdev.h | 4 + 4 files changed, 771 insertions(+) create mode 100644 drivers/net/pch_gbe.c create mode 100644 drivers/net/pch_gbe.h
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 46c4ac6..66c35fa 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -47,6 +47,7 @@ obj-$(CONFIG_DRIVER_NE2000) += ne2000.o ne2000_base.o obj-$(CONFIG_DRIVER_AX88796L) += ax88796.o ne2000_base.o obj-$(CONFIG_NETCONSOLE) += netconsole.o obj-$(CONFIG_NS8382X) += ns8382x.o +obj-$(CONFIG_PCH_GBE) += pch_gbe.o obj-$(CONFIG_PCNET) += pcnet.o obj-$(CONFIG_RTL8139) += rtl8139.o obj-$(CONFIG_RTL8169) += rtl8169.o diff --git a/drivers/net/pch_gbe.c b/drivers/net/pch_gbe.c new file mode 100644 index 0000000..976848d --- /dev/null +++ b/drivers/net/pch_gbe.c @@ -0,0 +1,466 @@ +/* + * Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com + * + * Intel Platform Controller Hub EG20T (codename Topcliff) GMAC Driver + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <errno.h> +#include <asm/io.h> +#include <pci.h> +#include <malloc.h> +#include <miiphy.h> +#include "pch_gbe.h" + +#if !defined(CONFIG_PHYLIB) +# error "PCH Gigabit Ethernet driver requires PHYLIB - missing CONFIG_PHYLIB" +#endif + +static struct pci_device_id supported[] = { + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TCF_GBE }, + { } +}; + +static void pch_gbe_mac_read(struct pch_gbe_regs *mac_regs, u8 *addr) +{ + u32 macid_hi, macid_lo; + + macid_hi = readl(&mac_regs->mac_adr[0].high); + macid_lo = readl(&mac_regs->mac_adr[0].low) & 0xffff; + debug("pch_gbe: macid_hi %#x macid_lo %#x\n", macid_hi, macid_lo); + + addr[0] = (u8)(macid_hi & 0xff); + addr[1] = (u8)((macid_hi >> 8) & 0xff); + addr[2] = (u8)((macid_hi >> 16) & 0xff); + addr[3] = (u8)((macid_hi >> 24) & 0xff); + addr[4] = (u8)(macid_lo & 0xff); + addr[5] = (u8)((macid_lo >> 8) & 0xff); +} + +static int pch_gbe_mac_write(struct pch_gbe_regs *mac_regs, u8 *addr) +{ + u32 macid_hi, macid_lo; + ulong start; + + macid_hi = addr[0] + (addr[1] << 8) + (addr[2] << 16) + (addr[3] << 24); + macid_lo = addr[4] + (addr[5] << 8); + + writel(macid_hi, &mac_regs->mac_adr[0].high); + writel(macid_lo, &mac_regs->mac_adr[0].low); + writel(0xfffe, &mac_regs->addr_mask); + + start = get_timer(0); + while (get_timer(start) < PCH_GBE_TIMEOUT) { + if (!(readl(&mac_regs->addr_mask) & PCH_GBE_BUSY)) + return 0; + + udelay(10); + } + + return -ETIME; +} + +static int pch_gbe_reset(struct eth_device *dev) +{ + struct pch_gbe_priv *priv = dev->priv; + struct pch_gbe_regs *mac_regs = priv->mac_regs; + ulong start; + + priv->rx_idx = 0; + priv->tx_idx = 0; + + writel(PCH_GBE_ALL_RST, &mac_regs->reset); + + /* + * Configure the MAC to RGMII mode after reset + * + * For some unknown reason, we must do the configuration here right + * after resetting the whole MAC, otherwise the reset bit in the RESET + * register will never be cleared by the hardware. And there is another + * way of having the same magic, that is to configure the MODE register + * to have the MAC work in MII/GMII mode, which is how current Linux + * pch_gbe driver does. Since anyway we need program the MAC to RGMII + * mode in the driver, we just do it here. + * + * Note: this behavior is not documented in the hardware manual. + */ + writel(PCH_GBE_RGMII_MODE_RGMII | PCH_GBE_CHIP_TYPE_INTERNAL, + &mac_regs->rgmii_ctrl); + + start = get_timer(0); + while (get_timer(start) < PCH_GBE_TIMEOUT) { + if (!(readl(&mac_regs->reset) & PCH_GBE_ALL_RST)) { + /* + * Soft reset clears hardware MAC address registers, + * so we have to reload MAC address here in order to + * make linux pch_gbe driver happy. + */ + return pch_gbe_mac_write(mac_regs, dev->enetaddr); + } + + udelay(10); + } + + debug("pch_gbe: reset timeout\n"); + return -ETIME; +} + +static void pch_gbe_rx_descs_init(struct eth_device *dev) +{ + struct pch_gbe_priv *priv = dev->priv; + struct pch_gbe_regs *mac_regs = priv->mac_regs; + struct pch_gbe_rx_desc *rx_desc = &priv->rx_desc[0]; + int i; + + memset(rx_desc, 0, sizeof(struct pch_gbe_rx_desc) * PCH_GBE_DESC_NUM); + for (i = 0; i < PCH_GBE_DESC_NUM; i++) + rx_desc->buffer_addr = pci_phys_to_mem(priv->bdf, + (u32)(priv->rx_buff[i])); + + writel(pci_phys_to_mem(priv->bdf, (u32)rx_desc), + &mac_regs->rx_dsc_base); + writel(sizeof(struct pch_gbe_rx_desc) * (PCH_GBE_DESC_NUM - 1), + &mac_regs->rx_dsc_size); + + writel(pci_phys_to_mem(priv->bdf, (u32)(rx_desc + 1)), + &mac_regs->rx_dsc_sw_p); +} + +static void pch_gbe_tx_descs_init(struct eth_device *dev) +{ + struct pch_gbe_priv *priv = dev->priv; + struct pch_gbe_regs *mac_regs = priv->mac_regs; + struct pch_gbe_tx_desc *tx_desc = &priv->tx_desc[0]; + + memset(tx_desc, 0, sizeof(struct pch_gbe_tx_desc) * PCH_GBE_DESC_NUM); + + writel(pci_phys_to_mem(priv->bdf, (u32)tx_desc), + &mac_regs->tx_dsc_base); + writel(sizeof(struct pch_gbe_tx_desc) * (PCH_GBE_DESC_NUM - 1), + &mac_regs->tx_dsc_size); + writel(pci_phys_to_mem(priv->bdf, (u32)(tx_desc + 1)), + &mac_regs->tx_dsc_sw_p); +} + +static void pch_gbe_adjust_link(struct pch_gbe_regs *mac_regs, + struct phy_device *phydev) +{ + if (!phydev->link) { + printf("%s: No link.\n", phydev->dev->name); + return; + } + + clrbits_le32(&mac_regs->rgmii_ctrl, + PCH_GBE_RGMII_RATE_2_5M | PCH_GBE_CRS_SEL); + clrbits_le32(&mac_regs->mode, + PCH_GBE_MODE_GMII_ETHER | PCH_GBE_MODE_FULL_DUPLEX); + + switch (phydev->speed) { + case 1000: + setbits_le32(&mac_regs->rgmii_ctrl, PCH_GBE_RGMII_RATE_125M); + setbits_le32(&mac_regs->mode, PCH_GBE_MODE_GMII_ETHER); + break; + case 100: + setbits_le32(&mac_regs->rgmii_ctrl, PCH_GBE_RGMII_RATE_25M); + setbits_le32(&mac_regs->mode, PCH_GBE_MODE_MII_ETHER); + break; + case 10: + setbits_le32(&mac_regs->rgmii_ctrl, PCH_GBE_RGMII_RATE_2_5M); + setbits_le32(&mac_regs->mode, PCH_GBE_MODE_MII_ETHER); + break; + } + + if (phydev->duplex) { + setbits_le32(&mac_regs->rgmii_ctrl, PCH_GBE_CRS_SEL); + setbits_le32(&mac_regs->mode, PCH_GBE_MODE_FULL_DUPLEX); + } + + printf("Speed: %d, %s duplex\n", phydev->speed, + (phydev->duplex) ? "full" : "half"); + + return; +} + +static int pch_gbe_init(struct eth_device *dev, bd_t *bis) +{ + struct pch_gbe_priv *priv = dev->priv; + struct pch_gbe_regs *mac_regs = priv->mac_regs; + + if (pch_gbe_reset(dev)) + return -1; + + pch_gbe_rx_descs_init(dev); + pch_gbe_tx_descs_init(dev); + + /* Enable frame bursting */ + writel(PCH_GBE_MODE_FR_BST, &mac_regs->mode); + /* Disable TCP/IP accelerator */ + writel(PCH_GBE_RX_TCPIPACC_OFF, &mac_regs->tcpip_acc); + /* Disable RX flow control */ + writel(0, &mac_regs->rx_fctrl); + /* Configure RX/TX mode */ + writel(PCH_GBE_RH_ALM_EMP_16 | PCH_GBE_RH_ALM_FULL_16 | + PCH_GBE_RH_RD_TRG_32, &mac_regs->rx_mode); + writel(PCH_GBE_TM_TH_TX_STRT_32 | PCH_GBE_TM_TH_ALM_EMP_16 | + PCH_GBE_TM_TH_ALM_FULL_32 | PCH_GBE_TM_ST_AND_FD | + PCH_GBE_TM_SHORT_PKT, &mac_regs->tx_mode); + + /* Start up the PHY */ + if (phy_startup(priv->phydev)) { + printf("Could not initialize PHY %s\n", + priv->phydev->dev->name); + return -1; + } + + pch_gbe_adjust_link(mac_regs, priv->phydev); + + if (!priv->phydev->link) + return -1; + + /* Enable TX & RX */ + writel(PCH_GBE_RX_DMA_EN | PCH_GBE_TX_DMA_EN, &mac_regs->dma_ctrl); + writel(PCH_GBE_MRE_MAC_RX_EN, &mac_regs->mac_rx_en); + + return 0; +} + +static void pch_gbe_halt(struct eth_device *dev) +{ + struct pch_gbe_priv *priv = dev->priv; + + pch_gbe_reset(dev); + + phy_shutdown(priv->phydev); +} + +static int pch_gbe_send(struct eth_device *dev, void *packet, int length) +{ + struct pch_gbe_priv *priv = dev->priv; + struct pch_gbe_regs *mac_regs = priv->mac_regs; + struct pch_gbe_tx_desc *tx_head, *tx_desc; + u16 frame_ctrl = 0; + u32 int_st; + ulong start; + + tx_head = &priv->tx_desc[0]; + tx_desc = &priv->tx_desc[priv->tx_idx]; + + if (length < 64) + frame_ctrl |= PCH_GBE_TXD_CTRL_APAD; + + tx_desc->buffer_addr = pci_phys_to_mem(priv->bdf, (u32)packet); + tx_desc->length = length; + tx_desc->tx_words_eob = length + 3; + tx_desc->tx_frame_ctrl = frame_ctrl; + tx_desc->dma_status = 0; + tx_desc->gbec_status = 0; + + /* Test the wrap-around condition */ + if (++priv->tx_idx >= PCH_GBE_DESC_NUM) + priv->tx_idx = 0; + + writel(pci_phys_to_mem(priv->bdf, (u32)(tx_head + priv->tx_idx)), + &mac_regs->tx_dsc_sw_p); + + start = get_timer(0); + while (get_timer(start) < PCH_GBE_TIMEOUT) { + int_st = readl(&mac_regs->int_st); + if (int_st & PCH_GBE_INT_TX_CMPLT) + return 0; + + udelay(10); + } + + debug("pch_gbe: sent failed\n"); + return -ETIME; +} + +static int pch_gbe_recv(struct eth_device *dev) +{ + struct pch_gbe_priv *priv = dev->priv; + struct pch_gbe_regs *mac_regs = priv->mac_regs; + struct pch_gbe_rx_desc *rx_head, *rx_desc; + u32 hw_desc, buffer_addr, length; + int rx_swp; + + rx_head = &priv->rx_desc[0]; + rx_desc = &priv->rx_desc[priv->rx_idx]; + + readl(&mac_regs->int_st); + hw_desc = readl(&mac_regs->rx_dsc_hw_p_hld); + + /* Just return if not receiving any packet */ + if ((u32)rx_desc == hw_desc) + return 0; + + buffer_addr = pci_mem_to_phys(priv->bdf, rx_desc->buffer_addr); + length = rx_desc->rx_words_eob - 3 - ETH_FCS_LEN; + NetReceive((uchar *)buffer_addr, length); + + /* Test the wrap-around condition */ + if (++priv->rx_idx >= PCH_GBE_DESC_NUM) + priv->rx_idx = 0; + rx_swp = priv->rx_idx; + if (++rx_swp >= PCH_GBE_DESC_NUM) + rx_swp = 0; + + writel(pci_phys_to_mem(priv->bdf, (u32)(rx_head + rx_swp)), + &mac_regs->rx_dsc_sw_p); + + return length; +} + +static int pch_gbe_mdio_ready(struct pch_gbe_regs *mac_regs) +{ + ulong start = get_timer(0); + + while (get_timer(start) < PCH_GBE_TIMEOUT) { + if (readl(&mac_regs->miim) & PCH_GBE_MIIM_OPER_READY) + return 0; + + udelay(10); + } + + return -ETIME; +} + +static int pch_gbe_mdio_read(struct mii_dev *bus, int addr, int devad, int reg) +{ + struct pch_gbe_regs *mac_regs = bus->priv; + u32 miim; + + if (pch_gbe_mdio_ready(mac_regs)) + return -ETIME; + + miim = (addr << PCH_GBE_MIIM_PHY_ADDR_SHIFT) | + (reg << PCH_GBE_MIIM_REG_ADDR_SHIFT) | + PCH_GBE_MIIM_OPER_READ; + writel(miim, &mac_regs->miim); + + if (pch_gbe_mdio_ready(mac_regs)) + return -ETIME; + + return readl(&mac_regs->miim) & 0xffff; +} + +static int pch_gbe_mdio_write(struct mii_dev *bus, int addr, int devad, + int reg, u16 val) +{ + struct pch_gbe_regs *mac_regs = bus->priv; + u32 miim; + + if (pch_gbe_mdio_ready(mac_regs)) + return -ETIME; + + miim = (addr << PCH_GBE_MIIM_PHY_ADDR_SHIFT) | + (reg << PCH_GBE_MIIM_REG_ADDR_SHIFT) | + PCH_GBE_MIIM_OPER_WRITE | val; + writel(miim, &mac_regs->miim); + + if (pch_gbe_mdio_ready(mac_regs)) + return -ETIME; + else + return 0; +} + +static int pch_gbe_mdio_init(char *name, struct pch_gbe_regs *mac_regs) +{ + struct mii_dev *bus; + + bus = mdio_alloc(); + if (!bus) { + debug("pch_gbe: failed to allocate MDIO bus\n"); + return -ENOMEM; + } + + bus->read = pch_gbe_mdio_read; + bus->write = pch_gbe_mdio_write; + sprintf(bus->name, name); + + bus->priv = (void *)mac_regs; + + return mdio_register(bus); +} + +static int pch_gbe_phy_init(struct eth_device *dev) +{ + struct pch_gbe_priv *priv = dev->priv; + struct phy_device *phydev; + int mask = 0xffffffff; + + phydev = phy_find_by_mask(priv->bus, mask, priv->interface); + if (!phydev) { + printf("pch_gbe: cannot find the phy\n"); + return -1; + } + + phy_connect_dev(phydev, dev); + + phydev->supported &= PHY_GBIT_FEATURES; + phydev->advertising = phydev->supported; + + priv->phydev = phydev; + phy_config(phydev); + + return 1; +} + +int pch_gbe_register(bd_t *bis) +{ + struct eth_device *dev; + struct pch_gbe_priv *priv; + pci_dev_t devno; + u32 iobase; + + devno = pci_find_devices(supported, 0); + if (devno == -1) + return -ENODEV; + + dev = (struct eth_device *)malloc(sizeof(*dev)); + if (!dev) + return -ENOMEM; + memset(dev, 0, sizeof(*dev)); + + /* + * The priv structure contains the descriptors and frame buffers which + * need a strict buswidth alignment (64 bytes) + */ + priv = (struct pch_gbe_priv *)memalign(PCH_GBE_ALIGN_SIZE, + sizeof(*priv)); + if (!priv) { + free(dev); + return -ENOMEM; + } + memset(priv, 0, sizeof(*priv)); + + dev->priv = priv; + priv->dev = dev; + priv->bdf = devno; + + pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase); + iobase &= PCI_BASE_ADDRESS_MEM_MASK; + iobase = pci_mem_to_phys(devno, iobase); + + dev->iobase = iobase; + priv->mac_regs = (struct pch_gbe_regs *)iobase; + + sprintf(dev->name, "pch_gbe.%x", iobase); + + /* Read MAC address from SROM and initialize dev->enetaddr with it */ + pch_gbe_mac_read(priv->mac_regs, dev->enetaddr); + + dev->init = pch_gbe_init; + dev->halt = pch_gbe_halt; + dev->send = pch_gbe_send; + dev->recv = pch_gbe_recv; + + eth_register(dev); + + priv->interface = PHY_INTERFACE_MODE_RGMII; + pch_gbe_mdio_init(dev->name, priv->mac_regs); + priv->bus = miiphy_get_dev_by_name(dev->name); + + return pch_gbe_phy_init(dev); +} diff --git a/drivers/net/pch_gbe.h b/drivers/net/pch_gbe.h new file mode 100644 index 0000000..11329d4 --- /dev/null +++ b/drivers/net/pch_gbe.h @@ -0,0 +1,300 @@ +/* + * Copyright (C) 2015, Bin Meng bmeng.cn@gmail.com + * + * Intel Platform Controller Hub EG20T (codename Topcliff) GMAC Driver + * Adapted from linux drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _PCH_GBE_H_ +#define _PCH_GBE_H_ + +#define PCH_GBE_TIMEOUT (3 * CONFIG_SYS_HZ) + +#define PCH_GBE_DESC_NUM 4 +#define PCH_GBE_ALIGN_SIZE 64 + +/* + * Topcliff GBE MAC supports receiving ethernet frames with normal frame size + * (64-1518 bytes) as well as up to 10318 bytes, however it does not have a + * register bit to turn off receiving 'jumbo frame', so we have to allocate + * our own buffer to store the received frames instead of using U-Boot's own. + */ +#define PCH_GBE_RX_FRAME_LEN ROUND(10318, PCH_GBE_ALIGN_SIZE) + +/* Interrupt Status */ +/* Interrupt Status Hold */ +/* Interrupt Enable */ +#define PCH_GBE_INT_RX_DMA_CMPLT 0x00000001 +#define PCH_GBE_INT_RX_VALID 0x00000002 +#define PCH_GBE_INT_RX_FRAME_ERR 0x00000004 +#define PCH_GBE_INT_RX_FIFO_ERR 0x00000008 +#define PCH_GBE_INT_RX_DMA_ERR 0x00000010 +#define PCH_GBE_INT_RX_DSC_EMP 0x00000020 +#define PCH_GBE_INT_TX_CMPLT 0x00000100 +#define PCH_GBE_INT_TX_DMA_CMPLT 0x00000200 +#define PCH_GBE_INT_TX_FIFO_ERR 0x00000400 +#define PCH_GBE_INT_TX_DMA_ERR 0x00000800 +#define PCH_GBE_INT_PAUSE_CMPLT 0x00001000 +#define PCH_GBE_INT_MIIM_CMPLT 0x00010000 +#define PCH_GBE_INT_PHY_INT 0x00100000 +#define PCH_GBE_INT_WOL_DET 0x01000000 +#define PCH_GBE_INT_TCPIP_ERR 0x10000000 + +/* Mode */ +#define PCH_GBE_MODE_MII_ETHER 0x00000000 +#define PCH_GBE_MODE_GMII_ETHER 0x80000000 +#define PCH_GBE_MODE_HALF_DUPLEX 0x00000000 +#define PCH_GBE_MODE_FULL_DUPLEX 0x40000000 +#define PCH_GBE_MODE_FR_BST 0x04000000 + +/* Reset */ +#define PCH_GBE_ALL_RST 0x80000000 +#define PCH_GBE_TX_RST 0x00008000 +#define PCH_GBE_RX_RST 0x00004000 + +/* TCP/IP Accelerator Control */ +#define PCH_GBE_EX_LIST_EN 0x00000008 +#define PCH_GBE_RX_TCPIPACC_OFF 0x00000004 +#define PCH_GBE_TX_TCPIPACC_EN 0x00000002 +#define PCH_GBE_RX_TCPIPACC_EN 0x00000001 + +/* MAC RX Enable */ +#define PCH_GBE_MRE_MAC_RX_EN 0x00000001 + +/* RX Flow Control */ +#define PCH_GBE_FL_CTRL_EN 0x80000000 + +/* RX Mode */ +#define PCH_GBE_ADD_FIL_EN 0x80000000 +#define PCH_GBE_MLT_FIL_EN 0x40000000 +#define PCH_GBE_RH_ALM_EMP_4 0x00000000 +#define PCH_GBE_RH_ALM_EMP_8 0x00004000 +#define PCH_GBE_RH_ALM_EMP_16 0x00008000 +#define PCH_GBE_RH_ALM_EMP_32 0x0000c000 +#define PCH_GBE_RH_ALM_FULL_4 0x00000000 +#define PCH_GBE_RH_ALM_FULL_8 0x00001000 +#define PCH_GBE_RH_ALM_FULL_16 0x00002000 +#define PCH_GBE_RH_ALM_FULL_32 0x00003000 +#define PCH_GBE_RH_RD_TRG_4 0x00000000 +#define PCH_GBE_RH_RD_TRG_8 0x00000200 +#define PCH_GBE_RH_RD_TRG_16 0x00000400 +#define PCH_GBE_RH_RD_TRG_32 0x00000600 +#define PCH_GBE_RH_RD_TRG_64 0x00000800 +#define PCH_GBE_RH_RD_TRG_128 0x00000a00 +#define PCH_GBE_RH_RD_TRG_256 0x00000c00 +#define PCH_GBE_RH_RD_TRG_512 0x00000e00 + +/* TX Mode */ +#define PCH_GBE_TM_NO_RTRY 0x80000000 +#define PCH_GBE_TM_LONG_PKT 0x40000000 +#define PCH_GBE_TM_ST_AND_FD 0x20000000 +#define PCH_GBE_TM_SHORT_PKT 0x10000000 +#define PCH_GBE_TM_LTCOL_RETX 0x08000000 +#define PCH_GBE_TM_TH_TX_STRT_4 0x00000000 +#define PCH_GBE_TM_TH_TX_STRT_8 0x00004000 +#define PCH_GBE_TM_TH_TX_STRT_16 0x00008000 +#define PCH_GBE_TM_TH_TX_STRT_32 0x0000c000 +#define PCH_GBE_TM_TH_ALM_EMP_4 0x00000000 +#define PCH_GBE_TM_TH_ALM_EMP_8 0x00000800 +#define PCH_GBE_TM_TH_ALM_EMP_16 0x00001000 +#define PCH_GBE_TM_TH_ALM_EMP_32 0x00001800 +#define PCH_GBE_TM_TH_ALM_EMP_64 0x00002000 +#define PCH_GBE_TM_TH_ALM_EMP_128 0x00002800 +#define PCH_GBE_TM_TH_ALM_EMP_256 0x00003000 +#define PCH_GBE_TM_TH_ALM_EMP_512 0x00003800 +#define PCH_GBE_TM_TH_ALM_FULL_4 0x00000000 +#define PCH_GBE_TM_TH_ALM_FULL_8 0x00000200 +#define PCH_GBE_TM_TH_ALM_FULL_16 0x00000400 +#define PCH_GBE_TM_TH_ALM_FULL_32 0x00000600 + +/* MAC Address Mask */ +#define PCH_GBE_BUSY 0x80000000 + +/* MIIM */ +#define PCH_GBE_MIIM_OPER_WRITE 0x04000000 +#define PCH_GBE_MIIM_OPER_READ 0x00000000 +#define PCH_GBE_MIIM_OPER_READY 0x04000000 +#define PCH_GBE_MIIM_PHY_ADDR_SHIFT 21 +#define PCH_GBE_MIIM_REG_ADDR_SHIFT 16 + +/* RGMII Control */ +#define PCH_GBE_CRS_SEL 0x00000010 +#define PCH_GBE_RGMII_RATE_125M 0x00000000 +#define PCH_GBE_RGMII_RATE_25M 0x00000008 +#define PCH_GBE_RGMII_RATE_2_5M 0x0000000c +#define PCH_GBE_RGMII_MODE_GMII 0x00000000 +#define PCH_GBE_RGMII_MODE_RGMII 0x00000002 +#define PCH_GBE_CHIP_TYPE_EXTERNAL 0x00000000 +#define PCH_GBE_CHIP_TYPE_INTERNAL 0x00000001 + +/* DMA Control */ +#define PCH_GBE_RX_DMA_EN 0x00000002 +#define PCH_GBE_TX_DMA_EN 0x00000001 + +/* Receive Descriptor bit definitions */ +#define PCH_GBE_RXD_ACC_STAT_BCAST 0x00000400 +#define PCH_GBE_RXD_ACC_STAT_MCAST 0x00000200 +#define PCH_GBE_RXD_ACC_STAT_UCAST 0x00000100 +#define PCH_GBE_RXD_ACC_STAT_TCPIPOK 0x000000c0 +#define PCH_GBE_RXD_ACC_STAT_IPOK 0x00000080 +#define PCH_GBE_RXD_ACC_STAT_TCPOK 0x00000040 +#define PCH_GBE_RXD_ACC_STAT_IP6ERR 0x00000020 +#define PCH_GBE_RXD_ACC_STAT_OFLIST 0x00000010 +#define PCH_GBE_RXD_ACC_STAT_TYPEIP 0x00000008 +#define PCH_GBE_RXD_ACC_STAT_MACL 0x00000004 +#define PCH_GBE_RXD_ACC_STAT_PPPOE 0x00000002 +#define PCH_GBE_RXD_ACC_STAT_VTAGT 0x00000001 +#define PCH_GBE_RXD_GMAC_STAT_PAUSE 0x0200 +#define PCH_GBE_RXD_GMAC_STAT_MARBR 0x0100 +#define PCH_GBE_RXD_GMAC_STAT_MARMLT 0x0080 +#define PCH_GBE_RXD_GMAC_STAT_MARIND 0x0040 +#define PCH_GBE_RXD_GMAC_STAT_MARNOTMT 0x0020 +#define PCH_GBE_RXD_GMAC_STAT_TLONG 0x0010 +#define PCH_GBE_RXD_GMAC_STAT_TSHRT 0x0008 +#define PCH_GBE_RXD_GMAC_STAT_NOTOCTAL 0x0004 +#define PCH_GBE_RXD_GMAC_STAT_NBLERR 0x0002 +#define PCH_GBE_RXD_GMAC_STAT_CRCERR 0x0001 + +/* Transmit Descriptor bit definitions */ +#define PCH_GBE_TXD_CTRL_TCPIP_ACC_OFF 0x0008 +#define PCH_GBE_TXD_CTRL_ITAG 0x0004 +#define PCH_GBE_TXD_CTRL_ICRC 0x0002 +#define PCH_GBE_TXD_CTRL_APAD 0x0001 +#define PCH_GBE_TXD_WORDS_SHIFT 2 +#define PCH_GBE_TXD_GMAC_STAT_CMPLT 0x2000 +#define PCH_GBE_TXD_GMAC_STAT_ABT 0x1000 +#define PCH_GBE_TXD_GMAC_STAT_EXCOL 0x0800 +#define PCH_GBE_TXD_GMAC_STAT_SNGCOL 0x0400 +#define PCH_GBE_TXD_GMAC_STAT_MLTCOL 0x0200 +#define PCH_GBE_TXD_GMAC_STAT_CRSER 0x0100 +#define PCH_GBE_TXD_GMAC_STAT_TLNG 0x0080 +#define PCH_GBE_TXD_GMAC_STAT_TSHRT 0x0040 +#define PCH_GBE_TXD_GMAC_STAT_LTCOL 0x0020 +#define PCH_GBE_TXD_GMAC_STAT_TFUNDFLW 0x0010 + +/** + * struct pch_gbe_rx_desc - Receive Descriptor + * @buffer_addr: RX Frame Buffer Address + * @tcp_ip_status: TCP/IP Accelerator Status + * @rx_words_eob: RX word count and Byte position + * @gbec_status: GMAC Status + * @dma_status: DMA Status + * @reserved1: Reserved + * @reserved2: Reserved + */ +struct pch_gbe_rx_desc { + u32 buffer_addr; + u32 tcp_ip_status; + u16 rx_words_eob; + u16 gbec_status; + u8 dma_status; + u8 reserved1; + u16 reserved2; +}; + +/** + * struct pch_gbe_tx_desc - Transmit Descriptor + * @buffer_addr: TX Frame Buffer Address + * @length: Data buffer length + * @reserved1: Reserved + * @tx_words_eob: TX word count and Byte position + * @tx_frame_ctrl: TX Frame Control + * @dma_status: DMA Status + * @reserved2: Reserved + * @gbec_status: GMAC Status + */ +struct pch_gbe_tx_desc { + u32 buffer_addr; + u16 length; + u16 reserved1; + u16 tx_words_eob; + u16 tx_frame_ctrl; + u8 dma_status; + u8 reserved2; + u16 gbec_status; +}; + +/** + * pch_gbe_regs_mac_adr - structure holding values of mac address registers + * + * @high Denotes the 1st to 4th byte from the initial of MAC address + * @low Denotes the 5th to 6th byte from the initial of MAC address + */ +struct pch_gbe_regs_mac_adr { + u32 high; + u32 low; +}; + +/** + * pch_gbe_regs - structure holding values of MAC registers + */ +struct pch_gbe_regs { + u32 int_st; + u32 int_en; + u32 mode; + u32 reset; + u32 tcpip_acc; + u32 ex_list; + u32 int_st_hold; + u32 phy_int_ctrl; + u32 mac_rx_en; + u32 rx_fctrl; + u32 pause_req; + u32 rx_mode; + u32 tx_mode; + u32 rx_fifo_st; + u32 tx_fifo_st; + u32 tx_fid; + u32 tx_result; + u32 pause_pkt1; + u32 pause_pkt2; + u32 pause_pkt3; + u32 pause_pkt4; + u32 pause_pkt5; + u32 reserve[2]; + struct pch_gbe_regs_mac_adr mac_adr[16]; + u32 addr_mask; + u32 miim; + u32 mac_addr_load; + u32 rgmii_st; + u32 rgmii_ctrl; + u32 reserve3[3]; + u32 dma_ctrl; + u32 reserve4[3]; + u32 rx_dsc_base; + u32 rx_dsc_size; + u32 rx_dsc_hw_p; + u32 rx_dsc_hw_p_hld; + u32 rx_dsc_sw_p; + u32 reserve5[3]; + u32 tx_dsc_base; + u32 tx_dsc_size; + u32 tx_dsc_hw_p; + u32 tx_dsc_hw_p_hld; + u32 tx_dsc_sw_p; + u32 reserve6[3]; + u32 rx_dma_st; + u32 tx_dma_st; + u32 reserve7[2]; + u32 wol_st; + u32 wol_ctrl; + u32 wol_addr_mask; +}; + +struct pch_gbe_priv { + struct pch_gbe_rx_desc rx_desc[PCH_GBE_DESC_NUM]; + struct pch_gbe_tx_desc tx_desc[PCH_GBE_DESC_NUM]; + char rx_buff[PCH_GBE_DESC_NUM][PCH_GBE_RX_FRAME_LEN]; + struct eth_device *dev; + struct phy_device *phydev; + struct mii_dev *bus; + struct pch_gbe_regs *mac_regs; + pci_dev_t bdf; + u32 interface; + int rx_idx; + int tx_idx; +}; + +#endif /* _PCH_GBE_H_ */ diff --git a/include/netdev.h b/include/netdev.h index daffc12..4cbf055 100644 --- a/include/netdev.h +++ b/include/netdev.h @@ -70,6 +70,7 @@ int natsemi_initialize(bd_t *bis); int ne2k_register(void); int npe_initialize(bd_t *bis); int ns8382x_initialize(bd_t *bis); +int pch_gbe_register(bd_t *bis); int pcnet_initialize(bd_t *bis); int ppc_4xx_eth_initialize (bd_t *bis); int rtl8139_initialize(bd_t *bis); @@ -124,6 +125,9 @@ static inline int pci_eth_init(bd_t *bis) #ifdef CONFIG_E1000 num += e1000_initialize(bis); #endif +#ifdef CONFIG_PCH_GBE + num += pch_gbe_register(bis); +#endif #ifdef CONFIG_PCNET num += pcnet_initialize(bis); #endif

On Fri, Mar 20, 2015 at 4:12 AM, Bin Meng bmeng.cn@gmail.com wrote:
Add a new driver for the Gigabit Ethernet MAC found on Intel Topcliff Platform Controller Hub. Tested under 10/100 half/full duplex and 1000 full duplex modes using ping and tftpboot commands.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Acked-by: Joe Hershberger joe.hershberger@ni.com

Hi Bin,
On 20 March 2015 at 13:18, Joe Hershberger joe.hershberger@gmail.com wrote:
On Fri, Mar 20, 2015 at 4:12 AM, Bin Meng bmeng.cn@gmail.com wrote:
Add a new driver for the Gigabit Ethernet MAC found on Intel Topcliff Platform Controller Hub. Tested under 10/100 half/full duplex and 1000 full duplex modes using ping and tftpboot commands.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Acked-by: Joe Hershberger joe.hershberger@ni.com
Do you think this could be converted to driver model?
E.g., see this:
http://patchwork.ozlabs.org/patch/444846/
Regards, Simon

Hi Simon,
On Tue, Mar 24, 2015 at 5:57 AM, Simon Glass sjg@chromium.org wrote:
Hi Bin,
On 20 March 2015 at 13:18, Joe Hershberger joe.hershberger@gmail.com wrote:
On Fri, Mar 20, 2015 at 4:12 AM, Bin Meng bmeng.cn@gmail.com wrote:
Add a new driver for the Gigabit Ethernet MAC found on Intel Topcliff Platform Controller Hub. Tested under 10/100 half/full duplex and 1000 full duplex modes using ping and tftpboot commands.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Acked-by: Joe Hershberger joe.hershberger@ni.com
Do you think this could be converted to driver model?
E.g., see this:
Yes, I plan to do the conversion in the future as a separate patch. If possible to catch up the train for the v2015.04 release, are you going to apply this series now?
Regards, Bin

Hi Bin,
On Mar 23, 2015 7:24 PM, "Bin Meng" bmeng.cn@gmail.com wrote:
Hi Simon,
On Tue, Mar 24, 2015 at 5:57 AM, Simon Glass sjg@chromium.org wrote:
Hi Bin,
On 20 March 2015 at 13:18, Joe Hershberger joe.hershberger@gmail.com
wrote:
On Fri, Mar 20, 2015 at 4:12 AM, Bin Meng bmeng.cn@gmail.com wrote:
Add a new driver for the Gigabit Ethernet MAC found on Intel Topcliff Platform Controller Hub. Tested under 10/100 half/full duplex and 1000 full duplex modes using ping and tftpboot commands.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Acked-by: Joe Hershberger joe.hershberger@ni.com
Do you think this could be converted to driver model?
E.g., see this:
Yes, I plan to do the conversion in the future as a separate patch. If possible to catch up the train for the v2015.04 release, are you going to apply this series now?
I was planning to do this later. Do you want it in this release? I suppose that would be ok because it is a new board.
Regards, Simon

Hi Simon,
On Tue, Mar 24, 2015 at 12:18 PM, Simon Glass sjg@chromium.org wrote:
Hi Bin,
On Mar 23, 2015 7:24 PM, "Bin Meng" bmeng.cn@gmail.com wrote:
Hi Simon,
On Tue, Mar 24, 2015 at 5:57 AM, Simon Glass sjg@chromium.org wrote:
Hi Bin,
On 20 March 2015 at 13:18, Joe Hershberger joe.hershberger@gmail.com wrote:
On Fri, Mar 20, 2015 at 4:12 AM, Bin Meng bmeng.cn@gmail.com wrote:
Add a new driver for the Gigabit Ethernet MAC found on Intel Topcliff Platform Controller Hub. Tested under 10/100 half/full duplex and 1000 full duplex modes using ping and tftpboot commands.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Acked-by: Joe Hershberger joe.hershberger@ni.com
Do you think this could be converted to driver model?
E.g., see this:
Yes, I plan to do the conversion in the future as a separate patch. If possible to catch up the train for the v2015.04 release, are you going to apply this series now?
I was planning to do this later. Do you want it in this release? I suppose that would be ok because it is a new board.
Yep, given the series look OK and no rework will be needed, I would like to add it to this release if time permits. And maybe along with my other patches before (quark)?
Regards, Bin

On 23 March 2015 at 22:54, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Tue, Mar 24, 2015 at 12:18 PM, Simon Glass sjg@chromium.org wrote:
Hi Bin,
On Mar 23, 2015 7:24 PM, "Bin Meng" bmeng.cn@gmail.com wrote:
Hi Simon,
On Tue, Mar 24, 2015 at 5:57 AM, Simon Glass sjg@chromium.org wrote:
Hi Bin,
On 20 March 2015 at 13:18, Joe Hershberger joe.hershberger@gmail.com wrote:
On Fri, Mar 20, 2015 at 4:12 AM, Bin Meng bmeng.cn@gmail.com wrote:
Add a new driver for the Gigabit Ethernet MAC found on Intel Topcliff Platform Controller Hub. Tested under 10/100 half/full duplex and 1000 full duplex modes using ping and tftpboot commands.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Acked-by: Joe Hershberger joe.hershberger@ni.com
Do you think this could be converted to driver model?
E.g., see this:
Yes, I plan to do the conversion in the future as a separate patch. If possible to catch up the train for the v2015.04 release, are you going to apply this series now?
I was planning to do this later. Do you want it in this release? I suppose that would be ok because it is a new board.
Yep, given the series look OK and no rework will be needed, I would like to add it to this release if time permits. And maybe along with my other patches before (quark)?
Regards, Bin
Applied to u-boot-x86, thanks!

Intel Crown Bay board has one ethernet port connected from Intel Topcliff PCH. Enable it in the board configuration.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
---
include/configs/crownbay.h | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/include/configs/crownbay.h b/include/configs/crownbay.h index 4a74f82..df32f2a 100644 --- a/include/configs/crownbay.h +++ b/include/configs/crownbay.h @@ -52,6 +52,10 @@ #define CONFIG_MMC_SDMA #define CONFIG_CMD_MMC
+/* Topcliff Gigabit Ethernet */ +#define CONFIG_PCH_GBE +#define CONFIG_PHYLIB + /* Video is not supported */ #undef CONFIG_VIDEO #undef CONFIG_CFB_CONSOLE

On Fri, Mar 20, 2015 at 4:12 AM, Bin Meng bmeng.cn@gmail.com wrote:
Intel Crown Bay board has one ethernet port connected from Intel Topcliff PCH. Enable it in the board configuration.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Reviewed-by: Joe Hershberger joe.hershberger@ni.com

On 20 March 2015 at 13:18, Joe Hershberger joe.hershberger@gmail.com wrote:
On Fri, Mar 20, 2015 at 4:12 AM, Bin Meng bmeng.cn@gmail.com wrote:
Intel Crown Bay board has one ethernet port connected from Intel Topcliff PCH. Enable it in the board configuration.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Reviewed-by: Joe Hershberger joe.hershberger@ni.com
Applied to u-boot-x86, thanks!

Hi Simon,
On Fri, Mar 20, 2015 at 4:12 AM, Bin Meng bmeng.cn@gmail.com wrote:
This series adds a new ethernet driver for the GMAC found on Intel
Topcliff
Platform Controller Hub and enable its support on Intel Crown Bay board.
The series also did some clean up work below:
- Introduce ETH_FCS_LEN macro as it is often used by some ethernet drivers
- Remove any local version of ETH_FCS_LEN from various places
- Update README.drivers.eth for up-to-date mdio APIs
Bin Meng (4): net: Add ethernet FCS length macro in net.h net: Update README.drivers.eth to mention latest APIs net: Add Intel Topcliff GMAC driver x86: crownbay: Enable Intel Topcliff GMAC support
I assume it is preferable to pull this through the x86 tree. Let me know either way.
-Joe

Hi Joe,
On 20 March 2015 at 13:18, Joe Hershberger joe.hershberger@gmail.com wrote:
Hi Simon,
On Fri, Mar 20, 2015 at 4:12 AM, Bin Meng bmeng.cn@gmail.com wrote:
This series adds a new ethernet driver for the GMAC found on Intel Topcliff Platform Controller Hub and enable its support on Intel Crown Bay board.
The series also did some clean up work below:
- Introduce ETH_FCS_LEN macro as it is often used by some ethernet drivers
- Remove any local version of ETH_FCS_LEN from various places
- Update README.drivers.eth for up-to-date mdio APIs
Bin Meng (4): net: Add ethernet FCS length macro in net.h net: Update README.drivers.eth to mention latest APIs net: Add Intel Topcliff GMAC driver x86: crownbay: Enable Intel Topcliff GMAC support
I assume it is preferable to pull this through the x86 tree. Let me know either way.
Yes, will do. But I suspect it should be converted to driver model. Let's see.
Regards, Simon
participants (3)
-
Bin Meng
-
Joe Hershberger
-
Simon Glass