Ethernet使用参考


1. 概述

在计算机网络的七层模型(OSI 模型)和四层模型(TCP/IP 模型)中,并未明确指定物理层和数据链路层的具体实现技术。行业内有线网络常用 以太网技术,无线网络常用 无线局域网技术(Wi-Fi)

除上述主流技术外,其他可用于物理层和数据链路层的技术还包括:

  • 有线网络:串口(RS-232)、光纤(SDH)、USB 等
  • 无线网络:蓝牙、ZigBee、蜂窝网络(4G/5G)等

这些技术均能支撑 TCP/IP 协议的运行。

以太网技术和 Wi-Fi 技术均覆盖物理层和数据链路层,其核心硬件及功能如下:

物理层:核心硬件为 PHY 芯片(又称 PHY 控制器),主要负责信号转换、物理介质适配及链路协商

数据链路层 MAC 子层:核心硬件为 MAC 芯片(又称 MAC 控制器),主要负责帧的封装 / 解封装、介质访问控制、流量控制及差错处理

说明:部分芯片将 MAC 芯片与 PHY 芯片集成于同一颗芯片中(如多数 Wi-Fi 芯片);极少数芯片无硬件 MAC 控制器,需通过软件模拟实现其功能。

本章讲解以太网技术,它是一种定义了物理层和数据链路层标准的有线网络技术。SigmaStar 的 PCUPID 系列芯片在 SoC 内部集成了以太网数据链路层控制器(简称 EMAC 控制器),但未集成物理层 PHY 控制器,因此需外挂一颗以太网 PHY 芯片。

外挂 PHY 芯片与 SoC 的 MAC 控制器之间的通信需遵循相关标准接口,包括:

  • 百兆接口:MII/RMII

  • 千兆接口:GMII/RGMII

  • 万兆接口:XGMII

2. 关键字说明

  • EMAC :Ethernet Media Access Controller(以太网媒体访问控制器)简称为EMAC,主要负责数据链路层控制和管理,也负责利用MII/RMII/GMII接口直接对PHY芯片进行控制和管理

  • EPHY :Ethernet Physical Layer(以太网物理层控制器)简称为Ephy,又称以太网PHY芯片,以太网收发器

  • MII :MII(Media Independent Interface)即媒体独立接口,MII接口是MAC与PHY连接的标准接口,MII接口提供了MAC与PHY之间的互联支持。支持网络速率10Mbit/s和100Mbit/s

  • RMII : RMII(Reduced Media Independant Interface)即简化媒体独立接口,是标准的以太网接口之一,比MII有更少的I/O传输引脚。支持网络速率10Mbit/s和100Mbit/s

  • RX :接收器(Receiver)或接收(Reception)

  • TX :发送器(Transmitter)或传输(Transmission)

  • 网卡 :网卡是一个统一概念,通常指包含 MAC(介质访问控制)和 PHY(物理层)功能的硬件,集成了数据链路层和物理层的实现。但在不同场景中,“网卡” 的硬件形态存在差异:

    1. 台式 PC 的独立网卡:如 Realtek、Intel 等品牌的以太网网卡,通常是一个完整的 “MAC+PHY” 硬件模块,同时包含独立的 MAC 芯片和 PHY 芯片,以及它们之间的通信接口,因此被称为 “独立网卡”。
    2. 嵌入式 SoC 中的网卡:许多嵌入式 SoC 内部会集成 MAC 控制器,即 “MAC 功能” 由 SoC 内部模块实现,而 PHY 芯片通常为外置独立芯片,通过 MII/RMII 等接口与 SoC 内置的 MAC 连接。这种情况下,“网卡” 的硬件形态表现为 “SoC 内置 MAC + 外置 PHY 芯片 + 接口电路(如 RMII)” 的组合。此外,部分嵌入式 SoC 会采用更高集成度设计,将 PHY 功能也集成到 SoC 内部,形成 “SoC 内置 MAC + 内置 PHY” 的一体化方案。这种情况下,网卡的硬件形态可简化为“SoC 内置 MAC + 内置 PHY,以及它们之间的通信总线” ,无需额外外挂 PHY 芯片,能有效减少硬件设计复杂度和成本。

3. 功能描述

PCUPID 系列芯片的以太网框架如图,soc内部有两个EMAC控制器:EMAC0 + EMAC1。这两个emac控制器只支持RMII接口。

以太网框架

从硬件角度看:

  • EMAC0 : 仅支持RMII外挂Ephy (百兆phy芯片)

  • EMAC1 : 仅支持RMII外挂Ephy (百兆phy芯片)

从软件角度看:

  • uboot

     EMAC0 : RMII
     EMAC1 : RMII (默认关闭)
     注意 :UBOOT下只能同时启用一个EMAC
    
  • kernel

     EMAC0 : RMII
     EMAC1 : RMII (默认关闭)
     注意:kernel下可以同时启用两个EMAC
    

EMAC控制器支持以下功能

  • 网络流量控制

  • 网络风暴保护

  • 网络中断聚合

3.1 网络流量控制

PCUPID 系列芯片的emac控制器支持全双工模式下流量控制(flow control),流量控制通过"PAUSE帧"实现。它主要解决的是数据传输两端处理速度不一致导致的问题,当接收端无法及时处理数据时,会发送PAUSE_ON帧。发送端收到PAUSE_ON帧后立即暂停发送,直至收到PAUSE_OFF帧或者PAUSE时间到期且没有收到新的PAUSE_ON帧,发送端才恢复数据发送。流量控制可有效调控数据传输过程,避免数据丢失。

实例说明: 当 100M 网卡通过交换机向 10M 网卡发送数据帧时,由于 10M 网卡速率较低,可能因缓冲区溢出导致丢帧。10M 网卡在缓冲区即将溢出前主动发送 PAUSE 帧,请求发送设备暂停一段时间后再继续发送数据,从而避免丢帧。

注:PAUSE 帧是数据链路层实现流量控制的专用数据包,由链路自动处理,无需上层干预。

3.1.1 PAUSE 帧的格式

PAUSE 帧的格式如下图所示:

pause 帧格式

主要关注time-unit字段,time-unit 是暂停传送时间参数,单位是当前速率下传输512bit的时间,即slot time。

  • 如果是PAUSE_ON pkt, 则time_unit不为0,软件flow control 默认值为 0x2000, 硬件flow control 默认值为 0xffff

  • 如果是PAUSE_OFF pkt, 则time_unit为0, 当收到PAUSE_OFF pkt时,则说明流控已经关掉,可以正常tx pkt了,即具有唤醒功能

time-unit 常用值见下表

value 10M 暂停时间 100M 暂停时间
20 1ms 100us
200 10ms 1ms
2000 100ms 10ms
20000 1s 100ms
60000 3s 300ms
65535 3.27s 327ms

3.1.2 如何ON/OFF PAUSE

pause的开关有以下注意点

  • 通过 hal_emac.h 中的宏 HW_FLOW_CONTROL 来决定pause帧是由emac硬件发送还是由驱动软件发送

    1. HW_FLOW_CONTROL打开,默认由emac硬件发送pause帧,此时time-unit的值默认为0xffff。软件不参与 flow control处理
    2. HW_FLOW_CONTROL关闭,默认由驱动软件发送pause帧,此时time-unit的值默认为0x2000。emac硬件不参与flow control处理
    3. HW_FLOW_CONTROL默认关闭
  • 当HW_FLOW_CONTROL关闭时,可以通过ethtool控制驱动软件的ON/OFF PAUSE

    1. tx指的传输方向流控,表示eth0在传输流量时收到PAUSE帧,能否暂停传输

    2. rx指的接收方向流控,表示eth0能否在接收流量时向对端发送PAUSE帧

       命令"ethtool -a eth0"  # 显示当前的流控状态
      
       命令"ethtool -A eth0 rx on tx on"     # 打开tx rx 的流控
      
       命令"ethtool -A eth0 rx off tx off"   # 关闭tx rx 的流控
      

3.1.3 如何修改 PAUSE

  • 如果本机作为PAUSE帧接收方,PASUE帧的time-unit字段值是不可以修改的。

  • 如果本机作为PAUSE帧发送方,PAUSE帧time-unit的字段值可以修改,通过修改驱动代码来静态修改(不建议)。sdk没有对外提供修改的接口,暂不支持设备运行的过程中动态修改。

总的来说,不建议修改PAUSE帧的time-unit字段值

3.2 网络风暴保护

PCUPID 系列芯片的emac硬件支持网络风暴保护,可以限制 unicast (单播), multicast (多播) 和 broadcast (广播)的收发带宽。一般广播风暴(broadcast storm)比较常见,广播数据占用大量网络带宽导致正常业务不能运行,甚至彻底瘫痪,针对广播风暴场景,对broadcast流量进行限制就能解决问题。

3.2.1 风暴保护原理

风暴保护的核心原理是控制接收帧的速率,而非关注接收的比特(bit)速率。PCUPID 系列芯片通过 EMAC 硬件的令牌桶机制实现对接收帧速率的控制,具体参数及作用如下:

  • max : 影响令牌桶大小(桶深/桶容量/桶大小),桶大小 = max / consume,桶的大小影响突发流量的处理能力,max默认是 400000,不建议修改

  • consume : 决定令牌(token)的产生速率,token的产生速率即网络风暴保护的最大限制速率

token产生速率的计算公式为:token产生速率 = RX_CLK /consume

EMAC 控制器的接收时钟频率(RX_CLK)和网络速率相关

  • 工作在 100Mbit/s 网络时,RX_CLK = 25MHz

  • 工作在 10Mbit/s 网络时,RX_CLK = 2.5MHz

其中,consume表示每产生 1 个令牌所需的接收时钟周期数。

例如,默认consume值为 2500 时,表示每2500个接收时钟周期才会产生1个token,在 100Mbit/s 网络下的风暴限制速率为:

25MHz / 2500 = 10000 帧 / 秒(一万帧每秒)。

若默认值无法满足需求,可通过修改consume值调整风暴保护的最大限制速率,主要有两种方式可以修改consume的值,静态的方式和动态的方式

3.2.2 静态设置帧接收最大速率

