/*
* 当你使用 ifconfig ethx up、down 时, 这个函数就被执行到了. 知道了它的执行时机了吧 😄
* 比如 : PHY_FORCING -> PHY_RUNNING 切换的时候.
*
* phy 的12种状态中的4种在phy状态机中是归纳为同一种处理的.
* state 叠加了 ? 不论你观不观测它, 它都是4态合一, TMD 量子力学也只有两态吧 😄😄
* 这几天著名的双缝干涉实验看的有点多 .... 😂
*/
static void phy_link_change(struct phy_device *phydev, bool up, bool do_carrier)
{
/*
* 核心动作来了.
* 为了 mac 与 phy 的绑定, kernel 准备了很多. 用兵一时. 好了,这里就拿出mac来了.
* 拿出mac仅仅是为了执行netif_carrier_xx的需要. 在核心函数 如 macb_handle_link_change()
* 也仅仅是为了获取到 phy.
*/
struct net_device *netdev = phydev->attached_dev;
/*
* 这是一个布尔值. 要明白这个值的用意,就必须要理解 phy的状态切换.
*/
if (do_carrier) {
if (up)
netif_carrier_on(netdev);
else
netif_carrier_off(netdev);
}
phydev->adjust_link(netdev);
}
static void macb_handle_link_change(struct net_device *dev)
{
struct macb *bp = netdev_priv(dev);
struct phy_device *phydev = dev->phydev;
unsigned long flags;
int status_change = 0;
spin_lock_irqsave(&bp->lock, flags);
if (phydev->link) {
if ((bp->speed != phydev->speed) ||
(bp->duplex != phydev->duplex)) {
u32 reg;
reg = macb_readl(bp, NCFGR);
reg &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
if (macb_is_gem(bp))
reg &= ~GEM_BIT(GBE);
if (phydev->duplex)
reg |= MACB_BIT(FD);
if (phydev->speed == SPEED_100)
reg |= MACB_BIT(SPD);
if (phydev->speed == SPEED_1000 &&
bp->caps & MACB_CAPS_GIGABIT_MODE_AVAILABLE)
reg |= GEM_BIT(GBE);
macb_or_gem_writel(bp, NCFGR, reg);
bp->speed = phydev->speed;
bp->duplex = phydev->duplex;
status_change = 1;
}
}
if (phydev->link != bp->link) {
if (!phydev->link) {
bp->speed = 0;
bp->duplex = -1;
}
bp->link = phydev->link;
status_change = 1;
}
spin_unlock_irqrestore(&bp->lock, flags);
if (status_change) {
if (phydev->link) {
/* Update the TX clock rate if and only if the link is
* up and there has been a link change.
*/
macb_set_tx_clk(bp->tx_clk, phydev->speed, dev);
netif_carrier_on(dev);
netdev_info(dev, "link up (%d/%s)\n",
phydev->speed,
phydev->duplex == DUPLEX_FULL ?
"Full" : "Half");
} else {
netif_carrier_off(dev);
netdev_info(dev, "link down\n");
}
}
}