iPXE
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.
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.

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 {
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 ) {
96 grh->ipver__tclass__flowlabel =
97 htonl ( IB_GRH_IPVER_IPv6 << 28 );
98 grh->paylen = htons ( grh_len );
99 grh->nxthdr = IB_GRH_NXTHDR_IBA;
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 */
106 bth->opcode = BTH_OPCODE_UD_SEND;
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}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
struct arbelprm_qp_db_record qp
Definition arbel.h:2
long pad_len
Definition bigint.h:31
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" retur dest)
Definition string.h:151
#define DBGCP_HDA(...)
Definition compiler.h:540
#define DBGC2(...)
Definition compiler.h:522
struct ib_datagram_extended_transport_header deth
Definition ib_packet.h:3
#define IB_GRH_IPVER_IPv6
Definition ib_packet.h:110
@ IB_LNH_BTH
Definition ib_packet.h:79
@ IB_LNH_GRH
Definition ib_packet.h:80
#define IB_GRH_NXTHDR_IBA
Definition ib_packet.h:111
@ IB_VL_DEFAULT
Definition ib_packet.h:71
@ IB_VL_SMP
Definition ib_packet.h:72
@ BTH_OPCODE_UD_SEND
Definition ib_packet.h:129
struct ib_global_route_header grh
Definition ib_packet.h:1
struct ib_base_transport_header bth
Definition ib_packet.h:2
struct ib_local_route_header lrh
Definition ib_packet.h:0
#define htonl(value)
Definition byteswap.h:134
#define htons(value)
Definition byteswap.h:136
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define IB_QPN_SMI
Subnet management interface QPN.
Definition infiniband.h:22
#define iob_push(iobuf, len)
Definition iobuf.h:89
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
An Infiniband Base Transport Header.
Definition ib_packet.h:114
An Infiniband Datagram Extended Transport Header.
Definition ib_packet.h:133
char name[IBDEV_NAME_LEN]
Name of this Infiniband device.
Definition infiniband.h:409
uint16_t pkey
Partition key.
Definition infiniband.h:450
uint16_t lid
Port LID.
Definition infiniband.h:444
union ib_gid gid
Port GID (comprising GID prefix and port GUID)
Definition infiniband.h:442
An Infiniband Global Route Header.
Definition ib_packet.h:90
An Infiniband Local Route Header.
Definition ib_packet.h:56
void * data
Start of data.
Definition iobuf.h:53

References bth, BTH_OPCODE_UD_SEND, io_buffer::data, DBGC2, DBGCP_HDA, dest, deth, ib_device::gid, grh, 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_device::lid, lrh, memcpy(), ib_device::name, NULL, pad_len, ib_device::pkey, and qp.

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 {
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 assert(condition)
Assert a condition at run-time.
Definition assert.h:50
#define DBGC(...)
Definition compiler.h:505
#define EINVAL
Invalid argument.
Definition errno.h:429
#define ENOTSUP
Operation not supported.
Definition errno.h:590
#define ENODEV
No such device.
Definition errno.h:510
#define IB_GID_ARGS(gid)
Infiniband Global Identifier debug message arguments.
Definition ib_packet.h:49
#define IB_GID_FMT
Infiniband Global Identifier debug message format.
Definition ib_packet.h:46
#define IB_LID_MULTICAST(lid)
Test for multicast LID.
Definition ib_packet.h:87
#define ntohl(value)
Definition byteswap.h:135
#define ntohs(value)
Definition byteswap.h:137
void * memset(void *dest, int character, size_t len) __nonnull
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
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 iob_pull(iobuf, len)
Definition iobuf.h:107
unsigned int sl
Service level.
Definition infiniband.h:89
unsigned long qkey
Queue key.
Definition infiniband.h:80
unsigned int gid_present
GID is present.
Definition infiniband.h:91
unsigned int lid
Local ID.
Definition infiniband.h:82
union ib_gid gid
GID, if present.
Definition infiniband.h:93
unsigned long qpn
Queue Pair Number.
Definition infiniband.h:75

References assert, bth, BTH_OPCODE_UD_SEND, io_buffer::data, DBGC, DBGC2, DBGCP_HDA, dest, deth, 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_address_vector::lid, lrh, memcpy(), memset(), ib_device::name, ntohl, ntohs, NULL, pad_len, ib_address_vector::qkey, qp, ib_address_vector::qpn, and ib_address_vector::sl.

Referenced by linda_complete_recv(), and qib7322_complete_recv().