* [PATCH v4 5/9] MIPS: PCI: use information from 1-wire PROM for IOC3 detection
From: Thomas Bogendoerfer @ 2019-08-09 10:32 UTC (permalink / raw)
To: Ralf Baechle, Paul Burton, James Hogan, Dmitry Torokhov,
Lee Jones, David S. Miller, Srinivas Kandagatla, Alessandro Zummo,
Alexandre Belloni, Greg Kroah-Hartman, Jiri Slaby,
Evgeniy Polyakov, linux-mips, linux-kernel, linux-input, netdev,
linux-rtc, linux-serial
In-Reply-To: <20190809103235.16338-1-tbogendoerfer@suse.de>
IOC3 chips in SGI system are conntected to a bridge ASIC, which has
a 1-wire prom attached with part number information. This changeset
uses this information to create PCI subsystem information, which
the MFD driver uses for further platform device setup.
Signed-off-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
---
arch/mips/include/asm/pci/bridge.h | 1 +
arch/mips/include/asm/sn/ioc3.h | 9 +++
arch/mips/pci/pci-xtalk-bridge.c | 135 ++++++++++++++++++++++++++++++++++++-
arch/mips/sgi-ip27/ip27-xtalk.c | 38 +++++++++--
4 files changed, 175 insertions(+), 8 deletions(-)
diff --git a/arch/mips/include/asm/pci/bridge.h b/arch/mips/include/asm/pci/bridge.h
index a92cd30b48c9..3bc630ff9ad4 100644
--- a/arch/mips/include/asm/pci/bridge.h
+++ b/arch/mips/include/asm/pci/bridge.h
@@ -807,6 +807,7 @@ struct bridge_controller {
unsigned long intr_addr;
struct irq_domain *domain;
unsigned int pci_int[8];
+ u32 ioc3_sid[8];
nasid_t nasid;
};
diff --git a/arch/mips/include/asm/sn/ioc3.h b/arch/mips/include/asm/sn/ioc3.h
index 25c8dccab51f..5022b0ab2074 100644
--- a/arch/mips/include/asm/sn/ioc3.h
+++ b/arch/mips/include/asm/sn/ioc3.h
@@ -661,4 +661,13 @@ typedef enum ioc3_subdevs_e {
#define IOC3_INTA_SUBDEVS IOC3_SDB_ETHER
#define IOC3_INTB_SUBDEVS (IOC3_SDB_GENERIC|IOC3_SDB_KBMS|IOC3_SDB_SERIAL|IOC3_SDB_ECPP|IOC3_SDB_RT)
+/* subsystem IDs supplied by card detection in pci-xtalk-bridge */
+#define IOC3_SUBSYS_IP27_BASEIO6G 0xc300
+#define IOC3_SUBSYS_IP27_MIO 0xc301
+#define IOC3_SUBSYS_IP27_BASEIO 0xc302
+#define IOC3_SUBSYS_IP29_SYSBOARD 0xc303
+#define IOC3_SUBSYS_IP30_SYSBOARD 0xc304
+#define IOC3_SUBSYS_MENET 0xc305
+#define IOC3_SUBSYS_MENET4 0xc306
+
#endif /* _IOC3_H */
diff --git a/arch/mips/pci/pci-xtalk-bridge.c b/arch/mips/pci/pci-xtalk-bridge.c
index 7b4d40354ee7..dcf6117a17c3 100644
--- a/arch/mips/pci/pci-xtalk-bridge.c
+++ b/arch/mips/pci/pci-xtalk-bridge.c
@@ -11,16 +11,22 @@
#include <linux/dma-direct.h>
#include <linux/platform_device.h>
#include <linux/platform_data/xtalk-bridge.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/crc16.h>
#include <asm/pci/bridge.h>
#include <asm/paccess.h>
#include <asm/sn/irq_alloc.h>
+#include <asm/sn/ioc3.h>
+
+#define CRC16_INIT 0
+#define CRC16_VALID 0xb001
/*
* Most of the IOC3 PCI config register aren't present
* we emulate what is needed for a normal PCI enumeration
*/
-static int ioc3_cfg_rd(void *addr, int where, int size, u32 *value)
+static int ioc3_cfg_rd(void *addr, int where, int size, u32 *value, u32 sid)
{
u32 cf, shift, mask;
@@ -30,6 +36,9 @@ static int ioc3_cfg_rd(void *addr, int where, int size, u32 *value)
if (get_dbe(cf, (u32 *)addr))
return PCIBIOS_DEVICE_NOT_FOUND;
break;
+ case 0x2c:
+ cf = sid;
+ break;
case 0x3c:
/* emulate sane interrupt pin value */
cf = 0x00000100;
@@ -111,7 +120,8 @@ static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn,
*/
if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) {
addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
- return ioc3_cfg_rd(addr, where, size, value);
+ return ioc3_cfg_rd(addr, where, size, value,
+ bc->ioc3_sid[slot]);
}
addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)];
@@ -149,7 +159,8 @@ static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn,
*/
if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) {
addr = &bridge->b_type1_cfg.c[(fn << 8) | (where & ~3)];
- return ioc3_cfg_rd(addr, where, size, value);
+ return ioc3_cfg_rd(addr, where, size, value,
+ bc->ioc3_sid[slot]);
}
addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))];
@@ -426,6 +437,117 @@ static int bridge_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
return irq;
}
+#define IOC3_SID(sid) (PCI_VENDOR_ID_SGI << 16 | (sid))
+
+static void bridge_setup_ip27_baseio6g(struct bridge_controller *bc)
+{
+ bc->ioc3_sid[2] = IOC3_SID(IOC3_SUBSYS_IP27_BASEIO6G);
+ bc->ioc3_sid[6] = IOC3_SID(IOC3_SUBSYS_IP27_MIO);
+}
+
+static void bridge_setup_ip27_baseio(struct bridge_controller *bc)
+{
+ bc->ioc3_sid[2] = IOC3_SID(IOC3_SUBSYS_IP27_BASEIO);
+}
+
+static void bridge_setup_ip29_baseio(struct bridge_controller *bc)
+{
+ bc->ioc3_sid[2] = IOC3_SID(IOC3_SUBSYS_IP29_SYSBOARD);
+}
+
+static void bridge_setup_ip30_sysboard(struct bridge_controller *bc)
+{
+ bc->ioc3_sid[2] = IOC3_SID(IOC3_SUBSYS_IP30_SYSBOARD);
+}
+
+static void bridge_setup_menet(struct bridge_controller *bc)
+{
+ bc->ioc3_sid[0] = IOC3_SID(IOC3_SUBSYS_MENET);
+ bc->ioc3_sid[1] = IOC3_SID(IOC3_SUBSYS_MENET);
+ bc->ioc3_sid[2] = IOC3_SID(IOC3_SUBSYS_MENET);
+ bc->ioc3_sid[3] = IOC3_SID(IOC3_SUBSYS_MENET4);
+}
+
+#define BRIDGE_BOARD_SETUP(_partno, _setup) \
+ { .match = _partno, .setup = _setup }
+
+static const struct {
+ char *match;
+ void (*setup)(struct bridge_controller *bc);
+} bridge_ioc3_devid[] = {
+ BRIDGE_BOARD_SETUP("030-0734-", bridge_setup_ip27_baseio6g),
+ BRIDGE_BOARD_SETUP("030-0880-", bridge_setup_ip27_baseio6g),
+ BRIDGE_BOARD_SETUP("030-1023-", bridge_setup_ip27_baseio),
+ BRIDGE_BOARD_SETUP("030-1124-", bridge_setup_ip27_baseio),
+ BRIDGE_BOARD_SETUP("030-1025-", bridge_setup_ip29_baseio),
+ BRIDGE_BOARD_SETUP("030-1244-", bridge_setup_ip29_baseio),
+ BRIDGE_BOARD_SETUP("030-1389-", bridge_setup_ip29_baseio),
+ BRIDGE_BOARD_SETUP("030-0887-", bridge_setup_ip30_sysboard),
+ BRIDGE_BOARD_SETUP("030-1467-", bridge_setup_ip30_sysboard),
+ BRIDGE_BOARD_SETUP("030-0873-", bridge_setup_menet),
+};
+
+static void bridge_setup_board(struct bridge_controller *bc, char *partnum)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(bridge_ioc3_devid); i++)
+ if (!strncmp(partnum, bridge_ioc3_devid[i].match,
+ strlen(bridge_ioc3_devid[i].match))) {
+ bridge_ioc3_devid[i].setup(bc);
+ }
+}
+
+static int bridge_nvmem_match(struct device *dev, const void *data)
+{
+ const char *name = dev_name(dev);
+ const char *prefix = data;
+
+ if (strlen(name) < strlen(prefix))
+ return 0;
+
+ return memcmp(prefix, dev_name(dev), strlen(prefix)) == 0;
+}
+
+static int bridge_get_partnum(u64 baddr, char *partnum)
+{
+ struct nvmem_device *nvmem;
+ char prefix[24];
+ u8 prom[64];
+ int i, j;
+ int ret;
+
+ snprintf(prefix, sizeof(prefix), "bridge-%012llx-0b-", baddr);
+
+ nvmem = nvmem_device_find(prefix, bridge_nvmem_match);
+ if (IS_ERR(nvmem))
+ return PTR_ERR(nvmem);
+
+ ret = nvmem_device_read(nvmem, 0, 64, prom);
+ nvmem_device_put(nvmem);
+
+ if (ret != 64)
+ return ret;
+
+ if (crc16(CRC16_INIT, prom, 32) != CRC16_VALID ||
+ crc16(CRC16_INIT, prom + 32, 32) != CRC16_VALID)
+ return -EINVAL;
+
+ /* Assemble part number */
+ j = 0;
+ for (i = 0; i < 19; i++)
+ if (prom[i + 11] != ' ')
+ partnum[j++] = prom[i + 11];
+
+ for (i = 0; i < 6; i++)
+ if (prom[i + 32] != ' ')
+ partnum[j++] = prom[i + 32];
+
+ partnum[j] = 0;
+
+ return 0;
+}
+
static int bridge_probe(struct platform_device *pdev)
{
struct xtalk_bridge_platform_data *bd = dev_get_platdata(&pdev->dev);
@@ -434,9 +556,14 @@ static int bridge_probe(struct platform_device *pdev)
struct pci_host_bridge *host;
struct irq_domain *domain, *parent;
struct fwnode_handle *fn;
+ char partnum[26];
int slot;
int err;
+ /* get part number from one wire prom */
+ if (bridge_get_partnum(virt_to_phys((void *)bd->bridge_addr), partnum))
+ return -EPROBE_DEFER; /* not available yet */
+
parent = irq_get_default_host();
if (!parent)
return -ENODEV;
@@ -517,6 +644,8 @@ static int bridge_probe(struct platform_device *pdev)
}
bridge_read(bc, b_wid_tflush); /* wait until Bridge PIO complete */
+ bridge_setup_board(bc, partnum);
+
host->dev.parent = dev;
host->sysdata = bc;
host->busnr = 0;
diff --git a/arch/mips/sgi-ip27/ip27-xtalk.c b/arch/mips/sgi-ip27/ip27-xtalk.c
index 4a1f0b0c29e2..9b7524362a11 100644
--- a/arch/mips/sgi-ip27/ip27-xtalk.c
+++ b/arch/mips/sgi-ip27/ip27-xtalk.c
@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/smp.h>
#include <linux/platform_device.h>
+#include <linux/platform_data/sgi-w1.h>
#include <linux/platform_data/xtalk-bridge.h>
#include <asm/sn/addrs.h>
#include <asm/sn/types.h>
@@ -26,9 +27,35 @@
static void bridge_platform_create(nasid_t nasid, int widget, int masterwid)
{
struct xtalk_bridge_platform_data *bd;
+ struct sgi_w1_platform_data *wd;
struct platform_device *pdev;
+ struct resource w1_res;
unsigned long offset;
+ offset = NODE_OFFSET(nasid);
+
+ wd = kzalloc(sizeof(*wd), GFP_KERNEL);
+ if (!wd)
+ goto no_mem;
+
+ snprintf(wd->dev_id, sizeof(wd->dev_id), "bridge-%012lx",
+ offset + (widget << SWIN_SIZE_BITS));
+
+ memset(&w1_res, 0, sizeof(w1_res));
+ w1_res.start = offset + (widget << SWIN_SIZE_BITS) +
+ offsetof(struct bridge_regs, b_nic);
+ w1_res.end = w1_res.start + 3;
+ w1_res.flags = IORESOURCE_MEM;
+
+ pdev = platform_device_alloc("sgi_w1", PLATFORM_DEVID_AUTO);
+ if (!pdev) {
+ kfree(wd);
+ goto no_mem;
+ }
+ platform_device_add_resources(pdev, &w1_res, 1);
+ platform_device_add_data(pdev, wd, sizeof(*wd));
+ platform_device_add(pdev);
+
bd = kzalloc(sizeof(*bd), GFP_KERNEL);
if (!bd)
goto no_mem;
@@ -38,7 +65,6 @@ static void bridge_platform_create(nasid_t nasid, int widget, int masterwid)
goto no_mem;
}
- offset = NODE_OFFSET(nasid);
bd->bridge_addr = RAW_NODE_SWIN_BASE(nasid, widget);
bd->intr_addr = BIT_ULL(47) + 0x01800000 + PI_INT_PEND_MOD;
@@ -46,14 +72,14 @@ static void bridge_platform_create(nasid_t nasid, int widget, int masterwid)
bd->masterwid = masterwid;
bd->mem.name = "Bridge PCI MEM";
- bd->mem.start = offset + (widget << SWIN_SIZE_BITS);
- bd->mem.end = bd->mem.start + SWIN_SIZE - 1;
+ bd->mem.start = offset + (widget << SWIN_SIZE_BITS) + BRIDGE_DEVIO0;
+ bd->mem.end = offset + (widget << SWIN_SIZE_BITS) + SWIN_SIZE - 1;
bd->mem.flags = IORESOURCE_MEM;
bd->mem_offset = offset;
bd->io.name = "Bridge PCI IO";
- bd->io.start = offset + (widget << SWIN_SIZE_BITS);
- bd->io.end = bd->io.start + SWIN_SIZE - 1;
+ bd->io.start = offset + (widget << SWIN_SIZE_BITS) + BRIDGE_DEVIO0;
+ bd->io.end = offset + (widget << SWIN_SIZE_BITS) + SWIN_SIZE - 1;
bd->io.flags = IORESOURCE_IO;
bd->io_offset = offset;
@@ -81,6 +107,8 @@ static int probe_one_port(nasid_t nasid, int widget, int masterwid)
bridge_platform_create(nasid, widget, masterwid);
break;
default:
+ pr_info("xtalk:n%d/%d unknown widget (0x%x)\n",
+ nasid, widget, partnum);
break;
}
--
2.13.7
^ permalink raw reply related
* [PATCH v4 4/9] MIPS: PCI: refactor ioc3 special handling
From: Thomas Bogendoerfer @ 2019-08-09 10:32 UTC (permalink / raw)
To: Ralf Baechle, Paul Burton, James Hogan, Dmitry Torokhov,
Lee Jones, David S. Miller, Srinivas Kandagatla, Alessandro Zummo,
Alexandre Belloni, Greg Kroah-Hartman, Jiri Slaby,
Evgeniy Polyakov, linux-mips, linux-kernel, linux-input, netdev,
linux-rtc, linux-serial
In-Reply-To: <20190809103235.16338-1-tbogendoerfer@suse.de>
Refactored code to only have one ioc3 special handling for read
access and one for write access.
Signed-off-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
---
arch/mips/pci/pci-xtalk-bridge.c | 167 +++++++++++++++------------------------
1 file changed, 62 insertions(+), 105 deletions(-)
diff --git a/arch/mips/pci/pci-xtalk-bridge.c b/arch/mips/pci/pci-xtalk-bridge.c
index bcf7f559789a..7b4d40354ee7 100644
--- a/arch/mips/pci/pci-xtalk-bridge.c
+++ b/arch/mips/pci/pci-xtalk-bridge.c
@@ -20,16 +20,50 @@
* Most of the IOC3 PCI config register aren't present
* we emulate what is needed for a normal PCI enumeration
*/
-static u32 emulate_ioc3_cfg(int where, int size)
+static int ioc3_cfg_rd(void *addr, int where, int size, u32 *value)
{
- if (size == 1 && where == 0x3d)
- return 0x01;
- else if (size == 2 && where == 0x3c)
- return 0x0100;
- else if (size == 4 && where == 0x3c)
- return 0x00000100;
+ u32 cf, shift, mask;
- return 0;
+ switch (where & ~3) {
+ case 0x00 ... 0x10:
+ case 0x40 ... 0x44:
+ if (get_dbe(cf, (u32 *)addr))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ break;
+ case 0x3c:
+ /* emulate sane interrupt pin value */
+ cf = 0x00000100;
+ break;
+ default:
+ cf = 0;
+ break;
+ }
+ shift = (where & 3) << 3;
+ mask = 0xffffffffU >> ((4 - size) << 3);
+ *value = (cf >> shift) & mask;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int ioc3_cfg_wr(void *addr, int where, int size, u32 value)
+{
+ u32 cf, shift, mask, smask;
+
+ if ((where >= 0x14 && where < 0x40) || (where >= 0x48))
+ return PCIBIOS_SUCCESSFUL;
+
+ if (get_dbe(cf, (u32 *)addr))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ shift = ((where & 3) << 3);
+ mask = (0xffffffffU >> ((4 - size) << 3));
+ smask = mask << shift;
+
+ cf = (cf & ~smask) | ((value & mask) << shift);
+ if (put_dbe(cf, (u32 *)addr))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ return PCIBIOS_SUCCESSFUL;
}
static void bridge_disable_swapping(struct pci_dev *dev)
@@ -64,7 +98,7 @@ static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn,
int slot = PCI_SLOT(devfn);
int fn = PCI_FUNC(devfn);
void *addr;
- u32 cf, shift, mask;
+ u32 cf;
int res;
addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[PCI_VENDOR_ID];
@@ -75,8 +109,10 @@ static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn,
* IOC3 is broken beyond belief ... Don't even give the
* generic PCI code a chance to look at it for real ...
*/
- if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
- goto is_ioc3;
+ if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) {
+ addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
+ return ioc3_cfg_rd(addr, where, size, value);
+ }
addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)];
@@ -88,26 +124,6 @@ static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn,
res = get_dbe(*value, (u32 *)addr);
return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
-
-is_ioc3:
-
- /*
- * IOC3 special handling
- */
- if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) {
- *value = emulate_ioc3_cfg(where, size);
- return PCIBIOS_SUCCESSFUL;
- }
-
- addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
- if (get_dbe(cf, (u32 *)addr))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- shift = ((where & 3) << 3);
- mask = (0xffffffffU >> ((4 - size) << 3));
- *value = (cf >> shift) & mask;
-
- return PCIBIOS_SUCCESSFUL;
}
static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn,
@@ -119,7 +135,7 @@ static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn,
int slot = PCI_SLOT(devfn);
int fn = PCI_FUNC(devfn);
void *addr;
- u32 cf, shift, mask;
+ u32 cf;
int res;
bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11));
@@ -131,8 +147,10 @@ static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn,
* IOC3 is broken beyond belief ... Don't even give the
* generic PCI code a chance to look at it for real ...
*/
- if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
- goto is_ioc3;
+ if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) {
+ addr = &bridge->b_type1_cfg.c[(fn << 8) | (where & ~3)];
+ return ioc3_cfg_rd(addr, where, size, value);
+ }
addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))];
@@ -144,26 +162,6 @@ static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn,
res = get_dbe(*value, (u32 *)addr);
return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
-
-is_ioc3:
-
- /*
- * IOC3 special handling
- */
- if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) {
- *value = emulate_ioc3_cfg(where, size);
- return PCIBIOS_SUCCESSFUL;
- }
-
- addr = &bridge->b_type1_cfg.c[(fn << 8) | where];
- if (get_dbe(cf, (u32 *)addr))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- shift = ((where & 3) << 3);
- mask = (0xffffffffU >> ((4 - size) << 3));
- *value = (cf >> shift) & mask;
-
- return PCIBIOS_SUCCESSFUL;
}
static int pci_read_config(struct pci_bus *bus, unsigned int devfn,
@@ -183,7 +181,7 @@ static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn,
int slot = PCI_SLOT(devfn);
int fn = PCI_FUNC(devfn);
void *addr;
- u32 cf, shift, mask, smask;
+ u32 cf;
int res;
addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[PCI_VENDOR_ID];
@@ -194,8 +192,10 @@ static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn,
* IOC3 is broken beyond belief ... Don't even give the
* generic PCI code a chance to look at it for real ...
*/
- if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
- goto is_ioc3;
+ if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) {
+ addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
+ return ioc3_cfg_wr(addr, where, size, value);
+ }
addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)];
@@ -210,29 +210,6 @@ static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn,
return PCIBIOS_DEVICE_NOT_FOUND;
return PCIBIOS_SUCCESSFUL;
-
-is_ioc3:
-
- /*
- * IOC3 special handling
- */
- if ((where >= 0x14 && where < 0x40) || (where >= 0x48))
- return PCIBIOS_SUCCESSFUL;
-
- addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
-
- if (get_dbe(cf, (u32 *)addr))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- shift = ((where & 3) << 3);
- mask = (0xffffffffU >> ((4 - size) << 3));
- smask = mask << shift;
-
- cf = (cf & ~smask) | ((value & mask) << shift);
- if (put_dbe(cf, (u32 *)addr))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- return PCIBIOS_SUCCESSFUL;
}
static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn,
@@ -244,7 +221,7 @@ static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn,
int fn = PCI_FUNC(devfn);
int busno = bus->number;
void *addr;
- u32 cf, shift, mask, smask;
+ u32 cf;
int res;
bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11));
@@ -256,8 +233,10 @@ static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn,
* IOC3 is broken beyond belief ... Don't even give the
* generic PCI code a chance to look at it for real ...
*/
- if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
- goto is_ioc3;
+ if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) {
+ addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
+ return ioc3_cfg_wr(addr, where, size, value);
+ }
addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))];
@@ -272,28 +251,6 @@ static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn,
return PCIBIOS_DEVICE_NOT_FOUND;
return PCIBIOS_SUCCESSFUL;
-
-is_ioc3:
-
- /*
- * IOC3 special handling
- */
- if ((where >= 0x14 && where < 0x40) || (where >= 0x48))
- return PCIBIOS_SUCCESSFUL;
-
- addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
- if (get_dbe(cf, (u32 *)addr))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- shift = ((where & 3) << 3);
- mask = (0xffffffffU >> ((4 - size) << 3));
- smask = mask << shift;
-
- cf = (cf & ~smask) | ((value & mask) << shift);
- if (put_dbe(cf, (u32 *)addr))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- return PCIBIOS_SUCCESSFUL;
}
static int pci_write_config(struct pci_bus *bus, unsigned int devfn,
--
2.13.7
^ permalink raw reply related
* [PATCH v4 3/9] nvmem: core: add nvmem_device_find
From: Thomas Bogendoerfer @ 2019-08-09 10:32 UTC (permalink / raw)
To: Ralf Baechle, Paul Burton, James Hogan, Dmitry Torokhov,
Lee Jones, David S. Miller, Srinivas Kandagatla, Alessandro Zummo,
Alexandre Belloni, Greg Kroah-Hartman, Jiri Slaby,
Evgeniy Polyakov, linux-mips, linux-kernel, linux-input, netdev,
linux-rtc, linux-serial
In-Reply-To: <20190809103235.16338-1-tbogendoerfer@suse.de>
nvmem_device_find provides a way to search for nvmem devices with
the help of a match function simlair to bus_find_device.
Signed-off-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
---
drivers/nvmem/core.c | 62 ++++++++++++++++++++++--------------------
include/linux/nvmem-consumer.h | 9 ++++++
2 files changed, 41 insertions(+), 30 deletions(-)
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index ac5d945be88a..e591ba54758f 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -76,36 +76,18 @@ static struct bus_type nvmem_bus_type = {
.name = "nvmem",
};
+#if IS_ENABLED(CONFIG_OF)
static int of_nvmem_match(struct device *dev, const void *nvmem_np)
{
return dev->of_node == nvmem_np;
}
+#endif
-static struct nvmem_device *of_nvmem_find(struct device_node *nvmem_np)
+static int nvmem_match_name(struct device *dev, const void *data)
{
- struct device *d;
-
- if (!nvmem_np)
- return NULL;
-
- d = bus_find_device(&nvmem_bus_type, NULL, nvmem_np, of_nvmem_match);
-
- if (!d)
- return NULL;
+ const char *name = data;
- return to_nvmem_device(d);
-}
-
-static struct nvmem_device *nvmem_find(const char *name)
-{
- struct device *d;
-
- d = bus_find_device_by_name(&nvmem_bus_type, NULL, name);
-
- if (!d)
- return NULL;
-
- return to_nvmem_device(d);
+ return sysfs_streq(name, dev_name(dev));
}
static void nvmem_cell_drop(struct nvmem_cell *cell)
@@ -537,13 +519,16 @@ int devm_nvmem_unregister(struct device *dev, struct nvmem_device *nvmem)
}
EXPORT_SYMBOL(devm_nvmem_unregister);
-static struct nvmem_device *__nvmem_device_get(struct device_node *np,
- const char *nvmem_name)
+static struct nvmem_device *__nvmem_device_get(void *data,
+ int (*match)(struct device *dev, const void *data))
{
struct nvmem_device *nvmem = NULL;
+ struct device *dev;
mutex_lock(&nvmem_mutex);
- nvmem = np ? of_nvmem_find(np) : nvmem_find(nvmem_name);
+ dev = bus_find_device(&nvmem_bus_type, NULL, data, match);
+ if (dev)
+ nvmem = to_nvmem_device(dev);
mutex_unlock(&nvmem_mutex);
if (!nvmem)
return ERR_PTR(-EPROBE_DEFER);
@@ -592,7 +577,7 @@ struct nvmem_device *of_nvmem_device_get(struct device_node *np, const char *id)
if (!nvmem_np)
return ERR_PTR(-ENOENT);
- return __nvmem_device_get(nvmem_np, NULL);
+ return __nvmem_device_get(nvmem_np, of_nvmem_match);
}
EXPORT_SYMBOL_GPL(of_nvmem_device_get);
#endif
@@ -618,10 +603,26 @@ struct nvmem_device *nvmem_device_get(struct device *dev, const char *dev_name)
}
- return __nvmem_device_get(NULL, dev_name);
+ return __nvmem_device_get((void *)dev_name, nvmem_match_name);
}
EXPORT_SYMBOL_GPL(nvmem_device_get);
+/**
+ * nvmem_device_find() - Find nvmem device with matching function
+ *
+ * @data: Data to pass to match function
+ * @match: Callback function to check device
+ *
+ * Return: ERR_PTR() on error or a valid pointer to a struct nvmem_device
+ * on success.
+ */
+struct nvmem_device *nvmem_device_find(void *data,
+ int (*match)(struct device *dev, const void *data))
+{
+ return __nvmem_device_get(data, match);
+}
+EXPORT_SYMBOL_GPL(nvmem_device_find);
+
static int devm_nvmem_device_match(struct device *dev, void *res, void *data)
{
struct nvmem_device **nvmem = res;
@@ -715,7 +716,8 @@ nvmem_cell_get_from_lookup(struct device *dev, const char *con_id)
if ((strcmp(lookup->dev_id, dev_id) == 0) &&
(strcmp(lookup->con_id, con_id) == 0)) {
/* This is the right entry. */
- nvmem = __nvmem_device_get(NULL, lookup->nvmem_name);
+ nvmem = __nvmem_device_get((void *)lookup->nvmem_name,
+ nvmem_match_name);
if (IS_ERR(nvmem)) {
/* Provider may not be registered yet. */
cell = ERR_CAST(nvmem);
@@ -785,7 +787,7 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, const char *id)
if (!nvmem_np)
return ERR_PTR(-EINVAL);
- nvmem = __nvmem_device_get(nvmem_np, NULL);
+ nvmem = __nvmem_device_get(nvmem_np, of_nvmem_match);
of_node_put(nvmem_np);
if (IS_ERR(nvmem))
return ERR_CAST(nvmem);
diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h
index 8f8be5b00060..02dc4aa992b2 100644
--- a/include/linux/nvmem-consumer.h
+++ b/include/linux/nvmem-consumer.h
@@ -89,6 +89,9 @@ void nvmem_del_cell_lookups(struct nvmem_cell_lookup *entries,
int nvmem_register_notifier(struct notifier_block *nb);
int nvmem_unregister_notifier(struct notifier_block *nb);
+struct nvmem_device *nvmem_device_find(void *data,
+ int (*match)(struct device *dev, const void *data));
+
#else
static inline struct nvmem_cell *nvmem_cell_get(struct device *dev,
@@ -204,6 +207,12 @@ static inline int nvmem_unregister_notifier(struct notifier_block *nb)
return -EOPNOTSUPP;
}
+static inline struct nvmem_device *nvmem_device_find(void *data,
+ int (*match)(struct device *dev, const void *data))
+{
+ return NULL;
+}
+
#endif /* CONFIG_NVMEM */
#if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF)
--
2.13.7
^ permalink raw reply related
* [PATCH v4 0/9] Use MFD framework for SGI IOC3 drivers
From: Thomas Bogendoerfer @ 2019-08-09 10:32 UTC (permalink / raw)
To: Ralf Baechle, Paul Burton, James Hogan, Dmitry Torokhov,
Lee Jones, David S. Miller, Srinivas Kandagatla, Alessandro Zummo,
Alexandre Belloni, Greg Kroah-Hartman, Jiri Slaby,
Evgeniy Polyakov, linux-mips, linux-kernel, linux-input, netdev,
linux-rtc, linux-serial
SGI IOC3 ASIC includes support for ethernet, PS2 keyboard/mouse,
NIC (number in a can), GPIO and a byte bus. By attaching a
SuperIO chip to it, it also supports serial lines and a parallel
port. The chip is used on a variety of SGI systems with different
configurations. This patchset moves code out of the network driver,
which doesn't belong there, into its new place a MFD driver and
specific platform drivers for the different subfunctions.
Changes in v4:
- added w1 drivers to the series after merge in 5.3 failed because
of no response from maintainer and other parts of this series
won't work without that drivers
- moved ip30 systemboard support to the ip30 series, which will
deal with rtc oddity Lee found
- converted to use devm_platform_ioremap_resource
- use PLATFORM_DEVID_AUTO for serial, ethernet and serio in mfd driver
- fixed reverse christmas order in ioc3-eth.c
- formating issue found by Lee
- re-worked irq request/free in serio driver to avoid crashes during
probe/remove
Changes in v3:
- use 1-wire subsystem for handling proms
- pci-xtalk driver uses prom information to create PCI subsystem
ids for use in MFD driver
- changed MFD driver to only use static declared mfd_cells
- added IP30 system board setup to MFD driver
- mac address is now read from ioc3-eth driver with nvmem framework
Changes in v2:
- fixed issue in ioc3kbd.c reported by Dmitry Torokhov
- merged IP27 RTC removal and 8250 serial driver addition into
main MFD patch to keep patches bisectable
Thomas Bogendoerfer (9):
w1: add 1-wire master driver for IP block found in SGI ASICs
w1: add DS2501, DS2502, DS2505 EPROM device driver
nvmem: core: add nvmem_device_find
MIPS: PCI: refactor ioc3 special handling
MIPS: PCI: use information from 1-wire PROM for IOC3 detection
MIPS: SGI-IP27: remove ioc3 ethernet init
mfd: ioc3: Add driver for SGI IOC3 chip
MIPS: SGI-IP27: fix readb/writeb addressing
Input: add IOC3 serio driver
arch/mips/include/asm/mach-ip27/mangle-port.h | 4 +-
arch/mips/include/asm/pci/bridge.h | 1 +
arch/mips/include/asm/sn/ioc3.h | 356 ++---
arch/mips/pci/pci-xtalk-bridge.c | 296 ++--
arch/mips/sgi-ip27/ip27-console.c | 5 +-
arch/mips/sgi-ip27/ip27-init.c | 13 -
arch/mips/sgi-ip27/ip27-timer.c | 20 -
arch/mips/sgi-ip27/ip27-xtalk.c | 38 +-
drivers/input/serio/Kconfig | 10 +
drivers/input/serio/Makefile | 1 +
drivers/input/serio/ioc3kbd.c | 163 +++
drivers/mfd/Kconfig | 13 +
drivers/mfd/Makefile | 1 +
drivers/mfd/ioc3.c | 586 ++++++++
drivers/net/ethernet/sgi/Kconfig | 4 +-
drivers/net/ethernet/sgi/ioc3-eth.c | 1936 ++++++++++---------------
drivers/nvmem/core.c | 62 +-
drivers/rtc/rtc-m48t35.c | 11 +
drivers/tty/serial/8250/8250_ioc3.c | 98 ++
drivers/tty/serial/8250/Kconfig | 11 +
drivers/tty/serial/8250/Makefile | 1 +
drivers/w1/masters/Kconfig | 9 +
drivers/w1/masters/Makefile | 1 +
drivers/w1/masters/sgi_w1.c | 130 ++
drivers/w1/slaves/Kconfig | 6 +
drivers/w1/slaves/Makefile | 1 +
drivers/w1/slaves/w1_ds250x.c | 293 ++++
include/linux/nvmem-consumer.h | 9 +
include/linux/platform_data/sgi-w1.h | 15 +
include/linux/w1.h | 2 +
30 files changed, 2522 insertions(+), 1574 deletions(-)
create mode 100644 drivers/input/serio/ioc3kbd.c
create mode 100644 drivers/mfd/ioc3.c
create mode 100644 drivers/tty/serial/8250/8250_ioc3.c
create mode 100644 drivers/w1/masters/sgi_w1.c
create mode 100644 drivers/w1/slaves/w1_ds250x.c
create mode 100644 include/linux/platform_data/sgi-w1.h
--
2.13.7
^ permalink raw reply
* [PATCH v4 1/9] w1: add 1-wire master driver for IP block found in SGI ASICs
From: Thomas Bogendoerfer @ 2019-08-09 10:32 UTC (permalink / raw)
To: Ralf Baechle, Paul Burton, James Hogan, Dmitry Torokhov,
Lee Jones, David S. Miller, Srinivas Kandagatla, Alessandro Zummo,
Alexandre Belloni, Greg Kroah-Hartman, Jiri Slaby,
Evgeniy Polyakov, linux-mips, linux-kernel, linux-input, netdev,
linux-rtc, linux-serial
In-Reply-To: <20190809103235.16338-1-tbogendoerfer@suse.de>
Starting with SGI Origin machines nearly every new SGI ASIC contains
an 1-Wire master. They are used for attaching One-Wire prom devices,
which contain information about part numbers, revision numbers,
serial number etc. and MAC addresses for ethernet interfaces.
This patch adds a master driver to support this IP block.
It also adds an extra field dev_id to struct w1_bus_master, which
could be in used in slave drivers for creating unique device names.
Signed-off-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
---
drivers/w1/masters/Kconfig | 9 +++
drivers/w1/masters/Makefile | 1 +
drivers/w1/masters/sgi_w1.c | 130 +++++++++++++++++++++++++++++++++++
include/linux/platform_data/sgi-w1.h | 15 ++++
include/linux/w1.h | 2 +
5 files changed, 157 insertions(+)
create mode 100644 drivers/w1/masters/sgi_w1.c
create mode 100644 include/linux/platform_data/sgi-w1.h
diff --git a/drivers/w1/masters/Kconfig b/drivers/w1/masters/Kconfig
index 7ae260577901..24b9a8e05f64 100644
--- a/drivers/w1/masters/Kconfig
+++ b/drivers/w1/masters/Kconfig
@@ -65,5 +65,14 @@ config HDQ_MASTER_OMAP
Say Y here if you want support for the 1-wire or HDQ Interface
on an OMAP processor.
+config W1_MASTER_SGI
+ tristate "SGI ASIC driver"
+ help
+ Say Y here if you want support for your 1-wire devices using
+ SGI ASIC 1-Wire interface
+
+ This support is also available as a module. If so, the module
+ will be called sgi_w1.
+
endmenu
diff --git a/drivers/w1/masters/Makefile b/drivers/w1/masters/Makefile
index 18954cae4256..dae629b7ab49 100644
--- a/drivers/w1/masters/Makefile
+++ b/drivers/w1/masters/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_W1_MASTER_MXC) += mxc_w1.o
obj-$(CONFIG_W1_MASTER_DS1WM) += ds1wm.o
obj-$(CONFIG_W1_MASTER_GPIO) += w1-gpio.o
obj-$(CONFIG_HDQ_MASTER_OMAP) += omap_hdq.o
+obj-$(CONFIG_W1_MASTER_SGI) += sgi_w1.o
diff --git a/drivers/w1/masters/sgi_w1.c b/drivers/w1/masters/sgi_w1.c
new file mode 100644
index 000000000000..1b2d96b945be
--- /dev/null
+++ b/drivers/w1/masters/sgi_w1.c
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * sgi_w1.c - w1 master driver for one wire support in SGI ASICs
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/sgi-w1.h>
+
+#include <linux/w1.h>
+
+#define MCR_RD_DATA BIT(0)
+#define MCR_DONE BIT(1)
+
+#define MCR_PACK(pulse, sample) (((pulse) << 10) | ((sample) << 2))
+
+struct sgi_w1_device {
+ u32 __iomem *mcr;
+ struct w1_bus_master bus_master;
+ char dev_id[64];
+};
+
+static u8 sgi_w1_wait(u32 __iomem *mcr)
+{
+ u32 mcr_val;
+
+ do {
+ mcr_val = readl(mcr);
+ } while (!(mcr_val & MCR_DONE));
+
+ return (mcr_val & MCR_RD_DATA) ? 1 : 0;
+}
+
+/*
+ * this is the low level routine to
+ * reset the device on the One Wire interface
+ * on the hardware
+ */
+static u8 sgi_w1_reset_bus(void *data)
+{
+ struct sgi_w1_device *dev = data;
+ u8 ret;
+
+ writel(MCR_PACK(520, 65), dev->mcr);
+ ret = sgi_w1_wait(dev->mcr);
+ udelay(500); /* recovery time */
+ return ret;
+}
+
+/*
+ * this is the low level routine to read/write a bit on the One Wire
+ * interface on the hardware. It does write 0 if parameter bit is set
+ * to 0, otherwise a write 1/read.
+ */
+static u8 sgi_w1_touch_bit(void *data, u8 bit)
+{
+ struct sgi_w1_device *dev = data;
+ u8 ret;
+
+ if (bit)
+ writel(MCR_PACK(6, 13), dev->mcr);
+ else
+ writel(MCR_PACK(80, 30), dev->mcr);
+
+ ret = sgi_w1_wait(dev->mcr);
+ if (bit)
+ udelay(100); /* recovery */
+ return ret;
+}
+
+static int sgi_w1_probe(struct platform_device *pdev)
+{
+ struct sgi_w1_device *sdev;
+ struct sgi_w1_platform_data *pdata;
+ struct resource *res;
+
+ sdev = devm_kzalloc(&pdev->dev, sizeof(struct sgi_w1_device),
+ GFP_KERNEL);
+ if (!sdev)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ sdev->mcr = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(sdev->mcr))
+ return PTR_ERR(sdev->mcr);
+
+ sdev->bus_master.data = sdev;
+ sdev->bus_master.reset_bus = sgi_w1_reset_bus;
+ sdev->bus_master.touch_bit = sgi_w1_touch_bit;
+
+ pdata = dev_get_platdata(&pdev->dev);
+ if (pdata) {
+ strlcpy(sdev->dev_id, pdata->dev_id, sizeof(sdev->dev_id));
+ sdev->bus_master.dev_id = sdev->dev_id;
+ }
+
+ platform_set_drvdata(pdev, sdev);
+
+ return w1_add_master_device(&sdev->bus_master);
+}
+
+/*
+ * disassociate the w1 device from the driver
+ */
+static int sgi_w1_remove(struct platform_device *pdev)
+{
+ struct sgi_w1_device *sdev = platform_get_drvdata(pdev);
+
+ w1_remove_master_device(&sdev->bus_master);
+
+ return 0;
+}
+
+static struct platform_driver sgi_w1_driver = {
+ .driver = {
+ .name = "sgi_w1",
+ },
+ .probe = sgi_w1_probe,
+ .remove = sgi_w1_remove,
+};
+module_platform_driver(sgi_w1_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Thomas Bogendoerfer");
+MODULE_DESCRIPTION("Driver for One-Wire IP in SGI ASICs");
diff --git a/include/linux/platform_data/sgi-w1.h b/include/linux/platform_data/sgi-w1.h
new file mode 100644
index 000000000000..fc6b92e0b942
--- /dev/null
+++ b/include/linux/platform_data/sgi-w1.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * SGI One-Wire (W1) IP
+ */
+
+#ifndef PLATFORM_DATA_SGI_W1_H
+#define PLATFORM_DATA_SGI_W1_H
+
+#include <asm/sn/types.h>
+
+struct sgi_w1_platform_data {
+ char dev_id[64];
+};
+
+#endif /* PLATFORM_DATA_SGI_W1_H */
diff --git a/include/linux/w1.h b/include/linux/w1.h
index e0b5156f78fd..89843e9f634c 100644
--- a/include/linux/w1.h
+++ b/include/linux/w1.h
@@ -150,6 +150,8 @@ struct w1_bus_master {
void (*search)(void *, struct w1_master *,
u8, w1_slave_found_callback);
+
+ char *dev_id;
};
/**
--
2.13.7
^ permalink raw reply related
* [PATCH] perf trace: Fix segmentation fault when access syscall info
From: Leo Yan @ 2019-08-09 10:47 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo, Alexander Shishkin, Jiri Olsa,
Namhyung Kim, Daniel Borkmann, Martin KaFai Lau, Song Liu,
Yonghong Song, linux-kernel, netdev, bpf
Cc: Leo Yan
'perf trace' reports the segmentation fault as below on Arm64:
# perf trace -e string -e augmented_raw_syscalls.c
LLVM: dumping tools/perf/examples/bpf/augmented_raw_syscalls.o
perf: Segmentation fault
Obtained 12 stack frames.
perf(sighandler_dump_stack+0x47) [0xaaaaac96ac87]
linux-vdso.so.1(+0x5b7) [0xffffadbeb5b7]
/lib/aarch64-linux-gnu/libc.so.6(strlen+0x10) [0xfffface7d5d0]
/lib/aarch64-linux-gnu/libc.so.6(_IO_vfprintf+0x1ac7) [0xfffface49f97]
/lib/aarch64-linux-gnu/libc.so.6(__vsnprintf_chk+0xc7) [0xffffacedfbe7]
perf(scnprintf+0x97) [0xaaaaac9ca3ff]
perf(+0x997bb) [0xaaaaac8e37bb]
perf(cmd_trace+0x28e7) [0xaaaaac8ec09f]
perf(+0xd4a13) [0xaaaaac91ea13]
perf(main+0x62f) [0xaaaaac8a147f]
/lib/aarch64-linux-gnu/libc.so.6(__libc_start_main+0xe3) [0xfffface22d23]
perf(+0x57723) [0xaaaaac8a1723]
Segmentation fault
This issue is introduced by commit 30a910d7d3e0 ("perf trace:
Preallocate the syscall table"), it allocates trace->syscalls.table[]
array and the element count is 'trace->sctbl->syscalls.nr_entries';
but on Arm64, the system call number is not continuously used; e.g. the
syscall maximum id is 436 but the real entries is only 281. So the
table is allocated with 'nr_entries' as the element count, but it
accesses the table with the syscall id, which might be out of the bound
of the array and cause the segmentation fault.
This patch allocates trace->syscalls.table[] with the element count is
'trace->sctbl->syscalls.max_id + 1', this allows any id to access the
table without out of the bound.
Fixes: 30a910d7d3e0 ("perf trace: Preallocate the syscall table")
Signed-off-by: Leo Yan <leo.yan@linaro.org>
---
tools/perf/builtin-trace.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 75eb3811e942..d553d06a9aeb 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1492,7 +1492,7 @@ static int trace__read_syscall_info(struct trace *trace, int id)
const char *name = syscalltbl__name(trace->sctbl, id);
if (trace->syscalls.table == NULL) {
- trace->syscalls.table = calloc(trace->sctbl->syscalls.nr_entries, sizeof(*sc));
+ trace->syscalls.table = calloc(trace->sctbl->syscalls.max_id + 1, sizeof(*sc));
if (trace->syscalls.table == NULL)
return -ENOMEM;
}
--
2.17.1
^ permalink raw reply related
* KASAN: null-ptr-deref Write in rxrpc_unuse_local
From: syzbot @ 2019-08-09 10:58 UTC (permalink / raw)
To: davem, dhowells, linux-afs, linux-kernel, netdev, syzkaller-bugs
Hello,
syzbot found the following crash on:
HEAD commit: 87b983f5 Add linux-next specific files for 20190809
git tree: linux-next
console output: https://syzkaller.appspot.com/x/log.txt?x=143aecee600000
kernel config: https://syzkaller.appspot.com/x/.config?x=28eea330e11df0eb
dashboard link: https://syzkaller.appspot.com/bug?extid=20dee719a2e090427b5f
compiler: gcc (GCC) 9.0.0 20181231 (experimental)
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=17ceae36600000
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=10ebc40e600000
IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+20dee719a2e090427b5f@syzkaller.appspotmail.com
==================================================================
BUG: KASAN: null-ptr-deref in atomic_sub_return
include/asm-generic/atomic-instrumented.h:159 [inline]
BUG: KASAN: null-ptr-deref in atomic_dec_return
include/linux/atomic-fallback.h:455 [inline]
BUG: KASAN: null-ptr-deref in rxrpc_unuse_local+0x23/0x70
net/rxrpc/local_object.c:405
Write of size 4 at addr 0000000000000010 by task syz-executor725/10010
CPU: 1 PID: 10010 Comm: syz-executor725 Not tainted 5.3.0-rc3-next-20190809
#63
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+0x172/0x1f0 lib/dump_stack.c:113
__kasan_report.cold+0x5/0x36 mm/kasan/report.c:486
kasan_report+0x12/0x17 mm/kasan/common.c:610
check_memory_region_inline mm/kasan/generic.c:185 [inline]
check_memory_region+0x134/0x1a0 mm/kasan/generic.c:192
__kasan_check_write+0x14/0x20 mm/kasan/common.c:98
atomic_sub_return include/asm-generic/atomic-instrumented.h:159 [inline]
atomic_dec_return include/linux/atomic-fallback.h:455 [inline]
rxrpc_unuse_local+0x23/0x70 net/rxrpc/local_object.c:405
rxrpc_release_sock net/rxrpc/af_rxrpc.c:904 [inline]
rxrpc_release+0x47d/0x840 net/rxrpc/af_rxrpc.c:930
__sock_release+0xce/0x280 net/socket.c:590
sock_close+0x1e/0x30 net/socket.c:1268
__fput+0x2ff/0x890 fs/file_table.c:280
____fput+0x16/0x20 fs/file_table.c:313
task_work_run+0x145/0x1c0 kernel/task_work.c:113
exit_task_work include/linux/task_work.h:22 [inline]
do_exit+0x92f/0x2e50 kernel/exit.c:879
do_group_exit+0x135/0x360 kernel/exit.c:983
__do_sys_exit_group kernel/exit.c:994 [inline]
__se_sys_exit_group kernel/exit.c:992 [inline]
__x64_sys_exit_group+0x44/0x50 kernel/exit.c:992
do_syscall_64+0xfa/0x760 arch/x86/entry/common.c:290
entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x43ed68
Code: Bad RIP value.
RSP: 002b:00007ffc2b7b93f8 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7
RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 000000000043ed68
RDX: 0000000000000000 RSI: 000000000000003c RDI: 0000000000000000
RBP: 00000000004be568 R08: 00000000000000e7 R09: ffffffffffffffd0
R10: 00000000ffffffff R11: 0000000000000246 R12: 0000000000000001
R13: 00000000006d0180 R14: 0000000000000000 R15: 0000000000000000
==================================================================
---
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#status for how to communicate with syzbot.
syzbot can test patches for this bug, for details see:
https://goo.gl/tpsmEJ#testing-patches
^ permalink raw reply
* [patch net-next] netdevsim: register couple of devlink params
From: Jiri Pirko @ 2019-08-09 11:05 UTC (permalink / raw)
To: netdev; +Cc: davem, jakub.kicinski, mlxsw
From: Jiri Pirko <jiri@mellanox.com>
Register couple of devlink params, one generic, one driver-specific.
Make the values available over debugfs.
Example:
$ echo "111" > /sys/bus/netdevsim/new_device
$ devlink dev param
netdevsim/netdevsim111:
name max_macs type generic
values:
cmode driverinit value 32
name test1 type driver-specific
values:
cmode driverinit value true
$ cat /sys/kernel/debug/netdevsim/netdevsim111/max_macs
32
$ cat /sys/kernel/debug/netdevsim/netdevsim111/test1
Y
$ devlink dev param set netdevsim/netdevsim111 name max_macs cmode driverinit value 16
$ devlink dev param set netdevsim/netdevsim111 name test1 cmode driverinit value false
$ devlink dev reload netdevsim/netdevsim111
$ cat /sys/kernel/debug/netdevsim/netdevsim111/max_macs
16
$ cat /sys/kernel/debug/netdevsim/netdevsim111/test1
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
drivers/net/netdevsim/dev.c | 72 ++++++++++++++++++++++++++++++-
drivers/net/netdevsim/netdevsim.h | 2 +
2 files changed, 73 insertions(+), 1 deletion(-)
diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
index 685dd21f5500..127aef85dc99 100644
--- a/drivers/net/netdevsim/dev.c
+++ b/drivers/net/netdevsim/dev.c
@@ -40,6 +40,10 @@ static int nsim_dev_debugfs_init(struct nsim_dev *nsim_dev)
return PTR_ERR_OR_ZERO(nsim_dev->ports_ddir) ?: -EINVAL;
debugfs_create_bool("fw_update_status", 0600, nsim_dev->ddir,
&nsim_dev->fw_update_status);
+ debugfs_create_u32("max_macs", 0600, nsim_dev->ddir,
+ &nsim_dev->max_macs);
+ debugfs_create_bool("test1", 0600, nsim_dev->ddir,
+ &nsim_dev->test1);
return 0;
}
@@ -196,6 +200,54 @@ static int nsim_dev_resources_register(struct devlink *devlink)
return err;
}
+enum nsim_devlink_param_id {
+ NSIM_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
+ NSIM_DEVLINK_PARAM_ID_TEST1,
+};
+
+static const struct devlink_param nsim_devlink_params[] = {
+ DEVLINK_PARAM_GENERIC(MAX_MACS,
+ BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
+ NULL, NULL, NULL),
+ DEVLINK_PARAM_DRIVER(NSIM_DEVLINK_PARAM_ID_TEST1,
+ "test1", DEVLINK_PARAM_TYPE_BOOL,
+ BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
+ NULL, NULL, NULL),
+};
+
+static void nsim_devlink_set_params_init_values(struct nsim_dev *nsim_dev,
+ struct devlink *devlink)
+{
+ union devlink_param_value value;
+
+ value.vu32 = nsim_dev->max_macs;
+ devlink_param_driverinit_value_set(devlink,
+ DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
+ value);
+ value.vbool = nsim_dev->test1;
+ devlink_param_driverinit_value_set(devlink,
+ NSIM_DEVLINK_PARAM_ID_TEST1,
+ value);
+}
+
+static void nsim_devlink_param_load_driverinit_values(struct devlink *devlink)
+{
+ struct nsim_dev *nsim_dev = devlink_priv(devlink);
+ union devlink_param_value saved_value;
+ int err;
+
+ err = devlink_param_driverinit_value_get(devlink,
+ DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
+ &saved_value);
+ if (!err)
+ nsim_dev->max_macs = saved_value.vu32;
+ err = devlink_param_driverinit_value_get(devlink,
+ NSIM_DEVLINK_PARAM_ID_TEST1,
+ &saved_value);
+ if (!err)
+ nsim_dev->test1 = saved_value.vbool;
+}
+
static int nsim_dev_reload(struct devlink *devlink,
struct netlink_ext_ack *extack)
{
@@ -218,6 +270,7 @@ static int nsim_dev_reload(struct devlink *devlink,
return err;
}
}
+ nsim_devlink_param_load_driverinit_values(devlink);
return 0;
}
@@ -267,6 +320,9 @@ static const struct devlink_ops nsim_dev_devlink_ops = {
.flash_update = nsim_dev_flash_update,
};
+#define NSIM_DEV_MAX_MACS_DEFAULT 32
+#define NSIM_DEV_TEST1_DEFAULT true
+
static struct nsim_dev *
nsim_dev_create(struct net *net, struct nsim_bus_dev *nsim_bus_dev,
unsigned int port_count)
@@ -286,6 +342,8 @@ nsim_dev_create(struct net *net, struct nsim_bus_dev *nsim_bus_dev,
INIT_LIST_HEAD(&nsim_dev->port_list);
mutex_init(&nsim_dev->port_list_lock);
nsim_dev->fw_update_status = true;
+ nsim_dev->max_macs = NSIM_DEV_MAX_MACS_DEFAULT;
+ nsim_dev->test1 = NSIM_DEV_TEST1_DEFAULT;
nsim_dev->fib_data = nsim_fib_create();
if (IS_ERR(nsim_dev->fib_data)) {
@@ -301,18 +359,28 @@ nsim_dev_create(struct net *net, struct nsim_bus_dev *nsim_bus_dev,
if (err)
goto err_resources_unregister;
- err = nsim_dev_debugfs_init(nsim_dev);
+ err = devlink_params_register(devlink, nsim_devlink_params,
+ ARRAY_SIZE(nsim_devlink_params));
if (err)
goto err_dl_unregister;
+ nsim_devlink_set_params_init_values(nsim_dev, devlink);
+
+ err = nsim_dev_debugfs_init(nsim_dev);
+ if (err)
+ goto err_params_unregister;
err = nsim_bpf_dev_init(nsim_dev);
if (err)
goto err_debugfs_exit;
+ devlink_params_publish(devlink);
return nsim_dev;
err_debugfs_exit:
nsim_dev_debugfs_exit(nsim_dev);
+err_params_unregister:
+ devlink_params_unregister(devlink, nsim_devlink_params,
+ ARRAY_SIZE(nsim_devlink_params));
err_dl_unregister:
devlink_unregister(devlink);
err_resources_unregister:
@@ -330,6 +398,8 @@ static void nsim_dev_destroy(struct nsim_dev *nsim_dev)
nsim_bpf_dev_exit(nsim_dev);
nsim_dev_debugfs_exit(nsim_dev);
+ devlink_params_unregister(devlink, nsim_devlink_params,
+ ARRAY_SIZE(nsim_devlink_params));
devlink_unregister(devlink);
devlink_resources_unregister(devlink, NULL);
nsim_fib_destroy(nsim_dev->fib_data);
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index 9563acb61b03..ef879892dd6f 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -161,6 +161,8 @@ struct nsim_dev {
struct list_head port_list;
struct mutex port_list_lock; /* protects port list */
bool fw_update_status;
+ u32 max_macs;
+ bool test1;
};
int nsim_dev_init(void);
--
2.21.0
^ permalink raw reply related
* BUG: corrupted list in rxrpc_local_processor
From: syzbot @ 2019-08-09 11:06 UTC (permalink / raw)
To: davem, dhowells, linux-afs, linux-kernel, netdev, syzkaller-bugs
Hello,
syzbot found the following crash on:
HEAD commit: 87b983f5 Add linux-next specific files for 20190809
git tree: linux-next
console output: https://syzkaller.appspot.com/x/log.txt?x=161309c2600000
kernel config: https://syzkaller.appspot.com/x/.config?x=28eea330e11df0eb
dashboard link: https://syzkaller.appspot.com/bug?extid=193e29e9387ea5837f1d
compiler: gcc (GCC) 9.0.0 20181231 (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+193e29e9387ea5837f1d@syzkaller.appspotmail.com
list_del corruption. prev->next should be ffff8880a4570da0, but was
ffff88808c74b6e0
------------[ cut here ]------------
kernel BUG at lib/list_debug.c:51!
invalid opcode: 0000 [#1] PREEMPT SMP KASAN
CPU: 1 PID: 22 Comm: kworker/1:1 Not tainted 5.3.0-rc3-next-20190809 #63
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
Google 01/01/2011
Workqueue: krxrpcd rxrpc_local_processor
RIP: 0010:__list_del_entry_valid.cold+0xf/0x4f lib/list_debug.c:51
Code: e8 f9 73 1d fe 0f 0b 48 89 f1 48 c7 c7 c0 6f e6 87 4c 89 e6 e8 e5 73
1d fe 0f 0b 4c 89 f6 48 c7 c7 60 71 e6 87 e8 d4 73 1d fe <0f> 0b 4c 89 ea
4c 89 f6 48 c7 c7 a0 70 e6 87 e8 c0 73 1d fe 0f 0b
RSP: 0018:ffff8880a9a47cc0 EFLAGS: 00010286
RAX: 0000000000000054 RBX: ffff8880a4570db8 RCX: 0000000000000000
RDX: 0000000000000000 RSI: ffffffff815bb706 RDI: ffffed1015348f8a
RBP: ffff8880a9a47cd8 R08: 0000000000000054 R09: ffffed1015d260d9
R10: ffffed1015d260d8 R11: ffff8880ae9306c7 R12: ffff888074400878
R13: ffff888074400878 R14: ffff8880a4570da0 R15: ffff88809509e580
FS: 0000000000000000(0000) GS:ffff8880ae900000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000400200 CR3: 000000006f1ac000 CR4: 00000000001406e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
__list_del_entry include/linux/list.h:131 [inline]
list_del_init include/linux/list.h:190 [inline]
rxrpc_local_destroyer net/rxrpc/local_object.c:427 [inline]
rxrpc_local_processor+0x251/0x830 net/rxrpc/local_object.c:463
process_one_work+0x9af/0x1740 kernel/workqueue.c:2269
worker_thread+0x98/0xe40 kernel/workqueue.c:2415
kthread+0x361/0x430 kernel/kthread.c:255
ret_from_fork+0x24/0x30 arch/x86/entry/entry_64.S:352
Modules linked in:
---[ end trace c8e00778000f001d ]---
RIP: 0010:__list_del_entry_valid.cold+0xf/0x4f lib/list_debug.c:51
Code: e8 f9 73 1d fe 0f 0b 48 89 f1 48 c7 c7 c0 6f e6 87 4c 89 e6 e8 e5 73
1d fe 0f 0b 4c 89 f6 48 c7 c7 60 71 e6 87 e8 d4 73 1d fe <0f> 0b 4c 89 ea
4c 89 f6 48 c7 c7 a0 70 e6 87 e8 c0 73 1d fe 0f 0b
RSP: 0018:ffff8880a9a47cc0 EFLAGS: 00010286
RAX: 0000000000000054 RBX: ffff8880a4570db8 RCX: 0000000000000000
RDX: 0000000000000000 RSI: ffffffff815bb706 RDI: ffffed1015348f8a
RBP: ffff8880a9a47cd8 R08: 0000000000000054 R09: ffffed1015d260d9
R10: ffffed1015d260d8 R11: ffff8880ae9306c7 R12: ffff888074400878
R13: ffff888074400878 R14: ffff8880a4570da0 R15: ffff88809509e580
FS: 0000000000000000(0000) GS:ffff8880ae900000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000001b32f22000 CR3: 000000006f1ac000 CR4: 00000000001406e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
---
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#status for how to communicate with syzbot.
^ permalink raw reply
* Re: [PATCH] net: phy: at803x: stop switching phy delay config needlessly
From: Vladimir Oltean @ 2019-08-09 11:09 UTC (permalink / raw)
To: André Draszik
Cc: lkml, Andrew Lunn, Florian Fainelli, Heiner Kallweit,
David S. Miller, netdev
In-Reply-To: <14396bfacec0c4877cb0ea9009dc92b33c169cac.camel@andred.net>
Hi Andre,
On Fri, 9 Aug 2019 at 13:00, André Draszik <git@andred.net> wrote:
>
> Hi Vladimir,
>
> On Fri, 2019-08-09 at 12:43 +0300, Vladimir Oltean wrote:
> > Hi Andre,
> >
> > On Fri, 9 Aug 2019 at 03:58, André Draszik <git@andred.net> wrote:
> > > This driver does a funny dance disabling and re-enabling
> > > RX and/or TX delays. In any of the RGMII-ID modes, it first
> > > disables the delays, just to re-enable them again right
> > > away. This looks like a needless exercise.
> > >
> > > Just enable the respective delays when in any of the
> > > relevant 'id' modes, and disable them otherwise.
> > >
> > > Also, remove comments which don't add anything that can't be
> > > seen by looking at the code.
> > >
> > > Signed-off-by: André Draszik <git@andred.net>
> > > CC: Andrew Lunn <andrew@lunn.ch>
> > > CC: Florian Fainelli <f.fainelli@gmail.com>
> > > CC: Heiner Kallweit <hkallweit1@gmail.com>
> > > CC: "David S. Miller" <davem@davemloft.net>
> > > CC: netdev@vger.kernel.org
> > > ---
> >
> > Is there any particular problem you're facing? Does this make any difference?
>
> This is a clean-up, reducing the number of lines and if statements
> by removing unnecessary code paths and comments.
>
Ok. Did checkpatch not complain about the braces which you left open
around a single line?
>
> Cheers,
> Andre'
>
>
> >
> > > drivers/net/phy/at803x.c | 26 ++++++--------------------
> > > 1 file changed, 6 insertions(+), 20 deletions(-)
> > >
> > > diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
> > > index 222ccd9ecfce..2ab51f552e92 100644
> > > --- a/drivers/net/phy/at803x.c
> > > +++ b/drivers/net/phy/at803x.c
> > > @@ -257,35 +257,21 @@ static int at803x_config_init(struct phy_device *phydev)
> > > * after HW reset: RX delay enabled and TX delay disabled
> > > * after SW reset: RX delay enabled, while TX delay retains the
> > > * value before reset.
> > > - *
> > > - * So let's first disable the RX and TX delays in PHY and enable
> > > - * them based on the mode selected (this also takes care of RGMII
> > > - * mode where we expect delays to be disabled)
> > > */
> > > -
> > > - ret = at803x_disable_rx_delay(phydev);
> > > - if (ret < 0)
> > > - return ret;
> > > - ret = at803x_disable_tx_delay(phydev);
> > > - if (ret < 0)
> > > - return ret;
> > > -
> > > if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
> > > phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
> > > - /* If RGMII_ID or RGMII_RXID are specified enable RX delay,
> > > - * otherwise keep it disabled
> > > - */
> > > ret = at803x_enable_rx_delay(phydev);
> > > - if (ret < 0)
> > > - return ret;
> > > + } else {
> > > + ret = at803x_disable_rx_delay(phydev);
> > > }
> > > + if (ret < 0)
> > > + return ret;
> > >
> > > if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
> > > phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
> > > - /* If RGMII_ID or RGMII_TXID are specified enable TX delay,
> > > - * otherwise keep it disabled
> > > - */
> > > ret = at803x_enable_tx_delay(phydev);
> > > + } else {
> > > + ret = at803x_disable_tx_delay(phydev);
> > > }
> > >
> > > return ret;
> > > --
> > > 2.20.1
> > >
> >
> > Regards,
> > -Vladimir
>
Thanks,
-Vladimir
^ permalink raw reply
* Re: [PATCH] net: phy: at803x: stop switching phy delay config needlessly
From: André Draszik @ 2019-08-09 11:15 UTC (permalink / raw)
To: Vladimir Oltean
Cc: lkml, Andrew Lunn, Florian Fainelli, Heiner Kallweit,
David S. Miller, netdev
In-Reply-To: <CA+h21hq69YyG3zcs2dzKJBNv-UwDPZ3ARQF9Y++9sLsvf472rg@mail.gmail.com>
Hi,
On Fri, 2019-08-09 at 14:09 +0300, Vladimir Oltean wrote:
> Hi Andre,
>
> On Fri, 9 Aug 2019 at 13:00, André Draszik <git@andred.net> wrote:
> > Hi Vladimir,
> >
> > On Fri, 2019-08-09 at 12:43 +0300, Vladimir Oltean wrote:
> > > Hi Andre,
> > >
> > > On Fri, 9 Aug 2019 at 03:58, André Draszik <git@andred.net> wrote:
> > > > This driver does a funny dance disabling and re-enabling
> > > > RX and/or TX delays. In any of the RGMII-ID modes, it first
> > > > disables the delays, just to re-enable them again right
> > > > away. This looks like a needless exercise.
> > > >
> > > > Just enable the respective delays when in any of the
> > > > relevant 'id' modes, and disable them otherwise.
> > > >
> > > > Also, remove comments which don't add anything that can't be
> > > > seen by looking at the code.
> > > >
> > > > Signed-off-by: André Draszik <git@andred.net>
> > > > CC: Andrew Lunn <andrew@lunn.ch>
> > > > CC: Florian Fainelli <f.fainelli@gmail.com>
> > > > CC: Heiner Kallweit <hkallweit1@gmail.com>
> > > > CC: "David S. Miller" <davem@davemloft.net>
> > > > CC: netdev@vger.kernel.org
> > > > ---
> > >
> > > Is there any particular problem you're facing? Does this make any difference?
> >
> > This is a clean-up, reducing the number of lines and if statements
> > by removing unnecessary code paths and comments.
> >
>
> Ok. Did checkpatch not complain about the braces which you left open
> around a single line?
It actually doesn't... Should I send a v2?
Cheers,
Andre'
>
> > Cheers,
> > Andre'
> >
> >
> > > > drivers/net/phy/at803x.c | 26 ++++++--------------------
> > > > 1 file changed, 6 insertions(+), 20 deletions(-)
> > > >
> > > > diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
> > > > index 222ccd9ecfce..2ab51f552e92 100644
> > > > --- a/drivers/net/phy/at803x.c
> > > > +++ b/drivers/net/phy/at803x.c
> > > > @@ -257,35 +257,21 @@ static int at803x_config_init(struct phy_device *phydev)
> > > > * after HW reset: RX delay enabled and TX delay disabled
> > > > * after SW reset: RX delay enabled, while TX delay retains the
> > > > * value before reset.
> > > > - *
> > > > - * So let's first disable the RX and TX delays in PHY and enable
> > > > - * them based on the mode selected (this also takes care of RGMII
> > > > - * mode where we expect delays to be disabled)
> > > > */
> > > > -
> > > > - ret = at803x_disable_rx_delay(phydev);
> > > > - if (ret < 0)
> > > > - return ret;
> > > > - ret = at803x_disable_tx_delay(phydev);
> > > > - if (ret < 0)
> > > > - return ret;
> > > > -
> > > > if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
> > > > phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
> > > > - /* If RGMII_ID or RGMII_RXID are specified enable RX delay,
> > > > - * otherwise keep it disabled
> > > > - */
> > > > ret = at803x_enable_rx_delay(phydev);
> > > > - if (ret < 0)
> > > > - return ret;
> > > > + } else {
> > > > + ret = at803x_disable_rx_delay(phydev);
> > > > }
> > > > + if (ret < 0)
> > > > + return ret;
> > > >
> > > > if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
> > > > phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
> > > > - /* If RGMII_ID or RGMII_TXID are specified enable TX delay,
> > > > - * otherwise keep it disabled
> > > > - */
> > > > ret = at803x_enable_tx_delay(phydev);
> > > > + } else {
> > > > + ret = at803x_disable_tx_delay(phydev);
> > > > }
> > > >
> > > > return ret;
> > > > --
> > > > 2.20.1
> > > >
> > >
> > > Regards,
> > > -Vladimir
>
> Thanks,
> -Vladimir
^ permalink raw reply
* [PATCH v2] net: phy: at803x: stop switching phy delay config needlessly
From: André Draszik @ 2019-08-09 11:20 UTC (permalink / raw)
To: linux-kernel
Cc: André Draszik, Andrew Lunn, Florian Fainelli,
Heiner Kallweit, David S. Miller, netdev
In-Reply-To: <20190809005754.23009-1-git@andred.net>
This driver does a funny dance disabling and re-enabling
RX and/or TX delays. In any of the RGMII-ID modes, it first
disables the delays, just to re-enable them again right
away. This looks like a needless exercise.
Just enable the respective delays when in any of the
relevant 'id' modes, and disable them otherwise.
Also, remove comments which don't add anything that can't be
seen by looking at the code.
Signed-off-by: André Draszik <git@andred.net>
CC: Andrew Lunn <andrew@lunn.ch>
CC: Florian Fainelli <f.fainelli@gmail.com>
CC: Heiner Kallweit <hkallweit1@gmail.com>
CC: "David S. Miller" <davem@davemloft.net>
CC: netdev@vger.kernel.org
---
v2: also remove braces around single lines
---
drivers/net/phy/at803x.c | 32 ++++++++------------------------
1 file changed, 8 insertions(+), 24 deletions(-)
diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index 222ccd9ecfce..6ad8b1c63c34 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -257,36 +257,20 @@ static int at803x_config_init(struct phy_device *phydev)
* after HW reset: RX delay enabled and TX delay disabled
* after SW reset: RX delay enabled, while TX delay retains the
* value before reset.
- *
- * So let's first disable the RX and TX delays in PHY and enable
- * them based on the mode selected (this also takes care of RGMII
- * mode where we expect delays to be disabled)
*/
-
- ret = at803x_disable_rx_delay(phydev);
- if (ret < 0)
- return ret;
- ret = at803x_disable_tx_delay(phydev);
- if (ret < 0)
- return ret;
-
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
- phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
- /* If RGMII_ID or RGMII_RXID are specified enable RX delay,
- * otherwise keep it disabled
- */
+ phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
ret = at803x_enable_rx_delay(phydev);
- if (ret < 0)
- return ret;
- }
+ else
+ ret = at803x_disable_rx_delay(phydev);
+ if (ret < 0)
+ return ret;
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
- phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
- /* If RGMII_ID or RGMII_TXID are specified enable TX delay,
- * otherwise keep it disabled
- */
+ phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
ret = at803x_enable_tx_delay(phydev);
- }
+ else
+ ret = at803x_disable_tx_delay(phydev);
return ret;
}
--
2.20.1
^ permalink raw reply related
* Re: [PATCH net-next v2 0/9] net: macsec: initial support for hardware offloading
From: Allan W. Nielsen @ 2019-08-09 11:23 UTC (permalink / raw)
To: Antoine Tenart
Cc: davem, sd, andrew, f.fainelli, hkallweit1, netdev, linux-kernel,
thomas.petazzoni, alexandre.belloni, camelia.groza,
Simon.Edelhaus
In-Reply-To: <20190808140600.21477-1-antoine.tenart@bootlin.com>
Hi Antoine,
I have done a first read through of your patch and it looks good to me.
The only thing which confused me is all the references to Ocelot.
As far as I can see, this is a driver for the vsc8584 PHY in the Viper family.
The Ocelot confusion is properly because you are developing it on an Ocelot
board. But this is actually a modded board, the official PCB 120 and PCB123 has
a different pin compatible PHY without MACsec.
FYI: In the Viper family we have VSC8575, VSC8582, VSC8584, VSC8562 and VSC8564.
VSC8575, does not have MACsec, but all other does, and they are binary
compatible (it is the same die instantiated 2 or 4 times, with or without
MACsec/SyncE).
I beleive it is only the commit comments which needs to be addressed.
/Allan
The 08/08/2019 16:05, Antoine Tenart wrote:
> External E-Mail
>
>
> Hello,
>
> This series intends to add support for offloading MACsec transformations
> in hardware enabled devices. The series is divided in two parts: the
> first 6 patches add the infrastructure support to offload a MACsec
> configuration to hardware drivers; and the last 3 patches introduce the
> MACsec offloading support in the Microsemi Ocelot networking PHY, making
> it the first driver to support the MACsec hardware offloading feature.
>
> The series can also be found at:
> https://github.com/atenart/linux/tree/net-next/macsec
>
> MACsec hardware offloading infrastructure
> -----------------------------------------
>
> Linux has a software implementation of the MACsec standard and so far no
> hardware offloading feature was developed and submitted. Some hardware
> engines can perform MACsec operations, such as the Intel ixgbe NIC and
> the Microsemi Ocelot PHY (the one we use in this series). This means the
> MACsec offloading infrastructure should support networking PHY and
> Ethernet drivers. A preliminary email[1] was sent about this.
>
> The main idea here is to re-use the logic and data structures of the
> software MACsec implementation. This allows not to duplicate definitions
> and structure storing the same kind of information. It also allows to
> use a unified genlink interface for both MACsec implementations (so that
> the same userspace tool, `ip macsec`, is used with the same arguments).
> The MACsec offloading support cannot be disabled if an interface
> supports it at the moment, but this could be implemented later on if
> this is a need (we could think of something like
> `ip macsec set macsec0 offloading off`).
>
> Because we do reuse the software implementation logic and because the
> choice was made to expose the exact same interface to the user, a
> virtual interface is created exactly as if the MACsec software
> implementation was used. This was a big question when doing this work,
> and another approach would have been to register the genl helpers for
> all MACsec implementations and to have the software one a provider (such
> as the h/w offloading device drivers are). This would mean there would
> be no way to switch between implementations in the future at runtime.
> I'm open to discuss this point as I think this is really important and
> I'm not sure what is the best solution here.
>
> The MACsec configuration is passed to device drivers supporting it
> through MACsec ops which are called (indirectly) from the MACsec
> genl helpers. This function calls the MACsec ops of PHY and Ethernet
> drivers in two steps: a preparation one, and a commit one. The first
> step is allowed to fail and should be used to check if a provided
> configuration is compatible with the features provided by a MACsec
> engine, while the second step is not allowed to fail and should only be
> used to enable a given MACsec configuration. Two extra calls are made:
> when a virtual MACsec interface is created and when it is deleted, so
> that the hardware driver can stay in sync.
>
> The Rx and TX handlers are modified to take in account the special case
> were the MACsec transformation happens in the hardware, whether in a PHY
> or in a MAC, as the packets seen by the networking stack on both the
> physical and MACsec virtual interface are exactly the same. This leads
> to some limitations: the hardware and software implementations can't be
> used on the same physical interface, as the policies would be impossible
> to fulfill (such as strict validation of the frames). Also only a single
> virtual MACsec interface can be attached to a physical port supporting
> hardware offloading as it would be impossible to guess onto which
> interface a given packet should go (for ingress traffic).
>
> Another limitation as of now is that the counters and statistics are not
> reported back from the hardware to the software MACsec implementation.
> This isn't an issue when using offloaded MACsec transformations, but it
> should be added in the future so that the MACsec state can be reported
> to the user (which would also improve the debug).
>
> [1] https://www.spinics.net/lists/netdev/msg513047.html
>
> Microsemi Ocelot PHY MACsec support
> -----------------------------------
>
> In order to add support for the MACsec offloading feature in the
> Microsemi Ocelot driver, the __phy_read_page and __phy_write_page
> helpers had to be exported. This is because the initialization of the
> PHY is done while holding the MDIO bus lock, and we need to change the
> page to configure the MACsec block.
>
> The support itself is then added in two patches. The first one adds
> support for configuring the MACsec block within the PHY, so that it is
> up, running and available for future configuration, but is not doing any
> modification on the traffic passing through the PHY. The second patch
> implements the phy_device MACsec ops in the Microsemi Ocelot PHY driver,
> and introduce helpers to configure MACsec transformations and flows to
> match specific packets.
>
> Thanks!
> Antoine
>
> Since v1:
> - Reworked the MACsec offloading API, moving from a single helper
> called for all MACsec configuration operations, to a per-operation
> function that is provided by the underlying hardware drivers.
> - Those functions now contain a verb to describe the configuration
> action they're offloading.
> - Improved the error handling in the MACsec genl helpers to revert
> the configuration to its previous state when the offloading call
> failed.
> - Reworked the file inclusions.
>
> Antoine Tenart (9):
> net: introduce the MACSEC netdev feature
> net: macsec: move some definitions in a dedicated header
> net: macsec: introduce the macsec_context structure
> net: introduce MACsec ops and add a reference in net_device
> net: phy: add MACsec ops in phy_device
> net: macsec: hardware offloading infrastructure
> net: phy: export __phy_read_page/__phy_write_page
> net: phy: mscc: macsec initialization
> net: phy: mscc: macsec support
>
> drivers/net/macsec.c | 542 ++++++++++------
> drivers/net/phy/Kconfig | 2 +
> drivers/net/phy/mscc.c | 1024 ++++++++++++++++++++++++++++++
> drivers/net/phy/mscc_fc_buffer.h | 64 ++
> drivers/net/phy/mscc_mac.h | 159 +++++
> drivers/net/phy/mscc_macsec.h | 258 ++++++++
> drivers/net/phy/phy-core.c | 6 +-
> include/linux/netdev_features.h | 3 +
> include/linux/netdevice.h | 31 +
> include/linux/phy.h | 13 +
> include/net/macsec.h | 203 ++++++
> include/uapi/linux/if_macsec.h | 3 +-
> net/core/ethtool.c | 1 +
> 13 files changed, 2125 insertions(+), 184 deletions(-)
> create mode 100644 drivers/net/phy/mscc_fc_buffer.h
> create mode 100644 drivers/net/phy/mscc_mac.h
> create mode 100644 drivers/net/phy/mscc_macsec.h
> create mode 100644 include/net/macsec.h
>
> --
> 2.21.0
>
>
--
/Allan
^ permalink raw reply
* Re: [PATCH v3 20/41] fbdev/pvr2fb: convert put_page() to put_user_page*()
From: Bartlomiej Zolnierkiewicz @ 2019-08-09 11:38 UTC (permalink / raw)
To: john.hubbard
Cc: Andrew Morton, Christoph Hellwig, Dan Williams, Dave Chinner,
Dave Hansen, Ira Weiny, Jan Kara, Jason Gunthorpe,
Jérôme Glisse, LKML, amd-gfx, ceph-devel, devel, devel,
dri-devel, intel-gfx, kvm, linux-arm-kernel, linux-block,
linux-crypto, linux-fbdev, linux-fsdevel, linux-media, linux-mm,
linux-nfs, linux-rdma, linux-rpi-kernel, linux-xfs, netdev,
rds-devel, sparclinux, x86, xen-devel, John Hubbard, Kees Cook,
Al Viro, Bhumika Goyal, Arvind Yadav
In-Reply-To: <20190807013340.9706-21-jhubbard@nvidia.com>
On 8/7/19 3:33 AM, john.hubbard@gmail.com wrote:
> From: John Hubbard <jhubbard@nvidia.com>
>
> For pages that were retained via get_user_pages*(), release those pages
> via the new put_user_page*() routines, instead of via put_page() or
> release_pages().
>
> This is part a tree-wide conversion, as described in commit fc1d8e7cca2d
> ("mm: introduce put_user_page*(), placeholder versions").
>
> Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
> Cc: Kees Cook <keescook@chromium.org>
> Cc: Al Viro <viro@zeniv.linux.org.uk>
> Cc: Bhumika Goyal <bhumirks@gmail.com>
> Cc: Arvind Yadav <arvind.yadav.cs@gmail.com>
> Cc: dri-devel@lists.freedesktop.org
> Cc: linux-fbdev@vger.kernel.org
> Signed-off-by: John Hubbard <jhubbard@nvidia.com>
Acked-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics
> ---
> drivers/video/fbdev/pvr2fb.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/drivers/video/fbdev/pvr2fb.c b/drivers/video/fbdev/pvr2fb.c
> index 7ff4b6b84282..0e4f9aa6444d 100644
> --- a/drivers/video/fbdev/pvr2fb.c
> +++ b/drivers/video/fbdev/pvr2fb.c
> @@ -700,8 +700,7 @@ static ssize_t pvr2fb_write(struct fb_info *info, const char *buf,
> ret = count;
>
> out_unmap:
> - for (i = 0; i < nr_pages; i++)
> - put_page(pages[i]);
> + put_user_pages(pages, nr_pages);
>
> kfree(pages);
^ permalink raw reply
* Re: [PATCH net-next v2 0/9] net: macsec: initial support for hardware offloading
From: Antoine Tenart @ 2019-08-09 11:40 UTC (permalink / raw)
To: Allan W. Nielsen
Cc: Antoine Tenart, davem, sd, andrew, f.fainelli, hkallweit1, netdev,
linux-kernel, thomas.petazzoni, alexandre.belloni, camelia.groza,
Simon.Edelhaus
In-Reply-To: <20190809112344.5anl7wq5df5ctj26@lx-anielsen.microsemi.net>
Hi Allan,
On Fri, Aug 09, 2019 at 01:23:47PM +0200, Allan W. Nielsen wrote:
>
> I have done a first read through of your patch and it looks good to me.
>
> The only thing which confused me is all the references to Ocelot.
>
> As far as I can see, this is a driver for the vsc8584 PHY in the Viper family.
> The Ocelot confusion is properly because you are developing it on an Ocelot
> board. But this is actually a modded board, the official PCB 120 and PCB123 has
> a different pin compatible PHY without MACsec.
>
> FYI: In the Viper family we have VSC8575, VSC8582, VSC8584, VSC8562 and VSC8564.
>
> VSC8575, does not have MACsec, but all other does, and they are binary
> compatible (it is the same die instantiated 2 or 4 times, with or without
> MACsec/SyncE).
>
> I beleive it is only the commit comments which needs to be addressed.
That's right, I mixed up Ocelot and the actual PHY names. I'll look for
Ocelot references in the patches and I'll fix it in v3.
Thanks for spotting this,
Antoine
--
Antoine Ténart, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: [PATCH v2 02/15] net: phy: adin: hook genphy_read_abilities() to get_features
From: Ardelean, Alexandru @ 2019-08-09 12:00 UTC (permalink / raw)
To: hkallweit1@gmail.com, andrew@lunn.ch
Cc: f.fainelli@gmail.com, mark.rutland@arm.com,
devicetree@vger.kernel.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, robh+dt@kernel.org,
davem@davemloft.net
In-Reply-To: <eeda87c9-bdba-8ef7-6043-85a16bd2cfc2@gmail.com>
On Thu, 2019-08-08 at 21:32 +0200, Heiner Kallweit wrote:
> [External]
>
> On 08.08.2019 17:24, Andrew Lunn wrote:
> > On Thu, Aug 08, 2019 at 03:30:13PM +0300, Alexandru Ardelean wrote:
> > > The ADIN PHYs can operate with Clause 45, however they are not typical for
> > > how phylib considers Clause 45 PHYs.
> > >
> > > If the `features` field & the `get_features` hook are unspecified, and the
> > > device wants to operate via Clause 45, it would also try to read features
> > > via the `genphy_c45_pma_read_abilities()`, which will try to read PMA regs
> > > that are unsupported.
> > >
> > > Hooking the `genphy_read_abilities()` function to the `get_features` hook
> > > will ensure that this does not happen and the PHY features are read
> > > correctly regardless of Clause 22 or Clause 45 operation.
> >
> > I think we need to stop and think about a PHY which supports both C22
> > and C45.
> >
> > How does bus enumeration work? Is it discovered twice? I've always
> > considered phydev->is_c45 means everything is c45, not that some
> > registers can be accessed via c45. But the driver is mixing c22 and
> > c45. Does the driver actually require c45? Are some features which are
> > only accessibly via C45? What does C45 actually bring us for this
> > device?
> >
Hmm, I can't answer [all] these questions.
These PHYs seem to be a bit different from the rest that I looked at in drivers/net/phy with regard to C45 & C22.
And C45 seems to be more/closer related to 10G PHYs [from what I can tell].
The ADIN PHYs can operate only in C22.
The only thing that is needed [and a bit special] is EEE, which [for C22] requires the translation layer to convert C45
reg addresses to internal C22 equivalent.
> genphy_c45_pma_read_abilities() is only called if phydev->is_c45 is set.
> And this flag means that the PHY complies with Clause 45 incl. all the
> standard devices like PMA. In the case here only some vendor-specific
> registers can be accessed via Clause 45 and therefore is_c45 shouldn't
> bet set. As a consequence this patch isn't needed.
ack, will drop patch
>
> > Andrew
> >
> Heiner
>
^ permalink raw reply
* [PATCH net-next] tcp: batch calls to sk_flush_backlog()
From: Eric Dumazet @ 2019-08-09 12:04 UTC (permalink / raw)
To: David S . Miller
Cc: netdev, Eric Dumazet, Eric Dumazet, Soheil Hassas Yeganeh
Starting from commit d41a69f1d390 ("tcp: make tcp_sendmsg() aware of socket backlog")
loopback flows got hurt, because for each skb sent, the socket receives an
immediate ACK and sk_flush_backlog() causes extra work.
Intent was to not let the backlog grow too much, but we went a bit too far.
We can check the backlog every 16 skbs (about 1MB chunks)
to increase TCP over loopback performance by about 15 %
Note that the call to sk_flush_backlog() handles a single ACK,
thanks to coalescing done on backlog, but cleans the 16 skbs
found in rtx rb-tree.
Reported-by: Soheil Hassas Yeganeh <soheil@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
net/ipv4/tcp.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index a0a66321c0ee99918b2080219dbaefcf3c398e13..f8fa1686f7f3e64f5d4ea8163e7f87538cc0d672 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1162,7 +1162,7 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size)
struct sockcm_cookie sockc;
int flags, err, copied = 0;
int mss_now = 0, size_goal, copied_syn = 0;
- bool process_backlog = false;
+ int process_backlog = 0;
bool zc = false;
long timeo;
@@ -1254,9 +1254,10 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size)
if (!sk_stream_memory_free(sk))
goto wait_for_sndbuf;
- if (process_backlog && sk_flush_backlog(sk)) {
- process_backlog = false;
- goto restart;
+ if (unlikely(process_backlog >= 16)) {
+ process_backlog = 0;
+ if (sk_flush_backlog(sk))
+ goto restart;
}
first_skb = tcp_rtx_and_write_queues_empty(sk);
skb = sk_stream_alloc_skb(sk, 0, sk->sk_allocation,
@@ -1264,7 +1265,7 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size)
if (!skb)
goto wait_for_memory;
- process_backlog = true;
+ process_backlog++;
skb->ip_summed = CHECKSUM_PARTIAL;
skb_entail(sk, skb);
--
2.23.0.rc1.153.gdeed80330f-goog
^ permalink raw reply related
* Re: [PATCH v2 05/15] net: phy: adin: add {write,read}_mmd hooks
From: Ardelean, Alexandru @ 2019-08-09 12:05 UTC (permalink / raw)
To: andrew@lunn.ch
Cc: davem@davemloft.net, hkallweit1@gmail.com,
devicetree@vger.kernel.org, mark.rutland@arm.com,
linux-kernel@vger.kernel.org, f.fainelli@gmail.com,
netdev@vger.kernel.org, robh+dt@kernel.org
In-Reply-To: <20190808153514.GE27917@lunn.ch>
On Thu, 2019-08-08 at 17:35 +0200, Andrew Lunn wrote:
> [External]
>
> On Thu, Aug 08, 2019 at 03:30:16PM +0300, Alexandru Ardelean wrote:
> > Both ADIN1200 & ADIN1300 support Clause 45 access.
> > The Extended Management Interface (EMI) registers are accessible via both
> > Clause 45 (at register MDIO_MMD_VEND1) and using Clause 22.
> >
> > However, the Clause 22 MMD access operations differ from the implementation
> > in the kernel, in the sense that it uses registers ExtRegPtr (0x10) &
> > ExtRegData (0x11) to access Clause 45 & EMI registers.
>
> It is not that they differ from what the kernel supports. Its that
> they differ from what the Standard says they should use. These
> registers are defined in 802.3, part of C22, and this hardware
> implements the standard incorrectly.
Will update comment.
I did not find a document describing this as a standard.
But, I admit I am terrible when finding some docs.
I only found this presentation from a while back:
http://www.ieee802.org/3/efm/public/nov02/oam/pannell_oam_1_1102.pdf
It seemed more like a proposal.
Thanks
Alex
>
> Andrew
^ permalink raw reply
* Re: [PATCH v2 13/15] net: phy: adin: configure downshift on config_init
From: Ardelean, Alexandru @ 2019-08-09 12:06 UTC (permalink / raw)
To: hkallweit1@gmail.com, andrew@lunn.ch
Cc: f.fainelli@gmail.com, mark.rutland@arm.com,
devicetree@vger.kernel.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, robh+dt@kernel.org,
davem@davemloft.net
In-Reply-To: <20190808203932.GP27917@lunn.ch>
On Thu, 2019-08-08 at 22:39 +0200, Andrew Lunn wrote:
> [External]
>
> On Thu, Aug 08, 2019 at 09:38:40PM +0200, Heiner Kallweit wrote:
> > On 08.08.2019 14:30, Alexandru Ardelean wrote:
> > > Down-speed auto-negotiation may not always be enabled, in which case the
> > > PHY won't down-shift to 100 or 10 during auto-negotiation.
> > >
> > > This change enables downshift and configures the number of retries to
> > > default 8 (maximum supported value).
> > >
> > > The change has been adapted from the Marvell PHY driver.
> > >
> > Instead of a fixed downshift setting (like in the Marvell driver) you
> > may consider to implement the ethtool phy-tunable ETHTOOL_PHY_DOWNSHIFT.
>
> Hi Alexandru
>
> Upps, sorry, my bad.
>
> I looked at marvell_set_downshift(), and assumed it was connected to
> the phy-tunable. I have patches somewhere which does that. But they
> have not made it into mainline yet.
>
> > See the Aquantia PHY driver for an example.
>
> Yes, that does have all the tunable stuff.
Ack.
Will use that
>
> Andrew
^ permalink raw reply
* Re: [PATCH v2 15/15] dt-bindings: net: add bindings for ADIN PHY driver
From: Ardelean, Alexandru @ 2019-08-09 12:06 UTC (permalink / raw)
To: robh+dt@kernel.org
Cc: andrew@lunn.ch, davem@davemloft.net, hkallweit1@gmail.com,
devicetree@vger.kernel.org, mark.rutland@arm.com,
linux-kernel@vger.kernel.org, f.fainelli@gmail.com,
netdev@vger.kernel.org
In-Reply-To: <CAL_Jsq+zH9cL5-8aDARzPar+xoD71WbESTckGjzaUTodu-+Trg@mail.gmail.com>
On Thu, 2019-08-08 at 17:03 -0600, Rob Herring wrote:
> [External]
>
> On Thu, Aug 8, 2019 at 6:31 AM Alexandru Ardelean
> <alexandru.ardelean@analog.com> wrote:
> > This change adds bindings for the Analog Devices ADIN PHY driver, detailing
> > all the properties implemented by the driver.
> >
> > Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
> > ---
> > .../devicetree/bindings/net/adi,adin.yaml | 76 +++++++++++++++++++
> > MAINTAINERS | 1 +
> > 2 files changed, 77 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/net/adi,adin.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/net/adi,adin.yaml
> > b/Documentation/devicetree/bindings/net/adi,adin.yaml
> > new file mode 100644
> > index 000000000000..86177c8fe23a
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/net/adi,adin.yaml
> > @@ -0,0 +1,76 @@
> > +# SPDX-License-Identifier: GPL-2.0+
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/net/adi,adin.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Analog Devices ADIN1200/ADIN1300 PHY
> > +
> > +maintainers:
> > + - Alexandru Ardelean <alexandru.ardelean@analog.com>
> > +
> > +description: |
> > + Bindings for Analog Devices Industrial Ethernet PHYs
> > +
> > +allOf:
> > + - $ref: ethernet-phy.yaml#
> > +
> > +properties:
> > + adi,rx-internal-delay-ps:
> > + $ref: /schemas/types.yaml#/definitions/uint32
> > + description: |
> > + RGMII RX Clock Delay used only when PHY operates in RGMII mode with
> > + internal delay (phy-mode is 'rgmii-id' or 'rgmii-rxid') in pico-seconds.
> > + enum: [ 1600, 1800, 2000, 2200, 2400 ]
> > + default: 2000
>
> This doesn't actually do what you think. The '$ref' has to be under an
> 'allOf' to work. It's an oddity of json-schema. However, anything with
> a standard unit suffix already has a schema to define the type, so you
> don't need to here and can just drop $ref.
ack
will drop
>
> > +
> > + adi,tx-internal-delay-ps:
> > + $ref: /schemas/types.yaml#/definitions/uint32
> > + description: |
> > + RGMII TX Clock Delay used only when PHY operates in RGMII mode with
> > + internal delay (phy-mode is 'rgmii-id' or 'rgmii-txid') in pico-seconds.
> > + enum: [ 1600, 1800, 2000, 2200, 2400 ]
> > + default: 2000
> > +
> > + adi,fifo-depth-bits:
> > + $ref: /schemas/types.yaml#/definitions/uint32
> > + description: |
> > + When operating in RMII mode, this option configures the FIFO depth.
> > + enum: [ 4, 8, 12, 16, 20, 24 ]
> > + default: 8
> > +
> > + adi,disable-energy-detect:
> > + description: |
> > + Disables Energy Detect Powerdown Mode (default disabled, i.e energy detect
> > + is enabled if this property is unspecified)
> > + type: boolean
> > +
> > +examples:
> > + - |
> > + ethernet {
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > +
> > + phy-mode = "rgmii-id";
> > +
> > + ethernet-phy@0 {
> > + reg = <0>;
> > +
> > + adi,rx-internal-delay-ps = <1800>;
> > + adi,tx-internal-delay-ps = <2200>;
> > + };
> > + };
> > + - |
> > + ethernet {
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > +
> > + phy-mode = "rmii";
> > +
> > + ethernet-phy@1 {
> > + reg = <1>;
> > +
> > + adi,fifo-depth-bits = <16>;
> > + adi,disable-energy-detect;
> > + };
> > + };
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index e8aa8a667864..fd9ab61c2670 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -944,6 +944,7 @@ L: netdev@vger.kernel.org
> > W: http://ez.analog.com/community/linux-device-drivers
> > S: Supported
> > F: drivers/net/phy/adin.c
> > +F: Documentation/devicetree/bindings/net/adi,adin.yaml
> >
> > ANALOG DEVICES INC ADIS DRIVER LIBRARY
> > M: Alexandru Ardelean <alexandru.ardelean@analog.com>
> > --
> > 2.20.1
> >
^ permalink raw reply
* Re: [PATCH v3 38/41] powerpc: convert put_page() to put_user_page*()
From: Michael Ellerman @ 2019-08-09 12:20 UTC (permalink / raw)
To: John Hubbard, Andrew Morton
Cc: Christoph Hellwig, Dan Williams, Dave Chinner, Dave Hansen,
Ira Weiny, Jan Kara, Jason Gunthorpe, Jérôme Glisse,
LKML, amd-gfx, ceph-devel, devel, devel, dri-devel, intel-gfx,
kvm, linux-arm-kernel, linux-block, linux-crypto, linux-fbdev,
linux-fsdevel, linux-media, linux-mm, linux-nfs, linux-rdma,
linux-rpi-kernel, linux-xfs, netdev, rds-devel, sparclinux, x86,
xen-devel, Benjamin Herrenschmidt, Christoph Hellwig,
linuxppc-dev
In-Reply-To: <248c9ab2-93cc-6d8b-606d-d85b83e791e5@nvidia.com>
John Hubbard <jhubbard@nvidia.com> writes:
> On 8/7/19 10:42 PM, Michael Ellerman wrote:
>> Hi John,
>>
>> john.hubbard@gmail.com writes:
>>> diff --git a/arch/powerpc/mm/book3s64/iommu_api.c b/arch/powerpc/mm/book3s64/iommu_api.c
>>> index b056cae3388b..e126193ba295 100644
>>> --- a/arch/powerpc/mm/book3s64/iommu_api.c
>>> +++ b/arch/powerpc/mm/book3s64/iommu_api.c
>>> @@ -203,6 +202,7 @@ static void mm_iommu_unpin(struct mm_iommu_table_group_mem_t *mem)
>>> {
>>> long i;
>>> struct page *page = NULL;
>>> + bool dirty = false;
>>
>> I don't think you need that initialisation do you?
>>
>
> Nope, it can go. Fixed locally, thanks.
Thanks.
> Did you get a chance to look at enough of the other bits to feel comfortable
> with the patch, overall?
Mostly :) It's not really my area, but all the conversions looked
correct to me as best as I could tell.
So I'm fine for it to go in as part of the series:
Acked-by: Michael Ellerman <mpe@ellerman.id.au> (powerpc)
cheers
^ permalink raw reply
* Re: [PATCH v3 5/7] mfd: ioc3: Add driver for SGI IOC3 chip
From: Alexandre Belloni @ 2019-08-09 12:22 UTC (permalink / raw)
To: Thomas Bogendoerfer
Cc: Lee Jones, Ralf Baechle, Paul Burton, James Hogan,
Dmitry Torokhov, David S. Miller, Srinivas Kandagatla,
Alessandro Zummo, Greg Kroah-Hartman, Jiri Slaby, linux-mips,
linux-kernel, linux-input, netdev, linux-rtc, linux-serial
In-Reply-To: <20190729204557.468db2153efefda96dd41ec0@suse.de>
On 29/07/2019 20:45:57+0200, Thomas Bogendoerfer wrote:
> On Thu, 25 Jul 2019 12:47:16 +0100
> Lee Jones <lee.jones@linaro.org> wrote:
>
> > On Thu, 13 Jun 2019, Thomas Bogendoerfer wrote:
> > > +/*
> > > + * On IP30 the RTC (a DS1687) is behind the IOC3 on the generic
> > > + * ByteBus regions. We have to write the RTC address of interest to
> > > + * IOC3_BYTEBUS_DEV1, then read the data from IOC3_BYTEBUS_DEV2.
> > > + * rtc->regs already points to IOC3_BYTEBUS_DEV1.
> > > + */
> > > +#define IP30_RTC_ADDR(rtc) (rtc->regs)
> > > +#define IP30_RTC_DATA(rtc) ((rtc->regs) + IOC3_BYTEBUS_DEV2 - IOC3_BYTEBUS_DEV1)
> > > +
> > > +static u8 ip30_rtc_read(struct ds1685_priv *rtc, int reg)
> > > +{
> > > + writeb((reg & 0x7f), IP30_RTC_ADDR(rtc));
> > > + return readb(IP30_RTC_DATA(rtc));
> > > +}
> > > +
> > > +static void ip30_rtc_write(struct ds1685_priv *rtc, int reg, u8 value)
> > > +{
> > > + writeb((reg & 0x7f), IP30_RTC_ADDR(rtc));
> > > + writeb(value, IP30_RTC_DATA(rtc));
> > > +}
> >
> > Why is this not in the RTC driver?
>
> because rtc1685 is used in different systems and accessing the chip
> differs between those systems.
>
> > > +static struct ds1685_rtc_platform_data ip30_rtc_platform_data = {
> > > + .bcd_mode = false,
> > > + .no_irq = false,
> > > + .uie_unsupported = true,
> > > + .alloc_io_resources = true,
> >
> > > + .plat_read = ip30_rtc_read,
> > > + .plat_write = ip30_rtc_write,
> >
> > Call-backs in a non-subsystem API is pretty ugly IMHO.
>
> I agree
>
> > Where are these called from?
>
> drivers/rtc/rtc-ds1685.c
>
> I could do the same as done for serial8250 and add an additional .c file
> in drivers/rtc which handles this for SGI-IP30. Alexandre would this work
> for you as well ?
>
As it is not particularly big, you could put that directly in
rtc-ds1685.c.
--
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: [PATCH 00/17] Networking driver debugfs cleanups
From: Greg KH @ 2019-08-09 12:30 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20190808.184237.1532563308186831482.davem@davemloft.net>
On Thu, Aug 08, 2019 at 06:42:37PM -0700, David Miller wrote:
> From: David Miller <davem@davemloft.net>
> Date: Thu, 08 Aug 2019 18:37:56 -0700 (PDT)
>
> > I applied this without patch #17 which you said you would respin in order
> > to get rid of the now unused local variable.
>
> Actually, there is a bunch of fallout still:
>
> drivers/net/wimax/i2400m/debugfs.c: In function ‘i2400m_debugfs_add’:
> drivers/net/wimax/i2400m/debugfs.c:192:17: warning: unused variable ‘dev’ [-Wunused-variable]
> struct device *dev = i2400m_dev(i2400m);
> ^~~
> drivers/net/wimax/i2400m/usb.c: In function ‘i2400mu_debugfs_add’:
> drivers/net/wimax/i2400m/usb.c:375:17: warning: unused variable ‘fd’ [-Wunused-variable]
> struct dentry *fd;
> ^~
> drivers/net/wimax/i2400m/usb.c:373:17: warning: unused variable ‘dev’ [-Wunused-variable]
> struct device *dev = &i2400mu->usb_iface->dev;
> ^~~
> drivers/net/wimax/i2400m/usb.c:372:6: warning: unused variable ‘result’ [-Wunused-variable]
> int result;
> ^~~~~~
> drivers/net/ethernet/intel/i40e/i40e_debugfs.c: In function ‘i40e_dbg_pf_init’:
> drivers/net/ethernet/intel/i40e/i40e_debugfs.c:1736:23: warning: unused variable ‘dev’ [-Wunused-variable]
> const struct device *dev = &pf->pdev->dev;
> ^~~
>
> This is with:
>
> [davem@localhost net-next]$ gcc --version
> gcc (GCC) 8.3.1 20190223 (Red Hat 8.3.1-2)
> Copyright (C) 2018 Free Software Foundation, Inc.
> This is free software; see the source for copying conditions. There is NO
> warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
>
> [davem@localhost net-next]$
>
> So I'm reverting.
>
> Please respin the series with this stuff fixed, thanks Greg.
Ugh, that sucks, it looks like I never even built this series. My
apologies for wasting people's time.
Let me fix this all up, properly build it, and resend.
thanks,
greg k-h
^ permalink raw reply
* [PATCH v2 01/17] wimax: no need to check return value of debugfs_create functions
From: Greg Kroah-Hartman @ 2019-08-09 12:30 UTC (permalink / raw)
To: netdev; +Cc: Greg Kroah-Hartman, Inaky Perez-Gonzalez, linux-wimax
In-Reply-To: <20190809123108.27065-1-gregkh@linuxfoundation.org>
When calling debugfs functions, there is no need to ever check the
return value. The function can work or not, but the code logic should
never do something different based on this.
This cleans up a lot of unneeded code and logic around the debugfs wimax
files, making all of this much simpler and easier to understand.
Cc: Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
Cc: linux-wimax@intel.com
Cc: netdev@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wimax/i2400m/debugfs.c | 149 +++++------------------------
drivers/net/wimax/i2400m/driver.c | 7 +-
drivers/net/wimax/i2400m/i2400m.h | 7 +-
drivers/net/wimax/i2400m/usb.c | 64 +++----------
include/linux/wimax/debug.h | 20 +---
net/wimax/debugfs.c | 42 ++------
net/wimax/stack.c | 11 +--
net/wimax/wimax-internal.h | 7 +-
8 files changed, 51 insertions(+), 256 deletions(-)
diff --git a/drivers/net/wimax/i2400m/debugfs.c b/drivers/net/wimax/i2400m/debugfs.c
index 6544ac9df047..01492c1fa70b 100644
--- a/drivers/net/wimax/i2400m/debugfs.c
+++ b/drivers/net/wimax/i2400m/debugfs.c
@@ -30,15 +30,6 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_netdev_queue_stopped,
debugfs_netdev_queue_stopped_get,
NULL, "%llu\n");
-
-static
-struct dentry *debugfs_create_netdev_queue_stopped(
- const char *name, struct dentry *parent, struct i2400m *i2400m)
-{
- return debugfs_create_file(name, 0400, parent, i2400m,
- &fops_netdev_queue_stopped);
-}
-
/*
* We don't allow partial reads of this file, as then the reader would
* get weirdly confused data as it is updated.
@@ -167,15 +158,6 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_i2400m_suspend,
NULL, debugfs_i2400m_suspend_set,
"%llu\n");
-static
-struct dentry *debugfs_create_i2400m_suspend(
- const char *name, struct dentry *parent, struct i2400m *i2400m)
-{
- return debugfs_create_file(name, 0200, parent, i2400m,
- &fops_i2400m_suspend);
-}
-
-
/*
* Reset the device
*
@@ -205,73 +187,26 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_i2400m_reset,
NULL, debugfs_i2400m_reset_set,
"%llu\n");
-static
-struct dentry *debugfs_create_i2400m_reset(
- const char *name, struct dentry *parent, struct i2400m *i2400m)
+void i2400m_debugfs_add(struct i2400m *i2400m)
{
- return debugfs_create_file(name, 0200, parent, i2400m,
- &fops_i2400m_reset);
-}
-
-
-#define __debugfs_register(prefix, name, parent) \
-do { \
- result = d_level_register_debugfs(prefix, name, parent); \
- if (result < 0) \
- goto error; \
-} while (0)
-
-
-int i2400m_debugfs_add(struct i2400m *i2400m)
-{
- int result;
struct device *dev = i2400m_dev(i2400m);
struct dentry *dentry = i2400m->wimax_dev.debugfs_dentry;
- struct dentry *fd;
dentry = debugfs_create_dir("i2400m", dentry);
- result = PTR_ERR(dentry);
- if (IS_ERR(dentry)) {
- if (result == -ENODEV)
- result = 0; /* No debugfs support */
- goto error;
- }
i2400m->debugfs_dentry = dentry;
- __debugfs_register("dl_", control, dentry);
- __debugfs_register("dl_", driver, dentry);
- __debugfs_register("dl_", debugfs, dentry);
- __debugfs_register("dl_", fw, dentry);
- __debugfs_register("dl_", netdev, dentry);
- __debugfs_register("dl_", rfkill, dentry);
- __debugfs_register("dl_", rx, dentry);
- __debugfs_register("dl_", tx, dentry);
-
- fd = debugfs_create_size_t("tx_in", 0400, dentry,
- &i2400m->tx_in);
- result = PTR_ERR(fd);
- if (IS_ERR(fd) && result != -ENODEV) {
- dev_err(dev, "Can't create debugfs entry "
- "tx_in: %d\n", result);
- goto error;
- }
- fd = debugfs_create_size_t("tx_out", 0400, dentry,
- &i2400m->tx_out);
- result = PTR_ERR(fd);
- if (IS_ERR(fd) && result != -ENODEV) {
- dev_err(dev, "Can't create debugfs entry "
- "tx_out: %d\n", result);
- goto error;
- }
+ d_level_register_debugfs("dl_", control, dentry);
+ d_level_register_debugfs("dl_", driver, dentry);
+ d_level_register_debugfs("dl_", debugfs, dentry);
+ d_level_register_debugfs("dl_", fw, dentry);
+ d_level_register_debugfs("dl_", netdev, dentry);
+ d_level_register_debugfs("dl_", rfkill, dentry);
+ d_level_register_debugfs("dl_", rx, dentry);
+ d_level_register_debugfs("dl_", tx, dentry);
- fd = debugfs_create_u32("state", 0600, dentry,
- &i2400m->state);
- result = PTR_ERR(fd);
- if (IS_ERR(fd) && result != -ENODEV) {
- dev_err(dev, "Can't create debugfs entry "
- "state: %d\n", result);
- goto error;
- }
+ debugfs_create_size_t("tx_in", 0400, dentry, &i2400m->tx_in);
+ debugfs_create_size_t("tx_out", 0400, dentry, &i2400m->tx_out);
+ debugfs_create_u32("state", 0600, dentry, &i2400m->state);
/*
* Trace received messages from user space
@@ -295,60 +230,22 @@ int i2400m_debugfs_add(struct i2400m *i2400m)
* It is not really very atomic, but it is also not too
* critical.
*/
- fd = debugfs_create_u8("trace_msg_from_user", 0600, dentry,
- &i2400m->trace_msg_from_user);
- result = PTR_ERR(fd);
- if (IS_ERR(fd) && result != -ENODEV) {
- dev_err(dev, "Can't create debugfs entry "
- "trace_msg_from_user: %d\n", result);
- goto error;
- }
+ debugfs_create_u8("trace_msg_from_user", 0600, dentry,
+ &i2400m->trace_msg_from_user);
- fd = debugfs_create_netdev_queue_stopped("netdev_queue_stopped",
- dentry, i2400m);
- result = PTR_ERR(fd);
- if (IS_ERR(fd) && result != -ENODEV) {
- dev_err(dev, "Can't create debugfs entry "
- "netdev_queue_stopped: %d\n", result);
- goto error;
- }
+ debugfs_create_file("netdev_queue_stopped", 0400, dentry, i2400m,
+ &fops_netdev_queue_stopped);
- fd = debugfs_create_file("rx_stats", 0600, dentry, i2400m,
- &i2400m_rx_stats_fops);
- result = PTR_ERR(fd);
- if (IS_ERR(fd) && result != -ENODEV) {
- dev_err(dev, "Can't create debugfs entry "
- "rx_stats: %d\n", result);
- goto error;
- }
+ debugfs_create_file("rx_stats", 0600, dentry, i2400m,
+ &i2400m_rx_stats_fops);
- fd = debugfs_create_file("tx_stats", 0600, dentry, i2400m,
- &i2400m_tx_stats_fops);
- result = PTR_ERR(fd);
- if (IS_ERR(fd) && result != -ENODEV) {
- dev_err(dev, "Can't create debugfs entry "
- "tx_stats: %d\n", result);
- goto error;
- }
+ debugfs_create_file("tx_stats", 0600, dentry, i2400m,
+ &i2400m_tx_stats_fops);
- fd = debugfs_create_i2400m_suspend("suspend", dentry, i2400m);
- result = PTR_ERR(fd);
- if (IS_ERR(fd) && result != -ENODEV) {
- dev_err(dev, "Can't create debugfs entry suspend: %d\n",
- result);
- goto error;
- }
+ debugfs_create_file("suspend", 0200, dentry, i2400m,
+ &fops_i2400m_suspend);
- fd = debugfs_create_i2400m_reset("reset", dentry, i2400m);
- result = PTR_ERR(fd);
- if (IS_ERR(fd) && result != -ENODEV) {
- dev_err(dev, "Can't create debugfs entry reset: %d\n", result);
- goto error;
- }
-
- result = 0;
-error:
- return result;
+ debugfs_create_file("reset", 0200, dentry, i2400m, &fops_i2400m_reset);
}
void i2400m_debugfs_rm(struct i2400m *i2400m)
diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c
index 0a29222a1bf9..f66c0f8f6f4a 100644
--- a/drivers/net/wimax/i2400m/driver.c
+++ b/drivers/net/wimax/i2400m/driver.c
@@ -905,11 +905,7 @@ int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags)
goto error_sysfs_setup;
}
- result = i2400m_debugfs_add(i2400m);
- if (result < 0) {
- dev_err(dev, "cannot setup i2400m's debugfs: %d\n", result);
- goto error_debugfs_setup;
- }
+ i2400m_debugfs_add(i2400m);
result = i2400m_dev_start(i2400m, bm_flags);
if (result < 0)
@@ -919,7 +915,6 @@ int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags)
error_dev_start:
i2400m_debugfs_rm(i2400m);
-error_debugfs_setup:
sysfs_remove_group(&i2400m->wimax_dev.net_dev->dev.kobj,
&i2400m_dev_attr_group);
error_sysfs_setup:
diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h
index 5a34e72bab9a..a3733a6d14f5 100644
--- a/drivers/net/wimax/i2400m/i2400m.h
+++ b/drivers/net/wimax/i2400m/i2400m.h
@@ -812,13 +812,10 @@ enum i2400m_pt;
int i2400m_tx(struct i2400m *, const void *, size_t, enum i2400m_pt);
#ifdef CONFIG_DEBUG_FS
-int i2400m_debugfs_add(struct i2400m *);
+void i2400m_debugfs_add(struct i2400m *);
void i2400m_debugfs_rm(struct i2400m *);
#else
-static inline int i2400m_debugfs_add(struct i2400m *i2400m)
-{
- return 0;
-}
+static inline void i2400m_debugfs_add(struct i2400m *i2400m) {}
static inline void i2400m_debugfs_rm(struct i2400m *i2400m) {}
#endif
diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c
index 2075e7b1fff6..6953f904232f 100644
--- a/drivers/net/wimax/i2400m/usb.c
+++ b/drivers/net/wimax/i2400m/usb.c
@@ -366,61 +366,25 @@ struct d_level D_LEVEL[] = {
};
size_t D_LEVEL_SIZE = ARRAY_SIZE(D_LEVEL);
-
-#define __debugfs_register(prefix, name, parent) \
-do { \
- result = d_level_register_debugfs(prefix, name, parent); \
- if (result < 0) \
- goto error; \
-} while (0)
-
-
static
-int i2400mu_debugfs_add(struct i2400mu *i2400mu)
+void i2400mu_debugfs_add(struct i2400mu *i2400mu)
{
- int result;
- struct device *dev = &i2400mu->usb_iface->dev;
struct dentry *dentry = i2400mu->i2400m.wimax_dev.debugfs_dentry;
- struct dentry *fd;
dentry = debugfs_create_dir("i2400m-usb", dentry);
- result = PTR_ERR(dentry);
- if (IS_ERR(dentry)) {
- if (result == -ENODEV)
- result = 0; /* No debugfs support */
- goto error;
- }
i2400mu->debugfs_dentry = dentry;
- __debugfs_register("dl_", usb, dentry);
- __debugfs_register("dl_", fw, dentry);
- __debugfs_register("dl_", notif, dentry);
- __debugfs_register("dl_", rx, dentry);
- __debugfs_register("dl_", tx, dentry);
- /* Don't touch these if you don't know what you are doing */
- fd = debugfs_create_u8("rx_size_auto_shrink", 0600, dentry,
- &i2400mu->rx_size_auto_shrink);
- result = PTR_ERR(fd);
- if (IS_ERR(fd) && result != -ENODEV) {
- dev_err(dev, "Can't create debugfs entry "
- "rx_size_auto_shrink: %d\n", result);
- goto error;
- }
+ d_level_register_debugfs("dl_", usb, dentry);
+ d_level_register_debugfs("dl_", fw, dentry);
+ d_level_register_debugfs("dl_", notif, dentry);
+ d_level_register_debugfs("dl_", rx, dentry);
+ d_level_register_debugfs("dl_", tx, dentry);
- fd = debugfs_create_size_t("rx_size", 0600, dentry,
- &i2400mu->rx_size);
- result = PTR_ERR(fd);
- if (IS_ERR(fd) && result != -ENODEV) {
- dev_err(dev, "Can't create debugfs entry "
- "rx_size: %d\n", result);
- goto error;
- }
-
- return 0;
+ /* Don't touch these if you don't know what you are doing */
+ debugfs_create_u8("rx_size_auto_shrink", 0600, dentry,
+ &i2400mu->rx_size_auto_shrink);
-error:
- debugfs_remove_recursive(i2400mu->debugfs_dentry);
- return result;
+ debugfs_create_size_t("rx_size", 0600, dentry, &i2400mu->rx_size);
}
@@ -534,15 +498,9 @@ int i2400mu_probe(struct usb_interface *iface,
dev_err(dev, "cannot setup device: %d\n", result);
goto error_setup;
}
- result = i2400mu_debugfs_add(i2400mu);
- if (result < 0) {
- dev_err(dev, "Can't register i2400mu's debugfs: %d\n", result);
- goto error_debugfs_add;
- }
+ i2400mu_debugfs_add(i2400mu);
return 0;
-error_debugfs_add:
- i2400m_release(i2400m);
error_setup:
usb_set_intfdata(iface, NULL);
usb_put_dev(i2400mu->usb_dev);
diff --git a/include/linux/wimax/debug.h b/include/linux/wimax/debug.h
index 7cb63e4ec0ae..4dd2c1cea6a9 100644
--- a/include/linux/wimax/debug.h
+++ b/include/linux/wimax/debug.h
@@ -98,9 +98,7 @@
* To manipulate from user space the levels, create a debugfs dentry
* and then register each submodule with:
*
- * result = d_level_register_debugfs("PREFIX_", submodule_X, parent);
- * if (result < 0)
- * goto error;
+ * d_level_register_debugfs("PREFIX_", submodule_X, parent);
*
* Where PREFIX_ is a name of your chosing. This will create debugfs
* file with a single numeric value that can be use to tweak it. To
@@ -408,25 +406,13 @@ do { \
* @submodule: name of submodule (not a string, just the name)
* @dentry: debugfs parent dentry
*
- * Returns: 0 if ok, < 0 errno on error.
- *
* For removing, just use debugfs_remove_recursive() on the parent.
*/
#define d_level_register_debugfs(prefix, name, parent) \
({ \
- int rc; \
- struct dentry *fd; \
- struct dentry *verify_parent_type = parent; \
- fd = debugfs_create_u8( \
- prefix #name, 0600, verify_parent_type, \
+ debugfs_create_u8( \
+ prefix #name, 0600, parent, \
&(D_LEVEL[__D_SUBMODULE_ ## name].level)); \
- rc = PTR_ERR(fd); \
- if (IS_ERR(fd) && rc != -ENODEV) \
- printk(KERN_ERR "%s: Can't create debugfs entry %s: " \
- "%d\n", __func__, prefix #name, rc); \
- else \
- rc = 0; \
- rc; \
})
diff --git a/net/wimax/debugfs.c b/net/wimax/debugfs.c
index 1af56df30276..3c54bb6b925a 100644
--- a/net/wimax/debugfs.c
+++ b/net/wimax/debugfs.c
@@ -13,49 +13,23 @@
#define D_SUBMODULE debugfs
#include "debug-levels.h"
-
-#define __debugfs_register(prefix, name, parent) \
-do { \
- result = d_level_register_debugfs(prefix, name, parent); \
- if (result < 0) \
- goto error; \
-} while (0)
-
-
-int wimax_debugfs_add(struct wimax_dev *wimax_dev)
+void wimax_debugfs_add(struct wimax_dev *wimax_dev)
{
- int result;
struct net_device *net_dev = wimax_dev->net_dev;
- struct device *dev = net_dev->dev.parent;
struct dentry *dentry;
char buf[128];
snprintf(buf, sizeof(buf), "wimax:%s", net_dev->name);
dentry = debugfs_create_dir(buf, NULL);
- result = PTR_ERR(dentry);
- if (IS_ERR(dentry)) {
- if (result == -ENODEV)
- result = 0; /* No debugfs support */
- else
- dev_err(dev, "Can't create debugfs dentry: %d\n",
- result);
- goto out;
- }
wimax_dev->debugfs_dentry = dentry;
- __debugfs_register("wimax_dl_", debugfs, dentry);
- __debugfs_register("wimax_dl_", id_table, dentry);
- __debugfs_register("wimax_dl_", op_msg, dentry);
- __debugfs_register("wimax_dl_", op_reset, dentry);
- __debugfs_register("wimax_dl_", op_rfkill, dentry);
- __debugfs_register("wimax_dl_", op_state_get, dentry);
- __debugfs_register("wimax_dl_", stack, dentry);
- result = 0;
-out:
- return result;
-error:
- debugfs_remove_recursive(wimax_dev->debugfs_dentry);
- return result;
+ d_level_register_debugfs("wimax_dl_", debugfs, dentry);
+ d_level_register_debugfs("wimax_dl_", id_table, dentry);
+ d_level_register_debugfs("wimax_dl_", op_msg, dentry);
+ d_level_register_debugfs("wimax_dl_", op_reset, dentry);
+ d_level_register_debugfs("wimax_dl_", op_rfkill, dentry);
+ d_level_register_debugfs("wimax_dl_", op_state_get, dentry);
+ d_level_register_debugfs("wimax_dl_", stack, dentry);
}
void wimax_debugfs_rm(struct wimax_dev *wimax_dev)
diff --git a/net/wimax/stack.c b/net/wimax/stack.c
index 1ba99d65feca..4b9b1c5e8f3a 100644
--- a/net/wimax/stack.c
+++ b/net/wimax/stack.c
@@ -481,12 +481,7 @@ int wimax_dev_add(struct wimax_dev *wimax_dev, struct net_device *net_dev)
/* Set up user-space interaction */
mutex_lock(&wimax_dev->mutex);
wimax_id_table_add(wimax_dev);
- result = wimax_debugfs_add(wimax_dev);
- if (result < 0) {
- dev_err(dev, "cannot initialize debugfs: %d\n",
- result);
- goto error_debugfs_add;
- }
+ wimax_debugfs_add(wimax_dev);
__wimax_state_set(wimax_dev, WIMAX_ST_DOWN);
mutex_unlock(&wimax_dev->mutex);
@@ -498,10 +493,6 @@ int wimax_dev_add(struct wimax_dev *wimax_dev, struct net_device *net_dev)
d_fnend(3, dev, "(wimax_dev %p net_dev %p) = 0\n", wimax_dev, net_dev);
return 0;
-error_debugfs_add:
- wimax_id_table_rm(wimax_dev);
- mutex_unlock(&wimax_dev->mutex);
- wimax_rfkill_rm(wimax_dev);
error_rfkill_add:
d_fnend(3, dev, "(wimax_dev %p net_dev %p) = %d\n",
wimax_dev, net_dev, result);
diff --git a/net/wimax/wimax-internal.h b/net/wimax/wimax-internal.h
index e819a09337ee..40751207296c 100644
--- a/net/wimax/wimax-internal.h
+++ b/net/wimax/wimax-internal.h
@@ -57,13 +57,10 @@ void __wimax_state_set(struct wimax_dev *wimax_dev, enum wimax_st state)
void __wimax_state_change(struct wimax_dev *, enum wimax_st);
#ifdef CONFIG_DEBUG_FS
-int wimax_debugfs_add(struct wimax_dev *);
+void wimax_debugfs_add(struct wimax_dev *);
void wimax_debugfs_rm(struct wimax_dev *);
#else
-static inline int wimax_debugfs_add(struct wimax_dev *wimax_dev)
-{
- return 0;
-}
+static inline void wimax_debugfs_add(struct wimax_dev *wimax_dev) {}
static inline void wimax_debugfs_rm(struct wimax_dev *wimax_dev) {}
#endif
--
2.22.0
^ permalink raw reply related
* [PATCH v2 00/17] Networking driver debugfs cleanups
From: Greg Kroah-Hartman @ 2019-08-09 12:30 UTC (permalink / raw)
To: netdev; +Cc: Greg Kroah-Hartman
There is no need to test the result of any debugfs call anymore. The
debugfs core warns the user if something fails, and the return value of
a debugfs call can always be fed back into another debugfs call with no
problems.
Also, debugfs is for debugging, so if there are problems with debugfs
(i.e. the system is out of memory) the rest of the kernel should not
change behavior, so testing for debugfs calls is pointless and not the
goal of debugfs at all.
This series cleans up a lot of networking drivers and some wimax code
that was calling debugfs and trying to do something with the return
value that it didn't need to. Removing this logic makes the code
smaller, easier to understand, and use less run-time memory in some
cases, all good things.
The series is against net-next, and have no dependancies between any of
them if they want to go through any random tree/order. Or, if wanted,
I can take them through my driver-core tree where other debugfs cleanups
are being slowly fed during major merge windows.
thanks,
greg k-h
v2: fix up build warnings, it's as if I never even built these. Ugh, so
sorry for wasting people's time with the v1 series. I need to stop
relying on 0-day as it isn't working well anymore :(
Greg Kroah-Hartman (17):
wimax: no need to check return value of debugfs_create functions
bonding: no need to print a message if debugfs_create_dir() fails
mlx5: no need to check return value of debugfs_create functions
xgbe: no need to check return value of debugfs_create functions
bnxt: no need to check return value of debugfs_create functions
cxgb4: no need to check return value of debugfs_create functions
hns3: no need to check return value of debugfs_create functions
nfp: no need to check return value of debugfs_create functions
stmmac: no need to check return value of debugfs_create functions
dpaa2: no need to check return value of debugfs_create functions
qca: no need to check return value of debugfs_create functions
skge: no need to check return value of debugfs_create functions
mvpp2: no need to check return value of debugfs_create functions
fm10k: no need to check return value of debugfs_create functions
i40e: no need to check return value of debugfs_create functions
ixgbe: no need to check return value of debugfs_create functions
ieee802154: no need to check return value of debugfs_create functions
drivers/net/bonding/bond_debugfs.c | 5 -
drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c | 107 ++++---------
drivers/net/ethernet/broadcom/bnxt/bnxt.h | 1 -
.../net/ethernet/broadcom/bnxt/bnxt_debugfs.c | 39 ++---
.../ethernet/chelsio/cxgb4/cxgb4_debugfs.c | 5 +-
.../net/ethernet/chelsio/cxgb4/cxgb4_main.c | 3 -
.../ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | 21 +--
.../freescale/dpaa2/dpaa2-eth-debugfs.c | 54 +------
.../freescale/dpaa2/dpaa2-eth-debugfs.h | 3 -
.../ethernet/hisilicon/hns3/hns3_debugfs.c | 17 +-
.../net/ethernet/intel/fm10k/fm10k_debugfs.c | 2 -
.../net/ethernet/intel/i40e/i40e_debugfs.c | 22 +--
.../net/ethernet/intel/ixgbe/ixgbe_debugfs.c | 22 +--
.../ethernet/marvell/mvpp2/mvpp2_debugfs.c | 19 +--
drivers/net/ethernet/marvell/skge.c | 39 ++---
drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 51 +-----
.../net/ethernet/mellanox/mlx5/core/debugfs.c | 102 ++----------
drivers/net/ethernet/mellanox/mlx5/core/eq.c | 11 +-
.../net/ethernet/mellanox/mlx5/core/lib/eq.h | 2 +-
.../net/ethernet/mellanox/mlx5/core/main.c | 7 +-
.../ethernet/mellanox/mlx5/core/mlx5_core.h | 2 +-
.../ethernet/netronome/nfp/nfp_net_debugfs.c | 17 +-
drivers/net/ethernet/qualcomm/qca_debug.c | 13 +-
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 2 -
.../net/ethernet/stmicro/stmmac/stmmac_main.c | 52 +-----
drivers/net/ieee802154/adf7242.c | 13 +-
drivers/net/ieee802154/at86rf230.c | 20 +--
drivers/net/ieee802154/ca8210.c | 9 +-
drivers/net/wimax/i2400m/debugfs.c | 149 +++---------------
drivers/net/wimax/i2400m/driver.c | 7 +-
drivers/net/wimax/i2400m/i2400m.h | 7 +-
drivers/net/wimax/i2400m/usb.c | 64 ++------
include/linux/mlx5/driver.h | 12 +-
include/linux/wimax/debug.h | 20 +--
net/wimax/debugfs.c | 42 +----
net/wimax/stack.c | 11 +-
net/wimax/wimax-internal.h | 7 +-
37 files changed, 175 insertions(+), 804 deletions(-)
--
2.22.0
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox