kernel: add support for kernel 5.4

The following patches were removed because they are integrated in the upstream kernel 5.4:
 * backport-5.4/047-v4.21-mtd-keep-original-flags-for-every-struct-mtd_info.patch
 * backport-5.4/048-v4.21-mtd-improve-calculating-partition-boundaries-when-ch.patch
 * backport-5.4/080-v5.1-0001-bcma-keep-a-direct-pointer-to-the-struct-device.patch
 * backport-5.4/080-v5.1-0002-bcma-use-dev_-printing-functions.patch
 * backport-5.4/095-Allow-class-e-address-assignment-via-ifconfig-ioctl.patch
 * backport-5.4/101-arm-cns3xxx-use-actual-size-reads-for-PCIe.patch
 * backport-5.4/200-v5.2-usb-dwc2-Set-lpm-mode-parameters-depend-on-HW-configuration.patch
 * backport-5.4/210-arm64-sve-Disentangle-uapi-asm-ptrace.h-from-uapi-as.patch
 * backport-5.4/380-v5.3-net-sched-Introduce-act_ctinfo-action.patch
 * backport-5.4/450-v5.0-mtd-spinand-winbond-Add-support-for-W25N01GV.patch
 * backport-5.4/451-v5.0-mtd-spinand-Add-initial-support-for-Toshiba-TC58CVG2.patch
 * backport-5.4/452-v5.0-mtd-spinand-add-support-for-GigaDevice-GD5FxGQ4xA.patch
 * backport-5.4/455-v5.1-mtd-spinand-Add-support-for-all-Toshiba-Memory-produ.patch
 * backport-5.4/456-v5.1-mtd-spinand-Add-support-for-GigaDevice-GD5F1GQ4UExxG.patch
 * backport-5.4/460-v5.0-mtd-spi-nor-Add-support-for-mx25u12835f.patch
 * backport-5.4/460-v5.3-mtd-spinand-Define-macros-for-page-read-ops-with-thr.patch
 * backport-5.4/461-v5.3-mtd-spinand-Add-support-for-two-byte-device-IDs.patch
 * backport-5.4/462-v5.3-mtd-spinand-Add-support-for-GigaDevice-GD5F1GQ4UFxxG.patch
 * backport-5.4/463-v5.3-mtd-spinand-Add-initial-support-for-Paragon-PN26G0xA.patch
 * backport-5.4/700-v5.1-net-phylink-only-call-mac_config-during-resolve-when.patch
 * backport-5.4/701-v5.2-net-phylink-ensure-inband-AN-works-correctly.patch
 * backport-5.4/702-v4.20-net-ethernet-Add-helper-for-MACs-which-support-asym-.patch
 * backport-5.4/703-v4.20-net-ethernet-Add-helper-for-set_pauseparam-for-Asym-.patch
 * backport-5.4/704-v4.20-net-phy-Stop-with-excessive-soft-reset.patch
 * backport-5.4/705-v5.1-net-phy-provide-full-set-of-accessor-functions-to-MM.patch
 * backport-5.4/706-v5.1-net-phy-add-register-modifying-helpers-returning-1-o.patch
 * backport-5.4/707-v5.1-net-phy-add-genphy_c45_check_and_restart_aneg.patch
 * backport-5.4/708-v5.3-net-phylink-remove-netdev-from-phylink-mii-ioctl-emu.patch
 * backport-5.4/709-v5.3-net-phylink-support-for-link-gpio-interrupt.patch
 * backport-5.4/710-v5.3-net-phy-allow-Clause-45-access-via-mii-ioctl.patch
 * backport-5.4/711-v5.3-net-sfp-add-mandatory-attach-detach-methods-for-sfp-.patch
 * backport-5.4/712-v5.3-net-sfp-remove-sfp-bus-use-of-netdevs.patch
 * backport-5.4/713-v5.2-net-phylink-avoid-reducing-support-mask.patch
 * backport-5.4/714-v5.3-net-sfp-Stop-SFP-polling-and-interrupt-handling-duri.patch
 * backport-5.4/715-v5.3-net-phylink-don-t-start-and-stop-SGMII-PHYs-in-SFP-m.patch
 * backport-5.4/740-v5.5-net-phy-avoid-matching-all-ones-clause-45-PHY-IDs.patch
 * backport-5.4/741-v5.5-net-phylink-fix-link-mode-modification-in-PHY-mode.patch
 * pending-5.4/103-MIPS-perf-ath79-Fix-perfcount-IRQ-assignment.patch
 * pending-5.4/131-spi-use-gpio_set_value_cansleep-for-setting-chipsele.patch
 * pending-5.4/132-spi-spi-gpio-fix-crash-when-num-chipselects-is-0.patch
 * pending-5.4/220-optimize_inlining.patch
 * pending-5.4/341-MIPS-mm-remove-no-op-dma_map_ops-where-possible.patch
 * pending-5.4/475-mtd-spi-nor-Add-Winbond-w25q128jv-support.patch
 * pending-5.4/477-mtd-add-spi-nor-add-mx25u3235f.patch
 * pending-5.4/479-mtd-spi-nor-add-eon-en25qh64.patch

Some bigger changes were done to this feature and we did not port this patch yet:
 * hack-5.4/207-disable-modorder.patch

This depends on BOOTMEM which was removed from the kernel, this needs some bigger changes:
 * hack-5.4/930-crashlog.patch

A different version of the FPU disable patch was merged upstream, OpenWrt needs some adaptations.
 * pending-5.4/304-mips_disable_fpu.patch

- no crashlog support yet as a required file got deleted upstream
- Removed patch below, which is now seen as a recursive dependency [1]
- Removed patch below due to build error [2]
- fix still required to avoid identical function def [3]
- Fixes included from Blocktrron
- Fixes included from Chunkeey
- Fix included from nbd regarding "dst leak in Flow Offload"

[1] target/linux/generic/hack-5.4/260-crypto_test_dependencies.patch
[2] target/linux/generic/hack-5.4/207-disable-modorder.patch
[3] target/linux/generic/pending-5.4/613-netfilter_optional_tcp_window_check.patch

Signed-off-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
Signed-off-by: David Bauer <mail@david-bauer.net>
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
Signed-off-by: Robert Marko <robimarko@gmail.com>
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
This commit is contained in:
Koen Vandeputte 2019-11-25 16:08:31 +01:00
parent c16517d26d
commit 4e0c54bc5b
216 changed files with 1537 additions and 6794 deletions

View File

@ -8,9 +8,11 @@ endif
LINUX_VERSION-4.14 = .171
LINUX_VERSION-4.19 = .106
LINUX_VERSION-5.4 = .22
LINUX_KERNEL_HASH-4.14.171 = 4fe02489e4b4a187eccf0ef87df6100534c9d485e76d876b1fa247c7635332a0
LINUX_KERNEL_HASH-4.19.106 = 63c8bd76a9b282e18112f8ff9e3fd41e3d1df9f9b7248ea1a370b05a827e9cda
LINUX_KERNEL_HASH-5.4.22 = 661bcb8d7e390dcc28e53795485e648f2bdc9b697b731459cc2bcc9ceb4a7d1a
remove_uri_prefix=$(subst git://,,$(subst http://,,$(subst https://,,$(1))))
sanitize_uri=$(call qstrip,$(subst @,_,$(subst :,_,$(subst .,_,$(subst -,_,$(subst /,_,$(1)))))))

View File

@ -10,14 +10,15 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/Makefile
+++ b/Makefile
@@ -432,8 +432,8 @@ KBUILD_LDFLAGS :=
@@ -471,8 +471,9 @@ KBUILD_LDFLAGS :=
GCC_PLUGINS_CFLAGS :=
CLANG_FLAGS :=
-export ARCH SRCARCH CONFIG_SHELL HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE AS LD CC
-export CPP AR NM STRIP OBJCOPY OBJDUMP KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS
+export ARCH SRCARCH SUBARCH CONFIG_SHELL HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE AS LD
+export CC CPP AR NM STRIP OBJCOPY OBJDUMP KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS
export MAKE LEX YACC AWK GENKSYMS INSTALLKERNEL PERL PYTHON PYTHON2 PYTHON3 UTS_MACHINE
export HOSTCXX KBUILD_HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
-export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE AS LD CC
-export CPP AR NM STRIP OBJCOPY OBJDUMP OBJSIZE PAHOLE LEX YACC AWK INSTALLKERNEL
+export ARCH SRCARCH SUBARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE AS LD
+export CC CPP AR NM STRIP OBJCOPY OBJDUMP OBJSIZE PAHOLE LEX YACC AWK INSTALLKERNEL
+
export PERL PYTHON PYTHON2 PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX
export KBUILD_HOSTCXXFLAGS KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS LDFLAGS_MODULE

View File

@ -94,7 +94,7 @@ Signed-off-by: Florian Westphal <fw@strlen.de>
+}
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -135,6 +135,18 @@ config NF_CONNTRACK_EVENTS
@@ -136,6 +136,18 @@ config NF_CONNTRACK_EVENTS
If unsure, say `N'.
@ -115,16 +115,16 @@ Signed-off-by: Florian Westphal <fw@strlen.de>
depends on NETFILTER_ADVANCED
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -25,6 +25,9 @@ obj-$(CONFIG_NETFILTER_NETLINK_OSF) += n
@@ -26,6 +26,9 @@ obj-$(CONFIG_NETFILTER_NETLINK_OSF) += n
# connection tracking
obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o
+# optional conntrack route cache extension
+obj-$(CONFIG_NF_CONNTRACK_RTCACHE) += nf_conntrack_rtcache.o
+
obj-$(CONFIG_NF_CT_PROTO_GRE) += nf_conntrack_proto_gre.o
# netlink interface for nf_conntrack
obj-$(CONFIG_NF_CT_NETLINK) += nf_conntrack_netlink.o
obj-$(CONFIG_NF_CT_NETLINK_TIMEOUT) += nfnetlink_cttimeout.o
--- /dev/null
+++ b/net/netfilter/nf_conntrack_rtcache.c
@@ -0,0 +1,428 @@

View File

@ -1,58 +0,0 @@
From 1186af457cc186c5ed01708da71b1ffbdf0a2638 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Tue, 20 Nov 2018 09:55:45 +0100
Subject: [PATCH] mtd: keep original flags for every struct mtd_info
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When allocating a new partition mtd subsystem runs internal tests in the
allocate_partition(). They may result in modifying specified flags (e.g.
dropping some /features/ like write access).
Those constraints don't have to be necessary true for subpartitions. It
may happen parent partition isn't block aligned (effectively disabling
write access) while subpartition may fit blocks nicely. In such case all
checks should be run again (starting with original flags value).
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
---
drivers/mtd/mtdcore.c | 2 ++
drivers/mtd/mtdpart.c | 3 ++-
include/linux/mtd/mtd.h | 1 +
3 files changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -665,6 +665,8 @@ static void mtd_set_dev_defaults(struct
} else {
pr_debug("mtd device won't show a device symlink in sysfs\n");
}
+
+ mtd->orig_flags = mtd->flags;
}
/**
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -346,7 +346,8 @@ static struct mtd_part *allocate_partiti
/* set up the MTD object for this partition */
slave->mtd.type = parent->type;
- slave->mtd.flags = parent->flags & ~part->mask_flags;
+ slave->mtd.flags = parent->orig_flags & ~part->mask_flags;
+ slave->mtd.orig_flags = slave->mtd.flags;
slave->mtd.size = part->size;
slave->mtd.writesize = parent->writesize;
slave->mtd.writebufsize = parent->writebufsize;
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -207,6 +207,7 @@ struct mtd_debug_info {
struct mtd_info {
u_char type;
uint32_t flags;
+ uint32_t orig_flags; /* Flags as before running mtd checks */
uint64_t size; // Total size of the MTD
/* "Major" erase size for the device. Naïve users may take this

View File

@ -1,55 +0,0 @@
From 6750f61a13a0197c40e4a40739117493b15f19e8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Tue, 20 Nov 2018 10:24:09 +0100
Subject: [PATCH] mtd: improve calculating partition boundaries when checking
for alignment
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When checking for alignment mtd should check absolute offsets. It's
important for subpartitions as it doesn't make sense to check their
relative addresses.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
---
drivers/mtd/mtdpart.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -61,6 +61,15 @@ static inline struct mtd_part *mtd_to_pa
return container_of(mtd, struct mtd_part, mtd);
}
+static u64 part_absolute_offset(struct mtd_info *mtd)
+{
+ struct mtd_part *part = mtd_to_part(mtd);
+
+ if (!mtd_is_partition(mtd))
+ return 0;
+
+ return part_absolute_offset(part->parent) + part->offset;
+}
/*
* MTD methods which simply translate the effective address and pass through
@@ -518,7 +527,7 @@ static struct mtd_part *allocate_partiti
if (!(slave->mtd.flags & MTD_NO_ERASE))
wr_alignment = slave->mtd.erasesize;
- tmp = slave->offset;
+ tmp = part_absolute_offset(parent) + slave->offset;
remainder = do_div(tmp, wr_alignment);
if ((slave->mtd.flags & MTD_WRITEABLE) && remainder) {
/* Doesn't start on a boundary of major erase size */
@@ -529,7 +538,7 @@ static struct mtd_part *allocate_partiti
part->name);
}
- tmp = slave->mtd.size;
+ tmp = part_absolute_offset(parent) + slave->mtd.size;
remainder = do_div(tmp, wr_alignment);
if ((slave->mtd.flags & MTD_WRITEABLE) && remainder) {
slave->mtd.flags &= ~MTD_WRITEABLE;

View File

@ -1,199 +0,0 @@
From 5a1c18b761ddb299a06746948b9ec2814b04fa92 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Wed, 2 Jan 2019 00:00:01 +0100
Subject: [PATCH] bcma: keep a direct pointer to the struct device
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Accessing struct device is pretty useful/common so having a direct
pointer:
1) Simplifies some code
2) Makes bcma_bus_get_host_dev() unneeded
3) Allows further improvements like using dev_* printing helpers
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
drivers/bcma/bcma_private.h | 1 -
drivers/bcma/driver_gpio.c | 2 +-
drivers/bcma/host_pci.c | 2 ++
drivers/bcma/host_soc.c | 4 ++--
drivers/bcma/main.c | 45 +++++++++----------------------------
include/linux/bcma/bcma.h | 11 +++------
6 files changed, 18 insertions(+), 47 deletions(-)
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
@@ -33,7 +33,6 @@ int __init bcma_bus_early_register(struc
int bcma_bus_suspend(struct bcma_bus *bus);
int bcma_bus_resume(struct bcma_bus *bus);
#endif
-struct device *bcma_bus_get_host_dev(struct bcma_bus *bus);
/* scan.c */
void bcma_detect_chip(struct bcma_bus *bus);
--- a/drivers/bcma/driver_gpio.c
+++ b/drivers/bcma/driver_gpio.c
@@ -183,7 +183,7 @@ int bcma_gpio_init(struct bcma_drv_cc *c
chip->direction_input = bcma_gpio_direction_input;
chip->direction_output = bcma_gpio_direction_output;
chip->owner = THIS_MODULE;
- chip->parent = bcma_bus_get_host_dev(bus);
+ chip->parent = bus->dev;
#if IS_BUILTIN(CONFIG_OF)
chip->of_node = cc->core->dev.of_node;
#endif
--- a/drivers/bcma/host_pci.c
+++ b/drivers/bcma/host_pci.c
@@ -196,6 +196,8 @@ static int bcma_host_pci_probe(struct pc
goto err_pci_release_regions;
}
+ bus->dev = &dev->dev;
+
/* Map MMIO */
err = -ENOMEM;
bus->mmio = pci_iomap(dev, 0, ~0UL);
--- a/drivers/bcma/host_soc.c
+++ b/drivers/bcma/host_soc.c
@@ -179,7 +179,6 @@ int __init bcma_host_soc_register(struct
/* Host specific */
bus->hosttype = BCMA_HOSTTYPE_SOC;
bus->ops = &bcma_host_soc_ops;
- bus->host_pdev = NULL;
/* Initialize struct, detect chip */
bcma_init_bus(bus);
@@ -213,6 +212,8 @@ static int bcma_host_soc_probe(struct pl
if (!bus)
return -ENOMEM;
+ bus->dev = dev;
+
/* Map MMIO */
bus->mmio = of_iomap(np, 0);
if (!bus->mmio)
@@ -221,7 +222,6 @@ static int bcma_host_soc_probe(struct pl
/* Host specific */
bus->hosttype = BCMA_HOSTTYPE_SOC;
bus->ops = &bcma_host_soc_ops;
- bus->host_pdev = pdev;
/* Initialize struct, detect chip */
bcma_init_bus(bus);
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -223,8 +223,8 @@ unsigned int bcma_core_irq(struct bcma_d
mips_irq = bcma_core_mips_irq(core);
return mips_irq <= 4 ? mips_irq + 2 : 0;
}
- if (bus->host_pdev)
- return bcma_of_get_irq(&bus->host_pdev->dev, core, num);
+ if (bus->dev)
+ return bcma_of_get_irq(bus->dev, core, num);
return 0;
case BCMA_HOSTTYPE_SDIO:
return 0;
@@ -239,18 +239,18 @@ void bcma_prepare_core(struct bcma_bus *
core->dev.release = bcma_release_core_dev;
core->dev.bus = &bcma_bus_type;
dev_set_name(&core->dev, "bcma%d:%d", bus->num, core->core_index);
- core->dev.parent = bcma_bus_get_host_dev(bus);
- if (core->dev.parent)
- bcma_of_fill_device(core->dev.parent, core);
+ core->dev.parent = bus->dev;
+ if (bus->dev)
+ bcma_of_fill_device(bus->dev, core);
switch (bus->hosttype) {
case BCMA_HOSTTYPE_PCI:
- core->dma_dev = &bus->host_pci->dev;
+ core->dma_dev = bus->dev;
core->irq = bus->host_pci->irq;
break;
case BCMA_HOSTTYPE_SOC:
- if (IS_ENABLED(CONFIG_OF) && bus->host_pdev) {
- core->dma_dev = &bus->host_pdev->dev;
+ if (IS_ENABLED(CONFIG_OF) && bus->dev) {
+ core->dma_dev = bus->dev;
} else {
core->dev.dma_mask = &core->dev.coherent_dma_mask;
core->dma_dev = &core->dev;
@@ -261,28 +261,6 @@ void bcma_prepare_core(struct bcma_bus *
}
}
-struct device *bcma_bus_get_host_dev(struct bcma_bus *bus)
-{
- switch (bus->hosttype) {
- case BCMA_HOSTTYPE_PCI:
- if (bus->host_pci)
- return &bus->host_pci->dev;
- else
- return NULL;
- case BCMA_HOSTTYPE_SOC:
- if (bus->host_pdev)
- return &bus->host_pdev->dev;
- else
- return NULL;
- case BCMA_HOSTTYPE_SDIO:
- if (bus->host_sdio)
- return &bus->host_sdio->dev;
- else
- return NULL;
- }
- return NULL;
-}
-
void bcma_init_bus(struct bcma_bus *bus)
{
mutex_lock(&bcma_buses_mutex);
@@ -402,7 +380,6 @@ int bcma_bus_register(struct bcma_bus *b
{
int err;
struct bcma_device *core;
- struct device *dev;
/* Scan for devices (cores) */
err = bcma_bus_scan(bus);
@@ -425,10 +402,8 @@ int bcma_bus_register(struct bcma_bus *b
bcma_core_pci_early_init(&bus->drv_pci[0]);
}
- dev = bcma_bus_get_host_dev(bus);
- if (dev) {
- of_platform_default_populate(dev->of_node, NULL, dev);
- }
+ if (bus->dev)
+ of_platform_default_populate(bus->dev->of_node, NULL, bus->dev);
/* Cores providing flash access go before SPROM init */
list_for_each_entry(core, &bus->cores, list) {
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -332,6 +332,8 @@ extern int bcma_arch_register_fallback_s
struct ssb_sprom *out));
struct bcma_bus {
+ struct device *dev;
+
/* The MMIO area. */
void __iomem *mmio;
@@ -339,14 +341,7 @@ struct bcma_bus {
enum bcma_hosttype hosttype;
bool host_is_pcie2; /* Used for BCMA_HOSTTYPE_PCI only */
- union {
- /* Pointer to the PCI bus (only for BCMA_HOSTTYPE_PCI) */
- struct pci_dev *host_pci;
- /* Pointer to the SDIO device (only for BCMA_HOSTTYPE_SDIO) */
- struct sdio_func *host_sdio;
- /* Pointer to platform device (only for BCMA_HOSTTYPE_SOC) */
- struct platform_device *host_pdev;
- };
+ struct pci_dev *host_pci; /* PCI bus pointer (BCMA_HOSTTYPE_PCI only) */
struct bcma_chipinfo chipinfo;

View File

@ -1,36 +0,0 @@
From 777bc4801a6868fcbff09ffb6e30f023e7c5ed38 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Wed, 2 Jan 2019 00:00:02 +0100
Subject: [PATCH] bcma: use dev_* printing functions
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
It provides more meaningful messages.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
drivers/bcma/bcma_private.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
@@ -10,13 +10,13 @@
#include <linux/delay.h>
#define bcma_err(bus, fmt, ...) \
- pr_err("bus%d: " fmt, (bus)->num, ##__VA_ARGS__)
+ dev_err((bus)->dev, "bus%d: " fmt, (bus)->num, ##__VA_ARGS__)
#define bcma_warn(bus, fmt, ...) \
- pr_warn("bus%d: " fmt, (bus)->num, ##__VA_ARGS__)
+ dev_warn((bus)->dev, "bus%d: " fmt, (bus)->num, ##__VA_ARGS__)
#define bcma_info(bus, fmt, ...) \
- pr_info("bus%d: " fmt, (bus)->num, ##__VA_ARGS__)
+ dev_info((bus)->dev, "bus%d: " fmt, (bus)->num, ##__VA_ARGS__)
#define bcma_debug(bus, fmt, ...) \
- pr_debug("bus%d: " fmt, (bus)->num, ##__VA_ARGS__)
+ dev_dbg((bus)->dev, "bus%d: " fmt, (bus)->num, ##__VA_ARGS__)
struct bcma_bus;

View File

@ -1,79 +0,0 @@
From 46bf067870156abd61fe24d14c2486d15b8b502c Mon Sep 17 00:00:00 2001
From: Dave Taht <dave@taht.net>
Date: Fri, 14 Dec 2018 18:38:40 +0000
Subject: [PATCH 1/1] Allow class-e address assignment in ifconfig and early
boot
While the linux kernel became mostly "class-e clean" a decade ago,
and most distributions long ago switched to the iproute2 suite
of utilities, which allow class-e (240.0.0.0/4) address assignment,
distributions relying on busybox, toybox and other forms of
ifconfig cannot assign class-e addresses without this kernel patch.
With this patch, also, a boot command line on these addresses is feasible:
(ip=248.0.1.2::248.0.1.1:255.255.255.0).
While CIDR has been obsolete for 2 decades, and a survey of all the
userspace open source code in the world shows most IN_whatever macros
are also obsolete... rather than obsolete CIDR from this ioctl entirely,
this patch merely enables class-e assignment, sanely.
H/T to Vince Fuller and his original patch here:
https://lkml.org/lkml/2008/1/7/370
Signed-off-by: Dave Taht <dave.taht@gmail.com>
Reviewed-by: John Gilmore <gnu@toad.com>
---
include/uapi/linux/in.h | 8 ++++++--
net/ipv4/devinet.c | 4 +++-
net/ipv4/ipconfig.c | 2 ++
3 files changed, 11 insertions(+), 3 deletions(-)
--- a/include/uapi/linux/in.h
+++ b/include/uapi/linux/in.h
@@ -268,8 +268,12 @@ struct sockaddr_in {
#define IN_MULTICAST(a) IN_CLASSD(a)
#define IN_MULTICAST_NET 0xF0000000
-#define IN_EXPERIMENTAL(a) ((((long int) (a)) & 0xf0000000) == 0xf0000000)
-#define IN_BADCLASS(a) IN_EXPERIMENTAL((a))
+#define IN_BADCLASS(a) (((long int) (a) ) == (long int)0xffffffff)
+#define IN_EXPERIMENTAL(a) IN_BADCLASS((a))
+
+#define IN_CLASSE(a) ((((long int) (a)) & 0xf0000000) == 0xf0000000)
+#define IN_CLASSE_NET 0xffffffff
+#define IN_CLASSE_NSHIFT 0
/* Address to accept any incoming messages. */
#define INADDR_ANY ((unsigned long int) 0x00000000)
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -949,7 +949,7 @@ static int inet_abc_len(__be32 addr)
{
int rc = -1; /* Something else, probably a multicast. */
- if (ipv4_is_zeronet(addr))
+ if (ipv4_is_zeronet(addr) || ipv4_is_lbcast(addr))
rc = 0;
else {
__u32 haddr = ntohl(addr);
@@ -960,6 +960,8 @@ static int inet_abc_len(__be32 addr)
rc = 16;
else if (IN_CLASSC(haddr))
rc = 24;
+ else if (IN_CLASSE(haddr))
+ rc = 32;
}
return rc;
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -429,6 +429,8 @@ static int __init ic_defaults(void)
ic_netmask = htonl(IN_CLASSB_NET);
else if (IN_CLASSC(ntohl(ic_myaddr)))
ic_netmask = htonl(IN_CLASSC_NET);
+ else if (IN_CLASSE(ntohl(ic_myaddr)))
+ ic_netmask = htonl(IN_CLASSE_NET);
else {
pr_err("IP-Config: Unable to guess netmask for address %pI4\n",
&ic_myaddr);

View File

@ -1,46 +0,0 @@
From 4cc30de79d293f1e8c5f50ae3a9c005def9564a0 Mon Sep 17 00:00:00 2001
From: Koen Vandeputte <koen.vandeputte@ncentric.com>
Date: Mon, 7 Jan 2019 14:14:27 +0100
Subject: [PATCH 2/2] arm: cns3xxx: use actual size reads for PCIe
commit 802b7c06adc7 ("ARM: cns3xxx: Convert PCI to use generic config accessors")
reimplemented cns3xxx_pci_read_config() using pci_generic_config_read32(),
which preserved the property of only doing 32-bit reads.
It also replaced cns3xxx_pci_write_config() with pci_generic_config_write(),
so it changed writes from always being 32 bits to being the actual size,
which works just fine.
Due to:
- The documentation does not mention that only 32 bit access is allowed.
- Writes are already executed using the actual size
- Extensive testing shows that 8b, 16b and 32b reads work as intended
It makes perfectly sense to also swap 32 bit reading in favor of actual size.
Fixes: 802b7c06adc7 ("ARM: cns3xxx: Convert PCI to use generic config accessors")
Suggested-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
CC: Arnd Bergmann <arnd@arndb.de>
CC: Krzysztof Halasa <khalasa@piap.pl>
CC: Olof Johansson <olof@lixom.net>
CC: Robin Leblon <robin.leblon@ncentric.com>
CC: Rob Herring <robh@kernel.org>
CC: Russell King <linux@armlinux.org.uk>
CC: Tim Harvey <tharvey@gateworks.com>
CC: stable@vger.kernel.org # v4.0+
---
arch/arm/mach-cns3xxx/pcie.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/arm/mach-cns3xxx/pcie.c
+++ b/arch/arm/mach-cns3xxx/pcie.c
@@ -93,7 +93,7 @@ static int cns3xxx_pci_read_config(struc
u32 mask = (0x1ull << (size * 8)) - 1;
int shift = (where % 4) * 8;
- ret = pci_generic_config_read32(bus, devfn, where, size, val);
+ ret = pci_generic_config_read(bus, devfn, where, size, val);
if (ret == PCIBIOS_SUCCESSFUL && !bus->number && !devfn &&
(where & 0xffc) == PCI_CLASS_REVISION)

View File

@ -1,63 +0,0 @@
From 28b5c129ca6e585ec95c160ec4297bc6c6360b6f Mon Sep 17 00:00:00 2001
From: Minas Harutyunyan <minas.harutyunyan@synopsys.com>
Date: Mon, 4 Mar 2019 17:08:07 +0400
Subject: usb: dwc2: Set lpm mode parameters depend on HW configuration
If core not supported lpm, i.e. BCM2835 then confusing warnings seen
in log.
To avoid these warnings, added function dwc2_set_param_lpm() to set
lpm and other lpm related parameters based on lpm support by core.
Signed-off-by: Minas Harutyunyan <hminas@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
---
drivers/usb/dwc2/params.c | 23 ++++++++++++++++++-----
1 file changed, 18 insertions(+), 5 deletions(-)
--- a/drivers/usb/dwc2/params.c
+++ b/drivers/usb/dwc2/params.c
@@ -273,6 +273,23 @@ static void dwc2_set_param_power_down(st
hsotg->params.power_down = val;
}
+static void dwc2_set_param_lpm(struct dwc2_hsotg *hsotg)
+{
+ struct dwc2_core_params *p = &hsotg->params;
+
+ p->lpm = hsotg->hw_params.lpm_mode;
+ if (p->lpm) {
+ p->lpm_clock_gating = true;
+ p->besl = true;
+ p->hird_threshold_en = true;
+ p->hird_threshold = 4;
+ } else {
+ p->lpm_clock_gating = false;
+ p->besl = false;
+ p->hird_threshold_en = false;
+ }
+}
+
/**
* dwc2_set_default_params() - Set all core parameters to their
* auto-detected default values.
@@ -291,6 +308,7 @@ static void dwc2_set_default_params(stru
dwc2_set_param_speed(hsotg);
dwc2_set_param_phy_utmi_width(hsotg);
dwc2_set_param_power_down(hsotg);
+ dwc2_set_param_lpm(hsotg);
p->phy_ulpi_ddr = false;
p->phy_ulpi_ext_vbus = false;
@@ -303,11 +321,6 @@ static void dwc2_set_default_params(stru
p->reload_ctl = (hw->snpsid >= DWC2_CORE_REV_2_92a);
p->uframe_sched = true;
p->external_id_pin_ctl = false;
- p->lpm = true;
- p->lpm_clock_gating = true;
- p->besl = true;
- p->hird_threshold_en = true;
- p->hird_threshold = 4;
p->ipg_isoc_en = false;
p->max_packet_count = hw->max_packet_count;
p->max_transfer_size = hw->max_transfer_size;

View File

@ -1,280 +0,0 @@
From 9966a05c7b80f075f2bc7e48dbb108d3f2927234 Mon Sep 17 00:00:00 2001
From: Dave Martin <Dave.Martin@arm.com>
Date: Fri, 4 Jan 2019 13:09:51 +0000
Subject: [PATCH] arm64/sve: Disentangle <uapi/asm/ptrace.h> from
<uapi/asm/sigcontext.h>
Currently, <uapi/asm/sigcontext.h> provides common definitions for
describing SVE context structures that are also used by the ptrace
definitions in <uapi/asm/ptrace.h>.
For this reason, a #include of <asm/sigcontext.h> was added in
ptrace.h, but it this turns out that this can interact badly with
userspace code that tries to include ptrace.h on top of the libc
headers (which may provide their own shadow definitions for
sigcontext.h).
To make the headers easier for userspace to consume, this patch
bounces the common definitions into an __SVE_* namespace and moves
them to a backend header <uapi/asm/sve_context.h> that can be
included by the other headers as appropriate. This should allow
ptrace.h to be used alongside libc's sigcontext.h (if any) without
ill effects.
This should make the situation unambiguous: <asm/sigcontext.h> is
the header to include for the sigframe-specific definitions, while
<asm/ptrace.h> is the header to include for ptrace-specific
definitions.
To avoid conflicting with existing usage, <asm/sigcontext.h>
remains the canonical way to get the common definitions for
SVE_VQ_MIN, sve_vq_from_vl() etc., both in userspace and in the
kernel: relying on these being defined as a side effect of
including just <asm/ptrace.h> was never intended to be safe.
Signed-off-by: Dave Martin <Dave.Martin@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/arm64/include/uapi/asm/ptrace.h | 39 ++++++++--------
arch/arm64/include/uapi/asm/sigcontext.h | 56 +++++++++++------------
arch/arm64/include/uapi/asm/sve_context.h | 53 +++++++++++++++++++++
3 files changed, 99 insertions(+), 49 deletions(-)
create mode 100644 arch/arm64/include/uapi/asm/sve_context.h
--- a/arch/arm64/include/uapi/asm/ptrace.h
+++ b/arch/arm64/include/uapi/asm/ptrace.h
@@ -23,7 +23,7 @@
#include <linux/types.h>
#include <asm/hwcap.h>
-#include <asm/sigcontext.h>
+#include <asm/sve_context.h>
/*
@@ -129,9 +129,9 @@ struct user_sve_header {
*/
/* Offset from the start of struct user_sve_header to the register data */
-#define SVE_PT_REGS_OFFSET \
- ((sizeof(struct user_sve_header) + (SVE_VQ_BYTES - 1)) \
- / SVE_VQ_BYTES * SVE_VQ_BYTES)
+#define SVE_PT_REGS_OFFSET \
+ ((sizeof(struct user_sve_header) + (__SVE_VQ_BYTES - 1)) \
+ / __SVE_VQ_BYTES * __SVE_VQ_BYTES)
/*
* The register data content and layout depends on the value of the
@@ -177,39 +177,36 @@ struct user_sve_header {
* Additional data might be appended in the future.
*/
-#define SVE_PT_SVE_ZREG_SIZE(vq) SVE_SIG_ZREG_SIZE(vq)
-#define SVE_PT_SVE_PREG_SIZE(vq) SVE_SIG_PREG_SIZE(vq)
-#define SVE_PT_SVE_FFR_SIZE(vq) SVE_SIG_FFR_SIZE(vq)
+#define SVE_PT_SVE_ZREG_SIZE(vq) __SVE_ZREG_SIZE(vq)
+#define SVE_PT_SVE_PREG_SIZE(vq) __SVE_PREG_SIZE(vq)
+#define SVE_PT_SVE_FFR_SIZE(vq) __SVE_FFR_SIZE(vq)
#define SVE_PT_SVE_FPSR_SIZE sizeof(__u32)
#define SVE_PT_SVE_FPCR_SIZE sizeof(__u32)
-#define __SVE_SIG_TO_PT(offset) \
- ((offset) - SVE_SIG_REGS_OFFSET + SVE_PT_REGS_OFFSET)
-
#define SVE_PT_SVE_OFFSET SVE_PT_REGS_OFFSET
#define SVE_PT_SVE_ZREGS_OFFSET \
- __SVE_SIG_TO_PT(SVE_SIG_ZREGS_OFFSET)
+ (SVE_PT_REGS_OFFSET + __SVE_ZREGS_OFFSET)
#define SVE_PT_SVE_ZREG_OFFSET(vq, n) \
- __SVE_SIG_TO_PT(SVE_SIG_ZREG_OFFSET(vq, n))
+ (SVE_PT_REGS_OFFSET + __SVE_ZREG_OFFSET(vq, n))
#define SVE_PT_SVE_ZREGS_SIZE(vq) \
- (SVE_PT_SVE_ZREG_OFFSET(vq, SVE_NUM_ZREGS) - SVE_PT_SVE_ZREGS_OFFSET)
+ (SVE_PT_SVE_ZREG_OFFSET(vq, __SVE_NUM_ZREGS) - SVE_PT_SVE_ZREGS_OFFSET)
#define SVE_PT_SVE_PREGS_OFFSET(vq) \
- __SVE_SIG_TO_PT(SVE_SIG_PREGS_OFFSET(vq))
+ (SVE_PT_REGS_OFFSET + __SVE_PREGS_OFFSET(vq))
#define SVE_PT_SVE_PREG_OFFSET(vq, n) \
- __SVE_SIG_TO_PT(SVE_SIG_PREG_OFFSET(vq, n))
+ (SVE_PT_REGS_OFFSET + __SVE_PREG_OFFSET(vq, n))
#define SVE_PT_SVE_PREGS_SIZE(vq) \
- (SVE_PT_SVE_PREG_OFFSET(vq, SVE_NUM_PREGS) - \
+ (SVE_PT_SVE_PREG_OFFSET(vq, __SVE_NUM_PREGS) - \
SVE_PT_SVE_PREGS_OFFSET(vq))
#define SVE_PT_SVE_FFR_OFFSET(vq) \
- __SVE_SIG_TO_PT(SVE_SIG_FFR_OFFSET(vq))
+ (SVE_PT_REGS_OFFSET + __SVE_FFR_OFFSET(vq))
#define SVE_PT_SVE_FPSR_OFFSET(vq) \
((SVE_PT_SVE_FFR_OFFSET(vq) + SVE_PT_SVE_FFR_SIZE(vq) + \
- (SVE_VQ_BYTES - 1)) \
- / SVE_VQ_BYTES * SVE_VQ_BYTES)
+ (__SVE_VQ_BYTES - 1)) \
+ / __SVE_VQ_BYTES * __SVE_VQ_BYTES)
#define SVE_PT_SVE_FPCR_OFFSET(vq) \
(SVE_PT_SVE_FPSR_OFFSET(vq) + SVE_PT_SVE_FPSR_SIZE)
@@ -220,8 +217,8 @@ struct user_sve_header {
#define SVE_PT_SVE_SIZE(vq, flags) \
((SVE_PT_SVE_FPCR_OFFSET(vq) + SVE_PT_SVE_FPCR_SIZE \
- - SVE_PT_SVE_OFFSET + (SVE_VQ_BYTES - 1)) \
- / SVE_VQ_BYTES * SVE_VQ_BYTES)
+ - SVE_PT_SVE_OFFSET + (__SVE_VQ_BYTES - 1)) \
+ / __SVE_VQ_BYTES * __SVE_VQ_BYTES)
#define SVE_PT_SIZE(vq, flags) \
(((flags) & SVE_PT_REGS_MASK) == SVE_PT_REGS_SVE ? \
--- a/arch/arm64/include/uapi/asm/sigcontext.h
+++ b/arch/arm64/include/uapi/asm/sigcontext.h
@@ -130,6 +130,8 @@ struct sve_context {
#endif /* !__ASSEMBLY__ */
+#include <asm/sve_context.h>
+
/*
* The SVE architecture leaves space for future expansion of the
* vector length beyond its initial architectural limit of 2048 bits
@@ -138,21 +140,20 @@ struct sve_context {
* See linux/Documentation/arm64/sve.txt for a description of the VL/VQ
* terminology.
*/
-#define SVE_VQ_BYTES 16 /* number of bytes per quadword */
+#define SVE_VQ_BYTES __SVE_VQ_BYTES /* bytes per quadword */
-#define SVE_VQ_MIN 1
-#define SVE_VQ_MAX 512
+#define SVE_VQ_MIN __SVE_VQ_MIN
+#define SVE_VQ_MAX __SVE_VQ_MAX
-#define SVE_VL_MIN (SVE_VQ_MIN * SVE_VQ_BYTES)
-#define SVE_VL_MAX (SVE_VQ_MAX * SVE_VQ_BYTES)
+#define SVE_VL_MIN __SVE_VL_MIN
+#define SVE_VL_MAX __SVE_VL_MAX
-#define SVE_NUM_ZREGS 32
-#define SVE_NUM_PREGS 16
+#define SVE_NUM_ZREGS __SVE_NUM_ZREGS
+#define SVE_NUM_PREGS __SVE_NUM_PREGS
-#define sve_vl_valid(vl) \
- ((vl) % SVE_VQ_BYTES == 0 && (vl) >= SVE_VL_MIN && (vl) <= SVE_VL_MAX)
-#define sve_vq_from_vl(vl) ((vl) / SVE_VQ_BYTES)
-#define sve_vl_from_vq(vq) ((vq) * SVE_VQ_BYTES)
+#define sve_vl_valid(vl) __sve_vl_valid(vl)
+#define sve_vq_from_vl(vl) __sve_vq_from_vl(vl)
+#define sve_vl_from_vq(vq) __sve_vl_from_vq(vq)
/*
* If the SVE registers are currently live for the thread at signal delivery,
@@ -205,34 +206,33 @@ struct sve_context {
* Additional data might be appended in the future.
*/
-#define SVE_SIG_ZREG_SIZE(vq) ((__u32)(vq) * SVE_VQ_BYTES)
-#define SVE_SIG_PREG_SIZE(vq) ((__u32)(vq) * (SVE_VQ_BYTES / 8))
-#define SVE_SIG_FFR_SIZE(vq) SVE_SIG_PREG_SIZE(vq)
+#define SVE_SIG_ZREG_SIZE(vq) __SVE_ZREG_SIZE(vq)
+#define SVE_SIG_PREG_SIZE(vq) __SVE_PREG_SIZE(vq)
+#define SVE_SIG_FFR_SIZE(vq) __SVE_FFR_SIZE(vq)
#define SVE_SIG_REGS_OFFSET \
- ((sizeof(struct sve_context) + (SVE_VQ_BYTES - 1)) \
- / SVE_VQ_BYTES * SVE_VQ_BYTES)
+ ((sizeof(struct sve_context) + (__SVE_VQ_BYTES - 1)) \
+ / __SVE_VQ_BYTES * __SVE_VQ_BYTES)
-#define SVE_SIG_ZREGS_OFFSET SVE_SIG_REGS_OFFSET
+#define SVE_SIG_ZREGS_OFFSET \
+ (SVE_SIG_REGS_OFFSET + __SVE_ZREGS_OFFSET)
#define SVE_SIG_ZREG_OFFSET(vq, n) \
- (SVE_SIG_ZREGS_OFFSET + SVE_SIG_ZREG_SIZE(vq) * (n))
-#define SVE_SIG_ZREGS_SIZE(vq) \
- (SVE_SIG_ZREG_OFFSET(vq, SVE_NUM_ZREGS) - SVE_SIG_ZREGS_OFFSET)
+ (SVE_SIG_REGS_OFFSET + __SVE_ZREG_OFFSET(vq, n))
+#define SVE_SIG_ZREGS_SIZE(vq) __SVE_ZREGS_SIZE(vq)
#define SVE_SIG_PREGS_OFFSET(vq) \
- (SVE_SIG_ZREGS_OFFSET + SVE_SIG_ZREGS_SIZE(vq))
+ (SVE_SIG_REGS_OFFSET + __SVE_PREGS_OFFSET(vq))
#define SVE_SIG_PREG_OFFSET(vq, n) \
- (SVE_SIG_PREGS_OFFSET(vq) + SVE_SIG_PREG_SIZE(vq) * (n))
-#define SVE_SIG_PREGS_SIZE(vq) \
- (SVE_SIG_PREG_OFFSET(vq, SVE_NUM_PREGS) - SVE_SIG_PREGS_OFFSET(vq))
+ (SVE_SIG_REGS_OFFSET + __SVE_PREG_OFFSET(vq, n))
+#define SVE_SIG_PREGS_SIZE(vq) __SVE_PREGS_SIZE(vq)
#define SVE_SIG_FFR_OFFSET(vq) \
- (SVE_SIG_PREGS_OFFSET(vq) + SVE_SIG_PREGS_SIZE(vq))
+ (SVE_SIG_REGS_OFFSET + __SVE_FFR_OFFSET(vq))
#define SVE_SIG_REGS_SIZE(vq) \
- (SVE_SIG_FFR_OFFSET(vq) + SVE_SIG_FFR_SIZE(vq) - SVE_SIG_REGS_OFFSET)
-
-#define SVE_SIG_CONTEXT_SIZE(vq) (SVE_SIG_REGS_OFFSET + SVE_SIG_REGS_SIZE(vq))
+ (__SVE_FFR_OFFSET(vq) + __SVE_FFR_SIZE(vq))
+#define SVE_SIG_CONTEXT_SIZE(vq) \
+ (SVE_SIG_REGS_OFFSET + SVE_SIG_REGS_SIZE(vq))
#endif /* _UAPI__ASM_SIGCONTEXT_H */
--- /dev/null
+++ b/arch/arm64/include/uapi/asm/sve_context.h
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/* Copyright (C) 2017-2018 ARM Limited */
+
+/*
+ * For use by other UAPI headers only.
+ * Do not make direct use of header or its definitions.
+ */
+
+#ifndef _UAPI__ASM_SVE_CONTEXT_H
+#define _UAPI__ASM_SVE_CONTEXT_H
+
+#include <linux/types.h>
+
+#define __SVE_VQ_BYTES 16 /* number of bytes per quadword */
+
+#define __SVE_VQ_MIN 1
+#define __SVE_VQ_MAX 512
+
+#define __SVE_VL_MIN (__SVE_VQ_MIN * __SVE_VQ_BYTES)
+#define __SVE_VL_MAX (__SVE_VQ_MAX * __SVE_VQ_BYTES)
+
+#define __SVE_NUM_ZREGS 32
+#define __SVE_NUM_PREGS 16
+
+#define __sve_vl_valid(vl) \
+ ((vl) % __SVE_VQ_BYTES == 0 && \
+ (vl) >= __SVE_VL_MIN && \
+ (vl) <= __SVE_VL_MAX)
+
+#define __sve_vq_from_vl(vl) ((vl) / __SVE_VQ_BYTES)
+#define __sve_vl_from_vq(vq) ((vq) * __SVE_VQ_BYTES)
+
+#define __SVE_ZREG_SIZE(vq) ((__u32)(vq) * __SVE_VQ_BYTES)
+#define __SVE_PREG_SIZE(vq) ((__u32)(vq) * (__SVE_VQ_BYTES / 8))
+#define __SVE_FFR_SIZE(vq) __SVE_PREG_SIZE(vq)
+
+#define __SVE_ZREGS_OFFSET 0
+#define __SVE_ZREG_OFFSET(vq, n) \
+ (__SVE_ZREGS_OFFSET + __SVE_ZREG_SIZE(vq) * (n))
+#define __SVE_ZREGS_SIZE(vq) \
+ (__SVE_ZREG_OFFSET(vq, __SVE_NUM_ZREGS) - __SVE_ZREGS_OFFSET)
+
+#define __SVE_PREGS_OFFSET(vq) \
+ (__SVE_ZREGS_OFFSET + __SVE_ZREGS_SIZE(vq))
+#define __SVE_PREG_OFFSET(vq, n) \
+ (__SVE_PREGS_OFFSET(vq) + __SVE_PREG_SIZE(vq) * (n))
+#define __SVE_PREGS_SIZE(vq) \
+ (__SVE_PREG_OFFSET(vq, __SVE_NUM_PREGS) - __SVE_PREGS_OFFSET(vq))
+
+#define __SVE_FFR_OFFSET(vq) \
+ (__SVE_PREGS_OFFSET(vq) + __SVE_PREGS_SIZE(vq))
+
+#endif /* ! _UAPI__ASM_SVE_CONTEXT_H */

View File

@ -10,7 +10,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
--- a/net/netfilter/nf_flow_table_core.c
+++ b/net/netfilter/nf_flow_table_core.c
@@ -535,5 +535,35 @@ void nf_flow_table_free(struct nf_flowta
@@ -529,5 +529,35 @@ void nf_flow_table_free(struct nf_flowta
}
EXPORT_SYMBOL_GPL(nf_flow_table_free);
@ -22,7 +22,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+ if (event != NETDEV_DOWN)
+ return NOTIFY_DONE;
+
+ nf_flow_table_cleanup(dev_net(dev), dev);
+ nf_flow_table_cleanup(dev);
+
+ return NOTIFY_DONE;
+}
@ -48,7 +48,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
--- a/net/netfilter/nft_flow_offload.c
+++ b/net/netfilter/nft_flow_offload.c
@@ -216,47 +216,14 @@ static struct nft_expr_type nft_flow_off
@@ -234,47 +234,14 @@ static struct nft_expr_type nft_flow_off
.owner = THIS_MODULE,
};
@ -60,7 +60,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
- if (event != NETDEV_DOWN)
- return NOTIFY_DONE;
-
- nf_flow_table_cleanup(dev_net(dev), dev);
- nf_flow_table_cleanup(dev);
-
- return NOTIFY_DONE;
-}

View File

@ -21,7 +21,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1178,18 +1178,6 @@ static bool gc_worker_can_early_drop(con
@@ -1206,18 +1206,6 @@ static bool gc_worker_can_early_drop(con
return false;
}
@ -40,7 +40,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
static void gc_worker(struct work_struct *work)
{
unsigned int min_interval = max(HZ / GC_MAX_BUCKETS_DIV, 1u);
@@ -1226,10 +1214,8 @@ static void gc_worker(struct work_struct
@@ -1254,10 +1242,8 @@ static void gc_worker(struct work_struct
tmp = nf_ct_tuplehash_to_ctrack(h);
scanned++;
@ -54,7 +54,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
nf_ct_gc_expired(tmp);
--- a/net/netfilter/nf_flow_table_core.c
+++ b/net/netfilter/nf_flow_table_core.c
@@ -183,10 +183,29 @@ static const struct rhashtable_params nf
@@ -198,10 +198,29 @@ static const struct rhashtable_params nf
.automatic_shrinking = true,
};
@ -84,29 +84,31 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
flow->timeout = (u32)jiffies + NF_FLOW_TIMEOUT;
err = rhashtable_insert_fast(&flow_table->rhashtable,
@@ -317,6 +336,8 @@ static int nf_flow_offload_gc_step(struc
@@ -304,6 +323,7 @@ nf_flow_table_iterate(struct nf_flowtabl
rhashtable_walk_start(&hti);
while ((tuplehash = rhashtable_walk_next(&hti))) {
+ bool teardown;
+
if (IS_ERR(tuplehash)) {
err = PTR_ERR(tuplehash);
if (err != -EAGAIN)
@@ -329,9 +350,13 @@ static int nf_flow_offload_gc_step(struc
if (PTR_ERR(tuplehash) != -EAGAIN) {
err = PTR_ERR(tuplehash);
@@ -328,10 +348,17 @@ static void nf_flow_offload_gc_step(stru
{
struct nf_flowtable *flow_table = data;
struct flow_offload_entry *e;
+ bool teardown;
flow = container_of(tuplehash, struct flow_offload, tuplehash[0]);
e = container_of(flow, struct flow_offload_entry, flow);
- if (nf_flow_has_expired(flow) || nf_ct_is_dying(e->ct) ||
- (flow->flags & (FLOW_OFFLOAD_DYING | FLOW_OFFLOAD_TEARDOWN)))
+
+ teardown = flow->flags & (FLOW_OFFLOAD_DYING |
+ FLOW_OFFLOAD_TEARDOWN);
+
+ if (!teardown)
+ nf_ct_offload_timeout(flow);
+
+ if (nf_flow_has_expired(flow) || teardown)
flow_offload_del(flow_table, flow);
}
- if (nf_flow_has_expired(flow) ||
- (flow->flags & (FLOW_OFFLOAD_DYING |
- FLOW_OFFLOAD_TEARDOWN)))
+ teardown = flow->flags & (FLOW_OFFLOAD_DYING |
+ FLOW_OFFLOAD_TEARDOWN);
+
+ if (!teardown)
+ nf_ct_offload_timeout(flow);
+
+ if (nf_flow_has_expired(flow) || teardown)
flow_offload_del(flow_table, flow);
}
out:

View File

@ -12,9 +12,9 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/net/netfilter/nf_flow_table_core.c
+++ b/net/netfilter/nf_flow_table_core.c
@@ -243,6 +243,9 @@ static void flow_offload_del(struct nf_f
e = container_of(flow, struct flow_offload_entry, flow);
clear_bit(IPS_OFFLOAD_BIT, &e->ct->status);
@@ -268,6 +268,9 @@ static void flow_offload_del(struct nf_f
else if (flow->flags & FLOW_OFFLOAD_TEARDOWN)
flow_offload_fixup_ct_timeout(e->ct);
+ if (!(flow->flags & FLOW_OFFLOAD_TEARDOWN))
+ flow_offload_fixup_ct_state(e->ct);

View File

@ -1,670 +0,0 @@
From d129a72f465dab2d9fc8f1580c38600a8b808327 Mon Sep 17 00:00:00 2001
From: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
Date: Wed, 13 Mar 2019 20:54:49 +0000
Subject: [PATCH] net: sched: Backport Introduce act_ctinfo action
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
ctinfo is a new tc filter action module. It is designed to restore
information contained in firewall conntrack marks to other packet fields
and is typically used on packet ingress paths. At present it has two
independent sub-functions or operating modes, DSCP restoration mode &
skb mark restoration mode.
The DSCP restore mode:
This mode copies DSCP values that have been placed in the firewall
conntrack mark back into the IPv4/v6 diffserv fields of relevant
packets.
The DSCP restoration is intended for use and has been found useful for
restoring ingress classifications based on egress classifications across
links that bleach or otherwise change DSCP, typically home ISP Internet
links. Restoring DSCP on ingress on the WAN link allows qdiscs such as
but by no means limited to CAKE to shape inbound packets according to
policies that are easier to set & mark on egress.
Ingress classification is traditionally a challenging task since
iptables rules haven't yet run and tc filter/eBPF programs are pre-NAT
lookups, hence are unable to see internal IPv4 addresses as used on the
typical home masquerading gateway. Thus marking the connection in some
manner on egress for later restoration of classification on ingress is
easier to implement.
Parameters related to DSCP restore mode:
dscpmask - a 32 bit mask of 6 contiguous bits and indicate bits of the
conntrack mark field contain the DSCP value to be restored.
statemask - a 32 bit mask of (usually) 1 bit length, outside the area
specified by dscpmask. This represents a conditional operation flag
whereby the DSCP is only restored if the flag is set. This is useful to
implement a 'one shot' iptables based classification where the
'complicated' iptables rules are only run once to classify the
connection on initial (egress) packet and subsequent packets are all
marked/restored with the same DSCP. A mask of zero disables the
conditional behaviour ie. the conntrack mark DSCP bits are always
restored to the ip diffserv field (assuming the conntrack entry is found
& the skb is an ipv4/ipv6 type)
e.g. dscpmask 0xfc000000 statemask 0x01000000
|----0xFC----conntrack mark----000000---|
| Bits 31-26 | bit 25 | bit24 |~~~ Bit 0|
| DSCP | unused | flag |unused |
|-----------------------0x01---000000---|
| |
| |
---| Conditional flag
v only restore if set
|-ip diffserv-|
| 6 bits |
|-------------|
The skb mark restore mode (cpmark):
This mode copies the firewall conntrack mark to the skb's mark field.
It is completely the functional equivalent of the existing act_connmark
action with the additional feature of being able to apply a mask to the
restored value.
Parameters related to skb mark restore mode:
mask - a 32 bit mask applied to the firewall conntrack mark to mask out
bits unwanted for restoration. This can be useful where the conntrack
mark is being used for different purposes by different applications. If
not specified and by default the whole mark field is copied (i.e.
default mask of 0xffffffff)
e.g. mask 0x00ffffff to mask out the top 8 bits being used by the
aforementioned DSCP restore mode.
|----0x00----conntrack mark----ffffff---|
| Bits 31-24 | |
| DSCP & flag| some value here |
|---------------------------------------|
|
|
v
|------------skb mark-------------------|
| | |
| zeroed | |
|---------------------------------------|
Overall parameters:
zone - conntrack zone
control - action related control (reclassify | pipe | drop | continue |
ok | goto chain <CHAIN_INDEX>)
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
Acked-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Backport
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
---
include/net/tc_act/tc_ctinfo.h | 33 ++
include/uapi/linux/pkt_cls.h | 3 +-
include/uapi/linux/tc_act/tc_ctinfo.h | 29 ++
net/sched/Kconfig | 17 +
net/sched/Makefile | 1 +
net/sched/act_ctinfo.c | 420 ++++++++++++++++++++++
tools/testing/selftests/tc-testing/config | 1 +
7 files changed, 503 insertions(+), 1 deletion(-)
create mode 100644 include/net/tc_act/tc_ctinfo.h
create mode 100644 include/uapi/linux/tc_act/tc_ctinfo.h
create mode 100644 net/sched/act_ctinfo.c
--- /dev/null
+++ b/include/net/tc_act/tc_ctinfo.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __NET_TC_CTINFO_H
+#define __NET_TC_CTINFO_H
+
+#include <net/act_api.h>
+
+struct tcf_ctinfo_params {
+ struct rcu_head rcu;
+ struct net *net;
+ u32 dscpmask;
+ u32 dscpstatemask;
+ u32 cpmarkmask;
+ u16 zone;
+ u8 mode;
+ u8 dscpmaskshift;
+};
+
+struct tcf_ctinfo {
+ struct tc_action common;
+ struct tcf_ctinfo_params __rcu *params;
+ u64 stats_dscp_set;
+ u64 stats_dscp_error;
+ u64 stats_cpmark_set;
+};
+
+enum {
+ CTINFO_MODE_DSCP = BIT(0),
+ CTINFO_MODE_CPMARK = BIT(1)
+};
+
+#define to_ctinfo(a) ((struct tcf_ctinfo *)a)
+
+#endif /* __NET_TC_CTINFO_H */
--- a/include/uapi/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
@@ -68,7 +68,8 @@ enum {
TCA_ID_UNSPEC=0,
TCA_ID_POLICE=1,
/* other actions go here */
- __TCA_ID_MAX=255
+ TCA_ID_CTINFO,
+ __TCA_ID_MAX = 255
};
#define TCA_ID_MAX __TCA_ID_MAX
--- /dev/null
+++ b/include/uapi/linux/tc_act/tc_ctinfo.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef __UAPI_TC_CTINFO_H
+#define __UAPI_TC_CTINFO_H
+
+#include <linux/types.h>
+#include <linux/pkt_cls.h>
+
+struct tc_ctinfo {
+ tc_gen;
+};
+
+enum {
+ TCA_CTINFO_UNSPEC,
+ TCA_CTINFO_PAD,
+ TCA_CTINFO_TM,
+ TCA_CTINFO_ACT,
+ TCA_CTINFO_ZONE,
+ TCA_CTINFO_PARMS_DSCP_MASK,
+ TCA_CTINFO_PARMS_DSCP_STATEMASK,
+ TCA_CTINFO_PARMS_CPMARK_MASK,
+ TCA_CTINFO_STATS_DSCP_SET,
+ TCA_CTINFO_STATS_DSCP_ERROR,
+ TCA_CTINFO_STATS_CPMARK_SET,
+ __TCA_CTINFO_MAX
+};
+
+#define TCA_CTINFO_MAX (__TCA_CTINFO_MAX - 1)
+
+#endif
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -866,6 +866,23 @@ config NET_ACT_CONNMARK
To compile this code as a module, choose M here: the
module will be called act_connmark.
+config NET_ACT_CTINFO
+ tristate "Netfilter Connection Mark Actions"
+ depends on NET_CLS_ACT && NETFILTER && IP_NF_IPTABLES
+ depends on NF_CONNTRACK && NF_CONNTRACK_MARK
+ help
+ Say Y here to allow transfer of a connmark stored information.
+ Current actions transfer connmark stored DSCP into
+ ipv4/v6 diffserv and/or to transfer connmark to packet
+ mark. Both are useful for restoring egress based marks
+ back onto ingress connections for qdisc priority mapping
+ purposes.
+
+ If unsure, say N.
+
+ To compile this code as a module, choose M here: the
+ module will be called act_ctinfo.
+
config NET_ACT_SKBMOD
tristate "skb data modification action"
depends on NET_CLS_ACT
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_NET_ACT_CSUM) += act_csum.o
obj-$(CONFIG_NET_ACT_VLAN) += act_vlan.o
obj-$(CONFIG_NET_ACT_BPF) += act_bpf.o
obj-$(CONFIG_NET_ACT_CONNMARK) += act_connmark.o
+obj-$(CONFIG_NET_ACT_CTINFO) += act_ctinfo.o
obj-$(CONFIG_NET_ACT_SKBMOD) += act_skbmod.o
obj-$(CONFIG_NET_ACT_IFE) += act_ife.o
obj-$(CONFIG_NET_IFE_SKBMARK) += act_meta_mark.o
--- /dev/null
+++ b/net/sched/act_ctinfo.c
@@ -0,0 +1,420 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* net/sched/act_ctinfo.c netfilter ctinfo connmark actions
+ *
+ * Copyright (c) 2019 Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/skbuff.h>
+#include <linux/rtnetlink.h>
+#include <linux/pkt_cls.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <net/netlink.h>
+#include <net/pkt_sched.h>
+#include <net/act_api.h>
+#include <net/pkt_cls.h>
+#include <uapi/linux/tc_act/tc_ctinfo.h>
+#include <net/tc_act/tc_ctinfo.h>
+
+#include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_core.h>
+#include <net/netfilter/nf_conntrack_ecache.h>
+#include <net/netfilter/nf_conntrack_zones.h>
+
+static struct tc_action_ops act_ctinfo_ops;
+static unsigned int ctinfo_net_id;
+
+static void tcf_ctinfo_dscp_set(struct nf_conn *ct, struct tcf_ctinfo *ca,
+ struct tcf_ctinfo_params *cp,
+ struct sk_buff *skb, int wlen, int proto)
+{
+ u8 dscp, newdscp;
+
+ newdscp = (((ct->mark & cp->dscpmask) >> cp->dscpmaskshift) << 2) &
+ ~INET_ECN_MASK;
+
+ switch (proto) {
+ case NFPROTO_IPV4:
+ dscp = ipv4_get_dsfield(ip_hdr(skb)) & ~INET_ECN_MASK;
+ if (dscp != newdscp) {
+ if (likely(!skb_try_make_writable(skb, wlen))) {
+ ipv4_change_dsfield(ip_hdr(skb),
+ INET_ECN_MASK,
+ newdscp);
+ ca->stats_dscp_set++;
+ } else {
+ ca->stats_dscp_error++;
+ }
+ }
+ break;
+ case NFPROTO_IPV6:
+ dscp = ipv6_get_dsfield(ipv6_hdr(skb)) & ~INET_ECN_MASK;
+ if (dscp != newdscp) {
+ if (likely(!skb_try_make_writable(skb, wlen))) {
+ ipv6_change_dsfield(ipv6_hdr(skb),
+ INET_ECN_MASK,
+ newdscp);
+ ca->stats_dscp_set++;
+ } else {
+ ca->stats_dscp_error++;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static void tcf_ctinfo_cpmark_set(struct nf_conn *ct, struct tcf_ctinfo *ca,
+ struct tcf_ctinfo_params *cp,
+ struct sk_buff *skb)
+{
+ ca->stats_cpmark_set++;
+ skb->mark = ct->mark & cp->cpmarkmask;
+}
+
+static int tcf_ctinfo_act(struct sk_buff *skb, const struct tc_action *a,
+ struct tcf_result *res)
+{
+ const struct nf_conntrack_tuple_hash *thash = NULL;
+ struct tcf_ctinfo *ca = to_ctinfo(a);
+ struct nf_conntrack_tuple tuple;
+ struct nf_conntrack_zone zone;
+ enum ip_conntrack_info ctinfo;
+ struct tcf_ctinfo_params *cp;
+ struct nf_conn *ct;
+ int proto, wlen;
+ int action;
+
+ cp = rcu_dereference_bh(ca->params);
+
+ tcf_lastuse_update(&ca->tcf_tm);
+ bstats_update(&ca->tcf_bstats, skb);
+ action = READ_ONCE(ca->tcf_action);
+
+ wlen = skb_network_offset(skb);
+ if (tc_skb_protocol(skb) == htons(ETH_P_IP)) {
+ wlen += sizeof(struct iphdr);
+ if (!pskb_may_pull(skb, wlen))
+ goto out;
+
+ proto = NFPROTO_IPV4;
+ } else if (tc_skb_protocol(skb) == htons(ETH_P_IPV6)) {
+ wlen += sizeof(struct ipv6hdr);
+ if (!pskb_may_pull(skb, wlen))
+ goto out;
+
+ proto = NFPROTO_IPV6;
+ } else {
+ goto out;
+ }
+
+ ct = nf_ct_get(skb, &ctinfo);
+ if (!ct) { /* look harder, usually ingress */
+ if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb),
+ proto, cp->net, &tuple))
+ goto out;
+ zone.id = cp->zone;
+ zone.dir = NF_CT_DEFAULT_ZONE_DIR;
+
+ thash = nf_conntrack_find_get(cp->net, &zone, &tuple);
+ if (!thash)
+ goto out;
+
+ ct = nf_ct_tuplehash_to_ctrack(thash);
+ }
+
+ if (cp->mode & CTINFO_MODE_DSCP)
+ if (!cp->dscpstatemask || (ct->mark & cp->dscpstatemask))
+ tcf_ctinfo_dscp_set(ct, ca, cp, skb, wlen, proto);
+
+ if (cp->mode & CTINFO_MODE_CPMARK)
+ tcf_ctinfo_cpmark_set(ct, ca, cp, skb);
+
+ if (thash)
+ nf_ct_put(ct);
+out:
+ return action;
+}
+
+static const struct nla_policy ctinfo_policy[TCA_CTINFO_MAX + 1] = {
+ [TCA_CTINFO_ACT] = { .len = sizeof(struct
+ tc_ctinfo) },
+ [TCA_CTINFO_ZONE] = { .type = NLA_U16 },
+ [TCA_CTINFO_PARMS_DSCP_MASK] = { .type = NLA_U32 },
+ [TCA_CTINFO_PARMS_DSCP_STATEMASK] = { .type = NLA_U32 },
+ [TCA_CTINFO_PARMS_CPMARK_MASK] = { .type = NLA_U32 },
+};
+
+static int tcf_ctinfo_init(struct net *net, struct nlattr *nla,
+ struct nlattr *est, struct tc_action **a,
+ int ovr, int bind, bool rtnl_held,
+ struct netlink_ext_ack *extack)
+{
+ struct tc_action_net *tn = net_generic(net, ctinfo_net_id);
+ u32 dscpmask = 0, dscpstatemask, index;
+ struct nlattr *tb[TCA_CTINFO_MAX + 1];
+ struct tcf_ctinfo_params *cp_new;
+/* struct tcf_chain *goto_ch = NULL; */
+ struct tc_ctinfo *actparm;
+ struct tcf_ctinfo *ci;
+ u8 dscpmaskshift;
+ int ret = 0, err;
+
+ if (!nla) {
+ NL_SET_ERR_MSG_MOD(extack, "ctinfo requires attributes to be passed");
+ return -EINVAL;
+ }
+
+ err = nla_parse_nested(tb, TCA_CTINFO_MAX, nla, ctinfo_policy, extack);
+ if (err < 0)
+ return err;
+
+ if (!tb[TCA_CTINFO_ACT]) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "Missing required TCA_CTINFO_ACT attribute");
+ return -EINVAL;
+ }
+ actparm = nla_data(tb[TCA_CTINFO_ACT]);
+
+ /* do some basic validation here before dynamically allocating things */
+ /* that we would otherwise have to clean up. */
+ if (tb[TCA_CTINFO_PARMS_DSCP_MASK]) {
+ dscpmask = nla_get_u32(tb[TCA_CTINFO_PARMS_DSCP_MASK]);
+ /* need contiguous 6 bit mask */
+ dscpmaskshift = dscpmask ? __ffs(dscpmask) : 0;
+ if ((~0 & (dscpmask >> dscpmaskshift)) != 0x3f) {
+ NL_SET_ERR_MSG_ATTR(extack,
+ tb[TCA_CTINFO_PARMS_DSCP_MASK],
+ "dscp mask must be 6 contiguous bits");
+ return -EINVAL;
+ }
+ dscpstatemask = tb[TCA_CTINFO_PARMS_DSCP_STATEMASK] ?
+ nla_get_u32(tb[TCA_CTINFO_PARMS_DSCP_STATEMASK]) : 0;
+ /* mask & statemask must not overlap */
+ if (dscpmask & dscpstatemask) {
+ NL_SET_ERR_MSG_ATTR(extack,
+ tb[TCA_CTINFO_PARMS_DSCP_STATEMASK],
+ "dscp statemask must not overlap dscp mask");
+ return -EINVAL;
+ }
+ }
+
+ /* done the validation:now to the actual action allocation */
+ index = actparm->index;
+ err = tcf_idr_check_alloc(tn, &index, a, bind);
+ if (!err) {
+ ret = tcf_idr_create(tn, index, est, a,
+ &act_ctinfo_ops, bind, false);
+ if (ret) {
+ tcf_idr_cleanup(tn, index);
+ return ret;
+ }
+ ret = ACT_P_CREATED;
+ } else if (err > 0) {
+ if (bind) /* don't override defaults */
+ return 0;
+ if (!ovr) {
+ tcf_idr_release(*a, bind);
+ return -EEXIST;
+ }
+ } else {
+ return err;
+ }
+
+/* err = tcf_action_check_ctrlact(actparm->action, tp, &goto_ch, extack);
+ if (err < 0)
+ goto release_idr;
+ */
+
+ ci = to_ctinfo(*a);
+
+ cp_new = kzalloc(sizeof(*cp_new), GFP_KERNEL);
+ if (unlikely(!cp_new)) {
+ err = -ENOMEM;
+ goto put_chain;
+ }
+
+ cp_new->net = net;
+ cp_new->zone = tb[TCA_CTINFO_ZONE] ?
+ nla_get_u16(tb[TCA_CTINFO_ZONE]) : 0;
+ if (dscpmask) {
+ cp_new->dscpmask = dscpmask;
+ cp_new->dscpmaskshift = dscpmaskshift;
+ cp_new->dscpstatemask = dscpstatemask;
+ cp_new->mode |= CTINFO_MODE_DSCP;
+ }
+
+ if (tb[TCA_CTINFO_PARMS_CPMARK_MASK]) {
+ cp_new->cpmarkmask =
+ nla_get_u32(tb[TCA_CTINFO_PARMS_CPMARK_MASK]);
+ cp_new->mode |= CTINFO_MODE_CPMARK;
+ }
+
+ spin_lock_bh(&ci->tcf_lock);
+/* goto_ch = tcf_action_set_ctrlact(*a, actparm->action, goto_ch); */
+ ci->tcf_action = actparm->action;
+ rcu_swap_protected(ci->params, cp_new,
+ lockdep_is_held(&ci->tcf_lock));
+ spin_unlock_bh(&ci->tcf_lock);
+
+/* if (goto_ch)
+ tcf_chain_put_by_act(goto_ch); */
+ if (cp_new)
+ kfree_rcu(cp_new, rcu);
+
+ if (ret == ACT_P_CREATED)
+ tcf_idr_insert(tn, *a);
+
+ return ret;
+
+put_chain:
+/* if (goto_ch)
+ tcf_chain_put_by_act(goto_ch);
+release_idr: */
+ tcf_idr_release(*a, bind);
+ return err;
+}
+
+static int tcf_ctinfo_dump(struct sk_buff *skb, struct tc_action *a,
+ int bind, int ref)
+{
+ struct tcf_ctinfo *ci = to_ctinfo(a);
+ struct tc_ctinfo opt = {
+ .index = ci->tcf_index,
+ .refcnt = refcount_read(&ci->tcf_refcnt) - ref,
+ .bindcnt = atomic_read(&ci->tcf_bindcnt) - bind,
+ };
+ unsigned char *b = skb_tail_pointer(skb);
+ struct tcf_ctinfo_params *cp;
+ struct tcf_t t;
+
+ spin_lock_bh(&ci->tcf_lock);
+ cp = rcu_dereference_protected(ci->params,
+ lockdep_is_held(&ci->tcf_lock));
+
+ tcf_tm_dump(&t, &ci->tcf_tm);
+ if (nla_put_64bit(skb, TCA_CTINFO_TM, sizeof(t), &t, TCA_CTINFO_PAD))
+ goto nla_put_failure;
+
+ opt.action = ci->tcf_action;
+ if (nla_put(skb, TCA_CTINFO_ACT, sizeof(opt), &opt))
+ goto nla_put_failure;
+
+ if (nla_put_u16(skb, TCA_CTINFO_ZONE, cp->zone))
+ goto nla_put_failure;
+
+ if (cp->mode & CTINFO_MODE_DSCP) {
+ if (nla_put_u32(skb, TCA_CTINFO_PARMS_DSCP_MASK,
+ cp->dscpmask))
+ goto nla_put_failure;
+ if (nla_put_u32(skb, TCA_CTINFO_PARMS_DSCP_STATEMASK,
+ cp->dscpstatemask))
+ goto nla_put_failure;
+ }
+
+ if (cp->mode & CTINFO_MODE_CPMARK) {
+ if (nla_put_u32(skb, TCA_CTINFO_PARMS_CPMARK_MASK,
+ cp->cpmarkmask))
+ goto nla_put_failure;
+ }
+
+ if (nla_put_u64_64bit(skb, TCA_CTINFO_STATS_DSCP_SET,
+ ci->stats_dscp_set, TCA_CTINFO_PAD))
+ goto nla_put_failure;
+
+ if (nla_put_u64_64bit(skb, TCA_CTINFO_STATS_DSCP_ERROR,
+ ci->stats_dscp_error, TCA_CTINFO_PAD))
+ goto nla_put_failure;
+
+ if (nla_put_u64_64bit(skb, TCA_CTINFO_STATS_CPMARK_SET,
+ ci->stats_cpmark_set, TCA_CTINFO_PAD))
+ goto nla_put_failure;
+
+ spin_unlock_bh(&ci->tcf_lock);
+ return skb->len;
+
+nla_put_failure:
+ spin_unlock_bh(&ci->tcf_lock);
+ nlmsg_trim(skb, b);
+ return -1;
+}
+
+static int tcf_ctinfo_walker(struct net *net, struct sk_buff *skb,
+ struct netlink_callback *cb, int type,
+ const struct tc_action_ops *ops,
+ struct netlink_ext_ack *extack)
+{
+ struct tc_action_net *tn = net_generic(net, ctinfo_net_id);
+
+ return tcf_generic_walker(tn, skb, cb, type, ops, extack);
+}
+
+static int tcf_ctinfo_search(struct net *net, struct tc_action **a, u32 index,
+ struct netlink_ext_ack *extack)
+{
+ struct tc_action_net *tn = net_generic(net, ctinfo_net_id);
+
+ return tcf_idr_search(tn, a, index);
+}
+
+static void tcf_ctinfo_cleanup(struct tc_action *a)
+{
+ struct tcf_ctinfo *ci = to_ctinfo(a);
+ struct tcf_ctinfo_params *cp;
+
+ cp = rcu_dereference_protected(ci->params, 1);
+ if (cp)
+ kfree_rcu(cp, rcu);
+}
+
+static struct tc_action_ops act_ctinfo_ops = {
+ .kind = "ctinfo",
+ .type = TCA_ID_CTINFO,
+ .owner = THIS_MODULE,
+ .act = tcf_ctinfo_act,
+ .dump = tcf_ctinfo_dump,
+ .init = tcf_ctinfo_init,
+ .walk = tcf_ctinfo_walker,
+ .cleanup= tcf_ctinfo_cleanup,
+ .lookup = tcf_ctinfo_search,
+ .size = sizeof(struct tcf_ctinfo),
+};
+
+static __net_init int ctinfo_init_net(struct net *net)
+{
+ struct tc_action_net *tn = net_generic(net, ctinfo_net_id);
+
+ return tc_action_net_init(net, tn, &act_ctinfo_ops);
+}
+
+static void __net_exit ctinfo_exit_net(struct list_head *net_list)
+{
+ tc_action_net_exit(net_list, ctinfo_net_id);
+}
+
+static struct pernet_operations ctinfo_net_ops = {
+ .init = ctinfo_init_net,
+ .exit_batch = ctinfo_exit_net,
+ .id = &ctinfo_net_id,
+ .size = sizeof(struct tc_action_net),
+};
+
+static int __init ctinfo_init_module(void)
+{
+ return tcf_register_action(&act_ctinfo_ops, &ctinfo_net_ops);
+}
+
+static void __exit ctinfo_cleanup_module(void)
+{
+ tcf_unregister_action(&act_ctinfo_ops, &ctinfo_net_ops);
+}
+
+module_init(ctinfo_init_module);
+module_exit(ctinfo_cleanup_module);
+MODULE_AUTHOR("Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>");
+MODULE_DESCRIPTION("Connection tracking mark actions");
+MODULE_LICENSE("GPL");
--- a/tools/testing/selftests/tc-testing/config
+++ b/tools/testing/selftests/tc-testing/config
@@ -38,6 +38,7 @@ CONFIG_NET_ACT_CSUM=m
CONFIG_NET_ACT_VLAN=m
CONFIG_NET_ACT_BPF=m
CONFIG_NET_ACT_CONNMARK=m
+CONFIG_NET_ACT_CONNCTINFO=m
CONFIG_NET_ACT_SKBMOD=m
CONFIG_NET_ACT_IFE=m
CONFIG_NET_ACT_TUNNEL_KEY=m

View File

@ -1,37 +0,0 @@
From 9a4d83074769d6ecf1f5c3fef0f183b09abf3726 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Sat, 6 Oct 2018 17:36:42 +0200
Subject: [PATCH 1/8] mtd: spinand: winbond: Add support for W25N01GV
W25N01GV is a single die version of the already supported
W25M02GV with half the capacity. Everything else is the
same so introduce support for W25N01GV.
Datasheet:http://www.winbond.com/resource-files/w25n01gv%20revl%20050918%20unsecured.pdf
Tested on 8devices Jalapeno dev board under OpenWrt running 4.19-rc5.
Signed-off-by: Robert Marko <robimarko@gmail.com>
Reviewed-by: Boris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
drivers/mtd/nand/spi/winbond.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/drivers/mtd/nand/spi/winbond.c
+++ b/drivers/mtd/nand/spi/winbond.c
@@ -84,6 +84,14 @@ static const struct spinand_info winbond
0,
SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL),
SPINAND_SELECT_TARGET(w25m02gv_select_target)),
+ SPINAND_INFO("W25N01GV", 0xAA,
+ NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
+ NAND_ECCREQ(1, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
};
/**

View File

@ -1,188 +0,0 @@
From 10949af1681d5bb5cdbcc012815c6e40eec17d02 Mon Sep 17 00:00:00 2001
From: Schrempf Frieder <frieder.schrempf@kontron.De>
Date: Thu, 8 Nov 2018 08:32:11 +0000
Subject: [PATCH 2/8] mtd: spinand: Add initial support for Toshiba TC58CVG2S0H
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add minimal support for the Toshiba TC58CVG2S0H SPI NAND chip.
Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
Acked-by: Clément Péron <peron.clem@gmail.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
drivers/mtd/nand/spi/Makefile | 2 +-
drivers/mtd/nand/spi/core.c | 1 +
drivers/mtd/nand/spi/toshiba.c | 137 +++++++++++++++++++++++++++++++++
include/linux/mtd/spinand.h | 1 +
4 files changed, 140 insertions(+), 1 deletion(-)
create mode 100644 drivers/mtd/nand/spi/toshiba.c
--- a/drivers/mtd/nand/spi/Makefile
+++ b/drivers/mtd/nand/spi/Makefile
@@ -1,3 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
-spinand-objs := core.o macronix.o micron.o winbond.o
+spinand-objs := core.o macronix.o micron.o toshiba.o winbond.o
obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -764,6 +764,7 @@ static const struct nand_ops spinand_ops
static const struct spinand_manufacturer *spinand_manufacturers[] = {
&macronix_spinand_manufacturer,
&micron_spinand_manufacturer,
+ &toshiba_spinand_manufacturer,
&winbond_spinand_manufacturer,
};
--- /dev/null
+++ b/drivers/mtd/nand/spi/toshiba.c
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 exceet electronics GmbH
+ * Copyright (c) 2018 Kontron Electronics GmbH
+ *
+ * Author: Frieder Schrempf <frieder.schrempf@kontron.de>
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/mtd/spinand.h>
+
+#define SPINAND_MFR_TOSHIBA 0x98
+#define TOSH_STATUS_ECC_HAS_BITFLIPS_T (3 << 4)
+
+static SPINAND_OP_VARIANTS(read_cache_variants,
+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
+
+static SPINAND_OP_VARIANTS(write_cache_variants,
+ SPINAND_PROG_LOAD(true, 0, NULL, 0));
+
+static SPINAND_OP_VARIANTS(update_cache_variants,
+ SPINAND_PROG_LOAD(false, 0, NULL, 0));
+
+static int tc58cvg2s0h_ooblayout_ecc(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
+{
+ if (section > 7)
+ return -ERANGE;
+
+ region->offset = 128 + 16 * section;
+ region->length = 16;
+
+ return 0;
+}
+
+static int tc58cvg2s0h_ooblayout_free(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
+{
+ if (section > 0)
+ return -ERANGE;
+
+ /* 2 bytes reserved for BBM */
+ region->offset = 2;
+ region->length = 126;
+
+ return 0;
+}
+
+static const struct mtd_ooblayout_ops tc58cvg2s0h_ooblayout = {
+ .ecc = tc58cvg2s0h_ooblayout_ecc,
+ .free = tc58cvg2s0h_ooblayout_free,
+};
+
+static int tc58cvg2s0h_ecc_get_status(struct spinand_device *spinand,
+ u8 status)
+{
+ struct nand_device *nand = spinand_to_nand(spinand);
+ u8 mbf = 0;
+ struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, &mbf);
+
+ switch (status & STATUS_ECC_MASK) {
+ case STATUS_ECC_NO_BITFLIPS:
+ return 0;
+
+ case STATUS_ECC_UNCOR_ERROR:
+ return -EBADMSG;
+
+ case STATUS_ECC_HAS_BITFLIPS:
+ case TOSH_STATUS_ECC_HAS_BITFLIPS_T:
+ /*
+ * Let's try to retrieve the real maximum number of bitflips
+ * in order to avoid forcing the wear-leveling layer to move
+ * data around if it's not necessary.
+ */
+ if (spi_mem_exec_op(spinand->spimem, &op))
+ return nand->eccreq.strength;
+
+ mbf >>= 4;
+
+ if (WARN_ON(mbf > nand->eccreq.strength || !mbf))
+ return nand->eccreq.strength;
+
+ return mbf;
+
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static const struct spinand_info toshiba_spinand_table[] = {
+ SPINAND_INFO("TC58CVG2S0H", 0xCD,
+ NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&tc58cvg2s0h_ooblayout,
+ tc58cvg2s0h_ecc_get_status)),
+};
+
+static int toshiba_spinand_detect(struct spinand_device *spinand)
+{
+ u8 *id = spinand->id.data;
+ int ret;
+
+ /*
+ * Toshiba SPI NAND read ID needs a dummy byte,
+ * so the first byte in id is garbage.
+ */
+ if (id[1] != SPINAND_MFR_TOSHIBA)
+ return 0;
+
+ ret = spinand_match_and_init(spinand, toshiba_spinand_table,
+ ARRAY_SIZE(toshiba_spinand_table),
+ id[2]);
+ if (ret)
+ return ret;
+
+ return 1;
+}
+
+static const struct spinand_manufacturer_ops toshiba_spinand_manuf_ops = {
+ .detect = toshiba_spinand_detect,
+};
+
+const struct spinand_manufacturer toshiba_spinand_manufacturer = {
+ .id = SPINAND_MFR_TOSHIBA,
+ .name = "Toshiba",
+ .ops = &toshiba_spinand_manuf_ops,
+};
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -196,6 +196,7 @@ struct spinand_manufacturer {
/* SPI NAND manufacturers */
extern const struct spinand_manufacturer macronix_spinand_manufacturer;
extern const struct spinand_manufacturer micron_spinand_manufacturer;
+extern const struct spinand_manufacturer toshiba_spinand_manufacturer;
extern const struct spinand_manufacturer winbond_spinand_manufacturer;
/**

View File

@ -1,196 +0,0 @@
From c93c613214ac70c87beab5422a60077bf126b855 Mon Sep 17 00:00:00 2001
From: Chuanhong Guo <gch981213@gmail.com>
Date: Wed, 28 Nov 2018 21:07:25 +0800
Subject: [PATCH 3/8] mtd: spinand: add support for GigaDevice GD5FxGQ4xA
Add support for GigaDevice GD5F1G/2G/4GQ4xA SPI NAND.
Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
drivers/mtd/nand/spi/Makefile | 2 +-
drivers/mtd/nand/spi/core.c | 1 +
drivers/mtd/nand/spi/gigadevice.c | 148 ++++++++++++++++++++++++++++++
include/linux/mtd/spinand.h | 1 +
4 files changed, 151 insertions(+), 1 deletion(-)
create mode 100644 drivers/mtd/nand/spi/gigadevice.c
--- a/drivers/mtd/nand/spi/Makefile
+++ b/drivers/mtd/nand/spi/Makefile
@@ -1,3 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
-spinand-objs := core.o macronix.o micron.o toshiba.o winbond.o
+spinand-objs := core.o gigadevice.o macronix.o micron.o toshiba.o winbond.o
obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -762,6 +762,7 @@ static const struct nand_ops spinand_ops
};
static const struct spinand_manufacturer *spinand_manufacturers[] = {
+ &gigadevice_spinand_manufacturer,
&macronix_spinand_manufacturer,
&micron_spinand_manufacturer,
&toshiba_spinand_manufacturer,
--- /dev/null
+++ b/drivers/mtd/nand/spi/gigadevice.c
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Author:
+ * Chuanhong Guo <gch981213@gmail.com>
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/mtd/spinand.h>
+
+#define SPINAND_MFR_GIGADEVICE 0xC8
+#define GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS (1 << 4)
+#define GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS (3 << 4)
+
+static SPINAND_OP_VARIANTS(read_cache_variants,
+ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
+
+static SPINAND_OP_VARIANTS(write_cache_variants,
+ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
+ SPINAND_PROG_LOAD(true, 0, NULL, 0));
+
+static SPINAND_OP_VARIANTS(update_cache_variants,
+ SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
+ SPINAND_PROG_LOAD(false, 0, NULL, 0));
+
+static int gd5fxgq4xa_ooblayout_ecc(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
+{
+ if (section > 3)
+ return -ERANGE;
+
+ region->offset = (16 * section) + 8;
+ region->length = 8;
+
+ return 0;
+}
+
+static int gd5fxgq4xa_ooblayout_free(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
+{
+ if (section > 3)
+ return -ERANGE;
+
+ if (section) {
+ region->offset = 16 * section;
+ region->length = 8;
+ } else {
+ /* section 0 has one byte reserved for bad block mark */
+ region->offset = 1;
+ region->length = 7;
+ }
+ return 0;
+}
+
+static int gd5fxgq4xa_ecc_get_status(struct spinand_device *spinand,
+ u8 status)
+{
+ switch (status & STATUS_ECC_MASK) {
+ case STATUS_ECC_NO_BITFLIPS:
+ return 0;
+
+ case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS:
+ /* 1-7 bits are flipped. return the maximum. */
+ return 7;
+
+ case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS:
+ return 8;
+
+ case STATUS_ECC_UNCOR_ERROR:
+ return -EBADMSG;
+
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static const struct mtd_ooblayout_ops gd5fxgq4xa_ooblayout = {
+ .ecc = gd5fxgq4xa_ooblayout_ecc,
+ .free = gd5fxgq4xa_ooblayout_free,
+};
+
+static const struct spinand_info gigadevice_spinand_table[] = {
+ SPINAND_INFO("GD5F1GQ4xA", 0xF1,
+ NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
+ gd5fxgq4xa_ecc_get_status)),
+ SPINAND_INFO("GD5F2GQ4xA", 0xF2,
+ NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
+ gd5fxgq4xa_ecc_get_status)),
+ SPINAND_INFO("GD5F4GQ4xA", 0xF4,
+ NAND_MEMORG(1, 2048, 64, 64, 4096, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
+ gd5fxgq4xa_ecc_get_status)),
+};
+
+static int gigadevice_spinand_detect(struct spinand_device *spinand)
+{
+ u8 *id = spinand->id.data;
+ int ret;
+
+ /*
+ * For GD NANDs, There is an address byte needed to shift in before IDs
+ * are read out, so the first byte in raw_id is dummy.
+ */
+ if (id[1] != SPINAND_MFR_GIGADEVICE)
+ return 0;
+
+ ret = spinand_match_and_init(spinand, gigadevice_spinand_table,
+ ARRAY_SIZE(gigadevice_spinand_table),
+ id[2]);
+ if (ret)
+ return ret;
+
+ return 1;
+}
+
+static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = {
+ .detect = gigadevice_spinand_detect,
+};
+
+const struct spinand_manufacturer gigadevice_spinand_manufacturer = {
+ .id = SPINAND_MFR_GIGADEVICE,
+ .name = "GigaDevice",
+ .ops = &gigadevice_spinand_manuf_ops,
+};
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -194,6 +194,7 @@ struct spinand_manufacturer {
};
/* SPI NAND manufacturers */
+extern const struct spinand_manufacturer gigadevice_spinand_manufacturer;
extern const struct spinand_manufacturer macronix_spinand_manufacturer;
extern const struct spinand_manufacturer micron_spinand_manufacturer;
extern const struct spinand_manufacturer toshiba_spinand_manufacturer;

View File

@ -1,136 +0,0 @@
From db214513f62fd13c0a9af3bd5c5d634dba37e65d Mon Sep 17 00:00:00 2001
From: Yoshio Furuyama <tmcmc-mb-yfuruyama7@ml.toshiba.co.jp>
Date: Wed, 16 Jan 2019 14:53:19 +0900
Subject: [PATCH 7/8] mtd: spinand: Add support for all Toshiba Memory products
Add device table for Toshiba Memory products.
Also, generalize OOB layout structure and function names.
Signed-off-by: Yoshio Furuyama <tmcmc-mb-yfuruyama7@ml.toshiba.co.jp>
Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
drivers/mtd/nand/spi/toshiba.c | 79 ++++++++++++++++++++++++++++------
1 file changed, 65 insertions(+), 14 deletions(-)
--- a/drivers/mtd/nand/spi/toshiba.c
+++ b/drivers/mtd/nand/spi/toshiba.c
@@ -25,19 +25,19 @@ static SPINAND_OP_VARIANTS(write_cache_v
static SPINAND_OP_VARIANTS(update_cache_variants,
SPINAND_PROG_LOAD(false, 0, NULL, 0));
-static int tc58cvg2s0h_ooblayout_ecc(struct mtd_info *mtd, int section,
+static int tc58cxgxsx_ooblayout_ecc(struct mtd_info *mtd, int section,
struct mtd_oob_region *region)
{
- if (section > 7)
+ if (section > 0)
return -ERANGE;
- region->offset = 128 + 16 * section;
- region->length = 16;
+ region->offset = mtd->oobsize / 2;
+ region->length = mtd->oobsize / 2;
return 0;
}
-static int tc58cvg2s0h_ooblayout_free(struct mtd_info *mtd, int section,
+static int tc58cxgxsx_ooblayout_free(struct mtd_info *mtd, int section,
struct mtd_oob_region *region)
{
if (section > 0)
@@ -45,17 +45,17 @@ static int tc58cvg2s0h_ooblayout_free(st
/* 2 bytes reserved for BBM */
region->offset = 2;
- region->length = 126;
+ region->length = (mtd->oobsize / 2) - 2;
return 0;
}
-static const struct mtd_ooblayout_ops tc58cvg2s0h_ooblayout = {
- .ecc = tc58cvg2s0h_ooblayout_ecc,
- .free = tc58cvg2s0h_ooblayout_free,
+static const struct mtd_ooblayout_ops tc58cxgxsx_ooblayout = {
+ .ecc = tc58cxgxsx_ooblayout_ecc,
+ .free = tc58cxgxsx_ooblayout_free,
};
-static int tc58cvg2s0h_ecc_get_status(struct spinand_device *spinand,
+static int tc58cxgxsx_ecc_get_status(struct spinand_device *spinand,
u8 status)
{
struct nand_device *nand = spinand_to_nand(spinand);
@@ -94,15 +94,66 @@ static int tc58cvg2s0h_ecc_get_status(st
}
static const struct spinand_info toshiba_spinand_table[] = {
- SPINAND_INFO("TC58CVG2S0H", 0xCD,
+ /* 3.3V 1Gb */
+ SPINAND_INFO("TC58CVG0S3", 0xC2,
+ NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
+ tc58cxgxsx_ecc_get_status)),
+ /* 3.3V 2Gb */
+ SPINAND_INFO("TC58CVG1S3", 0xCB,
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
+ tc58cxgxsx_ecc_get_status)),
+ /* 3.3V 4Gb */
+ SPINAND_INFO("TC58CVG2S0", 0xCD,
+ NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
+ tc58cxgxsx_ecc_get_status)),
+ /* 1.8V 1Gb */
+ SPINAND_INFO("TC58CYG0S3", 0xB2,
+ NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
+ tc58cxgxsx_ecc_get_status)),
+ /* 1.8V 2Gb */
+ SPINAND_INFO("TC58CYG1S3", 0xBB,
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
+ tc58cxgxsx_ecc_get_status)),
+ /* 1.8V 4Gb */
+ SPINAND_INFO("TC58CYG2S0", 0xBD,
NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
NAND_ECCREQ(8, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
&write_cache_variants,
&update_cache_variants),
- SPINAND_HAS_QE_BIT,
- SPINAND_ECCINFO(&tc58cvg2s0h_ooblayout,
- tc58cvg2s0h_ecc_get_status)),
+ 0,
+ SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
+ tc58cxgxsx_ecc_get_status)),
};
static int toshiba_spinand_detect(struct spinand_device *spinand)

View File

@ -1,129 +0,0 @@
From c40c7a990a46e5102a1cc4190557bf315d32d80d Mon Sep 17 00:00:00 2001
From: Stefan Roese <sr@denx.de>
Date: Thu, 24 Jan 2019 13:48:06 +0100
Subject: [PATCH 8/8] mtd: spinand: Add support for GigaDevice GD5F1GQ4UExxG
Add support for GigaDevice GD5F1GQ4UExxG SPI NAND chip.
Signed-off-by: Stefan Roese <sr@denx.de>
Cc: Chuanhong Guo <gch981213@gmail.com>
Cc: Frieder Schrempf <frieder.schrempf@kontron.de>
Cc: Miquel Raynal <miquel.raynal@bootlin.com>
Cc: Boris Brezillon <bbrezillon@kernel.org>
Reviewed-by: Boris Brezillon <bbrezillon@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
drivers/mtd/nand/spi/gigadevice.c | 83 +++++++++++++++++++++++++++++++
1 file changed, 83 insertions(+)
--- a/drivers/mtd/nand/spi/gigadevice.c
+++ b/drivers/mtd/nand/spi/gigadevice.c
@@ -12,6 +12,8 @@
#define GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS (1 << 4)
#define GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS (3 << 4)
+#define GD5FXGQ4UEXXG_REG_STATUS2 0xf0
+
static SPINAND_OP_VARIANTS(read_cache_variants,
SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
@@ -81,11 +83,83 @@ static int gd5fxgq4xa_ecc_get_status(str
return -EINVAL;
}
+static int gd5fxgq4uexxg_ooblayout_ecc(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
+{
+ if (section)
+ return -ERANGE;
+
+ region->offset = 64;
+ region->length = 64;
+
+ return 0;
+}
+
+static int gd5fxgq4uexxg_ooblayout_free(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
+{
+ if (section)
+ return -ERANGE;
+
+ /* Reserve 1 bytes for the BBM. */
+ region->offset = 1;
+ region->length = 63;
+
+ return 0;
+}
+
+static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand,
+ u8 status)
+{
+ u8 status2;
+ struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQ4UEXXG_REG_STATUS2,
+ &status2);
+ int ret;
+
+ switch (status & STATUS_ECC_MASK) {
+ case STATUS_ECC_NO_BITFLIPS:
+ return 0;
+
+ case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS:
+ /*
+ * Read status2 register to determine a more fine grained
+ * bit error status
+ */
+ ret = spi_mem_exec_op(spinand->spimem, &op);
+ if (ret)
+ return ret;
+
+ /*
+ * 4 ... 7 bits are flipped (1..4 can't be detected, so
+ * report the maximum of 4 in this case
+ */
+ /* bits sorted this way (3...0): ECCS1,ECCS0,ECCSE1,ECCSE0 */
+ return ((status & STATUS_ECC_MASK) >> 2) |
+ ((status2 & STATUS_ECC_MASK) >> 4);
+
+ case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS:
+ return 8;
+
+ case STATUS_ECC_UNCOR_ERROR:
+ return -EBADMSG;
+
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
static const struct mtd_ooblayout_ops gd5fxgq4xa_ooblayout = {
.ecc = gd5fxgq4xa_ooblayout_ecc,
.free = gd5fxgq4xa_ooblayout_free,
};
+static const struct mtd_ooblayout_ops gd5fxgq4uexxg_ooblayout = {
+ .ecc = gd5fxgq4uexxg_ooblayout_ecc,
+ .free = gd5fxgq4uexxg_ooblayout_free,
+};
+
static const struct spinand_info gigadevice_spinand_table[] = {
SPINAND_INFO("GD5F1GQ4xA", 0xF1,
NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
@@ -114,6 +188,15 @@ static const struct spinand_info gigadev
0,
SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
gd5fxgq4xa_ecc_get_status)),
+ SPINAND_INFO("GD5F1GQ4UExxG", 0xd1,
+ NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&gd5fxgq4uexxg_ooblayout,
+ gd5fxgq4uexxg_ecc_get_status)),
};
static int gigadevice_spinand_detect(struct spinand_device *spinand)

View File

@ -1,25 +0,0 @@
From 81554171373018b83f3554b9e725d2b5bf1844a5 Mon Sep 17 00:00:00 2001
From: Alexander Sverdlin <alexander.sverdlin@nokia.com>
Date: Fri, 13 Jul 2018 15:06:46 +0200
Subject: [PATCH] mtd: spi-nor: Add support for mx25u12835f
This chip supports dual and quad read and uniform 4K-byte erase.
Signed-off-by: Alexander Sverdlin <alexander.sverdlin@nokia.com>
Reviewed-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
---
drivers/mtd/spi-nor/spi-nor.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -1088,6 +1088,8 @@ static const struct flash_info spi_nor_i
{ "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) },
{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
+ { "mx25u12835f", INFO(0xc22538, 0, 64 * 1024, 256,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_4B_OPCODES) },
{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },

View File

@ -1,81 +0,0 @@
From d014717d50b1efd011a3a028ce92563a4dc9bae5 Mon Sep 17 00:00:00 2001
From: Jeff Kletsky <git-commits@allycomm.com>
Date: Wed, 22 May 2019 15:05:53 -0700
Subject: [PATCH 1/3] mtd: spinand: Define macros for page-read ops with
three-byte addresses
The GigaDevice GD5F1GQ4UFxxG SPI NAND utilizes three-byte addresses
for its page-read ops.
http://www.gigadevice.com/datasheet/gd5f1gq4xfxxg/
Signed-off-by: Jeff Kletsky <git-commits@allycomm.com>
Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
include/linux/mtd/spinand.h | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -68,30 +68,60 @@
SPI_MEM_OP_DUMMY(ndummy, 1), \
SPI_MEM_OP_DATA_IN(len, buf, 1))
+#define SPINAND_PAGE_READ_FROM_CACHE_OP_3A(fast, addr, ndummy, buf, len) \
+ SPI_MEM_OP(SPI_MEM_OP_CMD(fast ? 0x0b : 0x03, 1), \
+ SPI_MEM_OP_ADDR(3, addr, 1), \
+ SPI_MEM_OP_DUMMY(ndummy, 1), \
+ SPI_MEM_OP_DATA_IN(len, buf, 1))
+
#define SPINAND_PAGE_READ_FROM_CACHE_X2_OP(addr, ndummy, buf, len) \
SPI_MEM_OP(SPI_MEM_OP_CMD(0x3b, 1), \
SPI_MEM_OP_ADDR(2, addr, 1), \
SPI_MEM_OP_DUMMY(ndummy, 1), \
SPI_MEM_OP_DATA_IN(len, buf, 2))
+#define SPINAND_PAGE_READ_FROM_CACHE_X2_OP_3A(addr, ndummy, buf, len) \
+ SPI_MEM_OP(SPI_MEM_OP_CMD(0x3b, 1), \
+ SPI_MEM_OP_ADDR(3, addr, 1), \
+ SPI_MEM_OP_DUMMY(ndummy, 1), \
+ SPI_MEM_OP_DATA_IN(len, buf, 2))
+
#define SPINAND_PAGE_READ_FROM_CACHE_X4_OP(addr, ndummy, buf, len) \
SPI_MEM_OP(SPI_MEM_OP_CMD(0x6b, 1), \
SPI_MEM_OP_ADDR(2, addr, 1), \
SPI_MEM_OP_DUMMY(ndummy, 1), \
SPI_MEM_OP_DATA_IN(len, buf, 4))
+#define SPINAND_PAGE_READ_FROM_CACHE_X4_OP_3A(addr, ndummy, buf, len) \
+ SPI_MEM_OP(SPI_MEM_OP_CMD(0x6b, 1), \
+ SPI_MEM_OP_ADDR(3, addr, 1), \
+ SPI_MEM_OP_DUMMY(ndummy, 1), \
+ SPI_MEM_OP_DATA_IN(len, buf, 4))
+
#define SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(addr, ndummy, buf, len) \
SPI_MEM_OP(SPI_MEM_OP_CMD(0xbb, 1), \
SPI_MEM_OP_ADDR(2, addr, 2), \
SPI_MEM_OP_DUMMY(ndummy, 2), \
SPI_MEM_OP_DATA_IN(len, buf, 2))
+#define SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP_3A(addr, ndummy, buf, len) \
+ SPI_MEM_OP(SPI_MEM_OP_CMD(0xbb, 1), \
+ SPI_MEM_OP_ADDR(3, addr, 2), \
+ SPI_MEM_OP_DUMMY(ndummy, 2), \
+ SPI_MEM_OP_DATA_IN(len, buf, 2))
+
#define SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(addr, ndummy, buf, len) \
SPI_MEM_OP(SPI_MEM_OP_CMD(0xeb, 1), \
SPI_MEM_OP_ADDR(2, addr, 4), \
SPI_MEM_OP_DUMMY(ndummy, 4), \
SPI_MEM_OP_DATA_IN(len, buf, 4))
+#define SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP_3A(addr, ndummy, buf, len) \
+ SPI_MEM_OP(SPI_MEM_OP_CMD(0xeb, 1), \
+ SPI_MEM_OP_ADDR(3, addr, 4), \
+ SPI_MEM_OP_DUMMY(ndummy, 4), \
+ SPI_MEM_OP_DATA_IN(len, buf, 4))
+
#define SPINAND_PROG_EXEC_OP(addr) \
SPI_MEM_OP(SPI_MEM_OP_CMD(0x10, 1), \
SPI_MEM_OP_ADDR(3, addr, 1), \

View File

@ -1,48 +0,0 @@
From 53dd94a79d3bfdaae30e5a4ebf474ea1af1d572e Mon Sep 17 00:00:00 2001
From: Jeff Kletsky <git-commits@allycomm.com>
Date: Wed, 22 May 2019 15:05:54 -0700
Subject: [PATCH 2/3] mtd: spinand: Add support for two-byte device IDs
The GigaDevice GD5F1GQ4UFxxG SPI NAND utilizes two-byte device IDs.
http://www.gigadevice.com/datasheet/gd5f1gq4xfxxg/
Signed-off-by: Jeff Kletsky <git-commits@allycomm.com>
Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
drivers/mtd/nand/spi/core.c | 2 +-
include/linux/mtd/spinand.h | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -853,7 +853,7 @@ spinand_select_op_variant(struct spinand
*/
int spinand_match_and_init(struct spinand_device *spinand,
const struct spinand_info *table,
- unsigned int table_size, u8 devid)
+ unsigned int table_size, u16 devid)
{
struct nand_device *nand = spinand_to_nand(spinand);
unsigned int i;
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -290,7 +290,7 @@ struct spinand_ecc_info {
*/
struct spinand_info {
const char *model;
- u8 devid;
+ u16 devid;
u32 flags;
struct nand_memory_organization memorg;
struct nand_ecc_req eccreq;
@@ -445,7 +445,7 @@ static inline void spinand_set_of_node(s
int spinand_match_and_init(struct spinand_device *dev,
const struct spinand_info *table,
- unsigned int table_size, u8 devid);
+ unsigned int table_size, u16 devid);
int spinand_upd_cfg(struct spinand_device *spinand, u8 mask, u8 val);
int spinand_select_target(struct spinand_device *spinand, unsigned int target);

View File

@ -1,197 +0,0 @@
IMPORTANT NOTE
==============
The content of this patch has been adapted for Linux 4.19
Changes were made in Linux 5.x to add the bad-block limit
to the metadata available to the driver, adding a parameter
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
^- New bad-block limit
This patch omits that parameter from the upstream patch
for compatibility with the Linux 4.19 driver.
=====
From 049df13c4e63884fe6634db5568e08f65922256e Mon Sep 17 00:00:00 2001
From: Jeff Kletsky <git-commits@allycomm.com>
Date: Wed, 22 May 2019 15:05:55 -0700
Subject: [PATCH 3/3] mtd: spinand: Add support for GigaDevice GD5F1GQ4UFxxG
The GigaDevice GD5F1GQ4UFxxG SPI NAND is in current production devices
and, while it has the same logical layout as the E-series devices,
it differs in the SPI interfacing in significant ways.
This support is contingent on previous commits to:
* Add support for two-byte device IDs
* Define macros for page-read ops with three-byte addresses
http://www.gigadevice.com/datasheet/gd5f1gq4xfxxg/
Signed-off-by: Jeff Kletsky <git-commits@allycomm.com>
Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
drivers/mtd/nand/spi/gigadevice.c | 79 +++++++++++++++++++++++++------
1 file changed, 64 insertions(+), 15 deletions(-)
--- a/drivers/mtd/nand/spi/gigadevice.c
+++ b/drivers/mtd/nand/spi/gigadevice.c
@@ -9,11 +9,17 @@
#include <linux/mtd/spinand.h>
#define SPINAND_MFR_GIGADEVICE 0xC8
+
#define GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS (1 << 4)
#define GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS (3 << 4)
#define GD5FXGQ4UEXXG_REG_STATUS2 0xf0
+#define GD5FXGQ4UXFXXG_STATUS_ECC_MASK (7 << 4)
+#define GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS (0 << 4)
+#define GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS (1 << 4)
+#define GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR (7 << 4)
+
static SPINAND_OP_VARIANTS(read_cache_variants,
SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
@@ -22,6 +28,14 @@ static SPINAND_OP_VARIANTS(read_cache_va
SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
+static SPINAND_OP_VARIANTS(read_cache_variants_f,
+ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP_3A(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP_3A(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_OP_3A(true, 0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_OP_3A(false, 0, 0, NULL, 0));
+
static SPINAND_OP_VARIANTS(write_cache_variants,
SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
SPINAND_PROG_LOAD(true, 0, NULL, 0));
@@ -59,6 +73,11 @@ static int gd5fxgq4xa_ooblayout_free(str
return 0;
}
+static const struct mtd_ooblayout_ops gd5fxgq4xa_ooblayout = {
+ .ecc = gd5fxgq4xa_ooblayout_ecc,
+ .free = gd5fxgq4xa_ooblayout_free,
+};
+
static int gd5fxgq4xa_ecc_get_status(struct spinand_device *spinand,
u8 status)
{
@@ -83,7 +102,7 @@ static int gd5fxgq4xa_ecc_get_status(str
return -EINVAL;
}
-static int gd5fxgq4uexxg_ooblayout_ecc(struct mtd_info *mtd, int section,
+static int gd5fxgq4_variant2_ooblayout_ecc(struct mtd_info *mtd, int section,
struct mtd_oob_region *region)
{
if (section)
@@ -95,7 +114,7 @@ static int gd5fxgq4uexxg_ooblayout_ecc(s
return 0;
}
-static int gd5fxgq4uexxg_ooblayout_free(struct mtd_info *mtd, int section,
+static int gd5fxgq4_variant2_ooblayout_free(struct mtd_info *mtd, int section,
struct mtd_oob_region *region)
{
if (section)
@@ -108,6 +127,11 @@ static int gd5fxgq4uexxg_ooblayout_free(
return 0;
}
+static const struct mtd_ooblayout_ops gd5fxgq4_variant2_ooblayout = {
+ .ecc = gd5fxgq4_variant2_ooblayout_ecc,
+ .free = gd5fxgq4_variant2_ooblayout_free,
+};
+
static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand,
u8 status)
{
@@ -150,15 +174,25 @@ static int gd5fxgq4uexxg_ecc_get_status(
return -EINVAL;
}
-static const struct mtd_ooblayout_ops gd5fxgq4xa_ooblayout = {
- .ecc = gd5fxgq4xa_ooblayout_ecc,
- .free = gd5fxgq4xa_ooblayout_free,
-};
+static int gd5fxgq4ufxxg_ecc_get_status(struct spinand_device *spinand,
+ u8 status)
+{
+ switch (status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) {
+ case GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS:
+ return 0;
-static const struct mtd_ooblayout_ops gd5fxgq4uexxg_ooblayout = {
- .ecc = gd5fxgq4uexxg_ooblayout_ecc,
- .free = gd5fxgq4uexxg_ooblayout_free,
-};
+ case GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS:
+ return 3;
+
+ case GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR:
+ return -EBADMSG;
+
+ default: /* (2 << 4) through (6 << 4) are 4-8 corrected errors */
+ return ((status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) >> 4) + 2;
+ }
+
+ return -EINVAL;
+}
static const struct spinand_info gigadevice_spinand_table[] = {
SPINAND_INFO("GD5F1GQ4xA", 0xF1,
@@ -195,25 +229,40 @@ static const struct spinand_info gigadev
&write_cache_variants,
&update_cache_variants),
0,
- SPINAND_ECCINFO(&gd5fxgq4uexxg_ooblayout,
+ SPINAND_ECCINFO(&gd5fxgq4_variant2_ooblayout,
gd5fxgq4uexxg_ecc_get_status)),
+ SPINAND_INFO("GD5F1GQ4UFxxG", 0xb148,
+ NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
+ &write_cache_variants,
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&gd5fxgq4_variant2_ooblayout,
+ gd5fxgq4ufxxg_ecc_get_status)),
};
static int gigadevice_spinand_detect(struct spinand_device *spinand)
{
u8 *id = spinand->id.data;
+ u16 did;
int ret;
/*
- * For GD NANDs, There is an address byte needed to shift in before IDs
- * are read out, so the first byte in raw_id is dummy.
+ * Earlier GDF5-series devices (A,E) return [0][MID][DID]
+ * Later (F) devices return [MID][DID1][DID2]
*/
- if (id[1] != SPINAND_MFR_GIGADEVICE)
+
+ if (id[0] == SPINAND_MFR_GIGADEVICE)
+ did = (id[1] << 8) + id[2];
+ else if (id[0] == 0 && id[1] == SPINAND_MFR_GIGADEVICE)
+ did = id[2];
+ else
return 0;
ret = spinand_match_and_init(spinand, gigadevice_spinand_table,
ARRAY_SIZE(gigadevice_spinand_table),
- id[2]);
+ did);
if (ret)
return ret;

View File

@ -1,203 +0,0 @@
From 3552691616c940a7c4125c2678ba816653cd725e Mon Sep 17 00:00:00 2001
From: Jeff Kletsky <git-commits@allycomm.com>
Date: Tue, 18 Jun 2019 10:08:05 -0700
Subject: [PATCH] mtd: spinand: Add initial support for Paragon PN26G0xA
Add initial support for Paragon Technology
PN26G01Axxxxx and PN26G02Axxxxx SPI NAND
Datasheets available at
http://www.xtxtech.com/upfile/2016082517274590.pdf
http://www.xtxtech.com/upfile/2016082517282329.pdf
Signed-off-by: Jeff Kletsky <git-commits@allycomm.com>
Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
ADOPTED FROM UPSTREAM due to upstream commit 377e517b5fa5 in Linux 5.2
which added another parameter to NAND_MEMORG
---
drivers/mtd/nand/spi/Makefile | 2 +-
drivers/mtd/nand/spi/core.c | 1 +
drivers/mtd/nand/spi/paragon.c | 147 +++++++++++++++++++++++++++++++++
include/linux/mtd/spinand.h | 1 +
4 files changed, 150 insertions(+), 1 deletion(-)
create mode 100644 drivers/mtd/nand/spi/paragon.c
--- a/drivers/mtd/nand/spi/Makefile
+++ b/drivers/mtd/nand/spi/Makefile
@@ -1,3 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
-spinand-objs := core.o gigadevice.o macronix.o micron.o toshiba.o winbond.o
+spinand-objs := core.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o
obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -765,6 +765,7 @@ static const struct spinand_manufacturer
&gigadevice_spinand_manufacturer,
&macronix_spinand_manufacturer,
&micron_spinand_manufacturer,
+ &paragon_spinand_manufacturer,
&toshiba_spinand_manufacturer,
&winbond_spinand_manufacturer,
};
--- /dev/null
+++ b/drivers/mtd/nand/spi/paragon.c
@@ -0,0 +1,147 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 Jeff Kletsky
+ *
+ * Author: Jeff Kletsky <git-commits@allycomm.com>
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/mtd/spinand.h>
+
+
+#define SPINAND_MFR_PARAGON 0xa1
+
+
+#define PN26G0XA_STATUS_ECC_BITMASK (3 << 4)
+
+#define PN26G0XA_STATUS_ECC_NONE_DETECTED (0 << 4)
+#define PN26G0XA_STATUS_ECC_1_7_CORRECTED (1 << 4)
+#define PN26G0XA_STATUS_ECC_ERRORED (2 << 4)
+#define PN26G0XA_STATUS_ECC_8_CORRECTED (3 << 4)
+
+
+static SPINAND_OP_VARIANTS(read_cache_variants,
+ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
+
+static SPINAND_OP_VARIANTS(write_cache_variants,
+ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
+ SPINAND_PROG_LOAD(true, 0, NULL, 0));
+
+static SPINAND_OP_VARIANTS(update_cache_variants,
+ SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
+ SPINAND_PROG_LOAD(false, 0, NULL, 0));
+
+
+static int pn26g0xa_ooblayout_ecc(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
+{
+ if (section > 3)
+ return -ERANGE;
+
+ region->offset = 6 + (15 * section); /* 4 BBM + 2 user bytes */
+ region->length = 13;
+
+ return 0;
+}
+
+static int pn26g0xa_ooblayout_free(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
+{
+ if (section > 4)
+ return -ERANGE;
+
+ if (section == 4) {
+ region->offset = 64;
+ region->length = 64;
+ } else {
+ region->offset = 4 + (15 * section);
+ region->length = 2;
+ }
+
+ return 0;
+}
+
+static int pn26g0xa_ecc_get_status(struct spinand_device *spinand,
+ u8 status)
+{
+ switch (status & PN26G0XA_STATUS_ECC_BITMASK) {
+ case PN26G0XA_STATUS_ECC_NONE_DETECTED:
+ return 0;
+
+ case PN26G0XA_STATUS_ECC_1_7_CORRECTED:
+ return 7; /* Return upper limit by convention */
+
+ case PN26G0XA_STATUS_ECC_8_CORRECTED:
+ return 8;
+
+ case PN26G0XA_STATUS_ECC_ERRORED:
+ return -EBADMSG;
+
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static const struct mtd_ooblayout_ops pn26g0xa_ooblayout = {
+ .ecc = pn26g0xa_ooblayout_ecc,
+ .free = pn26g0xa_ooblayout_free,
+};
+
+
+static const struct spinand_info paragon_spinand_table[] = {
+ SPINAND_INFO("PN26G01A", 0xe1,
+ NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&pn26g0xa_ooblayout,
+ pn26g0xa_ecc_get_status)),
+ SPINAND_INFO("PN26G02A", 0xe2,
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&pn26g0xa_ooblayout,
+ pn26g0xa_ecc_get_status)),
+};
+
+static int paragon_spinand_detect(struct spinand_device *spinand)
+{
+ u8 *id = spinand->id.data;
+ int ret;
+
+ /* Read ID returns [0][MID][DID] */
+
+ if (id[1] != SPINAND_MFR_PARAGON)
+ return 0;
+
+ ret = spinand_match_and_init(spinand, paragon_spinand_table,
+ ARRAY_SIZE(paragon_spinand_table),
+ id[2]);
+ if (ret)
+ return ret;
+
+ return 1;
+}
+
+static const struct spinand_manufacturer_ops paragon_spinand_manuf_ops = {
+ .detect = paragon_spinand_detect,
+};
+
+const struct spinand_manufacturer paragon_spinand_manufacturer = {
+ .id = SPINAND_MFR_PARAGON,
+ .name = "Paragon",
+ .ops = &paragon_spinand_manuf_ops,
+};
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -227,6 +227,7 @@ struct spinand_manufacturer {
extern const struct spinand_manufacturer gigadevice_spinand_manufacturer;
extern const struct spinand_manufacturer macronix_spinand_manufacturer;
extern const struct spinand_manufacturer micron_spinand_manufacturer;
+extern const struct spinand_manufacturer paragon_spinand_manufacturer;
extern const struct spinand_manufacturer toshiba_spinand_manufacturer;
extern const struct spinand_manufacturer winbond_spinand_manufacturer;

View File

@ -1,44 +0,0 @@
From 6f3ea4e5b1f0867ec217f6101fcb89783ed905d7 Mon Sep 17 00:00:00 2001
From: Russell King <rmk+kernel@armlinux.org.uk>
Date: Sat, 9 Feb 2019 18:23:26 +0000
Subject: [PATCH] net: phylink: only call mac_config() during resolve
when link is up
There's little point calling mac_config() when the link is down.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/phylink.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -339,6 +339,13 @@ static void phylink_mac_config(struct ph
pl->ops->mac_config(pl->netdev, pl->link_an_mode, state);
}
+static void phylink_mac_config_up(struct phylink *pl,
+ const struct phylink_link_state *state)
+{
+ if (state->link)
+ phylink_mac_config(pl, state);
+}
+
static void phylink_mac_an_restart(struct phylink *pl)
{
if (pl->link_config.an_enabled &&
@@ -442,12 +449,12 @@ static void phylink_resolve(struct work_
case MLO_AN_PHY:
link_state = pl->phy_state;
phylink_resolve_flow(pl, &link_state);
- phylink_mac_config(pl, &link_state);
+ phylink_mac_config_up(pl, &link_state);
break;
case MLO_AN_FIXED:
phylink_get_fixed_state(pl, &link_state);
- phylink_mac_config(pl, &link_state);
+ phylink_mac_config_up(pl, &link_state);
break;
case MLO_AN_INBAND:

View File

@ -1,59 +0,0 @@
From 72f973f292b3eaaf451ebcd3253900d41f4ef24a Mon Sep 17 00:00:00 2001
From: Russell King <rmk+kernel@armlinux.org.uk>
Date: Fri, 25 Jan 2019 17:42:51 +0000
Subject: [PATCH] net: phylink: ensure inband AN works correctly
Do not update the link interface mode while the link is down to avoid
spurious link interface changes.
Always call mac_config if we have a PHY to propagate the pause mode
settings to the MAC.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/phylink.c | 37 +++++++++++++++----------------------
1 file changed, 15 insertions(+), 22 deletions(-)
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -459,28 +459,21 @@ static void phylink_resolve(struct work_
case MLO_AN_INBAND:
phylink_get_mac_state(pl, &link_state);
- if (pl->phydev) {
- bool changed = false;
- link_state.link = link_state.link &&
- pl->phy_state.link;
+ /* If we have a phy, the "up" state is the union of
+ * both the PHY and the MAC */
+ if (pl->phydev)
+ link_state.link &= pl->phy_state.link;
- if (pl->phy_state.interface !=
- link_state.interface) {
- link_state.interface = pl->phy_state.interface;
- changed = true;
- }
+ /* Only update if the PHY link is up */
+ if (pl->phydev && pl->phy_state.link) {
+ link_state.interface = pl->phy_state.interface;
- /* Propagate the flow control from the PHY
- * to the MAC. Also propagate the interface
- * if changed.
- */
- if (pl->phy_state.link || changed) {
- link_state.pause |= pl->phy_state.pause;
- phylink_resolve_flow(pl, &link_state);
-
- phylink_mac_config(pl, &link_state);
- }
+ /* If we have a PHY, we need to update with
+ * the pause mode bits. */
+ link_state.pause |= pl->phy_state.pause;
+ phylink_resolve_flow(pl, &link_state);
+ phylink_mac_config(pl, &link_state);
}
break;
}

View File

@ -1,49 +0,0 @@
From 1da223db3a0c522300b519ecbe1dc45927e28088 Mon Sep 17 00:00:00 2001
From: Andrew Lunn <andrew@lunn.ch>
Date: Wed, 12 Sep 2018 01:53:15 +0200
Subject: [PATCH 600/660] net: ethernet: Add helper for MACs which support asym
pause
Rather than have the MAC drivers manipulate phydev members to indicate
they support Asym Pause, add a helper function.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/phy/phy_device.c | 13 +++++++++++++
include/linux/phy.h | 1 +
2 files changed, 14 insertions(+)
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1777,6 +1777,19 @@ int phy_set_max_speed(struct phy_device
}
EXPORT_SYMBOL(phy_set_max_speed);
+/**
+ * phy_support_asym_pause - Enable support of asym pause
+ * @phydev: target phy_device struct
+ *
+ * Description: Called by the MAC to indicate is supports Asym Pause.
+ */
+void phy_support_asym_pause(struct phy_device *phydev)
+{
+ phydev->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
+ phydev->advertising = phydev->supported;
+}
+EXPORT_SYMBOL(phy_support_asym_pause);
+
static void of_set_phy_supported(struct phy_device *phydev)
{
struct device_node *node = phydev->mdio.dev.of_node;
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -1049,6 +1049,7 @@ int phy_mii_ioctl(struct phy_device *phy
int phy_start_interrupts(struct phy_device *phydev);
void phy_print_status(struct phy_device *phydev);
int phy_set_max_speed(struct phy_device *phydev, u32 max_speed);
+void phy_support_asym_pause(struct phy_device *phydev);
int phy_register_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask,
int (*run)(struct phy_device *));

View File

@ -1,66 +0,0 @@
From ce825df56e0480a2cbb296e38976babafb57e503 Mon Sep 17 00:00:00 2001
From: Andrew Lunn <andrew@lunn.ch>
Date: Wed, 12 Sep 2018 01:53:17 +0200
Subject: [PATCH 601/660] net: ethernet: Add helper for set_pauseparam for Asym
Pause
ethtool can be used to enable/disable pause. Add a helper to configure
the PHY when asym pause is supported.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/phy/phy_device.c | 30 ++++++++++++++++++++++++++++++
include/linux/phy.h | 1 +
2 files changed, 31 insertions(+)
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1790,6 +1790,36 @@ void phy_support_asym_pause(struct phy_d
}
EXPORT_SYMBOL(phy_support_asym_pause);
+/**
+ * phy_set_asym_pause - Configure Pause and Asym Pause
+ * @phydev: target phy_device struct
+ * @rx: Receiver Pause is supported
+ * @tx: Transmit Pause is supported
+ *
+ * Description: Configure advertised Pause support depending on if
+ * transmit and receiver pause is supported. If there has been a
+ * change in adverting, trigger a new autoneg. Generally called from
+ * the set_pauseparam .ndo.
+ */
+void phy_set_asym_pause(struct phy_device *phydev, bool rx, bool tx)
+{
+ u16 oldadv = phydev->advertising;
+ u16 newadv = oldadv &= ~(SUPPORTED_Pause | SUPPORTED_Asym_Pause);
+
+ if (rx)
+ newadv |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
+ if (tx)
+ newadv ^= SUPPORTED_Asym_Pause;
+
+ if (oldadv != newadv) {
+ phydev->advertising = newadv;
+
+ if (phydev->autoneg)
+ phy_start_aneg(phydev);
+ }
+}
+EXPORT_SYMBOL(phy_set_asym_pause);
+
static void of_set_phy_supported(struct phy_device *phydev)
{
struct device_node *node = phydev->mdio.dev.of_node;
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -1050,6 +1050,7 @@ int phy_start_interrupts(struct phy_devi
void phy_print_status(struct phy_device *phydev);
int phy_set_max_speed(struct phy_device *phydev, u32 max_speed);
void phy_support_asym_pause(struct phy_device *phydev);
+void phy_set_asym_pause(struct phy_device *phydev, bool rx, bool tx);
int phy_register_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask,
int (*run)(struct phy_device *));

View File

@ -1,40 +0,0 @@
From 1541649a9dd79e9b941d399de564475e426a2d0b Mon Sep 17 00:00:00 2001
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Tue, 25 Sep 2018 11:28:45 -0700
Subject: [PATCH 602/660] net: phy: Stop with excessive soft reset
While consolidating the PHY reset in phy_init_hw() an unconditionaly
BMCR soft-reset I became quite trigger happy with those. This was later
on deactivated for the Generic PHY driver on the premise that a prior
software entity (e.g: bootloader) might have applied workarounds in
commit 0878fff1f42c ("net: phy: Do not perform software reset for
Generic PHY").
Since we have a hook to wire-up a soft_reset callback, just use that and
get rid of the call to genphy_soft_reset() entirely. This speeds up
initialization and link establishment for most PHYs out there that do
not require a reset.
Fixes: 87aa9f9c61ad ("net: phy: consolidate PHY reset in phy_init_hw()")
Tested-by: Wang, Dongsheng <dongsheng.wang@hxt-semitech.com>
Tested-by: Chris Healy <cphealy@gmail.com>
Tested-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Clemens Gruber <clemens.gruber@pqgruber.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/phy_device.c | 2 --
1 file changed, 2 deletions(-)
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -886,8 +886,6 @@ int phy_init_hw(struct phy_device *phyde
if (phydev->drv->soft_reset)
ret = phydev->drv->soft_reset(phydev);
- else
- ret = genphy_soft_reset(phydev);
if (ret < 0)
return ret;

View File

@ -1,375 +0,0 @@
From 80758d9542205cd2e9fa730067bc3888d4f5a096 Mon Sep 17 00:00:00 2001
From: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
Date: Wed, 6 Feb 2019 07:36:40 +0100
Subject: [PATCH 603/660] net: phy: provide full set of accessor functions to
MMD registers
This adds full set of locked and unlocked accessor functions to read and
write PHY MMD registers and/or bitfields.
Set of functions exactly matches what is already available for PHY
legacy registers.
Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/phy-core.c | 116 ++++++++++++++++++++++++++++----
include/linux/phy.h | 134 ++++++++++++++++++++++++++++++-------
2 files changed, 214 insertions(+), 36 deletions(-)
--- a/drivers/net/phy/phy-core.c
+++ b/drivers/net/phy/phy-core.c
@@ -247,15 +247,15 @@ static void mmd_phy_indirect(struct mii_
}
/**
- * phy_read_mmd - Convenience function for reading a register
+ * __phy_read_mmd - Convenience function for reading a register
* from an MMD on a given PHY.
* @phydev: The phy_device struct
* @devad: The MMD to read from (0..31)
* @regnum: The register on the MMD to read (0..65535)
*
- * Same rules as for phy_read();
+ * Same rules as for __phy_read();
*/
-int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
+int __phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
{
int val;
@@ -267,33 +267,52 @@ int phy_read_mmd(struct phy_device *phyd
} else if (phydev->is_c45) {
u32 addr = MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff);
- val = mdiobus_read(phydev->mdio.bus, phydev->mdio.addr, addr);
+ val = __mdiobus_read(phydev->mdio.bus, phydev->mdio.addr, addr);
} else {
struct mii_bus *bus = phydev->mdio.bus;
int phy_addr = phydev->mdio.addr;
- mutex_lock(&bus->mdio_lock);
mmd_phy_indirect(bus, phy_addr, devad, regnum);
/* Read the content of the MMD's selected register */
val = __mdiobus_read(bus, phy_addr, MII_MMD_DATA);
- mutex_unlock(&bus->mdio_lock);
}
return val;
}
+EXPORT_SYMBOL(__phy_read_mmd);
+
+/**
+ * phy_read_mmd - Convenience function for reading a register
+ * from an MMD on a given PHY.
+ * @phydev: The phy_device struct
+ * @devad: The MMD to read from
+ * @regnum: The register on the MMD to read
+ *
+ * Same rules as for phy_read();
+ */
+int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
+{
+ int ret;
+
+ mutex_lock(&phydev->mdio.bus->mdio_lock);
+ ret = __phy_read_mmd(phydev, devad, regnum);
+ mutex_unlock(&phydev->mdio.bus->mdio_lock);
+
+ return ret;
+}
EXPORT_SYMBOL(phy_read_mmd);
/**
- * phy_write_mmd - Convenience function for writing a register
+ * __phy_write_mmd - Convenience function for writing a register
* on an MMD on a given PHY.
* @phydev: The phy_device struct
* @devad: The MMD to read from
* @regnum: The register on the MMD to read
* @val: value to write to @regnum
*
- * Same rules as for phy_write();
+ * Same rules as for __phy_write();
*/
-int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
+int __phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
{
int ret;
@@ -305,23 +324,43 @@ int phy_write_mmd(struct phy_device *phy
} else if (phydev->is_c45) {
u32 addr = MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff);
- ret = mdiobus_write(phydev->mdio.bus, phydev->mdio.addr,
- addr, val);
+ ret = __mdiobus_write(phydev->mdio.bus, phydev->mdio.addr,
+ addr, val);
} else {
struct mii_bus *bus = phydev->mdio.bus;
int phy_addr = phydev->mdio.addr;
- mutex_lock(&bus->mdio_lock);
mmd_phy_indirect(bus, phy_addr, devad, regnum);
/* Write the data into MMD's selected register */
__mdiobus_write(bus, phy_addr, MII_MMD_DATA, val);
- mutex_unlock(&bus->mdio_lock);
ret = 0;
}
return ret;
}
+EXPORT_SYMBOL(__phy_write_mmd);
+
+/**
+ * phy_write_mmd - Convenience function for writing a register
+ * on an MMD on a given PHY.
+ * @phydev: The phy_device struct
+ * @devad: The MMD to read from
+ * @regnum: The register on the MMD to read
+ * @val: value to write to @regnum
+ *
+ * Same rules as for phy_write();
+ */
+int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
+{
+ int ret;
+
+ mutex_lock(&phydev->mdio.bus->mdio_lock);
+ ret = __phy_write_mmd(phydev, devad, regnum, val);
+ mutex_unlock(&phydev->mdio.bus->mdio_lock);
+
+ return ret;
+}
EXPORT_SYMBOL(phy_write_mmd);
/**
@@ -371,6 +410,57 @@ int phy_modify(struct phy_device *phydev
}
EXPORT_SYMBOL_GPL(phy_modify);
+/**
+ * __phy_modify_mmd - Convenience function for modifying a register on MMD
+ * @phydev: the phy_device struct
+ * @devad: the MMD containing register to modify
+ * @regnum: register number to modify
+ * @mask: bit mask of bits to clear
+ * @set: new value of bits set in mask to write to @regnum
+ *
+ * Unlocked helper function which allows a MMD register to be modified as
+ * new register value = (old register value & ~mask) | set
+ */
+int __phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
+ u16 mask, u16 set)
+{
+ int ret;
+
+ ret = __phy_read_mmd(phydev, devad, regnum);
+ if (ret < 0)
+ return ret;
+
+ ret = __phy_write_mmd(phydev, devad, regnum, (ret & ~mask) | set);
+
+ return ret < 0 ? ret : 0;
+}
+EXPORT_SYMBOL_GPL(__phy_modify_mmd);
+
+/**
+ * phy_modify_mmd - Convenience function for modifying a register on MMD
+ * @phydev: the phy_device struct
+ * @devad: the MMD containing register to modify
+ * @regnum: register number to modify
+ * @mask: bit mask of bits to clear
+ * @set: new value of bits set in mask to write to @regnum
+ *
+ * NOTE: MUST NOT be called from interrupt context,
+ * because the bus read/write functions may wait for an interrupt
+ * to conclude the operation.
+ */
+int phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
+ u16 mask, u16 set)
+{
+ int ret;
+
+ mutex_lock(&phydev->mdio.bus->mdio_lock);
+ ret = __phy_modify_mmd(phydev, devad, regnum, mask, set);
+ mutex_unlock(&phydev->mdio.bus->mdio_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(phy_modify_mmd);
+
static int __phy_read_page(struct phy_device *phydev)
{
return phydev->drv->read_page(phydev);
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -695,17 +695,6 @@ size_t phy_speeds(unsigned int *speeds,
void phy_resolve_aneg_linkmode(struct phy_device *phydev);
/**
- * phy_read_mmd - Convenience function for reading a register
- * from an MMD on a given PHY.
- * @phydev: The phy_device struct
- * @devad: The MMD to read from
- * @regnum: The register on the MMD to read
- *
- * Same rules as for phy_read();
- */
-int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum);
-
-/**
* phy_read - Convenience function for reading a given PHY register
* @phydev: the phy_device struct
* @regnum: register number to read
@@ -760,9 +749,60 @@ static inline int __phy_write(struct phy
val);
}
+/**
+ * phy_read_mmd - Convenience function for reading a register
+ * from an MMD on a given PHY.
+ * @phydev: The phy_device struct
+ * @devad: The MMD to read from
+ * @regnum: The register on the MMD to read
+ *
+ * Same rules as for phy_read();
+ */
+int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum);
+
+/**
+ * __phy_read_mmd - Convenience function for reading a register
+ * from an MMD on a given PHY.
+ * @phydev: The phy_device struct
+ * @devad: The MMD to read from
+ * @regnum: The register on the MMD to read
+ *
+ * Same rules as for __phy_read();
+ */
+int __phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum);
+
+/**
+ * phy_write_mmd - Convenience function for writing a register
+ * on an MMD on a given PHY.
+ * @phydev: The phy_device struct
+ * @devad: The MMD to write to
+ * @regnum: The register on the MMD to read
+ * @val: value to write to @regnum
+ *
+ * Same rules as for phy_write();
+ */
+int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val);
+
+/**
+ * __phy_write_mmd - Convenience function for writing a register
+ * on an MMD on a given PHY.
+ * @phydev: The phy_device struct
+ * @devad: The MMD to write to
+ * @regnum: The register on the MMD to read
+ * @val: value to write to @regnum
+ *
+ * Same rules as for __phy_write();
+ */
+int __phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val);
+
int __phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set);
int phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set);
+int __phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
+ u16 mask, u16 set);
+int phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
+ u16 mask, u16 set);
+
/**
* __phy_set_bits - Convenience function for setting bits in a PHY register
* @phydev: the phy_device struct
@@ -813,6 +853,66 @@ static inline int phy_clear_bits(struct
}
/**
+ * __phy_set_bits_mmd - Convenience function for setting bits in a register
+ * on MMD
+ * @phydev: the phy_device struct
+ * @devad: the MMD containing register to modify
+ * @regnum: register number to modify
+ * @val: bits to set
+ *
+ * The caller must have taken the MDIO bus lock.
+ */
+static inline int __phy_set_bits_mmd(struct phy_device *phydev, int devad,
+ u32 regnum, u16 val)
+{
+ return __phy_modify_mmd(phydev, devad, regnum, 0, val);
+}
+
+/**
+ * __phy_clear_bits_mmd - Convenience function for clearing bits in a register
+ * on MMD
+ * @phydev: the phy_device struct
+ * @devad: the MMD containing register to modify
+ * @regnum: register number to modify
+ * @val: bits to clear
+ *
+ * The caller must have taken the MDIO bus lock.
+ */
+static inline int __phy_clear_bits_mmd(struct phy_device *phydev, int devad,
+ u32 regnum, u16 val)
+{
+ return __phy_modify_mmd(phydev, devad, regnum, val, 0);
+}
+
+/**
+ * phy_set_bits_mmd - Convenience function for setting bits in a register
+ * on MMD
+ * @phydev: the phy_device struct
+ * @devad: the MMD containing register to modify
+ * @regnum: register number to modify
+ * @val: bits to set
+ */
+static inline int phy_set_bits_mmd(struct phy_device *phydev, int devad,
+ u32 regnum, u16 val)
+{
+ return phy_modify_mmd(phydev, devad, regnum, 0, val);
+}
+
+/**
+ * phy_clear_bits_mmd - Convenience function for clearing bits in a register
+ * on MMD
+ * @phydev: the phy_device struct
+ * @devad: the MMD containing register to modify
+ * @regnum: register number to modify
+ * @val: bits to clear
+ */
+static inline int phy_clear_bits_mmd(struct phy_device *phydev, int devad,
+ u32 regnum, u16 val)
+{
+ return phy_modify_mmd(phydev, devad, regnum, val, 0);
+}
+
+/**
* phy_interrupt_is_valid - Convenience function for testing a given PHY irq
* @phydev: the phy_device struct
*
@@ -888,18 +988,6 @@ static inline bool phy_is_pseudo_fixed_l
return phydev->is_pseudo_fixed_link;
}
-/**
- * phy_write_mmd - Convenience function for writing a register
- * on an MMD on a given PHY.
- * @phydev: The phy_device struct
- * @devad: The MMD to read from
- * @regnum: The register on the MMD to read
- * @val: value to write to @regnum
- *
- * Same rules as for phy_write();
- */
-int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val);
-
int phy_save_page(struct phy_device *phydev);
int phy_select_page(struct phy_device *phydev, int page);
int phy_restore_page(struct phy_device *phydev, int oldpage, int ret);

View File

@ -1,217 +0,0 @@
From c1e3f753f6b85d7636024159bb78f764e09492f1 Mon Sep 17 00:00:00 2001
From: Heiner Kallweit <hkallweit1@gmail.com>
Date: Sun, 10 Feb 2019 19:57:56 +0100
Subject: [PATCH 604/660] net: phy: add register modifying helpers returning 1
on change
When modifying registers there are scenarios where we need to know
whether the register content actually changed. This patch adds
new helpers to not break users of the current ones, phy_modify() etc.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/phy-core.c | 127 ++++++++++++++++++++++++++++++++++---
include/linux/phy.h | 12 +++-
2 files changed, 128 insertions(+), 11 deletions(-)
--- a/drivers/net/phy/phy-core.c
+++ b/drivers/net/phy/phy-core.c
@@ -364,7 +364,7 @@ int phy_write_mmd(struct phy_device *phy
EXPORT_SYMBOL(phy_write_mmd);
/**
- * __phy_modify() - Convenience function for modifying a PHY register
+ * __phy_modify_changed() - Convenience function for modifying a PHY register
* @phydev: a pointer to a &struct phy_device
* @regnum: register number
* @mask: bit mask of bits to clear
@@ -372,16 +372,69 @@ EXPORT_SYMBOL(phy_write_mmd);
*
* Unlocked helper function which allows a PHY register to be modified as
* new register value = (old register value & ~mask) | set
+ *
+ * Returns negative errno, 0 if there was no change, and 1 in case of change
*/
-int __phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)
+int __phy_modify_changed(struct phy_device *phydev, u32 regnum, u16 mask,
+ u16 set)
{
- int ret;
+ int new, ret;
ret = __phy_read(phydev, regnum);
if (ret < 0)
return ret;
- ret = __phy_write(phydev, regnum, (ret & ~mask) | set);
+ new = (ret & ~mask) | set;
+ if (new == ret)
+ return 0;
+
+ ret = __phy_write(phydev, regnum, new);
+
+ return ret < 0 ? ret : 1;
+}
+EXPORT_SYMBOL_GPL(__phy_modify_changed);
+
+/**
+ * phy_modify_changed - Function for modifying a PHY register
+ * @phydev: the phy_device struct
+ * @regnum: register number to modify
+ * @mask: bit mask of bits to clear
+ * @set: new value of bits set in mask to write to @regnum
+ *
+ * NOTE: MUST NOT be called from interrupt context,
+ * because the bus read/write functions may wait for an interrupt
+ * to conclude the operation.
+ *
+ * Returns negative errno, 0 if there was no change, and 1 in case of change
+ */
+int phy_modify_changed(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)
+{
+ int ret;
+
+ mutex_lock(&phydev->mdio.bus->mdio_lock);
+ ret = __phy_modify_changed(phydev, regnum, mask, set);
+ mutex_unlock(&phydev->mdio.bus->mdio_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(phy_modify_changed);
+
+/**
+ * __phy_modify - Convenience function for modifying a PHY register
+ * @phydev: the phy_device struct
+ * @regnum: register number to modify
+ * @mask: bit mask of bits to clear
+ * @set: new value of bits set in mask to write to @regnum
+ *
+ * NOTE: MUST NOT be called from interrupt context,
+ * because the bus read/write functions may wait for an interrupt
+ * to conclude the operation.
+ */
+int __phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)
+{
+ int ret;
+
+ ret = __phy_modify_changed(phydev, regnum, mask, set);
return ret < 0 ? ret : 0;
}
@@ -411,7 +464,7 @@ int phy_modify(struct phy_device *phydev
EXPORT_SYMBOL_GPL(phy_modify);
/**
- * __phy_modify_mmd - Convenience function for modifying a register on MMD
+ * __phy_modify_mmd_changed - Function for modifying a register on MMD
* @phydev: the phy_device struct
* @devad: the MMD containing register to modify
* @regnum: register number to modify
@@ -420,17 +473,73 @@ EXPORT_SYMBOL_GPL(phy_modify);
*
* Unlocked helper function which allows a MMD register to be modified as
* new register value = (old register value & ~mask) | set
+ *
+ * Returns negative errno, 0 if there was no change, and 1 in case of change
*/
-int __phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
- u16 mask, u16 set)
+int __phy_modify_mmd_changed(struct phy_device *phydev, int devad, u32 regnum,
+ u16 mask, u16 set)
{
- int ret;
+ int new, ret;
ret = __phy_read_mmd(phydev, devad, regnum);
if (ret < 0)
return ret;
- ret = __phy_write_mmd(phydev, devad, regnum, (ret & ~mask) | set);
+ new = (ret & ~mask) | set;
+ if (new == ret)
+ return 0;
+
+ ret = __phy_write_mmd(phydev, devad, regnum, new);
+
+ return ret < 0 ? ret : 1;
+}
+EXPORT_SYMBOL_GPL(__phy_modify_mmd_changed);
+
+/**
+ * phy_modify_mmd_changed - Function for modifying a register on MMD
+ * @phydev: the phy_device struct
+ * @devad: the MMD containing register to modify
+ * @regnum: register number to modify
+ * @mask: bit mask of bits to clear
+ * @set: new value of bits set in mask to write to @regnum
+ *
+ * NOTE: MUST NOT be called from interrupt context,
+ * because the bus read/write functions may wait for an interrupt
+ * to conclude the operation.
+ *
+ * Returns negative errno, 0 if there was no change, and 1 in case of change
+ */
+int phy_modify_mmd_changed(struct phy_device *phydev, int devad, u32 regnum,
+ u16 mask, u16 set)
+{
+ int ret;
+
+ mutex_lock(&phydev->mdio.bus->mdio_lock);
+ ret = __phy_modify_mmd_changed(phydev, devad, regnum, mask, set);
+ mutex_unlock(&phydev->mdio.bus->mdio_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(phy_modify_mmd_changed);
+
+/**
+ * __phy_modify_mmd - Convenience function for modifying a register on MMD
+ * @phydev: the phy_device struct
+ * @devad: the MMD containing register to modify
+ * @regnum: register number to modify
+ * @mask: bit mask of bits to clear
+ * @set: new value of bits set in mask to write to @regnum
+ *
+ * NOTE: MUST NOT be called from interrupt context,
+ * because the bus read/write functions may wait for an interrupt
+ * to conclude the operation.
+ */
+int __phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
+ u16 mask, u16 set)
+{
+ int ret;
+
+ ret = __phy_modify_mmd_changed(phydev, devad, regnum, mask, set);
return ret < 0 ? ret : 0;
}
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -795,13 +795,21 @@ int phy_write_mmd(struct phy_device *phy
*/
int __phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val);
+int __phy_modify_changed(struct phy_device *phydev, u32 regnum, u16 mask,
+ u16 set);
+int phy_modify_changed(struct phy_device *phydev, u32 regnum, u16 mask,
+ u16 set);
int __phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set);
int phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set);
+int __phy_modify_mmd_changed(struct phy_device *phydev, int devad, u32 regnum,
+ u16 mask, u16 set);
+int phy_modify_mmd_changed(struct phy_device *phydev, int devad, u32 regnum,
+ u16 mask, u16 set);
int __phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
- u16 mask, u16 set);
+ u16 mask, u16 set);
int phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
- u16 mask, u16 set);
+ u16 mask, u16 set);
/**
* __phy_set_bits - Convenience function for setting bits in a PHY register

View File

@ -1,64 +0,0 @@
From 2c3db705737cf52d7d24c993f0889b25b956c718 Mon Sep 17 00:00:00 2001
From: Heiner Kallweit <hkallweit1@gmail.com>
Date: Mon, 18 Feb 2019 21:27:18 +0100
Subject: [PATCH 605/660] net: phy: add genphy_c45_check_and_restart_aneg
This function will be used by config_aneg callback implementations of
PHY drivers and allows to reduce boilerplate code.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/phy/phy-c45.c | 30 ++++++++++++++++++++++++++++++
include/linux/phy.h | 1 +
2 files changed, 31 insertions(+)
--- a/drivers/net/phy/phy-c45.c
+++ b/drivers/net/phy/phy-c45.c
@@ -110,6 +110,36 @@ int genphy_c45_restart_aneg(struct phy_d
EXPORT_SYMBOL_GPL(genphy_c45_restart_aneg);
/**
+ * genphy_c45_check_and_restart_aneg - Enable and restart auto-negotiation
+ * @phydev: target phy_device struct
+ * @restart: whether aneg restart is requested
+ *
+ * This assumes that the auto-negotiation MMD is present.
+ *
+ * Check, and restart auto-negotiation if needed.
+ */
+int genphy_c45_check_and_restart_aneg(struct phy_device *phydev, bool restart)
+{
+ int ret = 0;
+
+ if (!restart) {
+ /* Configure and restart aneg if it wasn't set before */
+ ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1);
+ if (ret < 0)
+ return ret;
+
+ if (!(ret & MDIO_AN_CTRL1_ENABLE))
+ restart = true;
+ }
+
+ if (restart)
+ ret = genphy_c45_restart_aneg(phydev);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(genphy_c45_check_and_restart_aneg);
+
+/**
* genphy_c45_aneg_done - return auto-negotiation complete status
* @phydev: target phy_device struct
*
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -1098,6 +1098,7 @@ int genphy_write_mmd_unsupported(struct
/* Clause 45 PHY */
int genphy_c45_restart_aneg(struct phy_device *phydev);
+int genphy_c45_check_and_restart_aneg(struct phy_device *phydev, bool restart);
int genphy_c45_aneg_done(struct phy_device *phydev);
int genphy_c45_read_link(struct phy_device *phydev, u32 mmd_mask);
int genphy_c45_read_lpa(struct phy_device *phydev);

View File

@ -1,59 +0,0 @@
From 4c4323084e9a67210c8d269dceba1be99356c414 Mon Sep 17 00:00:00 2001
From: Russell King <rmk+kernel@armlinux.org.uk>
Date: Tue, 28 May 2019 10:57:18 +0100
Subject: [PATCH 606/660] net: phylink: remove netdev from phylink mii ioctl
emulation
The netdev used in the phylink ioctl emulation is never used, so let's
remove it.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/phylink.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -1360,8 +1360,8 @@ EXPORT_SYMBOL_GPL(phylink_ethtool_set_ee
*
* FIXME: should deal with negotiation state too.
*/
-static int phylink_mii_emul_read(struct net_device *ndev, unsigned int reg,
- struct phylink_link_state *state, bool aneg)
+static int phylink_mii_emul_read(unsigned int reg,
+ struct phylink_link_state *state)
{
struct fixed_phy_status fs;
int val;
@@ -1376,8 +1376,6 @@ static int phylink_mii_emul_read(struct
if (reg == MII_BMSR) {
if (!state->an_complete)
val &= ~BMSR_ANEGCOMPLETE;
- if (!aneg)
- val &= ~BMSR_ANEGCAPABLE;
}
return val;
}
@@ -1473,8 +1471,7 @@ static int phylink_mii_read(struct phyli
case MLO_AN_FIXED:
if (phy_id == 0) {
phylink_get_fixed_state(pl, &state);
- val = phylink_mii_emul_read(pl->netdev, reg, &state,
- true);
+ val = phylink_mii_emul_read(reg, &state);
}
break;
@@ -1487,8 +1484,7 @@ static int phylink_mii_read(struct phyli
if (val < 0)
return val;
- val = phylink_mii_emul_read(pl->netdev, reg, &state,
- true);
+ val = phylink_mii_emul_read(reg, &state);
}
break;
}

View File

@ -1,90 +0,0 @@
From cba0aba37d2228556e0d1f776d403435868cdbfa Mon Sep 17 00:00:00 2001
From: Russell King <rmk+kernel@armlinux.org.uk>
Date: Tue, 28 May 2019 10:57:23 +0100
Subject: [PATCH 607/660] net: phylink: support for link gpio interrupt
Add support for using GPIO interrupts with a fixed-link GPIO rather than
polling the GPIO every second and invoking the phylink resolution. This
avoids unnecessary calls to mac_config().
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/phylink.c | 36 ++++++++++++++++++++++++++++++++----
1 file changed, 32 insertions(+), 4 deletions(-)
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -59,6 +59,7 @@ struct phylink {
phy_interface_t cur_interface;
struct gpio_desc *link_gpio;
+ unsigned int link_irq;
struct timer_list link_poll;
void (*get_fixed_state)(struct net_device *dev,
struct phylink_link_state *s);
@@ -645,7 +646,7 @@ void phylink_destroy(struct phylink *pl)
{
if (pl->sfp_bus)
sfp_unregister_upstream(pl->sfp_bus);
- if (!IS_ERR_OR_NULL(pl->link_gpio))
+ if (pl->link_gpio)
gpiod_put(pl->link_gpio);
cancel_work_sync(&pl->resolve);
@@ -912,6 +913,15 @@ void phylink_mac_change(struct phylink *
}
EXPORT_SYMBOL_GPL(phylink_mac_change);
+static irqreturn_t phylink_link_handler(int irq, void *data)
+{
+ struct phylink *pl = data;
+
+ phylink_run_resolve(pl);
+
+ return IRQ_HANDLED;
+}
+
/**
* phylink_start() - start a phylink instance
* @pl: a pointer to a &struct phylink returned from phylink_create()
@@ -947,7 +957,22 @@ void phylink_start(struct phylink *pl)
clear_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state);
phylink_run_resolve(pl);
- if (pl->link_an_mode == MLO_AN_FIXED && !IS_ERR(pl->link_gpio))
+ if (pl->link_an_mode == MLO_AN_FIXED && pl->link_gpio) {
+ int irq = gpiod_to_irq(pl->link_gpio);
+
+ if (irq > 0) {
+ if (!request_irq(irq, phylink_link_handler,
+ IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING,
+ "netdev link", pl))
+ pl->link_irq = irq;
+ else
+ irq = 0;
+ }
+ if (irq <= 0)
+ mod_timer(&pl->link_poll, jiffies + HZ);
+ }
+ if (pl->link_an_mode == MLO_AN_FIXED && pl->get_fixed_state)
mod_timer(&pl->link_poll, jiffies + HZ);
if (pl->sfp_bus)
sfp_upstream_start(pl->sfp_bus);
@@ -973,8 +998,11 @@ void phylink_stop(struct phylink *pl)
phy_stop(pl->phydev);
if (pl->sfp_bus)
sfp_upstream_stop(pl->sfp_bus);
- if (pl->link_an_mode == MLO_AN_FIXED && !IS_ERR(pl->link_gpio))
- del_timer_sync(&pl->link_poll);
+ del_timer_sync(&pl->link_poll);
+ if (pl->link_irq) {
+ free_irq(pl->link_irq, pl);
+ pl->link_irq = 0;
+ }
phylink_run_resolve_and_disable(pl, PHYLINK_DISABLE_STOPPED);
}

View File

@ -1,77 +0,0 @@
From eb5df3d026824832831376bbdf04e01a52776eea Mon Sep 17 00:00:00 2001
From: Russell King <rmk+kernel@armlinux.org.uk>
Date: Tue, 28 May 2019 10:57:29 +0100
Subject: [PATCH 608/660] net: phy: allow Clause 45 access via mii ioctl
Allow userspace to generate Clause 45 MII access cycles via phylib.
This is useful for tools such as mii-diag to be able to inspect Clause
45 PHYs.
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/phy.c | 33 ++++++++++++++++++++++++---------
1 file changed, 24 insertions(+), 9 deletions(-)
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -397,6 +397,7 @@ int phy_mii_ioctl(struct phy_device *phy
struct mii_ioctl_data *mii_data = if_mii(ifr);
u16 val = mii_data->val_in;
bool change_autoneg = false;
+ int prtad, devad;
switch (cmd) {
case SIOCGMIIPHY:
@@ -404,14 +405,29 @@ int phy_mii_ioctl(struct phy_device *phy
/* fall through */
case SIOCGMIIREG:
- mii_data->val_out = mdiobus_read(phydev->mdio.bus,
- mii_data->phy_id,
- mii_data->reg_num);
+ if (mdio_phy_id_is_c45(mii_data->phy_id)) {
+ prtad = mdio_phy_id_prtad(mii_data->phy_id);
+ devad = mdio_phy_id_devad(mii_data->phy_id);
+ devad = MII_ADDR_C45 | devad << 16 | mii_data->reg_num;
+ } else {
+ prtad = mii_data->phy_id;
+ devad = mii_data->reg_num;
+ }
+ mii_data->val_out = mdiobus_read(phydev->mdio.bus, prtad,
+ devad);
return 0;
case SIOCSMIIREG:
- if (mii_data->phy_id == phydev->mdio.addr) {
- switch (mii_data->reg_num) {
+ if (mdio_phy_id_is_c45(mii_data->phy_id)) {
+ prtad = mdio_phy_id_prtad(mii_data->phy_id);
+ devad = mdio_phy_id_devad(mii_data->phy_id);
+ devad = MII_ADDR_C45 | devad << 16 | mii_data->reg_num;
+ } else {
+ prtad = mii_data->phy_id;
+ devad = mii_data->reg_num;
+ }
+ if (prtad == phydev->mdio.addr) {
+ switch (devad) {
case MII_BMCR:
if ((val & (BMCR_RESET | BMCR_ANENABLE)) == 0) {
if (phydev->autoneg == AUTONEG_ENABLE)
@@ -443,11 +459,10 @@ int phy_mii_ioctl(struct phy_device *phy
}
}
- mdiobus_write(phydev->mdio.bus, mii_data->phy_id,
- mii_data->reg_num, val);
+ mdiobus_write(phydev->mdio.bus, prtad, devad, val);
- if (mii_data->phy_id == phydev->mdio.addr &&
- mii_data->reg_num == MII_BMCR &&
+ if (prtad == phydev->mdio.addr &&
+ devad == MII_BMCR &&
val & BMCR_RESET)
return phy_init_hw(phydev);

View File

@ -1,94 +0,0 @@
From aeabfaa63285470e81fa341e14f92d68880aa160 Mon Sep 17 00:00:00 2001
From: Russell King <rmk+kernel@armlinux.org.uk>
Date: Tue, 28 May 2019 10:57:34 +0100
Subject: [PATCH 609/660] net: sfp: add mandatory attach/detach methods for sfp
buses
Add attach and detach methods for SFP buses, which will allow us to get
rid of the netdev storage in sfp-bus.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/phylink.c | 16 ++++++++++++++++
drivers/net/phy/sfp-bus.c | 4 ++--
include/linux/sfp.h | 6 ++++++
3 files changed, 24 insertions(+), 2 deletions(-)
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -1615,6 +1615,20 @@ int phylink_mii_ioctl(struct phylink *pl
}
EXPORT_SYMBOL_GPL(phylink_mii_ioctl);
+static void phylink_sfp_attach(void *upstream, struct sfp_bus *bus)
+{
+ struct phylink *pl = upstream;
+
+ pl->netdev->sfp_bus = bus;
+}
+
+static void phylink_sfp_detach(void *upstream, struct sfp_bus *bus)
+{
+ struct phylink *pl = upstream;
+
+ pl->netdev->sfp_bus = NULL;
+}
+
static int phylink_sfp_module_insert(void *upstream,
const struct sfp_eeprom_id *id)
{
@@ -1733,6 +1747,8 @@ static void phylink_sfp_disconnect_phy(v
}
static const struct sfp_upstream_ops sfp_phylink_ops = {
+ .attach = phylink_sfp_attach,
+ .detach = phylink_sfp_detach,
.module_insert = phylink_sfp_module_insert,
.link_up = phylink_sfp_link_up,
.link_down = phylink_sfp_link_down,
--- a/drivers/net/phy/sfp-bus.c
+++ b/drivers/net/phy/sfp-bus.c
@@ -350,7 +350,7 @@ static int sfp_register_bus(struct sfp_b
bus->socket_ops->attach(bus->sfp);
if (bus->started)
bus->socket_ops->start(bus->sfp);
- bus->netdev->sfp_bus = bus;
+ bus->upstream_ops->attach(bus->upstream, bus);
bus->registered = true;
return 0;
}
@@ -359,8 +359,8 @@ static void sfp_unregister_bus(struct sf
{
const struct sfp_upstream_ops *ops = bus->upstream_ops;
- bus->netdev->sfp_bus = NULL;
if (bus->registered) {
+ bus->upstream_ops->detach(bus->upstream, bus);
if (bus->started)
bus->socket_ops->stop(bus->sfp);
bus->socket_ops->detach(bus->sfp);
--- a/include/linux/sfp.h
+++ b/include/linux/sfp.h
@@ -469,6 +469,10 @@ struct sfp_bus;
/**
* struct sfp_upstream_ops - upstream operations structure
+ * @attach: called when the sfp socket driver is bound to the upstream
+ * (mandatory).
+ * @detach: called when the sfp socket driver is unbound from the upstream
+ * (mandatory).
* @module_insert: called after a module has been detected to determine
* whether the module is supported for the upstream device.
* @module_remove: called after the module has been removed.
@@ -481,6 +485,8 @@ struct sfp_bus;
* been removed.
*/
struct sfp_upstream_ops {
+ void (*attach)(void *priv, struct sfp_bus *bus);
+ void (*detach)(void *priv, struct sfp_bus *bus);
int (*module_insert)(void *priv, const struct sfp_eeprom_id *id);
void (*module_remove)(void *priv);
void (*link_down)(void *priv);

View File

@ -1,118 +0,0 @@
From 60d756717d772be90d07a07cd2cc140c76da3e4a Mon Sep 17 00:00:00 2001
From: Russell King <rmk+kernel@armlinux.org.uk>
Date: Tue, 28 May 2019 10:57:39 +0100
Subject: [PATCH 610/660] net: sfp: remove sfp-bus use of netdevs
The sfp-bus code now no longer has any use for the network device
structure, so remove its use.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/phylink.c | 3 +--
drivers/net/phy/sfp-bus.c | 10 +++-------
include/linux/sfp.h | 6 ++----
3 files changed, 6 insertions(+), 13 deletions(-)
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -555,8 +555,7 @@ static int phylink_register_sfp(struct p
return ret;
}
- pl->sfp_bus = sfp_register_upstream(ref.fwnode, pl->netdev, pl,
- &sfp_phylink_ops);
+ pl->sfp_bus = sfp_register_upstream(ref.fwnode, pl, &sfp_phylink_ops);
if (!pl->sfp_bus)
return -ENOMEM;
--- a/drivers/net/phy/sfp-bus.c
+++ b/drivers/net/phy/sfp-bus.c
@@ -23,7 +23,6 @@ struct sfp_bus {
const struct sfp_upstream_ops *upstream_ops;
void *upstream;
- struct net_device *netdev;
struct phy_device *phydev;
bool registered;
@@ -442,13 +441,11 @@ static void sfp_upstream_clear(struct sf
{
bus->upstream_ops = NULL;
bus->upstream = NULL;
- bus->netdev = NULL;
}
/**
* sfp_register_upstream() - Register the neighbouring device
* @fwnode: firmware node for the SFP bus
- * @ndev: network device associated with the interface
* @upstream: the upstream private data
* @ops: the upstream's &struct sfp_upstream_ops
*
@@ -459,7 +456,7 @@ static void sfp_upstream_clear(struct sf
* On error, returns %NULL.
*/
struct sfp_bus *sfp_register_upstream(struct fwnode_handle *fwnode,
- struct net_device *ndev, void *upstream,
+ void *upstream,
const struct sfp_upstream_ops *ops)
{
struct sfp_bus *bus = sfp_bus_get(fwnode);
@@ -469,7 +466,6 @@ struct sfp_bus *sfp_register_upstream(st
rtnl_lock();
bus->upstream_ops = ops;
bus->upstream = upstream;
- bus->netdev = ndev;
if (bus->sfp) {
ret = sfp_register_bus(bus);
@@ -591,7 +587,7 @@ struct sfp_bus *sfp_register_socket(stru
bus->sfp = sfp;
bus->socket_ops = ops;
- if (bus->netdev) {
+ if (bus->upstream_ops) {
ret = sfp_register_bus(bus);
if (ret)
sfp_socket_clear(bus);
@@ -611,7 +607,7 @@ EXPORT_SYMBOL_GPL(sfp_register_socket);
void sfp_unregister_socket(struct sfp_bus *bus)
{
rtnl_lock();
- if (bus->netdev)
+ if (bus->upstream_ops)
sfp_unregister_bus(bus);
sfp_socket_clear(bus);
rtnl_unlock();
--- a/include/linux/sfp.h
+++ b/include/linux/sfp.h
@@ -464,7 +464,6 @@ enum {
struct fwnode_handle;
struct ethtool_eeprom;
struct ethtool_modinfo;
-struct net_device;
struct sfp_bus;
/**
@@ -510,7 +509,7 @@ int sfp_get_module_eeprom(struct sfp_bus
void sfp_upstream_start(struct sfp_bus *bus);
void sfp_upstream_stop(struct sfp_bus *bus);
struct sfp_bus *sfp_register_upstream(struct fwnode_handle *fwnode,
- struct net_device *ndev, void *upstream,
+ void *upstream,
const struct sfp_upstream_ops *ops);
void sfp_unregister_upstream(struct sfp_bus *bus);
#else
@@ -555,8 +554,7 @@ static inline void sfp_upstream_stop(str
}
static inline struct sfp_bus *sfp_register_upstream(
- struct fwnode_handle *fwnode,
- struct net_device *ndev, void *upstream,
+ struct fwnode_handle *fwnode, void *upstream,
const struct sfp_upstream_ops *ops)
{
return (struct sfp_bus *)-1;

View File

@ -1,84 +0,0 @@
From 8ac1d3e5cf7d277769ba3403d99f643fab1e3fae Mon Sep 17 00:00:00 2001
From: Russell King <rmk+kernel@armlinux.org.uk>
Date: Sat, 23 Nov 2019 14:19:54 +0000
Subject: [PATCH 611/660] net: phylink: avoid reducing support mask
Avoid reducing the support mask as a result of the interface type
selected for SFP modules, or when setting the link settings through
ethtool - this should only change when the supported link modes of
the hardware combination change.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/phy/phylink.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -1137,6 +1137,7 @@ EXPORT_SYMBOL_GPL(phylink_ethtool_ksetti
int phylink_ethtool_ksettings_set(struct phylink *pl,
const struct ethtool_link_ksettings *kset)
{
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(support);
struct ethtool_link_ksettings our_kset;
struct phylink_link_state config;
int ret;
@@ -1147,11 +1148,12 @@ int phylink_ethtool_ksettings_set(struct
kset->base.autoneg != AUTONEG_ENABLE)
return -EINVAL;
+ linkmode_copy(support, pl->supported);
config = pl->link_config;
/* Mask out unsupported advertisements */
linkmode_and(config.advertising, kset->link_modes.advertising,
- pl->supported);
+ support);
/* FIXME: should we reject autoneg if phy/mac does not support it? */
if (kset->base.autoneg == AUTONEG_DISABLE) {
@@ -1161,7 +1163,7 @@ int phylink_ethtool_ksettings_set(struct
* duplex.
*/
s = phy_lookup_setting(kset->base.speed, kset->base.duplex,
- pl->supported,
+ support,
__ETHTOOL_LINK_MODE_MASK_NBITS, false);
if (!s)
return -EINVAL;
@@ -1191,7 +1193,7 @@ int phylink_ethtool_ksettings_set(struct
__set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, config.advertising);
}
- if (phylink_validate(pl, pl->supported, &config))
+ if (phylink_validate(pl, support, &config))
return -EINVAL;
/* If autonegotiation is enabled, we must have an advertisement */
@@ -1633,6 +1635,7 @@ static int phylink_sfp_module_insert(voi
{
struct phylink *pl = upstream;
__ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, };
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(support1);
struct phylink_link_state config;
phy_interface_t iface;
int ret = 0;
@@ -1660,6 +1663,8 @@ static int phylink_sfp_module_insert(voi
return ret;
}
+ linkmode_copy(support1, support);
+
iface = sfp_select_interface(pl->sfp_bus, id, config.advertising);
if (iface == PHY_INTERFACE_MODE_NA) {
netdev_err(pl->netdev,
@@ -1669,7 +1674,7 @@ static int phylink_sfp_module_insert(voi
}
config.interface = iface;
- ret = phylink_validate(pl, support, &config);
+ ret = phylink_validate(pl, support1, &config);
if (ret) {
netdev_err(pl->netdev, "validation of %s/%s with support %*pb failed: %d\n",
phylink_an_mode_str(MLO_AN_INBAND),

View File

@ -1,94 +0,0 @@
From 254236a22109efa84c9e9f5a9c76a1719439e309 Mon Sep 17 00:00:00 2001
From: Robert Hancock <hancock@sedsystems.ca>
Date: Fri, 7 Jun 2019 10:42:35 -0600
Subject: [PATCH 612/660] net: sfp: Stop SFP polling and interrupt handling
during shutdown
SFP device polling can cause problems during the shutdown process if the
parent devices of the network controller have been shut down already.
This problem was seen on the iMX6 platform with PCIe devices, where
accessing the device after the bus is shut down causes a hang.
Free any acquired GPIO interrupts and stop all delayed work in the SFP
driver during the shutdown process, so that we ensure that no pending
operations are still occurring after the SFP shutdown completes.
Signed-off-by: Robert Hancock <hancock@sedsystems.ca>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/phy/sfp.c | 31 ++++++++++++++++++++++++++-----
1 file changed, 26 insertions(+), 5 deletions(-)
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -183,6 +183,7 @@ struct sfp {
int (*write)(struct sfp *, bool, u8, void *, size_t);
struct gpio_desc *gpio[GPIO_MAX];
+ int gpio_irq[GPIO_MAX];
bool attached;
struct mutex st_mutex; /* Protects state */
@@ -1803,7 +1804,7 @@ static int sfp_probe(struct platform_dev
const struct sff_data *sff;
struct sfp *sfp;
bool poll = false;
- int irq, err, i;
+ int err, i;
sfp = sfp_alloc(&pdev->dev);
if (IS_ERR(sfp))
@@ -1885,19 +1886,22 @@ static int sfp_probe(struct platform_dev
if (gpio_flags[i] != GPIOD_IN || !sfp->gpio[i])
continue;
- irq = gpiod_to_irq(sfp->gpio[i]);
- if (!irq) {
+ sfp->gpio_irq[i] = gpiod_to_irq(sfp->gpio[i]);
+ if (!sfp->gpio_irq[i]) {
poll = true;
continue;
}
- err = devm_request_threaded_irq(sfp->dev, irq, NULL, sfp_irq,
+ err = devm_request_threaded_irq(sfp->dev, sfp->gpio_irq[i],
+ NULL, sfp_irq,
IRQF_ONESHOT |
IRQF_TRIGGER_RISING |
IRQF_TRIGGER_FALLING,
dev_name(sfp->dev), sfp);
- if (err)
+ if (err) {
+ sfp->gpio_irq[i] = 0;
poll = true;
+ }
}
if (poll)
@@ -1928,9 +1932,26 @@ static int sfp_remove(struct platform_de
return 0;
}
+static void sfp_shutdown(struct platform_device *pdev)
+{
+ struct sfp *sfp = platform_get_drvdata(pdev);
+ int i;
+
+ for (i = 0; i < GPIO_MAX; i++) {
+ if (!sfp->gpio_irq[i])
+ continue;
+
+ devm_free_irq(sfp->dev, sfp->gpio_irq[i], sfp);
+ }
+
+ cancel_delayed_work_sync(&sfp->poll);
+ cancel_delayed_work_sync(&sfp->timeout);
+}
+
static struct platform_driver sfp_driver = {
.probe = sfp_probe,
.remove = sfp_remove,
+ .shutdown = sfp_shutdown,
.driver = {
.name = "sfp",
.of_match_table = sfp_of_match,

View File

@ -1,141 +0,0 @@
From b8803113537a1c1f457eba6270d46e3af305031f Mon Sep 17 00:00:00 2001
From: Arseny Solokha <asolokha@kb.kras.ru>
Date: Wed, 24 Jul 2019 20:31:39 +0700
Subject: [PATCH 613/660] net: phylink: don't start and stop SGMII PHYs in SFP
modules twice
SFP modules connected using the SGMII interface have their own PHYs which
are handled by the struct phylink's phydev field. On the other hand, for
the modules connected using 1000Base-X interface that field is not set.
Since commit ce0aa27ff3f6 ("sfp: add sfp-bus to bridge between network
devices and sfp cages") phylink_start() ends up setting the phydev field
using the sfp-bus infrastructure, which eventually calls phy_start() on it,
and then calling phy_start() again on the same phydev from phylink_start()
itself. Similar call sequence holds for phylink_stop(), only in the reverse
order. This results in WARNs during network interface bringup and shutdown
when a copper SFP module is connected, as phy_start() and phy_stop() are
called twice in a row for the same phy_device:
% ip link set up dev eth0
------------[ cut here ]------------
called from state UP
WARNING: CPU: 1 PID: 155 at drivers/net/phy/phy.c:895 phy_start+0x74/0xc0
Modules linked in:
CPU: 1 PID: 155 Comm: backend Not tainted 5.2.0+ #1
NIP: c0227bf0 LR: c0227bf0 CTR: c004d224
REGS: df547720 TRAP: 0700 Not tainted (5.2.0+)
MSR: 00029000 <CE,EE,ME> CR: 24002822 XER: 00000000
GPR00: c0227bf0 df5477d8 df5d7080 00000014 df9d2370 df9d5ac4 1f4eb000 00000001
GPR08: c061fe58 00000000 00000000 df5477d8 0000003c 100c8768 00000000 00000000
GPR16: df486a00 c046f1c8 c046eea0 00000000 c046e904 c0239604 db68449c 00000000
GPR24: e9083204 00000000 00000001 db684460 e9083404 00000000 db6dce00 db6dcc00
NIP [c0227bf0] phy_start+0x74/0xc0
LR [c0227bf0] phy_start+0x74/0xc0
Call Trace:
[df5477d8] [c0227bf0] phy_start+0x74/0xc0 (unreliable)
[df5477e8] [c023cad0] startup_gfar+0x398/0x3f4
[df547828] [c023cf08] gfar_enet_open+0x364/0x374
[df547898] [c029d870] __dev_open+0xe4/0x140
[df5478c8] [c029db70] __dev_change_flags+0xf0/0x188
[df5478f8] [c029dc28] dev_change_flags+0x20/0x54
[df547918] [c02ae304] do_setlink+0x310/0x818
[df547a08] [c02b1eb8] __rtnl_newlink+0x384/0x6b0
[df547c28] [c02b222c] rtnl_newlink+0x48/0x68
[df547c48] [c02ad7c8] rtnetlink_rcv_msg+0x240/0x27c
[df547c98] [c02cc068] netlink_rcv_skb+0x8c/0xf0
[df547cd8] [c02cba3c] netlink_unicast+0x114/0x19c
[df547d08] [c02cbd74] netlink_sendmsg+0x2b0/0x2c0
[df547d58] [c027b668] sock_sendmsg_nosec+0x20/0x40
[df547d68] [c027d080] ___sys_sendmsg+0x17c/0x1dc
[df547e98] [c027df7c] __sys_sendmsg+0x68/0x84
[df547ef8] [c027e430] sys_socketcall+0x1a0/0x204
[df547f38] [c000d1d8] ret_from_syscall+0x0/0x38
--- interrupt: c01 at 0xfd4e030
LR = 0xfd4e010
Instruction dump:
813f0188 38800000 2b890005 419d0014 3d40c046 5529103a 394aa208 7c8a482e
3c60c046 3863a1b8 4cc63182 4be009a1 <0fe00000> 48000030 3c60c046 3863a1d0
---[ end trace d4c095aeaf6ea998 ]---
and
% ip link set down dev eth0
------------[ cut here ]------------
called from state HALTED
WARNING: CPU: 1 PID: 184 at drivers/net/phy/phy.c:858 phy_stop+0x3c/0x88
<...>
Call Trace:
[df581788] [c0228450] phy_stop+0x3c/0x88 (unreliable)
[df581798] [c022d548] sfp_sm_phy_detach+0x1c/0x44
[df5817a8] [c022e8cc] sfp_sm_event+0x4b0/0x87c
[df581848] [c022f04c] sfp_upstream_stop+0x34/0x44
[df581858] [c0225608] phylink_stop+0x7c/0xe4
[df581868] [c023c57c] stop_gfar+0x7c/0x94
[df581888] [c023c5b8] gfar_close+0x24/0x94
[df5818a8] [c0298688] __dev_close_many+0xdc/0xf8
[df5818c8] [c029db58] __dev_change_flags+0xd8/0x188
[df5818f8] [c029dc28] dev_change_flags+0x20/0x54
[df581918] [c02ae304] do_setlink+0x310/0x818
[df581a08] [c02b1eb8] __rtnl_newlink+0x384/0x6b0
[df581c28] [c02b222c] rtnl_newlink+0x48/0x68
[df581c48] [c02ad7c8] rtnetlink_rcv_msg+0x240/0x27c
[df581c98] [c02cc068] netlink_rcv_skb+0x8c/0xf0
[df581cd8] [c02cba3c] netlink_unicast+0x114/0x19c
[df581d08] [c02cbd74] netlink_sendmsg+0x2b0/0x2c0
[df581d58] [c027b668] sock_sendmsg_nosec+0x20/0x40
[df581d68] [c027d080] ___sys_sendmsg+0x17c/0x1dc
[df581e98] [c027df7c] __sys_sendmsg+0x68/0x84
[df581ef8] [c027e430] sys_socketcall+0x1a0/0x204
[df581f38] [c000d1d8] ret_from_syscall+0x0/0x38
<...>
---[ end trace d4c095aeaf6ea999 ]---
SFP modules with the 1000Base-X interface are not affected.
Place explicit calls to phy_start() and phy_stop() before enabling or after
disabling an attached SFP module, where phydev is not yet set (or is
already unset), so they will be made only from the inside of sfp-bus, if
needed.
Fixes: 217962615662 ("net: phy: warn if phy_start is called from invalid state")
Signed-off-by: Arseny Solokha <asolokha@kb.kras.ru>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/phy/phylink.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -973,10 +973,10 @@ void phylink_start(struct phylink *pl)
}
if (pl->link_an_mode == MLO_AN_FIXED && pl->get_fixed_state)
mod_timer(&pl->link_poll, jiffies + HZ);
- if (pl->sfp_bus)
- sfp_upstream_start(pl->sfp_bus);
if (pl->phydev)
phy_start(pl->phydev);
+ if (pl->sfp_bus)
+ sfp_upstream_start(pl->sfp_bus);
}
EXPORT_SYMBOL_GPL(phylink_start);
@@ -993,10 +993,10 @@ void phylink_stop(struct phylink *pl)
{
ASSERT_RTNL();
- if (pl->phydev)
- phy_stop(pl->phydev);
if (pl->sfp_bus)
sfp_upstream_stop(pl->sfp_bus);
+ if (pl->phydev)
+ phy_stop(pl->phydev);
del_timer_sync(&pl->link_poll);
if (pl->link_irq) {
free_irq(pl->link_irq, pl);

View File

@ -16,7 +16,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -538,26 +538,17 @@ static const struct sfp_upstream_ops sfp
@@ -565,26 +565,17 @@ static const struct sfp_upstream_ops sfp
static int phylink_register_sfp(struct phylink *pl,
struct fwnode_handle *fwnode)
{
@ -33,12 +33,12 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
- if (ret == -ENOENT)
- return 0;
-
- netdev_err(pl->netdev, "unable to parse \"sfp\" node: %d\n",
- ret);
- phylink_err(pl, "unable to parse \"sfp\" node: %d\n",
- ret);
+ bus = sfp_register_upstream_node(fwnode, pl, &sfp_phylink_ops);
+ if (IS_ERR(bus)) {
+ ret = PTR_ERR(bus);
+ netdev_err(pl->netdev, "unable to attach SFP bus: %d\n", ret);
+ phylink_err(pl, "unable to attach SFP bus: %d\n", ret);
return ret;
}
@ -51,7 +51,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
}
--- a/drivers/net/phy/sfp-bus.c
+++ b/drivers/net/phy/sfp-bus.c
@@ -3,6 +3,7 @@
@@ -4,6 +4,7 @@
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/phylink.h>
@ -59,7 +59,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
#include <linux/rtnetlink.h>
#include <linux/slab.h>
@@ -444,45 +445,63 @@ static void sfp_upstream_clear(struct sf
@@ -445,45 +446,63 @@ static void sfp_upstream_clear(struct sf
}
/**

View File

@ -20,7 +20,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -541,7 +541,7 @@ static int phylink_register_sfp(struct p
@@ -568,7 +568,7 @@ static int phylink_register_sfp(struct p
struct sfp_bus *bus;
int ret;
@ -28,8 +28,8 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+ bus = sfp_bus_find_fwnode(fwnode);
if (IS_ERR(bus)) {
ret = PTR_ERR(bus);
netdev_err(pl->netdev, "unable to attach SFP bus: %d\n", ret);
@@ -550,7 +550,10 @@ static int phylink_register_sfp(struct p
phylink_err(pl, "unable to attach SFP bus: %d\n", ret);
@@ -577,7 +577,10 @@ static int phylink_register_sfp(struct p
pl->sfp_bus = bus;
@ -41,7 +41,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
}
/**
@@ -634,8 +637,7 @@ EXPORT_SYMBOL_GPL(phylink_create);
@@ -675,8 +678,7 @@ EXPORT_SYMBOL_GPL(phylink_create);
*/
void phylink_destroy(struct phylink *pl)
{
@ -53,7 +53,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/sfp-bus.c
+++ b/drivers/net/phy/sfp-bus.c
@@ -328,10 +328,19 @@ static void sfp_bus_release(struct kref
@@ -329,10 +329,19 @@ static void sfp_bus_release(struct kref
kfree(bus);
}
@ -75,7 +75,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
static int sfp_register_bus(struct sfp_bus *bus)
{
@@ -347,11 +356,11 @@ static int sfp_register_bus(struct sfp_b
@@ -348,11 +357,11 @@ static int sfp_register_bus(struct sfp_b
return ret;
}
}
@ -88,7 +88,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
return 0;
}
@@ -445,13 +454,12 @@ static void sfp_upstream_clear(struct sf
@@ -446,13 +455,12 @@ static void sfp_upstream_clear(struct sf
}
/**
@ -106,7 +106,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
*
* Returns: on success, a pointer to the sfp_bus structure,
* %NULL if no SFP is specified,
@@ -461,9 +469,7 @@ static void sfp_upstream_clear(struct sf
@@ -462,9 +470,7 @@ static void sfp_upstream_clear(struct sf
* %-ENOMEM if we failed to allocate the bus.
* an error from the upstream's connect_phy() method.
*/
@ -117,7 +117,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
{
struct fwnode_reference_args ref;
struct sfp_bus *bus;
@@ -481,7 +487,39 @@ struct sfp_bus *sfp_register_upstream_no
@@ -482,7 +488,39 @@ struct sfp_bus *sfp_register_upstream_no
if (!bus)
return ERR_PTR(-ENOMEM);
@ -157,7 +157,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
bus->upstream_ops = ops;
bus->upstream = upstream;
@@ -494,33 +532,33 @@ struct sfp_bus *sfp_register_upstream_no
@@ -495,33 +533,33 @@ struct sfp_bus *sfp_register_upstream_no
}
rtnl_unlock();

View File

@ -16,7 +16,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/sfp-bus.c
+++ b/drivers/net/phy/sfp-bus.c
@@ -330,7 +330,7 @@ static void sfp_bus_release(struct kref
@@ -331,7 +331,7 @@ static void sfp_bus_release(struct kref
/**
* sfp_bus_put() - put a reference on the &struct sfp_bus

View File

@ -16,7 +16,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -1479,19 +1479,34 @@ static void sfp_sm_mod_remove(struct sfp
@@ -1544,19 +1544,34 @@ static void sfp_sm_mod_remove(struct sfp
dev_info(sfp->dev, "module removed\n");
}
@ -61,7 +61,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
switch (sfp->sm_mod_state) {
default:
if (event == SFP_E_INSERT && sfp->attached) {
@@ -1531,27 +1546,10 @@ static void sfp_sm_event(struct sfp *sfp
@@ -1596,27 +1611,10 @@ static void sfp_sm_event(struct sfp *sfp
}
break;
}
@ -92,7 +92,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
/* Some events are global */
if (sfp->sm_state != SFP_S_DOWN &&
(sfp->sm_mod_state != SFP_MOD_PRESENT ||
@@ -1562,7 +1560,6 @@ static void sfp_sm_event(struct sfp *sfp
@@ -1627,7 +1625,6 @@ static void sfp_sm_event(struct sfp *sfp
if (sfp->mod_phy)
sfp_sm_phy_detach(sfp);
sfp_sm_next(sfp, SFP_S_DOWN, 0);
@ -100,7 +100,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
return;
}
@@ -1617,6 +1614,21 @@ static void sfp_sm_event(struct sfp *sfp
@@ -1682,6 +1679,21 @@ static void sfp_sm_event(struct sfp *sfp
case SFP_S_TX_DISABLE:
break;
}

View File

@ -14,7 +14,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -1489,15 +1489,8 @@ static void sfp_sm_device(struct sfp *sf
@@ -1554,15 +1554,8 @@ static void sfp_sm_device(struct sfp *sf
break;
case SFP_DEV_UP:
@ -31,7 +31,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
break;
}
}
@@ -1559,6 +1552,7 @@ static void sfp_sm_main(struct sfp *sfp,
@@ -1624,6 +1617,7 @@ static void sfp_sm_main(struct sfp *sfp,
sfp_sm_link_down(sfp);
if (sfp->mod_phy)
sfp_sm_phy_detach(sfp);

View File

@ -14,7 +14,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -1180,7 +1180,7 @@ static void sfp_sm_next(struct sfp *sfp,
@@ -1245,7 +1245,7 @@ static void sfp_sm_next(struct sfp *sfp,
sfp_sm_set_timer(sfp, timeout);
}
@ -23,7 +23,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
unsigned int timeout)
{
sfp->sm_mod_state = state;
@@ -1504,22 +1504,22 @@ static void sfp_sm_module(struct sfp *sf
@@ -1569,22 +1569,22 @@ static void sfp_sm_module(struct sfp *sf
default:
if (event == SFP_E_INSERT && sfp->attached) {
sfp_module_tx_disable(sfp);
@ -51,7 +51,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
else
sfp_sm_set_timer(sfp, T_PROBE_RETRY);
}
@@ -1527,7 +1527,7 @@ static void sfp_sm_module(struct sfp *sf
@@ -1592,7 +1592,7 @@ static void sfp_sm_module(struct sfp *sf
case SFP_MOD_HPOWER:
if (event == SFP_E_TIMEOUT) {
@ -60,7 +60,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
break;
}
/* fallthrough */
@@ -1535,7 +1535,7 @@ static void sfp_sm_module(struct sfp *sf
@@ -1600,7 +1600,7 @@ static void sfp_sm_module(struct sfp *sf
case SFP_MOD_ERROR:
if (event == SFP_E_REMOVE) {
sfp_sm_mod_remove(sfp);

View File

@ -14,7 +14,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -1500,6 +1500,14 @@ static void sfp_sm_device(struct sfp *sf
@@ -1565,6 +1565,14 @@ static void sfp_sm_device(struct sfp *sf
*/
static void sfp_sm_module(struct sfp *sfp, unsigned int event)
{
@ -29,7 +29,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
switch (sfp->sm_mod_state) {
default:
if (event == SFP_E_INSERT && sfp->attached) {
@@ -1509,9 +1517,7 @@ static void sfp_sm_module(struct sfp *sf
@@ -1574,9 +1582,7 @@ static void sfp_sm_module(struct sfp *sf
break;
case SFP_MOD_PROBE:
@ -40,7 +40,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
int val = sfp_sm_mod_probe(sfp);
if (val == 0)
@@ -1533,10 +1539,6 @@ static void sfp_sm_module(struct sfp *sf
@@ -1598,10 +1604,6 @@ static void sfp_sm_module(struct sfp *sf
/* fallthrough */
case SFP_MOD_PRESENT:
case SFP_MOD_ERROR:

View File

@ -14,7 +14,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -147,11 +147,10 @@ static const enum gpiod_flags gpio_flags
@@ -149,11 +149,10 @@ static const enum gpiod_flags gpio_flags
* the same length on the PCB, which means it's possible for MOD DEF 0 to
* connect before the I2C bus on MOD DEF 1/2.
*
@ -29,7 +29,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
#define T_HPOWER_LEVEL msecs_to_jiffies(300)
#define T_PROBE_RETRY msecs_to_jiffies(100)
@@ -1495,8 +1494,8 @@ static void sfp_sm_device(struct sfp *sf
@@ -1560,8 +1559,8 @@ static void sfp_sm_device(struct sfp *sf
}
}
@ -40,7 +40,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
*/
static void sfp_sm_module(struct sfp *sfp, unsigned int event)
{
@@ -1512,7 +1511,7 @@ static void sfp_sm_module(struct sfp *sf
@@ -1577,7 +1576,7 @@ static void sfp_sm_module(struct sfp *sf
default:
if (event == SFP_E_INSERT && sfp->attached) {
sfp_module_tx_disable(sfp);

View File

@ -13,7 +13,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -196,6 +196,8 @@ struct sfp {
@@ -198,6 +198,8 @@ struct sfp {
unsigned int sm_retries;
struct sfp_eeprom_id id;
@ -22,7 +22,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
#if IS_ENABLED(CONFIG_HWMON)
struct sfp_diag diag;
struct device *hwmon_dev;
@@ -1309,17 +1311,14 @@ static void sfp_sm_mod_init(struct sfp *
@@ -1374,17 +1376,14 @@ static void sfp_sm_mod_init(struct sfp *
sfp_sm_probe_phy(sfp);
}
@ -44,7 +44,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
if (sfp->id.ext.sff8472_compliance == SFP_SFF8472_COMPLIANCE_NONE &&
(sfp->id.ext.diagmon & (SFP_DIAGMON_DDM | SFP_DIAGMON_ADDRMODE)) !=
@@ -1328,23 +1327,33 @@ static int sfp_sm_mod_hpower(struct sfp
@@ -1393,23 +1392,33 @@ static int sfp_sm_mod_hpower(struct sfp
* or requires an address change sequence, so assume that
* the module powers up in the indicated power mode.
*/
@ -83,7 +83,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
return 0;
err = sfp_read(sfp, true, SFP_EXT_STATUS, &val, sizeof(val));
@@ -1364,7 +1373,8 @@ static int sfp_sm_mod_hpower(struct sfp
@@ -1429,7 +1438,8 @@ static int sfp_sm_mod_hpower(struct sfp
}
dev_info(sfp->dev, "Module switched to %u.%uW power level\n",
@ -93,7 +93,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
return T_HPOWER_LEVEL;
err:
@@ -1451,6 +1461,11 @@ static int sfp_sm_mod_probe(struct sfp *
@@ -1516,6 +1526,11 @@ static int sfp_sm_mod_probe(struct sfp *
dev_warn(sfp->dev,
"module address swap to access page 0xA2 is not supported.\n");
@ -105,7 +105,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
ret = sfp_hwmon_insert(sfp);
if (ret < 0)
return ret;
@@ -1474,6 +1489,7 @@ static void sfp_sm_mod_remove(struct sfp
@@ -1539,6 +1554,7 @@ static void sfp_sm_mod_remove(struct sfp
sfp_module_tx_disable(sfp);
memset(&sfp->id, 0, sizeof(sfp->id));

View File

@ -17,7 +17,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -1320,25 +1320,34 @@ static int sfp_module_parse_power(struct
@@ -1385,25 +1385,34 @@ static int sfp_module_parse_power(struct
if (sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_HIGH_POWER_LEVEL))
power_mW = 2000;

View File

@ -26,7 +26,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -1492,11 +1492,6 @@ static void sfp_sm_mod_remove(struct sfp
@@ -1557,11 +1557,6 @@ static void sfp_sm_mod_remove(struct sfp
sfp_hwmon_remove(sfp);
@ -38,7 +38,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
memset(&sfp->id, 0, sizeof(sfp->id));
sfp->module_power_mW = 0;
@@ -1534,10 +1529,8 @@ static void sfp_sm_module(struct sfp *sf
@@ -1599,10 +1594,8 @@ static void sfp_sm_module(struct sfp *sf
switch (sfp->sm_mod_state) {
default:

View File

@ -14,7 +14,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -1288,14 +1288,10 @@ static void sfp_sm_fault(struct sfp *sfp
@@ -1353,14 +1353,10 @@ static void sfp_sm_fault(struct sfp *sfp
static void sfp_sm_mod_init(struct sfp *sfp)
{
sfp_module_tx_enable(sfp);
@ -32,7 +32,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
/* Setting the serdes link mode is guesswork: there's no
* field in the EEPROM which indicates what mode should
* be used.
@@ -1580,8 +1576,17 @@ static void sfp_sm_main(struct sfp *sfp,
@@ -1645,8 +1641,17 @@ static void sfp_sm_main(struct sfp *sfp,
switch (sfp->sm_state) {
case SFP_S_DOWN:
if (sfp->sm_mod_state == SFP_MOD_PRESENT &&

View File

@ -15,7 +15,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -52,6 +52,7 @@ enum {
@@ -54,6 +54,7 @@ enum {
SFP_DEV_UP,
SFP_S_DOWN = 0,
@ -23,7 +23,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
SFP_S_INIT,
SFP_S_WAIT_LOS,
SFP_S_LINK_UP,
@@ -108,6 +109,7 @@ static const char *event_to_str(unsigned
@@ -110,6 +111,7 @@ static const char *event_to_str(unsigned
static const char * const sm_state_strings[] = {
[SFP_S_DOWN] = "down",
@ -31,7 +31,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
[SFP_S_INIT] = "init",
[SFP_S_WAIT_LOS] = "wait_los",
[SFP_S_LINK_UP] = "link_up",
@@ -139,6 +141,7 @@ static const enum gpiod_flags gpio_flags
@@ -141,6 +143,7 @@ static const enum gpiod_flags gpio_flags
GPIOD_ASIS,
};
@ -39,7 +39,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
#define T_INIT_JIFFIES msecs_to_jiffies(300)
#define T_RESET_US 10
#define T_FAULT_RECOVER msecs_to_jiffies(1000)
@@ -159,9 +162,6 @@ static const enum gpiod_flags gpio_flags
@@ -161,9 +164,6 @@ static const enum gpiod_flags gpio_flags
*/
#define SFP_PHY_ADDR 22
@ -49,7 +49,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
struct sff_data {
unsigned int gpios;
bool (*module_supported)(const struct sfp_eeprom_id *id);
@@ -1202,8 +1202,6 @@ static void sfp_sm_probe_phy(struct sfp
@@ -1267,8 +1267,6 @@ static void sfp_sm_probe_phy(struct sfp
struct phy_device *phy;
int err;
@ -58,7 +58,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
phy = mdiobus_scan(sfp->i2c_mii, SFP_PHY_ADDR);
if (phy == ERR_PTR(-ENODEV)) {
dev_info(sfp->dev, "no PHY detected\n");
@@ -1558,6 +1556,8 @@ static void sfp_sm_module(struct sfp *sf
@@ -1623,6 +1621,8 @@ static void sfp_sm_module(struct sfp *sf
static void sfp_sm_main(struct sfp *sfp, unsigned int event)
{
@ -67,7 +67,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
/* Some events are global */
if (sfp->sm_state != SFP_S_DOWN &&
(sfp->sm_mod_state != SFP_MOD_PRESENT ||
@@ -1575,17 +1575,45 @@ static void sfp_sm_main(struct sfp *sfp,
@@ -1640,17 +1640,45 @@ static void sfp_sm_main(struct sfp *sfp,
/* The main state machine */
switch (sfp->sm_state) {
case SFP_S_DOWN:
@ -119,7 +119,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
}
break;
@@ -1593,7 +1621,7 @@ static void sfp_sm_main(struct sfp *sfp,
@@ -1658,7 +1686,7 @@ static void sfp_sm_main(struct sfp *sfp,
if (event == SFP_E_TIMEOUT && sfp->state & SFP_F_TX_FAULT)
sfp_sm_fault(sfp, true);
else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR)

View File

@ -14,7 +14,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -1269,7 +1269,7 @@ static bool sfp_los_event_inactive(struc
@@ -1334,7 +1334,7 @@ static bool sfp_los_event_inactive(struc
event == SFP_E_LOS_LOW);
}
@ -23,7 +23,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
{
if (sfp->sm_retries && !--sfp->sm_retries) {
dev_err(sfp->dev,
@@ -1279,7 +1279,7 @@ static void sfp_sm_fault(struct sfp *sfp
@@ -1344,7 +1344,7 @@ static void sfp_sm_fault(struct sfp *sfp
if (warn)
dev_err(sfp->dev, "module transmit fault indicated\n");
@ -32,7 +32,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
}
}
@@ -1619,14 +1619,14 @@ static void sfp_sm_main(struct sfp *sfp,
@@ -1684,14 +1684,14 @@ static void sfp_sm_main(struct sfp *sfp,
case SFP_S_INIT:
if (event == SFP_E_TIMEOUT && sfp->state & SFP_F_TX_FAULT)
@ -49,7 +49,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
else if (sfp_los_event_inactive(sfp, event))
sfp_sm_link_up(sfp);
break;
@@ -1634,7 +1634,7 @@ static void sfp_sm_main(struct sfp *sfp,
@@ -1699,7 +1699,7 @@ static void sfp_sm_main(struct sfp *sfp,
case SFP_S_LINK_UP:
if (event == SFP_E_TX_FAULT) {
sfp_sm_link_down(sfp);
@ -58,7 +58,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
} else if (sfp_los_event_active(sfp, event)) {
sfp_sm_link_down(sfp);
sfp_sm_next(sfp, SFP_S_WAIT_LOS, 0);
@@ -1650,7 +1650,7 @@ static void sfp_sm_main(struct sfp *sfp,
@@ -1715,7 +1715,7 @@ static void sfp_sm_main(struct sfp *sfp,
case SFP_S_REINIT:
if (event == SFP_E_TIMEOUT && sfp->state & SFP_F_TX_FAULT) {

View File

@ -19,7 +19,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -54,6 +54,7 @@ enum {
@@ -56,6 +56,7 @@ enum {
SFP_S_DOWN = 0,
SFP_S_WAIT,
SFP_S_INIT,
@ -27,7 +27,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
SFP_S_WAIT_LOS,
SFP_S_LINK_UP,
SFP_S_TX_FAULT,
@@ -111,6 +112,7 @@ static const char * const sm_state_strin
@@ -113,6 +114,7 @@ static const char * const sm_state_strin
[SFP_S_DOWN] = "down",
[SFP_S_WAIT] = "wait",
[SFP_S_INIT] = "init",
@ -35,7 +35,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
[SFP_S_WAIT_LOS] = "wait_los",
[SFP_S_LINK_UP] = "link_up",
[SFP_S_TX_FAULT] = "tx_fault",
@@ -1595,8 +1597,6 @@ static void sfp_sm_main(struct sfp *sfp,
@@ -1660,8 +1662,6 @@ static void sfp_sm_main(struct sfp *sfp,
if (event != SFP_E_TIMEOUT)
break;
@ -44,7 +44,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
if (sfp->state & SFP_F_TX_FAULT) {
/* Wait t_init before indicating that the link is up,
* provided the current state indicates no TX_FAULT. If
@@ -1618,10 +1618,29 @@ static void sfp_sm_main(struct sfp *sfp,
@@ -1683,10 +1683,29 @@ static void sfp_sm_main(struct sfp *sfp,
break;
case SFP_S_INIT:

View File

@ -24,7 +24,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -34,6 +34,8 @@ enum {
@@ -36,6 +36,8 @@ enum {
SFP_E_INSERT = 0,
SFP_E_REMOVE,
@ -33,7 +33,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
SFP_E_DEV_DOWN,
SFP_E_DEV_UP,
SFP_E_TX_FAULT,
@@ -48,7 +50,8 @@ enum {
@@ -50,7 +52,8 @@ enum {
SFP_MOD_PRESENT,
SFP_MOD_ERROR,
@ -43,7 +43,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
SFP_DEV_UP,
SFP_S_DOWN = 0,
@@ -78,6 +81,7 @@ static const char *mod_state_to_str(unsi
@@ -80,6 +83,7 @@ static const char *mod_state_to_str(unsi
}
static const char * const dev_state_strings[] = {
@ -51,7 +51,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
[SFP_DEV_DOWN] = "down",
[SFP_DEV_UP] = "up",
};
@@ -92,6 +96,8 @@ static const char *dev_state_to_str(unsi
@@ -94,6 +98,8 @@ static const char *dev_state_to_str(unsi
static const char * const event_strings[] = {
[SFP_E_INSERT] = "insert",
[SFP_E_REMOVE] = "remove",
@ -60,7 +60,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
[SFP_E_DEV_DOWN] = "dev_down",
[SFP_E_DEV_UP] = "dev_up",
[SFP_E_TX_FAULT] = "tx_fault",
@@ -186,7 +192,6 @@ struct sfp {
@@ -188,7 +194,6 @@ struct sfp {
struct gpio_desc *gpio[GPIO_MAX];
int gpio_irq[GPIO_MAX];
@ -68,7 +68,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
struct mutex st_mutex; /* Protects state */
unsigned int state;
struct delayed_work poll;
@@ -1494,17 +1499,26 @@ static void sfp_sm_mod_remove(struct sfp
@@ -1559,17 +1564,26 @@ static void sfp_sm_mod_remove(struct sfp
dev_info(sfp->dev, "module removed\n");
}
@ -98,7 +98,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
sfp->sm_dev_state = SFP_DEV_DOWN;
break;
}
@@ -1515,17 +1529,20 @@ static void sfp_sm_device(struct sfp *sf
@@ -1580,17 +1594,20 @@ static void sfp_sm_device(struct sfp *sf
*/
static void sfp_sm_module(struct sfp *sfp, unsigned int event)
{
@ -123,7 +123,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
sfp_sm_mod_next(sfp, SFP_MOD_PROBE, T_SERIAL);
break;
@@ -1691,8 +1708,8 @@ static void sfp_sm_event(struct sfp *sfp
@@ -1756,8 +1773,8 @@ static void sfp_sm_event(struct sfp *sfp
sm_state_to_str(sfp->sm_state),
event_to_str(event));
@ -133,7 +133,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
sfp_sm_main(sfp, event);
dev_dbg(sfp->dev, "SM: exit %s:%s:%s\n",
@@ -1705,15 +1722,14 @@ static void sfp_sm_event(struct sfp *sfp
@@ -1770,15 +1787,14 @@ static void sfp_sm_event(struct sfp *sfp
static void sfp_attach(struct sfp *sfp)
{

View File

@ -18,7 +18,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -47,6 +47,7 @@ enum {
@@ -49,6 +49,7 @@ enum {
SFP_MOD_EMPTY = 0,
SFP_MOD_PROBE,
SFP_MOD_HPOWER,
@ -26,7 +26,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
SFP_MOD_PRESENT,
SFP_MOD_ERROR,
@@ -69,6 +70,7 @@ static const char * const mod_state_str
@@ -71,6 +72,7 @@ static const char * const mod_state_str
[SFP_MOD_EMPTY] = "empty",
[SFP_MOD_PROBE] = "probe",
[SFP_MOD_HPOWER] = "hpower",
@ -34,7 +34,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
[SFP_MOD_PRESENT] = "present",
[SFP_MOD_ERROR] = "error",
};
@@ -1358,37 +1360,34 @@ static int sfp_module_parse_power(struct
@@ -1423,37 +1425,34 @@ static int sfp_module_parse_power(struct
return 0;
}
@ -84,7 +84,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
}
static int sfp_sm_mod_probe(struct sfp *sfp)
@@ -1484,7 +1483,7 @@ static int sfp_sm_mod_probe(struct sfp *
@@ -1549,7 +1548,7 @@ static int sfp_sm_mod_probe(struct sfp *
if (ret < 0)
return ret;
@ -93,7 +93,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
}
static void sfp_sm_mod_remove(struct sfp *sfp)
@@ -1529,13 +1528,22 @@ static void sfp_sm_device(struct sfp *sf
@@ -1594,13 +1593,22 @@ static void sfp_sm_device(struct sfp *sf
*/
static void sfp_sm_module(struct sfp *sfp, unsigned int event)
{
@ -121,7 +121,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
sfp_sm_mod_next(sfp, SFP_MOD_EMPTY, 0);
return;
}
@@ -1547,26 +1555,45 @@ static void sfp_sm_module(struct sfp *sf
@@ -1612,26 +1620,45 @@ static void sfp_sm_module(struct sfp *sf
break;
case SFP_MOD_PROBE:

View File

@ -20,7 +20,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -45,11 +45,12 @@ enum {
@@ -47,11 +47,12 @@ enum {
SFP_E_TIMEOUT,
SFP_MOD_EMPTY = 0,
@ -34,7 +34,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
SFP_DEV_DETACHED = 0,
SFP_DEV_DOWN,
@@ -68,11 +69,12 @@ enum {
@@ -70,11 +71,12 @@ enum {
static const char * const mod_state_strings[] = {
[SFP_MOD_EMPTY] = "empty",
@ -48,7 +48,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
};
static const char *mod_state_to_str(unsigned short mod_state)
@@ -1479,16 +1481,13 @@ static int sfp_sm_mod_probe(struct sfp *
@@ -1544,16 +1546,13 @@ static int sfp_sm_mod_probe(struct sfp *
if (ret < 0)
return ret;
@ -67,7 +67,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
sfp_hwmon_remove(sfp);
@@ -1539,12 +1538,12 @@ static void sfp_sm_module(struct sfp *sf
@@ -1604,12 +1603,12 @@ static void sfp_sm_module(struct sfp *sf
}
/* Handle device detach globally */
@ -83,7 +83,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
return;
}
@@ -1555,6 +1554,7 @@ static void sfp_sm_module(struct sfp *sf
@@ -1620,6 +1619,7 @@ static void sfp_sm_module(struct sfp *sf
break;
case SFP_MOD_PROBE:
@ -91,7 +91,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
if (event != SFP_E_TIMEOUT)
break;
@@ -1568,6 +1568,20 @@ static void sfp_sm_module(struct sfp *sf
@@ -1633,6 +1633,20 @@ static void sfp_sm_module(struct sfp *sf
break;
}
@ -112,7 +112,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
/* If this is a power level 1 module, we are done */
if (sfp->module_power_mW <= 1000)
goto insert;
@@ -1577,12 +1591,17 @@ static void sfp_sm_module(struct sfp *sf
@@ -1642,12 +1656,17 @@ static void sfp_sm_module(struct sfp *sf
case SFP_MOD_HPOWER:
/* Enable high power mode */
err = sfp_sm_mod_hpower(sfp, true);
@ -136,7 +136,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
break;
case SFP_MOD_WAITPWR:
@@ -1750,8 +1769,6 @@ static void sfp_sm_event(struct sfp *sfp
@@ -1815,8 +1834,6 @@ static void sfp_sm_event(struct sfp *sfp
static void sfp_attach(struct sfp *sfp)
{
sfp_sm_event(sfp, SFP_E_DEV_ATTACH);
@ -145,7 +145,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
}
static void sfp_detach(struct sfp *sfp)
@@ -2001,6 +2018,11 @@ static int sfp_probe(struct platform_dev
@@ -2084,6 +2101,11 @@ static int sfp_probe(struct platform_dev
sfp->state |= SFP_F_RATE_SELECT;
sfp_set_state(sfp, sfp->state);
sfp_module_tx_disable(sfp);

View File

@ -19,7 +19,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -165,9 +165,12 @@ static const enum gpiod_flags gpio_flags
@@ -167,9 +167,12 @@ static const enum gpiod_flags gpio_flags
* The SFF-8472 specifies t_serial ("Time from power on until module is
* ready for data transmission over the two wire serial bus.") as 300ms.
*/
@ -35,7 +35,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
/* SFP modules appear to always have their PHY configured for bus address
* 0x56 (which with mdio-i2c, translates to a PHY address of 22).
@@ -202,6 +205,8 @@ struct sfp {
@@ -204,6 +207,8 @@ struct sfp {
struct delayed_work timeout;
struct mutex sm_mutex; /* Protects state machine */
unsigned char sm_mod_state;
@ -44,7 +44,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
unsigned char sm_dev_state;
unsigned short sm_state;
unsigned int sm_retries;
@@ -1392,7 +1397,7 @@ static int sfp_sm_mod_hpower(struct sfp
@@ -1457,7 +1462,7 @@ static int sfp_sm_mod_hpower(struct sfp
return 0;
}
@ -53,7 +53,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
{
/* SFP module inserted - read I2C data */
struct sfp_eeprom_id id;
@@ -1402,7 +1407,8 @@ static int sfp_sm_mod_probe(struct sfp *
@@ -1467,7 +1472,8 @@ static int sfp_sm_mod_probe(struct sfp *
ret = sfp_read(sfp, false, 0, &id, sizeof(id));
if (ret < 0) {
@ -63,7 +63,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
return -EAGAIN;
}
@@ -1549,8 +1555,11 @@ static void sfp_sm_module(struct sfp *sf
@@ -1614,8 +1620,11 @@ static void sfp_sm_module(struct sfp *sf
switch (sfp->sm_mod_state) {
default:
@ -76,7 +76,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
break;
case SFP_MOD_PROBE:
@@ -1558,10 +1567,19 @@ static void sfp_sm_module(struct sfp *sf
@@ -1623,10 +1632,19 @@ static void sfp_sm_module(struct sfp *sf
if (event != SFP_E_TIMEOUT)
break;
@ -99,7 +99,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
}
if (err < 0) {
sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0);
@@ -1596,7 +1614,7 @@ static void sfp_sm_module(struct sfp *sf
@@ -1661,7 +1679,7 @@ static void sfp_sm_module(struct sfp *sf
sfp_module_remove(sfp->sfp_bus);
sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0);
} else {

View File

@ -27,7 +27,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -216,6 +216,8 @@ struct sfp {
@@ -218,6 +218,8 @@ struct sfp {
#if IS_ENABLED(CONFIG_HWMON)
struct sfp_diag diag;
@ -36,7 +36,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
struct device *hwmon_dev;
char *hwmon_name;
#endif
@@ -1094,29 +1096,27 @@ static const struct hwmon_chip_info sfp_
@@ -1159,29 +1161,27 @@ static const struct hwmon_chip_info sfp_
.info = sfp_hwmon_info,
};
@ -81,7 +81,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
for (i = 0; sfp->hwmon_name[i]; i++)
if (hwmon_is_bad_char(sfp->hwmon_name[i]))
@@ -1126,18 +1126,52 @@ static int sfp_hwmon_insert(struct sfp *
@@ -1191,18 +1191,52 @@ static int sfp_hwmon_insert(struct sfp *
sfp->hwmon_name, sfp,
&sfp_hwmon_chip_info,
NULL);
@ -135,7 +135,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
#else
static int sfp_hwmon_insert(struct sfp *sfp)
{
@@ -1147,6 +1181,15 @@ static int sfp_hwmon_insert(struct sfp *
@@ -1212,6 +1246,15 @@ static int sfp_hwmon_insert(struct sfp *
static void sfp_hwmon_remove(struct sfp *sfp)
{
}
@ -151,7 +151,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
#endif
/* Helpers */
@@ -1483,10 +1526,6 @@ static int sfp_sm_mod_probe(struct sfp *
@@ -1548,10 +1591,6 @@ static int sfp_sm_mod_probe(struct sfp *
if (ret < 0)
return ret;
@ -162,7 +162,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
return 0;
}
@@ -1635,6 +1674,15 @@ static void sfp_sm_module(struct sfp *sf
@@ -1700,6 +1739,15 @@ static void sfp_sm_module(struct sfp *sf
case SFP_MOD_ERROR:
break;
}
@ -178,7 +178,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
}
static void sfp_sm_main(struct sfp *sfp, unsigned int event)
@@ -1936,6 +1984,8 @@ static struct sfp *sfp_alloc(struct devi
@@ -2001,6 +2049,8 @@ static struct sfp *sfp_alloc(struct devi
INIT_DELAYED_WORK(&sfp->poll, sfp_poll);
INIT_DELAYED_WORK(&sfp->timeout, sfp_timeout);
@ -187,7 +187,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
return sfp;
}
@@ -1943,6 +1993,8 @@ static void sfp_cleanup(void *data)
@@ -2008,6 +2058,8 @@ static void sfp_cleanup(void *data)
{
struct sfp *sfp = data;

View File

@ -16,7 +16,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -30,6 +30,7 @@
@@ -23,6 +23,7 @@
#include <linux/ethtool.h>
#include <linux/phy.h>
#include <linux/phy_led_triggers.h>
@ -24,38 +24,38 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
#include <linux/workqueue.h>
#include <linux/mdio.h>
#include <linux/io.h>
@@ -871,6 +872,9 @@ void phy_stop(struct phy_device *phydev)
if (phy_interrupt_is_valid(phydev))
phy_disable_interrupts(phydev);
@@ -841,6 +842,9 @@ void phy_stop(struct phy_device *phydev)
mutex_lock(&phydev->lock);
+ if (phydev->sfp_bus)
+ sfp_upstream_stop(phydev->sfp_bus);
+
phydev->state = PHY_HALTED;
out_unlock:
@@ -899,6 +903,9 @@ void phy_start(struct phy_device *phydev
mutex_unlock(&phydev->lock);
@@ -903,6 +907,9 @@ void phy_state_machine(struct work_struc
mutex_lock(&phydev->lock);
old_state = phydev->state;
+ if (phydev->sfp_bus)
+ sfp_upstream_start(phydev->sfp_bus);
+
switch (phydev->state) {
case PHY_STARTING:
phydev->state = PHY_PENDING;
case PHY_DOWN:
case PHY_READY:
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -31,6 +31,7 @@
#include <linux/ethtool.h>
@@ -27,6 +27,7 @@
#include <linux/bitmap.h>
#include <linux/phy.h>
#include <linux/phy_led_triggers.h>
+#include <linux/sfp.h>
#include <linux/mdio.h>
#include <linux/io.h>
#include <linux/uaccess.h>
@@ -944,6 +945,65 @@ void phy_attached_print(struct phy_devic
EXPORT_SYMBOL(phy_attached_print);
@@ -1178,6 +1179,65 @@ phy_standalone_show(struct device *dev,
static DEVICE_ATTR_RO(phy_standalone);
/**
+ * phy_sfp_attach - attach the SFP bus to the PHY upstream network device
@ -120,9 +120,9 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
* phy_attach_direct - attach a network device to a given PHY device pointer
* @dev: network device to attach
* @phydev: Pointer to phy_device to attach
@@ -1016,6 +1076,9 @@ int phy_attach_direct(struct net_device
phydev->attached_dev = dev;
dev->phydev = phydev;
@@ -1254,6 +1314,9 @@ int phy_attach_direct(struct net_device
dev->phydev = phydev;
}
+ if (phydev->sfp_bus_attached)
+ dev->sfp_bus = phydev->sfp_bus;
@ -130,7 +130,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
/* Some Ethernet drivers try to connect to a PHY device before
* calling register_netdevice() -> netdev_register_kobject() and
* does the dev->dev.kobj initialization. Here we only check for
@@ -1950,6 +2013,9 @@ static int phy_remove(struct device *dev
@@ -2282,6 +2345,9 @@ static int phy_remove(struct device *dev
phydev->state = PHY_DOWN;
mutex_unlock(&phydev->lock);
@ -142,7 +142,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -184,6 +184,8 @@ static inline const char *phy_modes(phy_
@@ -203,6 +203,8 @@ static inline const char *phy_modes(phy_
struct device;
struct phylink;
@ -151,16 +151,16 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
struct sk_buff;
/*
@@ -382,6 +384,8 @@ struct phy_c45_device_ids {
@@ -342,6 +344,8 @@ struct phy_c45_device_ids {
* dev_flags: Device-specific flags used by the PHY driver.
* irq: IRQ number of the PHY's interrupt (-1 if none)
* phy_timer: The timer for handling the state machine
* phy_queue: A work_queue for the phy_mac_interrupt
+ * sfp_bus_attached: flag indicating whether the SFP bus has been attached
+ * sfp_bus: SFP bus attached to this PHY's fiber port
* attached_dev: The attached enet driver's device instance ptr
* adjust_link: Callback for the enet controller to respond to
* changes in the link state.
@@ -471,6 +475,9 @@ struct phy_device {
@@ -432,6 +436,9 @@ struct phy_device {
struct mutex lock;
@ -170,7 +170,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
struct phylink *phylink;
struct net_device *attached_dev;
@@ -1031,6 +1038,10 @@ int phy_suspend(struct phy_device *phyde
@@ -1020,6 +1027,10 @@ int phy_suspend(struct phy_device *phyde
int phy_resume(struct phy_device *phydev);
int __phy_resume(struct phy_device *phydev);
int phy_loopback(struct phy_device *phydev, bool enable);

View File

@ -19,15 +19,15 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/marvell10g.c
+++ b/drivers/net/phy/marvell10g.c
@@ -25,6 +25,7 @@
@@ -26,6 +26,7 @@
#include <linux/hwmon.h>
#include <linux/marvell_phy.h>
#include <linux/phy.h>
+#include <linux/sfp.h>
enum {
MV_PMA_BOOT = 0xc050,
@@ -219,6 +220,28 @@ static int mv3310_hwmon_probe(struct phy
#define MV_PHY_ALASKA_NBT_QUIRK_MASK 0xfffffffe
#define MV_PHY_ALASKA_NBT_QUIRK_REV (MARVELL_PHY_ID_88X3310 | 0xa)
@@ -206,6 +207,28 @@ static int mv3310_hwmon_probe(struct phy
}
#endif
@ -56,7 +56,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
static int mv3310_probe(struct phy_device *phydev)
{
struct mv3310_priv *priv;
@@ -249,7 +272,7 @@ static int mv3310_probe(struct phy_devic
@@ -236,7 +259,7 @@ static int mv3310_probe(struct phy_devic
if (ret)
return ret;

View File

@ -12,20 +12,19 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -678,12 +678,6 @@ static int phylink_bringup_phy(struct ph
u32 advertising;
@@ -718,11 +718,6 @@ static int phylink_bringup_phy(struct ph
__ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
int ret;
- memset(&config, 0, sizeof(config));
- ethtool_convert_legacy_u32_to_link_mode(supported, phy->supported);
- ethtool_convert_legacy_u32_to_link_mode(config.advertising,
- phy->advertising);
- linkmode_copy(supported, phy->supported);
- linkmode_copy(config.advertising, phy->advertising);
- config.interface = pl->link_config.interface;
-
/*
* This is the new way of dealing with flow control for PHYs,
* as described by Timur Tabi in commit 529ed1275263 ("net: phy:
@@ -691,10 +685,13 @@ static int phylink_bringup_phy(struct ph
@@ -730,10 +725,12 @@ static int phylink_bringup_phy(struct ph
* using our validate call to the MAC, we rely upon the MAC
* clearing the bits from both supported and advertising fields.
*/
@ -36,9 +35,8 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+ phy_support_asym_pause(phy);
+
+ memset(&config, 0, sizeof(config));
+ ethtool_convert_legacy_u32_to_link_mode(supported, phy->supported);
+ ethtool_convert_legacy_u32_to_link_mode(config.advertising,
+ phy->advertising);
+ linkmode_copy(supported, phy->supported);
+ linkmode_copy(config.advertising, phy->advertising);
+ config.interface = pl->link_config.interface;
ret = phylink_validate(pl, supported, &config);

View File

@ -1,63 +0,0 @@
From 1be8018db381200c24854e0c299206c557f76fe0 Mon Sep 17 00:00:00 2001
From: Russell King <rmk+kernel@armlinux.org.uk>
Date: Mon, 11 Nov 2019 11:58:09 +0000
Subject: [PATCH 638/660] net: phy: avoid matching all-ones clause 45 PHY IDs
We currently match clause 45 PHYs using any ID read from a MMD marked
as present in the "Devices in package" registers 5 and 6. However,
this is incorrect. 45.2 says:
"The definition of the term package is vendor specific and could be
a chip, module, or other similar entity."
so a package could be more or less than the whole PHY - a PHY could be
made up of several modules instantiated onto a single chip such as the
Marvell 88x3310, or some of the MMDs could be disabled according to
chip configuration, such as the Broadcom 84881.
In the case of Broadcom 84881, the "Devices in package" registers
contain 0xc000009b, meaning that there is a PHYXS present in the
package, but all registers in MMD 4 return 0xffff. This leads to our
matching code incorrectly binding this PHY to one of our generic PHY
drivers.
This patch changes the way we determine whether to attempt to match a
MMD identifier, or use it to request a module - if the identifier is
all-ones, then we skip over it. When reading the identifiers, we
initialise phydev->c45_ids.device_ids to all-ones, only reading the
device ID if the "Devices in package" registers indicates we should.
This avoids the generic drivers incorrectly matching on a PHY ID of
0xffffffff.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/phy_device.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -335,7 +335,7 @@ static int phy_bus_match(struct device *
if (phydev->is_c45) {
for (i = 1; i < num_ids; i++) {
- if (!(phydev->c45_ids.devices_in_package & (1 << i)))
+ if (phydev->c45_ids.device_ids[i] == 0xffffffff)
continue;
if ((phydrv->phy_id & phydrv->phy_id_mask) ==
@@ -623,10 +623,13 @@ static int get_phy_id(struct mii_bus *bu
*/
struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45)
{
- struct phy_c45_device_ids c45_ids = {0};
+ struct phy_c45_device_ids c45_ids;
u32 phy_id = 0;
int r;
+ c45_ids.devices_in_package = 0;
+ memset(c45_ids.device_ids, 0xff, sizeof(c45_ids.device_ids));
+
r = get_phy_id(bus, addr, &phy_id, is_c45, &c45_ids);
if (r)
return ERR_PTR(r);

View File

@ -1,66 +0,0 @@
From 4c9633f75dc35abe1b9261e0415d77802f35741d Mon Sep 17 00:00:00 2001
From: Russell King <rmk+kernel@armlinux.org.uk>
Date: Tue, 5 Nov 2019 11:58:00 +0000
Subject: [PATCH 639/660] net: phylink: fix link mode modification in PHY mode
Modifying the link settings via phylink_ethtool_ksettings_set() and
phylink_ethtool_set_pauseparam() didn't always work as intended for
PHY based setups, as calling phylink_mac_config() would result in the
unresolved configuration being committed to the MAC, rather than the
configuration with the speed and duplex setting.
This would work fine if the update caused the link to renegotiate,
but if no settings have changed, phylib won't trigger a renegotiation
cycle, and the MAC will be left incorrectly configured.
Avoid calling phylink_mac_config() unless we are using an inband mode
in phylink_ethtool_ksettings_set(), and use phy_set_asym_pause() as
introduced in 4.20 to set the PHY settings in
phylink_ethtool_set_pauseparam().
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/phylink.c | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -1210,7 +1210,13 @@ int phylink_ethtool_ksettings_set(struct
pl->link_config.duplex = our_kset.base.duplex;
pl->link_config.an_enabled = our_kset.base.autoneg != AUTONEG_DISABLE;
- if (!test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) {
+ /* If we have a PHY, phylib will call our link state function if the
+ * mode has changed, which will trigger a resolve and update the MAC
+ * configuration. For a fixed link, this isn't able to change any
+ * parameters, which just leaves inband mode.
+ */
+ if (pl->link_an_mode == MLO_AN_INBAND &&
+ !test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) {
phylink_mac_config(pl, &pl->link_config);
phylink_mac_an_restart(pl);
}
@@ -1290,14 +1296,16 @@ int phylink_ethtool_set_pauseparam(struc
if (pause->tx_pause)
config->pause |= MLO_PAUSE_TX;
- if (!test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) {
+ /* If we have a PHY, phylib will call our link state function if the
+ * mode has changed, which will trigger a resolve and update the MAC
+ * configuration.
+ */
+ if (pl->phydev) {
+ phy_set_asym_pause(pl->phydev, pause->rx_pause,
+ pause->tx_pause);
+ } else if (!test_bit(PHYLINK_DISABLE_STOPPED,
+ &pl->phylink_disable_state)) {
switch (pl->link_an_mode) {
- case MLO_AN_PHY:
- /* Silently mark the carrier down, and then trigger a resolve */
- netif_carrier_off(pl->netdev);
- phylink_run_resolve(pl);
- break;
-
case MLO_AN_FIXED:
/* Should we allow fixed links to change against the config? */
phylink_resolve_flow(pl, config);

View File

@ -13,7 +13,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/sfp-bus.c
+++ b/drivers/net/phy/sfp-bus.c
@@ -9,6 +9,12 @@
@@ -10,6 +10,12 @@
#include "sfp.h"
@ -26,7 +26,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
/**
* struct sfp_bus - internal representation of a sfp bus
*/
@@ -21,6 +27,7 @@ struct sfp_bus {
@@ -22,6 +28,7 @@ struct sfp_bus {
const struct sfp_socket_ops *socket_ops;
struct device *sfp_dev;
struct sfp *sfp;
@ -34,7 +34,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
const struct sfp_upstream_ops *upstream_ops;
void *upstream;
@@ -30,6 +37,46 @@ struct sfp_bus {
@@ -31,6 +38,46 @@ struct sfp_bus {
bool started;
};
@ -81,7 +81,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
/**
* sfp_parse_port() - Parse the EEPROM base ID, setting the port type
* @bus: a pointer to the &struct sfp_bus structure for the sfp module
@@ -233,6 +280,9 @@ void sfp_parse_support(struct sfp_bus *b
@@ -234,6 +281,9 @@ void sfp_parse_support(struct sfp_bus *b
phylink_set(modes, 1000baseX_Full);
}
@ -91,7 +91,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
bitmap_or(support, support, modes, __ETHTOOL_LINK_MODE_MASK_NBITS);
phylink_set(support, Autoneg);
@@ -609,6 +659,8 @@ int sfp_module_insert(struct sfp_bus *bu
@@ -610,6 +660,8 @@ int sfp_module_insert(struct sfp_bus *bu
const struct sfp_upstream_ops *ops = sfp_get_upstream_ops(bus);
int ret = 0;
@ -100,7 +100,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
if (ops && ops->module_insert)
ret = ops->module_insert(bus->upstream, id);
@@ -622,6 +674,8 @@ void sfp_module_remove(struct sfp_bus *b
@@ -623,6 +675,8 @@ void sfp_module_remove(struct sfp_bus *b
if (ops && ops->module_remove)
ops->module_remove(bus->upstream);

View File

@ -17,7 +17,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/sfp-bus.c
+++ b/drivers/net/phy/sfp-bus.c
@@ -37,7 +37,32 @@ struct sfp_bus {
@@ -38,7 +38,32 @@ struct sfp_bus {
bool started;
};

View File

@ -16,7 +16,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -199,7 +199,10 @@ struct sfp {
@@ -201,7 +201,10 @@ struct sfp {
struct gpio_desc *gpio[GPIO_MAX];
int gpio_irq[GPIO_MAX];
@ -27,7 +27,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
unsigned int state;
struct delayed_work poll;
struct delayed_work timeout;
@@ -393,24 +396,90 @@ static int sfp_i2c_configure(struct sfp
@@ -395,24 +398,90 @@ static int sfp_i2c_configure(struct sfp
}
/* Interface */
@ -126,7 +126,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
}
static unsigned int sfp_check(void *buf, size_t len)
@@ -1342,11 +1411,6 @@ static void sfp_sm_fault(struct sfp *sfp
@@ -1407,11 +1476,6 @@ static void sfp_sm_fault(struct sfp *sfp
}
}
@ -138,7 +138,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
static void sfp_sm_probe_for_phy(struct sfp *sfp)
{
/* Setting the serdes link mode is guesswork: there's no
@@ -1509,7 +1573,7 @@ static int sfp_sm_mod_probe(struct sfp *
@@ -1574,7 +1638,7 @@ static int sfp_sm_mod_probe(struct sfp *
(int)sizeof(id.ext.datecode), id.ext.datecode);
/* Check whether we support this module */
@ -147,7 +147,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
dev_err(sfp->dev,
"module is not supported - phys id 0x%02x 0x%02x\n",
sfp->id.base.phys_id, sfp->id.base.phys_ext_id);
@@ -1699,6 +1763,7 @@ static void sfp_sm_main(struct sfp *sfp,
@@ -1764,6 +1828,7 @@ static void sfp_sm_main(struct sfp *sfp,
if (sfp->mod_phy)
sfp_sm_phy_detach(sfp);
sfp_module_tx_disable(sfp);
@ -155,7 +155,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
sfp_sm_next(sfp, SFP_S_DOWN, 0);
return;
}
@@ -1710,7 +1775,10 @@ static void sfp_sm_main(struct sfp *sfp,
@@ -1775,7 +1840,10 @@ static void sfp_sm_main(struct sfp *sfp,
sfp->sm_dev_state != SFP_DEV_UP)
break;
@ -167,7 +167,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
/* Initialise the fault clearance retries */
sfp->sm_retries = 5;
@@ -1966,7 +2034,10 @@ static void sfp_poll(struct work_struct
@@ -2031,7 +2099,10 @@ static void sfp_poll(struct work_struct
struct sfp *sfp = container_of(work, struct sfp, poll.work);
sfp_check_state(sfp);
@ -179,15 +179,15 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
}
static struct sfp *sfp_alloc(struct device *dev)
@@ -2010,7 +2081,6 @@ static int sfp_probe(struct platform_dev
{
@@ -2076,7 +2147,6 @@ static int sfp_probe(struct platform_dev
const struct sff_data *sff;
struct i2c_adapter *i2c;
struct sfp *sfp;
- bool poll = false;
int err, i;
sfp = sfp_alloc(&pdev->dev);
@@ -2100,7 +2170,7 @@ static int sfp_probe(struct platform_dev
@@ -2183,7 +2253,7 @@ static int sfp_probe(struct platform_dev
sfp->gpio_irq[i] = gpiod_to_irq(sfp->gpio[i]);
if (!sfp->gpio_irq[i]) {
@ -196,7 +196,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
continue;
}
@@ -2112,11 +2182,11 @@ static int sfp_probe(struct platform_dev
@@ -2195,11 +2265,11 @@ static int sfp_probe(struct platform_dev
dev_name(sfp->dev), sfp);
if (err) {
sfp->gpio_irq[i] = 0;

File diff suppressed because it is too large Load Diff

View File

@ -2487,7 +2487,9 @@ ar8xxx_phy_read_status(struct phy_device *phydev)
struct switch_port_link link;
/* check for switch port link changes */
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 1, 0)
if (phydev->state == PHY_CHANGELINK)
#endif
ar8xxx_check_link_states(priv);
if (phydev->mdio.addr != 0)
@ -2628,6 +2630,14 @@ found:
priv->use_count++;
if (phydev->mdio.addr == 0) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
linkmode_zero(phydev->supported);
if (ar8xxx_has_gige(priv))
linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, phydev->supported);
else
linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, phydev->supported);
linkmode_copy(phydev->advertising, phydev->supported);
#else
if (ar8xxx_has_gige(priv)) {
phydev->supported = SUPPORTED_1000baseT_Full;
phydev->advertising = ADVERTISED_1000baseT_Full;
@ -2635,6 +2645,7 @@ found:
phydev->supported = SUPPORTED_100baseT_Full;
phydev->advertising = ADVERTISED_100baseT_Full;
}
#endif
if (priv->chip->config_at_probe) {
priv->phy = phydev;
@ -2645,8 +2656,14 @@ found:
}
} else {
if (ar8xxx_has_gige(priv)) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
linkmode_zero(phydev->supported);
linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, phydev->supported);
linkmode_copy(phydev->advertising, phydev->supported);
#else
phydev->supported |= SUPPORTED_1000baseT_Full;
phydev->advertising |= ADVERTISED_1000baseT_Full;
#endif
}
if (priv->chip->phy_rgmii_set)
priv->chip->phy_rgmii_set(priv, phydev);

View File

@ -14,7 +14,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -160,6 +160,7 @@ extern void cleanup_module(void);
@@ -157,6 +157,7 @@ extern void cleanup_module(void);
/* Generic info of form tag = "info" */
#define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info)
@ -22,7 +22,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
/* For userspace: you can also call me... */
#define MODULE_ALIAS(_alias) MODULE_INFO(alias, _alias)
@@ -203,12 +204,12 @@ extern void cleanup_module(void);
@@ -216,12 +217,12 @@ extern void cleanup_module(void);
* Author(s), use "Name <email>" or just "Name", for multiple
* authors use multiple MODULE_AUTHOR() statements/lines.
*/
@ -38,7 +38,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
/* Creates an alias so file2alias.c can find device table. */
#define MODULE_DEVICE_TABLE(type, name) \
extern typeof(name) __mod_##type##__##name##_device_table \
@@ -235,7 +236,9 @@ extern typeof(name) __mod_##type##__##na
@@ -248,7 +249,9 @@ extern typeof(name) __mod_##type##__##na
*/
#if defined(MODULE) || !defined(CONFIG_SYSFS)
@ -48,19 +48,19 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+#define MODULE_VERSION(_version) __MODULE_INFO_DISABLED(version)
#else
#define MODULE_VERSION(_version) \
static struct module_version_attribute ___modver_attr = { \
@@ -257,7 +260,7 @@ extern typeof(name) __mod_##type##__##na
MODULE_INFO(version, _version); \
@@ -271,7 +274,7 @@ extern typeof(name) __mod_##type##__##na
/* Optional firmware file (or files) needed by the module
* format is simply firmware file name. Multiple firmware
* files require multiple MODULE_FIRMWARE() specifiers */
-#define MODULE_FIRMWARE(_firmware) MODULE_INFO(firmware, _firmware)
+#define MODULE_FIRMWARE(_firmware) MODULE_INFO_STRIP(firmware, _firmware)
struct notifier_block;
#define MODULE_IMPORT_NS(ns) MODULE_INFO(import_ns, #ns)
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -17,6 +17,16 @@
@@ -20,10 +20,24 @@
/* Chosen so that structs with an unsigned long line up. */
#define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long))
@ -74,20 +74,18 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+#define __MODULE_INFO_STRIP(tag, name, info) __MODULE_INFO(tag, name, info)
+#endif
+
#ifdef MODULE
+#ifdef MODULE
#define __MODULE_INFO(tag, name, info) \
static const char __UNIQUE_ID(name)[] \
@@ -24,8 +34,7 @@ static const char __UNIQUE_ID(name)[]
= __stringify(tag) "=" info
#else /* !MODULE */
/* This struct is here for syntactic coherency, it is not used */
-#define __MODULE_INFO(tag, name, info) \
- struct __UNIQUE_ID(name) {}
__used __attribute__((section(".modinfo"), unused, aligned(1))) \
= __MODULE_INFO_PREFIX __stringify(tag) "=" info
+#else
+#define __MODULE_INFO(tag, name, info) __MODULE_INFO_DISABLED(name)
#endif
+#endif
#define __MODULE_PARM_TYPE(name, _type) \
__MODULE_INFO(parmtype, name##type, #name ":" _type)
@@ -33,7 +42,7 @@ static const char __UNIQUE_ID(name)[]
@@ -31,7 +45,7 @@ static const char __UNIQUE_ID(name)[]
/* One for each parameter, describing how to use it. Some files do
multiple of these per line, so can't just use MODULE_INFO. */
#define MODULE_PARM_DESC(_parm, desc) \
@ -98,7 +96,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1997,6 +1997,13 @@ config TRIM_UNUSED_KSYMS
@@ -2233,6 +2233,13 @@ config TRIM_UNUSED_KSYMS
If unsure, or if you need to build out-of-tree modules, say N.
@ -114,7 +112,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
config MODULES_TREE_LOOKUP
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -3029,9 +3029,11 @@ static int setup_load_info(struct load_i
@@ -3107,9 +3107,11 @@ static int setup_load_info(struct load_i
static int check_modinfo(struct module *mod, struct load_info *info, int flags)
{
@ -127,7 +125,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (flags & MODULE_INIT_IGNORE_VERMAGIC)
modmagic = NULL;
@@ -3052,6 +3054,7 @@ static int check_modinfo(struct module *
@@ -3130,6 +3132,7 @@ static int check_modinfo(struct module *
mod->name);
add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK);
}
@ -137,7 +135,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -1983,7 +1983,9 @@ static void read_symbols(const char *mod
@@ -2051,7 +2051,9 @@ static void read_symbols(const char *mod
symname = remove_dot(info.strtab + sym->st_name);
handle_modversions(mod, &info, sym, symname);
@ -145,9 +143,9 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
handle_moddevtable(mod, &info, sym, symname);
+#endif
}
if (!is_vmlinux(modname) || vmlinux_section_warnings)
check_sec_ref(mod, modname, &info);
@@ -2146,8 +2148,10 @@ static void add_header(struct buffer *b,
/* Apply symbol namespaces from __kstrtabns_<symbol> entries. */
@@ -2265,8 +2267,10 @@ static void add_header(struct buffer *b,
buf_printf(b, "\n");
buf_printf(b, "BUILD_SALT;\n");
buf_printf(b, "\n");
@ -157,8 +155,8 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+#endif
buf_printf(b, "\n");
buf_printf(b, "__visible struct module __this_module\n");
buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n");
@@ -2164,8 +2168,10 @@ static void add_header(struct buffer *b,
buf_printf(b, "__section(.gnu.linkonce.this_module) = {\n");
@@ -2283,8 +2287,10 @@ static void add_header(struct buffer *b,
static void add_intree_flag(struct buffer *b, int is_intree)
{
@ -169,7 +167,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
}
/* Cannot check for assembler */
@@ -2178,8 +2184,10 @@ static void add_retpoline(struct buffer
@@ -2297,8 +2303,10 @@ static void add_retpoline(struct buffer
static void add_staging_flag(struct buffer *b, const char *name)
{
@ -180,7 +178,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
}
/**
@@ -2278,11 +2286,13 @@ static void add_depends(struct buffer *b
@@ -2382,11 +2390,13 @@ static void add_depends(struct buffer *b
static void add_srcversion(struct buffer *b, struct module *mod)
{
@ -194,10 +192,10 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
}
static void write_if_changed(struct buffer *b, const char *fname)
@@ -2519,7 +2529,9 @@ int main(int argc, char **argv)
@@ -2656,7 +2666,9 @@ int main(int argc, char **argv)
add_staging_flag(&buf, mod->name);
err |= add_versions(&buf, mod);
add_depends(&buf, mod, modules);
add_depends(&buf, mod);
+#ifndef CONFIG_MODULE_STRIPPED
add_moddevtable(&buf, mod);
+#endif

View File

@ -1,44 +0,0 @@
From c9ef4ab0f54356ee9f91d9676ea0ec123840ddc7 Mon Sep 17 00:00:00 2001
From: Felix Fietkau <nbd@nbd.name>
Date: Fri, 7 Jul 2017 16:57:33 +0200
Subject: kernel: do not build modules.order
It is not needed for anything on the system and skipping this saves some
build time, especially in cases where there is nothing to do.
lede-commit: afc1675833a7bf5df094f59f7250369520646d04
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
Makefile | 2 --
scripts/Makefile.build | 2 +-
2 files changed, 1 insertion(+), 3 deletions(-)
--- a/Makefile
+++ b/Makefile
@@ -1232,7 +1232,6 @@ all: modules
PHONY += modules
modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) modules.builtin
- $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order
@$(kecho) ' Building modules, stage 2.';
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
@@ -1261,7 +1260,6 @@ _modinst_:
rm -f $(MODLIB)/build ; \
ln -s $(CURDIR) $(MODLIB)/build ; \
fi
- @cp -f $(objtree)/modules.order $(MODLIB)/
@cp -f $(objtree)/modules.builtin $(MODLIB)/
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -78,7 +78,7 @@ modorder-target := $(obj)/modules.order
# We keep a list of all modules in $(MODVERDIR)
__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
- $(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \
+ $(if $(KBUILD_MODULES),$(obj-m)) \
$(subdir-ym) $(always)
@:

View File

@ -13,7 +13,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/include/uapi/linux/spi/spidev.h
+++ b/include/uapi/linux/spi/spidev.h
@@ -113,7 +113,7 @@ struct spi_ioc_transfer {
@@ -117,7 +117,7 @@ struct spi_ioc_transfer {
/* not all platforms use <asm-generic/ioctl.h> or _IOC_TYPECHECK() ... */
#define SPI_MSGSIZE(N) \

View File

@ -19,45 +19,19 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
include/asm-generic/vmlinux.lds.h | 63 ++++++++++++++++++++-------------------
7 files changed, 55 insertions(+), 51 deletions(-)
--- a/Makefile
+++ b/Makefile
@@ -294,6 +294,11 @@ else
scripts/Kbuild.include: ;
include scripts/Kbuild.include
+ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION
+KBUILD_CFLAGS_KERNEL += -ffunction-sections -fdata-sections
+LDFLAGS_vmlinux += --gc-sections
+endif
+
# Read KERNELRELEASE from include/config/kernel.release (if it exists)
KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)
KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION)
@@ -782,11 +787,6 @@ ifdef CONFIG_DEBUG_SECTION_MISMATCH
KBUILD_CFLAGS += $(call cc-option, -fno-inline-functions-called-once)
endif
-ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION
-KBUILD_CFLAGS_KERNEL += -ffunction-sections -fdata-sections
-LDFLAGS_vmlinux += --gc-sections
-endif
-
# arch Makefile may override CC so keep this after arch Makefile is included
NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -98,6 +98,7 @@ config ARM
@@ -111,6 +111,7 @@ config ARM
select HAVE_UID16
select HAVE_VIRT_CPU_ACCOUNTING_GEN
select IRQ_FORCED_THREADING
+ select HAVE_LD_DEAD_CODE_DATA_ELIMINATION
select MODULES_USE_ELF_REL
select NEED_DMA_MAP_STATE
select NO_BOOTMEM
select OF_EARLY_FLATTREE if OF
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -106,6 +106,7 @@ ifeq ($(CONFIG_FUNCTION_TRACER),y)
@@ -107,6 +107,7 @@ ifeq ($(CONFIG_FUNCTION_TRACER),y)
ORIG_CFLAGS := $(KBUILD_CFLAGS)
KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
endif
@ -160,33 +134,3 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
} \
. = __stubs_start + SIZEOF(.stubs); \
__stubs_end = .; \
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -43,6 +43,7 @@ config MIPS
select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES && 64BIT
select HAVE_CBPF_JIT if (!64BIT && !CPU_MICROMIPS)
select HAVE_EBPF_JIT if (64BIT && !CPU_MICROMIPS)
+ select HAVE_LD_DEAD_CODE_DATA_ELIMINATION
select HAVE_CONTEXT_TRACKING
select HAVE_COPY_THREAD_TLS
select HAVE_C_RECORDMCOUNT
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -72,7 +72,7 @@ SECTIONS
/* Exception table for data bus errors */
__dbe_table : {
__start___dbe_table = .;
- *(__dbe_table)
+ KEEP(*(__dbe_table))
__stop___dbe_table = .;
}
@@ -123,7 +123,7 @@ SECTIONS
. = ALIGN(4);
.mips.machines.init : AT(ADDR(.mips.machines.init) - LOAD_OFFSET) {
__mips_machines_start = .;
- *(.mips.machines.init)
+ KEEP(*(.mips.machines.init))
__mips_machines_end = .;
}

View File

@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
/* Align . to a 8 byte boundary equals to maximum function alignment. */
#define ALIGN_FUNCTION() . = ALIGN(8)
@@ -372,14 +382,14 @@
@@ -405,14 +415,14 @@
/* Kernel symbol table: Normal symbols */ \
__ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \
__start___ksymtab = .; \
@ -47,7 +47,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
__stop___ksymtab_gpl = .; \
} \
\
@@ -441,7 +451,7 @@
@@ -474,7 +484,7 @@
\
/* Kernel symbol table: strings */ \
__ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \
@ -56,7 +56,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
} \
\
/* __*init sections */ \
@@ -841,6 +851,8 @@
@@ -865,6 +875,8 @@
EXIT_TEXT \
EXIT_DATA \
EXIT_CALL \
@ -64,12 +64,12 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ SYMTAB_DISCARD_GPL \
*(.discard) \
*(.discard.*) \
}
*(.modinfo) \
--- a/include/linux/export.h
+++ b/include/linux/export.h
@@ -74,12 +74,19 @@ struct kernel_symbol {
};
#endif
@@ -98,18 +98,26 @@ struct kernel_symbol {
#else
+#ifdef MODULE
+#define __EXPORT_SUFFIX(sym)
@ -77,20 +77,28 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+#define __EXPORT_SUFFIX(sym) "+" #sym
+#endif
+
/* For every exported symbol, place a struct in the __ksymtab section */
#define ___EXPORT_SYMBOL(sym, sec) \
#define ___export_symbol_common(sym, sec) \
extern typeof(sym) sym; \
__CRC_SYMBOL(sym, sec) \
__CRC_SYMBOL(sym, sec); \
static const char __kstrtab_##sym[] \
- __attribute__((section("__ksymtab_strings"), used, aligned(1))) \
+ __attribute__((section("__ksymtab_strings" \
+ __EXPORT_SUFFIX(sym)), used, aligned(1))) \
= #sym; \
__KSYMTAB_ENTRY(sym, sec)
= #sym \
/* For every exported symbol, place a struct in the __ksymtab section */
#define ___EXPORT_SYMBOL_NS(sym, sec, ns) \
___export_symbol_common(sym, sec); \
static const char __kstrtabns_##sym[] \
- __attribute__((section("__ksymtab_strings"), used, aligned(1))) \
+ __attribute__((section("__ksymtab_strings" \
+ __EXPORT_SUFFIX(sym)), used, aligned(1))) \
= #ns; \
__KSYMTAB_ENTRY_NS(sym, sec)
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -408,7 +408,7 @@ targets += $(extra-y) $(MAKECMDGOALS) $(
@@ -362,7 +362,7 @@ targets += $(extra-y) $(MAKECMDGOALS) $(
# Linker scripts preprocessor (.lds.S -> .lds)
# ---------------------------------------------------------------------------
quiet_cmd_cpp_lds_S = LDS $@

View File

@ -23,15 +23,15 @@ Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
{ {0x02, 0x21}, "lz4", unlz4 },
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -325,7 +325,7 @@ cmd_bzip2 = (cat $(filter-out FORCE,$^)
@@ -342,7 +342,7 @@ quiet_cmd_bzip2 = BZIP2 $@
# ---------------------------------------------------------------------------
quiet_cmd_lzma = LZMA $@
cmd_lzma = (cat $(filter-out FORCE,$^) | \
- lzma -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
+ lzma e -d20 -lc1 -lp2 -pb2 -eos -si -so && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
(rm -f $@ ; false)
- cmd_lzma = { cat $(real-prereqs) | lzma -9; $(size_append); } > $@
+ cmd_lzma = { cat $(real-prereqs) | lzma e -d20 -lc1 -lp2 -pb2 -eos -si -so; $(size_append); } > $@
quiet_cmd_lzo = LZO $@
cmd_lzo = { cat $(real-prereqs) | lzop -9; $(size_append); } > $@
--- a/usr/gen_initramfs_list.sh
+++ b/usr/gen_initramfs_list.sh
@@ -229,7 +229,7 @@ cpio_list=

View File

@ -9,7 +9,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -241,7 +241,6 @@ config NF_CONNTRACK_FTP
@@ -240,7 +240,6 @@ config NF_CONNTRACK_FTP
config NF_CONNTRACK_H323
tristate "H.323 protocol support"
@ -17,7 +17,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
depends on NETFILTER_ADVANCED
help
H.323 is a VoIP signalling protocol from ITU-T. As one of the most
@@ -1077,7 +1076,6 @@ config NETFILTER_XT_TARGET_SECMARK
@@ -1100,7 +1099,6 @@ config NETFILTER_XT_TARGET_SECMARK
config NETFILTER_XT_TARGET_TCPMSS
tristate '"TCPMSS" target support'

View File

@ -43,8 +43,8 @@ Signed-off-by: John Crispin <john@phrozen.org>
select CRYPTO_BLKCIPHER2
select CRYPTO_ALGAPI
@@ -64,7 +64,7 @@ config CRYPTO_BLKCIPHER2
select CRYPTO_WORKQUEUE
@@ -63,7 +63,7 @@ config CRYPTO_BLKCIPHER2
select CRYPTO_RNG2
config CRYPTO_HASH
- tristate
@ -52,7 +52,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
select CRYPTO_HASH2
select CRYPTO_ALGAPI
@@ -73,7 +73,7 @@ config CRYPTO_HASH2
@@ -72,7 +72,7 @@ config CRYPTO_HASH2
select CRYPTO_ALGAPI2
config CRYPTO_RNG
@ -73,7 +73,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
bool
--- a/drivers/ssb/Kconfig
+++ b/drivers/ssb/Kconfig
@@ -28,6 +28,7 @@ config SSB_SPROM
@@ -29,6 +29,7 @@ config SSB_SPROM
config SSB_BLOCKIO
bool
depends on SSB
@ -81,7 +81,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
config SSB_PCIHOST_POSSIBLE
bool
@@ -48,7 +49,7 @@ config SSB_PCIHOST
@@ -49,7 +50,7 @@ config SSB_PCIHOST
config SSB_B43_PCI_BRIDGE
bool
depends on SSB_PCIHOST
@ -92,7 +92,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
bool
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -377,16 +377,16 @@ config BCH_CONST_T
@@ -402,16 +402,16 @@ config BCH_CONST_T
# Textsearch support is select'ed if needed
#
config TEXTSEARCH
@ -115,7 +115,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
bool
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -10,7 +10,7 @@ config NETFILTER_INGRESS
@@ -11,7 +11,7 @@ config NETFILTER_INGRESS
infrastructure.
config NETFILTER_NETLINK
@ -126,14 +126,15 @@ Signed-off-by: John Crispin <john@phrozen.org>
bool
--- a/net/wireless/Kconfig
+++ b/net/wireless/Kconfig
@@ -1,5 +1,5 @@
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
config WIRELESS_EXT
- bool
+ bool "Wireless extensions"
config WEXT_CORE
def_bool y
@@ -11,10 +11,10 @@ config WEXT_PROC
@@ -12,10 +12,10 @@ config WEXT_PROC
depends on WEXT_CORE
config WEXT_SPY
@ -146,7 +147,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
config CFG80211
tristate "cfg80211 - wireless configuration API"
@@ -202,7 +202,7 @@ config CFG80211_WEXT_EXPORT
@@ -203,7 +203,7 @@ config CFG80211_WEXT_EXPORT
endif # CFG80211
config LIB80211
@ -155,29 +156,29 @@ Signed-off-by: John Crispin <john@phrozen.org>
default n
help
This options enables a library of common routines used
@@ -211,13 +211,16 @@ config LIB80211
@@ -212,16 +212,16 @@ config LIB80211
Drivers should select this themselves if needed.
config LIB80211_CRYPT_WEP
- tristate
+ tristate "LIB80211_CRYPT_WEP"
+ select LIB80211
select CRYPTO_LIB_ARC4
config LIB80211_CRYPT_CCMP
- tristate
+ tristate "LIB80211_CRYPT_CCMP"
+ select LIB80211
select CRYPTO_AES
select CRYPTO_CCM
config LIB80211_CRYPT_TKIP
- tristate
+ tristate "LIB80211_CRYPT_TKIP"
+ select LIB80211
select CRYPTO_LIB_ARC4
config LIB80211_DEBUG
bool "lib80211 debugging messages"
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -16,7 +16,7 @@ config SND_DMAENGINE_PCM
@@ -17,7 +17,7 @@ config SND_DMAENGINE_PCM
tristate
config SND_HWDEP
@ -186,7 +187,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
config SND_SEQ_DEVICE
tristate
@@ -26,7 +26,7 @@ config SND_RAWMIDI
@@ -27,7 +27,7 @@ config SND_RAWMIDI
select SND_SEQ_DEVICE if SND_SEQUENCER != n
config SND_COMPRESS_OFFLOAD

View File

@ -18,14 +18,14 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
# subsystems should select the appropriate symbols.
config REGMAP
- default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_W1 || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ)
- default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_W1 || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ || REGMAP_SCCB || REGMAP_I3C)
select IRQ_DOMAIN if REGMAP_IRQ
- bool
+ tristate
config REGCACHE_COMPRESSED
select LZO_COMPRESS
@@ -18,6 +17,7 @@ config REGMAP_AC97
@@ -18,38 +17,49 @@ config REGMAP_AC97
config REGMAP_I2C
tristate
@ -33,7 +33,9 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
depends on I2C
config REGMAP_SLIMBUS
@@ -26,20 +26,26 @@ config REGMAP_SLIMBUS
tristate
+ select REGMAP
depends on SLIMBUS
config REGMAP_SPI
tristate
@ -42,13 +44,13 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
depends on SPI
config REGMAP_SPMI
+ select REGMAP
tristate
+ select REGMAP
depends on SPMI
config REGMAP_W1
+ select REGMAP
tristate
+ select REGMAP
depends on W1
config REGMAP_MMIO
@ -56,10 +58,23 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ select REGMAP
config REGMAP_IRQ
+ select REGMAP
bool
+ select REGMAP
config REGMAP_SOUNDWIRE
tristate
+ select REGMAP
depends on SOUNDWIRE
config REGMAP_SCCB
tristate
+ select REGMAP
depends on I2C
config REGMAP_I3C
tristate
+ select REGMAP
depends on I3C
--- a/drivers/base/regmap/Makefile
+++ b/drivers/base/regmap/Makefile
@@ -2,10 +2,14 @@
@ -83,7 +98,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
obj-$(CONFIG_REGMAP_SLIMBUS) += regmap-slimbus.o
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -13,6 +13,7 @@
@@ -9,6 +9,7 @@
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/export.h>
@ -91,7 +106,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
#include <linux/mutex.h>
#include <linux/err.h>
#include <linux/of.h>
@@ -3039,3 +3040,5 @@ static int __init regmap_initcall(void)
@@ -3124,3 +3125,5 @@ static int __init regmap_initcall(void)
return 0;
}
postcore_initcall(regmap_initcall);
@ -99,7 +114,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+MODULE_LICENSE("GPL");
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -187,7 +187,7 @@ struct reg_sequence {
@@ -185,7 +185,7 @@ struct reg_sequence {
pollret ?: ((cond) ? 0 : -ETIMEDOUT); \
})

View File

@ -14,7 +14,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -144,13 +144,13 @@ config CRYPTO_MANAGER
@@ -120,13 +120,13 @@ config CRYPTO_MANAGER
cbc(aes).
config CRYPTO_MANAGER2
@ -35,17 +35,27 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
config CRYPTO_USER
tristate "Userspace cryptographic algorithm configuration"
@@ -163,7 +163,6 @@ config CRYPTO_USER
@@ -136,8 +136,6 @@ config CRYPTO_USER
Userspace configuration for cryptographic instantiations such as
cbc(aes).
-if CRYPTO_MANAGER2
-
config CRYPTO_MANAGER_DISABLE_TESTS
bool "Disable run-time self tests"
default y
- depends on CRYPTO_MANAGER2
help
@@ -145,6 +143,8 @@ config CRYPTO_MANAGER_DISABLE_TESTS
Disable run-time self tests that normally take place at
algorithm registration.
+if CRYPTO_MANAGER2
+
config CRYPTO_MANAGER_EXTRA_TESTS
bool "Enable extra run-time crypto self tests"
depends on DEBUG_KERNEL && !CRYPTO_MANAGER_DISABLE_TESTS
--- a/crypto/algboss.c
+++ b/crypto/algboss.c
@@ -247,8 +247,12 @@ static int cryptomgr_schedule_test(struc
@@ -242,8 +242,12 @@ static int cryptomgr_schedule_test(struc
type = alg->cra_flags;
/* Do not test internal algorithms. */

View File

@ -0,0 +1,15 @@
This makes it possible to select CONFIG_CRYPTO_LIB_ARC4 directly. We
need this to be able to compile this into the kernel and make use of it
from backports.
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -1151,7 +1151,7 @@ config CRYPTO_ANUBIS
<http://www.larc.usp.br/~pbarreto/AnubisPage.html>
config CRYPTO_LIB_ARC4
- tristate
+ tristate "ARC4 cipher library"
config CRYPTO_ARC4
tristate "ARC4 cipher algorithm"

View File

@ -37,7 +37,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
ifneq ($(CONFIG_DCB),)
--- a/net/rfkill/Kconfig
+++ b/net/rfkill/Kconfig
@@ -1,7 +1,11 @@
@@ -2,7 +2,11 @@
#
# RF switch subsystem configuration
#
@ -50,7 +50,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
tristate "RF switch subsystem support"
help
Say Y here if you want to have control over RF switches
@@ -13,19 +17,19 @@ menuconfig RFKILL
@@ -14,19 +18,19 @@ menuconfig RFKILL
# LED trigger support
config RFKILL_LEDS
bool
@ -75,7 +75,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
help
--- a/net/rfkill/Makefile
+++ b/net/rfkill/Makefile
@@ -4,5 +4,5 @@
@@ -5,5 +5,5 @@
rfkill-y += core.o
rfkill-$(CONFIG_RFKILL_INPUT) += input.o

View File

@ -14,7 +14,8 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -1,5 +1,5 @@
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
menuconfig NVMEM
- bool "NVMEM Support"
+ tristate "NVMEM Support"
@ -23,7 +24,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -71,6 +71,7 @@ config OF_IRQ
@@ -72,6 +72,7 @@ config OF_IRQ
config OF_NET
depends on NETDEVICES

View File

@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
--- a/arch/mips/include/asm/r4kcache.h
+++ b/arch/mips/include/asm/r4kcache.h
@@ -683,16 +683,48 @@ static inline void prot##extra##blast_##
@@ -617,14 +617,46 @@ static inline void prot##extra##blast_##
unsigned long end) \
{ \
unsigned long lsize = cpu_##desc##_line_size(); \
@ -26,8 +26,6 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ unsigned long aend = (end + lsize - 1) & ~(lsize - 1); \
+ int lines = (aend - addr) / lsize; \
\
__##pfx##flush_prologue \
\
- while (1) { \
+ while (lines >= 8) { \
+ prot##cache_op(hitop, addr); \
@ -62,5 +60,5 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
- break; \
- addr += lsize; \
} \
\
__##pfx##flush_epilogue \
}

View File

@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1144,6 +1144,10 @@ config SYNC_R4K
@@ -1156,6 +1156,10 @@ config SYNC_R4K
config MIPS_MACHINE
def_bool n
@ -25,7 +25,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+++ b/arch/mips/kernel/head.S
@@ -79,6 +79,12 @@ FEXPORT(__kernel_entry)
j kernel_entry
#endif
#endif /* CONFIG_BOOT_RAW */
+#ifdef CONFIG_IMAGE_CMDLINE_HACK
+ .ascii "CMDLINE:"

View File

@ -16,7 +16,7 @@ Signed-off-by: Alexandros C. Couloumbis <alex@ozo.com>
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -60,20 +60,6 @@ machine-$(CONFIG_PPC64) += 64
@@ -61,20 +61,6 @@ machine-$(CONFIG_PPC64) += 64
machine-$(CONFIG_CPU_LITTLE_ENDIAN) += le
UTS_MACHINE := $(subst $(space),,$(machine-y))
@ -24,7 +24,7 @@ Signed-off-by: Alexandros C. Couloumbis <alex@ozo.com>
-ifdef CONFIG_PPC32
-KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o
-else
-KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/powerpc/kernel/module.lds
-KBUILD_LDS_MODULE += $(srctree)/arch/powerpc/kernel/module.lds
-ifeq ($(call ld-ifversion, -ge, 225000000, y),y)
-# Have the linker provide sfpr if possible.
-# There is a corresponding test in arch/powerpc/lib/Makefile

View File

@ -18,7 +18,7 @@ Reviewed-by: Bart Van Assche <bvanassche@acm.org>
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -460,7 +460,7 @@ static void lo_complete_rq(struct reques
@@ -461,7 +461,7 @@ static void lo_complete_rq(struct reques
if (!cmd->use_aio || cmd->ret < 0 || cmd->ret == blk_rq_bytes(rq) ||
req_op(rq) != REQ_OP_READ) {
if (cmd->ret < 0)
@ -27,7 +27,7 @@ Reviewed-by: Bart Van Assche <bvanassche@acm.org>
goto end_io;
}
@@ -1904,7 +1904,10 @@ static void loop_handle_cmd(struct loop_
@@ -1950,7 +1950,10 @@ static void loop_handle_cmd(struct loop_
failed:
/* complete non-aio request */
if (!cmd->use_aio || ret) {

View File

@ -28,7 +28,7 @@ Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -426,11 +426,12 @@ static int lo_fallocate(struct loop_devi
@@ -427,11 +427,12 @@ static int lo_fallocate(struct loop_devi
* information.
*/
struct file *file = lo->lo_backing_file;
@ -42,7 +42,7 @@ Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
ret = -EOPNOTSUPP;
goto out;
}
@@ -863,6 +864,21 @@ static void loop_config_discard(struct l
@@ -862,6 +863,21 @@ static void loop_config_discard(struct l
struct file *file = lo->lo_backing_file;
struct inode *inode = file->f_mapping->host;
struct request_queue *q = lo->lo_queue;
@ -64,7 +64,7 @@ Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
/*
* We use punch hole to reclaim the free space used by the
@@ -870,22 +886,24 @@ static void loop_config_discard(struct l
@@ -869,22 +885,24 @@ static void loop_config_discard(struct l
* encryption is enabled, because it may give an attacker
* useful information.
*/

View File

@ -12,7 +12,7 @@ Signed-off-by: Etienne Champetier <champetier.etienne@gmail.com>
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -108,10 +108,14 @@ int br_handle_frame_finish(struct net *n
@@ -103,10 +103,14 @@ int br_handle_frame_finish(struct net *n
}
}
@ -30,7 +30,7 @@ Signed-off-by: Etienne Champetier <champetier.etienne@gmail.com>
if (IS_ENABLED(CONFIG_INET) &&
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -337,6 +337,8 @@ struct net_bridge {
@@ -345,6 +345,8 @@ struct net_bridge {
u16 group_fwd_mask;
u16 group_fwd_mask_required;
@ -41,7 +41,7 @@ Signed-off-by: Etienne Champetier <champetier.etienne@gmail.com>
bridge_id bridge_id;
--- a/net/bridge/br_sysfs_br.c
+++ b/net/bridge/br_sysfs_br.c
@@ -170,6 +170,30 @@ static ssize_t group_fwd_mask_store(stru
@@ -166,6 +166,30 @@ static ssize_t group_fwd_mask_store(stru
}
static DEVICE_ATTR_RW(group_fwd_mask);
@ -72,7 +72,7 @@ Signed-off-by: Etienne Champetier <champetier.etienne@gmail.com>
static ssize_t priority_show(struct device *d, struct device_attribute *attr,
char *buf)
{
@@ -810,6 +834,7 @@ static struct attribute *bridge_attrs[]
@@ -851,6 +875,7 @@ static struct attribute *bridge_attrs[]
&dev_attr_ageing_time.attr,
&dev_attr_stp_state.attr,
&dev_attr_group_fwd_mask.attr,

View File

@ -109,7 +109,7 @@ Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
__u8 invert;
--- a/net/netfilter/xt_connmark.c
+++ b/net/netfilter/xt_connmark.c
@@ -36,12 +36,13 @@ MODULE_ALIAS("ipt_connmark");
@@ -24,12 +24,13 @@ MODULE_ALIAS("ipt_connmark");
MODULE_ALIAS("ip6t_connmark");
static unsigned int
@ -124,7 +124,7 @@ Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
ct = nf_ct_get(skb, &ctinfo);
if (ct == NULL)
@@ -49,12 +50,24 @@ connmark_tg_shift(struct sk_buff *skb, c
@@ -37,12 +38,24 @@ connmark_tg_shift(struct sk_buff *skb, c
switch (info->mode) {
case XT_CONNMARK_SET:
@ -154,7 +154,7 @@ Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
if (ct->mark != newmark) {
ct->mark = newmark;
nf_conntrack_event_cache(IPCT_MARK, ct);
@@ -93,20 +106,36 @@ static unsigned int
@@ -81,20 +94,36 @@ static unsigned int
connmark_tg(struct sk_buff *skb, const struct xt_action_param *par)
{
const struct xt_connmark_tginfo1 *info = par->targinfo;
@ -193,7 +193,7 @@ Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
return connmark_tg_shift(skb, info);
}
@@ -177,6 +206,16 @@ static struct xt_target connmark_tg_reg[
@@ -165,6 +194,16 @@ static struct xt_target connmark_tg_reg[
.targetsize = sizeof(struct xt_connmark_tginfo2),
.destroy = connmark_tg_destroy,
.me = THIS_MODULE,

View File

@ -1,6 +1,6 @@
--- a/include/net/netfilter/nf_flow_table.h
+++ b/include/net/netfilter/nf_flow_table.h
@@ -163,6 +163,8 @@ struct nf_flow_table_hw {
@@ -158,6 +158,8 @@ struct nf_flow_table_hw {
int nf_flow_table_hw_register(const struct nf_flow_table_hw *offload);
void nf_flow_table_hw_unregister(const struct nf_flow_table_hw *offload);
@ -11,15 +11,15 @@
#define MODULE_ALIAS_NF_FLOWTABLE(family) \
--- a/net/netfilter/nf_flow_table_core.c
+++ b/net/netfilter/nf_flow_table_core.c
@@ -11,6 +11,7 @@
#include <net/netfilter/nf_conntrack.h>
@@ -13,6 +13,7 @@
#include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_l4proto.h>
#include <net/netfilter/nf_conntrack_tuple.h>
+#include <net/netfilter/nf_conntrack_acct.h>
struct flow_offload_entry {
struct flow_offload flow;
@@ -149,6 +150,22 @@ void flow_offload_free(struct flow_offlo
@@ -164,6 +165,22 @@ void flow_offload_free(struct flow_offlo
}
EXPORT_SYMBOL_GPL(flow_offload_free);
@ -44,7 +44,7 @@
const struct flow_offload_tuple *tuple = data;
--- a/net/netfilter/nf_flow_table_ip.c
+++ b/net/netfilter/nf_flow_table_ip.c
@@ -11,6 +11,7 @@
@@ -12,6 +12,7 @@
#include <net/ip6_route.h>
#include <net/neighbour.h>
#include <net/netfilter/nf_flow_table.h>
@ -52,7 +52,7 @@
/* For layer 4 checksum field offset. */
#include <linux/tcp.h>
#include <linux/udp.h>
@@ -267,6 +268,7 @@ nf_flow_offload_ip_hook(void *priv, stru
@@ -295,6 +296,7 @@ nf_flow_offload_ip_hook(void *priv, stru
skb->dev = outdev;
nexthop = rt_nexthop(rt, flow->tuplehash[!dir].tuple.src_v4.s_addr);
skb_dst_set_noref(skb, &rt->dst);
@ -60,7 +60,7 @@
neigh_xmit(NEIGH_ARP_TABLE, outdev, &nexthop, skb);
return NF_STOLEN;
@@ -487,6 +489,7 @@ nf_flow_offload_ipv6_hook(void *priv, st
@@ -524,6 +526,7 @@ nf_flow_offload_ipv6_hook(void *priv, st
skb->dev = outdev;
nexthop = rt6_nexthop(rt, &flow->tuplehash[!dir].tuple.src_v6);
skb_dst_set_noref(skb, &rt->dst);

View File

@ -8,7 +8,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -63,8 +63,6 @@ config NF_TABLES_ARP
@@ -56,8 +56,6 @@ config NF_TABLES_ARP
help
This option enables the ARP support for nf_tables.
@ -17,7 +17,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
config NF_FLOW_TABLE_IPV4
tristate "Netfilter flow table IPv4 module"
depends on NF_FLOW_TABLE
@@ -73,6 +71,8 @@ config NF_FLOW_TABLE_IPV4
@@ -66,6 +64,8 @@ config NF_FLOW_TABLE_IPV4
To compile it as a module, choose M here.
@ -28,7 +28,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
depends on !NF_CONNTRACK || NF_CONNTRACK
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -80,7 +80,6 @@ config NFT_FIB_IPV6
@@ -45,7 +45,6 @@ config NFT_FIB_IPV6
multicast or blackhole.
endif # NF_TABLES_IPV6
@ -36,7 +36,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
config NF_FLOW_TABLE_IPV6
tristate "Netfilter flow table IPv6 module"
@@ -90,6 +89,8 @@ config NF_FLOW_TABLE_IPV6
@@ -55,6 +54,8 @@ config NF_FLOW_TABLE_IPV6
To compile it as a module, choose M here.
@ -47,7 +47,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
depends on !NF_CONNTRACK || NF_CONNTRACK
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -693,8 +693,6 @@ config NFT_FIB_NETDEV
@@ -702,8 +702,6 @@ config NFT_FIB_NETDEV
endif # NF_TABLES_NETDEV
@ -56,7 +56,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
config NF_FLOW_TABLE_INET
tristate "Netfilter flow table mixed IPv4/IPv6 module"
depends on NF_FLOW_TABLE
@@ -703,11 +701,12 @@ config NF_FLOW_TABLE_INET
@@ -712,11 +710,12 @@ config NF_FLOW_TABLE_INET
To compile it as a module, choose M here.
@ -70,7 +70,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
help
This option adds the flow table core infrastructure.
@@ -996,6 +995,15 @@ config NETFILTER_XT_TARGET_NOTRACK
@@ -1005,6 +1004,15 @@ config NETFILTER_XT_TARGET_NOTRACK
depends on NETFILTER_ADVANCED
select NETFILTER_XT_TARGET_CT
@ -98,7 +98,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
--- /dev/null
+++ b/net/netfilter/xt_FLOWOFFLOAD.c
@@ -0,0 +1,422 @@
@@ -0,0 +1,427 @@
+/*
+ * Copyright (C) 2018 Felix Fietkau <nbd@nbd.name>
+ *
@ -143,6 +143,10 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ return NF_ACCEPT;
+}
+
+int nf_flow_table_iterate(struct nf_flowtable *flow_table,
+ void (*iter)(struct flow_offload *flow, void *data),
+ void *data);
+
+static int
+xt_flowoffload_create_hook(struct net_device *dev)
+{
@ -240,11 +244,12 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ struct flow_offload_tuple *tuple = &flow->tuplehash[0].tuple;
+ struct xt_flowoffload_hook *hook;
+ bool *found = data;
+ struct rtable *rt = (struct rtable *)tuple->dst_cache;
+
+ spin_lock_bh(&hooks_lock);
+ hlist_for_each_entry(hook, &hooks, list) {
+ if (hook->ops.dev->ifindex != tuple->iifidx &&
+ hook->ops.dev->ifindex != tuple->oifidx)
+ hook->ops.dev->ifindex != rt->dst.dev->ifindex)
+ continue;
+
+ hook->used = true;
@ -483,7 +488,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ kfree(hook);
+ }
+
+ nf_flow_table_cleanup(dev_net(dev), dev);
+ nf_flow_table_cleanup(dev);
+
+ return NOTIFY_DONE;
+}
@ -523,7 +528,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+module_exit(xt_flowoffload_tg_exit);
--- a/net/netfilter/nf_flow_table_core.c
+++ b/net/netfilter/nf_flow_table_core.c
@@ -6,7 +6,6 @@
@@ -7,7 +7,6 @@
#include <linux/netdevice.h>
#include <net/ip.h>
#include <net/ip6_route.h>
@ -531,6 +536,24 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
#include <net/netfilter/nf_flow_table.h>
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_core.h>
@@ -338,8 +337,7 @@ flow_offload_lookup(struct nf_flowtable
}
EXPORT_SYMBOL_GPL(flow_offload_lookup);
-static int
-nf_flow_table_iterate(struct nf_flowtable *flow_table,
+int nf_flow_table_iterate(struct nf_flowtable *flow_table,
void (*iter)(struct flow_offload *flow, void *data),
void *data)
{
@@ -372,6 +370,7 @@ nf_flow_table_iterate(struct nf_flowtabl
return err;
}
+EXPORT_SYMBOL_GPL(nf_flow_table_iterate);
static void nf_flow_offload_gc_step(struct flow_offload *flow, void *data)
{
--- /dev/null
+++ b/include/uapi/linux/netfilter/xt_FLOWOFFLOAD.h
@@ -0,0 +1,17 @@
@ -551,3 +574,16 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+};
+
+#endif /* _XT_FLOWOFFLOAD_H */
--- a/include/net/netfilter/nf_flow_table.h
+++ b/include/net/netfilter/nf_flow_table.h
@@ -128,6 +128,10 @@ static inline void flow_offload_dead(str
flow->flags |= FLOW_OFFLOAD_DYING;
}
+int nf_flow_table_iterate(struct nf_flowtable *flow_table,
+ void (*iter)(struct flow_offload *flow, void *data),
+ void *data);
+
int nf_flow_snat_port(const struct flow_offload *flow,
struct sk_buff *skb, unsigned int thoff,
u8 protocol, enum flow_offload_tuple_dir dir);

View File

@ -11,7 +11,7 @@ Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -140,8 +140,8 @@ static inline bool dev_xmit_complete(int
@@ -136,8 +136,8 @@ static inline bool dev_xmit_complete(int
#if defined(CONFIG_HYPERV_NET)
# define LL_MAX_HEADER 128

View File

@ -13,7 +13,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/net/sched/sch_fq_codel.c
+++ b/net/sched/sch_fq_codel.c
@@ -474,7 +474,11 @@ static int fq_codel_init(struct Qdisc *s
@@ -462,7 +462,11 @@ static int fq_codel_init(struct Qdisc *s
sch->limit = 10*1024;
q->flows_cnt = 1024;

View File

@ -14,7 +14,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -487,12 +487,13 @@ extern struct Qdisc_ops noop_qdisc_ops;
@@ -569,12 +569,13 @@ extern struct Qdisc_ops noop_qdisc_ops;
extern struct Qdisc_ops pfifo_fast_ops;
extern struct Qdisc_ops mq_qdisc_ops;
extern struct Qdisc_ops noqueue_qdisc_ops;
@ -31,7 +31,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
struct Qdisc_class_common {
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -3,8 +3,9 @@
@@ -4,8 +4,9 @@
#
menuconfig NET_SCHED
@ -44,7 +44,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
device, it has to decide which ones to send first, which ones to
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -2162,7 +2162,7 @@ static int __init pktsched_init(void)
@@ -2271,7 +2271,7 @@ static int __init pktsched_init(void)
return err;
}
@ -55,7 +55,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
register_qdisc(&pfifo_head_drop_qdisc_ops);
--- a/net/sched/sch_fq_codel.c
+++ b/net/sched/sch_fq_codel.c
@@ -714,7 +714,7 @@ static const struct Qdisc_class_ops fq_c
@@ -702,7 +702,7 @@ static const struct Qdisc_class_ops fq_c
.walk = fq_codel_walk,
};
@ -64,7 +64,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
.cl_ops = &fq_codel_class_ops,
.id = "fq_codel",
.priv_size = sizeof(struct fq_codel_sched_data),
@@ -729,6 +729,7 @@ static struct Qdisc_ops fq_codel_qdisc_o
@@ -717,6 +717,7 @@ static struct Qdisc_ops fq_codel_qdisc_o
.dump_stats = fq_codel_dump_stats,
.owner = THIS_MODULE,
};
@ -74,7 +74,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
{
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -35,7 +35,7 @@
@@ -32,7 +32,7 @@
#include <net/xfrm.h>
/* Qdisc to use by default */
@ -83,7 +83,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
EXPORT_SYMBOL(default_qdisc_ops);
/* Main transmission queue. */
@@ -1025,7 +1025,7 @@ static void attach_one_default_qdisc(str
@@ -1034,12 +1034,12 @@ static void attach_one_default_qdisc(str
void *_unused)
{
struct Qdisc *qdisc;
@ -92,3 +92,9 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (dev->priv_flags & IFF_NO_QUEUE)
ops = &noqueue_qdisc_ops;
else if(dev->type == ARPHRD_CAN)
- ops = &pfifo_fast_ops;
+ ops = &fq_codel_qdisc_ops;
qdisc = qdisc_create_dflt(dev_queue, ops, TC_H_ROOT, NULL);
if (!qdisc) {

View File

@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -612,207 +612,6 @@ struct Qdisc_ops noqueue_qdisc_ops __rea
@@ -594,211 +594,6 @@ struct Qdisc_ops noqueue_qdisc_ops __rea
.owner = THIS_MODULE,
};
@ -49,14 +49,14 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
-
- err = skb_array_produce(q, skb);
-
- if (unlikely(err))
- return qdisc_drop_cpu(skb, qdisc, to_free);
- if (unlikely(err)) {
- if (qdisc_is_percpu_stats(qdisc))
- return qdisc_drop_cpu(skb, qdisc, to_free);
- else
- return qdisc_drop(skb, qdisc, to_free);
- }
-
- qdisc_qstats_atomic_qlen_inc(qdisc);
- /* Note: skb can not be used after skb_array_produce(),
- * so we better not use qdisc_qstats_cpu_backlog_inc()
- */
- this_cpu_add(qdisc->cpu_qstats->backlog, pkt_len);
- qdisc_update_stats_at_enqueue(qdisc, pkt_len);
- return NET_XMIT_SUCCESS;
-}
-
@ -75,9 +75,9 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
- skb = __skb_array_consume(q);
- }
- if (likely(skb)) {
- qdisc_qstats_cpu_backlog_dec(qdisc, skb);
- qdisc_bstats_cpu_update(qdisc, skb);
- qdisc_qstats_atomic_qlen_dec(qdisc);
- qdisc_update_stats_at_dequeue(qdisc, skb);
- } else {
- WRITE_ONCE(qdisc->empty, true);
- }
-
- return skb;
@ -117,10 +117,14 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
- kfree_skb(skb);
- }
-
- for_each_possible_cpu(i) {
- struct gnet_stats_queue *q = per_cpu_ptr(qdisc->cpu_qstats, i);
- if (qdisc_is_percpu_stats(qdisc)) {
- for_each_possible_cpu(i) {
- struct gnet_stats_queue *q;
-
- q->backlog = 0;
- q = per_cpu_ptr(qdisc->cpu_qstats, i);
- q->backlog = 0;
- q->qlen = 0;
- }
- }
-}
-
@ -215,6 +219,6 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
-};
-EXPORT_SYMBOL(pfifo_fast_ops);
-
static struct lock_class_key qdisc_tx_busylock;
static struct lock_class_key qdisc_running_key;
struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
const struct Qdisc_ops *ops,
struct netlink_ext_ack *extack)

View File

@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -209,6 +209,89 @@ config LED_TRIGGER_PHY
@@ -249,6 +249,89 @@ config LED_TRIGGER_PHY
for any speed known to the PHY.
@ -123,9 +123,9 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+obj-$(CONFIG_RTL8367_PHY) += rtl8367.o
+obj-$(CONFIG_RTL8367B_PHY) += rtl8367b.o
+
obj-$(CONFIG_MDIO_ASPEED) += mdio-aspeed.o
obj-$(CONFIG_MDIO_BCM_IPROC) += mdio-bcm-iproc.o
obj-$(CONFIG_MDIO_BCM_UNIMAC) += mdio-bcm-unimac.o
obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o
--- a/include/linux/platform_data/b53.h
+++ b/include/linux/platform_data/b53.h
@@ -29,6 +29,9 @@ struct b53_platform_data {

View File

@ -1,6 +1,6 @@
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -555,6 +555,12 @@ struct phy_driver {
@@ -522,6 +522,12 @@ struct phy_driver {
/* Determines the negotiated speed and duplex */
int (*read_status)(struct phy_device *phydev);
@ -15,9 +15,9 @@
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1577,6 +1577,9 @@ int genphy_update_link(struct phy_device
{
int status;
@@ -1822,6 +1822,9 @@ int genphy_update_link(struct phy_device
if (bmcr & BMCR_ANRESTART)
goto done;
+ if (phydev->drv && phydev->drv->update_link)
+ return phydev->drv->update_link(phydev);

View File

@ -15,7 +15,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1514,6 +1514,7 @@ enum netdev_priv_flags {
@@ -1544,6 +1544,7 @@ enum netdev_priv_flags {
IFF_FAILOVER_SLAVE = 1<<28,
IFF_L3MDEV_RX_HANDLER = 1<<29,
IFF_LIVE_RENAME_OK = 1<<30,
@ -23,7 +23,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
};
#define IFF_802_1Q_VLAN IFF_802_1Q_VLAN
@@ -1546,6 +1547,7 @@ enum netdev_priv_flags {
@@ -1576,6 +1577,7 @@ enum netdev_priv_flags {
#define IFF_FAILOVER_SLAVE IFF_FAILOVER_SLAVE
#define IFF_L3MDEV_RX_HANDLER IFF_L3MDEV_RX_HANDLER
#define IFF_LIVE_RENAME_OK IFF_LIVE_RENAME_OK
@ -31,7 +31,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
/**
* struct net_device - The DEVICE structure.
@@ -1846,6 +1848,11 @@ struct net_device {
@@ -1877,6 +1879,11 @@ struct net_device {
const struct tlsdev_ops *tlsdev_ops;
#endif
@ -43,7 +43,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
const struct header_ops *header_ops;
unsigned int flags;
@@ -1928,6 +1935,10 @@ struct net_device {
@@ -1959,6 +1966,10 @@ struct net_device {
struct mpls_dev __rcu *mpls_ptr;
#endif
@ -56,7 +56,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
*/
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2547,6 +2547,10 @@ static inline int pskb_trim(struct sk_bu
@@ -2665,6 +2665,10 @@ static inline int pskb_trim(struct sk_bu
return (len < skb->len) ? __pskb_trim(skb, len) : 0;
}
@ -67,7 +67,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
/**
* pskb_trim_unique - remove end from a paged unique (not cloned) buffer
* @skb: buffer to alter
@@ -2678,16 +2682,6 @@ static inline struct sk_buff *dev_alloc_
@@ -2796,16 +2800,6 @@ static inline struct sk_buff *dev_alloc_
}
@ -86,7 +86,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
{
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -25,6 +25,12 @@ menuconfig NET
@@ -26,6 +26,12 @@ menuconfig NET
if NET
@ -101,8 +101,8 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
help
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3253,10 +3253,20 @@ static int xmit_one(struct sk_buff *skb,
if (!list_empty(&ptype_all) || !list_empty(&dev->ptype_all))
@@ -3194,10 +3194,20 @@ static int xmit_one(struct sk_buff *skb,
if (dev_nit_active(dev))
dev_queue_xmit_nit(skb, dev);
- len = skb->len;
@ -128,15 +128,15 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
}
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -63,6 +63,7 @@
#include <linux/errqueue.h>
@@ -60,6 +60,7 @@
#include <linux/prefetch.h>
#include <linux/if_vlan.h>
#include <linux/mpls.h>
+#include <linux/if.h>
#include <net/protocol.h>
#include <net/dst.h>
@@ -503,6 +504,22 @@ skb_fail:
@@ -540,6 +541,22 @@ skb_fail:
}
EXPORT_SYMBOL(__napi_alloc_skb);
@ -161,7 +161,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
{
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -172,6 +172,12 @@ __be16 eth_type_trans(struct sk_buff *sk
@@ -171,6 +171,12 @@ __be16 eth_type_trans(struct sk_buff *sk
const struct ethhdr *eth;
skb->dev = dev;

Some files were not shown because too many files have changed in this diff Show More