* [PATCH 0/2] net/irda: sh_sir: Bug fix patches
From: Kuninori Morimoto @ 2010-04-06 4:42 UTC (permalink / raw)
To: netdev; +Cc: Samuel Ortiz, David S. Miller
Dear David
Kuninori Morimoto (2):
net/irda: sh_sir: fixup err return value on sh_sir_open
net/irda: sh_sir: Modify iounmap wrong execution
These 2 patches are bug fix of sh_sir driver.
Best regards
--
Kuninori Morimoto
^ permalink raw reply
* Re: [v2 Patch 3/3] bonding: make bonding support netpoll
From: Cong Wang @ 2010-04-06 4:38 UTC (permalink / raw)
To: Andy Gospodarek
Cc: linux-kernel, Matt Mackall, netdev, bridge, Andy Gospodarek,
Neil Horman, Jeff Moyer, Stephen Hemminger, bonding-devel,
Jay Vosburgh, David Miller
In-Reply-To: <4BBA9FDB.4040909@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 279 bytes --]
Cong Wang wrote:
> Before I try to reproduce it, could you please try to replace the
> 'read_lock()'
> in slaves_support_netpoll() with 'read_lock_bh()'? (read_unlock() too)
> Try if this helps.
>
Confirmed. Please use the attached patch instead, for your testing.
Thanks!
[-- Attachment #2: bonding-support-netpoll.diff --]
[-- Type: text/x-patch, Size: 4225 bytes --]
Index: linux-2.6/drivers/net/bonding/bond_main.c
===================================================================
--- linux-2.6.orig/drivers/net/bonding/bond_main.c
+++ linux-2.6/drivers/net/bonding/bond_main.c
@@ -59,6 +59,7 @@
#include <linux/uaccess.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
+#include <linux/netpoll.h>
#include <linux/inetdevice.h>
#include <linux/igmp.h>
#include <linux/etherdevice.h>
@@ -430,7 +431,18 @@ int bond_dev_queue_xmit(struct bonding *
}
skb->priority = 1;
- dev_queue_xmit(skb);
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ if (bond->dev->priv_flags & IFF_IN_NETPOLL) {
+ struct netpoll *np = bond->dev->npinfo->netpoll;
+ slave_dev->npinfo = bond->dev->npinfo;
+ np->real_dev = np->dev = skb->dev;
+ slave_dev->priv_flags |= IFF_IN_NETPOLL;
+ netpoll_send_skb(np, skb);
+ slave_dev->priv_flags &= ~IFF_IN_NETPOLL;
+ np->dev = bond->dev;
+ } else
+#endif
+ dev_queue_xmit(skb);
return 0;
}
@@ -1329,6 +1341,61 @@ static void bond_detach_slave(struct bon
bond->slave_cnt--;
}
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * You must hold read lock of bond->lock before calling this.
+ */
+static bool slaves_support_netpoll(struct net_device *bond_dev)
+{
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct slave *slave;
+ int i = 0;
+ bool ret = true;
+
+ bond_for_each_slave(bond, slave, i) {
+ if ((slave->dev->priv_flags & IFF_DISABLE_NETPOLL)
+ || !slave->dev->netdev_ops->ndo_poll_controller)
+ ret = false;
+ }
+ return i != 0 && ret;
+}
+
+static void bond_poll_controller(struct net_device *bond_dev)
+{
+ struct net_device *dev = bond_dev->npinfo->netpoll->real_dev;
+ if (dev != bond_dev)
+ netpoll_poll_dev(dev);
+}
+
+static void bond_netpoll_cleanup(struct net_device *bond_dev)
+{
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct slave *slave;
+ const struct net_device_ops *ops;
+ int i;
+
+ read_lock(&bond->lock);
+ bond_dev->npinfo = NULL;
+ bond_for_each_slave(bond, slave, i) {
+ if (slave->dev) {
+ ops = slave->dev->netdev_ops;
+ if (ops->ndo_netpoll_cleanup)
+ ops->ndo_netpoll_cleanup(slave->dev);
+ else
+ slave->dev->npinfo = NULL;
+ }
+ }
+ read_unlock(&bond->lock);
+}
+
+#else
+
+static void bond_netpoll_cleanup(struct net_device *bond_dev)
+{
+}
+
+#endif
+
/*---------------------------------- IOCTL ----------------------------------*/
static int bond_sethwaddr(struct net_device *bond_dev,
@@ -1735,6 +1802,18 @@ int bond_enslave(struct net_device *bond
bond_set_carrier(bond);
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ if (slaves_support_netpoll(bond_dev)) {
+ bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL;
+ if (bond_dev->npinfo)
+ slave_dev->npinfo = bond_dev->npinfo;
+ } else if (!(bond_dev->priv_flags & IFF_DISABLE_NETPOLL)) {
+ bond_dev->priv_flags |= IFF_DISABLE_NETPOLL;
+ pr_info("New slave device %s does not support netpoll\n",
+ slave_dev->name);
+ pr_info("Disabling netpoll support for %s\n", bond_dev->name);
+ }
+#endif
read_unlock(&bond->lock);
res = bond_create_slave_symlinks(bond_dev, slave_dev);
@@ -1929,6 +2008,17 @@ int bond_release(struct net_device *bond
netdev_set_master(slave_dev, NULL);
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ read_lock_bh(&bond->lock);
+ if (slaves_support_netpoll(bond_dev))
+ bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL;
+ read_unlock_bh(&bond->lock);
+ if (slave_dev->netdev_ops->ndo_netpoll_cleanup)
+ slave_dev->netdev_ops->ndo_netpoll_cleanup(slave_dev);
+ else
+ slave_dev->npinfo = NULL;
+#endif
+
/* close slave before restoring its mac address */
dev_close(slave_dev);
@@ -4448,6 +4538,10 @@ static const struct net_device_ops bond_
.ndo_vlan_rx_register = bond_vlan_rx_register,
.ndo_vlan_rx_add_vid = bond_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = bond_vlan_rx_kill_vid,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_netpoll_cleanup = bond_netpoll_cleanup,
+ .ndo_poll_controller = bond_poll_controller,
+#endif
};
static void bond_setup(struct net_device *bond_dev)
@@ -4533,6 +4627,8 @@ static void bond_uninit(struct net_devic
{
struct bonding *bond = netdev_priv(bond_dev);
+ bond_netpoll_cleanup(bond_dev);
+
/* Release the bonded slaves */
bond_release_all(bond_dev);
^ permalink raw reply
* Re: [PATCH] IPVS: replace sprintf to snprintf to avoid stack buffer overflow
From: Simon Horman @ 2010-04-06 3:26 UTC (permalink / raw)
To: Changli Gao
Cc: wzt.wzt, linux-kernel, wensong, Julian Anastasov, netdev,
lvs-devel, Patrick McHardy
In-Reply-To: <k2l412e6f7f1004051958h7c50f439r6b7a84379c35cba5@mail.gmail.com>
On Tue, Apr 06, 2010 at 10:58:28AM +0800, Changli Gao wrote:
> On Tue, Apr 6, 2010 at 10:50 AM, <wzt.wzt@gmail.com> wrote:
> > IPVS not check the length of pp->name, use sprintf will cause stack buffer overflow.
> > struct ip_vs_protocol{} declare name as char *, if register a protocol as:
> > struct ip_vs_protocol ip_vs_test = {
> > .name = "aaaaaaaa....128...aaa",
> > .debug_packet = ip_vs_tcpudp_debug_packet,
> > };
> >
> > when called ip_vs_tcpudp_debug_packet(), sprintf(buf, "%s TRUNCATED", pp->name);
> > will cause stack buffer overflow.
> >
>
> Long messages will be truncated instead of buffer overflow. We need to
> find a way to handle long messages elegantly.
Its really a corner case. In practice protocol modules don't have really
long names. And if one was merged that did, the buffer size could be increased
at that time.
So while I think its reasonable to protect against something unexpected
in a protocol-module name crashing the system. Especially as that
can be achieved without any real overhead. I don't think we need
to sanitise the output.
^ permalink raw reply
* Re: [PATCH] IPVS: replace sprintf to snprintf to avoid stack buffer overflow
From: Simon Horman @ 2010-04-06 3:22 UTC (permalink / raw)
To: wzt.wzt
Cc: linux-kernel, Wensong Zhang, Julian Anastasov, netdev, lvs-devel,
Patrick McHardy
In-Reply-To: <20100406025020.GA2741@localhost.localdomain>
On Tue, Apr 06, 2010 at 10:50:20AM +0800, wzt.wzt@gmail.com wrote:
> IPVS not check the length of pp->name, use sprintf will cause stack buffer overflow.
> struct ip_vs_protocol{} declare name as char *, if register a protocol as:
> struct ip_vs_protocol ip_vs_test = {
> .name = "aaaaaaaa....128...aaa",
> .debug_packet = ip_vs_tcpudp_debug_packet,
> };
>
> when called ip_vs_tcpudp_debug_packet(), sprintf(buf, "%s TRUNCATED", pp->name);
> will cause stack buffer overflow.
>
> Signed-off-by: Zhitong Wang <zhitong.wangzt@alibaba-inc.com>
I think that the simple answer is, don't do that.
But your patch seems entirely reasonable to me.
Acked-by: Simon Horman <horms@verge.net.au>
Patrick, please consider merging this.
^ permalink raw reply
* Re: [PATCH] virtio-net: move sg off stack
From: Rusty Russell @ 2010-04-06 3:14 UTC (permalink / raw)
To: David Miller; +Cc: mst, jpirko, xma, netdev, linux-kernel
In-Reply-To: <20100401.192648.185498218.davem@davemloft.net>
On Fri, 2 Apr 2010 12:56:48 pm David Miller wrote:
> From: "Michael S. Tsirkin" <mst@redhat.com>
> Date: Wed, 31 Mar 2010 15:41:58 +0300
>
> > Move sg structure off stack and into virtnet_info structure.
> > This helps remove extra sg_init_table calls as well as reduce
> > stack usage.
> >
> > Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> > ---
> >
> > Compile-tested only for now.
> > Shirley, Rusty Russell, does this fix CONFIG_DEBUG_SG=y for you?
Yes, this fixes the BUG_ON() for me (trivial changes to base on Linus'
tree only).
Thanks,
Rusty.
^ permalink raw reply
* Re: [PATCH] IPVS: replace sprintf to snprintf to avoid stack buffer overflow
From: Changli Gao @ 2010-04-06 2:58 UTC (permalink / raw)
To: wzt.wzt; +Cc: linux-kernel, wensong, netdev, lvs-devel
In-Reply-To: <20100406025020.GA2741@localhost.localdomain>
On Tue, Apr 6, 2010 at 10:50 AM, <wzt.wzt@gmail.com> wrote:
> IPVS not check the length of pp->name, use sprintf will cause stack buffer overflow.
> struct ip_vs_protocol{} declare name as char *, if register a protocol as:
> struct ip_vs_protocol ip_vs_test = {
> .name = "aaaaaaaa....128...aaa",
> .debug_packet = ip_vs_tcpudp_debug_packet,
> };
>
> when called ip_vs_tcpudp_debug_packet(), sprintf(buf, "%s TRUNCATED", pp->name);
> will cause stack buffer overflow.
>
Long messages will be truncated instead of buffer overflow. We need to
find a way to handle long messages elegantly.
--
Regards,
Changli Gao(xiaosuo@gmail.com)
^ permalink raw reply
* [PATCH] IPVS: replace sprintf to snprintf to avoid stack buffer overflow
From: wzt.wzt @ 2010-04-06 2:50 UTC (permalink / raw)
To: linux-kernel; +Cc: wensong, netdev, lvs-devel
IPVS not check the length of pp->name, use sprintf will cause stack buffer overflow.
struct ip_vs_protocol{} declare name as char *, if register a protocol as:
struct ip_vs_protocol ip_vs_test = {
.name = "aaaaaaaa....128...aaa",
.debug_packet = ip_vs_tcpudp_debug_packet,
};
when called ip_vs_tcpudp_debug_packet(), sprintf(buf, "%s TRUNCATED", pp->name);
will cause stack buffer overflow.
Signed-off-by: Zhitong Wang <zhitong.wangzt@alibaba-inc.com>
---
net/netfilter/ipvs/ip_vs_proto.c | 16 ++++++++--------
net/netfilter/ipvs/ip_vs_proto_ah_esp.c | 8 ++++----
2 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/net/netfilter/ipvs/ip_vs_proto.c b/net/netfilter/ipvs/ip_vs_proto.c
index 0e58455..8143318 100644
--- a/net/netfilter/ipvs/ip_vs_proto.c
+++ b/net/netfilter/ipvs/ip_vs_proto.c
@@ -166,9 +166,9 @@ ip_vs_tcpudp_debug_packet_v4(struct ip_vs_protocol *pp,
ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
if (ih == NULL)
- sprintf(buf, "%s TRUNCATED", pp->name);
+ snprintf(buf, sizeof(buf), "%s TRUNCATED", pp->name);
else if (ih->frag_off & htons(IP_OFFSET))
- sprintf(buf, "%s %pI4->%pI4 frag",
+ snprintf(buf, sizeof(buf), "%s %pI4->%pI4 frag",
pp->name, &ih->saddr, &ih->daddr);
else {
__be16 _ports[2], *pptr
@@ -176,10 +176,10 @@ ip_vs_tcpudp_debug_packet_v4(struct ip_vs_protocol *pp,
pptr = skb_header_pointer(skb, offset + ih->ihl*4,
sizeof(_ports), _ports);
if (pptr == NULL)
- sprintf(buf, "%s TRUNCATED %pI4->%pI4",
+ snprintf(buf, sizeof(buf), "%s TRUNCATED %pI4->%pI4",
pp->name, &ih->saddr, &ih->daddr);
else
- sprintf(buf, "%s %pI4:%u->%pI4:%u",
+ snprintf(buf, sizeof(buf), "%s %pI4:%u->%pI4:%u",
pp->name,
&ih->saddr, ntohs(pptr[0]),
&ih->daddr, ntohs(pptr[1]));
@@ -200,9 +200,9 @@ ip_vs_tcpudp_debug_packet_v6(struct ip_vs_protocol *pp,
ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
if (ih == NULL)
- sprintf(buf, "%s TRUNCATED", pp->name);
+ snprintf(buf, sizeof(buf), "%s TRUNCATED", pp->name);
else if (ih->nexthdr == IPPROTO_FRAGMENT)
- sprintf(buf, "%s %pI6->%pI6 frag",
+ snprintf(buf, sizeof(buf), "%s %pI6->%pI6 frag",
pp->name, &ih->saddr, &ih->daddr);
else {
__be16 _ports[2], *pptr;
@@ -210,10 +210,10 @@ ip_vs_tcpudp_debug_packet_v6(struct ip_vs_protocol *pp,
pptr = skb_header_pointer(skb, offset + sizeof(struct ipv6hdr),
sizeof(_ports), _ports);
if (pptr == NULL)
- sprintf(buf, "%s TRUNCATED %pI6->%pI6",
+ snprintf(buf, sizeof(buf), "%s TRUNCATED %pI6->%pI6",
pp->name, &ih->saddr, &ih->daddr);
else
- sprintf(buf, "%s %pI6:%u->%pI6:%u",
+ snprintf(buf, sizeof(buf), "%s %pI6:%u->%pI6:%u",
pp->name,
&ih->saddr, ntohs(pptr[0]),
&ih->daddr, ntohs(pptr[1]));
diff --git a/net/netfilter/ipvs/ip_vs_proto_ah_esp.c b/net/netfilter/ipvs/ip_vs_proto_ah_esp.c
index c30b43c..ce795ab 100644
--- a/net/netfilter/ipvs/ip_vs_proto_ah_esp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_ah_esp.c
@@ -136,9 +136,9 @@ ah_esp_debug_packet_v4(struct ip_vs_protocol *pp, const struct sk_buff *skb,
ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
if (ih == NULL)
- sprintf(buf, "%s TRUNCATED", pp->name);
+ snprintf(buf, sizeof(buf), "%s TRUNCATED", pp->name);
else
- sprintf(buf, "%s %pI4->%pI4",
+ snprintf(buf, sizeof(buf), "%s %pI4->%pI4",
pp->name, &ih->saddr, &ih->daddr);
pr_debug("%s: %s\n", msg, buf);
@@ -154,9 +154,9 @@ ah_esp_debug_packet_v6(struct ip_vs_protocol *pp, const struct sk_buff *skb,
ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
if (ih == NULL)
- sprintf(buf, "%s TRUNCATED", pp->name);
+ snprintf(buf, sizeof(buf), "%s TRUNCATED", pp->name);
else
- sprintf(buf, "%s %pI6->%pI6",
+ snprintf(buf, sizeof(buf), "%s %pI6->%pI6",
pp->name, &ih->saddr, &ih->daddr);
pr_debug("%s: %s\n", msg, buf);
--
1.6.5.3
^ permalink raw reply related
* Re: [v2 Patch 3/3] bonding: make bonding support netpoll
From: Cong Wang @ 2010-04-06 2:43 UTC (permalink / raw)
To: Andy Gospodarek
Cc: linux-kernel, Matt Mackall, netdev, bridge, Andy Gospodarek,
Neil Horman, Jeff Moyer, Stephen Hemminger, bonding-devel,
Jay Vosburgh, David Miller
In-Reply-To: <20100405194356.GA10488@gospo.rdu.redhat.com>
Andy Gospodarek wrote:
>
> I tried these patches on top of Linus' latest tree and still get
> deadlocks. Your line numbers might differ a bit, but you should be
> seeing them too.
>
Yeah, my local clone is some days behind Linus' latest tree. :)
> # echo 7 4 1 7 > /proc/sys/kernel/printk
> # ifup bond0
> bonding: bond0: setting mode to balance-rr (0).
> bonding: bond0: Setting MII monitoring interval to 1000.
> ADDRCONF(NETDEV_UP): bond0: link is not ready
> bonding: bond0: Adding slave eth4.
> bnx2 0000:10:00.0: eth4: using MSIX
> bonding: bond0: enslaving eth4 as an active interface with a down link.
> bonding: bond0: Adding slave eth5.
> bnx2 0000:10:00.1: eth5: using MSIX
> bonding: bond0: enslaving eth5 as an active interface with a down link.
> bnx2 0000:10:00.0: eth4: NIC Copper Link is Up, 100 Mbps full duplex,
> receive & transmit flow control ON
> bonding: bond0: link status definitely up for interface eth4.
> ADDRCONF(NETDEV_CHANGE): bond0: link becomes ready
> bnx2 0000:10:00.1: eth5: NIC Copper Link is Up, 100 Mbps full duplex,
> receive & transmit flow control ON
> bond0: IPv6 duplicate address fe80::210:18ff:fe36:ad4 detected!
> bonding: bond0: link status definitely up for interface eth5.
> # cat /proc/net/bonding/bond0
> Ethernet Channel Bonding Driver: v3.6.0 (September 26, 2009)
>
> Bonding Mode: load balancing (round-robin)
> MII Status: up
> MII Polling Interval (ms): 1000
> Up Delay (ms): 0
> Down Delay (ms): 0
>
> Slave Interface: eth4
> MII Status: up
> Link Failure Count: 0
> Permanent HW addr: 00:10:18:36:0a:d4
>
> Slave Interface: eth5
> MII Status: up
> Link Failure Count: 0
> Permanent HW addr: 00:10:18:36:0a:d6
> # modprobe netconsole
> netconsole: local port 1234
> netconsole: local IP 10.0.100.2
> netconsole: interface 'bond0'
> netconsole: remote port 6666
> netconsole: remote IP 10.0.100.1
> netconsole: remote ethernet address 00:e0:81:71:ee:aa
> console [netcon0] enabled
> netconsole: network logging started
> # echo -eth4 > /sys/class/net/bond0/bonding/slaves
> bonding: bond0: Removing slave eth4
>
> [ now the system is hung ]
>
> My suspicion from dealing with this problem in the past is that there is
> contention over bond->lock.
>
> Since there statements that will result in netconsole messages inside
> the write_lock_bh in bond_release:
>
> 1882 write_lock_bh(&bond->lock);
> 1883
> 1884 slave = bond_get_slave_by_dev(bond, slave_dev);
> 1885 if (!slave) {
> 1886 /* not a slave of this bond */
> 1887 pr_info("%s: %s not enslaved\n",
> 1888 bond_dev->name, slave_dev->name);
> 1889 write_unlock_bh(&bond->lock);
> 1890 return -EINVAL;
> 1891 }
> 1892
> 1893 if (!bond->params.fail_over_mac) {
> 1894 if (!compare_ether_addr(bond_dev->dev_addr, slave->perm_hwaddr) &&
> 1895 bond->slave_cnt > 1)
> 1896 pr_warning("%s: Warning: the permanent HWaddr of %s - %pM - is still in use by %s.
>
> we are getting stuck at 1986 since bond_xmit_roundrobin (in my case)
> will try and acquire bond->lock for reading.
>
> One valuable aspect netpoll_start_xmit routine was that is could be used
> to check to be sure that bond->lock could be taken for writing. This
> made us sure that we were not in a call stack that has already taken the
> lock and queuing the skb to be sent later would prevent the imminent
> deadlock.
>
> A way to prevent this is needed and a first-pass might be to do
> something similar to what I below above for all the xmit routines. I
> confirmed the following patch prevents that deadlock:
>
> # git diff drivers/net/bonding/
> diff --git a/drivers/net/bonding/bond_main.c
> b/drivers/net/bonding/bond_main.c
> index 4a41886..53b39cc 100644
> --- a/drivers/net/bonding/bond_main.c
> +++ b/drivers/net/bonding/bond_main.c
> @@ -4232,7 +4232,8 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struc
> int i, slave_no, res = 1;
> struct iphdr *iph = ip_hdr(skb);
>
> - read_lock(&bond->lock);
> + if (!read_trylock(&bond->lock))
> + return NETDEV_TX_BUSY;
>
> if (!BOND_IS_OK(bond))
> goto out;
>
> The kernel no longer hangs, but a new warning message shows up (over
> netconsole even!):
>
> ------------[ cut here ]------------
> WARNING: at kernel/softirq.c:143 local_bh_enable+0x43/0xba()
> Hardware name: HP xw4400 Workstation
> Modules linked in: tg3 netconsole bonding ipt_REJECT bridge stp autofs4
> i2c_dev i2c_core hidp rfcomm l2cap crc16 bluetooth rfkill sunrpc 8021q
> iptable_filter ip_tables ip6t_REJECT xt_tcpudp ip6table_filter
> ip6_tables x_tables ipv6 cpufreq_ondemand acpi_cpufreq dm_multipath
> video output sbs sbshc battery acpi_memhotplug ac lp sg ide_cd_mod
> tpm_tis rtc_cmos rtc_core serio_raw cdrom libphy e1000e floppy
> parport_pc parport button tpm tpm_bios bnx2 rtc_lib tulip pcspkr shpchp
> dm_snapshot dm_zero dm_mirror dm_region_hash dm_log dm_mod ata_piix ahci
> libata sd_mod scsi_mod ext3 jbd uhci_hcd ohci_hcd ehci_hcd [last
> unloaded: tg3]
> Pid: 9, comm: events/0 Not tainted 2.6.34-rc3 #6
> Call Trace:
> [<ffffffff81058754>] ? cpu_clock+0x2d/0x41
> [<ffffffff810404d9>] ? local_bh_enable+0x43/0xba
> [<ffffffff8103a350>] warn_slowpath_common+0x77/0x8f
> [<ffffffff812a4659>] ? dev_queue_xmit+0x408/0x467
> [<ffffffff8103a377>] warn_slowpath_null+0xf/0x11
> [<ffffffff810404d9>] local_bh_enable+0x43/0xba
> [<ffffffff812a4659>] dev_queue_xmit+0x408/0x467
> [<ffffffff812a435e>] ? dev_queue_xmit+0x10d/0x467
> [<ffffffffa04a3868>] bond_dev_queue_xmit+0x1cd/0x1f9 [bonding]
> [<ffffffffa04a4217>] bond_start_xmit+0x139/0x3e9 [bonding]
> [<ffffffff812b0e9a>] queue_process+0xa8/0x160
> [<ffffffff812b0df2>] ? queue_process+0x0/0x160
> [<ffffffff81003794>] kernel_thread_helper+0x4/0x10
> [<ffffffff813362bc>] ? restore_args+0x0/0x30
> [<ffffffff81053884>] ? kthread+0x0/0x85
>
> to point out possible locking issues (probably in netpoll_send_skb) that
> I would suggest you investigate further. It may point to why we cannot
> perform an:
>
> # rmmod bonding
>
> without the system deadlocking (even with my patch above).
>
Thanks a lot for testing!
Before I try to reproduce it, could you please try to replace the 'read_lock()'
in slaves_support_netpoll() with 'read_lock_bh()'? (read_unlock() too) Try if this helps.
After I reproduce this, I will try it too.
^ permalink raw reply
* RE: net-next: 2.6.34-rc1 regression: panic when running diagnostic on interface with IPv6
From: Tantilov, Emil S @ 2010-04-06 2:37 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: David Miller, netdev@vger.kernel.org
In-Reply-To: <20100405191524.2a7848f3@nehalam>
Stephen Hemminger wrote:
> On Mon, 5 Apr 2010 17:50:38 -0600
> "Tantilov, Emil S" <emil.s.tantilov@intel.com> wrote:
>
>> David Miller wrote:
>>> From: "Tantilov, Emil S" <emil.s.tantilov@intel.com>
>>> Date: Mon, 5 Apr 2010 17:03:56 -0600
>>>
>>>> David Miller wrote:
>>>>> From: "Tantilov, Emil S" <emil.s.tantilov@intel.com>
>>>>> Date: Tue, 23 Mar 2010 12:28:08 -0600
>>>>>
>>>>>> Bisecting points to this patch:
>>>>>> http://git.kernel.org/?p=linux/kernel/git/davem/net-next-2.6.git;a=commitdiff;h=84e8b803f1e16f3a2b8b80f80a63fa2f2f8a9be6
>>>>>>
>>>>>> And I confirmed that the issue goes away after reverting it.
>>>>>>
>>>>>> Steps to reproduce:
>>>>>> 1. Load the driver and configure IPv6 address.
>>>>>> 2. Run ethtool diag:
>>>>>> ethtool -t eth0
>>>>>>
>>>>>> 3. If this doesn't brake it try again, or just do ifdown/up.
>>>>>> Other operations on the interface will eventually panic the
>>>>>> system:
>>>>>
>>>>> Stephen please fix this, thanks.
>>>>
>>>> Just FYI - I still see this issue with latest pull from net-2.6.
>>>
>>> It's net-next-2.6 that introduced the problem and has the follow-on
>>> fixes, not net-2.6
>>
>> Same in net-next:
>>
>> [ 55.706583] WARNING: at net/ipv6/ip6_fib.c:1170
>> fib6_del+0x44/0x39f [ipv6]() [ 55.714851] Hardware name: S5520HC
>> [ 55.719037] Modules linked in: ipv6 e1000e e1000
>> [ 55.724866] Pid: 5599, comm: ifconfig Not tainted
>> 2.6.34-rc1-net-next-e1000e-040510 #9 [ 55.734418] Call Trace: [
>> 55.737540] [<ffffffff81033a3e>] ? __wake_up+0x43/0x50 [
>> 55.743773] [<ffffffffa006cb4e>] ? fib6_del+0x44/0x39f [ipv6] [
>> 55.750687] [<ffffffff81038b1e>] warn_slowpath_common+0x77/0x8f [
>> 55.757793] [<ffffffff81038b45>] warn_slowpath_null+0xf/0x11 [
>> 55.764608] [<ffffffffa006cb4e>] fib6_del+0x44/0x39f [ipv6] [
>> 55.771314] [<ffffffffa006a13b>] __ip6_del_rt+0x49/0x68 [ipv6] [
>> 55.778319] [<ffffffffa006a2aa>] ip6_del_rt+0x38/0x3a [ipv6] [
>> 55.785136] [<ffffffffa0065573>] __ipv6_ifa_notify+0x141/0x17d
>> [ipv6] [ 55.792816] [<ffffffffa00660a4>]
>> addrconf_ifdown+0x1ed/0x2cb [ipv6] [ 55.800300]
>> [<ffffffffa0067126>] addrconf_notify+0x705/0x7b6 [ipv6] [
>> 55.807788] [<ffffffff810456ce>] ? spin_unlock_irqrestore+0x9/0xb [
>> 55.815088] [<ffffffff81045b80>] ? __mod_timer+0x125/0x137 [
>> 55.821703] [<ffffffff8144eb60>] ? _raw_write_unlock_bh+0x12/0x14 [
>> 55.828995] [<ffffffff8103e37d>] ? local_bh_enable_ip+0x9/0xb [
>> 55.835906] [<ffffffff8144ec75>] ? _raw_spin_unlock_bh+0x12/0x14 [
>> 55.843109] [<ffffffffa006ca9b>] ? fib6_run_gc+0xca/0xcf [ipv6] [
>> 55.850213] [<ffffffff81451b29>] notifier_call_chain+0x33/0x5b [
>> 55.857216] [<ffffffff81055575>] __raw_notifier_call_chain+0x9/0xb [
>> 55.864604] [<ffffffff81055586>] raw_notifier_call_chain+0xf/0x11 [
>> 55.871901] [<ffffffff81397d8f>] call_netdevice_notifiers+0x16/0x18
>> [ 55.879390] [<ffffffff81397eb2>] __dev_notify_flags+0x35/0x59 [
>> 55.886293] [<ffffffff81397f1c>] dev_change_flags+0x46/0x52 [
>> 55.893007] [<ffffffff813f0844>] devinet_ioctl+0x27f/0x54b [
>> 55.899614] [<ffffffff813f2c18>] inet_ioctl+0x8a/0xa2 [ 55.905733]
>> [<ffffffff81387275>] sock_do_ioctl+0x26/0x46 [ 55.912149]
>> [<ffffffff81387490>] sock_ioctl+0x1fb/0x20e [ 55.918461]
>> [<ffffffff810e7b4b>] vfs_ioctl+0x2a/0x9d [ 55.924495]
>> [<ffffffff810e80c2>] do_vfs_ioctl+0x48c/0x4dd [ 55.930999]
>> [<ffffffff810e816a>] sys_ioctl+0x57/0x7a [ 55.937033]
>> [<ffffffff81002a2b>] system_call_fastpath+0x16/0x1b [ 55.944123]
>> ---[ end trace c1c390412f982fb6 ]--- [ 55.949677] Freeing alive
>> inet6 address ffff8801eee32000 [ 56.034060] fib6_clean_node: del
>> failed: rt=ffff8801ec984e00@(null) err=-2
>>
>
> Which driver is this, the test function is driver dependent?
I have seen the panic with e1000e and bnx2.
Emil
^ permalink raw reply
* Re: net-next: 2.6.34-rc1 regression: panic when running diagnostic on interface with IPv6
From: Stephen Hemminger @ 2010-04-06 2:15 UTC (permalink / raw)
To: Tantilov, Emil S; +Cc: David Miller, netdev@vger.kernel.org
In-Reply-To: <EA929A9653AAE14F841771FB1DE5A1365FE4E2E334@rrsmsx501.amr.corp.intel.com>
On Mon, 5 Apr 2010 17:50:38 -0600
"Tantilov, Emil S" <emil.s.tantilov@intel.com> wrote:
> David Miller wrote:
> > From: "Tantilov, Emil S" <emil.s.tantilov@intel.com>
> > Date: Mon, 5 Apr 2010 17:03:56 -0600
> >
> >> David Miller wrote:
> >>> From: "Tantilov, Emil S" <emil.s.tantilov@intel.com>
> >>> Date: Tue, 23 Mar 2010 12:28:08 -0600
> >>>
> >>>> Bisecting points to this patch:
> >>>> http://git.kernel.org/?p=linux/kernel/git/davem/net-next-2.6.git;a=commitdiff;h=84e8b803f1e16f3a2b8b80f80a63fa2f2f8a9be6
> >>>>
> >>>> And I confirmed that the issue goes away after reverting it.
> >>>>
> >>>> Steps to reproduce:
> >>>> 1. Load the driver and configure IPv6 address.
> >>>> 2. Run ethtool diag:
> >>>> ethtool -t eth0
> >>>>
> >>>> 3. If this doesn't brake it try again, or just do ifdown/up. Other
> >>>> operations on the interface will eventually panic the system:
> >>>
> >>> Stephen please fix this, thanks.
> >>
> >> Just FYI - I still see this issue with latest pull from net-2.6.
> >
> > It's net-next-2.6 that introduced the problem and has the follow-on
> > fixes, not net-2.6
>
> Same in net-next:
>
> [ 55.706583] WARNING: at net/ipv6/ip6_fib.c:1170 fib6_del+0x44/0x39f [ipv6]()
> [ 55.714851] Hardware name: S5520HC
> [ 55.719037] Modules linked in: ipv6 e1000e e1000
> [ 55.724866] Pid: 5599, comm: ifconfig Not tainted 2.6.34-rc1-net-next-e1000e-040510 #9
> [ 55.734418] Call Trace:
> [ 55.737540] [<ffffffff81033a3e>] ? __wake_up+0x43/0x50
> [ 55.743773] [<ffffffffa006cb4e>] ? fib6_del+0x44/0x39f [ipv6]
> [ 55.750687] [<ffffffff81038b1e>] warn_slowpath_common+0x77/0x8f
> [ 55.757793] [<ffffffff81038b45>] warn_slowpath_null+0xf/0x11
> [ 55.764608] [<ffffffffa006cb4e>] fib6_del+0x44/0x39f [ipv6]
> [ 55.771314] [<ffffffffa006a13b>] __ip6_del_rt+0x49/0x68 [ipv6]
> [ 55.778319] [<ffffffffa006a2aa>] ip6_del_rt+0x38/0x3a [ipv6]
> [ 55.785136] [<ffffffffa0065573>] __ipv6_ifa_notify+0x141/0x17d [ipv6]
> [ 55.792816] [<ffffffffa00660a4>] addrconf_ifdown+0x1ed/0x2cb [ipv6]
> [ 55.800300] [<ffffffffa0067126>] addrconf_notify+0x705/0x7b6 [ipv6]
> [ 55.807788] [<ffffffff810456ce>] ? spin_unlock_irqrestore+0x9/0xb
> [ 55.815088] [<ffffffff81045b80>] ? __mod_timer+0x125/0x137
> [ 55.821703] [<ffffffff8144eb60>] ? _raw_write_unlock_bh+0x12/0x14
> [ 55.828995] [<ffffffff8103e37d>] ? local_bh_enable_ip+0x9/0xb
> [ 55.835906] [<ffffffff8144ec75>] ? _raw_spin_unlock_bh+0x12/0x14
> [ 55.843109] [<ffffffffa006ca9b>] ? fib6_run_gc+0xca/0xcf [ipv6]
> [ 55.850213] [<ffffffff81451b29>] notifier_call_chain+0x33/0x5b
> [ 55.857216] [<ffffffff81055575>] __raw_notifier_call_chain+0x9/0xb
> [ 55.864604] [<ffffffff81055586>] raw_notifier_call_chain+0xf/0x11
> [ 55.871901] [<ffffffff81397d8f>] call_netdevice_notifiers+0x16/0x18
> [ 55.879390] [<ffffffff81397eb2>] __dev_notify_flags+0x35/0x59
> [ 55.886293] [<ffffffff81397f1c>] dev_change_flags+0x46/0x52
> [ 55.893007] [<ffffffff813f0844>] devinet_ioctl+0x27f/0x54b
> [ 55.899614] [<ffffffff813f2c18>] inet_ioctl+0x8a/0xa2
> [ 55.905733] [<ffffffff81387275>] sock_do_ioctl+0x26/0x46
> [ 55.912149] [<ffffffff81387490>] sock_ioctl+0x1fb/0x20e
> [ 55.918461] [<ffffffff810e7b4b>] vfs_ioctl+0x2a/0x9d
> [ 55.924495] [<ffffffff810e80c2>] do_vfs_ioctl+0x48c/0x4dd
> [ 55.930999] [<ffffffff810e816a>] sys_ioctl+0x57/0x7a
> [ 55.937033] [<ffffffff81002a2b>] system_call_fastpath+0x16/0x1b
> [ 55.944123] ---[ end trace c1c390412f982fb6 ]---
> [ 55.949677] Freeing alive inet6 address ffff8801eee32000
> [ 56.034060] fib6_clean_node: del failed: rt=ffff8801ec984e00@(null) err=-2
>
Which driver is this, the test function is driver dependent?
--
^ permalink raw reply
* Re: [PATCH 1/2] TIPC: Updated topology subscription protocol according to latest spec
From: David Miller @ 2010-04-06 2:18 UTC (permalink / raw)
To: jon.maloy; +Cc: netdev, tipc-discussion
In-Reply-To: <1270516572-27789-1-git-send-email-jon.maloy@ericsson.com>
You're going to need to provide a descriptive commit log message with
these changes explaining what exactly is changing and why, as well as
provide a proper signoff for the patch.
Please read Documentation/SubmittingPatches at a minimum...
^ permalink raw reply
* re-submit3 [ANNOUNCEMENT] NET: usb: sierra_net.c driver
From: Elina Pasheva @ 2010-04-06 1:39 UTC (permalink / raw)
To: dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f
Cc: epasheva-ywE8TTl5eJHWpu6QEFMNjNBPR1lH4CV8,
rfiler-ywE8TTl5eJHWpu6QEFMNjNBPR1lH4CV8,
linux-usb-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA
Subject: re-submit3 [ANNOUNCEMENT] NET: usb: sierra_net.c driver
From: Elina Pasheva <epasheva-ywE8TTl5eJHWpu6QEFMNjNBPR1lH4CV8@public.gmane.org>
The following is a new Linux driver which exposes certain models of Sierra
Wireless modems to the operating system as Network Interface Cards (NICs).
This driver requires a version of the sierra.c driver which supports
blacklisting to work properly. The blacklist in sierra.c rejects the interfaces
claimed by sierra_net.c. Likewise, the sierra_net.c driver only accepts
(i.e. whitelists) the interface(s) used for USB-to-WWAN traffic.
The version of sierra.c which supports blacklisting is
available from the sierra wireless knowledge base page for older kernels. It is
also available in Linux kernel starting from version 2.6.31.
This driver works with all Sierra Wireless devices configured with PID=68A3
like USB305, USB306 provided the corresponding firmware version is I2.0
(for USB305) or M3.0 (for USB306) and later.
This driver will not work with earlier firmware versions than the ones shown
above. In this case the driver will issue an error message indicating
incompatibility and will not serve the device's USB-to-WWAN interface.
Sierra_net.c sits atop a pre-existing Linux driver called usbnet.c.
A series of hook functions are provided in sierra_net.c which are called by
usbnet.c in response to a particular condition such as receipt or transmission
of a data packet. As such, usbnet.c does most of the work of making
a modem appear to the system as a network device and for properly exchanging
traffic between the USB subsystem and the Network card interface.
Sierra_net.c is concerned with managing the data exchanged between the
USB-to-WWAN interface and the upper layers of the operating system.
The version number of sierra_net.c driver is set to 2.0.
This patch has been tested on kernel-2.6.34-rc3.
This patch has been checked against net-2.6 tree.
Signed-off-by: Elina Pasheva <epasheva-ywE8TTl5eJHWpu6QEFMNjNBPR1lH4CV8@public.gmane.org>
Signed-off-by: Rory Filer <rfiler-ywE8TTl5eJHWpu6QEFMNjNBPR1lH4CV8@public.gmane.org>
---
drivers/net/usb/Kconfig | 10
drivers/net/usb/Makefile | 2
drivers/net/usb/sierra_net.c | 970 +++++++++++++++++++++++++++++++++
3 files changed, 982 insertions(+)
--- a/drivers/net/usb/Kconfig 2010-04-01 10:10:56.000000000 -0700
+++ b/drivers/net/usb/Kconfig 2010-04-01 13:09:20.000000000 -0700
@@ -385,4 +385,14 @@ config USB_CDC_PHONET
cellular modem, as found on most Nokia handsets with the
"PC suite" USB profile.
+config USB_SIERRA_NET
+ tristate "USB-to-WWAN Driver for Sierra Wireless modems"
+ depends on USB_USBNET
+ default y
+ help
+ Choose this option if you have a Sierra Wireless USB-to-WWAN device.
+
+ To compile this driver as a module, choose M here: the
+ module will be called sierra_net.
+
endmenu
--- a/drivers/net/usb/Makefile 2010-04-01 10:10:45.000000000 -0700
+++ b/drivers/net/usb/Makefile 2010-04-01 10:12:16.000000000 -0700
@@ -23,4 +23,6 @@ obj-$(CONFIG_USB_NET_MCS7830) += mcs7830
obj-$(CONFIG_USB_USBNET) += usbnet.o
obj-$(CONFIG_USB_NET_INT51X1) += int51x1.o
obj-$(CONFIG_USB_CDC_PHONET) += cdc-phonet.o
+obj-$(CONFIG_USB_SIERRA_NET) += sierra_net.o
+
--- a/drivers/net/usb/sierra_net.c 2010-04-01 16:43:34.000000000 -0700
+++ b/drivers/net/usb/sierra_net.c 2010-04-01 17:12:59.000000000 -0700
@@ -1 +1,971 @@
+/*
+ * USB-to-WWAN Driver for Sierra Wireless modems
+ *
+ * Copyright (C) 2008, 2009, 2010 Paxton Smith, Matthew Safar, Rory Filer
+ * <linux-ywE8TTl5eJHWpu6QEFMNjNBPR1lH4CV8@public.gmane.org>
+ *
+ * Portions of this based on the cdc_ether driver by David Brownell (2003-2005)
+ * and Ole Andre Vadla Ravnas (ActiveSync) (2006).
+ *
+ * IMPORTANT DISCLAIMER: This driver is not commercially supported by
+ * Sierra Wireless. Use at your own risk.
+ *
+ * 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
+ */
+
+#define DRIVER_VERSION "v.2.0"
+#define DRIVER_AUTHOR "Paxton Smith, Matthew Safar, Rory Filer"
+#define DRIVER_DESC "USB-to-WWAN Driver for Sierra Wireless modems"
+static const char driver_name[] = "sierra_net";
+
+/* if defined debug messages enabled */
+/*#define DEBUG*/
+
+#include <linux/module.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/usb.h>
+#include <linux/usb/cdc.h>
+#include <net/ip.h>
+#include <net/udp.h>
+#include <asm/unaligned.h>
+#include <linux/usb/usbnet.h>
+
+#define SWI_USB_REQUEST_GET_FW_ATTR 0x06
+#define SWI_GET_FW_ATTR_MASK 0x08
+
+/* atomic counter partially included in MAC address to make sure 2 devices
+ * do not end up with the same MAC - concept breaks in case of > 255 ifaces
+ */
+static atomic_t iface_counter = ATOMIC_INIT(0);
+
+/*
+ * SYNC Timer Delay definition used to set the expiry time
+ */
+#define SIERRA_NET_SYNCDELAY (2*HZ)
+
+/* Max. MTU supported. The modem buffers are limited to 1500 */
+#define SIERRA_NET_MAX_SUPPORTED_MTU 1500
+
+/* The SIERRA_NET_USBCTL_BUF_LEN defines a buffer size allocated for control
+ * message reception ... and thus the max. received packet.
+ * (May be the cause for parse_hip returning -3)
+ */
+#define SIERRA_NET_USBCTL_BUF_LEN 1024
+
+/* list of interface numbers - used for constructing interface lists */
+struct sierra_net_iface_info {
+ const u32 infolen; /* number of interface numbers on list */
+ const u8 *ifaceinfo; /* pointer to the array holding the numbers */
+};
+
+struct sierra_net_info_data {
+ u16 rx_urb_size;
+ struct sierra_net_iface_info whitelist;
+};
+
+/* Private data structure */
+struct sierra_net_data {
+
+ u8 ethr_hdr_tmpl[ETH_HLEN]; /* ethernet header template for rx'd pkts */
+
+ u16 link_up; /* air link up or down */
+ u8 tx_hdr_template[4]; /* part of HIP hdr for tx'd packets */
+
+ u8 sync_msg[4]; /* SYNC message */
+ u8 shdwn_msg[4]; /* Shutdown message */
+
+ /* Backpointer to the container */
+ struct usbnet *usbnet;
+
+ u8 ifnum; /* interface number */
+
+/* Bit masks, must be a power of 2 */
+#define SIERRA_NET_EVENT_RESP_AVAIL 0x01
+#define SIERRA_NET_TIMER_EXPIRY 0x02
+ unsigned long kevent_flags;
+ struct work_struct sierra_net_kevent;
+ struct timer_list sync_timer; /* For retrying SYNC sequence */
+};
+
+struct param {
+ int is_present;
+ union {
+ void *ptr;
+ u32 dword;
+ u16 word;
+ u8 byte;
+ };
+};
+
+/* HIP message type */
+#define SIERRA_NET_HIP_EXTENDEDID 0x7F
+#define SIERRA_NET_HIP_HSYNC_ID 0x60 /* Modem -> host */
+#define SIERRA_NET_HIP_RESTART_ID 0x62 /* Modem -> host */
+#define SIERRA_NET_HIP_MSYNC_ID 0x20 /* Host -> modem */
+#define SIERRA_NET_HIP_SHUTD_ID 0x26 /* Host -> modem */
+
+#define SIERRA_NET_HIP_EXT_IP_IN_ID 0x0202
+#define SIERRA_NET_HIP_EXT_IP_OUT_ID 0x0002
+
+/* 3G UMTS Link Sense Indication definitions */
+#define SIERRA_NET_HIP_LSI_UMTSID 0x78
+
+/* Reverse Channel Grant Indication HIP message */
+#define SIERRA_NET_HIP_RCGI 0x64
+
+/* LSI Protocol types */
+#define SIERRA_NET_PROTOCOL_UMTS 0x01
+/* LSI Coverage */
+#define SIERRA_NET_COVERAGE_NONE 0x00
+#define SIERRA_NET_COVERAGE_NOPACKET 0x01
+
+/* LSI Session */
+#define SIERRA_NET_SESSION_IDLE 0x00
+/* LSI Link types */
+#define SIERRA_NET_AS_LINK_TYPE_IPv4 0x00
+
+typedef struct s_lsi_umts {
+ u8 protocol;
+ u8 unused1;
+ __be16 length;
+ /* eventually use a union for the rest - assume umts for now */
+ u8 coverage;
+ u8 unused2[41];
+ u8 session_state;
+ u8 unused3[33];
+ u8 link_type;
+ u8 pdp_addr_len; /* NW-supplied PDP address len */
+ u8 pdp_addr[16]; /* NW-supplied PDP address (bigendian)) */
+ u8 unused4[23];
+ u8 dns1_addr_len; /* NW-supplied 1st DNS address len (bigendian) */
+ u8 dns1_addr[16]; /* NW-supplied 1st DNS address */
+ u8 dns2_addr_len; /* NW-supplied 2nd DNS address len */
+ u8 dns2_addr[16]; /* NW-supplied 2nd DNS address (bigendian)*/
+ u8 wins1_addr_len; /* NW-supplied 1st Wins address len */
+ u8 wins1_addr[16]; /* NW-supplied 1st Wins address (bigendian)*/
+ u8 wins2_addr_len; /* NW-supplied 2nd Wins address len */
+ u8 wins2_addr[16]; /* NW-supplied 2nd Wins address (bigendian) */
+ u8 unused5[4];
+ u8 gw_addr_len; /* NW-supplied GW address len */
+ u8 gw_addr[16]; /* NW-supplied GW address (bigendian) */
+ u8 reserved[8];
+} __attribute__ ((packed)) lsi_umts_t;
+
+#define SIERRA_NET_LSI_COMMON_LEN 4
+#define SIERRA_NET_LSI_UMTS_LEN (sizeof(lsi_umts_t))
+#define SIERRA_NET_LSI_UMTS_STATUS_LEN \
+ (SIERRA_NET_LSI_UMTS_LEN - SIERRA_NET_LSI_COMMON_LEN)
+
+/* Forward definitions */
+extern void sierra_sync_timer(unsigned long syncdata);
+static int sierra_net_change_mtu(struct net_device *net, int new_mtu);
+
+/* Our own net device operations structure */
+static const struct net_device_ops sierra_net_device_ops = {
+ .ndo_open = usbnet_open,
+ .ndo_stop = usbnet_stop,
+ .ndo_start_xmit = usbnet_start_xmit,
+ .ndo_tx_timeout = usbnet_tx_timeout,
+ .ndo_change_mtu = sierra_net_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
+/* get private data associated with passed in usbnet device */
+static inline struct sierra_net_data *sierra_net_get_private(struct usbnet *dev)
+{
+ return (struct sierra_net_data *)dev->data[0];
+}
+
+/* set private data associated with passed in usbnet device */
+static inline void sierra_net_set_private(struct usbnet *dev,
+ struct sierra_net_data *priv)
+{
+ dev->data[0] = (unsigned long)priv;
+}
+
+/* is packet IPv4 */
+static inline int is_ip(struct sk_buff *skb)
+{
+ return (skb->protocol == cpu_to_be16(ETH_P_IP));
+}
+
+/*
+ * check passed in packet and make sure that:
+ * - it is linear (no scatter/gather)
+ * - it is ethernet (mac_header properly set)
+ */
+static int check_ethip_packet(struct sk_buff *skb, struct usbnet *dev)
+{
+ skb_reset_mac_header(skb); /* ethernet header */
+
+ if (skb_is_nonlinear(skb)) {
+ netdev_err(dev->net, "Non linear buffer-dropping");
+ return 0;
+ }
+
+ if (!pskb_may_pull(skb, ETH_HLEN))
+ return 0;
+ skb->protocol = eth_hdr(skb)->h_proto;
+
+ return 1;
+}
+
+static const u8 *save16bit(struct param *p, const u8 *datap)
+{
+ p->is_present = 1;
+ p->word = get_unaligned_be16(datap);
+ return datap + sizeof(p->word);
+}
+
+static const u8 *save8bit(struct param *p, const u8 *datap)
+{
+ p->is_present = 1;
+ p->byte = *datap;
+ return datap + sizeof(p->byte);
+}
+
+/*----------------------------------------------------------------------------*
+ * BEGIN HIP *
+ *----------------------------------------------------------------------------*/
+/* HIP header */
+#define SIERRA_NET_HIP_HDR_LEN 4
+/* Extended HIP header */
+#define SIERRA_NET_HIP_EXT_HDR_LEN 6
+
+struct hip_hdr {
+ int hdrlen;
+ struct param payload_len;
+ struct param msgid;
+ struct param msgspecific;
+ struct param extmsgid;
+};
+
+static int parse_hip(const u8 *buf, const u32 buflen, struct hip_hdr *hh)
+{
+ const u8 *curp = buf;
+ int padded;
+
+ if (buflen < SIERRA_NET_HIP_HDR_LEN)
+ return -1;
+
+ curp = save16bit(&hh->payload_len, curp);
+ curp = save8bit(&hh->msgid, curp);
+ curp = save8bit(&hh->msgspecific, curp);
+
+ padded = hh->msgid.byte & 0x80;
+ hh->msgid.byte &= 0x7F; /* 7 bits */
+
+ hh->extmsgid.is_present = (hh->msgid.byte == SIERRA_NET_HIP_EXTENDEDID);
+ if (hh->extmsgid.is_present) {
+ if (buflen < SIERRA_NET_HIP_EXT_HDR_LEN)
+ return -2;
+
+ hh->payload_len.word &= 0x3FFF; /* 14 bits */
+
+ curp = save16bit(&hh->extmsgid, curp);
+ hh->extmsgid.word &= 0x03FF; /* 10 bits */
+
+ hh->hdrlen = SIERRA_NET_HIP_EXT_HDR_LEN;
+ } else {
+ hh->payload_len.word &= 0x07FF; /* 11 bits */
+ hh->hdrlen = SIERRA_NET_HIP_HDR_LEN;
+ }
+
+ if (padded) {
+ hh->hdrlen++;
+ hh->payload_len.word--;
+ }
+
+ /* if real packet shorter than the claimed length */
+ if (buflen < (hh->hdrlen + hh->payload_len.word))
+ return -3;
+
+ return 0;
+}
+
+static void build_hip(u8 *buf, const u16 payloadlen,
+ struct sierra_net_data *priv)
+{
+ /* the following doesn't have the full functionality. We
+ * currently build only one kind of header, so it is faster this way
+ */
+ put_unaligned_be16(payloadlen, buf);
+ memcpy(buf+2, priv->tx_hdr_template, sizeof(priv->tx_hdr_template));
+}
+/*----------------------------------------------------------------------------*
+ * END HIP *
+ *----------------------------------------------------------------------------*/
+
+static void sierra_net_send_cmd(struct usbnet *dev,
+ u8 *cmd, int cmdlen, const char * cmd_name)
+{
+ struct sierra_net_data *priv = sierra_net_get_private(dev);
+ int status;
+
+ status = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
+ USB_CDC_SEND_ENCAPSULATED_COMMAND,
+ USB_DIR_OUT|USB_TYPE_CLASS|USB_RECIP_INTERFACE, 0,
+ priv->ifnum, cmd, cmdlen, 0);
+
+ if (status != cmdlen && status != -ENODEV)
+ netdev_err(dev->net, "Submit %s failed %d", cmd_name, status);
+}
+
+static void sierra_net_send_sync(struct usbnet *dev)
+{
+ struct sierra_net_data *priv = sierra_net_get_private(dev);
+
+ dev_dbg(&dev->udev->dev, "%s", __func__);
+
+ sierra_net_send_cmd(dev, priv->sync_msg,
+ sizeof(priv->sync_msg), "SYNC");
+}
+
+static void sierra_net_send_shutdown(struct usbnet *dev)
+{
+ struct sierra_net_data *priv = sierra_net_get_private(dev);
+
+ dev_dbg(&dev->udev->dev, "%s", __func__);
+
+ sierra_net_send_cmd(dev, priv->shdwn_msg,
+ sizeof(priv->shdwn_msg), "Shutdown");
+}
+
+static void sierra_net_set_ctx_index(struct sierra_net_data *priv, u8 ctx_ix)
+{
+ dev_dbg(&(priv->usbnet->udev->dev), "%s %d", __func__, ctx_ix);
+ priv->tx_hdr_template[0] = 0x3F;
+ priv->tx_hdr_template[1] = ctx_ix;
+ *((u16 *)&priv->tx_hdr_template[2]) =
+ cpu_to_be16(SIERRA_NET_HIP_EXT_IP_OUT_ID);
+}
+
+static inline int sierra_net_is_valid_addrlen(u8 len)
+{
+ return (len == sizeof(struct in_addr));
+}
+
+static int sierra_net_parse_lsi(struct usbnet *dev, char *data, int datalen)
+{
+ lsi_umts_t *lsi = (lsi_umts_t *)data;
+
+ if (lsi->length != cpu_to_be16(SIERRA_NET_LSI_UMTS_STATUS_LEN)) {
+ netdev_err(dev->net, "%s: LSI_UMTS_STATUS_LEN %d, expected %u",
+ __func__, be16_to_cpu(lsi->length),
+ (u32)SIERRA_NET_LSI_UMTS_STATUS_LEN);
+ return -1;
+ }
+
+ /* Validate the protocol - only support UMTS for now */
+ if (lsi->protocol != SIERRA_NET_PROTOCOL_UMTS) {
+ netdev_err(dev->net, "Protocol unsupported, 0x%02x",
+ lsi->protocol);
+ return -1;
+ }
+
+ /* Validate the link type */
+ if (lsi->link_type != SIERRA_NET_AS_LINK_TYPE_IPv4) {
+ netdev_err(dev->net, "Link type unsupported: 0x%02x",
+ lsi->link_type);
+ return -1;
+ }
+
+ /* Validate the coverage */
+ if (lsi->coverage == SIERRA_NET_COVERAGE_NONE
+ || lsi->coverage == SIERRA_NET_COVERAGE_NOPACKET) {
+ netdev_err(dev->net, "No coverage, 0x%02x", lsi->coverage);
+ return 0;
+ }
+
+ /* Validate the session state */
+ if (lsi->session_state == SIERRA_NET_SESSION_IDLE) {
+ netdev_err(dev->net, "Session idle, 0x%02x",
+ lsi->session_state);
+ return 0;
+ }
+
+ /* Set link_sense true */
+ return 1;
+}
+
+static void sierra_net_handle_lsi(struct usbnet *dev, char *data,
+ struct hip_hdr *hh)
+{
+ struct sierra_net_data *priv = sierra_net_get_private(dev);
+ int link_up;
+
+ link_up = sierra_net_parse_lsi(dev, data + hh->hdrlen,
+ hh->payload_len.word);
+ if (link_up < 0) {
+ netdev_err(dev->net, "Invalid LSI");
+ return;
+ }
+ if (link_up) {
+ sierra_net_set_ctx_index(priv, hh->msgspecific.byte);
+ priv->link_up = 1;
+ netif_carrier_on(dev->net);
+ } else {
+ priv->link_up = 0;
+ netif_carrier_off(dev->net);
+ }
+}
+
+static void sierra_net_dosync(struct usbnet *dev)
+{
+ struct sierra_net_data *priv = sierra_net_get_private(dev);
+
+ dev_dbg(&dev->udev->dev, "%s", __func__);
+
+ /* tell modem we are ready */
+ sierra_net_send_sync(dev);
+ sierra_net_send_sync(dev);
+
+ /* Now, start a timer and make sure we get the Restart Indication */
+ priv->sync_timer.function = sierra_sync_timer;
+ priv->sync_timer.data = (unsigned long) dev;
+ priv->sync_timer.expires = jiffies + SIERRA_NET_SYNCDELAY;
+ add_timer(&priv->sync_timer);
+}
+
+static void sierra_net_kevent(struct work_struct *work)
+{
+ struct sierra_net_data *priv =
+ container_of(work, struct sierra_net_data, sierra_net_kevent);
+ struct usbnet *dev = priv->usbnet;
+ int len;
+ int err;
+ u8 *buf;
+ u8 ifnum;
+
+ if (test_bit(SIERRA_NET_EVENT_RESP_AVAIL, &priv->kevent_flags)) {
+ clear_bit(SIERRA_NET_EVENT_RESP_AVAIL, &priv->kevent_flags);
+
+ /* Query the modem for the LSI message */
+ buf = kzalloc(SIERRA_NET_USBCTL_BUF_LEN, GFP_KERNEL);
+ if (!buf) {
+ netdev_err(dev->net,
+ "failed to allocate buf for LS msg");
+ return;
+ }
+ ifnum = priv->ifnum;
+ len = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
+ USB_CDC_GET_ENCAPSULATED_RESPONSE,
+ USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE,
+ 0, ifnum, buf, SIERRA_NET_USBCTL_BUF_LEN, 0);
+
+ if (unlikely(len < 0)) {
+ netdev_err(dev->net,
+ "usb_control_msg failed, status %d", len);
+ } else {
+ struct hip_hdr hh;
+
+ dev_dbg(&dev->udev->dev, "%s: Received status message,"
+ " %04x bytes", __func__, len);
+
+ err = parse_hip(buf, len, &hh);
+ if (err) {
+ netdev_err(dev->net, "%s: Bad packet,"
+ " parse result %d", __func__, err);
+ kfree(buf);
+ return;
+ }
+
+ /* Validate packet length */
+ if (len != hh.hdrlen + hh.payload_len.word) {
+ netdev_err(dev->net, "%s: Bad packet, received"
+ " %d, expected %d", __func__, len,
+ hh.hdrlen + hh.payload_len.word);
+ kfree(buf);
+ return;
+ }
+
+ /* Switch on received message types */
+ switch (hh.msgid.byte) {
+ case SIERRA_NET_HIP_LSI_UMTSID:
+ dev_dbg(&dev->udev->dev, "LSI for ctx:%d",
+ hh.msgspecific.byte);
+ sierra_net_handle_lsi(dev, buf, &hh);
+ break;
+ case SIERRA_NET_HIP_RESTART_ID:
+ dev_dbg(&dev->udev->dev, "Restart reported: %d,"
+ " stopping sync timer",
+ hh.msgspecific.byte);
+ /* Got sync resp - stop timer & clear mask */
+ del_timer_sync(&priv->sync_timer);
+ clear_bit(SIERRA_NET_TIMER_EXPIRY,
+ &priv->kevent_flags);
+ break;
+ case SIERRA_NET_HIP_HSYNC_ID:
+ dev_dbg(&dev->udev->dev, "SYNC received");
+ sierra_net_send_sync(dev);
+ break;
+ case SIERRA_NET_HIP_EXTENDEDID:
+ netdev_err(dev->net, "Unrecognized HIP msg, "
+ "extmsgid 0x%04x", hh.extmsgid.word);
+ break;
+ case SIERRA_NET_HIP_RCGI:
+ /* Ignored */
+ break;
+ default:
+ netdev_err(dev->net, "Unrecognized HIP msg, "
+ "msgid 0x%02x", hh.msgid.byte);
+ break;
+ }
+ }
+ kfree(buf);
+ }
+ /* The sync timer bit might be set */
+ if (test_bit(SIERRA_NET_TIMER_EXPIRY, &priv->kevent_flags)) {
+ clear_bit(SIERRA_NET_TIMER_EXPIRY, &priv->kevent_flags);
+ dev_dbg(&dev->udev->dev, "Deferred sync timer expiry");
+ sierra_net_dosync(priv->usbnet);
+ }
+
+ if (priv->kevent_flags)
+ dev_dbg(&dev->udev->dev, "sierra_net_kevent done, "
+ "kevent_flags = 0x%lx", priv->kevent_flags);
+}
+
+static void sierra_net_defer_kevent(struct usbnet *dev, int work)
+{
+ struct sierra_net_data *priv = sierra_net_get_private(dev);
+
+ set_bit(work, &priv->kevent_flags);
+ schedule_work(&priv->sierra_net_kevent);
+}
+
+/*
+ * Sync Retransmit Timer Handler. On expiry, kick the work queue
+ */
+void sierra_sync_timer(unsigned long syncdata)
+{
+ struct usbnet *dev = (struct usbnet *)syncdata;
+
+ dev_dbg(&dev->udev->dev, "%s", __func__);
+ /* Kick the tasklet */
+ sierra_net_defer_kevent(dev, SIERRA_NET_TIMER_EXPIRY);
+}
+
+static void sierra_net_status(struct usbnet *dev, struct urb *urb)
+{
+ struct usb_cdc_notification *event;
+
+ dev_dbg(&dev->udev->dev, "%s", __func__);
+
+ if (urb->actual_length < sizeof *event)
+ return;
+
+ /* Add cases to handle other standard notifications. */
+ event = urb->transfer_buffer;
+ switch (event->bNotificationType) {
+ case USB_CDC_NOTIFY_NETWORK_CONNECTION:
+ case USB_CDC_NOTIFY_SPEED_CHANGE:
+ /* USB 305 sends those */
+ break;
+ case USB_CDC_NOTIFY_RESPONSE_AVAILABLE:
+ sierra_net_defer_kevent(dev, SIERRA_NET_EVENT_RESP_AVAIL);
+ break;
+ default:
+ netdev_err(dev->net, ": unexpected notification %02x!",
+ event->bNotificationType);
+ break;
+ }
+}
+
+static void sierra_net_get_drvinfo(struct net_device *net,
+ struct ethtool_drvinfo *info)
+{
+ /* Inherit standard device info */
+ usbnet_get_drvinfo(net, info);
+ strncpy(info->driver, driver_name, sizeof info->driver);
+ strncpy(info->version, DRIVER_VERSION, sizeof info->version);
+}
+
+static u32 sierra_net_get_link(struct net_device *net)
+{
+ struct usbnet *dev = netdev_priv(net);
+ /* Report link is down whenever the interface is down */
+ return sierra_net_get_private(dev)->link_up && netif_running(net);
+}
+
+static struct ethtool_ops sierra_net_ethtool_ops = {
+ .get_drvinfo = sierra_net_get_drvinfo,
+ .get_link = sierra_net_get_link,
+ .get_msglevel = usbnet_get_msglevel,
+ .set_msglevel = usbnet_set_msglevel,
+ .get_settings = usbnet_get_settings,
+ .set_settings = usbnet_set_settings,
+ .nway_reset = usbnet_nway_reset,
+};
+
+/* MTU can not be more than 1500 bytes, enforce it. */
+static int sierra_net_change_mtu(struct net_device *net, int new_mtu)
+{
+ if (new_mtu > SIERRA_NET_MAX_SUPPORTED_MTU)
+ return -EINVAL;
+
+ return usbnet_change_mtu(net, new_mtu);
+}
+
+static int is_whitelisted(const u8 ifnum,
+ const struct sierra_net_iface_info *whitelist)
+{
+ if (whitelist) {
+ const u8 *list = whitelist->ifaceinfo;
+ int i;
+
+ for (i = 0; i < whitelist->infolen; i++) {
+ if (list[i] == ifnum)
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap)
+{
+ int result = 0;
+ u16 *attrdata;
+
+ attrdata = kmalloc(sizeof(*attrdata), GFP_KERNEL);
+ if (!attrdata)
+ return -ENOMEM;
+
+ result = usb_control_msg(
+ dev->udev,
+ usb_rcvctrlpipe(dev->udev, 0),
+ /* _u8 vendor specific request */
+ SWI_USB_REQUEST_GET_FW_ATTR,
+ USB_DIR_IN | USB_TYPE_VENDOR, /* __u8 request type */
+ 0x0000, /* __u16 value not used */
+ 0x0000, /* __u16 index not used */
+ attrdata, /* char *data */
+ sizeof(*attrdata), /* __u16 size */
+ USB_CTRL_SET_TIMEOUT); /* int timeout */
+
+ if (result < 0) {
+ kfree(attrdata);
+ return -EIO;
+ }
+
+ *datap = *attrdata;
+
+ kfree(attrdata);
+ return result;
+}
+
+/*
+ * collects the bulk endpoints, the status endpoint.
+ */
+static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+ u8 ifacenum;
+ u8 numendpoints;
+ u16 fwattr = 0;
+ int status;
+ struct ethhdr *eth;
+ struct sierra_net_data *priv;
+ static const u8 sync_tmplate[sizeof(priv->sync_msg)] = {
+ 0x00, 0x00, SIERRA_NET_HIP_MSYNC_ID, 0x00};
+ static const u8 shdwn_tmplate[sizeof(priv->shdwn_msg)] = {
+ 0x00, 0x00, SIERRA_NET_HIP_SHUTD_ID, 0x00};
+
+ struct sierra_net_info_data *data =
+ (struct sierra_net_info_data *)dev->driver_info->data;
+
+ dev_dbg(&dev->udev->dev, "%s", __func__);
+
+ ifacenum = intf->cur_altsetting->desc.bInterfaceNumber;
+ /* We only accept certain interfaces */
+ if (!is_whitelisted(ifacenum, &data->whitelist)) {
+ dev_dbg(&dev->udev->dev, "Ignoring interface: %d", ifacenum);
+ return -ENODEV;
+ }
+ numendpoints = intf->cur_altsetting->desc.bNumEndpoints;
+ /* We have three endpoints, bulk in and out, and a status */
+ if (numendpoints != 3) {
+ dev_err(&dev->udev->dev, "Expected 3 endpoints, found: %d",
+ numendpoints);
+ return -ENODEV;
+ }
+ /* Status endpoint set in usbnet_get_endpoints() */
+ dev->status = NULL;
+ status = usbnet_get_endpoints(dev, intf);
+ if (status < 0) {
+ dev_err(&dev->udev->dev, "Error in usbnet_get_endpoints (%d)",
+ status);
+ return -ENODEV;
+ }
+ /* Initialize sierra private data */
+ priv = kzalloc(sizeof *priv, GFP_KERNEL);
+ if (!priv) {
+ dev_err(&dev->udev->dev, "No memory");
+ return -ENOMEM;
+ }
+
+ priv->usbnet = dev;
+ priv->ifnum = ifacenum;
+ dev->net->netdev_ops = &sierra_net_device_ops;
+
+ /* change MAC addr to include, ifacenum, and to be unique */
+ dev->net->dev_addr[ETH_ALEN-2] = atomic_inc_return(&iface_counter);
+ dev->net->dev_addr[ETH_ALEN-1] = ifacenum;
+
+ /* we will have to manufacture ethernet headers, prepare template */
+ eth = (struct ethhdr *)priv->ethr_hdr_tmpl;
+ memcpy(ð->h_dest, dev->net->dev_addr, ETH_ALEN);
+ eth->h_proto = cpu_to_be16(ETH_P_IP);
+
+ /* prepare shutdown message template */
+ memcpy(priv->shdwn_msg, shdwn_tmplate, sizeof(priv->shdwn_msg));
+ /* set context index initially to 0 - prepares tx hdr template */
+ sierra_net_set_ctx_index(priv, 0);
+
+ /* decrease the rx_urb_size and max_tx_size to 4k on USB 1.1 */
+ dev->rx_urb_size = data->rx_urb_size;
+ if (dev->udev->speed != USB_SPEED_HIGH)
+ dev->rx_urb_size = min_t(size_t, 4096, data->rx_urb_size);
+
+ dev->net->hard_header_len += SIERRA_NET_HIP_EXT_HDR_LEN;
+ dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
+
+ /* Set up the netdev */
+ dev->net->flags |= IFF_NOARP;
+ dev->net->ethtool_ops = &sierra_net_ethtool_ops;
+ netif_carrier_off(dev->net);
+
+ sierra_net_set_private(dev, priv);
+
+ priv->kevent_flags = 0;
+
+ /* Use the shared workqueue */
+ INIT_WORK(&priv->sierra_net_kevent, sierra_net_kevent);
+
+ /* Only need to do this once */
+ init_timer(&priv->sync_timer);
+
+ /* verify fw attributes */
+ status = sierra_net_get_fw_attr(dev, &fwattr);
+ dev_dbg(&dev->udev->dev, "Fw attr: %x\n", fwattr);
+
+ /* test whether firmware supports DHCP */
+ if (!(status == sizeof(fwattr) && (fwattr & SWI_GET_FW_ATTR_MASK))) {
+ /* found incompatible firmware version */
+ dev_err(&dev->udev->dev, "Incompatible driver and firmware"
+ " versions\n");
+ kfree(priv);
+ return -ENODEV;
+ }
+ /* prepare sync message from template */
+ memcpy(priv->sync_msg, sync_tmplate, sizeof(priv->sync_msg));
+
+ /* initiate the sync sequence */
+ sierra_net_dosync(dev);
+
+ return 0;
+}
+
+static void sierra_net_unbind(struct usbnet *dev, struct usb_interface *intf)
+{
+ struct sierra_net_data *priv = sierra_net_get_private(dev);
+
+ dev_dbg(&dev->udev->dev, "%s", __func__);
+
+ /* Kill the timer then flush the work queue */
+ del_timer_sync(&priv->sync_timer);
+
+ flush_scheduled_work();
+
+ /* tell modem we are going away */
+ sierra_net_send_shutdown(dev);
+
+ sierra_net_set_private(dev, NULL);
+
+ kfree(priv);
+}
+
+static struct sk_buff *sierra_net_skb_clone(struct usbnet *dev,
+ struct sk_buff *skb, int len)
+{
+ struct sk_buff *new_skb;
+
+ /* clone skb */
+ new_skb = skb_clone(skb, GFP_ATOMIC);
+
+ /* remove len bytes from original */
+ skb_pull(skb, len);
+
+ /* trim next packet to it's length */
+ if (new_skb) {
+ skb_trim(new_skb, len);
+ } else {
+ if (netif_msg_rx_err(dev))
+ netdev_err(dev->net, "failed to get skb");
+ dev->net->stats.rx_dropped++;
+ }
+
+ return new_skb;
+}
+
+/* ---------------------------- Receive data path ----------------------*/
+static int sierra_net_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+ int err;
+ struct hip_hdr hh;
+ struct sk_buff *new_skb;
+
+ dev_dbg(&dev->udev->dev, "%s", __func__);
+
+ /* could contain multiple packets */
+ while (likely(skb->len)) {
+ err = parse_hip(skb->data, skb->len, &hh);
+ if (err) {
+ if (netif_msg_rx_err(dev))
+ netdev_err(dev->net, "Invalid HIP header %d",
+ err);
+ /* dev->net->stats.rx_errors incremented by caller */
+ dev->net->stats.rx_length_errors++;
+ return 0;
+ }
+
+ /* Validate Extended HIP header */
+ if (!hh.extmsgid.is_present
+ || hh.extmsgid.word != SIERRA_NET_HIP_EXT_IP_IN_ID) {
+ if (netif_msg_rx_err(dev))
+ netdev_err(dev->net, "HIP/ETH: Invalid packet");
+
+ dev->net->stats.rx_frame_errors++;
+ /* dev->net->stats.rx_errors incremented by caller */;
+ return 0;
+ }
+
+ skb_pull(skb, hh.hdrlen);
+
+ /* We are going to accept this packet, prepare it */
+ memcpy(skb->data, sierra_net_get_private(dev)->ethr_hdr_tmpl,
+ ETH_HLEN);
+
+ /* Last packet in batch handled by usbnet */
+ if (hh.payload_len.word == skb->len)
+ return 1;
+
+ new_skb = sierra_net_skb_clone(dev, skb, hh.payload_len.word);
+ if (new_skb)
+ usbnet_skb_return(dev, new_skb);
+
+ } /* while */
+
+ return 0;
+}
+
+/* ---------------------------- Transmit data path ----------------------*/
+struct sk_buff *sierra_net_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
+ gfp_t flags)
+{
+ struct sierra_net_data *priv = sierra_net_get_private(dev);
+ u16 len;
+
+ dev_dbg(&dev->udev->dev, "%s", __func__);
+ if (priv->link_up && check_ethip_packet(skb, dev) && is_ip(skb)) {
+ /* enough head room as is? */
+ if (SIERRA_NET_HIP_EXT_HDR_LEN <= skb_headroom(skb)) {
+ /* Save the Eth/IP length and set up HIP hdr */
+ len = skb->len;
+ skb_push(skb, SIERRA_NET_HIP_EXT_HDR_LEN);
+ build_hip(skb->data, len, priv);
+ return skb;
+ } else {
+ /*
+ * compensate in the future if necessary
+ */
+ netdev_err(dev->net, "tx_fixup: no room for HIP");
+ } /* headroom */
+ }
+
+ if (!priv->link_up)
+ dev->net->stats.tx_carrier_errors++;
+
+ /* tx_dropped incremented by usbnet */
+
+ /* filter the packet out, release it */
+ dev_kfree_skb_any(skb);
+ return NULL;
+}
+
+static const u8 sierra_net_ifnum_list[] = { 7, 10, 11 };
+static const struct sierra_net_info_data sierra_net_info_data_68A3 = {
+ .rx_urb_size = 8 * 1024,
+ .whitelist = {
+ .infolen = ARRAY_SIZE(sierra_net_ifnum_list),
+ .ifaceinfo = sierra_net_ifnum_list
+ }
+};
+
+static const struct driver_info sierra_net_info_68A3 = {
+ .description = "Sierra Wireless USB-to-WWAN Modem",
+ .flags = FLAG_WWAN | FLAG_SEND_ZLP,
+ .bind = sierra_net_bind,
+ .unbind = sierra_net_unbind,
+ .status = sierra_net_status,
+ .rx_fixup = sierra_net_rx_fixup,
+ .tx_fixup = sierra_net_tx_fixup,
+ .data = (unsigned long)&sierra_net_info_data_68A3,
+};
+
+static const struct usb_device_id products[] = {
+ {USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless USB-to-WWAN modem */
+ .driver_info = (unsigned long) &sierra_net_info_68A3},
+
+ {}, /* last item */
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+/* We are based on usbnet, so let it handle the USB driver specifics */
+static struct usb_driver sierra_net_driver = {
+ .name = "sierra_net",
+ .id_table = products,
+ .probe = usbnet_probe,
+ .disconnect = usbnet_disconnect,
+ .suspend = usbnet_suspend,
+ .resume = usbnet_resume,
+ .no_dynamic_id = 1,
+};
+
+static int __init sierra_net_init(void)
+{
+ BUILD_BUG_ON(FIELD_SIZEOF(struct usbnet, data)
+ < sizeof(struct cdc_state));
+
+ return usb_register(&sierra_net_driver);
+}
+
+static void __exit sierra_net_exit(void)
+{
+ usb_deregister(&sierra_net_driver);
+}
+
+module_exit(sierra_net_exit);
+module_init(sierra_net_init);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL");
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH] cnic: Fix crash during bnx2x MTU change.
From: Michael Chan @ 2010-04-06 1:44 UTC (permalink / raw)
To: davem; +Cc: netdev
cnic_service_bnx2x() irq handler can be called during chip reset from
MTU change. Need to check that the cnic's device state is up before
handling the irq.
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/cnic.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index 9781942..4b451a7 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -2334,13 +2334,13 @@ static int cnic_service_bnx2x(void *data, void *status_blk)
struct cnic_local *cp = dev->cnic_priv;
u16 prod = cp->kcq_prod_idx & MAX_KCQ_IDX;
- prefetch(cp->status_blk.bnx2x);
- prefetch(&cp->kcq[KCQ_PG(prod)][KCQ_IDX(prod)]);
+ if (likely(test_bit(CNIC_F_CNIC_UP, &dev->flags))) {
+ prefetch(cp->status_blk.bnx2x);
+ prefetch(&cp->kcq[KCQ_PG(prod)][KCQ_IDX(prod)]);
- if (likely(test_bit(CNIC_F_CNIC_UP, &dev->flags)))
tasklet_schedule(&cp->cnic_irq_task);
-
- cnic_chk_pkt_rings(cp);
+ cnic_chk_pkt_rings(cp);
+ }
return 0;
}
--
1.6.4.GIT
^ permalink raw reply related
* [PATCH 2/2] TIPC: Minor change to comment field in API
From: Jon Maloy @ 2010-04-06 1:16 UTC (permalink / raw)
To: David Miller; +Cc: Maloy, netdev, tipc-discussion, Jon
In-Reply-To: <../outgoing_patches/>
---
include/linux/tipc.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/include/linux/tipc.h b/include/linux/tipc.h
index 9536d8a..ab2e551 100644
--- a/include/linux/tipc.h
+++ b/include/linux/tipc.h
@@ -86,7 +86,7 @@ static inline unsigned int tipc_node(__u32 addr)
*/
#define TIPC_CFG_SRV 0 /* configuration service name type */
-#define TIPC_TOP_SRV 1 /* topology service name type */
+#define TIPC_TOP_SRV 1 /* topology service name type and instance*/
#define TIPC_RESERVED_TYPES 64 /* lowest user-publishable name type */
/*
--
1.5.4.3
------------------------------------------------------------------------------
Download Intel® Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
^ permalink raw reply related
* [PATCH 1/2] TIPC: Updated topology subscription protocol according to latest spec
From: Jon Maloy @ 2010-04-06 1:16 UTC (permalink / raw)
To: David Miller; +Cc: Maloy, netdev, tipc-discussion, Jon
In-Reply-To: <../outgoing_patches/>
---
include/linux/tipc.h | 30 ++++++++++++------------------
net/tipc/core.c | 2 +-
net/tipc/subscr.c | 15 ++++++++++-----
3 files changed, 23 insertions(+), 24 deletions(-)
diff --git a/include/linux/tipc.h b/include/linux/tipc.h
index 3d92396..9536d8a 100644
--- a/include/linux/tipc.h
+++ b/include/linux/tipc.h
@@ -127,23 +127,17 @@ static inline unsigned int tipc_node(__u32 addr)
* TIPC topology subscription service definitions
*/
-#define TIPC_SUB_PORTS 0x01 /* filter for port availability */
-#define TIPC_SUB_SERVICE 0x02 /* filter for service availability */
-#define TIPC_SUB_CANCEL 0x04 /* cancel a subscription */
-#if 0
-/* The following filter options are not currently implemented */
-#define TIPC_SUB_NO_BIND_EVTS 0x04 /* filter out "publish" events */
-#define TIPC_SUB_NO_UNBIND_EVTS 0x08 /* filter out "withdraw" events */
-#define TIPC_SUB_SINGLE_EVT 0x10 /* expire after first event */
-#endif
+#define TIPC_SUB_SERVICE 0x00 /* Filter for service availability */
+#define TIPC_SUB_PORTS 0x01 /* Filter for port availability */
+#define TIPC_SUB_CANCEL 0x04 /* Cancel a subscription */
#define TIPC_WAIT_FOREVER ~0 /* timeout for permanent subscription */
struct tipc_subscr {
- struct tipc_name_seq seq; /* name sequence of interest */
- __u32 timeout; /* subscription duration (in ms) */
- __u32 filter; /* bitmask of filter options */
- char usr_handle[8]; /* available for subscriber use */
+ struct tipc_name_seq seq; /* NBO. Name sequence of interest */
+ __u32 timeout; /* NBO. Subscription duration (in ms) */
+ __u32 filter; /* NBO. Bitmask of filter options */
+ char usr_handle[8]; /* Opaque. Available for subscriber use */
};
#define TIPC_PUBLISHED 1 /* publication event */
@@ -151,11 +145,11 @@ struct tipc_subscr {
#define TIPC_SUBSCR_TIMEOUT 3 /* subscription timeout event */
struct tipc_event {
- __u32 event; /* event type */
- __u32 found_lower; /* matching name seq instances */
- __u32 found_upper; /* " " " " */
- struct tipc_portid port; /* associated port */
- struct tipc_subscr s; /* associated subscription */
+ __u32 event; /* NBO. Event type, as defined above */
+ __u32 found_lower; /* NBO. Matching name seq instances */
+ __u32 found_upper; /* " " " " " */
+ struct tipc_portid port; /* NBO. Associated port */
+ struct tipc_subscr s; /* Original, associated subscription */
};
/*
diff --git a/net/tipc/core.c b/net/tipc/core.c
index 52c571f..4e84c84 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -49,7 +49,7 @@
#include "config.h"
-#define TIPC_MOD_VER "1.6.4"
+#define TIPC_MOD_VER "2.0.0"
#ifndef CONFIG_TIPC_ZONES
#define CONFIG_TIPC_ZONES 3
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index ff123e5..ab6eab4 100644
--- a/net/tipc/subscr.c
+++ b/net/tipc/subscr.c
@@ -274,7 +274,7 @@ static void subscr_cancel(struct tipc_subscr *s,
{
struct subscription *sub;
struct subscription *sub_temp;
- __u32 type, lower, upper;
+ __u32 type, lower, upper, timeout, filter;
int found = 0;
/* Find first matching subscription, exit if not found */
@@ -282,12 +282,18 @@ static void subscr_cancel(struct tipc_subscr *s,
type = ntohl(s->seq.type);
lower = ntohl(s->seq.lower);
upper = ntohl(s->seq.upper);
+ timeout = ntohl(s->timeout);
+ filter = ntohl(s->filter) & ~TIPC_SUB_CANCEL;
list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list,
subscription_list) {
if ((type == sub->seq.type) &&
(lower == sub->seq.lower) &&
- (upper == sub->seq.upper)) {
+ (upper == sub->seq.upper) &&
+ (timeout == sub->timeout) &&
+ (filter == sub->filter) &&
+ !memcmp(s->usr_handle,sub->evt.s.usr_handle,
+ sizeof(s->usr_handle)) ){
found = 1;
break;
}
@@ -304,7 +310,7 @@ static void subscr_cancel(struct tipc_subscr *s,
k_term_timer(&sub->timer);
spin_lock_bh(subscriber->lock);
}
- dbg("Cancel: removing sub %u,%u,%u from subscriber %x list\n",
+ dbg("Cancel: removing sub %u,%u,%u from subscriber %p list\n",
sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber);
subscr_del(sub);
}
@@ -352,8 +358,7 @@ static struct subscription *subscr_subscribe(struct tipc_subscr *s,
sub->seq.upper = ntohl(s->seq.upper);
sub->timeout = ntohl(s->timeout);
sub->filter = ntohl(s->filter);
- if ((!(sub->filter & TIPC_SUB_PORTS) ==
- !(sub->filter & TIPC_SUB_SERVICE)) ||
+ if ((sub->filter && (sub->filter != TIPC_SUB_PORTS)) ||
(sub->seq.lower > sub->seq.upper)) {
warn("Subscription rejected, illegal request\n");
kfree(sub);
--
1.5.4.3
------------------------------------------------------------------------------
Download Intel® Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
^ permalink raw reply related
* Re: [RFC PATCH 1/2] netdev: buffer infrastructure to log network driver's information
From: Neil Horman @ 2010-04-06 0:10 UTC (permalink / raw)
To: David Miller
Cc: eric.dumazet, sanagi.koki, netdev, izumi.taku, kaneshige.kenji,
jeffrey.t.kirsher, jesse.brandeburg, bruce.w.allan,
alexander.h.duyck, peter.p.waskiewicz.jr, john.ronciak
In-Reply-To: <20100405.123155.263974951.davem@davemloft.net>
On Mon, Apr 05, 2010 at 12:31:55PM -0700, David Miller wrote:
> From: Eric Dumazet <eric.dumazet@gmail.com>
> Date: Mon, 05 Apr 2010 10:42:26 +0200
>
> > Le lundi 05 avril 2010 à 15:52 +0900, Koki Sanagi a écrit :
> >> This patch implements buffer infrastructure under driver/net.
> >> This buffer records information from network driver.
> >>
> >> Signed-off-by: Koki Sanagi <sanagi.koki@jp.fujitsu.com>
> >> ---
> >> drivers/net/Kconfig | 8 +
> >> drivers/net/Makefile | 1 +
> >> drivers/net/ndrvbuf.c | 535 +++++++++++++++++++++++++++++++++++++++++++++++
> >> include/linux/ndrvbuf.h | 57 +++++
> >> 4 files changed, 601 insertions(+), 0 deletions(-)
> >>
> >
> > Wow, 600 lines... thats what I call bloat...
>
> And we have all sorts of facilities for creating filesystem
> streams and ring buffers of debug information.
>
> You could even hook into 'perf' to log and process these
> events in probably like 12 lines of code.
>
I'm still having a hard time understanding why this approach is preferable to
the previous approach you took using tracepoints. Granted you can't get driver
internal state as easily, but its generic and doesn't do...this.
Neil
^ permalink raw reply
* Re: [PATCH] [V3] Add non-Virtex5 support for LL TEMAC driver
From: Grant Likely @ 2010-04-06 0:08 UTC (permalink / raw)
To: John Linn
Cc: netdev, linuxppc-dev, jwboyer, john.williams, michal.simek,
John Tyner, David Miller
In-Reply-To: <d9134316-bd07-46a8-91d4-c30f27baeb60@SG2EHSMHS007.ehs.local>
On Mon, Apr 5, 2010 at 3:11 PM, John Linn <john.linn@xilinx.com> wrote:
> This patch adds support for using the LL TEMAC Ethernet driver on
> non-Virtex 5 platforms by adding support for accessing the Soft DMA
> registers as if they were memory mapped instead of solely through the
> DCR's (available on the Virtex 5).
>
> The patch also updates the driver so that it runs on the MicroBlaze.
> The changes were tested on the PowerPC 440, PowerPC 405, and the
> MicroBlaze platforms.
>
> Signed-off-by: John Tyner <jtyner@cs.ucr.edu>
> Signed-off-by: John Linn <john.linn@xilinx.com>
>
> ---
>
> V2 - Incorporated comments from Grant and added more logic to allow the driver
> to work on MicroBlaze.
>
> V3 - Only updated it to apply to head, minor change to include slab.h. Also
> verified that it now builds for MicroBlaze. Retested on PowerPC and MicroBlaze.
> ---
> drivers/net/Kconfig | 1 -
> drivers/net/ll_temac.h | 17 +++++-
> drivers/net/ll_temac_main.c | 124 ++++++++++++++++++++++++++++++++++---------
> 3 files changed, 113 insertions(+), 29 deletions(-)
>
> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
> index 0ba5b8e..17044dc 100644
> --- a/drivers/net/Kconfig
> +++ b/drivers/net/Kconfig
> @@ -2435,7 +2435,6 @@ config MV643XX_ETH
> config XILINX_LL_TEMAC
> tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver"
> select PHYLIB
> - depends on PPC_DCR_NATIVE
> help
> This driver supports the Xilinx 10/100/1000 LocalLink TEMAC
> core used in Xilinx Spartan and Virtex FPGAs
This still at the very least needs to depend on CONFIG_OF. Otherwise
allmodconfig and allyesconfig on x86 and others will break. The
driver also doesn't build on sparc, so you'll need to either exclude
CONFIG_SPARC or depend on (PPC || MICROBLAZE) too.
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* Re: net-next: 2.6.34-rc1 regression: panic when running diagnostic on interface with IPv6
From: David Miller @ 2010-04-05 23:53 UTC (permalink / raw)
To: emil.s.tantilov; +Cc: shemminger, netdev
In-Reply-To: <EA929A9653AAE14F841771FB1DE5A1365FE4E2E334@rrsmsx501.amr.corp.intel.com>
From: "Tantilov, Emil S" <emil.s.tantilov@intel.com>
Date: Mon, 5 Apr 2010 17:50:38 -0600
> David Miller wrote:
>> From: "Tantilov, Emil S" <emil.s.tantilov@intel.com>
>> Date: Mon, 5 Apr 2010 17:03:56 -0600
>>
>>> David Miller wrote:
>>>> From: "Tantilov, Emil S" <emil.s.tantilov@intel.com>
>>>> Date: Tue, 23 Mar 2010 12:28:08 -0600
>>>>
>>>>> Bisecting points to this patch:
>>>>> http://git.kernel.org/?p=linux/kernel/git/davem/net-next-2.6.git;a=commitdiff;h=84e8b803f1e16f3a2b8b80f80a63fa2f2f8a9be6
>>>>>
>>>>> And I confirmed that the issue goes away after reverting it.
>>>>>
>>>>> Steps to reproduce:
>>>>> 1. Load the driver and configure IPv6 address.
>>>>> 2. Run ethtool diag:
>>>>> ethtool -t eth0
>>>>>
>>>>> 3. If this doesn't brake it try again, or just do ifdown/up. Other
>>>>> operations on the interface will eventually panic the system:
>>>>
>>>> Stephen please fix this, thanks.
>>>
>>> Just FYI - I still see this issue with latest pull from net-2.6.
>>
>> It's net-next-2.6 that introduced the problem and has the follow-on
>> fixes, not net-2.6
>
> Same in net-next:
Ok, Stephen please look into this, we've had this regression
for almost two weeks now.
^ permalink raw reply
* RE: net-next: 2.6.34-rc1 regression: panic when running diagnostic on interface with IPv6
From: Tantilov, Emil S @ 2010-04-05 23:50 UTC (permalink / raw)
To: David Miller; +Cc: shemminger@vyatta.com, netdev@vger.kernel.org
In-Reply-To: <20100405.161221.159637463.davem@davemloft.net>
David Miller wrote:
> From: "Tantilov, Emil S" <emil.s.tantilov@intel.com>
> Date: Mon, 5 Apr 2010 17:03:56 -0600
>
>> David Miller wrote:
>>> From: "Tantilov, Emil S" <emil.s.tantilov@intel.com>
>>> Date: Tue, 23 Mar 2010 12:28:08 -0600
>>>
>>>> Bisecting points to this patch:
>>>> http://git.kernel.org/?p=linux/kernel/git/davem/net-next-2.6.git;a=commitdiff;h=84e8b803f1e16f3a2b8b80f80a63fa2f2f8a9be6
>>>>
>>>> And I confirmed that the issue goes away after reverting it.
>>>>
>>>> Steps to reproduce:
>>>> 1. Load the driver and configure IPv6 address.
>>>> 2. Run ethtool diag:
>>>> ethtool -t eth0
>>>>
>>>> 3. If this doesn't brake it try again, or just do ifdown/up. Other
>>>> operations on the interface will eventually panic the system:
>>>
>>> Stephen please fix this, thanks.
>>
>> Just FYI - I still see this issue with latest pull from net-2.6.
>
> It's net-next-2.6 that introduced the problem and has the follow-on
> fixes, not net-2.6
Same in net-next:
[ 55.706583] WARNING: at net/ipv6/ip6_fib.c:1170 fib6_del+0x44/0x39f [ipv6]()
[ 55.714851] Hardware name: S5520HC
[ 55.719037] Modules linked in: ipv6 e1000e e1000
[ 55.724866] Pid: 5599, comm: ifconfig Not tainted 2.6.34-rc1-net-next-e1000e-040510 #9
[ 55.734418] Call Trace:
[ 55.737540] [<ffffffff81033a3e>] ? __wake_up+0x43/0x50
[ 55.743773] [<ffffffffa006cb4e>] ? fib6_del+0x44/0x39f [ipv6]
[ 55.750687] [<ffffffff81038b1e>] warn_slowpath_common+0x77/0x8f
[ 55.757793] [<ffffffff81038b45>] warn_slowpath_null+0xf/0x11
[ 55.764608] [<ffffffffa006cb4e>] fib6_del+0x44/0x39f [ipv6]
[ 55.771314] [<ffffffffa006a13b>] __ip6_del_rt+0x49/0x68 [ipv6]
[ 55.778319] [<ffffffffa006a2aa>] ip6_del_rt+0x38/0x3a [ipv6]
[ 55.785136] [<ffffffffa0065573>] __ipv6_ifa_notify+0x141/0x17d [ipv6]
[ 55.792816] [<ffffffffa00660a4>] addrconf_ifdown+0x1ed/0x2cb [ipv6]
[ 55.800300] [<ffffffffa0067126>] addrconf_notify+0x705/0x7b6 [ipv6]
[ 55.807788] [<ffffffff810456ce>] ? spin_unlock_irqrestore+0x9/0xb
[ 55.815088] [<ffffffff81045b80>] ? __mod_timer+0x125/0x137
[ 55.821703] [<ffffffff8144eb60>] ? _raw_write_unlock_bh+0x12/0x14
[ 55.828995] [<ffffffff8103e37d>] ? local_bh_enable_ip+0x9/0xb
[ 55.835906] [<ffffffff8144ec75>] ? _raw_spin_unlock_bh+0x12/0x14
[ 55.843109] [<ffffffffa006ca9b>] ? fib6_run_gc+0xca/0xcf [ipv6]
[ 55.850213] [<ffffffff81451b29>] notifier_call_chain+0x33/0x5b
[ 55.857216] [<ffffffff81055575>] __raw_notifier_call_chain+0x9/0xb
[ 55.864604] [<ffffffff81055586>] raw_notifier_call_chain+0xf/0x11
[ 55.871901] [<ffffffff81397d8f>] call_netdevice_notifiers+0x16/0x18
[ 55.879390] [<ffffffff81397eb2>] __dev_notify_flags+0x35/0x59
[ 55.886293] [<ffffffff81397f1c>] dev_change_flags+0x46/0x52
[ 55.893007] [<ffffffff813f0844>] devinet_ioctl+0x27f/0x54b
[ 55.899614] [<ffffffff813f2c18>] inet_ioctl+0x8a/0xa2
[ 55.905733] [<ffffffff81387275>] sock_do_ioctl+0x26/0x46
[ 55.912149] [<ffffffff81387490>] sock_ioctl+0x1fb/0x20e
[ 55.918461] [<ffffffff810e7b4b>] vfs_ioctl+0x2a/0x9d
[ 55.924495] [<ffffffff810e80c2>] do_vfs_ioctl+0x48c/0x4dd
[ 55.930999] [<ffffffff810e816a>] sys_ioctl+0x57/0x7a
[ 55.937033] [<ffffffff81002a2b>] system_call_fastpath+0x16/0x1b
[ 55.944123] ---[ end trace c1c390412f982fb6 ]---
[ 55.949677] Freeing alive inet6 address ffff8801eee32000
[ 56.034060] fib6_clean_node: del failed: rt=ffff8801ec984e00@(null) err=-2
Emil
^ permalink raw reply
* Re: [PATCH 33/37] sound/soc: use .dev.of_node instead of .node in struct of_device
From: Grant Likely @ 2010-04-05 23:47 UTC (permalink / raw)
To: Ben Dooks
Cc: monstr-pSz03upnqPeHXe+LvDLADg, gregkh-l3A5Bk7waGM,
benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
davem-fT/PcQaiUtIeIZ0/mPfg9Q, sfr-3FnU+UHB4dNDw9hX6IcOSA,
jgarzik-e+AXbWqSrlAAvxtiuMwx3w, dwmw2-wEGCiKHe2LqWVfeAwA7xHQ,
jeremy.kerr-Z7WLFzj8eWMS+FvcfC7Uqw, James.Bottomley-l3A5Bk7waGM,
broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
microblaze-uclinux-rVRm/Wmeqae7NGdpmJTKYQ,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linuxppc-dev-mnsaURCQ41sdnm+yROfE0A,
sparclinux-u79uwXL29TY76Z2rM5mHXA,
linux-ide-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-scsi-u79uwXL29TY76Z2rM5mHXA,
alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw
In-Reply-To: <20100405230301.GF32401-elnMNo+KYs3pIgCt6eIbzw@public.gmane.org>
Hi Ben, thanks for the comment. Reply below...
On Mon, Apr 5, 2010 at 5:03 PM, Ben Dooks <ben-linux-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org> wrote:
> On Thu, Mar 11, 2010 at 11:06:50AM -0700, Grant Likely wrote:
>> .node is being removed
[...]
>> --- a/sound/soc/fsl/mpc8610_hpcd.c
>> +++ b/sound/soc/fsl/mpc8610_hpcd.c
>> @@ -202,7 +202,7 @@ static struct snd_soc_ops mpc8610_hpcd_ops = {
>> static int mpc8610_hpcd_probe(struct of_device *ofdev,
>> const struct of_device_id *match)
>> {
>> - struct device_node *np = ofdev->node;
>> + struct device_node *np = ofdev->dev.of_node;
>> struct device_node *codec_np = NULL;
>> struct device_node *guts_np = NULL;
>> struct device_node *dma_np = NULL;
>
> This looks like one case where an inline function would have been a
> help.
In what regard (how would you like it to look)? The node pointer
location is very unlikely to move again, and I prefer the clarity of
direct dereferencing.
g.
^ permalink raw reply
* Re: net-next: 2.6.34-rc1 regression: panic when running diagnostic on interface with IPv6
From: David Miller @ 2010-04-05 23:12 UTC (permalink / raw)
To: emil.s.tantilov; +Cc: shemminger, netdev
In-Reply-To: <EA929A9653AAE14F841771FB1DE5A1365FE4E2E26C@rrsmsx501.amr.corp.intel.com>
From: "Tantilov, Emil S" <emil.s.tantilov@intel.com>
Date: Mon, 5 Apr 2010 17:03:56 -0600
> David Miller wrote:
>> From: "Tantilov, Emil S" <emil.s.tantilov@intel.com>
>> Date: Tue, 23 Mar 2010 12:28:08 -0600
>>
>>> Bisecting points to this patch:
>>> http://git.kernel.org/?p=linux/kernel/git/davem/net-next-2.6.git;a=commitdiff;h=84e8b803f1e16f3a2b8b80f80a63fa2f2f8a9be6
>>>
>>> And I confirmed that the issue goes away after reverting it.
>>>
>>> Steps to reproduce:
>>> 1. Load the driver and configure IPv6 address.
>>> 2. Run ethtool diag:
>>> ethtool -t eth0
>>>
>>> 3. If this doesn't brake it try again, or just do ifdown/up. Other
>>> operations on the interface will eventually panic the system:
>>
>> Stephen please fix this, thanks.
>
> Just FYI - I still see this issue with latest pull from net-2.6.
It's net-next-2.6 that introduced the problem and has the follow-on
fixes, not net-2.6
^ permalink raw reply
* RE: net-next: 2.6.34-rc1 regression: panic when running diagnostic on interface with IPv6
From: Tantilov, Emil S @ 2010-04-05 23:03 UTC (permalink / raw)
To: shemminger@vyatta.com; +Cc: netdev@vger.kernel.org, David Miller
In-Reply-To: <20100323.233323.93371615.davem@davemloft.net>
David Miller wrote:
> From: "Tantilov, Emil S" <emil.s.tantilov@intel.com>
> Date: Tue, 23 Mar 2010 12:28:08 -0600
>
>> Bisecting points to this patch:
>> http://git.kernel.org/?p=linux/kernel/git/davem/net-next-2.6.git;a=commitdiff;h=84e8b803f1e16f3a2b8b80f80a63fa2f2f8a9be6
>>
>> And I confirmed that the issue goes away after reverting it.
>>
>> Steps to reproduce:
>> 1. Load the driver and configure IPv6 address.
>> 2. Run ethtool diag:
>> ethtool -t eth0
>>
>> 3. If this doesn't brake it try again, or just do ifdown/up. Other
>> operations on the interface will eventually panic the system:
>
> Stephen please fix this, thanks.
Just FYI - I still see this issue with latest pull from net-2.6.
Thanks,
Emil
^ permalink raw reply
* Re: [PATCH 33/37] sound/soc: use .dev.of_node instead of .node in struct of_device
From: Ben Dooks @ 2010-04-05 23:03 UTC (permalink / raw)
To: Grant Likely
Cc: monstr-pSz03upnqPeHXe+LvDLADg, gregkh-l3A5Bk7waGM,
benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
davem-fT/PcQaiUtIeIZ0/mPfg9Q, sfr-3FnU+UHB4dNDw9hX6IcOSA,
jgarzik-e+AXbWqSrlAAvxtiuMwx3w, ben-linux-elnMNo+KYs3YtjvyW6yDsg,
dwmw2-wEGCiKHe2LqWVfeAwA7xHQ, jeremy.kerr-Z7WLFzj8eWMS+FvcfC7Uqw,
James.Bottomley-l3A5Bk7waGM,
broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
microblaze-uclinux-rVRm/Wmeqae7NGdpmJTKYQ,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linuxppc-dev-mnsaURCQ41sdnm+yROfE0A,
sparclinux-u79uwXL29TY76Z2rM5mHXA,
linux-ide-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-scsi-u79uwXL29TY76Z2rM5mHXA,
alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw
In-Reply-To: <20100311180649.4824.10368.stgit@angua>
On Thu, Mar 11, 2010 at 11:06:50AM -0700, Grant Likely wrote:
> .node is being removed
>
> Signed-off-by: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>
> ---
>
> sound/soc/fsl/mpc8610_hpcd.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
> index ef67d1c..d7e1b9a 100644
> --- a/sound/soc/fsl/mpc8610_hpcd.c
> +++ b/sound/soc/fsl/mpc8610_hpcd.c
> @@ -202,7 +202,7 @@ static struct snd_soc_ops mpc8610_hpcd_ops = {
> static int mpc8610_hpcd_probe(struct of_device *ofdev,
> const struct of_device_id *match)
> {
> - struct device_node *np = ofdev->node;
> + struct device_node *np = ofdev->dev.of_node;
> struct device_node *codec_np = NULL;
> struct device_node *guts_np = NULL;
> struct device_node *dma_np = NULL;
This looks like one case where an inline function would have been a
help.
--
Ben (ben-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org, http://www.fluff.org/)
'a smiley only costs 4 bytes'
^ permalink raw reply
* Re: [PATCH net-next-2.6] net: Add a missing local_irq_enable()
From: David Miller @ 2010-04-05 22:42 UTC (permalink / raw)
To: eric.dumazet; +Cc: xiaosuo, therbert, netdev
In-Reply-To: <1270507307.9013.43.camel@edumazet-laptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Tue, 06 Apr 2010 00:41:47 +0200
> Le mardi 06 avril 2010 à 06:23 +0800, Changli Gao a écrit :
>
>> It seems that irq isn't enabled when breaking the loop. Please add
>> local_irq_enable();
>> after rps_unlock(queue);
>
> Gah.. you are right, following patch needed, since David already applied
> Tom's patch.
>
> [PATCH net-next-2.6] net: Add a missing local_irq_enable()
>
> As noticed by Changli Gao, we must call local_irq_enable() after
> rps_unlock()
>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Applied, hope it's fully resolved now :-)
^ permalink raw reply
* [PATCH net-next-2.6] net: Add a missing local_irq_enable()
From: Eric Dumazet @ 2010-04-05 22:41 UTC (permalink / raw)
To: Changli Gao; +Cc: Tom Herbert, davem, netdev
In-Reply-To: <z2m412e6f7f1004051523p6198556ak3e2ab9a52a3167d4@mail.gmail.com>
Le mardi 06 avril 2010 à 06:23 +0800, Changli Gao a écrit :
> It seems that irq isn't enabled when breaking the loop. Please add
> local_irq_enable();
> after rps_unlock(queue);
Gah.. you are right, following patch needed, since David already applied
Tom's patch.
[PATCH net-next-2.6] net: Add a missing local_irq_enable()
As noticed by Changli Gao, we must call local_irq_enable() after
rps_unlock()
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
diff --git a/net/core/dev.c b/net/core/dev.c
index 74f77ca..b98ddc6 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3121,6 +3121,7 @@ static int process_backlog(struct napi_struct *napi, int quota)
if (!skb) {
__napi_complete(napi);
rps_unlock(queue);
+ local_irq_enable();
break;
}
rps_unlock(queue);
^ permalink raw reply related
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