静态设置帧接收的最大速率,是指通过 API 接口传入参数,在编译阶段就设置好帧接收的最大速率。当前API接口默认提供五个挡位,在 drv_emac.c 中的 Dev_EMAC_init 中三个对应函数设置。

level consume 百兆 RMII 的限制速率 帧/s
1 40000 625
2 20000 1250
3 10000 2500
4 5000 5000
5 2500 10000
Hal_EMAC_Netsp_Unicast_Setting(hemac->hal, TX_MAX_DEFAULT, TX_CONSUME_LEVEL_5, 1);  //限制 unicast   的收发带宽
Hal_EMAC_Netsp_Multicast_Setting(hemac->hal, TX_MAX_DEFAULT, TX_CONSUME_LEVEL_5, 1);//限制 multicast 的收发带宽
Hal_EMAC_Netsp_Broadcast_Setting(hemac->hal, TX_MAX_DEFAULT, TX_CONSUME_LEVEL_5, 1);//限制 broadcast 的收发带宽

3.2.3 动态设置帧接收的最大速率

动态设置帧接收的最大速率,是指设备开机运行过程中,通过写入寄存器值来配置帧接收的最大速率,且该速率可在设备运行期间进行动态修改。

下面提供一组默认的寄存器设定,客户可以根据方法自由调整。emac0的控制寄存器地址是1511,emac1的控制寄存器地址是1515。以emac0的风暴保护为例,max的值仍然用默认的400000,高16位是0x0006,低16位是0x1A80。consume的值仍然用默认的2500,十六进制0x09C4

  • unicast 单包保护

    /customer/riu_w 1511 50 1A80   //max 低16位
    /customer/riu_w 1511 51 0006   //max 高16位
    /customer/riu_w 1511 52 09C4   //counsume  低16位
    /customer/riu_w 1511 68 0001   //bit0  1-使能 0-失能
    
  • multicast 多包保护

    /customer/riu_w 1511 58 1A80
    /customer/riu_w 1511 59 0006
    /customer/riu_w 1511 5A 09C4
    /customer/riu_w 1511 68 0002   //bit1  1-使能 0-失能
    
  • broadcast 广播包保护

    /customer/riu_w 1511 60 1A80
    /customer/riu_w 1511 61 0006
    /customer/riu_w 1511 62 09C4
    /customer/riu_w 1511 68 0004   //bit2  1-使能 0-失能
    

3.3 网络接收中断聚合

EMAC RX 硬件在收到帧后,会触发中断以唤醒 RX 线程进行收包。当网络流量较大时,会产生大量中断,这会消耗大量 CPU 性能,导致 CPU 负载上升。EMAC 硬件提供接收中断聚合功能(有时也称为 RX DELAY),其作用机制为:允许 EMAC 在收到帧后不立即触发中断,而是在满足以下任一条件时才触发:

  • 收到的帧数达到设定数量(delay_num)

  • 未达到设定帧数,但已超过指定时间(cyc_num)

通过这种机制,可减少接收中断产生的次数,从而节省 CPU 资源。

此外,RX Delay 内部还具备动态调节功能:

  • 网络空闲时,delay_num和cyc_num会自动设为较小值

  • 网络繁忙时,delay_num和cyc_num会自动设为较大值

该动态调节功能可通过调整dts中的rx-delay-int属性进行开关控制

  • rx-delay-int设置为1,接收中断聚合功能打开,默认打开

  • rx-delay-int设置为0,接收中断聚合功能关闭

3.4 ipv6

kernel提供了ipv6功能,如果需要使用IPV6功能,需要开启对应的CONFIG, (默认开启)

  • kernel 中打开 ipv6 支持
    -> Networking support (NET [=y])
        -> Networking options
            -> TCP/IP networking (INET [=y])
                <*>   The IPv6 protocol
    

4. 硬件连接介绍

4.1 soc硬件接口确认

这里以Comake_Pi_D1板子为例,通过查看其soc的数据手册,确认emac只支持RMII接口。RMII接口的引脚分布通过查看soc的hw checklist表来确认。

下面几张图是Comake_Pi_D1板载soc芯片的hw_checklist表的子表“ARMTmux”。对reg_eth_mode寄存器写不同的值,连接emac0的RMII引脚也将会不同,emac1的RMII引脚分布同理。dts里用xxx_padmux.dtsi来指定不同的reg_eth_mode寄存器的值。

emac0的RMII引脚分布

4.2 PHY芯片硬件接口确认

Comake_Pi_D1板子的外挂PHY芯片型号是IP101GR,查看其数据手册,RMII接口接线如下图。

phy芯片的RMII引脚接线

4.3 原理图连接

Comake_Pi_D1板子有两个单网口, soc芯片的emac0和外挂phy芯片之间的RMII接线如下图,emac0用的是reg_eth_mode=3,引脚是GPIOE20 ~ GPIOE27

emac0-rmii-phy接线

emac1和外挂phy芯片之间的RMII接线如下图,emac1用的是reg_eth_mode=2,引脚是GPIOB0 ~ GPIOB8。需要注意的是,三排直插排针JP185默认B排和C排是不接的,默认接A排和B排供sensor接口用。也就是此RMII接线没有接上,默认的emac1网口不能使用。如果你想使用emac1对应的网口,需要用跳线帽将B排和C排的排针连接起来,并且修改dts配置。

