- uint16_t etype;
-
- /*
- * Determine where frame payload starts.
- * Jump over vlan headers if already present,
- * helpful for QinQ too.
- */
- KASSERT(mp->m_len >= ETHER_HDR_LEN,
- ("em_txcsum_pullup is not called (eh)?"));
- eh = mtod(mp, struct ether_vlan_header *);
- if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
- KASSERT(mp->m_len >= ETHER_HDR_LEN + EVL_ENCAPLEN,
- ("em_txcsum_pullup is not called (evh)?"));
- etype = ntohs(eh->evl_proto);
- ehdrlen = ETHER_HDR_LEN + EVL_ENCAPLEN;
- } else {
- etype = ntohs(eh->evl_encap_proto);
- ehdrlen = ETHER_HDR_LEN;
- }
-
- /*
- * We only support TCP/UDP for IPv4 for the moment.
- * TODO: Support SCTP too when it hits the tree.
- */
- if (etype != ETHERTYPE_IP)
- return 0;
-
- KASSERT(mp->m_len >= ehdrlen + EM_IPVHL_SIZE,
- ("em_txcsum_pullup is not called (eh+ip_vhl)?"));
-
- /* NOTE: We could only safely access ip.ip_vhl part */
- ip = (struct ip *)(mp->m_data + ehdrlen);
- ip_hlen = ip->ip_hl << 2;