How to access MII management bus from userspace?

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
I'm trying to write a user-space app to access devices on an MII
management bus (MDIO/MDC) associated with an Ethernet controller.

I'm using code copied from mii-tool, but the method used by mii-tool
to override the PHY id doesn't seem to work.

After calling an ioctl() to fill in the mii/phy details in the
interface request structure, mii-tool then overrides the phy_id field
like this:

  static struct ifreq ifr;

  ioctl(skfd, SIOCGMIIPHY, &ifr);  // load ifr with mii/phy details

  struct mii_ioctl_data *mii = (struct mii_ioctl_data*)&ifr.ifr_data;
  
  mii->phy_id = phyid;  // override phy mii bus address
      
But that doesn't actually seem to work.  No matter what value is
written to mii->phy_id, the id that ends up passed to the ethernet
driver's mdio_read/write() functions is always 0.

How do I control what MII bus address is read/written by the
SIOCGMIIREG and SIOCSMIIREG?

--
Grant Edwards               grant.b.edwards        Yow! What GOOD is a
                                  at               CARDBOARD suitcase ANYWAY?
We've slightly trimmed the long signature. Click to see the full one.
Re: How to access MII management bus from userspace?

Quoted text here. Click to load it

I've traced the calls through the kernel, and that field in the
request structure is never even passed to the phy_read() or
phy_write() routines by phy_mii_ioclt().  phy_read() and phy_write()
always use a phy_id that's taken from a different structure.

However that field _is_ checked by phy_mii_ioclt() and there are
certain side effects if the phy id you're attempting to write to
matches the phy id that actually gets written to.  Oddly, the write
happens (not to the id you specified) even if they don't match, but
there are extra side effects if the request matches the id that's
forced during the write.

Doesn't make much sense to me...

Quoted text here. Click to load it

AFAICT you can't, and mii-tool is deluding itself.

--
Grant Edwards               grant.b.edwards        Yow! I'll show you MY
                                  at               telex number if you show me
We've slightly trimmed the long signature. Click to see the full one.
Re: How to access MII management bus from userspace?
Quoted text here. Click to load it
Yow! I'll show you MY
Quoted text here. Click to load it
 A0% A0% A0% A0% A0%YOURS ...

Hi Grant,

Here's the code I used to read MII regs.

ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, "eth0"); //set to whatever your ethernet device
is
mii_ioctl_data* mii 3D% (mii_ioctl_data*)(&ifr.ifr_data);
mii->phy_id 3D% phyId; //set to your phy's ID
mii->reg_num 3D% reg; //the register you want to read
mii->val_in 3D% 0;
mii->val_out 3D% 0;

int fd 3D% socket(AF_INET, SOCK_DGRAM, 0);
int err 3D% ioctl(fd, SIOCGMIIREG, &ifr);

Assuming your working an embedded platform, you may have a custom
ethernet driver.  Make sure you should have
static int mdio_read(struct net_device *dev, int phy_id, int location)
static void mdio_write(struct net_device *dev, int phy_id, int
location, int value)
in your driver. Try putting a printk here to see the phy_id.

If your ioctl calls don't get as far as mdio_read/write, check your
ioctl function in your driver.  It should call generic_mii_ioctl().
Also, check that your (driver's private data)->mii.phy_id_mask isn't
set to 0!

What driver are you using / can you post your driver's ioctl function?

Good luck,
Jeremy

Site Timeline