Merge tag 'efi-2019-07-rc4' of git://git.denx.de/u-boot-efi

Pull request for UEFI sub-system for v2019.07-rc4

Corrections for boottime services for protocols and for the SetTime()
service are provided.

Error messages for the 'setenv -e' and 'bootefi bootmgr' commands are
added.
diff --git a/Documentation/devicetree/bindings/net/ethernet.txt b/Documentation/devicetree/bindings/net/ethernet.txt
new file mode 100644
index 0000000..cfc376b
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/ethernet.txt
@@ -0,0 +1,66 @@
+The following properties are common to the Ethernet controllers:
+
+NOTE: All 'phy*' properties documented below are Ethernet specific. For the
+generic PHY 'phys' property, see
+Documentation/devicetree/bindings/phy/phy-bindings.txt.
+
+- local-mac-address: array of 6 bytes, specifies the MAC address that was
+  assigned to the network device;
+- mac-address: array of 6 bytes, specifies the MAC address that was last used by
+  the boot program; should be used in cases where the MAC address assigned to
+  the device by the boot program is different from the "local-mac-address"
+  property;
+- nvmem-cells: phandle, reference to an nvmem node for the MAC address;
+- nvmem-cell-names: string, should be "mac-address" if nvmem is to be used;
+- max-speed: number, specifies maximum speed in Mbit/s supported by the device;
+- max-frame-size: number, maximum transfer unit (IEEE defined MTU), rather than
+  the maximum frame size (there's contradiction in the Devicetree
+  Specification).
+- phy-mode: string, operation mode of the PHY interface. This is now a de-facto
+  standard property; supported values are:
+  * "internal"
+  * "mii"
+  * "gmii"
+  * "sgmii"
+  * "qsgmii"
+  * "tbi"
+  * "rev-mii"
+  * "rmii"
+  * "rgmii" (RX and TX delays are added by the MAC when required)
+  * "rgmii-id" (RGMII with internal RX and TX delays provided by the PHY, the
+     MAC should not add the RX or TX delays in this case)
+  * "rgmii-rxid" (RGMII with internal RX delay provided by the PHY, the MAC
+     should not add an RX delay in this case)
+  * "rgmii-txid" (RGMII with internal TX delay provided by the PHY, the MAC
+     should not add an TX delay in this case)
+  * "rtbi"
+  * "smii"
+  * "xgmii"
+  * "trgmii"
+  * "2000base-x",
+  * "2500base-x",
+  * "rxaui"
+  * "xaui"
+  * "10gbase-kr" (10GBASE-KR, XFI, SFI)
+- phy-connection-type: the same as "phy-mode" property but described in the
+  Devicetree Specification;
+- phy-handle: phandle, specifies a reference to a node representing a PHY
+  device; this property is described in the Devicetree Specification and so
+  preferred;
+- phy: the same as "phy-handle" property, not recommended for new bindings.
+- phy-device: the same as "phy-handle" property, not recommended for new
+  bindings.
+- rx-fifo-depth: the size of the controller's receive fifo in bytes. This
+  is used for components that can have configurable receive fifo sizes,
+  and is useful for determining certain configuration settings such as
+  flow control thresholds.
+- tx-fifo-depth: the size of the controller's transmit fifo in bytes. This
+  is used for components that can have configurable fifo sizes.
+- managed: string, specifies the PHY management type. Supported values are:
+  "auto", "in-band-status". "auto" is the default, it usess MDIO for
+  management if fixed-link is not specified.
+
+Child nodes of the Ethernet controller are typically the individual PHY devices
+connected via the MDIO bus (sometimes the MDIO bus controller is separate).
+They are described in the phy.txt file in this same directory.
+For non-MDIO PHY management see fixed-link.txt.
diff --git a/board/sifive/fu540/Kconfig b/board/sifive/fu540/Kconfig
index f464379..8eb5e30 100644
--- a/board/sifive/fu540/Kconfig
+++ b/board/sifive/fu540/Kconfig
@@ -28,6 +28,7 @@
 	imply CMD_PING
 	imply CLK_SIFIVE
 	imply CLK_SIFIVE_FU540_PRCI
+	imply CLK_SIFIVE_GEMGXL_MGMT
 	imply DOS_PARTITION
 	imply EFI_PARTITION
 	imply IP_DYN
