#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <byteswap.h>
#include <gpxe/iobuf.h>
#include <gpxe/infiniband.h>
#include <gpxe/ib_packet.h>
Go to the source code of this file.
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. | |
Definition in file ib_packet.c.
| 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.
| 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.
| 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 }
1.5.7.1