前言
关于,在LS1043A处理器下,使用NXP提供的LSDK的内核启动系统,当打算在应用层通过编程读写PHY的寄存器的时候,使用 ioctl 命令会失败返回 -EINVAL即 -22,有很大可能是本文提到的情况。
- 内核版本 linux5_10
详情
- 首先,关于LS1043A的驱动代码,无论配置是dpaa还是sdk_dpaa, dpaa 使用的是
drivers\net\ethernet\freescale\dpaa\dpaa_eth.c
sdk_dpaa 使用的是
drivers\net\ethernet\freescale\sdk_dpaa\dpaa_eth.c
,两者均是同一种情况;
- 以 dpaa 为例,ioctl 会调用驱动中的 net_device_ops 结构体中的 dpaa_ioctl
static const struct net_device_ops dpaa_ops = {
.ndo_open = dpaa_open,
.ndo_start_xmit = dpaa_start_xmit,
.ndo_stop = dpaa_eth_stop,
.ndo_tx_timeout = dpaa_tx_timeout,
.ndo_get_stats64 = dpaa_get_stats64,
.ndo_change_carrier = fixed_phy_change_carrier,
.ndo_set_mac_address = dpaa_set_mac_address,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_rx_mode = dpaa_set_rx_mode,
.ndo_do_ioctl = dpaa_ioctl,
.ndo_setup_tc = dpaa_setup_tc,
};
- 查看 dpaa_ioctl 函数:
static int dpaa_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd)
{
int ret = -EINVAL;
if (cmd == SIOCGMIIREG) {
if (net_dev->phydev)
return phy_mii_ioctl(net_dev->phydev, rq, cmd);
}
if (cmd == SIOCSHWTSTAMP)
return dpaa_ts_ioctl(net_dev, rq, cmd);
return ret;
}
由此函数知,只有在 cmd == SIOCGMIIREG 或者 SIOCSHWTSTAMP 的时候才会处理,其他命令均返回错误,这就是原因。解决办法就是,一在驱动中配置PHY寄存器,二修改此处的内核驱动文件即可。
static int dpaa_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd)
{
int ret = -EINVAL;
//if (cmd == SIOCGMIIREG)
{
if (net_dev->phydev)
return phy_mii_ioctl(net_dev->phydev, rq, cmd);
}
if (cmd == SIOCSHWTSTAMP)
return dpaa_ts_ioctl(net_dev, rq, cmd);
return ret;
}