aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/core/ud_header.c117
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c2
-rw-r--r--include/rdma/ib_pack.h30
4 files changed, 113 insertions, 38 deletions
diff --git a/drivers/infiniband/core/ud_header.c b/drivers/infiniband/core/ud_header.c
index 650b501eb142..cb0dd5ae2777 100644
--- a/drivers/infiniband/core/ud_header.c
+++ b/drivers/infiniband/core/ud_header.c
@@ -80,6 +80,29 @@ static const struct ib_field lrh_table[] = {
80 .size_bits = 16 } 80 .size_bits = 16 }
81}; 81};
82 82
83static const struct ib_field eth_table[] = {
84 { STRUCT_FIELD(eth, dmac_h),
85 .offset_words = 0,
86 .offset_bits = 0,
87 .size_bits = 32 },
88 { STRUCT_FIELD(eth, dmac_l),
89 .offset_words = 1,
90 .offset_bits = 0,
91 .size_bits = 16 },
92 { STRUCT_FIELD(eth, smac_h),
93 .offset_words = 1,
94 .offset_bits = 16,
95 .size_bits = 16 },
96 { STRUCT_FIELD(eth, smac_l),
97 .offset_words = 2,
98 .offset_bits = 0,
99 .size_bits = 32 },
100 { STRUCT_FIELD(eth, type),
101 .offset_words = 3,
102 .offset_bits = 0,
103 .size_bits = 16 }
104};
105
83static const struct ib_field grh_table[] = { 106static const struct ib_field grh_table[] = {
84 { STRUCT_FIELD(grh, ip_version), 107 { STRUCT_FIELD(grh, ip_version),
85 .offset_words = 0, 108 .offset_words = 0,
@@ -180,38 +203,38 @@ static const struct ib_field deth_table[] = {
180/** 203/**
181 * ib_ud_header_init - Initialize UD header structure 204 * ib_ud_header_init - Initialize UD header structure
182 * @payload_bytes:Length of packet payload 205 * @payload_bytes:Length of packet payload
206 * @lrh_present: specify if LRH is present
207 * @eth_present: specify if Eth header is present
183 * @grh_present:GRH flag (if non-zero, GRH will be included) 208 * @grh_present:GRH flag (if non-zero, GRH will be included)
184 * @immediate_present: specify if immediate data should be used 209 * @immediate_present: specify if immediate data is present
185 * @header:Structure to initialize 210 * @header:Structure to initialize
186 *
187 * ib_ud_header_init() initializes the lrh.link_version, lrh.link_next_header,
188 * lrh.packet_length, grh.ip_version, grh.payload_length,
189 * grh.next_header, bth.opcode, bth.pad_count and
190 * bth.transport_header_version fields of a &struct ib_ud_header given
191 * the payload length and whether a GRH will be included.
192 */ 211 */
193void ib_ud_header_init(int payload_bytes, 212void ib_ud_header_init(int payload_bytes,
213 int lrh_present,
214 int eth_present,
194 int grh_present, 215 int grh_present,
195 int immediate_present, 216 int immediate_present,
196 struct ib_ud_header *header) 217 struct ib_ud_header *header)
197{ 218{
198 u16 packet_length;
199
200 memset(header, 0, sizeof *header); 219 memset(header, 0, sizeof *header);
201 220
202 header->lrh.link_version = 0; 221 if (lrh_present) {
203 header->lrh.link_next_header = 222 u16 packet_length;
204 grh_present ? IB_LNH_IBA_GLOBAL : IB_LNH_IBA_LOCAL; 223
205 packet_length = (IB_LRH_BYTES + 224 header->lrh.link_version = 0;
206 IB_BTH_BYTES + 225 header->lrh.link_next_header =
207 IB_DETH_BYTES + 226 grh_present ? IB_LNH_IBA_GLOBAL : IB_LNH_IBA_LOCAL;
208 payload_bytes + 227 packet_length = (IB_LRH_BYTES +
209 4 + /* ICRC */ 228 IB_BTH_BYTES +
210 3) / 4; /* round up */ 229 IB_DETH_BYTES +
211 230 (grh_present ? IB_GRH_BYTES : 0) +
212 header->grh_present = grh_present; 231 payload_bytes +
232 4 + /* ICRC */
233 3) / 4; /* round up */
234 header->lrh.packet_length = cpu_to_be16(packet_length);
235 }
236
213 if (grh_present) { 237 if (grh_present) {
214 packet_length += IB_GRH_BYTES / 4;
215 header->grh.ip_version = 6; 238 header->grh.ip_version = 6;
216 header->grh.payload_length = 239 header->grh.payload_length =
217 cpu_to_be16((IB_BTH_BYTES + 240 cpu_to_be16((IB_BTH_BYTES +
@@ -222,19 +245,51 @@ void ib_ud_header_init(int payload_bytes,
222 header->grh.next_header = 0x1b; 245 header->grh.next_header = 0x1b;
223 } 246 }
224 247
225 header->lrh.packet_length = cpu_to_be16(packet_length);
226
227 header->immediate_present = immediate_present;
228 if (immediate_present) 248 if (immediate_present)
229 header->bth.opcode = IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE; 249 header->bth.opcode = IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE;
230 else 250 else
231 header->bth.opcode = IB_OPCODE_UD_SEND_ONLY; 251 header->bth.opcode = IB_OPCODE_UD_SEND_ONLY;
232 header->bth.pad_count = (4 - payload_bytes) & 3; 252 header->bth.pad_count = (4 - payload_bytes) & 3;
233 header->bth.transport_header_version = 0; 253 header->bth.transport_header_version = 0;
254
255 header->lrh_present = lrh_present;
256 header->eth_present = eth_present;
257 header->grh_present = grh_present;
258 header->immediate_present = immediate_present;
234} 259}
235EXPORT_SYMBOL(ib_ud_header_init); 260EXPORT_SYMBOL(ib_ud_header_init);
236 261
237/** 262/**
263 * ib_lrh_header_pack - Pack LRH header struct into wire format
264 * @lrh:unpacked LRH header struct
265 * @buf:Buffer to pack into
266 *
267 * ib_lrh_header_pack() packs the LRH header structure @lrh into
268 * wire format in the buffer @buf.
269 */
270int ib_lrh_header_pack(struct ib_unpacked_lrh *lrh, void *buf)
271{
272 ib_pack(lrh_table, ARRAY_SIZE(lrh_table), lrh, buf);
273 return 0;
274}
275EXPORT_SYMBOL(ib_lrh_header_pack);
276
277/**
278 * ib_lrh_header_unpack - Unpack LRH structure from wire format
279 * @lrh:unpacked LRH header struct
280 * @buf:Buffer to pack into
281 *
282 * ib_lrh_header_unpack() unpacks the LRH header structure from
283 * wire format (in buf) into @lrh.
284 */
285int ib_lrh_header_unpack(void *buf, struct ib_unpacked_lrh *lrh)
286{
287 ib_unpack(lrh_table, ARRAY_SIZE(lrh_table), buf, lrh);
288 return 0;
289}
290EXPORT_SYMBOL(ib_lrh_header_unpack);
291
292/**
238 * ib_ud_header_pack - Pack UD header struct into wire format 293 * ib_ud_header_pack - Pack UD header struct into wire format
239 * @header:UD header struct 294 * @header:UD header struct
240 * @buf:Buffer to pack into 295 * @buf:Buffer to pack into
@@ -247,10 +302,16 @@ int ib_ud_header_pack(struct ib_ud_header *header,
247{ 302{
248 int len = 0; 303 int len = 0;
249 304
250 ib_pack(lrh_table, ARRAY_SIZE(lrh_table), 305 if (header->lrh_present) {
251 &header->lrh, buf); 306 ib_pack(lrh_table, ARRAY_SIZE(lrh_table),
252 len += IB_LRH_BYTES; 307 &header->lrh, buf + len);
253 308 len += IB_LRH_BYTES;
309 }
310 if (header->eth_present) {
311 ib_pack(eth_table, ARRAY_SIZE(eth_table),
312 &header->eth, buf + len);
313 len += IB_ETH_BYTES;
314 }
254 if (header->grh_present) { 315 if (header->grh_present) {
255 ib_pack(grh_table, ARRAY_SIZE(grh_table), 316 ib_pack(grh_table, ARRAY_SIZE(grh_table),
256 &header->grh, buf + len); 317 &header->grh, buf + len);
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 6a60827b2301..bb1277c8fbf0 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -1231,7 +1231,7 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_send_wr *wr,
1231 for (i = 0; i < wr->num_sge; ++i) 1231 for (i = 0; i < wr->num_sge; ++i)
1232 send_size += wr->sg_list[i].length; 1232 send_size += wr->sg_list[i].length;
1233 1233
1234 ib_ud_header_init(send_size, mlx4_ib_ah_grh_present(ah), 0, &sqp->ud_header); 1234 ib_ud_header_init(send_size, 1, 0, mlx4_ib_ah_grh_present(ah), 0, &sqp->ud_header);
1235 1235
1236 sqp->ud_header.lrh.service_level = 1236 sqp->ud_header.lrh.service_level =
1237 be32_to_cpu(ah->av.sl_tclass_flowlabel) >> 28; 1237 be32_to_cpu(ah->av.sl_tclass_flowlabel) >> 28;
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index d2d172e6289c..1a1c55fb13f3 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -1493,7 +1493,7 @@ static int build_mlx_header(struct mthca_dev *dev, struct mthca_sqp *sqp,
1493 int err; 1493 int err;
1494 u16 pkey; 1494 u16 pkey;
1495 1495
1496 ib_ud_header_init(256, /* assume a MAD */ 1496 ib_ud_header_init(256, /* assume a MAD */ 1, 0,
1497 mthca_ah_grh_present(to_mah(wr->wr.ud.ah)), 0, 1497 mthca_ah_grh_present(to_mah(wr->wr.ud.ah)), 0,
1498 &sqp->ud_header); 1498 &sqp->ud_header);
1499 1499
diff --git a/include/rdma/ib_pack.h b/include/rdma/ib_pack.h
index cbb50f4da3dd..6b91d8e7a1fa 100644
--- a/include/rdma/ib_pack.h
+++ b/include/rdma/ib_pack.h
@@ -37,6 +37,7 @@
37 37
38enum { 38enum {
39 IB_LRH_BYTES = 8, 39 IB_LRH_BYTES = 8,
40 IB_ETH_BYTES = 14,
40 IB_GRH_BYTES = 40, 41 IB_GRH_BYTES = 40,
41 IB_BTH_BYTES = 12, 42 IB_BTH_BYTES = 12,
42 IB_DETH_BYTES = 8 43 IB_DETH_BYTES = 8
@@ -210,14 +211,25 @@ struct ib_unpacked_deth {
210 __be32 source_qpn; 211 __be32 source_qpn;
211}; 212};
212 213
214struct ib_unpacked_eth {
215 u8 dmac_h[4];
216 u8 dmac_l[2];
217 u8 smac_h[2];
218 u8 smac_l[4];
219 __be16 type;
220};
221
213struct ib_ud_header { 222struct ib_ud_header {
223 int lrh_present;
214 struct ib_unpacked_lrh lrh; 224 struct ib_unpacked_lrh lrh;
215 int grh_present; 225 int eth_present;
216 struct ib_unpacked_grh grh; 226 struct ib_unpacked_eth eth;
217 struct ib_unpacked_bth bth; 227 int grh_present;
228 struct ib_unpacked_grh grh;
229 struct ib_unpacked_bth bth;
218 struct ib_unpacked_deth deth; 230 struct ib_unpacked_deth deth;
219 int immediate_present; 231 int immediate_present;
220 __be32 immediate_data; 232 __be32 immediate_data;
221}; 233};
222 234
223void ib_pack(const struct ib_field *desc, 235void ib_pack(const struct ib_field *desc,
@@ -230,9 +242,11 @@ void ib_unpack(const struct ib_field *desc,
230 void *buf, 242 void *buf,
231 void *structure); 243 void *structure);
232 244
233void ib_ud_header_init(int payload_bytes, 245void ib_ud_header_init(int payload_bytes,
234 int grh_present, 246 int lrh_present,
235 int immediate_present, 247 int eth_present,
248 int grh_present,
249 int immediate_present,
236 struct ib_ud_header *header); 250 struct ib_ud_header *header);
237 251
238int ib_ud_header_pack(struct ib_ud_header *header, 252int ib_ud_header_pack(struct ib_ud_header *header,