Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci Add TX checksum offload supports for ixl(4)
details: https://anonhg.NetBSD.org/src/rev/81e13ae4c668
branches: trunk
changeset: 968736:81e13ae4c668
user: yamaguchi <yamaguchi%NetBSD.org@localhost>
date: Mon Jan 27 09:40:43 2020 +0000
description:
Add TX checksum offload supports for ixl(4)
diffstat:
sys/dev/pci/if_ixl.c | 104 +++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 92 insertions(+), 12 deletions(-)
diffs (164 lines):
diff -r 72a48e0a7f65 -r 81e13ae4c668 sys/dev/pci/if_ixl.c
--- a/sys/dev/pci/if_ixl.c Mon Jan 27 08:40:46 2020 +0000
+++ b/sys/dev/pci/if_ixl.c Mon Jan 27 09:40:43 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_ixl.c,v 1.27 2020/01/27 08:40:46 yamaguchi Exp $ */
+/* $NetBSD: if_ixl.c,v 1.28 2020/01/27 09:40:43 yamaguchi Exp $ */
/*
* Copyright (c) 2013-2015, Intel Corporation
@@ -104,6 +104,9 @@
#include <net/if_ether.h>
#include <net/rss_config.h>
+#include <netinet/tcp.h> /* for struct tcphdr */
+#include <netinet/udp.h> /* for struct udphdr */
+
#include <dev/pci/pcivar.h>
#include <dev/pci/pcidevs.h>
@@ -704,11 +707,19 @@
#define IXL_TX_INTR_PROCESS_LIMIT 256
#define IXL_RX_INTR_PROCESS_LIMIT 0U
-#define IXL_IFCAP_RXCSUM (IFCAP_CSUM_IPv4_Rx| \
- IFCAP_CSUM_TCPv4_Rx| \
- IFCAP_CSUM_UDPv4_Rx| \
- IFCAP_CSUM_TCPv6_Rx| \
+#define IXL_IFCAP_RXCSUM (IFCAP_CSUM_IPv4_Rx | \
+ IFCAP_CSUM_TCPv4_Rx | \
+ IFCAP_CSUM_UDPv4_Rx | \
+ IFCAP_CSUM_TCPv6_Rx | \
IFCAP_CSUM_UDPv6_Rx)
+#define IXL_IFCAP_TXCSUM (IFCAP_CSUM_IPv4_Tx | \
+ IFCAP_CSUM_TCPv4_Tx | \
+ IFCAP_CSUM_UDPv4_Tx | \
+ IFCAP_CSUM_TCPv6_Tx | \
+ IFCAP_CSUM_UDPv6_Tx)
+#define IXL_CSUM_ALL_OFFLOAD (M_CSUM_IPv4 | \
+ M_CSUM_TCPv4 | M_CSUM_TCPv6 | \
+ M_CSUM_UDPv4 | M_CSUM_UDPv6)
#define delaymsec(_x) DELAY(1000 * (_x))
#ifdef IXL_DEBUG
@@ -1340,8 +1351,9 @@
IFQ_SET_MAXLEN(&ifp->if_snd, sc->sc_tx_ring_ndescs);
IFQ_SET_READY(&ifp->if_snd);
ifp->if_capabilities |= IXL_IFCAP_RXCSUM;
+ ifp->if_capabilities |= IXL_IFCAP_TXCSUM;
#if 0
- ifp->if_capabilities |= IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_UDPv4_Tx;
+ ifp->if_capabilities |= IFCAP_TSOv4 | IFCAP_TSOv6;
#endif
ether_set_vlan_cb(&sc->sc_ec, ixl_vlan_cb);
sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_MTU;
@@ -2548,6 +2560,71 @@
return error;
}
+static inline int
+ixl_tx_setup_offloads(struct mbuf *m, uint64_t *cmd_txd)
+{
+ struct ether_header *eh;
+ size_t len;
+ uint64_t cmd;
+
+ cmd = 0;
+
+ eh = mtod(m, struct ether_header *);
+ switch (htons(eh->ether_type)) {
+ case ETHERTYPE_IP:
+ case ETHERTYPE_IPV6:
+ len = ETHER_HDR_LEN;
+ break;
+ case ETHERTYPE_VLAN:
+ len = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
+ break;
+ default:
+ len = 0;
+ }
+ cmd |= ((len >> 1) << IXL_TX_DESC_MACLEN_SHIFT);
+
+ if (m->m_pkthdr.csum_flags &
+ (M_CSUM_TSOv4 | M_CSUM_TCPv4 | M_CSUM_UDPv4)) {
+ cmd |= IXL_TX_DESC_CMD_IIPT_IPV4;
+ }
+ if (m->m_pkthdr.csum_flags & M_CSUM_IPv4) {
+ cmd |= IXL_TX_DESC_CMD_IIPT_IPV4_CSUM;
+ }
+
+ if (m->m_pkthdr.csum_flags &
+ (M_CSUM_TSOv6 | M_CSUM_TCPv6 | M_CSUM_UDPv6)) {
+ cmd |= IXL_TX_DESC_CMD_IIPT_IPV6;
+ }
+
+ switch (cmd & IXL_TX_DESC_CMD_IIPT_MASK) {
+ case IXL_TX_DESC_CMD_IIPT_IPV4:
+ case IXL_TX_DESC_CMD_IIPT_IPV4_CSUM:
+ len = M_CSUM_DATA_IPv4_IPHL(m->m_pkthdr.csum_data);
+ break;
+ case IXL_TX_DESC_CMD_IIPT_IPV6:
+ len = M_CSUM_DATA_IPv6_IPHL(m->m_pkthdr.csum_data);
+ break;
+ default:
+ len = 0;
+ }
+ cmd |= ((len >> 2) << IXL_TX_DESC_IPLEN_SHIFT);
+
+ if (m->m_pkthdr.csum_flags &
+ (M_CSUM_TSOv4 | M_CSUM_TSOv6 | M_CSUM_TCPv4 | M_CSUM_TCPv6)) {
+ len = sizeof(struct tcphdr);
+ cmd |= IXL_TX_DESC_CMD_L4T_EOFT_TCP;
+ } else if (m->m_pkthdr.csum_flags & (M_CSUM_UDPv4 | M_CSUM_UDPv6)) {
+ len = sizeof(struct udphdr);
+ cmd |= IXL_TX_DESC_CMD_L4T_EOFT_UDP;
+ } else {
+ len = 0;
+ }
+ cmd |= ((len >> 2) << IXL_TX_DESC_L4LEN_SHIFT);
+
+ *cmd_txd |= cmd;
+ return 0;
+}
+
static void
ixl_tx_common_locked(struct ifnet *ifp, struct ixl_tx_ring *txr,
bool is_transmit)
@@ -2557,7 +2634,7 @@
struct ixl_tx_map *txm;
bus_dmamap_t map;
struct mbuf *m;
- uint64_t cmd, cmd_vlan;
+ uint64_t cmd, cmd_txd;
unsigned int prod, free, last, i;
unsigned int mask;
int post = 0;
@@ -2611,12 +2688,15 @@
continue;
}
+ cmd_txd = 0;
+ if (m->m_pkthdr.csum_flags & IXL_CSUM_ALL_OFFLOAD) {
+ ixl_tx_setup_offloads(m, &cmd_txd);
+ }
+
if (vlan_has_tag(m)) {
- cmd_vlan = (uint64_t)vlan_get_tag(m) <<
+ cmd_txd |= (uint64_t)vlan_get_tag(m) <<
IXL_TX_DESC_L2TAG1_SHIFT;
- cmd_vlan |= IXL_TX_DESC_CMD_IL2TAG1;
- } else {
- cmd_vlan = 0;
+ cmd_txd |= IXL_TX_DESC_CMD_IL2TAG1;
}
bus_dmamap_sync(sc->sc_dmat, map, 0,
@@ -2628,7 +2708,7 @@
cmd = (uint64_t)map->dm_segs[i].ds_len <<
IXL_TX_DESC_BSIZE_SHIFT;
cmd |= IXL_TX_DESC_DTYPE_DATA | IXL_TX_DESC_CMD_ICRC;
- cmd |= cmd_vlan;
+ cmd |= cmd_txd;
txd->addr = htole64(map->dm_segs[i].ds_addr);
txd->cmd = htole64(cmd);
Home |
Main Index |
Thread Index |
Old Index