Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH v2] ethernet: arc: Add support for Rockchip SoC layer device tree bindings
From: Heiko Stübner @ 2014-08-27 20:19 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: Romain Perier, linux-rockchip, linux-arm-kernel, netdev
In-Reply-To: <3619843.a6HHkMsuOu@wuerfel>

Am Mittwoch, 27. August 2014, 22:11:29 schrieb Arnd Bergmann:
> On Wednesday 27 August 2014 06:55:27 Romain Perier wrote:
> > This patch defines a platform glue layer for Rockchip SoCs which
> > support arc-emac driver. It ensures that regulator for the rmii is on
> > before trying to connect to the ethernet controller. It applies right
> > speed and mode changes to the grf when ethernet settings change.
> > 
> > Signed-off-by: Romain Perier <romain.perier@gmail.com>
> > ---
> > 
> >  drivers/net/ethernet/arc/Kconfig         |  15 +++
> >  drivers/net/ethernet/arc/Makefile        |   1 +
> >  drivers/net/ethernet/arc/emac.h          |   2 +
> >  drivers/net/ethernet/arc/emac_main.c     |   2 +
> >  drivers/net/ethernet/arc/emac_rockchip.c | 224
> >  +++++++++++++++++++++++++++++++ 5 files changed, 244 insertions(+)
> >  create mode 100644 drivers/net/ethernet/arc/emac_rockchip.c
> > 
> > diff --git a/drivers/net/ethernet/arc/Kconfig
> > b/drivers/net/ethernet/arc/Kconfig index 89e04fd..6d96a82 100644
> > --- a/drivers/net/ethernet/arc/Kconfig
> > +++ b/drivers/net/ethernet/arc/Kconfig
> > @@ -32,4 +32,19 @@ config ARC_EMAC
> > 
> >  	  non-standard on-chip ethernet device ARC EMAC 10/100 is used.
> >  	  Say Y here if you have such a board.  If unsure, say N.
> > 
> > +config EMAC_ROCKCHIP
> > +       tristate "Rockchip EMAC support"
> > +       select ARC_EMAC_CORE
> > +       depends on OF_IRQ
> > +       depends on OF_NET
> > +       depends on ARCH_ROCKCHIP
> > +       depends on REGULATOR_ACT8865
> > +       depends on SMSC_PHY
> > +       depends on MFD_SYSCON
> 
> You should generally not add 'depends on' for specific drivers out
> of a subsystems. Just list the build-time dependencies, like
> 
> 	depends on OF_IRQ && OF_NET && PHYLIB && REGULATOR && MFD_SYSCON

in this case even MFD_SYSCON can go away, as the syscon functions provide 
stubs for !MFD_SYSCON .


[...]

> > +	rate = 50000000;
> 
> Where does this number come from?

The RMII interface needs always a rate of 50MHz ... my questions would be why 
the 50000000 are not in the clk_set_rate directly and need an extra var :-)



Heiko

^ permalink raw reply

* Re: [PATCH v2] ethernet: arc: Add support for Rockchip SoC layer device tree bindings
From: Arnd Bergmann @ 2014-08-27 20:11 UTC (permalink / raw)
  To: Romain Perier; +Cc: heiko, linux-rockchip, linux-arm-kernel, netdev
In-Reply-To: <1409122527-17673-1-git-send-email-romain.perier@gmail.com>

On Wednesday 27 August 2014 06:55:27 Romain Perier wrote:
> This patch defines a platform glue layer for Rockchip SoCs which
> support arc-emac driver. It ensures that regulator for the rmii is on
> before trying to connect to the ethernet controller. It applies right
> speed and mode changes to the grf when ethernet settings change.
> 
> Signed-off-by: Romain Perier <romain.perier@gmail.com>
> ---
>  drivers/net/ethernet/arc/Kconfig         |  15 +++
>  drivers/net/ethernet/arc/Makefile        |   1 +
>  drivers/net/ethernet/arc/emac.h          |   2 +
>  drivers/net/ethernet/arc/emac_main.c     |   2 +
>  drivers/net/ethernet/arc/emac_rockchip.c | 224 +++++++++++++++++++++++++++++++
>  5 files changed, 244 insertions(+)
>  create mode 100644 drivers/net/ethernet/arc/emac_rockchip.c
> 
> diff --git a/drivers/net/ethernet/arc/Kconfig b/drivers/net/ethernet/arc/Kconfig
> index 89e04fd..6d96a82 100644
> --- a/drivers/net/ethernet/arc/Kconfig
> +++ b/drivers/net/ethernet/arc/Kconfig
> @@ -32,4 +32,19 @@ config ARC_EMAC
>  	  non-standard on-chip ethernet device ARC EMAC 10/100 is used.
>  	  Say Y here if you have such a board.  If unsure, say N.
>  
> +config EMAC_ROCKCHIP
> +       tristate "Rockchip EMAC support"
> +       select ARC_EMAC_CORE
> +       depends on OF_IRQ
> +       depends on OF_NET
> +       depends on ARCH_ROCKCHIP
> +       depends on REGULATOR_ACT8865
> +       depends on SMSC_PHY
> +       depends on MFD_SYSCON

You should generally not add 'depends on' for specific drivers out
of a subsystems. Just list the build-time dependencies, like

	depends on OF_IRQ && OF_NET && PHYLIB && REGULATOR && MFD_SYSCON

You can add the ARCH_ROCKCHIPS part if you think that's valuable, but
add an '|| COMPILE_TEST' so it's possible to still build it elsewhere.

> +#define GRF_MODE_MII   BIT(0)
> +#define GRF_MODE_RMII  0x0
> +#define GRF_SPEED_10M  0x0
> +#define GRF_SPEED_100M BIT(1)

Just use 0x... for consistency for all of these.

> +static const struct of_device_id emac_rockchip_dt_ids[];

Can you rearrange it to avoid the forward declaration?

> +       priv->soc_data = (struct emac_rockchip_soc_data *)match->data;

This cast turns a 'const' pointer into a non-const pointer, which is
bad. Mark the soc_data pointer as const as well so you can remove the
cast here.

> +	/* write-enable bits */
> +	data = BIT(16) | BIT(17);
> +
> +	data |= GRF_SPEED_100M;
> +	data |= GRF_MODE_RMII;

If you have macros for some bits, you should have them for all of them.

> +	rate = 50000000;

Where does this number come from?

> +static const struct of_device_id emac_rockchip_dt_ids[] = {
> +	{ .compatible = "rockchip,rk3066-emac", .data = (void *)&emac_rockchip_dt_data[0]},
> +	{ .compatible = "rockchip,rk3188-emac", .data = (void *)&emac_rockchip_dt_data[1]},
> +	{ /* Sentinel */ }
> +};

This cast is harmless, but I'd remove it as well.

	Arnd

^ permalink raw reply

* Re: Sending undersized ARP packets with VXLAN L3 interface
From: Martin Rusko @ 2014-08-27 20:01 UTC (permalink / raw)
  To: Vlad Yasevich; +Cc: Stephen Hemminger, Cong Wang, netdev
In-Reply-To: <53FE2738.30702@gmail.com>

On Wed, Aug 27, 2014 at 8:45 PM, Vlad Yasevich <vyasevich@gmail.com> wrote:
> On 08/27/2014 02:42 PM, Stephen Hemminger wrote:
>> On Wed, 27 Aug 2014 13:52:03 -0400
>> Vlad Yasevich <vyasevich@gmail.com> wrote:
>>
>>> On 08/27/2014 01:28 PM, Cong Wang wrote:
>>>> On Wed, Aug 27, 2014 at 10:06 AM, Martin Rusko <martin.rusko@gmail.com> wrote:
>>>>>
>>>>> I'm wondering, where is the proper place to fix this. Should
>>>>> arp_create() function allocate skb big enough to produce ethernet
>>>>> frame with at least minimum size? Or is it somewhere in NIC drivers
>>>>> where small packets are padded with zeros?
>>>>
>>>> Drivers do that, for example e1000:
>>>>
>>>>         /* On PCI/PCI-X HW, if packet size is less than ETH_ZLEN,
>>>>          * packets may get corrupted during padding by HW.
>>>>          * To WA this issue, pad all small packets manually.
>>>>          */
>>>>         if (skb->len < ETH_ZLEN) {
>>>>                 if (skb_pad(skb, ETH_ZLEN - skb->len))
>>>>                         return NETDEV_TX_OK;
>>>>                 skb->len = ETH_ZLEN;
>>>>                 skb_set_tail_pointer(skb, ETH_ZLEN);
>>>>         }
>>>
>>>
>>> I think vxlan needs something like this:
>>>
>>> From: Vladislav Yasevich <vyasevich@gmail.com>
>>> Date: Wed, 27 Aug 2014 13:39:32 -0400
>>> Subject: [PATCH] vxlan: Pad short ethernet frames.
>>>
>>> If sending short ethernet frames from the vxlan device, pad
>>> them to minimum size so they can be forwarded after decapsulation.
>>>
>>> Reported-by: Martin Rusko <martin.rusko@gmail.com>
>>> Signed-off-by: Vladislav Yasevich <vyasevich@gmail.com>
>>> ---
>>>  drivers/net/vxlan.c | 8 ++++++++
>>>  1 file changed, 8 insertions(+)
>>>
>>> diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
>>> index 1fb7b37..48267d4 100644
>>> --- a/drivers/net/vxlan.c
>>> +++ b/drivers/net/vxlan.c
>>> @@ -1939,6 +1939,14 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct
>>> net_device *dev)
>>>  #endif
>>>      }
>>>
>>> +    /* Pad short frames so they can be forwarded after decapsulation */
>>> +    if (skb->len < ETH_ZLEN) {
>>> +            if (skb_pad(skb, ETH_ZLEN - skb->len))
>>> +                    return NETDEV_TX_OK;
>>> +            skb->len = ETH_ZLEN;
>>> +            skb_set_tail_pointer(skb, ETH_ZLEN);
>>> +    }
>>> +
>>>      f = vxlan_find_mac(vxlan, eth->h_dest);
>>>      did_rsc = false;
>>>
>>
>> No. The short frame is perfectly valid, over the VXLAN.
>> The system doing the decap and forwarding should be where any padding is added if necessary.
>>

Well, RFC 7348 is not dealing with padding at all. Both deployment
scenarios listed in RFC, as well as most of the existing real life
deployments today (in my opinion) use VXLAN for bridged traffic. In
other words, frame encapsulated by VTEP is received first over some
ethernet interface (physical or virtual) which implies that the frame
is at least 64 bytes long already.

Perhaps we're going to see more VXLAN interfaces in L3 mode, yet it
might be safer not to count on receiving VTEP doing the right thing
(pad small packets with zeros).

>
> If that's the case, then Martin is most likely seeing a HW bug on the switch.
> I wonder how common such a bug might be?
>
> -vlad
>

I see this on Vmware distributed virtual switch. Perhaps soon I will
be able to test it against HP 5930 switch. I'm going to try how Linux
bridge copes with it, now.

Many thanks for the patch anyway!

Regards,
Martin

^ permalink raw reply

* Re: [PATCH RFC v7 net-next 00/28] BPF syscall
From: Alexei Starovoitov @ 2014-08-27 19:37 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: Andy Lutomirski, Daniel Borkmann, H. Peter Anvin, Andrew Morton,
	Chema Gonzalez, Namhyung Kim, Eric Dumazet, David S. Miller,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Brendan Gregg, Linus Torvalds, Steven Rostedt,
	Network Development, Peter Zijlstra, Kees Cook, Linux API,
	Ingo Molnar
In-Reply-To: <20140827121801.3bfd916e@urahara>

On Wed, Aug 27, 2014 at 12:18 PM, Stephen Hemminger
<stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ@public.gmane.org> wrote:
> Something in man page format similar to FreeBSD man page:
>  http://www.freebsd.org/cgi/man.cgi?bpf(4)
>
> would be more readable and reviewable.

Ok. will chop it into smallest diff possible and will add a doc
for syscall only. I guess the problem is that we have too many
docs now that talk about everything.

^ permalink raw reply

* Re: [PATCH RFC v7 net-next 00/28] BPF syscall
From: Daniel Borkmann @ 2014-08-27 19:35 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: Andy Lutomirski, Alexei Starovoitov, H. Peter Anvin,
	Andrew Morton, Chema Gonzalez, Namhyung Kim, Eric Dumazet,
	David S. Miller,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Brendan Gregg, Linus Torvalds, Steven Rostedt,
	Network Development, Peter Zijlstra, Kees Cook, Linux API,
	Ingo Molnar
In-Reply-To: <20140827121801.3bfd916e@urahara>

On 08/27/2014 09:18 PM, Stephen Hemminger wrote:
> Something in man page format similar to FreeBSD man page:
>   http://www.freebsd.org/cgi/man.cgi?bpf(4)
>
> would be more readable and reviewable.

I think at some point, we could perhaps do a section 7 page
with a general overview of the engine and where it can be
applied, and let the syscall page partially refer to it so
that it doesn't get too long. So far, we tried to squeeze
everything into Documentation/networking/filter.txt, and that
itself is quite long already.

^ permalink raw reply

* Re: [PATCH 0/2] Get rid of ndo_xmit_flush
From: Tom Herbert @ 2014-08-27 19:31 UTC (permalink / raw)
  To: Cong Wang
  Cc: David Miller, netdev, Jamal Hadi Salim, Hannes Frederic Sowa,
	Eric Dumazet, Jeff Kirsher, Rusty Russell, Daniel Borkmann,
	brouer
In-Reply-To: <CAHA+R7MJX3Du8ggOo2GqGA4rXvY30YOpCFqS4PBN2ZNE=kwKuA@mail.gmail.com>

On Wed, Aug 27, 2014 at 11:28 AM, Cong Wang <cwang@twopensource.com> wrote:
> On Mon, Aug 25, 2014 at 4:34 PM, David Miller <davem@davemloft.net> wrote:
>>
>> Given Jesper's performance numbers, it's not the way to go.
>>
>> Instead, go with a signalling scheme via new boolean skb->xmit_more.
>>
>> This has several advantages:
>>
>> 1) Nearly trivial driver support, just protect the tail pointer
>>    update with the skb->xmit_more check.
>>
>> 2) No extra indirect calls in the non-deferral cases.
>>
>
> First of all, I missed your discussion at kernel summit.
>
> Second of all, I am not familiar with hardware NIC drivers.
>
> But for me, it looks like you are trying to pend some more packets
> in a TX queue until the driver decides to flush them all in one shot.
> So if that is true, doesn't this mean the latency of first packet pending
> in this queue will increase and network traffic will be more bursty for
> the receiver??
>
I suspect this won't be an big issue. The dequeue is still work
conserving and BQL limit already ensures that HW queue doesn't drain
completely when packets are pending in the qdisc-- I doubt this will
increase BQL limits, but that should be verified. We might see some
latency increase for a batch sent on an idle link (possible with
GSO)-- if this is a concern we could arrange flush on sending packets
on idle links.

> Also, even if this is a cool feature in hardware driver, doesn't it make
> sense to allow users to disable it with ethtool?
>
> It looks like this is still WIP, since no one really sets ->xmit_more to 1
> in the code.
>
> Thanks.

^ permalink raw reply

* Re: [PATCH RFC v7 net-next 00/28] BPF syscall
From: Stephen Hemminger @ 2014-08-27 19:18 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Alexei Starovoitov, Daniel Borkmann, H. Peter Anvin,
	Andrew Morton, Chema Gonzalez, Namhyung Kim, Eric Dumazet,
	David S. Miller,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Brendan Gregg, Linus Torvalds, Steven Rostedt,
	Network Development, Peter Zijlstra, Kees Cook, Linux API,
	Ingo Molnar
In-Reply-To: <CALCETrXAfZJTsF2nPFw55rHkfbNXKQuF8Frnq3e1wHEoGxLM4w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

Something in man page format similar to FreeBSD man page:
 http://www.freebsd.org/cgi/man.cgi?bpf(4)

would be more readable and reviewable.

^ permalink raw reply

* Re: Sending undersized ARP packets with VXLAN L3 interface
From: Vlad Yasevich @ 2014-08-27 18:45 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Cong Wang, Martin Rusko, netdev
In-Reply-To: <20140827114209.3a9d3761@urahara>

On 08/27/2014 02:42 PM, Stephen Hemminger wrote:
> On Wed, 27 Aug 2014 13:52:03 -0400
> Vlad Yasevich <vyasevich@gmail.com> wrote:
> 
>> On 08/27/2014 01:28 PM, Cong Wang wrote:
>>> On Wed, Aug 27, 2014 at 10:06 AM, Martin Rusko <martin.rusko@gmail.com> wrote:
>>>>
>>>> I'm wondering, where is the proper place to fix this. Should
>>>> arp_create() function allocate skb big enough to produce ethernet
>>>> frame with at least minimum size? Or is it somewhere in NIC drivers
>>>> where small packets are padded with zeros?
>>>
>>> Drivers do that, for example e1000:
>>>
>>>         /* On PCI/PCI-X HW, if packet size is less than ETH_ZLEN,
>>>          * packets may get corrupted during padding by HW.
>>>          * To WA this issue, pad all small packets manually.
>>>          */
>>>         if (skb->len < ETH_ZLEN) {
>>>                 if (skb_pad(skb, ETH_ZLEN - skb->len))
>>>                         return NETDEV_TX_OK;
>>>                 skb->len = ETH_ZLEN;
>>>                 skb_set_tail_pointer(skb, ETH_ZLEN);
>>>         }
>>
>>
>> I think vxlan needs something like this:
>>
>> From: Vladislav Yasevich <vyasevich@gmail.com>
>> Date: Wed, 27 Aug 2014 13:39:32 -0400
>> Subject: [PATCH] vxlan: Pad short ethernet frames.
>>
>> If sending short ethernet frames from the vxlan device, pad
>> them to minimum size so they can be forwarded after decapsulation.
>>
>> Reported-by: Martin Rusko <martin.rusko@gmail.com>
>> Signed-off-by: Vladislav Yasevich <vyasevich@gmail.com>
>> ---
>>  drivers/net/vxlan.c | 8 ++++++++
>>  1 file changed, 8 insertions(+)
>>
>> diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
>> index 1fb7b37..48267d4 100644
>> --- a/drivers/net/vxlan.c
>> +++ b/drivers/net/vxlan.c
>> @@ -1939,6 +1939,14 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct
>> net_device *dev)
>>  #endif
>>  	}
>>
>> +	/* Pad short frames so they can be forwarded after decapsulation */
>> +	if (skb->len < ETH_ZLEN) {
>> +		if (skb_pad(skb, ETH_ZLEN - skb->len))
>> +			return NETDEV_TX_OK;
>> +		skb->len = ETH_ZLEN;
>> +		skb_set_tail_pointer(skb, ETH_ZLEN);
>> +	}
>> +
>>  	f = vxlan_find_mac(vxlan, eth->h_dest);
>>  	did_rsc = false;
>>
> 
> No. The short frame is perfectly valid, over the VXLAN.
> The system doing the decap and forwarding should be where any padding is added if necessary.
> 

If that's the case, then Martin is most likely seeing a HW bug on the switch.
I wonder how common such a bug might be?

-vlad

^ permalink raw reply

* [PATCH net-next] net: phy: properly report internal PHYs through sysfs
From: Florian Fainelli @ 2014-08-27 18:44 UTC (permalink / raw)
  To: netdev; +Cc: davem, Florian Fainelli

Internal PHYs may not have a valid PHY interface defined, which will
show up in sysfs as "". Add an explicit check of internal PHYs to report
their interface correctly.

Fixes: 3d055d8d1c24 ("net: phy: expose PHY device interface mode")
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/net/phy/mdio_bus.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 4eaadcfcb0fe..50051f271b10 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -553,8 +553,14 @@ static ssize_t
 phy_interface_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct phy_device *phydev = to_phy_device(dev);
+	const char *mode = NULL;
 
-	return sprintf(buf, "%s\n", phy_modes(phydev->interface));
+	if (phy_is_internal(phydev))
+		mode = "internal";
+	else
+		mode = phy_modes(phydev->interface);
+
+	return sprintf(buf, "%s\n", mode);
 }
 static DEVICE_ATTR_RO(phy_interface);
 
-- 
1.9.1

^ permalink raw reply related

* Re: Sending undersized ARP packets with VXLAN L3 interface
From: Stephen Hemminger @ 2014-08-27 18:42 UTC (permalink / raw)
  To: Vlad Yasevich; +Cc: Cong Wang, Martin Rusko, netdev
In-Reply-To: <53FE1AC3.5030409@gmail.com>

On Wed, 27 Aug 2014 13:52:03 -0400
Vlad Yasevich <vyasevich@gmail.com> wrote:

> On 08/27/2014 01:28 PM, Cong Wang wrote:
> > On Wed, Aug 27, 2014 at 10:06 AM, Martin Rusko <martin.rusko@gmail.com> wrote:
> >>
> >> I'm wondering, where is the proper place to fix this. Should
> >> arp_create() function allocate skb big enough to produce ethernet
> >> frame with at least minimum size? Or is it somewhere in NIC drivers
> >> where small packets are padded with zeros?
> >
> > Drivers do that, for example e1000:
> >
> >         /* On PCI/PCI-X HW, if packet size is less than ETH_ZLEN,
> >          * packets may get corrupted during padding by HW.
> >          * To WA this issue, pad all small packets manually.
> >          */
> >         if (skb->len < ETH_ZLEN) {
> >                 if (skb_pad(skb, ETH_ZLEN - skb->len))
> >                         return NETDEV_TX_OK;
> >                 skb->len = ETH_ZLEN;
> >                 skb_set_tail_pointer(skb, ETH_ZLEN);
> >         }
> 
> 
> I think vxlan needs something like this:
> 
> From: Vladislav Yasevich <vyasevich@gmail.com>
> Date: Wed, 27 Aug 2014 13:39:32 -0400
> Subject: [PATCH] vxlan: Pad short ethernet frames.
> 
> If sending short ethernet frames from the vxlan device, pad
> them to minimum size so they can be forwarded after decapsulation.
> 
> Reported-by: Martin Rusko <martin.rusko@gmail.com>
> Signed-off-by: Vladislav Yasevich <vyasevich@gmail.com>
> ---
>  drivers/net/vxlan.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
> index 1fb7b37..48267d4 100644
> --- a/drivers/net/vxlan.c
> +++ b/drivers/net/vxlan.c
> @@ -1939,6 +1939,14 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct
> net_device *dev)
>  #endif
>  	}
> 
> +	/* Pad short frames so they can be forwarded after decapsulation */
> +	if (skb->len < ETH_ZLEN) {
> +		if (skb_pad(skb, ETH_ZLEN - skb->len))
> +			return NETDEV_TX_OK;
> +		skb->len = ETH_ZLEN;
> +		skb_set_tail_pointer(skb, ETH_ZLEN);
> +	}
> +
>  	f = vxlan_find_mac(vxlan, eth->h_dest);
>  	did_rsc = false;
> 

No. The short frame is perfectly valid, over the VXLAN.
The system doing the decap and forwarding should be where any padding is added if necessary.

^ permalink raw reply

* Re: [PATCH 0/2] Get rid of ndo_xmit_flush
From: Cong Wang @ 2014-08-27 18:28 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, Tom Herbert, Jamal Hadi Salim, Hannes Frederic Sowa,
	Eric Dumazet, jeffrey.t.kirsher, rusty, Daniel Borkmann, brouer
In-Reply-To: <20140825.163458.1117073971092495452.davem@davemloft.net>

On Mon, Aug 25, 2014 at 4:34 PM, David Miller <davem@davemloft.net> wrote:
>
> Given Jesper's performance numbers, it's not the way to go.
>
> Instead, go with a signalling scheme via new boolean skb->xmit_more.
>
> This has several advantages:
>
> 1) Nearly trivial driver support, just protect the tail pointer
>    update with the skb->xmit_more check.
>
> 2) No extra indirect calls in the non-deferral cases.
>

First of all, I missed your discussion at kernel summit.

Second of all, I am not familiar with hardware NIC drivers.

But for me, it looks like you are trying to pend some more packets
in a TX queue until the driver decides to flush them all in one shot.
So if that is true, doesn't this mean the latency of first packet pending
in this queue will increase and network traffic will be more bursty for
the receiver??

Also, even if this is a cool feature in hardware driver, doesn't it make
sense to allow users to disable it with ethtool?

It looks like this is still WIP, since no one really sets ->xmit_more to 1
in the code.

Thanks.

^ permalink raw reply

* Re: [PATCH RFC v7 net-next 00/28] BPF syscall
From: Andy Lutomirski @ 2014-08-27 18:26 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: Daniel Borkmann, H. Peter Anvin, Andrew Morton, Chema Gonzalez,
	Namhyung Kim, Eric Dumazet, David S. Miller,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Brendan Gregg, Linus Torvalds, Steven Rostedt,
	Network Development, Peter Zijlstra, Kees Cook, Linux API,
	Ingo Molnar
In-Reply-To: <CAMEtUuw1n1HzAeyKFj9=nGq7RKZq7TADS-6M_BkHbTsWJ_Gm-Q-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

On Tue, Aug 26, 2014 at 9:57 PM, Alexei Starovoitov <ast-uqk4Ao+rVK5Wk0Htik3J/w@public.gmane.org> wrote:
> On Tue, Aug 26, 2014 at 9:49 PM, Andy Lutomirski <luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org> wrote:
>> On Tue, Aug 26, 2014 at 9:35 PM, Alexei Starovoitov <ast-uqk4Ao+rVK5Wk0Htik3J/w@public.gmane.org> wrote:
>>> On Tue, Aug 26, 2014 at 8:56 PM, Andy Lutomirski <luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org> wrote:
>>>> On Aug 26, 2014 7:29 PM, "Alexei Starovoitov" <ast-uqk4Ao+rVK5Wk0Htik3J/w@public.gmane.org> wrote:
>>>>>
>>>>> Hi Ingo, David,
>>>>>
>>>>> posting whole thing again as RFC to get feedback on syscall only.
>>>>> If syscall bpf(int cmd, union bpf_attr *attr, unsigned int size) is ok,
>>>>> I'll split them into small chunks as requested and will repost without RFC.
>>>>
>>>> IMO it's much easier to review a syscall if we just look at a
>>>> specification of what it does.  The code is, in some sense, secondary.
>>>
>>> 'specification of what it does'... hmm, you mean beyond what's
>>> there in commit logs and in Documentation/networking/filter.txt ?
>>> Aren't samples at the end give an idea on 'what it does'?
>>> I'm happy to add 'specification', I just don't understand yet what
>>> it suppose to talk about beyond what's already written.
>>> I understand that the patches are missing explanation on 'why'
>>> the syscall is being added, but I don't think it's what you're asking...
>>
>> I mean a hopefully short document that defines what the syscall does.
>> It should be precise enough that one could, in principle, implement
>> the syscall just by reading the document and that one could use the
>> syscall just by reading the document.
>>
>> Given that there's a whole instruction set to go with it, it may end
>> up being moderately complicated or saying things like "see this other
>> thing for a description of the instruction set" and "there are some
>> extensible sets of functions you can call with it".
>
> I'm still lost.
>
> Here is the quote from Documentation/networking/filter.txt
> "
> 'maps' is a generic storage of different types for sharing data between kernel
> and userspace.
>
> The maps are accessed from user space via BPF syscall,
> which has commands:
> - create a map with given type and attributes
>   map_fd = bpf(BPF_MAP_CREATE, union bpf_attr *attr, u32 size)
>   using attr->map_type, attr->key_size, attr->value_size, attr->max_entries
>   returns process-local file descriptor or negative error
>
> - lookup key in a given map
>   err = bpf(BPF_MAP_LOOKUP_ELEM, union bpf_attr *attr, u32 size)
>   using attr->map_fd, attr->key, attr->value
>   returns zero and stores found elem into value or negative error
>
> - create or update key/value pair in a given map
>   err = bpf(BPF_MAP_UPDATE_ELEM, union bpf_attr *attr, u32 size)
>   using attr->map_fd, attr->key, attr->value
>   returns zero or negative error
>
> - find and delete element by key in a given map
>   err = bpf(BPF_MAP_DELETE_ELEM, union bpf_attr *attr, u32 size)
>   using attr->map_fd, attr->key
>
> - to delete map: close(fd)
>   Exiting process will delete maps automatically
>
> userspace programs uses this API to create/populate/read
> maps that eBPF programs are concurrently updating.
> "
> and more in commit log:
> "
> - load eBPF program
>   fd = bpf(BPF_PROG_LOAD, union bpf_attr *attr, u32 size)
>
>   where 'attr' is
>   struct {
>       enum bpf_prog_type prog_type;
>       __u32 insn_cnt;
>       struct bpf_insn __user *insns;
>       const char __user *license;
>   };
>   insns - array of eBPF instructions
>   license - must be GPL compatible to call helper functions marked gpl_only
>
> - unload eBPF program
>   close(fd)
> "
>
> Isn't it short and describes what it does?
> Do you want me to describe what eBPF program can do?

The problem is that everyone needs to dig around a very long patch
series to find it.  Since you're asking for a review of a syscall, it
would be nice to have everything needed to review whether the syscall
is a good idea in its present form in one place and to keep the amount
of email under control.

--Andy

-- 
Andy Lutomirski
AMA Capital Management, LLC

^ permalink raw reply

* Re: skb_warn_bad_offload warnings with FreeBSD guests
From: Brian Rak @ 2014-08-27 18:25 UTC (permalink / raw)
  To: Vlad Yasevich, netdev
In-Reply-To: <53FE1445.9060206@gmail.com>


On 8/27/2014 1:24 PM, Vlad Yasevich wrote:
> On 08/27/2014 12:09 PM, Brian Rak wrote:
>> On 8/25/2014 10:25 AM, Vlad Yasevich wrote:
>>> On 08/22/2014 12:19 PM, Brian Rak wrote:
>>>> We have a number of machines running qemu with bridged networking. We have noticed that
>>>> *sometimes* FreeBSD guests cause this warning to flood the host "WARNING: CPU: 5 PID: 3705
>>>> at net/core/dev.c:2238 skb_warn_bad_offload+0xc3/0xd0()".  I haven't been able to come up
>>>> with any sort of reproduction steps, it just seems to happen to some FreeBSD guests, but
>>>> not others.
>>>>
>>>> A full stack trace looks like this:
>>>>
>>>> ------------[ cut here ]------------
>>>> WARNING: CPU: 1 PID: 7147 at net/core/dev.c:2233 skb_warn_bad_offload+0xc3/0xd0()
>>>> igb: caps=(0x0000000190114bb3, 0x0000000000000000) len=2962 data_len=0 gso_size=1448
>>>> gso_type=5 ip_summed=0
>>>> Modules linked in: dm_snapshot dm_bufio ipmi_devintf xt_physdev ebt_arp ebt_ip ebtable_nat
>>>> ebtables cls_fw sch_sfq sch_htb tun kvm_intel kvm 8021q garp nfnetlink_queue nfnetlink_log
>>>> nfnetlink bluetooth rfkill bridge stp llc xt_CHECKSUM iptable_mangle ipt_REJECT
>>>> iptable_filter ip
>>>> _tables ip6t_REJECT ip6table_filter ip6_tables ipv6 iTCO_wdt iTCO_vendor_support ipmi_si
>>>> ipmi_msghandler microcode pcspkr i2c_i801 joydev sg lpc_ich shpchp igb dca ptp pps_core
>>>> hwmon ext4 jbd2 mbcache sd_mod crc_t10dif crct10dif_common video ahci libahci xhci_hcd ast
>>>> ttm drm_kms
>>>> _helper sysimgblt sysfillrect syscopyarea dm_mirror dm_region_hash dm_log dm_mod
>>>> CPU: 1 PID: 7147 Comm: qemu-kvm Tainted: G        W 3.15.5-1.el6.elrepo.x86_64 #1
>>>> Hardware name: Supermicro X10SLE-F/HF/X10SLE, BIOS 1.1 07/19/2013
>>>>    00000000000008b9 ffff88081fc435d8 ffffffff8163ba90 00000000000008b9
>>>>    ffff88081fc43628 ffff88081fc43618 ffffffff8106c30c ffffc90007a06e30
>>>>    0000000000000000 ffff8807f2b64000 ffff8807f2b64000 0000000000000000
>>>> Call Trace:
>>>>    <IRQ>  [<ffffffff8163ba90>] dump_stack+0x49/0x61
>>>>    [<ffffffff8106c30c>] warn_slowpath_common+0x8c/0xc0
>>>>    [<ffffffff8106c3f6>] warn_slowpath_fmt+0x46/0x50
>>>>    [<ffffffff8156ce93>] skb_warn_bad_offload+0xc3/0xd0
>>>>    [<ffffffff81574a29>] ? dev_hard_start_xmit+0x339/0x640
>>>>    [<ffffffff81574699>] __skb_gso_segment+0x89/0xe0
>>>>    [<ffffffff81574876>] dev_hard_start_xmit+0x186/0x640
>>>>    [<ffffffff81594f5a>] sch_direct_xmit+0xfa/0x1d0
>>>>    [<ffffffff81574f2f>] __dev_queue_xmit+0x1ff/0x4f0
>>>>    [<ffffffff81575240>] dev_queue_xmit+0x10/0x20
>>>>    [<ffffffffa02e6612>] br_dev_queue_push_xmit+0x82/0xb0 [bridge]
>>>>    [<ffffffffa02ee680>] br_nf_dev_queue_xmit+0x20/0x90 [bridge]
>>>>    [<ffffffffa02ef4b8>] br_nf_post_routing+0x2d8/0x300 [bridge]
>>>>    [<ffffffffa02e6590>] ? deliver_clone+0x60/0x60 [bridge]
>>>>    [<ffffffff815a357e>] nf_iterate+0x8e/0xc0
>>>>    [<ffffffffa02e6590>] ? deliver_clone+0x60/0x60 [bridge]
>>>>    [<ffffffff815a37ad>] nf_hook_slow+0x7d/0x150
>>>>    [<ffffffffa02e6590>] ? deliver_clone+0x60/0x60 [bridge]
>>>>    [<ffffffffa02ee6f0>] ? br_nf_dev_queue_xmit+0x90/0x90 [bridge]
>>>>    [<ffffffffa02e6b43>] br_forward_finish+0x43/0x60 [bridge]
>>>>    [<ffffffffa02ee8a8>] br_nf_forward_finish+0x1b8/0x1d0 [bridge]
>>>>    [<ffffffffa02ef178>] br_nf_forward_ip+0x3a8/0x410 [bridge]
>>>>    [<ffffffffa02e6b00>] ? br_flood_deliver+0x20/0x20 [bridge]
>>>>    [<ffffffff815a357e>] nf_iterate+0x8e/0xc0
>>>>    [<ffffffffa02e6b00>] ? br_flood_deliver+0x20/0x20 [bridge]
>>>>    [<ffffffff815a37ad>] nf_hook_slow+0x7d/0x150
>>>>    [<ffffffffa02e6b00>] ? br_flood_deliver+0x20/0x20 [bridge]
>>>>    [<ffffffffa02e66e4>] __br_forward+0xa4/0x100 [bridge]
>>>>    [<ffffffffa02e7800>] ? NF_HOOK.clone.0+0x70/0x70 [bridge]
>>>>    [<ffffffffa02e67d6>] br_forward+0x96/0xb0 [bridge]
>>>>    [<ffffffffa02e7800>] ? NF_HOOK.clone.0+0x70/0x70 [bridge]
>>>>    [<ffffffffa02e7997>] br_handle_frame_finish+0x197/0x3f0 [bridge]
>>>>    [<ffffffffa02e7800>] ? NF_HOOK.clone.0+0x70/0x70 [bridge]
>>>>    [<ffffffffa02ef790>] br_nf_pre_routing_finish+0x2b0/0x370 [bridge]
>>>>    [<ffffffffa02ef4e0>] ? br_nf_post_routing+0x300/0x300 [bridge]
>>>>    [<ffffffffa02ed986>] NF_HOOK_THRESH+0x56/0x60 [bridge]
>>>>    [<ffffffffa02eed2b>] br_nf_pre_routing+0x2fb/0x3a0 [bridge]
>>>>    [<ffffffff815a357e>] nf_iterate+0x8e/0xc0
>>>>    [<ffffffffa02e7800>] ? NF_HOOK.clone.0+0x70/0x70 [bridge]
>>>>    [<ffffffff815a37ad>] nf_hook_slow+0x7d/0x150
>>>>    [<ffffffffa02e7800>] ? NF_HOOK.clone.0+0x70/0x70 [bridge]
>>>>    [<ffffffffa02e7d8c>] br_handle_frame+0x19c/0x240 [bridge]
>>>>    [<ffffffffa02e7bf0>] ? br_handle_frame_finish+0x3f0/0x3f0 [bridge]
>>>>    [<ffffffff81572fa5>] __netif_receive_skb_core+0x1e5/0x620
>>>>    [<ffffffff81573407>] __netif_receive_skb+0x27/0x70
>>>>    [<ffffffff81573553>] process_backlog+0x103/0x200
>>>>    [<ffffffff81573d62>] net_rx_action+0x112/0x2a0
>>>>    [<ffffffff8107111c>] __do_softirq+0xfc/0x2b0
>>>>    [<ffffffff810713cd>] ? irq_exit+0xad/0xd0
>>>>    [<ffffffff8164a81c>] do_softirq_own_stack+0x1c/0x30
>>>>    <EOI>  [<ffffffff81070e75>] do_softirq+0x55/0x60
>>>>    [<ffffffff81571e19>] netif_rx_ni+0x39/0x70
>>>>    [<ffffffffa03e84e0>] tun_get_user+0x310/0x6c0 [tun]
>>>>    [<ffffffffa03e8995>] tun_chr_aio_write+0x85/0xa0 [tun]
>>>>    [<ffffffff811beb9d>] do_sync_readv_writev+0x4d/0x80
>>>>    [<ffffffff811c0128>] do_readv_writev+0xc8/0x2c0
>>>>    [<ffffffff811bebd0>] ? do_sync_readv_writev+0x80/0x80
>>>>    [<ffffffff811d2c45>] ? poll_select_set_timeout+0x95/0xb0
>>>>    [<ffffffff811c0357>] vfs_writev+0x37/0x50
>>>>    [<ffffffff811c0496>] SyS_writev+0x56/0xf0
>>>>    [<ffffffff81648ee9>] system_call_fastpath+0x16/0x1b
>>>> ---[ end trace d26e70ba037ab631 ]---
>>>>
>>>>
>>>> gso_type=5 and ip_summed=0 are always the same (though len, data_len, and gso_size vary).
>>>>
>>>> What is causing this?
>>> The reason that the warning is triggered is ip_summed = 0 which means there is not
>>> checksum already in the packet and it needs to be calculated.  If the packet is GSO,
>>> then it needs to have partial checksum set (ip_summed == 3).
>>>
>>> You might try using systemtap or instrumenting tun and bridge to see what the
>>> ip_summed value is when this happens.
>> Who needs systemtap when you have strace ;)
>>
>> I managed to intercept the raw packet + headers being delivered to the tun device, though
>> I'm having some trouble making sense of it. I've got this call:
>>
>> writev(33, [{"\x00\x01\x42\x00\xa0\x05\x00\x00\x00\x00\x00\x00", 12}, .... ], 4) = 4258
>>
>> If I ignore the first 12 bytes that were written, I end up with a 4246 byte packet, which
>> matches the warning message:
>>
>> kernel: igb: caps=(0x0000000390114bb3, 0x0000000000000000) len=4246 data_len=4180
>> gso_size=1440 gso_type=5 ip_summed=0
>>
>> Looking at the code (
>> https://github.com/torvalds/linux/blob/68e370289c29e3beac99d59c6d840d470af9dfcf/drivers/net/tun.c#L1037
>> ) it seems that the tun device is expecting a virtio_net_hdr, but that structure is only
>> 10 bytes long ( http://lxr.free-electrons.com/source/include/uapi/linux/virtio_net.h#L73
>> ).  I'm assuming the last two bytes are padding, because then the rest of the structure
>> decodes okay:
>>
>> flags =  0
>> gso_type = VIRTIO_NET_HDR_GSO_TCPV4
>> hdr_len = 66
>> gso_size =  1440
>> csum_start = 0
>> csum_offset = 0
> This isn't right.  Like Eric said, the flags should be set VIRTIO_NET_HDR_F_NEEDS_CSUM
> (1), and the csum_start and csum_offset should be set.
>> This matches what the warning message says, so I'm fairly confident in it.  If I decode
>> the remainder of the write call (ignoring the 2 bytes after the header), I'm left with a
>> perfectly normal looking TCP packet (with a 4180 byte payload).
>>
>> Looking at the packet itself, I see a valid IP checksum, and a valid TCP checksum.  So, it
>> seems like FreeBSD is calculating the packet checksums correctly, but I'm unsure of why
>> Linux isn't noticing that.  I thought it might be related to VIRTIO_NET_HDR_F_DATA_VALID,
>> but I can't seem to find any uses of this that seem relevant (not that FreeBSD sets it
>> anyway).
> Linux is looking at the flags to see what it needs to do.  With flags = 0, it means
> Linux will have to compute the whole checksum all by itself.
>
> When the code hits the linux segmentation to break the 4K packet into MSS chunks,
> it seem that there is no partial checksum computed and thus throws the warning you see.
>
> It is rather pointless for BSD to compute the TCP checksum for the whole 4K
> packet, only to have linux host recompute it for every segment.
>
> Looks like these are some bugs in the BSD virio-net implementation.
>
>> Shouldn't the tun code be setting ip_summed after receiving a packet with a valid
>> checksum?  It's not clear to me where ip_summed should be getting set.
> tun code with set the value of ip_summed based on the flags passed it.
>
> -vlad
Thanks, that explination makes sense to me.  I'll contact the FreeBSD 
developers and see if they can correct the issue.

^ permalink raw reply

* Re: [PATCH RFC v7 net-next 00/28] BPF syscall
From: Steven Stewart-Gallus @ 2014-08-27 18:24 UTC (permalink / raw)
  To: David Miller
  Cc: mingo-DgEjT+Ai2ygdnm+yROfE0A,
	torvalds-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	luto-kltTT9wpgjJwATOyAt5JVQ, rostedt-nx8X9YLhiw1AfugRpC6u6w,
	dborkman-H+wXaHxf7aLQT0dZR+AlfA, chema-hpIqsD4AKlfQT0dZR+AlfA,
	edumazet-hpIqsD4AKlfQT0dZR+AlfA,
	a.p.zijlstra-/NLkJaSkS4VmR6Xm/wNWPw,
	brendan.d.gregg-Re5JQEeQqe8AvxtiuMwx3w,
	namhyung-DgEjT+Ai2ygdnm+yROfE0A, hpa-YMNOUZJC4hwAvxtiuMwx3w,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	keescook-F7+t8E8rja9g9hUCZPvPmw, linux-api-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20140826.231155.421325307812864648.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>

> I'm personally not reviewing such a large patch series, sorry.
> 
> You need to submit smaller sets if you want to get reasonable
> review of your changes and ideas.

Hello. As well, this clogs up the mailing boxes of other people who
have no interest in the patch set.

Thank you,
Steven Stewart-Gallus

^ permalink raw reply

* Re: Sending undersized ARP packets with VXLAN L3 interface
From: Rick Jones @ 2014-08-27 18:16 UTC (permalink / raw)
  To: Vlad Yasevich, Cong Wang, Martin Rusko; +Cc: netdev
In-Reply-To: <53FE1AC3.5030409@gmail.com>

On 08/27/2014 10:52 AM, Vlad Yasevich wrote:
> I think vxlan needs something like this:
>
> From: Vladislav Yasevich <vyasevich@gmail.com>
> Date: Wed, 27 Aug 2014 13:39:32 -0400
> Subject: [PATCH] vxlan: Pad short ethernet frames.
>
> If sending short ethernet frames from the vxlan device, pad
> them to minimum size so they can be forwarded after decapsulation.
>
> Reported-by: Martin Rusko <martin.rusko@gmail.com>
> Signed-off-by: Vladislav Yasevich <vyasevich@gmail.com>
> ---
>   drivers/net/vxlan.c | 8 ++++++++
>   1 file changed, 8 insertions(+)
>
> diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
> index 1fb7b37..48267d4 100644
> --- a/drivers/net/vxlan.c
> +++ b/drivers/net/vxlan.c
> @@ -1939,6 +1939,14 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct
> net_device *dev)
>   #endif
>   	}
>
> +	/* Pad short frames so they can be forwarded after decapsulation */
> +	if (skb->len < ETH_ZLEN) {
> +		if (skb_pad(skb, ETH_ZLEN - skb->len))
> +			return NETDEV_TX_OK;
> +		skb->len = ETH_ZLEN;
> +		skb_set_tail_pointer(skb, ETH_ZLEN);
> +	}
> +
>   	f = vxlan_find_mac(vxlan, eth->h_dest);
>   	did_rsc = false;
>

It is perhaps putting a stripe on the bikeshed, but should that be an 
"unlikely" on the length check?  There seem to be examples both ways in 
the handful of physical drivers I've checked.

rick jones

^ permalink raw reply

* Re: Sending undersized ARP packets with VXLAN L3 interface
From: Vlad Yasevich @ 2014-08-27 17:52 UTC (permalink / raw)
  To: Cong Wang, Martin Rusko; +Cc: netdev
In-Reply-To: <CAHA+R7Ok6K_9U6RCZkSLCuVXtFG4Zs60FQKFZMu-v2yK581hog@mail.gmail.com>

On 08/27/2014 01:28 PM, Cong Wang wrote:
> On Wed, Aug 27, 2014 at 10:06 AM, Martin Rusko <martin.rusko@gmail.com> wrote:
>>
>> I'm wondering, where is the proper place to fix this. Should
>> arp_create() function allocate skb big enough to produce ethernet
>> frame with at least minimum size? Or is it somewhere in NIC drivers
>> where small packets are padded with zeros?
>
> Drivers do that, for example e1000:
>
>         /* On PCI/PCI-X HW, if packet size is less than ETH_ZLEN,
>          * packets may get corrupted during padding by HW.
>          * To WA this issue, pad all small packets manually.
>          */
>         if (skb->len < ETH_ZLEN) {
>                 if (skb_pad(skb, ETH_ZLEN - skb->len))
>                         return NETDEV_TX_OK;
>                 skb->len = ETH_ZLEN;
>                 skb_set_tail_pointer(skb, ETH_ZLEN);
>         }


I think vxlan needs something like this:

From: Vladislav Yasevich <vyasevich@gmail.com>
Date: Wed, 27 Aug 2014 13:39:32 -0400
Subject: [PATCH] vxlan: Pad short ethernet frames.

If sending short ethernet frames from the vxlan device, pad
them to minimum size so they can be forwarded after decapsulation.

Reported-by: Martin Rusko <martin.rusko@gmail.com>
Signed-off-by: Vladislav Yasevich <vyasevich@gmail.com>
---
 drivers/net/vxlan.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 1fb7b37..48267d4 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -1939,6 +1939,14 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct
net_device *dev)
 #endif
 	}

+	/* Pad short frames so they can be forwarded after decapsulation */
+	if (skb->len < ETH_ZLEN) {
+		if (skb_pad(skb, ETH_ZLEN - skb->len))
+			return NETDEV_TX_OK;
+		skb->len = ETH_ZLEN;
+		skb_set_tail_pointer(skb, ETH_ZLEN);
+	}
+
 	f = vxlan_find_mac(vxlan, eth->h_dest);
 	did_rsc = false;

-- 
1.9.3

^ permalink raw reply related

* Re: [PATCH] carl9170: tx: Replace rcu_assign_pointer() with RCU_INIT_POINTER()
From: Christian Lamparter @ 2014-08-27 17:38 UTC (permalink / raw)
  To: Andreea-Cristina Bernat
  Cc: linville, linux-wireless, netdev, linux-kernel, paulmck
In-Reply-To: <20140827132730.GA31650@ada>

On Wednesday, August 27, 2014 04:27:30 PM Andreea-Cristina Bernat wrote:
> According to RCU_INIT_POINTER()'s block comment 3.a, it can be used if
> "3.   The referenced data structure has already been exposed to readers either
> at compile time or via rcu_assign_pointer() -and-
>  a.   You have not made -any- reader-visible changes to this structure since
> then".
> [...]
> 
> Signed-off-by: Andreea-Cristina Bernat <bernat.ada@gmail.com>
Acked-by: Christian Lamparter <chunkeey@googlemail.com>

[OT: John, will "carl9170: Remove redundant protection check" make it 
in the next round too?]

Regards
Christian

^ permalink raw reply

* Re: Sending undersized ARP packets with VXLAN L3 interface
From: Cong Wang @ 2014-08-27 17:28 UTC (permalink / raw)
  To: Martin Rusko; +Cc: netdev
In-Reply-To: <CAMYYbY79hOVA5b22-gmLJTNQwprdfwa_QxKqveuwNhJMcXv9tA@mail.gmail.com>

On Wed, Aug 27, 2014 at 10:06 AM, Martin Rusko <martin.rusko@gmail.com> wrote:
>
> I'm wondering, where is the proper place to fix this. Should
> arp_create() function allocate skb big enough to produce ethernet
> frame with at least minimum size? Or is it somewhere in NIC drivers
> where small packets are padded with zeros?

Drivers do that, for example e1000:

        /* On PCI/PCI-X HW, if packet size is less than ETH_ZLEN,
         * packets may get corrupted during padding by HW.
         * To WA this issue, pad all small packets manually.
         */
        if (skb->len < ETH_ZLEN) {
                if (skb_pad(skb, ETH_ZLEN - skb->len))
                        return NETDEV_TX_OK;
                skb->len = ETH_ZLEN;
                skb_set_tail_pointer(skb, ETH_ZLEN);
        }

^ permalink raw reply

* Re: skb_warn_bad_offload warnings with FreeBSD guests
From: Vlad Yasevich @ 2014-08-27 17:24 UTC (permalink / raw)
  To: Brian Rak, netdev
In-Reply-To: <53FE02CC.50501@gameservers.com>

On 08/27/2014 12:09 PM, Brian Rak wrote:
> 
> On 8/25/2014 10:25 AM, Vlad Yasevich wrote:
>> On 08/22/2014 12:19 PM, Brian Rak wrote:
>>> We have a number of machines running qemu with bridged networking. We have noticed that
>>> *sometimes* FreeBSD guests cause this warning to flood the host "WARNING: CPU: 5 PID: 3705
>>> at net/core/dev.c:2238 skb_warn_bad_offload+0xc3/0xd0()".  I haven't been able to come up
>>> with any sort of reproduction steps, it just seems to happen to some FreeBSD guests, but
>>> not others.
>>>
>>> A full stack trace looks like this:
>>>
>>> ------------[ cut here ]------------
>>> WARNING: CPU: 1 PID: 7147 at net/core/dev.c:2233 skb_warn_bad_offload+0xc3/0xd0()
>>> igb: caps=(0x0000000190114bb3, 0x0000000000000000) len=2962 data_len=0 gso_size=1448
>>> gso_type=5 ip_summed=0
>>> Modules linked in: dm_snapshot dm_bufio ipmi_devintf xt_physdev ebt_arp ebt_ip ebtable_nat
>>> ebtables cls_fw sch_sfq sch_htb tun kvm_intel kvm 8021q garp nfnetlink_queue nfnetlink_log
>>> nfnetlink bluetooth rfkill bridge stp llc xt_CHECKSUM iptable_mangle ipt_REJECT
>>> iptable_filter ip
>>> _tables ip6t_REJECT ip6table_filter ip6_tables ipv6 iTCO_wdt iTCO_vendor_support ipmi_si
>>> ipmi_msghandler microcode pcspkr i2c_i801 joydev sg lpc_ich shpchp igb dca ptp pps_core
>>> hwmon ext4 jbd2 mbcache sd_mod crc_t10dif crct10dif_common video ahci libahci xhci_hcd ast
>>> ttm drm_kms
>>> _helper sysimgblt sysfillrect syscopyarea dm_mirror dm_region_hash dm_log dm_mod
>>> CPU: 1 PID: 7147 Comm: qemu-kvm Tainted: G        W 3.15.5-1.el6.elrepo.x86_64 #1
>>> Hardware name: Supermicro X10SLE-F/HF/X10SLE, BIOS 1.1 07/19/2013
>>>   00000000000008b9 ffff88081fc435d8 ffffffff8163ba90 00000000000008b9
>>>   ffff88081fc43628 ffff88081fc43618 ffffffff8106c30c ffffc90007a06e30
>>>   0000000000000000 ffff8807f2b64000 ffff8807f2b64000 0000000000000000
>>> Call Trace:
>>>   <IRQ>  [<ffffffff8163ba90>] dump_stack+0x49/0x61
>>>   [<ffffffff8106c30c>] warn_slowpath_common+0x8c/0xc0
>>>   [<ffffffff8106c3f6>] warn_slowpath_fmt+0x46/0x50
>>>   [<ffffffff8156ce93>] skb_warn_bad_offload+0xc3/0xd0
>>>   [<ffffffff81574a29>] ? dev_hard_start_xmit+0x339/0x640
>>>   [<ffffffff81574699>] __skb_gso_segment+0x89/0xe0
>>>   [<ffffffff81574876>] dev_hard_start_xmit+0x186/0x640
>>>   [<ffffffff81594f5a>] sch_direct_xmit+0xfa/0x1d0
>>>   [<ffffffff81574f2f>] __dev_queue_xmit+0x1ff/0x4f0
>>>   [<ffffffff81575240>] dev_queue_xmit+0x10/0x20
>>>   [<ffffffffa02e6612>] br_dev_queue_push_xmit+0x82/0xb0 [bridge]
>>>   [<ffffffffa02ee680>] br_nf_dev_queue_xmit+0x20/0x90 [bridge]
>>>   [<ffffffffa02ef4b8>] br_nf_post_routing+0x2d8/0x300 [bridge]
>>>   [<ffffffffa02e6590>] ? deliver_clone+0x60/0x60 [bridge]
>>>   [<ffffffff815a357e>] nf_iterate+0x8e/0xc0
>>>   [<ffffffffa02e6590>] ? deliver_clone+0x60/0x60 [bridge]
>>>   [<ffffffff815a37ad>] nf_hook_slow+0x7d/0x150
>>>   [<ffffffffa02e6590>] ? deliver_clone+0x60/0x60 [bridge]
>>>   [<ffffffffa02ee6f0>] ? br_nf_dev_queue_xmit+0x90/0x90 [bridge]
>>>   [<ffffffffa02e6b43>] br_forward_finish+0x43/0x60 [bridge]
>>>   [<ffffffffa02ee8a8>] br_nf_forward_finish+0x1b8/0x1d0 [bridge]
>>>   [<ffffffffa02ef178>] br_nf_forward_ip+0x3a8/0x410 [bridge]
>>>   [<ffffffffa02e6b00>] ? br_flood_deliver+0x20/0x20 [bridge]
>>>   [<ffffffff815a357e>] nf_iterate+0x8e/0xc0
>>>   [<ffffffffa02e6b00>] ? br_flood_deliver+0x20/0x20 [bridge]
>>>   [<ffffffff815a37ad>] nf_hook_slow+0x7d/0x150
>>>   [<ffffffffa02e6b00>] ? br_flood_deliver+0x20/0x20 [bridge]
>>>   [<ffffffffa02e66e4>] __br_forward+0xa4/0x100 [bridge]
>>>   [<ffffffffa02e7800>] ? NF_HOOK.clone.0+0x70/0x70 [bridge]
>>>   [<ffffffffa02e67d6>] br_forward+0x96/0xb0 [bridge]
>>>   [<ffffffffa02e7800>] ? NF_HOOK.clone.0+0x70/0x70 [bridge]
>>>   [<ffffffffa02e7997>] br_handle_frame_finish+0x197/0x3f0 [bridge]
>>>   [<ffffffffa02e7800>] ? NF_HOOK.clone.0+0x70/0x70 [bridge]
>>>   [<ffffffffa02ef790>] br_nf_pre_routing_finish+0x2b0/0x370 [bridge]
>>>   [<ffffffffa02ef4e0>] ? br_nf_post_routing+0x300/0x300 [bridge]
>>>   [<ffffffffa02ed986>] NF_HOOK_THRESH+0x56/0x60 [bridge]
>>>   [<ffffffffa02eed2b>] br_nf_pre_routing+0x2fb/0x3a0 [bridge]
>>>   [<ffffffff815a357e>] nf_iterate+0x8e/0xc0
>>>   [<ffffffffa02e7800>] ? NF_HOOK.clone.0+0x70/0x70 [bridge]
>>>   [<ffffffff815a37ad>] nf_hook_slow+0x7d/0x150
>>>   [<ffffffffa02e7800>] ? NF_HOOK.clone.0+0x70/0x70 [bridge]
>>>   [<ffffffffa02e7d8c>] br_handle_frame+0x19c/0x240 [bridge]
>>>   [<ffffffffa02e7bf0>] ? br_handle_frame_finish+0x3f0/0x3f0 [bridge]
>>>   [<ffffffff81572fa5>] __netif_receive_skb_core+0x1e5/0x620
>>>   [<ffffffff81573407>] __netif_receive_skb+0x27/0x70
>>>   [<ffffffff81573553>] process_backlog+0x103/0x200
>>>   [<ffffffff81573d62>] net_rx_action+0x112/0x2a0
>>>   [<ffffffff8107111c>] __do_softirq+0xfc/0x2b0
>>>   [<ffffffff810713cd>] ? irq_exit+0xad/0xd0
>>>   [<ffffffff8164a81c>] do_softirq_own_stack+0x1c/0x30
>>>   <EOI>  [<ffffffff81070e75>] do_softirq+0x55/0x60
>>>   [<ffffffff81571e19>] netif_rx_ni+0x39/0x70
>>>   [<ffffffffa03e84e0>] tun_get_user+0x310/0x6c0 [tun]
>>>   [<ffffffffa03e8995>] tun_chr_aio_write+0x85/0xa0 [tun]
>>>   [<ffffffff811beb9d>] do_sync_readv_writev+0x4d/0x80
>>>   [<ffffffff811c0128>] do_readv_writev+0xc8/0x2c0
>>>   [<ffffffff811bebd0>] ? do_sync_readv_writev+0x80/0x80
>>>   [<ffffffff811d2c45>] ? poll_select_set_timeout+0x95/0xb0
>>>   [<ffffffff811c0357>] vfs_writev+0x37/0x50
>>>   [<ffffffff811c0496>] SyS_writev+0x56/0xf0
>>>   [<ffffffff81648ee9>] system_call_fastpath+0x16/0x1b
>>> ---[ end trace d26e70ba037ab631 ]---
>>>
>>>
>>> gso_type=5 and ip_summed=0 are always the same (though len, data_len, and gso_size vary).
>>>
>>> What is causing this?
>> The reason that the warning is triggered is ip_summed = 0 which means there is not
>> checksum already in the packet and it needs to be calculated.  If the packet is GSO,
>> then it needs to have partial checksum set (ip_summed == 3).
>>
>> You might try using systemtap or instrumenting tun and bridge to see what the
>> ip_summed value is when this happens.
> Who needs systemtap when you have strace ;)
> 
> I managed to intercept the raw packet + headers being delivered to the tun device, though
> I'm having some trouble making sense of it. I've got this call:
> 
> writev(33, [{"\x00\x01\x42\x00\xa0\x05\x00\x00\x00\x00\x00\x00", 12}, .... ], 4) = 4258
> 
> If I ignore the first 12 bytes that were written, I end up with a 4246 byte packet, which
> matches the warning message:
> 
> kernel: igb: caps=(0x0000000390114bb3, 0x0000000000000000) len=4246 data_len=4180
> gso_size=1440 gso_type=5 ip_summed=0
> 
> Looking at the code (
> https://github.com/torvalds/linux/blob/68e370289c29e3beac99d59c6d840d470af9dfcf/drivers/net/tun.c#L1037
> ) it seems that the tun device is expecting a virtio_net_hdr, but that structure is only
> 10 bytes long ( http://lxr.free-electrons.com/source/include/uapi/linux/virtio_net.h#L73
> ).  I'm assuming the last two bytes are padding, because then the rest of the structure
> decodes okay:
> 
> flags =  0
> gso_type = VIRTIO_NET_HDR_GSO_TCPV4
> hdr_len = 66
> gso_size =  1440
> csum_start = 0
> csum_offset = 0

This isn't right.  Like Eric said, the flags should be set VIRTIO_NET_HDR_F_NEEDS_CSUM
(1), and the csum_start and csum_offset should be set.
> 
> This matches what the warning message says, so I'm fairly confident in it.  If I decode
> the remainder of the write call (ignoring the 2 bytes after the header), I'm left with a
> perfectly normal looking TCP packet (with a 4180 byte payload).
> 
> Looking at the packet itself, I see a valid IP checksum, and a valid TCP checksum.  So, it
> seems like FreeBSD is calculating the packet checksums correctly, but I'm unsure of why
> Linux isn't noticing that.  I thought it might be related to VIRTIO_NET_HDR_F_DATA_VALID,
> but I can't seem to find any uses of this that seem relevant (not that FreeBSD sets it
> anyway).

Linux is looking at the flags to see what it needs to do.  With flags = 0, it means
Linux will have to compute the whole checksum all by itself.

When the code hits the linux segmentation to break the 4K packet into MSS chunks,
it seem that there is no partial checksum computed and thus throws the warning you see.

It is rather pointless for BSD to compute the TCP checksum for the whole 4K
packet, only to have linux host recompute it for every segment.

Looks like these are some bugs in the BSD virio-net implementation.

> 
> Shouldn't the tun code be setting ip_summed after receiving a packet with a valid
> checksum?  It's not clear to me where ip_summed should be getting set.

tun code with set the value of ip_summed based on the flags passed it.

-vlad

^ permalink raw reply

* [PATCH net-next 3/6] qlcnic: Use usleep_range() instead of msleep() for sleep less than 20ms
From: Shahed Shaikh @ 2014-08-27 16:43 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept-GELinuxNICDev, Jitendra Kalsaria
In-Reply-To: <1409157802-7895-1-git-send-email-shahed.shaikh@qlogic.com>

From: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>

As per recommendation, msleep() may sleep longer than intended time for
values less than 20ms. So, use usleep_range() instead of msleep()

Signed-off-by: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 2 +-
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c      | 2 +-
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c    | 6 +++---
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index 528c651..840bf36 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -2701,7 +2701,7 @@ static int qlcnic_83xx_poll_flash_status_reg(struct qlcnic_adapter *adapter)
 		    QLC_83XX_FLASH_STATUS_READY)
 			break;
 
-		msleep(QLC_83XX_FLASH_STATUS_REG_POLL_DELAY);
+		usleep_range(1000, 1100);
 	} while (--retries);
 
 	if (!retries)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
index 851cb4a..8102673 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
@@ -341,7 +341,7 @@ qlcnic_pcie_sem_lock(struct qlcnic_adapter *adapter, int sem, u32 id_reg)
 			}
 			return -EIO;
 		}
-		msleep(1);
+		usleep_range(1000, 1500);
 	}
 
 	if (id_reg)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c
index c4262c2..be41e4c 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c
@@ -537,7 +537,7 @@ int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter)
 	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_3 + 0xc, 0);
 	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_4 + 0x8, 0);
 	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_4 + 0xc, 0);
-	msleep(1);
+	usleep_range(1000, 1500);
 
 	QLC_SHARED_REG_WR32(adapter, QLCNIC_PEG_HALT_STATUS1, 0);
 	QLC_SHARED_REG_WR32(adapter, QLCNIC_PEG_HALT_STATUS2, 0);
@@ -1198,7 +1198,7 @@ qlcnic_load_firmware(struct qlcnic_adapter *adapter)
 			flashaddr += 8;
 		}
 	}
-	msleep(1);
+	usleep_range(1000, 1500);
 
 	QLCWR32(adapter, QLCNIC_CRB_PEG_NET_0 + 0x18, 0x1020);
 	QLCWR32(adapter, QLCNIC_ROMUSB_GLB_SW_RESET, 0x80001e);
@@ -1295,7 +1295,7 @@ next:
 		rc = qlcnic_validate_firmware(adapter);
 		if (rc != 0) {
 			release_firmware(adapter->fw);
-			msleep(1);
+			usleep_range(1000, 1500);
 			goto next;
 		}
 	}
-- 
1.8.1.4

^ permalink raw reply related

* [PATCH net-next 1/6] qlcnic: Update Link speed and port type info for 83xx adapter
From: Shahed Shaikh @ 2014-08-27 16:43 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept-GELinuxNICDev, Jitendra Kalsaria
In-Reply-To: <1409157802-7895-1-git-send-email-shahed.shaikh@qlogic.com>

From: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>

o Update the port type information
o Advertise correct link modes and autonegotiation
o Add support to change link speed

Signed-off-by: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
---
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c    | 216 +++++++++++++++------
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h    |   1 -
 2 files changed, 158 insertions(+), 59 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index 476e499..528c651 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -35,6 +35,35 @@ static void qlcnic_83xx_get_beacon_state(struct qlcnic_adapter *);
 #define QLC_SKIP_INACTIVE_PCI_REGS	7
 #define QLC_MAX_LEGACY_FUNC_SUPP	8
 
+/* 83xx Module type */
+#define QLC_83XX_MODULE_FIBRE_10GBASE_LRM	0x1 /* 10GBase-LRM */
+#define QLC_83XX_MODULE_FIBRE_10GBASE_LR	0x2 /* 10GBase-LR */
+#define QLC_83XX_MODULE_FIBRE_10GBASE_SR	0x3 /* 10GBase-SR */
+#define QLC_83XX_MODULE_DA_10GE_PASSIVE_CP	0x4 /* 10GE passive
+						     * copper(compliant)
+						     */
+#define QLC_83XX_MODULE_DA_10GE_ACTIVE_CP	0x5 /* 10GE active limiting
+						     * copper(compliant)
+						     */
+#define QLC_83XX_MODULE_DA_10GE_LEGACY_CP	0x6 /* 10GE passive copper
+						     * (legacy, best effort)
+						     */
+#define QLC_83XX_MODULE_FIBRE_1000BASE_SX	0x7 /* 1000Base-SX */
+#define QLC_83XX_MODULE_FIBRE_1000BASE_LX	0x8 /* 1000Base-LX */
+#define QLC_83XX_MODULE_FIBRE_1000BASE_CX	0x9 /* 1000Base-CX */
+#define QLC_83XX_MODULE_TP_1000BASE_T		0xa /* 1000Base-T*/
+#define QLC_83XX_MODULE_DA_1GE_PASSIVE_CP	0xb /* 1GE passive copper
+						     * (legacy, best effort)
+						     */
+#define QLC_83XX_MODULE_UNKNOWN			0xf /* Unknown module type */
+
+/* Port types */
+#define QLC_83XX_10_CAPABLE	 BIT_8
+#define QLC_83XX_100_CAPABLE	 BIT_9
+#define QLC_83XX_1G_CAPABLE	 BIT_10
+#define QLC_83XX_10G_CAPABLE	 BIT_11
+#define QLC_83XX_AUTONEG_ENABLE	 BIT_15
+
 static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
 	{QLCNIC_CMD_CONFIGURE_IP_ADDR, 6, 1},
 	{QLCNIC_CMD_CONFIG_INTRPT, 18, 34},
@@ -667,6 +696,7 @@ void qlcnic_83xx_write_crb(struct qlcnic_adapter *adapter, char *buf,
 
 int qlcnic_83xx_get_port_info(struct qlcnic_adapter *adapter)
 {
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
 	int status;
 
 	status = qlcnic_83xx_get_port_config(adapter);
@@ -674,13 +704,20 @@ int qlcnic_83xx_get_port_info(struct qlcnic_adapter *adapter)
 		dev_err(&adapter->pdev->dev,
 			"Get Port Info failed\n");
 	} else {
-		if (QLC_83XX_SFP_10G_CAPABLE(adapter->ahw->port_config))
-			adapter->ahw->port_type = QLCNIC_XGBE;
-		else
-			adapter->ahw->port_type = QLCNIC_GBE;
 
-		if (QLC_83XX_AUTONEG(adapter->ahw->port_config))
-			adapter->ahw->link_autoneg = AUTONEG_ENABLE;
+		if (ahw->port_config & QLC_83XX_10G_CAPABLE) {
+			ahw->port_type = QLCNIC_XGBE;
+		} else if (ahw->port_config & QLC_83XX_10_CAPABLE ||
+			   ahw->port_config & QLC_83XX_100_CAPABLE ||
+			   ahw->port_config & QLC_83XX_1G_CAPABLE) {
+			ahw->port_type = QLCNIC_GBE;
+		} else {
+			ahw->port_type = QLCNIC_XGBE;
+		}
+
+		if (QLC_83XX_AUTONEG(ahw->port_config))
+			ahw->link_autoneg = AUTONEG_ENABLE;
+
 	}
 	return status;
 }
@@ -3176,22 +3213,33 @@ int qlcnic_83xx_test_link(struct qlcnic_adapter *adapter)
 			break;
 		}
 		config = cmd.rsp.arg[3];
-		if (QLC_83XX_SFP_PRESENT(config)) {
-			switch (ahw->module_type) {
-			case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
-			case LINKEVENT_MODULE_OPTICAL_SRLR:
-			case LINKEVENT_MODULE_OPTICAL_LRM:
-			case LINKEVENT_MODULE_OPTICAL_SFP_1G:
-				ahw->supported_type = PORT_FIBRE;
-				break;
-			case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE:
-			case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN:
-			case LINKEVENT_MODULE_TWINAX:
-				ahw->supported_type = PORT_TP;
-				break;
-			default:
-				ahw->supported_type = PORT_OTHER;
-			}
+		switch (QLC_83XX_SFP_MODULE_TYPE(config)) {
+		case QLC_83XX_MODULE_FIBRE_10GBASE_LRM:
+		case QLC_83XX_MODULE_FIBRE_10GBASE_LR:
+		case QLC_83XX_MODULE_FIBRE_10GBASE_SR:
+			ahw->supported_type = PORT_FIBRE;
+			ahw->port_type = QLCNIC_XGBE;
+			break;
+		case QLC_83XX_MODULE_FIBRE_1000BASE_SX:
+		case QLC_83XX_MODULE_FIBRE_1000BASE_LX:
+		case QLC_83XX_MODULE_FIBRE_1000BASE_CX:
+			ahw->supported_type = PORT_FIBRE;
+			ahw->port_type = QLCNIC_GBE;
+			break;
+		case QLC_83XX_MODULE_TP_1000BASE_T:
+			ahw->supported_type = PORT_TP;
+			ahw->port_type = QLCNIC_GBE;
+			break;
+		case QLC_83XX_MODULE_DA_10GE_PASSIVE_CP:
+		case QLC_83XX_MODULE_DA_10GE_ACTIVE_CP:
+		case QLC_83XX_MODULE_DA_10GE_LEGACY_CP:
+		case QLC_83XX_MODULE_DA_1GE_PASSIVE_CP:
+			ahw->supported_type = PORT_DA;
+			ahw->port_type = QLCNIC_XGBE;
+			break;
+		default:
+			ahw->supported_type = PORT_OTHER;
+			ahw->port_type = QLCNIC_XGBE;
 		}
 		if (config & 1)
 			err = 1;
@@ -3204,9 +3252,9 @@ out:
 int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter,
 			     struct ethtool_cmd *ecmd)
 {
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
 	u32 config = 0;
 	int status = 0;
-	struct qlcnic_hardware_context *ahw = adapter->ahw;
 
 	if (!test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state)) {
 		/* Get port configuration info */
@@ -3229,20 +3277,41 @@ int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter,
 		ecmd->autoneg = AUTONEG_DISABLE;
 	}
 
