From b3eabd82f21b4d9206622fc5aee16751d2f4be8f Mon Sep 17 00:00:00 2001 From: Pankaj Bansal Date: Fri, 16 Nov 2018 06:26:18 +0000 Subject: [PATCH 01/17] net: phy: Add clause 45 identifier to phy_device The phy devices can be accessed via clause 22 or via clause 45. This information can be deduced when we read phy id. if the phy id is read without giving any MDIO Manageable Device Address (MMD), then it conforms to clause 22. otherwise it conforms to clause 45. Signed-off-by: Pankaj Bansal Acked-by: Joe Hershberger --- drivers/net/phy/phy.c | 15 ++++++++++----- include/phy.h | 1 + 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index cda4caa803..78205a3948 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -620,7 +620,7 @@ static struct phy_driver *get_phy_driver(struct phy_device *phydev, } static struct phy_device *phy_device_create(struct mii_dev *bus, int addr, - u32 phy_id, + u32 phy_id, bool is_c45, phy_interface_t interface) { struct phy_device *dev; @@ -650,6 +650,7 @@ static struct phy_device *phy_device_create(struct mii_dev *bus, int addr, dev->addr = addr; dev->phy_id = phy_id; + dev->is_c45 = is_c45; dev->bus = bus; dev->drv = get_phy_driver(dev, interface); @@ -702,13 +703,17 @@ static struct phy_device *create_phy_by_mask(struct mii_dev *bus, phy_interface_t interface) { u32 phy_id = 0xffffffff; + bool is_c45; while (phy_mask) { int addr = ffs(phy_mask) - 1; int r = get_phy_id(bus, addr, devad, &phy_id); /* If the PHY ID is mostly f's, we didn't find anything */ - if (r == 0 && (phy_id & 0x1fffffff) != 0x1fffffff) - return phy_device_create(bus, addr, phy_id, interface); + if (r == 0 && (phy_id & 0x1fffffff) != 0x1fffffff) { + is_c45 = (devad == MDIO_DEVAD_NONE) ? false : true; + return phy_device_create(bus, addr, phy_id, is_c45, + interface); + } phy_mask &= ~(1 << addr); } return NULL; @@ -895,8 +900,8 @@ struct phy_device *phy_connect(struct mii_dev *bus, int addr, while (sn > 0) { name = fdt_get_name(gd->fdt_blob, sn, NULL); if (name && strcmp(name, "fixed-link") == 0) { - phydev = phy_device_create(bus, - sn, PHY_FIXED_ID, interface); + phydev = phy_device_create(bus, sn, PHY_FIXED_ID, false, + interface); break; } sn = fdt_next_subnode(gd->fdt_blob, sn); diff --git a/include/phy.h b/include/phy.h index b86fdfb2ce..f23ca63f3b 100644 --- a/include/phy.h +++ b/include/phy.h @@ -138,6 +138,7 @@ struct phy_device { int pause; int asym_pause; u32 phy_id; + bool is_c45; u32 flags; }; From ae8ac8d423675904fdbf1510ad71e37d71db0568 Mon Sep 17 00:00:00 2001 From: Simon Goldschmidt Date: Sat, 17 Nov 2018 10:24:41 +0100 Subject: [PATCH 02/17] net: designware: fix tx packet length The designware driver has a bug in setting the tx length into the dma descriptor: it always or's the length into the descriptor without zeroing out the length mask before. This results in occasional packets being transmitted with a length greater than they should be (trailer). Due to the nature of Ethernet allowing such a trailer, most packets seem to be parsed fine by remote hosts, which is probably why this hasn't been noticed. Fix this by correctly clearing the size mask before setting the new length. Tested on socfpga gen5. Signed-off-by: Simon Goldschmidt Acked-by: Joe Hershberger Reviewed-by: Philipp Tomsich --- drivers/net/designware.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/net/designware.c b/drivers/net/designware.c index 4fa26abc1b..01abcc21d2 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -389,15 +389,17 @@ static int _dw_eth_send(struct dw_eth_dev *priv, void *packet, int length) #if defined(CONFIG_DW_ALTDESCRIPTOR) desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST; - desc_p->dmamac_cntl |= (length << DESC_TXCTRL_SIZE1SHFT) & - DESC_TXCTRL_SIZE1MASK; + desc_p->dmamac_cntl = (desc_p->dmamac_cntl & ~DESC_TXCTRL_SIZE1MASK) | + ((length << DESC_TXCTRL_SIZE1SHFT) & + DESC_TXCTRL_SIZE1MASK); desc_p->txrx_status &= ~(DESC_TXSTS_MSK); desc_p->txrx_status |= DESC_TXSTS_OWNBYDMA; #else - desc_p->dmamac_cntl |= ((length << DESC_TXCTRL_SIZE1SHFT) & - DESC_TXCTRL_SIZE1MASK) | DESC_TXCTRL_TXLAST | - DESC_TXCTRL_TXFIRST; + desc_p->dmamac_cntl = (desc_p->dmamac_cntl & ~DESC_TXCTRL_SIZE1MASK) | + ((length << DESC_TXCTRL_SIZE1SHFT) & + DESC_TXCTRL_SIZE1MASK) | DESC_TXCTRL_TXLAST | + DESC_TXCTRL_TXFIRST; desc_p->txrx_status = DESC_TXSTS_OWNBYDMA; #endif From 7efb75b11480c46077b44df70aa30d375bf761be Mon Sep 17 00:00:00 2001 From: Simon Goldschmidt Date: Sat, 17 Nov 2018 10:24:42 +0100 Subject: [PATCH 03/17] net: designware: clear padding bytes Short frames are padded to the minimum allowed size of 60 bytes. However, the designware driver sends old data in these padding bytes. It is common practice to zero out these padding bytes ro prevent leaking memory contents to other hosts. Fix the padding code to zero out the padded bytes at the end. Tested on socfpga gen5. Signed-off-by: Simon Goldschmidt Acked-by: Joe Hershberger --- drivers/net/designware.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/designware.c b/drivers/net/designware.c index 01abcc21d2..2c5d9560c5 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -380,9 +380,11 @@ 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); + if (length < ETH_ZLEN) { + memset(&((char *)data_start)[length], 0, ETH_ZLEN - length); + length = ETH_ZLEN; + } /* Flush data to be sent */ flush_dcache_range(data_start, data_end); From acce753dfb6d297c9f779dd04bb24d0004e6bc64 Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Wed, 21 Nov 2018 13:05:33 +0200 Subject: [PATCH 04/17] net: mvpp2: fix lookup of mdio registers base address Current mdio base lookup code relies on a 'reg' property at the upper CP node. There is no 'reg' property there in current DT files of Armada CP110. Use ofnode_get_addr() instead since it provides proper DT address translation. Cc: Ken Ma Cc: Stefan Chulski Signed-off-by: Baruch Siach Reviewed-by: Stefan Roese Acked-by: Joe Hershberger --- drivers/net/mvpp2.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/net/mvpp2.c b/drivers/net/mvpp2.c index 9b3ab25c19..23c4da8ceb 100644 --- a/drivers/net/mvpp2.c +++ b/drivers/net/mvpp2.c @@ -4705,21 +4705,22 @@ static int phy_info_parse(struct udevice *dev, struct mvpp2_port *port) { int port_node = dev_of_offset(dev); const char *phy_mode_str; - int phy_node, mdio_off, cp_node; + int phy_node; u32 id; u32 phyaddr = 0; int phy_mode = -1; - phys_addr_t mdio_addr; phy_node = fdtdec_lookup_phandle(gd->fdt_blob, port_node, "phy"); if (phy_node > 0) { + ofnode phy_ofnode; + fdt_addr_t phy_base; + phyaddr = fdtdec_get_int(gd->fdt_blob, phy_node, "reg", 0); if (phyaddr < 0) { dev_err(&pdev->dev, "could not find phy address\n"); return -1; } - mdio_off = fdt_parent_offset(gd->fdt_blob, phy_node); /* TODO: This WA for mdio issue. U-boot 2017 don't have * mdio driver and on MACHIATOBin board ports from CP1 @@ -4728,14 +4729,10 @@ static int phy_info_parse(struct udevice *dev, struct mvpp2_port *port) * base address. WA should be removed after * mdio driver implementation. */ - mdio_addr = fdtdec_get_uint(gd->fdt_blob, - mdio_off, "reg", 0); - cp_node = fdt_parent_offset(gd->fdt_blob, mdio_off); - mdio_addr |= fdt_get_base_address((void *)gd->fdt_blob, - cp_node); - - port->priv->mdio_base = (void *)mdio_addr; + phy_ofnode = ofnode_get_parent(offset_to_ofnode(phy_node)); + phy_base = ofnode_get_addr(phy_ofnode); + port->priv->mdio_base = (void *)phy_base; if (port->priv->mdio_base < 0) { dev_err(&pdev->dev, "could not find mdio base address\n"); From 21586cdd50dbcb9572514d5288f8cbdc17e23264 Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Wed, 21 Nov 2018 13:05:34 +0200 Subject: [PATCH 05/17] net: mvpp2: mdio device per port Current code forces all ports on a given Ethernet device to use the same mdio device. In practice different ports might be wired to separate mdio devices. Move the mdio device from the container struct mvpp2 to the per port struct mvpp2_port. Cc: Ken Ma Cc: Stefan Chulski Signed-off-by: Baruch Siach Reviewed-by: Stefan Roese Acked-by: Joe Hershberger --- drivers/net/mvpp2.c | 75 ++++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/drivers/net/mvpp2.c b/drivers/net/mvpp2.c index 23c4da8ceb..bcc6fe92a9 100644 --- a/drivers/net/mvpp2.c +++ b/drivers/net/mvpp2.c @@ -897,7 +897,6 @@ struct mvpp2 { void __iomem *base; void __iomem *lms_base; void __iomem *iface_base; - void __iomem *mdio_base; void __iomem *mpcs_base; void __iomem *xpcs_base; @@ -928,8 +927,6 @@ struct mvpp2 { /* Maximum number of RXQs per port */ unsigned int max_port_rxqs; - struct mii_dev *bus; - int probe_done; u8 num_ports; }; @@ -955,6 +952,7 @@ struct mvpp2_port { /* Per-port registers' base address */ void __iomem *base; + void __iomem *mdio_base; struct mvpp2_rx_queue **rxqs; struct mvpp2_tx_queue **txqs; @@ -977,6 +975,7 @@ struct mvpp2_port { phy_interface_t phy_interface; int phy_node; int phyaddr; + struct mii_dev *bus; #ifdef CONFIG_DM_GPIO struct gpio_desc phy_reset_gpio; struct gpio_desc phy_tx_disable_gpio; @@ -4500,7 +4499,7 @@ static int mvpp2_phy_connect(struct udevice *dev, struct mvpp2_port *port) struct phy_device *phy_dev; if (!port->init || port->link == 0) { - phy_dev = phy_connect(port->priv->bus, port->phyaddr, dev, + phy_dev = phy_connect(port->bus, port->phyaddr, dev, port->phy_interface); port->phy_dev = phy_dev; if (!phy_dev) { @@ -4710,6 +4709,12 @@ static int phy_info_parse(struct udevice *dev, struct mvpp2_port *port) u32 phyaddr = 0; int phy_mode = -1; + /* Default mdio_base from the same eth base */ + if (port->priv->hw_version == MVPP21) + port->mdio_base = port->priv->lms_base + MVPP21_SMI; + else + port->mdio_base = port->priv->iface_base + MVPP22_SMI; + phy_node = fdtdec_lookup_phandle(gd->fdt_blob, port_node, "phy"); if (phy_node > 0) { @@ -4722,19 +4727,11 @@ static int phy_info_parse(struct udevice *dev, struct mvpp2_port *port) return -1; } - /* TODO: This WA for mdio issue. U-boot 2017 don't have - * mdio driver and on MACHIATOBin board ports from CP1 - * connected to mdio on CP0. - * WA is to get mdio address from phy handler parent - * base address. WA should be removed after - * mdio driver implementation. - */ - phy_ofnode = ofnode_get_parent(offset_to_ofnode(phy_node)); phy_base = ofnode_get_addr(phy_ofnode); - port->priv->mdio_base = (void *)phy_base; + port->mdio_base = (void *)phy_base; - if (port->priv->mdio_base < 0) { + if (port->mdio_base < 0) { dev_err(&pdev->dev, "could not find mdio base address\n"); return -1; } @@ -5056,7 +5053,7 @@ static int mvpp2_init(struct udevice *dev, struct mvpp2 *priv) /* SMI / MDIO functions */ -static int smi_wait_ready(struct mvpp2 *priv) +static int smi_wait_ready(struct mvpp2_port *priv) { u32 timeout = MVPP2_SMI_TIMEOUT; u32 smi_reg; @@ -5081,7 +5078,7 @@ static int smi_wait_ready(struct mvpp2 *priv) */ static int mpp2_mdio_read(struct mii_dev *bus, int addr, int devad, int reg) { - struct mvpp2 *priv = bus->priv; + struct mvpp2_port *priv = bus->priv; u32 smi_reg; u32 timeout; @@ -5136,7 +5133,7 @@ static int mpp2_mdio_read(struct mii_dev *bus, int addr, int devad, int reg) static int mpp2_mdio_write(struct mii_dev *bus, int addr, int devad, int reg, u16 value) { - struct mvpp2 *priv = bus->priv; + struct mvpp2_port *priv = bus->priv; u32 smi_reg; /* check parameters */ @@ -5335,7 +5332,6 @@ static int mvpp22_smi_phy_addr_cfg(struct mvpp2_port *port) static int mvpp2_base_probe(struct udevice *dev) { struct mvpp2 *priv = dev_get_priv(dev); - struct mii_dev *bus; void *bd_space; u32 size = 0; int i; @@ -5394,15 +5390,11 @@ static int mvpp2_base_probe(struct udevice *dev) priv->lms_base = (void *)devfdt_get_addr_index(dev, 1); if (IS_ERR(priv->lms_base)) return PTR_ERR(priv->lms_base); - - priv->mdio_base = priv->lms_base + MVPP21_SMI; } else { priv->iface_base = (void *)devfdt_get_addr_index(dev, 1); if (IS_ERR(priv->iface_base)) return PTR_ERR(priv->iface_base); - priv->mdio_base = priv->iface_base + MVPP22_SMI; - /* Store common base addresses for all ports */ priv->mpcs_base = priv->iface_base + MVPP22_MPCS; priv->xpcs_base = priv->iface_base + MVPP22_XPCS; @@ -5414,7 +5406,23 @@ static int mvpp2_base_probe(struct udevice *dev) else priv->max_port_rxqs = 32; - /* Finally create and register the MDIO bus driver */ + return 0; +} + +static int mvpp2_probe(struct udevice *dev) +{ + struct mvpp2_port *port = dev_get_priv(dev); + struct mvpp2 *priv = dev_get_priv(dev->parent); + struct mii_dev *bus; + int err; + + /* Only call the probe function for the parent once */ + if (!priv->probe_done) + err = mvpp2_base_probe(dev->parent); + + port->priv = dev_get_priv(dev->parent); + + /* Create and register the MDIO bus driver */ bus = mdio_alloc(); if (!bus) { printf("Failed to allocate MDIO bus\n"); @@ -5424,23 +5432,12 @@ static int mvpp2_base_probe(struct udevice *dev) bus->read = mpp2_mdio_read; bus->write = mpp2_mdio_write; snprintf(bus->name, sizeof(bus->name), dev->name); - bus->priv = (void *)priv; - priv->bus = bus; + bus->priv = (void *)port; + port->bus = bus; - return mdio_register(bus); -} - -static int mvpp2_probe(struct udevice *dev) -{ - struct mvpp2_port *port = dev_get_priv(dev); - struct mvpp2 *priv = dev_get_priv(dev->parent); - int err; - - /* Only call the probe function for the parent once */ - if (!priv->probe_done) - err = mvpp2_base_probe(dev->parent); - - port->priv = dev_get_priv(dev->parent); + err = mdio_register(bus); + if (err) + return err; err = phy_info_parse(dev, port); if (err) From a735e6e9d639114d67e4440f9e051a89d2094118 Mon Sep 17 00:00:00 2001 From: Thomas RIENOESSL Date: Wed, 21 Nov 2018 15:56:07 +0100 Subject: [PATCH 06/17] net: explicitly assign errno to return code in case of network failure When dealing with two ethernet ports and having "netretry" set to "once", it could occur that the connection (e.g. an ARP request) failed, hence the status of the netloop was "NETLOOP_FAIL". Due to the setting of "netretry", the network logic would then switch to the other network interface, assigning "ret" with the return value of "net_start_again()". If this call succeeded we would return 0 (i.e. success) to the caller when in reality the network action failed. Signed-off-by: Thomas RIENOESSL Reviewed-by: Christian Gmeiner Acked-by: Joe Hershberger --- net/net.c | 1 + test/dm/eth.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/net/net.c b/net/net.c index a5a216c3ee..e9f7a7d85e 100644 --- a/net/net.c +++ b/net/net.c @@ -657,6 +657,7 @@ restart: /* Invalidate the last protocol */ eth_set_last_protocol(BOOTP); debug_cond(DEBUG_INT_STATE, "--- net_loop Fail!\n"); + ret = -ENONET; goto done; case NETLOOP_CONTINUE: diff --git a/test/dm/eth.c b/test/dm/eth.c index 850eabb9dc..6e002b8dce 100644 --- a/test/dm/eth.c +++ b/test/dm/eth.c @@ -237,7 +237,7 @@ static int _dm_test_net_retry(struct unit_test_state *uts) env_set("ethact", "eth@10004000"); env_set("netretry", "no"); sandbox_eth_skip_timeout(); - ut_asserteq(-ETIMEDOUT, net_loop(PING)); + ut_asserteq(-ENONET, net_loop(PING)); ut_asserteq_str("eth@10004000", env_get("ethact")); return 0; From 6880efdf5aa63ba3d598af68dbbbc2511a1a604f Mon Sep 17 00:00:00 2001 From: Simon Goldschmidt Date: Thu, 22 Nov 2018 16:58:32 +0100 Subject: [PATCH 07/17] net: remove duplicate definition of ETHADDR_WILDCARD ETHADDR_WILDCARD is defined as the same value in both env_flags.h and env_callback.h As env_callback.h includes env_flags.h, remove the duplicate definition from env_callback.h Signed-off-by: Simon Goldschmidt Acked-by: Joe Hershberger --- include/env_callback.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/env_callback.h b/include/env_callback.h index 3c44ff574b..507a52e13c 100644 --- a/include/env_callback.h +++ b/include/env_callback.h @@ -32,10 +32,8 @@ #ifdef CONFIG_REGEX #define ENV_DOT_ESCAPE "\\" -#define ETHADDR_WILDCARD "\\d?" #else #define ENV_DOT_ESCAPE -#define ETHADDR_WILDCARD #endif #ifdef CONFIG_CMD_DNS From be09f5bc7c0c3f0d0bc7b88d23dae883bfa4e014 Mon Sep 17 00:00:00 2001 From: Simon Goldschmidt Date: Thu, 22 Nov 2018 17:06:39 +0100 Subject: [PATCH 08/17] net: fix env flags for eth10addr and above With CONFIG_REGEX enabled, ETHADDR_WILDCARD is set up for up to 10 interfaces (0..9) as the number can only have one digit. On boards with more than 10 interfaces, this leads to the protection and format checks being absent for eth10addr and above. Fix this by changing ETHADDR_WILDCARD from "\\d?" to "\\d*" to allow more than one digit. Signed-off-by: Simon Goldschmidt Acked-by: Joe Hershberger --- include/env_flags.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/env_flags.h b/include/env_flags.h index cc2c34f939..23744e395c 100644 --- a/include/env_flags.h +++ b/include/env_flags.h @@ -38,7 +38,7 @@ enum env_flags_varaccess { #ifdef CONFIG_CMD_NET #ifdef CONFIG_REGEX -#define ETHADDR_WILDCARD "\\d?" +#define ETHADDR_WILDCARD "\\d*" #else #define ETHADDR_WILDCARD #endif From 3b4cda34d48ab997e788be5fb9cbd5151f1e7c2e Mon Sep 17 00:00:00 2001 From: Andreas Pretzsch Date: Thu, 29 Nov 2018 20:04:53 +0100 Subject: [PATCH 09/17] net: phy: micrel: fix KSZ9031 clock skew for values greater 0ps For KSZ9021, all skew register fields are 4-bit wide. For KSZ9031, the clock skew register fields are 5-bit wide. The common code in ksz90x1_of_config_group calculating the combined register value checks if the requested value is above the maximum and uses this maximum if so. The calculation of this maximum uses the register width, but the check itself does not. It uses a hardcoded value of 0xf, which is too low in case of the 5-bit clock (0x1f). This detail was probably lost during driver unification. Effect (only for KSZ9031 clock skews): For values greater 900 (== 0ps), this silently results in 1860 (== +960ps) instead of the requested one. Fix the check by using the bit width instead of hardcoded value(s). Signed-off-by: Andreas Pretzsch Acked-by: Joe Hershberger --- drivers/net/phy/micrel_ksz90x1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/phy/micrel_ksz90x1.c b/drivers/net/phy/micrel_ksz90x1.c index 3951535bf1..63e7b0242b 100644 --- a/drivers/net/phy/micrel_ksz90x1.c +++ b/drivers/net/phy/micrel_ksz90x1.c @@ -123,8 +123,8 @@ static int ksz90x1_of_config_group(struct phy_device *phydev, } else { changed = 1; /* Value was changed in OF */ /* Calculate the register value and fix corner cases */ - if (val[i] > ps_to_regval * 0xf) { - max = (1 << ofcfg->grp[i].size) - 1; + max = (1 << ofcfg->grp[i].size) - 1; + if (val[i] > ps_to_regval * max) { regval |= max << offset; } else { regval |= (val[i] / ps_to_regval) << offset; From 92f129f4a098a47bbf889ea31e94edaa16edf256 Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Tue, 4 Dec 2018 19:54:30 +1300 Subject: [PATCH 10/17] net: mvgbe: fallback phy-mode to GMII Some existing device trees don't specify a phy-mode so fallback to GMII when a phy-mode is not provided. Signed-off-by: Chris Packham Reviewed-by: Stefan Roese Acked-by: Joe Hershberger --- drivers/net/mvgbe.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/mvgbe.c b/drivers/net/mvgbe.c index 74fed7abd8..037e59ec6e 100644 --- a/drivers/net/mvgbe.c +++ b/drivers/net/mvgbe.c @@ -1005,10 +1005,8 @@ static int mvgbe_ofdata_to_platdata(struct udevice *dev) phy_mode = fdt_getprop(gd->fdt_blob, pnode, "phy-mode", NULL); if (phy_mode) pdata->phy_interface = phy_get_interface_by_name(phy_mode); - if (pdata->phy_interface == -1) { - debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode); - return -EINVAL; - } + else + pdata->phy_interface = PHY_INTERFACE_MODE_GMII; dmvgbe->phy_interface = pdata->phy_interface; From 18bfc8fa84cd6d748c134b6265786f7d8226f86c Mon Sep 17 00:00:00 2001 From: Aditya Prayoga Date: Wed, 5 Dec 2018 00:39:23 +0800 Subject: [PATCH 11/17] net: mvneta: Add GPIO configuration support This patch add GPIO configuration support in mvneta driver. Driver will handle PHY reset. GPIO pins should be set in device tree. Ported from mvpp2x [https://patchwork.ozlabs.org/patch/799654/] Initial discussion to port the changes into mvneta [https://patchwork.ozlabs.org/patch/1005765/] Signed-off-by: Aditya Prayoga Tested-by: Dennis Gilmore Reviewed-by: Stefan Roese Acked-by: Joe Hershberger --- drivers/net/mvneta.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/net/mvneta.c b/drivers/net/mvneta.c index 8cb04b52d7..333be8ff28 100644 --- a/drivers/net/mvneta.c +++ b/drivers/net/mvneta.c @@ -27,6 +27,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -274,6 +275,9 @@ struct mvneta_port { int init; int phyaddr; struct phy_device *phydev; +#ifdef CONFIG_DM_GPIO + struct gpio_desc phy_reset_gpio; +#endif struct mii_dev *bus; }; @@ -1749,6 +1753,17 @@ static int mvneta_probe(struct udevice *dev) if (ret) return ret; +#ifdef CONFIG_DM_GPIO + gpio_request_by_name(dev, "phy-reset-gpios", 0, + &pp->phy_reset_gpio, GPIOD_IS_OUT); + + if (dm_gpio_is_valid(&pp->phy_reset_gpio)) { + dm_gpio_set_value(&pp->phy_reset_gpio, 1); + mdelay(10); + dm_gpio_set_value(&pp->phy_reset_gpio, 0); + } +#endif + return board_network_enable(bus); } From 9043c4e0fc130aba5a1f4161885c9d97b5d8a73f Mon Sep 17 00:00:00 2001 From: Ramon Fried Date: Thu, 27 Dec 2018 19:58:42 +0200 Subject: [PATCH 12/17] net: macb: fix mapping of registers Some architectures (MIPS) needs mapping to access IOMEM. Fix that. Fixes: f1dcc19b213d ("net: macb: Convert to driver model") Signed-off-by: Ramon Fried Acked-by: Joe Hershberger --- drivers/net/macb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 94c89c762b..c9ee22279a 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -1151,7 +1151,9 @@ static int macb_eth_ofdata_to_platdata(struct udevice *dev) { struct eth_pdata *pdata = dev_get_platdata(dev); - pdata->iobase = devfdt_get_addr(dev); + pdata->iobase = (phys_addr_t)dev_remap_addr(dev); + if (!pdata->iobase) + return -EINVAL; return macb_late_eth_ofdata_to_platdata(dev); } From e57c9fdb042741e4049661074c25e7b7ff8a68cc Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Wed, 16 Jan 2019 11:34:50 +0000 Subject: [PATCH 13/17] net: phy: realtek: Add functions to read PHY's extended registers According to the datasheet to access the extended registers we have to: 1. Write Register 31 Data = 0x0XYZ (Page 0xXYZ) 2. Read/Write the target Register Data 3. Write Register 31 Data = 0x0000 or 0xa42 (switch back to IEEE Standard Registers) Hook the missing functions so that we can use the `mdio rx/wx` command to easily access the extended registers. Signed-off-by: Carlo Caione Acked-by: Joe Hershberger --- drivers/net/phy/realtek.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index b3e6578df9..dd45e11b3a 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -57,6 +57,33 @@ #define MIIM_RTL8211F_TX_DELAY 0x100 #define MIIM_RTL8211F_LCR 0x10 +static int rtl8211f_phy_extread(struct phy_device *phydev, int addr, + int devaddr, int regnum) +{ + int oldpage = phy_read(phydev, MDIO_DEVAD_NONE, + MIIM_RTL8211F_PAGE_SELECT); + int val; + + phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, devaddr); + val = phy_read(phydev, MDIO_DEVAD_NONE, regnum); + phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, oldpage); + + return val; +} + +static int rtl8211f_phy_extwrite(struct phy_device *phydev, int addr, + int devaddr, int regnum, u16 val) +{ + int oldpage = phy_read(phydev, MDIO_DEVAD_NONE, + MIIM_RTL8211F_PAGE_SELECT); + + phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, devaddr); + phy_write(phydev, MDIO_DEVAD_NONE, regnum, val); + phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, oldpage); + + return 0; +} + static int rtl8211b_probe(struct phy_device *phydev) { #ifdef CONFIG_RTL8211X_PHY_FORCE_MASTER @@ -336,6 +363,8 @@ static struct phy_driver RTL8211F_driver = { .config = &rtl8211f_config, .startup = &rtl8211f_startup, .shutdown = &genphy_shutdown, + .readext = &rtl8211f_phy_extread, + .writeext = &rtl8211f_phy_extwrite, }; int phy_realtek_init(void) From 1a4af5c562fdb9f5a884a53f136f2b2075ffd1d8 Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Mon, 26 Nov 2018 21:00:28 +1300 Subject: [PATCH 14/17] net: move ether_crc to tsec driver ether_crc was added to the core net code in commit 53a5c424bf86 ("multicast tftp: RFC2090") so that other drivers could use it. However the only current user of it is tsec.c so move it there. Signed-off-by: Chris Packham Acked-by: Joe Hershberger --- drivers/net/tsec.c | 25 +++++++++++++++++++++++++ include/net.h | 1 - net/eth_legacy.c | 24 ------------------------ 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index 03a46da2f8..9a4fab85e9 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -80,6 +80,31 @@ static void tsec_configure_serdes(struct tsec_private *priv) #ifdef CONFIG_MCAST_TFTP +/* the 'way' for ethernet-CRC-32. Spliced in from Linux lib/crc32.c + * and this is the ethernet-crc method needed for TSEC -- and perhaps + * some other adapter -- hash tables + */ +#define CRCPOLY_LE 0xedb88320 +static u32 ether_crc(size_t len, unsigned char const *p) +{ + int i; + u32 crc; + + crc = ~0; + while (len--) { + crc ^= *p++; + for (i = 0; i < 8; i++) + crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0); + } + /* an reverse the bits, cuz of way they arrive -- last-first */ + crc = (crc >> 16) | (crc << 16); + crc = (crc >> 8 & 0x00ff00ff) | (crc << 8 & 0xff00ff00); + crc = (crc >> 4 & 0x0f0f0f0f) | (crc << 4 & 0xf0f0f0f0); + crc = (crc >> 2 & 0x33333333) | (crc << 2 & 0xcccccccc); + crc = (crc >> 1 & 0x55555555) | (crc << 1 & 0xaaaaaaaa); + return crc; +} + /* CREDITS: linux gianfar driver, slightly adjusted... thanx. */ /* Set the appropriate hash bit for the given addr */ diff --git a/include/net.h b/include/net.h index 51c099dae2..359bfb5ef6 100644 --- a/include/net.h +++ b/include/net.h @@ -289,7 +289,6 @@ const char *eth_get_name(void); /* get name of current device */ #ifdef CONFIG_MCAST_TFTP int eth_mcast_join(struct in_addr mcast_addr, int join); -u32 ether_crc(size_t len, unsigned char const *p); #endif diff --git a/net/eth_legacy.c b/net/eth_legacy.c index 2a9caa3509..d2e16b8fa3 100644 --- a/net/eth_legacy.c +++ b/net/eth_legacy.c @@ -310,30 +310,6 @@ int eth_mcast_join(struct in_addr mcast_ip, int join) return eth_current->mcast(eth_current, mcast_mac, join); } -/* the 'way' for ethernet-CRC-32. Spliced in from Linux lib/crc32.c - * and this is the ethernet-crc method needed for TSEC -- and perhaps - * some other adapter -- hash tables - */ -#define CRCPOLY_LE 0xedb88320 -u32 ether_crc(size_t len, unsigned char const *p) -{ - int i; - u32 crc; - crc = ~0; - while (len--) { - crc ^= *p++; - for (i = 0; i < 8; i++) - crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0); - } - /* an reverse the bits, cuz of way they arrive -- last-first */ - crc = (crc >> 16) | (crc << 16); - crc = (crc >> 8 & 0x00ff00ff) | (crc << 8 & 0xff00ff00); - crc = (crc >> 4 & 0x0f0f0f0f) | (crc << 4 & 0xf0f0f0f0); - crc = (crc >> 2 & 0x33333333) | (crc << 2 & 0xcccccccc); - crc = (crc >> 1 & 0x55555555) | (crc << 1 & 0xaaaaaaaa); - return crc; -} - #endif From 67bb984249442378ebb6a0eb68b6b0dd67dfbe72 Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Mon, 26 Nov 2018 21:00:29 +1300 Subject: [PATCH 15/17] net: remove CONFIG_MCAST_TFTP No mainline board enables CONFIG_MCAST_TFTP and there have been compilation issues with the code for some time. Additionally, it has a potential buffer underrun issue (reported as a side note in CVE-2018-18439). Remove the multicast TFTP code but keep the driver API for the future addition of IPv6. Cc: Simon Goldschmidt Signed-off-by: Chris Packham Acked-by: Joe Hershberger --- README | 9 -- drivers/net/rtl8139.c | 6 +- drivers/net/tsec.c | 14 +-- drivers/usb/gadget/ether.c | 3 - include/net.h | 14 +-- net/eth-uclass.c | 2 - net/eth_legacy.c | 4 - net/net.c | 7 -- net/tftp.c | 219 ----------------------------------- scripts/config_whitelist.txt | 1 - 10 files changed, 6 insertions(+), 273 deletions(-) diff --git a/README b/README index 17d56b8034..aed6b96b57 100644 --- a/README +++ b/README @@ -1429,15 +1429,6 @@ The following options need to be configured: forwarded through a router. (Environment variable "netmask") -- Multicast TFTP Mode: - CONFIG_MCAST_TFTP - - Defines whether you want to support multicast TFTP as per - rfc-2090; for example to work with atftp. Lets lots of targets - tftp down the same boot image concurrently. Note: the Ethernet - driver in use must provide a function: mcast() to join/leave a - multicast group. - - BOOTP Recovery Mode: CONFIG_BOOTP_RANDOM_DELAY diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index 590f8ce154..13309970e2 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -183,12 +183,10 @@ static void rtl_reset(struct eth_device *dev); static int rtl_transmit(struct eth_device *dev, void *packet, int length); static int rtl_poll(struct eth_device *dev); static void rtl_disable(struct eth_device *dev); -#ifdef CONFIG_MCAST_TFTP/* This driver already accepts all b/mcast */ -static int rtl_bcast_addr(struct eth_device *dev, const u8 *bcast_mac, u8 set) +static int rtl_bcast_addr(struct eth_device *dev, const u8 *bcast_mac, int join) { return (0); } -#endif static struct pci_device_id supported[] = { {PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139}, @@ -229,9 +227,7 @@ int rtl8139_initialize(bd_t *bis) dev->halt = rtl_disable; dev->send = rtl_transmit; dev->recv = rtl_poll; -#ifdef CONFIG_MCAST_TFTP dev->mcast = rtl_bcast_addr; -#endif eth_register (dev); diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index 9a4fab85e9..06a9b4fb03 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -78,8 +78,6 @@ static void tsec_configure_serdes(struct tsec_private *priv) 0, TBI_CR, CONFIG_TSEC_TBICR_SETTINGS); } -#ifdef CONFIG_MCAST_TFTP - /* the 'way' for ethernet-CRC-32. Spliced in from Linux lib/crc32.c * and this is the ethernet-crc method needed for TSEC -- and perhaps * some other adapter -- hash tables @@ -124,9 +122,10 @@ static u32 ether_crc(size_t len, unsigned char const *p) * the entry. */ #ifndef CONFIG_DM_ETH -static int tsec_mcast_addr(struct eth_device *dev, const u8 *mcast_mac, u8 set) +static int tsec_mcast_addr(struct eth_device *dev, const u8 *mcast_mac, + int join) #else -static int tsec_mcast_addr(struct udevice *dev, const u8 *mcast_mac, int set) +static int tsec_mcast_addr(struct udevice *dev, const u8 *mcast_mac, int join) #endif { struct tsec_private *priv = (struct tsec_private *)dev->priv; @@ -140,14 +139,13 @@ static int tsec_mcast_addr(struct udevice *dev, const u8 *mcast_mac, int set) value = BIT(31 - whichbit); - if (set) + if (join) setbits_be32(®s->hash.gaddr0 + whichreg, value); else clrbits_be32(®s->hash.gaddr0 + whichreg, value); return 0; } -#endif /* Multicast TFTP ? */ /* * Initialized required registers to appropriate values, zeroing @@ -745,9 +743,7 @@ static int tsec_initialize(bd_t *bis, struct tsec_info_struct *tsec_info) dev->halt = tsec_halt; dev->send = tsec_send; dev->recv = tsec_recv; -#ifdef CONFIG_MCAST_TFTP dev->mcast = tsec_mcast_addr; -#endif /* Tell U-Boot to get the addr from the env */ for (i = 0; i < 6; i++) @@ -887,9 +883,7 @@ static const struct eth_ops tsec_ops = { .recv = tsec_recv, .free_pkt = tsec_free_pkt, .stop = tsec_halt, -#ifdef CONFIG_MCAST_TFTP .mcast = tsec_mcast_addr, -#endif }; static const struct udevice_id tsec_ids[] = { diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 3b3d9af681..e4993dc6e6 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -2579,9 +2579,6 @@ int usb_eth_initialize(bd_t *bi) netdev->halt = usb_eth_halt; netdev->priv = l_priv; -#ifdef CONFIG_MCAST_TFTP - #error not supported -#endif eth_register(netdev); return 0; } diff --git a/include/net.h b/include/net.h index 359bfb5ef6..dd52ed3f47 100644 --- a/include/net.h +++ b/include/net.h @@ -140,9 +140,7 @@ struct eth_ops { int (*recv)(struct udevice *dev, int flags, uchar **packetp); int (*free_pkt)(struct udevice *dev, uchar *packet, int length); void (*stop)(struct udevice *dev); -#ifdef CONFIG_MCAST_TFTP int (*mcast)(struct udevice *dev, const u8 *enetaddr, int join); -#endif int (*write_hwaddr)(struct udevice *dev); int (*read_rom_hwaddr)(struct udevice *dev); }; @@ -175,9 +173,7 @@ struct eth_device { int (*send)(struct eth_device *, void *packet, int length); int (*recv)(struct eth_device *); void (*halt)(struct eth_device *); -#ifdef CONFIG_MCAST_TFTP - int (*mcast)(struct eth_device *, const u8 *enetaddr, u8 set); -#endif + int (*mcast)(struct eth_device *, const u8 *enetaddr, int join); int (*write_hwaddr)(struct eth_device *); struct eth_device *next; int index; @@ -286,11 +282,7 @@ extern void (*push_packet)(void *packet, int length); int eth_rx(void); /* Check for received packets */ void eth_halt(void); /* stop SCC */ const char *eth_get_name(void); /* get name of current device */ - -#ifdef CONFIG_MCAST_TFTP int eth_mcast_join(struct in_addr mcast_addr, int join); -#endif - /**********************************************************************/ /* @@ -577,10 +569,6 @@ extern struct in_addr net_ntp_server; /* the ip address to NTP */ extern int net_ntp_time_offset; /* offset time from UTC */ #endif -#if defined(CONFIG_MCAST_TFTP) -extern struct in_addr net_mcast_addr; -#endif - /* Initialize the network adapter */ void net_init(void); int net_loop(enum proto_t); diff --git a/net/eth-uclass.c b/net/eth-uclass.c index 91d861be41..2ef20df192 100644 --- a/net/eth-uclass.c +++ b/net/eth-uclass.c @@ -476,10 +476,8 @@ static int eth_post_probe(struct udevice *dev) ops->free_pkt += gd->reloc_off; if (ops->stop) ops->stop += gd->reloc_off; -#ifdef CONFIG_MCAST_TFTP if (ops->mcast) ops->mcast += gd->reloc_off; -#endif if (ops->write_hwaddr) ops->write_hwaddr += gd->reloc_off; if (ops->read_rom_hwaddr) diff --git a/net/eth_legacy.c b/net/eth_legacy.c index d2e16b8fa3..e250a430f3 100644 --- a/net/eth_legacy.c +++ b/net/eth_legacy.c @@ -291,7 +291,6 @@ int eth_initialize(void) return num_devices; } -#ifdef CONFIG_MCAST_TFTP /* Multicast. * mcast_addr: multicast ipaddr from which multicast Mac is made * join: 1=join, 0=leave. @@ -310,9 +309,6 @@ int eth_mcast_join(struct in_addr mcast_ip, int join) return eth_current->mcast(eth_current, mcast_mac, join); } -#endif - - int eth_init(void) { struct eth_device *old_current; diff --git a/net/net.c b/net/net.c index e9f7a7d85e..58b0417cbe 100644 --- a/net/net.c +++ b/net/net.c @@ -131,10 +131,6 @@ struct in_addr net_dns_server; struct in_addr net_dns_server2; #endif -#ifdef CONFIG_MCAST_TFTP /* Multicast TFTP */ -struct in_addr net_mcast_addr; -#endif - /** END OF BOOTP EXTENTIONS **/ /* Our ethernet address */ @@ -1216,9 +1212,6 @@ void net_process_received_packet(uchar *in_packet, int len) dst_ip = net_read_ip(&ip->ip_dst); if (net_ip.s_addr && dst_ip.s_addr != net_ip.s_addr && dst_ip.s_addr != 0xFFFFFFFF) { -#ifdef CONFIG_MCAST_TFTP - if (net_mcast_addr != dst_ip) -#endif return; } /* Read source IP address for later use */ diff --git a/net/tftp.c b/net/tftp.c index a9335b1b7e..8fab6d2650 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -140,36 +140,6 @@ static char tftp_filename[MAX_LEN]; static unsigned short tftp_block_size = TFTP_BLOCK_SIZE; static unsigned short tftp_block_size_option = TFTP_MTU_BLOCKSIZE; -#ifdef CONFIG_MCAST_TFTP -#include -#define MTFTP_BITMAPSIZE 0x1000 -static unsigned *tftp_mcast_bitmap; -static int tftp_mcast_prev_hole; -static int tftp_mcast_bitmap_size = MTFTP_BITMAPSIZE; -static int tftp_mcast_disabled; -static int tftp_mcast_master_client; -static int tftp_mcast_active; -static int tftp_mcast_port; -/* can get 'last' block before done..*/ -static ulong tftp_mcast_ending_block; - -static void parse_multicast_oack(char *pkt, int len); - -static void mcast_cleanup(void) -{ - if (net_mcast_addr) - eth_mcast_join(net_mcast_addr, 0); - if (tftp_mcast_bitmap) - free(tftp_mcast_bitmap); - tftp_mcast_bitmap = NULL; - net_mcast_addr.s_addr = 0; - tftp_mcast_active = 0; - tftp_mcast_port = 0; - tftp_mcast_ending_block = -1; -} - -#endif /* CONFIG_MCAST_TFTP */ - static inline int store_block(int block, uchar *src, unsigned int len) { ulong offset = block * tftp_block_size + tftp_block_wrap_offset; @@ -211,10 +181,6 @@ static inline int store_block(int block, uchar *src, unsigned int len) memcpy(ptr, src, len); unmap_sysmem(ptr); } -#ifdef CONFIG_MCAST_TFTP - if (tftp_mcast_active) - ext2_set_bit(block, tftp_mcast_bitmap); -#endif if (net_boot_file_size < newsize) net_boot_file_size = newsize; @@ -292,9 +258,6 @@ static void show_block_marker(void) static void restart(const char *msg) { printf("\n%s; starting again\n", msg); -#ifdef CONFIG_MCAST_TFTP - mcast_cleanup(); -#endif net_start_again(); } @@ -349,12 +312,6 @@ static void tftp_send(void) int len = 0; ushort *s; -#ifdef CONFIG_MCAST_TFTP - /* Multicast TFTP.. non-MasterClients do not ACK data. */ - if (tftp_mcast_active && tftp_state == STATE_DATA && - tftp_mcast_master_client == 0) - return; -#endif /* * We will always be sending some sort of packet, so * cobble together the packet headers now. @@ -389,30 +346,10 @@ static void tftp_send(void) /* try for more effic. blk size */ pkt += sprintf((char *)pkt, "blksize%c%d%c", 0, tftp_block_size_option, 0); -#ifdef CONFIG_MCAST_TFTP - /* Check all preconditions before even trying the option */ - if (!tftp_mcast_disabled) { - tftp_mcast_bitmap = malloc(tftp_mcast_bitmap_size); - if (tftp_mcast_bitmap && eth_get_dev()->mcast) { - free(tftp_mcast_bitmap); - tftp_mcast_bitmap = NULL; - pkt += sprintf((char *)pkt, "multicast%c%c", - 0, 0); - } - } -#endif /* CONFIG_MCAST_TFTP */ len = pkt - xp; break; case STATE_OACK: -#ifdef CONFIG_MCAST_TFTP - /* My turn! Start at where I need blocks I missed. */ - if (tftp_mcast_active) - tftp_cur_block = ext2_find_next_zero_bit( - tftp_mcast_bitmap, - tftp_mcast_bitmap_size * 8, 0); - /* fall through */ -#endif case STATE_RECV_WRQ: case STATE_DATA: @@ -482,10 +419,6 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip, int i; if (dest != tftp_our_port) { -#ifdef CONFIG_MCAST_TFTP - if (tftp_mcast_active && - (!tftp_mcast_port || dest != tftp_mcast_port)) -#endif return; } if (tftp_state != STATE_SEND_RRQ && src != tftp_remote_port && @@ -566,12 +499,6 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip, } #endif } -#ifdef CONFIG_MCAST_TFTP - parse_multicast_oack((char *)pkt, len - 1); - if ((tftp_mcast_active) && (!tftp_mcast_master_client)) - tftp_state = STATE_DATA; /* passive.. */ - else -#endif #ifdef CONFIG_CMD_TFTPPUT if (tftp_put_active) { /* Get ready to send the first block */ @@ -599,11 +526,6 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip, tftp_remote_port = src; new_transfer(); -#ifdef CONFIG_MCAST_TFTP - if (tftp_mcast_active) { /* start!=1 common if mcast */ - tftp_prev_block = tftp_cur_block - 1; - } else -#endif if (tftp_cur_block != 1) { /* Assertion */ puts("\nTFTP error: "); printf("First block is not block 1 (%ld)\n", @@ -633,44 +555,8 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip, * Acknowledge the block just received, which will prompt * the remote for the next one. */ -#ifdef CONFIG_MCAST_TFTP - /* if I am the MasterClient, actively calculate what my next - * needed block is; else I'm passive; not ACKING - */ - if (tftp_mcast_active) { - if (len < tftp_block_size) { - tftp_mcast_ending_block = tftp_cur_block; - } else if (tftp_mcast_master_client) { - tftp_mcast_prev_hole = ext2_find_next_zero_bit( - tftp_mcast_bitmap, - tftp_mcast_bitmap_size * 8, - tftp_mcast_prev_hole); - tftp_cur_block = tftp_mcast_prev_hole; - if (tftp_cur_block > - ((tftp_mcast_bitmap_size * 8) - 1)) { - debug("tftpfile too big\n"); - /* try to double it and retry */ - tftp_mcast_bitmap_size <<= 1; - mcast_cleanup(); - net_start_again(); - return; - } - tftp_prev_block = tftp_cur_block; - } - } -#endif tftp_send(); -#ifdef CONFIG_MCAST_TFTP - if (tftp_mcast_active) { - if (tftp_mcast_master_client && - (tftp_cur_block >= tftp_mcast_ending_block)) { - puts("\nMulticast tftp done\n"); - mcast_cleanup(); - net_set_state(NETLOOP_SUCCESS); - } - } else -#endif if (len < tftp_block_size) tftp_complete(); break; @@ -693,9 +579,6 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip, case TFTP_ERR_FILE_ALREADY_EXISTS: default: puts("Starting again\n\n"); -#ifdef CONFIG_MCAST_TFTP - mcast_cleanup(); -#endif net_start_again(); break; } @@ -873,9 +756,6 @@ void tftp_start(enum proto_t protocol) memset(net_server_ethaddr, 0, 6); /* Revert tftp_block_size to dflt */ tftp_block_size = TFTP_BLOCK_SIZE; -#ifdef CONFIG_MCAST_TFTP - mcast_cleanup(); -#endif #ifdef CONFIG_TFTP_TSIZE tftp_tsize = 0; tftp_tsize_num_hash = 0; @@ -924,102 +804,3 @@ void tftp_start_server(void) } #endif /* CONFIG_CMD_TFTPSRV */ -#ifdef CONFIG_MCAST_TFTP -/* - * Credits: atftp project. - */ - -/* - * Pick up BcastAddr, Port, and whether I am [now] the master-client. - * Frame: - * +-------+-----------+---+-------~~-------+---+ - * | opc | multicast | 0 | addr, port, mc | 0 | - * +-------+-----------+---+-------~~-------+---+ - * The multicast addr/port becomes what I listen to, and if 'mc' is '1' then - * I am the new master-client so must send ACKs to DataBlocks. If I am not - * master-client, I'm a passive client, gathering what DataBlocks I may and - * making note of which ones I got in my bitmask. - * In theory, I never go from master->passive.. - * .. this comes in with pkt already pointing just past opc - */ -static void parse_multicast_oack(char *pkt, int len) -{ - int i; - struct in_addr addr; - char *mc_adr; - char *port; - char *mc; - - mc_adr = NULL; - port = NULL; - mc = NULL; - /* march along looking for 'multicast\0', which has to start at least - * 14 bytes back from the end. - */ - for (i = 0; i < len - 14; i++) - if (strcmp(pkt + i, "multicast") == 0) - break; - if (i >= (len - 14)) /* non-Multicast OACK, ign. */ - return; - - i += 10; /* strlen multicast */ - mc_adr = pkt + i; - for (; i < len; i++) { - if (*(pkt + i) == ',') { - *(pkt + i) = '\0'; - if (port) { - mc = pkt + i + 1; - break; - } else { - port = pkt + i + 1; - } - } - } - if (!port || !mc_adr || !mc) - return; - if (tftp_mcast_active && tftp_mcast_master_client) { - printf("I got a OACK as master Client, WRONG!\n"); - return; - } - /* ..I now accept packets destined for this MCAST addr, port */ - if (!tftp_mcast_active) { - if (tftp_mcast_bitmap) { - printf("Internal failure! no mcast.\n"); - free(tftp_mcast_bitmap); - tftp_mcast_bitmap = NULL; - tftp_mcast_disabled = 1; - return; - } - /* I malloc instead of pre-declare; so that if the file ends - * up being too big for this bitmap I can retry - */ - tftp_mcast_bitmap = malloc(tftp_mcast_bitmap_size); - if (!tftp_mcast_bitmap) { - printf("No bitmap, no multicast. Sorry.\n"); - tftp_mcast_disabled = 1; - return; - } - memset(tftp_mcast_bitmap, 0, tftp_mcast_bitmap_size); - tftp_mcast_prev_hole = 0; - tftp_mcast_active = 1; - } - addr = string_to_ip(mc_adr); - if (net_mcast_addr.s_addr != addr.s_addr) { - if (net_mcast_addr.s_addr) - eth_mcast_join(net_mcast_addr, 0); - net_mcast_addr = addr; - if (eth_mcast_join(net_mcast_addr, 1)) { - printf("Fail to set mcast, revert to TFTP\n"); - tftp_mcast_disabled = 1; - mcast_cleanup(); - net_start_again(); - } - } - tftp_mcast_master_client = simple_strtoul((char *)mc, NULL, 10); - tftp_mcast_port = (unsigned short)simple_strtoul(port, NULL, 10); - printf("Multicast: %s:%d [%d]\n", mc_adr, tftp_mcast_port, - tftp_mcast_master_client); - return; -} - -#endif /* Multicast TFTP */ diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index e6ac098e27..d03ddd876f 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -1198,7 +1198,6 @@ CONFIG_MAX_FPGA_DEVICES CONFIG_MAX_MEM_MAPPED CONFIG_MAX_PKT CONFIG_MAX_RAM_BANK_SIZE -CONFIG_MCAST_TFTP CONFIG_MCF5249 CONFIG_MCF5253 CONFIG_MCFFEC From c54bfbf96f908e8b84291b7c556a2a1cabecac23 Mon Sep 17 00:00:00 2001 From: Valentin-catalin Neacsu Date: Tue, 30 Oct 2018 09:54:46 +0000 Subject: [PATCH 16/17] net: phy: aquantia: Enable autoneg when on USXGMII If System Interface protocol is USXGMII then enable USXGMII autoneg Signed-off-by: Valentin Catalin Neacsu Acked-by: Joe Hershberger --- drivers/net/phy/aquantia.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c index a0abb23299..3edc35eb21 100644 --- a/drivers/net/phy/aquantia.c +++ b/drivers/net/phy/aquantia.c @@ -3,6 +3,7 @@ * Aquantia PHY drivers * * Copyright 2014 Freescale Semiconductor, Inc. + * Copyright 2018 NXP */ #include #include @@ -19,6 +20,13 @@ #define AQUNTIA_SPEED_LSB_MASK 0x2000 #define AQUNTIA_SPEED_MSB_MASK 0x40 +#define AQUANTIA_SYSTEM_INTERFACE_SR 0xe812 +#define AQUANTIA_VENDOR_PROVISIONING_REG 0xC441 + +#define AQUANTIA_USX_AUTONEG_CONTROL_ENA 0x0008 +#define AQUANTIA_SI_IN_USE_MASK 0x0078 +#define AQUANTIA_SI_USXGMII 0x0018 + /* registers in MDIO_MMD_VEND1 region */ #define GLOBAL_FIRMWARE_ID 0x20 #define GLOBAL_FAULT 0xc850 @@ -284,6 +292,16 @@ int aquantia_config(struct phy_device *phydev) phy_write(phydev, MDIO_MMD_PMAPMD, MII_BMCR, AQUNTIA_SPEED_LSB_MASK | AQUNTIA_SPEED_MSB_MASK); + + val = phy_read(phydev, MDIO_MMD_PHYXS, + AQUANTIA_SYSTEM_INTERFACE_SR); + /* If SI is USXGMII then start USXGMII autoneg */ + if ((val & AQUANTIA_SI_IN_USE_MASK) == AQUANTIA_SI_USXGMII) { + phy_write(phydev, MDIO_MMD_PHYXS, + AQUANTIA_VENDOR_PROVISIONING_REG, + AQUANTIA_USX_AUTONEG_CONTROL_ENA); + } + } else if (phydev->interface == PHY_INTERFACE_MODE_SGMII_2500) { /* 2.5GBASE-T mode */ phydev->advertising = SUPPORTED_1000baseT_Full; From 91c9cbabf935b37ab6c0b9b622e7faf0b350acb6 Mon Sep 17 00:00:00 2001 From: Valentin-catalin Neacsu Date: Tue, 6 Nov 2018 12:16:54 +0000 Subject: [PATCH 17/17] net: phy: aquantia: Print information on config Print information about Aquantia system interface and firmware loaded on the phy. Signed-off-by: Valentin Catalin Neacsu Acked-by: Joe Hershberger --- drivers/net/phy/aquantia.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c index 3edc35eb21..12df09877d 100644 --- a/drivers/net/phy/aquantia.c +++ b/drivers/net/phy/aquantia.c @@ -22,6 +22,11 @@ #define AQUANTIA_SYSTEM_INTERFACE_SR 0xe812 #define AQUANTIA_VENDOR_PROVISIONING_REG 0xC441 +#define AQUANTIA_FIRMWARE_ID 0x20 +#define AQUANTIA_RESERVED_STATUS 0xc885 +#define AQUANTIA_FIRMWARE_MAJOR_MASK 0xff00 +#define AQUANTIA_FIRMWARE_MINOR_MASK 0xff +#define AQUANTIA_FIRMWARE_BUILD_MASK 0xf0 #define AQUANTIA_USX_AUTONEG_CONTROL_ENA 0x0008 #define AQUANTIA_SI_IN_USE_MASK 0x0078 @@ -252,6 +257,7 @@ static int aquantia_upload_firmware(struct phy_device *phydev) int aquantia_config(struct phy_device *phydev) { u32 val, id, rstatus, fault; + u32 reg_val1 = 0; id = phy_read(phydev, MDIO_MMD_VEND1, GLOBAL_FIRMWARE_ID); rstatus = phy_read(phydev, MDIO_MMD_VEND1, GLOBAL_RSTATUS_1); @@ -300,6 +306,11 @@ int aquantia_config(struct phy_device *phydev) phy_write(phydev, MDIO_MMD_PHYXS, AQUANTIA_VENDOR_PROVISIONING_REG, AQUANTIA_USX_AUTONEG_CONTROL_ENA); + printf("%s: system interface USXGMII\n", + phydev->dev->name); + } else { + printf("%s: system interface XFI\n", + phydev->dev->name); } } else if (phydev->interface == PHY_INTERFACE_MODE_SGMII_2500) { @@ -317,6 +328,16 @@ int aquantia_config(struct phy_device *phydev) val = (val & ~AQUNTIA_SPEED_MSB_MASK) | AQUNTIA_SPEED_LSB_MASK; phy_write(phydev, MDIO_MMD_PMAPMD, MII_BMCR, val); } + + val = phy_read(phydev, MDIO_MMD_VEND1, AQUANTIA_RESERVED_STATUS); + reg_val1 = phy_read(phydev, MDIO_MMD_VEND1, AQUANTIA_FIRMWARE_ID); + + printf("%s: %s Firmware Version %x.%x.%x\n", phydev->dev->name, + phydev->drv->name, + (reg_val1 & AQUANTIA_FIRMWARE_MAJOR_MASK) >> 8, + reg_val1 & AQUANTIA_FIRMWARE_MINOR_MASK, + (val & AQUANTIA_FIRMWARE_BUILD_MASK) >> 4); + return 0; }