Linux网络驱动基本概念

MAC、MDIO、MII、PHY

  • MAC(Media Access Control)

    媒体访问控制,使用硬件实现ISO网络5层网络模型数据链路层,对数据进行数据链路层的封包和解包。一般MAC位于处理器芯片内部。

  • PHY(Physical Layer)

    物理层,使用硬件实现ISO网络5层网络模型物理层,一般是单独的芯片

  • MDIO(Management Data Input/Output Interface)

    数据输入输出管理接口,是MAC与PHY之间的控制接口。用于传输控制信息。MDIO是总线式接口,即一个MDIO总线上能挂载多个PHY,多个PHY之间使用addr区分不同的PHY

  • MII(Media Independent Interface)

    介质独立界面,是MAC与PHY之间的数据传输接口,用于传输控制信息。衍生MII接口有GMII、RGMII,RMII。R是简化,G是千兆。RGMII就是简化的千兆MII

Linux设备树

mdio@102903c0 {								//MDIO总线
    compatible = "vendor,gemac-mdio";
    reg = <0x102903c0 0x20>;
    clocks = <0x5 0x65>;
    resets = <0x5 0x37cc 0x0>;
    reset-names = "phy_reset";
    #address-cells = <0x1>;
    #size-cells = <0x0>;

    ethernet-phy@1 {						// PHY芯片  1
        reg = <0x1>;
        phandle = <0xa>;
	};

	ethernet-phy@2 {						// PHY芯片  2
        reg = <0x2>;
        phandle = <0xb>;
	};
};

ethernet@10290000 {							// MAC
    compatible = "vendor,gmac-v5";
    reg = <0x10290000 0x1000 0x1029300c 0x4>;
    interrupts = <0x0 0x65 0x4 0x0 0x66 0x4 0x0 0x67 0x4 0x0 0x68 0x4>;
    clocks = <0x5 0x65 0x5 0x66>;
    clock-names = "gmac_clk", "macif_clk";
    resets = <0x5 0x37c4 0x0 0x5 0x37c0 0x0>;
    reset-names = "port_reset", "macif_reset";
    mac-address = [00 00 00 00 00 00];
    phy-handle = <0xa>;						// 通过phandle将MAC与phy链接
    phy-mode = "rgmii";						// 指定phy的模式为rgmii
};

Linux 驱动结构体

```

## 调用堆栈

```c
/**
 * @brief 检查给定的"compat"字符串是否与device的"compatible"属性中的某个字符串匹配
 * 
 * @param device 设备树节点结构体
 * @param compat 待匹配的compat属性
 * @return int 没有匹配成功返回0
 */
int of_device_is_compatible(const struct device_node *device,const char *compat);
/**
 * @brief 从device的compatible获取pyh_id,ethernet-phy-idAAAA.BBBB
 * 
 * @param device 设备树节点结构体
 * @param phy_id [out]若匹配成功则输出获取的phy_id
 * @return int 匹配成功返回0,否则返回-EINVAL
 */
int of_get_phy_id(struct device_node *device, u32 *phy_id);

mdio初始化流程

bsp_gemac_mdio_probe		// 注册mdio设备
    of_mdiobus_register		// 注册mdio_bus设备
        of_mdiobus_register_phy		// 遍历子phy设备并注册
    		get_phy_device[note:1]
    			get_phy_id
    			phy_device_create
    		of_mdiobus_phy_device_register
                phy_device_register		// PHY device注册
                    phy_scan_fixups		// 扫描可执行的fixup

gmac初始化流程

gmac_dev_probe			// 注册 gmac 设备	
    gmac_phy_init
    gmac_dev_probe_phy
    	gmac_phy_register_fixups		// 注册fixup函数
    		of_phy_connect
    			phy_connect_direct
    				phy_attach_direct
    					phy_init_hw
    						phy_scan_fixups

note:1

// 如果phy节点包含phy_id,则调用phy_device_create
if (!is_c45 && !of_get_phy_id(child, &phy_id))
    phy = phy_device_create(mdio, addr, phy_id, 0, NULL);
else
    phy = get_phy_device(mdio, addr, is_c45);

参考文档

  1. 一文搞定以太网PHY、MAC及其通信接口
0%