* Re: kernel crash in bpf_jit on x86_64 when running nmap
From: Alexei Starovoitov @ 2014-10-10 21:17 UTC (permalink / raw)
To: Darrick J. Wong
Cc: David S. Miller, linux-kernel, Daniel Borkmann, H. Peter Anvin,
Thomas Gleixner, Ingo Molnar, Network Development
In-Reply-To: <20141010204403.GA30018@birch.djwong.org>
On Fri, Oct 10, 2014 at 1:44 PM, Darrick J. Wong
<darrick.wong@oracle.com> wrote:
> Hi everyone,
>
> I was running nmap on a x86_64 qemu guest and experienced the following crash:
>
> # nmap -sS -O -vvv 192.168.122.1
> Starting Nmap 6.40 ( http://nmap.org ) at 2014-10-10 13:14 PDT
> Initiating ARP Ping Scan at 13:14
> Scanning 192.168.122.1 [1 port]
> <kaboom>
>
> dmesg output is as follows (I set net.core.bpf_jit_enable=2 the second time):
>
> [ 32.376291] flen=3 proglen=82 pass=0 image=ffffffffc01ac65b
> [ 32.377595] JIT code: 00000000: 55 48 89 e5 48 81 ec 28 02 00 00 48 89 9d d8 fd
> [ 32.379243] JIT code: 00000010: ff ff 4c 89 ad e0 fd ff ff 4c 89 b5 e8 fd ff ff
> [ 32.380984] JIT code: 00000020: 4c 89 bd f0 fd ff ff 31 c0 4d 31 ed 48 89 fb b8
> [ 32.382606] JIT code: 00000030: 00 00 00 00 48 8b 9d d8 fd ff ff 4c 8b ad e0 fd
> [ 32.384280] JIT code: 00000040: ff ff 4c 8b b5 e8 fd ff ff 4c 8b bd f0 fd ff ff
> [ 32.385911] JIT code: 00000050: c9 c3
> [ 32.386841] bpf_jit: proglen=265 != oldproglen=269
thanks for the report. The line above indicates that JIT tried to emit
4 byte longer program than during pre-final pass.
Will look at it asap.
^ permalink raw reply
* Re: [PATCH] fm10k: Add skb->xmit_more support
From: Vick, Matthew @ 2014-10-10 21:12 UTC (permalink / raw)
To: alexander.duyck@gmail.com, e1000-devel@lists.sourceforge.net,
netdev@vger.kernel.org, Kirsher, Jeffrey T
In-Reply-To: <20141010201714.20593.67813.stgit@ahduyck-workstation.home>
On 10/10/14, 1:17 PM, "alexander.duyck@gmail.com"
<alexander.duyck@gmail.com> wrote:
>From: Alexander Duyck <alexander.h.duyck@redhat.com>
>
>This change adds suport for skb->xmit_more based on the changes that were
>made to igb to support the feature. The main changes are moving up the
>check for maybe_stop_tx so that we can check netif_xmit_stopped to
>determine
>if we must write the tail because we can add no further buffers.
>
>Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
s/suport/support in the first line of the patch description, but other
than that this looks good to me. Thanks, Alex!
Acked-by: Matthew Vick <matthew.vick@intel.com>
^ permalink raw reply
* [PATCH net] skbuff: fix ftrace handling in skb_unshare
From: Alexander Aring @ 2014-10-10 21:10 UTC (permalink / raw)
To: netdev; +Cc: kernel, Alexander Aring
If the skb is not dropped afterwards we should run consume_skb instead
kfree_skb. Inside of function skb_unshare we do always a kfree_skb,
doesn't depend if skb_copy failed or was successful.
This patch switch this behaviour like skb_share_check, if allocation of
sk_buff failed we use kfree_skb otherwise consume_skb.
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
include/linux/skbuff.h | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index abde271..d150734 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1116,7 +1116,12 @@ static inline struct sk_buff *skb_unshare(struct sk_buff *skb,
might_sleep_if(pri & __GFP_WAIT);
if (skb_cloned(skb)) {
struct sk_buff *nskb = skb_copy(skb, pri);
- kfree_skb(skb); /* Free our shared copy */
+
+ /* Free our shared copy */
+ if (likely(nskb))
+ consume_skb(skb);
+ else
+ kfree_skb(skb);
skb = nskb;
}
return skb;
--
2.1.2
^ permalink raw reply related
* Re: [Nios2-dev] [PATCH net-next 0/2] Altera TSE with no PHY
From: Matthew Gerlach @ 2014-10-10 20:46 UTC (permalink / raw)
To: Walter Lozano, netdev@vger.kernel.org
Cc: f.fainelli@gmail.com, tobias.klauser@gmail.com,
vbridgers2013@gmail.com, nios2-dev@lists.rocketboards.org,
davem@davemloft.net, guido@vanguardiasur.com.ar
In-Reply-To: <1412359741-8423-1-git-send-email-walter@vanguardiasur.com.ar>
Hi Walter,
I've examined your patch, and it makes sense to me. I tested your patch again the TSE example design, and it did not break anything.
Thanks,
Matthew Gerlach
________________________________________
From: nios2-dev-bounces@lists.rocketboards.org <nios2-dev-bounces@lists.rocketboards.org> on behalf of Walter Lozano <walter@vanguardiasur.com.ar>
Sent: Friday, October 3, 2014 11:08 AM
To: netdev@vger.kernel.org
Cc: f.fainelli@gmail.com; tobias.klauser@gmail.com; vbridgers2013@gmail.com; nios2-dev@lists.rocketboards.org; davem@davemloft.net; guido@vanguardiasur.com.ar
Subject: [Nios2-dev] [PATCH net-next 0/2] Altera TSE with no PHY
In some scenarios there is no PHY chip present, for example in optical links.
This serie of patches moves PHY get addr and MDIO create to a new function and
avoids PHY and MDIO probing in these cases.
Walter Lozano (2):
Altera TSE: Move PHY get addr and MDIO create
Altera TSE: Add support for no PHY
drivers/net/ethernet/altera/altera_tse_main.c | 65 +++++++++++++++++--------
1 file changed, 44 insertions(+), 21 deletions(-)
--
1.7.10.4
_______________________________________________
Nios2-dev mailing list
Nios2-dev@lists.rocketboards.org
http://lists.rocketboards.org/cgi-bin/mailman/listinfo/nios2-dev
^ permalink raw reply
* Re: [PATCH iproute2] Changed action labels to [action ] format
From: Vadim Kochan @ 2014-10-10 20:59 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev@vger.kernel.org
In-Reply-To: <20141010155648.1f1b51bf@uryu.home.lan>
But the scripts can be easy rewritten ?
On Fri, Oct 10, 2014 at 11:56 PM, Stephen Hemminger
<stephen@networkplumber.org> wrote:
> On Fri, 10 Oct 2014 19:51:56 +0300
> Vadim Kochan <vadim4j@gmail.com> wrote:
>
>> The reasons for this change were:
>> - different ip utils uses different labels for action: Deleted/delete
>> - make an action labels to be easy found in logs
>
> Fine in concept. But people do stupid things like parse the output of commands.
> I am loathe to make cosmetic change.
>
^ permalink raw reply
* Re: [PATCH iproute2] Changed action labels to [action ] format
From: Stephen Hemminger @ 2014-10-10 20:56 UTC (permalink / raw)
To: Vadim Kochan; +Cc: netdev
In-Reply-To: <1412959916-32169-1-git-send-email-vadim4j@gmail.com>
On Fri, 10 Oct 2014 19:51:56 +0300
Vadim Kochan <vadim4j@gmail.com> wrote:
> The reasons for this change were:
> - different ip utils uses different labels for action: Deleted/delete
> - make an action labels to be easy found in logs
Fine in concept. But people do stupid things like parse the output of commands.
I am loathe to make cosmetic change.
^ permalink raw reply
* kernel crash in bpf_jit on x86_64 when running nmap
From: Darrick J. Wong @ 2014-10-10 20:44 UTC (permalink / raw)
To: Alexei Starovoitov, David S. Miller
Cc: linux-kernel, Daniel Borkmann, H. Peter Anvin, Thomas Gleixner,
Ingo Molnar, netdev
Hi everyone,
I was running nmap on a x86_64 qemu guest and experienced the following crash:
# nmap -sS -O -vvv 192.168.122.1
Starting Nmap 6.40 ( http://nmap.org ) at 2014-10-10 13:14 PDT
Initiating ARP Ping Scan at 13:14
Scanning 192.168.122.1 [1 port]
<kaboom>
dmesg output is as follows (I set net.core.bpf_jit_enable=2 the second time):
[ 32.376291] flen=3 proglen=82 pass=0 image=ffffffffc01ac65b
[ 32.377595] JIT code: 00000000: 55 48 89 e5 48 81 ec 28 02 00 00 48 89 9d d8 fd
[ 32.379243] JIT code: 00000010: ff ff 4c 89 ad e0 fd ff ff 4c 89 b5 e8 fd ff ff
[ 32.380984] JIT code: 00000020: 4c 89 bd f0 fd ff ff 31 c0 4d 31 ed 48 89 fb b8
[ 32.382606] JIT code: 00000030: 00 00 00 00 48 8b 9d d8 fd ff ff 4c 8b ad e0 fd
[ 32.384280] JIT code: 00000040: ff ff 4c 8b b5 e8 fd ff ff 4c 8b bd f0 fd ff ff
[ 32.385911] JIT code: 00000050: c9 c3
[ 32.386841] bpf_jit: proglen=265 != oldproglen=269
[ 32.387936] flen=33 proglen=265 pass=0 image=ffffffffc01ae3a2
[ 32.389288] JIT code: 00000000: 55 48 89 e5 48 81 ec 28 02 00 00 48 89 9d d8 fd
[ 32.390916] JIT code: 00000010: ff ff 4c 89 ad e0 fd ff ff 4c 89 b5 e8 fd ff ff
[ 32.393150] JIT code: 00000020: 4c 89 bd f0 fd ff ff 31 c0 4d 31 ed 44 8b 4f 68
[ 32.394820] JIT code: 00000030: 44 2b 4f 6c 4c 8b 97 c8 00 00 00 48 89 fb be 0c
[ 32.397303] JIT code: 00000040: 00 00 00 e8 07 85 ec c0 48 81 f8 06 08 00 00 0f
[ 32.399712] JIT code: 00000050: 85 95 00 00 00 be 0c 00 00 00 e8 f0 84 ec c0 48
[ 32.402163] JIT code: 00000060: 81 f8 06 08 00 00 75 7e b8 12 00 00 00 89 45 c0
[ 32.404627] JIT code: 00000070: 44 8b 6d c0 4c 89 ee 83 c6 0e e8 ab 84 ec c0 89
[ 32.407027] JIT code: 00000080: 45 c4 b8 39 00 54 52 89 45 c8 44 8b 6d c8 8b 45
[ 32.409498] JIT code: 00000090: c4 44 29 e8 48 83 f8 00 75 4c be 0c 00 00 00 e8
[ 32.411916] JIT code: 000000a0: a7 84 ec c0 48 81 f8 06 08 00 00 75 39 b8 16 00
[ 32.414479] JIT code: 000000b0: 00 00 89 45 c8 44 8b 6d c8 4c 89 ee 83 c6 0e e8
[ 32.417109] JIT code: 000000c0: 7f 84 ec c0 89 45 cc b8 36 15 00 00 89 45 d0 44
[ 32.419497] JIT code: 000000d0: 8b 6d d0 8b 45 cc 44 29 e8 48 83 f8 00 75 07 b8
[ 32.426032] JIT code: 000000e0: 00 01 00 00 eb 05 b8 00 00 00 00 48 8b 9d d8 fd
[ 32.428445] JIT code: 000000f0: ff ff 4c 8b ad e0 fd ff ff 4c 8b b5 e8 fd ff ff
[ 32.430839] JIT code: 00000100: 4c 8b bd f0 fd ff ff c9 c3
[ 32.432562] BUG: unable to handle kernel NULL pointer dereference at 0000000000000012
[ 32.435275] IP: [<ffffffff810768cc>] efi_call+0xfc/0x100
[ 32.436464] PGD 1f6b59067 PUD 1f79b6067 PMD 0
[ 32.436464] Oops: 0002 [#1] PREEMPT SMP
[ 32.436464] Modules linked in: sch_fq_codel lpc_ich mfd_core fuse nfsd auth_rpcgss exportfs virtio_scsi af_packet
[ 32.436464] CPU: 0 PID: 3577 Comm: nmap Tainted: G W 3.17.0-mcsum #1
[ 32.436464] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS Bochs 01/01/2011
[ 32.436464] task: ffff8801f6c69840 ti: ffff8801f6dd4000 task.ti: ffff8801f6dd4000
[ 32.436464] RIP: 0010:[<ffffffff810768cc>] [<ffffffff810768cc>] efi_call+0xfc/0x100
[ 32.436464] RSP: 0018:ffff8801f6dd7860 EFLAGS: 00010212
[ 32.436464] RAX: 0000000000000012 RBX: ffff8801f76e2f00 RCX: ffffffff81a94d40
[ 32.436464] RDX: ffff88007b1aa080 RSI: 0000000000000020 RDI: ffff8801f76e2f00
[ 32.436464] RBP: ffff8801f6dd7a90 R08: 00000000000000cc R09: 000000000000002a
[ 32.436464] R10: ffff8801f796e420 R11: 000000000000002a R12: ffff8801f796e420
[ 32.436464] R13: 0000000000000012 R14: ffff8801f6981000 R15: 000000000000002a
[ 32.436464] FS: 00007fd30509c780(0000) GS:ffff8801ff600000(0000) knlGS:0000000000000000
[ 32.436464] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 32.436464] CR2: 0000000000000012 CR3: 00000001f6a43000 CR4: 00000000000006f0
[ 32.436464] Stack:
[ 32.436464] ffffffffc01ae421 ffff8801f76e2f00 ffff8801f6f5c000 ffff8801f6981000
[ 32.436464] 000000000000002a 00000000002284d0 0000000000000010 00000000ffffffff
[ 32.436464] 0000000000000000 0000010000000003 ffffffff81aa64c0 ffffffff81aa7248
[ 32.436464] Call Trace:
[ 32.436464] [<ffffffff8114bf1a>] ? __alloc_pages_nodemask+0x14a/0xa40
[ 32.436464] [<ffffffff8129a662>] ? put_dec+0x72/0x90
[ 32.436464] [<ffffffff8129b593>] ? number.isra.2+0x323/0x360
[ 32.436464] [<ffffffff810a8538>] ? __enqueue_entity+0x78/0x80
[ 32.436464] [<ffffffff810a9bc5>] ? set_next_entity+0x95/0xb0
[ 32.436464] [<ffffffff810af0d2>] ? pick_next_task_fair+0x722/0x880
[ 32.436464] [<ffffffff81001625>] ? __switch_to+0x165/0x5a0
[ 32.436464] [<ffffffff8103fa28>] ? lookup_address+0x28/0x30
[ 32.436464] [<ffffffff8103facb>] ? _lookup_address_cpa.isra.11+0x3b/0x40
[ 32.436464] [<ffffffffc013140f>] tpacket_rcv+0xdf/0x88d [af_packet]
[ 32.436464] [<ffffffff815a3b78>] ? __schedule+0x348/0x800
[ 32.436464] [<ffffffff81039e29>] ? kvm_clock_get_cycles+0x9/0x10
[ 32.436464] [<ffffffff8149e4a7>] dev_queue_xmit_nit+0x1b7/0x230
[ 32.436464] [<ffffffff814a07dc>] dev_hard_start_xmit+0x2fc/0x650
[ 32.436464] [<ffffffff814be62e>] sch_direct_xmit+0xee/0x1c0
[ 32.436464] [<ffffffff814a0d15>] __dev_queue_xmit+0x1e5/0x4f0
[ 32.436464] [<ffffffff814a1030>] dev_queue_xmit+0x10/0x20
[ 32.436464] [<ffffffffc0130b93>] packet_sendmsg+0xd33/0x1070 [af_packet]
[ 32.436464] [<ffffffff81485c1e>] sock_sendmsg+0x6e/0x90
[ 32.436464] [<ffffffff81485db1>] SYSC_sendto+0x121/0x1d0
[ 32.436464] [<ffffffff81039e07>] ? kvm_clock_read+0x27/0x40
[ 32.436464] [<ffffffff81039e29>] ? kvm_clock_get_cycles+0x9/0x10
[ 32.436464] [<ffffffff810df857>] ? __getnstimeofday64+0x37/0xd0
[ 32.436464] [<ffffffff810df8fe>] ? getnstimeofday64+0xe/0x30
[ 32.436464] [<ffffffff810df93a>] ? do_gettimeofday+0x1a/0x50
[ 32.436464] [<ffffffff8148684e>] SyS_sendto+0xe/0x10
[ 32.436464] [<ffffffff815a882d>] system_call_fastpath+0x1a/0x1f
[ 32.436464] Code: 0f 28 4c 24 50 0f 28 54 24 40 0f 28 5c 24 30 0f 28 64 24 20 0f 28 6c 24 10 48 8b 74 24 08 0f 22 c6 48 8b 24 24 c3 66 0f 1f 84 00 <00> 00 00 00 85 f6 0f 88 cc 00 00 00 44 89 c8 29 f0 83 f8 03 7e
[ 32.436464] RIP [<ffffffff810768cc>] efi_call+0xfc/0x100
[ 32.436464] RSP <ffff8801f6dd7860>
[ 32.436464] CR2: 0000000000000012
[ 32.436464] ---[ end trace c2167eb2b612f788 ]---
[ 32.436464] Kernel panic - not syncing: Fatal exception in interrupt
[ 32.436464] Kernel Offset: 0x0 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff)
[ 32.436464] ---[ end Kernel panic - not syncing: Fatal exception in interrupt
git bisect traced it back to commit 622582786c9e041d0bd52bde201787adeab249f8
("net: filter: x86: internal BPF JIT") in 3.15-rc4. Reverting it or setting
bpf_jit_enable=0 makes the crash go away and nmap runs to completion.
I'm not sure why %rip is efi_call, since the QEMU guest doesn't support UEFI.
I'm guessing the CPU is off in the weeds, possibly as some side effect of the
proglen mismatch. I can help debug, but I'm not a bpf_jit expert by any means.
:)
Thanks,
--Darrick
^ permalink raw reply
* [PATCH] net: can: esd_usb2: fix memory leak on disconnect
From: Alexey Khoroshilov @ 2014-10-10 20:31 UTC (permalink / raw)
To: Matthias Fuchs, Wolfgang Grandegger, Marc Kleine-Budde
Cc: Alexey Khoroshilov, linux-can, netdev, linux-kernel, ldv-project
It seems struct esd_usb2 dev is not deallocated on disconnect.
The patch adds the deallocation.
Found by Linux Driver Verification project (linuxtesting.org).
Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
---
drivers/net/can/usb/esd_usb2.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb2.c
index b7c9e8b11460..7a90075529c3 100644
--- a/drivers/net/can/usb/esd_usb2.c
+++ b/drivers/net/can/usb/esd_usb2.c
@@ -1143,6 +1143,7 @@ static void esd_usb2_disconnect(struct usb_interface *intf)
}
}
unlink_all_urbs(dev);
+ kfree(dev);
}
}
--
1.9.1
^ permalink raw reply related
* [PATCH v1 2/3] drivers: net: xgene: Add SGMII based 1GbE support
From: Iyappan Subramanian @ 2014-10-10 20:18 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q, netdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
patches-qTEPVZfXA3Y, kchudgar-qTEPVZfXA3Y, Iyappan Subramanian
In-Reply-To: <1412972316-16344-1-git-send-email-isubramanian-qTEPVZfXA3Y@public.gmane.org>
Signed-off-by: Iyappan Subramanian <isubramanian-qTEPVZfXA3Y@public.gmane.org>
Signed-off-by: Keyur Chudgar <kchudgar-qTEPVZfXA3Y@public.gmane.org>
---
drivers/net/ethernet/apm/xgene/Makefile | 2 +-
drivers/net/ethernet/apm/xgene/xgene_enet_hw.c | 1 -
drivers/net/ethernet/apm/xgene/xgene_enet_hw.h | 2 +-
drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 24 +-
drivers/net/ethernet/apm/xgene/xgene_enet_main.h | 5 +-
drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c | 407 ++++++++++++++++++++++
drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.h | 41 +++
drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c | 3 +-
drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h | 4 -
9 files changed, 473 insertions(+), 16 deletions(-)
create mode 100644 drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c
create mode 100644 drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.h
diff --git a/drivers/net/ethernet/apm/xgene/Makefile b/drivers/net/ethernet/apm/xgene/Makefile
index 589b352..68be5655 100644
--- a/drivers/net/ethernet/apm/xgene/Makefile
+++ b/drivers/net/ethernet/apm/xgene/Makefile
@@ -2,6 +2,6 @@
# Makefile for APM X-Gene Ethernet Driver.
#
-xgene-enet-objs := xgene_enet_hw.o xgene_enet_xgmac.o \
+xgene-enet-objs := xgene_enet_hw.o xgene_enet_sgmac.o xgene_enet_xgmac.o \
xgene_enet_main.o xgene_enet_ethtool.o
obj-$(CONFIG_NET_XGENE) += xgene-enet.o
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
index c8f3824..63ea194 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
@@ -410,7 +410,6 @@ static void xgene_gmac_set_mac_addr(struct xgene_enet_pdata *pdata)
addr0 = (dev_addr[3] << 24) | (dev_addr[2] << 16) |
(dev_addr[1] << 8) | dev_addr[0];
addr1 = (dev_addr[5] << 24) | (dev_addr[4] << 16);
- addr1 |= pdata->phy_addr & 0xFFFF;
xgene_enet_wr_mcx_mac(pdata, STATION_ADDR0_ADDR, addr0);
xgene_enet_wr_mcx_mac(pdata, STATION_ADDR1_ADDR, addr1);
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
index 15ec426..dc024c1 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
@@ -44,6 +44,7 @@ static inline u32 xgene_get_bits(u32 val, u32 start, u32 end)
enum xgene_enet_rm {
RM0,
+ RM1,
RM3 = 3
};
@@ -179,7 +180,6 @@ enum xgene_enet_rm {
#define TUND_ADDR 0x4a
#define TSO_IPPROTO_TCP 1
-#define FULL_DUPLEX 2
#define USERINFO_POS 0
#define USERINFO_LEN 32
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
index 9b85239..743eccf 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
@@ -21,6 +21,7 @@
#include "xgene_enet_main.h"
#include "xgene_enet_hw.h"
+#include "xgene_enet_sgmac.h"
#include "xgene_enet_xgmac.h"
static void xgene_enet_init_bufpool(struct xgene_enet_desc_ring *buf_pool)
@@ -813,6 +814,7 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
return pdata->phy_mode;
}
if (pdata->phy_mode != PHY_INTERFACE_MODE_RGMII &&
+ pdata->phy_mode != PHY_INTERFACE_MODE_SGMII &&
pdata->phy_mode != PHY_INTERFACE_MODE_XGMII) {
dev_err(dev, "Incorrect phy-connection-type specified\n");
return -ENODEV;
@@ -830,14 +832,12 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
pdata->eth_csr_addr = base_addr + BLOCK_ETH_CSR_OFFSET;
pdata->eth_ring_if_addr = base_addr + BLOCK_ETH_RING_IF_OFFSET;
pdata->eth_diag_csr_addr = base_addr + BLOCK_ETH_DIAG_CSR_OFFSET;
- if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) {
- pdata->mcx_mac_addr = base_addr + BLOCK_ETH_MAC_OFFSET;
- pdata->mcx_mac_csr_addr = base_addr + BLOCK_ETH_MAC_CSR_OFFSET;
- pdata->rm = RM3;
- } else {
+ if (pdata->phy_mode == PHY_INTERFACE_MODE_XGMII) {
pdata->mcx_mac_addr = base_addr + BLOCK_AXG_MAC_OFFSET;
pdata->mcx_mac_csr_addr = base_addr + BLOCK_AXG_MAC_CSR_OFFSET;
- pdata->rm = RM0;
+ } else {
+ pdata->mcx_mac_addr = base_addr + BLOCK_ETH_MAC_OFFSET;
+ pdata->mcx_mac_csr_addr = base_addr + BLOCK_ETH_MAC_CSR_OFFSET;
}
pdata->rx_buff_cnt = NUM_PKT_BUF;
@@ -881,10 +881,17 @@ static void xgene_enet_setup_ops(struct xgene_enet_pdata *pdata)
case PHY_INTERFACE_MODE_RGMII:
pdata->mac_ops = &xgene_gmac_ops;
pdata->port_ops = &xgene_gport_ops;
+ pdata->rm = RM3;
+ break;
+ case PHY_INTERFACE_MODE_SGMII:
+ pdata->mac_ops = &xgene_sgmac_ops;
+ pdata->port_ops = &xgene_sgport_ops;
+ pdata->rm = RM1;
break;
default:
pdata->mac_ops = &xgene_xgmac_ops;
pdata->port_ops = &xgene_xgport_ops;
+ pdata->rm = RM0;
break;
}
}
@@ -895,6 +902,7 @@ static int xgene_enet_probe(struct platform_device *pdev)
struct xgene_enet_pdata *pdata;
struct device *dev = &pdev->dev;
struct napi_struct *napi;
+ struct xgene_mac_ops *mac_ops;
int ret;
ndev = alloc_etherdev(sizeof(struct xgene_enet_pdata));
@@ -937,10 +945,12 @@ static int xgene_enet_probe(struct platform_device *pdev)
napi = &pdata->rx_ring->napi;
netif_napi_add(ndev, napi, xgene_enet_napi, NAPI_POLL_WEIGHT);
+
+ mac_ops = pdata->mac_ops;
if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII)
ret = xgene_enet_mdio_config(pdata);
else
- INIT_DELAYED_WORK(&pdata->link_work, xgene_enet_link_state);
+ INIT_DELAYED_WORK(&pdata->link_work, mac_ops->link_state);
return ret;
err:
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
index 86cf68b..1057181 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
@@ -39,6 +39,9 @@
#define NUM_PKT_BUF 64
#define NUM_BUFPOOL 32
+#define PHY_POLL_LINK_ON (10 * HZ)
+#define PHY_POLL_LINK_OFF (PHY_POLL_LINK_ON / 5)
+
/* software context of a descriptor ring */
struct xgene_enet_desc_ring {
struct net_device *ndev;
@@ -76,6 +79,7 @@ struct xgene_mac_ops {
void (*tx_disable)(struct xgene_enet_pdata *pdata);
void (*rx_disable)(struct xgene_enet_pdata *pdata);
void (*set_mac_addr)(struct xgene_enet_pdata *pdata);
+ void (*link_state)(struct work_struct *work);
};
struct xgene_port_ops {
@@ -109,7 +113,6 @@ struct xgene_enet_pdata {
void __iomem *base_addr;
void __iomem *ring_csr_addr;
void __iomem *ring_cmd_addr;
- u32 phy_addr;
int phy_mode;
enum xgene_enet_rm rm;
struct rtnl_link_stats64 stats;
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c
new file mode 100644
index 0000000..6038596
--- /dev/null
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c
@@ -0,0 +1,407 @@
+/* Applied Micro X-Gene SoC Ethernet Driver
+ *
+ * Copyright (c) 2014, Applied Micro Circuits Corporation
+ * Authors: Iyappan Subramanian <isubramanian-qTEPVZfXA3Y@public.gmane.org>
+ * Keyur Chudgar <kchudgar-qTEPVZfXA3Y@public.gmane.org>
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "xgene_enet_main.h"
+#include "xgene_enet_hw.h"
+#include "xgene_enet_sgmac.h"
+
+static void xgene_enet_wr_csr(struct xgene_enet_pdata *pdata,
+ u32 offset, u32 val)
+{
+ void __iomem *addr = pdata->eth_csr_addr + offset;
+
+ iowrite32(val, addr);
+}
+
+static void xgene_enet_wr_ring_if(struct xgene_enet_pdata *pdata,
+ u32 offset, u32 val)
+{
+ void __iomem *addr = pdata->eth_ring_if_addr + offset;
+
+ iowrite32(val, addr);
+}
+
+static void xgene_enet_wr_diag_csr(struct xgene_enet_pdata *pdata,
+ u32 offset, u32 val)
+{
+ void __iomem *addr = pdata->eth_diag_csr_addr + offset;
+
+ iowrite32(val, addr);
+}
+
+static bool xgene_enet_wr_indirect(void __iomem *addr, void __iomem *wr,
+ void __iomem *cmd, void __iomem *cmd_done,
+ u32 wr_addr, u32 wr_data)
+{
+ u32 done;
+ u8 wait = 10;
+
+ iowrite32(wr_addr, addr);
+ iowrite32(wr_data, wr);
+ iowrite32(XGENE_ENET_WR_CMD, cmd);
+
+ /* wait for write command to complete */
+ while (!(done = ioread32(cmd_done)) && wait--)
+ udelay(1);
+
+ if (!done)
+ return false;
+
+ iowrite32(0, cmd);
+
+ return true;
+}
+
+static void xgene_enet_wr_mac(struct xgene_enet_pdata *pdata,
+ u32 wr_addr, u32 wr_data)
+{
+ void __iomem *addr, *wr, *cmd, *cmd_done;
+
+ addr = pdata->mcx_mac_addr + MAC_ADDR_REG_OFFSET;
+ wr = pdata->mcx_mac_addr + MAC_WRITE_REG_OFFSET;
+ cmd = pdata->mcx_mac_addr + MAC_COMMAND_REG_OFFSET;
+ cmd_done = pdata->mcx_mac_addr + MAC_COMMAND_DONE_REG_OFFSET;
+
+ if (!xgene_enet_wr_indirect(addr, wr, cmd, cmd_done, wr_addr, wr_data))
+ netdev_err(pdata->ndev, "MCX mac write failed, addr: %04x\n",
+ wr_addr);
+}
+
+static void xgene_enet_rd_csr(struct xgene_enet_pdata *pdata,
+ u32 offset, u32 *val)
+{
+ void __iomem *addr = pdata->eth_csr_addr + offset;
+
+ *val = ioread32(addr);
+}
+
+static void xgene_enet_rd_diag_csr(struct xgene_enet_pdata *pdata,
+ u32 offset, u32 *val)
+{
+ void __iomem *addr = pdata->eth_diag_csr_addr + offset;
+
+ *val = ioread32(addr);
+}
+
+static bool xgene_enet_rd_indirect(void __iomem *addr, void __iomem *rd,
+ void __iomem *cmd, void __iomem *cmd_done,
+ u32 rd_addr, u32 *rd_data)
+{
+ u32 done;
+ u8 wait = 10;
+
+ iowrite32(rd_addr, addr);
+ iowrite32(XGENE_ENET_RD_CMD, cmd);
+
+ /* wait for read command to complete */
+ while (!(done = ioread32(cmd_done)) && wait--)
+ udelay(1);
+
+ if (!done)
+ return false;
+
+ *rd_data = ioread32(rd);
+ iowrite32(0, cmd);
+
+ return true;
+}
+
+static void xgene_enet_rd_mac(struct xgene_enet_pdata *pdata,
+ u32 rd_addr, u32 *rd_data)
+{
+ void __iomem *addr, *rd, *cmd, *cmd_done;
+
+ addr = pdata->mcx_mac_addr + MAC_ADDR_REG_OFFSET;
+ rd = pdata->mcx_mac_addr + MAC_READ_REG_OFFSET;
+ cmd = pdata->mcx_mac_addr + MAC_COMMAND_REG_OFFSET;
+ cmd_done = pdata->mcx_mac_addr + MAC_COMMAND_DONE_REG_OFFSET;
+
+ if (!xgene_enet_rd_indirect(addr, rd, cmd, cmd_done, rd_addr, rd_data))
+ netdev_err(pdata->ndev, "MCX mac read failed, addr: %04x\n",
+ rd_addr);
+}
+
+static int xgene_enet_ecc_init(struct xgene_enet_pdata *pdata)
+{
+ struct net_device *ndev = pdata->ndev;
+ u32 data;
+ u8 wait = 10;
+
+ xgene_enet_wr_diag_csr(pdata, ENET_CFG_MEM_RAM_SHUTDOWN_ADDR, 0x0);
+ do {
+ usleep_range(100, 110);
+ xgene_enet_rd_diag_csr(pdata, ENET_BLOCK_MEM_RDY_ADDR, &data);
+ } while ((data != 0xffffffff) && wait--);
+
+ if (data != 0xffffffff) {
+ netdev_err(ndev, "Failed to release memory from shutdown\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static void xgene_enet_config_ring_if_assoc(struct xgene_enet_pdata *pdata)
+{
+ xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIWQASSOC_ADDR, 0xffffffff);
+ xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIFPQASSOC_ADDR, 0xffffffff);
+}
+
+static void xgene_mii_phy_write(struct xgene_enet_pdata *pdata, u8 phy_id,
+ u32 reg, u16 data)
+{
+ u32 addr, wr_data, done;
+ u8 wait = 10;
+
+ addr = PHY_ADDR(phy_id) | REG_ADDR(reg);
+ xgene_enet_wr_mac(pdata, MII_MGMT_ADDRESS_ADDR, addr);
+
+ wr_data = PHY_CONTROL(data);
+ xgene_enet_wr_mac(pdata, MII_MGMT_CONTROL_ADDR, wr_data);
+
+ while (wait--) {
+ xgene_enet_rd_mac(pdata, MII_MGMT_INDICATORS_ADDR, &done);
+ if (!(done & BUSY_MASK))
+ break;
+ usleep_range(10, 20);
+ }
+ if (done & BUSY_MASK)
+ netdev_err(pdata->ndev, "MII_MGMT write failed\n");
+}
+
+static void xgene_mii_phy_read(struct xgene_enet_pdata *pdata, u8 phy_id,
+ u32 reg, u32 *data)
+{
+ u32 addr, done;
+ u8 wait = 10;
+
+ addr = PHY_ADDR(phy_id) | REG_ADDR(reg);
+ xgene_enet_wr_mac(pdata, MII_MGMT_ADDRESS_ADDR, addr);
+ xgene_enet_wr_mac(pdata, MII_MGMT_COMMAND_ADDR, READ_CYCLE_MASK);
+
+ while (wait--) {
+ xgene_enet_rd_mac(pdata, MII_MGMT_INDICATORS_ADDR, &done);
+ if (!(done & BUSY_MASK))
+ break;
+ usleep_range(10, 20);
+ }
+ if (done & BUSY_MASK)
+ netdev_err(pdata->ndev, "MII_MGMT read failed\n");
+
+ xgene_enet_rd_mac(pdata, MII_MGMT_STATUS_ADDR, data);
+ xgene_enet_wr_mac(pdata, MII_MGMT_COMMAND_ADDR, 0);
+}
+
+static void xgene_sgmac_reset(struct xgene_enet_pdata *pdata)
+{
+ xgene_enet_wr_mac(pdata, MAC_CONFIG_1_ADDR, SOFT_RESET1);
+ xgene_enet_wr_mac(pdata, MAC_CONFIG_1_ADDR, 0);
+}
+
+static void xgene_sgmac_set_mac_addr(struct xgene_enet_pdata *pdata)
+{
+ u32 addr0, addr1;
+ u8 *dev_addr = pdata->ndev->dev_addr;
+
+ addr0 = (dev_addr[3] << 24) | (dev_addr[2] << 16) |
+ (dev_addr[1] << 8) | dev_addr[0];
+ xgene_enet_wr_mac(pdata, STATION_ADDR0_ADDR, addr0);
+
+ xgene_enet_rd_mac(pdata, STATION_ADDR1_ADDR, &addr1);
+ addr1 |= (dev_addr[5] << 24) | (dev_addr[4] << 16);
+ xgene_enet_wr_mac(pdata, STATION_ADDR1_ADDR, addr1);
+}
+
+static u32 xgene_enet_link_status(struct xgene_enet_pdata *pdata)
+{
+ u32 data;
+
+ xgene_mii_phy_read(pdata, INT_PHY_ADDR,
+ SGMII_BASE_PAGE_ABILITY_ADDR >> 2, &data);
+
+ return data & LINK_UP;
+}
+
+static void xgene_sgmac_init(struct xgene_enet_pdata *pdata)
+{
+ u32 data, loop = 10;
+
+ xgene_sgmac_reset(pdata);
+
+ /* Enable auto-negotiation */
+ xgene_mii_phy_write(pdata, INT_PHY_ADDR,
+ SGMII_CONTROL_ADDR >> 2, 0x1000);
+ xgene_mii_phy_write(pdata, INT_PHY_ADDR,
+ SGMII_TBI_CONTROL_ADDR >> 2, 0);
+
+ while (loop--) {
+ xgene_mii_phy_read(pdata, INT_PHY_ADDR,
+ SGMII_STATUS_ADDR >> 2, &data);
+ if ((data & AUTO_NEG_COMPLETE) && (data & LINK_STATUS))
+ break;
+ usleep_range(10, 20);
+ }
+ if (!(data & AUTO_NEG_COMPLETE) || !(data & LINK_STATUS))
+ netdev_err(pdata->ndev, "Auto-negotiation failed\n");
+
+ xgene_enet_rd_mac(pdata, MAC_CONFIG_2_ADDR, &data);
+ ENET_INTERFACE_MODE2_SET(&data, 2);
+ xgene_enet_wr_mac(pdata, MAC_CONFIG_2_ADDR, data | FULL_DUPLEX2);
+ xgene_enet_wr_mac(pdata, INTERFACE_CONTROL_ADDR, ENET_GHD_MODE);
+
+ xgene_enet_rd_csr(pdata, ENET_SPARE_CFG_REG_ADDR, &data);
+ data |= MPA_IDLE_WITH_QMI_EMPTY;
+ xgene_enet_wr_csr(pdata, ENET_SPARE_CFG_REG_ADDR, data);
+
+ xgene_sgmac_set_mac_addr(pdata);
+
+ xgene_enet_rd_csr(pdata, DEBUG_REG_ADDR, &data);
+ data |= CFG_BYPASS_UNISEC_TX | CFG_BYPASS_UNISEC_RX;
+ xgene_enet_wr_csr(pdata, DEBUG_REG_ADDR, data);
+
+ /* Adjust MDC clock frequency */
+ xgene_enet_rd_mac(pdata, MII_MGMT_CONFIG_ADDR, &data);
+ MGMT_CLOCK_SEL_SET(&data, 7);
+ xgene_enet_wr_mac(pdata, MII_MGMT_CONFIG_ADDR, data);
+
+ /* Enable drop if bufpool not available */
+ xgene_enet_rd_csr(pdata, RSIF_CONFIG_REG_ADDR, &data);
+ data |= CFG_RSIF_FPBUFF_TIMEOUT_EN;
+ xgene_enet_wr_csr(pdata, RSIF_CONFIG_REG_ADDR, data);
+
+ /* Rtype should be copied from FP */
+ xgene_enet_wr_csr(pdata, RSIF_RAM_DBG_REG0_ADDR, 0);
+
+ /* Bypass traffic gating */
+ xgene_enet_wr_csr(pdata, CFG_LINK_AGGR_RESUME_0_ADDR, TX_PORT0);
+ xgene_enet_wr_csr(pdata, CFG_BYPASS_ADDR, RESUME_TX);
+ xgene_enet_wr_csr(pdata, SG_RX_DV_GATE_REG_0_ADDR, RESUME_RX0);
+}
+
+static void xgene_sgmac_rx_enable(struct xgene_enet_pdata *pdata)
+{
+ u32 data;
+
+ xgene_enet_rd_mac(pdata, MAC_CONFIG_1_ADDR, &data);
+ xgene_enet_wr_mac(pdata, MAC_CONFIG_1_ADDR, data | RX_EN);
+}
+
+static void xgene_sgmac_tx_enable(struct xgene_enet_pdata *pdata)
+{
+ u32 data;
+
+ xgene_enet_rd_mac(pdata, MAC_CONFIG_1_ADDR, &data);
+ xgene_enet_wr_mac(pdata, MAC_CONFIG_1_ADDR, data | TX_EN);
+}
+
+static void xgene_sgmac_rx_disable(struct xgene_enet_pdata *pdata)
+{
+ u32 data;
+
+ xgene_enet_rd_mac(pdata, MAC_CONFIG_1_ADDR, &data);
+ xgene_enet_wr_mac(pdata, MAC_CONFIG_1_ADDR, data & ~RX_EN);
+}
+
+static void xgene_sgmac_tx_disable(struct xgene_enet_pdata *pdata)
+{
+ u32 data;
+
+ xgene_enet_rd_mac(pdata, MAC_CONFIG_1_ADDR, &data);
+ xgene_enet_wr_mac(pdata, MAC_CONFIG_1_ADDR, data & ~TX_EN);
+}
+
+static void xgene_enet_reset(struct xgene_enet_pdata *pdata)
+{
+ clk_prepare_enable(pdata->clk);
+ clk_disable_unprepare(pdata->clk);
+ clk_prepare_enable(pdata->clk);
+
+ xgene_enet_ecc_init(pdata);
+ xgene_enet_config_ring_if_assoc(pdata);
+}
+
+static void xgene_enet_cle_bypass(struct xgene_enet_pdata *pdata,
+ u32 dst_ring_num, u16 bufpool_id)
+{
+ u32 cb, fpsel;
+
+ xgene_enet_rd_csr(pdata, CLE_BYPASS_REG0_0_ADDR, &cb);
+ cb |= CFG_CLE_BYPASS_EN0;
+ CFG_CLE_IP_PROTOCOL0_SET(&cb, 3);
+ xgene_enet_wr_csr(pdata, CLE_BYPASS_REG0_0_ADDR, cb);
+
+ fpsel = xgene_enet_ring_bufnum(bufpool_id) - 0x20;
+ xgene_enet_rd_csr(pdata, CLE_BYPASS_REG1_0_ADDR, &cb);
+ CFG_CLE_DSTQID0_SET(&cb, dst_ring_num);
+ CFG_CLE_FPSEL0_SET(&cb, fpsel);
+ xgene_enet_wr_csr(pdata, CLE_BYPASS_REG1_0_ADDR, cb);
+}
+
+static void xgene_enet_shutdown(struct xgene_enet_pdata *pdata)
+{
+ clk_disable_unprepare(pdata->clk);
+}
+
+static void xgene_enet_link_state(struct work_struct *work)
+{
+ struct xgene_enet_pdata *pdata = container_of(to_delayed_work(work),
+ struct xgene_enet_pdata, link_work);
+ struct net_device *ndev = pdata->ndev;
+ u32 link_status, poll_interval;
+
+ link_status = xgene_enet_link_status(pdata);
+ if (link_status) {
+ if (!netif_carrier_ok(ndev)) {
+ netif_carrier_on(ndev);
+ xgene_sgmac_init(pdata);
+ xgene_sgmac_rx_enable(pdata);
+ xgene_sgmac_tx_enable(pdata);
+ netdev_info(ndev, "Link is Up - 1Gbps\n");
+ }
+ poll_interval = PHY_POLL_LINK_ON;
+ } else {
+ if (netif_carrier_ok(ndev)) {
+ xgene_sgmac_rx_disable(pdata);
+ xgene_sgmac_tx_disable(pdata);
+ netif_carrier_off(ndev);
+ netdev_info(ndev, "Link is Down\n");
+ }
+ poll_interval = PHY_POLL_LINK_OFF;
+ }
+
+ schedule_delayed_work(&pdata->link_work, poll_interval);
+}
+
+struct xgene_mac_ops xgene_sgmac_ops = {
+ .init = xgene_sgmac_init,
+ .reset = xgene_sgmac_reset,
+ .rx_enable = xgene_sgmac_rx_enable,
+ .tx_enable = xgene_sgmac_tx_enable,
+ .rx_disable = xgene_sgmac_rx_disable,
+ .tx_disable = xgene_sgmac_tx_disable,
+ .set_mac_addr = xgene_sgmac_set_mac_addr,
+ .link_state = xgene_enet_link_state
+};
+
+struct xgene_port_ops xgene_sgport_ops = {
+ .reset = xgene_enet_reset,
+ .cle_bypass = xgene_enet_cle_bypass,
+ .shutdown = xgene_enet_shutdown,
+};
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.h b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.h
new file mode 100644
index 0000000..de43246
--- /dev/null
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.h
@@ -0,0 +1,41 @@
+/* Applied Micro X-Gene SoC Ethernet Driver
+ *
+ * Copyright (c) 2014, Applied Micro Circuits Corporation
+ * Authors: Iyappan Subramanian <isubramanian-qTEPVZfXA3Y@public.gmane.org>
+ * Keyur Chudgar <kchudgar-qTEPVZfXA3Y@public.gmane.org>
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __XGENE_ENET_SGMAC_H__
+#define __XGENE_ENET_SGMAC_H__
+
+#define PHY_ADDR(src) (((src)<<8) & GENMASK(12, 8))
+#define REG_ADDR(src) ((src) & GENMASK(4, 0))
+#define PHY_CONTROL(src) ((src) & GENMASK(15, 0))
+#define INT_PHY_ADDR 0x1e
+#define SGMII_TBI_CONTROL_ADDR 0x44
+#define SGMII_CONTROL_ADDR 0x00
+#define SGMII_STATUS_ADDR 0x04
+#define SGMII_BASE_PAGE_ABILITY_ADDR 0x14
+#define AUTO_NEG_COMPLETE BIT(5)
+#define LINK_STATUS BIT(2)
+#define LINK_UP BIT(15)
+#define MPA_IDLE_WITH_QMI_EMPTY BIT(12)
+#define SG_RX_DV_GATE_REG_0_ADDR 0x0dfc
+
+extern struct xgene_mac_ops xgene_sgmac_ops;
+extern struct xgene_port_ops xgene_sgport_ops;
+
+#endif /* __XGENE_ENET_SGMAC_H__ */
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
index cd64b9f..67d0720 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
@@ -284,7 +284,7 @@ static void xgene_enet_shutdown(struct xgene_enet_pdata *pdata)
clk_disable_unprepare(pdata->clk);
}
-void xgene_enet_link_state(struct work_struct *work)
+static void xgene_enet_link_state(struct work_struct *work)
{
struct xgene_enet_pdata *pdata = container_of(to_delayed_work(work),
struct xgene_enet_pdata, link_work);
@@ -322,6 +322,7 @@ struct xgene_mac_ops xgene_xgmac_ops = {
.rx_disable = xgene_xgmac_rx_disable,
.tx_disable = xgene_xgmac_tx_disable,
.set_mac_addr = xgene_xgmac_set_mac_addr,
+ .link_state = xgene_enet_link_state
};
struct xgene_port_ops xgene_xgport_ops = {
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h
index d2d59e7..5a5296a 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h
@@ -47,10 +47,6 @@
#define XG_ENET_SPARE_CFG_REG_1_ADDR 0x0410
#define XGENET_RX_DV_GATE_REG_0_ADDR 0x0804
-#define PHY_POLL_LINK_ON (10 * HZ)
-#define PHY_POLL_LINK_OFF (PHY_POLL_LINK_ON / 5)
-
-void xgene_enet_link_state(struct work_struct *work);
extern struct xgene_mac_ops xgene_xgmac_ops;
extern struct xgene_port_ops xgene_xgport_ops;
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v1 3/3] drivers: net: xgene: Add SGMII based 1GbE ethtool support
From: Iyappan Subramanian @ 2014-10-10 20:18 UTC (permalink / raw)
To: davem, netdev, devicetree
Cc: linux-arm-kernel, patches, kchudgar, Iyappan Subramanian
In-Reply-To: <1412972316-16344-1-git-send-email-isubramanian@apm.com>
Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
---
.../net/ethernet/apm/xgene/xgene_enet_ethtool.c | 25 +++++++++++++++-------
1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c b/drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c
index c1c997b..416d6eb 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c
@@ -64,16 +64,25 @@ static int xgene_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
return -ENODEV;
return phy_ethtool_gset(phydev, cmd);
+ } else if (pdata->phy_mode == PHY_INTERFACE_MODE_SGMII) {
+ cmd->supported = SUPPORTED_1000baseT_Full |
+ SUPPORTED_Autoneg | SUPPORTED_MII;
+ cmd->advertising = cmd->supported;
+ ethtool_cmd_speed_set(cmd, SPEED_1000);
+ cmd->duplex = DUPLEX_FULL;
+ cmd->port = PORT_MII;
+ cmd->transceiver = XCVR_INTERNAL;
+ cmd->autoneg = AUTONEG_ENABLE;
+ } else {
+ cmd->supported = SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE;
+ cmd->advertising = cmd->supported;
+ ethtool_cmd_speed_set(cmd, SPEED_10000);
+ cmd->duplex = DUPLEX_FULL;
+ cmd->port = PORT_FIBRE;
+ cmd->transceiver = XCVR_INTERNAL;
+ cmd->autoneg = AUTONEG_DISABLE;
}
- cmd->supported = SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE;
- cmd->advertising = cmd->supported;
- ethtool_cmd_speed_set(cmd, SPEED_10000);
- cmd->duplex = DUPLEX_FULL;
- cmd->port = PORT_FIBRE;
- cmd->transceiver = XCVR_EXTERNAL;
- cmd->autoneg = AUTONEG_DISABLE;
-
return 0;
}
--
1.9.1
^ permalink raw reply related
* [PATCH v1 0/3] Add SGMII based 1GbE support to APM X-Gene SoC ethernet driver
From: Iyappan Subramanian @ 2014-10-10 20:18 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q, netdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
patches-qTEPVZfXA3Y, kchudgar-qTEPVZfXA3Y, Iyappan Subramanian
Adding SGMII based 1GbE basic support to APM X-Gene SoC ethernet driver.
v1:
* Initial version
---
Iyappan Subramanian (3):
dtb: Add SGMII based 1GbE node to APM X-Gene SoC device tree
drivers: net: xgene: Add SGMII based 1GbE support
drivers: net: xgene: Add SGMII based 1GbE ethtool support
arch/arm64/boot/dts/apm-mustang.dts | 4 +
arch/arm64/boot/dts/apm-storm.dtsi | 24 ++
drivers/net/ethernet/apm/xgene/Makefile | 2 +-
.../net/ethernet/apm/xgene/xgene_enet_ethtool.c | 25 +-
drivers/net/ethernet/apm/xgene/xgene_enet_hw.c | 1 -
drivers/net/ethernet/apm/xgene/xgene_enet_hw.h | 2 +-
drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 24 +-
drivers/net/ethernet/apm/xgene/xgene_enet_main.h | 5 +-
drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c | 407 +++++++++++++++++++++
drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.h | 41 +++
drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c | 3 +-
drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h | 4 -
12 files changed, 518 insertions(+), 24 deletions(-)
create mode 100644 drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c
create mode 100644 drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.h
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v1 1/3] dtb: Add SGMII based 1GbE node to APM X-Gene SoC device tree
From: Iyappan Subramanian @ 2014-10-10 20:18 UTC (permalink / raw)
To: davem, netdev, devicetree
Cc: linux-arm-kernel, patches, kchudgar, Iyappan Subramanian
In-Reply-To: <1412972316-16344-1-git-send-email-isubramanian@apm.com>
Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
---
arch/arm64/boot/dts/apm-mustang.dts | 4 ++++
arch/arm64/boot/dts/apm-storm.dtsi | 24 ++++++++++++++++++++++++
2 files changed, 28 insertions(+)
diff --git a/arch/arm64/boot/dts/apm-mustang.dts b/arch/arm64/boot/dts/apm-mustang.dts
index 2ae782b..71a1489 100644
--- a/arch/arm64/boot/dts/apm-mustang.dts
+++ b/arch/arm64/boot/dts/apm-mustang.dts
@@ -33,6 +33,10 @@
status = "ok";
};
+&sgenet0 {
+ status = "ok";
+};
+
&xgenet {
status = "ok";
};
diff --git a/arch/arm64/boot/dts/apm-storm.dtsi b/arch/arm64/boot/dts/apm-storm.dtsi
index d16cc03..f45bbfe 100644
--- a/arch/arm64/boot/dts/apm-storm.dtsi
+++ b/arch/arm64/boot/dts/apm-storm.dtsi
@@ -176,6 +176,16 @@
clock-output-names = "menetclk";
};
+ sge0clk: sge0clk@1f21c000 {
+ compatible = "apm,xgene-device-clock";
+ #clock-cells = <1>;
+ clocks = <&socplldiv2 0>;
+ reg = <0x0 0x1f21c000 0x0 0x1000>;
+ reg-names = "csr-reg";
+ csr-mask = <0x3>;
+ clock-output-names = "sge0clk";
+ };
+
xge0clk: xge0clk@1f61c000 {
compatible = "apm,xgene-device-clock";
#clock-cells = <1>;
@@ -446,6 +456,20 @@
};
};
+ sgenet0: ethernet@1f210000 {
+ compatible = "apm,xgene-enet";
+ status = "disabled";
+ reg = <0x0 0x1f210000 0x0 0x10000>,
+ <0x0 0x1f200000 0x0 0X10000>,
+ <0x0 0x1B000000 0x0 0X20000>;
+ reg-names = "enet_csr", "ring_csr", "ring_cmd";
+ interrupts = <0x0 0xA0 0x4>;
+ dma-coherent;
+ clocks = <&sge0clk 0>;
+ local-mac-address = [00 00 00 00 00 00];
+ phy-connection-type = "sgmii";
+ };
+
xgenet: ethernet@1f610000 {
compatible = "apm,xgene-enet";
status = "disabled";
--
1.9.1
^ permalink raw reply related
* [PATCH] fm10k: Add skb->xmit_more support
From: alexander.duyck @ 2014-10-10 20:17 UTC (permalink / raw)
To: e1000-devel, netdev, jeffrey.t.kirsher; +Cc: matthew.vick
From: Alexander Duyck <alexander.h.duyck@redhat.com>
This change adds suport for skb->xmit_more based on the changes that were
made to igb to support the feature. The main changes are moving up the
check for maybe_stop_tx so that we can check netif_xmit_stopped to determine
if we must write the tail because we can add no further buffers.
Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
---
drivers/net/ethernet/intel/fm10k/fm10k_main.c | 65 +++++++++++++------------
1 file changed, 34 insertions(+), 31 deletions(-)
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_main.c b/drivers/net/ethernet/intel/fm10k/fm10k_main.c
index 6c800a3..8ad7ff4 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_main.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_main.c
@@ -930,6 +930,30 @@ static bool fm10k_tx_desc_push(struct fm10k_ring *tx_ring,
return i == tx_ring->count;
}
+static int __fm10k_maybe_stop_tx(struct fm10k_ring *tx_ring, u16 size)
+{
+ netif_stop_subqueue(tx_ring->netdev, tx_ring->queue_index);
+
+ smp_mb();
+
+ /* We need to check again in a case another CPU has just
+ * made room available. */
+ if (likely(fm10k_desc_unused(tx_ring) < size))
+ return -EBUSY;
+
+ /* A reprieve! - use start_queue because it doesn't call schedule */
+ netif_start_subqueue(tx_ring->netdev, tx_ring->queue_index);
+ ++tx_ring->tx_stats.restart_queue;
+ return 0;
+}
+
+static inline int fm10k_maybe_stop_tx(struct fm10k_ring *tx_ring, u16 size)
+{
+ if (likely(fm10k_desc_unused(tx_ring) >= size))
+ return 0;
+ return __fm10k_maybe_stop_tx(tx_ring, size);
+}
+
static void fm10k_tx_map(struct fm10k_ring *tx_ring,
struct fm10k_tx_buffer *first)
{
@@ -1023,13 +1047,18 @@ static void fm10k_tx_map(struct fm10k_ring *tx_ring,
tx_ring->next_to_use = i;
+ /* Make sure there is space in the ring for the next send. */
+ fm10k_maybe_stop_tx(tx_ring, DESC_NEEDED);
+
/* notify HW of packet */
- writel(i, tx_ring->tail);
+ if (netif_xmit_stopped(txring_txq(tx_ring)) || !skb->xmit_more) {
+ writel(i, tx_ring->tail);
- /* we need this if more than one processor can write to our tail
- * at a time, it synchronizes IO on IA64/Altix systems
- */
- mmiowb();
+ /* we need this if more than one processor can write to our tail
+ * at a time, it synchronizes IO on IA64/Altix systems
+ */
+ mmiowb();
+ }
return;
dma_error:
@@ -1049,30 +1078,6 @@ dma_error:
tx_ring->next_to_use = i;
}
-static int __fm10k_maybe_stop_tx(struct fm10k_ring *tx_ring, u16 size)
-{
- netif_stop_subqueue(tx_ring->netdev, tx_ring->queue_index);
-
- smp_mb();
-
- /* We need to check again in a case another CPU has just
- * made room available. */
- if (likely(fm10k_desc_unused(tx_ring) < size))
- return -EBUSY;
-
- /* A reprieve! - use start_queue because it doesn't call schedule */
- netif_start_subqueue(tx_ring->netdev, tx_ring->queue_index);
- ++tx_ring->tx_stats.restart_queue;
- return 0;
-}
-
-static inline int fm10k_maybe_stop_tx(struct fm10k_ring *tx_ring, u16 size)
-{
- if (likely(fm10k_desc_unused(tx_ring) >= size))
- return 0;
- return __fm10k_maybe_stop_tx(tx_ring, size);
-}
-
netdev_tx_t fm10k_xmit_frame_ring(struct sk_buff *skb,
struct fm10k_ring *tx_ring)
{
@@ -1117,8 +1122,6 @@ netdev_tx_t fm10k_xmit_frame_ring(struct sk_buff *skb,
fm10k_tx_map(tx_ring, first);
- fm10k_maybe_stop_tx(tx_ring, DESC_NEEDED);
-
return NETDEV_TX_OK;
out_drop:
^ permalink raw reply related
* Re: [PATCH net-next] net: bcmgenet: enable driver to work without a device tree
From: Petri Gynther @ 2014-10-10 19:46 UTC (permalink / raw)
To: Florian Fainelli; +Cc: netdev, David Miller
In-Reply-To: <54382CA0.6040105@gmail.com>
Hi Florian,
On Fri, Oct 10, 2014 at 11:59 AM, Florian Fainelli <f.fainelli@gmail.com> wrote:
> On 10/10/2014 11:35 AM, Petri Gynther wrote:
>> Broadcom 7xxx MIPS-based STB platforms do not use device trees.
>> Modify bcmgenet driver so that it can be used on those platforms.
>>
>> Signed-off-by: Petri Gynther <pgynther@google.com>
>> ---
>
> [snip]
>
>> diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
>> index dbf524e..5191e3f 100644
>> --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h
>> +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
>> @@ -17,6 +17,17 @@
>> #include <linux/if_vlan.h>
>> #include <linux/phy.h>
>>
>> +struct bcmgenet_platform_data {
>> + void __iomem *base_reg;
>> + int irq0;
>> + int irq1;
>
> Why would these members here? The platform device should provide those
> as standard resources that the driver fetches using
> platform_get_resource() and platform_get_irq().
>
I modeled this on struct bcmemac_platform_data that was used in the
legacy BRCMSTB code.
include/linux/brcmstb/brcmstb.h:
struct bcmemac_platform_data {
/* used by the BSP code only */
uintptr_t base_reg;
int irq0;
int irq1;
int phy_type;
int phy_id;
int phy_speed;
u8 macaddr[ETH_ALEN];
};
The legacy BRCMSTB code stores all relevant GENET info in this struct
and then creates the resources from that info:
static void __init brcm_register_genet(int id, struct bcmemac_platform_data *pd)
{
struct resource res[3];
struct platform_device *pdev;
memset(&res, 0, sizeof(res));
res[0].start = BPHYSADDR(pd->base_reg);
res[0].end = BPHYSADDR(pd->base_reg + 0x4fff);
res[0].flags = IORESOURCE_MEM;
res[1].start = res[1].end = pd->irq0;
res[1].flags = IORESOURCE_IRQ;
res[2].start = res[2].end = pd->irq1;
res[2].flags = IORESOURCE_IRQ;
brcm_alloc_macaddr(pd->macaddr);
pdev = platform_device_alloc("bcmgenet", id);
platform_device_add_resources(pdev, res, 3);
platform_device_add_data(pdev, pd, sizeof(*pd));
platform_device_add(pdev);
}
>> + int phy_type;
>> + int phy_addr;
>> + int phy_speed;
>> + u8 macaddr[ETH_ALEN];
>> + int genet_version;
>> +};
>
> I would rather we put this in include/linux/platform_data/bcmgenet.h
> where it belongs.
>
I wasn't aware of the directory include/linux/platform_data/. Yes,
that's where this belongs.
>> +
>> /* total number of Buffer Descriptors, same for Rx/Tx */
>> #define TOTAL_DESC 256
>>
>> diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c
>> index 9ff799a..e5ff913 100644
>> --- a/drivers/net/ethernet/broadcom/genet/bcmmii.c
>> +++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c
>> @@ -157,6 +157,21 @@ static void bcmgenet_mii_setup(struct net_device *dev)
>> phy_print_status(phydev);
>> }
>>
>> +static int bcmgenet_moca_fphy_update(struct net_device *dev,
>> + struct fixed_phy_status *status)
>> +{
>> + struct bcmgenet_priv *priv = netdev_priv(dev);
>> + struct phy_device *phydev = priv->phydev;
>> +
>> + /*
>> + * MoCA daemon updates phydev->autoneg to reflect the link status.
>> + * Update MoCA fixed PHY status accordingly, so that the PHY state
>> + * machine becomes aware of the real link status.
>> + */
>> + status->link = phydev->autoneg;
>> + return 0;
>> +}
>
> I don't want to see that in the upstream driver, please enable the link
> interrupts like I suggested before and do not use the autoneg field at
> all, which should require no MoCA daemon modifications.
>
I added debug printk's to bcmgenet_isr0 to check on UMAC_IRQ_LINK_UP
and UMAC_IRQ_LINK_DOWN.
I am not getting those interrupts on eth1 (MoCA) port when coax is
removed/inserted.
But, they do work on eth0.
I'll modify init_umac() to enable those interrupts for MoCA port and retest.
> [snip]
>
>>
>> priv->phydev = phydev;
>> @@ -437,6 +464,104 @@ static int bcmgenet_mii_of_init(struct bcmgenet_priv *priv)
>> return 0;
>> }
>>
>> +static int bcmgenet_mii_pd_init(struct bcmgenet_priv *priv)
>> +{
>> + struct device *kdev = &priv->pdev->dev;
>> + struct bcmgenet_platform_data *pd = kdev->platform_data;
>> + struct mii_bus *mdio = priv->mii_bus;
>> + int phy_addr = pd->phy_addr;
>> + struct phy_device *phydev;
>> + int ret;
>> + int i;
>> +
>> + /* Disable automatic MDIO bus scan */
>> + mdio->phy_mask = ~0;
>> +
>> + /* Clear all the IRQ properties */
>> + if (mdio->irq)
>> + for (i = 0; i < PHY_MAX_ADDR; i++)
>> + mdio->irq[i] = PHY_POLL;
>> +
>> + /* Register the MDIO bus */
>> + ret = mdiobus_register(mdio);
>> + if (ret) {
>> + dev_err(kdev, "failed to register MDIO bus\n");
>> + return ret;
>> + }
>> +
>> + /*
>> + * bcmgenet_platform_data needs to pass a valid PHY address for
>> + * internal/external PHY or -1 for MoCA PHY.
>> + */
>> + if (phy_addr >= 0 && phy_addr < PHY_MAX_ADDR) {
>
> We do too much low-level PHY device handling, and since you already have
> the phy_type provided via platform_data, we can use that hint to do the
> following:
>
> 1) an internal or external PHY with MDIO accesses should leave the bus
> auto-probing on with the specified PHY address in the mdio bus phy_mask
>
> 2) a MoCA PHY or an external PHY with MDIO accesses disabled should use
> the fixed-0 MII bus instead.
>
> This would look like this:
>
> if (pd->phy_type != PHY_INTERFACE_MODE_MOCA || pd->mdio_enabled)
> mdio->phy_mask = ~(1 << pd->phy_addr);
>
> ...
> mdiobus_register()
>
> priv->phydev = mdio->bus->phy_map[pd->phy_addr];
>
> phydev->phy_flags |= mask;
>
> if (pd->phy_type == PHY_INTERFACE_MODE_MOCA || !pd->mdio_enabled)
> priv->phydev = fixed_phy_register(...);
>
> and in both cases, later on you do connect to the PHY device
>
> I can cook a patch to illustrate what I think this could look like since
> I realize using pseudo-code to explain might not be the best thing.
>
I think I understand what you mean. I'll make a change.
>> + /*
>> + * 10/100/1000 Ethernet port with external or internal PHY.
>> + */
>> + phydev = get_phy_device(mdio, phy_addr, false);
>> + if (!phydev || IS_ERR(phydev)) {
>> + dev_err(kdev, "failed to create PHY device\n");
>> + mdiobus_unregister(mdio);
>> + return 1;
>> + }
>> +
>> + phydev->irq = PHY_POLL;
>> +
>> + ret = phy_device_register(phydev);
>> + if (ret) {
>> + dev_err(kdev, "failed to register PHY device\n");
>> + phy_device_free(phydev);
>> + mdiobus_unregister(mdio);
>> + return 1;
>> + }
>> +
>> + priv->phydev = phydev;
>> + priv->phy_interface = pd->phy_type;
>> + } else {
>> + /*
>> + * MoCA port with no MDIO-accessible PHY.
>> + * We need to use 1000/HD fixed PHY to represent the link layer.
>> + * MoCA daemon interacts with this PHY via ethtool.
>> + */
>> + struct fixed_phy_status moca_fphy_status = {
>> + .link = 0,
>> + .duplex = 0,
>
> This should be DUPLEX_FULL here, the link between GENET and the MoCA
> Ethernet convergence layer is full-duplex by nature (despite we report
> the PHY being half-duplex, which is a mistake in the downstream driver),
> the MoCA medium on the coaxial cable is half-duplex though, but that is
> handled by the MoCA HW.
>
> NB: I had issues in the past using a half-duplex link with the MoCA
> ethernet convergence layer, causing various types of packet loss because
> we use a simplified signaling internally in the hardware.
>
I picked this setting from 3.3 GENET driver. I'll test 1000/FULL on my
platform to see if it works.
>> + .speed = 1000,
>> + .pause = 0,
>> + .asym_pause = 0,
>> + };
>> +
>> + phydev = fixed_phy_register(PHY_POLL, &moca_fphy_status, NULL);
>> + if (!phydev || IS_ERR(phydev)) {
>> + dev_err(kdev, "failed to register fixed PHY device\n");
>> + mdiobus_unregister(mdio);
>> + return 1;
>> + }
>> +
>> + phydev->autoneg = AUTONEG_DISABLE;
>> +
>> + ret = fixed_phy_set_link_update(phydev,
>> + bcmgenet_moca_fphy_update);
>> + if (ret) {
>> + dev_err(kdev, "failed to set fixed PHY link update\n");
>> + }
>
> Should not we propagate this error to the caller?
Good catch. Yes.
> --
> Florian
^ permalink raw reply
* Re: [PATCH net v2 0/3] net: bcmgenet & systemport fixes
From: David Miller @ 2014-10-10 19:39 UTC (permalink / raw)
To: f.fainelli; +Cc: netdev, pgynther, jaedon.shin
In-Reply-To: <1412963514-7718-1-git-send-email-f.fainelli@gmail.com>
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Fri, 10 Oct 2014 10:51:51 -0700
> This patch series fixes an off-by-one error introduced during a previous
> change, and the two other fixes fix a wake depth imbalance situation for
> the Wake-on-LAN interrupt line.
Series applied, thanks Florian.
^ permalink raw reply
* Re: [PATCH v2 net 0/5] net: fix races accessing page->_count
From: David Miller @ 2014-10-10 19:37 UTC (permalink / raw)
To: edumazet
Cc: netdev, alexander.h.duyck, jeffrey.t.kirsher, andreslc, gthelen,
hughd, rientjes
In-Reply-To: <1412941698-17502-1-git-send-email-edumazet@google.com>
From: Eric Dumazet <edumazet@google.com>
Date: Fri, 10 Oct 2014 04:48:13 -0700
> This is illegal to use atomic_set(&page->_count, ...) even if we 'own'
> the page. Other entities in the kernel need to use get_page_unless_zero()
> to get a reference to the page before testing page properties, so we could
> loose a refcount increment.
>
> The only case it is valid is when page->_count is 0, we can use this in
> __netdev_alloc_frag()
>
> Note that I never seen crashes caused by these races, the issue was reported
> by Andres Lagar-Cavilla and Hugh Dickins.
Series applied, thanks Eric.
^ permalink raw reply
* Re: [PATCH v2] net/phy: micrel: Add clock support for KSZ8021/KSZ8031
From: David Miller @ 2014-10-10 19:36 UTC (permalink / raw)
To: s.hauer; +Cc: f.fainelli, netdev, linux-kernel, kernel
In-Reply-To: <1412927285-6809-1-git-send-email-s.hauer@pengutronix.de>
From: Sascha Hauer <s.hauer@pengutronix.de>
Date: Fri, 10 Oct 2014 09:48:05 +0200
> The KSZ8021 and KSZ8031 support RMII reference input clocks of 25MHz
> and 50MHz. Both PHYs differ in the default frequency they expect
> after reset. If this differs from the actual input clock, then
> register 0x1f bit 7 must be changed.
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH v4] flow-dissector: Fix alignment issue in __skb_flow_get_ports
From: David Miller @ 2014-10-10 19:34 UTC (permalink / raw)
To: alexander.duyck; +Cc: netdev, eric.dumazet
In-Reply-To: <20141010190716.8311.98709.stgit@ahduyck-workstation.home>
From: alexander.duyck@gmail.com
Date: Fri, 10 Oct 2014 12:09:12 -0700
> From: Alexander Duyck <alexander.h.duyck@redhat.com>
>
> This patch addresses a kernel unaligned access bug seen on a sparc64 system
> with an igb adapter. Specifically the __skb_flow_get_ports was returning a
> be32 pointer which was then having the value directly returned.
>
> In order to prevent this it is actually easier to simply not populate the
> ports or address values when an skb is not present. In this case the
> assumption is that the data isn't needed and rather than slow down the
> faster aligned accesses by making them have to assume the unaligned path on
> architectures that don't support efficent unaligned access it makes more
> sense to simply switch off the bits that were copying the source and
> destination address/port for the case where we only care about the protocol
> types and lengths which are normally 16 bit fields anyway.
>
> Reported-by: David S. Miller <davem@davemloft.net>
> Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
> ---
>
> v2: Fixed alignment to __be16 on ports
> v3: Discarded previous approach and instead simplified things by
> not populating ports, or src/dst addresses if skb is not present.
> By doing this we avoid the unaligned access issue entirely and do not
> populate fields that will not be used by the eth_get_headlen function.
> v4: Minor whitespace cleanups
> Added workaround for access of doff resulting in unaligned access
Applied, thanks Alex.
^ permalink raw reply
* Re: [PATCH] flow-dissector: Fix alignment issue in __skb_flow_get_ports
From: David Miller @ 2014-10-10 19:32 UTC (permalink / raw)
To: alexander.h.duyck; +Cc: alexander.duyck, eric.dumazet, David.Laight, netdev
In-Reply-To: <54382B2F.8030203@redhat.com>
From: Alexander Duyck <alexander.h.duyck@redhat.com>
Date: Fri, 10 Oct 2014 11:53:35 -0700
> On 10/10/2014 11:22 AM, David Miller wrote:
>> From: David Miller <davem@davemloft.net>
>> Date: Fri, 10 Oct 2014 14:15:59 -0400 (EDT)
>>
>>> Your original code works because you do things like "byte[12] & 0xf0"
>>> to
>>> extract these fields.
>> Changing that th->doff sequence to instead be:
>>
>> const u8 *bp;
>> u8 buf[13];
>>
>> bp = __skb_header_pointer(skb, poff, sizeof(buf),
>> data, hlen, &buf);
>> if (!bp)
>> return poff;
>>
>> poff += max_t(u32, sizeof(struct tcphdr), (bp[12] & 0xf0) >> 2);
>> break;
>>
>> on top of your v3 patch works for me.
>>
>> Please double-check my calculations.
>
> Any reason why you are grabbing all 13 bytes instead of just the 1 we
> care about? Seems like we could just use a u8 buf instead of the
> array since we are only grabbing doff.
No reason, just a thinko, my brain implemented this as if skb_header_pointer
worked like skb_pull :-/
^ permalink raw reply
* Re: [PATCH][net-next][V2] net: filter: fix the comments
From: David Miller @ 2014-10-10 19:12 UTC (permalink / raw)
To: roy.qing.li; +Cc: netdev, ast, alexei.starovoitov
In-Reply-To: <1412920611-2094-1-git-send-email-roy.qing.li@gmail.com>
From: roy.qing.li@gmail.com
Date: Fri, 10 Oct 2014 13:56:51 +0800
> From: Li RongQing <roy.qing.li@gmail.com>
>
> 1. sk_run_filter has been renamed, sk_filter() is using SK_RUN_FILTER.
> 2. Remove wrong comments about storing intermediate value.
> 3. replace sk_run_filter with __bpf_prog_run for check_load_and_stores's
> comments
>
> Cc: Alexei Starovoitov <ast@plumgrid.com>
> Signed-off-by: Li RongQing <roy.qing.li@gmail.com>
Applied.
^ permalink raw reply
* Re: [PATCH][net-next] Documentation: replace __sk_run_filter with __bpf_prog_run
From: David Miller @ 2014-10-10 19:11 UTC (permalink / raw)
To: roy.qing.li; +Cc: netdev
In-Reply-To: <1412912214-964-1-git-send-email-roy.qing.li@gmail.com>
From: roy.qing.li@gmail.com
Date: Fri, 10 Oct 2014 11:36:54 +0800
> From: Li RongQing <roy.qing.li@gmail.com>
>
> __sk_run_filter has been renamed as __bpf_prog_run, so replace them in comments
>
> Signed-off-by: Li RongQing <roy.qing.li@gmail.com>
Applied.
^ permalink raw reply
* Re: [PATCH net-next 0/2] macvlan: optimize receive path
From: David Miller @ 2014-10-10 19:10 UTC (permalink / raw)
To: jbaron; +Cc: eric.dumazet, stephen, vyasevich, kaber, netdev
In-Reply-To: <cover.1412908929.git.jbaron@akamai.com>
From: Jason Baron <jbaron@akamai.com>
Date: Fri, 10 Oct 2014 03:13:24 +0000 (GMT)
> So after porting this optimization to net-next, I found that the netperf
> results of TCP_RR regress right at the maximum peak of transactions/sec. That
> is as I increase the number of threads via the first argument to super_netperf,
> the number of transactions/sec keep increasing, peak, and then start
> decreasing. It is right at the peak, that I see a small regression with this
> patch (see results in patch 2/2).
>
> Without the patch, the ksoftirqd threads are the top cpu consumers threads on
> the system, since the extra 'netif_rx()', is queuing more softirq work, whereas
> with the patch, the ksoftirqd threads are below all of the 'netserver' threads
> in terms of their cpu usage. So there appears to be some interaction between how
> softirqs are serviced at the peak here and this patch. I think the test results
> are still supportive of this approach, but I wanted to be clear on my findings.
I think this is definitely the right thing to do, applied, thanks!
^ permalink raw reply
* [PATCH v4] flow-dissector: Fix alignment issue in __skb_flow_get_ports
From: alexander.duyck @ 2014-10-10 19:09 UTC (permalink / raw)
To: netdev, davem; +Cc: eric.dumazet
From: Alexander Duyck <alexander.h.duyck@redhat.com>
This patch addresses a kernel unaligned access bug seen on a sparc64 system
with an igb adapter. Specifically the __skb_flow_get_ports was returning a
be32 pointer which was then having the value directly returned.
In order to prevent this it is actually easier to simply not populate the
ports or address values when an skb is not present. In this case the
assumption is that the data isn't needed and rather than slow down the
faster aligned accesses by making them have to assume the unaligned path on
architectures that don't support efficent unaligned access it makes more
sense to simply switch off the bits that were copying the source and
destination address/port for the case where we only care about the protocol
types and lengths which are normally 16 bit fields anyway.
Reported-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
---
v2: Fixed alignment to __be16 on ports
v3: Discarded previous approach and instead simplified things by
not populating ports, or src/dst addresses if skb is not present.
By doing this we avoid the unaligned access issue entirely and do not
populate fields that will not be used by the eth_get_headlen function.
v4: Minor whitespace cleanups
Added workaround for access of doff resulting in unaligned access
net/core/flow_dissector.c | 36 +++++++++++++++++++++++-------------
1 file changed, 23 insertions(+), 13 deletions(-)
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 8560dea..4508493 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -100,6 +100,13 @@ ip:
if (ip_is_fragment(iph))
ip_proto = 0;
+ /* skip the address processing if skb is NULL. The assumption
+ * here is that if there is no skb we are not looking for flow
+ * info but lengths and protocols.
+ */
+ if (!skb)
+ break;
+
iph_to_flow_copy_addrs(flow, iph);
break;
}
@@ -114,17 +121,15 @@ ipv6:
return false;
ip_proto = iph->nexthdr;
- flow->src = (__force __be32)ipv6_addr_hash(&iph->saddr);
- flow->dst = (__force __be32)ipv6_addr_hash(&iph->daddr);
nhoff += sizeof(struct ipv6hdr);
- /* skip the flow label processing if skb is NULL. The
- * assumption here is that if there is no skb we are not
- * looking for flow info as much as we are length.
- */
+ /* see comment above in IPv4 section */
if (!skb)
break;
+ flow->src = (__force __be32)ipv6_addr_hash(&iph->saddr);
+ flow->dst = (__force __be32)ipv6_addr_hash(&iph->daddr);
+
flow_label = ip6_flowlabel(iph);
if (flow_label) {
/* Awesome, IPv6 packet has a flow label so we can
@@ -231,9 +236,13 @@ ipv6:
flow->n_proto = proto;
flow->ip_proto = ip_proto;
- flow->ports = __skb_flow_get_ports(skb, nhoff, ip_proto, data, hlen);
flow->thoff = (u16) nhoff;
+ /* unless skb is set we don't need to record port info */
+ if (skb)
+ flow->ports = __skb_flow_get_ports(skb, nhoff, ip_proto,
+ data, hlen);
+
return true;
}
EXPORT_SYMBOL(__skb_flow_dissect);
@@ -334,15 +343,16 @@ u32 __skb_get_poff(const struct sk_buff *skb, void *data,
switch (keys->ip_proto) {
case IPPROTO_TCP: {
- const struct tcphdr *tcph;
- struct tcphdr _tcph;
+ /* access doff as u8 to avoid unaligned access */
+ const u8 *doff;
+ u8 _doff;
- tcph = __skb_header_pointer(skb, poff, sizeof(_tcph),
- data, hlen, &_tcph);
- if (!tcph)
+ doff = __skb_header_pointer(skb, poff + 12, sizeof(_doff),
+ data, hlen, &_doff);
+ if (!doff)
return poff;
- poff += max_t(u32, sizeof(struct tcphdr), tcph->doff * 4);
+ poff += max_t(u32, sizeof(struct tcphdr), (*doff & 0xF0) >> 2);
break;
}
case IPPROTO_UDP:
^ permalink raw reply related
* Re: [PATCH v4 0/6] Add 10GbE support to APM X-Gene SoC ethernet driver
From: David Miller @ 2014-10-10 19:07 UTC (permalink / raw)
To: isubramanian; +Cc: netdev, devicetree, linux-arm-kernel, patches, kchudgar
In-Reply-To: <1412904727-23485-1-git-send-email-isubramanian@apm.com>
From: Iyappan Subramanian <isubramanian@apm.com>
Date: Thu, 9 Oct 2014 18:32:01 -0700
> Adding 10GbE support to APM X-Gene SoC ethernet driver.
>
> v4: Address comments from v3
> * dtb: resolved merge conflict for the net tree
>
> v3: Address comments from v2
> * dtb: changed to use all-zeros for the mac address
>
> v2: Address comments from v1
> * created preparatory patch to review before adding new functionality
> * dtb: updated to use tabs consistently
>
> v1:
> * Initial version
Series applied, thanks.
^ permalink raw reply
* Re: [PATCH net] net: bpf: fix bpf syscall dependence on anon_inodes
From: David Miller @ 2014-10-10 19:03 UTC (permalink / raw)
To: ast; +Cc: sojkam1, netdev, linux-kernel
In-Reply-To: <1412893001-8401-1-git-send-email-ast@plumgrid.com>
From: Alexei Starovoitov <ast@plumgrid.com>
Date: Thu, 9 Oct 2014 15:16:41 -0700
> minimal configurations where EPOLL, PERF_EVENTS, etc are disabled,
> but NET is enabled, are failing to build with link error:
> kernel/built-in.o: In function `bpf_prog_load':
> syscall.c:(.text+0x3b728): undefined reference to `anon_inode_getfd'
>
> fix it by selecting ANON_INODES when NET is enabled
>
> Reported-by: Michal Sojka <sojkam1@fel.cvut.cz>
> Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
> ---
>
> I understand that 'select' is highly non-recommended for all good reasons,
> but here 'depends on' is very user unfriendly, since ANON_INODES is
> a hidden config that users cannot select directly.
Applied, thanks.
^ 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