Split the pre-computed ifnet checksum flags into Tx and Rx directions.

Add capabilities bits that indicate an interface can only perform
in-bound TCPv4 or UDPv4 checksums.  There is at least one Gig-E chip
for which this is true (Level One LXT-1001), and this is also the
case for the Intel i82559 10/100 Ethernet chips.
This commit is contained in:
thorpej 2001-09-17 17:26:59 +00:00
parent 87a75cec20
commit d679590033
8 changed files with 50 additions and 29 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: if.c,v 1.96 2001/08/02 01:42:38 itojun Exp $ */
/* $NetBSD: if.c,v 1.97 2001/09/17 17:26:59 thorpej Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
@ -405,7 +405,8 @@ if_attach(ifp)
ifp->if_link_state = LINK_STATE_UNKNOWN;
ifp->if_capenable = 0;
ifp->if_csum_flags = 0;
ifp->if_csum_flags_tx = 0;
ifp->if_csum_flags_rx = 0;
#ifdef ALTQ
ifp->if_snd.altq_type = 0;
@ -1302,17 +1303,34 @@ ifioctl(so, cmd, data, p)
ifp->if_capenable = ifcr->ifcr_capenable;
/* Pre-compute the checksum flags mask. */
ifp->if_csum_flags = 0;
if (ifp->if_capenable & IFCAP_CSUM_IPv4)
ifp->if_csum_flags |= M_CSUM_IPv4;
if (ifp->if_capenable & IFCAP_CSUM_TCPv4)
ifp->if_csum_flags |= M_CSUM_TCPv4;
if (ifp->if_capenable & IFCAP_CSUM_UDPv4)
ifp->if_csum_flags |= M_CSUM_UDPv4;
if (ifp->if_capenable & IFCAP_CSUM_TCPv6)
ifp->if_csum_flags |= M_CSUM_TCPv6;
if (ifp->if_capenable & IFCAP_CSUM_UDPv6)
ifp->if_csum_flags |= M_CSUM_UDPv6;
ifp->if_csum_flags_tx = 0;
ifp->if_csum_flags_rx = 0;
if (ifp->if_capenable & IFCAP_CSUM_IPv4) {
ifp->if_csum_flags_tx |= M_CSUM_IPv4;
ifp->if_csum_flags_rx |= M_CSUM_IPv4;
}
if (ifp->if_capenable & IFCAP_CSUM_TCPv4) {
ifp->if_csum_flags_tx |= M_CSUM_TCPv4;
ifp->if_csum_flags_rx |= M_CSUM_TCPv4;
} else if (ifp->if_capenable & IFCAP_CSUM_TCPv4_Rx)
ifp->if_csum_flags_rx |= M_CSUM_TCPv4;
if (ifp->if_capenable & IFCAP_CSUM_UDPv4) {
ifp->if_csum_flags_tx |= M_CSUM_UDPv4;
ifp->if_csum_flags_rx |= M_CSUM_UDPv4;
} else if (ifp->if_capenable & IFCAP_CSUM_UDPv4_Rx)
ifp->if_csum_flags_rx |= M_CSUM_UDPv4;
if (ifp->if_capenable & IFCAP_CSUM_TCPv6) {
ifp->if_csum_flags_tx |= M_CSUM_TCPv6;
ifp->if_csum_flags_rx |= M_CSUM_TCPv6;
}
if (ifp->if_capenable & IFCAP_CSUM_UDPv6) {
ifp->if_csum_flags_tx |= M_CSUM_UDPv6;
ifp->if_csum_flags_rx |= M_CSUM_UDPv6;
}
/*
* Only kick the interface if it's up. If it's

View File

@ -1,4 +1,4 @@
/* $NetBSD: if.h,v 1.73 2001/06/14 06:37:34 itojun Exp $ */
/* $NetBSD: if.h,v 1.74 2001/09/17 17:26:59 thorpej Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
@ -284,7 +284,8 @@ struct ifnet { /* and the entries */
* These are pre-computed based on an interfaces enabled
* capabilities, for speed elsewhere.
*/
int if_csum_flags; /* M_CSUM_* flags */
int if_csum_flags_tx; /* M_CSUM_* flags for Tx */
int if_csum_flags_rx; /* M_CSUM_* flags for Rx */
};
#define if_mtu if_data.ifi_mtu
#define if_type if_data.ifi_type
@ -342,6 +343,8 @@ struct ifnet { /* and the entries */
#define IFCAP_CSUM_UDPv4 0x0004 /* can do IPv4/UDP checksums */
#define IFCAP_CSUM_TCPv6 0x0008 /* can do IPv6/TCP checksums */
#define IFCAP_CSUM_UDPv6 0x0010 /* can do IPv6/UDP checksums */
#define IFCAP_CSUM_TCPv4_Rx 0x0020 /* can do IPv4/TCP (Rx only) */
#define IFCAP_CSUM_UDPv4_Rx 0x0040 /* can do IPv4/UDP (Rx only) */
/*
* Output queues (ifp->if_snd) and internetwork datagram level (pup level 1)

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_fil.c,v 1.68 2001/06/02 16:17:09 thorpej Exp $ */
/* $NetBSD: ip_fil.c,v 1.69 2001/09/17 17:27:00 thorpej Exp $ */
/*
* Copyright (C) 1993-2000 by Darren Reed.
@ -9,7 +9,7 @@
*/
#if !defined(lint)
#if defined(__NetBSD__)
static const char rcsid[] = "$NetBSD: ip_fil.c,v 1.68 2001/06/02 16:17:09 thorpej Exp $";
static const char rcsid[] = "$NetBSD: ip_fil.c,v 1.69 2001/09/17 17:27:00 thorpej Exp $";
#else
static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)Id: ip_fil.c,v 2.42.2.17 2000/10/19 15:39:42 darrenr Exp";
@ -1499,7 +1499,7 @@ frdest_t *fdp;
ip->ip_len = htons(ip->ip_len);
ip->ip_off = htons(ip->ip_off);
# if defined(__NetBSD__) && defined(M_CSUM_IPv4)
if (ifp->if_csum_flags & M_CSUM_IPv4)
if (ifp->if_csum_flags_tx & M_CSUM_IPv4)
m->m_pkthdr.csum_flags |= M_CSUM_IPv4;
else if (ip->ip_sum == 0)
ip->ip_sum = in_cksum(m, hlen);

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_flow.c,v 1.19 2001/06/12 15:17:28 wiz Exp $ */
/* $NetBSD: ip_flow.c,v 1.20 2001/09/17 17:27:00 thorpej Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -182,7 +182,7 @@ ipflow_fastforward(
* Verify the IP header checksum.
*/
switch (m->m_pkthdr.csum_flags &
((m->m_pkthdr.rcvif->if_csum_flags & M_CSUM_IPv4) |
((m->m_pkthdr.rcvif->if_csum_flags_rx & M_CSUM_IPv4) |
M_CSUM_IPv4_BAD)) {
case M_CSUM_IPv4|M_CSUM_IPv4_BAD:
return (0);

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_input.c,v 1.136 2001/08/06 10:25:00 itojun Exp $ */
/* $NetBSD: ip_input.c,v 1.137 2001/09/17 17:27:00 thorpej Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -459,7 +459,7 @@ ip_input(struct mbuf *m)
}
switch (m->m_pkthdr.csum_flags &
((m->m_pkthdr.rcvif->if_csum_flags & M_CSUM_IPv4) |
((m->m_pkthdr.rcvif->if_csum_flags_rx & M_CSUM_IPv4) |
M_CSUM_IPv4_BAD)) {
case M_CSUM_IPv4|M_CSUM_IPv4_BAD:
INET_CSUM_COUNTER_INCR(&ip_hwcsum_bad);

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_output.c,v 1.87 2001/08/11 12:26:50 yamt Exp $ */
/* $NetBSD: ip_output.c,v 1.88 2001/09/17 17:27:00 thorpej Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -592,7 +592,7 @@ skip_ipsec:
ip->ip_sum = 0;
m->m_pkthdr.csum_flags |= M_CSUM_IPv4;
sw_csum = m->m_pkthdr.csum_flags & ~ifp->if_csum_flags;
sw_csum = m->m_pkthdr.csum_flags & ~ifp->if_csum_flags_tx;
/*
* Perform any checksums that the hardware can't do
@ -607,7 +607,7 @@ skip_ipsec:
in_delayed_cksum(m);
sw_csum &= ~(M_CSUM_TCPv4|M_CSUM_UDPv4);
}
m->m_pkthdr.csum_flags &= ifp->if_csum_flags;
m->m_pkthdr.csum_flags &= ifp->if_csum_flags_tx;
#ifdef IPSEC
/* clean ipsec history once it goes out of the node */

View File

@ -1,4 +1,4 @@
/* $NetBSD: tcp_input.c,v 1.130 2001/09/11 21:03:20 thorpej Exp $ */
/* $NetBSD: tcp_input.c,v 1.131 2001/09/17 17:27:00 thorpej Exp $ */
/*
%%% portions-copyright-nrl-95
@ -969,7 +969,7 @@ findpcb:
#ifdef INET
case AF_INET:
switch (m->m_pkthdr.csum_flags &
((m->m_pkthdr.rcvif->if_csum_flags & M_CSUM_TCPv4) |
((m->m_pkthdr.rcvif->if_csum_flags_rx & M_CSUM_TCPv4) |
M_CSUM_TCP_UDP_BAD | M_CSUM_DATA)) {
case M_CSUM_TCPv4|M_CSUM_TCP_UDP_BAD:
TCP_CSUM_COUNTER_INCR(&tcp_hwcsum_bad);

View File

@ -1,4 +1,4 @@
/* $NetBSD: udp_usrreq.c,v 1.83 2001/07/25 23:28:02 itojun Exp $ */
/* $NetBSD: udp_usrreq.c,v 1.84 2001/09/17 17:27:01 thorpej Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -284,7 +284,7 @@ udp_input(m, va_alist)
*/
if (uh->uh_sum) {
switch (m->m_pkthdr.csum_flags &
((m->m_pkthdr.rcvif->if_csum_flags & M_CSUM_UDPv4) |
((m->m_pkthdr.rcvif->if_csum_flags_rx & M_CSUM_UDPv4) |
M_CSUM_TCP_UDP_BAD | M_CSUM_DATA)) {
case M_CSUM_UDPv4|M_CSUM_TCP_UDP_BAD:
UDP_CSUM_COUNTER_INCR(&udp_hwcsum_bad);