1、MAC操控器、网卡、PHY、MDIO、mii、gmii、rgmii概念扫盲
网卡在功能上包含OSI模型的两个层,数据链路层和物理层。物理层界说了数据传送与接纳所需求的电与光信号、线路状况、时钟基准、数据编码和电路等,并向数据链路层设备供给规范接口。数据链路层则供给寻址组织、数据帧的构建、数据过失查看、传送操控、向网络层供给规范的数据接口等功能。网卡中担任数据链路的芯片叫做MAC操控器,担任物理层的芯片叫做PHY。所以,一个网卡由MAC操控器和PHY组成。
MAC操控器与PHY衔接运用MII(Medium independent interface)媒体独立接口,这个接口是IEEE-802.3界说的以太网行业规范界说的接口,包含一个数据接口和一个MAC和PHY之间的办理接口即MDIO。MII规范接口用于衔接MAC和PHY,媒体独立表明不对MAC硬件从头规划或替换的情况下,任何类型的PHY设备接到当时MAC操控器上都能够正常作业。
MII支撑10M和100M的网络速率,由于网卡的速率不同,所以在其他速率下作业的与MII等效的接口有:AUI(10M 以太网)、GMII(Gigabit 以太网)和XAUI(10-Gigabit 以太网)。此外还有RMII、RGMII、SMII、SGMII等。一切这些接口都是由MII而来。MII支撑10兆和100兆的操作,一个接口由14根线组成。 RMII是简化的MII接口,在数据的收发上它比MII接口少了一倍的信号线。SMII是由思科提出的一种媒体接口,它有比RMII更少的信号线数目,S表明串行的意思。由于它只用一根信号线传送发送数据,一根信号线传输承受数据,所以在时钟上为了满意100的需求,它的时钟频率很高,达到了125兆,为什么用125兆,是由于数据线里面会传送一些操控信息。GMII选用8位接口数据,作业时钟125MHz,因而传输速率可达1000Mbps。一起兼容MII所规则的10/100 Mbps作业方式。RGMII又是GMII接口的精简版。SGMII又是GMII的串行版。
MAC操控器和PHY除了数据传输的沟通外,MAC和PHY操控信息的沟通经过MDIO(办理数据输入输出)接口来完结。详细MAC操控器进行PHY检测、MAC操控器回去PHY当时状况、MAC操控器操控PHY速率等操作就经过MDIO来完结。
2. xilinx uboot网卡驱动剖析
xilinx网卡形式比较灵敏,能够外接PHY芯片也能够用FPGA做PHY芯片。
以zynqmp_zcu102为例,在其dts中界说的网卡设备树为
&gem3 {
status = “okay”;
local-mac-address = [00 0a 35 00 02 90];
phy-handle = 《&phy0》;
phy-mode = “rgmii-id”;
phy0: phy@21 {
reg = 《21》;
TI,rx-internal-delay = 《0x8》;
TI,tx-internal-delay = 《0xa》;
TI,fifo-depth = 《0x1》;
};
};
uboot加载设备树种的信息创立device后,与driver匹配后履行zynq_gem_probe函数。
在uboot中办理整个网卡驱动的结构为
struct zynq_gem_priv {
struct emac_bd *tx_bd;
struct emac_bd *rx_bd;
char *rxbuffers;
u32 rxbd_current;
u32 rx_first_buf;
int phyaddr;
u32 emio;
int init;
struct zynq_gem_regs *iobase;
phy_interface_t interface;
struct phy_device *phydev;
int phy_of_handle;
struct mii_dev *bus;
};
由变量名可知,它包含了一切操作网卡需求的信息。
zynq_gem_probe(struct udevice *dev)函数中详细做的操作有:
priv-》rxbuffers = memalign(ARCH_DMA_MINALIGN, RX_BUF * PKTSIZE_ALIGN); 为priv分配接纳buffers
priv-》tx_bd = (struct emac_bd *)bd_space; //分配tx_bd的空间
priv-》rx_bd = (struct emac_bd *)((ulong)bd_space + BD_SEPRN_SPACE);//分配rx_bd的空间
priv-》bus = mdio_alloc();//分配mdio bus,首要是初始化了一个bus链表
priv-》bus-》read = zynq_gem_miiphy_read; //mdio总线读函数,用于读取phy信息
priv-》bus-》write = zynq_gem_miiphy_write;//mdio写总线函数
priv-》bus-》priv = priv;
strcpy(priv-》bus-》name, “gem”);//总线名为gem
ret = mdio_register(priv-》bus);//注册mdio,首要进行的操作是list_add_tail(&bus-》link, &mii_devs);
return zynq_phy_init(dev); //phy初始化
接下来看下 zynq_phy_init函数里干了啥。
zynq_phy_init(struct udevice *dev)
writel(ZYNQ_GEM_NWCTRL_MDEN_MASK, ®s-》nwctrl);写MAC操控器寄存器,Enable MDIO bus
ret = phy_detecTIon(dev);//经过MDIO来检测phy,经过phyread函数检测正确的phy地址,假如没有检测到,zynq_phy_init将会退出,后边的初始化就不会有,网卡就不能运用,在调试的时分能够注意下这个进程。
priv-》phydev = phy_connect(priv-》bus, priv-》phyaddr, dev,priv-》interface);