linux-6.12-rc6
Signed-off-by: sbwml <admin@cooluc.com>
This commit is contained in:
commit
2995a2080c
123
backport-6.12/002-struct-net_device.patch
Normal file
123
backport-6.12/002-struct-net_device.patch
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
--- a/include/linux/netdevice.h
|
||||||
|
+++ b/include/linux/netdevice.h
|
||||||
|
@@ -2224,12 +2224,8 @@ struct net_device {
|
||||||
|
#if IS_ENABLED(CONFIG_AX25)
|
||||||
|
void *ax25_ptr;
|
||||||
|
#endif
|
||||||
|
-#if IS_ENABLED(CONFIG_CFG80211)
|
||||||
|
struct wireless_dev *ieee80211_ptr;
|
||||||
|
-#endif
|
||||||
|
-#if IS_ENABLED(CONFIG_IEEE802154) || IS_ENABLED(CONFIG_6LOWPAN)
|
||||||
|
struct wpan_dev *ieee802154_ptr;
|
||||||
|
-#endif
|
||||||
|
#if IS_ENABLED(CONFIG_MPLS_ROUTING)
|
||||||
|
struct mpls_dev __rcu *mpls_ptr;
|
||||||
|
#endif
|
||||||
|
--- a/include/net/cfg802154.h
|
||||||
|
+++ b/include/net/cfg802154.h
|
||||||
|
@@ -513,7 +513,6 @@ struct wpan_dev {
|
||||||
|
|
||||||
|
#define to_phy(_dev) container_of(_dev, struct wpan_phy, dev)
|
||||||
|
|
||||||
|
-#if IS_ENABLED(CONFIG_IEEE802154) || IS_ENABLED(CONFIG_6LOWPAN)
|
||||||
|
static inline int
|
||||||
|
wpan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
|
||||||
|
const struct ieee802154_addr *daddr,
|
||||||
|
@@ -524,7 +523,6 @@ wpan_dev_hard_header(struct sk_buff *skb
|
||||||
|
|
||||||
|
return wpan_dev->header_ops->create(skb, dev, daddr, saddr, len);
|
||||||
|
}
|
||||||
|
-#endif
|
||||||
|
|
||||||
|
struct wpan_phy *
|
||||||
|
wpan_phy_new(const struct cfg802154_ops *ops, size_t priv_size);
|
||||||
|
--- a/net/batman-adv/hard-interface.c
|
||||||
|
+++ b/net/batman-adv/hard-interface.c
|
||||||
|
@@ -309,11 +309,9 @@ static bool batadv_is_cfg80211_netdev(st
|
||||||
|
if (!net_device)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
-#if IS_ENABLED(CONFIG_CFG80211)
|
||||||
|
/* cfg80211 drivers have to set ieee80211_ptr */
|
||||||
|
if (net_device->ieee80211_ptr)
|
||||||
|
return true;
|
||||||
|
-#endif
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
--- a/net/core/net-sysfs.c
|
||||||
|
+++ b/net/core/net-sysfs.c
|
||||||
|
@@ -769,6 +769,7 @@ static const struct attribute_group nets
|
||||||
|
.attrs = netstat_attrs,
|
||||||
|
};
|
||||||
|
|
||||||
|
+#if IS_ENABLED(CONFIG_WIRELESS_EXT) || IS_ENABLED(CONFIG_CFG80211)
|
||||||
|
static struct attribute *wireless_attrs[] = {
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
@@ -777,19 +778,7 @@ static const struct attribute_group wire
|
||||||
|
.name = "wireless",
|
||||||
|
.attrs = wireless_attrs,
|
||||||
|
};
|
||||||
|
-
|
||||||
|
-static bool wireless_group_needed(struct net_device *ndev)
|
||||||
|
-{
|
||||||
|
-#if IS_ENABLED(CONFIG_CFG80211)
|
||||||
|
- if (ndev->ieee80211_ptr)
|
||||||
|
- return true;
|
||||||
|
#endif
|
||||||
|
-#if IS_ENABLED(CONFIG_WIRELESS_EXT)
|
||||||
|
- if (ndev->wireless_handlers)
|
||||||
|
- return true;
|
||||||
|
-#endif
|
||||||
|
- return false;
|
||||||
|
-}
|
||||||
|
|
||||||
|
#else /* CONFIG_SYSFS */
|
||||||
|
#define net_class_groups NULL
|
||||||
|
@@ -2132,8 +2121,14 @@ int netdev_register_kobject(struct net_d
|
||||||
|
|
||||||
|
*groups++ = &netstat_group;
|
||||||
|
|
||||||
|
- if (wireless_group_needed(ndev))
|
||||||
|
+#if IS_ENABLED(CONFIG_WIRELESS_EXT) || IS_ENABLED(CONFIG_CFG80211)
|
||||||
|
+ if (ndev->ieee80211_ptr)
|
||||||
|
+ *groups++ = &wireless_group;
|
||||||
|
+#if IS_ENABLED(CONFIG_WIRELESS_EXT)
|
||||||
|
+ else if (ndev->wireless_handlers)
|
||||||
|
*groups++ = &wireless_group;
|
||||||
|
+#endif
|
||||||
|
+#endif
|
||||||
|
#endif /* CONFIG_SYSFS */
|
||||||
|
|
||||||
|
error = device_add(dev);
|
||||||
|
--- a/include/linux/pci.h
|
||||||
|
+++ b/include/linux/pci.h
|
||||||
|
@@ -1080,6 +1080,8 @@ enum {
|
||||||
|
#define PCI_IRQ_MSIX (1 << 2) /* Allow MSI-X interrupts */
|
||||||
|
#define PCI_IRQ_AFFINITY (1 << 3) /* Auto-assign affinity */
|
||||||
|
|
||||||
|
+#define PCI_IRQ_LEGACY PCI_IRQ_INTX /* Deprecated! Use PCI_IRQ_INTX */
|
||||||
|
+
|
||||||
|
/* These external functions are only available when PCI support is enabled */
|
||||||
|
#ifdef CONFIG_PCI
|
||||||
|
|
||||||
|
@@ -1645,7 +1647,8 @@ int pci_set_vga_state(struct pci_dev *pd
|
||||||
|
*/
|
||||||
|
#define PCI_IRQ_VIRTUAL (1 << 4)
|
||||||
|
|
||||||
|
-#define PCI_IRQ_ALL_TYPES (PCI_IRQ_INTX | PCI_IRQ_MSI | PCI_IRQ_MSIX)
|
||||||
|
+#define PCI_IRQ_ALL_TYPES \
|
||||||
|
+ (PCI_IRQ_LEGACY | PCI_IRQ_MSI | PCI_IRQ_MSIX)
|
||||||
|
|
||||||
|
#include <linux/dmapool.h>
|
||||||
|
|
||||||
|
@@ -1708,7 +1711,7 @@ pci_alloc_irq_vectors_affinity(struct pc
|
||||||
|
unsigned int max_vecs, unsigned int flags,
|
||||||
|
struct irq_affinity *aff_desc)
|
||||||
|
{
|
||||||
|
- if ((flags & PCI_IRQ_INTX) && min_vecs == 1 && dev->irq)
|
||||||
|
+ if ((flags & PCI_IRQ_LEGACY) && min_vecs == 1 && dev->irq)
|
||||||
|
return 1;
|
||||||
|
return -ENOSPC;
|
||||||
|
}
|
8354
config-6.12
Normal file
8354
config-6.12
Normal file
File diff suppressed because it is too large
Load Diff
39
hack-6.12/100-mm-memcontrol-v1-drop-warning-message.patch
Normal file
39
hack-6.12/100-mm-memcontrol-v1-drop-warning-message.patch
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
From c99ad062effe9b733a3216fa8af909245c2e23d3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: sbwml <admin@cooluc.com>
|
||||||
|
Date: Sat, 12 Oct 2024 09:49:43 +0800
|
||||||
|
Subject: [PATCH] mm: memcontrol-v1: drop warning message
|
||||||
|
|
||||||
|
Signed-off-by: sbwml <admin@cooluc.com>
|
||||||
|
---
|
||||||
|
mm/memcontrol-v1.c | 10 ----------
|
||||||
|
1 file changed, 10 deletions(-)
|
||||||
|
|
||||||
|
--- a/mm/memcontrol-v1.c
|
||||||
|
+++ b/mm/memcontrol-v1.c
|
||||||
|
@@ -1994,15 +1994,9 @@ static ssize_t memcg_write_event_control
|
||||||
|
event->register_event = mem_cgroup_usage_register_event;
|
||||||
|
event->unregister_event = mem_cgroup_usage_unregister_event;
|
||||||
|
} else if (!strcmp(name, "memory.oom_control")) {
|
||||||
|
- pr_warn_once("oom_control is deprecated and will be removed. "
|
||||||
|
- "Please report your usecase to linux-mm-@kvack.org"
|
||||||
|
- " if you depend on this functionality. \n");
|
||||||
|
event->register_event = mem_cgroup_oom_register_event;
|
||||||
|
event->unregister_event = mem_cgroup_oom_unregister_event;
|
||||||
|
} else if (!strcmp(name, "memory.pressure_level")) {
|
||||||
|
- pr_warn_once("pressure_level is deprecated and will be removed. "
|
||||||
|
- "Please report your usecase to linux-mm-@kvack.org "
|
||||||
|
- "if you depend on this functionality. \n");
|
||||||
|
event->register_event = vmpressure_register_event;
|
||||||
|
event->unregister_event = vmpressure_unregister_event;
|
||||||
|
} else if (!strcmp(name, "memory.memsw.usage_in_bytes")) {
|
||||||
|
@@ -2847,10 +2841,6 @@ static int mem_cgroup_oom_control_write(
|
||||||
|
{
|
||||||
|
struct mem_cgroup *memcg = mem_cgroup_from_css(css);
|
||||||
|
|
||||||
|
- pr_warn_once("oom_control is deprecated and will be removed. "
|
||||||
|
- "Please report your usecase to linux-mm-@kvack.org if you "
|
||||||
|
- "depend on this functionality. \n");
|
||||||
|
-
|
||||||
|
/* cannot set to root cgroup and only 0 and 1 are allowed */
|
||||||
|
if (mem_cgroup_is_root(memcg) || !((val == 0) || (val == 1)))
|
||||||
|
return -EINVAL;
|
173
hack-6.12/204-module_strip.patch
Normal file
173
hack-6.12/204-module_strip.patch
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
From a779a482fb9b9f8fcdf8b2519c789b4b9bb5dd05 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Fri, 7 Jul 2017 16:56:48 +0200
|
||||||
|
Subject: build: add a hack for removing non-essential module info
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
include/linux/module.h | 13 ++++++++-----
|
||||||
|
include/linux/moduleparam.h | 15 ++++++++++++---
|
||||||
|
init/Kconfig | 7 +++++++
|
||||||
|
kernel/module.c | 5 ++++-
|
||||||
|
scripts/mod/modpost.c | 12 ++++++++++++
|
||||||
|
5 files changed, 43 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
--- a/include/linux/module.h
|
||||||
|
+++ b/include/linux/module.h
|
||||||
|
@@ -164,6 +164,7 @@ extern void cleanup_module(void);
|
||||||
|
|
||||||
|
/* Generic info of form tag = "info" */
|
||||||
|
#define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info)
|
||||||
|
+#define MODULE_INFO_STRIP(tag, info) __MODULE_INFO_STRIP(tag, tag, info)
|
||||||
|
|
||||||
|
/* For userspace: you can also call me... */
|
||||||
|
#define MODULE_ALIAS(_alias) MODULE_INFO(alias, _alias)
|
||||||
|
@@ -239,12 +240,12 @@ extern void cleanup_module(void);
|
||||||
|
* Author(s), use "Name <email>" or just "Name", for multiple
|
||||||
|
* authors use multiple MODULE_AUTHOR() statements/lines.
|
||||||
|
*/
|
||||||
|
-#define MODULE_AUTHOR(_author) MODULE_INFO(author, _author)
|
||||||
|
+#define MODULE_AUTHOR(_author) MODULE_INFO_STRIP(author, _author)
|
||||||
|
|
||||||
|
/* What your module does. */
|
||||||
|
-#define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description)
|
||||||
|
+#define MODULE_DESCRIPTION(_description) MODULE_INFO_STRIP(description, _description)
|
||||||
|
|
||||||
|
-#ifdef MODULE
|
||||||
|
+#if defined(MODULE) && !defined(CONFIG_MODULE_STRIPPED)
|
||||||
|
/* Creates an alias so file2alias.c can find device table. */
|
||||||
|
#define MODULE_DEVICE_TABLE(type, name) \
|
||||||
|
extern typeof(name) __mod_##type##__##name##_device_table \
|
||||||
|
@@ -271,7 +272,9 @@ extern typeof(name) __mod_##type##__##na
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(MODULE) || !defined(CONFIG_SYSFS)
|
||||||
|
-#define MODULE_VERSION(_version) MODULE_INFO(version, _version)
|
||||||
|
+#define MODULE_VERSION(_version) MODULE_INFO_STRIP(version, _version)
|
||||||
|
+#elif defined(CONFIG_MODULE_STRIPPED)
|
||||||
|
+#define MODULE_VERSION(_version) __MODULE_INFO_DISABLED(version)
|
||||||
|
#else
|
||||||
|
#define MODULE_VERSION(_version) \
|
||||||
|
MODULE_INFO(version, _version); \
|
||||||
|
@@ -294,7 +297,7 @@ extern typeof(name) __mod_##type##__##na
|
||||||
|
/* Optional firmware file (or files) needed by the module
|
||||||
|
* format is simply firmware file name. Multiple firmware
|
||||||
|
* files require multiple MODULE_FIRMWARE() specifiers */
|
||||||
|
-#define MODULE_FIRMWARE(_firmware) MODULE_INFO(firmware, _firmware)
|
||||||
|
+#define MODULE_FIRMWARE(_firmware) MODULE_INFO_STRIP(firmware, _firmware)
|
||||||
|
|
||||||
|
#define MODULE_IMPORT_NS(ns) MODULE_INFO(import_ns, __stringify(ns))
|
||||||
|
|
||||||
|
--- a/include/linux/moduleparam.h
|
||||||
|
+++ b/include/linux/moduleparam.h
|
||||||
|
@@ -20,6 +20,16 @@
|
||||||
|
/* Chosen so that structs with an unsigned long line up. */
|
||||||
|
#define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long))
|
||||||
|
|
||||||
|
+/* This struct is here for syntactic coherency, it is not used */
|
||||||
|
+#define __MODULE_INFO_DISABLED(name) \
|
||||||
|
+ struct __UNIQUE_ID(name) {}
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_MODULE_STRIPPED
|
||||||
|
+#define __MODULE_INFO_STRIP(tag, name, info) __MODULE_INFO_DISABLED(name)
|
||||||
|
+#else
|
||||||
|
+#define __MODULE_INFO_STRIP(tag, name, info) __MODULE_INFO(tag, name, info)
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#define __MODULE_INFO(tag, name, info) \
|
||||||
|
static const char __UNIQUE_ID(name)[] \
|
||||||
|
__used __section(".modinfo") __aligned(1) \
|
||||||
|
@@ -31,7 +41,7 @@
|
||||||
|
/* One for each parameter, describing how to use it. Some files do
|
||||||
|
multiple of these per line, so can't just use MODULE_INFO. */
|
||||||
|
#define MODULE_PARM_DESC(_parm, desc) \
|
||||||
|
- __MODULE_INFO(parm, _parm, #_parm ":" desc)
|
||||||
|
+ __MODULE_INFO_STRIP(parm, _parm, #_parm ":" desc)
|
||||||
|
|
||||||
|
struct kernel_param;
|
||||||
|
|
||||||
|
--- a/kernel/module/Kconfig
|
||||||
|
+++ b/kernel/module/Kconfig
|
||||||
|
@@ -397,6 +397,13 @@ config UNUSED_KSYMS_WHITELIST
|
||||||
|
one per line. The path can be absolute, or relative to the kernel
|
||||||
|
source or obj tree.
|
||||||
|
|
||||||
|
+config MODULE_STRIPPED
|
||||||
|
+ bool "Reduce module size"
|
||||||
|
+ depends on MODULES
|
||||||
|
+ help
|
||||||
|
+ Remove module parameter descriptions, author info, version, aliases,
|
||||||
|
+ device tables, etc.
|
||||||
|
+
|
||||||
|
config MODULES_TREE_LOOKUP
|
||||||
|
def_bool y
|
||||||
|
depends on PERF_EVENTS || TRACING || CFI_CLANG
|
||||||
|
--- a/kernel/module/main.c
|
||||||
|
+++ b/kernel/module/main.c
|
||||||
|
@@ -2093,9 +2093,11 @@ static void module_augment_kernel_taints
|
||||||
|
|
||||||
|
static int check_modinfo(struct module *mod, struct load_info *info, int flags)
|
||||||
|
{
|
||||||
|
- const char *modmagic = get_modinfo(info, "vermagic");
|
||||||
|
int err;
|
||||||
|
|
||||||
|
+#ifndef CONFIG_MODULE_STRIPPED
|
||||||
|
+ const char *modmagic = get_modinfo(info, "vermagic");
|
||||||
|
+
|
||||||
|
if (flags & MODULE_INIT_IGNORE_VERMAGIC)
|
||||||
|
modmagic = NULL;
|
||||||
|
|
||||||
|
@@ -2109,6 +2111,7 @@ static int check_modinfo(struct module *
|
||||||
|
info->name, modmagic, vermagic);
|
||||||
|
return -ENOEXEC;
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
err = check_modinfo_livepatch(mod, info);
|
||||||
|
if (err)
|
||||||
|
--- a/scripts/mod/modpost.c
|
||||||
|
+++ b/scripts/mod/modpost.c
|
||||||
|
@@ -1601,7 +1601,9 @@ static void read_symbols(const char *mod
|
||||||
|
symname = remove_dot(info.strtab + sym->st_name);
|
||||||
|
|
||||||
|
handle_symbol(mod, &info, sym, symname);
|
||||||
|
+#ifndef CONFIG_MODULE_STRIPPED
|
||||||
|
handle_moddevtable(mod, &info, sym, symname);
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
check_sec_ref(mod, &info);
|
||||||
|
@@ -1758,7 +1760,9 @@ static void add_header(struct buffer *b,
|
||||||
|
buf_printf(b, "#include <linux/export-internal.h>\n");
|
||||||
|
buf_printf(b, "#include <linux/compiler.h>\n");
|
||||||
|
buf_printf(b, "\n");
|
||||||
|
+#ifndef CONFIG_MODULE_STRIPPED
|
||||||
|
buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n");
|
||||||
|
+#endif
|
||||||
|
buf_printf(b, "\n");
|
||||||
|
buf_printf(b, "__visible struct module __this_module\n");
|
||||||
|
buf_printf(b, "__section(\".gnu.linkonce.this_module\") = {\n");
|
||||||
|
@@ -1886,11 +1890,13 @@ static void add_depends(struct buffer *b
|
||||||
|
|
||||||
|
static void add_srcversion(struct buffer *b, struct module *mod)
|
||||||
|
{
|
||||||
|
+#ifndef CONFIG_MODULE_STRIPPED
|
||||||
|
if (mod->srcversion[0]) {
|
||||||
|
buf_printf(b, "\n");
|
||||||
|
buf_printf(b, "MODULE_INFO(srcversion, \"%s\");\n",
|
||||||
|
mod->srcversion);
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void write_buf(struct buffer *b, const char *fname)
|
||||||
|
@@ -1973,7 +1979,9 @@ static void write_mod_c_file(struct modu
|
||||||
|
add_exported_symbols(&buf, mod);
|
||||||
|
add_versions(&buf, mod);
|
||||||
|
add_depends(&buf, mod);
|
||||||
|
+#ifndef CONFIG_MODULE_STRIPPED
|
||||||
|
add_moddevtable(&buf, mod);
|
||||||
|
+#endif
|
||||||
|
add_srcversion(&buf, mod);
|
||||||
|
|
||||||
|
ret = snprintf(fname, sizeof(fname), "%s.mod.c", mod->name);
|
11
hack-6.12/205-kconfig-exit.patch
Normal file
11
hack-6.12/205-kconfig-exit.patch
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
--- a/scripts/kconfig/conf.c
|
||||||
|
+++ b/scripts/kconfig/conf.c
|
||||||
|
@@ -406,6 +406,8 @@ static int conf_sym(struct menu *menu)
|
||||||
|
break;
|
||||||
|
continue;
|
||||||
|
case 0:
|
||||||
|
+ if (!sym_has_value(sym) && !tty_stdio && getenv("FAIL_ON_UNCONFIGURED"))
|
||||||
|
+ exit(1);
|
||||||
|
newval = oldval;
|
||||||
|
break;
|
||||||
|
case '?':
|
3053
hack-6.12/210-darwin_scripts_include.patch
Normal file
3053
hack-6.12/210-darwin_scripts_include.patch
Normal file
File diff suppressed because it is too large
Load Diff
22
hack-6.12/211-darwin-uuid-typedef-clash.patch
Normal file
22
hack-6.12/211-darwin-uuid-typedef-clash.patch
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
From e44fc2af1ddc452b6659d08c16973d65c73b7d0a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||||
|
Date: Wed, 5 Feb 2020 18:36:43 +0000
|
||||||
|
Subject: [PATCH] file2alias: build on macos
|
||||||
|
|
||||||
|
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||||
|
---
|
||||||
|
scripts/mod/file2alias.c | 3 +++
|
||||||
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
|
--- a/scripts/mod/file2alias.c
|
||||||
|
+++ b/scripts/mod/file2alias.c
|
||||||
|
@@ -40,6 +40,9 @@ typedef struct {
|
||||||
|
__u8 b[16];
|
||||||
|
} guid_t;
|
||||||
|
|
||||||
|
+#ifdef __APPLE__
|
||||||
|
+#define uuid_t compat_uuid_t
|
||||||
|
+#endif
|
||||||
|
typedef struct {
|
||||||
|
__u8 b[16];
|
||||||
|
} uuid_t;
|
83
hack-6.12/212-tools_portability.patch
Normal file
83
hack-6.12/212-tools_portability.patch
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
From 48232d3d931c95953ce2ddfe7da7bb164aef6a73 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Fri, 7 Jul 2017 17:03:16 +0200
|
||||||
|
Subject: fix portability of some includes files in tools/ used on the host
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
tools/include/tools/be_byteshift.h | 4 ++++
|
||||||
|
tools/include/tools/le_byteshift.h | 4 ++++
|
||||||
|
tools/include/tools/linux_types.h | 22 ++++++++++++++++++++++
|
||||||
|
3 files changed, 30 insertions(+)
|
||||||
|
create mode 100644 tools/include/tools/linux_types.h
|
||||||
|
|
||||||
|
--- a/tools/include/tools/be_byteshift.h
|
||||||
|
+++ b/tools/include/tools/be_byteshift.h
|
||||||
|
@@ -2,6 +2,10 @@
|
||||||
|
#ifndef _TOOLS_BE_BYTESHIFT_H
|
||||||
|
#define _TOOLS_BE_BYTESHIFT_H
|
||||||
|
|
||||||
|
+#ifndef __linux__
|
||||||
|
+#include "linux_types.h"
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
static inline uint16_t __get_unaligned_be16(const uint8_t *p)
|
||||||
|
--- a/tools/include/tools/le_byteshift.h
|
||||||
|
+++ b/tools/include/tools/le_byteshift.h
|
||||||
|
@@ -2,6 +2,10 @@
|
||||||
|
#ifndef _TOOLS_LE_BYTESHIFT_H
|
||||||
|
#define _TOOLS_LE_BYTESHIFT_H
|
||||||
|
|
||||||
|
+#ifndef __linux__
|
||||||
|
+#include "linux_types.h"
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
static inline uint16_t __get_unaligned_le16(const uint8_t *p)
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tools/include/tools/linux_types.h
|
||||||
|
@@ -0,0 +1,26 @@
|
||||||
|
+#ifndef __LINUX_TYPES_H
|
||||||
|
+#define __LINUX_TYPES_H
|
||||||
|
+
|
||||||
|
+#include <stdint.h>
|
||||||
|
+
|
||||||
|
+typedef int8_t __s8;
|
||||||
|
+typedef uint8_t __u8;
|
||||||
|
+typedef uint8_t __be8;
|
||||||
|
+typedef uint8_t __le8;
|
||||||
|
+
|
||||||
|
+typedef int16_t __s16;
|
||||||
|
+typedef uint16_t __u16;
|
||||||
|
+typedef uint16_t __be16;
|
||||||
|
+typedef uint16_t __le16;
|
||||||
|
+
|
||||||
|
+typedef int32_t __s32;
|
||||||
|
+typedef uint32_t __u32;
|
||||||
|
+typedef uint32_t __be32;
|
||||||
|
+typedef uint32_t __le32;
|
||||||
|
+
|
||||||
|
+typedef int64_t __s64;
|
||||||
|
+typedef uint64_t __u64;
|
||||||
|
+typedef uint64_t __be64;
|
||||||
|
+typedef uint64_t __le64;
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
--- a/tools/include/linux/types.h
|
||||||
|
+++ b/tools/include/linux/types.h
|
||||||
|
@@ -10,8 +10,12 @@
|
||||||
|
#define __SANE_USERSPACE_TYPES__ /* For PPC64, to get LL64 types */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#ifndef __linux__
|
||||||
|
+#include <tools/linux_types.h>
|
||||||
|
+#else
|
||||||
|
#include <asm/types.h>
|
||||||
|
#include <asm/posix_types.h>
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
struct page;
|
||||||
|
struct kmem_cache;
|
24
hack-6.12/214-spidev_h_portability.patch
Normal file
24
hack-6.12/214-spidev_h_portability.patch
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
From be9be95ff10e16a5b4ad36f903978d0cc5747024 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Fri, 7 Jul 2017 17:04:08 +0200
|
||||||
|
Subject: kernel: fix linux/spi/spidev.h portability issues with musl
|
||||||
|
|
||||||
|
Felix will try to get this define included into musl
|
||||||
|
|
||||||
|
lede-commit: 795e7cf60de19e7a076a46874fab7bb88b43bbff
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
include/uapi/linux/spi/spidev.h | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/include/uapi/linux/spi/spidev.h
|
||||||
|
+++ b/include/uapi/linux/spi/spidev.h
|
||||||
|
@@ -93,7 +93,7 @@ struct spi_ioc_transfer {
|
||||||
|
|
||||||
|
/* not all platforms use <asm-generic/ioctl.h> or _IOC_TYPECHECK() ... */
|
||||||
|
#define SPI_MSGSIZE(N) \
|
||||||
|
- ((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << _IOC_SIZEBITS)) \
|
||||||
|
+ ((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << 13)) \
|
||||||
|
? ((N)*(sizeof (struct spi_ioc_transfer))) : 0)
|
||||||
|
#define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)])
|
||||||
|
|
103
hack-6.12/220-arm-gc_sections.patch
Normal file
103
hack-6.12/220-arm-gc_sections.patch
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
From e3d8676f5722b7622685581e06e8f53e6138e3ab Mon Sep 17 00:00:00 2001
|
||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Sat, 15 Jul 2017 23:42:36 +0200
|
||||||
|
Subject: use -ffunction-sections, -fdata-sections and --gc-sections
|
||||||
|
|
||||||
|
In combination with kernel symbol export stripping this significantly reduces
|
||||||
|
the kernel image size. Used on both ARM and MIPS architectures.
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
|
||||||
|
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
|
||||||
|
---
|
||||||
|
--- a/arch/arm/Kconfig
|
||||||
|
+++ b/arch/arm/Kconfig
|
||||||
|
@@ -136,6 +136,7 @@ config ARM
|
||||||
|
select HAVE_VIRT_CPU_ACCOUNTING_GEN
|
||||||
|
select HOTPLUG_CORE_SYNC_DEAD if HOTPLUG_CPU
|
||||||
|
select IRQ_FORCED_THREADING
|
||||||
|
+ select HAVE_LD_DEAD_CODE_DATA_ELIMINATION
|
||||||
|
select LOCK_MM_AND_FIND_VMA
|
||||||
|
select MODULES_USE_ELF_REL
|
||||||
|
select NEED_DMA_MAP_STATE
|
||||||
|
--- a/arch/arm/boot/compressed/Makefile
|
||||||
|
+++ b/arch/arm/boot/compressed/Makefile
|
||||||
|
@@ -86,6 +86,7 @@ endif
|
||||||
|
ifeq ($(CONFIG_USE_OF),y)
|
||||||
|
OBJS += $(libfdt_objs) fdt_check_mem_start.o
|
||||||
|
endif
|
||||||
|
+KBUILD_CFLAGS_KERNEL := $(patsubst -f%-sections,,$(KBUILD_CFLAGS_KERNEL))
|
||||||
|
|
||||||
|
OBJS += lib1funcs.o ashldi3.o bswapsdi2.o
|
||||||
|
|
||||||
|
--- a/arch/arm/kernel/vmlinux.lds.S
|
||||||
|
+++ b/arch/arm/kernel/vmlinux.lds.S
|
||||||
|
@@ -74,7 +74,7 @@ SECTIONS
|
||||||
|
. = ALIGN(4);
|
||||||
|
__ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
|
||||||
|
__start___ex_table = .;
|
||||||
|
- ARM_MMU_KEEP(KEEP(*(__ex_table)))
|
||||||
|
+ KEEP(*(__ex_table))
|
||||||
|
__stop___ex_table = .;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -104,13 +104,13 @@ SECTIONS
|
||||||
|
}
|
||||||
|
.init.tagtable : {
|
||||||
|
__tagtable_begin = .;
|
||||||
|
- *(.taglist.init)
|
||||||
|
+ KEEP(*(.taglist.init))
|
||||||
|
__tagtable_end = .;
|
||||||
|
}
|
||||||
|
#ifdef CONFIG_SMP_ON_UP
|
||||||
|
.init.smpalt : {
|
||||||
|
__smpalt_begin = .;
|
||||||
|
- *(.alt.smp.init)
|
||||||
|
+ KEEP(*(.alt.smp.init))
|
||||||
|
__smpalt_end = .;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
--- a/arch/arm/include/asm/vmlinux.lds.h
|
||||||
|
+++ b/arch/arm/include/asm/vmlinux.lds.h
|
||||||
|
@@ -48,7 +48,7 @@
|
||||||
|
#define IDMAP_TEXT \
|
||||||
|
ALIGN_FUNCTION(); \
|
||||||
|
__idmap_text_start = .; \
|
||||||
|
- *(.idmap.text) \
|
||||||
|
+ KEEP(*(.idmap.text)) \
|
||||||
|
__idmap_text_end = .; \
|
||||||
|
|
||||||
|
#define ARM_DISCARD \
|
||||||
|
@@ -108,12 +108,12 @@
|
||||||
|
. = ALIGN(8); \
|
||||||
|
.ARM.unwind_idx : { \
|
||||||
|
__start_unwind_idx = .; \
|
||||||
|
- *(.ARM.exidx*) \
|
||||||
|
+ KEEP(*(.ARM.exidx*)) \
|
||||||
|
__stop_unwind_idx = .; \
|
||||||
|
} \
|
||||||
|
.ARM.unwind_tab : { \
|
||||||
|
__start_unwind_tab = .; \
|
||||||
|
- *(.ARM.extab*) \
|
||||||
|
+ KEEP(*(.ARM.extab*)) \
|
||||||
|
__stop_unwind_tab = .; \
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -125,7 +125,7 @@
|
||||||
|
__vectors_lma = .; \
|
||||||
|
OVERLAY 0xffff0000 : NOCROSSREFS AT(__vectors_lma) { \
|
||||||
|
.vectors { \
|
||||||
|
- *(.vectors) \
|
||||||
|
+ KEEP(*(.vectors)) \
|
||||||
|
} \
|
||||||
|
.vectors.bhb.loop8 { \
|
||||||
|
*(.vectors.bhb.loop8) \
|
||||||
|
@@ -143,7 +143,7 @@
|
||||||
|
\
|
||||||
|
__stubs_lma = .; \
|
||||||
|
.stubs ADDR(.vectors) + 0x1000 : AT(__stubs_lma) { \
|
||||||
|
- *(.stubs) \
|
||||||
|
+ KEEP(*(.stubs)) \
|
||||||
|
} \
|
||||||
|
ARM_LMA(__stubs, .stubs); \
|
||||||
|
. = __stubs_lma + SIZEOF(.stubs); \
|
34
hack-6.12/230-openwrt_lzma_options.patch
Normal file
34
hack-6.12/230-openwrt_lzma_options.patch
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
From b3d00b452467f621317953d9e4c6f9ae8dcfd271 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Imre Kaloz <kaloz@openwrt.org>
|
||||||
|
Date: Fri, 7 Jul 2017 17:06:55 +0200
|
||||||
|
Subject: use the openwrt lzma options for now
|
||||||
|
|
||||||
|
lede-commit: 548de949f392049420a6a1feeef118b30ab8ea8c
|
||||||
|
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
|
||||||
|
---
|
||||||
|
lib/decompress.c | 1 +
|
||||||
|
scripts/Makefile.lib | 2 +-
|
||||||
|
usr/gen_initramfs_list.sh | 10 +++++-----
|
||||||
|
3 files changed, 7 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
--- a/lib/decompress.c
|
||||||
|
+++ b/lib/decompress.c
|
||||||
|
@@ -53,6 +53,7 @@ static const struct compress_format comp
|
||||||
|
{ {0x1f, 0x9e}, "gzip", gunzip },
|
||||||
|
{ {0x42, 0x5a}, "bzip2", bunzip2 },
|
||||||
|
{ {0x5d, 0x00}, "lzma", unlzma },
|
||||||
|
+ { {0x6d, 0x00}, "lzma-openwrt", unlzma },
|
||||||
|
{ {0xfd, 0x37}, "xz", unxz },
|
||||||
|
{ {0x89, 0x4c}, "lzo", unlzo },
|
||||||
|
{ {0x02, 0x21}, "lz4", unlz4 },
|
||||||
|
--- a/scripts/Makefile.lib
|
||||||
|
+++ b/scripts/Makefile.lib
|
||||||
|
@@ -359,7 +359,7 @@ quiet_cmd_bzip2_with_size = BZIP2 $@
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
quiet_cmd_lzma = LZMA $@
|
||||||
|
- cmd_lzma = cat $(real-prereqs) | $(LZMA) -9 > $@
|
||||||
|
+ cmd_lzma = { cat $(real-prereqs) | $(LZMA) e -d20 -lc1 -lp2 -pb2 -eos -si -so; $(size_append); } > $@
|
||||||
|
|
||||||
|
quiet_cmd_lzma_with_size = LZMA $@
|
||||||
|
cmd_lzma_with_size = { cat $(real-prereqs) | $(LZMA) -9; $(size_append); } > $@
|
11
hack-6.12/249-udp-tunnel-selection.patch
Normal file
11
hack-6.12/249-udp-tunnel-selection.patch
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
--- a/net/ipv4/Kconfig
|
||||||
|
+++ b/net/ipv4/Kconfig
|
||||||
|
@@ -315,7 +315,7 @@ config NET_IPVTI
|
||||||
|
on top.
|
||||||
|
|
||||||
|
config NET_UDP_TUNNEL
|
||||||
|
- tristate
|
||||||
|
+ tristate "IP: UDP tunneling support"
|
||||||
|
select NET_IP_TUNNEL
|
||||||
|
default n
|
||||||
|
|
27
hack-6.12/250-netfilter_depends.patch
Normal file
27
hack-6.12/250-netfilter_depends.patch
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Subject: hack: net: remove bogus netfilter dependencies
|
||||||
|
|
||||||
|
lede-commit: 589d2a377dee27d206fc3725325309cf649e4df6
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
net/netfilter/Kconfig | 2 --
|
||||||
|
1 file changed, 2 deletions(-)
|
||||||
|
|
||||||
|
--- a/net/netfilter/Kconfig
|
||||||
|
+++ b/net/netfilter/Kconfig
|
||||||
|
@@ -259,7 +259,6 @@ config NF_CONNTRACK_FTP
|
||||||
|
|
||||||
|
config NF_CONNTRACK_H323
|
||||||
|
tristate "H.323 protocol support"
|
||||||
|
- depends on IPV6 || IPV6=n
|
||||||
|
depends on NETFILTER_ADVANCED
|
||||||
|
help
|
||||||
|
H.323 is a VoIP signalling protocol from ITU-T. As one of the most
|
||||||
|
@@ -1120,7 +1119,6 @@ config NETFILTER_XT_TARGET_SECMARK
|
||||||
|
|
||||||
|
config NETFILTER_XT_TARGET_TCPMSS
|
||||||
|
tristate '"TCPMSS" target support'
|
||||||
|
- depends on IPV6 || IPV6=n
|
||||||
|
default m if NETFILTER_ADVANCED=n
|
||||||
|
help
|
||||||
|
This option adds a `TCPMSS' target, which allows you to alter the
|
199
hack-6.12/251-kconfig.patch
Normal file
199
hack-6.12/251-kconfig.patch
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
From da3c50704f14132f4adf80d48e9a4cd5d46e54c9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <john@phrozen.org>
|
||||||
|
Date: Fri, 7 Jul 2017 17:09:21 +0200
|
||||||
|
Subject: kconfig: owrt specifc dependencies
|
||||||
|
|
||||||
|
Signed-off-by: John Crispin <john@phrozen.org>
|
||||||
|
---
|
||||||
|
crypto/Kconfig | 10 +++++-----
|
||||||
|
drivers/bcma/Kconfig | 1 +
|
||||||
|
drivers/ssb/Kconfig | 3 ++-
|
||||||
|
lib/Kconfig | 8 ++++----
|
||||||
|
net/netfilter/Kconfig | 2 +-
|
||||||
|
net/wireless/Kconfig | 17 ++++++++++-------
|
||||||
|
sound/core/Kconfig | 4 ++--
|
||||||
|
7 files changed, 25 insertions(+), 20 deletions(-)
|
||||||
|
|
||||||
|
--- a/crypto/Kconfig
|
||||||
|
+++ b/crypto/Kconfig
|
||||||
|
@@ -55,7 +55,7 @@ config CRYPTO_FIPS_VERSION
|
||||||
|
By default the KERNELRELEASE value is used.
|
||||||
|
|
||||||
|
config CRYPTO_ALGAPI
|
||||||
|
- tristate
|
||||||
|
+ tristate "ALGAPI"
|
||||||
|
select CRYPTO_ALGAPI2
|
||||||
|
help
|
||||||
|
This option provides the API for cryptographic algorithms.
|
||||||
|
@@ -64,7 +64,7 @@ config CRYPTO_ALGAPI2
|
||||||
|
tristate
|
||||||
|
|
||||||
|
config CRYPTO_AEAD
|
||||||
|
- tristate
|
||||||
|
+ tristate "AEAD"
|
||||||
|
select CRYPTO_AEAD2
|
||||||
|
select CRYPTO_ALGAPI
|
||||||
|
|
||||||
|
@@ -82,7 +82,7 @@ config CRYPTO_SIG2
|
||||||
|
select CRYPTO_ALGAPI2
|
||||||
|
|
||||||
|
config CRYPTO_SKCIPHER
|
||||||
|
- tristate
|
||||||
|
+ tristate "SKCIPHER"
|
||||||
|
select CRYPTO_SKCIPHER2
|
||||||
|
select CRYPTO_ALGAPI
|
||||||
|
select CRYPTO_ECB
|
||||||
|
@@ -92,7 +92,7 @@ config CRYPTO_SKCIPHER2
|
||||||
|
select CRYPTO_ALGAPI2
|
||||||
|
|
||||||
|
config CRYPTO_HASH
|
||||||
|
- tristate
|
||||||
|
+ tristate "HASH"
|
||||||
|
select CRYPTO_HASH2
|
||||||
|
select CRYPTO_ALGAPI
|
||||||
|
|
||||||
|
@@ -101,7 +101,7 @@ config CRYPTO_HASH2
|
||||||
|
select CRYPTO_ALGAPI2
|
||||||
|
|
||||||
|
config CRYPTO_RNG
|
||||||
|
- tristate
|
||||||
|
+ tristate "RNG"
|
||||||
|
select CRYPTO_RNG2
|
||||||
|
select CRYPTO_ALGAPI
|
||||||
|
|
||||||
|
--- a/drivers/bcma/Kconfig
|
||||||
|
+++ b/drivers/bcma/Kconfig
|
||||||
|
@@ -16,6 +16,7 @@ if BCMA
|
||||||
|
# Support for Block-I/O. SELECT this from the driver that needs it.
|
||||||
|
config BCMA_BLOCKIO
|
||||||
|
bool
|
||||||
|
+ default y
|
||||||
|
|
||||||
|
config BCMA_HOST_PCI_POSSIBLE
|
||||||
|
bool
|
||||||
|
--- a/drivers/ssb/Kconfig
|
||||||
|
+++ b/drivers/ssb/Kconfig
|
||||||
|
@@ -29,6 +29,7 @@ config SSB_SPROM
|
||||||
|
config SSB_BLOCKIO
|
||||||
|
bool
|
||||||
|
depends on SSB
|
||||||
|
+ default y
|
||||||
|
|
||||||
|
config SSB_PCIHOST_POSSIBLE
|
||||||
|
bool
|
||||||
|
@@ -49,7 +50,7 @@ config SSB_PCIHOST
|
||||||
|
config SSB_B43_PCI_BRIDGE
|
||||||
|
bool
|
||||||
|
depends on SSB_PCIHOST
|
||||||
|
- default n
|
||||||
|
+ default y
|
||||||
|
|
||||||
|
config SSB_PCMCIAHOST_POSSIBLE
|
||||||
|
bool
|
||||||
|
--- a/lib/Kconfig
|
||||||
|
+++ b/lib/Kconfig
|
||||||
|
@@ -457,16 +457,16 @@ config BCH_CONST_T
|
||||||
|
# Textsearch support is select'ed if needed
|
||||||
|
#
|
||||||
|
config TEXTSEARCH
|
||||||
|
- bool
|
||||||
|
+ bool "Textsearch support"
|
||||||
|
|
||||||
|
config TEXTSEARCH_KMP
|
||||||
|
- tristate
|
||||||
|
+ tristate "Textsearch KMP"
|
||||||
|
|
||||||
|
config TEXTSEARCH_BM
|
||||||
|
- tristate
|
||||||
|
+ tristate "Textsearch BM"
|
||||||
|
|
||||||
|
config TEXTSEARCH_FSM
|
||||||
|
- tristate
|
||||||
|
+ tristate "Textsearch FSM"
|
||||||
|
|
||||||
|
config BTREE
|
||||||
|
bool
|
||||||
|
--- a/net/netfilter/Kconfig
|
||||||
|
+++ b/net/netfilter/Kconfig
|
||||||
|
@@ -22,7 +22,7 @@ config NETFILTER_SKIP_EGRESS
|
||||||
|
def_bool NETFILTER_EGRESS && (NET_CLS_ACT || IFB)
|
||||||
|
|
||||||
|
config NETFILTER_NETLINK
|
||||||
|
- tristate
|
||||||
|
+ tristate "Netfilter NFNETLINK interface"
|
||||||
|
|
||||||
|
config NETFILTER_FAMILY_BRIDGE
|
||||||
|
bool
|
||||||
|
--- a/net/wireless/Kconfig
|
||||||
|
+++ b/net/wireless/Kconfig
|
||||||
|
@@ -1,6 +1,6 @@
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
config WIRELESS_EXT
|
||||||
|
- bool
|
||||||
|
+ bool "Wireless extensions"
|
||||||
|
|
||||||
|
config WEXT_CORE
|
||||||
|
def_bool y
|
||||||
|
@@ -12,10 +12,10 @@ config WEXT_PROC
|
||||||
|
depends on WEXT_CORE
|
||||||
|
|
||||||
|
config WEXT_SPY
|
||||||
|
- bool
|
||||||
|
+ bool "WEXT_SPY"
|
||||||
|
|
||||||
|
config WEXT_PRIV
|
||||||
|
- bool
|
||||||
|
+ bool "WEXT_PRIV"
|
||||||
|
|
||||||
|
config CFG80211
|
||||||
|
tristate "cfg80211 - wireless configuration API"
|
||||||
|
@@ -214,7 +214,7 @@ config CFG80211_KUNIT_TEST
|
||||||
|
endif # CFG80211
|
||||||
|
|
||||||
|
config LIB80211
|
||||||
|
- tristate
|
||||||
|
+ tristate "LIB80211"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
This options enables a library of common routines used
|
||||||
|
@@ -223,17 +223,17 @@ config LIB80211
|
||||||
|
Drivers should select this themselves if needed.
|
||||||
|
|
||||||
|
config LIB80211_CRYPT_WEP
|
||||||
|
- tristate
|
||||||
|
+ tristate "LIB80211_CRYPT_WEP"
|
||||||
|
select CRYPTO_LIB_ARC4
|
||||||
|
|
||||||
|
config LIB80211_CRYPT_CCMP
|
||||||
|
- tristate
|
||||||
|
+ tristate "LIB80211_CRYPT_CCMP"
|
||||||
|
select CRYPTO
|
||||||
|
select CRYPTO_AES
|
||||||
|
select CRYPTO_CCM
|
||||||
|
|
||||||
|
config LIB80211_CRYPT_TKIP
|
||||||
|
- tristate
|
||||||
|
+ tristate "LIB80211_CRYPT_TKIP"
|
||||||
|
select CRYPTO_LIB_ARC4
|
||||||
|
|
||||||
|
config LIB80211_DEBUG
|
||||||
|
--- a/sound/core/Kconfig
|
||||||
|
+++ b/sound/core/Kconfig
|
||||||
|
@@ -17,7 +17,7 @@ config SND_DMAENGINE_PCM
|
||||||
|
tristate
|
||||||
|
|
||||||
|
config SND_HWDEP
|
||||||
|
- tristate
|
||||||
|
+ tristate "Sound hardware support"
|
||||||
|
|
||||||
|
config SND_SEQ_DEVICE
|
||||||
|
tristate
|
||||||
|
@@ -57,7 +57,7 @@ config SND_CORE_TEST
|
||||||
|
|
||||||
|
|
||||||
|
config SND_COMPRESS_OFFLOAD
|
||||||
|
- tristate
|
||||||
|
+ tristate "Compression offloading support"
|
||||||
|
|
||||||
|
config SND_JACK
|
||||||
|
bool
|
23
hack-6.12/252-SATA_PMP.patch
Normal file
23
hack-6.12/252-SATA_PMP.patch
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
From 8c817e33be829c7249c2cfd59ff48ad5fac6a31d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sungbo Eo <mans0n@gorani.run>
|
||||||
|
Date: Fri, 7 Jul 2017 17:09:21 +0200
|
||||||
|
Subject: [PATCH] kconfig: solidify SATA_PMP config
|
||||||
|
|
||||||
|
SATA_PMP option in kernel config file disappears for every kernel_oldconfig refresh.
|
||||||
|
To prevent this, SATA_HOST is now selected automatically when SATA_PMP is enabled.
|
||||||
|
This patch can be dropped if SATA_MV is ever re-added into the config.
|
||||||
|
---
|
||||||
|
drivers/ata/Kconfig | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/drivers/ata/Kconfig
|
||||||
|
+++ b/drivers/ata/Kconfig
|
||||||
|
@@ -96,7 +96,7 @@ config SATA_ZPODD
|
||||||
|
|
||||||
|
config SATA_PMP
|
||||||
|
bool "SATA Port Multiplier support"
|
||||||
|
- depends on SATA_HOST
|
||||||
|
+ select SATA_HOST
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
This option adds support for SATA Port Multipliers
|
22
hack-6.12/253-ksmbd-config.patch
Normal file
22
hack-6.12/253-ksmbd-config.patch
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
--- a/init/Kconfig
|
||||||
|
+++ b/init/Kconfig
|
||||||
|
@@ -2034,7 +2034,7 @@ config PADATA
|
||||||
|
bool
|
||||||
|
|
||||||
|
config ASN1
|
||||||
|
- tristate
|
||||||
|
+ tristate "ASN1"
|
||||||
|
help
|
||||||
|
Build a simple ASN.1 grammar compiler that produces a bytecode output
|
||||||
|
that can be interpreted by the ASN.1 stream decoder and used to
|
||||||
|
--- a/lib/Kconfig
|
||||||
|
+++ b/lib/Kconfig
|
||||||
|
@@ -642,7 +642,7 @@ config LIBFDT
|
||||||
|
bool
|
||||||
|
|
||||||
|
config OID_REGISTRY
|
||||||
|
- tristate
|
||||||
|
+ tristate "OID"
|
||||||
|
help
|
||||||
|
Enable fast lookup object identifier registry.
|
||||||
|
|
159
hack-6.12/259-regmap_dynamic.patch
Normal file
159
hack-6.12/259-regmap_dynamic.patch
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
From 811d9e2268a62b830cfe93cd8bc929afcb8b198b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Sat, 15 Jul 2017 21:12:38 +0200
|
||||||
|
Subject: kernel: move regmap bloat out of the kernel image if it is only being used in modules
|
||||||
|
|
||||||
|
lede-commit: 96f39119815028073583e4fca3a9c5fe9141e998
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
drivers/base/regmap/Kconfig | 15 ++++++++++-----
|
||||||
|
drivers/base/regmap/Makefile | 12 ++++++++----
|
||||||
|
drivers/base/regmap/regmap.c | 3 +++
|
||||||
|
include/linux/regmap.h | 2 +-
|
||||||
|
4 files changed, 22 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/base/regmap/Kconfig
|
||||||
|
+++ b/drivers/base/regmap/Kconfig
|
||||||
|
@@ -5,9 +5,9 @@
|
||||||
|
|
||||||
|
config REGMAP
|
||||||
|
bool
|
||||||
|
- default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_W1 || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ || REGMAP_SOUNDWIRE || REGMAP_SOUNDWIRE_MBQ || REGMAP_SCCB || REGMAP_I3C || REGMAP_SPI_AVMM || REGMAP_MDIO || REGMAP_FSI)
|
||||||
|
select IRQ_DOMAIN if REGMAP_IRQ
|
||||||
|
select MDIO_BUS if REGMAP_MDIO
|
||||||
|
+ tristate
|
||||||
|
help
|
||||||
|
Enable support for the Register Map (regmap) access API.
|
||||||
|
|
||||||
|
@@ -19,8 +19,9 @@ config REGMAP
|
||||||
|
|
||||||
|
config REGMAP_KUNIT
|
||||||
|
tristate "KUnit tests for regmap"
|
||||||
|
- depends on KUNIT && REGMAP
|
||||||
|
+ depends on KUNIT
|
||||||
|
default KUNIT_ALL_TESTS
|
||||||
|
+ select REGMAP
|
||||||
|
select REGMAP_RAM
|
||||||
|
|
||||||
|
config REGMAP_BUILD
|
||||||
|
@@ -34,60 +35,76 @@ config REGMAP_BUILD
|
||||||
|
normally enabled.
|
||||||
|
|
||||||
|
config REGMAP_AC97
|
||||||
|
+ select REGMAP
|
||||||
|
tristate
|
||||||
|
|
||||||
|
config REGMAP_I2C
|
||||||
|
+ select REGMAP
|
||||||
|
tristate
|
||||||
|
depends on I2C
|
||||||
|
|
||||||
|
config REGMAP_SLIMBUS
|
||||||
|
+ select REGMAP
|
||||||
|
tristate
|
||||||
|
depends on SLIMBUS
|
||||||
|
|
||||||
|
config REGMAP_SPI
|
||||||
|
+ select REGMAP
|
||||||
|
tristate
|
||||||
|
depends on SPI
|
||||||
|
|
||||||
|
config REGMAP_SPMI
|
||||||
|
+ select REGMAP
|
||||||
|
tristate
|
||||||
|
depends on SPMI
|
||||||
|
|
||||||
|
config REGMAP_W1
|
||||||
|
+ select REGMAP
|
||||||
|
tristate
|
||||||
|
depends on W1
|
||||||
|
|
||||||
|
config REGMAP_MDIO
|
||||||
|
+ select REGMAP
|
||||||
|
tristate
|
||||||
|
|
||||||
|
config REGMAP_MMIO
|
||||||
|
+ select REGMAP
|
||||||
|
tristate
|
||||||
|
|
||||||
|
config REGMAP_IRQ
|
||||||
|
+ select REGMAP
|
||||||
|
bool
|
||||||
|
|
||||||
|
config REGMAP_RAM
|
||||||
|
+ select REGMAP
|
||||||
|
tristate
|
||||||
|
|
||||||
|
config REGMAP_SOUNDWIRE
|
||||||
|
+ select REGMAP
|
||||||
|
tristate
|
||||||
|
depends on SOUNDWIRE
|
||||||
|
|
||||||
|
config REGMAP_SOUNDWIRE_MBQ
|
||||||
|
+ select REGMAP
|
||||||
|
tristate
|
||||||
|
depends on SOUNDWIRE
|
||||||
|
|
||||||
|
config REGMAP_SCCB
|
||||||
|
+ select REGMAP
|
||||||
|
tristate
|
||||||
|
depends on I2C
|
||||||
|
|
||||||
|
config REGMAP_I3C
|
||||||
|
+ select REGMAP
|
||||||
|
tristate
|
||||||
|
depends on I3C
|
||||||
|
|
||||||
|
config REGMAP_SPI_AVMM
|
||||||
|
+ select REGMAP
|
||||||
|
tristate
|
||||||
|
depends on SPI
|
||||||
|
|
||||||
|
config REGMAP_FSI
|
||||||
|
+ select REGMAP
|
||||||
|
tristate
|
||||||
|
depends on FSI
|
||||||
|
--- a/drivers/base/regmap/Makefile
|
||||||
|
+++ b/drivers/base/regmap/Makefile
|
||||||
|
@@ -2,9 +2,11 @@
|
||||||
|
# For include/trace/define_trace.h to include trace.h
|
||||||
|
CFLAGS_regmap.o := -I$(src)
|
||||||
|
|
||||||
|
-obj-$(CONFIG_REGMAP) += regmap.o regcache.o
|
||||||
|
-obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-flat.o regcache-maple.o
|
||||||
|
-obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o
|
||||||
|
+regmap-core-objs = regmap.o regcache.o regcache-rbtree.o regcache-flat.o regcache-maple.o
|
||||||
|
+ifdef CONFIG_DEBUG_FS
|
||||||
|
+regmap-core-objs += regmap-debugfs.o
|
||||||
|
+endif
|
||||||
|
+obj-$(CONFIG_REGMAP) += regmap-core.o
|
||||||
|
obj-$(CONFIG_REGMAP_KUNIT) += regmap-kunit.o
|
||||||
|
obj-$(CONFIG_REGMAP_AC97) += regmap-ac97.o
|
||||||
|
obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o
|
||||||
|
--- a/drivers/base/regmap/regmap.c
|
||||||
|
+++ b/drivers/base/regmap/regmap.c
|
||||||
|
@@ -9,6 +9,7 @@
|
||||||
|
#include <linux/device.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/export.h>
|
||||||
|
+#include <linux/module.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/property.h>
|
||||||
|
@@ -3506,3 +3507,5 @@ static int __init regmap_initcall(void)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
postcore_initcall(regmap_initcall);
|
||||||
|
+
|
||||||
|
+MODULE_LICENSE("GPL");
|
||||||
|
--- a/include/linux/regmap.h
|
||||||
|
+++ b/include/linux/regmap.h
|
||||||
|
@@ -197,7 +197,7 @@ struct reg_sequence {
|
||||||
|
__ret ?: __tmp; \
|
||||||
|
})
|
||||||
|
|
||||||
|
-#ifdef CONFIG_REGMAP
|
||||||
|
+#if IS_REACHABLE(CONFIG_REGMAP)
|
||||||
|
|
||||||
|
enum regmap_endian {
|
||||||
|
/* Unspecified -> 0 -> Backwards compatible default */
|
15
hack-6.12/261-lib-arc4-unhide.patch
Normal file
15
hack-6.12/261-lib-arc4-unhide.patch
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
This makes it possible to select CONFIG_CRYPTO_LIB_ARC4 directly. We
|
||||||
|
need this to be able to compile this into the kernel and make use of it
|
||||||
|
from backports.
|
||||||
|
|
||||||
|
--- a/lib/crypto/Kconfig
|
||||||
|
+++ b/lib/crypto/Kconfig
|
||||||
|
@@ -20,7 +20,7 @@ config CRYPTO_LIB_AESGCM
|
||||||
|
select CRYPTO_LIB_UTILS
|
||||||
|
|
||||||
|
config CRYPTO_LIB_ARC4
|
||||||
|
- tristate
|
||||||
|
+ tristate "ARC4 cipher library"
|
||||||
|
|
||||||
|
config CRYPTO_LIB_GF128MUL
|
||||||
|
tristate
|
84
hack-6.12/280-rfkill-stubs.patch
Normal file
84
hack-6.12/280-rfkill-stubs.patch
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
From 236c1acdfef5958010ac9814a9872e0a46fd78ee Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <john@phrozen.org>
|
||||||
|
Date: Fri, 7 Jul 2017 17:13:44 +0200
|
||||||
|
Subject: rfkill: add fake rfkill support
|
||||||
|
|
||||||
|
allow building of modules depending on RFKILL even if RFKILL is not enabled.
|
||||||
|
|
||||||
|
Signed-off-by: John Crispin <john@phrozen.org>
|
||||||
|
---
|
||||||
|
include/linux/rfkill.h | 2 +-
|
||||||
|
net/Makefile | 2 +-
|
||||||
|
net/rfkill/Kconfig | 14 +++++++++-----
|
||||||
|
net/rfkill/Makefile | 2 +-
|
||||||
|
4 files changed, 12 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
--- a/include/linux/rfkill.h
|
||||||
|
+++ b/include/linux/rfkill.h
|
||||||
|
@@ -64,7 +64,7 @@ struct rfkill_ops {
|
||||||
|
int (*set_block)(void *data, bool blocked);
|
||||||
|
};
|
||||||
|
|
||||||
|
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
|
||||||
|
+#if defined(CONFIG_RFKILL_FULL) || defined(CONFIG_RFKILL_FULL_MODULE)
|
||||||
|
/**
|
||||||
|
* rfkill_alloc - Allocate rfkill structure
|
||||||
|
* @name: name of the struct -- the string is not copied internally
|
||||||
|
--- a/net/Makefile
|
||||||
|
+++ b/net/Makefile
|
||||||
|
@@ -51,7 +51,7 @@ obj-$(CONFIG_TIPC) += tipc/
|
||||||
|
obj-$(CONFIG_NETLABEL) += netlabel/
|
||||||
|
obj-$(CONFIG_IUCV) += iucv/
|
||||||
|
obj-$(CONFIG_SMC) += smc/
|
||||||
|
-obj-$(CONFIG_RFKILL) += rfkill/
|
||||||
|
+obj-$(CONFIG_RFKILL_FULL) += rfkill/
|
||||||
|
obj-$(CONFIG_NET_9P) += 9p/
|
||||||
|
obj-$(CONFIG_CAIF) += caif/
|
||||||
|
obj-$(CONFIG_DCB) += dcb/
|
||||||
|
--- a/net/rfkill/Kconfig
|
||||||
|
+++ b/net/rfkill/Kconfig
|
||||||
|
@@ -2,7 +2,11 @@
|
||||||
|
#
|
||||||
|
# RF switch subsystem configuration
|
||||||
|
#
|
||||||
|
-menuconfig RFKILL
|
||||||
|
+config RFKILL
|
||||||
|
+ bool
|
||||||
|
+ default y
|
||||||
|
+
|
||||||
|
+menuconfig RFKILL_FULL
|
||||||
|
tristate "RF switch subsystem support"
|
||||||
|
help
|
||||||
|
Say Y here if you want to have control over RF switches
|
||||||
|
@@ -14,19 +18,19 @@ menuconfig RFKILL
|
||||||
|
# LED trigger support
|
||||||
|
config RFKILL_LEDS
|
||||||
|
bool
|
||||||
|
- depends on RFKILL
|
||||||
|
+ depends on RFKILL_FULL
|
||||||
|
depends on LEDS_TRIGGERS = y || RFKILL = LEDS_TRIGGERS
|
||||||
|
default y
|
||||||
|
|
||||||
|
config RFKILL_INPUT
|
||||||
|
bool "RF switch input support" if EXPERT
|
||||||
|
- depends on RFKILL
|
||||||
|
+ depends on RFKILL_FULL
|
||||||
|
depends on INPUT = y || RFKILL = INPUT
|
||||||
|
default y if !EXPERT
|
||||||
|
|
||||||
|
config RFKILL_GPIO
|
||||||
|
tristate "GPIO RFKILL driver"
|
||||||
|
- depends on RFKILL
|
||||||
|
+ depends on RFKILL_FULL
|
||||||
|
depends on GPIOLIB || COMPILE_TEST
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
--- a/net/rfkill/Makefile
|
||||||
|
+++ b/net/rfkill/Makefile
|
||||||
|
@@ -5,5 +5,5 @@
|
||||||
|
|
||||||
|
rfkill-y += core.o
|
||||||
|
rfkill-$(CONFIG_RFKILL_INPUT) += input.o
|
||||||
|
-obj-$(CONFIG_RFKILL) += rfkill.o
|
||||||
|
+obj-$(CONFIG_RFKILL_FULL) += rfkill.o
|
||||||
|
obj-$(CONFIG_RFKILL_GPIO) += rfkill-gpio.o
|
@ -0,0 +1,64 @@
|
|||||||
|
From: Ben Menchaca <ben.menchaca@qca.qualcomm.com>
|
||||||
|
Date: Fri, 7 Jun 2013 18:35:22 -0500
|
||||||
|
Subject: MIPS: r4k_cache: use more efficient cache blast
|
||||||
|
|
||||||
|
Optimize the compiler output for larger cache blast cases that are
|
||||||
|
common for DMA-based networking.
|
||||||
|
|
||||||
|
Signed-off-by: Ben Menchaca <ben.menchaca@qca.qualcomm.com>
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
--- a/arch/mips/include/asm/r4kcache.h
|
||||||
|
+++ b/arch/mips/include/asm/r4kcache.h
|
||||||
|
@@ -290,14 +290,46 @@ static inline void prot##extra##blast_##
|
||||||
|
unsigned long end) \
|
||||||
|
{ \
|
||||||
|
unsigned long lsize = cpu_##desc##_line_size(); \
|
||||||
|
+ unsigned long lsize_2 = lsize * 2; \
|
||||||
|
+ unsigned long lsize_3 = lsize * 3; \
|
||||||
|
+ unsigned long lsize_4 = lsize * 4; \
|
||||||
|
+ unsigned long lsize_5 = lsize * 5; \
|
||||||
|
+ unsigned long lsize_6 = lsize * 6; \
|
||||||
|
+ unsigned long lsize_7 = lsize * 7; \
|
||||||
|
+ unsigned long lsize_8 = lsize * 8; \
|
||||||
|
unsigned long addr = start & ~(lsize - 1); \
|
||||||
|
- unsigned long aend = (end - 1) & ~(lsize - 1); \
|
||||||
|
+ unsigned long aend = (end + lsize - 1) & ~(lsize - 1); \
|
||||||
|
+ int lines = (aend - addr) / lsize; \
|
||||||
|
\
|
||||||
|
- while (1) { \
|
||||||
|
+ while (lines >= 8) { \
|
||||||
|
+ prot##cache_op(hitop, addr); \
|
||||||
|
+ prot##cache_op(hitop, addr + lsize); \
|
||||||
|
+ prot##cache_op(hitop, addr + lsize_2); \
|
||||||
|
+ prot##cache_op(hitop, addr + lsize_3); \
|
||||||
|
+ prot##cache_op(hitop, addr + lsize_4); \
|
||||||
|
+ prot##cache_op(hitop, addr + lsize_5); \
|
||||||
|
+ prot##cache_op(hitop, addr + lsize_6); \
|
||||||
|
+ prot##cache_op(hitop, addr + lsize_7); \
|
||||||
|
+ addr += lsize_8; \
|
||||||
|
+ lines -= 8; \
|
||||||
|
+ } \
|
||||||
|
+ \
|
||||||
|
+ if (lines & 0x4) { \
|
||||||
|
+ prot##cache_op(hitop, addr); \
|
||||||
|
+ prot##cache_op(hitop, addr + lsize); \
|
||||||
|
+ prot##cache_op(hitop, addr + lsize_2); \
|
||||||
|
+ prot##cache_op(hitop, addr + lsize_3); \
|
||||||
|
+ addr += lsize_4; \
|
||||||
|
+ } \
|
||||||
|
+ \
|
||||||
|
+ if (lines & 0x2) { \
|
||||||
|
+ prot##cache_op(hitop, addr); \
|
||||||
|
+ prot##cache_op(hitop, addr + lsize); \
|
||||||
|
+ addr += lsize_2; \
|
||||||
|
+ } \
|
||||||
|
+ \
|
||||||
|
+ if (lines & 0x1) { \
|
||||||
|
prot##cache_op(hitop, addr); \
|
||||||
|
- if (addr == aend) \
|
||||||
|
- break; \
|
||||||
|
- addr += lsize; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
38
hack-6.12/301-mips_image_cmdline_hack.patch
Normal file
38
hack-6.12/301-mips_image_cmdline_hack.patch
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
From: John Crispin <john@phrozen.org>
|
||||||
|
Subject: hack: kernel: add generic image_cmdline hack to MIPS targets
|
||||||
|
|
||||||
|
lede-commit: d59f5b3a987a48508257a0ddbaeadc7909f9f976
|
||||||
|
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
|
||||||
|
---
|
||||||
|
arch/mips/Kconfig | 4 ++++
|
||||||
|
arch/mips/kernel/head.S | 6 ++++++
|
||||||
|
2 files changed, 10 insertions(+)
|
||||||
|
|
||||||
|
--- a/arch/mips/Kconfig
|
||||||
|
+++ b/arch/mips/Kconfig
|
||||||
|
@@ -1133,6 +1133,10 @@ config MIPS_MSC
|
||||||
|
config SYNC_R4K
|
||||||
|
bool
|
||||||
|
|
||||||
|
+config IMAGE_CMDLINE_HACK
|
||||||
|
+ bool "OpenWrt specific image command line hack"
|
||||||
|
+ default n
|
||||||
|
+
|
||||||
|
config NO_IOPORT_MAP
|
||||||
|
def_bool n
|
||||||
|
|
||||||
|
--- a/arch/mips/kernel/head.S
|
||||||
|
+++ b/arch/mips/kernel/head.S
|
||||||
|
@@ -79,6 +79,12 @@ FEXPORT(__kernel_entry)
|
||||||
|
j kernel_entry
|
||||||
|
#endif /* CONFIG_BOOT_RAW */
|
||||||
|
|
||||||
|
+#ifdef CONFIG_IMAGE_CMDLINE_HACK
|
||||||
|
+ .ascii "CMDLINE:"
|
||||||
|
+EXPORT(__image_cmdline)
|
||||||
|
+ .fill 0x400
|
||||||
|
+#endif /* CONFIG_IMAGE_CMDLINE_HACK */
|
||||||
|
+
|
||||||
|
__REF
|
||||||
|
|
||||||
|
NESTED(kernel_entry, 16, sp) # kernel entry point
|
196
hack-6.12/410-block-fit-partition-parser.patch
Normal file
196
hack-6.12/410-block-fit-partition-parser.patch
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
--- a/block/blk.h
|
||||||
|
+++ b/block/blk.h
|
||||||
|
@@ -558,6 +558,8 @@ void blk_free_ext_minor(unsigned int min
|
||||||
|
#define ADDPART_FLAG_NONE 0
|
||||||
|
#define ADDPART_FLAG_RAID 1
|
||||||
|
#define ADDPART_FLAG_WHOLEDISK 2
|
||||||
|
+#define ADDPART_FLAG_READONLY 4
|
||||||
|
+#define ADDPART_FLAG_ROOTDEV 8
|
||||||
|
int bdev_add_partition(struct gendisk *disk, int partno, sector_t start,
|
||||||
|
sector_t length);
|
||||||
|
int bdev_del_partition(struct gendisk *disk, int partno);
|
||||||
|
--- a/block/partitions/Kconfig
|
||||||
|
+++ b/block/partitions/Kconfig
|
||||||
|
@@ -103,6 +103,13 @@ config ATARI_PARTITION
|
||||||
|
Say Y here if you would like to use hard disks under Linux which
|
||||||
|
were partitioned under the Atari OS.
|
||||||
|
|
||||||
|
+config FIT_PARTITION
|
||||||
|
+ bool "Flattened-Image-Tree (FIT) partition support" if PARTITION_ADVANCED
|
||||||
|
+ default n
|
||||||
|
+ help
|
||||||
|
+ Say Y here if your system needs to mount the filesystem part of
|
||||||
|
+ a Flattened-Image-Tree (FIT) image commonly used with Das U-Boot.
|
||||||
|
+
|
||||||
|
config IBM_PARTITION
|
||||||
|
bool "IBM disk label and partition support"
|
||||||
|
depends on PARTITION_ADVANCED && S390
|
||||||
|
--- a/block/partitions/Makefile
|
||||||
|
+++ b/block/partitions/Makefile
|
||||||
|
@@ -8,6 +8,7 @@ obj-$(CONFIG_ACORN_PARTITION) += acorn.o
|
||||||
|
obj-$(CONFIG_AMIGA_PARTITION) += amiga.o
|
||||||
|
obj-$(CONFIG_ATARI_PARTITION) += atari.o
|
||||||
|
obj-$(CONFIG_AIX_PARTITION) += aix.o
|
||||||
|
+obj-$(CONFIG_FIT_PARTITION) += fit.o
|
||||||
|
obj-$(CONFIG_CMDLINE_PARTITION) += cmdline.o
|
||||||
|
obj-$(CONFIG_MAC_PARTITION) += mac.o
|
||||||
|
obj-$(CONFIG_LDM_PARTITION) += ldm.o
|
||||||
|
--- a/block/partitions/check.h
|
||||||
|
+++ b/block/partitions/check.h
|
||||||
|
@@ -57,6 +57,7 @@ int amiga_partition(struct parsed_partit
|
||||||
|
int atari_partition(struct parsed_partitions *state);
|
||||||
|
int cmdline_partition(struct parsed_partitions *state);
|
||||||
|
int efi_partition(struct parsed_partitions *state);
|
||||||
|
+int fit_partition(struct parsed_partitions *state);
|
||||||
|
int ibm_partition(struct parsed_partitions *);
|
||||||
|
int karma_partition(struct parsed_partitions *state);
|
||||||
|
int ldm_partition(struct parsed_partitions *state);
|
||||||
|
@@ -67,3 +68,5 @@ int sgi_partition(struct parsed_partitio
|
||||||
|
int sun_partition(struct parsed_partitions *state);
|
||||||
|
int sysv68_partition(struct parsed_partitions *state);
|
||||||
|
int ultrix_partition(struct parsed_partitions *state);
|
||||||
|
+
|
||||||
|
+int parse_fit_partitions(struct parsed_partitions *state, u64 start_sector, u64 nr_sectors, int *slot, int add_remain);
|
||||||
|
--- a/block/partitions/core.c
|
||||||
|
+++ b/block/partitions/core.c
|
||||||
|
@@ -10,6 +10,10 @@
|
||||||
|
#include <linux/ctype.h>
|
||||||
|
#include <linux/vmalloc.h>
|
||||||
|
#include <linux/raid/detect.h>
|
||||||
|
+#ifdef CONFIG_FIT_PARTITION
|
||||||
|
+#include <linux/root_dev.h>
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#include "check.h"
|
||||||
|
|
||||||
|
static int (*const check_part[])(struct parsed_partitions *) = {
|
||||||
|
@@ -46,6 +50,9 @@ static int (*const check_part[])(struct
|
||||||
|
#ifdef CONFIG_EFI_PARTITION
|
||||||
|
efi_partition, /* this must come before msdos */
|
||||||
|
#endif
|
||||||
|
+#ifdef CONFIG_FIT_PARTITION
|
||||||
|
+ fit_partition,
|
||||||
|
+#endif
|
||||||
|
#ifdef CONFIG_SGI_PARTITION
|
||||||
|
sgi_partition,
|
||||||
|
#endif
|
||||||
|
@@ -373,6 +380,11 @@ static struct block_device *add_partitio
|
||||||
|
goto out_del;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#ifdef CONFIG_FIT_PARTITION
|
||||||
|
+ if (flags & ADDPART_FLAG_READONLY)
|
||||||
|
+ bdev->bd_read_only = true;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/* everything is up and running, commence */
|
||||||
|
err = xa_insert(&disk->part_tbl, partno, bdev, GFP_KERNEL);
|
||||||
|
if (err)
|
||||||
|
@@ -567,6 +579,11 @@ static bool blk_add_partition(struct gen
|
||||||
|
(state->parts[p].flags & ADDPART_FLAG_RAID))
|
||||||
|
md_autodetect_dev(part->bd_dev);
|
||||||
|
|
||||||
|
+#ifdef CONFIG_FIT_PARTITION
|
||||||
|
+ if ((state->parts[p].flags & ADDPART_FLAG_ROOTDEV) && ROOT_DEV == 0)
|
||||||
|
+ ROOT_DEV = part->bd_dev;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
--- a/drivers/mtd/ubi/block.c
|
||||||
|
+++ b/drivers/mtd/ubi/block.c
|
||||||
|
@@ -416,6 +416,9 @@ int ubiblock_create(struct ubi_volume_in
|
||||||
|
}
|
||||||
|
gd->flags |= GENHD_FL_NO_PART;
|
||||||
|
gd->private_data = dev;
|
||||||
|
+#ifdef CONFIG_FIT_PARTITION
|
||||||
|
+ gd->flags |= GENHD_FL_EXT_DEVT;
|
||||||
|
+#endif
|
||||||
|
sprintf(gd->disk_name, "ubiblock%d_%d", dev->ubi_num, dev->vol_id);
|
||||||
|
set_capacity(gd, disk_capacity);
|
||||||
|
dev->gd = gd;
|
||||||
|
--- a/drivers/mtd/mtd_blkdevs.c
|
||||||
|
+++ b/drivers/mtd/mtd_blkdevs.c
|
||||||
|
@@ -353,6 +353,9 @@ int add_mtd_blktrans_dev(struct mtd_blkt
|
||||||
|
gd->first_minor = (new->devnum) << tr->part_bits;
|
||||||
|
gd->minors = 1 << tr->part_bits;
|
||||||
|
gd->fops = &mtd_block_ops;
|
||||||
|
+#ifdef CONFIG_FIT_PARTITION
|
||||||
|
+ gd->flags |= GENHD_FL_EXT_DEVT;
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
if (tr->part_bits) {
|
||||||
|
if (new->devnum < 26)
|
||||||
|
--- a/block/partitions/efi.c
|
||||||
|
+++ b/block/partitions/efi.c
|
||||||
|
@@ -716,6 +716,9 @@ int efi_partition(struct parsed_partitio
|
||||||
|
gpt_entry *ptes = NULL;
|
||||||
|
u32 i;
|
||||||
|
unsigned ssz = queue_logical_block_size(state->disk->queue) / 512;
|
||||||
|
+#ifdef CONFIG_FIT_PARTITION
|
||||||
|
+ u32 extra_slot = 64;
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) {
|
||||||
|
kfree(gpt);
|
||||||
|
@@ -749,6 +752,11 @@ int efi_partition(struct parsed_partitio
|
||||||
|
ARRAY_SIZE(ptes[i].partition_name));
|
||||||
|
utf16_le_to_7bit(ptes[i].partition_name, label_max, info->volname);
|
||||||
|
state->parts[i + 1].has_info = true;
|
||||||
|
+#ifdef CONFIG_FIT_PARTITION
|
||||||
|
+ /* If this is a U-Boot FIT volume it may have subpartitions */
|
||||||
|
+ if (!efi_guidcmp(ptes[i].partition_type_guid, PARTITION_LINUX_FIT_GUID))
|
||||||
|
+ (void) parse_fit_partitions(state, start * ssz, size * ssz, &extra_slot, 1);
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
kfree(ptes);
|
||||||
|
kfree(gpt);
|
||||||
|
--- a/block/partitions/efi.h
|
||||||
|
+++ b/block/partitions/efi.h
|
||||||
|
@@ -51,6 +51,9 @@
|
||||||
|
#define PARTITION_LINUX_LVM_GUID \
|
||||||
|
EFI_GUID( 0xe6d6d379, 0xf507, 0x44c2, \
|
||||||
|
0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28)
|
||||||
|
+#define PARTITION_LINUX_FIT_GUID \
|
||||||
|
+ EFI_GUID( 0xcae9be83, 0xb15f, 0x49cc, \
|
||||||
|
+ 0x86, 0x3f, 0x08, 0x1b, 0x74, 0x4a, 0x2d, 0x93)
|
||||||
|
|
||||||
|
typedef struct _gpt_header {
|
||||||
|
__le64 signature;
|
||||||
|
--- a/block/partitions/msdos.c
|
||||||
|
+++ b/block/partitions/msdos.c
|
||||||
|
@@ -564,6 +564,15 @@ static void parse_minix(struct parsed_pa
|
||||||
|
#endif /* CONFIG_MINIX_SUBPARTITION */
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void parse_fit_mbr(struct parsed_partitions *state,
|
||||||
|
+ sector_t offset, sector_t size, int origin)
|
||||||
|
+{
|
||||||
|
+#ifdef CONFIG_FIT_PARTITION
|
||||||
|
+ u32 extra_slot = 64;
|
||||||
|
+ (void) parse_fit_partitions(state, offset, size, &extra_slot, 1);
|
||||||
|
+#endif /* CONFIG_FIT_PARTITION */
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static struct {
|
||||||
|
unsigned char id;
|
||||||
|
void (*parse)(struct parsed_partitions *, sector_t, sector_t, int);
|
||||||
|
@@ -575,6 +584,7 @@ static struct {
|
||||||
|
{UNIXWARE_PARTITION, parse_unixware},
|
||||||
|
{SOLARIS_X86_PARTITION, parse_solaris_x86},
|
||||||
|
{NEW_SOLARIS_X86_PARTITION, parse_solaris_x86},
|
||||||
|
+ {FIT_PARTITION, parse_fit_mbr},
|
||||||
|
{0, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
--- a/include/linux/msdos_partition.h
|
||||||
|
+++ b/include/linux/msdos_partition.h
|
||||||
|
@@ -31,6 +31,7 @@ enum msdos_sys_ind {
|
||||||
|
LINUX_LVM_PARTITION = 0x8e,
|
||||||
|
LINUX_RAID_PARTITION = 0xfd, /* autodetect RAID partition */
|
||||||
|
|
||||||
|
+ FIT_PARTITION = 0x2e, /* U-Boot uImage.FIT */
|
||||||
|
SOLARIS_X86_PARTITION = 0x82, /* also Linux swap partitions */
|
||||||
|
NEW_SOLARIS_X86_PARTITION = 0xbf,
|
||||||
|
|
39
hack-6.12/420-mtd-set-rootfs-to-be-root-dev.patch
Normal file
39
hack-6.12/420-mtd-set-rootfs-to-be-root-dev.patch
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
From: Gabor Juhos <juhosg@openwrt.org>
|
||||||
|
Subject: kernel/3.1[02]: move MTD root device setup code to mtdcore
|
||||||
|
|
||||||
|
The current code only allows to automatically set
|
||||||
|
root device on MTD partitions. Move the code to MTD
|
||||||
|
core to allow to use it with all MTD devices.
|
||||||
|
|
||||||
|
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
|
||||||
|
---
|
||||||
|
drivers/mtd/mtdcore.c | 10 ++++++++++
|
||||||
|
1 file changed, 10 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/mtd/mtdcore.c
|
||||||
|
+++ b/drivers/mtd/mtdcore.c
|
||||||
|
@@ -28,6 +28,7 @@
|
||||||
|
#include <linux/reboot.h>
|
||||||
|
#include <linux/leds.h>
|
||||||
|
#include <linux/debugfs.h>
|
||||||
|
+#include <linux/root_dev.h>
|
||||||
|
#include <linux/nvmem-provider.h>
|
||||||
|
#include <linux/root_dev.h>
|
||||||
|
#include <linux/error-injection.h>
|
||||||
|
@@ -784,6 +785,16 @@ int add_mtd_device(struct mtd_info *mtd)
|
||||||
|
of this try_ nonsense, and no bitching about it
|
||||||
|
either. :) */
|
||||||
|
__module_get(THIS_MODULE);
|
||||||
|
+
|
||||||
|
+ if (!strcmp(mtd->name, "rootfs") &&
|
||||||
|
+ IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) &&
|
||||||
|
+ ROOT_DEV == 0) {
|
||||||
|
+ unsigned int index = mtd->index;
|
||||||
|
+ pr_notice("mtd: device %d (%s) set to be root filesystem\n",
|
||||||
|
+ mtd->index, mtd->name);
|
||||||
|
+ ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, index);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
fail_nvmem_add:
|
@ -0,0 +1,120 @@
|
|||||||
|
From 6fa9e3678eb002246df1280322b6a024853950a5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Date: Mon, 11 Oct 2021 00:53:14 +0200
|
||||||
|
Subject: [PATCH] drivers: mtd: parsers: add nvmem support to cmdlinepart
|
||||||
|
|
||||||
|
Assuming cmdlinepart is only one level deep partition scheme and that
|
||||||
|
static partition are also defined in DTS, we can assign an of_node for
|
||||||
|
partition declared from bootargs. cmdlinepart have priority than
|
||||||
|
fiexed-partition parser so in this specific case the parser doesn't
|
||||||
|
assign an of_node. Fix this by searching a defined of_node using a
|
||||||
|
similar fixed_partition parser and if a partition is found with the same
|
||||||
|
label, check that it has the same offset and size and return the DT
|
||||||
|
of_node to correctly use NVMEM cells.
|
||||||
|
|
||||||
|
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
---
|
||||||
|
drivers/mtd/parsers/cmdlinepart.c | 71 +++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 71 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/mtd/parsers/cmdlinepart.c
|
||||||
|
+++ b/drivers/mtd/parsers/cmdlinepart.c
|
||||||
|
@@ -43,6 +43,7 @@
|
||||||
|
#include <linux/mtd/partitions.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
+#include <linux/of.h>
|
||||||
|
|
||||||
|
/* special size referring to all the remaining space in a partition */
|
||||||
|
#define SIZE_REMAINING ULLONG_MAX
|
||||||
|
@@ -315,6 +316,68 @@ static int mtdpart_setup_real(char *s)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int search_fixed_partition(struct mtd_info *master,
|
||||||
|
+ struct mtd_partition *target_part,
|
||||||
|
+ struct mtd_partition *fixed_part)
|
||||||
|
+{
|
||||||
|
+ struct device_node *mtd_node;
|
||||||
|
+ struct device_node *ofpart_node;
|
||||||
|
+ struct device_node *pp;
|
||||||
|
+ struct mtd_partition part;
|
||||||
|
+ const char *partname;
|
||||||
|
+
|
||||||
|
+ mtd_node = mtd_get_of_node(master);
|
||||||
|
+ if (!mtd_node)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ ofpart_node = of_get_child_by_name(mtd_node, "partitions");
|
||||||
|
+
|
||||||
|
+ for_each_child_of_node(ofpart_node, pp) {
|
||||||
|
+ const __be32 *reg;
|
||||||
|
+ int len;
|
||||||
|
+ int a_cells, s_cells;
|
||||||
|
+
|
||||||
|
+ reg = of_get_property(pp, "reg", &len);
|
||||||
|
+ if (!reg) {
|
||||||
|
+ pr_debug("%s: ofpart partition %pOF (%pOF) missing reg property.\n",
|
||||||
|
+ master->name, pp,
|
||||||
|
+ mtd_node);
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ a_cells = of_n_addr_cells(pp);
|
||||||
|
+ s_cells = of_n_size_cells(pp);
|
||||||
|
+ if (len / 4 != a_cells + s_cells) {
|
||||||
|
+ pr_debug("%s: ofpart partition %pOF (%pOF) error parsing reg property.\n",
|
||||||
|
+ master->name, pp,
|
||||||
|
+ mtd_node);
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ part.offset = of_read_number(reg, a_cells);
|
||||||
|
+ part.size = of_read_number(reg + a_cells, s_cells);
|
||||||
|
+ part.of_node = pp;
|
||||||
|
+
|
||||||
|
+ partname = of_get_property(pp, "label", &len);
|
||||||
|
+ if (!partname)
|
||||||
|
+ partname = of_get_property(pp, "name", &len);
|
||||||
|
+ part.name = partname;
|
||||||
|
+
|
||||||
|
+ if (!strncmp(target_part->name, part.name, len)) {
|
||||||
|
+ if (part.offset != target_part->offset)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ if (part.size != target_part->size)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ memcpy(fixed_part, &part, sizeof(struct mtd_partition));
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return -EINVAL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Main function to be called from the MTD mapping driver/device to
|
||||||
|
* obtain the partitioning information. At this point the command line
|
||||||
|
@@ -330,6 +393,7 @@ static int parse_cmdline_partitions(stru
|
||||||
|
int i, err;
|
||||||
|
struct cmdline_mtd_partition *part;
|
||||||
|
const char *mtd_id = master->name;
|
||||||
|
+ struct mtd_partition fixed_part;
|
||||||
|
|
||||||
|
/* parse command line */
|
||||||
|
if (!cmdline_parsed) {
|
||||||
|
@@ -374,6 +438,13 @@ static int parse_cmdline_partitions(stru
|
||||||
|
sizeof(*part->parts) * (part->num_parts - i));
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ err = search_fixed_partition(master, &part->parts[i], &fixed_part);
|
||||||
|
+ if (!err) {
|
||||||
|
+ part->parts[i].of_node = fixed_part.of_node;
|
||||||
|
+ pr_info("Found partition defined in DT for %s. Assigning OF node to support nvmem.",
|
||||||
|
+ part->parts[i].name);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
*pparts = kmemdup(part->parts, sizeof(*part->parts) * part->num_parts,
|
23
hack-6.12/430-mtk-bmt-support.patch
Normal file
23
hack-6.12/430-mtk-bmt-support.patch
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
--- a/drivers/mtd/nand/Kconfig
|
||||||
|
+++ b/drivers/mtd/nand/Kconfig
|
||||||
|
@@ -61,6 +61,10 @@ config MTD_NAND_ECC_MEDIATEK
|
||||||
|
help
|
||||||
|
This enables support for the hardware ECC engine from Mediatek.
|
||||||
|
|
||||||
|
+config MTD_NAND_MTK_BMT
|
||||||
|
+ bool "Support MediaTek NAND Bad-block Management Table"
|
||||||
|
+ default n
|
||||||
|
+
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
--- a/drivers/mtd/nand/Makefile
|
||||||
|
+++ b/drivers/mtd/nand/Makefile
|
||||||
|
@@ -3,6 +3,7 @@
|
||||||
|
nandcore-objs := core.o bbt.o
|
||||||
|
obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o
|
||||||
|
obj-$(CONFIG_MTD_NAND_ECC_MEDIATEK) += ecc-mtk.o
|
||||||
|
+obj-$(CONFIG_MTD_NAND_MTK_BMT) += mtk_bmt.o mtk_bmt_v2.o mtk_bmt_bbt.o mtk_bmt_nmbm.o
|
||||||
|
|
||||||
|
obj-y += onenand/
|
||||||
|
obj-y += raw/
|
1040
hack-6.12/531-debloat_lzma.patch
Normal file
1040
hack-6.12/531-debloat_lzma.patch
Normal file
File diff suppressed because it is too large
Load Diff
230
hack-6.12/645-netfilter-connmark-introduce-set-dscpmark.patch
Normal file
230
hack-6.12/645-netfilter-connmark-introduce-set-dscpmark.patch
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
From eda40b8c8c82e0f2789d6bc8bf63846dce2e8f32 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||||
|
Date: Sat, 23 Mar 2019 09:29:49 +0000
|
||||||
|
Subject: [PATCH] netfilter: connmark: introduce set-dscpmark
|
||||||
|
|
||||||
|
set-dscpmark is a method of storing the DSCP of an ip packet into
|
||||||
|
conntrack mark. In combination with a suitable tc filter action
|
||||||
|
(act_ctinfo) DSCP values are able to be stored in the mark on egress and
|
||||||
|
restored on ingress across links that otherwise alter or bleach DSCP.
|
||||||
|
|
||||||
|
This is useful for qdiscs such as CAKE which are able to shape according
|
||||||
|
to policies based on DSCP.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
x_tables CONNMARK set-dscpmark target solves the problem of storing the
|
||||||
|
DSCP to the conntrack mark in a way suitable for the new act_ctinfo tc
|
||||||
|
action to restore.
|
||||||
|
|
||||||
|
The set-dscpmark option accepts 2 parameters, a 32bit 'dscpmask' and a
|
||||||
|
32bit 'statemask'. The dscp mask must be 6 contiguous bits and
|
||||||
|
represents the area where the DSCP will be stored in the connmark. The
|
||||||
|
state mask is a minimum 1 bit length mask that must not overlap with the
|
||||||
|
dscpmask. It represents a flag which is set when the DSCP has been
|
||||||
|
stored in the conntrack mark. 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 state
|
||||||
|
mask of zero disables the setting of a status bit/s.
|
||||||
|
|
||||||
|
example syntax with a suitably modified iptables user space application:
|
||||||
|
|
||||||
|
iptables -A QOS_MARK_eth0 -t mangle -j CONNMARK --set-dscpmark 0xfc000000/0x01000000
|
||||||
|
|
||||||
|
Would store the DSCP in the top 6 bits of the 32bit mark field, and use
|
||||||
|
the LSB of the top byte as the 'DSCP has been stored' marker.
|
||||||
|
|
||||||
|
|----0xFC----conntrack mark----000000---|
|
||||||
|
| Bits 31-26 | bit 25 | bit24 |~~~ Bit 0|
|
||||||
|
| DSCP | unused | flag |unused |
|
||||||
|
|-----------------------0x01---000000---|
|
||||||
|
^ ^
|
||||||
|
| |
|
||||||
|
---| Conditional flag
|
||||||
|
| set this when dscp
|
||||||
|
|-ip diffserv-| stored in mark
|
||||||
|
| 6 bits |
|
||||||
|
|-------------|
|
||||||
|
|
||||||
|
an identically configured tc action to restore looks like:
|
||||||
|
|
||||||
|
tc filter show dev eth0 ingress
|
||||||
|
filter parent ffff: protocol all pref 10 u32 chain 0
|
||||||
|
filter parent ffff: protocol all pref 10 u32 chain 0 fh 800: ht divisor 1
|
||||||
|
filter parent ffff: protocol all pref 10 u32 chain 0 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1: not_in_hw
|
||||||
|
match 00000000/00000000 at 0
|
||||||
|
action order 1: ctinfo zone 0 pipe
|
||||||
|
index 2 ref 1 bind 1 dscp 0xfc000000/0x1000000
|
||||||
|
|
||||||
|
action order 2: mirred (Egress Redirect to device ifb4eth0) stolen
|
||||||
|
index 1 ref 1 bind 1
|
||||||
|
|
||||||
|
|----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 |
|
||||||
|
|-------------|
|
||||||
|
|
||||||
|
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||||
|
---
|
||||||
|
include/uapi/linux/netfilter/xt_connmark.h | 10 ++++
|
||||||
|
net/netfilter/xt_connmark.c | 55 ++++++++++++++++++----
|
||||||
|
2 files changed, 57 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
--- a/include/uapi/linux/netfilter/xt_connmark.h
|
||||||
|
+++ b/include/uapi/linux/netfilter/xt_connmark.h
|
||||||
|
@@ -15,6 +15,11 @@ enum {
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
+ XT_CONNMARK_VALUE = (1 << 0),
|
||||||
|
+ XT_CONNMARK_DSCP = (1 << 1)
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+enum {
|
||||||
|
D_SHIFT_LEFT = 0,
|
||||||
|
D_SHIFT_RIGHT,
|
||||||
|
};
|
||||||
|
@@ -29,6 +34,11 @@ struct xt_connmark_tginfo2 {
|
||||||
|
__u8 shift_dir, shift_bits, mode;
|
||||||
|
};
|
||||||
|
|
||||||
|
+struct xt_connmark_tginfo3 {
|
||||||
|
+ __u32 ctmark, ctmask, nfmask;
|
||||||
|
+ __u8 shift_dir, shift_bits, mode, func;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
struct xt_connmark_mtinfo1 {
|
||||||
|
__u32 mark, mask;
|
||||||
|
__u8 invert;
|
||||||
|
--- a/net/netfilter/xt_connmark.c
|
||||||
|
+++ b/net/netfilter/xt_connmark.c
|
||||||
|
@@ -24,13 +24,14 @@ MODULE_ALIAS("ipt_connmark");
|
||||||
|
MODULE_ALIAS("ip6t_connmark");
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
-connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo2 *info)
|
||||||
|
+connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo3 *info)
|
||||||
|
{
|
||||||
|
enum ip_conntrack_info ctinfo;
|
||||||
|
u_int32_t new_targetmark;
|
||||||
|
struct nf_conn *ct;
|
||||||
|
u_int32_t newmark;
|
||||||
|
u_int32_t oldmark;
|
||||||
|
+ u_int8_t dscp;
|
||||||
|
|
||||||
|
ct = nf_ct_get(skb, &ctinfo);
|
||||||
|
if (ct == NULL)
|
||||||
|
@@ -39,12 +40,24 @@ connmark_tg_shift(struct sk_buff *skb, c
|
||||||
|
switch (info->mode) {
|
||||||
|
case XT_CONNMARK_SET:
|
||||||
|
oldmark = READ_ONCE(ct->mark);
|
||||||
|
- newmark = (oldmark & ~info->ctmask) ^ info->ctmark;
|
||||||
|
- if (info->shift_dir == D_SHIFT_RIGHT)
|
||||||
|
- newmark >>= info->shift_bits;
|
||||||
|
- else
|
||||||
|
- newmark <<= info->shift_bits;
|
||||||
|
+ newmark = ct->mark;
|
||||||
|
+ if (info->func & XT_CONNMARK_VALUE) {
|
||||||
|
+ newmark = (newmark & ~info->ctmask) ^ info->ctmark;
|
||||||
|
+ if (info->shift_dir == D_SHIFT_RIGHT)
|
||||||
|
+ newmark >>= info->shift_bits;
|
||||||
|
+ else
|
||||||
|
+ newmark <<= info->shift_bits;
|
||||||
|
+ } else if (info->func & XT_CONNMARK_DSCP) {
|
||||||
|
+ if (skb->protocol == htons(ETH_P_IP))
|
||||||
|
+ dscp = ipv4_get_dsfield(ip_hdr(skb)) >> 2;
|
||||||
|
+ else if (skb->protocol == htons(ETH_P_IPV6))
|
||||||
|
+ dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> 2;
|
||||||
|
+ else /* protocol doesn't have diffserv */
|
||||||
|
+ break;
|
||||||
|
|
||||||
|
+ newmark = (newmark & ~info->ctmark) |
|
||||||
|
+ (info->ctmask | (dscp << info->shift_bits));
|
||||||
|
+ }
|
||||||
|
if (READ_ONCE(ct->mark) != newmark) {
|
||||||
|
WRITE_ONCE(ct->mark, newmark);
|
||||||
|
nf_conntrack_event_cache(IPCT_MARK, ct);
|
||||||
|
@@ -83,20 +96,36 @@ static unsigned int
|
||||||
|
connmark_tg(struct sk_buff *skb, const struct xt_action_param *par)
|
||||||
|
{
|
||||||
|
const struct xt_connmark_tginfo1 *info = par->targinfo;
|
||||||
|
- const struct xt_connmark_tginfo2 info2 = {
|
||||||
|
+ const struct xt_connmark_tginfo3 info3 = {
|
||||||
|
.ctmark = info->ctmark,
|
||||||
|
.ctmask = info->ctmask,
|
||||||
|
.nfmask = info->nfmask,
|
||||||
|
.mode = info->mode,
|
||||||
|
+ .func = XT_CONNMARK_VALUE
|
||||||
|
};
|
||||||
|
|
||||||
|
- return connmark_tg_shift(skb, &info2);
|
||||||
|
+ return connmark_tg_shift(skb, &info3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
connmark_tg_v2(struct sk_buff *skb, const struct xt_action_param *par)
|
||||||
|
{
|
||||||
|
const struct xt_connmark_tginfo2 *info = par->targinfo;
|
||||||
|
+ const struct xt_connmark_tginfo3 info3 = {
|
||||||
|
+ .ctmark = info->ctmark,
|
||||||
|
+ .ctmask = info->ctmask,
|
||||||
|
+ .nfmask = info->nfmask,
|
||||||
|
+ .mode = info->mode,
|
||||||
|
+ .func = XT_CONNMARK_VALUE
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ return connmark_tg_shift(skb, &info3);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static unsigned int
|
||||||
|
+connmark_tg_v3(struct sk_buff *skb, const struct xt_action_param *par)
|
||||||
|
+{
|
||||||
|
+ const struct xt_connmark_tginfo3 *info = par->targinfo;
|
||||||
|
|
||||||
|
return connmark_tg_shift(skb, info);
|
||||||
|
}
|
||||||
|
@@ -168,6 +197,16 @@ static struct xt_target connmark_tg_reg[
|
||||||
|
.destroy = connmark_tg_destroy,
|
||||||
|
.me = THIS_MODULE,
|
||||||
|
},
|
||||||
|
+ {
|
||||||
|
+ .name = "CONNMARK",
|
||||||
|
+ .revision = 3,
|
||||||
|
+ .family = NFPROTO_IPV4,
|
||||||
|
+ .checkentry = connmark_tg_check,
|
||||||
|
+ .target = connmark_tg_v3,
|
||||||
|
+ .targetsize = sizeof(struct xt_connmark_tginfo3),
|
||||||
|
+ .destroy = connmark_tg_destroy,
|
||||||
|
+ .me = THIS_MODULE,
|
||||||
|
+ },
|
||||||
|
#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
|
||||||
|
{
|
||||||
|
.name = "CONNMARK",
|
||||||
|
@@ -189,6 +228,16 @@ static struct xt_target connmark_tg_reg[
|
||||||
|
.destroy = connmark_tg_destroy,
|
||||||
|
.me = THIS_MODULE,
|
||||||
|
},
|
||||||
|
+ {
|
||||||
|
+ .name = "CONNMARK",
|
||||||
|
+ .revision = 3,
|
||||||
|
+ .family = NFPROTO_IPV6,
|
||||||
|
+ .checkentry = connmark_tg_check,
|
||||||
|
+ .target = connmark_tg_v3,
|
||||||
|
+ .targetsize = sizeof(struct xt_connmark_tginfo3),
|
||||||
|
+ .destroy = connmark_tg_destroy,
|
||||||
|
+ .me = THIS_MODULE,
|
||||||
|
+ },
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
812
hack-6.12/650-netfilter-add-xt_FLOWOFFLOAD-target.patch
Normal file
812
hack-6.12/650-netfilter-add-xt_FLOWOFFLOAD-target.patch
Normal file
@ -0,0 +1,812 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Tue, 20 Feb 2018 15:56:02 +0100
|
||||||
|
Subject: [PATCH] netfilter: add xt_FLOWOFFLOAD target
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
create mode 100644 net/netfilter/xt_OFFLOAD.c
|
||||||
|
|
||||||
|
--- a/net/netfilter/Kconfig
|
||||||
|
+++ b/net/netfilter/Kconfig
|
||||||
|
@@ -729,7 +729,6 @@ config NF_FLOW_TABLE
|
||||||
|
tristate "Netfilter flow table module"
|
||||||
|
depends on NETFILTER_INGRESS
|
||||||
|
depends on NF_CONNTRACK
|
||||||
|
- depends on NF_TABLES
|
||||||
|
help
|
||||||
|
This option adds the flow table core infrastructure.
|
||||||
|
|
||||||
|
@@ -1025,6 +1024,15 @@ config NETFILTER_XT_TARGET_NOTRACK
|
||||||
|
depends on NETFILTER_ADVANCED
|
||||||
|
select NETFILTER_XT_TARGET_CT
|
||||||
|
|
||||||
|
+config NETFILTER_XT_TARGET_FLOWOFFLOAD
|
||||||
|
+ tristate '"FLOWOFFLOAD" target support'
|
||||||
|
+ depends on NF_FLOW_TABLE
|
||||||
|
+ depends on NETFILTER_INGRESS
|
||||||
|
+ help
|
||||||
|
+ This option adds a `FLOWOFFLOAD' target, which uses the nf_flow_offload
|
||||||
|
+ module to speed up processing of packets by bypassing the usual
|
||||||
|
+ netfilter chains
|
||||||
|
+
|
||||||
|
config NETFILTER_XT_TARGET_RATEEST
|
||||||
|
tristate '"RATEEST" target support'
|
||||||
|
depends on NETFILTER_ADVANCED
|
||||||
|
--- a/net/netfilter/Makefile
|
||||||
|
+++ b/net/netfilter/Makefile
|
||||||
|
@@ -168,6 +168,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIF
|
||||||
|
obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
|
||||||
|
obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o
|
||||||
|
obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
|
||||||
|
+obj-$(CONFIG_NETFILTER_XT_TARGET_FLOWOFFLOAD) += xt_FLOWOFFLOAD.o
|
||||||
|
obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o
|
||||||
|
obj-$(CONFIG_NETFILTER_XT_TARGET_HMARK) += xt_HMARK.o
|
||||||
|
obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/net/netfilter/xt_FLOWOFFLOAD.c
|
||||||
|
@@ -0,0 +1,703 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright (C) 2018-2021 Felix Fietkau <nbd@nbd.name>
|
||||||
|
+ *
|
||||||
|
+ * 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.
|
||||||
|
+ */
|
||||||
|
+#include <linux/module.h>
|
||||||
|
+#include <linux/init.h>
|
||||||
|
+#include <linux/netfilter.h>
|
||||||
|
+#include <linux/netfilter/xt_FLOWOFFLOAD.h>
|
||||||
|
+#include <linux/if_vlan.h>
|
||||||
|
+#include <net/ip.h>
|
||||||
|
+#include <net/netfilter/nf_conntrack.h>
|
||||||
|
+#include <net/netfilter/nf_conntrack_extend.h>
|
||||||
|
+#include <net/netfilter/nf_conntrack_helper.h>
|
||||||
|
+#include <net/netfilter/nf_flow_table.h>
|
||||||
|
+
|
||||||
|
+struct xt_flowoffload_hook {
|
||||||
|
+ struct hlist_node list;
|
||||||
|
+ struct nf_hook_ops ops;
|
||||||
|
+ struct net *net;
|
||||||
|
+ bool registered;
|
||||||
|
+ bool used;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct xt_flowoffload_table {
|
||||||
|
+ struct nf_flowtable ft;
|
||||||
|
+ struct hlist_head hooks;
|
||||||
|
+ struct delayed_work work;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct nf_forward_info {
|
||||||
|
+ const struct net_device *indev;
|
||||||
|
+ const struct net_device *outdev;
|
||||||
|
+ const struct net_device *hw_outdev;
|
||||||
|
+ struct id {
|
||||||
|
+ __u16 id;
|
||||||
|
+ __be16 proto;
|
||||||
|
+ } encap[NF_FLOW_TABLE_ENCAP_MAX];
|
||||||
|
+ u8 num_encaps;
|
||||||
|
+ u8 ingress_vlans;
|
||||||
|
+ u8 h_source[ETH_ALEN];
|
||||||
|
+ u8 h_dest[ETH_ALEN];
|
||||||
|
+ enum flow_offload_xmit_type xmit_type;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static DEFINE_SPINLOCK(hooks_lock);
|
||||||
|
+
|
||||||
|
+struct xt_flowoffload_table flowtable[2];
|
||||||
|
+
|
||||||
|
+static unsigned int
|
||||||
|
+xt_flowoffload_net_hook(void *priv, struct sk_buff *skb,
|
||||||
|
+ const struct nf_hook_state *state)
|
||||||
|
+{
|
||||||
|
+ struct vlan_ethhdr *veth;
|
||||||
|
+ __be16 proto;
|
||||||
|
+
|
||||||
|
+ switch (skb->protocol) {
|
||||||
|
+ case htons(ETH_P_8021Q):
|
||||||
|
+ veth = (struct vlan_ethhdr *)skb_mac_header(skb);
|
||||||
|
+ proto = veth->h_vlan_encapsulated_proto;
|
||||||
|
+ break;
|
||||||
|
+ case htons(ETH_P_PPP_SES):
|
||||||
|
+ if (!nf_flow_pppoe_proto(skb, &proto))
|
||||||
|
+ return NF_ACCEPT;
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ proto = skb->protocol;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ switch (proto) {
|
||||||
|
+ case htons(ETH_P_IP):
|
||||||
|
+ return nf_flow_offload_ip_hook(priv, skb, state);
|
||||||
|
+ case htons(ETH_P_IPV6):
|
||||||
|
+ return nf_flow_offload_ipv6_hook(priv, skb, state);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return NF_ACCEPT;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+xt_flowoffload_create_hook(struct xt_flowoffload_table *table,
|
||||||
|
+ struct net_device *dev)
|
||||||
|
+{
|
||||||
|
+ struct xt_flowoffload_hook *hook;
|
||||||
|
+ struct nf_hook_ops *ops;
|
||||||
|
+
|
||||||
|
+ hook = kzalloc(sizeof(*hook), GFP_ATOMIC);
|
||||||
|
+ if (!hook)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ ops = &hook->ops;
|
||||||
|
+ ops->pf = NFPROTO_NETDEV;
|
||||||
|
+ ops->hooknum = NF_NETDEV_INGRESS;
|
||||||
|
+ ops->priority = 10;
|
||||||
|
+ ops->priv = &table->ft;
|
||||||
|
+ ops->hook = xt_flowoffload_net_hook;
|
||||||
|
+ ops->dev = dev;
|
||||||
|
+
|
||||||
|
+ hlist_add_head(&hook->list, &table->hooks);
|
||||||
|
+ mod_delayed_work(system_power_efficient_wq, &table->work, 0);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct xt_flowoffload_hook *
|
||||||
|
+flow_offload_lookup_hook(struct xt_flowoffload_table *table,
|
||||||
|
+ struct net_device *dev)
|
||||||
|
+{
|
||||||
|
+ struct xt_flowoffload_hook *hook;
|
||||||
|
+
|
||||||
|
+ hlist_for_each_entry(hook, &table->hooks, list) {
|
||||||
|
+ if (hook->ops.dev == dev)
|
||||||
|
+ return hook;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+xt_flowoffload_check_device(struct xt_flowoffload_table *table,
|
||||||
|
+ struct net_device *dev)
|
||||||
|
+{
|
||||||
|
+ struct xt_flowoffload_hook *hook;
|
||||||
|
+
|
||||||
|
+ if (!dev)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ spin_lock_bh(&hooks_lock);
|
||||||
|
+ hook = flow_offload_lookup_hook(table, dev);
|
||||||
|
+ if (hook)
|
||||||
|
+ hook->used = true;
|
||||||
|
+ else
|
||||||
|
+ xt_flowoffload_create_hook(table, dev);
|
||||||
|
+ spin_unlock_bh(&hooks_lock);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+xt_flowoffload_register_hooks(struct xt_flowoffload_table *table)
|
||||||
|
+{
|
||||||
|
+ struct xt_flowoffload_hook *hook;
|
||||||
|
+
|
||||||
|
+restart:
|
||||||
|
+ hlist_for_each_entry(hook, &table->hooks, list) {
|
||||||
|
+ if (hook->registered)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ hook->registered = true;
|
||||||
|
+ hook->net = dev_net(hook->ops.dev);
|
||||||
|
+ spin_unlock_bh(&hooks_lock);
|
||||||
|
+ nf_register_net_hook(hook->net, &hook->ops);
|
||||||
|
+ if (table->ft.flags & NF_FLOWTABLE_HW_OFFLOAD)
|
||||||
|
+ table->ft.type->setup(&table->ft, hook->ops.dev,
|
||||||
|
+ FLOW_BLOCK_BIND);
|
||||||
|
+ spin_lock_bh(&hooks_lock);
|
||||||
|
+ goto restart;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static bool
|
||||||
|
+xt_flowoffload_cleanup_hooks(struct xt_flowoffload_table *table)
|
||||||
|
+{
|
||||||
|
+ struct xt_flowoffload_hook *hook;
|
||||||
|
+ bool active = false;
|
||||||
|
+
|
||||||
|
+restart:
|
||||||
|
+ spin_lock_bh(&hooks_lock);
|
||||||
|
+ hlist_for_each_entry(hook, &table->hooks, list) {
|
||||||
|
+ if (hook->used || !hook->registered) {
|
||||||
|
+ active = true;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ hlist_del(&hook->list);
|
||||||
|
+ spin_unlock_bh(&hooks_lock);
|
||||||
|
+ if (table->ft.flags & NF_FLOWTABLE_HW_OFFLOAD)
|
||||||
|
+ table->ft.type->setup(&table->ft, hook->ops.dev,
|
||||||
|
+ FLOW_BLOCK_UNBIND);
|
||||||
|
+ nf_unregister_net_hook(hook->net, &hook->ops);
|
||||||
|
+ kfree(hook);
|
||||||
|
+ goto restart;
|
||||||
|
+ }
|
||||||
|
+ spin_unlock_bh(&hooks_lock);
|
||||||
|
+
|
||||||
|
+ return active;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+xt_flowoffload_check_hook(struct nf_flowtable *flowtable,
|
||||||
|
+ struct flow_offload *flow, void *data)
|
||||||
|
+{
|
||||||
|
+ struct xt_flowoffload_table *table;
|
||||||
|
+ struct flow_offload_tuple *tuple0 = &flow->tuplehash[0].tuple;
|
||||||
|
+ struct flow_offload_tuple *tuple1 = &flow->tuplehash[1].tuple;
|
||||||
|
+ struct xt_flowoffload_hook *hook;
|
||||||
|
+
|
||||||
|
+ table = container_of(flowtable, struct xt_flowoffload_table, ft);
|
||||||
|
+
|
||||||
|
+ spin_lock_bh(&hooks_lock);
|
||||||
|
+ hlist_for_each_entry(hook, &table->hooks, list) {
|
||||||
|
+ if (hook->ops.dev->ifindex != tuple0->iifidx &&
|
||||||
|
+ hook->ops.dev->ifindex != tuple1->iifidx)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ hook->used = true;
|
||||||
|
+ }
|
||||||
|
+ spin_unlock_bh(&hooks_lock);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+xt_flowoffload_hook_work(struct work_struct *work)
|
||||||
|
+{
|
||||||
|
+ struct xt_flowoffload_table *table;
|
||||||
|
+ struct xt_flowoffload_hook *hook;
|
||||||
|
+ int err;
|
||||||
|
+
|
||||||
|
+ table = container_of(work, struct xt_flowoffload_table, work.work);
|
||||||
|
+
|
||||||
|
+ spin_lock_bh(&hooks_lock);
|
||||||
|
+ xt_flowoffload_register_hooks(table);
|
||||||
|
+ hlist_for_each_entry(hook, &table->hooks, list)
|
||||||
|
+ hook->used = false;
|
||||||
|
+ spin_unlock_bh(&hooks_lock);
|
||||||
|
+
|
||||||
|
+ err = nf_flow_table_iterate(&table->ft, xt_flowoffload_check_hook,
|
||||||
|
+ NULL);
|
||||||
|
+ if (err && err != -EAGAIN)
|
||||||
|
+ goto out;
|
||||||
|
+
|
||||||
|
+ if (!xt_flowoffload_cleanup_hooks(table))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+out:
|
||||||
|
+ queue_delayed_work(system_power_efficient_wq, &table->work, HZ);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static bool
|
||||||
|
+xt_flowoffload_skip(struct sk_buff *skb, int family)
|
||||||
|
+{
|
||||||
|
+ if (skb_sec_path(skb))
|
||||||
|
+ return true;
|
||||||
|
+
|
||||||
|
+ if (family == NFPROTO_IPV4) {
|
||||||
|
+ const struct ip_options *opt = &(IPCB(skb)->opt);
|
||||||
|
+
|
||||||
|
+ if (unlikely(opt->optlen))
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return false;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static enum flow_offload_xmit_type nf_xmit_type(struct dst_entry *dst)
|
||||||
|
+{
|
||||||
|
+ if (dst_xfrm(dst))
|
||||||
|
+ return FLOW_OFFLOAD_XMIT_XFRM;
|
||||||
|
+
|
||||||
|
+ return FLOW_OFFLOAD_XMIT_NEIGH;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void nf_default_forward_path(struct nf_flow_route *route,
|
||||||
|
+ struct dst_entry *dst_cache,
|
||||||
|
+ enum ip_conntrack_dir dir,
|
||||||
|
+ struct net_device **dev)
|
||||||
|
+{
|
||||||
|
+ dev[!dir] = dst_cache->dev;
|
||||||
|
+ route->tuple[!dir].in.ifindex = dst_cache->dev->ifindex;
|
||||||
|
+ route->tuple[dir].dst = dst_cache;
|
||||||
|
+ route->tuple[dir].xmit_type = nf_xmit_type(dst_cache);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static bool nf_is_valid_ether_device(const struct net_device *dev)
|
||||||
|
+{
|
||||||
|
+ if (!dev || (dev->flags & IFF_LOOPBACK) || dev->type != ARPHRD_ETHER ||
|
||||||
|
+ dev->addr_len != ETH_ALEN || !is_valid_ether_addr(dev->dev_addr))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void nf_dev_path_info(const struct net_device_path_stack *stack,
|
||||||
|
+ struct nf_forward_info *info,
|
||||||
|
+ unsigned char *ha)
|
||||||
|
+{
|
||||||
|
+ const struct net_device_path *path;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ memcpy(info->h_dest, ha, ETH_ALEN);
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < stack->num_paths; i++) {
|
||||||
|
+ path = &stack->path[i];
|
||||||
|
+ switch (path->type) {
|
||||||
|
+ case DEV_PATH_ETHERNET:
|
||||||
|
+ case DEV_PATH_DSA:
|
||||||
|
+ case DEV_PATH_VLAN:
|
||||||
|
+ case DEV_PATH_PPPOE:
|
||||||
|
+ info->indev = path->dev;
|
||||||
|
+ if (is_zero_ether_addr(info->h_source))
|
||||||
|
+ memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN);
|
||||||
|
+
|
||||||
|
+ if (path->type == DEV_PATH_ETHERNET)
|
||||||
|
+ break;
|
||||||
|
+ if (path->type == DEV_PATH_DSA) {
|
||||||
|
+ i = stack->num_paths;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* DEV_PATH_VLAN and DEV_PATH_PPPOE */
|
||||||
|
+ if (info->num_encaps >= NF_FLOW_TABLE_ENCAP_MAX) {
|
||||||
|
+ info->indev = NULL;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ if (!info->outdev)
|
||||||
|
+ info->outdev = path->dev;
|
||||||
|
+ info->encap[info->num_encaps].id = path->encap.id;
|
||||||
|
+ info->encap[info->num_encaps].proto = path->encap.proto;
|
||||||
|
+ info->num_encaps++;
|
||||||
|
+ if (path->type == DEV_PATH_PPPOE)
|
||||||
|
+ memcpy(info->h_dest, path->encap.h_dest, ETH_ALEN);
|
||||||
|
+ break;
|
||||||
|
+ case DEV_PATH_BRIDGE:
|
||||||
|
+ if (is_zero_ether_addr(info->h_source))
|
||||||
|
+ memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN);
|
||||||
|
+
|
||||||
|
+ switch (path->bridge.vlan_mode) {
|
||||||
|
+ case DEV_PATH_BR_VLAN_UNTAG_HW:
|
||||||
|
+ info->ingress_vlans |= BIT(info->num_encaps - 1);
|
||||||
|
+ break;
|
||||||
|
+ case DEV_PATH_BR_VLAN_TAG:
|
||||||
|
+ info->encap[info->num_encaps].id = path->bridge.vlan_id;
|
||||||
|
+ info->encap[info->num_encaps].proto = path->bridge.vlan_proto;
|
||||||
|
+ info->num_encaps++;
|
||||||
|
+ break;
|
||||||
|
+ case DEV_PATH_BR_VLAN_UNTAG:
|
||||||
|
+ info->num_encaps--;
|
||||||
|
+ break;
|
||||||
|
+ case DEV_PATH_BR_VLAN_KEEP:
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ info->indev = NULL;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if (!info->outdev)
|
||||||
|
+ info->outdev = info->indev;
|
||||||
|
+
|
||||||
|
+ info->hw_outdev = info->indev;
|
||||||
|
+
|
||||||
|
+ if (nf_is_valid_ether_device(info->indev))
|
||||||
|
+ info->xmit_type = FLOW_OFFLOAD_XMIT_DIRECT;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int nf_dev_fill_forward_path(const struct nf_flow_route *route,
|
||||||
|
+ const struct dst_entry *dst_cache,
|
||||||
|
+ const struct nf_conn *ct,
|
||||||
|
+ enum ip_conntrack_dir dir, u8 *ha,
|
||||||
|
+ struct net_device_path_stack *stack)
|
||||||
|
+{
|
||||||
|
+ const void *daddr = &ct->tuplehash[!dir].tuple.src.u3;
|
||||||
|
+ struct net_device *dev = dst_cache->dev;
|
||||||
|
+ struct neighbour *n;
|
||||||
|
+ u8 nud_state;
|
||||||
|
+
|
||||||
|
+ if (!nf_is_valid_ether_device(dev))
|
||||||
|
+ goto out;
|
||||||
|
+
|
||||||
|
+ n = dst_neigh_lookup(dst_cache, daddr);
|
||||||
|
+ if (!n)
|
||||||
|
+ return -1;
|
||||||
|
+
|
||||||
|
+ read_lock_bh(&n->lock);
|
||||||
|
+ nud_state = n->nud_state;
|
||||||
|
+ ether_addr_copy(ha, n->ha);
|
||||||
|
+ read_unlock_bh(&n->lock);
|
||||||
|
+ neigh_release(n);
|
||||||
|
+
|
||||||
|
+ if (!(nud_state & NUD_VALID))
|
||||||
|
+ return -1;
|
||||||
|
+
|
||||||
|
+out:
|
||||||
|
+ return dev_fill_forward_path(dev, ha, stack);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void nf_dev_forward_path(struct nf_flow_route *route,
|
||||||
|
+ const struct nf_conn *ct,
|
||||||
|
+ enum ip_conntrack_dir dir,
|
||||||
|
+ struct net_device **devs)
|
||||||
|
+{
|
||||||
|
+ const struct dst_entry *dst = route->tuple[dir].dst;
|
||||||
|
+ struct net_device_path_stack stack;
|
||||||
|
+ struct nf_forward_info info = {};
|
||||||
|
+ unsigned char ha[ETH_ALEN];
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ if (nf_dev_fill_forward_path(route, dst, ct, dir, ha, &stack) >= 0)
|
||||||
|
+ nf_dev_path_info(&stack, &info, ha);
|
||||||
|
+
|
||||||
|
+ devs[!dir] = (struct net_device *)info.indev;
|
||||||
|
+ if (!info.indev)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ route->tuple[!dir].in.ifindex = info.indev->ifindex;
|
||||||
|
+ for (i = 0; i < info.num_encaps; i++) {
|
||||||
|
+ route->tuple[!dir].in.encap[i].id = info.encap[i].id;
|
||||||
|
+ route->tuple[!dir].in.encap[i].proto = info.encap[i].proto;
|
||||||
|
+ }
|
||||||
|
+ route->tuple[!dir].in.num_encaps = info.num_encaps;
|
||||||
|
+ route->tuple[!dir].in.ingress_vlans = info.ingress_vlans;
|
||||||
|
+
|
||||||
|
+ if (info.xmit_type == FLOW_OFFLOAD_XMIT_DIRECT) {
|
||||||
|
+ memcpy(route->tuple[dir].out.h_source, info.h_source, ETH_ALEN);
|
||||||
|
+ memcpy(route->tuple[dir].out.h_dest, info.h_dest, ETH_ALEN);
|
||||||
|
+ route->tuple[dir].out.ifindex = info.outdev->ifindex;
|
||||||
|
+ route->tuple[dir].out.hw_ifindex = info.hw_outdev->ifindex;
|
||||||
|
+ route->tuple[dir].xmit_type = info.xmit_type;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+xt_flowoffload_route(struct sk_buff *skb, const struct nf_conn *ct,
|
||||||
|
+ const struct xt_action_param *par,
|
||||||
|
+ struct nf_flow_route *route, enum ip_conntrack_dir dir,
|
||||||
|
+ struct net_device **devs)
|
||||||
|
+{
|
||||||
|
+ struct dst_entry *this_dst = skb_dst(skb);
|
||||||
|
+ struct dst_entry *other_dst = NULL;
|
||||||
|
+ struct flowi fl;
|
||||||
|
+
|
||||||
|
+ memset(&fl, 0, sizeof(fl));
|
||||||
|
+ switch (xt_family(par)) {
|
||||||
|
+ case NFPROTO_IPV4:
|
||||||
|
+ fl.u.ip4.daddr = ct->tuplehash[dir].tuple.src.u3.ip;
|
||||||
|
+ fl.u.ip4.flowi4_oif = xt_in(par)->ifindex;
|
||||||
|
+ break;
|
||||||
|
+ case NFPROTO_IPV6:
|
||||||
|
+ fl.u.ip6.saddr = ct->tuplehash[!dir].tuple.dst.u3.in6;
|
||||||
|
+ fl.u.ip6.daddr = ct->tuplehash[dir].tuple.src.u3.in6;
|
||||||
|
+ fl.u.ip6.flowi6_oif = xt_in(par)->ifindex;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!dst_hold_safe(this_dst))
|
||||||
|
+ return -ENOENT;
|
||||||
|
+
|
||||||
|
+ nf_route(xt_net(par), &other_dst, &fl, false, xt_family(par));
|
||||||
|
+ if (!other_dst) {
|
||||||
|
+ dst_release(this_dst);
|
||||||
|
+ return -ENOENT;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ nf_default_forward_path(route, this_dst, dir, devs);
|
||||||
|
+ nf_default_forward_path(route, other_dst, !dir, devs);
|
||||||
|
+
|
||||||
|
+ if (route->tuple[dir].xmit_type == FLOW_OFFLOAD_XMIT_NEIGH &&
|
||||||
|
+ route->tuple[!dir].xmit_type == FLOW_OFFLOAD_XMIT_NEIGH) {
|
||||||
|
+ nf_dev_forward_path(route, ct, dir, devs);
|
||||||
|
+ nf_dev_forward_path(route, ct, !dir, devs);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static unsigned int
|
||||||
|
+flowoffload_tg(struct sk_buff *skb, const struct xt_action_param *par)
|
||||||
|
+{
|
||||||
|
+ struct xt_flowoffload_table *table;
|
||||||
|
+ const struct xt_flowoffload_target_info *info = par->targinfo;
|
||||||
|
+ struct tcphdr _tcph, *tcph = NULL;
|
||||||
|
+ enum ip_conntrack_info ctinfo;
|
||||||
|
+ enum ip_conntrack_dir dir;
|
||||||
|
+ struct nf_flow_route route = {};
|
||||||
|
+ struct flow_offload *flow = NULL;
|
||||||
|
+ struct net_device *devs[2] = {};
|
||||||
|
+ struct nf_conn *ct;
|
||||||
|
+ struct net *net;
|
||||||
|
+
|
||||||
|
+ if (xt_flowoffload_skip(skb, xt_family(par)))
|
||||||
|
+ return XT_CONTINUE;
|
||||||
|
+
|
||||||
|
+ ct = nf_ct_get(skb, &ctinfo);
|
||||||
|
+ if (ct == NULL)
|
||||||
|
+ return XT_CONTINUE;
|
||||||
|
+
|
||||||
|
+ switch (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum) {
|
||||||
|
+ case IPPROTO_TCP:
|
||||||
|
+ if (ct->proto.tcp.state != TCP_CONNTRACK_ESTABLISHED)
|
||||||
|
+ return XT_CONTINUE;
|
||||||
|
+
|
||||||
|
+ tcph = skb_header_pointer(skb, par->thoff,
|
||||||
|
+ sizeof(_tcph), &_tcph);
|
||||||
|
+ if (unlikely(!tcph || tcph->fin || tcph->rst))
|
||||||
|
+ return XT_CONTINUE;
|
||||||
|
+ break;
|
||||||
|
+ case IPPROTO_UDP:
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ return XT_CONTINUE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (nf_ct_ext_exist(ct, NF_CT_EXT_HELPER) ||
|
||||||
|
+ ct->status & (IPS_SEQ_ADJUST | IPS_NAT_CLASH))
|
||||||
|
+ return XT_CONTINUE;
|
||||||
|
+
|
||||||
|
+ if (!nf_ct_is_confirmed(ct))
|
||||||
|
+ return XT_CONTINUE;
|
||||||
|
+
|
||||||
|
+ dir = CTINFO2DIR(ctinfo);
|
||||||
|
+
|
||||||
|
+ devs[dir] = xt_out(par);
|
||||||
|
+ devs[!dir] = xt_in(par);
|
||||||
|
+
|
||||||
|
+ if (!devs[dir] || !devs[!dir])
|
||||||
|
+ return XT_CONTINUE;
|
||||||
|
+
|
||||||
|
+ if (test_and_set_bit(IPS_OFFLOAD_BIT, &ct->status))
|
||||||
|
+ return XT_CONTINUE;
|
||||||
|
+
|
||||||
|
+ if (xt_flowoffload_route(skb, ct, par, &route, dir, devs) < 0)
|
||||||
|
+ goto err_flow_route;
|
||||||
|
+
|
||||||
|
+ flow = flow_offload_alloc(ct);
|
||||||
|
+ if (!flow)
|
||||||
|
+ goto err_flow_alloc;
|
||||||
|
+
|
||||||
|
+ flow_offload_route_init(flow, &route);
|
||||||
|
+
|
||||||
|
+ if (tcph) {
|
||||||
|
+ ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL;
|
||||||
|
+ ct->proto.tcp.seen[1].flags |= IP_CT_TCP_FLAG_BE_LIBERAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ table = &flowtable[!!(info->flags & XT_FLOWOFFLOAD_HW)];
|
||||||
|
+
|
||||||
|
+ net = read_pnet(&table->ft.net);
|
||||||
|
+ if (!net)
|
||||||
|
+ write_pnet(&table->ft.net, xt_net(par));
|
||||||
|
+
|
||||||
|
+ __set_bit(NF_FLOW_HW_BIDIRECTIONAL, &flow->flags);
|
||||||
|
+ if (flow_offload_add(&table->ft, flow) < 0)
|
||||||
|
+ goto err_flow_add;
|
||||||
|
+
|
||||||
|
+ xt_flowoffload_check_device(table, devs[0]);
|
||||||
|
+ xt_flowoffload_check_device(table, devs[1]);
|
||||||
|
+
|
||||||
|
+ return XT_CONTINUE;
|
||||||
|
+
|
||||||
|
+err_flow_add:
|
||||||
|
+ flow_offload_free(flow);
|
||||||
|
+err_flow_alloc:
|
||||||
|
+ dst_release(route.tuple[dir].dst);
|
||||||
|
+ dst_release(route.tuple[!dir].dst);
|
||||||
|
+err_flow_route:
|
||||||
|
+ clear_bit(IPS_OFFLOAD_BIT, &ct->status);
|
||||||
|
+
|
||||||
|
+ return XT_CONTINUE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int flowoffload_chk(const struct xt_tgchk_param *par)
|
||||||
|
+{
|
||||||
|
+ struct xt_flowoffload_target_info *info = par->targinfo;
|
||||||
|
+
|
||||||
|
+ if (info->flags & ~XT_FLOWOFFLOAD_MASK)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct xt_target offload_tg_reg __read_mostly = {
|
||||||
|
+ .family = NFPROTO_UNSPEC,
|
||||||
|
+ .name = "FLOWOFFLOAD",
|
||||||
|
+ .revision = 0,
|
||||||
|
+ .targetsize = sizeof(struct xt_flowoffload_target_info),
|
||||||
|
+ .usersize = sizeof(struct xt_flowoffload_target_info),
|
||||||
|
+ .checkentry = flowoffload_chk,
|
||||||
|
+ .target = flowoffload_tg,
|
||||||
|
+ .me = THIS_MODULE,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int flow_offload_netdev_event(struct notifier_block *this,
|
||||||
|
+ unsigned long event, void *ptr)
|
||||||
|
+{
|
||||||
|
+ struct xt_flowoffload_hook *hook0, *hook1;
|
||||||
|
+ struct net_device *dev = netdev_notifier_info_to_dev(ptr);
|
||||||
|
+
|
||||||
|
+ if (event != NETDEV_UNREGISTER)
|
||||||
|
+ return NOTIFY_DONE;
|
||||||
|
+
|
||||||
|
+ spin_lock_bh(&hooks_lock);
|
||||||
|
+ hook0 = flow_offload_lookup_hook(&flowtable[0], dev);
|
||||||
|
+ if (hook0)
|
||||||
|
+ hlist_del(&hook0->list);
|
||||||
|
+
|
||||||
|
+ hook1 = flow_offload_lookup_hook(&flowtable[1], dev);
|
||||||
|
+ if (hook1)
|
||||||
|
+ hlist_del(&hook1->list);
|
||||||
|
+ spin_unlock_bh(&hooks_lock);
|
||||||
|
+
|
||||||
|
+ if (hook0) {
|
||||||
|
+ nf_unregister_net_hook(hook0->net, &hook0->ops);
|
||||||
|
+ kfree(hook0);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (hook1) {
|
||||||
|
+ nf_unregister_net_hook(hook1->net, &hook1->ops);
|
||||||
|
+ kfree(hook1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ nf_flow_table_cleanup(dev);
|
||||||
|
+
|
||||||
|
+ return NOTIFY_DONE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct notifier_block flow_offload_netdev_notifier = {
|
||||||
|
+ .notifier_call = flow_offload_netdev_event,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int nf_flow_rule_route_inet(struct net *net,
|
||||||
|
+ struct flow_offload *flow,
|
||||||
|
+ enum flow_offload_tuple_dir dir,
|
||||||
|
+ struct nf_flow_rule *flow_rule)
|
||||||
|
+{
|
||||||
|
+ const struct flow_offload_tuple *flow_tuple = &flow->tuplehash[dir].tuple;
|
||||||
|
+ int err;
|
||||||
|
+
|
||||||
|
+ switch (flow_tuple->l3proto) {
|
||||||
|
+ case NFPROTO_IPV4:
|
||||||
|
+ err = nf_flow_rule_route_ipv4(net, flow, dir, flow_rule);
|
||||||
|
+ break;
|
||||||
|
+ case NFPROTO_IPV6:
|
||||||
|
+ err = nf_flow_rule_route_ipv6(net, flow, dir, flow_rule);
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ err = -1;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return err;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct nf_flowtable_type flowtable_inet = {
|
||||||
|
+ .family = NFPROTO_INET,
|
||||||
|
+ .init = nf_flow_table_init,
|
||||||
|
+ .setup = nf_flow_table_offload_setup,
|
||||||
|
+ .action = nf_flow_rule_route_inet,
|
||||||
|
+ .free = nf_flow_table_free,
|
||||||
|
+ .hook = xt_flowoffload_net_hook,
|
||||||
|
+ .owner = THIS_MODULE,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int init_flowtable(struct xt_flowoffload_table *tbl)
|
||||||
|
+{
|
||||||
|
+ INIT_DELAYED_WORK(&tbl->work, xt_flowoffload_hook_work);
|
||||||
|
+ tbl->ft.type = &flowtable_inet;
|
||||||
|
+ tbl->ft.flags = NF_FLOWTABLE_COUNTER;
|
||||||
|
+
|
||||||
|
+ return nf_flow_table_init(&tbl->ft);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int __init xt_flowoffload_tg_init(void)
|
||||||
|
+{
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ register_netdevice_notifier(&flow_offload_netdev_notifier);
|
||||||
|
+
|
||||||
|
+ ret = init_flowtable(&flowtable[0]);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = init_flowtable(&flowtable[1]);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto cleanup;
|
||||||
|
+
|
||||||
|
+ flowtable[1].ft.flags |= NF_FLOWTABLE_HW_OFFLOAD;
|
||||||
|
+
|
||||||
|
+ ret = xt_register_target(&offload_tg_reg);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto cleanup2;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+cleanup2:
|
||||||
|
+ nf_flow_table_free(&flowtable[1].ft);
|
||||||
|
+cleanup:
|
||||||
|
+ nf_flow_table_free(&flowtable[0].ft);
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void __exit xt_flowoffload_tg_exit(void)
|
||||||
|
+{
|
||||||
|
+ xt_unregister_target(&offload_tg_reg);
|
||||||
|
+ unregister_netdevice_notifier(&flow_offload_netdev_notifier);
|
||||||
|
+ nf_flow_table_free(&flowtable[0].ft);
|
||||||
|
+ nf_flow_table_free(&flowtable[1].ft);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+MODULE_LICENSE("GPL");
|
||||||
|
+module_init(xt_flowoffload_tg_init);
|
||||||
|
+module_exit(xt_flowoffload_tg_exit);
|
||||||
|
--- a/net/netfilter/nf_flow_table_core.c
|
||||||
|
+++ b/net/netfilter/nf_flow_table_core.c
|
||||||
|
@@ -7,7 +7,6 @@
|
||||||
|
#include <linux/netdevice.h>
|
||||||
|
#include <net/ip.h>
|
||||||
|
#include <net/ip6_route.h>
|
||||||
|
-#include <net/netfilter/nf_tables.h>
|
||||||
|
#include <net/netfilter/nf_flow_table.h>
|
||||||
|
#include <net/netfilter/nf_conntrack.h>
|
||||||
|
#include <net/netfilter/nf_conntrack_core.h>
|
||||||
|
@@ -373,8 +372,7 @@ flow_offload_lookup(struct nf_flowtable
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(flow_offload_lookup);
|
||||||
|
|
||||||
|
-static int
|
||||||
|
-nf_flow_table_iterate(struct nf_flowtable *flow_table,
|
||||||
|
+int nf_flow_table_iterate(struct nf_flowtable *flow_table,
|
||||||
|
void (*iter)(struct nf_flowtable *flowtable,
|
||||||
|
struct flow_offload *flow, void *data),
|
||||||
|
void *data)
|
||||||
|
@@ -435,6 +433,7 @@ static void nf_flow_offload_gc_step(stru
|
||||||
|
nf_flow_offload_stats(flow_table, flow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(nf_flow_table_iterate);
|
||||||
|
|
||||||
|
void nf_flow_table_gc_run(struct nf_flowtable *flow_table)
|
||||||
|
{
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/include/uapi/linux/netfilter/xt_FLOWOFFLOAD.h
|
||||||
|
@@ -0,0 +1,17 @@
|
||||||
|
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||||
|
+#ifndef _XT_FLOWOFFLOAD_H
|
||||||
|
+#define _XT_FLOWOFFLOAD_H
|
||||||
|
+
|
||||||
|
+#include <linux/types.h>
|
||||||
|
+
|
||||||
|
+enum {
|
||||||
|
+ XT_FLOWOFFLOAD_HW = 1 << 0,
|
||||||
|
+
|
||||||
|
+ XT_FLOWOFFLOAD_MASK = XT_FLOWOFFLOAD_HW
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct xt_flowoffload_target_info {
|
||||||
|
+ __u32 flags;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+#endif /* _XT_FLOWOFFLOAD_H */
|
||||||
|
--- a/include/net/netfilter/nf_flow_table.h
|
||||||
|
+++ b/include/net/netfilter/nf_flow_table.h
|
||||||
|
@@ -294,6 +294,11 @@ void nf_flow_table_free(struct nf_flowta
|
||||||
|
|
||||||
|
void flow_offload_teardown(struct flow_offload *flow);
|
||||||
|
|
||||||
|
+int nf_flow_table_iterate(struct nf_flowtable *flow_table,
|
||||||
|
+ void (*iter)(struct nf_flowtable *flowtable,
|
||||||
|
+ struct flow_offload *flow, void *data),
|
||||||
|
+ void *data);
|
||||||
|
+
|
||||||
|
void nf_flow_snat_port(const struct flow_offload *flow,
|
||||||
|
struct sk_buff *skb, unsigned int thoff,
|
||||||
|
u8 protocol, enum flow_offload_tuple_dir dir);
|
24
hack-6.12/651-wireless_mesh_header.patch
Normal file
24
hack-6.12/651-wireless_mesh_header.patch
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
From 6d3bc769657b0ee7c7506dad9911111c4226a7ea Mon Sep 17 00:00:00 2001
|
||||||
|
From: Imre Kaloz <kaloz@openwrt.org>
|
||||||
|
Date: Fri, 7 Jul 2017 17:21:05 +0200
|
||||||
|
Subject: mac80211: increase wireless mesh header size
|
||||||
|
|
||||||
|
lede-commit 3d4466cfd8f75f717efdb1f96fdde3c70d865fc1
|
||||||
|
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
|
||||||
|
---
|
||||||
|
include/linux/netdevice.h | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
--- a/include/linux/netdevice.h
|
||||||
|
+++ b/include/linux/netdevice.h
|
||||||
|
@@ -159,8 +159,8 @@ static inline bool dev_xmit_complete(int
|
||||||
|
|
||||||
|
#if defined(CONFIG_HYPERV_NET)
|
||||||
|
# define LL_MAX_HEADER 128
|
||||||
|
-#elif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25)
|
||||||
|
-# if defined(CONFIG_MAC80211_MESH)
|
||||||
|
+#elif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25) || 1
|
||||||
|
+# if defined(CONFIG_MAC80211_MESH) || 1
|
||||||
|
# define LL_MAX_HEADER 128
|
||||||
|
# else
|
||||||
|
# define LL_MAX_HEADER 96
|
27
hack-6.12/660-fq_codel_defaults.patch
Normal file
27
hack-6.12/660-fq_codel_defaults.patch
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
From a6ccb238939b25851474a279b20367fd24a0e816 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Fri, 7 Jul 2017 17:21:53 +0200
|
||||||
|
Subject: hack: net: fq_codel: tune defaults for small devices
|
||||||
|
|
||||||
|
Assume that x86_64 devices always have a big memory and do not need this
|
||||||
|
optimization compared to devices with only 32 MB or 64 MB RAM.
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
net/sched/sch_fq_codel.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/net/sched/sch_fq_codel.c
|
||||||
|
+++ b/net/sched/sch_fq_codel.c
|
||||||
|
@@ -480,7 +480,11 @@ static int fq_codel_init(struct Qdisc *s
|
||||||
|
|
||||||
|
sch->limit = 10*1024;
|
||||||
|
q->flows_cnt = 1024;
|
||||||
|
+#ifdef CONFIG_X86_64
|
||||||
|
q->memory_limit = 32 << 20; /* 32 MBytes */
|
||||||
|
+#else
|
||||||
|
+ q->memory_limit = 4 << 20; /* 4 MBytes */
|
||||||
|
+#endif
|
||||||
|
q->drop_batch_size = 64;
|
||||||
|
q->quantum = psched_mtu(qdisc_dev(sch));
|
||||||
|
INIT_LIST_HEAD(&q->new_flows);
|
131
hack-6.12/700-swconfig_switch_drivers.patch
Normal file
131
hack-6.12/700-swconfig_switch_drivers.patch
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
From 36e516290611e613aa92996cb4339561452695b4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Fri, 7 Jul 2017 17:24:23 +0200
|
||||||
|
Subject: net: swconfig: adds openwrt switch layer
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
drivers/net/phy/Kconfig | 83 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
drivers/net/phy/Makefile | 15 +++++++++
|
||||||
|
include/uapi/linux/Kbuild | 1 +
|
||||||
|
3 files changed, 99 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/net/phy/Kconfig
|
||||||
|
+++ b/drivers/net/phy/Kconfig
|
||||||
|
@@ -77,6 +77,80 @@ config SFP
|
||||||
|
depends on HWMON || HWMON=n
|
||||||
|
select MDIO_I2C
|
||||||
|
|
||||||
|
+comment "Switch configuration API + drivers"
|
||||||
|
+
|
||||||
|
+config SWCONFIG
|
||||||
|
+ tristate "Switch configuration API"
|
||||||
|
+ help
|
||||||
|
+ Switch configuration API using netlink. This allows
|
||||||
|
+ you to configure the VLAN features of certain switches.
|
||||||
|
+
|
||||||
|
+config SWCONFIG_LEDS
|
||||||
|
+ bool "Switch LED trigger support"
|
||||||
|
+ depends on (SWCONFIG && LEDS_TRIGGERS)
|
||||||
|
+
|
||||||
|
+config ADM6996_PHY
|
||||||
|
+ tristate "Driver for ADM6996 switches"
|
||||||
|
+ select SWCONFIG
|
||||||
|
+ help
|
||||||
|
+ Currently supports the ADM6996FC and ADM6996M switches.
|
||||||
|
+ Support for FC is very limited.
|
||||||
|
+
|
||||||
|
+config AR8216_PHY
|
||||||
|
+ tristate "Driver for Atheros AR8216/8327 switches"
|
||||||
|
+ select SWCONFIG
|
||||||
|
+ select ETHERNET_PACKET_MANGLE
|
||||||
|
+
|
||||||
|
+config AR8216_PHY_LEDS
|
||||||
|
+ bool "Atheros AR8216 switch LED support"
|
||||||
|
+ depends on (AR8216_PHY && LEDS_CLASS)
|
||||||
|
+
|
||||||
|
+source "drivers/net/phy/b53/Kconfig"
|
||||||
|
+
|
||||||
|
+config IP17XX_PHY
|
||||||
|
+ tristate "Driver for IC+ IP17xx switches"
|
||||||
|
+ select SWCONFIG
|
||||||
|
+
|
||||||
|
+config PSB6970_PHY
|
||||||
|
+ tristate "Lantiq XWAY Tantos (PSB6970) Ethernet switch"
|
||||||
|
+ select SWCONFIG
|
||||||
|
+
|
||||||
|
+config RTL8306_PHY
|
||||||
|
+ tristate "Driver for Realtek RTL8306S switches"
|
||||||
|
+ select SWCONFIG
|
||||||
|
+
|
||||||
|
+config RTL8366_SMI
|
||||||
|
+ tristate "Driver for the RTL8366 SMI interface"
|
||||||
|
+ depends on GPIOLIB
|
||||||
|
+ help
|
||||||
|
+ This module implements the SMI interface protocol which is used
|
||||||
|
+ by some RTL8366 ethernet switch devices via the generic GPIO API.
|
||||||
|
+
|
||||||
|
+if RTL8366_SMI
|
||||||
|
+
|
||||||
|
+config RTL8366_SMI_DEBUG_FS
|
||||||
|
+ bool "RTL8366 SMI interface debugfs support"
|
||||||
|
+ depends on DEBUG_FS
|
||||||
|
+ default n
|
||||||
|
+
|
||||||
|
+config RTL8366S_PHY
|
||||||
|
+ tristate "Driver for the Realtek RTL8366S switch"
|
||||||
|
+ select SWCONFIG
|
||||||
|
+
|
||||||
|
+config RTL8366RB_PHY
|
||||||
|
+ tristate "Driver for the Realtek RTL8366RB switch"
|
||||||
|
+ select SWCONFIG
|
||||||
|
+
|
||||||
|
+config RTL8367_PHY
|
||||||
|
+ tristate "Driver for the Realtek RTL8367R/M switches"
|
||||||
|
+ select SWCONFIG
|
||||||
|
+
|
||||||
|
+config RTL8367B_PHY
|
||||||
|
+ tristate "Driver fot the Realtek RTL8367R-VB switch"
|
||||||
|
+ select SWCONFIG
|
||||||
|
+
|
||||||
|
+endif # RTL8366_SMI
|
||||||
|
+
|
||||||
|
comment "MII PHY device drivers"
|
||||||
|
|
||||||
|
config AIR_EN8811H_PHY
|
||||||
|
--- a/drivers/net/phy/Makefile
|
||||||
|
+++ b/drivers/net/phy/Makefile
|
||||||
|
@@ -27,6 +27,21 @@ libphy-$(CONFIG_OPEN_ALLIANCE_HELPERS) +
|
||||||
|
obj-$(CONFIG_PHYLINK) += phylink.o
|
||||||
|
obj-$(CONFIG_PHYLIB) += libphy.o
|
||||||
|
|
||||||
|
+obj-$(CONFIG_SWCONFIG) += swconfig.o
|
||||||
|
+obj-$(CONFIG_ADM6996_PHY) += adm6996.o
|
||||||
|
+obj-$(CONFIG_AR8216_PHY) += ar8xxx.o
|
||||||
|
+ar8xxx-y += ar8216.o
|
||||||
|
+ar8xxx-y += ar8327.o
|
||||||
|
+obj-$(CONFIG_SWCONFIG_B53) += b53/
|
||||||
|
+obj-$(CONFIG_IP17XX_PHY) += ip17xx.o
|
||||||
|
+obj-$(CONFIG_PSB6970_PHY) += psb6970.o
|
||||||
|
+obj-$(CONFIG_RTL8306_PHY) += rtl8306.o
|
||||||
|
+obj-$(CONFIG_RTL8366_SMI) += rtl8366_smi.o
|
||||||
|
+obj-$(CONFIG_RTL8366S_PHY) += rtl8366s.o
|
||||||
|
+obj-$(CONFIG_RTL8366RB_PHY) += rtl8366rb.o
|
||||||
|
+obj-$(CONFIG_RTL8367_PHY) += rtl8367.o
|
||||||
|
+obj-$(CONFIG_RTL8367B_PHY) += rtl8367b.o
|
||||||
|
+
|
||||||
|
obj-$(CONFIG_NETWORK_PHY_TIMESTAMPING) += mii_timestamper.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_SFP) += sfp.o
|
||||||
|
--- a/include/linux/platform_data/b53.h
|
||||||
|
+++ b/include/linux/platform_data/b53.h
|
||||||
|
@@ -29,6 +29,9 @@ struct b53_platform_data {
|
||||||
|
u32 chip_id;
|
||||||
|
u16 enabled_ports;
|
||||||
|
|
||||||
|
+ /* allow to specify an ethX alias */
|
||||||
|
+ const char *alias;
|
||||||
|
+
|
||||||
|
/* only used by MMAP'd driver */
|
||||||
|
unsigned big_endian:1;
|
||||||
|
void __iomem *regs;
|
@ -0,0 +1,74 @@
|
|||||||
|
From 82985725e071f2a5735052f18e109a32aeac3a0b Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Bauer <mail@david-bauer.net>
|
||||||
|
Date: Sun, 26 Jul 2020 02:38:31 +0200
|
||||||
|
Subject: [PATCH] net: usb: r8152: add LED configuration from OF
|
||||||
|
|
||||||
|
This adds the ability to configure the LED configuration register using
|
||||||
|
OF. This way, the correct value for board specific LED configuration can
|
||||||
|
be determined.
|
||||||
|
|
||||||
|
Signed-off-by: David Bauer <mail@david-bauer.net>
|
||||||
|
---
|
||||||
|
drivers/net/usb/r8152.c | 23 +++++++++++++++++++++++
|
||||||
|
1 file changed, 23 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/net/usb/r8152.c
|
||||||
|
+++ b/drivers/net/usb/r8152.c
|
||||||
|
@@ -12,6 +12,7 @@
|
||||||
|
#include <linux/ethtool.h>
|
||||||
|
#include <linux/phy.h>
|
||||||
|
#include <linux/usb.h>
|
||||||
|
+#include <linux/of.h>
|
||||||
|
#include <linux/crc32.h>
|
||||||
|
#include <linux/if_vlan.h>
|
||||||
|
#include <linux/uaccess.h>
|
||||||
|
@@ -7046,6 +7047,22 @@ static void rtl_tally_reset(struct r8152
|
||||||
|
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RSTTALLY, ocp_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int r8152_led_configuration(struct r8152 *tp)
|
||||||
|
+{
|
||||||
|
+ u32 led_data;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ ret = of_property_read_u32(tp->udev->dev.of_node, "realtek,led-data",
|
||||||
|
+ &led_data);
|
||||||
|
+
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_LEDSEL, led_data);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void r8152b_init(struct r8152 *tp)
|
||||||
|
{
|
||||||
|
u32 ocp_data;
|
||||||
|
@@ -7087,6 +7104,8 @@ static void r8152b_init(struct r8152 *tp
|
||||||
|
ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL);
|
||||||
|
ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN);
|
||||||
|
ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data);
|
||||||
|
+
|
||||||
|
+ r8152_led_configuration(tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void r8153_init(struct r8152 *tp)
|
||||||
|
@@ -7227,6 +7246,8 @@ static void r8153_init(struct r8152 *tp)
|
||||||
|
tp->coalesce = COALESCE_SLOW;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ r8152_led_configuration(tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void r8153b_init(struct r8152 *tp)
|
||||||
|
@@ -7309,6 +7330,8 @@ static void r8153b_init(struct r8152 *tp
|
||||||
|
rtl_tally_reset(tp);
|
||||||
|
|
||||||
|
tp->coalesce = 15000; /* 15 us */
|
||||||
|
+
|
||||||
|
+ r8152_led_configuration(tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void r8153c_init(struct r8152 *tp)
|
@ -0,0 +1,54 @@
|
|||||||
|
From 3ee05f4aa64fc86af3be5bc176ba5808de9260a7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Bauer <mail@david-bauer.net>
|
||||||
|
Date: Sun, 26 Jul 2020 15:30:33 +0200
|
||||||
|
Subject: [PATCH] dt-bindings: net: add RTL8152 binding documentation
|
||||||
|
|
||||||
|
Add binding documentation for the Realtek RTL8152 / RTL8153 USB ethernet
|
||||||
|
adapters.
|
||||||
|
|
||||||
|
Signed-off-by: David Bauer <mail@david-bauer.net>
|
||||||
|
---
|
||||||
|
.../bindings/net/realtek,rtl8152.yaml | 36 +++++++++++++++++++
|
||||||
|
1 file changed, 36 insertions(+)
|
||||||
|
create mode 100644 Documentation/devicetree/bindings/net/realtek,rtl8152.yaml
|
||||||
|
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/Documentation/devicetree/bindings/net/realtek,rtl8152.yaml
|
||||||
|
@@ -0,0 +1,36 @@
|
||||||
|
+# SPDX-License-Identifier: GPL-2.0
|
||||||
|
+%YAML 1.2
|
||||||
|
+---
|
||||||
|
+$id: http://devicetree.org/schemas/net/realtek,rtl8152.yaml#
|
||||||
|
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
+
|
||||||
|
+title: Realtek RTL8152/RTL8153 series USB ethernet
|
||||||
|
+
|
||||||
|
+maintainers:
|
||||||
|
+ - David Bauer <mail@david-bauer.net>
|
||||||
|
+
|
||||||
|
+properties:
|
||||||
|
+ compatible:
|
||||||
|
+ oneOf:
|
||||||
|
+ - items:
|
||||||
|
+ - enum:
|
||||||
|
+ - realtek,rtl8152
|
||||||
|
+ - realtek,rtl8153
|
||||||
|
+
|
||||||
|
+ reg:
|
||||||
|
+ description: The device number on the USB bus
|
||||||
|
+
|
||||||
|
+ realtek,led-data:
|
||||||
|
+ description: Value to be written to the LED configuration register.
|
||||||
|
+
|
||||||
|
+required:
|
||||||
|
+ - compatible
|
||||||
|
+ - reg
|
||||||
|
+
|
||||||
|
+examples:
|
||||||
|
+ - |
|
||||||
|
+ usb-eth@2 {
|
||||||
|
+ compatible = "realtek,rtl8153";
|
||||||
|
+ reg = <2>;
|
||||||
|
+ realtek,led-data = <0x87>;
|
||||||
|
+ };
|
||||||
|
\ No newline at end of file
|
98
hack-6.12/773-bgmac-add-srab-switch.patch
Normal file
98
hack-6.12/773-bgmac-add-srab-switch.patch
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
From 3cb240533ab787899dc7f17aa7d6c5b4810e2e58 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
Date: Fri, 7 Jul 2017 17:26:01 +0200
|
||||||
|
Subject: bcm53xx: bgmac: use srab switch driver
|
||||||
|
|
||||||
|
use the srab switch driver on these SoCs.
|
||||||
|
|
||||||
|
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
---
|
||||||
|
drivers/net/ethernet/broadcom/bgmac-bcma.c | 1 +
|
||||||
|
drivers/net/ethernet/broadcom/bgmac.c | 24 ++++++++++++++++++++++++
|
||||||
|
drivers/net/ethernet/broadcom/bgmac.h | 4 ++++
|
||||||
|
3 files changed, 29 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/net/ethernet/broadcom/bgmac-bcma.c
|
||||||
|
+++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c
|
||||||
|
@@ -280,6 +280,7 @@ static int bgmac_probe(struct bcma_devic
|
||||||
|
bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
|
||||||
|
bgmac->feature_flags |= BGMAC_FEAT_NO_RESET;
|
||||||
|
bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500;
|
||||||
|
+ bgmac->feature_flags |= BGMAC_FEAT_SRAB;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
|
||||||
|
--- a/drivers/net/ethernet/broadcom/bgmac.c
|
||||||
|
+++ b/drivers/net/ethernet/broadcom/bgmac.c
|
||||||
|
@@ -12,6 +12,7 @@
|
||||||
|
#include <linux/bcma/bcma.h>
|
||||||
|
#include <linux/etherdevice.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
+#include <linux/platform_data/b53.h>
|
||||||
|
#include <linux/bcm47xx_nvram.h>
|
||||||
|
#include <linux/phy.h>
|
||||||
|
#include <linux/phy_fixed.h>
|
||||||
|
@@ -1408,6 +1409,17 @@ static const struct ethtool_ops bgmac_et
|
||||||
|
.set_link_ksettings = phy_ethtool_set_link_ksettings,
|
||||||
|
};
|
||||||
|
|
||||||
|
+static struct b53_platform_data bgmac_b53_pdata = {
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct platform_device bgmac_b53_dev = {
|
||||||
|
+ .name = "b53-srab-switch",
|
||||||
|
+ .id = -1,
|
||||||
|
+ .dev = {
|
||||||
|
+ .platform_data = &bgmac_b53_pdata,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
/**************************************************
|
||||||
|
* MII
|
||||||
|
**************************************************/
|
||||||
|
@@ -1546,6 +1558,14 @@ int bgmac_enet_probe(struct bgmac *bgmac
|
||||||
|
|
||||||
|
bgmac->in_init = false;
|
||||||
|
|
||||||
|
+ if ((bgmac->feature_flags & BGMAC_FEAT_SRAB) && !bgmac_b53_pdata.regs) {
|
||||||
|
+ bgmac_b53_pdata.regs = ioremap(0x18007000, 0x1000);
|
||||||
|
+
|
||||||
|
+ err = platform_device_register(&bgmac_b53_dev);
|
||||||
|
+ if (!err)
|
||||||
|
+ bgmac->b53_device = &bgmac_b53_dev;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
err = register_netdev(bgmac->net_dev);
|
||||||
|
if (err) {
|
||||||
|
dev_err(bgmac->dev, "Cannot register net device\n");
|
||||||
|
@@ -1568,6 +1588,10 @@ EXPORT_SYMBOL_GPL(bgmac_enet_probe);
|
||||||
|
|
||||||
|
void bgmac_enet_remove(struct bgmac *bgmac)
|
||||||
|
{
|
||||||
|
+ if (bgmac->b53_device)
|
||||||
|
+ platform_device_unregister(&bgmac_b53_dev);
|
||||||
|
+ bgmac->b53_device = NULL;
|
||||||
|
+
|
||||||
|
unregister_netdev(bgmac->net_dev);
|
||||||
|
phy_disconnect(bgmac->net_dev->phydev);
|
||||||
|
netif_napi_del(&bgmac->napi);
|
||||||
|
--- a/drivers/net/ethernet/broadcom/bgmac.h
|
||||||
|
+++ b/drivers/net/ethernet/broadcom/bgmac.h
|
||||||
|
@@ -388,6 +388,7 @@
|
||||||
|
#define BGMAC_FEAT_CC4_IF_SW_TYPE_RGMII BIT(18)
|
||||||
|
#define BGMAC_FEAT_CC7_IF_TYPE_RGMII BIT(19)
|
||||||
|
#define BGMAC_FEAT_IDM_MASK BIT(20)
|
||||||
|
+#define BGMAC_FEAT_SRAB BIT(21)
|
||||||
|
|
||||||
|
struct bgmac_slot_info {
|
||||||
|
union {
|
||||||
|
@@ -495,6 +496,9 @@ struct bgmac {
|
||||||
|
void (*cmn_maskset32)(struct bgmac *bgmac, u16 offset, u32 mask,
|
||||||
|
u32 set);
|
||||||
|
int (*phy_connect)(struct bgmac *bgmac);
|
||||||
|
+
|
||||||
|
+ /* platform device for associated switch */
|
||||||
|
+ struct platform_device *b53_device;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bgmac *bgmac_alloc(struct device *dev);
|
33
hack-6.12/780-usb-net-MeigLink_modem_support.patch
Normal file
33
hack-6.12/780-usb-net-MeigLink_modem_support.patch
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
--- a/drivers/net/usb/qmi_wwan.c
|
||||||
|
+++ b/drivers/net/usb/qmi_wwan.c
|
||||||
|
@@ -1083,6 +1083,7 @@ static const struct usb_device_id produc
|
||||||
|
{QMI_MATCH_FF_FF_FF(0x2c7c, 0x0620)}, /* Quectel EM160R-GL */
|
||||||
|
{QMI_MATCH_FF_FF_FF(0x2c7c, 0x0800)}, /* Quectel RM500Q-GL */
|
||||||
|
{QMI_MATCH_FF_FF_FF(0x2c7c, 0x0801)}, /* Quectel RM520N */
|
||||||
|
+ {QMI_MATCH_FF_FF_FF(0x05c6, 0xf601)}, /* MeigLink SLM750 */
|
||||||
|
|
||||||
|
/* 3. Combined interface devices matching on interface number */
|
||||||
|
{QMI_FIXED_INTF(0x0408, 0xea42, 4)}, /* Yota / Megafon M100-1 */
|
||||||
|
--- a/drivers/usb/serial/option.c
|
||||||
|
+++ b/drivers/usb/serial/option.c
|
||||||
|
@@ -247,6 +247,8 @@ static void option_instat_callback(struc
|
||||||
|
#define UBLOX_PRODUCT_R410M 0x90b2
|
||||||
|
/* These Yuga products use Qualcomm's vendor ID */
|
||||||
|
#define YUGA_PRODUCT_CLM920_NC5 0x9625
|
||||||
|
+/* These MeigLink products use Qualcomm's vendor ID */
|
||||||
|
+#define MEIGLINK_PRODUCT_SLM750 0xf601
|
||||||
|
|
||||||
|
#define QUECTEL_VENDOR_ID 0x2c7c
|
||||||
|
/* These Quectel products use Quectel's vendor ID */
|
||||||
|
@@ -1200,6 +1202,11 @@ static const struct usb_device_id option
|
||||||
|
.driver_info = ZLP },
|
||||||
|
{ USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96),
|
||||||
|
.driver_info = RSVD(4) },
|
||||||
|
+ /* Meiglink products using Qualcomm vendor ID */
|
||||||
|
+ // Works OK. In case of some issues check macros that are used by Quectel Products
|
||||||
|
+ { USB_DEVICE_AND_INTERFACE_INFO(QUALCOMM_VENDOR_ID, MEIGLINK_PRODUCT_SLM750, 0xff, 0xff, 0xff),
|
||||||
|
+ .driver_info = NUMEP2 },
|
||||||
|
+ { USB_DEVICE_AND_INTERFACE_INFO(QUALCOMM_VENDOR_ID, MEIGLINK_PRODUCT_SLM750, 0xff, 0, 0) },
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0xff, 0xff),
|
||||||
|
.driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 },
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0, 0) },
|
148
hack-6.12/800-GPIO-add-named-gpio-exports.patch
Normal file
148
hack-6.12/800-GPIO-add-named-gpio-exports.patch
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
From cc809a441d8f2924f785eb863dfa6aef47a25b0b Mon Sep 17 00:00:00 2001
|
||||||
|
From: John Crispin <blogic@openwrt.org>
|
||||||
|
Date: Tue, 12 Aug 2014 20:49:27 +0200
|
||||||
|
Subject: [PATCH 30/36] GPIO: add named gpio exports
|
||||||
|
|
||||||
|
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||||
|
--- a/drivers/gpio/gpiolib-of.c
|
||||||
|
+++ b/drivers/gpio/gpiolib-of.c
|
||||||
|
@@ -21,6 +21,8 @@
|
||||||
|
|
||||||
|
#include <linux/gpio/consumer.h>
|
||||||
|
#include <linux/gpio/machine.h>
|
||||||
|
+#include <linux/init.h>
|
||||||
|
+#include <linux/platform_device.h>
|
||||||
|
|
||||||
|
#include "gpiolib.h"
|
||||||
|
#include "gpiolib-of.h"
|
||||||
|
@@ -1187,3 +1189,72 @@ void of_gpiochip_remove(struct gpio_chip
|
||||||
|
{
|
||||||
|
of_node_put(dev_of_node(&chip->gpiodev->dev));
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_GPIO_SYSFS
|
||||||
|
+
|
||||||
|
+static struct of_device_id gpio_export_ids[] = {
|
||||||
|
+ { .compatible = "gpio-export" },
|
||||||
|
+ { /* sentinel */ }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int of_gpio_export_probe(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ struct device_node *np = pdev->dev.of_node;
|
||||||
|
+ struct device_node *cnp;
|
||||||
|
+ u32 val;
|
||||||
|
+ int nb = 0;
|
||||||
|
+
|
||||||
|
+ for_each_child_of_node(np, cnp) {
|
||||||
|
+ const char *name = NULL;
|
||||||
|
+ int gpio;
|
||||||
|
+ bool dmc;
|
||||||
|
+ int max_gpio = 1;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ of_property_read_string(cnp, "gpio-export,name", &name);
|
||||||
|
+
|
||||||
|
+ if (!name)
|
||||||
|
+ // max_gpio = of_gpio_count(cnp);
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < max_gpio; i++) {
|
||||||
|
+ unsigned flags = 0;
|
||||||
|
+ enum of_gpio_flags of_flags;
|
||||||
|
+
|
||||||
|
+ gpio = of_get_named_gpio(cnp, i, &of_flags);
|
||||||
|
+ if (!gpio_is_valid(gpio))
|
||||||
|
+ return gpio;
|
||||||
|
+
|
||||||
|
+ if (of_flags == OF_GPIO_ACTIVE_LOW)
|
||||||
|
+ flags |= GPIOF_ACTIVE_LOW;
|
||||||
|
+
|
||||||
|
+ if (!of_property_read_u32(cnp, "gpio-export,output", &val))
|
||||||
|
+ flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
|
||||||
|
+ else
|
||||||
|
+ flags |= GPIOF_IN;
|
||||||
|
+
|
||||||
|
+ if (devm_gpio_request_one(&pdev->dev, gpio, flags, name ? name : of_node_full_name(np)))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ dmc = of_property_read_bool(cnp, "gpio-export,direction_may_change");
|
||||||
|
+ gpio_export_with_name(gpio, dmc, name);
|
||||||
|
+ nb++;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ dev_info(&pdev->dev, "%d gpio(s) exported\n", nb);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct platform_driver gpio_export_driver = {
|
||||||
|
+ .driver = {
|
||||||
|
+ .name = "gpio-export",
|
||||||
|
+ .owner = THIS_MODULE,
|
||||||
|
+ .of_match_table = of_match_ptr(gpio_export_ids),
|
||||||
|
+ },
|
||||||
|
+ .probe = of_gpio_export_probe,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+module_platform_driver(gpio_export_driver);
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
\ No newline at end of file
|
||||||
|
--- a/include/linux/gpio/consumer.h
|
||||||
|
+++ b/include/linux/gpio/consumer.h
|
||||||
|
@@ -628,6 +628,7 @@ static inline int devm_acpi_dev_add_driv
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS)
|
||||||
|
|
||||||
|
+int _gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
|
||||||
|
int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
|
||||||
|
int gpiod_export_link(struct device *dev, const char *name,
|
||||||
|
struct gpio_desc *desc);
|
||||||
|
@@ -637,6 +638,13 @@ void gpiod_unexport(struct gpio_desc *de
|
||||||
|
|
||||||
|
#include <asm/errno.h>
|
||||||
|
|
||||||
|
+static inline int _gpiod_export(struct gpio_desc *desc,
|
||||||
|
+ bool direction_may_change,
|
||||||
|
+ const char *name)
|
||||||
|
+{
|
||||||
|
+ return -ENOSYS;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static inline int gpiod_export(struct gpio_desc *desc,
|
||||||
|
bool direction_may_change)
|
||||||
|
{
|
||||||
|
--- a/drivers/gpio/gpiolib-sysfs.c
|
||||||
|
+++ b/drivers/gpio/gpiolib-sysfs.c
|
||||||
|
@@ -571,7 +571,7 @@ static struct class gpio_class = {
|
||||||
|
* Returns:
|
||||||
|
* 0 on success, or negative errno on failure.
|
||||||
|
*/
|
||||||
|
-int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
|
||||||
|
+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name)
|
||||||
|
{
|
||||||
|
const char *ioname = NULL;
|
||||||
|
struct gpio_device *gdev;
|
||||||
|
@@ -629,6 +629,8 @@ int gpiod_export(struct gpio_desc *desc,
|
||||||
|
offset = gpio_chip_hwgpio(desc);
|
||||||
|
if (guard.gc->names && guard.gc->names[offset])
|
||||||
|
ioname = guard.gc->names[offset];
|
||||||
|
+ if (name)
|
||||||
|
+ ioname = name;
|
||||||
|
|
||||||
|
dev = device_create_with_groups(&gpio_class, &gdev->dev,
|
||||||
|
MKDEV(0, 0), data, gpio_groups,
|
||||||
|
@@ -650,6 +652,12 @@ err_unlock:
|
||||||
|
gpiod_dbg(desc, "%s: status %d\n", __func__, status);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
+EXPORT_SYMBOL_GPL(__gpiod_export);
|
||||||
|
+
|
||||||
|
+int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
|
||||||
|
+{
|
||||||
|
+ return __gpiod_export(desc, direction_may_change, NULL);
|
||||||
|
+}
|
||||||
|
EXPORT_SYMBOL_GPL(gpiod_export);
|
||||||
|
|
||||||
|
static int match_export(struct device *dev, const void *desc)
|
397
hack-6.12/902-debloat_proc.patch
Normal file
397
hack-6.12/902-debloat_proc.patch
Normal file
@ -0,0 +1,397 @@
|
|||||||
|
From 9e3f1d0805b2d919904dd9a4ff0d956314cc3cba Mon Sep 17 00:00:00 2001
|
||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Sat, 8 Jul 2017 08:20:09 +0200
|
||||||
|
Subject: debloat: procfs
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
fs/locks.c | 2 ++
|
||||||
|
fs/proc/Kconfig | 5 +++++
|
||||||
|
fs/proc/consoles.c | 3 +++
|
||||||
|
fs/proc/proc_tty.c | 11 ++++++++++-
|
||||||
|
include/net/snmp.h | 18 +++++++++++++++++-
|
||||||
|
ipc/msg.c | 3 +++
|
||||||
|
ipc/sem.c | 2 ++
|
||||||
|
ipc/shm.c | 2 ++
|
||||||
|
ipc/util.c | 3 +++
|
||||||
|
kernel/exec_domain.c | 2 ++
|
||||||
|
kernel/irq/proc.c | 9 +++++++++
|
||||||
|
kernel/time/timer_list.c | 2 ++
|
||||||
|
mm/vmalloc.c | 2 ++
|
||||||
|
mm/vmstat.c | 8 +++++---
|
||||||
|
net/8021q/vlanproc.c | 6 ++++++
|
||||||
|
net/core/net-procfs.c | 18 ++++++++++++------
|
||||||
|
net/core/sock.c | 2 ++
|
||||||
|
net/ipv4/fib_trie.c | 18 ++++++++++++------
|
||||||
|
net/ipv4/proc.c | 3 +++
|
||||||
|
net/ipv4/route.c | 3 +++
|
||||||
|
20 files changed, 105 insertions(+), 17 deletions(-)
|
||||||
|
|
||||||
|
--- a/fs/locks.c
|
||||||
|
+++ b/fs/locks.c
|
||||||
|
@@ -2971,6 +2971,8 @@ static const struct seq_operations locks
|
||||||
|
|
||||||
|
static int __init proc_locks_init(void)
|
||||||
|
{
|
||||||
|
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||||
|
+ return 0;
|
||||||
|
proc_create_seq_private("locks", 0, NULL, &locks_seq_operations,
|
||||||
|
sizeof(struct locks_iterator), NULL);
|
||||||
|
return 0;
|
||||||
|
--- a/fs/proc/Kconfig
|
||||||
|
+++ b/fs/proc/Kconfig
|
||||||
|
@@ -101,6 +101,11 @@ config PROC_CHILDREN
|
||||||
|
Say Y if you are running any user-space software which takes benefit from
|
||||||
|
this interface. For example, rkt is such a piece of software.
|
||||||
|
|
||||||
|
+config PROC_STRIPPED
|
||||||
|
+ default n
|
||||||
|
+ depends on EXPERT
|
||||||
|
+ bool "Strip non-essential /proc functionality to reduce code size"
|
||||||
|
+
|
||||||
|
config PROC_PID_ARCH_STATUS
|
||||||
|
def_bool n
|
||||||
|
depends on PROC_FS
|
||||||
|
--- a/fs/proc/consoles.c
|
||||||
|
+++ b/fs/proc/consoles.c
|
||||||
|
@@ -110,6 +110,9 @@ static const struct seq_operations conso
|
||||||
|
|
||||||
|
static int __init proc_consoles_init(void)
|
||||||
|
{
|
||||||
|
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
proc_create_seq("consoles", 0, NULL, &consoles_op);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
--- a/fs/proc/proc_tty.c
|
||||||
|
+++ b/fs/proc/proc_tty.c
|
||||||
|
@@ -131,7 +131,10 @@ static const struct seq_operations tty_d
|
||||||
|
void proc_tty_register_driver(struct tty_driver *driver)
|
||||||
|
{
|
||||||
|
struct proc_dir_entry *ent;
|
||||||
|
-
|
||||||
|
+
|
||||||
|
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
if (!driver->driver_name || driver->proc_entry ||
|
||||||
|
!driver->ops->proc_show)
|
||||||
|
return;
|
||||||
|
@@ -148,6 +151,9 @@ void proc_tty_unregister_driver(struct t
|
||||||
|
{
|
||||||
|
struct proc_dir_entry *ent;
|
||||||
|
|
||||||
|
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
ent = driver->proc_entry;
|
||||||
|
if (!ent)
|
||||||
|
return;
|
||||||
|
@@ -162,6 +168,9 @@ void proc_tty_unregister_driver(struct t
|
||||||
|
*/
|
||||||
|
void __init proc_tty_init(void)
|
||||||
|
{
|
||||||
|
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
if (!proc_mkdir("tty", NULL))
|
||||||
|
return;
|
||||||
|
proc_mkdir("tty/ldisc", NULL); /* Preserved: it's userspace visible */
|
||||||
|
--- a/include/net/snmp.h
|
||||||
|
+++ b/include/net/snmp.h
|
||||||
|
@@ -124,6 +124,21 @@ struct linux_tls_mib {
|
||||||
|
#define DECLARE_SNMP_STAT(type, name) \
|
||||||
|
extern __typeof__(type) __percpu *name
|
||||||
|
|
||||||
|
+#ifdef CONFIG_PROC_STRIPPED
|
||||||
|
+#define __SNMP_STATS_DUMMY(mib) \
|
||||||
|
+ do { (void) mib->mibs[0]; } while(0)
|
||||||
|
+
|
||||||
|
+#define __SNMP_INC_STATS(mib, field) __SNMP_STATS_DUMMY(mib)
|
||||||
|
+#define SNMP_INC_STATS_ATOMIC_LONG(mib, field) __SNMP_STATS_DUMMY(mib)
|
||||||
|
+#define SNMP_INC_STATS(mib, field) __SNMP_STATS_DUMMY(mib)
|
||||||
|
+#define SNMP_DEC_STATS(mib, field) __SNMP_STATS_DUMMY(mib)
|
||||||
|
+#define __SNMP_ADD_STATS(mib, field, addend) __SNMP_STATS_DUMMY(mib)
|
||||||
|
+#define SNMP_ADD_STATS(mib, field, addend) __SNMP_STATS_DUMMY(mib)
|
||||||
|
+#define SNMP_UPD_PO_STATS(mib, basefield, addend) __SNMP_STATS_DUMMY(mib)
|
||||||
|
+#define __SNMP_UPD_PO_STATS(mib, basefield, addend) __SNMP_STATS_DUMMY(mib)
|
||||||
|
+
|
||||||
|
+#else
|
||||||
|
+
|
||||||
|
#define __SNMP_INC_STATS(mib, field) \
|
||||||
|
__this_cpu_inc(mib->mibs[field])
|
||||||
|
|
||||||
|
@@ -154,8 +169,9 @@ struct linux_tls_mib {
|
||||||
|
__this_cpu_add(ptr[basefield##OCTETS], addend); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
-#if BITS_PER_LONG==32
|
||||||
|
+#if (BITS_PER_LONG==32) && !defined(CONFIG_PROC_STRIPPED)
|
||||||
|
|
||||||
|
#define __SNMP_ADD_STATS64(mib, field, addend) \
|
||||||
|
do { \
|
||||||
|
--- a/ipc/msg.c
|
||||||
|
+++ b/ipc/msg.c
|
||||||
|
@@ -1370,6 +1370,9 @@ void __init msg_init(void)
|
||||||
|
{
|
||||||
|
msg_init_ns(&init_ipc_ns);
|
||||||
|
|
||||||
|
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
ipc_init_proc_interface("sysvipc/msg",
|
||||||
|
" key msqid perms cbytes qnum lspid lrpid uid gid cuid cgid stime rtime ctime\n",
|
||||||
|
IPC_MSG_IDS, sysvipc_msg_proc_show);
|
||||||
|
--- a/ipc/sem.c
|
||||||
|
+++ b/ipc/sem.c
|
||||||
|
@@ -268,6 +268,8 @@ void sem_exit_ns(struct ipc_namespace *n
|
||||||
|
void __init sem_init(void)
|
||||||
|
{
|
||||||
|
sem_init_ns(&init_ipc_ns);
|
||||||
|
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||||
|
+ return;
|
||||||
|
ipc_init_proc_interface("sysvipc/sem",
|
||||||
|
" key semid perms nsems uid gid cuid cgid otime ctime\n",
|
||||||
|
IPC_SEM_IDS, sysvipc_sem_proc_show);
|
||||||
|
--- a/ipc/shm.c
|
||||||
|
+++ b/ipc/shm.c
|
||||||
|
@@ -155,6 +155,8 @@ pure_initcall(ipc_ns_init);
|
||||||
|
|
||||||
|
void __init shm_init(void)
|
||||||
|
{
|
||||||
|
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||||
|
+ return;
|
||||||
|
ipc_init_proc_interface("sysvipc/shm",
|
||||||
|
#if BITS_PER_LONG <= 32
|
||||||
|
" key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime rss swap\n",
|
||||||
|
--- a/ipc/util.c
|
||||||
|
+++ b/ipc/util.c
|
||||||
|
@@ -141,6 +141,9 @@ void __init ipc_init_proc_interface(cons
|
||||||
|
struct proc_dir_entry *pde;
|
||||||
|
struct ipc_proc_iface *iface;
|
||||||
|
|
||||||
|
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
iface = kmalloc(sizeof(*iface), GFP_KERNEL);
|
||||||
|
if (!iface)
|
||||||
|
return;
|
||||||
|
--- a/kernel/exec_domain.c
|
||||||
|
+++ b/kernel/exec_domain.c
|
||||||
|
@@ -29,6 +29,8 @@ static int execdomains_proc_show(struct
|
||||||
|
|
||||||
|
static int __init proc_execdomains_init(void)
|
||||||
|
{
|
||||||
|
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||||
|
+ return 0;
|
||||||
|
proc_create_single("execdomains", 0, NULL, execdomains_proc_show);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
--- a/kernel/irq/proc.c
|
||||||
|
+++ b/kernel/irq/proc.c
|
||||||
|
@@ -339,6 +339,9 @@ void register_irq_proc(unsigned int irq,
|
||||||
|
void __maybe_unused *irqp = (void *)(unsigned long) irq;
|
||||||
|
char name [MAX_NAMELEN];
|
||||||
|
|
||||||
|
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
if (!root_irq_dir || (desc->irq_data.chip == &no_irq_chip))
|
||||||
|
return;
|
||||||
|
|
||||||
|
@@ -397,6 +400,9 @@ void unregister_irq_proc(unsigned int ir
|
||||||
|
{
|
||||||
|
char name [MAX_NAMELEN];
|
||||||
|
|
||||||
|
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
if (!root_irq_dir || !desc->dir)
|
||||||
|
return;
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
@@ -435,6 +441,9 @@ void init_irq_proc(void)
|
||||||
|
unsigned int irq;
|
||||||
|
struct irq_desc *desc;
|
||||||
|
|
||||||
|
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
/* create /proc/irq */
|
||||||
|
root_irq_dir = proc_mkdir("irq", NULL);
|
||||||
|
if (!root_irq_dir)
|
||||||
|
--- a/kernel/time/timer_list.c
|
||||||
|
+++ b/kernel/time/timer_list.c
|
||||||
|
@@ -354,6 +354,8 @@ static int __init init_timer_list_procfs
|
||||||
|
{
|
||||||
|
struct proc_dir_entry *pe;
|
||||||
|
|
||||||
|
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||||
|
+ return 0;
|
||||||
|
pe = proc_create_seq_private("timer_list", 0400, NULL, &timer_list_sops,
|
||||||
|
sizeof(struct timer_list_iter), NULL);
|
||||||
|
if (!pe)
|
||||||
|
--- a/mm/vmstat.c
|
||||||
|
+++ b/mm/vmstat.c
|
||||||
|
@@ -2192,10 +2192,12 @@ void __init init_mm_internals(void)
|
||||||
|
start_shepherd_timer();
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_PROC_FS
|
||||||
|
- proc_create_seq("buddyinfo", 0444, NULL, &fragmentation_op);
|
||||||
|
- proc_create_seq("pagetypeinfo", 0400, NULL, &pagetypeinfo_op);
|
||||||
|
+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) {
|
||||||
|
+ proc_create_seq("buddyinfo", 0444, NULL, &fragmentation_op);
|
||||||
|
+ proc_create_seq("pagetypeinfo", 0400, NULL, &pagetypeinfo_op);
|
||||||
|
+ proc_create_seq("zoneinfo", 0444, NULL, &zoneinfo_op);
|
||||||
|
+ }
|
||||||
|
proc_create_seq("vmstat", 0444, NULL, &vmstat_op);
|
||||||
|
- proc_create_seq("zoneinfo", 0444, NULL, &zoneinfo_op);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
--- a/net/8021q/vlanproc.c
|
||||||
|
+++ b/net/8021q/vlanproc.c
|
||||||
|
@@ -93,6 +93,9 @@ void vlan_proc_cleanup(struct net *net)
|
||||||
|
{
|
||||||
|
struct vlan_net *vn = net_generic(net, vlan_net_id);
|
||||||
|
|
||||||
|
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
if (vn->proc_vlan_conf)
|
||||||
|
remove_proc_entry(name_conf, vn->proc_vlan_dir);
|
||||||
|
|
||||||
|
@@ -112,6 +115,9 @@ int __net_init vlan_proc_init(struct net
|
||||||
|
{
|
||||||
|
struct vlan_net *vn = net_generic(net, vlan_net_id);
|
||||||
|
|
||||||
|
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
vn->proc_vlan_dir = proc_net_mkdir(net, name_root, net->proc_net);
|
||||||
|
if (!vn->proc_vlan_dir)
|
||||||
|
goto err;
|
||||||
|
--- a/net/core/net-procfs.c
|
||||||
|
+++ b/net/core/net-procfs.c
|
||||||
|
@@ -295,10 +295,12 @@ static int __net_init dev_proc_net_init(
|
||||||
|
if (!proc_create_net("dev", 0444, net->proc_net, &dev_seq_ops,
|
||||||
|
sizeof(struct seq_net_private)))
|
||||||
|
goto out;
|
||||||
|
- if (!proc_create_seq("softnet_stat", 0444, net->proc_net,
|
||||||
|
+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) &&
|
||||||
|
+ !proc_create_seq("softnet_stat", 0444, net->proc_net,
|
||||||
|
&softnet_seq_ops))
|
||||||
|
goto out_dev;
|
||||||
|
- if (!proc_create_net("ptype", 0444, net->proc_net, &ptype_seq_ops,
|
||||||
|
+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) &&
|
||||||
|
+ !proc_create_net("ptype", 0444, net->proc_net, &ptype_seq_ops,
|
||||||
|
sizeof(struct seq_net_private)))
|
||||||
|
goto out_softnet;
|
||||||
|
|
||||||
|
@@ -308,9 +310,11 @@ static int __net_init dev_proc_net_init(
|
||||||
|
out:
|
||||||
|
return rc;
|
||||||
|
out_ptype:
|
||||||
|
- remove_proc_entry("ptype", net->proc_net);
|
||||||
|
+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||||
|
+ remove_proc_entry("ptype", net->proc_net);
|
||||||
|
out_softnet:
|
||||||
|
- remove_proc_entry("softnet_stat", net->proc_net);
|
||||||
|
+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||||
|
+ remove_proc_entry("softnet_stat", net->proc_net);
|
||||||
|
out_dev:
|
||||||
|
remove_proc_entry("dev", net->proc_net);
|
||||||
|
goto out;
|
||||||
|
@@ -320,8 +324,10 @@ static void __net_exit dev_proc_net_exit
|
||||||
|
{
|
||||||
|
wext_proc_exit(net);
|
||||||
|
|
||||||
|
- remove_proc_entry("ptype", net->proc_net);
|
||||||
|
- remove_proc_entry("softnet_stat", net->proc_net);
|
||||||
|
+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) {
|
||||||
|
+ remove_proc_entry("ptype", net->proc_net);
|
||||||
|
+ remove_proc_entry("softnet_stat", net->proc_net);
|
||||||
|
+ }
|
||||||
|
remove_proc_entry("dev", net->proc_net);
|
||||||
|
}
|
||||||
|
|
||||||
|
--- a/net/core/sock.c
|
||||||
|
+++ b/net/core/sock.c
|
||||||
|
@@ -4223,6 +4223,8 @@ static __net_initdata struct pernet_oper
|
||||||
|
|
||||||
|
static int __init proto_init(void)
|
||||||
|
{
|
||||||
|
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||||
|
+ return 0;
|
||||||
|
return register_pernet_subsys(&proto_net_ops);
|
||||||
|
}
|
||||||
|
|
||||||
|
--- a/net/ipv4/fib_trie.c
|
||||||
|
+++ b/net/ipv4/fib_trie.c
|
||||||
|
@@ -3037,11 +3037,13 @@ static const struct seq_operations fib_r
|
||||||
|
|
||||||
|
int __net_init fib_proc_init(struct net *net)
|
||||||
|
{
|
||||||
|
- if (!proc_create_net("fib_trie", 0444, net->proc_net, &fib_trie_seq_ops,
|
||||||
|
+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) &&
|
||||||
|
+ !proc_create_net("fib_trie", 0444, net->proc_net, &fib_trie_seq_ops,
|
||||||
|
sizeof(struct fib_trie_iter)))
|
||||||
|
goto out1;
|
||||||
|
|
||||||
|
- if (!proc_create_net_single("fib_triestat", 0444, net->proc_net,
|
||||||
|
+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) &&
|
||||||
|
+ !proc_create_net_single("fib_triestat", 0444, net->proc_net,
|
||||||
|
fib_triestat_seq_show, NULL))
|
||||||
|
goto out2;
|
||||||
|
|
||||||
|
@@ -3052,17 +3054,21 @@ int __net_init fib_proc_init(struct net
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
out3:
|
||||||
|
- remove_proc_entry("fib_triestat", net->proc_net);
|
||||||
|
+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||||
|
+ remove_proc_entry("fib_triestat", net->proc_net);
|
||||||
|
out2:
|
||||||
|
- remove_proc_entry("fib_trie", net->proc_net);
|
||||||
|
+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||||
|
+ remove_proc_entry("fib_trie", net->proc_net);
|
||||||
|
out1:
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __net_exit fib_proc_exit(struct net *net)
|
||||||
|
{
|
||||||
|
- remove_proc_entry("fib_trie", net->proc_net);
|
||||||
|
- remove_proc_entry("fib_triestat", net->proc_net);
|
||||||
|
+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) {
|
||||||
|
+ remove_proc_entry("fib_trie", net->proc_net);
|
||||||
|
+ remove_proc_entry("fib_triestat", net->proc_net);
|
||||||
|
+ }
|
||||||
|
remove_proc_entry("route", net->proc_net);
|
||||||
|
}
|
||||||
|
|
||||||
|
--- a/net/ipv4/proc.c
|
||||||
|
+++ b/net/ipv4/proc.c
|
||||||
|
@@ -563,5 +563,8 @@ static __net_initdata struct pernet_oper
|
||||||
|
|
||||||
|
int __init ip_misc_proc_init(void)
|
||||||
|
{
|
||||||
|
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
return register_pernet_subsys(&ip_proc_ops);
|
||||||
|
}
|
||||||
|
--- a/net/ipv4/route.c
|
||||||
|
+++ b/net/ipv4/route.c
|
||||||
|
@@ -378,6 +378,9 @@ static struct pernet_operations ip_rt_pr
|
||||||
|
|
||||||
|
static int __init ip_rt_proc_init(void)
|
||||||
|
{
|
||||||
|
+ if (IS_ENABLED(CONFIG_PROC_STRIPPED))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
return register_pernet_subsys(&ip_rt_proc_ops);
|
||||||
|
}
|
||||||
|
|
134
hack-6.12/910-kobject_uevent.patch
Normal file
134
hack-6.12/910-kobject_uevent.patch
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
From 0d37e6edc09c99e683dd91ca0e83bbc0df8477b3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Sun, 16 Jul 2017 16:56:10 +0200
|
||||||
|
Subject: lib: add uevent_next_seqnum()
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
include/linux/kobject.h | 5 +++++
|
||||||
|
lib/kobject_uevent.c | 37 +++++++++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 42 insertions(+)
|
||||||
|
|
||||||
|
--- a/include/linux/kobject.h
|
||||||
|
+++ b/include/linux/kobject.h
|
||||||
|
@@ -38,7 +38,7 @@ extern char uevent_helper[];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* counter to tag the uevent, read only except for the kobject core */
|
||||||
|
-extern atomic64_t uevent_seqnum;
|
||||||
|
+extern u64 uevent_seqnum;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The actions here must match the index to the string array
|
||||||
|
--- a/kernel/ksysfs.c
|
||||||
|
+++ b/kernel/ksysfs.c
|
||||||
|
@@ -39,7 +39,7 @@ static struct kobj_attribute _name##_att
|
||||||
|
static ssize_t uevent_seqnum_show(struct kobject *kobj,
|
||||||
|
struct kobj_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
- return sysfs_emit(buf, "%llu\n", (u64)atomic64_read(&uevent_seqnum));
|
||||||
|
+ return sysfs_emit(buf, "%llu\n", (unsigned long long)uevent_seqnum);
|
||||||
|
}
|
||||||
|
KERNEL_ATTR_RO(uevent_seqnum);
|
||||||
|
|
||||||
|
--- a/lib/kobject_uevent.c
|
||||||
|
+++ b/lib/kobject_uevent.c
|
||||||
|
@@ -30,7 +30,7 @@
|
||||||
|
#include <net/net_namespace.h>
|
||||||
|
|
||||||
|
|
||||||
|
-atomic64_t uevent_seqnum;
|
||||||
|
+u64 uevent_seqnum;
|
||||||
|
#ifdef CONFIG_UEVENT_HELPER
|
||||||
|
char uevent_helper[UEVENT_HELPER_PATH_LEN] = CONFIG_UEVENT_HELPER_PATH;
|
||||||
|
#endif
|
||||||
|
@@ -42,10 +42,11 @@ struct uevent_sock {
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET
|
||||||
|
static LIST_HEAD(uevent_sock_list);
|
||||||
|
-/* This lock protects uevent_sock_list */
|
||||||
|
-static DEFINE_MUTEX(uevent_sock_mutex);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+/* This lock protects uevent_seqnum and uevent_sock_list */
|
||||||
|
+static DEFINE_MUTEX(uevent_sock_mutex);
|
||||||
|
+
|
||||||
|
/* the strings here must match the enum in include/linux/kobject.h */
|
||||||
|
static const char *kobject_actions[] = {
|
||||||
|
[KOBJ_ADD] = "add",
|
||||||
|
@@ -178,6 +179,18 @@ out:
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
+u64 uevent_next_seqnum(void)
|
||||||
|
+{
|
||||||
|
+ u64 seq;
|
||||||
|
+
|
||||||
|
+ mutex_lock(&uevent_sock_mutex);
|
||||||
|
+ seq = ++uevent_seqnum;
|
||||||
|
+ mutex_unlock(&uevent_sock_mutex);
|
||||||
|
+
|
||||||
|
+ return seq;
|
||||||
|
+}
|
||||||
|
+EXPORT_SYMBOL_GPL(uevent_next_seqnum);
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* kobject_synth_uevent - send synthetic uevent with arguments
|
||||||
|
*
|
||||||
|
@@ -314,7 +327,6 @@ static int uevent_net_broadcast_untagged
|
||||||
|
int retval = 0;
|
||||||
|
|
||||||
|
/* send netlink message */
|
||||||
|
- mutex_lock(&uevent_sock_mutex);
|
||||||
|
list_for_each_entry(ue_sk, &uevent_sock_list, list) {
|
||||||
|
struct sock *uevent_sock = ue_sk->sk;
|
||||||
|
|
||||||
|
@@ -334,7 +346,6 @@ static int uevent_net_broadcast_untagged
|
||||||
|
if (retval == -ENOBUFS || retval == -ESRCH)
|
||||||
|
retval = 0;
|
||||||
|
}
|
||||||
|
- mutex_unlock(&uevent_sock_mutex);
|
||||||
|
consume_skb(skb);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
@@ -599,14 +610,16 @@ int kobject_uevent_env(struct kobject *k
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ mutex_lock(&uevent_sock_mutex);
|
||||||
|
/* we will send an event, so request a new sequence number */
|
||||||
|
- retval = add_uevent_var(env, "SEQNUM=%llu",
|
||||||
|
- atomic64_inc_return(&uevent_seqnum));
|
||||||
|
- if (retval)
|
||||||
|
+ retval = add_uevent_var(env, "SEQNUM=%llu", ++uevent_seqnum);
|
||||||
|
+ if (retval) {
|
||||||
|
+ mutex_unlock(&uevent_sock_mutex);
|
||||||
|
goto exit;
|
||||||
|
-
|
||||||
|
+ }
|
||||||
|
retval = kobject_uevent_net_broadcast(kobj, env, action_string,
|
||||||
|
devpath);
|
||||||
|
+ mutex_unlock(&uevent_sock_mutex);
|
||||||
|
|
||||||
|
#ifdef CONFIG_UEVENT_HELPER
|
||||||
|
/* call uevent_helper, usually only enabled during early boot */
|
||||||
|
@@ -702,8 +715,7 @@ static int uevent_net_broadcast(struct s
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* bump and prepare sequence number */
|
||||||
|
- ret = snprintf(buf, sizeof(buf), "SEQNUM=%llu",
|
||||||
|
- atomic64_inc_return(&uevent_seqnum));
|
||||||
|
+ ret = snprintf(buf, sizeof(buf), "SEQNUM=%llu", ++uevent_seqnum);
|
||||||
|
if (ret < 0 || (size_t)ret >= sizeof(buf))
|
||||||
|
return -ENOMEM;
|
||||||
|
ret++;
|
||||||
|
@@ -757,7 +769,9 @@ static int uevent_net_rcv_skb(struct sk_
|
||||||
|
return -EPERM;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ mutex_lock(&uevent_sock_mutex);
|
||||||
|
ret = uevent_net_broadcast(net->uevent_sock->sk, skb, extack);
|
||||||
|
+ mutex_unlock(&uevent_sock_mutex);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
76
hack-6.12/911-kobject_add_broadcast_uevent.patch
Normal file
76
hack-6.12/911-kobject_add_broadcast_uevent.patch
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
From 0d37e6edc09c99e683dd91ca0e83bbc0df8477b3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Sun, 16 Jul 2017 16:56:10 +0200
|
||||||
|
Subject: lib: add uevent_next_seqnum()
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
include/linux/kobject.h | 5 +++++
|
||||||
|
lib/kobject_uevent.c | 37 +++++++++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 42 insertions(+)
|
||||||
|
|
||||||
|
--- a/include/linux/kobject.h
|
||||||
|
+++ b/include/linux/kobject.h
|
||||||
|
@@ -32,6 +32,8 @@
|
||||||
|
#define UEVENT_NUM_ENVP 64 /* number of env pointers */
|
||||||
|
#define UEVENT_BUFFER_SIZE 2048 /* buffer for the variables */
|
||||||
|
|
||||||
|
+struct sk_buff;
|
||||||
|
+
|
||||||
|
#ifdef CONFIG_UEVENT_HELPER
|
||||||
|
/* path to the userspace helper executed on an event */
|
||||||
|
extern char uevent_helper[];
|
||||||
|
@@ -219,4 +221,7 @@ int kobject_synth_uevent(struct kobject
|
||||||
|
__printf(2, 3)
|
||||||
|
int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...);
|
||||||
|
|
||||||
|
+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group,
|
||||||
|
+ gfp_t allocation);
|
||||||
|
+
|
||||||
|
#endif /* _KOBJECT_H_ */
|
||||||
|
--- a/lib/kobject_uevent.c
|
||||||
|
+++ b/lib/kobject_uevent.c
|
||||||
|
@@ -706,6 +706,43 @@ int add_uevent_var(struct kobj_uevent_en
|
||||||
|
EXPORT_SYMBOL_GPL(add_uevent_var);
|
||||||
|
|
||||||
|
#if defined(CONFIG_NET)
|
||||||
|
+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group,
|
||||||
|
+ gfp_t allocation)
|
||||||
|
+{
|
||||||
|
+ struct uevent_sock *ue_sk;
|
||||||
|
+ int err = 0;
|
||||||
|
+
|
||||||
|
+ /* send netlink message */
|
||||||
|
+ mutex_lock(&uevent_sock_mutex);
|
||||||
|
+ list_for_each_entry(ue_sk, &uevent_sock_list, list) {
|
||||||
|
+ struct sock *uevent_sock = ue_sk->sk;
|
||||||
|
+ struct sk_buff *skb2;
|
||||||
|
+
|
||||||
|
+ skb2 = skb_clone(skb, allocation);
|
||||||
|
+ if (!skb2)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ err = netlink_broadcast(uevent_sock, skb2, pid, group,
|
||||||
|
+ allocation);
|
||||||
|
+ if (err)
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ mutex_unlock(&uevent_sock_mutex);
|
||||||
|
+
|
||||||
|
+ kfree_skb(skb);
|
||||||
|
+ return err;
|
||||||
|
+}
|
||||||
|
+#else
|
||||||
|
+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group,
|
||||||
|
+ gfp_t allocation)
|
||||||
|
+{
|
||||||
|
+ kfree_skb(skb);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
+EXPORT_SYMBOL_GPL(broadcast_uevent);
|
||||||
|
+
|
||||||
|
+#if defined(CONFIG_NET)
|
||||||
|
static int uevent_net_broadcast(struct sock *usk, struct sk_buff *skb,
|
||||||
|
struct netlink_ext_ack *extack)
|
||||||
|
{
|
12
hack-6.12/920-device_tree_cmdline.patch
Normal file
12
hack-6.12/920-device_tree_cmdline.patch
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
--- a/drivers/of/fdt.c
|
||||||
|
+++ b/drivers/of/fdt.c
|
||||||
|
@@ -1051,6 +1051,9 @@ int __init early_init_dt_scan_chosen(cha
|
||||||
|
p = of_get_flat_dt_prop(node, "bootargs", &l);
|
||||||
|
if (p != NULL && l > 0)
|
||||||
|
strscpy(cmdline, p, min(l, COMMAND_LINE_SIZE));
|
||||||
|
+ p = of_get_flat_dt_prop(node, "bootargs-append", &l);
|
||||||
|
+ if (p != NULL && l > 0)
|
||||||
|
+ strlcat(cmdline, p, min_t(int, strlen(cmdline) + (int)l, COMMAND_LINE_SIZE));
|
||||||
|
|
||||||
|
handle_cmdline:
|
||||||
|
/*
|
12
hack-6.12/991-mkbuild.patch
Normal file
12
hack-6.12/991-mkbuild.patch
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
--- a/scripts/mkcompile_h
|
||||||
|
+++ b/scripts/mkcompile_h
|
||||||
|
@@ -21,7 +21,7 @@ LD_VERSION=$(LC_ALL=C $LD -v | head -n1
|
||||||
|
|
||||||
|
cat <<EOF
|
||||||
|
#define UTS_MACHINE "${UTS_MACHINE}"
|
||||||
|
-#define LINUX_COMPILE_BY "${LINUX_COMPILE_BY}"
|
||||||
|
-#define LINUX_COMPILE_HOST "${LINUX_COMPILE_HOST}"
|
||||||
|
+#define LINUX_COMPILE_BY "admin"
|
||||||
|
+#define LINUX_COMPILE_HOST "cooluc.com"
|
||||||
|
#define LINUX_COMPILER "${CC_VERSION}, ${LD_VERSION}"
|
||||||
|
EOF
|
18467
hack-6.12/992-update-zstd.patch
Normal file
18467
hack-6.12/992-update-zstd.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,29 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Thu, 22 Oct 2020 22:00:03 +0200
|
||||||
|
Subject: [PATCH] compiler.h: only include asm/rwonce.h for kernel code
|
||||||
|
|
||||||
|
This header file is not in uapi, which makes any user space code that includes
|
||||||
|
linux/compiler.h to fail with the error 'asm/rwonce.h: No such file or directory'
|
||||||
|
|
||||||
|
Fixes: e506ea451254 ("compiler.h: Split {READ,WRITE}_ONCE definitions out into rwonce.h")
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/include/linux/compiler.h
|
||||||
|
+++ b/include/linux/compiler.h
|
||||||
|
@@ -214,6 +214,8 @@ void ftrace_likely_update(struct ftrace_
|
||||||
|
__v; \
|
||||||
|
})
|
||||||
|
|
||||||
|
+#include <asm/rwonce.h>
|
||||||
|
+
|
||||||
|
#endif /* __KERNEL__ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -314,6 +316,4 @@ static inline void *offset_to_ptr(const
|
||||||
|
*/
|
||||||
|
#define prevent_tail_call_optimization() mb()
|
||||||
|
|
||||||
|
-#include <asm/rwonce.h>
|
||||||
|
-
|
||||||
|
#endif /* __LINUX_COMPILER_H */
|
@ -0,0 +1,57 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Wed, 18 Apr 2018 10:50:05 +0200
|
||||||
|
Subject: [PATCH] MIPS: only process negative stack offsets on stack traces
|
||||||
|
|
||||||
|
Fixes endless back traces in cases where the compiler emits a stack
|
||||||
|
pointer increase in a branch delay slot (probably for some form of
|
||||||
|
function return).
|
||||||
|
|
||||||
|
[ 3.475442] BUG: MAX_STACK_TRACE_ENTRIES too low!
|
||||||
|
[ 3.480070] turning off the locking correctness validator.
|
||||||
|
[ 3.485521] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.14.34 #0
|
||||||
|
[ 3.491475] Stack : 00000000 00000000 00000000 00000000 80e0fce2 00000034 00000000 00000000
|
||||||
|
[ 3.499764] 87c3838c 80696377 8061047c 00000000 00000001 00000001 87c2d850 6534689f
|
||||||
|
[ 3.508059] 00000000 00000000 80e10000 00000000 00000000 000000cf 0000000f 00000000
|
||||||
|
[ 3.516353] 00000000 806a0000 00076891 00000000 00000000 00000000 ffffffff 00000000
|
||||||
|
[ 3.524648] 806c0000 00000004 80e10000 806a0000 00000003 80690000 00000000 80700000
|
||||||
|
[ 3.532942] ...
|
||||||
|
[ 3.535362] Call Trace:
|
||||||
|
[ 3.537818] [<80010a48>] show_stack+0x58/0x100
|
||||||
|
[ 3.542207] [<804c2f78>] dump_stack+0xe8/0x170
|
||||||
|
[ 3.546613] [<80079f90>] save_trace+0xf0/0x110
|
||||||
|
[ 3.551010] [<8007b1ec>] mark_lock+0x33c/0x78c
|
||||||
|
[ 3.555413] [<8007bf48>] __lock_acquire+0x2ac/0x1a08
|
||||||
|
[ 3.560337] [<8007de60>] lock_acquire+0x64/0x8c
|
||||||
|
[ 3.564846] [<804e1570>] _raw_spin_lock_irqsave+0x54/0x78
|
||||||
|
[ 3.570186] [<801b618c>] kernfs_notify+0x94/0xac
|
||||||
|
[ 3.574770] [<801b7b10>] sysfs_notify+0x74/0xa0
|
||||||
|
[ 3.579257] [<801b618c>] kernfs_notify+0x94/0xac
|
||||||
|
[ 3.583839] [<801b7b10>] sysfs_notify+0x74/0xa0
|
||||||
|
[ 3.588329] [<801b618c>] kernfs_notify+0x94/0xac
|
||||||
|
[ 3.592911] [<801b7b10>] sysfs_notify+0x74/0xa0
|
||||||
|
[ 3.597401] [<801b618c>] kernfs_notify+0x94/0xac
|
||||||
|
[ 3.601983] [<801b7b10>] sysfs_notify+0x74/0xa0
|
||||||
|
[ 3.606473] [<801b618c>] kernfs_notify+0x94/0xac
|
||||||
|
[ 3.611055] [<801b7b10>] sysfs_notify+0x74/0xa0
|
||||||
|
[ 3.615545] [<801b618c>] kernfs_notify+0x94/0xac
|
||||||
|
[ 3.620125] [<801b7b10>] sysfs_notify+0x74/0xa0
|
||||||
|
[ 3.624619] [<801b618c>] kernfs_notify+0x94/0xac
|
||||||
|
[ 3.629197] [<801b7b10>] sysfs_notify+0x74/0xa0
|
||||||
|
[ 3.633691] [<801b618c>] kernfs_notify+0x94/0xac
|
||||||
|
[ 3.638269] [<801b7b10>] sysfs_notify+0x74/0xa0
|
||||||
|
[ 3.642763] [<801b618c>] kernfs_notify+0x94/0xac
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/arch/mips/kernel/process.c
|
||||||
|
+++ b/arch/mips/kernel/process.c
|
||||||
|
@@ -395,6 +395,8 @@ static inline int is_sp_move_ins(union m
|
||||||
|
|
||||||
|
if (ip->i_format.opcode == addiu_op ||
|
||||||
|
ip->i_format.opcode == daddiu_op) {
|
||||||
|
+ if (ip->i_format.simmediate > 0)
|
||||||
|
+ return 0;
|
||||||
|
*frame_size = -ip->i_format.simmediate;
|
||||||
|
return 1;
|
||||||
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Subject: jffs2: use .rename2 and add RENAME_WHITEOUT support
|
||||||
|
|
||||||
|
It is required for renames on overlayfs
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/fs/jffs2/dir.c
|
||||||
|
+++ b/fs/jffs2/dir.c
|
||||||
|
@@ -620,8 +620,8 @@ static int jffs2_rmdir (struct inode *di
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int jffs2_mknod (struct mnt_idmap *idmap, struct inode *dir_i,
|
||||||
|
- struct dentry *dentry, umode_t mode, dev_t rdev)
|
||||||
|
+static int __jffs2_mknod (struct mnt_idmap *idmap, struct inode *dir_i,
|
||||||
|
+ struct dentry *dentry, umode_t mode, dev_t rdev, bool whiteout)
|
||||||
|
{
|
||||||
|
struct jffs2_inode_info *f, *dir_f;
|
||||||
|
struct jffs2_sb_info *c;
|
||||||
|
@@ -761,7 +761,11 @@ static int jffs2_mknod (struct mnt_idmap
|
||||||
|
mutex_unlock(&dir_f->sem);
|
||||||
|
jffs2_complete_reservation(c);
|
||||||
|
|
||||||
|
- d_instantiate_new(dentry, inode);
|
||||||
|
+ if (!whiteout)
|
||||||
|
+ d_instantiate_new(dentry, inode);
|
||||||
|
+ else
|
||||||
|
+ unlock_new_inode(inode);
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
@@ -769,6 +773,19 @@ static int jffs2_mknod (struct mnt_idmap
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int jffs2_mknod (struct mnt_idmap *idmap, struct inode *dir_i,
|
||||||
|
+ struct dentry *dentry, umode_t mode, dev_t rdev)
|
||||||
|
+{
|
||||||
|
+ return __jffs2_mknod(idmap, dir_i, dentry, mode, rdev, false);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int jffs2_whiteout (struct mnt_idmap *idmap, struct inode *old_dir,
|
||||||
|
+ struct dentry *old_dentry)
|
||||||
|
+{
|
||||||
|
+ return __jffs2_mknod(idmap, old_dir, old_dentry, S_IFCHR | WHITEOUT_MODE,
|
||||||
|
+ WHITEOUT_DEV, true);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int jffs2_rename (struct mnt_idmap *idmap,
|
||||||
|
struct inode *old_dir_i, struct dentry *old_dentry,
|
||||||
|
struct inode *new_dir_i, struct dentry *new_dentry,
|
||||||
|
@@ -780,7 +797,7 @@ static int jffs2_rename (struct mnt_idma
|
||||||
|
uint8_t type;
|
||||||
|
uint32_t now;
|
||||||
|
|
||||||
|
- if (flags & ~RENAME_NOREPLACE)
|
||||||
|
+ if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* The VFS will check for us and prevent trying to rename a
|
||||||
|
@@ -846,9 +863,14 @@ static int jffs2_rename (struct mnt_idma
|
||||||
|
if (d_is_dir(old_dentry) && !victim_f)
|
||||||
|
inc_nlink(new_dir_i);
|
||||||
|
|
||||||
|
- /* Unlink the original */
|
||||||
|
- ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
|
||||||
|
- old_dentry->d_name.name, old_dentry->d_name.len, NULL, now);
|
||||||
|
+ if (flags & RENAME_WHITEOUT)
|
||||||
|
+ /* Replace with whiteout */
|
||||||
|
+ ret = jffs2_whiteout(idmap, old_dir_i, old_dentry);
|
||||||
|
+ else
|
||||||
|
+ /* Unlink the original */
|
||||||
|
+ ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
|
||||||
|
+ old_dentry->d_name.name,
|
||||||
|
+ old_dentry->d_name.len, NULL, now);
|
||||||
|
|
||||||
|
/* We don't touch inode->i_nlink */
|
||||||
|
|
73
pending-6.12/141-jffs2-add-RENAME_EXCHANGE-support.patch
Normal file
73
pending-6.12/141-jffs2-add-RENAME_EXCHANGE-support.patch
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Subject: jffs2: add RENAME_EXCHANGE support
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/fs/jffs2/dir.c
|
||||||
|
+++ b/fs/jffs2/dir.c
|
||||||
|
@@ -794,18 +794,31 @@ static int jffs2_rename (struct mnt_idma
|
||||||
|
int ret;
|
||||||
|
struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb);
|
||||||
|
struct jffs2_inode_info *victim_f = NULL;
|
||||||
|
+ struct inode *fst_inode = d_inode(old_dentry);
|
||||||
|
+ struct inode *snd_inode = d_inode(new_dentry);
|
||||||
|
uint8_t type;
|
||||||
|
uint32_t now;
|
||||||
|
|
||||||
|
- if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT))
|
||||||
|
+ if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT|RENAME_EXCHANGE))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
+ if ((flags & RENAME_EXCHANGE) && (old_dir_i != new_dir_i)) {
|
||||||
|
+ if (S_ISDIR(fst_inode->i_mode) && !S_ISDIR(snd_inode->i_mode)) {
|
||||||
|
+ inc_nlink(new_dir_i);
|
||||||
|
+ drop_nlink(old_dir_i);
|
||||||
|
+ }
|
||||||
|
+ else if (!S_ISDIR(fst_inode->i_mode) && S_ISDIR(snd_inode->i_mode)) {
|
||||||
|
+ drop_nlink(new_dir_i);
|
||||||
|
+ inc_nlink(old_dir_i);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* The VFS will check for us and prevent trying to rename a
|
||||||
|
* file over a directory and vice versa, but if it's a directory,
|
||||||
|
* the VFS can't check whether the victim is empty. The filesystem
|
||||||
|
* needs to do that for itself.
|
||||||
|
*/
|
||||||
|
- if (d_really_is_positive(new_dentry)) {
|
||||||
|
+ if (d_really_is_positive(new_dentry) && !(flags & RENAME_EXCHANGE)) {
|
||||||
|
victim_f = JFFS2_INODE_INFO(d_inode(new_dentry));
|
||||||
|
if (d_is_dir(new_dentry)) {
|
||||||
|
struct jffs2_full_dirent *fd;
|
||||||
|
@@ -840,7 +853,7 @@ static int jffs2_rename (struct mnt_idma
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
- if (victim_f) {
|
||||||
|
+ if (victim_f && !(flags & RENAME_EXCHANGE)) {
|
||||||
|
/* There was a victim. Kill it off nicely */
|
||||||
|
if (d_is_dir(new_dentry))
|
||||||
|
clear_nlink(d_inode(new_dentry));
|
||||||
|
@@ -866,6 +879,12 @@ static int jffs2_rename (struct mnt_idma
|
||||||
|
if (flags & RENAME_WHITEOUT)
|
||||||
|
/* Replace with whiteout */
|
||||||
|
ret = jffs2_whiteout(idmap, old_dir_i, old_dentry);
|
||||||
|
+ else if (flags & RENAME_EXCHANGE)
|
||||||
|
+ /* Replace the original */
|
||||||
|
+ ret = jffs2_do_link(c, JFFS2_INODE_INFO(old_dir_i),
|
||||||
|
+ d_inode(new_dentry)->i_ino, type,
|
||||||
|
+ old_dentry->d_name.name, old_dentry->d_name.len,
|
||||||
|
+ now);
|
||||||
|
else
|
||||||
|
/* Unlink the original */
|
||||||
|
ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
|
||||||
|
@@ -898,7 +917,7 @@ static int jffs2_rename (struct mnt_idma
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (d_is_dir(old_dentry))
|
||||||
|
+ if (d_is_dir(old_dentry) && !(flags & RENAME_EXCHANGE))
|
||||||
|
drop_nlink(old_dir_i);
|
||||||
|
|
||||||
|
inode_set_mtime_to_ts(old_dir_i,
|
@ -0,0 +1,45 @@
|
|||||||
|
From: Stephen Hemminger <stephen@networkplumber.org>
|
||||||
|
Subject: bridge: allow receiption on disabled port
|
||||||
|
|
||||||
|
When an ethernet device is enslaved to a bridge, and the bridge STP
|
||||||
|
detects loss of carrier (or operational state down), then normally
|
||||||
|
packet receiption is blocked.
|
||||||
|
|
||||||
|
This breaks control applications like WPA which maybe expecting to
|
||||||
|
receive packets to negotiate to bring link up. The bridge needs to
|
||||||
|
block forwarding packets from these disabled ports, but there is no
|
||||||
|
hard requirement to not allow local packet delivery.
|
||||||
|
|
||||||
|
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
|
||||||
|
--- a/net/bridge/br_input.c
|
||||||
|
+++ b/net/bridge/br_input.c
|
||||||
|
@@ -244,6 +244,9 @@ static void __br_handle_local_finish(str
|
||||||
|
/* note: already called with rcu_read_lock */
|
||||||
|
static int br_handle_local_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
+ struct net_bridge_port *p = br_port_get_rcu(skb->dev);
|
||||||
|
+
|
||||||
|
+ if (p->state != BR_STATE_DISABLED)
|
||||||
|
__br_handle_local_finish(skb);
|
||||||
|
|
||||||
|
/* return 1 to signal the okfn() was called so it's ok to use the skb */
|
||||||
|
@@ -415,6 +418,17 @@ forward:
|
||||||
|
goto defer_stp_filtering;
|
||||||
|
|
||||||
|
switch (p->state) {
|
||||||
|
+ case BR_STATE_DISABLED:
|
||||||
|
+ if (ether_addr_equal(p->br->dev->dev_addr, dest))
|
||||||
|
+ skb->pkt_type = PACKET_HOST;
|
||||||
|
+
|
||||||
|
+ if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING,
|
||||||
|
+ dev_net(skb->dev), NULL, skb, skb->dev, NULL,
|
||||||
|
+ br_handle_local_finish) == 1) {
|
||||||
|
+ return RX_HANDLER_PASS;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
case BR_STATE_FORWARDING:
|
||||||
|
case BR_STATE_LEARNING:
|
||||||
|
defer_stp_filtering:
|
@ -0,0 +1,94 @@
|
|||||||
|
From: Daniel González Cabanelas <dgcbueu@gmail.com>
|
||||||
|
Subject: [PATCH 1/2] rtc: rs5c372: support alarms up to 1 week
|
||||||
|
|
||||||
|
The Ricoh R2221x, R2223x, RS5C372, RV5C387A chips can handle 1 week
|
||||||
|
alarms.
|
||||||
|
|
||||||
|
Read the "wday" alarm register and convert it to a date to support up 1
|
||||||
|
week in our driver.
|
||||||
|
|
||||||
|
Signed-off-by: Daniel González Cabanelas <dgcbueu@gmail.com>
|
||||||
|
---
|
||||||
|
drivers/rtc/rtc-rs5c372.c | 48 ++++++++++++++++++++++++++++++++++-----
|
||||||
|
1 file changed, 42 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/rtc/rtc-rs5c372.c
|
||||||
|
+++ b/drivers/rtc/rtc-rs5c372.c
|
||||||
|
@@ -399,7 +399,9 @@ static int rs5c_read_alarm(struct device
|
||||||
|
{
|
||||||
|
struct i2c_client *client = to_i2c_client(dev);
|
||||||
|
struct rs5c372 *rs5c = i2c_get_clientdata(client);
|
||||||
|
- int status;
|
||||||
|
+ int status, wday_offs;
|
||||||
|
+ struct rtc_time rtc;
|
||||||
|
+ unsigned long alarm_secs;
|
||||||
|
|
||||||
|
status = rs5c_get_regs(rs5c);
|
||||||
|
if (status < 0)
|
||||||
|
@@ -409,6 +411,30 @@ static int rs5c_read_alarm(struct device
|
||||||
|
t->time.tm_sec = 0;
|
||||||
|
t->time.tm_min = bcd2bin(rs5c->regs[RS5C_REG_ALARM_A_MIN] & 0x7f);
|
||||||
|
t->time.tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C_REG_ALARM_A_HOURS]);
|
||||||
|
+ t->time.tm_wday = ffs(rs5c->regs[RS5C_REG_ALARM_A_WDAY] & 0x7f) - 1;
|
||||||
|
+
|
||||||
|
+ /* determine the day, month and year based on alarm wday, taking as a
|
||||||
|
+ * reference the current time from the rtc
|
||||||
|
+ */
|
||||||
|
+ status = rs5c372_rtc_read_time(dev, &rtc);
|
||||||
|
+ if (status < 0)
|
||||||
|
+ return status;
|
||||||
|
+
|
||||||
|
+ wday_offs = t->time.tm_wday - rtc.tm_wday;
|
||||||
|
+ alarm_secs = mktime64(rtc.tm_year + 1900,
|
||||||
|
+ rtc.tm_mon + 1,
|
||||||
|
+ rtc.tm_mday + wday_offs,
|
||||||
|
+ t->time.tm_hour,
|
||||||
|
+ t->time.tm_min,
|
||||||
|
+ t->time.tm_sec);
|
||||||
|
+
|
||||||
|
+ if (wday_offs < 0 || (wday_offs == 0 &&
|
||||||
|
+ (t->time.tm_hour < rtc.tm_hour ||
|
||||||
|
+ (t->time.tm_hour == rtc.tm_hour &&
|
||||||
|
+ t->time.tm_min <= rtc.tm_min))))
|
||||||
|
+ alarm_secs += 7 * 86400;
|
||||||
|
+
|
||||||
|
+ rtc_time64_to_tm(alarm_secs, &t->time);
|
||||||
|
|
||||||
|
/* ... and status */
|
||||||
|
t->enabled = !!(rs5c->regs[RS5C_REG_CTRL1] & RS5C_CTRL1_AALE);
|
||||||
|
@@ -423,12 +449,20 @@ static int rs5c_set_alarm(struct device
|
||||||
|
struct rs5c372 *rs5c = i2c_get_clientdata(client);
|
||||||
|
int status, addr, i;
|
||||||
|
unsigned char buf[3];
|
||||||
|
+ struct rtc_time rtc_tm;
|
||||||
|
+ unsigned long rtc_secs, alarm_secs;
|
||||||
|
|
||||||
|
- /* only handle up to 24 hours in the future, like RTC_ALM_SET */
|
||||||
|
- if (t->time.tm_mday != -1
|
||||||
|
- || t->time.tm_mon != -1
|
||||||
|
- || t->time.tm_year != -1)
|
||||||
|
+ /* chip only can handle alarms up to one week in the future*/
|
||||||
|
+ status = rs5c372_rtc_read_time(dev, &rtc_tm);
|
||||||
|
+ if (status)
|
||||||
|
+ return status;
|
||||||
|
+ rtc_secs = rtc_tm_to_time64(&rtc_tm);
|
||||||
|
+ alarm_secs = rtc_tm_to_time64(&t->time);
|
||||||
|
+ if (alarm_secs >= rtc_secs + 7 * 86400) {
|
||||||
|
+ dev_err(dev, "%s: alarm maximum is one week in the future (%d)\n",
|
||||||
|
+ __func__, status);
|
||||||
|
return -EINVAL;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/* REVISIT: round up tm_sec */
|
||||||
|
|
||||||
|
@@ -449,7 +483,9 @@ static int rs5c_set_alarm(struct device
|
||||||
|
/* set alarm */
|
||||||
|
buf[0] = bin2bcd(t->time.tm_min);
|
||||||
|
buf[1] = rs5c_hr2reg(rs5c, t->time.tm_hour);
|
||||||
|
- buf[2] = 0x7f; /* any/all days */
|
||||||
|
+ /* each bit is the day of the week, 0x7f means all days */
|
||||||
|
+ buf[2] = (t->time.tm_wday >= 0 && t->time.tm_wday < 7) ?
|
||||||
|
+ BIT(t->time.tm_wday) : 0x7f;
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(buf); i++) {
|
||||||
|
addr = RS5C_ADDR(RS5C_REG_ALARM_A_MIN + i);
|
@ -0,0 +1,70 @@
|
|||||||
|
From: Daniel González Cabanelas <dgcbueu@gmail.com>
|
||||||
|
Subject: [PATCH 2/2] rtc: rs5c372: let the alarm to be used as wakeup source
|
||||||
|
|
||||||
|
Currently there is no use for the interrupts on the rs5c372 RTC and the
|
||||||
|
wakealarm isn't enabled. There are some devices like NASes which use this
|
||||||
|
RTC to wake up from the power off state when the INTR pin is activated by
|
||||||
|
the alarm clock.
|
||||||
|
|
||||||
|
Enable the alarm and let to be used as a wakeup source.
|
||||||
|
|
||||||
|
Tested on a Buffalo LS421DE NAS.
|
||||||
|
|
||||||
|
Signed-off-by: Daniel González Cabanelas <dgcbueu@gmail.com>
|
||||||
|
---
|
||||||
|
drivers/rtc/rtc-rs5c372.c | 16 ++++++++++++++++
|
||||||
|
1 file changed, 16 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/rtc/rtc-rs5c372.c
|
||||||
|
+++ b/drivers/rtc/rtc-rs5c372.c
|
||||||
|
@@ -832,6 +832,7 @@ static int rs5c372_probe(struct i2c_clie
|
||||||
|
int err = 0;
|
||||||
|
int smbus_mode = 0;
|
||||||
|
struct rs5c372 *rs5c372;
|
||||||
|
+ bool rs5c372_can_wakeup_device = false;
|
||||||
|
|
||||||
|
dev_dbg(&client->dev, "%s\n", __func__);
|
||||||
|
|
||||||
|
@@ -868,6 +869,12 @@ static int rs5c372_probe(struct i2c_clie
|
||||||
|
rs5c372->type = id->driver_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#ifdef CONFIG_OF
|
||||||
|
+ if(of_property_read_bool(client->dev.of_node,
|
||||||
|
+ "wakeup-source"))
|
||||||
|
+ rs5c372_can_wakeup_device = true;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/* we read registers 0x0f then 0x00-0x0f; skip the first one */
|
||||||
|
rs5c372->regs = &rs5c372->buf[1];
|
||||||
|
rs5c372->smbus = smbus_mode;
|
||||||
|
@@ -901,6 +908,8 @@ static int rs5c372_probe(struct i2c_clie
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ rs5c372->has_irq = 1;
|
||||||
|
+
|
||||||
|
/* if the oscillator lost power and no other software (like
|
||||||
|
* the bootloader) set it up, do it here.
|
||||||
|
*
|
||||||
|
@@ -927,6 +936,10 @@ static int rs5c372_probe(struct i2c_clie
|
||||||
|
);
|
||||||
|
|
||||||
|
/* REVISIT use client->irq to register alarm irq ... */
|
||||||
|
+ if (rs5c372_can_wakeup_device) {
|
||||||
|
+ device_init_wakeup(&client->dev, true);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
rs5c372->rtc = devm_rtc_device_register(&client->dev,
|
||||||
|
rs5c372_driver.driver.name,
|
||||||
|
&rs5c372_rtc_ops, THIS_MODULE);
|
||||||
|
@@ -940,6 +953,9 @@ static int rs5c372_probe(struct i2c_clie
|
||||||
|
if (err)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
+ /* the rs5c372 alarm only supports a minute accuracy */
|
||||||
|
+
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
exit:
|
41
pending-6.12/205-backtrace_module_info.patch
Normal file
41
pending-6.12/205-backtrace_module_info.patch
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Subject: kernel: when KALLSYMS is disabled, print module address + size for matching backtrace entries
|
||||||
|
|
||||||
|
[john@phrozen.org: felix will add this to his upstream queue]
|
||||||
|
|
||||||
|
lede-commit 53827cdc824556cda910b23ce5030c363b8f1461
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
lib/vsprintf.c | 15 +++++++++++----
|
||||||
|
1 file changed, 11 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
--- a/lib/vsprintf.c
|
||||||
|
+++ b/lib/vsprintf.c
|
||||||
|
@@ -983,8 +983,10 @@ char *symbol_string(char *buf, char *end
|
||||||
|
struct printf_spec spec, const char *fmt)
|
||||||
|
{
|
||||||
|
unsigned long value;
|
||||||
|
-#ifdef CONFIG_KALLSYMS
|
||||||
|
char sym[KSYM_SYMBOL_LEN];
|
||||||
|
+#ifndef CONFIG_KALLSYMS
|
||||||
|
+ struct module *mod;
|
||||||
|
+ int len;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (fmt[1] == 'R')
|
||||||
|
@@ -1005,8 +1007,14 @@ char *symbol_string(char *buf, char *end
|
||||||
|
|
||||||
|
return string_nocheck(buf, end, sym, spec);
|
||||||
|
#else
|
||||||
|
- return special_hex_number(buf, end, value, sizeof(void *));
|
||||||
|
+ len = snprintf(sym, sizeof(sym), "0x%lx", value);
|
||||||
|
+ mod = __module_address(value);
|
||||||
|
+ if (mod)
|
||||||
|
+ snprintf(sym + len, sizeof(sym) - len, " [%s@%p+0x%x]",
|
||||||
|
+ mod->name, mod->mem[MOD_TEXT].base,
|
||||||
|
+ mod->mem[MOD_TEXT].size);
|
||||||
|
#endif
|
||||||
|
+ return string(buf, end, sym, spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct printf_spec default_str_spec = {
|
@ -0,0 +1,30 @@
|
|||||||
|
From: Gabor Juhos <juhosg@openwrt.org>
|
||||||
|
Subject: usr: sanitize deps_initramfs list
|
||||||
|
|
||||||
|
If any filename in the intramfs dependency
|
||||||
|
list contains a colon, that causes a kernel
|
||||||
|
build error like this:
|
||||||
|
|
||||||
|
/devel/openwrt/build_dir/linux-ar71xx_generic/linux-3.6.6/usr/Makefile:58: *** multiple target patterns. Stop.
|
||||||
|
make[5]: *** [usr] Error 2
|
||||||
|
|
||||||
|
Fix it by removing such filenames from the
|
||||||
|
deps_initramfs list.
|
||||||
|
|
||||||
|
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
usr/Makefile | 8 +++++---
|
||||||
|
1 file changed, 5 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
--- a/usr/Makefile
|
||||||
|
+++ b/usr/Makefile
|
||||||
|
@@ -56,6 +56,8 @@ hostprogs := gen_init_cpio
|
||||||
|
# The dependency list is generated by gen_initramfs.sh -l
|
||||||
|
-include $(obj)/.initramfs_data.cpio.d
|
||||||
|
|
||||||
|
+deps_initramfs := $(foreach v,$(deps_initramfs),$(if $(findstring :,$(v)),,$(v)))
|
||||||
|
+
|
||||||
|
# do not try to update files included in initramfs
|
||||||
|
$(deps_initramfs): ;
|
||||||
|
|
40
pending-6.12/300-mips_expose_boot_raw.patch
Normal file
40
pending-6.12/300-mips_expose_boot_raw.patch
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
From: Mark Miller <mark@mirell.org>
|
||||||
|
Subject: mips: expose CONFIG_BOOT_RAW
|
||||||
|
|
||||||
|
This exposes the CONFIG_BOOT_RAW symbol in Kconfig. This is needed on
|
||||||
|
certain Broadcom chipsets running CFE in order to load the kernel.
|
||||||
|
|
||||||
|
Signed-off-by: Mark Miller <mark@mirell.org>
|
||||||
|
Acked-by: Rob Landley <rob@landley.net>
|
||||||
|
---
|
||||||
|
--- a/arch/mips/Kconfig
|
||||||
|
+++ b/arch/mips/Kconfig
|
||||||
|
@@ -1055,9 +1055,6 @@ config FW_ARC
|
||||||
|
config ARCH_MAY_HAVE_PC_FDC
|
||||||
|
bool
|
||||||
|
|
||||||
|
-config BOOT_RAW
|
||||||
|
- bool
|
||||||
|
-
|
||||||
|
config CEVT_BCM1480
|
||||||
|
bool
|
||||||
|
|
||||||
|
@@ -2988,6 +2985,18 @@ choice
|
||||||
|
bool "Extend builtin kernel arguments with bootloader arguments"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
+config BOOT_RAW
|
||||||
|
+ bool "Enable the kernel to be executed from the load address"
|
||||||
|
+ default n
|
||||||
|
+ help
|
||||||
|
+ Allow the kernel to be executed from the load address for
|
||||||
|
+ bootloaders which cannot read the ELF format. This places
|
||||||
|
+ a jump to start_kernel at the load address.
|
||||||
|
+
|
||||||
|
+ If unsure, say N.
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
config LOCKDEP_SUPPORT
|
22
pending-6.12/302-mips_no_branch_likely.patch
Normal file
22
pending-6.12/302-mips_no_branch_likely.patch
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Subject: mips: use -mno-branch-likely for kernel and userspace
|
||||||
|
|
||||||
|
saves ~11k kernel size after lzma and ~12k squashfs size in the
|
||||||
|
|
||||||
|
lede-commit: 41a039f46450ffae9483d6216422098669da2900
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
arch/mips/Makefile | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/arch/mips/Makefile
|
||||||
|
+++ b/arch/mips/Makefile
|
||||||
|
@@ -94,7 +94,7 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlin
|
||||||
|
# machines may also. Since BFD is incredibly buggy with respect to
|
||||||
|
# crossformat linking we rely on the elf2ecoff tool for format conversion.
|
||||||
|
#
|
||||||
|
-cflags-y += -G 0 -mno-abicalls -fno-pic -pipe
|
||||||
|
+cflags-y += -G 0 -mno-abicalls -fno-pic -pipe -mno-branch-likely
|
||||||
|
cflags-y += -msoft-float -Wa,-msoft-float
|
||||||
|
LDFLAGS_vmlinux += -G 0 -static -n -nostdlib
|
||||||
|
KBUILD_AFLAGS_MODULE += -mlong-calls
|
19
pending-6.12/307-mips_highmem_offset.patch
Normal file
19
pending-6.12/307-mips_highmem_offset.patch
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Subject: kernel: adjust mips highmem offset to avoid the need for -mlong-calls on systems with >256M RAM
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
arch/mips/include/asm/mach-generic/spaces.h | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/arch/mips/include/asm/mach-generic/spaces.h
|
||||||
|
+++ b/arch/mips/include/asm/mach-generic/spaces.h
|
||||||
|
@@ -46,7 +46,7 @@
|
||||||
|
* Memory above this physical address will be considered highmem.
|
||||||
|
*/
|
||||||
|
#ifndef HIGHMEM_START
|
||||||
|
-#define HIGHMEM_START _AC(0x20000000, UL)
|
||||||
|
+#define HIGHMEM_START _AC(0x10000000, UL)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CKSEG0ADDR_OR_64BIT(x) CKSEG0ADDR(x)
|
22
pending-6.12/308-mips32r2_tune.patch
Normal file
22
pending-6.12/308-mips32r2_tune.patch
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Subject: kernel: add -mtune=34kc to MIPS CFLAGS when building for mips32r2
|
||||||
|
|
||||||
|
This provides a good tradeoff across at least 24Kc-74Kc, while also
|
||||||
|
producing smaller code.
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
arch/mips/Makefile | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/arch/mips/Makefile
|
||||||
|
+++ b/arch/mips/Makefile
|
||||||
|
@@ -153,7 +153,7 @@ cflags-$(CONFIG_CPU_R4300) += $(call cc-
|
||||||
|
cflags-$(CONFIG_CPU_R4X00) += $(call cc-option,-march=r4600,-march=mips3) -Wa,--trap
|
||||||
|
cflags-$(CONFIG_CPU_TX49XX) += $(call cc-option,-march=r4600,-march=mips3) -Wa,--trap
|
||||||
|
cflags-$(CONFIG_CPU_MIPS32_R1) += -march=mips32 -Wa,--trap
|
||||||
|
-cflags-$(CONFIG_CPU_MIPS32_R2) += -march=mips32r2 -Wa,--trap
|
||||||
|
+cflags-$(CONFIG_CPU_MIPS32_R2) += -march=mips32r2 -mtune=34kc -Wa,--trap
|
||||||
|
cflags-$(CONFIG_CPU_MIPS32_R5) += -march=mips32r5 -Wa,--trap -modd-spreg
|
||||||
|
cflags-$(CONFIG_CPU_MIPS32_R6) += -march=mips32r6 -Wa,--trap -modd-spreg
|
||||||
|
cflags-$(CONFIG_CPU_MIPS64_R1) += -march=mips64 -Wa,--trap
|
22
pending-6.12/310-arm_module_unresolved_weak_sym.patch
Normal file
22
pending-6.12/310-arm_module_unresolved_weak_sym.patch
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Subject: fix errors in unresolved weak symbols on arm
|
||||||
|
|
||||||
|
lede-commit: 570699d4838a907c3ef9f2819bf19eb72997b32f
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
arch/arm/kernel/module.c | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
--- a/arch/arm/kernel/module.c
|
||||||
|
+++ b/arch/arm/kernel/module.c
|
||||||
|
@@ -112,6 +112,10 @@ apply_relocate(Elf32_Shdr *sechdrs, cons
|
||||||
|
return -ENOEXEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if ((IS_ERR_VALUE(sym->st_value) || !sym->st_value) &&
|
||||||
|
+ ELF_ST_BIND(sym->st_info) == STB_WEAK)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
loc = dstsec->sh_addr + rel->r_offset;
|
||||||
|
|
||||||
|
switch (ELF32_R_TYPE(rel->r_info)) {
|
@ -0,0 +1,282 @@
|
|||||||
|
From: Yousong Zhou <yszhou4tech@gmail.com>
|
||||||
|
Subject: MIPS: kexec: Accept command line parameters from userspace.
|
||||||
|
|
||||||
|
Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
|
||||||
|
---
|
||||||
|
arch/mips/kernel/machine_kexec.c | 153 +++++++++++++++++++++++++++++++-----
|
||||||
|
arch/mips/kernel/machine_kexec.h | 20 +++++
|
||||||
|
arch/mips/kernel/relocate_kernel.S | 21 +++--
|
||||||
|
3 files changed, 167 insertions(+), 27 deletions(-)
|
||||||
|
create mode 100644 arch/mips/kernel/machine_kexec.h
|
||||||
|
|
||||||
|
--- a/arch/mips/kernel/machine_kexec.c
|
||||||
|
+++ b/arch/mips/kernel/machine_kexec.c
|
||||||
|
@@ -10,14 +10,11 @@
|
||||||
|
#include <linux/libfdt.h>
|
||||||
|
#include <linux/reboot.h>
|
||||||
|
|
||||||
|
+#include <asm/bootinfo.h>
|
||||||
|
#include <asm/cacheflush.h>
|
||||||
|
#include <asm/page.h>
|
||||||
|
-
|
||||||
|
-extern const unsigned char relocate_new_kernel[];
|
||||||
|
-extern const size_t relocate_new_kernel_size;
|
||||||
|
-
|
||||||
|
-extern unsigned long kexec_start_address;
|
||||||
|
-extern unsigned long kexec_indirection_page;
|
||||||
|
+#include <linux/uaccess.h>
|
||||||
|
+#include "machine_kexec.h"
|
||||||
|
|
||||||
|
static unsigned long reboot_code_buffer;
|
||||||
|
|
||||||
|
@@ -31,6 +28,101 @@ void (*_crash_smp_send_stop)(void) = NUL
|
||||||
|
void (*_machine_kexec_shutdown)(void) = NULL;
|
||||||
|
void (*_machine_crash_shutdown)(struct pt_regs *regs) = NULL;
|
||||||
|
|
||||||
|
+static void machine_kexec_print_args(void)
|
||||||
|
+{
|
||||||
|
+ unsigned long argc = (int)kexec_args[0];
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ pr_info("kexec_args[0] (argc): %lu\n", argc);
|
||||||
|
+ pr_info("kexec_args[1] (argv): %p\n", (void *)kexec_args[1]);
|
||||||
|
+ pr_info("kexec_args[2] (env ): %p\n", (void *)kexec_args[2]);
|
||||||
|
+ pr_info("kexec_args[3] (desc): %p\n", (void *)kexec_args[3]);
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < argc; i++) {
|
||||||
|
+ pr_info("kexec_argv[%d] = %p, %s\n",
|
||||||
|
+ i, kexec_argv[i], kexec_argv[i]);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void machine_kexec_init_argv(struct kimage *image)
|
||||||
|
+{
|
||||||
|
+ void __user *buf = NULL;
|
||||||
|
+ size_t bufsz;
|
||||||
|
+ size_t size;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ bufsz = 0;
|
||||||
|
+ for (i = 0; i < image->nr_segments; i++) {
|
||||||
|
+ struct kexec_segment *seg;
|
||||||
|
+
|
||||||
|
+ seg = &image->segment[i];
|
||||||
|
+ if (seg->bufsz < 6)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ if (strncmp((char *) seg->buf, "kexec ", 6))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ buf = seg->buf;
|
||||||
|
+ bufsz = seg->bufsz;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!buf)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ size = KEXEC_COMMAND_LINE_SIZE;
|
||||||
|
+ size = min(size, bufsz);
|
||||||
|
+ if (size < bufsz)
|
||||||
|
+ pr_warn("kexec command line truncated to %zd bytes\n", size);
|
||||||
|
+
|
||||||
|
+ /* Copy to kernel space */
|
||||||
|
+ if (copy_from_user(kexec_argv_buf, buf, size))
|
||||||
|
+ pr_warn("kexec command line copy to kernel space failed\n");
|
||||||
|
+
|
||||||
|
+ kexec_argv_buf[size - 1] = 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void machine_kexec_parse_argv(struct kimage *image)
|
||||||
|
+{
|
||||||
|
+ char *reboot_code_buffer;
|
||||||
|
+ int reloc_delta;
|
||||||
|
+ char *ptr;
|
||||||
|
+ int argc;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ ptr = kexec_argv_buf;
|
||||||
|
+ argc = 0;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * convert command line string to array of parameters
|
||||||
|
+ * (as bootloader does).
|
||||||
|
+ */
|
||||||
|
+ while (ptr && *ptr && (KEXEC_MAX_ARGC > argc)) {
|
||||||
|
+ if (*ptr == ' ') {
|
||||||
|
+ *ptr++ = '\0';
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ kexec_argv[argc++] = ptr;
|
||||||
|
+ ptr = strchr(ptr, ' ');
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!argc)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ kexec_args[0] = argc;
|
||||||
|
+ kexec_args[1] = (unsigned long)kexec_argv;
|
||||||
|
+ kexec_args[2] = 0;
|
||||||
|
+ kexec_args[3] = 0;
|
||||||
|
+
|
||||||
|
+ reboot_code_buffer = page_address(image->control_code_page);
|
||||||
|
+ reloc_delta = reboot_code_buffer - (char *)kexec_relocate_new_kernel;
|
||||||
|
+
|
||||||
|
+ kexec_args[1] += reloc_delta;
|
||||||
|
+ for (i = 0; i < argc; i++)
|
||||||
|
+ kexec_argv[i] += reloc_delta;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void kexec_image_info(const struct kimage *kimage)
|
||||||
|
{
|
||||||
|
unsigned long i;
|
||||||
|
@@ -100,6 +192,18 @@ machine_kexec_prepare(struct kimage *kim
|
||||||
|
#endif
|
||||||
|
|
||||||
|
kexec_image_info(kimage);
|
||||||
|
+ /*
|
||||||
|
+ * Whenever arguments passed from kexec-tools, Init the arguments as
|
||||||
|
+ * the original ones to try avoiding booting failure.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ kexec_args[0] = fw_arg0;
|
||||||
|
+ kexec_args[1] = fw_arg1;
|
||||||
|
+ kexec_args[2] = fw_arg2;
|
||||||
|
+ kexec_args[3] = fw_arg3;
|
||||||
|
+
|
||||||
|
+ machine_kexec_init_argv(kimage);
|
||||||
|
+ machine_kexec_parse_argv(kimage);
|
||||||
|
|
||||||
|
if (_machine_kexec_prepare)
|
||||||
|
return _machine_kexec_prepare(kimage);
|
||||||
|
@@ -162,7 +266,7 @@ machine_crash_shutdown(struct pt_regs *r
|
||||||
|
void kexec_nonboot_cpu_jump(void)
|
||||||
|
{
|
||||||
|
local_flush_icache_range((unsigned long)relocated_kexec_smp_wait,
|
||||||
|
- reboot_code_buffer + relocate_new_kernel_size);
|
||||||
|
+ reboot_code_buffer + KEXEC_RELOCATE_NEW_KERNEL_SIZE);
|
||||||
|
|
||||||
|
relocated_kexec_smp_wait(NULL);
|
||||||
|
}
|
||||||
|
@@ -200,7 +304,7 @@ void kexec_reboot(void)
|
||||||
|
* machine_kexec() CPU.
|
||||||
|
*/
|
||||||
|
local_flush_icache_range(reboot_code_buffer,
|
||||||
|
- reboot_code_buffer + relocate_new_kernel_size);
|
||||||
|
+ reboot_code_buffer + KEXEC_RELOCATE_NEW_KERNEL_SIZE);
|
||||||
|
|
||||||
|
do_kexec = (void *)reboot_code_buffer;
|
||||||
|
do_kexec();
|
||||||
|
@@ -213,10 +317,12 @@ machine_kexec(struct kimage *image)
|
||||||
|
unsigned long *ptr;
|
||||||
|
|
||||||
|
reboot_code_buffer =
|
||||||
|
- (unsigned long)page_address(image->control_code_page);
|
||||||
|
+ (unsigned long)page_address(image->control_code_page);
|
||||||
|
+ pr_info("reboot_code_buffer = %p\n", (void *)reboot_code_buffer);
|
||||||
|
|
||||||
|
kexec_start_address =
|
||||||
|
(unsigned long) phys_to_virt(image->start);
|
||||||
|
+ pr_info("kexec_start_address = %p\n", (void *)kexec_start_address);
|
||||||
|
|
||||||
|
if (image->type == KEXEC_TYPE_DEFAULT) {
|
||||||
|
kexec_indirection_page =
|
||||||
|
@@ -224,9 +330,19 @@ machine_kexec(struct kimage *image)
|
||||||
|
} else {
|
||||||
|
kexec_indirection_page = (unsigned long)&image->head;
|
||||||
|
}
|
||||||
|
+ pr_info("kexec_indirection_page = %p\n", (void *)kexec_indirection_page);
|
||||||
|
|
||||||
|
- memcpy((void*)reboot_code_buffer, relocate_new_kernel,
|
||||||
|
- relocate_new_kernel_size);
|
||||||
|
+ pr_info("Where is memcpy: %p\n", memcpy);
|
||||||
|
+ pr_info("kexec_relocate_new_kernel = %p, kexec_relocate_new_kernel_end = %p\n",
|
||||||
|
+ (void *)kexec_relocate_new_kernel, &kexec_relocate_new_kernel_end);
|
||||||
|
+ pr_info("Copy %lu bytes from %p to %p\n", KEXEC_RELOCATE_NEW_KERNEL_SIZE,
|
||||||
|
+ (void *)kexec_relocate_new_kernel, (void *)reboot_code_buffer);
|
||||||
|
+ memcpy((void*)reboot_code_buffer, kexec_relocate_new_kernel,
|
||||||
|
+ KEXEC_RELOCATE_NEW_KERNEL_SIZE);
|
||||||
|
+
|
||||||
|
+ pr_info("Before _print_args().\n");
|
||||||
|
+ machine_kexec_print_args();
|
||||||
|
+ pr_info("Before eval loop.\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The generic kexec code builds a page list with physical
|
||||||
|
@@ -257,7 +373,7 @@ machine_kexec(struct kimage *image)
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
/* All secondary cpus now may jump to kexec_wait cycle */
|
||||||
|
relocated_kexec_smp_wait = reboot_code_buffer +
|
||||||
|
- (void *)(kexec_smp_wait - relocate_new_kernel);
|
||||||
|
+ (void *)(kexec_smp_wait - kexec_relocate_new_kernel);
|
||||||
|
smp_wmb();
|
||||||
|
atomic_set(&kexec_ready_to_reboot, 1);
|
||||||
|
#endif
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/arch/mips/kernel/machine_kexec.h
|
||||||
|
@@ -0,0 +1,20 @@
|
||||||
|
+#ifndef _MACHINE_KEXEC_H
|
||||||
|
+#define _MACHINE_KEXEC_H
|
||||||
|
+
|
||||||
|
+#ifndef __ASSEMBLY__
|
||||||
|
+extern const unsigned char kexec_relocate_new_kernel[];
|
||||||
|
+extern unsigned long kexec_relocate_new_kernel_end;
|
||||||
|
+extern unsigned long kexec_start_address;
|
||||||
|
+extern unsigned long kexec_indirection_page;
|
||||||
|
+
|
||||||
|
+extern char kexec_argv_buf[];
|
||||||
|
+extern char *kexec_argv[];
|
||||||
|
+
|
||||||
|
+#define KEXEC_RELOCATE_NEW_KERNEL_SIZE ((unsigned long)&kexec_relocate_new_kernel_end - (unsigned long)kexec_relocate_new_kernel)
|
||||||
|
+#endif /* !__ASSEMBLY__ */
|
||||||
|
+
|
||||||
|
+#define KEXEC_COMMAND_LINE_SIZE 256
|
||||||
|
+#define KEXEC_ARGV_SIZE (KEXEC_COMMAND_LINE_SIZE / 16)
|
||||||
|
+#define KEXEC_MAX_ARGC (KEXEC_ARGV_SIZE / sizeof(long))
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
--- a/arch/mips/kernel/relocate_kernel.S
|
||||||
|
+++ b/arch/mips/kernel/relocate_kernel.S
|
||||||
|
@@ -10,10 +10,11 @@
|
||||||
|
#include <asm/mipsregs.h>
|
||||||
|
#include <asm/stackframe.h>
|
||||||
|
#include <asm/addrspace.h>
|
||||||
|
+#include "machine_kexec.h"
|
||||||
|
|
||||||
|
#include <kernel-entry-init.h>
|
||||||
|
|
||||||
|
-LEAF(relocate_new_kernel)
|
||||||
|
+LEAF(kexec_relocate_new_kernel)
|
||||||
|
PTR_L a0, arg0
|
||||||
|
PTR_L a1, arg1
|
||||||
|
PTR_L a2, arg2
|
||||||
|
@@ -97,7 +98,7 @@ done:
|
||||||
|
#endif
|
||||||
|
/* jump to kexec_start_address */
|
||||||
|
j s1
|
||||||
|
- END(relocate_new_kernel)
|
||||||
|
+ END(kexec_relocate_new_kernel)
|
||||||
|
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
/*
|
||||||
|
@@ -176,8 +177,15 @@ EXPORT(kexec_indirection_page)
|
||||||
|
PTR_WD 0
|
||||||
|
.size kexec_indirection_page, PTRSIZE
|
||||||
|
|
||||||
|
-relocate_new_kernel_end:
|
||||||
|
+kexec_argv_buf:
|
||||||
|
+ EXPORT(kexec_argv_buf)
|
||||||
|
+ .skip KEXEC_COMMAND_LINE_SIZE
|
||||||
|
+ .size kexec_argv_buf, KEXEC_COMMAND_LINE_SIZE
|
||||||
|
+
|
||||||
|
+kexec_argv:
|
||||||
|
+ EXPORT(kexec_argv)
|
||||||
|
+ .skip KEXEC_ARGV_SIZE
|
||||||
|
+ .size kexec_argv, KEXEC_ARGV_SIZE
|
||||||
|
|
||||||
|
-EXPORT(relocate_new_kernel_size)
|
||||||
|
- PTR_WD relocate_new_kernel_end - relocate_new_kernel
|
||||||
|
- .size relocate_new_kernel_size, PTRSIZE
|
||||||
|
+kexec_relocate_new_kernel_end:
|
||||||
|
+ EXPORT(kexec_relocate_new_kernel_end)
|
84
pending-6.12/332-arc-add-OWRTDTB-section.patch
Normal file
84
pending-6.12/332-arc-add-OWRTDTB-section.patch
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
From bb0c3b0175240bf152fd7c644821a0cf9f77c37c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Evgeniy Didin <Evgeniy.Didin@synopsys.com>
|
||||||
|
Date: Fri, 15 Mar 2019 18:53:38 +0300
|
||||||
|
Subject: [PATCH] arc add OWRTDTB section
|
||||||
|
|
||||||
|
This change allows OpenWRT to patch resulting kernel binary with
|
||||||
|
external .dtb.
|
||||||
|
|
||||||
|
That allows us to re-use exactky the same vmlinux on different boards
|
||||||
|
given its ARC core configurations match (at least cache line sizes etc).
|
||||||
|
|
||||||
|
""patch-dtb" searches for ASCII "OWRTDTB:" strign and copies external
|
||||||
|
.dtb right after it, keeping the string in place.
|
||||||
|
|
||||||
|
Signed-off-by: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
|
||||||
|
Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
|
||||||
|
Signed-off-by: Evgeniy Didin <Evgeniy.Didin@synopsys.com>
|
||||||
|
---
|
||||||
|
arch/arc/kernel/head.S | 10 ++++++++++
|
||||||
|
arch/arc/kernel/setup.c | 4 +++-
|
||||||
|
arch/arc/kernel/vmlinux.lds.S | 13 +++++++++++++
|
||||||
|
3 files changed, 26 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/arch/arc/kernel/head.S
|
||||||
|
+++ b/arch/arc/kernel/head.S
|
||||||
|
@@ -88,6 +88,16 @@
|
||||||
|
DSP_EARLY_INIT
|
||||||
|
.endm
|
||||||
|
|
||||||
|
+ ; Here "patch-dtb" will embed external .dtb
|
||||||
|
+ ; Note "patch-dtb" searches for ASCII "OWRTDTB:" string
|
||||||
|
+ ; and pastes .dtb right after it, hense the string precedes
|
||||||
|
+ ; __image_dtb symbol.
|
||||||
|
+ .section .owrt, "aw",@progbits
|
||||||
|
+ .ascii "OWRTDTB:"
|
||||||
|
+ENTRY(__image_dtb)
|
||||||
|
+ .fill 0x4000
|
||||||
|
+END(__image_dtb)
|
||||||
|
+
|
||||||
|
.section .init.text, "ax",@progbits
|
||||||
|
|
||||||
|
;----------------------------------------------------------------
|
||||||
|
--- a/arch/arc/kernel/setup.c
|
||||||
|
+++ b/arch/arc/kernel/setup.c
|
||||||
|
@@ -450,6 +450,8 @@ static inline bool uboot_arg_invalid(uns
|
||||||
|
/* We always pass 0 as magic from U-boot */
|
||||||
|
#define UBOOT_MAGIC_VALUE 0
|
||||||
|
|
||||||
|
+extern struct boot_param_header __image_dtb;
|
||||||
|
+
|
||||||
|
void __init handle_uboot_args(void)
|
||||||
|
{
|
||||||
|
bool use_embedded_dtb = true;
|
||||||
|
@@ -488,7 +490,7 @@ void __init handle_uboot_args(void)
|
||||||
|
ignore_uboot_args:
|
||||||
|
|
||||||
|
if (use_embedded_dtb) {
|
||||||
|
- machine_desc = setup_machine_fdt(__dtb_start);
|
||||||
|
+ machine_desc = setup_machine_fdt(&__image_dtb);
|
||||||
|
if (!machine_desc)
|
||||||
|
panic("Embedded DT invalid\n");
|
||||||
|
}
|
||||||
|
--- a/arch/arc/kernel/vmlinux.lds.S
|
||||||
|
+++ b/arch/arc/kernel/vmlinux.lds.S
|
||||||
|
@@ -27,6 +27,19 @@ SECTIONS
|
||||||
|
|
||||||
|
. = CONFIG_LINUX_LINK_BASE;
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * In OpenWRT we want to patch built binary embedding .dtb of choice.
|
||||||
|
+ * This is implemented with "patch-dtb" utility which searches for
|
||||||
|
+ * "OWRTDTB:" string in first 16k of image and if it is found
|
||||||
|
+ * copies .dtb right after mentioned string.
|
||||||
|
+ *
|
||||||
|
+ * Note: "OWRTDTB:" won't be overwritten with .dtb, .dtb will follow it.
|
||||||
|
+ */
|
||||||
|
+ .owrt : {
|
||||||
|
+ *(.owrt)
|
||||||
|
+ . = ALIGN(PAGE_SIZE);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
_int_vec_base_lds = .;
|
||||||
|
.vector : {
|
||||||
|
*(.vector)
|
@ -0,0 +1,24 @@
|
|||||||
|
From: Alexey Brodkin <abrodkin@synopsys.com>
|
||||||
|
Subject: arc: enable unaligned access in kernel mode
|
||||||
|
|
||||||
|
This enables misaligned access handling even in kernel mode.
|
||||||
|
Some wireless drivers (ath9k-htc and mt7601u) use misaligned accesses
|
||||||
|
here and there and to cope with that without fixing stuff in the drivers
|
||||||
|
we're just gracefully handling it on ARC.
|
||||||
|
|
||||||
|
Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
|
||||||
|
---
|
||||||
|
arch/arc/kernel/unaligned.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/arch/arc/kernel/unaligned.c
|
||||||
|
+++ b/arch/arc/kernel/unaligned.c
|
||||||
|
@@ -203,7 +203,7 @@ int misaligned_fixup(unsigned long addre
|
||||||
|
char buf[TASK_COMM_LEN];
|
||||||
|
|
||||||
|
/* handle user mode only and only if enabled by sysadmin */
|
||||||
|
- if (!user_mode(regs) || !unaligned_enabled)
|
||||||
|
+ if (!unaligned_enabled)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (no_unaligned_warning) {
|
@ -0,0 +1,25 @@
|
|||||||
|
From 66770a004afe10df11d3902e16eaa0c2c39436bb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Pawel Dembicki <paweldembicki@gmail.com>
|
||||||
|
Date: Fri, 24 May 2019 17:56:19 +0200
|
||||||
|
Subject: [PATCH] powerpc: Enable kernel XZ compression option on PPC_85xx
|
||||||
|
|
||||||
|
Enable kernel XZ compression option on PPC_85xx. Tested with
|
||||||
|
simpleImage on TP-Link TL-WDR4900 (Freescale P1014 processor).
|
||||||
|
|
||||||
|
Suggested-by: Christian Lamparter <chunkeey@gmail.com>
|
||||||
|
Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
|
||||||
|
---
|
||||||
|
arch/powerpc/Kconfig | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/arch/powerpc/Kconfig
|
||||||
|
+++ b/arch/powerpc/Kconfig
|
||||||
|
@@ -254,7 +254,7 @@ config PPC
|
||||||
|
select HAVE_KERNEL_GZIP
|
||||||
|
select HAVE_KERNEL_LZMA if DEFAULT_UIMAGE
|
||||||
|
select HAVE_KERNEL_LZO if DEFAULT_UIMAGE
|
||||||
|
- select HAVE_KERNEL_XZ if PPC_BOOK3S || 44x
|
||||||
|
+ select HAVE_KERNEL_XZ if PPC_BOOK3S || 44x || PPC_85xx
|
||||||
|
select HAVE_KPROBES
|
||||||
|
select HAVE_KPROBES_ON_FTRACE
|
||||||
|
select HAVE_KRETPROBES
|
314
pending-6.12/400-mtd-mtdsplit-support.patch
Normal file
314
pending-6.12/400-mtd-mtdsplit-support.patch
Normal file
@ -0,0 +1,314 @@
|
|||||||
|
--- a/drivers/mtd/Kconfig
|
||||||
|
+++ b/drivers/mtd/Kconfig
|
||||||
|
@@ -12,6 +12,25 @@ menuconfig MTD
|
||||||
|
|
||||||
|
if MTD
|
||||||
|
|
||||||
|
+menu "OpenWrt specific MTD options"
|
||||||
|
+
|
||||||
|
+config MTD_ROOTFS_ROOT_DEV
|
||||||
|
+ bool "Automatically set 'rootfs' partition to be root filesystem"
|
||||||
|
+ default y
|
||||||
|
+
|
||||||
|
+config MTD_SPLIT_FIRMWARE
|
||||||
|
+ bool "Automatically split firmware partition for kernel+rootfs"
|
||||||
|
+ default y
|
||||||
|
+
|
||||||
|
+config MTD_SPLIT_FIRMWARE_NAME
|
||||||
|
+ string "Firmware partition name"
|
||||||
|
+ depends on MTD_SPLIT_FIRMWARE
|
||||||
|
+ default "firmware"
|
||||||
|
+
|
||||||
|
+source "drivers/mtd/mtdsplit/Kconfig"
|
||||||
|
+
|
||||||
|
+endmenu
|
||||||
|
+
|
||||||
|
config MTD_TESTS
|
||||||
|
tristate "MTD tests support (DANGEROUS)"
|
||||||
|
depends on m
|
||||||
|
--- a/drivers/mtd/mtdpart.c
|
||||||
|
+++ b/drivers/mtd/mtdpart.c
|
||||||
|
@@ -15,11 +15,13 @@
|
||||||
|
#include <linux/kmod.h>
|
||||||
|
#include <linux/mtd/mtd.h>
|
||||||
|
#include <linux/mtd/partitions.h>
|
||||||
|
+#include <linux/magic.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/of_platform.h>
|
||||||
|
|
||||||
|
#include "mtdcore.h"
|
||||||
|
+#include "mtdsplit/mtdsplit.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MTD methods which simply translate the effective address and pass through
|
||||||
|
@@ -242,6 +244,146 @@ static int mtd_add_partition_attrs(struc
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static DEFINE_SPINLOCK(part_parser_lock);
|
||||||
|
+static LIST_HEAD(part_parsers);
|
||||||
|
+
|
||||||
|
+static struct mtd_part_parser *mtd_part_parser_get(const char *name)
|
||||||
|
+{
|
||||||
|
+ struct mtd_part_parser *p, *ret = NULL;
|
||||||
|
+
|
||||||
|
+ spin_lock(&part_parser_lock);
|
||||||
|
+
|
||||||
|
+ list_for_each_entry(p, &part_parsers, list)
|
||||||
|
+ if (!strcmp(p->name, name) && try_module_get(p->owner)) {
|
||||||
|
+ ret = p;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ spin_unlock(&part_parser_lock);
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void mtd_part_parser_put(const struct mtd_part_parser *p)
|
||||||
|
+{
|
||||||
|
+ module_put(p->owner);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct mtd_part_parser *
|
||||||
|
+get_partition_parser_by_type(enum mtd_parser_type type,
|
||||||
|
+ struct mtd_part_parser *start)
|
||||||
|
+{
|
||||||
|
+ struct mtd_part_parser *p, *ret = NULL;
|
||||||
|
+
|
||||||
|
+ spin_lock(&part_parser_lock);
|
||||||
|
+
|
||||||
|
+ p = list_prepare_entry(start, &part_parsers, list);
|
||||||
|
+ if (start)
|
||||||
|
+ mtd_part_parser_put(start);
|
||||||
|
+
|
||||||
|
+ list_for_each_entry_continue(p, &part_parsers, list) {
|
||||||
|
+ if (p->type == type && try_module_get(p->owner)) {
|
||||||
|
+ ret = p;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ spin_unlock(&part_parser_lock);
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int parse_mtd_partitions_by_type(struct mtd_info *master,
|
||||||
|
+ enum mtd_parser_type type,
|
||||||
|
+ const struct mtd_partition **pparts,
|
||||||
|
+ struct mtd_part_parser_data *data)
|
||||||
|
+{
|
||||||
|
+ struct mtd_part_parser *prev = NULL;
|
||||||
|
+ int ret = 0;
|
||||||
|
+
|
||||||
|
+ while (1) {
|
||||||
|
+ struct mtd_part_parser *parser;
|
||||||
|
+
|
||||||
|
+ parser = get_partition_parser_by_type(type, prev);
|
||||||
|
+ if (!parser)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ ret = (*parser->parse_fn)(master, pparts, data);
|
||||||
|
+
|
||||||
|
+ if (ret > 0) {
|
||||||
|
+ mtd_part_parser_put(parser);
|
||||||
|
+ printk(KERN_NOTICE
|
||||||
|
+ "%d %s partitions found on MTD device %s\n",
|
||||||
|
+ ret, parser->name, master->name);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ prev = parser;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+run_parsers_by_type(struct mtd_info *child, enum mtd_parser_type type)
|
||||||
|
+{
|
||||||
|
+ struct mtd_partition *parts;
|
||||||
|
+ int nr_parts;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ nr_parts = parse_mtd_partitions_by_type(child, type, (const struct mtd_partition **)&parts,
|
||||||
|
+ NULL);
|
||||||
|
+ if (nr_parts <= 0)
|
||||||
|
+ return nr_parts;
|
||||||
|
+
|
||||||
|
+ if (WARN_ON(!parts))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < nr_parts; i++) {
|
||||||
|
+ /* adjust partition offsets */
|
||||||
|
+ parts[i].offset += child->part.offset;
|
||||||
|
+
|
||||||
|
+ mtd_add_partition(child->parent,
|
||||||
|
+ parts[i].name,
|
||||||
|
+ parts[i].offset,
|
||||||
|
+ parts[i].size);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ kfree(parts);
|
||||||
|
+
|
||||||
|
+ return nr_parts;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME
|
||||||
|
+#define SPLIT_FIRMWARE_NAME CONFIG_MTD_SPLIT_FIRMWARE_NAME
|
||||||
|
+#else
|
||||||
|
+#define SPLIT_FIRMWARE_NAME "unused"
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+static void split_firmware(struct mtd_info *master, struct mtd_info *part)
|
||||||
|
+{
|
||||||
|
+ run_parsers_by_type(part, MTD_PARSER_TYPE_FIRMWARE);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void mtd_partition_split(struct mtd_info *master, struct mtd_info *part)
|
||||||
|
+{
|
||||||
|
+ static int rootfs_found = 0;
|
||||||
|
+
|
||||||
|
+ if (rootfs_found)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (!strcmp(part->name, "rootfs")) {
|
||||||
|
+ run_parsers_by_type(part, MTD_PARSER_TYPE_ROOTFS);
|
||||||
|
+
|
||||||
|
+ rootfs_found = 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (IS_ENABLED(CONFIG_MTD_SPLIT_FIRMWARE) &&
|
||||||
|
+ !strcmp(part->name, SPLIT_FIRMWARE_NAME) &&
|
||||||
|
+ !of_find_property(mtd_get_of_node(part), "compatible", NULL))
|
||||||
|
+ split_firmware(master, part);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int mtd_add_partition(struct mtd_info *parent, const char *name,
|
||||||
|
long long offset, long long length)
|
||||||
|
{
|
||||||
|
@@ -280,6 +422,7 @@ int mtd_add_partition(struct mtd_info *p
|
||||||
|
if (ret)
|
||||||
|
goto err_remove_part;
|
||||||
|
|
||||||
|
+ mtd_partition_split(parent, child);
|
||||||
|
mtd_add_partition_attrs(child);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
@@ -423,6 +566,7 @@ int add_mtd_partitions(struct mtd_info *
|
||||||
|
goto err_del_partitions;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ mtd_partition_split(master, child);
|
||||||
|
mtd_add_partition_attrs(child);
|
||||||
|
|
||||||
|
/* Look for subpartitions */
|
||||||
|
@@ -443,31 +587,6 @@ err_del_partitions:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static DEFINE_SPINLOCK(part_parser_lock);
|
||||||
|
-static LIST_HEAD(part_parsers);
|
||||||
|
-
|
||||||
|
-static struct mtd_part_parser *mtd_part_parser_get(const char *name)
|
||||||
|
-{
|
||||||
|
- struct mtd_part_parser *p, *ret = NULL;
|
||||||
|
-
|
||||||
|
- spin_lock(&part_parser_lock);
|
||||||
|
-
|
||||||
|
- list_for_each_entry(p, &part_parsers, list)
|
||||||
|
- if (!strcmp(p->name, name) && try_module_get(p->owner)) {
|
||||||
|
- ret = p;
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- spin_unlock(&part_parser_lock);
|
||||||
|
-
|
||||||
|
- return ret;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static inline void mtd_part_parser_put(const struct mtd_part_parser *p)
|
||||||
|
-{
|
||||||
|
- module_put(p->owner);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
/*
|
||||||
|
* Many partition parsers just expected the core to kfree() all their data in
|
||||||
|
* one chunk. Do that by default.
|
||||||
|
--- a/include/linux/mtd/partitions.h
|
||||||
|
+++ b/include/linux/mtd/partitions.h
|
||||||
|
@@ -75,6 +75,12 @@ struct mtd_part_parser_data {
|
||||||
|
* Functions dealing with the various ways of partitioning the space
|
||||||
|
*/
|
||||||
|
|
||||||
|
+enum mtd_parser_type {
|
||||||
|
+ MTD_PARSER_TYPE_DEVICE = 0,
|
||||||
|
+ MTD_PARSER_TYPE_ROOTFS,
|
||||||
|
+ MTD_PARSER_TYPE_FIRMWARE,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
struct mtd_part_parser {
|
||||||
|
struct list_head list;
|
||||||
|
struct module *owner;
|
||||||
|
@@ -83,6 +89,7 @@ struct mtd_part_parser {
|
||||||
|
int (*parse_fn)(struct mtd_info *, const struct mtd_partition **,
|
||||||
|
struct mtd_part_parser_data *);
|
||||||
|
void (*cleanup)(const struct mtd_partition *pparts, int nr_parts);
|
||||||
|
+ enum mtd_parser_type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Container for passing around a set of parsed partitions */
|
||||||
|
--- a/drivers/mtd/Makefile
|
||||||
|
+++ b/drivers/mtd/Makefile
|
||||||
|
@@ -9,6 +9,8 @@ mtd-y := mtdcore.o mtdsuper.o mtdconc
|
||||||
|
|
||||||
|
obj-y += parsers/
|
||||||
|
|
||||||
|
+obj-$(CONFIG_MTD_SPLIT) += mtdsplit/
|
||||||
|
+
|
||||||
|
# 'Users' - code which presents functionality to userspace.
|
||||||
|
obj-$(CONFIG_MTD_BLKDEVS) += mtd_blkdevs.o
|
||||||
|
obj-$(CONFIG_MTD_BLOCK) += mtdblock.o
|
||||||
|
--- a/include/linux/mtd/mtd.h
|
||||||
|
+++ b/include/linux/mtd/mtd.h
|
||||||
|
@@ -615,6 +615,24 @@ static inline void mtd_align_erase_req(s
|
||||||
|
req->len += mtd->erasesize - mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static inline uint64_t mtd_roundup_to_eb(uint64_t sz, struct mtd_info *mtd)
|
||||||
|
+{
|
||||||
|
+ if (mtd_mod_by_eb(sz, mtd) == 0)
|
||||||
|
+ return sz;
|
||||||
|
+
|
||||||
|
+ /* Round up to next erase block */
|
||||||
|
+ return (mtd_div_by_eb(sz, mtd) + 1) * mtd->erasesize;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline uint64_t mtd_rounddown_to_eb(uint64_t sz, struct mtd_info *mtd)
|
||||||
|
+{
|
||||||
|
+ if (mtd_mod_by_eb(sz, mtd) == 0)
|
||||||
|
+ return sz;
|
||||||
|
+
|
||||||
|
+ /* Round down to the start of the current erase block */
|
||||||
|
+ return (mtd_div_by_eb(sz, mtd)) * mtd->erasesize;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static inline uint32_t mtd_div_by_ws(uint64_t sz, struct mtd_info *mtd)
|
||||||
|
{
|
||||||
|
if (mtd->writesize_shift)
|
||||||
|
@@ -688,6 +706,13 @@ extern struct mtd_info *of_get_mtd_devic
|
||||||
|
extern struct mtd_info *get_mtd_device_nm(const char *name);
|
||||||
|
extern void put_mtd_device(struct mtd_info *mtd);
|
||||||
|
|
||||||
|
+static inline uint64_t mtdpart_get_offset(const struct mtd_info *mtd)
|
||||||
|
+{
|
||||||
|
+ if (!mtd_is_partition(mtd))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ return mtd->part.offset;
|
||||||
|
+}
|
||||||
|
|
||||||
|
struct mtd_notifier {
|
||||||
|
void (*add)(struct mtd_info *mtd);
|
@ -0,0 +1,389 @@
|
|||||||
|
From patchwork Tue Jun 8 04:07:19 2021
|
||||||
|
Content-Type: text/plain; charset="utf-8"
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Transfer-Encoding: 7bit
|
||||||
|
X-Patchwork-Submitter: John Thomson <git@johnthomson.fastmail.com.au>
|
||||||
|
X-Patchwork-Id: 1489105
|
||||||
|
X-Patchwork-Delegate: tudor.ambarus@gmail.com
|
||||||
|
Return-Path:
|
||||||
|
<linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org>
|
||||||
|
X-Original-To: incoming@patchwork.ozlabs.org
|
||||||
|
Delivered-To: patchwork-incoming@bilbo.ozlabs.org
|
||||||
|
Authentication-Results: ozlabs.org;
|
||||||
|
spf=none (no SPF record) smtp.mailfrom=lists.infradead.org
|
||||||
|
(client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org;
|
||||||
|
envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org;
|
||||||
|
receiver=<UNKNOWN>)
|
||||||
|
Authentication-Results: ozlabs.org;
|
||||||
|
dkim=pass (2048-bit key;
|
||||||
|
secure) header.d=lists.infradead.org header.i=@lists.infradead.org
|
||||||
|
header.a=rsa-sha256 header.s=bombadil.20210309 header.b=EMabhVoR;
|
||||||
|
dkim=fail reason="signature verification failed" (2048-bit key;
|
||||||
|
unprotected) header.d=fastmail.com.au header.i=@fastmail.com.au
|
||||||
|
header.a=rsa-sha256 header.s=fm3 header.b=dLzuZ6dB;
|
||||||
|
dkim=fail reason="signature verification failed" (2048-bit key;
|
||||||
|
unprotected) header.d=messagingengine.com header.i=@messagingengine.com
|
||||||
|
header.a=rsa-sha256 header.s=fm3 header.b=nSRGsW+C;
|
||||||
|
dkim-atps=neutral
|
||||||
|
Received: from bombadil.infradead.org (bombadil.infradead.org
|
||||||
|
[IPv6:2607:7c80:54:e::133])
|
||||||
|
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
|
||||||
|
key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest
|
||||||
|
SHA256)
|
||||||
|
(No client certificate requested)
|
||||||
|
by ozlabs.org (Postfix) with ESMTPS id 4FzcFN1j1nz9sW8
|
||||||
|
for <incoming@patchwork.ozlabs.org>; Tue, 8 Jun 2021 14:09:28 +1000 (AEST)
|
||||||
|
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
|
||||||
|
d=lists.infradead.org; s=bombadil.20210309; h=Sender:
|
||||||
|
Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post:
|
||||||
|
List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:Cc
|
||||||
|
:To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:
|
||||||
|
Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:
|
||||||
|
List-Owner; bh=6mUWQd71FwsINycGYY1qOhKz+ecWJVNtwDkTebG3XkA=; b=EMabhVoRE3ad89
|
||||||
|
o3L2AgyKrs+blSofUC3hoSsQe7gi3m4si8S9HW8Z+8SsS5TufUsvGwDl80qSYGlQOytQF+1yRUWvE
|
||||||
|
6FJ/+bqv+TwjqZFibgJ6+9OVsQN9dZ/no1R0bBXIpmrf8ORUmv58QK4ZQquaFKbyXKpFeWOC2MSv4
|
||||||
|
H2MAhyhTU8a3gtooH6G8+KvsJEfVgh6C+aDbwxyh2UY3chHKuw1kvL6AktbfUE2xl4zxi3x3kc70B
|
||||||
|
Wi3LiJBFokxVdgnROXxTU5tI0XboWYkQV64gLuQNV4XKClcuhVpzloDK8Iok6NTd7b32a7TdEFlCS
|
||||||
|
lGKsEKmxtUlW2FpfoduA==;
|
||||||
|
Received: from localhost ([::1] helo=bombadil.infradead.org)
|
||||||
|
by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux))
|
||||||
|
id 1lqT1r-006OAW-DX; Tue, 08 Jun 2021 04:07:51 +0000
|
||||||
|
Received: from new1-smtp.messagingengine.com ([66.111.4.221])
|
||||||
|
by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux))
|
||||||
|
id 1lqT1l-006O9b-Fq
|
||||||
|
for linux-mtd@lists.infradead.org; Tue, 08 Jun 2021 04:07:50 +0000
|
||||||
|
Received: from compute2.internal (compute2.nyi.internal [10.202.2.42])
|
||||||
|
by mailnew.nyi.internal (Postfix) with ESMTP id 4456B580622;
|
||||||
|
Tue, 8 Jun 2021 00:07:42 -0400 (EDT)
|
||||||
|
Received: from mailfrontend2 ([10.202.2.163])
|
||||||
|
by compute2.internal (MEProxy); Tue, 08 Jun 2021 00:07:42 -0400
|
||||||
|
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fastmail.com.au;
|
||||||
|
h=from:to:cc:subject:date:message-id:mime-version
|
||||||
|
:content-transfer-encoding; s=fm3; bh=ZXRH+YluM1mHCS1EWUiCY/Sg8O
|
||||||
|
LccfHe1oW5iAay6y8=; b=dLzuZ6dBYf7ZA8tWLOBFZYLi7ERsGe/4vnMXG+ovvb
|
||||||
|
dNBO0+SaFGwoqYSFrfq/TeyHfKyvxrA7+LCdopIuT4abpLHxtRwtRiafQcDYCPat
|
||||||
|
qJIqOZO+wCZC5S9Jc1OP7+t1FviGpgevqIMotci37P+RWc5u3AweMzFljZk90E8C
|
||||||
|
uorV6rXagD+OssJQzllRnAIK88+rOAC9ZyXv2gWxy4d1HSCwSWgzx2vnV9CNp918
|
||||||
|
YC/3tiHas9krbrPIaAsdBROr7Bvoe/ShRRzruKRuvZVgg5NN90vX+/5ZjI8u04GM
|
||||||
|
p2bWCbC62CP6wlcgDaz+c/Sgr5ITd2GPENJsHfqmLRBA==
|
||||||
|
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=
|
||||||
|
messagingengine.com; h=cc:content-transfer-encoding:date:from
|
||||||
|
:message-id:mime-version:subject:to:x-me-proxy:x-me-proxy
|
||||||
|
:x-me-sender:x-me-sender:x-sasl-enc; s=fm3; bh=ZXRH+YluM1mHCS1EW
|
||||||
|
UiCY/Sg8OLccfHe1oW5iAay6y8=; b=nSRGsW+CQ2Zx1RVpIUu8W/VD/k5P+32BW
|
||||||
|
5k2ltd+UhI3dfldBPzHrYiOP/IJqGkNW+V+rHASacW/vFygnaZoxNjRYKnOsu+26
|
||||||
|
wb2yK3jpl6lsNTg3N1Z4XJrYY2lf9H29DMFbhC67l0PTc050rcZk4XsKTLAlv14Q
|
||||||
|
VA4WREYSaX/4IN4O+ES4TMq0a/3gKZh6nvbbJXbsXfK0WlSHTGZtZmW3fyrqvbXa
|
||||||
|
t+R7L8vvqWvwls0pV+Sn8LeQqb7+A69w0UOnuznjkcA3sCc2YehcHbxcUEnMH+9N
|
||||||
|
bxOjmIDeg9/4X/829tUWUJiLhE5SFmQZ1P6oFtmbWoLrDz0ZJIVBw==
|
||||||
|
X-ME-Sender: <xms:C-2-YD2uka4HsA6gcdsV2Ia7vebY4Yjp9E8q7KBMb54jnAzGL7-67Q>
|
||||||
|
<xme:C-2-YCEaxASy5VlcrvNO_jLFpMDGkFCRsuVNuZGEQsiRZygk8jPHWq7unPjeT6uYS
|
||||||
|
2pUP6PrTQ2rggjEIg>
|
||||||
|
X-ME-Received:
|
||||||
|
<xmr:C-2-YD4exeK49N_YZWWf2BWDhVyCbCY3wwvjTyDOFxeugx7Jg08pzMUToo9oJjrBpcVTaA3kbfk>
|
||||||
|
X-ME-Proxy-Cause:
|
||||||
|
gggruggvucftvghtrhhoucdtuddrgeduledrfedtkedgjeduucetufdoteggodetrfdotf
|
||||||
|
fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen
|
||||||
|
uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne
|
||||||
|
cujfgurhephffvufffkffoggfgsedtkeertdertddtnecuhfhrohhmpeflohhhnhcuvfhh
|
||||||
|
ohhmshhonhcuoehgihhtsehjohhhnhhthhhomhhsohhnrdhfrghsthhmrghilhdrtghomh
|
||||||
|
drrghuqeenucggtffrrghtthgvrhhnpefffeeihfdukedtuedufeetieeuudfhhefhkefh
|
||||||
|
tefgtdeuffekffelleetveduieenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmh
|
||||||
|
epmhgrihhlfhhrohhmpehgihhtsehjohhhnhhthhhomhhsohhnrdhfrghsthhmrghilhdr
|
||||||
|
tghomhdrrghu
|
||||||
|
X-ME-Proxy: <xmx:C-2-YI0AJZGjcB3wIbI9BoC9X8VNl4i9A7cQnBkvwZ25czWJlkKCLw>
|
||||||
|
<xmx:C-2-YGGufw99T-O81-FeiSyEruv6_Pr0IHFhspQdxjv5k1VFTZ0lzQ>
|
||||||
|
<xmx:C-2-YJ8BW7DhSDSCEAPSJWrwh_hHP79qreTZtWh_kOUwSh1c0MMlAg>
|
||||||
|
<xmx:Du2-YJBeX2Fg9oFZVXGwEJ1ZrZnXHiAqNON8tbpzquYgcm2o_LM48g>
|
||||||
|
Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue,
|
||||||
|
8 Jun 2021 00:07:35 -0400 (EDT)
|
||||||
|
From: John Thomson <git@johnthomson.fastmail.com.au>
|
||||||
|
To: Miquel Raynal <miquel.raynal@bootlin.com>,
|
||||||
|
Richard Weinberger <richard@nod.at>, Vignesh Raghavendra <vigneshr@ti.com>,
|
||||||
|
Tudor Ambarus <tudor.ambarus@microchip.com>,
|
||||||
|
Michael Walle <michael@walle.cc>, Pratyush Yadav <p.yadav@ti.com>,
|
||||||
|
linux-mtd@lists.infradead.org
|
||||||
|
Cc: linux-kernel@vger.kernel.org,
|
||||||
|
John Thomson <git@johnthomson.fastmail.com.au>,
|
||||||
|
kernel test robot <lkp@intel.com>, Dan Carpenter <dan.carpenter@oracle.com>
|
||||||
|
Subject: [PATCH] mtd: spi-nor: write support for minor aligned partitions
|
||||||
|
Date: Tue, 8 Jun 2021 14:07:19 +1000
|
||||||
|
Message-Id: <20210608040719.14431-1-git@johnthomson.fastmail.com.au>
|
||||||
|
X-Mailer: git-send-email 2.31.1
|
||||||
|
MIME-Version: 1.0
|
||||||
|
X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3
|
||||||
|
X-CRM114-CacheID: sfid-20210607_210745_712053_67A7D864
|
||||||
|
X-CRM114-Status: GOOD ( 26.99 )
|
||||||
|
X-Spam-Score: -0.8 (/)
|
||||||
|
X-Spam-Report: Spam detection software,
|
||||||
|
running on the system "bombadil.infradead.org",
|
||||||
|
has NOT identified this incoming email as spam. The original
|
||||||
|
message has been attached to this so you can view it or label
|
||||||
|
similar future email. If you have any questions, see
|
||||||
|
the administrator of that system for details.
|
||||||
|
Content preview: Do not prevent writing to mtd partitions where a partition
|
||||||
|
boundary sits on a minor erasesize boundary. This addresses a FIXME that
|
||||||
|
has been present since the start of the linux git history: /* Doesn' [...]
|
||||||
|
Content analysis details: (-0.8 points, 5.0 required)
|
||||||
|
pts rule name description
|
||||||
|
---- ----------------------
|
||||||
|
--------------------------------------------------
|
||||||
|
-0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at https://www.dnswl.org/,
|
||||||
|
low trust [66.111.4.221 listed in list.dnswl.org]
|
||||||
|
-0.0 SPF_PASS SPF: sender matches SPF record
|
||||||
|
-0.0 SPF_HELO_PASS SPF: HELO matches SPF record
|
||||||
|
0.0 RCVD_IN_MSPIKE_H3 RBL: Good reputation (+3)
|
||||||
|
[66.111.4.221 listed in wl.mailspike.net]
|
||||||
|
-0.1 DKIM_VALID Message has at least one valid DKIM or DK signature
|
||||||
|
0.1 DKIM_SIGNED Message has a DKIM or DK signature,
|
||||||
|
not necessarily
|
||||||
|
valid
|
||||||
|
-0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from
|
||||||
|
envelope-from domain
|
||||||
|
0.0 RCVD_IN_MSPIKE_WL Mailspike good senders
|
||||||
|
X-BeenThere: linux-mtd@lists.infradead.org
|
||||||
|
X-Mailman-Version: 2.1.34
|
||||||
|
Precedence: list
|
||||||
|
List-Id: Linux MTD discussion mailing list <linux-mtd.lists.infradead.org>
|
||||||
|
List-Unsubscribe: <http://lists.infradead.org/mailman/options/linux-mtd>,
|
||||||
|
<mailto:linux-mtd-request@lists.infradead.org?subject=unsubscribe>
|
||||||
|
List-Archive: <http://lists.infradead.org/pipermail/linux-mtd/>
|
||||||
|
List-Post: <mailto:linux-mtd@lists.infradead.org>
|
||||||
|
List-Help: <mailto:linux-mtd-request@lists.infradead.org?subject=help>
|
||||||
|
List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-mtd>,
|
||||||
|
<mailto:linux-mtd-request@lists.infradead.org?subject=subscribe>
|
||||||
|
Sender: "linux-mtd" <linux-mtd-bounces@lists.infradead.org>
|
||||||
|
Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org
|
||||||
|
|
||||||
|
Do not prevent writing to mtd partitions where a partition boundary sits
|
||||||
|
on a minor erasesize boundary.
|
||||||
|
This addresses a FIXME that has been present since the start of the
|
||||||
|
linux git history:
|
||||||
|
/* Doesn't start on a boundary of major erase size */
|
||||||
|
/* FIXME: Let it be writable if it is on a boundary of
|
||||||
|
* _minor_ erase size though */
|
||||||
|
|
||||||
|
Allow a uniform erase region spi-nor device to be configured
|
||||||
|
to use the non-uniform erase regions code path for an erase with:
|
||||||
|
CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y
|
||||||
|
|
||||||
|
On supporting hardware (SECT_4K: majority of current SPI-NOR device)
|
||||||
|
provide the facility for an erase to use the least number
|
||||||
|
of SPI-NOR operations, as well as access to 4K erase without
|
||||||
|
requiring CONFIG_MTD_SPI_NOR_USE_4K_SECTORS
|
||||||
|
|
||||||
|
Introduce erasesize_minor to the mtd struct,
|
||||||
|
the smallest erasesize supported by the device
|
||||||
|
|
||||||
|
On existing devices, this is useful where write support is wanted
|
||||||
|
for data on a 4K partition, such as some u-boot-env partitions,
|
||||||
|
or RouterBoot soft_config, while still netting the performance
|
||||||
|
benefits of using 64K sectors
|
||||||
|
|
||||||
|
Performance:
|
||||||
|
time mtd erase firmware
|
||||||
|
OpenWrt 5.10 ramips MT7621 w25q128jv 0xfc0000 partition length
|
||||||
|
|
||||||
|
Without this patch
|
||||||
|
MTD_SPI_NOR_USE_4K_SECTORS=y |n
|
||||||
|
real 2m 11.66s |0m 50.86s
|
||||||
|
user 0m 0.00s |0m 0.00s
|
||||||
|
sys 1m 56.20s |0m 50.80s
|
||||||
|
|
||||||
|
With this patch
|
||||||
|
MTD_SPI_NOR_USE_VARIABLE_ERASE=n|y |4K_SECTORS=y
|
||||||
|
real 0m 51.68s |0m 50.85s |2m 12.89s
|
||||||
|
user 0m 0.00s |0m 0.00s |0m 0.01s
|
||||||
|
sys 0m 46.94s |0m 50.38s |2m 12.46s
|
||||||
|
|
||||||
|
Signed-off-by: John Thomson <git@johnthomson.fastmail.com.au>
|
||||||
|
---
|
||||||
|
Have not tested on variable erase regions device.
|
||||||
|
|
||||||
|
checkpatch does not like the printk(KERN_WARNING
|
||||||
|
these should be changed separately beforehand?
|
||||||
|
|
||||||
|
Changes RFC -> v1:
|
||||||
|
Fix uninitialized variable smatch warning
|
||||||
|
Reported-by: kernel test robot <lkp@intel.com>
|
||||||
|
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
|
||||||
|
---
|
||||||
|
drivers/mtd/mtdpart.c | 52 ++++++++++++++++++++++++++++---------
|
||||||
|
drivers/mtd/spi-nor/Kconfig | 10 +++++++
|
||||||
|
drivers/mtd/spi-nor/core.c | 10 +++++--
|
||||||
|
include/linux/mtd/mtd.h | 2 ++
|
||||||
|
4 files changed, 60 insertions(+), 14 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/mtd/mtdpart.c
|
||||||
|
+++ b/drivers/mtd/mtdpart.c
|
||||||
|
@@ -47,10 +47,11 @@ static struct mtd_info *allocate_partiti
|
||||||
|
struct mtd_info *master = mtd_get_master(parent);
|
||||||
|
int wr_alignment = (parent->flags & MTD_NO_ERASE) ?
|
||||||
|
master->writesize : master->erasesize;
|
||||||
|
+ int wr_alignment_minor = 0;
|
||||||
|
u64 parent_size = mtd_is_partition(parent) ?
|
||||||
|
parent->part.size : parent->size;
|
||||||
|
struct mtd_info *child;
|
||||||
|
- u32 remainder;
|
||||||
|
+ u32 remainder, remainder_minor;
|
||||||
|
char *name;
|
||||||
|
u64 tmp;
|
||||||
|
|
||||||
|
@@ -152,6 +153,7 @@ static struct mtd_info *allocate_partiti
|
||||||
|
int i, max = parent->numeraseregions;
|
||||||
|
u64 end = child->part.offset + child->part.size;
|
||||||
|
struct mtd_erase_region_info *regions = parent->eraseregions;
|
||||||
|
+ uint32_t erasesize_minor = child->erasesize;
|
||||||
|
|
||||||
|
/* Find the first erase regions which is part of this
|
||||||
|
* partition. */
|
||||||
|
@@ -162,15 +164,24 @@ static struct mtd_info *allocate_partiti
|
||||||
|
if (i > 0)
|
||||||
|
i--;
|
||||||
|
|
||||||
|
- /* Pick biggest erasesize */
|
||||||
|
for (; i < max && regions[i].offset < end; i++) {
|
||||||
|
+ /* Pick biggest erasesize */
|
||||||
|
if (child->erasesize < regions[i].erasesize)
|
||||||
|
child->erasesize = regions[i].erasesize;
|
||||||
|
+ /* Pick smallest non-zero erasesize */
|
||||||
|
+ if ((erasesize_minor > regions[i].erasesize) && (regions[i].erasesize > 0))
|
||||||
|
+ erasesize_minor = regions[i].erasesize;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ if (erasesize_minor < child->erasesize)
|
||||||
|
+ child->erasesize_minor = erasesize_minor;
|
||||||
|
+
|
||||||
|
BUG_ON(child->erasesize == 0);
|
||||||
|
} else {
|
||||||
|
/* Single erase size */
|
||||||
|
child->erasesize = master->erasesize;
|
||||||
|
+ if (master->erasesize_minor)
|
||||||
|
+ child->erasesize_minor = master->erasesize_minor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -178,26 +189,43 @@ static struct mtd_info *allocate_partiti
|
||||||
|
* exposes several regions with different erasesize. Adjust
|
||||||
|
* wr_alignment accordingly.
|
||||||
|
*/
|
||||||
|
- if (!(child->flags & MTD_NO_ERASE))
|
||||||
|
+ if (!(child->flags & MTD_NO_ERASE)) {
|
||||||
|
wr_alignment = child->erasesize;
|
||||||
|
+ if (IS_ENABLED(CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE) && child->erasesize_minor)
|
||||||
|
+ wr_alignment_minor = child->erasesize_minor;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
tmp = mtd_get_master_ofs(child, 0);
|
||||||
|
remainder = do_div(tmp, wr_alignment);
|
||||||
|
if ((child->flags & MTD_WRITEABLE) && remainder) {
|
||||||
|
- /* Doesn't start on a boundary of major erase size */
|
||||||
|
- /* FIXME: Let it be writable if it is on a boundary of
|
||||||
|
- * _minor_ erase size though */
|
||||||
|
- child->flags &= ~MTD_WRITEABLE;
|
||||||
|
- printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase/write block boundary -- force read-only\n",
|
||||||
|
- part->name);
|
||||||
|
+ if (wr_alignment_minor) {
|
||||||
|
+ tmp = mtd_get_master_ofs(child, 0);
|
||||||
|
+ remainder_minor = do_div(tmp, wr_alignment_minor);
|
||||||
|
+ if (remainder_minor == 0)
|
||||||
|
+ child->erasesize = child->erasesize_minor;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if ((!wr_alignment_minor) || (wr_alignment_minor && remainder_minor != 0)) {
|
||||||
|
+ child->flags &= ~MTD_WRITEABLE;
|
||||||
|
+ printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase/write block boundary -- force read-only\n",
|
||||||
|
+ part->name);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = mtd_get_master_ofs(child, 0) + child->part.size;
|
||||||
|
remainder = do_div(tmp, wr_alignment);
|
||||||
|
if ((child->flags & MTD_WRITEABLE) && remainder) {
|
||||||
|
- child->flags &= ~MTD_WRITEABLE;
|
||||||
|
- printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase/write block -- force read-only\n",
|
||||||
|
- part->name);
|
||||||
|
+ if (wr_alignment_minor) {
|
||||||
|
+ tmp = mtd_get_master_ofs(child, 0) + child->part.size;
|
||||||
|
+ remainder_minor = do_div(tmp, wr_alignment_minor);
|
||||||
|
+ if (remainder_minor == 0)
|
||||||
|
+ child->erasesize = child->erasesize_minor;
|
||||||
|
+ }
|
||||||
|
+ if ((!wr_alignment_minor) || (wr_alignment_minor && remainder_minor != 0)) {
|
||||||
|
+ child->flags &= ~MTD_WRITEABLE;
|
||||||
|
+ printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase/write block -- force read-only\n",
|
||||||
|
+ part->name);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
child->size = child->part.size;
|
||||||
|
--- a/drivers/mtd/spi-nor/Kconfig
|
||||||
|
+++ b/drivers/mtd/spi-nor/Kconfig
|
||||||
|
@@ -10,6 +10,16 @@ menuconfig MTD_SPI_NOR
|
||||||
|
|
||||||
|
if MTD_SPI_NOR
|
||||||
|
|
||||||
|
+config MTD_SPI_NOR_USE_VARIABLE_ERASE
|
||||||
|
+ bool "Disable uniform_erase to allow use of all hardware supported erasesizes"
|
||||||
|
+ depends on !MTD_SPI_NOR_USE_4K_SECTORS
|
||||||
|
+ default n
|
||||||
|
+ help
|
||||||
|
+ Allow mixed use of all hardware supported erasesizes,
|
||||||
|
+ by forcing spi_nor to use the multiple eraseregions code path.
|
||||||
|
+ For example: A 68K erase will use one 64K erase, and one 4K erase
|
||||||
|
+ on supporting hardware.
|
||||||
|
+
|
||||||
|
config MTD_SPI_NOR_USE_4K_SECTORS
|
||||||
|
bool "Use small 4096 B erase sectors"
|
||||||
|
default y
|
||||||
|
--- a/drivers/mtd/spi-nor/core.c
|
||||||
|
+++ b/drivers/mtd/spi-nor/core.c
|
||||||
|
@@ -1158,6 +1158,8 @@ static u8 spi_nor_convert_3to4_erase(u8
|
||||||
|
|
||||||
|
static bool spi_nor_has_uniform_erase(const struct spi_nor *nor)
|
||||||
|
{
|
||||||
|
+ if (IS_ENABLED(CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE))
|
||||||
|
+ return false;
|
||||||
|
return !!nor->params->erase_map.uniform_region.erase_mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2516,6 +2518,7 @@ static int spi_nor_select_erase(struct s
|
||||||
|
{
|
||||||
|
struct spi_nor_erase_map *map = &nor->params->erase_map;
|
||||||
|
const struct spi_nor_erase_type *erase = NULL;
|
||||||
|
+ const struct spi_nor_erase_type *erase_minor = NULL;
|
||||||
|
struct mtd_info *mtd = &nor->mtd;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
@@ -2542,8 +2545,9 @@ static int spi_nor_select_erase(struct s
|
||||||
|
*/
|
||||||
|
for (i = SNOR_ERASE_TYPE_MAX - 1; i >= 0; i--) {
|
||||||
|
if (map->erase_type[i].size) {
|
||||||
|
- erase = &map->erase_type[i];
|
||||||
|
- break;
|
||||||
|
+ if (!erase)
|
||||||
|
+ erase = &map->erase_type[i];
|
||||||
|
+ erase_minor = &map->erase_type[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2551,6 +2555,8 @@ static int spi_nor_select_erase(struct s
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
mtd->erasesize = erase->size;
|
||||||
|
+ if (erase_minor && erase_minor->size < erase->size)
|
||||||
|
+ mtd->erasesize_minor = erase_minor->size;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
--- a/include/linux/mtd/mtd.h
|
||||||
|
+++ b/include/linux/mtd/mtd.h
|
||||||
|
@@ -245,6 +245,8 @@ struct mtd_info {
|
||||||
|
* information below if they desire
|
||||||
|
*/
|
||||||
|
uint32_t erasesize;
|
||||||
|
+ /* "Minor" (smallest) erase size supported by the whole device */
|
||||||
|
+ uint32_t erasesize_minor;
|
||||||
|
/* Minimal writable flash unit size. In case of NOR flash it is 1 (even
|
||||||
|
* though individual bits can be cleared), in case of NAND flash it is
|
||||||
|
* one NAND page (or half, or one-fourths of it), in case of ECC-ed NOR
|
@ -0,0 +1,22 @@
|
|||||||
|
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||||
|
Subject: [PATCH] mtd: redboot: add of_match_table with DT binding
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
This allows parsing RedBoot compatible partitions for properly described
|
||||||
|
flash device in DT.
|
||||||
|
|
||||||
|
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/drivers/mtd/parsers/redboot.c
|
||||||
|
+++ b/drivers/mtd/parsers/redboot.c
|
||||||
|
@@ -305,6 +305,7 @@ nogood:
|
||||||
|
|
||||||
|
static const struct of_device_id mtd_parser_redboot_of_match_table[] = {
|
||||||
|
{ .compatible = "redboot-fis" },
|
||||||
|
+ { .compatible = "ecoscentric,redboot-fis-partitions" },
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, mtd_parser_redboot_of_match_table);
|
41
pending-6.12/420-mtd-redboot_space.patch
Normal file
41
pending-6.12/420-mtd-redboot_space.patch
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Subject: add patch for including unpartitioned space in the rootfs partition for redboot devices (if applicable)
|
||||||
|
|
||||||
|
[john@phrozen.org: used by ixp and others]
|
||||||
|
|
||||||
|
lede-commit: 394918851f84e4d00fa16eb900e7700e95091f00
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
drivers/mtd/redboot.c | 19 +++++++++++++------
|
||||||
|
1 file changed, 13 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/mtd/parsers/redboot.c
|
||||||
|
+++ b/drivers/mtd/parsers/redboot.c
|
||||||
|
@@ -278,14 +278,21 @@ nogood:
|
||||||
|
#endif
|
||||||
|
names += strlen(names) + 1;
|
||||||
|
|
||||||
|
-#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
|
||||||
|
if (fl->next && fl->img->flash_base + fl->img->size + master->erasesize <= fl->next->img->flash_base) {
|
||||||
|
- i++;
|
||||||
|
- parts[i].offset = parts[i - 1].size + parts[i - 1].offset;
|
||||||
|
- parts[i].size = fl->next->img->flash_base - parts[i].offset;
|
||||||
|
- parts[i].name = nullname;
|
||||||
|
- }
|
||||||
|
+ if (!strcmp(parts[i].name, "rootfs")) {
|
||||||
|
+ parts[i].size = fl->next->img->flash_base;
|
||||||
|
+ parts[i].size &= ~(master->erasesize - 1);
|
||||||
|
+ parts[i].size -= parts[i].offset;
|
||||||
|
+#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
|
||||||
|
+ nrparts--;
|
||||||
|
+ } else {
|
||||||
|
+ i++;
|
||||||
|
+ parts[i].offset = parts[i-1].size + parts[i-1].offset;
|
||||||
|
+ parts[i].size = fl->next->img->flash_base - parts[i].offset;
|
||||||
|
+ parts[i].name = nullname;
|
||||||
|
#endif
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
tmp_fl = fl;
|
||||||
|
fl = fl->next;
|
||||||
|
kfree(tmp_fl);
|
229
pending-6.12/430-mtd-add-myloader-partition-parser.patch
Normal file
229
pending-6.12/430-mtd-add-myloader-partition-parser.patch
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
From: Florian Fainelli <f.fainelli@gmail.com>
|
||||||
|
Subject: Add myloader partition table parser
|
||||||
|
|
||||||
|
[john@phozen.org: shoud be upstreamable]
|
||||||
|
|
||||||
|
lede-commit: d8bf22859b51faa09d22c056fe221a45d2f7a3b8
|
||||||
|
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
|
||||||
|
[adjust for kernel 5.4, add myloader.c to patch]
|
||||||
|
Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
|
||||||
|
|
||||||
|
--- a/drivers/mtd/parsers/Kconfig
|
||||||
|
+++ b/drivers/mtd/parsers/Kconfig
|
||||||
|
@@ -62,6 +62,22 @@ config MTD_CMDLINE_PARTS
|
||||||
|
|
||||||
|
If unsure, say 'N'.
|
||||||
|
|
||||||
|
+config MTD_MYLOADER_PARTS
|
||||||
|
+ tristate "MyLoader partition parsing"
|
||||||
|
+ depends on ADM5120 || ATH25 || ATH79
|
||||||
|
+ help
|
||||||
|
+ MyLoader is a bootloader which allows the user to define partitions
|
||||||
|
+ in flash devices, by putting a table in the second erase block
|
||||||
|
+ on the device, similar to a partition table. This table gives the
|
||||||
|
+ offsets and lengths of the user defined partitions.
|
||||||
|
+
|
||||||
|
+ If you need code which can detect and parse these tables, and
|
||||||
|
+ register MTD 'partitions' corresponding to each image detected,
|
||||||
|
+ enable this option.
|
||||||
|
+
|
||||||
|
+ You will still need the parsing functions to be called by the driver
|
||||||
|
+ for your particular device. It won't happen automatically.
|
||||||
|
+
|
||||||
|
config MTD_OF_PARTS
|
||||||
|
tristate "OpenFirmware (device tree) partitioning parser"
|
||||||
|
default y
|
||||||
|
--- a/drivers/mtd/parsers/Makefile
|
||||||
|
+++ b/drivers/mtd/parsers/Makefile
|
||||||
|
@@ -3,6 +3,7 @@ obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm4
|
||||||
|
obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o
|
||||||
|
obj-$(CONFIG_MTD_BRCM_U_BOOT) += brcm_u-boot.o
|
||||||
|
obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o
|
||||||
|
+obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o
|
||||||
|
obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o
|
||||||
|
ofpart-y += ofpart_core.o
|
||||||
|
ofpart-$(CONFIG_MTD_OF_PARTS_BCM4908) += ofpart_bcm4908.o
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/drivers/mtd/parsers/myloader.c
|
||||||
|
@@ -0,0 +1,181 @@
|
||||||
|
+/*
|
||||||
|
+ * Parse MyLoader-style flash partition tables and produce a Linux partition
|
||||||
|
+ * array to match.
|
||||||
|
+ *
|
||||||
|
+ * Copyright (C) 2007-2009 Gabor Juhos <juhosg@openwrt.org>
|
||||||
|
+ *
|
||||||
|
+ * This file was based on drivers/mtd/redboot.c
|
||||||
|
+ * Author: Red Hat, Inc. - David Woodhouse <dwmw2@cambridge.redhat.com>
|
||||||
|
+ *
|
||||||
|
+ * 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.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <linux/kernel.h>
|
||||||
|
+#include <linux/module.h>
|
||||||
|
+#include <linux/version.h>
|
||||||
|
+#include <linux/slab.h>
|
||||||
|
+#include <linux/init.h>
|
||||||
|
+#include <linux/vmalloc.h>
|
||||||
|
+#include <linux/mtd/mtd.h>
|
||||||
|
+#include <linux/mtd/partitions.h>
|
||||||
|
+#include <linux/byteorder/generic.h>
|
||||||
|
+#include <linux/myloader.h>
|
||||||
|
+
|
||||||
|
+#define BLOCK_LEN_MIN 0x10000
|
||||||
|
+#define PART_NAME_LEN 32
|
||||||
|
+
|
||||||
|
+struct part_data {
|
||||||
|
+ struct mylo_partition_table tab;
|
||||||
|
+ char names[MYLO_MAX_PARTITIONS][PART_NAME_LEN];
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int myloader_parse_partitions(struct mtd_info *master,
|
||||||
|
+ const struct mtd_partition **pparts,
|
||||||
|
+ struct mtd_part_parser_data *data)
|
||||||
|
+{
|
||||||
|
+ struct part_data *buf;
|
||||||
|
+ struct mylo_partition_table *tab;
|
||||||
|
+ struct mylo_partition *part;
|
||||||
|
+ struct mtd_partition *mtd_parts;
|
||||||
|
+ struct mtd_partition *mtd_part;
|
||||||
|
+ int num_parts;
|
||||||
|
+ int ret, i;
|
||||||
|
+ size_t retlen;
|
||||||
|
+ char *names;
|
||||||
|
+ unsigned long offset;
|
||||||
|
+ unsigned long blocklen;
|
||||||
|
+
|
||||||
|
+ buf = vmalloc(sizeof(*buf));
|
||||||
|
+ if (!buf) {
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+ tab = &buf->tab;
|
||||||
|
+
|
||||||
|
+ blocklen = master->erasesize;
|
||||||
|
+ if (blocklen < BLOCK_LEN_MIN)
|
||||||
|
+ blocklen = BLOCK_LEN_MIN;
|
||||||
|
+
|
||||||
|
+ offset = blocklen;
|
||||||
|
+
|
||||||
|
+ /* Find the partition table */
|
||||||
|
+ for (i = 0; i < 4; i++, offset += blocklen) {
|
||||||
|
+ printk(KERN_DEBUG "%s: searching for MyLoader partition table"
|
||||||
|
+ " at offset 0x%lx\n", master->name, offset);
|
||||||
|
+
|
||||||
|
+ ret = mtd_read(master, offset, sizeof(*buf), &retlen,
|
||||||
|
+ (void *)buf);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto out_free_buf;
|
||||||
|
+
|
||||||
|
+ if (retlen != sizeof(*buf)) {
|
||||||
|
+ ret = -EIO;
|
||||||
|
+ goto out_free_buf;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Check for Partition Table magic number */
|
||||||
|
+ if (tab->magic == le32_to_cpu(MYLO_MAGIC_PARTITIONS))
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (tab->magic != le32_to_cpu(MYLO_MAGIC_PARTITIONS)) {
|
||||||
|
+ printk(KERN_DEBUG "%s: no MyLoader partition table found\n",
|
||||||
|
+ master->name);
|
||||||
|
+ ret = 0;
|
||||||
|
+ goto out_free_buf;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* The MyLoader and the Partition Table is always present */
|
||||||
|
+ num_parts = 2;
|
||||||
|
+
|
||||||
|
+ /* Detect number of used partitions */
|
||||||
|
+ for (i = 0; i < MYLO_MAX_PARTITIONS; i++) {
|
||||||
|
+ part = &tab->partitions[i];
|
||||||
|
+
|
||||||
|
+ if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ num_parts++;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ mtd_parts = kzalloc((num_parts * sizeof(*mtd_part) +
|
||||||
|
+ num_parts * PART_NAME_LEN), GFP_KERNEL);
|
||||||
|
+
|
||||||
|
+ if (!mtd_parts) {
|
||||||
|
+ ret = -ENOMEM;
|
||||||
|
+ goto out_free_buf;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ mtd_part = mtd_parts;
|
||||||
|
+ names = (char *)&mtd_parts[num_parts];
|
||||||
|
+
|
||||||
|
+ strncpy(names, "myloader", PART_NAME_LEN);
|
||||||
|
+ mtd_part->name = names;
|
||||||
|
+ mtd_part->offset = 0;
|
||||||
|
+ mtd_part->size = offset;
|
||||||
|
+ mtd_part->mask_flags = MTD_WRITEABLE;
|
||||||
|
+ mtd_part++;
|
||||||
|
+ names += PART_NAME_LEN;
|
||||||
|
+
|
||||||
|
+ strncpy(names, "partition_table", PART_NAME_LEN);
|
||||||
|
+ mtd_part->name = names;
|
||||||
|
+ mtd_part->offset = offset;
|
||||||
|
+ mtd_part->size = blocklen;
|
||||||
|
+ mtd_part->mask_flags = MTD_WRITEABLE;
|
||||||
|
+ mtd_part++;
|
||||||
|
+ names += PART_NAME_LEN;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < MYLO_MAX_PARTITIONS; i++) {
|
||||||
|
+ part = &tab->partitions[i];
|
||||||
|
+
|
||||||
|
+ if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ if ((buf->names[i][0]) && (buf->names[i][0] != '\xff'))
|
||||||
|
+ strncpy(names, buf->names[i], PART_NAME_LEN);
|
||||||
|
+ else
|
||||||
|
+ snprintf(names, PART_NAME_LEN, "partition%d", i);
|
||||||
|
+
|
||||||
|
+ mtd_part->offset = le32_to_cpu(part->addr);
|
||||||
|
+ mtd_part->size = le32_to_cpu(part->size);
|
||||||
|
+ mtd_part->name = names;
|
||||||
|
+ mtd_part++;
|
||||||
|
+ names += PART_NAME_LEN;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *pparts = mtd_parts;
|
||||||
|
+ ret = num_parts;
|
||||||
|
+
|
||||||
|
+ out_free_buf:
|
||||||
|
+ vfree(buf);
|
||||||
|
+ out:
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct mtd_part_parser myloader_mtd_parser = {
|
||||||
|
+ .owner = THIS_MODULE,
|
||||||
|
+ .parse_fn = myloader_parse_partitions,
|
||||||
|
+ .name = "MyLoader",
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int __init myloader_mtd_parser_init(void)
|
||||||
|
+{
|
||||||
|
+ register_mtd_parser(&myloader_mtd_parser);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void __exit myloader_mtd_parser_exit(void)
|
||||||
|
+{
|
||||||
|
+ deregister_mtd_parser(&myloader_mtd_parser);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+module_init(myloader_mtd_parser_init);
|
||||||
|
+module_exit(myloader_mtd_parser_exit);
|
||||||
|
+
|
||||||
|
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
|
||||||
|
+MODULE_DESCRIPTION("Parsing code for MyLoader partition tables");
|
||||||
|
+MODULE_LICENSE("GPL v2");
|
@ -0,0 +1,68 @@
|
|||||||
|
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
|
||||||
|
Subject: [PATCH] mtd: bcm47xxpart: check for bad blocks when calculating offsets
|
||||||
|
|
||||||
|
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/drivers/mtd/parsers/parser_trx.c
|
||||||
|
+++ b/drivers/mtd/parsers/parser_trx.c
|
||||||
|
@@ -25,6 +25,33 @@ struct trx_header {
|
||||||
|
uint32_t offset[3];
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Calculate real end offset (address) for a given amount of data. It checks
|
||||||
|
+ * all blocks skipping bad ones.
|
||||||
|
+ */
|
||||||
|
+static size_t parser_trx_real_offset(struct mtd_info *mtd, size_t bytes)
|
||||||
|
+{
|
||||||
|
+ size_t real_offset = 0;
|
||||||
|
+
|
||||||
|
+ if (mtd_block_isbad(mtd, real_offset))
|
||||||
|
+ pr_warn("Base offset shouldn't be at bad block");
|
||||||
|
+
|
||||||
|
+ while (bytes >= mtd->erasesize) {
|
||||||
|
+ bytes -= mtd->erasesize;
|
||||||
|
+ real_offset += mtd->erasesize;
|
||||||
|
+ while (mtd_block_isbad(mtd, real_offset)) {
|
||||||
|
+ real_offset += mtd->erasesize;
|
||||||
|
+
|
||||||
|
+ if (real_offset >= mtd->size)
|
||||||
|
+ return real_offset - mtd->erasesize;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ real_offset += bytes;
|
||||||
|
+
|
||||||
|
+ return real_offset;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static const char *parser_trx_data_part_name(struct mtd_info *master,
|
||||||
|
size_t offset)
|
||||||
|
{
|
||||||
|
@@ -86,21 +113,21 @@ static int parser_trx_parse(struct mtd_i
|
||||||
|
if (trx.offset[2]) {
|
||||||
|
part = &parts[curr_part++];
|
||||||
|
part->name = "loader";
|
||||||
|
- part->offset = trx.offset[i];
|
||||||
|
+ part->offset = parser_trx_real_offset(mtd, trx.offset[i]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trx.offset[i]) {
|
||||||
|
part = &parts[curr_part++];
|
||||||
|
part->name = "linux";
|
||||||
|
- part->offset = trx.offset[i];
|
||||||
|
+ part->offset = parser_trx_real_offset(mtd, trx.offset[i]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trx.offset[i]) {
|
||||||
|
part = &parts[curr_part++];
|
||||||
|
- part->name = parser_trx_data_part_name(mtd, trx.offset[i]);
|
||||||
|
- part->offset = trx.offset[i];
|
||||||
|
+ part->offset = parser_trx_real_offset(mtd, trx.offset[i]);
|
||||||
|
+ part->name = parser_trx_data_part_name(mtd, part->offset);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
|||||||
|
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
|
||||||
|
Subject: mtd: bcm47xxpart: detect T_Meter partition
|
||||||
|
|
||||||
|
It can be found on many Netgear devices. It consists of many 0x30 blocks
|
||||||
|
starting with 4D 54.
|
||||||
|
|
||||||
|
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
|
||||||
|
---
|
||||||
|
drivers/mtd/bcm47xxpart.c | 10 ++++++++++
|
||||||
|
1 file changed, 10 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/mtd/parsers/bcm47xxpart.c
|
||||||
|
+++ b/drivers/mtd/parsers/bcm47xxpart.c
|
||||||
|
@@ -35,6 +35,7 @@
|
||||||
|
#define NVRAM_HEADER 0x48534C46 /* FLSH */
|
||||||
|
#define POT_MAGIC1 0x54544f50 /* POTT */
|
||||||
|
#define POT_MAGIC2 0x504f /* OP */
|
||||||
|
+#define T_METER_MAGIC 0x4D540000 /* MT */
|
||||||
|
#define ML_MAGIC1 0x39685a42
|
||||||
|
#define ML_MAGIC2 0x26594131
|
||||||
|
#define TRX_MAGIC 0x30524448
|
||||||
|
@@ -178,6 +179,15 @@ static int bcm47xxpart_parse(struct mtd_
|
||||||
|
MTD_WRITEABLE);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ /* T_Meter */
|
||||||
|
+ if ((le32_to_cpu(buf[0x000 / 4]) & 0xFFFF0000) == T_METER_MAGIC &&
|
||||||
|
+ (le32_to_cpu(buf[0x030 / 4]) & 0xFFFF0000) == T_METER_MAGIC &&
|
||||||
|
+ (le32_to_cpu(buf[0x060 / 4]) & 0xFFFF0000) == T_METER_MAGIC) {
|
||||||
|
+ bcm47xxpart_add_part(&parts[curr_part++], "T_Meter", offset,
|
||||||
|
+ MTD_WRITEABLE);
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/* TRX */
|
||||||
|
if (buf[0x000 / 4] == TRX_MAGIC) {
|
38
pending-6.12/435-mtd-add-routerbootpart-parser-config.patch
Normal file
38
pending-6.12/435-mtd-add-routerbootpart-parser-config.patch
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
From 4437e01fb6bca63fccdba5d6c44888b0935885c2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Thibaut=20VAR=C3=88NE?= <hacks@slashdirt.org>
|
||||||
|
Date: Tue, 24 Mar 2020 11:45:07 +0100
|
||||||
|
Subject: [PATCH] generic: routerboot partition build bits (5.4)
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
This patch adds routerbootpart kernel build bits
|
||||||
|
|
||||||
|
Signed-off-by: Thibaut VARÈNE <hacks@slashdirt.org>
|
||||||
|
---
|
||||||
|
drivers/mtd/parsers/Kconfig | 9 +++++++++
|
||||||
|
drivers/mtd/parsers/Makefile | 1 +
|
||||||
|
2 files changed, 10 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/mtd/parsers/Kconfig
|
||||||
|
+++ b/drivers/mtd/parsers/Kconfig
|
||||||
|
@@ -231,3 +231,12 @@ config MTD_SERCOMM_PARTS
|
||||||
|
partition map. This partition table contains real partition
|
||||||
|
offsets, which may differ from device to device depending on the
|
||||||
|
number and location of bad blocks on NAND.
|
||||||
|
+
|
||||||
|
+config MTD_ROUTERBOOT_PARTS
|
||||||
|
+ tristate "RouterBoot flash partition parser"
|
||||||
|
+ depends on MTD && OF
|
||||||
|
+ help
|
||||||
|
+ MikroTik RouterBoot is implemented as a multi segment system on the
|
||||||
|
+ flash, some of which are fixed and some of which are located at
|
||||||
|
+ variable offsets. This parser handles both cases via properly
|
||||||
|
+ formatted DTS.
|
||||||
|
--- a/drivers/mtd/parsers/Makefile
|
||||||
|
+++ b/drivers/mtd/parsers/Makefile
|
||||||
|
@@ -16,3 +16,4 @@ obj-$(CONFIG_MTD_SERCOMM_PARTS) += scpa
|
||||||
|
obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o
|
||||||
|
obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o
|
||||||
|
obj-$(CONFIG_MTD_QCOMSMEM_PARTS) += qcomsmempart.o
|
||||||
|
+obj-$(CONFIG_MTD_ROUTERBOOT_PARTS) += routerbootpart.o
|
25
pending-6.12/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch
Normal file
25
pending-6.12/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Subject: kernel: disable cfi cmdset 0002 erase suspend
|
||||||
|
|
||||||
|
on some platforms, erase suspend leads to data corruption and lockups when write
|
||||||
|
ops collide with erase ops. this has been observed on the buffalo wzr-hp-g300nh.
|
||||||
|
rather than play whack-a-mole with a hard to reproduce issue on a variety of devices,
|
||||||
|
simply disable erase suspend, as it will usually not produce any useful gain on
|
||||||
|
the small filesystems used on embedded hardware.
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
drivers/mtd/chips/cfi_cmdset_0002.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
|
||||||
|
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
|
||||||
|
@@ -906,7 +906,7 @@ static int get_chip(struct map_info *map
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case FL_ERASING:
|
||||||
|
- if (!cfip || !(cfip->EraseSuspend & (0x1|0x2)) ||
|
||||||
|
+ if (1 /* no suspend */ || !cfip || !(cfip->EraseSuspend & (0x1|0x2)) ||
|
||||||
|
!(mode == FL_READY || mode == FL_POINT ||
|
||||||
|
(mode == FL_WRITING && (cfip->EraseSuspend & 0x2))))
|
||||||
|
goto sleep;
|
@ -0,0 +1,17 @@
|
|||||||
|
From: George Kashperko <george@znau.edu.ua>
|
||||||
|
Subject: Issue map read after Write Buffer Load command to ensure chip is ready to receive data.
|
||||||
|
|
||||||
|
Signed-off-by: George Kashperko <george@znau.edu.ua>
|
||||||
|
---
|
||||||
|
drivers/mtd/chips/cfi_cmdset_0002.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
|
||||||
|
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
|
||||||
|
@@ -2050,6 +2050,7 @@ static int __xipram do_write_buffer(stru
|
||||||
|
|
||||||
|
/* Write Buffer Load */
|
||||||
|
map_write(map, CMD(0x25), cmd_adr);
|
||||||
|
+ (void) map_read(map, cmd_adr);
|
||||||
|
|
||||||
|
chip->state = FL_WRITING_TO_BUFFER;
|
||||||
|
|
18
pending-6.12/465-m25p80-mx-disable-software-protection.patch
Normal file
18
pending-6.12/465-m25p80-mx-disable-software-protection.patch
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Subject: Disable software protection bits for Macronix flashes.
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
drivers/mtd/spi-nor/spi-nor.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
--- a/drivers/mtd/spi-nor/macronix.c
|
||||||
|
+++ b/drivers/mtd/spi-nor/macronix.c
|
||||||
|
@@ -194,6 +194,7 @@ static int macronix_nor_late_init(struct
|
||||||
|
{
|
||||||
|
if (!nor->params->set_4byte_addr_mode)
|
||||||
|
nor->params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode_en4b_ex4b;
|
||||||
|
+ nor->flags |= SNOR_F_HAS_LOCK;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,104 @@
|
|||||||
|
From: Daniel Golle <daniel@makrotopia.org>
|
||||||
|
Subject: ubi: auto-attach mtd device named "ubi" or "data" on boot
|
||||||
|
|
||||||
|
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||||
|
---
|
||||||
|
drivers/mtd/ubi/build.c | 36 ++++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 36 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/mtd/ubi/build.c
|
||||||
|
+++ b/drivers/mtd/ubi/build.c
|
||||||
|
@@ -1263,6 +1263,80 @@ static struct mtd_notifier ubi_mtd_notif
|
||||||
|
.remove = ubi_notify_remove,
|
||||||
|
};
|
||||||
|
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * This function tries attaching mtd partitions named either "ubi" or "data"
|
||||||
|
+ * during boot.
|
||||||
|
+ */
|
||||||
|
+static void __init ubi_auto_attach(void)
|
||||||
|
+{
|
||||||
|
+ int err;
|
||||||
|
+ struct mtd_info *mtd;
|
||||||
|
+ struct device_node *np;
|
||||||
|
+ loff_t offset = 0;
|
||||||
|
+ size_t len;
|
||||||
|
+ char magic[4];
|
||||||
|
+
|
||||||
|
+ /* try attaching mtd device named "ubi" or "data" */
|
||||||
|
+ mtd = open_mtd_device("ubi");
|
||||||
|
+ if (IS_ERR(mtd))
|
||||||
|
+ mtd = open_mtd_device("data");
|
||||||
|
+
|
||||||
|
+ if (IS_ERR(mtd))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ /* skip "linux,ubi" mtd as it has already been attached */
|
||||||
|
+ np = mtd_get_of_node(mtd);
|
||||||
|
+ if (of_device_is_compatible(np, "linux,ubi"))
|
||||||
|
+ goto cleanup;
|
||||||
|
+
|
||||||
|
+ /* get the first not bad block */
|
||||||
|
+ if (mtd_can_have_bb(mtd))
|
||||||
|
+ while (mtd_block_isbad(mtd, offset)) {
|
||||||
|
+ offset += mtd->erasesize;
|
||||||
|
+
|
||||||
|
+ if (offset > mtd->size) {
|
||||||
|
+ pr_err("UBI error: Failed to find a non-bad "
|
||||||
|
+ "block on mtd%d\n", mtd->index);
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* check if the read from flash was successful */
|
||||||
|
+ err = mtd_read(mtd, offset, 4, &len, (void *) magic);
|
||||||
|
+ if ((err && !mtd_is_bitflip(err)) || len != 4) {
|
||||||
|
+ pr_err("UBI error: unable to read from mtd%d\n", mtd->index);
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* check for a valid ubi magic */
|
||||||
|
+ if (strncmp(magic, "UBI#", 4)) {
|
||||||
|
+ pr_err("UBI error: no valid UBI magic found inside mtd%d\n", mtd->index);
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* don't auto-add media types where UBI doesn't makes sense */
|
||||||
|
+ if (mtd->type != MTD_NANDFLASH &&
|
||||||
|
+ mtd->type != MTD_NORFLASH &&
|
||||||
|
+ mtd->type != MTD_DATAFLASH &&
|
||||||
|
+ mtd->type != MTD_MLCNANDFLASH)
|
||||||
|
+ goto cleanup;
|
||||||
|
+
|
||||||
|
+ mutex_lock(&ubi_devices_mutex);
|
||||||
|
+ pr_notice("UBI: auto-attach mtd%d\n", mtd->index);
|
||||||
|
+ err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, 0, 0, false, false);
|
||||||
|
+ mutex_unlock(&ubi_devices_mutex);
|
||||||
|
+ if (err < 0) {
|
||||||
|
+ pr_err("UBI error: cannot attach mtd%d\n", mtd->index);
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+cleanup:
|
||||||
|
+ put_mtd_device(mtd);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int __init ubi_init_attach(void)
|
||||||
|
{
|
||||||
|
int err, i, k;
|
||||||
|
@@ -1314,6 +1388,12 @@ static int __init ubi_init_attach(void)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* auto-attach mtd devices only if built-in to the kernel and no ubi.mtd
|
||||||
|
+ * parameter was given */
|
||||||
|
+ if (IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) &&
|
||||||
|
+ !ubi_is_module() && !mtd_devs)
|
||||||
|
+ ubi_auto_attach();
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
out_detach:
|
@ -0,0 +1,77 @@
|
|||||||
|
From: Daniel Golle <daniel@makrotopia.org>
|
||||||
|
Subject: ubi: auto-create ubiblock device for rootfs
|
||||||
|
|
||||||
|
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||||
|
---
|
||||||
|
drivers/mtd/ubi/block.c | 42 ++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 42 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/mtd/ubi/block.c
|
||||||
|
+++ b/drivers/mtd/ubi/block.c
|
||||||
|
@@ -575,10 +575,47 @@ match_volume_desc(struct ubi_volume_info
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#define UBIFS_NODE_MAGIC 0x06101831
|
||||||
|
+static inline int ubi_vol_is_ubifs(struct ubi_volume_desc *desc)
|
||||||
|
+{
|
||||||
|
+ int ret;
|
||||||
|
+ uint32_t magic_of, magic;
|
||||||
|
+ ret = ubi_read(desc, 0, (char *)&magic_of, 0, 4);
|
||||||
|
+ if (ret)
|
||||||
|
+ return 0;
|
||||||
|
+ magic = le32_to_cpu(magic_of);
|
||||||
|
+ return magic == UBIFS_NODE_MAGIC;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void __init ubiblock_create_auto_rootfs(struct ubi_volume_info *vi)
|
||||||
|
+{
|
||||||
|
+ int ret, is_ubifs;
|
||||||
|
+ struct ubi_volume_desc *desc;
|
||||||
|
+
|
||||||
|
+ if (strcmp(vi->name, "rootfs") &&
|
||||||
|
+ strcmp(vi->name, "fit"))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ desc = ubi_open_volume(vi->ubi_num, vi->vol_id, UBI_READONLY);
|
||||||
|
+ if (IS_ERR(desc))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ is_ubifs = ubi_vol_is_ubifs(desc);
|
||||||
|
+ ubi_close_volume(desc);
|
||||||
|
+ if (is_ubifs)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ ret = ubiblock_create(vi);
|
||||||
|
+ if (ret)
|
||||||
|
+ pr_err("UBI error: block: can't add '%s' volume, err=%d\n",
|
||||||
|
+ vi->name, ret);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void
|
||||||
|
ubiblock_create_from_param(struct ubi_volume_info *vi)
|
||||||
|
{
|
||||||
|
int i, ret = 0;
|
||||||
|
+ bool got_param = false;
|
||||||
|
struct ubiblock_param *p;
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -591,6 +628,7 @@ ubiblock_create_from_param(struct ubi_vo
|
||||||
|
if (!match_volume_desc(vi, p->name, p->ubi_num, p->vol_id))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
+ got_param = true;
|
||||||
|
ret = ubiblock_create(vi);
|
||||||
|
if (ret) {
|
||||||
|
pr_err(
|
||||||
|
@@ -599,6 +637,10 @@ ubiblock_create_from_param(struct ubi_vo
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ /* auto-attach "rootfs" volume if existing and non-ubifs */
|
||||||
|
+ if (!got_param && IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV))
|
||||||
|
+ ubiblock_create_auto_rootfs(vi);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ubiblock_notify(struct notifier_block *nb,
|
@ -0,0 +1,34 @@
|
|||||||
|
From: Daniel Golle <daniel@makrotopia.org>
|
||||||
|
Subject: ubi: set ROOT_DEV to ubiblock "rootfs" if unset
|
||||||
|
|
||||||
|
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||||
|
---
|
||||||
|
drivers/mtd/ubi/block.c | 10 ++++++++++
|
||||||
|
1 file changed, 10 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/mtd/ubi/block.c
|
||||||
|
+++ b/drivers/mtd/ubi/block.c
|
||||||
|
@@ -41,6 +41,7 @@
|
||||||
|
#include <linux/scatterlist.h>
|
||||||
|
#include <linux/idr.h>
|
||||||
|
#include <asm/div64.h>
|
||||||
|
+#include <linux/root_dev.h>
|
||||||
|
|
||||||
|
#include "ubi-media.h"
|
||||||
|
#include "ubi.h"
|
||||||
|
@@ -431,6 +432,15 @@ int ubiblock_create(struct ubi_volume_in
|
||||||
|
dev_info(disk_to_dev(dev->gd), "created from ubi%d:%d(%s)",
|
||||||
|
dev->ubi_num, dev->vol_id, vi->name);
|
||||||
|
mutex_unlock(&devices_mutex);
|
||||||
|
+
|
||||||
|
+ if (!strcmp(vi->name, "rootfs") &&
|
||||||
|
+ IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) &&
|
||||||
|
+ ROOT_DEV == 0) {
|
||||||
|
+ pr_notice("ubiblock: device ubiblock%d_%d (%s) set to be root filesystem\n",
|
||||||
|
+ dev->ubi_num, dev->vol_id, vi->name);
|
||||||
|
+ ROOT_DEV = MKDEV(gd->major, gd->first_minor);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
out_remove_minor:
|
60
pending-6.12/494-mtd-ubi-add-EOF-marker-support.patch
Normal file
60
pending-6.12/494-mtd-ubi-add-EOF-marker-support.patch
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
From: Gabor Juhos <juhosg@openwrt.org>
|
||||||
|
Subject: mtd: add EOF marker support to the UBI layer
|
||||||
|
|
||||||
|
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
|
||||||
|
---
|
||||||
|
drivers/mtd/ubi/attach.c | 25 ++++++++++++++++++++++---
|
||||||
|
drivers/mtd/ubi/ubi.h | 1 +
|
||||||
|
2 files changed, 23 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/mtd/ubi/attach.c
|
||||||
|
+++ b/drivers/mtd/ubi/attach.c
|
||||||
|
@@ -926,6 +926,13 @@ static bool vol_ignored(int vol_id)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
+static bool ec_hdr_has_eof(struct ubi_ec_hdr *ech)
|
||||||
|
+{
|
||||||
|
+ return ech->padding1[0] == 'E' &&
|
||||||
|
+ ech->padding1[1] == 'O' &&
|
||||||
|
+ ech->padding1[2] == 'F';
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* scan_peb - scan and process UBI headers of a PEB.
|
||||||
|
* @ubi: UBI device description object
|
||||||
|
@@ -958,9 +965,21 @@ static int scan_peb(struct ubi_device *u
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0);
|
||||||
|
- if (err < 0)
|
||||||
|
- return err;
|
||||||
|
+ if (!ai->eof_found) {
|
||||||
|
+ err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0);
|
||||||
|
+ if (err < 0)
|
||||||
|
+ return err;
|
||||||
|
+
|
||||||
|
+ if (ec_hdr_has_eof(ech)) {
|
||||||
|
+ pr_notice("UBI: EOF marker found, PEBs from %d will be erased\n",
|
||||||
|
+ pnum);
|
||||||
|
+ ai->eof_found = true;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (ai->eof_found)
|
||||||
|
+ err = UBI_IO_FF_BITFLIPS;
|
||||||
|
+
|
||||||
|
switch (err) {
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
--- a/drivers/mtd/ubi/ubi.h
|
||||||
|
+++ b/drivers/mtd/ubi/ubi.h
|
||||||
|
@@ -778,6 +778,7 @@ struct ubi_attach_info {
|
||||||
|
int mean_ec;
|
||||||
|
uint64_t ec_sum;
|
||||||
|
int ec_count;
|
||||||
|
+ bool eof_found;
|
||||||
|
struct kmem_cache *aeb_slab_cache;
|
||||||
|
struct ubi_ec_hdr *ech;
|
||||||
|
struct ubi_vid_io_buf *vidb;
|
75
pending-6.12/495-mtd-core-add-get_mtd_device_by_node.patch
Normal file
75
pending-6.12/495-mtd-core-add-get_mtd_device_by_node.patch
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
From 1bd1b740f208d1cf4071932cc51860d37266c402 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Bernhard Frauendienst <kernel@nospam.obeliks.de>
|
||||||
|
Date: Sat, 1 Sep 2018 00:30:11 +0200
|
||||||
|
Subject: [PATCH 495/497] mtd: core: add get_mtd_device_by_node
|
||||||
|
|
||||||
|
Add function to retrieve a mtd device by its OF node. Since drivers can
|
||||||
|
assign arbitrary names to mtd devices in the absence of a label
|
||||||
|
property, there is no other reliable way to retrieve a mtd device for a
|
||||||
|
given OF node.
|
||||||
|
|
||||||
|
Signed-off-by: Bernhard Frauendienst <kernel@nospam.obeliks.de>
|
||||||
|
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||||
|
---
|
||||||
|
drivers/mtd/mtdcore.c | 38 ++++++++++++++++++++++++++++++++++++++
|
||||||
|
include/linux/mtd/mtd.h | 2 ++
|
||||||
|
2 files changed, 40 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/mtd/mtdcore.c
|
||||||
|
+++ b/drivers/mtd/mtdcore.c
|
||||||
|
@@ -1334,6 +1334,44 @@ out_unlock:
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(get_mtd_device_nm);
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * get_mtd_device_by_node - obtain a validated handle for an MTD device
|
||||||
|
+ * by of_node
|
||||||
|
+ * @of_node: OF node of MTD device to open
|
||||||
|
+ *
|
||||||
|
+ * This function returns MTD device description structure in case of
|
||||||
|
+ * success and an error code in case of failure.
|
||||||
|
+ */
|
||||||
|
+struct mtd_info *get_mtd_device_by_node(const struct device_node *of_node)
|
||||||
|
+{
|
||||||
|
+ int err = -ENODEV;
|
||||||
|
+ struct mtd_info *mtd = NULL, *other;
|
||||||
|
+
|
||||||
|
+ mutex_lock(&mtd_table_mutex);
|
||||||
|
+
|
||||||
|
+ mtd_for_each_device(other) {
|
||||||
|
+ if (of_node == other->dev.of_node) {
|
||||||
|
+ mtd = other;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!mtd)
|
||||||
|
+ goto out_unlock;
|
||||||
|
+
|
||||||
|
+ err = __get_mtd_device(mtd);
|
||||||
|
+ if (err)
|
||||||
|
+ goto out_unlock;
|
||||||
|
+
|
||||||
|
+ mutex_unlock(&mtd_table_mutex);
|
||||||
|
+ return mtd;
|
||||||
|
+
|
||||||
|
+out_unlock:
|
||||||
|
+ mutex_unlock(&mtd_table_mutex);
|
||||||
|
+ return ERR_PTR(err);
|
||||||
|
+}
|
||||||
|
+EXPORT_SYMBOL_GPL(get_mtd_device_by_node);
|
||||||
|
+
|
||||||
|
void put_mtd_device(struct mtd_info *mtd)
|
||||||
|
{
|
||||||
|
mutex_lock(&mtd_table_mutex);
|
||||||
|
--- a/include/linux/mtd/mtd.h
|
||||||
|
+++ b/include/linux/mtd/mtd.h
|
||||||
|
@@ -706,6 +706,8 @@ extern int __get_mtd_device(struct mtd_i
|
||||||
|
extern void __put_mtd_device(struct mtd_info *mtd);
|
||||||
|
extern struct mtd_info *of_get_mtd_device_by_node(struct device_node *np);
|
||||||
|
extern struct mtd_info *get_mtd_device_nm(const char *name);
|
||||||
|
+extern struct mtd_info *get_mtd_device_by_node(
|
||||||
|
+ const struct device_node *of_node);
|
||||||
|
extern void put_mtd_device(struct mtd_info *mtd);
|
||||||
|
|
||||||
|
static inline uint64_t mtdpart_get_offset(const struct mtd_info *mtd)
|
@ -0,0 +1,52 @@
|
|||||||
|
From 5734c6669fba7ddb5ef491ccff7159d15dba0b59 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Bernhard Frauendienst <kernel@nospam.obeliks.de>
|
||||||
|
Date: Wed, 5 Sep 2018 01:32:51 +0200
|
||||||
|
Subject: [PATCH 496/497] dt-bindings: add bindings for mtd-concat devices
|
||||||
|
|
||||||
|
Document virtual mtd-concat device bindings.
|
||||||
|
|
||||||
|
Signed-off-by: Bernhard Frauendienst <kernel@nospam.obeliks.de>
|
||||||
|
---
|
||||||
|
.../devicetree/bindings/mtd/mtd-concat.txt | 36 +++++++++++++++++++
|
||||||
|
1 file changed, 36 insertions(+)
|
||||||
|
create mode 100644 Documentation/devicetree/bindings/mtd/mtd-concat.txt
|
||||||
|
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/Documentation/devicetree/bindings/mtd/mtd-concat.txt
|
||||||
|
@@ -0,0 +1,36 @@
|
||||||
|
+Virtual MTD concat device
|
||||||
|
+
|
||||||
|
+Requires properties:
|
||||||
|
+- devices: list of phandles to mtd nodes that should be concatenated
|
||||||
|
+
|
||||||
|
+Example:
|
||||||
|
+
|
||||||
|
+&spi {
|
||||||
|
+ flash0: flash@0 {
|
||||||
|
+ ...
|
||||||
|
+ };
|
||||||
|
+ flash1: flash@1 {
|
||||||
|
+ ...
|
||||||
|
+ };
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+flash {
|
||||||
|
+ compatible = "mtd-concat";
|
||||||
|
+
|
||||||
|
+ devices = <&flash0 &flash1>;
|
||||||
|
+
|
||||||
|
+ partitions {
|
||||||
|
+ compatible = "fixed-partitions";
|
||||||
|
+
|
||||||
|
+ partition@0 {
|
||||||
|
+ label = "boot";
|
||||||
|
+ reg = <0x0000000 0x0040000>;
|
||||||
|
+ read-only;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ partition@40000 {
|
||||||
|
+ label = "firmware";
|
||||||
|
+ reg = <0x0040000 0x1fc0000>;
|
||||||
|
+ };
|
||||||
|
+ }
|
||||||
|
+}
|
@ -0,0 +1,216 @@
|
|||||||
|
From e53f712d8eac71f54399b61038ccf87d2cee99d7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Bernhard Frauendienst <kernel@nospam.obeliks.de>
|
||||||
|
Date: Sat, 25 Aug 2018 12:35:22 +0200
|
||||||
|
Subject: [PATCH 497/497] mtd: mtdconcat: add dt driver for concat devices
|
||||||
|
|
||||||
|
Some mtd drivers like physmap variants have support for concatenating
|
||||||
|
multiple mtd devices, but there is no generic way to define such a
|
||||||
|
concat device from within the device tree.
|
||||||
|
|
||||||
|
This is useful for some SoC boards that use multiple flash chips as
|
||||||
|
memory banks of a single mtd device, with partitions spanning chip
|
||||||
|
borders.
|
||||||
|
|
||||||
|
This commit adds a driver for creating virtual mtd-concat devices. They
|
||||||
|
must have a compatible = "mtd-concat" line, and define a list of devices
|
||||||
|
to concat in the 'devices' property, for example:
|
||||||
|
|
||||||
|
flash {
|
||||||
|
compatible = "mtd-concat";
|
||||||
|
|
||||||
|
devices = <&flash0 &flash1>;
|
||||||
|
|
||||||
|
partitions {
|
||||||
|
...
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
The driver is added to the very end of the mtd Makefile to increase the
|
||||||
|
likelyhood of all child devices already being loaded at the time of
|
||||||
|
probing, preventing unnecessary deferred probes.
|
||||||
|
|
||||||
|
Signed-off-by: Bernhard Frauendienst <kernel@nospam.obeliks.de>
|
||||||
|
---
|
||||||
|
drivers/mtd/Kconfig | 2 +
|
||||||
|
drivers/mtd/Makefile | 3 +
|
||||||
|
drivers/mtd/composite/Kconfig | 12 +++
|
||||||
|
drivers/mtd/composite/Makefile | 6 ++
|
||||||
|
drivers/mtd/composite/virt_concat.c | 128 ++++++++++++++++++++++++++++
|
||||||
|
5 files changed, 151 insertions(+)
|
||||||
|
create mode 100644 drivers/mtd/composite/Kconfig
|
||||||
|
create mode 100644 drivers/mtd/composite/Makefile
|
||||||
|
create mode 100644 drivers/mtd/composite/virt_concat.c
|
||||||
|
|
||||||
|
--- a/drivers/mtd/Kconfig
|
||||||
|
+++ b/drivers/mtd/Kconfig
|
||||||
|
@@ -241,4 +241,6 @@ source "drivers/mtd/ubi/Kconfig"
|
||||||
|
|
||||||
|
source "drivers/mtd/hyperbus/Kconfig"
|
||||||
|
|
||||||
|
+source "drivers/mtd/composite/Kconfig"
|
||||||
|
+
|
||||||
|
endif # MTD
|
||||||
|
--- a/drivers/mtd/Makefile
|
||||||
|
+++ b/drivers/mtd/Makefile
|
||||||
|
@@ -33,3 +33,6 @@ obj-y += chips/ lpddr/ maps/ devices/ n
|
||||||
|
obj-$(CONFIG_MTD_SPI_NOR) += spi-nor/
|
||||||
|
obj-$(CONFIG_MTD_UBI) += ubi/
|
||||||
|
obj-$(CONFIG_MTD_HYPERBUS) += hyperbus/
|
||||||
|
+
|
||||||
|
+# Composite drivers must be loaded last
|
||||||
|
+obj-y += composite/
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/drivers/mtd/composite/Kconfig
|
||||||
|
@@ -0,0 +1,12 @@
|
||||||
|
+menu "Composite MTD device drivers"
|
||||||
|
+ depends on MTD!=n
|
||||||
|
+
|
||||||
|
+config MTD_VIRT_CONCAT
|
||||||
|
+ tristate "Virtual concat MTD device"
|
||||||
|
+ help
|
||||||
|
+ This driver allows creation of a virtual MTD concat device, which
|
||||||
|
+ concatenates multiple underlying MTD devices to a single device.
|
||||||
|
+ This is required by some SoC boards where multiple memory banks are
|
||||||
|
+ used as one device with partitions spanning across device boundaries.
|
||||||
|
+
|
||||||
|
+endmenu
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/drivers/mtd/composite/Makefile
|
||||||
|
@@ -0,0 +1,6 @@
|
||||||
|
+# SPDX-License-Identifier: GPL-2.0
|
||||||
|
+#
|
||||||
|
+# linux/drivers/mtd/composite/Makefile
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+obj-$(CONFIG_MTD_VIRT_CONCAT) += virt_concat.o
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/drivers/mtd/composite/virt_concat.c
|
||||||
|
@@ -0,0 +1,128 @@
|
||||||
|
+// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
+/*
|
||||||
|
+ * Virtual concat MTD device driver
|
||||||
|
+ *
|
||||||
|
+ * Copyright (C) 2018 Bernhard Frauendienst
|
||||||
|
+ * Author: Bernhard Frauendienst, kernel@nospam.obeliks.de
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <linux/module.h>
|
||||||
|
+#include <linux/device.h>
|
||||||
|
+#include <linux/mtd/concat.h>
|
||||||
|
+#include <linux/mtd/mtd.h>
|
||||||
|
+#include <linux/mtd/partitions.h>
|
||||||
|
+#include <linux/of.h>
|
||||||
|
+#include <linux/of_platform.h>
|
||||||
|
+#include <linux/slab.h>
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * struct of_virt_concat - platform device driver data.
|
||||||
|
+ * @cmtd the final mtd_concat device
|
||||||
|
+ * @num_devices the number of devices in @devices
|
||||||
|
+ * @devices points to an array of devices already loaded
|
||||||
|
+ */
|
||||||
|
+struct of_virt_concat {
|
||||||
|
+ struct mtd_info *cmtd;
|
||||||
|
+ int num_devices;
|
||||||
|
+ struct mtd_info **devices;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int virt_concat_remove(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ struct of_virt_concat *info;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ info = platform_get_drvdata(pdev);
|
||||||
|
+ if (!info)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ // unset data for when this is called after a probe error
|
||||||
|
+ platform_set_drvdata(pdev, NULL);
|
||||||
|
+
|
||||||
|
+ if (info->cmtd) {
|
||||||
|
+ mtd_device_unregister(info->cmtd);
|
||||||
|
+ mtd_concat_destroy(info->cmtd);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (info->devices) {
|
||||||
|
+ for (i = 0; i < info->num_devices; i++)
|
||||||
|
+ put_mtd_device(info->devices[i]);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int virt_concat_probe(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ struct device_node *node = pdev->dev.of_node;
|
||||||
|
+ struct of_phandle_iterator it;
|
||||||
|
+ struct of_virt_concat *info;
|
||||||
|
+ struct mtd_info *mtd;
|
||||||
|
+ int err = 0, count;
|
||||||
|
+
|
||||||
|
+ count = of_count_phandle_with_args(node, "devices", NULL);
|
||||||
|
+ if (count <= 0)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
|
||||||
|
+ if (!info)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+ info->devices = devm_kcalloc(&pdev->dev, count,
|
||||||
|
+ sizeof(*(info->devices)), GFP_KERNEL);
|
||||||
|
+ if (!info->devices) {
|
||||||
|
+ err = -ENOMEM;
|
||||||
|
+ goto err_remove;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ platform_set_drvdata(pdev, info);
|
||||||
|
+
|
||||||
|
+ of_for_each_phandle(&it, err, node, "devices", NULL, 0) {
|
||||||
|
+ mtd = get_mtd_device_by_node(it.node);
|
||||||
|
+ if (IS_ERR(mtd)) {
|
||||||
|
+ of_node_put(it.node);
|
||||||
|
+ err = -EPROBE_DEFER;
|
||||||
|
+ goto err_remove;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ info->devices[info->num_devices++] = mtd;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ info->cmtd = mtd_concat_create(info->devices, info->num_devices,
|
||||||
|
+ dev_name(&pdev->dev));
|
||||||
|
+ if (!info->cmtd) {
|
||||||
|
+ err = -ENXIO;
|
||||||
|
+ goto err_remove;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ info->cmtd->dev.parent = &pdev->dev;
|
||||||
|
+ mtd_set_of_node(info->cmtd, node);
|
||||||
|
+ mtd_device_register(info->cmtd, NULL, 0);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+err_remove:
|
||||||
|
+ virt_concat_remove(pdev);
|
||||||
|
+
|
||||||
|
+ return err;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static const struct of_device_id virt_concat_of_match[] = {
|
||||||
|
+ { .compatible = "mtd-concat", },
|
||||||
|
+ { /* sentinel */ }
|
||||||
|
+};
|
||||||
|
+MODULE_DEVICE_TABLE(of, virt_concat_of_match);
|
||||||
|
+
|
||||||
|
+static struct platform_driver virt_concat_driver = {
|
||||||
|
+ .probe = virt_concat_probe,
|
||||||
|
+ .remove = virt_concat_remove,
|
||||||
|
+ .driver = {
|
||||||
|
+ .name = "virt-mtdconcat",
|
||||||
|
+ .of_match_table = virt_concat_of_match,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+module_platform_driver(virt_concat_driver);
|
||||||
|
+
|
||||||
|
+MODULE_LICENSE("GPL v2");
|
||||||
|
+MODULE_AUTHOR("Bernhard Frauendienst <kernel@nospam.obeliks.de>");
|
||||||
|
+MODULE_DESCRIPTION("Virtual concat MTD device driver");
|
@ -0,0 +1,30 @@
|
|||||||
|
From 245224608b5368c10407da07557e546743d3c489 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nick Hainke <vincent@systemli.org>
|
||||||
|
Date: Mon, 27 Dec 2021 09:33:13 +0100
|
||||||
|
Subject: [PATCH 2/2] mtd: spi-nor: disable 16-bit-sr for macronix
|
||||||
|
|
||||||
|
Macronix flash chips seem to consist of only one status register.
|
||||||
|
These chips will not work with the "16-bit Write Status (01h) Command".
|
||||||
|
Disable SNOR_F_HAS_16BIT_SR for all Macronix chips.
|
||||||
|
|
||||||
|
Tested with MX25L6405D.
|
||||||
|
|
||||||
|
Fixes: 39d1e3340c73 ("mtd: spi-nor: Fix clearing of QE bit on
|
||||||
|
lock()/unlock()")
|
||||||
|
|
||||||
|
Signed-off-by: David Bauer <mail@david-bauer.net>
|
||||||
|
Signed-off-by: Nick Hainke <vincent@systemli.org>
|
||||||
|
---
|
||||||
|
drivers/mtd/spi-nor/macronix.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
--- a/drivers/mtd/spi-nor/macronix.c
|
||||||
|
+++ b/drivers/mtd/spi-nor/macronix.c
|
||||||
|
@@ -194,6 +194,7 @@ static int macronix_nor_late_init(struct
|
||||||
|
{
|
||||||
|
if (!nor->params->set_4byte_addr_mode)
|
||||||
|
nor->params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode_en4b_ex4b;
|
||||||
|
+ nor->flags &= ~SNOR_F_HAS_16BIT_SR;
|
||||||
|
nor->flags |= SNOR_F_HAS_LOCK;
|
||||||
|
|
||||||
|
return 0;
|
52
pending-6.12/500-fs_cdrom_dependencies.patch
Normal file
52
pending-6.12/500-fs_cdrom_dependencies.patch
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
From af7b91bcecce0eae24e90acd35d96ecee73e1407 Mon Sep 17 00:00:00 2001
|
||||||
|
From: OpenWrt community <openwrt-devel@lists.openwrt.org>
|
||||||
|
Date: Wed, 13 Jul 2022 12:21:15 +0200
|
||||||
|
Subject: [PATCH] fs: add cdrom dependency
|
||||||
|
|
||||||
|
---
|
||||||
|
fs/hfs/Kconfig | 1 +
|
||||||
|
fs/hfsplus/Kconfig | 1 +
|
||||||
|
fs/isofs/Kconfig | 1 +
|
||||||
|
fs/udf/Kconfig | 1 +
|
||||||
|
4 files changed, 4 insertions(+)
|
||||||
|
|
||||||
|
--- a/fs/hfs/Kconfig
|
||||||
|
+++ b/fs/hfs/Kconfig
|
||||||
|
@@ -2,6 +2,7 @@
|
||||||
|
config HFS_FS
|
||||||
|
tristate "Apple Macintosh file system support"
|
||||||
|
depends on BLOCK
|
||||||
|
+ select CDROM
|
||||||
|
select BUFFER_HEAD
|
||||||
|
select NLS
|
||||||
|
select LEGACY_DIRECT_IO
|
||||||
|
--- a/fs/hfsplus/Kconfig
|
||||||
|
+++ b/fs/hfsplus/Kconfig
|
||||||
|
@@ -2,6 +2,7 @@
|
||||||
|
config HFSPLUS_FS
|
||||||
|
tristate "Apple Extended HFS file system support"
|
||||||
|
depends on BLOCK
|
||||||
|
+ select CDROM
|
||||||
|
select BUFFER_HEAD
|
||||||
|
select NLS
|
||||||
|
select NLS_UTF8
|
||||||
|
--- a/fs/isofs/Kconfig
|
||||||
|
+++ b/fs/isofs/Kconfig
|
||||||
|
@@ -1,6 +1,7 @@
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
config ISO9660_FS
|
||||||
|
tristate "ISO 9660 CDROM file system support"
|
||||||
|
+ select CDROM
|
||||||
|
select BUFFER_HEAD
|
||||||
|
help
|
||||||
|
This is the standard file system used on CD-ROMs. It was previously
|
||||||
|
--- a/fs/udf/Kconfig
|
||||||
|
+++ b/fs/udf/Kconfig
|
||||||
|
@@ -1,6 +1,7 @@
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
config UDF_FS
|
||||||
|
tristate "UDF file system support"
|
||||||
|
+ select CDROM
|
||||||
|
select BUFFER_HEAD
|
||||||
|
select CRC_ITU_T
|
||||||
|
select NLS
|
5180
pending-6.12/530-jffs2_make_lzma_available.patch
Normal file
5180
pending-6.12/530-jffs2_make_lzma_available.patch
Normal file
File diff suppressed because it is too large
Load Diff
65
pending-6.12/532-jffs2_eofdetect.patch
Normal file
65
pending-6.12/532-jffs2_eofdetect.patch
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Subject: fs: jffs2: EOF marker
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
fs/jffs2/build.c | 10 ++++++++++
|
||||||
|
fs/jffs2/scan.c | 21 +++++++++++++++++++--
|
||||||
|
2 files changed, 29 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
--- a/fs/jffs2/build.c
|
||||||
|
+++ b/fs/jffs2/build.c
|
||||||
|
@@ -117,6 +117,16 @@ static int jffs2_build_filesystem(struct
|
||||||
|
dbg_fsbuild("scanned flash completely\n");
|
||||||
|
jffs2_dbg_dump_block_lists_nolock(c);
|
||||||
|
|
||||||
|
+ if (c->flags & (1 << 7)) {
|
||||||
|
+ printk("%s(): unlocking the mtd device... ", __func__);
|
||||||
|
+ mtd_unlock(c->mtd, 0, c->mtd->size);
|
||||||
|
+ printk("done.\n");
|
||||||
|
+
|
||||||
|
+ printk("%s(): erasing all blocks after the end marker... ", __func__);
|
||||||
|
+ jffs2_erase_pending_blocks(c, -1);
|
||||||
|
+ printk("done.\n");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
dbg_fsbuild("pass 1 starting\n");
|
||||||
|
c->flags |= JFFS2_SB_FLAG_BUILDING;
|
||||||
|
/* Now scan the directory tree, increasing nlink according to every dirent found. */
|
||||||
|
--- a/fs/jffs2/scan.c
|
||||||
|
+++ b/fs/jffs2/scan.c
|
||||||
|
@@ -148,8 +148,14 @@ int jffs2_scan_medium(struct jffs2_sb_in
|
||||||
|
/* reset summary info for next eraseblock scan */
|
||||||
|
jffs2_sum_reset_collected(s);
|
||||||
|
|
||||||
|
- ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset),
|
||||||
|
- buf_size, s);
|
||||||
|
+ if (c->flags & (1 << 7)) {
|
||||||
|
+ if (mtd_block_isbad(c->mtd, jeb->offset))
|
||||||
|
+ ret = BLK_STATE_BADBLOCK;
|
||||||
|
+ else
|
||||||
|
+ ret = BLK_STATE_ALLFF;
|
||||||
|
+ } else
|
||||||
|
+ ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset),
|
||||||
|
+ buf_size, s);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
goto out;
|
||||||
|
@@ -567,6 +573,17 @@ full_scan:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if ((buf[0] == 0xde) &&
|
||||||
|
+ (buf[1] == 0xad) &&
|
||||||
|
+ (buf[2] == 0xc0) &&
|
||||||
|
+ (buf[3] == 0xde)) {
|
||||||
|
+ /* end of filesystem. erase everything after this point */
|
||||||
|
+ printk("%s(): End of filesystem marker found at 0x%x\n", __func__, jeb->offset);
|
||||||
|
+ c->flags |= (1 << 7);
|
||||||
|
+
|
||||||
|
+ return BLK_STATE_ALLFF;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* We temporarily use 'ofs' as a pointer into the buffer/jeb */
|
||||||
|
ofs = 0;
|
||||||
|
max_ofs = EMPTY_SCAN_SIZE(c->sector_size);
|
88
pending-6.12/600-netfilter_conntrack_flush.patch
Normal file
88
pending-6.12/600-netfilter_conntrack_flush.patch
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Subject: netfilter: add support for flushing conntrack via /proc
|
||||||
|
|
||||||
|
lede-commit 8193bbe59a74d34d6a26d4a8cb857b1952905314
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
net/netfilter/nf_conntrack_standalone.c | 59 ++++++++++++++++++++++++++++++++-
|
||||||
|
1 file changed, 58 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/net/netfilter/nf_conntrack_standalone.c
|
||||||
|
+++ b/net/netfilter/nf_conntrack_standalone.c
|
||||||
|
@@ -9,6 +9,7 @@
|
||||||
|
#include <linux/percpu.h>
|
||||||
|
#include <linux/netdevice.h>
|
||||||
|
#include <linux/security.h>
|
||||||
|
+#include <linux/inet.h>
|
||||||
|
#include <net/net_namespace.h>
|
||||||
|
#ifdef CONFIG_SYSCTL
|
||||||
|
#include <linux/sysctl.h>
|
||||||
|
@@ -458,6 +459,56 @@ static int ct_cpu_seq_show(struct seq_fi
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+struct kill_request {
|
||||||
|
+ u16 family;
|
||||||
|
+ union nf_inet_addr addr;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int kill_matching(struct nf_conn *i, void *data)
|
||||||
|
+{
|
||||||
|
+ struct kill_request *kr = data;
|
||||||
|
+ struct nf_conntrack_tuple *t1 = &i->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
|
||||||
|
+ struct nf_conntrack_tuple *t2 = &i->tuplehash[IP_CT_DIR_REPLY].tuple;
|
||||||
|
+
|
||||||
|
+ if (!kr->family)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ if (t1->src.l3num != kr->family)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ return (nf_inet_addr_cmp(&kr->addr, &t1->src.u3) ||
|
||||||
|
+ nf_inet_addr_cmp(&kr->addr, &t1->dst.u3) ||
|
||||||
|
+ nf_inet_addr_cmp(&kr->addr, &t2->src.u3) ||
|
||||||
|
+ nf_inet_addr_cmp(&kr->addr, &t2->dst.u3));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int ct_file_write(struct file *file, char *buf, size_t count)
|
||||||
|
+{
|
||||||
|
+ struct seq_file *seq = file->private_data;
|
||||||
|
+ struct net *net = seq_file_net(seq);
|
||||||
|
+ struct kill_request kr = { };
|
||||||
|
+
|
||||||
|
+ if (count == 0)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ if (count >= INET6_ADDRSTRLEN)
|
||||||
|
+ count = INET6_ADDRSTRLEN - 1;
|
||||||
|
+
|
||||||
|
+ if (strnchr(buf, count, ':')) {
|
||||||
|
+ kr.family = AF_INET6;
|
||||||
|
+ if (!in6_pton(buf, count, (void *)&kr.addr, '\n', NULL))
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ } else if (strnchr(buf, count, '.')) {
|
||||||
|
+ kr.family = AF_INET;
|
||||||
|
+ if (!in4_pton(buf, count, (void *)&kr.addr, '\n', NULL))
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static const struct seq_operations ct_cpu_seq_ops = {
|
||||||
|
.start = ct_cpu_seq_start,
|
||||||
|
.next = ct_cpu_seq_next,
|
||||||
|
@@ -471,8 +522,9 @@ static int nf_conntrack_standalone_init_
|
||||||
|
kuid_t root_uid;
|
||||||
|
kgid_t root_gid;
|
||||||
|
|
||||||
|
- pde = proc_create_net("nf_conntrack", 0440, net->proc_net, &ct_seq_ops,
|
||||||
|
- sizeof(struct ct_iter_state));
|
||||||
|
+ pde = proc_create_net_data_write("nf_conntrack", 0440, net->proc_net,
|
||||||
|
+ &ct_seq_ops, &ct_file_write,
|
||||||
|
+ sizeof(struct ct_iter_state), NULL);
|
||||||
|
if (!pde)
|
||||||
|
goto out_nf_conntrack;
|
||||||
|
|
110
pending-6.12/610-netfilter_match_bypass_default_checks.patch
Normal file
110
pending-6.12/610-netfilter_match_bypass_default_checks.patch
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Subject: kernel: add a new version of my netfilter speedup patches for linux 2.6.39 and 3.0
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
include/uapi/linux/netfilter_ipv4/ip_tables.h | 1 +
|
||||||
|
net/ipv4/netfilter/ip_tables.c | 37 +++++++++++++++++++++++++++
|
||||||
|
2 files changed, 38 insertions(+)
|
||||||
|
|
||||||
|
--- a/include/uapi/linux/netfilter_ipv4/ip_tables.h
|
||||||
|
+++ b/include/uapi/linux/netfilter_ipv4/ip_tables.h
|
||||||
|
@@ -89,6 +89,7 @@ struct ipt_ip {
|
||||||
|
#define IPT_F_FRAG 0x01 /* Set if rule is a fragment rule */
|
||||||
|
#define IPT_F_GOTO 0x02 /* Set if jump is a goto */
|
||||||
|
#define IPT_F_MASK 0x03 /* All possible flag bits mask. */
|
||||||
|
+#define IPT_F_NO_DEF_MATCH 0x80 /* Internal: no default match rules present */
|
||||||
|
|
||||||
|
/* Values for "inv" field in struct ipt_ip. */
|
||||||
|
#define IPT_INV_VIA_IN 0x01 /* Invert the sense of IN IFACE. */
|
||||||
|
--- a/net/ipv4/netfilter/ip_tables.c
|
||||||
|
+++ b/net/ipv4/netfilter/ip_tables.c
|
||||||
|
@@ -48,6 +48,9 @@ ip_packet_match(const struct iphdr *ip,
|
||||||
|
{
|
||||||
|
unsigned long ret;
|
||||||
|
|
||||||
|
+ if (ipinfo->flags & IPT_F_NO_DEF_MATCH)
|
||||||
|
+ return true;
|
||||||
|
+
|
||||||
|
if (NF_INVF(ipinfo, IPT_INV_SRCIP,
|
||||||
|
(ip->saddr & ipinfo->smsk.s_addr) != ipinfo->src.s_addr) ||
|
||||||
|
NF_INVF(ipinfo, IPT_INV_DSTIP,
|
||||||
|
@@ -78,6 +81,29 @@ ip_packet_match(const struct iphdr *ip,
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void
|
||||||
|
+ip_checkdefault(struct ipt_ip *ip)
|
||||||
|
+{
|
||||||
|
+ static const char iface_mask[IFNAMSIZ] = {};
|
||||||
|
+
|
||||||
|
+ if (ip->invflags || ip->flags & IPT_F_FRAG)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (memcmp(ip->iniface_mask, iface_mask, IFNAMSIZ) != 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (memcmp(ip->outiface_mask, iface_mask, IFNAMSIZ) != 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (ip->smsk.s_addr || ip->dmsk.s_addr)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (ip->proto)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ ip->flags |= IPT_F_NO_DEF_MATCH;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static bool
|
||||||
|
ip_checkentry(const struct ipt_ip *ip)
|
||||||
|
{
|
||||||
|
@@ -523,6 +549,8 @@ find_check_entry(struct ipt_entry *e, st
|
||||||
|
struct xt_mtchk_param mtpar;
|
||||||
|
struct xt_entry_match *ematch;
|
||||||
|
|
||||||
|
+ ip_checkdefault(&e->ip);
|
||||||
|
+
|
||||||
|
if (!xt_percpu_counter_alloc(alloc_state, &e->counters))
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@@ -817,6 +845,7 @@ copy_entries_to_user(unsigned int total_
|
||||||
|
const struct xt_table_info *private = table->private;
|
||||||
|
int ret = 0;
|
||||||
|
const void *loc_cpu_entry;
|
||||||
|
+ u8 flags;
|
||||||
|
|
||||||
|
counters = alloc_counters(table);
|
||||||
|
if (IS_ERR(counters))
|
||||||
|
@@ -844,6 +873,14 @@ copy_entries_to_user(unsigned int total_
|
||||||
|
goto free_counters;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ flags = e->ip.flags & IPT_F_MASK;
|
||||||
|
+ if (copy_to_user(userptr + off
|
||||||
|
+ + offsetof(struct ipt_entry, ip.flags),
|
||||||
|
+ &flags, sizeof(flags)) != 0) {
|
||||||
|
+ ret = -EFAULT;
|
||||||
|
+ goto free_counters;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
for (i = sizeof(struct ipt_entry);
|
||||||
|
i < e->target_offset;
|
||||||
|
i += m->u.match_size) {
|
||||||
|
@@ -1225,12 +1262,15 @@ compat_copy_entry_to_user(struct ipt_ent
|
||||||
|
compat_uint_t origsize;
|
||||||
|
const struct xt_entry_match *ematch;
|
||||||
|
int ret = 0;
|
||||||
|
+ u8 flags = e->ip.flags & IPT_F_MASK;
|
||||||
|
|
||||||
|
origsize = *size;
|
||||||
|
ce = *dstptr;
|
||||||
|
if (copy_to_user(ce, e, sizeof(struct ipt_entry)) != 0 ||
|
||||||
|
copy_to_user(&ce->counters, &counters[i],
|
||||||
|
- sizeof(counters[i])) != 0)
|
||||||
|
+ sizeof(counters[i])) != 0 ||
|
||||||
|
+ copy_to_user(&ce->ip.flags, &flags,
|
||||||
|
+ sizeof(flags)) != 0)
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
*dstptr += sizeof(struct compat_ipt_entry);
|
106
pending-6.12/611-netfilter_match_bypass_default_table.patch
Normal file
106
pending-6.12/611-netfilter_match_bypass_default_table.patch
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Subject: netfilter: match bypass default table
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
net/ipv4/netfilter/ip_tables.c | 79 +++++++++++++++++++++++++++++++-----------
|
||||||
|
1 file changed, 58 insertions(+), 21 deletions(-)
|
||||||
|
|
||||||
|
--- a/net/ipv4/netfilter/ip_tables.c
|
||||||
|
+++ b/net/ipv4/netfilter/ip_tables.c
|
||||||
|
@@ -244,6 +244,33 @@ struct ipt_entry *ipt_next_entry(const s
|
||||||
|
return (void *)entry + entry->next_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static bool
|
||||||
|
+ipt_handle_default_rule(struct ipt_entry *e, unsigned int *verdict)
|
||||||
|
+{
|
||||||
|
+ struct xt_entry_target *t;
|
||||||
|
+ struct xt_standard_target *st;
|
||||||
|
+
|
||||||
|
+ if (e->target_offset != sizeof(struct ipt_entry))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ if (!(e->ip.flags & IPT_F_NO_DEF_MATCH))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ t = ipt_get_target(e);
|
||||||
|
+ if (t->u.kernel.target->target)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ st = (struct xt_standard_target *) t;
|
||||||
|
+ if (st->verdict == XT_RETURN)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ if (st->verdict >= 0)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ *verdict = (unsigned)(-st->verdict) - 1;
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Returns one of the generic firewall policies, like NF_ACCEPT. */
|
||||||
|
unsigned int
|
||||||
|
ipt_do_table(void *priv,
|
||||||
|
@@ -265,27 +292,28 @@ ipt_do_table(void *priv,
|
||||||
|
unsigned int addend;
|
||||||
|
|
||||||
|
/* Initialization */
|
||||||
|
+ WARN_ON(!(table->valid_hooks & (1 << hook)));
|
||||||
|
+ local_bh_disable();
|
||||||
|
+ private = READ_ONCE(table->private); /* Address dependency. */
|
||||||
|
+ cpu = smp_processor_id();
|
||||||
|
+ table_base = private->entries;
|
||||||
|
+
|
||||||
|
+ e = get_entry(table_base, private->hook_entry[hook]);
|
||||||
|
+ if (ipt_handle_default_rule(e, &verdict)) {
|
||||||
|
+ struct xt_counters *counter;
|
||||||
|
+
|
||||||
|
+ counter = xt_get_this_cpu_counter(&e->counters);
|
||||||
|
+ ADD_COUNTER(*counter, skb->len, 1);
|
||||||
|
+ local_bh_enable();
|
||||||
|
+ return verdict;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
stackidx = 0;
|
||||||
|
ip = ip_hdr(skb);
|
||||||
|
indev = state->in ? state->in->name : nulldevname;
|
||||||
|
outdev = state->out ? state->out->name : nulldevname;
|
||||||
|
- /* We handle fragments by dealing with the first fragment as
|
||||||
|
- * if it was a normal packet. All other fragments are treated
|
||||||
|
- * normally, except that they will NEVER match rules that ask
|
||||||
|
- * things we don't know, ie. tcp syn flag or ports). If the
|
||||||
|
- * rule is also a fragment-specific rule, non-fragments won't
|
||||||
|
- * match it. */
|
||||||
|
- acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
|
||||||
|
- acpar.thoff = ip_hdrlen(skb);
|
||||||
|
- acpar.hotdrop = false;
|
||||||
|
- acpar.state = state;
|
||||||
|
|
||||||
|
- WARN_ON(!(table->valid_hooks & (1 << hook)));
|
||||||
|
- local_bh_disable();
|
||||||
|
addend = xt_write_recseq_begin();
|
||||||
|
- private = READ_ONCE(table->private); /* Address dependency. */
|
||||||
|
- cpu = smp_processor_id();
|
||||||
|
- table_base = private->entries;
|
||||||
|
jumpstack = (struct ipt_entry **)private->jumpstack[cpu];
|
||||||
|
|
||||||
|
/* Switch to alternate jumpstack if we're being invoked via TEE.
|
||||||
|
@@ -298,7 +326,16 @@ ipt_do_table(void *priv,
|
||||||
|
if (static_key_false(&xt_tee_enabled))
|
||||||
|
jumpstack += private->stacksize * __this_cpu_read(nf_skb_duplicated);
|
||||||
|
|
||||||
|
- e = get_entry(table_base, private->hook_entry[hook]);
|
||||||
|
+ /* We handle fragments by dealing with the first fragment as
|
||||||
|
+ * if it was a normal packet. All other fragments are treated
|
||||||
|
+ * normally, except that they will NEVER match rules that ask
|
||||||
|
+ * things we don't know, ie. tcp syn flag or ports). If the
|
||||||
|
+ * rule is also a fragment-specific rule, non-fragments won't
|
||||||
|
+ * match it. */
|
||||||
|
+ acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
|
||||||
|
+ acpar.thoff = ip_hdrlen(skb);
|
||||||
|
+ acpar.hotdrop = false;
|
||||||
|
+ acpar.state = state;
|
||||||
|
|
||||||
|
do {
|
||||||
|
const struct xt_entry_target *t;
|
22
pending-6.12/612-netfilter_match_reduce_memory_access.patch
Normal file
22
pending-6.12/612-netfilter_match_reduce_memory_access.patch
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Subject: netfilter: reduce match memory access
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
net/ipv4/netfilter/ip_tables.c | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
--- a/net/ipv4/netfilter/ip_tables.c
|
||||||
|
+++ b/net/ipv4/netfilter/ip_tables.c
|
||||||
|
@@ -51,9 +51,9 @@ ip_packet_match(const struct iphdr *ip,
|
||||||
|
if (ipinfo->flags & IPT_F_NO_DEF_MATCH)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
- if (NF_INVF(ipinfo, IPT_INV_SRCIP,
|
||||||
|
+ if (NF_INVF(ipinfo, IPT_INV_SRCIP, ipinfo->smsk.s_addr &&
|
||||||
|
(ip->saddr & ipinfo->smsk.s_addr) != ipinfo->src.s_addr) ||
|
||||||
|
- NF_INVF(ipinfo, IPT_INV_DSTIP,
|
||||||
|
+ NF_INVF(ipinfo, IPT_INV_DSTIP, ipinfo->dmsk.s_addr &&
|
||||||
|
(ip->daddr & ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr))
|
||||||
|
return false;
|
||||||
|
|
@ -0,0 +1,86 @@
|
|||||||
|
From: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
|
||||||
|
Date: Mon, 21 Aug 2017 11:14:14 +0300
|
||||||
|
Subject: [PATCH] net_sched/codel: do not defer queue length update
|
||||||
|
|
||||||
|
When codel wants to drop last packet in ->dequeue() it cannot call
|
||||||
|
qdisc_tree_reduce_backlog() right away - it will notify parent qdisc
|
||||||
|
about zero qlen and HTB/HFSC will deactivate class. The same class will
|
||||||
|
be deactivated second time by caller of ->dequeue(). Currently codel and
|
||||||
|
fq_codel defer update. This triggers warning in HFSC when it's qlen != 0
|
||||||
|
but there is no active classes.
|
||||||
|
|
||||||
|
This patch update parent queue length immediately: just temporary increase
|
||||||
|
qlen around qdisc_tree_reduce_backlog() to prevent first class deactivation
|
||||||
|
if we have skb to return.
|
||||||
|
|
||||||
|
This might open another problem in HFSC - now operation peek could fail and
|
||||||
|
deactivate parent class.
|
||||||
|
|
||||||
|
Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
|
||||||
|
Link: https://bugzilla.kernel.org/show_bug.cgi?id=109581
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/net/sched/sch_codel.c
|
||||||
|
+++ b/net/sched/sch_codel.c
|
||||||
|
@@ -65,11 +65,17 @@ static struct sk_buff *codel_qdisc_deque
|
||||||
|
&q->stats, qdisc_pkt_len, codel_get_enqueue_time,
|
||||||
|
drop_func, dequeue_func);
|
||||||
|
|
||||||
|
- /* We cant call qdisc_tree_reduce_backlog() if our qlen is 0,
|
||||||
|
- * or HTB crashes. Defer it for next round.
|
||||||
|
+ /* If our qlen is 0 qdisc_tree_reduce_backlog() will deactivate
|
||||||
|
+ * parent class, dequeue in parent qdisc will do the same if we
|
||||||
|
+ * return skb. Temporary increment qlen if we have skb.
|
||||||
|
*/
|
||||||
|
- if (q->stats.drop_count && sch->q.qlen) {
|
||||||
|
- qdisc_tree_reduce_backlog(sch, q->stats.drop_count, q->stats.drop_len);
|
||||||
|
+ if (q->stats.drop_count) {
|
||||||
|
+ if (skb)
|
||||||
|
+ sch->q.qlen++;
|
||||||
|
+ qdisc_tree_reduce_backlog(sch, q->stats.drop_count,
|
||||||
|
+ q->stats.drop_len);
|
||||||
|
+ if (skb)
|
||||||
|
+ sch->q.qlen--;
|
||||||
|
q->stats.drop_count = 0;
|
||||||
|
q->stats.drop_len = 0;
|
||||||
|
}
|
||||||
|
--- a/net/sched/sch_fq_codel.c
|
||||||
|
+++ b/net/sched/sch_fq_codel.c
|
||||||
|
@@ -304,6 +304,21 @@ begin:
|
||||||
|
&flow->cvars, &q->cstats, qdisc_pkt_len,
|
||||||
|
codel_get_enqueue_time, drop_func, dequeue_func);
|
||||||
|
|
||||||
|
+ /* If our qlen is 0 qdisc_tree_reduce_backlog() will deactivate
|
||||||
|
+ * parent class, dequeue in parent qdisc will do the same if we
|
||||||
|
+ * return skb. Temporary increment qlen if we have skb.
|
||||||
|
+ */
|
||||||
|
+ if (q->cstats.drop_count) {
|
||||||
|
+ if (skb)
|
||||||
|
+ sch->q.qlen++;
|
||||||
|
+ qdisc_tree_reduce_backlog(sch, q->cstats.drop_count,
|
||||||
|
+ q->cstats.drop_len);
|
||||||
|
+ if (skb)
|
||||||
|
+ sch->q.qlen--;
|
||||||
|
+ q->cstats.drop_count = 0;
|
||||||
|
+ q->cstats.drop_len = 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (!skb) {
|
||||||
|
/* force a pass through old_flows to prevent starvation */
|
||||||
|
if ((head == &q->new_flows) && !list_empty(&q->old_flows))
|
||||||
|
@@ -314,15 +329,6 @@ begin:
|
||||||
|
}
|
||||||
|
qdisc_bstats_update(sch, skb);
|
||||||
|
flow->deficit -= qdisc_pkt_len(skb);
|
||||||
|
- /* We cant call qdisc_tree_reduce_backlog() if our qlen is 0,
|
||||||
|
- * or HTB crashes. Defer it for next round.
|
||||||
|
- */
|
||||||
|
- if (q->cstats.drop_count && sch->q.qlen) {
|
||||||
|
- qdisc_tree_reduce_backlog(sch, q->cstats.drop_count,
|
||||||
|
- q->cstats.drop_len);
|
||||||
|
- q->cstats.drop_count = 0;
|
||||||
|
- q->cstats.drop_len = 0;
|
||||||
|
- }
|
||||||
|
return skb;
|
||||||
|
}
|
||||||
|
|
20
pending-6.12/655-increase_skb_pad.patch
Normal file
20
pending-6.12/655-increase_skb_pad.patch
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Subject: kernel: add a few patches for avoiding unnecessary skb reallocations - significantly improves ethernet<->wireless performance
|
||||||
|
|
||||||
|
lede-commit: 6f89cffc9add6939d44a6b54cf9a5e77849aa7fd
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
include/linux/skbuff.h | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/include/linux/skbuff.h
|
||||||
|
+++ b/include/linux/skbuff.h
|
||||||
|
@@ -3180,7 +3180,7 @@ static inline int pskb_network_may_pull(
|
||||||
|
* NET_IP_ALIGN(2) + ethernet_header(14) + IP_header(20/40) + ports(8)
|
||||||
|
*/
|
||||||
|
#ifndef NET_SKB_PAD
|
||||||
|
-#define NET_SKB_PAD max(32, L1_CACHE_BYTES)
|
||||||
|
+#define NET_SKB_PAD max(64, L1_CACHE_BYTES)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int ___pskb_trim(struct sk_buff *skb, unsigned int len);
|
511
pending-6.12/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch
Normal file
511
pending-6.12/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch
Normal file
@ -0,0 +1,511 @@
|
|||||||
|
From: Steven Barth <steven@midlink.org>
|
||||||
|
Subject: Add support for MAP-E FMRs (mesh mode)
|
||||||
|
|
||||||
|
MAP-E FMRs (draft-ietf-softwire-map-10) are rules for IPv4-communication
|
||||||
|
between MAP CEs (mesh mode) without the need to forward such data to a
|
||||||
|
border relay. This is similar to how 6rd works but for IPv4 over IPv6.
|
||||||
|
|
||||||
|
Signed-off-by: Steven Barth <cyrus@openwrt.org>
|
||||||
|
---
|
||||||
|
include/net/ip6_tunnel.h | 13 ++
|
||||||
|
include/uapi/linux/if_tunnel.h | 13 ++
|
||||||
|
net/ipv6/ip6_tunnel.c | 276 +++++++++++++++++++++++++++++++++++++++--
|
||||||
|
3 files changed, 291 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
|
--- a/include/net/ip6_tunnel.h
|
||||||
|
+++ b/include/net/ip6_tunnel.h
|
||||||
|
@@ -18,6 +18,18 @@
|
||||||
|
/* determine capability on a per-packet basis */
|
||||||
|
#define IP6_TNL_F_CAP_PER_PACKET 0x40000
|
||||||
|
|
||||||
|
+/* IPv6 tunnel FMR */
|
||||||
|
+struct __ip6_tnl_fmr {
|
||||||
|
+ struct __ip6_tnl_fmr *next; /* next fmr in list */
|
||||||
|
+ struct in6_addr ip6_prefix;
|
||||||
|
+ struct in_addr ip4_prefix;
|
||||||
|
+
|
||||||
|
+ __u8 ip6_prefix_len;
|
||||||
|
+ __u8 ip4_prefix_len;
|
||||||
|
+ __u8 ea_len;
|
||||||
|
+ __u8 offset;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
struct __ip6_tnl_parm {
|
||||||
|
char name[IFNAMSIZ]; /* name of tunnel device */
|
||||||
|
int link; /* ifindex of underlying L2 interface */
|
||||||
|
@@ -29,6 +41,7 @@ struct __ip6_tnl_parm {
|
||||||
|
__u32 flags; /* tunnel flags */
|
||||||
|
struct in6_addr laddr; /* local tunnel end-point address */
|
||||||
|
struct in6_addr raddr; /* remote tunnel end-point address */
|
||||||
|
+ struct __ip6_tnl_fmr *fmrs; /* FMRs */
|
||||||
|
|
||||||
|
IP_TUNNEL_DECLARE_FLAGS(i_flags);
|
||||||
|
IP_TUNNEL_DECLARE_FLAGS(o_flags);
|
||||||
|
--- a/include/uapi/linux/if_tunnel.h
|
||||||
|
+++ b/include/uapi/linux/if_tunnel.h
|
||||||
|
@@ -77,10 +77,23 @@ enum {
|
||||||
|
IFLA_IPTUN_ENCAP_DPORT,
|
||||||
|
IFLA_IPTUN_COLLECT_METADATA,
|
||||||
|
IFLA_IPTUN_FWMARK,
|
||||||
|
+ IFLA_IPTUN_FMRS,
|
||||||
|
__IFLA_IPTUN_MAX,
|
||||||
|
};
|
||||||
|
#define IFLA_IPTUN_MAX (__IFLA_IPTUN_MAX - 1)
|
||||||
|
|
||||||
|
+enum {
|
||||||
|
+ IFLA_IPTUN_FMR_UNSPEC,
|
||||||
|
+ IFLA_IPTUN_FMR_IP6_PREFIX,
|
||||||
|
+ IFLA_IPTUN_FMR_IP4_PREFIX,
|
||||||
|
+ IFLA_IPTUN_FMR_IP6_PREFIX_LEN,
|
||||||
|
+ IFLA_IPTUN_FMR_IP4_PREFIX_LEN,
|
||||||
|
+ IFLA_IPTUN_FMR_EA_LEN,
|
||||||
|
+ IFLA_IPTUN_FMR_OFFSET,
|
||||||
|
+ __IFLA_IPTUN_FMR_MAX,
|
||||||
|
+};
|
||||||
|
+#define IFLA_IPTUN_FMR_MAX (__IFLA_IPTUN_FMR_MAX - 1)
|
||||||
|
+
|
||||||
|
enum tunnel_encap_types {
|
||||||
|
TUNNEL_ENCAP_NONE,
|
||||||
|
TUNNEL_ENCAP_FOU,
|
||||||
|
--- a/net/ipv6/ip6_tunnel.c
|
||||||
|
+++ b/net/ipv6/ip6_tunnel.c
|
||||||
|
@@ -11,6 +11,9 @@
|
||||||
|
* linux/net/ipv6/sit.c and linux/net/ipv4/ipip.c
|
||||||
|
*
|
||||||
|
* RFC 2473
|
||||||
|
+ *
|
||||||
|
+ * Changes:
|
||||||
|
+ * Steven Barth <cyrus@openwrt.org>: MAP-E FMR support
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||||
|
@@ -68,9 +71,9 @@ static bool log_ecn_error = true;
|
||||||
|
module_param(log_ecn_error, bool, 0644);
|
||||||
|
MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN");
|
||||||
|
|
||||||
|
-static u32 HASH(const struct in6_addr *addr1, const struct in6_addr *addr2)
|
||||||
|
+static u32 HASH(const struct in6_addr *addr)
|
||||||
|
{
|
||||||
|
- u32 hash = ipv6_addr_hash(addr1) ^ ipv6_addr_hash(addr2);
|
||||||
|
+ u32 hash = ipv6_addr_hash(addr);
|
||||||
|
|
||||||
|
return hash_32(hash, IP6_TUNNEL_HASH_SIZE_SHIFT);
|
||||||
|
}
|
||||||
|
@@ -115,17 +118,33 @@ static struct ip6_tnl *
|
||||||
|
ip6_tnl_lookup(struct net *net, int link,
|
||||||
|
const struct in6_addr *remote, const struct in6_addr *local)
|
||||||
|
{
|
||||||
|
- unsigned int hash = HASH(remote, local);
|
||||||
|
+ unsigned int hash = HASH(local);
|
||||||
|
struct ip6_tnl *t, *cand = NULL;
|
||||||
|
struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
|
||||||
|
struct in6_addr any;
|
||||||
|
|
||||||
|
for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
|
||||||
|
if (!ipv6_addr_equal(local, &t->parms.laddr) ||
|
||||||
|
- !ipv6_addr_equal(remote, &t->parms.raddr) ||
|
||||||
|
!(t->dev->flags & IFF_UP))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
+ if (!ipv6_addr_equal(remote, &t->parms.raddr)) {
|
||||||
|
+ struct __ip6_tnl_fmr *fmr;
|
||||||
|
+ bool found = false;
|
||||||
|
+
|
||||||
|
+ for (fmr = t->parms.fmrs; fmr; fmr = fmr->next) {
|
||||||
|
+ if (!ipv6_prefix_equal(remote, &fmr->ip6_prefix,
|
||||||
|
+ fmr->ip6_prefix_len))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ found = true;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!found)
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (link == t->parms.link)
|
||||||
|
return t;
|
||||||
|
else
|
||||||
|
@@ -133,7 +152,7 @@ ip6_tnl_lookup(struct net *net, int link
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&any, 0, sizeof(any));
|
||||||
|
- hash = HASH(&any, local);
|
||||||
|
+ hash = HASH(local);
|
||||||
|
for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
|
||||||
|
if (!ipv6_addr_equal(local, &t->parms.laddr) ||
|
||||||
|
!ipv6_addr_any(&t->parms.raddr) ||
|
||||||
|
@@ -146,7 +165,7 @@ ip6_tnl_lookup(struct net *net, int link
|
||||||
|
cand = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
- hash = HASH(remote, &any);
|
||||||
|
+ hash = HASH(&any);
|
||||||
|
for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
|
||||||
|
if (!ipv6_addr_equal(remote, &t->parms.raddr) ||
|
||||||
|
!ipv6_addr_any(&t->parms.laddr) ||
|
||||||
|
@@ -195,7 +214,7 @@ ip6_tnl_bucket(struct ip6_tnl_net *ip6n,
|
||||||
|
|
||||||
|
if (!ipv6_addr_any(remote) || !ipv6_addr_any(local)) {
|
||||||
|
prio = 1;
|
||||||
|
- h = HASH(remote, local);
|
||||||
|
+ h = HASH(local);
|
||||||
|
}
|
||||||
|
return &ip6n->tnls[prio][h];
|
||||||
|
}
|
||||||
|
@@ -376,6 +395,12 @@ ip6_tnl_dev_uninit(struct net_device *de
|
||||||
|
struct net *net = t->net;
|
||||||
|
struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
|
||||||
|
|
||||||
|
+ while (t->parms.fmrs) {
|
||||||
|
+ struct __ip6_tnl_fmr *next = t->parms.fmrs->next;
|
||||||
|
+ kfree(t->parms.fmrs);
|
||||||
|
+ t->parms.fmrs = next;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (dev == ip6n->fb_tnl_dev)
|
||||||
|
RCU_INIT_POINTER(ip6n->tnls_wc[0], NULL);
|
||||||
|
else
|
||||||
|
@@ -790,6 +815,107 @@ int ip6_tnl_rcv_ctl(struct ip6_tnl *t,
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(ip6_tnl_rcv_ctl);
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * ip4ip6_fmr_calc - calculate target / source IPv6-address based on FMR
|
||||||
|
+ * @dest: destination IPv6 address buffer
|
||||||
|
+ * @skb: received socket buffer
|
||||||
|
+ * @fmr: MAP FMR
|
||||||
|
+ * @xmit: Calculate for xmit or rcv
|
||||||
|
+ **/
|
||||||
|
+static void ip4ip6_fmr_calc(struct in6_addr *dest,
|
||||||
|
+ const struct iphdr *iph, const uint8_t *end,
|
||||||
|
+ const struct __ip6_tnl_fmr *fmr, bool xmit)
|
||||||
|
+{
|
||||||
|
+ int psidlen = fmr->ea_len - (32 - fmr->ip4_prefix_len);
|
||||||
|
+ u8 *portp = NULL;
|
||||||
|
+ bool use_dest_addr;
|
||||||
|
+ const struct iphdr *dsth = iph;
|
||||||
|
+
|
||||||
|
+ if ((u8*)dsth >= end)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ /* find significant IP header */
|
||||||
|
+ if (iph->protocol == IPPROTO_ICMP) {
|
||||||
|
+ struct icmphdr *ih = (struct icmphdr*)(((u8*)dsth) + dsth->ihl * 4);
|
||||||
|
+ if (ih && ((u8*)&ih[1]) <= end && (
|
||||||
|
+ ih->type == ICMP_DEST_UNREACH ||
|
||||||
|
+ ih->type == ICMP_SOURCE_QUENCH ||
|
||||||
|
+ ih->type == ICMP_TIME_EXCEEDED ||
|
||||||
|
+ ih->type == ICMP_PARAMETERPROB ||
|
||||||
|
+ ih->type == ICMP_REDIRECT))
|
||||||
|
+ dsth = (const struct iphdr*)&ih[1];
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* in xmit-path use dest port by default and source port only if
|
||||||
|
+ this is an ICMP reply to something else; vice versa in rcv-path */
|
||||||
|
+ use_dest_addr = (xmit && dsth == iph) || (!xmit && dsth != iph);
|
||||||
|
+
|
||||||
|
+ /* get dst port */
|
||||||
|
+ if (((u8*)&dsth[1]) <= end && (
|
||||||
|
+ dsth->protocol == IPPROTO_UDP ||
|
||||||
|
+ dsth->protocol == IPPROTO_TCP ||
|
||||||
|
+ dsth->protocol == IPPROTO_SCTP ||
|
||||||
|
+ dsth->protocol == IPPROTO_DCCP)) {
|
||||||
|
+ /* for UDP, TCP, SCTP and DCCP source and dest port
|
||||||
|
+ follow IPv4 header directly */
|
||||||
|
+ portp = ((u8*)dsth) + dsth->ihl * 4;
|
||||||
|
+
|
||||||
|
+ if (use_dest_addr)
|
||||||
|
+ portp += sizeof(u16);
|
||||||
|
+ } else if (iph->protocol == IPPROTO_ICMP) {
|
||||||
|
+ struct icmphdr *ih = (struct icmphdr*)(((u8*)dsth) + dsth->ihl * 4);
|
||||||
|
+
|
||||||
|
+ /* use icmp identifier as port */
|
||||||
|
+ if (((u8*)&ih) <= end && (
|
||||||
|
+ (use_dest_addr && (
|
||||||
|
+ ih->type == ICMP_ECHOREPLY ||
|
||||||
|
+ ih->type == ICMP_TIMESTAMPREPLY ||
|
||||||
|
+ ih->type == ICMP_INFO_REPLY ||
|
||||||
|
+ ih->type == ICMP_ADDRESSREPLY)) ||
|
||||||
|
+ (!use_dest_addr && (
|
||||||
|
+ ih->type == ICMP_ECHO ||
|
||||||
|
+ ih->type == ICMP_TIMESTAMP ||
|
||||||
|
+ ih->type == ICMP_INFO_REQUEST ||
|
||||||
|
+ ih->type == ICMP_ADDRESS)
|
||||||
|
+ )))
|
||||||
|
+ portp = (u8*)&ih->un.echo.id;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if ((portp && &portp[2] <= end) || psidlen == 0) {
|
||||||
|
+ int frombyte = fmr->ip6_prefix_len / 8;
|
||||||
|
+ int fromrem = fmr->ip6_prefix_len % 8;
|
||||||
|
+ int bytes = sizeof(struct in6_addr) - frombyte;
|
||||||
|
+ const u32 *addr = (use_dest_addr) ? &iph->daddr : &iph->saddr;
|
||||||
|
+ u64 eabits = ((u64)ntohl(*addr)) << (32 + fmr->ip4_prefix_len);
|
||||||
|
+ u64 t = 0;
|
||||||
|
+
|
||||||
|
+ /* extract PSID from port and add it to eabits */
|
||||||
|
+ u16 psidbits = 0;
|
||||||
|
+ if (psidlen > 0) {
|
||||||
|
+ psidbits = ((u16)portp[0]) << 8 | ((u16)portp[1]);
|
||||||
|
+ psidbits >>= 16 - psidlen - fmr->offset;
|
||||||
|
+ psidbits = (u16)(psidbits << (16 - psidlen));
|
||||||
|
+ eabits |= ((u64)psidbits) << (48 - (fmr->ea_len - psidlen));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* rewrite destination address */
|
||||||
|
+ *dest = fmr->ip6_prefix;
|
||||||
|
+ memcpy(&dest->s6_addr[10], addr, sizeof(*addr));
|
||||||
|
+ dest->s6_addr16[7] = htons(psidbits >> (16 - psidlen));
|
||||||
|
+
|
||||||
|
+ if (bytes > sizeof(u64))
|
||||||
|
+ bytes = sizeof(u64);
|
||||||
|
+
|
||||||
|
+ /* insert eabits */
|
||||||
|
+ memcpy(&t, &dest->s6_addr[frombyte], bytes);
|
||||||
|
+ t = be64_to_cpu(t) & ~(((((u64)1) << fmr->ea_len) - 1)
|
||||||
|
+ << (64 - fmr->ea_len - fromrem));
|
||||||
|
+ t = cpu_to_be64(t | (eabits >> fromrem));
|
||||||
|
+ memcpy(&dest->s6_addr[frombyte], &t, bytes);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb,
|
||||||
|
const struct tnl_ptk_info *tpi,
|
||||||
|
struct metadata_dst *tun_dst,
|
||||||
|
@@ -855,6 +981,27 @@ static int __ip6_tnl_rcv(struct ip6_tnl
|
||||||
|
|
||||||
|
memset(skb->cb, 0, sizeof(struct inet6_skb_parm));
|
||||||
|
|
||||||
|
+ if (tpi->proto == htons(ETH_P_IP) && tunnel->parms.fmrs &&
|
||||||
|
+ !ipv6_addr_equal(&ipv6h->saddr, &tunnel->parms.raddr)) {
|
||||||
|
+ /* Packet didn't come from BR, so lookup FMR */
|
||||||
|
+ struct __ip6_tnl_fmr *fmr;
|
||||||
|
+ struct in6_addr expected = tunnel->parms.raddr;
|
||||||
|
+ for (fmr = tunnel->parms.fmrs; fmr; fmr = fmr->next)
|
||||||
|
+ if (ipv6_prefix_equal(&ipv6h->saddr,
|
||||||
|
+ &fmr->ip6_prefix, fmr->ip6_prefix_len))
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ /* Check that IPv6 matches IPv4 source to prevent spoofing */
|
||||||
|
+ if (fmr)
|
||||||
|
+ ip4ip6_fmr_calc(&expected, ip_hdr(skb),
|
||||||
|
+ skb_tail_pointer(skb), fmr, false);
|
||||||
|
+
|
||||||
|
+ if (!ipv6_addr_equal(&ipv6h->saddr, &expected)) {
|
||||||
|
+ rcu_read_unlock();
|
||||||
|
+ goto drop;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
__skb_tunnel_rx(skb, tunnel->dev, tunnel->net);
|
||||||
|
|
||||||
|
err = dscp_ecn_decapsulate(tunnel, ipv6h, skb);
|
||||||
|
@@ -1004,6 +1151,7 @@ static void init_tel_txopt(struct ipv6_t
|
||||||
|
opt->ops.opt_nflen = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* ip6_tnl_addr_conflict - compare packet addresses to tunnel's own
|
||||||
|
* @t: the outgoing tunnel device
|
||||||
|
@@ -1294,6 +1442,7 @@ ipxip6_tnl_xmit(struct sk_buff *skb, str
|
||||||
|
u8 protocol)
|
||||||
|
{
|
||||||
|
struct ip6_tnl *t = netdev_priv(dev);
|
||||||
|
+ struct __ip6_tnl_fmr *fmr;
|
||||||
|
struct ipv6hdr *ipv6h;
|
||||||
|
const struct iphdr *iph;
|
||||||
|
int encap_limit = -1;
|
||||||
|
@@ -1393,6 +1542,18 @@ ipxip6_tnl_xmit(struct sk_buff *skb, str
|
||||||
|
fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL);
|
||||||
|
dsfield = INET_ECN_encapsulate(dsfield, orig_dsfield);
|
||||||
|
|
||||||
|
+ /* try to find matching FMR */
|
||||||
|
+ for (fmr = t->parms.fmrs; fmr; fmr = fmr->next) {
|
||||||
|
+ unsigned mshift = 32 - fmr->ip4_prefix_len;
|
||||||
|
+ if (ntohl(fmr->ip4_prefix.s_addr) >> mshift ==
|
||||||
|
+ ntohl(ip_hdr(skb)->daddr) >> mshift)
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* change dstaddr according to FMR */
|
||||||
|
+ if (fmr)
|
||||||
|
+ ip4ip6_fmr_calc(&fl6.daddr, ip_hdr(skb), skb_tail_pointer(skb), fmr, true);
|
||||||
|
+
|
||||||
|
if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
@@ -1546,6 +1707,14 @@ ip6_tnl_change(struct ip6_tnl *t, const
|
||||||
|
t->parms.link = p->link;
|
||||||
|
t->parms.proto = p->proto;
|
||||||
|
t->parms.fwmark = p->fwmark;
|
||||||
|
+
|
||||||
|
+ while (t->parms.fmrs) {
|
||||||
|
+ struct __ip6_tnl_fmr *next = t->parms.fmrs->next;
|
||||||
|
+ kfree(t->parms.fmrs);
|
||||||
|
+ t->parms.fmrs = next;
|
||||||
|
+ }
|
||||||
|
+ t->parms.fmrs = p->fmrs;
|
||||||
|
+
|
||||||
|
dst_cache_reset(&t->dst_cache);
|
||||||
|
ip6_tnl_link_config(t);
|
||||||
|
}
|
||||||
|
@@ -1580,6 +1749,7 @@ ip6_tnl_parm_from_user(struct __ip6_tnl_
|
||||||
|
p->flowinfo = u->flowinfo;
|
||||||
|
p->link = u->link;
|
||||||
|
p->proto = u->proto;
|
||||||
|
+ p->fmrs = NULL;
|
||||||
|
memcpy(p->name, u->name, sizeof(u->name));
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1963,6 +2133,15 @@ static int ip6_tnl_validate(struct nlatt
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static const struct nla_policy ip6_tnl_fmr_policy[IFLA_IPTUN_FMR_MAX + 1] = {
|
||||||
|
+ [IFLA_IPTUN_FMR_IP6_PREFIX] = { .len = sizeof(struct in6_addr) },
|
||||||
|
+ [IFLA_IPTUN_FMR_IP4_PREFIX] = { .len = sizeof(struct in_addr) },
|
||||||
|
+ [IFLA_IPTUN_FMR_IP6_PREFIX_LEN] = { .type = NLA_U8 },
|
||||||
|
+ [IFLA_IPTUN_FMR_IP4_PREFIX_LEN] = { .type = NLA_U8 },
|
||||||
|
+ [IFLA_IPTUN_FMR_EA_LEN] = { .type = NLA_U8 },
|
||||||
|
+ [IFLA_IPTUN_FMR_OFFSET] = { .type = NLA_U8 }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
static void ip6_tnl_netlink_parms(struct nlattr *data[],
|
||||||
|
struct __ip6_tnl_parm *parms)
|
||||||
|
{
|
||||||
|
@@ -2000,6 +2179,46 @@ static void ip6_tnl_netlink_parms(struct
|
||||||
|
|
||||||
|
if (data[IFLA_IPTUN_FWMARK])
|
||||||
|
parms->fwmark = nla_get_u32(data[IFLA_IPTUN_FWMARK]);
|
||||||
|
+
|
||||||
|
+ if (data[IFLA_IPTUN_FMRS]) {
|
||||||
|
+ unsigned rem;
|
||||||
|
+ struct nlattr *fmr;
|
||||||
|
+ nla_for_each_nested(fmr, data[IFLA_IPTUN_FMRS], rem) {
|
||||||
|
+ struct nlattr *fmrd[IFLA_IPTUN_FMR_MAX + 1], *c;
|
||||||
|
+ struct __ip6_tnl_fmr *nfmr;
|
||||||
|
+
|
||||||
|
+ nla_parse_nested(fmrd, IFLA_IPTUN_FMR_MAX,
|
||||||
|
+ fmr, ip6_tnl_fmr_policy, NULL);
|
||||||
|
+
|
||||||
|
+ if (!(nfmr = kzalloc(sizeof(*nfmr), GFP_KERNEL)))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ nfmr->offset = 6;
|
||||||
|
+
|
||||||
|
+ if ((c = fmrd[IFLA_IPTUN_FMR_IP6_PREFIX]))
|
||||||
|
+ nla_memcpy(&nfmr->ip6_prefix, fmrd[IFLA_IPTUN_FMR_IP6_PREFIX],
|
||||||
|
+ sizeof(nfmr->ip6_prefix));
|
||||||
|
+
|
||||||
|
+ if ((c = fmrd[IFLA_IPTUN_FMR_IP4_PREFIX]))
|
||||||
|
+ nla_memcpy(&nfmr->ip4_prefix, fmrd[IFLA_IPTUN_FMR_IP4_PREFIX],
|
||||||
|
+ sizeof(nfmr->ip4_prefix));
|
||||||
|
+
|
||||||
|
+ if ((c = fmrd[IFLA_IPTUN_FMR_IP6_PREFIX_LEN]))
|
||||||
|
+ nfmr->ip6_prefix_len = nla_get_u8(c);
|
||||||
|
+
|
||||||
|
+ if ((c = fmrd[IFLA_IPTUN_FMR_IP4_PREFIX_LEN]))
|
||||||
|
+ nfmr->ip4_prefix_len = nla_get_u8(c);
|
||||||
|
+
|
||||||
|
+ if ((c = fmrd[IFLA_IPTUN_FMR_EA_LEN]))
|
||||||
|
+ nfmr->ea_len = nla_get_u8(c);
|
||||||
|
+
|
||||||
|
+ if ((c = fmrd[IFLA_IPTUN_FMR_OFFSET]))
|
||||||
|
+ nfmr->offset = nla_get_u8(c);
|
||||||
|
+
|
||||||
|
+ nfmr->next = parms->fmrs;
|
||||||
|
+ parms->fmrs = nfmr;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ip6_tnl_newlink(struct net *src_net, struct net_device *dev,
|
||||||
|
@@ -2083,6 +2302,12 @@ static void ip6_tnl_dellink(struct net_d
|
||||||
|
|
||||||
|
static size_t ip6_tnl_get_size(const struct net_device *dev)
|
||||||
|
{
|
||||||
|
+ const struct ip6_tnl *t = netdev_priv(dev);
|
||||||
|
+ struct __ip6_tnl_fmr *c;
|
||||||
|
+ int fmrs = 0;
|
||||||
|
+ for (c = t->parms.fmrs; c; c = c->next)
|
||||||
|
+ ++fmrs;
|
||||||
|
+
|
||||||
|
return
|
||||||
|
/* IFLA_IPTUN_LINK */
|
||||||
|
nla_total_size(4) +
|
||||||
|
@@ -2112,6 +2337,24 @@ static size_t ip6_tnl_get_size(const str
|
||||||
|
nla_total_size(0) +
|
||||||
|
/* IFLA_IPTUN_FWMARK */
|
||||||
|
nla_total_size(4) +
|
||||||
|
+ /* IFLA_IPTUN_FMRS */
|
||||||
|
+ nla_total_size(0) +
|
||||||
|
+ (
|
||||||
|
+ /* nest */
|
||||||
|
+ nla_total_size(0) +
|
||||||
|
+ /* IFLA_IPTUN_FMR_IP6_PREFIX */
|
||||||
|
+ nla_total_size(sizeof(struct in6_addr)) +
|
||||||
|
+ /* IFLA_IPTUN_FMR_IP4_PREFIX */
|
||||||
|
+ nla_total_size(sizeof(struct in_addr)) +
|
||||||
|
+ /* IFLA_IPTUN_FMR_EA_LEN */
|
||||||
|
+ nla_total_size(1) +
|
||||||
|
+ /* IFLA_IPTUN_FMR_IP6_PREFIX_LEN */
|
||||||
|
+ nla_total_size(1) +
|
||||||
|
+ /* IFLA_IPTUN_FMR_IP4_PREFIX_LEN */
|
||||||
|
+ nla_total_size(1) +
|
||||||
|
+ /* IFLA_IPTUN_FMR_OFFSET */
|
||||||
|
+ nla_total_size(1)
|
||||||
|
+ ) * fmrs +
|
||||||
|
0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2119,6 +2362,9 @@ static int ip6_tnl_fill_info(struct sk_b
|
||||||
|
{
|
||||||
|
struct ip6_tnl *tunnel = netdev_priv(dev);
|
||||||
|
struct __ip6_tnl_parm *parm = &tunnel->parms;
|
||||||
|
+ struct __ip6_tnl_fmr *c;
|
||||||
|
+ int fmrcnt = 0;
|
||||||
|
+ struct nlattr *fmrs;
|
||||||
|
|
||||||
|
if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) ||
|
||||||
|
nla_put_in6_addr(skb, IFLA_IPTUN_LOCAL, &parm->laddr) ||
|
||||||
|
@@ -2128,9 +2374,27 @@ static int ip6_tnl_fill_info(struct sk_b
|
||||||
|
nla_put_be32(skb, IFLA_IPTUN_FLOWINFO, parm->flowinfo) ||
|
||||||
|
nla_put_u32(skb, IFLA_IPTUN_FLAGS, parm->flags) ||
|
||||||
|
nla_put_u8(skb, IFLA_IPTUN_PROTO, parm->proto) ||
|
||||||
|
- nla_put_u32(skb, IFLA_IPTUN_FWMARK, parm->fwmark))
|
||||||
|
+ nla_put_u32(skb, IFLA_IPTUN_FWMARK, parm->fwmark) ||
|
||||||
|
+ !(fmrs = nla_nest_start(skb, IFLA_IPTUN_FMRS)))
|
||||||
|
goto nla_put_failure;
|
||||||
|
|
||||||
|
+ for (c = parm->fmrs; c; c = c->next) {
|
||||||
|
+ struct nlattr *fmr = nla_nest_start(skb, ++fmrcnt);
|
||||||
|
+ if (!fmr ||
|
||||||
|
+ nla_put(skb, IFLA_IPTUN_FMR_IP6_PREFIX,
|
||||||
|
+ sizeof(c->ip6_prefix), &c->ip6_prefix) ||
|
||||||
|
+ nla_put(skb, IFLA_IPTUN_FMR_IP4_PREFIX,
|
||||||
|
+ sizeof(c->ip4_prefix), &c->ip4_prefix) ||
|
||||||
|
+ nla_put_u8(skb, IFLA_IPTUN_FMR_IP6_PREFIX_LEN, c->ip6_prefix_len) ||
|
||||||
|
+ nla_put_u8(skb, IFLA_IPTUN_FMR_IP4_PREFIX_LEN, c->ip4_prefix_len) ||
|
||||||
|
+ nla_put_u8(skb, IFLA_IPTUN_FMR_EA_LEN, c->ea_len) ||
|
||||||
|
+ nla_put_u8(skb, IFLA_IPTUN_FMR_OFFSET, c->offset))
|
||||||
|
+ goto nla_put_failure;
|
||||||
|
+
|
||||||
|
+ nla_nest_end(skb, fmr);
|
||||||
|
+ }
|
||||||
|
+ nla_nest_end(skb, fmrs);
|
||||||
|
+
|
||||||
|
if (nla_put_u16(skb, IFLA_IPTUN_ENCAP_TYPE, tunnel->encap.type) ||
|
||||||
|
nla_put_be16(skb, IFLA_IPTUN_ENCAP_SPORT, tunnel->encap.sport) ||
|
||||||
|
nla_put_be16(skb, IFLA_IPTUN_ENCAP_DPORT, tunnel->encap.dport) ||
|
||||||
|
@@ -2170,6 +2434,7 @@ static const struct nla_policy ip6_tnl_p
|
||||||
|
[IFLA_IPTUN_ENCAP_DPORT] = { .type = NLA_U16 },
|
||||||
|
[IFLA_IPTUN_COLLECT_METADATA] = { .type = NLA_FLAG },
|
||||||
|
[IFLA_IPTUN_FWMARK] = { .type = NLA_U32 },
|
||||||
|
+ [IFLA_IPTUN_FMRS] = { .type = NLA_NESTED },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct rtnl_link_ops ip6_link_ops __read_mostly = {
|
@ -0,0 +1,263 @@
|
|||||||
|
From: Jonas Gorski <jogo@openwrt.org>
|
||||||
|
Subject: ipv6: allow rejecting with "source address failed policy"
|
||||||
|
|
||||||
|
RFC6204 L-14 requires rejecting traffic from invalid addresses with
|
||||||
|
ICMPv6 Destination Unreachable, Code 5 (Source address failed ingress/
|
||||||
|
egress policy) on the LAN side, so add an appropriate rule for that.
|
||||||
|
|
||||||
|
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
|
||||||
|
---
|
||||||
|
include/net/netns/ipv6.h | 1 +
|
||||||
|
include/uapi/linux/fib_rules.h | 4 +++
|
||||||
|
include/uapi/linux/rtnetlink.h | 1 +
|
||||||
|
net/ipv4/fib_semantics.c | 4 +++
|
||||||
|
net/ipv4/fib_trie.c | 1 +
|
||||||
|
net/ipv4/ipmr.c | 1 +
|
||||||
|
net/ipv6/fib6_rules.c | 4 +++
|
||||||
|
net/ipv6/ip6mr.c | 2 ++
|
||||||
|
net/ipv6/route.c | 58 +++++++++++++++++++++++++++++++++++++++++-
|
||||||
|
9 files changed, 75 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/include/net/netns/ipv6.h
|
||||||
|
+++ b/include/net/netns/ipv6.h
|
||||||
|
@@ -86,6 +86,7 @@ struct netns_ipv6 {
|
||||||
|
unsigned int fib6_routes_require_src;
|
||||||
|
#endif
|
||||||
|
struct rt6_info *ip6_prohibit_entry;
|
||||||
|
+ struct rt6_info *ip6_policy_failed_entry;
|
||||||
|
struct rt6_info *ip6_blk_hole_entry;
|
||||||
|
struct fib6_table *fib6_local_tbl;
|
||||||
|
struct fib_rules_ops *fib6_rules_ops;
|
||||||
|
--- a/include/uapi/linux/fib_rules.h
|
||||||
|
+++ b/include/uapi/linux/fib_rules.h
|
||||||
|
@@ -83,6 +83,10 @@ enum {
|
||||||
|
FR_ACT_BLACKHOLE, /* Drop without notification */
|
||||||
|
FR_ACT_UNREACHABLE, /* Drop with ENETUNREACH */
|
||||||
|
FR_ACT_PROHIBIT, /* Drop with EACCES */
|
||||||
|
+ FR_ACT_RES9,
|
||||||
|
+ FR_ACT_RES10,
|
||||||
|
+ FR_ACT_RES11,
|
||||||
|
+ FR_ACT_POLICY_FAILED, /* Drop with EACCES */
|
||||||
|
__FR_ACT_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
--- a/include/uapi/linux/rtnetlink.h
|
||||||
|
+++ b/include/uapi/linux/rtnetlink.h
|
||||||
|
@@ -265,6 +265,7 @@ enum {
|
||||||
|
RTN_THROW, /* Not in this table */
|
||||||
|
RTN_NAT, /* Translate this address */
|
||||||
|
RTN_XRESOLVE, /* Use external resolver */
|
||||||
|
+ RTN_POLICY_FAILED, /* Failed ingress/egress policy */
|
||||||
|
__RTN_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
--- a/net/ipv4/fib_semantics.c
|
||||||
|
+++ b/net/ipv4/fib_semantics.c
|
||||||
|
@@ -145,6 +145,10 @@ const struct fib_prop fib_props[RTN_MAX
|
||||||
|
.error = -EINVAL,
|
||||||
|
.scope = RT_SCOPE_NOWHERE,
|
||||||
|
},
|
||||||
|
+ [RTN_POLICY_FAILED] = {
|
||||||
|
+ .error = -EACCES,
|
||||||
|
+ .scope = RT_SCOPE_UNIVERSE,
|
||||||
|
+ },
|
||||||
|
};
|
||||||
|
|
||||||
|
static void rt_fibinfo_free(struct rtable __rcu **rtp)
|
||||||
|
--- a/net/ipv4/fib_trie.c
|
||||||
|
+++ b/net/ipv4/fib_trie.c
|
||||||
|
@@ -2784,6 +2784,7 @@ static const char *const rtn_type_names[
|
||||||
|
[RTN_THROW] = "THROW",
|
||||||
|
[RTN_NAT] = "NAT",
|
||||||
|
[RTN_XRESOLVE] = "XRESOLVE",
|
||||||
|
+ [RTN_POLICY_FAILED] = "POLICY_FAILED",
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline const char *rtn_type(char *buf, size_t len, unsigned int t)
|
||||||
|
--- a/net/ipv4/ipmr.c
|
||||||
|
+++ b/net/ipv4/ipmr.c
|
||||||
|
@@ -181,6 +181,7 @@ static int ipmr_rule_action(struct fib_r
|
||||||
|
case FR_ACT_UNREACHABLE:
|
||||||
|
return -ENETUNREACH;
|
||||||
|
case FR_ACT_PROHIBIT:
|
||||||
|
+ case FR_ACT_POLICY_FAILED:
|
||||||
|
return -EACCES;
|
||||||
|
case FR_ACT_BLACKHOLE:
|
||||||
|
default:
|
||||||
|
--- a/net/ipv6/fib6_rules.c
|
||||||
|
+++ b/net/ipv6/fib6_rules.c
|
||||||
|
@@ -222,6 +222,10 @@ static int __fib6_rule_action(struct fib
|
||||||
|
err = -EACCES;
|
||||||
|
rt = net->ipv6.ip6_prohibit_entry;
|
||||||
|
goto discard_pkt;
|
||||||
|
+ case FR_ACT_POLICY_FAILED:
|
||||||
|
+ err = -EACCES;
|
||||||
|
+ rt = net->ipv6.ip6_policy_failed_entry;
|
||||||
|
+ goto discard_pkt;
|
||||||
|
}
|
||||||
|
|
||||||
|
tb_id = fib_rule_get_table(rule, arg);
|
||||||
|
--- a/net/ipv6/ip6mr.c
|
||||||
|
+++ b/net/ipv6/ip6mr.c
|
||||||
|
@@ -170,6 +170,8 @@ static int ip6mr_rule_action(struct fib_
|
||||||
|
return -ENETUNREACH;
|
||||||
|
case FR_ACT_PROHIBIT:
|
||||||
|
return -EACCES;
|
||||||
|
+ case FR_ACT_POLICY_FAILED:
|
||||||
|
+ return -EACCES;
|
||||||
|
case FR_ACT_BLACKHOLE:
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
--- a/net/ipv6/route.c
|
||||||
|
+++ b/net/ipv6/route.c
|
||||||
|
@@ -98,6 +98,8 @@ static int ip6_pkt_discard(struct sk_bu
|
||||||
|
static int ip6_pkt_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb);
|
||||||
|
static int ip6_pkt_prohibit(struct sk_buff *skb);
|
||||||
|
static int ip6_pkt_prohibit_out(struct net *net, struct sock *sk, struct sk_buff *skb);
|
||||||
|
+static int ip6_pkt_policy_failed(struct sk_buff *skb);
|
||||||
|
+static int ip6_pkt_policy_failed_out(struct net *net, struct sock *sk, struct sk_buff *skb);
|
||||||
|
static void ip6_link_failure(struct sk_buff *skb);
|
||||||
|
static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
|
||||||
|
struct sk_buff *skb, u32 mtu,
|
||||||
|
@@ -316,6 +318,18 @@ static const struct rt6_info ip6_prohibi
|
||||||
|
.rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP),
|
||||||
|
};
|
||||||
|
|
||||||
|
+static const struct rt6_info ip6_policy_failed_entry_template = {
|
||||||
|
+ .dst = {
|
||||||
|
+ .__rcuref = RCUREF_INIT(1),
|
||||||
|
+ .__use = 1,
|
||||||
|
+ .obsolete = DST_OBSOLETE_FORCE_CHK,
|
||||||
|
+ .error = -EACCES,
|
||||||
|
+ .input = ip6_pkt_policy_failed,
|
||||||
|
+ .output = ip6_pkt_policy_failed_out,
|
||||||
|
+ },
|
||||||
|
+ .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
static const struct rt6_info ip6_blk_hole_entry_template = {
|
||||||
|
.dst = {
|
||||||
|
.__rcuref = RCUREF_INIT(1),
|
||||||
|
@@ -1048,6 +1062,7 @@ static const int fib6_prop[RTN_MAX + 1]
|
||||||
|
[RTN_BLACKHOLE] = -EINVAL,
|
||||||
|
[RTN_UNREACHABLE] = -EHOSTUNREACH,
|
||||||
|
[RTN_PROHIBIT] = -EACCES,
|
||||||
|
+ [RTN_POLICY_FAILED] = -EACCES,
|
||||||
|
[RTN_THROW] = -EAGAIN,
|
||||||
|
[RTN_NAT] = -EINVAL,
|
||||||
|
[RTN_XRESOLVE] = -EINVAL,
|
||||||
|
@@ -1083,6 +1098,10 @@ static void ip6_rt_init_dst_reject(struc
|
||||||
|
rt->dst.output = ip6_pkt_prohibit_out;
|
||||||
|
rt->dst.input = ip6_pkt_prohibit;
|
||||||
|
break;
|
||||||
|
+ case RTN_POLICY_FAILED:
|
||||||
|
+ rt->dst.output = ip6_pkt_policy_failed_out;
|
||||||
|
+ rt->dst.input = ip6_pkt_policy_failed;
|
||||||
|
+ break;
|
||||||
|
case RTN_THROW:
|
||||||
|
case RTN_UNREACHABLE:
|
||||||
|
default:
|
||||||
|
@@ -4555,6 +4574,17 @@ static int ip6_pkt_prohibit_out(struct n
|
||||||
|
return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int ip6_pkt_policy_failed(struct sk_buff *skb)
|
||||||
|
+{
|
||||||
|
+ return ip6_pkt_drop(skb, ICMPV6_POLICY_FAIL, IPSTATS_MIB_INNOROUTES);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int ip6_pkt_policy_failed_out(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||||
|
+{
|
||||||
|
+ skb->dev = skb_dst(skb)->dev;
|
||||||
|
+ return ip6_pkt_drop(skb, ICMPV6_POLICY_FAIL, IPSTATS_MIB_OUTNOROUTES);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Allocate a dst for local (unicast / anycast) address.
|
||||||
|
*/
|
||||||
|
@@ -5046,7 +5076,8 @@ static int rtm_to_fib6_config(struct sk_
|
||||||
|
if (rtm->rtm_type == RTN_UNREACHABLE ||
|
||||||
|
rtm->rtm_type == RTN_BLACKHOLE ||
|
||||||
|
rtm->rtm_type == RTN_PROHIBIT ||
|
||||||
|
- rtm->rtm_type == RTN_THROW)
|
||||||
|
+ rtm->rtm_type == RTN_THROW ||
|
||||||
|
+ rtm->rtm_type == RTN_POLICY_FAILED)
|
||||||
|
cfg->fc_flags |= RTF_REJECT;
|
||||||
|
|
||||||
|
if (rtm->rtm_type == RTN_LOCAL)
|
||||||
|
@@ -6291,6 +6322,8 @@ static int ip6_route_dev_notify(struct n
|
||||||
|
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
|
||||||
|
net->ipv6.ip6_prohibit_entry->dst.dev = dev;
|
||||||
|
net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev);
|
||||||
|
+ net->ipv6.ip6_policy_failed_entry->dst.dev = dev;
|
||||||
|
+ net->ipv6.ip6_policy_failed_entry->rt6i_idev = in6_dev_get(dev);
|
||||||
|
net->ipv6.ip6_blk_hole_entry->dst.dev = dev;
|
||||||
|
net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev);
|
||||||
|
#endif
|
||||||
|
@@ -6302,6 +6335,7 @@ static int ip6_route_dev_notify(struct n
|
||||||
|
in6_dev_put_clear(&net->ipv6.ip6_null_entry->rt6i_idev);
|
||||||
|
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
|
||||||
|
in6_dev_put_clear(&net->ipv6.ip6_prohibit_entry->rt6i_idev);
|
||||||
|
+ in6_dev_put_clear(&net->ipv6.ip6_policy_failed_entry->rt6i_idev);
|
||||||
|
in6_dev_put_clear(&net->ipv6.ip6_blk_hole_entry->rt6i_idev);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
@@ -6497,6 +6531,8 @@ static int __net_init ip6_route_net_init
|
||||||
|
|
||||||
|
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
|
||||||
|
net->ipv6.fib6_has_custom_rules = false;
|
||||||
|
+
|
||||||
|
+
|
||||||
|
net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template,
|
||||||
|
sizeof(*net->ipv6.ip6_prohibit_entry),
|
||||||
|
GFP_KERNEL);
|
||||||
|
@@ -6507,11 +6543,21 @@ static int __net_init ip6_route_net_init
|
||||||
|
ip6_template_metrics, true);
|
||||||
|
INIT_LIST_HEAD(&net->ipv6.ip6_prohibit_entry->dst.rt_uncached);
|
||||||
|
|
||||||
|
+ net->ipv6.ip6_policy_failed_entry =
|
||||||
|
+ kmemdup(&ip6_policy_failed_entry_template,
|
||||||
|
+ sizeof(*net->ipv6.ip6_policy_failed_entry), GFP_KERNEL);
|
||||||
|
+ if (!net->ipv6.ip6_policy_failed_entry)
|
||||||
|
+ goto out_ip6_prohibit_entry;
|
||||||
|
+ net->ipv6.ip6_policy_failed_entry->dst.ops = &net->ipv6.ip6_dst_ops;
|
||||||
|
+ dst_init_metrics(&net->ipv6.ip6_policy_failed_entry->dst,
|
||||||
|
+ ip6_template_metrics, true);
|
||||||
|
+ INIT_LIST_HEAD(&net->ipv6.ip6_policy_failed_entry->dst.rt_uncached);
|
||||||
|
+
|
||||||
|
net->ipv6.ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template,
|
||||||
|
sizeof(*net->ipv6.ip6_blk_hole_entry),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!net->ipv6.ip6_blk_hole_entry)
|
||||||
|
- goto out_ip6_prohibit_entry;
|
||||||
|
+ goto out_ip6_policy_failed_entry;
|
||||||
|
net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops;
|
||||||
|
dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst,
|
||||||
|
ip6_template_metrics, true);
|
||||||
|
@@ -6538,6 +6584,8 @@ out:
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
|
||||||
|
+out_ip6_policy_failed_entry:
|
||||||
|
+ kfree(net->ipv6.ip6_policy_failed_entry);
|
||||||
|
out_ip6_prohibit_entry:
|
||||||
|
kfree(net->ipv6.ip6_prohibit_entry);
|
||||||
|
out_ip6_null_entry:
|
||||||
|
@@ -6557,6 +6605,7 @@ static void __net_exit ip6_route_net_exi
|
||||||
|
kfree(net->ipv6.ip6_null_entry);
|
||||||
|
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
|
||||||
|
kfree(net->ipv6.ip6_prohibit_entry);
|
||||||
|
+ kfree(net->ipv6.ip6_policy_failed_entry);
|
||||||
|
kfree(net->ipv6.ip6_blk_hole_entry);
|
||||||
|
#endif
|
||||||
|
dst_entries_destroy(&net->ipv6.ip6_dst_ops);
|
||||||
|
@@ -6640,6 +6689,9 @@ void __init ip6_route_init_special_entri
|
||||||
|
init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
|
||||||
|
init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev;
|
||||||
|
init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
|
||||||
|
+ init_net.ipv6.ip6_policy_failed_entry->dst.dev = init_net.loopback_dev;
|
||||||
|
+ init_net.ipv6.ip6_policy_failed_entry->rt6i_idev =
|
||||||
|
+ in6_dev_get(init_net.loopback_dev);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
|||||||
|
From: Jonas Gorski <jogo@openwrt.org>
|
||||||
|
Subject: net: provide defines for _POLICY_FAILED until all code is updated
|
||||||
|
|
||||||
|
Upstream introduced ICMPV6_POLICY_FAIL for code 5 of destination
|
||||||
|
unreachable, conflicting with our name.
|
||||||
|
|
||||||
|
Add appropriate defines to allow our code to build with the new
|
||||||
|
name until we have updated our local patches for older kernels
|
||||||
|
and userspace packages.
|
||||||
|
|
||||||
|
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
|
||||||
|
---
|
||||||
|
include/uapi/linux/fib_rules.h | 2 ++
|
||||||
|
include/uapi/linux/icmpv6.h | 2 ++
|
||||||
|
include/uapi/linux/rtnetlink.h | 2 ++
|
||||||
|
3 files changed, 6 insertions(+)
|
||||||
|
|
||||||
|
--- a/include/uapi/linux/fib_rules.h
|
||||||
|
+++ b/include/uapi/linux/fib_rules.h
|
||||||
|
@@ -90,6 +90,8 @@ enum {
|
||||||
|
__FR_ACT_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
+#define FR_ACT_FAILED_POLICY FR_ACT_POLICY_FAILED
|
||||||
|
+
|
||||||
|
#define FR_ACT_MAX (__FR_ACT_MAX - 1)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
--- a/include/uapi/linux/icmpv6.h
|
||||||
|
+++ b/include/uapi/linux/icmpv6.h
|
||||||
|
@@ -127,6 +127,8 @@ struct icmp6hdr {
|
||||||
|
#define ICMPV6_POLICY_FAIL 5
|
||||||
|
#define ICMPV6_REJECT_ROUTE 6
|
||||||
|
|
||||||
|
+#define ICMPV6_FAILED_POLICY ICMPV6_POLICY_FAIL
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Codes for Time Exceeded
|
||||||
|
*/
|
||||||
|
--- a/include/uapi/linux/rtnetlink.h
|
||||||
|
+++ b/include/uapi/linux/rtnetlink.h
|
||||||
|
@@ -269,6 +269,8 @@ enum {
|
||||||
|
__RTN_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
+#define RTN_FAILED_POLICY RTN_POLICY_FAILED
|
||||||
|
+
|
||||||
|
#define RTN_MAX (__RTN_MAX - 1)
|
||||||
|
|
||||||
|
|
@ -0,0 +1,90 @@
|
|||||||
|
From 844c273286f328acf0dab5fbd5d864366b4904dc Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
Date: Tue, 30 Mar 2021 18:21:14 +0200
|
||||||
|
Subject: [PATCH] of_net: add mac-address-increment support
|
||||||
|
|
||||||
|
Lots of embedded devices use the mac-address of other interface
|
||||||
|
extracted from nvmem cells and increments it by one or two. Add two
|
||||||
|
bindings to integrate this and directly use the right mac-address for
|
||||||
|
the interface. Some example are some routers that use the gmac
|
||||||
|
mac-address stored in the art partition and increments it by one for the
|
||||||
|
wifi. mac-address-increment-byte bindings is used to tell what byte of
|
||||||
|
the mac-address has to be increased (if not defined the last byte is
|
||||||
|
increased) and mac-address-increment tells how much the byte decided
|
||||||
|
early has to be increased.
|
||||||
|
|
||||||
|
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
||||||
|
---
|
||||||
|
net/core/of_net.c | 43 +++++++++++++++++++++++++++++++++++++++----
|
||||||
|
1 file changed, 39 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
--- a/net/core/of_net.c
|
||||||
|
+++ b/net/core/of_net.c
|
||||||
|
@@ -121,28 +121,63 @@ EXPORT_SYMBOL(of_get_mac_address_nvmem);
|
||||||
|
* this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
|
||||||
|
* but is all zeros.
|
||||||
|
*
|
||||||
|
+ * DT can tell the system to increment the mac-address after is extracted by
|
||||||
|
+ * using:
|
||||||
|
+ * - mac-address-increment-byte to decide what byte to increase
|
||||||
|
+ * (if not defined is increased the last byte)
|
||||||
|
+ * - mac-address-increment to decide how much to increase. The value WILL
|
||||||
|
+ * overflow to other bytes if the increment is over 255 or the total
|
||||||
|
+ * increment will exceed 255 of the current byte.
|
||||||
|
+ * (example 00:01:02:03:04:ff + 1 == 00:01:02:03:05:00)
|
||||||
|
+ * (example 00:01:02:03:04:fe + 5 == 00:01:02:03:05:03)
|
||||||
|
+ *
|
||||||
|
* Return: 0 on success and errno in case of error.
|
||||||
|
*/
|
||||||
|
int of_get_mac_address(struct device_node *np, u8 *addr)
|
||||||
|
{
|
||||||
|
+ u32 inc_idx, mac_inc, mac_val;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
+ /* Check first if the increment byte is present and valid.
|
||||||
|
+ * If not set assume to increment the last byte if found.
|
||||||
|
+ */
|
||||||
|
+ if (of_property_read_u32(np, "mac-address-increment-byte", &inc_idx))
|
||||||
|
+ inc_idx = 5;
|
||||||
|
+ if (inc_idx < 3 || inc_idx > 5)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
if (!np)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
ret = of_get_mac_addr(np, "mac-address", addr);
|
||||||
|
if (!ret)
|
||||||
|
- return 0;
|
||||||
|
+ goto found;
|
||||||
|
|
||||||
|
ret = of_get_mac_addr(np, "local-mac-address", addr);
|
||||||
|
if (!ret)
|
||||||
|
- return 0;
|
||||||
|
+ goto found;
|
||||||
|
|
||||||
|
ret = of_get_mac_addr(np, "address", addr);
|
||||||
|
if (!ret)
|
||||||
|
- return 0;
|
||||||
|
+ goto found;
|
||||||
|
+
|
||||||
|
+ ret = of_get_mac_address_nvmem(np, addr);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+found:
|
||||||
|
+ if (!of_property_read_u32(np, "mac-address-increment", &mac_inc)) {
|
||||||
|
+ /* Convert to a contiguous value */
|
||||||
|
+ mac_val = (addr[3] << 16) + (addr[4] << 8) + addr[5];
|
||||||
|
+ mac_val += mac_inc << 8 * (5-inc_idx);
|
||||||
|
+
|
||||||
|
+ /* Apply the incremented value handling overflow case */
|
||||||
|
+ addr[3] = (mac_val >> 16) & 0xff;
|
||||||
|
+ addr[4] = (mac_val >> 8) & 0xff;
|
||||||
|
+ addr[5] = (mac_val >> 0) & 0xff;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- return of_get_mac_address_nvmem(np, addr);
|
||||||
|
+ return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(of_get_mac_address);
|
||||||
|
|
38
pending-6.12/683-of_net-add-mac-address-to-of-tree.patch
Normal file
38
pending-6.12/683-of_net-add-mac-address-to-of-tree.patch
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
--- a/net/core/of_net.c
|
||||||
|
+++ b/net/core/of_net.c
|
||||||
|
@@ -97,6 +97,27 @@ int of_get_mac_address_nvmem(struct devi
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(of_get_mac_address_nvmem);
|
||||||
|
|
||||||
|
+static int of_add_mac_address(struct device_node *np, u8* addr)
|
||||||
|
+{
|
||||||
|
+ struct property *prop;
|
||||||
|
+
|
||||||
|
+ prop = kzalloc(sizeof(*prop), GFP_KERNEL);
|
||||||
|
+ if (!prop)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ prop->name = "mac-address";
|
||||||
|
+ prop->length = ETH_ALEN;
|
||||||
|
+ prop->value = kmemdup(addr, ETH_ALEN, GFP_KERNEL);
|
||||||
|
+ if (!prop->value || of_update_property(np, prop))
|
||||||
|
+ goto free;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+free:
|
||||||
|
+ kfree(prop->value);
|
||||||
|
+ kfree(prop);
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* of_get_mac_address()
|
||||||
|
* @np: Caller's Device Node
|
||||||
|
@@ -177,6 +198,7 @@ found:
|
||||||
|
addr[5] = (mac_val >> 0) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ of_add_mac_address(np, addr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(of_get_mac_address);
|
@ -0,0 +1,26 @@
|
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Thu, 8 Jul 2021 07:08:29 +0200
|
||||||
|
Subject: [PATCH] net: ethernet: mtk_eth_soc: avoid creating duplicate offload
|
||||||
|
entries
|
||||||
|
|
||||||
|
Sometimes multiple CLS_REPLACE calls are issued for the same connection.
|
||||||
|
rhashtable_insert_fast does not check for these duplicates, so multiple
|
||||||
|
hardware flow entries can be created.
|
||||||
|
Fix this by checking for an existing entry early
|
||||||
|
|
||||||
|
Fixes: 502e84e2382d ("net: ethernet: mtk_eth_soc: add flow offloading support")
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
|
||||||
|
+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
|
||||||
|
@@ -260,6 +260,9 @@ mtk_flow_offload_replace(struct mtk_eth
|
||||||
|
if (rhashtable_lookup(ð->flow_table, &f->cookie, mtk_flow_ht_params))
|
||||||
|
return -EEXIST;
|
||||||
|
|
||||||
|
+ if (rhashtable_lookup(ð->flow_table, &f->cookie, mtk_flow_ht_params))
|
||||||
|
+ return -EEXIST;
|
||||||
|
+
|
||||||
|
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_META)) {
|
||||||
|
struct flow_match_meta match;
|
||||||
|
|
@ -0,0 +1,38 @@
|
|||||||
|
From: Gabor Juhos <juhosg@openwrt.org>
|
||||||
|
Subject: generic: add detach callback to struct phy_driver
|
||||||
|
|
||||||
|
lede-commit: fe61fc2d7d0b3fb348b502f68f98243b3ddf5867
|
||||||
|
|
||||||
|
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
|
||||||
|
---
|
||||||
|
drivers/net/phy/phy_device.c | 3 +++
|
||||||
|
include/linux/phy.h | 6 ++++++
|
||||||
|
2 files changed, 9 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/net/phy/phy_device.c
|
||||||
|
+++ b/drivers/net/phy/phy_device.c
|
||||||
|
@@ -1986,6 +1986,9 @@ void phy_detach(struct phy_device *phyde
|
||||||
|
if (phydev->devlink)
|
||||||
|
device_link_del(phydev->devlink);
|
||||||
|
|
||||||
|
+ if (phydev->drv && phydev->drv->detach)
|
||||||
|
+ phydev->drv->detach(phydev);
|
||||||
|
+
|
||||||
|
if (phydev->sysfs_links) {
|
||||||
|
if (dev)
|
||||||
|
sysfs_remove_link(&dev->dev.kobj, "phydev");
|
||||||
|
--- a/include/linux/phy.h
|
||||||
|
+++ b/include/linux/phy.h
|
||||||
|
@@ -998,6 +998,12 @@ struct phy_driver {
|
||||||
|
/** @handle_interrupt: Override default interrupt handling */
|
||||||
|
irqreturn_t (*handle_interrupt)(struct phy_device *phydev);
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * Called before an ethernet device is detached
|
||||||
|
+ * from the PHY.
|
||||||
|
+ */
|
||||||
|
+ void (*detach)(struct phy_device *phydev);
|
||||||
|
+
|
||||||
|
/** @remove: Clears up any memory if needed */
|
||||||
|
void (*remove)(struct phy_device *phydev);
|
||||||
|
|
@ -0,0 +1,27 @@
|
|||||||
|
From: Tobias Waldekranz <tobias@waldekranz.com>
|
||||||
|
Subject: [RFC net-next 7/7] net: dsa: mv88e6xxx: Request assisted learning on CPU port
|
||||||
|
Date: Sat, 16 Jan 2021 02:25:15 +0100
|
||||||
|
Archived-At: <https://lore.kernel.org/netdev/20210116012515.3152-8-tobias@waldekranz.com/>
|
||||||
|
|
||||||
|
While the hardware is capable of performing learning on the CPU port,
|
||||||
|
it requires alot of additions to the bridge's forwarding path in order
|
||||||
|
to handle multi-destination traffic correctly.
|
||||||
|
|
||||||
|
Until that is in place, opt for the next best thing and let DSA sync
|
||||||
|
the relevant addresses down to the hardware FDB.
|
||||||
|
|
||||||
|
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
|
||||||
|
---
|
||||||
|
drivers/net/dsa/mv88e6xxx/chip.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
--- a/drivers/net/dsa/mv88e6xxx/chip.c
|
||||||
|
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
|
||||||
|
@@ -7135,6 +7135,7 @@ static int mv88e6xxx_register_switch(str
|
||||||
|
ds->phylink_mac_ops = &mv88e6xxx_phylink_mac_ops;
|
||||||
|
ds->ageing_time_min = chip->info->age_time_coeff;
|
||||||
|
ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX;
|
||||||
|
+ ds->assisted_learning_on_cpu_port = true;
|
||||||
|
|
||||||
|
/* Some chips support up to 32, but that requires enabling the
|
||||||
|
* 5-bit port mode, which we do not support. 640k^W16 ought to
|
@ -0,0 +1,61 @@
|
|||||||
|
From patchwork Thu Aug 5 22:23:30 2021
|
||||||
|
Content-Type: text/plain; charset="utf-8"
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Transfer-Encoding: 7bit
|
||||||
|
X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
|
||||||
|
X-Patchwork-Id: 12422209
|
||||||
|
Date: Thu, 5 Aug 2021 23:23:30 +0100
|
||||||
|
From: Daniel Golle <daniel@makrotopia.org>
|
||||||
|
To: linux-arm-kernel@lists.infradead.org, netdev@vger.kernel.org,
|
||||||
|
linux-kernel@vger.kernel.org
|
||||||
|
Cc: "David S. Miller" <davem@davemloft.net>, Andrew Lunn <andrew@lunn.ch>,
|
||||||
|
Michael Walle <michael@walle.cc>
|
||||||
|
Subject: [PATCH] ARM: kirkwood: add missing <linux/if_ether.h> for ETH_ALEN
|
||||||
|
Message-ID: <YQxk4jrbm31NM1US@makrotopia.org>
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Disposition: inline
|
||||||
|
X-BeenThere: linux-arm-kernel@lists.infradead.org
|
||||||
|
X-Mailman-Version: 2.1.34
|
||||||
|
Precedence: list
|
||||||
|
List-Id: <linux-arm-kernel.lists.infradead.org>
|
||||||
|
List-Archive: <http://lists.infradead.org/pipermail/linux-arm-kernel/>
|
||||||
|
Sender: "linux-arm-kernel" <linux-arm-kernel-bounces@lists.infradead.org>
|
||||||
|
|
||||||
|
After commit 83216e3988cd1 ("of: net: pass the dst buffer to
|
||||||
|
of_get_mac_address()") build fails for kirkwood as ETH_ALEN is not
|
||||||
|
defined.
|
||||||
|
|
||||||
|
arch/arm/mach-mvebu/kirkwood.c: In function 'kirkwood_dt_eth_fixup':
|
||||||
|
arch/arm/mach-mvebu/kirkwood.c:87:13: error: 'ETH_ALEN' undeclared (first use in this function); did you mean 'ESTALE'?
|
||||||
|
u8 tmpmac[ETH_ALEN];
|
||||||
|
^~~~~~~~
|
||||||
|
ESTALE
|
||||||
|
arch/arm/mach-mvebu/kirkwood.c:87:13: note: each undeclared identifier is reported only once for each function it appears in
|
||||||
|
arch/arm/mach-mvebu/kirkwood.c:87:6: warning: unused variable 'tmpmac' [-Wunused-variable]
|
||||||
|
u8 tmpmac[ETH_ALEN];
|
||||||
|
^~~~~~
|
||||||
|
make[5]: *** [scripts/Makefile.build:262: arch/arm/mach-mvebu/kirkwood.o] Error 1
|
||||||
|
make[5]: *** Waiting for unfinished jobs....
|
||||||
|
|
||||||
|
Add missing #include <linux/if_ether.h> to fix this.
|
||||||
|
|
||||||
|
Cc: David S. Miller <davem@davemloft.net>
|
||||||
|
Cc: Andrew Lunn <andrew@lunn.ch>
|
||||||
|
Cc: Michael Walle <michael@walle.cc>
|
||||||
|
Reported-by: https://buildbot.openwrt.org/master/images/#/builders/56/builds/220/steps/44/logs/stdio
|
||||||
|
Fixes: 83216e3988cd1 ("of: net: pass the dst buffer to of_get_mac_address()")
|
||||||
|
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||||
|
---
|
||||||
|
arch/arm/mach-mvebu/kirkwood.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
--- a/arch/arm/mach-mvebu/kirkwood.c
|
||||||
|
+++ b/arch/arm/mach-mvebu/kirkwood.c
|
||||||
|
@@ -11,6 +11,7 @@
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/mbus.h>
|
||||||
|
+#include <linux/if_ether.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/of_address.h>
|
||||||
|
#include <linux/of_net.h>
|
48
pending-6.12/790-bus-mhi-core-add-SBL-state-callback.patch
Normal file
48
pending-6.12/790-bus-mhi-core-add-SBL-state-callback.patch
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
From 5f7c5e1c0d7a79be144e5efc1f24728ddd7fc25c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Robert Marko <robimarko@gmail.com>
|
||||||
|
Date: Sat, 5 Nov 2022 20:02:56 +0100
|
||||||
|
Subject: [PATCH 1/2] bus: mhi: core: add SBL state callback
|
||||||
|
|
||||||
|
Add support for SBL state callback in MHI core.
|
||||||
|
|
||||||
|
It is required for ath11k MHI devices in order to be able to set QRTR
|
||||||
|
instance ID in the SBL state so that QRTR instance ID-s dont conflict in
|
||||||
|
case of multiple PCI/MHI cards or AHB + PCI/MHI card.
|
||||||
|
Setting QRTR instance ID is only possible in SBL state and there is
|
||||||
|
currently no way to ensure that we are in that state, so provide a
|
||||||
|
callback that the controller can trigger off.
|
||||||
|
|
||||||
|
Signed-off-by: Robert Marko <robimarko@gmail.com>
|
||||||
|
---
|
||||||
|
drivers/bus/mhi/host/main.c | 1 +
|
||||||
|
include/linux/mhi.h | 2 ++
|
||||||
|
2 files changed, 3 insertions(+)
|
||||||
|
|
||||||
|
--- a/drivers/bus/mhi/host/main.c
|
||||||
|
+++ b/drivers/bus/mhi/host/main.c
|
||||||
|
@@ -906,6 +906,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_
|
||||||
|
switch (event) {
|
||||||
|
case MHI_EE_SBL:
|
||||||
|
st = DEV_ST_TRANSITION_SBL;
|
||||||
|
+ mhi_cntrl->status_cb(mhi_cntrl, MHI_CB_EE_SBL_MODE);
|
||||||
|
break;
|
||||||
|
case MHI_EE_WFW:
|
||||||
|
case MHI_EE_AMSS:
|
||||||
|
--- a/include/linux/mhi.h
|
||||||
|
+++ b/include/linux/mhi.h
|
||||||
|
@@ -34,6 +34,7 @@ struct mhi_buf_info;
|
||||||
|
* @MHI_CB_SYS_ERROR: MHI device entered error state (may recover)
|
||||||
|
* @MHI_CB_FATAL_ERROR: MHI device entered fatal error state
|
||||||
|
* @MHI_CB_BW_REQ: Received a bandwidth switch request from device
|
||||||
|
+ * @MHI_CB_EE_SBL_MODE: MHI device entered SBL mode
|
||||||
|
*/
|
||||||
|
enum mhi_callback {
|
||||||
|
MHI_CB_IDLE,
|
||||||
|
@@ -45,6 +46,7 @@ enum mhi_callback {
|
||||||
|
MHI_CB_SYS_ERROR,
|
||||||
|
MHI_CB_FATAL_ERROR,
|
||||||
|
MHI_CB_BW_REQ,
|
||||||
|
+ MHI_CB_EE_SBL_MODE,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
@ -0,0 +1,73 @@
|
|||||||
|
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||||
|
Subject: [PATCH] bcma: get SoC device struct & copy its DMA params to the
|
||||||
|
subdevices
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
For bus devices to be fully usable it's required to set their DMA
|
||||||
|
parameters.
|
||||||
|
|
||||||
|
For years it has been missing and remained unnoticed because of
|
||||||
|
mips_dma_alloc_coherent() silently handling the empty coherent_dma_mask.
|
||||||
|
Kernel 4.19 came with a lot of DMA changes and caused a regression on
|
||||||
|
the bcm47xx. Starting with the commit f8c55dc6e828 ("MIPS: use generic
|
||||||
|
dma noncoherent ops for simple noncoherent platforms") DMA coherent
|
||||||
|
allocations just fail. Example:
|
||||||
|
[ 1.114914] bgmac_bcma bcma0:2: Allocation of TX ring 0x200 failed
|
||||||
|
[ 1.121215] bgmac_bcma bcma0:2: Unable to alloc memory for DMA
|
||||||
|
[ 1.127626] bgmac_bcma: probe of bcma0:2 failed with error -12
|
||||||
|
[ 1.133838] bgmac_bcma: Broadcom 47xx GBit MAC driver loaded
|
||||||
|
|
||||||
|
This change fixes above regression in addition to the MIPS bcm47xx
|
||||||
|
commit 321c46b91550 ("MIPS: BCM47XX: Setup struct device for the SoC").
|
||||||
|
|
||||||
|
It also fixes another *old* GPIO regression caused by a parent pointing
|
||||||
|
to the NULL:
|
||||||
|
[ 0.157054] missing gpiochip .dev parent pointer
|
||||||
|
[ 0.157287] bcma: bus0: Error registering GPIO driver: -22
|
||||||
|
introduced by the commit 74f4e0cc6108 ("bcma: switch GPIO portions to
|
||||||
|
use GPIOLIB_IRQCHIP").
|
||||||
|
|
||||||
|
Fixes: f8c55dc6e828 ("MIPS: use generic dma noncoherent ops for simple noncoherent platforms")
|
||||||
|
Fixes: 74f4e0cc6108 ("bcma: switch GPIO portions to use GPIOLIB_IRQCHIP")
|
||||||
|
Cc: linux-mips@linux-mips.org
|
||||||
|
Cc: Christoph Hellwig <hch@lst.de>
|
||||||
|
Cc: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/drivers/bcma/host_soc.c
|
||||||
|
+++ b/drivers/bcma/host_soc.c
|
||||||
|
@@ -191,6 +191,8 @@ int __init bcma_host_soc_init(struct bcm
|
||||||
|
struct bcma_bus *bus = &soc->bus;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
+ bus->dev = soc->dev;
|
||||||
|
+
|
||||||
|
/* Scan bus and initialize it */
|
||||||
|
err = bcma_bus_early_register(bus);
|
||||||
|
if (err)
|
||||||
|
--- a/drivers/bcma/main.c
|
||||||
|
+++ b/drivers/bcma/main.c
|
||||||
|
@@ -237,13 +237,17 @@ EXPORT_SYMBOL(bcma_core_irq);
|
||||||
|
|
||||||
|
void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core)
|
||||||
|
{
|
||||||
|
- device_initialize(&core->dev);
|
||||||
|
+ struct device *dev = &core->dev;
|
||||||
|
+
|
||||||
|
+ device_initialize(dev);
|
||||||
|
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);
|
||||||
|
+ dev_set_name(dev, "bcma%d:%d", bus->num, core->core_index);
|
||||||
|
core->dev.parent = bus->dev;
|
||||||
|
- if (bus->dev)
|
||||||
|
+ if (bus->dev) {
|
||||||
|
bcma_of_fill_device(bus->dev, core);
|
||||||
|
+ dma_coerce_mask_and_coherent(dev, bus->dev->coherent_dma_mask);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
switch (bus->hosttype) {
|
||||||
|
case BCMA_HOSTTYPE_PCI:
|
@ -0,0 +1,222 @@
|
|||||||
|
From fc23ea48ba52c24f201fe5ca0132ee1a3de5a70a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mauri Sandberg <maukka@ext.kapsi.fi>
|
||||||
|
Date: Thu, 25 Mar 2021 11:48:05 +0200
|
||||||
|
Subject: [PATCH 2/2] gpio: gpio-cascade: add generic GPIO cascade
|
||||||
|
|
||||||
|
Adds support for building cascades of GPIO lines. That is, it allows
|
||||||
|
setups when there is one upstream line and multiple cascaded lines, out
|
||||||
|
of which one can be chosen at a time. The status of the upstream line
|
||||||
|
can be conveyed to the selected cascaded line or, vice versa, the status
|
||||||
|
of the cascaded line can be conveyed to the upstream line.
|
||||||
|
|
||||||
|
A multiplexer is being used to select, which cascaded GPIO line is being
|
||||||
|
used at any given time.
|
||||||
|
|
||||||
|
At the moment only input direction is supported. In future it should be
|
||||||
|
possible to add support for output direction, too.
|
||||||
|
|
||||||
|
Signed-off-by: Mauri Sandberg <maukka@ext.kapsi.fi>
|
||||||
|
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
|
||||||
|
---
|
||||||
|
v7 -> v8:
|
||||||
|
- rearrange members in struct gpio_cascade
|
||||||
|
- cosmetic changes in file header and in one function declaration
|
||||||
|
- added Reviewed-by tags by Linus and Andy
|
||||||
|
v6 -> v7:
|
||||||
|
- In Kconfig add info about module name
|
||||||
|
- adhere to new convention that allows lines longer than 80 chars
|
||||||
|
- use dev_probe_err with upstream gpio line too
|
||||||
|
- refactor for cleaner exit of probe function.
|
||||||
|
v5 -> v6:
|
||||||
|
- In Kconfig, remove dependency to OF_GPIO and select only MULTIPLEXER
|
||||||
|
- refactor code preferring one-liners
|
||||||
|
- clean up prints, removing them from success-path.
|
||||||
|
- don't explicitly set gpio_chip.of_node as it's done in the GPIO library
|
||||||
|
- use devm_gpiochip_add_data instead of gpiochip_add
|
||||||
|
v4 -> v5:
|
||||||
|
- renamed gpio-mux-input -> gpio-cascade. refactored code accordingly
|
||||||
|
here and there and changed to use new bindings and compatible string
|
||||||
|
- ambigious and vague 'pin' was rename to 'upstream_line'
|
||||||
|
- dropped Tested-by and Reviewed-by due to changes in bindings
|
||||||
|
- dropped Reported-by suggested by an automatic bot as it was not really
|
||||||
|
appropriate to begin with
|
||||||
|
- functionally it's the same as v4
|
||||||
|
v3 -> v4:
|
||||||
|
- Changed author email
|
||||||
|
- Included Tested-by and Reviewed-by from Drew
|
||||||
|
v2 -> v3:
|
||||||
|
- use managed device resources
|
||||||
|
- update Kconfig description
|
||||||
|
v1 -> v2:
|
||||||
|
- removed .owner from platform_driver as per test bot's instruction
|
||||||
|
- added MODULE_AUTHOR, MODULE_DESCRIPTION, MODULE_LICENSE
|
||||||
|
- added gpio_mux_input_get_direction as it's recommended for all chips
|
||||||
|
- removed because this is input only chip: gpio_mux_input_set_value
|
||||||
|
- removed because they are not needed for input/output only chips:
|
||||||
|
gpio_mux_input_direction_input
|
||||||
|
gpio_mux_input_direction_output
|
||||||
|
- fixed typo in an error message
|
||||||
|
- added info message about successful registration
|
||||||
|
- removed can_sleep flag as this does not sleep while getting GPIO value
|
||||||
|
like I2C or SPI do
|
||||||
|
- Updated description in Kconfig
|
||||||
|
---
|
||||||
|
drivers/gpio/Kconfig | 15 +++++
|
||||||
|
drivers/gpio/Makefile | 1 +
|
||||||
|
drivers/gpio/gpio-cascade.c | 117 ++++++++++++++++++++++++++++++++++++
|
||||||
|
3 files changed, 133 insertions(+)
|
||||||
|
create mode 100644 drivers/gpio/gpio-cascade.c
|
||||||
|
|
||||||
|
--- a/drivers/gpio/Kconfig
|
||||||
|
+++ b/drivers/gpio/Kconfig
|
||||||
|
@@ -1929,4 +1929,19 @@ config GPIO_VIRTUSER
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
+comment "Other GPIO expanders"
|
||||||
|
+
|
||||||
|
+config GPIO_CASCADE
|
||||||
|
+ tristate "General GPIO cascade"
|
||||||
|
+ select MULTIPLEXER
|
||||||
|
+ help
|
||||||
|
+ Say yes here to enable support for generic GPIO cascade.
|
||||||
|
+
|
||||||
|
+ This allows building one-to-many cascades of GPIO lines using
|
||||||
|
+ different types of multiplexers readily available. At the
|
||||||
|
+ moment only input lines are supported.
|
||||||
|
+
|
||||||
|
+ To build the driver as a module choose 'm' and the resulting module
|
||||||
|
+ will be called 'gpio-cascade'.
|
||||||
|
+
|
||||||
|
endif
|
||||||
|
--- a/drivers/gpio/Makefile
|
||||||
|
+++ b/drivers/gpio/Makefile
|
||||||
|
@@ -45,6 +45,7 @@ obj-$(CONFIG_GPIO_BD9571MWV) += gpio-bd
|
||||||
|
obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o
|
||||||
|
obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o
|
||||||
|
obj-$(CONFIG_GPIO_CADENCE) += gpio-cadence.o
|
||||||
|
+obj-$(CONFIG_GPIO_CASCADE) += gpio-cascade.o
|
||||||
|
obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o
|
||||||
|
obj-$(CONFIG_GPIO_SNPS_CREG) += gpio-creg-snps.o
|
||||||
|
obj-$(CONFIG_GPIO_CROS_EC) += gpio-cros-ec.o
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/drivers/gpio/gpio-cascade.c
|
||||||
|
@@ -0,0 +1,117 @@
|
||||||
|
+// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
+/*
|
||||||
|
+ * A generic GPIO cascade driver
|
||||||
|
+ *
|
||||||
|
+ * Copyright (C) 2021 Mauri Sandberg <maukka@ext.kapsi.fi>
|
||||||
|
+ *
|
||||||
|
+ * This allows building cascades of GPIO lines in a manner illustrated
|
||||||
|
+ * below:
|
||||||
|
+ *
|
||||||
|
+ * /|---- Cascaded GPIO line 0
|
||||||
|
+ * Upstream | |---- Cascaded GPIO line 1
|
||||||
|
+ * GPIO line ----+ | .
|
||||||
|
+ * | | .
|
||||||
|
+ * \|---- Cascaded GPIO line n
|
||||||
|
+ *
|
||||||
|
+ * A multiplexer is being used to select, which cascaded line is being
|
||||||
|
+ * addressed at any given time.
|
||||||
|
+ *
|
||||||
|
+ * At the moment only input mode is supported due to lack of means for
|
||||||
|
+ * testing output functionality. At least theoretically output should be
|
||||||
|
+ * possible with open drain constructions.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <linux/module.h>
|
||||||
|
+#include <linux/slab.h>
|
||||||
|
+#include <linux/platform_device.h>
|
||||||
|
+#include <linux/mux/consumer.h>
|
||||||
|
+
|
||||||
|
+#include <linux/gpio/consumer.h>
|
||||||
|
+#include <linux/gpio/driver.h>
|
||||||
|
+
|
||||||
|
+struct gpio_cascade {
|
||||||
|
+ struct gpio_chip gpio_chip;
|
||||||
|
+ struct device *parent;
|
||||||
|
+ struct mux_control *mux_control;
|
||||||
|
+ struct gpio_desc *upstream_line;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct gpio_cascade *chip_to_cascade(struct gpio_chip *gc)
|
||||||
|
+{
|
||||||
|
+ return container_of(gc, struct gpio_cascade, gpio_chip);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int gpio_cascade_get_direction(struct gpio_chip *gc, unsigned int offset)
|
||||||
|
+{
|
||||||
|
+ return GPIO_LINE_DIRECTION_IN;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int gpio_cascade_get_value(struct gpio_chip *gc, unsigned int offset)
|
||||||
|
+{
|
||||||
|
+ struct gpio_cascade *cas = chip_to_cascade(gc);
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ ret = mux_control_select(cas->mux_control, offset);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ ret = gpiod_get_value(cas->upstream_line);
|
||||||
|
+ mux_control_deselect(cas->mux_control);
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int gpio_cascade_probe(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ struct device *dev = &pdev->dev;
|
||||||
|
+ struct gpio_cascade *cas;
|
||||||
|
+ struct mux_control *mc;
|
||||||
|
+ struct gpio_desc *upstream;
|
||||||
|
+ struct gpio_chip *gc;
|
||||||
|
+
|
||||||
|
+ cas = devm_kzalloc(dev, sizeof(*cas), GFP_KERNEL);
|
||||||
|
+ if (!cas)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ mc = devm_mux_control_get(dev, NULL);
|
||||||
|
+ if (IS_ERR(mc))
|
||||||
|
+ return dev_err_probe(dev, PTR_ERR(mc), "unable to get mux-control\n");
|
||||||
|
+
|
||||||
|
+ cas->mux_control = mc;
|
||||||
|
+ upstream = devm_gpiod_get(dev, "upstream", GPIOD_IN);
|
||||||
|
+ if (IS_ERR(upstream))
|
||||||
|
+ return dev_err_probe(dev, PTR_ERR(upstream), "unable to claim upstream GPIO line\n");
|
||||||
|
+
|
||||||
|
+ cas->upstream_line = upstream;
|
||||||
|
+ cas->parent = dev;
|
||||||
|
+
|
||||||
|
+ gc = &cas->gpio_chip;
|
||||||
|
+ gc->get = gpio_cascade_get_value;
|
||||||
|
+ gc->get_direction = gpio_cascade_get_direction;
|
||||||
|
+ gc->base = -1;
|
||||||
|
+ gc->ngpio = mux_control_states(mc);
|
||||||
|
+ gc->label = dev_name(cas->parent);
|
||||||
|
+ gc->parent = cas->parent;
|
||||||
|
+ gc->owner = THIS_MODULE;
|
||||||
|
+
|
||||||
|
+ platform_set_drvdata(pdev, cas);
|
||||||
|
+ return devm_gpiochip_add_data(dev, &cas->gpio_chip, NULL);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static const struct of_device_id gpio_cascade_id[] = {
|
||||||
|
+ { .compatible = "gpio-cascade" },
|
||||||
|
+ { /* sentinel */ }
|
||||||
|
+};
|
||||||
|
+MODULE_DEVICE_TABLE(of, gpio_cascade_id);
|
||||||
|
+
|
||||||
|
+static struct platform_driver gpio_cascade_driver = {
|
||||||
|
+ .driver = {
|
||||||
|
+ .name = "gpio-cascade",
|
||||||
|
+ .of_match_table = gpio_cascade_id,
|
||||||
|
+ },
|
||||||
|
+ .probe = gpio_cascade_probe,
|
||||||
|
+};
|
||||||
|
+module_platform_driver(gpio_cascade_driver);
|
||||||
|
+
|
||||||
|
+MODULE_AUTHOR("Mauri Sandberg <maukka@ext.kapsi.fi>");
|
||||||
|
+MODULE_DESCRIPTION("Generic GPIO cascade");
|
||||||
|
+MODULE_LICENSE("GPL");
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user