Blame view
cmd/mdio.c
7.08 KB
83d290c56 SPDX: Convert all... |
1 |
// SPDX-License-Identifier: GPL-2.0+ |
995daa0b8 Add mdio command ... |
2 3 4 |
/* * (C) Copyright 2011 Freescale Semiconductor, Inc * Andy Fleming |
76048fc70 mdio: Save previo... |
5 |
* Copyright 2017 NXP |
995daa0b8 Add mdio command ... |
6 7 8 9 10 11 12 13 14 15 |
*/ /* * MDIO Commands */ #include <common.h> #include <command.h> #include <miiphy.h> #include <phy.h> |
995daa0b8 Add mdio command ... |
16 17 18 19 20 21 22 23 24 25 26 27 |
static char last_op[2]; static uint last_data; static uint last_addr_lo; static uint last_addr_hi; static uint last_devad_lo; static uint last_devad_hi; static uint last_reg_lo; static uint last_reg_hi; static int extract_range(char *input, int *plo, int *phi) { char *end; |
15a2acdf8 common: miiphyuti... |
28 |
*plo = simple_strtol(input, &end, 16); |
995daa0b8 Add mdio command ... |
29 30 31 32 |
if (end == input) return -1; if ((*end == '-') && *(++end)) |
15a2acdf8 common: miiphyuti... |
33 |
*phi = simple_strtol(end, NULL, 16); |
995daa0b8 Add mdio command ... |
34 35 36 37 38 39 40 |
else if (*end == '\0') *phi = *plo; else return -1; return 0; } |
e55047ec5 cmd: mdio: Switch... |
41 |
static int mdio_write_ranges(struct mii_dev *bus, |
26b807c4f net: add support ... |
42 |
int addrlo, |
088f1b199 common/cmd_*.c: s... |
43 |
int addrhi, int devadlo, int devadhi, |
26b807c4f net: add support ... |
44 45 |
int reglo, int reghi, unsigned short data, int extended) |
995daa0b8 Add mdio command ... |
46 |
{ |
e55047ec5 cmd: mdio: Switch... |
47 |
struct phy_device *phydev; |
995daa0b8 Add mdio command ... |
48 49 50 51 |
int addr, devad, reg; int err = 0; for (addr = addrlo; addr <= addrhi; addr++) { |
e55047ec5 cmd: mdio: Switch... |
52 |
phydev = bus->phymap[addr]; |
995daa0b8 Add mdio command ... |
53 54 |
for (devad = devadlo; devad <= devadhi; devad++) { for (reg = reglo; reg <= reghi; reg++) { |
b4c20f20a cmd: mdio: Fix ac... |
55 56 57 58 |
if (!phydev) err = bus->write(bus, addr, devad, reg, data); else if (!extended) |
e55047ec5 cmd: mdio: Switch... |
59 60 |
err = phy_write_mmd(phydev, devad, reg, data); |
26b807c4f net: add support ... |
61 62 63 |
else err = phydev->drv->writeext(phydev, addr, devad, reg, data); |
995daa0b8 Add mdio command ... |
64 65 66 67 68 69 70 71 72 73 |
if (err) goto err_out; } } } err_out: return err; } |
e55047ec5 cmd: mdio: Switch... |
74 |
static int mdio_read_ranges(struct mii_dev *bus, |
26b807c4f net: add support ... |
75 |
int addrlo, |
088f1b199 common/cmd_*.c: s... |
76 |
int addrhi, int devadlo, int devadhi, |
26b807c4f net: add support ... |
77 |
int reglo, int reghi, int extended) |
995daa0b8 Add mdio command ... |
78 79 |
{ int addr, devad, reg; |
e55047ec5 cmd: mdio: Switch... |
80 |
struct phy_device *phydev; |
995daa0b8 Add mdio command ... |
81 82 83 84 |
printf("Reading from bus %s ", bus->name); for (addr = addrlo; addr <= addrhi; addr++) { |
e55047ec5 cmd: mdio: Switch... |
85 |
phydev = bus->phymap[addr]; |
15a2acdf8 common: miiphyuti... |
86 87 |
printf("PHY at address %x: ", addr); |
995daa0b8 Add mdio command ... |
88 89 90 |
for (devad = devadlo; devad <= devadhi; devad++) { for (reg = reglo; reg <= reghi; reg++) { |
a621b167b common/cmd_mdio.c... |
91 |
int val; |
995daa0b8 Add mdio command ... |
92 |
|
b4c20f20a cmd: mdio: Fix ac... |
93 94 95 |
if (!phydev) val = bus->read(bus, addr, devad, reg); else if (!extended) |
e55047ec5 cmd: mdio: Switch... |
96 |
val = phy_read_mmd(phydev, devad, reg); |
26b807c4f net: add support ... |
97 98 99 |
else val = phydev->drv->readext(phydev, addr, devad, reg); |
995daa0b8 Add mdio command ... |
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
if (val < 0) { printf("Error "); return val; } if (devad >= 0) printf("%d.", devad); printf("%d - 0x%x ", reg, val & 0xffff); } } } return 0; } /* The register will be in the form [a[-b].]x[-y] */ |
088f1b199 common/cmd_*.c: s... |
120 121 |
static int extract_reg_range(char *input, int *devadlo, int *devadhi, int *reglo, int *reghi) |
995daa0b8 Add mdio command ... |
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
{ char *regstr; /* use strrchr to find the last string after a '.' */ regstr = strrchr(input, '.'); /* If it exists, extract the devad(s) */ if (regstr) { char devadstr[32]; strncpy(devadstr, input, regstr - input); devadstr[regstr - input] = '\0'; if (extract_range(devadstr, devadlo, devadhi)) return -1; regstr++; } else { /* Otherwise, we have no devad, and we just got regs */ *devadlo = *devadhi = MDIO_DEVAD_NONE; regstr = input; } return extract_range(regstr, reglo, reghi); } |
088f1b199 common/cmd_*.c: s... |
148 |
static int extract_phy_range(char *const argv[], int argc, struct mii_dev **bus, |
26b807c4f net: add support ... |
149 |
struct phy_device **phydev, |
088f1b199 common/cmd_*.c: s... |
150 |
int *addrlo, int *addrhi) |
995daa0b8 Add mdio command ... |
151 |
{ |
26b807c4f net: add support ... |
152 |
struct phy_device *dev = *phydev; |
995daa0b8 Add mdio command ... |
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
if ((argc < 1) || (argc > 2)) return -1; /* If there are two arguments, it's busname addr */ if (argc == 2) { *bus = miiphy_get_dev_by_name(argv[0]); if (!*bus) return -1; return extract_range(argv[1], addrlo, addrhi); } /* It must be one argument, here */ /* * This argument can be one of two things: * 1) Ethernet device name * 2) Just an address (use the previously-used bus) * * We check all buses for a PHY which is connected to an ethernet * device by the given name. If none are found, we call * extract_range() on the string, and see if it's an address range. */ |
26b807c4f net: add support ... |
178 |
dev = mdio_phydev_for_ethname(argv[0]); |
995daa0b8 Add mdio command ... |
179 |
|
26b807c4f net: add support ... |
180 181 182 |
if (dev) { *addrlo = *addrhi = dev->addr; *bus = dev->bus; |
995daa0b8 Add mdio command ... |
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
return 0; } /* It's an address or nothing useful */ return extract_range(argv[0], addrlo, addrhi); } /* ---------------------------------------------------------------- */ static int do_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char op[2]; int addrlo, addrhi, reglo, reghi, devadlo, devadhi; unsigned short data; int pos = argc - 1; struct mii_dev *bus; |
26b807c4f net: add support ... |
199 200 |
struct phy_device *phydev = NULL; int extended = 0; |
995daa0b8 Add mdio command ... |
201 202 |
if (argc < 2) |
4c12eeb8b Convert cmd_usage... |
203 |
return CMD_RET_USAGE; |
995daa0b8 Add mdio command ... |
204 |
|
c3452b50c net: introduce MD... |
205 206 207 208 |
#ifdef CONFIG_DM_MDIO /* probe DM MII device before any operation so they are all accesible */ dm_mdio_probe_devices(); #endif |
995daa0b8 Add mdio command ... |
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
/* * We use the last specified parameters, unless new ones are * entered. */ op[0] = argv[1][0]; addrlo = last_addr_lo; addrhi = last_addr_hi; devadlo = last_devad_lo; devadhi = last_devad_hi; reglo = last_reg_lo; reghi = last_reg_hi; data = last_data; bus = mdio_get_current_dev(); if (flag & CMD_FLAG_REPEAT) op[0] = last_op[0]; |
26b807c4f net: add support ... |
226 227 228 229 230 231 232 233 234 235 236 |
if (strlen(argv[1]) > 1) { op[1] = argv[1][1]; if (op[1] == 'x') { phydev = mdio_phydev_for_ethname(argv[2]); if (phydev) { addrlo = phydev->addr; addrhi = addrlo; bus = phydev->bus; extended = 1; } else { |
e55047ec5 cmd: mdio: Switch... |
237 |
return CMD_RET_FAILURE; |
26b807c4f net: add support ... |
238 239 240 241 242 243 244 |
} if (!phydev->drv || (!phydev->drv->writeext && (op[0] == 'w')) || (!phydev->drv->readext && (op[0] == 'r'))) { puts("PHY does not have extended functions "); |
e55047ec5 cmd: mdio: Switch... |
245 |
return CMD_RET_FAILURE; |
26b807c4f net: add support ... |
246 247 248 |
} } } |
995daa0b8 Add mdio command ... |
249 250 251 252 |
switch (op[0]) { case 'w': if (pos > 1) data = simple_strtoul(argv[pos--], NULL, 16); |
14a8adebb net: mdio: Clarif... |
253 |
/* Intentional fall-through - Get reg for read and write */ |
995daa0b8 Add mdio command ... |
254 255 256 |
case 'r': if (pos > 1) if (extract_reg_range(argv[pos--], &devadlo, &devadhi, |
c55038988 cmd: mdio: Fix st... |
257 |
®lo, ®hi)) |
e55047ec5 cmd: mdio: Switch... |
258 |
return CMD_RET_FAILURE; |
14a8adebb net: mdio: Clarif... |
259 |
/* Intentional fall-through - Get phy for all commands */ |
995daa0b8 Add mdio command ... |
260 261 |
default: if (pos > 1) |
c55038988 cmd: mdio: Fix st... |
262 263 |
if (extract_phy_range(&argv[2], pos - 1, &bus, &phydev, &addrlo, &addrhi)) |
e55047ec5 cmd: mdio: Switch... |
264 |
return CMD_RET_FAILURE; |
995daa0b8 Add mdio command ... |
265 266 267 |
break; } |
cb58d18be cmd: mdio: preven... |
268 269 270 271 272 |
if (!bus) { puts("No MDIO bus found "); return CMD_RET_FAILURE; } |
995daa0b8 Add mdio command ... |
273 274 275 276 277 |
/* Save the chosen bus */ miiphy_set_current_dev(bus->name); switch (op[0]) { case 'w': |
e55047ec5 cmd: mdio: Switch... |
278 |
mdio_write_ranges(bus, addrlo, addrhi, devadlo, devadhi, |
26b807c4f net: add support ... |
279 |
reglo, reghi, data, extended); |
995daa0b8 Add mdio command ... |
280 281 282 |
break; case 'r': |
e55047ec5 cmd: mdio: Switch... |
283 |
mdio_read_ranges(bus, addrlo, addrhi, devadlo, devadhi, |
26b807c4f net: add support ... |
284 |
reglo, reghi, extended); |
995daa0b8 Add mdio command ... |
285 |
break; |
76048fc70 mdio: Save previo... |
286 287 288 289 |
case 'l': mdio_list_devices(); break; |
995daa0b8 Add mdio command ... |
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 |
} /* * Save the parameters for repeats. */ last_op[0] = op[0]; last_addr_lo = addrlo; last_addr_hi = addrhi; last_devad_lo = devadlo; last_devad_hi = devadhi; last_reg_lo = reglo; last_reg_hi = reghi; last_data = data; return 0; } /***************************************************/ U_BOOT_CMD( mdio, 6, 1, do_mdio, "MDIO utility commands", "list - List MDIO buses " "mdio read <phydev> [<devad>.]<reg> - " "read PHY's register at <devad>.<reg> " "mdio write <phydev> [<devad>.]<reg> <data> - " "write PHY's register at <devad>.<reg> " |
26b807c4f net: add support ... |
320 321 322 323 324 325 |
"mdio rx <phydev> [<devad>.]<reg> - " "read PHY's extended register at <devad>.<reg> " "mdio wx <phydev> [<devad>.]<reg> <data> - " "write PHY's extended register at <devad>.<reg> " |
995daa0b8 Add mdio command ... |
326 327 328 329 330 331 332 333 334 335 336 |
"<phydev> may be: " " <busname> <addr> " " <addr> " " <eth name> " "<addr> <devad>, and <reg> may be ranges, e.g. 1-5.4-0x1f. " ); |