All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC 00/15] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM
@ 2015-11-19 19:55 Tom Herbert
  2015-11-19 19:55 ` [PATCH 01/15] net: Add skb_inner_transport_offset function Tom Herbert
                   ` (15 more replies)
  0 siblings, 16 replies; 19+ messages in thread
From: Tom Herbert @ 2015-11-19 19:55 UTC (permalink / raw)
  To: davem, netdev; +Cc: kernel-team

Background:

This patch set starts to address one front in the battle against
protocol ossification. Protocol ossification describes the state
that we have arrived at in the evolution of the Internet where we are
materially limited to only using a very narrow range of protocols
and protocol features. For instance, only TCP and UDP is sufficiently
supported on the Internet so that deploying alternative protocols,
such as SCTP and DCCP, are non-starters. Similarly, IP options and IPv6
extension headers are typically not considered feasible for wide
deployment, so we have loss the extensibility of IP protocols.

Protocol ossification is not only a problem on the Internet, but in
the data center as well. The root cause of this seems to be narrow,
protocol specific optimizations implemented in switches (for doing
EMCP) and in NICs (NIC offloads). These tend to be performance
optimization around TCP and UDP packets, and these have become
requirements to implement performant network solutions at scale.

Attempts to deal with protocol ossification in data center have yielded
ad hoc, sub-optimal solutions. A main driver of foo-over-UDP (e.g.
GRE/UDP, MPLS/UDP) is to leverage the existing EMCP and RSS support for
UDP by setting the source port as an entropy value. This has seen some
success, but the cost of additional overhead and layering limits its
usefulness.  An even more extreme solution is STT where non-TCP packets
are spoofed as TCP to leverage NIC offloads.

This patch set endeavours to address protocol ossification caused by
techniques used in transmit checksum offload for NICs. Future work
will address protocol ossification in the other primary NIC offloads--
namely receive checksum offload, LSO, LRO, and RSS.

NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM:

NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM exemplify the problem of protocol
ossification. These features are relics from a simpler time in the
Internet, before encapsulation, before GRE and  IPIP. Many hardware
vendors only saw the need to provide checksum offload for simple UDP and
TCP packets over IPv4 (IPv6 support is an afterthought also). In today's
Internet and data centers, checksum offload is well established as a
valuable feature, but we can no longer afford to be contsrained to
use a handful of protocols and features that are supported at the
discretion of NIC vendors. Generic and protocol agnostic methods are
needed.

The actual interface that the stack uses with drivers for checksum
offload is CHECKSUM_PARTIAL. This is a generic and protocol agnostic
interface. A driver for a device that supports this generic
interface advertises NETIF_F_HW_CSUM.

Goals of this patch set:

We propose that drivers advertise NETIF_F_HW_CSUM instead of protocol
specific values of NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM.  If the
driver's device is constrained (for instance it can only offlaod simple
IPv4 and IPv6 packets) then these constraints can be checked in the
transmit path and skb_checksum_help would be called for packets that the
driver is unable to offload. In order to facilitate this, we add some
helper functions that takes a specification argument indicating the
type of packets a device is able to offload. If a packet does not match
the specification, the helper function calls skb_checksum_help.

Benefits of this approach are:
  - Simplify the stack and clarify the interface for checksum offload
  - Encourage NIC vendors to implement the generic. protocol agnostic
    checksum offload methods in hardware
  - Encourage feature parity in NIC offloads for IPv4 and IPv6

Many drivers advertise NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM and it
probably isn't feasible to convert them all in a given time frame
(although if we could this would be a great simplification to the
stack). A reasonable direction may be to declare that new drivers must
use NETIF_F_HW_CSUM as NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM are
considered deprecated.

There is a class of drivers that should now be converted to advertise
NETIF_F_HW_CSUM, namely those that support offload of ecapsulated
checksums. These drivers have to date been using skb->encapsulation
to infer that checksum offload is being performed for an encapsulated
checksum. This is strictly not correct. skb->encapsulation
indicates that the inner headers are valid in the skbuff, whereas
the stack indicates checksum offload arguments exclusively in csum_start
and csum_offset. At some point we may want to set the inner headers for
an skbuff but offload the outer transport checksum, so this needs to be
fixed.

In this patch set:

  - Rename some of constants involved in checksum offload to be more
    reflective of their function
  - Eliminate NETIF_F_GEN_CSUM and NETIF_F_V[46]_CSUM entirely as
    unnecessary convolutions
  - Fix conditions in tcp_sendpage and tcp_sendmsg to take IP protocol
    into account when determining if checksum offload can be done
  - Add driver helper functions for determining if a checksum can
    be offloaded to a device. If not, the helper function can call
    skb_checksum_help
  - Convert bnx2x, bnxt, emulex, fm10k, ixgbe, mlx4, and qlogic drivers
    to advertise NETIF_F_HW_CSUM. The helper functions are called
    to checksum device constraints (IP protocol, UDP or TCP, etc.)
  - Document the checksum offload interface between the stack and
    drivers with detail and specifics

Testing:

Have been testing ixgbe and mlx4. No noticeable regressions seen yet.

Tom Herbert (15):
  net: Add skb_inner_transport_offset function
  sctp: Rename NETIF_F_SCTP_CSUM to NETIF_F_SCTP_CRC
  fcoe: Use CHECKSUM_PARTIAL to indicate CRC offload
  net: Rename NETIF_F_ALL_CSUM to NETIF_F_CSUM_MASK
  net: Eliminate NETIF_F_GEN_CSUM and NETIF_F_V[46]_CSUM
  tcp: Fix conditions to determine checksum offload
  net: Add driver helper functions to determine checksum offloadability
  net: Elaborate on checksum offload interface description
  bnx2x: Convert to advertise NETIF_F_HW_CSUM
  bnxt: Convert to advertise NETIF_F_HW_CSUM
  emulex: Convert to advertise NETIF_F_HW_CSUM
  fm10k: Convert to advertise NETIF_F_HW_CSUM
  ixgbe: Convert to advertise NETIF_F_HW_CSUM
  mlx4: Convert to advertise NETIF_F_HW_CSUM
  qlogic: Convert to advertise NETIF_F_HW_CSUM

 drivers/net/bonding/bond_main.c                    |   7 +-
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c    |  15 +-
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c   |   6 +-
 drivers/net/ethernet/broadcom/bnxt/bnxt.c          |  21 ++-
 drivers/net/ethernet/emulex/benet/be.h             |   1 +
 drivers/net/ethernet/emulex/benet/be_main.c        |  32 +++--
 drivers/net/ethernet/ibm/ibmveth.c                 |   5 +-
 drivers/net/ethernet/intel/fm10k/fm10k_main.c      |  16 ++-
 drivers/net/ethernet/intel/fm10k/fm10k_netdev.c    |   7 +-
 drivers/net/ethernet/intel/i40e/i40e_main.c        |   4 +-
 drivers/net/ethernet/intel/i40evf/i40evf_main.c    |   2 +-
 drivers/net/ethernet/intel/igb/igb_main.c          |   4 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c      |  47 +++++--
 drivers/net/ethernet/jme.c                         |   2 +-
 drivers/net/ethernet/marvell/sky2.c                |   2 +-
 drivers/net/ethernet/mellanox/mlx4/en_netdev.c     |   6 +-
 drivers/net/ethernet/mellanox/mlx4/en_tx.c         |  16 ++-
 .../net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c  |   2 +-
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c     |  10 +-
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c     |  16 ++-
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c   |  10 +-
 drivers/net/ethernet/sfc/efx.c                     |   4 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |   4 +-
 drivers/net/ipvlan/ipvlan_main.c                   |   2 +-
 drivers/net/loopback.c                             |   2 +-
 drivers/net/macvlan.c                              |   4 +-
 drivers/net/macvtap.c                              |   2 +-
 drivers/net/team/team.c                            |   3 +-
 drivers/net/usb/r8152.c                            |   2 +-
 drivers/scsi/fcoe/fcoe.c                           |   2 +-
 .../lustre/lnet/klnds/socklnd/socklnd_lib.c        |   2 +-
 include/linux/if_vlan.h                            |   2 +-
 include/linux/netdev_features.h                    |  14 +-
 include/linux/netdevice.h                          | 118 ++++++++++++++--
 include/linux/skbuff.h                             | 143 +++++++++++++++----
 include/net/sock.h                                 |   9 ++
 include/net/vxlan.h                                |   2 +-
 net/8021q/vlan_dev.c                               |   4 +-
 net/core/dev.c                                     | 153 +++++++++++++++++++--
 net/core/ethtool.c                                 |   4 +-
 net/core/pktgen.c                                  |   4 +-
 net/ipv4/ip_output.c                               |   2 +-
 net/ipv4/netfilter/nf_nat_l3proto_ipv4.c           |   3 +-
 net/ipv4/tcp.c                                     |   4 +-
 net/ipv4/udp.c                                     |   3 +-
 net/ipv4/udp_offload.c                             |   5 +-
 net/ipv6/ip6_output.c                              |   2 +-
 net/ipv6/netfilter/nf_nat_l3proto_ipv6.c           |   3 +-
 net/netfilter/ipvs/ip_vs_proto_sctp.c              |   2 +-
 net/sctp/output.c                                  |   2 +-
 50 files changed, 571 insertions(+), 166 deletions(-)

-- 
2.4.6

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 01/15] net: Add skb_inner_transport_offset function
  2015-11-19 19:55 [PATCH RFC 00/15] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM Tom Herbert
@ 2015-11-19 19:55 ` Tom Herbert
  2015-11-19 19:55 ` [PATCH 02/15] sctp: Rename NETIF_F_SCTP_CSUM to NETIF_F_SCTP_CRC Tom Herbert
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Tom Herbert @ 2015-11-19 19:55 UTC (permalink / raw)
  To: davem, netdev; +Cc: kernel-team

Same thing as skb_transport_offset but returns the offset of the inner
transport header (when skb->encpasulation is set).

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 include/linux/skbuff.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index c9c394b..0713080 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1939,6 +1939,11 @@ static inline unsigned char *skb_inner_transport_header(const struct sk_buff
 	return skb->head + skb->inner_transport_header;
 }
 
