[U-Boot] [PATCH v2] mii: add read-modify-write option to mii command

Tim James tim.james at macltd.com
Wed Mar 25 12:55:15 CET 2015


When accessing PHY registers it is often desirable to only update
selected bits, so it is necessary to first read the current value
before writing back an modified value with the relevant bits
updated.

To simplify this and to allow such operations to be incorporated
into simple shell scripts propose adding a 'modify' option to the
existing mii command, which takes a mask indicating the bits to
be updated in addition to a data value containing the new bits,
ie, <updated> = (<data> & <mask>) | (<current> & ~<mask>).

Signed-off-by: Tim <tim.james at macltd.com>
Cc: Nobuhiro Iwamatsu <iwamatsu at nigauri.org>
Cc: Joe Hershberger <joe.hershberger at gmail.com>
Cc: Jeroen Hofstee <jeroen at myspectrum.nl>
Cc: Tom Rini <trini at konsulko.com>
Cc: Tim <tim.james at macltd.com>
---
Changes for v2:
 - Addressed checkpatch.pl messages.
 - No functional changes.

 common/cmd_mii.c | 47 ++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 38 insertions(+), 9 deletions(-)

diff --git a/common/cmd_mii.c b/common/cmd_mii.c
index 7c4a57a..d9d7f7b 100644
--- a/common/cmd_mii.c
+++ b/common/cmd_mii.c
@@ -249,6 +249,7 @@ static uint last_addr_lo;
 static uint last_addr_hi;
 static uint last_reg_lo;
 static uint last_reg_hi;
+static uint last_mask;
 
 static void extract_range(
 	char * input,
@@ -272,7 +273,7 @@ static int do_mii(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	char		op[2];
 	unsigned char	addrlo, addrhi, reglo, reghi;
 	unsigned char	addr, reg;
-	unsigned short	data;
+	unsigned short	data, mask;
 	int		rcode = 0;
 	const char	*devname;
 
@@ -294,6 +295,7 @@ static int do_mii(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	reglo  = last_reg_lo;
 	reghi  = last_reg_hi;
 	data   = last_data;
+	mask   = last_mask;
 
 	if ((flag & CMD_FLAG_REPEAT) == 0) {
 		op[0] = argv[1][0];
@@ -307,7 +309,9 @@ static int do_mii(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 		if (argc >= 4)
 			extract_range(argv[3], &reglo, &reghi);
 		if (argc >= 5)
-			data = simple_strtoul (argv[4], NULL, 16);
+			data = simple_strtoul(argv[4], NULL, 16);
+		if (argc >= 6)
+			mask = simple_strtoul(argv[5], NULL, 16);
 	}
 
 	/* use current device */
@@ -375,6 +379,28 @@ static int do_mii(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 				}
 			}
 		}
+	} else if (op[0] == 'm') {
+		for (addr = addrlo; addr <= addrhi; addr++) {
+			for (reg = reglo; reg <= reghi; reg++) {
+				unsigned short val = 0;
+				if (miiphy_read(devname, addr,
+						reg, &val)) {
+					printf("Error reading from the PHY");
+					printf(" addr=%02x", addr);
+					printf(" reg=%02x\n", reg);
+					rcode = 1;
+				} else {
+					val = (val & ~mask) | (data & mask);
+					if (miiphy_write(devname, addr,
+							 reg, val)) {
+						printf("Error writing to the PHY");
+						printf(" addr=%02x", addr);
+						printf(" reg=%02x\n", reg);
+						rcode = 1;
+					}
+				}
+			}
+		}
 	} else if (strncmp(op, "du", 2) == 0) {
 		ushort regs[6];
 		int ok = 1;
@@ -417,6 +443,7 @@ static int do_mii(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	last_reg_lo  = reglo;
 	last_reg_hi  = reghi;
 	last_data    = data;
+	last_mask    = mask;
 
 	return rcode;
 }
@@ -424,13 +451,15 @@ static int do_mii(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 /***************************************************/
 
 U_BOOT_CMD(
-	mii,	5,	1,	do_mii,
+	mii, 6, 1, do_mii,
 	"MII utility commands",
-	"device                     - list available devices\n"
-	"mii device <devname>           - set current device\n"
-	"mii info   <addr>              - display MII PHY info\n"
-	"mii read   <addr> <reg>        - read  MII PHY <addr> register <reg>\n"
-	"mii write  <addr> <reg> <data> - write MII PHY <addr> register <reg>\n"
-	"mii dump   <addr> <reg>        - pretty-print <addr> <reg> (0-5 only)\n"
+	"device                            - list available devices\n"
+	"mii device <devname>                  - set current device\n"
+	"mii info   <addr>                     - display MII PHY info\n"
+	"mii read   <addr> <reg>               - read  MII PHY <addr> register <reg>\n"
+	"mii write  <addr> <reg> <data>        - write MII PHY <addr> register <reg>\n"
+	"mii modify <addr> <reg> <data> <mask> - modify MII PHY <addr> register <reg>\n"
+	"                                        updating bits identified in <mask>\n"
+	"mii dump   <addr> <reg>               - pretty-print <addr> <reg> (0-5 only)\n"
 	"Addr and/or reg may be ranges, e.g. 2-7."
 );
-- 
1.9.1


More information about the U-Boot mailing list