走ifconfig ethx
sys_ioctl
do_vfs_ioctl
vfs_ioctl
sock_ioctl
inet_ioctl
devinet_ioctl
dev_change_flags
__dev_charge_flag
__dev_open
gfar_enet_open
进入真正的流程
int gfar_enet_open(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
skb_queue_head_init(&priv->rx_recycle);
/* Initialize a bunch of registers */
init_registers(dev);
gfar_set_mac_address(dev);
err = init_phy(dev);
=>int init_phy(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
interface = gfar_get_interface(dev);
priv->phydev = of_phy_connect(dev, priv->phy_node, &adjust_link, 0,
interface);//net_device的priv的phy_node就是phy
=>struct phy_device *of_phy_connect(struct net_device *dev,
struct device_node *phy_np,
void (*hndlr)(struct net_device *), u32 flags,
phy_interface_t iface)
{
struct phy_device *phy = of_phy_find_device(phy_np);
if (!phy)
return NULL;
return phy_connect_direct(dev, phy, hndlr, flags, iface) ? NULL : phy;
=>int phy_connect_direct(struct net_device *dev, struct phy_device *phydev,
void (*handler)(struct net_device *), u32 flags,
phy_interface_t interface)
{
int rc = phy_attach_direct(dev, phydev, flags, interface);
=>int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
u32 flags, phy_interface_t interface)
{
struct device *d = &phydev->dev;
/* Assume that if there is no driver, that it doesn't
* exist, and we should use the genphy driver. */
if (NULL == d->driver) { //如果找不到phy的驱动, 则挂接通用phy启动
d->driver = &genphy_driver.driver;
int err = d->driver->probe(d);
if (err >= 0)
err = device_bind_driver(d);
}
phydev->attached_dev = dev;
phydev->dev_flags = flags;
phydev->interface = interface;
/* Do initial configuration here, now that
* we have certain key parameters
* (dev_flags and interface) */
return phy_init_hw(phydev);
=>int phy_init_hw(struct phy_device *phydev)
{
return phydev->drv->config_init(phydev);
}
}
phy_prepare_link(phydev, handler);
phy_start_machine(phydev, NULL);
if (phydev->irq > 0)
phy_start_interrupts(phydev);
return 0;
}
}
if (interface == PHY_INTERFACE_MODE_SGMII)
gfar_configure_serdes(dev);
}
err = startup_gfar(dev);
netif_tx_start_all_queues(dev);
device_set_wakeup_enable(&dev->dev, priv->wol_en);
}
mac初始化与phy联系起来
int gfar_of_init(struct of_device *ofdev, struct net_device **pdev)
{
struct net_device *dev = NULL;
struct gfar_private *priv = NULL;
*pdev = alloc_etherdev_mq(sizeof(*priv), num_tx_qs);
dev = *pdev;
priv = netdev_priv(dev);
priv->node = ofdev->node;
priv->ndev = dev;
priv->phy_node = of_parse_phandle(np, "phy-handle", 0);
/* Find the TBI PHY. If it's not there, we don't support SGMII */
priv->tbi_node = of_parse_phandle(np, "tbi-handle", 0);
}
ifconfig ethx之后查看sysfs文件系统
#ls /sys/bus/mdio_bus/devices
# mdio@xxxx24520:10
mdios@xxx24520:11
#ls /sys/bus/mdio_bus/drivers
# Marvell 88E1111
Generic PHY
Generic 10GPHY
#ls /sys/class/mdio_bus -l
# 0->../../devices/platform/Fixed MDIO bus.0/mdio_bus/0
mdio@xxxx24520->../../devices/xxxx00000.soc8572/xxxx24520.mdio/mdio_bus/mdio@xxxx24520