Introduction
Adaptive Retransmission (ADP) Algorithm timeout adjustments is introduced in the April 2025 GA firmware for all NICs supporting the standard ADP algorithm. It addresses advanced customer needs for greater flexibility, enabling multiple timeout values and configurable retry counts per timeout. This enhancement allows for faster reactions to dropped packet reports while giving the transport layer the ability to defer flow errors. It assumes that QP users understand their fabric's characteristics and can select appropriate parameter values to optimize performance.
ROCE_ACCL Layout and Relevant Field Description
ROCE_ACCL Register
|
Offset |
Bits |
Name |
Description |
Access |
|---|---|---|---|---|
|
00h |
28 |
|
In query, indicates that In set, indicates that the profile indicated |
RW |
|
0 |
|
In Query, indicates if In set, indicates |
RW |
|
|
04h |
30:28 |
|
The index of the adaptive-retransmission profile to query or to modify. Value 0 is reserved. Valid if |
Index |
|
0 |
|
If set, the adaptive retransmission window functionality is enabled. Valid only when |
RW |
|
|
08h |
30:28 |
|
Maximal number of timeout ranges in |
RO |
|
26:24 |
|
Maximal index supported for |
RO |
|
|
19:0 |
|
The minimal base-timeout value for |
RO |
|
|
10h-3Ch |
384 |
|
Adaptive Retransmission: Parameters Control | Adaptive Retransmission Profile. |
RW |
Adaptive Retransmission Profile
|
Offset |
Bits |
Name |
Description |
Access |
|---|---|---|---|---|
|
00h |
31 |
|
If set, Total Retransmission Timeout will use QP parameters as timeout value, given by:
|
|
|
30:28 |
|
Number of valid ranges in |
|
|
|
26:24 |
|
Index of |
|
|
|
23:22 |
|
Time granularity of
|
|
|
|
15:0 |
|
Base value for all time parameter, units defined by |
|
|
|
04h |
31:24 |
|
Total Retransmission Timeout, given by Valid if |
|
|
15:8 |
|
Lower bound for QP initial timeout randomization, given by |
|
|
|
7:0 |
|
Upper bound for QP initial timeout randomization, given by
|
|
|
|
08h-14h |
31:0 |
|
Array of timeout ranges. First |
|
Adaptive Retransmission Timeout Range
|
Offset |
Bits |
Name |
Description |
Access |
|---|---|---|---|---|
|
00h |
30:28 |
|
Index of the timeout range to used when the current timeout is the range's lower-bound, and timeout should be decreased. |
|
|
27:26 |
|
Defines the behavior of timeout decrease until lower bound is reached.
|
|
|
|
25:16 |
|
Number of consecutive retransmissions attempts with the same timeout value, before timeout is increased. |
|
|
|
15:8 |
|
Lower bound of the timeout range, given by |
|
|
|
7:0 |
|
Upper bound of the timeout range given by |
|
Enablement and Capabilities
The following are ADP Retransmission configuration details:
-
roce_adp_retrans_field_select– Indicates that ADP Retransmission functionality is supported by the device. -
adp_retx_profile_select– Indicates support for advanced ADP Retransmission profile configuration. -
roce_adp_retrans_en– Enables ADP Retransmission. -
adp_retx_profile_id– Activates an advanced ADP Retransmission profile with the specified ID. Currently, only profile #1 is available for users; profile #0 is reserved as the default. -
adp_retx_base_timeout_min– Minimum base timeout enforced by firmware:0xFA0(4000 nanoseconds, i.e., 4 microseconds). -
adp_retx_profile_max_id– Maximum of 1 profile supported by the firmware. -
adp_retx_profile_max_range_num– Maximum of 4 timeout ranges supported per profile.
Algorithm & Profile Description and Formulas
The following is the adaptive retransmission (ADP) timeout algorithm flow.
Initialization
-
Initial timeout value:
rand(profile.timeout_init_low_bound, profile.timeout_init_low_bound + profile.timeout_init_range_size - 1) -
Hardware timer:
profile.time_base * (2 ^ granularity)Granularity = initial timeout.
-
On the first timeout event:
-
If
current_timeoutfalls within any defined range (range_low_bound→range_low_bound + range_size), the algorithm continues within that range. -
Otherwise, it starts from
profile.timeout_range[profile.start_range_index].range_low_bound.
-
Notes:
-
Initial timeout is randomized to prevent multiple QPs from starting with the same value.
-
A good configuration ensures the initial timeout falls within a defined range.
-
The initial timeout value is retried only once.
-
time_basemust be a power of 2, with the minimum allowed value per firmware capability (4 µs).
On Consecutive Timeout Events
-
current_timeoutis usedprofile.timeout_range[current_range].timeout_retry_numtimes. -
Once exhausted,
current_timeoutis doubled until it reachesprofile.timeout_range[current_range].range_low_bound + profile.timeout_range[current_range].range_size -
The algorithm then continues with the next defined range.
Notes:
-
Each range defines one or more timeout values.
-
Timeout ranges must be sorted by
range_low_bound(range_low_bound[i] < range_low_bound[j]fori < j). -
Maximum timeout is capped by
QP.ack_timeout, regardless of configured ranges. -
The overall timeout is determined by:
-
profile.qp_total_timeout ? (QP.ack_timeout * QP.retry_num) : profile.retx_total_timeout
-
-
If no forward progress is made within the total timeout, the QP fails and transitions to ERR state with error code
IBV_WC_RETRY_EXC_ERR (Transport Retry Counter Exceeded).
On Forward Progress (e.g., ACK Received)
-
current_timeoutis decremented based onprofile.timeout_range[current_range].dec_mode:-
Decrement by 2
-
Decrement by 4
-
Or reset to
profile.timeout_range[current_range].range_low_boundof the current range.
-
-
If
current_timeoutreaches the lowest timeout in the range, move to the previous range defined byprofile.timeout_range[current_range].prev_range_index.
Notes:
-
The minimum enforced timeout is
adp_retx_base_timeout_min(4 µs). -
prev_range_indexmust always be less thancurrent_range.
General Notes
-
If no profile is selected, the ADP algorithm defaults to firmware-defined timeouts.
-
When a profile is selected, it applies to all QPs of the PF and its associated VFs.
-
Reverting to firmware-defined timeouts requires a fwreset or system reboot.
-
To check which mode is active:
-
adp_retx_profile_id = 0→ firmware-defined timeouts -
adp_retx_profile_id > 0→ profile-based timeouts
-
Sample Usage
The following examples show how to review and update the Adaptive Retransmission (ADP) profile using both:
-
The standard
ROCE_ACCLregister -
The advanced mechanism (
reg_id 0x402c)
The examples below use mlxreg, but the same usage applies when using the mstreg tool.
[]$ sudo mlxreg -d 1a:00.0 --yes --reg_name ROCE_ACCL --get
Sending access register...
Field Name | Data
============================================================
roce_adp_retrans_field_select | 0x00000001
roce_tx_window_field_select | 0x00000001
roce_slow_restart_field_select | 0x00000001
roce_slow_restart_idle_field_select | 0x00000001
min_ack_timeout_limit_disabled_field_select | 0x00000001
adaptive_routing_forced_en_field_select | 0x00000000
selective_repeat_forced_en_field_select | 0x00000001
dc_half_handshake_en_field_select | 0x00000000
cc_per_plane_en_field_select | 0x00000000
ack_dscp_force_field_select | 0x00000001
cc_burst_size_select | 0x00000001
ps_metadata_reg_id_select | 0x00000000
ifa2_turn_around_select | 0x00000001
adp_retx_profile_select | 0x00000001
roce_adp_retrans_en | 0x00000001
roce_tx_window_en | 0x00000000
roce_slow_restart_en | 0x00000001
roce_slow_restart_idle_en | 0x00000000
min_ack_timeout_limit_disabled | 0x00000000
adaptive_routing_forced_en | 0x00000000
selective_repeat_forced_en | 0x00000000
dc_half_handshake_en | 0x00000000
cc_per_plane_en | 0x00000000
ack_dscp_force | 0x00000000
ack_dscp | 0x00000000
ps_metadata_reg_id | 0x00000000
cc_burst_size | 0x00000000
Ifa2_turn_around_en | 0x00000000
adp_retx_profile_id | 0x00000000
adp_retx_base_timeout_min | 0x00000fa0
adp_retx_profile_max_id | 0x00000001
adp_retx_profile_max_range_num | 0x00000004
time_base | 0x00000000
time_unit | 0x00000000
start_range_index | 0x00000000
range_num | 0x00000000
qp_total_timeout | 0x00000000
timeout_init_range_size | 0x00000000
timeout_init_low_bound | 0x00000000
retx_total_timeout | 0x00000000
range_size_0 | 0x00000000
range_low_bound_0 | 0x00000000
timeout_retry_num_0 | 0x00000000
dec_mode_0 | 0x00000000
prev_range_index_0 | 0x00000000
range_size_1 | 0x00000000
range_low_bound_1 | 0x00000000
timeout_retry_num_1 | 0x00000000
dec_mode_1 | 0x00000000
prev_range_index_1 | 0x00000000
range_size_2 | 0x00000000
range_low_bound_2 | 0x00000000
timeout_retry_num_2 | 0x00000000
dec_mode_2 | 0x00000000
prev_range_index_2 | 0x00000000
range_size_3 | 0x00000000
range_low_bound_3 | 0x00000000
timeout_retry_num_3 | 0x00000000
dec_mode_3 | 0x00000000
prev_range_index_3 | 0x00000000
============================================================
[]$ sudo mlxreg -d 1a:00.0 --yes --reg_id 0x402c --reg_len 0x40 --get
Sending access register...
Address | Data
=======================
0x00000000 | 0x1800065f
0x00000004 | 0x00000005
0x00000008 | 0x41000fa0
0x0000000c | 0x00000000
0x00000010 | 0x00000000
0x00000014 | 0x00000000
0x00000018 | 0x00000000
0x0000001c | 0x00000000
0x00000020 | 0x00000000
0x00000024 | 0x00000000
0x00000028 | 0x00000000
0x0000002c | 0x00000000
0x00000030 | 0x00000000
0x00000034 | 0x00000000
0x00000038 | 0x00000000
0x0000003c | 0x00000000
=======================
// Equivalent usage with ROCE_ACCL reg_name commented out for clarity and future usage
[]$ ###sudo mlxreg -d 1a:00.0 --reg_name ROCE_ACCL --set roce_adp_retrans_en=0x1,adp_retx_profile_id=0x1,time_base=4,time_unit=1,start_range_index=0,range_num=1,qp_total_timeout=1,timeout_init_range_size=2,timeout_init_low_bound=0,range_size_0=0x2,range_low_bound_0=0,timeout_retry_num_0=0x1,dec_mode_0=1,prev_range_index_0=0
[]$ sudo mlxreg -d 1a:00.0 --reg_id 0x402c --reg_len 0x40 --set "0x4.0:1=1,0x4.28:3=1,0x10.0:16=4,0x10.22:2=1,0x10.24:3=0,0x10.28:3=1,0x10.31:1=1,0x14.0:8=2,0x14.8:8=0,0x18.0:8=2,0x18.8:8=0,0x18.16:10=1,0x18.26:2=1"
You are about to send access register id: 0x402c with the following data:
Address | Data
=======================
0x00000000 | 0x1800065f
0x00000004 | 0x10000005
0x00000008 | 0x41000fa0
0x0000000c | 0x00000000
0x00000010 | 0x90400004
0x00000014 | 0x00000002
0x00000018 | 0x04010002
0x0000001c | 0x00000000
0x00000020 | 0x00000000
0x00000024 | 0x00000000
0x00000028 | 0x00000000
0x0000002c | 0x00000000
0x00000030 | 0x00000000
0x00000034 | 0x00000000
0x00000038 | 0x00000000
0x0000003c | 0x00000000
=======================
Do you want to continue ? (y/n) [n] : y
Sending access register...
[]$ sudo mlxreg -d 1a:00.0 --yes --reg_name ROCE_ACCL --get
Sending access register...
Field Name | Data
============================================================
roce_adp_retrans_field_select | 0x00000001
roce_tx_window_field_select | 0x00000001
roce_slow_restart_field_select | 0x00000001
roce_slow_restart_idle_field_select | 0x00000001
min_ack_timeout_limit_disabled_field_select | 0x00000001
adaptive_routing_forced_en_field_select | 0x00000000
selective_repeat_forced_en_field_select | 0x00000001
dc_half_handshake_en_field_select | 0x00000000
cc_per_plane_en_field_select | 0x00000000
ack_dscp_force_field_select | 0x00000001
cc_burst_size_select | 0x00000001
ps_metadata_reg_id_select | 0x00000000
ifa2_turn_around_select | 0x00000001
adp_retx_profile_select | 0x00000001
roce_adp_retrans_en | 0x00000001
roce_tx_window_en | 0x00000000
roce_slow_restart_en | 0x00000001
roce_slow_restart_idle_en | 0x00000000
min_ack_timeout_limit_disabled | 0x00000000
adaptive_routing_forced_en | 0x00000000
selective_repeat_forced_en | 0x00000000
dc_half_handshake_en | 0x00000000
cc_per_plane_en | 0x00000000
ack_dscp_force | 0x00000000
ack_dscp | 0x00000000
ps_metadata_reg_id | 0x00000000
cc_burst_size | 0x00000000
Ifa2_turn_around_en | 0x00000000
adp_retx_profile_id | 0x00000001
adp_retx_base_timeout_min | 0x00000fa0
adp_retx_profile_max_id | 0x00000001
adp_retx_profile_max_range_num | 0x00000004
time_base | 0x00000004
time_unit | 0x00000001
start_range_index | 0x00000000
range_num | 0x00000001
qp_total_timeout | 0x00000001
timeout_init_range_size | 0x00000002
timeout_init_low_bound | 0x00000000
retx_total_timeout | 0x00000000
range_size_0 | 0x00000002
range_low_bound_0 | 0x00000000
timeout_retry_num_0 | 0x00000001
dec_mode_0 | 0x00000001
prev_range_index_0 | 0x00000000
range_size_1 | 0x00000000
range_low_bound_1 | 0x00000000
timeout_retry_num_1 | 0x00000000
dec_mode_1 | 0x00000000
prev_range_index_1 | 0x00000000
range_size_2 | 0x00000000
range_low_bound_2 | 0x00000000
timeout_retry_num_2 | 0x00000000
dec_mode_2 | 0x00000000
prev_range_index_2 | 0x00000000
range_size_3 | 0x00000000
range_low_bound_3 | 0x00000000
timeout_retry_num_3 | 0x00000000
dec_mode_3 | 0x00000000
prev_range_index_3 | 0x00000000
============================================================
Last updated: