目录
- 前言
- 一、简介
- 1.1 接收部件组成
- 1.2 发送部件组成
- 二、数据链路层功能详细介绍
- 2.1 DLLP介绍
- 2.2 ACK/NAK协议
- 2.3 发送端逻辑
- 2.3.1 发送端TLP包处理总流程
- 2.3.2 使用ACK/NAK协议详解
- 2.4 接收端逻辑
- 2.4.1 接收端TLP包处理流程
- 2.4.2 如何使用ACK/NAK协议
- 2.5 数据链路层发送报文的顺序
- 三、其他相关知识介绍
- 1、PCI总线及发展历程总结
- 2、PCIe物理层总结-PCIE专题知识(一)
前言
本文主要介绍数据链路层的相关知识,通过详细的图文解析,方便读者快速掌握。
一、简介
PCIe 总线的数据链路层(Data Link Layer)处于事务层和物理层之间,主要进行链路管理(Link Management)、TLP错误检测,Flow Control和Link功耗管理,负责数据链路层包(Data Link Layer Packet,DLLP)的创建,解码和校检,保证来自事务层的 TLP 在 PCIe 链路中的正确传递。
与事务层不同, 数据链路层主要处理端到端的数据传送,本层还实现了Ack/Nak的应答机制,数据链路层不仅可以转发来自事务层的包(TLP),还可以直接向另一个相邻设备的数据链路层直接发送DLLP,比如应用于Flow Control和Ack/Nak的DLLP,如下图所示,具体的知识本章会在下面详细介绍。
数据链路层由发送和接收两部分组成:
1.1 接收部件组成
1、ACK/NAK DLLP发送逻辑;
2、“Error Check”逻辑;
3、TLP接收逻辑;
1.2 发送部件组成
1、ACK/NAK接收逻辑;
2、Replay Buffer;
3、TLP发送逻辑;
二、数据链路层功能详细介绍
一个正常的数据包经过事务层、数据链路层和物理层会被封装加上不同的头尾用于保存特定的信息,具体如下:
2.1 DLLP介绍
DLLP产生于数据链路层,终止于数据链路层,设置DLLP的目的是保证TLP的正确传输和管理PCIe链路。
一个DLLP长度为6byte,其中byte0存放DLLP的类型,byte1~ byte3与DLLP的类型有关,byte4~byte5位DLLP的16bit的CRC校验结果。
DLLP报文类型有:
1、 ACK DLLP:由数据接收方发送给数据发送方,该DLLP表示接收方正确接收到来自发送方的TLP。
2、 NAK DLLP:由数据接收方发送给数据发送方,该DLLP表示哪些TLP没有被正确接收,在接收到该TLP时,接收方“Replay Buffer”加释放已经被正确接收的TLP。
3、 Power Management DLLPs:PCIe设备使用过该组DLLPs进行电源管理,并向对端设备通知当前PCIe链路的状态,拥有保证电源管理状态机的正确运行。
4、 FLOW Control Packet DLLPs:流控制DLLP,包括InitFC1、InitFC2、UpdateFC DLLP等类型,用于流量控制。
5、 Vendor_Defined DLLPs:厂商自定义DLLP。
2.2 ACK/NAK协议
数据链路层还实现了一种自动的错误校正功能,即Ack/Nak机制。
如下图所示,发送方会对每一个TLP在Replay Buffer中做备份,直到其接收到来自接收方的Ack DLLP,确认该DLP已经成功的被接受,才会删除这个备份。
ACK/NAK协议详细介绍:
如果接收方发现TLP存在错误,则会向发送发发送Nak DLLP,然后发送方会从Replay Buffer中取出数据,重新发送该TLP。
ACK/NAK是一种滑动窗口协议,PCIe设备数据链路层的发送端和接收端分别有一个滑动窗口,发送端在发送TLP时,首先将这个TLP存放到发送窗口(这个窗口就是“Replay Buffer”)中,并对这些TLP从0~n进行编号,只要发送窗口不满,发送端就一直发送端就一直可以从事务层接收报文存放到发送窗口中。
当发送端收到接收端第n个ACK确认报文后,表示第n、n-1……0等在“Replay Buffer”的报文已被正确接收,然后滑动窗口,释放已被确认的TLP,提高PCIe总线的传输效率。
下图是数据链路层Ack/Nak机制详细的结构图,理解了这幅图就基本掌握了Ack/Nak机制,下面会详细介绍该图。
2.3 发送端逻辑
2.3.1 发送端TLP包处理总流程
1、为TLP分配Sequence ID;
2、为TLP增加LCRC;
3、将TLP在Retry Buffer备份;
4、发送端检查接收端返回的DLLPs;
2.3.2 使用ACK/NAK协议详解
1、数据链路层在发送TLP之前,首先要给这个TLP添加一个Sequence前缀和LCRC后缀,之后再将TLP放入“Replay Buffer”中。
2、发送端设置了一个12bit的计数器NXT_TRANSMIT_SEQ, 简称NTS,这个计数器的初始值为0,在数据链路层处于Inactive状态时该计数器保持为0。
3、发送端使用NXT_TRANSMIT_SEQ保存即将发送TLP的Sequence号,PCIe设备每发送完一个TLP,该计数器加一,然后把累加后的数值再赋值给下一个TLP,直到4095。
4、同时接收方也有一个12bit的NXT_RCV_SEQ,该计数器记录接收端即将接收的TLP总线号(Sequence Number)。
5、发送端为了处理来自接收端的ACK/NAK DLLPs,设置了一个ACKD_SEQ,该计数器记录ACK/NAK DLLP中的AckNack_Seq_Num字段,该计数器的初始值为全1,数据链路层为Inactive状态时,保持为全1,在接收到接收方的ACK/NAK DLLP时,将使用ACK/NACK DLLP中的AckNak_Seq_Num字段更新ACKD_SEQ计数器。
2.4 接收端逻辑
2.4.1 接收端TLP包处理流程
1、接收端对接收的TLP进行LCRC检查;
2、LCRC检查OK,检查Sequence ID;
3、Ack/Nak Latency Timer;
2.4.2 如何使用ACK/NAK协议
接收端首先从物理层获得TLP,此时这个TLP中包含Sequence前缀和LCRC后缀,接收端收到这个TLP后,首先将这个报文放入receive buffer中,然后进行CRC检查,检查成功时,结束段将根据缓存的阈值发送ACK DLLP给发送端。
ACK 应答原则:
(1)接收端收到一定数量的报文后,统一发送给一个ACK给发送方
(2)接收端收到的报文未达到阈值,但是ACK_NACK_LATENCY_TIMER计数器超时后,仍要发出ACK DLLP。
2.5 数据链路层发送报文的顺序
数据链路层还规定了报文发送的顺序,因为DLLP、TLP、PLP(物理层包)使用同一链路,因此PCIe链路需要合理安排报文发送顺序,防止死锁:
1、 正在发送的TLP、DLLP报文,为了报文的完整性,正在传输的报文享有最高优先级。
2、 PLP,协议底层的报文优先级高于协议高层的报文,这是避免传输死锁的一种有效方法。
3、 NACK(原因同2)
4、 ACK,(一般来说。错误信息报文具有更高优先级)
5、 重传的TLP,也是一种发现错误后的恢复手段,在错误未处理完毕之前,所有TLP的传递没有意义,接收端都将丢弃这些报文。
6、 数据缓冲区的TLP
7、 其他DLLP,包括地址路由、电源管理等报文,与数据报文的传递无关,是PCIe总线规定的一些控制报文,优先级高的话会占用较多传输资源,降低通信带宽,所有优先级最低。