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:
		
							parent
							
								
									c16517d26d
								
							
						
					
					
						commit
						4e0c54bc5b
					
				| @ -8,9 +8,11 @@ endif | |||||||
| 
 | 
 | ||||||
| LINUX_VERSION-4.14 = .171 | LINUX_VERSION-4.14 = .171 | ||||||
| LINUX_VERSION-4.19 = .106 | LINUX_VERSION-4.19 = .106 | ||||||
|  | LINUX_VERSION-5.4 = .22 | ||||||
| 
 | 
 | ||||||
| LINUX_KERNEL_HASH-4.14.171 = 4fe02489e4b4a187eccf0ef87df6100534c9d485e76d876b1fa247c7635332a0 | LINUX_KERNEL_HASH-4.14.171 = 4fe02489e4b4a187eccf0ef87df6100534c9d485e76d876b1fa247c7635332a0 | ||||||
| LINUX_KERNEL_HASH-4.19.106 = 63c8bd76a9b282e18112f8ff9e3fd41e3d1df9f9b7248ea1a370b05a827e9cda | LINUX_KERNEL_HASH-4.19.106 = 63c8bd76a9b282e18112f8ff9e3fd41e3d1df9f9b7248ea1a370b05a827e9cda | ||||||
|  | LINUX_KERNEL_HASH-5.4.22 = 661bcb8d7e390dcc28e53795485e648f2bdc9b697b731459cc2bcc9ceb4a7d1a | ||||||
| 
 | 
 | ||||||
| remove_uri_prefix=$(subst git://,,$(subst http://,,$(subst https://,,$(1)))) | remove_uri_prefix=$(subst git://,,$(subst http://,,$(subst https://,,$(1)))) | ||||||
| sanitize_uri=$(call qstrip,$(subst @,_,$(subst :,_,$(subst .,_,$(subst -,_,$(subst /,_,$(1))))))) | sanitize_uri=$(call qstrip,$(subst @,_,$(subst :,_,$(subst .,_,$(subst -,_,$(subst /,_,$(1))))))) | ||||||
|  | |||||||
| @ -10,14 +10,15 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| 
 | 
 | ||||||
| --- a/Makefile
 | --- a/Makefile
 | ||||||
| +++ b/Makefile
 | +++ b/Makefile
 | ||||||
| @@ -432,8 +432,8 @@ KBUILD_LDFLAGS :=
 | @@ -471,8 +471,9 @@ KBUILD_LDFLAGS :=
 | ||||||
|  GCC_PLUGINS_CFLAGS := |  GCC_PLUGINS_CFLAGS := | ||||||
|  CLANG_FLAGS := |  CLANG_FLAGS := | ||||||
|   |   | ||||||
| -export ARCH SRCARCH CONFIG_SHELL HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE AS LD CC
 | -export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE AS LD CC
 | ||||||
| -export CPP AR NM STRIP OBJCOPY OBJDUMP KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS
 | -export CPP AR NM STRIP OBJCOPY OBJDUMP OBJSIZE PAHOLE LEX YACC AWK INSTALLKERNEL
 | ||||||
| +export ARCH SRCARCH SUBARCH CONFIG_SHELL HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE AS LD
 | +export ARCH SRCARCH SUBARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE AS LD
 | ||||||
| +export CC CPP AR NM STRIP OBJCOPY OBJDUMP KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS
 | +export CC CPP AR NM STRIP OBJCOPY OBJDUMP OBJSIZE PAHOLE LEX YACC AWK INSTALLKERNEL
 | ||||||
|  export MAKE LEX YACC AWK GENKSYMS INSTALLKERNEL PERL PYTHON PYTHON2 PYTHON3 UTS_MACHINE | +
 | ||||||
|  export HOSTCXX KBUILD_HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS |  export PERL PYTHON PYTHON2 PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX | ||||||
|  |  export KBUILD_HOSTCXXFLAGS KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS LDFLAGS_MODULE | ||||||
|   |   | ||||||
|  | |||||||
| @ -94,7 +94,7 @@ Signed-off-by: Florian Westphal <fw@strlen.de> | |||||||
| +}
 | +}
 | ||||||
| --- a/net/netfilter/Kconfig
 | --- a/net/netfilter/Kconfig
 | ||||||
| +++ b/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'. |  	  If unsure, say `N'. | ||||||
|   |   | ||||||
| @ -115,16 +115,16 @@ Signed-off-by: Florian Westphal <fw@strlen.de> | |||||||
|  	depends on NETFILTER_ADVANCED |  	depends on NETFILTER_ADVANCED | ||||||
| --- a/net/netfilter/Makefile
 | --- a/net/netfilter/Makefile
 | ||||||
| +++ b/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 |  # connection tracking | ||||||
|  obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o |  obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o | ||||||
|   |   | ||||||
| +# optional conntrack route cache extension
 | +# optional conntrack route cache extension
 | ||||||
| +obj-$(CONFIG_NF_CONNTRACK_RTCACHE) += nf_conntrack_rtcache.o
 | +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 |  # 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
 | --- /dev/null
 | ||||||
| +++ b/net/netfilter/nf_conntrack_rtcache.c
 | +++ b/net/netfilter/nf_conntrack_rtcache.c
 | ||||||
| @@ -0,0 +1,428 @@
 | @@ -0,0 +1,428 @@
 | ||||||
|  | |||||||
| @ -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 |  | ||||||
| @ -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; |  | ||||||
| @ -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; |  | ||||||
|   |  | ||||||
| @ -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; |  | ||||||
|   |  | ||||||
| @ -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); |  | ||||||
| @ -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) |  | ||||||
| @ -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; |  | ||||||
| @ -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 */
 |  | ||||||
| @ -10,7 +10,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> | |||||||
| 
 | 
 | ||||||
| --- a/net/netfilter/nf_flow_table_core.c
 | --- a/net/netfilter/nf_flow_table_core.c
 | ||||||
| +++ b/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); |  EXPORT_SYMBOL_GPL(nf_flow_table_free); | ||||||
|   |   | ||||||
| @ -22,7 +22,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> | |||||||
| +	if (event != NETDEV_DOWN)
 | +	if (event != NETDEV_DOWN)
 | ||||||
| +		return NOTIFY_DONE;
 | +		return NOTIFY_DONE;
 | ||||||
| +
 | +
 | ||||||
| +	nf_flow_table_cleanup(dev_net(dev), dev);
 | +	nf_flow_table_cleanup(dev);
 | ||||||
| +
 | +
 | ||||||
| +	return NOTIFY_DONE;
 | +	return NOTIFY_DONE;
 | ||||||
| +}
 | +}
 | ||||||
| @ -48,7 +48,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> | |||||||
|  MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>"); |  MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>"); | ||||||
| --- a/net/netfilter/nft_flow_offload.c
 | --- a/net/netfilter/nft_flow_offload.c
 | ||||||
| +++ b/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, |  	.owner		= THIS_MODULE, | ||||||
|  }; |  }; | ||||||
|   |   | ||||||
| @ -60,7 +60,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> | |||||||
| -	if (event != NETDEV_DOWN)
 | -	if (event != NETDEV_DOWN)
 | ||||||
| -		return NOTIFY_DONE;
 | -		return NOTIFY_DONE;
 | ||||||
| -
 | -
 | ||||||
| -	nf_flow_table_cleanup(dev_net(dev), dev);
 | -	nf_flow_table_cleanup(dev);
 | ||||||
| -
 | -
 | ||||||
| -	return NOTIFY_DONE;
 | -	return NOTIFY_DONE;
 | ||||||
| -}
 | -}
 | ||||||
|  | |||||||
| @ -21,7 +21,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| 
 | 
 | ||||||
| --- a/net/netfilter/nf_conntrack_core.c
 | --- a/net/netfilter/nf_conntrack_core.c
 | ||||||
