2 * Copyright (c) 2016 Mellanox Technologies Ltd. All rights reserved.
3 * Copyright (c) 2015 System Fabric Works, Inc. All rights reserved.
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:
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
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.
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
37 /* Compute a partial ICRC for all the IB transport headers. */
38 u32
rxe_icrc_hdr(struct rxe_pkt_info
*pkt
, struct sk_buff
*skb
)
40 unsigned int bth_offset
= 0;
41 struct iphdr
*ip4h
= NULL
;
42 struct ipv6hdr
*ip6h
= NULL
;
47 int hdr_size
= sizeof(struct udphdr
) +
48 (skb
->protocol
== htons(ETH_P_IP
) ?
49 sizeof(struct iphdr
) : sizeof(struct ipv6hdr
));
50 /* pseudo header buffer size is calculate using ipv6 header size since
51 * it is bigger than ipv4
53 u8 pshdr
[sizeof(struct udphdr
) +
54 sizeof(struct ipv6hdr
) +
57 /* This seed is the result of computing a CRC with a seed of
58 * 0xfffffff and 8 bytes of 0xff representing a masked LRH.
62 if (skb
->protocol
== htons(ETH_P_IP
)) { /* IPv4 */
63 memcpy(pshdr
, ip_hdr(skb
), hdr_size
);
64 ip4h
= (struct iphdr
*)pshdr
;
65 udph
= (struct udphdr
*)(ip4h
+ 1);
68 ip4h
->check
= CSUM_MANGLED_0
;
71 memcpy(pshdr
, ipv6_hdr(skb
), hdr_size
);
72 ip6h
= (struct ipv6hdr
*)pshdr
;
73 udph
= (struct udphdr
*)(ip6h
+ 1);
75 memset(ip6h
->flow_lbl
, 0xff, sizeof(ip6h
->flow_lbl
));
77 ip6h
->hop_limit
= 0xff;
79 udph
->check
= CSUM_MANGLED_0
;
81 bth_offset
+= hdr_size
;
83 memcpy(&pshdr
[bth_offset
], pkt
->hdr
, RXE_BTH_BYTES
);
84 bth
= (struct rxe_bth
*)&pshdr
[bth_offset
];
86 /* exclude bth.resv8a */
87 bth
->qpn
|= cpu_to_be32(~BTH_QPN_MASK
);
89 length
= hdr_size
+ RXE_BTH_BYTES
;
90 crc
= rxe_crc32(pkt
->rxe
, crc
, pshdr
, length
);
92 /* And finish to compute the CRC on the remainder of the headers. */
93 crc
= rxe_crc32(pkt
->rxe
, crc
, pkt
->hdr
+ RXE_BTH_BYTES
,
94 rxe_opcode
[pkt
->opcode
].length
- RXE_BTH_BYTES
);