以太網驅動的流程淺析(四)-以太網驅動probe流程
**Author:張昺華
Email:920052390@qq.com
Time:2019年3月23日星期六
**
此文也在我的個人公眾號以及《Linux內核之旅》上有發表:以太網驅動的流程淺析(四)-以太網驅動probe流程
很喜歡一群人在研究技術,一起做有意思的東西,一起分享技術帶給我們的快樂,也希望中國有更多的人熱愛技術,喜歡一起研究、分享技術,然后可以一起用我們的技術來做一些好玩的東西,可以為這個社會創造一些東西來改善人們的生活。
如下是本人調試過程中的一點經驗分享,以太網驅動架構畢竟涉及的東西太多,如下僅僅是針對加載流程和圍繞這個問題產生的分析過程和驅動加載流程部分,並不涉及以太網協議層的數據流程分析。
【硬件環境】 Imx6ul
【Linux kernel版本】 Linux4.1.15
【以太網phy】 Realtek8201f
1.1. 以太網驅動probe流程
1.1 以太網初始化
fec_main.c fec_probe
=>fec_enet_mii_init
=>of_get_child_by_name(pdev->dev.of_node, "mdio");
of_mdiobus_register(fep->mii_bus, node);
=>rc = of_mdiobus_register_phy(mdio, child, addr);
=> phy = get_phy_device(mdio, addr, is_c45);
rc = phy_device_register(phy);
搞驅動的都知道,probe是drvier的入口函數:
這個 probe中主要做了哪些事情呢?以下我只寫主要的一些,不是全部的。
struct net_device *ndev;這里對net_device進行初始化,分配內存
接下來做如下動作,注釋都很明顯,我就不解釋了,
struct fec_enet_private *fep;
獲取時鍾:
使能clk,fec_enet_clk_enable(ndev, true);
復位phy,硬件復位,具體取決於不同phy的datasheet的reset時序,fec_reset_phy(pdev);
一些初始化動作,fec_enet_init(ndev);由於代碼注釋寫的很好,上代碼:
1.2 獲取以太網mac地址
這里獲取mac 地址的流程我要說一下,之前有講過流程,我這里再提一下:
1) 模塊化參數設置,如果沒有跳到步驟2
2) device tree中設置,如果沒有跳到步驟3;
3) from flash / fuse / via platform data,如果沒有跳到步驟4;
4) FEC mac registers set by bootloader===》即靠usb方式下載mac address ,如果沒有跳到步驟5;
- 靠kernel算一個隨機數mac address出來,然后寫入mac
所以最后一種方式就是kernel會自己算一個mac地址出來,我這里有個前提是這個是freescale(現在被nxp收購了)的控制器代碼這樣寫的,我不確定其他廠商的控制器是否也是這樣的流程,技術講究嚴謹,所以這里不能一概而論。當然這個mac 地址也是可以用戶自己在dts中進行自行配置的。
這里就是kernel隨機數的接口了,會總隨機池中獲取一個隨機數並返回。
大家看到那些獲取mac address的步驟中有這樣的函數
is_valid_ether_addr,用來檢測以太網地址是否正確的
因此我們從代碼中可以看出,內核認為全0或者是全FF的以太網地址是不正確的,
獲取了mac 地址后,就會通過寄存器寫入mac中
CONFIG_ARCH_MXC因為我們使用的是這個宏,因此:
否則:
設置buffer傳輸的基地址
提供一些以太網控制器的操作接口,應用層調用socket通信最終的實現接口方式,並且提供開源工具ethtool工具的底層操作接口支持
所以有些人用ethtool工具發現不同平台可能不一樣,同樣的命令有些可能返回不同,或者功能不支持,就可以猜想一下可能是因為不同廠商的控制器驅動這里的實現問題導致,部分接口可能沒有實現或者有bug等等,這些就要具體問題具體分析了,有些板子可能某些接口根本都沒實現,自然ethtool的一些命令就無法正常使用了。
最后進行控制器對phy的復位動作
fec_restart(ndev);
流程如下:
- Whack a reset. We should wait for this. For i.MX6SX SOC, enet use AXI bus, we use disable MAC , instead of reset MAC itself.
2)enet-mac reset will reset mac address registers too, so need to reconfigure it. - Clear any outstanding interrupt.
- Reset tx SKB buffers.
- Enable MII mode
- The phy interface and speed need to get configured,
- configure the gasket: RMII, 50 MHz, no loopback, no echo; MII, 25 MHz, no loopback, no echo
- Setup multicast filter.
- And last, enable the transmit and receive processing
- Enable interrupts we wish to service
- Init the interrupt coalescing
fec_enet_init函數的流程到此結束
我們繼續回歸到fec_probe函數,然后是注冊中斷處理函數
4. 網址分享
http://stackoverflow.com/questions/5308090/set-ip-address-using-siocsifaddr-ioctl
http://www.ibm.com/support/knowledgecenter/ssw_aix_72/com.ibm.aix.commtrf2/ioctl_socket_control_operations.htm
https://lkml.org/lkml/2017/2/3/396
linux PHY驅動
http://www.latelee.org/programming-under-linux/linux-phy-driver.html
Linux PHY幾個狀態的跟蹤
http://www.latelee.org/programming-under-linux/linux-phy-state.html
第十六章PHY -基於Linux3.10
https://blog.csdn.net/shichaog/article/details/44682931
### End