Xilinx Uboot網卡驅動分析


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, &regs->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);

本文轉載自: https://blog.csdn.net/u012075739/article/details/52966751


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM