Re: [RFC PATCH] net: phy/mdio: enable mmd indirect access through phy_mii_ioctl()

From: Grygorii Strashko
Date: Tue Nov 02 2021 - 15:13:14 EST




On 02/11/2021 20:37, Grygorii Strashko wrote:
Hi Russell, Andrew,

Thanks a lot for you comments.

On 02/11/2021 19:41, Russell King (Oracle) wrote:
On Tue, Nov 02, 2021 at 07:19:46PM +0200, Grygorii Strashko wrote:
It would require MDIO bus lock, which is not a solution,
or some sort of batch processing, like for mmd:
  w reg1 val1
  w reg2 val2
  w reg1 val3
  r reg2

What Kernel interface do you have in mind?

That is roughly what I was thinking, but Andrew has basically said no
to it.

Sry, but I have to note that demand for this become terribly high, min two pings in months

Feel free to continue demanding it, but it seems that at least two of
the phylib maintainers are in agreement that providing generic
emulation of C45 accesses in kernel space is just not going to happen.


not ready to give up.

One more idea how about mdiobus_get_phy(), so we can search for PHY and
if present try to use proper API phy_read/phy_write_mmd?



smth like below
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index a3bfb156c83d..8ebe59b5647d 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -285,6 +285,7 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd)
u16 val = mii_data->val_in;
bool change_autoneg = false;
int prtad, devad;
+ struct phy_device *phydev_rq = phydev;
switch (cmd) {
case SIOCGMIIPHY:
@@ -300,8 +301,18 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd)
prtad = mii_data->phy_id;
devad = mii_data->reg_num;
}
- mii_data->val_out = mdiobus_read(phydev->mdio.bus, prtad,
- devad);
+
+ if (prtad != phydev->mdio.addr)
+ phydev_rq = mdiobus_get_phy(phydev->mdio.bus, prtad);
+
+ if (!phydev_rq) {
+ mii_data->val_out = mdiobus_read(phydev->mdio.bus, prtad, devad);
+ } else if (mdio_phy_id_is_c45(mii_data->phy_id) && !phydev->is_c45) {
+ mii_data->val_out = phy_read_mmd(phydev_rq, mdio_phy_id_devad(mii_data->phy_id), mii_data->reg_num);
+ } else {
+ mii_data->val_out = phy_read(phydev_rq, mii_data->reg_num);
+ }
+
return 0;
case SIOCSMIIREG:

--
Best regards,
grygorii