初始化信息
phy正常连接
log信息
[ 1.279600] rk_gmac-dwmac fe300000.ethernet: clock input or output? (input).
[ 1.280239] rk_gmac-dwmac fe300000.ethernet: TX delay(0x28).
[ 1.280746] rk_gmac-dwmac fe300000.ethernet: RX delay(0x11).
[ 1.281275] rk_gmac-dwmac fe300000.ethernet: integrated PHY? (no).
[ 1.281991] rk_gmac-dwmac fe300000.ethernet: cannot get clock clk_mac_speed
[ 1.282620] rk_gmac-dwmac fe300000.ethernet: clock input from PHY
[ 1.288166] rk_gmac-dwmac fe300000.ethernet: init for RGMII
[ 1.288783] stmmac - user ID: 0x10, Synopsys ID: 0x35
[ 1.289240] Ring mode enabled
[ 1.289512] DMA HW capability register supported
[ 1.289911] Normal descriptors
[ 1.290220] RX Checksum Offload Engine supported (type 2)
[ 1.290717] TX Checksum insertion supported
[ 1.291093] Wake-Up On Lan supported
[ 1.291463] Enable RX Mitigation via HW Watchdog Timer
[ 1.356532] libphy: stmmac: probed
[ 1.356845] eth%d: PHY ID 001cc915 at 0 IRQ POLL (stmmac-0:00) active
[ 1.357428] eth%d: PHY ID 001cc915 at 1 IRQ POLL (stmmac-0:01)
sysfs接口信息
[root@rk3399:/]# cat /sys/devices/platform/fe300000.ethernet/mdio_bus/stmmac-0/
device/ stmmac-0:00/ subsystem/
power/ stmmac-0:01/ uevent
[root@rk3399:/]# cat /sys/devices/platform/fe300000.ethernet/mdio_bus/stmmac-0/s
tmmac-0:00/phy_id
0x001cc915
[root@rk3399:/]# cat /sys/devices/platform/fe300000.ethernet/mdio_bus/stmmac-0/s
tmmac-0:00/phy_registers
0: 0x1140
1: 0x796d
2: 0x1c
3: 0xc915
4: 0x1e1
5: 0xc1e1
6: 0xd
7: 0x2001
8: 0x6001
9: 0x300
10: 0x3800
11: 0x0
12: 0x0
13: 0x0
14: 0x0
15: 0x3000
16: 0x16e
17: 0xad42
18: 0x9f01
19: 0x6c52
20: 0x8040
21: 0x1006
22: 0x4100
23: 0x2100
24: 0x0
25: 0x8c00
26: 0x40
27: 0x106
28: 0x217c
29: 0x8038
30: 0x123
31: 0x0
去掉phy芯片
log信息
[ 1.286877] rk_gmac-dwmac fe300000.ethernet: clock input or output? (input).
[ 1.287517] rk_gmac-dwmac fe300000.ethernet: TX delay(0x28).
[ 1.288023] rk_gmac-dwmac fe300000.ethernet: RX delay(0x11).
[ 1.288552] rk_gmac-dwmac fe300000.ethernet: integrated PHY? (no).
[ 1.289270] rk_gmac-dwmac fe300000.ethernet: cannot get clock clk_mac_speed
[ 1.289899] rk_gmac-dwmac fe300000.ethernet: clock input from PHY
[ 1.295453] rk_gmac-dwmac fe300000.ethernet: init for RGMII
[ 1.296059] stmmac - user ID: 0x10, Synopsys ID: 0x35
[ 1.296515] Ring mode enabled
[ 1.296788] DMA HW capability register supported
[ 1.297186] Normal descriptors
[ 1.297503] RX Checksum Offload Engine supported (type 2)
[ 1.297992] TX Checksum insertion supported
[ 1.298376] Wake-Up On Lan supported
[ 1.298736] Enable RX Mitigation via HW Watchdog Timer
[ 1.364025] libphy: stmmac: probed
[ 1.364343] eth%d: No PHY found
驱动识别过程
驱动文件
kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
kernel/drivers/net/phy/phy_device.c
kernel/drivers/net/phy/mdio_bus.c
kernel/include/linux/phy.h
kernel/drivers/net/ethernet/stmicro/stmmac/stmmac.h
kernel/include/linux/netdevice.h
#define PHY_MAX_ADDR 32
#define SET_NETDEV_DEV(net, pdev) ((net)->dev.parent = (pdev))
#define mdiobus_register(bus) __mdiobus_register(bus, THIS_MODULE)
stmmac_mdio_register(struct net_device *ndev) //注册mdio总线,配置总线参数,配置phydev中断属性
mdiobus_register(new_bus); //注册mii_bus,在总线上扫描PHY_ADDR 0到31是否有对应的phydev
mdiobus_scan(bus, i); //按照传递的addr数值,获取总线上是否有p对应的phydev,如果有使用phy_device_register函数进行注册
get_phy_device(bus, addr, false);
get_phy_id(bus, addr, &phy_id, is_c45, &c45_ids); //按照传递的addr数值读取对应addr上phy设备的id,如果有对应的设备会返回phy设备的id,否则返回0xffffffff
phy_device_create(bus, addr, phy_id, is_c45, &c45_ids);
phy_device_register(phydev);
/**
* stmmac_mdio_register
* @ndev: net device structure
* Description: it registers the MII bus
*/
int stmmac_mdio_register(struct net_device *ndev)
{
int err = 0;
struct mii_bus *new_bus;
int *irqlist;
struct stmmac_priv *priv = netdev_priv(ndev);
struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data;
int addr, found;
if (!mdio_bus_data)
return 0;
new_bus = mdiobus_alloc();
if (new_bus == NULL)
return -ENOMEM;
if (mdio_bus_data->irqs) {
irqlist = mdio_bus_data->irqs;
} else {
for (addr = 0; addr < PHY_MAX_ADDR; addr++)
priv->mii_irq[addr] = PHY_POLL;
irqlist = priv->mii_irq;
}
#ifdef CONFIG_OF
if (priv->device->of_node)
mdio_bus_data->reset_gpio = -1;
#endif
new_bus->name = "stmmac";
new_bus->read = &stmmac_mdio_read;
new_bus->write = &stmmac_mdio_write;
new_bus->reset = &stmmac_mdio_reset;
snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%x",
new_bus->name, priv->plat->bus_id);
new_bus->priv = ndev;
new_bus->irq = irqlist;
new_bus->phy_mask = mdio_bus_data->phy_mask;
new_bus->parent = priv->device;
err = mdiobus_register(new_bus);
if (err != 0) {
pr_err("%s: Cannot register as MDIO bus\n", new_bus->name);
goto bus_register_fail;
}
found = 0;
for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
struct phy_device *phydev = new_bus->phy_map[addr];
if (phydev) {
int act = 0;
char irq_num[4];
char *irq_str;
/*
* If an IRQ was provided to be assigned after
* the bus probe, do it here.
*/
if ((mdio_bus_data->irqs == NULL) &&
(mdio_bus_data->probed_phy_irq > 0)) {
irqlist[addr] = mdio_bus_data->probed_phy_irq;
phydev->irq = mdio_bus_data->probed_phy_irq;
}
/*
* If we're going to bind the MAC to this PHY bus,
* and no PHY number was provided to the MAC,
* use the one probed here.
*/
if (priv->plat->phy_addr == -1)
priv->plat->phy_addr = addr;
act = (priv->plat->phy_addr == addr);
switch (phydev->irq) {
case PHY_POLL:
irq_str = "POLL";
break;
case PHY_IGNORE_INTERRUPT:
irq_str = "IGNORE";
break;
default:
sprintf(irq_num, "%d", phydev->irq);
irq_str = irq_num;
break;
}
pr_info("%s: PHY ID %08x at %d IRQ %s (%s)%s\n",
ndev->name, phydev->phy_id, addr,
irq_str, dev_name(&phydev->dev),
act ? " active" : "");
found = 1;
}
}
if (!found) {
pr_warn("%s: No PHY found\n", ndev->name);
mdiobus_unregister(new_bus);
mdiobus_free(new_bus);
return -ENODEV;
}
priv->mii = new_bus;
return 0;
bus_register_fail:
mdiobus_free(new_bus);
return err;
}
/**
* __mdiobus_register - bring up all the PHYs on a given bus and attach them to bus
* @bus: target mii_bus
* @owner: module containing bus accessor functions
*
* Description: Called by a bus driver to bring up all the PHYs
* on a given bus, and attach them to the bus. Drivers should use
* mdiobus_register() rather than __mdiobus_register() unless they
* need to pass a specific owner module.
*
* Returns 0 on success or < 0 on error.
*/
int __mdiobus_register(struct mii_bus *bus, struct module *owner)
struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)
/**
* get_phy_device - reads the specified PHY device and returns its @phy_device
* struct
* @bus: the target MII bus
* @addr: PHY address on the MII bus
* @is_c45: If true the PHY uses the 802.3 clause 45 protocol
*
* Description: Reads the ID registers of the PHY at @addr on the
* @bus, then allocates and returns the phy_device to represent it.
*/
struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45)
/**
* phy_device_register - Register the phy device on the MDIO bus
* @phydev: phy_device structure to be added to the MDIO bus
*/
int phy_device_register(struct phy_device *phydev)
struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id,
bool is_c45,
struct phy_c45_device_ids *c45_ids)