diff --git a/cmd/mdio.c b/cmd/mdio.c
index efe8c9e..5e219f6 100644
--- a/cmd/mdio.c
+++ b/cmd/mdio.c
@@ -54,7 +54,10 @@
 
 		for (devad = devadlo; devad <= devadhi; devad++) {
 			for (reg = reglo; reg <= reghi; reg++) {
-				if (!extended)
+				if (!phydev)
+					err = bus->write(bus, addr, devad,
+							 reg, data);
+				else if (!extended)
 					err = phy_write_mmd(phydev, devad,
 							    reg, data);
 				else
@@ -88,7 +91,9 @@
 			for (reg = reglo; reg <= reghi; reg++) {
 				int val;
 
-				if (!extended)
+				if (!phydev)
+					val = bus->read(bus, addr, devad, reg);
+				else if (!extended)
 					val = phy_read_mmd(phydev, devad, reg);
 				else
 					val = phydev->drv->readext(phydev, addr,
diff --git a/drivers/clk/sifive/Kconfig b/drivers/clk/sifive/Kconfig
index 81fc9f8..644881b 100644
--- a/drivers/clk/sifive/Kconfig
+++ b/drivers/clk/sifive/Kconfig
@@ -17,3 +17,10 @@
 	  Supports the Power Reset Clock interface (PRCI) IP block found in
 	  FU540 SoCs.  If this kernel is meant to run on a SiFive FU540 SoC,
 	  enable this driver.
+
+config CLK_SIFIVE_GEMGXL_MGMT
+	bool "GEMGXL management for SiFive FU540 SoCs"
+	depends on CLK_SIFIVE
+	help
+	  Supports the GEMGXL management IP block found in FU540 SoCs to
+	  control GEM TX clock operation mode for 10/100/1000 Mbps.
diff --git a/drivers/clk/sifive/Makefile b/drivers/clk/sifive/Makefile
index 1155e07..f8263e7 100644
--- a/drivers/clk/sifive/Makefile
+++ b/drivers/clk/sifive/Makefile
@@ -3,3 +3,5 @@
 obj-$(CONFIG_CLK_ANALOGBITS_WRPLL_CLN28HPC)	+= wrpll-cln28hpc.o
 
 obj-$(CONFIG_CLK_SIFIVE_FU540_PRCI)		+= fu540-prci.o
+
+obj-$(CONFIG_CLK_SIFIVE_GEMGXL_MGMT)		+= gemgxl-mgmt.o
diff --git a/drivers/clk/sifive/gemgxl-mgmt.c b/drivers/clk/sifive/gemgxl-mgmt.c
new file mode 100644
index 0000000..eb37416
--- /dev/null
+++ b/drivers/clk/sifive/gemgxl-mgmt.c
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019, Bin Meng <bmeng.cn@gmail.com>
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <asm/io.h>
+
+struct gemgxl_mgmt_regs {
+	__u32 tx_clk_sel;
+};
+
+struct gemgxl_mgmt_platdata {
+	struct gemgxl_mgmt_regs *regs;
+};
+
+static int gemgxl_mgmt_ofdata_to_platdata(struct udevice *dev)
+{
+	struct gemgxl_mgmt_platdata *plat = dev_get_platdata(dev);
+
+	plat->regs = (struct gemgxl_mgmt_regs *)dev_read_addr(dev);
+
+	return 0;
+}
+
+static ulong gemgxl_mgmt_set_rate(struct clk *clk, ulong rate)
+{
+	struct gemgxl_mgmt_platdata *plat = dev_get_platdata(clk->dev);
+
+	/*
+	 * GEMGXL TX clock operation mode:
+	 *
+	 * 0 = GMII mode. Use 125 MHz gemgxlclk from PRCI in TX logic
+	 *     and output clock on GMII output signal GTX_CLK
+	 * 1 = MII mode. Use MII input signal TX_CLK in TX logic
+	 */
+	writel(rate != 125000000, &plat->regs->tx_clk_sel);
+
+	return 0;
+}
+
+const struct clk_ops gemgxl_mgmt_ops = {
+	.set_rate = gemgxl_mgmt_set_rate,
+};
+
+static const struct udevice_id gemgxl_mgmt_match[] = {
+	{ .compatible = "sifive,cadencegemgxlmgmt0", },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(sifive_gemgxl_mgmt) = {
+	.name = "sifive-gemgxl-mgmt",
+	.id = UCLASS_CLK,
+	.of_match = gemgxl_mgmt_match,
+	.ofdata_to_platdata = gemgxl_mgmt_ofdata_to_platdata,
+	.platdata_auto_alloc_size = sizeof(struct gemgxl_mgmt_platdata),
+	.ops = &gemgxl_mgmt_ops,
+};
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 7261416..c5560a7 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -488,15 +488,58 @@
 
 /**
  * macb_linkspd_cb - Linkspeed change callback function
- * @regs:	Base Register of MACB devices
+ * @dev/@regs:	MACB udevice (DM version) or
+ *		Base Register of MACB devices (non-DM version)
  * @speed:	Linkspeed
  * Returns 0 when operation success and negative errno number
  * when operation failed.
  */
+#ifdef CONFIG_DM_ETH
+int __weak macb_linkspd_cb(struct udevice *dev, unsigned int speed)
+{
+#ifdef CONFIG_CLK
+	struct clk tx_clk;
+	ulong rate;
+	int ret;
+
+	/*
+	 * "tx_clk" is an optional clock source for MACB.
+	 * Ignore if it does not exist in DT.
+	 */
+	ret = clk_get_by_name(dev, "tx_clk", &tx_clk);
+	if (ret)
+		return 0;
+
+	switch (speed) {
+	case _10BASET:
+		rate = 2500000;		/* 2.5 MHz */
+		break;
+	case _100BASET:
+		rate = 25000000;	/* 25 MHz */
+		break;
+	case _1000BASET:
+		rate = 125000000;	/* 125 MHz */
+		break;
+	default:
+		/* does not change anything */
+		return 0;
+	}
+
+	if (tx_clk.dev) {
+		ret = clk_set_rate(&tx_clk, rate);
+		if (ret)
+			return ret;
+	}
+#endif
+
+	return 0;
+}
+#else
 int __weak macb_linkspd_cb(void *regs, unsigned int speed)
 {
 	return 0;
 }
+#endif
 
 #ifdef CONFIG_DM_ETH
 static int macb_phy_init(struct udevice *dev, const char *name)
@@ -589,7 +632,11 @@
 
 			macb_writel(macb, NCFGR, ncfgr);
 
+#ifdef CONFIG_DM_ETH
+			ret = macb_linkspd_cb(dev, _1000BASET);
+#else
 			ret = macb_linkspd_cb(macb->regs, _1000BASET);
+#endif
 			if (ret)
 				return ret;
 
@@ -614,9 +661,17 @@
 	ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD) | GEM_BIT(GBE));
 	if (speed) {
 		ncfgr |= MACB_BIT(SPD);
+#ifdef CONFIG_DM_ETH
+		ret = macb_linkspd_cb(dev, _100BASET);
+#else
 		ret = macb_linkspd_cb(macb->regs, _100BASET);
+#endif
 	} else {
+#ifdef CONFIG_DM_ETH
+		ret = macb_linkspd_cb(dev, _10BASET);
+#else
 		ret = macb_linkspd_cb(macb->regs, _10BASET);
+#endif
 	}
 
 	if (ret)
diff --git a/net/eth-uclass.c b/net/eth-uclass.c
index 2ef20df..031d558 100644
--- a/net/eth-uclass.c
+++ b/net/eth-uclass.c
@@ -455,6 +455,26 @@
 	return 0;
 }
 
+static bool eth_dev_get_mac_address(struct udevice *dev, u8 mac[ARP_HLEN])
+{
+#if IS_ENABLED(CONFIG_OF_CONTROL)
+	const uint8_t *p;
+
+	p = dev_read_u8_array_ptr(dev, "mac-address", ARP_HLEN);
+	if (!p)
+		p = dev_read_u8_array_ptr(dev, "local-mac-address", ARP_HLEN);
+
+	if (!p)
+		return false;
+
+	memcpy(mac, p, ARP_HLEN);
+
+	return true;
+#else
+	return false;
+#endif
+}
+
 static int eth_post_probe(struct udevice *dev)
 {
 	struct eth_device_priv *priv = dev->uclass_priv;
@@ -489,9 +509,13 @@
 
 	priv->state = ETH_STATE_INIT;
 
-	/* Check if the device has a MAC address in ROM */
-	if (eth_get_ops(dev)->read_rom_hwaddr)
-		eth_get_ops(dev)->read_rom_hwaddr(dev);
+	/* Check if the device has a valid MAC address in device tree */
+	if (!eth_dev_get_mac_address(dev, pdata->enetaddr) ||
+	    !is_valid_ethaddr(pdata->enetaddr)) {
+		/* Check if the device has a MAC address in ROM */
+		if (eth_get_ops(dev)->read_rom_hwaddr)
+			eth_get_ops(dev)->read_rom_hwaddr(dev);
+	}
 
 	eth_env_get_enetaddr_by_index("eth", dev->seq, env_enetaddr);
 	if (!is_zero_ethaddr(env_enetaddr)) {
@@ -524,6 +548,8 @@
 #endif
 	}
 
+	eth_write_hwaddr(dev);
+
 	return 0;
 }