+static inline int skb_inner_transport_offset(const struct sk_buff *skb)
+{
+	return skb_inner_transport_header(skb) - skb->data;
+}
+
 static inline void skb_reset_inner_transport_header(struct sk_buff *skb)
 {
 	skb->inner_transport_header = skb->data - skb->head;
-- 
2.4.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 02/15] sctp: Rename NETIF_F_SCTP_CSUM to NETIF_F_SCTP_CRC
  2015-11-19 19:55 [PATCH RFC 00/15] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM Tom Herbert
  2015-11-19 19:55 ` [PATCH 01/15] net: Add skb_inner_transport_offset function Tom Herbert
@ 2015-11-19 19:55 ` Tom Herbert
  2015-11-19 19:55 ` [PATCH 03/15] fcoe: Use CHECKSUM_PARTIAL to indicate CRC offload Tom Herbert
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Tom Herbert @ 2015-11-19 19:55 UTC (permalink / raw)
  To: davem, netdev; +Cc: kernel-team

The SCTP checksum is really a CRC and is very different from the
standards 1's complement checksum that serves as the checksum
for IP protocols. This offload interface is also very different.
Rename NETIF_F_SCTP_CSUM to NETIF_F_SCTP_CRC to highlight these
differences. The term CSUM should be reserved in the stack to refer
to the standard 1's complement IP checksum.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 drivers/net/ethernet/intel/i40e/i40e_main.c     | 2 +-
 drivers/net/ethernet/intel/i40evf/i40evf_main.c | 2 +-
 drivers/net/ethernet/intel/igb/igb_main.c       | 4 ++--
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c   | 4 ++--
 drivers/net/loopback.c                          | 2 +-
 include/linux/netdev_features.h                 | 4 ++--
 net/8021q/vlan_dev.c                            | 2 +-
 net/core/ethtool.c                              | 4 ++--
 net/netfilter/ipvs/ip_vs_proto_sctp.c           | 2 +-
 net/sctp/output.c                               | 2 +-
 10 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index b825f97..fc4ee0a 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -8638,7 +8638,7 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
 
 	netdev->features = NETIF_F_SG		       |
 			   NETIF_F_IP_CSUM	       |
-			   NETIF_F_SCTP_CSUM	       |
+			   NETIF_F_SCTP_CRC	       |
 			   NETIF_F_HIGHDMA	       |
 			   NETIF_F_GSO_UDP_TUNNEL      |
 			   NETIF_F_GSO_GRE	       |
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
index d962164..1b22b71 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
@@ -2137,7 +2137,7 @@ int i40evf_process_config(struct i40evf_adapter *adapter)
 	netdev->features |= NETIF_F_HIGHDMA |
 			    NETIF_F_SG |
 			    NETIF_F_IP_CSUM |
-			    NETIF_F_SCTP_CSUM |
+			    NETIF_F_SCTP_CRC |
 			    NETIF_F_IPV6_CSUM |
 			    NETIF_F_TSO |
 			    NETIF_F_TSO6 |
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index ea7b098..1e21db3 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -2378,8 +2378,8 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	}
 
 	if (hw->mac.type >= e1000_82576) {
-		netdev->hw_features |= NETIF_F_SCTP_CSUM;
-		netdev->features |= NETIF_F_SCTP_CSUM;
+		netdev->hw_features |= NETIF_F_SCTP_CRC;
+		netdev->features |= NETIF_F_SCTP_CRC;
 	}
 
 	netdev->priv_flags |= IFF_UNICAST_FLT;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 4089d77..3e8b3d7 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -8781,8 +8781,8 @@ skip_sriov:
 	case ixgbe_mac_X540:
 	case ixgbe_mac_X550:
 	case ixgbe_mac_X550EM_x:
-		netdev->features |= NETIF_F_SCTP_CSUM;
-		netdev->hw_features |= NETIF_F_SCTP_CSUM |
+		netdev->features |= NETIF_F_SCTP_CRC;
+		netdev->hw_features |= NETIF_F_SCTP_CRC |
 				       NETIF_F_NTUPLE;
 		break;
 	default:
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index dc7d970..a400288 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -175,7 +175,7 @@ static void loopback_setup(struct net_device *dev)
 		| NETIF_F_UFO
 		| NETIF_F_HW_CSUM
 		| NETIF_F_RXCSUM
-		| NETIF_F_SCTP_CSUM
+		| NETIF_F_SCTP_CRC
 		| NETIF_F_HIGHDMA
 		| NETIF_F_LLTX
 		| NETIF_F_NETNS_LOCAL
diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
index f0d8734..6395f83 100644
--- a/include/linux/netdev_features.h
+++ b/include/linux/netdev_features.h
@@ -52,7 +52,7 @@ enum {
 		NETIF_F_GSO_TUNNEL_REMCSUM_BIT,
 
 	NETIF_F_FCOE_CRC_BIT,		/* FCoE CRC32 */
-	NETIF_F_SCTP_CSUM_BIT,		/* SCTP checksum offload */
+	NETIF_F_SCTP_CRC_BIT,		/* SCTP checksum offload */
 	NETIF_F_FCOE_MTU_BIT,		/* Supports max FCoE MTU, 2158 bytes*/
 	NETIF_F_NTUPLE_BIT,		/* N-tuple filters supported */
 	NETIF_F_RXHASH_BIT,		/* Receive hashing offload */
@@ -103,7 +103,7 @@ enum {
 #define NETIF_F_NTUPLE		__NETIF_F(NTUPLE)
 #define NETIF_F_RXCSUM		__NETIF_F(RXCSUM)
 #define NETIF_F_RXHASH		__NETIF_F(RXHASH)
-#define NETIF_F_SCTP_CSUM	__NETIF_F(SCTP_CSUM)
+#define NETIF_F_SCTP_CRC	__NETIF_F(SCTP_CRC)
 #define NETIF_F_SG		__NETIF_F(SG)
 #define NETIF_F_TSO6		__NETIF_F(TSO6)
 #define NETIF_F_TSO_ECN		__NETIF_F(TSO_ECN)
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index fded865..c2bf37f 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -544,7 +544,7 @@ static int vlan_dev_init(struct net_device *dev)
 
 	dev->hw_features = NETIF_F_ALL_CSUM | NETIF_F_SG |
 			   NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE |
-			   NETIF_F_HIGHDMA | NETIF_F_SCTP_CSUM |
+			   NETIF_F_HIGHDMA | NETIF_F_SCTP_CRC |
 			   NETIF_F_ALL_FCOE;
 
 	dev->features |= real_dev->vlan_features | NETIF_F_LLTX |
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 29edf74..4a0cab8 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -87,7 +87,7 @@ static const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN]
 	[NETIF_F_GSO_UDP_TUNNEL_BIT] =	 "tx-udp_tnl-segmentation",
 
 	[NETIF_F_FCOE_CRC_BIT] =         "tx-checksum-fcoe-crc",
-	[NETIF_F_SCTP_CSUM_BIT] =        "tx-checksum-sctp",
+	[NETIF_F_SCTP_CRC_BIT] =        "tx-checksum-sctp",
 	[NETIF_F_FCOE_MTU_BIT] =         "fcoe-mtu",
 	[NETIF_F_NTUPLE_BIT] =           "rx-ntuple-filter",
 	[NETIF_F_RXHASH_BIT] =           "rx-hashing",
@@ -235,7 +235,7 @@ static netdev_features_t ethtool_get_feature_mask(u32 eth_cmd)
 	switch (eth_cmd) {
 	case ETHTOOL_GTXCSUM:
 	case ETHTOOL_STXCSUM:
-		return NETIF_F_ALL_CSUM | NETIF_F_SCTP_CSUM;
+		return NETIF_F_ALL_CSUM | NETIF_F_SCTP_CRC;
 	case ETHTOOL_GRXCSUM:
 	case ETHTOOL_SRXCSUM:
 		return NETIF_F_RXCSUM;
diff --git a/net/netfilter/ipvs/ip_vs_proto_sctp.c b/net/netfilter/ipvs/ip_vs_proto_sctp.c
index 010ddee..d952d67 100644
--- a/net/netfilter/ipvs/ip_vs_proto_sctp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_sctp.c
@@ -169,7 +169,7 @@ sctp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
 	/* Only update csum if we really have to */
 	if (sctph->dest != cp->dport || payload_csum ||
 	    (skb->ip_summed == CHECKSUM_PARTIAL &&
-	     !(skb_dst(skb)->dev->features & NETIF_F_SCTP_CSUM))) {
+	     !(skb_dst(skb)->dev->features & NETIF_F_SCTP_CRC))) {
 		sctph->dest = cp->dport;
 		sctp_nat_csum(skb, sctph, sctphoff);
 	} else if (skb->ip_summed != CHECKSUM_PARTIAL) {
diff --git a/net/sctp/output.c b/net/sctp/output.c
index abe7c2d..9d610ed 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -534,7 +534,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
 	 * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>.
 	 */
 	if (!sctp_checksum_disable) {
-		if (!(dst->dev->features & NETIF_F_SCTP_CSUM) ||
+		if (!(dst->dev->features & NETIF_F_SCTP_CRC) ||
 		    (dst_xfrm(dst) != NULL) || packet->ipfragok) {
 			sh->checksum = sctp_compute_cksum(nskb, 0);
 		} else {
-- 
2.4.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 03/15] fcoe: Use CHECKSUM_PARTIAL to indicate CRC offload
  2015-11-19 19:55 [PATCH RFC 00/15] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM Tom Herbert
  2015-11-19 19:55 ` [PATCH 01/15] net: Add skb_inner_transport_offset function Tom Herbert
  2015-11-19 19:55 ` [PATCH 02/15] sctp: Rename NETIF_F_SCTP_CSUM to NETIF_F_SCTP_CRC Tom Herbert
@ 2015-11-19 19:55 ` Tom Herbert
  2015-11-19 19:55 ` [PATCH 04/15] net: Rename NETIF_F_ALL_CSUM to NETIF_F_CSUM_MASK Tom Herbert
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Tom Herbert @ 2015-11-19 19:55 UTC (permalink / raw)
  To: davem, netdev; +Cc: kernel-team

When setting up CRC offload set ip_summed to CHECKSUM_PARTIAL
instead of CHECKSUM_UNNECESSARY. This is consistent with the
definition of CHECKSUM_PARTIAL.

The only driver that seems to be advertising NETIF_F_FCOE_CRC is
ixgbe. AFICT the driver does not look at ip_summed for FCOE and
just assumes that CRC is being offloaded.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 drivers/scsi/fcoe/fcoe.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index f442406..0efe711 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -1625,7 +1625,7 @@ static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp)
 
 	/* crc offload */
 	if (likely(lport->crc_offload)) {
-		skb->ip_summed = CHECKSUM_UNNECESSARY;
+		skb->ip_summed = CHECKSUM_PARTIAL;
 		skb->csum_start = skb_headroom(skb);
 		skb->csum_offset = skb->len;
 		crc = 0;
-- 
2.4.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 04/15] net: Rename NETIF_F_ALL_CSUM to NETIF_F_CSUM_MASK
  2015-11-19 19:55 [PATCH RFC 00/15] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM Tom Herbert
                   ` (2 preceding siblings ...)
  2015-11-19 19:55 ` [PATCH 03/15] fcoe: Use CHECKSUM_PARTIAL to indicate CRC offload Tom Herbert
@ 2015-11-19 19:55 ` Tom Herbert
  2015-11-19 19:55 ` [PATCH 05/15] net: Eliminate NETIF_F_GEN_CSUM and NETIF_F_V[46]_CSUM Tom Herbert
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Tom Herbert @ 2015-11-19 19:55 UTC (permalink / raw)
  To: davem, netdev; +Cc: kernel-team

The name NETIF_F_ALL_CSUM is a misnomer. This does not correspond to the
set of features for offloading all checksums. This a mask of the
checksum offload related features bits. It is incorrect to set both
NETIF_F_HW_CSUM and NETIF_F_IP_CSUM or NETIF_F_IPV6 at the same time for
features of a device.

This patch:
  - Changes instances of NETIF_F_ALL_CSUM to NETIF_F_CSUM_MASK (where
    NETIF_F_ALL_CSUM is being used as a mask).
  - Changes bonding, sfc/efx, ipvlan, macvlan, vlan, and team drivers to
    use NEITF_F_HW_CSUM in features list instead of NETIF_F_ALL_CSUM.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 drivers/net/bonding/bond_main.c                         |  7 +++----
 drivers/net/ethernet/emulex/benet/be_main.c             |  2 +-
 drivers/net/ethernet/ibm/ibmveth.c                      |  5 +++--
 drivers/net/ethernet/intel/fm10k/fm10k_netdev.c         |  2 +-
 drivers/net/ethernet/intel/i40e/i40e_main.c             |  2 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c           |  2 +-
 drivers/net/ethernet/jme.c                              |  2 +-
 drivers/net/ethernet/marvell/sky2.c                     |  2 +-
 drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c   |  2 +-
 drivers/net/ethernet/sfc/efx.c                          |  2 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c       |  4 ++--
 drivers/net/ipvlan/ipvlan_main.c                        |  2 +-
 drivers/net/macvlan.c                                   |  2 +-
 drivers/net/macvtap.c                                   |  2 +-
 drivers/net/team/team.c                                 |  3 +--
 drivers/net/usb/r8152.c                                 |  2 +-
 drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c |  2 +-
 include/linux/netdev_features.h                         |  7 ++++++-
 include/linux/netdevice.h                               |  6 +++---
 include/net/vxlan.h                                     |  2 +-
 net/8021q/vlan_dev.c                                    |  2 +-
 net/core/dev.c                                          | 10 +++++-----
 net/core/ethtool.c                                      |  2 +-
 net/ipv4/tcp.c                                          |  4 ++--
 24 files changed, 41 insertions(+), 37 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 9e0f8a7..132a6d5 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1066,12 +1066,12 @@ static netdev_features_t bond_fix_features(struct net_device *dev,
 	return features;
 }
 
-#define BOND_VLAN_FEATURES	(NETIF_F_ALL_CSUM | NETIF_F_SG | \
+#define BOND_VLAN_FEATURES	(NETIF_F_HW_CSUM | NETIF_F_SG | \
 				 NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \
 				 NETIF_F_HIGHDMA | NETIF_F_LRO)
 
-#define BOND_ENC_FEATURES	(NETIF_F_ALL_CSUM | NETIF_F_SG | NETIF_F_RXCSUM |\
-				 NETIF_F_ALL_TSO)
+#define BOND_ENC_FEATURES	(NETIF_F_HW_CSUM | NETIF_F_SG | \
+				 NETIF_F_RXCSUM | NETIF_F_ALL_TSO)
 
 static void bond_compute_features(struct bonding *bond)
 {
@@ -4135,7 +4135,6 @@ void bond_setup(struct net_device *bond_dev)
 				NETIF_F_HW_VLAN_CTAG_RX |
 				NETIF_F_HW_VLAN_CTAG_FILTER;
 
-	bond_dev->hw_features &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_HW_CSUM);
 	bond_dev->hw_features |= NETIF_F_GSO_ENCAP_ALL;
 	bond_dev->features |= bond_dev->hw_features;
 }
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 4cab887..34e324f 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -5289,7 +5289,7 @@ static netdev_features_t be_features_check(struct sk_buff *skb,
 	    skb->inner_protocol != htons(ETH_P_TEB) ||
 	    skb_inner_mac_header(skb) - skb_transport_header(skb) !=
 	    sizeof(struct udphdr) + sizeof(struct vxlanhdr))
-		return features & ~(NETIF_F_ALL_CSUM | NETIF_F_GSO_MASK);
+		return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
 
 	return features;
 }
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c
index 7af870a..6691b5a 100644
--- a/drivers/net/ethernet/ibm/ibmveth.c
+++ b/drivers/net/ethernet/ibm/ibmveth.c
@@ -763,7 +763,7 @@ static netdev_features_t ibmveth_fix_features(struct net_device *dev,
 	 */
 
 	if (!(features & NETIF_F_RXCSUM))
-		features &= ~NETIF_F_ALL_CSUM;
+		features &= ~NETIF_F_CSUM_MASK;
 
 	return features;
 }
@@ -928,7 +928,8 @@ static int ibmveth_set_features(struct net_device *dev,
 		rc1 = ibmveth_set_csum_offload(dev, rx_csum);
 		if (rc1 && !adapter->rx_csum)
 			dev->features =
-				features & ~(NETIF_F_ALL_CSUM | NETIF_F_RXCSUM);
+				features & ~(NETIF_F_CSUM_MASK |
+					     NETIF_F_RXCSUM);
 	}
 
 	if (large_send != adapter->large_send) {
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
index 639263d..a340772 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
@@ -1353,7 +1353,7 @@ static netdev_features_t fm10k_features_check(struct sk_buff *skb,
 	if (!skb->encapsulation || fm10k_tx_encap_offload(skb))
 		return features;
 
-	return features & ~(NETIF_F_ALL_CSUM | NETIF_F_GSO_MASK);
+	return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
 }
 
 static const struct net_device_ops fm10k_netdev_ops = {
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index fc4ee0a..71c1b79 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -8562,7 +8562,7 @@ static netdev_features_t i40e_features_check(struct sk_buff *skb,
 	if (skb->encapsulation &&
 	    (skb_inner_mac_header(skb) - skb_transport_header(skb) >
 	     I40E_MAX_TUNNEL_HDR_LEN))
-		return features & ~(NETIF_F_ALL_CSUM | NETIF_F_GSO_MASK);
+		return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
 
 	return features;
 }
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 3e8b3d7..80823f5 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -8384,7 +8384,7 @@ ixgbe_features_check(struct sk_buff *skb, struct net_device *dev,
 
 	if (unlikely(skb_inner_mac_header(skb) - skb_transport_header(skb) >
 		     IXGBE_MAX_TUNNEL_HDR_LEN))
-		return features & ~NETIF_F_ALL_CSUM;
+		return features & ~NETIF_F_CSUM_MASK;
 
 	return features;
 }
diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c
index 060dd39..b1de7af 100644
--- a/drivers/net/ethernet/jme.c
+++ b/drivers/net/ethernet/jme.c
@@ -2753,7 +2753,7 @@ static netdev_features_t
 jme_fix_features(struct net_device *netdev, netdev_features_t features)
 {
 	if (netdev->mtu > 1900)
-		features &= ~(NETIF_F_ALL_TSO | NETIF_F_ALL_CSUM);
+		features &= ~(NETIF_F_ALL_TSO | NETIF_F_CSUM_MASK);
 	return features;
 }
 
diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
index 5606a04..ec0a221 100644
--- a/drivers/net/ethernet/marvell/sky2.c
+++ b/drivers/net/ethernet/marvell/sky2.c
@@ -4380,7 +4380,7 @@ static netdev_features_t sky2_fix_features(struct net_device *dev,
 	 */
 	if (dev->mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U) {
 		netdev_info(dev, "checksum offload not possible with jumbo frames\n");
-		features &= ~(NETIF_F_TSO|NETIF_F_SG|NETIF_F_ALL_CSUM);
+		features &= ~(NETIF_F_TSO | NETIF_F_SG | NETIF_F_CSUM_MASK);
 	}
 
 	/* Some hardware requires receive checksum for RSS to work. */
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c
index 08d4be6..e097e6b 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c
@@ -500,7 +500,7 @@ void pch_gbe_check_options(struct pch_gbe_adapter *adapter)
 		val = XsumTX;
 		pch_gbe_validate_option(&val, &opt, adapter);
 		if (!val)
-			dev->features &= ~NETIF_F_ALL_CSUM;
+			dev->features &= ~NETIF_F_CSUM_MASK;
 	}
 	{ /* Flow Control */
 		static const struct pch_gbe_option opt = {
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 4e82bcf..78aaca2 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -3125,7 +3125,7 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
 	if (efx->type->offload_features & NETIF_F_V6_CSUM)
 		net_dev->features |= NETIF_F_TSO6;
 	/* Mask for features that also apply to VLAN devices */
-	net_dev->vlan_features |= (NETIF_F_ALL_CSUM | NETIF_F_SG |
+	net_dev->vlan_features |= (NETIF_F_HW_CSUM | NETIF_F_SG |
 				   NETIF_F_HIGHDMA | NETIF_F_ALL_TSO |
 				   NETIF_F_RXCSUM);
 	/* All offloads can be toggled */
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 64d8aa4..8862d5b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2396,7 +2396,7 @@ static netdev_features_t stmmac_fix_features(struct net_device *dev,
 		features &= ~NETIF_F_RXCSUM;
 
 	if (!priv->plat->tx_coe)
-		features &= ~NETIF_F_ALL_CSUM;
+		features &= ~NETIF_F_CSUM_MASK;
 
 	/* Some GMAC devices have a bugged Jumbo frame support that
 	 * needs to have the Tx COE disabled for oversized frames
@@ -2404,7 +2404,7 @@ static netdev_features_t stmmac_fix_features(struct net_device *dev,
 	 * the TX csum insertionin the TDES and not use SF.
 	 */
 	if (priv->plat->bugged_jumbo && (dev->mtu > ETH_DATA_LEN))
-		features &= ~NETIF_F_ALL_CSUM;
+		features &= ~NETIF_F_CSUM_MASK;
 
 	return features;
 }
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
index a9268db..f94392d 100644
--- a/drivers/net/ipvlan/ipvlan_main.c
+++ b/drivers/net/ipvlan/ipvlan_main.c
@@ -88,7 +88,7 @@ static struct lock_class_key ipvlan_netdev_xmit_lock_key;
 static struct lock_class_key ipvlan_netdev_addr_lock_key;
 
 #define IPVLAN_FEATURES \
-	(NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \
+	(NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \
 	 NETIF_F_GSO | NETIF_F_TSO | NETIF_F_UFO | NETIF_F_GSO_ROBUST | \
 	 NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_GRO | NETIF_F_RXCSUM | \
 	 NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_STAG_FILTER)
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 06c8bfe..ae3b486 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -762,7 +762,7 @@ static struct lock_class_key macvlan_netdev_addr_lock_key;
 	 NETIF_F_GSO_ROBUST)
 
 #define MACVLAN_FEATURES \
-	(NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \
+	(NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \
 	 NETIF_F_GSO | NETIF_F_TSO | NETIF_F_UFO | NETIF_F_LRO | \
 	 NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_GRO | NETIF_F_RXCSUM | \
 	 NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_STAG_FILTER)
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index 54036ae..bb1fd86 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -388,7 +388,7 @@ static rx_handler_result_t macvtap_handle_frame(struct sk_buff **pskb)
 		 *        check, we either support them all or none.
 		 */
 		if (skb->ip_summed == CHECKSUM_PARTIAL &&
-		    !(features & NETIF_F_ALL_CSUM) &&
+		    !(features & NETIF_F_CSUM_MASK) &&
 		    skb_checksum_help(skb))
 			goto drop;
 		skb_queue_tail(&q->sk.sk_receive_queue, skb);
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 651d35e..ae5cc2b 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -965,7 +965,7 @@ static void team_port_disable(struct team *team,
 	team_mcast_rejoin(team);
 }
 
-#define TEAM_VLAN_FEATURES (NETIF_F_ALL_CSUM | NETIF_F_SG | \
+#define TEAM_VLAN_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \
 			    NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \
 			    NETIF_F_HIGHDMA | NETIF_F_LRO)
 
@@ -2073,7 +2073,6 @@ static void team_setup(struct net_device *dev)
 			   NETIF_F_HW_VLAN_CTAG_RX |
 			   NETIF_F_HW_VLAN_CTAG_FILTER;
 
-	dev->hw_features &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_HW_CSUM);
 	dev->features |= dev->hw_features;
 }
 
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index d9427ca..34642a9 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1986,7 +1986,7 @@ rtl8152_features_check(struct sk_buff *skb, struct net_device *dev,
 	int offset = skb_transport_offset(skb);
 
 	if ((mss || skb->ip_summed == CHECKSUM_PARTIAL) && offset > max_offset)
-		features &= ~(NETIF_F_ALL_CSUM | NETIF_F_GSO_MASK);
+		features &= ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
 	else if ((skb->len + sizeof(struct tx_desc)) > agg_buf_sz)
 		features &= ~NETIF_F_GSO_MASK;
 
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c
index 679785b..9de4f23 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c
@@ -69,7 +69,7 @@ ksocknal_lib_zc_capable(ksock_conn_t *conn)
 
 	/* ZC if the socket supports scatter/gather and doesn't need software
 	 * checksums */
-	return ((caps & NETIF_F_SG) != 0 && (caps & NETIF_F_ALL_CSUM) != 0);
+	return ((caps & NETIF_F_SG) != 0 && (caps & NETIF_F_CSUM_MASK) != 0);
 }
 
 int
diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
index 6395f83..2c4e94a 100644
--- a/include/linux/netdev_features.h
+++ b/include/linux/netdev_features.h
@@ -149,7 +149,12 @@ enum {
 #define NETIF_F_GEN_CSUM	NETIF_F_HW_CSUM
 #define NETIF_F_V4_CSUM		(NETIF_F_GEN_CSUM | NETIF_F_IP_CSUM)
 #define NETIF_F_V6_CSUM		(NETIF_F_GEN_CSUM | NETIF_F_IPV6_CSUM)
-#define NETIF_F_ALL_CSUM	(NETIF_F_V4_CSUM | NETIF_F_V6_CSUM)
+
+/* List of IP checksum features. Note that NETIF_HW_CSUM should not be
+ * set in features when NETIF_F_IP_CSUM or NETIF_F_IPV6_CSUM are set--
+ * this would be contradictory
+ */
+#define NETIF_F_CSUM_MASK	(NETIF_F_V4_CSUM | NETIF_F_V6_CSUM)
 
 #define NETIF_F_ALL_TSO 	(NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN)
 
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 7d2d1d7..aecab79 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3732,12 +3732,12 @@ static inline netdev_features_t netdev_intersect_features(netdev_features_t f1,
 							  netdev_features_t f2)
 {
 	if (f1 & NETIF_F_GEN_CSUM)
-		f1 |= (NETIF_F_ALL_CSUM & ~NETIF_F_GEN_CSUM);
+		f1 |= (NETIF_F_CSUM_MASK & ~NETIF_F_GEN_CSUM);
 	if (f2 & NETIF_F_GEN_CSUM)
-		f2 |= (NETIF_F_ALL_CSUM & ~NETIF_F_GEN_CSUM);
+		f2 |= (NETIF_F_CSUM_MASK & ~NETIF_F_GEN_CSUM);
 	f1 &= f2;
 	if (f1 & NETIF_F_GEN_CSUM)
-		f1 &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_GEN_CSUM);
+		f1 &= ~(NETIF_F_CSUM_MASK & ~NETIF_F_GEN_CSUM);
 
 	return f1;
 }
diff --git a/include/net/vxlan.h b/include/net/vxlan.h
index c1c899c..b5a1aec 100644
--- a/include/net/vxlan.h
+++ b/include/net/vxlan.h
@@ -232,7 +232,7 @@ static inline netdev_features_t vxlan_features_check(struct sk_buff *skb,
 	     skb->inner_protocol != htons(ETH_P_TEB) ||
 	     (skb_inner_mac_header(skb) - skb_transport_header(skb) !=
 	      sizeof(struct udphdr) + sizeof(struct vxlanhdr))))
-		return features & ~(NETIF_F_ALL_CSUM | NETIF_F_GSO_MASK);
+		return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
 
 	return features;
 }
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index c2bf37f..58477d9 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -542,7 +542,7 @@ static int vlan_dev_init(struct net_device *dev)
 					  (1<<__LINK_STATE_DORMANT))) |
 		      (1<<__LINK_STATE_PRESENT);
 
-	dev->hw_features = NETIF_F_ALL_CSUM | NETIF_F_SG |
+	dev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG |
 			   NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE |
 			   NETIF_F_HIGHDMA | NETIF_F_SCTP_CRC |
 			   NETIF_F_ALL_FCOE;
diff --git a/net/core/dev.c b/net/core/dev.c
index 41cef3e..1aa9030 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2645,7 +2645,7 @@ static netdev_features_t harmonize_features(struct sk_buff *skb,
 
 	if (skb->ip_summed != CHECKSUM_NONE &&
 	    !can_checksum_protocol(features, type)) {
-		features &= ~NETIF_F_ALL_CSUM;
+		features &= ~NETIF_F_CSUM_MASK;
 	} else if (illegal_highdma(skb->dev, skb)) {
 		features &= ~NETIF_F_SG;
 	}
@@ -2792,7 +2792,7 @@ static struct sk_buff *validate_xmit_skb(struct sk_buff *skb, struct net_device
 			else
 				skb_set_transport_header(skb,
 							 skb_checksum_start_offset(skb));
-			if (!(features & NETIF_F_ALL_CSUM) &&
+			if (!(features & NETIF_F_CSUM_MASK) &&
 			    skb_checksum_help(skb))
 				goto out_kfree_skb;
 		}
@@ -7548,15 +7548,15 @@ netdev_features_t netdev_increment_features(netdev_features_t all,
 	netdev_features_t one, netdev_features_t mask)
 {
 	if (mask & NETIF_F_GEN_CSUM)
-		mask |= NETIF_F_ALL_CSUM;
+		mask |= NETIF_F_CSUM_MASK;
 	mask |= NETIF_F_VLAN_CHALLENGED;
 
-	all |= one & (NETIF_F_ONE_FOR_ALL|NETIF_F_ALL_CSUM) & mask;
+	all |= one & (NETIF_F_ONE_FOR_ALL | NETIF_F_CSUM_MASK) & mask;
 	all &= one | ~NETIF_F_ALL_FOR_ALL;
 
 	/* If one device supports hw checksumming, set for all. */
 	if (all & NETIF_F_GEN_CSUM)
-		all &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_GEN_CSUM);
+		all &= ~(NETIF_F_CSUM_MASK & ~NETIF_F_GEN_CSUM);
 
 	return all;
 }
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 4a0cab8..09948a7 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -235,7 +235,7 @@ static netdev_features_t ethtool_get_feature_mask(u32 eth_cmd)
 	switch (eth_cmd) {
 	case ETHTOOL_GTXCSUM:
 	case ETHTOOL_STXCSUM:
-		return NETIF_F_ALL_CSUM | NETIF_F_SCTP_CRC;
+		return NETIF_F_CSUM_MASK | NETIF_F_SCTP_CRC;
 	case ETHTOOL_GRXCSUM:
 	case ETHTOOL_SRXCSUM:
 		return NETIF_F_RXCSUM;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index c172877..47f2741 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1019,7 +1019,7 @@ int tcp_sendpage(struct sock *sk, struct page *page, int offset,
 	ssize_t res;
 
 	if (!(sk->sk_route_caps & NETIF_F_SG) ||
-	    !(sk->sk_route_caps & NETIF_F_ALL_CSUM))
+	    !(sk->sk_route_caps & NETIF_F_CSUM_MASK))
 		return sock_no_sendpage(sk->sk_socket, page, offset, size,
 					flags);
 
@@ -1176,7 +1176,7 @@ new_segment:
 			/*
 			 * Check whether we can use HW checksum.
 			 */
-			if (sk->sk_route_caps & NETIF_F_ALL_CSUM)
+			if (sk->sk_route_caps & NETIF_F_CSUM_MASK)
 				skb->ip_summed = CHECKSUM_PARTIAL;
 
 			skb_entail(sk, skb);
-- 
2.4.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 05/15] net: Eliminate NETIF_F_GEN_CSUM and NETIF_F_V[46]_CSUM
  2015-11-19 19:55 [PATCH RFC 00/15] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM Tom Herbert
                   ` (3 preceding siblings ...)
  2015-11-19 19:55 ` [PATCH 04/15] net: Rename NETIF_F_ALL_CSUM to NETIF_F_CSUM_MASK Tom Herbert
@ 2015-11-19 19:55 ` Tom Herbert
  2015-11-19 19:55 ` [PATCH 06/15] tcp: Fix conditions to determine checksum offload Tom Herbert
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Tom Herbert @ 2015-11-19 19:55 UTC (permalink / raw)
  To: davem, netdev; +Cc: kernel-team

These netif flags are unnecessary convolutions. It is more
straightforward to just use NETIF_F_HW_CSUM, NETIF_F_IP_CSUM,
and NETIF_F_IPV6_CSUM directly.

This patch also:
    - Cleans up can_checksum_protocol
    - Simplifies netdev_intersect_features

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 drivers/net/ethernet/sfc/efx.c           |  2 +-
 drivers/net/macvlan.c                    |  2 +-
 include/linux/if_vlan.h                  |  2 +-
 include/linux/netdev_features.h          |  9 +++----
 include/linux/netdevice.h                | 40 ++++++++++++++++++++------------
 net/core/dev.c                           | 12 +++++-----
 net/core/pktgen.c                        |  4 ++--
 net/ipv4/ip_output.c                     |  2 +-
 net/ipv4/netfilter/nf_nat_l3proto_ipv4.c |  3 ++-
 net/ipv4/udp.c                           |  3 ++-
 net/ipv4/udp_offload.c                   |  5 ++--
 net/ipv6/ip6_output.c                    |  2 +-
 net/ipv6/netfilter/nf_nat_l3proto_ipv6.c |  3 ++-
 13 files changed, 50 insertions(+), 39 deletions(-)

diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 78aaca2..a544948 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -3122,7 +3122,7 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
 	net_dev->features |= (efx->type->offload_features | NETIF_F_SG |
 			      NETIF_F_HIGHDMA | NETIF_F_TSO |
 			      NETIF_F_RXCSUM);
-	if (efx->type->offload_features & NETIF_F_V6_CSUM)
+	if (efx->type->offload_features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM))
 		net_dev->features |= NETIF_F_TSO6;
 	/* Mask for features that also apply to VLAN devices */
 	net_dev->vlan_features |= (NETIF_F_HW_CSUM | NETIF_F_SG |
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index ae3b486..6a57a00 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -758,7 +758,7 @@ static struct lock_class_key macvlan_netdev_xmit_lock_key;
 static struct lock_class_key macvlan_netdev_addr_lock_key;
 
 #define ALWAYS_ON_FEATURES \
-	(NETIF_F_SG | NETIF_F_GEN_CSUM | NETIF_F_GSO_SOFTWARE | NETIF_F_LLTX | \
+	(NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE | NETIF_F_LLTX | \
 	 NETIF_F_GSO_ROBUST)
 
 #define MACVLAN_FEATURES \
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index 67ce5bd..ad599c4 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -621,7 +621,7 @@ static inline netdev_features_t vlan_features_check(const struct sk_buff *skb,
 						     NETIF_F_SG |
 						     NETIF_F_HIGHDMA |
 						     NETIF_F_FRAGLIST |
-						     NETIF_F_GEN_CSUM |
+						     NETIF_F_HW_CSUM |
 						     NETIF_F_HW_VLAN_CTAG_TX |
 						     NETIF_F_HW_VLAN_STAG_TX);
 
diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
index 2c4e94a..d9654f0e 100644
--- a/include/linux/netdev_features.h
+++ b/include/linux/netdev_features.h
@@ -146,15 +146,12 @@ enum {
 #define NETIF_F_GSO_SOFTWARE	(NETIF_F_TSO | NETIF_F_TSO_ECN | \
 				 NETIF_F_TSO6 | NETIF_F_UFO)
 
-#define NETIF_F_GEN_CSUM	NETIF_F_HW_CSUM
-#define NETIF_F_V4_CSUM		(NETIF_F_GEN_CSUM | NETIF_F_IP_CSUM)
-#define NETIF_F_V6_CSUM		(NETIF_F_GEN_CSUM | NETIF_F_IPV6_CSUM)
-
-/* List of IP checksum features. Note that NETIF_HW_CSUM should not be
+/* List of IP checksum features. Note that NETIF_F_ HW_CSUM should not be
  * set in features when NETIF_F_IP_CSUM or NETIF_F_IPV6_CSUM are set--
  * this would be contradictory
  */
-#define NETIF_F_CSUM_MASK	(NETIF_F_V4_CSUM | NETIF_F_V6_CSUM)
+#define NETIF_F_CSUM_MASK	(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \
+				 NETIF_F_HW_CSUM)
 
 #define NETIF_F_ALL_TSO 	(NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN)
 
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index aecab79..52b41c8 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3660,13 +3660,24 @@ __be16 skb_network_protocol(struct sk_buff *skb, int *depth);
 static inline bool can_checksum_protocol(netdev_features_t features,
 					 __be16 protocol)
 {
-	return ((features & NETIF_F_GEN_CSUM) ||
-		((features & NETIF_F_V4_CSUM) &&
-		 protocol == htons(ETH_P_IP)) ||
-		((features & NETIF_F_V6_CSUM) &&
-		 protocol == htons(ETH_P_IPV6)) ||
-		((features & NETIF_F_FCOE_CRC) &&
-		 protocol == htons(ETH_P_FCOE)));
+	if (protocol == htons(ETH_P_FCOE))
+		return !!(features & NETIF_F_FCOE_CRC);
+
+	/* Assume this is an IP checksum (not SCTP CRC) */
+
+	if (features & NETIF_F_HW_CSUM) {
+		/* Can checksum everything */
+		return true;
+	}
+
+	switch (protocol) {
+	case htons(ETH_P_IP):
+		return !!(features & NETIF_F_IP_CSUM);
+	case htons(ETH_P_IPV6):
+		return !!(features & NETIF_F_IPV6_CSUM);
+	default:
+		return false;
+	}
 }
 
 #ifdef CONFIG_BUG
@@ -3731,15 +3742,14 @@ void linkwatch_run_queue(void);
 static inline netdev_features_t netdev_intersect_features(netdev_features_t f1,
 							  netdev_features_t f2)
 {
-	if (f1 & NETIF_F_GEN_CSUM)
-		f1 |= (NETIF_F_CSUM_MASK & ~NETIF_F_GEN_CSUM);
-	if (f2 & NETIF_F_GEN_CSUM)
-		f2 |= (NETIF_F_CSUM_MASK & ~NETIF_F_GEN_CSUM);
-	f1 &= f2;
-	if (f1 & NETIF_F_GEN_CSUM)
-		f1 &= ~(NETIF_F_CSUM_MASK & ~NETIF_F_GEN_CSUM);
+	if ((f1 ^ f2) & NETIF_F_HW_CSUM) {
+		if (f1 & NETIF_F_HW_CSUM)
+			f1 |= (NETIF_F_IP_CSUM|NETIF_F_IP_CSUM);
+		else
+			f2 |= (NETIF_F_IP_CSUM|NETIF_F_IP_CSUM);
+	}
 
-	return f1;
+	return f1 & f2;
 }
 
 static inline netdev_features_t netdev_get_wanted_features(
diff --git a/net/core/dev.c b/net/core/dev.c
index 1aa9030..65784f0 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6443,9 +6443,9 @@ static netdev_features_t netdev_fix_features(struct net_device *dev,
 	/* UFO needs SG and checksumming */
 	if (features & NETIF_F_UFO) {
 		/* maybe split UFO into V4 and V6? */
-		if (!((features & NETIF_F_GEN_CSUM) ||
-		    (features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))
-			    == (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) {
+		if (!(features & NETIF_F_HW_CSUM) &&
+		    ((features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)) !=
+		     (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM))) {
 			netdev_dbg(dev,
 				"Dropping NETIF_F_UFO since no checksum offload features.\n");
 			features &= ~NETIF_F_UFO;
@@ -7547,7 +7547,7 @@ static int dev_cpu_callback(struct notifier_block *nfb,
 netdev_features_t netdev_increment_features(netdev_features_t all,
 	netdev_features_t one, netdev_features_t mask)
 {
-	if (mask & NETIF_F_GEN_CSUM)
+	if (mask & NETIF_F_HW_CSUM)
 		mask |= NETIF_F_CSUM_MASK;
 	mask |= NETIF_F_VLAN_CHALLENGED;
 
@@ -7555,8 +7555,8 @@ netdev_features_t netdev_increment_features(netdev_features_t all,
 	all &= one | ~NETIF_F_ALL_FOR_ALL;
 
 	/* If one device supports hw checksumming, set for all. */
-	if (all & NETIF_F_GEN_CSUM)
-		all &= ~(NETIF_F_CSUM_MASK & ~NETIF_F_GEN_CSUM);
+	if (all & NETIF_F_HW_CSUM)
+		all &= ~(NETIF_F_CSUM_MASK & ~NETIF_F_HW_CSUM);
 
 	return all;
 }
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index de8d5cc..2be1444 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -2898,7 +2898,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
 
 	if (!(pkt_dev->flags & F_UDPCSUM)) {
 		skb->ip_summed = CHECKSUM_NONE;
-	} else if (odev->features & NETIF_F_V4_CSUM) {
+	} else if (odev->features & (NETIF_F_HW_CSUM | NETIF_F_IP_CSUM)) {
 		skb->ip_summed = CHECKSUM_PARTIAL;
 		skb->csum = 0;
 		udp4_hwcsum(skb, iph->saddr, iph->daddr);
@@ -3032,7 +3032,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
 
 	if (!(pkt_dev->flags & F_UDPCSUM)) {
 		skb->ip_summed = CHECKSUM_NONE;
-	} else if (odev->features & NETIF_F_V6_CSUM) {
+	} else if (odev->features & (NETIF_F_HW_CSUM | NETIF_F_IPV6_CSUM)) {
 		skb->ip_summed = CHECKSUM_PARTIAL;
 		skb->csum_start = skb_transport_header(skb) - skb->head;
 		skb->csum_offset = offsetof(struct udphdr, check);
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 4233cbe..8432d50 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -912,7 +912,7 @@ static int __ip_append_data(struct sock *sk,
 	 */
 	if (transhdrlen &&
 	    length + fragheaderlen <= mtu &&
-	    rt->dst.dev->features & NETIF_F_V4_CSUM &&
+	    rt->dst.dev->features & (NETIF_F_HW_CSUM | NETIF_F_IP_CSUM) &&
 	    !(flags & MSG_MORE) &&
 	    !exthdrlen)
 		csummode = CHECKSUM_PARTIAL;
diff --git a/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c b/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c
index 5075b7e..61c7cc2 100644
--- a/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c
@@ -132,7 +132,8 @@ static void nf_nat_ipv4_csum_recalc(struct sk_buff *skb,
 
 	if (skb->ip_summed != CHECKSUM_PARTIAL) {
 		if (!(rt->rt_flags & RTCF_LOCAL) &&
-		    (!skb->dev || skb->dev->features & NETIF_F_V4_CSUM)) {
+		    (!skb->dev || skb->dev->features &
+		     (NETIF_F_IP_CSUM | NETIF_F_HW_CSUM))) {
 			skb->ip_summed = CHECKSUM_PARTIAL;
 			skb->csum_start = skb_headroom(skb) +
 					  skb_network_offset(skb) +
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 24ec14f..4efb85f 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -773,7 +773,8 @@ void udp_set_csum(bool nocheck, struct sk_buff *skb,
 	else if (skb_is_gso(skb))
 		uh->check = ~udp_v4_check(len, saddr, daddr, 0);
 	else if (skb_dst(skb) && skb_dst(skb)->dev &&
-		 (skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) {
+		 (skb_dst(skb)->dev->features &
+		  (NETIF_F_IP_CSUM | NETIF_F_HW_CSUM))) {
 
 		BUG_ON(skb->ip_summed == CHECKSUM_PARTIAL);
 
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
index f938616..1300426 100644
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
@@ -60,8 +60,9 @@ static struct sk_buff *__skb_udp_tunnel_segment(struct sk_buff *skb,
 
 	/* Try to offload checksum if possible */
 	offload_csum = !!(need_csum &&
-			  (skb->dev->features &
-			   (is_ipv6 ? NETIF_F_V6_CSUM : NETIF_F_V4_CSUM)));
+			  ((skb->dev->features & NETIF_F_HW_CSUM) ||
+			   (skb->dev->features & (is_ipv6 ?
+			    NETIF_F_IPV6_CSUM : NETIF_F_IP_CSUM))));
 
 	/* segment inner packet. */
 	enc_features = skb->dev->hw_enc_features & features;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index e6a7bd15..2f74845 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1322,7 +1322,7 @@ emsgsize:
 	    headersize == sizeof(struct ipv6hdr) &&
 	    length < mtu - headersize &&
 	    !(flags & MSG_MORE) &&
-	    rt->dst.dev->features & NETIF_F_V6_CSUM)
+	    rt->dst.dev->features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM))
 		csummode = CHECKSUM_PARTIAL;
 
 	if (sk->sk_type == SOCK_DGRAM || sk->sk_type == SOCK_RAW) {
diff --git a/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c b/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c
index 238e70c..6ce3099 100644
--- a/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c
@@ -136,7 +136,8 @@ static void nf_nat_ipv6_csum_recalc(struct sk_buff *skb,
 
 	if (skb->ip_summed != CHECKSUM_PARTIAL) {
 		if (!(rt->rt6i_flags & RTF_LOCAL) &&
-		    (!skb->dev || skb->dev->features & NETIF_F_V6_CSUM)) {
+		    (!skb->dev || skb->dev->features &
+		     (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM))) {
 			skb->ip_summed = CHECKSUM_PARTIAL;
 			skb->csum_start = skb_headroom(skb) +
 					  skb_network_offset(skb) +
-- 
2.4.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 06/15] tcp: Fix conditions to determine checksum offload
  2015-11-19 19:55 [PATCH RFC 00/15] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM Tom Herbert
                   ` (4 preceding siblings ...)
  2015-11-19 19:55 ` [PATCH 05/15] net: Eliminate NETIF_F_GEN_CSUM and NETIF_F_V[46]_CSUM Tom Herbert
@ 2015-11-19 19:55 ` Tom Herbert
  2015-11-19 19:55 ` [PATCH 07/15] net: Add driver helper functions to determine checksum offloadability Tom Herbert
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Tom Herbert @ 2015-11-19 19:55 UTC (permalink / raw)
  To: davem, netdev; +Cc: kernel-team

In tcp_send_sendpage and tcp_sendmsg we check the route capabilities to
determine if checksum offload can be performed. This check currently
does not take the IP protocol into account for devices that advertise
only one of NETIF_F_IPV6_CSUM or NETIF_F_IP_CSUM. This patch adds a
function to check capabilities for checksum offload with a socket
called sk_check_csum_caps. This function checks for specific IPv4 or
IPv6 offload support based on the family of the socket.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 include/net/sock.h | 9 +++++++++
 net/ipv4/tcp.c     | 4 ++--
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/include/net/sock.h b/include/net/sock.h
index 7f89e4b..8ba056e 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1794,6 +1794,15 @@ static inline void sk_nocaps_add(struct sock *sk, netdev_features_t flags)
 	sk->sk_route_caps &= ~flags;
 }
 
+static inline bool sk_check_csum_caps(struct sock *sk)
+{
+	return (sk->sk_route_caps & NETIF_F_HW_CSUM) ||
+	       (sk->sk_family == PF_INET &&
+		(sk->sk_route_caps & NETIF_F_IP_CSUM)) ||
+	       (sk->sk_family == PF_INET6 &&
+		(sk->sk_route_caps & NETIF_F_IPV6_CSUM));
+}
+
 static inline int skb_do_copy_data_nocache(struct sock *sk, struct sk_buff *skb,
 					   struct iov_iter *from, char *to,
 					   int copy, int offset)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 47f2741..1ab2949 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1019,7 +1019,7 @@ int tcp_sendpage(struct sock *sk, struct page *page, int offset,
 	ssize_t res;
 
 	if (!(sk->sk_route_caps & NETIF_F_SG) ||
-	    !(sk->sk_route_caps & NETIF_F_CSUM_MASK))
+	    !sk_check_csum_caps(sk))
 		return sock_no_sendpage(sk->sk_socket, page, offset, size,
 					flags);
 
@@ -1176,7 +1176,7 @@ new_segment:
 			/*
 			 * Check whether we can use HW checksum.
 			 */
-			if (sk->sk_route_caps & NETIF_F_CSUM_MASK)
+			if (sk_check_csum_caps(sk))
 				skb->ip_summed = CHECKSUM_PARTIAL;
 
 			skb_entail(sk, skb);
-- 
2.4.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 07/15] net: Add driver helper functions to determine checksum offloadability
  2015-11-19 19:55 [PATCH RFC 00/15] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM Tom Herbert
                   ` (5 preceding siblings ...)
  2015-11-19 19:55 ` [PATCH 06/15] tcp: Fix conditions to determine checksum offload Tom Herbert
@ 2015-11-19 19:55 ` Tom Herbert
  2015-11-22 10:14   ` Yuval Mintz
  2015-11-19 19:55 ` [PATCH 08/15] net: Elaborate on checksum offload interface description Tom Herbert
                   ` (8 subsequent siblings)
  15 siblings, 1 reply; 19+ messages in thread
From: Tom Herbert @ 2015-11-19 19:55 UTC (permalink / raw)
  To: davem, netdev; +Cc: kernel-team

Add skb_csum_offload_chk driver helper function to determine if a
device with limited checksum offload capabilities is able to offload the
checksum for a given packet.

This patch includes:
  - The skb_csum_offload_chk function. Returns true if checksum is
    offloadable, else false. Optionally, in the case that the checksum
    is not offloable, the function can call skb_checksum_help to resolve
    the checksum. skb_csum_offload_chk also returns whether the checksum
    refers to an encapsulated checksum.
  - Definition of skb_csum_offl_spec structure that caller uses to
    indicate rules about what it can offload (e.g. IPv4/v6, TCP/UDP only,
    whether encapsulated checksums can be offloaded, whether checksum with
    IPv6 extension headers can be offloaded).
  - Ancilary functions called skb_csum_offload_chk_help,
    skb_csum_off_chk_help_cmn, skb_csum_off_chk_help_cmn_v4_only.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 include/linux/netdevice.h |  78 +++++++++++++++++++++++++++
 net/core/dev.c            | 133 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 211 insertions(+)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 52b41c8..14c2ea9 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2491,6 +2491,71 @@ static inline void skb_gro_remcsum_cleanup(struct sk_buff *skb,
 	remcsum_unadjust((__sum16 *)ptr, grc->delta);
 }
 
+struct skb_csum_offl_spec {
+	__u16		ipv4_okay:1,
+			ipv6_okay:1,
+			encap_okay:1,
+			ip_options_okay:1,
+			ext_hdrs_okay:1,
+			tcp_okay:1,
+			udp_okay:1,
+			sctp_okay:1,
+			vlan_okay:1,
+			no_encapped_ipv6:1,
+			no_not_encapped:1;
+};
+
+bool __skb_csum_offload_chk(struct sk_buff *skb,
+			    const struct skb_csum_offl_spec *spec,
+			    bool *csum_encapped,
+			    bool csum_help);
+
+static inline bool skb_csum_offload_chk(struct sk_buff *skb,
+					const struct skb_csum_offl_spec *spec,
+					bool *csum_encapped,
+					bool csum_help)
+{
+	if (skb->ip_summed != CHECKSUM_PARTIAL)
+		return false;
+
+	return __skb_csum_offload_chk(skb, spec, csum_encapped, csum_help);
+}
+
+static inline bool skb_csum_offload_chk_help(struct sk_buff *skb,
+					     const struct skb_csum_offl_spec *spec)
+{
+	bool csum_encapped;
+
+	return skb_csum_offload_chk(skb, spec, &csum_encapped, true);
+}
+
+static inline bool skb_csum_off_chk_help_cmn(struct sk_buff *skb)
+{
+	static const struct skb_csum_offl_spec csum_offl_spec = {
+		.ipv4_okay = 1,
+		.ip_options_okay = 1,
+		.ipv6_okay = 1,
+		.vlan_okay = 1,
+		.tcp_okay = 1,
+		.udp_okay = 1,
+	};
+
+	return skb_csum_offload_chk_help(skb, &csum_offl_spec);
+}
+
+static inline bool skb_csum_off_chk_help_cmn_v4_only(struct sk_buff *skb)
+{
+	static const struct skb_csum_offl_spec csum_offl_spec = {
+		.ipv4_okay = 1,
+		.ip_options_okay = 1,
+		.tcp_okay = 1,
+		.udp_okay = 1,
+		.vlan_okay = 1,
+	};
+
+	return skb_csum_offload_chk_help(skb, &csum_offl_spec);
+}
+
 static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev,
 				  unsigned short type,
 				  const void *daddr, const void *saddr,
@@ -3680,6 +3745,19 @@ static inline bool can_checksum_protocol(netdev_features_t features,
 	}
 }
 
+/* Map an ethertype into IP protocol if possible */
+static inline int eproto_to_ipproto(int eproto)
+{
+	switch (eproto) {
+	case htons(ETH_P_IP):
+		return IPPROTO_IP;
+	case htons(ETH_P_IPV6):
+		return IPPROTO_IPV6;
+	default:
+		return -1;
+	}
+}
+
 #ifdef CONFIG_BUG
 void netdev_rx_csum_fault(struct net_device *dev);
 #else
diff --git a/net/core/dev.c b/net/core/dev.c
index 65784f0..7c21747 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -138,6 +138,7 @@
 #include <linux/errqueue.h>
 #include <linux/hrtimer.h>
 #include <linux/netfilter_ingress.h>
+#include <linux/sctp.h>
 
 #include "net-sysfs.h"
 
@@ -2471,6 +2472,138 @@ out:
 }
 EXPORT_SYMBOL(skb_checksum_help);
 
+/* skb_csum_offload_check - Driver helper function to determine if a device
+ * with limited checksum offload capabilities is able to offload the checksum
+ * for a given packet.
+ *
+ * Arguments:
+ *   skb - sk_buff for the packet in question
+ *   spec - contains the description of what device can offload
+ *   csum_encapped - returns true if the checksum being offloaded is
+ *	      encpasulated. That is it is checksum for the transport header
+ *	      in the inner headers.
+ *   checksum_help - when set indicates that helper function should
+ *	      call skb_checksum_help if offload checks fail
+ *
+ * Returns:
+ *   true: Packet has passed the checksum checks and should be offloadable to
+ *	   the device (a driver may still need to check for additional
+ *	   restrictions of its device)
+ *   false: Checksum is not offloadable. If checksum_help was set then
+ *	   skb_checksum_help was called to resolve checksum for non-GSO
+ *	   packets and when IP protocol is not SCTP
+ */
+bool __skb_csum_offload_chk(struct sk_buff *skb,
+			    const struct skb_csum_offl_spec *spec,
+			    bool *csum_encapped,
+			    bool csum_help)
+{
+	struct iphdr *iph;
+	struct ipv6hdr *ipv6;
+	void *nhdr;
+	int protocol;
+	u8 ip_proto;
+
+	if (skb->protocol == htons(ETH_P_8021Q) ||
+	    skb->protocol == htons(ETH_P_8021AD)) {
+		if (!spec->vlan_okay)
+			goto need_help;
+	}
+
+	/* We are assuming that checksum start must coincide with the inner or
+	 * outer transport header. This is true for TCP, UDP, and SCTP-- but if
+	 * support is ever added for GRE checksum offload this would not hold.
+	 */
+	if (skb_checksum_start_offset(skb) == skb_transport_offset(skb)) {
+		/* Non-encapsulated checksum */
+		protocol = eproto_to_ipproto(vlan_get_protocol(skb));
+		nhdr = skb_network_header(skb);
+		*csum_encapped = false;
+		if (spec->no_not_encapped)
+			goto need_help;
+	} else if (skb->encapsulation && spec->encap_okay &&
+		   skb_checksum_start_offset(skb) ==
+		   skb_inner_transport_offset(skb)) {
+		/* Encapsulated checksum */
+		*csum_encapped = true;
+		switch (skb->inner_protocol_type) {
+		case ENCAP_TYPE_ETHER:
+			protocol = eproto_to_ipproto(skb->inner_protocol);
+			break;
+		case ENCAP_TYPE_IPPROTO:
+			protocol = skb->inner_protocol;
+			break;
+		}
+		nhdr = skb_inner_network_header(skb);
+	} else {
+		goto need_help;
+	}
+
+	switch (protocol) {
+	case IPPROTO_IP:
+		if (!spec->ipv4_okay)
+			goto need_help;
+		iph = nhdr;
+		ip_proto = iph->protocol;
+		if (iph->ihl != 5 && !spec->ip_options_okay)
+			goto need_help;
+		break;
+	case IPPROTO_IPV6:
+		if (!spec->ipv6_okay)
+			goto need_help;
+		ipv6 = nhdr;
+		nhdr += sizeof(*ipv6);
+		ip_proto = ipv6->nexthdr;
+		break;
+	default:
+		goto need_help;
+	}
+
+ip_proto_again:
+	switch (ip_proto) {
+	case IPPROTO_TCP:
+		if (!spec->tcp_okay ||
+		    skb->csum_offset != offsetof(struct tcphdr, check))
+			goto need_help;
+		break;
+	case IPPROTO_UDP:
+		if (!spec->udp_okay ||
+		    skb->csum_offset != offsetof(struct udphdr, check))
+			goto need_help;
+		break;
+	case IPPROTO_SCTP:
+		if (!spec->sctp_okay ||
+		    skb->csum_offset != offsetof(struct sctphdr, checksum))
+			goto cant_help;
+		break;
+	case NEXTHDR_HOP:
+	case NEXTHDR_ROUTING:
+	case NEXTHDR_DEST: {
+		u8 *opthdr = nhdr;
+
+		if (protocol != IPPROTO_IPV6 || !spec->ext_hdrs_okay)
+			goto need_help;
+
+		ip_proto = opthdr[0];
+		nhdr += (opthdr[1] + 1) << 3;
+
+		goto ip_proto_again;
+	}
+	default:
+		goto need_help;
+	}
+
+	/* Passed the tests */
+	return true;
+
+need_help:
+	if (csum_help && !skb_shinfo(skb)->gso_size)
+		skb_checksum_help(skb);
+cant_help:
+	return false;
+}
+EXPORT_SYMBOL(__skb_csum_offload_chk);
+
 __be16 skb_network_protocol(struct sk_buff *skb, int *depth)
 {
 	__be16 type = skb->protocol;
-- 
2.4.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 08/15] net: Elaborate on checksum offload interface description
  2015-11-19 19:55 [PATCH RFC 00/15] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM Tom Herbert
                   ` (6 preceding siblings ...)
  2015-11-19 19:55 ` [PATCH 07/15] net: Add driver helper functions to determine checksum offloadability Tom Herbert
@ 2015-11-19 19:55 ` Tom Herbert
  2015-11-19 19:55 ` [PATCH 09/15] bnx2x: Convert to advertise NETIF_F_HW_CSUM Tom Herbert
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Tom Herbert @ 2015-11-19 19:55 UTC (permalink / raw)
  To: davem, netdev; +Cc: kernel-team

Add specifics and details the description of the interface between
the stack and drivers for doing checksum offload. This description
is meant to be as specific and complete as possible.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 include/linux/skbuff.h | 138 ++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 109 insertions(+), 29 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 0713080..a3a7557 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -39,11 +39,55 @@
 #include <linux/in6.h>
 #include <net/flow.h>
 
-/* A. Checksumming of received packets by device.
+/* The interface for checksum offload between the stack and networking drivers
+ * is as follows...
+ *
+ * A. IP checksum related features
+ *
+ * Drivers advertise checksum offload capabilities in the features of a device.
+ * From the stack's point of view these are capabilities offered by the driver,
+ * a driver typically only advertises features that it is capable of offloading
+ * to its device.
+ *
+ * The checksum related features are:
+ *
+ *	NETIF_F_HW_CSUM	- The driver (or its device) is able to compute the
+ *			  IP (one's complement) checksum for any combination
+ *			  of protocols or protocol layering. The checksum is
+ *			  computed and set in a packet per the CHECKSUM_PARTIAL
+ *			  interface (see below).
+ *
+ *	NETIF_F_IP_CSUM - Driver (device) is only able to checksum plain
+ *			  TCP or UDP packets over IPv4. These are specifically
+ *			  unencapsulated packets of the form IPv4|TCP or
+ *			  IPv4|UDP where the Protocol field in the IPv4 header
+ *			  is TCP or UDP. The IPv4 header may contain IP options
+ *			  This feature cannot be set in features for a device
+ *			  with NETIF_F_HW_CSUM also set. This feature is being
+ *			  DEPRECATED (see below).
+ *
+ *	NETIF_F_IPV6_CSUM - Driver (device) is only able to checksum plain
+ *			  TCP or UDP packets over IPv6. These are specifically
+ *			  unencapsulated packets of the form IPv6|TCP or
+ *			  IPv4|UDP where the Next Header field in the IPv6
+ *			  header is either TCP or UDP. IPv6 extension headers
+ *			  are not supported with this feature. This feature
+ *			  cannot be set in features for a device with
+ *			  NETIF_F_HW_CSUM also set. This feature is being
+ *			  DEPRECATED (see below).
+ *
+ *	NETIF_F_RXCSUM - Driver (device) performs receive checksum offload.
+ *			 This flag is used only used to disable the RX checksum
+ *			 feature for a device. The stack will accept receive
+ *			 checksum indication in packets received on a device
+ *			 regardless of whether NETIF_F_RXCSUM is set.
+ *
+ * B. Checksumming of received packets by device. Indication of checksum
+ *    verification is in set skb->ip_summed. Possible values are:
  *
  * CHECKSUM_NONE:
  *
- *   Device failed to checksum this packet e.g. due to lack of capabilities.
+ *   Device did not checksum this packet e.g. due to lack of capabilities.
  *   The packet contains full (though not verified) checksum in packet but
  *   not in skb->csum. Thus, skb->csum is undefined in this case.
  *
@@ -53,9 +97,8 @@
  *   (as in CHECKSUM_COMPLETE), but it does parse headers and verify checksums
  *   for specific protocols. For such packets it will set CHECKSUM_UNNECESSARY
  *   if their checksums are okay. skb->csum is still undefined in this case
- *   though. It is a bad option, but, unfortunately, nowadays most vendors do
- *   this. Apparently with the secret goal to sell you new devices, when you
- *   will add new protocol to your host, f.e. IPv6 8)
+ *   though. A driver or device must never modify the checksum field in the
+ *   packet even if checksum is verified.
  *
  *   CHECKSUM_UNNECESSARY is applicable to following protocols:
  *     TCP: IPv6 and IPv4.
@@ -96,40 +139,77 @@
  *   packet that are after the checksum being offloaded are not considered to
  *   be verified.
  *
- * B. Checksumming on output.
- *
- * CHECKSUM_NONE:
- *
- *   The skb was already checksummed by the protocol, or a checksum is not
- *   required.
+ * C. Checksumming on transmit for non-GSO. The stack requests checksum offload
+ *    in the skb->ip_summed for a packet. Values are:
  *
  * CHECKSUM_PARTIAL:
  *
- *   The device is required to checksum the packet as seen by hard_start_xmit()
+ *   The driver is required to checksum the packet as seen by hard_start_xmit()
  *   from skb->csum_start up to the end, and to record/write the checksum at
- *   offset skb->csum_start + skb->csum_offset.
+ *   offset skb->csum_start + skb->csum_offset. A driver may verify that the
+ *   csum_start and csum_offset values are valid values given the length and
+ *   offset of the packet, however they should not attempt to validate that the
+ *   checksum refers to a legitimate transport layer checksum-- it is the
+ *   purview of the stack to validate that csum_start and csum_offset are set
+ *   correctly.
+ *
+ *   When the stack requests checksum offload for a packet, the driver MUST
+ *   ensure that the checksum is set correctly. A driver can either offload the
+ *   checksum calculation to the device, or call skb_checksum_help (in the case
+ *   that the device does not support offload for a particular checksum).
+ *
+ *   NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM are being deprecated in favor of
+ *   NETIF_F_HW_CSUM. New devices should use NETIF_F_HW_CSUM to indicate
+ *   checksum offload capability. If a	device has limited checksum capabilities
+ *   (for instance can only perform NETIF_F_IP_CSUM or NETIF_F_IPV6_CSUM as
+ *   described above) a helper function can be called to resolve
+ *   CHECKSUM_PARTIAL. The helper functions are skb_csum_off_chk*. The helper
+ *   function takes a spec argument that describes the protocol layer that is
+ *   supported for checksum offload and can be called for each packet. If a
+ *   packet does not match the specification for offload, skb_checksum_help
+ *   is called to resolve the checksum.
  *
- *   The device must show its capabilities in dev->features, set up at device
- *   setup time, e.g. netdev_features.h:
+ * CHECKSUM_NONE:
  *
- *	NETIF_F_HW_CSUM	- It's a clever device, it's able to checksum everything.
- *	NETIF_F_IP_CSUM - Device is dumb, it's able to checksum only TCP/UDP over
- *			  IPv4. Sigh. Vendors like this way for an unknown reason.
- *			  Though, see comment above about CHECKSUM_UNNECESSARY. 8)
- *	NETIF_F_IPV6_CSUM - About as dumb as the last one but does IPv6 instead.
- *	NETIF_F_...     - Well, you get the picture.
+ *   The skb was already checksummed by the protocol, or a checksum is not
+ *   required.
  *
  * CHECKSUM_UNNECESSARY:
  *
- *   Normally, the device will do per protocol specific checksumming. Protocol
- *   implementations that do not want the NIC to perform the checksum
- *   calculation should use this flag in their outgoing skbs.
+ *   This has the same meaning on as CHECKSUM_NONE for checksum offload on
+ *   output.
  *
- *	NETIF_F_FCOE_CRC - This indicates that the device can do FCoE FC CRC
- *			   offload. Correspondingly, the FCoE protocol driver
- *			   stack should use CHECKSUM_UNNECESSARY.
- *
- * Any questions? No questions, good.		--ANK
+ * CHECKSUM_COMPLETE:
+ *   Not used in checksum output. If a driver observes a packet with this value
+ *   set in skbuff, if should treat as CHECKSUM_NONE being set.
+ *
+ * D. Non-IP checksum (CRC) offloads
+ *
+ *   NETIF_F_SCTP_CRC - This feature indicates that a device is capable of
+ *     offloading the SCTP CRC in a packet. To perform this offload the stack
+ *     will set ip_summed to CHECKSUM_PARTIAL and set csum_start and csum_offset
+ *     accordingly. Note the there is no indication in the skbuff that the
+ *     CHECKSUM_PARTIAL refers to an SCTP checksum, a driver that supports
+ *     both IP checksum offload and SCTP CRC offload must verify which offload
+ *     is configured for a packet presumably by inspecting packet headers.
+ *
+ *   NETIF_F_FCOE_CRC - This feature indicates that a device is capable of
+ *     offloading the FCOE CRC in a packet. To perform this offload the stack
+ *     will set ip_summed to CHECKSUM_PARTIAL and set csum_start and csum_offset
+ *     accordingly. Note the there is no indication in the skbuff that the
+ *     CHECKSUM_PARTIAL refers to an FCOE checksum, a driver that supports
+ *     both IP checksum offload and FCOE CRC offload must verify which offload
+ *     is configured for a packet presumably by inspecting packet headers.
+ *
+ * E. Checksumming on output with GSO.
+ *
+ * In the case of a GSO packet (skb_is_gso(skb) is true), checksum offload
+ * is implied by the SKB_GSO_* flags in gso_type. Most obviously, if the
+ * gso_type is SKB_GSO_TCPV4 or SKB_GSO_TCPV6, TCP checksum offload as
+ * part of the GSO operation is implied. If a checksum is being offloaded
+ * with GSO then ip_summed is CHECKSUM_PARTIAL, csum_start and csum_offset
+ * are set to refer to the outermost checksum being offload (two offloaded
+ * checksums are possible with UDP encapsulation).
  */
 
 /* Don't change this without changing skb_csum_unnecessary! */
-- 
2.4.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 09/15] bnx2x: Convert to advertise NETIF_F_HW_CSUM
  2015-11-19 19:55 [PATCH RFC 00/15] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM Tom Herbert
                   ` (7 preceding siblings ...)
  2015-11-19 19:55 ` [PATCH 08/15] net: Elaborate on checksum offload interface description Tom Herbert
@ 2015-11-19 19:55 ` Tom Herbert
  2015-11-19 19:55 ` [PATCH 10/15] bnxt: " Tom Herbert
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Tom Herbert @ 2015-11-19 19:55 UTC (permalink / raw)
  To: davem, netdev; +Cc: kernel-team

The skb_csum_offload_chk is used to resolve checksums that are unable
to be offloaded to the device.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c  | 15 +++++++++++++--
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c |  6 +++---
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index d9add7c..f239d34 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -3337,13 +3337,24 @@ static __le16 bnx2x_csum_fix(unsigned char *t_header, u16 csum, s8 fix)
 	return bswab16(tsum);
 }
 
+static const struct skb_csum_offl_spec csum_offl_spec = {
+	.ipv4_okay = 1,
+	.ip_options_okay = 1,
+	.ipv6_okay = 1,
+	.encap_okay = 1,
+	.vlan_okay = 1,
+	.tcp_okay = 1,
+	.udp_okay = 1,
+};
+
 static u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb)
 {
 	u32 rc;
 	__u8 prot = 0;
 	__be16 protocol;
+	bool csum_encapped;
 
-	if (skb->ip_summed != CHECKSUM_PARTIAL)
+	if (!skb_csum_offload_chk(skb, &csum_offl_spec, &csum_encapped, true))
 		return XMIT_PLAIN;
 
 	protocol = vlan_get_protocol(skb);
@@ -3355,7 +3366,7 @@ static u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb)
 		prot = ip_hdr(skb)->protocol;
 	}
 
-	if (!CHIP_IS_E1x(bp) && skb->encapsulation) {
+	if (!CHIP_IS_E1x(bp) && csum_encapped) {
 		if (inner_ip_hdr(skb)->version == 6) {
 			rc |= XMIT_CSUM_ENC_V6;
 			if (inner_ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 2273576..c3c3d5d 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -13184,7 +13184,7 @@ static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev,
 
 	dev->priv_flags |= IFF_UNICAST_FLT;
 
-	dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+	dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM |
 		NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 |
 		NETIF_F_RXCSUM | NETIF_F_LRO | NETIF_F_GRO |
 		NETIF_F_RXHASH | NETIF_F_HW_VLAN_CTAG_TX;
@@ -13192,14 +13192,14 @@ static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev,
 		dev->hw_features |= NETIF_F_GSO_GRE | NETIF_F_GSO_UDP_TUNNEL |
 				    NETIF_F_GSO_IPIP | NETIF_F_GSO_SIT;
 		dev->hw_enc_features =
-			NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SG |
+			NETIF_F_HW_CSUM | NETIF_F_SG |
 			NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 |
 			NETIF_F_GSO_IPIP |
 			NETIF_F_GSO_SIT |
 			NETIF_F_GSO_GRE | NETIF_F_GSO_UDP_TUNNEL;
 	}
 
-	dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+	dev->vlan_features = NETIF_F_SG | NETIF_F_HW_CSUM |
 		NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_HIGHDMA;
 
 	/* VF with OLD Hypervisor or old PF do not support filtering */
-- 
2.4.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 10/15] bnxt: Convert to advertise NETIF_F_HW_CSUM
  2015-11-19 19:55 [PATCH RFC 00/15] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM Tom Herbert
                   ` (8 preceding siblings ...)
  2015-11-19 19:55 ` [PATCH 09/15] bnx2x: Convert to advertise NETIF_F_HW_CSUM Tom Herbert
@ 2015-11-19 19:55 ` Tom Herbert
  2015-11-19 19:55 ` [PATCH 11/15] emulex: " Tom Herbert
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Tom Herbert @ 2015-11-19 19:55 UTC (permalink / raw)
  To: davem, netdev; +Cc: kernel-team

The skb_csum_offload_chk is used to resolve checksums that are unable
to be offloaded to the device.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index f2d0dc9..eebc9a0 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -161,6 +161,16 @@ static const u16 bnxt_lhint_arr[] = {
 	TX_BD_FLAGS_LHINT_2048_AND_LARGER,
 };
 
+static const struct skb_csum_offl_spec csum_offl_spec = {
+	.ipv4_okay = 1,
+	.ip_options_okay = 1,
+	.ipv6_okay = 1,
+	.encap_okay = 1,
+	.vlan_okay = 1,
+	.tcp_okay = 1,
+	.udp_okay = 1,
+};
+
 static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct bnxt *bp = netdev_priv(dev);
@@ -176,6 +186,7 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	struct bnxt_napi *bnapi;
 	struct bnxt_tx_ring_info *txr;
 	struct bnxt_sw_tx_bd *tx_buf;
+	bool csum_encapped;
 
 	i = skb_get_queue_mapping(skb);
 	if (unlikely(i >= bp->tx_nr_rings)) {
@@ -234,7 +245,8 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
 					TX_BD_FLAGS_PACKET_END |
 					(2 << TX_BD_FLAGS_BD_CNT_SHIFT));
 
-		if (skb->ip_summed == CHECKSUM_PARTIAL)
+		if (skb_csum_offload_chk(skb, &csum_offl_spec,
+					 &csum_encapped, true))
 			tx_push1->tx_bd_hsize_lflags =
 					cpu_to_le32(TX_BD_FLAGS_TCP_UDP_CHKSUM);
 		else
@@ -323,7 +335,8 @@ normal_tx:
 		length = skb_shinfo(skb)->gso_size;
 		txbd1->tx_bd_mss = cpu_to_le32(length);
 		length += hdr_len;
-	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+	} else if (skb_csum_offload_chk(skb, &csum_offl_spec,
+					&csum_encapped, true)) {
 		txbd1->tx_bd_hsize_lflags =
 			cpu_to_le32(TX_BD_FLAGS_TCP_UDP_CHKSUM);
 		txbd1->tx_bd_mss = 0;
@@ -5629,7 +5642,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	pci_set_drvdata(pdev, dev);
 
-	dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SG |
+	dev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG |
 			   NETIF_F_TSO | NETIF_F_TSO6 |
 			   NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_GRE |
 			   NETIF_F_GSO_IPIP | NETIF_F_GSO_SIT |
@@ -5640,7 +5653,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 		dev->hw_features |= NETIF_F_NTUPLE;
 
 	dev->hw_enc_features =
-			NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SG |
+			NETIF_F_HW_CSUM | NETIF_F_SG |
 			NETIF_F_TSO | NETIF_F_TSO6 |
 			NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_GRE |
 			NETIF_F_GSO_IPIP | NETIF_F_GSO_SIT;
-- 
2.4.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 11/15] emulex: Convert to advertise NETIF_F_HW_CSUM
  2015-11-19 19:55 [PATCH RFC 00/15] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM Tom Herbert
                   ` (9 preceding siblings ...)
  2015-11-19 19:55 ` [PATCH 10/15] bnxt: " Tom Herbert
@ 2015-11-19 19:55 ` Tom Herbert
  2015-11-19 19:55 ` [PATCH 12/15] fm10k: " Tom Herbert
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Tom Herbert @ 2015-11-19 19:55 UTC (permalink / raw)
  To: davem, netdev; +Cc: kernel-team

The skb_csum_offload_chk is used to resolve checksums that are unable
to be offloaded to the device.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 drivers/net/ethernet/emulex/benet/be.h      |  1 +
 drivers/net/ethernet/emulex/benet/be_main.c | 30 +++++++++++++++++++++--------
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index d463563..7f7344e 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -480,6 +480,7 @@ struct be_wrb_params {
 	u32 features;	/* Feature bits */
 	u16 vlan_tag;	/* VLAN tag */
 	u16 lso_mss;	/* MSS for LSO */
+	u32 encapped_csum : 1;
 };
 
 struct be_adapter {
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 34e324f..01a8642 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -678,7 +678,8 @@ void be_link_status_update(struct be_adapter *adapter, u8 link_status)
 	netdev_info(netdev, "Link is %s\n", link_status ? "Up" : "Down");
 }
 
-static void be_tx_stats_update(struct be_tx_obj *txo, struct sk_buff *skb)
+static void be_tx_stats_update(struct be_tx_obj *txo, struct sk_buff *skb,
+			       bool encapped_csum)
 {
 	struct be_tx_stats *stats = tx_stats(txo);
 	u64 tx_pkts = skb_shinfo(skb)->gso_segs ? : 1;
@@ -687,7 +688,7 @@ static void be_tx_stats_update(struct be_tx_obj *txo, struct sk_buff *skb)
 	stats->tx_reqs++;
 	stats->tx_bytes += skb->len;
 	stats->tx_pkts += tx_pkts;
-	if (skb->encapsulation && skb->ip_summed == CHECKSUM_PARTIAL)
+	if (encapped_csum)
 		stats->tx_vxlan_offload_pkts += tx_pkts;
 	u64_stats_update_end(&stats->sync);
 }
@@ -762,19 +763,32 @@ static inline bool be_is_tx_compl_pending(struct be_tx_obj *txo)
 	return atomic_read(&txo->q.used) > txo->pend_wrb_cnt;
 }
 
+static const struct skb_csum_offl_spec csum_offl_spec = {
+	.ipv4_okay = 1,
+	.ip_options_okay = 1,
+	.ipv6_okay = 1,
+	.encap_okay = 1,
+	.vlan_okay = 1,
+	.tcp_okay = 1,
+	.udp_okay = 1,
+};
+
 static void be_get_wrb_params_from_skb(struct be_adapter *adapter,
 				       struct sk_buff *skb,
 				       struct be_wrb_params *wrb_params)
 {
 	u16 proto;
+	bool csum_encapped;
 
 	if (skb_is_gso(skb)) {
 		BE_WRB_F_SET(wrb_params->features, LSO, 1);
 		wrb_params->lso_mss = skb_shinfo(skb)->gso_size;
 		if (skb_is_gso_v6(skb) && !lancer_chip(adapter))
 			BE_WRB_F_SET(wrb_params->features, LSO6, 1);
-	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
-		if (skb->encapsulation) {
+	} else if (skb_csum_offload_chk(skb, &csum_offl_spec,
+					&csum_encapped, true)) {
+		wrb_params->encapped_csum = csum_encapped;
+		if (csum_encapped) {
 			BE_WRB_F_SET(wrb_params->features, IPCS, 1);
 			proto = skb_inner_ip_proto(skb);
 		} else {
@@ -960,7 +974,7 @@ static u32 be_xmit_enqueue(struct be_adapter *adapter, struct be_tx_obj *txo,
 
 	be_tx_setup_wrb_hdr(adapter, txo, wrb_params, skb, head);
 
-	be_tx_stats_update(txo, skb);
+	be_tx_stats_update(txo, skb, !!wrb_params->encapped_csum);
 	return wrb_cnt;
 
 dma_err:
@@ -5215,7 +5229,7 @@ static void be_add_vxlan_port(struct net_device *netdev, sa_family_t sa_family,
 	adapter->flags |= BE_FLAGS_VXLAN_OFFLOADS;
 	adapter->vxlan_port = port;
 
-	netdev->hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+	netdev->hw_enc_features |= NETIF_F_HW_CSUM |
 				   NETIF_F_TSO | NETIF_F_TSO6 |
 				   NETIF_F_GSO_UDP_TUNNEL;
 	netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL;
@@ -5354,7 +5368,7 @@ static void be_netdev_init(struct net_device *netdev)
 	struct be_adapter *adapter = netdev_priv(netdev);
 
 	netdev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
-		NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM |
+		NETIF_F_HW_CSUM | NETIF_F_RXCSUM |
 		NETIF_F_HW_VLAN_CTAG_TX;
 	if (be_multi_rxq(adapter))
 		netdev->hw_features |= NETIF_F_RXHASH;
@@ -5363,7 +5377,7 @@ static void be_netdev_init(struct net_device *netdev)
 		NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_FILTER;
 
 	netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
-		NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+		NETIF_F_HW_CSUM;
 
 	netdev->priv_flags |= IFF_UNICAST_FLT;
 
-- 
2.4.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 12/15] fm10k: Convert to advertise NETIF_F_HW_CSUM
  2015-11-19 19:55 [PATCH RFC 00/15] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM Tom Herbert
                   ` (10 preceding siblings ...)
  2015-11-19 19:55 ` [PATCH 11/15] emulex: " Tom Herbert
@ 2015-11-19 19:55 ` Tom Herbert
  2015-11-19 19:55 ` [PATCH 13/15] ixgbe: " Tom Herbert
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Tom Herbert @ 2015-11-19 19:55 UTC (permalink / raw)
  To: davem, netdev; +Cc: kernel-team

The skb_csum_offload_chk is used to resolve checksums that are unable
to be offloaded to the device.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 drivers/net/ethernet/intel/fm10k/fm10k_main.c   | 16 ++++++++++++++--
 drivers/net/ethernet/intel/fm10k/fm10k_netdev.c |  5 ++---
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_main.c b/drivers/net/ethernet/intel/fm10k/fm10k_main.c
index e76a44c..3c78ea6 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_main.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_main.c
@@ -827,6 +827,17 @@ err_vxlan:
 	return -1;
 }
 
+static const struct skb_csum_offl_spec csum_offl_spec = {
+	.ipv4_okay = 1,
+	.ip_options_okay = 1,
+	.ipv6_okay = 1,
+	.encap_okay = 1,
+	.no_encapped_ipv6 = 1,
+	.vlan_okay = 1,
+	.tcp_okay = 1,
+	.udp_okay = 1,
+};
+
 static void fm10k_tx_csum(struct fm10k_ring *tx_ring,
 			  struct fm10k_tx_buffer *first)
 {
@@ -839,11 +850,12 @@ static void fm10k_tx_csum(struct fm10k_ring *tx_ring,
 	} network_hdr;
 	__be16 protocol;
 	u8 l4_hdr = 0;
+	bool csum_encapped;
 
-	if (skb->ip_summed != CHECKSUM_PARTIAL)
+	if (!skb_csum_offload_chk(skb, &csum_offl_spec, &csum_encapped, true))
 		goto no_csum;
 
-	if (skb->encapsulation) {
+	if (csum_encapped) {
 		protocol = fm10k_tx_encap_offload(skb);
 		if (!protocol) {
 			if (skb_checksum_help(skb)) {
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
index a340772..b467e2b 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
@@ -1404,8 +1404,7 @@ struct net_device *fm10k_alloc_netdev(void)
 	interface->msg_enable = (1 << DEFAULT_DEBUG_LEVEL_SHIFT) - 1;
 
 	/* configure default features */
-	dev->features |= NETIF_F_IP_CSUM |
-			 NETIF_F_IPV6_CSUM |
+	dev->features |= NETIF_F_HW_CSUM |
 			 NETIF_F_SG |
 			 NETIF_F_TSO |
 			 NETIF_F_TSO6 |
@@ -1424,7 +1423,7 @@ struct net_device *fm10k_alloc_netdev(void)
 	dev->vlan_features |= dev->features;
 
 	/* configure tunnel offloads */
-	dev->hw_enc_features |= NETIF_F_IP_CSUM |
+	dev->hw_enc_features |= NETIF_F_HW_CSUM |
 				NETIF_F_TSO |
 				NETIF_F_TSO6 |
 				NETIF_F_TSO_ECN |
-- 
2.4.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 13/15] ixgbe: Convert to advertise NETIF_F_HW_CSUM
  2015-11-19 19:55 [PATCH RFC 00/15] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM Tom Herbert
                   ` (11 preceding siblings ...)
  2015-11-19 19:55 ` [PATCH 12/15] fm10k: " Tom Herbert
@ 2015-11-19 19:55 ` Tom Herbert
  2015-11-20 23:56   ` Rustad, Mark D
  2015-11-19 19:56 ` [PATCH 14/15] mlx4: " Tom Herbert
                   ` (2 subsequent siblings)
  15 siblings, 1 reply; 19+ messages in thread
From: Tom Herbert @ 2015-11-19 19:55 UTC (permalink / raw)
  To: davem, netdev; +Cc: kernel-team

The skb_csum_offload_chk is used to resolve checksums that are unable
to be offloaded to the device.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 41 +++++++++++++++++++--------
 1 file changed, 29 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 80823f5..26c1633 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -6999,15 +6999,28 @@ static int ixgbe_tso(struct ixgbe_ring *tx_ring,
 	return 1;
 }
 
+static const struct skb_csum_offl_spec csum_offl_spec = {
+	.ipv4_okay = 1,
+	.ip_options_okay = 1,
+	.ipv6_okay = 1,
+	.encap_okay = 1,
+	.vlan_okay = 1,
+	.tcp_okay = 1,
+	.udp_okay = 1,
+};
+
 static void ixgbe_tx_csum(struct ixgbe_ring *tx_ring,
-			  struct ixgbe_tx_buffer *first)
+			  struct ixgbe_tx_buffer *first,
+			  struct ixgbe_adapter *adapter)
 {
 	struct sk_buff *skb = first->skb;
 	u32 vlan_macip_lens = 0;
 	u32 mss_l4len_idx = 0;
 	u32 type_tucmd = 0;
+	bool csum_encapped;
 
-	if (skb->ip_summed != CHECKSUM_PARTIAL) {
+	if (!skb_csum_offload_chk(skb, &csum_offl_spec, &csum_encapped, true)) {
+no_csum:
 		if (!(first->tx_flags & IXGBE_TX_FLAGS_HW_VLAN) &&
 		    !(first->tx_flags & IXGBE_TX_FLAGS_CC))
 			return;
@@ -7025,7 +7038,15 @@ static void ixgbe_tx_csum(struct ixgbe_ring *tx_ring,
 			u8 *raw;
 		} transport_hdr;
 
-		if (skb->encapsulation) {
+		if (csum_encapped) {
+			switch (adapter->hw.mac.type) {
+			case ixgbe_mac_X550:
+			case ixgbe_mac_X550EM_x:
+				break;
+			default:
+				skb_checksum_help(skb);
+				goto no_csum;
+			}
 			network_hdr.raw = skb_inner_network_header(skb);
 			transport_hdr.raw = skb_inner_transport_header(skb);
 			vlan_macip_lens = skb_inner_network_offset(skb) <<
@@ -7602,7 +7623,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
 	if (tso < 0)
 		goto out_drop;
 	else if (!tso)
-		ixgbe_tx_csum(tx_ring, first);
+		ixgbe_tx_csum(tx_ring, first, adapter);
 
 	/* add the ATR filter if ATR is on */
 	if (test_bit(__IXGBE_TX_FDIR_INIT_DONE, &tx_ring->state))
@@ -8765,8 +8786,7 @@ skip_sriov:
 
 #endif
 	netdev->features = NETIF_F_SG |
-			   NETIF_F_IP_CSUM |
-			   NETIF_F_IPV6_CSUM |
+			   NETIF_F_HW_CSUM |
 			   NETIF_F_HW_VLAN_CTAG_TX |
 			   NETIF_F_HW_VLAN_CTAG_RX |
 			   NETIF_F_TSO |
@@ -8794,12 +8814,10 @@ skip_sriov:
 
 	netdev->vlan_features |= NETIF_F_TSO;
 	netdev->vlan_features |= NETIF_F_TSO6;
-	netdev->vlan_features |= NETIF_F_IP_CSUM;
-	netdev->vlan_features |= NETIF_F_IPV6_CSUM;
+	netdev->vlan_features |= NETIF_F_HW_CSUM;
 	netdev->vlan_features |= NETIF_F_SG;
 
-	netdev->hw_enc_features |= NETIF_F_SG | NETIF_F_IP_CSUM |
-				   NETIF_F_IPV6_CSUM;
+	netdev->hw_enc_features |= NETIF_F_SG | NETIF_F_HW_CSUM;
 
 	netdev->priv_flags |= IFF_UNICAST_FLT;
 	netdev->priv_flags |= IFF_SUPP_NOFCS;
@@ -8809,8 +8827,7 @@ skip_sriov:
 	case ixgbe_mac_X550:
 	case ixgbe_mac_X550EM_x:
 		netdev->hw_enc_features |= NETIF_F_RXCSUM |
-					   NETIF_F_IP_CSUM |
-					   NETIF_F_IPV6_CSUM;
+					   NETIF_F_HW_CSUM;
 		break;
 	default:
 		break;
-- 
2.4.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 14/15] mlx4: Convert to advertise NETIF_F_HW_CSUM
  2015-11-19 19:55 [PATCH RFC 00/15] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM Tom Herbert
                   ` (12 preceding siblings ...)
  2015-11-19 19:55 ` [PATCH 13/15] ixgbe: " Tom Herbert
@ 2015-11-19 19:56 ` Tom Herbert
  2015-11-19 19:56 ` [PATCH 15/15] qlogic: " Tom Herbert
  2015-11-20 21:42 ` [PATCH RFC 00/15] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM David Miller
  15 siblings, 0 replies; 19+ messages in thread
From: Tom Herbert @ 2015-11-19 19:56 UTC (permalink / raw)
  To: davem, netdev; +Cc: kernel-team

The skb_csum_offload_chk is used to resolve checksums that are unable
to be offloaded to the device.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 drivers/net/ethernet/mellanox/mlx4/en_netdev.c |  6 +++---
 drivers/net/ethernet/mellanox/mlx4/en_tx.c     | 16 ++++++++++++++--
 2 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 659209f..7bc2b90 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -2339,7 +2339,7 @@ out:
 	}
 
 	/* set offloads */
-	priv->dev->hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
+	priv->dev->hw_enc_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM |
 				      NETIF_F_TSO | NETIF_F_GSO_UDP_TUNNEL;
 	priv->dev->hw_features |= NETIF_F_GSO_UDP_TUNNEL;
 	priv->dev->features    |= NETIF_F_GSO_UDP_TUNNEL;
@@ -2351,7 +2351,7 @@ static void mlx4_en_del_vxlan_offloads(struct work_struct *work)
 	struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv,
 						 vxlan_del_task);
 	/* unset offloads */
-	priv->dev->hw_enc_features &= ~(NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
+	priv->dev->hw_enc_features &= ~(NETIF_F_HW_CSUM | NETIF_F_RXCSUM |
 				      NETIF_F_TSO | NETIF_F_GSO_UDP_TUNNEL);
 	priv->dev->hw_features &= ~NETIF_F_GSO_UDP_TUNNEL;
 	priv->dev->features    &= ~NETIF_F_GSO_UDP_TUNNEL;
@@ -2918,7 +2918,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
 	/*
 	 * Set driver features
 	 */
-	dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+	dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM;
 	if (mdev->LSO_support)
 		dev->hw_features |= NETIF_F_TSO | NETIF_F_TSO6;
 
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
index 4421bf5..34929d5 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
@@ -702,6 +702,17 @@ static void mlx4_bf_copy(void __iomem *dst, const void *src,
 	__iowrite64_copy(dst, src, bytecnt / 8);
 }
 
+static const struct skb_csum_offl_spec csum_offl_spec = {
+	.ipv4_okay = 1,
+	.ip_options_okay = 1,
+	.ipv6_okay = 1,
+	.encap_okay = 1,
+	.no_encapped_ipv6 = 1,
+	.vlan_okay = 1,
+	.tcp_okay = 1,
+	.udp_okay = 1,
+};
+
 netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct skb_shared_info *shinfo = skb_shinfo(skb);
@@ -727,6 +738,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
 	bool stop_queue;
 	bool inline_ok;
 	u32 ring_cons;
+	bool csum_encapped;
 
 	if (!priv->port_up)
 		goto tx_drop;
@@ -853,8 +865,8 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
 	/* Prepare ctrl segement apart opcode+ownership, which depends on
 	 * whether LSO is used */
 	tx_desc->ctrl.srcrb_flags = priv->ctrl_flags;
-	if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
-		if (!skb->encapsulation)
+	if (skb_csum_offload_chk(skb, &csum_offl_spec, &csum_encapped, true)) {
+		if (!csum_encapped)
 			tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM |
 								 MLX4_WQE_CTRL_TCP_UDP_CSUM);
 		else
-- 
2.4.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 15/15] qlogic: Convert to advertise NETIF_F_HW_CSUM
  2015-11-19 19:55 [PATCH RFC 00/15] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM Tom Herbert
                   ` (13 preceding siblings ...)
  2015-11-19 19:56 ` [PATCH 14/15] mlx4: " Tom Herbert
@ 2015-11-19 19:56 ` Tom Herbert
  2015-11-20 21:42 ` [PATCH RFC 00/15] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM David Miller
  15 siblings, 0 replies; 19+ messages in thread
From: Tom Herbert @ 2015-11-19 19:56 UTC (permalink / raw)
  To: davem, netdev; +Cc: kernel-team

The skb_csum_offload_chk is used to resolve checksums that are unable
to be offloaded to the device.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c   | 10 +++-------
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c   | 16 ++++++++++++++--
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 10 ++++------
 3 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
index 509b596..380b621 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
@@ -1044,8 +1044,7 @@ static netdev_features_t qlcnic_process_flags(struct qlcnic_adapter *adapter,
 	u32 offload_flags = adapter->offload_flags;
 
 	if (offload_flags & BIT_0) {
-		features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
-			    NETIF_F_IPV6_CSUM;
+		features |= NETIF_F_RXCSUM | NETIF_F_HW_CSUM;
 		adapter->rx_csum = 1;
 		if (QLCNIC_IS_TSO_CAPABLE(adapter)) {
 			if (!(offload_flags & BIT_1))
@@ -1059,9 +1058,7 @@ static netdev_features_t qlcnic_process_flags(struct qlcnic_adapter *adapter,
 				features |= NETIF_F_TSO6;
 		}
 	} else {
-		features &= ~(NETIF_F_RXCSUM |
-			      NETIF_F_IP_CSUM |
-			      NETIF_F_IPV6_CSUM);
+		features &= ~(NETIF_F_RXCSUM | NETIF_F_HW_CSUM);
 
 		if (QLCNIC_IS_TSO_CAPABLE(adapter))
 			features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
@@ -1084,8 +1081,7 @@ netdev_features_t qlcnic_fix_features(struct net_device *netdev,
 		} else {
 			changed = features ^ netdev->features;
 			features ^= changed & (NETIF_F_RXCSUM |
-					       NETIF_F_IP_CSUM |
-					       NETIF_F_IPV6_CSUM |
+					       NETIF_F_HW_CSUM |
 					       NETIF_F_TSO |
 					       NETIF_F_TSO6);
 		}
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
index 7bd6f25..1165ac2 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
@@ -368,6 +368,16 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter,
 #define QLCNIC_ENCAP_DO_L3_CSUM		BIT_4
 #define QLCNIC_ENCAP_DO_L4_CSUM		BIT_5
 
+static const struct skb_csum_offl_spec csum_offl_encap_spec = {
+	.ipv4_okay = 1,
+	.ip_options_okay = 1,
+	.vlan_okay = 1,
+	.tcp_okay = 1,
+	.udp_okay = 1,
+	.encap_okay = 1,
+	.no_not_encapped = 1,
+};
+
 static int qlcnic_tx_encap_pkt(struct qlcnic_adapter *adapter,
 			       struct cmd_desc_type0 *first_desc,
 			       struct sk_buff *skb,
@@ -378,6 +388,7 @@ static int qlcnic_tx_encap_pkt(struct qlcnic_adapter *adapter,
 	u32 producer = tx_ring->producer;
 	struct cmd_desc_type0 *hwdesc;
 	u16 flags = 0, encap_descr = 0;
+	bool csum_encapped;
 
 	opcode = QLCNIC_TX_ETHER_PKT;
 	encap_descr = QLCNIC_ENCAP_VXLAN_PKT;
@@ -423,7 +434,8 @@ static int qlcnic_tx_encap_pkt(struct qlcnic_adapter *adapter,
 		adapter->stats.encap_lso_frames++;
 
 		opcode = QLCNIC_TX_ENCAP_LSO;
-	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+	} else if (skb_csum_offload_chk(skb, &csum_offl_encap_spec,
+					&csum_encapped, true)) {
 		if (inner_ip_hdr(skb)->version == 6) {
 			if (inner_ipv6_hdr(skb)->nexthdr == IPPROTO_UDP)
 				encap_descr |= QLCNIC_ENCAP_INNER_L4_UDP;
@@ -552,7 +564,7 @@ set_flags:
 		smp_mb();
 		adapter->stats.lso_frames++;
 
-	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+	} else if (skb_csum_off_chk_help_cmn(skb)) {
 		if (protocol == ETH_P_IP) {
 			l4proto = ip_hdr(skb)->protocol;
 
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 1205f6f..301ee8f 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -2301,11 +2301,9 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev,
 	netdev->ethtool_ops = (qlcnic_sriov_vf_check(adapter)) ?
 		&qlcnic_sriov_vf_ethtool_ops : &qlcnic_ethtool_ops;
 
-	netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
-			     NETIF_F_IPV6_CSUM | NETIF_F_GRO |
-			     NETIF_F_HW_VLAN_CTAG_RX);
-	netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM |
-				  NETIF_F_IPV6_CSUM);
+	netdev->features |= (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_RXCSUM |
+			     NETIF_F_GRO | NETIF_F_HW_VLAN_CTAG_RX);
+	netdev->vlan_features |= (NETIF_F_SG | NETIF_F_HW_CSUM);
 
 	if (QLCNIC_IS_TSO_CAPABLE(adapter)) {
 		netdev->features |= (NETIF_F_TSO | NETIF_F_TSO6);
@@ -2330,7 +2328,7 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev,
 		netdev->features |= NETIF_F_GSO_UDP_TUNNEL;
 
 		/* encapsulation Tx offload supported by Adapter */
-		netdev->hw_enc_features = NETIF_F_IP_CSUM        |
+		netdev->hw_enc_features = NETIF_F_HW_CSUM        |
 					  NETIF_F_GSO_UDP_TUNNEL |
 					  NETIF_F_TSO            |
 					  NETIF_F_TSO6;
-- 
2.4.6

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH RFC 00/15] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM
  2015-11-19 19:55 [PATCH RFC 00/15] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM Tom Herbert
                   ` (14 preceding siblings ...)
  2015-11-19 19:56 ` [PATCH 15/15] qlogic: " Tom Herbert
@ 2015-11-20 21:42 ` David Miller
  15 siblings, 0 replies; 19+ messages in thread
From: David Miller @ 2015-11-20 21:42 UTC (permalink / raw)
  To: tom; +Cc: netdev, kernel-team

From: Tom Herbert <tom@herbertland.com>
Date: Thu, 19 Nov 2015 11:55:46 -0800

> Goals of this patch set:
> 
> We propose that drivers advertise NETIF_F_HW_CSUM instead of protocol
> specific values of NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM.  If the
> driver's device is constrained (for instance it can only offlaod simple
> IPv4 and IPv6 packets) then these constraints can be checked in the
> transmit path and skb_checksum_help would be called for packets that the
> driver is unable to offload. In order to facilitate this, we add some
> helper functions that takes a specification argument indicating the
> type of packets a device is able to offload. If a packet does not match
> the specification, the helper function calls skb_checksum_help.

I very much like the direction this is taking things.  And I do sincerely
hope that this does in fact actually encourage HW vendors to drop all of
the protocol specific offloading, and just support 2's complement sums.

They can turn that _trivially_ into whatever the Windows et al. driver
interfaces want in their respective drivers.

There is absolutely no reason to implement protocol specific checksum
offloads in silicon in this day and age.

Absolutely none.

So driver folks tell your hardware buddies to just stop doing it now
and get with the program.  Even your marketing department shouldn't
care, they can list support for every protocol on the planet in their
specs and packaging if they want, and it might even look impressive...

Thanks.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 13/15] ixgbe: Convert to advertise NETIF_F_HW_CSUM
  2015-11-19 19:55 ` [PATCH 13/15] ixgbe: " Tom Herbert
@ 2015-11-20 23:56   ` Rustad, Mark D
  0 siblings, 0 replies; 19+ messages in thread
From: Rustad, Mark D @ 2015-11-20 23:56 UTC (permalink / raw)
  To: Tom Herbert; +Cc: davem, netdev, kernel-team

[-- Attachment #1: Type: text/plain, Size: 3595 bytes --]

Tom Herbert <tom@herbertland.com> wrote:

> The skb_csum_offload_chk is used to resolve checksums that are unable
> to be offloaded to the device.
> 
> Signed-off-by: Tom Herbert <tom@herbertland.com>
> ---
> drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 41 +++++++++++++++++++--------
> 1 file changed, 29 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> index 80823f5..26c1633 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c

<snip>

> static void ixgbe_tx_csum(struct ixgbe_ring *tx_ring,
> -			  struct ixgbe_tx_buffer *first)
> +			  struct ixgbe_tx_buffer *first,
> +			  struct ixgbe_adapter *adapter)

This added parameter should not be needed. See below.

> {
> 	struct sk_buff *skb = first->skb;
> 	u32 vlan_macip_lens = 0;
> 	u32 mss_l4len_idx = 0;
> 	u32 type_tucmd = 0;
> +	bool csum_encapped;
> 
> -	if (skb->ip_summed != CHECKSUM_PARTIAL) {
> +	if (!skb_csum_offload_chk(skb, &csum_offl_spec, &csum_encapped, true)) {
> +no_csum:
> 		if (!(first->tx_flags & IXGBE_TX_FLAGS_HW_VLAN) &&
> 		    !(first->tx_flags & IXGBE_TX_FLAGS_CC))
> 			return;
> @@ -7025,7 +7038,15 @@ static void ixgbe_tx_csum(struct ixgbe_ring *tx_ring,
> 			u8 *raw;
> 		} transport_hdr;
> 
> -		if (skb->encapsulation) {
> +		if (csum_encapped) {
> +			switch (adapter->hw.mac.type) {
> +			case ixgbe_mac_X550:
> +			case ixgbe_mac_X550EM_x:
> +				break;
> +			default:
> +				skb_checksum_help(skb);
> +				goto no_csum;
> +			}
> 			network_hdr.raw = skb_inner_network_header(skb);
> 			transport_hdr.raw = skb_inner_transport_header(skb);
> 			vlan_macip_lens = skb_inner_network_offset(skb) <<

The switch checking the mac type above is not needed. All of the ixgbe devices can handle encapsulated tx checksum offload. The X550 series
has the ability to offload the rx side as well, but is not a factor
here. That also means that the added adapter parameter would not be
needed.

> @@ -7602,7 +7623,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
> 	if (tso < 0)
> 		goto out_drop;
> 	else if (!tso)
> -		ixgbe_tx_csum(tx_ring, first);
> +		ixgbe_tx_csum(tx_ring, first, adapter);
> 
> 	/* add the ATR filter if ATR is on */
> 	if (test_bit(__IXGBE_TX_FDIR_INIT_DONE, &tx_ring->state))

<snip>

> @@ -8794,12 +8814,10 @@ skip_sriov:
> 
> 	netdev->vlan_features |= NETIF_F_TSO;
> 	netdev->vlan_features |= NETIF_F_TSO6;
> -	netdev->vlan_features |= NETIF_F_IP_CSUM;
> -	netdev->vlan_features |= NETIF_F_IPV6_CSUM;
> +	netdev->vlan_features |= NETIF_F_HW_CSUM;
> 	netdev->vlan_features |= NETIF_F_SG;
> 
> -	netdev->hw_enc_features |= NETIF_F_SG | NETIF_F_IP_CSUM |
> -				   NETIF_F_IPV6_CSUM;
> +	netdev->hw_enc_features |= NETIF_F_SG | NETIF_F_HW_CSUM;
> 
> 	netdev->priv_flags |= IFF_UNICAST_FLT;
> 	netdev->priv_flags |= IFF_SUPP_NOFCS;
> @@ -8809,8 +8827,7 @@ skip_sriov:
> 	case ixgbe_mac_X550:
> 	case ixgbe_mac_X550EM_x:
> 		netdev->hw_enc_features |= NETIF_F_RXCSUM |
> -					   NETIF_F_IP_CSUM |
> -					   NETIF_F_IPV6_CSUM;
> +					   NETIF_F_HW_CSUM;

This is actually redundant, because the bit in hw_enc_features was set above. I already have a patch in queue that changes the statement above to only set the NETIF_F_RXCSUM for the X550 devices because the other bits were set just above. So once my patch is applied, this last hunk won't be needed here.

--
Mark Rustad, Networking Division, Intel Corporation

[-- Attachment #2: Message signed with OpenPGP using GPGMail --]
[-- Type: application/pgp-signature, Size: 841 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: [PATCH 07/15] net: Add driver helper functions to determine checksum offloadability
  2015-11-19 19:55 ` [PATCH 07/15] net: Add driver helper functions to determine checksum offloadability Tom Herbert
@ 2015-11-22 10:14   ` Yuval Mintz
  0 siblings, 0 replies; 19+ messages in thread
From: Yuval Mintz @ 2015-11-22 10:14 UTC (permalink / raw)
  To: Tom Herbert, David Miller, netdev; +Cc: kernel-team

> +struct skb_csum_offl_spec {
...
> +			no_encapped_ipv6:1,
...
> +};

I don't think it's actually checked by this patch.

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2015-11-22 10:30 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-19 19:55 [PATCH RFC 00/15] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM Tom Herbert
2015-11-19 19:55 ` [PATCH 01/15] net: Add skb_inner_transport_offset function Tom Herbert
2015-11-19 19:55 ` [PATCH 02/15] sctp: Rename NETIF_F_SCTP_CSUM to NETIF_F_SCTP_CRC Tom Herbert
2015-11-19 19:55 ` [PATCH 03/15] fcoe: Use CHECKSUM_PARTIAL to indicate CRC offload Tom Herbert
2015-11-19 19:55 ` [PATCH 04/15] net: Rename NETIF_F_ALL_CSUM to NETIF_F_CSUM_MASK Tom Herbert
2015-11-19 19:55 ` [PATCH 05/15] net: Eliminate NETIF_F_GEN_CSUM and NETIF_F_V[46]_CSUM Tom Herbert
2015-11-19 19:55 ` [PATCH 06/15] tcp: Fix conditions to determine checksum offload Tom Herbert
2015-11-19 19:55 ` [PATCH 07/15] net: Add driver helper functions to determine checksum offloadability Tom Herbert
2015-11-22 10:14   ` Yuval Mintz
2015-11-19 19:55 ` [PATCH 08/15] net: Elaborate on checksum offload interface description Tom Herbert
2015-11-19 19:55 ` [PATCH 09/15] bnx2x: Convert to advertise NETIF_F_HW_CSUM Tom Herbert
2015-11-19 19:55 ` [PATCH 10/15] bnxt: " Tom Herbert
2015-11-19 19:55 ` [PATCH 11/15] emulex: " Tom Herbert
2015-11-19 19:55 ` [PATCH 12/15] fm10k: " Tom Herbert
2015-11-19 19:55 ` [PATCH 13/15] ixgbe: " Tom Herbert
2015-11-20 23:56   ` Rustad, Mark D
2015-11-19 19:56 ` [PATCH 14/15] mlx4: " Tom Herbert
2015-11-19 19:56 ` [PATCH 15/15] qlogic: " Tom Herbert
2015-11-20 21:42 ` [PATCH RFC 00/15] net: The beginning of the end for NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.