接前一篇文章:Linux网络驱动之Fixed-Link(7)
本文内容参考:
GMAC网卡Fixed-Link模式 - StepForwards - 博客园
RTL8367RB的国产P2P替代方案用JL6107-PC的可行性及实现方法-CSDN博客
linux phy处理流程一:探测phy设备_phy link过程-CSDN博客
Linux 网络驱动-MAC、PHY层驱动框架(三)_ethernet-phy-ieee802.3-c22-CSDN博客
特此致谢!
三、深入了解
4. Linux内核中Fixed-Link的相关内容
(2)PHY驱动(driver)匹配
上一回继续讲解of_phy_get_and_connect函数,讲到了of_phy_connect函数,本回开始解析该函数。为了便于理解和回顾,再次贴出of_phy_get_and_connect函数代码,在drivers/net/mdio/of_mdio.c中,如下:
cpp
/**
* of_phy_get_and_connect
* - Get phy node and connect to the phy described in the device tree
* @dev: pointer to net_device claiming the phy
* @np: Pointer to device tree node for the net_device claiming the phy
* @hndlr: Link state callback for the network device
*
* If successful, returns a pointer to the phy_device with the embedded
* struct device refcount incremented by one, or NULL on failure. The
* refcount must be dropped by calling phy_disconnect() or phy_detach().
*/
struct phy_device *of_phy_get_and_connect(struct net_device *dev,
struct device_node *np,
void (*hndlr)(struct net_device *))
{
phy_interface_t iface;
struct device_node *phy_np;
struct phy_device *phy;
int ret;
ret = of_get_phy_mode(np, &iface);
if (ret)
return NULL;
if (of_phy_is_fixed_link(np)) {
ret = of_phy_register_fixed_link(np);
if (ret < 0) {
netdev_err(dev, "broken fixed-link specification\n");
return NULL;
}
phy_np = of_node_get(np);
} else {
phy_np = of_parse_phandle(np, "phy-handle", 0);
if (!phy_np)
return NULL;
}
phy = of_phy_connect(dev, phy_np, hndlr, 0, iface);
of_node_put(phy_np);
return phy;
}
EXPORT_SYMBOL(of_phy_get_and_connect);
前文书讲过,通过of_phy_register_fixed_link函数(最终是通过fixed_phy_register函数)完成了PHY设备(struct phy_device)设备的注册。接下来就要调用of_phy_connect函数来匹配PHY驱动(struct phy_driver)。当前正是讲到这个of_phy_connect函数。
of_phy_connect函数。其也在drivers/net/mdio/of_mdio.c中,代码如下:
cpp
/**
* of_phy_connect - Connect to the phy described in the device tree
* @dev: pointer to net_device claiming the phy
* @phy_np: Pointer to device tree node for the PHY
* @hndlr: Link state callback for the network device
* @flags: flags to pass to the PHY
* @iface: PHY data interface type
*
* If successful, returns a pointer to the phy_device with the embedded
* struct device refcount incremented by one, or NULL on failure. The
* refcount must be dropped by calling phy_disconnect() or phy_detach().
*/
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);
int ret;
if (!phy)
return NULL;
phy->dev_flags |= flags;
ret = phy_connect_direct(dev, phy, hndlr, iface);
/* refcount is held by phy_connect_direct() on success */
put_device(&phy->mdio.dev);
return ret ? NULL : phy;
}
EXPORT_SYMBOL(of_phy_connect);
先来看一下of_phy_connect函数的注释。
of_phy_connect函数的作用是,获取phy节点并连接到设备树中描述的phy。
参数说明:
- dev:指向声称拥有phy的net_device的指针
- phy_np:指向PHY设备树节点的指针
- hndlr:网络设备的链路状态回调
- flags:传递给PHY的标志
- iface:PHY数据接口类型
返回值:
如果成功,返回一个指向phy_device的指针,其中嵌入的结构设备refcount递增1;否则返回NULL。
必须通过调用phy_disconnect()或phy_detach()来删除引用计数。
下一回开始解析函数具体内容。