MII (Media Independent Interface(介質無關介面);或稱為媒體獨立介面,它是IEEE-802.3定義的乙太網路行業標準。它包括一個資料介面,以及一個MAC和PHY之間的管理介面。資料介面包括分別用於發送器和接收器的兩條獨立通道。每條通道都有自己的資料、時鐘和控制訊號。MII資料介面總共需要16個訊號。管理介面(我們板子上通過serial management interface,smi)是個雙訊號介面:一個是時鐘訊號,另一個是資料訊號(即MDC(clock),MDIO(data))。通過管理介面,上層能監視和控制PHY。MII(Management interface)只有兩條訊號線。
MII標準介面用於串連Fast Ethernet MAC-block與PHY。“介質無關”表明在不對MAC硬體重新設計或替換的情況下,任何類型的PHY裝置都可以正常工作。在其他速率下工作的與 MII等效的介面有:AUI(10M 乙太網路)、GMII(Gigabit 乙太網路)和XAUI(10-Gigabit 乙太網路)。
在IEEE802.3中規定的MII匯流排是一種用於將不同類型的PHY與相同網路控制卡(MAC)相串連的通用匯流排。網路控制卡可以用同樣的硬體介面與任何PHY進行串連。
MII相關介面介紹:
乙太網路媒體介面有:MII RMII SMII GMII
所有的這些介面都從MII而來,MII是(Medium Independent Interface)的意思,是指不用考慮媒體是銅軸、光纖、電纜等,因為這些ApsaraVideo for Media Processing的相關工作都有PHY或者叫做MAC的晶片完成。
MII支援10兆和100兆的操作,一個介面由14根線組成,它的支援還是比較靈活的,但是有一個缺點是因為它一個連接埠用的訊號線太多,如果一個8連接埠的交換器要用到112根線,16連接埠就要用到224根線,到32連接埠的話就要用到448根線,一般按照這個介面做交換器,是不太現實的,所以現代的交換器的製作都會用到其它的一些從MII簡化出來的標準,比如RMII、SMII、GMII等。
RMII是簡化的MII介面,在資料的收發上它比MII介面少了一倍的訊號線,所以它一般要求是50兆的匯流排時鐘。RMII一般用在多連接埠的交換器,它不是每個連接埠安排收、發兩個時鐘,而是所有的資料連接埠公用一個時鐘用於所有連接埠的收發,這裡就節省了不少的連接埠數目。RMII的一個連接埠要求7個資料線,比MII少了一倍,所以交換器能夠接入多一倍資料的連接埠。和MII一樣,RMII支援10兆和100兆的匯流排介面速度。
SMII是由思科提出的一種媒體介面,它有比RMII更少的訊號線數目,S表示串列的意思。因為它只用一根訊號線傳送發送資料,一根訊號線傳輸接受資料,所以在時鐘上為了滿足100的需求,它的時鐘頻率很高,達到了125兆,為什麼用125兆,是因為資料線裡面會傳送一些控制資訊。SMII一個連接埠僅用4根訊號線完成100訊號的傳輸,比起RMII差不多又少了一倍的訊號線。SMII在工業界的支援力度是很高的。同理,所有連接埠的資料收發都公用同一個外部的125M時鐘。
GMII是千兆網的MII介面,這個也有相應的RGMII介面,表示簡化了的GMII介面。
MII工作原理:
“媒體獨立”表明在不對MAC硬體重新設計或替換的情況下,任何類型的PHY裝置都可以正常工作。包括分別用於發送器和接收器的兩條獨立通道。每條通道都有自己的資料、時鐘和控制訊號。
MII資料介面總共需要16個訊號,包括TX_ER,TXD,TX_EN,TX_CLK,COL,RXD,RX_EX,RX_CLK,CRS,RX_DV等。
MII以4位半位元組方式傳送資料雙向傳輸,時脈速率25MHz。其工作速率可達100Mb/s。
MII管理介面是個雙訊號介面,一個是時鐘訊號,另一個是資料訊號。通過管理介面,上層能監視和控制PHY,其管理是使用SMI(Serial Management Interface)匯流排通過讀寫PHY的寄存器來完成的。
PHY裡面的部分寄存器是IEEE定義的,這樣PHY把自己的目前的狀態反映到寄存器裡面,MAC通過SMI匯流排不斷的讀取PHY的狀態寄存器以得知目前PHY的狀態,例如連線速度,雙工的能力等。
當然也可以通過SMI設定PHY的寄存器達到控制的目的,例如流控的開啟關閉,自協商模式還是強制模式等。
不論是物理串連的MII匯流排和SMI匯流排還是PHY的狀態寄存器和控制寄存器都是有IEEE的規範的,因此不同公司的MAC和PHY一樣可以協調工作。當然為了配合不同公司的PHY的自己特有的一些功能,驅動需要做相應的修改。
PHY是物理介面收發器,它實現物理層。包括MII/GMII(介質獨立介面)子層、PCS(物理編碼子層)、PMA(物理介質附加)子層、PMD(物理介質相關)子層、MDI子層。100BaseTX採用4B/5B編碼。
PHY在發送資料的時候,收到MAC過來的資料(對PHY來說,沒有幀的概念,對它來說,都是資料而不管什麼地址,資料還是CRC),每4bit就增加1bit的檢錯碼,然後把並行資料轉化為串列流資料,再按照物理層的編碼規則把資料編碼,再變為類比訊號把資料送出去。收資料時的流程反之。
PHY還有個重要的功能就是實現CSMA/CD的部分功能。
它可以檢測到網路上是否有資料在傳送,如果有資料在傳送中就等待,一旦檢測到網路空閑,再等待一個隨機時間後將送資料出去。如果兩個碰巧同時送出了資料,那樣必將造成衝突,這時候,衝突檢測機構可以檢測到衝突,然後各等待一個隨機的時間重新發送資料。這個隨機時間很有講究的,並不是一個常數,在不同的時刻計算出來的隨機時間都是不同的,而且有多重演算法來應付出現機率很低的同兩台主機之間的第二次衝突。
通訊速率通過雙方協商,協商的結果是兩個裝置中能同時支援的最大速度和最好的雙工模式,這個技術被稱為Auto Negotiation或者NWAY。
隔離變壓器把PHY送出來的差分訊號用差模耦合的線圈耦合濾波以增強訊號,並且通過電磁場的轉換耦合到串連網線的另外一端。
RJ-45中1、2是傳送資料的,3、6是接收資料的。
新的PHY支援AUTO MDI-X功能(MDI/MDIX自動翻轉功能,個功能使得無論是交叉線還是直連線都能使用),也需要隔離變壓器支援,它可以實現RJ-45介面的1、2上的傳送訊號線和3、6上的接收訊號線的功能自動互相交換。
------------------------------------------------------------------------------------------------------------------
88f6282項目中相關文檔:
hardware spec
p33: smi interface pin assignments
functional spec
p154: mii interface
p161:smi interface
MV-S104224-00_88E1116R_Datasheet.pdf
p19: mac interface (RGMII) ,資料介面
p61: hardware configuration
硬體設定phyad,以後搜尋時候可以搜PHYAD關鍵字
這個晶片是通過CONFIG pins所串連的 pins來配置的(可參考p9)
p63:軟體配置 ,管理介面,SMI(mido,和mdc)
p67:寄存器配置
see also:
mii
http://en.wikipedia.org/wiki/Media_Independent_Interface
Management Data Input/Output, or MDI
http://en.wikipedia.org/wiki/Management_Data_Input/Output
----------------------------------------------------------
88f6282 smi相關函數
mvEthPhy.c
/*******************************************************************************
* mvEthPhyRegRead - Read from ethernet phy register.
*
* DESCRIPTION:
* This function reads ethernet phy register.
*
* INPUT:
* phyAddr - Phy address.
* regOffs - Phy register offset.
*
* OUTPUT:
* None.
*
* RETURN:
* 16bit phy register value, or 0xffff on error
*
*******************************************************************************/
MV_STATUS mvEthPhyRegRead(MV_U32 phyAddr, MV_U32 regOffs, MV_U16 *data)
{
MV_U32 smiReg;
volatile MV_U32 timeout;
/* check parameters */
if ((phyAddr << ETH_PHY_SMI_DEV_ADDR_OFFS) & ~ETH_PHY_SMI_DEV_ADDR_MASK)
{
mvOsPrintf("mvEthPhyRegRead: Err. Illegal PHY device address %d\n",
phyAddr);
return MV_FAIL;
}
if ((regOffs << ETH_PHY_SMI_REG_ADDR_OFFS) & ~ETH_PHY_SMI_REG_ADDR_MASK)
{
mvOsPrintf("mvEthPhyRegRead: Err. Illegal PHY register offset %d\n",
regOffs);
return MV_FAIL;
}
timeout = ETH_PHY_TIMEOUT;
/* wait till the SMI is not busy*/
do
{
/* read smi register */
smiReg = MV_REG_READ(ETH_PHY_SMI_REG);
if (timeout-- == 0)
{
mvOsPrintf("mvEthPhyRegRead: SMI busy timeout\n");
return MV_FAIL;
}
}while (smiReg & ETH_PHY_SMI_BUSY_MASK);
/* fill the phy address and regiser offset and read opcode */
smiReg = (phyAddr << ETH_PHY_SMI_DEV_ADDR_OFFS) | (regOffs << ETH_PHY_SMI_REG_ADDR_OFFS )|
ETH_PHY_SMI_OPCODE_READ;
/* write the smi register */
/*通過smi寄存器操縱phy內部寄存器*/
MV_REG_WRITE(ETH_PHY_SMI_REG, smiReg);
timeout=ETH_PHY_TIMEOUT;
/*wait till readed value is ready */
do
{
/* read smi register */
smiReg=MV_REG_READ(ETH_PHY_SMI_REG);
if (timeout-- == 0) {
mvOsPrintf("mvEthPhyRegRead: SMI read-valid timeout\n");
return MV_FAIL;
}
}while (!(smiReg & ETH_PHY_SMI_READ_VALID_MASK));
/* Wait for the data to update in the SMI register */
for(timeout = 0 ; timeout < ETH_PHY_TIMEOUT ; timeout++);
*data = (MV_U16)( MV_REG_READ(ETH_PHY_SMI_REG) & ETH_PHY_SMI_DATA_MASK);
return MV_OK;
}
/*******************************************************************************
* mvEthPhyRegWrite - Write to ethernet phy register.
*
* DESCRIPTION:
* This function write to ethernet phy register.
*
* INPUT:
* phyAddr - Phy address.
* regOffs - Phy register offset.
* data - 16bit data.
*
* OUTPUT:
* None.
*
* RETURN:
* MV_OK if write succeed, MV_BAD_PARAM on bad parameters , MV_ERROR on error .
* MV_TIMEOUT on timeout
*
*******************************************************************************/
MV_STATUS mvEthPhyRegWrite(MV_U32 phyAddr, MV_U32 regOffs, MV_U16 data)
{
MV_U32 smiReg;
volatile MV_U32 timeout;
/* check parameters */
if ((phyAddr << ETH_PHY_SMI_DEV_ADDR_OFFS) & ~ETH_PHY_SMI_DEV_ADDR_MASK)
{
mvOsPrintf("mvEthPhyRegWrite: Err. Illegal phy address \n");
return MV_BAD_PARAM;
}
if ((regOffs << ETH_PHY_SMI_REG_ADDR_OFFS) & ~ETH_PHY_SMI_REG_ADDR_MASK)
{
mvOsPrintf("mvEthPhyRegWrite: Err. Illegal register offset \n");
return MV_BAD_PARAM;
}
timeout=ETH_PHY_TIMEOUT;
/* wait till the SMI is not busy*/
do
{
/* read smi register */
smiReg=MV_REG_READ(ETH_PHY_SMI_REG);
if (timeout-- == 0) {
mvOsPrintf("mvEthPhyRegWrite: SMI busy timeout\n");
return MV_TIMEOUT;
}
}while (smiReg & ETH_PHY_SMI_BUSY_MASK);
/* fill the phy address and regiser offset and write opcode and data*/
smiReg = (data << ETH_PHY_SMI_DATA_OFFS);
smiReg |= (phyAddr << ETH_PHY_SMI_DEV_ADDR_OFFS) | (regOffs << ETH_PHY_SMI_REG_ADDR_OFFS );
smiReg &= ~ETH_PHY_SMI_OPCODE_READ;
/* write the smi register */
MV_REG_WRITE(ETH_PHY_SMI_REG, smiReg);
return MV_OK;
}