* I need your help please
From: sarah.montembault @ 2013-03-02 16:34 UTC (permalink / raw)
I am Julia Jenkins the wife of Late Mr.Terry Jenkins A white farmer that was shot
dead in Zimbabwe by "war veterans. Please i need your help. Please contact me on
my email mrs.juliajenkinss@kelebek.gen.tr
^ permalink raw reply
* [PATCH] caif_dev: fix sparse warnings for caif_flow_cb
From: Silviu-Mihai Popescu @ 2013-03-02 19:45 UTC (permalink / raw)
To: netdev; +Cc: sjur.brandeland, davem, linux-kernel
This fixed the following sparse warning:
net/caif/caif_dev.c:121:6: warning: symbol 'caif_flow_cb' was not
declared. Should it be static?
Signed-off-by: Silviu-Mihai Popescu <silviupopescu1990@gmail.com>
---
net/caif/caif_dev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c
index 1ae1d9c..21760f0 100644
--- a/net/caif/caif_dev.c
+++ b/net/caif/caif_dev.c
@@ -118,7 +118,7 @@ static struct caif_device_entry *caif_get(struct net_device *dev)
return NULL;
}
-void caif_flow_cb(struct sk_buff *skb)
+static void caif_flow_cb(struct sk_buff *skb)
{
struct caif_device_entry *caifd;
void (*dtor)(struct sk_buff *skb) = NULL;
--
1.7.9.5
^ permalink raw reply related
* Re: tg3: regression of netdev stats
From: Nithin Nayak Sujir @ 2013-03-02 18:56 UTC (permalink / raw)
To: OGAWA Hirofumi; +Cc: Michael Chan, davem, netdev
In-Reply-To: <87txouwcf8.fsf@devron.myhome.or.jp>
On 3/1/2013 10:20 PM, OGAWA Hirofumi wrote:
> OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> writes:
>
>> zero). But, e.g. ping/nfs itself works fine.
>>
>> BTW, chip is
>>
>> 02:00.0 Ethernet controller [0200]: Broadcom Corporation NetLink BCM57788 Gigabit Ethernet PCIe [14e4:1691] (rev 01)
>>
>> tg3 0000:02:00.0 eth0: Tigon3 [partno(BCM57788) rev 57780001] (PCI Express) MAC address d4:be:d9:a6:a3:3b
>> tg3 0000:02:00.0 eth0: attached PHY driver [Broadcom BCM57780] (mii_bus:phy_addr=200:01)
>
> With some read, this chip seems to be using PHYLIB, and PHYLIB modify
> carrier state, so ->link_up confuses with it?
>
Yes, this may be relevant. I'll investigate further with this device.
> Thanks.
>
^ permalink raw reply
* atl1c: DMA: Out of SW-IOMMU space
From: Andre Heider @ 2013-03-02 17:28 UTC (permalink / raw)
To: netdev, xiong
Hi,
my "AR8151 v2.0 Gigabit Ethernet (rev c0)" becomes unusable on v3.8
after some usage.
It's easily reproducible with "dd if=/dev/zero of=<nfsshare>/test
bs=1M count=2048. Point of failure varies, but somewhat after >1.5gb
of data written to the nfs server dmesg gets spammed with "DMA: Out of
SW-IOMMU space for x bytes at device 0000:06:00.0" (where x varies)
and all sorts of follow up problems start occurring.
Apparently I'm not the only one affected:
https://www.google.com/search?q=atl1c+%22DMA%3A+Out+of+SW-IOMMU+space%22
The problem doesn't exist on v3.8-rc7.
The only atl1c commit in v3.8-rc7..v3.8 is:
commit ac574804d412047e52de4dd887615cc88f58aeb0
Author: Huang, Xiong <xiong@qca.qualcomm.com>
Date: Mon Feb 11 14:44:40 2013 +0000
atl1c: add error checking for pci_map_single functions
it is reported that code hit DMA-API errors on 3.8-rc6+,
(see https://bugzilla.redhat.com/show_bug.cgi?id=908436, and
https://bugzilla.redhat.com/show_bug.cgi?id=908550)
this patch just adds error handler for
pci_map_single and skb_frag_dma_map.
Signed-off-by: xiong <xiong@qca.qualcomm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Reverting that on top of v3.8 seems to fix the problem in my little
testing, so it sounds like that fix introduced a iommu leak?
Thanks,
Andre
^ permalink raw reply
* Re: [PATCH V2] lglock: add read-preference local-global rwlock
From: Oleg Nesterov @ 2013-03-02 17:20 UTC (permalink / raw)
To: Lai Jiangshan
Cc: Lai Jiangshan, linux-doc, peterz, fweisbec, Michel Lespinasse,
mingo, linux-arch, linux, xiaoguangrong, wangyun, paulmck, nikunj,
linux-pm, rusty, rostedt, rjw, namhyung, tglx, linux-arm-kernel,
netdev, linux-kernel, vincent.guittot, sbw, Srivatsa S. Bhat, tj,
akpm, linuxppc-dev
In-Reply-To: <5131FB4C.7070408@cn.fujitsu.com>
On 03/02, Lai Jiangshan wrote:
>
> +void lg_rwlock_local_read_unlock(struct lgrwlock *lgrw)
> +{
> + switch (__this_cpu_read(*lgrw->reader_refcnt)) {
> + case 1:
> + __this_cpu_write(*lgrw->reader_refcnt, 0);
> + lg_local_unlock(&lgrw->lglock);
> + return;
> + case FALLBACK_BASE:
> + __this_cpu_write(*lgrw->reader_refcnt, 0);
> + read_unlock(&lgrw->fallback_rwlock);
> + rwlock_release(&lg->lock_dep_map, 1, _RET_IP_);
I guess "case 1:" should do rwlock_release() too.
Otherwise, at first glance looks correct...
However, I still think that FALLBACK_BASE only adds the unnecessary
complications. But even if I am right this is subjective of course, please
feel free to ignore.
And btw, I am not sure about lg->lock_dep_map, perhaps we should use
fallback_rwlock->dep_map ?
We need rwlock_acquire_read() even in the fast-path, and this acquire_read
should be paired with rwlock_acquire() in _write_lock(), but it does
spin_acquire(lg->lock_dep_map). Yes, currently this is the same (afaics)
but perhaps fallback_rwlock->dep_map would be more clean.
Oleg.
^ permalink raw reply
* Re: [PATCH V2] lglock: add read-preference local-global rwlock
From: Srivatsa S. Bhat @ 2013-03-02 17:11 UTC (permalink / raw)
To: Lai Jiangshan
Cc: Michel Lespinasse, Oleg Nesterov, Lai Jiangshan, linux-doc,
peterz, fweisbec, linux-kernel, namhyung, mingo, linux-arch,
linux, xiaoguangrong, wangyun, paulmck, nikunj, linux-pm, rusty,
rostedt, rjw, vincent.guittot, tglx, linux-arm-kernel, netdev,
sbw, tj, akpm, linuxppc-dev
In-Reply-To: <5131FB4C.7070408@cn.fujitsu.com>
On 03/02/2013 06:44 PM, Lai Jiangshan wrote:
> From 345a7a75c314ff567be48983e0892bc69c4452e7 Mon Sep 17 00:00:00 2001
> From: Lai Jiangshan <laijs@cn.fujitsu.com>
> Date: Sat, 2 Mar 2013 20:33:14 +0800
> Subject: [PATCH] lglock: add read-preference local-global rwlock
>
> Current lglock is not read-preference, so it can't be used on some cases
> which read-preference rwlock can do. Example, get_cpu_online_atomic().
>
[...]
> diff --git a/kernel/lglock.c b/kernel/lglock.c
> index 6535a66..52e9b2c 100644
> --- a/kernel/lglock.c
> +++ b/kernel/lglock.c
> @@ -87,3 +87,71 @@ void lg_global_unlock(struct lglock *lg)
> preempt_enable();
> }
> EXPORT_SYMBOL(lg_global_unlock);
> +
> +#define FALLBACK_BASE (1UL << 30)
> +
> +void lg_rwlock_local_read_lock(struct lgrwlock *lgrw)
> +{
> + struct lglock *lg = &lgrw->lglock;
> +
> + preempt_disable();
> + if (likely(!__this_cpu_read(*lgrw->reader_refcnt))) {
> + rwlock_acquire_read(&lg->lock_dep_map, 0, 0, _RET_IP_);
> + if (unlikely(!arch_spin_trylock(this_cpu_ptr(lg->lock)))) {
> + read_lock(&lgrw->fallback_rwlock);
> + __this_cpu_write(*lgrw->reader_refcnt, FALLBACK_BASE);
> + return;
> + }
> + }
> +
> + __this_cpu_inc(*lgrw->reader_refcnt);
> +}
> +EXPORT_SYMBOL(lg_rwlock_local_read_lock);
> +
> +void lg_rwlock_local_read_unlock(struct lgrwlock *lgrw)
> +{
> + switch (__this_cpu_read(*lgrw->reader_refcnt)) {
> + case 1:
> + __this_cpu_write(*lgrw->reader_refcnt, 0);
> + lg_local_unlock(&lgrw->lglock);
> + return;
This should be a break, instead of a return, right?
Otherwise, there will be a preempt imbalance...
> + case FALLBACK_BASE:
> + __this_cpu_write(*lgrw->reader_refcnt, 0);
> + read_unlock(&lgrw->fallback_rwlock);
> + rwlock_release(&lg->lock_dep_map, 1, _RET_IP_);
> + break;
> + default:
> + __this_cpu_dec(*lgrw->reader_refcnt);
> + break;
> + }
> +
> + preempt_enable();
> +}
Regards,
Srivatsa S. Bhat
^ permalink raw reply
* Re: [PATCH] lglock: add read-preference local-global rwlock
From: Oleg Nesterov @ 2013-03-02 17:06 UTC (permalink / raw)
To: Michel Lespinasse
Cc: Lai Jiangshan, Srivatsa S. Bhat, Lai Jiangshan, linux-doc, peterz,
fweisbec, linux-kernel, namhyung, mingo, linux-arch, linux,
xiaoguangrong, wangyun, paulmck, nikunj, linux-pm, rusty, rostedt,
rjw, vincent.guittot, tglx, linux-arm-kernel, netdev, sbw, tj,
akpm, linuxppc-dev
In-Reply-To: <CANN689HEW=b5S93J27p+rBX-5m7jkW4FER=eHDCp7OgMaTWLPw@mail.gmail.com>
On 03/02, Michel Lespinasse wrote:
>
> My version would be slower if it needs to take the
> slow path in a reentrant way, but I'm not sure it matters either :)
I'd say, this doesn't matter at all, simply because this can only happen
if we race with the active writer.
Oleg.
^ permalink raw reply
* Re: [RFC PATCH 0/5] net: low latency Ethernet device polling
From: Eliezer Tamir @ 2013-03-02 17:02 UTC (permalink / raw)
To: David Miller
Cc: eliezer.tamir, linux-kernel, netdev, jesse.brandeburg,
e1000-devel, willemb, andi, hpa, eliezer
In-Reply-To: <20130301.162400.1645765127882618751.davem@davemloft.net>
On 01/03/2013 23:24, David Miller wrote:
> From: Eliezer Tamir <eliezer.tamir@linux.jf.intel.com>
> Date: Wed, 27 Feb 2013 09:55:49 -0800
>
>> This patchset adds the ability for the socket layer code to poll directly
>> on an Ethernet device's RX queue. This eliminates the cost of the interrupt
>> and context switch and with proper tuning allows us to get very close
>> to the HW latency.
>>
>> This is a follow up to Jesse Brandeburg's Kernel Plumbers talk from last year
>> http://www.linuxplumbersconf.org/2012/wp-content/uploads/2012/09/2012-lpc-Low-Latency-Sockets-slides-brandeburg.pdf
>
> I just wanted to say that I like this work a lot.
>
> It proves a lot of things I try to impress upon people who talk about
> how RDMA is such a "must have" because the software stack can't
> possibly give anything near HW latency.
>
> Obviously such arguments are complete bullshit as is shown by these
> changes.
>
> This is exactly the kind of approach that makes sense rather than
> trying to put entire TCP stacks in the network card firmware.
>
> Thanks again for doing this work and I look forward to applying
> this stuff once all the kinks are worked out. The folks in the
> Intel NIC group continue to impress me.
It would really help us to hear opinions on the open issues we listed.
Thanks,
Eliezer
^ permalink raw reply
* Re: [PATCH] lglock: add read-preference local-global rwlock
From: Oleg Nesterov @ 2013-03-02 17:01 UTC (permalink / raw)
To: Lai Jiangshan
Cc: paulmck, Srivatsa S. Bhat, Lai Jiangshan, Michel Lespinasse,
linux-doc, peterz, fweisbec, linux-kernel, namhyung, mingo,
linux-arch, linux, xiaoguangrong, wangyun, nikunj, linux-pm,
rusty, rostedt, rjw, vincent.guittot, tglx, linux-arm-kernel,
netdev, sbw, tj, akpm, linuxppc-dev
In-Reply-To: <513201B7.5070004@cn.fujitsu.com>
On 03/02, Lai Jiangshan wrote:
>
> On 02/03/13 02:28, Oleg Nesterov wrote:
> > Lai, I didn't read this discussion except the code posted by Michel.
> > I'll try to read this patch carefully later, but I'd like to ask
> > a couple of questions.
> >
> > This version looks more complex than Michel's, why? Just curious, I
> > am trying to understand what I missed. See
> > http://marc.info/?l=linux-kernel&m=136196350213593
>
> Michel changed my old draft version a little, his version is good enough for me.
Yes, I see. But imho Michel suggested the valuable cleanup, the code
becomes even more simple with the same perfomance.
Your v2 looks almost correct to me, but I still think it makes sense
to incorporate the simplification from Michel.
> My new version tries to add a little better nestable support with only
> adding single __this_cpu_op() in _read_[un]lock().
How? Afaics with or without FALLBACK_BASE you need _reed + _inc/dec in
_read_lock/unlock.
Oleg.
^ permalink raw reply
* Re: [PATCH net 1/1] r8169: honor jumbo settings when chipset is requested to start.
From: Tomi Orava @ 2013-03-02 16:43 UTC (permalink / raw)
To: Francois Romieu; +Cc: netdev, David Miller, Hayes Wang
In-Reply-To: <20130227230157.GA30053@electric-eye.fr.zoreil.com>
On 02/28/2013 01:01 AM, Francois Romieu wrote:
> Some hardware start settings implicitely assume an usual 1500 bytes mtu
> that can't be guaranteed because changes of mtu may be requested both
> before and after the hardware is started.
>
> Reported-by: Tomi Orava <tomimo@ncircle.nullnet.fi>
> Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
> Cc: Hayes Wang <hayeswang@realtek.com>
> ---
>
> Tomi, can you give this one a try ? It should be the "don't break non
> jumbo setup and fix similar problem on different chipsets" patch that
> my previous hack wasn't.
This latest worked just fine, no matter if the system was cold booted or
warm booted with jumbo frames enabled using this NIC:
03:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168B PCI Express Gigabit Ethernet controller (rev 01)
03:00.0 0200: 10ec:8168 (rev 01)
Subsystem: 1043:8385
Flags: bus master, fast devsel, latency 0, IRQ 40
I/O ports at e800 [size=256]
Memory at febff000 (64-bit, non-prefetchable) [size=4K]
Expansion ROM at febc0000 [disabled] [size=128K]
Capabilities: [40] Power Management version 2
Capabilities: [48] Vital Product Data
Capabilities: [50] MSI: Enable+ Count=1/2 Maskable- 64bit+
Capabilities: [60] Express Endpoint, MSI 00
Capabilities: [84] Vendor Specific Information: Len=4c <?>
Kernel driver in use: r8169
Ie. works for me.
Thanks!
Tomi
>
> drivers/net/ethernet/realtek/r8169.c | 27 ++++++++++++++++++---------
> 1 file changed, 18 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
> index 8900398..28fb50a 100644
> --- a/drivers/net/ethernet/realtek/r8169.c
> +++ b/drivers/net/ethernet/realtek/r8169.c
> @@ -4765,8 +4765,10 @@ static void rtl_hw_start_8168bb(struct rtl8169_private *tp)
>
> RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
>
> - rtl_tx_performance_tweak(pdev,
> - (0x5 << MAX_READ_REQUEST_SHIFT) | PCI_EXP_DEVCTL_NOSNOOP_EN);
> + if (tp->dev->mtu <= ETH_DATA_LEN) {
> + rtl_tx_performance_tweak(pdev, (0x5 << MAX_READ_REQUEST_SHIFT) |
> + PCI_EXP_DEVCTL_NOSNOOP_EN);
> + }
> }
>
> static void rtl_hw_start_8168bef(struct rtl8169_private *tp)
> @@ -4789,7 +4791,8 @@ static void __rtl_hw_start_8168cp(struct rtl8169_private *tp)
>
> RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
>
> - rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
> + if (tp->dev->mtu <= ETH_DATA_LEN)
> + rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
>
> rtl_disable_clock_request(pdev);
>
> @@ -4822,7 +4825,8 @@ static void rtl_hw_start_8168cp_2(struct rtl8169_private *tp)
>
> RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
>
> - rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
> + if (tp->dev->mtu <= ETH_DATA_LEN)
> + rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
>
> RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
> }
> @@ -4841,7 +4845,8 @@ static void rtl_hw_start_8168cp_3(struct rtl8169_private *tp)
>
> RTL_W8(MaxTxPacketSize, TxPacketMax);
>
> - rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
> + if (tp->dev->mtu <= ETH_DATA_LEN)
> + rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
>
> RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
> }
> @@ -4901,7 +4906,8 @@ static void rtl_hw_start_8168d(struct rtl8169_private *tp)
>
> RTL_W8(MaxTxPacketSize, TxPacketMax);
>
> - rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
> + if (tp->dev->mtu <= ETH_DATA_LEN)
> + rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
>
> RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
> }
> @@ -4913,7 +4919,8 @@ static void rtl_hw_start_8168dp(struct rtl8169_private *tp)
>
> rtl_csi_access_enable_1(tp);
>
> - rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
> + if (tp->dev->mtu <= ETH_DATA_LEN)
> + rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
>
> RTL_W8(MaxTxPacketSize, TxPacketMax);
>
> @@ -4972,7 +4979,8 @@ static void rtl_hw_start_8168e_1(struct rtl8169_private *tp)
>
> rtl_ephy_init(tp, e_info_8168e_1, ARRAY_SIZE(e_info_8168e_1));
>
> - rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
> + if (tp->dev->mtu <= ETH_DATA_LEN)
> + rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
>
> RTL_W8(MaxTxPacketSize, TxPacketMax);
>
> @@ -4998,7 +5006,8 @@ static void rtl_hw_start_8168e_2(struct rtl8169_private *tp)
>
> rtl_ephy_init(tp, e_info_8168e_2, ARRAY_SIZE(e_info_8168e_2));
>
> - rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
> + if (tp->dev->mtu <= ETH_DATA_LEN)
> + rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
>
> rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
> rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
>
^ permalink raw reply
* Re: [PATCH] lglock: add read-preference local-global rwlock
From: Lai Jiangshan @ 2013-03-02 13:42 UTC (permalink / raw)
To: Oleg Nesterov, paulmck
Cc: Srivatsa S. Bhat, Lai Jiangshan, Michel Lespinasse, linux-doc,
peterz, fweisbec, linux-kernel, namhyung, mingo, linux-arch,
linux, xiaoguangrong, wangyun, nikunj, linux-pm, rusty, rostedt,
rjw, vincent.guittot, tglx, linux-arm-kernel, netdev, sbw, tj,
akpm, linuxppc-dev
In-Reply-To: <20130301182854.GA3631@redhat.com>
On 02/03/13 02:28, Oleg Nesterov wrote:
> Lai, I didn't read this discussion except the code posted by Michel.
> I'll try to read this patch carefully later, but I'd like to ask
> a couple of questions.
>
> This version looks more complex than Michel's, why? Just curious, I
> am trying to understand what I missed. See
> http://marc.info/?l=linux-kernel&m=136196350213593
Michel changed my old draft version a little, his version is good enough for me.
My new version tries to add a little better nestable support with only
adding single __this_cpu_op() in _read_[un]lock().
>
> And I can't understand FALLBACK_BASE...
>
> OK, suppose that CPU_0 does _write_unlock() and releases ->fallback_rwlock.
>
> CPU_1 does _read_lock(), and ...
>
>> +void lg_rwlock_local_read_lock(struct lgrwlock *lgrw)
>> +{
>> + struct lglock *lg = &lgrw->lglock;
>> +
>> + preempt_disable();
>> + rwlock_acquire_read(&lg->lock_dep_map, 0, 0, _RET_IP_);
>> + if (likely(!__this_cpu_read(*lgrw->reader_refcnt))) {
>> + if (!arch_spin_trylock(this_cpu_ptr(lg->lock))) {
>
> _trylock() fails,
>
>> + read_lock(&lgrw->fallback_rwlock);
>> + __this_cpu_add(*lgrw->reader_refcnt, FALLBACK_BASE);
>
> so we take ->fallback_rwlock and ->reader_refcnt == FALLBACK_BASE.
>
> CPU_0 does lg_global_unlock(lgrw->lglock) and finishes _write_unlock().
>
> Interrupt handler on CPU_1 does _read_lock() notices ->reader_refcnt != 0
> and simply does this_cpu_inc(), so reader_refcnt == FALLBACK_BASE + 1.
>
> Then irq does _read_unlock(), and
>
>> +void lg_rwlock_local_read_unlock(struct lgrwlock *lgrw)
>> +{
>> + switch (__this_cpu_dec_return(*lgrw->reader_refcnt)) {
>> + case 0:
>> + lg_local_unlock(&lgrw->lglock);
>> + return;
>> + case FALLBACK_BASE:
>> + __this_cpu_sub(*lgrw->reader_refcnt, FALLBACK_BASE);
>> + read_unlock(&lgrw->fallback_rwlock);
>
> hits this case?
>
> Doesn't look right, but most probably I missed something.
Your are right, I just realized that I had spit a code which should be atomic.
I hope this patch(V2) can get more reviews.
My first and many locking knowledge is learned from Paul.
Paul, would you also review it?
Thanks,
Lai
>
> Oleg.
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
^ permalink raw reply
* [PATCH V2] lglock: add read-preference local-global rwlock
From: Lai Jiangshan @ 2013-03-02 13:14 UTC (permalink / raw)
To: Michel Lespinasse, Srivatsa S. Bhat
Cc: Lai Jiangshan, linux-doc, peterz, fweisbec, linux-kernel, mingo,
linux-arch, linux, xiaoguangrong, wangyun, paulmck, nikunj,
linux-pm, rusty, rostedt, rjw, namhyung, tglx, linux-arm-kernel,
netdev, Oleg Nesterov, vincent.guittot, sbw, tj, akpm,
linuxppc-dev
In-Reply-To: <CANN689HEW=b5S93J27p+rBX-5m7jkW4FER=eHDCp7OgMaTWLPw@mail.gmail.com>
>From 345a7a75c314ff567be48983e0892bc69c4452e7 Mon Sep 17 00:00:00 2001
From: Lai Jiangshan <laijs@cn.fujitsu.com>
Date: Sat, 2 Mar 2013 20:33:14 +0800
Subject: [PATCH] lglock: add read-preference local-global rwlock
Current lglock is not read-preference, so it can't be used on some cases
which read-preference rwlock can do. Example, get_cpu_online_atomic().
Although we can use rwlock for these cases which needs read-preference.
but it leads to unnecessary cache-line bouncing even when there are no
writers present, which can slow down the system needlessly. It will be
worse when we have a lot of CPUs, it is not scale.
So we look forward to lglock. lglock is read-write-lock based on percpu locks,
but it is not read-preference due to its underlining percpu locks.
But what if we convert the percpu locks of lglock to use percpu rwlocks:
CPU 0 CPU 1
------ ------
1. spin_lock(&random_lock); read_lock(my_rwlock of CPU 1);
2. read_lock(my_rwlock of CPU 0); spin_lock(&random_lock);
Writer:
CPU 2:
------
for_each_online_cpu(cpu)
write_lock(my_rwlock of 'cpu');
Consider what happens if the writer begins his operation in between steps 1
and 2 at the reader side. It becomes evident that we end up in a (previously
non-existent) deadlock due to a circular locking dependency between the 3
entities, like this:
(holds Waiting for
random_lock) CPU 0 -------------> CPU 2 (holds my_rwlock of CPU 0
for write)
^ |
| |
Waiting| | Waiting
for | | for
| V
------ CPU 1 <------
(holds my_rwlock of
CPU 1 for read)
So obviously this "straight-forward" way of implementing percpu rwlocks is
deadlock-prone. So we can't implement read-preference local-global rwlock
like this.
The implement of this patch reuse current lglock as frontend to achieve
local-read-lock, and reuse global fallback rwlock as backend to achieve
read-preference, and use percpu reader counter to indicate 1) the depth
of the nested reader lockes and 2) whether the outmost lock is percpu lock
or fallback rwlock.
The algorithm is simple, in the read site:
If it is nested reader, just increase the counter
If it is the outmost reader,
1) try to lock its cpu's lock of the frontend lglock.
(reader count +=1 if success)
2) if the above step fails, read_lock(&fallback_rwlock).
(reader count += FALLBACK_BASE + 1)
Write site:
Do the lg_global_lock() of the frontend lglock.
And then write_lock(&fallback_rwlock).
Prof:
1) reader-writer exclusive:
write-site must requires all percpu locks and fallback_rwlock.
outmost read-site must requires one of these locks.
2) read-preference:
before write site lock finished acquired, read site at least
wins at read_lock(&fallback_rwlock) due to rwlock is read-preference.
3) read site functions are irqsafe(reentrance-safe)
(read site functions is not protected by disabled irq, but they are irqsafe)
If read site function is interrupted at any point and reenters read site
again, reentranced read site will not be mislead by the first read site if the
reader counter > 0, in this case, it means currently frontend(this cpu lock of
lglock) or backend(fallback rwlock) lock is held, it is safe to act as
nested reader.
if the reader counter=0, eentranced reader considers it is the
outmost read site, and it always successes after the write side release the lock.
(even the interrupted read-site has already hold the cpu lock of lglock
or the fallback_rwlock).
And reentranced read site only calls arch_spin_trylock(), read_lock()
and __this_cpu_op(), arch_spin_trylock(), read_lock() is already reentrance-safe.
Although __this_cpu_op() is not reentrance-safe, but the value of the counter
will be restored after the interrupted finished, so read site functions
are still reentrance-safe.
Performance:
We only focus on the performance of the read site. this read site's fast path
is just preempt_disable() + __this_cpu_read/inc() + arch_spin_trylock(),
It has only one heavy memory operation. it will be expected fast.
We test three locks.
1) traditional rwlock WITHOUT remote competition nor cache-bouncing.(opt-rwlock)
2) this lock(lgrwlock)
3) V6 percpu-rwlock by "Srivatsa S. Bhat". (percpu-rwlock)
(https://lkml.org/lkml/2013/2/18/186)
nested=1(no nested) nested=2 nested=4
opt-rwlock 517181 1009200 2010027
lgrwlock 452897 700026 1201415
percpu-rwlock 1192955 1451343 1951757
The value is the time(nano-second) of 10000 times of the operations
{
read-lock
[nested read-lock]...
[nested read-unlock]...
read-unlock
}
If the way of this test is wrong nor bad, please correct me,
the code of test is here: https://gist.github.com/laijs/5066159
(i5 760, 64bit)
Changed from V1
fix a reentrance-bug which is cought by Oleg
don't touch lockdep for nested reader(needed by below change)
add two special APIs for cpuhotplug.
Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
---
include/linux/lglock.h | 38 ++++++++++++++++++++++++++
kernel/lglock.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 106 insertions(+), 0 deletions(-)
diff --git a/include/linux/lglock.h b/include/linux/lglock.h
index 0d24e93..90bfe79 100644
--- a/include/linux/lglock.h
+++ b/include/linux/lglock.h
@@ -67,4 +67,42 @@ void lg_local_unlock_cpu(struct lglock *lg, int cpu);
void lg_global_lock(struct lglock *lg);
void lg_global_unlock(struct lglock *lg);
+/* read-preference read-write-lock like rwlock but provides local-read-lock */
+struct lgrwlock {
+ unsigned long __percpu *reader_refcnt;
+ struct lglock lglock;
+ rwlock_t fallback_rwlock;
+};
+
+#define __DEFINE_LGRWLOCK_PERCPU_DATA(name) \
+ static DEFINE_PER_CPU(arch_spinlock_t, name ## _lock) \
+ = __ARCH_SPIN_LOCK_UNLOCKED; \
+ static DEFINE_PER_CPU(unsigned long, name ## _refcnt);
+
+#define __LGRWLOCK_INIT(name) \
+ { \
+ .reader_refcnt = &name ## _refcnt, \
+ .lglock = { .lock = &name ## _lock }, \
+ .fallback_rwlock = __RW_LOCK_UNLOCKED(name.fallback_rwlock)\
+ }
+
+#define DEFINE_LGRWLOCK(name) \
+ __DEFINE_LGRWLOCK_PERCPU_DATA(name) \
+ struct lgrwlock name = __LGRWLOCK_INIT(name)
+
+#define DEFINE_STATIC_LGRWLOCK(name) \
+ __DEFINE_LGRWLOCK_PERCPU_DATA(name) \
+ static struct lgrwlock name = __LGRWLOCK_INIT(name)
+
+static inline void lg_rwlock_init(struct lgrwlock *lgrw, char *name)
+{
+ lg_lock_init(&lgrw->lglock, name);
+}
+
+void lg_rwlock_local_read_lock(struct lgrwlock *lgrw);
+void lg_rwlock_local_read_unlock(struct lgrwlock *lgrw);
+void lg_rwlock_global_write_lock(struct lgrwlock *lgrw);
+void lg_rwlock_global_write_unlock(struct lgrwlock *lgrw);
+void __lg_rwlock_global_read_write_lock(struct lgrwlock *lgrw);
+void __lg_rwlock_global_read_write_unlock(struct lgrwlock *lgrw);
#endif
diff --git a/kernel/lglock.c b/kernel/lglock.c
index 6535a66..52e9b2c 100644
--- a/kernel/lglock.c
+++ b/kernel/lglock.c
@@ -87,3 +87,71 @@ void lg_global_unlock(struct lglock *lg)
preempt_enable();
}
EXPORT_SYMBOL(lg_global_unlock);
+
+#define FALLBACK_BASE (1UL << 30)
+
+void lg_rwlock_local_read_lock(struct lgrwlock *lgrw)
+{
+ struct lglock *lg = &lgrw->lglock;
+
+ preempt_disable();
+ if (likely(!__this_cpu_read(*lgrw->reader_refcnt))) {
+ rwlock_acquire_read(&lg->lock_dep_map, 0, 0, _RET_IP_);
+ if (unlikely(!arch_spin_trylock(this_cpu_ptr(lg->lock)))) {
+ read_lock(&lgrw->fallback_rwlock);
+ __this_cpu_write(*lgrw->reader_refcnt, FALLBACK_BASE);
+ return;
+ }
+ }
+
+ __this_cpu_inc(*lgrw->reader_refcnt);
+}
+EXPORT_SYMBOL(lg_rwlock_local_read_lock);
+
+void lg_rwlock_local_read_unlock(struct lgrwlock *lgrw)
+{
+ switch (__this_cpu_read(*lgrw->reader_refcnt)) {
+ case 1:
+ __this_cpu_write(*lgrw->reader_refcnt, 0);
+ lg_local_unlock(&lgrw->lglock);
+ return;
+ case FALLBACK_BASE:
+ __this_cpu_write(*lgrw->reader_refcnt, 0);
+ read_unlock(&lgrw->fallback_rwlock);
+ rwlock_release(&lg->lock_dep_map, 1, _RET_IP_);
+ break;
+ default:
+ __this_cpu_dec(*lgrw->reader_refcnt);
+ break;
+ }
+
+ preempt_enable();
+}
+EXPORT_SYMBOL(lg_rwlock_local_read_unlock);
+
+void lg_rwlock_global_write_lock(struct lgrwlock *lgrw)
+{
+ lg_global_lock(&lgrw->lglock);
+ write_lock(&lgrw->fallback_rwlock);
+}
+EXPORT_SYMBOL(lg_rwlock_global_write_lock);
+
+void lg_rwlock_global_write_unlock(struct lgrwlock *lgrw)
+{
+ write_unlock(&lgrw->fallback_rwlock);
+ lg_global_unlock(&lgrw->lglock);
+}
+EXPORT_SYMBOL(lg_rwlock_global_write_unlock);
+
+/* special write-site APIs allolw nested reader in such write-site */
+void __lg_rwlock_global_read_write_lock(struct lgrwlock *lgrw)
+{
+ lg_rwlock_global_write_lock(lgrw);
+ __this_cpu_write(*lgrw->reader_refcnt, 1);
+}
+
+void __lg_rwlock_global_read_write_unlock(struct lgrwlock *lgrw)
+{
+ __this_cpu_write(*lgrw->reader_refcnt, 0);
+ lg_rwlock_global_write_unlock(lgrw);
+}
--
1.7.7.6
^ permalink raw reply related
* Re: [PATCH RESEND 3/3] e1000e: fix accessing to suspended device
From: Konstantin Khlebnikov @ 2013-03-02 12:26 UTC (permalink / raw)
To: Ben Hutchings
Cc: Rafael J. Wysocki, e1000-devel, netdev, Bruce Allan, linux-kernel
In-Reply-To: <1361921710.2996.19.camel@bwh-desktop.uk.solarflarecom.com>
Ben Hutchings wrote:
> On Tue, 2013-02-26 at 14:03 +0400, Konstantin Khlebnikov wrote:
>> Waskiewicz Jr, Peter P wrote:
>>> On 2/24/2013 9:19 PM, Konstantin Khlebnikov wrote:
>>>> This patch fixes some annoying messages like 'Error reading PHY register' and
>>>> 'Hardware Erorr' and saves several seconds on reboot.
>>>
>>> Any networking-related patches should also include netdev@vger.kernel.org.
>>
>> Yeah, I forgot about this, since I came here from PCI-bus side, not from the network =)
>>
>>>
>>> I'm also a bit confused how the changes below match the patch description.
>> > Elaborating a bit more how the changes suppress the messages might be a good thing.
>>
>> Patch eliminates reason of these errors -- now driver will wake up
>> the device before accessing to its registers.
> [...]
>
> But e1000e calls netif_device_detach() when entering run-time suspend.
> That currently prevents any ethtool operations from running until it
> resumes.
This seems racy. dev_ethtool() runs under rtnl-lock, but suspend-resume
run asynchronously. Runtime-suspend shoudn't call netif_device_detach(),
logically device isn't dead it just take a nap for a while..
>
> (This is definitely a misfeature of either the ethtool core or e1000e.
> It is absolutely ridiculous that I can't check the PHY settings of an
> e1000e - or even driver information! - when the link is down.)
Ok link is down, but device still alive and I not see anything ridiculous
in checking its registers.
------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_feb
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel® Ethernet, visit http://communities.intel.com/community/wired
^ permalink raw reply
* Re: [PATCH] lglock: add read-preference local-global rwlock
From: Michel Lespinasse @ 2013-03-02 12:13 UTC (permalink / raw)
To: Oleg Nesterov
Cc: Lai Jiangshan, Srivatsa S. Bhat, Lai Jiangshan, linux-doc, peterz,
fweisbec, linux-kernel, namhyung, mingo, linux-arch, linux,
xiaoguangrong, wangyun, paulmck, nikunj, linux-pm, rusty, rostedt,
rjw, vincent.guittot, tglx, linux-arm-kernel, netdev, sbw, tj,
akpm, linuxppc-dev
In-Reply-To: <20130301182854.GA3631@redhat.com>
On Sat, Mar 2, 2013 at 2:28 AM, Oleg Nesterov <oleg@redhat.com> wrote:
> Lai, I didn't read this discussion except the code posted by Michel.
> I'll try to read this patch carefully later, but I'd like to ask
> a couple of questions.
>
> This version looks more complex than Michel's, why? Just curious, I
> am trying to understand what I missed. See
> http://marc.info/?l=linux-kernel&m=136196350213593
>From what I can see, my version used local_refcnt to count how many
reentrant locks are represented by the fastpath lglock spinlock; Lai's
version uses it to count how many reentrant locks are represented by
either the fastpath lglock spinlock or the global rwlock, with
FALLBACK_BASE being a bit thrown in so we can remember which of these
locks was acquired. My version would be slower if it needs to take the
slow path in a reentrant way, but I'm not sure it matters either :)
> Interrupt handler on CPU_1 does _read_lock() notices ->reader_refcnt != 0
> and simply does this_cpu_inc(), so reader_refcnt == FALLBACK_BASE + 1.
>
> Then irq does _read_unlock(), and
>
>> +void lg_rwlock_local_read_unlock(struct lgrwlock *lgrw)
>> +{
>> + switch (__this_cpu_dec_return(*lgrw->reader_refcnt)) {
>> + case 0:
>> + lg_local_unlock(&lgrw->lglock);
>> + return;
>> + case FALLBACK_BASE:
>> + __this_cpu_sub(*lgrw->reader_refcnt, FALLBACK_BASE);
>> + read_unlock(&lgrw->fallback_rwlock);
>
> hits this case?
>
> Doesn't look right, but most probably I missed something.
Good catch. I think this is easily fixed by setting reader_refcn
directly to FALLBACK_BASE+1, instead of setting it to FALLBACK_BASE
and then incrementing it to FALLBACK_BASE+1.
--
Michel "Walken" Lespinasse
A program is never fully debugged until the last user dies.
^ permalink raw reply
* [PATCH resubmit] ax88179_178a: ASIX AX88179_178A USB 3.0/2.0 to gigabit ethernet adapter driver
From: Freddy Xin @ 2013-03-02 10:41 UTC (permalink / raw)
To: netdev; +Cc: linux-usb, linux-kernel, louis, Freddy Xin
From: Freddy Xin <freddy@asix.com.tw>
This is a resubmission.
Added kfree() in ax88179_get_eeprom to prevent memory leakage.
Modified "__le16 rxctl" to "u16 rxctl" in "struct ax88179_data" and removed pointless casts.
Removed asix_init and asix_exit functions and added "module_usb_driver(ax88179_178a_driver)".
Fixed endianness issue on big endian systems and verified this driver on iBook G4.
Removed steps that change net->features in ax88179_set_features function.
Added "const" to ethtool_ops structure and fixed the coding style of AX88179_BULKIN_SIZE array.
Fixed the issue that the default MTU is not 1500.
Added ax88179_change_mtu function and enabled the hardware jumbo frame function to support an
MTU higher than 1500.
Fixed indentation and empty line 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 | 1448 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 1467 insertions(+)
create mode 100644 drivers/net/usb/ax88179_178a.c
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index da92ed3..21e084d 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -156,6 +156,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..71c27d8
--- /dev/null
+++ b/drivers/net/usb/ax88179_178a.c
@@ -0,0 +1,1448 @@
+/*
+ * ASIX AX88179/178A USB 3.0/2.0 to Gigabit Ethernet Devices
+ *
+ * Copyright (C) 2011-2013 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 ((u32)BIT(16))
+#define AX_RXHDR_L4_TYPE_MASK 0x1c
+#define AX_RXHDR_L4_TYPE_UDP 4
+#define AX_RXHDR_L4_TYPE_TCP 16
+#define AX_RXHDR_L3CSUM_ERR 2
+#define AX_RXHDR_L4CSUM_ERR 1
+#define AX_RXHDR_CRC_ERR ((u32)BIT(31))
+#define AX_RXHDR_DROP_ERR ((u32)BIT(30))
+#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_EN_125MHZ 0x08
+ #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_MEDIUM_JUMBO_EN 0x8040
+
+#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 0xff8f
+ #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;
+ u16 reserved;
+};
+
+struct ax88179_int_data {
+ __le32 intdata1;
+ __le32 intdata2;
+};
+
+static const struct {
+ unsigned char ctrl, timer_l, timer_h, size, ifg;
+} AX88179_BULKIN_SIZE[] = {
+ {7, 0x4f, 0, 0x12, 0xff},
+ {7, 0x20, 3, 0x16, 0xff},
+ {7, 0xae, 7, 0x18, 0xff},
+ {7, 0xcc, 0x4c, 0x18, 8},
+};
+
+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);
+
+ BUG_ON(!dev);
+
+ 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 (unlikely(ret < 0))
+ netdev_warn(dev->net, "Failed to read reg index 0x%04x: %d\n",
+ index, ret);
+
+ return ret;
+}
+
+static int __ax88179_write_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, const void *, u16);
+
+ BUG_ON(!dev);
+
+ if (!in_pm)
+ fn = usbnet_write_cmd;
+ else
+ fn = usbnet_write_cmd_nopm;
+
+ ret = fn(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value, index, data, size);
+
+ if (unlikely(ret < 0))
+ netdev_warn(dev->net, "Failed to write reg index 0x%04x: %d\n",
+ index, ret);
+
+ return ret;
+}
+
+static void ax88179_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value,
+ u16 index, u16 size, void *data)
+{
+ u16 buf;
+
+ if (2 == size) {
+ buf = *((u16 *)data);
+ cpu_to_le16s(&buf);
+ usbnet_write_cmd_async(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR |
+ USB_RECIP_DEVICE, value, index, &buf,
+ size);
+ } else {
+ 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)
+{
+ int ret;
+
+ if (2 == size) {
+ u16 buf;
+ ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 1);
+ le16_to_cpus(&buf);
+ *((u16 *)data) = buf;
+ } else if (4 == size) {
+ u32 buf;
+ ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 1);
+ le32_to_cpus(&buf);
+ *((u32 *)data) = buf;
+ } else {
+ ret = __ax88179_read_cmd(dev, cmd, value, index, size, data, 1);
+ }
+
+ return ret;
+}
+
+static int ax88179_write_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value,
+ u16 index, u16 size, void *data)
+{
+ int ret;
+
+ if (2 == size) {
+ u16 buf;
+ buf = *((u16 *)data);
+ cpu_to_le16s(&buf);
+ ret = __ax88179_write_cmd(dev, cmd, value, index,
+ size, &buf, 1);
+ } else {
+ ret = __ax88179_write_cmd(dev, cmd, value, index,
+ size, data, 1);
+ }
+
+ return ret;
+}
+
+static int ax88179_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+ u16 size, void *data)
+{
+ int ret;
+
+ if (2 == size) {
+ u16 buf;
+ ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 0);
+ le16_to_cpus(&buf);
+ *((u16 *)data) = buf;
+ } else if (4 == size) {
+ u32 buf;
+ ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 0);
+ le32_to_cpus(&buf);
+ *((u32 *)data) = buf;
+ } else {
+ ret = __ax88179_read_cmd(dev, cmd, value, index, size, data, 0);
+ }
+
+ return ret;
+}
+
+static int ax88179_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+ u16 size, void *data)
+{
+ int ret;
+
+ if (2 == size) {
+ u16 buf;
+ buf = *((u16 *)data);
+ cpu_to_le16s(&buf);
+ ret = __ax88179_write_cmd(dev, cmd, value, index,
+ size, &buf, 0);
+ } else {
+ ret = __ax88179_write_cmd(dev, cmd, value, index,
+ size, data, 0);
+ }
+
+ return ret;
+}
+
+static void ax88179_status(struct usbnet *dev, struct urb *urb)
+{
+ struct ax88179_int_data *event;
+ u32 link;
+
+ if (urb->actual_length < 8)
+ return;
+
+ event = urb->transfer_buffer;
+ le32_to_cpus((void *)&event->intdata1);
+
+ link = (((__force u32)event->intdata1) & AX_INT_PPLS_LINK) >> 16;
+
+ 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 res;
+}
+
+static void ax88179_mdio_write(struct net_device *netdev, int phy_id, int loc,
+ int val)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+ u16 res = (u16) 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;
+ u8 tmp8;
+
+ 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 */
+ tmp8 = 0;
+ ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8);
+
+ /* 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 tmp16;
+ u8 tmp8;
+ int (*fnr)(struct usbnet *, u8, u16, u16, u16, void *);
+ int (*fnw)(struct usbnet *, u8, u16, u16, u16, void *);
+
+ if (!in_pm) {
+ fnr = ax88179_read_cmd;
+ fnw = ax88179_write_cmd;
+ } else {
+ fnr = ax88179_read_cmd_nopm;
+ fnw = ax88179_write_cmd_nopm;
+ }
+
+ if (fnr(dev, AX_ACCESS_EEPROM, 0x43, 1, 2, &tmp16) < 0)
+ return 0;
+
+ if ((tmp16 == 0xFFFF) || (!(tmp16 & 0x0100)))
+ return 0;
+
+ /* Enable Auto Detach bit */
+ tmp8 = 0;
+ fnr(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8);
+ tmp8 |= AX_CLK_SELECT_ULR;
+ fnw(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8);
+
+ fnr(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &tmp16);
+ tmp16 |= AX_PHYPWR_RSTCTL_AT;
+ fnw(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &tmp16);
+
+ return 0;
+}
+
+static int ax88179_resume(struct usb_interface *intf)
+{
+ struct usbnet *dev = usb_get_intfdata(intf);
+ u16 tmp16;
+ u8 tmp8;
+
+ 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, &tmp8);
+ tmp8 |= AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS;
+ ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8);
+ 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, ret;
+
+ 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++) {
+ ret = __ax88179_read_cmd(dev, AX_ACCESS_EEPROM, i, 1, 2,
+ &eeprom_buff[i - first_word],
+ 0);
+ if (ret < 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 const 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_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);
+ }
+
+ 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);
+ }
+
+ 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);
+ }
+
+ return 0;
+}
+
+static int ax88179_change_mtu(struct net_device *net, int new_mtu)
+{
+ struct usbnet *dev = netdev_priv(net);
+ u16 tmp16;
+
+ if (new_mtu <= 0 || new_mtu > 4088)
+ return -EINVAL;
+
+ net->mtu = new_mtu;
+ dev->hard_mtu = net->mtu + net->hard_header_len;
+
+ if (net->mtu > 1500) {
+ ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+ 2, 2, &tmp16);
+ tmp16 |= AX_MEDIUM_JUMBO_EN;
+ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+ 2, 2, &tmp16);
+ } else {
+ ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+ 2, 2, &tmp16);
+ tmp16 &= ~AX_MEDIUM_JUMBO_EN;
+ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+ 2, 2, &tmp16);
+ }
+
+ 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 = ax88179_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, buf, 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], 0);
+
+ 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->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, AX_RX_CTL, 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, u32 *pkt_hdr)
+{
+ skb->ip_summed = CHECKSUM_NONE;
+
+ /* checksum error bit is set */
+ if ((*pkt_hdr & AX_RXHDR_L3CSUM_ERR) ||
+ (*pkt_hdr & AX_RXHDR_L4CSUM_ERR))
+ return;
+
+ /* It must be a TCP or UDP packet with a valid checksum */
+ if (((*pkt_hdr & AX_RXHDR_L4_TYPE_MASK) == AX_RXHDR_L4_TYPE_TCP) ||
+ ((*pkt_hdr & AX_RXHDR_L4_TYPE_MASK) == 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;
+ u32 *pkt_hdr;
+
+ skb_trim(skb, skb->len - 4);
+ memcpy(&rx_hdr, skb_tail_pointer(skb), 4);
+ le32_to_cpus(&rx_hdr);
+
+ pkt_cnt = (u16)rx_hdr;
+ hdr_off = (u16)(rx_hdr >> 16);
+ pkt_hdr = (u32 *)(skb->data + hdr_off);
+
+ while (pkt_cnt--) {
+ u16 pkt_len;
+
+ le32_to_cpus(pkt_hdr);
+ pkt_len = (*pkt_hdr >> 16) & 0x1fff;
+
+ /* Check CRC or runt packet */
+ if ((*pkt_hdr & AX_RXHDR_CRC_ERR) ||
+ (*pkt_hdr & AX_RXHDR_DROP_ERR)) {
+ 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_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 | AX_MEDIUM_EN_125MHZ;
+ if (dev->net->mtu > 1500)
+ mode |= AX_MEDIUM_JUMBO_EN;
+
+ 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);
+
+ dev->rx_urb_size = (1024 * (tmp[3] + 2));
+
+ if (tmp16 & GMII_PHY_PHYSR_FULL)
+ mode |= AX_MEDIUM_FULL_DUPLEX;
+ 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, AX_RX_CTL, 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 ax88179_178a_driver = {
+ .name = "ax88179_178a",
+ .id_table = products,
+ .probe = usbnet_probe,
+ .suspend = ax88179_suspend,
+ .resume = ax88179_resume,
+ .disconnect = usbnet_disconnect,
+ .supports_autosuspend = 1,
+ .disable_hub_initiated_lpm = 1,
+};
+
+module_usb_driver(ax88179_178a_driver);
+
+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: tg3: regression of netdev stats
From: OGAWA Hirofumi @ 2013-03-02 6:20 UTC (permalink / raw)
To: Michael Chan; +Cc: nsujir, davem, netdev
In-Reply-To: <87y5e6wcv1.fsf@devron.myhome.or.jp>
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> writes:
> "Michael Chan" <mchan@broadcom.com> writes:
>
>> On Fri, 2013-03-01 at 22:21 +0900, OGAWA Hirofumi wrote:
>>> Hi,
>>>
>>> f4a46d1f46a8fece34edd2023e054072b02e110d (tg3: Prevent spurious tx
>>> timeout by setting carrier off before tx disable.) seems to add the bug.
>>>
>>> On 3.8.1 (I didn't use 3.7.x series), "ifconfig" commands doesn't show
>>> any stats, i.e. all stats are zero.
>>
>> No stats on an active device transmitting and receiving packets? I
>> don't seem to see the same problem, but we'll look into this further.
>> Thanks.
>
> Yes, /proc/net/dev didn't show any packet traffic stats (always
> zero). But, e.g. ping/nfs itself works fine.
>
> BTW, chip is
>
> 02:00.0 Ethernet controller [0200]: Broadcom Corporation NetLink BCM57788 Gigabit Ethernet PCIe [14e4:1691] (rev 01)
>
> tg3 0000:02:00.0 eth0: Tigon3 [partno(BCM57788) rev 57780001] (PCI Express) MAC address d4:be:d9:a6:a3:3b
> tg3 0000:02:00.0 eth0: attached PHY driver [Broadcom BCM57780] (mii_bus:phy_addr=200:01)
With some read, this chip seems to be using PHYLIB, and PHYLIB modify
carrier state, so ->link_up confuses with it?
Thanks.
--
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
^ permalink raw reply
* Re: tg3: regression of netdev stats
From: OGAWA Hirofumi @ 2013-03-02 6:10 UTC (permalink / raw)
To: Michael Chan; +Cc: nsujir, davem, netdev
In-Reply-To: <1362152836.6212.27.camel@LTIRV-MCHAN1.corp.ad.broadcom.com>
"Michael Chan" <mchan@broadcom.com> writes:
> On Fri, 2013-03-01 at 22:21 +0900, OGAWA Hirofumi wrote:
>> Hi,
>>
>> f4a46d1f46a8fece34edd2023e054072b02e110d (tg3: Prevent spurious tx
>> timeout by setting carrier off before tx disable.) seems to add the bug.
>>
>> On 3.8.1 (I didn't use 3.7.x series), "ifconfig" commands doesn't show
>> any stats, i.e. all stats are zero.
>
> No stats on an active device transmitting and receiving packets? I
> don't seem to see the same problem, but we'll look into this further.
> Thanks.
Yes, /proc/net/dev didn't show any packet traffic stats (always
zero). But, e.g. ping/nfs itself works fine.
BTW, chip is
02:00.0 Ethernet controller [0200]: Broadcom Corporation NetLink BCM57788 Gigabit Ethernet PCIe [14e4:1691] (rev 01)
tg3 0000:02:00.0 eth0: Tigon3 [partno(BCM57788) rev 57780001] (PCI Express) MAC address d4:be:d9:a6:a3:3b
tg3 0000:02:00.0 eth0: attached PHY driver [Broadcom BCM57780] (mii_bus:phy_addr=200:01)
>> And bisect points the above commit.
>> In fact, reverting the above patch fixes the regression of netdev stats.
>>
>> This patch looks like strange, and I'm not sure what this want to do.
>> Any ideas?
>
> Every time we reset the device (ethtool, MTU change, etc), we need to
> turn off all the tx queues before resetting. As soon as we turn off
> these queues, if we don't turn off carrier, a tx timeout may be
> triggered if it's been more than 5 seconds since the last transmit on
> any of the tx queues. These tx timeouts cause unnecessary concern to
> the user.
Hmm... I'm not reading codes almost, so this might be wrong
though. tg3_phy_reset() set off if ->link_up, so this seems to be not
saving original state, and I'm not sure what want to do with ->link_up.
I felt the following pesudo code might be work and simple...
ok = netif_carrier_ok()
netif_carrier_off()
[reconfigure...]
if (ok)
netif_carrier_on()
Thanks.
--
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
^ permalink raw reply
* Re: upgrade to 3.8.1 : BUG Scheduling while atomic in bonding driver:
From: Linda Walsh @ 2013-03-02 5:21 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Linux-Kernel, netdev, Jay Vosburgh, Jeff Kirsher, Cong Wang
In-Reply-To: <51317FCF.1070400@tlinx.org>
Linda Walsh wrote:
>
>
> This patch is not in the latest kernel. I don't know if it is the
> 'best' way, but it does stop BUG error messages.
---
Update -- it *used* to stop the messages in 3.6.7.
It no longer stops the messages in 3.8.1 -- (and isn't present by
default -- tried
adding the unlock/lock -- no difference.
Weird. *sigh*
>
>
> -------- Original Message --------
> Subject: Re: BUG: scheduling while atomic:
> ifup-bonding/3711/0x00000002 -- V3.6.7
> Date: Wed, 28 Nov 2012 13:17:31 -0800
> From: Linda Walsh <lkml@tlinx.org>
> To: Cong Wang <xiyou.wangcong@gmail.com>
> CC: LKML <linux-kernel@vger.kernel.org>, Linux Kernel Network
> Developers <netdev@vger.kernel.org>
> References: <50B5248A.5010908@tlinx.org>
> <CAM_iQpUW2Oz9p0K0gGKc6JoD7WAu0kJtRa4uBSe+WfXg0Nn3jA@mail.gmail.com>
>
>
>
> Cong Wang wrote:
>> Does this quick fix help?
>> diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
>> index 5f5b69f..4a4d9eb 100644
>> --- a/drivers/net/bonding/bond_main.c
>> +++ b/drivers/net/bonding/bond_main.c
>> @@ -1785,7 +1785,9 @@ int bond_enslave(struct net_device *bond_dev,
>> struct net_device *slave_dev)
>> new_slave->link == BOND_LINK_DOWN ? "DOWN" :
>> (new_slave->link == BOND_LINK_UP ? "UP" : "BACK"));
>>
>> + read_unlock(&bond->lock);
>> bond_update_speed_duplex(new_slave);
>> + read_lock(&bond->lock);
>>
>> if (USES_PRIMARY(bond->params.mode) && bond->params.primary[0]) {
>> /* if there is a primary slave, remember it */
>>
>> Thanks!
>>
>
>
>
>
> Eric Dumazet wrote:
>> On Fri, 2013-03-01 at 00:15 -0800, Linda Walsh wrote:
>>
>>> Just installed 3.8.1....
>>>
>>> Thought this had been fixed? Note it causes the kernel to
>>> show up as tainted after the 1st...
>>>
>>>
>>
>> CC netdev & Jay Vosburgh & Jeff Kirsher
>>
>>
>>> As the system was coming up and initializing the bond0 driver:
>>>
>>>
>>> [ 19.847743] ixgbe 0000:06:00.0: registered PHC device on eth_s2_0
>>> [ 20.258245] BUG: scheduling while atomic: ifup-bonding/2003/0x00000002
>>> [ 20.264812] 4 locks held by ifup-bonding/2003:
>>> [ 20.269298] #0: (&buffer->mutex){......}, at: [<ffffffff811c401f>]
>>> sysfs_write_file+0x3f/0x150
>>> [ 20.278319] #1: (s_active#59){......}, at: [<ffffffff811c409b>]
>>> sysfs_write_file+0xbb/0x150
>>> [ 20.287088] #2: (rtnl_mutex){......}, at: [<ffffffff81590bf0>]
>>> rtnl_trylock+0x10/0x20
>>> [ 20.295373] #3: (&bond->lock){......}, at: [<ffffffff8145be6f>]
>>> bond_enslave+0x4ef/0xb80
>>> [ 20.303912] Modules linked in: iptable_filter kvm_intel kvm acpi_cpufreq
>>> mperf button processor mousedev iTCO_wdt
>>> [ 20.314695] Pid: 2003, comm: ifup-bonding Not tainted 3.8.1-Isht-Van #5
>>> [ 20.321340] Call Trace:
>>> [ 20.323833] [<ffffffff8162b029>] __schedule_bug+0x5e/0x6c
>>> [ 20.329356] [<ffffffff81634592>] __schedule+0x762/0x7f0
>>> [ 20.334701] [<ffffffff81634734>] schedule+0x24/0x70
>>> [ 20.339703] [<ffffffff816336f4>] schedule_hrtimeout_range_clock+0xa4/0x130
>>> [ 20.346699] [<ffffffff81068250>] ? update_rmtp+0x60/0x60
>>> [ 20.352130] [<ffffffff81068f9f>] ? hrtimer_start_range_ns+0xf/0x20
>>> [ 20.358434] [<ffffffff8163378e>] schedule_hrtimeout_range+0xe/0x10
>>> [ 20.364734] [<ffffffff8104ec1b>] usleep_range+0x3b/0x40
>>> [ 20.370082] [<ffffffff814b2d7c>] ixgbe_acquire_swfw_sync_X540+0xbc/0x100
>>> [ 20.376905] [<ffffffff814aeb0d>] ixgbe_read_phy_reg_generic+0x3d/0x140
>>> [ 20.383553] [<ffffffff814aedac>]
>>> ixgbe_get_copper_link_capabilities_generic+0x2c/0x60
>>> [ 20.391499] [<ffffffff8145be6f>] ? bond_enslave+0x4ef/0xb80
>>> [ 20.397194] [<ffffffff814a64e4>] ixgbe_get_settings+0x34/0x340
>>> [ 20.403148] [<ffffffff81586ab8>] __ethtool_get_settings+0x88/0x130
>>> [ 20.409448] [<ffffffff814568a3>] bond_update_speed_duplex+0x23/0x60
>>> [ 20.415833] [<ffffffff8145bed9>] bond_enslave+0x559/0xb80
>>> [ 20.421356] [<ffffffff8146454f>] bonding_store_slaves+0x16f/0x1c0
>>> [ 20.427569] [<ffffffff813bfb83>] dev_attr_store+0x13/0x30
>>> [ 20.433091] [<ffffffff811c40b4>] sysfs_write_file+0xd4/0x150
>>> [ 20.438872] [<ffffffff81154b81>] vfs_write+0xb1/0x190
>>> [ 20.444047] [<ffffffff81154ee0>] sys_write+0x50/0xa0
>>> [ 20.449137] [<ffffffff81637092>] system_call_fastpath+0x16/0x1b
>>> [ 20.455264] BUG: scheduling while atomic: ifup-bonding/2003/0x00000002
>>> [ 20.461851] 4 locks held by ifup-bonding/2003:
>>> [ 20.466334] #0: (&buffer->mutex){......}, at: [<ffffffff811c401f>]
>>> sysfs_write_file+0x3f/0x150
>>> [ 20.475356] #1: (s_active#59){......}, at: [<ffffffff811c409b>]
>>> sysfs_write_file+0xbb/0x150
>>> [ 20.484117] #2: (rtnl_mutex){......}, at: [<ffffffff81590bf0>]
>>> rtnl_trylock+0x10/0x20
>>> [ 20.492403] #3: (&bond->lock){......}, at: [<ffffffff8145be6f>]
>>> bond_enslave+0x4ef/0xb80
>>> [ 20.500902] Modules linked in: iptable_filter kvm_intel kvm acpi_cpufreq
>>> mperf button processor mousedev iTCO_wdt
>>> [ 20.511640] Pid: 2003, comm: ifup-bonding Tainted: G W
>>> 3.8.1-Isht-Van #5
>>> [ 20.519240] Call Trace:
>>> [ 20.521729] [<ffffffff8162b029>] __schedule_bug+0x5e/0x6c
>>> [ 20.527251] [<ffffffff81634592>] __schedule+0x762/0x7f0
>>> [ 20.532599] [<ffffffff81634734>] schedule+0x24/0x70
>>> [ 20.537599] [<ffffffff816336f4>] schedule_hrtimeout_range_clock+0xa4/0x130
>>> [ 20.544592] [<ffffffff81068250>] ? update_rmtp+0x60/0x60
>>> [ 20.550026] [<ffffffff81068250>] ? update_rmtp+0x60/0x60
>>> [ 20.555462] [<ffffffff81068f9f>] ? hrtimer_start_range_ns+0xf/0x20
>>> [ 20.561763] [<ffffffff8163378e>] schedule_hrtimeout_range+0xe/0x10
>>> [ 20.568064] [<ffffffff8104ec1b>] usleep_range+0x3b/0x40
>>> [ 20.573415] [<ffffffff814b2cae>] ixgbe_release_swfw_sync_X540+0x4e/0x60
>>> [ 20.580146] [<ffffffff814aebdd>] ixgbe_read_phy_reg_generic+0x10d/0x140
>>> [ 20.586960] [<ffffffff814aedac>]
>>> ixgbe_get_copper_link_capabilities_generic+0x2c/0x60
>>> [ 20.594908] [<ffffffff8145be6f>] ? bond_enslave+0x4ef/0xb80
>>> [ 20.600601] [<ffffffff814a64e4>] ixgbe_get_settings+0x34/0x340
>>> [ 20.606557] [<ffffffff81586ab8>] __ethtool_get_settings+0x88/0x130
>>> [ 20.612858] [<ffffffff814568a3>] bond_update_speed_duplex+0x23/0x60
>>> [ 20.619244] [<ffffffff8145bed9>] bond_enslave+0x559/0xb80
>>> [ 20.624767] [<ffffffff8146454f>] bonding_store_slaves+0x16f/0x1c0
>>> [ 20.630983] [<ffffffff813bfb83>] dev_attr_store+0x13/0x30
>>> [ 20.636503] [<ffffffff811c40b4>] sysfs_write_file+0xd4/0x150
>>> [ 20.642283] [<ffffffff81154b81>] vfs_write+0xb1/0x190
>>> [ 20.647462] [<ffffffff81154ee0>] sys_write+0x50/0xa0
>>> [ 20.652548] [<ffffffff81637092>] system_call_fastpath+0x16/0x1b
>>> [ 20.658696] bonding: bond0: enslaving eth_s2_0 as an active interface with a
>>> down link.
>>> [ 20.676577] bonding: bond0: Adding slave eth_s2_1.
>>> [ 20.743760] pps pps1: new PPS source ptp1
>>> [ 20.747792] ixgbe 0000:06:00.1: registered PHC device on eth_s2_1
>>> [ 21.150267] BUG: scheduling while atomic: ifup-bonding/2003/0x00000002
>>> [ 21.156836] 4 locks held by ifup-bonding/2003:
>>> [ 21.161319] #0: (&buffer->mutex){......}, at: [<ffffffff811c401f>]
>>> sysfs_write_file+0x3f/0x150
>>> [ 21.170388] #1: (s_active#59){......}, at: [<ffffffff811c409b>]
>>> sysfs_write_file+0xbb/0x150
>>> [ 21.179149] #2: (rtnl_mutex){......}, at: [<ffffffff81590bf0>]
>>> rtnl_trylock+0x10/0x20
>>> [ 21.187403] #3: (&bond->lock){......}, at: [<ffffffff8145be6f>]
>>> bond_enslave+0x4ef/0xb80
>>> [ 21.195904] Modules linked in: iptable_filter kvm_intel kvm acpi_cpufreq
>>> mperf button processor mousedev iTCO_wdt
>>> [ 21.206644] Pid: 2003, comm: ifup-bonding Tainted: G W
>>> 3.8.1-Isht-Van #5
>>> [ 21.214240] Call Trace:
>>> [ 21.216732] [<ffffffff8162b029>] __schedule_bug+0x5e/0x6c
>>> [ 21.222254] [<ffffffff81634592>] __schedule+0x762/0x7f0
>>> [ 21.227604] [<ffffffff81634734>] schedule+0x24/0x70
>>> [ 21.232606] [<ffffffff816336f4>] schedule_hrtimeout_range_clock+0xa4/0x130
>>> [ 21.239601] [<ffffffff81068250>] ? update_rmtp+0x60/0x60
>>> [ 21.245033] [<ffffffff81068f9f>] ? hrtimer_start_range_ns+0xf/0x20
>>> [ 21.251339] [<ffffffff8163378e>] schedule_hrtimeout_range+0xe/0x10
>>> [ 21.257635] [<ffffffff8104ec1b>] usleep_range+0x3b/0x40
>>> [ 21.262987] [<ffffffff814b2d7c>] ixgbe_acquire_swfw_sync_X540+0xbc/0x100
>>> [ 21.269811] [<ffffffff814aeb0d>] ixgbe_read_phy_reg_generic+0x3d/0x140
>>> [ 21.276461] [<ffffffff814aedac>]
>>> ixgbe_get_copper_link_capabilities_generic+0x2c/0x60
>>> [ 21.284409] [<ffffffff8145be6f>] ? bond_enslave+0x4ef/0xb80
>>> [ 21.290106] [<ffffffff814a64e4>] ixgbe_get_settings+0x34/0x340
>>> [ 21.296067] [<ffffffff81586ab8>] __ethtool_get_settings+0x88/0x130
>>> [ 21.302369] [<ffffffff814568a3>] bond_update_speed_duplex+0x23/0x60
>>> [ 21.308754] [<ffffffff8145bed9>] bond_enslave+0x559/0xb80
>>> [ 21.314278] [<ffffffff8146454f>] bonding_store_slaves+0x16f/0x1c0
>>> [ 21.320491] [<ffffffff813bfb83>] dev_attr_store+0x13/0x30
>>> [ 21.326009] [<ffffffff811c40b4>] sysfs_write_file+0xd4/0x150
>>> [ 21.331793] [<ffffffff81154b81>] vfs_write+0xb1/0x190
>>> [ 21.336964] [<ffffffff81154ee0>] sys_write+0x50/0xa0
>>> [ 21.342053] [<ffffffff81637092>] system_call_fastpath+0x16/0x1b
>>> [ 21.348191] BUG: scheduling while atomic: ifup-bonding/2003/0x00000002
>>> [ 21.354775] 4 locks held by ifup-bonding/2003:
>>> [ 21.359258] #0: (&buffer->mutex){......}, at: [<ffffffff811c401f>]
>>> sysfs_write_file+0x3f/0x150
>>> [ 21.368283] #1: (s_active#59){......}, at: [<ffffffff811c409b>]
>>> sysfs_write_file+0xbb/0x150
>>> [ 21.377104] #2: (rtnl_mutex){......}, at: [<ffffffff81590bf0>]
>>> rtnl_trylock+0x10/0x20
>>> [ 21.385343] #3: (&bond->lock){......}, at: [<ffffffff8145be6f>]
>>> bond_enslave+0x4ef/0xb80
>>> [ 21.393887] Modules linked in: iptable_filter kvm_intel kvm acpi_cpufreq
>>> mperf button processor mousedev iTCO_wdt
>>> [ 21.404575] Pid: 2003, comm: ifup-bonding Tainted: G W
>>> 3.8.1-Isht-Van #5
>>> [ 21.412176] Call Trace:
>>> [ 21.414666] [<ffffffff8162b029>] __schedule_bug+0x5e/0x6c
>>> [ 21.420188] [<ffffffff81634592>] __schedule+0x762/0x7f0
>>> [ 21.425536] [<ffffffff81634734>] schedule+0x24/0x70
>>> [ 21.430541] [<ffffffff816336f4>] schedule_hrtimeout_range_clock+0xa4/0x130
>>> [ 21.437532] [<ffffffff81068250>] ? update_rmtp+0x60/0x60
>>> [ 21.442967] [<ffffffff81068250>] ? update_rmtp+0x60/0x60
>>> [ 21.448407] [<ffffffff81068f9f>] ? hrtimer_start_range_ns+0xf/0x20
>>> [ 21.454712] [<ffffffff8163378e>] schedule_hrtimeout_range+0xe/0x10
>>> [ 21.461015] [<ffffffff8104ec1b>] usleep_range+0x3b/0x40
>>> [ 21.466370] [<ffffffff814b2cae>] ixgbe_release_swfw_sync_X540+0x4e/0x60
>>> [ 21.473105] [<ffffffff814aebdd>] ixgbe_read_phy_reg_generic+0x10d/0x140
>>> [ 21.479843] [<ffffffff814aedac>]
>>> ixgbe_get_copper_link_capabilities_generic+0x2c/0x60
>>> [ 21.487787] [<ffffffff8145be6f>] ? bond_enslave+0x4ef/0xb80
>>> [ 21.493513] [<ffffffff814a64e4>] ixgbe_get_settings+0x34/0x340
>>> [ 21.499468] [<ffffffff81586ab8>] __ethtool_get_settings+0x88/0x130
>>> [ 21.505767] [<ffffffff814568a3>] bond_update_speed_duplex+0x23/0x60
>>> [ 21.512153] [<ffffffff8145bed9>] bond_enslave+0x559/0xb80
>>> [ 21.517677] [<ffffffff8146454f>] bonding_store_slaves+0x16f/0x1c0
>>> [ 21.523889] [<ffffffff813bfb83>] dev_attr_store+0x13/0x30
>>> [ 21.529412] [<ffffffff811c40b4>] sysfs_write_file+0xd4/0x150
>>> [ 21.535193] [<ffffffff81154b81>] vfs_write+0xb1/0x190
>>> [ 21.540373] [<ffffffff81154ee0>] sys_write+0x50/0xa0
>>> [ 21.545463] [<ffffffff81637092>] system_call_fastpath+0x16/0x1b
>>> --
>>>
>>
>>
>
^ permalink raw reply
* Help regarding kernel hang issue
From: Ajith Adapa @ 2013-03-02 4:38 UTC (permalink / raw)
To: netdev
Hi,
Any pointers or help would be of great help for the below issue.
I am trying to run a kernel module in 3.6 kernel and finding a hang
issue ideally seems to be because of locks. I could see the trace as
shown below. Since it is a hang I could see some more traces on screen
but cannot capture them fully.
When I tried KGDB .. I dont see any hang in my target machine other
than the same log in dmesg. Why doesn't kernel hang reproducible with
KGDB ??
[ 514.299185] ------------[ cut here ]------------
[ 514.299999] WARNING: at kernel/lockdep.c:2966 lockdep_init_map+0x16a/0x420()
[ 514.307653] Hardware name: VirtualBox
[ 514.307735] Modules linked in: l2_module ppdev joydev microcode
pcspkr parport_pc i2c_piix4 e1000 parport i2c_core uinput
[ 514.308001] Pid: 911, comm: pm Not tainted 3.6.11-ZebOS #3
[ 514.310001] Call Trace:
[ 514.311000] [<c043c812>] warn_slowpath_common+0x72/0xa0
[ 514.312995] [<c0494b4a>] ? lockdep_init_map+0x16a/0x420
[ 514.317999] [<c0494b4a>] ? lockdep_init_map+0x16a/0x420
[ 514.320622] [<c043c862>] warn_slowpath_null+0x22/0x30
[ 514.322959] [<c0494b4a>] lockdep_init_map+0x16a/0x420
[ 514.324957] [<c08706b5>] sk_alloc+0x95/0xf0
[ 514.326986] [<e09ec430>] garp_create+0x47/0xea [l2_module]
[ 514.329282] [<c086bb70>] ? __sock_create+0x140/0x250
[ 514.330932] [<c086bac6>] ? __sock_create+0x96/0x250
[ 514.333271] [<c0984580>] ? spurious_fault+0x9b/0x9b
[ 514.335002] [<c086bcfd>] sock_create+0x3d/0x50
[ 514.336986] [<c086c2e2>] sys_socket+0x32/0x80
[ 514.372351] [<c086d480>] sys_socketcall+0x70/0x2d0
[ 514.408357] [<c06882a1>] ? copy_to_user+0x41/0x60
[ 514.444340] [<c09816d0>] syscall_call+0x7/0xb
[ 514.479187] ---[ end trace 13a03f62973de4ee ]---
Regards,
Ajith
^ permalink raw reply
* Re: tg3: regression of netdev stats
From: Nithin Nayak Sujir @ 2013-03-02 2:30 UTC (permalink / raw)
To: Michael Chan; +Cc: OGAWA Hirofumi, davem, netdev
In-Reply-To: <1362152836.6212.27.camel@LTIRV-MCHAN1.corp.ad.broadcom.com>
On 3/1/2013 7:47 AM, Michael Chan wrote:
> On Fri, 2013-03-01 at 22:21 +0900, OGAWA Hirofumi wrote:
>> Hi,
>>
>> f4a46d1f46a8fece34edd2023e054072b02e110d (tg3: Prevent spurious tx
>> timeout by setting carrier off before tx disable.) seems to add the bug.
>>
>> On 3.8.1 (I didn't use 3.7.x series), "ifconfig" commands doesn't show
>> any stats, i.e. all stats are zero.
>
> No stats on an active device transmitting and receiving packets? I
> don't seem to see the same problem, but we'll look into this further.
> Thanks.
>
Hi Hirofumi,
I too am not able to see zero stats with 3.8.1. I ran traffic and stats
go up as expected.
Are you certain that the interface was up? Did you run ifconfig with
traffic running on the interface?
Thanks,
Nithin.
>> And bisect points the above commit.
>> In fact, reverting the above patch fixes the regression of netdev stats.
>>
>> This patch looks like strange, and I'm not sure what this want to do.
>> Any ideas?
>
> Every time we reset the device (ethtool, MTU change, etc), we need to
> turn off all the tx queues before resetting. As soon as we turn off
> these queues, if we don't turn off carrier, a tx timeout may be
> triggered if it's been more than 5 seconds since the last transmit on
> any of the tx queues. These tx timeouts cause unnecessary concern to
> the user.
>
>>
>> Well, anyway, this is bug report.
>>
>> Thanks.
>
>
^ permalink raw reply
* hang with e1000_
From: Yinghai Lu @ 2013-03-01 23:44 UTC (permalink / raw)
To: Jeff Kirsher, NetDev, Linux Kernel Mailing List
on today mainline tree.
[ 529.379490] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs"
disables this message.
[ 529.399350] swapper/0 D ffff883025294000 0 1 0 0x00000000
[ 529.399726] ffff8810274f5ab8 0000000000000046 ffffffff810b3111
ffff8810274f5fd8
[ 529.424058] ffff8810274f5fd8 0000000000004000 ffff881027578000
ffff8810274f8000
[ 529.439317] ffff8810274f59f8 0000000000000002 0000000000000282
ffff88203e40d680
[ 529.439740] Call Trace:
[ 529.459254] [<ffffffff810b3111>] ? __hrtimer_start_range_ns+0x391/0x400
[ 529.459610] [<ffffffff810e95bd>] ? trace_hardirqs_on+0xd/0x10
[ 529.480104] [<ffffffff810b3111>] ? __hrtimer_start_range_ns+0x391/0x400
[ 529.480482] [<ffffffff8219535d>] schedule+0x5d/0x60
[ 529.499357] [<ffffffff8219405c>] schedule_hrtimeout_range_clock+0x10c/0x160
[ 529.499710] [<ffffffff810b2720>] ? update_rmtp+0x70/0x70
[ 529.519406] [<ffffffff810b31b4>] ? hrtimer_start_range_ns+0x14/0x20
[ 529.539192] [<ffffffff821940c3>] schedule_hrtimeout_range+0x13/0x20
[ 529.539507] [<ffffffff8109a040>] usleep_range+0x40/0x50
[ 529.559225] [<ffffffff81b33dc9>] e1000_get_cfg_done_82571+0x39/0x50
[ 529.559539] [<ffffffff81b42dc2>] e1000e_phy_hw_reset_generic+0x102/0x160
[ 529.579338] [<ffffffff81b41ac7>] e1000e_copper_link_setup_igp+0x17/0x160
[ 529.579662] [<ffffffff81b34e80>] e1000_setup_copper_link_82571+0xb0/0xd0
[ 529.599457] [<ffffffff81b3e22f>] e1000e_setup_link_generic+0xbf/0x280
[ 529.621078] [<ffffffff81b33fc2>] e1000_setup_link_82571+0x32/0x40
[ 529.621365] [<ffffffff81b54495>] e1000_open+0xc5/0x540
[ 529.639395] [<ffffffff810b4f3e>] ? __raw_notifier_call_chain+0xe/0x10
[ 529.639723] [<ffffffff81f95510>] __dev_open+0x90/0x100
[ 529.659431] [<ffffffff81f95804>] __dev_change_flags+0xd4/0x170
[ 529.659723] [<ffffffff81f95948>] dev_change_flags+0x28/0x70
[ 529.679957] [<ffffffff82ffc978>] ip_auto_config+0x193/0xea4
[ 529.680270] [<ffffffff82ffc7e5>] ? root_nfs_parse_addr+0xc0/0xc0
[ 529.699378] [<ffffffff82179e58>] ? printk+0x4d/0x4f
[ 529.699668] [<ffffffff82ffc7e5>] ? root_nfs_parse_addr+0xc0/0xc0
[ 529.719381] [<ffffffff81000254>] do_one_initcall+0x64/0x160
[ 529.719692] [<ffffffff82faf31c>] kernel_init_freeable+0x1bf/0x251
[ 529.739527] [<ffffffff82faea6c>] ? loglevel+0x31/0x31
[ 529.739835] [<ffffffff82164a70>] ? rest_init+0xc0/0xc0
[ 529.759417] [<ffffffff82164a7e>] kernel_init+0xe/0xf0
[ 529.759658] [<ffffffff8219f75c>] ret_from_fork+0x7c/0xb0
[ 529.779357] [<ffffffff82164a70>] ? rest_init+0xc0/0xc0
[ 529.779592] 1 lock held by swapper/0/1:
[ 529.799285] #0: (rtnl_mutex){+.+.+.}, at: [<ffffffff81fa3487>]
rtnl_lock+0x17/0x20
The system is nehalem-ex 8 sockets.
Another westmere-ex 8 sockets is ok.
They have same IO add-on cards.
Thanks
Yinghai
^ permalink raw reply
* Re: [RFC PATCH 0/5] net: low latency Ethernet device polling
From: Tom Herbert @ 2013-03-01 22:57 UTC (permalink / raw)
To: David Miller
Cc: eliezer.tamir, linux-kernel, netdev, jesse.brandeburg,
e1000-devel, willemb, andi, hpa, eliezer
In-Reply-To: <20130301.162400.1645765127882618751.davem@davemloft.net>
> This is exactly the kind of approach that makes sense rather than
> trying to put entire TCP stacks in the network card firmware.
>
And should also obviate the need to put a full TCP stack in user space!
> Thanks again for doing this work and I look forward to applying
> this stuff once all the kinks are worked out. The folks in the
> Intel NIC group continue to impress me.
>
> --
> 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 v2 net-next 2/4] ixgbe: Remove driver specific fdb handlers.
From: John Fastabend @ 2013-03-01 22:22 UTC (permalink / raw)
To: Vlad Yasevich; +Cc: netdev, Gregory Rose
In-Reply-To: <1362151906-20993-3-git-send-email-vyasevic@redhat.com>
On 3/1/2013 7:31 AM, Vlad Yasevich wrote:
> Remove driver specific fdb handlers since they are the same
> as the default ones.
>
> CC: John Fastabend <john.r.fastabend@intel.com>
> CC: Gregory Rose <gregory.v.rose@intel.com>
> Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
> ---
> drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 42 +------------------------
> 1 files changed, 1 insertions(+), 41 deletions(-)
^^^^^^^^^^^^^^^^
nice.
Acked-By: John Fastabend <john.r.fastabend@intel.com>
^ permalink raw reply
* Re: [PATCH v2 net-next 1/4] net: generic fdb support for drivers without ndo_fdb_<op>
From: John Fastabend @ 2013-03-01 22:20 UTC (permalink / raw)
To: Vlad Yasevich; +Cc: netdev
In-Reply-To: <1362151906-20993-2-git-send-email-vyasevic@redhat.com>
On 3/1/2013 7:31 AM, Vlad Yasevich wrote:
> If the driver does not support the ndo_op use the generic
> handler for it. This should work in the majority of cases.
> Eventually the fdb_dflt_add call gets translated into a
> __dev_set_rx_mode() call which should handle hardware
> support for filtering via the IFF_UNICAST_FLT flag.
>
> Namely IFF_UNICAST_FLT indicates if the hardware can do
> unicast address filtering. If no support is available
> the device is put into promisc mode.
>
> CC: John Fastabend <john.r.fastabend@intel.com>
> Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
> ---
> include/linux/rtnetlink.h | 9 +++++
> net/core/rtnetlink.c | 81 +++++++++++++++++++++++++++++++++++++++++---
> 2 files changed, 84 insertions(+), 6 deletions(-)
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
Feel free to carry the line forward when you submit these after net-next
opens.
^ permalink raw reply
* Re: [patch net-next 0/2] team: introduce random mode
From: David Miller @ 2013-03-01 21:26 UTC (permalink / raw)
To: jiri; +Cc: netdev, edumazet, fbl
In-Reply-To: <1362133566-1382-1-git-send-email-jiri@resnulli.us>
From: Jiri Pirko <jiri@resnulli.us>
Date: Fri, 1 Mar 2013 11:26:04 +0100
> Jiri Pirko (2):
> team: introduce two default team_modeop functions and use them in
> modes
> team: introduce random mode
Looks fine, please resubmit when net-next opens back up.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox