GMAC基础知识
1.MAC与PHY
PHY:
用于真正的收发数据。属于物理层。
MAC:
作用是数据控制。EMAC即百兆网卡,GMAC即千兆网卡,属于数据链路层。
MAC和PHY之间直接通过MII接口进行通信。
一个MAC可以同时管理多个PHY的行为(1个GMAC可以创建多个网卡设备)。
CPU与MAC与PHY的结构如下:
2.GMAC组成
GMAC可以分为四个部分:
帧发送(Frame Transmission)
接收上层协议传来的数据,加头尾(控制信息),组成以太网帧,以位数据流形式传到物理层。
帧接收(Frame Reception)
接收物理层位数据流,检查是否有效(目的IP,校验码,字节对齐),发送给上层协议,或丢弃。
GMAC控制(GMAC Control)
用于全双工模式下控制帧的生成、检测,它处在主机和发送、接收模块之间,对普通的数据帧来说是透明的。
媒体独立接口管理(GMII)
控制物理层的输入输出操作,检查物理层的状态信息。(控制PHY)
3.GMAC工作模式
GMAC的工作方式有半双工和全双工两种。
半双工:
半双工模式:GMAC client将数据传给GMAC后,GMAC先给数据加上Preamble、FSD、FCS,组成以太网帧,然后检查载波侦听信号(CRS),若有载波信号,表示有数据正在 本地网段上传播,就等待直到载波信号消失,载波信号消失后,GMAC还要等待一个帧间延时(interFrame Spacing),若在帧间延时期间,一直没有载波信号,该以太网帧就可以开始向物理层传输。
全双工:
全双工模式:GMAC从GMAC Client接收到数据后,不需要载波侦听和冲突检测,直接向物理层传送,其它操作与半双工相同。
4.以太网帧格式
以下为最常见的ethernet-II型以太网帧格式:
目的mac: 0x00e04c32b8fb
源mac:0x028148fdde8c
以太类型:0x0800(ipv4数据报)
实际发送时,到GMAC网卡驱动的pbuf只含红框中的内容。
常见的以太网帧类型:(其它以太网帧当负载小于0x800时,负载的实际意义是数据段长度)
0x0800 IPv4数据报
0x0806 ARP帧
0x8100 IEEE 802.1Q帧
0x86DD IPv6帧。
FCS(frame check sequence):CRC字段,32 b CRC校验码由802.3规定的校验公式决定,作用范围是从DA字段到Pad字段(如果有的话);
5.MAC与PHY间的通信
以太网MAC芯片的一端接计算机PCI总线;另外一端就接到PHY芯片上,它们之间是通过MII接口通信的。
MII接口:
包括数据接口,管理接口。数据接口:16线;管理接口:2线(MDC:管理时钟,MDIO:管理数据)。
支持10兆和100兆的总线接口速度,时钟都由PHY或FPGA提供。
16个数据线如下:
TX:使能,错误,时钟,数据*4。RX:使能,错误,时钟,数据*4。
CRS载波检测,COL冲突检测。
GMII接口:
GMII采用8位接口数据,工作时钟125MHz,因此传输速率可达1000Mbps(每个数据收发口每秒有125M个周期的电平变换,收发各8个口)。同时兼容MII所规定的10/100 Mbps工作方式。
发送:
GTXCLK(125MHz)(千兆模式下,MAC提供这个时钟(与MII区别),其他信号和这个信号同步)
TXCLK——10/100M信号时钟(百兆模式下,PHY提供这个时钟,其他信号和这个同步)
TXD[7..0]——被发送数据
TXEN——发送器使能信号
TXER——发送器错误(用于破坏一个数据包)
接收:
RXCLK——接收时钟信号(从收到的数据中提取,因此与GTXCLK无关联)
RXD[7..0]——接收数据
RXDV——接收数据有效指示
RXER——接收数据出错指示
COL——冲突检测(仅用于半双工状态)
管理配置:(用于配置PHY)
MDC——配置接口时钟
MDIO——配置接口I/O
RGMII接口:
由GMII的24线简化为14线,TX/RX数据宽度从8为变为4位。
为了保持1000Mbps的传输速率不变,RGMII接口在时钟的上升沿和下降沿都采样数据,时钟频率仍旧为125MHz。
(100M和10M时参考时钟为25Mhz和2.5MHz)
在参考时钟的上升沿发送GMII接口中的TXD[3:0]/RXD[3:0],在参考时钟的下降沿发送GMII接口中的TXD[7:4]/RXD[7:4]。
TX_EN信号线上传送TX_EN和TX_ER两种信息,在TX_CLK的上升沿发送TX_EN,下降沿发送TX_ER;RX同理。
6.GMAC如何操纵PHY(以T3为例)
GMAC通过GMAC_CMD和GMAC_DATA读写PHY的寄存器,以此配置PHY的工作模式,并获取PHY状态。
PHY寄存器简介:
共32个寄存器,每个寄存器16bit。
前16个结构基本固定,后16个由厂商自定义。
PHY的地址0-31(占5bit,不清楚的情况下可以轮询读)。PHY的ID号由硬件厂商决定。
7.GMAC TX/RX描述符
GMAC结构如下:
GMAC内部DMA通过一个描述符链表在内存和TX/RX_FIFO之间传输数据,
每个描述符结构如下图:
Status:用于标识当前传输的帧是否有各种错误.
Buffersize:控制发送中断,标识当前帧大小
Buffer Addr:当前描述符指定的pBuf的地址。
NextDesc:下一个描述符的地址。
如何理解GMAC接收数据的方式:
给GMAC一个地址,GMAC默认这个地址是DescList Base Addr。在数据来之前配置好这个地址(DB),和DB[2]的Buffer Addr。数据将被GMAC的内部DMA存放到Buffer Addr指向的区域。(数据的接收)
正常的接收流程:
把Buffer Addr指向的区域的数据,拷贝一次,生成内核协议栈可理解的pbuf结构。(这一步是可以通过0拷贝省略的)
内核收到pbuf后再拷贝一次把数据传给对应的应用。(第次拷贝过程)
正常的发送过程相反。
注意:
1、以上的DB环形链表 ,buffer_tmp,pbuf都是在系统初始化的时候就创建好的;
2、DB环形链表在实际的内存中也可能是连续的,便于直接找下一个可用的。(HRT项目中就是连续的)
3、以HRT项目为例,TX的DB结构有512个,RX的DB结构有512个,内核中的pbuf有1024个;
4、从PHY过来的数据存到buffer_tmp,是由GMAC硬件完成的,只要初始化配置的没问题,进TX函数后,可以直接通过buffer_addr取数据。
8.零拷贝
在创建buffer_tmp和pbuf时注意结构的安排:
如上图,直接将buffer_addr指向pbuf的payload的首地址。
buffer_tmp:GMAC硬件,接收数据的位置。
pbuf:接收时驱动需要向内核提交的结构。
pbuf head:用于管理pbuf的数据结构。
pbuf payload:用于存放帧数据的缓冲区。
如上图pbuf_head加上paylaod就是一个完整的pbuf。把buffer_tmp放在payload的位置上。就能省掉一次拷贝的过程。
从图中还可以看出pbuf head的大小是cacheline大小对齐的,在32位平台上,pbuf head为36字节大小,cacheline对齐后为64字节。一个结点的典型设置值为2KB大小,也就是说payload区域的大小是1984字节。
注意点:
1、注意失效cache
GMAC内部DMA会直接用payload的地址,所以在收发数据前要失效整个pbuf的cache,确保发送时,发送的数据已经写到内存里,而不是还在cache里.
2、注意pbuf的回收时机:
发送时pbuf的数据先考到buffer_tmp里,可以直接重置pbuf的空间,再次使用。零拷贝的情况下,要注意确定数据已经通过GMAC发出去了才能重置pbuf,(用引用技术的方式,使用pbuf时加1,在发送完成后将引用计数减一)接收时同理。
9.Ping命令流程
MAC从PCI总线收到IP数据包(或者其他网络层协议的数据包)后,将之拆分并重新打包成最大1518Byte、最小64Byte的帧。这个帧里面包括了目标MAC地址、自己的源MAC地址和数据包里面的协议类型(比如IP数据包的类型用80表示,最后还有一个DWORD(4Byte)的CRC码。
可是目标的MAC地址是哪里来的呢?这牵扯到一个ARP协议(介乎于网络层和数据链路层的一个协议)。第一次传送某个目的IP地址的数据的时候,先会发出一个ARP包,其MAC的目标地址是广播地址,里面说到:“谁是xxx.xxx.xxx.xxx这个IP地址的主人?”因为是广播包,所有这个局域网的主机都收到了这个ARP请求。收到请求的主机将这个IP地址和自己的相比较,如果不相同就不予理会,如果相同就发出ARP响应包。这个IP地址的主机收到这个ARP请求包后回复的ARP响应里说到:“我是这个IP地址的主人”。这个包里面就包括了他的MAC地址。以后的给这个IP地址的帧的目标MAC地址就被确定了。
IP地址和MAC地址之间的关联关系保存在主机系统里面,叫做ARP表。由驱动程序和操作系统完成。在Microsoft的系统里面可以用arp-a 的命令查看ARP表。收到数据帧的时候也是一样,做完CRC校验以后,如果没有CRC效验错误,就把帧头去掉,把数据包拿出来通过标准的接口传递给驱动和上层的协议栈。最终正确的达到应用程序。
10.数据接收流程:
系统启动时创建一个环形链表,保存1024个描述符。使能数据收发后,有数据来会进入中断。
以下为接收数据的流程:
1 处理器初始化 BD 表;buf descript
2 处理器初始化网络设备(GMAC);
3 MAC 模块从网络中接收数据(实际是PHY);
4 MAC 模块通知 DMA 模块来取数据;
5 DMA 模块从 BD 表中取出合适的 BD;
6 MAC 模块将数据发送至当前 BD 对应的缓存内;
(3-6 由硬件自动完成,无需软件干预)至此BD的buffer addr已经保存了接收的数据。
7 网络设备通知处理器开始接收数据(以中断方式或轮询方式);
8 协议层从当前的 BD 缓存内取走数据。(非零拷贝的情况下会把BD中的数据复制一份,组成pbuf,交给内核)
7,8实际上就是从BD中取数据,拷贝到pbuf里,把pbuf提交给内核(用input)。
9 内核把pbuf中的数据拷贝后给应用,然后释放pbuf的空间。