9-Linux phy system

題圖:gratisography

Linux phy system

PHY芯片為OSI的最底層-物理層(Physical Layer),通過MII與數(shù)據(jù)鏈路層的MAC芯片相連跳仿,對于MAC與PHY之間的一些知識可以查看Mac與Phy組成原理的簡單分析,這篇文章進行熟悉。

PHY與MAC整體的連接框架:

連接框架

PHY的硬件系統(tǒng)算是比較復雜的,PHY與MAC相連灿椅,MAC與CPU相通,PHY與MAC通過MII和MDIO/MDC相連钞支,MII是走網(wǎng)絡數(shù)據(jù)的茫蛹,MDIO/MDC是用來與PHY的寄存器通訊的,對PHY進行配置烁挟。類似的SWITCH芯片一般也有兩種接口婴洼,MII用來走網(wǎng)絡數(shù)據(jù),SPI用來設置SWITCH的寄存器撼嗓。

跟以前分析I2C/SPI的驅(qū)動一樣柬采,分為控制器驅(qū)動和設備器驅(qū)動欢唾。

1、控制器驅(qū)動

控制器的驅(qū)動使用的一樣是platform總線的連接方式粉捻,在arch或dts下面進行對phy的platform進行add礁遣,platform_driver的register一般也放在/driver/net/phy/下面,device和driver的name匹配后就會執(zhí)行platform_driver結(jié)構(gòu)體所對應的probe接口,都大同小異肩刃,如下:

static struct platform_driver pfe_platform_driver = {
    .probe = pfe_platform_probe,
    .remove = pfe_platform_remove,
    .driver = {
        .name = "pfe",
#ifdef CONFIG_PM
        .pm = &pfe_platform_pm_ops,
#endif
    },
};


static int __init pfe_module_init(void)
{
    return platform_driver_register(&pfe_platform_driver);
}


static void __exit pfe_module_exit(void)
{
    platform_driver_unregister(&pfe_platform_driver);
}

MODULE_LICENSE("GPL");
module_init(pfe_module_init);
module_exit(pfe_module_exit);

因為phy與cpu的通訊配置使用的是MII祟霍、MDIO/MDC來進行傳輸控制的,所以probe函數(shù)里面如要對MII總線進行配置盈包,最后調(diào)用mdiobus_register()of_mdiobus_register()對mdio_bus進行注冊沸呐。

of_mdiobus_register()函數(shù)位于drivers/of/of_mdio.c中,該函數(shù)最后還是會調(diào)用mdiobus_register()函數(shù)呢燥,mdiobus_register()函數(shù)位于drivers\net\phy\mdio_bus.c中垂谢,通過一層一層的往下?lián)埽瑫腥缦陆Y(jié)構(gòu):

 ‐‐> mdiobus_register
     ‐‐> device_register
     ‐‐> mdiobus_scan
         ‐‐> get_phy_device
             ‐‐> get_phy_id         // 讀寄存器
                 ‐‐> phy_device_create  // 創(chuàng)建phy設備
                 ‐‐> INIT_DELAYED_WORK(&dev‐>state_queue, phy_state_machine); //初始化狀態(tài)機

這邊就是控制器和設備器的交接了疮茄,創(chuàng)建phy設備初始化PHY狀態(tài)機,接下去就看設備器的驅(qū)動根暑。

2力试、設備器驅(qū)動

設備器的驅(qū)動也是三個方面device每强、driver糯笙、bus。PHY的device接口為phy_device_registerphy_device_release滑频,driver接口為phy_driver_registerphy_driver_unregister淳地,bus接口為mdiobus_registermdiobus_unregister怖糊。

這樣一分析感覺就跟清晰了,有關(guān)PHY驅(qū)動的內(nèi)容都位于/drivers/net/phy中颇象。

phy的設備驅(qū)動不像i2c/spi有一個board_info函數(shù)進行添加設備伍伤,而是直接讀取phy中的寄存器,根據(jù)IEEE的規(guī)定PHY芯片的前16個寄存器的內(nèi)容必須是固定的遣钳,如下:


register

其中寄存器0x02和0x03即設備ID的高低位扰魂,每一種型號的PHY有其一串ID號,這我們查看對于的手冊即可知道蕴茴。

在設備的driver中使用MODULE_DEVICE_TABLE將對應的設備ID添加進入劝评,他的效果可以理解為board_info函數(shù)所實現(xiàn)的內(nèi)容,如broadcom的table:

static struct mdio_device_id __maybe_unused broadcom_tbl[] = {
    { PHY_ID_BCM5411, 0xfffffff0 },
    { PHY_ID_BCM5421, 0xfffffff0 },
    { PHY_ID_BCM54210S, 0xfffffff0 },
    { PHY_ID_BCM5461, 0xfffffff0 },
    { PHY_ID_BCM5464, 0xfffffff0 },
    { PHY_ID_BCM5482, 0xfffffff0 },
    { PHY_ID_BCM5482, 0xfffffff0 },
    { PHY_ID_BCM50610, 0xfffffff0 },
    { PHY_ID_BCM50610M, 0xfffffff0 },
    { PHY_ID_BCM57780, 0xfffffff0 },
    { PHY_ID_BCMAC131, 0xfffffff0 },
    { PHY_ID_BCM5241, 0xfffffff0 },
    { }
};

MODULE_DEVICE_TABLE(mdio, broadcom_tbl);

phy_driver的register大概為如下一個過程倦淀,進行簡單分析:

drivers/net/phy/phy_device.c
phy_init
    ‐‐> mdio_bus_init 注冊mdio總線
       ‐‐> class_register(&mdio_bus_class);
       ‐‐> bus_register(&mdio_bus_type);
 ‐‐> phy_driver_register(&genphy_driver);

在mdio總線注冊的時候會調(diào)用mdio_bus_match蒋畜,如果match函數(shù)找到設備則會進行設備驅(qū)動的注冊,match函數(shù)位于/drivers/net/phy/mdio_bus.c中撞叽,如下姻成,進行phy_id的打印插龄。

static int mdio_bus_match(struct device *dev, struct device_driver *drv)
{
    struct phy_device *phydev = to_phy_device(dev);
    struct phy_driver *phydrv = to_phy_driver(drv);
    
    printk("phydev->phy_id:%x ",phydev->phy_id);
    printk("phydrv->phy_id:%x \n",phydrv->phy_id);
    
    return ((phydrv->phy_id & phydrv->phy_id_mask) ==
        (phydev->phy_id & phydrv->phy_id_mask));
}

由log可以看出,設備dev的ID為600d8595佣渴,然后就去查找對應的驅(qū)動drv的ID辫狼,知道找到600d8595則進入probe函數(shù)。

[   23.306611] phydev->phy_id:600d8595 phydrv->phy_id:ffffffff
[   23.312150] phydev->phy_id:600d8595 phydrv->phy_id:ffffffff
[   23.317731] phydev->phy_id:600d8595 phydrv->phy_id:4dd072
[   23.323084] phydev->phy_id:600d8595 phydrv->phy_id:4dd033
[   23.328461] phydev->phy_id:600d8595 phydrv->phy_id:206070
[   23.333812] phydev->phy_id:600d8595 phydrv->phy_id:2060e0
[   23.339182] phydev->phy_id:600d8595 phydrv->phy_id:600d8595

這樣找到ID后就會進行設備驅(qū)動的注冊辛润,對應的phy_driver_register()函數(shù)才能返回成功膨处,才會執(zhí)行phy_driver結(jié)構(gòu)體下面的內(nèi)容,如下:

static struct phy_driver bcm54210s_driver = {
    .phy_id     = PHY_ID_BCM54210S,
    .phy_id_mask    = 0xfffffff0,
    .name       = "Broadcom BCM54210S",
    .features   = PHY_GBIT_FEATURES |
              SUPPORTED_Pause | SUPPORTED_Asym_Pause,
    .flags      = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
    .config_init    = bcm54210s_config_init,
    .config_aneg    = bcm54210s_config_aneg,
    .read_status    = bcm54210s_read_status,
    .ack_interrupt  = bcm54xx_ack_interrupt,
    .config_intr    = bcm54xx_config_intr,
    .driver     = { .owner = THIS_MODULE },
};

里面對phy的寄存器等進行初始化配置砂竖,這邊對PHY的驅(qū)動進行簡單的介紹真椿,關(guān)于PHY的內(nèi)容還有好多,比如:PHY狀態(tài)機乎澄、ethtool工具這些都是在后面應用的時候需要用到的突硝,等我自己深入研究后再進行學習總結(jié)。

Linux phy system的分析就到這邊置济,有感悟時會持續(xù)會更新解恰。

注:以上內(nèi)容都是本人在學習過程積累的一些心得,難免會有參考到其他文章的一些知識浙于,如有侵權(quán)护盈,請及時通知我,我將及時刪除或標注內(nèi)容出處羞酗,如有錯誤之處也請指出腐宋,進行探討學習。文章只是起一個引導作用檀轨,詳細的數(shù)據(jù)解析內(nèi)容還請查看Linux相關(guān)教程胸竞,感謝您的查閱。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末参萄,一起剝皮案震驚了整個濱河市卫枝,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌讹挎,老刑警劉巖剃盾,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異淤袜,居然都是意外死亡痒谴,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門铡羡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來积蔚,“玉大人,你說我怎么就攤上這事烦周【”” “怎么了怎顾?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長漱贱。 經(jīng)常有香客問我槐雾,道長,這世上最難降的妖魔是什么幅狮? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任募强,我火速辦了婚禮,結(jié)果婚禮上崇摄,老公的妹妹穿的比我還像新娘擎值。我一直安慰自己,他們只是感情好逐抑,可當我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布鸠儿。 她就那樣靜靜地躺著,像睡著了一般厕氨。 火紅的嫁衣襯著肌膚如雪进每。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天命斧,我揣著相機與錄音品追,去河邊找鬼。 笑死冯丙,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的遭京。 我是一名探鬼主播胃惜,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼哪雕!你這毒婦竟也來了船殉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤斯嚎,失蹤者是張志新(化名)和其女友劉穎利虫,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體堡僻,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡糠惫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了钉疫。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片硼讽。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖牲阁,靈堂內(nèi)的尸體忽然破棺而出固阁,到底是詐尸還是另有隱情壤躲,我是刑警寧澤,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布备燃,位于F島的核電站碉克,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏并齐。R本人自食惡果不足惜漏麦,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望冀膝。 院中可真熱鬧唁奢,春花似錦、人聲如沸窝剖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽赐纱。三九已至脊奋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間疙描,已是汗流浹背诚隙。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留起胰,地道東北人久又。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像效五,于是被迫代替她去往敵國和親地消。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內(nèi)容