blob: d57b5e956ceba75aa009a127dc21ccb67c214c0a [file] [log] [blame]
Moni Shoua8700e3e2016-06-16 16:45:23 +03001/*
2 * Copyright (c) 2016 Mellanox Technologies Ltd. All rights reserved.
3 * Copyright (c) 2015 System Fabric Works, Inc. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33
34#ifndef RXE_HDR_H
35#define RXE_HDR_H
36
37/* extracted information about a packet carried in an sk_buff struct fits in
38 * the skbuff cb array. Must be at most 48 bytes. stored in control block of
39 * sk_buff for received packets.
40 */
41struct rxe_pkt_info {
42 struct rxe_dev *rxe; /* device that owns packet */
43 struct rxe_qp *qp; /* qp that owns packet */
44 struct rxe_send_wqe *wqe; /* send wqe */
45 u8 *hdr; /* points to bth */
46 u32 mask; /* useful info about pkt */
47 u32 psn; /* bth psn of packet */
48 u16 pkey_index; /* partition of pkt */
49 u16 paylen; /* length of bth - icrc */
50 u8 port_num; /* port pkt received on */
51 u8 opcode; /* bth opcode of packet */
52 u8 offset; /* bth offset from pkt->hdr */
53};
54
55/* Macros should be used only for received skb */
56#define SKB_TO_PKT(skb) ((struct rxe_pkt_info *)(skb)->cb)
57#define PKT_TO_SKB(pkt) container_of((void *)(pkt), struct sk_buff, cb)
58
59/*
60 * IBA header types and methods
61 *
62 * Some of these are for reference and completeness only since
63 * rxe does not currently support RD transport
64 * most of this could be moved into IB core. ib_pack.h has
65 * part of this but is incomplete
66 *
67 * Header specific routines to insert/extract values to/from headers
68 * the routines that are named __hhh_(set_)fff() take a pointer to a
69 * hhh header and get(set) the fff field. The routines named
70 * hhh_(set_)fff take a packet info struct and find the
71 * header and field based on the opcode in the packet.
72 * Conversion to/from network byte order from cpu order is also done.
73 */
74
75#define RXE_ICRC_SIZE (4)
76#define RXE_MAX_HDR_LENGTH (80)
77
78/******************************************************************************
79 * Base Transport Header
80 ******************************************************************************/
81struct rxe_bth {
82 u8 opcode;
83 u8 flags;
84 __be16 pkey;
85 __be32 qpn;
86 __be32 apsn;
87};
88
89#define BTH_TVER (0)
90#define BTH_DEF_PKEY (0xffff)
91
92#define BTH_SE_MASK (0x80)
93#define BTH_MIG_MASK (0x40)
94#define BTH_PAD_MASK (0x30)
95#define BTH_TVER_MASK (0x0f)
96#define BTH_FECN_MASK (0x80000000)
97#define BTH_BECN_MASK (0x40000000)
98#define BTH_RESV6A_MASK (0x3f000000)
99#define BTH_QPN_MASK (0x00ffffff)
100#define BTH_ACK_MASK (0x80000000)
101#define BTH_RESV7_MASK (0x7f000000)
102#define BTH_PSN_MASK (0x00ffffff)
103
104static inline u8 __bth_opcode(void *arg)
105{
106 struct rxe_bth *bth = arg;
107
108 return bth->opcode;
109}
110
111static inline void __bth_set_opcode(void *arg, u8 opcode)
112{
113 struct rxe_bth *bth = arg;
114
115 bth->opcode = opcode;
116}
117
118static inline u8 __bth_se(void *arg)
119{
120 struct rxe_bth *bth = arg;
121
122 return 0 != (BTH_SE_MASK & bth->flags);
123}
124
125static inline void __bth_set_se(void *arg, int se)
126{
127 struct rxe_bth *bth = arg;
128
129 if (se)
130 bth->flags |= BTH_SE_MASK;
131 else
132 bth->flags &= ~BTH_SE_MASK;
133}
134
135static inline u8 __bth_mig(void *arg)
136{
137 struct rxe_bth *bth = arg;
138
139 return 0 != (BTH_MIG_MASK & bth->flags);
140}
141
142static inline void __bth_set_mig(void *arg, u8 mig)
143{
144 struct rxe_bth *bth = arg;
145
146 if (mig)
147 bth->flags |= BTH_MIG_MASK;
148 else
149 bth->flags &= ~BTH_MIG_MASK;
150}
151
152static inline u8 __bth_pad(void *arg)
153{
154 struct rxe_bth *bth = arg;
155
156 return (BTH_PAD_MASK & bth->flags) >> 4;
157}
158
159static inline void __bth_set_pad(void *arg, u8 pad)
160{
161 struct rxe_bth *bth = arg;
162
163 bth->flags = (BTH_PAD_MASK & (pad << 4)) |
164 (~BTH_PAD_MASK & bth->flags);
165}
166
167static inline u8 __bth_tver(void *arg)
168{
169 struct rxe_bth *bth = arg;
170
171 return BTH_TVER_MASK & bth->flags;
172}
173
174static inline void __bth_set_tver(void *arg, u8 tver)
175{
176 struct rxe_bth *bth = arg;
177
178 bth->flags = (BTH_TVER_MASK & tver) |
179 (~BTH_TVER_MASK & bth->flags);
180}
181
182static inline u16 __bth_pkey(void *arg)
183{
184 struct rxe_bth *bth = arg;
185
186 return be16_to_cpu(bth->pkey);
187}
188
189static inline void __bth_set_pkey(void *arg, u16 pkey)
190{
191 struct rxe_bth *bth = arg;
192
193 bth->pkey = cpu_to_be16(pkey);
194}
195
196static inline u32 __bth_qpn(void *arg)
197{
198 struct rxe_bth *bth = arg;
199
200 return BTH_QPN_MASK & be32_to_cpu(bth->qpn);
201}
202
203static inline void __bth_set_qpn(void *arg, u32 qpn)
204{
205 struct rxe_bth *bth = arg;
206 u32 resvqpn = be32_to_cpu(bth->qpn);
207
208 bth->qpn = cpu_to_be32((BTH_QPN_MASK & qpn) |
209 (~BTH_QPN_MASK & resvqpn));
210}
211
212static inline int __bth_fecn(void *arg)
213{
214 struct rxe_bth *bth = arg;
215
216 return 0 != (cpu_to_be32(BTH_FECN_MASK) & bth->qpn);
217}
218
219static inline void __bth_set_fecn(void *arg, int fecn)
220{
221 struct rxe_bth *bth = arg;
222
223 if (fecn)
224 bth->qpn |= cpu_to_be32(BTH_FECN_MASK);
225 else
226 bth->qpn &= ~cpu_to_be32(BTH_FECN_MASK);
227}
228
229static inline int __bth_becn(void *arg)
230{
231 struct rxe_bth *bth = arg;
232
233 return 0 != (cpu_to_be32(BTH_BECN_MASK) & bth->qpn);
234}
235
236static inline void __bth_set_becn(void *arg, int becn)
237{
238 struct rxe_bth *bth = arg;
239
240 if (becn)
241 bth->qpn |= cpu_to_be32(BTH_BECN_MASK);
242 else
243 bth->qpn &= ~cpu_to_be32(BTH_BECN_MASK);
244}
245
246static inline u8 __bth_resv6a(void *arg)
247{
248 struct rxe_bth *bth = arg;
249
250 return (BTH_RESV6A_MASK & be32_to_cpu(bth->qpn)) >> 24;
251}
252
253static inline void __bth_set_resv6a(void *arg)
254{
255 struct rxe_bth *bth = arg;
256
257 bth->qpn = cpu_to_be32(~BTH_RESV6A_MASK);
258}
259
260static inline int __bth_ack(void *arg)
261{
262 struct rxe_bth *bth = arg;
263
264 return 0 != (cpu_to_be32(BTH_ACK_MASK) & bth->apsn);
265}
266
267static inline void __bth_set_ack(void *arg, int ack)
268{
269 struct rxe_bth *bth = arg;
270
271 if (ack)
272 bth->apsn |= cpu_to_be32(BTH_ACK_MASK);
273 else
274 bth->apsn &= ~cpu_to_be32(BTH_ACK_MASK);
275}
276
277static inline void __bth_set_resv7(void *arg)
278{
279 struct rxe_bth *bth = arg;
280
281 bth->apsn &= ~cpu_to_be32(BTH_RESV7_MASK);
282}
283
284static inline u32 __bth_psn(void *arg)
285{
286 struct rxe_bth *bth = arg;
287
288 return BTH_PSN_MASK & be32_to_cpu(bth->apsn);
289}
290
291static inline void __bth_set_psn(void *arg, u32 psn)
292{
293 struct rxe_bth *bth = arg;
294 u32 apsn = be32_to_cpu(bth->apsn);
295
296 bth->apsn = cpu_to_be32((BTH_PSN_MASK & psn) |
297 (~BTH_PSN_MASK & apsn));
298}
299
300static inline u8 bth_opcode(struct rxe_pkt_info *pkt)
301{
302 return __bth_opcode(pkt->hdr + pkt->offset);
303}
304
305static inline void bth_set_opcode(struct rxe_pkt_info *pkt, u8 opcode)
306{
307 __bth_set_opcode(pkt->hdr + pkt->offset, opcode);
308}
309
310static inline u8 bth_se(struct rxe_pkt_info *pkt)
311{
312 return __bth_se(pkt->hdr + pkt->offset);
313}
314
315static inline void bth_set_se(struct rxe_pkt_info *pkt, int se)
316{
317 __bth_set_se(pkt->hdr + pkt->offset, se);
318}
319
320static inline u8 bth_mig(struct rxe_pkt_info *pkt)
321{
322 return __bth_mig(pkt->hdr + pkt->offset);
323}
324
325static inline void bth_set_mig(struct rxe_pkt_info *pkt, u8 mig)
326{
327 __bth_set_mig(pkt->hdr + pkt->offset, mig);
328}
329
330static inline u8 bth_pad(struct rxe_pkt_info *pkt)
331{
332 return __bth_pad(pkt->hdr + pkt->offset);
333}
334
335static inline void bth_set_pad(struct rxe_pkt_info *pkt, u8 pad)
336{
337 __bth_set_pad(pkt->hdr + pkt->offset, pad);
338}
339
340static inline u8 bth_tver(struct rxe_pkt_info *pkt)
341{
342 return __bth_tver(pkt->hdr + pkt->offset);
343}
344
345static inline void bth_set_tver(struct rxe_pkt_info *pkt, u8 tver)
346{
347 __bth_set_tver(pkt->hdr + pkt->offset, tver);
348}
349
350static inline u16 bth_pkey(struct rxe_pkt_info *pkt)
351{
352 return __bth_pkey(pkt->hdr + pkt->offset);
353}
354
355static inline void bth_set_pkey(struct rxe_pkt_info *pkt, u16 pkey)
356{
357 __bth_set_pkey(pkt->hdr + pkt->offset, pkey);
358}
359
360static inline u32 bth_qpn(struct rxe_pkt_info *pkt)
361{
362 return __bth_qpn(pkt->hdr + pkt->offset);
363}
364
365static inline void bth_set_qpn(struct rxe_pkt_info *pkt, u32 qpn)
366{
367 __bth_set_qpn(pkt->hdr + pkt->offset, qpn);
368}
369
370static inline int bth_fecn(struct rxe_pkt_info *pkt)
371{
372 return __bth_fecn(pkt->hdr + pkt->offset);
373}
374
375static inline void bth_set_fecn(struct rxe_pkt_info *pkt, int fecn)
376{
377 __bth_set_fecn(pkt->hdr + pkt->offset, fecn);
378}
379
380static inline int bth_becn(struct rxe_pkt_info *pkt)
381{
382 return __bth_becn(pkt->hdr + pkt->offset);
383}
384
385static inline void bth_set_becn(struct rxe_pkt_info *pkt, int becn)
386{
387 __bth_set_becn(pkt->hdr + pkt->offset, becn);
388}
389
390static inline u8 bth_resv6a(struct rxe_pkt_info *pkt)
391{
392 return __bth_resv6a(pkt->hdr + pkt->offset);
393}
394
395static inline void bth_set_resv6a(struct rxe_pkt_info *pkt)
396{
397 __bth_set_resv6a(pkt->hdr + pkt->offset);
398}
399
400static inline int bth_ack(struct rxe_pkt_info *pkt)
401{
402 return __bth_ack(pkt->hdr + pkt->offset);
403}
404
405static inline void bth_set_ack(struct rxe_pkt_info *pkt, int ack)
406{
407 __bth_set_ack(pkt->hdr + pkt->offset, ack);
408}
409
410static inline void bth_set_resv7(struct rxe_pkt_info *pkt)
411{
412 __bth_set_resv7(pkt->hdr + pkt->offset);
413}
414
415static inline u32 bth_psn(struct rxe_pkt_info *pkt)
416{
417 return __bth_psn(pkt->hdr + pkt->offset);
418}
419
420static inline void bth_set_psn(struct rxe_pkt_info *pkt, u32 psn)
421{
422 __bth_set_psn(pkt->hdr + pkt->offset, psn);
423}
424
425static inline void bth_init(struct rxe_pkt_info *pkt, u8 opcode, int se,
426 int mig, int pad, u16 pkey, u32 qpn, int ack_req,
427 u32 psn)
428{
429 struct rxe_bth *bth = (struct rxe_bth *)(pkt->hdr + pkt->offset);
430
431 bth->opcode = opcode;
432 bth->flags = (pad << 4) & BTH_PAD_MASK;
433 if (se)
434 bth->flags |= BTH_SE_MASK;
435 if (mig)
436 bth->flags |= BTH_MIG_MASK;
437 bth->pkey = cpu_to_be16(pkey);
438 bth->qpn = cpu_to_be32(qpn & BTH_QPN_MASK);
439 psn &= BTH_PSN_MASK;
440 if (ack_req)
441 psn |= BTH_ACK_MASK;
442 bth->apsn = cpu_to_be32(psn);
443}
444
445/******************************************************************************
446 * Reliable Datagram Extended Transport Header
447 ******************************************************************************/
448struct rxe_rdeth {
449 __be32 een;
450};
451
452#define RDETH_EEN_MASK (0x00ffffff)
453
454static inline u8 __rdeth_een(void *arg)
455{
456 struct rxe_rdeth *rdeth = arg;
457
458 return RDETH_EEN_MASK & be32_to_cpu(rdeth->een);
459}
460
461static inline void __rdeth_set_een(void *arg, u32 een)
462{
463 struct rxe_rdeth *rdeth = arg;
464
465 rdeth->een = cpu_to_be32(RDETH_EEN_MASK & een);
466}
467
468static inline u8 rdeth_een(struct rxe_pkt_info *pkt)
469{
470 return __rdeth_een(pkt->hdr + pkt->offset
471 + rxe_opcode[pkt->opcode].offset[RXE_RDETH]);
472}
473
474static inline void rdeth_set_een(struct rxe_pkt_info *pkt, u32 een)
475{
476 __rdeth_set_een(pkt->hdr + pkt->offset
477 + rxe_opcode[pkt->opcode].offset[RXE_RDETH], een);
478}
479
480/******************************************************************************
481 * Datagram Extended Transport Header
482 ******************************************************************************/
483struct rxe_deth {
484 __be32 qkey;
485 __be32 sqp;
486};
487
488#define GSI_QKEY (0x80010000)
489#define DETH_SQP_MASK (0x00ffffff)
490
491static inline u32 __deth_qkey(void *arg)
492{
493 struct rxe_deth *deth = arg;
494
495 return be32_to_cpu(deth->qkey);
496}
497
498static inline void __deth_set_qkey(void *arg, u32 qkey)
499{
500 struct rxe_deth *deth = arg;
501
502 deth->qkey = cpu_to_be32(qkey);
503}
504
505static inline u32 __deth_sqp(void *arg)
506{
507 struct rxe_deth *deth = arg;
508
509 return DETH_SQP_MASK & be32_to_cpu(deth->sqp);
510}
511
512static inline void __deth_set_sqp(void *arg, u32 sqp)
513{
514 struct rxe_deth *deth = arg;
515
516 deth->sqp = cpu_to_be32(DETH_SQP_MASK & sqp);
517}
518
519static inline u32 deth_qkey(struct rxe_pkt_info *pkt)
520{
521 return __deth_qkey(pkt->hdr + pkt->offset
522 + rxe_opcode[pkt->opcode].offset[RXE_DETH]);
523}
524
525static inline void deth_set_qkey(struct rxe_pkt_info *pkt, u32 qkey)
526{
527 __deth_set_qkey(pkt->hdr + pkt->offset
528 + rxe_opcode[pkt->opcode].offset[RXE_DETH], qkey);
529}
530
531static inline u32 deth_sqp(struct rxe_pkt_info *pkt)
532{
533 return __deth_sqp(pkt->hdr + pkt->offset
534 + rxe_opcode[pkt->opcode].offset[RXE_DETH]);
535}
536
537static inline void deth_set_sqp(struct rxe_pkt_info *pkt, u32 sqp)
538{
539 __deth_set_sqp(pkt->hdr + pkt->offset
540 + rxe_opcode[pkt->opcode].offset[RXE_DETH], sqp);
541}
542
543/******************************************************************************
544 * RDMA Extended Transport Header
545 ******************************************************************************/
546struct rxe_reth {
547 __be64 va;
548 __be32 rkey;
549 __be32 len;
550};
551
552static inline u64 __reth_va(void *arg)
553{
554 struct rxe_reth *reth = arg;
555
556 return be64_to_cpu(reth->va);
557}
558
559static inline void __reth_set_va(void *arg, u64 va)
560{
561 struct rxe_reth *reth = arg;
562
563 reth->va = cpu_to_be64(va);
564}
565
566static inline u32 __reth_rkey(void *arg)
567{
568 struct rxe_reth *reth = arg;
569
570 return be32_to_cpu(reth->rkey);
571}
572
573static inline void __reth_set_rkey(void *arg, u32 rkey)
574{
575 struct rxe_reth *reth = arg;
576
577 reth->rkey = cpu_to_be32(rkey);
578}
579
580static inline u32 __reth_len(void *arg)
581{
582 struct rxe_reth *reth = arg;
583
584 return be32_to_cpu(reth->len);
585}
586
587static inline void __reth_set_len(void *arg, u32 len)
588{
589 struct rxe_reth *reth = arg;
590
591 reth->len = cpu_to_be32(len);
592}
593
594static inline u64 reth_va(struct rxe_pkt_info *pkt)
595{
596 return __reth_va(pkt->hdr + pkt->offset
597 + rxe_opcode[pkt->opcode].offset[RXE_RETH]);
598}
599
600static inline void reth_set_va(struct rxe_pkt_info *pkt, u64 va)
601{
602 __reth_set_va(pkt->hdr + pkt->offset
603 + rxe_opcode[pkt->opcode].offset[RXE_RETH], va);
604}
605
606static inline u32 reth_rkey(struct rxe_pkt_info *pkt)
607{
608 return __reth_rkey(pkt->hdr + pkt->offset
609 + rxe_opcode[pkt->opcode].offset[RXE_RETH]);
610}
611
612static inline void reth_set_rkey(struct rxe_pkt_info *pkt, u32 rkey)
613{
614 __reth_set_rkey(pkt->hdr + pkt->offset
615 + rxe_opcode[pkt->opcode].offset[RXE_RETH], rkey);
616}
617
618static inline u32 reth_len(struct rxe_pkt_info *pkt)
619{
620 return __reth_len(pkt->hdr + pkt->offset
621 + rxe_opcode[pkt->opcode].offset[RXE_RETH]);
622}
623
624static inline void reth_set_len(struct rxe_pkt_info *pkt, u32 len)
625{
626 __reth_set_len(pkt->hdr + pkt->offset
627 + rxe_opcode[pkt->opcode].offset[RXE_RETH], len);
628}
629
630/******************************************************************************
631 * Atomic Extended Transport Header
632 ******************************************************************************/
633struct rxe_atmeth {
634 __be64 va;
635 __be32 rkey;
636 __be64 swap_add;
637 __be64 comp;
638} __attribute__((__packed__));
639
640static inline u64 __atmeth_va(void *arg)
641{
642 struct rxe_atmeth *atmeth = arg;
643
644 return be64_to_cpu(atmeth->va);
645}
646
647static inline void __atmeth_set_va(void *arg, u64 va)
648{
649 struct rxe_atmeth *atmeth = arg;
650
651 atmeth->va = cpu_to_be64(va);
652}
653
654static inline u32 __atmeth_rkey(void *arg)
655{
656 struct rxe_atmeth *atmeth = arg;
657
658 return be32_to_cpu(atmeth->rkey);
659}
660
661static inline void __atmeth_set_rkey(void *arg, u32 rkey)
662{
663 struct rxe_atmeth *atmeth = arg;
664
665 atmeth->rkey = cpu_to_be32(rkey);
666}
667
668static inline u64 __atmeth_swap_add(void *arg)
669{
670 struct rxe_atmeth *atmeth = arg;
671
672 return be64_to_cpu(atmeth->swap_add);
673}
674
675static inline void __atmeth_set_swap_add(void *arg, u64 swap_add)
676{
677 struct rxe_atmeth *atmeth = arg;
678
679 atmeth->swap_add = cpu_to_be64(swap_add);
680}
681
682static inline u64 __atmeth_comp(void *arg)
683{
684 struct rxe_atmeth *atmeth = arg;
685
686 return be64_to_cpu(atmeth->comp);
687}
688
689static inline void __atmeth_set_comp(void *arg, u64 comp)
690{
691 struct rxe_atmeth *atmeth = arg;
692
693 atmeth->comp = cpu_to_be64(comp);
694}
695
696static inline u64 atmeth_va(struct rxe_pkt_info *pkt)
697{
698 return __atmeth_va(pkt->hdr + pkt->offset
699 + rxe_opcode[pkt->opcode].offset[RXE_ATMETH]);
700}
701
702static inline void atmeth_set_va(struct rxe_pkt_info *pkt, u64 va)
703{
704 __atmeth_set_va(pkt->hdr + pkt->offset
705 + rxe_opcode[pkt->opcode].offset[RXE_ATMETH], va);
706}
707
708static inline u32 atmeth_rkey(struct rxe_pkt_info *pkt)
709{
710 return __atmeth_rkey(pkt->hdr + pkt->offset
711 + rxe_opcode[pkt->opcode].offset[RXE_ATMETH]);
712}
713
714static inline void atmeth_set_rkey(struct rxe_pkt_info *pkt, u32 rkey)
715{
716 __atmeth_set_rkey(pkt->hdr + pkt->offset
717 + rxe_opcode[pkt->opcode].offset[RXE_ATMETH], rkey);
718}
719
720static inline u64 atmeth_swap_add(struct rxe_pkt_info *pkt)
721{
722 return __atmeth_swap_add(pkt->hdr + pkt->offset
723 + rxe_opcode[pkt->opcode].offset[RXE_ATMETH]);
724}
725
726static inline void atmeth_set_swap_add(struct rxe_pkt_info *pkt, u64 swap_add)
727{
728 __atmeth_set_swap_add(pkt->hdr + pkt->offset
729 + rxe_opcode[pkt->opcode].offset[RXE_ATMETH], swap_add);
730}
731
732static inline u64 atmeth_comp(struct rxe_pkt_info *pkt)
733{
734 return __atmeth_comp(pkt->hdr + pkt->offset
735 + rxe_opcode[pkt->opcode].offset[RXE_ATMETH]);
736}
737
738static inline void atmeth_set_comp(struct rxe_pkt_info *pkt, u64 comp)
739{
740 __atmeth_set_comp(pkt->hdr + pkt->offset
741 + rxe_opcode[pkt->opcode].offset[RXE_ATMETH], comp);
742}
743
744/******************************************************************************
745 * Ack Extended Transport Header
746 ******************************************************************************/
747struct rxe_aeth {
748 __be32 smsn;
749};
750
751#define AETH_SYN_MASK (0xff000000)
752#define AETH_MSN_MASK (0x00ffffff)
753
754enum aeth_syndrome {
755 AETH_TYPE_MASK = 0xe0,
756 AETH_ACK = 0x00,
757 AETH_RNR_NAK = 0x20,
758 AETH_RSVD = 0x40,
759 AETH_NAK = 0x60,
760 AETH_ACK_UNLIMITED = 0x1f,
761 AETH_NAK_PSN_SEQ_ERROR = 0x60,
762 AETH_NAK_INVALID_REQ = 0x61,
763 AETH_NAK_REM_ACC_ERR = 0x62,
764 AETH_NAK_REM_OP_ERR = 0x63,
765 AETH_NAK_INV_RD_REQ = 0x64,
766};
767
768static inline u8 __aeth_syn(void *arg)
769{
770 struct rxe_aeth *aeth = arg;
771
772 return (AETH_SYN_MASK & be32_to_cpu(aeth->smsn)) >> 24;
773}
774
775static inline void __aeth_set_syn(void *arg, u8 syn)
776{
777 struct rxe_aeth *aeth = arg;
778 u32 smsn = be32_to_cpu(aeth->smsn);
779
780 aeth->smsn = cpu_to_be32((AETH_SYN_MASK & (syn << 24)) |
781 (~AETH_SYN_MASK & smsn));
782}
783
784static inline u32 __aeth_msn(void *arg)
785{
786 struct rxe_aeth *aeth = arg;
787
788 return AETH_MSN_MASK & be32_to_cpu(aeth->smsn);
789}
790
791static inline void __aeth_set_msn(void *arg, u32 msn)
792{
793 struct rxe_aeth *aeth = arg;
794 u32 smsn = be32_to_cpu(aeth->smsn);
795
796 aeth->smsn = cpu_to_be32((AETH_MSN_MASK & msn) |
797 (~AETH_MSN_MASK & smsn));
798}
799
800static inline u8 aeth_syn(struct rxe_pkt_info *pkt)
801{
802 return __aeth_syn(pkt->hdr + pkt->offset
803 + rxe_opcode[pkt->opcode].offset[RXE_AETH]);
804}
805
806static inline void aeth_set_syn(struct rxe_pkt_info *pkt, u8 syn)
807{
808 __aeth_set_syn(pkt->hdr + pkt->offset
809 + rxe_opcode[pkt->opcode].offset[RXE_AETH], syn);
810}
811
812static inline u32 aeth_msn(struct rxe_pkt_info *pkt)
813{
814 return __aeth_msn(pkt->hdr + pkt->offset
815 + rxe_opcode[pkt->opcode].offset[RXE_AETH]);
816}
817
818static inline void aeth_set_msn(struct rxe_pkt_info *pkt, u32 msn)
819{
820 __aeth_set_msn(pkt->hdr + pkt->offset
821 + rxe_opcode[pkt->opcode].offset[RXE_AETH], msn);
822}
823
824/******************************************************************************
825 * Atomic Ack Extended Transport Header
826 ******************************************************************************/
827struct rxe_atmack {
828 __be64 orig;
829};
830
831static inline u64 __atmack_orig(void *arg)
832{
833 struct rxe_atmack *atmack = arg;
834
835 return be64_to_cpu(atmack->orig);
836}
837
838static inline void __atmack_set_orig(void *arg, u64 orig)
839{
840 struct rxe_atmack *atmack = arg;
841
842 atmack->orig = cpu_to_be64(orig);
843}
844
845static inline u64 atmack_orig(struct rxe_pkt_info *pkt)
846{
847 return __atmack_orig(pkt->hdr + pkt->offset
848 + rxe_opcode[pkt->opcode].offset[RXE_ATMACK]);
849}
850
851static inline void atmack_set_orig(struct rxe_pkt_info *pkt, u64 orig)
852{
853 __atmack_set_orig(pkt->hdr + pkt->offset
854 + rxe_opcode[pkt->opcode].offset[RXE_ATMACK], orig);
855}
856
857/******************************************************************************
858 * Immediate Extended Transport Header
859 ******************************************************************************/
860struct rxe_immdt {
861 __be32 imm;
862};
863
864static inline __be32 __immdt_imm(void *arg)
865{
866 struct rxe_immdt *immdt = arg;
867
868 return immdt->imm;
869}
870
871static inline void __immdt_set_imm(void *arg, __be32 imm)
872{
873 struct rxe_immdt *immdt = arg;
874
875 immdt->imm = imm;
876}
877
878static inline __be32 immdt_imm(struct rxe_pkt_info *pkt)
879{
880 return __immdt_imm(pkt->hdr + pkt->offset
881 + rxe_opcode[pkt->opcode].offset[RXE_IMMDT]);
882}
883
884static inline void immdt_set_imm(struct rxe_pkt_info *pkt, __be32 imm)
885{
886 __immdt_set_imm(pkt->hdr + pkt->offset
887 + rxe_opcode[pkt->opcode].offset[RXE_IMMDT], imm);
888}
889
890/******************************************************************************
891 * Invalidate Extended Transport Header
892 ******************************************************************************/
893struct rxe_ieth {
894 __be32 rkey;
895};
896
897static inline u32 __ieth_rkey(void *arg)
898{
899 struct rxe_ieth *ieth = arg;
900
901 return be32_to_cpu(ieth->rkey);
902}
903
904static inline void __ieth_set_rkey(void *arg, u32 rkey)
905{
906 struct rxe_ieth *ieth = arg;
907
908 ieth->rkey = cpu_to_be32(rkey);
909}
910
911static inline u32 ieth_rkey(struct rxe_pkt_info *pkt)
912{
913 return __ieth_rkey(pkt->hdr + pkt->offset
914 + rxe_opcode[pkt->opcode].offset[RXE_IETH]);
915}
916
917static inline void ieth_set_rkey(struct rxe_pkt_info *pkt, u32 rkey)
918{
919 __ieth_set_rkey(pkt->hdr + pkt->offset
920 + rxe_opcode[pkt->opcode].offset[RXE_IETH], rkey);
921}
922
923enum rxe_hdr_length {
924 RXE_BTH_BYTES = sizeof(struct rxe_bth),
925 RXE_DETH_BYTES = sizeof(struct rxe_deth),
926 RXE_IMMDT_BYTES = sizeof(struct rxe_immdt),
927 RXE_RETH_BYTES = sizeof(struct rxe_reth),
928 RXE_AETH_BYTES = sizeof(struct rxe_aeth),
929 RXE_ATMACK_BYTES = sizeof(struct rxe_atmack),
930 RXE_ATMETH_BYTES = sizeof(struct rxe_atmeth),
931 RXE_IETH_BYTES = sizeof(struct rxe_ieth),
932 RXE_RDETH_BYTES = sizeof(struct rxe_rdeth),
933};
934
935static inline size_t header_size(struct rxe_pkt_info *pkt)
936{
937 return pkt->offset + rxe_opcode[pkt->opcode].length;
938}
939
940static inline void *payload_addr(struct rxe_pkt_info *pkt)
941{
942 return pkt->hdr + pkt->offset
943 + rxe_opcode[pkt->opcode].offset[RXE_PAYLOAD];
944}
945
946static inline size_t payload_size(struct rxe_pkt_info *pkt)
947{
948 return pkt->paylen - rxe_opcode[pkt->opcode].offset[RXE_PAYLOAD]
949 - bth_pad(pkt) - RXE_ICRC_SIZE;
950}
951
952#endif /* RXE_HDR_H */