本文为CoryXie原创译文,转载及有任何问题请联系cory.xie#gmail.com。
链路层具有维持链路连接性的责任,从而确保在两个链路伙伴之间的成功数据传输。基于包(packets)和链路命令(link commands)定义了健壮的链路流程控制。数据包在链路层被准备好,携带数据和不同的信息在主机和设备之间传输。链路命令的定义是为了链路伙伴两者之间的通信。包帧(Packet frame)有序集(ordered sets)和链路命令有序集也被构造得可以容忍一个符号错误。此外,错误检测也被融入数据包和链接命令,用来验证包和链路命令的完整性。在链路层也有链路训练,链路测试/调试,以及链路电源管理。 这是通过引入链路训练状况状态机【Link Training Status State Machine(LTSSM)】而得以实现的。 本章的重点是解决以下几个问题:
- 包分帧(Packet Framing)
- 链路命令定义和用法(Link command definition and usage)
- 链路初始化和流程控制(Link initialization and flow control)
- 链路电源管理(Link power management)
- 链路错误规则和恢复(Link error rules/recovery)
- 复位(Resets)
- LTSSM规范(LTSSM specifications)
7.1 字节序 【Byte Ordering】
包或链路命令的多字节字段以小端(little-endian)顺序在总线上搬移, 即最低有效字节(LSB)最先传输,最高有效字节(MSB)最后传输。图7-2显示了一个字节序的例子。
数据包或链路命令的每一个字节都要在物理层使用的8B/10B编码进行编码。请参阅第6.3节关于8b/10b编码和位序的介绍。
7.2 链路管理和流程控制 【Link Management and Flow Control】
本节包含有关链路数据完整性,流程控制和链路电源管理的信息。
- 包和包分帧【packet and packet framing】一节定义每个数据包的包类型,包结构和CRC的要求。
- 链路命令【link command】部分定义在链路层级上控制各种功能性的特殊链路命令。
- 逻辑空闲【logical idle】定义了一个特殊的符号供U0使用。
- 流程控制【flow control】定义了用于包事务的一组握手规则。
7.2.1 包和包分帧 【Packets and Packet Framing】
超高速使用数据包来传输信息。详细的链路管理包(LMP),事务包(TP),等时时间戳包(ITP),以及数据包(DP)等包格式被定义在8.2节。
7.2.1.1 头包结构 【Header Packet Structure】
所有的头包(header packets)都是20个符号长,如图7-3的格式。这包括LMPs, TPs, ITPs, 以及DPHs。头包包括3个部分,一个头包分帧符号(header packet framing),一个包头(packet header),以及一个链路控制字(Link Control Word)。
7.2.1.1.1 头包分帧符号 【Header Packet Framing】
头包分帧符号(header packet framing),HPSTART有续集,是一个基于K-符号(K-symbols)的4个符号的头包起始帧有续集(header packet starting frame ordered set)。它定义为3个连续的SHP后面紧跟一个K-符号EPF。一个头包应该总是以HPSTART有续集开始。头包分帧符号(header packet framing)的构造是为了达到1个符号的容错性(error tolerance)。
7.2.1.1.2 包头 【Packet Header】
一个包头包含如图7-4格式的14字节。它包括12字节头信息以及2字节CRC-16。CRC-16用来保护该12字节头信息的数据完整性。
包头的CRC-16的实现定义如下:
- CRC-16多项式应该是100Bh。
注意:CRC-16多项式与USB 2.0使用的不相同。
- CRC-16的初值应为FFFFh。
- CRC-16应该对所有的12字节的头信息进行计算,不包含任何分帧符号。
- CRC-16计算应该从字节0的比特0开始,并继续到12个字节的每个的比特7。
- CRC-16的余数(remainder)应该被补偿(complemented)。
- CRC-16的残差(residual)应该为F6AAh。【译注:校对概念的准确性!】
注意:在接收端,CRC-16的余数(remainder)加上偏移量FFFFh,会得到CRC-16的一个常量残差(residual)F6AAh。
图7-5显示了CRC-16的余数(remainder)的生成。输出比特顺序列出在表7-1中。
7.2.1.1.3 链路控制字 【Link Control Word】
2字节的链路控制字(Link Control Word)格式如图7-6所示。它被用来对链路层和端到端两者进行流程控制。
链路控制字(Link Control Word)应该包含一个3比特的头序列号(Header Sequence Number),一个3比特保留字段,一个3比特集线器深度索引(Hub Depth Index),一个延迟标志比特(Delayed bit (DL)),一个推后标志比特(Deferred bit (DF)),以及一个5比特的CRC-5。
CRC-5保护流程控制字的数据完整性。CRC-5的实现定义如下:
- CRC-5多项式应该是00101b。
- CRC-5的初值应为11111b。
- CRC-5是对流程控制字的其余11比特进行计算。
- CRC-5计算应该从比特0开始,并继续到比特10。
- CRC-5的余数(remainder)应该被补偿(complemented),将流程控制字的MSb映射到比特11,下一个MSb映射到比特12,如此下去,直到LSb被映射到比特15。
- CRC-5的残差(residual)应该为01100b。【译注:校对概念的准确性!】
注意:在接收端,CRC-5的余数(remainder)加上偏移量11111b,会得到CRC-5的一个常量残差(residual)01100b。
图7-7显示了CRC-5的余数(remainder)的生成。
7.2.1.2 数据包负载结构 【Data Packet Payload Structure】
数据包是特殊类型的包,由数据包头【Data Packet Header (DPH)】以及数据包负载【Data Packet Payload (DPP)】组成。DPH定义在7.2.1.1节。而另一方面,DPP则由数据包负载分帧符号(data packet payload framing),以及可变长度的数据,紧跟4字节的CRC-32组成。图7-8描述了DPP的格式。
7.2.1.2.1 数据包负载分帧符号 【Data Packet Payload Framing】
DPP分帧符号包含8个K-符号,一个4符号的DPP起始帧有续集(DPP starting frame ordered set),以及一个4符号的结束帧有续集(ending frame ordered set)。正如图7-8所示,一个DPPSTART有续集,实际上是一个DPP起始帧有续集(DPP starting frame ordered set),包含3个连续的K符号SDP,紧跟一个K符号EPF。第二种类型,DPPABORT有续集,是一个DPP中止帧有续集(DPP aborting frame ordered set),包含2个连续的K-符号EDB(无效包结束,end of nullified packet),紧跟一个K-符号的EPF。DPPEND有续集用来指示一个常规的完整DPP的结束。DPPABORT有续集用来指示DPP的不正常结束。
7.2.1.2.2 数据包负载 【Data Packet Payload】
DPP部分包含0到1024数据字节,紧跟4字节的CRC-32。任何的提前中止DPP都应该包含一个DPPABORT有续集。DPP应该紧跟在其相应的DPH后面,中间不能有间隙。
CRC-32保护数据负载的数据完整性。CRC-32的实现定义如下:
- CRC-32多项式应该是04C1 1DB7h。
- CRC-32的初值应为FFFF FFFFh。
- CRC-32是对DPP的所有字节进行计算,不包括任何包的分帧符号。
- CRC-32计算应该从字节0的比特0开始,并继续到每个DPP字节的比特7。
- CRC-32的余数(remainder)应该被补偿(complemented)。
- CRC-32的残差(residual)应该为C704DD7Bh。【译注:校对概念的准确性!】
注意:在接收端,CRC-32的余数(remainder)加上偏移量FFFF FFFFh,会得到CRC-32的一个常量残差(residual)C704DD7Bh。
图7-9说明了CRC-32余数的生成。输出比特顺序列于表7-2中。
7.2.1.2.3 数据包头和数据包负载之间的间隙【Spacing Between Data Packet Header and Data Packet Payload】
在数据包头(DPH)和其相应的数据包负载(DPP)之间不应该有任何间隙。这显示在图7-10中。
在第7.2.4节将描述关于如何在链路层传送和接收头包的更多细节。
7.2.2 链路命令【Link Commands】
链路命令用于链路层的数据完整性,流程控制和链路电源管理。链路命令具有固定的8个符号长,并包含重复的符号来增加容错性。参考第7.3节更多细节。链路命令名称具有L-前缀,以便区分其是用于链路层的,并避免与包相冲突。
7.2.2.1 链路命令结构【Link Command Structure】
链路命令应该是8个符号长,并使用下面图7-11的格式构建。首先的4个符号,LCSTART,是链路命令起始帧有续集(link command starting frame ordered set),由3个连续的SLC紧跟EPF组成。其次的4个符号由一个两个符号的链路命令字(link command word)和其复制品(replica)组成。两个链路命令字都被加扰了(scrambled)。表7-3总结了,链路命令结构。
7.2.2.2 链路命令字定义【Link Command Word Definition】
链路命令字(Link command word)共16比特长,具有被5比特CRC-5(见图7-12)保护的11比特链路命令信息。11比特链路命令信息定义于表7-4。CRC-5的计算与图7-6中显示的链路控制字(Link Control Word)相同。
链路命令被定义用于4种使用方式。第一,链路命令被用于确保包的成功传输。第二,链路命令被用于链路流程控制(link flow control)。第三,链路命令被用于电源管理。最后,一个特殊的链路命令被定义用于上游面端口在U0下展示其存在(an upstream port to signal its presence in U0)。
链路伙伴之间的成功头包事务要求恰当的头包确认(header packet acknowledgement)。Rx头包缓冲信用交换(Rx Header Buffer Credit exchange)有益于链路流程控制。头包确认和Rx头包缓冲信用交换由不同的链路命令来实现。LGOOD_n (n = 0 to 7) 和 LBAD被用于确认一个头包是否已经被恰当接收。LRTY被用于通知头包已经被重传(re-sent)。 LCRD_A, LCRD_B, LCRD_C, 以及LCRD_D被用于通知Rx Header Buffers已经可用,按信用而言(terms of Credit)。在下面的小节中,使用LCRD_x,其中x指代A, B,C, 或者D。参见表7-5的详情。
LGOOD_n使用一个明确的叫做头包序列号(Header Sequence Number)的数字索引来表示头包的顺序。头包序列号(Header Sequence Number)以0开始,并且每个头包都基于模8加法(modulo-8 addition)增加1。索引相应于接收到的头包序列号(Header Sequence Number),用于流程控制以及检测丢失或者破损的头包。
LCRD_x使用明确的以字母顺序的索引(alphabetical index)。索引A, B, C, D, A, B, C…在每个头包被处理并且Rx头包缓冲信用(Rx Header Buffer Credit)可用时被递增1。该索引用于确保Rx头包缓冲信用(Rx Header Buffer Credit)被按照顺序接收到,这样丢失一个LCRD_x就可以被检测出来。
LBAD 以及 LRTY 不使用索引。
LGO_U1, LGO_U2, LGO_U3, LAU, LXU, 以及LPMA是用于链路电源管理的链路命令。
LUP是一个特殊的链路命令,被上游面端口用于在U0时指示其端口的存在。关于LUP的使用在表7-5中描述。
更多的关于使用链路命令的要求和示例可以在第7.2.4节找到。
Table 7-5. Link Command Definitions
链路命令 |
定义 – 见第7.2.4.1, 7.2.4.2, 以及7.5.6节中详细的使用和要求 |
LGOOD_n |
n (0, 1, 2, ....7 ):头包序列号(Header Sequence Number)
由接收到头包的端口在下列所有条件都是真时发送: • 头包具有有效的结构并可以被接收器识别。 • CRC-5 和CRC-16 都有效。 • 接收到的头包中的头包序列号(Header Sequence Number)与所期望的Rx头包序列号(Rx Header Sequence Number)匹配。 • 在接收器端具有Rx头包缓冲(Rx Header Buffer)可用来存储接收到的头包。
接收到的头包中的头包序列号(Header Sequence Number)与所期望的Rx头包序列号(Rx Header Sequence Number)不匹配将会导致端口转换进入Recovery。
由发送头包的端口所接收到。这是从链路伙伴来的对具有头包序列号(Header Sequence Number)为"n"的头包已经被恰当接收到的确认。接收到LGOOD_n而不匹配所期望的ACK Tx头包序列号(ACK Tx Header Sequence Number)将会导致端口转换进入Recovery。
也可以被端口在进入U0时发送,作为头包序列号广告(Header Sequence Number Advertisement)来初始化两个端口的ACK Tx头包序列号(ACK Tx Header Sequence Number)。
参考第7.2.4.1节中的详情。 |
LBAD |
不好的头包(Bad header packet)。
由接收头包的端口在响应无效头包时发送。接收到的包的CRC-5和/或CRC-16被损坏。接收到LBAD 将导致端口重新发送在最后一次被LGOOD_n确认之后的所有的头包。
参考第7.2.4.1节中的详情。 |
LCRD_x |
x (A, B, C, D):Rx头包缓冲信用索引(Rx Header Buffer Credit Index)。
通知一个Rx头包缓冲信用(Rx Header Buffer Credit)已经可用。
由端口在接收到满足下面情形的头包时发送: • LGOOD_n已经被或者即将被发送【已勘误】。 • 头包已经被处理,并且Rx Header Buffer Credit 已经可用。
LCRD_x 按照字母顺序发送,并且绕回到A,没有跳跃。丢失LCRD_x 将会导致链路转换进入Recovery。
参考第7.2.4.1节中的详情。 |
LRTY |
由端口在响应接收到的LBAD而重新发送第一个头包之前发送。 |
LGO_U1 |
由请求进入U1的端口发送。 |
LGO_U2 |
由请求进入U2的端口发送。 |
LGO_U3 |
由请求进入U3的下游面端口发送。上游面端口应该接受该请求。 |
LAU |
由接受进入U1,U2或者U3的端口发送。 |
LXU |
由拒绝进入U1或U2的端口发送。 |
LPMA |
由端口在接收到LAU时发送。用来配合(in conjunction with)LGO_Ux以及LAU握手来保证两个端口都处于相同状态。 |
LUP |
设备在U0时存在。由上游面端口在没有包或者其他链路命令要被传输时,每隔10 μs 发送一次。参考7.5.6.1节中的详情。 |
7.2.2.3 链路命令的放置【Link Command Placement】
链路命令的放置应该满足下面的规则:
• 链路命令不应该被放置在头包结构内部(例如, 在LMPs, TPs, ITPs, 或者DPHs内部)。
• 链路命令不应该被放置在DP结构的DPP内部。
• 链路命令不应该被放置在DPH和DPP之间。
• 链路命令可以被放置在头包之前或者之后,除了不能被放置在DPH和DPP之间例外。
• 多个链路命令被允许背靠背(back to back)传输。
• 链路命令不能在所有已经调度的SKP有续集被全部传完之前被发送。
注意:在第10.7.5到10.7.12节中可以找到关于调度链路命令的更多规则。
7.2.3 逻辑空闲【Logical Idle】
逻辑空闲(Logical Idle)定义为一段长为一个或者多个符号周期的时间,期间没有信息(包或链路命令)正被在链路上传输。一个特殊D-符号(00h),定义为空闲符号【Idle Symbol (IS)】,只要在U0状态任何时间满足逻辑空闲定义,就应该被端口传送。该IS应该被按照第6.4.3节定义的规则加扰。
7.2.4 链路命令用于流程控制,错误恢复以及电源管理
链路命令被用于链路层的头包流程控制(flow control),来识别丢失或者损坏的头包,并发起/确认链路层的电源管理的转换。每个链路命令的构造和描述在第7.2.2节中可以找到。
7.2.4.1 头包链路控制和错误恢复【Header Packet Flow Control and Error Recovery】
头包链路控制(Header packet flow control)被用于所有的头包。它要求链路的每端都遵循特定的头包缓冲和传输顺序的限制(specific header buffer and transmission ordering constraints),以保证包的成功传输和链路互操作。本节详细地描述包流程控制(packet flow control)的规则。
7.2.4.1.1 初始化【Initialization】
链路初始化(link initialization)是指一旦链路从Polling,Recovery,或者Hot Reset转换进入U0时对端口的初始化。该初始化包括在两个端口之间(在能够传送包之前)进行头包序列号宣告(Header Sequence Number Advertisement)以及Rx头包缓冲信用宣告(Rx Header Buffer Credit Advertisement)。
• 下面的要求应该被应用于端口:
1. 端口应该维护两个Tx Header Sequence Numbers。一个是Tx Header Sequence Number,定义为当一个头包被首次传送时(不是重传)被指派给头包的Header Sequence Number。另一个是ACK Tx Header Sequence Number,定义为将要被接收到头包的端口使用LGOOD_n确认时所期望的Header Sequence Number。
2. 端口应该有一个Rx Header Sequence Number,定义为当端口接收一个头包时所期望的Header Sequence Number。
3. 端口应该维护两个Rx Header Buffer Credit Counts。一个是Local Rx Header Buffer Credit Count,定义为其接收器可用的Rx Header Buffer Credits的个数。另一个是Remote Rx Header Buffer Credit Count,定义为其链路伙伴的可用Rx Header Buffer Credits的个数。
4. 端口应该有足够的Tx Header Buffers在其发射器中,以便能保持达4个未被确认的头包(unacknowledged header packets)。
5. 如果其Remote Rx Header Buffer Credit Count为0,则端口不应该传送任何头包。
6. 端口应该有足够的Rx Header Buffers在其接收器中,以便能接收达4个头包。
7. 当进入U0时,应该按顺序执行如下动作:
a. 端口应该启动一个PENDING_HP_TIMER和CREDIT_HP_TIMER,以期待Header Sequence Number Advertisement以及Rx Header Buffer Credit Advertisement。
b. 端口应该启动Header Sequence Number Advertisement。
c. 端口应该启动Rx Header Buffer Credit Advertisement。
• Header Sequence Number Advertisement是指ACK Tx Header Sequence Number的初始化,通过在两个端口之间交换 Header Sequence Numbers来完成。这个Header Sequence Number是该端口在上一次恰当接收到的头包的Header Sequence Number。Header Sequence Number Advertisement的主要目的是在Recovery前后维持链路流程(link flow),以便再次进入U0的端口知道在Recovery之前成功被发送的头包,并决定在其Tx Header Buffers中哪些头包可以被清空(flushed)或者被重传。在Header Sequence Number Advertisement中应该适用如下规则:
1. 端口应该按照如下定义来设置其初始Rx Header Sequence Number:
a. 如果端口是从Polling或Hot Reset进入U0,则Rx Header Sequence Number为0。
b. 如果端口从Recovery进入U0,则Rx Header Sequence Number是期待的下一个头包的Header Sequence Number。
2. 端口应该按照如下定义来设置其初始Tx Header Sequence Number:
a. 如果端口是从Polling或Hot Reset进入U0,则Tx Header Sequence Number为0。
b. 如果端口从Recovery进入U0,则Tx Header Sequence Number与Recovery之前的Tx Header Sequence Number相同。
注意:被重传的头包应该维持其原先被指派的Header Sequence Number。
3. 端口应该通过传送LGOOD_n ("n"等于Rx Header Sequence Number减1)来启动Header Sequence Number Advertisement。
注意:递减是基于模8操作。
4. 端口应该设置其初始ACK Tx Header Sequence Number等于在Rx Header Sequence Number Advertisement中接收到的Sequence Number加上1。
注意:递增是基于模8操作。
5. 直到接收到了Header Sequence Number Advertisement,并且有一个Remote Rx Header Buffer Credit可用之前,端口不能发送任何头包。
6. 端口在接收以及发送Header Sequence Number Advertisement之前,不应该请求低功耗链路状态的进入(low power link state entry)。
注意:关于低功耗链路状态的发起(Low Power Link State Initiation)的规则依然适用(参考第7.2.4.2节)。
7. 当接收到Header Sequence Number Advertisement时,端口应该清空(flush)其Tx Header Buffers中的头包。端口应该执行下列之一:
a. 如果端口是从Polling或Hot Reset进入U0,它应该清空(flush)其Tx Header Buffers中的所有头包。
b. 如果端口从Recovery进入U0, 它应该清空(flush)其Tx Header Buffers中在Recovery之前已经发送过的所有头包,除了其中的Header Sequence Number大于(模8)Header Sequence Number Advertisement中所接收到的Header Sequence Number的那些头包。
注意:举例,如果接收到为LGOOD_1的Header Sequence Number Advertisement,端口应该清空(flush)其Tx Header Buffers中的Header Sequence Numbers为1, 0, 7, 6的头包。
• Rx Header Buffer Credit Advertisement是指Remote Rx Header Buffer Credit Count的初始化,通过在两个端口之间交换可用的Local Rx Header Buffer Credits的个数而完成。这一宣告的主要目的是让端口在进入U0时使其Remote Rx
Header Buffer Credit Count与其链路伙伴一致。在Rx Header Buffer Credit Advertisement期间,适用于下面的规则:
1. 在Header Sequence Number Advertisement期间,端口应该在发送LGOOD_n之后,发起Rx Header Buffer Credit Advertisement【已勘误】。
2. 在发送Rx Header Buffer Credit之前,端口应做如下初始化:
a. 端口应该初始化其Tx Header Buffer Credit index 为 A.
b. 端口应该初始化其Rx Header Buffer Credit index 为 A.
c. 端口应该初始化其Remote Rx Header Buffer Credit Count 为 0.
d. 端口应该继续处理在Rx Header Buffers中的头包(这些头包已经在进入Recovery之前被用LGOOD_n确认,或者在Recovery期间被验证为有效),并更新Local Rx Header Buffer Credit Count。
e. 端口应按如下定义设置其Local Rx Header Buffer Credit Count:
1. 如果端口是从Polling或Hot Reset进入U0,则其Local Rx Header Buffer Credit Count为4。
2. 如果端口从Recovery进入U0,则其Local Rx Header Buffer Credit Count是可以用于容纳输入头包的Rx Header Buffers的个数。
3. 端口应该通过传输LCRD_x来执行Rx Header Buffer Credit Advertisement来通知其链路伙伴。端口应该基于其
Local Rx Header Buffer Credit Count来做如下传送:
a. 如果Local Rx Header Buffer Credit Count是1, 则传送LCRD_A。
b. 如果Local Rx Header Buffer Credit Count是2, 则传送LCRD_A和LCRD_B。
c. 如果Local Rx Header Buffer Credit Count是3, 则传送LCRD_A,LCRD_B和LCRD_C。
d. 如果Local Rx Header Buffer Credit Count是4, 则传送LCRD_A,LCRD_B,LCRD_C和LCRD_D。
4. 从其链路伙伴处接收LCRD_x的端口应该在每次接收到LCRD_x时,将其Remote Rx Header Buffer Credit Count增加1,直到4。
5. 如果其Remote Rx Header Buffer Credit Count为0,端口不应该传送任何头包。
6. 在Rx Header Buffer Credit Advertisement期间,在接收和发送LCRD_x之前,端口不应该请求低功耗链路状态的进入(low power link state entry)。
注意:低功耗链路状态的发起(Low Power Link State Initiation)规则(参考第7.2.4.2节)依然适用。
• 当端口从Recovery进入U0时,下面的附加规则应该被应用于端口:
1. 在Recovery之前发送了LBAD的端口,不应期望(shall not expect)在进入U0时能在一个被重试的头包之前接收到LRTY。
2. 在Recovery之前接收到LBAD的端口,不应该在进入U0时在发送被重试的头包之前发送LRTY。
注意:存在一种情形,一个端口在Recovery之前发送了一个LBAD,但是它可能会,也可能不会被其链路伙伴接收到。在这种情形下,LBAD/LRTY的规则就不适用。参考第7.2.4.1.4节和第7.2.4.1.9节的详情。
3. 上行端口可以在链路初始化期间发送LUP。
• 一旦进入Recovery,而下一个状态是Hot Reset 或者 Loopback,端口可以可选地继续处理被恰当接收到的所有包。
7.2.4.1.2 LGOOD_n和LCRD_x用法的总体规则
• Rx Header Buffer Credit应该以字母顺序被传送,LCRD_A,LCRD_B,LCRD_C,LCRD_D,然后返回到LCRD_A。没有按照字母顺序接收到LCRD_x被认为是丢失了链路命令,应该启动转换到Recovery。
• 头包应该以Header Sequence Number的数字顺序发送,从0到7,并返回到0。没有按照数字顺序接收到LGOOD_n被认为是丢失了链路命令,应该启动转换到Recovery。
• 头包的传送可以被延迟(delayed)。当这发生时,集线器应该将链路控制字(Link Control Word)的DL位置位(外围设备或者主机可选)。一些(但不一定是全部)可能导致这一延迟的条件如下:
1. 当头包被重新发送(resent)。
2. 当链路处于Recovery。
3. 当Remote Rx Header Buffer Credit Count为0。
4. 当Tx Header Buffer非空。
注意:延迟(delayed)位(DL位)只有在ITP中被设置时才有影响(significance)。如果设备使用ITP来同步其内部时钟,则它应该忽略延迟(delayed)位(DL位)被设置的所有ITPs【已勘误】。
7.2.4.1.3 发送头包【Transmitting Header Packets】
• 在发送一个头包之前,端口应该相应于链路控制字(Link Control Word)的Header Sequence Number字段来增加Tx Header Sequence Number。
• 传送一个头包将消耗一个Tx Header Buffer。相应地,在传送完毕后,Tx Header Sequence Number应该被加1,或者在已经达到最大Header Sequence Number时回滚到0。
• 传送一个被重试的头包不会消耗附加的Tx Header Buffer,且Tx Header Sequence Number应该保持不变。
• 当接收到LBAD时,端口应该发送LRTY,紧跟着再重传还没有被LGOOD_n确认的所有头包,除了Recovery之外。参考第7.2.4.1.1节关于端口从Recovery进入U0时可适用的更多规则。
• 在重传头包之前,端口应该设置链路控制字(Link Control Word)中的Delay位(DL位),并重新计算CRC-5。
注意:头包中的CRC-16保持不变。
• 如果接收到了有效的LCRD_x,则Remote Rx Header Buffer Credit Count应该增加1。
• 如果在进入U0后一个头包被首次发送(包括在Recovery后它被重传),Remote Rx Header Buffer Credit Count应该被减1。
• 当头包在LRTY后被重试时,Remote Rx Header Buffer Credit Count不应该被改变。
7.2.4.1.4 接收头包【Receiving Header Packets】
• 当接收到头包时,应该执行下列验证:
1. CRC-5
2. CRC-16
3. 匹配接收到的头包中的Header Sequence Number和Rx Header Sequence Number。
4. 用以存储头包的Rx Header Buffer的可用性
• 当上面描述的所有条件都通过时,头包被定义为"恰当接收(received properly)"。
• 当一个头包被恰当接收时,端口应该发送一个LGOOD_n ,其中"n"相应于Rx Header Sequence Number,并将Rx Header Sequence Number递增1(或者在达到最大Header Sequence Number时回滚至0)。
• 端口将消耗一个Rx Header Buffer,直到头包被处理。
• 当头包没有被"恰当接收"时,下列之一将发生:
1. 如果头包有一个或多个CRC-5或CRC-16错误,端口应该发出一个LBAD。端口应该忽略所有后续的头包,直到接收到一个LRTY,或者链路已经进入Recovery。参考第7.2.4.1.1节关于端口从Recovery进入U0时可适用的更多规则。
2. 如果接收到的头包中的Header Sequence Number和Rx Header Sequence Number不匹配,或者端口没有可供用来存储头包的Rx Header Buffer,端口应该转换到Recovery。
• 在传送LBAD之后,如果有Rx Header Buffer Credit变得可用,端口应该继续发送LCRD_x。
• 如果连续3次接收头包失败,端口应该直接转换进入Recovery。端口在第3次错误时不应该发送第3个LBAD。
7.2.4.1.5 Rx头包缓冲信用【Rx Header Buffer Credit】
每个端口都要求有4个Rx Header Buffer Credits在其接收器中。这是指Local Rx Header Buffer Credit。Local Rx Header Buffer Credits的个数代表端口能够接受的头包的个数,并由Local Rx Header Buffer Credit Count来管理。
• 如果一个头包被"恰当接收",端口应该消耗一个Local Rx Header Buffer Credit。Local Rx Header Buffer Credit Count应该被递减1。
• 当完成处理一个头包,端口应该这样恢复一个Local Rx Header Buffer Credit:
1. 发送一个LCRD_x
2. 以字母序步进Credit index(或者Header Buffer Credit index到达D时回滚至A)
3. 将Local Rx Header Buffer Credit Count递增1。
注意:LCRD_x index被用来确保Rx Header Buffer Credits被以字母顺序发送,从而丢失一个LCRD_x可以被检测出来。
7.2.4.1.6 接收数据包负载【Receiving Data Packet Payload】
DPP的处理应该遵循如下规则:
• 如果满足下列两个条件,DPP应该被接受:
1. DPH被恰当接收。
2. DPPStart有序集紧跟其DPH之后被恰当接收。
• 当检测到有效的DPPEND时,应该完成DPP处理。
• 当满足下列条件时,DPP应该被中止:
1. 检测到一个有效的DPPABORT有序集。
2. 在一个有效的DPPEND或DPPABORT有序集之前,检测到一个既不属于DPPEND也不属于DPPABORT有序集的K-符号。端口应该忽略相应的与该DPP相关联的DPPEND或DPPABORT有序集。
3. DPP长度已经超过sDataSymbolsBabble【已勘误】 (见表10-15),并且还没检测到有效的DPPEND或DPPABORT有序集。
• 如果DPH被损坏了,DPP应该被丢掉。
• 当DPP没有紧跟其DPH时,DPP应该被丢掉。
7.2.4.1.7 接收LGOOD_n 【Receiving LGOOD_n】
• 端口应该在其Tx Header Buffer 保持每一个被发送过的头包,直到它接收到一个LGOOD_n。当接收到一个LGOOD_n时,端口应该做如下事项:
1. 如果该LGOOD_n是Header Sequence Number Advertisement,并且端口是从Recovery进入U0,则端口应该清空Tx Header Buffers中所保持的Header Sequence Numbers小于或等于所接收到的Header Sequence Number的头包,并且将其ACK Tx Header Sequence Number初始化成所接收到的Header Sequence Number加上1。
注意:比较和递增是模8操作。
2. 如果端口接收到一个LGOOD_n,但是该LGOOD_n不是Header Sequence Number Advertisement,则它应该清空其Tx Header Buffer中Header Sequence Number与接收到的Header Sequence Number一致的头包,并基于模8操作将ACK Tx Header Sequence Number递增1。
3. 如果端口接收到一个LGOOD_n,但是该LGOOD_n不是Header Sequence Number Advertisement,如果接收到的如果端口接收到一个LGOOD_n,但是该LGOOD_n不是Header Sequence Number Advertisement不匹配ACK Tx Header Sequence Number,则端口应该转换到Recovery。ACK Tx Header Sequence Number应该不变。
注意:接收到乱序的LGOOD_n意味着丢失或者损坏了链路命令,从而应该转换进入Recovery。
7.2.4.1.8 接收LCRD_x 【Receiving LCRD_x】
• 端口应基于接收到的LCRD_x来调整其Remote Rx Header Buffer Credit Count:
1. 当接收到LCRD_x 时,端口应该将其Remote Rx Header Buffer Credit Count递增1。
2. 如果接收到乱序的LCRD_x,端口应该转换进入Recovery。
注意:接收到乱序的信用(credit)意味着丢失或者损坏了链路命令,从而应该转换进入Recovery。
7.2.4.1.9 接收LBAD 【Receiving LBAD】
• 当接收到LBAD时,端口应该发送一个LRTY,紧跟着再重传其Tx Header Buffers中还没有被LGOOD_n确认的所有头包。集线器应该在所有被重传的头包的链路控制字(Link Control Word)中设置DL位,并重算CRC-5。主机或者外围设备可以可选地在所有被重传的头包的链路控制字(Link Control Word)中设置DL位,并重算CRC-5。如果被重传的包是DP,并且其置DL位是空的,则DPH后面应该紧跟一个DPP【已勘误】。
注意:重传ITP使得等时时间戳值无效(invalidates the isochronous timestamp value)。在被重传的头包中CRC-16不变。
• 在接收到LBAD时,如果在Tx Header Buffers中没有未被确认的头包,端口(依然)应该发送一个LRTY。
注意:这是一个错误情形,LBAD是由于链路错误而创建的。
7.2.4.1.10 发送器定时器【Transmitter Timers】
PENDING_HP_TIMER被指定用来覆盖从一个头包被发送给链路伙伴到该头包被链路伙伴确认的时间周期。该时间限制的目的是为了允许端口检测由其链路伙伴所发送的头包确认(header packet acknowledgement)是否丢失了或者损坏了。PENDING_HP_TIMER的超时值被列于表7-7中。PENDING_HP_TIMER的操作应该基于以下规则:
• 端口应该只在U0期间并且下列条件其中之一被满足时有一个活跃的PENDING_HP_TIMER:
1. 端口已经发送了一个头包,但是还没有被其链路伙伴确认 (除了在接收到LBAD之后到重传Tx Header Buffer中最老的头包之间的一段时间)。
2. 端口正在期待从其链路伙伴来的头包序列号宣告(Header Sequence Number Advertisement)。
• PENDING_HP_TIMER应该在下列条件之一被满足时被启动:
1. 当端口进入U0,期望头包序列号宣告(Header Sequence Number Advertisement)。
2. 当一个头包被发送,并且Tx Header Buffers中之前没有已经被发送而没被确认的头包。
3. 当响应LBAD 而重传最老的头包(oldest header packet)时。
• 当一个头包被LGOOD_n确认,而在Tx Header Buffers中还有已经被发送而没被确认的头包时,PENDING_HP_TIMER应该被复位并重启。
• 当下列条件之一被满足时,PENDING_HP_TIMER应该被复位并停止:
1. 当接收到头包序列号宣告(Header Sequence Number Advertisement)时。
2. 当一个头包确认LGOOD_n被收到且Tx Header Buffers中所有已经发送的头包都已经被确认时。
3. 当一个头包确认LBAD被收到时。
• 如果下面两个条件被满足,则端口应该转换到Recovery:
1. PENDING_HP_TIMER超时。
2. 向外的头包(outgoing header packet)的传输被完成,或者向外的DPP(outgoing DPP)的传输要么被DPPEND完成,要么被DPPABORT终结。
注意: 这是为了允许优雅的(graceful)转换进入Recovery,而不会使得头包被截断(truncated)。
还指定了一个CREDIT_HP_TIMER,用来覆盖当一个头包已经被发送且其远端Rx头包缓冲信用(Remote Rx Header Buffer Credit)的个数少于4,到接收到一个Remote Rx Header Buffer Credit,并且其Remote Rx Header Buffer Credit个数返回到4,之间的一段时间。这个定时器的目的是为了确保一个Remote Rx Header Buffer Credit在合理的时间限度内被收到。这可以允许发送头包的端口在一定的时间限度内回收(reclaim)一个Remote Rx Header Buffer Credit,以便可以继续处理包传输。 这也可以允许一个接收头包的端口由足够的时间来处理头包。CREDIT_HP_TIMER 的超时值被列于表7-7。CREDIT_HP_TIMER 的操作应该基于下面的规则:
- 端口应该只在U0期间并且下列条件其中之一被满足时有一个活跃的CREDIT_HP_TIMER:
1. 端口的Remote Rx Header Buffer Credit Count 小于4。
2. 端口正在期待来自其链路伙伴的Header Sequence Number Advertisement 和Rx Header Buffer Credit Advertisement。
• 当一个头包或者被重试的头包被发送,或者端口进入U0时,CREDIT_HP_TIMER应该被启动。
• 当有效的LCRD_x被接收到时,CREDIT_HP_TIMER应该被复位。
• 当有效的LCRD_x被接收到,并且Remote Rx Header Buffer Credit Count小于4时,CREDIT_HP_TIMER应该被重启。
-
如果下面两个条件被满足,则端口应该转换到Recovery:
- CREDIT_HP_TIMER超时。
2. 向外的头包(outgoing header packet)的传输被完成,或者向外的DPP(outgoing DPP)的传输要么被DPPEND完成,要么被DPPABORT终结。
注意: 这是为了允许优雅的(graceful)转换进入Recovery,而不会使得头包被截断(truncated)。