如何使用 gpio 模擬 mdio 通信?

一、前言

實際項目開發中,由於設計原因,會將 phy 的 mdio 引腳連接到 SoC 的 2 個空閒 gpio 上,

這樣就無法通過 Gmac 自有的架構實現修改 phy,

因此只能通過 GPIO 模擬的方式實現 MDIO,

好在 Linux 支持 MDIO via GPIO 功能。

該功能需要用到內核驅動 mdio-bitbang.c 和 mdio-gpio.c。

本例 :

復旦微
linux 4.14.55-xxxxx
yt8521
gmac0
gpioc 2
portc 3

二、mdio 基礎概念

1、SMI 接口

SMI 是 MAC 內核訪問 PHY 寄存器接口,它由兩根線組成,雙工:

原理上跟 I2C 總線很類似,也可以通過總線訪問多個不同的 phy。

MDIO 協議是以太網標準 IEEE802.3 中專門用於 MAC 和 PYH 之間管理的串行接口總線,該接口主要用於 MAC 控制器對 PYH 層的狀態讀取和設置(寄存器操作)、獲取鏈路狀態,控制物理層協商等操作。

MDC/MDIO 基本特性:

其中主設備稱作 STA,從設備稱作 MDI,一個主設備可以對多個從設備進行命令讀寫操作。

三、mdio 協議波形

1、MDIO 接口數據幀

在 IEEE802.3 協議中,把 MDIO 接口數據幀分爲兩種,一種是 Clause22,另一種是 Clause45

前者主要用於百兆千兆以太網,後者用於千兆以上的以太網。

2、Clause22

MDIO 接口的讀寫通信協議如下圖所示:

CLAUSE22 數據幀協議

波形舉例

向phy:3 寄存器0x00 寫入 數據0x4140

3、Clause45

四、YT8521

YT8521S 是一款高度集成的以太網收發器,符合 10BASE-Te、100BASE-TX 和 1000BASE-T IEEE 802.3 標準。

1、引腳

其中與 mdio 相關引腳:

14  MDC         Management Data Clock
15  MDIO        Input/Output of Management Data.
      Pull up 3.3V/2.5V/1.8V for 3.3V/2.5V/1.8V I/O respectively

2、模塊圖

3、MDIO 協議時序 -[重要]

下面 YT8521 的 SMI 時序圖:

上升沿讀數據,下降沿寫數據

五、驅動移植

1、驅動文件及移植

mdio-gpio.c
mdio-bitbang.c

在這裏插入圖片描述

勾選 下面幾項:

  │ │                   <*>   Bitbanged MDIO buses                                            │ │  
  │ │                   <*>   GPIO controlled MDIO bus multiplexers                           │ │  
  │ │                   <*>   MMIO device-controlled MDIO bus multiplexers                    │ │

2、移植設備樹

 aliases {
    …………
     mdio-gpio0 = &mdio0;
 };
 
 mdio0: mdio {
     compatible = "virtual,mdio-gpio";
     gpios = <&portc 2 0 >,<&portc 3 0>;                                               
     #address-cells = <1>;
     #size-cells = <0>;
   
     phy0: ethernet-phy@7 {
         reg = <0x7>;
         yt,phy-delay = <0xfc>;
         phy-connection-type = "rgmii-id";
     };
 };
 &gmac0 {
  status = "okay";
  phy-handle = <&phy0>;
 };

由設備樹可知,

  1. 我們創建了 1 個獨立的 mdio 設備節點,

  2. 當用命令 mdio 修改 phy 時,就會根據 gmac0 的 phy-handle,

  3. 找到 mdio0 節點從而調用 mdio-gpio 驅動模塊來配置 phy:8521。

下圖,是 phy 直接連接到 gmac0 的 mdio 接口,mdio 命令執行的通路:

下圖是 phy 連接到 gpio 口,mdio 命令執行的通路:

3、查看 log

開機有以下 log,說明驅動 移植成功:

# dmesg | grep MDIO
[    3.257270] libphy: GPIO Bitbanged MDIO: probed
[    3.274202] libphy: Fixed MDIO Bus: probed
# cd /sys/class/mdio_bus/
# ls
fixed-0   gpio-0    stmmac-0  stmmac-1
# cd gpio-0/
# ls
device     gpio-0:03  of_node    power      subsystem  uevent
# cd gpio-0\:03/
# ls
attached_dev    phy_has_fixups  power
driver          phy_id          subsystem
of_node         phy_interface   uevent

4、操作

修改 eth0 爲百兆速率,則設置 Speed_Selection 位爲 01,同時自動協商爲 Autoneg_En 要禁用,即設置該寄存器值爲 0x2140:

# mdio eth0 0x00 0x2140
 write phy addr: 0x3  reg: 0x0  value : 0x2140

抓取波形如下:

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/TYUAnNLTJuZ7swp2ULDZow