* [PATCH net-next 1/5] vxlan: Make VXLAN default UDP port number available for others
2014-03-10 16:48 [PATCH net-next 0/5] VXLAN offload support Shahed Shaikh
@ 2014-03-10 16:48 ` Shahed Shaikh
2014-03-10 19:43 ` Stephen Hemminger
2014-03-10 19:57 ` Or Gerlitz
2014-03-10 16:48 ` [PATCH net-next 2/5] qlcnic: Get NIC capabilities using mailbox poll mode Shahed Shaikh
` (3 subsequent siblings)
4 siblings, 2 replies; 16+ messages in thread
From: Shahed Shaikh @ 2014-03-10 16:48 UTC (permalink / raw)
To: davem; +Cc: netdev, Dept-HSGLinuxNICDev, Shahed Shaikh
From: Shahed Shaikh <shahed.shaikh@qlogic.com>
Although vxlan module has capability to notify udp ports to
other interested net devices using .ndo_add_rx_vxlan_port and
.ndo_del_rx_vxlan_port, there could be some devices which support
vxlan offload but not interested in updating udp port numbers.
This may be because some hardware do not support programming multiple
udp ports and their drivers may decide to program only default udp port
into adapter. So that adapter, at least, can do offloading for
default udp port number.
Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
---
drivers/net/vxlan.c | 6 +-----
include/net/vxlan.h | 6 ++++++
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index eb59b14..ace758f 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -71,11 +71,7 @@ struct vxlanhdr {
__be32 vx_vni;
};
-/* UDP port for VXLAN traffic.
- * The IANA assigned port is 4789, but the Linux default is 8472
- * for compatibility with early adopters.
- */
-static unsigned short vxlan_port __read_mostly = 8472;
+static unsigned short vxlan_port __read_mostly = VXLAN_DEFAULT_PORT;
module_param_named(udp_port, vxlan_port, ushort, 0444);
MODULE_PARM_DESC(udp_port, "Destination UDP port");
diff --git a/include/net/vxlan.h b/include/net/vxlan.h
index 5deef1a..4c16629 100644
--- a/include/net/vxlan.h
+++ b/include/net/vxlan.h
@@ -8,6 +8,12 @@
#define VNI_HASH_BITS 10
#define VNI_HASH_SIZE (1<<VNI_HASH_BITS)
+/* UDP port for VXLAN traffic.
+ * The IANA assigned port is 4789, but the Linux default is 8472
+ * for compatibility with early adopters.
+ */
+#define VXLAN_DEFAULT_PORT 8472
+
struct vxlan_sock;
typedef void (vxlan_rcv_t)(struct vxlan_sock *vh, struct sk_buff *skb, __be32 key);
--
1.8.3.1
^ permalink raw reply related [flat|nested] 16+ messages in thread* Re: [PATCH net-next 1/5] vxlan: Make VXLAN default UDP port number available for others
2014-03-10 16:48 ` [PATCH net-next 1/5] vxlan: Make VXLAN default UDP port number available for others Shahed Shaikh
@ 2014-03-10 19:43 ` Stephen Hemminger
2014-03-11 5:37 ` Shahed Shaikh
2014-03-10 19:57 ` Or Gerlitz
1 sibling, 1 reply; 16+ messages in thread
From: Stephen Hemminger @ 2014-03-10 19:43 UTC (permalink / raw)
To: Shahed Shaikh; +Cc: davem, netdev, Dept-HSGLinuxNICDev
On Mon, 10 Mar 2014 12:48:58 -0400
Shahed Shaikh <shahed.shaikh@qlogic.com> wrote:
> From: Shahed Shaikh <shahed.shaikh@qlogic.com>
>
> Although vxlan module has capability to notify udp ports to
> other interested net devices using .ndo_add_rx_vxlan_port and
> .ndo_del_rx_vxlan_port, there could be some devices which support
> vxlan offload but not interested in updating udp port numbers.
> This may be because some hardware do not support programming multiple
> udp ports and their drivers may decide to program only default udp port
> into adapter. So that adapter, at least, can do offloading for
> default udp port number.
>
> Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
Rather than compiling in the value, it makes more sense to make
the default port variable in vxlan driver exported. That way if user
overrides it with a module parameter the offload will still work.
^ permalink raw reply [flat|nested] 16+ messages in thread
* RE: [PATCH net-next 1/5] vxlan: Make VXLAN default UDP port number available for others
2014-03-10 19:43 ` Stephen Hemminger
@ 2014-03-11 5:37 ` Shahed Shaikh
0 siblings, 0 replies; 16+ messages in thread
From: Shahed Shaikh @ 2014-03-11 5:37 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: David Miller, netdev, Dept-HSG Linux NIC Dev
> -----Original Message-----
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Tuesday, March 11, 2014 1:13 AM
> To: Shahed Shaikh
> Cc: David Miller; netdev; Dept-HSG Linux NIC Dev
> Subject: Re: [PATCH net-next 1/5] vxlan: Make VXLAN default UDP port
> number available for others
>
> On Mon, 10 Mar 2014 12:48:58 -0400
> Shahed Shaikh <shahed.shaikh@qlogic.com> wrote:
>
> > From: Shahed Shaikh <shahed.shaikh@qlogic.com>
> >
> > Although vxlan module has capability to notify udp ports to other
> > interested net devices using .ndo_add_rx_vxlan_port and
> > .ndo_del_rx_vxlan_port, there could be some devices which support
> > vxlan offload but not interested in updating udp port numbers.
> > This may be because some hardware do not support programming multiple
> > udp ports and their drivers may decide to program only default udp
> > port into adapter. So that adapter, at least, can do offloading for
> > default udp port number.
> >
> > Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
>
> Rather than compiling in the value, it makes more sense to make the default
> port variable in vxlan driver exported. That way if user overrides it with a
> module parameter the offload will still work.
Makes sense. I will re-spin this patch to export default port variable. Thanks for the feedback.
Thanks,
Shahed
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 1/5] vxlan: Make VXLAN default UDP port number available for others
2014-03-10 16:48 ` [PATCH net-next 1/5] vxlan: Make VXLAN default UDP port number available for others Shahed Shaikh
2014-03-10 19:43 ` Stephen Hemminger
@ 2014-03-10 19:57 ` Or Gerlitz
2014-03-11 5:41 ` Shahed Shaikh
1 sibling, 1 reply; 16+ messages in thread
From: Or Gerlitz @ 2014-03-10 19:57 UTC (permalink / raw)
To: Shahed Shaikh; +Cc: David Miller, netdev@vger.kernel.org, Dept-HSGLinuxNICDev
On Mon, Mar 10, 2014 at 6:48 PM, Shahed Shaikh <shahed.shaikh@qlogic.com> wrote:
> From: Shahed Shaikh <shahed.shaikh@qlogic.com>
>
> Although vxlan module has capability to notify udp ports to
> other interested net devices using .ndo_add_rx_vxlan_port and
> .ndo_del_rx_vxlan_port, there could be some devices which support
> vxlan offload but not interested in updating udp port numbers.
> This may be because some hardware do not support programming multiple
> udp ports and their drivers may decide to program only default udp port
> into adapter. So that adapter, at least, can do offloading for
> default udp port number.
Indeed, but the default port number can be unused while another port
is used. The ndo will be invoked only behalf
of an actual instancing of udp port for listener socket (==
destination port you want the hw to indentify), what's wrong
with support this ndo also for devices that supported limited (say
one) such port?
>
> Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
> ---
> drivers/net/vxlan.c | 6 +-----
> include/net/vxlan.h | 6 ++++++
> 2 files changed, 7 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
> index eb59b14..ace758f 100644
> --- a/drivers/net/vxlan.c
> +++ b/drivers/net/vxlan.c
> @@ -71,11 +71,7 @@ struct vxlanhdr {
> __be32 vx_vni;
> };
>
> -/* UDP port for VXLAN traffic.
> - * The IANA assigned port is 4789, but the Linux default is 8472
> - * for compatibility with early adopters.
> - */
> -static unsigned short vxlan_port __read_mostly = 8472;
> +static unsigned short vxlan_port __read_mostly = VXLAN_DEFAULT_PORT;
> module_param_named(udp_port, vxlan_port, ushort, 0444);
> MODULE_PARM_DESC(udp_port, "Destination UDP port");
>
> diff --git a/include/net/vxlan.h b/include/net/vxlan.h
> index 5deef1a..4c16629 100644
> --- a/include/net/vxlan.h
> +++ b/include/net/vxlan.h
> @@ -8,6 +8,12 @@
> #define VNI_HASH_BITS 10
> #define VNI_HASH_SIZE (1<<VNI_HASH_BITS)
>
> +/* UDP port for VXLAN traffic.
> + * The IANA assigned port is 4789, but the Linux default is 8472
> + * for compatibility with early adopters.
> + */
> +#define VXLAN_DEFAULT_PORT 8472
> +
> struct vxlan_sock;
> typedef void (vxlan_rcv_t)(struct vxlan_sock *vh, struct sk_buff *skb, __be32 key);
>
> --
> 1.8.3.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 16+ messages in thread* RE: [PATCH net-next 1/5] vxlan: Make VXLAN default UDP port number available for others
2014-03-10 19:57 ` Or Gerlitz
@ 2014-03-11 5:41 ` Shahed Shaikh
2014-03-11 6:42 ` Or Gerlitz
0 siblings, 1 reply; 16+ messages in thread
From: Shahed Shaikh @ 2014-03-11 5:41 UTC (permalink / raw)
To: Or Gerlitz; +Cc: David Miller, netdev, Dept-HSG Linux NIC Dev
> -----Original Message-----
> From: Or Gerlitz [mailto:or.gerlitz@gmail.com]
> Sent: Tuesday, March 11, 2014 1:28 AM
> To: Shahed Shaikh
> Cc: David Miller; netdev; Dept-HSG Linux NIC Dev
> Subject: Re: [PATCH net-next 1/5] vxlan: Make VXLAN default UDP port
> number available for others
>
> On Mon, Mar 10, 2014 at 6:48 PM, Shahed Shaikh
> <shahed.shaikh@qlogic.com> wrote:
> > From: Shahed Shaikh <shahed.shaikh@qlogic.com>
> >
> > Although vxlan module has capability to notify udp ports to other
> > interested net devices using .ndo_add_rx_vxlan_port and
> > .ndo_del_rx_vxlan_port, there could be some devices which support
> > vxlan offload but not interested in updating udp port numbers.
> > This may be because some hardware do not support programming multiple
> > udp ports and their drivers may decide to program only default udp
> > port into adapter. So that adapter, at least, can do offloading for
> > default udp port number.
>
> Indeed, but the default port number can be unused while another port is
> used. The ndo will be invoked only behalf of an actual instancing of udp port
> for listener socket (== destination port you want the hw to indentify), what's
> wrong with support this ndo also for devices that supported limited (say
> one) such port?
If driver implements .ndo for udp port and user creates multiple vxlan device with different
udp ports, it may end up programming the udp port which may not go through the adapter
and no offload will happen. OTOH, if drive does not implement .ndo and if user is aware that driver
is capable of offloading for default port, he can at least crate vxlan device on top of qlcnic interface
with default udp port. So, there is no chance for other udp port numbers to replace default udp port and disturb offloading.
Like Stephen suggested, exporting udp port variable of vxlan driver will be more suitable approach.
Thanks,
Shahed
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 1/5] vxlan: Make VXLAN default UDP port number available for others
2014-03-11 5:41 ` Shahed Shaikh
@ 2014-03-11 6:42 ` Or Gerlitz
2014-03-11 7:22 ` Shahed Shaikh
2014-03-11 17:28 ` Joseph Gasparakis
0 siblings, 2 replies; 16+ messages in thread
From: Or Gerlitz @ 2014-03-11 6:42 UTC (permalink / raw)
To: Shahed Shaikh, Joseph Gasparakis, John Fastabend
Cc: David Miller, netdev, Dept-HSG Linux NIC Dev
On Tue, Mar 11, 2014 at 7:41 AM, Shahed Shaikh <shahed.shaikh@qlogic.com> wrote:
>> -----Original Message-----
>> From: Or Gerlitz [mailto:or.gerlitz@gmail.com]
>> Sent: Tuesday, March 11, 2014 1:28 AM
>> To: Shahed Shaikh
>> Cc: David Miller; netdev; Dept-HSG Linux NIC Dev
>> Subject: Re: [PATCH net-next 1/5] vxlan: Make VXLAN default UDP port
>> number available for others
>>
>> On Mon, Mar 10, 2014 at 6:48 PM, Shahed Shaikh
>> <shahed.shaikh@qlogic.com> wrote:
>> > From: Shahed Shaikh <shahed.shaikh@qlogic.com>
>> >
>> > Although vxlan module has capability to notify udp ports to other
>> > interested net devices using .ndo_add_rx_vxlan_port and
>> > .ndo_del_rx_vxlan_port, there could be some devices which support
>> > vxlan offload but not interested in updating udp port numbers.
>> > This may be because some hardware do not support programming multiple
>> > udp ports and their drivers may decide to program only default udp
>> > port into adapter. So that adapter, at least, can do offloading for
>> > default udp port number.
>>
>> Indeed, but the default port number can be unused while another port is
>> used. The ndo will be invoked only behalf of an actual instancing of udp port
>> for listener socket (== destination port you want the hw to indentify), what's
>> wrong with support this ndo also for devices that supported limited (say
>> one) such port?
>
>
> If driver implements .ndo for udp port and user creates multiple vxlan device with different
> udp ports, it may end up programming the udp port which may not go through the adapter
> and no offload will happen. OTOH, if drive does not implement .ndo and if user is aware that driver
> is capable of offloading for default port, he can at least crate vxlan device on top of qlcnic interface
> with default udp port. So, there is no chance for other udp port numbers to replace default udp port and disturb offloading.
I see your point, but doesn't this suggests we need to somehow enhance
the current framework to
let drivers know which vxlan traffic is expected to be received over
them according to the current routing rules?
I understand this is a bit tricky because vxlan and routing are l3
constructs while drivers deal with l2, John/Joseph -
what's your thinking here?
> Like Stephen suggested, exporting udp port variable of vxlan driver will be more suitable approach.
^ permalink raw reply [flat|nested] 16+ messages in thread
* RE: [PATCH net-next 1/5] vxlan: Make VXLAN default UDP port number available for others
2014-03-11 6:42 ` Or Gerlitz
@ 2014-03-11 7:22 ` Shahed Shaikh
2014-03-11 15:28 ` Stephen Hemminger
2014-03-11 17:28 ` Joseph Gasparakis
1 sibling, 1 reply; 16+ messages in thread
From: Shahed Shaikh @ 2014-03-11 7:22 UTC (permalink / raw)
To: Or Gerlitz, Joseph Gasparakis, John Fastabend,
Stephen Hemminger (stephen@networkplumber.org)
Cc: David Miller, netdev, Dept-HSG Linux NIC Dev
> -----Original Message-----
> From: Or Gerlitz [mailto:or.gerlitz@gmail.com]
> Sent: Tuesday, March 11, 2014 12:12 PM
> To: Shahed Shaikh; Joseph Gasparakis; John Fastabend
> Cc: David Miller; netdev; Dept-HSG Linux NIC Dev
> Subject: Re: [PATCH net-next 1/5] vxlan: Make VXLAN default UDP port
> number available for others
>
...
> >> >
> >> > Although vxlan module has capability to notify udp ports to other
> >> > interested net devices using .ndo_add_rx_vxlan_port and
> >> > .ndo_del_rx_vxlan_port, there could be some devices which support
> >> > vxlan offload but not interested in updating udp port numbers.
> >> > This may be because some hardware do not support programming
> >> > multiple udp ports and their drivers may decide to program only
> >> > default udp port into adapter. So that adapter, at least, can do
> >> > offloading for default udp port number.
> >>
> >> Indeed, but the default port number can be unused while another port
> >> is used. The ndo will be invoked only behalf of an actual instancing
> >> of udp port for listener socket (== destination port you want the hw
> >> to indentify), what's wrong with support this ndo also for devices
> >> that supported limited (say
> >> one) such port?
> >
> >
> > If driver implements .ndo for udp port and user creates multiple
> > vxlan device with different udp ports, it may end up programming the
> > udp port which may not go through the adapter and no offload will
> > happen. OTOH, if drive does not implement .ndo and if user is aware
> > that driver is capable of offloading for default port, he can at least crate
> vxlan device on top of qlcnic interface with default udp port. So, there is no
> chance for other udp port numbers to replace default udp port and disturb
> offloading.
>
> I see your point, but doesn't this suggests we need to somehow enhance
> the current framework to let drivers know which vxlan traffic is expected to
> be received over them according to the current routing rules?
Agree. Because of this limitation I used default udp port for offloading.
> I understand this is a bit tricky because vxlan and routing are l3 constructs
> while drivers deal with l2, John/Joseph - what's your thinking here?
Yes. May be John, Joseph or Stephen can suggest on this.
Thanks,
Shahed
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 1/5] vxlan: Make VXLAN default UDP port number available for others
2014-03-11 7:22 ` Shahed Shaikh
@ 2014-03-11 15:28 ` Stephen Hemminger
2014-03-12 9:44 ` Shahed Shaikh
0 siblings, 1 reply; 16+ messages in thread
From: Stephen Hemminger @ 2014-03-11 15:28 UTC (permalink / raw)
To: Shahed Shaikh
Cc: Or Gerlitz, Joseph Gasparakis, John Fastabend, David Miller,
netdev, Dept-HSG Linux NIC Dev
On Tue, 11 Mar 2014 07:22:31 +0000
Shahed Shaikh <shahed.shaikh@qlogic.com> wrote:
> > -----Original Message-----
> > From: Or Gerlitz [mailto:or.gerlitz@gmail.com]
> > Sent: Tuesday, March 11, 2014 12:12 PM
> > To: Shahed Shaikh; Joseph Gasparakis; John Fastabend
> > Cc: David Miller; netdev; Dept-HSG Linux NIC Dev
> > Subject: Re: [PATCH net-next 1/5] vxlan: Make VXLAN default UDP port
> > number available for others
> >
> ...
> > >> >
> > >> > Although vxlan module has capability to notify udp ports to other
> > >> > interested net devices using .ndo_add_rx_vxlan_port and
> > >> > .ndo_del_rx_vxlan_port, there could be some devices which support
> > >> > vxlan offload but not interested in updating udp port numbers.
> > >> > This may be because some hardware do not support programming
> > >> > multiple udp ports and their drivers may decide to program only
> > >> > default udp port into adapter. So that adapter, at least, can do
> > >> > offloading for default udp port number.
> > >>
> > >> Indeed, but the default port number can be unused while another port
> > >> is used. The ndo will be invoked only behalf of an actual instancing
> > >> of udp port for listener socket (== destination port you want the hw
> > >> to indentify), what's wrong with support this ndo also for devices
> > >> that supported limited (say
> > >> one) such port?
> > >
> > >
> > > If driver implements .ndo for udp port and user creates multiple
> > > vxlan device with different udp ports, it may end up programming the
> > > udp port which may not go through the adapter and no offload will
> > > happen. OTOH, if drive does not implement .ndo and if user is aware
> > > that driver is capable of offloading for default port, he can at least crate
> > vxlan device on top of qlcnic interface with default udp port. So, there is no
> > chance for other udp port numbers to replace default udp port and disturb
> > offloading.
> >
> > I see your point, but doesn't this suggests we need to somehow enhance
> > the current framework to let drivers know which vxlan traffic is expected to
> > be received over them according to the current routing rules?
>
> Agree. Because of this limitation I used default udp port for offloading.
>
> > I understand this is a bit tricky because vxlan and routing are l3 constructs
> > while drivers deal with l2, John/Joseph - what's your thinking here?
>
> Yes. May be John, Joseph or Stephen can suggest on this.
>
> Thanks,
> Shahed
>
Is it possible to do "lazy bind" to port, and set up offload when the
first VXLAN is created? For most user's they will use one port and multiplex
by VNI. But there maybe migration scenario's with multiple ports.
The kernel made unfortunate choice of non-standard port, and has to
stick with that. The ip command tries to nudge users to use the correct IANA
port, therefore correct offload should wait until the first tunnel is created.
^ permalink raw reply [flat|nested] 16+ messages in thread
* RE: [PATCH net-next 1/5] vxlan: Make VXLAN default UDP port number available for others
2014-03-11 15:28 ` Stephen Hemminger
@ 2014-03-12 9:44 ` Shahed Shaikh
0 siblings, 0 replies; 16+ messages in thread
From: Shahed Shaikh @ 2014-03-12 9:44 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Or Gerlitz, Joseph Gasparakis, John Fastabend, David Miller,
netdev, Dept-HSG Linux NIC Dev
> -----Original Message-----
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Tuesday, March 11, 2014 8:58 PM
> To: Shahed Shaikh
> Cc: Or Gerlitz; Joseph Gasparakis; John Fastabend; David Miller; netdev;
> Dept-HSG Linux NIC Dev
> Subject: Re: [PATCH net-next 1/5] vxlan: Make VXLAN default UDP port
> number available for others
>
...
>
> Is it possible to do "lazy bind" to port, and set up offload when the first
> VXLAN is created? For most user's they will use one port and multiplex by
> VNI. But there maybe migration scenario's with multiple ports.
>
Hi Stephen,
If I understand you comment correctly, does this mean, driver should set up offload only for first N udp ports (here N=1 in case of qlcnic) used by VXLAN driver through vxlan_get_rx_port() -> ndo_add_vxlan_port() and discard subsequent ndo_add_vxlan_port() notification for N+ udp ports?
I see similar implementation in i40e driver (N = 16).
Thanks,
Shahed
> The kernel made unfortunate choice of non-standard port, and has to stick
> with that. The ip command tries to nudge users to use the correct IANA port,
> therefore correct offload should wait until the first tunnel is created.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 1/5] vxlan: Make VXLAN default UDP port number available for others
2014-03-11 6:42 ` Or Gerlitz
2014-03-11 7:22 ` Shahed Shaikh
@ 2014-03-11 17:28 ` Joseph Gasparakis
2014-03-12 10:20 ` Shahed Shaikh
1 sibling, 1 reply; 16+ messages in thread
From: Joseph Gasparakis @ 2014-03-11 17:28 UTC (permalink / raw)
To: Or Gerlitz
Cc: Shahed Shaikh, Joseph Gasparakis, John Fastabend, David Miller,
netdev, Dept-HSG Linux NIC Dev
On Mon, 10 Mar 2014, Or Gerlitz wrote:
> On Tue, Mar 11, 2014 at 7:41 AM, Shahed Shaikh <shahed.shaikh@qlogic.com> wrote:
> >> -----Original Message-----
> >> From: Or Gerlitz [mailto:or.gerlitz@gmail.com]
> >> Sent: Tuesday, March 11, 2014 1:28 AM
> >> To: Shahed Shaikh
> >> Cc: David Miller; netdev; Dept-HSG Linux NIC Dev
> >> Subject: Re: [PATCH net-next 1/5] vxlan: Make VXLAN default UDP port
> >> number available for others
> >>
> >> On Mon, Mar 10, 2014 at 6:48 PM, Shahed Shaikh
> >> <shahed.shaikh@qlogic.com> wrote:
> >> > From: Shahed Shaikh <shahed.shaikh@qlogic.com>
> >> >
> >> > Although vxlan module has capability to notify udp ports to other
> >> > interested net devices using .ndo_add_rx_vxlan_port and
> >> > .ndo_del_rx_vxlan_port, there could be some devices which support
> >> > vxlan offload but not interested in updating udp port numbers.
> >> > This may be because some hardware do not support programming multiple
> >> > udp ports and their drivers may decide to program only default udp
> >> > port into adapter. So that adapter, at least, can do offloading for
> >> > default udp port number.
> >>
> >> Indeed, but the default port number can be unused while another port is
> >> used. The ndo will be invoked only behalf of an actual instancing of udp port
> >> for listener socket (== destination port you want the hw to indentify), what's
> >> wrong with support this ndo also for devices that supported limited (say
> >> one) such port?
> >
> >
> > If driver implements .ndo for udp port and user creates multiple vxlan device with different
> > udp ports, it may end up programming the udp port which may not go through the adapter
> > and no offload will happen. OTOH, if drive does not implement .ndo and if user is aware that driver
> > is capable of offloading for default port, he can at least crate vxlan device on top of qlcnic interface
> > with default udp port. So, there is no chance for other udp port numbers to replace default udp port and disturb offloading.
>
> I see your point, but doesn't this suggests we need to somehow enhance
> the current framework to
> let drivers know which vxlan traffic is expected to be received over
> them according to the current routing rules?
> I understand this is a bit tricky because vxlan and routing are l3
> constructs while drivers deal with l2, John/Joseph -
> what's your thinking here?
>
For the sake of simplicity: if you have say two VXLANs listening on two
different UDP ports, and a single port NIC that can only offload traffic
from one UDP port, how would you know which VXLAN is more useful to
offload? There might be traffic from the one port (and in this case it
might be the default one or not) or you might have traffic from both.
The fact is that you have a hw limitation, and you need something
to help you predict what which VXLAN you are going to have traffic from
which is not trivial at all.
Therefore even having a way to use the routing tables wouldn't help I
think.
In other words, IMHO the best option for running a NIC that can offload X
UDP ports, is to use up to X UDP ports. Anything else, requres guessing that
might not be accurate and hence can make things worse instead of better.
>
> > Like Stephen suggested, exporting udp port variable of vxlan driver will be more suitable approach.
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* RE: [PATCH net-next 1/5] vxlan: Make VXLAN default UDP port number available for others
2014-03-11 17:28 ` Joseph Gasparakis
@ 2014-03-12 10:20 ` Shahed Shaikh
0 siblings, 0 replies; 16+ messages in thread
From: Shahed Shaikh @ 2014-03-12 10:20 UTC (permalink / raw)
To: Joseph Gasparakis, Or Gerlitz
Cc: John Fastabend, David Miller, netdev, Dept-HSG Linux NIC Dev
> -----Original Message-----
> From: Joseph Gasparakis [mailto:joseph.gasparakis@intel.com]
> Sent: Tuesday, March 11, 2014 10:59 PM
> To: Or Gerlitz
> Cc: Shahed Shaikh; Joseph Gasparakis; John Fastabend; David Miller; netdev;
> Dept-HSG Linux NIC Dev
> Subject: Re: [PATCH net-next 1/5] vxlan: Make VXLAN default UDP port
> number available for others
>
>
>
...
>
> For the sake of simplicity: if you have say two VXLANs listening on two
> different UDP ports, and a single port NIC that can only offload traffic from
> one UDP port, how would you know which VXLAN is more useful to offload?
> There might be traffic from the one port (and in this case it might be the
> default one or not) or you might have traffic from both.
> The fact is that you have a hw limitation, and you need something to help
> you predict what which VXLAN you are going to have traffic from which is not
> trivial at all.
> Therefore even having a way to use the routing tables wouldn't help I think.
>
> In other words, IMHO the best option for running a NIC that can offload X
> UDP ports, is to use up to X UDP ports. Anything else, requres guessing that
> might not be accurate and hence can make things worse instead of better.
Makes sense. Thanks for your feedback Joseph.
Thanks,
Shahed
>
> >
> > > Like Stephen suggested, exporting udp port variable of vxlan driver will
> be more suitable approach.
> >
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH net-next 2/5] qlcnic: Get NIC capabilities using mailbox poll mode
2014-03-10 16:48 [PATCH net-next 0/5] VXLAN offload support Shahed Shaikh
2014-03-10 16:48 ` [PATCH net-next 1/5] vxlan: Make VXLAN default UDP port number available for others Shahed Shaikh
@ 2014-03-10 16:48 ` Shahed Shaikh
2014-03-10 16:49 ` [PATCH net-next 3/5] qlcnic: Add VXLAN Tx offload support Shahed Shaikh
` (2 subsequent siblings)
4 siblings, 0 replies; 16+ messages in thread
From: Shahed Shaikh @ 2014-03-10 16:48 UTC (permalink / raw)
To: davem; +Cc: netdev, Dept-HSGLinuxNICDev, Shahed Shaikh
From: Shahed Shaikh <shahed.shaikh@qlogic.com>
In order to enable VXLAN offload feature, we should get adapter
capabilities well before enabling mailbox command in interrupt
mode. So, issue mailbox command to get capabilities in poll mode
and get adapter's capabilities.
Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
---
drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
index 90a2dda..760e602 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
@@ -2194,6 +2194,19 @@ static int qlcnic_83xx_get_fw_info(struct qlcnic_adapter *adapter)
return err;
}
+static void qlcnic_83xx_get_nic_capability(struct qlcnic_adapter *adapter)
+{
+ struct qlcnic_info nic_info;
+
+ memset(&nic_info, 0, sizeof(struct qlcnic_info));
+ qlcnic_83xx_enable_mbx_poll(adapter);
+
+ qlcnic_83xx_clear_function_resources(adapter);
+ qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw->pci_func);
+
+ qlcnic_83xx_disable_mbx_poll(adapter);
+}
+
static void qlcnic_83xx_init_rings(struct qlcnic_adapter *adapter)
{
u8 rx_cnt = QLCNIC_DEF_SDS_RINGS;
@@ -2253,6 +2266,9 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)
if (err)
goto detach_mbx;
+ /* Get nic capabilities by issuing mailbox in poll mode */
+ qlcnic_83xx_get_nic_capability(adapter);
+
err = qlcnic_setup_intr(adapter);
if (err) {
dev_err(&adapter->pdev->dev, "Failed to setup interrupt\n");
@@ -2263,8 +2279,6 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)
if (err)
goto disable_mbx_intr;
- qlcnic_83xx_clear_function_resources(adapter);
-
INIT_DELAYED_WORK(&adapter->idc_aen_work, qlcnic_83xx_idc_aen_work);
qlcnic_83xx_initialize_nic(adapter, 1);
--
1.8.3.1
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH net-next 3/5] qlcnic: Add VXLAN Tx offload support
2014-03-10 16:48 [PATCH net-next 0/5] VXLAN offload support Shahed Shaikh
2014-03-10 16:48 ` [PATCH net-next 1/5] vxlan: Make VXLAN default UDP port number available for others Shahed Shaikh
2014-03-10 16:48 ` [PATCH net-next 2/5] qlcnic: Get NIC capabilities using mailbox poll mode Shahed Shaikh
@ 2014-03-10 16:49 ` Shahed Shaikh
2014-03-10 16:49 ` [PATCH net-next 4/5] qlcnic: Add VXLAN Rx offload support for 84xx Shahed Shaikh
2014-03-10 16:49 ` [PATCH net-next 5/5] qlcnic: Update version to 5.3.57 Shahed Shaikh
4 siblings, 0 replies; 16+ messages in thread
From: Shahed Shaikh @ 2014-03-10 16:49 UTC (permalink / raw)
To: davem; +Cc: netdev, Dept-HSGLinuxNICDev, Shahed Shaikh
From: Shahed Shaikh <shahed.shaikh@qlogic.com>
This patch adds LSO, LSO6 and Tx checksum offload support for VXLAN
encapsulated packets on 83xx/84xx series adapters.
Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
---
drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 30 +++-
.../net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 4 +
drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | 166 +++++++++++++++++----
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 11 ++
4 files changed, 182 insertions(+), 29 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index df9daa3..5c48263 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -169,11 +169,20 @@ struct cmd_desc_type0 {
__le64 addr_buffer2;
- __le16 reference_handle;
+ __le16 encap_descr; /* 15:10 offset of outer L3 header,
+ * 9:6 number of 32bit words in outer L3 header,
+ * 5 offload outer L4 checksum,
+ * 4 offload outer L3 checksum,
+ * 3 Inner L4 type, TCP=0, UDP=1,
+ * 2 Inner L3 type, IPv4=0, IPv6=1,
+ * 1 Outer L3 type,IPv4=0, IPv6=1,
+ * 0 type of encapsulation, GRE=0, VXLAN=1
+ */
__le16 mss;
u8 port_ctxid; /* 7:4 ctxid 3:0 port */
- u8 total_hdr_length; /* LSO only : MAC+IP+TCP Hdr size */
- __le16 conn_id; /* IPSec offoad only */
+ u8 hdr_length; /* LSO only : MAC+IP+TCP Hdr size */
+ u8 outer_hdr_length; /* Encapsulation only */
+ u8 rsvd1;
__le64 addr_buffer3;
__le64 addr_buffer1;
@@ -183,7 +192,9 @@ struct cmd_desc_type0 {
__le64 addr_buffer4;
u8 eth_addr[ETH_ALEN];
- __le16 vlan_TCI;
+ __le16 vlan_TCI; /* In case of encapsulation,
+ * this is for outer VLAN
+ */
} __attribute__ ((aligned(64)));
@@ -538,6 +549,8 @@ struct qlcnic_adapter_stats {
u64 txbytes;
u64 lrobytes;
u64 lso_frames;
+ u64 encap_lso_frames;
+ u64 encap_tx_csummed;
u64 xmit_on;
u64 xmit_off;
u64 skb_alloc_failure;
@@ -899,6 +912,9 @@ struct qlcnic_mac_vlan_list {
#define QLCNIC_FW_CAPABILITY_2_BEACON BIT_7
#define QLCNIC_FW_CAPABILITY_2_PER_PORT_ESWITCH_CFG BIT_9
+#define QLCNIC_83XX_FW_CAPAB_ENCAP_TX_OFFLOAD BIT_1
+#define QLCNIC_83XX_FW_CAPAB_ENCAP_CKO_OFFLOAD BIT_4
+
/* module types */
#define LINKEVENT_MODULE_NOT_PRESENT 1
#define LINKEVENT_MODULE_OPTICAL_UNKNOWN 2
@@ -1806,6 +1822,12 @@ struct qlcnic_hardware_ops {
extern struct qlcnic_nic_template qlcnic_vf_ops;
+static inline bool qlcnic_encap_tx_offload(struct qlcnic_adapter *adapter)
+{
+ return adapter->ahw->extra_capability[0] &
+ QLCNIC_83XX_FW_CAPAB_ENCAP_TX_OFFLOAD;
+}
+
static inline int qlcnic_start_firmware(struct qlcnic_adapter *adapter)
{
return adapter->nic_ops->start_firmware(adapter);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
index 1960609..dfc25f7 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
@@ -47,6 +47,10 @@ static const struct qlcnic_stats qlcnic_gstrings_stats[] = {
{"lro_pkts", QLC_SIZEOF(stats.lro_pkts), QLC_OFF(stats.lro_pkts)},
{"lrobytes", QLC_SIZEOF(stats.lrobytes), QLC_OFF(stats.lrobytes)},
{"lso_frames", QLC_SIZEOF(stats.lso_frames), QLC_OFF(stats.lso_frames)},
+ {"encap_lso_frames", QLC_SIZEOF(stats.encap_lso_frames),
+ QLC_OFF(stats.encap_lso_frames)},
+ {"encap_tx_csummed", QLC_SIZEOF(stats.encap_tx_csummed),
+ QLC_OFF(stats.encap_tx_csummed)},
{"skb_alloc_failure", QLC_SIZEOF(stats.skb_alloc_failure),
QLC_OFF(stats.skb_alloc_failure)},
{"mac_filter_limit_overrun", QLC_SIZEOF(stats.mac_filter_limit_overrun),
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
index 54ebf30..7252af9 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
@@ -13,16 +13,19 @@
#include "qlcnic.h"
-#define TX_ETHER_PKT 0x01
-#define TX_TCP_PKT 0x02
-#define TX_UDP_PKT 0x03
-#define TX_IP_PKT 0x04
-#define TX_TCP_LSO 0x05
-#define TX_TCP_LSO6 0x06
-#define TX_TCPV6_PKT 0x0b
-#define TX_UDPV6_PKT 0x0c
-#define FLAGS_VLAN_TAGGED 0x10
-#define FLAGS_VLAN_OOB 0x40
+#define QLCNIC_TX_ETHER_PKT 0x01
+#define QLCNIC_TX_TCP_PKT 0x02
+#define QLCNIC_TX_UDP_PKT 0x03
+#define QLCNIC_TX_IP_PKT 0x04
+#define QLCNIC_TX_TCP_LSO 0x05
+#define QLCNIC_TX_TCP_LSO6 0x06
+#define QLCNIC_TX_ENCAP_PKT 0x07
+#define QLCNIC_TX_ENCAP_LSO 0x08
+#define QLCNIC_TX_TCPV6_PKT 0x0b
+#define QLCNIC_TX_UDPV6_PKT 0x0c
+
+#define QLCNIC_FLAGS_VLAN_TAGGED 0x10
+#define QLCNIC_FLAGS_VLAN_OOB 0x40
#define qlcnic_set_tx_vlan_tci(cmd_desc, v) \
(cmd_desc)->vlan_TCI = cpu_to_le16(v);
@@ -364,6 +367,101 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter,
spin_unlock(&adapter->mac_learn_lock);
}
+#define QLCNIC_ENCAP_VXLAN_PKT BIT_0
+#define QLCNIC_ENCAP_OUTER_L3_IP6 BIT_1
+#define QLCNIC_ENCAP_INNER_L3_IP6 BIT_2
+#define QLCNIC_ENCAP_INNER_L4_UDP BIT_3
+#define QLCNIC_ENCAP_DO_L3_CSUM BIT_4
+#define QLCNIC_ENCAP_DO_L4_CSUM BIT_5
+
+static int qlcnic_tx_encap_pkt(struct qlcnic_adapter *adapter,
+ struct cmd_desc_type0 *first_desc,
+ struct sk_buff *skb,
+ struct qlcnic_host_tx_ring *tx_ring)
+{
+ u8 opcode = 0, inner_hdr_len = 0, outer_hdr_len = 0, total_hdr_len = 0;
+ int copied, copy_len, descr_size;
+ u32 producer = tx_ring->producer;
+ struct cmd_desc_type0 *hwdesc;
+ u16 flags = 0, encap_descr = 0;
+
+ opcode = QLCNIC_TX_ETHER_PKT;
+ encap_descr = QLCNIC_ENCAP_VXLAN_PKT;
+
+ if (skb_is_gso(skb)) {
+ inner_hdr_len = skb_inner_transport_header(skb) +
+ inner_tcp_hdrlen(skb) -
+ skb_inner_mac_header(skb);
+
+ /* VXLAN header size = 8 */
+ outer_hdr_len = skb_transport_offset(skb) + 8 +
+ sizeof(struct udphdr);
+ first_desc->outer_hdr_length = outer_hdr_len;
+ total_hdr_len = inner_hdr_len + outer_hdr_len;
+ encap_descr |= QLCNIC_ENCAP_DO_L3_CSUM |
+ QLCNIC_ENCAP_DO_L4_CSUM;
+ first_desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
+ first_desc->hdr_length = inner_hdr_len;
+
+ /* Copy inner and outer headers in Tx descriptor(s)
+ * If total_hdr_len > cmd_desc_type0, use multiple
+ * descriptors
+ */
+ copied = 0;
+ descr_size = (int)sizeof(struct cmd_desc_type0);
+ while (copied < total_hdr_len) {
+ copy_len = min(descr_size, (total_hdr_len - copied));
+ hwdesc = &tx_ring->desc_head[producer];
+ tx_ring->cmd_buf_arr[producer].skb = NULL;
+ skb_copy_from_linear_data_offset(skb, copied,
+ (char *)hwdesc,
+ copy_len);
+ copied += copy_len;
+ producer = get_next_index(producer, tx_ring->num_desc);
+ }
+
+ tx_ring->producer = producer;
+
+ /* Make sure updated tx_ring->producer is visible
+ * for qlcnic_tx_avail()
+ */
+ smp_mb();
+ adapter->stats.encap_lso_frames++;
+
+ opcode = QLCNIC_TX_ENCAP_LSO;
+ } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ if (inner_ip_hdr(skb)->version == 6) {
+ if (inner_ipv6_hdr(skb)->nexthdr == IPPROTO_UDP)
+ encap_descr |= QLCNIC_ENCAP_INNER_L4_UDP;
+ } else {
+ if (inner_ip_hdr(skb)->protocol == IPPROTO_UDP)
+ encap_descr |= QLCNIC_ENCAP_INNER_L4_UDP;
+ }
+
+ adapter->stats.encap_tx_csummed++;
+ opcode = QLCNIC_TX_ENCAP_PKT;
+ }
+
+ /* Prepare first 16 bits of byte offset 16 of Tx descriptor */
+ if (ip_hdr(skb)->version == 6)
+ encap_descr |= QLCNIC_ENCAP_OUTER_L3_IP6;
+
+ /* outer IP header's size in 32bit words size*/
+ encap_descr |= (skb_network_header_len(skb) >> 2) << 6;
+
+ /* outer IP header offset */
+ encap_descr |= skb_network_offset(skb) << 10;
+ first_desc->encap_descr = cpu_to_le16(encap_descr);
+
+ first_desc->tcp_hdr_offset = skb_inner_transport_header(skb) -
+ skb->data;
+ first_desc->ip_hdr_offset = skb_inner_network_offset(skb);
+
+ qlcnic_set_tx_flags_opcode(first_desc, flags, opcode);
+
+ return 0;
+}
+
static int qlcnic_tx_pkt(struct qlcnic_adapter *adapter,
struct cmd_desc_type0 *first_desc, struct sk_buff *skb,
struct qlcnic_host_tx_ring *tx_ring)
@@ -378,11 +476,11 @@ static int qlcnic_tx_pkt(struct qlcnic_adapter *adapter,
if (protocol == ETH_P_8021Q) {
vh = (struct vlan_ethhdr *)skb->data;
- flags = FLAGS_VLAN_TAGGED;
+ flags = QLCNIC_FLAGS_VLAN_TAGGED;
vlan_tci = ntohs(vh->h_vlan_TCI);
protocol = ntohs(vh->h_vlan_encapsulated_proto);
} else if (vlan_tx_tag_present(skb)) {
- flags = FLAGS_VLAN_OOB;
+ flags = QLCNIC_FLAGS_VLAN_OOB;
vlan_tci = vlan_tx_tag_get(skb);
}
if (unlikely(adapter->tx_pvid)) {
@@ -391,7 +489,7 @@ static int qlcnic_tx_pkt(struct qlcnic_adapter *adapter,
if (vlan_tci && (adapter->flags & QLCNIC_TAGGING_ENABLED))
goto set_flags;
- flags = FLAGS_VLAN_OOB;
+ flags = QLCNIC_FLAGS_VLAN_OOB;
vlan_tci = adapter->tx_pvid;
}
set_flags:
@@ -402,25 +500,26 @@ set_flags:
flags |= BIT_0;
memcpy(&first_desc->eth_addr, skb->data, ETH_ALEN);
}
- opcode = TX_ETHER_PKT;
+ opcode = QLCNIC_TX_ETHER_PKT;
if (skb_is_gso(skb)) {
hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
first_desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
- first_desc->total_hdr_length = hdr_len;
- opcode = (protocol == ETH_P_IPV6) ? TX_TCP_LSO6 : TX_TCP_LSO;
+ first_desc->hdr_length = hdr_len;
+ opcode = (protocol == ETH_P_IPV6) ? QLCNIC_TX_TCP_LSO6 :
+ QLCNIC_TX_TCP_LSO;
/* For LSO, we need to copy the MAC/IP/TCP headers into
* the descriptor ring */
copied = 0;
offset = 2;
- if (flags & FLAGS_VLAN_OOB) {
- first_desc->total_hdr_length += VLAN_HLEN;
+ if (flags & QLCNIC_FLAGS_VLAN_OOB) {
+ first_desc->hdr_length += VLAN_HLEN;
first_desc->tcp_hdr_offset = VLAN_HLEN;
first_desc->ip_hdr_offset = VLAN_HLEN;
/* Only in case of TSO on vlan device */
- flags |= FLAGS_VLAN_TAGGED;
+ flags |= QLCNIC_FLAGS_VLAN_TAGGED;
/* Create a TSO vlan header template for firmware */
hwdesc = &tx_ring->desc_head[producer];
@@ -464,16 +563,16 @@ set_flags:
l4proto = ip_hdr(skb)->protocol;
if (l4proto == IPPROTO_TCP)
- opcode = TX_TCP_PKT;
+ opcode = QLCNIC_TX_TCP_PKT;
else if (l4proto == IPPROTO_UDP)
- opcode = TX_UDP_PKT;
+ opcode = QLCNIC_TX_UDP_PKT;
} else if (protocol == ETH_P_IPV6) {
l4proto = ipv6_hdr(skb)->nexthdr;
if (l4proto == IPPROTO_TCP)
- opcode = TX_TCPV6_PKT;
+ opcode = QLCNIC_TX_TCPV6_PKT;
else if (l4proto == IPPROTO_UDP)
- opcode = TX_UDPV6_PKT;
+ opcode = QLCNIC_TX_UDPV6_PKT;
}
}
first_desc->tcp_hdr_offset += skb_transport_offset(skb);
@@ -563,6 +662,8 @@ netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
struct ethhdr *phdr;
int i, k, frag_count, delta = 0;
u32 producer, num_txd;
+ u16 protocol;
+ bool l4_is_udp = false;
if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
netif_tx_stop_all_queues(netdev);
@@ -653,8 +754,23 @@ netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
tx_ring->producer = get_next_index(producer, num_txd);
smp_mb();
- if (unlikely(qlcnic_tx_pkt(adapter, first_desc, skb, tx_ring)))
- goto unwind_buff;
+ protocol = ntohs(skb->protocol);
+ if (protocol == ETH_P_IP)
+ l4_is_udp = ip_hdr(skb)->protocol == IPPROTO_UDP;
+ else if (protocol == ETH_P_IPV6)
+ l4_is_udp = ipv6_hdr(skb)->nexthdr == IPPROTO_UDP;
+
+ /* Check if it is a VXLAN packet */
+ if (!skb->encapsulation || !l4_is_udp ||
+ !qlcnic_encap_tx_offload(adapter)) {
+ if (unlikely(qlcnic_tx_pkt(adapter, first_desc, skb,
+ tx_ring)))
+ goto unwind_buff;
+ } else {
+ if (unlikely(qlcnic_tx_encap_pkt(adapter, first_desc,
+ skb, tx_ring)))
+ goto unwind_buff;
+ }
if (adapter->drv_mac_learn)
qlcnic_send_filter(adapter, first_desc, skb);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index a335472..3564886 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -2204,6 +2204,17 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev,
if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)
netdev->features |= NETIF_F_LRO;
+ if (qlcnic_encap_tx_offload(adapter)) {
+ netdev->features |= NETIF_F_GSO_UDP_TUNNEL;
+
+ /* encapsulation Tx offload supported by Adapter */
+ netdev->hw_enc_features = NETIF_F_IP_CSUM |
+ NETIF_F_GSO_UDP_TUNNEL |
+ NETIF_F_TSO |
+ NETIF_F_TSO6 |
+ NETIF_F_SG;
+ }
+
netdev->hw_features = netdev->features;
netdev->priv_flags |= IFF_UNICAST_FLT;
netdev->irq = adapter->msix_entries[0].vector;
--
1.8.3.1
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH net-next 4/5] qlcnic: Add VXLAN Rx offload support for 84xx
2014-03-10 16:48 [PATCH net-next 0/5] VXLAN offload support Shahed Shaikh
` (2 preceding siblings ...)
2014-03-10 16:49 ` [PATCH net-next 3/5] qlcnic: Add VXLAN Tx offload support Shahed Shaikh
@ 2014-03-10 16:49 ` Shahed Shaikh
2014-03-10 16:49 ` [PATCH net-next 5/5] qlcnic: Update version to 5.3.57 Shahed Shaikh
4 siblings, 0 replies; 16+ messages in thread
From: Shahed Shaikh @ 2014-03-10 16:49 UTC (permalink / raw)
To: davem; +Cc: netdev, Dept-HSGLinuxNICDev, Shahed Shaikh
From: Shahed Shaikh <shahed.shaikh@qlogic.com>
This patch adds Rx checksum offload support for VXLAN over 84xx
series adapters.
Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
---
drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 8 +++++++
.../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 27 +++++++++++++++-------
.../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | 3 ++-
.../net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 25 ++++++++++++++++++++
.../net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 2 ++
drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h | 1 +
drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | 13 +++++++++++
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 3 +++
8 files changed, 73 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index 5c48263..cf5a186 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -551,6 +551,7 @@ struct qlcnic_adapter_stats {
u64 lso_frames;
u64 encap_lso_frames;
u64 encap_tx_csummed;
+ u64 encap_rx_csummed;
u64 xmit_on;
u64 xmit_off;
u64 skb_alloc_failure;
@@ -912,6 +913,7 @@ struct qlcnic_mac_vlan_list {
#define QLCNIC_FW_CAPABILITY_2_BEACON BIT_7
#define QLCNIC_FW_CAPABILITY_2_PER_PORT_ESWITCH_CFG BIT_9
+#define QLCNIC_83XX_FW_CAPAB_ENCAP_RX_OFFLOAD BIT_0
#define QLCNIC_83XX_FW_CAPAB_ENCAP_TX_OFFLOAD BIT_1
#define QLCNIC_83XX_FW_CAPAB_ENCAP_CKO_OFFLOAD BIT_4
@@ -1828,6 +1830,12 @@ static inline bool qlcnic_encap_tx_offload(struct qlcnic_adapter *adapter)
QLCNIC_83XX_FW_CAPAB_ENCAP_TX_OFFLOAD;
}
+static inline bool qlcnic_encap_rx_offload(struct qlcnic_adapter *adapter)
+{
+ return adapter->ahw->extra_capability[0] &
+ QLCNIC_83XX_FW_CAPAB_ENCAP_RX_OFFLOAD;
+}
+
static inline int qlcnic_start_firmware(struct qlcnic_adapter *adapter)
{
return adapter->nic_ops->start_firmware(adapter);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index 0f39778e..06a84a8 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -12,6 +12,7 @@
#include <linux/ethtool.h>
#include <linux/interrupt.h>
#include <linux/aer.h>
+#include <net/vxlan.h>
static void __qlcnic_83xx_process_aen(struct qlcnic_adapter *);
static int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *, u8);
@@ -77,7 +78,7 @@ static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
{QLCNIC_CMD_GET_PORT_CONFIG, 2, 2},
{QLCNIC_CMD_GET_LINK_STATUS, 2, 4},
{QLCNIC_CMD_IDC_ACK, 5, 1},
- {QLCNIC_CMD_INIT_NIC_FUNC, 2, 1},
+ {QLCNIC_CMD_INIT_NIC_FUNC, 3, 1},
{QLCNIC_CMD_STOP_NIC_FUNC, 2, 1},
{QLCNIC_CMD_SET_LED_CONFIG, 5, 1},
{QLCNIC_CMD_GET_LED_CONFIG, 1, 5},
@@ -87,6 +88,7 @@ static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
{QLCNIC_CMD_BC_EVENT_SETUP, 2, 1},
{QLCNIC_CMD_DCB_QUERY_CAP, 1, 2},
{QLCNIC_CMD_DCB_QUERY_PARAM, 1, 50},
+ {QLCNIC_CMD_SET_INGRESS_ENCAP, 2, 1},
};
const u32 qlcnic_83xx_ext_reg_tbl[] = {
@@ -1567,25 +1569,34 @@ int qlcnic_83xx_set_led(struct net_device *netdev,
return err;
}
+#define QLC_83XX_ENCAP_TYPE_VXLAN BIT_1
+#define QLC_83XX_MATCH_ENCAP_ID BIT_2
+#define QLC_83XX_SET_VXLAN_UDP_DPORT BIT_3
+#define QLC_83XX_VXLAN_UDP_DPORT ((VXLAN_DEFAULT_PORT & 0xffff) << 16)
+
void qlcnic_83xx_initialize_nic(struct qlcnic_adapter *adapter, int enable)
{
struct qlcnic_cmd_args cmd;
+ u32 op_type;
int status;
if (qlcnic_sriov_vf_check(adapter))
return;
- if (enable)
- status = qlcnic_alloc_mbx_args(&cmd, adapter,
- QLCNIC_CMD_INIT_NIC_FUNC);
- else
- status = qlcnic_alloc_mbx_args(&cmd, adapter,
- QLCNIC_CMD_STOP_NIC_FUNC);
+ op_type = enable ? QLCNIC_CMD_INIT_NIC_FUNC : QLCNIC_CMD_STOP_NIC_FUNC;
+ status = qlcnic_alloc_mbx_args(&cmd, adapter, op_type);
if (status)
return;
- cmd.req.arg[1] = QLC_REGISTER_LB_IDC | QLC_INIT_FW_RESOURCES;
+ if (enable && qlcnic_encap_rx_offload(adapter)) {
+ cmd.req.arg[1] = QLC_83XX_MULTI_TENANCY_INFO;
+ cmd.req.arg[2] = QLC_83XX_ENCAP_TYPE_VXLAN |
+ QLC_83XX_SET_VXLAN_UDP_DPORT |
+ QLC_83XX_VXLAN_UDP_DPORT;
+ }
+
+ cmd.req.arg[1] |= QLC_REGISTER_LB_IDC | QLC_INIT_FW_RESOURCES;
if (adapter->dcb)
cmd.req.arg[1] |= QLC_REGISTER_DCB_AEN;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
index 81c1889..88d809c 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
@@ -528,8 +528,9 @@ enum qlc_83xx_ext_regs {
};
/* Initialize/Stop NIC command bit definitions */
-#define QLC_REGISTER_DCB_AEN BIT_1
#define QLC_REGISTER_LB_IDC BIT_0
+#define QLC_REGISTER_DCB_AEN BIT_1
+#define QLC_83XX_MULTI_TENANCY_INFO BIT_29
#define QLC_INIT_FW_RESOURCES BIT_31
/* 83xx funcitons */
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
index 760e602..fea4157 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
@@ -2225,6 +2225,28 @@ static void qlcnic_83xx_init_rings(struct qlcnic_adapter *adapter)
qlcnic_set_sds_ring_count(adapter, rx_cnt);
}
+#define QLCNIC_ENABLE_INGRESS_ENCAP_PARSING 1
+
+static void qlcnic_83xx_set_ingress_encap(struct qlcnic_adapter *adapter)
+{
+ struct qlcnic_cmd_args cmd;
+ int ret;
+
+ ret = qlcnic_alloc_mbx_args(&cmd, adapter,
+ QLCNIC_CMD_SET_INGRESS_ENCAP);
+ if (ret)
+ return;
+
+ /* Enable encapsulation parsing */
+ cmd.req.arg[1] = QLCNIC_ENABLE_INGRESS_ENCAP_PARSING;
+ ret = qlcnic_issue_cmd(adapter, &cmd);
+ if (ret)
+ dev_err(&adapter->pdev->dev,
+ "Failed to enable encapulation parsing\n");
+
+ qlcnic_free_mbx_args(&cmd);
+}
+
int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)
{
struct qlcnic_hardware_context *ahw = adapter->ahw;
@@ -2283,6 +2305,9 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)
qlcnic_83xx_initialize_nic(adapter, 1);
+ if (qlcnic_encap_rx_offload(adapter))
+ qlcnic_83xx_set_ingress_encap(adapter);
+
/* Configure default, SR-IOV or Virtual NIC mode of operation */
err = qlcnic_83xx_configure_opmode(adapter);
if (err)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
index dfc25f7..5bacf52 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
@@ -51,6 +51,8 @@ static const struct qlcnic_stats qlcnic_gstrings_stats[] = {
QLC_OFF(stats.encap_lso_frames)},
{"encap_tx_csummed", QLC_SIZEOF(stats.encap_tx_csummed),
QLC_OFF(stats.encap_tx_csummed)},
+ {"encap_rx_csummed", QLC_SIZEOF(stats.encap_rx_csummed),
+ QLC_OFF(stats.encap_rx_csummed)},
{"skb_alloc_failure", QLC_SIZEOF(stats.skb_alloc_failure),
QLC_OFF(stats.skb_alloc_failure)},
{"mac_filter_limit_overrun", QLC_SIZEOF(stats.mac_filter_limit_overrun),
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h
index 576b301..cbe2399 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h
@@ -98,6 +98,7 @@ enum qlcnic_regs {
#define QLCNIC_CMD_GET_LINK_EVENT 0x48
#define QLCNIC_CMD_CONFIGURE_MAC_RX_MODE 0x49
#define QLCNIC_CMD_CONFIGURE_HW_LRO 0x4A
+#define QLCNIC_CMD_SET_INGRESS_ENCAP 0x4E
#define QLCNIC_CMD_INIT_NIC_FUNC 0x60
#define QLCNIC_CMD_STOP_NIC_FUNC 0x61
#define QLCNIC_CMD_IDC_ACK 0x63
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
index 7252af9..173b3d1 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
@@ -1703,6 +1703,13 @@ static inline int qlcnic_83xx_is_lb_pkt(u64 sts_data, int lro_pkt)
return (sts_data & QLC_83XX_NORMAL_LB_PKT) ? 1 : 0;
}
+#define QLCNIC_ENCAP_LENGTH_MASK 0x7f
+
+static inline u8 qlcnic_encap_length(u64 sts_data)
+{
+ return sts_data & QLCNIC_ENCAP_LENGTH_MASK;
+}
+
static struct qlcnic_rx_buffer *
qlcnic_83xx_process_rcv(struct qlcnic_adapter *adapter,
struct qlcnic_host_sds_ring *sds_ring,
@@ -1753,6 +1760,12 @@ qlcnic_83xx_process_rcv(struct qlcnic_adapter *adapter,
skb->protocol = eth_type_trans(skb, netdev);
+ if (qlcnic_encap_length(sts_data[1]) &&
+ skb->ip_summed == CHECKSUM_UNNECESSARY) {
+ skb->encapsulation = 1;
+ adapter->stats.encap_rx_csummed++;
+ }
+
if (vid != 0xffff)
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vid);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 3564886..d8d03db 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -2215,6 +2215,9 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev,
NETIF_F_SG;
}
+ if (qlcnic_encap_rx_offload(adapter))
+ netdev->hw_enc_features |= NETIF_F_RXCSUM;
+
netdev->hw_features = netdev->features;
netdev->priv_flags |= IFF_UNICAST_FLT;
netdev->irq = adapter->msix_entries[0].vector;
--
1.8.3.1
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH net-next 5/5] qlcnic: Update version to 5.3.57
2014-03-10 16:48 [PATCH net-next 0/5] VXLAN offload support Shahed Shaikh
` (3 preceding siblings ...)
2014-03-10 16:49 ` [PATCH net-next 4/5] qlcnic: Add VXLAN Rx offload support for 84xx Shahed Shaikh
@ 2014-03-10 16:49 ` Shahed Shaikh
4 siblings, 0 replies; 16+ messages in thread
From: Shahed Shaikh @ 2014-03-10 16:49 UTC (permalink / raw)
To: davem; +Cc: netdev, Dept-HSGLinuxNICDev, Shahed Shaikh
From: Shahed Shaikh <shahed.shaikh@qlogic.com>
Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
---
drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index cf5a186..6789cca 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -38,8 +38,8 @@
#define _QLCNIC_LINUX_MAJOR 5
#define _QLCNIC_LINUX_MINOR 3
-#define _QLCNIC_LINUX_SUBVERSION 56
-#define QLCNIC_LINUX_VERSIONID "5.3.56"
+#define _QLCNIC_LINUX_SUBVERSION 57
+#define QLCNIC_LINUX_VERSIONID "5.3.57"
#define QLCNIC_DRV_IDC_VER 0x01
#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\
(_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
--
1.8.3.1
^ permalink raw reply related [flat|nested] 16+ messages in thread