ib_packet.h File Reference

Infiniband packet format. More...

Go to the source code of this file.

Data Structures

struct  ib_gid_half
 Half of an Infiniband Global Identifier. More...
struct  ib_gid
 An Infiniband Global Identifier. More...
struct  ib_local_route_header
 An Infiniband Local Route Header. More...
struct  ib_global_route_header
 An Infiniband Global Route Header. More...
struct  ib_base_transport_header
 An Infiniband Base Transport Header. More...
struct  ib_datagram_extended_transport_header
 An Infiniband Datagram Extended Transport Header. More...
union  ib_headers
 All known IB header formats. More...

Defines

#define IB_LID_NONE   0xffff
 Default Infiniband LID.
#define IB_LID_MULTICAST(lid)   ( ( (lid) >= 0xc000 ) && ( (lid) <= 0xfffe ) )
 Test for multicast LID.
#define IB_GRH_IPVER_IPv6   0x06
#define IB_GRH_NXTHDR_IBA   0x1b
#define IB_MAX_HEADER_SIZE   sizeof ( union ib_headers )
 Maximum size required for IB headers.

Enumerations

enum  ib_vl { IB_VL_DEFAULT = 0, IB_VL_SMP = 15 }
 Infiniband virtual lanes. More...
enum  ib_lnh { IB_LNH_RAW = 0, IB_LNH_IPv6 = 1, IB_LNH_BTH = 2, IB_LNH_GRH = 3 }
 An Infiniband Link Next Header value. More...
enum  ib_bth_opcode { BTH_OPCODE_UD_SEND = 0x64 }
 An Infiniband BTH opcode. More...

Functions

 FILE_LICENCE (GPL2_OR_LATER)
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 *av)
 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 *av)
 Remove IB headers.

Variables

struct ib_local_route_header packed
 An Infiniband Local Route Header.


Detailed Description

Infiniband packet format.

Definition in file ib_packet.h.


Define Documentation

#define IB_LID_NONE   0xffff

Default Infiniband LID.

Definition at line 65 of file ib_packet.h.

Referenced by alloc_ibdev().

#define IB_LID_MULTICAST ( lid   )     ( ( (lid) >= 0xc000 ) && ( (lid) <= 0xfffe ) )

Test for multicast LID.

Definition at line 68 of file ib_packet.h.

Referenced by ib_pull().

#define IB_GRH_IPVER_IPv6   0x06

Definition at line 91 of file ib_packet.h.

Referenced by ib_push().

#define IB_GRH_NXTHDR_IBA   0x1b

Definition at line 92 of file ib_packet.h.

Referenced by ib_push().

#define IB_MAX_HEADER_SIZE   sizeof ( union ib_headers )

Maximum size required for IB headers.

Definition at line 138 of file ib_packet.h.

Referenced by linda_post_send().


Enumeration Type Documentation

enum ib_vl

Infiniband virtual lanes.

Enumerator:
IB_VL_DEFAULT 
IB_VL_SMP 

Definition at line 51 of file ib_packet.h.

00051            {
00052         IB_VL_DEFAULT = 0,
00053         IB_VL_SMP = 15,
00054 };

enum ib_lnh

An Infiniband Link Next Header value.

Enumerator:
IB_LNH_RAW 
IB_LNH_IPv6 
IB_LNH_BTH 
IB_LNH_GRH 

Definition at line 57 of file ib_packet.h.

00057             {
00058         IB_LNH_RAW = 0,
00059         IB_LNH_IPv6 = 1,
00060         IB_LNH_BTH = 2,
00061         IB_LNH_GRH = 3
00062 };

An Infiniband BTH opcode.

Enumerator:
BTH_OPCODE_UD_SEND 

Definition at line 109 of file ib_packet.h.

00109                    {
00110         BTH_OPCODE_UD_SEND = 0x64,
00111 };


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER   ) 

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 av 
)

Add IB headers.

Parameters:
ibdev Infiniband device
iobuf I/O buffer to contain headers
qp Queue pair
payload_len Payload length
av Address vector

Definition at line 46 of file ib_packet.c.

References ib_base_transport_header::ack__psn, BTH_OPCODE_UD_SEND, io_buffer::data, DBGC2, DBGCP_HDA, ib_base_transport_header::dest_qp, ib_global_route_header::dgid, ib_local_route_header::dlid, ib_queue_pair::ext_qpn, ib_address_vector::gid, ib_device::gid, ib_address_vector::gid_present, 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_address_vector::lid, ib_device::lid, memcpy, NULL, ib_global_route_header::nxthdr, ib_base_transport_header::opcode, ib_global_route_header::paylen, ib_device::pkey, ib_base_transport_header::pkey, ib_work_queue::psn, ib_datagram_extended_transport_header::qkey, ib_address_vector::qkey, ib_address_vector::qpn, ib_base_transport_header::se__m__padcnt__tver, ib_queue_pair::send, ib_global_route_header::sgid, ib_address_vector::sl, 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 hermon_fill_mlx_send_wqe(), and linda_post_send().

00048                                                    {
00049         struct ib_local_route_header *lrh;
00050         struct ib_global_route_header *grh;
00051         struct ib_base_transport_header *bth;
00052         struct ib_datagram_extended_transport_header *deth;
00053         size_t orig_iob_len = iob_len ( iobuf );
00054         size_t pad_len;
00055         size_t lrh_len;
00056         size_t grh_len;
00057         unsigned int vl;
00058         unsigned int lnh;
00059 
00060         DBGC2 ( ibdev, "IBDEV %p TX %04x:%08lx => %04x:%08lx (key %08lx)\n",
00061                 ibdev, ibdev->lid, qp->ext_qpn, av->lid, av->qpn, av->qkey );
00062 
00063         /* Calculate packet length */
00064         pad_len = ( (-payload_len) & 0x3 );
00065         payload_len += pad_len;
00066         payload_len += 4; /* ICRC */
00067 
00068         /* Reserve space for headers */
00069         orig_iob_len = iob_len ( iobuf );
00070         deth = iob_push ( iobuf, sizeof ( *deth ) );
00071         bth = iob_push ( iobuf, sizeof ( *bth ) );
00072         grh_len = ( payload_len + iob_len ( iobuf ) - orig_iob_len );
00073         grh = ( av->gid_present ?
00074                 iob_push ( iobuf, sizeof ( *grh ) ) : NULL );
00075         lrh = iob_push ( iobuf, sizeof ( *lrh ) );
00076         lrh_len = ( payload_len + iob_len ( iobuf ) - orig_iob_len );
00077 
00078         /* Construct LRH */
00079         vl = ( ( qp->ext_qpn == IB_QPN_SMI ) ? IB_VL_SMP : IB_VL_DEFAULT );
00080         lrh->vl__lver = ( vl << 4 );
00081         lnh = ( grh ? IB_LNH_GRH : IB_LNH_BTH );
00082         lrh->sl__lnh = ( ( av->sl << 4 ) | lnh );
00083         lrh->dlid = htons ( av->lid );
00084         lrh->length = htons ( lrh_len >> 2 );
00085         lrh->slid = htons ( ibdev->lid );
00086 
00087         /* Construct GRH, if required */
00088         if ( grh ) {
00089                 grh->ipver__tclass__flowlabel =
00090                         htonl ( IB_GRH_IPVER_IPv6 << 28 );
00091                 grh->paylen = htons ( grh_len );
00092                 grh->nxthdr = IB_GRH_NXTHDR_IBA;
00093                 grh->hoplmt = 0;
00094                 memcpy ( &grh->sgid, &ibdev->gid, sizeof ( grh->sgid ) );
00095                 memcpy ( &grh->dgid, &av->gid, sizeof ( grh->dgid ) );
00096         }
00097 
00098         /* Construct BTH */
00099         bth->opcode = BTH_OPCODE_UD_SEND;
00100         bth->se__m__padcnt__tver = ( pad_len << 4 );
00101         bth->pkey = htons ( ibdev->pkey );
00102         bth->dest_qp = htonl ( av->qpn );
00103         bth->ack__psn = htonl ( ( qp->send.psn++ ) & 0xffffffUL );
00104 
00105         /* Construct DETH */
00106         deth->qkey = htonl ( av->qkey );
00107         deth->src_qp = htonl ( qp->ext_qpn );
00108 
00109         DBGCP_HDA ( ibdev, 0, iobuf->data,
00110                     ( iob_len ( iobuf ) - orig_iob_len ) );
00111 
00112         return 0;
00113 }

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

Remove IB headers.

Parameters:
ibdev Infiniband device
iobuf I/O buffer containing headers
qp Queue pair to fill in, or NULL
payload_len Payload length to fill in, or NULL
av Address vector to fill in

Definition at line 124 of file ib_packet.c.

References assert, BTH_OPCODE_UD_SEND, io_buffer::data, DBGC, DBGC2, DBGCP_HDA, ib_base_transport_header::dest_qp, ib_global_route_header::dgid, ib_local_route_header::dlid, ib_gid::dwords, EINVAL, ENODEV, ENOTSUP, ib_queue_pair::ext_qpn, ib_address_vector::gid, ib_address_vector::gid_present, ib_find_qp_mgid(), ib_find_qp_qpn(), IB_LID_MULTICAST, IB_LNH_BTH, IB_LNH_GRH, iob_len(), iob_pull, ib_local_route_header::length, ib_address_vector::lid, memcpy, memset(), ntohl, ntohs, NULL, ib_base_transport_header::opcode, ib_datagram_extended_transport_header::qkey, ib_address_vector::qkey, 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, ib_datagram_extended_transport_header::src_qp, and ib_gid::u.

Referenced by linda_complete_recv().

00126                                              {
00127         struct ib_local_route_header *lrh;
00128         struct ib_global_route_header *grh;
00129         struct ib_base_transport_header *bth;
00130         struct ib_datagram_extended_transport_header *deth;
00131         size_t orig_iob_len = iob_len ( iobuf );
00132         unsigned int lnh;
00133         size_t pad_len;
00134         unsigned long qpn;
00135         unsigned int lid;
00136 
00137         /* Clear return values */
00138         if ( qp )
00139                 *qp = NULL;
00140         if ( payload_len )
00141                 *payload_len = 0;
00142         memset ( av, 0, sizeof ( *av ) );
00143 
00144         /* Extract LRH */
00145         if ( iob_len ( iobuf ) < sizeof ( *lrh ) ) {
00146                 DBGC ( ibdev, "IBDEV %p RX too short (%zd bytes) for LRH\n",
00147                        ibdev, iob_len ( iobuf ) );
00148                 return -EINVAL;
00149         }
00150         lrh = iobuf->data;
00151         iob_pull ( iobuf, sizeof ( *lrh ) );
00152         av->lid = ntohs ( lrh->slid );
00153         av->sl = ( lrh->sl__lnh >> 4 );
00154         lnh = ( lrh->sl__lnh & 0x3 );
00155         lid = ntohs ( lrh->dlid );
00156 
00157         /* Reject unsupported packets */
00158         if ( ! ( ( lnh == IB_LNH_BTH ) || ( lnh == IB_LNH_GRH ) ) ) {
00159                 DBGC ( ibdev, "IBDEV %p RX unsupported LNH %x\n",
00160                        ibdev, lnh );
00161                 return -ENOTSUP;
00162         }
00163 
00164         /* Extract GRH, if present */
00165         if ( lnh == IB_LNH_GRH ) {
00166                 if ( iob_len ( iobuf ) < sizeof ( *grh ) ) {
00167                         DBGC ( ibdev, "IBDEV %p RX too short (%zd bytes) "
00168                                "for GRH\n", ibdev, iob_len ( iobuf ) );
00169                         return -EINVAL;
00170                 }
00171                 grh = iobuf->data;
00172                 iob_pull ( iobuf, sizeof ( *grh ) );
00173                 av->gid_present = 1;
00174                 memcpy ( &av->gid, &grh->sgid, sizeof ( av->gid ) );
00175         } else {
00176                 grh = NULL;
00177         }
00178 
00179         /* Extract BTH */
00180         if ( iob_len ( iobuf ) < sizeof ( *bth ) ) {
00181                 DBGC ( ibdev, "IBDEV %p RX too short (%zd bytes) for BTH\n",
00182                        ibdev, iob_len ( iobuf ) );
00183                 return -EINVAL;
00184         }
00185         bth = iobuf->data;
00186         iob_pull ( iobuf, sizeof ( *bth ) );
00187         if ( bth->opcode != BTH_OPCODE_UD_SEND ) {
00188                 DBGC ( ibdev, "IBDEV %p unsupported BTH opcode %x\n",
00189                        ibdev, bth->opcode );
00190                 return -ENOTSUP;
00191         }
00192         qpn = ntohl ( bth->dest_qp );
00193 
00194         /* Extract DETH */
00195         if ( iob_len ( iobuf ) < sizeof ( *deth ) ) {
00196                 DBGC ( ibdev, "IBDEV %p RX too short (%zd bytes) for DETH\n",
00197                        ibdev, iob_len ( iobuf ) );
00198                 return -EINVAL;
00199         }
00200         deth = iobuf->data;
00201         iob_pull ( iobuf, sizeof ( *deth ) );
00202         av->qpn = ntohl ( deth->src_qp );
00203         av->qkey = ntohl ( deth->qkey );
00204 
00205         /* Calculate payload length, if applicable */
00206         if ( payload_len ) {
00207                 pad_len = ( ( bth->se__m__padcnt__tver >> 4 ) & 0x3 );
00208                 *payload_len = ( ( ntohs ( lrh->length ) << 2 )
00209                                  - ( orig_iob_len - iob_len ( iobuf ) )
00210                                  - pad_len - 4 /* ICRC */ );
00211         }
00212 
00213         /* Determine destination QP, if applicable */
00214         if ( qp ) {
00215                 if ( IB_LID_MULTICAST ( lid ) && grh ) {
00216                         if ( ! ( *qp = ib_find_qp_mgid ( ibdev, &grh->dgid ))){
00217                                 DBGC ( ibdev, "IBDEV %p RX for unknown MGID "
00218                                        "%08x:%08x:%08x:%08x\n", ibdev,
00219                                        ntohl ( grh->dgid.u.dwords[0] ),
00220                                        ntohl ( grh->dgid.u.dwords[1] ),
00221                                        ntohl ( grh->dgid.u.dwords[2] ),
00222                                        ntohl ( grh->dgid.u.dwords[3] ) );
00223                                 return -ENODEV;
00224                         }
00225                 } else {
00226                         if ( ! ( *qp = ib_find_qp_qpn ( ibdev, qpn ) ) ) {
00227                                 DBGC ( ibdev, "IBDEV %p RX for nonexistent "
00228                                        "QPN %lx\n", ibdev, qpn );
00229                                 return -ENODEV;
00230                         }
00231                 }
00232                 assert ( *qp );
00233         }
00234 
00235         DBGC2 ( ibdev, "IBDEV %p RX %04x:%08lx <= %04x:%08lx (key %08x)\n",
00236                 ibdev, lid, ( IB_LID_MULTICAST( lid ) ?
00237                               ( qp ? (*qp)->ext_qpn : -1UL ) : qpn ),
00238                 av->lid, av->qpn, ntohl ( deth->qkey ) );
00239         DBGCP_HDA ( ibdev, 0,
00240                     ( iobuf->data - ( orig_iob_len - iob_len ( iobuf ) ) ),
00241                     ( orig_iob_len - iob_len ( iobuf ) ) );
00242 
00243         return 0;
00244 }


Variable Documentation

An Infiniband Local Route Header.

All known IB header formats.

An Infiniband Datagram Extended Transport Header.

An Infiniband Base Transport Header.

An Infiniband Global Route Header.


Generated on Tue Apr 6 20:01:50 2010 for gPXE by  doxygen 1.5.7.1