使用ioctl命令时,可以看到上述两个命令的存在,
在头文件 include/linux/sockios.h,定义如下:
#define SIOCETHTOOL 0x8946 /* Ethtool interface */ ethtool 接口
#define SIOCGMIIPHY 0x8947 /* Get address of MII PHY in use. */ 获取MII phy的地址
#define SIOCGMIIREG 0x8948 /* Read MII PHY register. */ 读取 MII phy 寄存器
#define SIOCSMIIREG 0x8949 /* Write MII PHY register. */ 写MII phy 寄存器
内核中对于上述两个命令的处理定义在文件 /drivers/net/phy/phy.c 的函数 phy_mii_ioctl中,
函数原型如下:
/**
* phy_mii_ioctl - generic PHY MII ioctl interface
* @phydev: the phy_device struct
* @ifr: &struct ifreq for socket ioctl's
* @cmd: ioctl cmd to execute
*
* Note that this function is currently incompatible with the
* PHYCONTROL layer. It changes registers without regard to
* current state. Use at own risk.
*/
int phy_mii_ioctl(struct phy_device *phydev,
struct ifreq *ifr, int cmd)
{
struct mii_ioctl_data *mii_data = if_mii(ifr);
u16 val = mii_data->val_in;
switch (cmd) {
case SIOCGMIIPHY: // 获取phy的地址
mii_data->phy_id = phydev->addr;
/* fall through */
case SIOCGMIIREG:
mii_data->val_out = mdiobus_read(phydev->bus, mii_data->phy_id, mii_data->reg_num);
break;
case SIOCSMIIREG:
if (mii_data->phy_id == phydev->addr) {
switch(mii_data->reg_num) {
case MII_BMCR:
if ((val & (BMCR_RESET|BMCR_ANENABLE)) == 0)
phydev->autoneg = AUTONEG_DISABLE;
else
phydev->autoneg = AUTONEG_ENABLE;
if ((!phydev->autoneg) && (val & BMCR_FULLDPLX))
phydev->duplex = DUPLEX_FULL;
else
phydev->duplex = DUPLEX_HALF;
if ((!phydev->autoneg) &&
(val & BMCR_SPEED1000))
phydev->speed = SPEED_1000;
else if ((!phydev->autoneg) &&
(val & BMCR_SPEED100))
phydev->speed = SPEED_100;
break;
case MII_ADVERTISE:
phydev->advertising = val;
break;
default:
/* do nothing */
break;
}
}
mdiobus_write(phydev->bus, mii_data->phy_id,
mii_data->reg_num, val);
if (mii_data->reg_num == MII_BMCR &&
val & BMCR_RESET &&
phydev->drv->config_init) {
phy_scan_fixups(phydev);
phydev->drv->config_init(phydev);
}
break;
case SIOCSHWTSTAMP:
if (phydev->drv->hwtstamp)
return phydev->drv->hwtstamp(phydev, ifr);
/* fall through */
default:
return -EOPNOTSUPP;
}
return 0;
}
EXPORT_SYMBOL(phy_mii_ioctl);
补充:
关于MII,百度内容如下:
MII即“媒体独立接口”,也叫“独立于介质的接口”。它是IEEE-802.3定义的以太网行业标准。它包括一个数据接口,以及一个MAC和PHY之间的管理接口。
RMII全称为“简化的媒体独立接口”,是IEEE-802.3u标准中除MII接口之外的另一种实现。
独立于介质的接口(MII) 用于MAC与外接的PHY互联,支持10Mbit/s和100Mbit/s数据传输模式。