Path Delay

Reference Documentation

product_line_custom
Intel® PAC
Napatech SmartNIC
category
Reference Information
Napatech Software Suite: Path Delay

Overview

An adapter uses time stamps for time-stamping incoming packets, and for sending packets at the correct time. When receiving a packet there is a delay from the time that a packet (frame) arrives and until the adapter time-stamps it. This delay is called the RX path delay. When transmitting a packet there is a delay from the time that the adapter releases a packet (frame) and until it is transmitted. This delay is called the TX path delay.

An application can retrieve the path delay from the driver. A path delay is an integer value in nanoseconds. The delay information may not always be available, and an application must be ready to handle that situation.

When delay information is available, the application can subtract the RX path delay from the time stamp in a packet descriptor to calculate when an incoming packet (frame) arrived at the port. When using global sync mode, the application can adjust for the TX path delay when calculating the value of the single TX clock origin.

To use the feature properly, an application must query the delay when the link speed changes, or a NIM module is inserted. The system provides suitable events for this purpose, see Detecting Link Speed Change or New NIM Module.

API

An application can use the information stream to retrieve the path delays for a port.

  • The information stream provides access to path delays. An application must use the NtInfo_t structure and set the cmd member to NT_INFO_CMD_READ_PATH_DELAY command and the NtInfoCmdPortPathDelay_s command structure to retrieve the path delay for a port. The application should set the direction member to NT_PATH_DELAY_RX_DIR or NT_PATH_DELAY_TX_DIR to retrieve the RX and TX path delays, respectively. Section Example Program contains a simple example program that retrieves the RX and TX delays for port number zero.
  • RX and TX path delays are kept separate in the API. This means that an application cannot retrieve both types of delays for a given port at the same time.
  • The API returns a delay value and a status code via the NtInfoPortPathDelay_s structure. The member status provides the status code, and the member is the returned delay. The status code is an enumeration NtPathDelayStatus_e that indicates whether the delay value is valid. The returned value is an integer, which is the path delay in nanoseconds.
  • The returned delay is a single value that is the sum of the adapter and the NIM module contributions, or in some cases only the adapter delay without the NIM module delay. An application must use the status code to interpret the delay value correctly. Section Path Delay Status Codes describes the meaning of the return codes.
  • Status code NT_PATH_DELAY_SUCCESS means the link is up, and the driver has recognized the adapter/FPGA and the installed NIM modules. The returned delay value is the sum of the adapter and NIM module delays.
  • Status codes NT_PATH_DELAY_LINK_DOWN and NT_PATH_DELAY_NOT_SUPPORTED mean the delay value is unavailable. If the staus code is NT_PATH_DELAY_LINK_DOWN, an application may try to retrieve the delay value later, or it can catch the NT_EVENT_PORT_LINK_UP event.
  • Status code NT_PATH_DELAY_UNKNOWN_NIM means the link is up, and the driver has recognized the adapter/FPGA but not the NIM module. The returned delay value is without the NIM module delay.
Note
Observe the limitations in the current implementation.

Path Delay Status Codes

The status code is the status member of the NtInfoPortPathDelay_s structure.

Path Delay Status Codes
Code Meaning
NT_PATH_DELAY_LINK_DOWN Link is down, no delay to return, not even if the NIM module is optical.
NT_PATH_DELAY_NOT_SUPPORTED No delay available for the FPGA version. It is undefined whether the NIM module is known.
NT_PATH_DELAY_SUCCESS Link is up and FPGA and NIM modules are known.
NT_PATH_DELAY_UNKNOWN_NIM NIM is unknown but the FPGA version is known. The returned delay does not contain any contribution from the NIM module.

Detecting Link Speed Change or New NIM Module

The path delay depends on the link speed and NIM module type, and an application must retrieve the delay whenever the link speed changes, or the NIM module is replaced. This is also true if the same NIM is removed and reinserted.

An application can catch the NT_EVENT_PORT_NIM_REMOVED and NT_EVENT_PORT_NIM_INSERTED events to detect replacement of a NIM module, but although a NIM is a requisite for a network link, it is not until the link is up, and the link speed is set, that the correct path delay is available. Remember that the path delay depends on the NIM module type and link speed. An application can, and must, detect whenever a link goes down, and when the link is up again; the application must retrieve the path delay (again). An application can detect a change of the link speed indirectly by catching the events NT_EVENT_PORT_LINK_DOWN and NT_EVENT_PORT_LINK_UP, and retrieve the path delay when the link is up again.

Note that the solution does not provide a way for an application to identify the first network packet that pertains to a new link speed. An application must implement logic for that purpose itself. Since the solution requires a link is up for the delay to be available, there is a small time period following a link down event, where packets may arrive without the application knowing the correct (receive) delay; the application can either disregard the delay or postpone processing of the packets until the delay has been retrieved.

Note
A user may consider disabling auto negotiation to avoid externally imposed link speed changes, however even with auto negotiation enabled, a link will go down and come back up when the speed changes, which gives an application the possibility to detect the change.

Limitations

The version number mentioned in this section can be found by running the adapterinfo command. The version number is the third number series in the line that begins with FPGA ID. The following command line gives an example that illustrates a version number of 47.

# /opt/napatech3/bin/adapterinfo | grep "^FPGA "
FPGA ID:        200-9220-47-01-00

The current implementation has the following limitation:

  • GEN1 capture adapters are not supported. The system returns NT_PATH_DELAY_NOT_SUPPORTED for GEN1 capture adapters.

Example Program

// Save in get_path_delay.c and build with
// cc -I/opt/napatech3/include -L/opt/napatech3/lib -lntapi \
// -g -o get_path_delay get_path_delay.c
#include "nt.h"
#include <stdio.h>
#include <assert.h>
static NtInfoStream_t hInfo = NULL;
static const char *status2text(enum NtPathDelayStatus_e status)
{
switch (status) {
return "SUCCESS";
return "NOT_SUPPORTED";
return "LINK_DOWN";
return "UNKNOWN_NIM";
default:
assert(0);
}
}
int main()
{
const uint8_t virtualPortNo = 0;
NtInfo_t info;
char errBuf[1024];
int status;
// Initialize NTAPI
if ((status = NT_Init(NTAPI_VERSION)) != NT_SUCCESS) {
NT_ExplainError(status, errBuf, sizeof(errBuf));
fprintf(stderr, ">>> Error: NT_Init failed. Code 0x%x = %s\n",
status, errBuf);
return 1;
}
// Open information stream
if ((status = NT_InfoOpen(&hInfo, "CONFIG")) != NT_SUCCESS) {
NT_ExplainError(status, errBuf, sizeof(errBuf));
fprintf(stderr, ">>> Error: NT_InfoOpen failed. Code 0x%x = %s\n",
status, errBuf);
return 1;
}
// Read RX path delay for port `virtualPortNo'
info.u.pathDelay.portNo = virtualPortNo;
if ((status = NT_InfoRead(hInfo, &info)) != NT_SUCCESS) {
NT_ExplainError(status, errBuf, sizeof(errBuf));
fprintf(stderr, ">>> Error: NT_InfoRead failed. Code 0x%x = %s\n",
status, errBuf);
return 1;
}
(void)printf("RX port path delay for port %u: status = %s; delay = %d\n",
status2text(info.u.pathDelay.data.status),
// Read TX path delay for port `virtualPortNo'
if ((status = NT_InfoRead(hInfo, &info)) != NT_SUCCESS) {
NT_ExplainError(status, errBuf, sizeof(errBuf));
fprintf(stderr, ">>> Error: NT_InfoRead failed. Code 0x%x = %s\n",
status, errBuf);
return 1;
}
(void)printf("TX port path delay for port %u: status = %s; delay = %d\n",
status2text(info.u.pathDelay.data.status),
return 0;
}