PCIe数据链路层主要进行链路管理(Link Management)、TLP错误检测,Flow Control和Link功耗管理。
Flow Control
对于大部分的串行传输协议而言,发送方能够有效地将数据发送至接收方的前提是,接收方有足够的接收Buffer来接收数据。 在PCI总线中,发送方在发送前并不知道接收法是否有足够的Buffer来接收数据(即接收方是否就绪), 因此经常需要一些Disconnects和Retries的操作,这将会严重地影响到总线的传输效率(性能)。
PCIe总线为了解决这一问题,提出了Flow Control的概念,如下图所示。PCIe总线中要求接收方必须经常(在特定时间)向发送方报告其VC Buffer的使用情况。 而报告的方式是,接收方向发送方发送Flow Control的DLLP(数据链路层包), 且这种DLLP的收发是由硬件层面上自动完成的,并不需要人为的干预。 需要注意的是,虽然这一操作旨在数据链路层之间进行,但是这些VC Buffer的使用情况对于应用层(软件层)也是可见的。
采用Flow Control机制的PCIe总线,相对于PCI总线获得了更高的总线利用率。 虽然增加了Flow Control DLLP,但是这些DLLP对带宽的占用极小,几乎对总线利用率没有什么影响。
数据链路层不仅可以转发来自事务层的包(TLP),还可以直接向另一个相邻设备的数据链路层直接发送DLLP, 比如应用于Flow Control和Ack/Nak的DLLP。如下图所示:
Ack/Nak 机制
数据链路层还实现了一种自动的错误校正功能,即Ack/Nak机制。 如下图所示,发送方会对每一个TLP在Replay Buffer中做备份,直到其接收到来自接收方的Ack DLLP,确认该DLP已经成功的被接受,才会删除这个备份。 如果接收方发现TLP存在错误,则会向发送发发送Nak DLLP,然后发送方会从Replay Buffer中取出数据,重新发送该TLP。
两种DLLP(转发TLP的DLLP,用于Flow Control或Ack/Nak等的DLLP)的结构图分别如下图所示。这个应该是表示用于转发的DLLP和用于flow control/Ack/Nak 的DLLP格式有一点点不同:
一个Non-Posted传输中,Ack/Nak的执行过程如下图所示