10.1 Protocol Description

RapidIO is considered as a reliable media, so there is no need for a reliability protocol. RapidIO hardware are however not reliable to the full extent - packets can be received in a different order than they were sent. This requires sequence numbers on all data packets that are sent with the protocol described herein.

If a malformed packet is received, the RapidIO Connection Manager resets the connection and informs the RLNH.

When the RapidIO Connection Manager encounters problems which prevents delivery of a message or part of a message it must reset the connection. The RapidIO CM notifies the RLNH when the peer replies with RESET or, if the peer has crashed, the Connection Supervision timer fires.

All Enea LINX RapidIO packets starts with the common rio_frame header. The rio_frame header allows for other protocols to coexist with this protocol.

Table 10.1 RIOCM rio_frame header

0123
protocolsize

The protocol number is 0x22cf (8911) for version 2 of the Enea LINX RapidIO Connection Manager Protocol. It was 0x8911 for version 1.

The rio_frame header is followed by either a CONN, HEARTBEAT or UDATA header. There are three types of CONN headers, one HEARTBEAT header and five types of UDATA headers. Some fields are common for all nine headers. The common fields are type and dst_port:

Table 10.2 RIOCM common fields

0123
typereserved
dst_portreserved

The type is used to identify the type of the packet. The dst_port is used to identify the destination port of the packet. In multi-core processors that share the same RapidIO device, the dst_port can be used by the hardware to identify the destination core of the packet.

10.1.1 LINX RapidIO Connection Establishment Algorithm

The following headers types are used in the Connection Establishment Algorithm:

Table 10.3 RapidIO Connection Manager Connect Headers

Header typeValueDefinition
RIO_CONN_REQ0x81Connect request. Used to request connection establishment and its settings
RIO_CONN_ACK0x82Connect acknowledgement. Used to acknowledge the connection request and its settings.
RIO_CONN_RESET0x83Reset. Used to cancel the connection.

The connection algorithm is quite straightforward.

Let X and Y be two nodes in the same rapidio network. Let a connection be created on X towards Y. X will start to periodically send RIO_CONN_REQ to Y. When a connection is created on Y towards X, it will do the same.

When Y (or X) receives a RIO_CONN_REQ, it will respond with a RIO_CONN_ACK. When X receives a correct RIO_CONN_ACK, it will consider the connection as established and respond with its RIO_CONN_ACK. When Y receives this RIO_CONN_ACK, it will consider the connection as established, it may also send a RIO_CONN_ACK to X again, which will be dropped by X.

The last transmission of a RIO_CONN_ACK will seem unnecessary, but it is a consequence of the state machine used in the implementation. The important thing to notice here is that a correct RIO_CONN_ACK is dropped by a peer that considers the connection to be established.

A correct RIO_CONN_ACK is a RIO_CONN_ACK with the correct negotiated settings for the connection. The RIO_CONN_REQ has fields with requests for the mtu and the heartbeat timeout for the connection. These values are set by a logic expression for each field. The result of this calculation is sent in the RIO_CONN_ACK. The lowest configured mtu is used, while the largest configured heartbeat timeout is used. If this calculation mismatches, the RIO_CONN_ACK is regarded as incorrect, and then treated as a RIO_CONN_REQ instead!

10.1.1.1 RIO_CONN_REQ Header

Table 10.4 RIO_CONN_REQ Header

0123
typegenerationmtu
dst_portrsvdhb_tmo
sendersrc_port

type

RIO_CONN_REQ

generation

A generation value for this connection. Used to distinguish between new and old connections.

mtu

The MTU that the sender of the RIO_CONN_REQ wants to use for this connection.

dst_port

The user defined destination port of the connection. This field is used by some RapidIO hardware to distinguish between destination cores that shares the same device. When multiple connections share a device ID they must have different ports.

reserved

This field is not used in this header.

hb_tmo

The heartbeat timeout that the sender of the RIO_CONN_REQ wants to use for this connection. The value is written in hundreds of msec. A value of 5 yields a tmo of 500ms.

sender

The device id of the sender.

