3 PCIe数据链路层介绍
3.1 数据链路层概述:
数据链路层负责通过 PCI Express 链路可靠地将事务层提供的事务层数据包(TLP)传输到其他组件的事务层。
一、主要功能如下:
1、数据交换:(1)在发送端接收事务层 TLP,送到物理层;(2)在接收端把物理层接收到的 TLP 发送给事务层。
2、错误检测和重试:(1)生成TLP Sequence Number 和 LCRC ;(2)存储发送端用于链路层重试的TLP报文;(3)TLP 和 DLLP 的数据链路层数据完整性检查;(4)Ack/Nak 机制(下文重点介绍);(5)错误指示,用于错误报告和日志记录机制;(6)链路超时重传机制。
3、初始化和电源管理:踪链路状态并把 active/reset/disconnected 等状态发送给事务层;
4、收发DLLP报文:(1)用作链路管理功能的 Ack/Nak DLLP、用作电源管理的 DLLP 和用作流控管理的 DLLP;(2)DLLP 在链路两侧设备的的数据链路层交换;
二、传输类型:
DLLP 是点到点而不是端到端的传输。TLP 是端到端传输。
知识拓展:
点到点:PCIe 点到点传输是指两个 PCIe 设备之间通过 PCIe 链路直接进行数据交换,而无需经过主机内存或 CPU 的干预。
端到端:PCIe 端到端传输是指从一个 PCIe 设备(Source Endpoint)发送数据到另一个 PCIe 设备(Destination Endpoint)的过程。
三、数据完整性检查:
DLLP 和 TLP 的数据完整性检查是通过跨链路发送的每个数据包附带的 CRC 完成的。DLLP 使用 16 位 CRC,而 TLP 使用 32 位 LCRC。 TLP 还包含一个序列号,该序列号用于检测一个或多个完整 TLP 是否丢失。收到的未通过 CRC 检查的 DLLP 将被丢弃。使用 DLLP 的机制可能会因信息丢失而遭受性能损失,但会进行自我修复(重传机制),以使后续 的 DLLP 会取代任何丢失的信息。
数据完整性检查(LCRC 检查和序列号检查)失败,或在从一个组件到另一个组件的传输中丢失了 TLP,则由发送器重新发送。 发送器存储所有已发送 TLP 的报文,并在需要时重新发送这些报文,并且仅当它从其他组件收到 Ack 确认后才清除这些缓存。如果在指定时间段内未收到 Ack,则发送器将自动开始重新发送缓存的TLP报文。 接收方可以使用 Nak 请求要求发送方立即重发。
在任何给定的单个链路上,灌入发送数据链路层(1 和 3)的所有 TLP 之后将以相同顺序出现在接收数据链路层(2 和 4)的输出处,如 Figure 3-1 所示。 之间的延迟将取决于许多因素,包括流水线 延迟、链路的宽度、工作频率、链路上电信号的传输以及由数据链路层重试引起的延迟。由于这些延迟,传输数据链路层(1 和 3)可以向传输事务层施加反压,而接收数据链路层(2 和 4)将有效信息的存在或不存在传达给接收事务层。
3.2 数据链路控制和管理状态机
数据链路层跟踪链路的状态。它与事务层和物理层通信链路状态,并通过物理层执行链路管理。数据链路层包含执行这些任务的数据链路控制和管理状态机(DLCMSM)。该状态机的状态描述如下,如 Figure 3-2 所示。
(1)状态机有如下状态:
- DL_Inactive :物理层报告链路不可用或端口无连接时数据链路层处于 DL_Inactive 状态。
- DL_Feature(可选):物理层报告链路可操作,执行 Data Link Feature Exchange。
- DL_Init :物理层报告链接可操作后进入 DL_Init,数据链路层在 DL_Init 状态为默认虚通道初始化流控制。
- DL_Active :正常操作状态。
(2)输出的数据链路层状态有两个:
- DL_Down :数据链路层未与链路另一侧的组件进行通信。
- DL_Up:数据链路层正在与链路另一侧的组件进行通信。
3.2.1 数据链路控制和管理状态机规则
- DL_Inactive:
- PCI Express Hot Reset、Warm Reset 或 Cold Reset 后数据链路层进入该初始状态(请参阅 Section 6.6)。请注意,DL 状态不受 FLR 的影响(请参阅 Section 6.6)。
- 进入 DL_Inactive 时:所有数据链路层状态复位为默认值;如果端口支持可选实现的 Data Link Feature Exchange,则 Remote Data Link Feature Supported 字段和 Remote Data Link Feature Supported Valid 字段必须清 0;丢弃数据链路层 Retry Buffer 的值(see Section 3.6)。
- 在 DL_Inactive 时:向事务层以及对端设备数据链路层报告 DL_Down 状态;这将导致事务层丢弃所有 outstanding transaction,并在内部终止尝试发送 TLP。对于下游端口,这等效于“Hot-Remove”。对于上游端口,使链路断开等效于 Hot Reset(see Section 2.9)。丢弃来自事务层和物理层的 TLP。不能生成 DLLP,也不能接收 DLLP。
- 在以下情况会退出 DL_Inactive 并进入 DL_Feature 状态:端口支持可选的 Data Link Feature Exchange,Data Link Feature Exchange Enable 字段被置 1,事务层指示该链路未
被软件禁用,并且物理层报告 Physical LinkUp = 1b。
- 退出 DL_Inactive 时:(1)端口不支持可选实现的 Data Link Feature Exchange,事务层指示该链路未被软件禁用,并且物理层报告Physical LinkUp = 1b;(2)如果端口支持可选实现的 Data Link Feature Exchange,则 Data Link Feature Exchange Enable 字段清 0,事务层指示该链路未被软件禁用,并且物理层报告 Physical LinkUp = 1b。
- DL_Feature :
- 在 DL_Feature 时:按 Section 3.3 描述的执行 Data Link Feature Exchange 协议。 报告 DL_Down 状态。允许状态为 DL_Down 的端口的数据链路层丢弃任何接收到的 TLP,前提是它不通过发送一个或多个 Ack DLLP 来 确认那些 TLP。
- 在以下情况会退出 DL_Feature 并进入 DL_Init:(1)Data Link Feature Exchange 成功完成,并且物理层继续报告 Physical LinkUp = 1b;(2)Data Link Feature Exchange 确定远程数据链路层不支持可选的 Data Link Feature Exchange 协议,并且物理层继续报告 Physical LinkUp = 1b。
- 在下列情况下,终止 Data Link Feature Exchange 协议并退出到 DL_Inactive: 物理层报告 Physical LinkUp = 0b 。
-
DL_Init:
-
在 DL_init 时:(1)按照 Section 3.3 中描述的流控制初始化协议,为默认虚通道 VC0 初始化流控制。(2)发送 FC_INIT1 DLLP 的过程中报告 DL_Down 状态;发送 FC_INIT2 DLLP 的过程中报告 DL_Up 状态。(3)允许状态为 DL_Down 的端口的数据链路层丢弃任何接收到的 TLP,前提是它不通过发送一个或多个 Ack DLLP 来确认那些 TLP。
- 在以下情况会退出 DL_Init 并进入 DL_Active 状态:流控制初始化成功完成,并且物理层继续报告 Physical LinkUp = 1b。
-
在以下情况下,终止尝试初始化 VC0 的流控制并退出到 DL_Inactive: 物理层报告 Physical LinkUp = 0b。
-
DL_Active:
-
DL_Active 为正常操作状态。
-
在 DL_Active 时:(1)TLP 正常传输。(2)DLLP 正常发送和接收。(3)向事务层和物理层报告 DL_Up 状态。
- 在下述情况退出到 DL_Inactive 状态:(1)物理层报告 Physical LinkUp = 0b。(2)上游组件可以将从 DL_Active 到 DL_Inactive 的转换视为一个 Surprise Down error,特殊情况除外:软件设置了Bridge Control寄存器里的Secondary Bus Reset位;软件设置了Link Disable位;软件端口之外的事件导致;接收到PME_Turn_Off Message;端口支持热插拔,且软件设置了Hot Plug Surprise位;端口支持热插拔,且软件设置了Power Controller Control位;
3.3 数据链路特性交换
一、Data Link Feature Exchange的能力:
- Local Data Link Feature Supported 字段表示 local Port 支持此数据链路功能。
- Remote Data Link Feature Supported 字段表示 remote Port 支持此数据链路功能。
- Remote Data Link Feature Supported Valid 字段表示 Remote Data Link Feature Supported 字段包含有效数据。
- Data Link Feature Exchange Enable 字段允许系统禁用 Data Link Feature Exchange。可以用于处理没有正确忽略DLLP的遗留硬件;
二、Data Link Feature Exchange规则:
Data Link Feature Exchange 协议将 Local Port 的 Feature Supported 的信息传输到 Remote Port,并捕获该 Remote Port 的 Feature Supported 的信息。该功能从Gen4开始加入,目前实际只支持Scaled Flow Control一个Feature,16GT/s及以上速率必须支持该Feature协商。规则如下:
- 在进入 DL_Feature 时:Remote Data Link Feature Supported 和 Remote Data Link Feature Supported Valid 字段必须清 0。
- 在 DL_Feature 时: (1)事务层必须阻塞 TLP 的发送。(2)发送 Data Link Feature DLLP:发送的 DLLP 的 Feature Supported 字段必须等于 Local Data Link Feature Supported 字段的值。发送的 DLLP 的 Feature Ack 字段必须等于 Remote Data Link Feature Supported Valid 字段值。(3)Data Link Feature DLLP 必须每 34μs 至少发送一次。在 Recovery 或 Configuration 状态中花费的时间不会导致此限制。(4)处理收到的 Data Link Feature DLLP:如果 Remote Data Link Feature Supported Valid 字段清 0,请在 Remote Data Link Feature Supported 字段中记录接收到的 Data Link Feature DLLP 中的 Feature Supported 字段的值,然后把 Remote Data Link Feature Supported Valid 字段设置为 1。
- 在以下情况下会退出 DL_Feature:(1)收到了一个 InitFC1 DLLP。(2)收到了一个 MR-IOV MRInit DLLP(编码为 0000 0001b)。(3)在 DL_Feature 中时,至少收到一个 Feature Ack 字段设置为 1 的 Data Link Feature DLLP。
每个 Data Link Feature 在 Feature Supported 字段中都有一个对应的比特位。当在 Local Data Link Feature Supported 和 Remote Data Link Feature Supported 字段中将该位设置为“1 时,将激活此 Data Link Feature。
3.4 流程控制初始化
- FC_INIT1
- FC_INIT2
各个过程的规则如下节描述。
3.4.1 流控制初始化状态机规则
- 如果在 VC 1-7 初始化期间的任何时间禁用了 VC,则终止 VC 的流控制初始化过程。
- FC_INIT1 状态的规则:(1)如果需要初始化一个 VC(VCx)就进入此状态:在进入 DL_Init 状态时,VCx = VC0;当软件使能一个 VC(VCx = VC1-7)时就会进入 FC_INIT1。(2)在 FC_INIT1 状态下:事务层必须阻止使用 VCx 传输 TLP。按下述顺序为 VCx 发送以下三个 InitFC1 DLLP:InitFC1 – P (first)、InitFC1 – NP (second)、InitFC1 – Cpl (third);(3)三个 InitFC1 DLLP 必须每 34μs 至少发送一次:在 Recovery 或 Configuration 状态消耗的时间不会导致此限制;强烈建议频繁重复 InitFC1 DLLP 传输,尤其是在没有其他 TLP 或 DLLP 可用于传输时;(4)如果链路激活了 Scaled Flow Control,请将 InitFC1 DLLP 中的 HdrScale 和 DataScale 字段设置为 01b,10b 或 11b,以指示其在相应的 HdrFC 和 DataFC 值上使用的缩放因子。(5)如果发送器不支持 Scaled Flow Control,或者如果链路未激活 Scaled Flow Control,则将 HdrScale 和 DataScale 字段设置为 00b。(6)除非要保证最小的传输 InitFC1 DLLP 的频率,否则数据链路层不得阻止其他传输:请注意,这包括所有物理层发起的传输(例如,有序集)、Ack 和 Nak DLLP、以及使用先前已完成初始化的 VC 的 TLP。(7)处理收到的 InitFC1 和 InitFC2 DLLP:记录其中携带的 HdrFC 和 DataFC 值;如果接收器支持 Scaled Flow Control,则记录其中的 HdrScale 和 DataScale 值;一旦记录了 VCx 的每个 P、NP 和 Cpl 的 FC unit 值,就设置标志 FI1。(8)下述条件满足则退出 FC_INIT1 状态进入 FC_INIT2:已设置 FI1,表示已为 VCx 的每个 P、NP 和 Cpl 记录了 FC unit 值,则进入 FC_INIT2 状态。
知识拓展:在 PCIe(Peripheral Component Interconnect Express)系统中,Scaled Flow Control(扩展流量控制) 是一种用于优化链路层数据传输的机制。它通过动态调整信用值(Credit)的数量和分配方式,提高了 PCIe 链路的效率和灵活性。
- FC_INIT2 状态的规则:(1)在FC_INIT2状态时:事务层必须阻止使用 VCx 传输 TLP;(2)按下述顺序为 VCx 发送以下三个 InitFC2 DLLP:InitFC2 – P (first)、InitFC2 – NP (second)、InitFC2 – Cpl (third);(3)处理收到的 InitFC1 和 InitFC2 DLLP:忽略其中携带的 HdrFC、DataFC、HdrScale 和 DataScale 的值。 一旦收到任何针对 VCx 的 InitFC2 DLLP,就设置标志 FI2。(4)在收到 VCx 上的任何 TLP 或 UpdateFC DLLP 时,设置标志 FI2。
- 满足下述条件则完成初始化并退出 FC_INIT2:(1)FI2 被设置为 1。(2)如果链路激活了 Scaled Flow Control,则发送器必须在 VCx 的所有 UpdateFC DLLP 中为 HdrScale 和 DataScale 发送 01b,10b 或 11b。(3)如果支持 Scaled Flow Control 或链路未激活 Scaled Flow Control,则发送器必须在所有 VCx 的 UpdateFC DLLP 中为HdrScale 和 DataScale 发送 00b。
NOTE:流控初始化示例:
说明了 Switch 和下游组件之间 VC0 的流控制初始化协议的示例。在此示例中,每个组件都会为每种类型的流控制信用通告最小允许值。对于这两个组件,支持的最大 Max_Payload_Size 值为 1024 字节,对应于 040h 的数据有效负载信用通告。所有 DLLP 都显示为已收到,没有错误。
3.4.2 Scaled Flow Control
一、背景:
- 发送和接收的 InitFC1、InitFC2 和 UpdateFC DLLP 的 HdrScale 和 DataScale 字段必须为 00b。
- HdrFC 计数器为 8 比特宽,且 HdrFC DLLP 字段包括此计数器的所有比特。
- DataFC 计数器为 12 比特宽,且 DataFC DLLP 字段包括此计数器的所有比特。
(2) 当为链路激活 Scaled Flow Control 时,以下规则适用:
- InitFC1 和 InitFC2 DLLP 在 HdrScale 字段中必须包含 01b、10b 或 11b。该值由 Table 3-2 中定义的指定信用类型的 outstanding 的最大 Header 信用数确定。
- InitFC1 和 InitFC2 DLLP 在 DataScale 字段中必须包含 01b,10b 或 11b。该值由 Table 3-2 中定义的指示信用类型的 outstanding的数据有效载荷信用的最大数量确定。
- 如果在状态 FC_INIT1 中记录的接收到的 HdrScale 和 DataScale 值不为零,则在此 VC 上启用 Scaled Flow Control,并且 UpdateFC DLLP 在 HdrScale 和 DataScale 字段中必须包含 01b,10b 或 11b。
- 如果在状态 FC_INIT1 中记录的接收到的 HdrScale 和 DataScale 值为零,则在此 VC 上未启用 Scaled Flow Control,并且 UpdateFC DLLP 在 HdrScale 和 DataScale 字段中必须包含 00b。
3.5 数据链路层数据包
- Ack DLLP :TLP Sequence number 应答;用于指示成功接收到一定数量的 TLP。
- Nak DLLP :TLP Sequence number 否定确认;用于启动数据链路层重试。
- InitFC1、InitFC2 和 UpdateFC DLLP :用于流控制。
- 电源管理 DLLP。
3.5.1 数据链路层的数据包规则
- DLLP Type —— DLLP 类型编码字段,如 Table 3-3。
- 16-bit CRC 字段。
- 对 Ack 和 Nak DLLP(see Figure 3-5):(1)AckNak_Seq_Num 字段用于指示哪些 TLP 受到影响。(2)数据链路层根据 Section 3.6 中提供的规则发送和接收。
- 对于 InitFC1、InitFC2 和 UpdateFC DLLP:(1)HdrFC 字段指 P、NP 或 Cpl 类型报头的信用值。(2)DataFC 字段指 P、NP 或 Cpl 类型数据负载的信用值。(3)HdrScale 字段包含对应类型的 Header 的缩放因子。编码在 Table 3-4 中定义。(4)DataScale 字段包含对应类型的有效负载数据的缩放因子。编码在 Table 3-4 中定义。(5)如果激活了 Scaled Flow Control,则必须在所有传输的 InitFC1,InitFC2 和 UpdateFC DLLP 中将 HdrScale 和DataScale 字段设置为 01b,10b 或 11b。(6)在 UpdateFC 中,仅允许发送器在支持 Scaled Flow Control 的情况下在 HdrScale 和 DataScale 字段中发送非零值,并且在此 VC 的 InitFC1 和 InitFC2 中接收到 HdrScale 和 DataScale 的非零值。(7)InitFC1、InitFC2 和 UpdateFC DLLP 包格式如 Figure 3-7、Figure 3-8 和 Figure 3-9 所示。(8)当数据链路层初始化虚通道的流控制(请参见 Section 3.4),事务层根据 Section2.6 中的规则对流控制进行初始化后,触发传输。(9) 在数据链路层接收时检查完整性,如果正确,则将 DLLP 的信息内容传递到事务层。如果检查失败,则信息将被丢弃。
- 电源管理 DLLP(see Figure 3-10): (1)根据 Chapter 5 中的电源管理逻辑规则触发。 (2)在数据链路层接收时检查完整性,然后传递到组件的电源管理逻辑。
- Vendor Specific DLLP(see Figure 3-11): (1)建议接收者静默丢弃 Vendor Specific DLLP,除非由特定于实现的机制启用。(2)建议发送者不要发送 Vendor Specific DLLP,除非由特定于实现的机制启用。
- NOP DLLP(see Figure 3-6):接收者应在检查 DLLP 的数据完整性后不采取任何措施并将其丢弃。 注:这是不支持 DLLP Type 编码的更通用规则的特殊情况(请参见 Section 3.6.2.2)。
- Data Link Feature DLLP(see Figure 3-12) :(1)Feature Ack 字段设置为 1 表示发送端口已接收到一个 Data Link Feature DLLP。(2)Feature Supported 字段表示发送端口支持的 feature。这些位等于 Local Data Link Feature Supported 字段的值(请参见Section 7.7.4.2)。
- 当 DLLP 呈现给物理层或从物理层接收时,它们与 TLP 不同。
-
DLLP 使用一个 16-bit 的 CRC 保护 DLLP 完整性。
- 该 16-bit CRC 计算规则如下(see Figure 3-13):(1)用于 CRC 计算的多项式的系数表示为 100Bh。(2)seed 值为 FFFFh。(3)CRC 计算从 byte 0 的 bit 0 开始,从每个字节的 bit 0 到 bit 7。(4)请注意,CRC 计算使用 DLLP 的所有位,而与字段类型无关,包括保留字段。计算结果经过补充,然后放入 DLLP 的 16位 CRC 字段中,如 Table 3-5 所示。
NOTE:CRC算法;
3.6 数据完整性机制
3.6.1 介绍

3.6.2 LCRC、序列号和重试管理(TLP重传)
3.6.2.1 LCRC和序列号规则(TLP重传)
以下计数器和计时器用于解释本节中的其余规则:
- 使用了两个 12-bit 的计数器:(1)NEXT_TRANSMIT_SEQ — 存储用于 TLP 的 Sequence Number。该计数器为每个将发送的新的 TLP 分配序列号,每个新 TLP 其值加 1,计数到 4095 时重新返回 0,在 DL_Inactive 状态设置为 0。(2)ACKD_SEQ — 存储最近收到的 Ack 或 Nak DLLP 中的序列号( AckNak_Seq_Num 字段的值,NEXT_TRANSMIT_SEQ
与此值的差值的模表示有多少 TLP 未被响应),在 DL_Inactive 状态设置为 FFFh。
- 使用了一个 2-bit 的计数器:REPLAY_NUM —计算重试缓冲区已重新发送该 TLP 的次数。当 REPLAY_NUM 从 2’b11 翻转到 2’b00 时会触发一次物理层的链路重新训练,在重新训练之后,再次尝试重发该 TLP。无论何时收到 ACK,此计数器也会复位为 2’b00。在 DL_Inactive 状态设置为 0。
- 使用了下述计时器:REPLAY_TIMER — 根据以下规则计算需要重试的时间。或者理解为用来度量从发出 TLP 到收到对应的 ACK 或 NAK DLLP 的时间。(1)从任何 TLP 传输或重传的最后一个符号开始。(2)对于每个重试,在发送要重传的第一个 TLP 的最后一个符号时,重置并重新启动 REPLAY_TIMER。(3)在还有更多未确认的 TLP 要发送时,当且仅当接收到的 Ack DLLP 确认重试缓冲区中的某些 TLP 时,对于收到的每个 Ack DLLP 重置并重新启动 REPLAY_TIMER,注意:这样可确保仅在 TLP 正在传递过程时重置 REPLAY_TIMER。(4)当收到 Nak、或当 REPLAY_TIMER 到期,需要重置 REPLAY_TIMER 直到重发条件满足。(5)链路重新训练期间 REPLAY_TIMER 值不增加(即当 LTSSM 处于 Recovery 或 Configuration 状态时保持其值)。请参阅 Section 4.2.5.3 和 Section 4.2.5.4。(6)如果支持协议多路复用,则可以选择在接收 PMUX 数据包期间不增加 REPLAY_TIMER 的值(PMUX 请参阅 AppendixG)。(7)如果以 Nak 响应的 TLP 都解决了,则 REPLAY_TIMER 重置并保持。
以下规则描述了 TLP 在传递到物理层之前如何准备进行传输:
- 事务层在传输 TLP 时会向数据链路层指示 TLP 的开始和结束:数据链路层将 TLP 视为“黑盒”,并且不处理或修改 TLP 的内容。
- 当数据链路层从事务层的发送端接受每个 TLP 时,会为其分配一个 12 位序列号:(1)在从事务层接受 TLP 时,通过以下方式将数据包序列号应用于 TLP:把 12-bit 的 NEXT_TRANSMIT_SEQ 添加到 TLP 的头部;在序列号之前添加 4 bit 保留位(请参见 Figure 3-15)。(2)如果 (NEXT_TRANSMIT_SEQ – ACKD_SEQ) mod 4096 >= 2048 为真,发送器必须停止从事务层接受 TLP,直到等式不再成立为止。这还会报告一个致命的、无法修正的数据链路层协议错误。(3)在将 NEXT_TRANSMIT_SEQ 应用于从事务层的发送方接受的 TLP 之后,NEXT_TRANSMIT_SEQ 递增(除非 TLP 为空)NEXT_TRANSMIT_SEQ := (NEXT_TRANSMIT_SEQ + 1) mod 4096
-
数据链路层使用 32-bit LCRC 保护 TLP 数据完整性。



以下规则描述了数据链路层重试缓冲区的操作,必要时将从中重新发送 TLP:
当由于接收到 Nak 或由于 REPLAY_TIMER 到期而触发重发时,以下规则描述了必须遵循的操作顺序:
-
从事务层收到这些字节之后,将 32 位 LCRC 字段附加到 TLP(请参见 Figure 3-16)
- 允许发送器作废正在发送的 TLP;为了防止误解或损坏 TLP,发送器必须执行以下操作:(1)当物理层使用 128b/130b 编码时,发送 TLP 的所有 DW(请参阅 Section 4.2.2.3.1)。(2)使用计算出的 LCRC 值的其余部分并且不进行反转(正常使用时 LCRC 值会逻辑反转)。(3)向物理层指示该 TLP 无效。
- 完成此操作后,发送器不会递增 NEXT_TRANSMIT_SEQ。
- 传输的 TLP 必须存储在数据链路层重试缓冲区中,但无效的 TLP 除外。
- 如果已确认所有传输的 TLP(Retry Buffer 为空),请终止重发,否则继续。
- REPLAY_NUM 递增。当通过接收确认重试缓冲区中某些 TLP 的 Nak 触发重发时,将重置 REPLAY_NUM。 然后允许(但不是必需)递增:(1)如果 REPLAY_NUM 从 11b 翻转到 00b,发送器将向物理层发送信号以重新训练链路,并在重新进行重发之前等待重新训练的完成。这会报告与端口相关的错误(请参见 Section 6.2)。Note:除非物理层报告 Physical LinkUp = 0b(导致数据链路控制和管理状态机转换到 DL_Inactive 状态),否则此操作不会重置数据链路层状态(包括重试缓冲区的内容)。(2)如果 REPLAY_NUM 不能从 11b 翻转到 00b,请继续重发。
- 阻止从事务层接受新的 TLP。
- 完成当前正在传输的任何 TLP 的传输。
- 重传响应了 Nak 的 TLP,从最早响应 Nak 的 TLP 开始,以最初传输顺序发送。(1)发送第一个要重传的 TLP 的最后一个符号时,重置并重新启动REPLAY_TIMER。(2)一旦所有响应 Nak 的 TLP 被重新发送,请返回正常操作。(3)如果在重发期间收到任何 Ack 或 Nak DLLP,则允许发送器完成重发而无需考虑 Ack 或 Nak DLLP,或者跳过任何新确认的 TLP。发送器一旦开始重新发送 TLP,则在所有情况下都必须完成该 TLP 的发送。(4)重发期间收到的 Ack 和 Nak DLLP 必须进行处理,并且可能会collapsed:如果收到多个 Ack,则仅应考虑指定最新序列号值的 Ack——指定较早序列号值的 Ack 实际上会“collapsed”到该 Ack中;
在重发期间,会收到 Nak,接着是一个 Ack,该 Ack 指定了后面的序列号—— Ack 取代了 Nak,而 Nak 被忽略。 注意:由于发送器的流控制选通逻辑已在接收器中为重试缓冲区中的所有条目分配了空间,因此无需进一步进行流控制同步。
-
事务层重新启用 TLP 的接收。

- 如果发送重试缓冲区包含未收到 Ack 或 Nak DLLP 的 TLP,并且(如 REPLAY_TIMER 所示)在超过 REPLAY_TIMER 限制的时间内未收到 Ack 或 Nak DLLP,则发送器将启动 Replay;(1)Simplified REPLAY_TIMER Limit 为:当 Extended Synch 字段清 0 时,为 24000 到 31000 个 Symbol Time ;当 Extended Synch 字段置 1 时,为 80000 到 100000 个 Symbol Time 。如果 Extended Synch 字段在未确认的 TLP 处于 outstanding 时改变状态,则允许实现在 Extended Synch 字段改变状态时或下次复位 REPLAY_TIMER 时调整其 REPLAY_TIMER Limit。(2)支持 16.0 GT/s 或更高数据速率的实现必须使用 Simplified REPLAY_TIMER Limit,以便在所有数据速率下进行操作。(3)强烈建议仅支持低于 16.0 GT/s 的数据速率的实现在所有数据速率下使用 Simplified REPLAY_TIMER Limit,但依然允许它们使用[PCIe-3.1]中描述的 REPLAY_TIMER Limit。
这是一个重发计时器超时错误,是与端口相关的报告错误(请参见 Section 6.2)。
知识拓展:Symbol Time 是 PCIe 链路中传输一个符号(Symbol)所需的时间。符号是 PCIe 数据传输的基本单位,在物理层中通过串行化器(Serializer)将数据转换为符号流进行传输。
确定REPLAY_TIMER的极限值:Replay 主要由 Nak DLLP 启动,而 REPLAY_TIMER 作为辅助机制。由于它是辅助机制,因此 REPLAY_TIMER Limit 对跨链路传输 TLP 所需的平均时间影响相对较小。本规范又定义了 Simplified REPLAY_TIMER Limit,因此与本规范的先前版本一样,无需对 ASPM L0s,Retimer 或其他项进行调整。
TLP发送器和一致性测试必须根据在TLP发送器端口上测量的重发时序。该时序以发送的TLP的最后一个符号或接收到的Ack DLLP 的最后一个符号开始,主要看哪个是最早响应 Nak 的 TLP。该时序以 TLP 重传的第一个符号结尾。 在测量重发时序到 TLP 重发开始的时间点时,一致性测试必须允许在该方向上已经在进行任何其他 TLP 或 DLLP 传输(从而防止 TLP 重发)。
计划传输的推荐优先级:如果计划传输多个相同类型的 DLLP 但尚未传输,则在多数情况下有可能将它们“collapsed”为单个 DLLP。例如,如果已调度的 Ack DLLP 传输停顿以等待另一次传输完成,并且在此期间已调度另一 Ack 进行传输,则仅需要传输第二个 Ack,因为它提供的信息将取代第一个 Ack 中的信息。除了来自事务层(或重试缓冲区,如果正在进行重发)的任何 TLP 之外,还可以同时调度多个不同类型的 DLLP 进行传输,此时必须对这些 DLLP 区分优先级进行传输。以下列表显示了选择传输信息的首选优先级顺序。请注意,未列出特定于供应商的 DLLP 的优先级,因为这完全是特定于实现的,因此没有建议的优先级。请注意,此优先级顺序是一个准则,并且在所有情况下都强烈建议采用一种公平机制,以确保任何类型的业务流不会导致任何其他类型的业务流长时间或无限期地被阻塞。请注意,Ack Latency 值和 REPLAY_TIMER 限制指定了在组件的端口上测量的要求,并且组件的内部仲裁策略必须确保满足这些外部测量的要求。
- 当前正在进行的任何传输(TLP 或 DLLP)的完成包(最高优先级)。
- Nak DLLP。
- 由于以下原因,需要尽快安排Ack DLLP传输:收到一个副本TLP(重传过来的TLP)或Ack延迟计时器到期(see Section 3.6.3.1)。
- 满足 Section 2.6 要求的 FC DLLP 传输。
- 重试缓冲区重传。
- 来自事务层的 TLP。
- 不满足 Section 2.6 要求的 FC DLLP 传输。
- 所有其他 DLLP 的传输(最低优先级)。
3.6.2.2 Handling of Received DLLP
- 如果物理层指示接收器错误,则丢弃当前正在接收的任何 DLLP 并释放为该 DLLP 分配的任何存储。请注意,将此类错误报告给软件是由物理层完成的(因此,数据链路层不会报告)。
- 对所有收到的 DLLP 执行以下 CRC 检查过程:(1)对接收的 DLLP 应用于发送相同的 DLLP 的算法,不包括接收的 DLLP 的 16-bit CRC 字段。(2)比较该计算值与 DLLP 中携带的 16-bit CRC 的值:如果不相等,则 DLLP 被损坏。(3)接收到损坏了的 DLLP 将被丢弃,并且是与端口相关的报告错误(请参见 Section 6.2)。
- 接收到的未损坏但使用不受支持的 DLLP Type 编码的 DLLP 会被丢弃,而无需采取进一步措施。这不被视为错误。
- 保留字段中的非零值将被忽略。
- 接收者必须按照接收到的速率处理所有接收到的 DLLP。
- 把接收到的 FC DLLP 传递到事务层;
-
把接收到的 PM DLLP 传递到组件的电源管理控制逻辑。
- 对于 Ack 和 Nak DLLP,请遵循以下处理步骤(请参阅 Figure 3-18):(1)如果由 AckNak_Seq_Num 指示的 Sequence Number 不与任何响应 Nak 的 TLP 对应,或不与ACKD_SEQ 值对应,则 DLLP将被丢弃。这是一个数据链路协议错误,是一个与端口相关的报告错误(参见 Section 6.2)。Note:只要指示的 Sequence Number 与 ACKD_SEQ 值匹配,当 TLP(包括复位和第一次 TLP 传输之间的时间)全部被确认,接收 Ack DLLP 并不是错误。(2)如果 AckNak_Seq_Num 没有指示为一个最近响应 Ack 的 TLP 的 Sequence Number,则用 Ack DLLP 响应重试缓冲区中的某些 TLP:从重试缓冲区中清除所有 TLP,从最早的到对应于 AckNak_Seq_Num 的 TLP;使用 AckNak_Seq_Num 字段中的值加载 ACKD_SEQ;重置 REPLAY_NUM 和 REPLAY_TIMER。(3)如果 DLLP 是 Nak,则触发 Replay 过程(请参见上文)。Note:收到 Nak 不报告错误。
3.6.3 LCRC and Sequence Number (TLP Receiver)
3.6.3.1 LCRC and Sequence Number Rules (TLP Receiver)
- 使用了一个 12-bit 的计数器: NEXT_RCV_SEQ —— 存储下一个 TLP 的期望 Sequence Number 值。 在 DL_Inactive 状态重置为 0。
- 使用了下述 flag:NAK_SCHEDULED,在 DL_Inactive 状态重置为 0b。
- 使用了下述计时器:AckNak_LATENCY_TIMER —— 根据以下规则对 Ack DLLP 何时调度传输的时间进行计数:(1)在 DL_Inactive 状态重置为 0。 (2)每次调度发送 Ack 或 Nak DLLP 时该值都从 0 重新开始;用 Ack DLLP 确认收到的所有 TLP 时重置为 0。(3)如果最初没有未确认的 TLP,然后接收到 TLP,则只有当 TLP 已转发到接收事务层时,AckNak_LATENCY_TIMER 才开始计数。
-
如果物理层报告一个 Receiver Error,则丢弃当前正在接收的任何 TLP,并释放为该 TLP 分配的任何存储。请注意,将此类错误报告给软件是由物理层完成的(因此,数据链路层不会报告)。
- 如果 TLP 无效,但 LCRC 与计算值的逻辑非匹配,则 TLP 损坏——丢弃 TLP 并释放为 TLP 分配的任何存储:(1)如果 NAK_SCHEDULED 标志清为 0,立即调度一个 Nak DLLP 发送出去。把 NAK_SCHEDULED 是为 1。这是 Bad TLP 错误,是报告的与端口相关的错误(请参见 Section 6.2)。
-
按以下方式检查 LCRC : (1)对接收到的 TLP 应用与上述计算相同的算法,不包括接收到的 TLP 的 32 位 LCRC 字段。(2) 把计算的值与数据链路层 TLP 携带的 LCRC 比较:如果不相等,则 TLP 损坏——丢弃 TLP 并释放为 TLP 分配的任何存储。如果 NAK_SCHEDULED 标志清为 0,立即调度一个 Nak DLLP 发送出去。把 NAK_SCHEDULED 是为 1 。 这是 Bad TLP 错误,是报告的与端口相关的错误(请参见 Section 6.2 )。
- 如果 TLP Sequence Number 不等于期望值,则存储在 NEXT_RCV_SEQ 中:(1)丢弃 TLP 并释放为 TLP 分配的任何存储。(2)如果 TLP Sequence Number 满足以下方程式:
(NEXT_RCV_SEQ - TLP Sequence Number) mod 4096 <= 2048 则 TLP 是对方重发过来的,需要为此传输 Ack DLLP(根据传输优先级规则)。
- 否则,TLP 顺序不正确(指示一个或多个丢失的 TLP):如果 NAK_SCHEDULED 标志清为 0,立即调度一个 Nak DLLP 发送出去。把 NAK_SCHEDULED 是为 1。这是 Bad TLP 错误,是报告的与端口相关的错误(请参见 Section 6.2)。无论 NAK_SCHEDULED 的状态如何,都可以将其报告为与端口相关的错误(请参见 Section 6.2 节),并且这种允许的行为如 Figure 3-17 所示。但是,为了防止错误污染,建议仅当 NAK_SCHEDULED 标志清零时,端口才报告此类错误。
-
如果 TLP Sequence Number 等于存储在 NEXT_RCV_SEQ 中的期望值:(1)删除 4-bit 的保留位、 TLP Sequence Number 和 LCRC (见 Figure 3-12),并发送到事务处理层。数据链路层在传输 TLP 时向事务层指示 TLP 的开始和结束。 数据链路层将 TLP 视为“黑盒”,并且不处理或修改 TLP 的内容。 请注意,在将 TLP 转发到事务层之前,接收方流控制机制不会考虑任何接收到的 TLP。(2)NEXT_RCV_SEQ 递增。 (3)如果 NAK_SCHEDULED 为 1 ,则清为 0 。