iPXE
Functions
ib_packet.c File Reference

Infiniband Packet Formats. More...

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/iobuf.h>
#include <ipxe/infiniband.h>
#include <ipxe/ib_packet.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
int ib_push (struct ib_device *ibdev, struct io_buffer *iobuf, struct ib_queue_pair *qp, size_t payload_len, const struct ib_address_vector *dest)
 Add IB headers. More...
 
int ib_pull (struct ib_device *ibdev, struct io_buffer *iobuf, struct ib_queue_pair **qp, size_t *payload_len, struct ib_address_vector *dest, struct ib_address_vector *source)
 Remove IB headers. More...
 

Detailed Description

Infiniband Packet Formats.

Definition in file ib_packet.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ ib_push()

int ib_push ( struct ib_device ibdev,
struct io_buffer iobuf,
struct ib_queue_pair qp,
size_t  payload_len,
const struct ib_address_vector dest 
)

Add IB headers.

Parameters
ibdevInfiniband device
iobufI/O buffer to contain headers
qpQueue pair
payload_lenPayload length
destDestination address vector
Return values
rcReturn status code

Definition at line 52 of file ib_packet.c.

54  {
55  struct ib_local_route_header *lrh;
59  size_t orig_iob_len = iob_len ( iobuf );
60  size_t pad_len;
61  size_t lrh_len;
62  size_t grh_len;
63  unsigned int vl;
64  unsigned int lnh;
65 
66  DBGC2 ( ibdev, "IBDEV %s TX %04x:%08lx => %04x:%08lx (key %08lx)\n",
67  ibdev->name, ibdev->lid, qp->ext_qpn, dest->lid, dest->qpn,
68  dest->qkey );
69 
70  /* Calculate packet length */
71  pad_len = ( (-payload_len) & 0x3 );
72  payload_len += pad_len;
73  payload_len += 4; /* ICRC */
74 
75  /* Reserve space for headers */
76  orig_iob_len = iob_len ( iobuf );
77  deth = iob_push ( iobuf, sizeof ( *deth ) );
78  bth = iob_push ( iobuf, sizeof ( *bth ) );
79  grh_len = ( payload_len + iob_len ( iobuf ) - orig_iob_len );
80  grh = ( dest->gid_present ?
81  iob_push ( iobuf, sizeof ( *grh ) ) : NULL );
82  lrh = iob_push ( iobuf, sizeof ( *lrh ) );
83  lrh_len = ( payload_len + iob_len ( iobuf ) - orig_iob_len );
84 
85  /* Construct LRH */
86  vl = ( ( qp->ext_qpn == IB_QPN_SMI ) ? IB_VL_SMP : IB_VL_DEFAULT );
87  lrh->vl__lver = ( vl << 4 );
88  lnh = ( grh ? IB_LNH_GRH : IB_LNH_BTH );
89  lrh->sl__lnh = ( ( dest->sl << 4 ) | lnh );
90  lrh->dlid = htons ( dest->lid );
91  lrh->length = htons ( lrh_len >> 2 );
92  lrh->slid = htons ( ibdev->lid );
93 
94  /* Construct GRH, if required */
95  if ( grh ) {
97  htonl ( IB_GRH_IPVER_IPv6 << 28 );
98  grh->paylen = htons ( grh_len );
100  grh->hoplmt = 0;
101  memcpy ( &grh->sgid, &ibdev->gid, sizeof ( grh->sgid ) );
102  memcpy ( &grh->dgid, &dest->gid, sizeof ( grh->dgid ) );
103  }
104 
105  /* Construct BTH */
107  bth->se__m__padcnt__tver = ( pad_len << 4 );
108  bth->pkey = htons ( ibdev->pkey );
109  bth->dest_qp = htonl ( dest->qpn );
110  bth->ack__psn = htonl ( ( qp->send.psn++ ) & 0xffffffUL );
111 
112  /* Construct DETH */
113  deth->qkey = htonl ( dest->qkey );
114  deth->src_qp = htonl ( qp->ext_qpn );
115 
116  DBGCP_HDA ( ibdev, 0, iobuf->data,
117  ( iob_len ( iobuf ) - orig_iob_len ) );
118 
119  return 0;
120 }
struct ib_base_transport_header bth
Definition: ib_packet.h:17
An Infiniband Datagram Extended Transport Header.
Definition: ib_packet.h:132
struct ib_local_route_header lrh
Definition: ib_packet.h:15
#define IB_QPN_SMI
Subnet management interface QPN.
Definition: infiniband.h:21
char name[IBDEV_NAME_LEN]
Name of this Infiniband device.
Definition: infiniband.h:408
union ib_gid gid
Port GID (comprising GID prefix and port GUID)
Definition: infiniband.h:441
uint32_t dest_qp
Destination queue pair.
Definition: ib_packet.h:121
#define iob_push(iobuf, len)
Definition: iobuf.h:84
uint8_t nxthdr
Next header.
Definition: ib_packet.h:100
uint16_t lid
Port LID.
Definition: infiniband.h:443
uint8_t se__m__padcnt__tver
Transport header version, pad count, migration and solicitation.
Definition: ib_packet.h:117
uint8_t sl__lnh
Service level and next link header.
Definition: ib_packet.h:59
struct ib_global_route_header grh
Definition: ib_packet.h:16
uint16_t pkey
Partition key.
Definition: ib_packet.h:119
#define htonl(value)
Definition: byteswap.h:133
#define IB_GRH_NXTHDR_IBA
Definition: ib_packet.h:110
union ib_gid dgid
Destiniation GID.
Definition: ib_packet.h:106
#define DBGCP_HDA(...)
Definition: compiler.h:540
uint16_t slid
Source LID.
Definition: ib_packet.h:65
void * memcpy(void *dest, const void *src, size_t len) __nonnull
An Infiniband Base Transport Header.
Definition: ib_packet.h:113
uint8_t hoplmt
Hop limit.
Definition: ib_packet.h:102
An Infiniband Global Route Header.
Definition: ib_packet.h:89
struct ib_datagram_extended_transport_header deth
Definition: ib_packet.h:18
static void * dest
Definition: strings.h:176
uint8_t opcode
Opcode.
Definition: ib_packet.h:115
union ib_gid sgid
Source GID.
Definition: ib_packet.h:104
An Infiniband Local Route Header.
Definition: ib_packet.h:55
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
uint16_t paylen
Payload length.
Definition: ib_packet.h:98
uint8_t vl__lver
Virtual lane and link version.
Definition: ib_packet.h:57
uint16_t dlid
Destination LID.
Definition: ib_packet.h:61
uint32_t ipver__tclass__flowlabel
IP version, traffic class, and flow label.
Definition: ib_packet.h:96
uint16_t length
Packet length.
Definition: ib_packet.h:63
long pad_len
Definition: bigint.h:30
struct arbelprm_qp_db_record qp
Definition: arbel.h:13
#define DBGC2(...)
Definition: compiler.h:522
void * data
Start of data.
Definition: iobuf.h:48
uint32_t src_qp
Source queue pair.
Definition: ib_packet.h:136
uint16_t pkey
Partition key.
Definition: infiniband.h:449
uint32_t ack__psn
Packet sequence number and acknowledge request.
Definition: ib_packet.h:123
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define htons(value)
Definition: byteswap.h:135
#define IB_GRH_IPVER_IPv6
Definition: ib_packet.h:109