emac1-rmii-phy接线

注意:需要去除残断,否则可能影响功能正常使用

注意:emac-id,硬件原理图上的eth-id和ifconfig看到的eth-id,三个id的意义并不一样。

  • emac-id指定的是soc芯片里的emac控制器的序号。

  • 硬件原理图上的eth-id,是画原理图时自定义的名称,只是个称号,没有特殊含义。

  • ifconfig看到的eth-id指定了eth设备注册的先后顺序

    1. 如果注册顺序是emac0,emac1,那么ifconfig看到的eth0对应emac0,eth1对应emac1

    2. 如果注册顺序是emac1,emac0,那么ifconfig看到的eth0对应emac1,eth1对应emac0

    3. 如果只有emac1注册,那么ifconfig看到的eth0对应emac1,没有eth1

Comake_Pi_D1 开发板网口使用说明

  • emac0 对应网口:硬件默认可用,且设备树(dts)已完成默认配置。若需使用,仅需确认以下内核配置项(kernel config)是否开启,见后面的章节

  • emac1 对应网口:若需使用,需完成两项操作:

    1. 硬件跳线

    2. 设备树(dts)配置修改

5. Uboot用法介绍

5.1 uboot config 配置

uboot下不能两个emac同时使用,emac0默认打开,emac1默认关闭

  • 默认启用 EMAC0 driver

    [*] SigmaStar drivers  --->
        SigmaStar EMAC --->
            [*] SigmaStar EMAC
            [*]   EMAC supply to RMII
            [ ]     EMAC supply to IC+ Phy
            [ ]   EMAC fix link to mii/rmii
            [*]   EMAC phy reset reverse
            [*]   EMAC 0
            [ ]     EMAC0 PHY RESET
            [ ]   EMAC 1
    
    EMAC0如果要启用EMAC0 PHY RESET,参数如下
    
    [*] SigmaStar drivers  --->
        SigmaStar EMAC --->
            [*] SigmaStar EMAC
            [*]   EMAC supply to RMII
            [ ]     EMAC supply to IC+ Phy
            [ ]   EMAC fix link to mii/rmii
            [*]   EMAC phy reset reverse
            [*]   EMAC 0
            [*]     EMAC0 PHY RESET
            (17)      EMAC 0 FOR PHY RESET PAD
            (20)      EMAC 0 FOR PHY RESET HOLD MS
            (50)      EMAC 0 FOR PHY WAIT READY MS
            [ ]   EMAC 1
    
  • 如需启用 EMAC1 driver,需要关掉EMAC0 driver

    [*] SigmaStar drivers  --->
        SigmaStar EMAC --->
            [*] SigmaStar EMAC
            [*]   EMAC supply to RMII
            [ ]     EMAC supply to IC+ Phy
            [ ]   EMAC fix link to mii/rmii
            [*]   EMAC phy reset reverse
            [ ]   EMAC 0
            [*]   EMAC 1
            [ ]     EMAC1 PHY RESET
    
    EMAC1如果要启用EMAC1 PHY RESET,参数如下
    
    [*] SigmaStar drivers  --->
        SigmaStar EMAC --->
            [*] SigmaStar EMAC
            [*]   EMAC supply to RMII
            [ ]     EMAC supply to IC+ Phy
            [ ]   EMAC fix link to mii/rmii
            [*]   EMAC phy reset reverse
            [ ]   EMAC 0
            [*]   EMAC 1
            [*]     EMAC1 PHY RESET
            (121)     EMAC 1 FOR PHY RESET PAD
            (20)      EMAC 1 FOR PHY RESET HOLD MS
            (50)      EMAC 1 FOR PHY WAIT READY MS
    
    CONFIG 说明 默认值
    [*] SigmaStar EMAC 使能EMAC 使能
    [*] EMAC supply to RMII 使能RMII模式 使能
    [ ] EMAC supply to IC+ Phy 支持 ICPULS PHY 不使能
    [ ] EMAC fix link to mii/rmii 使能 fix link 不使能
    [*] EMAC phy reset reverse phy reset时反向拉高拉低 使能
    [*] EMAC 0 使能EMAC0 使能
    [*] EMAC0 PHY RESET 使能 EMAC0 软件 phy reset 不使能
    (17) EMAC 0 FOR PHY RESET PAD EMAC0 的 phy reset padmux值 17
    (20) EMAC 0 FOR PHY RESET HOLD MS EMAC0 设置低电平的保持时间 20ms
    (50) EMAC 0 FOR PHY WAIT READY MS EMAC0 设置高电平的等待就绪时间 50ms
    [*] EMAC 1 使能EMAC1 此时uboot改为使用EMAC1 网卡 不使能
    [*] EMAC1 PHY RESET 使能EMAC1软件 phy reset 不使能
    (121) EMAC 1 FOR PHY RESET PAD EMAC1 的 phy reset padmux值 121
    (20) EMAC 1 FOR PHY RESET HOLD MS EMAC1 设置低电平的保持时间 20ms
    (50) EMAC 1 FOR PHY WAIT READY MS EMAC1 设置高电平的等待就绪时间 50ms
  • Network commands

    Command line interface --->
        Network commands --->
            [*]   bootp
            [*]     dhcp
            [*]   tftpboot
            [*]   ping
    

5.2 环境变量

uboot 下网络主要使用到ping dhcp tftp 命令,在使用这些命令之前需要配置网络使用的环境变量。

5.2.1 开机网卡自动初始化

通过环境变量autoestart配置网卡的开机自动初始化功能。

  • 若autoestart=0:

    开机时不会自动初始化网卡。如果要在uboot下使用网络,需手动执行estart命令进行网卡初始化,否则会提示No ethernet found

    示例命令:

    estart //手动初始化网卡

  • 若autoestart=1:

    开机时会自动完成网卡初始化

    配置命令:

    setenv -f autoestart 1 //设置开机自动初始化网卡

注意:由于网卡初始化过程中会等待网卡自协商完成,可能导致启机速度变慢,因此需根据实际需求决定是否启用该配置。

5.2.2 设置静态IP

setenv -f ethact sstar_emac          //配置网卡驱动为emac
setenv -f ethaddr xx:xx:xx:xx:xx:xx  //配置 mac 地址
setenv -f ipaddr xxx.xxx.xxx.xxx     //配置静态 ip 地址
setenv -f netmask xxx.xxx.xxx.xxx    //配置 ip 地址掩码
setenv -f serverip xxx.xxx.xxx.xxx   //配置tftp server ip
save                                 //保存配置

5.3 常用命令

5.3.1 设置静态ip + ping示例

图5-1 uboot_ping_cmd

5.3.2 动态获取ip示例(dhcp)

setenv -f ethact sstar_emac          //配置网卡驱动为emac
setenv -f ethaddr xx:xx:xx:xx:xx:xx  //配置 mac 地址
setenv -f serverip xxx.xxx.xxx.xxx   //配置tftp server ip
save                                 //保存配置
dhcp                                 //dhcp动态获取ip

图5-2 uboot_dhcp_cmd

5.3.3 tftp示例

 tftp 0x20000000 kernel  //将服务器里名为kernel的文件通过tftp拷贝保存到首地址=0x20000000的内存中

图5-3 uboot_tftp_cmd

6. Kernel用法介绍

6.1 kernel config 配置

  • 启用 EMAC driver

    Device Drivers --->
        SStar Soc platform drivers --->
            [*]SSTAR_EMAC
    
  • 启用 nfs cifs

    File systems --->
        Network File Systems --->
            <M> NFS client support
            <M>     NFS client support for NFS version 2
            <M>     NFS client support for NFS version 3
            <M> SMB3 and CIFS support
    

6.2 dts配置

6.2.1 使用emac0的网口

dts节点配置

默认状态是打开的status = "okay"

    emac0: emac0 {
        compatible = "sstar-emac";
        interrupts = <GIC_SPI INT_IRQ_EMAC IRQ_TYPE_LEVEL_HIGH>;
        clocks = <&CLK_emac_ahb>;
        reg = <0x0 0x1F2A2000 0x0 0x800>, <0x0 0x1F304200 0x0 0x600>, <0x0 0x00000000 0x0 0x000>;
        pad-rmii = <0x1F2079B8 0x0003 0x0003>; // pad-rmii selection from 0x0003
        bus-mode = <2>; //1:MII 2:RMII
        phy-handle = <&phy0>;
        max-speed = <100>;
        status = "okay";
        emac-id = <0>;
        reset_reverse;
        cpu-affinity = <0>; //0:single cpu 1:multi cpu
        rx-delay-int = <1>;//0:disable 1:enable
        mdio-bus@emac0 {
            phy0: ethernet-phy@0 {
                phy-mode = "rmii";
                //phy-mode = "mii";
            };
        };
    };

padmux配置

默认状态是打开的#if 1

    #if 1
    //eth0 rmii
    <PAD_GPIOE_08            PINMUX_FOR_GPIO_MODE             MDRV_PUSE_ETH0_PHY_RESET>,
    <PAD_GPIOE_20            PINMUX_FOR_ETH_MODE_3            MDRV_PUSE_ETH0_COL>,
    <PAD_GPIOE_21            PINMUX_FOR_ETH_MODE_3            MDRV_PUSE_ETH0_RXD0>,
    <PAD_GPIOE_22            PINMUX_FOR_ETH_MODE_3            MDRV_PUSE_ETH0_RXD1>,
    <PAD_GPIOE_23            PINMUX_FOR_ETH_MODE_3            MDRV_PUSE_ETH0_TX_CLK>,
    <PAD_GPIOE_24            PINMUX_FOR_ETH_MODE_3            MDRV_PUSE_ETH0_TXD0>,
    <PAD_GPIOE_25            PINMUX_FOR_ETH_MODE_3            MDRV_PUSE_ETH0_TXD1>,
    <PAD_GPIOE_26            PINMUX_FOR_ETH_MODE_3            MDRV_PUSE_ETH0_TX_CTL>,
    <PAD_GPIOE_27            PINMUX_FOR_ETH_MODE_3            MDRV_PUSE_ETH0_MDIO>,
    <PAD_GPIOE_28            PINMUX_FOR_ETH_MODE_3            MDRV_PUSE_ETH0_MDC>,
    #endif

6.2.2 使用emac1的网口

dts节点配置

默认状态是关闭的status = "disable",要改成status = "okay"

    emac1: emac1 {
        compatible = "sstar-emac";
        interrupts = <GIC_SPI INT_IRQ_EMAC_1 IRQ_TYPE_LEVEL_HIGH>;
        clocks = <&CLK_emac1_ahb>;
        reg = <0x0 0x1F2A2C00 0x0 0x800>, <0x0 0x1F304A00 0x0 0x600>, <0x0 0x00000000 0x0 0x000>;
        pad-rmii = <0x1F2079B8 0x0020 0x0020>; // pad-rmii selection from 0x0020
        bus-mode = <2>;//1:MII 2:RMII
        phy-handle = <&phy1>;
        max-speed = <100>;
        status = "disabled";
        emac-id = <1>;
        reset_reverse;
        cpu-affinity = <0>; //0:single cpu 1:multi cpu
        rx-delay-int = <1>;//0:disable 1:enable
        mdio-bus@emac1 {
            phy1: ethernet-phy@1 {
                phy-mode = "rmii";
                //phy-mode = "mii";
            };
        };
    };

padmux配置

默认状态是#if 0,需要改成#if 1

    #if 0
    //eth1 rmii
    <PAD_PM_PWM1_OUT         PINMUX_FOR_GPIO_MODE             MDRV_PUSE_ETH1_PHY_RESET>,
    <PAD_GPIOB_00            PINMUX_FOR_ETH1_MODE_2           MDRV_PUSE_ETH1_COL>,
    <PAD_GPIOB_01            PINMUX_FOR_ETH1_MODE_2           MDRV_PUSE_ETH1_RXD0>,
    <PAD_GPIOB_02            PINMUX_FOR_ETH1_MODE_2           MDRV_PUSE_ETH1_RXD1>,
    <PAD_GPIOB_03            PINMUX_FOR_ETH1_MODE_2           MDRV_PUSE_ETH1_TX_CLK>,
    <PAD_GPIOB_04            PINMUX_FOR_ETH1_MODE_2           MDRV_PUSE_ETH1_TXD0>,
    <PAD_GPIOB_05            PINMUX_FOR_ETH1_MODE_2           MDRV_PUSE_ETH1_TXD1>,
    <PAD_GPIOB_06            PINMUX_FOR_ETH1_MODE_2           MDRV_PUSE_ETH1_TX_CTL>,
    <PAD_GPIOB_07            PINMUX_FOR_ETH1_MODE_2           MDRV_PUSE_ETH1_MDIO>,
    <PAD_GPIOB_08            PINMUX_FOR_ETH1_MODE_2           MDRV_PUSE_ETH1_MDC>,
    #else
    //sensor 0/1 i2c
    <PAD_GPIOB_00            PINMUX_FOR_I2C0_MODE_4           MDRV_PUSE_I2C0_SCL>,
    <PAD_GPIOB_01            PINMUX_FOR_I2C0_MODE_4           MDRV_PUSE_I2C0_SDA>,
    <PAD_GPIOB_04            PINMUX_FOR_I2C1_MODE_4           MDRV_PUSE_I2C1_SCL>,
    <PAD_GPIOB_05            PINMUX_FOR_I2C1_MODE_4           MDRV_PUSE_I2C1_SDA>,
    #endif

6.2.3 dts配置项讲解

第4.1小节中提到了,reg_eth_mode/reg_eth1_mode的值决定了哪些引脚用于emac0/1。emac的mode配置和《sensor使用参考》里mipi mode配置不同,它不需要显式的用"snr_sr0_mipi_mode = <5>"来配置,而只需要配置好emac的padmux就行了,因为emac的驱动代码里会根据padmux配置自行计算出mode值,然后写进相应的寄存器里。由此可以看出,对于不同bsp mode的配置,并没有统一的方法,具体见每个bsp章节说明。

节点如上图展示,释义分别为:

参数 释义 备注
compatible 属性信息 驱动代码会匹配这个固定的字符串"sstar-emac",不能改
interrupts 中断脚 中断的触发引脚驱动获取
clocks EMAC时钟 驱动获取时钟节点,不能改
reg 寄存器映射的物理地址 第一个为emac 寄存器base, 第二个为x32寄存器base, 第三个为内部phy寄存器base,不能改
pad-rmii padmux 当CONFIG_PADMUX未启用时,此处生效。
bus-mode 决定了和外接phy芯片的接口类型。先看phy芯片支持什么接口,最终根据硬件原理图来选择mode 1:MII接口 2:RMII接口
phy-handle phy节点
max-speed 限制自协商下的最大速率,两个档位,只能选一个 <10> - 最大10Mbit/s, <100> - 最大100Mbit/s
status 驱动开关 "ok" - 打开当前emac,"disabled" - 关闭当前emac
emac-id 当前使用的emac id,不等同ifconfig看到的eth id <0>/<1>
reset_reverse reset外接反向电路时使用,配置后reset会 先拉高再拉低 配置生效,去掉则不生效
cpu-affinity cpu亲和性,开启后允许中断在多个CPU上处理 0:single cpu 1:multi cpu 一般默认设置0
phy-mode phy 接口选择 "mii"/"rmii"
rx-delay-int 网络接收中断聚合开关 0:disable , 1:enable

6.3 常用命令

  • 查看所有网卡信息

    ifconfig -a
    
  • eth0网卡使能

    ifconfig eth0 up
    
  • 配置网卡eth0的mac地址为 00:00:83:94:40:01

    ifconfig eth0 hw ether 00:00:83:94:40:01
    
  • 配置网卡eth0的静态ip地址为 40.1.1.1/24

    ifconfig eth0 40.1.1.1 netmask 255.255.255.0
    
  • 网卡eth0 dhcp获取ip

    udhcpc -i eth0 -s /etc/init.d/udhcpc.script
    
  • 挂载nfs目录

    mount -t nfs -o nolock xxx.xxx.xxx.xxx:/c/nfs /mnt  # "xxx.xxx.xxx.xxx:/c/nfs /mnt" 释义 "服务器ip地址:/c盘/nfs目录 设备的/mnt目录"
    
  • 挂载cifs目录

    mount -t cifs //xxx.xxx.xxx.xxx/cifs /mnt -o username=xxx,password=xxx,sec=ntlm,iocharset=utf8,vers=1.0  # "//xxx.xxx.xxx.xxx/cifs /mnt" 释义 "//服务器ip地址:/cifs(共享目录) 设备的/mnt目录"
    
  • tftp get

    tftp -g xxx.xxx.xxx.xxx -r file_name  # "xxx.xxx.xxx.xxx -r file_name" 释义 "服务器ip地址 -r 从服务器获取的目标文件名"
    
  • tftp put

    tftp -p xxx.xxx.xxx.xxx -l file_name  # "xxx.xxx.xxx.xxx -r file_name" 释义 "服务器ip地址 -r 向服务器发送的目标文件名"
    
  • 配置eth0 获取动态IP并挂载nfs

    图6-4 kernel_nfs_cmd

6.4 常用第三方工具

6.4.1 iperf3

  • iperf3 服务端模式

    ./iperf3 -s -i 1
    
    选项 说明
    -s 服务端模式
    -i 1 打印回显间隔(单位: 秒),这里是 1秒
  • iperf3 客户端模式

    ./iperf3 -c xxx.xxx.xxx.xxx -i 1 -t 36000 -b 95M
    
    选项 说明
    -c 客户端模式
    xxx.xxx.xxx.xxx 对端的ip地址
    -i 1 打印回显间隔,单位 秒,这里是 1秒
    -t 36000 打流时间,单位 秒,最高 86400 (24小时)
    -b 95M 打流速率 95Mbits/sec

6.4.2 tcpdump

tcpdump是一个linux下的抓包工具。

./tcpdump -s 0 -i eth0 -w /tmp/pkt.cap //捕获eth0 网卡的报文并缓存到 pkt.cap
选项 说明
-s 0 指定抓包大小,0表示不限制
-i eth0 表示连接的接口,any表示所有接口
-w /tmp/pkt.cap 表示抓的包写到指定path中。文件为.pcap

6.4.3 ethtool

  • 查看 eth0 网卡信息

    ethtool eth0
    
  • 切换 eth0 的网卡速率和双工模式

    ethtool -s eth0 speed 100 duplex full
    
  • 开启/关闭 eth0 自协商

    ethtool -s eth0 autoneg on/off
    
  • 开启流控 Flow Control

    ethtool -A eth0 rx on tx on
    
  • 查看 eth0 收包 statistics

    ethtool -S eth0
    

6.4.4 phytool

  • 读取phy reg的值

    read IFACE/ADDR/REG
    
    选项 说明
    IFACE eth0 or eth1
    ADDR mdio bus 上的位置
    REG 读取的phy reg

    eg: 读取 eth0 addr0 reg2

    phytool read eth0/0/2
    
  • 往phy reg 写入值

    write IFACE/ADDR/REG <0-0xffff>
    
    参数 说明
    IFACE eth0 or eth1
    ADDR mdio bus 上的位置
    REG 写入的phy reg
    <0-0xffff> 要写入的值

    eg: 写入 eth0 的 loopback bit

    phytool write eth0/0/0 4000
    

6.5 常用DEBUG节点使用方法

6.5.1 dlist emac驱动统计信息节点

通过cat dlist查看emac驱动中断/收包统计等信息。

/ # cat /sys/devices/virtual/sstar/emac0/dlist_info
RBQP_size=0x100
empty=0x100, hemac->rxBuffIndex=0x7f, u32RBQP_Addr=0x20a07f
0x000: 1111111111111111 1111111111111111
0x020: 1111111111111111 1111111111111111
0x040: 1111111111111111 1111111111111111
0x060: 1111111111111111 1111111111111111
0x080: 1111111111111111 1111111111111111
0x0a0: 1111111111111111 1111111111111111
0x0c0: 1111111111111111 1111111111111111
0x0e0: 1111111111111111 1111111111111111
max_rx_packet_count=4
max_tx_packet_count=1
IDX_CNT_INT_DONE=0
IDX_CNT_INT_RCOM=0
IDX_CNT_INT_RBNA=0
IDX_CNT_INT_TOVR=0
IDX_CNT_INT_TUND=0
IDX_CNT_INT_RTRY=0
IDX_CNT_INT_TCOM=0
IDX_CNT_INT_ROVR=0
IDX_CNT_JULIAN_D=67901
IDX_CNT_INT_TDLY=0
IDX_CNT_INT_TDTO=0
skb_tx_send=698
skb_tx_free=698
rx_duration_max=374
rx_packet_cnt=67967
tx_delay_pack_cnt=0
data_done=42
data_duration=41152
data_average=0
tx_pkt (duration)=1
tx_int (duration)=0
tx_int_dly (duration)=0
tx_int_to (duration)=0
rx_int_dly (duration)=976
rx_pkt (duration)=977
Hal_EMAC_TXQ_Mode=0
maxSG=2

6.5.2 phyStatusWR phy读写 debug节点

  • Usage

    / # cat /sys/devices/virtual/sstar/emac0/phyStatusWR
    phy read & write:
        Usage:
    echo phy_r phyAddress > phyStatusWR
    echo phy_w phyAddress phyValue> phyStatusWR
    echo phyE_r phyId phyAddress > phyStatusWR
    echo phyE_w phyId phyAddress phyValues > phyStatusW
    
  • eg

    /sys/devices/virtual/sstar/emac0 # echo phy_r 0 > phyStatusWR
    phy_r address[0] value[3100]
    /sys/devices/virtual/sstar/emac0 # echo phy_w 0 1200 > phyStatusWR
    phy_w address[0] value[1000]
    /sys/devices/virtual/sstar/emac0 # echo phyE_r 1 0 > phyStatusWR
    phyE_r id[1] address[0] value[3100]
    /sys/devices/virtual/sstar/emac0 # echo phyE_w 1 0 0x1200 > phyStatusWR
    phyE_w id[1] address[0] value[1000]
    

6.5.3 turndrv 驱动调试节点

  • Usage

    /sys/devices/virtual/sstar/emac0 # cat turndrv
    Usage:
            echo f10t    > turndrv => set max_speed to 10M
            echo an      > turndrv => set link mode to autonegotiatingn
            echo dir_on  > turndrv => enable  Dynamic Rx Interrupt
            echo dir_off > turndrv => disable Dynamic Rx Interrupt
            echo swing_100 [gear]  > turndrv => swing 100M tx gear
            echo swing_10  [gear]  > turndrv => swing 10M tx gear
            echo rx_imp    [level] > turndrv => adjust rx impedance, range:-4 ~ 7
            echo timing    [is_rise] [delay_time] [duty_cycle] [phase] > turndrv
    
  • f10t 限制最大速率为 10Mbits/sec

     需要进行一次自协商才能切换成10M
    
     / # echo f10t > /sys/devices/virtual/sstar/emac0/turndrv
     SPEED_10
     / # echo an > /sys/devices/virtual/sstar/emac0/turndrv
     phy_start_aneg
    
  • an 进行自协商

     / # echo an > /sys/devices/virtual/sstar/emac0/turndrv
     phy_start_aneg
    
  • dir_on 开启RX DELAY动态调整阈值

     / # echo dir_on > /sys/devices/virtual/sstar/emac0/turndrv
     rx_stats_enable: 1
    
  • dir_off 关闭RX DELAY动态调整阈值

     / # echo dir_off > /sys/devices/virtual/sstar/emac0/turndrv
     rx_stats_enable: 0
    

7. API参考

EMAC无对外API

8. FAQ

Q1:启机日志出现"xxx could not connect to PHY",并且网络无法通信

  1. 检查padmux.dtsi中RMII的引脚配置是否打开,并且确认引脚配置是否有冲突。

  2. 确认使用的phy的reset时序。若存在反向电路,则需要在dts emac节点中添加"reset_reverse"属性,反之则需要去掉"reset_reverse"属性。同时需确认保持电平的时间是否符合phy要求

    图8-1 reset_reverse dts

  3. 若使用的phy非sstar提供,则需要找对应phy厂商确认是否需要专用的phy驱动支持

  4. 检查硬件接线是否正确,有无接错、虚焊、短接等等情况

Q2:设备出现丢包多,网络速率上不去现象

  1. 需检查设备和对端的link mode是否一致,可通过"./ethtool eth0"命令查看当前的phy link mode

  2. 需检查网线物理连接是否松动,以及网线本身质量是否合格

  3. 检查网络环境是否正常,如是否开启了防火墙,是否中转设备(路由器, 交换机)有做了影响带宽的qos策略等等。可以改为直连环境验证排查(如DUT直连PC)。

  4. 检查设备的cpu负载是否过大,使得设备无法及时处理网络报文导致丢包。

  5. 检查信号质量,可以通过配置对应的phy寄存器,调整phy端驱动能力。

Q3:在不使用网络的情况下,保留EMAC模块是否会有额外功耗?

不会有额外功耗。只要网口处于down状态,就不会开启EMAC clk,可通过"ifconfig"命令查看当前是否有开启的网口