| +++ b/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; |  	return false; | ||||||
|  } |  } | ||||||
|   |   | ||||||
| @ -40,7 +40,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  static void gc_worker(struct work_struct *work) |  static void gc_worker(struct work_struct *work) | ||||||
|  { |  { | ||||||
|  	unsigned int min_interval = max(HZ / GC_MAX_BUCKETS_DIV, 1u); |  	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); |  			tmp = nf_ct_tuplehash_to_ctrack(h); | ||||||
|   |   | ||||||
|  			scanned++; |  			scanned++; | ||||||
| @ -54,7 +54,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  				nf_ct_gc_expired(tmp); |  				nf_ct_gc_expired(tmp); | ||||||
| --- a/net/netfilter/nf_flow_table_core.c
 | --- a/net/netfilter/nf_flow_table_core.c
 | ||||||
| +++ b/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, |  	.automatic_shrinking	= true, | ||||||
|  }; |  }; | ||||||
|   |   | ||||||
| @ -84,22 +84,24 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  	flow->timeout = (u32)jiffies + NF_FLOW_TIMEOUT; |  	flow->timeout = (u32)jiffies + NF_FLOW_TIMEOUT; | ||||||
|   |   | ||||||
|  	err = rhashtable_insert_fast(&flow_table->rhashtable, |  	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); |  	rhashtable_walk_start(&hti); | ||||||
|   |   | ||||||
|  	while ((tuplehash = rhashtable_walk_next(&hti))) { |  	while ((tuplehash = rhashtable_walk_next(&hti))) { | ||||||
| +		bool teardown;
 |  | ||||||
| +
 | +
 | ||||||
|  		if (IS_ERR(tuplehash)) { |  		if (IS_ERR(tuplehash)) { | ||||||
|  |  			if (PTR_ERR(tuplehash) != -EAGAIN) { | ||||||
|  				err = PTR_ERR(tuplehash); |  				err = PTR_ERR(tuplehash); | ||||||
|  			if (err != -EAGAIN) | @@ -328,10 +348,17 @@ static void nf_flow_offload_gc_step(stru
 | ||||||
| @@ -329,9 +350,13 @@ static int nf_flow_offload_gc_step(struc
 |  { | ||||||
|  |  	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) ||
 | ||||||
| -		if (nf_flow_has_expired(flow) ||
 | -	    (flow->flags & (FLOW_OFFLOAD_DYING | FLOW_OFFLOAD_TEARDOWN)))
 | ||||||
| -		    (flow->flags & (FLOW_OFFLOAD_DYING |
 | +
 | ||||||
| -				    FLOW_OFFLOAD_TEARDOWN)))
 |  | ||||||
| +	teardown = flow->flags & (FLOW_OFFLOAD_DYING |
 | +	teardown = flow->flags & (FLOW_OFFLOAD_DYING |
 | ||||||
| +				  FLOW_OFFLOAD_TEARDOWN);
 | +				  FLOW_OFFLOAD_TEARDOWN);
 | ||||||
| +
 | +
 | ||||||
| @ -109,4 +111,4 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| +	if (nf_flow_has_expired(flow) || teardown)
 | +	if (nf_flow_has_expired(flow) || teardown)
 | ||||||
|  		flow_offload_del(flow_table, flow); |  		flow_offload_del(flow_table, flow); | ||||||
|  } |  } | ||||||
|  out: |   | ||||||
|  | |||||||
| @ -12,9 +12,9 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| 
 | 
 | ||||||
| --- a/net/netfilter/nf_flow_table_core.c
 | --- a/net/netfilter/nf_flow_table_core.c
 | ||||||
| +++ b/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
 | @@ -268,6 +268,9 @@ static void flow_offload_del(struct nf_f
 | ||||||
|  	e = container_of(flow, struct flow_offload_entry, flow); |  	else if (flow->flags & FLOW_OFFLOAD_TEARDOWN) | ||||||
|  	clear_bit(IPS_OFFLOAD_BIT, &e->ct->status); |  		flow_offload_fixup_ct_timeout(e->ct); | ||||||
|   |   | ||||||
| +	if (!(flow->flags & FLOW_OFFLOAD_TEARDOWN))
 | +	if (!(flow->flags & FLOW_OFFLOAD_TEARDOWN))
 | ||||||
| +		flow_offload_fixup_ct_state(e->ct);
 | +		flow_offload_fixup_ct_state(e->ct);
 | ||||||
|  | |||||||
| @ -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 |  | ||||||
| @ -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)),
 |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  /** |  | ||||||
| @ -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[] = { |  | ||||||
|  	¯onix_spinand_manufacturer, |  | ||||||
|  	µn_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; |  | ||||||
|   |  | ||||||
|  /** |  | ||||||
| @ -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,
 |  | ||||||
|  	¯onix_spinand_manufacturer, |  | ||||||
|  	µn_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; |  | ||||||
| @ -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) |  | ||||||
| @ -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) |  | ||||||
| @ -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) }, |  | ||||||
| @ -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),				\ |  | ||||||
| @ -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); |  | ||||||
| @ -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; |  | ||||||
|   |  | ||||||
| @ -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, |  | ||||||
|  	¯onix_spinand_manufacturer, |  | ||||||
|  	µn_spinand_manufacturer, |  | ||||||
| +	¶gon_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 = ¶gon_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; |  | ||||||
|   |  | ||||||
| @ -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: |  | ||||||
| @ -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; |  | ||||||
|  		} |  | ||||||
| @ -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 *)); |  | ||||||
| @ -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 *)); |  | ||||||
| @ -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; |  | ||||||
| @ -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); |  | ||||||
| @ -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 |  | ||||||
| @ -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); |  | ||||||
| @ -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; |  | ||||||
|  	} |  | ||||||
| @ -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); |  | ||||||
|  } |  | ||||||
| @ -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); |  | ||||||
|   |  | ||||||
| @ -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); |  | ||||||
| @ -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; |  | ||||||
| @ -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), |  | ||||||
| @ -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, |  | ||||||
| @ -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); |  | ||||||
| @ -16,7 +16,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/net/phy/phylink.c
 | --- a/drivers/net/phy/phylink.c
 | ||||||
| +++ b/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, |  static int phylink_register_sfp(struct phylink *pl, | ||||||
|  				struct fwnode_handle *fwnode) |  				struct fwnode_handle *fwnode) | ||||||
|  { |  { | ||||||
| @ -33,12 +33,12 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
| -		if (ret == -ENOENT)
 | -		if (ret == -ENOENT)
 | ||||||
| -			return 0;
 | -			return 0;
 | ||||||
| -
 | -
 | ||||||
| -		netdev_err(pl->netdev, "unable to parse \"sfp\" node: %d\n",
 | -		phylink_err(pl, "unable to parse \"sfp\" node: %d\n",
 | ||||||
| -			    ret);
 | -			    ret);
 | ||||||
| +	bus = sfp_register_upstream_node(fwnode, pl, &sfp_phylink_ops);
 | +	bus = sfp_register_upstream_node(fwnode, pl, &sfp_phylink_ops);
 | ||||||
| +	if (IS_ERR(bus)) {
 | +	if (IS_ERR(bus)) {
 | ||||||
| +		ret = PTR_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; |  		return ret; | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
| @ -51,7 +51,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  } |  } | ||||||
| --- a/drivers/net/phy/sfp-bus.c
 | --- a/drivers/net/phy/sfp-bus.c
 | ||||||
| +++ b/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/list.h> | ||||||
|  #include <linux/mutex.h> |  #include <linux/mutex.h> | ||||||
|  #include <linux/phylink.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/rtnetlink.h> | ||||||
|  #include <linux/slab.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
 | ||||||
|  } |  } | ||||||
|   |   | ||||||
|  /** |  /** | ||||||
|  | |||||||
| @ -20,7 +20,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/net/phy/phylink.c
 | --- a/drivers/net/phy/phylink.c
 | ||||||
| +++ b/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; |  	struct sfp_bus *bus; | ||||||
|  	int ret; |  	int ret; | ||||||
|   |   | ||||||
| @ -28,8 +28,8 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
| +	bus = sfp_bus_find_fwnode(fwnode);
 | +	bus = sfp_bus_find_fwnode(fwnode);
 | ||||||
|  	if (IS_ERR(bus)) { |  	if (IS_ERR(bus)) { | ||||||
|  		ret = PTR_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); | ||||||
| @@ -550,7 +550,10 @@ static int phylink_register_sfp(struct p
 | @@ -577,7 +577,10 @@ static int phylink_register_sfp(struct p
 | ||||||
|   |   | ||||||
|  	pl->sfp_bus = bus; |  	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) |  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
 | --- a/drivers/net/phy/sfp-bus.c
 | ||||||
| +++ b/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); |  	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) |  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; |  				return ret; | ||||||
|  		} |  		} | ||||||
|  	} |  	} | ||||||
| @ -88,7 +88,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  	return 0; |  	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, |   * Returns: on success, a pointer to the sfp_bus structure, | ||||||
|   *	    %NULL if no SFP is specified, |   *	    %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. |   * 	        %-ENOMEM if we failed to allocate the bus. | ||||||
|   *		an error from the upstream's connect_phy() method. |   *		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 fwnode_reference_args ref; | ||||||
|  	struct sfp_bus *bus; |  	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) |  	if (!bus) | ||||||
|  		return ERR_PTR(-ENOMEM); |  		return ERR_PTR(-ENOMEM); | ||||||
|   |   | ||||||
| @ -157,7 +157,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  	bus->upstream_ops = ops; |  	bus->upstream_ops = ops; | ||||||
|  	bus->upstream = upstream; |  	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(); |  	rtnl_unlock(); | ||||||
|   |   | ||||||
|  | |||||||
| @ -16,7 +16,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/net/phy/sfp-bus.c
 | --- a/drivers/net/phy/sfp-bus.c
 | ||||||
| +++ b/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 |   * sfp_bus_put() - put a reference on the &struct sfp_bus | ||||||
|  | |||||||
| @ -16,7 +16,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/net/phy/sfp.c
 | --- a/drivers/net/phy/sfp.c
 | ||||||
| +++ b/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"); |  	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) { |  	switch (sfp->sm_mod_state) { | ||||||
|  	default: |  	default: | ||||||
|  		if (event == SFP_E_INSERT && sfp->attached) { |  		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; |  		break; | ||||||
|  	} |  	} | ||||||
| @ -92,7 +92,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  	/* Some events are global */ |  	/* Some events are global */ | ||||||
|  	if (sfp->sm_state != SFP_S_DOWN && |  	if (sfp->sm_state != SFP_S_DOWN && | ||||||
|  	    (sfp->sm_mod_state != SFP_MOD_PRESENT || |  	    (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) |  		if (sfp->mod_phy) | ||||||
|  			sfp_sm_phy_detach(sfp); |  			sfp_sm_phy_detach(sfp); | ||||||
|  		sfp_sm_next(sfp, SFP_S_DOWN, 0); |  		sfp_sm_next(sfp, SFP_S_DOWN, 0); | ||||||
| @ -100,7 +100,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  		return; |  		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: |  	case SFP_S_TX_DISABLE: | ||||||
|  		break; |  		break; | ||||||
|  	} |  	} | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/net/phy/sfp.c
 | --- a/drivers/net/phy/sfp.c
 | ||||||
| +++ b/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; |  		break; | ||||||
|   |   | ||||||
|  	case SFP_DEV_UP: |  	case SFP_DEV_UP: | ||||||
| @ -31,7 +31,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  		break; |  		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); |  			sfp_sm_link_down(sfp); | ||||||
|  		if (sfp->mod_phy) |  		if (sfp->mod_phy) | ||||||
|  			sfp_sm_phy_detach(sfp); |  			sfp_sm_phy_detach(sfp); | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/net/phy/sfp.c
 | --- a/drivers/net/phy/sfp.c
 | ||||||
| +++ b/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); |  	sfp_sm_set_timer(sfp, timeout); | ||||||
|  } |  } | ||||||
|   |   | ||||||
| @ -23,7 +23,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  			    unsigned int timeout) |  			    unsigned int timeout) | ||||||
|  { |  { | ||||||
|  	sfp->sm_mod_state = state; |  	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: |  	default: | ||||||
|  		if (event == SFP_E_INSERT && sfp->attached) { |  		if (event == SFP_E_INSERT && sfp->attached) { | ||||||
|  			sfp_module_tx_disable(sfp); |  			sfp_module_tx_disable(sfp); | ||||||
| @ -51,7 +51,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  			else |  			else | ||||||
|  				sfp_sm_set_timer(sfp, T_PROBE_RETRY); |  				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: |  	case SFP_MOD_HPOWER: | ||||||
|  		if (event == SFP_E_TIMEOUT) { |  		if (event == SFP_E_TIMEOUT) { | ||||||
| @ -60,7 +60,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  			break; |  			break; | ||||||
|  		} |  		} | ||||||
|  		/* fallthrough */ |  		/* 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: |  	case SFP_MOD_ERROR: | ||||||
|  		if (event == SFP_E_REMOVE) { |  		if (event == SFP_E_REMOVE) { | ||||||
|  			sfp_sm_mod_remove(sfp); |  			sfp_sm_mod_remove(sfp); | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/net/phy/sfp.c
 | --- a/drivers/net/phy/sfp.c
 | ||||||
| +++ b/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) |  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) { |  	switch (sfp->sm_mod_state) { | ||||||
|  	default: |  	default: | ||||||
|  		if (event == SFP_E_INSERT && sfp->attached) { |  		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; |  		break; | ||||||
|   |   | ||||||
|  	case SFP_MOD_PROBE: |  	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); |  			int val = sfp_sm_mod_probe(sfp); | ||||||
|   |   | ||||||
|  			if (val == 0) |  			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 */ |  		/* fallthrough */ | ||||||
|  	case SFP_MOD_PRESENT: |  	case SFP_MOD_PRESENT: | ||||||
|  	case SFP_MOD_ERROR: |  	case SFP_MOD_ERROR: | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/net/phy/sfp.c
 | --- a/drivers/net/phy/sfp.c
 | ||||||
| +++ b/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 |   * 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. |   * 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_HPOWER_LEVEL	msecs_to_jiffies(300) | ||||||
|  #define T_PROBE_RETRY	msecs_to_jiffies(100) |  #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) |  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: |  	default: | ||||||
|  		if (event == SFP_E_INSERT && sfp->attached) { |  		if (event == SFP_E_INSERT && sfp->attached) { | ||||||
|  			sfp_module_tx_disable(sfp); |  			sfp_module_tx_disable(sfp); | ||||||
|  | |||||||
| @ -13,7 +13,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/net/phy/sfp.c
 | --- a/drivers/net/phy/sfp.c
 | ||||||
| +++ b/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; |  	unsigned int sm_retries; | ||||||
|   |   | ||||||
|  	struct sfp_eeprom_id id; |  	struct sfp_eeprom_id id; | ||||||
| @ -22,7 +22,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  #if IS_ENABLED(CONFIG_HWMON) |  #if IS_ENABLED(CONFIG_HWMON) | ||||||
|  	struct sfp_diag diag; |  	struct sfp_diag diag; | ||||||
|  	struct device *hwmon_dev; |  	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); |  		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 && |  	if (sfp->id.ext.sff8472_compliance == SFP_SFF8472_COMPLIANCE_NONE && | ||||||
|  	    (sfp->id.ext.diagmon & (SFP_DIAGMON_DDM | SFP_DIAGMON_ADDRMODE)) != |  	    (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 |  		 * or requires an address change sequence, so assume that | ||||||
|  		 * the module powers up in the indicated power mode. |  		 * 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; |  		return 0; | ||||||
|   |   | ||||||
|  	err = sfp_read(sfp, true, SFP_EXT_STATUS, &val, sizeof(val)); |  	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", |  	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; |  	return T_HPOWER_LEVEL; | ||||||
|   |   | ||||||
|  err: |  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, |  		dev_warn(sfp->dev, | ||||||
|  			 "module address swap to access page 0xA2 is not supported.\n"); |  			 "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); |  	ret = sfp_hwmon_insert(sfp); | ||||||
|  	if (ret < 0) |  	if (ret < 0) | ||||||
|  		return ret; |  		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); |  	sfp_module_tx_disable(sfp); | ||||||
|   |   | ||||||
|  	memset(&sfp->id, 0, sizeof(sfp->id)); |  	memset(&sfp->id, 0, sizeof(sfp->id)); | ||||||
|  | |||||||
| @ -17,7 +17,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/net/phy/sfp.c
 | --- a/drivers/net/phy/sfp.c
 | ||||||
| +++ b/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)) |  	if (sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_HIGH_POWER_LEVEL)) | ||||||
|  		power_mW = 2000; |  		power_mW = 2000; | ||||||
|   |   | ||||||
|  | |||||||
| @ -26,7 +26,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/net/phy/sfp.c
 | --- a/drivers/net/phy/sfp.c
 | ||||||
| +++ b/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); |  	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)); |  	memset(&sfp->id, 0, sizeof(sfp->id)); | ||||||
|  	sfp->module_power_mW = 0; |  	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) { |  	switch (sfp->sm_mod_state) { | ||||||
|  	default: |  	default: | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/net/phy/sfp.c
 | --- a/drivers/net/phy/sfp.c
 | ||||||
| +++ b/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) |  static void sfp_sm_mod_init(struct sfp *sfp) | ||||||
|  { |  { | ||||||
|  	sfp_module_tx_enable(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 |  	/* Setting the serdes link mode is guesswork: there's no | ||||||
|  	 * field in the EEPROM which indicates what mode should |  	 * field in the EEPROM which indicates what mode should | ||||||
|  	 * be used. |  	 * 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) { |  	switch (sfp->sm_state) { | ||||||
|  	case SFP_S_DOWN: |  	case SFP_S_DOWN: | ||||||
|  		if (sfp->sm_mod_state == SFP_MOD_PRESENT && |  		if (sfp->sm_mod_state == SFP_MOD_PRESENT && | ||||||
|  | |||||||
| @ -15,7 +15,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/net/phy/sfp.c
 | --- a/drivers/net/phy/sfp.c
 | ||||||
| +++ b/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_DEV_UP, | ||||||
|   |   | ||||||
|  	SFP_S_DOWN = 0, |  	SFP_S_DOWN = 0, | ||||||
| @ -23,7 +23,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  	SFP_S_INIT, |  	SFP_S_INIT, | ||||||
|  	SFP_S_WAIT_LOS, |  	SFP_S_WAIT_LOS, | ||||||
|  	SFP_S_LINK_UP, |  	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[] = { |  static const char * const sm_state_strings[] = { | ||||||
|  	[SFP_S_DOWN] = "down", |  	[SFP_S_DOWN] = "down", | ||||||
| @ -31,7 +31,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  	[SFP_S_INIT] = "init", |  	[SFP_S_INIT] = "init", | ||||||
|  	[SFP_S_WAIT_LOS] = "wait_los", |  	[SFP_S_WAIT_LOS] = "wait_los", | ||||||
|  	[SFP_S_LINK_UP] = "link_up", |  	[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, |  	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_INIT_JIFFIES	msecs_to_jiffies(300) | ||||||
|  #define T_RESET_US	10 |  #define T_RESET_US	10 | ||||||
|  #define T_FAULT_RECOVER	msecs_to_jiffies(1000) |  #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 |  #define SFP_PHY_ADDR	22 | ||||||
|   |   | ||||||
| @ -49,7 +49,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  struct sff_data { |  struct sff_data { | ||||||
|  	unsigned int gpios; |  	unsigned int gpios; | ||||||
|  	bool (*module_supported)(const struct sfp_eeprom_id *id); |  	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; |  	struct phy_device *phy; | ||||||
|  	int err; |  	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); |  	phy = mdiobus_scan(sfp->i2c_mii, SFP_PHY_ADDR); | ||||||
|  	if (phy == ERR_PTR(-ENODEV)) { |  	if (phy == ERR_PTR(-ENODEV)) { | ||||||
|  		dev_info(sfp->dev, "no PHY detected\n"); |  		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) |  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 */ |  	/* Some events are global */ | ||||||
|  	if (sfp->sm_state != SFP_S_DOWN && |  	if (sfp->sm_state != SFP_S_DOWN && | ||||||
|  	    (sfp->sm_mod_state != SFP_MOD_PRESENT || |  	    (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 */ |  	/* The main state machine */ | ||||||
|  	switch (sfp->sm_state) { |  	switch (sfp->sm_state) { | ||||||
|  	case SFP_S_DOWN: |  	case SFP_S_DOWN: | ||||||
| @ -119,7 +119,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  		} |  		} | ||||||
|  		break; |  		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) |  		if (event == SFP_E_TIMEOUT && sfp->state & SFP_F_TX_FAULT) | ||||||
|  			sfp_sm_fault(sfp, true); |  			sfp_sm_fault(sfp, true); | ||||||
|  		else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) |  		else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/net/phy/sfp.c
 | --- a/drivers/net/phy/sfp.c
 | ||||||
| +++ b/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); |  		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) { |  	if (sfp->sm_retries && !--sfp->sm_retries) { | ||||||
|  		dev_err(sfp->dev, |  		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) |  		if (warn) | ||||||
|  			dev_err(sfp->dev, "module transmit fault indicated\n"); |  			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: |  	case SFP_S_INIT: | ||||||
|  		if (event == SFP_E_TIMEOUT && sfp->state & SFP_F_TX_FAULT) |  		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)) |  		else if (sfp_los_event_inactive(sfp, event)) | ||||||
|  			sfp_sm_link_up(sfp); |  			sfp_sm_link_up(sfp); | ||||||
|  		break; |  		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: |  	case SFP_S_LINK_UP: | ||||||
|  		if (event == SFP_E_TX_FAULT) { |  		if (event == SFP_E_TX_FAULT) { | ||||||
|  			sfp_sm_link_down(sfp); |  			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)) { |  		} else if (sfp_los_event_active(sfp, event)) { | ||||||
|  			sfp_sm_link_down(sfp); |  			sfp_sm_link_down(sfp); | ||||||
|  			sfp_sm_next(sfp, SFP_S_WAIT_LOS, 0); |  			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: |  	case SFP_S_REINIT: | ||||||
|  		if (event == SFP_E_TIMEOUT && sfp->state & SFP_F_TX_FAULT) { |  		if (event == SFP_E_TIMEOUT && sfp->state & SFP_F_TX_FAULT) { | ||||||
|  | |||||||
| @ -19,7 +19,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/net/phy/sfp.c
 | --- a/drivers/net/phy/sfp.c
 | ||||||
| +++ b/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_DOWN = 0, | ||||||
|  	SFP_S_WAIT, |  	SFP_S_WAIT, | ||||||
|  	SFP_S_INIT, |  	SFP_S_INIT, | ||||||
| @ -27,7 +27,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  	SFP_S_WAIT_LOS, |  	SFP_S_WAIT_LOS, | ||||||
|  	SFP_S_LINK_UP, |  	SFP_S_LINK_UP, | ||||||
|  	SFP_S_TX_FAULT, |  	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_DOWN] = "down", | ||||||
|  	[SFP_S_WAIT] = "wait", |  	[SFP_S_WAIT] = "wait", | ||||||
|  	[SFP_S_INIT] = "init", |  	[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_WAIT_LOS] = "wait_los", | ||||||
|  	[SFP_S_LINK_UP] = "link_up", |  	[SFP_S_LINK_UP] = "link_up", | ||||||
|  	[SFP_S_TX_FAULT] = "tx_fault", |  	[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) |  		if (event != SFP_E_TIMEOUT) | ||||||
|  			break; |  			break; | ||||||
|   |   | ||||||
| @ -44,7 +44,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  		if (sfp->state & SFP_F_TX_FAULT) { |  		if (sfp->state & SFP_F_TX_FAULT) { | ||||||
|  			/* Wait t_init before indicating that the link is up, |  			/* Wait t_init before indicating that the link is up, | ||||||
|  			 * provided the current state indicates no TX_FAULT. If |  			 * 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; |  		break; | ||||||
|   |   | ||||||
|  	case SFP_S_INIT: |  	case SFP_S_INIT: | ||||||
|  | |||||||
| @ -24,7 +24,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/net/phy/sfp.c
 | --- a/drivers/net/phy/sfp.c
 | ||||||
| +++ b/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_INSERT = 0, | ||||||
|  	SFP_E_REMOVE, |  	SFP_E_REMOVE, | ||||||
| @ -33,7 +33,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  	SFP_E_DEV_DOWN, |  	SFP_E_DEV_DOWN, | ||||||
|  	SFP_E_DEV_UP, |  	SFP_E_DEV_UP, | ||||||
|  	SFP_E_TX_FAULT, |  	SFP_E_TX_FAULT, | ||||||
| @@ -48,7 +50,8 @@ enum {
 | @@ -50,7 +52,8 @@ enum {
 | ||||||
|  	SFP_MOD_PRESENT, |  	SFP_MOD_PRESENT, | ||||||
|  	SFP_MOD_ERROR, |  	SFP_MOD_ERROR, | ||||||
|   |   | ||||||
| @ -43,7 +43,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  	SFP_DEV_UP, |  	SFP_DEV_UP, | ||||||
|   |   | ||||||
|  	SFP_S_DOWN = 0, |  	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[] = { |  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_DOWN] = "down", | ||||||
|  	[SFP_DEV_UP] = "up", |  	[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[] = { |  static const char * const event_strings[] = { | ||||||
|  	[SFP_E_INSERT] = "insert", |  	[SFP_E_INSERT] = "insert", | ||||||
|  	[SFP_E_REMOVE] = "remove", |  	[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_DOWN] = "dev_down", | ||||||
|  	[SFP_E_DEV_UP] = "dev_up", |  	[SFP_E_DEV_UP] = "dev_up", | ||||||
|  	[SFP_E_TX_FAULT] = "tx_fault", |  	[SFP_E_TX_FAULT] = "tx_fault", | ||||||
| @@ -186,7 +192,6 @@ struct sfp {
 | @@ -188,7 +194,6 @@ struct sfp {
 | ||||||
|  	struct gpio_desc *gpio[GPIO_MAX]; |  	struct gpio_desc *gpio[GPIO_MAX]; | ||||||
|  	int gpio_irq[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 */ |  	struct mutex st_mutex;			/* Protects state */ | ||||||
|  	unsigned int state; |  	unsigned int state; | ||||||
|  	struct delayed_work poll; |  	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"); |  	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; |  			sfp->sm_dev_state = SFP_DEV_DOWN; | ||||||
|  		break; |  		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) |  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); |  			sfp_sm_mod_next(sfp, SFP_MOD_PROBE, T_SERIAL); | ||||||
|  		break; |  		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), |  		sm_state_to_str(sfp->sm_state), | ||||||
|  		event_to_str(event)); |  		event_to_str(event)); | ||||||
|   |   | ||||||
| @ -133,7 +133,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  	sfp_sm_main(sfp, event); |  	sfp_sm_main(sfp, event); | ||||||
|   |   | ||||||
|  	dev_dbg(sfp->dev, "SM: exit %s:%s:%s\n", |  	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) |  static void sfp_attach(struct sfp *sfp) | ||||||
|  { |  { | ||||||
|  | |||||||
| @ -18,7 +18,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/net/phy/sfp.c
 | --- a/drivers/net/phy/sfp.c
 | ||||||
| +++ b/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_EMPTY = 0, | ||||||
|  	SFP_MOD_PROBE, |  	SFP_MOD_PROBE, | ||||||
|  	SFP_MOD_HPOWER, |  	SFP_MOD_HPOWER, | ||||||
| @ -26,7 +26,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  	SFP_MOD_PRESENT, |  	SFP_MOD_PRESENT, | ||||||
|  	SFP_MOD_ERROR, |  	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_EMPTY] = "empty", | ||||||
|  	[SFP_MOD_PROBE] = "probe", |  	[SFP_MOD_PROBE] = "probe", | ||||||
|  	[SFP_MOD_HPOWER] = "hpower", |  	[SFP_MOD_HPOWER] = "hpower", | ||||||
| @ -34,7 +34,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  	[SFP_MOD_PRESENT] = "present", |  	[SFP_MOD_PRESENT] = "present", | ||||||
|  	[SFP_MOD_ERROR] = "error", |  	[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; |  	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) |  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) |  	if (ret < 0) | ||||||
|  		return ret; |  		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) |  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) |  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); |  			sfp_sm_mod_next(sfp, SFP_MOD_EMPTY, 0); | ||||||
|  		return; |  		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; |  		break; | ||||||
|   |   | ||||||
|  	case SFP_MOD_PROBE: |  	case SFP_MOD_PROBE: | ||||||
|  | |||||||
| @ -20,7 +20,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/net/phy/sfp.c
 | --- a/drivers/net/phy/sfp.c
 | ||||||
| +++ b/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_E_TIMEOUT, | ||||||
|   |   | ||||||
|  	SFP_MOD_EMPTY = 0, |  	SFP_MOD_EMPTY = 0, | ||||||
| @ -34,7 +34,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|   |   | ||||||
|  	SFP_DEV_DETACHED = 0, |  	SFP_DEV_DETACHED = 0, | ||||||
|  	SFP_DEV_DOWN, |  	SFP_DEV_DOWN, | ||||||
| @@ -68,11 +69,12 @@ enum {
 | @@ -70,11 +71,12 @@ enum {
 | ||||||
|   |   | ||||||
|  static const char  * const mod_state_strings[] = { |  static const char  * const mod_state_strings[] = { | ||||||
|  	[SFP_MOD_EMPTY] = "empty", |  	[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) |  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) |  	if (ret < 0) | ||||||
|  		return ret; |  		return ret; | ||||||
|   |   | ||||||
| @ -67,7 +67,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|   |   | ||||||
|  	sfp_hwmon_remove(sfp); |  	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 */ |  	/* Handle device detach globally */ | ||||||
| @ -83,7 +83,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  		return; |  		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; |  		break; | ||||||
|   |   | ||||||
|  	case SFP_MOD_PROBE: |  	case SFP_MOD_PROBE: | ||||||
| @ -91,7 +91,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  		if (event != SFP_E_TIMEOUT) |  		if (event != SFP_E_TIMEOUT) | ||||||
|  			break; |  			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; |  			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 this is a power level 1 module, we are done */ | ||||||
|  		if (sfp->module_power_mW <= 1000) |  		if (sfp->module_power_mW <= 1000) | ||||||
|  			goto insert; |  			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: |  	case SFP_MOD_HPOWER: | ||||||
|  		/* Enable high power mode */ |  		/* Enable high power mode */ | ||||||
|  		err = sfp_sm_mod_hpower(sfp, true); |  		err = sfp_sm_mod_hpower(sfp, true); | ||||||
| @ -136,7 +136,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  		break; |  		break; | ||||||
|   |   | ||||||
|  	case SFP_MOD_WAITPWR: |  	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) |  static void sfp_attach(struct sfp *sfp) | ||||||
|  { |  { | ||||||
|  	sfp_sm_event(sfp, SFP_E_DEV_ATTACH); |  	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) |  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->state |= SFP_F_RATE_SELECT; | ||||||
|  	sfp_set_state(sfp, sfp->state); |  	sfp_set_state(sfp, sfp->state); | ||||||
|  	sfp_module_tx_disable(sfp); |  	sfp_module_tx_disable(sfp); | ||||||
|  | |||||||
| @ -19,7 +19,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/net/phy/sfp.c
 | --- a/drivers/net/phy/sfp.c
 | ||||||
| +++ b/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 |   * 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. |   * 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 |  /* SFP modules appear to always have their PHY configured for bus address | ||||||
|   * 0x56 (which with mdio-i2c, translates to a PHY address of 22). |   * 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 delayed_work timeout; | ||||||
|  	struct mutex sm_mutex;			/* Protects state machine */ |  	struct mutex sm_mutex;			/* Protects state machine */ | ||||||
|  	unsigned char sm_mod_state; |  	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 char sm_dev_state; | ||||||
|  	unsigned short sm_state; |  	unsigned short sm_state; | ||||||
|  	unsigned int sm_retries; |  	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; |  	return 0; | ||||||
|  } |  } | ||||||
|   |   | ||||||
| @ -53,7 +53,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  { |  { | ||||||
|  	/* SFP module inserted - read I2C data */ |  	/* SFP module inserted - read I2C data */ | ||||||
|  	struct sfp_eeprom_id id; |  	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)); |  	ret = sfp_read(sfp, false, 0, &id, sizeof(id)); | ||||||
|  	if (ret < 0) { |  	if (ret < 0) { | ||||||
| @ -63,7 +63,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  		return -EAGAIN; |  		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) { |  	switch (sfp->sm_mod_state) { | ||||||
|  	default: |  	default: | ||||||
| @ -76,7 +76,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  		break; |  		break; | ||||||
|   |   | ||||||
|  	case SFP_MOD_PROBE: |  	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) |  		if (event != SFP_E_TIMEOUT) | ||||||
|  			break; |  			break; | ||||||
|   |   | ||||||
| @ -99,7 +99,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  		} |  		} | ||||||
|  		if (err < 0) { |  		if (err < 0) { | ||||||
|  			sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 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_module_remove(sfp->sfp_bus); | ||||||
|  				sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0); |  				sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0); | ||||||
|  			} else { |  			} else { | ||||||
|  | |||||||
| @ -27,7 +27,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/net/phy/sfp.c
 | --- a/drivers/net/phy/sfp.c
 | ||||||
| +++ b/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) |  #if IS_ENABLED(CONFIG_HWMON) | ||||||
|  	struct sfp_diag diag; |  	struct sfp_diag diag; | ||||||
| @ -36,7 +36,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  	struct device *hwmon_dev; |  	struct device *hwmon_dev; | ||||||
|  	char *hwmon_name; |  	char *hwmon_name; | ||||||
|  #endif |  #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, |  	.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++) |  	for (i = 0; sfp->hwmon_name[i]; i++) | ||||||
|  		if (hwmon_is_bad_char(sfp->hwmon_name[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_name, sfp, | ||||||
|  							 &sfp_hwmon_chip_info, |  							 &sfp_hwmon_chip_info, | ||||||
|  							 NULL); |  							 NULL); | ||||||
| @ -135,7 +135,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  #else |  #else | ||||||
|  static int sfp_hwmon_insert(struct sfp *sfp) |  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) |  static void sfp_hwmon_remove(struct sfp *sfp) | ||||||
|  { |  { | ||||||
|  } |  } | ||||||
| @ -151,7 +151,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  #endif |  #endif | ||||||
|   |   | ||||||
|  /* Helpers */ |  /* 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) |  	if (ret < 0) | ||||||
|  		return ret; |  		return ret; | ||||||
|   |   | ||||||
| @ -162,7 +162,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  	return 0; |  	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: |  	case SFP_MOD_ERROR: | ||||||
|  		break; |  		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) |  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->poll, sfp_poll); | ||||||
|  	INIT_DELAYED_WORK(&sfp->timeout, sfp_timeout); |  	INIT_DELAYED_WORK(&sfp->timeout, sfp_timeout); | ||||||
|   |   | ||||||
| @ -187,7 +187,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  	return sfp; |  	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; |  	struct sfp *sfp = data; | ||||||
|   |   | ||||||
|  | |||||||
| @ -16,7 +16,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/net/phy/phy.c
 | --- a/drivers/net/phy/phy.c
 | ||||||
| +++ b/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/ethtool.h> | ||||||
|  #include <linux/phy.h> |  #include <linux/phy.h> | ||||||
|  #include <linux/phy_led_triggers.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/workqueue.h> | ||||||
|  #include <linux/mdio.h> |  #include <linux/mdio.h> | ||||||
|  #include <linux/io.h> |  #include <linux/io.h> | ||||||
| @@ -871,6 +872,9 @@ void phy_stop(struct phy_device *phydev)
 | @@ -841,6 +842,9 @@ void phy_stop(struct phy_device *phydev)
 | ||||||
|  	if (phy_interrupt_is_valid(phydev)) |   | ||||||
|  		phy_disable_interrupts(phydev); |  	mutex_lock(&phydev->lock); | ||||||
|   |   | ||||||
| +	if (phydev->sfp_bus)
 | +	if (phydev->sfp_bus)
 | ||||||
| +		sfp_upstream_stop(phydev->sfp_bus);
 | +		sfp_upstream_stop(phydev->sfp_bus);
 | ||||||
| +
 | +
 | ||||||
|  	phydev->state = PHY_HALTED; |  	phydev->state = PHY_HALTED; | ||||||
|   |   | ||||||
|  out_unlock: |  	mutex_unlock(&phydev->lock); | ||||||
| @@ -899,6 +903,9 @@ void phy_start(struct phy_device *phydev
 | @@ -903,6 +907,9 @@ void phy_state_machine(struct work_struc
 | ||||||
|   |   | ||||||
|  	mutex_lock(&phydev->lock); |  	old_state = phydev->state; | ||||||
|   |   | ||||||
| +	if (phydev->sfp_bus)
 | +	if (phydev->sfp_bus)
 | ||||||
| +		sfp_upstream_start(phydev->sfp_bus);
 | +		sfp_upstream_start(phydev->sfp_bus);
 | ||||||
| +
 | +
 | ||||||
|  	switch (phydev->state) { |  	switch (phydev->state) { | ||||||
|  	case PHY_STARTING: |  	case PHY_DOWN: | ||||||
|  		phydev->state = PHY_PENDING; |  	case PHY_READY: | ||||||
| --- a/drivers/net/phy/phy_device.c
 | --- a/drivers/net/phy/phy_device.c
 | ||||||
| +++ b/drivers/net/phy/phy_device.c
 | +++ b/drivers/net/phy/phy_device.c
 | ||||||
| @@ -31,6 +31,7 @@
 | @@ -27,6 +27,7 @@
 | ||||||
|  #include <linux/ethtool.h> |  #include <linux/bitmap.h> | ||||||
|  #include <linux/phy.h> |  #include <linux/phy.h> | ||||||
|  #include <linux/phy_led_triggers.h> |  #include <linux/phy_led_triggers.h> | ||||||
| +#include <linux/sfp.h>
 | +#include <linux/sfp.h>
 | ||||||
|  #include <linux/mdio.h> |  #include <linux/mdio.h> | ||||||
|  #include <linux/io.h> |  #include <linux/io.h> | ||||||
|  #include <linux/uaccess.h> |  #include <linux/uaccess.h> | ||||||
| @@ -944,6 +945,65 @@ void phy_attached_print(struct phy_devic
 | @@ -1178,6 +1179,65 @@ phy_standalone_show(struct device *dev,
 | ||||||
|  EXPORT_SYMBOL(phy_attached_print); |  static DEVICE_ATTR_RO(phy_standalone); | ||||||
|   |   | ||||||
|  /** |  /** | ||||||
| + * phy_sfp_attach - attach the SFP bus to the PHY upstream network device
 | + * 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 |   * phy_attach_direct - attach a network device to a given PHY device pointer | ||||||
|   * @dev: network device to attach |   * @dev: network device to attach | ||||||
|   * @phydev: Pointer to phy_device to attach |   * @phydev: Pointer to phy_device to attach | ||||||
| @@ -1016,6 +1076,9 @@ int phy_attach_direct(struct net_device
 | @@ -1254,6 +1314,9 @@ int phy_attach_direct(struct net_device
 | ||||||
|  	phydev->attached_dev = dev; |  | ||||||
|  		dev->phydev = phydev; |  		dev->phydev = phydev; | ||||||
|  |  	} | ||||||
|   |   | ||||||
| +	if (phydev->sfp_bus_attached)
 | +	if (phydev->sfp_bus_attached)
 | ||||||
| +		dev->sfp_bus = phydev->sfp_bus;
 | +		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 |  	/* Some Ethernet drivers try to connect to a PHY device before | ||||||
|  	 * calling register_netdevice() -> netdev_register_kobject() and |  	 * calling register_netdevice() -> netdev_register_kobject() and | ||||||
|  	 * does the dev->dev.kobj initialization. Here we only check for |  	 * 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; |  	phydev->state = PHY_DOWN; | ||||||
|  	mutex_unlock(&phydev->lock); |  	mutex_unlock(&phydev->lock); | ||||||
|   |   | ||||||
| @ -142,7 +142,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|   |   | ||||||
| --- a/include/linux/phy.h
 | --- a/include/linux/phy.h
 | ||||||
| +++ b/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 device; | ||||||
|  struct phylink; |  struct phylink; | ||||||
| @ -151,16 +151,16 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  struct sk_buff; |  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) |   * irq: IRQ number of the PHY's interrupt (-1 if none) | ||||||
|   * phy_timer: The timer for handling the state machine |   * 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_attached: flag indicating whether the SFP bus has been attached
 | ||||||
| + * sfp_bus: SFP bus attached to this PHY's fiber port
 | + * sfp_bus: SFP bus attached to this PHY's fiber port
 | ||||||
|   * attached_dev: The attached enet driver's device instance ptr |   * attached_dev: The attached enet driver's device instance ptr | ||||||
|   * adjust_link: Callback for the enet controller to respond to |   * adjust_link: Callback for the enet controller to respond to | ||||||
|   * changes in the link state. |   * changes in the link state. | ||||||
| @@ -471,6 +475,9 @@ struct phy_device {
 | @@ -432,6 +436,9 @@ struct phy_device {
 | ||||||
|   |   | ||||||
|  	struct mutex lock; |  	struct mutex lock; | ||||||
|   |   | ||||||
| @ -170,7 +170,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  	struct phylink *phylink; |  	struct phylink *phylink; | ||||||
|  	struct net_device *attached_dev; |  	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_resume(struct phy_device *phydev); |  int __phy_resume(struct phy_device *phydev); | ||||||
|  int phy_loopback(struct phy_device *phydev, bool enable); |  int phy_loopback(struct phy_device *phydev, bool enable); | ||||||
|  | |||||||
| @ -19,15 +19,15 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/net/phy/marvell10g.c
 | --- a/drivers/net/phy/marvell10g.c
 | ||||||
| +++ b/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/hwmon.h> | ||||||
|  #include <linux/marvell_phy.h> |  #include <linux/marvell_phy.h> | ||||||
|  #include <linux/phy.h> |  #include <linux/phy.h> | ||||||
| +#include <linux/sfp.h>
 | +#include <linux/sfp.h>
 | ||||||
|   |   | ||||||
|  enum { |  #define MV_PHY_ALASKA_NBT_QUIRK_MASK	0xfffffffe | ||||||
|  	MV_PMA_BOOT		= 0xc050, |  #define MV_PHY_ALASKA_NBT_QUIRK_REV	(MARVELL_PHY_ID_88X3310 | 0xa) | ||||||
| @@ -219,6 +220,28 @@ static int mv3310_hwmon_probe(struct phy
 | @@ -206,6 +207,28 @@ static int mv3310_hwmon_probe(struct phy
 | ||||||
|  } |  } | ||||||
|  #endif |  #endif | ||||||
|   |   | ||||||
| @ -56,7 +56,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  static int mv3310_probe(struct phy_device *phydev) |  static int mv3310_probe(struct phy_device *phydev) | ||||||
|  { |  { | ||||||
|  	struct mv3310_priv *priv; |  	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) |  	if (ret) | ||||||
|  		return ret; |  		return ret; | ||||||
|   |   | ||||||
|  | |||||||
| @ -12,20 +12,19 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/net/phy/phylink.c
 | --- a/drivers/net/phy/phylink.c
 | ||||||
| +++ b/drivers/net/phy/phylink.c
 | +++ b/drivers/net/phy/phylink.c
 | ||||||
| @@ -678,12 +678,6 @@ static int phylink_bringup_phy(struct ph
 | @@ -718,11 +718,6 @@ static int phylink_bringup_phy(struct ph
 | ||||||
|  	u32 advertising; |  	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported); | ||||||
|  	int ret; |  	int ret; | ||||||
|   |   | ||||||
| -	memset(&config, 0, sizeof(config));
 | -	memset(&config, 0, sizeof(config));
 | ||||||
| -	ethtool_convert_legacy_u32_to_link_mode(supported, phy->supported);
 | -	linkmode_copy(supported, phy->supported);
 | ||||||
| -	ethtool_convert_legacy_u32_to_link_mode(config.advertising,
 | -	linkmode_copy(config.advertising, phy->advertising);
 | ||||||
| -						phy->advertising);
 |  | ||||||
| -	config.interface = pl->link_config.interface;
 | -	config.interface = pl->link_config.interface;
 | ||||||
| -
 | -
 | ||||||
|  	/* |  	/* | ||||||
|  	 * This is the new way of dealing with flow control for PHYs, |  	 * This is the new way of dealing with flow control for PHYs, | ||||||
|  	 * as described by Timur Tabi in commit 529ed1275263 ("net: phy: |  	 * 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 |  	 * using our validate call to the MAC, we rely upon the MAC | ||||||
|  	 * clearing the bits from both supported and advertising fields. |  	 * 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);
 | +	phy_support_asym_pause(phy);
 | ||||||
| +
 | +
 | ||||||
| +	memset(&config, 0, sizeof(config));
 | +	memset(&config, 0, sizeof(config));
 | ||||||
| +	ethtool_convert_legacy_u32_to_link_mode(supported, phy->supported);
 | +	linkmode_copy(supported, phy->supported);
 | ||||||
| +	ethtool_convert_legacy_u32_to_link_mode(config.advertising,
 | +	linkmode_copy(config.advertising, phy->advertising);
 | ||||||
| +						phy->advertising);
 |  | ||||||
| +	config.interface = pl->link_config.interface;
 | +	config.interface = pl->link_config.interface;
 | ||||||
|   |   | ||||||
|  	ret = phylink_validate(pl, supported, &config); |  	ret = phylink_validate(pl, supported, &config); | ||||||
|  | |||||||
| @ -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); |  | ||||||
| @ -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); |  | ||||||
| @ -13,7 +13,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/net/phy/sfp-bus.c
 | --- a/drivers/net/phy/sfp-bus.c
 | ||||||
| +++ b/drivers/net/phy/sfp-bus.c
 | +++ b/drivers/net/phy/sfp-bus.c
 | ||||||
| @@ -9,6 +9,12 @@
 | @@ -10,6 +10,12 @@
 | ||||||
|   |   | ||||||
|  #include "sfp.h" |  #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 |   * 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; |  	const struct sfp_socket_ops *socket_ops; | ||||||
|  	struct device *sfp_dev; |  	struct device *sfp_dev; | ||||||
|  	struct sfp *sfp; |  	struct sfp *sfp; | ||||||
| @ -34,7 +34,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|   |   | ||||||
|  	const struct sfp_upstream_ops *upstream_ops; |  	const struct sfp_upstream_ops *upstream_ops; | ||||||
|  	void *upstream; |  	void *upstream; | ||||||
| @@ -30,6 +37,46 @@ struct sfp_bus {
 | @@ -31,6 +38,46 @@ struct sfp_bus {
 | ||||||
|  	bool started; |  	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 |   * 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 |   * @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); |  			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); |  	bitmap_or(support, support, modes, __ETHTOOL_LINK_MODE_MASK_NBITS); | ||||||
|   |   | ||||||
|  	phylink_set(support, Autoneg); |  	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); |  	const struct sfp_upstream_ops *ops = sfp_get_upstream_ops(bus); | ||||||
|  	int ret = 0; |  	int ret = 0; | ||||||
|   |   | ||||||
| @ -100,7 +100,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  	if (ops && ops->module_insert) |  	if (ops && ops->module_insert) | ||||||
|  		ret = ops->module_insert(bus->upstream, id); |  		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) |  	if (ops && ops->module_remove) | ||||||
|  		ops->module_remove(bus->upstream); |  		ops->module_remove(bus->upstream); | ||||||
|  | |||||||
| @ -17,7 +17,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/net/phy/sfp-bus.c
 | --- a/drivers/net/phy/sfp-bus.c
 | ||||||
| +++ b/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; |  	bool started; | ||||||
|  }; |  }; | ||||||
|   |   | ||||||
|  | |||||||
| @ -16,7 +16,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/net/phy/sfp.c
 | --- a/drivers/net/phy/sfp.c
 | ||||||
| +++ b/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]; |  	struct gpio_desc *gpio[GPIO_MAX]; | ||||||
|  	int gpio_irq[GPIO_MAX]; |  	int gpio_irq[GPIO_MAX]; | ||||||
|   |   | ||||||
| @ -27,7 +27,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  	unsigned int state; |  	unsigned int state; | ||||||
|  	struct delayed_work poll; |  	struct delayed_work poll; | ||||||
|  	struct delayed_work timeout; |  	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 */ |  /* 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) |  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) |  static void sfp_sm_probe_for_phy(struct sfp *sfp) | ||||||
|  { |  { | ||||||
|  	/* Setting the serdes link mode is guesswork: there's no |  	/* 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); |  		 (int)sizeof(id.ext.datecode), id.ext.datecode); | ||||||
|   |   | ||||||
|  	/* Check whether we support this module */ |  	/* Check whether we support this module */ | ||||||
| @ -147,7 +147,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  		dev_err(sfp->dev, |  		dev_err(sfp->dev, | ||||||
|  			"module is not supported - phys id 0x%02x 0x%02x\n", |  			"module is not supported - phys id 0x%02x 0x%02x\n", | ||||||
|  			sfp->id.base.phys_id, sfp->id.base.phys_ext_id); |  			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) |  		if (sfp->mod_phy) | ||||||
|  			sfp_sm_phy_detach(sfp); |  			sfp_sm_phy_detach(sfp); | ||||||
|  		sfp_module_tx_disable(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); |  		sfp_sm_next(sfp, SFP_S_DOWN, 0); | ||||||
|  		return; |  		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) |  		    sfp->sm_dev_state != SFP_DEV_UP) | ||||||
|  			break; |  			break; | ||||||
|   |   | ||||||
| @ -167,7 +167,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|   |   | ||||||
|  		/* Initialise the fault clearance retries */ |  		/* Initialise the fault clearance retries */ | ||||||
|  		sfp->sm_retries = 5; |  		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); |  	struct sfp *sfp = container_of(work, struct sfp, poll.work); | ||||||
|   |   | ||||||
|  	sfp_check_state(sfp); |  	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) |  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; |  	const struct sff_data *sff; | ||||||
|  |  	struct i2c_adapter *i2c; | ||||||
|  	struct sfp *sfp; |  	struct sfp *sfp; | ||||||
| -	bool poll = false;
 | -	bool poll = false;
 | ||||||
