基于嵌入式Linux的千兆以太網(wǎng)卡驅(qū)動(dòng)程序設(shè)計(jì)及測(cè)試
一.引言
千兆以太網(wǎng)是一種具有高帶寬和高響應(yīng)的新網(wǎng)絡(luò)技術(shù),相關(guān)協(xié)議遵循IEEE802.3規(guī)范標(biāo)準(zhǔn)。采用和10M以太網(wǎng)相似的幀格式、網(wǎng)絡(luò)協(xié)議和布線系統(tǒng),基于光纖和短距離同軸電纜的物理層介質(zhì),更適用于交換機(jī)、服務(wù)器等數(shù)據(jù)吞吐率大的設(shè)備。本文設(shè)計(jì)實(shí)現(xiàn)一種基于嵌入式Linux千兆以太網(wǎng)卡的驅(qū)動(dòng)程序,并完成后續(xù)的測(cè)試工作和代碼移植。
千兆以太網(wǎng)網(wǎng)卡工作在OSI網(wǎng)絡(luò)架構(gòu)的物理層和數(shù)據(jù)鏈路層,其中物理層由PHY芯片管理,數(shù)據(jù)鏈路層由千兆以太網(wǎng)控制器(GMAC)管理。硬件構(gòu)架上,GMAC控制器由核心層、MTL(MACTransactionLayer)層、DMA層和總線接口層構(gòu)成,如下圖1-1所示。核心層連接PHY芯片,管理和PHY芯片之間的通信;MTL層建立物理層和內(nèi)存之間的數(shù)據(jù)通道,調(diào)整幀傳輸結(jié)構(gòu),控制數(shù)據(jù)流,轉(zhuǎn)換時(shí)鐘域;DMA層完成數(shù)據(jù)的傳輸任務(wù)。GMAC配置寄存器CSR(ControlandStatusregister)通過(guò)系統(tǒng)總線和CPU交互,CPU通過(guò)總線slave端配置DMA和MAC區(qū)的CSR,其中MAC區(qū)的CSR可以設(shè)置PHY的芯片寄存器,通過(guò)對(duì)CSR的設(shè)置可以控制網(wǎng)卡切換工作狀態(tài)。
千兆以太網(wǎng)卡的數(shù)據(jù)傳輸任務(wù)由DMA完成,DMA傳輸操作通過(guò)預(yù)先在內(nèi)存中建立描述符的方式完成。描述符的作用是指定MAC幀數(shù)據(jù)所在的緩存地址,每個(gè)描述符可以最多指定兩個(gè)緩存地址,緩存大小有嚴(yán)格控制,一個(gè)描述符不能指定全部一個(gè)幀的緩存數(shù)據(jù),需要多個(gè)描述符構(gòu)成描述符鏈來(lái)完成。
有兩種描述符鏈結(jié)構(gòu):環(huán)狀描述符和鏈狀描述符。鏈狀描述符中的第二個(gè)buffer指定了下一個(gè)描述符所在的物理地址,而第一個(gè)buffer指定幀數(shù)據(jù)緩存的位置,環(huán)狀結(jié)構(gòu)描述符的位置是有序排放的,兩個(gè)buffer都指向幀數(shù)據(jù)的緩存地址,最后一個(gè)描述符指向第一個(gè)描述符所在物理地址形成桶狀描述符鏈。環(huán)狀和鏈狀結(jié)構(gòu)如圖1-2所示,一個(gè)描述符鏈只能用來(lái)存儲(chǔ)一個(gè)MAC幀的數(shù)據(jù),DMA每個(gè)通道一次最多完成兩個(gè)MAC幀的傳輸,多MAC幀的傳輸需要重新使能DMA通道。
描述符的具體結(jié)構(gòu)如圖1-3所示:
OWN位控制描述符是由DMA控制還是由host端控制,后面31位是描述符狀態(tài)信息,DES1為控制描述符并標(biāo)明兩個(gè)buffer大小,DES2和DES3描述兩個(gè)buffer所在地址。
二.千兆以太網(wǎng)卡驅(qū)動(dòng)程序設(shè)計(jì)
GMAC驅(qū)動(dòng)程序需要完成的內(nèi)容有:PHY芯片初始化,GMAC初始化,GMAC讀/寫數(shù)據(jù),GMAC數(shù)據(jù)流控制和各種模式設(shè)置。
GMAC初始化流程圖如圖2-1所示:
GMAC初始化過(guò)程首先檢查PHY芯片工作是否正常并配置PHY芯片模式,創(chuàng)建發(fā)送和接收描述符,初始化DMA,然后配置MAC工作模式,使能DMA后進(jìn)入工作狀態(tài)。
初始化完成后,數(shù)據(jù)等待發(fā)送或接收,DMA根據(jù)描述符狀態(tài)自動(dòng)完成數(shù)據(jù)發(fā)送或接收的任務(wù)。buffer中的幀結(jié)構(gòu)不包含preamble,PADbyte和FCS段,只包含源地址,目的地址和類型/長(zhǎng)度域。如果MAC禁止CRC校驗(yàn)和PAD插入,那么buffer就必須包含完整的幀結(jié)構(gòu),其中必須包含CRC校驗(yàn)位。DMA一次搬運(yùn)最多兩幀數(shù)據(jù),所以初始化后如果需要完成多幀數(shù)據(jù)搬運(yùn)需要重新使能DMA。
GMAC發(fā)送和接收過(guò)程如左圖2-2所示:

初始化后,第一次幀傳輸不需要等待中斷,DMA自動(dòng)完成發(fā)送接收任務(wù),當(dāng)有多次幀傳輸時(shí),DMA在完成一次發(fā)送接收任務(wù)后會(huì)給CPU發(fā)送中斷,CPU響應(yīng)中斷處理下一次讀寫任務(wù)。如果讀寫過(guò)程中發(fā)生幀錯(cuò)誤等導(dǎo)致操作未完成,則會(huì)產(chǎn)生相應(yīng)異常中斷直到CPU清除中斷位標(biāo)志,此時(shí)GMAC停止工作。
驅(qū)動(dòng)程序設(shè)計(jì)完成寄存器到功能函數(shù)的轉(zhuǎn)換,給上層操作系統(tǒng)提供應(yīng)用接口,Linux嵌入式操作系統(tǒng)有一套標(biāo)準(zhǔn)的接口規(guī)范,根據(jù)該規(guī)范設(shè)計(jì)驅(qū)動(dòng)需要預(yù)先定義兩種重要的結(jié)構(gòu)體:
描述符程序結(jié)構(gòu)體設(shè)計(jì):
typedefstructDmaDescStruct
{
__u32status;//DMA狀態(tài)
__u32length;//buffer1和buffer2長(zhǎng)度
__u32buffer1;//buffer1地址
__u32buffer2;//buffer2地址
//下面數(shù)據(jù)僅為驅(qū)動(dòng)使用
__u32extstatus;//接收描述符的擴(kuò)展位狀態(tài)
__u32reserved1;//保留部分
__u32timestamplow;//時(shí)間戳
__u32timestamphigh;
__u32data1;//buffer1虛擬地址(驅(qū)動(dòng)備用)
__u32data2;//buffer2虛擬地址(驅(qū)動(dòng)備用)
}DmaDesc;
GMAC控制器設(shè)備程序結(jié)構(gòu)體設(shè)計(jì):
typedefstructGMACDeviceStruct
{
__u32MacBase;//MAC基地址
__u32DmaBase;//DMA基地址
__u32PhyBase;//PHY基地址
__u32Version;
DmaDesc*TxDesc;//發(fā)送描述符鏈開始地址
DmaDesc*RxDesc;//接收描述符鏈開始地址
__u32BusyTxDesc;//當(dāng)前DMA所擁有發(fā)送描述符鏈數(shù)量
__u32BusyRxDesc;//當(dāng)前DMA所擁有接搜描述符鏈數(shù)量
__u32RxDescCount;//當(dāng)前描述符鏈中接收描述符數(shù)量
__u32TxDescCount;//當(dāng)前描述符鏈中發(fā)送描述符數(shù)量
__u32TxBusy;//指明當(dāng)前發(fā)送描述符是否由DMA控制,即OWN位是否為1
__u32TxNext;//指明下一個(gè)描述符鏈?zhǔn)欠裼行?/p>
__u32RxBusy;
__u32RxNext;
DmaDesc*TxBusyDesc;//與TxBusy對(duì)應(yīng)的當(dāng)前描述符地址
DmaDesc*TxNextDesc;//與TxNext對(duì)應(yīng)的下一個(gè)描述符鏈地址
DmaDesc*RxBusyDesc;
DmaDesc*RxNextDesc;
__u32ClockDivMdc;//時(shí)鐘分頻數(shù)
__u32LinkState;//網(wǎng)卡鏈接狀態(tài)
__u32DuplexMode;//半雙工,全雙工等工作模式選擇
__u32Speed;//連接速度。10M/100M/1000M
__u32LoopBackMode;//LoopBack模式
}GMACdevice;
三.測(cè)試實(shí)現(xiàn)
測(cè)試程序?qū)MAC進(jìn)行了相應(yīng)的黑盒測(cè)試和壓力測(cè)試,黑盒測(cè)試用來(lái)測(cè)試GMAC千兆網(wǎng)卡的各個(gè)模塊輸入相應(yīng)信號(hào)是否得到正確的輸出信號(hào),壓力測(cè)試用來(lái)測(cè)試網(wǎng)卡的系統(tǒng)穩(wěn)定性。
測(cè)試程序通過(guò)GMAC的LoopBack模式將數(shù)據(jù)寫入內(nèi)存并讓GMAC發(fā)送,再?gòu)慕邮彰枋龇付ǖ膬?nèi)存中讀出,判斷寫入寫出數(shù)據(jù)是否一致,完成數(shù)據(jù)讀寫測(cè)試。對(duì)于功能點(diǎn)測(cè)試,主要測(cè)試的GMAC功能有:PHY芯片自協(xié)商完成驗(yàn)證,GMACLoopBack模式,哈希值和MAC幀過(guò)濾,CRC校驗(yàn)和,AV模式和時(shí)間戳支持模式。
一次讀寫測(cè)試完成后,測(cè)試程序改變GMAC模式和狀態(tài),再進(jìn)行一次數(shù)據(jù)讀寫測(cè)試,同時(shí)加大數(shù)據(jù)量和功能點(diǎn)以完成壓力測(cè)試,再次判斷寫入寫出數(shù)據(jù)是否一致。不斷循環(huán)進(jìn)行直到測(cè)試程序測(cè)試結(jié)束,測(cè)試過(guò)程要完成判定覆蓋和條件覆蓋的100%代碼覆蓋率,需要不斷改變輸入信號(hào)和功能以滿足測(cè)試意圖,使用LoopBack模式的測(cè)試信號(hào)發(fā)送和接收結(jié)果如圖所示:
PHY和MAC使用GMII接口連接,全雙工模式下發(fā)送的同時(shí)進(jìn)行接收操作,實(shí)驗(yàn)結(jié)果發(fā)現(xiàn)在幀傳輸速度提升到1.3GMbps時(shí),有明顯的丟幀現(xiàn)象,MAC層的幀數(shù)據(jù)FIFO原數(shù)據(jù)被沖刷,丟幀現(xiàn)象明顯。在使能中斷的情況下,發(fā)生丟幀后會(huì)立刻進(jìn)入異常中斷,DMA停止工作等待CPU響應(yīng)中斷。
四.結(jié)束語(yǔ)
該驅(qū)動(dòng)程序已經(jīng)在Linux嵌入式系統(tǒng)下調(diào)試通過(guò),所有代碼下Linux嵌入式系統(tǒng)下移植完成,驅(qū)動(dòng)程序在MaPU定制指令SOC系統(tǒng)上調(diào)試通過(guò),使用該驅(qū)動(dòng)完成后續(xù)上層軟件開發(fā)。驗(yàn)證平臺(tái)基于ARMCortexA8,測(cè)試仿真使用RealViewDebugger完成指令仿真,使用VCS進(jìn)行時(shí)序精確仿真,測(cè)試程序代碼覆蓋率達(dá)到90%以上。
愛華網(wǎng)



