diff options
author | Eli Cohen <eli@dev.mellanox.co.il> | 2010-08-26 10:17:56 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2010-10-14 15:41:29 -0400 |
commit | ff7f5aab354dee01f29c9c00933f6d4aa590eadb (patch) | |
tree | c6f4075f712808ba76927224fac2960f4c5353ec | |
parent | 3c86aa70bf677a31b71c8292e349242e26cbc743 (diff) |
IB/pack: IBoE UD packet packing support
Add support for packing IBoE packet headers.
Signed-off-by: Eli Cohen <eli@mellanox.co.il>
[ Clean up and fix ib_ud_header_init() a bit. - Roland ]
Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r-- | drivers/infiniband/core/ud_header.c | 117 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/qp.c | 2 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_qp.c | 2 | ||||
-rw-r--r-- | include/rdma/ib_pack.h | 30 |
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 | ||
83 | static 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 | |||
83 | static const struct ib_field grh_table[] = { | 106 | static 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 | */ |
193 | void ib_ud_header_init(int payload_bytes, | 212 | void 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 | } |
235 | EXPORT_SYMBOL(ib_ud_header_init); | 260 | EXPORT_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 | */ | ||
270 | int 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 | } | ||
275 | EXPORT_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 | */ | ||
285 | int 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 | } | ||
290 | EXPORT_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 | ||
38 | enum { | 38 | enum { |
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 | ||
214 | struct 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 | |||
213 | struct ib_ud_header { | 222 | struct 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 | ||
223 | void ib_pack(const struct ib_field *desc, | 235 | void 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 | ||
233 | void ib_ud_header_init(int payload_bytes, | 245 | void 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 | ||
238 | int ib_ud_header_pack(struct ib_ud_header *header, | 252 | int ib_ud_header_pack(struct ib_ud_header *header, |