-	if (ahw->port_type == QLCNIC_XGBE) {
-		ecmd->supported = SUPPORTED_10000baseT_Full;
-		ecmd->advertising = ADVERTISED_10000baseT_Full;
+	ecmd->supported = (SUPPORTED_10baseT_Full |
+			   SUPPORTED_100baseT_Full |
+			   SUPPORTED_1000baseT_Full |
+			   SUPPORTED_10000baseT_Full |
+			   SUPPORTED_Autoneg);
+
+	if (ecmd->autoneg == AUTONEG_ENABLE) {
+		if (ahw->port_config & QLC_83XX_10_CAPABLE)
+			ecmd->advertising |= SUPPORTED_10baseT_Full;
+		if (ahw->port_config & QLC_83XX_100_CAPABLE)
+			ecmd->advertising |= SUPPORTED_100baseT_Full;
+		if (ahw->port_config & QLC_83XX_1G_CAPABLE)
+			ecmd->advertising |= SUPPORTED_1000baseT_Full;
+		if (ahw->port_config & QLC_83XX_10G_CAPABLE)
+			ecmd->advertising |= SUPPORTED_10000baseT_Full;
+		if (ahw->port_config & QLC_83XX_AUTONEG_ENABLE)
+			ecmd->advertising |= ADVERTISED_Autoneg;
 	} else {
-		ecmd->supported = (SUPPORTED_10baseT_Half |
-				   SUPPORTED_10baseT_Full |
-				   SUPPORTED_100baseT_Half |
-				   SUPPORTED_100baseT_Full |
-				   SUPPORTED_1000baseT_Half |
-				   SUPPORTED_1000baseT_Full);
-		ecmd->advertising = (ADVERTISED_100baseT_Half |
-				     ADVERTISED_100baseT_Full |
-				     ADVERTISED_1000baseT_Half |
-				     ADVERTISED_1000baseT_Full);
+		switch (ahw->link_speed) {
+		case SPEED_10:
+			ecmd->advertising = SUPPORTED_10baseT_Full;
+			break;
+		case SPEED_100:
+			ecmd->advertising = SUPPORTED_100baseT_Full;
+			break;
+		case SPEED_1000:
+			ecmd->advertising = SUPPORTED_1000baseT_Full;
+			break;
+		case SPEED_10000:
+			ecmd->advertising = SUPPORTED_10000baseT_Full;
+			break;
+		default:
+			break;
+		}
+
 	}
 
 	switch (ahw->supported_type) {
@@ -3258,6 +3327,12 @@ int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter,
 		ecmd->port = PORT_TP;
 		ecmd->transceiver = XCVR_INTERNAL;
 		break;
+	case PORT_DA:
+		ecmd->supported |= SUPPORTED_FIBRE;
+		ecmd->advertising |= ADVERTISED_FIBRE;
+		ecmd->port = PORT_DA;
+		ecmd->transceiver = XCVR_EXTERNAL;
+		break;
 	default:
 		ecmd->supported |= SUPPORTED_FIBRE;
 		ecmd->advertising |= ADVERTISED_FIBRE;
@@ -3272,35 +3347,60 @@ int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter,
 int qlcnic_83xx_set_settings(struct qlcnic_adapter *adapter,
 			     struct ethtool_cmd *ecmd)
 {
-	int status = 0;
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
 	u32 config = adapter->ahw->port_config;
+	int status = 0;
 
-	if (ecmd->autoneg)
-		adapter->ahw->port_config |= BIT_15;
-
-	switch (ethtool_cmd_speed(ecmd)) {
-	case SPEED_10:
-		adapter->ahw->port_config |= BIT_8;
-		break;
-	case SPEED_100:
-		adapter->ahw->port_config |= BIT_9;
-		break;
-	case SPEED_1000:
-		adapter->ahw->port_config |= BIT_10;
-		break;
-	case SPEED_10000:
-		adapter->ahw->port_config |= BIT_11;
-		break;
-	default:
-		return -EINVAL;
+	/* 83xx devices do not support Half duplex */
+	if (ecmd->duplex == DUPLEX_HALF) {
+			netdev_info(adapter->netdev,
+				    "Half duplex mode not supported\n");
+			return -EINVAL;
 	}
 
+	if (ecmd->autoneg) {
+		ahw->port_config |= QLC_83XX_AUTONEG_ENABLE;
+		ahw->port_config |= (QLC_83XX_100_CAPABLE |
+				     QLC_83XX_1G_CAPABLE |
+				     QLC_83XX_10G_CAPABLE);
+	} else { /* force speed */
+		ahw->port_config &= ~QLC_83XX_AUTONEG_ENABLE;
+		switch (ethtool_cmd_speed(ecmd)) {
+		case SPEED_10:
+			ahw->port_config &= ~(QLC_83XX_100_CAPABLE |
+					      QLC_83XX_1G_CAPABLE |
+					      QLC_83XX_10G_CAPABLE);
+			ahw->port_config |= QLC_83XX_10_CAPABLE;
+			break;
+		case SPEED_100:
+			ahw->port_config &= ~(QLC_83XX_10_CAPABLE |
+					      QLC_83XX_1G_CAPABLE |
+					      QLC_83XX_10G_CAPABLE);
+			ahw->port_config |= QLC_83XX_100_CAPABLE;
+			break;
+		case SPEED_1000:
+			ahw->port_config &= ~(QLC_83XX_10_CAPABLE |
+					      QLC_83XX_100_CAPABLE |
+					      QLC_83XX_10G_CAPABLE);
+			ahw->port_config |= QLC_83XX_1G_CAPABLE;
+			break;
+		case SPEED_10000:
+			ahw->port_config &= ~(QLC_83XX_10_CAPABLE |
+					      QLC_83XX_100_CAPABLE |
+					      QLC_83XX_1G_CAPABLE);
+			ahw->port_config |= QLC_83XX_10G_CAPABLE;
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
 	status = qlcnic_83xx_set_port_config(adapter);
 	if (status) {
-		dev_info(&adapter->pdev->dev,
-			 "Failed to Set Link Speed and autoneg.\n");
-		adapter->ahw->port_config = config;
+		netdev_info(adapter->netdev,
+			    "Failed to Set Link Speed and autoneg.\n");
+		ahw->port_config = config;
 	}
+
 	return status;
 }
 
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
index 2bf101a..abda0ce 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
@@ -360,7 +360,6 @@ enum qlcnic_83xx_states {
 #define QLC_83XX_SFP_MODULE_TYPE(data)		(((data) >> 4) & 0x1F)
 #define QLC_83XX_SFP_CU_LENGTH(data)		(LSB((data) >> 16))
 #define QLC_83XX_SFP_TX_FAULT(data)		((data) & BIT_10)
-#define QLC_83XX_SFP_10G_CAPABLE(data)		((data) & BIT_11)
 #define QLC_83XX_LINK_STATS(data)		((data) & BIT_0)
 #define QLC_83XX_CURRENT_LINK_SPEED(data)	(((data) >> 3) & 7)
 #define QLC_83XX_LINK_PAUSE(data)		(((data) >> 6) & 3)
-- 
1.8.1.4

^ permalink raw reply related

* [PATCH net-next 5/6] MAINTAINERS: Update group email alias for qlcnic driver
From: Shahed Shaikh @ 2014-08-27 16:43 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept-GELinuxNICDev, Shahed Shaikh
In-Reply-To: <1409157802-7895-1-git-send-email-shahed.shaikh@qlogic.com>

From: Shahed Shaikh <shahed.shaikh@qlogic.com>

Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index f01f54f2..c9b4b55 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7361,7 +7361,7 @@ F:	drivers/net/ethernet/qlogic/qla3xxx.*
 
 QLOGIC QLCNIC (1/10)Gb ETHERNET DRIVER
 M:	Shahed Shaikh <shahed.shaikh@qlogic.com>
-M:	Dept-HSGLinuxNICDev@qlogic.com
+M:	Dept-GELinuxNICDev@qlogic.com
 L:	netdev@vger.kernel.org
 S:	Supported
 F:	drivers/net/ethernet/qlogic/qlcnic/
-- 
1.8.1.4

^ permalink raw reply related

* [PATCH net-next 6/6] qlcnic: Update version to 5.3.62
From: Shahed Shaikh @ 2014-08-27 16:43 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept-GELinuxNICDev, Shahed Shaikh
In-Reply-To: <1409157802-7895-1-git-send-email-shahed.shaikh@qlogic.com>

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 1e8bb82..e56c1bb 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -39,8 +39,8 @@
 
 #define _QLCNIC_LINUX_MAJOR 5
 #define _QLCNIC_LINUX_MINOR 3
-#define _QLCNIC_LINUX_SUBVERSION 61
-#define QLCNIC_LINUX_VERSIONID  "5.3.61"
+#define _QLCNIC_LINUX_SUBVERSION 62
+#define QLCNIC_LINUX_VERSIONID  "5.3.62"
 #define QLCNIC_DRV_IDC_VER  0x01
 #define QLCNIC_DRIVER_VERSION  ((_QLCNIC_LINUX_MAJOR << 16) |\
 		 (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
-- 
1.8.1.4

^ permalink raw reply related

* [PATCH net-next 4/6] qlcnic: Add support to run firmware POST
From: Shahed Shaikh @ 2014-08-27 16:43 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept-GELinuxNICDev, Shahed Shaikh
In-Reply-To: <1409157802-7895-1-git-send-email-shahed.shaikh@qlogic.com>

From: Shahed Shaikh <shahed.shaikh@qlogic.com>

This patch adds support to run Power On Self Test (POST) for 83xx adapters.
POST can be run in 3 different speed modes :
	i)  Fast mode (takes about 690 ms)
	ii) Medium mode (takes about 2930 ms)
	iii) Slow mode (takes about 7500 ms)

To run POST, firmware file with name "83xx_post_fw.bin" should be present under
/lib/firmware directory. load_fw_file module parameter is used to specify
POST operation and its speed mode.
load_fw_file = 2 : Fast mode
load_fw_file = 3 : Medium mode
load_fw_file = 4 : Slow mode

Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic.h        |   2 +
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h    |   1 +
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c  | 155 ++++++++++++++++++++-
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c   |   2 +-
 4 files changed, 158 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index 80a5509..1e8bb82 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -540,6 +540,8 @@ struct qlcnic_hardware_context {
 	u8 lb_mode;
 	u16 vxlan_port;
 	struct device *hwmon_dev;
+	u32 post_mode;
+	bool run_post;
 };
 
 struct qlcnic_adapter_stats {
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
index abda0ce..f3346a3 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
@@ -83,6 +83,7 @@
 /* Firmware image definitions */
 #define QLC_83XX_BOOTLOADER_FLASH_ADDR	0x10000
 #define QLC_83XX_FW_FILE_NAME		"83xx_fw.bin"
+#define QLC_83XX_POST_FW_FILE_NAME	"83xx_post_fw.bin"
 #define QLC_84XX_FW_FILE_NAME		"84xx_fw.bin"
 #define QLC_83XX_BOOT_FROM_FLASH	0
 #define QLC_83XX_BOOT_FROM_FILE		0x12345678
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
index d1bded7..9a2cfe4 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
@@ -2075,6 +2075,121 @@ static void qlcnic_83xx_init_hw(struct qlcnic_adapter *p_dev)
 		dev_err(&p_dev->pdev->dev, "%s: failed\n", __func__);
 }
 
+/* POST FW related definations*/
+#define QLC_83XX_POST_SIGNATURE_REG	0x41602014
+#define QLC_83XX_POST_MODE_REG		0x41602018
+#define QLC_83XX_POST_FAST_MODE		0
+#define QLC_83XX_POST_MEDIUM_MODE	1
+#define QLC_83XX_POST_SLOW_MODE		2
+
+/* POST Timeout values in milliseconds */
+#define QLC_83XX_POST_FAST_MODE_TIMEOUT	690
+#define QLC_83XX_POST_MED_MODE_TIMEOUT	2930
+#define QLC_83XX_POST_SLOW_MODE_TIMEOUT	7500
+
+/* POST result values */
+#define QLC_83XX_POST_PASS			0xfffffff0
+#define QLC_83XX_POST_ASIC_STRESS_TEST_FAIL	0xffffffff
+#define QLC_83XX_POST_DDR_TEST_FAIL		0xfffffffe
+#define QLC_83XX_POST_ASIC_MEMORY_TEST_FAIL	0xfffffffc
+#define QLC_83XX_POST_FLASH_TEST_FAIL		0xfffffff8
+
+static int qlcnic_83xx_run_post(struct qlcnic_adapter *adapter)
+{
+	struct qlc_83xx_fw_info *fw_info = adapter->ahw->fw_info;
+	struct device *dev = &adapter->pdev->dev;
+	int timeout, count, ret = 0;
+	u32 signature;
+
+	/* Set timeout values with extra 2 seconds of buffer */
+	switch (adapter->ahw->post_mode) {
+	case QLC_83XX_POST_FAST_MODE:
+		timeout = QLC_83XX_POST_FAST_MODE_TIMEOUT + 2000;
+		break;
+	case QLC_83XX_POST_MEDIUM_MODE:
+		timeout = QLC_83XX_POST_MED_MODE_TIMEOUT + 2000;
+		break;
+	case QLC_83XX_POST_SLOW_MODE:
+		timeout = QLC_83XX_POST_SLOW_MODE_TIMEOUT + 2000;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	strncpy(fw_info->fw_file_name, QLC_83XX_POST_FW_FILE_NAME,
+		QLC_FW_FILE_NAME_LEN);
+
+	ret = request_firmware(&fw_info->fw, fw_info->fw_file_name, dev);
+	if (ret) {
+		dev_err(dev, "POST firmware can not be loaded, skipping POST\n");
+		return 0;
+	}
+
+	ret = qlcnic_83xx_copy_fw_file(adapter);
+	if (ret)
+		return ret;
+
+	/* clear QLC_83XX_POST_SIGNATURE_REG register */
+	qlcnic_ind_wr(adapter, QLC_83XX_POST_SIGNATURE_REG, 0);
+
+	/* Set POST mode */
+	qlcnic_ind_wr(adapter, QLC_83XX_POST_MODE_REG,
+		      adapter->ahw->post_mode);
+
+	QLC_SHARED_REG_WR32(adapter, QLCNIC_FW_IMG_VALID,
+			    QLC_83XX_BOOT_FROM_FILE);
+
+	qlcnic_83xx_start_hw(adapter);
+
+	count = 0;
+	do {
+		msleep(100);
+		count += 100;
+
+		signature = qlcnic_ind_rd(adapter, QLC_83XX_POST_SIGNATURE_REG);
+		if (signature == QLC_83XX_POST_PASS)
+			break;
+	} while (timeout > count);
+
+	if (timeout <= count) {
+		dev_err(dev, "POST timed out, signature = 0x%08x\n", signature);
+		return -EIO;
+	}
+
+	switch (signature) {
+	case QLC_83XX_POST_PASS:
+		dev_info(dev, "POST passed, Signature = 0x%08x\n", signature);
+		break;
+	case QLC_83XX_POST_ASIC_STRESS_TEST_FAIL:
+		dev_err(dev, "POST failed, Test case : ASIC STRESS TEST, Signature = 0x%08x\n",
+			signature);
+		ret = -EIO;
+		break;
+	case QLC_83XX_POST_DDR_TEST_FAIL:
+		dev_err(dev, "POST failed, Test case : DDT TEST, Signature = 0x%08x\n",
+			signature);
+		ret = -EIO;
+		break;
+	case QLC_83XX_POST_ASIC_MEMORY_TEST_FAIL:
+		dev_err(dev, "POST failed, Test case : ASIC MEMORY TEST, Signature = 0x%08x\n",
+			signature);
+		ret = -EIO;
+		break;
+	case QLC_83XX_POST_FLASH_TEST_FAIL:
+		dev_err(dev, "POST failed, Test case : FLASH TEST, Signature = 0x%08x\n",
+			signature);
+		ret = -EIO;
+		break;
+	default:
+		dev_err(dev, "POST failed, Test case : INVALID, Signature = 0x%08x\n",
+			signature);
+		ret = -EIO;
+		break;
+	}
+
+	return ret;
+}
+
 static int qlcnic_83xx_load_fw_image_from_host(struct qlcnic_adapter *adapter)
 {
 	struct qlc_83xx_fw_info *fw_info = adapter->ahw->fw_info;
@@ -2119,8 +2234,27 @@ static int qlcnic_83xx_restart_hw(struct qlcnic_adapter *adapter)
 
 	if (qlcnic_83xx_copy_bootloader(adapter))
 		return err;
+
+	/* Check if POST needs to be run */
+	if (adapter->ahw->run_post) {
+		err = qlcnic_83xx_run_post(adapter);
+		if (err)
+			return err;
+
+		/* No need to run POST in next reset sequence */
+		adapter->ahw->run_post = false;
+
+		/* Again reset the adapter to load regular firmware  */
+		qlcnic_83xx_stop_hw(adapter);
+		qlcnic_83xx_init_hw(adapter);
+
+		err = qlcnic_83xx_copy_bootloader(adapter);
+		if (err)
+			return err;
+	}
+
 	/* Boot either flash image or firmware image from host file system */
-	if (qlcnic_load_fw_file) {
+	if (qlcnic_load_fw_file == 1) {
 		if (qlcnic_83xx_load_fw_image_from_host(adapter))
 			return err;
 	} else {
@@ -2329,6 +2463,25 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)
 	adapter->rx_mac_learn = false;
 	ahw->msix_supported = !!qlcnic_use_msi_x;
 
+	/* Check if POST needs to be run */
+	switch (qlcnic_load_fw_file) {
+	case 2:
+		ahw->post_mode = QLC_83XX_POST_FAST_MODE;
+		ahw->run_post = true;
+		break;
+	case 3:
+		ahw->post_mode = QLC_83XX_POST_MEDIUM_MODE;
+		ahw->run_post = true;
+		break;
+	case 4:
+		ahw->post_mode = QLC_83XX_POST_SLOW_MODE;
+		ahw->run_post = true;
+		break;
+	default:
+		ahw->run_post = false;
+		break;
+	}
+
 	qlcnic_83xx_init_rings(adapter);
 
 	err = qlcnic_83xx_init_mailbox_work(adapter);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 8db11e2..f5e29f7 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -52,7 +52,7 @@ MODULE_PARM_DESC(auto_fw_reset, "Auto firmware reset (0=disabled, 1=enabled)");
 module_param_named(auto_fw_reset, qlcnic_auto_fw_reset, int, 0644);
 
 int qlcnic_load_fw_file;
-MODULE_PARM_DESC(load_fw_file, "Load firmware from (0=flash, 1=file)");
+MODULE_PARM_DESC(load_fw_file, "Load firmware from (0=flash, 1=file, 2=POST in fast mode, 3= POST in medium mode, 4=POST in slow mode)");
 module_param_named(load_fw_file, qlcnic_load_fw_file, int, 0444);
 
 static int qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
-- 
1.8.1.4

^ permalink raw reply related

* [PATCH net-next 2/6] qlcnic: Add support for 0x8830 device ID
From: Shahed Shaikh @ 2014-08-27 16:43 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept-GELinuxNICDev, Shahed Shaikh
In-Reply-To: <1409157802-7895-1-git-send-email-shahed.shaikh@qlogic.com>

From: Shahed Shaikh <shahed.shaikh@qlogic.com>

Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic.h           | 2 ++
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 1 +
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c      | 8 ++++++++
 3 files changed, 11 insertions(+)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index b84f5ea..80a5509 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -2283,6 +2283,7 @@ extern const struct ethtool_ops qlcnic_ethtool_failed_ops;
 
 #define PCI_DEVICE_ID_QLOGIC_QLE824X		0x8020
 #define PCI_DEVICE_ID_QLOGIC_QLE834X		0x8030
+#define PCI_DEVICE_ID_QLOGIC_QLE8830		0x8830
 #define PCI_DEVICE_ID_QLOGIC_VF_QLE834X	0x8430
 #define PCI_DEVICE_ID_QLOGIC_QLE844X		0x8040
 #define PCI_DEVICE_ID_QLOGIC_VF_QLE844X	0x8440
@@ -2307,6 +2308,7 @@ static inline bool qlcnic_83xx_check(struct qlcnic_adapter *adapter)
 	bool status;
 
 	status = ((device == PCI_DEVICE_ID_QLOGIC_QLE834X) ||
+		  (device == PCI_DEVICE_ID_QLOGIC_QLE8830) ||
 		  (device == PCI_DEVICE_ID_QLOGIC_QLE844X) ||
 		  (device == PCI_DEVICE_ID_QLOGIC_VF_QLE844X) ||
 		  (device == PCI_DEVICE_ID_QLOGIC_VF_QLE834X)) ? true : false;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
index 86783e1..d1bded7 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
@@ -2284,6 +2284,7 @@ static int qlcnic_83xx_get_fw_info(struct qlcnic_adapter *adapter)
 		fw_info = ahw->fw_info;
 		switch (pdev->device) {
 		case PCI_DEVICE_ID_QLOGIC_QLE834X:
+		case PCI_DEVICE_ID_QLOGIC_QLE8830:
 			strncpy(fw_info->fw_file_name, QLC_83XX_FW_FILE_NAME,
 				QLC_FW_FILE_NAME_LEN);
 			break;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index cf08b2d..8db11e2 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -111,6 +111,7 @@ static u32 qlcnic_vlan_tx_check(struct qlcnic_adapter *adapter)
 static const struct pci_device_id qlcnic_pci_tbl[] = {
 	ENTRY(PCI_DEVICE_ID_QLOGIC_QLE824X),
 	ENTRY(PCI_DEVICE_ID_QLOGIC_QLE834X),
+	ENTRY(PCI_DEVICE_ID_QLOGIC_QLE8830),
 	ENTRY(PCI_DEVICE_ID_QLOGIC_VF_QLE834X),
 	ENTRY(PCI_DEVICE_ID_QLOGIC_QLE844X),
 	ENTRY(PCI_DEVICE_ID_QLOGIC_VF_QLE844X),
@@ -228,6 +229,11 @@ static const struct qlcnic_board_info qlcnic_boards[] = {
 	  PCI_DEVICE_ID_QLOGIC_QLE834X,
 	  0x0, 0x0, "8300 Series 1/10GbE Controller" },
 	{ PCI_VENDOR_ID_QLOGIC,
+	  PCI_DEVICE_ID_QLOGIC_QLE8830,
+	  0x0,
+	  0x0,
+	  "8830 Series 1/10GbE Controller" },
+	{ PCI_VENDOR_ID_QLOGIC,
 	  PCI_DEVICE_ID_QLOGIC_QLE824X,
 	  PCI_VENDOR_ID_QLOGIC,
 	  0x203,
@@ -1131,6 +1137,7 @@ static void qlcnic_get_bar_length(u32 dev_id, ulong *bar)
 		*bar = QLCNIC_82XX_BAR0_LENGTH;
 		break;
 	case PCI_DEVICE_ID_QLOGIC_QLE834X:
+	case PCI_DEVICE_ID_QLOGIC_QLE8830:
 	case PCI_DEVICE_ID_QLOGIC_QLE844X:
 	case PCI_DEVICE_ID_QLOGIC_VF_QLE834X:
 	case PCI_DEVICE_ID_QLOGIC_VF_QLE844X:
@@ -2474,6 +2481,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		ahw->reg_tbl = (u32 *) qlcnic_reg_tbl;
 		break;
 	case PCI_DEVICE_ID_QLOGIC_QLE834X:
+	case PCI_DEVICE_ID_QLOGIC_QLE8830:
 	case PCI_DEVICE_ID_QLOGIC_QLE844X:
 		qlcnic_83xx_register_map(ahw);
 		break;
-- 
1.8.1.4

^ 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