1.mac控制器,phy晶片,rgmii協定
2.寄存器介紹
3.驅動源碼解析
4.nanopi t2 移植rtl8211e網卡驅動(首發)
驅動注冊入口
驅動的注冊分兩個部分,一個部分是靜态編譯的時候就會注冊好,另一個是動态注冊。動态網絡驅動注冊的入口主要是從initr_net進入,不熟悉源碼的參見我的uboot源碼解析
board_r.c

從eth_initialize進入eth.c,繼續初始化網絡,檢查有沒有網卡等等
eth.c
eth_common_init做一些架構初始化和phy驅動的注冊,最後注冊扳級初始化代碼,我這裡使用的裝置樹,不存在扳級代碼,有需要添加扳級操作,例如GPIO設定的可以添加到board_eth_init,這兩個函數都是弱引用,不寫就是空的代替。
phy_init()會做PHY驅動的注冊,可以看到有realtek的驅動注冊。
phy.c
cpu_eth_init
cpu級别的初始話和裝置注冊在上面eth_common_init的最後
cpu_eth_init
函數進行。
忽略其他部分,直接看sunxi_gmac_initialize
gmac.c
忽略sunxi_gmac_initialize中的其他部分,看到designware_initialize
designware_initialize
網絡裝置就這裡注冊了
dw_eth_init
dw_eth_send
dw_eth_recv
dw_eth_halt
這幾個函數比較重要,後面資料傳輸的時候分析。
dw_mdio_init
dw_phy_init
在驅動比對的時候又調用了一次,後面比對的時候分析。
驅動的比對
驅動的動态注冊講完了,下面看一下驅動的probe
先是gmac驅動的比對,gmac驅動使用的是
designware.c
這個是在靜态編譯的時候就已經注冊好了的,通過裝置樹中的compatible比對到就開始初始化。我這邊裝置樹的compatible值是
compatible = "nexell,nexell-gmac"
probe裡面對gmac進行初始化:
nexell_gmac_initialize
,mdio管理接口初始化:
dw_mdio_init
,phy初始化:
dw_phy_init
nexell_gmac_initialize
nexell_gmac_initialize
隻要設定gamc工作頻率,以及複位gmac
dw_mdio_init
dw_mdio_init
主要注冊管理接口的讀寫函數,讀寫類似I2C
看一下讀寫函數
給出讀取位址和寄存器就可以了,devad應該是沒什麼作用的。
dw_phy_init
設定PHY支援的速度
PHY_GBIT_FEATURES
基本所有速度都有,不展開,初始化PHY驅動,調用之前注冊好的初始化函數。
phy_config會調用到realtek phy驅動的config函數,看一下realtek phy的驅動
realtek.c
上面的config就調用到這裡了,這裡主要重新開機PHY和禁用中斷,然後跳轉到通用初始化phy.c中,其實這裡的realtek.c和phy.c是一個層次的,realtek.c是phy.c抽出的特殊配置。
比對的關鍵資訊到這裡就結束了。
資料通信
終于到最後的資料通信部分了
裝置初始化
這裡的裝置初始化是指抽象意義上的,主要是完成dev抽象裝置的初始化,完成鍊路速度比對,配置設定DMA傳輸控制塊,DMA記憶體等等。
首當其沖的就是上面留下的懸念函數dw_eth_init了
這裡面主要是以下四個函數
rx_descs_init
tx_descs_init
phy_startup
dw_adjust_link
rx_descs_init
主要就是初始化dmamacdescr 結構體,這個就是前面寄存器部分講的DMA控制符
dmamacdescr 結構體
struct dmamacdescr {
u32 txrx_status;
u32 dmamac_cntl;
u32 dmamac_addr;
u32 dmamac_next;
} __aligned(ARCH_DMA_MINALIGN);
DMA不展開解釋,基本流程就是使用這個描述符資訊進行資料傳輸,完成一個通過dmamac_next尋找下一個繼續傳輸。這裡dmamacdescr被放在數組裡面的,并且最後一個的next是第一個,形成一個循環單向連結清單。dmamac_addr為需要傳送的資料存放的位址,也是一個數組。tx_descs_init類似。
phy_startup
phy_startup最終調用的是realtek驅動中的開始函數
realtek.c
phy.c
主要通過mii管理接口設定鍊路,參考寄存器,不展開。
主要擷取phy的連接配接速度,使用指令的時候顯示的速度就是這裡來的。
dw_adjust_link
根據上一步擷取的速度重新配置gmac速度使之比對。
發送資料
終于到了最後的發送資料部分了
dw_eth_send
主要流程解析:
-
禁用cacheinvalidate_dcache_range:
-
拷貝傳送資料memcpy:
-
将cache寫入記憶體(主要操作cp15寄存器)。DMA讀寫記憶體,必須確定資料寫入記憶體flush_dcache_range:
-
writel(POLL_DATA, &dma_p->txpolldemand):
開始DMA傳送,寄存器篇有講過一個txpolldemand寄存器就是這個。
接收資料類似,到這裡整個流程就結束了。