src_port

The port of the sender.

10.1.1.2 RIO_CONN_ACK Header

Table 10.5 RIO_CONN_ACK Header

0123
typegenerationmtu_ack
dst_portgeneration_ackhb_tmo_ack
sendersrc_port
my_cid  

type

RIO_CONN_ADD

generation

A generation value for this connection. Used to distinguish between new and old connections. The connection generation value of the sender.

mtu_ack

The MTU calculated by the sending peer.

dst_port

The user defined destination port of the connection. This field is used by some RapidIO hardware to distinguish between destination cores that shares the same device. When multiple connections share a device ID they must have different ports.

generation_ack

This field is used to acknowledge the generation field sent from the peer in the RIO_CONN_REQ.

hb_tmo_ack

The heartbeat timeout calculated by the sending peer. The value is written in hundreds of msec. A value of 5 yields a tmo of 500ms.

sender

The device id of the sender.

src_port

The port of the sender.

my_cid

The cid (connection id) that is to be used in udata and heartbeat headers for this connection. It is uniqe for each connection and allows the receiver to quickly identify the connection.

10.1.1.3 RIO_CONN_RESET Header

Table 10.6 RIO_CONN_RESET Header

0123
typegenerationmtu
dst_portrsvd
sendersrc_port

type

RIO_CONN_RESET

generation

A generation value for this connection. Used to distinguish between new and old connections.

mtu

This may contain the MTU of the connection. Disregarded field.

dst_port

The user defined destination port of the connection. This field is used by some RapidIO hardware to distinguish between destination cores that shares the same device. When multiple connections share a device ID they must have different ports.

rsvd

This field is not used in this header.

sender

The device id of the sender.

src_port

The port of the sender.

10.1.2 Enea LINX RapidIO User Data Protocol

Data is sent reliable on RapidIO. But some drivers may not guarantee that the order of the incoming packets is the same as the order they were sent in. Therefore, the user data packets need sequence numbers. The receiver implements a reordering queue to ensure that all messages are delivered in order.

Table 10.7 RapidIO Connection Manager User Data Headers

Header typeValueDefinition
RIO_SINGLE0x1Used when the entire messages plus header can fit within the MTU
RIO_FRAG_START0x2The first fragment when sending with simple fragmentation
RIO_FRAG0x3Remaining fragments for both types of fragmentation
RIO_PATCH_START0x4The first fragment when receiving with improved fragmentation
RIO_PATCH0x5Contains patches for the ‘holes’ created by the improved fragmentation


Messages can be smaller or larger than the max amount of payload that can be sent in a single packet. When the messages are smaller, the RIO_SINGLE header is used. If otherwise, there are two ways of sending fragmented messages.

The simple fragmentation is implemented using two headers, RIO_FRAG_START and RIO_FRAG. A RIO_FRAG_START header is trailed by the needed amount of RIO_FRAG headers to complete the message.

The other way of sending/receiving fragmented messages is an optimization done in the OSEck Operating System. The Linux implementation of the RapidIO Connection Manager only has support of receiving such messages. This way is implemented using three headers, RIO_PATCH_START, RIO_FRAG and RIO_PATCH. The RIO_PATCH_START is trailed by the necessary amount of RIO_FRAG headers and then finally trailed by the necessary amount of RIO_PATCH headers. The scenario for using these headers is as follows:

The cm needs to send a message larger than mtu over the connection. To avoid a lot of memcpys, the cm merely overwrites some data of the message with RIO_PATCH_START and RIO_FRAG headers after moving that data to RIO_PATCH packets. It will then transmit every fragment of the message, which then consists of subsequent data packets. Finally, it transmits all RIO_PATCH packets that the peer needs to patch (repair) the overwritten data in the message with.

10.1.2.1 RIO_SINGLE Header

Table 10.8 RIO_SINGLE Header

0123
typemsgidseqno
dst_portdst_cid
sendersrc_port
src
dst
payl_size

type

RIO_SINGLE

msgid

A message identifier for this message.

seqno

The sequence number for this packet

dst_port

The user defined destination port of the connection. This field is used by some RapidIO hardware to distinguish between destination cores that shares the same device. When multiple connections share a device ID they must have different ports.

dst_cid

The connection id that was submitted in the RIO_CONN_ACK header.

sender

The device id of the sender.

src_port

The port of the sender.

src

The source link adress of the message

dst

The destination link adress of the message.

payl_size

The total size of the message.

10.1.2.2 RIO_FRAG_START Header

Table 10.9 RIO_FRAG_START Header

0123
typemsgidseqno
dst_portdst_cid
sendersrc_port
src
dst
payl_size

type

RIO_FRAG_START

msgid

A message identifier for this message.

seqno

The sequence number for this packet

dst_port

The user defined destination port of the connection. This field is used by some RapidIO hardware to distinguish between destination cores that shares the same device. When multiple connections share a device ID they must have different ports.

dst_cid

The connection id that was submitted in the RIO_CONN_ACK header.

sender

The device id of the sender.

src_port

The port of the sender.

src

The source link adress of the message

dst

The destination link adress of the message.

payl_size

The total size of the message.

10.1.2.3 RIO_FRAG Header

Table 10.10 RIO_FRAG Header

0123
typemsgidseqno
dst_portdst_cid
sendersrc_port

type

RIO_FRAG

msgid

A message identifier for this message.

seqno

The sequence number for this packet

dst_port

The user defined destination port of the connection. This field is used by some RapidIO hardware to distinguish between destination cores that shares the same device. When multiple connections share a device ID they must have different ports.

dst_cid

The connection id that was submitted in the RIO_CONN_ACK header.

sender

The device id of the sender.

src_port

The port of the sender.

10.1.2.4 RIO_PATCH_START Header

Table 10.11 RIO_PATCH_START Header

0123
typemsgidseqno
dst_portdst_cid
sendersrc_port
src
dst
payl_size
count_fragcount_patch

type

RIO_FRAG_START

msgid

A message identifier for this message.

seqno

The sequence number for this packet

dst_port

The user defined destination port of the connection. This field is used by some RapidIO hardware to distinguish between destination cores that shares the same device.

dst_cid

The connection id that was submitted in the RIO_CONN_ACK header.

sender

The device id of the sender.

src_port

The port of the sender.

src

The source link adress of the message

dst

The destination link adress of the message.

payl_size

The total size of the message.

count_frag

Number of RIO_FRAG fragments that will trail this header

count_patch

Number of RIO_PATCH packets that will trail the fragments

10.1.2.5 RIO_PATCH Header

Table 10.12 RIO_PATCH Header

0123
typemsgidseqno
dst_portdst_cid
sendersrc_port

type

RIO_PATCH

msgid

A message identifier for this message.

seqno

The sequence number for this packet

dst_port

This is the user defined destination port of the connection. This field is used by some RapidIO hardware to distinguish between destination cores that shares the same device.

dst_cid

The connection id that was submitted in the RIO_CONN_ACK header.

sender

This is the device id of the sender.

src_port

This is the port of the sender.

10.1.3 Enea LINX RapidIO Connection Supervision Protocol

Supervision of the connection is needed in order to detect if a peer has ‘died’.

Table 10.13 RapidIO Connection Manager Connection Supervision Header

Header typeValueDefinition
RIO_HEARTBEAT0x6Sent periodically to indicate that the sender is alive


The heartbeat packet is sent every negotiated hb_tmo * 100 ms. When a node has not received a heartbeat in three periods, the connection is considered timed out and has to be reestablished.

10.1.3.1 RIO_HEARTBEAT Header

Table 10.14 RIO_HEARTBEAT Header

0123
typepadrsvd
dst_portdst_cid
sendersrc_port

type

RIO_HEARTBEAT

pad

pad

rsvd

Not used.

dst_port

The user defined destination port of the connection. This field is used by some RapidIO hardware to distinguish between destination cores that shares the same device.

dst_cid

The connection id that was submitted in the RIO_CONN_ACK header.

sender

The device id of the sender.

src_port

The port of the sender.