|  	int err, i; |  	int err, i; | ||||||
|   |   | ||||||
|  	sfp = sfp_alloc(&pdev->dev); |  	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]); |  		sfp->gpio_irq[i] = gpiod_to_irq(sfp->gpio[i]); | ||||||
|  		if (!sfp->gpio_irq[i]) { |  		if (!sfp->gpio_irq[i]) { | ||||||
| @ -196,7 +196,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |||||||
|  			continue; |  			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); |  						dev_name(sfp->dev), sfp); | ||||||
|  		if (err) { |  		if (err) { | ||||||
|  			sfp->gpio_irq[i] = 0; |  			sfp->gpio_irq[i] = 0; | ||||||
|  | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -2487,7 +2487,9 @@ ar8xxx_phy_read_status(struct phy_device *phydev) | |||||||
| 	struct switch_port_link link; | 	struct switch_port_link link; | ||||||
| 
 | 
 | ||||||
| 	/* check for switch port link changes */ | 	/* check for switch port link changes */ | ||||||
|  | #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 1, 0) | ||||||
| 	if (phydev->state == PHY_CHANGELINK) | 	if (phydev->state == PHY_CHANGELINK) | ||||||
|  | #endif | ||||||
| 		ar8xxx_check_link_states(priv); | 		ar8xxx_check_link_states(priv); | ||||||
| 
 | 
 | ||||||
| 	if (phydev->mdio.addr != 0) | 	if (phydev->mdio.addr != 0) | ||||||
| @ -2628,6 +2630,14 @@ found: | |||||||
| 	priv->use_count++; | 	priv->use_count++; | ||||||
| 
 | 
 | ||||||
| 	if (phydev->mdio.addr == 0) { | 	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)) { | 		if (ar8xxx_has_gige(priv)) { | ||||||
| 			phydev->supported = SUPPORTED_1000baseT_Full; | 			phydev->supported = SUPPORTED_1000baseT_Full; | ||||||
| 			phydev->advertising = ADVERTISED_1000baseT_Full; | 			phydev->advertising = ADVERTISED_1000baseT_Full; | ||||||
| @ -2635,6 +2645,7 @@ found: | |||||||
| 			phydev->supported = SUPPORTED_100baseT_Full; | 			phydev->supported = SUPPORTED_100baseT_Full; | ||||||
| 			phydev->advertising = ADVERTISED_100baseT_Full; | 			phydev->advertising = ADVERTISED_100baseT_Full; | ||||||
| 		} | 		} | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| 		if (priv->chip->config_at_probe) { | 		if (priv->chip->config_at_probe) { | ||||||
| 			priv->phy = phydev; | 			priv->phy = phydev; | ||||||
| @ -2645,8 +2656,14 @@ found: | |||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		if (ar8xxx_has_gige(priv)) { | 		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->supported |= SUPPORTED_1000baseT_Full; | ||||||
| 			phydev->advertising |= ADVERTISED_1000baseT_Full; | 			phydev->advertising |= ADVERTISED_1000baseT_Full; | ||||||
|  | #endif | ||||||
| 		} | 		} | ||||||
| 		if (priv->chip->phy_rgmii_set) | 		if (priv->chip->phy_rgmii_set) | ||||||
| 			priv->chip->phy_rgmii_set(priv, phydev); | 			priv->chip->phy_rgmii_set(priv, phydev); | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| 
 | 
 | ||||||
| --- a/include/linux/module.h
 | --- a/include/linux/module.h
 | ||||||
| +++ b/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" */ |  /* Generic info of form tag = "info" */ | ||||||
|  #define MODULE_INFO(tag, info) __MODULE_INFO(tag, 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... */ |  /* For userspace: you can also call me... */ | ||||||
|  #define MODULE_ALIAS(_alias) MODULE_INFO(alias, _alias) |  #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 |   * Author(s), use "Name <email>" or just "Name", for multiple | ||||||
|   * authors use multiple MODULE_AUTHOR() statements/lines. |   * 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. */ |  /* Creates an alias so file2alias.c can find device table. */ | ||||||
|  #define MODULE_DEVICE_TABLE(type, name)					\ |  #define MODULE_DEVICE_TABLE(type, name)					\ | ||||||
|  extern typeof(name) __mod_##type##__##name##_device_table		\ |  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) |  #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)
 | +#define MODULE_VERSION(_version) __MODULE_INFO_DISABLED(version)
 | ||||||
|  #else |  #else | ||||||
|  #define MODULE_VERSION(_version)					\ |  #define MODULE_VERSION(_version)					\ | ||||||
|  	static struct module_version_attribute ___modver_attr = {	\ |  	MODULE_INFO(version, _version);					\ | ||||||
| @@ -257,7 +260,7 @@ extern typeof(name) __mod_##type##__##na
 | @@ -271,7 +274,7 @@ extern typeof(name) __mod_##type##__##na
 | ||||||
|  /* Optional firmware file (or files) needed by the module |  /* Optional firmware file (or files) needed by the module | ||||||
|   * format is simply firmware file name.  Multiple firmware |   * format is simply firmware file name.  Multiple firmware | ||||||
|   * files require multiple MODULE_FIRMWARE() specifiers */ |   * files require multiple MODULE_FIRMWARE() specifiers */ | ||||||
| -#define MODULE_FIRMWARE(_firmware) MODULE_INFO(firmware, _firmware)
 | -#define MODULE_FIRMWARE(_firmware) MODULE_INFO(firmware, _firmware)
 | ||||||
| +#define MODULE_FIRMWARE(_firmware) MODULE_INFO_STRIP(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
 | --- a/include/linux/moduleparam.h
 | ||||||
| +++ b/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. */ |  /* Chosen so that structs with an unsigned long line up. */ | ||||||
|  #define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long)) |  #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)
 | +#define __MODULE_INFO_STRIP(tag, name, info) __MODULE_INFO(tag, name, info)
 | ||||||
| +#endif
 | +#endif
 | ||||||
| +
 | +
 | ||||||
|  #ifdef MODULE | +#ifdef MODULE
 | ||||||
|  #define __MODULE_INFO(tag, name, info)					  \ |  #define __MODULE_INFO(tag, name, info)					  \ | ||||||
|  static const char __UNIQUE_ID(name)[]					  \ |  static const char __UNIQUE_ID(name)[]					  \ | ||||||
| @@ -24,8 +34,7 @@ static const char __UNIQUE_ID(name)[]
 |    __used __attribute__((section(".modinfo"), unused, aligned(1)))	  \ | ||||||
|    = __stringify(tag) "=" info |    = __MODULE_INFO_PREFIX __stringify(tag) "=" info | ||||||
|  #else  /* !MODULE */ | +#else
 | ||||||
|  /* This struct is here for syntactic coherency, it is not used */ |  | ||||||
| -#define __MODULE_INFO(tag, name, info)					  \
 |  | ||||||
| -  struct __UNIQUE_ID(name) {}
 |  | ||||||
| +#define __MODULE_INFO(tag, name, info) __MODULE_INFO_DISABLED(name)
 | +#define __MODULE_INFO(tag, name, info) __MODULE_INFO_DISABLED(name)
 | ||||||
|  #endif | +#endif
 | ||||||
|  |   | ||||||
|  #define __MODULE_PARM_TYPE(name, _type)					  \ |  #define __MODULE_PARM_TYPE(name, _type)					  \ | ||||||
|    __MODULE_INFO(parmtype, name##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 |  /* One for each parameter, describing how to use it.  Some files do | ||||||
|     multiple of these per line, so can't just use MODULE_INFO. */ |     multiple of these per line, so can't just use MODULE_INFO. */ | ||||||
|  #define MODULE_PARM_DESC(_parm, desc) \ |  #define MODULE_PARM_DESC(_parm, desc) \ | ||||||
| @ -98,7 +96,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|   |   | ||||||
| --- a/init/Kconfig
 | --- a/init/Kconfig
 | ||||||
| +++ b/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. |  	  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 |  config MODULES_TREE_LOOKUP | ||||||
| --- a/kernel/module.c
 | --- a/kernel/module.c
 | ||||||
| +++ b/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) |  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) |  	if (flags & MODULE_INIT_IGNORE_VERMAGIC) | ||||||
|  		modmagic = NULL; |  		modmagic = NULL; | ||||||
|   |   | ||||||
| @@ -3052,6 +3054,7 @@ static int check_modinfo(struct module *
 | @@ -3130,6 +3132,7 @@ static int check_modinfo(struct module *
 | ||||||
|  				mod->name); |  				mod->name); | ||||||
|  		add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK); |  		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
 | --- a/scripts/mod/modpost.c
 | ||||||
| +++ b/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); |  		symname = remove_dot(info.strtab + sym->st_name); | ||||||
|   |   | ||||||
|  		handle_modversions(mod, &info, sym, symname); |  		handle_modversions(mod, &info, sym, symname); | ||||||
| @ -145,9 +143,9 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  		handle_moddevtable(mod, &info, sym, symname); |  		handle_moddevtable(mod, &info, sym, symname); | ||||||
| +#endif
 | +#endif
 | ||||||
|  	} |  	} | ||||||
|  	if (!is_vmlinux(modname) || vmlinux_section_warnings) |   | ||||||
|  		check_sec_ref(mod, modname, &info); |  	/* Apply symbol namespaces from __kstrtabns_<symbol> entries. */ | ||||||
| @@ -2146,8 +2148,10 @@ static void add_header(struct buffer *b,
 | @@ -2265,8 +2267,10 @@ static void add_header(struct buffer *b,
 | ||||||
|  	buf_printf(b, "\n"); |  	buf_printf(b, "\n"); | ||||||
|  	buf_printf(b, "BUILD_SALT;\n"); |  	buf_printf(b, "BUILD_SALT;\n"); | ||||||
|  	buf_printf(b, "\n"); |  	buf_printf(b, "\n"); | ||||||
| @ -157,8 +155,8 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| +#endif
 | +#endif
 | ||||||
|  	buf_printf(b, "\n"); |  	buf_printf(b, "\n"); | ||||||
|  	buf_printf(b, "__visible struct module __this_module\n"); |  	buf_printf(b, "__visible struct module __this_module\n"); | ||||||
|  	buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n"); |  	buf_printf(b, "__section(.gnu.linkonce.this_module) = {\n"); | ||||||
| @@ -2164,8 +2168,10 @@ static void add_header(struct buffer *b,
 | @@ -2283,8 +2287,10 @@ static void add_header(struct buffer *b,
 | ||||||
|   |   | ||||||
|  static void add_intree_flag(struct buffer *b, int is_intree) |  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 */ |  /* 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) |  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) |  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) |  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); |  		add_staging_flag(&buf, mod->name); | ||||||
|  		err |= add_versions(&buf, mod); |  		err |= add_versions(&buf, mod); | ||||||
|  		add_depends(&buf, mod, modules); |  		add_depends(&buf, mod); | ||||||
| +#ifndef CONFIG_MODULE_STRIPPED
 | +#ifndef CONFIG_MODULE_STRIPPED
 | ||||||
|  		add_moddevtable(&buf, mod); |  		add_moddevtable(&buf, mod); | ||||||
| +#endif
 | +#endif
 | ||||||
|  | |||||||
| @ -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) |  | ||||||
|  	@: |  | ||||||
|   |  | ||||||
| @ -13,7 +13,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| 
 | 
 | ||||||
| --- a/include/uapi/linux/spi/spidev.h
 | --- a/include/uapi/linux/spi/spidev.h
 | ||||||
| +++ b/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() ... */ |  /* not all platforms use <asm-generic/ioctl.h> or _IOC_TYPECHECK() ... */ | ||||||
|  #define SPI_MSGSIZE(N) \ |  #define SPI_MSGSIZE(N) \ | ||||||
|  | |||||||
| @ -19,45 +19,19 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org> | |||||||
|  include/asm-generic/vmlinux.lds.h | 63 ++++++++++++++++++++------------------- |  include/asm-generic/vmlinux.lds.h | 63 ++++++++++++++++++++------------------- | ||||||
|  7 files changed, 55 insertions(+), 51 deletions(-) |  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
 | --- a/arch/arm/Kconfig
 | ||||||
| +++ b/arch/arm/Kconfig
 | +++ b/arch/arm/Kconfig
 | ||||||
| @@ -98,6 +98,7 @@ config ARM
 | @@ -111,6 +111,7 @@ config ARM
 | ||||||
|  	select HAVE_UID16 |  	select HAVE_UID16 | ||||||
|  	select HAVE_VIRT_CPU_ACCOUNTING_GEN |  	select HAVE_VIRT_CPU_ACCOUNTING_GEN | ||||||
|  	select IRQ_FORCED_THREADING |  	select IRQ_FORCED_THREADING | ||||||
| +	select HAVE_LD_DEAD_CODE_DATA_ELIMINATION
 | +	select HAVE_LD_DEAD_CODE_DATA_ELIMINATION
 | ||||||
|  	select MODULES_USE_ELF_REL |  	select MODULES_USE_ELF_REL | ||||||
|  	select NEED_DMA_MAP_STATE |  	select NEED_DMA_MAP_STATE | ||||||
|  	select NO_BOOTMEM |  	select OF_EARLY_FLATTREE if OF | ||||||
| --- a/arch/arm/boot/compressed/Makefile
 | --- a/arch/arm/boot/compressed/Makefile
 | ||||||
| +++ b/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) |  ORIG_CFLAGS := $(KBUILD_CFLAGS) | ||||||
|  KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS)) |  KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS)) | ||||||
|  endif |  endif | ||||||
| @ -160,33 +134,3 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org> | |||||||
|  	}								\ |  	}								\ | ||||||
|  	. = __stubs_start + SIZEOF(.stubs);				\ |  	. = __stubs_start + SIZEOF(.stubs);				\ | ||||||
|  	__stubs_end = .;						\ |  	__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 = .; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  | |||||||
| @ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  /* Align . to a 8 byte boundary equals to maximum function alignment. */ |  /* Align . to a 8 byte boundary equals to maximum function alignment. */ | ||||||
|  #define ALIGN_FUNCTION()  . = ALIGN(8) |  #define ALIGN_FUNCTION()  . = ALIGN(8) | ||||||
|   |   | ||||||
| @@ -372,14 +382,14 @@
 | @@ -405,14 +415,14 @@
 | ||||||
|  	/* Kernel symbol table: Normal symbols */			\ |  	/* Kernel symbol table: Normal symbols */			\ | ||||||
|  	__ksymtab         : AT(ADDR(__ksymtab) - LOAD_OFFSET) {		\ |  	__ksymtab         : AT(ADDR(__ksymtab) - LOAD_OFFSET) {		\ | ||||||
|  		__start___ksymtab = .;					\ |  		__start___ksymtab = .;					\ | ||||||
| @ -47,7 +47,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  		__stop___ksymtab_gpl = .;				\ |  		__stop___ksymtab_gpl = .;				\ | ||||||
|  	}								\ |  	}								\ | ||||||
|  									\ |  									\ | ||||||
| @@ -441,7 +451,7 @@
 | @@ -474,7 +484,7 @@
 | ||||||
|  									\ |  									\ | ||||||
|  	/* Kernel symbol table: strings */				\ |  	/* Kernel symbol table: strings */				\ | ||||||
|          __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) {	\ |          __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) {	\ | ||||||
| @ -56,7 +56,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  	}								\ |  	}								\ | ||||||
|  									\ |  									\ | ||||||
|  	/* __*init sections */						\ |  	/* __*init sections */						\ | ||||||
| @@ -841,6 +851,8 @@
 | @@ -865,6 +875,8 @@
 | ||||||
|  	EXIT_TEXT							\ |  	EXIT_TEXT							\ | ||||||
|  	EXIT_DATA							\ |  	EXIT_DATA							\ | ||||||
|  	EXIT_CALL							\ |  	EXIT_CALL							\ | ||||||
| @ -64,12 +64,12 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| +	SYMTAB_DISCARD_GPL						\
 | +	SYMTAB_DISCARD_GPL						\
 | ||||||
|  	*(.discard)							\ |  	*(.discard)							\ | ||||||
|  	*(.discard.*)							\ |  	*(.discard.*)							\ | ||||||
|  	} |  	*(.modinfo)							\ | ||||||
| --- a/include/linux/export.h
 | --- a/include/linux/export.h
 | ||||||
| +++ b/include/linux/export.h
 | +++ b/include/linux/export.h
 | ||||||
| @@ -74,12 +74,19 @@ struct kernel_symbol {
 | @@ -98,18 +98,26 @@ struct kernel_symbol {
 | ||||||
|  }; |   | ||||||
|  #endif |  #else | ||||||
|   |   | ||||||
| +#ifdef MODULE
 | +#ifdef MODULE
 | ||||||
| +#define __EXPORT_SUFFIX(sym)
 | +#define __EXPORT_SUFFIX(sym)
 | ||||||
| @ -77,20 +77,28 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| +#define __EXPORT_SUFFIX(sym) "+" #sym
 | +#define __EXPORT_SUFFIX(sym) "+" #sym
 | ||||||
| +#endif
 | +#endif
 | ||||||
| +
 | +
 | ||||||
|  /* For every exported symbol, place a struct in the __ksymtab section */ |  #define ___export_symbol_common(sym, sec)				\ | ||||||
|  #define ___EXPORT_SYMBOL(sym, sec)					\ |  | ||||||
|  	extern typeof(sym) sym;						\ |  	extern typeof(sym) sym;						\ | ||||||
|  	__CRC_SYMBOL(sym, sec)						\ |  	__CRC_SYMBOL(sym, sec);						\ | ||||||
|  	static const char __kstrtab_##sym[]				\ |  	static const char __kstrtab_##sym[]				\ | ||||||
| -	__attribute__((section("__ksymtab_strings"), used, aligned(1)))	\
 | -	__attribute__((section("__ksymtab_strings"), used, aligned(1)))	\
 | ||||||
| +	__attribute__((section("__ksymtab_strings"			\
 | +	__attribute__((section("__ksymtab_strings"			\
 | ||||||
| +	  __EXPORT_SUFFIX(sym)), used, aligned(1)))			\
 | +	  __EXPORT_SUFFIX(sym)), used, aligned(1)))			\
 | ||||||
|  	= #sym;								\ |  	= #sym								\ | ||||||
|  	__KSYMTAB_ENTRY(sym, sec) |   | ||||||
|  |  /* 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
 | --- a/scripts/Makefile.build
 | ||||||
| +++ b/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) |  # Linker scripts preprocessor (.lds.S -> .lds) | ||||||
|  # --------------------------------------------------------------------------- |  # --------------------------------------------------------------------------- | ||||||
|  quiet_cmd_cpp_lds_S = LDS     $@ |  quiet_cmd_cpp_lds_S = LDS     $@ | ||||||
|  | |||||||
| @ -23,15 +23,15 @@ Signed-off-by: Imre Kaloz <kaloz@openwrt.org> | |||||||
|  	{ {0x02, 0x21}, "lz4", unlz4 }, |  	{ {0x02, 0x21}, "lz4", unlz4 }, | ||||||
| --- a/scripts/Makefile.lib
 | --- a/scripts/Makefile.lib
 | ||||||
| +++ b/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    $@ |  quiet_cmd_lzma = LZMA    $@ | ||||||
|  cmd_lzma = (cat $(filter-out FORCE,$^) | \ | -      cmd_lzma = { cat $(real-prereqs) | lzma -9; $(size_append); } > $@
 | ||||||
| -	lzma -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
 | +      cmd_lzma = { cat $(real-prereqs) | lzma e -d20 -lc1 -lp2 -pb2 -eos -si -so; $(size_append); } > $@
 | ||||||
| +	lzma e -d20 -lc1 -lp2 -pb2 -eos -si -so && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
 |  | ||||||
|  	(rm -f $@ ; false) |  | ||||||
|   |   | ||||||
|  quiet_cmd_lzo = LZO     $@ |  quiet_cmd_lzo = LZO     $@ | ||||||
|  |        cmd_lzo = { cat $(real-prereqs) | lzop -9; $(size_append); } > $@ | ||||||
| --- a/usr/gen_initramfs_list.sh
 | --- a/usr/gen_initramfs_list.sh
 | ||||||
| +++ b/usr/gen_initramfs_list.sh
 | +++ b/usr/gen_initramfs_list.sh
 | ||||||
| @@ -229,7 +229,7 @@ cpio_list=
 | @@ -229,7 +229,7 @@ cpio_list=
 | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| 
 | 
 | ||||||
| --- a/net/netfilter/Kconfig
 | --- a/net/netfilter/Kconfig
 | ||||||
| +++ b/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 |  config NF_CONNTRACK_H323 | ||||||
|  	tristate "H.323 protocol support" |  	tristate "H.323 protocol support" | ||||||
| @ -17,7 +17,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  	depends on NETFILTER_ADVANCED |  	depends on NETFILTER_ADVANCED | ||||||
|  	help |  	help | ||||||
|  	  H.323 is a VoIP signalling protocol from ITU-T. As one of the most |  	  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 |  config NETFILTER_XT_TARGET_TCPMSS | ||||||
|  	tristate '"TCPMSS" target support' |  	tristate '"TCPMSS" target support' | ||||||
|  | |||||||
| @ -43,8 +43,8 @@ Signed-off-by: John Crispin <john@phrozen.org> | |||||||
|  	select CRYPTO_BLKCIPHER2 |  	select CRYPTO_BLKCIPHER2 | ||||||
|  	select CRYPTO_ALGAPI |  	select CRYPTO_ALGAPI | ||||||
|   |   | ||||||
| @@ -64,7 +64,7 @@ config CRYPTO_BLKCIPHER2
 | @@ -63,7 +63,7 @@ config CRYPTO_BLKCIPHER2
 | ||||||
|  	select CRYPTO_WORKQUEUE |  	select CRYPTO_RNG2 | ||||||
|   |   | ||||||
|  config CRYPTO_HASH |  config CRYPTO_HASH | ||||||
| -	tristate
 | -	tristate
 | ||||||
| @ -52,7 +52,7 @@ Signed-off-by: John Crispin <john@phrozen.org> | |||||||
|  	select CRYPTO_HASH2 |  	select CRYPTO_HASH2 | ||||||
|  	select CRYPTO_ALGAPI |  	select CRYPTO_ALGAPI | ||||||
|   |   | ||||||
| @@ -73,7 +73,7 @@ config CRYPTO_HASH2
 | @@ -72,7 +72,7 @@ config CRYPTO_HASH2
 | ||||||
|  	select CRYPTO_ALGAPI2 |  	select CRYPTO_ALGAPI2 | ||||||
|   |   | ||||||
|  config CRYPTO_RNG |  config CRYPTO_RNG | ||||||
| @ -73,7 +73,7 @@ Signed-off-by: John Crispin <john@phrozen.org> | |||||||
|  	bool |  	bool | ||||||
| --- a/drivers/ssb/Kconfig
 | --- a/drivers/ssb/Kconfig
 | ||||||
| +++ b/drivers/ssb/Kconfig
 | +++ b/drivers/ssb/Kconfig
 | ||||||
| @@ -28,6 +28,7 @@ config SSB_SPROM
 | @@ -29,6 +29,7 @@ config SSB_SPROM
 | ||||||
|  config SSB_BLOCKIO |  config SSB_BLOCKIO | ||||||
|  	bool |  	bool | ||||||
|  	depends on SSB |  	depends on SSB | ||||||
| @ -81,7 +81,7 @@ Signed-off-by: John Crispin <john@phrozen.org> | |||||||
|   |   | ||||||
|  config SSB_PCIHOST_POSSIBLE |  config SSB_PCIHOST_POSSIBLE | ||||||
|  	bool |  	bool | ||||||
| @@ -48,7 +49,7 @@ config SSB_PCIHOST
 | @@ -49,7 +50,7 @@ config SSB_PCIHOST
 | ||||||
|  config SSB_B43_PCI_BRIDGE |  config SSB_B43_PCI_BRIDGE | ||||||
|  	bool |  	bool | ||||||
|  	depends on SSB_PCIHOST |  	depends on SSB_PCIHOST | ||||||
| @ -92,7 +92,7 @@ Signed-off-by: John Crispin <john@phrozen.org> | |||||||
|  	bool |  	bool | ||||||
| --- a/lib/Kconfig
 | --- a/lib/Kconfig
 | ||||||
| +++ b/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 |  # Textsearch support is select'ed if needed | ||||||
|  # |  # | ||||||
|  config TEXTSEARCH |  config TEXTSEARCH | ||||||
| @ -115,7 +115,7 @@ Signed-off-by: John Crispin <john@phrozen.org> | |||||||
|  	bool |  	bool | ||||||
| --- a/net/netfilter/Kconfig
 | --- a/net/netfilter/Kconfig
 | ||||||
| +++ b/net/netfilter/Kconfig
 | +++ b/net/netfilter/Kconfig
 | ||||||
| @@ -10,7 +10,7 @@ config NETFILTER_INGRESS
 | @@ -11,7 +11,7 @@ config NETFILTER_INGRESS
 | ||||||
|  	  infrastructure. |  	  infrastructure. | ||||||
|   |   | ||||||
|  config NETFILTER_NETLINK |  config NETFILTER_NETLINK | ||||||
| @ -126,14 +126,15 @@ Signed-off-by: John Crispin <john@phrozen.org> | |||||||
|  	bool |  	bool | ||||||
| --- a/net/wireless/Kconfig
 | --- a/net/wireless/Kconfig
 | ||||||
| +++ b/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 |  config WIRELESS_EXT | ||||||
| -	bool
 | -	bool
 | ||||||
| +	bool "Wireless extensions"
 | +	bool "Wireless extensions"
 | ||||||
|   |   | ||||||
|  config WEXT_CORE |  config WEXT_CORE | ||||||
|  	def_bool y |  	def_bool y | ||||||
| @@ -11,10 +11,10 @@ config WEXT_PROC
 | @@ -12,10 +12,10 @@ config WEXT_PROC
 | ||||||
|  	depends on WEXT_CORE |  	depends on WEXT_CORE | ||||||
|   |   | ||||||
|  config WEXT_SPY |  config WEXT_SPY | ||||||
| @ -146,7 +147,7 @@ Signed-off-by: John Crispin <john@phrozen.org> | |||||||
|   |   | ||||||
|  config CFG80211 |  config CFG80211 | ||||||
|  	tristate "cfg80211 - wireless configuration API" |  	tristate "cfg80211 - wireless configuration API" | ||||||
| @@ -202,7 +202,7 @@ config CFG80211_WEXT_EXPORT
 | @@ -203,7 +203,7 @@ config CFG80211_WEXT_EXPORT
 | ||||||
|  endif # CFG80211 |  endif # CFG80211 | ||||||
|   |   | ||||||
|  config LIB80211 |  config LIB80211 | ||||||
| @ -155,29 +156,29 @@ Signed-off-by: John Crispin <john@phrozen.org> | |||||||
|  	default n |  	default n | ||||||
|  	help |  	help | ||||||
|  	  This options enables a library of common routines used |  	  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. |  	  Drivers should select this themselves if needed. | ||||||
|   |   | ||||||
|  config LIB80211_CRYPT_WEP |  config LIB80211_CRYPT_WEP | ||||||
| -	tristate
 | -	tristate
 | ||||||
| +	tristate "LIB80211_CRYPT_WEP"
 | +	tristate "LIB80211_CRYPT_WEP"
 | ||||||
| +	select LIB80211
 |  	select CRYPTO_LIB_ARC4 | ||||||
|   |   | ||||||
|  config LIB80211_CRYPT_CCMP |  config LIB80211_CRYPT_CCMP | ||||||
| -	tristate
 | -	tristate
 | ||||||
| +	tristate "LIB80211_CRYPT_CCMP"
 | +	tristate "LIB80211_CRYPT_CCMP"
 | ||||||
| +	select LIB80211
 |  	select CRYPTO_AES | ||||||
|  |  	select CRYPTO_CCM | ||||||
|   |   | ||||||
|  config LIB80211_CRYPT_TKIP |  config LIB80211_CRYPT_TKIP | ||||||
| -	tristate
 | -	tristate
 | ||||||
| +	tristate "LIB80211_CRYPT_TKIP"
 | +	tristate "LIB80211_CRYPT_TKIP"
 | ||||||
| +	select LIB80211
 |  	select CRYPTO_LIB_ARC4 | ||||||
|   |   | ||||||
|  config LIB80211_DEBUG |  config LIB80211_DEBUG | ||||||
|  	bool "lib80211 debugging messages" |  | ||||||
| --- a/sound/core/Kconfig
 | --- a/sound/core/Kconfig
 | ||||||
| +++ b/sound/core/Kconfig
 | +++ b/sound/core/Kconfig
 | ||||||
| @@ -16,7 +16,7 @@ config SND_DMAENGINE_PCM
 | @@ -17,7 +17,7 @@ config SND_DMAENGINE_PCM
 | ||||||
|  	tristate |  	tristate | ||||||
|   |   | ||||||
|  config SND_HWDEP |  config SND_HWDEP | ||||||
| @ -186,7 +187,7 @@ Signed-off-by: John Crispin <john@phrozen.org> | |||||||
|   |   | ||||||
|  config SND_SEQ_DEVICE |  config SND_SEQ_DEVICE | ||||||
|  	tristate |  	tristate | ||||||
| @@ -26,7 +26,7 @@ config SND_RAWMIDI
 | @@ -27,7 +27,7 @@ config SND_RAWMIDI
 | ||||||
|  	select SND_SEQ_DEVICE if SND_SEQUENCER != n |  	select SND_SEQ_DEVICE if SND_SEQUENCER != n | ||||||
|   |   | ||||||
|  config SND_COMPRESS_OFFLOAD |  config SND_COMPRESS_OFFLOAD | ||||||
|  | |||||||
| @ -18,14 +18,14 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  # subsystems should select the appropriate symbols. |  # subsystems should select the appropriate symbols. | ||||||
|   |   | ||||||
|  config REGMAP |  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 |  	select IRQ_DOMAIN if REGMAP_IRQ | ||||||
| -	bool
 | -	bool
 | ||||||
| +	tristate
 | +	tristate
 | ||||||
|   |   | ||||||
|  config REGCACHE_COMPRESSED |  config REGCACHE_COMPRESSED | ||||||
|  	select LZO_COMPRESS |  	select LZO_COMPRESS | ||||||
| @@ -18,6 +17,7 @@ config REGMAP_AC97
 | @@ -18,38 +17,49 @@ config REGMAP_AC97
 | ||||||
|   |   | ||||||
|  config REGMAP_I2C |  config REGMAP_I2C | ||||||
|  	tristate |  	tristate | ||||||
| @ -33,7 +33,9 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  	depends on I2C |  	depends on I2C | ||||||
|   |   | ||||||
|  config REGMAP_SLIMBUS |  config REGMAP_SLIMBUS | ||||||
| @@ -26,20 +26,26 @@ config REGMAP_SLIMBUS
 |  	tristate | ||||||
|  | +	select REGMAP
 | ||||||
|  |  	depends on SLIMBUS | ||||||
|   |   | ||||||
|  config REGMAP_SPI |  config REGMAP_SPI | ||||||
|  	tristate |  	tristate | ||||||
| @ -42,13 +44,13 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  	depends on SPI |  	depends on SPI | ||||||
|   |   | ||||||
|  config REGMAP_SPMI |  config REGMAP_SPMI | ||||||
| +	select REGMAP
 |  | ||||||
|  	tristate |  	tristate | ||||||
|  | +	select REGMAP
 | ||||||
|  	depends on SPMI |  	depends on SPMI | ||||||
|   |   | ||||||
|  config REGMAP_W1 |  config REGMAP_W1 | ||||||
| +	select REGMAP
 |  | ||||||
|  	tristate |  	tristate | ||||||
|  | +	select REGMAP
 | ||||||
|  	depends on W1 |  	depends on W1 | ||||||
|   |   | ||||||
|  config REGMAP_MMIO |  config REGMAP_MMIO | ||||||
| @ -56,10 +58,23 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| +	select REGMAP
 | +	select REGMAP
 | ||||||
|   |   | ||||||
|  config REGMAP_IRQ |  config REGMAP_IRQ | ||||||
| +	select REGMAP
 |  | ||||||
|  	bool |  	bool | ||||||
|  | +	select REGMAP
 | ||||||
|   |   | ||||||
|  config REGMAP_SOUNDWIRE |  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
 | --- a/drivers/base/regmap/Makefile
 | ||||||
| +++ b/drivers/base/regmap/Makefile
 | +++ b/drivers/base/regmap/Makefile
 | ||||||
| @@ -2,10 +2,14 @@
 | @@ -2,10 +2,14 @@
 | ||||||
| @ -83,7 +98,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  obj-$(CONFIG_REGMAP_SLIMBUS) += regmap-slimbus.o |  obj-$(CONFIG_REGMAP_SLIMBUS) += regmap-slimbus.o | ||||||
| --- a/drivers/base/regmap/regmap.c
 | --- a/drivers/base/regmap/regmap.c
 | ||||||
| +++ b/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/device.h> | ||||||
|  #include <linux/slab.h> |  #include <linux/slab.h> | ||||||
|  #include <linux/export.h> |  #include <linux/export.h> | ||||||
| @ -91,7 +106,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  #include <linux/mutex.h> |  #include <linux/mutex.h> | ||||||
|  #include <linux/err.h> |  #include <linux/err.h> | ||||||
|  #include <linux/of.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; |  	return 0; | ||||||
|  } |  } | ||||||
|  postcore_initcall(regmap_initcall); |  postcore_initcall(regmap_initcall); | ||||||
| @ -99,7 +114,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| +MODULE_LICENSE("GPL");
 | +MODULE_LICENSE("GPL");
 | ||||||
| --- a/include/linux/regmap.h
 | --- a/include/linux/regmap.h
 | ||||||
| +++ b/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); \ |  	pollret ?: ((cond) ? 0 : -ETIMEDOUT); \ | ||||||
|  }) |  }) | ||||||
|   |   | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| 
 | 
 | ||||||
| --- a/crypto/Kconfig
 | --- a/crypto/Kconfig
 | ||||||
| +++ b/crypto/Kconfig
 | +++ b/crypto/Kconfig
 | ||||||
| @@ -144,13 +144,13 @@ config CRYPTO_MANAGER
 | @@ -120,13 +120,13 @@ config CRYPTO_MANAGER
 | ||||||
|  	  cbc(aes). |  	  cbc(aes). | ||||||
|   |   | ||||||
|  config CRYPTO_MANAGER2 |  config CRYPTO_MANAGER2 | ||||||
| @ -35,17 +35,27 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|   |   | ||||||
|  config CRYPTO_USER |  config CRYPTO_USER | ||||||
|  	tristate "Userspace cryptographic algorithm configuration" |  	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 |  config CRYPTO_MANAGER_DISABLE_TESTS | ||||||
|  	bool "Disable run-time self tests" |  	bool "Disable run-time self tests" | ||||||
|  	default y |  	default y | ||||||
| -	depends on CRYPTO_MANAGER2
 | @@ -145,6 +143,8 @@ config CRYPTO_MANAGER_DISABLE_TESTS
 | ||||||
|  	help |  | ||||||
|  	  Disable run-time self tests that normally take place at |  	  Disable run-time self tests that normally take place at | ||||||
|  	  algorithm registration. |  	  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
 | --- a/crypto/algboss.c
 | ||||||
| +++ b/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; |  	type = alg->cra_flags; | ||||||
|   |   | ||||||
|  	/* Do not test internal algorithms. */ |  	/* Do not test internal algorithms. */ | ||||||
|  | |||||||
							
								
								
									
										15
									
								
								target/linux/generic/hack-5.4/260-lib-arc4-unhide.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								target/linux/generic/hack-5.4/260-lib-arc4-unhide.patch
									
									
									
									
									
										Normal 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" | ||||||
| @ -37,7 +37,7 @@ Signed-off-by: John Crispin <john@phrozen.org> | |||||||
|  ifneq ($(CONFIG_DCB),) |  ifneq ($(CONFIG_DCB),) | ||||||
| --- a/net/rfkill/Kconfig
 | --- a/net/rfkill/Kconfig
 | ||||||
| +++ b/net/rfkill/Kconfig
 | +++ b/net/rfkill/Kconfig
 | ||||||
| @@ -1,7 +1,11 @@
 | @@ -2,7 +2,11 @@
 | ||||||
|  # |  # | ||||||
|  # RF switch subsystem configuration |  # RF switch subsystem configuration | ||||||
|  # |  # | ||||||
| @ -50,7 +50,7 @@ Signed-off-by: John Crispin <john@phrozen.org> | |||||||
|  	tristate "RF switch subsystem support" |  	tristate "RF switch subsystem support" | ||||||
|  	help |  	help | ||||||
|  	  Say Y here if you want to have control over RF switches |  	  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 |  # LED trigger support | ||||||
|  config RFKILL_LEDS |  config RFKILL_LEDS | ||||||
|  	bool |  	bool | ||||||
| @ -75,7 +75,7 @@ Signed-off-by: John Crispin <john@phrozen.org> | |||||||
|  	help |  	help | ||||||
| --- a/net/rfkill/Makefile
 | --- a/net/rfkill/Makefile
 | ||||||
| +++ b/net/rfkill/Makefile
 | +++ b/net/rfkill/Makefile
 | ||||||
| @@ -4,5 +4,5 @@
 | @@ -5,5 +5,5 @@
 | ||||||
|   |   | ||||||
|  rfkill-y			+= core.o |  rfkill-y			+= core.o | ||||||
|  rfkill-$(CONFIG_RFKILL_INPUT)	+= input.o |  rfkill-$(CONFIG_RFKILL_INPUT)	+= input.o | ||||||
|  | |||||||
| @ -14,7 +14,8 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/nvmem/Kconfig
 | --- a/drivers/nvmem/Kconfig
 | ||||||
| +++ b/drivers/nvmem/Kconfig
 | +++ b/drivers/nvmem/Kconfig
 | ||||||
| @@ -1,5 +1,5 @@
 | @@ -1,6 +1,6 @@
 | ||||||
|  |  # SPDX-License-Identifier: GPL-2.0-only | ||||||
|  menuconfig NVMEM |  menuconfig NVMEM | ||||||
| -	bool "NVMEM Support"
 | -	bool "NVMEM Support"
 | ||||||
| +	tristate "NVMEM Support"
 | +	tristate "NVMEM Support"
 | ||||||
| @ -23,7 +24,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> | |||||||
|   |   | ||||||
| --- a/drivers/of/Kconfig
 | --- a/drivers/of/Kconfig
 | ||||||
| +++ b/drivers/of/Kconfig
 | +++ b/drivers/of/Kconfig
 | ||||||
| @@ -71,6 +71,7 @@ config OF_IRQ
 | @@ -72,6 +72,7 @@ config OF_IRQ
 | ||||||
|   |   | ||||||
|  config OF_NET |  config OF_NET | ||||||
|  	depends on NETDEVICES |  	depends on NETDEVICES | ||||||
|  | |||||||
| @ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| ---
 | ---
 | ||||||
| --- a/arch/mips/include/asm/r4kcache.h
 | --- a/arch/mips/include/asm/r4kcache.h
 | ||||||
| +++ b/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 end)	\ | ||||||
|  {									\ |  {									\ | ||||||
|  	unsigned long lsize = cpu_##desc##_line_size();			\ |  	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);		\
 | +	unsigned long aend = (end + lsize - 1) & ~(lsize - 1);		\
 | ||||||
| +	int lines = (aend - addr) / lsize;				\
 | +	int lines = (aend - addr) / lsize;				\
 | ||||||
|  									\ |  									\ | ||||||
|  	__##pfx##flush_prologue						\ |  | ||||||
|  									\ |  | ||||||
| -	while (1) {							\
 | -	while (1) {							\
 | ||||||
| +	while (lines >= 8) {						\
 | +	while (lines >= 8) {						\
 | ||||||
| +		prot##cache_op(hitop, addr);				\
 | +		prot##cache_op(hitop, addr);				\
 | ||||||
| @ -62,5 +60,5 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| -			break;						\
 | -			break;						\
 | ||||||
| -		addr += lsize;						\
 | -		addr += lsize;						\
 | ||||||
|  	}								\ |  	}								\ | ||||||
|  									\ |  } | ||||||
|  	__##pfx##flush_epilogue						\ |   | ||||||
|  | |||||||
| @ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org> | |||||||
| 
 | 
 | ||||||
| --- a/arch/mips/Kconfig
 | --- a/arch/mips/Kconfig
 | ||||||
| +++ b/arch/mips/Kconfig
 | +++ b/arch/mips/Kconfig
 | ||||||
| @@ -1144,6 +1144,10 @@ config SYNC_R4K
 | @@ -1156,6 +1156,10 @@ config SYNC_R4K
 | ||||||
|  config MIPS_MACHINE |  config MIPS_MACHINE | ||||||
|  	def_bool n |  	def_bool n | ||||||
|   |   | ||||||
| @ -25,7 +25,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org> | |||||||
| +++ b/arch/mips/kernel/head.S
 | +++ b/arch/mips/kernel/head.S
 | ||||||
| @@ -79,6 +79,12 @@ FEXPORT(__kernel_entry)
 | @@ -79,6 +79,12 @@ FEXPORT(__kernel_entry)
 | ||||||
|  	j	kernel_entry |  	j	kernel_entry | ||||||
|  #endif |  #endif /* CONFIG_BOOT_RAW */ | ||||||
|   |   | ||||||
| +#ifdef CONFIG_IMAGE_CMDLINE_HACK
 | +#ifdef CONFIG_IMAGE_CMDLINE_HACK
 | ||||||
| +	.ascii	"CMDLINE:"
 | +	.ascii	"CMDLINE:"
 | ||||||
|  | |||||||
| @ -16,7 +16,7 @@ Signed-off-by: Alexandros C. Couloumbis <alex@ozo.com> | |||||||
| 
 | 
 | ||||||
| --- a/arch/powerpc/Makefile
 | --- a/arch/powerpc/Makefile
 | ||||||
| +++ b/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 |  machine-$(CONFIG_CPU_LITTLE_ENDIAN) += le | ||||||
|  UTS_MACHINE := $(subst $(space),,$(machine-y)) |  UTS_MACHINE := $(subst $(space),,$(machine-y)) | ||||||
|   |   | ||||||
| @ -24,7 +24,7 @@ Signed-off-by: Alexandros C. Couloumbis <alex@ozo.com> | |||||||
| -ifdef CONFIG_PPC32
 | -ifdef CONFIG_PPC32
 | ||||||
| -KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o
 | -KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o
 | ||||||
| -else
 | -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)
 | -ifeq ($(call ld-ifversion, -ge, 225000000, y),y)
 | ||||||
| -# Have the linker provide sfpr if possible.
 | -# Have the linker provide sfpr if possible.
 | ||||||
| -# There is a corresponding test in arch/powerpc/lib/Makefile
 | -# There is a corresponding test in arch/powerpc/lib/Makefile
 | ||||||
|  | |||||||
| @ -18,7 +18,7 @@ Reviewed-by: Bart Van Assche <bvanassche@acm.org> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/block/loop.c
 | --- a/drivers/block/loop.c
 | ||||||
| +++ b/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) || |  	if (!cmd->use_aio || cmd->ret < 0 || cmd->ret == blk_rq_bytes(rq) || | ||||||
|  	    req_op(rq) != REQ_OP_READ) { |  	    req_op(rq) != REQ_OP_READ) { | ||||||
|  		if (cmd->ret < 0) |  		if (cmd->ret < 0) | ||||||
| @ -27,7 +27,7 @@ Reviewed-by: Bart Van Assche <bvanassche@acm.org> | |||||||
|  		goto end_io; |  		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: |   failed: | ||||||
|  	/* complete non-aio request */ |  	/* complete non-aio request */ | ||||||
|  	if (!cmd->use_aio || ret) { |  	if (!cmd->use_aio || ret) { | ||||||
|  | |||||||
| @ -28,7 +28,7 @@ Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/block/loop.c
 | --- a/drivers/block/loop.c
 | ||||||
| +++ b/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. |  	 * information. | ||||||
|  	 */ |  	 */ | ||||||
|  	struct file *file = lo->lo_backing_file; |  	struct file *file = lo->lo_backing_file; | ||||||
| @ -42,7 +42,7 @@ Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com> | |||||||
|  		ret = -EOPNOTSUPP; |  		ret = -EOPNOTSUPP; | ||||||
|  		goto out; |  		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 file *file = lo->lo_backing_file; | ||||||
|  	struct inode *inode = file->f_mapping->host; |  	struct inode *inode = file->f_mapping->host; | ||||||
|  	struct request_queue *q = lo->lo_queue; |  	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 |  	 * 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 |  	 * encryption is enabled, because it may give an attacker | ||||||
|  	 * useful information. |  	 * useful information. | ||||||
|  	 */ |  	 */ | ||||||
|  | |||||||
| @ -12,7 +12,7 @@ Signed-off-by: Etienne Champetier <champetier.etienne@gmail.com> | |||||||
| 
 | 
 | ||||||
| --- a/net/bridge/br_input.c
 | --- a/net/bridge/br_input.c
 | ||||||
| +++ b/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) && |  	if (IS_ENABLED(CONFIG_INET) && | ||||||
| --- a/net/bridge/br_private.h
 | --- a/net/bridge/br_private.h
 | ||||||
| +++ b/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; | ||||||
|  	u16				group_fwd_mask_required; |  	u16				group_fwd_mask_required; | ||||||
|   |   | ||||||
| @ -41,7 +41,7 @@ Signed-off-by: Etienne Champetier <champetier.etienne@gmail.com> | |||||||
|  	bridge_id			bridge_id; |  	bridge_id			bridge_id; | ||||||
| --- a/net/bridge/br_sysfs_br.c
 | --- a/net/bridge/br_sysfs_br.c
 | ||||||
| +++ b/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); |  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, |  static ssize_t priority_show(struct device *d, struct device_attribute *attr, | ||||||
|  			     char *buf) |  			     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_ageing_time.attr, | ||||||
|  	&dev_attr_stp_state.attr, |  	&dev_attr_stp_state.attr, | ||||||
|  	&dev_attr_group_fwd_mask.attr, |  	&dev_attr_group_fwd_mask.attr, | ||||||
|  | |||||||
| @ -109,7 +109,7 @@ Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> | |||||||
|  	__u8 invert; |  	__u8 invert; | ||||||
| --- a/net/netfilter/xt_connmark.c
 | --- a/net/netfilter/xt_connmark.c
 | ||||||
| +++ b/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"); |  MODULE_ALIAS("ip6t_connmark"); | ||||||
|   |   | ||||||
|  static unsigned int |  static unsigned int | ||||||
| @ -124,7 +124,7 @@ Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> | |||||||
|   |   | ||||||
|  	ct = nf_ct_get(skb, &ctinfo); |  	ct = nf_ct_get(skb, &ctinfo); | ||||||
|  	if (ct == NULL) |  	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) { |  	switch (info->mode) { | ||||||
|  	case XT_CONNMARK_SET: |  	case XT_CONNMARK_SET: | ||||||
| @ -154,7 +154,7 @@ Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> | |||||||
|  		if (ct->mark != newmark) { |  		if (ct->mark != newmark) { | ||||||
|  			ct->mark = newmark; |  			ct->mark = newmark; | ||||||
|  			nf_conntrack_event_cache(IPCT_MARK, ct); |  			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) |  connmark_tg(struct sk_buff *skb, const struct xt_action_param *par) | ||||||
|  { |  { | ||||||
|  	const struct xt_connmark_tginfo1 *info = par->targinfo; |  	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); |  	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), |  		.targetsize     = sizeof(struct xt_connmark_tginfo2), | ||||||
|  		.destroy        = connmark_tg_destroy, |  		.destroy        = connmark_tg_destroy, | ||||||
|  		.me             = THIS_MODULE, |  		.me             = THIS_MODULE, | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| --- a/include/net/netfilter/nf_flow_table.h
 | --- a/include/net/netfilter/nf_flow_table.h
 | ||||||
| +++ b/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); |  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); |  void nf_flow_table_hw_unregister(const struct nf_flow_table_hw *offload); | ||||||
|   |   | ||||||
| @ -11,15 +11,15 @@ | |||||||
|  #define MODULE_ALIAS_NF_FLOWTABLE(family)	\ |  #define MODULE_ALIAS_NF_FLOWTABLE(family)	\ | ||||||
| --- a/net/netfilter/nf_flow_table_core.c
 | --- a/net/netfilter/nf_flow_table_core.c
 | ||||||
| +++ b/net/netfilter/nf_flow_table_core.c
 | +++ b/net/netfilter/nf_flow_table_core.c
 | ||||||
| @@ -11,6 +11,7 @@
 | @@ -13,6 +13,7 @@
 | ||||||
|  #include <net/netfilter/nf_conntrack.h> |  | ||||||
|  #include <net/netfilter/nf_conntrack_core.h> |  #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_tuple.h> | ||||||
| +#include <net/netfilter/nf_conntrack_acct.h>
 | +#include <net/netfilter/nf_conntrack_acct.h>
 | ||||||
|   |   | ||||||
|  struct flow_offload_entry { |  struct flow_offload_entry { | ||||||
|  	struct flow_offload	flow; |  	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); |  EXPORT_SYMBOL_GPL(flow_offload_free); | ||||||
|   |   | ||||||
| @ -44,7 +44,7 @@ | |||||||
|  	const struct flow_offload_tuple *tuple = data; |  	const struct flow_offload_tuple *tuple = data; | ||||||
| --- a/net/netfilter/nf_flow_table_ip.c
 | --- a/net/netfilter/nf_flow_table_ip.c
 | ||||||
| +++ b/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/ip6_route.h> | ||||||
|  #include <net/neighbour.h> |  #include <net/neighbour.h> | ||||||
|  #include <net/netfilter/nf_flow_table.h> |  #include <net/netfilter/nf_flow_table.h> | ||||||
| @ -52,7 +52,7 @@ | |||||||
|  /* For layer 4 checksum field offset. */ |  /* For layer 4 checksum field offset. */ | ||||||
|  #include <linux/tcp.h> |  #include <linux/tcp.h> | ||||||
|  #include <linux/udp.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; |  	skb->dev = outdev; | ||||||
|  	nexthop = rt_nexthop(rt, flow->tuplehash[!dir].tuple.src_v4.s_addr); |  	nexthop = rt_nexthop(rt, flow->tuplehash[!dir].tuple.src_v4.s_addr); | ||||||
|  	skb_dst_set_noref(skb, &rt->dst); |  	skb_dst_set_noref(skb, &rt->dst); | ||||||
| @ -60,7 +60,7 @@ | |||||||
|  	neigh_xmit(NEIGH_ARP_TABLE, outdev, &nexthop, skb); |  	neigh_xmit(NEIGH_ARP_TABLE, outdev, &nexthop, skb); | ||||||
|   |   | ||||||
|  	return NF_STOLEN; |  	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; |  	skb->dev = outdev; | ||||||
|  	nexthop = rt6_nexthop(rt, &flow->tuplehash[!dir].tuple.src_v6); |  	nexthop = rt6_nexthop(rt, &flow->tuplehash[!dir].tuple.src_v6); | ||||||
|  	skb_dst_set_noref(skb, &rt->dst); |  	skb_dst_set_noref(skb, &rt->dst); | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| 
 | 
 | ||||||
| --- a/net/ipv4/netfilter/Kconfig
 | --- a/net/ipv4/netfilter/Kconfig
 | ||||||
| +++ b/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 |  	help | ||||||
|  	  This option enables the ARP support for nf_tables. |  	  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 |  config NF_FLOW_TABLE_IPV4 | ||||||
|  	tristate "Netfilter flow table IPv4 module" |  	tristate "Netfilter flow table IPv4 module" | ||||||
|  	depends on NF_FLOW_TABLE |  	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. |  	  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 |  	depends on !NF_CONNTRACK || NF_CONNTRACK | ||||||
| --- a/net/ipv6/netfilter/Kconfig
 | --- a/net/ipv6/netfilter/Kconfig
 | ||||||
| +++ b/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. |  	  multicast or blackhole. | ||||||
|   |   | ||||||
|  endif # NF_TABLES_IPV6 |  endif # NF_TABLES_IPV6 | ||||||
| @ -36,7 +36,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|   |   | ||||||
|  config NF_FLOW_TABLE_IPV6 |  config NF_FLOW_TABLE_IPV6 | ||||||
|  	tristate "Netfilter flow table IPv6 module" |  	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. |  	  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 |  	depends on !NF_CONNTRACK || NF_CONNTRACK | ||||||
| --- a/net/netfilter/Kconfig
 | --- a/net/netfilter/Kconfig
 | ||||||
| +++ b/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 |  endif # NF_TABLES_NETDEV | ||||||
|   |   | ||||||
| @ -56,7 +56,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  config NF_FLOW_TABLE_INET |  config NF_FLOW_TABLE_INET | ||||||
|  	tristate "Netfilter flow table mixed IPv4/IPv6 module" |  	tristate "Netfilter flow table mixed IPv4/IPv6 module" | ||||||
|  	depends on NF_FLOW_TABLE |  	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. |  	  To compile it as a module, choose M here. | ||||||
|   |   | ||||||
| @ -70,7 +70,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  	help |  	help | ||||||
|  	  This option adds the flow table core infrastructure. |  	  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 |  	depends on NETFILTER_ADVANCED | ||||||
|  	select NETFILTER_XT_TARGET_CT |  	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 |  obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o | ||||||
| --- /dev/null
 | --- /dev/null
 | ||||||
| +++ b/net/netfilter/xt_FLOWOFFLOAD.c
 | +++ b/net/netfilter/xt_FLOWOFFLOAD.c
 | ||||||
| @@ -0,0 +1,422 @@
 | @@ -0,0 +1,427 @@
 | ||||||
| +/*
 | +/*
 | ||||||
| + * Copyright (C) 2018 Felix Fietkau <nbd@nbd.name>
 | + * Copyright (C) 2018 Felix Fietkau <nbd@nbd.name>
 | ||||||
| + *
 | + *
 | ||||||
| @ -143,6 +143,10 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| +	return NF_ACCEPT;
 | +	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
 | +static int
 | ||||||
| +xt_flowoffload_create_hook(struct net_device *dev)
 | +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 flow_offload_tuple *tuple = &flow->tuplehash[0].tuple;
 | ||||||
| +	struct xt_flowoffload_hook *hook;
 | +	struct xt_flowoffload_hook *hook;
 | ||||||
| +	bool *found = data;
 | +	bool *found = data;
 | ||||||
|  | +	struct rtable *rt = (struct rtable *)tuple->dst_cache;
 | ||||||
| +
 | +
 | ||||||
| +	spin_lock_bh(&hooks_lock);
 | +	spin_lock_bh(&hooks_lock);
 | ||||||
| +	hlist_for_each_entry(hook, &hooks, list) {
 | +	hlist_for_each_entry(hook, &hooks, list) {
 | ||||||
| +		if (hook->ops.dev->ifindex != tuple->iifidx &&
 | +		if (hook->ops.dev->ifindex != tuple->iifidx &&
 | ||||||
| +		    hook->ops.dev->ifindex != tuple->oifidx)
 | +		    hook->ops.dev->ifindex != rt->dst.dev->ifindex)
 | ||||||
| +			continue;
 | +			continue;
 | ||||||
| +
 | +
 | ||||||
| +		hook->used = true;
 | +		hook->used = true;
 | ||||||
| @ -483,7 +488,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| +		kfree(hook);
 | +		kfree(hook);
 | ||||||
| +	}
 | +	}
 | ||||||
| +
 | +
 | ||||||
| +	nf_flow_table_cleanup(dev_net(dev), dev);
 | +	nf_flow_table_cleanup(dev);
 | ||||||
| +
 | +
 | ||||||
| +	return NOTIFY_DONE;
 | +	return NOTIFY_DONE;
 | ||||||
| +}
 | +}
 | ||||||
| @ -523,7 +528,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| +module_exit(xt_flowoffload_tg_exit);
 | +module_exit(xt_flowoffload_tg_exit);
 | ||||||
| --- a/net/netfilter/nf_flow_table_core.c
 | --- a/net/netfilter/nf_flow_table_core.c
 | ||||||
| +++ b/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 <linux/netdevice.h> | ||||||
|  #include <net/ip.h> |  #include <net/ip.h> | ||||||
|  #include <net/ip6_route.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_flow_table.h> | ||||||
|  #include <net/netfilter/nf_conntrack.h> |  #include <net/netfilter/nf_conntrack.h> | ||||||
|  #include <net/netfilter/nf_conntrack_core.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
 | --- /dev/null
 | ||||||
| +++ b/include/uapi/linux/netfilter/xt_FLOWOFFLOAD.h
 | +++ b/include/uapi/linux/netfilter/xt_FLOWOFFLOAD.h
 | ||||||
| @@ -0,0 +1,17 @@
 | @@ -0,0 +1,17 @@
 | ||||||
| @ -551,3 +574,16 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| +};
 | +};
 | ||||||
| +
 | +
 | ||||||
| +#endif /* _XT_FLOWOFFLOAD_H */
 | +#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); | ||||||
|  | |||||||
| @ -11,7 +11,7 @@ Signed-off-by: Imre Kaloz <kaloz@openwrt.org> | |||||||
| 
 | 
 | ||||||
| --- a/include/linux/netdevice.h
 | --- a/include/linux/netdevice.h
 | ||||||
| +++ b/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) |  #if defined(CONFIG_HYPERV_NET) | ||||||
|  # define LL_MAX_HEADER 128 |  # define LL_MAX_HEADER 128 | ||||||
|  | |||||||
| @ -13,7 +13,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| 
 | 
 | ||||||
| --- a/net/sched/sch_fq_codel.c
 | --- a/net/sched/sch_fq_codel.c
 | ||||||
| +++ b/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; |  	sch->limit = 10*1024; | ||||||
|  	q->flows_cnt = 1024; |  	q->flows_cnt = 1024; | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| 
 | 
 | ||||||
| --- a/include/net/sch_generic.h
 | --- a/include/net/sch_generic.h
 | ||||||
| +++ b/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 pfifo_fast_ops; | ||||||
|  extern struct Qdisc_ops mq_qdisc_ops; |  extern struct Qdisc_ops mq_qdisc_ops; | ||||||
|  extern struct Qdisc_ops noqueue_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 { |  struct Qdisc_class_common { | ||||||
| --- a/net/sched/Kconfig
 | --- a/net/sched/Kconfig
 | ||||||
| +++ b/net/sched/Kconfig
 | +++ b/net/sched/Kconfig
 | ||||||
| @@ -3,8 +3,9 @@
 | @@ -4,8 +4,9 @@
 | ||||||
|  # |  # | ||||||
|   |   | ||||||
|  menuconfig NET_SCHED |  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 |  	  device, it has to decide which ones to send first, which ones to | ||||||
| --- a/net/sched/sch_api.c
 | --- a/net/sched/sch_api.c
 | ||||||
| +++ b/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; |  		return err; | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
| @ -55,7 +55,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  	register_qdisc(&pfifo_head_drop_qdisc_ops); |  	register_qdisc(&pfifo_head_drop_qdisc_ops); | ||||||
| --- a/net/sched/sch_fq_codel.c
 | --- a/net/sched/sch_fq_codel.c
 | ||||||
| +++ b/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, |  	.walk		=	fq_codel_walk, | ||||||
|  }; |  }; | ||||||
|   |   | ||||||
| @ -64,7 +64,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  	.cl_ops		=	&fq_codel_class_ops, |  	.cl_ops		=	&fq_codel_class_ops, | ||||||
|  	.id		=	"fq_codel", |  	.id		=	"fq_codel", | ||||||
|  	.priv_size	=	sizeof(struct fq_codel_sched_data), |  	.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, |  	.dump_stats =	fq_codel_dump_stats, | ||||||
|  	.owner		=	THIS_MODULE, |  	.owner		=	THIS_MODULE, | ||||||
|  }; |  }; | ||||||
| @ -74,7 +74,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  { |  { | ||||||
| --- a/net/sched/sch_generic.c
 | --- a/net/sched/sch_generic.c
 | ||||||
| +++ b/net/sched/sch_generic.c
 | +++ b/net/sched/sch_generic.c
 | ||||||
| @@ -35,7 +35,7 @@
 | @@ -32,7 +32,7 @@
 | ||||||
|  #include <net/xfrm.h> |  #include <net/xfrm.h> | ||||||
|   |   | ||||||
|  /* Qdisc to use by default */ |  /* Qdisc to use by default */ | ||||||
| @ -83,7 +83,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  EXPORT_SYMBOL(default_qdisc_ops); |  EXPORT_SYMBOL(default_qdisc_ops); | ||||||
|   |   | ||||||
|  /* Main transmission queue. */ |  /* 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) |  				     void *_unused) | ||||||
|  { |  { | ||||||
|  	struct Qdisc *qdisc; |  	struct Qdisc *qdisc; | ||||||
| @ -92,3 +92,9 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|   |   | ||||||
|  	if (dev->priv_flags & IFF_NO_QUEUE) |  	if (dev->priv_flags & IFF_NO_QUEUE) | ||||||
|  		ops = &noqueue_qdisc_ops; |  		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) { | ||||||
|  | |||||||
| @ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| 
 | 
 | ||||||
| --- a/net/sched/sch_generic.c
 | --- a/net/sched/sch_generic.c
 | ||||||
| +++ b/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, |  	.owner		=	THIS_MODULE, | ||||||
|  }; |  }; | ||||||
|   |   | ||||||
| @ -49,14 +49,14 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| -
 | -
 | ||||||
| -	err = skb_array_produce(q, skb);
 | -	err = skb_array_produce(q, skb);
 | ||||||
| -
 | -
 | ||||||
| -	if (unlikely(err))
 | -	if (unlikely(err)) {
 | ||||||
|  | -		if (qdisc_is_percpu_stats(qdisc))
 | ||||||
| -			return qdisc_drop_cpu(skb, qdisc, to_free);
 | -			return qdisc_drop_cpu(skb, qdisc, to_free);
 | ||||||
|  | -		else
 | ||||||
|  | -			return qdisc_drop(skb, qdisc, to_free);
 | ||||||
|  | -	}
 | ||||||
| -
 | -
 | ||||||
| -	qdisc_qstats_atomic_qlen_inc(qdisc);
 | -	qdisc_update_stats_at_enqueue(qdisc, pkt_len);
 | ||||||
| -	/* 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);
 |  | ||||||
| -	return NET_XMIT_SUCCESS;
 | -	return NET_XMIT_SUCCESS;
 | ||||||
| -}
 | -}
 | ||||||
| -
 | -
 | ||||||
| @ -75,9 +75,9 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| -		skb = __skb_array_consume(q);
 | -		skb = __skb_array_consume(q);
 | ||||||
| -	}
 | -	}
 | ||||||
| -	if (likely(skb)) {
 | -	if (likely(skb)) {
 | ||||||
| -		qdisc_qstats_cpu_backlog_dec(qdisc, skb);
 | -		qdisc_update_stats_at_dequeue(qdisc, skb);
 | ||||||
| -		qdisc_bstats_cpu_update(qdisc, skb);
 | -	} else {
 | ||||||
| -		qdisc_qstats_atomic_qlen_dec(qdisc);
 | -		WRITE_ONCE(qdisc->empty, true);
 | ||||||
| -	}
 | -	}
 | ||||||
| -
 | -
 | ||||||
| -	return skb;
 | -	return skb;
 | ||||||
| @ -117,10 +117,14 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| -			kfree_skb(skb);
 | -			kfree_skb(skb);
 | ||||||
| -	}
 | -	}
 | ||||||
| -
 | -
 | ||||||
|  | -	if (qdisc_is_percpu_stats(qdisc)) {
 | ||||||
| -		for_each_possible_cpu(i) {
 | -		for_each_possible_cpu(i) {
 | ||||||
| -		struct gnet_stats_queue *q = per_cpu_ptr(qdisc->cpu_qstats, i);
 | -			struct gnet_stats_queue *q;
 | ||||||
| -
 | -
 | ||||||
|  | -			q = per_cpu_ptr(qdisc->cpu_qstats, i);
 | ||||||
| -			q->backlog = 0;
 | -			q->backlog = 0;
 | ||||||
|  | -			q->qlen = 0;
 | ||||||
|  | -		}
 | ||||||
| -	}
 | -	}
 | ||||||
| -}
 | -}
 | ||||||
| -
 | -
 | ||||||
| @ -215,6 +219,6 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| -};
 | -};
 | ||||||
| -EXPORT_SYMBOL(pfifo_fast_ops);
 | -EXPORT_SYMBOL(pfifo_fast_ops);
 | ||||||
| -
 | -
 | ||||||
|  static struct lock_class_key qdisc_tx_busylock; |  struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue, | ||||||
|  static struct lock_class_key qdisc_running_key; |  			  const struct Qdisc_ops *ops, | ||||||
|   |  			  struct netlink_ext_ack *extack) | ||||||
|  | |||||||
| @ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| 
 | 
 | ||||||
| --- a/drivers/net/phy/Kconfig
 | --- a/drivers/net/phy/Kconfig
 | ||||||
| +++ b/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. |  		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_RTL8367_PHY)	+= rtl8367.o
 | ||||||
| +obj-$(CONFIG_RTL8367B_PHY)	+= rtl8367b.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_IPROC)	+= mdio-bcm-iproc.o | ||||||
|  obj-$(CONFIG_MDIO_BCM_UNIMAC)	+= mdio-bcm-unimac.o |  obj-$(CONFIG_MDIO_BCM_UNIMAC)	+= mdio-bcm-unimac.o | ||||||
|  obj-$(CONFIG_MDIO_BITBANG)	+= mdio-bitbang.o |  | ||||||
| --- a/include/linux/platform_data/b53.h
 | --- a/include/linux/platform_data/b53.h
 | ||||||
| +++ b/include/linux/platform_data/b53.h
 | +++ b/include/linux/platform_data/b53.h
 | ||||||
| @@ -29,6 +29,9 @@ struct b53_platform_data {
 | @@ -29,6 +29,9 @@ struct b53_platform_data {
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| --- a/include/linux/phy.h
 | --- a/include/linux/phy.h
 | ||||||
| +++ b/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 */ |  	/* Determines the negotiated speed and duplex */ | ||||||
|  	int (*read_status)(struct phy_device *phydev); |  	int (*read_status)(struct phy_device *phydev); | ||||||
|   |   | ||||||
| @ -15,9 +15,9 @@ | |||||||
|   |   | ||||||
| --- a/drivers/net/phy/phy_device.c
 | --- a/drivers/net/phy/phy_device.c
 | ||||||
| +++ b/drivers/net/phy/phy_device.c
 | +++ b/drivers/net/phy/phy_device.c
 | ||||||
| @@ -1577,6 +1577,9 @@ int genphy_update_link(struct phy_device
 | @@ -1822,6 +1822,9 @@ int genphy_update_link(struct phy_device
 | ||||||
|  { |  	if (bmcr & BMCR_ANRESTART) | ||||||
|  	int status; |  		goto done; | ||||||
|   |   | ||||||
| +	if (phydev->drv && phydev->drv->update_link)
 | +	if (phydev->drv && phydev->drv->update_link)
 | ||||||
| +		return phydev->drv->update_link(phydev);
 | +		return phydev->drv->update_link(phydev);
 | ||||||
|  | |||||||
| @ -15,7 +15,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
| 
 | 
 | ||||||
| --- a/include/linux/netdevice.h
 | --- a/include/linux/netdevice.h
 | ||||||
| +++ b/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_FAILOVER_SLAVE		= 1<<28, | ||||||
|  	IFF_L3MDEV_RX_HANDLER		= 1<<29, |  	IFF_L3MDEV_RX_HANDLER		= 1<<29, | ||||||
|  	IFF_LIVE_RENAME_OK		= 1<<30, |  	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 |  #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_FAILOVER_SLAVE		IFF_FAILOVER_SLAVE | ||||||
|  #define IFF_L3MDEV_RX_HANDLER		IFF_L3MDEV_RX_HANDLER |  #define IFF_L3MDEV_RX_HANDLER		IFF_L3MDEV_RX_HANDLER | ||||||
|  #define IFF_LIVE_RENAME_OK		IFF_LIVE_RENAME_OK |  #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. |   *	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; |  	const struct tlsdev_ops *tlsdev_ops; | ||||||
|  #endif |  #endif | ||||||
|   |   | ||||||
| @ -43,7 +43,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  	const struct header_ops *header_ops; |  	const struct header_ops *header_ops; | ||||||
|   |   | ||||||
|  	unsigned int		flags; |  	unsigned int		flags; | ||||||
| @@ -1928,6 +1935,10 @@ struct net_device {
 | @@ -1959,6 +1966,10 @@ struct net_device {
 | ||||||
|  	struct mpls_dev __rcu	*mpls_ptr; |  	struct mpls_dev __rcu	*mpls_ptr; | ||||||
|  #endif |  #endif | ||||||
|   |   | ||||||
| @ -56,7 +56,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|   */ |   */ | ||||||
| --- a/include/linux/skbuff.h
 | --- a/include/linux/skbuff.h
 | ||||||
| +++ b/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; |  	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 |   *	pskb_trim_unique - remove end from a paged unique (not cloned) buffer | ||||||
|   *	@skb: buffer to alter |   *	@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
 | --- a/net/Kconfig
 | ||||||
| +++ b/net/Kconfig
 | +++ b/net/Kconfig
 | ||||||
| @@ -25,6 +25,12 @@ menuconfig NET
 | @@ -26,6 +26,12 @@ menuconfig NET
 | ||||||
|   |   | ||||||
|  if NET |  if NET | ||||||
|   |   | ||||||
| @ -101,8 +101,8 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  	help |  	help | ||||||
| --- a/net/core/dev.c
 | --- a/net/core/dev.c
 | ||||||
| +++ b/net/core/dev.c
 | +++ b/net/core/dev.c
 | ||||||
| @@ -3253,10 +3253,20 @@ static int xmit_one(struct sk_buff *skb,
 | @@ -3194,10 +3194,20 @@ static int xmit_one(struct sk_buff *skb,
 | ||||||
|  	if (!list_empty(&ptype_all) || !list_empty(&dev->ptype_all)) |  	if (dev_nit_active(dev)) | ||||||
|  		dev_queue_xmit_nit(skb, dev); |  		dev_queue_xmit_nit(skb, dev); | ||||||
|   |   | ||||||
| -	len = skb->len;
 | -	len = skb->len;
 | ||||||
| @ -128,15 +128,15 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  } |  } | ||||||
| --- a/net/core/skbuff.c
 | --- a/net/core/skbuff.c
 | ||||||
| +++ b/net/core/skbuff.c
 | +++ b/net/core/skbuff.c
 | ||||||
| @@ -63,6 +63,7 @@
 | @@ -60,6 +60,7 @@
 | ||||||
|  #include <linux/errqueue.h> |  | ||||||
|  #include <linux/prefetch.h> |  #include <linux/prefetch.h> | ||||||
|  #include <linux/if_vlan.h> |  #include <linux/if_vlan.h> | ||||||
|  |  #include <linux/mpls.h> | ||||||
| +#include <linux/if.h>
 | +#include <linux/if.h>
 | ||||||
|   |   | ||||||
|  #include <net/protocol.h> |  #include <net/protocol.h> | ||||||
|  #include <net/dst.h> |  #include <net/dst.h> | ||||||
| @@ -503,6 +504,22 @@ skb_fail:
 | @@ -540,6 +541,22 @@ skb_fail:
 | ||||||
|  } |  } | ||||||
|  EXPORT_SYMBOL(__napi_alloc_skb); |  EXPORT_SYMBOL(__napi_alloc_skb); | ||||||
|   |   | ||||||
| @ -161,7 +161,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  { |  { | ||||||
| --- a/net/ethernet/eth.c
 | --- a/net/ethernet/eth.c
 | ||||||
| +++ b/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; |  	const struct ethhdr *eth; | ||||||
|   |   | ||||||
|  	skb->dev = dev; |  	skb->dev = dev; | ||||||
|  | |||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue
	
	Block a user