PCI Express学习篇---链路层(一)ACK/NAK协议介绍

2024-03-15 00:30

本文主要是介绍PCI Express学习篇---链路层(一)ACK/NAK协议介绍,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

声明:此文章为原创,转载请注明 转自https://blog.csdn.net/weixin_48180416/article/details/117390013

数据链路层是为了保障TLP包的可靠传输,尽管Spec中规定了误码率小于10^-12,但是仍然会发生错误带来一些问题,单个bit的错误会使整个数据包被损坏。速率的提升会使这个问题更加显著。

为了实现链路层的保护,引入错误检测的编码---LCRC,计算范围是Sequence Number+TLP header+payload+ECRC。

接收端需要检查LCRC是否正确,Sequence Number是否正确,Receiver端通过ACK包告知接收到了正确的TLP包,通过NAK告知接收到了错误的TLP包。

以下介绍实现ACK/NAK协议的组件


发送端:

  • NEXT_TRANSMIT_SEQ: 记录下一个要发送的Sequence Number的值,最大值是4095之后会回0;
  • LCRC Generator: 产生32bit CRC, 计算范围包含TLP和Seq;
  • Replay Buffer: 按照发送的顺序存储TLP,包含Seq(2B)+Header(up to 16B)+Optional Payload(up to 4KB)+Optional ECRC(4B)+LCRC(4B),当收到ACK时会清除replay buffer内Seq小于或等于ACK包Seq的TLP,设计中允许一个ACK代表多个成功的TLP;当收到NAK时会清除replay buffer内Seq小于或等于NAK包Seq的TLP(因为NAK记录的是最后一个正确TLP的Seq),然后重传replay buffer中的所有TLP;
  • REPLAY_TIMER: 实质上是一个看门狗计数器,当timeout时还是没有收到ACK/NAK包就会replay并且restart;
  • REPLAY_NUM: 2bit Counter, 记录重传的次数,当从11 roll over到00(说明replay了4次),数据链路层就会自动force物理层重新训练状态机(LTSSM会进入Recovery状态);
  • ACKD_SEQ: 12bit寄存器,存储着最近收到的ACK/NAK的Seq,如果收到的ACK/NAK是"later Sequence Number"(可能存在4095->0 roll over的情况)可以认为是forward progress, 这个时候就可以清除replay buffer里面的TLP(replay buffer Seq <= ACK/NAK Seq),复位REPLAY_TIMER和REPLAY_NUM;
  • DLLP CRC Check: 检查DLLP的16bit CRC, 如果检测到错误,DLLP会丢弃并且会报告Correctable Error,DLLP包没有重传和校正的机制,只能期待下一个成功的ACK/NAK DLLP。

注:NEXT_TRANSMIT_SEQ - ACKD_SEQ不允许大于总Counter的一半,例如NEXT_TRANSMIT_SEQ - ACKD_SEQ = 2048时,链路层就不会从事务层接收TLP,直到有新的回应。如果发生了超过一半的情况,数据链路层会报告protocol error。

接收端:

收到的TLP会先检查LCRC错误,然后检查Sequence Number。如果没有错误的话TLP会传递到事务层,如果有错误,TLP会丢弃并且scheduled NAK除非已经有NAK outstanding。

  • LCRC Error Check:检查LCRC错误,如果计算的LCRC和TLP的LCRC不匹配,说明TLP中有bit错误,就会丢弃TLP并且发NAK;
  • NEXT_RCV_SEQ(NRS): 12bit计数器,跟踪下一个期待接收的Seq Num, TLP有CRC错误或无效包("nullified")或Seq Num Check有错误,就不会传到事务层,并且不会增加这个计数器;
  • Sequence Number Check:检查完LCRC OK后,检查接收的TLP Seq Num与NRS是否一致,存在以下三种情况:
  1. TLP Seq Num equal NRS:Good TLP,是正确的情况,当AckNak_LATENCY_TIMERS expire时,发送ACK包,包含最后一包good TLP的Seq Num(即NRS-1);
  2. TLP Seq Num earlier than NRS: Duplicate TLP,是以前发送过的重复包,NRS - TLP Seq Num不超过2048,不认为是错误,silently dropped并且发送一个带有Seq Num为(NRS-1)的ACK包;
  3. TLP Seq Num later than NRS: Invalid TLP,发生丢包的情况,会发送Nak,如果没有Nak outstanding。

由于4095后Seq Num会roll over,所以实际的范围是这样定义的:(以NRS=30/31/32为例)

  • NAK_SCHEDULED Flag: 当接收端schedule NAK的时候会置此标志位为1,当成功发送了一个带有Seq Num为(NRS-1)的NAK包后清零。目的是有outstanding NAK就不需要再发送NAK包;
  • AckNak_LATENCY_TIMER:接收到一个正确TLP后开始计数,当timer expire会发送一个带有Seq Num为(NRS-1)的ACK包,当发送了ACK或NAK包后复位;
  • Ack/Nak Generator: ACK/NAK中的Seq Num都是NRS-1,格式如下:

发送接收端具体实现细节


发送端:

  • Sequence Number:从事务层发往链路层,首先需要加入Sequence Number,Seq Num可能会roll over;
  • 32bit LCRC: 加入LCRC,范围是Seq Num+TLP;
  • Response to ACK DLLP: 把收到的ACK的Seq load到ACKD_SEQ中,复位REPLAY_TIMER和REPLAY_NUM,清除Replay buffer中的<=SEQ NUM的TLP;
  • Response to NAK DLLP:把收到的NAK的Seq load到ACKD_SEQ中,复位REPLAY_TIMER和REPLAY_NUM,清除Replay buffer中的<=SEQ NUM的TLP,重放buffer中剩余的包;

接收端:

  • Physical Layer: TLP接收在物理层检测到receiver error(framing,disparity, invalid symbols)如果告知链路层,链路层发NAK包并重放TLP包,如果不告知链路层,链路层也会因为Seq Num丢包而发NAK包并重放TLP包;
  • LCRC Check:检查LCRC错误,如果计算的LCRC和TLP的LCRC不匹配,说明TLP中有bit错误,就会丢弃TLP并且发NAK;
  • Next Received TLP's Sequence Number: 如果LCRC正确,会比较接收到的TLP的Seq Num和NRS;
  • Receiver Schedules a ACK:  AckNak_LATENCY_TIMER expire后发送一个ACK,含有NRS-1的Seq Num;
  • Receiver Schedules a NAK: 虽然发送端需要立刻发送NAK(因为后面的接收的其他TLP也会丢弃),但是其他的已经再处理的TLP, DLLP, Order Set优先级更高,NAK会等到它们都完成再发,同时,如果其他接收的TLP丢弃,由于NAK_SCHEDULED flag=1,就不会再有额外ACK/NAK schedule。

Replay Number Rolls Over


当REPLAY_TIMER由于没有接收到ACK或NAK而expire,replay过程可以被重复3次,如果重复大于3次,REPLAY_NUM就会从3 roll over至0.

  • 如果发生这种情况一定是链路存在一些问题,链路层就会触发物理层重新训练链路(LTSSM进入Recovery状态机);
  • 如果使能AER会报Replay Number Rollover error错误;
  • Replay Buffer的内容会保持,数据链路层不会初始化(只是重新训练链路,不会复位链路);
  • 当链路训练完成后,transmitter会再重放,以期望问题能够解决;
  • Spec没有规定如何处理repeat rollover event, PCIe Technology3.0建议记录重新训练的次数,超过规定的次数后,通过Uncorrectable Fatal Error或者中断通知软件。

Transmitter DLLP Handling


Ack/Nak Error Checking模块检查ACK/NAK DLLP的16bit CRC是否存在错误,

  • 如果存在错误,DLLP会丢弃,DLLP包没有重传和校正的机制;
  • AER会报告Correctable Error;
  • 会使ACK之间的间隔变大,REPLAY_TIMER可能会expire,导致TLP replay。

Error Situations Handled by Ack/Nak


  • LCRC错误
  • TLP Losts(物理层检测到错误后丢包)
  • Ack/Nak包损坏
  • 没有接收到Ack/Nak包
  • Receiver fails to send Ack/Nak

上述情况的详细处理过程见(二)ACK/NAK实例博文。

Switch Cut-Through Mode


当TLP经过Switch的Ingress Port的时候,当没有收到TLP的整包的时候是没有办法判断LCRC是否正确的,通常情况下用到Store-Forward模式缓存整包,没问题再送到Egress Port,但是这样的情况大包会有很大的Latency,会影响性能。

为了提高性能可以采用Cut-Through模式,这种模式下Ingress Port可能会将TLP传给Egress Port后才会发现LCRC错误。

Cut-Though Mode提供一个解决方案:“nullified” TLP

  • 这种TLP的LCRC是invert(按位取反)+EDB;
  • 这种TLP本质上处理的时候“好像不存在一样”;
  • 在Egress Port,不存入replay buffer,NEXT_TRANSMIT_SEQ回滚-1;
  • 接收端的NRS不增加,AckNak_LATENCY_TIMER不启动, NAK_SCHEDULED不设置;
  • 接收端只是简单的丢弃此包,不需要返回ACK/NAK。

 

 

 

 

这篇关于PCI Express学习篇---链路层(一)ACK/NAK协议介绍的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/810223

相关文章

Java中HashMap的用法详细介绍

《Java中HashMap的用法详细介绍》JavaHashMap是一种高效的数据结构,用于存储键值对,它是基于哈希表实现的,提供快速的插入、删除和查找操作,:本文主要介绍Java中HashMap... 目录一.HashMap1.基本概念2.底层数据结构:3.HashCode和equals方法为什么重写Has

Unity新手入门学习殿堂级知识详细讲解(图文)

《Unity新手入门学习殿堂级知识详细讲解(图文)》Unity是一款跨平台游戏引擎,支持2D/3D及VR/AR开发,核心功能模块包括图形、音频、物理等,通过可视化编辑器与脚本扩展实现开发,项目结构含A... 目录入门概述什么是 UnityUnity引擎基础认知编辑器核心操作Unity 编辑器项目模式分类工程

Springboot项目构建时各种依赖详细介绍与依赖关系说明详解

《Springboot项目构建时各种依赖详细介绍与依赖关系说明详解》SpringBoot通过spring-boot-dependencies统一依赖版本管理,spring-boot-starter-w... 目录一、spring-boot-dependencies1.简介2. 内容概览3.核心内容结构4.

Python学习笔记之getattr和hasattr用法示例详解

《Python学习笔记之getattr和hasattr用法示例详解》在Python中,hasattr()、getattr()和setattr()是一组内置函数,用于对对象的属性进行操作和查询,这篇文章... 目录1.getattr用法详解1.1 基本作用1.2 示例1.3 原理2.hasattr用法详解2.

Java对接MQTT协议的完整实现示例代码

《Java对接MQTT协议的完整实现示例代码》MQTT是一个基于客户端-服务器的消息发布/订阅传输协议,MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛,:本文主要介绍Ja... 目录前言前置依赖1. MQTT配置类代码解析1.1 MQTT客户端工厂1.2 MQTT消息订阅适配器1.

Linux中的自定义协议+序列反序列化用法

《Linux中的自定义协议+序列反序列化用法》文章探讨网络程序在应用层的实现,涉及TCP协议的数据传输机制、结构化数据的序列化与反序列化方法,以及通过JSON和自定义协议构建网络计算器的思路,强调分层... 目录一,再次理解协议二,序列化和反序列化三,实现网络计算器3.1 日志文件3.2Socket.hpp

Linux中的HTTPS协议原理分析

《Linux中的HTTPS协议原理分析》文章解释了HTTPS的必要性:HTTP明文传输易被篡改和劫持,HTTPS通过非对称加密协商对称密钥、CA证书认证和混合加密机制,有效防范中间人攻击,保障通信安全... 目录一、什么是加密和解密?二、为什么需要加密?三、常见的加密方式3.1 对称加密3.2非对称加密四、

setsid 命令工作原理和使用案例介绍

《setsid命令工作原理和使用案例介绍》setsid命令在Linux中创建独立会话,使进程脱离终端运行,适用于守护进程和后台任务,通过重定向输出和确保权限,可有效管理长时间运行的进程,本文给大家介... 目录setsid 命令介绍和使用案例基本介绍基本语法主要特点命令参数使用案例1. 在后台运行命令2.

MySQL常用字符串函数示例和场景介绍

《MySQL常用字符串函数示例和场景介绍》MySQL提供了丰富的字符串函数帮助我们高效地对字符串进行处理、转换和分析,本文我将全面且深入地介绍MySQL常用的字符串函数,并结合具体示例和场景,帮你熟练... 目录一、字符串函数概述1.1 字符串函数的作用1.2 字符串函数分类二、字符串长度与统计函数2.1

zookeeper端口说明及介绍

《zookeeper端口说明及介绍》:本文主要介绍zookeeper端口说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、zookeeper有三个端口(可以修改)aVNMqvZ二、3个端口的作用三、部署时注意总China编程结一、zookeeper有三个端口(可以