References ib_base_transport_header::ack__psn, bth, BTH_OPCODE_UD_SEND, io_buffer::data, DBGC2, DBGCP_HDA, dest, ib_base_transport_header::dest_qp, deth, ib_global_route_header::dgid, ib_local_route_header::dlid, ib_device::gid, grh, ib_global_route_header::hoplmt, htonl, htons, IB_GRH_IPVER_IPv6, IB_GRH_NXTHDR_IBA, IB_LNH_BTH, IB_LNH_GRH, IB_QPN_SMI, IB_VL_DEFAULT, IB_VL_SMP, iob_len(), iob_push, ib_global_route_header::ipver__tclass__flowlabel, ib_local_route_header::length, ib_device::lid, lrh, memcpy(), ib_device::name, NULL, ib_global_route_header::nxthdr, ib_base_transport_header::opcode, pad_len, ib_global_route_header::paylen, ib_base_transport_header::pkey, ib_device::pkey, ib_datagram_extended_transport_header::qkey, qp, ib_base_transport_header::se__m__padcnt__tver, ib_global_route_header::sgid, ib_local_route_header::sl__lnh, ib_local_route_header::slid, ib_datagram_extended_transport_header::src_qp, and ib_local_route_header::vl__lver.

Referenced by arbel_fill_mlx_send_wqe(), hermon_fill_mlx_send_wqe(), linda_post_send(), and qib7322_post_send().

◆ ib_pull()

int ib_pull ( struct ib_device ibdev,
struct io_buffer iobuf,
struct ib_queue_pair **  qp,
size_t payload_len,
struct ib_address_vector dest,
struct ib_address_vector source 
)

Remove IB headers.

Parameters
ibdevInfiniband device
iobufI/O buffer containing headers
qpQueue pair to fill in, or NULL
payload_lenPayload length to fill in, or NULL
destDestination address vector to fill in
sourceSource address vector to fill in
Return values
rcReturn status code

Definition at line 133 of file ib_packet.c.

136  {
137  struct ib_local_route_header *lrh;
138  struct ib_global_route_header *grh;
141  size_t orig_iob_len = iob_len ( iobuf );
142  unsigned int lnh;
143  size_t pad_len;
144 
145  /* Clear return values */
146  if ( qp )
147  *qp = NULL;
148  if ( payload_len )
149  *payload_len = 0;
150  memset ( dest, 0, sizeof ( *dest ) );
151  memset ( source, 0, sizeof ( *source ) );
152 
153  /* Extract LRH */
154  if ( iob_len ( iobuf ) < sizeof ( *lrh ) ) {
155  DBGC ( ibdev, "IBDEV %s RX too short (%zd bytes) for LRH\n",
156  ibdev->name, iob_len ( iobuf ) );
157  return -EINVAL;
158  }
159  lrh = iobuf->data;
160  iob_pull ( iobuf, sizeof ( *lrh ) );
161  dest->lid = ntohs ( lrh->dlid );
162  dest->sl = ( lrh->sl__lnh >> 4 );
163  source->lid = ntohs ( lrh->slid );
164  source->sl = ( lrh->sl__lnh >> 4 );
165  lnh = ( lrh->sl__lnh & 0x3 );
166 
167  /* Reject unsupported packets */
168  if ( ! ( ( lnh == IB_LNH_BTH ) || ( lnh == IB_LNH_GRH ) ) ) {
169  DBGC ( ibdev, "IBDEV %s RX unsupported LNH %x\n",
170  ibdev->name, lnh );
171  return -ENOTSUP;
172  }
173 
174  /* Extract GRH, if present */
175  if ( lnh == IB_LNH_GRH ) {
176  if ( iob_len ( iobuf ) < sizeof ( *grh ) ) {
177  DBGC ( ibdev, "IBDEV %s RX too short (%zd bytes) "
178  "for GRH\n", ibdev->name, iob_len ( iobuf ) );
179  return -EINVAL;
180  }
181  grh = iobuf->data;
182  iob_pull ( iobuf, sizeof ( *grh ) );
183  dest->gid_present = 1;
184  memcpy ( &dest->gid, &grh->dgid, sizeof ( dest->gid ) );
185  source->gid_present = 1;
186  memcpy ( &source->gid, &grh->sgid, sizeof ( source->gid ) );
187  } else {
188  grh = NULL;
189  }
190 
191  /* Extract BTH */
192  if ( iob_len ( iobuf ) < sizeof ( *bth ) ) {
193  DBGC ( ibdev, "IBDEV %s RX too short (%zd bytes) for BTH\n",
194  ibdev->name, iob_len ( iobuf ) );
195  return -EINVAL;
196  }
197  bth = iobuf->data;
198  iob_pull ( iobuf, sizeof ( *bth ) );
199  if ( bth->opcode != BTH_OPCODE_UD_SEND ) {
200  DBGC ( ibdev, "IBDEV %s unsupported BTH opcode %x\n",
201  ibdev->name, bth->opcode );
202  return -ENOTSUP;
203  }
204  dest->qpn = ntohl ( bth->dest_qp );
205 
206  /* Extract DETH */
207  if ( iob_len ( iobuf ) < sizeof ( *deth ) ) {
208  DBGC ( ibdev, "IBDEV %s RX too short (%zd bytes) for DETH\n",
209  ibdev->name, iob_len ( iobuf ) );
210  return -EINVAL;
211  }
212  deth = iobuf->data;
213  iob_pull ( iobuf, sizeof ( *deth ) );
214  source->qpn = ntohl ( deth->src_qp );
215  source->qkey = ntohl ( deth->qkey );
216 
217  /* Calculate payload length, if applicable */
218  if ( payload_len ) {
219  pad_len = ( ( bth->se__m__padcnt__tver >> 4 ) & 0x3 );
220  *payload_len = ( ( ntohs ( lrh->length ) << 2 )
221  - ( orig_iob_len - iob_len ( iobuf ) )
222  - pad_len - 4 /* ICRC */ );
223  }
224 
225  /* Determine destination QP, if applicable */
226  if ( qp ) {
227  if ( IB_LID_MULTICAST ( dest->lid ) && grh ) {
228  if ( ! ( *qp = ib_find_qp_mgid ( ibdev, &grh->dgid ))){
229  DBGC ( ibdev, "IBDEV %s RX for unknown MGID "
230  IB_GID_FMT "\n", ibdev->name,
231  IB_GID_ARGS ( &grh->dgid ) );
232  return -ENODEV;
233  }
234  } else {
235  if ( ! ( *qp = ib_find_qp_qpn ( ibdev, dest->qpn ) ) ) {
236  DBGC ( ibdev, "IBDEV %s RX for nonexistent "
237  "QPN %#lx\n", ibdev->name, dest->qpn );
238  return -ENODEV;
239  }
240  }
241  assert ( *qp );
242  }
243 
244  DBGC2 ( ibdev, "IBDEV %s RX %04x:%08lx <= %04x:%08lx (key %08x)\n",
245  ibdev->name, dest->lid,
246  ( IB_LID_MULTICAST ( dest->lid ) ?
247  ( qp ? (*qp)->ext_qpn : -1UL ) : dest->qpn ),
248  source->lid, source->qpn, ntohl ( deth->qkey ) );
249  DBGCP_HDA ( ibdev, 0,
250  ( iobuf->data - ( orig_iob_len - iob_len ( iobuf ) ) ),
251  ( orig_iob_len - iob_len ( iobuf ) ) );
252 
253  return 0;
254 }
#define iob_pull(iobuf, len)
Definition: iobuf.h:102
struct ib_base_transport_header bth
Definition: ib_packet.h:17
#define EINVAL
Invalid argument.
Definition: errno.h:428
An Infiniband Datagram Extended Transport Header.
Definition: ib_packet.h:132
struct ib_local_route_header lrh
Definition: ib_packet.h:15
char name[IBDEV_NAME_LEN]
Name of this Infiniband device.
Definition: infiniband.h:408
uint32_t dest_qp
Destination queue pair.
Definition: ib_packet.h:121
uint8_t se__m__padcnt__tver
Transport header version, pad count, migration and solicitation.
Definition: ib_packet.h:117
#define DBGC(...)
Definition: compiler.h:505
uint8_t sl__lnh
Service level and next link header.
Definition: ib_packet.h:59
#define ntohl(value)
Definition: byteswap.h:134
struct ib_global_route_header grh
Definition: ib_packet.h:16
#define ntohs(value)
Definition: byteswap.h:136
unsigned int gid_present
GID is present.
Definition: infiniband.h:90
union ib_gid dgid
Destiniation GID.
Definition: ib_packet.h:106
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
#define DBGCP_HDA(...)
Definition: compiler.h:540
uint16_t slid
Source LID.
Definition: ib_packet.h:65
void * memcpy(void *dest, const void *src, size_t len) __nonnull
unsigned long qkey
Queue key.
Definition: infiniband.h:79
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
An Infiniband Base Transport Header.
Definition: ib_packet.h:113
An Infiniband Global Route Header.
Definition: ib_packet.h:89
struct ib_datagram_extended_transport_header deth
Definition: ib_packet.h:18
static void * dest
Definition: strings.h:176
uint8_t opcode
Opcode.
Definition: ib_packet.h:115
#define IB_GID_ARGS(gid)
Infiniband Global Identifier debug message arguments.
Definition: ib_packet.h:48
union ib_gid sgid
Source GID.
Definition: ib_packet.h:104
An Infiniband Local Route Header.
Definition: ib_packet.h:55
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
#define ENODEV
No such device.
Definition: errno.h:509
uint16_t dlid
Destination LID.
Definition: ib_packet.h:61
unsigned long qpn
Queue Pair Number.
Definition: infiniband.h:74
#define IB_LID_MULTICAST(lid)
Test for multicast LID.
Definition: ib_packet.h:86
uint16_t length
Packet length.
Definition: ib_packet.h:63
unsigned int sl
Service level.
Definition: infiniband.h:88
long pad_len
Definition: bigint.h:30
struct arbelprm_qp_db_record qp
Definition: arbel.h:13
struct ib_queue_pair * ib_find_qp_mgid(struct ib_device *ibdev, union ib_gid *gid)
Find queue pair by multicast GID.
Definition: infiniband.c:372
#define DBGC2(...)
Definition: compiler.h:522
void * data
Start of data.
Definition: iobuf.h:48
uint32_t src_qp
Source queue pair.
Definition: ib_packet.h:136
union ib_gid gid
GID, if present.
Definition: infiniband.h:92
#define IB_GID_FMT
Infiniband Global Identifier debug message format.
Definition: ib_packet.h:45
unsigned int lid
Local ID.
Definition: infiniband.h:81
struct ib_queue_pair * ib_find_qp_qpn(struct ib_device *ibdev, unsigned long qpn)
Find queue pair by QPN.
Definition: infiniband.c:354
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
void * memset(void *dest, int character, size_t len) __nonnull

References assert(), bth, BTH_OPCODE_UD_SEND, io_buffer::data, DBGC, DBGC2, DBGCP_HDA, dest, ib_base_transport_header::dest_qp, deth, ib_global_route_header::dgid, ib_local_route_header::dlid, EINVAL, ENODEV, ENOTSUP, ib_address_vector::gid, ib_address_vector::gid_present, grh, ib_find_qp_mgid(), ib_find_qp_qpn(), IB_GID_ARGS, IB_GID_FMT, IB_LID_MULTICAST, IB_LNH_BTH, IB_LNH_GRH, iob_len(), iob_pull, ib_local_route_header::length, ib_address_vector::lid, lrh, memcpy(), memset(), ib_device::name, ntohl, ntohs, NULL, ib_base_transport_header::opcode, pad_len, ib_address_vector::qkey, ib_datagram_extended_transport_header::qkey, qp, ib_address_vector::qpn, ib_base_transport_header::se__m__padcnt__tver, ib_global_route_header::sgid, ib_address_vector::sl, ib_local_route_header::sl__lnh, ib_local_route_header::slid, and ib_datagram_extended_transport_header::src_qp.

Referenced by linda_complete_recv(), and qib7322_complete_recv().