[U-Boot] [PATCH v4 4/4] test: dm: add a test for MDIO MUX DM uclass
Alex Marginean
alexandru.marginean at nxp.com
Thu Jul 11 07:07:18 UTC 2019
Adds a test using a makeshift MDIO MUX. The test is based on the existing
MDIO test. It uses the last emulated PHY register to verify MUX selection.
Signed-off-by: Alex Marginean <alexm.osslist at gmail.com>
---
Changes in v2:
- no change
Changes in v3:
- no change, just fighting with the email server
Changes in v4:
- a more explicit comment on why relative ordering between mdio-test and
mdio-mux-test nodes in test.dts matters.
arch/Kconfig | 1 +
arch/sandbox/dts/test.dts | 23 +++++++-
drivers/net/Kconfig | 10 ++++
drivers/net/Makefile | 1 +
drivers/net/mdio_mux_sandbox.c | 97 ++++++++++++++++++++++++++++++++++
test/dm/Makefile | 1 +
test/dm/mdio_mux.c | 80 ++++++++++++++++++++++++++++
7 files changed, 212 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/mdio_mux_sandbox.c
create mode 100644 test/dm/mdio_mux.c
diff --git a/arch/Kconfig b/arch/Kconfig
index a6b2de8527..6dd0874d7c 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -123,6 +123,7 @@ config SANDBOX
imply PCH
imply PHYLIB
imply DM_MDIO
+ imply DM_MDIO_MUX
config SH
bool "SuperH architecture"
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index dd50a951a8..a88cf75652 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -808,7 +808,28 @@
dma-names = "m2m", "tx0", "rx0";
};
- mdio-test {
+ /*
+ * keep mdio-mux ahead of mdio so that the mux is removed first at the
+ * end of the test. If parent mdio is removed first, clean-up of the
+ * mux will trigger a 2nd probe of parent-mdio, leaving parent-mdio
+ * active at the end of the test. That it turn doesn't allow the mdio
+ * class to be destroyed, triggering an error.
+ */
+ mdio-mux-test {
+ compatible = "sandbox,mdio-mux";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ mdio-parent-bus = <&mdio>;
+
+ mdio-ch-test at 0 {
+ reg = <0>;
+ };
+ mdio-ch-test at 1 {
+ reg = <1>;
+ };
+ };
+
+ mdio: mdio-test {
compatible = "sandbox,mdio";
};
};
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index f09f8c5f52..4d85fb1716 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -46,6 +46,16 @@ config MDIO_SANDBOX
This driver is used in for testing in test/dm/mdio.c
+config MDIO_MUX_SANDBOX
+ depends on DM_MDIO_MUX && MDIO_SANDBOX
+ default y
+ bool "Sandbox: Mocked MDIO-MUX driver"
+ help
+ This driver implements dummy select/deselect ops mimicking a MUX on
+ the MDIO bux. It uses mdio_sandbox driver as parent MDIO.
+
+ This driver is used for testing in test/dm/mdio.c
+
menuconfig NETDEVICES
bool "Network device support"
depends on NET
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 1247b39a54..97119cec7c 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -79,3 +79,4 @@ obj-y += mscc_eswitch/
obj-$(CONFIG_HIGMACV300_ETH) += higmacv300.o
obj-$(CONFIG_MDIO_SANDBOX) += mdio_sandbox.o
obj-$(CONFIG_FSL_ENETC) += fsl_enetc.o fsl_enetc_mdio.o
+obj-$(CONFIG_MDIO_MUX_SANDBOX) += mdio_mux_sandbox.o
diff --git a/drivers/net/mdio_mux_sandbox.c b/drivers/net/mdio_mux_sandbox.c
new file mode 100644
index 0000000000..3dba4d18a1
--- /dev/null
+++ b/drivers/net/mdio_mux_sandbox.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019
+ * Alex Marginean, NXP
+ */
+
+#include <dm.h>
+#include <errno.h>
+#include <miiphy.h>
+
+/* macros copied over from mdio_sandbox.c */
+#define SANDBOX_PHY_ADDR 5
+#define SANDBOX_PHY_REG_CNT 2
+
+struct mdio_mux_sandbox_priv {
+ int enabled;
+ int sel;
+};
+
+static int mdio_mux_sandbox_mark_selection(struct udevice *dev, int sel)
+{
+ struct udevice *mdio;
+ struct mdio_ops *ops;
+ int err;
+
+ /*
+ * find the sandbox parent mdio and write a register on the PHY there
+ * so the mux test can verify selection.
+ */
+ err = uclass_get_device_by_name(UCLASS_MDIO, "mdio-test", &mdio);
+ if (err)
+ return err;
+ ops = mdio_get_ops(mdio);
+ return ops->write(mdio, SANDBOX_PHY_ADDR, MDIO_DEVAD_NONE,
+ SANDBOX_PHY_REG_CNT - 1, (u16)sel);
+}
+
+static int mdio_mux_sandbox_select(struct udevice *dev, int cur, int sel)
+{
+ struct mdio_mux_sandbox_priv *priv = dev_get_priv(dev);
+
+ if (!priv->enabled)
+ return -ENODEV;
+
+ if (cur != priv->sel)
+ return -EINVAL;
+
+ priv->sel = sel;
+ mdio_mux_sandbox_mark_selection(dev, priv->sel);
+
+ return 0;
+}
+
+static int mdio_mux_sandbox_deselect(struct udevice *dev, int sel)
+{
+ struct mdio_mux_sandbox_priv *priv = dev_get_priv(dev);
+
+ if (!priv->enabled)
+ return -ENODEV;
+
+ if (sel != priv->sel)
+ return -EINVAL;
+
+ priv->sel = -1;
+ mdio_mux_sandbox_mark_selection(dev, priv->sel);
+
+ return 0;
+}
+
+static const struct mdio_mux_ops mdio_mux_sandbox_ops = {
+ .select = mdio_mux_sandbox_select,
+ .deselect = mdio_mux_sandbox_deselect,
+};
+
+static int mdio_mux_sandbox_probe(struct udevice *dev)
+{
+ struct mdio_mux_sandbox_priv *priv = dev_get_priv(dev);
+
+ priv->enabled = 1;
+ priv->sel = -1;
+
+ return 0;
+}
+
+static const struct udevice_id mdio_mux_sandbox_ids[] = {
+ { .compatible = "sandbox,mdio-mux" },
+ { }
+};
+
+U_BOOT_DRIVER(mdio_mux_sandbox) = {
+ .name = "mdio_mux_sandbox",
+ .id = UCLASS_MDIO_MUX,
+ .of_match = mdio_mux_sandbox_ids,
+ .probe = mdio_mux_sandbox_probe,
+ .ops = &mdio_mux_sandbox_ops,
+ .priv_auto_alloc_size = sizeof(struct mdio_mux_sandbox_priv),
+};
diff --git a/test/dm/Makefile b/test/dm/Makefile
index 3f042e3ab4..8b3477c136 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -61,4 +61,5 @@ obj-$(CONFIG_TEE) += tee.o
obj-$(CONFIG_VIRTIO_SANDBOX) += virtio.o
obj-$(CONFIG_DMA) += dma.o
obj-$(CONFIG_DM_MDIO) += mdio.o
+obj-$(CONFIG_DM_MDIO_MUX) += mdio_mux.o
endif
diff --git a/test/dm/mdio_mux.c b/test/dm/mdio_mux.c
new file mode 100644
index 0000000000..f962e09dbc
--- /dev/null
+++ b/test/dm/mdio_mux.c
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019
+ * Alex Marginean, NXP
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/test.h>
+#include <misc.h>
+#include <test/ut.h>
+#include <miiphy.h>
+
+/* macros copied over from mdio_sandbox.c */
+#define SANDBOX_PHY_ADDR 5
+#define SANDBOX_PHY_REG_CNT 2
+
+#define TEST_REG_VALUE 0xabcd
+
+static int dm_test_mdio_mux(struct unit_test_state *uts)
+{
+ struct uclass *uc;
+ struct udevice *mux;
+ struct udevice *mdio_ch0, *mdio_ch1, *mdio;
+ struct mdio_ops *ops, *ops_parent;
+ struct mdio_mux_ops *mmops;
+ u16 reg;
+
+ ut_assertok(uclass_get(UCLASS_MDIO_MUX, &uc));
+
+ ut_assertok(uclass_get_device_by_name(UCLASS_MDIO_MUX, "mdio-mux-test",
+ &mux));
+
+ ut_assertok(uclass_get_device_by_name(UCLASS_MDIO, "mdio-ch-test at 0",
+ &mdio_ch0));
+ ut_assertok(uclass_get_device_by_name(UCLASS_MDIO, "mdio-ch-test at 1",
+ &mdio_ch1));
+
+ ut_assertok(uclass_get_device_by_name(UCLASS_MDIO, "mdio-test", &mdio));
+
+ ops = mdio_get_ops(mdio_ch0);
+ ut_assertnonnull(ops);
+ ut_assertnonnull(ops->read);
+ ut_assertnonnull(ops->write);
+
+ mmops = mdio_mux_get_ops(mux);
+ ut_assertnonnull(mmops);
+ ut_assertnonnull(mmops->select);
+
+ ops_parent = mdio_get_ops(mdio);
+ ut_assertnonnull(ops);
+ ut_assertnonnull(ops->read);
+
+ /*
+ * mux driver sets last register on the emulated PHY whenever a group
+ * is selected to the selection #. Just reading that register from
+ * either of the child buses should return the id of the child bus
+ */
+ reg = ops->read(mdio_ch0, SANDBOX_PHY_ADDR, MDIO_DEVAD_NONE,
+ SANDBOX_PHY_REG_CNT - 1);
+ ut_asserteq(reg, 0);
+
+ reg = ops->read(mdio_ch1, SANDBOX_PHY_ADDR, MDIO_DEVAD_NONE,
+ SANDBOX_PHY_REG_CNT - 1);
+ ut_asserteq(reg, 1);
+
+ mmops->select(mux, MDIO_MUX_SELECT_NONE, 5);
+ reg = ops_parent->read(mdio, SANDBOX_PHY_ADDR, MDIO_DEVAD_NONE,
+ SANDBOX_PHY_REG_CNT - 1);
+ ut_asserteq(reg, 5);
+
+ mmops->deselect(mux, 5);
+ reg = ops_parent->read(mdio, SANDBOX_PHY_ADDR, MDIO_DEVAD_NONE,
+ SANDBOX_PHY_REG_CNT - 1);
+ ut_asserteq(reg, (u16)MDIO_MUX_SELECT_NONE);
+
+ return 0;
+}
+
+DM_TEST(dm_test_mdio_mux, DM_TESTF_SCAN_FDT);
--
2.17.1
More information about the U-Boot
mailing list