1. 簡介
????????本文并不重點講解調試內容,重點了解以太網在ARM設計中的框架以及在設備樹以及驅動的一個整體框架。了解作為一個驅動開發人員當拿到一款未開發過的ARM板卡應該怎么去把網卡配置使用起來。
2. 基礎知識介紹
????????在嵌入式ARM中實現以太網的解決方案通常有以下兩種,通常在性能較低的單片機領域其SOC內部是不具備MAC控制器,但又有需求可以使用方案1這種架構,但在高性能的ARM處理器,例如RK3588這種SOC其內部已集成MAC控制器,可以直接選用方案2。
????????本文重點解方案2,那么在開始之前,先了解PHY芯片與MAC控制器之間的的接口協議RGMII。

????????
- 發送/接收數據線由8條改為4條
- TX_ER和TX_EN復用,通過TX_CTL傳送
- RX_ER與RX_DV復用,通過RX_CTL傳送
- 1 Gbit/s速率下,時鐘頻率為125MHz
- 100 Mbit/s速率下,時鐘頻率為25MHz
- 10 Mbit/s速率下,時鐘頻率為2.5MHz

????????


2. 硬件原理圖
????????有了前面的基礎知識鋪墊,我們從原理圖的硬件連接進一步了解其硬件框架。以RK3588的原理圖為例進行講解:
PHY:?YT8521SH-CA
3. 設備樹硬件描述
? ? ? ? 前面從硬件的角度分析了其框架,那同樣我們也可以在設備樹硬件描述上也能體現出上述框架。
????????MAC控制器設備節點:rk3588.dtsi
????????下面部分通常需要驅動開發人員補充,原因是涉及一些自定義的PHY復位引腳,這些都是自定義的。
????????先看一下引腳復用:rk3588-vccio3-pinctrl.dtsi
? ? ? ? 從上述設備樹節點先分析也是符和前面分析的框架的,對應以太網框架我們先分析到這里。
4. 工作定位
? ? ? ? 到了這里肯能很多朋友會產生疑問,那實際開發過程中我們驅動開發工作人員需要做哪些工作?這里就需要我們清楚我們的定位了,一個千兆網卡在驅動上我們可以劃分為兩大核心部分:MAC控制器驅動+PHY驅動。
? ? ? ? 通常MAC控制器驅動由原廠BSP工程師提供,不需要我們手搓。我們需要重點關注的是PHY驅動,當然由于業內早已建立了標準,內核源碼已提供了一套通用的PHY驅動,這套PHY驅動至少能讓網卡工作起來,不同的PHY廠商也會兼容這套標準。通常不同的廠商還會基于這套通用的驅動自定義屬于他們自己的一套驅動實現更加完善的功能。
5. PHY驅動分析
????????分析PHY驅動之前先補充一個知識點就是,MDIO 接口支持多達 32 個 PHY,它們是通過地址來區分的,通過不同的 PHY 芯片地址來對不同的 PHY 操作,YT8521SH通過設置PHYAD0引腳來設置其PHY地址。
下拉則地址為0x00000:
上拉則地址為0x00001:
? ? ? ? 有了上述的PHY地址了解之后,我們再回頭看看設備樹節點是如何體現PHY地址的,在前面設備樹MAC控制器節點里面有“phy-handle”屬性指定了phy,而phy節點的定義則掛載在了MDIO總線下。rgmii_phy0: phy@0節點名稱的@后面的數值就是 PHY 地址。
????????由于網絡驅動框架比較復雜,如果這里貼代碼展開講解,估計很多朋友就繃不住了,因此我們同樣是采樣框架學習法,了解驅動框架,重點了解我們作為驅動開發者通常需要做哪些工作即可。
? ? ? ? 本文我們不展開講解MAC控制器驅動,這里直接拋出答案:MAC控制器驅動無非就是解析設備樹節點,初始化MAC控制器、通過"phy-handle"屬性解析PHY節點相關信息,做一系列的RGMII接口初始化,最終注冊MDIO總線,注冊PHY設備。
? ? ? ? 講解PHY驅動之前,先了解PHY子系統。PHY 子系統就是用于 PHY 設備相關內容的,分為 PHY 設備和 PHY 驅動,和 platform 總線一樣,PHY 子系統也是一個設備、總線和驅動模型,這里的總線對應的就是MDIO總線。
????????PHY 設備:
????????Linux 內核使用 phy_device 結構體來表示 PHY 設備,結構體定義 在 include/linux/phy.h

????????PHY 設備的注冊過程一般是先調用 get_phy_device 函數獲取 PHY 設備,在通過函數phy_device_register 注冊phy_device。
? ? ? ? 這里需要注意一點的是,PHY設備與PHY驅動匹配并不是通過compatible屬性或name屬性進行匹配的,而是通過PHY ID。? ?
????????PHY 驅動:
????????PHY 驅動使用結構體 phy_driver 表示,結構體也定義在 include/linux/phy.h 文件中
?
????????可以看出,phy_driver 重點是大量的函數,編寫 PHY 驅動的主要工作就是實現這些函數, 但是不一定全部實現。PHY 驅動的注冊使用 phy_driver_register 函數。
????????phy_driver 里面有兩個 成員變量 phy_id 和 phy_id_mask,表示此驅動所匹配的 PHY 芯片 ID 以及 ID 掩碼,PHY 驅動編寫人員需要給這兩個成員變量賦值。phy_device 也有一個 phy_id 成員變量,表示此 PHY 芯 片的 ID,phy_device 里面的 phy_id 是在注冊 PHY 設備的時候調用 get_phy_id 函數直接讀取 PHY 芯片內部 ID 寄存器得到的!很明顯 PHY 驅動和 PHY 設備中的 ID 要一樣,這樣才能匹配 起來。如果 PHY 設備和 PHY 驅動匹配,那么就使用指定的 PHY 驅動,如果不匹配的話就使用Linux 內核自帶的通用 PHY 驅動。
?

????????通用的PHY驅動?drivers/net/phy/phy_device.c
?
????????phy_init 是整個 PHY 子系統的入口函數,調用 phy_driver_register 函數向內核直接注冊一個通用 PHY 驅動:genphy_driver,也就是通用 PHY 驅動,也就是說 Linux 系統啟動以后默認就已經存在了通用 PHY 驅動。
? ? ? ? PHY 廠商驅動:
????????YT8521SH PHY驅動: drivers/net/phy/motorcomm.c
? ? ? ? 說實話,網口驅動知識內容非常多,講到這里個人都差點忘了我們寫這篇文章的最終目的,兩個目的:
1. 如果要配置PHY芯片的某個功能,直接在PHY驅動操作就可以了。
2.需要學會如何在設備樹里面補充完善PHY驅動相關的內容。
????????第一點上面基本講解完了,下面重點講解第二點,回到最開始設備樹節點描述。先提出問題?首先我們是如何知道補充以下內容?
????????以RK3588為例:
參考官方手冊,除此之外還可以參考官板對網卡的配置。
Rockchip_Developer_Guide_Linux_GMAC_CN.pdf
Rockchip_Developer_Guide_Linux_GMAC_Mode_Configuration_CN.pdf