-/* $OpenBSD: if_vmx.c,v 1.80 2024/02/09 15:22:41 jan Exp $ */
+/* $OpenBSD: if_vmx.c,v 1.81 2024/02/15 13:24:45 jan Exp $ */
/*
* Copyright (c) 2013 Tsubai Masanari
ifp->if_watchdog = vmxnet3_watchdog;
ifp->if_hardmtu = VMXNET3_MAX_MTU;
ifp->if_capabilities = IFCAP_VLAN_MTU;
-#if 0
- if (sc->sc_ds->upt_features & UPT1_F_CSUM)
+
+ if (sc->sc_ds->upt_features & UPT1_F_CSUM) {
ifp->if_capabilities |= IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4;
-#endif
+ ifp->if_capabilities |= IFCAP_CSUM_TCPv6 | IFCAP_CSUM_UDPv6;
+ }
+
#if NVLAN > 0
if (sc->sc_ds->upt_features & UPT1_F_VLAN)
ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
BUS_DMA_STREAMING | BUS_DMA_NOWAIT));
}
+void
+vmxnet3_tx_offload(struct vmxnet3_txdesc *sop, struct mbuf *m)
+{
+ struct ether_extracted ext;
+ uint32_t offset = 0;
+ uint32_t hdrlen;
+
+ /*
+ * VLAN Offload
+ */
+
+#if NVLAN > 0
+ if (ISSET(m->m_flags, M_VLANTAG)) {
+ sop->tx_word3 |= htole32(VMXNET3_TX_VTAG_MODE);
+ sop->tx_word3 |= htole32((m->m_pkthdr.ether_vtag &
+ VMXNET3_TX_VLANTAG_M) << VMXNET3_TX_VLANTAG_S);
+ }
+#endif
+
+ /*
+ * Checksum Offload
+ */
+
+ if (!ISSET(m->m_pkthdr.csum_flags, M_TCP_CSUM_OUT) &&
+ !ISSET(m->m_pkthdr.csum_flags, M_UDP_CSUM_OUT))
+ return;
+
+ ether_extract_headers(m, &ext);
+
+ hdrlen = sizeof(*ext.eh);
+ if (ext.evh)
+ hdrlen = sizeof(*ext.evh);
+
+ if (ext.ip4 || ext.ip6)
+ hdrlen += ext.iphlen;
+
+ if (ext.tcp)
+ offset = hdrlen + offsetof(struct tcphdr, th_sum);
+ else if (ext.udp)
+ offset = hdrlen + offsetof(struct udphdr, uh_sum);
+
+ hdrlen &= VMXNET3_TX_HLEN_M;
+ offset &= VMXNET3_TX_OP_M;
+
+ sop->tx_word3 |= htole32(VMXNET3_OM_CSUM << VMXNET3_TX_OM_S);
+ sop->tx_word3 |= htole32(hdrlen << VMXNET3_TX_HLEN_S);
+ sop->tx_word2 |= htole32(offset << VMXNET3_TX_OP_S);
+}
+
void
vmxnet3_start(struct ifqueue *ifq)
{
}
txd->tx_word3 = htole32(VMXNET3_TX_EOP | VMXNET3_TX_COMPREQ);
-#if NVLAN > 0
- if (ISSET(m->m_flags, M_VLANTAG)) {
- sop->tx_word3 |= htole32(VMXNET3_TX_VTAG_MODE);
- sop->tx_word3 |= htole32((m->m_pkthdr.ether_vtag &
- VMXNET3_TX_VLANTAG_M) << VMXNET3_TX_VLANTAG_S);
- }
-#endif
+ vmxnet3_tx_offload(sop, m);
ring->prod = prod;
/* Change the ownership by flipping the "generation" bit */