Netdev List
 help / color / mirror / Atom feed
* KASAN: use-after-free Read in sctp_hash_transport
From: syzbot @ 2018-11-18 19:23 UTC (permalink / raw)
  To: davem, linux-kernel, linux-sctp, marcelo.leitner, netdev, nhorman,
	syzkaller-bugs, vyasevich

Hello,

syzbot found the following crash on:

HEAD commit:    e119a369b0f1 Merge branch 'SMSC95xx-driver-updates'
git tree:       net-next
console output: https://syzkaller.appspot.com/x/log.txt?x=124f5f7b400000
kernel config:  https://syzkaller.appspot.com/x/.config?x=d86f24333880b605
dashboard link: https://syzkaller.appspot.com/bug?extid=0b05d8aa7cb185107483
compiler:       gcc (GCC) 8.0.1 20180413 (experimental)

Unfortunately, I don't have any reproducer for this crash yet.

IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+0b05d8aa7cb185107483@syzkaller.appspotmail.com

==================================================================
BUG: KASAN: use-after-free in sctp_hash_transport+0x803/0x810  
net/sctp/input.c:958
Read of size 8 at addr ffff8881c6b98cb0 by task syz-executor5/3552

CPU: 0 PID: 3552 Comm: syz-executor5 Not tainted 4.20.0-rc2+ #299
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS  
Google 01/01/2011
Call Trace:
  __dump_stack lib/dump_stack.c:77 [inline]
  dump_stack+0x244/0x39d lib/dump_stack.c:113
  print_address_description.cold.7+0x9/0x1ff mm/kasan/report.c:256
  kasan_report_error mm/kasan/report.c:354 [inline]
  kasan_report.cold.8+0x242/0x309 mm/kasan/report.c:412
  __asan_report_load8_noabort+0x14/0x20 mm/kasan/report.c:433
  sctp_hash_transport+0x803/0x810 net/sctp/input.c:958
  sctp_assoc_add_peer+0xa21/0x10d0 net/sctp/associola.c:724
  sctp_sendmsg_new_asoc+0x5da/0x11f0 net/sctp/socket.c:1757
  sctp_sendmsg+0x18a5/0x1da0 net/sctp/socket.c:2086
  inet_sendmsg+0x1a1/0x690 net/ipv4/af_inet.c:798
  sock_sendmsg_nosec net/socket.c:621 [inline]
  sock_sendmsg+0xd5/0x120 net/socket.c:631
  ___sys_sendmsg+0x7fd/0x930 net/socket.c:2116
  __sys_sendmsg+0x11d/0x280 net/socket.c:2154
  __do_sys_sendmsg net/socket.c:2163 [inline]
  __se_sys_sendmsg net/socket.c:2161 [inline]
  __x64_sys_sendmsg+0x78/0xb0 net/socket.c:2161
  do_syscall_64+0x1b9/0x820 arch/x86/entry/common.c:290
  entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x457569
Code: fd b3 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7  
48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff  
ff 0f 83 cb b3 fb ff c3 66 2e 0f 1f 84 00 00 00 00
RSP: 002b:00007f45462c7c78 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 0000000000457569
RDX: 0000000000000000 RSI: 000000002001afc8 RDI: 0000000000000005
RBP: 000000000072c0e0 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 00007f45462c86d4
R13: 00000000004c381e R14: 00000000004d59e8 R15: 00000000ffffffff

Allocated by task 3509:
  save_stack+0x43/0xd0 mm/kasan/kasan.c:448
  set_track mm/kasan/kasan.c:460 [inline]
  kasan_kmalloc+0xc7/0xe0 mm/kasan/kasan.c:553
  kmem_cache_alloc_trace+0x152/0x750 mm/slab.c:3620
  kmalloc include/linux/slab.h:546 [inline]
  kzalloc include/linux/slab.h:741 [inline]
  sctp_association_new+0x14e/0x2290 net/sctp/associola.c:311
  sctp_sendmsg_new_asoc+0x39c/0x11f0 net/sctp/socket.c:1723
  sctp_sendmsg+0x18a5/0x1da0 net/sctp/socket.c:2086
  inet_sendmsg+0x1a1/0x690 net/ipv4/af_inet.c:798
  sock_sendmsg_nosec net/socket.c:621 [inline]
  sock_sendmsg+0xd5/0x120 net/socket.c:631
  ___sys_sendmsg+0x7fd/0x930 net/socket.c:2116
  __sys_sendmsg+0x11d/0x280 net/socket.c:2154
  __do_sys_sendmsg net/socket.c:2163 [inline]
  __se_sys_sendmsg net/socket.c:2161 [inline]
  __x64_sys_sendmsg+0x78/0xb0 net/socket.c:2161
  do_syscall_64+0x1b9/0x820 arch/x86/entry/common.c:290
  entry_SYSCALL_64_after_hwframe+0x49/0xbe

Freed by task 3552:
  save_stack+0x43/0xd0 mm/kasan/kasan.c:448
  set_track mm/kasan/kasan.c:460 [inline]
  __kasan_slab_free+0x102/0x150 mm/kasan/kasan.c:521
  kasan_slab_free+0xe/0x10 mm/kasan/kasan.c:528
  __cache_free mm/slab.c:3498 [inline]
  kfree+0xcf/0x230 mm/slab.c:3817
  sctp_association_destroy net/sctp/associola.c:437 [inline]
  sctp_association_put+0x264/0x350 net/sctp/associola.c:889
  sctp_transport_destroy net/sctp/transport.c:180 [inline]
  sctp_transport_put+0x186/0x1f0 net/sctp/transport.c:340
  sctp_hash_cmp+0x1ef/0x260 net/sctp/input.c:901
  __rhashtable_lookup.isra.24.constprop.29+0x3b6/0x7d0  
include/linux/rhashtable.h:483
  rhltable_lookup include/linux/rhashtable.h:566 [inline]
  sctp_hash_transport+0x2f6/0x810 net/sctp/input.c:954
  sctp_assoc_add_peer+0xa21/0x10d0 net/sctp/associola.c:724
  sctp_sendmsg_new_asoc+0x5da/0x11f0 net/sctp/socket.c:1757
  sctp_sendmsg+0x18a5/0x1da0 net/sctp/socket.c:2086
  inet_sendmsg+0x1a1/0x690 net/ipv4/af_inet.c:798
  sock_sendmsg_nosec net/socket.c:621 [inline]
  sock_sendmsg+0xd5/0x120 net/socket.c:631
  ___sys_sendmsg+0x7fd/0x930 net/socket.c:2116
  __sys_sendmsg+0x11d/0x280 net/socket.c:2154
  __do_sys_sendmsg net/socket.c:2163 [inline]
  __se_sys_sendmsg net/socket.c:2161 [inline]
  __x64_sys_sendmsg+0x78/0xb0 net/socket.c:2161
  do_syscall_64+0x1b9/0x820 arch/x86/entry/common.c:290
  entry_SYSCALL_64_after_hwframe+0x49/0xbe

The buggy address belongs to the object at ffff8881c6b98c00
  which belongs to the cache kmalloc-4k of size 4096
The buggy address is located 176 bytes inside of
  4096-byte region [ffff8881c6b98c00, ffff8881c6b99c00)
The buggy address belongs to the page:
page:ffffea00071ae600 count:1 mapcount:0 mapping:ffff8881da800dc0 index:0x0  
compound_mapcount: 0
flags: 0x2fffc0000010200(slab|head)
raw: 02fffc0000010200 ffffea0007175888 ffffea0006421308 ffff8881da800dc0
raw: 0000000000000000 ffff8881c6b98c00 0000000100000001 0000000000000000
page dumped because: kasan: bad access detected

Memory state around the buggy address:
  ffff8881c6b98b80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
  ffff8881c6b98c00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> ffff8881c6b98c80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
                                      ^
  ffff8881c6b98d00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
  ffff8881c6b98d80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================


---
This bug is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.

syzbot will keep track of this bug report. See:
https://goo.gl/tpsmEJ#bug-status-tracking for how to communicate with  
syzbot.

^ permalink raw reply

* Re: [PATCH 2/4] net/bpf: refactor freeing of executable allocations
From: Y Song @ 2018-11-18 20:20 UTC (permalink / raw)
  To: ard.biesheuvel
  Cc: LKML, Daniel Borkmann, Alexei Starovoitov, rick.p.edgecombe,
	eric.dumazet, jannh, Kees Cook, jeyu, arnd, catalin.marinas,
	will.deacon, mark.rutland, ralf, paul.burton, jhogan, benh,
	paulus, mpe, David Miller, linux-arm-kernel, linux-mips,
	linuxppc-dev, sparclinux, netdev
In-Reply-To: <CAKv+Gu9hB3a5LfFQskNzXZDmgps_+9dewbC1E5GFndcQZ-KgQg@mail.gmail.com>

On Sun, Nov 18, 2018 at 3:55 PM Ard Biesheuvel
<ard.biesheuvel@linaro.org> wrote:
>
> On Sat, 17 Nov 2018 at 23:47, Y Song <ys114321@gmail.com> wrote:
> >
> > On Sat, Nov 17, 2018 at 6:58 PM Ard Biesheuvel
> > <ard.biesheuvel@linaro.org> wrote:
> > >
> > > All arch overrides of the __weak bpf_jit_free() amount to the same
> > > thing: the allocated memory was never mapped read-only, and so
> > > it does not have to be remapped to read-write before being freed.
> > >
> > > So in preparation of permitting arches to serve allocations for BPF
> > > JIT programs from other regions than the module region, refactor
> > > the existing bpf_jit_free() implementations to use the shared code
> > > where possible, and only specialize the remap and free operations.
> > >
> > > Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> > > ---
> > >  arch/mips/net/bpf_jit.c           |  7 ++-----
> > >  arch/powerpc/net/bpf_jit_comp.c   |  7 ++-----
> > >  arch/powerpc/net/bpf_jit_comp64.c |  9 +++------
> > >  arch/sparc/net/bpf_jit_comp_32.c  |  7 ++-----
> > >  kernel/bpf/core.c                 | 15 +++++----------
> > >  5 files changed, 14 insertions(+), 31 deletions(-)
> > >
> > > diff --git a/arch/mips/net/bpf_jit.c b/arch/mips/net/bpf_jit.c
> > > index 1b69897274a1..5696bd7dccc7 100644
> > > --- a/arch/mips/net/bpf_jit.c
> > > +++ b/arch/mips/net/bpf_jit.c
> > > @@ -1261,10 +1261,7 @@ void bpf_jit_compile(struct bpf_prog *fp)
> > >         kfree(ctx.offsets);
> > >  }
> > >
> > > -void bpf_jit_free(struct bpf_prog *fp)
> > > +void bpf_jit_binary_free(struct bpf_binary_header *hdr)
> > >  {
> > > -       if (fp->jited)
> > > -               bpf_jit_binary_free(bpf_jit_binary_hdr(fp));
> > > -
> > > -       bpf_prog_unlock_free(fp);
> > > +       module_memfree(hdr);
> > >  }
> > > diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
> > > index a1ea1ea6b40d..5b5ce4a1b44b 100644
> > > --- a/arch/powerpc/net/bpf_jit_comp.c
> > > +++ b/arch/powerpc/net/bpf_jit_comp.c
> > > @@ -680,10 +680,7 @@ void bpf_jit_compile(struct bpf_prog *fp)
> > >         return;
> > >  }
> > >
> > > -void bpf_jit_free(struct bpf_prog *fp)
> > > +void bpf_jit_binary_free(struct bpf_binary_header *hdr)
> > >  {
> > > -       if (fp->jited)
> > > -               bpf_jit_binary_free(bpf_jit_binary_hdr(fp));
> > > -
> > > -       bpf_prog_unlock_free(fp);
> > > +       module_memfree(hdr);
> > >  }
> > > diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c
> > > index 84c8f013a6c6..f64f1294bd62 100644
> > > --- a/arch/powerpc/net/bpf_jit_comp64.c
> > > +++ b/arch/powerpc/net/bpf_jit_comp64.c
> > > @@ -1021,11 +1021,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
> > >         return fp;
> > >  }
> > >
> > > -/* Overriding bpf_jit_free() as we don't set images read-only. */
> > > -void bpf_jit_free(struct bpf_prog *fp)
> > > +/* Overriding bpf_jit_binary_free() as we don't set images read-only. */
> > > +void bpf_jit_binary_free(struct bpf_binary_header *hdr)
> > >  {
> > > -       if (fp->jited)
> > > -               bpf_jit_binary_free(bpf_jit_binary_hdr(fp));
> > > -
> > > -       bpf_prog_unlock_free(fp);
> > > +       module_memfree(hdr);
> > >  }
> > > diff --git a/arch/sparc/net/bpf_jit_comp_32.c b/arch/sparc/net/bpf_jit_comp_32.c
> > > index 01bda6bc9e7f..589950d152cc 100644
> > > --- a/arch/sparc/net/bpf_jit_comp_32.c
> > > +++ b/arch/sparc/net/bpf_jit_comp_32.c
> > > @@ -756,10 +756,7 @@ cond_branch:                       f_offset = addrs[i + filter[i].jf];
> > >         return;
> > >  }
> > >
> > > -void bpf_jit_free(struct bpf_prog *fp)
> > > +void bpf_jit_binary_free(struct bpf_binary_header *hdr)
> > >  {
> > > -       if (fp->jited)
> > > -               bpf_jit_binary_free(bpf_jit_binary_hdr(fp));
> > > -
> > > -       bpf_prog_unlock_free(fp);
> > > +       module_memfree(hdr);
> > >  }
> > > diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
> > > index 1a796e0799ec..29f766dac203 100644
> > > --- a/kernel/bpf/core.c
> > > +++ b/kernel/bpf/core.c
> > > @@ -646,25 +646,20 @@ bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr,
> > >         return hdr;
> > >  }
> > >
> > > -void bpf_jit_binary_free(struct bpf_binary_header *hdr)
> > > +void __weak bpf_jit_binary_free(struct bpf_binary_header *hdr)
> > >  {
> > > -       u32 pages = hdr->pages;
> > > -
> > > +       bpf_jit_binary_unlock_ro(hdr);
> > >         module_memfree(hdr);
> > > -       bpf_jit_uncharge_modmem(pages);
> > >  }
> > >
> > > -/* This symbol is only overridden by archs that have different
> > > - * requirements than the usual eBPF JITs, f.e. when they only
> > > - * implement cBPF JIT, do not set images read-only, etc.
> > > - */
> >
> > Do you want to move the above comments to
> > new weak function bpf_jit_binary_free?
> >
>
> Perhaps. But one thing I don't understand, looking at this again, is
> why we have these overrides in the first place. module_memfree() just
> calls vfree(), which takes down the mapping entirely (along with any
> updated permissions), and so remapping it back to r/w right before
> that seems rather pointless imo.
>
> Can we get rid of bpf_jit_binary_unlock_ro() entirely, and along with
> it, all these overrides for the free() path?

Maybe based on current implementation. Just a pure speculation.
module_memfree() can be overwritten by arch specific implementation.
The intention could be restoring the allocated page to its original permission
just in case arch specific implementation of module_memfree()
does different thing than default vfee().

^ permalink raw reply

* Re: [PATCH v1] tg3: optionally use eth_platform_get_mac_address() to get mac address
From: David Miller @ 2018-11-18 20:58 UTC (permalink / raw)
  To: thesven73
  Cc: svendev, siva.kallam, prashant, mchan, andrew, linux-kernel,
	netdev, arnd
In-Reply-To: <20181117155618.19486-1-TheSven73@googlemail.com>

From: thesven73@gmail.com
Date: Sat, 17 Nov 2018 10:56:18 -0500

> This function will try to determine the mac address via the devicetree,
> or via an architecture-specific method (e.g. a PROM on SPARC).
> 
> The SPARC-specific code in this driver (#ifdef SPARC) did exactly this,
> and is therefore removed.
> 
> Note that you can now specify the tg3 mac address via the devicetree,
> on any platform, not just SPARC:
> 
> Devicetree example:
> (see Documentation/devicetree/bindings/pci/pci.txt)
> 
> &pcie {
> 	host@0 {
> 		#address-cells = <3>;
> 		#size-cells = <2>;
> 		reg = <0 0 0 0 0>;
> 		bcm5778: bcm5778@0 {
> 			reg = <0 0 0 0 0>;
> 			mac-address = [CA 11 AB 1E 10 01];
> 		};
> 	};
> };
> 
> Signed-off-by: Sven Van Asbroeck <svendev@arcx.com>

Applied to net-next, thanks.

^ permalink raw reply

* [PATCH v2 0/7] IP101GR: devicetree based configuration of SEL_INTR32
From: Martin Blumenstingl @ 2018-11-18 21:23 UTC (permalink / raw)
  To: netdev, devicetree, f.fainelli, andrew, mark.rutland, robh+dt,
	davem
  Cc: linux-kernel, Martin Blumenstingl

The IP101GR is a 32-pin QFN package variant of the IP101G/IP101GA
Ethernet PHY. Due to it's limited amount of pins the RXER (receive
error) and INTR32 (interrupt) functions share pin 21.

The goal of this series is:
- some small cleanups in patches 3, 4 and 5
- allowing the kernel to detect IRQ floods on boards where the IP101GR
  is configured in RXER mode but the RXER line is configured on the
  host SoC as interrupt line (patch 6)
- configuration of the SEL_INTR32 register so we can use the interrupt
  function on boards where the RXER/INTR32 pin (pin 21) is routed to
  one of the host SoC's interrupt inputs (patches 1, 2, 7)

A use-case where this is needed is the Endless Mini (EC-100). I have
tested my changes on that board. This also confirms that Heiner
Kallweit's recent icplus.c PHY driver changes are working (at least on
my setup).

This series is based on net-next commit 7c460cf9cd1a ("net: aquantia:
fix spelling mistake "specfield" -> "specified"")


Changes since v1 at [0]:
- collected Andrew's Reviewed-by's (thank you!)
- updated description of patch #2 to explain why two properties were
  added instead of adding an "this is a IP101GR" property
- validate that there's no conflicting configuration in patch #7
- rebased on top of latest net-next


[0] https://patchwork.ozlabs.org/cover/999371/


Martin Blumenstingl (7):
  dt-bindings: vendor-prefix: add prefix for IC Plus Corp.
  dt-bindings: net: phy: add bindings for the IC Plus Corp. IP101A/G
    PHYs
  net: phy: icplus: keep all ip101a_g functions together
  net: phy: icplus: use the BIT macro where possible
  net: phy: icplus: rename IP101A_G_NO_IRQ to IP101A_G_IRQ_ALL_MASK
  net: phy: icplus: implement .did_interrupt for IP101A/G
  net: phy: icplus: allow configuring the interrupt function on IP101GR

 .../bindings/net/icplus-ip101ag.txt           |  19 +++
 .../devicetree/bindings/vendor-prefixes.txt   |   1 +
 drivers/net/phy/icplus.c                      | 135 +++++++++++++++---
 3 files changed, 135 insertions(+), 20 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/icplus-ip101ag.txt

-- 
2.19.1

^ permalink raw reply

* [PATCH v2 1/7] dt-bindings: vendor-prefix: add prefix for IC Plus Corp.
From: Martin Blumenstingl @ 2018-11-18 21:23 UTC (permalink / raw)
  To: netdev, devicetree, f.fainelli, andrew, mark.rutland, robh+dt,
	davem
  Cc: linux-kernel, Martin Blumenstingl
In-Reply-To: <20181118212359.32414-1-martin.blumenstingl@googlemail.com>

IC Plus Corp. has various Ethernet related products such as Ethernet
transceivers, Ethernet controllers, Ethernet switches, etc.

Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 4b1a2a8fcc16..cc6b2c0d3b49 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -170,6 +170,7 @@ holtek	Holtek Semiconductor, Inc.
 hwacom	HwaCom Systems Inc.
 i2se	I2SE GmbH
 ibm	International Business Machines (IBM)
+icplus	IC Plus Corp.
 idt	Integrated Device Technologies, Inc.
 ifi	Ingenieurburo Fur Ic-Technologie (I/F/I)
 ilitek	ILI Technology Corporation (ILITEK)
-- 
2.19.1

^ permalink raw reply related

* [PATCH v2 2/7] dt-bindings: net: phy: add bindings for the IC Plus Corp. IP101A/G PHYs
From: Martin Blumenstingl @ 2018-11-18 21:23 UTC (permalink / raw)
  To: netdev, devicetree, f.fainelli, andrew, mark.rutland, robh+dt,
	davem
  Cc: linux-kernel, Martin Blumenstingl
In-Reply-To: <20181118212359.32414-1-martin.blumenstingl@googlemail.com>

The IP101A and IP101G series both have various models. Depending on the
board implementation we need a special property for the IP101GR (32-pin
LQFP package) PHY:
pin 21 ("RXER/INTR_32") outputs the "receive error" signal by default
(LOW means "normal operation", HIGH means that there's either a decoding
error of the received signal or that the PHY is receiving LPI). This pin
can also be switched to INTR32 mode, where the interrupt signal is
routed to this pin. The other PHYs don't need this special handling
because they have more pins available so the interrupt function gets a
dedicated pin.

This adds two properties to either select the "receive error" or
"interrupt" function of pin 21. Not specifying any function means that
the default set by the bootloader is used. This is required because the
IP101GR cannot be differentiated between other IP101 PHYs as the PHY
identification registers on all of these is 0x02430c54.

The IP101G (sold as die only, without package) may suffer from the same
issue depending on how it's integrated into a multi chip package by
another manufacturer. If only the RXER/INTR_32 pin is routed then the
users of the die-only variant may also have to explicitly configure the
mode of hte RXER/INTR_32 pin. This is the reason why no "is-ip101gr"
property was added. I have no evidence though which would confirm this
theory - so the binding itself is independent of that.

Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
---
 .../bindings/net/icplus-ip101ag.txt           | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/icplus-ip101ag.txt

diff --git a/Documentation/devicetree/bindings/net/icplus-ip101ag.txt b/Documentation/devicetree/bindings/net/icplus-ip101ag.txt
new file mode 100644
index 000000000000..a784592bbb15
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/icplus-ip101ag.txt
@@ -0,0 +1,19 @@
+IC Plus Corp. IP101A / IP101G Ethernet PHYs
+
+There are different models of the IP101G Ethernet PHY:
+- IP101GR (32-pin QFN package)
+- IP101G (die only, no package)
+- IP101GA (48-pin LQFP package)
+
+There are different models of the IP101A Ethernet PHY (which is the
+predecessor of the IP101G):
+- IP101A (48-pin LQFP package)
+- IP101AH (48-pin LQFP package)
+
+Optional properties for the IP101GR (32-pin QFN package):
+
+- icplus,select-rx-error:
+  pin 21 ("RXER/INTR_32") will output the receive error status.
+  interrupts are not routed outside the PHY in this mode.
+- icplus,select-interrupt:
+  pin 21 ("RXER/INTR_32") will output the interrupt signal.
-- 
2.19.1

^ permalink raw reply related

* [PATCH v2 3/7] net: phy: icplus: keep all ip101a_g functions together
From: Martin Blumenstingl @ 2018-11-18 21:23 UTC (permalink / raw)
  To: netdev, devicetree, f.fainelli, andrew, mark.rutland, robh+dt,
	davem
  Cc: linux-kernel, Martin Blumenstingl
In-Reply-To: <20181118212359.32414-1-martin.blumenstingl@googlemail.com>

This simply moves ip101a_g_config_init right above
ip101a_g_config_intr so all functions for the ICPlus IP101A/G PHYs are
grouped together.
No functional changes.

Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/phy/icplus.c | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c
index ad87bd3280d7..3d3e9134c762 100644
--- a/drivers/net/phy/icplus.c
+++ b/drivers/net/phy/icplus.c
@@ -162,21 +162,6 @@ static int ip1001_config_init(struct phy_device *phydev)
 	return 0;
 }
 
-static int ip101a_g_config_init(struct phy_device *phydev)
-{
-	int c;
-
-	c = ip1xx_reset(phydev);
-	if (c < 0)
-		return c;
-
-	/* Enable Auto Power Saving mode */
-	c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS);
-	c |= IP101A_G_APS_ON;
-
-	return phy_write(phydev, IP10XX_SPEC_CTRL_STATUS, c);
-}
-
 static int ip175c_read_status(struct phy_device *phydev)
 {
 	if (phydev->mdio.addr == 4) /* WAN port */
@@ -196,6 +181,21 @@ static int ip175c_config_aneg(struct phy_device *phydev)
 	return 0;
 }
 
+static int ip101a_g_config_init(struct phy_device *phydev)
+{
+	int c;
+
+	c = ip1xx_reset(phydev);
+	if (c < 0)
+		return c;
+
+	/* Enable Auto Power Saving mode */
+	c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS);
+	c |= IP101A_G_APS_ON;
+
+	return phy_write(phydev, IP10XX_SPEC_CTRL_STATUS, c);
+}
+
 static int ip101a_g_config_intr(struct phy_device *phydev)
 {
 	u16 val;
-- 
2.19.1

^ permalink raw reply related

* [PATCH v2 4/7] net: phy: icplus: use the BIT macro where possible
From: Martin Blumenstingl @ 2018-11-18 21:23 UTC (permalink / raw)
  To: netdev, devicetree, f.fainelli, andrew, mark.rutland, robh+dt,
	davem
  Cc: linux-kernel, Martin Blumenstingl
In-Reply-To: <20181118212359.32414-1-martin.blumenstingl@googlemail.com>

This makes the code consistent by using the BIT() macro instead of
manual bit-shifting for some of the fields. No functional changes.

Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/phy/icplus.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c
index 3d3e9134c762..3ec470adde3d 100644
--- a/drivers/net/phy/icplus.c
+++ b/drivers/net/phy/icplus.c
@@ -36,11 +36,11 @@ MODULE_LICENSE("GPL");
 
 /* IP101A/G - IP1001 */
 #define IP10XX_SPEC_CTRL_STATUS		16	/* Spec. Control Register */
-#define IP1001_RXPHASE_SEL		(1<<0)	/* Add delay on RX_CLK */
-#define IP1001_TXPHASE_SEL		(1<<1)	/* Add delay on TX_CLK */
+#define IP1001_RXPHASE_SEL		BIT(0)	/* Add delay on RX_CLK */
+#define IP1001_TXPHASE_SEL		BIT(1)	/* Add delay on TX_CLK */
 #define IP1001_SPEC_CTRL_STATUS_2	20	/* IP1001 Spec. Control Reg 2 */
 #define IP1001_APS_ON			11	/* IP1001 APS Mode  bit */
-#define IP101A_G_APS_ON			2	/* IP101A/G APS Mode bit */
+#define IP101A_G_APS_ON			BIT(1)	/* IP101A/G APS Mode bit */
 #define IP101A_G_IRQ_CONF_STATUS	0x11	/* Conf Info IRQ & Status Reg */
 #define	IP101A_G_IRQ_PIN_USED		BIT(15) /* INTR pin used */
 #define	IP101A_G_NO_IRQ			BIT(11) /* IRQ's inactive */
-- 
2.19.1

^ permalink raw reply related

* [PATCH v2 5/7] net: phy: icplus: rename IP101A_G_NO_IRQ to IP101A_G_IRQ_ALL_MASK
From: Martin Blumenstingl @ 2018-11-18 21:23 UTC (permalink / raw)
  To: netdev, devicetree, f.fainelli, andrew, mark.rutland, robh+dt,
	davem
  Cc: linux-kernel, Martin Blumenstingl
In-Reply-To: <20181118212359.32414-1-martin.blumenstingl@googlemail.com>

The datasheet uses the name "All Mask" for this bit. Change the name of
our #define to be consistent with the datasheet. While here also replace
the tab between the #define and IP101A_G_IRQ_ALL_MASK with a space.
No functional changes.

Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/phy/icplus.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c
index 3ec470adde3d..c9489ec77cef 100644
--- a/drivers/net/phy/icplus.c
+++ b/drivers/net/phy/icplus.c
@@ -43,7 +43,7 @@ MODULE_LICENSE("GPL");
 #define IP101A_G_APS_ON			BIT(1)	/* IP101A/G APS Mode bit */
 #define IP101A_G_IRQ_CONF_STATUS	0x11	/* Conf Info IRQ & Status Reg */
 #define	IP101A_G_IRQ_PIN_USED		BIT(15) /* INTR pin used */
-#define	IP101A_G_NO_IRQ			BIT(11) /* IRQ's inactive */
+#define IP101A_G_IRQ_ALL_MASK		BIT(11) /* IRQ's inactive */
 
 static int ip175c_config_init(struct phy_device *phydev)
 {
@@ -204,7 +204,7 @@ static int ip101a_g_config_intr(struct phy_device *phydev)
 		/* INTR pin used: Speed/link/duplex will cause an interrupt */
 		val = IP101A_G_IRQ_PIN_USED;
 	else
-		val = IP101A_G_NO_IRQ;
+		val = IP101A_G_IRQ_ALL_MASK;
 
 	return phy_write(phydev, IP101A_G_IRQ_CONF_STATUS, val);
 }
-- 
2.19.1

^ permalink raw reply related

* [PATCH v2 7/7] net: phy: icplus: allow configuring the interrupt function on IP101GR
From: Martin Blumenstingl @ 2018-11-18 21:23 UTC (permalink / raw)
  To: netdev, devicetree, f.fainelli, andrew, mark.rutland, robh+dt,
	davem
  Cc: linux-kernel, Martin Blumenstingl
In-Reply-To: <20181118212359.32414-1-martin.blumenstingl@googlemail.com>

The IP101GR is a 32-pin QFN package variant of the IP101G/IP101GA
Ethernet PHY. Due to it's limited amount of pins the RXER (receive
error) and INTR32 (interrupt) functions share pin 21.
By default the PHY is configured to output the "receive error" status on
pin 21. Depending on the board layout and requirements we may want to
re-configure the PHY to output the interrupt signal there.

The mode of pin 21 can be configured in the "Digital I/O Specific
Control Register" (register 29), bit 2:
- 0 = RXER function
- 1 = INTR(32) function

Depending on the devicetree configuration we will now:
- change the mode to either ther RXER or INTR32 function
- keep the SEL_INTR32 value set by the bootloader (default) if no
  configuration is provided (to ensure that we're not breaking existing
  boards)
- error out if conflicting configuration is given (RXER and INTR32 mode
  are enabled at the same time)

Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
 drivers/net/phy/icplus.c | 81 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 80 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c
index 3dc8bbbe746b..7d5938b87660 100644
--- a/drivers/net/phy/icplus.c
+++ b/drivers/net/phy/icplus.c
@@ -25,6 +25,7 @@
 #include <linux/mii.h>
 #include <linux/ethtool.h>
 #include <linux/phy.h>
+#include <linux/property.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -48,6 +49,23 @@ MODULE_LICENSE("GPL");
 #define IP101A_G_IRQ_DUPLEX_CHANGE	BIT(1)
 #define IP101A_G_IRQ_LINK_CHANGE	BIT(0)
 
+#define IP101G_DIGITAL_IO_SPEC_CTRL			0x1d
+#define IP101G_DIGITAL_IO_SPEC_CTRL_SEL_INTR32		BIT(2)
+
+/* The 32-pin IP101GR package can re-configure the mode of the RXER/INTR_32 pin
+ * (pin number 21). The hardware default is RXER (receive error) mode. But it
+ * can be configured to interrupt mode manually.
+ */
+enum ip101gr_sel_intr32 {
+	IP101GR_SEL_INTR32_KEEP,
+	IP101GR_SEL_INTR32_INTR,
+	IP101GR_SEL_INTR32_RXER,
+};
+
+struct ip101a_g_phy_priv {
+	enum ip101gr_sel_intr32 sel_intr32;
+};
+
 static int ip175c_config_init(struct phy_device *phydev)
 {
 	int err, i;
@@ -184,14 +202,74 @@ static int ip175c_config_aneg(struct phy_device *phydev)
 	return 0;
 }
 
+static int ip101a_g_probe(struct phy_device *phydev)
+{
+	struct device *dev = &phydev->mdio.dev;
+	struct ip101a_g_phy_priv *priv;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	/* Both functions (RX error and interrupt status) are sharing the same
+	 * pin on the 32-pin IP101GR, so this is an exclusive choice.
+	 */
+	if (device_property_read_bool(dev, "icplus,select-rx-error") &&
+	    device_property_read_bool(dev, "icplus,select-interrupt")) {
+		dev_err(dev,
+			"RXER and INTR mode cannot be selected together\n");
+		return -EINVAL;
+	}
+
+	if (device_property_read_bool(dev, "icplus,select-rx-error"))
+		priv->sel_intr32 = IP101GR_SEL_INTR32_RXER;
+	else if (device_property_read_bool(dev, "icplus,select-interrupt"))
+		priv->sel_intr32 = IP101GR_SEL_INTR32_INTR;
+	else
+		priv->sel_intr32 = IP101GR_SEL_INTR32_KEEP;
+
+	phydev->priv = priv;
+
+	return 0;
+}
+
 static int ip101a_g_config_init(struct phy_device *phydev)
 {
-	int c;
+	struct ip101a_g_phy_priv *priv = phydev->priv;
+	int err, c;
 
 	c = ip1xx_reset(phydev);
 	if (c < 0)
 		return c;
 
+	/* configure the RXER/INTR_32 pin of the 32-pin IP101GR if needed: */
+	switch (priv->sel_intr32) {
+	case IP101GR_SEL_INTR32_RXER:
+		err = phy_modify(phydev, IP101G_DIGITAL_IO_SPEC_CTRL,
+				 IP101G_DIGITAL_IO_SPEC_CTRL_SEL_INTR32, 0);
+		if (err < 0)
+			return err;
+		break;
+
+	case IP101GR_SEL_INTR32_INTR:
+		err = phy_modify(phydev, IP101G_DIGITAL_IO_SPEC_CTRL,
+				 IP101G_DIGITAL_IO_SPEC_CTRL_SEL_INTR32,
+				 IP101G_DIGITAL_IO_SPEC_CTRL_SEL_INTR32);
+		if (err < 0)
+			return err;
+		break;
+
+	default:
+		/* Don't touch IP101G_DIGITAL_IO_SPEC_CTRL because it's not
+		 * documented on IP101A and it's not clear whether this would
+		 * cause problems.
+		 * For the 32-pin IP101GR we simply keep the SEL_INTR32
+		 * configuration as set by the bootloader when not configured
+		 * to one of the special functions.
+		 */
+		break;
+	}
+
 	/* Enable Auto Power Saving mode */
 	c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS);
 	c |= IP101A_G_APS_ON;
@@ -257,6 +335,7 @@ static struct phy_driver icplus_driver[] = {
 	.name		= "ICPlus IP101A/G",
 	.phy_id_mask	= 0x0ffffff0,
 	.features	= PHY_BASIC_FEATURES,
+	.probe		= ip101a_g_probe,
 	.config_intr	= ip101a_g_config_intr,
 	.did_interrupt	= ip101a_g_did_interrupt,
 	.ack_interrupt	= ip101a_g_ack_interrupt,
-- 
2.19.1

^ permalink raw reply related

* Re: [PATCH 7/7] net: phy: icplus: allow configuring the interrupt function on IP101GR
From: Martin Blumenstingl @ 2018-11-18 21:25 UTC (permalink / raw)
  To: andrew
  Cc: netdev, devicetree, f.fainelli, mark.rutland, robh+dt, davem,
	linux-kernel
In-Reply-To: <20181118174531.GA7446@lunn.ch>

On Sun, Nov 18, 2018 at 6:45 PM Andrew Lunn <andrew@lunn.ch> wrote:
>
> > I'll wait a few days for more feedback and re-send this series with
> > that issue fixed
>
> Hi Martin
>
> In networking world, you should expect feedback within 3 days. So i
> was actually a bit slow. If i'd of waited much longer, David would of
> merged the patches very soon.
good to know, thanks
for me as "someone who sends patches" (and as someone who is impatient
sometimes... ;)) this is great because I don't have to wait ages for
feedback!

> So feel free to respin the patchset now if you want.
I just sent v2


Regards
Martin

^ permalink raw reply

* Re: [PATCH iproute2-next v3] rdma: Document IB device renaming option
From: Leon Romanovsky @ 2018-11-18 11:05 UTC (permalink / raw)
  To: Ruhl, Michael J; +Cc: David Ahern, netdev, RDMA mailing list, Stephen Hemminger
In-Reply-To: <14063C7AD467DE4B82DEDB5C278E8663BE61B8E2@FMSMSX108.amr.corp.intel.com>

[-- Attachment #1: Type: text/plain, Size: 3114 bytes --]

On Fri, Nov 16, 2018 at 08:10:35PM +0000, Ruhl, Michael J wrote:
> >-----Original Message-----
> >From: linux-rdma-owner@vger.kernel.org [mailto:linux-rdma-
> >owner@vger.kernel.org] On Behalf Of Leon Romanovsky
> >Sent: Sunday, November 4, 2018 2:11 PM
> >To: David Ahern <dsahern@gmail.com>
> >Cc: Leon Romanovsky <leonro@mellanox.com>; netdev
> ><netdev@vger.kernel.org>; RDMA mailing list <linux-rdma@vger.kernel.org>;
> >Stephen Hemminger <stephen@networkplumber.org>
> >Subject: [PATCH iproute2-next v3] rdma: Document IB device renaming
> >option
> >
> >From: Leon Romanovsky <leonro@mellanox.com>
>
> Hi Leon,
>
> After looking at this and Steve Wise's changes for the ADDLINK/DELLINK,
> it occurred to me that the driver that handed the name to ib_register_device()
> might be interested in knowing that this name change occurred.
>
> Are there plans to include a some kind of notify mechanism so drivers can
> find out when things like this occur?

At least for device rename, I don't see any real need for such event,
because drivers are not supposed to rely on names.

I would say that it is probably driver bug to rely on device name
during its execution.

>
> Is this something that should be done?

I think yes, we can extend ib_event to support more events than now,
but should we?

>
> Thanks,
>
> Mike
>
> >[leonro@server /]$ lspci |grep -i Ether
> >00:08.0 Ethernet controller: Red Hat, Inc. Virtio network device
> >00:09.0 Ethernet controller: Mellanox Technologies MT27700 Family
> >[ConnectX-4]
> >[leonro@server /]$ sudo rdma dev
> >1: mlx5_0: node_type ca fw 3.8.9999 node_guid 5254:00c0:fe12:3455
> >sys_image_guid 5254:00c0:fe12:3455
> >[leonro@server /]$ sudo rdma dev set mlx5_0 name hfi1_0
> >[leonro@server /]$ sudo rdma dev
> >1: hfi1_0: node_type ca fw 3.8.9999 node_guid 5254:00c0:fe12:3455
> >sys_image_guid 5254:00c0:fe12:3455
> >
> >Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
> >---
> >Changelog:
> >v2->v3:
> > * Dropped "to be named" words from example section of man
> >---
> > man/man8/rdma-dev.8 | 15 ++++++++++++++-
> > 1 file changed, 14 insertions(+), 1 deletion(-)
> >
> >diff --git a/man/man8/rdma-dev.8 b/man/man8/rdma-dev.8
> >index 461681b6..7c275180 100644
> >--- a/man/man8/rdma-dev.8
> >+++ b/man/man8/rdma-dev.8
> >@@ -1,6 +1,6 @@
> > .TH RDMA\-DEV 8 "06 Jul 2017" "iproute2" "Linux"
> > .SH NAME
> >-rdmak-dev \- RDMA device configuration
> >+rdma-dev \- RDMA device configuration
> > .SH SYNOPSIS
> > .sp
> > .ad l
> >@@ -22,10 +22,18 @@ rdmak-dev \- RDMA device configuration
> > .B rdma dev show
> > .RI "[ " DEV " ]"
> >
> >+.ti -8
> >+.B rdma dev set
> >+.RI "[ " DEV " ]"
> >+.BR name
> >+.BR NEWNAME
> >+
> > .ti -8
> > .B rdma dev help
> >
> > .SH "DESCRIPTION"
> >+.SS rdma dev set - rename rdma device
> >+
> > .SS rdma dev show - display rdma device attributes
> >
> > .PP
> >@@ -45,6 +53,11 @@ rdma dev show mlx5_3
> > Shows the state of specified RDMA device.
> > .RE
> > .PP
> >+rdma dev set mlx5_3 name rdma_0
> >+.RS 4
> >+Renames the mlx5_3 device to rdma_0.
> >+.RE
> >+.PP
> >
> > .SH SEE ALSO
> > .BR rdma (8),
> >--
> >2.19.1
>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply

* (unknown), 
From: Mrs. Maureen Hinckley @ 2018-11-18  9:11 UTC (permalink / raw)




I am Maureen Hinckley and my foundation is donating (Five hundred and fifty thousand USD) to you. Contact us via my email at (maurhinck1@gmail.com) for further details.


 Best Regards, Mrs. Maureen Hinckley,  Copyright &copy;2018 The Maureen Hinckley Foundation All Rights Reserved.

^ permalink raw reply

* Re: [PATCH v2 0/7] IP101GR: devicetree based configuration of SEL_INTR32
From: David Miller @ 2018-11-19  0:16 UTC (permalink / raw)
  To: martin.blumenstingl
  Cc: netdev, devicetree, f.fainelli, andrew, mark.rutland, robh+dt,
	linux-kernel
In-Reply-To: <20181118212359.32414-1-martin.blumenstingl@googlemail.com>

From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Date: Sun, 18 Nov 2018 22:23:52 +0100

> The IP101GR is a 32-pin QFN package variant of the IP101G/IP101GA
> Ethernet PHY. Due to it's limited amount of pins the RXER (receive
> error) and INTR32 (interrupt) functions share pin 21.
 ...

Series applied to net-next, thank you.

^ permalink raw reply

* [PATCH net] sctp: not increase stream's incnt before sending addstrm_in request
From: Xin Long @ 2018-11-18 13:59 UTC (permalink / raw)
  To: network dev, linux-sctp; +Cc: davem, Marcelo Ricardo Leitner, Neil Horman

Different from processing the addstrm_out request, The receiver handles
an addstrm_in request by sending back an addstrm_out request to the
sender who will increase its stream's in and incnt later.

Now stream->incnt has been increased since it sent out the addstrm_in
request in sctp_send_add_streams(), with the wrong stream->incnt will
even cause crash when copying stream info from the old stream's in to
the new one's in sctp_process_strreset_addstrm_out().

This patch is to fix it by simply removing the stream->incnt change
from sctp_send_add_streams().

Fixes: 242bd2d519d7 ("sctp: implement sender-side procedures for Add Incoming/Outgoing Streams Request Parameter")
Reported-by: Jianwen Ji <jiji@redhat.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 net/sctp/stream.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/net/sctp/stream.c b/net/sctp/stream.c
index ffb940d..3892e76 100644
--- a/net/sctp/stream.c
+++ b/net/sctp/stream.c
@@ -535,7 +535,6 @@ int sctp_send_add_streams(struct sctp_association *asoc,
 		goto out;
 	}
 
-	stream->incnt = incnt;
 	stream->outcnt = outcnt;
 
 	asoc->strreset_outstanding = !!out + !!in;
-- 
2.1.0

^ permalink raw reply related

* Re: hw csum failure + conntrack with more debugging information
From: Andre Tomt @ 2018-11-18 14:51 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev, Cong Wang
In-Reply-To: <CANn89i+VooCQ9eTXWMjXWPvV0_LfKeQ_+aJbxBzdhSe8=7R6uw@mail.gmail.com>

On 18.11.2018 02:12, Eric Dumazet wrote:
> 
> 
> On Sat, Nov 17, 2018 at 3:18 PM Andre Tomt <andre@tomt.net 
> <mailto:andre@tomt.net>> wrote:
> 
>     I added Cong Wang's hw csum failure debug patch to my 4.19.2 tree and
>     got a splat with a bit more information.
> 
>      > [47273.905616] p0xe0: hw csum failure
>      > [47273.905642] dev features: 0x000860c000114bb3
>      > [47273.905663] skb len=44 data_len=0 gso_size=0 gso_type=0
>     ip_summed=2 csum=0, csum_complete_sw=0, csum_valid=0
>      > [47273.905706] CPU: 1 PID: 0 Comm: swapper/1 Not tainted 4.19.0-1 #1
>      > [47273.905707] Hardware name: Supermicro Super
>     Server/X10SDV-4C-TLN2F, BIOS 2.0 06/13/2018
>      > [47273.905707] Call Trace:
>      > [47273.905710]  <IRQ>
>      > [47273.905717]  dump_stack+0x5c/0x80
>      > [47273.905721]  __skb_checksum_complete+0xaf/0xc0
>      > [47273.905731]  icmp_error+0x1c8/0x1f0 [nf_conntrack]
>      > [47273.905734]  ? skb_copy_bits+0x13d/0x220
>      > [47273.905740]  nf_conntrack_in+0xd8/0x390 [nf_conntrack]
>      > [47273.905743]  ? ___pskb_trim+0x192/0x330
>      > [47273.905746]  nf_hook_slow+0x43/0xc0
>      > [47273.905749]  ip_rcv+0x90/0xb0
>      > [47273.905752]  ? ip_rcv_finish_core.isra.0+0x310/0x310
>      > [47273.905754]  __netif_receive_skb_one_core+0x42/0x50
>      > [47273.905756]  netif_receive_skb_internal+0x24/0xb0
>      > [47273.905758]  napi_gro_frags+0x177/0x210
>      > [47273.905762]  mlx4_en_process_rx_cq+0x8df/0xb50 [mlx4_en]
>      > [47273.905773]  ? mlx4_eq_int+0x38f/0xcb0 [mlx4_core]
>      > [47273.905776]  mlx4_en_poll_rx_cq+0x55/0xf0 [mlx4_en]
>      > [47273.905778]  net_rx_action+0xe1/0x2c0
>      > [47273.905781]  __do_softirq+0xe7/0x2d3
>      > [47273.905784]  irq_exit+0x96/0xd0
>      > [47273.905786]  do_IRQ+0x85/0xd0
>      > [47273.905790]  common_interrupt+0xf/0xf
>      > [47273.905791]  </IRQ>
>      > [47273.905794] RIP: 0010:cpuidle_enter_state+0xb9/0x320
>      > [47273.905796] Code: e8 3c 15 bc ff 80 7c 24 0b 00 74 17 9c 58 0f
>     1f 44 00 00 f6 c4 02 0f 85 3b 02 00 00 31 ff e8 6e fa c0 ff fb 66 0f
>     1f 44 00 00 <48> b8 ff ff ff ff f3 01 00 00 48 2b 1c 24 ba ff ff ff
>     7f 48 39 c3
>      > [47273.905798] RSP: 0018:ffffb75601943ea8 EFLAGS: 00000246
>     ORIG_RAX: ffffffffffffffdb
>      > [47273.905801] RAX: ffff9d636fa60fc0 RBX: 00002afed059e821 RCX:
>     000000000000001f
>      > [47273.905802] RDX: 00002afed059e821 RSI: 000000003a2ea91a RDI:
>     0000000000000000
>      > [47273.905803] RBP: ffff9d636fa698c8 R08: 0000000000000002 R09:
>     0000000000020840
>      > [47273.905804] R10: 000e97ef158d1e39 R11: ffff9d636fa601e8 R12:
>     0000000000000001
>      > [47273.905805] R13: ffffffffab0ac698 R14: 0000000000000001 R15:
>     0000000000000000
>      > [47273.905808]  ? cpuidle_enter_state+0x94/0x320
>      > [47273.905812]  do_idle+0x1e4/0x220
>      > [47273.905815]  cpu_startup_entry+0x5f/0x70
>      > [47273.905818]  start_secondary+0x185/0x1a0
>      > [47273.905821]  secondary_startup_64+0xa4/0xb0
> 
>     All instances stripped of the identical stack traces:
>      > [13778.531040] dev features: 0x000860c000114bb3
>      > [13778.531056] skb len=40 data_len=0 gso_size=0 gso_type=0
>     ip_summed=2 csum=0, csum_complete_sw=0, csum_valid=0
>      > [13778.531176] dev features: 0x000860c000114bb3
>      > [13778.531204] skb len=40 data_len=0 gso_size=0 gso_type=0
>     ip_summed=2 csum=0, csum_complete_sw=0, csum_valid=0
>      > [13778.531256] dev features: 0x000860c000114bb3
>      > [13778.531285] skb len=40 data_len=0 gso_size=0 gso_type=0
>     ip_summed=2 csum=0, csum_complete_sw=0, csum_valid=0 >
>     [47273.905642] dev features: 0x000860c000114bb3
>      > [47273.905663] skb len=44 data_len=0 gso_size=0 gso_type=0
>     ip_summed=2 csum=0, csum_complete_sw=0, csum_valid=0
> 
>     The setup has also further been simplified by also removing vlans and
>     6to4 tunnels, It's now only conntrack and nat (configured with
>     nftables)
>     on bare ethernet netdevs.
> 
>     offloads, ring sizes etc is left at defaults,
>     net.ipv4.ip_early_demux is
>     off, fq_codel as net.core.default_qdisc
> 
>     Hardware is ConnectX-3 VPI 2xQSFP+ (firmware 2.42.5000) on a quad core
>     Xeon D-1521, passing traffic from port 1 to port 2 on the same card.
>     Last switch to touch the packets is an Arista DCS-7050QX-32 running EOS
>     4.20.2.1F
> 
>     This kernel build contains some other bits and pieces from net.git
>     (mostly things queued for stable) and a couple of backports from
>     net-next (Aaron Lu's pcp page recycling fix, Eric's BQL+mlx4
>     optimizations), but the stack traces are identical to before so they
>     dont seem involved in this.
> 
>     Workload remains nearly exclusively TCP and UDP torrent junk traffic to
>     two machines behind it.
> 
> 
> 
> Please try this patch, we suspect mlx4 support for CHECKSUM_COMPLETE is 
> wrong.
> 
> (Only IPv4 handled, but I suspect a similar fix is needed for IPv6)

Testing it now. Can sometimes take a few days to hit here so will 
probably have to leave it running for a while.

^ permalink raw reply

* [PATCH net-next] tun: use netdev_alloc_frag() in tun_napi_alloc_frags()
From: Eric Dumazet @ 2018-11-18 15:37 UTC (permalink / raw)
  To: David S . Miller
  Cc: netdev, Eric Dumazet, Eric Dumazet, Petar Penkov, Mahesh Bandewar,
	Willem de Bruijn

In order to cook skbs in the same way than Ethernet drivers,
it is probably better to not use GFP_KERNEL, but rather
use the GFP_ATOMIC and PFMEMALLOC mechanisms provided by
netdev_alloc_frag().

This would allow to use tun driver even in memory stress
situations, especially if swap is used over this tun channel.

Fixes: 90e33d459407 ("tun: enable napi_gro_frags() for TUN/TAP driver")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Petar Penkov <peterpenkov96@gmail.com>
Cc: Mahesh Bandewar <maheshb@google.com>
Cc: Willem de Bruijn <willemb@google.com>
---
 drivers/net/tun.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 36163a147d3950a5d7451abed96809c2af7c322f..1e9da697081d10e086a26deb1ab38e62f77436b5 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1478,23 +1478,22 @@ static struct sk_buff *tun_napi_alloc_frags(struct tun_file *tfile,
 	skb->truesize += skb->data_len;
 
 	for (i = 1; i < it->nr_segs; i++) {
-		struct page_frag *pfrag = &current->task_frag;
 		size_t fragsz = it->iov[i].iov_len;
+		struct page *page;
+		void *frag;
 
 		if (fragsz == 0 || fragsz > PAGE_SIZE) {
 			err = -EINVAL;
 			goto free;
 		}
-
-		if (!skb_page_frag_refill(fragsz, pfrag, GFP_KERNEL)) {
+		frag = netdev_alloc_frag(fragsz);
+		if (!frag) {
 			err = -ENOMEM;
 			goto free;
 		}
-
-		skb_fill_page_desc(skb, i - 1, pfrag->page,
-				   pfrag->offset, fragsz);
-		page_ref_inc(pfrag->page);
-		pfrag->offset += fragsz;
+		page = virt_to_head_page(frag);
+		skb_fill_page_desc(skb, i - 1, page,
+				   frag - page_address(page), fragsz);
 	}
 
 	return skb;
-- 
2.19.1.1215.g8438c0b245-goog

^ permalink raw reply related

* Re: [v3, PATCH 2/2] dt-binding: mediatek-dwmac: add binding document for MediaTek MT2712 DWMAC
From: biao huang @ 2018-11-19  2:12 UTC (permalink / raw)
  To: Sean Wang
  Cc: davem@davemloft.net, robh+dt@kernel.org, mark.rutland@arm.com,
	devicetree@vger.kernel.org,
	Nelson Chang (張家祥), andrew@lunn.ch,
	netdev@vger.kernel.org, Liguo Zhang (张立国),
	linux-kernel@vger.kernel.org, Matthias Brugger,
	joabreu@synopsys.com, linux-mediatek@lists.infradead.org,
	Honghui Zhang (张洪辉)
In-Reply-To: <CAGp9LzrHm-ympV2zAKZKcEfA25aJp8BSS+=01B6G=sP_HiSSdA@mail.gmail.com>

Dear Sean,

	Thanks for your detailed comments~

On Sat, 2018-11-17 at 08:21 +0800, Sean Wang wrote:
> On Fri, Nov 16, 2018 at 1:19 AM Biao Huang <biao.huang@mediatek.com> wrote:
> >
> > The commit adds the device tree binding documentation for the MediaTek DWMAC
> > found on MediaTek MT2712.
> >
> > Change-Id: I3728666bf65927164bd82fa8dddb90df8270bd44
> 
> Drop change-id
sorry, I forgot it. will remove in next version.
> 
> > Signed-off-by: Biao Huang <biao.huang@mediatek.com>
> > ---
> >  .../devicetree/bindings/net/mediatek-dwmac.txt     |   77 ++++++++++++++++++++
> >  1 file changed, 77 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/net/mediatek-dwmac.txt
> >
> > diff --git a/Documentation/devicetree/bindings/net/mediatek-dwmac.txt b/Documentation/devicetree/bindings/net/mediatek-dwmac.txt
> > new file mode 100644
> > index 0000000..7fd56e0
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/net/mediatek-dwmac.txt
> > @@ -0,0 +1,77 @@
> > +MediaTek DWMAC glue layer controller
> > +
> > +This file documents platform glue layer for stmmac.
> > +Please see stmmac.txt for the other unchanged properties.
> > +
> > +The device node has following properties.
> > +
> > +Required properties:
> > +- compatible:  Should be "mediatek,mt2712-gmac" for MT2712 SoC
> > +- reg:  Address and length of the register set for the device
> > +- interrupts:  Should contain the MAC interrupts
> > +- interrupt-names: Should contain a list of interrupt names corresponding to
> > +       the interrupts in the interrupts property, if available.
> > +       Should be "macirq" for the main MAC IRQ
> > +- clocks: Must contain a phandle for each entry in clock-names.
> > +- clock-names: The name of the clock listed in the clocks property. These are
> > +       "axi", "apb", "mac_ext", "mac_parent", "ptp_ref", "ptp_parent", "ptp_top"
> > +       for MT2712 SoC
> 
> About not including these parent clocks to the controller, you can
> refer to assigned-clocks, assigned-clock-parents, assigned-clock-rates
> noted in Documentation/devicetree/bindings/clock/clock-bindings.txt to
> determine what speed these MUXs should be run at and see [1] as the
> example how applied in dts.
> 
> [1]
> https://elixir.bootlin.com/linux/latest/source/arch/arm/boot/dts/mt7623.dtsi#L660
> 
Got it, I'll remove parent info to dts.
> > +- mac-address: See ethernet.txt in the same directory
> > +- phy-mode: See ethernet.txt in the same directory
> > +
> > +Optional properties:
> > +- tx-delay: TX clock delay macro value. Range is 0~31. Default is 0.
> > +       It should be defined for rgmii/rgmii-rxid/mii interface.
> > +- rx-delay: RX clock delay macro value. Range is 0~31. Default is 0.
> > +       It should be defined for rgmii/rgmii-txid/mii/rmii interface.
> > +- fine-tune: This property will select coarse-tune delay or fine delay
> > +       for rgmii interface.
> what is the property's type?
> 
ok, property type info will be added in next version.
> > +       If fine-tune delay is enabled, tx-delay/rx-delay is 170+/-50ps
> > +       per stage.
> > +       Else coarse-tune delay is enabled, tx-delay/rx-delay is 0.55+/-0.2ns
> > +       per stage.
> > +       This property do not apply to non-rgmii PHYs.
> > +       Only coarse-tune delay is supported for mii/rmii PHYs.
> > +- rmii-rxc: Reference clock of rmii is from external PHYs,
> what is the property's type?
> 
got it.
> > +       and it can be connected to TXC or RXC pin on MT2712 SoC.
> > +       If ref_clk <--> TXC, disable it.
> > +       Else ref_clk <--> RXC, enable it.
> > +- txc-inverse: Inverse tx clock for mii/rgmii.
> what is the property's type?
> 
> > +       Inverse tx clock inside MAC relative to reference clock for rmii,
> > +       and it rarely happen.
> > +- rxc-inverse: Inverse rx clock for mii/rgmii interfaces.
> what is the property's type?
> 
got it.
> > +       Inverse reference clock for rmii.
> 
> If these optional properties look like generic enough, it would be
> good that place them to stmmac.txt. Otherwise, they should be added
> "mediatek," as the prefix string for these vendor-specific things.
> 
it's mediatek-specific, and the prefix string will be added in next
version.
> > +
> > +Example:
> > +       eth: ethernet@1101c000 {
> > +               compatible = "mediatek,mt2712-gmac";
> > +               reg = <0 0x1101c000 0 0x1300>;
> > +               interrupts = <GIC_SPI 237 IRQ_TYPE_LEVEL_LOW>;
> > +               interrupt-names = "macirq";
> > +               phy-mode ="rgmii-id";
> > +               mac-address = [00 55 7b b5 7d f7];
> > +               clock-names = "axi",
> > +                             "apb",
> > +                             "mac_ext",
> > +                             "mac_parent",
> > +                             "ptp_ref",
> > +                             "ptp_parent",
> > +                             "ptp_top";
> > +               clocks = <&pericfg CLK_PERI_GMAC>,
> > +                        <&pericfg CLK_PERI_GMAC_PCLK>,
> > +                        <&topckgen CLK_TOP_ETHER_125M_SEL>,
> > +                        <&topckgen CLK_TOP_ETHERPLL_125M>,
> > +                        <&topckgen CLK_TOP_ETHER_50M_SEL>,
> > +                        <&topckgen CLK_TOP_APLL1_D3>,
> > +                        <&topckgen CLK_TOP_APLL1>;
> > +               snps,txpbl = <32>;
> > +               snps,rxpbl = <32>;
> > +               snps,reset-gpio = <&pio 87 GPIO_ACTIVE_LOW>;
> > +               snps,reset-active-low;
> > +               tx-delay = <9>;
> > +               rx-delay = <9>;
> > +               fine-tune;
> > +               rmii-rxc;
> > +               txc-inverse;
> > +               rxc-inverse;
> > +       };
> > --
> > 1.7.9.5
> >
> >
> > _______________________________________________
> > Linux-mediatek mailing list
> > Linux-mediatek@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply

* Re: [PATCH 2/4] net/bpf: refactor freeing of executable allocations
From: Ard Biesheuvel @ 2018-11-18 15:55 UTC (permalink / raw)
  To: ys114321
  Cc: Linux Kernel Mailing List, Daniel Borkmann, Alexei Starovoitov,
	Rick Edgecombe, Eric Dumazet, Jann Horn, Kees Cook, Jessica Yu,
	Arnd Bergmann, Catalin Marinas, Will Deacon, Mark Rutland,
	Ralf Baechle, Paul Burton, James Hogan, Benjamin Herrenschmidt,
	Paul Mackerras, Michael Ellerman, David S. Miller,
	linux-arm-kernel <lin
In-Reply-To: <CAH3MdRV85imzia+=irgbjL48wqFdorB-F1=BkwBgJgi3Z-XAKA@mail.gmail.com>

On Sat, 17 Nov 2018 at 23:47, Y Song <ys114321@gmail.com> wrote:
>
> On Sat, Nov 17, 2018 at 6:58 PM Ard Biesheuvel
> <ard.biesheuvel@linaro.org> wrote:
> >
> > All arch overrides of the __weak bpf_jit_free() amount to the same
> > thing: the allocated memory was never mapped read-only, and so
> > it does not have to be remapped to read-write before being freed.
> >
> > So in preparation of permitting arches to serve allocations for BPF
> > JIT programs from other regions than the module region, refactor
> > the existing bpf_jit_free() implementations to use the shared code
> > where possible, and only specialize the remap and free operations.
> >
> > Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> > ---
> >  arch/mips/net/bpf_jit.c           |  7 ++-----
> >  arch/powerpc/net/bpf_jit_comp.c   |  7 ++-----
> >  arch/powerpc/net/bpf_jit_comp64.c |  9 +++------
> >  arch/sparc/net/bpf_jit_comp_32.c  |  7 ++-----
> >  kernel/bpf/core.c                 | 15 +++++----------
> >  5 files changed, 14 insertions(+), 31 deletions(-)
> >
> > diff --git a/arch/mips/net/bpf_jit.c b/arch/mips/net/bpf_jit.c
> > index 1b69897274a1..5696bd7dccc7 100644
> > --- a/arch/mips/net/bpf_jit.c
> > +++ b/arch/mips/net/bpf_jit.c
> > @@ -1261,10 +1261,7 @@ void bpf_jit_compile(struct bpf_prog *fp)
> >         kfree(ctx.offsets);
> >  }
> >
> > -void bpf_jit_free(struct bpf_prog *fp)
> > +void bpf_jit_binary_free(struct bpf_binary_header *hdr)
> >  {
> > -       if (fp->jited)
> > -               bpf_jit_binary_free(bpf_jit_binary_hdr(fp));
> > -
> > -       bpf_prog_unlock_free(fp);
> > +       module_memfree(hdr);
> >  }
> > diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
> > index a1ea1ea6b40d..5b5ce4a1b44b 100644
> > --- a/arch/powerpc/net/bpf_jit_comp.c
> > +++ b/arch/powerpc/net/bpf_jit_comp.c
> > @@ -680,10 +680,7 @@ void bpf_jit_compile(struct bpf_prog *fp)
> >         return;
> >  }
> >
> > -void bpf_jit_free(struct bpf_prog *fp)
> > +void bpf_jit_binary_free(struct bpf_binary_header *hdr)
> >  {
> > -       if (fp->jited)
> > -               bpf_jit_binary_free(bpf_jit_binary_hdr(fp));
> > -
> > -       bpf_prog_unlock_free(fp);
> > +       module_memfree(hdr);
> >  }
> > diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c
> > index 84c8f013a6c6..f64f1294bd62 100644
> > --- a/arch/powerpc/net/bpf_jit_comp64.c
> > +++ b/arch/powerpc/net/bpf_jit_comp64.c
> > @@ -1021,11 +1021,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
> >         return fp;
> >  }
> >
> > -/* Overriding bpf_jit_free() as we don't set images read-only. */
> > -void bpf_jit_free(struct bpf_prog *fp)
> > +/* Overriding bpf_jit_binary_free() as we don't set images read-only. */
> > +void bpf_jit_binary_free(struct bpf_binary_header *hdr)
> >  {
> > -       if (fp->jited)
> > -               bpf_jit_binary_free(bpf_jit_binary_hdr(fp));
> > -
> > -       bpf_prog_unlock_free(fp);
> > +       module_memfree(hdr);
> >  }
> > diff --git a/arch/sparc/net/bpf_jit_comp_32.c b/arch/sparc/net/bpf_jit_comp_32.c
> > index 01bda6bc9e7f..589950d152cc 100644
> > --- a/arch/sparc/net/bpf_jit_comp_32.c
> > +++ b/arch/sparc/net/bpf_jit_comp_32.c
> > @@ -756,10 +756,7 @@ cond_branch:                       f_offset = addrs[i + filter[i].jf];
> >         return;
> >  }
> >
> > -void bpf_jit_free(struct bpf_prog *fp)
> > +void bpf_jit_binary_free(struct bpf_binary_header *hdr)
> >  {
> > -       if (fp->jited)
> > -               bpf_jit_binary_free(bpf_jit_binary_hdr(fp));
> > -
> > -       bpf_prog_unlock_free(fp);
> > +       module_memfree(hdr);
> >  }
> > diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
> > index 1a796e0799ec..29f766dac203 100644
> > --- a/kernel/bpf/core.c
> > +++ b/kernel/bpf/core.c
> > @@ -646,25 +646,20 @@ bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr,
> >         return hdr;
> >  }
> >
> > -void bpf_jit_binary_free(struct bpf_binary_header *hdr)
> > +void __weak bpf_jit_binary_free(struct bpf_binary_header *hdr)
> >  {
> > -       u32 pages = hdr->pages;
> > -
> > +       bpf_jit_binary_unlock_ro(hdr);
> >         module_memfree(hdr);
> > -       bpf_jit_uncharge_modmem(pages);
> >  }
> >
> > -/* This symbol is only overridden by archs that have different
> > - * requirements than the usual eBPF JITs, f.e. when they only
> > - * implement cBPF JIT, do not set images read-only, etc.
> > - */
>
> Do you want to move the above comments to
> new weak function bpf_jit_binary_free?
>

Perhaps. But one thing I don't understand, looking at this again, is
why we have these overrides in the first place. module_memfree() just
calls vfree(), which takes down the mapping entirely (along with any
updated permissions), and so remapping it back to r/w right before
that seems rather pointless imo.

Can we get rid of bpf_jit_binary_unlock_ro() entirely, and along with
it, all these overrides for the free() path?

^ permalink raw reply

* Re: [PATCH v2 02/25] mtd: add support for reading MTD devices via the nvmem API
From: Boris Brezillon @ 2018-11-18 16:06 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Sekhar Nori, Kevin Hilman, Russell King, Arnd Bergmann,
	Greg Kroah-Hartman, David Woodhouse, Brian Norris, Marek Vasut,
	Richard Weinberger, Nicolas Ferre, David S . Miller,
	Grygorii Strashko, Srinivas Kandagatla, Andrew Lunn,
	Florian Fainelli, Rob Herring, Frank Rowand, Wolfram Sang,
	devicetree, netdev, lin
In-Reply-To: <20181113140133.17385-3-brgl@bgdev.pl>

On Tue, 13 Nov 2018 15:01:10 +0100
Bartosz Golaszewski <brgl@bgdev.pl> wrote:

> From: Alban Bedel <albeu@free.fr>
> 
> Allow drivers that use the nvmem API to read data stored on MTD devices.
> For this the mtd devices are registered as read-only NVMEM providers.
> 
> We don't support device tree systems for now.
> 
> Signed-off-by: Alban Bedel <albeu@free.fr>
> [Bartosz:
>   - include linux/nvmem-provider.h
>   - set the name of the nvmem provider
>   - set no_of_node to true in nvmem_config
>   - don't check the return value of nvmem_unregister() - it cannot fail
>   - tweaked the commit message]
> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Acked-by: Boris Brezillon <boris.brezillon@bootlin.com>

To the person taking this patch (Greg?): I'll need an immutable tag,
just in case we end up with other changes in mtdcore.c for this release.

> ---
>  drivers/mtd/Kconfig     |  1 +
>  drivers/mtd/mtdcore.c   | 56 +++++++++++++++++++++++++++++++++++++++++
>  include/linux/mtd/mtd.h |  2 ++
>  3 files changed, 59 insertions(+)
> 
> diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
> index c77f537323ec..efbe7a6f1d8f 100644
> --- a/drivers/mtd/Kconfig
> +++ b/drivers/mtd/Kconfig
> @@ -1,5 +1,6 @@
>  menuconfig MTD
>  	tristate "Memory Technology Device (MTD) support"
> +	imply NVMEM
>  	help
>  	  Memory Technology Devices are flash, RAM and similar chips, often
>  	  used for solid state file systems on embedded devices. This option
> diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
> index 97ac219c082e..5f1053d995b0 100644
> --- a/drivers/mtd/mtdcore.c
> +++ b/drivers/mtd/mtdcore.c
> @@ -41,6 +41,7 @@
>  #include <linux/reboot.h>
>  #include <linux/leds.h>
>  #include <linux/debugfs.h>
> +#include <linux/nvmem-provider.h>
>  
>  #include <linux/mtd/mtd.h>
>  #include <linux/mtd/partitions.h>
> @@ -488,6 +489,50 @@ int mtd_pairing_groups(struct mtd_info *mtd)
>  }
>  EXPORT_SYMBOL_GPL(mtd_pairing_groups);
>  
> +static int mtd_nvmem_reg_read(void *priv, unsigned int offset,
> +			      void *val, size_t bytes)
> +{
> +	struct mtd_info *mtd = priv;
> +	size_t retlen;
> +	int err;
> +
> +	err = mtd_read(mtd, offset, bytes, &retlen, val);
> +	if (err && err != -EUCLEAN)
> +		return err;
> +
> +	return retlen == bytes ? 0 : -EIO;
> +}
> +
> +static int mtd_nvmem_add(struct mtd_info *mtd)
> +{
> +	struct nvmem_config config = {};
> +
> +	config.dev = &mtd->dev;
> +	config.name = mtd->name;
> +	config.owner = THIS_MODULE;
> +	config.reg_read = mtd_nvmem_reg_read;
> +	config.size = mtd->size;
> +	config.word_size = 1;
> +	config.stride = 1;
> +	config.read_only = true;
> +	config.root_only = true;
> +	config.no_of_node = true;
> +	config.priv = mtd;
> +
> +	mtd->nvmem = nvmem_register(&config);
> +	if (IS_ERR(mtd->nvmem)) {
> +		/* Just ignore if there is no NVMEM support in the kernel */
> +		if (PTR_ERR(mtd->nvmem) == -ENOSYS) {
> +			mtd->nvmem = NULL;
> +		} else {
> +			dev_err(&mtd->dev, "Failed to register NVMEM device\n");
> +			return PTR_ERR(mtd->nvmem);
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>  static struct dentry *dfs_dir_mtd;
>  
>  /**
> @@ -570,6 +615,11 @@ int add_mtd_device(struct mtd_info *mtd)
>  	if (error)
>  		goto fail_added;
>  
> +	/* Add the nvmem provider */
> +	error = mtd_nvmem_add(mtd);
> +	if (error)
> +		goto fail_nvmem_add;
> +
>  	if (!IS_ERR_OR_NULL(dfs_dir_mtd)) {
>  		mtd->dbg.dfs_dir = debugfs_create_dir(dev_name(&mtd->dev), dfs_dir_mtd);
>  		if (IS_ERR_OR_NULL(mtd->dbg.dfs_dir)) {
> @@ -595,6 +645,8 @@ int add_mtd_device(struct mtd_info *mtd)
>  	__module_get(THIS_MODULE);
>  	return 0;
>  
> +fail_nvmem_add:
> +	device_unregister(&mtd->dev);
>  fail_added:
>  	of_node_put(mtd_get_of_node(mtd));
>  	idr_remove(&mtd_idr, i);
> @@ -637,6 +689,10 @@ int del_mtd_device(struct mtd_info *mtd)
>  		       mtd->index, mtd->name, mtd->usecount);
>  		ret = -EBUSY;
>  	} else {
> +		/* Try to remove the NVMEM provider */
> +		if (mtd->nvmem)
> +			nvmem_unregister(mtd->nvmem);
> +
>  		device_unregister(&mtd->dev);
>  
>  		idr_remove(&mtd_idr, mtd->index);
> diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
> index cd0be91bdefa..545070c2ee64 100644
> --- a/include/linux/mtd/mtd.h
> +++ b/include/linux/mtd/mtd.h
> @@ -25,6 +25,7 @@
>  #include <linux/notifier.h>
>  #include <linux/device.h>
>  #include <linux/of.h>
> +#include <linux/nvmem-provider.h>
>  
>  #include <mtd/mtd-abi.h>
>  
> @@ -341,6 +342,7 @@ struct mtd_info {
>  	struct device dev;
>  	int usecount;
>  	struct mtd_debug_info dbg;
> +	struct nvmem_device *nvmem;
>  };
>  
>  int mtd_ooblayout_ecc(struct mtd_info *mtd, int section,

^ permalink raw reply

* Re: [v3, PATCH 1/2] net:stmmac: dwmac-mediatek: add support for mt2712
From: biao huang @ 2018-11-19  2:38 UTC (permalink / raw)
  To: Sean Wang
  Cc: davem@davemloft.net, robh+dt@kernel.org, mark.rutland@arm.com,
	devicetree@vger.kernel.org,
	Nelson Chang (張家祥), andrew@lunn.ch,
	netdev@vger.kernel.org, Liguo Zhang (张立国),
	linux-kernel@vger.kernel.org, Matthias Brugger,
	joabreu@synopsys.com, linux-mediatek@lists.infradead.org,
	Honghui Zhang (张洪辉)
In-Reply-To: <CAGp9Lzq_4w656HpUYMNDp64e=0mKDGvs46d4fq61wp1GAyzmvA@mail.gmail.com>

Hi Sean,
	Thanks for your comments.
	I'll send a more general version soon.

On Sat, 2018-11-17 at 09:03 +0800, Sean Wang wrote:
> wi
> On Fri, Nov 16, 2018 at 1:19 AM Biao Huang <biao.huang@mediatek.com> wrote:
> >
> > Add Ethernet support for MediaTek SoCs from the mt2712 family
> >
> > Change-Id: Id3c535627088227793bd36405994edf2dc765e6a
> 
> Drop change-Id
> 
OK, I forgot it.
> > Signed-off-by: Biao Huang <biao.huang@mediatek.com>
> > ---
> >  drivers/net/ethernet/stmicro/stmmac/Kconfig        |    8 +
> >  drivers/net/ethernet/stmicro/stmmac/Makefile       |    1 +
> >  .../net/ethernet/stmicro/stmmac/dwmac-mediatek.c   |  383 ++++++++++++++++++++
> >  3 files changed, 392 insertions(+)
> >  create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
> >
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
> > index edf2036..28a7a28 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
> > +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
> > @@ -75,6 +75,14 @@ config DWMAC_LPC18XX
> >         ---help---
> >           Support for NXP LPC18xx/43xx DWMAC Ethernet.
> >
> > +config DWMAC_MEDIATEK
> > +       tristate "MediaTek MT27xx GMAC support"
> > +       depends on OF && (ARCH_MEDIATEK || COMPILE_TEST)
> > +       help
> > +         Support for MediaTek GMAC Ethernet controller.
> > +
> > +         This selects the MT2712 SoC support for the stmmac driver.
> > +
> >  config DWMAC_MESON
> >         tristate "Amlogic Meson dwmac support"
> >         default ARCH_MESON
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
> > index 99967a8..bf09701 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/Makefile
> > +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
> > @@ -13,6 +13,7 @@ obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o
> >  obj-$(CONFIG_DWMAC_ANARION)    += dwmac-anarion.o
> >  obj-$(CONFIG_DWMAC_IPQ806X)    += dwmac-ipq806x.o
> >  obj-$(CONFIG_DWMAC_LPC18XX)    += dwmac-lpc18xx.o
> > +obj-$(CONFIG_DWMAC_MEDIATEK)   += dwmac-mediatek.o
> >  obj-$(CONFIG_DWMAC_MESON)      += dwmac-meson.o dwmac-meson8b.o
> >  obj-$(CONFIG_DWMAC_OXNAS)      += dwmac-oxnas.o
> >  obj-$(CONFIG_DWMAC_ROCKCHIP)   += dwmac-rk.o
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
> > new file mode 100644
> > index 0000000..a80b3e0
> > --- /dev/null
> > +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
> > @@ -0,0 +1,383 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2018 MediaTek Inc.
> > + */
> > +#include <linux/io.h>
> > +#include <linux/mfd/syscon.h>
> > +#include <linux/of.h>
> > +#include <linux/of_device.h>
> > +#include <linux/of_net.h>
> > +#include <linux/regmap.h>
> > +#include <linux/stmmac.h>
> > +
> > +#include "stmmac.h"
> > +#include "stmmac_platform.h"
> > +
> > +/* Peri Configuration register */
> > +#define PERI_ETH_PHY_INTF_SEL  0x418
> > +#define PHY_INTF_MII_GMII      0
> > +#define PHY_INTF_RGMII         1
> > +#define PHY_INTF_RMII          4
> > +#define RMII_CLK_SRC_RXC       BIT(4)
> > +#define RMII_CLK_SRC_INTERNAL  BIT(5)
> > +
> > +#define PERI_ETH_PHY_DLY       0x428
> > +#define PHY_DLY_GTXC_INV       BIT(6)
> > +#define PHY_DLY_GTXC_ENABLE    BIT(5)
> > +#define PHY_DLY_GTXC_STAGES    GENMASK(4, 0)
> > +#define PHY_DLY_TXC_INV                BIT(20)
> > +#define PHY_DLY_TXC_ENABLE     BIT(19)
> > +#define PHY_DLY_TXC_STAGES     GENMASK(18, 14)
> > +#define PHY_DLY_TXC_SHIFT      14
> > +#define PHY_DLY_RXC_INV                BIT(13)
> > +#define PHY_DLY_RXC_ENABLE     BIT(12)
> > +#define PHY_DLY_RXC_STAGES     GENMASK(11, 7)
> > +#define PHY_DLY_RXC_SHIFT      7
> > +
> > +#define PERI_ETH_DLY_FINE      0x800
> > +#define ETH_RMII_DLY_TX_INV    BIT(2)
> > +#define ETH_FINE_DLY_GTXC      BIT(1)
> > +#define ETH_FINE_DLY_RXC       BIT(0)
> > +
> > +enum dwmac_clks_map {
> > +       DWMAC_CLK_AXI_DRAM,
> > +       DWMAC_CLK_APB_REG,
> > +       DWMAC_CLK_MAC_EXT,
> > +       DWMAC_CLK_MAC_PARENT,
> > +       DWMAC_CLK_PTP_REF,
> > +       DWMAC_CLK_PTP_PARENT,
> > +       DWMAC_CLK_PTP_TOP,
> > +       DWMAC_CLK_MAX
> > +};
> > +
> > +struct mac_delay_struct {
> > +       u32 tx_delay;
> > +       u32 rx_delay;
> > +       u32 tx_inv;
> > +       u32 rx_inv;
> > +};
> > +
> > +struct mediatek_dwmac_plat_data {
> > +       struct device *dev;
> > +       struct regmap *peri_regmap;
> > +       struct clk *clks[DWMAC_CLK_MAX];
> > +       struct device_node *np;
> > +       int phy_mode;
> > +       struct mac_delay_struct mac_delay;
> > +       const struct mediatek_dwmac_variant *variant;
> > +       int fine_tune;
> > +       int rmii_rxc;
> > +};
> > +
> > +struct mediatek_dwmac_variant {
> > +       int (*dwmac_config_dt)(struct mediatek_dwmac_plat_data *plat);
> > +       int (*dwmac_enable_clks)(struct mediatek_dwmac_plat_data *plat);
> > +       void (*dwmac_disable_clks)(struct mediatek_dwmac_plat_data *plat);
> 
> Each variant usually can reuse the same config_dt, enable/disable_clks function.
> 
ok, I'll try to make it more general.
> > +       u32 rx_delay_max;
> > +       u32 tx_delay_max;
> > +};
> > +
> > +static const char * const mediatek_dwmac_clks_name[] = {
> > +       "axi", "apb", "mac_ext", "mac_parent", "ptp_ref", "ptp_parent", "ptp_top"
> > +};
> > +
> > +static int mt2712_set_interface(struct mediatek_dwmac_plat_data *plat)
> 
> Kconfig indicates it's a mt27xx driver. so it's good if there is a
> more generic prefix.
> 
in this version, mt2712_set_interface is only for mt2712.
I'll try a more general solution.
> > +{
> > +       int rmii_rxc = plat->rmii_rxc ? RMII_CLK_SRC_RXC : 0;
> > +       u32 intf_val = 0;
> > +
> > +       /* select phy interface in top control domain */
> > +       switch (plat->phy_mode) {
> > +       case PHY_INTERFACE_MODE_MII:
> > +               intf_val |= PHY_INTF_MII_GMII;
> > +               break;
> > +       case PHY_INTERFACE_MODE_RMII:
> > +               intf_val |= PHY_INTF_RMII;
> > +               intf_val |= rmii_rxc;
> > +               break;
> > +       case PHY_INTERFACE_MODE_RGMII:
> > +       case PHY_INTERFACE_MODE_RGMII_TXID:
> > +       case PHY_INTERFACE_MODE_RGMII_RXID:
> > +       case PHY_INTERFACE_MODE_RGMII_ID:
> > +               intf_val |= PHY_INTF_RGMII;
> > +               break;
> > +       default:
> > +               dev_err(plat->dev, "phy interface not supported\n");
> > +               return -EINVAL;
> > +       }
> > +
> > +       regmap_write(plat->peri_regmap, PERI_ETH_PHY_INTF_SEL, intf_val);
> > +
> > +       return 0;
> > +}
> > +
> > +static int mt2712_set_delay(struct mediatek_dwmac_plat_data *plat)
> > +{
> > +       struct mac_delay_struct *mac_delay = &plat->mac_delay;
> > +       u32 delay_val = 0;
> > +       u32 fine_val = 0;
> > +
> > +       switch (plat->phy_mode) {
> > +       case PHY_INTERFACE_MODE_MII:
> > +               delay_val |= mac_delay->tx_delay ? PHY_DLY_TXC_ENABLE : 0;
> > +               delay_val |= (mac_delay->tx_delay << PHY_DLY_TXC_SHIFT) &
> > +                            PHY_DLY_TXC_STAGES;
> > +               delay_val |= mac_delay->tx_inv ? PHY_DLY_TXC_INV : 0;
> > +               delay_val |= mac_delay->rx_delay ? PHY_DLY_RXC_ENABLE : 0;
> > +               delay_val |= (mac_delay->rx_delay << PHY_DLY_RXC_SHIFT) &
> > +                            PHY_DLY_RXC_STAGES;
> > +               delay_val |= mac_delay->rx_inv ? PHY_DLY_RXC_INV : 0;
> > +               break;
> > +       case PHY_INTERFACE_MODE_RMII:
> > +               if (plat->rmii_rxc) {
> > +                       delay_val |= mac_delay->rx_delay ?
> > +                                    PHY_DLY_RXC_ENABLE : 0;
> > +                       delay_val |= (mac_delay->rx_delay <<
> > +                                     PHY_DLY_RXC_SHIFT) & PHY_DLY_RXC_STAGES;
> > +                       delay_val |= mac_delay->rx_inv ? PHY_DLY_RXC_INV : 0;
> > +                       fine_val |= mac_delay->tx_inv ?
> > +                                    ETH_RMII_DLY_TX_INV : 0;
> > +               } else {
> > +                       delay_val |= mac_delay->rx_delay ?
> > +                                    PHY_DLY_TXC_ENABLE : 0;
> > +                       delay_val |= (mac_delay->rx_delay <<
> > +                                    PHY_DLY_TXC_SHIFT) & PHY_DLY_TXC_STAGES;
> > +                       delay_val |= mac_delay->rx_inv ? PHY_DLY_TXC_INV : 0;
> > +                       fine_val |= mac_delay->tx_inv ?
> > +                                    ETH_RMII_DLY_TX_INV : 0;
> > +               }
> > +               break;
> > +       case PHY_INTERFACE_MODE_RGMII:
> > +               fine_val = plat->fine_tune ?
> > +                           (ETH_FINE_DLY_GTXC | ETH_FINE_DLY_RXC) : 0;
> > +               delay_val |= mac_delay->tx_delay ? PHY_DLY_GTXC_ENABLE : 0;
> > +               delay_val |= mac_delay->tx_delay & PHY_DLY_GTXC_STAGES;
> > +               delay_val |= mac_delay->tx_inv ? PHY_DLY_GTXC_INV : 0;
> > +               delay_val |= mac_delay->rx_delay ? PHY_DLY_RXC_ENABLE : 0;
> > +               delay_val |= (mac_delay->rx_delay << PHY_DLY_RXC_SHIFT) &
> > +                            PHY_DLY_RXC_STAGES;
> > +               delay_val |= mac_delay->rx_inv ? PHY_DLY_RXC_INV : 0;
> > +               break;
> > +       case PHY_INTERFACE_MODE_RGMII_TXID:
> > +               fine_val = plat->fine_tune ? ETH_FINE_DLY_RXC : 0;
> > +               delay_val |= mac_delay->rx_delay ? PHY_DLY_RXC_ENABLE : 0;
> > +               delay_val |= (mac_delay->rx_delay << PHY_DLY_RXC_SHIFT) &
> > +                            PHY_DLY_RXC_STAGES;
> > +               delay_val |= mac_delay->rx_inv ? PHY_DLY_RXC_INV : 0;
> > +               break;
> > +       case PHY_INTERFACE_MODE_RGMII_RXID:
> > +               fine_val = plat->fine_tune ? ETH_FINE_DLY_GTXC : 0;
> > +               delay_val |= mac_delay->tx_delay ? PHY_DLY_GTXC_ENABLE : 0;
> > +               delay_val |= mac_delay->tx_delay & PHY_DLY_GTXC_STAGES;
> > +               delay_val |= mac_delay->tx_inv ? PHY_DLY_GTXC_INV : 0;
> > +               break;
> > +       case PHY_INTERFACE_MODE_RGMII_ID:
> > +               break;
> > +       default:
> > +               dev_err(plat->dev, "phy interface not supported\n");
> > +               return -EINVAL;
> > +       }
> > +       regmap_write(plat->peri_regmap, PERI_ETH_PHY_DLY, delay_val);
> > +       regmap_write(plat->peri_regmap, PERI_ETH_DLY_FINE, fine_val);
> > +
> > +       return 0;
> > +}
> > +
> > +static int mt2712_get_clks(struct mediatek_dwmac_plat_data *plat)
> > +{
> > +       int i;
> > +
> > +       for (i = 0; i < ARRAY_SIZE(plat->clks); i++) {
> > +               plat->clks[i] = devm_clk_get(plat->dev,
> > +                                            mediatek_dwmac_clks_name[i]);
> > +               if (IS_ERR(plat->clks[i]))
> > +                       return PTR_ERR(plat->clks[i]);
> > +       }
> 
> can we use devm_clk_bulk_get?
> 
yes, will change to devm_clk_bulk_xx API in next version.
> > +
> > +       return 0;
> > +}
> > +
> > +static int mt2712_enable_clks(struct mediatek_dwmac_plat_data *plat)
> > +{
> > +       int clk, ret;
> > +
> > +       for (clk = 0; clk < DWMAC_CLK_MAX ; clk++) {
> > +               ret = clk_prepare_enable(plat->clks[clk]);
> > +               if (ret)
> > +                       goto err_disable_clks;
> > +       }
> 
> can we use clk_bulk_enable?
> 
yes
> > +
> > +       ret = clk_set_parent(plat->clks[DWMAC_CLK_MAC_EXT], plat->clks[DWMAC_CLK_MAC_PARENT]);
> > +       if (ret)
> > +               goto err_disable_clks;
> > +
> > +       ret = clk_set_parent(plat->clks[DWMAC_CLK_PTP_REF], plat->clks[DWMAC_CLK_PTP_PARENT]);
> > +       if (ret)
> > +               goto err_disable_clks;
> > +
> 
> I guess clk_set_parent can be trimmed if we involve assigned-clocks,
> assigned-clock-parents, assigned-clock-rates in the dts
> 
yes.
> > +       return 0;
> > +
> > +err_disable_clks:
> > +       while (--clk >= 0)
> > +               clk_disable_unprepare(plat->clks[clk]);
> > +
> 
> clk_bulk_enable would take care about the failed case
> 
Got it.
> > +       return ret;
> > +}
> > +
> > +static void mt2712_disable_clks(struct mediatek_dwmac_plat_data *plat)
> > +{
> > +       int clk;
> > +
> > +       for (clk = DWMAC_CLK_MAX - 1; clk >= 0; clk--)
> > +               clk_disable_unprepare(plat->clks[clk]);
> > +}
> 
> can we use clk_bulk_disable ?
> 
yes
> > +
> > +static int mt2712_config_dt(struct mediatek_dwmac_plat_data *plat)
> > +{
> > +       u32 tx_delay, rx_delay;
> > +
> > +       plat->peri_regmap = syscon_regmap_lookup_by_compatible("mediatek,mt2712-pericfg");
> 
> the driver would be not generic enough if we assigned a specific
> string into here.
> how about apply syscon_regmap_lookup_by_phandle in here?
> 
ok, I'll try it.
> > +       if (IS_ERR(plat->peri_regmap)) {
> > +               dev_err(plat->dev, "Failed to get pericfg syscon\n");
> > +               return PTR_ERR(plat->peri_regmap);
> > +       }
> > +
> > +       if (!of_property_read_u32(plat->np, "tx-delay", &tx_delay)) {
> > +               if (tx_delay < plat->variant->tx_delay_max) {
> > +                       plat->mac_delay.tx_delay = tx_delay;
> > +               } else {
> > +                       dev_err(plat->dev, "Invalid TX clock delay: %d\n", tx_delay);
> > +                       return -EINVAL;
> > +               }
> > +       }
> > +
> > +       if (!of_property_read_u32(plat->np, "rx-delay", &rx_delay)) {
> > +               if (rx_delay < plat->variant->rx_delay_max) {
> > +                       plat->mac_delay.rx_delay = rx_delay;
> > +               } else {
> > +                       dev_err(plat->dev, "Invalid RX clock delay: %d\n", rx_delay);
> > +                       return -EINVAL;
> > +               }
> > +       }
> > +
> > +       plat->mac_delay.tx_inv = of_property_read_bool(plat->np, "txc-inverse");
> > +
> can we drop the empty line?
> 
yes
> > +       plat->mac_delay.rx_inv = of_property_read_bool(plat->np, "rxc-inverse");
> > +
> can we drop the empty line?
> 
yes
> > +       plat->fine_tune = of_property_read_bool(plat->np, "fine-tune");
> > +
> can we drop the empty line?
> 
yes
> > +       plat->rmii_rxc = of_property_read_bool(plat->np, "rmii-rxc");
> > +
> > +       mt2712_set_interface(plat);
> > +
> > +       mt2712_set_delay(plat);
> > +
> > +       return mt2712_get_clks(plat);
> > +}
> > +
> > +static const struct mediatek_dwmac_variant mt2712_gmac_variant = {
> > +               .dwmac_config_dt = mt2712_config_dt,
> > +               .dwmac_enable_clks = mt2712_enable_clks,
> > +               .dwmac_disable_clks = mt2712_disable_clks,
> > +               .rx_delay_max = 32,
> > +               .tx_delay_max = 32,
> > +};
> 
> I thought we add the variant structure when the SoC variant is really in.
> 
ok.
> > +
> > +static int mediatek_dwmac_config_dt(struct mediatek_dwmac_plat_data *plat)
> > +{
> > +       const struct mediatek_dwmac_variant *variant = plat->variant;
> > +
> > +       /* Set the DMA mask, 4GB mode enabled */
> > +       dma_set_mask_and_coherent(plat->dev, DMA_BIT_MASK(33));
> > +
> > +       return variant->dwmac_config_dt(plat);
> > +}
> > +
> > +static int mediatek_dwmac_init(struct platform_device *pdev, void *priv)
> > +{
> > +       struct mediatek_dwmac_plat_data *plat = priv;
> > +       const struct mediatek_dwmac_variant *variant = plat->variant;
> > +
> > +       return variant->dwmac_enable_clks(plat);
> > +}
> > +
> > +static void mediatek_dwmac_exit(struct platform_device *pdev, void *priv)
> > +{
> > +       struct mediatek_dwmac_plat_data *plat = priv;
> > +       const struct mediatek_dwmac_variant *variant = plat->variant;
> > +
> > +       variant->dwmac_disable_clks(plat);
> > +}
> > +
> > +static int mediatek_dwmac_probe(struct platform_device *pdev)
> > +{
> > +       int ret = 0;
> > +       struct plat_stmmacenet_data *plat_dat;
> > +       struct stmmac_resources stmmac_res;
> > +       struct mediatek_dwmac_plat_data *priv_plat;
> 
> sorting these declarations into reverse Xmas tree seems to be good
> 
good tips.
> > +
> > +       priv_plat = devm_kzalloc(&pdev->dev, sizeof(*priv_plat), GFP_KERNEL);
> > +       if (!priv_plat)
> > +               return -ENOMEM;
> > +
> > +       priv_plat->variant = of_device_get_match_data(&pdev->dev);
> > +       if (!priv_plat->variant) {
> > +               dev_err(&pdev->dev, "Missing dwmac-mediatek variant\n");
> > +               return -EINVAL;
> > +       }
> > +
> > +       priv_plat->dev = &pdev->dev;
> > +       priv_plat->np = pdev->dev.of_node;
> > +       priv_plat->phy_mode = of_get_phy_mode(priv_plat->np);
> > +
> > +       ret = mediatek_dwmac_config_dt(priv_plat);
> > +       if (ret)
> > +               return ret;
> > +
> > +       ret = stmmac_get_platform_resources(pdev, &stmmac_res);
> > +       if (ret)
> > +               return ret;
> > +
> > +       plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
> > +       if (IS_ERR(plat_dat))
> > +               return PTR_ERR(plat_dat);
> > +
> > +       plat_dat->interface = priv_plat->phy_mode;
> > +       /* clk_csr_i = 250-300MHz & MDC = clk_csr_i/124 */
> > +       plat_dat->clk_csr = 5;
> > +       plat_dat->has_gmac4 = 1;
> > +       plat_dat->has_gmac = 0;
> > +       plat_dat->pmt = 0;
> > +       plat_dat->maxmtu = ETH_DATA_LEN;
> > +       plat_dat->bsp_priv = priv_plat;
> > +       plat_dat->init = mediatek_dwmac_init;
> > +       plat_dat->exit = mediatek_dwmac_exit;
> > +       mediatek_dwmac_init(pdev, priv_plat);
> > +
> > +       ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
> > +       if (ret) {
> > +               stmmac_remove_config_dt(pdev, plat_dat);
> > +               return ret;
> > +       }
> > +
> > +       return 0;
> > +}
> > +
> > +static const struct of_device_id mediatek_dwmac_match[] = {
> > +       { .compatible = "mediatek,mt2712-gmac",
> > +         .data = &mt2712_gmac_variant },
> > +       { }
> > +};
> > +
> > +MODULE_DEVICE_TABLE(of, mediatek_dwmac_match);
> > +
> > +static struct platform_driver mediatek_dwmac_driver = {
> > +       .probe  = mediatek_dwmac_probe,
> > +       .remove = stmmac_pltfr_remove,
> > +       .driver = {
> > +               .name           = "dwmac-mediatek",
> > +               .pm             = &stmmac_pltfr_pm_ops,
> > +               .of_match_table = mediatek_dwmac_match,
> > +       },
> > +};
> > +module_platform_driver(mediatek_dwmac_driver);
> > --
> > 1.7.9.5
> >
> >
> > _______________________________________________
> > Linux-mediatek mailing list
> > Linux-mediatek@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply

* Re: [v3, PATCH 2/2] dt-binding: mediatek-dwmac: add binding document for MediaTek MT2712 DWMAC
From: biao huang @ 2018-11-19  2:51 UTC (permalink / raw)
  To: Rob Herring
  Cc: davem@davemloft.net, Honghui Zhang (张洪辉),
	YT Shen (沈岳霆),
	Liguo Zhang (张立国), mark.rutland@arm.com,
	Nelson Chang (??家祥), matthias.bgg@gmail.com,
	netdev@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <20181117145611.GA26013@bogus>

Hi Rob,
	Thanks for your comments.
On Sat, 2018-11-17 at 22:56 +0800, Rob Herring wrote:
> On Fri, Nov 16, 2018 at 05:18:46PM +0800, Biao Huang wrote:
> > The commit adds the device tree binding documentation for the MediaTek DWMAC
> > found on MediaTek MT2712.
> > 
> > Change-Id: I3728666bf65927164bd82fa8dddb90df8270bd44
> > Signed-off-by: Biao Huang <biao.huang@mediatek.com>
> > ---
> >  .../devicetree/bindings/net/mediatek-dwmac.txt     |   77 ++++++++++++++++++++
> >  1 file changed, 77 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/net/mediatek-dwmac.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/net/mediatek-dwmac.txt b/Documentation/devicetree/bindings/net/mediatek-dwmac.txt
> > new file mode 100644
> > index 0000000..7fd56e0
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/net/mediatek-dwmac.txt
> > @@ -0,0 +1,77 @@
> > +MediaTek DWMAC glue layer controller
> > +
> > +This file documents platform glue layer for stmmac.
> > +Please see stmmac.txt for the other unchanged properties.
> > +
> > +The device node has following properties.
> > +
> > +Required properties:
> > +- compatible:  Should be "mediatek,mt2712-gmac" for MT2712 SoC
> > +- reg:  Address and length of the register set for the device
> > +- interrupts:  Should contain the MAC interrupts
> 
> How many?
> 
the common stmmac driver will parse interrupt-name "macirq",
so even only one interrupt is used in mediatek dwmac design,
the interrupt-names is still remained in device tree.
> > +- interrupt-names: Should contain a list of interrupt names corresponding to
> > +	the interrupts in the interrupts property, if available.
> > +	Should be "macirq" for the main MAC IRQ
> > +- clocks: Must contain a phandle for each entry in clock-names.
> > +- clock-names: The name of the clock listed in the clocks property. These are
> > +	"axi", "apb", "mac_ext", "mac_parent", "ptp_ref", "ptp_parent", "ptp_top"
> > +	for MT2712 SoC
> 
> Clocks should represent the physical clocks connected to a block. Parent 
> clocks are not in that category.
> 
Got it. assigned-clocks/assigned-clocks-parents properties can handle
it.
> > +- mac-address: See ethernet.txt in the same directory
> > +- phy-mode: See ethernet.txt in the same directory
> > +
> > +Optional properties:
> > +- tx-delay: TX clock delay macro value. Range is 0~31. Default is 0.
> > +	It should be defined for rgmii/rgmii-rxid/mii interface.
> > +- rx-delay: RX clock delay macro value. Range is 0~31. Default is 0.
> > +	It should be defined for rgmii/rgmii-txid/mii/rmii interface.
> > +- fine-tune: This property will select coarse-tune delay or fine delay
> > +	for rgmii interface.
> > +	If fine-tune delay is enabled, tx-delay/rx-delay is 170+/-50ps
> > +	per stage.
> > +	Else coarse-tune delay is enabled, tx-delay/rx-delay is 0.55+/-0.2ns
> > +	per stage.
> > +	This property do not apply to non-rgmii PHYs.
> > +	Only coarse-tune delay is supported for mii/rmii PHYs.
> 
> Perhaps the delays should be in ps and the driver can figure out 
> fine-tune or not based on the value.
> 
the delay time in mediatek dwmac design is not so accurate, 
the current mt2712 and the following ICs will not use the same delay
design, but will use stages to indicate different delay time.
so, maybe "mediatek,tx-delay" represent the delay stage is a good
choice.
> > +- rmii-rxc: Reference clock of rmii is from external PHYs,
> > +	and it can be connected to TXC or RXC pin on MT2712 SoC.
> > +	If ref_clk <--> TXC, disable it.
> > +	Else ref_clk <--> RXC, enable it.
> > +- txc-inverse: Inverse tx clock for mii/rgmii.
> > +	Inverse tx clock inside MAC relative to reference clock for rmii,
> > +	and it rarely happen.
> > +- rxc-inverse: Inverse rx clock for mii/rgmii interfaces.
> > +	Inverse reference clock for rmii.
> 
> These should all have vendor prefixes. 'snps' if these are all standard 
> GMAC controls or 'mediatek' if Mediatek specific.
> 
Got it, will be modified in next version.
> > +
> > +Example:
> > +	eth: ethernet@1101c000 {
> > +		compatible = "mediatek,mt2712-gmac";
> > +		reg = <0 0x1101c000 0 0x1300>;
> > +		interrupts = <GIC_SPI 237 IRQ_TYPE_LEVEL_LOW>;
> > +		interrupt-names = "macirq";
> > +		phy-mode ="rgmii-id";
> > +		mac-address = [00 55 7b b5 7d f7];
> > +		clock-names = "axi",
> > +			      "apb",
> > +			      "mac_ext",
> > +			      "mac_parent",
> > +			      "ptp_ref",
> > +			      "ptp_parent",
> > +			      "ptp_top";
> > +		clocks = <&pericfg CLK_PERI_GMAC>,
> > +			 <&pericfg CLK_PERI_GMAC_PCLK>,
> > +			 <&topckgen CLK_TOP_ETHER_125M_SEL>,
> > +			 <&topckgen CLK_TOP_ETHERPLL_125M>,
> > +			 <&topckgen CLK_TOP_ETHER_50M_SEL>,
> > +			 <&topckgen CLK_TOP_APLL1_D3>,
> > +			 <&topckgen CLK_TOP_APLL1>;
> > +		snps,txpbl = <32>;
> > +		snps,rxpbl = <32>;
> > +		snps,reset-gpio = <&pio 87 GPIO_ACTIVE_LOW>;
> > +		snps,reset-active-low;
> > +		tx-delay = <9>;
> > +		rx-delay = <9>;
> > +		fine-tune;
> > +		rmii-rxc;
> > +		txc-inverse;
> > +		rxc-inverse;
> > +	};
> > -- 
> > 1.7.9.5
> > 

^ permalink raw reply

* [PATCH net-next] mlxsw: spectrum: Expose discard counters via ethtool
From: Ido Schimmel @ 2018-11-18 16:43 UTC (permalink / raw)
  To: netdev@vger.kernel.org
  Cc: davem@davemloft.net, Jiri Pirko, Shalom Toledo, mlxsw,
	Ido Schimmel

From: Shalom Toledo <shalomt@mellanox.com>

Expose packets discard counters via ethtool to help with debugging.

Signed-off-by: Shalom Toledo <shalomt@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/reg.h     | 142 ++++++++++++++++
 .../net/ethernet/mellanox/mlxsw/spectrum.c    | 155 ++++++++++++++++++
 2 files changed, 297 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
index d3babcc49fd2..be2ffbd19e3a 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
@@ -4235,8 +4235,11 @@ MLXSW_ITEM32(reg, ppcnt, pnat, 0x00, 14, 2);
 
 enum mlxsw_reg_ppcnt_grp {
 	MLXSW_REG_PPCNT_IEEE_8023_CNT = 0x0,
+	MLXSW_REG_PPCNT_RFC_2863_CNT = 0x1,
 	MLXSW_REG_PPCNT_RFC_2819_CNT = 0x2,
+	MLXSW_REG_PPCNT_RFC_3635_CNT = 0x3,
 	MLXSW_REG_PPCNT_EXT_CNT = 0x5,
+	MLXSW_REG_PPCNT_DISCARD_CNT = 0x6,
 	MLXSW_REG_PPCNT_PRIO_CNT = 0x10,
 	MLXSW_REG_PPCNT_TC_CNT = 0x11,
 	MLXSW_REG_PPCNT_TC_CONG_TC = 0x13,
@@ -4251,6 +4254,7 @@ enum mlxsw_reg_ppcnt_grp {
  * 0x2: RFC 2819 Counters
  * 0x3: RFC 3635 Counters
  * 0x5: Ethernet Extended Counters
+ * 0x6: Ethernet Discard Counters
  * 0x8: Link Level Retransmission Counters
  * 0x10: Per Priority Counters
  * 0x11: Per Traffic Class Counters
@@ -4394,8 +4398,46 @@ MLXSW_ITEM64(reg, ppcnt, a_pause_mac_ctrl_frames_received,
 MLXSW_ITEM64(reg, ppcnt, a_pause_mac_ctrl_frames_transmitted,
 	     MLXSW_REG_PPCNT_COUNTERS_OFFSET + 0x90, 0, 64);
 
+/* Ethernet RFC 2863 Counter Group */
+
+/* reg_ppcnt_if_in_discards
+ * Access: RO
+ */
+MLXSW_ITEM64(reg, ppcnt, if_in_discards,
+	     MLXSW_REG_PPCNT_COUNTERS_OFFSET + 0x10, 0, 64);
+
+/* reg_ppcnt_if_out_discards
+ * Access: RO
+ */
+MLXSW_ITEM64(reg, ppcnt, if_out_discards,
+	     MLXSW_REG_PPCNT_COUNTERS_OFFSET + 0x38, 0, 64);
+
+/* reg_ppcnt_if_out_errors
+ * Access: RO
+ */
+MLXSW_ITEM64(reg, ppcnt, if_out_errors,
+	     MLXSW_REG_PPCNT_COUNTERS_OFFSET + 0x40, 0, 64);
+
 /* Ethernet RFC 2819 Counter Group */
 
+/* reg_ppcnt_ether_stats_undersize_pkts
+ * Access: RO
+ */
+MLXSW_ITEM64(reg, ppcnt, ether_stats_undersize_pkts,
+	     MLXSW_REG_PPCNT_COUNTERS_OFFSET + 0x30, 0, 64);
+
+/* reg_ppcnt_ether_stats_oversize_pkts
+ * Access: RO
+ */
+MLXSW_ITEM64(reg, ppcnt, ether_stats_oversize_pkts,
+	     MLXSW_REG_PPCNT_COUNTERS_OFFSET + 0x38, 0, 64);
+
+/* reg_ppcnt_ether_stats_fragments
+ * Access: RO
+ */
+MLXSW_ITEM64(reg, ppcnt, ether_stats_fragments,
+	     MLXSW_REG_PPCNT_COUNTERS_OFFSET + 0x40, 0, 64);
+
 /* reg_ppcnt_ether_stats_pkts64octets
  * Access: RO
  */
@@ -4456,6 +4498,32 @@ MLXSW_ITEM64(reg, ppcnt, ether_stats_pkts4096to8191octets,
 MLXSW_ITEM64(reg, ppcnt, ether_stats_pkts8192to10239octets,
 	     MLXSW_REG_PPCNT_COUNTERS_OFFSET + 0xA0, 0, 64);
 
+/* Ethernet RFC 3635 Counter Group */
+
+/* reg_ppcnt_dot3stats_fcs_errors
+ * Access: RO
+ */
+MLXSW_ITEM64(reg, ppcnt, dot3stats_fcs_errors,
+	     MLXSW_REG_PPCNT_COUNTERS_OFFSET + 0x08, 0, 64);
+
+/* reg_ppcnt_dot3stats_symbol_errors
+ * Access: RO
+ */
+MLXSW_ITEM64(reg, ppcnt, dot3stats_symbol_errors,
+	     MLXSW_REG_PPCNT_COUNTERS_OFFSET + 0x60, 0, 64);
+
+/* reg_ppcnt_dot3control_in_unknown_opcodes
+ * Access: RO
+ */
+MLXSW_ITEM64(reg, ppcnt, dot3control_in_unknown_opcodes,
+	     MLXSW_REG_PPCNT_COUNTERS_OFFSET + 0x68, 0, 64);
+
+/* reg_ppcnt_dot3in_pause_frames
+ * Access: RO
+ */
+MLXSW_ITEM64(reg, ppcnt, dot3in_pause_frames,
+	     MLXSW_REG_PPCNT_COUNTERS_OFFSET + 0x70, 0, 64);
+
 /* Ethernet Extended Counter Group Counters */
 
 /* reg_ppcnt_ecn_marked
@@ -4464,6 +4532,80 @@ MLXSW_ITEM64(reg, ppcnt, ether_stats_pkts8192to10239octets,
 MLXSW_ITEM64(reg, ppcnt, ecn_marked,
 	     MLXSW_REG_PPCNT_COUNTERS_OFFSET + 0x08, 0, 64);
 
+/* Ethernet Discard Counter Group Counters */
+
+/* reg_ppcnt_ingress_general
+ * Access: RO
+ */
+MLXSW_ITEM64(reg, ppcnt, ingress_general,
+	     MLXSW_REG_PPCNT_COUNTERS_OFFSET + 0x00, 0, 64);
+
+/* reg_ppcnt_ingress_policy_engine
+ * Access: RO
+ */
+MLXSW_ITEM64(reg, ppcnt, ingress_policy_engine,
+	     MLXSW_REG_PPCNT_COUNTERS_OFFSET + 0x08, 0, 64);
+
+/* reg_ppcnt_ingress_vlan_membership
+ * Access: RO
+ */
+MLXSW_ITEM64(reg, ppcnt, ingress_vlan_membership,
+	     MLXSW_REG_PPCNT_COUNTERS_OFFSET + 0x10, 0, 64);
+
+/* reg_ppcnt_ingress_tag_frame_type
+ * Access: RO
+ */
+MLXSW_ITEM64(reg, ppcnt, ingress_tag_frame_type,
+	     MLXSW_REG_PPCNT_COUNTERS_OFFSET + 0x18, 0, 64);
+
+/* reg_ppcnt_egress_vlan_membership
+ * Access: RO
+ */
+MLXSW_ITEM64(reg, ppcnt, egress_vlan_membership,
+	     MLXSW_REG_PPCNT_COUNTERS_OFFSET + 0x20, 0, 64);
+
+/* reg_ppcnt_loopback_filter
+ * Access: RO
+ */
+MLXSW_ITEM64(reg, ppcnt, loopback_filter,
+	     MLXSW_REG_PPCNT_COUNTERS_OFFSET + 0x28, 0, 64);
+
+/* reg_ppcnt_egress_general
+ * Access: RO
+ */
+MLXSW_ITEM64(reg, ppcnt, egress_general,
+	     MLXSW_REG_PPCNT_COUNTERS_OFFSET + 0x30, 0, 64);
+
+/* reg_ppcnt_egress_hoq
+ * Access: RO
+ */
+MLXSW_ITEM64(reg, ppcnt, egress_hoq,
+	     MLXSW_REG_PPCNT_COUNTERS_OFFSET + 0x40, 0, 64);
+
+/* reg_ppcnt_egress_policy_engine
+ * Access: RO
+ */
+MLXSW_ITEM64(reg, ppcnt, egress_policy_engine,
+	     MLXSW_REG_PPCNT_COUNTERS_OFFSET + 0x50, 0, 64);
+
+/* reg_ppcnt_ingress_tx_link_down
+ * Access: RO
+ */
+MLXSW_ITEM64(reg, ppcnt, ingress_tx_link_down,
+	     MLXSW_REG_PPCNT_COUNTERS_OFFSET + 0x58, 0, 64);
+
+/* reg_ppcnt_egress_stp_filter
+ * Access: RO
+ */
+MLXSW_ITEM64(reg, ppcnt, egress_stp_filter,
+	     MLXSW_REG_PPCNT_COUNTERS_OFFSET + 0x60, 0, 64);
+
+/* reg_ppcnt_egress_sll
+ * Access: RO
+ */
+MLXSW_ITEM64(reg, ppcnt, egress_sll,
+	     MLXSW_REG_PPCNT_COUNTERS_OFFSET + 0x70, 0, 64);
+
 /* Ethernet Per Priority Group Counters */
 
 /* reg_ppcnt_rx_octets
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 9bec940330a4..637e2ef76abe 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -1876,7 +1876,37 @@ static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_stats[] = {
 
 #define MLXSW_SP_PORT_HW_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_stats)
 
+static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_rfc_2863_stats[] = {
+	{
+		.str = "if_in_discards",
+		.getter = mlxsw_reg_ppcnt_if_in_discards_get,
+	},
+	{
+		.str = "if_out_discards",
+		.getter = mlxsw_reg_ppcnt_if_out_discards_get,
+	},
+	{
+		.str = "if_out_errors",
+		.getter = mlxsw_reg_ppcnt_if_out_errors_get,
+	},
+};
+
+#define MLXSW_SP_PORT_HW_RFC_2863_STATS_LEN \
+	ARRAY_SIZE(mlxsw_sp_port_hw_rfc_2863_stats)
+
 static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_rfc_2819_stats[] = {
+	{
+		.str = "ether_stats_undersize_pkts",
+		.getter = mlxsw_reg_ppcnt_ether_stats_undersize_pkts_get,
+	},
+	{
+		.str = "ether_stats_oversize_pkts",
+		.getter = mlxsw_reg_ppcnt_ether_stats_oversize_pkts_get,
+	},
+	{
+		.str = "ether_stats_fragments",
+		.getter = mlxsw_reg_ppcnt_ether_stats_fragments_get,
+	},
 	{
 		.str = "ether_pkts64octets",
 		.getter = mlxsw_reg_ppcnt_ether_stats_pkts64octets_get,
@@ -1922,6 +1952,82 @@ static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_rfc_2819_stats[] = {
 #define MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN \
 	ARRAY_SIZE(mlxsw_sp_port_hw_rfc_2819_stats)
 
+static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_rfc_3635_stats[] = {
+	{
+		.str = "dot3stats_fcs_errors",
+		.getter = mlxsw_reg_ppcnt_dot3stats_fcs_errors_get,
+	},
+	{
+		.str = "dot3stats_symbol_errors",
+		.getter = mlxsw_reg_ppcnt_dot3stats_symbol_errors_get,
+	},
+	{
+		.str = "dot3control_in_unknown_opcodes",
+		.getter = mlxsw_reg_ppcnt_dot3control_in_unknown_opcodes_get,
+	},
+	{
+		.str = "dot3in_pause_frames",
+		.getter = mlxsw_reg_ppcnt_dot3in_pause_frames_get,
+	},
+};
+
+#define MLXSW_SP_PORT_HW_RFC_3635_STATS_LEN \
+	ARRAY_SIZE(mlxsw_sp_port_hw_rfc_3635_stats)
+
+static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_discard_stats[] = {
+	{
+		.str = "discard_ingress_general",
+		.getter = mlxsw_reg_ppcnt_ingress_general_get,
+	},
+	{
+		.str = "discard_ingress_policy_engine",
+		.getter = mlxsw_reg_ppcnt_ingress_policy_engine_get,
+	},
+	{
+		.str = "discard_ingress_vlan_membership",
+		.getter = mlxsw_reg_ppcnt_ingress_vlan_membership_get,
+	},
+	{
+		.str = "discard_ingress_tag_frame_type",
+		.getter = mlxsw_reg_ppcnt_ingress_tag_frame_type_get,
+	},
+	{
+		.str = "discard_egress_vlan_membership",
+		.getter = mlxsw_reg_ppcnt_egress_vlan_membership_get,
+	},
+	{
+		.str = "discard_loopback_filter",
+		.getter = mlxsw_reg_ppcnt_loopback_filter_get,
+	},
+	{
+		.str = "discard_egress_general",
+		.getter = mlxsw_reg_ppcnt_egress_general_get,
+	},
+	{
+		.str = "discard_egress_hoq",
+		.getter = mlxsw_reg_ppcnt_egress_hoq_get,
+	},
+	{
+		.str = "discard_egress_policy_engine",
+		.getter = mlxsw_reg_ppcnt_egress_policy_engine_get,
+	},
+	{
+		.str = "discard_ingress_tx_link_down",
+		.getter = mlxsw_reg_ppcnt_ingress_tx_link_down_get,
+	},
+	{
+		.str = "discard_egress_stp_filter",
+		.getter = mlxsw_reg_ppcnt_egress_stp_filter_get,
+	},
+	{
+		.str = "discard_egress_sll",
+		.getter = mlxsw_reg_ppcnt_egress_sll_get,
+	},
+};
+
+#define MLXSW_SP_PORT_HW_DISCARD_STATS_LEN \
+	ARRAY_SIZE(mlxsw_sp_port_hw_discard_stats)
+
 static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_prio_stats[] = {
 	{
 		.str = "rx_octets_prio",
@@ -1974,7 +2080,10 @@ static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_tc_stats[] = {
 #define MLXSW_SP_PORT_HW_TC_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_tc_stats)
 
 #define MLXSW_SP_PORT_ETHTOOL_STATS_LEN (MLXSW_SP_PORT_HW_STATS_LEN + \
+					 MLXSW_SP_PORT_HW_RFC_2863_STATS_LEN + \
 					 MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN + \
+					 MLXSW_SP_PORT_HW_RFC_3635_STATS_LEN + \
+					 MLXSW_SP_PORT_HW_DISCARD_STATS_LEN + \
 					 (MLXSW_SP_PORT_HW_PRIO_STATS_LEN * \
 					  IEEE_8021QAZ_MAX_TCS) + \
 					 (MLXSW_SP_PORT_HW_TC_STATS_LEN * \
@@ -2015,12 +2124,31 @@ static void mlxsw_sp_port_get_strings(struct net_device *dev,
 			       ETH_GSTRING_LEN);
 			p += ETH_GSTRING_LEN;
 		}
+
+		for (i = 0; i < MLXSW_SP_PORT_HW_RFC_2863_STATS_LEN; i++) {
+			memcpy(p, mlxsw_sp_port_hw_rfc_2863_stats[i].str,
+			       ETH_GSTRING_LEN);
+			p += ETH_GSTRING_LEN;
+		}
+
 		for (i = 0; i < MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN; i++) {
 			memcpy(p, mlxsw_sp_port_hw_rfc_2819_stats[i].str,
 			       ETH_GSTRING_LEN);
 			p += ETH_GSTRING_LEN;
 		}
 
+		for (i = 0; i < MLXSW_SP_PORT_HW_RFC_3635_STATS_LEN; i++) {
+			memcpy(p, mlxsw_sp_port_hw_rfc_3635_stats[i].str,
+			       ETH_GSTRING_LEN);
+			p += ETH_GSTRING_LEN;
+		}
+
+		for (i = 0; i < MLXSW_SP_PORT_HW_DISCARD_STATS_LEN; i++) {
+			memcpy(p, mlxsw_sp_port_hw_discard_stats[i].str,
+			       ETH_GSTRING_LEN);
+			p += ETH_GSTRING_LEN;
+		}
+
 		for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
 			mlxsw_sp_port_get_prio_strings(&p, i);
 
@@ -2063,10 +2191,22 @@ mlxsw_sp_get_hw_stats_by_group(struct mlxsw_sp_port_hw_stats **p_hw_stats,
 		*p_hw_stats = mlxsw_sp_port_hw_stats;
 		*p_len = MLXSW_SP_PORT_HW_STATS_LEN;
 		break;
+	case MLXSW_REG_PPCNT_RFC_2863_CNT:
+		*p_hw_stats = mlxsw_sp_port_hw_rfc_2863_stats;
+		*p_len = MLXSW_SP_PORT_HW_RFC_2863_STATS_LEN;
+		break;
 	case MLXSW_REG_PPCNT_RFC_2819_CNT:
 		*p_hw_stats = mlxsw_sp_port_hw_rfc_2819_stats;
 		*p_len = MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN;
 		break;
+	case MLXSW_REG_PPCNT_RFC_3635_CNT:
+		*p_hw_stats = mlxsw_sp_port_hw_rfc_3635_stats;
+		*p_len = MLXSW_SP_PORT_HW_RFC_3635_STATS_LEN;
+		break;
+	case MLXSW_REG_PPCNT_DISCARD_CNT:
+		*p_hw_stats = mlxsw_sp_port_hw_discard_stats;
+		*p_len = MLXSW_SP_PORT_HW_DISCARD_STATS_LEN;
+		break;
 	case MLXSW_REG_PPCNT_PRIO_CNT:
 		*p_hw_stats = mlxsw_sp_port_hw_prio_stats;
 		*p_len = MLXSW_SP_PORT_HW_PRIO_STATS_LEN;
@@ -2116,11 +2256,26 @@ static void mlxsw_sp_port_get_stats(struct net_device *dev,
 				  data, data_index);
 	data_index = MLXSW_SP_PORT_HW_STATS_LEN;
 
+	/* RFC 2863 Counters */
+	__mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_RFC_2863_CNT, 0,
+				  data, data_index);
+	data_index += MLXSW_SP_PORT_HW_RFC_2863_STATS_LEN;
+
 	/* RFC 2819 Counters */
 	__mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_RFC_2819_CNT, 0,
 				  data, data_index);
 	data_index += MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN;
 
+	/* RFC 3635 Counters */
+	__mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_RFC_3635_CNT, 0,
+				  data, data_index);
+	data_index += MLXSW_SP_PORT_HW_RFC_3635_STATS_LEN;
+
+	/* Discard Counters */
+	__mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_DISCARD_CNT, 0,
+				  data, data_index);
+	data_index += MLXSW_SP_PORT_HW_DISCARD_STATS_LEN;
+
 	/* Per-Priority Counters */
 	for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
 		__mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_PRIO_CNT, i,
-- 
2.19.1

^ permalink raw reply related

* [GIT] Networking
From: David Miller @ 2018-11-19  3:12 UTC (permalink / raw)
  To: torvalds; +Cc: akpm, netdev, linux-kernel


1) Fix some potentially uninitialized variables and use-after-free in
   kvaser_usb can drier, from Jimmy Assarsson.

2) Fix leaks in qed driver, from Denis Bolotin.

3) Socket leak in l2tp, from Xin Long.

4) RSS context allocation fix in bnxt_en from Michael Chan.

5) Fix cxgb4 build errors, from Ganesh Goudar.

6) Route leaks in ipv6 when removing exceptions, from Xin Long.

7) Memory leak in IDR allocation handling of act_pedit, from Davide
   Caratti.

8) Use-after-free of bridge vlan stats, from Nikolay Aleksandrov.

9) When MTU is locked, do not force DF bit on ipv4 tunnels.  From
   Sabrina Dubroca.

10) When NAPI cached skb is reused, we must set it to the proper
    initial state which includes skb->pkt_type.  From Eric Dumazet.

11) Lockdep and non-linear SKB handling fix in tipc from Jon Maloy.

12) Set RX queue properly in various tuntap receive paths, from
    Matthew Cover.

Please pull, thanks a lot!

The following changes since commit ccda4af0f4b92f7b4c308d3acc262f4a7e3affad:

  Linux 4.20-rc2 (2018-11-11 17:12:31 -0600)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 

for you to fetch changes up to 8ebebcba559a1bfbaec7bbda64feb9870b9c58da:

  tuntap: fix multiqueue rx (2018-11-18 19:05:43 -0800)

----------------------------------------------------------------
Alexander Stein (1):
      can: flexcan: Always use last mailbox for TX

Andrew Morton (1):
      drivers/net/ethernet/qlogic/qed/qed_rdma.h: fix typo

Aya Levin (1):
      net/mlx4: Fix UBSAN warning of signed integer overflow

Brenda J. Butler (1):
      tc-testing: tdc.py: Guard against lack of returncode in executed command

Christophe JAILLET (1):
      net: lantiq: Fix returned value in case of error in 'xrx200_probe()'

David Ahern (1):
      ipv6: Fix PMTU updates for UDP/raw sockets in presence of VRF

David Howells (1):
      rxrpc: Fix life check

David S. Miller (7):
      Merge tag 'linux-can-fixes-for-4.20-20181109' of ssh://gitolite.kernel.org/.../mkl/linux-can
      Merge branch 'qed-Miscellaneous-bug-fixes'
      Merge branch 'bnxt_en-Bug-fixes'
      Merge branch 'mlx4-fixes'
      Merge tag 'batadv-net-for-davem-20181114' of git://git.open-mesh.org/linux-merge
      Revert "net: phy: mdio-gpio: Fix working over slow can_sleep GPIOs"
      Merge branch 'tdc-fixes'

Davide Caratti (1):
      net/sched: act_pedit: fix memory leak when IDR allocation fails

Denis Bolotin (3):
      qed: Fix PTT leak in qed_drain()
      qed: Fix overriding offload_tc by protocols without APP TLV
      qed: Fix reading wrong value in loop condition

Eric Dumazet (2):
      net_sched: sch_fq: ensure maxrate fq parameter applies to EDT flows
      net-gro: reset skb->pkt_type in napi_reuse_skb()

Eugeniu Rosca (1):
      dt-bindings: can: rcar_can: document r8a77965 support

Fabrizio Castro (2):
      can: rcar_can: Fix erroneous registration
      dt-bindings: can: rcar_can: Add r8a774a1 support

Ganesh Goudar (1):
      cxgb4: fix thermal zone build error

Jack Morgenstein (1):
      net/mlx4_core: Zero out lkey field in SW2HW_MPT fw command

Jimmy Assarsson (2):
      can: kvaser_usb: Fix potential uninitialized variable use
      can: kvaser_usb: Fix accessing freed memory in kvaser_usb_start_xmit()

Jon Maloy (2):
      tipc: fix lockdep warning when reinitilaizing sockets
      tipc: don't assume linear buffer when reading ancillary data

Lucas Bates (1):
      tc-testing: tdc.py: ignore errors when decoding stdout/stderr

Lukas Wunner (1):
      can: hi311x: Use level-triggered interrupt

Marc Kleine-Budde (5):
      can: flexcan: remove not needed struct flexcan_priv::tx_mb and struct flexcan_priv::tx_mb_idx
      can: dev: can_get_echo_skb(): factor out non sending code to __can_get_echo_skb()
      can: dev: __can_get_echo_skb(): replace struct can_frame by canfd_frame to access frame length
      can: dev: __can_get_echo_skb(): Don't crash the kernel if can_priv::echo_skb is accessed out of bounds
      can: dev: __can_get_echo_skb(): print error message, if trying to echo non existing skb

Martin Schiller (2):
      net: phy: mdio-gpio: Fix working over slow can_sleep GPIOs
      net: phy: mdio-gpio: Fix working over slow can_sleep GPIOs

Matthew Cover (1):
      tuntap: fix multiqueue rx

Maxime Chevallier (1):
      net: mvneta: Don't advertise 2.5G modes

Michael Chan (5):
      bnxt_en: Fix RSS context allocation.
      bnxt_en: Fix rx_l4_csum_errors counter on 57500 devices.
      bnxt_en: Disable RDMA support on the 57500 chips.
      bnxt_en: Workaround occasional TX timeout on 57500 A0.
      bnxt_en: Add software "missed_irqs" counter.

Michal Kalderon (1):
      qed: Fix rdma_info structure allocation

Nikolay Aleksandrov (1):
      net: bridge: fix vlan stats use-after-free on destruction

Oleksij Rempel (4):
      can: rx-offload: introduce can_rx_offload_get_echo_skb() and can_rx_offload_queue_sorted() functions
      can: flexcan: handle tx-complete CAN frames via rx-offload infrastructure
      can: rx-offload: rename can_rx_offload_irq_queue_err_skb() to can_rx_offload_queue_tail()
      can: flexcan: use can_rx_offload_queue_sorted() for flexcan_irq_bus_*()

Oliver Hartkopp (1):
      can: raw: check for CAN FD capable netdev in raw_sendmsg()

Pankaj Bansal (1):
      can: flexcan: Unlock the MB unconditionally

Sabrina Dubroca (1):
      ip_tunnel: don't force DF when MTU is locked

Slavomir Kaslev (1):
      socket: do a generic_file_splice_read when proto_ops has no splice_read

Sudarsana Reddy Kalluru (1):
      bnx2x: Assign unique DMAE channel number for FW DMAE transactions.

Sven Eckelmann (2):
      batman-adv: Use explicit tvlv padding for ELP packets
      batman-adv: Expand merged fragment buffer for full packet

Tariq Toukan (1):
      net/mlx4_core: Fix uninitialized variable compilation warning

Thor Thayer (1):
      MAINTAINERS: Replace Vince Bridgers as Altera TSE maintainer

Toke Høiland-Jørgensen (1):
      MAINTAINERS: Add entry for CAKE qdisc

Ursula Braun (1):
      s390/ism: clear dmbe_mask bit before SMC IRQ handling

Vasundhara Volam (1):
      bnxt_en: Fix filling time in bnxt_fill_coredump_record()

Xin Long (2):
      l2tp: fix a sock refcnt leak in l2tp_tunnel_register
      ipv6: fix a dst leak when removing its exception

YueHaibing (2):
      can: ucan: remove set but not used variable 'udev'
      can: ucan: remove duplicated include from ucan.c

 Documentation/devicetree/bindings/net/can/holt_hi311x.txt |   2 +-
 Documentation/devicetree/bindings/net/can/rcar_can.txt    |  28 ++++++++++++++---------
 Documentation/networking/rxrpc.txt                        |  17 +++++++++-----
 MAINTAINERS                                               |   8 ++++++-
 drivers/net/can/dev.c                                     |  48 ++++++++++++++++++++++++++++-----------
 drivers/net/can/flexcan.c                                 | 108 +++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------------
 drivers/net/can/rcar/rcar_can.c                           |   5 ++++-
 drivers/net/can/rx-offload.c                              |  51 ++++++++++++++++++++++++++++++++++++++++--
 drivers/net/can/spi/hi311x.c                              |   2 +-
 drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c          |   4 ++--
 drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c         |  10 ++++-----
 drivers/net/can/usb/ucan.c                                |   7 ------
 drivers/net/ethernet/broadcom/bnx2x/bnx2x.h               |   7 ++++++
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c            |   1 +
 drivers/net/ethernet/broadcom/bnxt/bnxt.c                 |  70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 drivers/net/ethernet/broadcom/bnxt/bnxt.h                 |   4 ++++
 drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c         |   9 +++++---
 drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c             |   3 +++
 drivers/net/ethernet/chelsio/Kconfig                      |   1 -
 drivers/net/ethernet/chelsio/cxgb4/Makefile               |   4 +---
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c           |   4 ++--
 drivers/net/ethernet/lantiq_xrx200.c                      |   5 +++--
 drivers/net/ethernet/marvell/mvneta.c                     |  12 +++-------
 drivers/net/ethernet/mellanox/mlx4/alloc.c                |   2 +-
 drivers/net/ethernet/mellanox/mlx4/mlx4.h                 |   4 ++--
 drivers/net/ethernet/mellanox/mlx4/mr.c                   |   1 +
 drivers/net/ethernet/qlogic/qed/qed_dcbx.c                |  14 ++++++------
 drivers/net/ethernet/qlogic/qed/qed_dev.c                 |  15 +++++++++----
 drivers/net/ethernet/qlogic/qed/qed_int.c                 |   2 ++
 drivers/net/ethernet/qlogic/qed/qed_main.c                |   2 +-
 drivers/net/ethernet/qlogic/qed/qed_rdma.c                |  50 ++++++++++++++++++++++++-----------------
 drivers/net/ethernet/qlogic/qed/qed_rdma.h                |   5 +++++
 drivers/net/phy/mdio-gpio.c                               |  10 ++++-----
 drivers/net/tun.c                                         |   7 +++++-
 drivers/s390/net/ism_drv.c                                |   2 +-
 fs/afs/rxrpc.c                                            |  11 ++++++++-
 include/linux/can/dev.h                                   |   1 +
 include/linux/can/rx-offload.h                            |   7 +++++-
 include/net/af_rxrpc.h                                    |   3 ++-
 include/trace/events/rxrpc.h                              |   2 ++
 net/batman-adv/bat_v_elp.c                                |   6 +++--
 net/batman-adv/fragmentation.c                            |   2 +-
 net/bridge/br_private.h                                   |   7 ++++++
 net/bridge/br_vlan.c                                      |   3 ++-
 net/can/raw.c                                             |  15 +++++++------
 net/core/dev.c                                            |   4 ++++
 net/ipv4/ip_tunnel_core.c                                 |   2 +-
 net/ipv6/route.c                                          |  14 +++++++-----
 net/l2tp/l2tp_core.c                                      |   9 ++++----
 net/rxrpc/af_rxrpc.c                                      |  27 ++++++++++++++++++----
 net/sched/act_pedit.c                                     |   3 ++-
 net/sched/sch_fq.c                                        |  31 +++++++++++++++----------
 net/socket.c                                              |   2 +-
 net/tipc/discover.c                                       |  19 ++++++++--------
 net/tipc/net.c                                            |  45 ++++++++++++++++++++++++++++++-------
 net/tipc/net.h                                            |   2 +-
 net/tipc/socket.c                                         |  15 +++++++++----
 tools/testing/selftests/tc-testing/tdc.py                 |  18 ++++++++++-----
 58 files changed, 539 insertions(+), 233 deletions(-)

^ permalink raw reply

* Re: [PATCH] rhashtable: detect when object movement between tables might have invalidated a lookup
From: Herbert Xu @ 2018-11-19  3:54 UTC (permalink / raw)
  To: NeilBrown; +Cc: David Miller, tgraf, netdev, linux-kernel, eric.dumazet
In-Reply-To: <878t1tece0.fsf@notabene.neil.brown.name>

On Fri, Nov 16, 2018 at 05:59:19PM +1100, NeilBrown wrote:
>
> NULLS_MARKER assumes a hash value in which the bottom bits are most
> likely to be unique.  To convert this to a pointer which certainly not
> valid, it shifts left by 1 and sets the lsb.
> We aren't passing a hash value, but are passing an address instead.
> In this case the bottom 2 bits are certain to be 0, and the top bit
> could contain valuable information (on a 32bit system).
> The best way to turn a pointer into a certainly-invalid pointer
> is to just set the lsb.  By shifting right by one, we discard an
> uninteresting bit, preserve all the interesting bits, and effectively
> just set the lsb.
> 
> I could add a comment explaining that if you like.

The top-bit is most likely to be fixed and offer no real value.

> >> diff --git a/lib/rhashtable.c b/lib/rhashtable.c
> >> index 30526afa8343..852ffa5160f1 100644
> >> --- a/lib/rhashtable.c
> >> +++ b/lib/rhashtable.c
> >> @@ -1179,8 +1179,7 @@ struct rhash_head __rcu **rht_bucket_nested(const struct bucket_table *tbl,
> >>  					    unsigned int hash)
> >>  {
> >>  	const unsigned int shift = PAGE_SHIFT - ilog2(sizeof(void *));
> >> -	static struct rhash_head __rcu *rhnull =
> >> -		(struct rhash_head __rcu *)NULLS_MARKER(0);
> >> +	static struct rhash_head __rcu *rhnull;
> >
> > I don't understand why you can't continue to do NULLS_MARKER(0) or
> > RHT_NULLS_MARKER(0).
> 
> Because then the test
> 
> +	} while (he != RHT_NULLS_MARKER(head));
> 
> in __rhashtable_lookup() would always succeed, and it would loop
> forever.

This change is only necessary because of your shifting change
above, which AFAICS adds no real benefit.

Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply


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