Linux MDIO模塊分析 (六)fixed-mii_bus分析(mac2mac相關)

前面幾章我們介紹了MDIO模塊的大部分內容,針對mii_bus、mdio_bus、phy_device、phy_driver相關的註冊、註銷均進行了介紹。基本上把mdio模塊的內容介紹完了,而本篇介紹的內容,主要是針對虛擬mii_bus實現,並將虛擬phy_device註冊至該mii_bus上。(本次分析內容基於LINUX3.10的內核)

那fixed-mii_bus起到什麼作用呢?其應用場景如下(示意圖如下):

  1. 兩個cpu間的mac通過rgmii/sgmii等直接相連(不需要phy device),這兩塊核心板存在於一塊單板上,無須使用phy芯片。
  2. cpu與fpga間的mac通過rgmii/sgmii等直接相連(不需要phy device),這兩塊核心板存在於一塊單板上,無須使用phy芯片。


Linux MDIO模塊分析 (六)fixed-mii_bus分析(mac2mac相關)

針對這兩種應用場景,均沒有使用phy芯片,但mac的驅動程序為保持通用性還是需要進行mii_bus註冊以及net-device與phy-device的connect。因此mdio模塊設計了一個虛擬的mii_bus(命名為fixed-mii_bus),用於mac芯片無需連接phy芯片的情況。

針對上述情況而言,因兩個mac間直接通過數據總線(rgmii/sgmii/qsgmii等)相連,因此需要手動配置mac芯片的模式(全雙工)、速率(千兆/百兆/萬兆等)。

fixed_mii_bus相關的數據結構說明

主要定義了struct fixed_mdio_bus、struct fixed_phy兩個結構體。其中struct fixed_mdio_bus中包含了

struct mii_bus類型的成員;而struct fixed_phy包含了struct phydev類型的成員。

struct fixed_mdio_bus

該結構體表徵一個虛擬mii_bus,幷包含了fixed相關的信息,其中:

  1. 鏈表頭phys用於將所有註冊至fixed_mii_bus上的邏輯phy device鏈接在一起;
  2. irqs表示每一個虛擬phy對應的中斷(基本上很少有使用該變量的,在mii_bus介紹章節中也說了,該中斷可實現對phy devic link up/down的中斷觸發。在此處基本用不到)
<code>\tstruct fixed_mdio_bus {
int irqs[PHY_MAX_ADDR];
struct mii_bus *mii_bus;
struct list_head phys;
\t};
/<code>

struct fixed_phy

該結構體表徵一個虛擬phy設備,其中:

  • id表示phy的addr,範圍[0-31];
  • regs示該虛擬phy設備的寄存器值(因是一個虛擬phy,因此該虛擬phy的寄存器值由fxied_phy_status中的值決定)
  • ss中定義了該虛擬phy設備的各狀態值,主要包括link狀態、speed、duplex、pause、asym_pause等,而regs中的值即根據該變量中的內容進行設置;
  • link_update接口用於更新虛擬phy的link狀態。該接口類似於struct phydev中的adjust_link。它們之間的區別是:
    1. adjust_link接口根據phy device的link狀態,對net_device的link狀態進行更新;
    2. link_update接口則是根據net_device的link狀態,對虛擬phy設備的link 狀態進行更新。

針對該接口指針,基本上不需要使用,若需要使用,則在創建虛擬phy設備時,賦值即可。

  • node主要用於將該結構體鏈接至fixed_mdio_bus的的phys鏈表上。
<code>\tstruct fixed_phy {
int id;
u16 regs[MII_REGS_NUM];
struct phy_device *phydev;
struct fixed_phy_status status;
int (*link_update)(struct net_device *, struct fixed_phy_status *);
struct list_head node;
\t};
\t
\tstruct fixed_phy_status {
int link;
int speed;
int duplex;
int pause;
int asym_pause;
};/<code>

fixed_mii_bus的實現流程

在《LINUX MDIO模塊分析(三)mii_bus註冊、註銷及其驅動開發流程》中,我們已經敘述瞭如何開發一個mii_bus驅動,此處引用一下:

mii_bus結構體的定義如下,我們實現一個mii_bus驅動也就是實現該結構體類型的變量,並調用上述的

mdiobus_register接口,即可完成mii_bus的註冊。具體步驟如下:

  1. 需設置該mii_bus的名稱與id,而在系統中可根據該id值搜索一個mii_bus;
  2. 完成read、write、reset方法,其中read、write主要用於與該mii_bus下的設備進行命令的交互;而reset方法主要用於對mii_bus的reset,關於這三個方法的實現,驅動開發人員可根據具體mac芯片的手冊說明進行相應的開發操作。
  3. phy_mask主要用於設置需要忽略的phy addr,如我們需要忽略對phy addr 0的查找,則將phy_mask設置為0x01即可。
  4. 而irq主要指向一個數組,該數組中存儲了每一個phy addr對應的irq,主要用於為每一個 phy addr對應的中斷,該中斷主要用於link up/down,針對該部分內容主要涉及到phy state machine,我們在後續章節中會詳述該部分(大部分的mii_bus一般不提供該irq,但phy state machine提供了phy_poll機制,即是沒有該irq,也可以進行phy link up/down,類似於mmc子模塊中mmc card的poll機制)。

而fixed_mii_bus的實現流程也大致如此。下面我們藉助mii_bus的實現流程來分析fixed_mii_bus。

  1. fixed_mii_bus的名稱為fixed-0;
  2. 提供了read、write方法(比不需要實現reset方法,其實write方法也沒有實現,因為掛載在該mii_bus上的均為虛擬phy設備,不需要進行設置操作)。read接口的功能為根據phy addr在fixed_mii_bus的phys鏈表中找到對應的虛擬phy設備,並根據該虛擬phy設備的struct fixed_phy_status類型的成員,更新其寄存器的值,並返回。
  3. fixed_mii_bus在初始化時,並沒有設置需要忽略的phy addr;
  4. 將struct fixed_mdio_bus類型的全局變量platform_fmb中的irq數組賦值給platform_fmb.mii_bus->irq。
  5. 調用mdiobus_register完成fixed_mii_bus的註冊。

fixed_mii_bus基本上嚴格按照我們上一篇文章中介紹的流程創建的mii_bus。而針對虛擬phy設備而言,需

要各模塊自行進行虛擬設備的添加,因此fixed_mii_bus模塊提供了添加接口fixed_phy_add(在3.10的內核中,僅提供了該接口,這限制了fixed_mii_bus的虛擬phy設備的添加時機,後面詳述。而在linux4.x以上的內核增加了接口fixed_phy_register)。

fixed_mdio_bus_init接口分析

該接口主要實現上述所說的fixed_mii_bus的實現流程:

  1. 為fixed_mii_bus申請對應的mii_bus,並設置其read、write、irq變量;
  2. 調用mdiobus_register接口,註冊fixed_mii_bus。此處我們也多說一下:
    1. mdiobus_register接口我們在之前已經介紹過程,其會為phy addr範圍為[0-31]的phy設備,調用mdiobus_scan進行phy device的搜索,若搜索到即為該虛擬phy設備創建phy_device,並註冊到mdio_bus中(在搜索phy device時,即會調用fixed_mii_bus的read接口,若虛擬phy設備已添加到fixed_mii_bus中,則返回的phyid即為該虛擬phy設備的addr值,因此即會調用phy_device_create接口創建phy device,並註冊至mdio_bus中。因此若在fixed_mdio_bus_init調用之前,未將虛擬phy設備添加至fixed_mii_bus上,則進行mdiobus_register時,搜索不到該虛擬phy設備)。


Linux MDIO模塊分析 (六)fixed-mii_bus分析(mac2mac相關)

fixed_mdio_read接口分析

該接口用於獲取一個虛擬phy設備的寄存器值,而針對虛擬phy設備,其各寄存器的值即根據fixed_phy的

struct fixed_phy_status 類型的成員變量status進行設置(即根據在虛擬phy設備的添加時,會通過struct fixed_phy_status 類型的變量,設置該虛擬phy設備的工作模式等信息)。該接口的實現流程圖如下,主要功能為:

  1. 根據輸入的phy addr,查找該phy addr對應的虛擬設備是否已添加至fixed_mii_bus,若沒有則返回失敗;否則進入步驟b;
  2. 若查找的fixed_phy提供link_update接口,則調用該接口更新該fixed_phy->status變量中各成員的值;
  3. 調用fixed_phy_update_regs接口,根據fixed_phy->status更新該fixed_phy各寄存器的值;
  4. 返回該fixed_phy對應寄存器的值。


Linux MDIO模塊分析 (六)fixed-mii_bus分析(mac2mac相關)

fixed_phy_add接口分析

該接口主要將一個fixed_phy添加至fixed_mii_bus中,該接口的實現流程如下所示。主要功能:

  1. 申請struct fixed_phy類型大小的內存空間;
  2. 若申請成功,則設置該fixed_phy的status成員,並更新其regs值;
  3. 將該fixed_phy添加至fixed_mii_bus的成員phys鏈表中。

該接口主要是將一個fixed_phy添加至fixed_mii_bus的成員phys中,並沒有為之創建對應的phy_device。而

針對fixed_mii_bus上的成員phys鏈表上的fixed_phy鏈表成員,僅在fixed_mdio_bus_init中註冊fixed_mii_bus時,通過mdiobus_register時,完成將該鏈表上的所有鏈表成員,均為其註冊對應的phy_device至mdio_bus上。因此若各驅動模塊想通過fixed_phy_add接口添加一個fixed_phy,則必須保證其在接口fixed_mdio_bus_init調用之前被調用到,否則該添加操作不起作用(因沒有創建對應的phy_device)。而在linux3.10中,僅提供了這一個接口進行fixed_phy的添加。這也是這個接口的缺陷,即必須保證調用該接口(fixed_phy_add)的代碼片段在fixed_mdio_bus_init執行之前調用。

Linux MDIO模塊分析 (六)fixed-mii_bus分析(mac2mac相關)

fixed_phy_register接口分析

上面分析fixed_phy_add接口的調用有所限制,必須保證其在fixed_mdio_bus_init執行之前調用。因此在

linux4.x的內核中,增加了接口fixed_phy_register,該接口彌補了fixed_phy_add的不足。接口fixed_phy_register在調用fixed_phy_add之後,調用phy_register,實現phy_device的註冊,彌補了fixed_phy_add的不足。該接口的實現流程圖如下:

  1. 獲取一個可用的phy addr,若獲取不到返回失敗;
  2. 調用fixed_phy_add將該fixed_phy添加至fixed_mii_bus;
  3. 調用phy_register將該phy_device註冊至mdio_bus上。


Linux MDIO模塊分析 (六)fixed-mii_bus分析(mac2mac相關)

在linux3.10及之前的版本,並沒有提供該接口,若要使用則可以自己添加該接口。

以上基本上完成了fixed_mii_bus模塊相關接口的介紹,下面我們主要介紹如何使用fixed_mii_bus的接

口。

Mac2mac驅動程序修改流程

上面介紹了fixed_mii_bus模塊的接口,下面我們說明一下如何修改一個mac的驅動,實現對fixed_phy的支持。我們從兩方面說明(支持設備樹、不支持設備樹)

不支持設備樹模式的修改流程

  1. 在mac驅動對應的platform driver的probe接口中,調用fixed_phy_register,完成fixed_phy的註冊;
  2. 在該net_device的ndo_open接口中,調用phy_connect接口進行phy_device、net_device的綁定時,可根據"fixed-0:phy_addr",在mdio_bus上查找對應的phy_device,從而完成phy_device與net_device的綁定。


支持設備樹模式的修改流程

  1. 在mac驅動對應的platform driver的probe接口中,通過獲取設備樹中針對phy-device的定義(如定義了fixed-link,則說明使用fixed_phy,則調用fixed_phy_register,完成fixed_phy的註冊;在4.x的內核提供了接口of_phy_register_fixed_link進行fixed_phy的註冊);
  2. 在在該net_device的ndo_open接口中,調用phy_connect接口進行phy_device、net_device的綁定時,可根據"fixed-0:phy_addr",在mdio_bus上查找對應的phy_device,從而完成phy_device與net_device的綁定。

通過進行以上的修改,即可讓mac驅動支持fixed-phy的支持。

本章完成了fixed-phy的分析,也基本上完成了mdio子系統的介紹,我們分析了mii_bus相關的實現流程以及具體mii_bus驅動的實現步驟;也分析了phy_device、phy_driver、mdio_bus的實現流程,以及net_device與phy_device的綁定(phy_connect);介紹了phy_device的狀態機流轉相關的內容;fixed_mii_bus與fixed_phy的實現以及如何修改mac驅動支持fixed_phy。


分享到:


相關文章: