* Re: 2.6.24-rc8-mm1 : net tcp_input.c warnings
From: Dave Young @ 2008-01-25 1:30 UTC (permalink / raw)
To: Ilpo Järvinen
Cc: Kamalesh Babulal, Krishna Kumar2, Denys Fedoryshchenko,
David Miller, LKML, Netdev, Andrew Morton
In-Reply-To: <Pine.LNX.4.64.0801241108400.31652@kivilampi-30.cs.helsinki.fi>
On Jan 24, 2008 5:54 PM, Ilpo Järvinen <ilpo.jarvinen@helsinki.fi> wrote:
> On Thu, 24 Jan 2008, Dave Young wrote:
>
> Hi Dave (& others),
>
> > Thanks.
>
> Thanks a lot, I was first to ignore all these because they occurred
> with newreno, but looked again... :-/
>
> > New warning trigged with your debug patch:
>
> This was probably with the earlier one I sent to you because there's still
> this case remaining which itself is valid:
>
> > P: 5 L: 0 vs 0 S: 0 vs 1 w: 2044790889-2044796616 (0)
>
> ...snip... this is still ok state (S+L <= P):
>
>
> > P: 5 L: 0 vs 0 S: 0 vs 3 w: 2044790889-2044796616 (0)
> > TCP wq(s) <
> > TCP wq(h) +++h+<
> > l0 s3 f0 p5 seq: su2044790889 hs2044795029 sn2044796616
> > ------------[ cut here ]------------
> > WARNING: at net/ipv4/tcp_input.c:2169 tcp_mark_head_lost+0x122/0x150()
> > Modules linked in: snd_seq_dummy snd_seq_oss snd_seq_midi_event
> > snd_seq snd_seq_device snd_pcm_oss snd_mixer_oss eeprom e100 psmouse
> > snd_hda_intel snd_pcm snd_timer btusb bluetooth serio_raw snd 3c59x sg
> > evdev thermal soundcore rtc_cmos snd_page_alloc rtc_core rtc_lib
> > i2c_i801 processor button intel_agp dcdbas pcspkr agpgart
> > Pid: 0, comm: swapper Not tainted 2.6.24-rc8-mm1 #8
> > [<c0132100>] ? have_callable_console+0x20/0x30
> > [<c0131844>] warn_on_slowpath+0x54/0x80
> > [<c03ffe54>] ? tcp_print_queue+0x1a4/0x230
> > [<c0132438>] ? vprintk+0x308/0x320
> > [<c0132438>] ? vprintk+0x308/0x320
> > [<c0132438>] ? vprintk+0x308/0x320
> > [<c03ffff6>] ? tcp_verify_wq+0x116/0x1c0
> > [<c03f6052>] tcp_mark_head_lost+0x122/0x150
> > [<c03f60ca>] tcp_update_scoreboard+0x4a/0x190
> > [<c03f6e7a>] tcp_fastretrans_alert+0x4da/0x700
> > [<c03f7e63>] tcp_ack+0x1b3/0x3a0
> > [<c03fa21b>] tcp_rcv_established+0x3eb/0x710
> > [<c0401c05>] tcp_v4_do_rcv+0xe5/0x100
> > [<c04021fb>] tcp_v4_rcv+0x5db/0x660
> > [<c0401fa7>] ? tcp_v4_rcv+0x387/0x660
> > [<c03e5eed>] ? ip_local_deliver_finish+0x2d/0x1d0
> > [<c03e5f44>] ip_local_deliver_finish+0x84/0x1d0
> > [<c03e5eed>] ? ip_local_deliver_finish+0x2d/0x1d0
> > [<c0156b97>] ? __lock_release+0x47/0x70
> > [<c03e6147>] ip_local_deliver+0xb7/0xc0
> > [<c03e6202>] ip_rcv_finish+0xb2/0x3c0
> > [<c03c01d8>] ? sock_def_readable+0x48/0xa0
> > [<c03be061>] ? sock_queue_rcv_skb+0xb1/0x1a0
> > [<c03be0a7>] ? sock_queue_rcv_skb+0xf7/0x1a0
> > [<c03e669f>] ip_rcv+0x18f/0x290
> > [<c042fb10>] ? packet_rcv_spkt+0xd0/0x130
> > [<c03c8da6>] netif_receive_skb+0x2b6/0x330
> > [<c03c8c17>] ? netif_receive_skb+0x127/0x330
> > [<c03c8ea3>] ? process_backlog+0x83/0x100
> > [<c03c8eae>] process_backlog+0x8e/0x100
> > [<c03c90bc>] net_rx_action+0x13c/0x230
> > [<c03c8fd9>] ? net_rx_action+0x59/0x230
> > [<c0136f63>] __do_softirq+0x93/0x120
> > [<c013706a>] do_softirq+0x7a/0x80
> > [<c0137135>] irq_exit+0x65/0x90
> > [<c01078b1>] do_IRQ+0x41/0x80
> > [<c0155659>] ? trace_hardirqs_on+0xb9/0x130
> > [<c01059ca>] common_interrupt+0x2e/0x34
> > [<c0103390>] ? mwait_idle_with_hints+0x40/0x50
> > [<c01033a0>] ? mwait_idle+0x0/0x20
> > [<c01033b2>] mwait_idle+0x12/0x20
> > [<c0103141>] cpu_idle+0x61/0x110
> > [<c04339fd>] rest_init+0x5d/0x60
> > [<c05a47fa>] start_kernel+0x1fa/0x260
> > [<c05a4190>] ? unknown_bootoption+0x0/0x130
> > =======================
> > ---[ end trace 14b601818e6903ac ]---
> > ------------[ cut here ]------------
> > WARNING: at net/ipv4/tcp_ipv4.c:197 tcp_verify_wq+0x1b6/0x1c0()
> > Modules linked in: snd_seq_dummy snd_seq_oss snd_seq_midi_event
> > snd_seq snd_seq_device snd_pcm_oss snd_mixer_oss eeprom e100 psmouse
> > snd_hda_intel snd_pcm snd_timer btusb bluetooth serio_raw snd 3c59x sg
> > evdev thermal soundcore rtc_cmos snd_page_alloc rtc_core rtc_lib
> > i2c_i801 processor button intel_agp dcdbas pcspkr agpgart
> > Pid: 0, comm: swapper Not tainted 2.6.24-rc8-mm1 #8
> > [<c0132100>] ? have_callable_console+0x20/0x30
> > [<c0131844>] warn_on_slowpath+0x54/0x80
> > [<c01317da>] ? print_oops_end_marker+0x2a/0x30
> > [<c0131849>] ? warn_on_slowpath+0x59/0x80
> > [<c03ffe54>] ? tcp_print_queue+0x1a4/0x230
> > [<c0132438>] ? vprintk+0x308/0x320
> > [<c0132438>] ? vprintk+0x308/0x320
> > [<c0400096>] tcp_verify_wq+0x1b6/0x1c0
> > [<c03ffff6>] ? tcp_verify_wq+0x116/0x1c0
> > [<c03f5ffc>] tcp_mark_head_lost+0xcc/0x150
> > [<c03f60ca>] tcp_update_scoreboard+0x4a/0x190
> > [<c03f6e7a>] tcp_fastretrans_alert+0x4da/0x700
> > [<c03f7e63>] tcp_ack+0x1b3/0x3a0
> > [<c03fa21b>] tcp_rcv_established+0x3eb/0x710
> > [<c0401c05>] tcp_v4_do_rcv+0xe5/0x100
> > [<c04021fb>] tcp_v4_rcv+0x5db/0x660
> > [<c0401fa7>] ? tcp_v4_rcv+0x387/0x660
> > [<c03e5eed>] ? ip_local_deliver_finish+0x2d/0x1d0
> > [<c03e5f44>] ip_local_deliver_finish+0x84/0x1d0
> > [<c03e5eed>] ? ip_local_deliver_finish+0x2d/0x1d0
> > [<c0156b97>] ? __lock_release+0x47/0x70
> > [<c03e6147>] ip_local_deliver+0xb7/0xc0
> > [<c03e6202>] ip_rcv_finish+0xb2/0x3c0
> > [<c03c01d8>] ? sock_def_readable+0x48/0xa0
> > [<c03be061>] ? sock_queue_rcv_skb+0xb1/0x1a0
> > [<c03be0a7>] ? sock_queue_rcv_skb+0xf7/0x1a0
> > [<c03e669f>] ip_rcv+0x18f/0x290
> > [<c042fb10>] ? packet_rcv_spkt+0xd0/0x130
> > [<c03c8da6>] netif_receive_skb+0x2b6/0x330
> > [<c03c8c17>] ? netif_receive_skb+0x127/0x330
> > [<c03c8ea3>] ? process_backlog+0x83/0x100
> > [<c03c8eae>] process_backlog+0x8e/0x100
> > [<c03c90bc>] net_rx_action+0x13c/0x230
> > [<c03c8fd9>] ? net_rx_action+0x59/0x230
> > [<c0136f63>] __do_softirq+0x93/0x120
> > [<c013706a>] do_softirq+0x7a/0x80
> > [<c0137135>] irq_exit+0x65/0x90
> > [<c01078b1>] do_IRQ+0x41/0x80
> > [<c0155659>] ? trace_hardirqs_on+0xb9/0x130
> > [<c01059ca>] common_interrupt+0x2e/0x34
> > [<c0103390>] ? mwait_idle_with_hints+0x40/0x50
> > [<c01033a0>] ? mwait_idle+0x0/0x20
> > [<c01033b2>] mwait_idle+0x12/0x20
> > [<c0103141>] cpu_idle+0x61/0x110
> > [<c04339fd>] rest_init+0x5d/0x60
> > [<c05a47fa>] start_kernel+0x1fa/0x260
> > [<c05a4190>] ? unknown_bootoption+0x0/0x130
> > =======================
> > ---[ end trace 14b601818e6903ac ]---
>
> ...But this no longer is, and even more, L: 5 is not valid state at this
> point all (should only happen if we went to RTO but it would reset S to
> zero with newreno):
>
> > P: 5 L: 5 vs 5 S: 0 vs 3 w: 2044790889-2044796616 (0)
> > TCP wq(s) LLLLl<
> > TCP wq(h) +++h+<
> > l5 s3 f0 p5 seq: su2044790889 hs2044795029 sn2044796616
>
> Surprisingly, it was the first time the WARN_ON for left_out returned
> correct location. This also explains why the patch I sent to Krishna
> didn't print anything (it didn't end up into printing because I forgot
> to add L+S>P check into to the state checking if).
>
> ...so please, could you (others than Denys) try this patch, it should
> solve the issue. And Denys, could you confirm (and if necessary double
> check) that the kernel you saw this similar problem with is the pure
> Linus' mainline, i.e., without any net-2.6.25 or mm bits please, if so,
> that problem persists. And anyway, there were some fackets_out related
> problems reported as well and this doesn't help for that but I think I've
> lost track of who was seeing it due to large number of reports :-), could
> somebody refresh my memory because I currently don't have time to dig it
> up from archives (at least on this week).
Thanks, applied on my test kernel, if there's no warnings I will just mute.
>
>
> --
> i.
>
> --
> [PATCH] [TCP]: NewReno must count every skb while marking losses
>
> NewReno should add cnt per skb (as with FACK) instead of depending
> on SACKED_ACKED bits which won't be set with it at all.
> Effectively, NewReno should always exists after the first
> iteration anyway (or immediately if there's already head in
> lost_out.
>
> This was fixed earlier in net-2.6.25 but got reverted among other
> stuff and I didn't notice that this is still necessary (actually
> wasn't even considering this case while trying to figure out the
> reports because I lived with different kind of code than it in
> reality was).
>
> This should solve the WARN_ONs in TCP code that as a result of
> this triggered multiple times in every place we check for this
> invariant.
>
> Special thanks to Dave Young <hidave.darkstar@gmail.com> and
> Krishna Kumar2 <krkumar2@in.ibm.com> for trying with my debug
> patches.
>
> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
> ---
> net/ipv4/tcp_input.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
> index 295490e..aa409a5 100644
> --- a/net/ipv4/tcp_input.c
> +++ b/net/ipv4/tcp_input.c
> @@ -2156,7 +2156,7 @@ static void tcp_mark_head_lost(struct sock *sk, int packets, int fast_rexmit)
> tp->lost_skb_hint = skb;
> tp->lost_cnt_hint = cnt;
>
> - if (tcp_is_fack(tp) ||
> + if (tcp_is_fack(tp) || tcp_is_reno(tp) ||
> (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED))
> cnt += tcp_skb_pcount(skb);
>
> --
> 1.5.2.2
>
^ permalink raw reply
* Re: [PATCH 00/14] RFC: Driver for Wireless RNDIS USB devices.
From: David Brownell @ 2008-01-25 1:19 UTC (permalink / raw)
To: Jussi Kivilinna; +Cc: linux-wireless, bjd, netdev
In-Reply-To: <20080120001342.25718.83669.stgit@fate.lan>
On Saturday 19 January 2008, Jussi Kivilinna wrote:
> Hello,
>
> This is second try on wireless RNDIS patchset started by Bjorge Dijkstra. Since
> Bjorge has disappeared, I claim maintainership of rndis_wext and this patchset
> until he returns.
>
> This patchset adds support for various 802.11 USB devices based on Broadcom
> 4320 chip. Chip uses RNDIS to communicate with the host, so module depend
> heavily on rndis_host/cdc_ether/usbnet and needs some changes on these
> modules in order to work.
>
> Patches 1-6 are from first patchset:
> 1. Fix sparse warning: returning void valued expression
> 2. [cdc_ether] Hardwire CDC descriptors when missing
> 3. [rndis_host] Use 1KB buffer in rndis_unbind
> 4. [rndis_host] Halt device if rndis_bind fails
> 5. [rndis_host] Fix rndis packet filter flags
> 6. [usbnet] Use wlan device name for RNDIS wireless devices
>
> Of these 1, 3 and 4 are not required for this version of rndis_wext to work.
>
> Actual wireless part is changed from extension on rndis_host to separate
> driver. Different devices are detected by device specific USB vendor/product
> IDs as the way done with Windows drivers instead of detecting RNDIS media type
> like in first patchset.
>
> New patches 7-14:
> 7. [rndis_host] Split up rndis_host.c
> 8. [rndis_host] export functions
> 9. [usbnet] add driver_priv pointer to 'struct usbnet'
So far as I'm concerned patches 1-9 can go in any time.
The other patches I won't ack yet; see below.
> 10. [rndis_host] Add rndis_early_init function pointer to 'struct rndis_data'.
> 11. [rndis_host] Add rndis_link_change function pointer to 'struct rndis_data'.
Those aren't added to "struct rndis_data" ... they're added to
the struct at the core of the usbnet framework. So they should
not be RNDIS-specific ... even though the only current user will
be the RNDIS host code. Rename those methods and I'll be happy.
> 12. Move usbnet.h and rndis_host.h to include/linux/usb
No problem with that, except that fixing #10 and #11 will
break them.
> 13. [rndis_host] blacklist known wireless RNDIS devices
That will be a headache over time though ... can't you just
let the probe succeed enough to recogize it's wireless (using
the media flag) and then bail, so the next driver can try?
> 14. Add new driver 'rndis_wext' for wireless RNDIS devices.
The real goods! :)
> Patches should be applied in order, series apply cleanly to 2.6.24-rc8.
>
> - Jussi Kivilinna
>
^ permalink raw reply
* Re: [PATCH 08/14] [rndis_host] export functions
From: David Brownell @ 2008-01-25 0:59 UTC (permalink / raw)
To: Jussi Kivilinna; +Cc: linux-wireless, bjd, netdev
In-Reply-To: <20080120001427.25718.45322.stgit@fate.lan>
On Saturday 19 January 2008, Jussi Kivilinna wrote:
> Export rndis_host functions and also rename rndis_bind() to
> generic_rndis_bind() for modules using rndis_host as base.
>
> Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
Acked-by: David Brownell <dbrownell@users.sourceforge.net>
> ---
>
> drivers/net/usb/rndis_host.c | 20 +++++++++++++-------
> drivers/net/usb/rndis_host.h | 9 +++++++++
> 2 files changed, 22 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
> index 29d7e3b..1d6bf0a 100644
> --- a/drivers/net/usb/rndis_host.c
> +++ b/drivers/net/usb/rndis_host.c
> @@ -60,13 +60,14 @@
> * RNDIS notifications from device: command completion; "reverse"
> * keepalives; etc
> */
> -static void rndis_status(struct usbnet *dev, struct urb *urb)
> +void rndis_status(struct usbnet *dev, struct urb *urb)
> {
> devdbg(dev, "rndis status urb, len %d stat %d",
> urb->actual_length, urb->status);
> // FIXME for keepalives, respond immediately (asynchronously)
> // if not an RNDIS status, do like cdc_status(dev,urb) does
> }
> +EXPORT_SYMBOL_GPL(rndis_status);
>
> /*
> * RPC done RNDIS-style. Caller guarantees:
> @@ -78,7 +79,7 @@ static void rndis_status(struct usbnet *dev, struct urb *urb)
> * Call context is likely probe(), before interface name is known,
> * which is why we won't try to use it in the diagnostics.
> */
> -static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf)
> +int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf)
> {
> struct cdc_state *info = (void *) &dev->data;
> int master_ifnum;
> @@ -187,6 +188,7 @@ static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf)
> dev_dbg(&info->control->dev, "rndis response timeout\n");
> return -ETIMEDOUT;
> }
> +EXPORT_SYMBOL_GPL(rndis_command);
>
> /*
> * rndis_query:
> @@ -253,7 +255,7 @@ response_error:
> return -EDOM;
> }
>
> -static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
> +int generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf)
> {
> int retval;
> struct net_device *net = dev->net;
> @@ -377,8 +379,9 @@ fail:
> kfree(u.buf);
> return retval;
> }
> +EXPORT_SYMBOL_GPL(generic_rndis_bind);
>
> -static void rndis_unbind(struct usbnet *dev, struct usb_interface *intf)
> +void rndis_unbind(struct usbnet *dev, struct usb_interface *intf)
> {
> struct rndis_halt *halt;
>
> @@ -393,11 +396,12 @@ static void rndis_unbind(struct usbnet *dev, struct usb_interface *intf)
>
> usbnet_cdc_unbind(dev, intf);
> }
> +EXPORT_SYMBOL_GPL(rndis_unbind);
>
> /*
> * DATA -- host must not write zlps
> */
> -static int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
> +int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
> {
> /* peripheral may have batched packets to us... */
> while (likely(skb->len)) {
> @@ -439,8 +443,9 @@ static int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
> /* caller will usbnet_skb_return the remaining packet */
> return 1;
> }
> +EXPORT_SYMBOL_GPL(rndis_rx_fixup);
>
> -static struct sk_buff *
> +struct sk_buff *
> rndis_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
> {
> struct rndis_data_hdr *hdr;
> @@ -485,12 +490,13 @@ fill:
> /* FIXME make the last packet always be short ... */
> return skb;
> }
> +EXPORT_SYMBOL_GPL(rndis_tx_fixup);
>
>
> static const struct driver_info rndis_info = {
> .description = "RNDIS device",
> .flags = FLAG_ETHER | FLAG_FRAMING_RN | FLAG_NO_SETINT,
> - .bind = rndis_bind,
> + .bind = generic_rndis_bind,
> .unbind = rndis_unbind,
> .status = rndis_status,
> .rx_fixup = rndis_rx_fixup,
> diff --git a/drivers/net/usb/rndis_host.h b/drivers/net/usb/rndis_host.h
> index 1386a17..61f1fd8 100644
> --- a/drivers/net/usb/rndis_host.h
> +++ b/drivers/net/usb/rndis_host.h
> @@ -244,5 +244,14 @@ struct rndis_keepalive_c { /* IN (optionally OUT) */
> RNDIS_PACKET_TYPE_ALL_MULTICAST | \
> RNDIS_PACKET_TYPE_PROMISCUOUS)
>
> +
> +extern void rndis_status(struct usbnet *dev, struct urb *urb);
> +extern int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf);
> +extern int generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf);
> +extern void rndis_unbind(struct usbnet *dev, struct usb_interface *intf);
> +extern int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb);
> +extern struct sk_buff *
> +rndis_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags);
> +
> #endif /* __RNDIS_HOST_H */
>
>
^ permalink raw reply
* Re: [PATCH 07/14] [rndis_host] Split up rndis_host.c
From: David Brownell @ 2008-01-25 0:58 UTC (permalink / raw)
To: Jussi Kivilinna; +Cc: linux-wireless, bjd, netdev
In-Reply-To: <20080120001421.25718.92634.stgit@fate.lan>
On Saturday 19 January 2008, Jussi Kivilinna wrote:
> Split up rndis_host.c into rndis_host.h and rndis_base.c. This is done so
> that rndis_wext can reuse common parts with rndis_host.
>
> Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
Acked-by: David Brownell <dbrownell@users.sourceforge.net>
> ---
>
> drivers/net/usb/rndis_host.c | 223 --------------------------------------
> drivers/net/usb/rndis_host.h | 248 ++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 249 insertions(+), 222 deletions(-)
>
> diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
> index 12daf9c..29d7e3b 100644
> --- a/drivers/net/usb/rndis_host.c
> +++ b/drivers/net/usb/rndis_host.c
> @@ -31,6 +31,7 @@
> #include <linux/usb/cdc.h>
>
> #include "usbnet.h"
> +#include "rndis_host.h"
>
>
> /*
> @@ -56,228 +57,6 @@
> */
>
> /*
> - * CONTROL uses CDC "encapsulated commands" with funky notifications.
> - * - control-out: SEND_ENCAPSULATED
> - * - interrupt-in: RESPONSE_AVAILABLE
> - * - control-in: GET_ENCAPSULATED
> - *
> - * We'll try to ignore the RESPONSE_AVAILABLE notifications.
> - *
> - * REVISIT some RNDIS implementations seem to have curious issues still
> - * to be resolved.
> - */
> -struct rndis_msg_hdr {
> - __le32 msg_type; /* RNDIS_MSG_* */
> - __le32 msg_len;
> - // followed by data that varies between messages
> - __le32 request_id;
> - __le32 status;
> - // ... and more
> -} __attribute__ ((packed));
> -
> -/* MS-Windows uses this strange size, but RNDIS spec says 1024 minimum */
> -#define CONTROL_BUFFER_SIZE 1025
> -
> -/* RNDIS defines an (absurdly huge) 10 second control timeout,
> - * but ActiveSync seems to use a more usual 5 second timeout
> - * (which matches the USB 2.0 spec).
> - */
> -#define RNDIS_CONTROL_TIMEOUT_MS (5 * 1000)
> -
> -
> -#define ccpu2 __constant_cpu_to_le32
> -
> -#define RNDIS_MSG_COMPLETION ccpu2(0x80000000)
> -
> -/* codes for "msg_type" field of rndis messages;
> - * only the data channel uses packet messages (maybe batched);
> - * everything else goes on the control channel.
> - */
> -#define RNDIS_MSG_PACKET ccpu2(0x00000001) /* 1-N packets */
> -#define RNDIS_MSG_INIT ccpu2(0x00000002)
> -#define RNDIS_MSG_INIT_C (RNDIS_MSG_INIT|RNDIS_MSG_COMPLETION)
> -#define RNDIS_MSG_HALT ccpu2(0x00000003)
> -#define RNDIS_MSG_QUERY ccpu2(0x00000004)
> -#define RNDIS_MSG_QUERY_C (RNDIS_MSG_QUERY|RNDIS_MSG_COMPLETION)
> -#define RNDIS_MSG_SET ccpu2(0x00000005)
> -#define RNDIS_MSG_SET_C (RNDIS_MSG_SET|RNDIS_MSG_COMPLETION)
> -#define RNDIS_MSG_RESET ccpu2(0x00000006)
> -#define RNDIS_MSG_RESET_C (RNDIS_MSG_RESET|RNDIS_MSG_COMPLETION)
> -#define RNDIS_MSG_INDICATE ccpu2(0x00000007)
> -#define RNDIS_MSG_KEEPALIVE ccpu2(0x00000008)
> -#define RNDIS_MSG_KEEPALIVE_C (RNDIS_MSG_KEEPALIVE|RNDIS_MSG_COMPLETION)
> -
> -/* codes for "status" field of completion messages */
> -#define RNDIS_STATUS_SUCCESS ccpu2(0x00000000)
> -#define RNDIS_STATUS_FAILURE ccpu2(0xc0000001)
> -#define RNDIS_STATUS_INVALID_DATA ccpu2(0xc0010015)
> -#define RNDIS_STATUS_NOT_SUPPORTED ccpu2(0xc00000bb)
> -#define RNDIS_STATUS_MEDIA_CONNECT ccpu2(0x4001000b)
> -#define RNDIS_STATUS_MEDIA_DISCONNECT ccpu2(0x4001000c)
> -
> -
> -struct rndis_data_hdr {
> - __le32 msg_type; /* RNDIS_MSG_PACKET */
> - __le32 msg_len; // rndis_data_hdr + data_len + pad
> - __le32 data_offset; // 36 -- right after header
> - __le32 data_len; // ... real packet size
> -
> - __le32 oob_data_offset; // zero
> - __le32 oob_data_len; // zero
> - __le32 num_oob; // zero
> - __le32 packet_data_offset; // zero
> -
> - __le32 packet_data_len; // zero
> - __le32 vc_handle; // zero
> - __le32 reserved; // zero
> -} __attribute__ ((packed));
> -
> -struct rndis_init { /* OUT */
> - // header and:
> - __le32 msg_type; /* RNDIS_MSG_INIT */
> - __le32 msg_len; // 24
> - __le32 request_id;
> - __le32 major_version; // of rndis (1.0)
> - __le32 minor_version;
> - __le32 max_transfer_size;
> -} __attribute__ ((packed));
> -
> -struct rndis_init_c { /* IN */
> - // header and:
> - __le32 msg_type; /* RNDIS_MSG_INIT_C */
> - __le32 msg_len;
> - __le32 request_id;
> - __le32 status;
> - __le32 major_version; // of rndis (1.0)
> - __le32 minor_version;
> - __le32 device_flags;
> - __le32 medium; // zero == 802.3
> - __le32 max_packets_per_message;
> - __le32 max_transfer_size;
> - __le32 packet_alignment; // max 7; (1<<n) bytes
> - __le32 af_list_offset; // zero
> - __le32 af_list_size; // zero
> -} __attribute__ ((packed));
> -
> -struct rndis_halt { /* OUT (no reply) */
> - // header and:
> - __le32 msg_type; /* RNDIS_MSG_HALT */
> - __le32 msg_len;
> - __le32 request_id;
> -} __attribute__ ((packed));
> -
> -struct rndis_query { /* OUT */
> - // header and:
> - __le32 msg_type; /* RNDIS_MSG_QUERY */
> - __le32 msg_len;
> - __le32 request_id;
> - __le32 oid;
> - __le32 len;
> - __le32 offset;
> -/*?*/ __le32 handle; // zero
> -} __attribute__ ((packed));
> -
> -struct rndis_query_c { /* IN */
> - // header and:
> - __le32 msg_type; /* RNDIS_MSG_QUERY_C */
> - __le32 msg_len;
> - __le32 request_id;
> - __le32 status;
> - __le32 len;
> - __le32 offset;
> -} __attribute__ ((packed));
> -
> -struct rndis_set { /* OUT */
> - // header and:
> - __le32 msg_type; /* RNDIS_MSG_SET */
> - __le32 msg_len;
> - __le32 request_id;
> - __le32 oid;
> - __le32 len;
> - __le32 offset;
> -/*?*/ __le32 handle; // zero
> -} __attribute__ ((packed));
> -
> -struct rndis_set_c { /* IN */
> - // header and:
> - __le32 msg_type; /* RNDIS_MSG_SET_C */
> - __le32 msg_len;
> - __le32 request_id;
> - __le32 status;
> -} __attribute__ ((packed));
> -
> -struct rndis_reset { /* IN */
> - // header and:
> - __le32 msg_type; /* RNDIS_MSG_RESET */
> - __le32 msg_len;
> - __le32 reserved;
> -} __attribute__ ((packed));
> -
> -struct rndis_reset_c { /* OUT */
> - // header and:
> - __le32 msg_type; /* RNDIS_MSG_RESET_C */
> - __le32 msg_len;
> - __le32 status;
> - __le32 addressing_lost;
> -} __attribute__ ((packed));
> -
> -struct rndis_indicate { /* IN (unrequested) */
> - // header and:
> - __le32 msg_type; /* RNDIS_MSG_INDICATE */
> - __le32 msg_len;
> - __le32 status;
> - __le32 length;
> - __le32 offset;
> -/**/ __le32 diag_status;
> - __le32 error_offset;
> -/**/ __le32 message;
> -} __attribute__ ((packed));
> -
> -struct rndis_keepalive { /* OUT (optionally IN) */
> - // header and:
> - __le32 msg_type; /* RNDIS_MSG_KEEPALIVE */
> - __le32 msg_len;
> - __le32 request_id;
> -} __attribute__ ((packed));
> -
> -struct rndis_keepalive_c { /* IN (optionally OUT) */
> - // header and:
> - __le32 msg_type; /* RNDIS_MSG_KEEPALIVE_C */
> - __le32 msg_len;
> - __le32 request_id;
> - __le32 status;
> -} __attribute__ ((packed));
> -
> -/* NOTE: about 30 OIDs are "mandatory" for peripherals to support ... and
> - * there are gobs more that may optionally be supported. We'll avoid as much
> - * of that mess as possible.
> - */
> -#define OID_802_3_PERMANENT_ADDRESS ccpu2(0x01010101)
> -#define OID_GEN_MAXIMUM_FRAME_SIZE ccpu2(0x00010106)
> -#define OID_GEN_CURRENT_PACKET_FILTER ccpu2(0x0001010e)
> -
> -/* packet filter bits used by OID_GEN_CURRENT_PACKET_FILTER */
> -#define RNDIS_PACKET_TYPE_DIRECTED ccpu2(0x00000001)
> -#define RNDIS_PACKET_TYPE_MULTICAST ccpu2(0x00000002)
> -#define RNDIS_PACKET_TYPE_ALL_MULTICAST ccpu2(0x00000004)
> -#define RNDIS_PACKET_TYPE_BROADCAST ccpu2(0x00000008)
> -#define RNDIS_PACKET_TYPE_SOURCE_ROUTING ccpu2(0x00000010)
> -#define RNDIS_PACKET_TYPE_PROMISCUOUS ccpu2(0x00000020)
> -#define RNDIS_PACKET_TYPE_SMT ccpu2(0x00000040)
> -#define RNDIS_PACKET_TYPE_ALL_LOCAL ccpu2(0x00000080)
> -#define RNDIS_PACKET_TYPE_GROUP ccpu2(0x00001000)
> -#define RNDIS_PACKET_TYPE_ALL_FUNCTIONAL ccpu2(0x00002000)
> -#define RNDIS_PACKET_TYPE_FUNCTIONAL ccpu2(0x00004000)
> -#define RNDIS_PACKET_TYPE_MAC_FRAME ccpu2(0x00008000)
> -
> -/* default filter used with RNDIS devices */
> -#define RNDIS_DEFAULT_FILTER ( \
> - RNDIS_PACKET_TYPE_DIRECTED | \
> - RNDIS_PACKET_TYPE_BROADCAST | \
> - RNDIS_PACKET_TYPE_ALL_MULTICAST | \
> - RNDIS_PACKET_TYPE_PROMISCUOUS)
> -
> -/*
> * RNDIS notifications from device: command completion; "reverse"
> * keepalives; etc
> */
> diff --git a/drivers/net/usb/rndis_host.h b/drivers/net/usb/rndis_host.h
> new file mode 100644
> index 0000000..1386a17
> --- /dev/null
> +++ b/drivers/net/usb/rndis_host.h
> @@ -0,0 +1,248 @@
> +/*
> + * Host Side support for RNDIS Networking Links
> + * Copyright (C) 2005 by David Brownell
> + *
> + * 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
> + */
> +
> +
> +#ifndef __RNDIS_HOST_H
> +#define __RNDIS_HOST_H
> +
> +
> +/*
> + * CONTROL uses CDC "encapsulated commands" with funky notifications.
> + * - control-out: SEND_ENCAPSULATED
> + * - interrupt-in: RESPONSE_AVAILABLE
> + * - control-in: GET_ENCAPSULATED
> + *
> + * We'll try to ignore the RESPONSE_AVAILABLE notifications.
> + *
> + * REVISIT some RNDIS implementations seem to have curious issues still
> + * to be resolved.
> + */
> +struct rndis_msg_hdr {
> + __le32 msg_type; /* RNDIS_MSG_* */
> + __le32 msg_len;
> + // followed by data that varies between messages
> + __le32 request_id;
> + __le32 status;
> + // ... and more
> +} __attribute__ ((packed));
> +
> +/* MS-Windows uses this strange size, but RNDIS spec says 1024 minimum */
> +#define CONTROL_BUFFER_SIZE 1025
> +
> +/* RNDIS defines an (absurdly huge) 10 second control timeout,
> + * but ActiveSync seems to use a more usual 5 second timeout
> + * (which matches the USB 2.0 spec).
> + */
> +#define RNDIS_CONTROL_TIMEOUT_MS (5 * 1000)
> +
> +
> +#define ccpu2 __constant_cpu_to_le32
> +
> +#define RNDIS_MSG_COMPLETION ccpu2(0x80000000)
> +
> +/* codes for "msg_type" field of rndis messages;
> + * only the data channel uses packet messages (maybe batched);
> + * everything else goes on the control channel.
> + */
> +#define RNDIS_MSG_PACKET ccpu2(0x00000001) /* 1-N packets */
> +#define RNDIS_MSG_INIT ccpu2(0x00000002)
> +#define RNDIS_MSG_INIT_C (RNDIS_MSG_INIT|RNDIS_MSG_COMPLETION)
> +#define RNDIS_MSG_HALT ccpu2(0x00000003)
> +#define RNDIS_MSG_QUERY ccpu2(0x00000004)
> +#define RNDIS_MSG_QUERY_C (RNDIS_MSG_QUERY|RNDIS_MSG_COMPLETION)
> +#define RNDIS_MSG_SET ccpu2(0x00000005)
> +#define RNDIS_MSG_SET_C (RNDIS_MSG_SET|RNDIS_MSG_COMPLETION)
> +#define RNDIS_MSG_RESET ccpu2(0x00000006)
> +#define RNDIS_MSG_RESET_C (RNDIS_MSG_RESET|RNDIS_MSG_COMPLETION)
> +#define RNDIS_MSG_INDICATE ccpu2(0x00000007)
> +#define RNDIS_MSG_KEEPALIVE ccpu2(0x00000008)
> +#define RNDIS_MSG_KEEPALIVE_C (RNDIS_MSG_KEEPALIVE|RNDIS_MSG_COMPLETION)
> +
> +/* codes for "status" field of completion messages */
> +#define RNDIS_STATUS_SUCCESS ccpu2(0x00000000)
> +#define RNDIS_STATUS_FAILURE ccpu2(0xc0000001)
> +#define RNDIS_STATUS_INVALID_DATA ccpu2(0xc0010015)
> +#define RNDIS_STATUS_NOT_SUPPORTED ccpu2(0xc00000bb)
> +#define RNDIS_STATUS_MEDIA_CONNECT ccpu2(0x4001000b)
> +#define RNDIS_STATUS_MEDIA_DISCONNECT ccpu2(0x4001000c)
> +
> +
> +struct rndis_data_hdr {
> + __le32 msg_type; /* RNDIS_MSG_PACKET */
> + __le32 msg_len; // rndis_data_hdr + data_len + pad
> + __le32 data_offset; // 36 -- right after header
> + __le32 data_len; // ... real packet size
> +
> + __le32 oob_data_offset; // zero
> + __le32 oob_data_len; // zero
> + __le32 num_oob; // zero
> + __le32 packet_data_offset; // zero
> +
> + __le32 packet_data_len; // zero
> + __le32 vc_handle; // zero
> + __le32 reserved; // zero
> +} __attribute__ ((packed));
> +
> +struct rndis_init { /* OUT */
> + // header and:
> + __le32 msg_type; /* RNDIS_MSG_INIT */
> + __le32 msg_len; // 24
> + __le32 request_id;
> + __le32 major_version; // of rndis (1.0)
> + __le32 minor_version;
> + __le32 max_transfer_size;
> +} __attribute__ ((packed));
> +
> +struct rndis_init_c { /* IN */
> + // header and:
> + __le32 msg_type; /* RNDIS_MSG_INIT_C */
> + __le32 msg_len;
> + __le32 request_id;
> + __le32 status;
> + __le32 major_version; // of rndis (1.0)
> + __le32 minor_version;
> + __le32 device_flags;
> + __le32 medium; // zero == 802.3
> + __le32 max_packets_per_message;
> + __le32 max_transfer_size;
> + __le32 packet_alignment; // max 7; (1<<n) bytes
> + __le32 af_list_offset; // zero
> + __le32 af_list_size; // zero
> +} __attribute__ ((packed));
> +
> +struct rndis_halt { /* OUT (no reply) */
> + // header and:
> + __le32 msg_type; /* RNDIS_MSG_HALT */
> + __le32 msg_len;
> + __le32 request_id;
> +} __attribute__ ((packed));
> +
> +struct rndis_query { /* OUT */
> + // header and:
> + __le32 msg_type; /* RNDIS_MSG_QUERY */
> + __le32 msg_len;
> + __le32 request_id;
> + __le32 oid;
> + __le32 len;
> + __le32 offset;
> +/*?*/ __le32 handle; // zero
> +} __attribute__ ((packed));
> +
> +struct rndis_query_c { /* IN */
> + // header and:
> + __le32 msg_type; /* RNDIS_MSG_QUERY_C */
> + __le32 msg_len;
> + __le32 request_id;
> + __le32 status;
> + __le32 len;
> + __le32 offset;
> +} __attribute__ ((packed));
> +
> +struct rndis_set { /* OUT */
> + // header and:
> + __le32 msg_type; /* RNDIS_MSG_SET */
> + __le32 msg_len;
> + __le32 request_id;
> + __le32 oid;
> + __le32 len;
> + __le32 offset;
> +/*?*/ __le32 handle; // zero
> +} __attribute__ ((packed));
> +
> +struct rndis_set_c { /* IN */
> + // header and:
> + __le32 msg_type; /* RNDIS_MSG_SET_C */
> + __le32 msg_len;
> + __le32 request_id;
> + __le32 status;
> +} __attribute__ ((packed));
> +
> +struct rndis_reset { /* IN */
> + // header and:
> + __le32 msg_type; /* RNDIS_MSG_RESET */
> + __le32 msg_len;
> + __le32 reserved;
> +} __attribute__ ((packed));
> +
> +struct rndis_reset_c { /* OUT */
> + // header and:
> + __le32 msg_type; /* RNDIS_MSG_RESET_C */
> + __le32 msg_len;
> + __le32 status;
> + __le32 addressing_lost;
> +} __attribute__ ((packed));
> +
> +struct rndis_indicate { /* IN (unrequested) */
> + // header and:
> + __le32 msg_type; /* RNDIS_MSG_INDICATE */
> + __le32 msg_len;
> + __le32 status;
> + __le32 length;
> + __le32 offset;
> +/**/ __le32 diag_status;
> + __le32 error_offset;
> +/**/ __le32 message;
> +} __attribute__ ((packed));
> +
> +struct rndis_keepalive { /* OUT (optionally IN) */
> + // header and:
> + __le32 msg_type; /* RNDIS_MSG_KEEPALIVE */
> + __le32 msg_len;
> + __le32 request_id;
> +} __attribute__ ((packed));
> +
> +struct rndis_keepalive_c { /* IN (optionally OUT) */
> + // header and:
> + __le32 msg_type; /* RNDIS_MSG_KEEPALIVE_C */
> + __le32 msg_len;
> + __le32 request_id;
> + __le32 status;
> +} __attribute__ ((packed));
> +
> +/* NOTE: about 30 OIDs are "mandatory" for peripherals to support ... and
> + * there are gobs more that may optionally be supported. We'll avoid as much
> + * of that mess as possible.
> + */
> +#define OID_802_3_PERMANENT_ADDRESS ccpu2(0x01010101)
> +#define OID_GEN_MAXIMUM_FRAME_SIZE ccpu2(0x00010106)
> +#define OID_GEN_CURRENT_PACKET_FILTER ccpu2(0x0001010e)
> +
> +/* packet filter bits used by OID_GEN_CURRENT_PACKET_FILTER */
> +#define RNDIS_PACKET_TYPE_DIRECTED ccpu2(0x00000001)
> +#define RNDIS_PACKET_TYPE_MULTICAST ccpu2(0x00000002)
> +#define RNDIS_PACKET_TYPE_ALL_MULTICAST ccpu2(0x00000004)
> +#define RNDIS_PACKET_TYPE_BROADCAST ccpu2(0x00000008)
> +#define RNDIS_PACKET_TYPE_SOURCE_ROUTING ccpu2(0x00000010)
> +#define RNDIS_PACKET_TYPE_PROMISCUOUS ccpu2(0x00000020)
> +#define RNDIS_PACKET_TYPE_SMT ccpu2(0x00000040)
> +#define RNDIS_PACKET_TYPE_ALL_LOCAL ccpu2(0x00000080)
> +#define RNDIS_PACKET_TYPE_GROUP ccpu2(0x00001000)
> +#define RNDIS_PACKET_TYPE_ALL_FUNCTIONAL ccpu2(0x00002000)
> +#define RNDIS_PACKET_TYPE_FUNCTIONAL ccpu2(0x00004000)
> +#define RNDIS_PACKET_TYPE_MAC_FRAME ccpu2(0x00008000)
> +
> +/* default filter used with RNDIS devices */
> +#define RNDIS_DEFAULT_FILTER ( \
> + RNDIS_PACKET_TYPE_DIRECTED | \
> + RNDIS_PACKET_TYPE_BROADCAST | \
> + RNDIS_PACKET_TYPE_ALL_MULTICAST | \
> + RNDIS_PACKET_TYPE_PROMISCUOUS)
> +
> +#endif /* __RNDIS_HOST_H */
> +
>
^ permalink raw reply
* Re: [PATCH 05/14] [rndis_host] Fix rndis packet filter flags.
From: David Brownell @ 2008-01-25 0:55 UTC (permalink / raw)
To: Jussi Kivilinna; +Cc: linux-wireless, bjd, netdev
In-Reply-To: <20080120001410.25718.70147.stgit@fate.lan>
On Saturday 19 January 2008, Jussi Kivilinna wrote:
> RNDIS packet filter flags are not exactly the same as CDC flags
> so we cannot reuse them.
>
> Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
> Signed-off-by: Bjorge Dijkstra <bjd@jooz.net>
Acked-by: David Brownell <dbrownell@users.sourceforge.net>
> ---
>
> drivers/net/usb/rndis_host.c | 23 ++++++++++++++++++++++-
> 1 files changed, 22 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
> index c686025..12daf9c 100644
> --- a/drivers/net/usb/rndis_host.c
> +++ b/drivers/net/usb/rndis_host.c
> @@ -256,6 +256,27 @@ struct rndis_keepalive_c { /* IN (optionally OUT) */
> #define OID_GEN_MAXIMUM_FRAME_SIZE ccpu2(0x00010106)
> #define OID_GEN_CURRENT_PACKET_FILTER ccpu2(0x0001010e)
>
> +/* packet filter bits used by OID_GEN_CURRENT_PACKET_FILTER */
> +#define RNDIS_PACKET_TYPE_DIRECTED ccpu2(0x00000001)
> +#define RNDIS_PACKET_TYPE_MULTICAST ccpu2(0x00000002)
> +#define RNDIS_PACKET_TYPE_ALL_MULTICAST ccpu2(0x00000004)
> +#define RNDIS_PACKET_TYPE_BROADCAST ccpu2(0x00000008)
> +#define RNDIS_PACKET_TYPE_SOURCE_ROUTING ccpu2(0x00000010)
> +#define RNDIS_PACKET_TYPE_PROMISCUOUS ccpu2(0x00000020)
> +#define RNDIS_PACKET_TYPE_SMT ccpu2(0x00000040)
> +#define RNDIS_PACKET_TYPE_ALL_LOCAL ccpu2(0x00000080)
> +#define RNDIS_PACKET_TYPE_GROUP ccpu2(0x00001000)
> +#define RNDIS_PACKET_TYPE_ALL_FUNCTIONAL ccpu2(0x00002000)
> +#define RNDIS_PACKET_TYPE_FUNCTIONAL ccpu2(0x00004000)
> +#define RNDIS_PACKET_TYPE_MAC_FRAME ccpu2(0x00008000)
> +
> +/* default filter used with RNDIS devices */
> +#define RNDIS_DEFAULT_FILTER ( \
> + RNDIS_PACKET_TYPE_DIRECTED | \
> + RNDIS_PACKET_TYPE_BROADCAST | \
> + RNDIS_PACKET_TYPE_ALL_MULTICAST | \
> + RNDIS_PACKET_TYPE_PROMISCUOUS)
> +
> /*
> * RNDIS notifications from device: command completion; "reverse"
> * keepalives; etc
> @@ -551,7 +572,7 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
> u.set->oid = OID_GEN_CURRENT_PACKET_FILTER;
> u.set->len = ccpu2(4);
> u.set->offset = ccpu2((sizeof *u.set) - 8);
> - *(__le32 *)(u.buf + sizeof *u.set) = ccpu2(DEFAULT_FILTER);
> + *(__le32 *)(u.buf + sizeof *u.set) = RNDIS_DEFAULT_FILTER;
>
> retval = rndis_command(dev, u.header);
> if (unlikely(retval < 0)) {
>
^ permalink raw reply
* Re: [PATCH 03/14] [rndis_host] Use 1KB buffer in rndis_unbind
From: David Brownell @ 2008-01-25 0:55 UTC (permalink / raw)
To: Jussi Kivilinna; +Cc: linux-wireless, bjd, netdev
In-Reply-To: <20080120001359.25718.20460.stgit@fate.lan>
On Saturday 19 January 2008, Jussi Kivilinna wrote:
> rndis_command requires the caller to pass in a buffer of at least 1KB.
>
> Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
> Signed-off-by: Bjorge Dijkstra <bjd@jooz.net>
Acked-by: David Brownell <dbrownell@users.sourceforge.net>
> ---
>
> drivers/net/usb/rndis_host.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
> index 96ef6a9..42b161c 100644
> --- a/drivers/net/usb/rndis_host.c
> +++ b/drivers/net/usb/rndis_host.c
> @@ -577,7 +577,7 @@ static void rndis_unbind(struct usbnet *dev, struct usb_interface *intf)
> struct rndis_halt *halt;
>
> /* try to clear any rndis state/activity (no i/o from stack!) */
> - halt = kzalloc(sizeof *halt, GFP_KERNEL);
> + halt = kzalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL);
> if (halt) {
> halt->msg_type = RNDIS_MSG_HALT;
> halt->msg_len = ccpu2(sizeof *halt);
>
^ permalink raw reply
* Re: [PATCH 02/14] [cdc_ether] Hardwire CDC descriptors when missing
From: David Brownell @ 2008-01-25 0:55 UTC (permalink / raw)
To: Jussi Kivilinna; +Cc: linux-wireless, bjd, netdev
In-Reply-To: <20080120001353.25718.38880.stgit@fate.lan>
On Saturday 19 January 2008, Jussi Kivilinna wrote:
> From: Bjorge Dijkstra <bjd@jooz.net>
>
> Just as ActiveSync devices, some regular RNDIS devices also lack
> the CDC descriptors (e.g. devices based on BCM4320 WLAN chip).
> This patch hardwires the CDC descriptors for all RNDIS style devices
> when they are missing.
>
> Signed-off-by: Bjorge Dijkstra <bjd@jooz.net>
> Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
Acked-by: David Brownell <dbrownell@users.sourceforge.net>
> ---
>
> drivers/net/usb/cdc_ether.c | 10 +++++-----
> 1 files changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
> index a42acc3..97c17bb 100644
> --- a/drivers/net/usb/cdc_ether.c
> +++ b/drivers/net/usb/cdc_ether.c
> @@ -228,15 +228,16 @@ next_desc:
> buf += buf [0];
> }
>
> - /* Microsoft ActiveSync based RNDIS devices lack the CDC descriptors,
> - * so we'll hard-wire the interfaces and not check for descriptors.
> + /* Microsoft ActiveSync based and some regular RNDIS devices lack the
> + * CDC descriptors, so we'll hard-wire the interfaces and not check
> + * for descriptors.
> */
> - if (is_activesync(&intf->cur_altsetting->desc) && !info->u) {
> + if (rndis && !info->u) {
> info->control = usb_ifnum_to_if(dev->udev, 0);
> info->data = usb_ifnum_to_if(dev->udev, 1);
> if (!info->control || !info->data) {
> dev_dbg(&intf->dev,
> - "activesync: master #0/%p slave #1/%p\n",
> + "rndis: master #0/%p slave #1/%p\n",
> info->control,
> info->data);
> goto bad_desc;
> @@ -316,7 +317,6 @@ void usbnet_cdc_unbind(struct usbnet *dev, struct usb_interface *intf)
> }
> EXPORT_SYMBOL_GPL(usbnet_cdc_unbind);
>
> -\f
> /*-------------------------------------------------------------------------
> *
> * Communications Device Class, Ethernet Control model
>
^ permalink raw reply
* Re: [PATCH 13/14] [rndis_host] blacklist known wireless RNDIS devices
From: David Brownell @ 2008-01-25 1:13 UTC (permalink / raw)
To: Jussi Kivilinna
Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA, bjd-a1rhEgazXTw,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20080120001455.25718.75424.stgit-q/85JClnwdg@public.gmane.org>
On Saturday 19 January 2008, Jussi Kivilinna wrote:
> Blacklist known wireless RNDIS devices that will be handled by
> rndis_wext module.
This seems destined to become a headache. Wouldn't it be better
to let the probe progress far enough to detect that it's actually
a WLAN device, and then back out so the next driver can try?
- Dave
> Signed-off-by: Jussi Kivilinna <jussi.kivilinna-E01nCVcF24I@public.gmane.org>
> ---
>
> drivers/net/usb/rndis_host.c | 104 ++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 104 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
> index 1ffbbb3..cd1f953 100644
> --- a/drivers/net/usb/rndis_host.c
> +++ b/drivers/net/usb/rndis_host.c
> @@ -530,6 +530,110 @@ static const struct driver_info rndis_info = {
> /*-------------------------------------------------------------------------*/
>
> static const struct usb_device_id products [] = {
> +/*
> + * BLACKLIST !!
> + *
> + * Blacklist RNDIS devices that are handled in separate RNDIS modules.
> + */
> +
> +#define RNDIS_MASTER_INTERFACE \
> + .bInterfaceClass = USB_CLASS_COMM, \
> + .bInterfaceSubClass = 2 /* ACM */, \
> + .bInterfaceProtocol = 0x0ff
> +
> +/* Wireless RNDIS devices, rndis_wext module */
> +{
> + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
> + | USB_DEVICE_ID_MATCH_DEVICE,
> + .idVendor = 0x0411,
> + .idProduct = 0x00bc, /* Buffalo WLI-U2-KG125S */
> + RNDIS_MASTER_INTERFACE,
> + .driver_info = 0,
> +}, {
> + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
> + | USB_DEVICE_ID_MATCH_DEVICE,
> + .idVendor = 0x0baf,
> + .idProduct = 0x011b, /* U.S. Robotics USR5421 */
> + RNDIS_MASTER_INTERFACE,
> + .driver_info = 0,
> +}, {
> + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
> + | USB_DEVICE_ID_MATCH_DEVICE,
> + .idVendor = 0x050d,
> + .idProduct = 0x011b, /* Belkin F5D7051 */
> + RNDIS_MASTER_INTERFACE,
> + .driver_info = 0,
> +}, {
> + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
> + | USB_DEVICE_ID_MATCH_DEVICE,
> + .idVendor = 0x1799, /* Belkin has two vendor ids */
> + .idProduct = 0x011b, /* Belkin F5D7051 */
> + RNDIS_MASTER_INTERFACE,
> + .driver_info = 0,
> +}, {
> + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
> + | USB_DEVICE_ID_MATCH_DEVICE,
> + .idVendor = 0x13b1,
> + .idProduct = 0x0014, /* Linksys WUSB54GSv2 */
> + RNDIS_MASTER_INTERFACE,
> + .driver_info = 0,
> +}, {
> + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
> + | USB_DEVICE_ID_MATCH_DEVICE,
> + .idVendor = 0x13b1,
> + .idProduct = 0x0026, /* Linksys WUSB54GSC */
> + RNDIS_MASTER_INTERFACE,
> + .driver_info = 0,
> +}, {
> + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
> + | USB_DEVICE_ID_MATCH_DEVICE,
> + .idVendor = 0x0b05,
> + .idProduct = 0x1717, /* Asus WL169gE */
> + RNDIS_MASTER_INTERFACE,
> + .driver_info = 0,
> +}, {
> + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
> + | USB_DEVICE_ID_MATCH_DEVICE,
> + .idVendor = 0x0a5c,
> + .idProduct = 0xd11b, /* Eminent EM4045 */
> + RNDIS_MASTER_INTERFACE,
> + .driver_info = 0,
> +}, {
> + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
> + | USB_DEVICE_ID_MATCH_DEVICE,
> + .idVendor = 0x1690,
> + .idProduct = 0x0715, /* BT Voyager 1055 */
> + RNDIS_MASTER_INTERFACE,
> + .driver_info = 0,
> +}, {
> + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
> + | USB_DEVICE_ID_MATCH_DEVICE,
> + .idVendor = 0x13b1,
> + .idProduct = 0x000e, /* Linksys WUSB54GSv1 */
> + RNDIS_MASTER_INTERFACE,
> + .driver_info = 0,
> +}, {
> + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
> + | USB_DEVICE_ID_MATCH_DEVICE,
> + .idVendor = 0x0baf,
> + .idProduct = 0x0111, /* U.S. Robotics USR5420 */
> + RNDIS_MASTER_INTERFACE,
> + .driver_info = 0,
> +}, {
> + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
> + | USB_DEVICE_ID_MATCH_DEVICE,
> + .idVendor = 0x0411,
> + .idProduct = 0x004b, /* BUFFALO WLI-USB-G54 */
> + RNDIS_MASTER_INTERFACE,
> + .driver_info = 0,
> +},
> +
> +/*
> + * WHITELIST!!!
> + *
> + * All other RNDIS devices that do not need special OID handling in order
> + * to work.
> + */
> {
> /* RNDIS is MSFT's un-official variant of CDC ACM */
> USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
>
^ permalink raw reply
* Re: [PATCH 10/14] [rndis_host] Add rndis_early_init function pointer to 'struct rndis_data'.
From: David Brownell @ 2008-01-25 1:10 UTC (permalink / raw)
To: Jussi Kivilinna
Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA, bjd-a1rhEgazXTw,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20080120001438.25718.96722.stgit-q/85JClnwdg@public.gmane.org>
On Saturday 19 January 2008, Jussi Kivilinna wrote:
> Function pointer is for rndis minidrivers that need to do work on device right
> after RNDIS_INIT. For example setting device specific configuration parameters
> with OID_GEN_RNDIS_CONFIG_PARAMETER.
>
> Signed-off-by: Jussi Kivilinna <jussi.kivilinna-E01nCVcF24I@public.gmane.org>
Could this -- and #11/14 -- instead be generalized a bit,
so they're not RNDIS-specific? At least in name; the
only user for now would be the rndis_host code.
The generalization would presumably be "early_init" and
"link_change", paired with doc comments reflecting that
they're usable by any driver stack built over the usbnet
framework core.
There's no point IMO to having generalizable hooks be
restricted this way.
- Dave
> ---
>
> drivers/net/usb/rndis_host.c | 6 ++++++
> drivers/net/usb/usbnet.h | 3 +++
> 2 files changed, 9 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
> index 1d6bf0a..22e5ca1 100644
> --- a/drivers/net/usb/rndis_host.c
> +++ b/drivers/net/usb/rndis_host.c
> @@ -336,6 +336,12 @@ int generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf)
> dev->hard_mtu, tmp, dev->rx_urb_size,
> 1 << le32_to_cpu(u.init_c->packet_alignment));
>
> + /* module has some device initialization code needs to be done right
> + * after RNDIS_INIT */
> + if (dev->driver_info->rndis_early_init &&
> + dev->driver_info->rndis_early_init(dev) != 0)
> + goto halt_fail_and_release;
> +
> /* Get designated host ethernet address */
> reply_len = ETH_ALEN;
> retval = rndis_query(dev, intf, u.buf, OID_802_3_PERMANENT_ADDRESS,
> diff --git a/drivers/net/usb/usbnet.h b/drivers/net/usb/usbnet.h
> index 0b4bf09..2bc5f76 100644
> --- a/drivers/net/usb/usbnet.h
> +++ b/drivers/net/usb/usbnet.h
> @@ -116,6 +116,9 @@ struct driver_info {
> struct sk_buff *(*tx_fixup)(struct usbnet *dev,
> struct sk_buff *skb, gfp_t flags);
>
> + /* rndis minidriver early initialization code, can sleep */
> + int (*rndis_early_init)(struct usbnet *dev);
> +
> /* for new devices, use the descriptor-reading code instead */
> int in; /* rx endpoint */
> int out; /* tx endpoint */
>
^ permalink raw reply
* Re: [PATCH 09/26] atl1: refactor tx processing
From: Chris Snook @ 2008-01-25 1:08 UTC (permalink / raw)
To: Jay Cliburn; +Cc: Jeff Garzik, linux-kernel, atl1-devel, netdev
In-Reply-To: <20080124190024.1b81238e@osprey.hogchain.net>
Jay Cliburn wrote:
> On Tue, 22 Jan 2008 18:31:09 -0600
> Jay Cliburn <jacliburn@bellsouth.net> wrote:
>
>> On Tue, 22 Jan 2008 04:58:17 -0500
>> Jeff Garzik <jeff@garzik.org> wrote:
>>
> [...]
>>> for such a huge patch, this description is very tiny. [describe]
>>> what is refactored, and why.
>
> Is this one any better?
This satisfies me.
Acked-by: Chris Snook <csnook@redhat.com>
> From df475e2eea401f9dc18ca23dab538b99fb9e710c Mon Sep 17 00:00:00 2001
> From: Jay Cliburn <jacliburn@bellsouth.net>
> Date: Wed, 23 Jan 2008 21:36:36 -0600
> Subject: [PATCH] atl1: simplify tx packet descriptor
>
> The transmit packet descriptor consists of four 32-bit words, with word 3
> upper bits overloaded depending upon the condition of its bits 3 and 4.
> The driver currently duplicates all word 2 and some word 3 register bit
> definitions unnecessarily and also uses a set of nested structures in its
> definition of the TPD without good cause. This patch adds a lengthy
> comment describing the TPD, eliminates duplicate TPD bit definitions,
> and simplifies the TPD structure itself. It also expands the TSO check
> to correctly handle custom checksum versus TSO processing using the revised
> TPD definitions. Finally, shorten some variable names in the transmit
> processing path to reduce line lengths, rename some variables to better
> describe their purpose (e.g., nseg versus m), and add a comment or two
> to better describe what the code is doing.
>
> Signed-off-by: Jay Cliburn <jacliburn@bellsouth.net>
^ permalink raw reply
* Re: [PATCH 09/26] atl1: refactor tx processing
From: Jay Cliburn @ 2008-01-25 1:00 UTC (permalink / raw)
To: Jay Cliburn; +Cc: Jeff Garzik, csnook, linux-kernel, atl1-devel, netdev
In-Reply-To: <20080122183109.5ab80802@osprey.hogchain.net>
On Tue, 22 Jan 2008 18:31:09 -0600
Jay Cliburn <jacliburn@bellsouth.net> wrote:
> On Tue, 22 Jan 2008 04:58:17 -0500
> Jeff Garzik <jeff@garzik.org> wrote:
>
[...]
> > for such a huge patch, this description is very tiny. [describe]
> > what is refactored, and why.
Is this one any better?
>From df475e2eea401f9dc18ca23dab538b99fb9e710c Mon Sep 17 00:00:00 2001
From: Jay Cliburn <jacliburn@bellsouth.net>
Date: Wed, 23 Jan 2008 21:36:36 -0600
Subject: [PATCH] atl1: simplify tx packet descriptor
The transmit packet descriptor consists of four 32-bit words, with word 3
upper bits overloaded depending upon the condition of its bits 3 and 4.
The driver currently duplicates all word 2 and some word 3 register bit
definitions unnecessarily and also uses a set of nested structures in its
definition of the TPD without good cause. This patch adds a lengthy
comment describing the TPD, eliminates duplicate TPD bit definitions,
and simplifies the TPD structure itself. It also expands the TSO check
to correctly handle custom checksum versus TSO processing using the revised
TPD definitions. Finally, shorten some variable names in the transmit
processing path to reduce line lengths, rename some variables to better
describe their purpose (e.g., nseg versus m), and add a comment or two
to better describe what the code is doing.
Signed-off-by: Jay Cliburn <jacliburn@bellsouth.net>
---
drivers/net/atlx/atl1.c | 265 +++++++++++++++++++++++++----------------------
drivers/net/atlx/atl1.h | 201 +++++++++++++++++++-----------------
2 files changed, 246 insertions(+), 220 deletions(-)
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index 1f564f0..f4add3c 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -1259,8 +1259,6 @@ static void atl1_intr_tx(struct atl1_adapter *adapter)
dev_kfree_skb_irq(buffer_info->skb);
buffer_info->skb = NULL;
}
- tpd->buffer_addr = 0;
- tpd->desc.data = 0;
if (++sw_tpd_next_to_clean == tpd_ring->count)
sw_tpd_next_to_clean = 0;
@@ -1282,48 +1280,69 @@ static u16 atl1_tpd_avail(struct atl1_tpd_ring *tpd_ring)
}
static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb,
- struct tso_param *tso)
+ struct tx_packet_desc *ptpd)
{
- /* We enter this function holding a spinlock. */
- u8 ipofst;
+ /* spinlock held */
+ u8 hdr_len, ip_off;
+ u32 real_len;
int err;
if (skb_shinfo(skb)->gso_size) {
if (skb_header_cloned(skb)) {
err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
if (unlikely(err))
- return err;
+ return -1;
}
if (skb->protocol == ntohs(ETH_P_IP)) {
struct iphdr *iph = ip_hdr(skb);
- iph->tot_len = 0;
+ real_len = (((unsigned char *)iph - skb->data) +
+ ntohs(iph->tot_len));
+ if (real_len < skb->len)
+ pskb_trim(skb, real_len);
+ hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
+ if (skb->len == hdr_len) {
+ iph->check = 0;
+ tcp_hdr(skb)->check =
+ ~csum_tcpudp_magic(iph->saddr,
+ iph->daddr, tcp_hdrlen(skb),
+ IPPROTO_TCP, 0);
+ ptpd->word3 |= (iph->ihl & TPD_IPHL_MASK) <<
+ TPD_IPHL_SHIFT;
+ ptpd->word3 |= ((tcp_hdrlen(skb) >> 2) &
+ TPD_TCPHDRLEN_MASK) <<
+ TPD_TCPHDRLEN_SHIFT;
+ ptpd->word3 |= 1 << TPD_IP_CSUM_SHIFT;
+ ptpd->word3 |= 1 << TPD_TCP_CSUM_SHIFT;
+ return 1;
+ }
+
iph->check = 0;
tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
- iph->daddr, 0, IPPROTO_TCP, 0);
- ipofst = skb_network_offset(skb);
- if (ipofst != ETH_HLEN) /* 802.3 frame */
- tso->tsopl |= 1 << TSO_PARAM_ETHTYPE_SHIFT;
-
- tso->tsopl |= (iph->ihl &
- TSO_PARAM_IPHL_MASK) << TSO_PARAM_IPHL_SHIFT;
- tso->tsopl |= ((tcp_hdrlen(skb) >> 2) &
- TSO_PARAM_TCPHDRLEN_MASK) <<
- TSO_PARAM_TCPHDRLEN_SHIFT;
- tso->tsopl |= (skb_shinfo(skb)->gso_size &
- TSO_PARAM_MSS_MASK) << TSO_PARAM_MSS_SHIFT;
- tso->tsopl |= 1 << TSO_PARAM_IPCKSUM_SHIFT;
- tso->tsopl |= 1 << TSO_PARAM_TCPCKSUM_SHIFT;
- tso->tsopl |= 1 << TSO_PARAM_SEGMENT_SHIFT;
- return true;
+ iph->daddr, 0, IPPROTO_TCP, 0);
+ ip_off = (unsigned char *)iph -
+ (unsigned char *) skb_network_header(skb);
+ if (ip_off == 8) /* 802.3-SNAP frame */
+ ptpd->word3 |= 1 << TPD_ETHTYPE_SHIFT;
+ else if (ip_off != 0)
+ return -2;
+
+ ptpd->word3 |= (iph->ihl & TPD_IPHL_MASK) <<
+ TPD_IPHL_SHIFT;
+ ptpd->word3 |= ((tcp_hdrlen(skb) >> 2) &
+ TPD_TCPHDRLEN_MASK) << TPD_TCPHDRLEN_SHIFT;
+ ptpd->word3 |= (skb_shinfo(skb)->gso_size &
+ TPD_MSS_MASK) << TPD_MSS_SHIFT;
+ ptpd->word3 |= 1 << TPD_SEGMENT_EN_SHIFT;
+ return 3;
}
}
return false;
}
static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb,
- struct csum_param *csum)
+ struct tx_packet_desc *ptpd)
{
u8 css, cso;
@@ -1335,115 +1354,116 @@ static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb,
"payload offset not an even number\n");
return -1;
}
- csum->csumpl |= (cso & CSUM_PARAM_PLOADOFFSET_MASK) <<
- CSUM_PARAM_PLOADOFFSET_SHIFT;
- csum->csumpl |= (css & CSUM_PARAM_XSUMOFFSET_MASK) <<
- CSUM_PARAM_XSUMOFFSET_SHIFT;
- csum->csumpl |= 1 << CSUM_PARAM_CUSTOMCKSUM_SHIFT;
+ ptpd->word3 |= (cso & TPD_PLOADOFFSET_MASK) <<
+ TPD_PLOADOFFSET_SHIFT;
+ ptpd->word3 |= (css & TPD_CCSUMOFFSET_MASK) <<
+ TPD_CCSUMOFFSET_SHIFT;
+ ptpd->word3 |= 1 << TPD_CUST_CSUM_EN_SHIFT;
return true;
}
-
- return true;
+ return 0;
}
static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
- bool tcp_seg)
+ struct tx_packet_desc *ptpd)
{
- /* We enter this function holding a spinlock. */
+ /* spinlock held */
struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
struct atl1_buffer *buffer_info;
+ u16 buf_len = skb->len;
struct page *page;
- int first_buf_len = skb->len;
unsigned long offset;
unsigned int nr_frags;
unsigned int f;
- u16 tpd_next_to_use;
- u16 proto_hdr_len;
- u16 len12;
+ int retval;
+ u16 next_to_use;
+ u16 data_len;
+ u8 hdr_len;
- first_buf_len -= skb->data_len;
+ buf_len -= skb->data_len;
nr_frags = skb_shinfo(skb)->nr_frags;
- tpd_next_to_use = atomic_read(&tpd_ring->next_to_use);
- buffer_info = &tpd_ring->buffer_info[tpd_next_to_use];
+ next_to_use = atomic_read(&tpd_ring->next_to_use);
+ buffer_info = &tpd_ring->buffer_info[next_to_use];
if (unlikely(buffer_info->skb))
BUG();
/* put skb in last TPD */
buffer_info->skb = NULL;
- if (tcp_seg) {
- /* TSO/GSO */
- proto_hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
- buffer_info->length = proto_hdr_len;
+ retval = (ptpd->word3 >> TPD_SEGMENT_EN_SHIFT) & TPD_SEGMENT_EN_MASK;
+ if (retval) {
+ /* TSO */
+ hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+ buffer_info->length = hdr_len;
page = virt_to_page(skb->data);
offset = (unsigned long)skb->data & ~PAGE_MASK;
buffer_info->dma = pci_map_page(adapter->pdev, page,
- offset, proto_hdr_len,
+ offset, hdr_len,
PCI_DMA_TODEVICE);
- if (++tpd_next_to_use == tpd_ring->count)
- tpd_next_to_use = 0;
+ if (++next_to_use == tpd_ring->count)
+ next_to_use = 0;
- if (first_buf_len > proto_hdr_len) {
- int i, m;
+ if (buf_len > hdr_len) {
+ int i, nseg;
- len12 = first_buf_len - proto_hdr_len;
- m = (len12 + ATL1_MAX_TX_BUF_LEN - 1) /
+ data_len = buf_len - hdr_len;
+ nseg = (data_len + ATL1_MAX_TX_BUF_LEN - 1) /
ATL1_MAX_TX_BUF_LEN;
- for (i = 0; i < m; i++) {
+ for (i = 0; i < nseg; i++) {
buffer_info =
- &tpd_ring->buffer_info[tpd_next_to_use];
+ &tpd_ring->buffer_info[next_to_use];
buffer_info->skb = NULL;
buffer_info->length =
(ATL1_MAX_TX_BUF_LEN >=
- len12) ? ATL1_MAX_TX_BUF_LEN : len12;
- len12 -= buffer_info->length;
+ data_len) ? ATL1_MAX_TX_BUF_LEN : data_len;
+ data_len -= buffer_info->length;
page = virt_to_page(skb->data +
- (proto_hdr_len +
- i * ATL1_MAX_TX_BUF_LEN));
+ (hdr_len + i * ATL1_MAX_TX_BUF_LEN));
offset = (unsigned long)(skb->data +
- (proto_hdr_len +
- i * ATL1_MAX_TX_BUF_LEN)) & ~PAGE_MASK;
+ (hdr_len + i * ATL1_MAX_TX_BUF_LEN)) &
+ ~PAGE_MASK;
buffer_info->dma = pci_map_page(adapter->pdev,
page, offset, buffer_info->length,
PCI_DMA_TODEVICE);
- if (++tpd_next_to_use == tpd_ring->count)
- tpd_next_to_use = 0;
+ if (++next_to_use == tpd_ring->count)
+ next_to_use = 0;
}
}
} else {
- /* not TSO/GSO */
- buffer_info->length = first_buf_len;
+ /* not TSO */
+ buffer_info->length = buf_len;
page = virt_to_page(skb->data);
offset = (unsigned long)skb->data & ~PAGE_MASK;
buffer_info->dma = pci_map_page(adapter->pdev, page,
- offset, first_buf_len, PCI_DMA_TODEVICE);
- if (++tpd_next_to_use == tpd_ring->count)
- tpd_next_to_use = 0;
+ offset, buf_len, PCI_DMA_TODEVICE);
+ if (++next_to_use == tpd_ring->count)
+ next_to_use = 0;
}
for (f = 0; f < nr_frags; f++) {
struct skb_frag_struct *frag;
- u16 lenf, i, m;
+ u16 i, nseg;
frag = &skb_shinfo(skb)->frags[f];
- lenf = frag->size;
+ buf_len = frag->size;
- m = (lenf + ATL1_MAX_TX_BUF_LEN - 1) / ATL1_MAX_TX_BUF_LEN;
- for (i = 0; i < m; i++) {
- buffer_info = &tpd_ring->buffer_info[tpd_next_to_use];
+ nseg = (buf_len + ATL1_MAX_TX_BUF_LEN - 1) /
+ ATL1_MAX_TX_BUF_LEN;
+ for (i = 0; i < nseg; i++) {
+ buffer_info = &tpd_ring->buffer_info[next_to_use];
if (unlikely(buffer_info->skb))
BUG();
buffer_info->skb = NULL;
- buffer_info->length = (lenf > ATL1_MAX_TX_BUF_LEN) ?
- ATL1_MAX_TX_BUF_LEN : lenf;
- lenf -= buffer_info->length;
+ buffer_info->length = (buf_len > ATL1_MAX_TX_BUF_LEN) ?
+ ATL1_MAX_TX_BUF_LEN : buf_len;
+ buf_len -= buffer_info->length;
buffer_info->dma = pci_map_page(adapter->pdev,
frag->page,
frag->page_offset + (i * ATL1_MAX_TX_BUF_LEN),
buffer_info->length, PCI_DMA_TODEVICE);
- if (++tpd_next_to_use == tpd_ring->count)
- tpd_next_to_use = 0;
+ if (++next_to_use == tpd_ring->count)
+ next_to_use = 0;
}
}
@@ -1451,39 +1471,44 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
buffer_info->skb = skb;
}
-static void atl1_tx_queue(struct atl1_adapter *adapter, int count,
- union tpd_descr *descr)
+static void atl1_tx_queue(struct atl1_adapter *adapter, u16 count,
+ struct tx_packet_desc *ptpd)
{
- /* We enter this function holding a spinlock. */
+ /* spinlock held */
struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
- int j;
- u32 val;
struct atl1_buffer *buffer_info;
struct tx_packet_desc *tpd;
- u16 tpd_next_to_use = atomic_read(&tpd_ring->next_to_use);
+ u16 j;
+ u32 val;
+ u16 next_to_use = (u16) atomic_read(&tpd_ring->next_to_use);
for (j = 0; j < count; j++) {
- buffer_info = &tpd_ring->buffer_info[tpd_next_to_use];
- tpd = ATL1_TPD_DESC(&adapter->tpd_ring, tpd_next_to_use);
- tpd->desc.csum.csumpu = descr->csum.csumpu;
- tpd->desc.csum.csumpl = descr->csum.csumpl;
- tpd->desc.tso.tsopu = descr->tso.tsopu;
- tpd->desc.tso.tsopl = descr->tso.tsopl;
+ buffer_info = &tpd_ring->buffer_info[next_to_use];
+ tpd = ATL1_TPD_DESC(&adapter->tpd_ring, next_to_use);
+ if (tpd != ptpd)
+ memcpy(tpd, ptpd, sizeof(struct tx_packet_desc));
tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
- tpd->desc.data = descr->data;
- tpd->desc.tso.tsopu |= (cpu_to_le16(buffer_info->length) &
- TSO_PARAM_BUFLEN_MASK) << TSO_PARAM_BUFLEN_SHIFT;
+ tpd->word2 = (cpu_to_le16(buffer_info->length) &
+ TPD_BUFLEN_MASK) << TPD_BUFLEN_SHIFT;
- val = (descr->tso.tsopl >> TSO_PARAM_SEGMENT_SHIFT) &
- TSO_PARAM_SEGMENT_MASK;
- if (val && !j)
- tpd->desc.tso.tsopl |= 1 << TSO_PARAM_HDRFLAG_SHIFT;
+ /*
+ * if this is the first packet in a TSO chain, set
+ * TPD_HDRFLAG, otherwise, clear it.
+ */
+ val = (tpd->word3 >> TPD_SEGMENT_EN_SHIFT) &
+ TPD_SEGMENT_EN_MASK;
+ if (val) {
+ if (!j)
+ tpd->word3 |= 1 << TPD_HDRFLAG_SHIFT;
+ else
+ tpd->word3 &= ~(1 << TPD_HDRFLAG_SHIFT);
+ }
if (j == (count - 1))
- tpd->desc.tso.tsopl |= 1 << TSO_PARAM_EOP_SHIFT;
+ tpd->word3 |= 1 << TPD_EOP_SHIFT;
- if (++tpd_next_to_use == tpd_ring->count)
- tpd_next_to_use = 0;
+ if (++next_to_use == tpd_ring->count)
+ next_to_use = 0;
}
/*
* Force memory writes to complete before letting h/w
@@ -1493,18 +1518,18 @@ static void atl1_tx_queue(struct atl1_adapter *adapter, int count,
*/
wmb();
- atomic_set(&tpd_ring->next_to_use, (int)tpd_next_to_use);
+ atomic_set(&tpd_ring->next_to_use, next_to_use);
}
static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
{
struct atl1_adapter *adapter = netdev_priv(netdev);
+ struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
int len = skb->len;
int tso;
int count = 1;
int ret_val;
- u32 val;
- union tpd_descr param;
+ struct tx_packet_desc *ptpd;
u16 frag_size;
u16 vlan_tag;
unsigned long flags;
@@ -1515,18 +1540,11 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
len -= skb->data_len;
- if (unlikely(skb->len == 0)) {
+ if (unlikely(skb->len <= 0)) {
dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
}
- param.data = 0;
- param.tso.tsopu = 0;
- param.tso.tsopl = 0;
- param.csum.csumpu = 0;
- param.csum.csumpl = 0;
-
- /* nr_frags will be nonzero if we're doing scatter/gather (SG) */
nr_frags = skb_shinfo(skb)->nr_frags;
for (f = 0; f < nr_frags; f++) {
frag_size = skb_shinfo(skb)->frags[f].size;
@@ -1535,10 +1553,9 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
ATL1_MAX_TX_BUF_LEN;
}
- /* mss will be nonzero if we're doing segment offload (TSO/GSO) */
mss = skb_shinfo(skb)->gso_size;
if (mss) {
- if (skb->protocol == htons(ETH_P_IP)) {
+ if (skb->protocol == ntohs(ETH_P_IP)) {
proto_hdr_len = (skb_transport_offset(skb) +
tcp_hdrlen(skb));
if (unlikely(proto_hdr_len > len)) {
@@ -1567,18 +1584,20 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
return NETDEV_TX_BUSY;
}
- param.data = 0;
+ ptpd = ATL1_TPD_DESC(tpd_ring,
+ (u16) atomic_read(&tpd_ring->next_to_use));
+ memset(ptpd, 0, sizeof(struct tx_packet_desc));
if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
vlan_tag = vlan_tx_tag_get(skb);
vlan_tag = (vlan_tag << 4) | (vlan_tag >> 13) |
((vlan_tag >> 9) & 0x8);
- param.tso.tsopl |= 1 << TSO_PARAM_INSVLAG_SHIFT;
- param.tso.tsopu |= (vlan_tag & TSO_PARAM_VLANTAG_MASK) <<
- TSO_PARAM_VLAN_SHIFT;
+ ptpd->word3 |= 1 << TPD_INS_VL_TAG_SHIFT;
+ ptpd->word3 |= (vlan_tag & TPD_VL_TAGGED_MASK) <<
+ TPD_VL_TAGGED_SHIFT;
}
- tso = atl1_tso(adapter, skb, ¶m.tso);
+ tso = atl1_tso(adapter, skb, ptpd);
if (tso < 0) {
spin_unlock_irqrestore(&adapter->lock, flags);
dev_kfree_skb_any(skb);
@@ -1586,7 +1605,7 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
}
if (!tso) {
- ret_val = atl1_tx_csum(adapter, skb, ¶m.csum);
+ ret_val = atl1_tx_csum(adapter, skb, ptpd);
if (ret_val < 0) {
spin_unlock_irqrestore(&adapter->lock, flags);
dev_kfree_skb_any(skb);
@@ -1594,13 +1613,11 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
}
}
- val = (param.tso.tsopl >> TSO_PARAM_SEGMENT_SHIFT) &
- TSO_PARAM_SEGMENT_MASK;
- atl1_tx_map(adapter, skb, 1 == val);
- atl1_tx_queue(adapter, count, ¶m);
- netdev->trans_start = jiffies;
- spin_unlock_irqrestore(&adapter->lock, flags);
+ atl1_tx_map(adapter, skb, ptpd);
+ atl1_tx_queue(adapter, count, ptpd);
atl1_update_mailbox(adapter);
+ spin_unlock_irqrestore(&adapter->lock, flags);
+ netdev->trans_start = jiffies;
return NETDEV_TX_OK;
}
@@ -2759,7 +2776,7 @@ const struct ethtool_ops atl1_ethtool_ops = {
.get_ringparam = atl1_get_ringparam,
.set_ringparam = atl1_set_ringparam,
.get_pauseparam = atl1_get_pauseparam,
- .set_pauseparam = atl1_set_pauseparam,
+ .set_pauseparam = atl1_set_pauseparam,
.get_rx_csum = atl1_get_rx_csum,
.set_tx_csum = ethtool_op_set_tx_hw_csum,
.get_link = ethtool_op_get_link,
diff --git a/drivers/net/atlx/atl1.h b/drivers/net/atlx/atl1.h
index 30c5a8d..4d3d65b 100644
--- a/drivers/net/atlx/atl1.h
+++ b/drivers/net/atlx/atl1.h
@@ -452,106 +452,115 @@ struct rx_free_desc {
/* __attribute__ ((packed)) is required */
} __attribute__ ((packed));
-/* tsopu defines */
-#define TSO_PARAM_BUFLEN_MASK 0x3FFF
-#define TSO_PARAM_BUFLEN_SHIFT 0
-#define TSO_PARAM_DMAINT_MASK 0x0001
-#define TSO_PARAM_DMAINT_SHIFT 14
-#define TSO_PARAM_PKTNT_MASK 0x0001
-#define TSO_PARAM_PKTINT_SHIFT 15
-#define TSO_PARAM_VLANTAG_MASK 0xFFFF
-#define TSO_PARAM_VLAN_SHIFT 16
-
-/* tsopl defines */
-#define TSO_PARAM_EOP_MASK 0x0001
-#define TSO_PARAM_EOP_SHIFT 0
-#define TSO_PARAM_COALESCE_MASK 0x0001
-#define TSO_PARAM_COALESCE_SHIFT 1
-#define TSO_PARAM_INSVLAG_MASK 0x0001
-#define TSO_PARAM_INSVLAG_SHIFT 2
-#define TSO_PARAM_CUSTOMCKSUM_MASK 0x0001
-#define TSO_PARAM_CUSTOMCKSUM_SHIFT 3
-#define TSO_PARAM_SEGMENT_MASK 0x0001
-#define TSO_PARAM_SEGMENT_SHIFT 4
-#define TSO_PARAM_IPCKSUM_MASK 0x0001
-#define TSO_PARAM_IPCKSUM_SHIFT 5
-#define TSO_PARAM_TCPCKSUM_MASK 0x0001
-#define TSO_PARAM_TCPCKSUM_SHIFT 6
-#define TSO_PARAM_UDPCKSUM_MASK 0x0001
-#define TSO_PARAM_UDPCKSUM_SHIFT 7
-#define TSO_PARAM_VLANTAGGED_MASK 0x0001
-#define TSO_PARAM_VLANTAGGED_SHIFT 8
-#define TSO_PARAM_ETHTYPE_MASK 0x0001
-#define TSO_PARAM_ETHTYPE_SHIFT 9
-#define TSO_PARAM_IPHL_MASK 0x000F
-#define TSO_PARAM_IPHL_SHIFT 10
-#define TSO_PARAM_TCPHDRLEN_MASK 0x000F
-#define TSO_PARAM_TCPHDRLEN_SHIFT 14
-#define TSO_PARAM_HDRFLAG_MASK 0x0001
-#define TSO_PARAM_HDRFLAG_SHIFT 18
-#define TSO_PARAM_MSS_MASK 0x1FFF
-#define TSO_PARAM_MSS_SHIFT 19
-
-/* csumpu defines */
-#define CSUM_PARAM_BUFLEN_MASK 0x3FFF
-#define CSUM_PARAM_BUFLEN_SHIFT 0
-#define CSUM_PARAM_DMAINT_MASK 0x0001
-#define CSUM_PARAM_DMAINT_SHIFT 14
-#define CSUM_PARAM_PKTINT_MASK 0x0001
-#define CSUM_PARAM_PKTINT_SHIFT 15
-#define CSUM_PARAM_VALANTAG_MASK 0xFFFF
-#define CSUM_PARAM_VALAN_SHIFT 16
-
-/* csumpl defines*/
-#define CSUM_PARAM_EOP_MASK 0x0001
-#define CSUM_PARAM_EOP_SHIFT 0
-#define CSUM_PARAM_COALESCE_MASK 0x0001
-#define CSUM_PARAM_COALESCE_SHIFT 1
-#define CSUM_PARAM_INSVLAG_MASK 0x0001
-#define CSUM_PARAM_INSVLAG_SHIFT 2
-#define CSUM_PARAM_CUSTOMCKSUM_MASK 0x0001
-#define CSUM_PARAM_CUSTOMCKSUM_SHIFT 3
-#define CSUM_PARAM_SEGMENT_MASK 0x0001
-#define CSUM_PARAM_SEGMENT_SHIFT 4
-#define CSUM_PARAM_IPCKSUM_MASK 0x0001
-#define CSUM_PARAM_IPCKSUM_SHIFT 5
-#define CSUM_PARAM_TCPCKSUM_MASK 0x0001
-#define CSUM_PARAM_TCPCKSUM_SHIFT 6
-#define CSUM_PARAM_UDPCKSUM_MASK 0x0001
-#define CSUM_PARAM_UDPCKSUM_SHIFT 7
-#define CSUM_PARAM_VLANTAGGED_MASK 0x0001
-#define CSUM_PARAM_VLANTAGGED_SHIFT 8
-#define CSUM_PARAM_ETHTYPE_MASK 0x0001
-#define CSUM_PARAM_ETHTYPE_SHIFT 9
-#define CSUM_PARAM_IPHL_MASK 0x000F
-#define CSUM_PARAM_IPHL_SHIFT 10
-#define CSUM_PARAM_PLOADOFFSET_MASK 0x00FF
-#define CSUM_PARAM_PLOADOFFSET_SHIFT 16
-#define CSUM_PARAM_XSUMOFFSET_MASK 0x00FF
-#define CSUM_PARAM_XSUMOFFSET_SHIFT 24
-
-/* TPD descriptor */
-struct tso_param {
- /* The order of these declarations is important -- don't change it */
- u32 tsopu; /* tso_param upper word */
- u32 tsopl; /* tso_param lower word */
-};
-
-struct csum_param {
- /* The order of these declarations is important -- don't change it */
- u32 csumpu; /* csum_param upper word */
- u32 csumpl; /* csum_param lower word */
-};
+/*
+ * The L1 transmit packet descriptor is comprised of four 32-bit words.
+ *
+ * 31 0
+ * +---------------------------------------+
+ * | Word 0: Buffer addr lo |
+ * +---------------------------------------+
+ * | Word 1: Buffer addr hi |
+ * +---------------------------------------+
+ * | Word 2 |
+ * +---------------------------------------+
+ * | Word 3 |
+ * +---------------------------------------+
+ *
+ * Words 0 and 1 combine to form a 64-bit buffer address.
+ *
+ * Word 2 is self explanatory in the #define block below.
+ *
+ * Word 3 has two forms, depending upon the state of bits 3 and 4.
+ * If bits 3 and 4 are both zero, then bits 14:31 are unused by the
+ * hardware. Otherwise, if either bit 3 or 4 is set, the definition
+ * of bits 14:31 vary according to the following depiction.
+ *
+ * 0 End of packet 0 End of packet
+ * 1 Coalesce 1 Coalesce
+ * 2 Insert VLAN tag 2 Insert VLAN tag
+ * 3 Custom csum enable = 0 3 Custom csum enable = 1
+ * 4 Segment enable = 1 4 Segment enable = 0
+ * 5 Generate IP checksum 5 Generate IP checksum
+ * 6 Generate TCP checksum 6 Generate TCP checksum
+ * 7 Generate UDP checksum 7 Generate UDP checksum
+ * 8 VLAN tagged 8 VLAN tagged
+ * 9 Ethernet frame type 9 Ethernet frame type
+ * 10-+ 10-+
+ * 11 | IP hdr length (10:13) 11 | IP hdr length (10:13)
+ * 12 | (num 32-bit words) 12 | (num 32-bit words)
+ * 13-+ 13-+
+ * 14-+ 14 Unused
+ * 15 | TCP hdr length (14:17) 15 Unused
+ * 16 | (num 32-bit words) 16-+
+ * 17-+ 17 |
+ * 18 Header TPD flag 18 |
+ * 19-+ 19 | Payload offset
+ * 20 | 20 | (16:23)
+ * 21 | 21 |
+ * 22 | 22 |
+ * 23 | 23-+
+ * 24 | 24-+
+ * 25 | MSS (19:31) 25 |
+ * 26 | 26 |
+ * 27 | 27 | Custom csum offset
+ * 28 | 28 | (24:31)
+ * 29 | 29 |
+ * 30 | 30 |
+ * 31-+ 31-+
+ */
-union tpd_descr {
- u64 data;
- struct csum_param csum;
- struct tso_param tso;
-};
+/* tpd word 2 */
+#define TPD_BUFLEN_MASK 0x3FFF
+#define TPD_BUFLEN_SHIFT 0
+#define TPD_DMAINT_MASK 0x0001
+#define TPD_DMAINT_SHIFT 14
+#define TPD_PKTNT_MASK 0x0001
+#define TPD_PKTINT_SHIFT 15
+#define TPD_VLANTAG_MASK 0xFFFF
+#define TPD_VLAN_SHIFT 16
+
+/* tpd word 3 bits 0:13 */
+#define TPD_EOP_MASK 0x0001
+#define TPD_EOP_SHIFT 0
+#define TPD_COALESCE_MASK 0x0001
+#define TPD_COALESCE_SHIFT 1
+#define TPD_INS_VL_TAG_MASK 0x0001
+#define TPD_INS_VL_TAG_SHIFT 2
+#define TPD_CUST_CSUM_EN_MASK 0x0001
+#define TPD_CUST_CSUM_EN_SHIFT 3
+#define TPD_SEGMENT_EN_MASK 0x0001
+#define TPD_SEGMENT_EN_SHIFT 4
+#define TPD_IP_CSUM_MASK 0x0001
+#define TPD_IP_CSUM_SHIFT 5
+#define TPD_TCP_CSUM_MASK 0x0001
+#define TPD_TCP_CSUM_SHIFT 6
+#define TPD_UDP_CSUM_MASK 0x0001
+#define TPD_UDP_CSUM_SHIFT 7
+#define TPD_VL_TAGGED_MASK 0x0001
+#define TPD_VL_TAGGED_SHIFT 8
+#define TPD_ETHTYPE_MASK 0x0001
+#define TPD_ETHTYPE_SHIFT 9
+#define TPD_IPHL_MASK 0x000F
+#define TPD_IPHL_SHIFT 10
+
+/* tpd word 3 bits 14:31 if segment enabled */
+#define TPD_TCPHDRLEN_MASK 0x000F
+#define TPD_TCPHDRLEN_SHIFT 14
+#define TPD_HDRFLAG_MASK 0x0001
+#define TPD_HDRFLAG_SHIFT 18
+#define TPD_MSS_MASK 0x1FFF
+#define TPD_MSS_SHIFT 19
+
+/* tpd word 3 bits 16:31 if custom csum enabled */
+#define TPD_PLOADOFFSET_MASK 0x00FF
+#define TPD_PLOADOFFSET_SHIFT 16
+#define TPD_CCSUMOFFSET_MASK 0x00FF
+#define TPD_CCSUMOFFSET_SHIFT 24
struct tx_packet_desc {
__le64 buffer_addr;
- union tpd_descr desc;
+ __le32 word2;
+ __le32 word3;
};
/* DMA Order Settings */
--
1.5.3.7
^ permalink raw reply related
* Re: [PATCH 09/14] [usbnet] add driver_priv pointer to 'struct usbnet'
From: David Brownell @ 2008-01-25 0:59 UTC (permalink / raw)
To: Jussi Kivilinna
Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA, bjd-a1rhEgazXTw,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20080120001432.25718.30378.stgit-q/85JClnwdg@public.gmane.org>
On Saturday 19 January 2008, Jussi Kivilinna wrote:
> Add a private data pointer to usbnet for rndis_wext module to use.
>
> Signed-off-by: Jussi Kivilinna <jussi.kivilinna-E01nCVcF24I@public.gmane.org>
Acked-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
> ---
>
> drivers/net/usb/usbnet.h | 1 +
> 1 files changed, 1 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/usb/usbnet.h b/drivers/net/usb/usbnet.h
> index 29ab92e..0b4bf09 100644
> --- a/drivers/net/usb/usbnet.h
> +++ b/drivers/net/usb/usbnet.h
> @@ -31,6 +31,7 @@ struct usbnet {
> struct usb_interface *intf;
> struct driver_info *driver_info;
> const char *driver_name;
> + void *driver_priv;
> wait_queue_head_t *wait;
> struct mutex phy_mutex;
> unsigned char suspend_count;
>
^ permalink raw reply
* Re: [PATCH 06/14] [usbnet] Use wlan device name for RNDIS wireless devices
From: David Brownell @ 2008-01-25 0:56 UTC (permalink / raw)
To: Jussi Kivilinna
Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA, bjd-a1rhEgazXTw,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20080120001415.25718.1762.stgit-q/85JClnwdg@public.gmane.org>
On Saturday 19 January 2008, Jussi Kivilinna wrote:
> Use wlan device name for RNDIS wireless devices.
>
> Signed-off-by: Jussi Kivilinna <jussi.kivilinna-E01nCVcF24I@public.gmane.org>
> Signed-off-by: Bjorge Dijkstra <bjd-a1rhEgazXTw@public.gmane.org>
Acked-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
> ---
>
> drivers/net/usb/usbnet.c | 3 +++
> drivers/net/usb/usbnet.h | 2 ++
> 2 files changed, 5 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
> index 8ed1fc5..a2a2d5e 100644
> --- a/drivers/net/usb/usbnet.c
> +++ b/drivers/net/usb/usbnet.c
> @@ -1204,6 +1204,9 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
> if ((dev->driver_info->flags & FLAG_ETHER) != 0
> && (net->dev_addr [0] & 0x02) == 0)
> strcpy (net->name, "eth%d");
> + /* WLAN devices should always be named "wlan%d" */
> + if ((dev->driver_info->flags & FLAG_WLAN) != 0)
> + strcpy(net->name, "wlan%d");
>
> /* maybe the remote can't receive an Ethernet MTU */
> if (net->mtu > (dev->hard_mtu - net->hard_header_len))
> diff --git a/drivers/net/usb/usbnet.h b/drivers/net/usb/usbnet.h
> index 1fae434..29ab92e 100644
> --- a/drivers/net/usb/usbnet.h
> +++ b/drivers/net/usb/usbnet.h
> @@ -87,6 +87,8 @@ struct driver_info {
> #define FLAG_ETHER 0x0020 /* maybe use "eth%d" names */
>
> #define FLAG_FRAMING_AX 0x0040 /* AX88772/178 packets */
> +#define FLAG_WLAN 0x0080 /* use "wlan%d" names */
> +
>
> /* init device ... can sleep, or cause probe() failure */
> int (*bind)(struct usbnet *, struct usb_interface *);
>
^ permalink raw reply
* Re: [PATCH 04/14] [rndis_host] Halt device if rndis_bind fails.
From: David Brownell @ 2008-01-25 0:55 UTC (permalink / raw)
To: Jussi Kivilinna
Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA, bjd-a1rhEgazXTw,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20080120001404.25718.6901.stgit-q/85JClnwdg@public.gmane.org>
On Saturday 19 January 2008, Jussi Kivilinna wrote:
> When bind fails after device was initialized, shutdown device properly
> by sending RNDIS_MSG_HALT.
>
> Signed-off-by: Jussi Kivilinna <jussi.kivilinna-E01nCVcF24I@public.gmane.org>
> Signed-off-by: Bjorge Dijkstra <bjd-a1rhEgazXTw@public.gmane.org>
Acked-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
> ---
>
> drivers/net/usb/rndis_host.c | 12 +++++++++---
> 1 files changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
> index 42b161c..c686025 100644
> --- a/drivers/net/usb/rndis_host.c
> +++ b/drivers/net/usb/rndis_host.c
> @@ -467,6 +467,7 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
> struct rndis_query_c *get_c;
> struct rndis_set *set;
> struct rndis_set_c *set_c;
> + struct rndis_halt *halt;
> } u;
> u32 tmp;
> int reply_len;
> @@ -517,7 +518,7 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
> "dev can't take %u byte packets (max %u)\n",
> dev->hard_mtu, tmp);
> retval = -EINVAL;
> - goto fail_and_release;
> + goto halt_fail_and_release;
> }
> dev->hard_mtu = tmp;
> net->mtu = dev->hard_mtu - net->hard_header_len;
> @@ -539,7 +540,7 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
> 48, (void **) &bp, &reply_len);
> if (unlikely(retval< 0)) {
> dev_err(&intf->dev, "rndis get ethaddr, %d\n", retval);
> - goto fail_and_release;
> + goto halt_fail_and_release;
> }
> memcpy(net->dev_addr, bp, ETH_ALEN);
>
> @@ -555,7 +556,7 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
> retval = rndis_command(dev, u.header);
> if (unlikely(retval < 0)) {
> dev_err(&intf->dev, "rndis set packet filter, %d\n", retval);
> - goto fail_and_release;
> + goto halt_fail_and_release;
> }
>
> retval = 0;
> @@ -563,6 +564,11 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
> kfree(u.buf);
> return retval;
>
> +halt_fail_and_release:
> + memset(u.halt, 0, sizeof *u.halt);
> + u.halt->msg_type = RNDIS_MSG_HALT;
> + u.halt->msg_len = ccpu2(sizeof *u.halt);
> + (void) rndis_command(dev, (void *)u.halt);
> fail_and_release:
> usb_set_intfdata(info->data, NULL);
> usb_driver_release_interface(driver_of(intf), info->data);
>
^ permalink raw reply
* Re: [PATCH 01/14] Fix sparse warning: returning void-valued expression
From: David Brownell @ 2008-01-25 0:52 UTC (permalink / raw)
To: Jussi Kivilinna
Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA, bjd-a1rhEgazXTw,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20080120001348.25718.36756.stgit-q/85JClnwdg@public.gmane.org>
On Saturday 19 January 2008, Jussi Kivilinna wrote:
> From: Bjorge Dijkstra <bjd-a1rhEgazXTw@public.gmane.org>
>
> rndis_unbind and usbnet_cdc_unbind don't return anything.
>
> Signed-off-by: Bjorge Dijkstra <bjd-a1rhEgazXTw@public.gmane.org>
> Signed-off-by: Jussi Kivilinna <jussi.kivilinna-E01nCVcF24I@public.gmane.org>
Acked-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
> ---
>
> drivers/net/usb/rndis_host.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
> index 1ebe325..96ef6a9 100644
> --- a/drivers/net/usb/rndis_host.c
> +++ b/drivers/net/usb/rndis_host.c
> @@ -585,7 +585,7 @@ static void rndis_unbind(struct usbnet *dev, struct usb_interface *intf)
> kfree(halt);
> }
>
> - return usbnet_cdc_unbind(dev, intf);
> + usbnet_cdc_unbind(dev, intf);
> }
>
> /*
>
^ permalink raw reply
* [ofa-general] Re: [PATCH 2.6.25] RDMA/cxgb3: Fix the T3A workaround checks.
From: Roland Dreier @ 2008-01-24 23:49 UTC (permalink / raw)
To: Steve Wise; +Cc: netdev, linux-kernel, general
In-Reply-To: <20080124223016.772.18293.stgit@dell3.ogc.int>
thanks, applied.
^ permalink raw reply
* [PATCH] SMC91x: Use IRQ save and restore versions of spinlocks
From: Kevin Hilman @ 2008-01-24 23:29 UTC (permalink / raw)
To: netdev; +Cc: Nicolas Pitre, Kevin Hilman
Under certain circumstances (e.g. kgdb over ethernet), the TX code may
be called with interrupts disabled. The spin_unlock_irq() calls in
the driver unconditionally re-enable interrupts, which may trigger the
netdev softirq to run and cause spinlock recursion in the net stack.
For example, here's an example path with interrupts disabled:
kgdb exception
eth_flush_buf
netpoll_send_udp
netpoll_send_skb [ takes netdevice->xmit_lock via netif_tx_trylock() ]
smc_hard_start_xmit
smc_hardware_send_pkt
SMC_ENABLE_INT()
spin_unlock_irq(&lp->lock)
That spin_unlock_irq() will re-enable interrupts, even if they wer
disabled, thus triggering the netdev softirq to run. The
dev_watchdog() will try to take the netdevice->xmit_lock which is
currently locked by netpoll_send_skb() and then BUG!
Also, use spin_trylock_irqsave() instead of a wrapped version of
spin_trylock.
Signed-off-by: Kevin Hilman <khilman@mvista.com>
Acked-by: Nicolas Pitre <nico@cam.org>
---
drivers/net/smc91x.c | 42 ++++++++++++++++++------------------------
1 files changed, 18 insertions(+), 24 deletions(-)
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index 7da7589..475de0f 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -222,21 +222,21 @@ static void PRINT_PKT(u_char *buf, int length)
/* this enables an interrupt in the interrupt mask register */
#define SMC_ENABLE_INT(x) do { \
unsigned char mask; \
- spin_lock_irq(&lp->lock); \
+ spin_lock_irqsave(&lp->lock, flags); \
mask = SMC_GET_INT_MASK(); \
mask |= (x); \
SMC_SET_INT_MASK(mask); \
- spin_unlock_irq(&lp->lock); \
+ spin_unlock_irqrestore(&lp->lock, flags); \
} while (0)
/* this disables an interrupt from the interrupt mask register */
#define SMC_DISABLE_INT(x) do { \
unsigned char mask; \
- spin_lock_irq(&lp->lock); \
+ spin_lock_irqsave(&lp->lock, flags); \
mask = SMC_GET_INT_MASK(); \
mask &= ~(x); \
SMC_SET_INT_MASK(mask); \
- spin_unlock_irq(&lp->lock); \
+ spin_unlock_irqrestore(&lp->lock, flags); \
} while (0)
/*
@@ -547,21 +547,13 @@ static inline void smc_rcv(struct net_device *dev)
* any other concurrent access and C would always interrupt B. But life
* isn't that easy in a SMP world...
*/
-#define smc_special_trylock(lock) \
-({ \
- int __ret; \
- local_irq_disable(); \
- __ret = spin_trylock(lock); \
- if (!__ret) \
- local_irq_enable(); \
- __ret; \
-})
-#define smc_special_lock(lock) spin_lock_irq(lock)
-#define smc_special_unlock(lock) spin_unlock_irq(lock)
+#define smc_special_trylock(lock, flags) spin_trylock_irqsave(lock, flags)
+#define smc_special_lock(lock, flags) spin_lock_irqsave(lock, flags)
+#define smc_special_unlock(lock, flags) spin_unlock_irqrestore(lock, flags)
#else
-#define smc_special_trylock(lock) (1)
-#define smc_special_lock(lock) do { } while (0)
-#define smc_special_unlock(lock) do { } while (0)
+#define smc_special_trylock(lock,flags) (1)
+#define smc_special_lock(lock,flags) do { } while (0)
+#define smc_special_unlock(lock,flags) do { } while (0)
#endif
/*
@@ -575,10 +567,11 @@ static void smc_hardware_send_pkt(unsigned long data)
struct sk_buff *skb;
unsigned int packet_no, len;
unsigned char *buf;
+ unsigned long flags;
DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
- if (!smc_special_trylock(&lp->lock)) {
+ if (!smc_special_trylock(&lp->lock, flags)) {
netif_stop_queue(dev);
tasklet_schedule(&lp->tx_task);
return;
@@ -586,7 +579,7 @@ static void smc_hardware_send_pkt(unsigned long data)
skb = lp->pending_tx_skb;
if (unlikely(!skb)) {
- smc_special_unlock(&lp->lock);
+ smc_special_unlock(&lp->lock, flags);
return;
}
lp->pending_tx_skb = NULL;
@@ -596,7 +589,7 @@ static void smc_hardware_send_pkt(unsigned long data)
printk("%s: Memory allocation failed.\n", dev->name);
dev->stats.tx_errors++;
dev->stats.tx_fifo_errors++;
- smc_special_unlock(&lp->lock);
+ smc_special_unlock(&lp->lock, flags);
goto done;
}
@@ -635,7 +628,7 @@ static void smc_hardware_send_pkt(unsigned long data)
/* queue the packet for TX */
SMC_SET_MMU_CMD(MC_ENQUEUE);
- smc_special_unlock(&lp->lock);
+ smc_special_unlock(&lp->lock, flags);
dev->trans_start = jiffies;
dev->stats.tx_packets++;
@@ -660,6 +653,7 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct smc_local *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base;
unsigned int numPages, poll_count, status;
+ unsigned long flags;
DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
@@ -685,7 +679,7 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
return 0;
}
- smc_special_lock(&lp->lock);
+ smc_special_lock(&lp->lock, flags);
/* now, try to allocate the memory */
SMC_SET_MMU_CMD(MC_ALLOC | numPages);
@@ -703,7 +697,7 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
} while (--poll_count);
- smc_special_unlock(&lp->lock);
+ smc_special_unlock(&lp->lock, flags);
lp->pending_tx_skb = skb;
if (!poll_count) {
--
1.5.3.7
^ permalink raw reply related
* [ofa-general] [PATCH 2.6.25] RDMA/cxgb3: Fix the T3A workaround checks.
From: Steve Wise @ 2008-01-24 22:30 UTC (permalink / raw)
To: rdreier; +Cc: netdev, linux-kernel, general
RDMA/cxgb3: Fix the T3A workaround checks.
Correctly work around T3A issues by checking "hwtype != T3A" instead of
"hwtype == T3B". Needed for new hw types.
Signed-off-by: Steve Wise <swise@opengridcomputing.com>
---
drivers/infiniband/hw/cxgb3/cxio_hal.c | 2 +-
drivers/infiniband/hw/cxgb3/iwch_cm.c | 4 ++--
drivers/infiniband/hw/cxgb3/iwch_provider.c | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c
index eec6a30..e220b44 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_hal.c
+++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c
@@ -179,7 +179,7 @@ int cxio_create_cq(struct cxio_rdev *rdev_p, struct t3_cq *cq)
setup.size = 1UL << cq->size_log2;
setup.credits = 65535;
setup.credit_thres = 1;
- if (rdev_p->t3cdev_p->type == T3B)
+ if (rdev_p->t3cdev_p->type != T3A)
setup.ovfl_mode = 0;
else
setup.ovfl_mode = 1;
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c
index 20ba372..f8cb0fe 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c
@@ -1118,7 +1118,7 @@ static int act_open_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
status2errno(rpl->status));
connect_reply_upcall(ep, status2errno(rpl->status));
state_set(&ep->com, DEAD);
- if (ep->com.tdev->type == T3B && act_open_has_tid(rpl->status))
+ if (ep->com.tdev->type != T3A && act_open_has_tid(rpl->status))
release_tid(ep->com.tdev, GET_TID(rpl), NULL);
cxgb3_free_atid(ep->com.tdev, ep->atid);
dst_release(ep->dst);
@@ -1249,7 +1249,7 @@ static void reject_cr(struct t3cdev *tdev, u32 hwtid, __be32 peer_ip,
skb_trim(skb, sizeof(struct cpl_tid_release));
skb_get(skb);
- if (tdev->type == T3B)
+ if (tdev->type != T3A)
release_tid(tdev, hwtid, skb);
else {
struct cpl_pass_accept_rpl *rpl;
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c
index 69b1204..df1838f 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_provider.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c
@@ -646,7 +646,7 @@ static struct ib_mr *iwch_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
if (err)
goto err;
- if (udata && t3b_device(rhp)) {
+ if (udata && !t3a_device(rhp)) {
uresp.pbl_addr = (mhp->attr.pbl_addr -
rhp->rdev.rnic_info.pbl_base) >> 3;
PDBG("%s user resp pbl_addr 0x%x\n", __FUNCTION__,
^ permalink raw reply related
* Re: Slow OOM in netif_RX function
From: Francois Romieu @ 2008-01-24 21:51 UTC (permalink / raw)
To: Ivan H. Dichev; +Cc: netdev
In-Reply-To: <20080124211810.3E24A46E9A@smtp.obs.bg>
Ivan H. Dichev <idichev@obs.bg> :
[...]
> Any other ideas appreciated.
Plot the slab values and the counters of the iptables rules against time ?
--
Ueimor
^ permalink raw reply
* [PATCH] fib_trie: rescan if key is lost during dump
From: Stephen Hemminger @ 2008-01-24 21:51 UTC (permalink / raw)
To: David Miller; +Cc: kaber, netdev
In-Reply-To: <20080123.232747.75654058.davem@davemloft.net>
Normally during a dump the key of the last dumped entry is used for
continuation, but since lock is dropped it might be lost. In that case
fallback to the old counter based N^2 behaviour. This means the dump will end up
skipping some routes which matches what FIB_HASH does.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/include/linux/netlink.h 2008-01-24 13:39:40.000000000 -0800
+++ b/include/linux/netlink.h 2008-01-24 13:42:05.000000000 -0800
@@ -219,7 +219,7 @@ struct netlink_callback
int (*dump)(struct sk_buff * skb, struct netlink_callback *cb);
int (*done)(struct netlink_callback *cb);
int family;
- long args[5];
+ long args[6];
};
struct netlink_notify
--- a/net/ipv4/fib_trie.c 2008-01-24 13:39:40.000000000 -0800
+++ b/net/ipv4/fib_trie.c 2008-01-24 13:44:26.000000000 -0800
@@ -1743,6 +1743,19 @@ static struct leaf *trie_nextleaf(struct
return leaf_walk_rcu(p, c);
}
+static struct leaf *trie_leafindex(struct trie *t, int index)
+{
+ struct leaf *l = trie_firstleaf(t);
+
+ while (index-- > 0) {
+ l = trie_nextleaf(l);
+ if (!l)
+ break;
+ }
+ return l;
+}
+
+
/*
* Caller must hold RTNL.
*/
@@ -1848,7 +1861,7 @@ static int fn_trie_dump_fa(t_key key, in
struct fib_alias *fa;
__be32 xkey = htonl(key);
- s_i = cb->args[4];
+ s_i = cb->args[5];
i = 0;
/* rcu_read_lock is hold by caller */
@@ -1869,12 +1882,12 @@ static int fn_trie_dump_fa(t_key key, in
plen,
fa->fa_tos,
fa->fa_info, NLM_F_MULTI) < 0) {
- cb->args[4] = i;
+ cb->args[5] = i;
return -1;
}
i++;
}
- cb->args[4] = i;
+ cb->args[5] = i;
return skb->len;
}
@@ -1885,7 +1898,7 @@ static int fn_trie_dump_leaf(struct leaf
struct hlist_node *node;
int i, s_i;
- s_i = cb->args[3];
+ s_i = cb->args[4];
i = 0;
/* rcu_read_lock is hold by caller */
@@ -1896,19 +1909,19 @@ static int fn_trie_dump_leaf(struct leaf
}
if (i > s_i)
- cb->args[4] = 0;
+ cb->args[5] = 0;
if (list_empty(&li->falh))
continue;
if (fn_trie_dump_fa(l->key, li->plen, &li->falh, tb, skb, cb) < 0) {
- cb->args[3] = i;
+ cb->args[4] = i;
return -1;
}
i++;
}
- cb->args[3] = i;
+ cb->args[4] = i;
return skb->len;
}
@@ -1918,35 +1931,37 @@ static int fn_trie_dump(struct fib_table
struct leaf *l;
struct trie *t = (struct trie *) tb->tb_data;
t_key key = cb->args[2];
+ int count = cb->args[3];
rcu_read_lock();
/* Dump starting at last key.
* Note: 0.0.0.0/0 (ie default) is first key.
*/
- if (!key)
+ if (count == 0)
l = trie_firstleaf(t);
else {
+ /* Normally, continue from last key, but if that is missing
+ * fallback to using slow rescan
+ */
l = fib_find_node(t, key);
- if (!l) {
- /* The table changed during the dump, rather than
- * giving partial data, just make application retry.
- */
- rcu_read_unlock();
- return -EBUSY;
- }
+ if (!l)
+ l = trie_leafindex(t, count);
}
while (l) {
cb->args[2] = l->key;
if (fn_trie_dump_leaf(l, tb, skb, cb) < 0) {
+ cb->args[3] = count;
rcu_read_unlock();
return -1;
}
+ ++count;
l = trie_nextleaf(l);
- memset(&cb->args[3], 0,
- sizeof(cb->args) - 3*sizeof(cb->args[0]));
+ memset(&cb->args[4], 0,
+ sizeof(cb->args) - 4*sizeof(cb->args[0]));
}
+ cb->args[3] = count;
rcu_read_unlock();
return skb->len;
^ permalink raw reply
* Re: [Bugme-new] [Bug 9808] New: system hung with htb QoS
From: Andrew Morton @ 2008-01-24 21:50 UTC (permalink / raw)
To: Brandeburg, Jesse
Cc: e1000-devel, netdev, bilias, auke-jan.h.kok, bugme-daemon
In-Reply-To: <36D9DB17C6DE9E40B059440DB8D95F520444FDF4@orsmsx418.amr.corp.intel.com>
> On Thu, 24 Jan 2008 12:06:58 -0800 "Brandeburg, Jesse" <jesse.brandeburg@intel.com> wrote:
> Would you be willing to try the 7.6.15 driver at e1000.sourceforge.net,
> it has many more fixes for e1000 than what is available in the in-kernel
> driver. I just posted a patch in the "Tracker/Patches" area that
> patches 7.6.15 to support the e1000_dump code to dump rings when the tx
> hang occurs which will help us figure out a) what software did to the
> ring, b) if something is messed up in the ring which we know will hang
> the hardware
General hand-waving: if you have a debug patch which helps diagnose
rare problems when a tester hits them, please consider just putting
them straight into the mainline tree.
We can always take them out later when everything is resolved, and we
can help ourselves a lot this way.
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
^ permalink raw reply
* Slow OOM in netif_RX function
From: Ivan H. Dichev @ 2008-01-24 21:18 UTC (permalink / raw)
To: netdev
In-Reply-To: <4798E32E.6080003@cosmosbay.com>
Eric Dumazet writes:
> Ivan Dichev a écrit :
>> Hello,
>> I got problem with my linux router. It has slow persistent OOM
>> problems from few months ago.
>> Every working(I mean days when more traffic is generated) day my
>> router is leaking with 15-20 MB memory and
>> after 2 weeks the restart is a MUST.
>>> From /proc/slabinfo I saw that size-2048 and size-512 are growing
>> rapidly every day when traffic occur.
>>
>> --------- /proc/slabinfo --------------------
>> size-2048 20322 20349 2072 3 2 : tunables 24 12 0
>> : slabdata 6780 6783 0
>> size-512 50984 51016 536 7 1 : tunables 32 16 0
>> : slabdata 7288 7288 0
>>
>>
>> I was wondering who is allocating this mem pools and then I changed
>> the kernel with 2.6.23-rc12 including options
>> CONFIG_DEBUG_SLAB=y
>> CONFIG_DEBUG_SLAB_LEAK=y
>>
>>
>> Unfortunately changing the kernel didn't solve the mem leak....
>> Now /proc/slab_allocators is showing that 3c59x driver is allocating
>> 2048 and 512 bytes memory pools
>> caused by RX function.
>> --------- from /proc/slab_allocators ------------------------------
>> 7612 size-2048: boomerang_rx+0x33b/0x437 [3c59x]
>> 16018 size-512: boomerang_rx+0x165/0x437 [3c59x]
>>
>> I was thinking that the 3com driver is bogus, .. but not!
>> After few days I changed the cards with rtl8139 and now ....
>> --------- from /proc/slab_allocators ------------------------------
>> size-2048: 20159 rtl8139_rx+0x155/0x2dc [8139too]
>> size-1024: 2693 rtl8139_rx+0x155/0x2dc [8139too]
>> size-512: 50515 rtl8139_rx+0x155/0x2dc [8139too]
>>
>> the memory leak appear again in the same function(RX).
>>
>> I did search over the mailing list and found as similar only this
>> http://www.spinics.net/lists/kernel/old/2003-q4/msg03071.html
>>
>>
>> For sure it does not depend on kernel version and network
>> driver(except case if both drivers are bogus :)
>> Any ideas ?
>>
>
> Could you post your iptable rules "iptables -t nat -nvL ; iptables -nvL",
> and full "cat /proc/slabinfo" ?
>
>
Sorry but my firewall is 7000+ lines and I cant paste the rules.
And that's why it's very hard to debug the chains :(
I have better idea!
What could happen if I put different Lan card in every slot?
In ex. to-private -> 3com
to-inet -> VIA
to-dmz -> rtl8139
And then to look which RX function is consuming the memory.
(boomerang_rx, rtl8139_rx, ... etc)
With this it will be easier to understand which iptables rules(bound to the
found interface) have to be watched.
(I am not sure that it will work ?)
Any other ideas appreciated.
Ivan Dichev
^ permalink raw reply
* Re: [PATCH UCC TDM 1/3 Updated] Platform changes for UCC TDM driver for MPC8323eRDB. Also includes related QE changes and dts entries.
From: Scott Wood @ 2008-01-24 20:24 UTC (permalink / raw)
To: Timur Tabi
Cc: Poonam_Aggrwal-b10812, michael.barkowski, netdev, kumar.gala,
linux-kernel, rubini, linuxppc-dev, ashish.kalra, rich.cutler,
akpm
In-Reply-To: <4798BDEB.2010501@freescale.com>
On Thu, Jan 24, 2008 at 10:33:47AM -0600, Timur Tabi wrote: Yes, but
> deciding what the UCC does might not be static. At what point do we
> declare, "UCC5 is for eth0 and eth0 only"?
When the board designer decides to hook eth0 up to UCC5.
If the board designer decides to hook multiple devices up to UCC5, we first
smack the board designer, and then set it up to whichever configuration has
been jumpered.
-Scott
^ permalink raw reply
* Re: [PATCH UCC TDM 3/3 ] Modified Documentation to explain dts entries for TDM driver
From: Scott Wood @ 2008-01-24 20:12 UTC (permalink / raw)
To: Poonam_Aggrwal-b10812
Cc: kumar.gala, akpm, linux-kernel, netdev, rubini, linuxppc-dev,
michael.barkowski, rich.cutler, timur, ashish.kalra
In-Reply-To: <Pine.LNX.4.64.0801241022070.27491@linux121>
On Thu, Jan 24, 2008 at 10:24:13AM +0530, Poonam_Aggrwal-b10812 wrote:
> + ix) Baud Rate Generator (BRG)
> +
> + Required properties:
> + - compatible : shpuld be "fsl,cpm-brg"
> + - fsl,brg-sources : define the input clock for all 16 BRGs. The input
> + clock source could be 1 to 24 for CLK1 to CLK24. Zero means that the
> + particular BRG will be driven by QE clock(BRGCLK).
Should also have a clock-frequency property to specify what BRGCLK is.
-Scott
^ permalink raw reply
* Re: [Bugme-new] [Bug 9808] New: system hung with htb QoS
From: Brandeburg, Jesse @ 2008-01-24 20:06 UTC (permalink / raw)
To: Andrew Morton, netdev; +Cc: e1000-devel, bilias, Kok, Auke-jan H, bugme-daemon
In-Reply-To: <20080124061157.3512a308.akpm@linux-foundation.org>
Andrew Morton wrote:
>> I'm also receiving this quite often:
>> Jan 15 12:23:17 ftp kernel: e1000: eth0: e1000_clean_tx_irq:
>> Detected Tx Unit Hang Jan 15 12:23:17 ftp kernel: Tx Queue
>> <0>
>> Jan 15 12:23:17 ftp kernel: TDH <2a>
>> Jan 15 12:23:17 ftp kernel: TDT <17>
>> Jan 15 12:23:17 ftp kernel: next_to_use <17>
>> Jan 15 12:23:17 ftp kernel: next_to_clean <2a>
>> Jan 15 12:23:17 ftp kernel: buffer_info[next_to_clean]
>> Jan 15 12:23:17 ftp kernel: time_stamp <5798144>
>> Jan 15 12:23:17 ftp kernel: next_to_watch <2d>
>> Jan 15 12:23:17 ftp kernel: jiffies <57988ef>
>> Jan 15 12:23:17 ftp kernel: next_to_watch.status <0>
>> Jan 15 12:23:19 ftp kernel: e1000: eth0: e1000_clean_tx_irq:
>> Detected Tx Unit Hang
Looks like a real hardware hang.
Would you be willing to try the 7.6.15 driver at e1000.sourceforge.net,
it has many more fixes for e1000 than what is available in the in-kernel
driver. I just posted a patch in the "Tracker/Patches" area that
patches 7.6.15 to support the e1000_dump code to dump rings when the tx
hang occurs which will help us figure out a) what software did to the
ring, b) if something is messed up in the ring which we know will hang
the hardware
>> Today for the first time (after applying options to e1000 driver in
>> modprobe.conf) I got a kernel panic:
>>
>> BUG: unable to handle kernel paging request at virtual address
>> a0379120
>> EIP: 0060: [<c05db2dc>] Not Tainted VLI
>> EIP is at ip_rcv+0x286/0x4ba
>> Kernel panic - not syncing: Fatal exception in interrupt
>>
>> This is what I wrote on paper cause there wasn't logged anywhere.
>> Usually it hungs without a kernel panic.
Everyone involved will need more information about the panic to make
progress on the panic.
>>
>> System in Fedoca Core 8 up2date
>> 2.6.23.9-85.fc8PAE
>> 2x Intel(R) Xeon(TM) CPU 3.20GHz
>> 4G RAM
>>
>> Without the QoS loaded system never hungs. It must be related to
>> this. However the e1000 error I'm receiving must have to do with the
>> e1000 driver. I've seen this bug in the past that's why I tried to
>> apply the options in modprobe.conf
>> modprobe.conf options for e1000:
>> options e1000 XsumRX=0 Speed=1000 Duplex=2 InterruptThrottleRate=0
>> FlowControl=3 RxDescriptors=4096 TxDescriptors=4096 RxIntDelay=0
>> TxIntDelay=0
Please don't use any of these options unless you must, they seem to have
come from some debian forum that someone just posted a SWAG at changing
parameters that fixed him for some unknown reason.
Get back to us with the debug output, the e1000 issue can be covered on
e1000-devel@lists.sourceforge.net
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox