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?
gmail.com
> 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
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...
> How do I control what MII bus address is read/written by the
> SIOCGMIIREG and SIOCSMIIREG?
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
gmail.com 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 = (mii_ioctl_data*)(&ifr.ifr_data);
mii->phy_id = phyId; //set to your phy's ID
mii->reg_num = reg; //the register you want to read
mii->val_in = 0;
mii->val_out = 0;
int fd = socket(AF_INET, SOCK_DGRAM, 0);
int err = 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