Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH]: Add Network Sysrq Support
From: Prarit Bhargava @ 2011-06-22 17:39 UTC (permalink / raw)
  To: David Miller
  Cc: John Haxby, Florian Westphal, fbl, netdev, agospoda, nhorman,
	lwoodman
In-Reply-To: <4E01E1FD.8010802@oracle.com>


> Although I wasn't sure that it could happen, it's also possible that the
> cryptographic functions can get in your way.  xt_SYSRQ does its best to
> avoid problems by pre-allocating everything it can so there is as little
> as possible to do when it is needed, but it is possible for it to fail.
>
>   

My running theory as to the failure is that the CPU that took the sysrq
is also the CPU that was having problems that resulted in the "slow
down" of the system.

On a known-good system, xt_SYSRQ behaves properly AFAICT.  It functions
exactly the way we want it to.

So ... I read the following discussion of xt_SYSRQ from last year:

http://www.kerneltrap.com/mailarchive/linux-netdev/2010/4/21/6275199/thread

And it seems there were no technical objections to the code, but there
were other concerns.

davem -- as I don't monitor this list, are you indicating that you are
more amenable to this code being accepted upstream?  Or is that part of
the debate still ongoing?

P.

^ permalink raw reply

* Re: Reported regression against commit a05d2ad
From: Tim Gardner @ 2011-06-22 17:32 UTC (permalink / raw)
  To: Eric W. Biederman; +Cc: Herton Ronaldo Krzesinski, lamont, sconklin, netdev
In-Reply-To: <m1oc1qnc46.fsf@fess.ebiederm.org>

On 06/21/2011 02:49 PM, Eric W. Biederman wrote:
<snip>
> I respectfully suggest that the bug is elsewhere perhaps a broken user
> space application out there that needs to be fixed, or you have a kernel
> memory stomp that removing patch a05d2ad happens to shift the memory
> layout to be harmful in a different way.
>

OK, I'm remembering how PF_UNIX Unix domain sockets are used, so I think 
your theory about a misbehaving user space application is more likely. 
However, I am a bit confused about how an application can attempt to 
receive before the socket is fully opened. Some kind of race condition 
with socketpair() ?

rtg
-- 
Tim Gardner tim.gardner@canonical.com

^ permalink raw reply

* [PATCH 1/1] qlge: Add maintainer.
From: Ron Mercer @ 2011-06-22 16:35 UTC (permalink / raw)
  To: davem; +Cc: netdev, ron.mercer, jitendra.kalsaria


Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
 MAINTAINERS |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 29801f7..c3ab303 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5178,6 +5178,7 @@ S:	Supported
 F:	drivers/net/qlcnic/
 
 QLOGIC QLGE 10Gb ETHERNET DRIVER
+M:	Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
 M:	Ron Mercer <ron.mercer@qlogic.com>
 M:	linux-driver@qlogic.com
 L:	netdev@vger.kernel.org
-- 
1.6.0.2



^ permalink raw reply related

* Re: [PATCH] gianfar v5: implement nfc
From: Joe Perches @ 2011-06-22 16:48 UTC (permalink / raw)
  To: Sebastian Pöhn; +Cc: Sebastian Pöhn, Linux Netdev
In-Reply-To: <1308734972.7885.19.camel@DENEC1DT0191>

On Wed, 2011-06-22 at 11:29 +0200, Sebastian Pöhn wrote:
> First of all thanks for the feedback. I know the fgar_swap_*bits
> function is a bit ugly. The problem with your suggestion is that it is
> necessary to swap a1<>a2 and b1<>b2 AT THE SAME TIME.

These swaps are done sequentially.
> Otherwise
> information the second swap is needing is swapped away by the first one.

How so?

> > swap_bits(temp_table->fe[new_first],
> >  temp_table->fe[old_first], 0xff80);
> > swap_bits(temp_table->fe[new_last],
> >  temp_table->fe[old_last], 0xff80);

new_first and old_first are swapped.
new_last and old_last are swapped.

> @@ -1356,10 +1356,13 @@ static void gfar_sort_mask_table(struct gfar_mask_entry *mask_table,
>  			new_first = mask_table[start].start + 1;
>  			new_last = mask_table[i - 1].end;

I'm a bit confused by this:

+		if (prev != mask_table[i].block) {
+			old_first = mask_table[start].start + 1;
+			old_last = mask_table[i - 1].end;

[no changes to start or i]

+			new_first = mask_table[start].start + 1;
+			new_last = mask_table[i - 1].end;
+
+			gfar_swap_ff80_bits(&temp_table->fe[new_first],
+					&temp_table->fe[old_first],
+					&temp_table->fe[new_last],
+					&temp_table->fe[old_last]);

Doesn't this just swap the same bits around twice?



^ permalink raw reply

* Re: [PATCH] MAINTAINERS: Remove Sven Eckelmann from BATMAN ADVANCED
From: Marek Lindner @ 2011-06-22 16:16 UTC (permalink / raw)
  To: b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, David Miller
In-Reply-To: <20110622.011620.1019772975075064501.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>


Hi,

> When we agree to allow someone to merge something into the tree,
> especially a significant piece of code like batman-adv, there are some
> impressions we want to have beforehand.
> 
> And one such impression we want is that there is going to be someone
> continuing to be active maintaing the code upstream, even after the
> code is merged.
> 
> Otherwise we get "merge and run" scenerios.  As networking maintainer,
> I've been burnt by this several times.
> 
> If you're the only person who had the energy and motivation to do the
> merges of this code, then you're only person we know that can keep up
> with the expectations we had when we agreed to merge the code.
> 
> If you step down, that trust has been broken, and we're left with a
> rotting pile of poo in the tree because it's unlikely anyone else is
> going to step up and keep things maintained upstream as you did.

believing that the batman-adv code base will not be kept in sync anymore is a 
bit premature at this point. David, you may not know this but the first person 
to handle the "upstream job" was Andrew Lunn. At a certain point he stepped 
down and Sven took over. Now, Sven decided to focus on other things and I am 
certain somebody else will take the job. If no one else volunteers I'll fill 
the gap.

Taking over Sven's position won't be easy as he did a very good job and passes 
on high expectations. Sven, thanks a lot for all your time and effort on this 
matter!

David, I hope you can excuse the bumpy way in which this fell onto you. A 
smooth transition would certainly have been better. We will try to work on 
that part in the future. 

Regards,
Marek

^ permalink raw reply

* Re: net/ipv4: commit d0733d2e29b breaks rtorrent
From: Stephen Hemminger @ 2011-06-22 15:53 UTC (permalink / raw)
  To: Reinhard Max
  Cc: Fabienne Ducroquet, Marcus Meissner, sundell.software,
	David S. Miller, netdev
In-Reply-To: <alpine.LNX.2.00.1106221654500.20275@nitsch.suse.de>

On Wed, 22 Jun 2011 16:58:24 +0200 (CEST)
Reinhard Max <max@suse.de> wrote:

> 
> On Wed, 22 Jun 2011 at 16:51, Fabienne Ducroquet wrote:
> 
> > If I understand correctly, it is trying to bind an IPv6 address to a 
> > socket expecting an IPv4 address, so it's a bug in 
> > libtorrent/rtorrent, but it was not visible before because an 
> > INADDR_ANY bind is not a problem for rtorrent?
> 
> Yes, exactly.
> 
> 
> cu
>  	Reinhard

You can find code here http://libtorrent.rakshasa.no/
but it is in C++ so there is an abnormally high indirection factor
between reality of the bug and the code as written.

Did you try contacting the developer?

^ permalink raw reply

* Re: [PATCH 1/3] serial/imx: add device tree support
From: Grant Likely @ 2011-06-22 15:52 UTC (permalink / raw)
  To: Shawn Guo
  Cc: patches, netdev, devicetree-discuss, Jason Liu, linux-kernel,
	Jeremy Kerr, Sascha Hauer, linux-arm-kernel, David Gibson
In-Reply-To: <20110622153353.GA25799@S2100-06.ap.freescale.net>

On Wed, Jun 22, 2011 at 9:33 AM, Shawn Guo <shawn.guo@freescale.com> wrote:
> On Tue, Jun 21, 2011 at 01:13:50PM -0600, Grant Likely wrote:
>> On Tue, Jun 21, 2011 at 7:55 AM, Shawn Guo <shawn.guo@freescale.com> wrote:
>> > Hi Grant,
>> >
>> > I just gave a try to use aliases node for identify the device index.
>> > Please take a look and let me know if it's what you expect.
>>
>> Thanks Shawn.  This is definitely on track.  Comments below...
>>
>> >
>> > On Sun, Jun 19, 2011 at 03:30:02PM +0800, Shawn Guo wrote:
>> > [...]
>> >> > >
>> >> > > +#ifdef CONFIG_OF
>> >> > > +static int serial_imx_probe_dt(struct imx_port *sport,
>> >> > > +         struct platform_device *pdev)
>> >> > > +{
>> >> > > + struct device_node *node = pdev->dev.of_node;
>> >> > > + const __be32 *line;
>> >> > > +
>> >> > > + if (!node)
>> >> > > +         return -ENODEV;
>> >> > > +
>> >> > > + line = of_get_property(node, "id", NULL);
>> >> > > + if (!line)
>> >> > > +         return -ENODEV;
>> >> > > +
>> >> > > + sport->port.line = be32_to_cpup(line) - 1;
>> >> >
>> >> > Hmmm, I really would like to be rid of this.  Instead, if uarts must
>> >> > be enumerated, the driver should look for a /aliases/uart* property
>> >> > that matches the of_node.  Doing it that way is already established in
>> >> > the OpenFirmware documentation, and it ensures there are no overlaps
>> >> > in the global namespace.
>> >> >
>> >>
>> >> I just gave one more try to avoid using 'aliases', and you gave a
>> >> 'no' again.  Now, I know how hard you are on this.  Okay, I start
>> >> thinking about your suggestion seriously :)
>> >>
>> >> > We do need some infrastructure to make that easier though.  Would you
>> >> > have time to help put that together?
>> >> >
>> >> Ok, I will give it a try.
>> >>
>> >
>> > diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts
>> > index da0381a..f4a5c3c 100644
>> > --- a/arch/arm/boot/dts/imx51-babbage.dts
>> > +++ b/arch/arm/boot/dts/imx51-babbage.dts
>> > @@ -18,6 +18,12 @@
>> >        compatible = "fsl,imx51-babbage", "fsl,imx51";
>> >        interrupt-parent = <&tzic>;
>> >
>> > +       aliases {
>> > +               serial0 = &uart0;
>> > +               serial1 = &uart1;
>> > +               serial2 = &uart2;
>> > +       };
>> > +
>>
>> Hmmm.  David Gibson had tossed out an idea of automatically generating
>> aliases from labels.  It may be time to revisit that idea.
>>
>> David, perhaps using this format for a label should turn it into an
>> alias (prefix label with an asterisk):
>>
>>         *thealias: i2c@12340000 { /*...*/ };
>>
>> .... although that approach gets *really* hairy when considering that
>> different boards will want different enumeration.  How would one
>> override an automatic alias defined by an included .dts file?
>>
> Another dependency the patch has to wait for?  Or we can go ahead and
> utilize the facility later when it gets ready?

No, this isn't something you need to wait for.  Just musing on future
enhancements.

>> Also, when obtaining an enumeration for a device, you'll need to be
>> careful about what number gets returned.  If the node doesn't match a
>> given alias, but aliases do exist for other devices of like type, then
>> you need to be careful not to assign a number already assigned to
>> another device via an alias (this of course assumes the driver
>> supports dynamics enumeration, which many drivers will).  It would be
>>
> Some words not finished?

heh, that happens sometimes.  I tend to be a bit scattered when
replying to email.  Just ignore the last sentence fragment.

>> > -       line = of_get_property(node, "id", NULL);
>> > -       if (!line)
>> > +       line = of_get_device_index(node, "serial");
>> > +       if (IS_ERR_VALUE(line))
>> >                return -ENODEV;
>>
>> Personally, it an alias isn't present, then I'd dynamically assign a port id.
>>
> We probably can not.  The driver works with being told the correct
> port id which is defined by soc.  Instead of dynamically assigning
> a port id, we have to tell the driver the exact hardware port id of
> the device that is being probed.

Are you sure?  It doesn't look like the driver behaviour uses id for
anything other than an index into the statically allocated serial port
instance table.  I don't see any change of behaviour based on the port
number anywhere.

g.

^ permalink raw reply

* eth4 received packet on queue 4, but number of RX queues is 4
From: Shawn Bohrer @ 2011-06-22 15:34 UTC (permalink / raw)
  To: Divy Le Ray; +Cc: netdev

I just booted up 3.0.0-rc4+ and got the following trace in the logs:

cxgb3 0000:04:00.0: found old FW minor version(7.4), driver compiled for version 7.10
cxgb3 0000:04:00.0: successful upgrade to firmware 7.10.0
cxgb3 0000:04:00.0: FW upgrade to 7.10.0 succeeded
eth4: link up, 10Gbps, full-duplex
eth4: link down
------------[ cut here ]------------
WARNING: at net/core/dev.c:2656 get_rps_cpu+0x1d1/0x350()
Hardware name: PowerEdge R610
eth4 received packet on queue 4, but number of RX queues is 4
Modules linked in: fuse ext3 jbd mbcache dm_mirror dm_multipath scsi_dh video sbs sbshc acpi_pad acpi_ipmi ipmi_msghandler parport_pc lp parport sg ses enclosure joydev cxgb3 mdio bnx2 iTCO_wdt iTCO_vendor_support serio_raw snd_pcm snd_timer snd soundcore snd_page_alloc dcdbas pcspkr dm_region_hash dm_log dm_mod shpchp megaraid_sas sd_mod scsi_mod crc_t10dif xfs exportfs uhci_hcd ohci_hcd ssb mmc_core ehci_hcd [last unloaded: microcode]
Pid: 0, comm: swapper Not tainted 3.0.0-rc4+ #25
Call Trace:
 <IRQ>  [<ffffffff8104e94f>] warn_slowpath_common+0x7f/0xc0
 [<ffffffff811da090>] ? timerqueue_add+0x60/0xb0
 [<ffffffff8104ea46>] warn_slowpath_fmt+0x46/0x50
 [<ffffffff813499e1>] get_rps_cpu+0x1d1/0x350
 [<ffffffff81073c8b>] ? hrtimer_interrupt+0x13b/0x230
 [<ffffffff81349b95>] netif_receive_skb+0x35/0x90
 [<ffffffffa026c6af>] process_responses+0x62f/0x1580 [cxgb3]
 [<ffffffff81075d55>] ? sched_clock_cpu+0xc5/0x100
 [<ffffffffa026d63c>] napi_rx_handler+0x3c/0x90 [cxgb3]
 [<ffffffff8134a3b7>] net_rx_action+0xe7/0x230
 [<ffffffff81055182>] __do_softirq+0xb2/0x1f0
 [<ffffffff81408cac>] call_softirq+0x1c/0x30
 [<ffffffff81004295>] do_softirq+0x55/0x90
 [<ffffffff81054fa5>] irq_exit+0x65/0x70
 [<ffffffff81409236>] do_IRQ+0x66/0xe0
 [<ffffffff81400513>] common_interrupt+0x13/0x13
 <EOI>  [<ffffffff8122c69b>] ? intel_idle+0xbb/0x110
 [<ffffffff8122c67e>] ? intel_idle+0x9e/0x110
 [<ffffffff813147fc>] cpuidle_idle_call+0xbc/0x240
 [<ffffffff81001ee9>] cpu_idle+0xa9/0xf0
 [<ffffffff813e85e2>] rest_init+0x72/0x80
 [<ffffffff81942cf4>] start_kernel+0x3a1/0x3ac
 [<ffffffff81942321>] x86_64_start_reservations+0x131/0x135
 [<ffffffff81942412>] x86_64_start_kernel+0xed/0xf4
---[ end trace 741fa1dbbcf6aa7b ]---
eth4: link up, 10Gbps, full-duplex
802.1Q VLAN Support v1.8


$ sudo /usr/sbin/ethtool -i eth4
driver: cxgb3
version: 1.1.4-ko
firmware-version: T 7.10.0 TP 1.1.0
bus-info: 0000:04:00.0


$ /sbin/lspci | grep 04:00.0
04:00.0 Ethernet controller: Chelsio Communications Inc S320-LP-CR 10GbE Dual Port Adapter


Thanks,
Shawn


---------------------------------------------------------------
This email, along with any attachments, is confidential. If you 
believe you received this message in error, please contact the 
sender immediately and delete all copies of the message.  
Thank you.


^ permalink raw reply

* Re: [PATCH 1/3] serial/imx: add device tree support
From: Shawn Guo @ 2011-06-22 15:33 UTC (permalink / raw)
  To: Grant Likely
  Cc: patches-QSEj5FYQhm4dnm+yROfE0A, netdev-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Jason Liu,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Jeremy Kerr, Sascha Hauer,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <BANLkTim4vunTm1176MRw3pqRZnunu4=9jg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

On Tue, Jun 21, 2011 at 01:13:50PM -0600, Grant Likely wrote:
> On Tue, Jun 21, 2011 at 7:55 AM, Shawn Guo <shawn.guo-KZfg59tc24xl57MIdRCFDg@public.gmane.org> wrote:
> > Hi Grant,
> >
> > I just gave a try to use aliases node for identify the device index.
> > Please take a look and let me know if it's what you expect.
> 
> Thanks Shawn.  This is definitely on track.  Comments below...
> 
> >
> > On Sun, Jun 19, 2011 at 03:30:02PM +0800, Shawn Guo wrote:
> > [...]
> >> > >
> >> > > +#ifdef CONFIG_OF
> >> > > +static int serial_imx_probe_dt(struct imx_port *sport,
> >> > > +         struct platform_device *pdev)
> >> > > +{
> >> > > + struct device_node *node = pdev->dev.of_node;
> >> > > + const __be32 *line;
> >> > > +
> >> > > + if (!node)
> >> > > +         return -ENODEV;
> >> > > +
> >> > > + line = of_get_property(node, "id", NULL);
> >> > > + if (!line)
> >> > > +         return -ENODEV;
> >> > > +
> >> > > + sport->port.line = be32_to_cpup(line) - 1;
> >> >
> >> > Hmmm, I really would like to be rid of this.  Instead, if uarts must
> >> > be enumerated, the driver should look for a /aliases/uart* property
> >> > that matches the of_node.  Doing it that way is already established in
> >> > the OpenFirmware documentation, and it ensures there are no overlaps
> >> > in the global namespace.
> >> >
> >>
> >> I just gave one more try to avoid using 'aliases', and you gave a
> >> 'no' again.  Now, I know how hard you are on this.  Okay, I start
> >> thinking about your suggestion seriously :)
> >>
> >> > We do need some infrastructure to make that easier though.  Would you
> >> > have time to help put that together?
> >> >
> >> Ok, I will give it a try.
> >>
> >
> > diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts
> > index da0381a..f4a5c3c 100644
> > --- a/arch/arm/boot/dts/imx51-babbage.dts
> > +++ b/arch/arm/boot/dts/imx51-babbage.dts
> > @@ -18,6 +18,12 @@
> >        compatible = "fsl,imx51-babbage", "fsl,imx51";
> >        interrupt-parent = <&tzic>;
> >
> > +       aliases {
> > +               serial0 = &uart0;
> > +               serial1 = &uart1;
> > +               serial2 = &uart2;
> > +       };
> > +
> 
> Hmmm.  David Gibson had tossed out an idea of automatically generating
> aliases from labels.  It may be time to revisit that idea.
> 
> David, perhaps using this format for a label should turn it into an
> alias (prefix label with an asterisk):
> 
>         *thealias: i2c@12340000 { /*...*/ };
> 
> .... although that approach gets *really* hairy when considering that
> different boards will want different enumeration.  How would one
> override an automatic alias defined by an included .dts file?
> 
Another dependency the patch has to wait for?  Or we can go ahead and
utilize the facility later when it gets ready?

> >        chosen {
> >                bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait";
> >        };
> > @@ -47,29 +53,29 @@
> >                        reg = <0x70000000 0x40000>;
> >                        ranges;
> >
> > -                       uart@7000c000 {
> > +                       uart2: uart@7000c000 {
> >                                compatible = "fsl,imx51-uart", "fsl,imx21-uart";
> >                                reg = <0x7000c000 0x4000>;
> >                                interrupts = <33>;
> >                                id = <3>;
> > -                               fsl,has-rts-cts;
> > +                               fsl,uart-has-rtscts;
> >                        };
> >                };
> >
> > -               uart@73fbc000 {
> > +               uart0: uart@73fbc000 {
> >                        compatible = "fsl,imx51-uart", "fsl,imx21-uart";
> >                        reg = <0x73fbc000 0x4000>;
> >                        interrupts = <31>;
> >                        id = <1>;
> > -                       fsl,has-rts-cts;
> > +                       fsl,uart-has-rtscts;
> >                };
> >
> > -               uart@73fc0000 {
> > +               uart1: uart@73fc0000 {
> >                        compatible = "fsl,imx51-uart", "fsl,imx21-uart";
> >                        reg = <0x73fc0000 0x4000>;
> >                        interrupts = <32>;
> >                        id = <2>;
> > -                       fsl,has-rts-cts;
> > +                       fsl,uart-has-rtscts;
> >                };
> >        };
> >
> > diff --git a/drivers/of/base.c b/drivers/of/base.c
> > index 632ebae..13df5d2 100644
> > --- a/drivers/of/base.c
> > +++ b/drivers/of/base.c
> > @@ -737,6 +737,37 @@ err0:
> >  EXPORT_SYMBOL(of_parse_phandles_with_args);
> >
> >  /**
> > + *     of_get_device_index - Get device index by looking up "aliases" node
> > + *     @np:    Pointer to device node that asks for device index
> > + *     @name:  The device alias without index number
> > + *
> > + *     Returns the device index if find it, else returns -ENODEV.
> > + */
> > +int of_get_device_index(struct device_node *np, const char *alias)
> > +{
> > +       struct device_node *aliases = of_find_node_by_name(NULL, "aliases");
> > +       struct property *prop;
> > +       char name[32];
> > +       int index = 0;
> > +
> > +       if (!aliases)
> > +               return -ENODEV;
> > +
> > +       while (1) {
> > +               snprintf(name, sizeof(name), "%s%d", alias, index);
> > +               prop = of_find_property(aliases, name, NULL);
> > +               if (!prop)
> > +                       return -ENODEV;
> > +               if (np == of_find_node_by_path(prop->value))
> > +                       break;
> > +               index++;
> > +       }
> 
> Rather than parsing the alias strings everytime, it would probably be
> better to preprocess all the properties in the aliases node and create
> a lookup table of alias->node references that can be walked quickly
> and trivially.
> 
Ok, I'm thinking about it.  Will probably ask something on details
later.

> Also, when obtaining an enumeration for a device, you'll need to be
> careful about what number gets returned.  If the node doesn't match a
> given alias, but aliases do exist for other devices of like type, then
> you need to be careful not to assign a number already assigned to
> another device via an alias (this of course assumes the driver
> supports dynamics enumeration, which many drivers will).  It would be
> 
Some words not finished?

> \> +
> > +       return index;
> > +}
> > +EXPORT_SYMBOL(of_get_device_index);
> > +
> > +/**
> >  * prom_add_property - Add a property to a node
> >  */
> >  int prom_add_property(struct device_node *np, struct property *prop)
> > diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
> > index da436e0..852668f 100644
> > --- a/drivers/tty/serial/imx.c
> > +++ b/drivers/tty/serial/imx.c
> > @@ -1271,18 +1271,18 @@ static int serial_imx_probe_dt(struct imx_port *sport,
> >        struct device_node *node = pdev->dev.of_node;
> >        const struct of_device_id *of_id =
> >                        of_match_device(imx_uart_dt_ids, &pdev->dev);
> > -       const __be32 *line;
> > +       int line;
> >
> >        if (!node)
> >                return -ENODEV;
> >
> > -       line = of_get_property(node, "id", NULL);
> > -       if (!line)
> > +       line = of_get_device_index(node, "serial");
> > +       if (IS_ERR_VALUE(line))
> >                return -ENODEV;
> 
> Personally, it an alias isn't present, then I'd dynamically assign a port id.
> 
We probably can not.  The driver works with being told the correct
port id which is defined by soc.  Instead of dynamically assigning
a port id, we have to tell the driver the exact hardware port id of
the device that is being probed.

-- 
Regards,
Shawn

^ permalink raw reply

* Re: [PATCH]: Add Network Sysrq Support
From: Andi Kleen @ 2011-06-22 15:29 UTC (permalink / raw)
  To: Prarit Bhargava; +Cc: netdev, davem, agospoda, nhorman, lwoodman
In-Reply-To: <20110621130040.12035.62533.sendpatchset@prarit.bos.redhat.com>

Prarit Bhargava <prarit@redhat.com> writes:
>
> Note that the network sysrq automatically disables after the receipt of
> the ping, ie) it is single-shot mode.  If you want to use this again, you
> must complete the above four steps again.
 
Good idea, but: why not add a single key (e.g. a hash digest with 
the key hashed in) and make it reasonably secure?  
That should not be that hard and would make it a lot more useful.

It would not defend against all attacks, but probably make it
"LAN grade" at least.

-Andi

-- 
ak@linux.intel.com -- Speaking for myself only

^ permalink raw reply

* [PATCH] net/usb: kalmia: Various fixes for better support of non-x86 architectures.
From: Marius B. Kotsbak @ 2011-06-22 15:26 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q, netdev-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA, Marius B. Kotsbak
In-Reply-To: <20110619.155755.1854488306547854947.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>

-Support for big endian.
-Do not use USB buffers at the stack.
-Safer/more efficient code for local constants.

Signed-off-by: Marius B. Kotsbak <marius-iy5w9mehe2BBDgjK7y7TUQ@public.gmane.org>
---
 drivers/net/usb/kalmia.c |   40 ++++++++++++++++++++++++----------------
 1 files changed, 24 insertions(+), 16 deletions(-)

diff --git a/drivers/net/usb/kalmia.c b/drivers/net/usb/kalmia.c
index d965fb1..d4edeb2 100644
--- a/drivers/net/usb/kalmia.c
+++ b/drivers/net/usb/kalmia.c
@@ -100,27 +100,35 @@ kalmia_send_init_packet(struct usbnet *dev, u8 *init_msg, u8 init_msg_len,
 static int
 kalmia_init_and_get_ethernet_addr(struct usbnet *dev, u8 *ethernet_addr)
 {
-	char init_msg_1[] =
+	const static char init_msg_1[] =
 		{ 0x57, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
 		0x00, 0x00 };
-	char init_msg_2[] =
+	const static char init_msg_2[] =
 		{ 0x57, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xf4,
 		0x00, 0x00 };
-	char receive_buf[28];
+	const static int buflen = 28;
+	char *usb_buf;
 	int status;
 
-	status = kalmia_send_init_packet(dev, init_msg_1, sizeof(init_msg_1)
-		/ sizeof(init_msg_1[0]), receive_buf, 24);
+	usb_buf = kmalloc(buflen, GFP_DMA | GFP_KERNEL);
+	if (!usb_buf)
+		return -ENOMEM;
+
+	memcpy(usb_buf, init_msg_1, 12);
+	status = kalmia_send_init_packet(dev, usb_buf, sizeof(init_msg_1)
+		/ sizeof(init_msg_1[0]), usb_buf, 24);
 	if (status != 0)
 		return status;
 
-	status = kalmia_send_init_packet(dev, init_msg_2, sizeof(init_msg_2)
-		/ sizeof(init_msg_2[0]), receive_buf, 28);
+	memcpy(usb_buf, init_msg_2, 12);
+	status = kalmia_send_init_packet(dev, usb_buf, sizeof(init_msg_2)
+		/ sizeof(init_msg_2[0]), usb_buf, 28);
 	if (status != 0)
 		return status;
 
-	memcpy(ethernet_addr, receive_buf + 10, ETH_ALEN);
+	memcpy(ethernet_addr, usb_buf + 10, ETH_ALEN);
 
+	kfree(usb_buf);
 	return status;
 }
 
@@ -190,7 +198,8 @@ kalmia_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
 	dev_kfree_skb_any(skb);
 	skb = skb2;
 
-	done: header_start = skb_push(skb, KALMIA_HEADER_LENGTH);
+done:
+	header_start = skb_push(skb, KALMIA_HEADER_LENGTH);
 	ether_type_1 = header_start[KALMIA_HEADER_LENGTH + 12];
 	ether_type_2 = header_start[KALMIA_HEADER_LENGTH + 13];
 
@@ -201,9 +210,8 @@ kalmia_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
 	header_start[0] = 0x57;
 	header_start[1] = 0x44;
 	content_len = skb->len - KALMIA_HEADER_LENGTH;
-	header_start[2] = (content_len & 0xff); /* low byte */
-	header_start[3] = (content_len >> 8); /* high byte */
 
+	put_unaligned_le16(content_len, &header_start[2]);
 	header_start[4] = ether_type_1;
 	header_start[5] = ether_type_2;
 
@@ -231,13 +239,13 @@ kalmia_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
 	 * Our task here is to strip off framing, leaving skb with one
 	 * data frame for the usbnet framework code to process.
 	 */
-	const u8 HEADER_END_OF_USB_PACKET[] =
+	const static u8 HEADER_END_OF_USB_PACKET[] =
 		{ 0x57, 0x5a, 0x00, 0x00, 0x08, 0x00 };
-	const u8 EXPECTED_UNKNOWN_HEADER_1[] =
+	const static u8 EXPECTED_UNKNOWN_HEADER_1[] =
 		{ 0x57, 0x43, 0x1e, 0x00, 0x15, 0x02 };
-	const u8 EXPECTED_UNKNOWN_HEADER_2[] =
+	const static u8 EXPECTED_UNKNOWN_HEADER_2[] =
 		{ 0x57, 0x50, 0x0e, 0x00, 0x00, 0x00 };
-	u8 i = 0;
+	int i = 0;
 
 	/* incomplete header? */
 	if (skb->len < KALMIA_HEADER_LENGTH)
@@ -285,7 +293,7 @@ kalmia_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
 
 		/* subtract start header and end header */
 		usb_packet_length = skb->len - (2 * KALMIA_HEADER_LENGTH);
-		ether_packet_length = header_start[2] + (header_start[3] << 8);
+		ether_packet_length = get_unaligned_le16(&header_start[2]);
 		skb_pull(skb, KALMIA_HEADER_LENGTH);
 
 		/* Some small packets misses end marker */
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* Re: [PATCH 1/2] net/usb: Add Samsung Kalmia driver for Samsung GT-B3730
From: Marius Kotsbak @ 2011-06-22 15:24 UTC (permalink / raw)
  To: David Miller
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	marius-iy5w9mehe2BBDgjK7y7TUQ
In-Reply-To: <20110619.155755.1854488306547854947.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>

On 20. juni 2011 00:57, David Miller wrote:
> From: "Marius B. Kotsbak" <marius.kotsbak-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Date: Sun, 19 Jun 2011 23:45:56 +0200
>
>> Introducing driver for the network port of Samsung Kalmia based USB LTE modems.
>> It has also an ACM interface that previous patches associates with the "option"
>> module. To access those interfaces, the modem must first be switched from modem
>> mode using a tool like usb_modeswitch.
>>
>> As the proprietary protocol has been discovered by watching the MS Windows driver
>> behavior, there might be errors in the protocol handling, but stable and fast
>> connection has been established for hours with Norwegian operator NetCom that
>> distributes this modem with their LTE/4G subscription.
>>
>> More and updated information about how to use this driver is available here:
>>
>> http://www.draisberghof.de/usb_modeswitch/bb/viewtopic.php?t=465
>> https://github.com/mkotsbak/Samsung-GT-B3730-linux-driver
>>
>> Signed-off-by: Marius B. Kotsbak <marius-iy5w9mehe2BBDgjK7y7TUQ@public.gmane.org>
> Please submit only one patch for adding a new driver.
>
> Adding a second patch that fixes the driver in various ways is
> just noise, put those fixes into this one initial patch instead.

Turned out the first patch already is accepted into Linus tree, so then
I send again just the second.

--
Marius


--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: net/ipv4: commit d0733d2e29b breaks rtorrent
From: Fabienne Ducroquet @ 2011-06-22 14:51 UTC (permalink / raw)
  To: Reinhard Max; +Cc: Marcus Meissner, sundell.software, David S. Miller, netdev
In-Reply-To: <alpine.LNX.2.00.1106221508310.10066@nitsch.suse.de>

On Wed, Jun 22, 2011 at 03:24:53PM +0200, Reinhard Max wrote:
> On Wed, 22 Jun 2011 at 14:47, Marcus Meissner wrote:
> 
> >Can you show us the code surrounding the bind in rtorrent?

Since I'm not a developer of rtorrent I'm not sure what the right code 
to show is, so I leave that to the developer of libtorrent/rtorrent, he 
is CC'ed.

> ... or short of that, the output of "strace -e socket,bind" when
> starting rtorrent with the kernel patch not reverted?

Here it is :

socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP) = -1 EAFNOSUPPORT (Address family not supported by protocol)
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 5
bind(5, {sa_family=AF_INET6, sin6_port=htons(6903), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = -1 EINVAL (Invalid argument)

[ 95 lines with only the number in parentheses after htons changing ]

bind(5, {sa_family=AF_INET6, sin6_port=htons(6999), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = -1 EINVAL (Invalid argument)
socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP) = -1 EAFNOSUPPORT (Address family not supported by protocol)
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 5
bind(5, {sa_family=AF_INET6, sin6_port=htons(6881), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = -1 EINVAL (Invalid argument)

[ 21 lines with only the number in parentheses after htons changing ]

bind(5, {sa_family=AF_INET6, sin6_port=htons(6903), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = -1 EINVAL (Invalid argument)


If I understand correctly, it is trying to bind an IPv6 address to a socket 
expecting an IPv4 address, so it's a bug in libtorrent/rtorrent, but it was not 
visible before because an INADDR_ANY bind is not a problem for rtorrent?

Fabienne

^ permalink raw reply

* Re: net/ipv4: commit d0733d2e29b breaks rtorrent
From: Reinhard Max @ 2011-06-22 14:58 UTC (permalink / raw)
  To: Fabienne Ducroquet
  Cc: Marcus Meissner, sundell.software, David S. Miller, netdev
In-Reply-To: <20110622145144.GA31734@localhost>


On Wed, 22 Jun 2011 at 16:51, Fabienne Ducroquet wrote:

> If I understand correctly, it is trying to bind an IPv6 address to a 
> socket expecting an IPv4 address, so it's a bug in 
> libtorrent/rtorrent, but it was not visible before because an 
> INADDR_ANY bind is not a problem for rtorrent?

Yes, exactly.


cu
 	Reinhard

^ permalink raw reply

* Re: [PATCH net-next 1/3] net: ipv4: fix potential memory leak by assigning uhash_entries
From: Paul Gortmaker @ 2011-06-22 14:23 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: davem, netdev, Mark Asselstine
In-Reply-To: <1308719087.2713.4.camel@edumazet-laptop>

On 11-06-22 01:04 AM, Eric Dumazet wrote:
> Le mardi 21 juin 2011 à 16:43 -0400, Paul Gortmaker a écrit :

[...]

>> diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
>> index abca870..6f53a5a 100644
>> --- a/net/ipv4/udp.c
>> +++ b/net/ipv4/udp.c
>> @@ -2155,7 +2155,7 @@ void udp4_proc_exit(void)
>>  }
>>  #endif /* CONFIG_PROC_FS */
>>  
>> -static __initdata unsigned long uhash_entries;
>> +static __initdata unsigned long uhash_entries = UDP_HTABLE_SIZE_MIN;
>>  static int __init set_uhash_entries(char *str)
>>  {
>>  	if (!str)
> 
> Arg no, I really wanted to get more hash slots in my 32bit machines,
> with 4Gbytes of memory.
> 
> Here is what I currently have (without your patch)
> 
> [    1.903086] UDP hash table entries: 512 (order: 2, 16384 bytes)
> 
> 
> I mean, this kmemleak was already reported.

Ah, I'd not read that thread - here is the link if anyone else
is following along:

http://lists-archives.org/linux-kernel/27460513-kmemleak-for-mips.html

> 
> 32MB machines are things of the past.
> 
> If you really care, please add a change to alloc_large_system_hash() ?

Given the user list (dcache.c, inode.c, pid.c, ...) it probably
isn't worth the churn of adding a min argument to the calls.
I'm fine with dropping this patch (and glad I'd CC'd you on it)

Thanks,
Paul.

> 
> 
> 

^ permalink raw reply

* [PATCH 4/7] qlcnic: fix initial number of msix entries in adapter.
From: Anirban Chakraborty @ 2011-06-22 12:52 UTC (permalink / raw)
  To: netdev; +Cc: David Miller, Sucheta Chakraborty
In-Reply-To: <1308747144-23785-1-git-send-email-anirban.chakraborty@qlogic.com>

From: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>

Calculation of number of MSI-X vectors was wrong on uniprocessor
systems.

Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
---
 drivers/net/qlcnic/qlcnic.h      |    1 -
 drivers/net/qlcnic/qlcnic_main.c |    6 ++----
 2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index e5bb332..58d7616 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -900,7 +900,6 @@ struct qlcnic_ipaddr {
 	((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED))
 
 #define QLCNIC_DEF_NUM_STS_DESC_RINGS	4
-#define QLCNIC_MIN_NUM_RSS_RINGS	2
 #define QLCNIC_MSIX_TBL_SPACE		8192
 #define QLCNIC_PCI_REG_MSIX_TBL 	0x44
 #define QLCNIC_MSIX_TBL_PGSIZE		4096
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index a656a12..a050746 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -418,10 +418,8 @@ qlcnic_setup_intr(struct qlcnic_adapter *adapter)
 	int num_msix;
 
 	if (adapter->msix_supported) {
-		num_msix = (num_online_cpus() >=
-			QLCNIC_DEF_NUM_STS_DESC_RINGS) ?
-			QLCNIC_DEF_NUM_STS_DESC_RINGS :
-			QLCNIC_MIN_NUM_RSS_RINGS;
+		num_msix = rounddown_pow_of_two(min_t(int, num_online_cpus(),
+				QLCNIC_DEF_NUM_STS_DESC_RINGS));
 	} else
 		num_msix = 1;
 
-- 
1.7.4.1


^ permalink raw reply related

* Re: net/ipv4: commit d0733d2e29b breaks rtorrent
From: Reinhard Max @ 2011-06-22 13:24 UTC (permalink / raw)
  To: Marcus Meissner
  Cc: Fabienne Ducroquet, sundell.software, David S. Miller, netdev
In-Reply-To: <20110622124727.GC19184@suse.de>

Hi,

On Wed, 22 Jun 2011 at 14:47, Marcus Meissner wrote:

> Can you show us the code surrounding the bind in rtorrent?

... or short of that, the output of "strace -e socket,bind" when 
starting rtorrent with the kernel patch not reverted?


cu
 	Reinhard

^ permalink raw reply

* [PATCH 4/7] qlcnic: fix initial number of msix entries in adapter.
From: Anirban Chakraborty @ 2011-06-22 12:55 UTC (permalink / raw)
  To: netdev; +Cc: David Miller, Sucheta Chakraborty

From: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>

Calculation of number of MSI-X vectors was wrong on uniprocessor
systems.

Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
---
 drivers/net/qlcnic/qlcnic.h      |    1 -
 drivers/net/qlcnic/qlcnic_main.c |    6 ++----
 2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index e5bb332..58d7616 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -900,7 +900,6 @@ struct qlcnic_ipaddr {
 	((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED))
 
 #define QLCNIC_DEF_NUM_STS_DESC_RINGS	4
-#define QLCNIC_MIN_NUM_RSS_RINGS	2
 #define QLCNIC_MSIX_TBL_SPACE		8192
 #define QLCNIC_PCI_REG_MSIX_TBL 	0x44
 #define QLCNIC_MSIX_TBL_PGSIZE		4096
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index a656a12..a050746 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -418,10 +418,8 @@ qlcnic_setup_intr(struct qlcnic_adapter *adapter)
 	int num_msix;
 
 	if (adapter->msix_supported) {
-		num_msix = (num_online_cpus() >=
-			QLCNIC_DEF_NUM_STS_DESC_RINGS) ?
-			QLCNIC_DEF_NUM_STS_DESC_RINGS :
-			QLCNIC_MIN_NUM_RSS_RINGS;
+		num_msix = rounddown_pow_of_two(min_t(int, num_online_cpus(),
+				QLCNIC_DEF_NUM_STS_DESC_RINGS));
 	} else
 		num_msix = 1;
 
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 7/7] qlcnic: multi protocol internal loopback support added.
From: Anirban Chakraborty @ 2011-06-22 12:52 UTC (permalink / raw)
  To: netdev; +Cc: David Miller, Sucheta Chakraborty
In-Reply-To: <1308747144-23785-1-git-send-email-anirban.chakraborty@qlogic.com>

From: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>

Driver will generate loopback traffic pattern and do the test. And
returns result of the test to application.

Updated driver version to 5.0.19.

Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
---
 drivers/net/qlcnic/qlcnic.h         |   22 ++++++-
 drivers/net/qlcnic/qlcnic_ethtool.c |  123 +++++++++++++++++++++++++++++++++-
 drivers/net/qlcnic/qlcnic_hw.c      |   50 ++++++++++++++
 drivers/net/qlcnic/qlcnic_init.c    |  126 ++++++++++++++++++++++++++++++++++-
 drivers/net/qlcnic/qlcnic_main.c    |    6 ++
 5 files changed, 322 insertions(+), 5 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 0be84bd..e545450 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -36,8 +36,8 @@
 
 #define _QLCNIC_LINUX_MAJOR 5
 #define _QLCNIC_LINUX_MINOR 0
-#define _QLCNIC_LINUX_SUBVERSION 18
-#define QLCNIC_LINUX_VERSIONID  "5.0.18"
+#define _QLCNIC_LINUX_SUBVERSION 19
+#define QLCNIC_LINUX_VERSIONID  "5.0.19"
 #define QLCNIC_DRV_IDC_VER  0x01
 #define QLCNIC_DRIVER_VERSION  ((_QLCNIC_LINUX_MAJOR << 16) |\
 		 (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
@@ -451,6 +451,7 @@ struct qlcnic_hardware_context {
 	u8 revision_id;
 	u8 pci_func;
 	u8 linkup;
+	u8 loopback_state;
 	u16 port_type;
 	u16 board_type;
 
@@ -780,6 +781,13 @@ struct qlcnic_mac_list_s {
 #define QLCNIC_IP_UP		2
 #define QLCNIC_IP_DOWN		3
 
+#define QLCNIC_ILB_MODE		0x1
+
+#define QLCNIC_LINKEVENT	0x1
+#define QLCNIC_LB_RESPONSE	0x2
+#define QLCNIC_IS_LB_CONFIGURED(VAL)	\
+		(VAL == (QLCNIC_LINKEVENT | QLCNIC_LB_RESPONSE))
+
 /*
  * Driver --> Firmware
  */
@@ -789,13 +797,17 @@ struct qlcnic_mac_list_s {
 #define QLCNIC_H2C_OPCODE_LRO_REQUEST			0x7
 #define QLCNIC_H2C_OPCODE_SET_MAC_RECEIVE_MODE		0xc
 #define QLCNIC_H2C_OPCODE_CONFIG_IPADDR		0x12
+
 #define QLCNIC_H2C_OPCODE_GET_LINKEVENT		0x15
 #define QLCNIC_H2C_OPCODE_CONFIG_BRIDGING		0x17
 #define QLCNIC_H2C_OPCODE_CONFIG_HW_LRO		0x18
+#define QLCNIC_H2C_OPCODE_CONFIG_LOOPBACK		0x13
+
 /*
  * Firmware --> Driver
  */
 
+#define QLCNIC_C2H_OPCODE_CONFIG_LOOPBACK		0x8f
 #define QLCNIC_C2H_OPCODE_GET_LINKEVENT_RESPONSE	141
 
 #define VPORT_MISS_MODE_DROP		0 /* drop all unmatched */
@@ -1430,6 +1442,12 @@ int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter);
 void qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter,
 		struct qlcnic_host_tx_ring *tx_ring);
 void qlcnic_fetch_mac(struct qlcnic_adapter *, u32, u32, u8, u8 *);
+void qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring);
+void qlcnic_clear_lb_mode(struct qlcnic_adapter *adapter);
+int qlcnic_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode);
+
+/* Functions from qlcnic_ethtool.c */
+int qlcnic_check_loopback_buff(unsigned char *data, u8 mac[]);
 
 /* Functions from qlcnic_main.c */
 int qlcnic_reset_context(struct qlcnic_adapter *);
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
index 31f5cba..743035e 100644
--- a/drivers/net/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/qlcnic/qlcnic_ethtool.c
@@ -84,7 +84,8 @@ static const char qlcnic_device_gstrings_stats[][ETH_GSTRING_LEN] = {
 static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = {
 	"Register_Test_on_offline",
 	"Link_Test_on_offline",
-	"Interrupt_Test_offline"
+	"Interrupt_Test_offline",
+	"Loopback_Test_offline"
 };
 
 #define QLCNIC_TEST_LEN	ARRAY_SIZE(qlcnic_gstrings_test)
@@ -685,6 +686,123 @@ clear_it:
 	return ret;
 }
 
+#define QLCNIC_ILB_PKT_SIZE 64
+#define QLCNIC_NUM_ILB_PKT	16
+#define QLCNIC_ILB_MAX_RCV_LOOP 10
+
+static void qlcnic_create_loopback_buff(unsigned char *data, u8 mac[])
+{
+	unsigned char random_data[] = {0xa8, 0x06, 0x45, 0x00};
+
+	memset(data, 0x4e, QLCNIC_ILB_PKT_SIZE);
+
+	memcpy(data, mac, ETH_ALEN);
+	memcpy(data + ETH_ALEN, mac, ETH_ALEN);
+
+	memcpy(data + 2 * ETH_ALEN, random_data, sizeof(random_data));
+}
+
+int qlcnic_check_loopback_buff(unsigned char *data, u8 mac[])
+{
+	unsigned char buff[QLCNIC_ILB_PKT_SIZE];
+	qlcnic_create_loopback_buff(buff, mac);
+	return memcmp(data, buff, QLCNIC_ILB_PKT_SIZE);
+}
+
+static int qlcnic_do_ilb_test(struct qlcnic_adapter *adapter)
+{
+	struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
+	struct qlcnic_host_sds_ring *sds_ring = &recv_ctx->sds_rings[0];
+	struct sk_buff *skb;
+	int i, loop, cnt = 0;
+
+	for (i = 0; i < QLCNIC_NUM_ILB_PKT; i++) {
+		skb = dev_alloc_skb(QLCNIC_ILB_PKT_SIZE);
+		qlcnic_create_loopback_buff(skb->data, adapter->mac_addr);
+		skb_put(skb, QLCNIC_ILB_PKT_SIZE);
+
+		adapter->diag_cnt = 0;
+		qlcnic_xmit_frame(skb, adapter->netdev);
+
+		loop = 0;
+		do {
+			msleep(1);
+			qlcnic_process_rcv_ring_diag(sds_ring);
+			if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP)
+				break;
+		} while (!adapter->diag_cnt);
+
+		dev_kfree_skb_any(skb);
+
+		if (!adapter->diag_cnt)
+			dev_warn(&adapter->pdev->dev, "ILB Test: %dth packet"
+				" not recevied\n", i + 1);
+		else
+			cnt++;
+	}
+	if (cnt != i) {
+		dev_warn(&adapter->pdev->dev, "ILB Test failed\n");
+		return -1;
+	}
+	return 0;
+}
+
+static int qlcnic_iloopback_test(struct net_device *netdev)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	int max_sds_rings = adapter->max_sds_rings;
+	struct qlcnic_host_sds_ring *sds_ring;
+	int loop = 0;
+	int ret;
+
+	netdev_info(netdev, "%s:  in progress\n", __func__);
+	if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) {
+		netdev_warn(netdev, "Loopback test not supported for non "
+				"privilege function\n");
+		return 0;
+	}
+
+	if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
+		return -EIO;
+
+
+	ret = qlcnic_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST);
+	if (ret)
+		goto clear_it;
+
+	sds_ring = &adapter->recv_ctx->sds_rings[0];
+
+	ret = qlcnic_set_lb_mode(adapter, QLCNIC_ILB_MODE);
+	if (ret)
+		goto free_res;
+
+	do {
+		msleep(500);
+		qlcnic_process_rcv_ring_diag(sds_ring);
+		if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP)
+			break;
+	} while (!QLCNIC_IS_LB_CONFIGURED(adapter->ahw->loopback_state));
+
+	if (!QLCNIC_IS_LB_CONFIGURED(adapter->ahw->loopback_state)) {
+		netdev_info(netdev, "firmware didnt respond to loopback "
+				"configure request\n");
+		ret = adapter->ahw->loopback_state;
+		goto free_res;
+	}
+
+	ret = qlcnic_do_ilb_test(adapter);
+
+	qlcnic_clear_lb_mode(adapter);
+
+ free_res:
+	qlcnic_diag_free_res(netdev, max_sds_rings);
+
+ clear_it:
+	adapter->max_sds_rings = max_sds_rings;
+	clear_bit(__QLCNIC_RESETTING, &adapter->state);
+	return ret;
+}
+
 static void
 qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
 		     u64 *data)
@@ -704,6 +822,9 @@ qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
 		if (data[2])
 			eth_test->flags |= ETH_TEST_FL_FAILED;
 
+		data[3] = qlcnic_iloopback_test(dev);
+		if (data[3])
+			eth_test->flags |= ETH_TEST_FL_FAILED;
 
 	}
 }
diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c
index 81de563..0391a04 100644
--- a/drivers/net/qlcnic/qlcnic_hw.c
+++ b/drivers/net/qlcnic/qlcnic_hw.c
@@ -533,6 +533,56 @@ void qlcnic_delete_lb_filters(struct qlcnic_adapter *adapter)
 	}
 }
 
+int qlcnic_set_fw_loopback(struct qlcnic_adapter *adapter, u8 flag)
+{
+	struct qlcnic_nic_req req;
+	int rv;
+
+	memset(&req, 0, sizeof(struct qlcnic_nic_req));
+
+	req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
+	req.req_hdr = cpu_to_le64(QLCNIC_H2C_OPCODE_CONFIG_LOOPBACK |
+		((u64) adapter->portnum << 16) | ((u64) 0x1 << 32));
+
+	req.words[0] = cpu_to_le64(flag);
+
+	rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+	if (rv != 0)
+		dev_err(&adapter->pdev->dev, "%sting loopback mode failed\n",
+				flag ? "Set" : "Reset");
+	return rv;
+}
+
+int qlcnic_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
+{
+	if (qlcnic_set_fw_loopback(adapter, mode))
+		return -EIO;
+
+	if (qlcnic_nic_set_promisc(adapter, VPORT_MISS_MODE_ACCEPT_ALL)) {
+		qlcnic_set_fw_loopback(adapter, mode);
+		return -EIO;
+	}
+
+	msleep(1000);
+	return 0;
+}
+
+void qlcnic_clear_lb_mode(struct qlcnic_adapter *adapter)
+{
+	int mode = VPORT_MISS_MODE_DROP;
+	struct net_device *netdev = adapter->netdev;
+
+	qlcnic_set_fw_loopback(adapter, 0);
+
+	if (netdev->flags & IFF_PROMISC)
+		mode = VPORT_MISS_MODE_ACCEPT_ALL;
+	else if (netdev->flags & IFF_ALLMULTI)
+		mode = VPORT_MISS_MODE_ACCEPT_MULTI;
+
+	qlcnic_nic_set_promisc(adapter, mode);
+	msleep(1000);
+}
+
 /*
  * Send the interrupt coalescing parameter set by ethtool to the card.
  */
diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c
index 5b8bbcf..9d5bee0 100644
--- a/drivers/net/qlcnic/qlcnic_init.c
+++ b/drivers/net/qlcnic/qlcnic_init.c
@@ -1281,6 +1281,7 @@ qlcnic_handle_linkevent(struct qlcnic_adapter *adapter,
 	u16 cable_len;
 	u16 link_speed;
 	u8  link_status, module, duplex, autoneg;
+	u8 lb_status = 0;
 	struct net_device *netdev = adapter->netdev;
 
 	adapter->has_link_events = 1;
@@ -1292,6 +1293,7 @@ qlcnic_handle_linkevent(struct qlcnic_adapter *adapter,
 	link_status = msg->body[2] & 0xff;
 	duplex = (msg->body[2] >> 16) & 0xff;
 	autoneg = (msg->body[2] >> 24) & 0xff;
+	lb_status = (msg->body[2] >> 32) & 0x3;
 
 	module = (msg->body[2] >> 8) & 0xff;
 	if (module == LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE)
@@ -1301,6 +1303,9 @@ qlcnic_handle_linkevent(struct qlcnic_adapter *adapter,
 		dev_info(&netdev->dev, "unsupported cable length %d\n",
 				cable_len);
 
+	if (!link_status && (lb_status == 1))
+		adapter->ahw->loopback_state |= QLCNIC_LINKEVENT;
+
 	qlcnic_advert_link_change(adapter, link_status);
 
 	if (duplex == LINKEVENT_FULL_DUPLEX)
@@ -1319,7 +1324,9 @@ qlcnic_handle_fw_message(int desc_cnt, int index,
 {
 	struct qlcnic_fw_msg msg;
 	struct status_desc *desc;
-	int i = 0, opcode;
+	struct qlcnic_adapter *adapter;
+	struct device *dev;
+	int i = 0, opcode, ret;
 
 	while (desc_cnt > 0 && i < 8) {
 		desc = &sds_ring->desc_head[index];
@@ -1330,10 +1337,28 @@ qlcnic_handle_fw_message(int desc_cnt, int index,
 		desc_cnt--;
 	}
 
+	adapter = sds_ring->adapter;
+	dev = &adapter->pdev->dev;
 	opcode = qlcnic_get_nic_msg_opcode(msg.body[0]);
+
 	switch (opcode) {
 	case QLCNIC_C2H_OPCODE_GET_LINKEVENT_RESPONSE:
-		qlcnic_handle_linkevent(sds_ring->adapter, &msg);
+		qlcnic_handle_linkevent(adapter, &msg);
+		break;
+	case QLCNIC_C2H_OPCODE_CONFIG_LOOPBACK:
+		ret = (u32)(msg.body[1]);
+		switch (ret) {
+		case 0:
+			adapter->ahw->loopback_state |= QLCNIC_LB_RESPONSE;
+			break;
+		case 1:
+			dev_info(dev, "loopback already in progress\n");
+			break;
+		default:
+			dev_info(dev, "loopback configure request failed,"
+					" ret %x\n", ret);
+			break;
+		}
 		break;
 	default:
 		break;
@@ -1746,6 +1771,103 @@ qlcnic_post_rx_buffers_nodb(struct qlcnic_adapter *adapter,
 	spin_unlock(&rds_ring->lock);
 }
 
+static void dump_skb(struct sk_buff *skb)
+{
+	int i;
+	unsigned char *data = skb->data;
+
+	printk(KERN_INFO "\n");
+	for (i = 0; i < skb->len; i++) {
+		printk(KERN_INFO "%02x ", data[i]);
+		if ((i & 0x0f) == 8)
+			printk(KERN_INFO "\n");
+	}
+}
+
+void qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter,
+		struct qlcnic_host_sds_ring *sds_ring,
+		int ring, u64 sts_data0)
+{
+	struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
+	struct sk_buff *skb;
+	struct qlcnic_host_rds_ring *rds_ring;
+	int index, length, cksum, pkt_offset;
+
+	if (unlikely(ring >= adapter->max_rds_rings))
+		return;
+
+	rds_ring = &recv_ctx->rds_rings[ring];
+
+	index = qlcnic_get_sts_refhandle(sts_data0);
+	length = qlcnic_get_sts_totallength(sts_data0);
+	if (unlikely(index >= rds_ring->num_desc))
+		return;
+
+	cksum  = qlcnic_get_sts_status(sts_data0);
+	pkt_offset = qlcnic_get_sts_pkt_offset(sts_data0);
+
+	skb = qlcnic_process_rxbuf(adapter, rds_ring, index, cksum);
+	if (!skb)
+		return;
+
+	if (length > rds_ring->skb_size)
+		skb_put(skb, rds_ring->skb_size);
+	else
+		skb_put(skb, length);
+
+	if (pkt_offset)
+		skb_pull(skb, pkt_offset);
+
+	if (!qlcnic_check_loopback_buff(skb->data, adapter->mac_addr))
+		adapter->diag_cnt++;
+	else
+		dump_skb(skb);
+
+	dev_kfree_skb_any(skb);
+	adapter->stats.rx_pkts++;
+	adapter->stats.rxbytes += length;
+
+	return;
+}
+
+void
+qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring)
+{
+	struct qlcnic_adapter *adapter = sds_ring->adapter;
+	struct status_desc *desc;
+	u64 sts_data0;
+	int ring, opcode, desc_cnt;
+
+	u32 consumer = sds_ring->consumer;
+
+	desc = &sds_ring->desc_head[consumer];
+	sts_data0 = le64_to_cpu(desc->status_desc_data[0]);
+
+	if (!(sts_data0 & STATUS_OWNER_HOST))
+		return;
+
+	desc_cnt = qlcnic_get_sts_desc_cnt(sts_data0);
+	opcode = qlcnic_get_sts_opcode(sts_data0);
+	switch (opcode) {
+	case QLCNIC_RESPONSE_DESC:
+		qlcnic_handle_fw_message(desc_cnt, consumer, sds_ring);
+		break;
+	default:
+		ring = qlcnic_get_sts_type(sts_data0);
+		qlcnic_process_rcv_diag(adapter, sds_ring, ring, sts_data0);
+		break;
+	}
+
+	for (; desc_cnt > 0; desc_cnt--) {
+		desc = &sds_ring->desc_head[consumer];
+		desc->status_desc_data[0] = cpu_to_le64(STATUS_OWNER_PHANTOM);
+		consumer = get_next_index(consumer, sds_ring->num_desc);
+	}
+
+	sds_ring->consumer = consumer;
+	writel(consumer, sds_ring->crb_sts_consumer);
+}
+
 void
 qlcnic_fetch_mac(struct qlcnic_adapter *adapter, u32 off1, u32 off2,
 			u8 alt_mac, u8 *mac)
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index ac7f8a2..357436b 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -1391,6 +1391,12 @@ int qlcnic_diag_alloc_res(struct net_device *netdev, int test)
 			qlcnic_enable_int(sds_ring);
 		}
 	}
+
+	if (adapter->diag_test == QLCNIC_LOOPBACK_TEST) {
+		adapter->ahw->loopback_state = 0;
+		qlcnic_linkevent_request(adapter, 1);
+	}
+
 	set_bit(__QLCNIC_DEV_UP, &adapter->state);
 
 	return 0;
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH net-next 0/7] qlcnic: Misc. fixes and loopback support
From: Anirban Chakraborty @ 2011-06-22 12:52 UTC (permalink / raw)
  To: netdev; +Cc: David Miller, Anirban Chakraborty
In-Reply-To: <1308747144-23785-1-git-send-email-anirban.chakraborty@qlogic.com>

Please apply the series to net-next. Thanks.

-Anirban


^ permalink raw reply

* [PATCH 6/7] qlcnic: Add support to enable/disable FW dump capability
From: Anirban Chakraborty @ 2011-06-22 12:52 UTC (permalink / raw)
  To: netdev; +Cc: David Miller, Anirban Chakraborty
In-Reply-To: <1308747144-23785-1-git-send-email-anirban.chakraborty@qlogic.com>

In certain situations, it may be required to not enable FW dump
capability. Add support to turn off/on FW dump capability.

Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
---
 drivers/net/qlcnic/qlcnic.h         |    3 +++
 drivers/net/qlcnic/qlcnic_ctx.c     |    1 +
 drivers/net/qlcnic/qlcnic_ethtool.c |   19 +++++++++++++++++++
 drivers/net/qlcnic/qlcnic_main.c    |    8 +++++---
 4 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 58d7616..0be84bd 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -429,6 +429,7 @@ struct qlcnic_dump_template_hdr {
 
 struct qlcnic_fw_dump {
 	u8	clr;	/* flag to indicate if dump is cleared */
+	u8	enable; /* enable/disable dump */
 	u32	size;	/* total size of the dump */
 	void	*data;	/* dump data area */
 	struct	qlcnic_dump_template_hdr *tmpl_hdr;
@@ -1320,6 +1321,8 @@ enum op_codes {
 #define QLCNIC_DUMP_MASK_DEF		0x7f
 #define QLCNIC_DUMP_MASK_MAX		0xff
 #define QLCNIC_FORCE_FW_DUMP_KEY	0xdeadfeed
+#define QLCNIC_ENABLE_FW_DUMP		0xaddfeed
+#define QLCNIC_DISABLE_FW_DUMP		0xbadfeed
 
 struct qlcnic_dump_operations {
 	enum op_codes opcode;
diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c
index be2dee1..33f5c8a 100644
--- a/drivers/net/qlcnic/qlcnic_ctx.c
+++ b/drivers/net/qlcnic/qlcnic_ctx.c
@@ -150,6 +150,7 @@ int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter)
 		tmpl_hdr->drv_cap_mask = tmpl_hdr->cap_mask;
 	else
 		tmpl_hdr->drv_cap_mask = QLCNIC_DUMP_MASK_DEF;
+	ahw->fw_dump.enable = 1;
 error:
 	dma_free_coherent(&adapter->pdev->dev, temp_size, tmp_addr, tmp_addr_t);
 	return err;
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
index e183ed2..31f5cba 100644
--- a/drivers/net/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/qlcnic/qlcnic_ethtool.c
@@ -1019,8 +1019,27 @@ qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
 	struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
 
 	if (val->flag == QLCNIC_FORCE_FW_DUMP_KEY) {
+		if (!fw_dump->enable) {
+			netdev_info(netdev, "FW dump not enabled\n");
+			return ret;
+		}
+		if (fw_dump->clr) {
+			dev_info(&adapter->pdev->dev,
+			"Previous dump not cleared, not forcing dump\n");
+			return ret;
+		}
 		netdev_info(netdev, "Forcing a FW dump\n");
 		qlcnic_dev_request_reset(adapter);
+	} else if (val->flag == QLCNIC_DISABLE_FW_DUMP) {
+		if (fw_dump->enable) {
+			netdev_info(netdev, "Disabling FW dump\n");
+			fw_dump->enable = 0;
+		}
+	} else if (val->flag == QLCNIC_ENABLE_FW_DUMP) {
+		if (!fw_dump->enable && fw_dump->tmpl_hdr) {
+			netdev_info(netdev, "Enabling FW dump\n");
+			fw_dump->enable = 1;
+		}
 	} else {
 		if (val->flag > QLCNIC_DUMP_MASK_MAX ||
 			val->flag < QLCNIC_DUMP_MASK_MIN) {
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 5dcb853..ac7f8a2 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -2849,9 +2849,11 @@ skip_ack_check:
 		qlcnic_api_unlock(adapter);
 
 		rtnl_lock();
-		QLCDB(adapter, DRV, "Take FW dump\n");
-		qlcnic_dump_fw(adapter);
-		adapter->flags &= ~QLCNIC_FW_RESET_OWNER;
+		if (adapter->ahw->fw_dump.enable) {
+			QLCDB(adapter, DRV, "Take FW dump\n");
+			qlcnic_dump_fw(adapter);
+			adapter->flags &= ~QLCNIC_FW_RESET_OWNER;
+		}
 		rtnl_unlock();
 		if (!adapter->nic_ops->start_firmware(adapter)) {
 			qlcnic_schedule_work(adapter, qlcnic_attach_work, 0);
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 1/7] qlcnic: Add capability to take FW dump deterministically
From: Anirban Chakraborty @ 2011-06-22 12:52 UTC (permalink / raw)
  To: netdev; +Cc: David Miller, Sritej Velaga

From: Sritej Velaga <sritej.velaga@qlogic.com>

In presence of multiple functions, current driver implementation does not
guarantee that the FW dump is taken by the same function that forces it.
Change it by adding a fw reset owner flag that could be changed in the device
reset path and only when a function determines that it needs to reset it.

Signed-off-by: Sritej Velaga <sritej.velaga@qlogic.com>
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
---
 drivers/net/qlcnic/qlcnic.h      |    1 +
 drivers/net/qlcnic/qlcnic_ctx.c  |    4 ++--
 drivers/net/qlcnic/qlcnic_main.c |   32 ++++++++++++++++++++++++--------
 3 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 480ef5c..194376e 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -895,6 +895,7 @@ struct qlcnic_ipaddr {
 #define QLCNIC_MAC_OVERRIDE_DISABLED	0x400
 #define QLCNIC_PROMISC_DISABLED		0x800
 #define QLCNIC_NEED_FLR			0x1000
+#define QLCNIC_FW_RESET_OWNER		0x2000
 #define QLCNIC_IS_MSI_FAMILY(adapter) \
 	((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED))
 
diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c
index c77024f..be2dee1 100644
--- a/drivers/net/qlcnic/qlcnic_ctx.c
+++ b/drivers/net/qlcnic/qlcnic_ctx.c
@@ -95,8 +95,8 @@ int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter)
 			QLCNIC_CDRP_CMD_TEMP_SIZE);
 	if (err != QLCNIC_RCODE_SUCCESS) {
 		err = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET);
-		dev_err(&adapter->pdev->dev,
-			"Failed to get template size %d\n", err);
+		dev_info(&adapter->pdev->dev,
+			"Can't get template size %d\n", err);
 		err = -EIO;
 		return err;
 	}
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 347a4a8..0ddbb80 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -1590,10 +1590,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	/* This will be reset for mezz cards  */
 	adapter->portnum = adapter->ahw->pci_func;
 
-	/* Get FW dump template and store it */
-	if (adapter->op_mode != QLCNIC_NON_PRIV_FUNC)
-		qlcnic_fw_cmd_get_minidump_temp(adapter);
-
 	err = qlcnic_get_board_info(adapter);
 	if (err) {
 		dev_err(&pdev->dev, "Error getting board config info.\n");
@@ -1612,6 +1608,12 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto err_out_decr_ref;
 	}
 
+	/* Get FW dump template and store it */
+	if (adapter->op_mode != QLCNIC_NON_PRIV_FUNC)
+		if (!qlcnic_fw_cmd_get_minidump_temp(adapter))
+			dev_info(&pdev->dev,
+				"Supports FW dump capability\n");
+
 	if (qlcnic_read_mac_addr(adapter))
 		dev_warn(&pdev->dev, "failed to read mac addr\n");
 
@@ -2683,11 +2685,16 @@ err:
 static int
 qlcnic_check_drv_state(struct qlcnic_adapter *adapter)
 {
-	int act, state;
+	int act, state, active_mask;
 
 	state = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE);
 	act = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE);
 
+	if (adapter->flags & QLCNIC_FW_RESET_OWNER) {
+		active_mask = (~(1 << (adapter->ahw->pci_func * 4)));
+		act = act & active_mask;
+	}
+
 	if (((state & 0x11111111) == (act & 0x11111111)) ||
 			((act & 0x11111111) == ((state >> 1) & 0x11111111)))
 		return 0;
@@ -2826,6 +2833,11 @@ qlcnic_fwinit_work(struct work_struct *work)
 
 	if (!qlcnic_check_drv_state(adapter)) {
 skip_ack_check:
+		if (!(adapter->flags & QLCNIC_FW_RESET_OWNER)) {
+			qlcnic_api_unlock(adapter);
+			goto wait_npar;
+		}
+
 		dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
 
 		if (dev_state == QLCNIC_DEV_NEED_RESET) {
@@ -2836,6 +2848,7 @@ skip_ack_check:
 			qlcnic_idc_debug_info(adapter, 0);
 			QLCDB(adapter, DRV, "Take FW dump\n");
 			qlcnic_dump_fw(adapter);
+			adapter->flags &= ~QLCNIC_FW_RESET_OWNER;
 		}
 
 		qlcnic_api_unlock(adapter);
@@ -2900,9 +2913,11 @@ qlcnic_detach_work(struct work_struct *work)
 
 	if (adapter->temp == QLCNIC_TEMP_PANIC)
 		goto err_ret;
-
-	if (qlcnic_set_drv_state(adapter, adapter->dev_state))
-		goto err_ret;
+	/* Dont ack if this instance is the reset owner */
+	if (!(adapter->flags & QLCNIC_FW_RESET_OWNER)) {
+		if (qlcnic_set_drv_state(adapter, adapter->dev_state))
+			goto err_ret;
+	}
 
 	adapter->fw_wait_cnt = 0;
 
@@ -2947,6 +2962,7 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
 
 	if (state == QLCNIC_DEV_READY) {
 		QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_NEED_RESET);
+		adapter->flags |= QLCNIC_FW_RESET_OWNER;
 		QLCDB(adapter, DRV, "NEED_RESET state set\n");
 		qlcnic_idc_debug_info(adapter, 0);
 	}
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 5/7] qlcnic: fix default operating state of interface
From: Anirban Chakraborty @ 2011-06-22 12:52 UTC (permalink / raw)
  To: netdev; +Cc: David Miller, Amit Kumar Salecha
In-Reply-To: <1308747144-23785-1-git-send-email-anirban.chakraborty@qlogic.com>

From: Amit Kumar Salecha <amit.salecha@qlogic.com>

Currently interface shows status as RUNNING, even if there is no link.
To fix this, netif_carrier_off should be called qlcnic_open().

Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
---
 drivers/net/qlcnic/qlcnic_main.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index a050746..5dcb853 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -1485,8 +1485,6 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter,
 
 	netdev->irq = adapter->msix_entries[0].vector;
 
-	netif_carrier_off(netdev);
-
 	err = register_netdev(netdev);
 	if (err) {
 		dev_err(&pdev->dev, "failed to register net device\n");
@@ -1816,6 +1814,8 @@ static int qlcnic_open(struct net_device *netdev)
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 	int err;
 
+	netif_carrier_off(netdev);
+
 	err = qlcnic_attach(adapter);
 	if (err)
 		return err;
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 2/7] qlcnic: Remove holding api lock while taking the dump
From: Anirban Chakraborty @ 2011-06-22 12:52 UTC (permalink / raw)
  To: netdev; +Cc: David Miller, Anirban Chakraborty
In-Reply-To: <1308747144-23785-1-git-send-email-anirban.chakraborty@qlogic.com>

With the change in logic for taking FW dump across multiple drivers,
there is no need to hold onto the api lock anymore in the fw dump path.
Instead use rtnl_lock() to synchronize the access to FW dump data structs.

Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
---
 drivers/net/qlcnic/qlcnic_ethtool.c |    6 ------
 drivers/net/qlcnic/qlcnic_main.c    |    8 +++++---
 2 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
index 8ea8001..e183ed2 100644
--- a/drivers/net/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/qlcnic/qlcnic_ethtool.c
@@ -986,8 +986,6 @@ qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 	struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
 
-	if (qlcnic_api_lock(adapter))
-		return -EIO;
 	if (!fw_dump->clr) {
 		netdev_info(netdev, "Dump not available\n");
 		qlcnic_api_unlock(adapter);
@@ -1009,7 +1007,6 @@ qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
 	vfree(fw_dump->data);
 	fw_dump->data = NULL;
 	fw_dump->clr = 0;
-	qlcnic_api_unlock(adapter);
 
 	return 0;
 }
@@ -1032,10 +1029,7 @@ qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
 				ret = -EINVAL;
 				goto out;
 		}
-		if (qlcnic_api_lock(adapter))
-			return -EIO;
 		fw_dump->tmpl_hdr->drv_cap_mask = val->flag & 0xff;
-		qlcnic_api_unlock(adapter);
 		netdev_info(netdev, "Driver mask changed to: 0x%x\n",
 			fw_dump->tmpl_hdr->drv_cap_mask);
 	}
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 0ddbb80..a656a12 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -2846,13 +2846,15 @@ skip_ack_check:
 			set_bit(__QLCNIC_START_FW, &adapter->state);
 			QLCDB(adapter, DRV, "Restarting fw\n");
 			qlcnic_idc_debug_info(adapter, 0);
-			QLCDB(adapter, DRV, "Take FW dump\n");
-			qlcnic_dump_fw(adapter);
-			adapter->flags &= ~QLCNIC_FW_RESET_OWNER;
 		}
 
 		qlcnic_api_unlock(adapter);
 
+		rtnl_lock();
+		QLCDB(adapter, DRV, "Take FW dump\n");
+		qlcnic_dump_fw(adapter);
+		adapter->flags &= ~QLCNIC_FW_RESET_OWNER;
+		rtnl_unlock();
 		if (!adapter->nic_ops->start_firmware(adapter)) {
 			qlcnic_schedule_work(adapter, qlcnic_attach_work, 0);
 			adapter->fw_wait_cnt = 0;
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 3/7] qlcnic: Add code to tune FW dump
From: Anirban Chakraborty @ 2011-06-22 12:52 UTC (permalink / raw)
  To: netdev; +Cc: David Miller, Anirban Chakraborty
In-Reply-To: <1308747144-23785-1-git-send-email-anirban.chakraborty@qlogic.com>

To accommodate change in FW dump template, it is required to modify the
FW dump routine that captures cache data. Also, the default mask is changed
to capture a dump that would cover all the protocols that this FW supports.

Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
---
 drivers/net/qlcnic/qlcnic.h    |    5 ++---
 drivers/net/qlcnic/qlcnic_hw.c |   14 +++++++++++---
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 194376e..e5bb332 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -1220,8 +1220,7 @@ struct __ctrl {
 
 struct __cache {
 	__le32	addr;
-	u8	stride;
-	u8	rsvd;
+	__le16	stride;
 	__le16	init_tag_val;
 	__le32	size;
 	__le32	no_ops;
@@ -1319,7 +1318,7 @@ enum op_codes {
 #define QLCNIC_DUMP_SKIP	BIT_7
 
 #define QLCNIC_DUMP_MASK_MIN		3
-#define QLCNIC_DUMP_MASK_DEF		0x0f
+#define QLCNIC_DUMP_MASK_DEF		0x7f
 #define QLCNIC_DUMP_MASK_MAX		0xff
 #define QLCNIC_FORCE_FW_DUMP_KEY	0xdeadfeed
 
diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c
index 1947f81..81de563 100644
--- a/drivers/net/qlcnic/qlcnic_hw.c
+++ b/drivers/net/qlcnic/qlcnic_hw.c
@@ -1509,18 +1509,26 @@ qlcnic_dump_l2_cache(struct qlcnic_adapter *adapter,
 
 	for (i = 0; i < l2->no_ops; i++) {
 		QLCNIC_WR_DUMP_REG(l2->addr, base, val);
-		do {
+		if (LSW(l2->ctrl_val))
 			QLCNIC_WR_DUMP_REG(l2->ctrl_addr, base,
 				LSW(l2->ctrl_val));
+		if (!poll_mask)
+			goto skip_poll;
+		do {
 			QLCNIC_RD_DUMP_REG(l2->ctrl_addr, base, &data);
 			if (!(data & poll_mask))
 				break;
 			msleep(1);
 			time_out++;
 		} while (time_out <= poll_to);
-		if (time_out > poll_to)
-			return -EINVAL;
 
+		if (time_out > poll_to) {
+			dev_err(&adapter->pdev->dev,
+				"Timeout exceeded in %s, aborting dump\n",
+				__func__);
+			return -EINVAL;
+		}
+skip_poll:
 		addr = l2->read_addr;
 		cnt = l2->read_addr_num;
 		while (cnt) {
-- 
1.7.4.1


^ 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