diff options
Diffstat (limited to 'target/linux/generic/backport-4.19')
88 files changed, 0 insertions, 10231 deletions
diff --git a/target/linux/generic/backport-4.19/010-Kbuild-don-t-hardcode-path-to-awk-in-scripts-ld-vers.patch b/target/linux/generic/backport-4.19/010-Kbuild-don-t-hardcode-path-to-awk-in-scripts-ld-vers.patch deleted file mode 100644 index 7ac4f9d240..0000000000 --- a/target/linux/generic/backport-4.19/010-Kbuild-don-t-hardcode-path-to-awk-in-scripts-ld-vers.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 13b1ecc3401653a355798eb1dee10cc1608202f4 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau <nbd@nbd.name> -Date: Mon, 18 Jan 2016 12:27:49 +0100 -Subject: [PATCH 33/34] Kbuild: don't hardcode path to awk in - scripts/ld-version.sh - -On some systems /usr/bin/awk does not exist, or is broken. Find it via -$PATH instead. - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - scripts/ld-version.sh | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/scripts/ld-version.sh -+++ b/scripts/ld-version.sh -@@ -1,6 +1,7 @@ --#!/usr/bin/awk -f -+#!/bin/sh - # SPDX-License-Identifier: GPL-2.0 - # extract linker version number from stdin and turn into single number -+exec awk ' - { - gsub(".*\\)", ""); - gsub(".*version ", ""); -@@ -9,3 +10,4 @@ - print a[1]*100000000 + a[2]*1000000 + a[3]*10000; - exit - } -+' diff --git a/target/linux/generic/backport-4.19/011-kbuild-export-SUBARCH.patch b/target/linux/generic/backport-4.19/011-kbuild-export-SUBARCH.patch deleted file mode 100644 index a42c720446..0000000000 --- a/target/linux/generic/backport-4.19/011-kbuild-export-SUBARCH.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 173019b66dcc9d68ad9333aa744dad1e369b5aa8 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau <nbd@nbd.name> -Date: Sun, 9 Jul 2017 00:26:53 +0200 -Subject: [PATCH 34/34] kernel: add compile fix for linux 4.9 on x86 - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - Makefile | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/Makefile -+++ b/Makefile -@@ -432,8 +432,8 @@ KBUILD_LDFLAGS := - GCC_PLUGINS_CFLAGS := - CLANG_FLAGS := - --export ARCH SRCARCH CONFIG_SHELL HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE AS LD CC --export CPP AR NM STRIP OBJCOPY OBJDUMP KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS -+export ARCH SRCARCH SUBARCH CONFIG_SHELL HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE AS LD -+export CC CPP AR NM STRIP OBJCOPY OBJDUMP KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS - export MAKE LEX YACC AWK GENKSYMS INSTALLKERNEL PERL PYTHON PYTHON2 PYTHON3 UTS_MACHINE - export HOSTCXX KBUILD_HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS - diff --git a/target/linux/generic/backport-4.19/020-backport_netfilter_rtcache.patch b/target/linux/generic/backport-4.19/020-backport_netfilter_rtcache.patch deleted file mode 100644 index c02b8f39e0..0000000000 --- a/target/linux/generic/backport-4.19/020-backport_netfilter_rtcache.patch +++ /dev/null @@ -1,558 +0,0 @@ -From 1bb0c3ec899827cfa4668bb63a08713a40744d21 Mon Sep 17 00:00:00 2001 -From: Florian Westphal <fw@strlen.de> -Date: Sun, 9 Jul 2017 08:58:30 +0200 -Subject: [PATCH] netfilter: conntrack: cache route for forwarded connections - -... to avoid per-packet FIB lookup if possible. - -The cached dst is re-used provided the input interface -is the same as that of the previous packet in the same direction. - -If not, the cached dst is invalidated. - -For ipv6 we also need to store sernum, else dst_check doesn't work, -pointed out by Eric Dumazet. - -This should speed up forwarding when conntrack is already in use -anyway, especially when using reverse path filtering -- active RPF -enforces two FIB lookups for each packet. - -Before the routing cache removal this didn't matter since RPF was performed -only when route cache didn't yield a result; but without route cache it -comes at higher price. - -Julian Anastasov suggested to add NETDEV_UNREGISTER handler to -avoid holding on to dsts of 'frozen' conntracks. - -Signed-off-by: Florian Westphal <fw@strlen.de> ---- - include/net/netfilter/nf_conntrack_extend.h | 4 + - include/net/netfilter/nf_conntrack_rtcache.h | 34 +++ - net/netfilter/Kconfig | 12 + - net/netfilter/Makefile | 3 + - net/netfilter/nf_conntrack_rtcache.c | 428 +++++++++++++++++++++++++++ - 5 files changed, 481 insertions(+) - create mode 100644 include/net/netfilter/nf_conntrack_rtcache.h - create mode 100644 net/netfilter/nf_conntrack_rtcache.c - ---- a/include/net/netfilter/nf_conntrack_extend.h -+++ b/include/net/netfilter/nf_conntrack_extend.h -@@ -28,6 +28,9 @@ enum nf_ct_ext_id { - #if IS_ENABLED(CONFIG_NETFILTER_SYNPROXY) - NF_CT_EXT_SYNPROXY, - #endif -+#if IS_ENABLED(CONFIG_NF_CONNTRACK_RTCACHE) -+ NF_CT_EXT_RTCACHE, -+#endif - NF_CT_EXT_NUM, - }; - -@@ -40,6 +43,7 @@ enum nf_ct_ext_id { - #define NF_CT_EXT_TIMEOUT_TYPE struct nf_conn_timeout - #define NF_CT_EXT_LABELS_TYPE struct nf_conn_labels - #define NF_CT_EXT_SYNPROXY_TYPE struct nf_conn_synproxy -+#define NF_CT_EXT_RTCACHE_TYPE struct nf_conn_rtcache - - /* Extensions: optional stuff which isn't permanently in struct. */ - struct nf_ct_ext { ---- /dev/null -+++ b/include/net/netfilter/nf_conntrack_rtcache.h -@@ -0,0 +1,34 @@ -+#include <linux/gfp.h> -+#include <net/netfilter/nf_conntrack.h> -+#include <net/netfilter/nf_conntrack_extend.h> -+ -+struct dst_entry; -+ -+struct nf_conn_dst_cache { -+ struct dst_entry *dst; -+ int iif; -+#if IS_ENABLED(CONFIG_NF_CONNTRACK_IPV6) -+ u32 cookie; -+#endif -+ -+}; -+ -+struct nf_conn_rtcache { -+ struct nf_conn_dst_cache cached_dst[IP_CT_DIR_MAX]; -+}; -+ -+static inline -+struct nf_conn_rtcache *nf_ct_rtcache_find(const struct nf_conn *ct) -+{ -+#if IS_ENABLED(CONFIG_NF_CONNTRACK_RTCACHE) -+ return nf_ct_ext_find(ct, NF_CT_EXT_RTCACHE); -+#else -+ return NULL; -+#endif -+} -+ -+static inline int nf_conn_rtcache_iif_get(const struct nf_conn_rtcache *rtc, -+ enum ip_conntrack_dir dir) -+{ -+ return rtc->cached_dst[dir].iif; -+} ---- a/net/netfilter/Kconfig -+++ b/net/netfilter/Kconfig -@@ -135,6 +135,18 @@ config NF_CONNTRACK_EVENTS - - If unsure, say `N'. - -+config NF_CONNTRACK_RTCACHE -+ tristate "Cache route entries in conntrack objects" -+ depends on NETFILTER_ADVANCED -+ depends on NF_CONNTRACK -+ help -+ If this option is enabled, the connection tracking code will -+ cache routing information for each connection that is being -+ forwarded, at a cost of 32 bytes per conntrack object. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ The module will be called nf_conntrack_rtcache. -+ - config NF_CONNTRACK_TIMEOUT - bool 'Connection tracking timeout' - depends on NETFILTER_ADVANCED ---- a/net/netfilter/Makefile -+++ b/net/netfilter/Makefile -@@ -25,6 +25,9 @@ obj-$(CONFIG_NETFILTER_NETLINK_OSF) += n - # connection tracking - obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o - -+# optional conntrack route cache extension -+obj-$(CONFIG_NF_CONNTRACK_RTCACHE) += nf_conntrack_rtcache.o -+ - obj-$(CONFIG_NF_CT_PROTO_GRE) += nf_conntrack_proto_gre.o - - # netlink interface for nf_conntrack ---- /dev/null -+++ b/net/netfilter/nf_conntrack_rtcache.c -@@ -0,0 +1,428 @@ -+/* route cache for netfilter. -+ * -+ * (C) 2014 Red Hat GmbH -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -+ -+#include <linux/types.h> -+#include <linux/netfilter.h> -+#include <linux/skbuff.h> -+#include <linux/stddef.h> -+#include <linux/kernel.h> -+#include <linux/netdevice.h> -+#include <linux/export.h> -+#include <linux/module.h> -+ -+#include <net/dst.h> -+ -+#include <net/netfilter/nf_conntrack.h> -+#include <net/netfilter/nf_conntrack_core.h> -+#include <net/netfilter/nf_conntrack_extend.h> -+#include <net/netfilter/nf_conntrack_rtcache.h> -+ -+#if IS_ENABLED(CONFIG_NF_CONNTRACK_IPV6) -+#include <net/ip6_fib.h> -+#endif -+ -+static void __nf_conn_rtcache_destroy(struct nf_conn_rtcache *rtc, -+ enum ip_conntrack_dir dir) -+{ -+ struct dst_entry *dst = rtc->cached_dst[dir].dst; -+ -+ dst_release(dst); -+} -+ -+static void nf_conn_rtcache_destroy(struct nf_conn *ct) -+{ -+ struct nf_conn_rtcache *rtc = nf_ct_rtcache_find(ct); -+ -+ if (!rtc) -+ return; -+ -+ __nf_conn_rtcache_destroy(rtc, IP_CT_DIR_ORIGINAL); -+ __nf_conn_rtcache_destroy(rtc, IP_CT_DIR_REPLY); -+} -+ -+static void nf_ct_rtcache_ext_add(struct nf_conn *ct) -+{ -+ struct nf_conn_rtcache *rtc; -+ -+ rtc = nf_ct_ext_add(ct, NF_CT_EXT_RTCACHE, GFP_ATOMIC); -+ if (rtc) { -+ rtc->cached_dst[IP_CT_DIR_ORIGINAL].iif = -1; -+ rtc->cached_dst[IP_CT_DIR_ORIGINAL].dst = NULL; -+ rtc->cached_dst[IP_CT_DIR_REPLY].iif = -1; -+ rtc->cached_dst[IP_CT_DIR_REPLY].dst = NULL; -+ } -+} -+ -+static struct nf_conn_rtcache *nf_ct_rtcache_find_usable(struct nf_conn *ct) -+{ -+ return nf_ct_rtcache_find(ct); -+} -+ -+static struct dst_entry * -+nf_conn_rtcache_dst_get(const struct nf_conn_rtcache *rtc, -+ enum ip_conntrack_dir dir) -+{ -+ return rtc->cached_dst[dir].dst; -+} -+ -+static u32 nf_rtcache_get_cookie(int pf, const struct dst_entry *dst) -+{ -+#if IS_ENABLED(CONFIG_NF_CONNTRACK_IPV6) -+ if (pf == NFPROTO_IPV6) { -+ const struct rt6_info *rt = (const struct rt6_info *)dst; -+ -+ if (rt->from && rt->from->fib6_node) -+ return (u32)rt->from->fib6_node->fn_sernum; -+ } -+#endif -+ return 0; -+} -+ -+static void nf_conn_rtcache_dst_set(int pf, -+ struct nf_conn_rtcache *rtc, -+ struct dst_entry *dst, -+ enum ip_conntrack_dir dir, int iif) -+{ -+ if (rtc->cached_dst[dir].iif != iif) -+ rtc->cached_dst[dir].iif = iif; -+ -+ if (rtc->cached_dst[dir].dst != dst) { -+ struct dst_entry *old; -+ -+ dst_hold(dst); -+ -+ old = xchg(&rtc->cached_dst[dir].dst, dst); -+ dst_release(old); -+ -+#if IS_ENABLED(CONFIG_NF_CONNTRACK_IPV6) -+ if (pf == NFPROTO_IPV6) -+ rtc->cached_dst[dir].cookie = -+ nf_rtcache_get_cookie(pf, dst); -+#endif -+ } -+} -+ -+static void nf_conn_rtcache_dst_obsolete(struct nf_conn_rtcache *rtc, -+ enum ip_conntrack_dir dir) -+{ -+ struct dst_entry *old; -+ -+ pr_debug("Invalidate iif %d for dir %d on cache %p\n", -+ rtc->cached_dst[dir].iif, dir, rtc); -+ -+ old = xchg(&rtc->cached_dst[dir].dst, NULL); -+ dst_release(old); -+ rtc->cached_dst[dir].iif = -1; -+} -+ -+static unsigned int nf_rtcache_in(u_int8_t pf, -+ struct sk_buff *skb, -+ const struct nf_hook_state *state) -+{ -+ struct nf_conn_rtcache *rtc; -+ enum ip_conntrack_info ctinfo; -+ enum ip_conntrack_dir dir; -+ struct dst_entry *dst; -+ struct nf_conn *ct; -+ int iif; -+ u32 cookie; -+ -+ if (skb_dst(skb) || skb->sk) -+ return NF_ACCEPT; -+ -+ ct = nf_ct_get(skb, &ctinfo); -+ if (!ct) -+ return NF_ACCEPT; -+ -+ rtc = nf_ct_rtcache_find_usable(ct); -+ if (!rtc) -+ return NF_ACCEPT; -+ -+ /* if iif changes, don't use cache and let ip stack -+ * do route lookup. -+ * -+ * If rp_filter is enabled it might toss skb, so -+ * we don't want to avoid these checks. -+ */ -+ dir = CTINFO2DIR(ctinfo); -+ iif = nf_conn_rtcache_iif_get(rtc, dir); -+ if (state->in->ifindex != iif) { -+ pr_debug("ct %p, iif %d, cached iif %d, skip cached entry\n", -+ ct, iif, state->in->ifindex); -+ return NF_ACCEPT; -+ } -+ dst = nf_conn_rtcache_dst_get(rtc, dir); -+ if (dst == NULL) -+ return NF_ACCEPT; -+ -+ cookie = nf_rtcache_get_cookie(pf, dst); -+ -+ dst = dst_check(dst, cookie); -+ pr_debug("obtained dst %p for skb %p, cookie %d\n", dst, skb, cookie); -+ if (likely(dst)) -+ skb_dst_set_noref(skb, dst); -+ else -+ nf_conn_rtcache_dst_obsolete(rtc, dir); -+ -+ return NF_ACCEPT; -+} -+ -+static unsigned int nf_rtcache_forward(u_int8_t pf, -+ struct sk_buff *skb, -+ const struct nf_hook_state *state) -+{ -+ struct nf_conn_rtcache *rtc; -+ enum ip_conntrack_info ctinfo; -+ enum ip_conntrack_dir dir; -+ struct nf_conn *ct; -+ struct dst_entry *dst = skb_dst(skb); -+ int iif; -+ -+ ct = nf_ct_get(skb, &ctinfo); -+ if (!ct) -+ return NF_ACCEPT; -+ -+ if (dst && dst_xfrm(dst)) -+ return NF_ACCEPT; -+ -+ if (!nf_ct_is_confirmed(ct)) { -+ if (WARN_ON(nf_ct_rtcache_find(ct))) -+ return NF_ACCEPT; -+ nf_ct_rtcache_ext_add(ct); -+ return NF_ACCEPT; -+ } -+ -+ rtc = nf_ct_rtcache_find_usable(ct); -+ if (!rtc) -+ return NF_ACCEPT; -+ -+ dir = CTINFO2DIR(ctinfo); -+ iif = nf_conn_rtcache_iif_get(rtc, dir); -+ pr_debug("ct %p, skb %p, dir %d, iif %d, cached iif %d\n", -+ ct, skb, dir, iif, state->in->ifindex); -+ if (likely(state->in->ifindex == iif)) -+ return NF_ACCEPT; -+ -+ nf_conn_rtcache_dst_set(pf, rtc, skb_dst(skb), dir, state->in->ifindex); -+ return NF_ACCEPT; -+} -+ -+static unsigned int nf_rtcache_in4(void *priv, -+ struct sk_buff *skb, -+ const struct nf_hook_state *state) -+{ -+ return nf_rtcache_in(NFPROTO_IPV4, skb, state); -+} -+ -+static unsigned int nf_rtcache_forward4(void *priv, -+ struct sk_buff *skb, -+ const struct nf_hook_state *state) -+{ -+ return nf_rtcache_forward(NFPROTO_IPV4, skb, state); -+} -+ -+#if IS_ENABLED(CONFIG_NF_CONNTRACK_IPV6) -+static unsigned int nf_rtcache_in6(void *priv, -+ struct sk_buff *skb, -+ const struct nf_hook_state *state) -+{ -+ return nf_rtcache_in(NFPROTO_IPV6, skb, state); -+} -+ -+static unsigned int nf_rtcache_forward6(void *priv, -+ struct sk_buff *skb, -+ const struct nf_hook_state *state) -+{ -+ return nf_rtcache_forward(NFPROTO_IPV6, skb, state); -+} -+#endif -+ -+static int nf_rtcache_dst_remove(struct nf_conn *ct, void *data) -+{ -+ struct nf_conn_rtcache *rtc = nf_ct_rtcache_find(ct); -+ struct net_device *dev = data; -+ -+ if (!rtc) -+ return 0; -+ -+ if (dev->ifindex == rtc->cached_dst[IP_CT_DIR_ORIGINAL].iif || -+ dev->ifindex == rtc->cached_dst[IP_CT_DIR_REPLY].iif) { -+ nf_conn_rtcache_dst_obsolete(rtc, IP_CT_DIR_ORIGINAL); -+ nf_conn_rtcache_dst_obsolete(rtc, IP_CT_DIR_REPLY); -+ } -+ -+ return 0; -+} -+ -+static int nf_rtcache_netdev_event(struct notifier_block *this, -+ unsigned long event, void *ptr) -+{ -+ struct net_device *dev = netdev_notifier_info_to_dev(ptr); -+ struct net *net = dev_net(dev); -+ -+ if (event == NETDEV_DOWN) -+ nf_ct_iterate_cleanup_net(net, nf_rtcache_dst_remove, dev, 0, 0); -+ -+ return NOTIFY_DONE; -+} -+ -+static struct notifier_block nf_rtcache_notifier = { -+ .notifier_call = nf_rtcache_netdev_event, -+}; -+ -+static struct nf_hook_ops rtcache_ops[] = { -+ { -+ .hook = nf_rtcache_in4, -+ .pf = NFPROTO_IPV4, -+ .hooknum = NF_INET_PRE_ROUTING, -+ .priority = NF_IP_PRI_LAST, -+ }, -+ { -+ .hook = nf_rtcache_forward4, -+ .pf = NFPROTO_IPV4, -+ .hooknum = NF_INET_FORWARD, -+ .priority = NF_IP_PRI_LAST, -+ }, -+#if IS_ENABLED(CONFIG_NF_CONNTRACK_IPV6) -+ { -+ .hook = nf_rtcache_in6, -+ .pf = NFPROTO_IPV6, -+ .hooknum = NF_INET_PRE_ROUTING, -+ .priority = NF_IP_PRI_LAST, -+ }, -+ { -+ .hook = nf_rtcache_forward6, -+ .pf = NFPROTO_IPV6, -+ .hooknum = NF_INET_FORWARD, -+ .priority = NF_IP_PRI_LAST, -+ }, -+#endif -+}; -+ -+static struct nf_ct_ext_type rtcache_extend __read_mostly = { -+ .len = sizeof(struct nf_conn_rtcache), -+ .align = __alignof__(struct nf_conn_rtcache), -+ .id = NF_CT_EXT_RTCACHE, -+ .destroy = nf_conn_rtcache_destroy, -+}; -+ -+static int __net_init rtcache_net_init(struct net *net) -+{ -+ return nf_register_net_hooks(net, rtcache_ops, ARRAY_SIZE(rtcache_ops)); -+} -+ -+static void __net_exit rtcache_net_exit(struct net *net) -+{ -+ /* remove hooks so no new connections get rtcache extension */ -+ nf_unregister_net_hooks(net, rtcache_ops, ARRAY_SIZE(rtcache_ops)); -+} -+ -+static struct pernet_operations rtcache_ops_net_ops = { -+ .init = rtcache_net_init, -+ .exit = rtcache_net_exit, -+}; -+ -+static int __init nf_conntrack_rtcache_init(void) -+{ -+ int ret = nf_ct_extend_register(&rtcache_extend); -+ -+ if (ret < 0) { -+ pr_err("nf_conntrack_rtcache: Unable to register extension\n"); -+ return ret; -+ } -+ -+ ret = register_pernet_subsys(&rtcache_ops_net_ops); -+ if (ret) { -+ nf_ct_extend_unregister(&rtcache_extend); -+ return ret; -+ } -+ -+ ret = register_netdevice_notifier(&nf_rtcache_notifier); -+ if (ret) { -+ nf_ct_extend_unregister(&rtcache_extend); -+ unregister_pernet_subsys(&rtcache_ops_net_ops); -+ } -+ -+ return ret; -+} -+ -+static int nf_rtcache_ext_remove(struct nf_conn *ct, void *data) -+{ -+ struct nf_conn_rtcache *rtc = nf_ct_rtcache_find(ct); -+ -+ return rtc != NULL; -+} -+ -+static bool __exit nf_conntrack_rtcache_wait_for_dying(struct net *net) -+{ -+ bool wait = false; -+ int cpu; -+ -+ for_each_possible_cpu(cpu) { -+ struct nf_conntrack_tuple_hash *h; -+ struct hlist_nulls_node *n; -+ struct nf_conn *ct; -+ struct ct_pcpu *pcpu = per_cpu_ptr(net->ct.pcpu_lists, cpu); -+ -+ rcu_read_lock(); -+ spin_lock_bh(&pcpu->lock); -+ -+ hlist_nulls_for_each_entry(h, n, &pcpu->dying, hnnode) { -+ ct = nf_ct_tuplehash_to_ctrack(h); -+ if (nf_ct_rtcache_find(ct) != NULL) { -+ wait = true; -+ break; -+ } -+ } -+ spin_unlock_bh(&pcpu->lock); -+ rcu_read_unlock(); -+ } -+ -+ return wait; -+} -+ -+static void __exit nf_conntrack_rtcache_fini(void) -+{ -+ struct net *net; -+ int count = 0; -+ -+ synchronize_net(); -+ -+ unregister_netdevice_notifier(&nf_rtcache_notifier); -+ unregister_pernet_subsys(&rtcache_ops_net_ops); -+ -+ synchronize_net(); -+ -+ rtnl_lock(); -+ -+ /* zap all conntracks with rtcache extension */ -+ for_each_net(net) -+ nf_ct_iterate_cleanup_net(net, nf_rtcache_ext_remove, NULL, 0, 0); -+ -+ for_each_net(net) { -+ /* .. and make sure they're gone from dying list, too */ -+ while (nf_conntrack_rtcache_wait_for_dying(net)) { -+ msleep(200); -+ WARN_ONCE(++count > 25, "Waiting for all rtcache conntracks to go away\n"); -+ } -+ } -+ -+ rtnl_unlock(); -+ -+ synchronize_net(); -+ nf_ct_extend_unregister(&rtcache_extend); -+} -+module_init(nf_conntrack_rtcache_init); -+module_exit(nf_conntrack_rtcache_fini); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Florian Westphal <fw@strlen.de>"); -+MODULE_DESCRIPTION("Conntrack route cache extension"); diff --git a/target/linux/generic/backport-4.19/047-v4.21-mtd-keep-original-flags-for-every-struct-mtd_info.patch b/target/linux/generic/backport-4.19/047-v4.21-mtd-keep-original-flags-for-every-struct-mtd_info.patch deleted file mode 100644 index d587c9ec07..0000000000 --- a/target/linux/generic/backport-4.19/047-v4.21-mtd-keep-original-flags-for-every-struct-mtd_info.patch +++ /dev/null @@ -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 diff --git a/target/linux/generic/backport-4.19/048-v4.21-mtd-improve-calculating-partition-boundaries-when-ch.patch b/target/linux/generic/backport-4.19/048-v4.21-mtd-improve-calculating-partition-boundaries-when-ch.patch deleted file mode 100644 index 02296276b0..0000000000 --- a/target/linux/generic/backport-4.19/048-v4.21-mtd-improve-calculating-partition-boundaries-when-ch.patch +++ /dev/null @@ -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; diff --git a/target/linux/generic/backport-4.19/080-v5.1-0001-bcma-keep-a-direct-pointer-to-the-struct-device.patch b/target/linux/generic/backport-4.19/080-v5.1-0001-bcma-keep-a-direct-pointer-to-the-struct-device.patch deleted file mode 100644 index cc32aee17b..0000000000 --- a/target/linux/generic/backport-4.19/080-v5.1-0001-bcma-keep-a-direct-pointer-to-the-struct-device.patch +++ /dev/null @@ -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; - diff --git a/target/linux/generic/backport-4.19/080-v5.1-0002-bcma-use-dev_-printing-functions.patch b/target/linux/generic/backport-4.19/080-v5.1-0002-bcma-use-dev_-printing-functions.patch deleted file mode 100644 index 7ce8ba8967..0000000000 --- a/target/linux/generic/backport-4.19/080-v5.1-0002-bcma-use-dev_-printing-functions.patch +++ /dev/null @@ -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; - diff --git a/target/linux/generic/backport-4.19/095-Allow-class-e-address-assignment-via-ifconfig-ioctl.patch b/target/linux/generic/backport-4.19/095-Allow-class-e-address-assignment-via-ifconfig-ioctl.patch deleted file mode 100644 index e473c8918b..0000000000 --- a/target/linux/generic/backport-4.19/095-Allow-class-e-address-assignment-via-ifconfig-ioctl.patch +++ /dev/null @@ -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 -@@ -955,7 +955,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); -@@ -966,6 +966,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); diff --git a/target/linux/generic/backport-4.19/101-arm-cns3xxx-use-actual-size-reads-for-PCIe.patch b/target/linux/generic/backport-4.19/101-arm-cns3xxx-use-actual-size-reads-for-PCIe.patch deleted file mode 100644 index 2b3384391a..0000000000 --- a/target/linux/generic/backport-4.19/101-arm-cns3xxx-use-actual-size-reads-for-PCIe.patch +++ /dev/null @@ -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) diff --git a/target/linux/generic/backport-4.19/200-v5.2-usb-dwc2-Set-lpm-mode-parameters-depend-on-HW-configuration.patch b/target/linux/generic/backport-4.19/200-v5.2-usb-dwc2-Set-lpm-mode-parameters-depend-on-HW-configuration.patch deleted file mode 100644 index ed4aadf2be..0000000000 --- a/target/linux/generic/backport-4.19/200-v5.2-usb-dwc2-Set-lpm-mode-parameters-depend-on-HW-configuration.patch +++ /dev/null @@ -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; diff --git a/target/linux/generic/backport-4.19/210-arm64-sve-Disentangle-uapi-asm-ptrace.h-from-uapi-as.patch b/target/linux/generic/backport-4.19/210-arm64-sve-Disentangle-uapi-asm-ptrace.h-from-uapi-as.patch deleted file mode 100644 index 7c574fd343..0000000000 --- a/target/linux/generic/backport-4.19/210-arm64-sve-Disentangle-uapi-asm-ptrace.h-from-uapi-as.patch +++ /dev/null @@ -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 */ diff --git a/target/linux/generic/backport-4.19/343-netfilter-nft_flow_offload-handle-netdevice-events-f.patch b/target/linux/generic/backport-4.19/343-netfilter-nft_flow_offload-handle-netdevice-events-f.patch deleted file mode 100644 index 577f2d3df6..0000000000 --- a/target/linux/generic/backport-4.19/343-netfilter-nft_flow_offload-handle-netdevice-events-f.patch +++ /dev/null @@ -1,99 +0,0 @@ -From: Pablo Neira Ayuso <pablo@netfilter.org> -Date: Thu, 25 Jan 2018 12:58:55 +0100 -Subject: [PATCH] netfilter: nft_flow_offload: handle netdevice events from - nf_flow_table - -Move the code that deals with device events to the core. - -Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> ---- - ---- a/net/netfilter/nf_flow_table_core.c -+++ b/net/netfilter/nf_flow_table_core.c -@@ -535,5 +535,35 @@ void nf_flow_table_free(struct nf_flowta - } - EXPORT_SYMBOL_GPL(nf_flow_table_free); - -+static int nf_flow_table_netdev_event(struct notifier_block *this, -+ unsigned long event, void *ptr) -+{ -+ struct net_device *dev = netdev_notifier_info_to_dev(ptr); -+ -+ if (event != NETDEV_DOWN) -+ return NOTIFY_DONE; -+ -+ nf_flow_table_cleanup(dev_net(dev), dev); -+ -+ return NOTIFY_DONE; -+} -+ -+static struct notifier_block flow_offload_netdev_notifier = { -+ .notifier_call = nf_flow_table_netdev_event, -+}; -+ -+static int __init nf_flow_table_module_init(void) -+{ -+ return register_netdevice_notifier(&flow_offload_netdev_notifier); -+} -+ -+static void __exit nf_flow_table_module_exit(void) -+{ -+ unregister_netdevice_notifier(&flow_offload_netdev_notifier); -+} -+ -+module_init(nf_flow_table_module_init); -+module_exit(nf_flow_table_module_exit); -+ - MODULE_LICENSE("GPL"); - MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>"); ---- a/net/netfilter/nft_flow_offload.c -+++ b/net/netfilter/nft_flow_offload.c -@@ -216,47 +216,14 @@ static struct nft_expr_type nft_flow_off - .owner = THIS_MODULE, - }; - --static int flow_offload_netdev_event(struct notifier_block *this, -- unsigned long event, void *ptr) --{ -- struct net_device *dev = netdev_notifier_info_to_dev(ptr); -- -- if (event != NETDEV_DOWN) -- return NOTIFY_DONE; -- -- nf_flow_table_cleanup(dev_net(dev), dev); -- -- return NOTIFY_DONE; --} -- --static struct notifier_block flow_offload_netdev_notifier = { -- .notifier_call = flow_offload_netdev_event, --}; -- - static int __init nft_flow_offload_module_init(void) - { -- int err; -- -- err = register_netdevice_notifier(&flow_offload_netdev_notifier); -- if (err) -- goto err; -- -- err = nft_register_expr(&nft_flow_offload_type); -- if (err < 0) -- goto register_expr; -- -- return 0; -- --register_expr: -- unregister_netdevice_notifier(&flow_offload_netdev_notifier); --err: -- return err; -+ return nft_register_expr(&nft_flow_offload_type); - } - - static void __exit nft_flow_offload_module_exit(void) - { - nft_unregister_expr(&nft_flow_offload_type); -- unregister_netdevice_notifier(&flow_offload_netdev_notifier); - } - - module_init(nft_flow_offload_module_init); diff --git a/target/linux/generic/backport-4.19/370-netfilter-nf_flow_table-fix-offloaded-connection-tim.patch b/target/linux/generic/backport-4.19/370-netfilter-nf_flow_table-fix-offloaded-connection-tim.patch deleted file mode 100644 index 7c10f6f189..0000000000 --- a/target/linux/generic/backport-4.19/370-netfilter-nf_flow_table-fix-offloaded-connection-tim.patch +++ /dev/null @@ -1,112 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Wed, 13 Jun 2018 12:33:39 +0200 -Subject: [PATCH] netfilter: nf_flow_table: fix offloaded connection timeout - corner case - -The full teardown of offloaded flows is deferred to a gc work item, -however processing of packets by netfilter needs to happen immediately -after a teardown is requested, because the conntrack state needs to be -fixed up. - -Since the IPS_OFFLOAD_BIT is still kept until the teardown is complete, -the netfilter conntrack gc can accidentally bump the timeout of a -connection where offload was just stopped, causing a conntrack entry -leak. - -Fix this by moving the conntrack timeout bumping from conntrack core to -the nf_flow_offload and add a check to prevent bogus timeout bumps. - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/net/netfilter/nf_conntrack_core.c -+++ b/net/netfilter/nf_conntrack_core.c -@@ -1178,18 +1178,6 @@ static bool gc_worker_can_early_drop(con - return false; - } - --#define DAY (86400 * HZ) -- --/* Set an arbitrary timeout large enough not to ever expire, this save -- * us a check for the IPS_OFFLOAD_BIT from the packet path via -- * nf_ct_is_expired(). -- */ --static void nf_ct_offload_timeout(struct nf_conn *ct) --{ -- if (nf_ct_expires(ct) < DAY / 2) -- ct->timeout = nfct_time_stamp + DAY; --} -- - static void gc_worker(struct work_struct *work) - { - unsigned int min_interval = max(HZ / GC_MAX_BUCKETS_DIV, 1u); -@@ -1226,10 +1214,8 @@ static void gc_worker(struct work_struct - tmp = nf_ct_tuplehash_to_ctrack(h); - - scanned++; -- if (test_bit(IPS_OFFLOAD_BIT, &tmp->status)) { -- nf_ct_offload_timeout(tmp); -+ if (test_bit(IPS_OFFLOAD_BIT, &tmp->status)) - continue; -- } - - if (nf_ct_is_expired(tmp)) { - nf_ct_gc_expired(tmp); ---- a/net/netfilter/nf_flow_table_core.c -+++ b/net/netfilter/nf_flow_table_core.c -@@ -183,10 +183,29 @@ static const struct rhashtable_params nf - .automatic_shrinking = true, - }; - -+#define DAY (86400 * HZ) -+ -+/* Set an arbitrary timeout large enough not to ever expire, this save -+ * us a check for the IPS_OFFLOAD_BIT from the packet path via -+ * nf_ct_is_expired(). -+ */ -+static void nf_ct_offload_timeout(struct flow_offload *flow) -+{ -+ struct flow_offload_entry *entry; -+ struct nf_conn *ct; -+ -+ entry = container_of(flow, struct flow_offload_entry, flow); -+ ct = entry->ct; -+ -+ if (nf_ct_expires(ct) < DAY / 2) -+ ct->timeout = nfct_time_stamp + DAY; -+} -+ - int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow) - { - int err; - -+ nf_ct_offload_timeout(flow); - flow->timeout = (u32)jiffies + NF_FLOW_TIMEOUT; - - err = rhashtable_insert_fast(&flow_table->rhashtable, -@@ -317,6 +336,8 @@ static int nf_flow_offload_gc_step(struc - rhashtable_walk_start(&hti); - - while ((tuplehash = rhashtable_walk_next(&hti))) { -+ bool teardown; -+ - if (IS_ERR(tuplehash)) { - err = PTR_ERR(tuplehash); - if (err != -EAGAIN) -@@ -329,9 +350,13 @@ static int nf_flow_offload_gc_step(struc - - flow = container_of(tuplehash, struct flow_offload, tuplehash[0]); - -- if (nf_flow_has_expired(flow) || -- (flow->flags & (FLOW_OFFLOAD_DYING | -- FLOW_OFFLOAD_TEARDOWN))) -+ teardown = flow->flags & (FLOW_OFFLOAD_DYING | -+ FLOW_OFFLOAD_TEARDOWN); -+ -+ if (!teardown) -+ nf_ct_offload_timeout(flow); -+ -+ if (nf_flow_has_expired(flow) || teardown) - flow_offload_del(flow_table, flow); - } - out: diff --git a/target/linux/generic/backport-4.19/371-netfilter-nf_flow_table-fix-up-ct-state-of-flows-aft.patch b/target/linux/generic/backport-4.19/371-netfilter-nf_flow_table-fix-up-ct-state-of-flows-aft.patch deleted file mode 100644 index 2e25066499..0000000000 --- a/target/linux/generic/backport-4.19/371-netfilter-nf_flow_table-fix-up-ct-state-of-flows-aft.patch +++ /dev/null @@ -1,24 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Thu, 14 Jun 2018 11:20:09 +0200 -Subject: [PATCH] netfilter: nf_flow_table: fix up ct state of flows after - timeout - -If a connection simply times out instead of being torn down, it is left -active with a long timeout. Fix this by calling flow_offload_fixup_ct_state -here as well. - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/net/netfilter/nf_flow_table_core.c -+++ b/net/netfilter/nf_flow_table_core.c -@@ -243,6 +243,9 @@ static void flow_offload_del(struct nf_f - e = container_of(flow, struct flow_offload_entry, flow); - clear_bit(IPS_OFFLOAD_BIT, &e->ct->status); - -+ if (!(flow->flags & FLOW_OFFLOAD_TEARDOWN)) -+ flow_offload_fixup_ct_state(e->ct); -+ - flow_offload_free(flow); - } - diff --git a/target/linux/generic/backport-4.19/380-v5.3-net-sched-Introduce-act_ctinfo-action.patch b/target/linux/generic/backport-4.19/380-v5.3-net-sched-Introduce-act_ctinfo-action.patch deleted file mode 100644 index cf7687b451..0000000000 --- a/target/linux/generic/backport-4.19/380-v5.3-net-sched-Introduce-act_ctinfo-action.patch +++ /dev/null @@ -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 (skb_protocol(skb, true) == htons(ETH_P_IP)) { -+ wlen += sizeof(struct iphdr); -+ if (!pskb_may_pull(skb, wlen)) -+ goto out; -+ -+ proto = NFPROTO_IPV4; -+ } else if (skb_protocol(skb, true) == 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 diff --git a/target/linux/generic/backport-4.19/390-v5.1-sch_cake-Make-the-dual-modes-fairer.patch b/target/linux/generic/backport-4.19/390-v5.1-sch_cake-Make-the-dual-modes-fairer.patch deleted file mode 100644 index 0454565747..0000000000 --- a/target/linux/generic/backport-4.19/390-v5.1-sch_cake-Make-the-dual-modes-fairer.patch +++ /dev/null @@ -1,217 +0,0 @@ -From 712639929912c5eefb09facccb48d55b3f72c9f8 Mon Sep 17 00:00:00 2001 -From: George Amanakis <gamanakis@gmail.com> -Date: Fri, 1 Mar 2019 16:04:05 +0100 -Subject: [PATCH] sch_cake: Make the dual modes fairer -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -CAKE host fairness does not work well with TCP flows in dual-srchost and -dual-dsthost setup. The reason is that ACKs generated by TCP flows are -classified as sparse flows, and affect flow isolation from other hosts. Fix -this by calculating host_load based only on the bulk flows a host -generates. In a hash collision the host_bulk_flow_count values must be -decremented on the old hosts and incremented on the new ones *if* the queue -is in the bulk set. - -Reported-by: Pete Heist <peteheist@gmail.com> -Signed-off-by: George Amanakis <gamanakis@gmail.com> -Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> -Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> ---- - net/sched/sch_cake.c | 92 ++++++++++++++++++++++++++++++-------------- - 1 file changed, 63 insertions(+), 29 deletions(-) - ---- a/net/sched/sch_cake.c -+++ b/net/sched/sch_cake.c -@@ -138,8 +138,8 @@ struct cake_flow { - struct cake_host { - u32 srchost_tag; - u32 dsthost_tag; -- u16 srchost_refcnt; -- u16 dsthost_refcnt; -+ u16 srchost_bulk_flow_count; -+ u16 dsthost_bulk_flow_count; - }; - - struct cake_heap_entry { -@@ -746,8 +746,10 @@ skip_hash: - * queue, accept the collision, update the host tags. - */ - q->way_collisions++; -- q->hosts[q->flows[reduced_hash].srchost].srchost_refcnt--; -- q->hosts[q->flows[reduced_hash].dsthost].dsthost_refcnt--; -+ if (q->flows[outer_hash + k].set == CAKE_SET_BULK) { -+ q->hosts[q->flows[reduced_hash].srchost].srchost_bulk_flow_count--; -+ q->hosts[q->flows[reduced_hash].dsthost].dsthost_bulk_flow_count--; -+ } - allocate_src = cake_dsrc(flow_mode); - allocate_dst = cake_ddst(flow_mode); - found: -@@ -767,13 +769,14 @@ found: - } - for (i = 0; i < CAKE_SET_WAYS; - i++, k = (k + 1) % CAKE_SET_WAYS) { -- if (!q->hosts[outer_hash + k].srchost_refcnt) -+ if (!q->hosts[outer_hash + k].srchost_bulk_flow_count) - break; - } - q->hosts[outer_hash + k].srchost_tag = srchost_hash; - found_src: - srchost_idx = outer_hash + k; -- q->hosts[srchost_idx].srchost_refcnt++; -+ if (q->flows[reduced_hash].set == CAKE_SET_BULK) -+ q->hosts[srchost_idx].srchost_bulk_flow_count++; - q->flows[reduced_hash].srchost = srchost_idx; - } - -@@ -789,13 +792,14 @@ found_src: - } - for (i = 0; i < CAKE_SET_WAYS; - i++, k = (k + 1) % CAKE_SET_WAYS) { -- if (!q->hosts[outer_hash + k].dsthost_refcnt) -+ if (!q->hosts[outer_hash + k].dsthost_bulk_flow_count) - break; - } - q->hosts[outer_hash + k].dsthost_tag = dsthost_hash; - found_dst: - dsthost_idx = outer_hash + k; -- q->hosts[dsthost_idx].dsthost_refcnt++; -+ if (q->flows[reduced_hash].set == CAKE_SET_BULK) -+ q->hosts[dsthost_idx].dsthost_bulk_flow_count++; - q->flows[reduced_hash].dsthost = dsthost_idx; - } - } -@@ -1817,20 +1821,30 @@ static s32 cake_enqueue(struct sk_buff * - b->sparse_flow_count++; - - if (cake_dsrc(q->flow_mode)) -- host_load = max(host_load, srchost->srchost_refcnt); -+ host_load = max(host_load, srchost->srchost_bulk_flow_count); - - if (cake_ddst(q->flow_mode)) -- host_load = max(host_load, dsthost->dsthost_refcnt); -+ host_load = max(host_load, dsthost->dsthost_bulk_flow_count); - - flow->deficit = (b->flow_quantum * - quantum_div[host_load]) >> 16; - } else if (flow->set == CAKE_SET_SPARSE_WAIT) { -+ struct cake_host *srchost = &b->hosts[flow->srchost]; -+ struct cake_host *dsthost = &b->hosts[flow->dsthost]; -+ - /* this flow was empty, accounted as a sparse flow, but actually - * in the bulk rotation. - */ - flow->set = CAKE_SET_BULK; - b->sparse_flow_count--; - b->bulk_flow_count++; -+ -+ if (cake_dsrc(q->flow_mode)) -+ srchost->srchost_bulk_flow_count++; -+ -+ if (cake_ddst(q->flow_mode)) -+ dsthost->dsthost_bulk_flow_count++; -+ - } - - if (q->buffer_used > q->buffer_max_used) -@@ -1998,23 +2012,8 @@ retry: - dsthost = &b->hosts[flow->dsthost]; - host_load = 1; - -- if (cake_dsrc(q->flow_mode)) -- host_load = max(host_load, srchost->srchost_refcnt); -- -- if (cake_ddst(q->flow_mode)) -- host_load = max(host_load, dsthost->dsthost_refcnt); -- -- WARN_ON(host_load > CAKE_QUEUES); -- - /* flow isolation (DRR++) */ - if (flow->deficit <= 0) { -- /* The shifted prandom_u32() is a way to apply dithering to -- * avoid accumulating roundoff errors -- */ -- flow->deficit += (b->flow_quantum * quantum_div[host_load] + -- (prandom_u32() >> 16)) >> 16; -- list_move_tail(&flow->flowchain, &b->old_flows); -- - /* Keep all flows with deficits out of the sparse and decaying - * rotations. No non-empty flow can go into the decaying - * rotation, so they can't get deficits -@@ -2023,6 +2022,13 @@ retry: - if (flow->head) { - b->sparse_flow_count--; - b->bulk_flow_count++; -+ -+ if (cake_dsrc(q->flow_mode)) -+ srchost->srchost_bulk_flow_count++; -+ -+ if (cake_ddst(q->flow_mode)) -+ dsthost->dsthost_bulk_flow_count++; -+ - flow->set = CAKE_SET_BULK; - } else { - /* we've moved it to the bulk rotation for -@@ -2032,6 +2038,22 @@ retry: - flow->set = CAKE_SET_SPARSE_WAIT; - } - } -+ -+ if (cake_dsrc(q->flow_mode)) -+ host_load = max(host_load, srchost->srchost_bulk_flow_count); -+ -+ if (cake_ddst(q->flow_mode)) -+ host_load = max(host_load, dsthost->dsthost_bulk_flow_count); -+ -+ WARN_ON(host_load > CAKE_QUEUES); -+ -+ /* The shifted prandom_u32() is a way to apply dithering to -+ * avoid accumulating roundoff errors -+ */ -+ flow->deficit += (b->flow_quantum * quantum_div[host_load] + -+ (prandom_u32() >> 16)) >> 16; -+ list_move_tail(&flow->flowchain, &b->old_flows); -+ - goto retry; - } - -@@ -2052,6 +2074,13 @@ retry: - &b->decaying_flows); - if (flow->set == CAKE_SET_BULK) { - b->bulk_flow_count--; -+ -+ if (cake_dsrc(q->flow_mode)) -+ srchost->srchost_bulk_flow_count--; -+ -+ if (cake_ddst(q->flow_mode)) -+ dsthost->dsthost_bulk_flow_count--; -+ - b->decaying_flow_count++; - } else if (flow->set == CAKE_SET_SPARSE || - flow->set == CAKE_SET_SPARSE_WAIT) { -@@ -2065,14 +2094,19 @@ retry: - if (flow->set == CAKE_SET_SPARSE || - flow->set == CAKE_SET_SPARSE_WAIT) - b->sparse_flow_count--; -- else if (flow->set == CAKE_SET_BULK) -+ else if (flow->set == CAKE_SET_BULK) { - b->bulk_flow_count--; -- else -+ -+ if (cake_dsrc(q->flow_mode)) -+ srchost->srchost_bulk_flow_count--; -+ -+ if (cake_ddst(q->flow_mode)) -+ dsthost->dsthost_bulk_flow_count--; -+ -+ } else - b->decaying_flow_count--; - - flow->set = CAKE_SET_NONE; -- srchost->srchost_refcnt--; -- dsthost->dsthost_refcnt--; - } - goto begin; - } diff --git a/target/linux/generic/backport-4.19/391-v5.1-sch_cake-Permit-use-of-connmarks-as-tin-classifiers.patch b/target/linux/generic/backport-4.19/391-v5.1-sch_cake-Permit-use-of-connmarks-as-tin-classifiers.patch deleted file mode 100644 index 638a2b4529..0000000000 --- a/target/linux/generic/backport-4.19/391-v5.1-sch_cake-Permit-use-of-connmarks-as-tin-classifiers.patch +++ /dev/null @@ -1,118 +0,0 @@ -From 0b5c7efdfc6e389ec6840579fe90bdb6f42b08dc Mon Sep 17 00:00:00 2001 -From: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> -Date: Fri, 1 Mar 2019 16:04:05 +0100 -Subject: [PATCH] sch_cake: Permit use of connmarks as tin classifiers -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add flag 'FWMARK' to enable use of firewall connmarks as tin selector. -The connmark (skbuff->mark) needs to be in the range 1->tin_cnt ie. -for diffserv3 the mark needs to be 1->3. - -Background - -Typically CAKE uses DSCP as the basis for tin selection. DSCP values -are relatively easily changed as part of the egress path, usually with -iptables & the mangle table, ingress is more challenging. CAKE is often -used on the WAN interface of a residential gateway where passthrough of -DSCP from the ISP is either missing or set to unhelpful values thus use -of ingress DSCP values for tin selection isn't helpful in that -environment. - -An approach to solving the ingress tin selection problem is to use -CAKE's understanding of tc filters. Naive tc filters could match on -source/destination port numbers and force tin selection that way, but -multiple filters don't scale particularly well as each filter must be -traversed whether it matches or not. e.g. a simple example to map 3 -firewall marks to tins: - -MAJOR=$( tc qdisc show dev $DEV | head -1 | awk '{print $3}' ) -tc filter add dev $DEV parent $MAJOR protocol all handle 0x01 fw action skbedit priority ${MAJOR}1 -tc filter add dev $DEV parent $MAJOR protocol all handle 0x02 fw action skbedit priority ${MAJOR}2 -tc filter add dev $DEV parent $MAJOR protocol all handle 0x03 fw action skbedit priority ${MAJOR}3 - -Another option is to use eBPF cls_act with tc filters e.g. - -MAJOR=$( tc qdisc show dev $DEV | head -1 | awk '{print $3}' ) -tc filter add dev $DEV parent $MAJOR bpf da obj my-bpf-fwmark-to-class.o - -This has the disadvantages of a) needing someone to write & maintain -the bpf program, b) a bpf toolchain to compile it and c) needing to -hardcode the major number in the bpf program so it matches the cake -instance (or forcing the cake instance to a particular major number) -since the major number cannot be passed to the bpf program via tc -command line. - -As already hinted at by the previous examples, it would be helpful -to associate tins with something that survives the Internet path and -ideally allows tin selection on both egress and ingress. Netfilter's -conntrack permits setting an identifying mark on a connection which -can also be restored to an ingress packet with tc action connmark e.g. - -tc filter add dev eth0 parent ffff: protocol all prio 10 u32 \ - match u32 0 0 flowid 1:1 action connmark action mirred egress redirect dev ifb1 - -Since tc's connmark action has restored any connmark into skb->mark, -any of the previous solutions are based upon it and in one form or -another copy that mark to the skb->priority field where again CAKE -picks this up. - -This change cuts out at least one of the (less intuitive & -non-scalable) middlemen and permit direct access to skb->mark. - -Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> -Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - include/uapi/linux/pkt_sched.h | 1 + - net/sched/sch_cake.c | 34 +++++++++++++++++++++++++++------- - 2 files changed, 28 insertions(+), 7 deletions(-) - ---- a/include/uapi/linux/pkt_sched.h -+++ b/include/uapi/linux/pkt_sched.h -@@ -991,6 +991,7 @@ enum { - TCA_CAKE_INGRESS, - TCA_CAKE_ACK_FILTER, - TCA_CAKE_SPLIT_GSO, -+ TCA_CAKE_FWMARK, - __TCA_CAKE_MAX - }; - #define TCA_CAKE_MAX (__TCA_CAKE_MAX - 1) ---- a/net/sched/sch_cake.c -+++ b/net/sched/sch_cake.c -@@ -258,7 +258,8 @@ enum { - CAKE_FLAG_AUTORATE_INGRESS = BIT(1), - CAKE_FLAG_INGRESS = BIT(2), - CAKE_FLAG_WASH = BIT(3), -- CAKE_FLAG_SPLIT_GSO = BIT(4) -+ CAKE_FLAG_SPLIT_GSO = BIT(4), -+ CAKE_FLAG_FWMARK = BIT(5) - }; - - /* COBALT operates the Codel and BLUE algorithms in parallel, in order to -@@ -2647,6 +2648,13 @@ static int cake_change(struct Qdisc *sch - q->rate_flags &= ~CAKE_FLAG_SPLIT_GSO; - } - -+ if (tb[TCA_CAKE_FWMARK]) { -+ if (!!nla_get_u32(tb[TCA_CAKE_FWMARK])) -+ q->rate_flags |= CAKE_FLAG_FWMARK; -+ else -+ q->rate_flags &= ~CAKE_FLAG_FWMARK; -+ } -+ - if (q->tins) { - sch_tree_lock(sch); - cake_reconfigure(sch); -@@ -2806,6 +2814,10 @@ static int cake_dump(struct Qdisc *sch, - !!(q->rate_flags & CAKE_FLAG_SPLIT_GSO))) - goto nla_put_failure; - -+ if (nla_put_u32(skb, TCA_CAKE_FWMARK, -+ !!(q->rate_flags & CAKE_FLAG_FWMARK))) -+ goto nla_put_failure; -+ - return nla_nest_end(skb, opts); - - nla_put_failure: diff --git a/target/linux/generic/backport-4.19/392-v5.1-sch_cake-Interpret-fwmark-parameter-as-a-bitmask.patch b/target/linux/generic/backport-4.19/392-v5.1-sch_cake-Interpret-fwmark-parameter-as-a-bitmask.patch deleted file mode 100644 index 6ba0897b34..0000000000 --- a/target/linux/generic/backport-4.19/392-v5.1-sch_cake-Interpret-fwmark-parameter-as-a-bitmask.patch +++ /dev/null @@ -1,102 +0,0 @@ -From eab2fc822af38f31fd5f4e731b5d10b94904d919 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= <toke@redhat.com> -Date: Thu, 14 Mar 2019 23:08:22 +0100 -Subject: [PATCH] sch_cake: Interpret fwmark parameter as a bitmask -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -We initially interpreted the fwmark parameter as a flag that simply turned -on the feature, using the whole skb->mark field as the index into the CAKE -tin_order array. However, it is quite common for different applications to -use different parts of the mask field for their own purposes, each using a -different mask. - -Support this use of subsets of the mark by interpreting the TCA_CAKE_FWMARK -parameter as a bitmask to apply to the fwmark field when reading it. The -result will be right-shifted by the number of unset lower bits of the mask -before looking up the tin. - -In the original commit message we also failed to credit Felix Resch with -originally suggesting the fwmark feature back in 2017; so the Suggested-By -in this commit covers the whole fwmark feature. - -Fixes: 0b5c7efdfc6e ("sch_cake: Permit use of connmarks as tin classifiers") -Suggested-by: Felix Resch <fuller@beif.de> -Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> -Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> ---- - net/sched/sch_cake.c | 25 ++++++++++++------------- - 1 file changed, 12 insertions(+), 13 deletions(-) - ---- a/net/sched/sch_cake.c -+++ b/net/sched/sch_cake.c -@@ -211,6 +211,9 @@ struct cake_sched_data { - u8 ack_filter; - u8 atm_mode; - -+ u32 fwmark_mask; -+ u16 fwmark_shft; -+ - /* time_next = time_this + ((len * rate_ns) >> rate_shft) */ - u16 rate_shft; - ktime_t time_next_packet; -@@ -258,8 +261,7 @@ enum { - CAKE_FLAG_AUTORATE_INGRESS = BIT(1), - CAKE_FLAG_INGRESS = BIT(2), - CAKE_FLAG_WASH = BIT(3), -- CAKE_FLAG_SPLIT_GSO = BIT(4), -- CAKE_FLAG_FWMARK = BIT(5) -+ CAKE_FLAG_SPLIT_GSO = BIT(4) - }; - - /* COBALT operates the Codel and BLUE algorithms in parallel, in order to -@@ -1573,7 +1575,7 @@ static struct cake_tin_data *cake_select - struct sk_buff *skb) - { - struct cake_sched_data *q = qdisc_priv(sch); -- u32 tin; -+ u32 tin, mark; - bool wash; - u8 dscp; - -@@ -1584,6 +1586,7 @@ static struct cake_tin_data *cake_select - wash = !!(q->rate_flags & CAKE_FLAG_WASH); - if (wash) - dscp = cake_handle_diffserv(skb, wash); -+ mark = (skb->mark & q->fwmark_mask) >> q->fwmark_shft; - - if (q->tin_mode == CAKE_DIFFSERV_BESTEFFORT) - tin = 0; -@@ -2202,6 +2205,7 @@ static const struct nla_policy cake_poli - [TCA_CAKE_MPU] = { .type = NLA_U32 }, - [TCA_CAKE_INGRESS] = { .type = NLA_U32 }, - [TCA_CAKE_ACK_FILTER] = { .type = NLA_U32 }, -+ [TCA_CAKE_FWMARK] = { .type = NLA_U32 }, - }; - - static void cake_set_rate(struct cake_tin_data *b, u64 rate, u32 mtu, -@@ -2649,10 +2653,8 @@ static int cake_change(struct Qdisc *sch - } - - if (tb[TCA_CAKE_FWMARK]) { -- if (!!nla_get_u32(tb[TCA_CAKE_FWMARK])) -- q->rate_flags |= CAKE_FLAG_FWMARK; -- else -- q->rate_flags &= ~CAKE_FLAG_FWMARK; -+ q->fwmark_mask = nla_get_u32(tb[TCA_CAKE_FWMARK]); -+ q->fwmark_shft = q->fwmark_mask ? __ffs(q->fwmark_mask) : 0; - } - - if (q->tins) { -@@ -2814,8 +2816,7 @@ static int cake_dump(struct Qdisc *sch, - !!(q->rate_flags & CAKE_FLAG_SPLIT_GSO))) - goto nla_put_failure; - -- if (nla_put_u32(skb, TCA_CAKE_FWMARK, -- !!(q->rate_flags & CAKE_FLAG_FWMARK))) -+ if (nla_put_u32(skb, TCA_CAKE_FWMARK, q->fwmark_mask)) - goto nla_put_failure; - - return nla_nest_end(skb, opts); diff --git a/target/linux/generic/backport-4.19/393-v5.5-sch_cake-drop-unused-variable-tin_quantum_prio.patch b/target/linux/generic/backport-4.19/393-v5.5-sch_cake-drop-unused-variable-tin_quantum_prio.patch deleted file mode 100644 index 023844f5e6..0000000000 --- a/target/linux/generic/backport-4.19/393-v5.5-sch_cake-drop-unused-variable-tin_quantum_prio.patch +++ /dev/null @@ -1,158 +0,0 @@ -From d7e1738f0a0b0573ac93cf570ba3df9dee61b68e Mon Sep 17 00:00:00 2001 -From: Kevin 'ldir' Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> -Date: Wed, 18 Dec 2019 14:05:13 +0000 -Subject: [PATCH 2/2] sch_cake: drop unused variable tin_quantum_prio -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Turns out tin_quantum_prio isn't used anymore and is a leftover from a -previous implementation of diffserv tins. Since the variable isn't used -in any calculations it can be eliminated. - -Drop variable and places where it was set. Rename remaining variable -and consolidate naming of intermediate variables that set it. - -Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> -Acked-by: Toke Høiland-Jørgensen <toke@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - net/sched/sch_cake.c | 59 ++++++++++++++------------------------------ - 1 file changed, 18 insertions(+), 41 deletions(-) - ---- a/net/sched/sch_cake.c -+++ b/net/sched/sch_cake.c -@@ -173,8 +173,7 @@ struct cake_tin_data { - u64 tin_rate_bps; - u16 tin_rate_shft; - -- u16 tin_quantum_prio; -- u16 tin_quantum_band; -+ u16 tin_quantum; - s32 tin_deficit; - u32 tin_backlog; - u32 tin_dropped; -@@ -1940,7 +1939,7 @@ begin: - while (b->tin_deficit < 0 || - !(b->sparse_flow_count + b->bulk_flow_count)) { - if (b->tin_deficit <= 0) -- b->tin_deficit += b->tin_quantum_band; -+ b->tin_deficit += b->tin_quantum; - if (b->sparse_flow_count + b->bulk_flow_count) - empty = false; - -@@ -2261,8 +2260,7 @@ static int cake_config_besteffort(struct - - cake_set_rate(b, rate, mtu, - us_to_ns(q->target), us_to_ns(q->interval)); -- b->tin_quantum_band = 65535; -- b->tin_quantum_prio = 65535; -+ b->tin_quantum = 65535; - - return 0; - } -@@ -2273,8 +2271,7 @@ static int cake_config_precedence(struct - struct cake_sched_data *q = qdisc_priv(sch); - u32 mtu = psched_mtu(qdisc_dev(sch)); - u64 rate = q->rate_bps; -- u32 quantum1 = 256; -- u32 quantum2 = 256; -+ u32 quantum = 256; - u32 i; - - q->tin_cnt = 8; -@@ -2287,18 +2284,14 @@ static int cake_config_precedence(struct - cake_set_rate(b, rate, mtu, us_to_ns(q->target), - us_to_ns(q->interval)); - -- b->tin_quantum_prio = max_t(u16, 1U, quantum1); -- b->tin_quantum_band = max_t(u16, 1U, quantum2); -+ b->tin_quantum = max_t(u16, 1U, quantum); - - /* calculate next class's parameters */ - rate *= 7; - rate >>= 3; - -- quantum1 *= 3; -- quantum1 >>= 1; -- -- quantum2 *= 7; -- quantum2 >>= 3; -+ quantum *= 7; -+ quantum >>= 3; - } - - return 0; -@@ -2367,8 +2360,7 @@ static int cake_config_diffserv8(struct - struct cake_sched_data *q = qdisc_priv(sch); - u32 mtu = psched_mtu(qdisc_dev(sch)); - u64 rate = q->rate_bps; -- u32 quantum1 = 256; -- u32 quantum2 = 256; -+ u32 quantum = 256; - u32 i; - - q->tin_cnt = 8; -@@ -2384,18 +2376,14 @@ static int cake_config_diffserv8(struct - cake_set_rate(b, rate, mtu, us_to_ns(q->target), - us_to_ns(q->interval)); - -- b->tin_quantum_prio = max_t(u16, 1U, quantum1); -- b->tin_quantum_band = max_t(u16, 1U, quantum2); -+ b->tin_quantum = max_t(u16, 1U, quantum); - - /* calculate next class's parameters */ - rate *= 7; - rate >>= 3; - -- quantum1 *= 3; -- quantum1 >>= 1; -- -- quantum2 *= 7; -- quantum2 >>= 3; -+ quantum *= 7; -+ quantum >>= 3; - } - - return 0; -@@ -2434,17 +2422,11 @@ static int cake_config_diffserv4(struct - cake_set_rate(&q->tins[3], rate >> 2, mtu, - us_to_ns(q->target), us_to_ns(q->interval)); - -- /* priority weights */ -- q->tins[0].tin_quantum_prio = quantum; -- q->tins[1].tin_quantum_prio = quantum >> 4; -- q->tins[2].tin_quantum_prio = quantum << 2; -- q->tins[3].tin_quantum_prio = quantum << 4; -- - /* bandwidth-sharing weights */ -- q->tins[0].tin_quantum_band = quantum; -- q->tins[1].tin_quantum_band = quantum >> 4; -- q->tins[2].tin_quantum_band = quantum >> 1; -- q->tins[3].tin_quantum_band = quantum >> 2; -+ q->tins[0].tin_quantum = quantum; -+ q->tins[1].tin_quantum = quantum >> 4; -+ q->tins[2].tin_quantum = quantum >> 1; -+ q->tins[3].tin_quantum = quantum >> 2; - - return 0; - } -@@ -2475,15 +2457,10 @@ static int cake_config_diffserv3(struct - cake_set_rate(&q->tins[2], rate >> 2, mtu, - us_to_ns(q->target), us_to_ns(q->interval)); - -- /* priority weights */ -- q->tins[0].tin_quantum_prio = quantum; -- q->tins[1].tin_quantum_prio = quantum >> 4; -- q->tins[2].tin_quantum_prio = quantum << 4; -- - /* bandwidth-sharing weights */ -- q->tins[0].tin_quantum_band = quantum; -- q->tins[1].tin_quantum_band = quantum >> 4; -- q->tins[2].tin_quantum_band = quantum >> 2; -+ q->tins[0].tin_quantum = quantum; -+ q->tins[1].tin_quantum = quantum >> 4; -+ q->tins[2].tin_quantum = quantum >> 2; - - return 0; - } diff --git a/target/linux/generic/backport-4.19/394-v5.4-sch_cake-Add-missing-NLA-policy-entry-TCA_CAKE_SPLIT.patch b/target/linux/generic/backport-4.19/394-v5.4-sch_cake-Add-missing-NLA-policy-entry-TCA_CAKE_SPLIT.patch deleted file mode 100644 index bc063dccca..0000000000 --- a/target/linux/generic/backport-4.19/394-v5.4-sch_cake-Add-missing-NLA-policy-entry-TCA_CAKE_SPLIT.patch +++ /dev/null @@ -1,30 +0,0 @@ -From b3c424eb6a1a3c485de64619418a471dee6ce849 Mon Sep 17 00:00:00 2001 -From: Victorien Molle <victorien.molle@wifirst.fr> -Date: Mon, 2 Dec 2019 15:11:38 +0100 -Subject: [PATCH] sch_cake: Add missing NLA policy entry TCA_CAKE_SPLIT_GSO -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This field has never been checked since introduction in mainline kernel - -Signed-off-by: Victorien Molle <victorien.molle@wifirst.fr> -Signed-off-by: Florent Fourcot <florent.fourcot@wifirst.fr> -Fixes: 2db6dc2662ba "sch_cake: Make gso-splitting configurable from userspace" -Acked-by: Toke Høiland-Jørgensen <toke@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> -Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> ---- - net/sched/sch_cake.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/net/sched/sch_cake.c -+++ b/net/sched/sch_cake.c -@@ -2204,6 +2204,7 @@ static const struct nla_policy cake_poli - [TCA_CAKE_MPU] = { .type = NLA_U32 }, - [TCA_CAKE_INGRESS] = { .type = NLA_U32 }, - [TCA_CAKE_ACK_FILTER] = { .type = NLA_U32 }, -+ [TCA_CAKE_SPLIT_GSO] = { .type = NLA_U32 }, - [TCA_CAKE_FWMARK] = { .type = NLA_U32 }, - }; - diff --git a/target/linux/generic/backport-4.19/395-v5.8-net-sch_cake-Take-advantage-of-skb-hash-where-appropriate.patch b/target/linux/generic/backport-4.19/395-v5.8-net-sch_cake-Take-advantage-of-skb-hash-where-appropriate.patch deleted file mode 100644 index a4981acdee..0000000000 --- a/target/linux/generic/backport-4.19/395-v5.8-net-sch_cake-Take-advantage-of-skb-hash-where-appropriate.patch +++ /dev/null @@ -1,170 +0,0 @@ -From b0c19ed6088ab41dd2a727b60594b7297c15d6ce Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= <toke@redhat.com> -Date: Fri, 29 May 2020 14:43:44 +0200 -Subject: [PATCH] sch_cake: Take advantage of skb->hash where appropriate -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -While the other fq-based qdiscs take advantage of skb->hash and doesn't -recompute it if it is already set, sch_cake does not. - -This was a deliberate choice because sch_cake hashes various parts of the -packet header to support its advanced flow isolation modes. However, -foregoing the use of skb->hash entirely loses a few important benefits: - -- When skb->hash is set by hardware, a few CPU cycles can be saved by not - hashing again in software. - -- Tunnel encapsulations will generally preserve the value of skb->hash from - before the encapsulation, which allows flow-based qdiscs to distinguish - between flows even though the outer packet header no longer has flow - information. - -It turns out that we can preserve these desirable properties in many cases, -while still supporting the advanced flow isolation properties of sch_cake. -This patch does so by reusing the skb->hash value as the flow_hash part of -the hashing procedure in cake_hash() only in the following conditions: - -- If the skb->hash is marked as covering the flow headers (skb->l4_hash is - set) - -AND - -- NAT header rewriting is either disabled, or did not change any values - used for hashing. The latter is important to match local-origin packets - such as those of a tunnel endpoint. - -The immediate motivation for fixing this was the recent patch to WireGuard -to preserve the skb->hash on encapsulation. As such, this is also what I -tested against; with this patch, added latency under load for competing -flows drops from ~8 ms to sub-1ms on an RRUL test over a WireGuard tunnel -going through a virtual link shaped to 1Gbps using sch_cake. This matches -the results we saw with a similar setup using sch_fq_codel when testing the -WireGuard patch. - -Fixes: 046f6fd5daef ("sched: Add Common Applications Kept Enhanced (cake) qdisc") -Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> -Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> ---- - net/sched/sch_cake.c | 65 ++++++++++++++++++++++++++++++++++---------- - 1 file changed, 51 insertions(+), 14 deletions(-) - ---- a/net/sched/sch_cake.c -+++ b/net/sched/sch_cake.c -@@ -584,26 +584,48 @@ static bool cobalt_should_drop(struct co - return drop; - } - --static void cake_update_flowkeys(struct flow_keys *keys, -+static bool cake_update_flowkeys(struct flow_keys *keys, - const struct sk_buff *skb) - { - #if IS_ENABLED(CONFIG_NF_CONNTRACK) - struct nf_conntrack_tuple tuple = {}; -- bool rev = !skb->_nfct; -+ bool rev = !skb->_nfct, upd = false; -+ __be32 ip; - - if (skb_protocol(skb, true) != htons(ETH_P_IP)) -- return; -+ return false; - - if (!nf_ct_get_tuple_skb(&tuple, skb)) -- return; -+ return false; - -- keys->addrs.v4addrs.src = rev ? tuple.dst.u3.ip : tuple.src.u3.ip; -- keys->addrs.v4addrs.dst = rev ? tuple.src.u3.ip : tuple.dst.u3.ip; -+ ip = rev ? tuple.dst.u3.ip : tuple.src.u3.ip; -+ if (ip != keys->addrs.v4addrs.src) { -+ keys->addrs.v4addrs.src = ip; -+ upd = true; -+ } -+ ip = rev ? tuple.src.u3.ip : tuple.dst.u3.ip; -+ if (ip != keys->addrs.v4addrs.dst) { -+ keys->addrs.v4addrs.dst = ip; -+ upd = true; -+ } - - if (keys->ports.ports) { -- keys->ports.src = rev ? tuple.dst.u.all : tuple.src.u.all; -- keys->ports.dst = rev ? tuple.src.u.all : tuple.dst.u.all; -+ __be16 port; -+ -+ port = rev ? tuple.dst.u.all : tuple.src.u.all; -+ if (port != keys->ports.src) { -+ keys->ports.src = port; -+ upd = true; -+ } -+ port = rev ? tuple.src.u.all : tuple.dst.u.all; -+ if (port != keys->ports.dst) { -+ port = keys->ports.dst; -+ upd = true; -+ } - } -+ return upd; -+#else -+ return false; - #endif - } - -@@ -624,23 +646,36 @@ static bool cake_ddst(int flow_mode) - static u32 cake_hash(struct cake_tin_data *q, const struct sk_buff *skb, - int flow_mode, u16 flow_override, u16 host_override) - { -+ bool hash_flows = (!flow_override && !!(flow_mode & CAKE_FLOW_FLOWS)); -+ bool hash_hosts = (!host_override && !!(flow_mode & CAKE_FLOW_HOSTS)); -+ bool nat_enabled = !!(flow_mode & CAKE_FLOW_NAT_FLAG); - u32 flow_hash = 0, srchost_hash = 0, dsthost_hash = 0; - u16 reduced_hash, srchost_idx, dsthost_idx; - struct flow_keys keys, host_keys; -+ bool use_skbhash = skb->l4_hash; - - if (unlikely(flow_mode == CAKE_FLOW_NONE)) - return 0; - -- /* If both overrides are set we can skip packet dissection entirely */ -- if ((flow_override || !(flow_mode & CAKE_FLOW_FLOWS)) && -- (host_override || !(flow_mode & CAKE_FLOW_HOSTS))) -+ /* If both overrides are set, or we can use the SKB hash and nat mode is -+ * disabled, we can skip packet dissection entirely. If nat mode is -+ * enabled there's another check below after doing the conntrack lookup. -+ */ -+ if ((!hash_flows || (use_skbhash && !nat_enabled)) && !hash_hosts) - goto skip_hash; - - skb_flow_dissect_flow_keys(skb, &keys, - FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL); - -- if (flow_mode & CAKE_FLOW_NAT_FLAG) -- cake_update_flowkeys(&keys, skb); -+ /* Don't use the SKB hash if we change the lookup keys from conntrack */ -+ if (nat_enabled && cake_update_flowkeys(&keys, skb)) -+ use_skbhash = false; -+ -+ /* If we can still use the SKB hash and don't need the host hash, we can -+ * skip the rest of the hashing procedure -+ */ -+ if (use_skbhash && !hash_hosts) -+ goto skip_hash; - - /* flow_hash_from_keys() sorts the addresses by value, so we have - * to preserve their order in a separate data structure to treat -@@ -679,12 +714,14 @@ static u32 cake_hash(struct cake_tin_dat - /* This *must* be after the above switch, since as a - * side-effect it sorts the src and dst addresses. - */ -- if (flow_mode & CAKE_FLOW_FLOWS) -+ if (hash_flows && !use_skbhash) - flow_hash = flow_hash_from_keys(&keys); - - skip_hash: - if (flow_override) - flow_hash = flow_override - 1; -+ else if (use_skbhash) -+ flow_hash = skb->hash; - if (host_override) { - dsthost_hash = host_override - 1; - srchost_hash = host_override - 1; diff --git a/target/linux/generic/backport-4.19/399-5.9-sch_cake-add-RFC-8622-LE-PHB-support-to-CAKE-diffser.patch b/target/linux/generic/backport-4.19/399-5.9-sch_cake-add-RFC-8622-LE-PHB-support-to-CAKE-diffser.patch deleted file mode 100644 index e171b4cec7..0000000000 --- a/target/linux/generic/backport-4.19/399-5.9-sch_cake-add-RFC-8622-LE-PHB-support-to-CAKE-diffser.patch +++ /dev/null @@ -1,57 +0,0 @@ -From b8392808eb3fc28e523e28cb258c81ca246deb9b Mon Sep 17 00:00:00 2001 -From: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> -Date: Thu, 25 Jun 2020 22:18:00 +0200 -Subject: [PATCH] sch_cake: add RFC 8622 LE PHB support to CAKE diffserv - handling -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Change tin mapping on diffserv3, 4 & 8 for LE PHB support, in essence -making LE a member of the Bulk tin. - -Bulk has the least priority and minimum of 1/16th total bandwidth in the -face of higher priority traffic. - -NB: Diffserv 3 & 4 swap tin 0 & 1 priorities from the default order as -found in diffserv8, in case anyone is wondering why it looks a bit odd. - -Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> -[ reword commit message slightly ] -Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com> -Signed-off-by: David S. Miller <davem@davemloft.net> ---- - net/sched/sch_cake.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/net/sched/sch_cake.c -+++ b/net/sched/sch_cake.c -@@ -312,8 +312,8 @@ static const u8 precedence[] = { - }; - - static const u8 diffserv8[] = { -- 2, 5, 1, 2, 4, 2, 2, 2, -- 0, 2, 1, 2, 1, 2, 1, 2, -+ 2, 0, 1, 2, 4, 2, 2, 2, -+ 1, 2, 1, 2, 1, 2, 1, 2, - 5, 2, 4, 2, 4, 2, 4, 2, - 3, 2, 3, 2, 3, 2, 3, 2, - 6, 2, 3, 2, 3, 2, 3, 2, -@@ -323,7 +323,7 @@ static const u8 diffserv8[] = { - }; - - static const u8 diffserv4[] = { -- 0, 2, 0, 0, 2, 0, 0, 0, -+ 0, 1, 0, 0, 2, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, - 2, 0, 2, 0, 2, 0, 2, 0, - 2, 0, 2, 0, 2, 0, 2, 0, -@@ -334,7 +334,7 @@ static const u8 diffserv4[] = { - }; - - static const u8 diffserv3[] = { -- 0, 0, 0, 0, 2, 0, 0, 0, -+ 0, 1, 0, 0, 2, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/target/linux/generic/backport-4.19/410-mtd-fix-calculating-partition-end-address.patch b/target/linux/generic/backport-4.19/410-mtd-fix-calculating-partition-end-address.patch deleted file mode 100644 index 4027bfd714..0000000000 --- a/target/linux/generic/backport-4.19/410-mtd-fix-calculating-partition-end-address.patch +++ /dev/null @@ -1,28 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> -Date: Mon, 9 Mar 2020 08:30:19 +0100 -Subject: [PATCH] mtd: fix calculating partition end address -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This fixes check for partitions that don't start at beginning of their -parents. Missing partition's offset in formula could result in forcing -read-only incorrectly. - -Fixes: 6750f61a13a0 ("mtd: improve calculating partition boundaries when checking for alignment") -Signed-off-by: RafaÅ‚ MiÅ‚ecki <rafal@milecki.pl> ---- - drivers/mtd/mtdpart.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/mtd/mtdpart.c -+++ b/drivers/mtd/mtdpart.c -@@ -538,7 +538,7 @@ static struct mtd_part *allocate_partiti - part->name); - } - -- tmp = part_absolute_offset(parent) + slave->mtd.size; -+ tmp = part_absolute_offset(parent) + slave->offset + slave->mtd.size; - remainder = do_div(tmp, wr_alignment); - if ((slave->mtd.flags & MTD_WRITEABLE) && remainder) { - slave->mtd.flags &= ~MTD_WRITEABLE; diff --git a/target/linux/generic/backport-4.19/450-v5.0-mtd-spinand-winbond-Add-support-for-W25N01GV.patch b/target/linux/generic/backport-4.19/450-v5.0-mtd-spinand-winbond-Add-support-for-W25N01GV.patch deleted file mode 100644 index 2024577b8f..0000000000 --- a/target/linux/generic/backport-4.19/450-v5.0-mtd-spinand-winbond-Add-support-for-W25N01GV.patch +++ /dev/null @@ -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)), - }; - - /** diff --git a/target/linux/generic/backport-4.19/451-v5.0-mtd-spinand-Add-initial-support-for-Toshiba-TC58CVG2.patch b/target/linux/generic/backport-4.19/451-v5.0-mtd-spinand-Add-initial-support-for-Toshiba-TC58CVG2.patch deleted file mode 100644 index 288fdbf267..0000000000 --- a/target/linux/generic/backport-4.19/451-v5.0-mtd-spinand-Add-initial-support-for-Toshiba-TC58CVG2.patch +++ /dev/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 -@@ -762,6 +762,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; - - /** diff --git a/target/linux/generic/backport-4.19/452-v5.0-mtd-spinand-add-support-for-GigaDevice-GD5FxGQ4xA.patch b/target/linux/generic/backport-4.19/452-v5.0-mtd-spinand-add-support-for-GigaDevice-GD5FxGQ4xA.patch deleted file mode 100644 index d3ded95ccb..0000000000 --- a/target/linux/generic/backport-4.19/452-v5.0-mtd-spinand-add-support-for-GigaDevice-GD5FxGQ4xA.patch +++ /dev/null @@ -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 -@@ -760,6 +760,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; diff --git a/target/linux/generic/backport-4.19/455-v5.1-mtd-spinand-Add-support-for-all-Toshiba-Memory-produ.patch b/target/linux/generic/backport-4.19/455-v5.1-mtd-spinand-Add-support-for-all-Toshiba-Memory-produ.patch deleted file mode 100644 index aad82dcf7a..0000000000 --- a/target/linux/generic/backport-4.19/455-v5.1-mtd-spinand-Add-support-for-all-Toshiba-Memory-produ.patch +++ /dev/null @@ -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) diff --git a/target/linux/generic/backport-4.19/456-v5.1-mtd-spinand-Add-support-for-GigaDevice-GD5F1GQ4UExxG.patch b/target/linux/generic/backport-4.19/456-v5.1-mtd-spinand-Add-support-for-GigaDevice-GD5F1GQ4UExxG.patch deleted file mode 100644 index 8e48debf43..0000000000 --- a/target/linux/generic/backport-4.19/456-v5.1-mtd-spinand-Add-support-for-GigaDevice-GD5F1GQ4UExxG.patch +++ /dev/null @@ -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) diff --git a/target/linux/generic/backport-4.19/460-v5.0-mtd-spi-nor-Add-support-for-mx25u12835f.patch b/target/linux/generic/backport-4.19/460-v5.0-mtd-spi-nor-Add-support-for-mx25u12835f.patch deleted file mode 100644 index 1bdf35b987..0000000000 --- a/target/linux/generic/backport-4.19/460-v5.0-mtd-spi-nor-Add-support-for-mx25u12835f.patch +++ /dev/null @@ -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) }, diff --git a/target/linux/generic/backport-4.19/460-v5.3-mtd-spinand-Define-macros-for-page-read-ops-with-thr.patch b/target/linux/generic/backport-4.19/460-v5.3-mtd-spinand-Define-macros-for-page-read-ops-with-thr.patch deleted file mode 100644 index c28ae1d797..0000000000 --- a/target/linux/generic/backport-4.19/460-v5.3-mtd-spinand-Define-macros-for-page-read-ops-with-thr.patch +++ /dev/null @@ -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), \ diff --git a/target/linux/generic/backport-4.19/461-v5.3-mtd-spinand-Add-support-for-two-byte-device-IDs.patch b/target/linux/generic/backport-4.19/461-v5.3-mtd-spinand-Add-support-for-two-byte-device-IDs.patch deleted file mode 100644 index ee81f97f4e..0000000000 --- a/target/linux/generic/backport-4.19/461-v5.3-mtd-spinand-Add-support-for-two-byte-device-IDs.patch +++ /dev/null @@ -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 -@@ -851,7 +851,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); diff --git a/target/linux/generic/backport-4.19/462-v5.3-mtd-spinand-Add-support-for-GigaDevice-GD5F1GQ4UFxxG.patch b/target/linux/generic/backport-4.19/462-v5.3-mtd-spinand-Add-support-for-GigaDevice-GD5F1GQ4UFxxG.patch deleted file mode 100644 index 06d87ba5e0..0000000000 --- a/target/linux/generic/backport-4.19/462-v5.3-mtd-spinand-Add-support-for-GigaDevice-GD5F1GQ4UFxxG.patch +++ /dev/null @@ -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; - diff --git a/target/linux/generic/backport-4.19/463-v5.3-mtd-spinand-Add-initial-support-for-Paragon-PN26G0xA.patch b/target/linux/generic/backport-4.19/463-v5.3-mtd-spinand-Add-initial-support-for-Paragon-PN26G0xA.patch deleted file mode 100644 index d30abdc143..0000000000 --- a/target/linux/generic/backport-4.19/463-v5.3-mtd-spinand-Add-initial-support-for-Paragon-PN26G0xA.patch +++ /dev/null @@ -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 -@@ -763,6 +763,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; - diff --git a/target/linux/generic/backport-4.19/464-v5.6-mtd-spi-nor-Add-4B_OPCODES-flag-to-w25q256.patch b/target/linux/generic/backport-4.19/464-v5.6-mtd-spi-nor-Add-4B_OPCODES-flag-to-w25q256.patch deleted file mode 100644 index db9f379c81..0000000000 --- a/target/linux/generic/backport-4.19/464-v5.6-mtd-spi-nor-Add-4B_OPCODES-flag-to-w25q256.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 10050a02f7d508fa88f70fcfceefbacd13488ca7 Mon Sep 17 00:00:00 2001 -From: Robert Marko <robimarko@gmail.com> -Date: Mon, 23 Dec 2019 17:05:49 +0200 -Subject: [PATCH] mtd: spi-nor: Add 4B_OPCODES flag to w25q256 - -The w25q256 supports 4-byte opcodes so lets add the flag. -Tested on OpenWrt under 4.19.82 kernel on 8devices Habanero. - -Signed-off-by: Robert Marko <robimarko@gmail.com> -Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com> ---- - drivers/mtd/spi-nor/spi-nor.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/drivers/mtd/spi-nor/spi-nor.c -+++ b/drivers/mtd/spi-nor/spi-nor.c -@@ -1244,7 +1244,9 @@ static const struct flash_info spi_nor_i - { "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) }, - { "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) }, - { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) }, -- { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+ { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, -+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | -+ SPI_NOR_4B_OPCODES) }, - { "w25m512jv", INFO(0xef7119, 0, 64 * 1024, 1024, - SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_DUAL_READ) }, - diff --git a/target/linux/generic/backport-4.19/499-v4.22-iio-add-IIO_MASSCONCENTRATION-channel-type.patch b/target/linux/generic/backport-4.19/499-v4.22-iio-add-IIO_MASSCONCENTRATION-channel-type.patch deleted file mode 100644 index bceb735146..0000000000 --- a/target/linux/generic/backport-4.19/499-v4.22-iio-add-IIO_MASSCONCENTRATION-channel-type.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 17abc9ec68b73ddeb262a507a62421016b9c54d5 Mon Sep 17 00:00:00 2001 -From: Tomasz Duszynski <tduszyns@gmail.com> -Date: Fri, 14 Dec 2018 19:28:01 +0100 -Subject: [PATCH] iio: add IIO_MASSCONCENTRATION channel type - -Measuring particulate matter in ug / m3 (micro-grams per cubic meter) -is de facto standard. Existing air quality sensors usually follow -this convention and are capable of returning measurements using -this unit. - -IIO currently does not offer suitable channel type for this -type of measurements hence this patch adds this. - -In addition, extra modifiers are introduced used for distinguishing -between fine pm1, pm2p5 and coarse pm4, pm10 particle measurements, i.e -IIO_MOD_PM1, IIO_MOD_PM25 and IIO_MOD_PM4, IIO_MOD_PM10. - -pmX consists of particles with aerodynamic diameter less or equal to -X micrometers. - -Signed-off-by: Tomasz Duszynski <tduszyns@gmail.com> -Acked-by: Matt Ranostay <matt.ranostay@konsulko.com> -Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> ---- - Documentation/ABI/testing/sysfs-bus-iio | 17 ++++++++++++++++- - drivers/iio/industrialio-core.c | 5 +++++ - include/uapi/linux/iio/types.h | 5 +++++ - tools/iio/iio_event_monitor.c | 10 ++++++++++ - 4 files changed, 36 insertions(+), 1 deletion(-) - ---- a/Documentation/ABI/testing/sysfs-bus-iio -+++ b/Documentation/ABI/testing/sysfs-bus-iio -@@ -1684,4 +1684,19 @@ KernelVersion: 4.18 - Contact: linux-iio@vger.kernel.org - Description: - Raw (unscaled) phase difference reading from channel Y -- that can be processed to radians. -\ No newline at end of file -+ that can be processed to radians. -+ -+What: /sys/bus/iio/devices/iio:deviceX/in_massconcentration_pm1_input -+What: /sys/bus/iio/devices/iio:deviceX/in_massconcentrationY_pm1_input -+What: /sys/bus/iio/devices/iio:deviceX/in_massconcentration_pm2p5_input -+What: /sys/bus/iio/devices/iio:deviceX/in_massconcentrationY_pm2p5_input -+What: /sys/bus/iio/devices/iio:deviceX/in_massconcentration_pm4_input -+What: /sys/bus/iio/devices/iio:deviceX/in_massconcentrationY_pm4_input -+What: /sys/bus/iio/devices/iio:deviceX/in_massconcentration_pm10_input -+What: /sys/bus/iio/devices/iio:deviceX/in_massconcentrationY_pm10_input -+KernelVersion: 4.22 -+Contact: linux-iio@vger.kernel.org -+Description: -+ Mass concentration reading of particulate matter in ug / m3. -+ pmX consists of particles with aerodynamic diameter less or -+ equal to X micrometers. ---- a/drivers/iio/industrialio-core.c -+++ b/drivers/iio/industrialio-core.c -@@ -87,6 +87,7 @@ static const char * const iio_chan_type_ - [IIO_GRAVITY] = "gravity", - [IIO_POSITIONRELATIVE] = "positionrelative", - [IIO_PHASE] = "phase", -+ [IIO_MASSCONCENTRATION] = "massconcentration", - }; - - static const char * const iio_modifier_names[] = { -@@ -127,6 +128,10 @@ static const char * const iio_modifier_n - [IIO_MOD_Q] = "q", - [IIO_MOD_CO2] = "co2", - [IIO_MOD_VOC] = "voc", -+ [IIO_MOD_PM1] = "pm1", -+ [IIO_MOD_PM2P5] = "pm2p5", -+ [IIO_MOD_PM4] = "pm4", -+ [IIO_MOD_PM10] = "pm10", - }; - - /* relies on pairs of these shared then separate */ ---- a/include/uapi/linux/iio/types.h -+++ b/include/uapi/linux/iio/types.h -@@ -46,6 +46,7 @@ enum iio_chan_type { - IIO_GRAVITY, - IIO_POSITIONRELATIVE, - IIO_PHASE, -+ IIO_MASSCONCENTRATION, - }; - - enum iio_modifier { -@@ -87,6 +88,10 @@ enum iio_modifier { - IIO_MOD_VOC, - IIO_MOD_LIGHT_UV, - IIO_MOD_LIGHT_DUV, -+ IIO_MOD_PM1, -+ IIO_MOD_PM2P5, -+ IIO_MOD_PM4, -+ IIO_MOD_PM10, - }; - - enum iio_event_type { ---- a/tools/iio/iio_event_monitor.c -+++ b/tools/iio/iio_event_monitor.c -@@ -60,6 +60,7 @@ static const char * const iio_chan_type_ - [IIO_GRAVITY] = "gravity", - [IIO_POSITIONRELATIVE] = "positionrelative", - [IIO_PHASE] = "phase", -+ [IIO_MASSCONCENTRATION] = "massconcentration", - }; - - static const char * const iio_ev_type_text[] = { -@@ -115,6 +116,10 @@ static const char * const iio_modifier_n - [IIO_MOD_Q] = "q", - [IIO_MOD_CO2] = "co2", - [IIO_MOD_VOC] = "voc", -+ [IIO_MOD_PM1] = "pm1", -+ [IIO_MOD_PM2P5] = "pm2p5", -+ [IIO_MOD_PM4] = "pm4", -+ [IIO_MOD_PM10] = "pm10", - }; - - static bool event_is_known(struct iio_event_data *event) -@@ -156,6 +161,7 @@ static bool event_is_known(struct iio_ev - case IIO_GRAVITY: - case IIO_POSITIONRELATIVE: - case IIO_PHASE: -+ case IIO_MASSCONCENTRATION: - break; - default: - return false; -@@ -200,6 +206,10 @@ static bool event_is_known(struct iio_ev - case IIO_MOD_Q: - case IIO_MOD_CO2: - case IIO_MOD_VOC: -+ case IIO_MOD_PM1: -+ case IIO_MOD_PM2P5: -+ case IIO_MOD_PM4: -+ case IIO_MOD_PM10: - break; - default: - return false; diff --git a/target/linux/generic/backport-4.19/500-v5.1-iio-chemical-add-support-for-Sensirion-SPS30-sensor.patch b/target/linux/generic/backport-4.19/500-v5.1-iio-chemical-add-support-for-Sensirion-SPS30-sensor.patch deleted file mode 100644 index d30c7c3cc1..0000000000 --- a/target/linux/generic/backport-4.19/500-v5.1-iio-chemical-add-support-for-Sensirion-SPS30-sensor.patch +++ /dev/null @@ -1,454 +0,0 @@ -From 232e0f6ddeaee104d64675fe7d0cc142cf955f35 Mon Sep 17 00:00:00 2001 -From: Tomasz Duszynski <tduszyns@gmail.com> -Date: Fri, 14 Dec 2018 19:28:02 +0100 -Subject: [PATCH] iio: chemical: add support for Sensirion SPS30 sensor - -Add support for Sensirion SPS30 particulate matter sensor. - -Signed-off-by: Tomasz Duszynski <tduszyns@gmail.com> -Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> ---- - drivers/iio/chemical/Kconfig | 11 + - drivers/iio/chemical/Makefile | 1 + - drivers/iio/chemical/sps30.c | 407 ++++++++++++++++++++++++++++++++++ - 3 files changed, 419 insertions(+) - create mode 100644 drivers/iio/chemical/sps30.c - ---- a/drivers/iio/chemical/Kconfig -+++ b/drivers/iio/chemical/Kconfig -@@ -61,6 +61,17 @@ config IAQCORE - iAQ-Core Continuous/Pulsed VOC (Volatile Organic Compounds) - sensors - -+config SPS30 -+ tristate "SPS30 particulate matter sensor" -+ depends on I2C -+ select CRC8 -+ help -+ Say Y here to build support for the Sensirion SPS30 particulate -+ matter sensor. -+ -+ To compile this driver as a module, choose M here: the module will -+ be called sps30. -+ - config VZ89X - tristate "SGX Sensortech MiCS VZ89X VOC sensor" - depends on I2C ---- a/drivers/iio/chemical/Makefile -+++ b/drivers/iio/chemical/Makefile -@@ -9,4 +9,5 @@ obj-$(CONFIG_BME680_I2C) += bme680_i2c.o - obj-$(CONFIG_BME680_SPI) += bme680_spi.o - obj-$(CONFIG_CCS811) += ccs811.o - obj-$(CONFIG_IAQCORE) += ams-iaq-core.o -+obj-$(CONFIG_SPS30) += sps30.o - obj-$(CONFIG_VZ89X) += vz89x.o ---- /dev/null -+++ b/drivers/iio/chemical/sps30.c -@@ -0,0 +1,407 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Sensirion SPS30 particulate matter sensor driver -+ * -+ * Copyright (c) Tomasz Duszynski <tduszyns@gmail.com> -+ * -+ * I2C slave address: 0x69 -+ * -+ * TODO: -+ * - support for turning on fan cleaning -+ * - support for reading/setting auto cleaning interval -+ */ -+ -+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -+ -+#include <asm/unaligned.h> -+#include <linux/crc8.h> -+#include <linux/delay.h> -+#include <linux/i2c.h> -+#include <linux/iio/buffer.h> -+#include <linux/iio/iio.h> -+#include <linux/iio/sysfs.h> -+#include <linux/iio/trigger_consumer.h> -+#include <linux/iio/triggered_buffer.h> -+#include <linux/module.h> -+ -+#define SPS30_CRC8_POLYNOMIAL 0x31 -+/* max number of bytes needed to store PM measurements or serial string */ -+#define SPS30_MAX_READ_SIZE 48 -+/* sensor measures reliably up to 3000 ug / m3 */ -+#define SPS30_MAX_PM 3000 -+ -+/* SPS30 commands */ -+#define SPS30_START_MEAS 0x0010 -+#define SPS30_STOP_MEAS 0x0104 -+#define SPS30_RESET 0xd304 -+#define SPS30_READ_DATA_READY_FLAG 0x0202 -+#define SPS30_READ_DATA 0x0300 -+#define SPS30_READ_SERIAL 0xd033 -+ -+enum { -+ PM1, -+ PM2P5, -+ PM4, -+ PM10, -+}; -+ -+struct sps30_state { -+ struct i2c_client *client; -+ /* -+ * Guards against concurrent access to sensor registers. -+ * Must be held whenever sequence of commands is to be executed. -+ */ -+ struct mutex lock; -+}; -+ -+DECLARE_CRC8_TABLE(sps30_crc8_table); -+ -+static int sps30_write_then_read(struct sps30_state *state, u8 *txbuf, -+ int txsize, u8 *rxbuf, int rxsize) -+{ -+ int ret; -+ -+ /* -+ * Sensor does not support repeated start so instead of -+ * sending two i2c messages in a row we just send one by one. -+ */ -+ ret = i2c_master_send(state->client, txbuf, txsize); -+ if (ret != txsize) -+ return ret < 0 ? ret : -EIO; -+ -+ if (!rxbuf) -+ return 0; -+ -+ ret = i2c_master_recv(state->client, rxbuf, rxsize); -+ if (ret != rxsize) -+ return ret < 0 ? ret : -EIO; -+ -+ return 0; -+} -+ -+static int sps30_do_cmd(struct sps30_state *state, u16 cmd, u8 *data, int size) -+{ -+ /* -+ * Internally sensor stores measurements in a following manner: -+ * -+ * PM1: upper two bytes, crc8, lower two bytes, crc8 -+ * PM2P5: upper two bytes, crc8, lower two bytes, crc8 -+ * PM4: upper two bytes, crc8, lower two bytes, crc8 -+ * PM10: upper two bytes, crc8, lower two bytes, crc8 -+ * -+ * What follows next are number concentration measurements and -+ * typical particle size measurement which we omit. -+ */ -+ u8 buf[SPS30_MAX_READ_SIZE] = { cmd >> 8, cmd }; -+ int i, ret = 0; -+ -+ switch (cmd) { -+ case SPS30_START_MEAS: -+ buf[2] = 0x03; -+ buf[3] = 0x00; -+ buf[4] = crc8(sps30_crc8_table, &buf[2], 2, CRC8_INIT_VALUE); -+ ret = sps30_write_then_read(state, buf, 5, NULL, 0); -+ break; -+ case SPS30_STOP_MEAS: -+ case SPS30_RESET: -+ ret = sps30_write_then_read(state, buf, 2, NULL, 0); -+ break; -+ case SPS30_READ_DATA_READY_FLAG: -+ case SPS30_READ_DATA: -+ case SPS30_READ_SERIAL: -+ /* every two data bytes are checksummed */ -+ size += size / 2; -+ ret = sps30_write_then_read(state, buf, 2, buf, size); -+ break; -+ } -+ -+ if (ret) -+ return ret; -+ -+ /* validate received data and strip off crc bytes */ -+ for (i = 0; i < size; i += 3) { -+ u8 crc = crc8(sps30_crc8_table, &buf[i], 2, CRC8_INIT_VALUE); -+ -+ if (crc != buf[i + 2]) { -+ dev_err(&state->client->dev, -+ "data integrity check failed\n"); -+ return -EIO; -+ } -+ -+ *data++ = buf[i]; -+ *data++ = buf[i + 1]; -+ } -+ -+ return 0; -+} -+ -+static s32 sps30_float_to_int_clamped(const u8 *fp) -+{ -+ int val = get_unaligned_be32(fp); -+ int mantissa = val & GENMASK(22, 0); -+ /* this is fine since passed float is always non-negative */ -+ int exp = val >> 23; -+ int fraction, shift; -+ -+ /* special case 0 */ -+ if (!exp && !mantissa) -+ return 0; -+ -+ exp -= 127; -+ if (exp < 0) { -+ /* return values ranging from 1 to 99 */ -+ return ((((1 << 23) + mantissa) * 100) >> 23) >> (-exp); -+ } -+ -+ /* return values ranging from 100 to 300000 */ -+ shift = 23 - exp; -+ val = (1 << exp) + (mantissa >> shift); -+ if (val >= SPS30_MAX_PM) -+ return SPS30_MAX_PM * 100; -+ -+ fraction = mantissa & GENMASK(shift - 1, 0); -+ -+ return val * 100 + ((fraction * 100) >> shift); -+} -+ -+static int sps30_do_meas(struct sps30_state *state, s32 *data, int size) -+{ -+ int i, ret, tries = 5; -+ u8 tmp[16]; -+ -+ while (tries--) { -+ ret = sps30_do_cmd(state, SPS30_READ_DATA_READY_FLAG, tmp, 2); -+ if (ret) -+ return -EIO; -+ -+ /* new measurements ready to be read */ -+ if (tmp[1] == 1) -+ break; -+ -+ msleep_interruptible(300); -+ } -+ -+ if (!tries) -+ return -ETIMEDOUT; -+ -+ ret = sps30_do_cmd(state, SPS30_READ_DATA, tmp, sizeof(int) * size); -+ if (ret) -+ return ret; -+ -+ for (i = 0; i < size; i++) -+ data[i] = sps30_float_to_int_clamped(&tmp[4 * i]); -+ -+ return 0; -+} -+ -+static irqreturn_t sps30_trigger_handler(int irq, void *p) -+{ -+ struct iio_poll_func *pf = p; -+ struct iio_dev *indio_dev = pf->indio_dev; -+ struct sps30_state *state = iio_priv(indio_dev); -+ int ret; -+ s32 data[4 + 2]; /* PM1, PM2P5, PM4, PM10, timestamp */ -+ -+ mutex_lock(&state->lock); -+ ret = sps30_do_meas(state, data, 4); -+ mutex_unlock(&state->lock); -+ if (ret) -+ goto err; -+ -+ iio_push_to_buffers_with_timestamp(indio_dev, data, -+ iio_get_time_ns(indio_dev)); -+err: -+ iio_trigger_notify_done(indio_dev->trig); -+ -+ return IRQ_HANDLED; -+} -+ -+static int sps30_read_raw(struct iio_dev *indio_dev, -+ struct iio_chan_spec const *chan, -+ int *val, int *val2, long mask) -+{ -+ struct sps30_state *state = iio_priv(indio_dev); -+ int data[4], ret = -EINVAL; -+ -+ switch (mask) { -+ case IIO_CHAN_INFO_PROCESSED: -+ switch (chan->type) { -+ case IIO_MASSCONCENTRATION: -+ mutex_lock(&state->lock); -+ /* read up to the number of bytes actually needed */ -+ switch (chan->channel2) { -+ case IIO_MOD_PM1: -+ ret = sps30_do_meas(state, data, 1); -+ break; -+ case IIO_MOD_PM2P5: -+ ret = sps30_do_meas(state, data, 2); -+ break; -+ case IIO_MOD_PM4: -+ ret = sps30_do_meas(state, data, 3); -+ break; -+ case IIO_MOD_PM10: -+ ret = sps30_do_meas(state, data, 4); -+ break; -+ } -+ mutex_unlock(&state->lock); -+ if (ret) -+ return ret; -+ -+ *val = data[chan->address] / 100; -+ *val2 = (data[chan->address] % 100) * 10000; -+ -+ return IIO_VAL_INT_PLUS_MICRO; -+ default: -+ return -EINVAL; -+ } -+ case IIO_CHAN_INFO_SCALE: -+ switch (chan->type) { -+ case IIO_MASSCONCENTRATION: -+ switch (chan->channel2) { -+ case IIO_MOD_PM1: -+ case IIO_MOD_PM2P5: -+ case IIO_MOD_PM4: -+ case IIO_MOD_PM10: -+ *val = 0; -+ *val2 = 10000; -+ -+ return IIO_VAL_INT_PLUS_MICRO; -+ } -+ default: -+ return -EINVAL; -+ } -+ } -+ -+ return -EINVAL; -+} -+ -+static const struct iio_info sps30_info = { -+ .read_raw = sps30_read_raw, -+}; -+ -+#define SPS30_CHAN(_index, _mod) { \ -+ .type = IIO_MASSCONCENTRATION, \ -+ .modified = 1, \ -+ .channel2 = IIO_MOD_ ## _mod, \ -+ .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \ -+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ -+ .address = _mod, \ -+ .scan_index = _index, \ -+ .scan_type = { \ -+ .sign = 'u', \ -+ .realbits = 19, \ -+ .storagebits = 32, \ -+ .endianness = IIO_CPU, \ -+ }, \ -+} -+ -+static const struct iio_chan_spec sps30_channels[] = { -+ SPS30_CHAN(0, PM1), -+ SPS30_CHAN(1, PM2P5), -+ SPS30_CHAN(2, PM4), -+ SPS30_CHAN(3, PM10), -+ IIO_CHAN_SOFT_TIMESTAMP(4), -+}; -+ -+static void sps30_stop_meas(void *data) -+{ -+ struct sps30_state *state = data; -+ -+ sps30_do_cmd(state, SPS30_STOP_MEAS, NULL, 0); -+} -+ -+static const unsigned long sps30_scan_masks[] = { 0x0f, 0x00 }; -+ -+static int sps30_probe(struct i2c_client *client) -+{ -+ struct iio_dev *indio_dev; -+ struct sps30_state *state; -+ u8 buf[32]; -+ int ret; -+ -+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) -+ return -EOPNOTSUPP; -+ -+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*state)); -+ if (!indio_dev) -+ return -ENOMEM; -+ -+ state = iio_priv(indio_dev); -+ i2c_set_clientdata(client, indio_dev); -+ state->client = client; -+ indio_dev->dev.parent = &client->dev; -+ indio_dev->info = &sps30_info; -+ indio_dev->name = client->name; -+ indio_dev->channels = sps30_channels; -+ indio_dev->num_channels = ARRAY_SIZE(sps30_channels); -+ indio_dev->modes = INDIO_DIRECT_MODE; -+ indio_dev->available_scan_masks = sps30_scan_masks; -+ -+ mutex_init(&state->lock); -+ crc8_populate_msb(sps30_crc8_table, SPS30_CRC8_POLYNOMIAL); -+ -+ ret = sps30_do_cmd(state, SPS30_RESET, NULL, 0); -+ if (ret) { -+ dev_err(&client->dev, "failed to reset device\n"); -+ return ret; -+ } -+ msleep(300); -+ /* -+ * Power-on-reset causes sensor to produce some glitch on i2c bus and -+ * some controllers end up in error state. Recover simply by placing -+ * some data on the bus, for example STOP_MEAS command, which -+ * is NOP in this case. -+ */ -+ sps30_do_cmd(state, SPS30_STOP_MEAS, NULL, 0); -+ -+ ret = sps30_do_cmd(state, SPS30_READ_SERIAL, buf, sizeof(buf)); -+ if (ret) { -+ dev_err(&client->dev, "failed to read serial number\n"); -+ return ret; -+ } -+ /* returned serial number is already NUL terminated */ -+ dev_info(&client->dev, "serial number: %s\n", buf); -+ -+ ret = sps30_do_cmd(state, SPS30_START_MEAS, NULL, 0); -+ if (ret) { -+ dev_err(&client->dev, "failed to start measurement\n"); -+ return ret; -+ } -+ -+ ret = devm_add_action_or_reset(&client->dev, sps30_stop_meas, state); -+ if (ret) -+ return ret; -+ -+ ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev, NULL, -+ sps30_trigger_handler, NULL); -+ if (ret) -+ return ret; -+ -+ return devm_iio_device_register(&client->dev, indio_dev); -+} -+ -+static const struct i2c_device_id sps30_id[] = { -+ { "sps30" }, -+ { } -+}; -+MODULE_DEVICE_TABLE(i2c, sps30_id); -+ -+static const struct of_device_id sps30_of_match[] = { -+ { .compatible = "sensirion,sps30" }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, sps30_of_match); -+ -+static struct i2c_driver sps30_driver = { -+ .driver = { -+ .name = "sps30", -+ .of_match_table = sps30_of_match, -+ }, -+ .id_table = sps30_id, -+ .probe_new = sps30_probe, -+}; -+module_i2c_driver(sps30_driver); -+ -+MODULE_AUTHOR("Tomasz Duszynski <tduszyns@gmail.com>"); -+MODULE_DESCRIPTION("Sensirion SPS30 particulate matter sensor driver"); -+MODULE_LICENSE("GPL v2"); diff --git a/target/linux/generic/backport-4.19/501-v5.1-iio-chemical-sps30-add-support-for-self-cleaning.patch b/target/linux/generic/backport-4.19/501-v5.1-iio-chemical-sps30-add-support-for-self-cleaning.patch deleted file mode 100644 index 7054fb0313..0000000000 --- a/target/linux/generic/backport-4.19/501-v5.1-iio-chemical-sps30-add-support-for-self-cleaning.patch +++ /dev/null @@ -1,100 +0,0 @@ -From c546d49656143855093c7b7fde60866e6e23a69d Mon Sep 17 00:00:00 2001 -From: Tomasz Duszynski <tduszyns@gmail.com> -Date: Tue, 18 Dec 2018 21:28:09 +0100 -Subject: [PATCH] iio: chemical: sps30: add support for self cleaning - -Self cleaning is especially useful in cases where sensor undergoes -frequent power on/off cycles. In such scenarios it is recommended to -turn self cleaning at least once per week in order to maintain reliable -measurements. - -Self cleaning is activated by writing 1 to a dedicated attribute. -Internal fan accelerates to its maximum speed and keeps spinning -for about 10 seconds blowing out accumulated dust. - -Signed-off-by: Tomasz Duszynski <tduszyns@gmail.com> -Tested-by: Andreas Brauchli <andreas.brauchli@sensirion.com> -Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> ---- - Documentation/ABI/testing/sysfs-bus-iio-sps30 | 8 +++++ - drivers/iio/chemical/sps30.c | 35 ++++++++++++++++++- - 2 files changed, 42 insertions(+), 1 deletion(-) - create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-sps30 - ---- /dev/null -+++ b/Documentation/ABI/testing/sysfs-bus-iio-sps30 -@@ -0,0 +1,8 @@ -+What: /sys/bus/iio/devices/iio:deviceX/start_cleaning -+Date: December 2018 -+KernelVersion: 4.22 -+Contact: linux-iio@vger.kernel.org -+Description: -+ Writing 1 starts sensor self cleaning. Internal fan accelerates -+ to its maximum speed and keeps spinning for about 10 seconds in -+ order to blow out accumulated dust. ---- a/drivers/iio/chemical/sps30.c -+++ b/drivers/iio/chemical/sps30.c -@@ -7,7 +7,6 @@ - * I2C slave address: 0x69 - * - * TODO: -- * - support for turning on fan cleaning - * - support for reading/setting auto cleaning interval - */ - -@@ -37,6 +36,7 @@ - #define SPS30_READ_DATA_READY_FLAG 0x0202 - #define SPS30_READ_DATA 0x0300 - #define SPS30_READ_SERIAL 0xd033 -+#define SPS30_START_FAN_CLEANING 0x5607 - - enum { - PM1, -@@ -104,6 +104,7 @@ static int sps30_do_cmd(struct sps30_sta - break; - case SPS30_STOP_MEAS: - case SPS30_RESET: -+ case SPS30_START_FAN_CLEANING: - ret = sps30_write_then_read(state, buf, 2, NULL, 0); - break; - case SPS30_READ_DATA_READY_FLAG: -@@ -275,7 +276,39 @@ static int sps30_read_raw(struct iio_dev - return -EINVAL; - } - -+static ssize_t start_cleaning_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t len) -+{ -+ struct iio_dev *indio_dev = dev_to_iio_dev(dev); -+ struct sps30_state *state = iio_priv(indio_dev); -+ int val, ret; -+ -+ if (kstrtoint(buf, 0, &val) || val != 1) -+ return -EINVAL; -+ -+ mutex_lock(&state->lock); -+ ret = sps30_do_cmd(state, SPS30_START_FAN_CLEANING, NULL, 0); -+ mutex_unlock(&state->lock); -+ if (ret) -+ return ret; -+ -+ return len; -+} -+ -+static IIO_DEVICE_ATTR_WO(start_cleaning, 0); -+ -+static struct attribute *sps30_attrs[] = { -+ &iio_dev_attr_start_cleaning.dev_attr.attr, -+ NULL -+}; -+ -+static const struct attribute_group sps30_attr_group = { -+ .attrs = sps30_attrs, -+}; -+ - static const struct iio_info sps30_info = { -+ .attrs = &sps30_attr_group, - .read_raw = sps30_read_raw, - }; - diff --git a/target/linux/generic/backport-4.19/502-v5.1-iio-chemical-sps30-allow-changing-self-cleaning-peri.patch b/target/linux/generic/backport-4.19/502-v5.1-iio-chemical-sps30-allow-changing-self-cleaning-peri.patch deleted file mode 100644 index 3a1335ba44..0000000000 --- a/target/linux/generic/backport-4.19/502-v5.1-iio-chemical-sps30-allow-changing-self-cleaning-peri.patch +++ /dev/null @@ -1,293 +0,0 @@ -From 62129a0849d27cc94ced832bcf9dcde283dcbe08 Mon Sep 17 00:00:00 2001 -From: Tomasz Duszynski <tduszyns@gmail.com> -Date: Tue, 15 Jan 2019 20:00:06 +0100 -Subject: [PATCH] iio: chemical: sps30: allow changing self cleaning period - -Sensor can periodically trigger self cleaning. Period can be changed by -writing a new value to a dedicated attribute. Upon attribute read -current period gets returned. - -Signed-off-by: Tomasz Duszynski <tduszyns@gmail.com> -Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> ---- - Documentation/ABI/testing/sysfs-bus-iio-sps30 | 20 +++ - drivers/iio/chemical/sps30.c | 143 +++++++++++++++--- - 2 files changed, 145 insertions(+), 18 deletions(-) - ---- a/Documentation/ABI/testing/sysfs-bus-iio-sps30 -+++ b/Documentation/ABI/testing/sysfs-bus-iio-sps30 -@@ -6,3 +6,23 @@ Description: - Writing 1 starts sensor self cleaning. Internal fan accelerates - to its maximum speed and keeps spinning for about 10 seconds in - order to blow out accumulated dust. -+ -+What: /sys/bus/iio/devices/iio:deviceX/cleaning_period -+Date: January 2019 -+KernelVersion: 5.1 -+Contact: linux-iio@vger.kernel.org -+Description: -+ Sensor is capable of triggering self cleaning periodically. -+ Period can be changed by writing a new value here. Upon reading -+ the current one is returned. Units are seconds. -+ -+ Writing 0 disables periodical self cleaning entirely. -+ -+What: /sys/bus/iio/devices/iio:deviceX/cleaning_period_available -+Date: January 2019 -+KernelVersion: 5.1 -+Contact: linux-iio@vger.kernel.org -+Description: -+ The range of available values in seconds represented as the -+ minimum value, the step and the maximum value, all enclosed in -+ square brackets. ---- a/drivers/iio/chemical/sps30.c -+++ b/drivers/iio/chemical/sps30.c -@@ -5,9 +5,6 @@ - * Copyright (c) Tomasz Duszynski <tduszyns@gmail.com> - * - * I2C slave address: 0x69 -- * -- * TODO: -- * - support for reading/setting auto cleaning interval - */ - - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -@@ -21,6 +18,7 @@ - #include <linux/iio/sysfs.h> - #include <linux/iio/trigger_consumer.h> - #include <linux/iio/triggered_buffer.h> -+#include <linux/kernel.h> - #include <linux/module.h> - - #define SPS30_CRC8_POLYNOMIAL 0x31 -@@ -28,6 +26,9 @@ - #define SPS30_MAX_READ_SIZE 48 - /* sensor measures reliably up to 3000 ug / m3 */ - #define SPS30_MAX_PM 3000 -+/* minimum and maximum self cleaning periods in seconds */ -+#define SPS30_AUTO_CLEANING_PERIOD_MIN 0 -+#define SPS30_AUTO_CLEANING_PERIOD_MAX 604800 - - /* SPS30 commands */ - #define SPS30_START_MEAS 0x0010 -@@ -37,6 +38,9 @@ - #define SPS30_READ_DATA 0x0300 - #define SPS30_READ_SERIAL 0xd033 - #define SPS30_START_FAN_CLEANING 0x5607 -+#define SPS30_AUTO_CLEANING_PERIOD 0x8004 -+/* not a sensor command per se, used only to distinguish write from read */ -+#define SPS30_READ_AUTO_CLEANING_PERIOD 0x8005 - - enum { - PM1, -@@ -45,6 +49,11 @@ enum { - PM10, - }; - -+enum { -+ RESET, -+ MEASURING, -+}; -+ - struct sps30_state { - struct i2c_client *client; - /* -@@ -52,6 +61,7 @@ struct sps30_state { - * Must be held whenever sequence of commands is to be executed. - */ - struct mutex lock; -+ int state; - }; - - DECLARE_CRC8_TABLE(sps30_crc8_table); -@@ -107,6 +117,9 @@ static int sps30_do_cmd(struct sps30_sta - case SPS30_START_FAN_CLEANING: - ret = sps30_write_then_read(state, buf, 2, NULL, 0); - break; -+ case SPS30_READ_AUTO_CLEANING_PERIOD: -+ buf[0] = SPS30_AUTO_CLEANING_PERIOD >> 8; -+ buf[1] = (u8)SPS30_AUTO_CLEANING_PERIOD; - case SPS30_READ_DATA_READY_FLAG: - case SPS30_READ_DATA: - case SPS30_READ_SERIAL: -@@ -114,6 +127,15 @@ static int sps30_do_cmd(struct sps30_sta - size += size / 2; - ret = sps30_write_then_read(state, buf, 2, buf, size); - break; -+ case SPS30_AUTO_CLEANING_PERIOD: -+ buf[2] = data[0]; -+ buf[3] = data[1]; -+ buf[4] = crc8(sps30_crc8_table, &buf[2], 2, CRC8_INIT_VALUE); -+ buf[5] = data[2]; -+ buf[6] = data[3]; -+ buf[7] = crc8(sps30_crc8_table, &buf[5], 2, CRC8_INIT_VALUE); -+ ret = sps30_write_then_read(state, buf, 8, NULL, 0); -+ break; - } - - if (ret) -@@ -170,6 +192,14 @@ static int sps30_do_meas(struct sps30_st - int i, ret, tries = 5; - u8 tmp[16]; - -+ if (state->state == RESET) { -+ ret = sps30_do_cmd(state, SPS30_START_MEAS, NULL, 0); -+ if (ret) -+ return ret; -+ -+ state->state = MEASURING; -+ } -+ - while (tries--) { - ret = sps30_do_cmd(state, SPS30_READ_DATA_READY_FLAG, tmp, 2); - if (ret) -@@ -276,6 +306,24 @@ static int sps30_read_raw(struct iio_dev - return -EINVAL; - } - -+static int sps30_do_cmd_reset(struct sps30_state *state) -+{ -+ int ret; -+ -+ ret = sps30_do_cmd(state, SPS30_RESET, NULL, 0); -+ msleep(300); -+ /* -+ * Power-on-reset causes sensor to produce some glitch on i2c bus and -+ * some controllers end up in error state. Recover simply by placing -+ * some data on the bus, for example STOP_MEAS command, which -+ * is NOP in this case. -+ */ -+ sps30_do_cmd(state, SPS30_STOP_MEAS, NULL, 0); -+ state->state = RESET; -+ -+ return ret; -+} -+ - static ssize_t start_cleaning_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) -@@ -296,10 +344,82 @@ static ssize_t start_cleaning_store(stru - return len; - } - -+static ssize_t cleaning_period_show(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct iio_dev *indio_dev = dev_to_iio_dev(dev); -+ struct sps30_state *state = iio_priv(indio_dev); -+ u8 tmp[4]; -+ int ret; -+ -+ mutex_lock(&state->lock); -+ ret = sps30_do_cmd(state, SPS30_READ_AUTO_CLEANING_PERIOD, tmp, 4); -+ mutex_unlock(&state->lock); -+ if (ret) -+ return ret; -+ -+ return sprintf(buf, "%d\n", get_unaligned_be32(tmp)); -+} -+ -+static ssize_t cleaning_period_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t len) -+{ -+ struct iio_dev *indio_dev = dev_to_iio_dev(dev); -+ struct sps30_state *state = iio_priv(indio_dev); -+ int val, ret; -+ u8 tmp[4]; -+ -+ if (kstrtoint(buf, 0, &val)) -+ return -EINVAL; -+ -+ if ((val < SPS30_AUTO_CLEANING_PERIOD_MIN) || -+ (val > SPS30_AUTO_CLEANING_PERIOD_MAX)) -+ return -EINVAL; -+ -+ put_unaligned_be32(val, tmp); -+ -+ mutex_lock(&state->lock); -+ ret = sps30_do_cmd(state, SPS30_AUTO_CLEANING_PERIOD, tmp, 0); -+ if (ret) { -+ mutex_unlock(&state->lock); -+ return ret; -+ } -+ -+ msleep(20); -+ -+ /* -+ * sensor requires reset in order to return up to date self cleaning -+ * period -+ */ -+ ret = sps30_do_cmd_reset(state); -+ if (ret) -+ dev_warn(dev, -+ "period changed but reads will return the old value\n"); -+ -+ mutex_unlock(&state->lock); -+ -+ return len; -+} -+ -+static ssize_t cleaning_period_available_show(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ return snprintf(buf, PAGE_SIZE, "[%d %d %d]\n", -+ SPS30_AUTO_CLEANING_PERIOD_MIN, 1, -+ SPS30_AUTO_CLEANING_PERIOD_MAX); -+} -+ - static IIO_DEVICE_ATTR_WO(start_cleaning, 0); -+static IIO_DEVICE_ATTR_RW(cleaning_period, 0); -+static IIO_DEVICE_ATTR_RO(cleaning_period_available, 0); - - static struct attribute *sps30_attrs[] = { - &iio_dev_attr_start_cleaning.dev_attr.attr, -+ &iio_dev_attr_cleaning_period.dev_attr.attr, -+ &iio_dev_attr_cleaning_period_available.dev_attr.attr, - NULL - }; - -@@ -362,6 +482,7 @@ static int sps30_probe(struct i2c_client - state = iio_priv(indio_dev); - i2c_set_clientdata(client, indio_dev); - state->client = client; -+ state->state = RESET; - indio_dev->dev.parent = &client->dev; - indio_dev->info = &sps30_info; - indio_dev->name = client->name; -@@ -373,19 +494,11 @@ static int sps30_probe(struct i2c_client - mutex_init(&state->lock); - crc8_populate_msb(sps30_crc8_table, SPS30_CRC8_POLYNOMIAL); - -- ret = sps30_do_cmd(state, SPS30_RESET, NULL, 0); -+ ret = sps30_do_cmd_reset(state); - if (ret) { - dev_err(&client->dev, "failed to reset device\n"); - return ret; - } -- msleep(300); -- /* -- * Power-on-reset causes sensor to produce some glitch on i2c bus and -- * some controllers end up in error state. Recover simply by placing -- * some data on the bus, for example STOP_MEAS command, which -- * is NOP in this case. -- */ -- sps30_do_cmd(state, SPS30_STOP_MEAS, NULL, 0); - - ret = sps30_do_cmd(state, SPS30_READ_SERIAL, buf, sizeof(buf)); - if (ret) { -@@ -395,12 +508,6 @@ static int sps30_probe(struct i2c_client - /* returned serial number is already NUL terminated */ - dev_info(&client->dev, "serial number: %s\n", buf); - -- ret = sps30_do_cmd(state, SPS30_START_MEAS, NULL, 0); -- if (ret) { -- dev_err(&client->dev, "failed to start measurement\n"); -- return ret; -- } -- - ret = devm_add_action_or_reset(&client->dev, sps30_stop_meas, state); - if (ret) - return ret; diff --git a/target/linux/generic/backport-4.19/503-v5.1-iio-chemical-sps30-remove-printk-format-specifier.patch b/target/linux/generic/backport-4.19/503-v5.1-iio-chemical-sps30-remove-printk-format-specifier.patch deleted file mode 100644 index b0fe5ac2e6..0000000000 --- a/target/linux/generic/backport-4.19/503-v5.1-iio-chemical-sps30-remove-printk-format-specifier.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 3fa30bf7004bb8069826ef85487f4753666a73da Mon Sep 17 00:00:00 2001 -From: Tomasz Duszynski <tduszyns@gmail.com> -Date: Sat, 2 Feb 2019 10:00:03 +0100 -Subject: [PATCH] iio: chemical: sps30: remove printk format specifier - -pr_fmt is used by printk wrappers. There are not any in the driver -code so remove the format specifier. - -Signed-off-by: Tomasz Duszynski <tduszyns@gmail.com> -Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> ---- - drivers/iio/chemical/sps30.c | 2 -- - 1 file changed, 2 deletions(-) - ---- a/drivers/iio/chemical/sps30.c -+++ b/drivers/iio/chemical/sps30.c -@@ -7,8 +7,6 @@ - * I2C slave address: 0x69 - */ - --#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -- - #include <asm/unaligned.h> - #include <linux/crc8.h> - #include <linux/delay.h> diff --git a/target/linux/generic/backport-4.19/504-v5.1-iio-chemical-sps30-fix-a-loop-timeout-test.patch b/target/linux/generic/backport-4.19/504-v5.1-iio-chemical-sps30-fix-a-loop-timeout-test.patch deleted file mode 100644 index c0aae35549..0000000000 --- a/target/linux/generic/backport-4.19/504-v5.1-iio-chemical-sps30-fix-a-loop-timeout-test.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 905889b4a34c753a538015f0b2cdaa0c9e3a4fd5 Mon Sep 17 00:00:00 2001 -From: Dan Carpenter <dan.carpenter@oracle.com> -Date: Sat, 9 Feb 2019 12:03:52 +0300 -Subject: [PATCH] iio: chemical: sps30: fix a loop timeout test - -The "while (tries--) {" loop is a postop so it exits with "tries" set -to -1. - -Fixes: 232e0f6ddeae ("iio: chemical: add support for Sensirion SPS30 sensor") -Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> -Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> ---- - drivers/iio/chemical/sps30.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/iio/chemical/sps30.c -+++ b/drivers/iio/chemical/sps30.c -@@ -210,7 +210,7 @@ static int sps30_do_meas(struct sps30_st - msleep_interruptible(300); - } - -- if (!tries) -+ if (tries == -1) - return -ETIMEDOUT; - - ret = sps30_do_cmd(state, SPS30_READ_DATA, tmp, sizeof(int) * size); diff --git a/target/linux/generic/backport-4.19/505-v5.1-iio-chemical-sps30-Supress-some-switch-fallthrough-w.patch b/target/linux/generic/backport-4.19/505-v5.1-iio-chemical-sps30-Supress-some-switch-fallthrough-w.patch deleted file mode 100644 index 08cc34ff40..0000000000 --- a/target/linux/generic/backport-4.19/505-v5.1-iio-chemical-sps30-Supress-some-switch-fallthrough-w.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 59b9bb0abca9efe47207301dbaf0d1beee2bd0f7 Mon Sep 17 00:00:00 2001 -From: Jonathan Cameron <Jonathan.Cameron@huawei.com> -Date: Sat, 9 Feb 2019 19:32:58 +0000 -Subject: [PATCH] iio:chemical:sps30 Supress some switch fallthrough warnings. - -Fixes warnings reported on linux-next but marking one path -and adding an explicit return in the other. - -Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> -Cc: Andreas Brauchli <a.brauchli@elementarea.net> -Acked-by: Tomasz Duszynski <tduszyns@gmail.com> ---- - drivers/iio/chemical/sps30.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/iio/chemical/sps30.c -+++ b/drivers/iio/chemical/sps30.c -@@ -118,6 +118,7 @@ static int sps30_do_cmd(struct sps30_sta - case SPS30_READ_AUTO_CLEANING_PERIOD: - buf[0] = SPS30_AUTO_CLEANING_PERIOD >> 8; - buf[1] = (u8)SPS30_AUTO_CLEANING_PERIOD; -+ /* fall through */ - case SPS30_READ_DATA_READY_FLAG: - case SPS30_READ_DATA: - case SPS30_READ_SERIAL: -@@ -295,6 +296,8 @@ static int sps30_read_raw(struct iio_dev - *val2 = 10000; - - return IIO_VAL_INT_PLUS_MICRO; -+ default: -+ return -EINVAL; - } - default: - return -EINVAL; diff --git a/target/linux/generic/backport-4.19/506-v5.1-iio-chemical-sps30-Explicity-truncate-constant-by-ma.patch b/target/linux/generic/backport-4.19/506-v5.1-iio-chemical-sps30-Explicity-truncate-constant-by-ma.patch deleted file mode 100644 index e1f4a3b635..0000000000 --- a/target/linux/generic/backport-4.19/506-v5.1-iio-chemical-sps30-Explicity-truncate-constant-by-ma.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 78b75ab3f8c9dfac563b81105a1b838ec37a940e Mon Sep 17 00:00:00 2001 -From: Jonathan Cameron <Jonathan.Cameron@huawei.com> -Date: Sun, 13 Oct 2019 10:55:15 +0100 -Subject: [PATCH] iio: chemical: sps30: Explicity truncate constant by masking - -When breaking up a constant to write to two 8 bit registers -it isn't obvious to sparse that it was intentional. - -CHECK drivers/iio/chemical/sps30.c -drivers/iio/chemical/sps30.c:120:30: warning: cast truncates bits from constant value (8004 becomes 4) - -So in the interests of minimising noisy warnings, let us add -a mask. - -Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> -Acked-by: Tomasz Duszynski <tduszyns@gmail.com> ---- - drivers/iio/chemical/sps30.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/iio/chemical/sps30.c -+++ b/drivers/iio/chemical/sps30.c -@@ -117,7 +117,7 @@ static int sps30_do_cmd(struct sps30_sta - break; - case SPS30_READ_AUTO_CLEANING_PERIOD: - buf[0] = SPS30_AUTO_CLEANING_PERIOD >> 8; -- buf[1] = (u8)SPS30_AUTO_CLEANING_PERIOD; -+ buf[1] = (u8)(SPS30_AUTO_CLEANING_PERIOD & 0xff); - /* fall through */ - case SPS30_READ_DATA_READY_FLAG: - case SPS30_READ_DATA: diff --git a/target/linux/generic/backport-4.19/507-v5.6-iio-chemical-sps30-fix-missing-triggered-buffer-depe.patch b/target/linux/generic/backport-4.19/507-v5.6-iio-chemical-sps30-fix-missing-triggered-buffer-depe.patch deleted file mode 100644 index c2b999b1cb..0000000000 --- a/target/linux/generic/backport-4.19/507-v5.6-iio-chemical-sps30-fix-missing-triggered-buffer-depe.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 61338e27e2eef3bfcd3df5c39cec5b9dc10ba25c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Petr=20=C5=A0tetiar?= <ynezz@true.cz> -Date: Sun, 23 Feb 2020 22:08:25 +0100 -Subject: [PATCH] iio: chemical: sps30: fix missing triggered buffer dependency -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -SPS30 uses triggered buffer, but the dependency is not specified in the -Kconfig file. Fix this by selecting IIO_BUFFER and IIO_TRIGGERED_BUFFER -config symbols. - -Cc: stable@vger.kernel.org -Fixes: 232e0f6ddeae ("iio: chemical: add support for Sensirion SPS30 sensor") -Signed-off-by: Petr Å tetiar <ynezz@true.cz> ---- - drivers/iio/chemical/Kconfig | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/iio/chemical/Kconfig -+++ b/drivers/iio/chemical/Kconfig -@@ -65,6 +65,8 @@ config SPS30 - tristate "SPS30 particulate matter sensor" - depends on I2C - select CRC8 -+ select IIO_BUFFER -+ select IIO_TRIGGERED_BUFFER - help - Say Y here to build support for the Sensirion SPS30 particulate - matter sensor. diff --git a/target/linux/generic/backport-4.19/700-v5.1-net-phylink-only-call-mac_config-during-resolve-when.patch b/target/linux/generic/backport-4.19/700-v5.1-net-phylink-only-call-mac_config-during-resolve-when.patch deleted file mode 100644 index 0e272ea891..0000000000 --- a/target/linux/generic/backport-4.19/700-v5.1-net-phylink-only-call-mac_config-during-resolve-when.patch +++ /dev/null @@ -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: diff --git a/target/linux/generic/backport-4.19/701-v5.2-net-phylink-ensure-inband-AN-works-correctly.patch b/target/linux/generic/backport-4.19/701-v5.2-net-phylink-ensure-inband-AN-works-correctly.patch deleted file mode 100644 index 746aca2e5a..0000000000 --- a/target/linux/generic/backport-4.19/701-v5.2-net-phylink-ensure-inband-AN-works-correctly.patch +++ /dev/null @@ -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; - } diff --git a/target/linux/generic/backport-4.19/702-v4.20-net-ethernet-Add-helper-for-MACs-which-support-asym-.patch b/target/linux/generic/backport-4.19/702-v4.20-net-ethernet-Add-helper-for-MACs-which-support-asym-.patch deleted file mode 100644 index 2f32c59ad2..0000000000 --- a/target/linux/generic/backport-4.19/702-v4.20-net-ethernet-Add-helper-for-MACs-which-support-asym-.patch +++ /dev/null @@ -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 -@@ -1783,6 +1783,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 -@@ -1051,6 +1051,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 *)); diff --git a/target/linux/generic/backport-4.19/703-v4.20-net-ethernet-Add-helper-for-set_pauseparam-for-Asym-.patch b/target/linux/generic/backport-4.19/703-v4.20-net-ethernet-Add-helper-for-set_pauseparam-for-Asym-.patch deleted file mode 100644 index 99aba28818..0000000000 --- a/target/linux/generic/backport-4.19/703-v4.20-net-ethernet-Add-helper-for-set_pauseparam-for-Asym-.patch +++ /dev/null @@ -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 -@@ -1796,6 +1796,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 -@@ -1052,6 +1052,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 *)); diff --git a/target/linux/generic/backport-4.19/704-v4.20-net-phy-Stop-with-excessive-soft-reset.patch b/target/linux/generic/backport-4.19/704-v4.20-net-phy-Stop-with-excessive-soft-reset.patch deleted file mode 100644 index 483815a338..0000000000 --- a/target/linux/generic/backport-4.19/704-v4.20-net-phy-Stop-with-excessive-soft-reset.patch +++ /dev/null @@ -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 -@@ -892,8 +892,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; diff --git a/target/linux/generic/backport-4.19/705-v5.1-net-phy-provide-full-set-of-accessor-functions-to-MM.patch b/target/linux/generic/backport-4.19/705-v5.1-net-phy-provide-full-set-of-accessor-functions-to-MM.patch deleted file mode 100644 index 2dbf9ebd10..0000000000 --- a/target/linux/generic/backport-4.19/705-v5.1-net-phy-provide-full-set-of-accessor-functions-to-MM.patch +++ /dev/null @@ -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 -@@ -697,17 +697,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 -@@ -762,9 +751,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 -@@ -815,6 +855,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 - * -@@ -890,18 +990,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); diff --git a/target/linux/generic/backport-4.19/706-v5.1-net-phy-add-register-modifying-helpers-returning-1-o.patch b/target/linux/generic/backport-4.19/706-v5.1-net-phy-add-register-modifying-helpers-returning-1-o.patch deleted file mode 100644 index 1cd26a2ad3..0000000000 --- a/target/linux/generic/backport-4.19/706-v5.1-net-phy-add-register-modifying-helpers-returning-1-o.patch +++ /dev/null @@ -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 -@@ -797,13 +797,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 diff --git a/target/linux/generic/backport-4.19/707-v5.1-net-phy-add-genphy_c45_check_and_restart_aneg.patch b/target/linux/generic/backport-4.19/707-v5.1-net-phy-add-genphy_c45_check_and_restart_aneg.patch deleted file mode 100644 index 0f2a216aa5..0000000000 --- a/target/linux/generic/backport-4.19/707-v5.1-net-phy-add-genphy_c45_check_and_restart_aneg.patch +++ /dev/null @@ -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 -@@ -1100,6 +1100,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); diff --git a/target/linux/generic/backport-4.19/708-v5.3-net-phylink-remove-netdev-from-phylink-mii-ioctl-emu.patch b/target/linux/generic/backport-4.19/708-v5.3-net-phylink-remove-netdev-from-phylink-mii-ioctl-emu.patch deleted file mode 100644 index 1c3f1cc01a..0000000000 --- a/target/linux/generic/backport-4.19/708-v5.3-net-phylink-remove-netdev-from-phylink-mii-ioctl-emu.patch +++ /dev/null @@ -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; - } diff --git a/target/linux/generic/backport-4.19/709-v5.3-net-phylink-support-for-link-gpio-interrupt.patch b/target/linux/generic/backport-4.19/709-v5.3-net-phylink-support-for-link-gpio-interrupt.patch deleted file mode 100644 index 84a1c853d1..0000000000 --- a/target/linux/generic/backport-4.19/709-v5.3-net-phylink-support-for-link-gpio-interrupt.patch +++ /dev/null @@ -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); - } diff --git a/target/linux/generic/backport-4.19/710-v5.3-net-phy-allow-Clause-45-access-via-mii-ioctl.patch b/target/linux/generic/backport-4.19/710-v5.3-net-phy-allow-Clause-45-access-via-mii-ioctl.patch deleted file mode 100644 index 3a601c65b0..0000000000 --- a/target/linux/generic/backport-4.19/710-v5.3-net-phy-allow-Clause-45-access-via-mii-ioctl.patch +++ /dev/null @@ -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); - diff --git a/target/linux/generic/backport-4.19/711-v5.3-net-sfp-add-mandatory-attach-detach-methods-for-sfp-.patch b/target/linux/generic/backport-4.19/711-v5.3-net-sfp-add-mandatory-attach-detach-methods-for-sfp-.patch deleted file mode 100644 index 0600da2fad..0000000000 --- a/target/linux/generic/backport-4.19/711-v5.3-net-sfp-add-mandatory-attach-detach-methods-for-sfp-.patch +++ /dev/null @@ -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 -@@ -425,7 +425,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; - } -@@ -434,8 +434,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); diff --git a/target/linux/generic/backport-4.19/712-v5.3-net-sfp-remove-sfp-bus-use-of-netdevs.patch b/target/linux/generic/backport-4.19/712-v5.3-net-sfp-remove-sfp-bus-use-of-netdevs.patch deleted file mode 100644 index e68cc381dc..0000000000 --- a/target/linux/generic/backport-4.19/712-v5.3-net-sfp-remove-sfp-bus-use-of-netdevs.patch +++ /dev/null @@ -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 -@@ -30,7 +30,6 @@ struct sfp_bus { - - const struct sfp_upstream_ops *upstream_ops; - void *upstream; -- struct net_device *netdev; - struct phy_device *phydev; - - bool registered; -@@ -517,13 +516,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 - * -@@ -534,7 +531,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); -@@ -544,7 +541,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); -@@ -670,7 +666,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); -@@ -690,7 +686,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; diff --git a/target/linux/generic/backport-4.19/713-v5.2-net-phylink-avoid-reducing-support-mask.patch b/target/linux/generic/backport-4.19/713-v5.2-net-phylink-avoid-reducing-support-mask.patch deleted file mode 100644 index 3aa8d9e571..0000000000 --- a/target/linux/generic/backport-4.19/713-v5.2-net-phylink-avoid-reducing-support-mask.patch +++ /dev/null @@ -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), diff --git a/target/linux/generic/backport-4.19/714-v5.3-net-sfp-Stop-SFP-polling-and-interrupt-handling-duri.patch b/target/linux/generic/backport-4.19/714-v5.3-net-sfp-Stop-SFP-polling-and-interrupt-handling-duri.patch deleted file mode 100644 index 0509950296..0000000000 --- a/target/linux/generic/backport-4.19/714-v5.3-net-sfp-Stop-SFP-polling-and-interrupt-handling-duri.patch +++ /dev/null @@ -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, diff --git a/target/linux/generic/backport-4.19/715-v5.3-net-phylink-don-t-start-and-stop-SGMII-PHYs-in-SFP-m.patch b/target/linux/generic/backport-4.19/715-v5.3-net-phylink-don-t-start-and-stop-SGMII-PHYs-in-SFP-m.patch deleted file mode 100644 index 94fb2fb3e4..0000000000 --- a/target/linux/generic/backport-4.19/715-v5.3-net-phylink-don-t-start-and-stop-SGMII-PHYs-in-SFP-m.patch +++ /dev/null @@ -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); diff --git a/target/linux/generic/backport-4.19/716-v5.5-net-sfp-move-fwnode-parsing-into-sfp-bus-layer.patch b/target/linux/generic/backport-4.19/716-v5.5-net-sfp-move-fwnode-parsing-into-sfp-bus-layer.patch deleted file mode 100644 index bc16e8f1c6..0000000000 --- a/target/linux/generic/backport-4.19/716-v5.5-net-sfp-move-fwnode-parsing-into-sfp-bus-layer.patch +++ /dev/null @@ -1,179 +0,0 @@ -From 4054955f0da08c81d42220cb445820d474f1ac92 Mon Sep 17 00:00:00 2001 -From: Russell King <rmk+kernel@armlinux.org.uk> -Date: Sat, 14 Sep 2019 14:21:22 +0100 -Subject: [PATCH 614/660] net: sfp: move fwnode parsing into sfp-bus layer - -Rather than parsing the sfp firmware node in phylink, parse it in the -sfp-bus code, so we can re-use this code for PHYs without having to -duplicate the parsing. - -Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> ---- - drivers/net/phy/phylink.c | 21 ++++--------- - drivers/net/phy/sfp-bus.c | 65 +++++++++++++++++++++++++-------------- - include/linux/sfp.h | 10 +++--- - 3 files changed, 53 insertions(+), 43 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -538,26 +538,17 @@ static const struct sfp_upstream_ops sfp - static int phylink_register_sfp(struct phylink *pl, - struct fwnode_handle *fwnode) - { -- struct fwnode_reference_args ref; -+ struct sfp_bus *bus; - int ret; - -- if (!fwnode) -- return 0; -- -- ret = fwnode_property_get_reference_args(fwnode, "sfp", NULL, -- 0, 0, &ref); -- if (ret < 0) { -- if (ret == -ENOENT) -- return 0; -- -- netdev_err(pl->netdev, "unable to parse \"sfp\" node: %d\n", -- ret); -+ bus = sfp_register_upstream_node(fwnode, pl, &sfp_phylink_ops); -+ if (IS_ERR(bus)) { -+ ret = PTR_ERR(bus); -+ netdev_err(pl->netdev, "unable to attach SFP bus: %d\n", ret); - return ret; - } - -- pl->sfp_bus = sfp_register_upstream(ref.fwnode, pl, &sfp_phylink_ops); -- if (!pl->sfp_bus) -- return -ENOMEM; -+ pl->sfp_bus = bus; - - return 0; - } ---- a/drivers/net/phy/sfp-bus.c -+++ b/drivers/net/phy/sfp-bus.c -@@ -3,6 +3,7 @@ - #include <linux/list.h> - #include <linux/mutex.h> - #include <linux/phylink.h> -+#include <linux/property.h> - #include <linux/rtnetlink.h> - #include <linux/slab.h> - -@@ -519,45 +520,63 @@ static void sfp_upstream_clear(struct sf - } - - /** -- * sfp_register_upstream() - Register the neighbouring device -- * @fwnode: firmware node for the SFP bus -+ * sfp_register_upstream_node() - parse and register the neighbouring device -+ * @fwnode: firmware node for the parent device (MAC or PHY) - * @upstream: the upstream private data - * @ops: the upstream's &struct sfp_upstream_ops - * -- * Register the upstream device (eg, PHY) with the SFP bus. MAC drivers -- * should use phylink, which will call this function for them. Returns -- * a pointer to the allocated &struct sfp_bus. -+ * Parse the parent device's firmware node for a SFP bus, and register the -+ * SFP bus using sfp_register_upstream(). - * -- * On error, returns %NULL. -+ * Returns: on success, a pointer to the sfp_bus structure, -+ * %NULL if no SFP is specified, -+ * on failure, an error pointer value: -+ * corresponding to the errors detailed for -+ * fwnode_property_get_reference_args(). -+ * %-ENOMEM if we failed to allocate the bus. -+ * an error from the upstream's connect_phy() method. - */ --struct sfp_bus *sfp_register_upstream(struct fwnode_handle *fwnode, -- void *upstream, -- const struct sfp_upstream_ops *ops) --{ -- struct sfp_bus *bus = sfp_bus_get(fwnode); -- int ret = 0; -- -- if (bus) { -- rtnl_lock(); -- bus->upstream_ops = ops; -- bus->upstream = upstream; -+struct sfp_bus *sfp_register_upstream_node(struct fwnode_handle *fwnode, -+ void *upstream, -+ const struct sfp_upstream_ops *ops) -+{ -+ struct fwnode_reference_args ref; -+ struct sfp_bus *bus; -+ int ret; - -- if (bus->sfp) { -- ret = sfp_register_bus(bus); -- if (ret) -- sfp_upstream_clear(bus); -- } -- rtnl_unlock(); -+ ret = fwnode_property_get_reference_args(fwnode, "sfp", NULL, -+ 0, 0, &ref); -+ if (ret == -ENOENT) -+ return NULL; -+ else if (ret < 0) -+ return ERR_PTR(ret); -+ -+ bus = sfp_bus_get(ref.fwnode); -+ fwnode_handle_put(ref.fwnode); -+ if (!bus) -+ return ERR_PTR(-ENOMEM); -+ -+ rtnl_lock(); -+ bus->upstream_ops = ops; -+ bus->upstream = upstream; -+ -+ if (bus->sfp) { -+ ret = sfp_register_bus(bus); -+ if (ret) -+ sfp_upstream_clear(bus); -+ } else { -+ ret = 0; - } -+ rtnl_unlock(); - - if (ret) { - sfp_bus_put(bus); -- bus = NULL; -+ bus = ERR_PTR(ret); - } - - return bus; - } --EXPORT_SYMBOL_GPL(sfp_register_upstream); -+EXPORT_SYMBOL_GPL(sfp_register_upstream_node); - - /** - * sfp_unregister_upstream() - Unregister sfp bus ---- a/include/linux/sfp.h -+++ b/include/linux/sfp.h -@@ -508,9 +508,9 @@ int sfp_get_module_eeprom(struct sfp_bus - u8 *data); - 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, -- void *upstream, -- const struct sfp_upstream_ops *ops); -+struct sfp_bus *sfp_register_upstream_node(struct fwnode_handle *fwnode, -+ void *upstream, -+ const struct sfp_upstream_ops *ops); - void sfp_unregister_upstream(struct sfp_bus *bus); - #else - static inline int sfp_parse_port(struct sfp_bus *bus, -@@ -553,11 +553,11 @@ static inline void sfp_upstream_stop(str - { - } - --static inline struct sfp_bus *sfp_register_upstream( -+static inline struct sfp_bus *sfp_register_upstream_node( - struct fwnode_handle *fwnode, void *upstream, - const struct sfp_upstream_ops *ops) - { -- return (struct sfp_bus *)-1; -+ return NULL; - } - - static inline void sfp_unregister_upstream(struct sfp_bus *bus) diff --git a/target/linux/generic/backport-4.19/717-v5.5-net-sfp-rework-upstream-interface.patch b/target/linux/generic/backport-4.19/717-v5.5-net-sfp-rework-upstream-interface.patch deleted file mode 100644 index a901b15aaf..0000000000 --- a/target/linux/generic/backport-4.19/717-v5.5-net-sfp-rework-upstream-interface.patch +++ /dev/null @@ -1,254 +0,0 @@ -From 863b5b6941f9f43b924393b6ba2b36647e7dee42 Mon Sep 17 00:00:00 2001 -From: Russell King <rmk+kernel@armlinux.org.uk> -Date: Thu, 7 Nov 2019 17:06:08 +0000 -Subject: [PATCH 615/660] net: sfp: rework upstream interface - -The current upstream interface is an all-or-nothing, which is -sub-optimal for future changes, as it doesn't allow the upstream driver -to prepare for the SFP module becoming available, as it is at boot. - -Switch to a find-sfp-bus, add-upstream, del-upstream, put-sfp-bus -interface structure instead, which allows the upstream driver to -prepare for a module being available as soon as add-upstream is called. - -Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> ---- - drivers/net/phy/phylink.c | 10 +++-- - drivers/net/phy/sfp-bus.c | 92 +++++++++++++++++++++++++++------------ - include/linux/sfp.h | 25 +++++++---- - 3 files changed, 88 insertions(+), 39 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -541,7 +541,7 @@ static int phylink_register_sfp(struct p - struct sfp_bus *bus; - int ret; - -- bus = sfp_register_upstream_node(fwnode, pl, &sfp_phylink_ops); -+ bus = sfp_bus_find_fwnode(fwnode); - if (IS_ERR(bus)) { - ret = PTR_ERR(bus); - netdev_err(pl->netdev, "unable to attach SFP bus: %d\n", ret); -@@ -550,7 +550,10 @@ static int phylink_register_sfp(struct p - - pl->sfp_bus = bus; - -- return 0; -+ ret = sfp_bus_add_upstream(bus, pl, &sfp_phylink_ops); -+ sfp_bus_put(bus); -+ -+ return ret; - } - - /** -@@ -634,8 +637,7 @@ EXPORT_SYMBOL_GPL(phylink_create); - */ - void phylink_destroy(struct phylink *pl) - { -- if (pl->sfp_bus) -- sfp_unregister_upstream(pl->sfp_bus); -+ sfp_bus_del_upstream(pl->sfp_bus); - if (pl->link_gpio) - gpiod_put(pl->link_gpio); - ---- a/drivers/net/phy/sfp-bus.c -+++ b/drivers/net/phy/sfp-bus.c -@@ -403,10 +403,19 @@ static void sfp_bus_release(struct kref - kfree(bus); - } - --static void sfp_bus_put(struct sfp_bus *bus) -+/** -+ * sfp_bus_put() - put a reference on the &struct sfp_bus -+ * bus: the &struct sfp_bus found via sfp_bus_find_fwnode() -+ * -+ * Put a reference on the &struct sfp_bus and free the underlying structure -+ * if this was the last reference. -+ */ -+void sfp_bus_put(struct sfp_bus *bus) - { -- kref_put_mutex(&bus->kref, sfp_bus_release, &sfp_mutex); -+ if (bus) -+ kref_put_mutex(&bus->kref, sfp_bus_release, &sfp_mutex); - } -+EXPORT_SYMBOL_GPL(sfp_bus_put); - - static int sfp_register_bus(struct sfp_bus *bus) - { -@@ -422,11 +431,11 @@ static int sfp_register_bus(struct sfp_b - return ret; - } - } -+ bus->registered = true; - bus->socket_ops->attach(bus->sfp); - if (bus->started) - bus->socket_ops->start(bus->sfp); - bus->upstream_ops->attach(bus->upstream, bus); -- bus->registered = true; - return 0; - } - -@@ -520,13 +529,12 @@ static void sfp_upstream_clear(struct sf - } - - /** -- * sfp_register_upstream_node() - parse and register the neighbouring device -+ * sfp_bus_find_fwnode() - parse and locate the SFP bus from fwnode - * @fwnode: firmware node for the parent device (MAC or PHY) -- * @upstream: the upstream private data -- * @ops: the upstream's &struct sfp_upstream_ops - * -- * Parse the parent device's firmware node for a SFP bus, and register the -- * SFP bus using sfp_register_upstream(). -+ * Parse the parent device's firmware node for a SFP bus, and locate -+ * the sfp_bus structure, incrementing its reference count. This must -+ * be put via sfp_bus_put() when done. - * - * Returns: on success, a pointer to the sfp_bus structure, - * %NULL if no SFP is specified, -@@ -536,9 +544,7 @@ static void sfp_upstream_clear(struct sf - * %-ENOMEM if we failed to allocate the bus. - * an error from the upstream's connect_phy() method. - */ --struct sfp_bus *sfp_register_upstream_node(struct fwnode_handle *fwnode, -- void *upstream, -- const struct sfp_upstream_ops *ops) -+struct sfp_bus *sfp_bus_find_fwnode(struct fwnode_handle *fwnode) - { - struct fwnode_reference_args ref; - struct sfp_bus *bus; -@@ -556,7 +562,39 @@ struct sfp_bus *sfp_register_upstream_no - if (!bus) - return ERR_PTR(-ENOMEM); - -+ return bus; -+} -+EXPORT_SYMBOL_GPL(sfp_bus_find_fwnode); -+ -+/** -+ * sfp_bus_add_upstream() - parse and register the neighbouring device -+ * @bus: the &struct sfp_bus found via sfp_bus_find_fwnode() -+ * @upstream: the upstream private data -+ * @ops: the upstream's &struct sfp_upstream_ops -+ * -+ * Add upstream driver for the SFP bus, and if the bus is complete, register -+ * the SFP bus using sfp_register_upstream(). This takes a reference on the -+ * bus, so it is safe to put the bus after this call. -+ * -+ * Returns: on success, a pointer to the sfp_bus structure, -+ * %NULL if no SFP is specified, -+ * on failure, an error pointer value: -+ * corresponding to the errors detailed for -+ * fwnode_property_get_reference_args(). -+ * %-ENOMEM if we failed to allocate the bus. -+ * an error from the upstream's connect_phy() method. -+ */ -+int sfp_bus_add_upstream(struct sfp_bus *bus, void *upstream, -+ const struct sfp_upstream_ops *ops) -+{ -+ int ret; -+ -+ /* If no bus, return success */ -+ if (!bus) -+ return 0; -+ - rtnl_lock(); -+ kref_get(&bus->kref); - bus->upstream_ops = ops; - bus->upstream = upstream; - -@@ -569,33 +607,33 @@ struct sfp_bus *sfp_register_upstream_no - } - rtnl_unlock(); - -- if (ret) { -+ if (ret) - sfp_bus_put(bus); -- bus = ERR_PTR(ret); -- } - -- return bus; -+ return ret; - } --EXPORT_SYMBOL_GPL(sfp_register_upstream_node); -+EXPORT_SYMBOL_GPL(sfp_bus_add_upstream); - - /** -- * sfp_unregister_upstream() - Unregister sfp bus -+ * sfp_bus_del_upstream() - Delete a sfp bus - * @bus: a pointer to the &struct sfp_bus structure for the sfp module - * -- * Unregister a previously registered upstream connection for the SFP -- * module. @bus is returned from sfp_register_upstream(). -+ * Delete a previously registered upstream connection for the SFP -+ * module. @bus should have been added by sfp_bus_add_upstream(). - */ --void sfp_unregister_upstream(struct sfp_bus *bus) -+void sfp_bus_del_upstream(struct sfp_bus *bus) - { -- rtnl_lock(); -- if (bus->sfp) -- sfp_unregister_bus(bus); -- sfp_upstream_clear(bus); -- rtnl_unlock(); -+ if (bus) { -+ rtnl_lock(); -+ if (bus->sfp) -+ sfp_unregister_bus(bus); -+ sfp_upstream_clear(bus); -+ rtnl_unlock(); - -- sfp_bus_put(bus); -+ sfp_bus_put(bus); -+ } - } --EXPORT_SYMBOL_GPL(sfp_unregister_upstream); -+EXPORT_SYMBOL_GPL(sfp_bus_del_upstream); - - /* Socket driver entry points */ - int sfp_add_phy(struct sfp_bus *bus, struct phy_device *phydev) ---- a/include/linux/sfp.h -+++ b/include/linux/sfp.h -@@ -508,10 +508,11 @@ int sfp_get_module_eeprom(struct sfp_bus - u8 *data); - void sfp_upstream_start(struct sfp_bus *bus); - void sfp_upstream_stop(struct sfp_bus *bus); --struct sfp_bus *sfp_register_upstream_node(struct fwnode_handle *fwnode, -- void *upstream, -- const struct sfp_upstream_ops *ops); --void sfp_unregister_upstream(struct sfp_bus *bus); -+void sfp_bus_put(struct sfp_bus *bus); -+struct sfp_bus *sfp_bus_find_fwnode(struct fwnode_handle *fwnode); -+int sfp_bus_add_upstream(struct sfp_bus *bus, void *upstream, -+ const struct sfp_upstream_ops *ops); -+void sfp_bus_del_upstream(struct sfp_bus *bus); - #else - static inline int sfp_parse_port(struct sfp_bus *bus, - const struct sfp_eeprom_id *id, -@@ -553,14 +554,22 @@ static inline void sfp_upstream_stop(str - { - } - --static inline struct sfp_bus *sfp_register_upstream_node( -- struct fwnode_handle *fwnode, void *upstream, -- const struct sfp_upstream_ops *ops) -+static inline void sfp_bus_put(struct sfp_bus *bus) -+{ -+} -+ -+static inline struct sfp_bus *sfp_bus_find_fwnode(struct fwnode_handle *fwnode) - { - return NULL; - } - --static inline void sfp_unregister_upstream(struct sfp_bus *bus) -+static int sfp_bus_add_upstream(struct sfp_bus *bus, void *upstream, -+ const struct sfp_upstream_ops *ops) -+{ -+ return 0; -+} -+ -+static inline void sfp_bus_del_upstream(struct sfp_bus *bus) - { - } - #endif diff --git a/target/linux/generic/backport-4.19/718-v5.5-net-sfp-fix-sfp_bus_put-kernel-documentation.patch b/target/linux/generic/backport-4.19/718-v5.5-net-sfp-fix-sfp_bus_put-kernel-documentation.patch deleted file mode 100644 index 7bfff60f2f..0000000000 --- a/target/linux/generic/backport-4.19/718-v5.5-net-sfp-fix-sfp_bus_put-kernel-documentation.patch +++ /dev/null @@ -1,27 +0,0 @@ -From ea7bfd81921827d334c2a23bd11ef0e4e2abafd2 Mon Sep 17 00:00:00 2001 -From: Russell King <rmk+kernel@armlinux.org.uk> -Date: Sat, 9 Nov 2019 08:13:50 +0000 -Subject: [PATCH 616/660] net: sfp: fix sfp_bus_put() kernel documentation - -The kbuild test robot found a problem with htmldocs with the recent -change to the SFP interfaces. Fix the kernel documentation for -sfp_bus_put() which was missing an '@' before the argument name -description. - -Fixes: 727b3668b730 ("net: sfp: rework upstream interface") -Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> ---- - drivers/net/phy/sfp-bus.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/phy/sfp-bus.c -+++ b/drivers/net/phy/sfp-bus.c -@@ -405,7 +405,7 @@ static void sfp_bus_release(struct kref - - /** - * sfp_bus_put() - put a reference on the &struct sfp_bus -- * bus: the &struct sfp_bus found via sfp_bus_find_fwnode() -+ * @bus: the &struct sfp_bus found via sfp_bus_find_fwnode() - * - * Put a reference on the &struct sfp_bus and free the underlying structure - * if this was the last reference. diff --git a/target/linux/generic/backport-4.19/719-v5.5-net-sfp-fix-sfp_bus_add_upstream-warning.patch b/target/linux/generic/backport-4.19/719-v5.5-net-sfp-fix-sfp_bus_add_upstream-warning.patch deleted file mode 100644 index 9528049e1b..0000000000 --- a/target/linux/generic/backport-4.19/719-v5.5-net-sfp-fix-sfp_bus_add_upstream-warning.patch +++ /dev/null @@ -1,27 +0,0 @@ -From f76d84cd85f8bd3f083495f7ca723822cba8abc9 Mon Sep 17 00:00:00 2001 -From: Russell King <rmk+kernel@armlinux.org.uk> -Date: Mon, 11 Nov 2019 10:23:35 +0000 -Subject: [PATCH 617/660] net: sfp: fix sfp_bus_add_upstream() warning - -When building with SFP disabled, the stub for sfp_bus_add_upstream() -missed "inline". Add it. - -Fixes: 727b3668b730 ("net: sfp: rework upstream interface") -Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> ---- - include/linux/sfp.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/include/linux/sfp.h -+++ b/include/linux/sfp.h -@@ -563,8 +563,8 @@ static inline struct sfp_bus *sfp_bus_fi - return NULL; - } - --static int sfp_bus_add_upstream(struct sfp_bus *bus, void *upstream, -- const struct sfp_upstream_ops *ops) -+static inline int sfp_bus_add_upstream(struct sfp_bus *bus, void *upstream, -+ const struct sfp_upstream_ops *ops) - { - return 0; - } diff --git a/target/linux/generic/backport-4.19/720-v5.5-net-sfp-move-sfp-sub-state-machines-into-separate-fu.patch b/target/linux/generic/backport-4.19/720-v5.5-net-sfp-move-sfp-sub-state-machines-into-separate-fu.patch deleted file mode 100644 index 2f90b00438..0000000000 --- a/target/linux/generic/backport-4.19/720-v5.5-net-sfp-move-sfp-sub-state-machines-into-separate-fu.patch +++ /dev/null @@ -1,124 +0,0 @@ -From b9d6ed5cdb67533feda7f221eb06f2f9f1ff5047 Mon Sep 17 00:00:00 2001 -From: Russell King <rmk+kernel@armlinux.org.uk> -Date: Fri, 11 Oct 2019 19:33:58 +0100 -Subject: [PATCH 618/660] net: sfp: move sfp sub-state machines into separate - functions - -Move the SFP sub-state machines out of the main state machine function, -in preparation for it doing a bit more with the device state. By doing -so, we ensure that our debug after the main state machine is always -printed. - -Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> ---- - drivers/net/phy/sfp.c | 74 +++++++++++++++++++++++++------------------ - 1 file changed, 43 insertions(+), 31 deletions(-) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -1479,19 +1479,34 @@ static void sfp_sm_mod_remove(struct sfp - dev_info(sfp->dev, "module removed\n"); - } - --static void sfp_sm_event(struct sfp *sfp, unsigned int event) -+/* This state machine tracks the netdev up/down state */ -+static void sfp_sm_device(struct sfp *sfp, unsigned int event) - { -- mutex_lock(&sfp->sm_mutex); -+ switch (sfp->sm_dev_state) { -+ default: -+ if (event == SFP_E_DEV_UP) -+ sfp->sm_dev_state = SFP_DEV_UP; -+ break; - -- dev_dbg(sfp->dev, "SM: enter %s:%s:%s event %s\n", -- mod_state_to_str(sfp->sm_mod_state), -- dev_state_to_str(sfp->sm_dev_state), -- sm_state_to_str(sfp->sm_state), -- event_to_str(event)); -+ case SFP_DEV_UP: -+ if (event == SFP_E_DEV_DOWN) { -+ /* If the module has a PHY, avoid raising TX disable -+ * as this resets the PHY. Otherwise, raise it to -+ * turn the laser off. -+ */ -+ if (!sfp->mod_phy) -+ sfp_module_tx_disable(sfp); -+ sfp->sm_dev_state = SFP_DEV_DOWN; -+ } -+ break; -+ } -+} - -- /* This state machine tracks the insert/remove state of -- * the module, and handles probing the on-board EEPROM. -- */ -+/* This state machine tracks the insert/remove state of -+ * the module, and handles probing the on-board EEPROM. -+ */ -+static void sfp_sm_module(struct sfp *sfp, unsigned int event) -+{ - switch (sfp->sm_mod_state) { - default: - if (event == SFP_E_INSERT && sfp->attached) { -@@ -1531,27 +1546,10 @@ static void sfp_sm_event(struct sfp *sfp - } - break; - } -+} - -- /* This state machine tracks the netdev up/down state */ -- switch (sfp->sm_dev_state) { -- default: -- if (event == SFP_E_DEV_UP) -- sfp->sm_dev_state = SFP_DEV_UP; -- break; -- -- case SFP_DEV_UP: -- if (event == SFP_E_DEV_DOWN) { -- /* If the module has a PHY, avoid raising TX disable -- * as this resets the PHY. Otherwise, raise it to -- * turn the laser off. -- */ -- if (!sfp->mod_phy) -- sfp_module_tx_disable(sfp); -- sfp->sm_dev_state = SFP_DEV_DOWN; -- } -- break; -- } -- -+static void sfp_sm_main(struct sfp *sfp, unsigned int event) -+{ - /* Some events are global */ - if (sfp->sm_state != SFP_S_DOWN && - (sfp->sm_mod_state != SFP_MOD_PRESENT || -@@ -1562,7 +1560,6 @@ static void sfp_sm_event(struct sfp *sfp - if (sfp->mod_phy) - sfp_sm_phy_detach(sfp); - sfp_sm_next(sfp, SFP_S_DOWN, 0); -- mutex_unlock(&sfp->sm_mutex); - return; - } - -@@ -1617,6 +1614,21 @@ static void sfp_sm_event(struct sfp *sfp - case SFP_S_TX_DISABLE: - break; - } -+} -+ -+static void sfp_sm_event(struct sfp *sfp, unsigned int event) -+{ -+ mutex_lock(&sfp->sm_mutex); -+ -+ dev_dbg(sfp->dev, "SM: enter %s:%s:%s event %s\n", -+ mod_state_to_str(sfp->sm_mod_state), -+ dev_state_to_str(sfp->sm_dev_state), -+ sm_state_to_str(sfp->sm_state), -+ event_to_str(event)); -+ -+ sfp_sm_module(sfp, event); -+ sfp_sm_device(sfp, event); -+ sfp_sm_main(sfp, event); - - dev_dbg(sfp->dev, "SM: exit %s:%s:%s\n", - mod_state_to_str(sfp->sm_mod_state), diff --git a/target/linux/generic/backport-4.19/721-v5.5-net-sfp-move-tx-disable-on-device-down-to-main-state.patch b/target/linux/generic/backport-4.19/721-v5.5-net-sfp-move-tx-disable-on-device-down-to-main-state.patch deleted file mode 100644 index 5b3caaf0fd..0000000000 --- a/target/linux/generic/backport-4.19/721-v5.5-net-sfp-move-tx-disable-on-device-down-to-main-state.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 7e89b737c97a9e7a81dd1584000bc136b92f12fd Mon Sep 17 00:00:00 2001 -From: Russell King <rmk+kernel@armlinux.org.uk> -Date: Fri, 11 Oct 2019 22:14:47 +0100 -Subject: [PATCH 619/660] net: sfp: move tx disable on device down to main - state machine - -Move the tx disable assertion on device down to the main state -machine. - -Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> ---- - drivers/net/phy/sfp.c | 10 ++-------- - 1 file changed, 2 insertions(+), 8 deletions(-) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -1489,15 +1489,8 @@ static void sfp_sm_device(struct sfp *sf - break; - - case SFP_DEV_UP: -- if (event == SFP_E_DEV_DOWN) { -- /* If the module has a PHY, avoid raising TX disable -- * as this resets the PHY. Otherwise, raise it to -- * turn the laser off. -- */ -- if (!sfp->mod_phy) -- sfp_module_tx_disable(sfp); -+ if (event == SFP_E_DEV_DOWN) - sfp->sm_dev_state = SFP_DEV_DOWN; -- } - break; - } - } -@@ -1559,6 +1552,7 @@ static void sfp_sm_main(struct sfp *sfp, - sfp_sm_link_down(sfp); - if (sfp->mod_phy) - sfp_sm_phy_detach(sfp); -+ sfp_module_tx_disable(sfp); - sfp_sm_next(sfp, SFP_S_DOWN, 0); - return; - } diff --git a/target/linux/generic/backport-4.19/722-v5.5-net-sfp-rename-sfp_sm_ins_next-as-sfp_sm_mod_next.patch b/target/linux/generic/backport-4.19/722-v5.5-net-sfp-rename-sfp_sm_ins_next-as-sfp_sm_mod_next.patch deleted file mode 100644 index ed84e76fdf..0000000000 --- a/target/linux/generic/backport-4.19/722-v5.5-net-sfp-rename-sfp_sm_ins_next-as-sfp_sm_mod_next.patch +++ /dev/null @@ -1,71 +0,0 @@ -From f2a1ccfc4ad4f97c98c3cc18eb32992151ce089a Mon Sep 17 00:00:00 2001 -From: Russell King <rmk+kernel@armlinux.org.uk> -Date: Fri, 11 Oct 2019 22:27:21 +0100 -Subject: [PATCH 620/660] net: sfp: rename sfp_sm_ins_next() as - sfp_sm_mod_next() - -sfp_sm_ins_next() modifies the module state machine. Change it's name -to reflect this. - -Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> ---- - drivers/net/phy/sfp.c | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -1180,7 +1180,7 @@ static void sfp_sm_next(struct sfp *sfp, - sfp_sm_set_timer(sfp, timeout); - } - --static void sfp_sm_ins_next(struct sfp *sfp, unsigned int state, -+static void sfp_sm_mod_next(struct sfp *sfp, unsigned int state, - unsigned int timeout) - { - sfp->sm_mod_state = state; -@@ -1504,22 +1504,22 @@ static void sfp_sm_module(struct sfp *sf - default: - if (event == SFP_E_INSERT && sfp->attached) { - sfp_module_tx_disable(sfp); -- sfp_sm_ins_next(sfp, SFP_MOD_PROBE, T_PROBE_INIT); -+ sfp_sm_mod_next(sfp, SFP_MOD_PROBE, T_PROBE_INIT); - } - break; - - case SFP_MOD_PROBE: - if (event == SFP_E_REMOVE) { -- sfp_sm_ins_next(sfp, SFP_MOD_EMPTY, 0); -+ sfp_sm_mod_next(sfp, SFP_MOD_EMPTY, 0); - } else if (event == SFP_E_TIMEOUT) { - int val = sfp_sm_mod_probe(sfp); - - if (val == 0) -- sfp_sm_ins_next(sfp, SFP_MOD_PRESENT, 0); -+ sfp_sm_mod_next(sfp, SFP_MOD_PRESENT, 0); - else if (val > 0) -- sfp_sm_ins_next(sfp, SFP_MOD_HPOWER, val); -+ sfp_sm_mod_next(sfp, SFP_MOD_HPOWER, val); - else if (val != -EAGAIN) -- sfp_sm_ins_next(sfp, SFP_MOD_ERROR, 0); -+ sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0); - else - sfp_sm_set_timer(sfp, T_PROBE_RETRY); - } -@@ -1527,7 +1527,7 @@ static void sfp_sm_module(struct sfp *sf - - case SFP_MOD_HPOWER: - if (event == SFP_E_TIMEOUT) { -- sfp_sm_ins_next(sfp, SFP_MOD_PRESENT, 0); -+ sfp_sm_mod_next(sfp, SFP_MOD_PRESENT, 0); - break; - } - /* fallthrough */ -@@ -1535,7 +1535,7 @@ static void sfp_sm_module(struct sfp *sf - case SFP_MOD_ERROR: - if (event == SFP_E_REMOVE) { - sfp_sm_mod_remove(sfp); -- sfp_sm_ins_next(sfp, SFP_MOD_EMPTY, 0); -+ sfp_sm_mod_next(sfp, SFP_MOD_EMPTY, 0); - } - break; - } diff --git a/target/linux/generic/backport-4.19/723-v5.5-net-sfp-handle-module-remove-outside-state-machine.patch b/target/linux/generic/backport-4.19/723-v5.5-net-sfp-handle-module-remove-outside-state-machine.patch deleted file mode 100644 index 542aeaea77..0000000000 --- a/target/linux/generic/backport-4.19/723-v5.5-net-sfp-handle-module-remove-outside-state-machine.patch +++ /dev/null @@ -1,53 +0,0 @@ -From d2591ea5520e2ee8fa557f96bb64c23cafac4b20 Mon Sep 17 00:00:00 2001 -From: Russell King <rmk+kernel@armlinux.org.uk> -Date: Tue, 15 Oct 2019 10:33:13 +0100 -Subject: [PATCH 621/660] net: sfp: handle module remove outside state machine - -Removing a module resets the module state machine back to its initial -state. Rather than explicitly handling this in every state, handle it -early on outside of the state machine. - -Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> ---- - drivers/net/phy/sfp.c | 16 +++++++++------- - 1 file changed, 9 insertions(+), 7 deletions(-) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -1500,6 +1500,14 @@ static void sfp_sm_device(struct sfp *sf - */ - static void sfp_sm_module(struct sfp *sfp, unsigned int event) - { -+ /* Handle remove event globally, it resets this state machine */ -+ if (event == SFP_E_REMOVE) { -+ if (sfp->sm_mod_state > SFP_MOD_PROBE) -+ sfp_sm_mod_remove(sfp); -+ sfp_sm_mod_next(sfp, SFP_MOD_EMPTY, 0); -+ return; -+ } -+ - switch (sfp->sm_mod_state) { - default: - if (event == SFP_E_INSERT && sfp->attached) { -@@ -1509,9 +1517,7 @@ static void sfp_sm_module(struct sfp *sf - break; - - case SFP_MOD_PROBE: -- if (event == SFP_E_REMOVE) { -- sfp_sm_mod_next(sfp, SFP_MOD_EMPTY, 0); -- } else if (event == SFP_E_TIMEOUT) { -+ if (event == SFP_E_TIMEOUT) { - int val = sfp_sm_mod_probe(sfp); - - if (val == 0) -@@ -1533,10 +1539,6 @@ static void sfp_sm_module(struct sfp *sf - /* fallthrough */ - case SFP_MOD_PRESENT: - case SFP_MOD_ERROR: -- if (event == SFP_E_REMOVE) { -- sfp_sm_mod_remove(sfp); -- sfp_sm_mod_next(sfp, SFP_MOD_EMPTY, 0); -- } - break; - } - } diff --git a/target/linux/generic/backport-4.19/724-v5.5-net-sfp-rename-T_PROBE_WAIT-to-T_SERIAL.patch b/target/linux/generic/backport-4.19/724-v5.5-net-sfp-rename-T_PROBE_WAIT-to-T_SERIAL.patch deleted file mode 100644 index e0c35feea3..0000000000 --- a/target/linux/generic/backport-4.19/724-v5.5-net-sfp-rename-T_PROBE_WAIT-to-T_SERIAL.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 615090acb3c0b41691f3a03522ea38350387c0e4 Mon Sep 17 00:00:00 2001 -From: Russell King <rmk+kernel@armlinux.org.uk> -Date: Tue, 15 Oct 2019 10:54:15 +0100 -Subject: [PATCH 622/660] net: sfp: rename T_PROBE_WAIT to T_SERIAL - -SFF-8472 rev 12.2 defines the time for the serial bus to become ready -using t_serial. Use this as our identifier for this timeout to make -it clear what we are referring to. - -Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> ---- - drivers/net/phy/sfp.c | 13 ++++++------- - 1 file changed, 6 insertions(+), 7 deletions(-) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -147,11 +147,10 @@ static const enum gpiod_flags gpio_flags - * the same length on the PCB, which means it's possible for MOD DEF 0 to - * connect before the I2C bus on MOD DEF 1/2. - * -- * The SFP MSA specifies 300ms as t_init (the time taken for TX_FAULT to -- * be deasserted) but makes no mention of the earliest time before we can -- * access the I2C EEPROM. However, Avago modules require 300ms. -+ * 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. - */ --#define T_PROBE_INIT msecs_to_jiffies(300) -+#define T_SERIAL msecs_to_jiffies(300) - #define T_HPOWER_LEVEL msecs_to_jiffies(300) - #define T_PROBE_RETRY msecs_to_jiffies(100) - -@@ -1495,8 +1494,8 @@ static void sfp_sm_device(struct sfp *sf - } - } - --/* This state machine tracks the insert/remove state of -- * the module, and handles probing the on-board EEPROM. -+/* This state machine tracks the insert/remove state of the module, probes -+ * the on-board EEPROM, and sets up the power level. - */ - static void sfp_sm_module(struct sfp *sfp, unsigned int event) - { -@@ -1512,7 +1511,7 @@ static void sfp_sm_module(struct sfp *sf - default: - if (event == SFP_E_INSERT && sfp->attached) { - sfp_module_tx_disable(sfp); -- sfp_sm_mod_next(sfp, SFP_MOD_PROBE, T_PROBE_INIT); -+ sfp_sm_mod_next(sfp, SFP_MOD_PROBE, T_SERIAL); - } - break; - diff --git a/target/linux/generic/backport-4.19/725-v5.5-net-sfp-parse-SFP-power-requirement-earlier.patch b/target/linux/generic/backport-4.19/725-v5.5-net-sfp-parse-SFP-power-requirement-earlier.patch deleted file mode 100644 index 0b358f86d2..0000000000 --- a/target/linux/generic/backport-4.19/725-v5.5-net-sfp-parse-SFP-power-requirement-earlier.patch +++ /dev/null @@ -1,115 +0,0 @@ -From d4b8746219e8c0361e5ed6e440ab3a8a600d1f76 Mon Sep 17 00:00:00 2001 -From: Russell King <rmk+kernel@armlinux.org.uk> -Date: Fri, 11 Oct 2019 17:24:40 +0100 -Subject: [PATCH 623/660] net: sfp: parse SFP power requirement earlier - -Parse the SFP power requirement earlier, in preparation for moving the -power level setup code. - -Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> ---- - drivers/net/phy/sfp.c | 42 +++++++++++++++++++++++++++++------------- - 1 file changed, 29 insertions(+), 13 deletions(-) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -196,6 +196,8 @@ struct sfp { - unsigned int sm_retries; - - struct sfp_eeprom_id id; -+ unsigned int module_power_mW; -+ - #if IS_ENABLED(CONFIG_HWMON) - struct sfp_diag diag; - struct device *hwmon_dev; -@@ -1309,17 +1311,14 @@ static void sfp_sm_mod_init(struct sfp * - sfp_sm_probe_phy(sfp); - } - --static int sfp_sm_mod_hpower(struct sfp *sfp) -+static int sfp_module_parse_power(struct sfp *sfp) - { -- u32 power; -- u8 val; -- int err; -+ u32 power_mW = 1000; - -- power = 1000; - if (sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_POWER_DECL)) -- power = 1500; -+ power_mW = 1500; - if (sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_HIGH_POWER_LEVEL)) -- power = 2000; -+ power_mW = 2000; - - if (sfp->id.ext.sff8472_compliance == SFP_SFF8472_COMPLIANCE_NONE && - (sfp->id.ext.diagmon & (SFP_DIAGMON_DDM | SFP_DIAGMON_ADDRMODE)) != -@@ -1328,23 +1327,33 @@ static int sfp_sm_mod_hpower(struct sfp - * or requires an address change sequence, so assume that - * the module powers up in the indicated power mode. - */ -- if (power > sfp->max_power_mW) { -+ if (power_mW > sfp->max_power_mW) { - dev_err(sfp->dev, - "Host does not support %u.%uW modules\n", -- power / 1000, (power / 100) % 10); -+ power_mW / 1000, (power_mW / 100) % 10); - return -EINVAL; - } - return 0; - } - -- if (power > sfp->max_power_mW) { -+ if (power_mW > sfp->max_power_mW) { - dev_warn(sfp->dev, - "Host does not support %u.%uW modules, module left in power mode 1\n", -- power / 1000, (power / 100) % 10); -+ power_mW / 1000, (power_mW / 100) % 10); - return 0; - } - -- if (power <= 1000) -+ sfp->module_power_mW = power_mW; -+ -+ return 0; -+} -+ -+static int sfp_sm_mod_hpower(struct sfp *sfp) -+{ -+ u8 val; -+ int err; -+ -+ if (sfp->module_power_mW <= 1000) - return 0; - - err = sfp_read(sfp, true, SFP_EXT_STATUS, &val, sizeof(val)); -@@ -1364,7 +1373,8 @@ static int sfp_sm_mod_hpower(struct sfp - } - - dev_info(sfp->dev, "Module switched to %u.%uW power level\n", -- power / 1000, (power / 100) % 10); -+ sfp->module_power_mW / 1000, -+ (sfp->module_power_mW / 100) % 10); - return T_HPOWER_LEVEL; - - err: -@@ -1451,6 +1461,11 @@ static int sfp_sm_mod_probe(struct sfp * - dev_warn(sfp->dev, - "module address swap to access page 0xA2 is not supported.\n"); - -+ /* Parse the module power requirement */ -+ ret = sfp_module_parse_power(sfp); -+ if (ret < 0) -+ return ret; -+ - ret = sfp_hwmon_insert(sfp); - if (ret < 0) - return ret; -@@ -1474,6 +1489,7 @@ static void sfp_sm_mod_remove(struct sfp - sfp_module_tx_disable(sfp); - - memset(&sfp->id, 0, sizeof(sfp->id)); -+ sfp->module_power_mW = 0; - - dev_info(sfp->dev, "module removed\n"); - } diff --git a/target/linux/generic/backport-4.19/726-v5.5-net-sfp-avoid-power-switch-on-address-change-modules.patch b/target/linux/generic/backport-4.19/726-v5.5-net-sfp-avoid-power-switch-on-address-change-modules.patch deleted file mode 100644 index 2ddd4c4d02..0000000000 --- a/target/linux/generic/backport-4.19/726-v5.5-net-sfp-avoid-power-switch-on-address-change-modules.patch +++ /dev/null @@ -1,65 +0,0 @@ -From dca678b8838945572cf50584cb33a7199c1fd397 Mon Sep 17 00:00:00 2001 -From: Russell King <rmk+kernel@armlinux.org.uk> -Date: Thu, 17 Oct 2019 00:24:18 +0100 -Subject: [PATCH 624/660] net: sfp: avoid power switch on address-change - modules - -If the module indicates that it requires an address change sequence to -switch between address 0x50 and 0x51, which we don't support, we can't -write to the register that controls the power mode to switch to high -power mode. Warn the user that the module may not be functional in -this case, and don't try to change the power mode. - -Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> ---- - drivers/net/phy/sfp.c | 31 ++++++++++++++++++++----------- - 1 file changed, 20 insertions(+), 11 deletions(-) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -1320,25 +1320,34 @@ static int sfp_module_parse_power(struct - if (sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_HIGH_POWER_LEVEL)) - power_mW = 2000; - -- if (sfp->id.ext.sff8472_compliance == SFP_SFF8472_COMPLIANCE_NONE && -- (sfp->id.ext.diagmon & (SFP_DIAGMON_DDM | SFP_DIAGMON_ADDRMODE)) != -- SFP_DIAGMON_DDM) { -- /* The module appears not to implement bus address 0xa2, -- * or requires an address change sequence, so assume that -- * the module powers up in the indicated power mode. -- */ -- if (power_mW > sfp->max_power_mW) { -+ if (power_mW > sfp->max_power_mW) { -+ /* Module power specification exceeds the allowed maximum. */ -+ if (sfp->id.ext.sff8472_compliance == -+ SFP_SFF8472_COMPLIANCE_NONE && -+ !(sfp->id.ext.diagmon & SFP_DIAGMON_DDM)) { -+ /* The module appears not to implement bus address -+ * 0xa2, so assume that the module powers up in the -+ * indicated mode. -+ */ - dev_err(sfp->dev, - "Host does not support %u.%uW modules\n", - power_mW / 1000, (power_mW / 100) % 10); - return -EINVAL; -+ } else { -+ dev_warn(sfp->dev, -+ "Host does not support %u.%uW modules, module left in power mode 1\n", -+ power_mW / 1000, (power_mW / 100) % 10); -+ return 0; - } -- return 0; - } - -- if (power_mW > sfp->max_power_mW) { -+ /* If the module requires a higher power mode, but also requires -+ * an address change sequence, warn the user that the module may -+ * not be functional. -+ */ -+ if (sfp->id.ext.diagmon & SFP_DIAGMON_ADDRMODE && power_mW > 1000) { - dev_warn(sfp->dev, -- "Host does not support %u.%uW modules, module left in power mode 1\n", -+ "Address Change Sequence not supported but module requies %u.%uW, module may not be functional\n", - power_mW / 1000, (power_mW / 100) % 10); - return 0; - } diff --git a/target/linux/generic/backport-4.19/727-v5.5-net-sfp-control-TX_DISABLE-and-phy-only-from-main-st.patch b/target/linux/generic/backport-4.19/727-v5.5-net-sfp-control-TX_DISABLE-and-phy-only-from-main-st.patch deleted file mode 100644 index 0eac6abb88..0000000000 --- a/target/linux/generic/backport-4.19/727-v5.5-net-sfp-control-TX_DISABLE-and-phy-only-from-main-st.patch +++ /dev/null @@ -1,52 +0,0 @@ -From df5c4d93c5a59cba0f7479a4cd4e22b50726ce88 Mon Sep 17 00:00:00 2001 -From: Russell King <rmk+kernel@armlinux.org.uk> -Date: Thu, 17 Oct 2019 11:12:42 +0100 -Subject: [PATCH 625/660] net: sfp: control TX_DISABLE and phy only from main - state machine - -We initialise TX_DISABLE when the sfp cage is probed, and then -maintain its state in the main state machine. However, the module -state machine: -- negates it when detecting a newly inserted module when it's already - guaranteed to be negated. -- negates it when the module is removed, but the main state machine - will do this anyway. - -Make TX_DISABLE entirely controlled by the main state machine. - -The main state machine also probes the module for a PHY, and removes -the PHY when the the module is removed. Hence, removing the PHY in -sfp_sm_module_remove() is also redundant, and is a left-over from -when we tried to probe for the PHY from the module state machine. - -Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> ---- - drivers/net/phy/sfp.c | 9 +-------- - 1 file changed, 1 insertion(+), 8 deletions(-) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -1492,11 +1492,6 @@ static void sfp_sm_mod_remove(struct sfp - - sfp_hwmon_remove(sfp); - -- if (sfp->mod_phy) -- sfp_sm_phy_detach(sfp); -- -- sfp_module_tx_disable(sfp); -- - memset(&sfp->id, 0, sizeof(sfp->id)); - sfp->module_power_mW = 0; - -@@ -1534,10 +1529,8 @@ static void sfp_sm_module(struct sfp *sf - - switch (sfp->sm_mod_state) { - default: -- if (event == SFP_E_INSERT && sfp->attached) { -- sfp_module_tx_disable(sfp); -+ if (event == SFP_E_INSERT && sfp->attached) - sfp_sm_mod_next(sfp, SFP_MOD_PROBE, T_SERIAL); -- } - break; - - case SFP_MOD_PROBE: diff --git a/target/linux/generic/backport-4.19/728-v5.5-net-sfp-split-the-PHY-probe-from-sfp_sm_mod_init.patch b/target/linux/generic/backport-4.19/728-v5.5-net-sfp-split-the-PHY-probe-from-sfp_sm_mod_init.patch deleted file mode 100644 index 7830b9268f..0000000000 --- a/target/linux/generic/backport-4.19/728-v5.5-net-sfp-split-the-PHY-probe-from-sfp_sm_mod_init.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 5ed0bd49b2d3ac4439c2d7f44e5a82b7cf6f409a Mon Sep 17 00:00:00 2001 -From: Russell King <rmk+kernel@armlinux.org.uk> -Date: Fri, 18 Oct 2019 10:09:02 +0100 -Subject: [PATCH 626/660] net: sfp: split the PHY probe from sfp_sm_mod_init() - -Move the PHY probe into a separate function, splitting it from -sfp_sm_mod_init(). This will allow us to eliminate the 50ms mdelay() -inside the state machine. - -Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> ---- - drivers/net/phy/sfp.c | 21 +++++++++++++-------- - 1 file changed, 13 insertions(+), 8 deletions(-) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -1288,14 +1288,10 @@ static void sfp_sm_fault(struct sfp *sfp - static void sfp_sm_mod_init(struct sfp *sfp) - { - sfp_module_tx_enable(sfp); -+} - -- /* Wait t_init before indicating that the link is up, provided the -- * current state indicates no TX_FAULT. If TX_FAULT clears before -- * this time, that's fine too. -- */ -- sfp_sm_next(sfp, SFP_S_INIT, T_INIT_JIFFIES); -- sfp->sm_retries = 5; -- -+static void sfp_sm_probe_for_phy(struct sfp *sfp) -+{ - /* Setting the serdes link mode is guesswork: there's no - * field in the EEPROM which indicates what mode should - * be used. -@@ -1580,8 +1576,17 @@ static void sfp_sm_main(struct sfp *sfp, - switch (sfp->sm_state) { - case SFP_S_DOWN: - if (sfp->sm_mod_state == SFP_MOD_PRESENT && -- sfp->sm_dev_state == SFP_DEV_UP) -+ sfp->sm_dev_state == SFP_DEV_UP) { - sfp_sm_mod_init(sfp); -+ sfp_sm_probe_for_phy(sfp); -+ -+ /* Wait t_init before indicating that the link is up, -+ * provided the current state indicates no TX_FAULT. If -+ * TX_FAULT clears before this time, that's fine too. -+ */ -+ sfp_sm_next(sfp, SFP_S_INIT, T_INIT_JIFFIES); -+ sfp->sm_retries = 5; -+ } - break; - - case SFP_S_INIT: diff --git a/target/linux/generic/backport-4.19/729-v5.5-net-sfp-eliminate-mdelay-from-PHY-probe.patch b/target/linux/generic/backport-4.19/729-v5.5-net-sfp-eliminate-mdelay-from-PHY-probe.patch deleted file mode 100644 index 5dc92bd10e..0000000000 --- a/target/linux/generic/backport-4.19/729-v5.5-net-sfp-eliminate-mdelay-from-PHY-probe.patch +++ /dev/null @@ -1,130 +0,0 @@ -From 0fe72afaa31f98ebd71bd6683fc47021105d0157 Mon Sep 17 00:00:00 2001 -From: Russell King <rmk+kernel@armlinux.org.uk> -Date: Fri, 18 Oct 2019 10:21:46 +0100 -Subject: [PATCH 627/660] net: sfp: eliminate mdelay() from PHY probe - -Rather than using mdelay() to wait before probing the PHY (which holds -several locks, including the rtnl lock), add an extra wait state to -the state machine to introduce the 50ms delay without holding any -locks. - -Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> ---- - drivers/net/phy/sfp.c | 52 +++++++++++++++++++++++++++++++++---------- - 1 file changed, 40 insertions(+), 12 deletions(-) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -52,6 +52,7 @@ enum { - SFP_DEV_UP, - - SFP_S_DOWN = 0, -+ SFP_S_WAIT, - SFP_S_INIT, - SFP_S_WAIT_LOS, - SFP_S_LINK_UP, -@@ -108,6 +109,7 @@ static const char *event_to_str(unsigned - - static const char * const sm_state_strings[] = { - [SFP_S_DOWN] = "down", -+ [SFP_S_WAIT] = "wait", - [SFP_S_INIT] = "init", - [SFP_S_WAIT_LOS] = "wait_los", - [SFP_S_LINK_UP] = "link_up", -@@ -139,6 +141,7 @@ static const enum gpiod_flags gpio_flags - GPIOD_ASIS, - }; - -+#define T_WAIT msecs_to_jiffies(50) - #define T_INIT_JIFFIES msecs_to_jiffies(300) - #define T_RESET_US 10 - #define T_FAULT_RECOVER msecs_to_jiffies(1000) -@@ -159,9 +162,6 @@ static const enum gpiod_flags gpio_flags - */ - #define SFP_PHY_ADDR 22 - --/* Give this long for the PHY to reset. */ --#define T_PHY_RESET_MS 50 -- - struct sff_data { - unsigned int gpios; - bool (*module_supported)(const struct sfp_eeprom_id *id); -@@ -1202,8 +1202,6 @@ static void sfp_sm_probe_phy(struct sfp - struct phy_device *phy; - int err; - -- msleep(T_PHY_RESET_MS); -- - phy = mdiobus_scan(sfp->i2c_mii, SFP_PHY_ADDR); - if (phy == ERR_PTR(-ENODEV)) { - dev_info(sfp->dev, "no PHY detected\n"); -@@ -1558,6 +1556,8 @@ static void sfp_sm_module(struct sfp *sf - - static void sfp_sm_main(struct sfp *sfp, unsigned int event) - { -+ unsigned long timeout; -+ - /* Some events are global */ - if (sfp->sm_state != SFP_S_DOWN && - (sfp->sm_mod_state != SFP_MOD_PRESENT || -@@ -1575,17 +1575,45 @@ static void sfp_sm_main(struct sfp *sfp, - /* The main state machine */ - switch (sfp->sm_state) { - case SFP_S_DOWN: -- if (sfp->sm_mod_state == SFP_MOD_PRESENT && -- sfp->sm_dev_state == SFP_DEV_UP) { -- sfp_sm_mod_init(sfp); -- sfp_sm_probe_for_phy(sfp); -+ if (sfp->sm_mod_state != SFP_MOD_PRESENT || -+ sfp->sm_dev_state != SFP_DEV_UP) -+ break; -+ -+ sfp_sm_mod_init(sfp); -+ -+ /* Initialise the fault clearance retries */ -+ sfp->sm_retries = 5; -+ -+ /* We need to check the TX_FAULT state, which is not defined -+ * while TX_DISABLE is asserted. The earliest we want to do -+ * anything (such as probe for a PHY) is 50ms. -+ */ -+ sfp_sm_next(sfp, SFP_S_WAIT, T_WAIT); -+ break; -+ -+ case SFP_S_WAIT: -+ if (event != SFP_E_TIMEOUT) -+ break; -+ -+ sfp_sm_probe_for_phy(sfp); - -+ if (sfp->state & SFP_F_TX_FAULT) { - /* Wait t_init before indicating that the link is up, - * provided the current state indicates no TX_FAULT. If - * TX_FAULT clears before this time, that's fine too. - */ -- sfp_sm_next(sfp, SFP_S_INIT, T_INIT_JIFFIES); -- sfp->sm_retries = 5; -+ timeout = T_INIT_JIFFIES; -+ if (timeout > T_WAIT) -+ timeout -= T_WAIT; -+ else -+ timeout = 1; -+ -+ sfp_sm_next(sfp, SFP_S_INIT, timeout); -+ } else { -+ /* TX_FAULT is not asserted, assume the module has -+ * finished initialising. -+ */ -+ goto init_done; - } - break; - -@@ -1593,7 +1621,7 @@ static void sfp_sm_main(struct sfp *sfp, - if (event == SFP_E_TIMEOUT && sfp->state & SFP_F_TX_FAULT) - sfp_sm_fault(sfp, true); - else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) -- sfp_sm_link_check_los(sfp); -+ init_done: sfp_sm_link_check_los(sfp); - break; - - case SFP_S_WAIT_LOS: diff --git a/target/linux/generic/backport-4.19/730-v5.5-net-sfp-allow-fault-processing-to-transition-to-othe.patch b/target/linux/generic/backport-4.19/730-v5.5-net-sfp-allow-fault-processing-to-transition-to-othe.patch deleted file mode 100644 index 6e34e6cc0f..0000000000 --- a/target/linux/generic/backport-4.19/730-v5.5-net-sfp-allow-fault-processing-to-transition-to-othe.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 2aa424ee7fbe43e2cd24e28c2f6388c4e1796bd2 Mon Sep 17 00:00:00 2001 -From: Russell King <rmk+kernel@armlinux.org.uk> -Date: Fri, 18 Oct 2019 09:58:33 +0100 -Subject: [PATCH 628/660] net: sfp: allow fault processing to transition to - other states - -Add the next state to sfp_sm_fault() so that it can branch to other -states. This will be necessary to improve the initialisation path. - -Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> ---- - drivers/net/phy/sfp.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -1269,7 +1269,7 @@ static bool sfp_los_event_inactive(struc - event == SFP_E_LOS_LOW); - } - --static void sfp_sm_fault(struct sfp *sfp, bool warn) -+static void sfp_sm_fault(struct sfp *sfp, unsigned int next_state, bool warn) - { - if (sfp->sm_retries && !--sfp->sm_retries) { - dev_err(sfp->dev, -@@ -1279,7 +1279,7 @@ static void sfp_sm_fault(struct sfp *sfp - if (warn) - dev_err(sfp->dev, "module transmit fault indicated\n"); - -- sfp_sm_next(sfp, SFP_S_TX_FAULT, T_FAULT_RECOVER); -+ sfp_sm_next(sfp, next_state, T_FAULT_RECOVER); - } - } - -@@ -1619,14 +1619,14 @@ static void sfp_sm_main(struct sfp *sfp, - - case SFP_S_INIT: - if (event == SFP_E_TIMEOUT && sfp->state & SFP_F_TX_FAULT) -- sfp_sm_fault(sfp, true); -+ sfp_sm_fault(sfp, SFP_S_TX_FAULT, true); - else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) - init_done: sfp_sm_link_check_los(sfp); - break; - - case SFP_S_WAIT_LOS: - if (event == SFP_E_TX_FAULT) -- sfp_sm_fault(sfp, true); -+ sfp_sm_fault(sfp, SFP_S_TX_FAULT, true); - else if (sfp_los_event_inactive(sfp, event)) - sfp_sm_link_up(sfp); - break; -@@ -1634,7 +1634,7 @@ static void sfp_sm_main(struct sfp *sfp, - case SFP_S_LINK_UP: - if (event == SFP_E_TX_FAULT) { - sfp_sm_link_down(sfp); -- sfp_sm_fault(sfp, true); -+ sfp_sm_fault(sfp, SFP_S_TX_FAULT, true); - } else if (sfp_los_event_active(sfp, event)) { - sfp_sm_link_down(sfp); - sfp_sm_next(sfp, SFP_S_WAIT_LOS, 0); -@@ -1650,7 +1650,7 @@ static void sfp_sm_main(struct sfp *sfp, - - case SFP_S_REINIT: - if (event == SFP_E_TIMEOUT && sfp->state & SFP_F_TX_FAULT) { -- sfp_sm_fault(sfp, false); -+ sfp_sm_fault(sfp, SFP_S_TX_FAULT, false); - } else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) { - dev_info(sfp->dev, "module transmit fault recovered\n"); - sfp_sm_link_check_los(sfp); diff --git a/target/linux/generic/backport-4.19/731-v5.5-net-sfp-ensure-TX_FAULT-has-deasserted-before-probin.patch b/target/linux/generic/backport-4.19/731-v5.5-net-sfp-ensure-TX_FAULT-has-deasserted-before-probin.patch deleted file mode 100644 index 03415fb6e7..0000000000 --- a/target/linux/generic/backport-4.19/731-v5.5-net-sfp-ensure-TX_FAULT-has-deasserted-before-probin.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 38b62a12231be4b86fc5ca5477579d29831c02a5 Mon Sep 17 00:00:00 2001 -From: Russell King <rmk+kernel@armlinux.org.uk> -Date: Fri, 18 Oct 2019 10:31:07 +0100 -Subject: [PATCH 629/660] net: sfp: ensure TX_FAULT has deasserted before - probing the PHY - -TX_FAULT should be deasserted to indicate that the module has completed -its initialisation. This may include the on-board PHY, so wait until -the module has deasserted TX_FAULT before probing the PHY. - -This means that we need an extra state to handle a TX_FAULT that -remains set for longer than t_init, since using the existing handling -state would bypass the PHY probe. - -Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> ---- - drivers/net/phy/sfp.c | 31 +++++++++++++++++++++++++------ - 1 file changed, 25 insertions(+), 6 deletions(-) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -54,6 +54,7 @@ enum { - SFP_S_DOWN = 0, - SFP_S_WAIT, - SFP_S_INIT, -+ SFP_S_INIT_TX_FAULT, - SFP_S_WAIT_LOS, - SFP_S_LINK_UP, - SFP_S_TX_FAULT, -@@ -111,6 +112,7 @@ static const char * const sm_state_strin - [SFP_S_DOWN] = "down", - [SFP_S_WAIT] = "wait", - [SFP_S_INIT] = "init", -+ [SFP_S_INIT_TX_FAULT] = "init_tx_fault", - [SFP_S_WAIT_LOS] = "wait_los", - [SFP_S_LINK_UP] = "link_up", - [SFP_S_TX_FAULT] = "tx_fault", -@@ -1595,8 +1597,6 @@ static void sfp_sm_main(struct sfp *sfp, - if (event != SFP_E_TIMEOUT) - break; - -- sfp_sm_probe_for_phy(sfp); -- - if (sfp->state & SFP_F_TX_FAULT) { - /* Wait t_init before indicating that the link is up, - * provided the current state indicates no TX_FAULT. If -@@ -1618,10 +1618,29 @@ static void sfp_sm_main(struct sfp *sfp, - break; - - case SFP_S_INIT: -- if (event == SFP_E_TIMEOUT && sfp->state & SFP_F_TX_FAULT) -- sfp_sm_fault(sfp, SFP_S_TX_FAULT, true); -- else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) -- init_done: sfp_sm_link_check_los(sfp); -+ if (event == SFP_E_TIMEOUT && sfp->state & SFP_F_TX_FAULT) { -+ /* TX_FAULT is still asserted after t_init, so assume -+ * there is a fault. -+ */ -+ sfp_sm_fault(sfp, SFP_S_INIT_TX_FAULT, -+ sfp->sm_retries == 5); -+ } else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) { -+ init_done: /* TX_FAULT deasserted or we timed out with TX_FAULT -+ * clear. Probe for the PHY and check the LOS state. -+ */ -+ sfp_sm_probe_for_phy(sfp); -+ sfp_sm_link_check_los(sfp); -+ -+ /* Reset the fault retry count */ -+ sfp->sm_retries = 5; -+ } -+ break; -+ -+ case SFP_S_INIT_TX_FAULT: -+ if (event == SFP_E_TIMEOUT) { -+ sfp_module_tx_fault_reset(sfp); -+ sfp_sm_next(sfp, SFP_S_INIT, T_INIT_JIFFIES); -+ } - break; - - case SFP_S_WAIT_LOS: diff --git a/target/linux/generic/backport-4.19/732-v5.5-net-sfp-track-upstream-s-attachment-state-in-state-m.patch b/target/linux/generic/backport-4.19/732-v5.5-net-sfp-track-upstream-s-attachment-state-in-state-m.patch deleted file mode 100644 index 5ee44dbf0c..0000000000 --- a/target/linux/generic/backport-4.19/732-v5.5-net-sfp-track-upstream-s-attachment-state-in-state-m.patch +++ /dev/null @@ -1,153 +0,0 @@ -From ec6036a58f979c66bbd5cd9d0d1c783a98c2c644 Mon Sep 17 00:00:00 2001 -From: Russell King <rmk+kernel@armlinux.org.uk> -Date: Tue, 5 Nov 2019 12:57:40 +0000 -Subject: [PATCH 630/660] net: sfp: track upstream's attachment state in state - machine - -Track the upstream's attachment state in the state machine rather than -maintaining a boolean, which ensures that we have a strict order of -ATTACH followed by an UP event - we can never believe that a newly -attached upstream will be anything but down. - -Rearrange the order of state machines so we run the module state -machine after the upstream device's state machine, so the module state -machine can check the current state of the device and take action to -e.g. reset back to empty state when the upstream is detached. - -This is to allow the module detection to run independently of the -network device becoming available. - -Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> ---- - drivers/net/phy/sfp.c | 42 +++++++++++++++++++++++++++++------------- - 1 file changed, 29 insertions(+), 13 deletions(-) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -34,6 +34,8 @@ enum { - - SFP_E_INSERT = 0, - SFP_E_REMOVE, -+ SFP_E_DEV_ATTACH, -+ SFP_E_DEV_DETACH, - SFP_E_DEV_DOWN, - SFP_E_DEV_UP, - SFP_E_TX_FAULT, -@@ -48,7 +50,8 @@ enum { - SFP_MOD_PRESENT, - SFP_MOD_ERROR, - -- SFP_DEV_DOWN = 0, -+ SFP_DEV_DETACHED = 0, -+ SFP_DEV_DOWN, - SFP_DEV_UP, - - SFP_S_DOWN = 0, -@@ -78,6 +81,7 @@ static const char *mod_state_to_str(unsi - } - - static const char * const dev_state_strings[] = { -+ [SFP_DEV_DETACHED] = "detached", - [SFP_DEV_DOWN] = "down", - [SFP_DEV_UP] = "up", - }; -@@ -92,6 +96,8 @@ static const char *dev_state_to_str(unsi - static const char * const event_strings[] = { - [SFP_E_INSERT] = "insert", - [SFP_E_REMOVE] = "remove", -+ [SFP_E_DEV_ATTACH] = "dev_attach", -+ [SFP_E_DEV_DETACH] = "dev_detach", - [SFP_E_DEV_DOWN] = "dev_down", - [SFP_E_DEV_UP] = "dev_up", - [SFP_E_TX_FAULT] = "tx_fault", -@@ -186,7 +192,6 @@ struct sfp { - struct gpio_desc *gpio[GPIO_MAX]; - int gpio_irq[GPIO_MAX]; - -- bool attached; - struct mutex st_mutex; /* Protects state */ - unsigned int state; - struct delayed_work poll; -@@ -1494,17 +1499,26 @@ static void sfp_sm_mod_remove(struct sfp - dev_info(sfp->dev, "module removed\n"); - } - --/* This state machine tracks the netdev up/down state */ -+/* This state machine tracks the upstream's state */ - static void sfp_sm_device(struct sfp *sfp, unsigned int event) - { - switch (sfp->sm_dev_state) { - default: -- if (event == SFP_E_DEV_UP) -+ if (event == SFP_E_DEV_ATTACH) -+ sfp->sm_dev_state = SFP_DEV_DOWN; -+ break; -+ -+ case SFP_DEV_DOWN: -+ if (event == SFP_E_DEV_DETACH) -+ sfp->sm_dev_state = SFP_DEV_DETACHED; -+ else if (event == SFP_E_DEV_UP) - sfp->sm_dev_state = SFP_DEV_UP; - break; - - case SFP_DEV_UP: -- if (event == SFP_E_DEV_DOWN) -+ if (event == SFP_E_DEV_DETACH) -+ sfp->sm_dev_state = SFP_DEV_DETACHED; -+ else if (event == SFP_E_DEV_DOWN) - sfp->sm_dev_state = SFP_DEV_DOWN; - break; - } -@@ -1515,17 +1529,20 @@ static void sfp_sm_device(struct sfp *sf - */ - static void sfp_sm_module(struct sfp *sfp, unsigned int event) - { -- /* Handle remove event globally, it resets this state machine */ -- if (event == SFP_E_REMOVE) { -+ /* Handle remove event globally, it resets this state machine. -+ * Also deal with upstream detachment. -+ */ -+ if (event == SFP_E_REMOVE || sfp->sm_dev_state < SFP_DEV_DOWN) { - if (sfp->sm_mod_state > SFP_MOD_PROBE) - sfp_sm_mod_remove(sfp); -- sfp_sm_mod_next(sfp, SFP_MOD_EMPTY, 0); -+ if (sfp->sm_mod_state != SFP_MOD_EMPTY) -+ sfp_sm_mod_next(sfp, SFP_MOD_EMPTY, 0); - return; - } - - switch (sfp->sm_mod_state) { - default: -- if (event == SFP_E_INSERT && sfp->attached) -+ if (event == SFP_E_INSERT) - sfp_sm_mod_next(sfp, SFP_MOD_PROBE, T_SERIAL); - break; - -@@ -1691,8 +1708,8 @@ static void sfp_sm_event(struct sfp *sfp - sm_state_to_str(sfp->sm_state), - event_to_str(event)); - -- sfp_sm_module(sfp, event); - sfp_sm_device(sfp, event); -+ sfp_sm_module(sfp, event); - sfp_sm_main(sfp, event); - - dev_dbg(sfp->dev, "SM: exit %s:%s:%s\n", -@@ -1705,15 +1722,14 @@ static void sfp_sm_event(struct sfp *sfp - - static void sfp_attach(struct sfp *sfp) - { -- sfp->attached = true; -+ sfp_sm_event(sfp, SFP_E_DEV_ATTACH); - if (sfp->state & SFP_F_PRESENT) - sfp_sm_event(sfp, SFP_E_INSERT); - } - - static void sfp_detach(struct sfp *sfp) - { -- sfp->attached = false; -- sfp_sm_event(sfp, SFP_E_REMOVE); -+ sfp_sm_event(sfp, SFP_E_DEV_DETACH); - } - - static void sfp_start(struct sfp *sfp) diff --git a/target/linux/generic/backport-4.19/733-v5.5-net-sfp-split-power-mode-switching-from-probe.patch b/target/linux/generic/backport-4.19/733-v5.5-net-sfp-split-power-mode-switching-from-probe.patch deleted file mode 100644 index 06b3cb5428..0000000000 --- a/target/linux/generic/backport-4.19/733-v5.5-net-sfp-split-power-mode-switching-from-probe.patch +++ /dev/null @@ -1,184 +0,0 @@ -From fdff863a4ce3677907f64396e34c45025abb6600 Mon Sep 17 00:00:00 2001 -From: Russell King <rmk+kernel@armlinux.org.uk> -Date: Tue, 5 Nov 2019 12:59:36 +0000 -Subject: [PATCH 631/660] net: sfp: split power mode switching from probe - -Switch the power mode switching from the probe, so that we don't -repeatedly re-probe the SFP device if there is a problem accessing -the registers at I2C address 0x51. - -In splitting this out, we can also fix a bug where we leave the module -in high-power mode when the upstream device is detached but the module -is still inserted. - -Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> ---- - drivers/net/phy/sfp.c | 101 ++++++++++++++++++++++++++---------------- - 1 file changed, 64 insertions(+), 37 deletions(-) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -47,6 +47,7 @@ enum { - SFP_MOD_EMPTY = 0, - SFP_MOD_PROBE, - SFP_MOD_HPOWER, -+ SFP_MOD_WAITPWR, - SFP_MOD_PRESENT, - SFP_MOD_ERROR, - -@@ -69,6 +70,7 @@ static const char * const mod_state_str - [SFP_MOD_EMPTY] = "empty", - [SFP_MOD_PROBE] = "probe", - [SFP_MOD_HPOWER] = "hpower", -+ [SFP_MOD_WAITPWR] = "waitpwr", - [SFP_MOD_PRESENT] = "present", - [SFP_MOD_ERROR] = "error", - }; -@@ -1358,37 +1360,34 @@ static int sfp_module_parse_power(struct - return 0; - } - --static int sfp_sm_mod_hpower(struct sfp *sfp) -+static int sfp_sm_mod_hpower(struct sfp *sfp, bool enable) - { - u8 val; - int err; - -- if (sfp->module_power_mW <= 1000) -- return 0; -- - err = sfp_read(sfp, true, SFP_EXT_STATUS, &val, sizeof(val)); - if (err != sizeof(val)) { - dev_err(sfp->dev, "Failed to read EEPROM: %d\n", err); -- err = -EAGAIN; -- goto err; -+ return -EAGAIN; - } - -- val |= BIT(0); -+ if (enable) -+ val |= BIT(0); -+ else -+ val &= ~BIT(0); - - err = sfp_write(sfp, true, SFP_EXT_STATUS, &val, sizeof(val)); - if (err != sizeof(val)) { - dev_err(sfp->dev, "Failed to write EEPROM: %d\n", err); -- err = -EAGAIN; -- goto err; -+ return -EAGAIN; - } - -- dev_info(sfp->dev, "Module switched to %u.%uW power level\n", -- sfp->module_power_mW / 1000, -- (sfp->module_power_mW / 100) % 10); -- return T_HPOWER_LEVEL; -+ if (enable) -+ dev_info(sfp->dev, "Module switched to %u.%uW power level\n", -+ sfp->module_power_mW / 1000, -+ (sfp->module_power_mW / 100) % 10); - --err: -- return err; -+ return 0; - } - - static int sfp_sm_mod_probe(struct sfp *sfp) -@@ -1484,7 +1483,7 @@ static int sfp_sm_mod_probe(struct sfp * - if (ret < 0) - return ret; - -- return sfp_sm_mod_hpower(sfp); -+ return 0; - } - - static void sfp_sm_mod_remove(struct sfp *sfp) -@@ -1529,13 +1528,22 @@ static void sfp_sm_device(struct sfp *sf - */ - static void sfp_sm_module(struct sfp *sfp, unsigned int event) - { -- /* Handle remove event globally, it resets this state machine. -- * Also deal with upstream detachment. -- */ -- if (event == SFP_E_REMOVE || sfp->sm_dev_state < SFP_DEV_DOWN) { -+ int err; -+ -+ /* Handle remove event globally, it resets this state machine */ -+ if (event == SFP_E_REMOVE) { - if (sfp->sm_mod_state > SFP_MOD_PROBE) - sfp_sm_mod_remove(sfp); -- if (sfp->sm_mod_state != SFP_MOD_EMPTY) -+ sfp_sm_mod_next(sfp, SFP_MOD_EMPTY, 0); -+ return; -+ } -+ -+ /* Handle device detach globally */ -+ if (sfp->sm_dev_state < SFP_DEV_DOWN) { -+ if (sfp->module_power_mW > 1000 && -+ sfp->sm_mod_state > SFP_MOD_HPOWER) -+ sfp_sm_mod_hpower(sfp, false); -+ if (sfp->sm_mod_state > SFP_MOD_EMPTY) - sfp_sm_mod_next(sfp, SFP_MOD_EMPTY, 0); - return; - } -@@ -1547,26 +1555,45 @@ static void sfp_sm_module(struct sfp *sf - break; - - case SFP_MOD_PROBE: -- if (event == SFP_E_TIMEOUT) { -- int val = sfp_sm_mod_probe(sfp); -+ if (event != SFP_E_TIMEOUT) -+ break; - -- if (val == 0) -- sfp_sm_mod_next(sfp, SFP_MOD_PRESENT, 0); -- else if (val > 0) -- sfp_sm_mod_next(sfp, SFP_MOD_HPOWER, val); -- else if (val != -EAGAIN) -- sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0); -- else -- sfp_sm_set_timer(sfp, T_PROBE_RETRY); -+ err = sfp_sm_mod_probe(sfp); -+ if (err == -EAGAIN) { -+ sfp_sm_set_timer(sfp, T_PROBE_RETRY); -+ break; - } -- break; -+ if (err < 0) { -+ sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0); -+ break; -+ } -+ -+ /* If this is a power level 1 module, we are done */ -+ if (sfp->module_power_mW <= 1000) -+ goto insert; - -+ sfp_sm_mod_next(sfp, SFP_MOD_HPOWER, 0); -+ /* fall through */ - case SFP_MOD_HPOWER: -- if (event == SFP_E_TIMEOUT) { -- sfp_sm_mod_next(sfp, SFP_MOD_PRESENT, 0); -+ /* Enable high power mode */ -+ err = sfp_sm_mod_hpower(sfp, true); -+ if (err == 0) -+ sfp_sm_mod_next(sfp, SFP_MOD_WAITPWR, T_HPOWER_LEVEL); -+ else if (err != -EAGAIN) -+ sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0); -+ else -+ sfp_sm_set_timer(sfp, T_PROBE_RETRY); -+ break; -+ -+ case SFP_MOD_WAITPWR: -+ /* Wait for T_HPOWER_LEVEL to time out */ -+ if (event != SFP_E_TIMEOUT) - break; -- } -- /* fallthrough */ -+ -+ insert: -+ sfp_sm_mod_next(sfp, SFP_MOD_PRESENT, 0); -+ break; -+ - case SFP_MOD_PRESENT: - case SFP_MOD_ERROR: - break; diff --git a/target/linux/generic/backport-4.19/734-v5.5-net-sfp-move-module-insert-reporting-out-of-probe.patch b/target/linux/generic/backport-4.19/734-v5.5-net-sfp-move-module-insert-reporting-out-of-probe.patch deleted file mode 100644 index 26b6a6b0e4..0000000000 --- a/target/linux/generic/backport-4.19/734-v5.5-net-sfp-move-module-insert-reporting-out-of-probe.patch +++ /dev/null @@ -1,159 +0,0 @@ -From 57cbf7453551db1df619b79410d79fc418d862d5 Mon Sep 17 00:00:00 2001 -From: Russell King <rmk+kernel@armlinux.org.uk> -Date: Tue, 5 Nov 2019 13:00:45 +0000 -Subject: [PATCH 632/660] net: sfp: move module insert reporting out of probe - -Move the module insertion reporting out of the probe handling, but -after we have detected that the upstream has attached (since that is -whom we are reporting insertion to.) - -Only report module removal if we had previously reported a module -insertion. - -This gives cleaner semantics, and means we can probe the module before -we have an upstream attached. - -Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> ---- - drivers/net/phy/sfp.c | 58 +++++++++++++++++++++++++++++-------------- - 1 file changed, 40 insertions(+), 18 deletions(-) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -45,11 +45,12 @@ enum { - SFP_E_TIMEOUT, - - SFP_MOD_EMPTY = 0, -+ SFP_MOD_ERROR, - SFP_MOD_PROBE, -+ SFP_MOD_WAITDEV, - SFP_MOD_HPOWER, - SFP_MOD_WAITPWR, - SFP_MOD_PRESENT, -- SFP_MOD_ERROR, - - SFP_DEV_DETACHED = 0, - SFP_DEV_DOWN, -@@ -68,11 +69,12 @@ enum { - - static const char * const mod_state_strings[] = { - [SFP_MOD_EMPTY] = "empty", -+ [SFP_MOD_ERROR] = "error", - [SFP_MOD_PROBE] = "probe", -+ [SFP_MOD_WAITDEV] = "waitdev", - [SFP_MOD_HPOWER] = "hpower", - [SFP_MOD_WAITPWR] = "waitpwr", - [SFP_MOD_PRESENT] = "present", -- [SFP_MOD_ERROR] = "error", - }; - - static const char *mod_state_to_str(unsigned short mod_state) -@@ -1479,16 +1481,13 @@ static int sfp_sm_mod_probe(struct sfp * - if (ret < 0) - return ret; - -- ret = sfp_module_insert(sfp->sfp_bus, &sfp->id); -- if (ret < 0) -- return ret; -- - return 0; - } - - static void sfp_sm_mod_remove(struct sfp *sfp) - { -- sfp_module_remove(sfp->sfp_bus); -+ if (sfp->sm_mod_state > SFP_MOD_WAITDEV) -+ sfp_module_remove(sfp->sfp_bus); - - sfp_hwmon_remove(sfp); - -@@ -1539,12 +1538,12 @@ static void sfp_sm_module(struct sfp *sf - } - - /* Handle device detach globally */ -- if (sfp->sm_dev_state < SFP_DEV_DOWN) { -+ if (sfp->sm_dev_state < SFP_DEV_DOWN && -+ sfp->sm_mod_state > SFP_MOD_WAITDEV) { - if (sfp->module_power_mW > 1000 && - sfp->sm_mod_state > SFP_MOD_HPOWER) - sfp_sm_mod_hpower(sfp, false); -- if (sfp->sm_mod_state > SFP_MOD_EMPTY) -- sfp_sm_mod_next(sfp, SFP_MOD_EMPTY, 0); -+ sfp_sm_mod_next(sfp, SFP_MOD_WAITDEV, 0); - return; - } - -@@ -1555,6 +1554,7 @@ static void sfp_sm_module(struct sfp *sf - break; - - case SFP_MOD_PROBE: -+ /* Wait for T_PROBE_INIT to time out */ - if (event != SFP_E_TIMEOUT) - break; - -@@ -1568,6 +1568,20 @@ static void sfp_sm_module(struct sfp *sf - break; - } - -+ sfp_sm_mod_next(sfp, SFP_MOD_WAITDEV, 0); -+ /* fall through */ -+ case SFP_MOD_WAITDEV: -+ /* Ensure that the device is attached before proceeding */ -+ if (sfp->sm_dev_state < SFP_DEV_DOWN) -+ break; -+ -+ /* Report the module insertion to the upstream device */ -+ err = sfp_module_insert(sfp->sfp_bus, &sfp->id); -+ if (err < 0) { -+ sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0); -+ break; -+ } -+ - /* If this is a power level 1 module, we are done */ - if (sfp->module_power_mW <= 1000) - goto insert; -@@ -1577,12 +1591,17 @@ static void sfp_sm_module(struct sfp *sf - case SFP_MOD_HPOWER: - /* Enable high power mode */ - err = sfp_sm_mod_hpower(sfp, true); -- if (err == 0) -- sfp_sm_mod_next(sfp, SFP_MOD_WAITPWR, T_HPOWER_LEVEL); -- else if (err != -EAGAIN) -- sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0); -- else -- sfp_sm_set_timer(sfp, T_PROBE_RETRY); -+ if (err < 0) { -+ if (err != -EAGAIN) { -+ sfp_module_remove(sfp->sfp_bus); -+ sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0); -+ } else { -+ sfp_sm_set_timer(sfp, T_PROBE_RETRY); -+ } -+ break; -+ } -+ -+ sfp_sm_mod_next(sfp, SFP_MOD_WAITPWR, T_HPOWER_LEVEL); - break; - - case SFP_MOD_WAITPWR: -@@ -1750,8 +1769,6 @@ static void sfp_sm_event(struct sfp *sfp - static void sfp_attach(struct sfp *sfp) - { - sfp_sm_event(sfp, SFP_E_DEV_ATTACH); -- if (sfp->state & SFP_F_PRESENT) -- sfp_sm_event(sfp, SFP_E_INSERT); - } - - static void sfp_detach(struct sfp *sfp) -@@ -2001,6 +2018,11 @@ static int sfp_probe(struct platform_dev - sfp->state |= SFP_F_RATE_SELECT; - sfp_set_state(sfp, sfp->state); - sfp_module_tx_disable(sfp); -+ if (sfp->state & SFP_F_PRESENT) { -+ rtnl_lock(); -+ sfp_sm_event(sfp, SFP_E_INSERT); -+ rtnl_unlock(); -+ } - - for (i = 0; i < GPIO_MAX; i++) { - if (gpio_flags[i] != GPIOD_IN || !sfp->gpio[i]) diff --git a/target/linux/generic/backport-4.19/735-v5.5-net-sfp-allow-sfp-to-probe-slow-to-initialise-GPON-m.patch b/target/linux/generic/backport-4.19/735-v5.5-net-sfp-allow-sfp-to-probe-slow-to-initialise-GPON-m.patch deleted file mode 100644 index 6cbd0864f7..0000000000 --- a/target/linux/generic/backport-4.19/735-v5.5-net-sfp-allow-sfp-to-probe-slow-to-initialise-GPON-m.patch +++ /dev/null @@ -1,110 +0,0 @@ -From fb56cd08880aff8fb030e684fa4311bef712a499 Mon Sep 17 00:00:00 2001 -From: Russell King <rmk+kernel@armlinux.org.uk> -Date: Tue, 5 Nov 2019 13:02:30 +0000 -Subject: [PATCH 633/660] net: sfp: allow sfp to probe slow to initialise GPON - modules - -Some GPON modules (e.g. Huawei MA5671A) take a significant amount of -time to start responding on the I2C bus, contary to the SFF -specifications. - -Work around this by implementing a two-level timeout strategy, where -we initially quickly retry for the module, and then use a slower retry -after we exceed a maximum number of quick attempts. - -Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> ---- - drivers/net/phy/sfp.c | 38 ++++++++++++++++++++++++++++---------- - 1 file changed, 28 insertions(+), 10 deletions(-) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -165,9 +165,12 @@ static const enum gpiod_flags gpio_flags - * The SFF-8472 specifies t_serial ("Time from power on until module is - * ready for data transmission over the two wire serial bus.") as 300ms. - */ --#define T_SERIAL msecs_to_jiffies(300) --#define T_HPOWER_LEVEL msecs_to_jiffies(300) --#define T_PROBE_RETRY msecs_to_jiffies(100) -+#define T_SERIAL msecs_to_jiffies(300) -+#define T_HPOWER_LEVEL msecs_to_jiffies(300) -+#define T_PROBE_RETRY_INIT msecs_to_jiffies(100) -+#define R_PROBE_RETRY_INIT 10 -+#define T_PROBE_RETRY_SLOW msecs_to_jiffies(5000) -+#define R_PROBE_RETRY_SLOW 12 - - /* SFP modules appear to always have their PHY configured for bus address - * 0x56 (which with mdio-i2c, translates to a PHY address of 22). -@@ -202,6 +205,8 @@ struct sfp { - struct delayed_work timeout; - struct mutex sm_mutex; /* Protects state machine */ - unsigned char sm_mod_state; -+ unsigned char sm_mod_tries_init; -+ unsigned char sm_mod_tries; - unsigned char sm_dev_state; - unsigned short sm_state; - unsigned int sm_retries; -@@ -1392,7 +1397,7 @@ static int sfp_sm_mod_hpower(struct sfp - return 0; - } - --static int sfp_sm_mod_probe(struct sfp *sfp) -+static int sfp_sm_mod_probe(struct sfp *sfp, bool report) - { - /* SFP module inserted - read I2C data */ - struct sfp_eeprom_id id; -@@ -1402,7 +1407,8 @@ static int sfp_sm_mod_probe(struct sfp * - - ret = sfp_read(sfp, false, 0, &id, sizeof(id)); - if (ret < 0) { -- dev_err(sfp->dev, "failed to read EEPROM: %d\n", ret); -+ if (report) -+ dev_err(sfp->dev, "failed to read EEPROM: %d\n", ret); - return -EAGAIN; - } - -@@ -1549,8 +1555,11 @@ static void sfp_sm_module(struct sfp *sf - - switch (sfp->sm_mod_state) { - default: -- if (event == SFP_E_INSERT) -+ if (event == SFP_E_INSERT) { - sfp_sm_mod_next(sfp, SFP_MOD_PROBE, T_SERIAL); -+ sfp->sm_mod_tries_init = R_PROBE_RETRY_INIT; -+ sfp->sm_mod_tries = R_PROBE_RETRY_SLOW; -+ } - break; - - case SFP_MOD_PROBE: -@@ -1558,10 +1567,19 @@ static void sfp_sm_module(struct sfp *sf - if (event != SFP_E_TIMEOUT) - break; - -- err = sfp_sm_mod_probe(sfp); -+ err = sfp_sm_mod_probe(sfp, sfp->sm_mod_tries == 1); - if (err == -EAGAIN) { -- sfp_sm_set_timer(sfp, T_PROBE_RETRY); -- break; -+ if (sfp->sm_mod_tries_init && -+ --sfp->sm_mod_tries_init) { -+ sfp_sm_set_timer(sfp, T_PROBE_RETRY_INIT); -+ break; -+ } else if (sfp->sm_mod_tries && --sfp->sm_mod_tries) { -+ if (sfp->sm_mod_tries == R_PROBE_RETRY_SLOW - 1) -+ dev_warn(sfp->dev, -+ "please wait, module slow to respond\n"); -+ sfp_sm_set_timer(sfp, T_PROBE_RETRY_SLOW); -+ break; -+ } - } - if (err < 0) { - sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0); -@@ -1596,7 +1614,7 @@ static void sfp_sm_module(struct sfp *sf - sfp_module_remove(sfp->sfp_bus); - sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0); - } else { -- sfp_sm_set_timer(sfp, T_PROBE_RETRY); -+ sfp_sm_set_timer(sfp, T_PROBE_RETRY_INIT); - } - break; - } diff --git a/target/linux/generic/backport-4.19/736-v5.5-net-sfp-allow-modules-with-slow-diagnostics-to-probe.patch b/target/linux/generic/backport-4.19/736-v5.5-net-sfp-allow-modules-with-slow-diagnostics-to-probe.patch deleted file mode 100644 index fe1e6c4822..0000000000 --- a/target/linux/generic/backport-4.19/736-v5.5-net-sfp-allow-modules-with-slow-diagnostics-to-probe.patch +++ /dev/null @@ -1,198 +0,0 @@ -From 559391fc20fae506adcb311b904cc544c76436c0 Mon Sep 17 00:00:00 2001 -From: Russell King <rmk+kernel@armlinux.org.uk> -Date: Thu, 7 Nov 2019 18:52:07 +0000 -Subject: [PATCH 634/660] net: sfp: allow modules with slow diagnostics to - probe - -When a module is inserted, we attempt to read read the ID from address -0x50. Once we are able to read the ID, we immediately attempt to -initialise the hwmon support by reading from address 0x51. If this -fails, then we fall into error state, and assume that the module is -not usable. - -Modules such as the ALCATELLUCENT 3FE46541AA use a real EEPROM for -I2C address 0x50, which responds immediately. However, address 0x51 -is an emulated, which only becomes available once the on-board firmware -has booted. This prompts us to fall into the error state. - -Since the module may be usable without diagnostics, arrange for the -hwmon probe independent of the rest of the SFP itself, retrying every -5s for up to about 60s for the monitoring to become available, and -print an error message if it doesn't become available. - -Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> ---- - drivers/net/phy/sfp.c | 96 +++++++++++++++++++++++++++++++++---------- - 1 file changed, 74 insertions(+), 22 deletions(-) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -216,6 +216,8 @@ struct sfp { - - #if IS_ENABLED(CONFIG_HWMON) - struct sfp_diag diag; -+ struct delayed_work hwmon_probe; -+ unsigned int hwmon_tries; - struct device *hwmon_dev; - char *hwmon_name; - #endif -@@ -1094,29 +1096,27 @@ static const struct hwmon_chip_info sfp_ - .info = sfp_hwmon_info, - }; - --static int sfp_hwmon_insert(struct sfp *sfp) -+static void sfp_hwmon_probe(struct work_struct *work) - { -+ struct sfp *sfp = container_of(work, struct sfp, hwmon_probe.work); - int err, i; - -- if (sfp->id.ext.sff8472_compliance == SFP_SFF8472_COMPLIANCE_NONE) -- return 0; -- -- if (!(sfp->id.ext.diagmon & SFP_DIAGMON_DDM)) -- return 0; -- -- if (sfp->id.ext.diagmon & SFP_DIAGMON_ADDRMODE) -- /* This driver in general does not support address -- * change. -- */ -- return 0; -- - err = sfp_read(sfp, true, 0, &sfp->diag, sizeof(sfp->diag)); -- if (err < 0) -- return err; -+ if (err < 0) { -+ if (sfp->hwmon_tries--) { -+ mod_delayed_work(system_wq, &sfp->hwmon_probe, -+ T_PROBE_RETRY_SLOW); -+ } else { -+ dev_warn(sfp->dev, "hwmon probe failed: %d\n", err); -+ } -+ return; -+ } - - sfp->hwmon_name = kstrdup(dev_name(sfp->dev), GFP_KERNEL); -- if (!sfp->hwmon_name) -- return -ENODEV; -+ if (!sfp->hwmon_name) { -+ dev_err(sfp->dev, "out of memory for hwmon name\n"); -+ return; -+ } - - for (i = 0; sfp->hwmon_name[i]; i++) - if (hwmon_is_bad_char(sfp->hwmon_name[i])) -@@ -1126,18 +1126,52 @@ static int sfp_hwmon_insert(struct sfp * - sfp->hwmon_name, sfp, - &sfp_hwmon_chip_info, - NULL); -+ if (IS_ERR(sfp->hwmon_dev)) -+ dev_err(sfp->dev, "failed to register hwmon device: %ld\n", -+ PTR_ERR(sfp->hwmon_dev)); -+} -+ -+static int sfp_hwmon_insert(struct sfp *sfp) -+{ -+ if (sfp->id.ext.sff8472_compliance == SFP_SFF8472_COMPLIANCE_NONE) -+ return 0; -+ -+ if (!(sfp->id.ext.diagmon & SFP_DIAGMON_DDM)) -+ return 0; -+ -+ if (sfp->id.ext.diagmon & SFP_DIAGMON_ADDRMODE) -+ /* This driver in general does not support address -+ * change. -+ */ -+ return 0; -+ -+ mod_delayed_work(system_wq, &sfp->hwmon_probe, 1); -+ sfp->hwmon_tries = R_PROBE_RETRY_SLOW; - -- return PTR_ERR_OR_ZERO(sfp->hwmon_dev); -+ return 0; - } - - static void sfp_hwmon_remove(struct sfp *sfp) - { -+ cancel_delayed_work_sync(&sfp->hwmon_probe); - if (!IS_ERR_OR_NULL(sfp->hwmon_dev)) { - hwmon_device_unregister(sfp->hwmon_dev); - sfp->hwmon_dev = NULL; - kfree(sfp->hwmon_name); - } - } -+ -+static int sfp_hwmon_init(struct sfp *sfp) -+{ -+ INIT_DELAYED_WORK(&sfp->hwmon_probe, sfp_hwmon_probe); -+ -+ return 0; -+} -+ -+static void sfp_hwmon_exit(struct sfp *sfp) -+{ -+ cancel_delayed_work_sync(&sfp->hwmon_probe); -+} - #else - static int sfp_hwmon_insert(struct sfp *sfp) - { -@@ -1147,6 +1181,15 @@ static int sfp_hwmon_insert(struct sfp * - static void sfp_hwmon_remove(struct sfp *sfp) - { - } -+ -+static int sfp_hwmon_init(struct sfp *sfp) -+{ -+ return 0; -+} -+ -+static void sfp_hwmon_exit(struct sfp *sfp) -+{ -+} - #endif - - /* Helpers */ -@@ -1483,10 +1526,6 @@ static int sfp_sm_mod_probe(struct sfp * - if (ret < 0) - return ret; - -- ret = sfp_hwmon_insert(sfp); -- if (ret < 0) -- return ret; -- - return 0; - } - -@@ -1635,6 +1674,15 @@ static void sfp_sm_module(struct sfp *sf - case SFP_MOD_ERROR: - break; - } -+ -+#if IS_ENABLED(CONFIG_HWMON) -+ if (sfp->sm_mod_state >= SFP_MOD_WAITDEV && -+ IS_ERR_OR_NULL(sfp->hwmon_dev)) { -+ err = sfp_hwmon_insert(sfp); -+ if (err) -+ dev_warn(sfp->dev, "hwmon probe failed: %d\n", err); -+ } -+#endif - } - - static void sfp_sm_main(struct sfp *sfp, unsigned int event) -@@ -1936,6 +1984,8 @@ static struct sfp *sfp_alloc(struct devi - INIT_DELAYED_WORK(&sfp->poll, sfp_poll); - INIT_DELAYED_WORK(&sfp->timeout, sfp_timeout); - -+ sfp_hwmon_init(sfp); -+ - return sfp; - } - -@@ -1943,6 +1993,8 @@ static void sfp_cleanup(void *data) - { - struct sfp *sfp = data; - -+ sfp_hwmon_exit(sfp); -+ - cancel_delayed_work_sync(&sfp->poll); - cancel_delayed_work_sync(&sfp->timeout); - if (sfp->i2c_mii) { diff --git a/target/linux/generic/backport-4.19/737-v5.5-net-phy-add-core-phylib-sfp-support.patch b/target/linux/generic/backport-4.19/737-v5.5-net-phy-add-core-phylib-sfp-support.patch deleted file mode 100644 index 1ffc545ad1..0000000000 --- a/target/linux/generic/backport-4.19/737-v5.5-net-phy-add-core-phylib-sfp-support.patch +++ /dev/null @@ -1,183 +0,0 @@ -From eb156db588ac583cdae7b91eaac9c0ad3a358e63 Mon Sep 17 00:00:00 2001 -From: Russell King <rmk+kernel@armlinux.org.uk> -Date: Sun, 15 Sep 2019 20:05:34 +0100 -Subject: [PATCH 635/660] net: phy: add core phylib sfp support - -Add core phylib help for supporting SFP sockets on PHYs. This provides -a mechanism to inform the SFP layer about PHY up/down events, and also -unregister the SFP bus when the PHY is going away. - -Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> ---- - drivers/net/phy/phy.c | 7 ++++ - drivers/net/phy/phy_device.c | 66 ++++++++++++++++++++++++++++++++++++ - include/linux/phy.h | 11 ++++++ - 3 files changed, 84 insertions(+) - ---- a/drivers/net/phy/phy.c -+++ b/drivers/net/phy/phy.c -@@ -30,6 +30,7 @@ - #include <linux/ethtool.h> - #include <linux/phy.h> - #include <linux/phy_led_triggers.h> -+#include <linux/sfp.h> - #include <linux/workqueue.h> - #include <linux/mdio.h> - #include <linux/io.h> -@@ -871,6 +872,9 @@ void phy_stop(struct phy_device *phydev) - if (phy_interrupt_is_valid(phydev)) - phy_disable_interrupts(phydev); - -+ if (phydev->sfp_bus) -+ sfp_upstream_stop(phydev->sfp_bus); -+ - phydev->state = PHY_HALTED; - - out_unlock: -@@ -899,6 +903,9 @@ void phy_start(struct phy_device *phydev - - mutex_lock(&phydev->lock); - -+ if (phydev->sfp_bus) -+ sfp_upstream_start(phydev->sfp_bus); -+ - switch (phydev->state) { - case PHY_STARTING: - phydev->state = PHY_PENDING; ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -31,6 +31,7 @@ - #include <linux/ethtool.h> - #include <linux/phy.h> - #include <linux/phy_led_triggers.h> -+#include <linux/sfp.h> - #include <linux/mdio.h> - #include <linux/io.h> - #include <linux/uaccess.h> -@@ -950,6 +951,65 @@ void phy_attached_print(struct phy_devic - EXPORT_SYMBOL(phy_attached_print); - - /** -+ * phy_sfp_attach - attach the SFP bus to the PHY upstream network device -+ * @upstream: pointer to the phy device -+ * @bus: sfp bus representing cage being attached -+ * -+ * This is used to fill in the sfp_upstream_ops .attach member. -+ */ -+void phy_sfp_attach(void *upstream, struct sfp_bus *bus) -+{ -+ struct phy_device *phydev = upstream; -+ -+ if (phydev->attached_dev) -+ phydev->attached_dev->sfp_bus = bus; -+ phydev->sfp_bus_attached = true; -+} -+EXPORT_SYMBOL(phy_sfp_attach); -+ -+/** -+ * phy_sfp_detach - detach the SFP bus from the PHY upstream network device -+ * @upstream: pointer to the phy device -+ * @bus: sfp bus representing cage being attached -+ * -+ * This is used to fill in the sfp_upstream_ops .detach member. -+ */ -+void phy_sfp_detach(void *upstream, struct sfp_bus *bus) -+{ -+ struct phy_device *phydev = upstream; -+ -+ if (phydev->attached_dev) -+ phydev->attached_dev->sfp_bus = NULL; -+ phydev->sfp_bus_attached = false; -+} -+EXPORT_SYMBOL(phy_sfp_detach); -+ -+/** -+ * phy_sfp_probe - probe for a SFP cage attached to this PHY device -+ * @phydev: Pointer to phy_device -+ * @ops: SFP's upstream operations -+ */ -+int phy_sfp_probe(struct phy_device *phydev, -+ const struct sfp_upstream_ops *ops) -+{ -+ struct sfp_bus *bus; -+ int ret; -+ -+ if (phydev->mdio.dev.fwnode) { -+ bus = sfp_bus_find_fwnode(phydev->mdio.dev.fwnode); -+ if (IS_ERR(bus)) -+ return PTR_ERR(bus); -+ -+ phydev->sfp_bus = bus; -+ -+ ret = sfp_bus_add_upstream(bus, phydev, ops); -+ sfp_bus_put(bus); -+ } -+ return 0; -+} -+EXPORT_SYMBOL(phy_sfp_probe); -+ -+/** - * phy_attach_direct - attach a network device to a given PHY device pointer - * @dev: network device to attach - * @phydev: Pointer to phy_device to attach -@@ -1022,6 +1082,9 @@ int phy_attach_direct(struct net_device - phydev->attached_dev = dev; - dev->phydev = phydev; - -+ if (phydev->sfp_bus_attached) -+ dev->sfp_bus = phydev->sfp_bus; -+ - /* Some Ethernet drivers try to connect to a PHY device before - * calling register_netdevice() -> netdev_register_kobject() and - * does the dev->dev.kobj initialization. Here we only check for -@@ -1956,6 +2019,9 @@ static int phy_remove(struct device *dev - phydev->state = PHY_DOWN; - mutex_unlock(&phydev->lock); - -+ sfp_bus_del_upstream(phydev->sfp_bus); -+ phydev->sfp_bus = NULL; -+ - if (phydev->drv && phydev->drv->remove) { - phydev->drv->remove(phydev); - ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -184,6 +184,8 @@ static inline const char *phy_modes(phy_ - - struct device; - struct phylink; -+struct sfp_bus; -+struct sfp_upstream_ops; - struct sk_buff; - - /* -@@ -383,6 +385,8 @@ struct phy_c45_device_ids { - * irq: IRQ number of the PHY's interrupt (-1 if none) - * phy_timer: The timer for handling the state machine - * phy_queue: A work_queue for the phy_mac_interrupt -+ * sfp_bus_attached: flag indicating whether the SFP bus has been attached -+ * sfp_bus: SFP bus attached to this PHY's fiber port - * attached_dev: The attached enet driver's device instance ptr - * adjust_link: Callback for the enet controller to respond to - * changes in the link state. -@@ -473,6 +477,9 @@ struct phy_device { - - struct mutex lock; - -+ /* This may be modified under the rtnl lock */ -+ bool sfp_bus_attached; -+ struct sfp_bus *sfp_bus; - struct phylink *phylink; - struct net_device *attached_dev; - -@@ -1033,6 +1040,10 @@ int phy_suspend(struct phy_device *phyde - int phy_resume(struct phy_device *phydev); - int __phy_resume(struct phy_device *phydev); - int phy_loopback(struct phy_device *phydev, bool enable); -+void phy_sfp_attach(void *upstream, struct sfp_bus *bus); -+void phy_sfp_detach(void *upstream, struct sfp_bus *bus); -+int phy_sfp_probe(struct phy_device *phydev, -+ const struct sfp_upstream_ops *ops); - struct phy_device *phy_attach(struct net_device *dev, const char *bus_id, - phy_interface_t interface); - struct phy_device *phy_find_first(struct mii_bus *bus); diff --git a/target/linux/generic/backport-4.19/738-v5.5-net-phy-marvell10g-add-SFP-support.patch b/target/linux/generic/backport-4.19/738-v5.5-net-phy-marvell10g-add-SFP-support.patch deleted file mode 100644 index a67431ce5c..0000000000 --- a/target/linux/generic/backport-4.19/738-v5.5-net-phy-marvell10g-add-SFP-support.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 0836d9fb41ed90090ef4af0d7abe784ee7706f80 Mon Sep 17 00:00:00 2001 -From: Russell King <rmk+kernel@armlinux.org.uk> -Date: Fri, 14 Apr 2017 14:21:25 +0100 -Subject: [PATCH 636/660] net: phy: marvell10g: add SFP+ support - -Add support for SFP+ cages to the Marvell 10G PHY driver. This is -slightly complicated by the way phylib works in that we need to use -a multi-step process to attach the SFP bus, and we also need to track -the phylink state machine to know when the module's transmit disable -signal should change state. - -With appropriate DT changes, this allows the SFP+ canges on the -Macchiatobin platform to be functional. - -Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> ---- - drivers/net/phy/marvell10g.c | 25 ++++++++++++++++++++++++- - 1 file changed, 24 insertions(+), 1 deletion(-) - ---- a/drivers/net/phy/marvell10g.c -+++ b/drivers/net/phy/marvell10g.c -@@ -25,6 +25,7 @@ - #include <linux/hwmon.h> - #include <linux/marvell_phy.h> - #include <linux/phy.h> -+#include <linux/sfp.h> - - enum { - MV_PMA_BOOT = 0xc050, -@@ -219,6 +220,28 @@ static int mv3310_hwmon_probe(struct phy - } - #endif - -+static int mv3310_sfp_insert(void *upstream, const struct sfp_eeprom_id *id) -+{ -+ struct phy_device *phydev = upstream; -+ __ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, }; -+ phy_interface_t iface; -+ -+ sfp_parse_support(phydev->sfp_bus, id, support); -+ iface = sfp_select_interface(phydev->sfp_bus, id, support); -+ -+ if (iface != PHY_INTERFACE_MODE_10GKR) { -+ dev_err(&phydev->mdio.dev, "incompatible SFP module inserted\n"); -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+static const struct sfp_upstream_ops mv3310_sfp_ops = { -+ .attach = phy_sfp_attach, -+ .detach = phy_sfp_detach, -+ .module_insert = mv3310_sfp_insert, -+}; -+ - static int mv3310_probe(struct phy_device *phydev) - { - struct mv3310_priv *priv; -@@ -249,7 +272,7 @@ static int mv3310_probe(struct phy_devic - if (ret) - return ret; - -- return 0; -+ return phy_sfp_probe(phydev, &mv3310_sfp_ops); - } - - static int mv3310_suspend(struct phy_device *phydev) diff --git a/target/linux/generic/backport-4.19/739-v5.5-net-phylink-update-to-use-phy_support_asym_pause.patch b/target/linux/generic/backport-4.19/739-v5.5-net-phylink-update-to-use-phy_support_asym_pause.patch deleted file mode 100644 index 15db0abc96..0000000000 --- a/target/linux/generic/backport-4.19/739-v5.5-net-phylink-update-to-use-phy_support_asym_pause.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 09d7d8395ec61fba4392b35baa6f71c4e36489df Mon Sep 17 00:00:00 2001 -From: Russell King <rmk+kernel@armlinux.org.uk> -Date: Fri, 8 Nov 2019 15:18:02 +0000 -Subject: [PATCH 637/660] net: phylink: update to use phy_support_asym_pause() - -Use phy_support_asym_pause() rather than open-coding it. - -Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> ---- - drivers/net/phy/phylink.c | 17 +++++++---------- - 1 file changed, 7 insertions(+), 10 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -678,12 +678,6 @@ static int phylink_bringup_phy(struct ph - u32 advertising; - int ret; - -- memset(&config, 0, sizeof(config)); -- ethtool_convert_legacy_u32_to_link_mode(supported, phy->supported); -- ethtool_convert_legacy_u32_to_link_mode(config.advertising, -- phy->advertising); -- config.interface = pl->link_config.interface; -- - /* - * This is the new way of dealing with flow control for PHYs, - * as described by Timur Tabi in commit 529ed1275263 ("net: phy: -@@ -691,10 +685,13 @@ static int phylink_bringup_phy(struct ph - * using our validate call to the MAC, we rely upon the MAC - * clearing the bits from both supported and advertising fields. - */ -- if (phylink_test(supported, Pause)) -- phylink_set(config.advertising, Pause); -- if (phylink_test(supported, Asym_Pause)) -- phylink_set(config.advertising, Asym_Pause); -+ phy_support_asym_pause(phy); -+ -+ memset(&config, 0, sizeof(config)); -+ ethtool_convert_legacy_u32_to_link_mode(supported, phy->supported); -+ ethtool_convert_legacy_u32_to_link_mode(config.advertising, -+ phy->advertising); -+ config.interface = pl->link_config.interface; - - ret = phylink_validate(pl, supported, &config); - if (ret) diff --git a/target/linux/generic/backport-4.19/740-v5.5-net-phy-avoid-matching-all-ones-clause-45-PHY-IDs.patch b/target/linux/generic/backport-4.19/740-v5.5-net-phy-avoid-matching-all-ones-clause-45-PHY-IDs.patch deleted file mode 100644 index 56bf507720..0000000000 --- a/target/linux/generic/backport-4.19/740-v5.5-net-phy-avoid-matching-all-ones-clause-45-PHY-IDs.patch +++ /dev/null @@ -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 -@@ -339,7 +339,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) == -@@ -629,10 +629,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); diff --git a/target/linux/generic/backport-4.19/741-v5.5-net-phylink-fix-link-mode-modification-in-PHY-mode.patch b/target/linux/generic/backport-4.19/741-v5.5-net-phylink-fix-link-mode-modification-in-PHY-mode.patch deleted file mode 100644 index 596ecc8272..0000000000 --- a/target/linux/generic/backport-4.19/741-v5.5-net-phylink-fix-link-mode-modification-in-PHY-mode.patch +++ /dev/null @@ -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); diff --git a/target/linux/generic/backport-4.19/744-v5.5-net-sfp-soft-status-and-control-support.patch b/target/linux/generic/backport-4.19/744-v5.5-net-sfp-soft-status-and-control-support.patch deleted file mode 100644 index 163d8072e6..0000000000 --- a/target/linux/generic/backport-4.19/744-v5.5-net-sfp-soft-status-and-control-support.patch +++ /dev/null @@ -1,225 +0,0 @@ -From 40e0b3b15f7da92e6b065292b14af7b9bfb1c6e0 Mon Sep 17 00:00:00 2001 -From: Russell King <rmk+kernel@armlinux.org.uk> -Date: Fri, 13 Sep 2019 23:00:35 +0100 -Subject: [PATCH 642/660] net: sfp: soft status and control support - -Add support for the soft status and control register, which allows -TX_FAULT and RX_LOS to be monitored and TX_DISABLE to be set. We -make use of this when the board does not support GPIOs for these -signals. - -Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> ---- - drivers/net/phy/sfp.c | 110 ++++++++++++++++++++++++++++++++++-------- - include/linux/sfp.h | 4 ++ - 2 files changed, 94 insertions(+), 20 deletions(-) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -199,7 +199,10 @@ struct sfp { - struct gpio_desc *gpio[GPIO_MAX]; - int gpio_irq[GPIO_MAX]; - -+ bool need_poll; -+ - struct mutex st_mutex; /* Protects state */ -+ unsigned int state_soft_mask; - unsigned int state; - struct delayed_work poll; - struct delayed_work timeout; -@@ -393,24 +396,90 @@ static int sfp_i2c_configure(struct sfp - } - - /* Interface */ --static unsigned int sfp_get_state(struct sfp *sfp) -+static int sfp_read(struct sfp *sfp, bool a2, u8 addr, void *buf, size_t len) - { -- return sfp->get_state(sfp); -+ return sfp->read(sfp, a2, addr, buf, len); - } - --static void sfp_set_state(struct sfp *sfp, unsigned int state) -+static int sfp_write(struct sfp *sfp, bool a2, u8 addr, void *buf, size_t len) - { -- sfp->set_state(sfp, state); -+ return sfp->write(sfp, a2, addr, buf, len); - } - --static int sfp_read(struct sfp *sfp, bool a2, u8 addr, void *buf, size_t len) -+static unsigned int sfp_soft_get_state(struct sfp *sfp) - { -- return sfp->read(sfp, a2, addr, buf, len); -+ unsigned int state = 0; -+ u8 status; -+ -+ if (sfp_read(sfp, true, SFP_STATUS, &status, sizeof(status)) == -+ sizeof(status)) { -+ if (status & SFP_STATUS_RX_LOS) -+ state |= SFP_F_LOS; -+ if (status & SFP_STATUS_TX_FAULT) -+ state |= SFP_F_TX_FAULT; -+ } -+ -+ return state & sfp->state_soft_mask; - } - --static int sfp_write(struct sfp *sfp, bool a2, u8 addr, void *buf, size_t len) -+static void sfp_soft_set_state(struct sfp *sfp, unsigned int state) - { -- return sfp->write(sfp, a2, addr, buf, len); -+ u8 status; -+ -+ if (sfp_read(sfp, true, SFP_STATUS, &status, sizeof(status)) == -+ sizeof(status)) { -+ if (state & SFP_F_TX_DISABLE) -+ status |= SFP_STATUS_TX_DISABLE_FORCE; -+ else -+ status &= ~SFP_STATUS_TX_DISABLE_FORCE; -+ -+ sfp_write(sfp, true, SFP_STATUS, &status, sizeof(status)); -+ } -+} -+ -+static void sfp_soft_start_poll(struct sfp *sfp) -+{ -+ const struct sfp_eeprom_id *id = &sfp->id; -+ -+ sfp->state_soft_mask = 0; -+ if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_DISABLE && -+ !sfp->gpio[GPIO_TX_DISABLE]) -+ sfp->state_soft_mask |= SFP_F_TX_DISABLE; -+ if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_FAULT && -+ !sfp->gpio[GPIO_TX_FAULT]) -+ sfp->state_soft_mask |= SFP_F_TX_FAULT; -+ if (id->ext.enhopts & SFP_ENHOPTS_SOFT_RX_LOS && -+ !sfp->gpio[GPIO_LOS]) -+ sfp->state_soft_mask |= SFP_F_LOS; -+ -+ if (sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT) && -+ !sfp->need_poll) -+ mod_delayed_work(system_wq, &sfp->poll, poll_jiffies); -+} -+ -+static void sfp_soft_stop_poll(struct sfp *sfp) -+{ -+ sfp->state_soft_mask = 0; -+} -+ -+static unsigned int sfp_get_state(struct sfp *sfp) -+{ -+ unsigned int state = sfp->get_state(sfp); -+ -+ if (state & SFP_F_PRESENT && -+ sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT)) -+ state |= sfp_soft_get_state(sfp); -+ -+ return state; -+} -+ -+static void sfp_set_state(struct sfp *sfp, unsigned int state) -+{ -+ sfp->set_state(sfp, state); -+ -+ if (state & SFP_F_PRESENT && -+ sfp->state_soft_mask & SFP_F_TX_DISABLE) -+ sfp_soft_set_state(sfp, state); - } - - static unsigned int sfp_check(void *buf, size_t len) -@@ -1342,11 +1411,6 @@ static void sfp_sm_fault(struct sfp *sfp - } - } - --static void sfp_sm_mod_init(struct sfp *sfp) --{ -- sfp_module_tx_enable(sfp); --} -- - static void sfp_sm_probe_for_phy(struct sfp *sfp) - { - /* Setting the serdes link mode is guesswork: there's no -@@ -1509,7 +1573,7 @@ static int sfp_sm_mod_probe(struct sfp * - (int)sizeof(id.ext.datecode), id.ext.datecode); - - /* Check whether we support this module */ -- if (!sfp->type->module_supported(&sfp->id)) { -+ if (!sfp->type->module_supported(&id)) { - dev_err(sfp->dev, - "module is not supported - phys id 0x%02x 0x%02x\n", - sfp->id.base.phys_id, sfp->id.base.phys_ext_id); -@@ -1699,6 +1763,7 @@ static void sfp_sm_main(struct sfp *sfp, - if (sfp->mod_phy) - sfp_sm_phy_detach(sfp); - sfp_module_tx_disable(sfp); -+ sfp_soft_stop_poll(sfp); - sfp_sm_next(sfp, SFP_S_DOWN, 0); - return; - } -@@ -1710,7 +1775,10 @@ static void sfp_sm_main(struct sfp *sfp, - sfp->sm_dev_state != SFP_DEV_UP) - break; - -- sfp_sm_mod_init(sfp); -+ if (!(sfp->id.ext.diagmon & SFP_DIAGMON_ADDRMODE)) -+ sfp_soft_start_poll(sfp); -+ -+ sfp_module_tx_enable(sfp); - - /* Initialise the fault clearance retries */ - sfp->sm_retries = 5; -@@ -1966,7 +2034,10 @@ static void sfp_poll(struct work_struct - struct sfp *sfp = container_of(work, struct sfp, poll.work); - - sfp_check_state(sfp); -- mod_delayed_work(system_wq, &sfp->poll, poll_jiffies); -+ -+ if (sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT) || -+ sfp->need_poll) -+ mod_delayed_work(system_wq, &sfp->poll, poll_jiffies); - } - - static struct sfp *sfp_alloc(struct device *dev) -@@ -2010,7 +2081,6 @@ static int sfp_probe(struct platform_dev - { - const struct sff_data *sff; - struct sfp *sfp; -- bool poll = false; - int err, i; - - sfp = sfp_alloc(&pdev->dev); -@@ -2100,7 +2170,7 @@ static int sfp_probe(struct platform_dev - - sfp->gpio_irq[i] = gpiod_to_irq(sfp->gpio[i]); - if (!sfp->gpio_irq[i]) { -- poll = true; -+ sfp->need_poll = true; - continue; - } - -@@ -2112,11 +2182,11 @@ static int sfp_probe(struct platform_dev - dev_name(sfp->dev), sfp); - if (err) { - sfp->gpio_irq[i] = 0; -- poll = true; -+ sfp->need_poll = true; - } - } - -- if (poll) -+ if (sfp->need_poll) - mod_delayed_work(system_wq, &sfp->poll, poll_jiffies); - - /* We could have an issue in cases no Tx disable pin is available or ---- a/include/linux/sfp.h -+++ b/include/linux/sfp.h -@@ -428,6 +428,10 @@ enum { - SFP_TEC_CUR = 0x6c, - - SFP_STATUS = 0x6e, -+ SFP_STATUS_TX_DISABLE = BIT(7), -+ SFP_STATUS_TX_DISABLE_FORCE = BIT(6), -+ SFP_STATUS_TX_FAULT = BIT(2), -+ SFP_STATUS_RX_LOS = BIT(1), - SFP_ALARM0 = 0x70, - SFP_ALARM0_TEMP_HIGH = BIT(7), - SFP_ALARM0_TEMP_LOW = BIT(6), diff --git a/target/linux/generic/backport-4.19/825-v5.8-spi-rb4xx-null-pointer-bug-fix.patch b/target/linux/generic/backport-4.19/825-v5.8-spi-rb4xx-null-pointer-bug-fix.patch deleted file mode 100644 index 811fe277dd..0000000000 --- a/target/linux/generic/backport-4.19/825-v5.8-spi-rb4xx-null-pointer-bug-fix.patch +++ /dev/null @@ -1,48 +0,0 @@ -From: Christopher Hill <ch6574@gmail.com> -To: Mark Brown <broonie@kernel.org> -Cc: Christopher Hill <ch6574@gmail.com>, linux-spi@vger.kernel.org, - linux-kernel@vger.kernel.org -Subject: [PATCH 1/3] spi: rb4xx: null pointer bug fix -Date: Thu, 21 May 2020 14:36:29 -0400 -Message-Id: <20200521183631.37806-1-ch6574@gmail.com> -X-Mailer: git-send-email 2.25.1 -MIME-Version: 1.0 -Sender: linux-spi-owner@vger.kernel.org -Precedence: bulk -List-ID: <linux-spi.vger.kernel.org> -X-Mailing-List: linux-spi@vger.kernel.org - -This patch fixes a null pointer bug in the spi driver spi-rb4xx.c by -moving the private data initialization to earlier in probe - -Signed-off-by: Christopher Hill <ch6574@gmail.com> ---- - drivers/spi/spi-rb4xx.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - ---- a/drivers/spi/spi-rb4xx.c -+++ b/drivers/spi/spi-rb4xx.c -@@ -164,6 +164,11 @@ static int rb4xx_spi_probe(struct platfo - master->transfer_one = rb4xx_transfer_one; - master->set_cs = rb4xx_set_cs; - -+ rbspi = spi_master_get_devdata(master); -+ rbspi->base = spi_base; -+ rbspi->clk = ahb_clk; -+ platform_set_drvdata(pdev, rbspi); -+ - err = devm_spi_register_master(&pdev->dev, master); - if (err) { - dev_err(&pdev->dev, "failed to register SPI master\n"); -@@ -174,11 +179,6 @@ static int rb4xx_spi_probe(struct platfo - if (err) - return err; - -- rbspi = spi_master_get_devdata(master); -- rbspi->base = spi_base; -- rbspi->clk = ahb_clk; -- platform_set_drvdata(pdev, rbspi); -- - /* Enable SPI */ - rb4xx_write(rbspi, AR71XX_SPI_REG_FS, AR71XX_SPI_FS_GPIO); - diff --git a/target/linux/generic/backport-4.19/826-v5.8-spi-rb4xx-update-driver-to-be-device-tree-aware.patch b/target/linux/generic/backport-4.19/826-v5.8-spi-rb4xx-update-driver-to-be-device-tree-aware.patch deleted file mode 100644 index d3e654e974..0000000000 --- a/target/linux/generic/backport-4.19/826-v5.8-spi-rb4xx-update-driver-to-be-device-tree-aware.patch +++ /dev/null @@ -1,60 +0,0 @@ -From: Christopher Hill <ch6574@gmail.com> -To: Mark Brown <broonie@kernel.org> -Cc: Christopher Hill <ch6574@gmail.com>, linux-spi@vger.kernel.org, - linux-kernel@vger.kernel.org -Subject: [PATCH 2/3] spi: rb4xx: update driver to be device tree aware -Date: Thu, 21 May 2020 14:36:30 -0400 -Message-Id: <20200521183631.37806-2-ch6574@gmail.com> -X-Mailer: git-send-email 2.25.1 -In-Reply-To: <20200521183631.37806-1-ch6574@gmail.com> -References: <20200521183631.37806-1-ch6574@gmail.com> -MIME-Version: 1.0 -Sender: linux-spi-owner@vger.kernel.org -Precedence: bulk -List-ID: <linux-spi.vger.kernel.org> -X-Mailing-List: linux-spi@vger.kernel.org - -This patch updates the spi driver spi-rb4xx.c to be device tree aware - -Signed-off-by: Christopher Hill <ch6574@gmail.com> ---- - drivers/spi/spi-rb4xx.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - ---- a/drivers/spi/spi-rb4xx.c -+++ b/drivers/spi/spi-rb4xx.c -@@ -18,6 +18,7 @@ - #include <linux/platform_device.h> - #include <linux/clk.h> - #include <linux/spi/spi.h> -+#include <linux/of.h> - - #include <asm/mach-ath79/ar71xx_regs.h> - -@@ -156,6 +157,7 @@ static int rb4xx_spi_probe(struct platfo - if (IS_ERR(ahb_clk)) - return PTR_ERR(ahb_clk); - -+ master->dev.of_node = pdev->dev.of_node; - master->bus_num = 0; - master->num_chipselect = 3; - master->mode_bits = SPI_TX_DUAL; -@@ -194,11 +196,18 @@ static int rb4xx_spi_remove(struct platf - return 0; - } - -+static const struct of_device_id rb4xx_spi_dt_match[] = { -+ { .compatible = "mikrotik,rb4xx-spi" }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(of, rb4xx_spi_dt_match); -+ - static struct platform_driver rb4xx_spi_drv = { - .probe = rb4xx_spi_probe, - .remove = rb4xx_spi_remove, - .driver = { - .name = "rb4xx-spi", -+ .of_match_table = of_match_ptr(rb4xx_spi_dt_match), - }, - }; - |