* Re: [PATCH net-next 1/4] net: dsa: move up phy enabling in core
From: Florian Fainelli @ 2017-09-22 16:52 UTC (permalink / raw)
To: Vivien Didelot, netdev; +Cc: linux-kernel, kernel, David S. Miller, Andrew Lunn
In-Reply-To: <20170922161753.19563-2-vivien.didelot@savoirfairelinux.com>
On 09/22/2017 09:17 AM, Vivien Didelot wrote:
> bcm_sf2 is currently the only driver using the phy argument passed to
> .port_enable. It resets the state machine if the phy has been hard
> reset. This check is generic and can be moved to DSA core.
This is completely specific to bcm_sf2 because it does call
bcm_sf2_gphy_enable_set() which performs a HW reset of the PHY, you
can't move this to the generic portion of net/dsa/slave.c. NACK.
>
> Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
> ---
> drivers/net/dsa/bcm_sf2.c | 16 +---------------
> net/dsa/slave.c | 15 +++++++++++++--
> 2 files changed, 14 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
> index 898d5642b516..ad96b9725a2c 100644
> --- a/drivers/net/dsa/bcm_sf2.c
> +++ b/drivers/net/dsa/bcm_sf2.c
> @@ -184,22 +184,8 @@ static int bcm_sf2_port_setup(struct dsa_switch *ds, int port,
> core_writel(priv, reg, CORE_PORT_TC2_QOS_MAP_PORT(port));
>
> /* Re-enable the GPHY and re-apply workarounds */
> - if (priv->int_phy_mask & 1 << port && priv->hw_params.num_gphy == 1) {
> + if (priv->int_phy_mask & 1 << port && priv->hw_params.num_gphy == 1)
> bcm_sf2_gphy_enable_set(ds, true);
> - if (phy) {
> - /* if phy_stop() has been called before, phy
> - * will be in halted state, and phy_start()
> - * will call resume.
> - *
> - * the resume path does not configure back
> - * autoneg settings, and since we hard reset
> - * the phy manually here, we need to reset the
> - * state machine also.
> - */
> - phy->state = PHY_READY;
> - phy_init_hw(phy);
> - }
> - }
>
> /* Enable MoCA port interrupts to get notified */
> if (port == priv->moca_port)
> diff --git a/net/dsa/slave.c b/net/dsa/slave.c
> index 02ace7d462c4..606812160fd5 100644
> --- a/net/dsa/slave.c
> +++ b/net/dsa/slave.c
> @@ -72,6 +72,7 @@ static int dsa_slave_get_iflink(const struct net_device *dev)
> static int dsa_slave_open(struct net_device *dev)
> {
> struct dsa_slave_priv *p = netdev_priv(dev);
> + struct phy_device *phy = p->phy;
> struct dsa_port *dp = p->dp;
> struct dsa_switch *ds = dp->ds;
> struct net_device *master = dsa_master_netdev(p);
> @@ -106,8 +107,18 @@ static int dsa_slave_open(struct net_device *dev)
>
> dsa_port_set_state_now(p->dp, stp_state);
>
> - if (p->phy)
> - phy_start(p->phy);
> + if (phy) {
> + /* If phy_stop() has been called before, phy will be in
> + * halted state, and phy_start() will call resume.
> + *
> + * The resume path does not configure back autoneg
> + * settings, and since the internal phy may have been
> + * hard reset, we need to reset the state machine also.
> + */
> + phy->state = PHY_READY;
> + phy_init_hw(phy);
> + phy_start(phy);
> + }
>
> return 0;
>
>
--
Florian
^ permalink raw reply
* Re: [PATCH net-next 1/4] net: dsa: move up phy enabling in core
From: Florian Fainelli @ 2017-09-22 16:58 UTC (permalink / raw)
To: Andrew Lunn, Vivien Didelot; +Cc: netdev, linux-kernel, kernel, David S. Miller
In-Reply-To: <20170922163258.GA3470@lunn.ch>
On 09/22/2017 09:32 AM, Andrew Lunn wrote:
> On Fri, Sep 22, 2017 at 12:17:50PM -0400, Vivien Didelot wrote:
>> bcm_sf2 is currently the only driver using the phy argument passed to
>> .port_enable. It resets the state machine if the phy has been hard
>> reset. This check is generic and can be moved to DSA core.
>>
>> dsa_port_set_state_now(p->dp, stp_state);
>>
>> - if (p->phy)
>> - phy_start(p->phy);
>> + if (phy) {
>> + /* If phy_stop() has been called before, phy will be in
>> + * halted state, and phy_start() will call resume.
>> + *
>> + * The resume path does not configure back autoneg
>> + * settings, and since the internal phy may have been
>> + * hard reset, we need to reset the state machine also.
>> + */
>> + phy->state = PHY_READY;
>> + phy_init_hw(phy);
>> + phy_start(phy);
>> + }
>
> Hi Vivien
>
> If this is generic, why is it needed at all here? Shouldn't this
> actually by in phylib?
This does not belong in the core logic within net/dsa/slave.c. The
reason why this is necessary here is because we are doing a HW-based
reset of the PHY, as the comment explains this is specific to how the HW
works. There may be a cleaner solution to this problem, but in any case,
I don't think other drivers should inherit that logic.
--
Florian
^ permalink raw reply
* usb/wireless/rsi_91x: use-after-free write in __run_timers
From: Andrey Konovalov @ 2017-09-22 17:04 UTC (permalink / raw)
To: Kalle Valo, Amitkumar Karwar, Prameela Rani Garnepudi,
Karun Eagalapati, linux-wireless, netdev, LKML
Cc: Dmitry Vyukov, Kostya Serebryany, syzkaller
Hi!
I've got the following report while fuzzing the kernel with syzkaller.
On commit 6e80ecdddf4ea6f3cd84e83720f3d852e6624a68 (Sep 21).
==================================================================
BUG: KASAN: use-after-free in __run_timers+0xc0e/0xd40
Write of size 8 at addr ffff880069f701b8 by task swapper/0/0
CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.14.0-rc1-42311-g6e80ecdddf4e #234
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
Call Trace:
<IRQ>
__dump_stack lib/dump_stack.c:16
dump_stack+0x292/0x395 lib/dump_stack.c:52
print_address_description+0x78/0x280 mm/kasan/report.c:252
kasan_report_error mm/kasan/report.c:351
kasan_report+0x22f/0x340 mm/kasan/report.c:409
__asan_report_store8_noabort+0x1c/0x20 mm/kasan/report.c:435
collect_expired_timers ./include/linux/list.h:729
__run_timers+0xc0e/0xd40 kernel/time/timer.c:1616
run_timer_softirq+0x83/0x140 kernel/time/timer.c:1646
__do_softirq+0x305/0xc2d kernel/softirq.c:284
invoke_softirq kernel/softirq.c:364
irq_exit+0x171/0x1a0 kernel/softirq.c:405
exiting_irq ./arch/x86/include/asm/apic.h:638
smp_apic_timer_interrupt+0x2b9/0x8d0 arch/x86/kernel/apic/apic.c:1048
apic_timer_interrupt+0x9d/0xb0
</IRQ>
RIP: 0010:native_safe_halt+0x6/0x10 ./arch/x86/include/asm/irqflags.h:53
RSP: 0018:ffffffff86607958 EFLAGS: 00000282 ORIG_RAX: ffffffffffffff10
RAX: dffffc0000000020 RBX: 1ffffffff0cc0f2f RCX: 0000000000000000
RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffffffff8662ea64
RBP: ffffffff86607958 R08: ffffffff813d3501 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000000 R12: 1ffffffff0cc0f3b
R13: ffffffff86607a98 R14: ffffffff86fc1628 R15: 0000000000000000
arch_safe_halt ./arch/x86/include/asm/paravirt.h:93
default_idle+0x127/0x690 arch/x86/kernel/process.c:341
arch_cpu_idle+0xf/0x20 arch/x86/kernel/process.c:332
default_idle_call+0x3b/0x60 kernel/sched/idle.c:98
cpuidle_idle_call kernel/sched/idle.c:156
do_idle+0x35c/0x440 kernel/sched/idle.c:246
cpu_startup_entry+0x1d/0x20 kernel/sched/idle.c:351
rest_init+0xf3/0x100 init/main.c:435
start_kernel+0x782/0x7b0 init/main.c:710
x86_64_start_reservations+0x2a/0x2c arch/x86/kernel/head64.c:377
x86_64_start_kernel+0x77/0x7a arch/x86/kernel/head64.c:358
secondary_startup_64+0xa5/0xa5 arch/x86/kernel/head_64.S:235
Allocated by task 1845:
save_stack_trace+0x1b/0x20 arch/x86/kernel/stacktrace.c:59
save_stack+0x43/0xd0 mm/kasan/kasan.c:447
set_track mm/kasan/kasan.c:459
kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:551
kmem_cache_alloc_trace+0x11e/0x2d0 mm/slub.c:2772
kmalloc ./include/linux/slab.h:493
kzalloc ./include/linux/slab.h:666
rsi_91x_init+0x98/0x510 drivers/net/wireless/rsi/rsi_91x_main.c:203
rsi_probe+0xb6/0x13b0 drivers/net/wireless/rsi/rsi_91x_usb.c:665
usb_probe_interface+0x35d/0x8e0 drivers/usb/core/driver.c:361
really_probe drivers/base/dd.c:413
driver_probe_device+0x610/0xa00 drivers/base/dd.c:557
__device_attach_driver+0x230/0x290 drivers/base/dd.c:653
bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463
__device_attach+0x26e/0x3d0 drivers/base/dd.c:710
device_initial_probe+0x1f/0x30 drivers/base/dd.c:757
bus_probe_device+0x1eb/0x290 drivers/base/bus.c:523
device_add+0xd0b/0x1660 drivers/base/core.c:1835
usb_set_configuration+0x104e/0x1870 drivers/usb/core/message.c:1932
generic_probe+0x73/0xe0 drivers/usb/core/generic.c:174
usb_probe_device+0xaf/0xe0 drivers/usb/core/driver.c:266
really_probe drivers/base/dd.c:413
driver_probe_device+0x610/0xa00 drivers/base/dd.c:557
__device_attach_driver+0x230/0x290 drivers/base/dd.c:653
bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463
__device_attach+0x26e/0x3d0 drivers/base/dd.c:710
device_initial_probe+0x1f/0x30 drivers/base/dd.c:757
bus_probe_device+0x1eb/0x290 drivers/base/bus.c:523
device_add+0xd0b/0x1660 drivers/base/core.c:1835
usb_new_device+0x7b8/0x1020 drivers/usb/core/hub.c:2457
hub_port_connect drivers/usb/core/hub.c:4903
hub_port_connect_change drivers/usb/core/hub.c:5009
port_event drivers/usb/core/hub.c:5115
hub_event+0x194d/0x3740 drivers/usb/core/hub.c:5195
process_one_work+0xc7f/0x1db0 kernel/workqueue.c:2119
worker_thread+0x221/0x1850 kernel/workqueue.c:2253
kthread+0x3a1/0x470 kernel/kthread.c:231
ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431
Freed by task 1845:
save_stack_trace+0x1b/0x20 arch/x86/kernel/stacktrace.c:59
save_stack+0x43/0xd0 mm/kasan/kasan.c:447
set_track mm/kasan/kasan.c:459
kasan_slab_free+0x72/0xc0 mm/kasan/kasan.c:524
slab_free_hook mm/slub.c:1390
slab_free_freelist_hook mm/slub.c:1412
slab_free mm/slub.c:2988
kfree+0xf6/0x2f0 mm/slub.c:3919
rsi_91x_deinit+0x1e8/0x250 drivers/net/wireless/rsi/rsi_91x_main.c:268
rsi_probe+0xed1/0x13b0 drivers/net/wireless/rsi/rsi_91x_usb.c:709
usb_probe_interface+0x35d/0x8e0 drivers/usb/core/driver.c:361
really_probe drivers/base/dd.c:413
driver_probe_device+0x610/0xa00 drivers/base/dd.c:557
__device_attach_driver+0x230/0x290 drivers/base/dd.c:653
bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463
__device_attach+0x26e/0x3d0 drivers/base/dd.c:710
device_initial_probe+0x1f/0x30 drivers/base/dd.c:757
bus_probe_device+0x1eb/0x290 drivers/base/bus.c:523
device_add+0xd0b/0x1660 drivers/base/core.c:1835
usb_set_configuration+0x104e/0x1870 drivers/usb/core/message.c:1932
generic_probe+0x73/0xe0 drivers/usb/core/generic.c:174
usb_probe_device+0xaf/0xe0 drivers/usb/core/driver.c:266
really_probe drivers/base/dd.c:413
driver_probe_device+0x610/0xa00 drivers/base/dd.c:557
__device_attach_driver+0x230/0x290 drivers/base/dd.c:653
bus_for_each_drv+0x161/0x210 drivers/base/bus.c:463
__device_attach+0x26e/0x3d0 drivers/base/dd.c:710
device_initial_probe+0x1f/0x30 drivers/base/dd.c:757
bus_probe_device+0x1eb/0x290 drivers/base/bus.c:523
device_add+0xd0b/0x1660 drivers/base/core.c:1835
usb_new_device+0x7b8/0x1020 drivers/usb/core/hub.c:2457
hub_port_connect drivers/usb/core/hub.c:4903
hub_port_connect_change drivers/usb/core/hub.c:5009
port_event drivers/usb/core/hub.c:5115
hub_event+0x194d/0x3740 drivers/usb/core/hub.c:5195
process_one_work+0xc7f/0x1db0 kernel/workqueue.c:2119
worker_thread+0x221/0x1850 kernel/workqueue.c:2253
kthread+0x3a1/0x470 kernel/kthread.c:231
ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431
The buggy address belongs to the object at ffff880069f70000
which belongs to the cache kmalloc-2048 of size 2048
The buggy address is located 440 bytes inside of
2048-byte region [ffff880069f70000, ffff880069f70800)
The buggy address belongs to the page:
page:ffffea0001a7dc00 count:1 mapcount:0 mapping: (null)
index:0xffff880069f77700 compound_mapcount: 0
flags: 0x100000000008100(slab|head)
raw: 0100000000008100 0000000000000000 ffff880069f77700 00000001800f000c
raw: ffffea000190e000 0000000200000002 ffff88006c402d80 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff880069f70080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff880069f70100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>ffff880069f70180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff880069f70200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff880069f70280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================
^ permalink raw reply
* Re: [PATCH iproute2 master 0/2] BPF/XDP json follow-up
From: Stephen Hemminger @ 2017-09-22 17:07 UTC (permalink / raw)
To: Daniel Borkmann; +Cc: ast, netdev
In-Reply-To: <cover.1505956723.git.daniel@iogearbox.net>
On Thu, 21 Sep 2017 10:42:27 +0200
Daniel Borkmann <daniel@iogearbox.net> wrote:
> After merging net-next branch into master, Stephen asked to
> fix up json dump for XDP as there were some merge conflicts,
> so here it is.
>
> Thanks!
>
> Daniel Borkmann (2):
> json: move json printer to common library
> bpf: properly output json for xdp
>
> include/json_print.h | 71 ++++++++++++++++
> ip/Makefile | 2 +-
> ip/ip_common.h | 65 ++------------
> ip/ip_print.c | 233 ---------------------------------------------------
> ip/iplink_xdp.c | 74 +++++++++-------
> lib/Makefile | 2 +-
> lib/bpf.c | 19 +++--
> lib/json_print.c | 231 ++++++++++++++++++++++++++++++++++++++++++++++++++
> 8 files changed, 369 insertions(+), 328 deletions(-)
> create mode 100644 include/json_print.h
> delete mode 100644 ip/ip_print.c
> create mode 100644 lib/json_print.c
>
Applied.
^ permalink raw reply
* [PATCH] Add a driver for Renesas uPD60620 and uPD60620A PHYs
From: Bernd Edlinger @ 2017-09-22 17:08 UTC (permalink / raw)
To: netdev@vger.kernel.org; +Cc: Andrew Lunn, Florian Fainelli
Signed-off-by: Bernd Edlinger <bernd.edlinger@hotmail.de>
---
drivers/net/phy/Kconfig | 5 +
drivers/net/phy/Makefile | 1 +
drivers/net/phy/uPD60620.c | 226
+++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 232 insertions(+)
create mode 100644 drivers/net/phy/uPD60620.c
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index a9d16a3..25089f0 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -287,6 +287,11 @@ config DP83867_PHY
---help---
Currently supports the DP83867 PHY.
+config RENESAS_PHY
+ tristate "Driver for Renesas PHYs"
+ ---help---
+ Supports the uPD60620 and uPD60620A PHYs.
+
config FIXED_PHY
tristate "MDIO Bus/PHY emulation with fixed speed/link PHYs"
depends on PHYLIB
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 416df92..1404ad3 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -72,6 +72,7 @@ obj-$(CONFIG_MICROSEMI_PHY) += mscc.o
obj-$(CONFIG_NATIONAL_PHY) += national.o
obj-$(CONFIG_QSEMI_PHY) += qsemi.o
obj-$(CONFIG_REALTEK_PHY) += realtek.o
+obj-$(CONFIG_RENESAS_PHY) += uPD60620.o
obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o
obj-$(CONFIG_SMSC_PHY) += smsc.o
obj-$(CONFIG_STE10XP) += ste10Xp.o
diff --git a/drivers/net/phy/uPD60620.c b/drivers/net/phy/uPD60620.c
new file mode 100644
index 0000000..b3d900c
--- /dev/null
+++ b/drivers/net/phy/uPD60620.c
@@ -0,0 +1,226 @@
+/*
+ * Driver for the Renesas PHY uPD60620.
+ *
+ * Copyright (C) 2015 Softing Industrial Automation GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/phy.h>
+
+#define UPD60620_PHY_ID 0xb8242824
+
+/* Extended Registers and values */
+/* PHY Special Control/Status */
+#define PHY_PHYSCR 0x1F /* PHY.31 */
+#define PHY_PHYSCR_10MB 0x0004 /* PHY speed = 10mb */
+#define PHY_PHYSCR_100MB 0x0008 /* PHY speed = 100mb */
+#define PHY_PHYSCR_DUPLEX 0x0010 /* PHY Duplex */
+#define PHY_PHYSCR_RSVD5 0x0020 /* Reserved Bit 5 */
+#define PHY_PHYSCR_MIIMOD 0x0040 /* Enable 4B5B MII mode */
+#define PHY_PHYSCR_RSVD7 0x0080 /* Reserved Bit 7 */
+#define PHY_PHYSCR_RSVD8 0x0100 /* Reserved Bit 8 */
+#define PHY_PHYSCR_RSVD9 0x0200 /* Reserved Bit 9 */
+#define PHY_PHYSCR_RSVD10 0x0400 /* Reserved Bit 10 */
+#define PHY_PHYSCR_RSVD11 0x0800 /* Reserved Bit 11 */
+#define PHY_PHYSCR_ANDONE 0x1000 /* Auto negotiation done */
+#define PHY_PHYSCR_RSVD13 0x2000 /* Reserved Bit 13 */
+#define PHY_PHYSCR_RSVD14 0x4000 /* Reserved Bit 14 */
+#define PHY_PHYSCR_RSVD15 0x8000 /* Reserved Bit 15 */
+
+/* PHY Global Config Mapping */
+#define PHY_GLOBAL_CONFIG 0x07
+/* PHY GPIO Config Register 1 */
+#define PHY_GPIO_CONFIG1 0x01 /* PHY 7.1 */
+#define PHY_GPIO4_INT0 0x000d /* GPIO4 configuration */
+#define PHY_GPIO5_INT1 0x00d0 /* GPIO5 configuration */
+
+/* PHY Interrupt Control Register */
+#define PHY_ICR 0x1e /* PHY.30 */
+#define PHY_ICR_RSVD0 0x0001 /* Reserved bit 0 */
+#define PHY_ICR_ANCPRRN 0x0002 /* Auto negotiation paged received */
+#define PHY_ICR_PDFEN 0x0004 /* Parallel detection fault */
+#define PHY_ICR_ANCLPAEN 0x0008 /* Auto negotiation last page ack */
+#define PHY_ICR_LNKINTEN 0x0010 /* Link down */
+#define PHY_ICR_REMFD 0x0020 /* Remote fault detected */
+#define PHY_ICR_ANCINTEN 0x0040 /* Auto negotiation complete */
+#define PHY_ICR_EOEN 0x0080 /* Energy on generated */
+#define PHY_ICR_RSVD8 0x0100 /* Reserved bit 8 */
+#define PHY_ICR_FEQTRGEN 0x0200 /* FEQ Trigger */
+#define PHY_ICR_BERTRGEN 0x0400 /* BER Counter Trigger */
+#define PHY_ICR_MLINTEN 0x0800 /* Maxlvl */
+#define PHY_ICR_CLPINTEN 0x1000 /* Clipping */
+#define PHY_ICR_RSVD13 0x2000 /* Reserved bit 13 */
+#define PHY_ICR_RSVD14 0x4000 /* Reserved bit 14 */
+#define PHY_ICR_RSVD15 0x8000 /* Reserved bit 15 */
+
+/* PHY Interrupt Status Register */
+#define PHY_ISR 0x1d /* PHY.29 */
+#define PHY_ISR_DUPINT 0x0000 /* Placeholder for Duplex/Speed
intr */
+#define PHY_ISR_RSVD0 0x0001 /* Reserved bit 0 */
+#define PHY_ISR_ANCPR 0x0002 /* Auto negotiation paged received */
+#define PHY_ISR_PDF 0x0004 /* Parallel detection fault */
+#define PHY_ISR_ANCLPA 0x0008 /* Auto negotiation last page ack */
+#define PHY_ISR_LNKINT 0x0010 /* Link down */
+#define PHY_ISR_REMFD 0x0020 /* Remote fault detected */
+#define PHY_ISR_ANCINT 0x0040 /* Auto negotiation complete */
+#define PHY_ISR_EO 0x0080 /* Energy on generated */
+#define PHY_ISR_RSVD8 0x0100 /* Reserved bit 8 */
+#define PHY_ISR_FEQTRG 0x0200 /* FEQ Trigger */
+#define PHY_ISR_BERTRG 0x0400 /* BER Counter Trigger */
+#define PHY_ISR_MLINT 0x0800 /* Maxlvl */
+#define PHY_ISR_CLPINT 0x1000 /* Clipping */
+#define PHY_ISR_RSVD13 0x2000 /* Reserved bit 13 */
+#define PHY_ISR_RSVD14 0x4000 /* Reserved bit 14 */
+#define PHY_ISR_RSVD15 0x8000 /* Reserved bit 15 */
+
+/* PHY Diagnosis Control/Status Register*/
+#define PHY_DCS 0x19 /* PHY.25 */
+#define PHY_DCS_PWDIAG1 0x0001 /* Pulse Width Diagnosis -- 8ns */
+#define PHY_DCS_DIAGSEL 0x0020 /* Diagnosis select Tx or Rx */
+#define PHY_DCS_DIAGPOL 0x0040 /* Diagnosis stop polarity */
+#define PHY_DCS_DIAGDONE 0x0080 /* Diagnosis done */
+#define PHY_DCS_ADCTRIG05 0x0700 /* ADC Trigger level 0.5V for
cable len */
+#define PHY_DCS_ADCMAX 0x3F00 /* ADC Max value */
+#define PHY_DCS_DIAGINIT 0x4000 /* Init TDR test */
+
+/* PHY Diagnosis Counter Register */
+#define PHY_DCR 0x1a /* PHY.26 */
+#define PHY_DCR_DIGNCNT 0x00ff /* Diagnosis Count */
+#define PHY_DCR_CNTWIN 0xff00 /* Diagnosis Count Window */
+
+/* PHY Mode Control/Status Register */
+#define PHY_MCS 0x11 /* PHY.17 */
+#define PHY_MCS_RSVD0 0x0001 /* Reserved bit 0 */
+#define PHY_MCS_ENERGYON 0x0002 /* Energy on the Line status */
+#define PHY_MCS_FGLS 0x0004 /* Force Good Link Status */
+#define PHY_MCS_RSVD3 0x0008 /* Reserved bit 3 */
+#define PHY_MCS_DCDPATGEN 0x0010 /* DCD measuring pattern generation */
+#define PHY_MCS_RSVD5 0x0020 /* Reserved bit 5 */
+#define PHY_MCS_MDIMODE 0x0040 /* Force MDIX or MDI */
+#define PHY_MCS_AUTOMDIX 0x0080 /* Auto MDIX enable */
+#define PHY_MCS_FASTEST 0x0100 /* Auto negotiation test mode */
+#define PHY_MCS_FARLOOP 0x0200 /* Remote loopback enable */
+#define PHY_MCS_RSVD10 0x0400 /* Reserved bit 10 */
+#define PHY_MCS_LOWSQEN 0x0800 /* Squelch Threshold */
+#define PHY_MCS_RSVD12 0x1000 /* Reserved bit 12 */
+#define PHY_MCS_EPWRDOWN 0x2000 /* Power down mode enable */
+#define PHY_MCS_FASTRIP 0x4000 /* 10Base-T Fast mode */
+#define PHY_MCS_RSVD15 0x8000 /* Reserved bit 15 */
+
+/* PHY Special Modes */
+#define PHY_SPM 0x12 /* PHY.18 */
+#define PHY_SPM_FX_MODE 0x400 /* Enable 100BASE-FX mode */
+#define PHY_SPM_PHYMODE 0x1E0 /* PHY mode of operation */
+#define PHY_SPM_PHYADD 0x01F /* PHY address of device */
+
+/* PHY BER Counter Register */
+#define PHY_BER 0x17 /* PHY.23 */
+#define PHY_BER_COUNT 0x007f /* BER Count Bits 6-0 */
+#define PHY_BER_WINDOW 0x0780 /* BER Window Bits 10-7 */
+#define PHY_BER_CNT_TRIG 0x3800 /* BER count trigger bits 13-11 */
+#define PHY_BER_CNT_LNK_EN 0x4000 /* BER count link enable */
+#define PHY_BER_LNK_OK 0x8000 /* BER link OK */
+
+/* Init PHY */
+
+static int upd60620_config_init(struct phy_device *phydev)
+{
+ /* Enable support for passive HUBs (could be a strap option) */
+ /* PHYMODE: All speeds, HD in parallel detect */
+ return phy_write(phydev, PHY_SPM, 0x0180 | phydev->mdio.addr);
+}
+
+/* Get PHY status from common registers */
+
+static int upd60620_read_status(struct phy_device *phydev)
+{
+ int phy_state;
+
+ /* Read negotiated state */
+ phy_state = phy_read(phydev, MII_BMSR);
+ if (phy_state < 0)
+ return phy_state;
+
+ phydev->link = 0;
+ phydev->lp_advertising = 0;
+ phydev->pause = 0;
+ phydev->asym_pause = 0;
+
+ if (phy_state & BMSR_ANEGCOMPLETE) {
+ phy_state = phy_read(phydev, PHY_PHYSCR);
+ if (phy_state < 0)
+ return phy_state;
+
+ if (phy_state & (PHY_PHYSCR_10MB | PHY_PHYSCR_100MB)) {
+ phydev->link = 1;
+ phydev->speed = SPEED_10;
+ phydev->duplex = DUPLEX_HALF;
+
+ if (phy_state & PHY_PHYSCR_100MB)
+ phydev->speed = SPEED_100;
+ if (phy_state & PHY_PHYSCR_DUPLEX)
+ phydev->duplex = DUPLEX_FULL;
+
+ phy_state = phy_read(phydev, MII_LPA);
+ if (phy_state < 0)
+ return phy_state;
+
+ phydev->lp_advertising
+ = mii_lpa_to_ethtool_lpa_t(phy_state);
+
+ if (phydev->duplex == DUPLEX_FULL) {
+ if (phy_state & LPA_PAUSE_CAP)
+ phydev->pause = 1;
+ if (phy_state & LPA_PAUSE_ASYM)
+ phydev->asym_pause = 1;
+ }
+ }
+ } else if (phy_state & BMSR_LSTATUS) {
+ phy_state = phy_read(phydev, MII_BMCR);
+ if (phy_state < 0)
+ return phy_state;
+
+ if (!(phy_state & BMCR_ANENABLE)) {
+ phydev->link = 1;
+ phydev->speed = SPEED_10;
+ phydev->duplex = DUPLEX_HALF;
+
+ if (phy_state & BMCR_SPEED100)
+ phydev->speed = SPEED_100;
+ if (phy_state & BMCR_FULLDPLX)
+ phydev->duplex = DUPLEX_FULL;
+ }
+ }
+ return 0;
+}
+
+MODULE_DESCRIPTION("Renesas uPD60620 PHY driver");
+MODULE_AUTHOR("Bernd Edlinger <bernd.edlinger@hotmail.de>");
+MODULE_LICENSE("GPL");
+
+static struct phy_driver upd60620_driver[1] = { {
+ .phy_id = UPD60620_PHY_ID,
+ .phy_id_mask = 0xfffffffe,
+ .name = "Renesas uPD60620",
+ .features = PHY_BASIC_FEATURES,
+ .flags = 0,
+ .config_init = upd60620_config_init,
+ .config_aneg = genphy_config_aneg,
+ .read_status = upd60620_read_status,
+} };
+
+module_phy_driver(upd60620_driver);
+
+static struct mdio_device_id __maybe_unused upd60620_tbl[] = {
+ { UPD60620_PHY_ID, 0xfffffffe },
+ { }
+};
+
+MODULE_DEVICE_TABLE(mdio, upd60620_tbl);
--
2.7.4
^ permalink raw reply related
* Re: [PATCH iproute2 v2] man: fix documentation for range of route table ID
From: Stephen Hemminger @ 2017-09-22 17:09 UTC (permalink / raw)
To: Thomas Haller; +Cc: netdev, Phil Sutter
In-Reply-To: <20170922112854.21289-1-thaller@redhat.com>
On Fri, 22 Sep 2017 13:28:54 +0200
Thomas Haller <thaller@redhat.com> wrote:
> Signed-off-by: Thomas Haller <thaller@redhat.com>
> ---
> Changes in v2:
> - "0" is not a valid table ID.
>
> man/man8/ip-route.8.in | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/man/man8/ip-route.8.in b/man/man8/ip-route.8.in
> index 803de3b9..705ceb20 100644
> --- a/man/man8/ip-route.8.in
> +++ b/man/man8/ip-route.8.in
> @@ -322,7 +322,7 @@ normal routing tables.
> .P
> .B Route tables:
> Linux-2.x can pack routes into several routing tables identified
> -by a number in the range from 1 to 2^31 or by name from the file
> +by a number in the range from 1 to 2^32-1 or by name from the file
> .B @SYSCONFDIR@/rt_tables
> By default all normal routes are inserted into the
> .B main
Applied
^ permalink raw reply
* Re: [PATCH,v2,net-next 1/2] tun: enable NAPI for TUN/TAP driver
From: Mahesh Bandewar (महेश बंडेवार) @ 2017-09-22 17:11 UTC (permalink / raw)
To: Petar Penkov
Cc: linux-netdev, Eric Dumazet, Willem de Bruijn, David Miller,
Petar Bozhidarov Penkov
In-Reply-To: <20170922021715.2618-2-peterpenkov96@gmail.com>
> #ifdef CONFIG_TUN_VNET_CROSS_LE
> static inline bool tun_legacy_is_little_endian(struct tun_struct *tun)
> {
> @@ -541,6 +604,11 @@ static void __tun_detach(struct tun_file *tfile, bool clean)
>
> tun = rtnl_dereference(tfile->tun);
>
> + if (tun && clean) {
> + tun_napi_disable(tun, tfile);
are we missing synchronize_net() separating disable and del calls?
> + tun_napi_del(tun, tfile);
> + }
> +
> if (tun && !tfile->detached) {
> u16 index = tfile->queue_index;
> BUG_ON(index >= tun->numqueues);
^ permalink raw reply
* [PATCH][V3] e1000: avoid null pointer dereference on invalid stat type
From: Colin King @ 2017-09-22 17:13 UTC (permalink / raw)
To: Jeff Kirsher, intel-wired-lan, netdev; +Cc: kernel-janitors, linux-kernel
From: Colin Ian King <colin.king@canonical.com>
Currently if the stat type is invalid then data[i] is being set
either by dereferencing a null pointer p, or it is reading from
an incorrect previous location if we had a valid stat type
previously. Fix this by skipping over the read of p on an invalid
stat type.
Detected by CoverityScan, CID#113385 ("Explicit null dereferenced")
Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
drivers/net/ethernet/intel/e1000/e1000_ethtool.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
index ec8aa4562cc9..3b3983a1ffbb 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
@@ -1824,11 +1824,12 @@ static void e1000_get_ethtool_stats(struct net_device *netdev,
{
struct e1000_adapter *adapter = netdev_priv(netdev);
int i;
- char *p = NULL;
const struct e1000_stats *stat = e1000_gstrings_stats;
e1000_update_stats(adapter);
- for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) {
+ for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++, stat++) {
+ char *p;
+
switch (stat->type) {
case NETDEV_STATS:
p = (char *)netdev + stat->stat_offset;
@@ -1839,15 +1840,13 @@ static void e1000_get_ethtool_stats(struct net_device *netdev,
default:
WARN_ONCE(1, "Invalid E1000 stat type: %u index %d\n",
stat->type, i);
- break;
+ continue;
}
if (stat->sizeof_stat == sizeof(u64))
data[i] = *(u64 *)p;
else
data[i] = *(u32 *)p;
-
- stat++;
}
/* BUG_ON(i != E1000_STATS_LEN); */
}
--
2.14.1
^ permalink raw reply related
* Re: [PATCH net-next 2/4] net: dsa: remove phy arg from port enable/disable
From: Florian Fainelli @ 2017-09-22 17:14 UTC (permalink / raw)
To: Vivien Didelot, netdev; +Cc: linux-kernel, kernel, David S. Miller, Andrew Lunn
In-Reply-To: <20170922161753.19563-3-vivien.didelot@savoirfairelinux.com>
On 09/22/2017 09:17 AM, Vivien Didelot wrote:
> The .port_enable and .port_disable functions are meant to deal with the
> switch ports only, and no driver is using the phy argument anyway.
> Remove it.
I don't think this makes sense, there are perfectly legit reasons why a
switch driver may have something to do with the PHY device attached to
its per-port network interface, we should definitively keep that around,
unless you think we should be accessing the PHY within the switch
drivers by doing:
struct phy_device *phydev = ds->ports[port].netdev->phydev?
>
> Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
> ---
> drivers/net/dsa/b53/b53_common.c | 6 +++---
> drivers/net/dsa/b53/b53_priv.h | 4 ++--
> drivers/net/dsa/bcm_sf2.c | 16 +++++++---------
> drivers/net/dsa/lan9303-core.c | 6 ++----
> drivers/net/dsa/microchip/ksz_common.c | 6 ++----
> drivers/net/dsa/mt7530.c | 8 +++-----
> drivers/net/dsa/mv88e6xxx/chip.c | 6 ++----
> drivers/net/dsa/qca8k.c | 6 ++----
> include/net/dsa.h | 6 ++----
> net/dsa/slave.c | 4 ++--
> 10 files changed, 27 insertions(+), 41 deletions(-)
>
> diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
> index d4ce092def83..e46eb29d29f0 100644
> --- a/drivers/net/dsa/b53/b53_common.c
> +++ b/drivers/net/dsa/b53/b53_common.c
> @@ -502,7 +502,7 @@ void b53_imp_vlan_setup(struct dsa_switch *ds, int cpu_port)
> }
> EXPORT_SYMBOL(b53_imp_vlan_setup);
>
> -int b53_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy)
> +int b53_enable_port(struct dsa_switch *ds, int port)
> {
> struct b53_device *dev = ds->priv;
> unsigned int cpu_port = dev->cpu_port;
> @@ -531,7 +531,7 @@ int b53_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy)
> }
> EXPORT_SYMBOL(b53_enable_port);
>
> -void b53_disable_port(struct dsa_switch *ds, int port, struct phy_device *phy)
> +void b53_disable_port(struct dsa_switch *ds, int port)
> {
> struct b53_device *dev = ds->priv;
> u8 reg;
> @@ -874,7 +874,7 @@ static int b53_setup(struct dsa_switch *ds)
> if (dsa_is_cpu_port(ds, port))
> b53_enable_cpu_port(dev, port);
> else if (!(BIT(port) & ds->enabled_port_mask))
> - b53_disable_port(ds, port, NULL);
> + b53_disable_port(ds, port);
> }
>
> return ret;
> diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h
> index 603c66d240d8..688d02ee6155 100644
> --- a/drivers/net/dsa/b53/b53_priv.h
> +++ b/drivers/net/dsa/b53/b53_priv.h
> @@ -311,8 +311,8 @@ int b53_mirror_add(struct dsa_switch *ds, int port,
> struct dsa_mall_mirror_tc_entry *mirror, bool ingress);
> void b53_mirror_del(struct dsa_switch *ds, int port,
> struct dsa_mall_mirror_tc_entry *mirror);
> -int b53_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy);
> -void b53_disable_port(struct dsa_switch *ds, int port, struct phy_device *phy);
> +int b53_enable_port(struct dsa_switch *ds, int port);
> +void b53_disable_port(struct dsa_switch *ds, int port);
> void b53_brcm_hdr_setup(struct dsa_switch *ds, int port);
> void b53_eee_enable_set(struct dsa_switch *ds, int port, bool enable);
> int b53_eee_init(struct dsa_switch *ds, int port, struct phy_device *phy);
> diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
> index ad96b9725a2c..77e0c43f973b 100644
> --- a/drivers/net/dsa/bcm_sf2.c
> +++ b/drivers/net/dsa/bcm_sf2.c
> @@ -159,8 +159,7 @@ static inline void bcm_sf2_port_intr_disable(struct bcm_sf2_priv *priv,
> intrl2_1_writel(priv, P_IRQ_MASK(off), INTRL2_CPU_CLEAR);
> }
>
> -static int bcm_sf2_port_setup(struct dsa_switch *ds, int port,
> - struct phy_device *phy)
> +static int bcm_sf2_port_setup(struct dsa_switch *ds, int port)
> {
> struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
> unsigned int i;
> @@ -191,11 +190,10 @@ static int bcm_sf2_port_setup(struct dsa_switch *ds, int port,
> if (port == priv->moca_port)
> bcm_sf2_port_intr_enable(priv, port);
>
> - return b53_enable_port(ds, port, phy);
> + return b53_enable_port(ds, port);
> }
>
> -static void bcm_sf2_port_disable(struct dsa_switch *ds, int port,
> - struct phy_device *phy)
> +static void bcm_sf2_port_disable(struct dsa_switch *ds, int port)
> {
> struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
> u32 off, reg;
> @@ -214,7 +212,7 @@ static void bcm_sf2_port_disable(struct dsa_switch *ds, int port,
> else
> off = CORE_G_PCTL_PORT(port);
>
> - b53_disable_port(ds, port, phy);
> + b53_disable_port(ds, port);
>
> /* Power down the port memory */
> reg = core_readl(priv, CORE_MEM_PSM_VDD_CTRL);
> @@ -613,7 +611,7 @@ static int bcm_sf2_sw_suspend(struct dsa_switch *ds)
> for (port = 0; port < DSA_MAX_PORTS; port++) {
> if ((1 << port) & ds->enabled_port_mask ||
> dsa_is_cpu_port(ds, port))
> - bcm_sf2_port_disable(ds, port, NULL);
> + bcm_sf2_port_disable(ds, port);
> }
>
> return 0;
> @@ -636,7 +634,7 @@ static int bcm_sf2_sw_resume(struct dsa_switch *ds)
>
> for (port = 0; port < DSA_MAX_PORTS; port++) {
> if ((1 << port) & ds->enabled_port_mask)
> - bcm_sf2_port_setup(ds, port, NULL);
> + bcm_sf2_port_setup(ds, port);
> else if (dsa_is_cpu_port(ds, port))
> bcm_sf2_imp_setup(ds, port);
> }
> @@ -745,7 +743,7 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds)
> if (dsa_is_cpu_port(ds, port))
> bcm_sf2_imp_setup(ds, port);
> else if (!((1 << port) & ds->enabled_port_mask))
> - bcm_sf2_port_disable(ds, port, NULL);
> + bcm_sf2_port_disable(ds, port);
> }
>
> bcm_sf2_sw_configure_vlan(ds);
> diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
> index 07355db2ad81..0c33b02562dc 100644
> --- a/drivers/net/dsa/lan9303-core.c
> +++ b/drivers/net/dsa/lan9303-core.c
> @@ -799,8 +799,7 @@ static void lan9303_adjust_link(struct dsa_switch *ds, int port,
> }
> }
>
> -static int lan9303_port_enable(struct dsa_switch *ds, int port,
> - struct phy_device *phy)
> +static int lan9303_port_enable(struct dsa_switch *ds, int port)
> {
> struct lan9303 *chip = ds->priv;
>
> @@ -817,8 +816,7 @@ static int lan9303_port_enable(struct dsa_switch *ds, int port,
> return -ENODEV;
> }
>
> -static void lan9303_port_disable(struct dsa_switch *ds, int port,
> - struct phy_device *phy)
> +static void lan9303_port_disable(struct dsa_switch *ds, int port)
> {
> struct lan9303 *chip = ds->priv;
>
> diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
> index 56cd6d365352..4095c50ae111 100644
> --- a/drivers/net/dsa/microchip/ksz_common.c
> +++ b/drivers/net/dsa/microchip/ksz_common.c
> @@ -418,8 +418,7 @@ static int ksz_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val)
> return 0;
> }
>
> -static int ksz_enable_port(struct dsa_switch *ds, int port,
> - struct phy_device *phy)
> +static int ksz_enable_port(struct dsa_switch *ds, int port)
> {
> struct ksz_device *dev = ds->priv;
>
> @@ -429,8 +428,7 @@ static int ksz_enable_port(struct dsa_switch *ds, int port,
> return 0;
> }
>
> -static void ksz_disable_port(struct dsa_switch *ds, int port,
> - struct phy_device *phy)
> +static void ksz_disable_port(struct dsa_switch *ds, int port)
> {
> struct ksz_device *dev = ds->priv;
>
> diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
> index faa3b88d2206..0a7f6209767f 100644
> --- a/drivers/net/dsa/mt7530.c
> +++ b/drivers/net/dsa/mt7530.c
> @@ -693,8 +693,7 @@ mt7530_cpu_port_enable(struct mt7530_priv *priv,
> }
>
> static int
> -mt7530_port_enable(struct dsa_switch *ds, int port,
> - struct phy_device *phy)
> +mt7530_port_enable(struct dsa_switch *ds, int port)
> {
> struct mt7530_priv *priv = ds->priv;
>
> @@ -719,8 +718,7 @@ mt7530_port_enable(struct dsa_switch *ds, int port,
> }
>
> static void
> -mt7530_port_disable(struct dsa_switch *ds, int port,
> - struct phy_device *phy)
> +mt7530_port_disable(struct dsa_switch *ds, int port)
> {
> struct mt7530_priv *priv = ds->priv;
>
> @@ -1006,7 +1004,7 @@ mt7530_setup(struct dsa_switch *ds)
> if (dsa_is_cpu_port(ds, i))
> mt7530_cpu_port_enable(priv, i);
> else
> - mt7530_port_disable(ds, i, NULL);
> + mt7530_port_disable(ds, i);
> }
>
> /* Flush the FDB table */
> diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
> index c6678aa9b4ef..e47898fb7dbc 100644
> --- a/drivers/net/dsa/mv88e6xxx/chip.c
> +++ b/drivers/net/dsa/mv88e6xxx/chip.c
> @@ -1862,8 +1862,7 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
> return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN, 0);
> }
>
> -static int mv88e6xxx_port_enable(struct dsa_switch *ds, int port,
> - struct phy_device *phydev)
> +static int mv88e6xxx_port_enable(struct dsa_switch *ds, int port)
> {
> struct mv88e6xxx_chip *chip = ds->priv;
> int err;
> @@ -1875,8 +1874,7 @@ static int mv88e6xxx_port_enable(struct dsa_switch *ds, int port,
> return err;
> }
>
> -static void mv88e6xxx_port_disable(struct dsa_switch *ds, int port,
> - struct phy_device *phydev)
> +static void mv88e6xxx_port_disable(struct dsa_switch *ds, int port)
> {
> struct mv88e6xxx_chip *chip = ds->priv;
>
> diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
> index 82f09711ac1a..622ee9b8e72b 100644
> --- a/drivers/net/dsa/qca8k.c
> +++ b/drivers/net/dsa/qca8k.c
> @@ -743,8 +743,7 @@ qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br)
> }
>
> static int
> -qca8k_port_enable(struct dsa_switch *ds, int port,
> - struct phy_device *phy)
> +qca8k_port_enable(struct dsa_switch *ds, int port)
> {
> struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
>
> @@ -755,8 +754,7 @@ qca8k_port_enable(struct dsa_switch *ds, int port,
> }
>
> static void
> -qca8k_port_disable(struct dsa_switch *ds, int port,
> - struct phy_device *phy)
> +qca8k_port_disable(struct dsa_switch *ds, int port)
> {
> struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
>
> diff --git a/include/net/dsa.h b/include/net/dsa.h
> index 8dee216a5a9b..65b031a69c19 100644
> --- a/include/net/dsa.h
> +++ b/include/net/dsa.h
> @@ -337,10 +337,8 @@ struct dsa_switch_ops {
> /*
> * Port enable/disable
> */
> - int (*port_enable)(struct dsa_switch *ds, int port,
> - struct phy_device *phy);
> - void (*port_disable)(struct dsa_switch *ds, int port,
> - struct phy_device *phy);
> + int (*port_enable)(struct dsa_switch *ds, int port);
> + void (*port_disable)(struct dsa_switch *ds, int port);
>
> /*
> * Port's MAC EEE settings
> diff --git a/net/dsa/slave.c b/net/dsa/slave.c
> index 606812160fd5..6290741e496a 100644
> --- a/net/dsa/slave.c
> +++ b/net/dsa/slave.c
> @@ -100,7 +100,7 @@ static int dsa_slave_open(struct net_device *dev)
> }
>
> if (ds->ops->port_enable) {
> - err = ds->ops->port_enable(ds, p->dp->index, p->phy);
> + err = ds->ops->port_enable(ds, p->dp->index);
> if (err)
> goto clear_promisc;
> }
> @@ -155,7 +155,7 @@ static int dsa_slave_close(struct net_device *dev)
> dev_uc_del(master, dev->dev_addr);
>
> if (ds->ops->port_disable)
> - ds->ops->port_disable(ds, p->dp->index, p->phy);
> + ds->ops->port_disable(ds, p->dp->index);
>
> dsa_port_set_state_now(p->dp, BR_STATE_DISABLED);
>
>
--
Florian
^ permalink raw reply
* Re: [PATCH net-next 3/4] net: dsa: make slave close symmetrical to open
From: Florian Fainelli @ 2017-09-22 17:15 UTC (permalink / raw)
To: Vivien Didelot, netdev; +Cc: linux-kernel, kernel, David S. Miller, Andrew Lunn
In-Reply-To: <20170922161753.19563-4-vivien.didelot@savoirfairelinux.com>
On 09/22/2017 09:17 AM, Vivien Didelot wrote:
> The DSA slave open function configures the unicast MAC addresses on the
> master device, enable the switch port, change its STP state, then start
> the PHY device.
>
> Make the close function symmetric, by first stopping the PHY device,
> then changing the STP state, disabling the switch port and restore the
> master device.
>
> Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
--
Florian
^ permalink raw reply
* Re: [PATCH net-next 4/4] net: dsa: add port enable and disable helpers
From: Florian Fainelli @ 2017-09-22 17:16 UTC (permalink / raw)
To: Vivien Didelot, netdev; +Cc: linux-kernel, kernel, David S. Miller, Andrew Lunn
In-Reply-To: <20170922161753.19563-5-vivien.didelot@savoirfairelinux.com>
On 09/22/2017 09:17 AM, Vivien Didelot wrote:
> Provide dsa_port_enable and dsa_port_disable helpers to respectively
> enable and disable a switch port. This makes the dsa_port_set_state_now
> helper static.
>
> Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
--
Florian
^ permalink raw reply
* Re: [PATCH,v2,net-next 2/2] tun: enable napi_gro_frags() for TUN/TAP driver
From: Petar Penkov @ 2017-09-22 17:48 UTC (permalink / raw)
To: Mahesh Bandewar (महेश बंडेवार)
Cc: Willem de Bruijn, Network Development, Eric Dumazet,
Willem de Bruijn, David Miller, Petar Bozhidarov Penkov
In-Reply-To: <CAF2d9jhng1-jQypPqA1XdQtocBQ9ayJYfGa1UGGvBhGP=CXoaA@mail.gmail.com>
On Fri, Sep 22, 2017 at 9:51 AM, Mahesh Bandewar (महेश बंडेवार)
<maheshb@google.com> wrote:
> On Fri, Sep 22, 2017 at 7:06 AM, Willem de Bruijn
> <willemdebruijn.kernel@gmail.com> wrote:
>>> @@ -2061,6 +2174,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
>>> if (tfile->detached)
>>> return -EINVAL;
>>>
>>> + if ((ifr->ifr_flags & IFF_NAPI_FRAGS) && !capable(CAP_NET_ADMIN))
>>> + return -EPERM;
>>> +
>>
>> This should perhaps be moved into the !dev branch, directly below the
>> ns_capable check.
>>
> Hmm, does that mean fail only on creation but allow to attach if
> exists? That would be wrong, isn't it? Correct me if I'm wrong but we
> want to prevent both these scenarios if user does not have sufficient
> privileges (i.e. NET_ADMIN in init-ns).
>
My understanding is we want to protect both scenarios.
>>> dev = __dev_get_by_name(net, ifr->ifr_name);
>>> if (dev) {
>>> if (ifr->ifr_flags & IFF_TUN_EXCL)
>>> @@ -2185,6 +2301,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
>>> tun->flags = (tun->flags & ~TUN_FEATURES) |
>>> (ifr->ifr_flags & TUN_FEATURES);
>>>
>>> + if (!(tun->flags & IFF_NAPI) || (tun->flags & TUN_TYPE_MASK) != IFF_TAP)
>>> + tun->flags = tun->flags & ~IFF_NAPI_FRAGS;
>>> +
>>
>> Similarly, this check only need to be performed in that branch.
>> Instead of reverting to non-frags mode, a tun_set_iff with the wrong
>> set of flags should probably fail hard.
> Yes, agree, wrong set of flags should fail hard and probably be done
> before attach or open, no?
Agreed, in v3 I will push this check before the conditional so both
branches can be rejected with EINVAL.
^ permalink raw reply
* Re: [PATCH,v2,net-next 2/2] tun: enable napi_gro_frags() for TUN/TAP driver
From: Willem de Bruijn @ 2017-09-22 17:50 UTC (permalink / raw)
To: Petar Penkov
Cc: Mahesh Bandewar (महेश बंडेवार),
Network Development, Eric Dumazet, Willem de Bruijn, David Miller,
Petar Bozhidarov Penkov
In-Reply-To: <CA+DcSEidWRHa1ovXfPOfG3OwQ=NASMt9NbTGpk=-NdC8BJQKhw@mail.gmail.com>
On Fri, Sep 22, 2017 at 1:48 PM, Petar Penkov <peterpenkov96@gmail.com> wrote:
> On Fri, Sep 22, 2017 at 9:51 AM, Mahesh Bandewar (महेश बंडेवार)
> <maheshb@google.com> wrote:
>> On Fri, Sep 22, 2017 at 7:06 AM, Willem de Bruijn
>> <willemdebruijn.kernel@gmail.com> wrote:
>>>> @@ -2061,6 +2174,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
>>>> if (tfile->detached)
>>>> return -EINVAL;
>>>>
>>>> + if ((ifr->ifr_flags & IFF_NAPI_FRAGS) && !capable(CAP_NET_ADMIN))
>>>> + return -EPERM;
>>>> +
>>>
>>> This should perhaps be moved into the !dev branch, directly below the
>>> ns_capable check.
>>>
>> Hmm, does that mean fail only on creation but allow to attach if
>> exists? That would be wrong, isn't it? Correct me if I'm wrong but we
>> want to prevent both these scenarios if user does not have sufficient
>> privileges (i.e. NET_ADMIN in init-ns).
Ok.
>>
> My understanding is we want to protect both scenarios.
>>>> dev = __dev_get_by_name(net, ifr->ifr_name);
>>>> if (dev) {
>>>> if (ifr->ifr_flags & IFF_TUN_EXCL)
>>>> @@ -2185,6 +2301,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
>>>> tun->flags = (tun->flags & ~TUN_FEATURES) |
>>>> (ifr->ifr_flags & TUN_FEATURES);
>>>>
>>>> + if (!(tun->flags & IFF_NAPI) || (tun->flags & TUN_TYPE_MASK) != IFF_TAP)
>>>> + tun->flags = tun->flags & ~IFF_NAPI_FRAGS;
>>>> +
>>>
>>> Similarly, this check only need to be performed in that branch.
>>> Instead of reverting to non-frags mode, a tun_set_iff with the wrong
>>> set of flags should probably fail hard.
>> Yes, agree, wrong set of flags should fail hard and probably be done
>> before attach or open, no?
> Agreed, in v3 I will push this check before the conditional so both
> branches can be rejected with EINVAL.
Sounds great.
^ permalink raw reply
* Re: [PATCH] Add a driver for Renesas uPD60620 and uPD60620A PHYs
From: Andrew Lunn @ 2017-09-22 17:59 UTC (permalink / raw)
To: Bernd Edlinger; +Cc: netdev@vger.kernel.org, Florian Fainelli
In-Reply-To: <AM5PR0701MB26574EBBE4E7CACC9173B345E4670@AM5PR0701MB2657.eurprd07.prod.outlook.com>
On Fri, Sep 22, 2017 at 05:08:45PM +0000, Bernd Edlinger wrote:
> Signed-off-by: Bernd Edlinger <bernd.edlinger@hotmail.de>
> ---
> drivers/net/phy/Kconfig | 5 +
> drivers/net/phy/Makefile | 1 +
> drivers/net/phy/uPD60620.c | 226
> +++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 232 insertions(+)
> create mode 100644 drivers/net/phy/uPD60620.c
>
> diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
> index a9d16a3..25089f0 100644
> --- a/drivers/net/phy/Kconfig
> +++ b/drivers/net/phy/Kconfig
> @@ -287,6 +287,11 @@ config DP83867_PHY
> ---help---
> Currently supports the DP83867 PHY.
>
> +config RENESAS_PHY
> + tristate "Driver for Renesas PHYs"
> + ---help---
> + Supports the uPD60620 and uPD60620A PHYs.
> +
Hi Bernd
Please call this "Reneseas PHYs" and place in it alphabetical order.
> config FIXED_PHY
> tristate "MDIO Bus/PHY emulation with fixed speed/link PHYs"
> depends on PHYLIB
> diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
> index 416df92..1404ad3 100644
> --- a/drivers/net/phy/Makefile
> +++ b/drivers/net/phy/Makefile
> @@ -72,6 +72,7 @@ obj-$(CONFIG_MICROSEMI_PHY) += mscc.o
> obj-$(CONFIG_NATIONAL_PHY) += national.o
> obj-$(CONFIG_QSEMI_PHY) += qsemi.o
> obj-$(CONFIG_REALTEK_PHY) += realtek.o
> +obj-$(CONFIG_RENESAS_PHY) += uPD60620.o
> obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o
> obj-$(CONFIG_SMSC_PHY) += smsc.o
> obj-$(CONFIG_STE10XP) += ste10Xp.o
> diff --git a/drivers/net/phy/uPD60620.c b/drivers/net/phy/uPD60620.c
> new file mode 100644
> index 0000000..b3d900c
> --- /dev/null
> +++ b/drivers/net/phy/uPD60620.c
> @@ -0,0 +1,226 @@
> +/*
> + * Driver for the Renesas PHY uPD60620.
> + *
> + * Copyright (C) 2015 Softing Industrial Automation GmbH
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/phy.h>
> +
> +#define UPD60620_PHY_ID 0xb8242824
> +
> +/* Extended Registers and values */
> +/* PHY Special Control/Status */
> +#define PHY_PHYSCR 0x1F /* PHY.31 */
> +#define PHY_PHYSCR_10MB 0x0004 /* PHY speed = 10mb */
> +#define PHY_PHYSCR_100MB 0x0008 /* PHY speed = 100mb */
> +#define PHY_PHYSCR_DUPLEX 0x0010 /* PHY Duplex */
> +#define PHY_PHYSCR_RSVD5 0x0020 /* Reserved Bit 5 */
> +#define PHY_PHYSCR_MIIMOD 0x0040 /* Enable 4B5B MII mode */
Are any of these comments actually useful. It seems like the defines
are pretty obvious.
> +#define PHY_PHYSCR_RSVD7 0x0080 /* Reserved Bit 7 */
> +#define PHY_PHYSCR_RSVD8 0x0100 /* Reserved Bit 8 */
> +#define PHY_PHYSCR_RSVD9 0x0200 /* Reserved Bit 9 */
> +#define PHY_PHYSCR_RSVD10 0x0400 /* Reserved Bit 10 */
> +#define PHY_PHYSCR_RSVD11 0x0800 /* Reserved Bit 11 */
> +#define PHY_PHYSCR_ANDONE 0x1000 /* Auto negotiation done */
> +#define PHY_PHYSCR_RSVD13 0x2000 /* Reserved Bit 13 */
> +#define PHY_PHYSCR_RSVD14 0x4000 /* Reserved Bit 14 */
> +#define PHY_PHYSCR_RSVD15 0x8000 /* Reserved Bit 15 */
It looks like the only register you use is SCR and SPM. Maybe delete
all the rest? Or do you plan to add more features making use of these
registers?
> +/* Init PHY */
> +
> +static int upd60620_config_init(struct phy_device *phydev)
> +{
> + /* Enable support for passive HUBs (could be a strap option) */
> + /* PHYMODE: All speeds, HD in parallel detect */
> + return phy_write(phydev, PHY_SPM, 0x0180 | phydev->mdio.addr);
> +}
> +
> +/* Get PHY status from common registers */
> +
> +static int upd60620_read_status(struct phy_device *phydev)
> +{
> + int phy_state;
> +
> + /* Read negotiated state */
> + phy_state = phy_read(phydev, MII_BMSR);
> + if (phy_state < 0)
> + return phy_state;
> +
> + phydev->link = 0;
> + phydev->lp_advertising = 0;
> + phydev->pause = 0;
> + phydev->asym_pause = 0;
> +
> + if (phy_state & BMSR_ANEGCOMPLETE) {
It is worth comparing this against genphy_read_status() which is the
reference implementation. You would normally check if auto negotiation
is enabled, not if it has completed. If it is enabled you read the
current negotiated state, even if it is not completed.
> + phy_state = phy_read(phydev, PHY_PHYSCR);
> + if (phy_state < 0)
> + return phy_state;
> +
> + if (phy_state & (PHY_PHYSCR_10MB | PHY_PHYSCR_100MB)) {
> + phydev->link = 1;
> + phydev->speed = SPEED_10;
> + phydev->duplex = DUPLEX_HALF;
> +
> + if (phy_state & PHY_PHYSCR_100MB)
> + phydev->speed = SPEED_100;
> + if (phy_state & PHY_PHYSCR_DUPLEX)
> + phydev->duplex = DUPLEX_FULL;
> +
> + phy_state = phy_read(phydev, MII_LPA);
> + if (phy_state < 0)
> + return phy_state;
> +
> + phydev->lp_advertising
> + = mii_lpa_to_ethtool_lpa_t(phy_state);
> +
> + if (phydev->duplex == DUPLEX_FULL) {
> + if (phy_state & LPA_PAUSE_CAP)
> + phydev->pause = 1;
> + if (phy_state & LPA_PAUSE_ASYM)
> + phydev->asym_pause = 1;
> + }
> + }
> + } else if (phy_state & BMSR_LSTATUS) {
The else clause is then for a fixed configuration. Since all you are
looking at is BMCR, you can probably just cut/paste from
genphy_read_status().
> + phy_state = phy_read(phydev, MII_BMCR);
> + if (phy_state < 0)
> + return phy_state;
> +
> + if (!(phy_state & BMCR_ANENABLE)) {
> + phydev->link = 1;
> + phydev->speed = SPEED_10;
> + phydev->duplex = DUPLEX_HALF;
> +
> + if (phy_state & BMCR_SPEED100)
> + phydev->speed = SPEED_100;
> + if (phy_state & BMCR_FULLDPLX)
> + phydev->duplex = DUPLEX_FULL;
> + }
> + }
> + return 0;
> +}
Andrew
^ permalink raw reply
* Re: [PATCH,v2,net-next 1/2] tun: enable NAPI for TUN/TAP driver
From: Willem de Bruijn @ 2017-09-22 18:03 UTC (permalink / raw)
To: Mahesh Bandewar (महेश बंडेवार)
Cc: Petar Penkov, linux-netdev, Eric Dumazet, Willem de Bruijn,
David Miller, Petar Bozhidarov Penkov
In-Reply-To: <CAF2d9jh=H1O4JR3u=Rs3ODuQRF-Qp2wzzhAVf3PQ_f_Ox98eKQ@mail.gmail.com>
On Fri, Sep 22, 2017 at 1:11 PM, Mahesh Bandewar (महेश बंडेवार)
<maheshb@google.com> wrote:
>> #ifdef CONFIG_TUN_VNET_CROSS_LE
>> static inline bool tun_legacy_is_little_endian(struct tun_struct *tun)
>> {
>> @@ -541,6 +604,11 @@ static void __tun_detach(struct tun_file *tfile, bool clean)
>>
>> tun = rtnl_dereference(tfile->tun);
>>
>> + if (tun && clean) {
>> + tun_napi_disable(tun, tfile);
> are we missing synchronize_net() separating disable and del calls?
That is not needed here. napi_disable has its own mechanism for waiting
until a napi struct is no longer run. netif_napi_del will call synchronize_net
if needed. These two calls are made one after the other in quite a few drivers.
^ permalink raw reply
* Re: [Intel-wired-lan] [PATCH][V3] e1000: avoid null pointer dereference on invalid stat type
From: Alexander Duyck @ 2017-09-22 18:09 UTC (permalink / raw)
To: Colin King
Cc: Jeff Kirsher, intel-wired-lan, Netdev, kernel-janitors,
linux-kernel@vger.kernel.org
In-Reply-To: <20170922171348.17630-1-colin.king@canonical.com>
On Fri, Sep 22, 2017 at 10:13 AM, Colin King <colin.king@canonical.com> wrote:
> From: Colin Ian King <colin.king@canonical.com>
>
> Currently if the stat type is invalid then data[i] is being set
> either by dereferencing a null pointer p, or it is reading from
> an incorrect previous location if we had a valid stat type
> previously. Fix this by skipping over the read of p on an invalid
> stat type.
>
> Detected by CoverityScan, CID#113385 ("Explicit null dereferenced")
>
> Signed-off-by: Colin Ian King <colin.king@canonical.com>
Looks good to me.
Reviewed-by: Alexander Duyck <alexander.h.duyck@intel.com>
> ---
> drivers/net/ethernet/intel/e1000/e1000_ethtool.c | 9 ++++-----
> 1 file changed, 4 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
> index ec8aa4562cc9..3b3983a1ffbb 100644
> --- a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
> +++ b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
> @@ -1824,11 +1824,12 @@ static void e1000_get_ethtool_stats(struct net_device *netdev,
> {
> struct e1000_adapter *adapter = netdev_priv(netdev);
> int i;
> - char *p = NULL;
> const struct e1000_stats *stat = e1000_gstrings_stats;
>
> e1000_update_stats(adapter);
> - for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) {
> + for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++, stat++) {
> + char *p;
> +
> switch (stat->type) {
> case NETDEV_STATS:
> p = (char *)netdev + stat->stat_offset;
> @@ -1839,15 +1840,13 @@ static void e1000_get_ethtool_stats(struct net_device *netdev,
> default:
> WARN_ONCE(1, "Invalid E1000 stat type: %u index %d\n",
> stat->type, i);
> - break;
> + continue;
> }
>
> if (stat->sizeof_stat == sizeof(u64))
> data[i] = *(u64 *)p;
> else
> data[i] = *(u32 *)p;
> -
> - stat++;
> }
> /* BUG_ON(i != E1000_STATS_LEN); */
> }
> --
> 2.14.1
>
> _______________________________________________
> Intel-wired-lan mailing list
> Intel-wired-lan@osuosl.org
> https://lists.osuosl.org/mailman/listinfo/intel-wired-lan
^ permalink raw reply
* Re: [PATCH net-next 2/4] net: dsa: remove phy arg from port enable/disable
From: Vivien Didelot @ 2017-09-22 18:12 UTC (permalink / raw)
To: Florian Fainelli, netdev
Cc: linux-kernel, kernel, David S. Miller, Andrew Lunn
In-Reply-To: <f8d74c3c-bd7f-8a84-2d57-c37250ff25f8@gmail.com>
Hi Florian,
Florian Fainelli <f.fainelli@gmail.com> writes:
> On 09/22/2017 09:17 AM, Vivien Didelot wrote:
>> The .port_enable and .port_disable functions are meant to deal with the
>> switch ports only, and no driver is using the phy argument anyway.
>> Remove it.
>
> I don't think this makes sense, there are perfectly legit reasons why a
> switch driver may have something to do with the PHY device attached to
> its per-port network interface, we should definitively keep that around,
> unless you think we should be accessing the PHY within the switch
> drivers by doing:
>
> struct phy_device *phydev = ds->ports[port].netdev->phydev?
bcm_sf2 is the only user for this phy argument right now. The reason I'm
doing this is because I prefer to discourage switch drivers to dig into
the phy device themselves while as you said there must be a cleaner
solution. This must be handled somehow elsewhere in the stack.
In the meantime, moving the PHY device up to the dsa_port structure is a
good solution, in order not to expose it in switch ops, but still make
it available to more complex drivers.
Do you know if netdev->phydev is usable? Why do DSA has its own copy in
dsa_slave_priv then?
I'll respin, thanks.
Vivien
^ permalink raw reply
* Re: [PATCH,v2,net-next 1/2] tun: enable NAPI for TUN/TAP driver
From: Mahesh Bandewar (महेश बंडेवार) @ 2017-09-22 18:12 UTC (permalink / raw)
To: Willem de Bruijn
Cc: Petar Penkov, linux-netdev, Eric Dumazet, Willem de Bruijn,
David Miller, Petar Bozhidarov Penkov
In-Reply-To: <CAF=yD-Ldc_K+MTd_wXNjvvQ-+UsjZOs+13irmRoGJzJmq5yfVA@mail.gmail.com>
On Fri, Sep 22, 2017 at 11:03 AM, Willem de Bruijn
<willemdebruijn.kernel@gmail.com> wrote:
> On Fri, Sep 22, 2017 at 1:11 PM, Mahesh Bandewar (महेश बंडेवार)
> <maheshb@google.com> wrote:
>>> #ifdef CONFIG_TUN_VNET_CROSS_LE
>>> static inline bool tun_legacy_is_little_endian(struct tun_struct *tun)
>>> {
>>> @@ -541,6 +604,11 @@ static void __tun_detach(struct tun_file *tfile, bool clean)
>>>
>>> tun = rtnl_dereference(tfile->tun);
>>>
>>> + if (tun && clean) {
>>> + tun_napi_disable(tun, tfile);
>> are we missing synchronize_net() separating disable and del calls?
>
> That is not needed here. napi_disable has its own mechanism for waiting
> until a napi struct is no longer run. netif_napi_del will call synchronize_net
> if needed.
Yes, that will do. Thanks.
> These two calls are made one after the other in quite a few drivers.
^ permalink raw reply
* Re: [PATCH net-next 2/4] net: dsa: remove phy arg from port enable/disable
From: Florian Fainelli @ 2017-09-22 18:23 UTC (permalink / raw)
To: Vivien Didelot, netdev; +Cc: linux-kernel, kernel, David S. Miller, Andrew Lunn
In-Reply-To: <87377eob5t.fsf@weeman.i-did-not-set--mail-host-address--so-tickle-me>
On 09/22/2017 11:12 AM, Vivien Didelot wrote:
> Hi Florian,
>
> Florian Fainelli <f.fainelli@gmail.com> writes:
>
>> On 09/22/2017 09:17 AM, Vivien Didelot wrote:
>>> The .port_enable and .port_disable functions are meant to deal with the
>>> switch ports only, and no driver is using the phy argument anyway.
>>> Remove it.
>>
>> I don't think this makes sense, there are perfectly legit reasons why a
>> switch driver may have something to do with the PHY device attached to
>> its per-port network interface, we should definitively keep that around,
>> unless you think we should be accessing the PHY within the switch
>> drivers by doing:
>>
>> struct phy_device *phydev = ds->ports[port].netdev->phydev?
>
> bcm_sf2 is the only user for this phy argument right now. The reason I'm
> doing this is because I prefer to discourage switch drivers to dig into
> the phy device themselves while as you said there must be a cleaner
> solution. This must be handled somehow elsewhere in the stack.
The current approach of passing the phy_device reference as an argument
is certainly a cleaner way then. The port_enable caller can provide the
correct phy_device and that lifts the switch driver from having to dig
it itself from its per-port netdev.
>
> In the meantime, moving the PHY device up to the dsa_port structure is a
> good solution, in order not to expose it in switch ops, but still make
> it available to more complex drivers.
>
> Do you know if netdev->phydev is usable? Why do DSA has its own copy in
> dsa_slave_priv then?
Historical reasons mostly. Considering the complexity of
dsa_slave_phy_setup(), I would certainly be extremely careful in
changing any of this, the potential for breakage is pretty big. At first
glance, I would say that this is a safe conversion to do, and I can test
this on the HW I have here anyway.
--
Florian
^ permalink raw reply
* [PATCH] r8152: add Linksys USB3GIGV1 id
From: Grant Grundler @ 2017-09-22 19:06 UTC (permalink / raw)
To: Hayes Wang
Cc: linux-usb, David S . Miller, LKML, netdev-u79uwXL29TY76Z2rM5mHXA,
Grant Grundler
This Linksys dongle by default comes up in cdc_ether mode.
This patch allows r8152 to claim the device:
Bus 002 Device 002: ID 13b1:0041 Linksys
Signed-off-by: Grant Grundler <grundler-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
---
drivers/net/usb/r8152.c | 2 ++
1 file changed, 2 insertions(+)
This was tested on chromeos-3.14, chromeos-3.18, and chromeos-4.4 kernels
with a mix of ARM/x86-64 systems.
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index ceb78e2ea4f0..941ece08ba78 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -613,6 +613,7 @@ enum rtl8152_flags {
#define VENDOR_ID_MICROSOFT 0x045e
#define VENDOR_ID_SAMSUNG 0x04e8
#define VENDOR_ID_LENOVO 0x17ef
+#define VENDOR_ID_LINKSYS 0x13b1
#define VENDOR_ID_NVIDIA 0x0955
#define MCU_TYPE_PLA 0x0100
@@ -5316,6 +5317,7 @@ static const struct usb_device_id rtl8152_table[] = {
{REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7205)},
{REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x720c)},
{REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7214)},
+ {REALTEK_USB_DEVICE(VENDOR_ID_LINKSYS, 0x0041)},
{REALTEK_USB_DEVICE(VENDOR_ID_NVIDIA, 0x09ff)},
{}
};
--
2.14.1.821.g8fa685d3b7-goog
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH net-next 2/4] net: dsa: remove phy arg from port enable/disable
From: Andrew Lunn @ 2017-09-22 19:11 UTC (permalink / raw)
To: Florian Fainelli
Cc: Vivien Didelot, netdev, linux-kernel, kernel, David S. Miller
In-Reply-To: <6d7799bb-2b33-0696-1805-63cea5e52667@gmail.com>
> Historical reasons mostly. Considering the complexity of
> dsa_slave_phy_setup(), I would certainly be extremely careful in
> changing any of this, the potential for breakage is pretty big.
Yes, i took a look at this, wondering how to convert to phylink. I
went away and got a stiff drink :-)
Andrew
^ permalink raw reply
* [PATCH net-next v2 0/3] net: dsa: use slave device phydev
From: Vivien Didelot @ 2017-09-22 19:40 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
Andrew Lunn, Vivien Didelot
This patchset removes the private phy_device in favor of the one
provided by the slave net_device, makes slave open and close symmetrical
and finally provides helpers for enabling or disabling a DSA port.
Changes in v2:
- do not remove the phy argument from port enable/disable
Vivien Didelot (3):
net: dsa: use slave device phydev
net: dsa: make slave close symmetrical to open
net: dsa: add port enable and disable helpers
net/dsa/dsa_priv.h | 3 +-
net/dsa/port.c | 31 +++++++++++-
net/dsa/slave.c | 143 +++++++++++++++++++++++------------------------------
3 files changed, 94 insertions(+), 83 deletions(-)
--
2.14.1
^ permalink raw reply
* [PATCH net-next v2 1/3] net: dsa: use slave device phydev
From: Vivien Didelot @ 2017-09-22 19:40 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
Andrew Lunn, Vivien Didelot
In-Reply-To: <20170922194045.18814-1-vivien.didelot@savoirfairelinux.com>
There is no need to store a phy_device in dsa_slave_priv since
net_device already provides one. Simply s/p->phy/dev->phydev/.
While at it, return -ENODEV when it is NULL instead of -EOPNOTSUPP.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
net/dsa/slave.c | 126 ++++++++++++++++++++++++++------------------------------
1 file changed, 58 insertions(+), 68 deletions(-)
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 02ace7d462c4..3760472bf41d 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -99,15 +99,15 @@ static int dsa_slave_open(struct net_device *dev)
}
if (ds->ops->port_enable) {
- err = ds->ops->port_enable(ds, p->dp->index, p->phy);
+ err = ds->ops->port_enable(ds, p->dp->index, dev->phydev);
if (err)
goto clear_promisc;
}
dsa_port_set_state_now(p->dp, stp_state);
- if (p->phy)
- phy_start(p->phy);
+ if (dev->phydev)
+ phy_start(dev->phydev);
return 0;
@@ -130,8 +130,8 @@ static int dsa_slave_close(struct net_device *dev)
struct net_device *master = dsa_master_netdev(p);
struct dsa_switch *ds = p->dp->ds;
- if (p->phy)
- phy_stop(p->phy);
+ if (dev->phydev)
+ phy_stop(dev->phydev);
dev_mc_unsync(master, dev);
dev_uc_unsync(master, dev);
@@ -144,7 +144,7 @@ static int dsa_slave_close(struct net_device *dev)
dev_uc_del(master, dev->dev_addr);
if (ds->ops->port_disable)
- ds->ops->port_disable(ds, p->dp->index, p->phy);
+ ds->ops->port_disable(ds, p->dp->index, dev->phydev);
dsa_port_set_state_now(p->dp, BR_STATE_DISABLED);
@@ -273,12 +273,10 @@ dsa_slave_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
static int dsa_slave_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
- struct dsa_slave_priv *p = netdev_priv(dev);
+ if (!dev->phydev)
+ return -ENODEV;
- if (p->phy != NULL)
- return phy_mii_ioctl(p->phy, ifr, cmd);
-
- return -EOPNOTSUPP;
+ return phy_mii_ioctl(dev->phydev, ifr, cmd);
}
static int dsa_slave_port_attr_set(struct net_device *dev,
@@ -435,12 +433,10 @@ static int
dsa_slave_get_link_ksettings(struct net_device *dev,
struct ethtool_link_ksettings *cmd)
{
- struct dsa_slave_priv *p = netdev_priv(dev);
+ if (!dev->phydev)
+ return -ENODEV;
- if (!p->phy)
- return -EOPNOTSUPP;
-
- phy_ethtool_ksettings_get(p->phy, cmd);
+ phy_ethtool_ksettings_get(dev->phydev, cmd);
return 0;
}
@@ -449,12 +445,10 @@ static int
dsa_slave_set_link_ksettings(struct net_device *dev,
const struct ethtool_link_ksettings *cmd)
{
- struct dsa_slave_priv *p = netdev_priv(dev);
+ if (!dev->phydev)
+ return -ENODEV;
- if (p->phy != NULL)
- return phy_ethtool_ksettings_set(p->phy, cmd);
-
- return -EOPNOTSUPP;
+ return phy_ethtool_ksettings_set(dev->phydev, cmd);
}
static void dsa_slave_get_drvinfo(struct net_device *dev,
@@ -488,24 +482,20 @@ dsa_slave_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *_p)
static int dsa_slave_nway_reset(struct net_device *dev)
{
- struct dsa_slave_priv *p = netdev_priv(dev);
+ if (!dev->phydev)
+ return -ENODEV;
- if (p->phy != NULL)
- return genphy_restart_aneg(p->phy);
-
- return -EOPNOTSUPP;
+ return genphy_restart_aneg(dev->phydev);
}
static u32 dsa_slave_get_link(struct net_device *dev)
{
- struct dsa_slave_priv *p = netdev_priv(dev);
+ if (!dev->phydev)
+ return -ENODEV;
- if (p->phy != NULL) {
- genphy_update_link(p->phy);
- return p->phy->link;
- }
+ genphy_update_link(dev->phydev);
- return -EOPNOTSUPP;
+ return dev->phydev->link;
}
static int dsa_slave_get_eeprom_len(struct net_device *dev)
@@ -640,7 +630,7 @@ static int dsa_slave_set_eee(struct net_device *dev, struct ethtool_eee *e)
int ret;
/* Port's PHY and MAC both need to be EEE capable */
- if (!p->phy)
+ if (!dev->phydev)
return -ENODEV;
if (!ds->ops->set_mac_eee)
@@ -651,12 +641,12 @@ static int dsa_slave_set_eee(struct net_device *dev, struct ethtool_eee *e)
return ret;
if (e->eee_enabled) {
- ret = phy_init_eee(p->phy, 0);
+ ret = phy_init_eee(dev->phydev, 0);
if (ret)
return ret;
}
- return phy_ethtool_set_eee(p->phy, e);
+ return phy_ethtool_set_eee(dev->phydev, e);
}
static int dsa_slave_get_eee(struct net_device *dev, struct ethtool_eee *e)
@@ -666,7 +656,7 @@ static int dsa_slave_get_eee(struct net_device *dev, struct ethtool_eee *e)
int ret;
/* Port's PHY and MAC both need to be EEE capable */
- if (!p->phy)
+ if (!dev->phydev)
return -ENODEV;
if (!ds->ops->get_mac_eee)
@@ -676,7 +666,7 @@ static int dsa_slave_get_eee(struct net_device *dev, struct ethtool_eee *e)
if (ret)
return ret;
- return phy_ethtool_get_eee(p->phy, e);
+ return phy_ethtool_get_eee(dev->phydev, e);
}
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -985,26 +975,26 @@ static void dsa_slave_adjust_link(struct net_device *dev)
struct dsa_switch *ds = p->dp->ds;
unsigned int status_changed = 0;
- if (p->old_link != p->phy->link) {
+ if (p->old_link != dev->phydev->link) {
status_changed = 1;
- p->old_link = p->phy->link;
+ p->old_link = dev->phydev->link;
}
- if (p->old_duplex != p->phy->duplex) {
+ if (p->old_duplex != dev->phydev->duplex) {
status_changed = 1;
- p->old_duplex = p->phy->duplex;
+ p->old_duplex = dev->phydev->duplex;
}
- if (p->old_pause != p->phy->pause) {
+ if (p->old_pause != dev->phydev->pause) {
status_changed = 1;
- p->old_pause = p->phy->pause;
+ p->old_pause = dev->phydev->pause;
}
if (ds->ops->adjust_link && status_changed)
- ds->ops->adjust_link(ds, p->dp->index, p->phy);
+ ds->ops->adjust_link(ds, p->dp->index, dev->phydev);
if (status_changed)
- phy_print_status(p->phy);
+ phy_print_status(dev->phydev);
}
static int dsa_slave_fixed_link_update(struct net_device *dev,
@@ -1029,17 +1019,18 @@ static int dsa_slave_phy_connect(struct net_device *slave_dev, int addr)
struct dsa_slave_priv *p = netdev_priv(slave_dev);
struct dsa_switch *ds = p->dp->ds;
- p->phy = mdiobus_get_phy(ds->slave_mii_bus, addr);
- if (!p->phy) {
+ slave_dev->phydev = mdiobus_get_phy(ds->slave_mii_bus, addr);
+ if (!slave_dev->phydev) {
netdev_err(slave_dev, "no phy at %d\n", addr);
return -ENODEV;
}
/* Use already configured phy mode */
if (p->phy_interface == PHY_INTERFACE_MODE_NA)
- p->phy_interface = p->phy->interface;
- return phy_connect_direct(slave_dev, p->phy, dsa_slave_adjust_link,
- p->phy_interface);
+ p->phy_interface = slave_dev->phydev->interface;
+
+ return phy_connect_direct(slave_dev, slave_dev->phydev,
+ dsa_slave_adjust_link, p->phy_interface);
}
static int dsa_slave_phy_setup(struct net_device *slave_dev)
@@ -1091,22 +1082,23 @@ static int dsa_slave_phy_setup(struct net_device *slave_dev)
return ret;
}
} else {
- p->phy = of_phy_connect(slave_dev, phy_dn,
- dsa_slave_adjust_link,
- phy_flags,
- p->phy_interface);
+ slave_dev->phydev = of_phy_connect(slave_dev, phy_dn,
+ dsa_slave_adjust_link,
+ phy_flags,
+ p->phy_interface);
}
of_node_put(phy_dn);
}
- if (p->phy && phy_is_fixed)
- fixed_phy_set_link_update(p->phy, dsa_slave_fixed_link_update);
+ if (slave_dev->phydev && phy_is_fixed)
+ fixed_phy_set_link_update(slave_dev->phydev,
+ dsa_slave_fixed_link_update);
/* We could not connect to a designated PHY, so use the switch internal
* MDIO bus instead
*/
- if (!p->phy) {
+ if (!slave_dev->phydev) {
ret = dsa_slave_phy_connect(slave_dev, p->dp->index);
if (ret) {
netdev_err(slave_dev, "failed to connect to port %d: %d\n",
@@ -1117,7 +1109,7 @@ static int dsa_slave_phy_setup(struct net_device *slave_dev)
}
}
- phy_attached_info(p->phy);
+ phy_attached_info(slave_dev->phydev);
return 0;
}
@@ -1137,12 +1129,12 @@ int dsa_slave_suspend(struct net_device *slave_dev)
netif_device_detach(slave_dev);
- if (p->phy) {
- phy_stop(p->phy);
+ if (slave_dev->phydev) {
+ phy_stop(slave_dev->phydev);
p->old_pause = -1;
p->old_link = -1;
p->old_duplex = -1;
- phy_suspend(p->phy);
+ phy_suspend(slave_dev->phydev);
}
return 0;
@@ -1150,13 +1142,11 @@ int dsa_slave_suspend(struct net_device *slave_dev)
int dsa_slave_resume(struct net_device *slave_dev)
{
- struct dsa_slave_priv *p = netdev_priv(slave_dev);
-
netif_device_attach(slave_dev);
- if (p->phy) {
- phy_resume(p->phy);
- phy_start(p->phy);
+ if (slave_dev->phydev) {
+ phy_resume(slave_dev->phydev);
+ phy_start(slave_dev->phydev);
}
return 0;
@@ -1249,8 +1239,8 @@ void dsa_slave_destroy(struct net_device *slave_dev)
port_dn = p->dp->dn;
netif_carrier_off(slave_dev);
- if (p->phy) {
- phy_disconnect(p->phy);
+ if (slave_dev->phydev) {
+ phy_disconnect(slave_dev->phydev);
if (of_phy_is_fixed_link(port_dn))
of_phy_deregister_fixed_link(port_dn);
--
2.14.1
^ permalink raw reply related
* [PATCH net-next v2 2/3] net: dsa: make slave close symmetrical to open
From: Vivien Didelot @ 2017-09-22 19:40 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
Andrew Lunn, Vivien Didelot
In-Reply-To: <20170922194045.18814-1-vivien.didelot@savoirfairelinux.com>
The DSA slave open function configures the unicast MAC addresses on the
master device, enable the switch port, change its STP state, then start
the PHY device.
Make the close function symmetric, by first stopping the PHY device,
then changing the STP state, disabling the switch port and restore the
master device.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
---
net/dsa/slave.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 3760472bf41d..0aab29928152 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -133,6 +133,11 @@ static int dsa_slave_close(struct net_device *dev)
if (dev->phydev)
phy_stop(dev->phydev);
+ dsa_port_set_state_now(p->dp, BR_STATE_DISABLED);
+
+ if (ds->ops->port_disable)
+ ds->ops->port_disable(ds, p->dp->index, dev->phydev);
+
dev_mc_unsync(master, dev);
dev_uc_unsync(master, dev);
if (dev->flags & IFF_ALLMULTI)
@@ -143,11 +148,6 @@ static int dsa_slave_close(struct net_device *dev)
if (!ether_addr_equal(dev->dev_addr, master->dev_addr))
dev_uc_del(master, dev->dev_addr);
- if (ds->ops->port_disable)
- ds->ops->port_disable(ds, p->dp->index, dev->phydev);
-
- dsa_port_set_state_now(p->dp, BR_STATE_DISABLED);
-
return 0;
}
--
2.14.1
^ permalink raw reply related
* [PATCH net-next v2 3/3] net: dsa: add port enable and disable helpers
From: Vivien Didelot @ 2017-09-22 19:40 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
Andrew Lunn, Vivien Didelot
In-Reply-To: <20170922194045.18814-1-vivien.didelot@savoirfairelinux.com>
Provide dsa_port_enable and dsa_port_disable helpers to respectively
enable and disable a switch port. This makes the dsa_port_set_state_now
helper static.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
---
net/dsa/dsa_priv.h | 3 ++-
net/dsa/port.c | 31 ++++++++++++++++++++++++++++++-
net/dsa/slave.c | 19 +++++--------------
3 files changed, 37 insertions(+), 16 deletions(-)
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index 9803952a5b40..0298a0f6a349 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -117,7 +117,8 @@ void dsa_master_ethtool_restore(struct net_device *dev);
/* port.c */
int dsa_port_set_state(struct dsa_port *dp, u8 state,
struct switchdev_trans *trans);
-void dsa_port_set_state_now(struct dsa_port *dp, u8 state);
+int dsa_port_enable(struct dsa_port *dp, struct phy_device *phy);
+void dsa_port_disable(struct dsa_port *dp, struct phy_device *phy);
int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br);
void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br);
int dsa_port_vlan_filtering(struct dsa_port *dp, bool vlan_filtering,
diff --git a/net/dsa/port.c b/net/dsa/port.c
index 76d43a82d397..72c8dbd3d3f2 100644
--- a/net/dsa/port.c
+++ b/net/dsa/port.c
@@ -56,7 +56,7 @@ int dsa_port_set_state(struct dsa_port *dp, u8 state,
return 0;
}
-void dsa_port_set_state_now(struct dsa_port *dp, u8 state)
+static void dsa_port_set_state_now(struct dsa_port *dp, u8 state)
{
int err;
@@ -65,6 +65,35 @@ void dsa_port_set_state_now(struct dsa_port *dp, u8 state)
pr_err("DSA: failed to set STP state %u (%d)\n", state, err);
}
+int dsa_port_enable(struct dsa_port *dp, struct phy_device *phy)
+{
+ u8 stp_state = dp->bridge_dev ? BR_STATE_BLOCKING : BR_STATE_FORWARDING;
+ struct dsa_switch *ds = dp->ds;
+ int port = dp->index;
+ int err;
+
+ if (ds->ops->port_enable) {
+ err = ds->ops->port_enable(ds, port, phy);
+ if (err)
+ return err;
+ }
+
+ dsa_port_set_state_now(dp, stp_state);
+
+ return 0;
+}
+
+void dsa_port_disable(struct dsa_port *dp, struct phy_device *phy)
+{
+ struct dsa_switch *ds = dp->ds;
+ int port = dp->index;
+
+ dsa_port_set_state_now(dp, BR_STATE_DISABLED);
+
+ if (ds->ops->port_disable)
+ ds->ops->port_disable(ds, port, phy);
+}
+
int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br)
{
struct dsa_notifier_bridge_info info = {
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 0aab29928152..4ea1c6eb0da8 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -73,9 +73,7 @@ static int dsa_slave_open(struct net_device *dev)
{
struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_port *dp = p->dp;
- struct dsa_switch *ds = dp->ds;
struct net_device *master = dsa_master_netdev(p);
- u8 stp_state = dp->bridge_dev ? BR_STATE_BLOCKING : BR_STATE_FORWARDING;
int err;
if (!(master->flags & IFF_UP))
@@ -98,13 +96,9 @@ static int dsa_slave_open(struct net_device *dev)
goto clear_allmulti;
}
- if (ds->ops->port_enable) {
- err = ds->ops->port_enable(ds, p->dp->index, dev->phydev);
- if (err)
- goto clear_promisc;
- }
-
- dsa_port_set_state_now(p->dp, stp_state);
+ err = dsa_port_enable(dp, dev->phydev);
+ if (err)
+ goto clear_promisc;
if (dev->phydev)
phy_start(dev->phydev);
@@ -128,15 +122,12 @@ static int dsa_slave_close(struct net_device *dev)
{
struct dsa_slave_priv *p = netdev_priv(dev);
struct net_device *master = dsa_master_netdev(p);
- struct dsa_switch *ds = p->dp->ds;
+ struct dsa_port *dp = p->dp;
if (dev->phydev)
phy_stop(dev->phydev);
- dsa_port_set_state_now(p->dp, BR_STATE_DISABLED);
-
- if (ds->ops->port_disable)
- ds->ops->port_disable(ds, p->dp->index, dev->phydev);
+ dsa_port_disable(dp, dev->phydev);
dev_mc_unsync(master, dev);
dev_uc_unsync(master, dev);
--
2.14.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox