Linux 网络
作者:互联网
Linux 网络
-
嵌入式下的网络硬件接口
- 嵌入式网络硬件分为两部分:MAC 和 PHY,通过看数据手册来判断一款 SOC 是否支持网络,如果一款芯片数据手册说自己支持网络,一般都是说的这款 SOC 内置 MAC,MAC 类似 I2C 控制器、SPI 控制器一样的外设。
- 但是光有 MAC还不能直接驱动网络,还需要另外一个芯片:PHY,因此对于内置 MAC 的 SOC,其外部必须搭配一个 PHY 芯片。
-
1、SOC 内部没有网络 MAC 外设
-
既然没有内部 MAC,那么可以找个外置的 MAC 芯片啊,不过一般这种外置的网络芯片都是 MAC+PHY 一体的。DM9000 对 SOC 提供了一个 SRAM 接口,SOC 会以 SRAM 的方式操作 DM9000。
-
有些外置的网络芯片更强大,内部甚至集成了硬件 TCP/IP 协议栈,对外提供一个 SPI 接口,比如 W5500。
-
这种方案的优点就是让不支持网络的 SOC 能够另辟蹊径,实现网络功能,但是缺点就是网络效率不高,因为一般芯片内置的 MAC 会有网络加速引擎,比如网络专用 DMA,网络处理效率会很高。
-
而且此类芯片网速都不快,基本就是 10/100M。另外,相比 PHY 芯片而言,此类芯片的成本也比较高,可选择比较少。
-
-
2、SOC 内部集成网络 MAC 外设
- 一般常见的通用 SOC 都会集成网络 MAC 外设,内部集成网络 MAC 的优点如下:
- ①、内部 MAC 外设会有专用的加速模块,比如专用的 DMA,加速网速数据的处理。
- ②、网速快,可以支持 10/100/1000M 网速。
- ③、外接 PHY 可选择性多,成本低。
- 内部的 MAC 外设会通过 MII 或者 RMII 接口来连接外部的 PHY 芯片,MII/RMII 接口用来传输网络数据。
- 另外主控需要配置或读取 PHY 芯片,也就是读写 PHY 的内部寄存器,所以还需要一个控制接口,叫做 MIDO,MDIO 很类似 IIC,也是两根线,一根数据线叫做 MDIO,一根时钟线叫做 MDC。
- 一般常见的通用 SOC 都会集成网络 MAC 外设,内部集成网络 MAC 的优点如下:
-
1、MII 接口
- MII 全称是 Media Independent Interface,直译过来就是介质独立接口,它是 IEEE-802.3 定义的以太网标准接口,MII 接口用于以太网 MAC 连接 PHY 芯片
- MII 接口的缺点就是所需信号线太多,这还没有算 MDIO 和 MDC 这两根管理接口的数据线,因此 MII 接口使用已经越来越少了。
-
2、RMII 接口
- RMII 全称是 Reduced Media Independent Interface,翻译过来就是精简的介质独立接口,也就是 MII 接口的精简版本。RMII 接口只需要 7 根数据线,相比 MII 直接减少了 9 根,极大的方便了板子布线
- 除了 MII 和 RMII 以外,还有其他接口,比如 GMII、RGMII、SMII、SMII 等,关于其他接口基本都是大同小异的
-
MDIO 接口
- MDIO 全称是 Management Data Input/Output,直译过来就是管理数据输入输出接口,是一个简单的两线串行接口,一根 MDIO 数据线,一根 MDC 时钟线。
- 驱动程序可以通过 MDIO 和MDC 这两根线访问 PHY 芯片的任意一个寄存器。MDIO 接口支持多达 32 个 PHY。
- 同一时刻内只能对一个 PHY 进行操作,那么如何区分这 32 个 PHY 芯片呢?和 IIC 一样,使用器件地址即可。
- 同一 MDIO 接口下的所有 PHY 芯片,其器件地址不能冲突,必须保证唯一,具体器件地址值要查阅相应的 PHY 数据手册。
- 因此,MAC 和外部 PHY 芯片进行连接的时候主要是 MII/RMII 和 MDIO 接口,另外可能还需要复位、中断等其他引脚。
-
RJ45 接口
- 网络设备是通过网线连接起来的,插入网线的叫做 RJ45 座
- RJ45 座要与 PHY 芯片连接在一起,但是中间需要一个网络变压器,网络编译器用于隔离以及滤波等,网络变压器也是一个芯片,
- 但是现在很多 RJ45 座子内部已经集成了网络变压器, HR911105A 就是内置网络变压器的 RJ45 座
- 内置网络变压器的 RJ45 座和不内置的引脚一样,但是一般不内置的 RJ45 座会短一点。
- RJ45 座子上一般有两个灯,一个黄色(橙色),一个绿色,绿色亮的话表示网络连接正常,黄色闪烁的话说明当前正在进行网络通信。
- 这两个灯由 PHY 芯片控制,PHY 芯片会有两个引脚来连接 RJ45 座上的这两个灯。
-
I.MX6ULL ENET 接口简介
-
I.MX6ULL 有两个网络接口,也就是两个 MAC 外设,一个 MAC 连接一个 PHY 芯片形成一个完整网络接口
-
I.MX6ULL 内部自带的 ENET 外设其实就是一个网络 MAC,支持 10/100M。
-
实现了三层网络加速,用于加速那些通用的网络协议,比如 IP、TCP、UDP 和 ICMP 等,为客户端应用程序提供加速服务。
-
I.MX6ULL 内核集成了两个 10/100Mbit/S 的网络 MAC,符合 IEEE802.3-2002 标准,MAC层支持双工、半双工局域网。
-
MAC 可编程、可以作为 NIC 卡或其他一些交换器件。
-
根据 IETF RFC 2819 协议,MAC 实现了 RMON(Remote Network Monitoring)计数功能。
-
MAC 内核拥有硬件加速处理单元来提高网络性能,硬件加速单元用于处理 TCP/IP、UDP、ICMP 等协议
-
通过硬件来处理帧头等信息,效果要比用一大堆软件处理要好很多
-
ENET 外设有一个专用的 DMA,此 DMA 用于在 ENET 外设和 SOC 之间传输数据,并且支持可编程的增强型的缓冲描述符,用以支持 IEEE 1588。
-
I.MX6ULL 内部 ENET 外设主要特性如下:
- 1)、实现了全功能的 802.3 规范前导码/SFD 生成、帧填充、CRC 生成和检查。
- 2)、支持零长的前导码。
- 3)、支持 10/100M 动态配置。
- 4)、兼容 AMD 远端节点电源管理的魔术帧中断检测。
- 5)、可以通过如下接口无缝的连接 PHY 芯片:
·4bit 的 MII 接口,频率为 2.5/25MHz。
·4bit 的 MII-Lite 接口,也就是 MII 接口取消掉 CRS 和 COL 这两根线,频率也是2.5/25MHz。
·2bit 的 RMII 接口,频率为 50MHz。 - 6)、MAC 地址可编程。
- 7)、多播和单播地址过滤,降低更高层的处理负担。
- 8)、MDIO 主接口,用于管理和配置 PHY 设备。
-
-
PHY 基础知识简介
- PHY 是 IEEE 802.3 规定的一个标准模块,SOC 可以对 PHY 进行配置或者读取PHY 相关状态,这个就需要 PHY 内部寄存器去实现了。
- PHY 芯片寄存器地址空间为 5 位,地址 0~31 共 32 个寄存器,IEEE 定义了 0~15 这 16 个寄存器的功能,16~31 这 16 个寄存器由厂商自行实现。
- 也就是说不管你用的哪个厂家的 PHY 芯片,其中 0~15 这 16 个寄存器是一模一样的。
- 随着现在的 PHY 芯片性能越来越强大,32 个寄存器可能满足不了厂商的需求,因此很多厂商采用分页技术来扩展寄存器地址空间,以求定义更多的寄存器。
- 这些多出来的寄存器可以用于实现厂商特有的一些技术,因此 Linux 内核的通用 PHY 驱动就无法驱动这些特色功能了,这个时候就需要 PHY 厂商提供相应的驱动源码了,所以大家也会在 Linux 内核里面看到很多具体的 PHY 芯片驱动源码。
-
LAN8720A 简介
- LAN8720A 是低功耗的 10/100M 单以太网 PHY 层芯片,可应用于机顶盒、网络打印机、嵌入式通信设备、IP 电话等领域。
- I/O 引脚电压符合 IEEE802.3-2005 标准。
- LAN8720A 支持通过 RMII 接口与以太网 MAC 层通信,内置 10-BASE-T/100BASE-TX 全双工传输模块,支持10Mbps 和 100Mbps。
- LAN8720A 可以通过自协商的方式选择与目的主机最佳的连接方式(速度和双工模式)。
- 支持 HP Auto-MDIX 自动翻转功能,无需更换网线即可将连接更改为直连或交叉连接。
-
LAN8720A 的主要特点如下:
· 高性能的 10/100M 以太网传输模块
· 支持 RMII 接口以减少引脚数
· 支持全双工和半双工模式
· 两个状态 LED 输出
· 可以使用 25M 晶振以降低成本
· 支持自协商模式
· 支持 HP Auto-MDIX 自动翻转功能
· 支持 SMI 串行管理接口
· 支持 MAC 接口 -
LAN8720A 中断管理
- LAN8720A 的器件管理接口支持非 IEEE 802.3 规范的中断功能。
- 当一个中断事件发生并且相应事件的中断位使能,LAN8720A 就会在 nINT(14 脚)产生一个低电平有效的中断信号。
- LAN8720A 的中断系统提供两种中断模式:主中断模式和复用中断模式。
- 主中断模式是默认中断模式,LAN8720A 上电或复位后就工作在主中断模式,当模式控制/状态寄存器(十进制地址为 17)的 ALTINT 位为 0 时 LAN8720A 工作在主模式
- 当 ALTINT 位为 1 时工作在复用中断模
-
PHY 地址设置
-
MAC 层通过 MDIO/MDC 总线对 PHY 进行读写操作,MDIO 最多可以控制 32 个 PHY 芯片,通过不同的 PHY 芯片地址来对不同的 PHY 操作。
-
LAN8720A 通过设置 RXER/PHYAD0引脚来设置其 PHY 地址,默认情况下为 0,
-
RXER/PHYAD0 引脚状态 PHY 地址
上拉 0X01
下拉(默认) 0X00 -
nINT/REFCLKO 配置
-
nINTSEL 引脚(2 号引脚)用于设置 nINT/REFCLKO 引脚(14 号引脚)的功能。
nINTSEL 引脚值 模式 nINT/REFCLKO 引脚功能
nINTSEL= 0 REF_CLK Out 模式 nINT/REFCLKO 作为 REF_CLK 时钟源
nINTSEL = 1(默认) REF_CLK In 模式 nINT/REFCLKO 作为中断引脚 -
两个 LAN8720A 而言,全都工作在默认的 REF_CLK In 模式下。
-
当 LAN8720A 工作在 REF_CLK In 模式时,50MHz 的外部时钟信号应接到 LAN8720 的XTAL1/CKIN 引脚(5 号引脚)上
-
为了降低成本,LAN8720A 可以从外部的 25MHz 的晶振中产生 REF_CLK 时钟。到要使用此功能时应工作在 REF_CLK Out 模式时。
-
-
Linux 内核网络驱动框架
- Linux 内核使用 net_device 结构体表示一个具体的网络设备,net_device 是整个网络驱动的灵魂
- 网络驱动的核心就是初始化 net_device 结构体中的各个成员变量,然后将初始化完成以后的 net_device 注册到 Linux 内核中
- net_device 结构体定义在 include/linux/netdevice.h 中
- if_port 指定接口的端口类型,如果设备支持多端口的话就通过 if_port 来指定所使用的端口类型。
- 可选的端口类型定义在 include/uapi/linux/netdevice.h 中
- type 用于指定 ARP 模块的类型,以太网的 ARP 接口为 ARPHRD_ETHER,Linux内核所支持的 ARP 协议定义在 include/uapi/linux/if_arp.h 中
- net_device 有个非常重要的成员变量:netdev_ops,为 net_device_ops 结构体指针类型,这就是网络设备的操作集。
- net_device_ops 结构体定义在 include/linux/netdevice.h 文件
- 网络是分层的,对于应用层而言不用关系具体的底层是如何工作的,只需要按照协议将要发送或接收的数据打包好即可。
- 打包好以后都通过 dev_queue_xmit 函数将数据发送出去,接收数据的话使用 netif_rx 函数即可,
- sk_buff 是 Linux 网络重要的数据结构,用于管理接收或发送数据包,sk_buff 结构体定义在 include/linux/skbuff.h 中
- 针对 sk_buff 内核提供了一系列的操作与管理函数
-
网络 NAPI 处理机制
- Linux 里面的网络数据接收也轮询和中断两种,
- 中断的好处就是响应快,数据量小的时候处理及时,速度快,但是一旦当数据量大,而且都是短帧的时候会导致中断频繁发生,消耗大量的 CPU 处理时间在中断自身处理上。
- 轮询恰好相反,响应没有中断及时,但是在处理大量数据的时候不需要消耗过多的 CPU 处理时间。
- Linux 在这两个处理方式的基础上提出了另外一种网络数据接收的处理方法:NAPI(New API),NAPI 是一种高效的网络处理技术。
- Linux 里面的网络数据接收也轮询和中断两种,
- NAPI 的核心思想就是不全部采用中断来读取网络数据,而是采用中断来唤醒数据接收服务程序,在接收服务程序中采用 POLL 的方法来轮询处理数据。
- 这种方法的好处就是可以提高短数据包的接收效率,减少中断处理的时间。
- 目前 NAPI 已经在 Linux 的网络驱动中得到了大量的应用,
- Linux 内核使用结构体 napi_struct 表示 NAPI,在使用 NAPI 之前要先初始化一个 napi_struct 实例。
-
MDIO 总线注册
- MDIO 就是用来管理 PHY 芯片的,分为 MDIO 和 MDC 两根线,
- Linux内核专门为 MDIO 准备一个总线,叫做 MDIO 总线,采用 mii_bus 结构体表示,定义在include/linux/phy.h 文件
- 简单总结一下,of_mdiobus_register 函数有两个主要的功能,
- 一个是通过 mdiobus_register函数向 Linux 内核,
- 另一个就是通过 of_mdiobus_register_phy 函数向内核注册 PHY。
Linux 内核 PHY 子系统与 MDIO 总线简析
- PHY 子系统就是用于 PHY 设备相关内容的,分为 PHY 设备和 PHY 驱动,和 platform 总线一样,PHY 子系统也是一个设备、总线和驱动模型。
-
PHY 设备
- Linux 内核使用 phy_device 结构体来表示 PHY 设备,结构体定义在 include/linux/phy.h
- 一个 PHY 设备对应一个 phy_device 实例,然后需要向 Linux 内核注册这个实例
- PHY 设备的注册过程一般是先调用 get_phy_device 函数获取 PHY 设备
-
MDIO 总线
-
PHY 子系统也是遵循设备、总线、驱动模型的,设备和驱动就是 phy_device 和phy_driver。
-
总线就是 MDIO 总线,因为 PHY 芯片是通过 MIDO 接口来管理的,
-
MDIO 总线最主要的工作就是匹配 PHY 设备和 PHY 驱动。在文件 drivers/net/phy/mdio_bus.c
-
如果 PHY 设备和 PHY 驱动匹配,那么就使用指定的 PHY 驱动,如果不匹配的话就使用Linux 内核自带的通用 PHY 驱动。
-
前面多次提到Linux内核已经集成了通用PHY驱动,通用PHY驱动名字为“Generic PHY”,打开 drivers/net/phy/phy_device.c
-
标签:芯片,MDIO,MAC,接口,网络,PHY,Linux 来源: https://blog.csdn.net/CouragelDesire/article/details/114777006