Message ID | 20190124085600.18886-4-ccaione@baylibre.com |
---|---|
State | Superseded |
Delegated to: | Joe Hershberger |
Headers | show |
Series | Add MMD PHY helpers | expand |
On 1/24/19 10:56 AM, Carlo Caione wrote: > Two new parameters (rmmd and wmmd) are added to allow the `mdio` command > to access the content of the MMD PHY registers. > > Signed-off-by: Carlo Caione <ccaione@baylibre.com> > Acked-by: Joe Hershberger <joe.hershberger@ni.com> > --- > cmd/mdio.c | 52 +++++++++++++++++++++++++++++++++++++--------------- > 1 file changed, 37 insertions(+), 15 deletions(-) > > diff --git a/cmd/mdio.c b/cmd/mdio.c > index 184868063a..5138db505a 100644 > --- a/cmd/mdio.c > +++ b/cmd/mdio.c > @@ -43,7 +43,7 @@ static int mdio_write_ranges(struct phy_device *phydev, struct mii_dev *bus, > int addrlo, > int addrhi, int devadlo, int devadhi, > int reglo, int reghi, unsigned short data, > - int extended) > + int extended, int mmd) > { > int addr, devad, reg; > int err = 0; > @@ -51,12 +51,15 @@ static int mdio_write_ranges(struct phy_device *phydev, struct mii_dev *bus, > for (addr = addrlo; addr <= addrhi; addr++) { > for (devad = devadlo; devad <= devadhi; devad++) { > for (reg = reglo; reg <= reghi; reg++) { > - if (!extended) > - err = bus->write(bus, addr, devad, > - reg, data); > - else > + if (mmd) > + err = phy_write_mmd(phydev, devad, reg, > + data); > + else if (extended) > err = phydev->drv->writeext(phydev, > addr, devad, reg, data); > + else > + err = bus->write(bus, addr, devad, > + reg, data); > > if (err) > goto err_out; > @@ -71,7 +74,7 @@ err_out: > static int mdio_read_ranges(struct phy_device *phydev, struct mii_dev *bus, > int addrlo, > int addrhi, int devadlo, int devadhi, > - int reglo, int reghi, int extended) > + int reglo, int reghi, int extended, int mmd) > { > int addr, devad, reg; > > @@ -83,11 +86,13 @@ static int mdio_read_ranges(struct phy_device *phydev, struct mii_dev *bus, > for (reg = reglo; reg <= reghi; reg++) { > int val; > > - if (!extended) > - val = bus->read(bus, addr, devad, reg); > - else > + if (mmd) > + val = phy_read_mmd(phydev, devad, reg); > + else if (extended) > val = phydev->drv->readext(phydev, addr, > devad, reg); > + else > + val = bus->read(bus, addr, devad, reg); > > if (val < 0) { > printf("Error\n"); > @@ -189,6 +194,7 @@ static int do_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) > struct mii_dev *bus; > struct phy_device *phydev = NULL; > int extended = 0; > + int mmd = 0; > > if (argc < 2) > return CMD_RET_USAGE; > @@ -222,14 +228,26 @@ static int do_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) > bus = phydev->bus; > extended = 1; > } else { > - return -1; > + return CMD_RET_FAILURE; > } > > if (!phydev->drv || > (!phydev->drv->writeext && (op[0] == 'w')) || > (!phydev->drv->readext && (op[0] == 'r'))) { > puts("PHY does not have extended functions\n"); > - return -1; > + return CMD_RET_FAILURE; > + } > + } > + if (op[1] == 'm') { > + phydev = mdio_phydev_for_ethname(argv[2]); > + > + if (phydev) { > + addrlo = phydev->addr; > + addrhi = addrlo; > + bus = phydev->bus; > + mmd = 1; > + } else { > + return CMD_RET_FAILURE; > } > } > } > @@ -242,13 +260,13 @@ static int do_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) > if (pos > 1) > if (extract_reg_range(argv[pos--], &devadlo, &devadhi, > ®lo, ®hi)) > - return -1; > + return CMD_RET_FAILURE; > > default: > if (pos > 1) > if (extract_phy_range(&argv[2], pos - 1, &bus, > &phydev, &addrlo, &addrhi)) > - return -1; > + return CMD_RET_FAILURE; > > break; > } > @@ -265,12 +283,12 @@ static int do_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) > switch (op[0]) { > case 'w': > mdio_write_ranges(phydev, bus, addrlo, addrhi, devadlo, devadhi, > - reglo, reghi, data, extended); > + reglo, reghi, data, extended, mmd); > break; > > case 'r': > mdio_read_ranges(phydev, bus, addrlo, addrhi, devadlo, devadhi, > - reglo, reghi, extended); > + reglo, reghi, extended, mmd); > break; > } > > @@ -303,6 +321,10 @@ U_BOOT_CMD( > "read PHY's extended register at <devad>.<reg>\n" > "mdio wx <phydev> [<devad>.]<reg> <data> - " > "write PHY's extended register at <devad>.<reg>\n" > + "mdio rmmd <phydev> [<devad>.]<reg> - " > + "read PHY's extended register at <devad>.<reg>\n" > + "mdio wmmd <phydev> [<devad>.]<reg> <data> - " > + "write PHY's extended register at <devad>.<reg>\n" > "<phydev> may be:\n" > " <busname> <addr>\n" > " <addr>\n" > It works for me, but I do have a question. Is there any limitation preventing you to add this functionality via the standard "mdio read x.y" instead of "mdio rmmd x.y" if the PHY is known to be C22? -Vladimir
On 24/01/2019 19:56, Vladimir Oltean wrote: > On 1/24/19 10:56 AM, Carlo Caione wrote: > It works for me, but I do have a question. > Is there any limitation preventing you to add this functionality via the > standard "mdio read x.y" instead of "mdio rmmd x.y" if the PHY is known > to be C22? You can used the standard "mdio read" but it's more verbose and hard to recall: mdio write 0 0.d 0x3 mdio write 0 0.e 0x1 mdio write 0 0.d 0x4003 mdio read 0 0.e vs mdio rmmd 3.1 -- Carlo Caione
On 1/24/19 10:01 PM, Carlo Caione wrote: > On 24/01/2019 19:56, Vladimir Oltean wrote: >> On 1/24/19 10:56 AM, Carlo Caione wrote: > >> It works for me, but I do have a question. >> Is there any limitation preventing you to add this functionality via the >> standard "mdio read x.y" instead of "mdio rmmd x.y" if the PHY is known >> to be C22? > > You can used the standard "mdio read" but it's more verbose and hard to > recall: > > mdio write 0 0.d 0x3 > mdio write 0 0.e 0x1 > mdio write 0 0.d 0x4003 > mdio read 0 0.e > > vs > > mdio rmmd 3.1 > > -- > Carlo Caione > No, I mean instead of doing "mdio rmmd 3.1" to do "mdio read 3.1" (basically not define a new command).
On 24/01/2019 20:04, Vladimir Oltean wrote: > On 1/24/19 10:01 PM, Carlo Caione wrote: >> On 24/01/2019 19:56, Vladimir Oltean wrote: >>> On 1/24/19 10:56 AM, Carlo Caione wrote: > > No, I mean instead of doing "mdio rmmd 3.1" to do "mdio read 3.1" > (basically not define a new command). Ooooh, I think you can do that only on C45 PHYs, not on C22. (tested on my board and it didn't work FWIW). Cheers, -- Carlo Caione
On 1/24/19 10:08 PM, Carlo Caione wrote: > On 24/01/2019 20:04, Vladimir Oltean wrote: >> On 1/24/19 10:01 PM, Carlo Caione wrote: >>> On 24/01/2019 19:56, Vladimir Oltean wrote: >>>> On 1/24/19 10:56 AM, Carlo Caione wrote: >> >> No, I mean instead of doing "mdio rmmd 3.1" to do "mdio read 3.1" >> (basically not define a new command). > > Ooooh, I think you can do that only on C45 PHYs, not on C22. > (tested on my board and it didn't work FWIW). > > Cheers, > > -- > Carlo Caione > > I still think I haven't successfully made my point. If "mdio read 3.1" is a C45-only thing, "mdio read 1" is a C22-only thing, then why do you need a new command "mdio rmmd 3.1" to do C45 emulation over C22? Is there any overlap I'm missing that mandates a new syntax to differentiate? Can the command not simply see whether the PHY is C22, and if it is and the MMD address is non-zero, just emulate it via 0xd and 0xe writes? -Vladimir
On 24/01/2019 20:12, Vladimir Oltean wrote: > > I still think I haven't successfully made my point. > If "mdio read 3.1" is a C45-only thing, "mdio read 1" is a C22-only > thing, then why do you need a new command "mdio rmmd 3.1" to do C45 > emulation over C22? Is there any overlap I'm missing that mandates a new > syntax to differentiate? Can the command not simply see whether the PHY > is C22, and if it is and the MMD address is non-zero, just emulate it > via 0xd and 0xe writes? Ok, I got your point now. I didn't give much thought on this TBH, good question. Do we currently have a way in U-Boot to differentiate between C22 and C45 PHYs? The generic_10g PHY should be C45 but is that the only one currently supported? -- Carlo Caione
On 1/24/19 10:19 PM, Carlo Caione wrote: > On 24/01/2019 20:12, Vladimir Oltean wrote: >> >> I still think I haven't successfully made my point. >> If "mdio read 3.1" is a C45-only thing, "mdio read 1" is a C22-only >> thing, then why do you need a new command "mdio rmmd 3.1" to do C45 >> emulation over C22? Is there any overlap I'm missing that mandates a new >> syntax to differentiate? Can the command not simply see whether the PHY >> is C22, and if it is and the MMD address is non-zero, just emulate it >> via 0xd and 0xe writes? > > Ok, I got your point now. I didn't give much thought on this TBH, good > question. > > Do we currently have a way in U-Boot to differentiate between C22 and > C45 PHYs? The generic_10g PHY should be C45 but is that the only one > currently supported? > > -- > Carlo Caione > I can't completely answer that, TBH I don't even know who is supposed to make that distinction. For Freescale parts that is a call for the MDIO bus driver to make, for good or bad (see drivers/net/fm/memac_phy.c where dev_addr is compared to MDIO_DEVAD_NONE). And in your patch, phy_write_mmd is only a wrapper over bus->write in the end, with some more logic to handle C22 indirection. So my question of unifying "mdio rmmd" with "mdio read" translates into: Does it make sense to also handle the check with MDIO_DEVAD_NONE in phy_write_mmd, instead of jumping straight ahead to perform indirection? The goal would then be to just call phy_write_mmd from cmd/mdio.c regardless of the target PHY's clause. -Vladimir
On 24/01/2019 20:48, Vladimir Oltean wrote: > On 1/24/19 10:19 PM, Carlo Caione wrote: >> On 24/01/2019 20:12, Vladimir Oltean wrote: >>> > > I can't completely answer that, TBH I don't even know who is supposed to > make that distinction. In the kernel that distinction is made by the driver itself, hence my question. See [0]. > For Freescale parts that is a call for the MDIO bus driver to make, for > good or bad (see drivers/net/fm/memac_phy.c where dev_addr is compared > to MDIO_DEVAD_NONE). > And in your patch, phy_write_mmd is only a wrapper over bus->write in > the end, with some more logic to handle C22 indirection. > So my question of unifying "mdio rmmd" with "mdio read" translates into: > Does it make sense to also handle the check with MDIO_DEVAD_NONE in > phy_write_mmd, instead of jumping straight ahead to perform indirection? Honestly I'm not quite sure of all the possible implications here IMO the safest bet here is just to follow what's done by the kernel. Maybe Joe can step in about this. In general we have 3 possible cases: 1) your driver is doing something non-standard when accessing the MMDs and we deal with that using the PHY driver hooks 2) your PHY is C22 and you have to use the indirect method 3) your PHY is C45 and you can use the direct register reading (mangling a bit the address apparently) The kernel is dealing with all the cases, U-Boot is only dealing with C22 PHYs (cases 1 and 2) because AFAICT there isn't yet a generic way to detect if the PHY is C22 or C45. I'm not sure if the indirect method works also for C45 PHYs. > The goal would then be to just call phy_write_mmd from cmd/mdio.c > regardless of the target PHY's clause. Again I wrote that patch only assuming that we were going to deal with C22 PHYs. At this point I wonder if the C22 indirect method works also for C45 PHYs. If that's the case than the phy_write_mmd should already work regardless of the target PHY clause. Cheers. [0] https://elixir.bootlin.com/linux/latest/source/drivers/net/phy/phy-core.c#L296
On 25.01.2019 12:12, Carlo Caione wrote: > On 24/01/2019 20:48, Vladimir Oltean wrote: >> On 1/24/19 10:19 PM, Carlo Caione wrote: >>> On 24/01/2019 20:12, Vladimir Oltean wrote: >>>> >> >> I can't completely answer that, TBH I don't even know who is supposed to >> make that distinction. > > In the kernel that distinction is made by the driver itself, hence my > question. See [0]. > >> For Freescale parts that is a call for the MDIO bus driver to make, for >> good or bad (see drivers/net/fm/memac_phy.c where dev_addr is compared >> to MDIO_DEVAD_NONE). > >> And in your patch, phy_write_mmd is only a wrapper over bus->write in >> the end, with some more logic to handle C22 indirection. >> So my question of unifying "mdio rmmd" with "mdio read" translates into: > >> Does it make sense to also handle the check with MDIO_DEVAD_NONE in >> phy_write_mmd, instead of jumping straight ahead to perform indirection? > > Honestly I'm not quite sure of all the possible implications here IMO > the safest bet here is just to follow what's done by the kernel. Maybe > Joe can step in about this. > > In general we have 3 possible cases: > > 1) your driver is doing something non-standard when accessing the MMDs > and we deal with that using the PHY driver hooks > 2) your PHY is C22 and you have to use the indirect method > 3) your PHY is C45 and you can use the direct register reading (mangling > a bit the address apparently) > > The kernel is dealing with all the cases, U-Boot is only dealing with > C22 PHYs (cases 1 and 2) because AFAICT there isn't yet a generic way to > detect if the PHY is C22 or C45. > > I'm not sure if the indirect method works also for C45 PHYs. > >> The goal would then be to just call phy_write_mmd from cmd/mdio.c >> regardless of the target PHY's clause. > > Again I wrote that patch only assuming that we were going to deal with > C22 PHYs. At this point I wonder if the C22 indirect method works also > for C45 PHYs. If that's the case than the phy_write_mmd should already > work regardless of the target PHY clause. > > Cheers. > > [0] > https://elixir.bootlin.com/linux/latest/source/drivers/net/phy/phy-core.c#L296 > I'm not suggesting to use C22 indirection if the PHY already supports native C45 addressing. Even if that worked, it would be a pointless exercise in all but a few cases (like the MDIO controller does not support C22, but the PHY does support both C22 and C45). I was just wondering out loud whether the introduction of the "mdio rmmd" command is justified or not. I now understand that using e.g. "mdio read 1.3" will confuse the command for clause 45 PHY's because it won't know whether it should access the PHY via native C45 or via indirect C22 (obviously it shouldn't do the latter). So in lack of a clear distinction mechanism, I now think that a new command truly is necessary for performing indirect C45 access on C22. What I am still not convinced of, however, is whether those commands should be called "rmmd" and "wmmd". It is not immediately obvious from the command description that this is what they are for, and a user may attempt to use them for C45 PHY's as well, which will probably not yield the intended result. -Vladimir
On Fri, Jan 25, 2019 at 7:12 AM Vladimir Oltean <vladimir.oltean@nxp.com> wrote: > > On 25.01.2019 12:12, Carlo Caione wrote: > > On 24/01/2019 20:48, Vladimir Oltean wrote: > >> On 1/24/19 10:19 PM, Carlo Caione wrote: > >>> On 24/01/2019 20:12, Vladimir Oltean wrote: > >>>> > >> > >> I can't completely answer that, TBH I don't even know who is supposed to > >> make that distinction. > > > > In the kernel that distinction is made by the driver itself, hence my > > question. See [0]. > > > >> For Freescale parts that is a call for the MDIO bus driver to make, for > >> good or bad (see drivers/net/fm/memac_phy.c where dev_addr is compared > >> to MDIO_DEVAD_NONE). > > > >> And in your patch, phy_write_mmd is only a wrapper over bus->write in > >> the end, with some more logic to handle C22 indirection. > >> So my question of unifying "mdio rmmd" with "mdio read" translates into: > > > >> Does it make sense to also handle the check with MDIO_DEVAD_NONE in > >> phy_write_mmd, instead of jumping straight ahead to perform indirection? > > > > Honestly I'm not quite sure of all the possible implications here IMO > > the safest bet here is just to follow what's done by the kernel. Maybe > > Joe can step in about this. > > > > In general we have 3 possible cases: > > > > 1) your driver is doing something non-standard when accessing the MMDs > > and we deal with that using the PHY driver hooks > > 2) your PHY is C22 and you have to use the indirect method > > 3) your PHY is C45 and you can use the direct register reading (mangling > > a bit the address apparently) > > > > The kernel is dealing with all the cases, U-Boot is only dealing with > > C22 PHYs (cases 1 and 2) because AFAICT there isn't yet a generic way to > > detect if the PHY is C22 or C45. > > > > I'm not sure if the indirect method works also for C45 PHYs. > > > >> The goal would then be to just call phy_write_mmd from cmd/mdio.c > >> regardless of the target PHY's clause. > > > > Again I wrote that patch only assuming that we were going to deal with > > C22 PHYs. At this point I wonder if the C22 indirect method works also > > for C45 PHYs. If that's the case than the phy_write_mmd should already > > work regardless of the target PHY clause. > > > > Cheers. > > > > [0] > > https://elixir.bootlin.com/linux/latest/source/drivers/net/phy/phy-core.c#L296 > > > > I'm not suggesting to use C22 indirection if the PHY already supports > native C45 addressing. Even if that worked, it would be a pointless > exercise in all but a few cases (like the MDIO controller does not > support C22, but the PHY does support both C22 and C45). > I was just wondering out loud whether the introduction of the "mdio > rmmd" command is justified or not. I now understand that using e.g. > "mdio read 1.3" will confuse the command for clause 45 PHY's because it > won't know whether it should access the PHY via native C45 or via > indirect C22 (obviously it shouldn't do the latter). So in lack of a > clear distinction mechanism, I now think that a new command truly is > necessary for performing indirect C45 access on C22. > What I am still not convinced of, however, is whether those commands > should be called "rmmd" and "wmmd". It is not immediately obvious from > the command description that this is what they are for, and a user may > attempt to use them for C45 PHY's as well, which will probably not yield > the intended result. I agree. The MMD in the register name is simply "MDIO Manageable Devices"... i.e. the phys. I think the commands should be "iread" and "iwrite" to denote the indirect access in use. Thanks, -Joe > _______________________________________________ > U-Boot mailing list > U-Boot@lists.denx.de > https://lists.denx.de/listinfo/u-boot
On 2/5/19 1:28 AM, Joe Hershberger wrote: > On Fri, Jan 25, 2019 at 7:12 AM Vladimir Oltean <vladimir.oltean@nxp.com> wrote: >> >> On 25.01.2019 12:12, Carlo Caione wrote: >>> On 24/01/2019 20:48, Vladimir Oltean wrote: >>>> On 1/24/19 10:19 PM, Carlo Caione wrote: >>>>> On 24/01/2019 20:12, Vladimir Oltean wrote: >>>>>> >>>> >>>> I can't completely answer that, TBH I don't even know who is supposed to >>>> make that distinction. >>> >>> In the kernel that distinction is made by the driver itself, hence my >>> question. See [0]. >>> >>>> For Freescale parts that is a call for the MDIO bus driver to make, for >>>> good or bad (see drivers/net/fm/memac_phy.c where dev_addr is compared >>>> to MDIO_DEVAD_NONE). >>> >>>> And in your patch, phy_write_mmd is only a wrapper over bus->write in >>>> the end, with some more logic to handle C22 indirection. >>>> So my question of unifying "mdio rmmd" with "mdio read" translates into: >>> >>>> Does it make sense to also handle the check with MDIO_DEVAD_NONE in >>>> phy_write_mmd, instead of jumping straight ahead to perform indirection? >>> >>> Honestly I'm not quite sure of all the possible implications here IMO >>> the safest bet here is just to follow what's done by the kernel. Maybe >>> Joe can step in about this. >>> >>> In general we have 3 possible cases: >>> >>> 1) your driver is doing something non-standard when accessing the MMDs >>> and we deal with that using the PHY driver hooks >>> 2) your PHY is C22 and you have to use the indirect method >>> 3) your PHY is C45 and you can use the direct register reading (mangling >>> a bit the address apparently) >>> >>> The kernel is dealing with all the cases, U-Boot is only dealing with >>> C22 PHYs (cases 1 and 2) because AFAICT there isn't yet a generic way to >>> detect if the PHY is C22 or C45. >>> >>> I'm not sure if the indirect method works also for C45 PHYs. >>> >>>> The goal would then be to just call phy_write_mmd from cmd/mdio.c >>>> regardless of the target PHY's clause. >>> >>> Again I wrote that patch only assuming that we were going to deal with >>> C22 PHYs. At this point I wonder if the C22 indirect method works also >>> for C45 PHYs. If that's the case than the phy_write_mmd should already >>> work regardless of the target PHY clause. >>> >>> Cheers. >>> >>> [0] >>> https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Felixir.bootlin.com%2Flinux%2Flatest%2Fsource%2Fdrivers%2Fnet%2Fphy%2Fphy-core.c%23L296&data=02%7C01%7Cvladimir.oltean%40nxp.com%7C826fd741578446f6f36908d68af87b27%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C636849197162094704&sdata=r9AlGZbzGtLC2z7u2HgKKZt17Cl1OcHncjeY00xlVWE%3D&reserved=0 >>> >> >> I'm not suggesting to use C22 indirection if the PHY already supports >> native C45 addressing. Even if that worked, it would be a pointless >> exercise in all but a few cases (like the MDIO controller does not >> support C22, but the PHY does support both C22 and C45). >> I was just wondering out loud whether the introduction of the "mdio >> rmmd" command is justified or not. I now understand that using e.g. >> "mdio read 1.3" will confuse the command for clause 45 PHY's because it >> won't know whether it should access the PHY via native C45 or via >> indirect C22 (obviously it shouldn't do the latter). So in lack of a >> clear distinction mechanism, I now think that a new command truly is >> necessary for performing indirect C45 access on C22. >> What I am still not convinced of, however, is whether those commands >> should be called "rmmd" and "wmmd". It is not immediately obvious from >> the command description that this is what they are for, and a user may >> attempt to use them for C45 PHY's as well, which will probably not yield >> the intended result. > > I agree. The MMD in the register name is simply "MDIO Manageable > Devices"... i.e. the phys. > > I think the commands should be "iread" and "iwrite" to denote the > indirect access in use. > Which brings me to my next point. If we can't properly make the distinction between an indirect C22 MMD access and a proper C45 MMD access, and hence not keeping proper API compatibility with Linux kernel, aren't we better off going back to square 1 and using phy_read_mmd_indirect and phy_write_mmd_indirect? -Vladimir
On Mon, Feb 4, 2019 at 5:39 PM Vladimir Oltean <vladimir.oltean@nxp.com> wrote: > > On 2/5/19 1:28 AM, Joe Hershberger wrote: > > On Fri, Jan 25, 2019 at 7:12 AM Vladimir Oltean <vladimir.oltean@nxp.com> wrote: > >> > >> On 25.01.2019 12:12, Carlo Caione wrote: > >>> On 24/01/2019 20:48, Vladimir Oltean wrote: > >>>> On 1/24/19 10:19 PM, Carlo Caione wrote: > >>>>> On 24/01/2019 20:12, Vladimir Oltean wrote: > >>>>>> > >>>> > >>>> I can't completely answer that, TBH I don't even know who is supposed to > >>>> make that distinction. > >>> > >>> In the kernel that distinction is made by the driver itself, hence my > >>> question. See [0]. > >>> > >>>> For Freescale parts that is a call for the MDIO bus driver to make, for > >>>> good or bad (see drivers/net/fm/memac_phy.c where dev_addr is compared > >>>> to MDIO_DEVAD_NONE). > >>> > >>>> And in your patch, phy_write_mmd is only a wrapper over bus->write in > >>>> the end, with some more logic to handle C22 indirection. > >>>> So my question of unifying "mdio rmmd" with "mdio read" translates into: > >>> > >>>> Does it make sense to also handle the check with MDIO_DEVAD_NONE in > >>>> phy_write_mmd, instead of jumping straight ahead to perform indirection? > >>> > >>> Honestly I'm not quite sure of all the possible implications here IMO > >>> the safest bet here is just to follow what's done by the kernel. Maybe > >>> Joe can step in about this. > >>> > >>> In general we have 3 possible cases: > >>> > >>> 1) your driver is doing something non-standard when accessing the MMDs > >>> and we deal with that using the PHY driver hooks > >>> 2) your PHY is C22 and you have to use the indirect method > >>> 3) your PHY is C45 and you can use the direct register reading (mangling > >>> a bit the address apparently) > >>> > >>> The kernel is dealing with all the cases, U-Boot is only dealing with > >>> C22 PHYs (cases 1 and 2) because AFAICT there isn't yet a generic way to > >>> detect if the PHY is C22 or C45. > >>> > >>> I'm not sure if the indirect method works also for C45 PHYs. > >>> > >>>> The goal would then be to just call phy_write_mmd from cmd/mdio.c > >>>> regardless of the target PHY's clause. > >>> > >>> Again I wrote that patch only assuming that we were going to deal with > >>> C22 PHYs. At this point I wonder if the C22 indirect method works also > >>> for C45 PHYs. If that's the case than the phy_write_mmd should already > >>> work regardless of the target PHY clause. > >>> > >>> Cheers. > >>> > >>> [0] > >>> https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Felixir.bootlin.com%2Flinux%2Flatest%2Fsource%2Fdrivers%2Fnet%2Fphy%2Fphy-core.c%23L296&data=02%7C01%7Cvladimir.oltean%40nxp.com%7C826fd741578446f6f36908d68af87b27%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C636849197162094704&sdata=r9AlGZbzGtLC2z7u2HgKKZt17Cl1OcHncjeY00xlVWE%3D&reserved=0 > >>> > >> > >> I'm not suggesting to use C22 indirection if the PHY already supports > >> native C45 addressing. Even if that worked, it would be a pointless > >> exercise in all but a few cases (like the MDIO controller does not > >> support C22, but the PHY does support both C22 and C45). > >> I was just wondering out loud whether the introduction of the "mdio > >> rmmd" command is justified or not. I now understand that using e.g. > >> "mdio read 1.3" will confuse the command for clause 45 PHY's because it > >> won't know whether it should access the PHY via native C45 or via > >> indirect C22 (obviously it shouldn't do the latter). So in lack of a > >> clear distinction mechanism, I now think that a new command truly is > >> necessary for performing indirect C45 access on C22. > >> What I am still not convinced of, however, is whether those commands > >> should be called "rmmd" and "wmmd". It is not immediately obvious from > >> the command description that this is what they are for, and a user may > >> attempt to use them for C45 PHY's as well, which will probably not yield > >> the intended result. > > > > I agree. The MMD in the register name is simply "MDIO Manageable > > Devices"... i.e. the phys. > > > > I think the commands should be "iread" and "iwrite" to denote the > > indirect access in use. > > > > Which brings me to my next point. > If we can't properly make the distinction between an indirect C22 MMD > access and a proper C45 MMD access, and hence not keeping proper API > compatibility with Linux kernel, aren't we better off going back to > square 1 and using phy_read_mmd_indirect and phy_write_mmd_indirect? I think we can and should make the new wrapper functions remain named phy_*_mmd_indirect and the names of the override functions in the phy driver ops should be *_mmd_indirect. The override is still for an indirect access of c45 registers, just an apparently non-standard one. It is this way in Linux as well. -Joe > -Vladimir > _______________________________________________ > U-Boot mailing list > U-Boot@lists.denx.de > https://lists.denx.de/listinfo/u-boot
On 05/02/2019 00:15, Joe Hershberger wrote: > On Mon, Feb 4, 2019 at 5:39 PM Vladimir Oltean <vladimir.oltean@nxp.com> wrote: /cut >> Which brings me to my next point. >> If we can't properly make the distinction between an indirect C22 MMD >> access and a proper C45 MMD access, and hence not keeping proper API >> compatibility with Linux kernel, aren't we better off going back to >> square 1 and using phy_read_mmd_indirect and phy_write_mmd_indirect? > > I think we can and should make the new wrapper functions remain named > phy_*_mmd_indirect and the names of the override functions in the phy > driver ops should be *_mmd_indirect. The override is still for an > indirect access of c45 registers, just an apparently non-standard one. > It is this way in Linux as well. Alright then. I'll prepare a V5. A couple on notes: 1. I'd prefer the parameters of the "mdio" command to be name "rimmd" and "wimmd" for "r/w indirect MMD" to keep the (twisted) logic of the mdio command code of differentiating the parameters according to argv[1][1] and r/w according to argv[1][0] 2. Since [0] needs a respin as well after the requested changes, I'm going to embedded that patch into this patchset. Cheers [0] https://lists.denx.de/pipermail/u-boot/2019-January/356019.html -- Carlo Caione
On Tue, Feb 5, 2019 at 9:20 AM Carlo Caione <ccaione@baylibre.com> wrote: > > On 05/02/2019 00:15, Joe Hershberger wrote: > > On Mon, Feb 4, 2019 at 5:39 PM Vladimir Oltean <vladimir.oltean@nxp.com> wrote: > > /cut > >> Which brings me to my next point. > >> If we can't properly make the distinction between an indirect C22 MMD > >> access and a proper C45 MMD access, and hence not keeping proper API > >> compatibility with Linux kernel, aren't we better off going back to > >> square 1 and using phy_read_mmd_indirect and phy_write_mmd_indirect? > > > > I think we can and should make the new wrapper functions remain named > > phy_*_mmd_indirect and the names of the override functions in the phy > > driver ops should be *_mmd_indirect. The override is still for an > > indirect access of c45 registers, just an apparently non-standard one. > > It is this way in Linux as well. > > Alright then. I'll prepare a V5. > > A couple on notes: > > 1. I'd prefer the parameters of the "mdio" command to be name "rimmd" > and "wimmd" for "r/w indirect MMD" to keep the (twisted) logic of the > mdio command code of differentiating the parameters according to > argv[1][1] and r/w according to argv[1][0] Is there a reason you want to keep the mmd in there? It seems implied by doing any access using the mdio command. Maybe wi and ri or windirect and rindirect or wind and rind? > 2. Since [0] needs a respin as well after the requested changes, I'm > going to embedded that patch into this patchset. Sounds good. > > Cheers > > [0] https://lists.denx.de/pipermail/u-boot/2019-January/356019.html > > -- > Carlo Caione > _______________________________________________ > U-Boot mailing list > U-Boot@lists.denx.de > https://lists.denx.de/listinfo/u-boot
On 2/6/19 12:10 AM, Joe Hershberger wrote: > On Tue, Feb 5, 2019 at 9:20 AM Carlo Caione <ccaione@baylibre.com> wrote: >> >> On 05/02/2019 00:15, Joe Hershberger wrote: >>> On Mon, Feb 4, 2019 at 5:39 PM Vladimir Oltean <vladimir.oltean@nxp.com> wrote: >> >> /cut >>>> Which brings me to my next point. >>>> If we can't properly make the distinction between an indirect C22 MMD >>>> access and a proper C45 MMD access, and hence not keeping proper API >>>> compatibility with Linux kernel, aren't we better off going back to >>>> square 1 and using phy_read_mmd_indirect and phy_write_mmd_indirect? >>> >>> I think we can and should make the new wrapper functions remain named >>> phy_*_mmd_indirect and the names of the override functions in the phy >>> driver ops should be *_mmd_indirect. The override is still for an >>> indirect access of c45 registers, just an apparently non-standard one. >>> It is this way in Linux as well. I guess it is just me who is still unclear on this? Since Russell King's patch "3b85d8d net: phy: remove the indirect MMD read/write methods", the Linux API is no longer like that (the phy_driver pointers phy_read_mmd and phy_read_mmd_indirect were merged into one). Just want to make sure that everybody is on the same page and we agreed on API compatibility with pre-3b85d8d Linux. >> >> Alright then. I'll prepare a V5. >> >> A couple on notes: >> >> 1. I'd prefer the parameters of the "mdio" command to be name "rimmd" >> and "wimmd" for "r/w indirect MMD" to keep the (twisted) logic of the >> mdio command code of differentiating the parameters according to >> argv[1][1] and r/w according to argv[1][0] > > Is there a reason you want to keep the mmd in there? It seems implied > by doing any access using the mdio command. > > Maybe wi and ri or windirect and rindirect or wind and rind? > What about exposing the indirect read as "mii read <addr> [<indirect_devad>.]<reg>"? It should be clear to most people (and if it isn't, it should be clarified) that the legacy "mii" command is clause 22 only, therefore the "<mmd>.<reg>" syntactic sugar must logically mean that indirect access is what's going on when applied to "mii". The implementation can freely call phy_read_mmd_indirect if it parses such syntax. Just my 2c. Either way, exposing an explicit command for indirect access means that U-boot commits long-term to not trying to implicitly know about, and populate, phydev->is_c45. -Vladimir
On Tue, Feb 5, 2019 at 7:37 PM Vladimir Oltean <vladimir.oltean@nxp.com> wrote: > > On 2/6/19 12:10 AM, Joe Hershberger wrote: > > On Tue, Feb 5, 2019 at 9:20 AM Carlo Caione <ccaione@baylibre.com> wrote: > >> > >> On 05/02/2019 00:15, Joe Hershberger wrote: > >>> On Mon, Feb 4, 2019 at 5:39 PM Vladimir Oltean <vladimir.oltean@nxp.com> wrote: > >> > >> /cut > >>>> Which brings me to my next point. > >>>> If we can't properly make the distinction between an indirect C22 MMD > >>>> access and a proper C45 MMD access, and hence not keeping proper API > >>>> compatibility with Linux kernel, aren't we better off going back to > >>>> square 1 and using phy_read_mmd_indirect and phy_write_mmd_indirect? > >>> > >>> I think we can and should make the new wrapper functions remain named > >>> phy_*_mmd_indirect and the names of the override functions in the phy > >>> driver ops should be *_mmd_indirect. The override is still for an > >>> indirect access of c45 registers, just an apparently non-standard one. > >>> It is this way in Linux as well. > > I guess it is just me who is still unclear on this? > Since Russell King's patch "3b85d8d net: phy: remove the indirect MMD > read/write methods", the Linux API is no longer like that (the > phy_driver pointers phy_read_mmd and phy_read_mmd_indirect were merged > into one). > Just want to make sure that everybody is on the same page and we agreed > on API compatibility with pre-3b85d8d Linux. Argh. I was looking at the patch that Carlo referenced and did not look to see that it further changed. But looking at 3b85d8d I don't see how the concerns that you and Carlo discussed about determining what to do if c45 is also supported. Do you know how Linux handles this or should I do some research? > >> > >> Alright then. I'll prepare a V5. > >> > >> A couple on notes: > >> > >> 1. I'd prefer the parameters of the "mdio" command to be name "rimmd" > >> and "wimmd" for "r/w indirect MMD" to keep the (twisted) logic of the > >> mdio command code of differentiating the parameters according to > >> argv[1][1] and r/w according to argv[1][0] > > > > Is there a reason you want to keep the mmd in there? It seems implied > > by doing any access using the mdio command. > > > > Maybe wi and ri or windirect and rindirect or wind and rind? > > > > What about exposing the indirect read as > "mii read <addr> [<indirect_devad>.]<reg>"? > > It should be clear to most people (and if it isn't, it should be > clarified) that the legacy "mii" command is clause 22 only, therefore > the "<mmd>.<reg>" syntactic sugar must logically mean that indirect > access is what's going on when applied to "mii". The implementation can > freely call phy_read_mmd_indirect if it parses such syntax. While it is clear, I would prefer to not encourage further use of the mii command. I would rather add the ability to explicitly specify the clause in the mdio command. Perhaps the default can be to attempt to auto select, but if it is ambiguous, require the explicit specification. It could follow a similar approach to the "md" command. We can add the ability to add ".22" and ".45" to the mdio command to explicitly select. > Just my 2c. Either way, exposing an explicit command for indirect access > means that U-boot commits long-term to not trying to implicitly know > about, and populate, phydev->is_c45. While using either mdio rindirect or mii / mdio.22 read they are effectively explicit commands to select "indirect", so I'm not sure what point you are making here. -Joe > > -Vladimir > _______________________________________________ > U-Boot mailing list > U-Boot@lists.denx.de > https://lists.denx.de/listinfo/u-boot
On 06/02/2019 03:31, Joe Hershberger wrote: /cut > Perhaps the default can be to attempt to auto select, but if it is > ambiguous, require the explicit specification. It could follow a > similar approach to the "md" command. We can add the ability to add > ".22" and ".45" to the mdio command to explicitly select. What about we go back to have a generic phy_{r|w}_mmd() and (in this order): 1) If the PHY driver is defining a generic {r|w}_mmd() hook we use that. 2) We do direct C45 access if (phy_driver->features & PHY_10G_FEATURES) 3) We do direct C22 access if (devad == MDIO_DEVAD_NONE) 4) We do indirect C22 access to C45 in all the other cases Se we can have one single "mdio" command for all the cases. -- Carlo Caione
On 2/6/19 11:35 AM, Carlo Caione wrote: > On 06/02/2019 03:31, Joe Hershberger wrote: > > /cut >> Perhaps the default can be to attempt to auto select, but if it is >> ambiguous, require the explicit specification. It could follow a >> similar approach to the "md" command. We can add the ability to add >> ".22" and ".45" to the mdio command to explicitly select. > > What about we go back to have a generic phy_{r|w}_mmd() and (in this order): > > 1) If the PHY driver is defining a generic {r|w}_mmd() hook we use that. > 2) We do direct C45 access if (phy_driver->features & PHY_10G_FEATURES) > 3) We do direct C22 access if (devad == MDIO_DEVAD_NONE) > 4) We do indirect C22 access to C45 in all the other cases > > Se we can have one single "mdio" command for all the cases. > This approximation sounds like it could actually work. And especially if you could make sure that even if the approximation is wrong, it is possible to correct it by implementing a driver-level override without duplicating too much code, then I think there's no practical issue. I think I do have a few boards with various C45 PHYs that I can volunteer to test your v5 patchset on, and report back if I see any glaring problems. > -- > Carlo Caione > On 2/6/19 5:31 AM, Joe Hershberger wrote: > On Tue, Feb 5, 2019 at 7:37 PM Vladimir Oltean wrote: >> Just my 2c. Either way, exposing an explicit command for indirect access >> means that U-boot commits long-term to not trying to implicitly know >> about, and populate, phydev->is_c45. > > While using either mdio rindirect or mii / mdio.22 read they are > effectively explicit commands to select "indirect", so I'm not sure > what point you are making here. > > -Joe > I mean that if U-boot were ever able to imply PHY compatibility with clause 45 (aka the API can be made to only expose phy_read_mmd and phy_write_mmd), then there shouldn't be a command exposed to the user for requesting an MMD access that is explicitly direct or indirect. What should the PHY driver do if it knows it's C22 but an explicit C45 MMD access is requested, or the other way around? Carlo's proposal sounds good and also solves the problem of "mdio read" semantics without over-engineering things. -Vladimir
diff --git a/cmd/mdio.c b/cmd/mdio.c index 184868063a..5138db505a 100644 --- a/cmd/mdio.c +++ b/cmd/mdio.c @@ -43,7 +43,7 @@ static int mdio_write_ranges(struct phy_device *phydev, struct mii_dev *bus, int addrlo, int addrhi, int devadlo, int devadhi, int reglo, int reghi, unsigned short data, - int extended) + int extended, int mmd) { int addr, devad, reg; int err = 0; @@ -51,12 +51,15 @@ static int mdio_write_ranges(struct phy_device *phydev, struct mii_dev *bus, for (addr = addrlo; addr <= addrhi; addr++) { for (devad = devadlo; devad <= devadhi; devad++) { for (reg = reglo; reg <= reghi; reg++) { - if (!extended) - err = bus->write(bus, addr, devad, - reg, data); - else + if (mmd) + err = phy_write_mmd(phydev, devad, reg, + data); + else if (extended) err = phydev->drv->writeext(phydev, addr, devad, reg, data); + else + err = bus->write(bus, addr, devad, + reg, data); if (err) goto err_out; @@ -71,7 +74,7 @@ err_out: static int mdio_read_ranges(struct phy_device *phydev, struct mii_dev *bus, int addrlo, int addrhi, int devadlo, int devadhi, - int reglo, int reghi, int extended) + int reglo, int reghi, int extended, int mmd) { int addr, devad, reg; @@ -83,11 +86,13 @@ static int mdio_read_ranges(struct phy_device *phydev, struct mii_dev *bus, for (reg = reglo; reg <= reghi; reg++) { int val; - if (!extended) - val = bus->read(bus, addr, devad, reg); - else + if (mmd) + val = phy_read_mmd(phydev, devad, reg); + else if (extended) val = phydev->drv->readext(phydev, addr, devad, reg); + else + val = bus->read(bus, addr, devad, reg); if (val < 0) { printf("Error\n"); @@ -189,6 +194,7 @@ static int do_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) struct mii_dev *bus; struct phy_device *phydev = NULL; int extended = 0; + int mmd = 0; if (argc < 2) return CMD_RET_USAGE; @@ -222,14 +228,26 @@ static int do_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) bus = phydev->bus; extended = 1; } else { - return -1; + return CMD_RET_FAILURE; } if (!phydev->drv || (!phydev->drv->writeext && (op[0] == 'w')) || (!phydev->drv->readext && (op[0] == 'r'))) { puts("PHY does not have extended functions\n"); - return -1; + return CMD_RET_FAILURE; + } + } + if (op[1] == 'm') { + phydev = mdio_phydev_for_ethname(argv[2]); + + if (phydev) { + addrlo = phydev->addr; + addrhi = addrlo; + bus = phydev->bus; + mmd = 1; + } else { + return CMD_RET_FAILURE; } } } @@ -242,13 +260,13 @@ static int do_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (pos > 1) if (extract_reg_range(argv[pos--], &devadlo, &devadhi, ®lo, ®hi)) - return -1; + return CMD_RET_FAILURE; default: if (pos > 1) if (extract_phy_range(&argv[2], pos - 1, &bus, &phydev, &addrlo, &addrhi)) - return -1; + return CMD_RET_FAILURE; break; } @@ -265,12 +283,12 @@ static int do_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) switch (op[0]) { case 'w': mdio_write_ranges(phydev, bus, addrlo, addrhi, devadlo, devadhi, - reglo, reghi, data, extended); + reglo, reghi, data, extended, mmd); break; case 'r': mdio_read_ranges(phydev, bus, addrlo, addrhi, devadlo, devadhi, - reglo, reghi, extended); + reglo, reghi, extended, mmd); break; } @@ -303,6 +321,10 @@ U_BOOT_CMD( "read PHY's extended register at <devad>.<reg>\n" "mdio wx <phydev> [<devad>.]<reg> <data> - " "write PHY's extended register at <devad>.<reg>\n" + "mdio rmmd <phydev> [<devad>.]<reg> - " + "read PHY's extended register at <devad>.<reg>\n" + "mdio wmmd <phydev> [<devad>.]<reg> <data> - " + "write PHY's extended register at <devad>.<reg>\n" "<phydev> may be:\n" " <busname> <addr>\n" " <addr>\n"