Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH] net: use CHECKSUM_NONE instead of magic number
From: David Miller @ 2011-03-28  1:37 UTC (permalink / raw)
  To: cesarb
  Cc: netdev, kuznet, pekkas, jmorris, yoshfuji, kaber, eric.dumazet,
	Tristram.Ha, linux-kernel
In-Reply-To: <1301152230-4897-1-git-send-email-cesarb@cesarb.net>

From: Cesar Eduardo Barros <cesarb@cesarb.net>
Date: Sat, 26 Mar 2011 12:10:30 -0300

> Two places in the kernel were doing skb->ip_summed = 0.
> 
> Change both to skb->ip_summed = CHECKSUM_NONE, which is more readable.
> 
> Signed-off-by: Cesar Eduardo Barros <cesarb@cesarb.net>

Applied, thank you.

^ permalink raw reply

* Re: [PATCH] Net / jme: Do not use legacy PCI power management
From: David Miller @ 2011-03-28  1:36 UTC (permalink / raw)
  To: rjw; +Cc: netdev, linux-kernel, linux-pm
In-Reply-To: <201103261234.06274.rjw@sisk.pl>

From: "Rafael J. Wysocki" <rjw@sisk.pl>
Date: Sat, 26 Mar 2011 12:34:06 +0100

> From: Rafael J. Wysocki <rjw@sisk.pl>
> 
> The jme driver uses the legacy PCI power management, so it has to do
> some PCI-specific things in its ->suspend() and ->resume() callbacks,
> which isn't necessary and should better be done by the PCI
> sybsystem-level power management code.  It also doesn't use device
> wakeup flags correctly.
> 
> Convert jme to the new PCI power management framework and make it
> let the PCI subsystem take care of all the PCI-specific aspects of
> device handling during system power transitions.
> 
> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>

Applied, thanks a lot.

^ permalink raw reply

* Re: [PATCH] myri10ge: small rx_done refactoring
From: David Miller @ 2011-03-28  1:35 UTC (permalink / raw)
  To: gallatin; +Cc: sgruszka, netdev, brice, shemminger, dhowells, bhutchings
In-Reply-To: <4D8C92B9.1010109@myri.com>

From: Andrew Gallatin <gallatin@myri.com>
Date: Fri, 25 Mar 2011 09:03:53 -0400

> On 03/25/11 07:21, Stanislaw Gruszka wrote:
>> Avoid theoretical race condition regarding accessing dev->features
>> NETIF_F_LRO flag, which is illustrated below.
>>
 ...
>>
>> On the way reduce myri10ge_rx_done() number of arguments and calls by
>> moving mgp->small_bytes check into that function. That reduce code
>> size
>>
...
>>
>> on my i686 system, what should also make myri10ge_clean_rx_done()
>> being faster.
>>
>> Signed-off-by: Stanislaw Gruszka<sgruszka@redhat.com>
> 
> Thank you very much!
> 
> Acked by: Andrew Gallatin <gallatin@myri.com>

Applied, thanks everyone.

^ permalink raw reply

* Re: [PATCH] bridge: notify applications if address of bridge device changes
From: David Miller @ 2011-03-28  1:34 UTC (permalink / raw)
  To: shemminger; +Cc: netdev, bridge
In-Reply-To: <20110324162401.2f322e3e@nehalam>

From: Stephen Hemminger <shemminger@vyatta.com>
Date: Thu, 24 Mar 2011 16:24:01 -0700

> The mac address of the bridge device may be changed when a new interface
> is added to the bridge. If this happens, then the bridge needs to call
> the network notifiers to tickle any other systems that care. Since bridge
> can be a module, this also means exporting the notifier function.
> 
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

Applied, thanks Stephen.

^ permalink raw reply

* Re: [PATCH] Fix IP timestamp option (IPOPT_TS_PRESPEC) handling in ip_options_echo()
From: David Miller @ 2011-03-28  1:32 UTC (permalink / raw)
  To: jluebbe; +Cc: netdev
In-Reply-To: <1301033472.3890.181.camel@mordor>

From: Jan Lübbe <jluebbe@debian.org>
Date: Fri, 25 Mar 2011 07:11:12 +0100

> The encoding of soffset is a bit unusual, in that the option is 'full'
> when soffset = optlen + 1. We need to keep advancing soffset by 8
> because that's really the amount of data per entry.

Ok, this code is officially terrible :-)

Thanks for explaining things, I've applied your patch, thanks.

^ permalink raw reply

* Re: [PATCH 4/4] can: c_can: remove duplicated #include
From: David Miller @ 2011-03-28  1:24 UTC (permalink / raw)
  To: wg-5Yr1BZd7O62+XT7JhA+gdA
  Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
	Netdev-u79uwXL29TY76Z2rM5mHXA, weiyi.huang-Re5JQEeQqe8AvxtiuMwx3w
In-Reply-To: <4D8B6E36.601-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>

From: Wolfgang Grandegger <wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
Date: Thu, 24 Mar 2011 17:15:50 +0100

> I added a CC to the netdev mailing list. Hope that's sufficient to get
> the patch accepted.

It's not, the patch must be submitted originally to netdev.

^ permalink raw reply

* Re: [PATCH resend] can: c_can: Fix tx_bytes accounting
From: David Miller @ 2011-03-28  1:24 UTC (permalink / raw)
  To: wg-5Yr1BZd7O62+XT7JhA+gdA
  Cc: Socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
	netdev-u79uwXL29TY76Z2rM5mHXA, jan-hfZtesqFncYOwBW4kG4KsQ,
	b.spranger-hfZtesqFncYOwBW4kG4KsQ
In-Reply-To: <4D8B2FAF.5040000-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>

From: Wolfgang Grandegger <wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
Date: Thu, 24 Mar 2011 12:49:03 +0100

> On 03/24/2011 11:49 AM, Kurt Van Dijck wrote:
>> On Thu, Mar 24, 2011 at 12:26:50PM +0100, Jan Altenberg wrote:
>>> The current SocketCAN implementation for the Bosch c_can cell doesn't
>>> account the TX bytes correctly, because it calls
>>> c_can_inval_msg_object() (which clears the msg ctrl register) before
>>> reading the DLC value:
>>>
>>> The fix is quite easy: Just move c_can_inval_msg_object() to the end of
>>> the if() statement. So:
>>>       * We only call c_can_inval_msg_object() if the message was
>>>         actually transmitted
>>>       * We read out the DLC value _before_ clearing the msg ctrl
>>>         register
>>>
>>> Signed-off-by: Jan Altenberg <jan-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
>> Acked-by: Kurt Van Dijck <kurt.van.dijck-/BeEPy95v10@public.gmane.org>
> Acked-by: Wolfgang Grandegger <wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>

Applied.

^ permalink raw reply

* Re: [PATCH 2/2] can: c_can_platform: fix irq check in probe
From: David Miller @ 2011-03-28  1:20 UTC (permalink / raw)
  To: mkl-bIcnvbaLZ9MEGnE8C9+IrQ
  Cc: Socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
	netdev-u79uwXL29TY76Z2rM5mHXA, jan-hfZtesqFncYOwBW4kG4KsQ
In-Reply-To: <1300970073-25522-3-git-send-email-mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>

From: Marc Kleine-Budde <mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
Date: Thu, 24 Mar 2011 13:34:33 +0100

> This patch fixes the check in the probe function whether a IRQ was supplied
> to the driver. The original driver check the irq "struct resource *" against
> <= 0. Use "platform_get_irq" instead.
> 
> Signed-off-by: Marc Kleine-Budde <mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>

Applied.

^ permalink raw reply

* Re: [PATCH v2] can: c_can: disable one shot mode until driver is fixed
From: David Miller @ 2011-03-28  1:19 UTC (permalink / raw)
  To: wg-5Yr1BZd7O62+XT7JhA+gdA
  Cc: Socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
	netdev-u79uwXL29TY76Z2rM5mHXA, mkl-bIcnvbaLZ9MEGnE8C9+IrQ,
	jan-hfZtesqFncYOwBW4kG4KsQ
In-Reply-To: <4D8B3163.8080706-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>

From: Wolfgang Grandegger <wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
Date: Thu, 24 Mar 2011 12:56:19 +0100

> On 03/24/2011 12:00 PM, Marc Kleine-Budde wrote:
>> This patch disables the one shot mode, until the driver has been fixed and
>> tested to support it.
>> 
>>> I'm quite sure I've seen a situation where msg_obj 17 "seemed" to be
>>> pending, while msg_obj 18 and 19 already have been transmitted. But
>>> in that case, I enabled ONESHOT for the can interface, which enables
>>> the DA mode (automatic retransmission is disabled).
>> 
>> Reported-by: Jan Altenberg <jan-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
>> Signed-off-by: Marc Kleine-Budde <mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
>> Signed-off-by: Kurt Van Dijck <kurt.van.dijck-/BeEPy95v10@public.gmane.org>
>> Cc: Bhupesh Sharma <bhupesh.sharma-qxv4g6HH51o@public.gmane.org>
> Acked-by: Wolfgang Grandegger <wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>

Applied, thanks everyone.

^ permalink raw reply

* Re: [PATCH] sctp: Make some local functions static
From: David Miller @ 2011-03-28  1:16 UTC (permalink / raw)
  To: holger; +Cc: netdev, linux-sctp
In-Reply-To: <4D89CFE7.4050907@freyther.de>

From: Holger Hans Peter Freyther <holger@freyther.de>
Date: Wed, 23 Mar 2011 11:48:07 +0100

> @@ -132,8 +132,8 @@ void  sctp_init_cause(struct sctp_chunk *chunk, __be16
> cause_code,

Your patches are corrupted by your email client, in particular it has
chopped up long lines.

Please fix your email setup, test it out by emailing both of your SCTP
patches to yourself, then try to apply the patches in the emails you
receive.

Then you can freshly resubmit them here.

Thank you.

^ permalink raw reply

* Re: [PATCH] can: make struct proto const
From: David Miller @ 2011-03-28  1:14 UTC (permalink / raw)
  To: kurt.van.dijck; +Cc: socketcan, netdev
In-Reply-To: <20110322190038.GA286@e-circ.dyndns.org>

From: Kurt Van Dijck <kurt.van.dijck@eia.be>
Date: Tue, 22 Mar 2011 20:00:38 +0100

> On Tue, Mar 22, 2011 at 07:27:25PM +0100, Oliver Hartkopp wrote:
>> can_ioctl is the only reason for struct proto to be non-const.
>> script/check-patch.pl suggests struct proto be const.
>> 
>> Setting the reference to the common can_ioctl() in all CAN protocols directly
>> removes the need to make the struct proto writable in af_can.c
>> 
>> Signed-off-by: Kurt Van Dijck <kurt.van.dijck@eia.be>
>> Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
>> 
> Good idea to take this apart from my J1939 series.

Applied, thanks.

^ permalink raw reply

* Re: [Patch] net: remove useless comments in net/core/dev.c
From: David Miller @ 2011-03-28  1:12 UTC (permalink / raw)
  To: amwang; +Cc: linux-kernel, eric.dumazet, xiaosuo, therbert, jesse, netdev
In-Reply-To: <1300795189-24655-1-git-send-email-amwang@redhat.com>

From: Amerigo Wang <amwang@redhat.com>
Date: Tue, 22 Mar 2011 19:59:47 +0800

> The code itself can explain what it is doing, no need these comments.
> 
> Signed-off-by: WANG Cong <amwang@redhat.com>

Agreed, these comments are superfluous, applied thanks!

^ permalink raw reply

* Re: [PATCH] usbnet: fix memory leak in usbnet_disconnect()
From: David Miller @ 2011-03-28  1:11 UTC (permalink / raw)
  To: xmb836; +Cc: netdev, a20612, jxchang
In-Reply-To: <AANLkTintuq7z45e-Cr8Ma5_Bm+UtnO+Gsysn6A3kv+CZ@mail.gmail.com>

From: DMITRIY GRUZMAN <xmb836@motorola.com>
Date: Mon, 21 Mar 2011 16:49:50 -0500

> usb_probe() allocates memory for transfer buffer and urb and this
> memory was not properly released in usbnet_disconnect().   The issue
> was found and the fix was recommended by Fu-Lei Tian and Jun-Xiao
> Chang.
> 
> Signed-off-by: Dmitriy Gruzman <xmb836@motorola.com>

Your email client corrupted your patch, among other things:

> @@ -210,6 +210,7 @@ static int init_status (struct usbnet *dev, struct
> usb_interface *intf)

it chopped up long lines.

Please fix this up, test your setup by emailing the patch to yourself
and trying to apply what you receive, then try submitting it here
freshly again.

Thanks.

^ permalink raw reply

* Re: [PATCH] net: Handle gso packets in dev_forward_skb
From: David Miller @ 2011-03-28  1:09 UTC (permalink / raw)
  To: ebiederm; +Cc: eric.dumazet, netdev, greearb, arnd, kaber
In-Reply-To: <m1hbawi15z.fsf@fess.ebiederm.org>

From: ebiederm@xmission.com (Eric W. Biederman)
Date: Mon, 21 Mar 2011 15:00:56 -0700

> Eric Dumazet <eric.dumazet@gmail.com> writes:
> 
>> Hmm, did you follow http://patchwork.ozlabs.org/patch/86815/
>> discussion ?
> 
> No.  It seems I missed it, but I do have the same problem, and
> essentially the same fix. 

Can someone work on getting this straightened out and resubmit the
final patch so I can apply something?

Thanks.

^ permalink raw reply

* Re: [PATCH] netxen: fix LRO disable warning
From: David Miller @ 2011-03-28  1:08 UTC (permalink / raw)
  To: amit.salecha; +Cc: eric.dumazet, netdev, ameen.rahman, rajesh.borundia
In-Reply-To: <99737F4847ED0A48AECC9F4A1974A4B80FD10E8439@MNEXMB2.qlogic.org>

From: Amit Salecha <amit.salecha@qlogic.com>
Date: Mon, 21 Mar 2011 06:13:02 -0500

>> Le lundi 21 mars 2011 à 03:37 -0700, Amit Kumar Salecha a écrit :
>> > netxen_nic_set_flags() rejects data if other flag than ETH_FLAG_LRO
>> is set.
>> > Driver also supports NETIF_F_HW_VLAN_TX.
>> > Now compare data with ethtool_op_get_flags(), to get all supported
>> features.
>> >
>> > Reported-by: Jesper Dangaard Brouer <jdb@comx.dk>
>> > Signed-off-by: Rajesh Borundia <rajesh.borundia@qlogic.com>
>> > Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
>> > ---
>>
>> Hmm, it would be really nice you provide more information for stable
>> teams.
>>
>> If I am not mistaken, bug was introduced in 2.6.36 ?
>>
> No, It was introduced in 2.6.37, when ETH_FLAG_TXVLAN and ETH_FLAG_RXVLAN introduced.
> Yes it should also make into 2.6.37.4 stable kernel.

Applied, but 2.6.37.x maintainence has ceased so there is no point
worrying about this patch for that stable branch any longer.

^ permalink raw reply

* Re: [PATCH 1/1] solos-pci: Use shared code for VCC management
From: David Miller @ 2011-03-28  1:06 UTC (permalink / raw)
  To: philipp_subx; +Cc: netdev, linux-atm-general
In-Reply-To: <4D867FF2.5040107@redfish-solutions.com>


None of your patches apply cleanly to the current net-2.6
tree.

Please respin all of your patches against net-2.6 so that I
can apply them properly.

Thanks.

^ permalink raw reply

* Re: [PATCH] irda: validate peer name and attribute lengths
From: David Miller @ 2011-03-28  0:59 UTC (permalink / raw)
  To: drosenberg; +Cc: samuel, netdev, security
In-Reply-To: <1300671126.9043.8.camel@dan>

From: Dan Rosenberg <drosenberg@vsecurity.com>
Date: Sun, 20 Mar 2011 21:32:06 -0400

> Length fields provided by a peer for names and attributes may be longer
> than the destination array sizes.  Validate lengths to prevent stack
> buffer overflows.
> 
> Signed-off-by: Dan Rosenberg <drosenberg@vsecurity.com>
> Cc: stable@kernel.org

Applied.

^ permalink raw reply

* Re: [PATCH v2] ROSE: prevent heap corruption with bad facilities
From: David Miller @ 2011-03-28  0:59 UTC (permalink / raw)
  To: ben; +Cc: drosenberg, ralf, netdev, security
In-Reply-To: <1300639685.26693.286.camel@localhost>

From: Ben Hutchings <ben@decadent.org.uk>
Date: Sun, 20 Mar 2011 16:48:05 +0000

> Subject: [PATCH] rose: Add length checks to CALL_REQUEST parsing
> 
> Define some constant offsets for CALL_REQUEST based on the description
> at <http://www.techfest.com/networking/wan/x25plp.htm> and the
> definition of ROSE as using 10-digit (5-byte) addresses.  Use them
> consistently.  Validate all implicit and explicit facilities lengths.
> Validate the address length byte rather than either trusting or
> assuming its value.
> 
> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>

Applied.

^ permalink raw reply

* Re: [PATCH v2] ROSE: prevent heap corruption with bad facilities
From: David Miller @ 2011-03-28  0:59 UTC (permalink / raw)
  To: drosenberg; +Cc: ralf, netdev, security
In-Reply-To: <1300603423.1869.18.camel@dan>

From: Dan Rosenberg <drosenberg@vsecurity.com>
Date: Sun, 20 Mar 2011 02:43:43 -0400

> When parsing the FAC_NATIONAL_DIGIS facilities field, it's possible for
> a remote host to provide more digipeaters than expected, resulting in
> heap corruption.  Check against ROSE_MAX_DIGIS to prevent overflows, and
> abort facilities parsing on failure.
> 
> Additionally, when parsing the FAC_CCITT_DEST_NSAP and
> FAC_CCITT_SRC_NSAP facilities fields, a remote host can provide a length
> of less than 10, resulting in an underflow in a memcpy size, causing a
> kernel panic due to massive heap corruption.  A length of greater than
> 20 results in a stack overflow of the callsign array.  Abort facilities
> parsing on these invalid length values.
> 
> Signed-off-by: Dan Rosenberg <drosenberg@vsecurity.com>
> Cc: stable@kernel.org

Applied.

^ permalink raw reply

* Re: [PATCH v2] irda: prevent heap corruption on invalid nickname
From: David Miller @ 2011-03-28  0:59 UTC (permalink / raw)
  To: drosenberg; +Cc: samuel, netdev, security
In-Reply-To: <1300601670.1869.5.camel@dan>

From: Dan Rosenberg <drosenberg@vsecurity.com>
Date: Sun, 20 Mar 2011 02:14:30 -0400

> Invalid nicknames containing only spaces will result in an underflow in
> a memcpy size calculation, subsequently destroying the heap and
> panicking.
> 
> v2 also catches the case where the provided nickname is longer than the
> buffer size, which can result in controllable heap corruption.
> 
> Signed-off-by: Dan Rosenberg <drosenberg@vsecurity.com>
> Cc: stable@kernel.org

Applied.

^ permalink raw reply

* [PATCH] net: Always allocate at least 16 skb frags regardless of page size
From: Anton Blanchard @ 2011-03-28  0:57 UTC (permalink / raw)
  To: davem, eric.dumazet, herbert; +Cc: netdev


When analysing performance of the cxgb3 on a ppc64 box I noticed that
we weren't doing much GRO merging. It turns out we are limited by the
number of SKB frags:

#define MAX_SKB_FRAGS (65536/PAGE_SIZE + 2)

With a 4kB page size we have 18 frags, but with a 64kB page size we
only have 3 frags.

I ran a single stream TCP bandwidth test to compare the performance of
different values of MAX_SKB_FRAGS on the receiver:

MAX_SKB_FRAGS   Mbps
3               7080	
8               7931    (+12%)
16              8335	(+17%)
32              8349	(+17%)

Performance continues to increase up to 16 frags then levels off so
the patch below puts a lower bound of 16 on MAX_SKB_FRAGS.

Signed-off-by: Anton Blanchard <anton@samba.org>
---

Index: powerpc.git/include/linux/skbuff.h
===================================================================
--- powerpc.git.orig/include/linux/skbuff.h	2011-03-28 09:41:25.392124844 +1100
+++ powerpc.git/include/linux/skbuff.h	2011-03-28 10:18:58.253050000 +1100
@@ -122,8 +122,14 @@ struct sk_buff_head {
 
 struct sk_buff;
 
-/* To allow 64K frame to be packed as single skb without frag_list */
+/* To allow 64K frame to be packed as single skb without frag_list. Since
+ * GRO uses frags we allocate at least 16 regardless of page size.
+ */
+#if (65536/PAGE_SIZE + 2) < 16
+#define MAX_SKB_FRAGS 16
+#else
 #define MAX_SKB_FRAGS (65536/PAGE_SIZE + 2)
+#endif
 
 typedef struct skb_frag_struct skb_frag_t;
 

^ permalink raw reply

* Re: [RFC PATCH] rtl8187: Fix led support for rfkill
From: Larry Finger @ 2011-03-27 22:47 UTC (permalink / raw)
  To: Hin-Tak Leung
  Cc: wu zhangjin, Herton Ronaldo Krzesinski,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA, Roman Mamedov
In-Reply-To: <4D8E8B1E.3030709-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>

On 03/26/2011 07:55 PM, Hin-Tak Leung wrote:
> wu zhangjin wrote:
>> On Sun, Mar 27, 2011 at 5:33 AM, Hin-Tak Leung
>> <htl10-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> wrote:
>>> Wu Zhangjin wrote:
>>>> led can not be turned off normally when rfkill is blocked, the cause is
>>>> the led_turn_off() function exit as not expected:
>>> Hmm. While this sounds more sensible, is it needed? And what does the
>>> windows driver do?
>>>
>>> I think there are two kind of LEDs - one that comes on and off with the
>>> rfkill switch; Larry or Herton makes the 2nd one, if there is one, blink
>>> while there is traffic (and stay steady on otherwise).
>>
>> I have used this driver on the YeeLoong netbook(only support Linux),
>> there is only one LED for rtl8187, when there is traffic, it blinks
>> perfectly, but If press the hotkey to turn off the rf, the network
>> interface is down, but the LED is still light, then, the users may
>> mistakenly think the hotkey or rfkill support doesn't work or simply
>> think the interface is still on. So, that's why we may need to fix it.
>
> My laptop (a Toshiba one) has the other kind of LED - the LED only comes on and
> off in relation to the rfkill switch, and does not blink with traffic. I think
> Herton or Larry has some devices with both types.
>
> Hmm, I seem to have the impression that there is code somewhere for switching a
> singular LED's behavior of the driver between one or the other, by echo'ing into
> sysfs or some other trickery? Or would that be a desired approach if that's not
> done at the moment?

My rtl8187 devices are both external USB sticks, thus they have no interaction 
with a radio-kill switch. I will test your patch to make sure it does no harm to 
my system.

I think the commit message should be revised. A simple statement like "the LED 
does not turn off when the rfkill switch is off" should be sufficient.

Larry

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" 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

* [PATCH] net/usb: Ethernet quirks for the LG-VL600 4G modem
From: Andrzej Zaborowski @ 2011-03-27 22:04 UTC (permalink / raw)
  To: netdev; +Cc: Oliver Neukum, David Brownell, linux-kernel, balrogg

This adds a driver for the CDC Ethernet part of this modem.  The
device's ID is blacklisted in cdc_ether.c and is white-listed in
this new driver because of the quirks needed to make it useful.
The modem's firmware exposes a CDC ACM port for modem control and a
CDC Ethernet port for network data.  The descriptors look fine but
both ports actually are some sort of multiplexers requiring non-
standard headers added/removed from every packet or else they're
ignored.  The CDC Ethernet port is not technically an ethernet
interface because the ethernet header is stripped away from packets
and only packets sent to/from the gateway IP are allowed.  But
treating it like an ethernet interface lets us to reuse a lot of
driver code and userspace code like DHCP.  All information is
based on a usb traffic log from a Windows machine.

Comments on how to improve the code are welcome.  Note that
usb_skb_return is used in tx_fixup without a bottom half, which
other drivers don't do.

On the Verizon 4G network I've seen speeds up to 1.1MB/s so far with
this driver, a speed-o-meter site reports 16.2Mbps/10.5Mbps.
Userspace scripts are required to talk to the CDC ACM port.

Signed-off-by: Andrzej Zaborowski <balrogg@gmail.com>
---
 drivers/net/usb/Kconfig     |   15 ++
 drivers/net/usb/Makefile    |    1 +
 drivers/net/usb/cdc_ether.c |   21 ++-
 drivers/net/usb/lg-vl600.c  |  325 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/usb/usbnet.h  |    4 +-
 5 files changed, 356 insertions(+), 7 deletions(-)
 create mode 100644 drivers/net/usb/lg-vl600.c

diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 6f600cc..b849017 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -433,4 +433,19 @@ config USB_SIERRA_NET
 	  To compile this driver as a module, choose M here: the
 	  module will be called sierra_net.
 
+config USB_VL600
+	tristate "LG VL600 modem dongle"
+	depends on USB_NET_CDCETHER
+	select USB_ACM
+	help
+	  Select this if you want to use an LG Electronics 4G/LTE usb modem
+	  called VL600.  This driver only handles the ethernet
+	  interface exposed by the modem firmware.  To establish a connection
+	  you will first need a userspace program that sends the right
+	  command to the modem through its CDC ACM port, and most
+	  likely also a DHCP client.  See this thread about using the
+	  4G modem from Verizon:
+
+	  http://ubuntuforums.org/showpost.php?p=10589647&postcount=17
+
 endmenu
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile
index cac1703..c7ec8a5 100644
--- a/drivers/net/usb/Makefile
+++ b/drivers/net/usb/Makefile
@@ -27,4 +27,5 @@ obj-$(CONFIG_USB_IPHETH)	+= ipheth.o
 obj-$(CONFIG_USB_SIERRA_NET)	+= sierra_net.o
 obj-$(CONFIG_USB_NET_CX82310_ETH)	+= cx82310_eth.o
 obj-$(CONFIG_USB_NET_CDC_NCM)	+= cdc_ncm.o
+obj-$(CONFIG_USB_VL600)		+= lg-vl600.o
 
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 9a60e41..8bcb3d9 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -378,7 +378,7 @@ static void dumpspeed(struct usbnet *dev, __le32 *speeds)
 		   __le32_to_cpu(speeds[1]) / 1000);
 }
 
-static void cdc_status(struct usbnet *dev, struct urb *urb)
+void usbnet_cdc_status(struct usbnet *dev, struct urb *urb)
 {
 	struct usb_cdc_notification	*event;
 
@@ -418,8 +418,9 @@ static void cdc_status(struct usbnet *dev, struct urb *urb)
 		break;
 	}
 }
+EXPORT_SYMBOL_GPL(usbnet_cdc_status);
 
-static int cdc_bind(struct usbnet *dev, struct usb_interface *intf)
+int usbnet_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
 {
 	int				status;
 	struct cdc_state		*info = (void *) &dev->data;
@@ -441,6 +442,7 @@ static int cdc_bind(struct usbnet *dev, struct usb_interface *intf)
 	 */
 	return 0;
 }
+EXPORT_SYMBOL_GPL(usbnet_cdc_bind);
 
 static int cdc_manage_power(struct usbnet *dev, int on)
 {
@@ -452,18 +454,18 @@ static const struct driver_info	cdc_info = {
 	.description =	"CDC Ethernet Device",
 	.flags =	FLAG_ETHER,
 	// .check_connect = cdc_check_connect,
-	.bind =		cdc_bind,
+	.bind =		usbnet_cdc_bind,
 	.unbind =	usbnet_cdc_unbind,
-	.status =	cdc_status,
+	.status =	usbnet_cdc_status,
 	.manage_power =	cdc_manage_power,
 };
 
 static const struct driver_info mbm_info = {
 	.description =	"Mobile Broadband Network Device",
 	.flags =	FLAG_WWAN,
-	.bind = 	cdc_bind,
+	.bind =		usbnet_cdc_bind,
 	.unbind =	usbnet_cdc_unbind,
-	.status =	cdc_status,
+	.status =	usbnet_cdc_status,
 	.manage_power =	cdc_manage_power,
 };
 
@@ -560,6 +562,13 @@ static const struct usb_device_id	products [] = {
 	.driver_info		= 0,
 },
 
+/* LG Electronics VL600 wants additional headers on every frame */
+{
+	USB_DEVICE_AND_INTERFACE_INFO(0x1004, 0x61aa, USB_CLASS_COMM,
+			USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
+	.driver_info		= 0,
+},
+
 /*
  * WHITELIST!!!
  *
diff --git a/drivers/net/usb/lg-vl600.c b/drivers/net/usb/lg-vl600.c
new file mode 100644
index 0000000..4f54661
--- /dev/null
+++ b/drivers/net/usb/lg-vl600.c
@@ -0,0 +1,325 @@
+/*
+ * Ethernet interface part of the LG VL600 LTE modem (4G dongle)
+ *
+ * Copyright (C) 2011 Intel Corporation
+ * Author: Andrzej Zaborowski <balrogg@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/usb/cdc.h>
+#include <linux/usb/usbnet.h>
+#include <linux/if_ether.h>
+#include <linux/if_arp.h>
+#include <linux/inetdevice.h>
+
+/*
+ * The device has a CDC ACM port for modem control (it claims to be
+ * CDC ACM anyway) and a CDC Ethernet port for actual network data.
+ * It will however ignore data on both ports that is not encapsulated
+ * in a specific way, any data returned is also encapsulated the same
+ * way.  The headers don't seem to follow any popular standard.
+ *
+ * This driver adds and strips these headers from the ethernet frames
+ * sent/received from the CDC Ethernet port.  The proprietary header
+ * replaces the standard ethernet header in a packet so only actual
+ * ethernet frames are allowed.  The headers allow some form of
+ * multiplexing by using non standard values of the .h_proto field.
+ * Windows/Mac drivers do send a couple of such frames to the device
+ * during initialisation, with protocol set to 0x0906 or 0x0b06 and (what
+ * seems to be) a flag in the .dummy_flags.  This doesn't seem necessary
+ * for modem operation but can possibly be used for GPS or other funcitons.
+ */
+
+struct vl600_frame_hdr {
+	__le32 len;
+	__le32 serial;
+	__le32 pkt_cnt;
+	__le32 dummy_flags;
+	__le32 dummy;
+	__le32 magic;
+} __attribute__((packed));
+
+struct vl600_pkt_hdr {
+	__le32 dummy[2];
+	__le32 len;
+	__be16 h_proto;
+} __attribute__((packed));
+
+/* Note: Turbo-hack! The modem firmware (or someone on the Verizon
+ * network side) works as a DHCP server and gateway between us and
+ * the intarwebs.  It has a dynamically assigned IP address on the
+ * same subnet as our IP and all communications goes through it.
+ * Effectively the subnet can contain only exactly two hosts (local
+ * and remote) and thus hardware addresses have no meaning any more
+ * making the ARP layer useless.  The source and the destination of
+ * each packet on the IN and on the OUT endpoints are known and are
+ * not included in the usb frames unlike on real ethernet.
+ * Apparently someone has noticed that ARP is not needed and the
+ * remote host doesn't bother answering ARP requests.  So we look
+ * for ARP requests in vl600_tx_fixup and we fake a response from
+ * the remote side containing a fake hardware address.
+ */
+static int vl600_handle_arp(struct usbnet *dev, struct sk_buff *skb)
+{
+	struct sk_buff *resp;
+	struct ethhdr *eth_req, *eth_resp;
+	struct arphdr *arp_req, *arp_resp;
+	int arp_len = arp_hdr_len(dev->net);
+	struct in_device *in_dev = dev->net->ip_ptr;
+
+	if (skb->len < sizeof(*eth_resp) + arp_len)
+		return 0;
+
+	arp_req = (struct arphdr *) (skb->data + sizeof(*eth_req));
+	if (be16_to_cpup(&arp_req->ar_hrd) != ARPHRD_ETHER ||
+			be16_to_cpup(&arp_req->ar_pro) != ETH_P_IP ||
+			arp_req->ar_hln != ETH_ALEN ||
+			arp_req->ar_pln != 4 ||
+			be16_to_cpup(&arp_req->ar_op) != ARPOP_REQUEST)
+		return 0;
+
+	if (!in_dev || !in_dev->ifa_list)
+		return 0;
+
+	/* This is a poor check that this request is not just ourselves asking
+	 * if the address proposed to us by DHCP is taken.. */
+	if (!memcmp(skb->data + sizeof(*eth_req) + sizeof(*arp_req) + ETH_ALEN,
+				"\0\0\0\0", 4))
+		return 0;
+
+	/* Build response packet */
+	resp = dev_alloc_skb(sizeof(*eth_resp) + arp_len);
+
+	eth_req = (struct ethhdr *) skb->data;
+	eth_resp = (struct ethhdr *) skb_put(resp, sizeof(*eth_resp));
+	eth_resp->h_proto = eth_req->h_proto;
+	memcpy(&eth_resp->h_dest, eth_req->h_source, ETH_ALEN);
+	memset(&eth_resp->h_source, 0, ETH_ALEN);
+
+	arp_req = (struct arphdr *) (skb->data + sizeof(*eth_req));
+	arp_resp = (struct arphdr *) skb_put(resp, sizeof(*arp_resp));
+	arp_resp->ar_hrd = arp_req->ar_hrd;
+	arp_resp->ar_pro = arp_req->ar_pro;
+	arp_resp->ar_hln = arp_req->ar_hln;
+	arp_resp->ar_pln = arp_req->ar_pln;
+	arp_resp->ar_op = cpu_to_be16(ARPOP_REPLY);
+
+	memcpy(skb_put(resp, ETH_ALEN + 4),
+			skb->data + sizeof(*eth_req) + sizeof(*arp_req) +
+			ETH_ALEN + 4, ETH_ALEN + 4);
+	memcpy(skb_put(resp, ETH_ALEN + 4),
+			skb->data + sizeof(*eth_req) + sizeof(*arp_req),
+			ETH_ALEN + 4);
+
+	usbnet_skb_return(dev, resp);
+
+	return 1;
+}
+
+static int vl600_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+	struct vl600_frame_hdr *frame;
+	struct vl600_pkt_hdr *packet;
+	struct ethhdr *ethhdr;
+	int packet_len, count;
+	struct sk_buff *clone;
+
+	frame = (struct vl600_frame_hdr *) skb->data;
+	/* Frame lengths are generally 4B multiplies but every couple of
+	 * hours there's an odd number of bytes sized yet correct frame,
+	 * so don't check for this.  */
+	if (skb->len < sizeof(*frame) ||
+			skb->len != le32_to_cpup(&frame->len)) {
+		netif_err(dev, ifup, dev->net, "Invalid frame length");
+		dev->net->stats.rx_length_errors++;
+		return 0;
+	}
+
+	/* Should check that frame->magic == 0x53544448 or so? */
+
+	count = le32_to_cpup(&frame->pkt_cnt);
+
+	skb_pull(skb, sizeof(*frame));
+
+	while (count--) {
+		if (skb->len < sizeof(*packet)) {
+			netif_err(dev, ifup, dev->net, "Frame too short");
+			dev->net->stats.rx_errors++;
+			return 0;
+		}
+
+		packet = (struct vl600_pkt_hdr *) skb->data;
+		packet_len = sizeof(*packet) + le32_to_cpup(&packet->len);
+		if (packet_len > skb->len) {
+			netif_err(dev, ifup, dev->net,
+					"Bad packet length stored in header");
+			dev->net->stats.rx_errors++;
+			return 0;
+		}
+
+		/* Packet header is same size as ethernet packet header
+		 * (sizeof(*packet) == sizeof(*ethhdr)), additionally
+		 * the h_proto field is in the same place so we just leave it
+		 * alone and fill in the remaining fields.
+		 */
+		ethhdr = (struct ethhdr *) skb->data;
+		if (be16_to_cpup(&ethhdr->h_proto) == ETH_P_ARP &&
+				skb->len > 0x26) {
+			/* Copy the addresses from packet contents */
+			memcpy(ethhdr->h_source,
+					&skb->data[sizeof(*ethhdr) + 0x8],
+					ETH_ALEN);
+			memcpy(ethhdr->h_dest,
+					&skb->data[sizeof(*ethhdr) + 0x12],
+					ETH_ALEN);
+		} else {
+			memset(ethhdr->h_source, 0, ETH_ALEN);
+			memcpy(ethhdr->h_dest, &dev->net->dev_addr, ETH_ALEN);
+		}
+
+		if (count) {
+			/* Not the last packet in this batch */
+			clone = skb_clone(skb, GFP_ATOMIC);
+			skb_trim(clone, packet_len);
+			usbnet_skb_return(dev, clone);
+
+			skb_pull(skb, (packet_len + 3) & ~3);
+		} else {
+			skb_trim(skb, packet_len);
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+static struct sk_buff *vl600_tx_fixup(struct usbnet *dev,
+		struct sk_buff *skb, gfp_t flags)
+{
+	struct sk_buff *ret;
+	struct vl600_frame_hdr *frame;
+	struct vl600_pkt_hdr *packet;
+	static uint32_t serial = 1;
+	int orig_len = skb->len - sizeof(struct ethhdr);
+	int full_len = (skb->len + sizeof(struct vl600_frame_hdr) + 3) & ~3;
+
+	frame = (struct vl600_frame_hdr *) skb->data;
+	if (skb->len > sizeof(*frame) && skb->len == le32_to_cpup(&frame->len))
+		return skb; /* Already encapsulated? */
+
+	if (skb->len < sizeof(struct ethhdr))
+		/* Drop, device can only deal with ethernet packets */
+		return NULL;
+
+	packet = (struct vl600_pkt_hdr *) skb->data;
+	if (be16_to_cpup(&packet->h_proto) == ETH_P_ARP)
+		if (vl600_handle_arp(dev, skb))
+			/* Drop if response faked */
+			return NULL;
+
+	if (!skb_cloned(skb)) {
+		int headroom = skb_headroom(skb);
+		int tailroom = skb_tailroom(skb);
+
+		if (tailroom >= full_len - skb->len - sizeof(*frame) &&
+				headroom >= sizeof(*frame))
+			/* There's enough head and tail room */
+			goto encapsulate;
+
+		if (headroom + tailroom + skb->len >= full_len) {
+			/* There's enough total room, just readjust */
+			skb->data = memmove(skb->head + sizeof(*frame),
+					skb->data, skb->len);
+			skb_set_tail_pointer(skb, skb->len);
+			goto encapsulate;
+		}
+	}
+
+	/* Alloc a new skb with the required size */
+	ret = skb_copy_expand(skb, sizeof(struct vl600_frame_hdr), full_len -
+			skb->len - sizeof(struct vl600_frame_hdr), flags);
+	dev_kfree_skb_any(skb);
+	if (!ret)
+		return ret;
+	skb = ret;
+
+encapsulate:
+	/* Packet header is same size as ethernet packet header
+	 * (sizeof(*packet) == sizeof(struct ethhdr)), additionally the
+	 * h_proto field is in the same place so we just leave it alone and
+	 * overwrite the remaining fields.
+	 */
+	packet = (struct vl600_pkt_hdr *) skb->data;
+	memset(&packet->dummy, 0, sizeof(packet->dummy));
+	packet->len = cpu_to_le32(orig_len);
+
+	frame = (struct vl600_frame_hdr *) skb_push(skb, sizeof(*frame));
+	memset(frame, 0, sizeof(*frame));
+	frame->len = cpu_to_le32(full_len);
+	frame->serial = cpu_to_le32(serial++);
+	frame->pkt_cnt = cpu_to_le32(1);
+
+	if (skb->len < full_len) /* Pad */
+		skb_put(skb, full_len - skb->len);
+
+	return skb;
+}
+
+static const struct driver_info	vl600_info = {
+	.description	= "LG VL600 modem",
+	.flags		= FLAG_ETHER,
+	.bind		= usbnet_cdc_bind,
+	.unbind		= usbnet_cdc_unbind,
+	.status		= usbnet_cdc_status,
+	.rx_fixup	= vl600_rx_fixup,
+	.tx_fixup	= vl600_tx_fixup,
+};
+
+static const struct usb_device_id products[] = {
+	{
+		USB_DEVICE_AND_INTERFACE_INFO(0x1004, 0x61aa, USB_CLASS_COMM,
+				USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
+		.driver_info	= (unsigned long) &vl600_info,
+	},
+	{},	/* End */
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver lg_vl600_driver = {
+	.name		= "lg-vl600",
+	.id_table	= products,
+	.probe		= usbnet_probe,
+	.disconnect	= usbnet_disconnect,
+	.suspend	= usbnet_suspend,
+	.resume		= usbnet_resume,
+};
+
+static int __init vl600_init(void)
+{
+	return usb_register(&lg_vl600_driver);
+}
+module_init(vl600_init);
+
+static void __exit vl600_exit(void)
+{
+	usb_deregister(&lg_vl600_driver);
+}
+module_exit(vl600_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index 44842c8..3bef970 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -172,7 +172,9 @@ struct cdc_state {
 };
 
 extern int usbnet_generic_cdc_bind(struct usbnet *, struct usb_interface *);
-extern void usbnet_cdc_unbind(struct usbnet *, struct usb_interface *);
+extern int usbnet_cdc_bind(struct usbnet *, struct usb_interface *);
+extern void usbnet_cdc_unbind(struct usbnet *, struct usb_interface *);
+extern void usbnet_cdc_status(struct usbnet *, struct urb *);
 
 /* CDC and RNDIS support the same host-chosen packet filters for IN transfers */
 #define	DEFAULT_FILTER	(USB_CDC_PACKET_TYPE_BROADCAST \
-- 
1.7.1.86.g0e460.dirty

^ permalink raw reply related

* Re: disabling ipv6 (when ipv6 module is already loaded or built in)
From: David Miller @ 2011-03-27 21:24 UTC (permalink / raw)
  To: a.miskiewicz; +Cc: brian.haley, netdev
In-Reply-To: <201103272319.16022.a.miskiewicz@gmail.com>

From: Arkadiusz Miskiewicz <a.miskiewicz@gmail.com>
Date: Sun, 27 Mar 2011 23:19:15 +0200

> Hm, maybe then it could be done in a way where ipv6 is initially built in but 
> disabled and could be permanently enabled via sysfs/proc/something based on a 
> userspace (or user/admin) decision runtime? That would be analogous to 
> "modprobe ipv6" in kernel with modular ipv6.

Sorry, no.

We believe the current facilities handle all reasonable uses of the
feature.

^ permalink raw reply

* Re: disabling ipv6 (when ipv6 module is already loaded or built in)
From: Arkadiusz Miskiewicz @ 2011-03-27 21:19 UTC (permalink / raw)
  To: David Miller; +Cc: brian.haley, netdev
In-Reply-To: <20110325.155657.193733904.davem@davemloft.net>

On Friday 25 of March 2011, David Miller wrote:
> From: Arkadiusz Miskiewicz <a.miskiewicz@gmail.com>
> Date: Fri, 25 Mar 2011 23:53:06 +0100
> 
> > The whole problem is that socket(AF_INET6,...) is allowed. If setting
> > net.ipv6.conf.all.disable_ipv6=1 would also prevent such socket() from
> > succeeding then everything would be fine.
> 
> You have to make this setting before the module loads, once we register
> the protocol handlers (which is what allows socket() to succeed) the
> cat is out of the bag.
> 
> If even just one socket exists, we can't perform the steps necessary
> to block new ones.
> 
> That's why you have to use the module option, and it is the only way
> to block this class of operations.

Hm, maybe then it could be done in a way where ipv6 is initially built in but 
disabled and could be permanently enabled via sysfs/proc/something based on a 
userspace (or user/admin) decision runtime? That would be analogous to 
"modprobe ipv6" in kernel with modular ipv6.

-- 
Arkadiusz Miśkiewicz        PLD/Linux Team
arekm / maven.pl            http://ftp.pld-linux.org/

^ permalink raw reply


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