Merge branch '2022-10-21-assorted-fixes-and-updates'

- NC-SI handling support and enable on evb-ast2[56]00, gpio driver for
  ADP5585, improve qfw support, print more sysresets info, gw_ventana
  and gcc-12 bugfix, improve BCB support, fix a few typos and remove an
  unused keymile CONFIG symbol.
diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi
index d2db1ea..7387b54 100644
--- a/arch/sandbox/dts/sandbox.dtsi
+++ b/arch/sandbox/dts/sandbox.dtsi
@@ -239,6 +239,7 @@
 
 	reset@1 {
 		compatible = "sandbox,reset";
+		u-boot,dm-pre-proper;
 	};
 
 	rng {
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index b853e13..70e27cd 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -1125,10 +1125,12 @@
 
 	reset@0 {
 		compatible = "sandbox,warm-reset";
+		u-boot,dm-pre-proper;
 	};
 
 	reset@1 {
 		compatible = "sandbox,reset";
+		u-boot,dm-pre-proper;
 	};
 
 	resetc: reset-ctl {
diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c
index 99f52b9..78d317d 100644
--- a/board/gateworks/gw_ventana/gw_ventana.c
+++ b/board/gateworks/gw_ventana/gw_ventana.c
@@ -633,8 +633,7 @@
 					       ctrl);
 			gpio_requestf(cfg->gpio_param, "dio%d", i);
 			gpio_direction_input(cfg->gpio_param);
-		} else if (hwconfig_subarg_cmp(arg, "mode", "pwm") &&
-			   cfg->pwm_padmux) {
+		} else if (hwconfig_subarg_cmp(arg, "mode", "pwm")) {
 			if (!cfg->pwm_param) {
 				printf("DIO%d:  Error: pwm config invalid\n",
 				       i);
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 16030e3..41cf1d4 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1842,6 +1842,14 @@
 	help
 	  Acquire a network IP address using the link-local protocol
 
+config CMD_NCSI
+	bool "ncsi"
+	depends on PHY_NCSI
+	help
+	  Manually configure the attached NIC via NC-SI.
+	  Normally this happens automatically before other network
+	  operations.
+
 endif
 
 config CMD_ETHSW
diff --git a/cmd/bcb.c b/cmd/bcb.c
index 1622a90..02d0c70 100644
--- a/cmd/bcb.c
+++ b/cmd/bcb.c
@@ -14,6 +14,7 @@
 #include <part.h>
 #include <malloc.h>
 #include <memalign.h>
+#include <linux/err.h>
 
 enum bcb_cmd {
 	BCB_CMD_LOAD,
@@ -128,6 +129,16 @@
 		goto err_read_fail;
 	}
 
+	/*
+	 * always select the USER mmc hwpart in case another
+	 * blk operation selected a different hwpart
+	 */
+	ret = blk_dselect_hwpart(desc, 0);
+	if (IS_ERR_VALUE(ret)) {
+		ret = -ENODEV;
+		goto err_read_fail;
+	}
+
 	part = simple_strtoul(partp, &endp, 0);
 	if (*endp == '\0') {
 		ret = part_get_info(desc, part, &info);
diff --git a/cmd/net.c b/cmd/net.c
index 46f8c87..addcad3 100644
--- a/cmd/net.c
+++ b/cmd/net.c
@@ -16,6 +16,7 @@
 #include <net.h>
 #include <net/udp.h>
 #include <net/sntp.h>
+#include <net/ncsi.h>
 
 static int netboot_common(enum proto_t, struct cmd_tbl *, int, char * const []);
 
@@ -566,3 +567,24 @@
 	"list - list available devices\n"
 );
 #endif // CONFIG_DM_ETH
+
+#if defined(CONFIG_CMD_NCSI)
+static int do_ncsi(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
+{
+	if (!phy_interface_is_ncsi() || !ncsi_active()) {
+		printf("Device not configured for NC-SI\n");
+		return CMD_RET_FAILURE;
+	}
+
+	if (net_loop(NCSI) < 0)
+		return CMD_RET_FAILURE;
+
+	return CMD_RET_SUCCESS;
+}
+
+U_BOOT_CMD(
+	ncsi,	1,	1,	do_ncsi,
+	"Configure attached NIC via NC-SI",
+	""
+);
+#endif  /* CONFIG_CMD_NCSI */
diff --git a/cmd/qfw.c b/cmd/qfw.c
index ccbc967..95ddc4b 100644
--- a/cmd/qfw.c
+++ b/cmd/qfw.c
@@ -26,8 +26,8 @@
 	qfw_read_entry(qfw_dev, FW_CFG_KERNEL_SIZE, 4, &kernel_size);
 
 	if (kernel_size == 0) {
-		printf("warning: no kernel available\n");
-		return -1;
+		printf("fatal: no kernel available\n");
+		return CMD_RET_FAILURE;
 	}
 
 	data_addr = load_addr;
@@ -40,6 +40,7 @@
 	qfw_read_entry(qfw_dev, FW_CFG_KERNEL_DATA,
 		       le32_to_cpu(kernel_size), data_addr);
 	data_addr += le32_to_cpu(kernel_size);
+	env_set_hex("filesize", le32_to_cpu(kernel_size));
 
 	data_addr = initrd_addr;
 	qfw_read_entry(qfw_dev, FW_CFG_INITRD_SIZE, 4, &initrd_size);
@@ -49,6 +50,7 @@
 		qfw_read_entry(qfw_dev, FW_CFG_INITRD_DATA,
 			       le32_to_cpu(initrd_size), data_addr);
 		data_addr += le32_to_cpu(initrd_size);
+		env_set_hex("filesize", le32_to_cpu(initrd_size));
 	}
 
 	qfw_read_entry(qfw_dev, FW_CFG_CMDLINE_SIZE, 4, &cmdline_size);
diff --git a/common/board_f.c b/common/board_f.c
index 5f17111..4355d1c 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -146,20 +146,27 @@
 {
 	struct udevice *dev;
 	char status[256];
+	bool status_printed = false;
 	int ret;
 
-	ret = uclass_first_device_err(UCLASS_SYSRESET, &dev);
-	if (ret) {
-		debug("%s: No sysreset device found (error: %d)\n",
-		      __func__, ret);
-		/* Not all boards have sysreset drivers available during early
-		 * boot, so don't fail if one can't be found.
-		 */
-		return 0;
-	}
+	/* Not all boards have sysreset drivers available during early
+	 * boot, so don't fail if one can't be found.
+	 */
+	for (ret = uclass_first_device_check(UCLASS_SYSRESET, &dev); dev;
+			ret = uclass_next_device_check(&dev)) {
+		if (ret) {
+			debug("%s: %s sysreset device (error: %d)\n",
+			      __func__, dev->name, ret);
+			continue;
+		}
 
-	if (!sysreset_get_status(dev, status, sizeof(status)))
-		printf("%s", status);
+		if (!sysreset_get_status(dev, status, sizeof(status))) {
+			printf("%s%s", status_printed ? " " : "", status);
+			status_printed = true;
+		}
+	}
+	if (status_printed)
+		printf("\n");
 
 	return 0;
 }
diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig
index 3061cbe..500c85b 100644
--- a/configs/evb-ast2500_defconfig
+++ b/configs/evb-ast2500_defconfig
@@ -28,6 +28,7 @@
 CONFIG_BOOTP_BOOTFILESIZE=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_CMD_NCSI=y
 CONFIG_ENV_OVERWRITE=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
@@ -50,6 +51,7 @@
 CONFIG_SPI_FLASH_WINBOND=y
 # CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
 CONFIG_PHY_REALTEK=y
+CONFIG_PHY_NCSI=y
 CONFIG_FTGMAC100=y
 CONFIG_PHY=y
 CONFIG_PINCTRL=y
diff --git a/configs/evb-ast2600_defconfig b/configs/evb-ast2600_defconfig
index 1981f89..a80513f 100644
--- a/configs/evb-ast2600_defconfig
+++ b/configs/evb-ast2600_defconfig
@@ -66,6 +66,7 @@
 CONFIG_BOOTP_BOOTFILESIZE=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
+CONFIG_CMD_NCSI=y
 CONFIG_CMD_EXT4=y
 CONFIG_DOS_PARTITION=y
 # CONFIG_SPL_DOS_PARTITION is not set
@@ -98,6 +99,7 @@
 CONFIG_SPI_FLASH_WINBOND=y
 # CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
 CONFIG_PHY_REALTEK=y
+CONFIG_PHY_NCSI=y
 CONFIG_DM_MDIO=y
 CONFIG_FTGMAC100=y
 CONFIG_ASPEED_MDIO=y
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 2a60478..220e2cb 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -611,4 +611,10 @@
 	help
 	   Support for GPIOs on Faraday Technology's FTGPIO010 controller.
 
+config ADP5585_GPIO
+	bool "ADP5585 GPIO driver"
+	depends on DM_GPIO && DM_I2C
+	help
+	  Support ADP5585 GPIO expander.
+
 endif
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index eee7908..7235714 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -76,3 +76,4 @@
 obj-$(CONFIG_SLG7XL45106_I2C_GPO)	+= gpio_slg7xl45106.o
 obj-$(CONFIG_$(SPL_TPL_)TURRIS_OMNIA_MCU)	+= turris_omnia_mcu.o
 obj-$(CONFIG_FTGPIO010)		+= ftgpio010.o
+obj-$(CONFIG_ADP5585_GPIO)	+= adp5585_gpio.o
diff --git a/drivers/gpio/adp5585_gpio.c b/drivers/gpio/adp5585_gpio.c
new file mode 100644
index 0000000..ea0cb75
--- /dev/null
+++ b/drivers/gpio/adp5585_gpio.c
@@ -0,0 +1,238 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2022 NXP
+ *
+ * ADP5585 I/O Expander Controller
+ *
+ * Author: Alice Guo <alice.guo@nxp.com>
+ */
+
+#include <asm/gpio.h>
+#include <dm.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <i2c.h>
+
+#define ADP5585_ID			0x00
+#define ADP5585_INT_STATUS		0x01
+#define ADP5585_STATUS			0x02
+#define ADP5585_FIFO_1			0x03
+#define ADP5585_FIFO_2			0x04
+#define ADP5585_FIFO_3			0x05
+#define ADP5585_FIFO_4			0x06
+#define ADP5585_FIFO_5			0x07
+#define ADP5585_FIFO_6			0x08
+#define ADP5585_FIFO_7			0x09
+#define ADP5585_FIFO_8			0x0A
+#define ADP5585_FIFO_9			0x0B
+#define ADP5585_FIFO_10			0x0C
+#define ADP5585_FIFO_11			0x0D
+#define ADP5585_FIFO_12			0x0E
+#define ADP5585_FIFO_13			0x0F
+#define ADP5585_FIFO_14			0x10
+#define ADP5585_FIFO_15			0x11
+#define ADP5585_FIFO_16			0x12
+#define ADP5585_GPI_INT_STAT_A		0x13
+#define ADP5585_GPI_INT_STAT_B		0x14
+#define ADP5585_GPI_STATUS_A		0x15
+#define ADP5585_GPI_STATUS_B		0x16
+#define ADP5585_RPULL_CONFIG_A		0x17
+#define ADP5585_RPULL_CONFIG_B		0x18
+#define ADP5585_RPULL_CONFIG_C		0x19
+#define ADP5585_RPULL_CONFIG_D		0x1A
+#define ADP5585_GPI_INT_LEVEL_A		0x1B
+#define ADP5585_GPI_INT_LEVEL_B		0x1C
+#define ADP5585_GPI_EVENT_EN_A		0x1D
+#define ADP5585_GPI_EVENT_EN_B		0x1E
+#define ADP5585_GPI_INTERRUPT_EN_A	0x1F
+#define ADP5585_GPI_INTERRUPT_EN_B	0x20
+#define ADP5585_DEBOUNCE_DIS_A		0x21
+#define ADP5585_DEBOUNCE_DIS_B		0x22
+#define ADP5585_GPO_DATA_OUT_A		0x23
+#define ADP5585_GPO_DATA_OUT_B		0x24
+#define ADP5585_GPO_OUT_MODE_A		0x25
+#define ADP5585_GPO_OUT_MODE_B		0x26
+#define ADP5585_GPIO_DIRECTION_A	0x27
+#define ADP5585_GPIO_DIRECTION_B	0x28
+#define ADP5585_RESET1_EVENT_A		0x29
+#define ADP5585_RESET1_EVENT_B		0x2A
+#define ADP5585_RESET1_EVENT_C		0x2B
+#define ADP5585_RESET2_EVENT_A		0x2C
+#define ADP5585_RESET2_EVENT_B		0x2D
+#define ADP5585_RESET_CFG		0x2E
+#define ADP5585_PWM_OFFT_LOW		0x2F
+#define ADP5585_PWM_OFFT_HIGH		0x30
+#define ADP5585_PWM_ONT_LOW		0x31
+#define ADP5585_PWM_ONT_HIGH		0x32
+#define ADP5585_PWM_CFG			0x33
+#define ADP5585_LOGIC_CFG		0x34
+#define ADP5585_LOGIC_FF_CFG		0x35
+#define ADP5585_LOGIC_INT_EVENT_EN	0x36
+#define ADP5585_POLL_PTIME_CFG		0x37
+#define ADP5585_PIN_CONFIG_A		0x38
+#define ADP5585_PIN_CONFIG_B		0x39
+#define ADP5585_PIN_CONFIG_D		0x3A
+#define ADP5585_GENERAL_CFG		0x3B
+#define ADP5585_INT_EN			0x3C
+
+#define ADP5585_MAXGPIO			10
+#define ADP5585_BANK(offs)		((offs) > 4)
+#define ADP5585_BIT(offs)		((offs) > 4 ? \
+					1u << ((offs) - 5) : 1u << (offs))
+
+struct adp5585_plat {
+	fdt_addr_t addr;
+	u8 id;
+	u8 dat_out[2];
+	u8 dir[2];
+};
+
+static int adp5585_direction_input(struct udevice *dev, unsigned int offset)
+{
+	int ret;
+	unsigned int bank;
+	struct adp5585_plat *plat = dev_get_plat(dev);
+
+	bank = ADP5585_BANK(offset);
+
+	plat->dir[bank] &= ~ADP5585_BIT(offset);
+	ret = dm_i2c_write(dev, ADP5585_GPIO_DIRECTION_A + bank, &plat->dir[bank], 1);
+
+	return ret;
+}
+
+static int adp5585_direction_output(struct udevice *dev, unsigned int offset,
+				    int value)
+{
+	int ret;
+	unsigned int bank, bit;
+	struct adp5585_plat *plat = dev_get_plat(dev);
+
+	bank =  ADP5585_BANK(offset);
+	bit = ADP5585_BIT(offset);
+
+	plat->dir[bank] |= bit;
+
+	if (value)
+		plat->dat_out[bank] |= bit;
+	else
+		plat->dat_out[bank] &= ~bit;
+
+	ret = dm_i2c_write(dev, ADP5585_GPO_DATA_OUT_A + bank, &plat->dat_out[bank], 1);
+	ret |= dm_i2c_write(dev, ADP5585_GPIO_DIRECTION_A + bank, &plat->dir[bank], 1);
+
+	return ret;
+}
+
+static int adp5585_get_value(struct udevice *dev, unsigned int offset)
+{
+	struct adp5585_plat *plat = dev_get_plat(dev);
+	unsigned int bank = ADP5585_BANK(offset);
+	unsigned int bit = ADP5585_BIT(offset);
+	u8 val;
+
+	if (plat->dir[bank] & bit)
+		val = plat->dat_out[bank];
+	else
+		dm_i2c_read(dev, ADP5585_GPI_STATUS_A + bank, &val, 1);
+
+	return !!(val & bit);
+}
+
+static int adp5585_set_value(struct udevice *dev, unsigned int offset, int value)
+{
+	int ret;
+	unsigned int bank, bit;
+	struct adp5585_plat *plat = dev_get_plat(dev);
+
+	bank =  ADP5585_BANK(offset);
+	bit = ADP5585_BIT(offset);
+
+	if (value)
+		plat->dat_out[bank] |= bit;
+	else
+		plat->dat_out[bank] &= ~bit;
+
+	ret = dm_i2c_write(dev, ADP5585_GPO_DATA_OUT_A + bank, &plat->dat_out[bank], 1);
+
+	return ret;
+}
+
+static int adp5585_get_function(struct udevice *dev, unsigned int offset)
+{
+	unsigned int bank, bit, dir;
+	struct adp5585_plat *plat = dev_get_plat(dev);
+
+	bank =  ADP5585_BANK(offset);
+	bit = ADP5585_BIT(offset);
+	dir = plat->dir[bank] & bit;
+
+	if (!dir)
+		return GPIOF_INPUT;
+	else
+		return GPIOF_OUTPUT;
+}
+
+static int adp5585_xlate(struct udevice *dev, struct gpio_desc *desc,
+			 struct ofnode_phandle_args *args)
+{
+	desc->offset =  args->args[0];
+	desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
+
+	return 0;
+}
+
+static const struct dm_gpio_ops adp5585_ops = {
+	.direction_input	= adp5585_direction_input,
+	.direction_output	= adp5585_direction_output,
+	.get_value		= adp5585_get_value,
+	.set_value		= adp5585_set_value,
+	.get_function		= adp5585_get_function,
+	.xlate			= adp5585_xlate,
+};
+
+static int adp5585_probe(struct udevice *dev)
+{
+	struct adp5585_plat *plat = dev_get_plat(dev);
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+	int ret;
+
+	if (!plat)
+		return 0;
+
+	plat->addr = dev_read_addr(dev);
+	if (plat->addr == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	ret = dm_i2c_read(dev, ADP5585_ID, &plat->id, 1);
+	if (ret < 0)
+		return ret;
+
+	uc_priv->gpio_count = ADP5585_MAXGPIO;
+	uc_priv->bank_name = "adp5585-gpio";
+
+	for (int i = 0; i < 2; i++) {
+		ret = dm_i2c_read(dev, ADP5585_GPO_DATA_OUT_A + i, &plat->dat_out[i], 1);
+		if (ret)
+			return ret;
+
+		ret = dm_i2c_read(dev, ADP5585_GPIO_DIRECTION_A + i, &plat->dir[i], 1);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static const struct udevice_id adp5585_ids[] = {
+	{ .compatible = "adp5585" },
+	{ }
+};
+
+U_BOOT_DRIVER(adp5585) = {
+	.name	= "adp5585",
+	.id	= UCLASS_GPIO,
+	.of_match	= adp5585_ids,
+	.probe	= adp5585_probe,
+	.ops	= &adp5585_ops,
+	.plat_auto	= sizeof(struct adp5585_plat),
+};
diff --git a/drivers/net/ftgmac100.c b/drivers/net/ftgmac100.c
index 74261d1..a50cde3 100644
--- a/drivers/net/ftgmac100.c
+++ b/drivers/net/ftgmac100.c
@@ -188,7 +188,7 @@
 	struct phy_device *phydev = priv->phydev;
 	u32 maccr;
 
-	if (!phydev->link) {
+	if (!phydev->link && priv->phy_mode != PHY_INTERFACE_MODE_NCSI) {
 		dev_err(phydev->dev, "No link\n");
 		return -EREMOTEIO;
 	}
@@ -228,7 +228,8 @@
 	if (!phydev)
 		return -ENODEV;
 
-	phydev->supported &= PHY_GBIT_FEATURES;
+	if (priv->phy_mode != PHY_INTERFACE_MODE_NCSI)
+		phydev->supported &= PHY_GBIT_FEATURES;
 	if (priv->max_speed) {
 		ret = phy_set_supported(phydev, priv->max_speed);
 		if (ret)
@@ -308,7 +309,8 @@
 
 	writel(0, &ftgmac100->maccr);
 
-	phy_shutdown(priv->phydev);
+	if (priv->phy_mode != PHY_INTERFACE_MODE_NCSI)
+		phy_shutdown(priv->phydev);
 }
 
 static int ftgmac100_start(struct udevice *dev)
@@ -580,6 +582,9 @@
 	priv->max_speed = pdata->max_speed;
 	priv->phy_addr = 0;
 
+	if (dev_read_bool(dev, "use-ncsi"))
+		priv->phy_mode = PHY_INTERFACE_MODE_NCSI;
+
 #ifdef CONFIG_PHY_ADDR
 	priv->phy_addr = CONFIG_PHY_ADDR;
 #endif
@@ -592,7 +597,8 @@
 	 * If DM MDIO is enabled, the MDIO bus will be initialized later in
 	 * dm_eth_phy_connect
 	 */
-	if (!IS_ENABLED(CONFIG_DM_MDIO)) {
+	if (priv->phy_mode != PHY_INTERFACE_MODE_NCSI &&
+	    !IS_ENABLED(CONFIG_DM_MDIO)) {
 		ret = ftgmac100_mdio_init(dev);
 		if (ret) {
 			dev_err(dev, "Failed to initialize mdiobus: %d\n", ret);
diff --git a/drivers/net/phy/ncsi.c b/drivers/net/phy/ncsi.c
index bf1e832..bb7eceb 100644
--- a/drivers/net/phy/ncsi.c
+++ b/drivers/net/phy/ncsi.c
@@ -9,6 +9,7 @@
 #include <log.h>
 #include <malloc.h>
 #include <phy.h>
+#include <net.h>
 #include <net/ncsi.h>
 #include <net/ncsi-pkt.h>
 #include <asm/unaligned.h>
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 0350afd..9087663 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -1026,7 +1026,7 @@
 #endif
 
 #ifdef CONFIG_PHY_NCSI
-	if (!phydev)
+	if (!phydev && interface == PHY_INTERFACE_MODE_NCSI)
 		phydev = phy_device_create(bus, 0, PHY_NCSI_ID, false);
 #endif
 
@@ -1275,3 +1275,10 @@
 
 	return 0;
 }
+
+bool phy_interface_is_ncsi(void)
+{
+	struct eth_pdata *pdata = dev_get_plat(eth_get_dev());
+
+	return pdata->phy_interface == PHY_INTERFACE_MODE_NCSI;
+}
diff --git a/include/blk.h b/include/blk.h
index 8806c38..d3ab9a1 100644
--- a/include/blk.h
+++ b/include/blk.h
@@ -119,7 +119,7 @@
  * @param start - starting block number
  * @param blkcnt - number of blocks to read
  * @param blksz - size in bytes of each block
- * @param buf - buffer to contain cached data
+ * @param buffer - buffer to contain cached data
  *
  * Return: - 1 if block returned from cache, 0 otherwise.
  */
@@ -136,7 +136,7 @@
  * @param start - starting block number
  * @param blkcnt - number of blocks available
  * @param blksz - size in bytes of each block
- * @param buf - buffer containing data to cache
+ * @param buffer - buffer containing data to cache
  *
  */
 void blkcache_fill(int iftype, int dev,
@@ -250,7 +250,7 @@
 	 * The MMC standard provides for two boot partitions (numbered 1 and 2),
 	 * rpmb (3), and up to 4 addition general-purpose partitions (4-7).
 	 *
-	 * @desc:	Block device to update
+	 * @dev:	Block device to update
 	 * @hwpart:	Hardware partition number to select. 0 means the raw
 	 *		device, 1 is the first partition, 2 is the second, etc.
 	 * @return 0 if OK, -ve on error
@@ -642,6 +642,7 @@
  *
  * @uclass_id:	Block device type
  * @devnum:	Device number
+ * @start:	Start block number to read (0=first)
  * @blkcnt:	Number of blocks to read
  * @buffer:	Address to write data to
  * Return: number of blocks read, or -ve error number on error
@@ -654,6 +655,7 @@
  *
  * @uclass_id:	Block device type
  * @devnum:	Device number
+ * @start:	Start block number to write (0=first)
  * @blkcnt:	Number of blocks to write
  * @buffer:	Address to read data from
  * Return: number of blocks written, or -ve error number on error
diff --git a/include/configs/km/km-powerpc.h b/include/configs/km/km-powerpc.h
index 20a36fb..424caa0 100644
--- a/include/configs/km/km-powerpc.h
+++ b/include/configs/km/km-powerpc.h
@@ -21,11 +21,8 @@
  * @CONFIG_KM_RESERVED_PRAM: reserved pram for special purpose
  * @CONFIG_KM_PHRAM: address for /var
  * @CONFIG_KM_PNVRAM: address for PNVRAM (for the application)
- * @CONFIG_KM_ROOTFSSIZE: address for rootfilesystem in RAM
  */
 
-/* size of rootfs in RAM */
-#define CONFIG_KM_ROOTFSSIZE	0x0
 /* set the default PRAM value to at least PNVRAM + PHRAM when pram env variable
  * is not valid yet, which is the case for when u-boot copies itself to RAM */
 #define CONFIG_PRAM		((CONFIG_KM_PNVRAM + CONFIG_KM_PHRAM)>>10)
diff --git a/include/configs/kmcent2.h b/include/configs/kmcent2.h
index 0d470c4..1b19001 100644
--- a/include/configs/kmcent2.h
+++ b/include/configs/kmcent2.h
@@ -179,11 +179,8 @@
  * @CONFIG_KM_RESERVED_PRAM: reserved pram for special purpose
  * @CONFIG_KM_PHRAM: address for /var
  * @CONFIG_KM_PNVRAM: address for PNVRAM (for the application)
- * @CONFIG_KM_ROOTFSSIZE: address for rootfilesystem in RAM
  */
 
-/* size of rootfs in RAM */
-#define CONFIG_KM_ROOTFSSIZE	0x0
 /* set the default PRAM value to at least PNVRAM + PHRAM when pram env variable
  * is not valid yet, which is the case for when u-boot copies itself to RAM
  */
diff --git a/include/configs/qemu-arm.h b/include/configs/qemu-arm.h
index dd2faeb..535762e 100644
--- a/include/configs/qemu-arm.h
+++ b/include/configs/qemu-arm.h
@@ -21,6 +21,17 @@
 	EFI_GUID(0x058b7d83, 0x50d5, 0x4c47, 0xa1, 0x95, \
 		 0x60, 0xd8, 0x6a, 0xd3, 0x41, 0xc4)
 
+/* Try files from QEMU's -kernel/-initrd, through the QEMU firmware device. */
+#define BOOTENV_DEV_QFW(devtypeu, devtypel, instance) \
+	"bootcmd_qfw= " \
+		"if qfw load $kernel_addr_r $ramdisk_addr_r; then " \
+		"  booti $kernel_addr_r $ramdisk_addr_r:$filesize $fdtcontroladdr; " \
+		"  if test $? -eq 1; then " \
+		"    bootz $kernel_addr_r $ramdisk_addr_r:$filesize $fdtcontroladdr; " \
+		"  fi ; " \
+		"fi\0"
+#define BOOTENV_DEV_NAME_QFW(devtypeu, devtypel, instance) "qfw "
+
 /* For timer, QEMU emulates an ARMv7/ARMv8 architected timer */
 
 /* Environment options */
@@ -56,6 +67,7 @@
 #endif
 
 #define BOOT_TARGET_DEVICES(func) \
+	func(QFW, qfw, na) \
 	BOOT_TARGET_USB(func) \
 	BOOT_TARGET_SCSI(func) \
 	BOOT_TARGET_VIRTIO(func) \
diff --git a/include/net.h b/include/net.h
index c06b577..32364ed 100644
--- a/include/net.h
+++ b/include/net.h
@@ -560,7 +560,7 @@
 
 enum proto_t {
 	BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
-	TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP
+	TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP, NCSI
 };
 
 extern char	net_boot_file_name[1024];/* Boot File name */
diff --git a/include/phy.h b/include/phy.h
index ad2096c..0737c4e 100644
--- a/include/phy.h
+++ b/include/phy.h
@@ -412,6 +412,8 @@
 		phydev->interface <= PHY_INTERFACE_MODE_QSGMII;
 }
 
+bool phy_interface_is_ncsi(void);
+
 /* PHY UIDs for various PHYs that are referenced in external code */
 #define PHY_UID_CS4340		0x13e51002
 #define PHY_UID_CS4223		0x03e57003
diff --git a/net/net.c b/net/net.c
index f9d11c0..b27b021 100644
--- a/net/net.c
+++ b/net/net.c
@@ -93,6 +93,7 @@
 #include <net.h>
 #include <net/fastboot.h>
 #include <net/tftp.h>
+#include <net/ncsi.h>
 #if defined(CONFIG_CMD_PCAP)
 #include <net/pcap.h>
 #endif
@@ -410,6 +411,16 @@
 	net_try_count = 1;
 	debug_cond(DEBUG_INT_STATE, "--- net_loop Entry\n");
 
+#ifdef CONFIG_PHY_NCSI
+	if (phy_interface_is_ncsi() && protocol != NCSI && !ncsi_active()) {
+		printf("%s: configuring NCSI first\n", __func__);
+		if (net_loop(NCSI) < 0)
+			return ret;
+		eth_init_state_only();
+		goto restart;
+	}
+#endif
+
 	bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start");
 	net_init();
 	if (eth_is_on_demand_init()) {
@@ -423,6 +434,7 @@
 	} else {
 		eth_init_state_only();
 	}
+
 restart:
 #ifdef CONFIG_USB_KEYBOARD
 	net_busy_flag = 0;
@@ -527,6 +539,11 @@
 			wol_start();
 			break;
 #endif
+#if defined(CONFIG_PHY_NCSI)
+		case NCSI:
+			ncsi_probe_packages();
+			break;
+#endif
 		default:
 			break;
 		}
@@ -637,7 +654,7 @@
 				env_set_hex("filesize", net_boot_file_size);
 				env_set_hex("fileaddr", image_load_addr);
 			}
-			if (protocol != NETCONS)
+			if (protocol != NETCONS && protocol != NCSI)
 				eth_halt();
 			else
 				eth_halt_state_only();
@@ -1322,6 +1339,11 @@
 		wol_receive(ip, len);
 		break;
 #endif
+#ifdef CONFIG_PHY_NCSI
+	case PROT_NCSI:
+		ncsi_receive(et, ip, len);
+		break;
+#endif
 	}
 }
 
@@ -1382,6 +1404,9 @@
 #ifdef CONFIG_CMD_RARP
 	case RARP:
 #endif
+#ifdef CONFIG_PHY_NCSI
+	case NCSI:
+#endif
 	case BOOTP:
 	case CDP:
 	case DHCP:
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index 15d39a6..4c760fe 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -246,7 +246,6 @@
 CONFIG_KM_DEV_ENV_FLASH_BOOT_UBI
 CONFIG_KM_ECC_MODE
 CONFIG_KM_NEW_ENV
-CONFIG_KM_ROOTFSSIZE
 CONFIG_KM_UBI_LINUX_MTD
 CONFIG_KM_UBI_PARTITION_NAME_APP
 CONFIG_KM_UBI_PARTITION_NAME_BOOT
diff --git a/test/run b/test/run
index 810b47e..c4ab046 100755
--- a/test/run
+++ b/test/run
@@ -51,9 +51,9 @@
 run_test "sandbox_spl" ./test/py/test.py --bd sandbox_spl --build ${para} \
 		-k 'test_ofplatdata or test_handoff or test_spl'
 
-# Run the sane tests with sandbox_noinst (i.e. without OF_PLATDATA_INST)
+# Run the same tests with sandbox_noinst (i.e. without OF_PLATDATA_INST)
 echo "${prompt}"
-run_test "sandbox_spl" ./test/py/test.py --bd sandbox_noinst --build ${para} \
+run_test "sandbox_noinst" ./test/py/test.py --bd sandbox_noinst --build ${para} \
 		-k 'test_ofplatdata or test_handoff or test_spl'
 
 if [ -z "$tools_only" ]; then