Netdev List
 help / color / mirror / Atom feed
* [PATCH v2] IP_GRE: Fix kernel panic in IP_GRE with GRE csum.
From: Pravin B Shelar @ 2013-01-22 22:56 UTC (permalink / raw)
  To: netdev; +Cc: jesse, Pravin B Shelar

Fixed code indentation according to comments from David Miller.

--8<--------------------------cut here-------------------------->8--
Due to GSO support, GRE can recieve non linear skb which
results in panic in case of GRE_CSUM.
Following patch fixes it by using correct csum API.

Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
---
 net/ipv4/ip_gre.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 303012a..8179e066 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -964,7 +964,10 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
 		}
 		if (tunnel->parms.o_flags&GRE_CSUM) {
 			*ptr = 0;
-			*(__sum16 *)ptr = ip_compute_csum((void *)(iph+1), skb->len - sizeof(struct iphdr));
+			*(__sum16 *)ptr = csum_fold(skb_checksum(skb,
+						    skb_transport_offset(skb),
+						    skb->len - skb_transport_offset(skb),
+						    0));
 		}
 	}
 
-- 
1.7.10

^ permalink raw reply related

* Re: [BUG] Bug in netprio_cgroup and netcls_cgroup ?
From: John Fastabend @ 2013-01-23  0:02 UTC (permalink / raw)
  To: Daniel Wagner
  Cc: Li Zefan, John Fastabend, Neil Horman, Daniel Wagner, LKML,
	netdev, Cgroups
In-Reply-To: <20130122100938.GA26820@candlejack.bmw-carit.intra>

[...]

>>
>> OK, I guess we should do something similar in the netprio, netcls
>> cgroups and
>> yes document it as you noted in your last comment.
>
> Here is my attempt to add such a check. I really don't know if this is the
> correct way to do so. To test this I have written a test program, which
> seems to test the right thing. Please have a look and let me know if
> it is correct: http://www.monom.org/misc/scm_rights.c
>
> And here a dirty first version of the patch:
>
>
>  From 49a78d907eaf31c16673025e7e3b4844e419e416 Mon Sep 17 00:00:00 2001
> From: Daniel Wagner <daniel.wagner@bmw-carit.de>
> Date: Tue, 22 Jan 2013 11:08:22 +0100
> Subject: [PATCH] net: net_prio: Block attach if a socket is shared
>
> ---
>   net/core/netprio_cgroup.c | 30 ++++++++++++++++++++++++++++++
>   1 file changed, 30 insertions(+)
>
> diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c
> index 847c02b..de4e6c5 100644
> --- a/net/core/netprio_cgroup.c
> +++ b/net/core/netprio_cgroup.c
> @@ -274,9 +274,39 @@ static struct cftype ss_files[] = {
>   	{ }	/* terminate */
>   };
>
> +static int check_cnt(const void *v, struct file *file, unsigned n)
> +{
> +	unsigned *flag = (unsigned *)v;
> +	int err;
> +
> +	struct socket *sock = sock_from_file(file, &err);
> +	if (sock && file_count(file) > 1)
> +		*flag = 1;
> +

I think this check will catch a lot of cases that are not necessarily
sharing a socket across tasks though. For example iscsid passes a file
descriptor to the kernel which does a sockfd_lookup() incrementing
f_count. Similarly look at dup/clone/etc.

In many of these cases I believe it should be OK to move the task
around when the sockets are not shared between multiple tasks.

.John

-- 
John Fastabend         Intel Corporation

^ permalink raw reply

* [PATCH] skb: add a comment to skb_csum_unnecessary to avoid miuse
From: Koki Sanagi @ 2013-01-23  0:30 UTC (permalink / raw)
  To: netdev; +Cc: davem

Due to its name and appearance, someone thinks this only checks if ip_summed is
CHECKSUM_UNNECESARRY.  But actually, this returns true even if ip_summed is
CHECKSUM_PARTIAL.  To avoid misuse, this patch a comment which specifies that
CHECKSUM_PARTIAL is OK.

Signed-off-by: Koki Sanagi <sanagi.koki@jp.fujitsu.com>
---
 include/linux/skbuff.h |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 8b2256e..bc41f64 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2522,6 +2522,16 @@ void skb_complete_wifi_ack(struct sk_buff *skb, bool acked);
 extern __sum16 __skb_checksum_complete_head(struct sk_buff *skb, int len);
 extern __sum16 __skb_checksum_complete(struct sk_buff *skb);
 
+/**
+ * skb_csum_unnecessary - check if the checksum needs to be verified
+ * @skb: skb to check
+ *
+ * check if the checksum of this skb needs to be verified.  This function is
+ * effective only against skbs on inbound path.
+ *
+ * NB: This returns true if ip_summed is CHECKSUM_UNNECESSARY or
+ *     CHECKSUM_PARTIAL.
+ **/
 static inline int skb_csum_unnecessary(const struct sk_buff *skb)
 {
 	return skb->ip_summed & CHECKSUM_UNNECESSARY;

^ permalink raw reply related

* Re: [PATCH net] r8169: remove the obsolete and incorrect AMD workaround
From: Francois Romieu @ 2013-01-23  0:05 UTC (permalink / raw)
  To: Timo Teräs; +Cc: netdev
In-Reply-To: <1358843435-24719-1-git-send-email-timo.teras@iki.fi>

Timo Teräs <timo.teras@iki.fi> :
[...]

Acked-by: Francois Romieu <romieu@fr.zoreil.com>

desc->opts2 is now a bit different in the RxRes path - the only path
where the patch can be noticed. I hope it won't uncloak something else.

-- 
Ueimor

^ permalink raw reply

* Re: [PATCH 2/2] IP_GRE: Linearize skb before csum.
From: David Miller @ 2013-01-23  0:41 UTC (permalink / raw)
  To: eric.dumazet; +Cc: jesse, pshelar, netdev
In-Reply-To: <1358894653.12374.201.camel@edumazet-glaptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Tue, 22 Jan 2013 14:44:13 -0800

> On Tue, 2013-01-22 at 14:38 -0800, Jesse Gross wrote:
> 
>> 
>> We're currently enforcing this assumption in the rest of the network
>> stack - it's why we mask out scatter/gather capability in the NIC if
>> it isn't capable of checksumming the packet.
>> 
>> Packets with asynchronous changes may come from VMs, so it isn't
>> necessarily reasonable to tell people that they need to disable
>> offloads with certain use cases.
>> 
>> As Pravin said, pushing down the GSO to the lowest layer is the best
>> way to solve the problem.  However, I would argue that the current
>> behavior is not correct.
> 
> You do understand this problem is generic to GSO ?
> 
> You basically are saying GSO should be removed.
> 
> If you really care, please find another way to address the problem.
> 
> Frames build by tcp_sendmsg() are fine : their content cannot be changed
> by the user.

We don't emit crap onto the wire knowingly.  Jesse is right.

If you want to do software GSO in situations where we know that the
paged data cannot be modified asynchronously, you'll have to
explicitly support that.

I will not accept us saying that allowing the emission of bad
checksums is OK.  It never is.  That's terrible behavior, and creates
impossible to disagnose problems.

^ permalink raw reply

* Re: [PATCH net] r8169: remove the obsolete and incorrect AMD workaround
From: David Miller @ 2013-01-23  0:42 UTC (permalink / raw)
  To: romieu; +Cc: timo.teras, netdev
In-Reply-To: <20130123000541.GA9515@electric-eye.fr.zoreil.com>

From: Francois Romieu <romieu@fr.zoreil.com>
Date: Wed, 23 Jan 2013 01:05:41 +0100

> Timo Teräs <timo.teras@iki.fi> :
> [...]
> 
> Acked-by: Francois Romieu <romieu@fr.zoreil.com>
> 
> desc->opts2 is now a bit different in the RxRes path - the only path
> where the patch can be noticed. I hope it won't uncloak something else.

Francois, do you want me to apply this directly or do you want
to submit this yourself along with any other r8169 changes you
might have queued up?

Thanks.

^ permalink raw reply

* Re: [PATCH 2/2] IP_GRE: Linearize skb before csum.
From: Eric Dumazet @ 2013-01-23  1:08 UTC (permalink / raw)
  To: David Miller; +Cc: jesse, pshelar, netdev
In-Reply-To: <20130122.194143.1205292712415183747.davem@davemloft.net>

On Tue, 2013-01-22 at 19:41 -0500, David Miller wrote:

> We don't emit crap onto the wire knowingly.  Jesse is right.
> 
> If you want to do software GSO in situations where we know that the
> paged data cannot be modified asynchronously, you'll have to
> explicitly support that.
> 
> I will not accept us saying that allowing the emission of bad
> checksums is OK.  It never is.  That's terrible behavior, and creates
> impossible to disagnose problems.

How is this related to GRE only ?

We have dozen of skb_checksum_help() calls that basically have the same
issue.

Am I missing some obvious thing ?

^ permalink raw reply

* [PATCH net-next] drivers/net/ethernet/micrel/ks8851_mll: Implement basic statistics
From: Choi, David @ 2013-01-23  1:40 UTC (permalink / raw)
  To: netdev@vger.kernel.org; +Cc: Doong, Ping, Choi, David

From: David J. Choi <david.choi@micrel.com>
 
Summary of changes:
  add codes to collect basic statistical information about Ethernet packets.
 
Signed-off-by: David J. Choi <david.choi@micrel.com>
---

--- net-next/drivers/net/ethernet/micrel/ks8851_mll.c.orig	2013-01-22 17:25:59.000000000 -0800
+++ net-next/drivers/net/ethernet/micrel/ks8851_mll.c	2013-01-22 17:27:57.000000000 -0800
@@ -798,10 +798,17 @@ static void ks_rcv(struct ks_net *ks, st
 			skb_reserve(skb, 2);
 			/* read data block including CRC 4 bytes */
 			ks_read_qmu(ks, (u16 *)skb->data, frame_hdr->len);
-			skb_put(skb, frame_hdr->len);
+			skb_put(skb, frame_hdr->len - 4); /*exclude size of CRC */
 			skb->protocol = eth_type_trans(skb, netdev);
 			netif_rx(skb);
+			netdev->stats.rx_packets++;
+			netdev->stats.rx_bytes += (frame_hdr->len - 4); /*crc field*/
 		} else {
+			netdev->stats.rx_dropped++;
+			if ((frame_hdr->len >= RX_BUF_SIZE) || (frame_hdr->len == 0))
+				netdev->stats.rx_length_errors++;
+			if (frame_hdr->sts & RXFSHR_RXFV) 
+				netdev->stats.rx_frame_errors++;
 			pr_err("%s: err:skb alloc\n", __func__);
 			ks_wrreg16(ks, KS_RXQCR, (ks->rc_rxqcr | RXQCR_RRXEF));
 			if (skb)
@@ -876,6 +883,8 @@ static irqreturn_t ks_irq(int irq, void 
 		pmecr &= ~PMECR_WKEVT_MASK;
 		ks_wrreg16(ks, KS_PMECR, pmecr | PMECR_WKEVT_LINK);
 	}
+	if (unlikely(status & IRQ_RXOI))
+		ks->netdev->stats.rx_over_errors++;
 
 	/* this should be the last in IRQ handler*/
 	ks_restore_cmd_reg(ks);
@@ -1015,6 +1024,8 @@ static int ks_start_xmit(struct sk_buff 
 
 	if (likely(ks_tx_fifo_space(ks) >= skb->len + 12)) {
 		ks_write_qmu(ks, skb->data, skb->len);
+		netdev->stats.tx_bytes += skb->len;
+		netdev->stats.tx_packets++;
 		dev_kfree_skb(skb);
 	} else
 		retv = NETDEV_TX_BUSY;

---

^ permalink raw reply

* Re: [PATCH net-next 0/4] Use IS_ERR_OR_NULL().
From: Paul Gortmaker @ 2013-01-23  1:44 UTC (permalink / raw)
  To: YOSHIFUJI Hideaki; +Cc: davem, netdev
In-Reply-To: <50FEBF1E.6070209@linux-ipv6.org>

On Tue, Jan 22, 2013 at 11:32 AM, YOSHIFUJI Hideaki
<yoshfuji@linux-ipv6.org> wrote:
> YOSHIFUJI Hideaki (4):
>   net: Use IS_ERR_OR_NULL().
>   ipv4: Use IS_ERR_OR_NULL().
>   ipv6: Use IS_ERR_OR_NULL().
>   netfilter: Use IS_ERR_OR_NULL().
>
>  net/core/flow.c                 |    2 +-
>  net/ipv4/af_inet.c              |    2 +-
>  net/ipv4/netfilter/arp_tables.c |   10 +++++-----
>  net/ipv4/netfilter/ip_tables.c  |   10 +++++-----
>  net/ipv4/tcp.c                  |    2 +-
>  net/ipv4/udp.c                  |    2 +-
>  net/ipv6/addrconf.c             |    4 ++--
>  net/ipv6/netfilter/ip6_tables.c |   10 +++++-----
>  8 files changed, 21 insertions(+), 21 deletions(-)

Just as a heads-up, there are discussions underway about
whether the whole IS_ERR_OR_NULL interface is one that
we want to be adding more users to:

https://patchwork.kernel.org/patch/1953271/

Paul.
--

>
> --
> 1.7.9.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH 2/2] IP_GRE: Linearize skb before csum.
From: David Miller @ 2013-01-23  1:46 UTC (permalink / raw)
  To: eric.dumazet; +Cc: jesse, pshelar, netdev
In-Reply-To: <1358903293.12374.492.camel@edumazet-glaptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Tue, 22 Jan 2013 17:08:13 -0800

> On Tue, 2013-01-22 at 19:41 -0500, David Miller wrote:
> 
>> We don't emit crap onto the wire knowingly.  Jesse is right.
>> 
>> If you want to do software GSO in situations where we know that the
>> paged data cannot be modified asynchronously, you'll have to
>> explicitly support that.
>> 
>> I will not accept us saying that allowing the emission of bad
>> checksums is OK.  It never is.  That's terrible behavior, and creates
>> impossible to disagnose problems.
> 
> How is this related to GRE only ?
> 
> We have dozen of skb_checksum_help() calls that basically have the same
> issue.
> 
> Am I missing some obvious thing ?

Then all of them need fixing.

We can't emit bogus checksums on the wire when this is completely
under our control.

^ permalink raw reply

* Re: [PATCH net-next] drivers/net/ethernet/micrel/ks8851_mll: Implement basic statistics
From: David Miller @ 2013-01-23  1:51 UTC (permalink / raw)
  To: David.Choi; +Cc: netdev, Ping.Doong
In-Reply-To: <FD9AD8C5375B924CABC56D982DB3A802079D32D1@EXMB1.micrel.com>

From: "Choi, David" <David.Choi@Micrel.Com>
Date: Wed, 23 Jan 2013 01:40:41 +0000

> From: David J. Choi <david.choi@micrel.com>
>  
> Summary of changes:
>   add codes to collect basic statistical information about Ethernet packets.
>  
> Signed-off-by: David J. Choi <david.choi@micrel.com>

A Subject prefix of "ks8851_mll: " is sufficient, people who want the
whole patch name can simply look at the patch.

> +			if (frame_hdr->sts & RXFSHR_RXFV) 

This line has trailing whitespace errors.

> +				netdev->stats.rx_frame_errors++;
>  			pr_err("%s: err:skb alloc\n", __func__);

BTW it's inappropriate to log an SKB allocation failure as an error in
the kernel logs like this.  This can be completely normal on a heavily
loaded system.  People can look at the device statistics to learn about
this event, or use a more sophisticated tool like the drop monitor.

^ permalink raw reply

* Re: [PATCH] skb: add a comment to skb_csum_unnecessary to avoid miuse
From: David Miller @ 2013-01-23  1:53 UTC (permalink / raw)
  To: sanagi.koki; +Cc: netdev
In-Reply-To: <50FF2F18.1050408@jp.fujitsu.com>

From: Koki Sanagi <sanagi.koki@jp.fujitsu.com>
Date: Wed, 23 Jan 2013 09:30:16 +0900

> Due to its name and appearance, someone thinks this only checks if ip_summed is
> CHECKSUM_UNNECESARRY.  But actually, this returns true even if ip_summed is
> CHECKSUM_PARTIAL.  To avoid misuse, this patch a comment which specifies that
> CHECKSUM_PARTIAL is OK.
> 
> Signed-off-by: Koki Sanagi <sanagi.koki@jp.fujitsu.com>

I'm not applying this, sorry.  It's a one line function and it's not
so non-obvious that it deserves an 8 line comment.

^ permalink raw reply

* Re: [PATCH v2] IP_GRE: Fix kernel panic in IP_GRE with GRE csum.
From: David Miller @ 2013-01-23  1:55 UTC (permalink / raw)
  To: pshelar; +Cc: netdev, jesse
In-Reply-To: <1358895398-2088-1-git-send-email-pshelar@nicira.com>

From: Pravin B Shelar <pshelar@nicira.com>
Date: Tue, 22 Jan 2013 14:56:38 -0800

> Fixed code indentation according to comments from David Miller.
> 
> --8<--------------------------cut here-------------------------->8--

This doesn't do what you think it does.  No automated tool is going
to edit the commit message the way you think this will.

You should instead put your "what is different in this revision"
comments right after the "---" below.

> Due to GSO support, GRE can recieve non linear skb which
> results in panic in case of GRE_CSUM.
> Following patch fixes it by using correct csum API.
> 
> Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
> ---
 ^^^

Right after that line.

^ permalink raw reply

* Re: 3.7.3+:  Bad paging request in ip_rcv_finish while running NFS traffic.
From: Ben Greear @ 2013-01-23  2:32 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev, linux-nfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <50FF102F.2050008-my8/4N5VtI7c+919tysfdA@public.gmane.org>

On 01/22/2013 02:18 PM, Ben Greear wrote:
> On 01/22/2013 09:26 AM, Eric Dumazet wrote:
>> On Tue, 2013-01-22 at 09:17 -0800, Eric Dumazet wrote:
>>> On Tue, 2013-01-22 at 09:08 -0800, Ben Greear wrote:
>>>
>>>> Unfortunately, I hit it again this morning after the first restart of
>>>> my application (which bounces all 3000 interfaces).  Memory poisoning
>>>> was disabled.
>>>
>>> Is your NFS traffic using TCP or UDP ?
>>>
>>
>> Oh well, it seems macvlan.c has to skb_drop_dst(skb) before giving skb
>> to netif_rx()
>
> I just saw another crash.  It had run 2 user-space restarts and
> 2 reboots, but on the third reboot, it crashed coming up.  It seemed
> to last longer this time, but that could just be luck as it's never
> been super easy to reproduce this quickly.

I added a patch to set dst->input and dst->output to 0xdeadbeef before
freeing the memory.  (The warn-on below did NOT hit)

@@ -452,6 +452,9 @@ static inline int dst_output(struct sk_buff *skb)
  /* Input packet from network to transport.  */
  static inline int dst_input(struct sk_buff *skb)
  {
+       if (WARN_ON(((unsigned long)(skb_dst(skb))) < 4000)) {
+               printk("Bad skb_dst: %lu\n", skb->_skb_refdst);
+       }
         return skb_dst(skb)->input(skb);
  }

diff --git a/net/core/dst.c b/net/core/dst.c
index ee6153e..234b168 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -245,6 +245,7 @@ again:
                 dst->ops->destroy(dst);
         if (dst->dev)
                 dev_put(dst->dev);
+       dst->input = dst->output = 0xdeadbeef;
         kmem_cache_free(dst->ops->kmem_cachep, dst);

         dst = child;

Looks like we do indeed access freed memory, based on this crash I saw on
the next reboot:

[root@lf1011-12060006 ~]# BUG: unable to handle kernel paging request at 00000000deadbeef
IP: [<00000000deadbeef>] 0xdeadbeee
PGD 0
Oops: 0010 [#1] PREEMPT SMP
Modules linked in: macvlan pktgen lockd sunrpc uinput iTCO_wdt iTCO_vendor_support gpio_ich coretemp hwmon kvm_intel kvm microcode pcspkr i2c_i801 lpc_ich 
e1000e i7core_edac ioatdma edac_core igb ptp pps_core dca ipv6 mgag200 i2c_algo_bit drm_kms_helper ttm drm i2c_core
CPU 8
Pid: 59, comm: ksoftirqd/8 Tainted: G         C O 3.7.3+ #46 Iron Systems Inc. EE2610R/X8ST3
RIP: 0010:[<00000000deadbeef>]  [<00000000deadbeef>] 0xdeadbeee
RSP: 0018:ffff88040d7d7bc0  EFLAGS: 00010286
RAX: ffff8803d97fc900 RBX: ffff8803d4d30d00 RCX: 0000000000000028
RDX: ffffffff81aafcb0 RSI: ffffffff81a2a500 RDI: ffff8803d4d30d00
RBP: ffff88040d7d7be8 R08: ffffffff814a8812 R09: ffff88040d7d7bb0
R10: ffff8803c9dfd8fc R11: ffff88040d7d7c48 R12: ffff8803c9dfd8fc
R13: ffff8803d4d30d00 R14: ffff88040d3f8000 R15: 0000000000000000
FS:  0000000000000000(0000) GS:ffff88041fd00000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 00000000deadbeef CR3: 0000000001a0b000 CR4: 00000000000007e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process ksoftirqd/8 (pid: 59, threadinfo ffff88040d7d6000, task ffff88040d7e1f50)
Stack:
  ffffffff814a8b02 ffff8803d4d30d00 ffffffff814a8812 ffff8803d4d30d00
  ffff88040d3f8000 ffff88040d7d7c18 ffffffff814a8eb5 0000000080000000
  ffffffff81472e61 ffff8803d4d30d00 ffff88040d3f8000 ffff88040d7d7c48
Call Trace:
  [<ffffffff814a8b02>] ? ip_rcv_finish+0x2f0/0x308
  [<ffffffff814a8812>] ? skb_dst+0x5a/0x5a
  [<ffffffff814a8eb5>] NF_HOOK.clone.1+0x4c/0x54
  [<ffffffff81472e61>] ? dev_seq_stop+0xb/0xb
  [<ffffffff814a9142>] ip_rcv+0x237/0x269
  [<ffffffff81473def>] __netif_receive_skb+0x487/0x530
  [<ffffffff81473f91>] process_backlog+0xf9/0x1da
  [<ffffffff8147639a>] net_rx_action+0xad/0x218
  [<ffffffff8108d50a>] __do_softirq+0x9c/0x161
  [<ffffffff8108d5f2>] run_ksoftirqd+0x23/0x42
  [<ffffffff810a7ebe>] smpboot_thread_fn+0x253/0x259
  [<ffffffff810a7c6b>] ? test_ti_thread_flag.clone.0+0x11/0x11
  [<ffffffff810a0a6d>] kthread+0xc2/0xca
  [<ffffffff810a09ab>] ? __init_kthread_worker+0x56/0x56
  [<ffffffff81537b7c>] ret_from_fork+0x7c/0xb0
  [<ffffffff810a09ab>] ? __init_kthread_worker+0x56/0x56
Code:  Bad RIP value.
RIP  [<00000000deadbeef>] 0xdeadbeee
  RSP <ffff88040d7d7bc0>
CR2: 00000000deadbeef
---[ end trace eed854e70ff0a575 ]---
Kernel panic - not syncing: Fatal excepti

Thanks,
Ben


-- 
Ben Greear <greearb-my8/4N5VtI7c+919tysfdA@public.gmane.org>
Candela Technologies Inc  http://www.candelatech.com

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

^ permalink raw reply related

* RE: [PATCH] skb: add a comment to skb_csum_unnecessary to avoid miuse
From: Sanagi, Koki @ 2013-01-23  2:32 UTC (permalink / raw)
  To: David Miller; +Cc: netdev@vger.kernel.org
In-Reply-To: <20130122.205346.633138554393148358.davem@davemloft.net>

> From: Koki Sanagi <sanagi.koki@jp.fujitsu.com>
> Date: Wed, 23 Jan 2013 09:30:16 +0900
> 
> > Due to its name and appearance, someone thinks this only checks if
> > ip_summed is CHECKSUM_UNNECESARRY.  But actually, this returns true
> > even if ip_summed is CHECKSUM_PARTIAL.  To avoid misuse, this patch a
> > comment which specifies that CHECKSUM_PARTIAL is OK.
> >
> > Signed-off-by: Koki Sanagi <sanagi.koki@jp.fujitsu.com>
> 
> I'm not applying this, sorry.  It's a one line function and it's not so
> non-obvious that it deserves an 8 line comment.

OK.  I just felt weird that CHECKSUM_* is not bit flag but this function handles
it as if it was bit flag.

^ permalink raw reply

* [PATCH, resubmit] ax88179_178a: ASIX AX88179_178A USB 3.0/2.0 to gigabit ethernet adapter driver
From: Freddy Xin @ 2013-01-23  2:32 UTC (permalink / raw)
  To: netdev; +Cc: linux-usb, linux-kernel, louis, davem, Freddy Xin

From: Freddy Xin <freddy@asix.com.tw>

This is a resubmission.
Fixed coding style errors.
The _nopm version usb functions were added to access register in suspend and resume functions.
Serveral variables allocted dynamically were removed and replaced by stack variables.
ax88179_get_eeprom were modified from asix_get_eeprom in asix_common.

This patch adds a driver for ASIX's AX88179 family of USB 3.0/2.0
to gigabit ethernet adapters. It's based on the AX88xxx driver but
the usb commands used to access registers for AX88179 are completely different.
This driver had been verified on x86 system with AX88179/AX88178A and
Sitcomm LN-032 USB dongles.

Signed-off-by: Freddy Xin <freddy@asix.com.tw>
---
 drivers/net/usb/Kconfig        |   18 +
 drivers/net/usb/Makefile       |    1 +
 drivers/net/usb/ax88179_178a.c | 1361 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 1380 insertions(+)
 create mode 100644 drivers/net/usb/ax88179_178a.c

diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index ef97621..75af401 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -158,6 +158,24 @@ config USB_NET_AX8817X
 	  This driver creates an interface named "ethX", where X depends on
 	  what other networking devices you have in use.
 
+config USB_NET_AX88179_178A
+	tristate "ASIX AX88179/178A USB 3.0/2.0 to Gigabit Ethernet"
+	depends on USB_USBNET
+	select CRC32
+	select PHYLIB
+	default y
+	help
+	  This option adds support for ASIX AX88179 based USB 3.0/2.0
+	  to Gigabit Ethernet adapters.
+
+ 	  This driver should work with at least the following devices:
+	    * ASIX AX88179
+	    * ASIX AX88178A
+	    * Sitcomm LN-032
+
+	  This driver creates an interface named "ethX", where X depends on
+	  what other networking devices you have in use.
+
 config USB_NET_CDCETHER
 	tristate "CDC Ethernet support (smart devices such as cable modems)"
 	depends on USB_USBNET
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile
index 4786913..119b06c 100644
--- a/drivers/net/usb/Makefile
+++ b/drivers/net/usb/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_USB_RTL8150)	+= rtl8150.o
 obj-$(CONFIG_USB_HSO)		+= hso.o
 obj-$(CONFIG_USB_NET_AX8817X)	+= asix.o
 asix-y := asix_devices.o asix_common.o ax88172a.o
+obj-$(CONFIG_USB_NET_AX88179_178A)      += ax88179_178a.o
 obj-$(CONFIG_USB_NET_CDCETHER)	+= cdc_ether.o
 obj-$(CONFIG_USB_NET_CDC_EEM)	+= cdc_eem.o
 obj-$(CONFIG_USB_NET_DM9601)	+= dm9601.o
diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
new file mode 100644
index 0000000..95d79bd
--- /dev/null
+++ b/drivers/net/usb/ax88179_178a.c
@@ -0,0 +1,1361 @@
+/*
+ * ASIX AX88179/178A USB 3.0/2.0 to Gigabit Ethernet Devices
+ *
+ * Copyright (C) 20011-2012 ASIX
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/etherdevice.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/crc32.h>
+#include <linux/usb/usbnet.h>
+
+#define AX88179_PHY_ID				0x03
+#define AX_EEPROM_LEN				0x100
+#define AX88179_EEPROM_MAGIC			0x17900b95
+#define AX_MCAST_FLTSIZE			8
+#define AX_MAX_MCAST				64
+#define AX_INT_PPLS_LINK			BIT(0)
+#define AX_RXHDR_L4_TYPE_UDP			1
+#define AX_RXHDR_L4_TYPE_TCP			4
+#define AX_ACCESS_MAC				0x01
+#define AX_ACCESS_PHY				0x02
+#define AX_ACCESS_EEPROM			0x04
+#define AX_ACCESS_EFUS				0x05
+#define AX_PAUSE_WATERLVL_HIGH			0x54
+#define AX_PAUSE_WATERLVL_LOW			0x55
+
+#define PHYSICAL_LINK_STATUS			0x02
+	#define	AX_USB_SS		0x04
+	#define	AX_USB_HS		0x02
+
+#define GENERAL_STATUS				0x03
+/* Check AX88179 version. UA1:Bit2 = 0,  UA2:Bit2 = 1 */
+	#define	AX_SECLD		0x04
+
+#define AX_SROM_ADDR				0x07
+#define AX_SROM_CMD				0x0a
+	#define EEP_RD			0x04
+	#define EEP_BUSY		0x10
+
+#define AX_SROM_DATA_LOW			0x08
+#define AX_SROM_DATA_HIGH			0x09
+
+#define AX_RX_CTL				0x0b
+	#define AX_RX_CTL_DROPCRCERR	0x0100
+	#define AX_RX_CTL_IPE		0x0200
+	#define AX_RX_CTL_START		0x0080
+	#define AX_RX_CTL_AP		0x0020
+	#define AX_RX_CTL_AM		0x0010
+	#define AX_RX_CTL_AB		0x0008
+	#define AX_RX_CTL_AMALL		0x0002
+	#define AX_RX_CTL_PRO		0x0001
+	#define AX_RX_CTL_STOP		0x0000
+
+#define AX_NODE_ID				0x10
+#define AX_MULFLTARY				0x16
+
+#define AX_MEDIUM_STATUS_MODE			0x22
+	#define AX_MEDIUM_GIGAMODE	0x01
+	#define AX_MEDIUM_FULL_DUPLEX	0x02
+	#define AX_MEDIUM_ALWAYS_ONE	0x04
+	#define AX_MEDIUM_RXFLOW_CTRLEN	0x10
+	#define AX_MEDIUM_TXFLOW_CTRLEN	0x20
+	#define AX_MEDIUM_RECEIVE_EN	0x100
+	#define AX_MEDIUM_PS		0x200
+
+#define AX_MONITOR_MOD				0x24
+	#define AX_MONITOR_MODE_RWLC	0x02
+	#define AX_MONITOR_MODE_RWMP	0x04
+	#define AX_MONITOR_MODE_PMEPOL	0x20
+	#define AX_MONITOR_MODE_PMETYPE	0x40
+
+#define AX_GPIO_CTRL				0x25
+	#define AX_GPIO_CTRL_GPIO3EN	0x80
+	#define AX_GPIO_CTRL_GPIO2EN	0x40
+	#define AX_GPIO_CTRL_GPIO1EN	0x20
+
+#define AX_PHYPWR_RSTCTL			0x26
+	#define AX_PHYPWR_RSTCTL_BZ	0x0010
+	#define AX_PHYPWR_RSTCTL_IPRL	0x0020
+	#define AX_PHYPWR_RSTCTL_AT	0x1000
+
+#define AX_RX_BULKIN_QCTRL			0x2e
+#define AX_CLK_SELECT				0x33
+	#define AX_CLK_SELECT_BCS	0x01
+	#define AX_CLK_SELECT_ACS	0x02
+	#define AX_CLK_SELECT_ULR	0x08
+
+#define AX_RXCOE_CTL				0x34
+	#define AX_RXCOE_IP		0x01
+	#define AX_RXCOE_TCP		0x02
+	#define AX_RXCOE_UDP		0x04
+	#define AX_RXCOE_TCPV6		0x20
+	#define AX_RXCOE_UDPV6		0x40
+
+#define AX_TXCOE_CTL				0x35
+	#define AX_TXCOE_IP		0x01
+	#define AX_TXCOE_TCP		0x02
+	#define AX_TXCOE_UDP		0x04
+	#define AX_TXCOE_TCPV6		0x20
+	#define AX_TXCOE_UDPV6		0x40
+
+#define AX_LEDCTRL				0x73
+
+#define GMII_PHY_PHYSR				0x11
+	#define GMII_PHY_PHYSR_SMASK	0xc000
+	#define GMII_PHY_PHYSR_GIGA	0x8000
+	#define GMII_PHY_PHYSR_100	0x4000
+	#define GMII_PHY_PHYSR_FULL	0x2000
+	#define GMII_PHY_PHYSR_LINK	0x400
+
+#define GMII_LED_ACT				0x1a
+	#define GMII_LED_ACTIVE_MASK	0xff8fd
+	#define GMII_LED0_ACTIVE	BIT(4)
+	#define GMII_LED1_ACTIVE	BIT(5)
+	#define GMII_LED2_ACTIVE	BIT(6)
+
+#define GMII_LED_LINK				0x1c
+	#define GMII_LED_LINK_MASK	0xf888
+	#define GMII_LED0_LINK_10	BIT(0)
+	#define GMII_LED0_LINK_100	BIT(1)
+	#define GMII_LED0_LINK_1000	BIT(2)
+	#define GMII_LED1_LINK_10	BIT(4)
+	#define GMII_LED1_LINK_100	BIT(5)
+	#define GMII_LED1_LINK_1000	BIT(6)
+	#define GMII_LED2_LINK_10	BIT(8)
+	#define GMII_LED2_LINK_100	BIT(9)
+	#define GMII_LED2_LINK_1000	BIT(10)
+	#define	LED0_ACTIVE		BIT(0)
+	#define	LED0_LINK_10		BIT(1)
+	#define	LED0_LINK_100		BIT(2)
+	#define	LED0_LINK_1000		BIT(3)
+	#define	LED0_FD			BIT(4)
+	#define LED0_USB3_MASK		0x001f
+	#define	LED1_ACTIVE		BIT(5)
+	#define	LED1_LINK_10		BIT(6)
+	#define	LED1_LINK_100		BIT(7)
+	#define	LED1_LINK_1000		BIT(8)
+	#define	LED1_FD			BIT(9)
+	#define LED1_USB3_MASK		0x03e0
+	#define	LED2_ACTIVE		BIT(10)
+	#define	LED2_LINK_1000		BIT(13)
+	#define	LED2_LINK_100		BIT(12)
+	#define	LED2_LINK_10		BIT(11)
+	#define	LED2_FD			BIT(14)
+	#define	LED_VALID		BIT(15)
+	#define LED2_USB3_MASK		0x7c00
+
+#define GMII_PHYPAGE				0x1e
+#define GMII_PHY_PAGE_SELECT			0x1f
+	#define GMII_PHY_PGSEL_EXT	0x0007
+	#define GMII_PHY_PGSEL_PAGE0	0X0000
+
+struct ax88179_data {
+	u16 rxctl;
+};
+
+struct ax88179_int_data {
+	u16 res1;
+	u8 link;
+	u16 res2;
+	u8 status;
+	u16 res3;
+} __packed;
+
+struct {unsigned char ctrl, timer_l, timer_h, size, ifg; }
+AX88179_BULKIN_SIZE[] =	{
+	{7, 0xa3, 0,	0x14, 0xff},
+	{7, 0x1e, 5,	0x18, 0xff},
+	{7, 0xae, 7,	0x18, 0xff},
+	{7, 0xcc, 0x4c, 0x18, 8},
+};
+
+struct ax88179_rx_pkt_header {
+	u8	l4_csum_err:1,
+		l3_csum_err:1,
+		l4_type:3,
+		l3_type:2,
+		ce:1;
+
+	u8	vlan_ind:3,
+		rx_ok:1,
+		pri:3,
+		bmc:1;
+
+	u16	len:13,
+		crc:1,
+		mii:1,
+		drop:1;
+} __packed;
+
+static int __ax88179_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+			   u16 size, void *data, int in_pm)
+{
+	int ret;
+	int (*fn)(struct usbnet *, u8, u8, u16, u16, void *, u16);
+
+	if (!in_pm)
+		fn = usbnet_read_cmd;
+	else
+		fn = usbnet_read_cmd_nopm;
+
+	ret = fn(dev, cmd, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+	      value, index, data, size);
+
+	if (ret != size && ret >= 0)
+		return -EINVAL;
+
+	return ret;
+}
+
+static int __ax88179_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+			    u16 size, void *data, int in_pm)
+{
+	int (*fn)(struct usbnet *, u8, u8, u16, u16, const void *, u16);
+
+	if (!in_pm)
+		fn = usbnet_write_cmd;
+	else
+		fn = usbnet_write_cmd_nopm;
+
+	return fn(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+	       value, index, data, size);
+
+}
+
+static void ax88179_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value,
+				 u16 index, u16 size, void *data)
+{
+	usbnet_write_cmd_async(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR |
+			    USB_RECIP_DEVICE, value, index, data, size);
+}
+
+static int ax88179_read_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value,
+			      u16 index, u16 size, void *data)
+{
+	return __ax88179_read_cmd(dev, cmd, value, index, size, data, 1);
+}
+
+static int ax88179_write_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value,
+			       u16 index, u16 size, void *data)
+{
+	return __ax88179_write_cmd(dev, cmd, value, index, size, data, 1);
+}
+
+static int ax88179_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+			 u16 size, void *data)
+{
+	return __ax88179_read_cmd(dev, cmd, value, index, size, data, 0);
+}
+
+static int ax88179_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+			  u16 size, void *data)
+{
+	return __ax88179_write_cmd(dev, cmd, value, index, size, data, 0);
+}
+
+static void ax88179_status(struct usbnet *dev, struct urb *urb)
+{
+	struct ax88179_int_data *event;
+	int link;
+
+	if (urb->actual_length < 8)
+		return;
+
+	event = urb->transfer_buffer;
+	link = event->link & AX_INT_PPLS_LINK;
+	if (netif_carrier_ok(dev->net) != link) {
+		if (link)
+			usbnet_defer_kevent(dev, EVENT_LINK_RESET);
+		else
+			netif_carrier_off(dev->net);
+		netdev_info(dev->net, "ax88179 - Link status is: %d\n", link);
+	}
+}
+
+static int ax88179_mdio_read(struct net_device *netdev, int phy_id, int loc)
+{
+	struct usbnet *dev = netdev_priv(netdev);
+	__u16 res;
+
+	ax88179_read_cmd(dev, AX_ACCESS_PHY, phy_id, (__u16)loc, 2, &res);
+
+	return le16_to_cpu(res & 0xffff);
+}
+
+static void ax88179_mdio_write(struct net_device *netdev, int phy_id, int loc,
+			    int val)
+{
+	struct usbnet *dev = netdev_priv(netdev);
+	__le16 res;
+
+	res = cpu_to_le16(val);
+	ax88179_write_cmd(dev, AX_ACCESS_PHY, phy_id, (__u16)loc, 2, &res);
+}
+
+static int ax88179_suspend(struct usb_interface *intf, pm_message_t message)
+{
+	struct usbnet *dev = usb_get_intfdata(intf);
+	u16 tmp16;
+
+	usbnet_suspend(intf, message);
+
+	/* Disable RX path */
+	ax88179_read_cmd_nopm(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+			   2, 2, &tmp16);
+	tmp16 &= ~AX_MEDIUM_RECEIVE_EN;
+	ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+			    2, 2, &tmp16);
+
+	/* Force bulk-in zero length */
+	ax88179_read_cmd_nopm(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL,
+			   2, 2, &tmp16);
+
+	tmp16 |= AX_PHYPWR_RSTCTL_BZ | AX_PHYPWR_RSTCTL_IPRL;
+	ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL,
+			    2, 2, &tmp16);
+
+	/* change clock */
+	tmp16 = 0;
+	ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp16);
+
+	/* Configure RX control register => stop operation */
+	tmp16 = AX_RX_CTL_STOP;
+	ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &tmp16);
+
+	return 0;
+}
+
+/* This function is used to enable the autodetach function. */
+/* This function is determined by offset 0x43 of EEPROM */
+static int ax88179_auto_detach(struct usbnet *dev, int in_pm)
+{
+	u16 tmp;
+
+	if (__ax88179_read_cmd(dev, AX_ACCESS_EEPROM, 0x43, 1, 2,
+			    &tmp, in_pm) < 0)
+		return 0;
+
+	if ((tmp == 0xFFFF) || (!(tmp & 0x0100)))
+		return 0;
+
+	/* Enable Auto Detach bit */
+	tmp = 0;
+	__ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT,
+			1, 1, &tmp, in_pm);
+	tmp |= AX_CLK_SELECT_ULR;
+	__ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT,
+			 1, 1, &tmp, in_pm);
+
+	__ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL,
+			2, 2, &tmp, in_pm);
+	tmp |= AX_PHYPWR_RSTCTL_AT;
+	__ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL,
+			 2, 2, &tmp, in_pm);
+
+	return 0;
+}
+
+static int ax88179_resume(struct usb_interface *intf)
+{
+	struct usbnet *dev = usb_get_intfdata(intf);
+	u16 tmp16;
+
+	netif_carrier_off(dev->net);
+
+	/* Power up ethernet PHY */
+	tmp16 = 0;
+	ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL,
+			    2, 2, &tmp16);
+	udelay(1000);
+
+	tmp16 = AX_PHYPWR_RSTCTL_IPRL;
+	ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL,
+			    2, 2, &tmp16);
+	msleep(200);
+
+	/* Ethernet PHY Auto Detach*/
+	ax88179_auto_detach(dev, 1);
+
+	/* enable clock */
+	ax88179_read_cmd_nopm(dev, AX_ACCESS_MAC,  AX_CLK_SELECT, 1, 1, &tmp16);
+	tmp16 |= AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS;
+	ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp16);
+	msleep(100);
+
+	/* Configure RX control register => start operation */
+	tmp16 = AX_RX_CTL_DROPCRCERR | AX_RX_CTL_IPE | AX_RX_CTL_START
+		| AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB;
+	ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &tmp16);
+
+	return usbnet_resume(intf);
+}
+
+static void
+ax88179_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
+{
+	struct usbnet *dev = netdev_priv(net);
+	u8 opt;
+
+	if (ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD,
+			  1, 1, &opt) < 0) {
+		wolinfo->supported = 0;
+		wolinfo->wolopts = 0;
+		return;
+	}
+
+	wolinfo->supported = WAKE_PHY | WAKE_MAGIC;
+	wolinfo->wolopts = 0;
+	if (opt & AX_MONITOR_MODE_RWLC)
+		wolinfo->wolopts |= WAKE_PHY;
+	if (opt & AX_MONITOR_MODE_RWMP)
+		wolinfo->wolopts |= WAKE_MAGIC;
+}
+
+static int
+ax88179_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
+{
+	struct usbnet *dev = netdev_priv(net);
+	u8 opt = 0;
+
+	if (wolinfo->wolopts & WAKE_PHY)
+		opt |= AX_MONITOR_MODE_RWLC;
+	if (wolinfo->wolopts & WAKE_MAGIC)
+		opt |= AX_MONITOR_MODE_RWMP;
+
+	if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD,
+			   1, 1, &opt) < 0)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int ax88179_get_eeprom_len(struct net_device *net)
+{
+	return AX_EEPROM_LEN;
+}
+
+static int
+ax88179_get_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom,
+		u8 *data)
+{
+	struct usbnet *dev = netdev_priv(net);
+	u16 *eeprom_buff;
+	int first_word, last_word;
+	int i;
+
+	if (eeprom->len == 0)
+		return -EINVAL;
+
+	eeprom->magic = AX88179_EEPROM_MAGIC;
+
+	first_word = eeprom->offset >> 1;
+	last_word = (eeprom->offset + eeprom->len - 1) >> 1;
+
+	eeprom_buff = kmalloc(sizeof(u16) * (last_word - first_word + 1),
+			   GFP_KERNEL);
+	if (!eeprom_buff)
+		return -ENOMEM;
+
+	/* ax88179/178A returns 2 bytes from eeprom on read */
+	for (i = first_word; i <= last_word; i++) {
+		if (ax88179_read_cmd(dev, AX_ACCESS_EEPROM, i, 1, 2,
+				  &(eeprom_buff[i - first_word])) < 0) {
+			kfree(eeprom_buff);
+			return -EIO;
+		}
+	}
+
+	memcpy(data, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len);
+	kfree(eeprom_buff);
+
+	return 0;
+}
+
+static int ax88179_get_settings(struct net_device *net, struct ethtool_cmd *cmd)
+{
+	struct usbnet *dev = netdev_priv(net);
+	return mii_ethtool_gset(&dev->mii, cmd);
+}
+
+static int ax88179_set_settings(struct net_device *net, struct ethtool_cmd *cmd)
+{
+	struct usbnet *dev = netdev_priv(net);
+	return mii_ethtool_sset(&dev->mii, cmd);
+}
+
+
+static int ax88179_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
+{
+	struct usbnet *dev = netdev_priv(net);
+	return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
+}
+
+static struct ethtool_ops ax88179_ethtool_ops = {
+	.get_link		= ethtool_op_get_link,
+	.get_msglevel		= usbnet_get_msglevel,
+	.set_msglevel		= usbnet_set_msglevel,
+	.get_wol		= ax88179_get_wol,
+	.set_wol		= ax88179_set_wol,
+	.get_eeprom_len		= ax88179_get_eeprom_len,
+	.get_eeprom		= ax88179_get_eeprom,
+	.get_settings		= ax88179_get_settings,
+	.set_settings		= ax88179_set_settings,
+	.nway_reset		= usbnet_nway_reset,
+};
+
+static void ax88179_set_multicast(struct net_device *net)
+{
+	struct usbnet *dev = netdev_priv(net);
+	struct ax88179_data *data = (struct ax88179_data *)dev->data;
+	u8 *m_filter = ((u8 *)dev->data) + 12;
+
+	data->rxctl = (AX_RX_CTL_START | AX_RX_CTL_AB | AX_RX_CTL_IPE);
+
+	if (net->flags & IFF_PROMISC) {
+		data->rxctl |= AX_RX_CTL_PRO;
+	} else if (net->flags & IFF_ALLMULTI
+		   || netdev_mc_count(net) > AX_MAX_MCAST) {
+		data->rxctl |= AX_RX_CTL_AMALL;
+	} else if (netdev_mc_empty(net)) {
+		/* just broadcast and directed */
+	} else {
+		/* We use the 20 byte dev->data for our 8 byte filter buffer
+		 * to avoid allocating memory that is tricky to free later
+		 */
+		u32 crc_bits;
+		struct netdev_hw_addr *ha;
+
+		memset(m_filter, 0, AX_MCAST_FLTSIZE);
+
+		netdev_for_each_mc_addr(ha, net) {
+			crc_bits = ether_crc(ETH_ALEN, ha->addr) >> 26;
+			*(m_filter + (crc_bits >> 3)) |= (1 << (crc_bits & 7));
+		}
+
+		ax88179_write_cmd_async(dev, AX_ACCESS_MAC, AX_MULFLTARY,
+				  AX_MCAST_FLTSIZE, AX_MCAST_FLTSIZE, m_filter);
+
+		data->rxctl |= AX_RX_CTL_AM;
+	}
+
+	ax88179_write_cmd_async(dev, AX_ACCESS_MAC, AX_RX_CTL,
+			     2, 2, &data->rxctl);
+}
+
+static int
+ax88179_set_features(struct net_device *net, netdev_features_t features)
+{
+	u8 tmp;
+	struct usbnet *dev = netdev_priv(net);
+	netdev_features_t changed = net->features ^ features;
+
+	if (changed & NETIF_F_TSO)
+		net->features ^= NETIF_F_TSO;
+
+	if (changed & NETIF_F_SG)
+		net->features ^= NETIF_F_SG;
+
+	if (changed & NETIF_F_IP_CSUM) {
+		ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &tmp);
+		tmp ^= AX_TXCOE_TCP | AX_TXCOE_UDP;
+		ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &tmp);
+		net->features ^= NETIF_F_IP_CSUM;
+	}
+
+	if (changed & NETIF_F_IPV6_CSUM) {
+		ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &tmp);
+		tmp ^= AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6;
+		ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &tmp);
+		net->features ^= NETIF_F_IPV6_CSUM;
+	}
+
+	if (changed & NETIF_F_RXCSUM) {
+		ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, &tmp);
+		tmp ^= AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP |
+		       AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6;
+		ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, &tmp);
+		net->features ^= NETIF_F_RXCSUM;
+	}
+
+	return 0;
+}
+
+static int ax88179_set_mac_addr(struct net_device *net, void *p)
+{
+	struct usbnet *dev = netdev_priv(net);
+	struct sockaddr *addr = p;
+
+	if (netif_running(net))
+		return -EBUSY;
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EADDRNOTAVAIL;
+
+	memcpy(net->dev_addr, addr->sa_data, ETH_ALEN);
+
+	/* Set the MAC address */
+	return ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN,
+			      ETH_ALEN, net->dev_addr);
+}
+
+static const struct net_device_ops ax88179_netdev_ops = {
+	.ndo_open		= usbnet_open,
+	.ndo_stop		= usbnet_stop,
+	.ndo_start_xmit		= usbnet_start_xmit,
+	.ndo_tx_timeout		= usbnet_tx_timeout,
+	.ndo_change_mtu		= usbnet_change_mtu,
+	.ndo_set_mac_address	= ax88179_set_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_do_ioctl		= ax88179_ioctl,
+	.ndo_set_rx_mode	= ax88179_set_multicast,
+	.ndo_set_features	= ax88179_set_features,
+};
+
+static int ax88179_check_eeprom(struct usbnet *dev)
+{
+	u8 i;
+	u8 buf;
+	u8 eeprom[20];
+	u16 csum, delay = HZ / 10;
+	unsigned long jtimeout;
+
+	/* Read EEPROM content */
+	for (i = 0; i < 6; i++) {
+		buf = i;
+		if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_SROM_ADDR,
+				   1, 1, &buf) < 0)
+			return -EINVAL;
+
+		buf = EEP_RD;
+		if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_SROM_CMD,
+				   1, 1, &buf) < 0)
+			return -EINVAL;
+
+		jtimeout = jiffies + delay;
+		do {
+			ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_CMD,
+				      1, 1, &buf);
+
+			if (time_after(jiffies, jtimeout))
+				return -EINVAL;
+
+		} while (buf & EEP_BUSY);
+
+		ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_DATA_LOW,
+			      2, 2, &eeprom[i * 2]);
+
+		if ((i == 0) && (eeprom[0] == 0xFF))
+			return -EINVAL;
+	}
+
+	csum = eeprom[6] + eeprom[7] + eeprom[8] + eeprom[9];
+	csum = (csum >> 8) + (csum & 0xff);
+	if ((csum + eeprom[10]) != 0xff)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int ax88179_check_efuse(struct usbnet *dev, u16 *ledmode)
+{
+	u8	i;
+	u8	efuse[64];
+	u16	csum = 0;
+
+	if (ax88179_read_cmd(dev, AX_ACCESS_EFUS, 0, 64, 64, efuse) < 0)
+		return -EINVAL;
+
+	if (*efuse == 0xFF)
+		return -EINVAL;
+
+	for (i = 0; i < 64; i++)
+		csum = csum + efuse[i];
+
+	while (csum > 255)
+		csum = (csum & 0x00FF) + ((csum >> 8) & 0x00FF);
+
+	if (csum != 0xFF)
+		return -EINVAL;
+
+	*ledmode = (efuse[51] << 8) | efuse[52];
+
+	return 0;
+}
+
+static int ax88179_convert_old_led(struct usbnet *dev, u16 *ledvalue)
+{
+	u16 led;
+
+	/* Loaded the old eFuse LED Mode */
+	if (ax88179_read_cmd(dev, AX_ACCESS_EEPROM, 0x3C, 1, 2, &led) < 0)
+		return -EINVAL;
+
+	led >>= 8;
+
+	switch (led) {
+	case 0xFF:
+		led = LED0_ACTIVE | LED1_LINK_10 | LED1_LINK_100 |
+			LED1_LINK_1000 | LED2_ACTIVE | LED2_LINK_10 |
+			LED2_LINK_100 | LED2_LINK_1000 | LED_VALID;
+		break;
+	case 0xFE:
+		led = LED0_ACTIVE | LED1_LINK_1000 | LED2_LINK_100 | LED_VALID;
+		break;
+	case 0xFD:
+		led = LED0_ACTIVE | LED1_LINK_1000 | LED2_LINK_100 |
+			LED2_LINK_10 | LED_VALID;
+		break;
+	case 0xFC:
+		led = LED0_ACTIVE | LED1_ACTIVE | LED1_LINK_1000 | LED2_ACTIVE |
+				LED2_LINK_100 | LED2_LINK_10 | LED_VALID;
+		break;
+	default:
+		led = LED0_ACTIVE | LED1_LINK_10 | LED1_LINK_100 |
+			LED1_LINK_1000 | LED2_ACTIVE | LED2_LINK_10 |
+			LED2_LINK_100 | LED2_LINK_1000 | LED_VALID;
+		break;
+	}
+
+	*ledvalue = led;
+
+	return 0;
+}
+
+static int ax88179_led_setting(struct usbnet *dev)
+{
+	u8 ledfd, value = 0;
+	u16 tmp, ledact, ledlink, ledvalue = 0, delay = HZ / 10;
+	unsigned long jtimeout;
+
+	/* Check AX88179 version. UA1 or UA2*/
+	ax88179_read_cmd(dev, AX_ACCESS_MAC, GENERAL_STATUS, 1, 1, &value);
+
+	if (!(value & AX_SECLD)) {	/* UA1 */
+		value = AX_GPIO_CTRL_GPIO3EN | AX_GPIO_CTRL_GPIO2EN |
+		    AX_GPIO_CTRL_GPIO1EN;
+		if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_GPIO_CTRL,
+				   1, 1, &value) < 0)
+			return -EINVAL;
+	}
+
+	/* Check EEPROM */
+	if (!ax88179_check_eeprom(dev)) {
+		value = 0x42;
+		if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_SROM_ADDR,
+				   1, 1, &value) < 0)
+			return -EINVAL;
+
+		value = EEP_RD;
+		if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_SROM_CMD,
+				   1, 1, &value) < 0)
+			return -EINVAL;
+
+		jtimeout = jiffies + delay;
+		do {
+			ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_CMD,
+				      1, 1, &value);
+
+			if (time_after(jiffies, jtimeout))
+				return -EINVAL;
+
+		} while (value & EEP_BUSY);
+
+		ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_DATA_HIGH,
+			      1, 1, &value);
+		ledvalue = (value << 8);
+
+		ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_DATA_LOW,
+			      1, 1, &value);
+		ledvalue |= value;
+
+		/* load internal ROM for defaule setting */
+		if ((ledvalue == 0xFFFF) || ((ledvalue & LED_VALID) == 0))
+			ax88179_convert_old_led(dev, &ledvalue);
+
+	} else if (!ax88179_check_efuse(dev, &ledvalue)) {
+		if ((ledvalue == 0xFFFF) || ((ledvalue & LED_VALID) == 0))
+			ax88179_convert_old_led(dev, &ledvalue);
+	} else {
+		ax88179_convert_old_led(dev, &ledvalue);
+	}
+
+	tmp = GMII_PHY_PGSEL_EXT;
+	ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+		       GMII_PHY_PAGE_SELECT, 2, &tmp);
+
+	tmp = 0x2c;
+	ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+		       GMII_PHYPAGE, 2, &tmp);
+
+	ax88179_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, GMII_LED_ACT,
+		      2, &ledact);
+
+	ax88179_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+		      GMII_LED_LINK, 2, &ledlink);
+
+	ledact &= GMII_LED_ACTIVE_MASK;
+	ledlink &= GMII_LED_LINK_MASK;
+
+	if (ledvalue & LED0_ACTIVE)
+		ledact |= GMII_LED0_ACTIVE;
+
+	if (ledvalue & LED1_ACTIVE)
+		ledact |= GMII_LED1_ACTIVE;
+
+	if (ledvalue & LED2_ACTIVE)
+		ledact |= GMII_LED2_ACTIVE;
+
+	if (ledvalue & LED0_LINK_10)
+		ledlink |= GMII_LED0_LINK_10;
+
+	if (ledvalue & LED1_LINK_10)
+		ledlink |= GMII_LED1_LINK_10;
+
+	if (ledvalue & LED2_LINK_10)
+		ledlink |= GMII_LED2_LINK_10;
+
+	if (ledvalue & LED0_LINK_100)
+		ledlink |= GMII_LED0_LINK_100;
+
+	if (ledvalue & LED1_LINK_100)
+		ledlink |= GMII_LED1_LINK_100;
+
+	if (ledvalue & LED2_LINK_100)
+		ledlink |= GMII_LED2_LINK_100;
+
+	if (ledvalue & LED0_LINK_1000)
+		ledlink |= GMII_LED0_LINK_1000;
+
+	if (ledvalue & LED1_LINK_1000)
+		ledlink |= GMII_LED1_LINK_1000;
+
+	if (ledvalue & LED2_LINK_1000)
+		ledlink |= GMII_LED2_LINK_1000;
+
+	tmp = ledact;
+	ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, GMII_LED_ACT,
+		       2, &tmp);
+
+	tmp = ledlink;
+	ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, GMII_LED_LINK,
+		       2, &tmp);
+
+	tmp = GMII_PHY_PGSEL_PAGE0;
+	ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+		       GMII_PHY_PAGE_SELECT, 2, &tmp);
+
+	/* LED full duplex setting */
+	ledfd = 0;
+	if (ledvalue & LED0_FD)
+		ledfd |= 0x01;
+	else if ((ledvalue & LED0_USB3_MASK) == 0)
+		ledfd |= 0x02;
+
+	if (ledvalue & LED1_FD)
+		ledfd |= 0x04;
+	else if ((ledvalue & LED1_USB3_MASK) == 0)
+		ledfd |= 0x08;
+
+	if (ledvalue & LED2_FD)
+		ledfd |= 0x10;
+	else if ((ledvalue & LED2_USB3_MASK) == 0)
+		ledfd |= 0x20;
+
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_LEDCTRL, 1, 1, &ledfd);
+
+	return 0;
+}
+
+static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+	u8 buf[5];
+	u16 *tmp16;
+	u8 *tmp;
+	struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data;
+
+	usbnet_get_endpoints(dev, intf);
+
+	tmp16 = (u16 *)buf;
+	tmp = (u8 *)buf;
+
+	memset(ax179_data, 0, sizeof(*ax179_data));
+
+	/* Power up ethernet PHY */
+	*tmp16 = 0;
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16);
+	*tmp16 = AX_PHYPWR_RSTCTL_IPRL;
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16);
+	msleep(200);
+
+	*tmp = AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS;
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, tmp);
+	msleep(100);
+
+	ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN,
+		      ETH_ALEN, dev->net->dev_addr);
+	memcpy(dev->net->perm_addr, dev->net->dev_addr, ETH_ALEN);
+
+	/* RX bulk configuration */
+	memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5);
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp);
+	dev->rx_urb_size = 1024 * 20;
+
+	*tmp = 0x34;
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_LOW, 1, 1, tmp);
+
+	*tmp = 0x52;
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH,
+		       1, 1, tmp);
+
+	dev->net->hard_header_len += 12;
+	dev->net->netdev_ops = &ax88179_netdev_ops;
+	dev->net->ethtool_ops = &ax88179_ethtool_ops;
+	dev->net->needed_headroom = 8;
+
+	/* Initialize MII structure */
+	dev->mii.dev = dev->net;
+	dev->mii.mdio_read = ax88179_mdio_read;
+	dev->mii.mdio_write = ax88179_mdio_write;
+	dev->mii.phy_id_mask = 0xff;
+	dev->mii.reg_num_mask = 0xff;
+	dev->mii.phy_id = 0x03;
+	dev->mii.supports_gmii = 1;
+
+	dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+			      NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO;
+
+	dev->net->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+				 NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO;
+
+	/* Enable checksum offload */
+	*tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP |
+	       AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6;
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, tmp);
+
+	*tmp = AX_TXCOE_IP | AX_TXCOE_TCP | AX_TXCOE_UDP |
+	       AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6;
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, tmp);
+
+	/* Configure RX control register => start operation */
+	*tmp16 = AX_RX_CTL_DROPCRCERR | AX_RX_CTL_IPE | AX_RX_CTL_START |
+		 AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB;
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, 0x0b, 2, 2, tmp16);
+
+	*tmp = AX_MONITOR_MODE_PMETYPE | AX_MONITOR_MODE_PMEPOL |
+	       AX_MONITOR_MODE_RWMP;
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD, 1, 1, tmp);
+
+	/* Configure default medium type => giga */
+	*tmp16 = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN |
+		 AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_ALWAYS_ONE |
+		 AX_MEDIUM_FULL_DUPLEX | AX_MEDIUM_GIGAMODE;
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+		       2, 2, tmp16);
+
+	ax88179_led_setting(dev);
+
+	/* Restart autoneg */
+	mii_nway_restart(&dev->mii);
+
+	netif_carrier_off(dev->net);
+
+	return 0;
+}
+
+static void ax88179_unbind(struct usbnet *dev, struct usb_interface *intf)
+{
+	u16 tmp16;
+
+	/* Configure RX control register => stop operation */
+	tmp16 = AX_RX_CTL_STOP;
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &tmp16);
+
+	tmp16 = 0;
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp16);
+
+	/* Power down ethernet PHY */
+	tmp16 = 0;
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &tmp16);
+}
+
+static void
+ax88179_rx_checksum(struct sk_buff *skb, struct ax88179_rx_pkt_header *pkt_hdr)
+{
+	skb->ip_summed = CHECKSUM_NONE;
+
+	/* checksum error bit is set */
+	if (pkt_hdr->l3_csum_err || pkt_hdr->l4_csum_err)
+		return;
+
+	/* It must be a TCP or UDP packet with a valid checksum */
+	if ((pkt_hdr->l4_type == AX_RXHDR_L4_TYPE_TCP) ||
+	    (pkt_hdr->l4_type == AX_RXHDR_L4_TYPE_UDP))
+		skb->ip_summed = CHECKSUM_UNNECESSARY;
+}
+
+static int ax88179_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+	struct sk_buff *ax_skb;
+	int pkt_cnt;
+	u32 rx_hdr;
+	u16 hdr_off;
+	struct ax88179_rx_pkt_header *pkt_hdr;
+
+	skb_trim(skb, skb->len - 4);
+	memcpy(&rx_hdr, skb_tail_pointer(skb), sizeof(rx_hdr));
+	le32_to_cpus(&rx_hdr);
+
+	pkt_cnt = (u16)rx_hdr;
+	hdr_off = (u16)(rx_hdr >> 16);
+	pkt_hdr = (struct ax88179_rx_pkt_header *)(skb->data + hdr_off);
+
+	while (pkt_cnt--) {
+
+		u16 pkt_len;
+
+		le32_to_cpus((u32 *)pkt_hdr);
+		pkt_len = pkt_hdr->len;
+
+		/* Check CRC or runt packet */
+		if (pkt_hdr->crc || pkt_hdr->drop) {
+			skb_pull(skb, (pkt_len + 7) & 0xFFF8);
+			pkt_hdr++;
+			continue;
+		}
+
+		if (pkt_cnt == 0) {
+			/* Skip IP alignment psudo header */
+			skb_pull(skb, 2);
+			skb->len = pkt_len;
+			skb_set_tail_pointer(skb, pkt_len);
+			skb->truesize = pkt_len + sizeof(struct sk_buff);
+			ax88179_rx_checksum(skb, pkt_hdr);
+			return 1;
+		}
+
+		ax_skb = skb_clone(skb, GFP_ATOMIC);
+		if (ax_skb) {
+			ax_skb->len = pkt_len;
+			ax_skb->data = skb->data + 2;
+			skb_set_tail_pointer(ax_skb, pkt_len);
+			ax_skb->truesize = pkt_len + sizeof(struct sk_buff);
+			ax88179_rx_checksum(ax_skb, pkt_hdr);
+			usbnet_skb_return(dev, ax_skb);
+		} else {
+			return 0;
+		}
+
+		skb_pull(skb, (pkt_len + 7) & 0xFFF8);
+		pkt_hdr++;
+	}
+
+	return 1;
+}
+
+static struct sk_buff *
+ax88179_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
+{
+	u32 tx_hdr1, tx_hdr2;
+	int frame_size = dev->maxpacket;
+	int mss = skb_shinfo(skb)->gso_size;
+	int headroom;
+	int tailroom;
+
+	tx_hdr1 = skb->len;
+	tx_hdr2 = mss;
+	if (((skb->len + 8) % frame_size) == 0)	{
+		tx_hdr2 |= 0x80008000;	/* Enable padding */
+		skb->len += 2;
+	}
+
+	skb_linearize(skb);
+	headroom = skb_headroom(skb);
+	tailroom = skb_tailroom(skb);
+
+	if (!skb_header_cloned(skb) && !skb_cloned(skb) &&
+				(headroom + tailroom) >= 8) {
+		if (headroom < 8) {
+			skb->data = memmove(skb->head + 8, skb->data, skb->len);
+			skb_set_tail_pointer(skb, skb->len);
+		}
+	} else {
+		struct sk_buff *skb2;
+		skb2 = skb_copy_expand(skb, 8, 0, flags);
+		dev_kfree_skb_any(skb);
+		skb = skb2;
+		if (!skb)
+			return NULL;
+	}
+
+	skb_push(skb, 4);
+	cpu_to_le32s(&tx_hdr2);
+	skb_copy_to_linear_data(skb, &tx_hdr2, 4);
+
+	skb_push(skb, 4);
+	cpu_to_le32s(&tx_hdr1);
+	skb_copy_to_linear_data(skb, &tx_hdr1, 4);
+
+	return skb;
+}
+
+static int ax88179_link_reset(struct usbnet *dev)
+{
+	struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data;
+	u8 tmp[5], link_sts;
+	u16 mode, tmp16, delay = HZ / 10;
+	u32 tmp32 = 0x40000000;
+	unsigned long jtimeout;
+
+	jtimeout = jiffies + delay;
+	while (tmp32 & 0x40000000) {
+		mode = 0;
+		ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &mode);
+		ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2,
+			       &ax179_data->rxctl);
+
+		/*link up, check the usb device control TX FIFO full or empty*/
+		ax88179_read_cmd(dev, 0x81, 0x8c, 0, 4, &tmp32);
+
+		if (time_after(jiffies, jtimeout))
+			return 0;
+	}
+
+	mode = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN |
+	       AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_ALWAYS_ONE;
+
+	ax88179_read_cmd(dev, AX_ACCESS_MAC, PHYSICAL_LINK_STATUS,
+		      1, 1, &link_sts);
+
+	ax88179_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, GMII_PHY_PHYSR,
+		      2, &tmp16);
+
+	if (!(tmp16 & GMII_PHY_PHYSR_LINK)) {
+		return 0;
+	} else if (GMII_PHY_PHYSR_GIGA == (tmp16 & GMII_PHY_PHYSR_SMASK)) {
+		mode |= AX_MEDIUM_GIGAMODE;
+		if (link_sts & AX_USB_SS)
+			memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5);
+		else if (link_sts & AX_USB_HS)
+			memcpy(tmp, &AX88179_BULKIN_SIZE[1], 5);
+		else
+			memcpy(tmp, &AX88179_BULKIN_SIZE[3], 5);
+	} else if (GMII_PHY_PHYSR_100 == (tmp16 & GMII_PHY_PHYSR_SMASK)) {
+		mode |= AX_MEDIUM_PS;
+		if (link_sts & (AX_USB_SS | AX_USB_HS))
+			memcpy(tmp, &AX88179_BULKIN_SIZE[2], 5);
+		else
+			memcpy(tmp, &AX88179_BULKIN_SIZE[3], 5);
+	} else {
+		memcpy(tmp, &AX88179_BULKIN_SIZE[3], 5);
+	}
+
+	/* RX bulk configuration */
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp);
+
+	if (tmp16 & GMII_PHY_PHYSR_FULL)
+		mode |= AX_MEDIUM_FULL_DUPLEX;
+
+	dev->rx_urb_size = (1024 * (*(tmp + 3)));
+
+	mode |= 0x08;
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+		       2, 2, &mode);
+
+	netif_carrier_on(dev->net);
+
+	return 0;
+}
+
+static int ax88179_reset(struct usbnet *dev)
+{
+	u8 buf[5];
+	u16 *tmp16;
+	u8 *tmp;
+
+	tmp16 = (u16 *)buf;
+	tmp = (u8 *)buf;
+
+	/* Power up ethernet PHY */
+	*tmp16 = 0;
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16);
+
+	*tmp16 = AX_PHYPWR_RSTCTL_IPRL;
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16);
+	msleep(200);
+
+	*tmp = AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS;
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, tmp);
+	msleep(100);
+
+	/* Ethernet PHY Auto Detach*/
+	ax88179_auto_detach(dev, 0);
+
+	ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN, ETH_ALEN,
+		      dev->net->dev_addr);
+	memcpy(dev->net->perm_addr, dev->net->dev_addr, ETH_ALEN);
+
+	/* RX bulk configuration */
+	memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5);
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp);
+
+	dev->rx_urb_size = 1024 * 20;
+
+	*tmp = 0x34;
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_LOW, 1, 1, tmp);
+
+	*tmp = 0x52;
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH,
+		       1, 1, tmp);
+
+	dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+			      NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO;
+
+	dev->net->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+				 NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO;
+
+	/* Enable checksum offload */
+	*tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP |
+	       AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6;
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, tmp);
+
+	*tmp = AX_TXCOE_IP | AX_TXCOE_TCP | AX_TXCOE_UDP |
+	       AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6;
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, tmp);
+
+	/* Configure RX control register => start operation */
+	*tmp16 = AX_RX_CTL_DROPCRCERR | AX_RX_CTL_IPE | AX_RX_CTL_START |
+		 AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB;
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, 0x0b, 2, 2, tmp16);
+
+	*tmp = AX_MONITOR_MODE_PMETYPE | AX_MONITOR_MODE_PMEPOL |
+	       AX_MONITOR_MODE_RWMP;
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD, 1, 1, tmp);
+
+	/* Configure default medium type => giga */
+	*tmp16 = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN |
+		 AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_ALWAYS_ONE |
+		 AX_MEDIUM_FULL_DUPLEX | AX_MEDIUM_GIGAMODE;
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+		       2, 2, tmp16);
+
+	ax88179_led_setting(dev);
+
+	/* Restart autoneg */
+	mii_nway_restart(&dev->mii);
+
+	netif_carrier_off(dev->net);
+
+	return 0;
+}
+
+static int ax88179_stop(struct usbnet *dev)
+{
+	u16 tmp16;
+
+	ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+		      2, 2, &tmp16);
+	tmp16 &= ~AX_MEDIUM_RECEIVE_EN;
+	ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+		       2, 2, &tmp16);
+
+	return 0;
+}
+
+static const struct driver_info ax88179_info = {
+	.description = "ASIX AX88179 USB 3.0 Gigibit Ethernet",
+	.bind = ax88179_bind,
+	.unbind = ax88179_unbind,
+	.status = ax88179_status,
+	.link_reset = ax88179_link_reset,
+	.reset = ax88179_reset,
+	.stop = ax88179_stop,
+	.flags = FLAG_ETHER | FLAG_FRAMING_AX,
+	.rx_fixup = ax88179_rx_fixup,
+	.tx_fixup = ax88179_tx_fixup,
+};
+
+static const struct driver_info ax88178a_info = {
+	.description = "ASIX AX88178A USB 2.0 Gigibit Ethernet",
+	.bind = ax88179_bind,
+	.unbind = ax88179_unbind,
+	.status = ax88179_status,
+	.link_reset = ax88179_link_reset,
+	.reset = ax88179_reset,
+	.stop = ax88179_stop,
+	.flags = FLAG_ETHER | FLAG_FRAMING_AX,
+	.rx_fixup = ax88179_rx_fixup,
+	.tx_fixup = ax88179_tx_fixup,
+};
+
+static const struct driver_info sitecom_info = {
+	.description = "Sitecom USB 3.0 to Gigabit Adapter",
+	.bind = ax88179_bind,
+	.unbind = ax88179_unbind,
+	.status = ax88179_status,
+	.link_reset = ax88179_link_reset,
+	.reset = ax88179_reset,
+	.stop = ax88179_stop,
+	.flags = FLAG_ETHER | FLAG_FRAMING_AX,
+	.rx_fixup = ax88179_rx_fixup,
+	.tx_fixup = ax88179_tx_fixup,
+};
+
+static const struct usb_device_id products[] = {
+{
+	/* ASIX AX88179 10/100/1000 */
+	USB_DEVICE(0x0b95, 0x1790),
+	.driver_info = (unsigned long)&ax88179_info,
+}, {
+	/* ASIX AX88178A 10/100/1000 */
+	USB_DEVICE(0x0b95, 0x178a),
+	.driver_info = (unsigned long)&ax88178a_info,
+}, {
+	/* Sitecom USB 3.0 to Gigabit Adapter */
+	USB_DEVICE(0x0df6, 0x0072),
+	.driver_info = (unsigned long) &sitecom_info,
+},
+	{ },
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver asix_driver = {
+	.name =		"ax88179_178a",
+	.id_table =	products,
+	.probe =	usbnet_probe,
+	.suspend =	ax88179_suspend,
+	.resume =	ax88179_resume,
+	.disconnect =	usbnet_disconnect,
+};
+
+static int __init asix_init(void)
+{
+	return usb_register(&asix_driver);
+}
+module_init(asix_init);
+
+static void __exit asix_exit(void)
+{
+	usb_deregister(&asix_driver);
+}
+module_exit(asix_exit);
+
+MODULE_DESCRIPTION("ASIX AX88179/178A based USB 3.0/2.0 Gigabit Ethernet Devices");
+MODULE_LICENSE("GPL");
+
-- 
1.7.9.5

^ permalink raw reply related

* Re: v3 for tcp friends?
From: Li Yu @ 2013-01-23  3:14 UTC (permalink / raw)
  To: Bruce Curtis; +Cc: David Miller, netdev
In-Reply-To: <CAEkNxbH0MAAU9oiwwrFTbMJP1yzfNdxD5NDdZOqGnvhTLvodoQ@mail.gmail.com>

于 2013年01月23日 05:08, Bruce Curtis 写道:
> Thanks, Li
> 
> Started working on friends again, v4, more soon.
> 
> 

:)

I found another odd bug in TCP friends v3, the clients
may hang at tcp_sendmsg() -> sk_stream_wait_memory() with or
without my refcnt fix patch.

Below shell script can reproduce this bug:

#! /bin/sh -x

sysctl -w net.ipv4.tcp_rmem="4096 1073741824 1073741824"
sysctl -w net.ipv4.tcp_wmem="4096 1073741824 1073741824"

sysctl -w net.ipv4.tcp_friends=1

msg=64K
buf=256M

pkill -9 netserver
netserver
netperf -t TCP_STREAM -l 1 -- -m ${msg} -M ${msg} -s ${buf} -S ${buf} -4

sysctl -w net.ipv4.tcp_friends=0
pkill -9 netserver
netserver
netperf -t TCP_STREAM -l 1 -- -m ${msg} -M ${msg} -s ${buf} -S ${buf} -4
##################SCRIPT END###################

netperf kernel stack is (by cat /proc/$netperf_pid/stack)

[<ffffffff812ce939>] sk_stream_wait_memory+0x2d9/0x2f0
[<ffffffff8131460c>] tcp_sendmsg+0xf6c/0x1240
[<ffffffff8133c117>] inet_sendmsg+0xf7/0x110
[<ffffffff812bedfd>] sock_sendmsg+0x7d/0xa0
[<ffffffff812c0e4d>] sys_sendto+0x13d/0x190
[<ffffffff8138a6c2>] system_call_fastpath+0x16/0x1b
[<ffffffffffffffff>] 0xffffffffffffffff

netserver kernel stack is :

[<ffffffff812c46ae>] sk_wait_data+0x8e/0xe0
[<ffffffff81315993>] tcp_recvmsg+0x5c3/0xbe0
[<ffffffff8133aefd>] inet_recvmsg+0xed/0x110
[<ffffffff812becf4>] sock_recvmsg+0x84/0xb0
[<ffffffff812c0fae>] sys_recvfrom+0xee/0x170
[<ffffffff8138a6c2>] system_call_fastpath+0x16/0x1b
[<ffffffffffffffff>] 0xffffffffffffffff

And, "netstat -tnp" give us below results:

Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address
State       PID/Program name
tcp        0      0 127.0.0.1:35451         127.0.0.1:12865
ESTABLISHED 2316/netperf
tcp6       0      0 127.0.0.1:12865         127.0.0.1:35451
ESTABLISHED 2317/netserver

(It seems that netperf hangs on the control connection of benchmark)

I also try to fix this ...

Thanks

Yu

> On Mon, Jan 21, 2013 at 12:55 AM, Li Yu <raise.sail@gmail.com 
> <mailto:raise.sail@gmail.com>> wrote:
> 
>     2013/1/21 Li Yu <raise.sail@gmail.com <mailto:raise.sail@gmail.com>>
> 
>         于 2013年01月21日 15:29, Li Yu 写道:
> 
>             于 2012年09月05日 00:58, David Miller 写道:
> 
>                 From: Bruce Curtis <brutus@google.com
>                 <mailto:brutus@google.com>>
>                 Date: Tue, 4 Sep 2012 08:10:23 -0700
> 
>                     Will do, issues addressed, I'll get the patch out
>                     later today or
>                     tomorrow at the latest.
> 
> 
>                 Thanks a lot Bruce.
>                 --
>                 To unsubscribe from this list: send the line
>                 "unsubscribe netdev" in
>                 the body of a message to majordomo@vger.kernel.org
>                 <mailto:majordomo@vger.kernel.org>
>                 More majordomo info at
>                 http://vger.kernel.org/__majordomo-info.html
>                 <http://vger.kernel.org/majordomo-info.html>
> 
> 
> 
>             Hi, Bruce,
> 
>                   I tested the TCP friends, found a bug here:
> 
>             [  106.541372] Pid: 1765, comm: client Not tainted
>             3.7.0-rc1+ #25
>             [  106.543121] Call Trace:
>             [  106.543950]  [<ffffffff8133d212>]
>             inet_sock_destruct+0x102/0x1f0
>             [  106.545687]  [<ffffffff812c38ad>] __sk_free+0x1d/0x110
>             [  106.547209]  [<ffffffff812c3a1c>] sk_free+0x1c/0x20
>             [  106.548611]  [<ffffffff8131680c>] tcp_close+0x6c/0x3f0
>             [  106.549863]  [<ffffffff8133caea>] inet_release+0xda/0xf0
>             [  106.551134]  [<ffffffff8133ca30>] ? inet_release+0x20/0xf0
>             [  106.552419]  [<ffffffff8137f3de>] ? mutex_unlock+0xe/0x10
>             [  106.553658]  [<ffffffff812bf948>] sock_release+0x28/0xa0
>             [  106.557366]  [<ffffffff812bfd69>] sock_close+0x29/0x30
>             [  106.558831]  [<ffffffff81128972>] __fput+0x122/0x210
>             [  106.560541]  [<ffffffff81128a6e>] ____fput+0xe/0x10
>             [  106.562006]  [<ffffffff8105354e>] task_work_run+0x9e/0xd0
>             [  106.563285]  [<ffffffff810027e1>] do_notify_resume+0x61/0x70
>             [  106.564582]  [<ffffffff8138a908>] int_signal+0x12/0x17
> 
> 
>                   I also backported and tested it on stable kernel
>             3.7.3/RHEL6
>             kernel, this bug still exists. It seem that client may close
>             listening
>             sockets, may we need to add one reference count for listen
>             socket
>             before send its address to peer?
> 
> 
>         Sorry, I lost an important line of kernel log before above them:
> 
>         [  106.539367] IPv4: Attempt to release TCP socket in state 10
>         ffff880074abb5c0
> 
>         BTW: state 10 = TCP_LISTEN
> 
> 
>     It seem this patch works for me.
> 
>     diff --git a/net/ipv4/inet_connection_sock.c
>     b/net/ipv4/inet_connection_sock.c
>     index 9641215..a625c02 100644
>     --- a/net/ipv4/inet_connection_sock.c
>     +++ b/net/ipv4/inet_connection_sock.c
>     @@ -623,8 +623,11 @@ struct sock *inet_csk_clone(struct sock *sk,
>     const struct request_sock *req,
>                              sock_hold(newsk);
>                              was = xchg(&req->friend->sk_friend, newsk);
>                              /* If requester already connect()ed, maybe
>     sleeping */
>     -                       if (was && !sock_flag(req->friend, SOCK_DEAD))
>     -                               sk->sk_state_change(req->friend);
>     +                       if (was) {
>     +                               if (!sock_flag(req->friend, SOCK_DEAD))
>     +                                      
>     sk->sk_state_change(req->friend);
>     +                               sock_put(was);
>     +                       }
>                      }
>                      newsk->sk_state = TCP_SYN_RECV;
>     diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
>     index 5917485..7a63245 100644
>     --- a/net/ipv4/tcp_output.c
>     +++ b/net/ipv4/tcp_output.c
>     @@ -2277,8 +2277,10 @@ struct sk_buff *tcp_make_synack(struct sock
>     *sk, struct dst_entry *dst,
>              memset(&opts, 0, sizeof(opts));
>              /* Only try to make friends if enabled */
>     -       if (sysctl_tcp_friends)
>     +       if (sysctl_tcp_friends) {
>     +               sock_hold(sk);
>                      skb->friend = sk;
>     +       }
>       #ifdef CONFIG_SYN_COOKIES
>              if (unlikely(req->cookie_ts))
> 
> 
>                   And, our TCP friends v4? :)
> 
>                   Thanks
> 
>             Yu
> 
> 
> 

^ permalink raw reply

* [Patch net-next] ipv6: remove duplicated declaration of ip6_fragment()
From: Cong Wang @ 2013-01-23  3:22 UTC (permalink / raw)
  To: netdev; +Cc: YOSHIFUJI Hideaki, David S. Miller, Cong Wang

From: Cong Wang <amwang@redhat.com>

It is declared in:
include/net/ip6_route.h:187:int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));

and net/ip6_route.h is already included.

Cc: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: Cong Wang <amwang@redhat.com>

---
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 7eee94c..7dea45a 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -56,8 +56,6 @@
 #include <net/checksum.h>
 #include <linux/mroute6.h>
 
-int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));
-
 int __ip6_local_out(struct sk_buff *skb)
 {
 	int len;

^ permalink raw reply related

* Re: [PATCH net-next 09/15] drivers/net: delete old 8 bit ISA Racal ni5010 support.
From: Andreas Mohr @ 2013-01-23  3:27 UTC (permalink / raw)
  To: Ondrej Zary
  Cc: Jan-Pascal van Best, Paul Gortmaker, David Miller, netdev,
	Andreas Mohr
In-Reply-To: <201301222155.11493.linux@rainbow-software.org>

Hi,

On Tue, Jan 22, 2013 at 09:55:11PM +0100, Ondrej Zary wrote:
> I have BNC network too and use it every day. It's mostly used for internet 
> access, with 3c509 and ne2000 cards (one of the machines has currently uptime 
> of 439 days, it runs kernel 3.1). I remember using HP pclan cards too and 
> they worked fine. Too bad they're going away :(
> Also got a nice 3c503 card a year ago or so. The driver worked fine after a 
> simple fix.
> 
> I really hate when a working driver is removed from Linux. New drivers are 
> either missing (alx) or problematic (various rtl8168/8169 variants, some of 
> which work and some don't). So you can't get any new machine and install 
> Linux. You also can't get any old machine and install Linux. If you're lucky 
> and the machine is somehow middle-aged, everything might work...

I have to ack the "any new machine and install Linux" bit, I'm afraid
(or probably in this case it applies to the middle-aged part).
I'm sitting here with an Aspire One probably sold > 3 million times,
and I'm currently still facing at least the following remaining issues:
- USB SDD connection gets broken *at random* on resume,
  which sometimes causes severe data corruption of the root partition
  [device enumeration?]
- fixed-storage reader resets on every resume, causing the existing mount to get
  broken (unless that happens to be XFS-formatted, it's been said)
- charge status indication is unreliable, at least in recent kernels (I
  didn't notice this issue in older ones) - sometimes simply indicates
  PSU where none is, or indicates battery where PSU is [no idea,
  investigation pending]
- rfkill status is problematic (not accurately visible), most likely due
  to issues presenting the correct state due to a stubbed-out rfkill WMI
  interface during netbook BIOS development (thanks but no thanks Acer)
  [I intend to at least brush up on user-side help texts
  to clearly spell out these machine-side support issues]
- webcam had a nice OOPS issue the last time I was using it (~3.5?)
- microphone array probably not very well-supported (probably still
  needs the "select one channel only" workaround to even get initial
  working recording, not to talk about real array support)
- 3.7 seems to show intermediate CPU lockup message (22s) on Intel GPU
  [when having heavily scrolled console output such as my build converter?]
- I'm sure I forgot something

(not mentioning the many issues that I had to help fixing already
initially, e.g. missing fan control [new acerhdf], firmware loader resume fix,
r8169[hah, there it is again] resume issue, ...)

And that's the status on one formerly extremely widely visible machine only :(


As to other network drivers being incomplete, via-rhine currently has
semi-working resume [to be submitted].

As to "might work", booting any of a selection of well-known live CDs on various
machines is quite likely to get you a blank (either rhetorically or for
real, e.g. due to broken graphics support), too (happened to me on
several occasions).

Unfortunately I don't know what's specifically productive about my reply here,
but at least this content suggests that something is not ending up quite
as well as it could be.
Possibly the only suitable answer is to try to brush up on the rate of
things to get fixed, but myself I'm working on several things already,
thus eventually one will get there, but most likely much slower than it
should be.
If there is something to be fixed about process (perhaps better official
central machine testing efforts?), then anything fruitful
should definitely be done.

Andreas Mohr

^ permalink raw reply

* [Patch net-next] netpoll: fix an uninitialized variable
From: Cong Wang @ 2013-01-23  3:39 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Cong Wang

From: Cong Wang <amwang@redhat.com>

Fengguang reported:

   net/core/netpoll.c: In function 'netpoll_setup':
   net/core/netpoll.c:1049:6: warning: 'err' may be used uninitialized in this function [-Wmaybe-uninitialized]

in !CONFIG_IPV6 case, we may error out without initializing
'err'.

Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: Cong Wang <amwang@redhat.com>

---
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index a9b1004..e2f79a1 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -1140,6 +1140,7 @@ int netpoll_setup(struct netpoll *np)
 #else
 			np_err(np, "IPv6 is not supported %s, aborting\n",
 			       np->dev_name);
+			err = -EINVAL;
 			goto put;
 #endif
 		}

^ permalink raw reply related

* Re: [PATCH net-next] drivers/net/ethernet/micrel/ks8851_mll: Implement basic statistics
From: Joe Perches @ 2013-01-23  3:57 UTC (permalink / raw)
  To: David Miller; +Cc: David.Choi, netdev, Ping.Doong
In-Reply-To: <20130122.205132.2281610193783011537.davem@davemloft.net>

On Tue, 2013-01-22 at 20:51 -0500, David Miller wrote:
> BTW it's inappropriate to log an SKB allocation failure as an error in
> the kernel logs like this.  This can be completely normal on a heavily
> loaded system.  People can look at the device statistics to learn about
> this event, or use a more sophisticated tool like the drop monitor.

There are many of these still around, though
hardly any in modern drivers.

I get this file list in drivers/net/ of
alloc_skb failures followed by printks:

Almost all of these are pretty old and are
probably best described as "don't bother".

Maybe the realtek.

drivers/net/appletalk/cops.c
drivers/net/can/grcan.c
drivers/net/can/mcp251x.c
drivers/net/can/mscan/mscan.c
drivers/net/ethernet/adi/bfin_mac.c
drivers/net/ethernet/aeroflex/greth.c
drivers/net/ethernet/amd/7990.c
drivers/net/ethernet/amd/a2065.c
drivers/net/ethernet/amd/am79c961a.c
drivers/net/ethernet/amd/au1000_eth.c
drivers/net/ethernet/amd/declance.c
drivers/net/ethernet/amd/ni65.c
drivers/net/ethernet/amd/sunlance.c
drivers/net/ethernet/cadence/at91_ether.c
drivers/net/ethernet/cirrus/cs89x0.c
drivers/net/ethernet/cirrus/mac89x0.c
drivers/net/ethernet/ethoc.c
drivers/net/ethernet/freescale/fec.c
drivers/net/ethernet/freescale/fec_mpc52xx.c
drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
drivers/net/ethernet/fujitsu/fmvj18x_cs.c
drivers/net/ethernet/i825xx/82596.c
drivers/net/ethernet/i825xx/lib82596.c
drivers/net/ethernet/microchip/enc28j60.c
drivers/net/ethernet/natsemi/sonic.c
drivers/net/ethernet/netx-eth.c
drivers/net/ethernet/nuvoton/w90p910_ether.c
drivers/net/ethernet/realtek/8139too.c
drivers/net/ethernet/realtek/atp.c
drivers/net/ethernet/seeq/sgiseeq.c
drivers/net/ethernet/sis/sis900.c
drivers/net/ethernet/smsc/smc9194.c
drivers/net/ethernet/smsc/smc91c92_cs.c
drivers/net/ethernet/smsc/smc91x.c
drivers/net/ethernet/xilinx/xilinx_emaclite.c
drivers/net/ethernet/xircom/xirc2ps_cs.c
drivers/net/hamradio/baycom_epp.c
drivers/net/hamradio/hdlcdrv.c
drivers/net/hamradio/mkiss.c
drivers/net/hippi/rrunner.c
drivers/net/irda/pxaficp_ir.c
drivers/net/sb1000.c
drivers/net/slip/slip.c
drivers/net/usb/ipheth.c
drivers/net/wan/cosa.c
drivers/net/wan/sdla.c
drivers/net/wan/x25_asy.c
drivers/net/wan/z85230.c
drivers/net/wimax/i2400m/netdev.c
drivers/net/wireless/ray_cs.c
drivers/net/wireless/wl3501_cs.c

^ permalink raw reply

* Re: [PATCH] skb: add a comment to skb_csum_unnecessary to avoid miuse
From: David Miller @ 2013-01-23  4:13 UTC (permalink / raw)
  To: sanagi.koki; +Cc: netdev
In-Reply-To: <F6CB40852BC6EF489E0AA83EFF537F470876B9FD@G01JPEXMBYT04>

From: "Sanagi, Koki" <sanagi.koki@jp.fujitsu.com>
Date: Wed, 23 Jan 2013 02:32:52 +0000

>> From: Koki Sanagi <sanagi.koki@jp.fujitsu.com>
>> Date: Wed, 23 Jan 2013 09:30:16 +0900
>> 
>> > Due to its name and appearance, someone thinks this only checks if
>> > ip_summed is CHECKSUM_UNNECESARRY.  But actually, this returns true
>> > even if ip_summed is CHECKSUM_PARTIAL.  To avoid misuse, this patch a
>> > comment which specifies that CHECKSUM_PARTIAL is OK.
>> >
>> > Signed-off-by: Koki Sanagi <sanagi.koki@jp.fujitsu.com>
>> 
>> I'm not applying this, sorry.  It's a one line function and it's not so
>> non-obvious that it deserves an 8 line comment.
> 
> OK.  I just felt weird that CHECKSUM_* is not bit flag but this function handles
> it as if it was bit flag.

The function name says what it does, it determines whether a checksum
is necessary or not.  How that is implemented is another issue.

^ permalink raw reply

* Re: [PATCH, resubmit] ax88179_178a: ASIX AX88179_178A USB 3.0/2.0 to gigabit ethernet adapter driver
From: David Miller @ 2013-01-23  4:15 UTC (permalink / raw)
  To: freddy; +Cc: netdev, linux-usb, linux-kernel, louis
In-Reply-To: <1358908337-13841-1-git-send-email-freddy@asix.com.tw>

From: Freddy Xin <freddy@asix.com.tw>
Date: Wed, 23 Jan 2013 10:32:17 +0800

> Fixed coding style errors.

There are still many style issues remaining, you have a lot more
work to do, for example:

> +	return fn(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
> +	       value, index, data, size);
> +

This empty line is unnecessary, get rid of it.

Also this function call is not indented properly.  The first character
on the second line of the fn() call should line up with the first
column after the openning parenthesis of the first line of the call.

^ permalink raw reply

* Re: [PATCH net-next] drivers/net/ethernet/micrel/ks8851_mll: Implement basic statistics
From: David Miller @ 2013-01-23  4:17 UTC (permalink / raw)
  To: joe; +Cc: David.Choi, netdev, Ping.Doong
In-Reply-To: <1358913454.2107.16.camel@joe-AO722>

From: Joe Perches <joe@perches.com>
Date: Tue, 22 Jan 2013 19:57:34 -0800

> On Tue, 2013-01-22 at 20:51 -0500, David Miller wrote:
>> BTW it's inappropriate to log an SKB allocation failure as an error in
>> the kernel logs like this.  This can be completely normal on a heavily
>> loaded system.  People can look at the device statistics to learn about
>> this event, or use a more sophisticated tool like the drop monitor.
> 
> There are many of these still around, though
> hardly any in modern drivers.

Right.

> I get this file list in drivers/net/ of
> alloc_skb failures followed by printks:
> 
> Almost all of these are pretty old and are
> probably best described as "don't bother".

Be also careful to not match the ones that are done to
do something like the initial RX ring filling during
device open.

If such an allocation failure causes device open to fail,
that's a legitimate situation in which to log.

^ permalink raw reply

* Re: [PATCH 2/2] IP_GRE: Linearize skb before csum.
From: David Miller @ 2013-01-23  4:22 UTC (permalink / raw)
  To: eric.dumazet; +Cc: jesse, pshelar, netdev
In-Reply-To: <20130122.204629.607263597214211092.davem@davemloft.net>

From: David Miller <davem@davemloft.net>
Date: Tue, 22 Jan 2013 20:46:29 -0500 (EST)

> We can't emit bogus checksums on the wire when this is completely
> under our control.

BTW consider a legitimate use case where an application has a shared
memory page between threads that keeps track of statistic counters,
and it uses sendfile() over an fd backing that mmap()'d area to
send the statistics out remotely over TCP.

That's completely legitimate.

As is an application constantly overwriting a page in the filesystem
page cache, and another app doing sendfile() over TCP from that
area.

In such a situation everyone of your magic retransmits will have a
bad checksum too.

You can't say that this behavior is anything other than broken, and
I don't want to be responsible for a system that's doing broken
things like that.

If your GSO over GRE tunnels stuff fundamentally depends upon this
magic retransmit fantasy working, then yes we have to disable it
completely.

^ permalink raw reply


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