Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH v2] net: smc911x: convert pxa dma to dmaengine
From: David Miller @ 2016-03-19  2:25 UTC (permalink / raw)
  To: robert.jarzmik; +Cc: netdev, linux-kernel, fabio.estevam
In-Reply-To: <1458149162-11469-1-git-send-email-robert.jarzmik@free.fr>

From: Robert Jarzmik <robert.jarzmik@free.fr>
Date: Wed, 16 Mar 2016 18:26:02 +0100

> Convert the dma transfers to be dmaengine based, now pxa has a dmaengine
> slave driver. This makes this driver a bit more PXA agnostic.
> 
> The driver was only compile tested. The risk is quite small as no
> current PXA platform I'm aware of is using smc911x driver.
> 
> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
> Tested-by: Fabio Estevam <fabio.estevam@nxp.com>
> ---
> Since v1: added Fabio's Tested-by

Applied, thanks.

^ permalink raw reply

* Re: [PATCH] net: removes duplicate skb_mark_napi_id() calls.
From: David Miller @ 2016-03-19  2:21 UTC (permalink / raw)
  To: weongyo.linux; +Cc: netdev
In-Reply-To: <20160316170450.GA30365@jwg>

From: Weongyo Jeong <weongyo.linux@gmail.com>
Date: Wed, 16 Mar 2016 10:04:53 -0700

> Because napi_gro_receive() function calls skb_mark_napi_id() function,
> it doesn't need to set it twice.
> 
> Signed-off-by: Weongyo Jeong <weongyo.linux@gmail.com>

Unless you can show a significant performance argument, or other
significant improvement resulting from this patch, I am not applying
it.

^ permalink raw reply

* Re: [PATCH net-next] vxlan: fix too large pskb_may_pull with remote checksum
From: David Miller @ 2016-03-19  2:19 UTC (permalink / raw)
  To: jbenc; +Cc: netdev, tom
In-Reply-To: <fcf7ae744d2ab9fa8e560c37f50fc3f80ff20aa8.1458146074.git.jbenc@redhat.com>

From: Jiri Benc <jbenc@redhat.com>
Date: Wed, 16 Mar 2016 17:35:47 +0100

> The vxlan header is pulled at this point, don't include it again in the
> calculation.
> 
> Signed-off-by: Jiri Benc <jbenc@redhat.com>

Please update the commit log message to explain where that pull
happens.

Thanks.

^ permalink raw reply

* Re: [net-next 0/2] remove duplicate set of flag IFF_MULTICAST
From: David Miller @ 2016-03-19  2:15 UTC (permalink / raw)
  To: zhangshengju; +Cc: j.vosburgh, jiri, netdev
In-Reply-To: <1458122356-25021-1-git-send-email-zhangshengju@cmss.chinamobile.com>

From: Zhang Shengju <zhangshengju@cmss.chinamobile.com>
Date: Wed, 16 Mar 2016 09:59:14 +0000

> This patch series remove duplicate set of flag IFF_MULTICAST.

Series applied, thanks.

^ permalink raw reply

* Re: [RFC net-next 0/2] Create ancient subdirectories for old hardware
From: David Miller @ 2016-03-19  2:11 UTC (permalink / raw)
  To: joe; +Cc: netdev, linux-kernel
In-Reply-To: <cover.1458347329.git.joe@perches.com>

From: Joe Perches <joe@perches.com>
Date: Fri, 18 Mar 2016 17:33:29 -0700

> Maybe something like this:
> 
> Old, rare, and unsupported hardware should be exposed as ancient.
> 
> The drivers for these ancient hardwares are generally untested with
> current kernels.

Moving drivers has a long term maintainence cost.

If they've moved into drivers/net proper, we have to maintain
them there forever.

^ permalink raw reply

* Re: [RFC PATCH 9/9] ixgbe/ixgbevf: Add support for GSO partial
From: Jesse Gross @ 2016-03-19  2:05 UTC (permalink / raw)
  To: Alexander Duyck
  Cc: Edward Cree, Linux Kernel Network Developers, David Miller,
	Alexander Duyck, Tom Herbert
In-Reply-To: <20160318232535.14955.19028.stgit@localhost.localdomain>

On Fri, Mar 18, 2016 at 4:25 PM, Alexander Duyck <aduyck@mirantis.com> wrote:
> This patch adds support for partial GSO segmentation in the case of GRE or
> UDP encapsulated frames.
>
> The one bit in this patch that is a bit controversial is the fact that we
> are leaving the inner IPv4 IP ID as a static value in the case of
> segmentation.  As per RFC6864 this should be acceptable as TCP frames set
> the DF bit so the IP ID should be ignored.  However this is not always the
> case as header compression schemes for PPP and SLIP can end up taking a
> performance hit as they have to record the fact that the ID didn't change
> as expected.
>
> In addition GRO was examining the IP ID field as well.  As such on older
> GRO implementations TSO frames from this driver may end up blocking GRO on
> the other end which will likely hurt performance instead of helping it.
>
> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>

I wasn't able to apply this patch, it seems like it might be based on
some Intel driver patches that haven't been merged into net-next yet?

^ permalink raw reply

* Re: [RFC PATCH 6/9] ethtool: Add support for toggling any of the GSO offloads
From: Jesse Gross @ 2016-03-19  2:01 UTC (permalink / raw)
  To: Ben Hutchings
  Cc: Alexander Duyck, Alexander Duyck, Edward Cree, Netdev,
	David Miller, Tom Herbert
In-Reply-To: <1458351771.2953.22.camel@decadent.org.uk>

On Fri, Mar 18, 2016 at 6:42 PM, Ben Hutchings <ben@decadent.org.uk> wrote:
> On Fri, 2016-03-18 at 17:30 -0700, Alexander Duyck wrote:
>> On Fri, Mar 18, 2016 at 5:18 PM, Ben Hutchings <ben@decadent.org.uk> wrote:
>> > On Fri, 2016-03-18 at 16:25 -0700, Alexander Duyck wrote:
>> > >       [NETIF_F_GSO_IPIP_BIT] =         "tx-ipip-segmentation",
>> > >       [NETIF_F_GSO_SIT_BIT] =          "tx-sit-segmentation",
>> > >       [NETIF_F_GSO_UDP_TUNNEL_BIT] =   "tx-udp_tnl-segmentation",
>> > > +     [NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT] = "tx-udp_tnl-csum-segmentation",
>> > > +     [NETIF_F_GSO_TUNNEL_REMCSUM_BIT] = "tx-remcsum-segmentation",
>> > I think this should be "tx-tunnel-remote-checksum-segmentation", though
>> > that is getting quite unwieldy.
>> Right.  As it is I think we might be coming up on the 32 character
>> limit for the strings.  Replacing csum with checksum would probably
>> push us over.
>
> Right, I wasn't even thinking about the static limit!  That does weigh
> rather heavily in favour of abbreviation here.
>
> Please do at least hyphenate "remcsum" though.

I think that remote checksum offload is just a purely internal feature
- that is no device will ever expose support for it, since it is
explicitly to work around lack of hardware support. As a result, I
don't know if it makes sense to show it through ethtool at all.

^ permalink raw reply

* Re: [RFC PATCH 6/9] ethtool: Add support for toggling any of the GSO offloads
From: Ben Hutchings @ 2016-03-19  1:42 UTC (permalink / raw)
  To: Alexander Duyck
  Cc: Alexander Duyck, Edward Cree, Netdev, David Miller, Tom Herbert
In-Reply-To: <CAKgT0UfTVCfTFgVTtA2sq1fZKVatAk=ciFG-dBtfU-oZmsAyiQ@mail.gmail.com>

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

On Fri, 2016-03-18 at 17:30 -0700, Alexander Duyck wrote:
> On Fri, Mar 18, 2016 at 5:18 PM, Ben Hutchings <ben@decadent.org.uk> wrote:
> > 
> > On Fri, 2016-03-18 at 16:25 -0700, Alexander Duyck wrote:
> > 
> > > 
> > > The strings were missing for several of the GSO offloads that are
> > > available.  This patch provides the missing strings so that we can toggle
> > > or query any of them via the ethtool command.
> > > 
> > > Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
> > > ---
> > >  net/core/ethtool.c |    3 +++
> > >  1 file changed, 3 insertions(+)
> > > 
> > > diff --git a/net/core/ethtool.c b/net/core/ethtool.c
> > > index 2966cd0d7c93..b3c39d531469 100644
> > > --- a/net/core/ethtool.c
> > > +++ b/net/core/ethtool.c
> > > @@ -82,9 +82,12 @@ static const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN]
> > >       [NETIF_F_TSO6_BIT] =             "tx-tcp6-segmentation",
> > >       [NETIF_F_FSO_BIT] =              "tx-fcoe-segmentation",
> > >       [NETIF_F_GSO_GRE_BIT] =          "tx-gre-segmentation",
> > > +     [NETIF_F_GSO_GRE_CSUM_BIT] =     "tx-gre-csum-segmentation",
> > All of the existing checksum offload names include the word "checksum"
> > in full, so I think the new names should do the same.
> It isn't a checksum offload though, it is a segmentation offload for a
> tunnel that has an outer checksum.  I was hoping to avoid using the
> word checksum as that might make it confusing as it is a segmentation
> offload, not a checksum offload.

Yes, but my point is that we haven't used the abbreviation "csum".

> > > 
> > >       [NETIF_F_GSO_IPIP_BIT] =         "tx-ipip-segmentation",
> > >       [NETIF_F_GSO_SIT_BIT] =          "tx-sit-segmentation",
> > >       [NETIF_F_GSO_UDP_TUNNEL_BIT] =   "tx-udp_tnl-segmentation",
> > > +     [NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT] = "tx-udp_tnl-csum-segmentation",
> > > +     [NETIF_F_GSO_TUNNEL_REMCSUM_BIT] = "tx-remcsum-segmentation",
> > I think this should be "tx-tunnel-remote-checksum-segmentation", though
> > that is getting quite unwieldy.
> Right.  As it is I think we might be coming up on the 32 character
> limit for the strings.  Replacing csum with checksum would probably
> push us over.

Right, I wasn't even thinking about the static limit!  That does weigh
rather heavily in favour of abbreviation here.

Please do at least hyphenate "remcsum" though.

Ben.

-- 
Ben Hutchings
To err is human; to really foul things up requires a computer.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply

* [net-next:master 386/609] include/net/vxlan.h:302:17: sparse: cast to restricted __be64
From: kbuild test robot @ 2016-03-19  0:57 UTC (permalink / raw)
  To: Jiri Benc; +Cc: kbuild-all, netdev

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git master
head:   93e68cd6115f67d8363c94dae8206af36f6d3b00
commit: 07dabf20d9867710b90b91108b2adcd448773e25 [386/609] vxlan: tun_id is 64bit, not 32bit
reproduce:
        # apt-get install sparse
        git checkout 07dabf20d9867710b90b91108b2adcd448773e25
        make ARCH=x86_64 allmodconfig
        make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)

   include/net/checksum.h:177:43: sparse: incorrect type in argument 2 (different base types)
   include/net/checksum.h:177:43:    expected restricted __wsum [usertype] addend
   include/net/checksum.h:177:43:    got restricted __sum16 [usertype] <noident>
   include/net/inet_ecn.h:131:58: sparse: incorrect type in argument 2 (different base types)
   include/net/inet_ecn.h:131:58:    expected restricted __wsum [usertype] addend
   include/net/inet_ecn.h:131:58:    got restricted __be32 [assigned] [usertype] from
   include/net/inet_ecn.h:131:65: sparse: incorrect type in argument 2 (different base types)
   include/net/inet_ecn.h:131:65:    expected restricted __wsum [usertype] addend
   include/net/inet_ecn.h:131:65:    got restricted __be32 [assigned] [usertype] to
   include/net/inet_ecn.h:131:58: sparse: incorrect type in argument 2 (different base types)
   include/net/inet_ecn.h:131:58:    expected restricted __wsum [usertype] addend
   include/net/inet_ecn.h:131:58:    got restricted __be32 [assigned] [usertype] from
   include/net/inet_ecn.h:131:65: sparse: incorrect type in argument 2 (different base types)
   include/net/inet_ecn.h:131:65:    expected restricted __wsum [usertype] addend
   include/net/inet_ecn.h:131:65:    got restricted __be32 [assigned] [usertype] to
   include/net/vxlan.h:275:27: sparse: restricted __be32 degrades to integer
   include/net/vxlan.h:275:45: sparse: incorrect type in return expression (different base types)
   include/net/vxlan.h:275:45:    expected restricted __be32
   include/net/vxlan.h:275:45:    got unsigned int
>> include/net/vxlan.h:302:17: sparse: cast to restricted __be64
>> include/net/vxlan.h:302:17: sparse: cast from restricted __be32
   include/net/vxlan.h:302:17: sparse: restricted __be64 degrades to integer
>> include/net/vxlan.h:302:28: sparse: incorrect type in return expression (different base types)
   include/net/vxlan.h:302:28:    expected restricted __be64
   include/net/vxlan.h:302:28:    got unsigned long long
   include/net/vxlan.h:275:27: sparse: restricted __be32 degrades to integer
   include/net/vxlan.h:275:45: sparse: incorrect type in return expression (different base types)
   include/net/vxlan.h:275:45:    expected restricted __be32
   include/net/vxlan.h:275:45:    got unsigned int
   include/net/vxlan.h:284:16: sparse: restricted __be32 degrades to integer
   include/net/vxlan.h:284:20: sparse: incorrect type in return expression (different base types)
   include/net/vxlan.h:284:20:    expected restricted __be32
   include/net/vxlan.h:284:20:    got unsigned int
   include/net/vxlan.h:293:16: sparse: restricted __be64 degrades to integer
   include/net/vxlan.h:293:23: sparse: incorrect type in return expression (different base types)
   include/net/vxlan.h:293:23:    expected restricted __be32
   include/net/vxlan.h:293:23:    got unsigned long long

vim +302 include/net/vxlan.h

   269	
   270	static inline __be32 vxlan_vni(__be32 vni_field)
   271	{
   272	#if defined(__BIG_ENDIAN)
   273		return vni_field >> 8;
   274	#else
 > 275		return (vni_field & VXLAN_VNI_MASK) << 8;
   276	#endif
   277	}
   278	
   279	static inline __be32 vxlan_vni_field(__be32 vni)
   280	{
   281	#if defined(__BIG_ENDIAN)
   282		return vni << 8;
   283	#else
   284		return vni >> 8;
   285	#endif
   286	}
   287	
   288	static inline __be32 vxlan_tun_id_to_vni(__be64 tun_id)
   289	{
   290	#if defined(__BIG_ENDIAN)
   291		return tun_id;
   292	#else
   293		return tun_id >> 32;
   294	#endif
   295	}
   296	
   297	static inline __be64 vxlan_vni_to_tun_id(__be32 vni)
   298	{
   299	#if defined(__BIG_ENDIAN)
   300		return (__be64)vni;
   301	#else
 > 302		return (__be64)vni << 32;
   303	#endif
   304	}
   305	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

^ permalink raw reply

* [PATCH iproute2 2/2] geneve: Add support for configuring UDP checksums.
From: Jesse Gross @ 2016-03-19  0:51 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev
In-Reply-To: <1458348669-48437-1-git-send-email-jesse@kernel.org>

Enable support for configuring outer UDP checksums on Geneve tunnels:

ip link add type geneve id 10 remote 10.0.0.2 udpcsum

Signed-off-by: Jesse Gross <jesse@kernel.org>
---
 ip/iplink_geneve.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/ip/iplink_geneve.c b/ip/iplink_geneve.c
index 30b16b9..13a6d80 100644
--- a/ip/iplink_geneve.c
+++ b/ip/iplink_geneve.c
@@ -20,6 +20,7 @@ static void print_explain(FILE *f)
 	fprintf(f, "Usage: ... geneve id VNI remote ADDR\n");
 	fprintf(f, "                 [ ttl TTL ] [ tos TOS ]\n");
 	fprintf(f, "                 [ dstport PORT ] [ [no]external ]\n");
+	fprintf(f, "                 [ [no]udpcsum ] [ [no]udp6zerocsumtx ] [ [no]udp6zerocsumrx ]\n");
 	fprintf(f, "\n");
 	fprintf(f, "Where: VNI  := 0-16777215\n");
 	fprintf(f, "       ADDR := IP_ADDRESS\n");
@@ -43,6 +44,12 @@ static int geneve_parse_opt(struct link_util *lu, int argc, char **argv,
 	__u8 tos = 0;
 	__u16 dstport = 0;
 	bool metadata = 0;
+	__u8 udpcsum = 0;
+	bool udpcsum_set = false;
+	__u8 udp6zerocsumtx = 0;
+	bool udp6zerocsumtx_set = false;
+	__u8 udp6zerocsumrx = 0;
+	bool udp6zerocsumrx_set = false;
 
 	while (argc > 0) {
 		if (!matches(*argv, "id") ||
@@ -91,6 +98,24 @@ static int geneve_parse_opt(struct link_util *lu, int argc, char **argv,
 			metadata = true;
 		} else if (!matches(*argv, "noexternal")) {
 			metadata = false;
+		} else if (!matches(*argv, "udpcsum")) {
+			udpcsum = 1;
+			udpcsum_set = true;
+		} else if (!matches(*argv, "noudpcsum")) {
+			udpcsum = 0;
+			udpcsum_set = true;
+		} else if (!matches(*argv, "udp6zerocsumtx")) {
+			udp6zerocsumtx = 1;
+			udp6zerocsumtx_set = true;
+		} else if (!matches(*argv, "noudp6zerocsumtx")) {
+			udp6zerocsumtx = 0;
+			udp6zerocsumtx_set = true;
+		} else if (!matches(*argv, "udp6zerocsumrx")) {
+			udp6zerocsumrx = 1;
+			udp6zerocsumrx_set = true;
+		} else if (!matches(*argv, "noudp6zerocsumrx")) {
+			udp6zerocsumrx = 0;
+			udp6zerocsumrx_set = true;
 		} else if (matches(*argv, "help") == 0) {
 			explain();
 			return -1;
@@ -131,6 +156,12 @@ static int geneve_parse_opt(struct link_util *lu, int argc, char **argv,
 		addattr16(n, 1024, IFLA_GENEVE_PORT, htons(dstport));
 	if (metadata)
 		addattr(n, 1024, IFLA_GENEVE_COLLECT_METADATA);
+	if (udpcsum_set)
+		addattr8(n, 1024, IFLA_GENEVE_UDP_CSUM, udpcsum);
+	if (udp6zerocsumtx_set)
+		addattr8(n, 1024, IFLA_GENEVE_UDP_ZERO_CSUM6_TX, udp6zerocsumtx);
+	if (udp6zerocsumrx_set)
+		addattr8(n, 1024, IFLA_GENEVE_UDP_ZERO_CSUM6_RX, udp6zerocsumrx);
 
 	return 0;
 }
@@ -187,6 +218,23 @@ static void geneve_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
 	if (tb[IFLA_GENEVE_COLLECT_METADATA])
 		fputs("external ", f);
 
+	if (tb[IFLA_GENEVE_UDP_CSUM]) {
+		if (!rta_getattr_u8(tb[IFLA_GENEVE_UDP_CSUM]))
+			fputs("no", f);
+		fputs("udpcsum ", f);
+	}
+
+	if (tb[IFLA_GENEVE_UDP_ZERO_CSUM6_TX]) {
+		if (!rta_getattr_u8(tb[IFLA_GENEVE_UDP_ZERO_CSUM6_TX]))
+			fputs("no", f);
+		fputs("udp6zerocsumtx ", f);
+	}
+
+	if (tb[IFLA_GENEVE_UDP_ZERO_CSUM6_RX]) {
+		if (!rta_getattr_u8(tb[IFLA_GENEVE_UDP_ZERO_CSUM6_RX]))
+			fputs("no", f);
+		fputs("udp6zerocsumrx ", f);
+	}
 }
 
 static void geneve_print_help(struct link_util *lu, int argc, char **argv,
-- 
2.5.0

^ permalink raw reply related

* [PATCH iproute2 1/2] vxlan: Follow kernel defaults for outer UDP checksum.
From: Jesse Gross @ 2016-03-19  0:51 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev

On recent kernels, UDP checksum computation has become more efficient and
the default behavior was changed, however, the ip command overrides this
by always specifying a particular behavior.

If the user does not specify that UDP checksums should either be computed
or not then we don't need to send an explicit netlink message - the kernel
can just use its default behavior.

Signed-off-by: Jesse Gross <jesse@kernel.org>
---
 ip/iplink_vxlan.c | 35 +++++++++++++++++++++++++++--------
 1 file changed, 27 insertions(+), 8 deletions(-)

diff --git a/ip/iplink_vxlan.c b/ip/iplink_vxlan.c
index ede8482..be5636f 100644
--- a/ip/iplink_vxlan.c
+++ b/ip/iplink_vxlan.c
@@ -68,8 +68,11 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
 	__u32 maxaddr = 0;
 	__u16 dstport = 0;
 	__u8 udpcsum = 0;
+	bool udpcsum_set = false;
 	__u8 udp6zerocsumtx = 0;
+	bool udp6zerocsumtx_set = false;
 	__u8 udp6zerocsumrx = 0;
+	bool udp6zerocsumrx_set = false;
 	__u8 remcsumtx = 0;
 	__u8 remcsumrx = 0;
 	__u8 metadata = 0;
@@ -193,16 +196,22 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
 			l3miss = 1;
 		} else if (!matches(*argv, "udpcsum")) {
 			udpcsum = 1;
+			udpcsum_set = true;
 		} else if (!matches(*argv, "noudpcsum")) {
 			udpcsum = 0;
+			udpcsum_set = true;
 		} else if (!matches(*argv, "udp6zerocsumtx")) {
 			udp6zerocsumtx = 1;
+			udp6zerocsumtx_set = true;
 		} else if (!matches(*argv, "noudp6zerocsumtx")) {
 			udp6zerocsumtx = 0;
+			udp6zerocsumtx_set = true;
 		} else if (!matches(*argv, "udp6zerocsumrx")) {
 			udp6zerocsumrx = 1;
+			udp6zerocsumrx_set = true;
 		} else if (!matches(*argv, "noudp6zerocsumrx")) {
 			udp6zerocsumrx = 0;
+			udp6zerocsumrx_set = true;
 		} else if (!matches(*argv, "remcsumtx")) {
 			remcsumtx = 1;
 		} else if (!matches(*argv, "noremcsumtx")) {
@@ -277,13 +286,16 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
 	addattr8(n, 1024, IFLA_VXLAN_RSC, rsc);
 	addattr8(n, 1024, IFLA_VXLAN_L2MISS, l2miss);
 	addattr8(n, 1024, IFLA_VXLAN_L3MISS, l3miss);
-	addattr8(n, 1024, IFLA_VXLAN_UDP_CSUM, udpcsum);
-	addattr8(n, 1024, IFLA_VXLAN_UDP_ZERO_CSUM6_TX, udp6zerocsumtx);
-	addattr8(n, 1024, IFLA_VXLAN_UDP_ZERO_CSUM6_RX, udp6zerocsumrx);
 	addattr8(n, 1024, IFLA_VXLAN_REMCSUM_TX, remcsumtx);
 	addattr8(n, 1024, IFLA_VXLAN_REMCSUM_RX, remcsumrx);
 	addattr8(n, 1024, IFLA_VXLAN_COLLECT_METADATA, metadata);
 
+	if (udpcsum_set)
+		addattr8(n, 1024, IFLA_VXLAN_UDP_CSUM, udpcsum);
+	if (udp6zerocsumtx_set)
+		addattr8(n, 1024, IFLA_VXLAN_UDP_ZERO_CSUM6_TX, udp6zerocsumtx);
+	if (udp6zerocsumrx_set)
+		addattr8(n, 1024, IFLA_VXLAN_UDP_ZERO_CSUM6_RX, udp6zerocsumrx);
 	if (noage)
 		addattr32(n, 1024, IFLA_VXLAN_AGEING, 0);
 	else if (age)
@@ -420,16 +432,23 @@ static void vxlan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
 	    ((maxaddr = rta_getattr_u32(tb[IFLA_VXLAN_LIMIT])) != 0))
 		    fprintf(f, "maxaddr %u ", maxaddr);
 
-	if (tb[IFLA_VXLAN_UDP_CSUM] && rta_getattr_u8(tb[IFLA_VXLAN_UDP_CSUM]))
+	if (tb[IFLA_VXLAN_UDP_CSUM]) {
+		if (!rta_getattr_u8(tb[IFLA_VXLAN_UDP_CSUM]))
+			fputs("no", f);
 		fputs("udpcsum ", f);
+	}
 
-	if (tb[IFLA_VXLAN_UDP_ZERO_CSUM6_TX] &&
-	    rta_getattr_u8(tb[IFLA_VXLAN_UDP_ZERO_CSUM6_TX]))
+	if (tb[IFLA_VXLAN_UDP_ZERO_CSUM6_TX]) {
+		if (!rta_getattr_u8(tb[IFLA_VXLAN_UDP_ZERO_CSUM6_TX]))
+			fputs("no", f);
 		fputs("udp6zerocsumtx ", f);
+	}
 
-	if (tb[IFLA_VXLAN_UDP_ZERO_CSUM6_RX] &&
-	    rta_getattr_u8(tb[IFLA_VXLAN_UDP_ZERO_CSUM6_RX]))
+	if (tb[IFLA_VXLAN_UDP_ZERO_CSUM6_RX]) {
+		if (!rta_getattr_u8(tb[IFLA_VXLAN_UDP_ZERO_CSUM6_RX]))
+			fputs("no", f);
 		fputs("udp6zerocsumrx ", f);
+	}
 
 	if (tb[IFLA_VXLAN_REMCSUM_TX] &&
 	    rta_getattr_u8(tb[IFLA_VXLAN_REMCSUM_TX]))
-- 
2.5.0

^ permalink raw reply related

* [RFC net-next 2/2] chelsio: Move original cxgb driver into ancient subdirectory
From: Joe Perches @ 2016-03-19  0:33 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev
In-Reply-To: <cover.1458347329.git.joe@perches.com>

This hardware is no longer sold or supported by Chelsio.
The hardware is relatively rare, so move it to an ancient subdirectory.

Signed-off-by: Joe Perches <joe@perches.com>
---
 drivers/net/ethernet/chelsio/Kconfig                                | 2 +-
 drivers/net/ethernet/chelsio/Makefile                               | 2 +-
 drivers/net/ethernet/chelsio/ancient/Makefile                       | 1 +
 drivers/net/ethernet/chelsio/{ => ancient}/cxgb/Makefile            | 0
 drivers/net/ethernet/chelsio/{ => ancient}/cxgb/common.h            | 0
 drivers/net/ethernet/chelsio/{ => ancient}/cxgb/cphy.h              | 0
 drivers/net/ethernet/chelsio/{ => ancient}/cxgb/cpl5_cmd.h          | 0
 drivers/net/ethernet/chelsio/{ => ancient}/cxgb/cxgb2.c             | 0
 drivers/net/ethernet/chelsio/{ => ancient}/cxgb/elmer0.h            | 0
 drivers/net/ethernet/chelsio/{ => ancient}/cxgb/espi.c              | 0
 drivers/net/ethernet/chelsio/{ => ancient}/cxgb/espi.h              | 0
 drivers/net/ethernet/chelsio/{ => ancient}/cxgb/fpga_defs.h         | 0
 drivers/net/ethernet/chelsio/{ => ancient}/cxgb/gmac.h              | 0
 drivers/net/ethernet/chelsio/{ => ancient}/cxgb/mv88e1xxx.c         | 0
 drivers/net/ethernet/chelsio/{ => ancient}/cxgb/mv88e1xxx.h         | 0
 drivers/net/ethernet/chelsio/{ => ancient}/cxgb/mv88x201x.c         | 0
 drivers/net/ethernet/chelsio/{ => ancient}/cxgb/my3126.c            | 0
 drivers/net/ethernet/chelsio/{ => ancient}/cxgb/pm3393.c            | 0
 drivers/net/ethernet/chelsio/{ => ancient}/cxgb/regs.h              | 0
 drivers/net/ethernet/chelsio/{ => ancient}/cxgb/sge.c               | 0
 drivers/net/ethernet/chelsio/{ => ancient}/cxgb/sge.h               | 0
 drivers/net/ethernet/chelsio/{ => ancient}/cxgb/subr.c              | 0
 drivers/net/ethernet/chelsio/{ => ancient}/cxgb/suni1x10gexp_regs.h | 0
 drivers/net/ethernet/chelsio/{ => ancient}/cxgb/tp.c                | 0
 drivers/net/ethernet/chelsio/{ => ancient}/cxgb/tp.h                | 0
 drivers/net/ethernet/chelsio/{ => ancient}/cxgb/vsc7326.c           | 0
 drivers/net/ethernet/chelsio/{ => ancient}/cxgb/vsc7326_reg.h       | 0
 27 files changed, 3 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ethernet/chelsio/ancient/Makefile
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/Makefile (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/common.h (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/cphy.h (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/cpl5_cmd.h (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/cxgb2.c (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/elmer0.h (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/espi.c (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/espi.h (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/fpga_defs.h (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/gmac.h (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/mv88e1xxx.c (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/mv88e1xxx.h (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/mv88x201x.c (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/my3126.c (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/pm3393.c (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/regs.h (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/sge.c (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/sge.h (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/subr.c (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/suni1x10gexp_regs.h (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/tp.c (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/tp.h (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/vsc7326.c (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/vsc7326_reg.h (100%)

diff --git a/drivers/net/ethernet/chelsio/Kconfig b/drivers/net/ethernet/chelsio/Kconfig
index 4d187f2..25f4931 100644
--- a/drivers/net/ethernet/chelsio/Kconfig
+++ b/drivers/net/ethernet/chelsio/Kconfig
@@ -18,7 +18,7 @@ if NET_VENDOR_CHELSIO
 
 config CHELSIO_T1
 	tristate "Chelsio 10Gb Ethernet support"
-	depends on PCI
+	depends on PCI && ANCIENT_NETDEVICES
 	select CRC32
 	select MDIO
 	---help---
diff --git a/drivers/net/ethernet/chelsio/Makefile b/drivers/net/ethernet/chelsio/Makefile
index 390510b..10a8f92 100644
--- a/drivers/net/ethernet/chelsio/Makefile
+++ b/drivers/net/ethernet/chelsio/Makefile
@@ -2,7 +2,7 @@
 # Makefile for the Chelsio network device drivers.
 #
 
-obj-$(CONFIG_CHELSIO_T1) += cxgb/
+obj-y += ancient/
 obj-$(CONFIG_CHELSIO_T3) += cxgb3/
 obj-$(CONFIG_CHELSIO_T4) += cxgb4/
 obj-$(CONFIG_CHELSIO_T4VF) += cxgb4vf/
diff --git a/drivers/net/ethernet/chelsio/ancient/Makefile b/drivers/net/ethernet/chelsio/ancient/Makefile
new file mode 100644
index 0000000..f60dbde
--- /dev/null
+++ b/drivers/net/ethernet/chelsio/ancient/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_CHELSIO_T1) += cxgb/
diff --git a/drivers/net/ethernet/chelsio/cxgb/Makefile b/drivers/net/ethernet/chelsio/ancient/cxgb/Makefile
similarity index 100%
rename from drivers/net/ethernet/chelsio/cxgb/Makefile
rename to drivers/net/ethernet/chelsio/ancient/cxgb/Makefile
diff --git a/drivers/net/ethernet/chelsio/cxgb/common.h b/drivers/net/ethernet/chelsio/ancient/cxgb/common.h
similarity index 100%
rename from drivers/net/ethernet/chelsio/cxgb/common.h
rename to drivers/net/ethernet/chelsio/ancient/cxgb/common.h
diff --git a/drivers/net/ethernet/chelsio/cxgb/cphy.h b/drivers/net/ethernet/chelsio/ancient/cxgb/cphy.h
similarity index 100%
rename from drivers/net/ethernet/chelsio/cxgb/cphy.h
rename to drivers/net/ethernet/chelsio/ancient/cxgb/cphy.h
diff --git a/drivers/net/ethernet/chelsio/cxgb/cpl5_cmd.h b/drivers/net/ethernet/chelsio/ancient/cxgb/cpl5_cmd.h
similarity index 100%
rename from drivers/net/ethernet/chelsio/cxgb/cpl5_cmd.h
rename to drivers/net/ethernet/chelsio/ancient/cxgb/cpl5_cmd.h
diff --git a/drivers/net/ethernet/chelsio/cxgb/cxgb2.c b/drivers/net/ethernet/chelsio/ancient/cxgb/cxgb2.c
similarity index 100%
rename from drivers/net/ethernet/chelsio/cxgb/cxgb2.c
rename to drivers/net/ethernet/chelsio/ancient/cxgb/cxgb2.c
diff --git a/drivers/net/ethernet/chelsio/cxgb/elmer0.h b/drivers/net/ethernet/chelsio/ancient/cxgb/elmer0.h
similarity index 100%
rename from drivers/net/ethernet/chelsio/cxgb/elmer0.h
rename to drivers/net/ethernet/chelsio/ancient/cxgb/elmer0.h
diff --git a/drivers/net/ethernet/chelsio/cxgb/espi.c b/drivers/net/ethernet/chelsio/ancient/cxgb/espi.c
similarity index 100%
rename from drivers/net/ethernet/chelsio/cxgb/espi.c
rename to drivers/net/ethernet/chelsio/ancient/cxgb/espi.c
diff --git a/drivers/net/ethernet/chelsio/cxgb/espi.h b/drivers/net/ethernet/chelsio/ancient/cxgb/espi.h
similarity index 100%
rename from drivers/net/ethernet/chelsio/cxgb/espi.h
rename to drivers/net/ethernet/chelsio/ancient/cxgb/espi.h
diff --git a/drivers/net/ethernet/chelsio/cxgb/fpga_defs.h b/drivers/net/ethernet/chelsio/ancient/cxgb/fpga_defs.h
similarity index 100%
rename from drivers/net/ethernet/chelsio/cxgb/fpga_defs.h
rename to drivers/net/ethernet/chelsio/ancient/cxgb/fpga_defs.h
diff --git a/drivers/net/ethernet/chelsio/cxgb/gmac.h b/drivers/net/ethernet/chelsio/ancient/cxgb/gmac.h
similarity index 100%
rename from drivers/net/ethernet/chelsio/cxgb/gmac.h
rename to drivers/net/ethernet/chelsio/ancient/cxgb/gmac.h
diff --git a/drivers/net/ethernet/chelsio/cxgb/mv88e1xxx.c b/drivers/net/ethernet/chelsio/ancient/cxgb/mv88e1xxx.c
similarity index 100%
rename from drivers/net/ethernet/chelsio/cxgb/mv88e1xxx.c
rename to drivers/net/ethernet/chelsio/ancient/cxgb/mv88e1xxx.c
diff --git a/drivers/net/ethernet/chelsio/cxgb/mv88e1xxx.h b/drivers/net/ethernet/chelsio/ancient/cxgb/mv88e1xxx.h
similarity index 100%
rename from drivers/net/ethernet/chelsio/cxgb/mv88e1xxx.h
rename to drivers/net/ethernet/chelsio/ancient/cxgb/mv88e1xxx.h
diff --git a/drivers/net/ethernet/chelsio/cxgb/mv88x201x.c b/drivers/net/ethernet/chelsio/ancient/cxgb/mv88x201x.c
similarity index 100%
rename from drivers/net/ethernet/chelsio/cxgb/mv88x201x.c
rename to drivers/net/ethernet/chelsio/ancient/cxgb/mv88x201x.c
diff --git a/drivers/net/ethernet/chelsio/cxgb/my3126.c b/drivers/net/ethernet/chelsio/ancient/cxgb/my3126.c
similarity index 100%
rename from drivers/net/ethernet/chelsio/cxgb/my3126.c
rename to drivers/net/ethernet/chelsio/ancient/cxgb/my3126.c
diff --git a/drivers/net/ethernet/chelsio/cxgb/pm3393.c b/drivers/net/ethernet/chelsio/ancient/cxgb/pm3393.c
similarity index 100%
rename from drivers/net/ethernet/chelsio/cxgb/pm3393.c
rename to drivers/net/ethernet/chelsio/ancient/cxgb/pm3393.c
diff --git a/drivers/net/ethernet/chelsio/cxgb/regs.h b/drivers/net/ethernet/chelsio/ancient/cxgb/regs.h
similarity index 100%
rename from drivers/net/ethernet/chelsio/cxgb/regs.h
rename to drivers/net/ethernet/chelsio/ancient/cxgb/regs.h
diff --git a/drivers/net/ethernet/chelsio/cxgb/sge.c b/drivers/net/ethernet/chelsio/ancient/cxgb/sge.c
similarity index 100%
rename from drivers/net/ethernet/chelsio/cxgb/sge.c
rename to drivers/net/ethernet/chelsio/ancient/cxgb/sge.c
diff --git a/drivers/net/ethernet/chelsio/cxgb/sge.h b/drivers/net/ethernet/chelsio/ancient/cxgb/sge.h
similarity index 100%
rename from drivers/net/ethernet/chelsio/cxgb/sge.h
rename to drivers/net/ethernet/chelsio/ancient/cxgb/sge.h
diff --git a/drivers/net/ethernet/chelsio/cxgb/subr.c b/drivers/net/ethernet/chelsio/ancient/cxgb/subr.c
similarity index 100%
rename from drivers/net/ethernet/chelsio/cxgb/subr.c
rename to drivers/net/ethernet/chelsio/ancient/cxgb/subr.c
diff --git a/drivers/net/ethernet/chelsio/cxgb/suni1x10gexp_regs.h b/drivers/net/ethernet/chelsio/ancient/cxgb/suni1x10gexp_regs.h
similarity index 100%
rename from drivers/net/ethernet/chelsio/cxgb/suni1x10gexp_regs.h
rename to drivers/net/ethernet/chelsio/ancient/cxgb/suni1x10gexp_regs.h
diff --git a/drivers/net/ethernet/chelsio/cxgb/tp.c b/drivers/net/ethernet/chelsio/ancient/cxgb/tp.c
similarity index 100%
rename from drivers/net/ethernet/chelsio/cxgb/tp.c
rename to drivers/net/ethernet/chelsio/ancient/cxgb/tp.c
diff --git a/drivers/net/ethernet/chelsio/cxgb/tp.h b/drivers/net/ethernet/chelsio/ancient/cxgb/tp.h
similarity index 100%
rename from drivers/net/ethernet/chelsio/cxgb/tp.h
rename to drivers/net/ethernet/chelsio/ancient/cxgb/tp.h
diff --git a/drivers/net/ethernet/chelsio/cxgb/vsc7326.c b/drivers/net/ethernet/chelsio/ancient/cxgb/vsc7326.c
similarity index 100%
rename from drivers/net/ethernet/chelsio/cxgb/vsc7326.c
rename to drivers/net/ethernet/chelsio/ancient/cxgb/vsc7326.c
diff --git a/drivers/net/ethernet/chelsio/cxgb/vsc7326_reg.h b/drivers/net/ethernet/chelsio/ancient/cxgb/vsc7326_reg.h
similarity index 100%
rename from drivers/net/ethernet/chelsio/cxgb/vsc7326_reg.h
rename to drivers/net/ethernet/chelsio/ancient/cxgb/vsc7326_reg.h
-- 
2.6.3.368.gf34be46

^ permalink raw reply related

* [RFC net-next 1/2] drivers/net: Create an ANCIENT_NETDEVICES symbol
From: Joe Perches @ 2016-03-19  0:33 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev
In-Reply-To: <cover.1458347329.git.joe@perches.com>

Many drivers are ancient and written for hardware that is no longer
available.  These drivers are effectively untested under current
kernels.  Add a symbol that could guard inclusions of these drivers
into modern kernels unless specifically requested.

Signed-off-by: Joe Perches <joe@perches.com>
---
 drivers/net/Kconfig | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 2a1ba62b..0878363 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -21,6 +21,25 @@ menuconfig NETDEVICES
 
 	  If unsure, say Y.
 
+menuconfig ANCIENT_NETDEVICES
+	   default n
+	   depends on NET && NETDEVICES
+	   bool "Network ancient device support"
+	   ---help---
+	   Many old devices are no longer manufactured.
+
+	   The drivers for these devices likely worked with the original
+	   kernel version when the devices were manufactured, but do not
+	   necessarily function well today.
+
+	   If these devices still exist and are still functional, the drivers
+	   for these devices get scant testing.
+
+	   The drivers for these devices are unmaintained and not supported by
+	   the vendor.
+
+	   If you are unsure that you need drivers for old hardware, say N.
+
 # All the following symbols are dependent on NETDEVICES - do not repeat
 # that for each of the symbols.
 if NETDEVICES
-- 
2.6.3.368.gf34be46

^ permalink raw reply related

* [RFC net-next 0/2] Create ancient subdirectories for old hardware
From: Joe Perches @ 2016-03-19  0:33 UTC (permalink / raw)
  To: netdev; +Cc: linux-kernel
In-Reply-To: <1458340518.26915.30.camel@perches.com>

Maybe something like this:

Old, rare, and unsupported hardware should be exposed as ancient.

The drivers for these ancient hardwares are generally untested with
current kernels.

Joe Perches (2):
  drivers/net: Create an ANCIENT_NETDEVICES symbol
  chelsio: Move original cxgb driver into ancient subdirectory

 drivers/net/Kconfig                                   | 19 +++++++++++++++++++
 drivers/net/ethernet/chelsio/Kconfig                  |  2 +-
 drivers/net/ethernet/chelsio/Makefile                 |  2 +-
 drivers/net/ethernet/chelsio/ancient/Makefile         |  1 +
 .../net/ethernet/chelsio/{ => ancient}/cxgb/Makefile  |  0
 .../net/ethernet/chelsio/{ => ancient}/cxgb/common.h  |  0
 .../net/ethernet/chelsio/{ => ancient}/cxgb/cphy.h    |  0
 .../ethernet/chelsio/{ => ancient}/cxgb/cpl5_cmd.h    |  0
 .../net/ethernet/chelsio/{ => ancient}/cxgb/cxgb2.c   |  0
 .../net/ethernet/chelsio/{ => ancient}/cxgb/elmer0.h  |  0
 .../net/ethernet/chelsio/{ => ancient}/cxgb/espi.c    |  0
 .../net/ethernet/chelsio/{ => ancient}/cxgb/espi.h    |  0
 .../ethernet/chelsio/{ => ancient}/cxgb/fpga_defs.h   |  0
 .../net/ethernet/chelsio/{ => ancient}/cxgb/gmac.h    |  0
 .../ethernet/chelsio/{ => ancient}/cxgb/mv88e1xxx.c   |  0
 .../ethernet/chelsio/{ => ancient}/cxgb/mv88e1xxx.h   |  0
 .../ethernet/chelsio/{ => ancient}/cxgb/mv88x201x.c   |  0
 .../net/ethernet/chelsio/{ => ancient}/cxgb/my3126.c  |  0
 .../net/ethernet/chelsio/{ => ancient}/cxgb/pm3393.c  |  0
 .../net/ethernet/chelsio/{ => ancient}/cxgb/regs.h    |  0
 drivers/net/ethernet/chelsio/{ => ancient}/cxgb/sge.c |  0
 drivers/net/ethernet/chelsio/{ => ancient}/cxgb/sge.h |  0
 .../net/ethernet/chelsio/{ => ancient}/cxgb/subr.c    |  0
 .../chelsio/{ => ancient}/cxgb/suni1x10gexp_regs.h    |  0
 drivers/net/ethernet/chelsio/{ => ancient}/cxgb/tp.c  |  0
 drivers/net/ethernet/chelsio/{ => ancient}/cxgb/tp.h  |  0
 .../net/ethernet/chelsio/{ => ancient}/cxgb/vsc7326.c |  0
 .../ethernet/chelsio/{ => ancient}/cxgb/vsc7326_reg.h |  0
 28 files changed, 22 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ethernet/chelsio/ancient/Makefile
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/Makefile (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/common.h (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/cphy.h (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/cpl5_cmd.h (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/cxgb2.c (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/elmer0.h (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/espi.c (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/espi.h (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/fpga_defs.h (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/gmac.h (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/mv88e1xxx.c (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/mv88e1xxx.h (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/mv88x201x.c (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/my3126.c (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/pm3393.c (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/regs.h (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/sge.c (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/sge.h (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/subr.c (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/suni1x10gexp_regs.h (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/tp.c (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/tp.h (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/vsc7326.c (100%)
 rename drivers/net/ethernet/chelsio/{ => ancient}/cxgb/vsc7326_reg.h (100%)

-- 
2.6.3.368.gf34be46

^ permalink raw reply

* Re: [RFC PATCH 6/9] ethtool: Add support for toggling any of the GSO offloads
From: Alexander Duyck @ 2016-03-19  0:30 UTC (permalink / raw)
  To: Ben Hutchings
  Cc: Alexander Duyck, Edward Cree, Netdev, David Miller, Tom Herbert
In-Reply-To: <1458346684.2953.16.camel@decadent.org.uk>

On Fri, Mar 18, 2016 at 5:18 PM, Ben Hutchings <ben@decadent.org.uk> wrote:
> On Fri, 2016-03-18 at 16:25 -0700, Alexander Duyck wrote:
>
>> The strings were missing for several of the GSO offloads that are
>> available.  This patch provides the missing strings so that we can toggle
>> or query any of them via the ethtool command.
>>
>> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
>> ---
>>  net/core/ethtool.c |    3 +++
>>  1 file changed, 3 insertions(+)
>>
>> diff --git a/net/core/ethtool.c b/net/core/ethtool.c
>> index 2966cd0d7c93..b3c39d531469 100644
>> --- a/net/core/ethtool.c
>> +++ b/net/core/ethtool.c
>> @@ -82,9 +82,12 @@ static const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN]
>>       [NETIF_F_TSO6_BIT] =             "tx-tcp6-segmentation",
>>       [NETIF_F_FSO_BIT] =              "tx-fcoe-segmentation",
>>       [NETIF_F_GSO_GRE_BIT] =          "tx-gre-segmentation",
>> +     [NETIF_F_GSO_GRE_CSUM_BIT] =     "tx-gre-csum-segmentation",
>
> All of the existing checksum offload names include the word "checksum"
> in full, so I think the new names should do the same.

It isn't a checksum offload though, it is a segmentation offload for a
tunnel that has an outer checksum.  I was hoping to avoid using the
word checksum as that might make it confusing as it is a segmentation
offload, not a checksum offload.

>>       [NETIF_F_GSO_IPIP_BIT] =         "tx-ipip-segmentation",
>>       [NETIF_F_GSO_SIT_BIT] =          "tx-sit-segmentation",
>>       [NETIF_F_GSO_UDP_TUNNEL_BIT] =   "tx-udp_tnl-segmentation",
>> +     [NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT] = "tx-udp_tnl-csum-segmentation",
>> +     [NETIF_F_GSO_TUNNEL_REMCSUM_BIT] = "tx-remcsum-segmentation",
>
> I think this should be "tx-tunnel-remote-checksum-segmentation", though
> that is getting quite unwieldy.

Right.  As it is I think we might be coming up on the 32 character
limit for the strings.  Replacing csum with checksum would probably
push us over.

- Alex

^ permalink raw reply

* Re: [RFC PATCH 6/9] ethtool: Add support for toggling any of the GSO offloads
From: Ben Hutchings @ 2016-03-19  0:18 UTC (permalink / raw)
  To: Alexander Duyck, ecree, netdev, davem, alexander.duyck, tom
In-Reply-To: <20160318232516.14955.2907.stgit@localhost.localdomain>

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

On Fri, 2016-03-18 at 16:25 -0700, Alexander Duyck wrote:

> The strings were missing for several of the GSO offloads that are
> available.  This patch provides the missing strings so that we can toggle
> or query any of them via the ethtool command.
> 
> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
> ---
>  net/core/ethtool.c |    3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/net/core/ethtool.c b/net/core/ethtool.c
> index 2966cd0d7c93..b3c39d531469 100644
> --- a/net/core/ethtool.c
> +++ b/net/core/ethtool.c
> @@ -82,9 +82,12 @@ static const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN]
>  	[NETIF_F_TSO6_BIT] =             "tx-tcp6-segmentation",
>  	[NETIF_F_FSO_BIT] =              "tx-fcoe-segmentation",
>  	[NETIF_F_GSO_GRE_BIT] =		 "tx-gre-segmentation",
> +	[NETIF_F_GSO_GRE_CSUM_BIT] =	 "tx-gre-csum-segmentation",

All of the existing checksum offload names include the word "checksum"
in full, so I think the new names should do the same.

>  	[NETIF_F_GSO_IPIP_BIT] =	 "tx-ipip-segmentation",
>  	[NETIF_F_GSO_SIT_BIT] =		 "tx-sit-segmentation",
>  	[NETIF_F_GSO_UDP_TUNNEL_BIT] =	 "tx-udp_tnl-segmentation",
> +	[NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT] = "tx-udp_tnl-csum-segmentation",
> +	[NETIF_F_GSO_TUNNEL_REMCSUM_BIT] = "tx-remcsum-segmentation",

I think this should be "tx-tunnel-remote-checksum-segmentation", though
that is getting quite unwieldy.

Ben.

>  	[NETIF_F_FCOE_CRC_BIT] =         "tx-checksum-fcoe-crc",
>  	[NETIF_F_SCTP_CRC_BIT] =        "tx-checksum-sctp",
> 
-- 
Ben Hutchings
To err is human; to really foul things up requires a computer.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply

* Re: [net-next] net: fix a comment typo
From: David Miller @ 2016-03-18 23:40 UTC (permalink / raw)
  To: zhangshengju; +Cc: netdev
In-Reply-To: <1458119566-22304-1-git-send-email-zhangshengju@cmss.chinamobile.com>

From: Zhang Shengju <zhangshengju@cmss.chinamobile.com>
Date: Wed, 16 Mar 2016 09:12:46 +0000

> Fix a comment typo.
> 
> Signed-off-by: Zhang Shengju <zhangshengju@cmss.chinamobile.com>

Applied.

^ permalink raw reply

* Re: [patch] ethernet: micrel: fix some error codes
From: David Miller @ 2016-03-18 23:40 UTC (permalink / raw)
  To: dan.carpenter; +Cc: richard.rojfors, netdev, kernel-janitors
In-Reply-To: <20160316074510.GF12860@mwanda>

From: Dan Carpenter <dan.carpenter@oracle.com>
Date: Wed, 16 Mar 2016 10:45:10 +0300

> There were two issues here:
> 1) dma_mapping_error() return true/false but we want to return -ENOMEM
> 2) If dmaengine_prep_slave_sg() failed then "err" wasn't set but
>    presumably that should be -ENOMEM as well.
> 
> I changed the success path to "return 0;" instead of "return ret;" for
> clarity.
> 
> Fixes: 94fe8c683cea ('ks8842: Support DMA when accessed via timberdale')
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>

Applied.

^ permalink raw reply

* Re: [PATCH net-next 0/3] Minor BPF follow-ups
From: David Miller @ 2016-03-18 23:40 UTC (permalink / raw)
  To: daniel; +Cc: alexei.starovoitov, netdev
In-Reply-To: <cover.1458085814.git.daniel@iogearbox.net>

From: Daniel Borkmann <daniel@iogearbox.net>
Date: Wed, 16 Mar 2016 01:42:48 +0100

> Some minor last follow-ups I still had in my queue. The first one adds
> readability support for __sk_buff's tc_classid member, the remaining
> two are some minor cleanups. For details please see individual patches.

Series applied.

^ permalink raw reply

* Re: [PATCH] net: mvneta: bm: clarify dependencies
From: David Miller @ 2016-03-18 23:37 UTC (permalink / raw)
  To: arnd; +Cc: netdev, gregory.clement, mw, linux-kernel
In-Reply-To: <1458078449-635940-1-git-send-email-arnd@arndb.de>

From: Arnd Bergmann <arnd@arndb.de>
Date: Tue, 15 Mar 2016 22:47:14 +0100

> MVNETA_BM has a dependency on MVNETA, so we can only select the former
> if the latter is enabled. However, the code dependency is the reverse:
> The mvneta module can call into the mvneta_bm module, so mvneta cannot
> be a built-in if mvneta_bm is a module, or we get a link error:
> 
> drivers/net/built-in.o: In function `mvneta_remove':
> drivers/net/ethernet/marvell/mvneta.c:4211: undefined reference to `mvneta_bm_pool_destroy'
> drivers/net/built-in.o: In function `mvneta_bm_update_mtu':
> drivers/net/ethernet/marvell/mvneta.c:1034: undefined reference to `mvneta_bm_bufs_free'
> 
> This avoids the problem by further clarifying the dependency so that
> MVNETA_BM is a silent Kconfig option that gets turned on by the
> new MVNETA_BM_ENABLE option. This way both the core HWBM module and
> the MVNETA_BM code are always built-in when needed.
> 
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> Fixes: dc35a10f68d3 ("net: mvneta: bm: add support for hardware buffer management")

Applied.

^ permalink raw reply

* Re: [PATCH net-next] cls_bpf: reset class and reuse major in da
From: David Miller @ 2016-03-18 23:35 UTC (permalink / raw)
  To: daniel; +Cc: alexei.starovoitov, netdev
In-Reply-To: <9e700a6f163815e6f79db50e7a8f9f52696f28e7.1458075641.git.daniel@iogearbox.net>

From: Daniel Borkmann <daniel@iogearbox.net>
Date: Tue, 15 Mar 2016 22:41:22 +0100

> There are two issues with the current code. First one is that we need
> to set res->class to 0 in case we use non-default classid matching.
> 
> This is important for the case where cls_bpf was initially set up with
> an optional binding to a default class with tcf_bind_filter(), where
> the underlying qdisc implements bind_tcf() that fills res->class and
> tests for it later on when doing the classification. Convention for
> these cases is that after tc_classify() was called, such qdiscs (atm,
> drr, qfq, cbq, hfsc, htb) first test class, and if 0, then they lookup
> based on classid.
> 
> Second, there's a bug with da mode, where res->classid is only assigned
> a 16 bit minor, but it needs to expand to the full 32 bit major/minor
> combination instead, therefore we need to expand with the bound major.
> This is fine as classes belonging to a classful qdisc must share the
> same major.
> 
> Fixes: 045efa82ff56 ("cls_bpf: introduce integrated actions")
> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
> Acked-by: Alexei Starovoitov <ast@kernel.org>

Applied, thanks Daniel.

^ permalink raw reply

* Re: [PATCH net-next v2 0/4] ldmvsw: Add ldmvsw driver
From: David Miller @ 2016-03-18 23:33 UTC (permalink / raw)
  To: Aaron.Young
  Cc: netdev, sowmini.varadhan, alexandre.chartre, rashmi.narasimhan,
	atish.patra
In-Reply-To: <cover.1458006737.git.Aaron.Young@oracle.com>

From: Aaron Young <Aaron.Young@oracle.com>
Date: Tue, 15 Mar 2016 11:35:36 -0700

> This series adds a new Logical Domains vSwitch (ldmvsw) driver.

Series applied, thanks Aaron.

^ permalink raw reply

* [RFC PATCH 9/9] ixgbe/ixgbevf: Add support for GSO partial
From: Alexander Duyck @ 2016-03-18 23:25 UTC (permalink / raw)
  To: ecree, netdev, davem, alexander.duyck, tom
In-Reply-To: <20160318230945.14955.63211.stgit@localhost.localdomain>

This patch adds support for partial GSO segmentation in the case of GRE or
UDP encapsulated frames.

The one bit in this patch that is a bit controversial is the fact that we
are leaving the inner IPv4 IP ID as a static value in the case of
segmentation.  As per RFC6864 this should be acceptable as TCP frames set
the DF bit so the IP ID should be ignored.  However this is not always the
case as header compression schemes for PPP and SLIP can end up taking a
performance hit as they have to record the fact that the ID didn't change
as expected.

In addition GRO was examining the IP ID field as well.  As such on older
GRO implementations TSO frames from this driver may end up blocking GRO on
the other end which will likely hurt performance instead of helping it.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c     |   72 +++++++++++++-------
 drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |   77 ++++++++++++++-------
 2 files changed, 99 insertions(+), 50 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 59b43ce200be..bef69306fb65 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -7178,9 +7178,18 @@ static int ixgbe_tso(struct ixgbe_ring *tx_ring,
 		     struct ixgbe_tx_buffer *first,
 		     u8 *hdr_len)
 {
+	u32 vlan_macip_lens, type_tucmd, mss_l4len_idx;
 	struct sk_buff *skb = first->skb;
-	u32 vlan_macip_lens, type_tucmd;
-	u32 mss_l4len_idx, l4len;
+	union {
+		struct iphdr *v4;
+		struct ipv6hdr *v6;
+		unsigned char *hdr;
+	} ip;
+	union {
+		struct tcphdr *tcp;
+		unsigned char *hdr;
+	} l4;
+	u32 paylen, l4_offset;
 	int err;
 
 	if (skb->ip_summed != CHECKSUM_PARTIAL)
@@ -7193,46 +7202,52 @@ static int ixgbe_tso(struct ixgbe_ring *tx_ring,
 	if (err < 0)
 		return err;
 
+	ip.hdr = skb_network_header(skb);
+	l4.hdr = skb_checksum_start(skb);
+
 	/* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */
 	type_tucmd = IXGBE_ADVTXD_TUCMD_L4T_TCP;
 
-	if (first->protocol == htons(ETH_P_IP)) {
-		struct iphdr *iph = ip_hdr(skb);
-		iph->tot_len = 0;
-		iph->check = 0;
-		tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
-							 iph->daddr, 0,
-							 IPPROTO_TCP,
-							 0);
+	/* initialize outer IP header fields */
+	if (ip.v4->version == 4) {
+		/* IP header will have to cancel out any data that
+		 * is not a part of the outer IP header
+		 */
+		ip.v4->check = csum_fold(csum_add(lco_csum(skb),
+						  csum_unfold(l4.tcp->check)));
 		type_tucmd |= IXGBE_ADVTXD_TUCMD_IPV4;
+
+		ip.v4->tot_len = 0;
 		first->tx_flags |= IXGBE_TX_FLAGS_TSO |
 				   IXGBE_TX_FLAGS_CSUM |
 				   IXGBE_TX_FLAGS_IPV4;
-	} else if (skb_is_gso_v6(skb)) {
-		ipv6_hdr(skb)->payload_len = 0;
-		tcp_hdr(skb)->check =
-		    ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
-				     &ipv6_hdr(skb)->daddr,
-				     0, IPPROTO_TCP, 0);
+	} else {
+		ip.v6->payload_len = 0;
 		first->tx_flags |= IXGBE_TX_FLAGS_TSO |
 				   IXGBE_TX_FLAGS_CSUM;
 	}
 
-	/* compute header lengths */
-	l4len = tcp_hdrlen(skb);
-	*hdr_len = skb_transport_offset(skb) + l4len;
+	/* determine offset of inner transport header */
+	l4_offset = l4.hdr - skb->data;
+
+	/* compute length of segmentation header */
+	*hdr_len = (l4.tcp->doff * 4) + l4_offset;
+
+	/* remove payload length from inner checksum */
+	paylen = skb->len - l4_offset;
+	csum_replace_by_diff(&l4.tcp->check, htonl(paylen));
 
 	/* update gso size and bytecount with header size */
 	first->gso_segs = skb_shinfo(skb)->gso_segs;
 	first->bytecount += (first->gso_segs - 1) * *hdr_len;
 
 	/* mss_l4len_id: use 0 as index for TSO */
-	mss_l4len_idx = l4len << IXGBE_ADVTXD_L4LEN_SHIFT;
+	mss_l4len_idx = (*hdr_len - l4_offset) << IXGBE_ADVTXD_L4LEN_SHIFT;
 	mss_l4len_idx |= skb_shinfo(skb)->gso_size << IXGBE_ADVTXD_MSS_SHIFT;
 
 	/* vlan_macip_lens: HEADLEN, MACLEN, VLAN tag */
-	vlan_macip_lens = skb_network_header_len(skb);
-	vlan_macip_lens |= skb_network_offset(skb) << IXGBE_ADVTXD_MACLEN_SHIFT;
+	vlan_macip_lens = l4.hdr - ip.hdr;
+	vlan_macip_lens |= (ip.hdr - skb->data) << IXGBE_ADVTXD_MACLEN_SHIFT;
 	vlan_macip_lens |= first->tx_flags & IXGBE_TX_FLAGS_VLAN_MASK;
 
 	ixgbe_tx_ctxtdesc(tx_ring, vlan_macip_lens, 0, type_tucmd,
@@ -9201,6 +9216,14 @@ skip_sriov:
 			   NETIF_F_HW_VLAN_CTAG_RX |
 			   NETIF_F_HW_VLAN_CTAG_FILTER;
 
+	netdev->gso_partial_features = NETIF_F_GSO_GRE |
+				       NETIF_F_GSO_GRE_CSUM |
+				       NETIF_F_GSO_UDP_TUNNEL |
+				       NETIF_F_GSO_UDP_TUNNEL_CSUM;
+
+	netdev->features |= NETIF_F_GSO_PARTIAL |
+			    netdev->gso_partial_features;
+
 	if (hw->mac.type >= ixgbe_mac_82599EB)
 		netdev->features |= NETIF_F_SCTP_CRC;
 
@@ -9219,7 +9242,10 @@ skip_sriov:
 				 NETIF_F_SCTP_CRC;
 
 	netdev->mpls_features |= NETIF_F_HW_CSUM;
-	netdev->hw_enc_features |= NETIF_F_HW_CSUM;
+	netdev->hw_enc_features |= NETIF_F_TSO |
+				   NETIF_F_TSO6 |
+				   NETIF_F_HW_CSUM |
+				   netdev->gso_partial_features;
 
 	netdev->priv_flags |= IFF_UNICAST_FLT;
 	netdev->priv_flags |= IFF_SUPP_NOFCS;
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 0c3e29b55b45..1ece15ee9834 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -3272,9 +3272,18 @@ static int ixgbevf_tso(struct ixgbevf_ring *tx_ring,
 		       struct ixgbevf_tx_buffer *first,
 		       u8 *hdr_len)
 {
+	u32 vlan_macip_lens, type_tucmd, mss_l4len_idx;
 	struct sk_buff *skb = first->skb;
-	u32 vlan_macip_lens, type_tucmd;
-	u32 mss_l4len_idx, l4len;
+	union {
+		struct iphdr *v4;
+		struct ipv6hdr *v6;
+		unsigned char *hdr;
+	} ip;
+	union {
+		struct tcphdr *tcp;
+		unsigned char *hdr;
+	} l4;
+	u32 paylen, l4_offset;
 	int err;
 
 	if (skb->ip_summed != CHECKSUM_PARTIAL)
@@ -3287,49 +3296,53 @@ static int ixgbevf_tso(struct ixgbevf_ring *tx_ring,
 	if (err < 0)
 		return err;
 
+	ip.hdr = skb_network_header(skb);
+	l4.hdr = skb_checksum_start(skb);
+
 	/* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */
 	type_tucmd = IXGBE_ADVTXD_TUCMD_L4T_TCP;
 
-	if (first->protocol == htons(ETH_P_IP)) {
-		struct iphdr *iph = ip_hdr(skb);
-
-		iph->tot_len = 0;
-		iph->check = 0;
-		tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
-							 iph->daddr, 0,
-							 IPPROTO_TCP,
-							 0);
+	/* initialize outer IP header fields */
+	if (ip.v4->version == 4) {
+		/* IP header will have to cancel out any data that
+		 * is not a part of the outer IP header
+		 */
+		ip.v4->check = csum_fold(csum_add(lco_csum(skb),
+						  csum_unfold(l4.tcp->check)));
 		type_tucmd |= IXGBE_ADVTXD_TUCMD_IPV4;
+
+		ip.v4->tot_len = 0;
 		first->tx_flags |= IXGBE_TX_FLAGS_TSO |
 				   IXGBE_TX_FLAGS_CSUM |
 				   IXGBE_TX_FLAGS_IPV4;
-	} else if (skb_is_gso_v6(skb)) {
-		ipv6_hdr(skb)->payload_len = 0;
-		tcp_hdr(skb)->check =
-		    ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
-				     &ipv6_hdr(skb)->daddr,
-				     0, IPPROTO_TCP, 0);
+	} else {
+		ip.v6->payload_len = 0;
 		first->tx_flags |= IXGBE_TX_FLAGS_TSO |
 				   IXGBE_TX_FLAGS_CSUM;
 	}
 
-	/* compute header lengths */
-	l4len = tcp_hdrlen(skb);
-	*hdr_len += l4len;
-	*hdr_len = skb_transport_offset(skb) + l4len;
+	/* determine offset of inner transport header */
+	l4_offset = l4.hdr - skb->data;
 
-	/* update GSO size and bytecount with header size */
+	/* compute length of segmentation header */
+	*hdr_len = (l4.tcp->doff * 4) + l4_offset;
+
+	/* remove payload length from inner checksum */
+	paylen = skb->len - l4_offset;
+	csum_replace_by_diff(&l4.tcp->check, htonl(paylen));
+
+	/* update gso size and bytecount with header size */
 	first->gso_segs = skb_shinfo(skb)->gso_segs;
 	first->bytecount += (first->gso_segs - 1) * *hdr_len;
 
 	/* mss_l4len_id: use 1 as index for TSO */
-	mss_l4len_idx = l4len << IXGBE_ADVTXD_L4LEN_SHIFT;
+	mss_l4len_idx = (*hdr_len - l4_offset) << IXGBE_ADVTXD_L4LEN_SHIFT;
 	mss_l4len_idx |= skb_shinfo(skb)->gso_size << IXGBE_ADVTXD_MSS_SHIFT;
 	mss_l4len_idx |= 1 << IXGBE_ADVTXD_IDX_SHIFT;
 
 	/* vlan_macip_lens: HEADLEN, MACLEN, VLAN tag */
-	vlan_macip_lens = skb_network_header_len(skb);
-	vlan_macip_lens |= skb_network_offset(skb) << IXGBE_ADVTXD_MACLEN_SHIFT;
+	vlan_macip_lens = l4.hdr - ip.hdr;
+	vlan_macip_lens |= (ip.hdr - skb->data) << IXGBE_ADVTXD_MACLEN_SHIFT;
 	vlan_macip_lens |= first->tx_flags & IXGBE_TX_FLAGS_VLAN_MASK;
 
 	ixgbevf_tx_ctxtdesc(tx_ring, vlan_macip_lens,
@@ -3992,12 +4005,19 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto err_sw_init;
 	}
 
+	netdev->gso_partial_features = NETIF_F_GSO_GRE |
+				       NETIF_F_GSO_GRE_CSUM |
+				       NETIF_F_GSO_UDP_TUNNEL |
+				       NETIF_F_GSO_UDP_TUNNEL_CSUM;
+
 	netdev->hw_features = NETIF_F_SG |
 			      NETIF_F_TSO |
 			      NETIF_F_TSO6 |
 			      NETIF_F_RXCSUM |
 			      NETIF_F_HW_CSUM |
-			      NETIF_F_SCTP_CRC;
+			      NETIF_F_SCTP_CRC |
+			      NETIF_F_GSO_PARTIAL |
+			      netdev->gso_partial_features;
 
 	netdev->features = netdev->hw_features |
 			   NETIF_F_HW_VLAN_CTAG_TX |
@@ -4011,7 +4031,10 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 				 NETIF_F_SCTP_CRC;
 
 	netdev->mpls_features |= NETIF_F_HW_CSUM;
-	netdev->hw_enc_features |= NETIF_F_HW_CSUM;
+	netdev->hw_enc_features |= NETIF_F_TSO |
+				   NETIF_F_TSO6 |
+				   NETIF_F_HW_CSUM |
+				   netdev->gso_partial_features;
 
 	if (pci_using_dac)
 		netdev->features |= NETIF_F_HIGHDMA;

^ permalink raw reply related

* [RFC PATCH 8/9] i40e/i40evf: Add support for GSO partial with UDP_TUNNEL_CSUM and GRE_CSUM
From: Alexander Duyck @ 2016-03-18 23:25 UTC (permalink / raw)
  To: ecree, netdev, davem, alexander.duyck, tom
In-Reply-To: <20160318230945.14955.63211.stgit@localhost.localdomain>

This patch makes it so that i40e and i40evf can use GSO_PARTIAL to support
segmentation for frames with checksums enabled in outer headers.  As a
result we can now send data over these types of tunnels at over 20Gb/s
versus the 12Gb/s that was previously possible on my system.

The advantage with the i40e parts is that this offload is mostly
transparent as the hardware still deals with the inner and/or outer IPv4
headers so the IP ID is still incrementing for both when this offload is
performed.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
---
 drivers/net/ethernet/intel/i40e/i40e_main.c     |    8 +++++++-
 drivers/net/ethernet/intel/i40e/i40e_txrx.c     |   14 +++++++++++---
 drivers/net/ethernet/intel/i40evf/i40e_txrx.c   |   14 +++++++++++---
 drivers/net/ethernet/intel/i40evf/i40evf_main.c |    8 +++++++-
 4 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 39b0009253c2..ac3964a9f5c0 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -9050,6 +9050,7 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
 				   NETIF_F_TSO6		       |
 				   NETIF_F_TSO_ECN	       |
 				   NETIF_F_GSO_GRE	       |
+				   NETIF_F_GSO_GRE_CSUM	       |
 				   NETIF_F_GSO_UDP_TUNNEL      |
 				   NETIF_F_GSO_UDP_TUNNEL_CSUM |
 				   0;
@@ -9074,7 +9075,12 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
 	if (!(pf->flags & I40E_FLAG_MFP_ENABLED))
 		netdev->features |= NETIF_F_NTUPLE;
 	if (pf->flags & I40E_FLAG_OUTER_UDP_CSUM_CAPABLE)
-		netdev->features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
+		netdev->features = NETIF_F_GSO_UDP_TUNNEL_CSUM;
+	else
+		netdev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM;
+
+	netdev->gso_partial_features |= NETIF_F_GSO_GRE_CSUM;
+	netdev->features |= NETIF_F_GSO_PARTIAL | netdev->gso_partial_features;
 
 	/* copy netdev features into list of user selectable features */
 	netdev->hw_features |= netdev->features;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
index 5d5fa5359a1d..50aa76d7f92e 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -2297,9 +2297,16 @@ static int i40e_tso(struct i40e_ring *tx_ring, struct sk_buff *skb,
 		ip.v6->payload_len = 0;
 	}
 
-	if (skb_shinfo(skb)->gso_type & (SKB_GSO_UDP_TUNNEL | SKB_GSO_GRE |
+	if (skb_shinfo(skb)->gso_type & (SKB_GSO_GRE |
+					 SKB_GSO_GRE_CSUM |
+					 SKB_GSO_UDP_TUNNEL |
 					 SKB_GSO_UDP_TUNNEL_CSUM)) {
-		if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM) {
+		if (skb_shinfo(skb)->gso_type & (SKB_GSO_UDP_TUNNEL |
+						 SKB_GSO_UDP_TUNNEL_CSUM))
+			l4.udp->len = 0;
+
+		if (!(skb_shinfo(skb)->gso_type & SKB_GSO_PARTIAL) &&
+		    (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM)) {
 			/* determine offset of outer transport header */
 			l4_offset = l4.hdr - skb->data;
 
@@ -2470,7 +2477,8 @@ static int i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,
 
 		/* indicate if we need to offload outer UDP header */
 		if ((*tx_flags & I40E_TX_FLAGS_TSO) &&
-		    (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM))
+		    (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM) &&
+		    !(skb_shinfo(skb)->gso_type & SKB_GSO_PARTIAL))
 			tunnel |= I40E_TXD_CTX_QW0_L4T_CS_MASK;
 
 		/* record tunnel offload values */
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
index 04aabc52ba0d..1bb7c3efa36c 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
@@ -1564,9 +1564,16 @@ static int i40e_tso(struct i40e_ring *tx_ring, struct sk_buff *skb,
 		ip.v6->payload_len = 0;
 	}
 
-	if (skb_shinfo(skb)->gso_type & (SKB_GSO_UDP_TUNNEL | SKB_GSO_GRE |
+	if (skb_shinfo(skb)->gso_type & (SKB_GSO_GRE |
+					 SKB_GSO_GRE_CSUM |
+					 SKB_GSO_UDP_TUNNEL |
 					 SKB_GSO_UDP_TUNNEL_CSUM)) {
-		if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM) {
+		if (skb_shinfo(skb)->gso_type & (SKB_GSO_UDP_TUNNEL |
+						 SKB_GSO_UDP_TUNNEL_CSUM))
+			l4.udp->len = 0;
+
+		if (!(skb_shinfo(skb)->gso_type & SKB_GSO_PARTIAL) &&
+		    (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM)) {
 			/* determine offset of outer transport header */
 			l4_offset = l4.hdr - skb->data;
 
@@ -1695,7 +1702,8 @@ static int i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,
 
 		/* indicate if we need to offload outer UDP header */
 		if ((*tx_flags & I40E_TX_FLAGS_TSO) &&
-		    (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM))
+		    (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM) &&
+		    !(skb_shinfo(skb)->gso_type & SKB_GSO_PARTIAL))
 			tunnel |= I40E_TXD_CTX_QW0_L4T_CS_MASK;
 
 		/* record tunnel offload values */
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
index e3973684746b..ed3c9310c3e0 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
@@ -2331,7 +2331,7 @@ int i40evf_process_config(struct i40evf_adapter *adapter)
 			    NETIF_F_TSO |
 			    NETIF_F_TSO6 |
 			    NETIF_F_TSO_ECN |
-			    NETIF_F_GSO_GRE	       |
+			    NETIF_F_GSO_GRE |
 			    NETIF_F_GSO_UDP_TUNNEL |
 			    NETIF_F_RXCSUM |
 			    NETIF_F_GRO;
@@ -2342,11 +2342,17 @@ int i40evf_process_config(struct i40evf_adapter *adapter)
 				   NETIF_F_TSO6		       |
 				   NETIF_F_TSO_ECN	       |
 				   NETIF_F_GSO_GRE	       |
+				   NETIF_F_GSO_GRE_CSUM	       |
 				   NETIF_F_GSO_UDP_TUNNEL      |
 				   NETIF_F_GSO_UDP_TUNNEL_CSUM;
 
 	if (adapter->flags & I40EVF_FLAG_OUTER_UDP_CSUM_CAPABLE)
 		netdev->features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
+	else
+		netdev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM;
+
+	netdev->gso_partial_features |= NETIF_F_GSO_GRE_CSUM;
+	netdev->features |= NETIF_F_GSO_PARTIAL | netdev->gso_partial_features;
 
 	/* copy netdev features into list of user selectable features */
 	netdev->hw_features |= netdev->features;

^ permalink raw reply related

* [RFC PATCH 7/9] GSO: Support partial segmentation offload
From: Alexander Duyck @ 2016-03-18 23:25 UTC (permalink / raw)
  To: ecree, netdev, davem, alexander.duyck, tom
In-Reply-To: <20160318230945.14955.63211.stgit@localhost.localdomain>

This patch adds support for something I am referring to as GSO partial.
The basic idea is that we can support a broader range of devices for
segmentation if we use fixed outer headers and have the hardware only
really deal with segmenting the inner header.  The idea behind the naming
is due to the fact that everything before csum_start will be fixed headers,
and everything after will be the region that is handled by hardware.

With the current implementation it allows us to add support for the
following GSO types with an inner TSO or TSO6 offload:
NETIF_F_GSO_GRE
NETIF_F_GSO_GRE_CSUM
NETIF_F_UDP_TUNNEL
NETIF_F_UDP_TUNNEL_CSUM

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
---
 include/linux/netdev_features.h |    7 ++++++-
 include/linux/netdevice.h       |    2 ++
 include/linux/skbuff.h          |    7 ++++++-
 net/core/dev.c                  |   31 ++++++++++++++++++++++++++++++-
 net/core/ethtool.c              |    1 +
 net/core/skbuff.c               |   21 ++++++++++++++++++++-
 net/ipv4/af_inet.c              |   12 ++++++++++--
 net/ipv4/gre_offload.c          |   23 +++++++++++++++++++----
 net/ipv4/tcp_offload.c          |   10 ++++++++--
 net/ipv4/udp_offload.c          |   20 ++++++++++++++++----
 net/ipv6/ip6_offload.c          |    9 ++++++++-
 11 files changed, 126 insertions(+), 17 deletions(-)

diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
index a734bf43d190..8df3c5553af0 100644
--- a/include/linux/netdev_features.h
+++ b/include/linux/netdev_features.h
@@ -48,8 +48,12 @@ enum {
 	NETIF_F_GSO_UDP_TUNNEL_BIT,	/* ... UDP TUNNEL with TSO */
 	NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT,/* ... UDP TUNNEL with TSO & CSUM */
 	NETIF_F_GSO_TUNNEL_REMCSUM_BIT, /* ... TUNNEL with TSO & REMCSUM */
+	NETIF_F_GSO_PARTIAL_BIT,	/* ... Only segment inner-most L4
+					 *     in hardware and all other
+					 *     headers in software.
+					 */
 	/**/NETIF_F_GSO_LAST =		/* last bit, see GSO_MASK */
-		NETIF_F_GSO_TUNNEL_REMCSUM_BIT,
+		NETIF_F_GSO_PARTIAL_BIT,
 
 	NETIF_F_FCOE_CRC_BIT,		/* FCoE CRC32 */
 	NETIF_F_SCTP_CRC_BIT,		/* SCTP checksum offload */
@@ -121,6 +125,7 @@ enum {
 #define NETIF_F_GSO_UDP_TUNNEL	__NETIF_F(GSO_UDP_TUNNEL)
 #define NETIF_F_GSO_UDP_TUNNEL_CSUM __NETIF_F(GSO_UDP_TUNNEL_CSUM)
 #define NETIF_F_GSO_TUNNEL_REMCSUM __NETIF_F(GSO_TUNNEL_REMCSUM)
+#define NETIF_F_GSO_PARTIAL	 __NETIF_F(GSO_PARTIAL)
 #define NETIF_F_HW_VLAN_STAG_FILTER __NETIF_F(HW_VLAN_STAG_FILTER)
 #define NETIF_F_HW_VLAN_STAG_RX	__NETIF_F(HW_VLAN_STAG_RX)
 #define NETIF_F_HW_VLAN_STAG_TX	__NETIF_F(HW_VLAN_STAG_TX)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 31474d9d8a96..427d748ad8f9 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1647,6 +1647,7 @@ struct net_device {
 	netdev_features_t	vlan_features;
 	netdev_features_t	hw_enc_features;
 	netdev_features_t	mpls_features;
+	netdev_features_t	gso_partial_features;
 
 	int			ifindex;
 	int			group;
@@ -4014,6 +4015,7 @@ static inline bool net_gso_ok(netdev_features_t features, int gso_type)
 	BUILD_BUG_ON(SKB_GSO_UDP_TUNNEL != (NETIF_F_GSO_UDP_TUNNEL >> NETIF_F_GSO_SHIFT));
 	BUILD_BUG_ON(SKB_GSO_UDP_TUNNEL_CSUM != (NETIF_F_GSO_UDP_TUNNEL_CSUM >> NETIF_F_GSO_SHIFT));
 	BUILD_BUG_ON(SKB_GSO_TUNNEL_REMCSUM != (NETIF_F_GSO_TUNNEL_REMCSUM >> NETIF_F_GSO_SHIFT));
+	BUILD_BUG_ON(SKB_GSO_PARTIAL != (NETIF_F_GSO_PARTIAL >> NETIF_F_GSO_SHIFT));
 
 	return (features & feature) == feature;
 }
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 15d0df943466..c291a282f8b6 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -482,6 +482,8 @@ enum {
 	SKB_GSO_UDP_TUNNEL_CSUM = 1 << 11,
 
 	SKB_GSO_TUNNEL_REMCSUM = 1 << 12,
+
+	SKB_GSO_PARTIAL = 1 << 13,
 };
 
 #if BITS_PER_LONG > 32
@@ -3584,7 +3586,10 @@ static inline struct sec_path *skb_sec_path(struct sk_buff *skb)
  * Keeps track of level of encapsulation of network headers.
  */
 struct skb_gso_cb {
-	int	mac_offset;
+	union {
+		int	mac_offset;
+		int	data_offset;
+	};
 	int	encap_level;
 	__wsum	csum;
 	__u16	csum_start;
diff --git a/net/core/dev.c b/net/core/dev.c
index edb7179bc051..666cf427898b 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2711,6 +2711,19 @@ struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
 			return ERR_PTR(err);
 	}
 
+	/* Only report GSO partial support if it will enable us to
+	 * support segmentation on this frame without needing additional
+	 * work.
+	 */
+	if (features & NETIF_F_GSO_PARTIAL) {
+		netdev_features_t partial_features;
+		struct net_device *dev = skb->dev;
+
+		partial_features = dev->features & dev->gso_partial_features;
+		if (!skb_gso_ok(skb, features | partial_features))
+			features &= ~NETIF_F_GSO_PARTIAL;
+	}
+
 	BUILD_BUG_ON(SKB_SGO_CB_OFFSET +
 		     sizeof(*SKB_GSO_CB(skb)) > sizeof(skb->cb));
 
@@ -2841,6 +2854,14 @@ netdev_features_t netif_skb_features(struct sk_buff *skb)
 	if (skb->encapsulation)
 		features &= dev->hw_enc_features;
 
+	/* Support for GSO partial features requires software intervention
+	 * before we can actually process the packets so we need to strip
+	 * support for any partial features now and we can pull them back
+	 * in after we have partially segmented the frame.
+	 */
+	if (skb_is_gso(skb) && !(skb_shinfo(skb)->gso_type & SKB_GSO_PARTIAL))
+		features &= ~dev->gso_partial_features;
+
 	if (skb_vlan_tagged(skb))
 		features = netdev_intersect_features(features,
 						     dev->vlan_features |
@@ -6702,6 +6723,14 @@ static netdev_features_t netdev_fix_features(struct net_device *dev,
 		}
 	}
 
+	/* GSO partial features require GSO partial be set */
+	if ((features & dev->gso_partial_features) &&
+	    !(features & NETIF_F_GSO_PARTIAL)) {
+		netdev_dbg(dev,
+			   "Dropping partially supported GSO features since no GSO partial.\n");
+		features &= ~dev->gso_partial_features;
+	}
+
 #ifdef CONFIG_NET_RX_BUSY_POLL
 	if (dev->netdev_ops->ndo_busy_poll)
 		features |= NETIF_F_BUSY_POLL;
@@ -6982,7 +7011,7 @@ int register_netdevice(struct net_device *dev)
 
 	/* Make NETIF_F_SG inheritable to tunnel devices.
 	 */
-	dev->hw_enc_features |= NETIF_F_SG;
+	dev->hw_enc_features |= NETIF_F_SG | NETIF_F_GSO_PARTIAL;
 
 	/* Make NETIF_F_SG inheritable to MPLS.
 	 */
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index b3c39d531469..d1b278c6c29f 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -88,6 +88,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_GSO_UDP_TUNNEL_CSUM_BIT] = "tx-udp_tnl-csum-segmentation",
 	[NETIF_F_GSO_TUNNEL_REMCSUM_BIT] = "tx-remcsum-segmentation",
+	[NETIF_F_GSO_PARTIAL_BIT] =	 "tx-gso-partial",
 
 	[NETIF_F_FCOE_CRC_BIT] =         "tx-checksum-fcoe-crc",
 	[NETIF_F_SCTP_CRC_BIT] =        "tx-checksum-sctp",
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index f044f970f1a6..bdcba77e164c 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -3076,8 +3076,9 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
 	struct sk_buff *frag_skb = head_skb;
 	unsigned int offset = doffset;
 	unsigned int tnl_hlen = skb_tnl_header_len(head_skb);
+	unsigned int partial_segs = 0;
 	unsigned int headroom;
-	unsigned int len;
+	unsigned int len = head_skb->len;
 	__be16 proto;
 	bool csum;
 	int sg = !!(features & NETIF_F_SG);
@@ -3094,6 +3095,15 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
 
 	csum = !!can_checksum_protocol(features, proto);
 
+	/* GSO partial only requires that we trim off any excess that
+	 * doesn't fit into an MSS sized block, so take care of that
+	 * now.
+	 */
+	if (features & NETIF_F_GSO_PARTIAL) {
+		partial_segs = len / mss;
+		mss *= partial_segs;
+	}
+
 	headroom = skb_headroom(head_skb);
 	pos = skb_headlen(head_skb);
 
@@ -3281,6 +3291,15 @@ perform_csum_check:
 	 */
 	segs->prev = tail;
 
+	/* Update GSO info on first skb in partial sequence. */
+	if (partial_segs) {
+		skb_shinfo(segs)->gso_size = mss / partial_segs;
+		skb_shinfo(segs)->gso_segs = partial_segs;
+		skb_shinfo(segs)->gso_type = skb_shinfo(head_skb)->gso_type |
+					     SKB_GSO_PARTIAL;
+		SKB_GSO_CB(segs)->data_offset = skb_headroom(segs) + doffset;
+	}
+
 	/* Following permits correct backpressure, for protocols
 	 * using skb_set_owner_w().
 	 * Idea is to tranfert ownership from head_skb to last segment.
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 5e3885672907..d091f91fa25d 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1199,7 +1199,7 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
 	unsigned int offset = 0;
 	bool udpfrag, encap;
 	struct iphdr *iph;
-	int proto;
+	int proto, tot_len;
 	int nhoff;
 	int ihl;
 	int id;
@@ -1269,10 +1269,18 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
 			if (skb->next)
 				iph->frag_off |= htons(IP_MF);
 			offset += skb->len - nhoff - ihl;
+			tot_len = skb->len - nhoff;
+		} else if (skb_is_gso(skb)) {
+			iph->id = htons(id);
+			id += skb_shinfo(skb)->gso_segs;
+			tot_len = skb_shinfo(skb)->gso_size +
+				  SKB_GSO_CB(skb)->data_offset +
+				  skb->head - (unsigned char *)iph;
 		} else {
 			iph->id = htons(id++);
+			tot_len = skb->len - nhoff;
 		}
-		iph->tot_len = htons(skb->len - nhoff);
+		iph->tot_len = htons(tot_len);
 		ip_send_check(iph);
 		if (encap)
 			skb_reset_inner_headers(skb);
diff --git a/net/ipv4/gre_offload.c b/net/ipv4/gre_offload.c
index 7ea14ced9222..dea0390d65bb 100644
--- a/net/ipv4/gre_offload.c
+++ b/net/ipv4/gre_offload.c
@@ -85,7 +85,7 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb,
 	skb = segs;
 	do {
 		struct gre_base_hdr *greh;
-		__be32 *pcsum;
+		__sum16 *pcsum;
 
 		/* Set up inner headers if we are offloading inner checksum */
 		if (skb->ip_summed == CHECKSUM_PARTIAL) {
@@ -105,10 +105,25 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb,
 			continue;
 
 		greh = (struct gre_base_hdr *)skb_transport_header(skb);
-		pcsum = (__be32 *)(greh + 1);
+		pcsum = (__sum16 *)(greh + 1);
+
+		if (skb_is_gso(skb)) {
+			unsigned int partial_adj;
+
+			/* Adjust checksum to account for the fact that
+			 * the partial checksum is based on actual size
+			 * whereas headers should be based on MSS size.
+			 */
+			partial_adj = skb->len + skb_headroom(skb) -
+				      SKB_GSO_CB(skb)->data_offset -
+				      skb_shinfo(skb)->gso_size;
+			*pcsum = ~csum_fold((__force __wsum)htonl(partial_adj));
+		} else {
+			*pcsum = 0;
+		}
 
-		*pcsum = 0;
-		*(__sum16 *)pcsum = gso_make_checksum(skb, 0);
+		*(pcsum + 1) = 0;
+		*pcsum = gso_make_checksum(skb, 0);
 	} while ((skb = skb->next));
 out:
 	return segs;
diff --git a/net/ipv4/tcp_offload.c b/net/ipv4/tcp_offload.c
index 1a2e9957c177..4e9b8f011473 100644
--- a/net/ipv4/tcp_offload.c
+++ b/net/ipv4/tcp_offload.c
@@ -107,6 +107,12 @@ struct sk_buff *tcp_gso_segment(struct sk_buff *skb,
 		goto out;
 	}
 
+	/* GSO partial only requires splitting the frame into an MSS
+	 * multiple and possibly a remainder.  So update the mss now.
+	 */
+	if (features & NETIF_F_GSO_PARTIAL)
+		mss = skb->len - (skb->len % mss);
+
 	copy_destructor = gso_skb->destructor == tcp_wfree;
 	ooo_okay = gso_skb->ooo_okay;
 	/* All segments but the first should have ooo_okay cleared */
@@ -131,7 +137,7 @@ struct sk_buff *tcp_gso_segment(struct sk_buff *skb,
 	newcheck = ~csum_fold((__force __wsum)((__force u32)th->check +
 					       (__force u32)delta));
 
-	do {
+	while (skb->next) {
 		th->fin = th->psh = 0;
 		th->check = newcheck;
 
@@ -151,7 +157,7 @@ struct sk_buff *tcp_gso_segment(struct sk_buff *skb,
 
 		th->seq = htonl(seq);
 		th->cwr = 0;
-	} while (skb->next);
+	}
 
 	/* Following permits TCP Small Queues to work well with GSO :
 	 * The callback to TCP stack will be called at the time last frag
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
index 8a3405a80260..5fcb93269afb 100644
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
@@ -100,7 +100,7 @@ static struct sk_buff *__skb_udp_tunnel_segment(struct sk_buff *skb,
 	udp_offset = outer_hlen - tnl_hlen;
 	skb = segs;
 	do {
-		__be16 len;
+		unsigned int len;
 
 		if (remcsum)
 			skb->ip_summed = CHECKSUM_NONE;
@@ -118,14 +118,26 @@ static struct sk_buff *__skb_udp_tunnel_segment(struct sk_buff *skb,
 		skb_reset_mac_header(skb);
 		skb_set_network_header(skb, mac_len);
 		skb_set_transport_header(skb, udp_offset);
-		len = htons(skb->len - udp_offset);
+		len = skb->len - udp_offset;
 		uh = udp_hdr(skb);
-		uh->len = len;
+
+		/* If we are only performing partial GSO the inner header
+		 * will be using a length value equal to only one MSS sized
+		 * segment instead of the entire frame.
+		 */
+		if (skb_is_gso(skb)) {
+			uh->len = htons(skb_shinfo(skb)->gso_size +
+					SKB_GSO_CB(skb)->data_offset +
+					skb->head - (unsigned char *)uh);
+		} else {
+			uh->len = htons(len);
+		}
 
 		if (!need_csum)
 			continue;
 
-		uh->check = ~csum_fold(csum_add(partial, (__force __wsum)len));
+		uh->check = ~csum_fold(csum_add(partial,
+				       (__force __wsum)htonl(len)));
 
 		if (skb->encapsulation || !offload_csum) {
 			uh->check = gso_make_checksum(skb, ~uh->check);
diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c
index eeca943f12dc..d467053c226a 100644
--- a/net/ipv6/ip6_offload.c
+++ b/net/ipv6/ip6_offload.c
@@ -63,6 +63,7 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,
 	int proto;
 	struct frag_hdr *fptr;
 	unsigned int unfrag_ip6hlen;
+	unsigned int payload_len;
 	u8 *prevhdr;
 	int offset = 0;
 	bool encap, udpfrag;
@@ -117,7 +118,13 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,
 
 	for (skb = segs; skb; skb = skb->next) {
 		ipv6h = (struct ipv6hdr *)(skb_mac_header(skb) + nhoff);
-		ipv6h->payload_len = htons(skb->len - nhoff - sizeof(*ipv6h));
+		if (skb_is_gso(skb))
+			payload_len = skb_shinfo(skb)->gso_size +
+				      SKB_GSO_CB(skb)->data_offset +
+				      skb->head - (unsigned char *)(ipv6h + 1);
+		else
+			payload_len = skb->len - nhoff - sizeof(*ipv6h);
+		ipv6h->payload_len = htons(payload_len);
 		skb->network_header = (u8 *)ipv6h - skb->head;
 
 		if (udpfrag) {

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox