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