func: static void vmxnet3_rx_need_csum_calculate(struct VmxnetRxPkt *pkt,
  
                                             const void *pkt_data,
  
                                             size_t pkt_len)
  
  {
  
      struct virtio_net_hdr *vhdr;
  
      bool isip4, isip6, istcp, isudp;
  
      uint8_t *data;
  
      int len;
  
  
  
      if (!vmxnet_rx_pkt_has_virt_hdr(pkt)) {
  
          return;
  
      }
  
  
  
      vhdr = vmxnet_rx_pkt_get_vhdr(pkt);
  
      if (!VMXNET_FLAG_IS_SET(vhdr->flags, VIRTIO_NET_HDR_F_NEEDS_CSUM)) {
  
          return;
  
      }
  
  
  
      vmxnet_rx_pkt_get_protocols(pkt, &isip4, &isip6, &isudp, &istcp);
  
      if (!(isip4 || isip6) || !(istcp || isudp)) {
  
          return;
  
      }
  
  
  
      vmxnet3_dump_virt_hdr(vhdr);
  
  
  
      /* Validate packet len: csum_start + scum_offset + length of csum field */
  
      if (pkt_len < (vhdr->csum_start + vhdr->csum_offset + 2)) {
  
          VMW_PKPRN("packet len:%d < csum_start(%d) + csum_offset(%d) + 2, "
  
                    "cannot calculate checksum",
  
                    len, vhdr->csum_start, vhdr->csum_offset);
  
          return;
  
      }
  
  
  
      data = (uint8_t *)pkt_data + vhdr->csum_start;
  
      len = pkt_len - vhdr->csum_start;
  
      /* Put the checksum obtained into the packet */
  
      stw_be_p(data + vhdr->csum_offset, net_raw_checksum(data, len));
  
  
  
      vhdr->flags &= ~VIRTIO_NET_HDR_F_NEEDS_CSUM;
  
      vhdr->flags |= VIRTIO_NET_HDR_F_DATA_VALID;
  
  }
  