From 4bf56913d0d3bf1e1dd9ccd54f582c034314b812 Mon Sep 17 00:00:00 2001 From: Wilson Lee Date: Tue, 22 Aug 2017 20:25:07 -0700 Subject: [PATCH 01/21] net: macb: Add support for Xilinx Zynq SoC Although Xilinx Zynq SoC was using MACB similar hardware. However, U-boot MACB driver was not supporting Xilinx Zynq SoC. This patch is to add support for the Xilinx Zynq SoC to the existing MACB network driver. This patch is to add Zynq GEM DMA Config, provide callback function for different linkspeed for case of using Xilinx Zynq Programmable Logic as GMII to RGMII converter. This patch convert the return value to use error codes. Signed-off-by: Wilson Lee Cc: Chen Yee Chew Cc: Keng Soon Cheah Cc: Joe Hershberger Cc: Wenyou Yang Acked-by: Joe Hershberger --- drivers/net/Kconfig | 7 ++++ drivers/net/macb.c | 91 +++++++++++++++++++++++++++++++++++++++------ drivers/net/macb.h | 1 + 3 files changed, 87 insertions(+), 12 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 46b17b17ad..c47d59c249 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -185,6 +185,13 @@ config MACB GEM (Gigabit Ethernet MAC) found in some ARM SoC devices. Say Y to include support for the MACB/GEM chip. +config MACB_ZYNQ + bool "Cadence MACB/GEM Ethernet Interface for Xilinx Zynq" + depends on MACB + help + The Cadence MACB ethernet interface was used on Zynq platform. + Say Y to enable support for the MACB/GEM in Zynq chip. + config PCH_GBE bool "Intel Platform Controller Hub EG20T GMAC driver" depends on DM_ETH && DM_PCI diff --git a/drivers/net/macb.c b/drivers/net/macb.c index f9373db0b9..e62aefcd0d 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -52,6 +52,22 @@ DECLARE_GLOBAL_DATA_PTR; #define MACB_TX_TIMEOUT 1000 #define MACB_AUTONEG_TIMEOUT 5000000 +#ifdef CONFIG_MACB_ZYNQ +/* INCR4 AHB bursts */ +#define MACB_ZYNQ_GEM_DMACR_BLENGTH 0x00000004 +/* Use full configured addressable space (8 Kb) */ +#define MACB_ZYNQ_GEM_DMACR_RXSIZE 0x00000300 +/* Use full configured addressable space (4 Kb) */ +#define MACB_ZYNQ_GEM_DMACR_TXSIZE 0x00000400 +/* Set RXBUF with use of 128 byte */ +#define MACB_ZYNQ_GEM_DMACR_RXBUF 0x00020000 +#define MACB_ZYNQ_GEM_DMACR_INIT \ + (MACB_ZYNQ_GEM_DMACR_BLENGTH | \ + MACB_ZYNQ_GEM_DMACR_RXSIZE | \ + MACB_ZYNQ_GEM_DMACR_TXSIZE | \ + MACB_ZYNQ_GEM_DMACR_RXBUF) +#endif + struct macb_dma_desc { u32 addr; u32 ctrl; @@ -461,13 +477,25 @@ static int macb_phy_find(struct macb_device *macb, const char *name) phy_id = macb_mdio_read(macb, MII_PHYSID1); if (phy_id != 0xffff) { printf("%s: PHY present at %d\n", name, i); - return 1; + return 0; } } /* PHY isn't up to snuff */ printf("%s: PHY not found\n", name); + return -ENODEV; +} + +/** + * macb_linkspd_cb - Linkspeed change callback function + * @regs: Base Register of MACB devices + * @speed: Linkspeed + * Returns 0 when operation success and negative errno number + * when operation failed. + */ +int __weak macb_linkspd_cb(void *regs, unsigned int speed) +{ return 0; } @@ -483,18 +511,20 @@ static int macb_phy_init(struct macb_device *macb, const char *name) u32 ncfgr; u16 phy_id, status, adv, lpa; int media, speed, duplex; + int ret; int i; arch_get_mdio_control(name); /* Auto-detect phy_addr */ - if (!macb_phy_find(macb, name)) - return 0; + ret = macb_phy_find(macb, name); + if (ret) + return ret; /* Check if the PHY is up to snuff... */ phy_id = macb_mdio_read(macb, MII_PHYSID1); if (phy_id == 0xffff) { printf("%s: No PHY present\n", name); - return 0; + return -ENODEV; } #ifdef CONFIG_PHYLIB @@ -530,7 +560,7 @@ static int macb_phy_init(struct macb_device *macb, const char *name) if (!(status & BMSR_LSTATUS)) { printf("%s: link down (status: 0x%04x)\n", name, status); - return 0; + return -ENETDOWN; } /* First check for GMAC and that it is GiB capable */ @@ -554,7 +584,11 @@ static int macb_phy_init(struct macb_device *macb, const char *name) macb_writel(macb, NCFGR, ncfgr); - return 1; + ret = macb_linkspd_cb(macb->regs, _1000BASET); + if (ret) + return ret; + + return 0; } } @@ -573,13 +607,21 @@ static int macb_phy_init(struct macb_device *macb, const char *name) ncfgr = macb_readl(macb, NCFGR); ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD) | GEM_BIT(GBE)); - if (speed) + if (speed) { ncfgr |= MACB_BIT(SPD); + ret = macb_linkspd_cb(macb->regs, _100BASET); + } else { + ret = macb_linkspd_cb(macb->regs, _10BASET); + } + + if (ret) + return ret; + if (duplex) ncfgr |= MACB_BIT(FD); macb_writel(macb, NCFGR, ncfgr); - return 1; + return 0; } static int gmac_init_multi_queues(struct macb_device *macb) @@ -616,6 +658,7 @@ static int _macb_init(struct macb_device *macb, const char *name) struct macb_device *macb = dev_get_priv(dev); #endif unsigned long paddr; + int ret; int i; /* @@ -649,6 +692,10 @@ static int _macb_init(struct macb_device *macb, const char *name) macb->tx_tail = 0; macb->next_rx_tail = 0; +#ifdef CONFIG_MACB_ZYNQ + macb_writel(macb, DMACFG, MACB_ZYNQ_GEM_DMACR_INIT); +#endif + macb_writel(macb, RBQP, macb->rx_ring_dma); macb_writel(macb, TBQP, macb->tx_ring_dma); @@ -709,11 +756,12 @@ static int _macb_init(struct macb_device *macb, const char *name) } #ifdef CONFIG_DM_ETH - if (!macb_phy_init(dev, name)) + ret = macb_phy_init(dev, name); #else - if (!macb_phy_init(macb, name)) + ret = macb_phy_init(macb, name); #endif - return -1; + if (ret) + return ret; /* Enable TX and RX */ macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE)); @@ -1013,9 +1061,15 @@ static int macb_enable_clk(struct udevice *dev) if (ret) return -EINVAL; + /* + * Zynq clock driver didn't support for enable or disable + * clock. Hence, clk_enable() didn't apply for Zynq + */ +#ifndef CONFIG_MACB_ZYNQ ret = clk_enable(&clk); if (ret) return ret; +#endif clk_rate = clk_get_rate(&clk); if (!clk_rate) @@ -1083,12 +1137,24 @@ static int macb_eth_remove(struct udevice *dev) return 0; } +/** + * macb_late_eth_ofdata_to_platdata + * @dev: udevice struct + * Returns 0 when operation success and negative errno number + * when operation failed. + */ +int __weak macb_late_eth_ofdata_to_platdata(struct udevice *dev) +{ + return 0; +} + static int macb_eth_ofdata_to_platdata(struct udevice *dev) { struct eth_pdata *pdata = dev_get_platdata(dev); pdata->iobase = devfdt_get_addr(dev); - return 0; + + return macb_late_eth_ofdata_to_platdata(dev); } static const struct udevice_id macb_eth_ids[] = { @@ -1097,6 +1163,7 @@ static const struct udevice_id macb_eth_ids[] = { { .compatible = "atmel,sama5d2-gem" }, { .compatible = "atmel,sama5d3-gem" }, { .compatible = "atmel,sama5d4-gem" }, + { .compatible = "cdns,zynq-gem" }, { } }; diff --git a/drivers/net/macb.h b/drivers/net/macb.h index 5bb48f449c..c39554df5f 100644 --- a/drivers/net/macb.h +++ b/drivers/net/macb.h @@ -11,6 +11,7 @@ #define MACB_NCFGR 0x0004 #define MACB_NSR 0x0008 #define GEM_UR 0x000c +#define MACB_DMACFG 0x0010 #define MACB_TSR 0x0014 #define MACB_RBQP 0x0018 #define MACB_TBQP 0x001c From 3cacc6a7722f4ba397ddbac991f6aa19645cc887 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Wed, 30 Aug 2017 17:32:31 -0500 Subject: [PATCH 02/21] net: Fix buffer overrun error in netconsole Need to not access the byte after the input_buffer. Reported-by: Coverity (CID: 144423) Signed-off-by: Joe Hershberger --- drivers/net/netconsole.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index e9dbedf326..028fca9663 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -153,14 +153,17 @@ int nc_input_packet(uchar *pkt, struct in_addr src_ip, unsigned dest_port, len = sizeof(input_buffer) - input_size; end = input_offset + input_size; - if (end > sizeof(input_buffer)) + if (end >= sizeof(input_buffer)) end -= sizeof(input_buffer); chunk = len; - if (end + len > sizeof(input_buffer)) { + /* Check if packet will wrap in input_buffer */ + if (end + len >= sizeof(input_buffer)) { chunk = sizeof(input_buffer) - end; + /* Copy the second part of the pkt to start of input_buffer */ memcpy(input_buffer, pkt + chunk, len - chunk); } + /* Copy first (or only) part of pkt after end of current valid input*/ memcpy(input_buffer + end, pkt, chunk); input_size += len; From 765a159cf5efe8b0b4f9f8ae415697c5fcbc82ef Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Wed, 30 Aug 2017 17:38:42 -0500 Subject: [PATCH 03/21] net: Remove nfs.h include from bootp.c Nothing from this header is used there, so remove it. Signed-off-by: Joe Hershberger --- net/bootp.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/bootp.c b/net/bootp.c index 73370a13fe..59bb2099f1 100644 --- a/net/bootp.c +++ b/net/bootp.c @@ -14,7 +14,6 @@ #include #include #include "bootp.h" -#include "nfs.h" #ifdef CONFIG_LED_STATUS #include #endif From ce27eb9b40594857a60cbff4763bc6a12e1118d3 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Mon, 30 Oct 2017 22:57:53 +0100 Subject: [PATCH 04/21] net: phy: marvell: Add functions to read PHY's extended registers This commit allows extended Marvell registers to be read with: foo > mdio rx FEC 3.10 Reading from bus FEC PHY at address 0: 3.16 - 0x1063 foo > mdio wx FEC 3.10 0x1011 The above code changes the way ETH connector LEDs blink. Signed-off-by: Lukasz Majewski Reviewed-by: York Sun Acked-by: Joe Hershberger --- drivers/net/phy/marvell.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index b7f300e40f..0b9a9fce8a 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -104,6 +104,31 @@ #define MIIM_88E151x_MODE_SGMII 1 #define MIIM_88E151x_RESET_OFFS 15 +static int m88e1xxx_phy_extread(struct phy_device *phydev, int addr, + int devaddr, int regnum) +{ + int oldpage = phy_read(phydev, MDIO_DEVAD_NONE, MII_MARVELL_PHY_PAGE); + int val; + + phy_write(phydev, MDIO_DEVAD_NONE, MII_MARVELL_PHY_PAGE, devaddr); + val = phy_read(phydev, MDIO_DEVAD_NONE, regnum); + phy_write(phydev, MDIO_DEVAD_NONE, MII_MARVELL_PHY_PAGE, oldpage); + + return val; +} + +static int m88e1xxx_phy_extwrite(struct phy_device *phydev, int addr, + int devaddr, int regnum, u16 val) +{ + int oldpage = phy_read(phydev, MDIO_DEVAD_NONE, MII_MARVELL_PHY_PAGE); + + phy_write(phydev, MDIO_DEVAD_NONE, MII_MARVELL_PHY_PAGE, devaddr); + phy_write(phydev, MDIO_DEVAD_NONE, regnum, val); + phy_write(phydev, MDIO_DEVAD_NONE, MII_MARVELL_PHY_PAGE, oldpage); + + return 0; +} + /* Marvell 88E1011S */ static int m88e1011s_config(struct phy_device *phydev) { @@ -669,6 +694,8 @@ static struct phy_driver M88E1510_driver = { .config = &m88e1510_config, .startup = &m88e1011s_startup, .shutdown = &genphy_shutdown, + .readext = &m88e1xxx_phy_extread, + .writeext = &m88e1xxx_phy_extwrite, }; /* @@ -684,6 +711,8 @@ static struct phy_driver M88E1518_driver = { .config = &m88e1518_config, .startup = &m88e1011s_startup, .shutdown = &genphy_shutdown, + .readext = &m88e1xxx_phy_extread, + .writeext = &m88e1xxx_phy_extwrite, }; static struct phy_driver M88E1310_driver = { From 5ad565b0d1c10d6bdbf40c0264573e2044ab80fc Mon Sep 17 00:00:00 2001 From: Chris Brandt Date: Fri, 3 Nov 2017 08:30:11 -0500 Subject: [PATCH 05/21] net: sh-eth: fix inl and outl definitions The macros inl and outl maybe already be defined from file arch/arm/include/asm/io.h so there may be no reason to define them. And if you do try defined them here, you get a redefined complier warning. Signed-off-by: Chris Brandt Acked-by: Nobuhiro Iwamatsu Acked-by: Joe Hershberger --- drivers/net/sh_eth.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h index 3645f0eca7..2345c34368 100644 --- a/drivers/net/sh_eth.h +++ b/drivers/net/sh_eth.h @@ -25,8 +25,10 @@ #define ADDR_TO_PHY(addr) ((int)(addr) & ~0xe0000000) #endif #elif defined(CONFIG_ARM) -#define inl readl +#ifndef inl +#define inl readl #define outl writel +#endif #define ADDR_TO_PHY(addr) ((int)(addr)) #define ADDR_TO_P2(addr) (addr) #endif /* defined(CONFIG_SH) */ From f6ac626c8a54fc4062e4be68274dda187e103245 Mon Sep 17 00:00:00 2001 From: Chris Brandt Date: Fri, 3 Nov 2017 08:30:12 -0500 Subject: [PATCH 06/21] net: sh-eth: remove sh_eth_offset_rz table First, this table could never be included in the build anyway because SH_ETH_TYPE_RZ is not defined until later in the file. Second, the register PIR was missing, so PHY MDIO never worked. Third, after adding the PIR register, the table is EXACTLY the same as sh_eth_offset_gigabit, so there is no value to it. Therefore, just delete it use the gigabit one. Signed-off-by: Chris Brandt Acked-by: Nobuhiro Iwamatsu Acked-by: Joe Hershberger --- drivers/net/sh_eth.h | 59 +------------------------------------------- 1 file changed, 1 insertion(+), 58 deletions(-) diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h index 2345c34368..a8339ebf33 100644 --- a/drivers/net/sh_eth.h +++ b/drivers/net/sh_eth.h @@ -228,61 +228,6 @@ static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = { [RMII_MII] = 0x0790, }; -#if defined(SH_ETH_TYPE_RZ) -static const u16 sh_eth_offset_rz[SH_ETH_MAX_REGISTER_OFFSET] = { - [EDSR] = 0x0000, - [EDMR] = 0x0400, - [EDTRR] = 0x0408, - [EDRRR] = 0x0410, - [EESR] = 0x0428, - [EESIPR] = 0x0430, - [TDLAR] = 0x0010, - [TDFAR] = 0x0014, - [TDFXR] = 0x0018, - [TDFFR] = 0x001c, - [RDLAR] = 0x0030, - [RDFAR] = 0x0034, - [RDFXR] = 0x0038, - [RDFFR] = 0x003c, - [TRSCER] = 0x0438, - [RMFCR] = 0x0440, - [TFTR] = 0x0448, - [FDR] = 0x0450, - [RMCR] = 0x0458, - [RPADIR] = 0x0460, - [FCFTR] = 0x0468, - [CSMR] = 0x04E4, - - [ECMR] = 0x0500, - [ECSR] = 0x0510, - [ECSIPR] = 0x0518, - [PSR] = 0x0528, - [PIPR] = 0x052c, - [RFLR] = 0x0508, - [APR] = 0x0554, - [MPR] = 0x0558, - [PFTCR] = 0x055c, - [PFRCR] = 0x0560, - [TPAUSER] = 0x0564, - [GECMR] = 0x05b0, - [BCULR] = 0x05b4, - [MAHR] = 0x05c0, - [MALR] = 0x05c8, - [TROCR] = 0x0700, - [CDCR] = 0x0708, - [LCCR] = 0x0710, - [CEFCR] = 0x0740, - [FRECR] = 0x0748, - [TSFRCR] = 0x0750, - [TLFRCR] = 0x0758, - [RFCR] = 0x0760, - [CERCR] = 0x0768, - [CEECR] = 0x0770, - [MAFCR] = 0x0778, - [RMII_MII] = 0x0790, -}; -#endif - static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = { [ECMR] = 0x0100, [RFLR] = 0x0108, @@ -659,12 +604,10 @@ enum FIFO_SIZE_BIT { static inline unsigned long sh_eth_reg_addr(struct sh_eth_dev *eth, int enum_index) { -#if defined(SH_ETH_TYPE_GETHER) +#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ) const u16 *reg_offset = sh_eth_offset_gigabit; #elif defined(SH_ETH_TYPE_ETHER) const u16 *reg_offset = sh_eth_offset_fast_sh4; -#elif defined(SH_ETH_TYPE_RZ) - const u16 *reg_offset = sh_eth_offset_rz; #else #error #endif From 33bab1045773dea9f1bac24569a7f4e29072fd20 Mon Sep 17 00:00:00 2001 From: Chris Brandt Date: Fri, 3 Nov 2017 08:30:13 -0500 Subject: [PATCH 07/21] net: miiphybb: fix casting error Since the return value is a signed int, if the leading MSB of rdreg is a 1, it will get signed extended and will return a negative value which is an error even though we read the correct value. Fixes: dfcc496ed7e2 ("net: mii: Changes not made by spatch") Signed-off-by: Chris Brandt Acked-by: Nobuhiro Iwamatsu Acked-by: Joe Hershberger --- drivers/net/phy/miiphybb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/phy/miiphybb.c b/drivers/net/phy/miiphybb.c index af676b9bae..d61722490e 100644 --- a/drivers/net/phy/miiphybb.c +++ b/drivers/net/phy/miiphybb.c @@ -232,7 +232,7 @@ static void miiphy_pre(struct bb_miiphy_bus *bus, char read, */ int bb_miiphy_read(struct mii_dev *miidev, int addr, int devad, int reg) { - short rdreg; /* register working value */ + unsigned short rdreg; /* register working value */ int v; int j; /* counter */ struct bb_miiphy_bus *bus; From 32ac8b0bba72684281a079a8e23832efabd97e09 Mon Sep 17 00:00:00 2001 From: Jason Brown Date: Tue, 28 Nov 2017 11:12:43 -0800 Subject: [PATCH 08/21] net: mvneta - Fixed recv() when multiple packets have arrived. This patch fixes a problem in the mvneta driver where if more than one packet arrives between calls to mvneta_recv(), the additional descriptors will be marked as free even though only one descriptor has been read and processed from the receive queue. This causes the additional packet(s) to be delayed until the next packet arrives. >From this point on all packets will be delayed because the receive queue will contain unprocessed packets but the hardware shows no busy descriptors. Signed-off-by: Jason Brown Reviewed-by: Stefan Roese Acked-by: Joe Hershberger --- drivers/net/mvneta.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/mvneta.c b/drivers/net/mvneta.c index f1be9521a9..83e3153768 100644 --- a/drivers/net/mvneta.c +++ b/drivers/net/mvneta.c @@ -1654,7 +1654,11 @@ static int mvneta_recv(struct udevice *dev, int flags, uchar **packetp) */ *packetp = data; - mvneta_rxq_desc_num_update(pp, rxq, rx_done, rx_done); + /* + * Only mark one descriptor as free + * since only one was processed + */ + mvneta_rxq_desc_num_update(pp, rxq, 1, 1); } return rx_bytes; From ea8cd652a791db47bf7b77a6af2a63fe35954ea2 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Wed, 29 Nov 2017 09:06:10 +0100 Subject: [PATCH 09/21] dm: core: add missing dev_count_phandle_with_args() Add missing dev_count_phandle_with_args() to avoid compilation issue. Signed-off-by: Patrice Chotard Reviewed-by: Joe Hershberger --- drivers/core/read.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/core/read.c b/drivers/core/read.c index 5d440cee72..f346cc1eb6 100644 --- a/drivers/core/read.c +++ b/drivers/core/read.c @@ -103,6 +103,13 @@ int dev_read_phandle_with_args(struct udevice *dev, const char *list_name, out_args); } +int dev_count_phandle_with_args(struct udevice *dev, const char *list_name, + const char *cells_name) +{ + return ofnode_count_phandle_with_args(dev_ofnode(dev), list_name, + cells_name); +} + int dev_read_addr_cells(struct udevice *dev) { return ofnode_read_addr_cells(dev_ofnode(dev)); From ba1f966725223c605ed504b09446c52a3f201c2b Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Wed, 29 Nov 2017 09:06:11 +0100 Subject: [PATCH 10/21] net: designware: add clock support This implementation manages several clocks, disable and free all of them in case of error during probe and in remove callback. Signed-off-by: Patrice Chotard Reviewed-by: Simon Glass Acked-by: Joe Hershberger --- drivers/net/designware.c | 43 ++++++++++++++++++++++++++++++++++++++++ drivers/net/designware.h | 4 ++++ 2 files changed, 47 insertions(+) diff --git a/drivers/net/designware.c b/drivers/net/designware.c index 036d231071..9207324731 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include @@ -661,6 +662,35 @@ int designware_eth_probe(struct udevice *dev) u32 iobase = pdata->iobase; ulong ioaddr; int ret; +#ifdef CONFIG_CLK + int i, err, clock_nb; + + priv->clock_count = 0; + clock_nb = dev_count_phandle_with_args(dev, "clocks", "#clock-cells"); + if (clock_nb > 0) { + priv->clocks = devm_kcalloc(dev, clock_nb, sizeof(struct clk), + GFP_KERNEL); + if (!priv->clocks) + return -ENOMEM; + + for (i = 0; i < clock_nb; i++) { + err = clk_get_by_index(dev, i, &priv->clocks[i]); + if (err < 0) + break; + + err = clk_enable(&priv->clocks[i]); + if (err) { + pr_err("failed to enable clock %d\n", i); + clk_free(&priv->clocks[i]); + goto clk_err; + } + priv->clock_count++; + } + } else if (clock_nb != -ENOENT) { + pr_err("failed to get clock phandle(%d)\n", clock_nb); + return clock_nb; + } +#endif #if defined(CONFIG_DM_REGULATOR) struct udevice *phy_supply; @@ -707,6 +737,15 @@ int designware_eth_probe(struct udevice *dev) debug("%s, ret=%d\n", __func__, ret); return ret; + +#ifdef CONFIG_CLK +clk_err: + ret = clk_release_all(priv->clocks, priv->clock_count); + if (ret) + pr_err("failed to disable all clocks\n"); + + return err; +#endif } static int designware_eth_remove(struct udevice *dev) @@ -717,7 +756,11 @@ static int designware_eth_remove(struct udevice *dev) mdio_unregister(priv->bus); mdio_free(priv->bus); +#ifdef CONFIG_CLK + return clk_release_all(priv->clocks, priv->clock_count); +#else return 0; +#endif } const struct eth_ops designware_eth_ops = { diff --git a/drivers/net/designware.h b/drivers/net/designware.h index 7992d0ebee..252cd24f1a 100644 --- a/drivers/net/designware.h +++ b/drivers/net/designware.h @@ -239,6 +239,10 @@ struct dw_eth_dev { #ifdef CONFIG_DM_GPIO struct gpio_desc reset_gpio; #endif +#ifdef CONFIG_CLK + struct clk *clocks; /* clock list */ + int clock_count; /* number of clock in clock list */ +#endif struct phy_device *phydev; struct mii_dev *bus; From 137963d71a2b2e0a1ac1fd755e0bec1409c2cdbd Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sat, 9 Dec 2017 14:59:54 -0800 Subject: [PATCH 11/21] net: phy: Add Broadcom BCM53xx switch driver Add a minimalistic Broadcom BCM53xx (roboswitch) switch driver similar to the Marvell MV88E617x. This takes care of configuring the minimum amount out of the switch hardware such that each user visible port (configurable) and the CPU port can forward packets between each other while preserving isolation with other ports. This is useful for e.g: the Lamobo R1 board featuring a Broadcom BCM53125 switch. Reviewed-by: Stefan Roese Signed-off-by: Florian Fainelli --- drivers/net/phy/Kconfig | 17 ++ drivers/net/phy/Makefile | 1 + drivers/net/phy/b53.c | 629 +++++++++++++++++++++++++++++++++++++++ drivers/net/phy/phy.c | 3 + include/phy.h | 1 + 5 files changed, 651 insertions(+) create mode 100644 drivers/net/phy/b53.c diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index e32f1eb1c0..95b7534323 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -12,6 +12,23 @@ menuconfig PHYLIB if PHYLIB +config B53_SWITCH + bool "Broadcom BCM53xx (RoboSwitch) Ethernet switch PHY support." + help + Enable support for Broadcom BCM53xx (RoboSwitch) Ethernet switches. + This currently supports BCM53125 and similar models. + +if B53_SWITCH + +config B53_CPU_PORT + int "CPU port" + default 8 + +config B53_PHY_PORTS + hex "Bitmask of PHY ports" + +endif # B53_SWITCH + config MV88E61XX_SWITCH bool "Marvel MV88E61xx Ethernet switch PHY support." diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index 1e264b2f2b..f1980371c3 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -6,6 +6,7 @@ # obj-$(CONFIG_BITBANGMII) += miiphybb.o +obj-$(CONFIG_B53_SWITCH) += b53.o obj-$(CONFIG_MV88E61XX_SWITCH) += mv88e61xx.o obj-$(CONFIG_MV88E6352_SWITCH) += mv88e6352.o diff --git a/drivers/net/phy/b53.c b/drivers/net/phy/b53.c new file mode 100644 index 0000000000..185a2cddab --- /dev/null +++ b/drivers/net/phy/b53.c @@ -0,0 +1,629 @@ +/* + * Copyright (C) 2017 + * Broadcom + * Florian Fainelli + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * PHY driver for Broadcom BCM53xx (roboswitch) Ethernet switches. + * + * This driver configures the b53 for basic use as a PHY. The switch supports + * vendor tags and VLAN configuration that can affect the switching decisions. + * This driver uses a simple configuration in which all ports are only allowed + * to send frames to the CPU port and receive frames from the CPU port this + * providing port isolation (no cross talk). + * + * The configuration determines which PHY ports to activate using the + * CONFIG_B53_PHY_PORTS bitmask. Set bit N will active port N and so on. + * + * This driver was written primarily for the Lamobo R1 platform using a BCM53152 + * switch but the BCM53xx being largely register compatible, extending it to + * cover other switches would be trivial. + */ + +#include + +#include +#include +#include +#include + +/* Pseudo-PHY address (non configurable) to access internal registers */ +#define BRCM_PSEUDO_PHY_ADDR 30 + +/* Maximum number of ports possible */ +#define B53_N_PORTS 9 + +#define B53_CTRL_PAGE 0x00 /* Control */ +#define B53_MGMT_PAGE 0x02 /* Management Mode */ +/* Port VLAN Page */ +#define B53_PVLAN_PAGE 0x31 + +/* Control Page registers */ +#define B53_PORT_CTRL(i) (0x00 + (i)) +#define PORT_CTRL_RX_DISABLE BIT(0) +#define PORT_CTRL_TX_DISABLE BIT(1) +#define PORT_CTRL_RX_BCST_EN BIT(2) /* Broadcast RX (P8 only) */ +#define PORT_CTRL_RX_MCST_EN BIT(3) /* Multicast RX (P8 only) */ +#define PORT_CTRL_RX_UCST_EN BIT(4) /* Unicast RX (P8 only) */ + +/* Switch Mode Control Register (8 bit) */ +#define B53_SWITCH_MODE 0x0b +#define SM_SW_FWD_MODE BIT(0) /* 1 = Managed Mode */ +#define SM_SW_FWD_EN BIT(1) /* Forwarding Enable */ + +/* IMP Port state override register (8 bit) */ +#define B53_PORT_OVERRIDE_CTRL 0x0e +#define PORT_OVERRIDE_LINK BIT(0) +#define PORT_OVERRIDE_FULL_DUPLEX BIT(1) /* 0 = Half Duplex */ +#define PORT_OVERRIDE_SPEED_S 2 +#define PORT_OVERRIDE_SPEED_10M (0 << PORT_OVERRIDE_SPEED_S) +#define PORT_OVERRIDE_SPEED_100M (1 << PORT_OVERRIDE_SPEED_S) +#define PORT_OVERRIDE_SPEED_1000M (2 << PORT_OVERRIDE_SPEED_S) +/* BCM5325 only */ +#define PORT_OVERRIDE_RV_MII_25 BIT(4) +#define PORT_OVERRIDE_RX_FLOW BIT(4) +#define PORT_OVERRIDE_TX_FLOW BIT(5) +/* BCM5301X only, requires setting 1000M */ +#define PORT_OVERRIDE_SPEED_2000M BIT(6) +#define PORT_OVERRIDE_EN BIT(7) /* Use the register contents */ + +#define B53_RGMII_CTRL_IMP 0x60 +#define RGMII_CTRL_ENABLE_GMII BIT(7) +#define RGMII_CTRL_TIMING_SEL BIT(2) +#define RGMII_CTRL_DLL_RXC BIT(1) +#define RGMII_CTRL_DLL_TXC BIT(0) + +/* Switch control (8 bit) */ +#define B53_SWITCH_CTRL 0x22 +#define B53_MII_DUMB_FWDG_EN BIT(6) + +/* Software reset register (8 bit) */ +#define B53_SOFTRESET 0x79 +#define SW_RST BIT(7) +#define EN_CH_RST BIT(6) +#define EN_SW_RST BIT(4) + +/* Fast Aging Control register (8 bit) */ +#define B53_FAST_AGE_CTRL 0x88 +#define FAST_AGE_STATIC BIT(0) +#define FAST_AGE_DYNAMIC BIT(1) +#define FAST_AGE_PORT BIT(2) +#define FAST_AGE_VLAN BIT(3) +#define FAST_AGE_STP BIT(4) +#define FAST_AGE_MC BIT(5) +#define FAST_AGE_DONE BIT(7) + +/* Port VLAN mask (16 bit) IMP port is always 8, also on 5325 & co */ +#define B53_PVLAN_PORT_MASK(i) ((i) * 2) + +/* MII registers */ +#define REG_MII_PAGE 0x10 /* MII Page register */ +#define REG_MII_ADDR 0x11 /* MII Address register */ +#define REG_MII_DATA0 0x18 /* MII Data register 0 */ +#define REG_MII_DATA1 0x19 /* MII Data register 1 */ +#define REG_MII_DATA2 0x1a /* MII Data register 2 */ +#define REG_MII_DATA3 0x1b /* MII Data register 3 */ + +#define REG_MII_PAGE_ENABLE BIT(0) +#define REG_MII_ADDR_WRITE BIT(0) +#define REG_MII_ADDR_READ BIT(1) + +struct b53_device { + struct mii_dev *bus; + unsigned int cpu_port; +}; + +static int b53_mdio_op(struct mii_dev *bus, u8 page, u8 reg, u16 op) +{ + int ret; + int i; + u16 v; + + /* set page number */ + v = (page << 8) | REG_MII_PAGE_ENABLE; + ret = bus->write(bus, BRCM_PSEUDO_PHY_ADDR, MDIO_DEVAD_NONE, + REG_MII_PAGE, v); + if (ret) + return ret; + + /* set register address */ + v = (reg << 8) | op; + ret = bus->write(bus, BRCM_PSEUDO_PHY_ADDR, MDIO_DEVAD_NONE, + REG_MII_ADDR, v); + if (ret) + return ret; + + /* check if operation completed */ + for (i = 0; i < 5; ++i) { + v = bus->read(bus, BRCM_PSEUDO_PHY_ADDR, MDIO_DEVAD_NONE, + REG_MII_ADDR); + if (!(v & (REG_MII_ADDR_WRITE | REG_MII_ADDR_READ))) + break; + + udelay(100); + } + + if (i == 5) + return -EIO; + + return 0; +} + +static int b53_mdio_read8(struct mii_dev *bus, u8 page, u8 reg, u8 *val) +{ + int ret; + + ret = b53_mdio_op(bus, page, reg, REG_MII_ADDR_READ); + if (ret) + return ret; + + *val = bus->read(bus, BRCM_PSEUDO_PHY_ADDR, MDIO_DEVAD_NONE, + REG_MII_DATA0) & 0xff; + + return 0; +} + +static int b53_mdio_read16(struct mii_dev *bus, u8 page, u8 reg, u16 *val) +{ + int ret; + + ret = b53_mdio_op(bus, page, reg, REG_MII_ADDR_READ); + if (ret) + return ret; + + *val = bus->read(bus, BRCM_PSEUDO_PHY_ADDR, MDIO_DEVAD_NONE, + REG_MII_DATA0); + + return 0; +} + +static int b53_mdio_read32(struct mii_dev *bus, u8 page, u8 reg, u32 *val) +{ + int ret; + + ret = b53_mdio_op(bus, page, reg, REG_MII_ADDR_READ); + if (ret) + return ret; + + *val = bus->read(bus, BRCM_PSEUDO_PHY_ADDR, MDIO_DEVAD_NONE, + REG_MII_DATA0); + *val |= bus->read(bus, BRCM_PSEUDO_PHY_ADDR, MDIO_DEVAD_NONE, + REG_MII_DATA1) << 16; + + return 0; +} + +static int b53_mdio_read48(struct mii_dev *bus, u8 page, u8 reg, u64 *val) +{ + u64 temp = 0; + int i; + int ret; + + ret = b53_mdio_op(bus, page, reg, REG_MII_ADDR_READ); + if (ret) + return ret; + + for (i = 2; i >= 0; i--) { + temp <<= 16; + temp |= bus->read(bus, BRCM_PSEUDO_PHY_ADDR, MDIO_DEVAD_NONE, + REG_MII_DATA0 + i); + } + + *val = temp; + + return 0; +} + +static int b53_mdio_read64(struct mii_dev *bus, u8 page, u8 reg, u64 *val) +{ + u64 temp = 0; + int i; + int ret; + + ret = b53_mdio_op(bus, page, reg, REG_MII_ADDR_READ); + if (ret) + return ret; + + for (i = 3; i >= 0; i--) { + temp <<= 16; + temp |= bus->read(bus, BRCM_PSEUDO_PHY_ADDR, MDIO_DEVAD_NONE, + REG_MII_DATA0 + i); + } + + *val = temp; + + return 0; +} + +static int b53_mdio_write8(struct mii_dev *bus, u8 page, u8 reg, u8 value) +{ + int ret; + + ret = bus->write(bus, BRCM_PSEUDO_PHY_ADDR, MDIO_DEVAD_NONE, + REG_MII_DATA0, value); + if (ret) + return ret; + + return b53_mdio_op(bus, page, reg, REG_MII_ADDR_WRITE); +} + +static int b53_mdio_write16(struct mii_dev *bus, u8 page, u8 reg, + u16 value) +{ + int ret; + + ret = bus->write(bus, BRCM_PSEUDO_PHY_ADDR, MDIO_DEVAD_NONE, + REG_MII_DATA0, value); + if (ret) + return ret; + + return b53_mdio_op(bus, page, reg, REG_MII_ADDR_WRITE); +} + +static int b53_mdio_write32(struct mii_dev *bus, u8 page, u8 reg, + u32 value) +{ + unsigned int i; + u32 temp = value; + + for (i = 0; i < 2; i++) { + int ret = bus->write(bus, BRCM_PSEUDO_PHY_ADDR, + MDIO_DEVAD_NONE, + REG_MII_DATA0 + i, temp & 0xffff); + if (ret) + return ret; + temp >>= 16; + } + + return b53_mdio_op(bus, page, reg, REG_MII_ADDR_WRITE); +} + +static int b53_mdio_write48(struct mii_dev *bus, u8 page, u8 reg, + u64 value) +{ + unsigned int i; + u64 temp = value; + + for (i = 0; i < 3; i++) { + int ret = bus->write(bus, BRCM_PSEUDO_PHY_ADDR, + MDIO_DEVAD_NONE, + REG_MII_DATA0 + i, temp & 0xffff); + if (ret) + return ret; + temp >>= 16; + } + + return b53_mdio_op(bus, page, reg, REG_MII_ADDR_WRITE); +} + +static int b53_mdio_write64(struct mii_dev *bus, u8 page, u8 reg, + u64 value) +{ + unsigned int i; + u64 temp = value; + + for (i = 0; i < 4; i++) { + int ret = bus->write(bus, BRCM_PSEUDO_PHY_ADDR, + MDIO_DEVAD_NONE, + REG_MII_DATA0 + i, temp & 0xffff); + if (ret) + return ret; + temp >>= 16; + } + + return b53_mdio_op(bus, page, reg, REG_MII_ADDR_WRITE); +} + +static inline int b53_read8(struct b53_device *dev, u8 page, + u8 reg, u8 *value) +{ + return b53_mdio_read8(dev->bus, page, reg, value); +} + +static inline int b53_read16(struct b53_device *dev, u8 page, + u8 reg, u16 *value) +{ + return b53_mdio_read16(dev->bus, page, reg, value); +} + +static inline int b53_read32(struct b53_device *dev, u8 page, + u8 reg, u32 *value) +{ + return b53_mdio_read32(dev->bus, page, reg, value); +} + +static inline int b53_read48(struct b53_device *dev, u8 page, + u8 reg, u64 *value) +{ + return b53_mdio_read48(dev->bus, page, reg, value); +} + +static inline int b53_read64(struct b53_device *dev, u8 page, + u8 reg, u64 *value) +{ + return b53_mdio_read64(dev->bus, page, reg, value); +} + +static inline int b53_write8(struct b53_device *dev, u8 page, + u8 reg, u8 value) +{ + return b53_mdio_write8(dev->bus, page, reg, value); +} + +static inline int b53_write16(struct b53_device *dev, u8 page, + u8 reg, u16 value) +{ + return b53_mdio_write16(dev->bus, page, reg, value); +} + +static inline int b53_write32(struct b53_device *dev, u8 page, + u8 reg, u32 value) +{ + return b53_mdio_write32(dev->bus, page, reg, value); +} + +static inline int b53_write48(struct b53_device *dev, u8 page, + u8 reg, u64 value) +{ + return b53_mdio_write48(dev->bus, page, reg, value); +} + +static inline int b53_write64(struct b53_device *dev, u8 page, + u8 reg, u64 value) +{ + return b53_mdio_write64(dev->bus, page, reg, value); +} + +static int b53_flush_arl(struct b53_device *dev, u8 mask) +{ + unsigned int i; + + b53_write8(dev, B53_CTRL_PAGE, B53_FAST_AGE_CTRL, + FAST_AGE_DONE | FAST_AGE_DYNAMIC | mask); + + for (i = 0; i < 10; i++) { + u8 fast_age_ctrl; + + b53_read8(dev, B53_CTRL_PAGE, B53_FAST_AGE_CTRL, + &fast_age_ctrl); + + if (!(fast_age_ctrl & FAST_AGE_DONE)) + goto out; + + mdelay(1); + } + + return -ETIMEDOUT; +out: + /* Only age dynamic entries (default behavior) */ + b53_write8(dev, B53_CTRL_PAGE, B53_FAST_AGE_CTRL, FAST_AGE_DYNAMIC); + return 0; +} + +static int b53_switch_reset(struct phy_device *phydev) +{ + struct b53_device *dev = phydev->priv; + unsigned int timeout = 1000; + u8 mgmt; + u8 reg; + + b53_read8(dev, B53_CTRL_PAGE, B53_SOFTRESET, ®); + reg |= SW_RST | EN_SW_RST | EN_CH_RST; + b53_write8(dev, B53_CTRL_PAGE, B53_SOFTRESET, reg); + + do { + b53_read8(dev, B53_CTRL_PAGE, B53_SOFTRESET, ®); + if (!(reg & SW_RST)) + break; + + mdelay(1); + } while (timeout-- > 0); + + if (timeout == 0) + return -ETIMEDOUT; + + b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt); + + if (!(mgmt & SM_SW_FWD_EN)) { + mgmt &= ~SM_SW_FWD_MODE; + mgmt |= SM_SW_FWD_EN; + + b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, mgmt); + b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt); + + if (!(mgmt & SM_SW_FWD_EN)) { + printf("Failed to enable switch!\n"); + return -EINVAL; + } + } + + /* Include IMP port in dumb forwarding mode when no tagging protocol + * is configured + */ + b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_CTRL, &mgmt); + mgmt |= B53_MII_DUMB_FWDG_EN; + b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_CTRL, mgmt); + + return b53_flush_arl(dev, FAST_AGE_STATIC); +} + +static void b53_enable_cpu_port(struct phy_device *phydev) +{ + struct b53_device *dev = phydev->priv; + u8 port_ctrl; + + port_ctrl = PORT_CTRL_RX_BCST_EN | + PORT_CTRL_RX_MCST_EN | + PORT_CTRL_RX_UCST_EN; + b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(dev->cpu_port), port_ctrl); + + port_ctrl = PORT_OVERRIDE_EN | PORT_OVERRIDE_LINK | + PORT_OVERRIDE_FULL_DUPLEX | PORT_OVERRIDE_SPEED_1000M; + b53_write8(dev, B53_CTRL_PAGE, B53_PORT_OVERRIDE_CTRL, port_ctrl); + + b53_read8(dev, B53_CTRL_PAGE, B53_RGMII_CTRL_IMP, &port_ctrl); +} + +static void b53_imp_vlan_setup(struct b53_device *dev, int cpu_port) +{ + unsigned int port; + u16 pvlan; + + /* Enable the IMP port to be in the same VLAN as the other ports + * on a per-port basis such that we only have Port i and IMP in + * the same VLAN. + */ + for (port = 0; port < B53_N_PORTS; port++) { + if (!((1 << port) & CONFIG_B53_PHY_PORTS)) + continue; + + b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), + &pvlan); + pvlan |= BIT(cpu_port); + b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), + pvlan); + } +} + +static int b53_port_enable(struct phy_device *phydev, unsigned int port) +{ + struct b53_device *dev = phydev->priv; + unsigned int cpu_port = dev->cpu_port; + u16 pvlan; + + /* Clear the Rx and Tx disable bits and set to no spanning tree */ + b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), 0); + + /* Set this port, and only this one to be in the default VLAN */ + b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), &pvlan); + pvlan &= ~0x1ff; + pvlan |= BIT(port); + b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), pvlan); + + b53_imp_vlan_setup(dev, cpu_port); + + return 0; +} + +static int b53_switch_init(struct phy_device *phydev) +{ + static int init; + int ret; + + if (init) + return 0; + + ret = b53_switch_reset(phydev); + if (ret < 0) + return ret; + + b53_enable_cpu_port(phydev); + + init = 1; + + return 0; +} + +static int b53_probe(struct phy_device *phydev) +{ + struct b53_device *dev; + int ret; + + dev = malloc(sizeof(*dev)); + if (!dev) + return -ENOMEM; + + memset(dev, 0, sizeof(*dev)); + + phydev->priv = dev; + dev->bus = phydev->bus; + dev->cpu_port = CONFIG_B53_CPU_PORT; + + ret = b53_switch_reset(phydev); + if (ret < 0) + return ret; + + return 0; +} + +static int b53_phy_config(struct phy_device *phydev) +{ + unsigned int port; + int res; + + res = b53_switch_init(phydev); + if (res < 0) + return res; + + for (port = 0; port < B53_N_PORTS; port++) { + if (!((1 << port) & CONFIG_B53_PHY_PORTS)) + continue; + + res = b53_port_enable(phydev, port); + if (res < 0) { + printf("Error enabling port %i\n", port); + continue; + } + + res = genphy_config_aneg(phydev); + if (res < 0) { + printf("Error setting PHY %i autoneg\n", port); + continue; + } + + res = 0; + } + + return res; +} + +static int b53_phy_startup(struct phy_device *phydev) +{ + unsigned int port; + int res; + + for (port = 0; port < B53_N_PORTS; port++) { + if (!((1 << port) & CONFIG_B53_PHY_PORTS)) + continue; + + phydev->addr = port; + + res = genphy_startup(phydev); + if (res < 0) + continue; + else + break; + } + + /* Since we are connected directly to the switch, hardcode the link + * parameters to match those of the CPU port configured in + * b53_enable_cpu_port, we cannot be dependent on the user-facing port + * settings (e.g: 100Mbits/sec would not work here) + */ + phydev->speed = 1000; + phydev->duplex = 1; + phydev->link = 1; + + return 0; +} + +static struct phy_driver b53_driver = { + .name = "Broadcom BCM53125", + .uid = 0x03625c00, + .mask = 0xfffffc00, + .features = PHY_GBIT_FEATURES, + .probe = b53_probe, + .config = b53_phy_config, + .startup = b53_phy_startup, + .shutdown = &genphy_shutdown, +}; + +int phy_b53_init(void) +{ + phy_register(&b53_driver); + + return 0; +} diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index fd3dd556c8..e31f3aa3a9 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -461,6 +461,9 @@ static LIST_HEAD(phy_drivers); int phy_init(void) { +#ifdef CONFIG_B53_SWITCH + phy_b53_init(); +#endif #ifdef CONFIG_MV88E61XX_SWITCH phy_mv88e61xx_init(); #endif diff --git a/include/phy.h b/include/phy.h index 50f1e12f8c..0543ec10c2 100644 --- a/include/phy.h +++ b/include/phy.h @@ -257,6 +257,7 @@ int gen10g_startup(struct phy_device *phydev); int gen10g_shutdown(struct phy_device *phydev); int gen10g_discover_mmds(struct phy_device *phydev); +int phy_b53_init(void); int phy_mv88e61xx_init(void); int phy_aquantia_init(void); int phy_atheros_init(void); From 7a9ca9db400fc95463011449cf47012fb2e1db0d Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sat, 9 Dec 2017 14:59:55 -0800 Subject: [PATCH 12/21] net: designware: Pad small packets Make sure that we pad small packets to a minimum length of 60 bytes (without FCS). This is necessary to interface with Ethernet switches that will reject RUNT frames unless padded correctly. Signed-off-by: Florian Fainelli --- drivers/net/designware.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/designware.c b/drivers/net/designware.c index 9207324731..6d5307128d 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include "designware.h" @@ -344,6 +345,8 @@ int designware_eth_enable(struct dw_eth_dev *priv) return 0; } +#define ETH_ZLEN 60 + static int _dw_eth_send(struct dw_eth_dev *priv, void *packet, int length) { struct eth_dma_regs *dma_p = priv->dma_regs_p; @@ -370,6 +373,8 @@ static int _dw_eth_send(struct dw_eth_dev *priv, void *packet, int length) return -EPERM; } + length = max(length, ETH_ZLEN); + memcpy((void *)data_start, packet, length); /* Flush data to be sent */ From f3d78fbfaf25ccbf74316760667c2ad1bb771375 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sat, 9 Dec 2017 14:59:56 -0800 Subject: [PATCH 13/21] net: phy: b53: Add b53_reg read/write commands Add a b53_reg read/write command which allows inspecting the switch registers. Because the Broadcom BCM53xx registers have different sizes, we need to split the accesses in 8, 16, 32, 48 or 64 bits to obtain expected results. Reviewed-by: Stefan Roese Acked-by: Joe Hershberger Signed-off-by: Florian Fainelli --- drivers/net/phy/b53.c | 139 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) diff --git a/drivers/net/phy/b53.c b/drivers/net/phy/b53.c index 185a2cddab..f7f2d9f1ee 100644 --- a/drivers/net/phy/b53.c +++ b/drivers/net/phy/b53.c @@ -627,3 +627,142 @@ int phy_b53_init(void) return 0; } + +int do_b53_reg_read(const char *name, int argc, char * const argv[]) +{ + u8 page, offset, width; + struct mii_dev *bus; + int ret = -EINVAL; + u64 value64 = 0; + u32 value32 = 0; + u16 value16 = 0; + u8 value8 = 0; + + bus = miiphy_get_dev_by_name(name); + if (!bus) { + printf("unable to find MDIO bus: %s\n", name); + return ret; + } + + page = simple_strtoul(argv[1], NULL, 16); + offset = simple_strtoul(argv[2], NULL, 16); + width = simple_strtoul(argv[3], NULL, 10); + + switch (width) { + case 8: + ret = b53_mdio_read8(bus, page, offset, &value8); + printf("page=0x%02x, offset=0x%02x, value=0x%02x\n", + page, offset, value8); + break; + case 16: + ret = b53_mdio_read16(bus, page, offset, &value16); + printf("page=0x%02x, offset=0x%02x, value=0x%04x\n", + page, offset, value16); + break; + case 32: + ret = b53_mdio_read32(bus, page, offset, &value32); + printf("page=0x%02x, offset=0x%02x, value=0x%08x\n", + page, offset, value32); + break; + case 48: + ret = b53_mdio_read48(bus, page, offset, &value64); + printf("page=0x%02x, offset=0x%02x, value=0x%012llx\n", + page, offset, value64); + break; + case 64: + ret = b53_mdio_read48(bus, page, offset, &value64); + printf("page=0x%02x, offset=0x%02x, value=0x%016llx\n", + page, offset, value64); + break; + default: + printf("Unsupported width: %d\n", width); + break; + } + + return ret; +} + +int do_b53_reg_write(const char *name, int argc, char * const argv[]) +{ + u8 page, offset, width; + struct mii_dev *bus; + int ret = -EINVAL; + u64 value64 = 0; + u32 value = 0; + + bus = miiphy_get_dev_by_name(name); + if (!bus) { + printf("unable to find MDIO bus: %s\n", name); + return ret; + } + + page = simple_strtoul(argv[1], NULL, 16); + offset = simple_strtoul(argv[2], NULL, 16); + width = simple_strtoul(argv[3], NULL, 10); + if (width == 48 || width == 64) + value64 = simple_strtoull(argv[4], NULL, 16); + else + value = simple_strtoul(argv[4], NULL, 16); + + switch (width) { + case 8: + ret = b53_mdio_write8(bus, page, offset, value & 0xff); + break; + case 16: + ret = b53_mdio_write16(bus, page, offset, value); + break; + case 32: + ret = b53_mdio_write32(bus, page, offset, value); + break; + case 48: + ret = b53_mdio_write48(bus, page, offset, value64); + break; + case 64: + ret = b53_mdio_write64(bus, page, offset, value64); + break; + default: + printf("Unsupported width: %d\n", width); + break; + } + + return ret; +} + +int do_b53_reg(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + const char *cmd, *mdioname; + int ret = 0; + + if (argc < 2) + return cmd_usage(cmdtp); + + cmd = argv[1]; + --argc; + ++argv; + + if (!strcmp(cmd, "write")) { + if (argc < 4) + return cmd_usage(cmdtp); + mdioname = argv[1]; + --argc; + ++argv; + ret = do_b53_reg_write(mdioname, argc, argv); + } else if (!strcmp(cmd, "read")) { + if (argc < 5) + return cmd_usage(cmdtp); + mdioname = argv[1]; + --argc; + ++argv; + ret = do_b53_reg_read(mdioname, argc, argv); + } else { + return cmd_usage(cmdtp); + } + + return ret; +} + +U_BOOT_CMD(b53_reg, 7, 1, do_b53_reg, + "Broadcom B53 switch register access", + "write mdioname page (hex) offset (hex) width (dec) value (hex)\n" + "read mdioname page (hex) offset (hex) width (dec)\n" + ); From d5d5757291509f0716f6c24a391a3ae1f51042be Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sat, 9 Dec 2017 14:59:57 -0800 Subject: [PATCH 14/21] configs: Update Lamobo_R1 with B53 switch options Enable CONFIG_B53_SWITCH, define the CPU/management port number (8) and enable all 5 ports of the switch to be usable. Reviewed-by: Stefan Roese Acked-by: Joe Hershberger Signed-off-by: Florian Fainelli --- configs/Lamobo_R1_defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configs/Lamobo_R1_defconfig b/configs/Lamobo_R1_defconfig index 4cc4dc4b16..805d4b7011 100644 --- a/configs/Lamobo_R1_defconfig +++ b/configs/Lamobo_R1_defconfig @@ -23,3 +23,6 @@ CONFIG_SUN7I_GMAC=y CONFIG_SCSI=y CONFIG_USB_EHCI_HCD=y CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y +CONFIG_B53_SWITCH=y +CONFIG_B53_CPU_PORT=8 +CONFIG_B53_PHY_PORTS=0x1f From 2099b9f27cebdbee1ff28ccf146c8dba8a922118 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Tue, 7 Nov 2017 18:13:40 -0800 Subject: [PATCH 15/21] net: dhcp: Allow "MAY_FAIL" to still try each adapter This change allows the "MAY_FAIL" DHCP option to still attempt to contact a DHCP server on each adapter and only give up once each adapter has failed once. To get the existing behavior, set the already-existing ethrotate=no variable. Signed-off-by: Joe Hershberger Cc: Keng Soon Cheah Cc: Chen Yee Chew --- net/bootp.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/net/bootp.c b/net/bootp.c index 59bb2099f1..efa959971c 100644 --- a/net/bootp.c +++ b/net/bootp.c @@ -386,12 +386,19 @@ static void bootp_timeout_handler(void) if (time_taken >= time_taken_max) { #ifdef CONFIG_BOOTP_MAY_FAIL - puts("\nRetry time exceeded\n"); - net_set_state(NETLOOP_FAIL); -#else - puts("\nRetry time exceeded; starting again\n"); - net_start_again(); + char *ethrotate; + + ethrotate = env_get("ethrotate"); + if ((ethrotate && strcmp(ethrotate, "no") == 0) || + net_restart_wrap) { + puts("\nRetry time exceeded\n"); + net_set_state(NETLOOP_FAIL); + } else #endif + { + puts("\nRetry time exceeded; starting again\n"); + net_start_again(); + } } else { bootp_timeout *= 2; if (bootp_timeout > 2000) From dc14867d0ffea3e4ffcda669780d85bb160871b0 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Fri, 1 Dec 2017 08:08:00 +0900 Subject: [PATCH 16/21] net: sh-eth: Fix coding style checked by checkpatch.pl This fixes the chord style checked by checkpatch.pl. Details of change details are as follows: - Fix typo Change from alligned to aligned. - Remove whitespace before ',' - Add spaces preferred around that '|' - Fix missing a blank line after declarations - Remove space after a cast declaration - Fix format of block comments - Add a blank line after function/struct/union/enum declarations Signed-off-by: Nobuhiro Iwamatsu Acked-by: Joe Hershberger --- drivers/net/sh_eth.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 970d730e56..eafc4d3f27 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -67,7 +67,7 @@ int sh_eth_send(struct eth_device *dev, void *packet, int len) /* packet must be a 4 byte boundary */ if ((int)packet & 3) { - printf(SHETHER_NAME ": %s: packet not 4 byte alligned\n" + printf(SHETHER_NAME ": %s: packet not 4 byte aligned\n" , __func__); ret = -EFAULT; goto err; @@ -222,8 +222,10 @@ static int sh_eth_tx_desc_init(struct sh_eth_dev *eth) cur_tx_desc--; cur_tx_desc->td0 |= TD_TDLE; - /* Point the controller to the tx descriptor list. Must use physical - addresses */ + /* + * Point the controller to the tx descriptor list. Must use physical + * addresses + */ sh_eth_write(eth, ADDR_TO_PHY(port_info->tx_desc_base), TDLAR); #if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ) sh_eth_write(eth, ADDR_TO_PHY(port_info->tx_desc_base), TDFAR); @@ -237,7 +239,7 @@ err: static int sh_eth_rx_desc_init(struct sh_eth_dev *eth) { - int port = eth->port, i , ret = 0; + int port = eth->port, i, ret = 0; u32 alloc_desc_size = NUM_RX_DESC * sizeof(struct rx_desc_s); struct sh_eth_info *port_info = ð->port_info[port]; struct rx_desc_s *cur_rx_desc; @@ -283,7 +285,7 @@ static int sh_eth_rx_desc_init(struct sh_eth_dev *eth) i < NUM_RX_DESC; cur_rx_desc++, rx_buf += MAX_BUF_SIZE, i++) { cur_rx_desc->rd0 = RD_RACT; cur_rx_desc->rd1 = MAX_BUF_SIZE << 16; - cur_rx_desc->rd2 = (u32) ADDR_TO_PHY(rx_buf); + cur_rx_desc->rd2 = (u32)ADDR_TO_PHY(rx_buf); } /* Mark the end of the descriptors */ @@ -465,11 +467,14 @@ static int sh_eth_config(struct sh_eth_dev *eth, bd_t *bd) /* Check if full duplex mode is supported by the phy */ if (phy->duplex) { printf("Full\n"); - sh_eth_write(eth, val | (ECMR_CHG_DM|ECMR_RE|ECMR_TE|ECMR_DM), + sh_eth_write(eth, + val | (ECMR_CHG_DM | ECMR_RE | ECMR_TE | ECMR_DM), ECMR); } else { printf("Half\n"); - sh_eth_write(eth, val | (ECMR_CHG_DM|ECMR_RE|ECMR_TE), ECMR); + sh_eth_write(eth, + val | (ECMR_CHG_DM | ECMR_RE | ECMR_TE), + ECMR); } return ret; @@ -524,6 +529,7 @@ err: void sh_eth_halt(struct eth_device *dev) { struct sh_eth_dev *eth = dev->priv; + sh_eth_stop(eth); } @@ -532,6 +538,7 @@ int sh_eth_initialize(bd_t *bd) int ret = 0; struct sh_eth_dev *eth = NULL; struct eth_device *dev = NULL; + struct mii_dev *mdiodev; eth = (struct sh_eth_dev *)malloc(sizeof(struct sh_eth_dev)); if (!eth) { @@ -566,17 +573,16 @@ int sh_eth_initialize(bd_t *bd) eth_register(dev); bb_miiphy_buses[0].priv = eth; - int retval; - struct mii_dev *mdiodev = mdio_alloc(); + mdiodev = mdio_alloc(); if (!mdiodev) return -ENOMEM; strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN); mdiodev->read = bb_miiphy_read; mdiodev->write = bb_miiphy_write; - retval = mdio_register(mdiodev); - if (retval < 0) - return retval; + ret = mdio_register(mdiodev); + if (ret < 0) + return ret; if (!eth_env_get_enetaddr("ethaddr", dev->enetaddr)) puts("Please set MAC address\n"); @@ -670,4 +676,5 @@ struct bb_miiphy_bus bb_miiphy_buses[] = { .delay = sh_eth_bb_delay, } }; + int bb_miiphy_buses_num = ARRAY_SIZE(bb_miiphy_buses); From 9b5f9ecf6e7e2af0d395e10323b14d77fc0c9a9b Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Fri, 1 Dec 2017 08:08:47 +0900 Subject: [PATCH 17/21] net: sh-eth: Remove bd_t from sh_eth_config() bd_t is not used in sh_eth_config(). This deletes bd_t from sh_eth_config() Signed-off-by: Nobuhiro Iwamatsu Acked-by: Joe Hershberger --- drivers/net/sh_eth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index eafc4d3f27..14816a0a03 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -373,7 +373,7 @@ static int sh_eth_phy_config(struct sh_eth_dev *eth) return ret; } -static int sh_eth_config(struct sh_eth_dev *eth, bd_t *bd) +static int sh_eth_config(struct sh_eth_dev *eth) { int port = eth->port, ret = 0; u32 val; @@ -510,7 +510,7 @@ int sh_eth_init(struct eth_device *dev, bd_t *bd) if (ret) goto err; - ret = sh_eth_config(eth, bd); + ret = sh_eth_config(eth); if (ret) goto err_config; From fbfb511548b686057e02f32ddf6e08a9e13206b8 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Fri, 1 Dec 2017 08:10:32 +0900 Subject: [PATCH 18/21] net: sh-eth: Change read/write() param to struct sh_eth_info This changes Change structure used in sh_eth_read and sh_eth_write function from struct sh_eth_dev to struct sh_eth_info. This is necessary to convert to Driver Model. Signed-off-by: Nobuhiro Iwamatsu Acked-by: Joe Hershberger --- drivers/net/sh_eth.c | 119 ++++++++++++++++++++++++------------------- drivers/net/sh_eth.h | 13 ++--- 2 files changed, 75 insertions(+), 57 deletions(-) diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 14816a0a03..f28f388ea9 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -86,8 +86,8 @@ int sh_eth_send(struct eth_device *dev, void *packet, int len) flush_cache_wback(port_info->tx_desc_cur, sizeof(struct tx_desc_s)); /* Restart the transmitter if disabled */ - if (!(sh_eth_read(eth, EDTRR) & EDTRR_TRNS)) - sh_eth_write(eth, EDTRR_TRNS, EDTRR); + if (!(sh_eth_read(port_info, EDTRR) & EDTRR_TRNS)) + sh_eth_write(port_info, EDTRR_TRNS, EDTRR); /* Wait until packet is transmitted */ timeout = TIMEOUT_CNT; @@ -147,24 +147,25 @@ int sh_eth_recv(struct eth_device *dev) } /* Restart the receiver if disabled */ - if (!(sh_eth_read(eth, EDRRR) & EDRRR_R)) - sh_eth_write(eth, EDRRR_R, EDRRR); + if (!(sh_eth_read(port_info, EDRRR) & EDRRR_R)) + sh_eth_write(port_info, EDRRR_R, EDRRR); return len; } static int sh_eth_reset(struct sh_eth_dev *eth) { + struct sh_eth_info *port_info = ð->port_info[eth->port]; #if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ) int ret = 0, i; /* Start e-dmac transmitter and receiver */ - sh_eth_write(eth, EDSR_ENALL, EDSR); + sh_eth_write(port_info, EDSR_ENALL, EDSR); /* Perform a software reset and wait for it to complete */ - sh_eth_write(eth, EDMR_SRST, EDMR); + sh_eth_write(port_info, EDMR_SRST, EDMR); for (i = 0; i < TIMEOUT_CNT; i++) { - if (!(sh_eth_read(eth, EDMR) & EDMR_SRST)) + if (!(sh_eth_read(port_info, EDMR) & EDMR_SRST)) break; udelay(1000); } @@ -176,9 +177,10 @@ static int sh_eth_reset(struct sh_eth_dev *eth) return ret; #else - sh_eth_write(eth, sh_eth_read(eth, EDMR) | EDMR_SRST, EDMR); + sh_eth_write(port_info, sh_eth_read(port_info, EDMR) | EDMR_SRST, EDMR); udelay(3000); - sh_eth_write(eth, sh_eth_read(eth, EDMR) & ~EDMR_SRST, EDMR); + sh_eth_write(port_info, + sh_eth_read(port_info, EDMR) & ~EDMR_SRST, EDMR); return 0; #endif @@ -226,11 +228,11 @@ static int sh_eth_tx_desc_init(struct sh_eth_dev *eth) * Point the controller to the tx descriptor list. Must use physical * addresses */ - sh_eth_write(eth, ADDR_TO_PHY(port_info->tx_desc_base), TDLAR); + sh_eth_write(port_info, ADDR_TO_PHY(port_info->tx_desc_base), TDLAR); #if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ) - sh_eth_write(eth, ADDR_TO_PHY(port_info->tx_desc_base), TDFAR); - sh_eth_write(eth, ADDR_TO_PHY(cur_tx_desc), TDFXR); - sh_eth_write(eth, 0x01, TDFFR);/* Last discriptor bit */ + sh_eth_write(port_info, ADDR_TO_PHY(port_info->tx_desc_base), TDFAR); + sh_eth_write(port_info, ADDR_TO_PHY(cur_tx_desc), TDFXR); + sh_eth_write(port_info, 0x01, TDFFR);/* Last discriptor bit */ #endif err: @@ -293,11 +295,11 @@ static int sh_eth_rx_desc_init(struct sh_eth_dev *eth) cur_rx_desc->rd0 |= RD_RDLE; /* Point the controller to the rx descriptor list */ - sh_eth_write(eth, ADDR_TO_PHY(port_info->rx_desc_base), RDLAR); + sh_eth_write(port_info, ADDR_TO_PHY(port_info->rx_desc_base), RDLAR); #if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ) - sh_eth_write(eth, ADDR_TO_PHY(port_info->rx_desc_base), RDFAR); - sh_eth_write(eth, ADDR_TO_PHY(cur_rx_desc), RDFXR); - sh_eth_write(eth, RDFFR_RDLF, RDFFR); + sh_eth_write(port_info, ADDR_TO_PHY(port_info->rx_desc_base), RDFAR); + sh_eth_write(port_info, ADDR_TO_PHY(cur_rx_desc), RDFXR); + sh_eth_write(port_info, RDFFR_RDLF, RDFFR); #endif return ret; @@ -382,45 +384,45 @@ static int sh_eth_config(struct sh_eth_dev *eth) struct phy_device *phy; /* Configure e-dmac registers */ - sh_eth_write(eth, (sh_eth_read(eth, EDMR) & ~EMDR_DESC_R) | + sh_eth_write(port_info, (sh_eth_read(port_info, EDMR) & ~EMDR_DESC_R) | (EMDR_DESC | EDMR_EL), EDMR); - sh_eth_write(eth, 0, EESIPR); - sh_eth_write(eth, 0, TRSCER); - sh_eth_write(eth, 0, TFTR); - sh_eth_write(eth, (FIFO_SIZE_T | FIFO_SIZE_R), FDR); - sh_eth_write(eth, RMCR_RST, RMCR); + sh_eth_write(port_info, 0, EESIPR); + sh_eth_write(port_info, 0, TRSCER); + sh_eth_write(port_info, 0, TFTR); + sh_eth_write(port_info, (FIFO_SIZE_T | FIFO_SIZE_R), FDR); + sh_eth_write(port_info, RMCR_RST, RMCR); #if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ) - sh_eth_write(eth, 0, RPADIR); + sh_eth_write(port_info, 0, RPADIR); #endif - sh_eth_write(eth, (FIFO_F_D_RFF | FIFO_F_D_RFD), FCFTR); + sh_eth_write(port_info, (FIFO_F_D_RFF | FIFO_F_D_RFD), FCFTR); /* Configure e-mac registers */ - sh_eth_write(eth, 0, ECSIPR); + sh_eth_write(port_info, 0, ECSIPR); /* Set Mac address */ val = dev->enetaddr[0] << 24 | dev->enetaddr[1] << 16 | dev->enetaddr[2] << 8 | dev->enetaddr[3]; - sh_eth_write(eth, val, MAHR); + sh_eth_write(port_info, val, MAHR); val = dev->enetaddr[4] << 8 | dev->enetaddr[5]; - sh_eth_write(eth, val, MALR); + sh_eth_write(port_info, val, MALR); - sh_eth_write(eth, RFLR_RFL_MIN, RFLR); + sh_eth_write(port_info, RFLR_RFL_MIN, RFLR); #if defined(SH_ETH_TYPE_GETHER) - sh_eth_write(eth, 0, PIPR); + sh_eth_write(port_info, 0, PIPR); #endif #if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ) - sh_eth_write(eth, APR_AP, APR); - sh_eth_write(eth, MPR_MP, MPR); - sh_eth_write(eth, TPAUSER_TPAUSE, TPAUSER); + sh_eth_write(port_info, APR_AP, APR); + sh_eth_write(port_info, MPR_MP, MPR); + sh_eth_write(port_info, TPAUSER_TPAUSE, TPAUSER); #endif #if defined(CONFIG_CPU_SH7734) || defined(CONFIG_R8A7740) - sh_eth_write(eth, CONFIG_SH_ETHER_SH7734_MII, RMII_MII); + sh_eth_write(port_info, CONFIG_SH_ETHER_SH7734_MII, RMII_MII); #elif defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791) || \ defined(CONFIG_R8A7793) || defined(CONFIG_R8A7794) - sh_eth_write(eth, sh_eth_read(eth, RMIIMR) | 0x1, RMIIMR); + sh_eth_write(port_info, sh_eth_read(port_info, RMIIMR) | 0x1, RMIIMR); #endif /* Configure phy */ ret = sh_eth_phy_config(eth); @@ -441,9 +443,9 @@ static int sh_eth_config(struct sh_eth_dev *eth) if (phy->speed == 100) { printf(SHETHER_NAME ": 100Base/"); #if defined(SH_ETH_TYPE_GETHER) - sh_eth_write(eth, GECMR_100B, GECMR); + sh_eth_write(port_info, GECMR_100B, GECMR); #elif defined(CONFIG_CPU_SH7757) || defined(CONFIG_CPU_SH7752) - sh_eth_write(eth, 1, RTRATE); + sh_eth_write(port_info, 1, RTRATE); #elif defined(CONFIG_CPU_SH7724) || defined(CONFIG_R8A7790) || \ defined(CONFIG_R8A7791) || defined(CONFIG_R8A7793) || \ defined(CONFIG_R8A7794) @@ -452,27 +454,27 @@ static int sh_eth_config(struct sh_eth_dev *eth) } else if (phy->speed == 10) { printf(SHETHER_NAME ": 10Base/"); #if defined(SH_ETH_TYPE_GETHER) - sh_eth_write(eth, GECMR_10B, GECMR); + sh_eth_write(port_info, GECMR_10B, GECMR); #elif defined(CONFIG_CPU_SH7757) || defined(CONFIG_CPU_SH7752) - sh_eth_write(eth, 0, RTRATE); + sh_eth_write(port_info, 0, RTRATE); #endif } #if defined(SH_ETH_TYPE_GETHER) else if (phy->speed == 1000) { printf(SHETHER_NAME ": 1000Base/"); - sh_eth_write(eth, GECMR_1000B, GECMR); + sh_eth_write(port_info, GECMR_1000B, GECMR); } #endif /* Check if full duplex mode is supported by the phy */ if (phy->duplex) { printf("Full\n"); - sh_eth_write(eth, + sh_eth_write(port_info, val | (ECMR_CHG_DM | ECMR_RE | ECMR_TE | ECMR_DM), ECMR); } else { printf("Half\n"); - sh_eth_write(eth, + sh_eth_write(port_info, val | (ECMR_CHG_DM | ECMR_RE | ECMR_TE), ECMR); } @@ -485,16 +487,20 @@ err_phy_cfg: static void sh_eth_start(struct sh_eth_dev *eth) { + struct sh_eth_info *port_info = ð->port_info[eth->port]; + /* * Enable the e-dmac receiver only. The transmitter will be enabled when * we have something to transmit */ - sh_eth_write(eth, EDRRR_R, EDRRR); + sh_eth_write(port_info, EDRRR_R, EDRRR); } static void sh_eth_stop(struct sh_eth_dev *eth) { - sh_eth_write(eth, ~EDRRR_R, EDRRR); + struct sh_eth_info *port_info = ð->port_info[eth->port]; + + sh_eth_write(port_info, ~EDRRR_R, EDRRR); } int sh_eth_init(struct eth_device *dev, bd_t *bd) @@ -558,6 +564,8 @@ int sh_eth_initialize(bd_t *bd) eth->port = CONFIG_SH_ETHER_USE_PORT; eth->port_info[eth->port].phy_addr = CONFIG_SH_ETHER_PHY_ADDR; + eth->port_info[eth->port].iobase = + (void __iomem *)(BASE_IO_ADDR + 0x800 * eth->port); dev->priv = (void *)eth; dev->iobase = 0; @@ -609,8 +617,9 @@ static int sh_eth_bb_init(struct bb_miiphy_bus *bus) static int sh_eth_bb_mdio_active(struct bb_miiphy_bus *bus) { struct sh_eth_dev *eth = bus->priv; + struct sh_eth_info *port_info = ð->port_info[eth->port]; - sh_eth_write(eth, sh_eth_read(eth, PIR) | PIR_MMD, PIR); + sh_eth_write(port_info, sh_eth_read(port_info, PIR) | PIR_MMD, PIR); return 0; } @@ -618,8 +627,9 @@ static int sh_eth_bb_mdio_active(struct bb_miiphy_bus *bus) static int sh_eth_bb_mdio_tristate(struct bb_miiphy_bus *bus) { struct sh_eth_dev *eth = bus->priv; + struct sh_eth_info *port_info = ð->port_info[eth->port]; - sh_eth_write(eth, sh_eth_read(eth, PIR) & ~PIR_MMD, PIR); + sh_eth_write(port_info, sh_eth_read(port_info, PIR) & ~PIR_MMD, PIR); return 0; } @@ -627,11 +637,14 @@ static int sh_eth_bb_mdio_tristate(struct bb_miiphy_bus *bus) static int sh_eth_bb_set_mdio(struct bb_miiphy_bus *bus, int v) { struct sh_eth_dev *eth = bus->priv; + struct sh_eth_info *port_info = ð->port_info[eth->port]; if (v) - sh_eth_write(eth, sh_eth_read(eth, PIR) | PIR_MDO, PIR); + sh_eth_write(port_info, + sh_eth_read(port_info, PIR) | PIR_MDO, PIR); else - sh_eth_write(eth, sh_eth_read(eth, PIR) & ~PIR_MDO, PIR); + sh_eth_write(port_info, + sh_eth_read(port_info, PIR) & ~PIR_MDO, PIR); return 0; } @@ -639,8 +652,9 @@ static int sh_eth_bb_set_mdio(struct bb_miiphy_bus *bus, int v) static int sh_eth_bb_get_mdio(struct bb_miiphy_bus *bus, int *v) { struct sh_eth_dev *eth = bus->priv; + struct sh_eth_info *port_info = ð->port_info[eth->port]; - *v = (sh_eth_read(eth, PIR) & PIR_MDI) >> 3; + *v = (sh_eth_read(port_info, PIR) & PIR_MDI) >> 3; return 0; } @@ -648,11 +662,14 @@ static int sh_eth_bb_get_mdio(struct bb_miiphy_bus *bus, int *v) static int sh_eth_bb_set_mdc(struct bb_miiphy_bus *bus, int v) { struct sh_eth_dev *eth = bus->priv; + struct sh_eth_info *port_info = ð->port_info[eth->port]; if (v) - sh_eth_write(eth, sh_eth_read(eth, PIR) | PIR_MDC, PIR); + sh_eth_write(port_info, + sh_eth_read(port_info, PIR) | PIR_MDC, PIR); else - sh_eth_write(eth, sh_eth_read(eth, PIR) & ~PIR_MDC, PIR); + sh_eth_write(port_info, + sh_eth_read(port_info, PIR) & ~PIR_MDC, PIR); return 0; } diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h index a8339ebf33..a0dcfcae09 100644 --- a/drivers/net/sh_eth.h +++ b/drivers/net/sh_eth.h @@ -92,6 +92,7 @@ struct sh_eth_info { u8 phy_addr; struct eth_device *dev; struct phy_device *phydev; + void __iomem *iobase; }; struct sh_eth_dev { @@ -601,7 +602,7 @@ enum FIFO_SIZE_BIT { FIFO_SIZE_T = 0x00000700, FIFO_SIZE_R = 0x00000007, }; -static inline unsigned long sh_eth_reg_addr(struct sh_eth_dev *eth, +static inline unsigned long sh_eth_reg_addr(struct sh_eth_info *port, int enum_index) { #if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ) @@ -611,17 +612,17 @@ static inline unsigned long sh_eth_reg_addr(struct sh_eth_dev *eth, #else #error #endif - return BASE_IO_ADDR + reg_offset[enum_index] + 0x800 * eth->port; + return (unsigned long)port->iobase + reg_offset[enum_index]; } -static inline void sh_eth_write(struct sh_eth_dev *eth, unsigned long data, +static inline void sh_eth_write(struct sh_eth_info *port, unsigned long data, int enum_index) { - outl(data, sh_eth_reg_addr(eth, enum_index)); + outl(data, sh_eth_reg_addr(port, enum_index)); } -static inline unsigned long sh_eth_read(struct sh_eth_dev *eth, +static inline unsigned long sh_eth_read(struct sh_eth_info *port, int enum_index) { - return inl(sh_eth_reg_addr(eth, enum_index)); + return inl(sh_eth_reg_addr(port, enum_index)); } From aae5d237b97dd93ac932d3329c6fdab4bd84c85d Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Fri, 1 Dec 2017 13:56:08 +0900 Subject: [PATCH 19/21] net: sh-eth: Fix misaligned cache operation warning When we using network on board using sh-eth, it prints a lot of "CACHE: Misaligned operation at range" messages. This commit fixes this problem. Signed-off-by: Nobuhiro Iwamatsu Acked-by: Joe Hershberger --- drivers/net/sh_eth.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index f28f388ea9..6edb51e12f 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -29,7 +29,8 @@ #if defined(CONFIG_SH_ETHER_CACHE_WRITEBACK) && !defined(CONFIG_SYS_DCACHE_OFF) #define flush_cache_wback(addr, len) \ - flush_dcache_range((u32)addr, (u32)(addr + len - 1)) + flush_dcache_range((u32)addr, \ + (u32)(addr + ALIGN(len, CONFIG_SH_ETHER_ALIGNE_SIZE))) #else #define flush_cache_wback(...) #endif @@ -205,7 +206,7 @@ static int sh_eth_tx_desc_init(struct sh_eth_dev *eth) goto err; } - flush_cache_wback((u32)port_info->tx_desc_alloc, alloc_desc_size); + flush_cache_wback(port_info->tx_desc_alloc, alloc_desc_size); /* Make sure we use a P2 address (non-cacheable) */ port_info->tx_desc_base = From dcd18eaf6147c0c69d510883ee08ed1971c5b979 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Fri, 1 Dec 2017 16:08:03 +0900 Subject: [PATCH 20/21] net: sh-eth: Add to Kconfig and convert This adds SH_ETHER to drivers/net/Kconfig and convert to Kconfig. Signed-off-by: Nobuhiro Iwamatsu Acked-by: Joe Hershberger --- configs/alt_defconfig | 3 ++- configs/ap_sh4a_4a_defconfig | 3 ++- configs/armadillo-800eva_defconfig | 3 ++- configs/ecovec_defconfig | 3 ++- configs/espt_defconfig | 3 ++- configs/gose_defconfig | 3 ++- configs/koelsch_defconfig | 3 ++- configs/lager_defconfig | 3 ++- configs/porter_defconfig | 3 ++- configs/r0p7734_defconfig | 3 ++- configs/sh7752evb_defconfig | 3 ++- configs/sh7753evb_defconfig | 3 ++- configs/sh7757lcr_defconfig | 3 ++- configs/sh7763rdp_defconfig | 3 ++- configs/silk_defconfig | 3 ++- configs/stout_defconfig | 3 ++- drivers/net/Kconfig | 6 ++++++ include/configs/alt.h | 1 - include/configs/ap_sh4a_4a.h | 1 - include/configs/armadillo-800eva.h | 1 - include/configs/ecovec.h | 1 - include/configs/espt.h | 1 - include/configs/gose.h | 1 - include/configs/koelsch.h | 1 - include/configs/lager.h | 1 - include/configs/porter.h | 1 - include/configs/r0p7734.h | 1 - include/configs/sh7752evb.h | 1 - include/configs/sh7753evb.h | 1 - include/configs/sh7757lcr.h | 1 - include/configs/sh7763rdp.h | 1 - include/configs/silk.h | 1 - include/configs/stout.h | 1 - scripts/config_whitelist.txt | 1 - 34 files changed, 38 insertions(+), 33 deletions(-) diff --git a/configs/alt_defconfig b/configs/alt_defconfig index bf51e5388c..157d830ff1 100644 --- a/configs/alt_defconfig +++ b/configs/alt_defconfig @@ -24,7 +24,8 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_BAR=y CONFIG_SPI_FLASH_SPANSION=y -CONFIG_PHYLIB=y +CONFIG_NETDEVICES=y +CONFIG_SH_ETHER=y CONFIG_PHY_MICREL=y CONFIG_BAUDRATE=38400 CONFIG_SCIF_CONSOLE=y diff --git a/configs/ap_sh4a_4a_defconfig b/configs/ap_sh4a_4a_defconfig index ef14121273..976680aa51 100644 --- a/configs/ap_sh4a_4a_defconfig +++ b/configs/ap_sh4a_4a_defconfig @@ -25,6 +25,7 @@ CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_ENV_IS_IN_FLASH=y CONFIG_MTD_NOR_FLASH=y -CONFIG_PHYLIB=y +CONFIG_NETDEVICES=y +CONFIG_SH_ETHER=y CONFIG_SCIF_CONSOLE=y CONFIG_USE_PRIVATE_LIBGCC=y diff --git a/configs/armadillo-800eva_defconfig b/configs/armadillo-800eva_defconfig index d9a5169905..14d6c843ae 100644 --- a/configs/armadillo-800eva_defconfig +++ b/configs/armadillo-800eva_defconfig @@ -27,6 +27,7 @@ CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_ENV_IS_IN_FLASH=y # CONFIG_MMC is not set -CONFIG_PHYLIB=y +CONFIG_NETDEVICES=y +CONFIG_SH_ETHER=y CONFIG_SCIF_CONSOLE=y CONFIG_OF_LIBFDT=y diff --git a/configs/ecovec_defconfig b/configs/ecovec_defconfig index 5d65e9dc30..5c6c55fdb8 100644 --- a/configs/ecovec_defconfig +++ b/configs/ecovec_defconfig @@ -29,7 +29,8 @@ CONFIG_CMD_EXT2=y CONFIG_CMD_FAT=y CONFIG_ENV_IS_IN_FLASH=y CONFIG_MTD_NOR_FLASH=y -CONFIG_PHYLIB=y +CONFIG_NETDEVICES=y +CONFIG_SH_ETHER=y CONFIG_SCIF_CONSOLE=y CONFIG_USB=y CONFIG_USB_STORAGE=y diff --git a/configs/espt_defconfig b/configs/espt_defconfig index 520bc9fa53..32ba9d0f6e 100644 --- a/configs/espt_defconfig +++ b/configs/espt_defconfig @@ -25,6 +25,7 @@ CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_ENV_IS_IN_FLASH=y CONFIG_MTD_NOR_FLASH=y -CONFIG_PHYLIB=y +CONFIG_NETDEVICES=y +CONFIG_SH_ETHER=y CONFIG_SCIF_CONSOLE=y CONFIG_USE_PRIVATE_LIBGCC=y diff --git a/configs/gose_defconfig b/configs/gose_defconfig index bc3299033a..5f10d9a304 100644 --- a/configs/gose_defconfig +++ b/configs/gose_defconfig @@ -24,8 +24,9 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_BAR=y CONFIG_SPI_FLASH_SPANSION=y -CONFIG_PHYLIB=y CONFIG_PHY_MICREL=y +CONFIG_NETDEVICES=y +CONFIG_SH_ETHER=y CONFIG_BAUDRATE=38400 CONFIG_SCIF_CONSOLE=y CONFIG_USB=y diff --git a/configs/koelsch_defconfig b/configs/koelsch_defconfig index 5def33bac3..acc7289139 100644 --- a/configs/koelsch_defconfig +++ b/configs/koelsch_defconfig @@ -24,8 +24,9 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_BAR=y CONFIG_SPI_FLASH_SPANSION=y -CONFIG_PHYLIB=y CONFIG_PHY_MICREL=y +CONFIG_NETDEVICES=y +CONFIG_SH_ETHER=y CONFIG_BAUDRATE=38400 CONFIG_SCIF_CONSOLE=y CONFIG_USB=y diff --git a/configs/lager_defconfig b/configs/lager_defconfig index 5072045e89..c0778ee824 100644 --- a/configs/lager_defconfig +++ b/configs/lager_defconfig @@ -24,8 +24,9 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_BAR=y CONFIG_SPI_FLASH_SPANSION=y -CONFIG_PHYLIB=y CONFIG_PHY_MICREL=y +CONFIG_NETDEVICES=y +CONFIG_SH_ETHER=y CONFIG_BAUDRATE=38400 CONFIG_SCIF_CONSOLE=y CONFIG_USB=y diff --git a/configs/porter_defconfig b/configs/porter_defconfig index ac36dca972..7374a30ed2 100644 --- a/configs/porter_defconfig +++ b/configs/porter_defconfig @@ -24,8 +24,9 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_BAR=y CONFIG_SPI_FLASH_SPANSION=y -CONFIG_PHYLIB=y CONFIG_PHY_MICREL=y +CONFIG_NETDEVICES=y +CONFIG_SH_ETHER=y CONFIG_BAUDRATE=38400 CONFIG_SCIF_CONSOLE=y CONFIG_USB=y diff --git a/configs/r0p7734_defconfig b/configs/r0p7734_defconfig index e0b19bbb7f..342365d8c5 100644 --- a/configs/r0p7734_defconfig +++ b/configs/r0p7734_defconfig @@ -25,6 +25,7 @@ CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_ENV_IS_IN_FLASH=y CONFIG_MTD_NOR_FLASH=y -CONFIG_PHYLIB=y +CONFIG_NETDEVICES=y +CONFIG_SH_ETHER=y CONFIG_SCIF_CONSOLE=y CONFIG_USE_PRIVATE_LIBGCC=y diff --git a/configs/sh7752evb_defconfig b/configs/sh7752evb_defconfig index 3152859071..9e4f5aac32 100644 --- a/configs/sh7752evb_defconfig +++ b/configs/sh7752evb_defconfig @@ -34,6 +34,7 @@ CONFIG_MMC=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_MACRONIX=y CONFIG_SPI_FLASH_STMICRO=y -CONFIG_PHYLIB=y +CONFIG_NETDEVICES=y +CONFIG_SH_ETHER=y CONFIG_SCIF_CONSOLE=y CONFIG_USE_PRIVATE_LIBGCC=y diff --git a/configs/sh7753evb_defconfig b/configs/sh7753evb_defconfig index 259d6a7e3d..631f241af0 100644 --- a/configs/sh7753evb_defconfig +++ b/configs/sh7753evb_defconfig @@ -33,6 +33,7 @@ CONFIG_MMC=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_MACRONIX=y CONFIG_SPI_FLASH_STMICRO=y -CONFIG_PHYLIB=y +CONFIG_NETDEVICES=y +CONFIG_SH_ETHER=y CONFIG_SCIF_CONSOLE=y CONFIG_USE_PRIVATE_LIBGCC=y diff --git a/configs/sh7757lcr_defconfig b/configs/sh7757lcr_defconfig index b2e7362e2f..c7e30af0bd 100644 --- a/configs/sh7757lcr_defconfig +++ b/configs/sh7757lcr_defconfig @@ -33,6 +33,7 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_MMC=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_STMICRO=y -CONFIG_PHYLIB=y +CONFIG_NETDEVICES=y +CONFIG_SH_ETHER=y CONFIG_SCIF_CONSOLE=y CONFIG_USE_PRIVATE_LIBGCC=y diff --git a/configs/sh7763rdp_defconfig b/configs/sh7763rdp_defconfig index 693a873ddd..a211e4c897 100644 --- a/configs/sh7763rdp_defconfig +++ b/configs/sh7763rdp_defconfig @@ -26,6 +26,7 @@ CONFIG_CMD_PING=y CONFIG_CMD_JFFS2=y CONFIG_ENV_IS_IN_FLASH=y CONFIG_MTD_NOR_FLASH=y -CONFIG_PHYLIB=y +CONFIG_NETDEVICES=y +CONFIG_SH_ETHER=y CONFIG_SCIF_CONSOLE=y CONFIG_USE_PRIVATE_LIBGCC=y diff --git a/configs/silk_defconfig b/configs/silk_defconfig index 8af1e19d13..ffe1d8b784 100644 --- a/configs/silk_defconfig +++ b/configs/silk_defconfig @@ -24,8 +24,9 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_BAR=y CONFIG_SPI_FLASH_SPANSION=y -CONFIG_PHYLIB=y CONFIG_PHY_MICREL=y +CONFIG_NETDEVICES=y +CONFIG_SH_ETHER=y CONFIG_BAUDRATE=38400 CONFIG_SCIF_CONSOLE=y CONFIG_USB=y diff --git a/configs/stout_defconfig b/configs/stout_defconfig index b6e71e7186..6750dcdd79 100644 --- a/configs/stout_defconfig +++ b/configs/stout_defconfig @@ -24,8 +24,9 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_BAR=y CONFIG_SPI_FLASH_SPANSION=y -CONFIG_PHYLIB=y CONFIG_PHY_MICREL=y +CONFIG_NETDEVICES=y +CONFIG_SH_ETHER=y CONFIG_BAUDRATE=38400 CONFIG_SCIF_CONSOLE=y CONFIG_USB=y diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index c47d59c249..de1947ccc1 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -276,6 +276,12 @@ config SUN8I_EMAC It can be found in H3/A64/A83T based SoCs and compatible with both External and Internal PHYs. +config SH_ETHER + bool "Renesas SH Ethernet MAC" + select PHYLIB + help + This driver supports the Ethernet for Renesas SH and ARM SoCs. + config XILINX_AXIEMAC depends on DM_ETH && (MICROBLAZE || ARCH_ZYNQ || ARCH_ZYNQMP) select PHYLIB diff --git a/include/configs/alt.h b/include/configs/alt.h index 35518da625..e35ddc8ed8 100644 --- a/include/configs/alt.h +++ b/include/configs/alt.h @@ -44,7 +44,6 @@ #define CONFIG_SPI_FLASH_QUAD /* SH Ether */ -#define CONFIG_SH_ETHER #define CONFIG_SH_ETHER_USE_PORT 0 #define CONFIG_SH_ETHER_PHY_ADDR 0x1 #define CONFIG_SH_ETHER_PHY_MODE PHY_INTERFACE_MODE_RMII diff --git a/include/configs/ap_sh4a_4a.h b/include/configs/ap_sh4a_4a.h index 37aaec30c5..2a01000803 100644 --- a/include/configs/ap_sh4a_4a.h +++ b/include/configs/ap_sh4a_4a.h @@ -18,7 +18,6 @@ #undef CONFIG_SHOW_BOOT_PROGRESS /* Ether */ -#define CONFIG_SH_ETHER 1 #define CONFIG_SH_ETHER_USE_PORT (0) #define CONFIG_SH_ETHER_PHY_ADDR (0x0) #define CONFIG_SH_ETHER_PHY_MODE (PHY_INTERFACE_MODE_GMII) diff --git a/include/configs/armadillo-800eva.h b/include/configs/armadillo-800eva.h index 66ae76b2d2..94aecb7de1 100644 --- a/include/configs/armadillo-800eva.h +++ b/include/configs/armadillo-800eva.h @@ -88,7 +88,6 @@ #define CONFIG_ENV_SIZE_REDUND (CONFIG_ENV_SECT_SIZE) /* SH Ether */ -#define CONFIG_SH_ETHER #define CONFIG_SH_ETHER_USE_PORT 0 #define CONFIG_SH_ETHER_PHY_ADDR 0x0 #define CONFIG_SH_ETHER_BASE_ADDR 0xe9a00000 diff --git a/include/configs/ecovec.h b/include/configs/ecovec.h index c6fb59f753..32d679d019 100644 --- a/include/configs/ecovec.h +++ b/include/configs/ecovec.h @@ -44,7 +44,6 @@ #define CONFIG_SH_I2C_CLOCK 41666666 /* Ether */ -#define CONFIG_SH_ETHER 1 #define CONFIG_SH_ETHER_USE_PORT (0) #define CONFIG_SH_ETHER_PHY_ADDR (0x1f) #define CONFIG_PHY_SMSC 1 diff --git a/include/configs/espt.h b/include/configs/espt.h index a5ac8cb584..65221fce8e 100644 --- a/include/configs/espt.h +++ b/include/configs/espt.h @@ -77,7 +77,6 @@ #define CONFIG_SYS_TMU_CLK_DIV 4 /* Ether */ -#define CONFIG_SH_ETHER 1 #define CONFIG_SH_ETHER_USE_PORT (1) #define CONFIG_SH_ETHER_PHY_ADDR (0x00) #define CONFIG_BITBANGMII diff --git a/include/configs/gose.h b/include/configs/gose.h index 610ba1a7ac..fab0edd5e6 100644 --- a/include/configs/gose.h +++ b/include/configs/gose.h @@ -44,7 +44,6 @@ #define CONFIG_SH_QSPI /* SH Ether */ -#define CONFIG_SH_ETHER #define CONFIG_SH_ETHER_USE_PORT 0 #define CONFIG_SH_ETHER_PHY_ADDR 0x1 #define CONFIG_SH_ETHER_PHY_MODE PHY_INTERFACE_MODE_RMII diff --git a/include/configs/koelsch.h b/include/configs/koelsch.h index b9214d2f34..c449e43f95 100644 --- a/include/configs/koelsch.h +++ b/include/configs/koelsch.h @@ -44,7 +44,6 @@ #define CONFIG_SH_QSPI /* SH Ether */ -#define CONFIG_SH_ETHER #define CONFIG_SH_ETHER_USE_PORT 0 #define CONFIG_SH_ETHER_PHY_ADDR 0x1 #define CONFIG_SH_ETHER_PHY_MODE PHY_INTERFACE_MODE_RMII diff --git a/include/configs/lager.h b/include/configs/lager.h index 291b03c50b..000e5cd8f3 100644 --- a/include/configs/lager.h +++ b/include/configs/lager.h @@ -44,7 +44,6 @@ #define CONFIG_SH_QSPI /* SH Ether */ -#define CONFIG_SH_ETHER #define CONFIG_SH_ETHER_USE_PORT 0 #define CONFIG_SH_ETHER_PHY_ADDR 0x1 #define CONFIG_SH_ETHER_PHY_MODE PHY_INTERFACE_MODE_RMII diff --git a/include/configs/porter.h b/include/configs/porter.h index 451d9dd66f..10dce6b476 100644 --- a/include/configs/porter.h +++ b/include/configs/porter.h @@ -45,7 +45,6 @@ #define CONFIG_SPI_FLASH_QUAD /* SH Ether */ -#define CONFIG_SH_ETHER #define CONFIG_SH_ETHER_USE_PORT 0 #define CONFIG_SH_ETHER_PHY_ADDR 0x1 #define CONFIG_SH_ETHER_PHY_MODE PHY_INTERFACE_MODE_RMII diff --git a/include/configs/r0p7734.h b/include/configs/r0p7734.h index 9258a3bcde..f9800ec168 100644 --- a/include/configs/r0p7734.h +++ b/include/configs/r0p7734.h @@ -18,7 +18,6 @@ #undef CONFIG_SHOW_BOOT_PROGRESS /* Ether */ -#define CONFIG_SH_ETHER 1 #define CONFIG_SH_ETHER_USE_PORT (0) #define CONFIG_SH_ETHER_PHY_ADDR (0x0) #define CONFIG_PHY_SMSC 1 diff --git a/include/configs/sh7752evb.h b/include/configs/sh7752evb.h index 2f81cc5bf9..ee57eb2fd1 100644 --- a/include/configs/sh7752evb.h +++ b/include/configs/sh7752evb.h @@ -47,7 +47,6 @@ #define CONFIG_SYS_BOOTMAPSZ (8 * 1024 * 1024) /* Ether */ -#define CONFIG_SH_ETHER 1 #define CONFIG_SH_ETHER_USE_PORT 0 #define CONFIG_SH_ETHER_PHY_ADDR 18 #define CONFIG_SH_ETHER_CACHE_WRITEBACK 1 diff --git a/include/configs/sh7753evb.h b/include/configs/sh7753evb.h index bcb85a6bd8..e7f9f61974 100644 --- a/include/configs/sh7753evb.h +++ b/include/configs/sh7753evb.h @@ -47,7 +47,6 @@ #define CONFIG_SYS_BOOTMAPSZ (8 * 1024 * 1024) /* Ether */ -#define CONFIG_SH_ETHER 1 #define CONFIG_SH_ETHER_USE_PORT 0 #define CONFIG_SH_ETHER_PHY_ADDR 18 #define CONFIG_SH_ETHER_CACHE_WRITEBACK 1 diff --git a/include/configs/sh7757lcr.h b/include/configs/sh7757lcr.h index bee1a1da51..a2b3307804 100644 --- a/include/configs/sh7757lcr.h +++ b/include/configs/sh7757lcr.h @@ -48,7 +48,6 @@ #define CONFIG_SYS_BOOTMAPSZ (8 * 1024 * 1024) /* Ether */ -#define CONFIG_SH_ETHER 1 #define CONFIG_SH_ETHER_USE_PORT 0 #define CONFIG_SH_ETHER_PHY_ADDR 1 #define CONFIG_SH_ETHER_CACHE_WRITEBACK 1 diff --git a/include/configs/sh7763rdp.h b/include/configs/sh7763rdp.h index 0598b25154..de4a587914 100644 --- a/include/configs/sh7763rdp.h +++ b/include/configs/sh7763rdp.h @@ -77,7 +77,6 @@ #define CONFIG_SYS_TMU_CLK_DIV (4) /* 4 (default), 16, 64, 256 or 1024 */ /* Ether */ -#define CONFIG_SH_ETHER 1 #define CONFIG_SH_ETHER_USE_PORT (1) #define CONFIG_SH_ETHER_PHY_ADDR (0x01) #define CONFIG_BITBANGMII diff --git a/include/configs/silk.h b/include/configs/silk.h index 0384325cb5..79a4f06c0b 100644 --- a/include/configs/silk.h +++ b/include/configs/silk.h @@ -45,7 +45,6 @@ #define CONFIG_SPI_FLASH_QUAD /* SH Ether */ -#define CONFIG_SH_ETHER #define CONFIG_SH_ETHER_USE_PORT 0 #define CONFIG_SH_ETHER_PHY_ADDR 0x1 #define CONFIG_SH_ETHER_PHY_MODE PHY_INTERFACE_MODE_RMII diff --git a/include/configs/stout.h b/include/configs/stout.h index 9422c042f3..789f364168 100644 --- a/include/configs/stout.h +++ b/include/configs/stout.h @@ -48,7 +48,6 @@ #define CONFIG_SPI_FLASH_QUAD /* SH Ether */ -#define CONFIG_SH_ETHER #define CONFIG_SH_ETHER_USE_PORT 0 #define CONFIG_SH_ETHER_PHY_ADDR 0x1 #define CONFIG_SH_ETHER_PHY_MODE PHY_INTERFACE_MODE_RMII diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index 4e87d66bea..394243b3d2 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -1924,7 +1924,6 @@ CONFIG_SHOW_ACTIVITY CONFIG_SHOW_BOOT_PROGRESS CONFIG_SH_CMT_CLK_FREQ CONFIG_SH_DSP -CONFIG_SH_ETHER CONFIG_SH_ETHER_ALIGNE_SIZE CONFIG_SH_ETHER_BASE_ADDR CONFIG_SH_ETHER_CACHE_INVALIDATE From 1e2d2597a667e16adfe0a8a9be22e904cee84727 Mon Sep 17 00:00:00 2001 From: Zhao Qiang Date: Thu, 14 Dec 2017 09:50:46 +0800 Subject: [PATCH 21/21] phy: atheros: set auto-negotiation for AR8021 Signed-off-by: Zhao Qiang Acked-by: Joe Hershberger --- drivers/net/phy/atheros.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/phy/atheros.c b/drivers/net/phy/atheros.c index b34cdd3d87..d7e76deeb7 100644 --- a/drivers/net/phy/atheros.c +++ b/drivers/net/phy/atheros.c @@ -19,6 +19,7 @@ static int ar8021_config(struct phy_device *phydev) { + phy_write(phydev, MDIO_DEVAD_NONE, 0x00, 0x1200); phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05); phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x3D47);