linux/drivers/infiniband/sw/rxe/rxe_icrc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
   2/*
   3 * Copyright (c) 2016 Mellanox Technologies Ltd. All rights reserved.
   4 * Copyright (c) 2015 System Fabric Works, Inc. All rights reserved.
   5 */
   6
   7#include "rxe.h"
   8#include "rxe_loc.h"
   9
  10/* Compute a partial ICRC for all the IB transport headers. */
  11u32 rxe_icrc_hdr(struct rxe_pkt_info *pkt, struct sk_buff *skb)
  12{
  13        unsigned int bth_offset = 0;
  14        struct iphdr *ip4h = NULL;
  15        struct ipv6hdr *ip6h = NULL;
  16        struct udphdr *udph;
  17        struct rxe_bth *bth;
  18        int crc;
  19        int length;
  20        int hdr_size = sizeof(struct udphdr) +
  21                (skb->protocol == htons(ETH_P_IP) ?
  22                sizeof(struct iphdr) : sizeof(struct ipv6hdr));
  23        /* pseudo header buffer size is calculate using ipv6 header size since
  24         * it is bigger than ipv4
  25         */
  26        u8 pshdr[sizeof(struct udphdr) +
  27                sizeof(struct ipv6hdr) +
  28                RXE_BTH_BYTES];
  29
  30        /* This seed is the result of computing a CRC with a seed of
  31         * 0xfffffff and 8 bytes of 0xff representing a masked LRH.
  32         */
  33        crc = 0xdebb20e3;
  34
  35        if (skb->protocol == htons(ETH_P_IP)) { /* IPv4 */
  36                memcpy(pshdr, ip_hdr(skb), hdr_size);
  37                ip4h = (struct iphdr *)pshdr;
  38                udph = (struct udphdr *)(ip4h + 1);
  39
  40                ip4h->ttl = 0xff;
  41                ip4h->check = CSUM_MANGLED_0;
  42                ip4h->tos = 0xff;
  43        } else {                                /* IPv6 */
  44                memcpy(pshdr, ipv6_hdr(skb), hdr_size);
  45                ip6h = (struct ipv6hdr *)pshdr;
  46                udph = (struct udphdr *)(ip6h + 1);
  47
  48                memset(ip6h->flow_lbl, 0xff, sizeof(ip6h->flow_lbl));
  49                ip6h->priority = 0xf;
  50                ip6h->hop_limit = 0xff;
  51        }
  52        udph->check = CSUM_MANGLED_0;
  53
  54        bth_offset += hdr_size;
  55
  56        memcpy(&pshdr[bth_offset], pkt->hdr, RXE_BTH_BYTES);
  57        bth = (struct rxe_bth *)&pshdr[bth_offset];
  58
  59        /* exclude bth.resv8a */
  60        bth->qpn |= cpu_to_be32(~BTH_QPN_MASK);
  61
  62        length = hdr_size + RXE_BTH_BYTES;
  63        crc = rxe_crc32(pkt->rxe, crc, pshdr, length);
  64
  65        /* And finish to compute the CRC on the remainder of the headers. */
  66        crc = rxe_crc32(pkt->rxe, crc, pkt->hdr + RXE_BTH_BYTES,
  67                        rxe_opcode[pkt->opcode].length - RXE_BTH_BYTES);
  68        return crc;
  69}
  70