From bcdf861519b8fddad1abc5d87c434252815a3a6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Sun, 11 Jun 2023 18:44:36 +0200 Subject: [PATCH 1/6] bmips: add support for Comtrend AR-5381u MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Comtrend AR-5381u is a wifi fast ethernet router, 2.4 GHz single band with two internal antennas. Hardware: - SoC: Broadcom BCM6328 - CPU: single core BMIPS4350 @ 320Mhz - RAM: 64 MB DDR - Flash: 16 MB SPI NOR - Ethernet LAN: 4x 100Mbit - Wifi 2.4 GHz: miniPCI Broadcom BCM43225 802.11bgn - USB: 1x 2.0 - Buttons: 1x (reset) - LEDs: yes - UART: yes Installation via CFE web UI: 1. Power off the router. 2. Press reset button near the power switch. 3. Keep it pressed while powering up during ~20+ seconds. 4. Browse to http://192.168.1.1 and upload the firmware. 5. Wait a few minutes for it to finish. Signed-off-by: Álvaro Fernández Rojas --- .../bcm6328/base-files/etc/board.d/02_network | 1 + .../base-files/etc/uci-defaults/09_fix_crc | 1 + .../bmips/dts/bcm6328-comtrend-ar-5381u.dts | 190 ++++++++++++++++++ target/linux/bmips/image/bcm6328.mk | 13 ++ 4 files changed, 205 insertions(+) create mode 100644 target/linux/bmips/dts/bcm6328-comtrend-ar-5381u.dts diff --git a/target/linux/bmips/bcm6328/base-files/etc/board.d/02_network b/target/linux/bmips/bcm6328/base-files/etc/board.d/02_network index 792926fcf2..c9c704067e 100644 --- a/target/linux/bmips/bcm6328/base-files/etc/board.d/02_network +++ b/target/linux/bmips/bcm6328/base-files/etc/board.d/02_network @@ -5,6 +5,7 @@ board_config_update case "$(board_name)" in +comtrend,ar-5381u |\ comtrend,ar-5387un) ucidef_set_bridge_device switch ucidef_set_interface_lan "lan1 lan2 lan3 lan4" diff --git a/target/linux/bmips/bcm6328/base-files/etc/uci-defaults/09_fix_crc b/target/linux/bmips/bcm6328/base-files/etc/uci-defaults/09_fix_crc index 3909947be6..21f18b4b81 100644 --- a/target/linux/bmips/bcm6328/base-files/etc/uci-defaults/09_fix_crc +++ b/target/linux/bmips/bcm6328/base-files/etc/uci-defaults/09_fix_crc @@ -3,6 +3,7 @@ . /lib/functions.sh case "$(board_name)" in +comtrend,ar-5381u |\ comtrend,ar-5387un) mtd fixtrx firmware ;; diff --git a/target/linux/bmips/dts/bcm6328-comtrend-ar-5381u.dts b/target/linux/bmips/dts/bcm6328-comtrend-ar-5381u.dts new file mode 100644 index 0000000000..7499e7090f --- /dev/null +++ b/target/linux/bmips/dts/bcm6328-comtrend-ar-5381u.dts @@ -0,0 +1,190 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "bcm6328.dtsi" + +/ { + model = "Comtrend AR-5381u"; + compatible = "comtrend,ar-5381u", "brcm,bcm6328"; + + aliases { + led-boot = &led_power_green; + led-failsafe = &led_alarm_red; + led-running = &led_power_green; + led-upgrade = &led_power_green; + }; + + keys { + compatible = "gpio-keys-polled"; + poll-interval = <100>; + + reset { + label = "reset"; + gpios = <&gpio 23 GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <60>; + }; + }; + + bcm43225-sprom { + compatible = "brcm,bcma-sprom"; + + pci-bus = <1>; + pci-dev = <0>; + + nvmem-cells = <&macaddr_cfe_6a0>; + nvmem-cell-names = "mac-address"; + mac-address-increment = <1>; + + brcm,sprom = "brcm/bcm43225-sprom.bin"; + brcm,sprom-fixups = <97 0xfee5>, + <98 0x157c>, + <99 0xfae7>, + <113 0xfefa>, + <114 0x15d6>, + <115 0xfaf8>; + }; +}; + +&ehci { + status = "okay"; +}; + +ðernet { + status = "okay"; + + nvmem-cells = <&macaddr_cfe_6a0>; + nvmem-cell-names = "mac-address"; +}; + +&hsspi { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + spi-max-frequency = <16666667>; + spi-tx-bus-width = <2>; + spi-rx-bus-width = <2>; + reg = <0>; + + #address-cells = <1>; + #size-cells = <1>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + cfe: partition@0 { + reg = <0x000000 0x010000>; + label = "cfe"; + read-only; + }; + + partition@10000 { + compatible = "brcm,bcm963xx-imagetag"; + reg = <0x010000 0xfe0000>; + label = "firmware"; + }; + + partition@ff0000 { + reg = <0xff0000 0x010000>; + label = "nvram"; + }; + }; + }; +}; + +&leds { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_leds>; + + led_alarm_red: led@2 { + reg = <2>; + active-low; + label = "red:alarm"; + panic-indicator; + }; + + led@3 { + reg = <3>; + active-low; + label = "green:internet"; + }; + + led_power_green: led@4 { + reg = <4>; + active-low; + label = "green:power"; + }; +}; + +&ohci { + status = "okay"; +}; + +&pcie { + status = "okay"; +}; + +&pinctrl { + pinctrl_leds: leds { + function = "led"; + pins = "gpio2", "gpio3", "gpio4"; + }; +}; + +&switch0 { + ports { + port@0 { + reg = <0>; + label = "lan1"; + + phy-handle = <&phy1>; + phy-mode = "mii"; + }; + + port@1 { + reg = <1>; + label = "lan2"; + + phy-handle = <&phy2>; + phy-mode = "mii"; + }; + + port@2 { + reg = <2>; + label = "lan3"; + + phy-handle = <&phy3>; + phy-mode = "mii"; + }; + + port@3 { + reg = <3>; + label = "lan4"; + + phy-handle = <&phy4>; + phy-mode = "mii"; + }; + }; +}; + +&uart0 { + status = "okay"; +}; + +&usbh { + status = "okay"; +}; + +&cfe { + compatible = "nvmem-cells"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_cfe_6a0: macaddr@6a0 { + reg = <0x6a0 0x6>; + }; +}; diff --git a/target/linux/bmips/image/bcm6328.mk b/target/linux/bmips/image/bcm6328.mk index b3cef51a71..dfa134df94 100644 --- a/target/linux/bmips/image/bcm6328.mk +++ b/target/linux/bmips/image/bcm6328.mk @@ -1,5 +1,18 @@ # SPDX-License-Identifier: GPL-2.0-or-later +define Device/comtrend_ar-5381u + $(Device/bcm63xx-cfe) + DEVICE_VENDOR := Comtrend + DEVICE_MODEL := AR-5381u + CHIP_ID := 6328 + CFE_BOARD_ID := 96328A-1241N + FLASH_MB := 16 + DEVICE_PACKAGES += $(USB2_PACKAGES) \ + $(B43_PACKAGES) broadcom-43225-sprom \ + kmod-leds-bcm6328 +endef +TARGET_DEVICES += comtrend_ar-5381u + define Device/comtrend_ar-5387un $(Device/bcm63xx-cfe) DEVICE_VENDOR := Comtrend From 5714660643e9170920be2abbb2297d9aac0b9533 Mon Sep 17 00:00:00 2001 From: John Audia Date: Tue, 6 Jun 2023 10:45:47 -0400 Subject: [PATCH 2/6] kernel: bump 5.15 to 5.15.115 Manually rebased: backport-5.15/603-v5.19-page_pool-Add-recycle-stats-to-page_pool_put_page_bu.patch pending-5.15/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch* Removed upstreamed: generic-backport/610-v6.3-net-page_pool-use-in_softirq-instead.patch[1] backport-5.15/705-12-v6.0-net-dsa-mt7530-rework-mt753-01-_setup.patch[2] backport-5.15/790-v6.4-0010-net-dsa-mt7530-split-off-common-parts-from-mt7531_se.patch[3] backport-5.15/703-10-v5.16-net-dsa-introduce-helpers-for-iterating-through-port.patch[4] All other patches automatically rebased. * Modified to define the variable i as suggested by DragonBluep in PR discussion. See: https://github.com/openwrt/openwrt/pull/12823#issuecomment-1578518576 1. https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v5.15.115&id=3af319d5147454dc63665ef451229c674b538377 2. https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v5.15.115&id=0753c1ef24194580f7165ae6e259b59a851392f2 3. https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v5.15.115&id=5a7266feaa6d708fc6880a161786eaa884ef3c8e 4. https://github.com/gregkh/linux/commit/9902f91cf666124a6b50bbcf483b46ecb09ef408 Build system: x86_64 Build-tested: bcm2711/RPi4B, ramips/tplink_archer-a6-v3, filogic/xiaomi_redmi-router-ax6000-ubootmod Run-tested: bcm2711/RPi4B, ramips/tplink_archer-a6-v3, filogic/xiaomi_redmi-router-ax6000-ubootmod Signed-off-by: John Audia --- include/kernel-5.15 | 4 +- ...v5.18-page_pool-Add-allocation-stats.patch | 16 +- ...01-v5.18-page_pool-Add-recycle-stats.patch | 14 +- ...d-function-to-batch-and-return-stats.patch | 2 +- ...cycle-stats-to-page_pool_put_page_bu.patch | 10 +- ...et-page_pool-introduce-ethtool-stats.patch | 6 +- ...gs-support-to-xdp_return_-buff-frame.patch | 6 +- ...net-page_pool-use-in_softirq-instead.patch | 56 ------- ...uce-tagger-owned-storage-for-private.patch | 2 +- ...populate-supported_interfaces-member.patch | 2 +- ...phylink_get_interfaces-with-phylink_.patch | 2 +- ...d-support-for-phylink-mac_select_pcs.patch | 2 +- ...e-helpers-for-iterating-through-port.patch | 68 --------- ...opulate-supported_interfaces-and-mac.patch | 16 +- ...t-dsa-mt7530-remove-interface-checks.patch | 16 +- ...rop-use-of-phylink_helper_basex_spee.patch | 2 +- ...nly-indicate-linkmodes-that-can-be-s.patch | 6 +- ...-switch-to-use-phylink_get_linkmodes.patch | 12 +- ...530-partially-convert-to-phylink_pcs.patch | 30 ++-- ...ove-autoneg-handling-to-PCS-validati.patch | 6 +- ...19-net-dsa-mt7530-mark-as-non-legacy.patch | 2 +- ...mt753x-fix-pcs-conversion-regression.patch | 4 +- ...et-dsa-mt7530-rework-mt753-01-_setup.patch | 75 --------- ...switch-operations-for-tracking-the-m.patch | 2 +- ...-add-support-for-in-band-link-status.patch | 12 +- ...t-dsa-mt7530-use-external-PCS-driver.patch | 20 +-- ...a-mt7530-refactor-SGMII-PCS-creation.patch | 4 +- ...mt7530-use-unlocked-regmap-accessors.patch | 6 +- ...se-regmap-to-access-switch-register-.patch | 10 +- ...ove-SGMII-PCS-creation-to-mt7530_pro.patch | 6 +- ...ntroduce-mt7530_probe_common-helper-.patch | 6 +- ...ntroduce-mt7530_remove_common-helper.patch | 4 +- ...plit-off-common-parts-from-mt7531_se.patch | 143 ------------------ ...t7530-introduce-separate-MDIO-driver.patch | 12 +- ...ntroduce-driver-for-MT7988-built-in-.patch | 14 +- ...-dsa-mt7530-fix-support-for-MT7531BE.patch | 2 +- ...e-all-MACs-are-powered-down-before-r.patch | 15 +- 37 files changed, 141 insertions(+), 474 deletions(-) delete mode 100644 target/linux/generic/backport-5.15/610-v6.3-net-page_pool-use-in_softirq-instead.patch delete mode 100644 target/linux/generic/backport-5.15/703-10-v5.16-net-dsa-introduce-helpers-for-iterating-through-port.patch delete mode 100644 target/linux/generic/backport-5.15/705-12-v6.0-net-dsa-mt7530-rework-mt753-01-_setup.patch delete mode 100644 target/linux/generic/backport-5.15/790-v6.4-0010-net-dsa-mt7530-split-off-common-parts-from-mt7531_se.patch diff --git a/include/kernel-5.15 b/include/kernel-5.15 index 4c18bc35c2..b8b89583b4 100644 --- a/include/kernel-5.15 +++ b/include/kernel-5.15 @@ -1,2 +1,2 @@ -LINUX_VERSION-5.15 = .114 -LINUX_KERNEL_HASH-5.15.114 = e981ea5d219f77735bf5a3f7e84a8af578df8ac3e1c4ff1b0649e2b0795277d2 +LINUX_VERSION-5.15 = .115 +LINUX_KERNEL_HASH-5.15.115 = 1b076860779235e90519e867c1ec78c7a34d1125d8fdba787ff495c7c14f1214 diff --git a/target/linux/generic/backport-5.15/600-v5.18-page_pool-Add-allocation-stats.patch b/target/linux/generic/backport-5.15/600-v5.18-page_pool-Add-allocation-stats.patch index 9e383de92c..f4c5b9afee 100644 --- a/target/linux/generic/backport-5.15/600-v5.18-page_pool-Add-allocation-stats.patch +++ b/target/linux/generic/backport-5.15/600-v5.18-page_pool-Add-allocation-stats.patch @@ -87,9 +87,9 @@ Signed-off-by: David S. Miller help --- a/net/core/page_pool.c +++ b/net/core/page_pool.c -@@ -26,6 +26,13 @@ - - #define BIAS_MAX LONG_MAX +@@ -49,6 +49,13 @@ static void page_pool_producer_unlock(st + spin_unlock_bh(&pool->ring.producer_lock); + } +#ifdef CONFIG_PAGE_POOL_STATS +/* alloc_stat_inc is intended to be used in softirq context */ @@ -101,7 +101,7 @@ Signed-off-by: David S. Miller static int page_pool_init(struct page_pool *pool, const struct page_pool_params *params) { -@@ -117,8 +124,10 @@ static struct page *page_pool_refill_all +@@ -140,8 +147,10 @@ static struct page *page_pool_refill_all int pref_nid; /* preferred NUMA node */ /* Quicker fallback, avoid locks when ring is empty */ @@ -113,7 +113,7 @@ Signed-off-by: David S. Miller /* Softirq guarantee CPU and thus NUMA node is stable. This, * assumes CPU refilling driver RX-ring will also run RX-NAPI. -@@ -148,14 +157,17 @@ static struct page *page_pool_refill_all +@@ -171,14 +180,17 @@ static struct page *page_pool_refill_all * This limit stress on page buddy alloactor. */ page_pool_return_page(pool, page); @@ -132,7 +132,7 @@ Signed-off-by: David S. Miller spin_unlock(&r->consumer_lock); return page; -@@ -170,6 +182,7 @@ static struct page *__page_pool_get_cach +@@ -193,6 +205,7 @@ static struct page *__page_pool_get_cach if (likely(pool->alloc.count)) { /* Fast-path */ page = pool->alloc.cache[--pool->alloc.count]; @@ -140,7 +140,7 @@ Signed-off-by: David S. Miller } else { page = page_pool_refill_alloc_cache(pool); } -@@ -241,6 +254,7 @@ static struct page *__page_pool_alloc_pa +@@ -264,6 +277,7 @@ static struct page *__page_pool_alloc_pa return NULL; } @@ -148,7 +148,7 @@ Signed-off-by: David S. Miller page_pool_set_pp_info(pool, page); /* Track how many pages are held 'in-flight' */ -@@ -295,10 +309,12 @@ static struct page *__page_pool_alloc_pa +@@ -318,10 +332,12 @@ static struct page *__page_pool_alloc_pa } /* Return last page */ diff --git a/target/linux/generic/backport-5.15/601-v5.18-page_pool-Add-recycle-stats.patch b/target/linux/generic/backport-5.15/601-v5.18-page_pool-Add-recycle-stats.patch index fb11f0035f..b425b78c75 100644 --- a/target/linux/generic/backport-5.15/601-v5.18-page_pool-Add-recycle-stats.patch +++ b/target/linux/generic/backport-5.15/601-v5.18-page_pool-Add-recycle-stats.patch @@ -53,7 +53,7 @@ Signed-off-by: David S. Miller /* A page_pool is strictly tied to a single RX-queue being --- a/net/core/page_pool.c +++ b/net/core/page_pool.c -@@ -29,8 +29,15 @@ +@@ -52,8 +52,15 @@ static void page_pool_producer_unlock(st #ifdef CONFIG_PAGE_POOL_STATS /* alloc_stat_inc is intended to be used in softirq context */ #define alloc_stat_inc(pool, __stat) (pool->alloc_stats.__stat++) @@ -69,7 +69,7 @@ Signed-off-by: David S. Miller #endif static int page_pool_init(struct page_pool *pool, -@@ -80,6 +87,12 @@ static int page_pool_init(struct page_po +@@ -103,6 +110,12 @@ static int page_pool_init(struct page_po pool->p.flags & PP_FLAG_PAGE_FRAG) return -EINVAL; @@ -82,7 +82,7 @@ Signed-off-by: David S. Miller if (ptr_ring_init(&pool->ring, ring_qsize, GFP_KERNEL) < 0) return -ENOMEM; -@@ -412,7 +425,12 @@ static bool page_pool_recycle_in_ring(st +@@ -435,7 +448,12 @@ static bool page_pool_recycle_in_ring(st else ret = ptr_ring_produce_bh(&pool->ring, page); @@ -96,7 +96,7 @@ Signed-off-by: David S. Miller } /* Only allow direct recycling in special circumstances, into the -@@ -423,11 +441,14 @@ static bool page_pool_recycle_in_ring(st +@@ -446,11 +464,14 @@ static bool page_pool_recycle_in_ring(st static bool page_pool_recycle_in_cache(struct page *page, struct page_pool *pool) { @@ -112,7 +112,7 @@ Signed-off-by: David S. Miller return true; } -@@ -482,6 +503,7 @@ __page_pool_put_page(struct page_pool *p +@@ -505,6 +526,7 @@ __page_pool_put_page(struct page_pool *p * doing refcnt based recycle tricks, meaning another process * will be invoking put_page. */ @@ -120,7 +120,7 @@ Signed-off-by: David S. Miller /* Do not replace this with page_pool_return_page() */ page_pool_release_page(pool, page); put_page(page); -@@ -495,6 +517,7 @@ void page_pool_put_page(struct page_pool +@@ -518,6 +540,7 @@ void page_pool_put_page(struct page_pool page = __page_pool_put_page(pool, page, dma_sync_size, allow_direct); if (page && !page_pool_recycle_in_ring(pool, page)) { /* Cache full, fallback to free pages */ @@ -128,7 +128,7 @@ Signed-off-by: David S. Miller page_pool_return_page(pool, page); } } -@@ -641,6 +664,9 @@ static void page_pool_free(struct page_p +@@ -665,6 +688,9 @@ static void page_pool_free(struct page_p if (pool->p.flags & PP_FLAG_DMA_MAP) put_device(pool->p.dev); diff --git a/target/linux/generic/backport-5.15/602-v5.18-page_pool-Add-function-to-batch-and-return-stats.patch b/target/linux/generic/backport-5.15/602-v5.18-page_pool-Add-function-to-batch-and-return-stats.patch index 41188fb7f2..e1a7635133 100644 --- a/target/linux/generic/backport-5.15/602-v5.18-page_pool-Add-function-to-batch-and-return-stats.patch +++ b/target/linux/generic/backport-5.15/602-v5.18-page_pool-Add-function-to-batch-and-return-stats.patch @@ -43,7 +43,7 @@ Signed-off-by: David S. Miller struct page_pool { --- a/net/core/page_pool.c +++ b/net/core/page_pool.c -@@ -35,6 +35,31 @@ +@@ -58,6 +58,31 @@ static void page_pool_producer_unlock(st struct page_pool_recycle_stats __percpu *s = pool->recycle_stats; \ this_cpu_inc(s->__stat); \ } while (0) diff --git a/target/linux/generic/backport-5.15/603-v5.19-page_pool-Add-recycle-stats-to-page_pool_put_page_bu.patch b/target/linux/generic/backport-5.15/603-v5.19-page_pool-Add-recycle-stats-to-page_pool_put_page_bu.patch index 6ae3fb7133..f438ef3a59 100644 --- a/target/linux/generic/backport-5.15/603-v5.19-page_pool-Add-recycle-stats-to-page_pool_put_page_bu.patch +++ b/target/linux/generic/backport-5.15/603-v5.19-page_pool-Add-recycle-stats-to-page_pool_put_page_bu.patch @@ -16,7 +16,7 @@ Signed-off-by: Paolo Abeni --- a/net/core/page_pool.c +++ b/net/core/page_pool.c -@@ -36,6 +36,12 @@ +@@ -59,6 +59,12 @@ static void page_pool_producer_unlock(st this_cpu_inc(s->__stat); \ } while (0) @@ -29,7 +29,7 @@ Signed-off-by: Paolo Abeni bool page_pool_get_stats(struct page_pool *pool, struct page_pool_stats *stats) { -@@ -63,6 +69,7 @@ EXPORT_SYMBOL(page_pool_get_stats); +@@ -86,6 +92,7 @@ EXPORT_SYMBOL(page_pool_get_stats); #else #define alloc_stat_inc(pool, __stat) #define recycle_stat_inc(pool, __stat) @@ -37,9 +37,9 @@ Signed-off-by: Paolo Abeni #endif static int page_pool_init(struct page_pool *pool, -@@ -569,9 +576,13 @@ void page_pool_put_page_bulk(struct page +@@ -593,9 +600,13 @@ void page_pool_put_page_bulk(struct page /* Bulk producer into ptr_ring page_pool cache */ - page_pool_ring_lock(pool); + in_softirq = page_pool_producer_lock(pool); for (i = 0; i < bulk_len; i++) { - if (__ptr_ring_produce(&pool->ring, data[i])) - break; /* ring full */ @@ -50,6 +50,6 @@ Signed-off-by: Paolo Abeni + } } + recycle_stat_add(pool, ring, i); - page_pool_ring_unlock(pool); + page_pool_producer_unlock(pool, in_softirq); /* Hopefully all pages was return into ptr_ring */ diff --git a/target/linux/generic/backport-5.15/604-v5.19-net-page_pool-introduce-ethtool-stats.patch b/target/linux/generic/backport-5.15/604-v5.19-net-page_pool-introduce-ethtool-stats.patch index e5cf91ceee..3ff136b084 100644 --- a/target/linux/generic/backport-5.15/604-v5.19-net-page_pool-introduce-ethtool-stats.patch +++ b/target/linux/generic/backport-5.15/604-v5.19-net-page_pool-introduce-ethtool-stats.patch @@ -62,7 +62,7 @@ Signed-off-by: David S. Miller #include -@@ -42,6 +43,20 @@ +@@ -65,6 +66,20 @@ static void page_pool_producer_unlock(st this_cpu_add(s->__stat, val); \ } while (0) @@ -83,7 +83,7 @@ Signed-off-by: David S. Miller bool page_pool_get_stats(struct page_pool *pool, struct page_pool_stats *stats) { -@@ -50,7 +65,13 @@ bool page_pool_get_stats(struct page_poo +@@ -73,7 +88,13 @@ bool page_pool_get_stats(struct page_poo if (!stats) return false; @@ -98,7 +98,7 @@ Signed-off-by: David S. Miller for_each_possible_cpu(cpu) { const struct page_pool_recycle_stats *pcpu = -@@ -66,6 +87,46 @@ bool page_pool_get_stats(struct page_poo +@@ -89,6 +110,46 @@ bool page_pool_get_stats(struct page_poo return true; } EXPORT_SYMBOL(page_pool_get_stats); diff --git a/target/linux/generic/backport-5.15/606-v5.18-xdp-add-frags-support-to-xdp_return_-buff-frame.patch b/target/linux/generic/backport-5.15/606-v5.18-xdp-add-frags-support-to-xdp_return_-buff-frame.patch index 86d24367dd..e126b21417 100644 --- a/target/linux/generic/backport-5.15/606-v5.18-xdp-add-frags-support-to-xdp_return_-buff-frame.patch +++ b/target/linux/generic/backport-5.15/606-v5.18-xdp-add-frags-support-to-xdp_return_-buff-frame.patch @@ -48,7 +48,7 @@ Signed-off-by: Alexei Starovoitov int xdp_rxq_info_reg(struct xdp_rxq_info *xdp_rxq, --- a/net/core/xdp.c +++ b/net/core/xdp.c -@@ -376,12 +376,38 @@ static void __xdp_return(void *data, str +@@ -409,12 +409,38 @@ static void __xdp_return(void *data, str void xdp_return_frame(struct xdp_frame *xdpf) { @@ -87,7 +87,7 @@ Signed-off-by: Alexei Starovoitov __xdp_return(xdpf->data, &xdpf->mem, true, NULL); } EXPORT_SYMBOL_GPL(xdp_return_frame_rx_napi); -@@ -417,7 +443,7 @@ void xdp_return_frame_bulk(struct xdp_fr +@@ -450,7 +476,7 @@ void xdp_return_frame_bulk(struct xdp_fr struct xdp_mem_allocator *xa; if (mem->type != MEM_TYPE_PAGE_POOL) { @@ -96,7 +96,7 @@ Signed-off-by: Alexei Starovoitov return; } -@@ -436,12 +462,38 @@ void xdp_return_frame_bulk(struct xdp_fr +@@ -469,12 +495,38 @@ void xdp_return_frame_bulk(struct xdp_fr bq->xa = rhashtable_lookup(mem_id_ht, &mem->id, mem_id_rht_params); } diff --git a/target/linux/generic/backport-5.15/610-v6.3-net-page_pool-use-in_softirq-instead.patch b/target/linux/generic/backport-5.15/610-v6.3-net-page_pool-use-in_softirq-instead.patch deleted file mode 100644 index 71e1140595..0000000000 --- a/target/linux/generic/backport-5.15/610-v6.3-net-page_pool-use-in_softirq-instead.patch +++ /dev/null @@ -1,56 +0,0 @@ -From: Qingfang DENG -Date: Fri, 3 Feb 2023 09:16:11 +0800 -Subject: [PATCH] net: page_pool: use in_softirq() instead - -We use BH context only for synchronization, so we don't care if it's -actually serving softirq or not. - -As a side node, in case of threaded NAPI, in_serving_softirq() will -return false because it's in process context with BH off, making -page_pool_recycle_in_cache() unreachable. - -Signed-off-by: Qingfang DENG ---- - ---- a/include/net/page_pool.h -+++ b/include/net/page_pool.h -@@ -357,7 +357,7 @@ static inline void page_pool_nid_changed - static inline void page_pool_ring_lock(struct page_pool *pool) - __acquires(&pool->ring.producer_lock) - { -- if (in_serving_softirq()) -+ if (in_softirq()) - spin_lock(&pool->ring.producer_lock); - else - spin_lock_bh(&pool->ring.producer_lock); -@@ -366,7 +366,7 @@ static inline void page_pool_ring_lock(s - static inline void page_pool_ring_unlock(struct page_pool *pool) - __releases(&pool->ring.producer_lock) - { -- if (in_serving_softirq()) -+ if (in_softirq()) - spin_unlock(&pool->ring.producer_lock); - else - spin_unlock_bh(&pool->ring.producer_lock); ---- a/net/core/page_pool.c -+++ b/net/core/page_pool.c -@@ -512,8 +512,8 @@ static void page_pool_return_page(struct - static bool page_pool_recycle_in_ring(struct page_pool *pool, struct page *page) - { - int ret; -- /* BH protection not needed if current is serving softirq */ -- if (in_serving_softirq()) -+ /* BH protection not needed if current is softirq */ -+ if (in_softirq()) - ret = ptr_ring_produce(&pool->ring, page); - else - ret = ptr_ring_produce_bh(&pool->ring, page); -@@ -576,7 +576,7 @@ __page_pool_put_page(struct page_pool *p - page_pool_dma_sync_for_device(pool, page, - dma_sync_size); - -- if (allow_direct && in_serving_softirq() && -+ if (allow_direct && in_softirq() && - page_pool_recycle_in_cache(page, pool)) - return NULL; - diff --git a/target/linux/generic/backport-5.15/700-v5.17-net-dsa-introduce-tagger-owned-storage-for-private.patch b/target/linux/generic/backport-5.15/700-v5.17-net-dsa-introduce-tagger-owned-storage-for-private.patch index f2b651f0c6..f56a968589 100644 --- a/target/linux/generic/backport-5.15/700-v5.17-net-dsa-introduce-tagger-owned-storage-for-private.patch +++ b/target/linux/generic/backport-5.15/700-v5.17-net-dsa-introduce-tagger-owned-storage-for-private.patch @@ -94,7 +94,7 @@ Signed-off-by: David S. Miller /* * Configuration data for this switch. */ -@@ -584,6 +589,13 @@ struct dsa_switch_ops { +@@ -612,6 +617,13 @@ struct dsa_switch_ops { enum dsa_tag_protocol mprot); int (*change_tag_protocol)(struct dsa_switch *ds, int port, enum dsa_tag_protocol proto); diff --git a/target/linux/generic/backport-5.15/703-03-v5.16-net-dsa-populate-supported_interfaces-member.patch b/target/linux/generic/backport-5.15/703-03-v5.16-net-dsa-populate-supported_interfaces-member.patch index b10e6da0e9..b438786536 100644 --- a/target/linux/generic/backport-5.15/703-03-v5.16-net-dsa-populate-supported_interfaces-member.patch +++ b/target/linux/generic/backport-5.15/703-03-v5.16-net-dsa-populate-supported_interfaces-member.patch @@ -26,7 +26,7 @@ Signed-off-by: David S. Miller --- a/include/net/dsa.h +++ b/include/net/dsa.h -@@ -626,6 +626,8 @@ struct dsa_switch_ops { +@@ -654,6 +654,8 @@ struct dsa_switch_ops { /* * PHYLINK integration */ diff --git a/target/linux/generic/backport-5.15/703-05-v5.17-net-dsa-replace-phylink_get_interfaces-with-phylink_.patch b/target/linux/generic/backport-5.15/703-05-v5.17-net-dsa-replace-phylink_get_interfaces-with-phylink_.patch index d70b9aa6a4..1d9616c0db 100644 --- a/target/linux/generic/backport-5.15/703-05-v5.17-net-dsa-replace-phylink_get_interfaces-with-phylink_.patch +++ b/target/linux/generic/backport-5.15/703-05-v5.17-net-dsa-replace-phylink_get_interfaces-with-phylink_.patch @@ -24,7 +24,7 @@ Signed-off-by: Jakub Kicinski --- a/include/net/dsa.h +++ b/include/net/dsa.h -@@ -626,8 +626,8 @@ struct dsa_switch_ops { +@@ -654,8 +654,8 @@ struct dsa_switch_ops { /* * PHYLINK integration */ diff --git a/target/linux/generic/backport-5.15/703-06-v5.18-net-dsa-add-support-for-phylink-mac_select_pcs.patch b/target/linux/generic/backport-5.15/703-06-v5.18-net-dsa-add-support-for-phylink-mac_select_pcs.patch index 2af5cb9d9d..9791ad2ac9 100644 --- a/target/linux/generic/backport-5.15/703-06-v5.18-net-dsa-add-support-for-phylink-mac_select_pcs.patch +++ b/target/linux/generic/backport-5.15/703-06-v5.18-net-dsa-add-support-for-phylink-mac_select_pcs.patch @@ -16,7 +16,7 @@ Signed-off-by: David S. Miller --- a/include/net/dsa.h +++ b/include/net/dsa.h -@@ -631,6 +631,9 @@ struct dsa_switch_ops { +@@ -659,6 +659,9 @@ struct dsa_switch_ops { void (*phylink_validate)(struct dsa_switch *ds, int port, unsigned long *supported, struct phylink_link_state *state); diff --git a/target/linux/generic/backport-5.15/703-10-v5.16-net-dsa-introduce-helpers-for-iterating-through-port.patch b/target/linux/generic/backport-5.15/703-10-v5.16-net-dsa-introduce-helpers-for-iterating-through-port.patch deleted file mode 100644 index a55623519c..0000000000 --- a/target/linux/generic/backport-5.15/703-10-v5.16-net-dsa-introduce-helpers-for-iterating-through-port.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 82b318983c515f29b8b3a0dad9f6a5fe8a68a7f4 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Wed, 20 Oct 2021 20:49:49 +0300 -Subject: [PATCH] net: dsa: introduce helpers for iterating through ports using - dp - -Since the DSA conversion from the ds->ports array into the dst->ports -list, the DSA API has encouraged driver writers, as well as the core -itself, to write inefficient code. - -Currently, code that wants to filter by a specific type of port when -iterating, like {!unused, user, cpu, dsa}, uses the dsa_is_*_port helper. -Under the hood, this uses dsa_to_port which iterates again through -dst->ports. But the driver iterates through the port list already, so -the complexity is quadratic for the typical case of a single-switch -tree. - -This patch introduces some iteration helpers where the iterator is -already a struct dsa_port *dp, so that the other variant of the -filtering functions, dsa_port_is_{unused,user,cpu_dsa}, can be used -directly on the iterator. This eliminates the second lookup. - -These functions can be used both by the core and by drivers. - -Signed-off-by: Vladimir Oltean -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - include/net/dsa.h | 28 ++++++++++++++++++++++++++++ - 1 file changed, 28 insertions(+) - ---- a/include/net/dsa.h -+++ b/include/net/dsa.h -@@ -476,6 +476,34 @@ static inline bool dsa_is_user_port(stru - return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_USER; - } - -+#define dsa_tree_for_each_user_port(_dp, _dst) \ -+ list_for_each_entry((_dp), &(_dst)->ports, list) \ -+ if (dsa_port_is_user((_dp))) -+ -+#define dsa_switch_for_each_port(_dp, _ds) \ -+ list_for_each_entry((_dp), &(_ds)->dst->ports, list) \ -+ if ((_dp)->ds == (_ds)) -+ -+#define dsa_switch_for_each_port_safe(_dp, _next, _ds) \ -+ list_for_each_entry_safe((_dp), (_next), &(_ds)->dst->ports, list) \ -+ if ((_dp)->ds == (_ds)) -+ -+#define dsa_switch_for_each_port_continue_reverse(_dp, _ds) \ -+ list_for_each_entry_continue_reverse((_dp), &(_ds)->dst->ports, list) \ -+ if ((_dp)->ds == (_ds)) -+ -+#define dsa_switch_for_each_available_port(_dp, _ds) \ -+ dsa_switch_for_each_port((_dp), (_ds)) \ -+ if (!dsa_port_is_unused((_dp))) -+ -+#define dsa_switch_for_each_user_port(_dp, _ds) \ -+ dsa_switch_for_each_port((_dp), (_ds)) \ -+ if (dsa_port_is_user((_dp))) -+ -+#define dsa_switch_for_each_cpu_port(_dp, _ds) \ -+ dsa_switch_for_each_port((_dp), (_ds)) \ -+ if (dsa_port_is_cpu((_dp))) -+ - static inline u32 dsa_user_ports(struct dsa_switch *ds) - { - u32 mask = 0; diff --git a/target/linux/generic/backport-5.15/705-02-v5.19-net-dsa-mt7530-populate-supported_interfaces-and-mac.patch b/target/linux/generic/backport-5.15/705-02-v5.19-net-dsa-mt7530-populate-supported_interfaces-and-mac.patch index 435f282845..f2ead18c36 100644 --- a/target/linux/generic/backport-5.15/705-02-v5.19-net-dsa-mt7530-populate-supported_interfaces-and-mac.patch +++ b/target/linux/generic/backport-5.15/705-02-v5.19-net-dsa-mt7530-populate-supported_interfaces-and-mac.patch @@ -23,7 +23,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2412,6 +2412,32 @@ mt7531_setup(struct dsa_switch *ds) +@@ -2444,6 +2444,32 @@ mt7531_setup(struct dsa_switch *ds) return 0; } @@ -56,7 +56,7 @@ Signed-off-by: Paolo Abeni static bool mt7530_phy_mode_supported(struct dsa_switch *ds, int port, const struct phylink_link_state *state) -@@ -2448,6 +2474,37 @@ static bool mt7531_is_rgmii_port(struct +@@ -2480,6 +2506,37 @@ static bool mt7531_is_rgmii_port(struct return (port == 5) && (priv->p5_intf_sel != P5_INTF_SEL_GMAC5_SGMII); } @@ -94,7 +94,7 @@ Signed-off-by: Paolo Abeni static bool mt7531_phy_mode_supported(struct dsa_switch *ds, int port, const struct phylink_link_state *state) -@@ -2924,6 +2981,18 @@ mt7531_cpu_port_config(struct dsa_switch +@@ -2956,6 +3013,18 @@ mt7531_cpu_port_config(struct dsa_switch return 0; } @@ -113,7 +113,7 @@ Signed-off-by: Paolo Abeni static void mt7530_mac_port_validate(struct dsa_switch *ds, int port, unsigned long *supported) -@@ -3159,6 +3228,7 @@ static const struct dsa_switch_ops mt753 +@@ -3191,6 +3260,7 @@ static const struct dsa_switch_ops mt753 .port_vlan_del = mt7530_port_vlan_del, .port_mirror_add = mt753x_port_mirror_add, .port_mirror_del = mt753x_port_mirror_del, @@ -121,7 +121,7 @@ Signed-off-by: Paolo Abeni .phylink_validate = mt753x_phylink_validate, .phylink_mac_link_state = mt753x_phylink_mac_link_state, .phylink_mac_config = mt753x_phylink_mac_config, -@@ -3176,6 +3246,7 @@ static const struct mt753x_info mt753x_t +@@ -3208,6 +3278,7 @@ static const struct mt753x_info mt753x_t .phy_read = mt7530_phy_read, .phy_write = mt7530_phy_write, .pad_setup = mt7530_pad_clk_setup, @@ -129,7 +129,7 @@ Signed-off-by: Paolo Abeni .phy_mode_supported = mt7530_phy_mode_supported, .mac_port_validate = mt7530_mac_port_validate, .mac_port_get_state = mt7530_phylink_mac_link_state, -@@ -3187,6 +3258,7 @@ static const struct mt753x_info mt753x_t +@@ -3219,6 +3290,7 @@ static const struct mt753x_info mt753x_t .phy_read = mt7530_phy_read, .phy_write = mt7530_phy_write, .pad_setup = mt7530_pad_clk_setup, @@ -137,7 +137,7 @@ Signed-off-by: Paolo Abeni .phy_mode_supported = mt7530_phy_mode_supported, .mac_port_validate = mt7530_mac_port_validate, .mac_port_get_state = mt7530_phylink_mac_link_state, -@@ -3199,6 +3271,7 @@ static const struct mt753x_info mt753x_t +@@ -3231,6 +3303,7 @@ static const struct mt753x_info mt753x_t .phy_write = mt7531_ind_phy_write, .pad_setup = mt7531_pad_setup, .cpu_port_config = mt7531_cpu_port_config, @@ -145,7 +145,7 @@ Signed-off-by: Paolo Abeni .phy_mode_supported = mt7531_phy_mode_supported, .mac_port_validate = mt7531_mac_port_validate, .mac_port_get_state = mt7531_phylink_mac_link_state, -@@ -3261,6 +3334,7 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3293,6 +3366,7 @@ mt7530_probe(struct mdio_device *mdiodev */ if (!priv->info->sw_setup || !priv->info->pad_setup || !priv->info->phy_read || !priv->info->phy_write || diff --git a/target/linux/generic/backport-5.15/705-03-v5.19-net-dsa-mt7530-remove-interface-checks.patch b/target/linux/generic/backport-5.15/705-03-v5.19-net-dsa-mt7530-remove-interface-checks.patch index 38a24dc46b..228016383d 100644 --- a/target/linux/generic/backport-5.15/705-03-v5.19-net-dsa-mt7530-remove-interface-checks.patch +++ b/target/linux/generic/backport-5.15/705-03-v5.19-net-dsa-mt7530-remove-interface-checks.patch @@ -21,7 +21,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2438,37 +2438,6 @@ static void mt7530_mac_port_get_caps(str +@@ -2470,37 +2470,6 @@ static void mt7530_mac_port_get_caps(str } } @@ -59,7 +59,7 @@ Signed-off-by: Paolo Abeni static bool mt7531_is_rgmii_port(struct mt7530_priv *priv, u32 port) { return (port == 5) && (priv->p5_intf_sel != P5_INTF_SEL_GMAC5_SGMII); -@@ -2505,44 +2474,6 @@ static void mt7531_mac_port_get_caps(str +@@ -2537,44 +2506,6 @@ static void mt7531_mac_port_get_caps(str } } @@ -104,7 +104,7 @@ Signed-off-by: Paolo Abeni static int mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state) { -@@ -2797,9 +2728,6 @@ mt753x_phylink_mac_config(struct dsa_swi +@@ -2829,9 +2760,6 @@ mt753x_phylink_mac_config(struct dsa_swi struct mt7530_priv *priv = ds->priv; u32 mcr_cur, mcr_new; @@ -114,7 +114,7 @@ Signed-off-by: Paolo Abeni switch (port) { case 0 ... 4: /* Internal phy */ if (state->interface != PHY_INTERFACE_MODE_GMII) -@@ -3015,12 +2943,6 @@ mt753x_phylink_validate(struct dsa_switc +@@ -3047,12 +2975,6 @@ mt753x_phylink_validate(struct dsa_switc __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; struct mt7530_priv *priv = ds->priv; @@ -127,7 +127,7 @@ Signed-off-by: Paolo Abeni phylink_set_port_modes(mask); if (state->interface != PHY_INTERFACE_MODE_TRGMII && -@@ -3247,7 +3169,6 @@ static const struct mt753x_info mt753x_t +@@ -3279,7 +3201,6 @@ static const struct mt753x_info mt753x_t .phy_write = mt7530_phy_write, .pad_setup = mt7530_pad_clk_setup, .mac_port_get_caps = mt7530_mac_port_get_caps, @@ -135,7 +135,7 @@ Signed-off-by: Paolo Abeni .mac_port_validate = mt7530_mac_port_validate, .mac_port_get_state = mt7530_phylink_mac_link_state, .mac_port_config = mt7530_mac_config, -@@ -3259,7 +3180,6 @@ static const struct mt753x_info mt753x_t +@@ -3291,7 +3212,6 @@ static const struct mt753x_info mt753x_t .phy_write = mt7530_phy_write, .pad_setup = mt7530_pad_clk_setup, .mac_port_get_caps = mt7530_mac_port_get_caps, @@ -143,7 +143,7 @@ Signed-off-by: Paolo Abeni .mac_port_validate = mt7530_mac_port_validate, .mac_port_get_state = mt7530_phylink_mac_link_state, .mac_port_config = mt7530_mac_config, -@@ -3272,7 +3192,6 @@ static const struct mt753x_info mt753x_t +@@ -3304,7 +3224,6 @@ static const struct mt753x_info mt753x_t .pad_setup = mt7531_pad_setup, .cpu_port_config = mt7531_cpu_port_config, .mac_port_get_caps = mt7531_mac_port_get_caps, @@ -151,7 +151,7 @@ Signed-off-by: Paolo Abeni .mac_port_validate = mt7531_mac_port_validate, .mac_port_get_state = mt7531_phylink_mac_link_state, .mac_port_config = mt7531_mac_config, -@@ -3335,7 +3254,6 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3367,7 +3286,6 @@ mt7530_probe(struct mdio_device *mdiodev if (!priv->info->sw_setup || !priv->info->pad_setup || !priv->info->phy_read || !priv->info->phy_write || !priv->info->mac_port_get_caps || diff --git a/target/linux/generic/backport-5.15/705-04-v5.19-net-dsa-mt7530-drop-use-of-phylink_helper_basex_spee.patch b/target/linux/generic/backport-5.15/705-04-v5.19-net-dsa-mt7530-drop-use-of-phylink_helper_basex_spee.patch index e607a3c7d2..1a1802a167 100644 --- a/target/linux/generic/backport-5.15/705-04-v5.19-net-dsa-mt7530-drop-use-of-phylink_helper_basex_spee.patch +++ b/target/linux/generic/backport-5.15/705-04-v5.19-net-dsa-mt7530-drop-use-of-phylink_helper_basex_spee.patch @@ -20,7 +20,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2967,11 +2967,6 @@ mt753x_phylink_validate(struct dsa_switc +@@ -2999,11 +2999,6 @@ mt753x_phylink_validate(struct dsa_switc linkmode_and(supported, supported, mask); linkmode_and(state->advertising, state->advertising, mask); diff --git a/target/linux/generic/backport-5.15/705-05-v5.19-net-dsa-mt7530-only-indicate-linkmodes-that-can-be-s.patch b/target/linux/generic/backport-5.15/705-05-v5.19-net-dsa-mt7530-only-indicate-linkmodes-that-can-be-s.patch index 63a3317630..636353c2d6 100644 --- a/target/linux/generic/backport-5.15/705-05-v5.19-net-dsa-mt7530-only-indicate-linkmodes-that-can-be-s.patch +++ b/target/linux/generic/backport-5.15/705-05-v5.19-net-dsa-mt7530-only-indicate-linkmodes-that-can-be-s.patch @@ -23,7 +23,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2545,12 +2545,13 @@ static int mt7531_rgmii_setup(struct mt7 +@@ -2577,12 +2577,13 @@ static int mt7531_rgmii_setup(struct mt7 } static void mt7531_sgmii_validate(struct mt7530_priv *priv, int port, @@ -38,7 +38,7 @@ Signed-off-by: Paolo Abeni phylink_set(supported, 2500baseX_Full); phylink_set(supported, 2500baseT_Full); } -@@ -2923,16 +2924,18 @@ static void mt753x_phylink_get_caps(stru +@@ -2955,16 +2956,18 @@ static void mt753x_phylink_get_caps(stru static void mt7530_mac_port_validate(struct dsa_switch *ds, int port, @@ -58,7 +58,7 @@ Signed-off-by: Paolo Abeni } static void -@@ -2955,12 +2958,13 @@ mt753x_phylink_validate(struct dsa_switc +@@ -2987,12 +2990,13 @@ mt753x_phylink_validate(struct dsa_switc } /* This switch only supports 1G full-duplex. */ diff --git a/target/linux/generic/backport-5.15/705-06-v5.19-net-dsa-mt7530-switch-to-use-phylink_get_linkmodes.patch b/target/linux/generic/backport-5.15/705-06-v5.19-net-dsa-mt7530-switch-to-use-phylink_get_linkmodes.patch index 97699d4c5e..4d7569b4ce 100644 --- a/target/linux/generic/backport-5.15/705-06-v5.19-net-dsa-mt7530-switch-to-use-phylink_get_linkmodes.patch +++ b/target/linux/generic/backport-5.15/705-06-v5.19-net-dsa-mt7530-switch-to-use-phylink_get_linkmodes.patch @@ -20,7 +20,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2544,19 +2544,6 @@ static int mt7531_rgmii_setup(struct mt7 +@@ -2576,19 +2576,6 @@ static int mt7531_rgmii_setup(struct mt7 return 0; } @@ -40,7 +40,7 @@ Signed-off-by: Paolo Abeni static void mt7531_sgmii_link_up_force(struct dsa_switch *ds, int port, unsigned int mode, phy_interface_t interface, -@@ -2923,51 +2910,21 @@ static void mt753x_phylink_get_caps(stru +@@ -2955,51 +2942,21 @@ static void mt753x_phylink_get_caps(stru } static void @@ -97,7 +97,7 @@ Signed-off-by: Paolo Abeni linkmode_and(supported, supported, mask); linkmode_and(state->advertising, state->advertising, mask); -@@ -3168,7 +3125,6 @@ static const struct mt753x_info mt753x_t +@@ -3200,7 +3157,6 @@ static const struct mt753x_info mt753x_t .phy_write = mt7530_phy_write, .pad_setup = mt7530_pad_clk_setup, .mac_port_get_caps = mt7530_mac_port_get_caps, @@ -105,7 +105,7 @@ Signed-off-by: Paolo Abeni .mac_port_get_state = mt7530_phylink_mac_link_state, .mac_port_config = mt7530_mac_config, }, -@@ -3179,7 +3135,6 @@ static const struct mt753x_info mt753x_t +@@ -3211,7 +3167,6 @@ static const struct mt753x_info mt753x_t .phy_write = mt7530_phy_write, .pad_setup = mt7530_pad_clk_setup, .mac_port_get_caps = mt7530_mac_port_get_caps, @@ -113,7 +113,7 @@ Signed-off-by: Paolo Abeni .mac_port_get_state = mt7530_phylink_mac_link_state, .mac_port_config = mt7530_mac_config, }, -@@ -3191,7 +3146,6 @@ static const struct mt753x_info mt753x_t +@@ -3223,7 +3178,6 @@ static const struct mt753x_info mt753x_t .pad_setup = mt7531_pad_setup, .cpu_port_config = mt7531_cpu_port_config, .mac_port_get_caps = mt7531_mac_port_get_caps, @@ -121,7 +121,7 @@ Signed-off-by: Paolo Abeni .mac_port_get_state = mt7531_phylink_mac_link_state, .mac_port_config = mt7531_mac_config, .mac_pcs_an_restart = mt7531_sgmii_restart_an, -@@ -3253,7 +3207,6 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3285,7 +3239,6 @@ mt7530_probe(struct mdio_device *mdiodev if (!priv->info->sw_setup || !priv->info->pad_setup || !priv->info->phy_read || !priv->info->phy_write || !priv->info->mac_port_get_caps || diff --git a/target/linux/generic/backport-5.15/705-07-v5.19-net-dsa-mt7530-partially-convert-to-phylink_pcs.patch b/target/linux/generic/backport-5.15/705-07-v5.19-net-dsa-mt7530-partially-convert-to-phylink_pcs.patch index b9b74833d2..fdf2a964cc 100644 --- a/target/linux/generic/backport-5.15/705-07-v5.19-net-dsa-mt7530-partially-convert-to-phylink_pcs.patch +++ b/target/linux/generic/backport-5.15/705-07-v5.19-net-dsa-mt7530-partially-convert-to-phylink_pcs.patch @@ -33,7 +33,7 @@ Signed-off-by: Paolo Abeni /* String, offset, and register size in bytes if different from 4 bytes */ static const struct mt7530_mib_desc mt7530_mib[] = { MIB_DESC(1, 0x00, "TxDrop"), -@@ -2544,12 +2549,11 @@ static int mt7531_rgmii_setup(struct mt7 +@@ -2576,12 +2581,11 @@ static int mt7531_rgmii_setup(struct mt7 return 0; } @@ -50,7 +50,7 @@ Signed-off-by: Paolo Abeni unsigned int val; /* For adjusting speed and duplex of SGMII force mode. */ -@@ -2575,6 +2579,9 @@ mt7531_sgmii_link_up_force(struct dsa_sw +@@ -2607,6 +2611,9 @@ mt7531_sgmii_link_up_force(struct dsa_sw /* MT7531 SGMII 1G force mode can only work in full duplex mode, * no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not. @@ -60,7 +60,7 @@ Signed-off-by: Paolo Abeni */ if ((speed == SPEED_10 || speed == SPEED_100) && duplex != DUPLEX_FULL) -@@ -2650,9 +2657,10 @@ static int mt7531_sgmii_setup_mode_an(st +@@ -2682,9 +2689,10 @@ static int mt7531_sgmii_setup_mode_an(st return 0; } @@ -73,7 +73,7 @@ Signed-off-by: Paolo Abeni u32 val; /* Only restart AN when AN is enabled */ -@@ -2709,6 +2717,24 @@ mt753x_mac_config(struct dsa_switch *ds, +@@ -2741,6 +2749,24 @@ mt753x_mac_config(struct dsa_switch *ds, return priv->info->mac_port_config(ds, port, mode, state->interface); } @@ -98,7 +98,7 @@ Signed-off-by: Paolo Abeni static void mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode, const struct phylink_link_state *state) -@@ -2770,17 +2796,6 @@ unsupported: +@@ -2802,17 +2828,6 @@ unsupported: mt7530_write(priv, MT7530_PMCR_P(port), mcr_new); } @@ -116,7 +116,7 @@ Signed-off-by: Paolo Abeni static void mt753x_phylink_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode, phy_interface_t interface) -@@ -2790,16 +2805,13 @@ static void mt753x_phylink_mac_link_down +@@ -2822,16 +2837,13 @@ static void mt753x_phylink_mac_link_down mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK); } @@ -139,7 +139,7 @@ Signed-off-by: Paolo Abeni } static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port, -@@ -2812,8 +2824,6 @@ static void mt753x_phylink_mac_link_up(s +@@ -2844,8 +2856,6 @@ static void mt753x_phylink_mac_link_up(s struct mt7530_priv *priv = ds->priv; u32 mcr; @@ -148,7 +148,7 @@ Signed-off-by: Paolo Abeni mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK; /* MT753x MAC works in 1G full duplex mode for all up-clocked -@@ -2891,6 +2901,8 @@ mt7531_cpu_port_config(struct dsa_switch +@@ -2923,6 +2933,8 @@ mt7531_cpu_port_config(struct dsa_switch return ret; mt7530_write(priv, MT7530_PMCR_P(port), PMCR_CPU_PORT_SETTING(priv->id)); @@ -157,7 +157,7 @@ Signed-off-by: Paolo Abeni mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED, interface, NULL, speed, DUPLEX_FULL, true, true); -@@ -2930,16 +2942,13 @@ mt753x_phylink_validate(struct dsa_switc +@@ -2962,16 +2974,13 @@ mt753x_phylink_validate(struct dsa_switc linkmode_and(state->advertising, state->advertising, mask); } @@ -178,7 +178,7 @@ Signed-off-by: Paolo Abeni pmsr = mt7530_read(priv, MT7530_PMSR_P(port)); state->link = (pmsr & PMSR_LINK); -@@ -2966,8 +2975,6 @@ mt7530_phylink_mac_link_state(struct dsa +@@ -2998,8 +3007,6 @@ mt7530_phylink_mac_link_state(struct dsa state->pause |= MLO_PAUSE_RX; if (pmsr & PMSR_TX_FC) state->pause |= MLO_PAUSE_TX; @@ -187,7 +187,7 @@ Signed-off-by: Paolo Abeni } static int -@@ -3009,32 +3016,49 @@ mt7531_sgmii_pcs_get_state_an(struct mt7 +@@ -3041,32 +3048,49 @@ mt7531_sgmii_pcs_get_state_an(struct mt7 return 0; } @@ -249,7 +249,7 @@ Signed-off-by: Paolo Abeni if (ret) return ret; -@@ -3047,6 +3071,13 @@ mt753x_setup(struct dsa_switch *ds) +@@ -3079,6 +3103,13 @@ mt753x_setup(struct dsa_switch *ds) if (ret && priv->irq) mt7530_free_irq_common(priv); @@ -263,7 +263,7 @@ Signed-off-by: Paolo Abeni return ret; } -@@ -3108,9 +3139,8 @@ static const struct dsa_switch_ops mt753 +@@ -3140,9 +3171,8 @@ static const struct dsa_switch_ops mt753 .port_mirror_del = mt753x_port_mirror_del, .phylink_get_caps = mt753x_phylink_get_caps, .phylink_validate = mt753x_phylink_validate, @@ -274,7 +274,7 @@ Signed-off-by: Paolo Abeni .phylink_mac_link_down = mt753x_phylink_mac_link_down, .phylink_mac_link_up = mt753x_phylink_mac_link_up, .get_mac_eee = mt753x_get_mac_eee, -@@ -3120,36 +3150,34 @@ static const struct dsa_switch_ops mt753 +@@ -3152,36 +3182,34 @@ static const struct dsa_switch_ops mt753 static const struct mt753x_info mt753x_table[] = { [ID_MT7621] = { .id = ID_MT7621, @@ -314,7 +314,7 @@ Signed-off-by: Paolo Abeni }, }; -@@ -3207,7 +3235,7 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3239,7 +3267,7 @@ mt7530_probe(struct mdio_device *mdiodev if (!priv->info->sw_setup || !priv->info->pad_setup || !priv->info->phy_read || !priv->info->phy_write || !priv->info->mac_port_get_caps || diff --git a/target/linux/generic/backport-5.15/705-08-v5.19-net-dsa-mt7530-move-autoneg-handling-to-PCS-validati.patch b/target/linux/generic/backport-5.15/705-08-v5.19-net-dsa-mt7530-move-autoneg-handling-to-PCS-validati.patch index 4aa013aad7..7b2fa36699 100644 --- a/target/linux/generic/backport-5.15/705-08-v5.19-net-dsa-mt7530-move-autoneg-handling-to-PCS-validati.patch +++ b/target/linux/generic/backport-5.15/705-08-v5.19-net-dsa-mt7530-move-autoneg-handling-to-PCS-validati.patch @@ -20,7 +20,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2921,25 +2921,16 @@ static void mt753x_phylink_get_caps(stru +@@ -2953,25 +2953,16 @@ static void mt753x_phylink_get_caps(stru priv->info->mac_port_get_caps(ds, port, config); } @@ -55,7 +55,7 @@ Signed-off-by: Paolo Abeni } static void mt7530_pcs_get_state(struct phylink_pcs *pcs, -@@ -3041,12 +3032,14 @@ static void mt7530_pcs_an_restart(struct +@@ -3073,12 +3064,14 @@ static void mt7530_pcs_an_restart(struct } static const struct phylink_pcs_ops mt7530_pcs_ops = { @@ -70,7 +70,7 @@ Signed-off-by: Paolo Abeni .pcs_get_state = mt7531_pcs_get_state, .pcs_config = mt753x_pcs_config, .pcs_an_restart = mt7531_pcs_an_restart, -@@ -3138,7 +3131,6 @@ static const struct dsa_switch_ops mt753 +@@ -3170,7 +3163,6 @@ static const struct dsa_switch_ops mt753 .port_mirror_add = mt753x_port_mirror_add, .port_mirror_del = mt753x_port_mirror_del, .phylink_get_caps = mt753x_phylink_get_caps, diff --git a/target/linux/generic/backport-5.15/705-09-v5.19-net-dsa-mt7530-mark-as-non-legacy.patch b/target/linux/generic/backport-5.15/705-09-v5.19-net-dsa-mt7530-mark-as-non-legacy.patch index d921d78733..8bb587f5f5 100644 --- a/target/linux/generic/backport-5.15/705-09-v5.19-net-dsa-mt7530-mark-as-non-legacy.patch +++ b/target/linux/generic/backport-5.15/705-09-v5.19-net-dsa-mt7530-mark-as-non-legacy.patch @@ -19,7 +19,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2918,6 +2918,12 @@ static void mt753x_phylink_get_caps(stru +@@ -2950,6 +2950,12 @@ static void mt753x_phylink_get_caps(stru config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | MAC_10 | MAC_100 | MAC_1000FD; diff --git a/target/linux/generic/backport-5.15/705-10-v5.19-net-dsa-mt753x-fix-pcs-conversion-regression.patch b/target/linux/generic/backport-5.15/705-10-v5.19-net-dsa-mt753x-fix-pcs-conversion-regression.patch index e797b1ecb4..438c02ade6 100644 --- a/target/linux/generic/backport-5.15/705-10-v5.19-net-dsa-mt753x-fix-pcs-conversion-regression.patch +++ b/target/linux/generic/backport-5.15/705-10-v5.19-net-dsa-mt753x-fix-pcs-conversion-regression.patch @@ -81,7 +81,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -3056,9 +3056,16 @@ static int +@@ -3088,9 +3088,16 @@ static int mt753x_setup(struct dsa_switch *ds) { struct mt7530_priv *priv = ds->priv; @@ -100,7 +100,7 @@ Signed-off-by: Jakub Kicinski if (ret) return ret; -@@ -3070,13 +3077,6 @@ mt753x_setup(struct dsa_switch *ds) +@@ -3102,13 +3109,6 @@ mt753x_setup(struct dsa_switch *ds) if (ret && priv->irq) mt7530_free_irq_common(priv); diff --git a/target/linux/generic/backport-5.15/705-12-v6.0-net-dsa-mt7530-rework-mt753-01-_setup.patch b/target/linux/generic/backport-5.15/705-12-v6.0-net-dsa-mt7530-rework-mt753-01-_setup.patch deleted file mode 100644 index b02705cc70..0000000000 --- a/target/linux/generic/backport-5.15/705-12-v6.0-net-dsa-mt7530-rework-mt753-01-_setup.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 1f0dfd443eea7fc3e818e96f7c8264913ba41859 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Fri, 10 Jun 2022 19:05:38 +0200 -Subject: [PATCH 12/13] net: dsa: mt7530: rework mt753[01]_setup - -Enumerate available cpu-ports instead of using hardcoded constant. - -Suggested-by: Vladimir Oltean -Signed-off-by: Frank Wunderlich -Reviewed-by: Vladimir Oltean -Reviewed-by: Florian Fainelli -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mt7530.c | 25 +++++++++++++++++++++---- - 1 file changed, 21 insertions(+), 4 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2101,11 +2101,12 @@ static int - mt7530_setup(struct dsa_switch *ds) - { - struct mt7530_priv *priv = ds->priv; -+ struct device_node *dn = NULL; - struct device_node *phy_node; - struct device_node *mac_np; - struct mt7530_dummy_poll p; - phy_interface_t interface; -- struct device_node *dn; -+ struct dsa_port *cpu_dp; - u32 id, val; - int ret, i; - -@@ -2113,7 +2114,19 @@ mt7530_setup(struct dsa_switch *ds) - * controller also is the container for two GMACs nodes representing - * as two netdev instances. - */ -- dn = dsa_to_port(ds, MT7530_CPU_PORT)->master->dev.of_node->parent; -+ dsa_switch_for_each_cpu_port(cpu_dp, ds) { -+ dn = cpu_dp->master->dev.of_node->parent; -+ /* It doesn't matter which CPU port is found first, -+ * their masters should share the same parent OF node -+ */ -+ break; -+ } -+ -+ if (!dn) { -+ dev_err(ds->dev, "parent OF node of DSA master not found"); -+ return -EINVAL; -+ } -+ - ds->assisted_learning_on_cpu_port = true; - ds->mtu_enforcement_ingress = true; - -@@ -2286,6 +2299,7 @@ mt7531_setup(struct dsa_switch *ds) - { - struct mt7530_priv *priv = ds->priv; - struct mt7530_dummy_poll p; -+ struct dsa_port *cpu_dp; - u32 val, id; - int ret, i; - -@@ -2360,8 +2374,11 @@ mt7531_setup(struct dsa_switch *ds) - CORE_PLL_GROUP4, val); - - /* BPDU to CPU port */ -- mt7530_rmw(priv, MT7531_CFC, MT7531_CPU_PMAP_MASK, -- BIT(MT7530_CPU_PORT)); -+ dsa_switch_for_each_cpu_port(cpu_dp, ds) { -+ mt7530_rmw(priv, MT7531_CFC, MT7531_CPU_PMAP_MASK, -+ BIT(cpu_dp->index)); -+ break; -+ } - mt7530_rmw(priv, MT753X_BPC, MT753X_BPDU_PORT_FW_MASK, - MT753X_BPDU_CPU_ONLY); - diff --git a/target/linux/generic/backport-5.15/766-v5.18-01-net-dsa-provide-switch-operations-for-tracking-the-m.patch b/target/linux/generic/backport-5.15/766-v5.18-01-net-dsa-provide-switch-operations-for-tracking-the-m.patch index bffdcb2881..79e8c1e4e2 100644 --- a/target/linux/generic/backport-5.15/766-v5.18-01-net-dsa-provide-switch-operations-for-tracking-the-m.patch +++ b/target/linux/generic/backport-5.15/766-v5.18-01-net-dsa-provide-switch-operations-for-tracking-the-m.patch @@ -68,7 +68,7 @@ Signed-off-by: David S. Miller static inline bool dsa_is_unused_port(struct dsa_switch *ds, int p) { return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_UNUSED; -@@ -949,6 +959,13 @@ struct dsa_switch_ops { +@@ -977,6 +987,13 @@ struct dsa_switch_ops { int (*tag_8021q_vlan_add)(struct dsa_switch *ds, int port, u16 vid, u16 flags); int (*tag_8021q_vlan_del)(struct dsa_switch *ds, int port, u16 vid); diff --git a/target/linux/generic/backport-5.15/782-v6.1-net-dsa-mt7530-add-support-for-in-band-link-status.patch b/target/linux/generic/backport-5.15/782-v6.1-net-dsa-mt7530-add-support-for-in-band-link-status.patch index ebfbaccc9d..377ee76171 100644 --- a/target/linux/generic/backport-5.15/782-v6.1-net-dsa-mt7530-add-support-for-in-band-link-status.patch +++ b/target/linux/generic/backport-5.15/782-v6.1-net-dsa-mt7530-add-support-for-in-band-link-status.patch @@ -19,7 +19,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2721,9 +2721,6 @@ mt7531_mac_config(struct dsa_switch *ds, +@@ -2736,9 +2736,6 @@ mt7531_mac_config(struct dsa_switch *ds, case PHY_INTERFACE_MODE_NA: case PHY_INTERFACE_MODE_1000BASEX: case PHY_INTERFACE_MODE_2500BASEX: @@ -29,7 +29,7 @@ Signed-off-by: David S. Miller return mt7531_sgmii_setup_mode_force(priv, port, interface); default: return -EINVAL; -@@ -2799,13 +2796,6 @@ unsupported: +@@ -2814,13 +2811,6 @@ unsupported: return; } @@ -43,7 +43,7 @@ Signed-off-by: David S. Miller mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port)); mcr_new = mcr_cur; mcr_new &= ~PMCR_LINK_SETTINGS_MASK; -@@ -2942,6 +2932,9 @@ static void mt753x_phylink_get_caps(stru +@@ -2957,6 +2947,9 @@ static void mt753x_phylink_get_caps(stru config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | MAC_10 | MAC_100 | MAC_1000FD; @@ -53,7 +53,7 @@ Signed-off-by: David S. Miller /* This driver does not make use of the speed, duplex, pause or the * advertisement in its mac_config, so it is safe to mark this driver * as non-legacy. -@@ -3007,6 +3000,7 @@ mt7531_sgmii_pcs_get_state_an(struct mt7 +@@ -3022,6 +3015,7 @@ mt7531_sgmii_pcs_get_state_an(struct mt7 status = mt7530_read(priv, MT7531_PCS_CONTROL_1(port)); state->link = !!(status & MT7531_SGMII_LINK_STATUS); @@ -61,7 +61,7 @@ Signed-off-by: David S. Miller if (state->interface == PHY_INTERFACE_MODE_SGMII && (status & MT7531_SGMII_AN_ENABLE)) { val = mt7530_read(priv, MT7531_PCS_SPEED_ABILITY(port)); -@@ -3037,16 +3031,44 @@ mt7531_sgmii_pcs_get_state_an(struct mt7 +@@ -3052,16 +3046,44 @@ mt7531_sgmii_pcs_get_state_an(struct mt7 return 0; } @@ -109,7 +109,7 @@ Signed-off-by: David S. Miller } static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode, -@@ -3087,6 +3109,8 @@ mt753x_setup(struct dsa_switch *ds) +@@ -3102,6 +3124,8 @@ mt753x_setup(struct dsa_switch *ds) priv->pcs[i].pcs.ops = priv->info->pcs_ops; priv->pcs[i].priv = priv; priv->pcs[i].port = i; diff --git a/target/linux/generic/backport-5.15/788-v6.3-net-dsa-mt7530-use-external-PCS-driver.patch b/target/linux/generic/backport-5.15/788-v6.3-net-dsa-mt7530-use-external-PCS-driver.patch index ee12399140..9e445f1300 100644 --- a/target/linux/generic/backport-5.15/788-v6.3-net-dsa-mt7530-use-external-PCS-driver.patch +++ b/target/linux/generic/backport-5.15/788-v6.3-net-dsa-mt7530-use-external-PCS-driver.patch @@ -81,7 +81,7 @@ Tested-by: Frank Wunderlich #include #include #include -@@ -2573,128 +2574,11 @@ static int mt7531_rgmii_setup(struct mt7 +@@ -2588,128 +2589,11 @@ static int mt7531_rgmii_setup(struct mt7 return 0; } @@ -210,7 +210,7 @@ Tested-by: Frank Wunderlich static int mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode, phy_interface_t interface) -@@ -2717,11 +2601,11 @@ mt7531_mac_config(struct dsa_switch *ds, +@@ -2732,11 +2616,11 @@ mt7531_mac_config(struct dsa_switch *ds, phydev = dp->slave->phydev; return mt7531_rgmii_setup(priv, port, interface, phydev); case PHY_INTERFACE_MODE_SGMII: @@ -224,7 +224,7 @@ Tested-by: Frank Wunderlich default: return -EINVAL; } -@@ -2746,11 +2630,11 @@ mt753x_phylink_mac_select_pcs(struct dsa +@@ -2761,11 +2645,11 @@ mt753x_phylink_mac_select_pcs(struct dsa switch (interface) { case PHY_INTERFACE_MODE_TRGMII: @@ -238,7 +238,7 @@ Tested-by: Frank Wunderlich default: return NULL; } -@@ -2991,86 +2875,6 @@ static void mt7530_pcs_get_state(struct +@@ -3006,86 +2890,6 @@ static void mt7530_pcs_get_state(struct state->pause |= MLO_PAUSE_TX; } @@ -325,7 +325,7 @@ Tested-by: Frank Wunderlich static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode, phy_interface_t interface, const unsigned long *advertising, -@@ -3090,18 +2894,57 @@ static const struct phylink_pcs_ops mt75 +@@ -3105,18 +2909,57 @@ static const struct phylink_pcs_ops mt75 .pcs_an_restart = mt7530_pcs_an_restart, }; @@ -389,7 +389,7 @@ Tested-by: Frank Wunderlich int i, ret; /* Initialise the PCS devices */ -@@ -3109,8 +2952,6 @@ mt753x_setup(struct dsa_switch *ds) +@@ -3124,8 +2967,6 @@ mt753x_setup(struct dsa_switch *ds) priv->pcs[i].pcs.ops = priv->info->pcs_ops; priv->pcs[i].priv = priv; priv->pcs[i].port = i; @@ -398,7 +398,7 @@ Tested-by: Frank Wunderlich } ret = priv->info->sw_setup(ds); -@@ -3125,6 +2966,16 @@ mt753x_setup(struct dsa_switch *ds) +@@ -3140,6 +2981,16 @@ mt753x_setup(struct dsa_switch *ds) if (ret && priv->irq) mt7530_free_irq_common(priv); @@ -415,7 +415,7 @@ Tested-by: Frank Wunderlich return ret; } -@@ -3216,7 +3067,7 @@ static const struct mt753x_info mt753x_t +@@ -3231,7 +3082,7 @@ static const struct mt753x_info mt753x_t }, [ID_MT7531] = { .id = ID_MT7531, @@ -424,7 +424,7 @@ Tested-by: Frank Wunderlich .sw_setup = mt7531_setup, .phy_read = mt7531_ind_phy_read, .phy_write = mt7531_ind_phy_write, -@@ -3324,7 +3175,7 @@ static void +@@ -3339,7 +3190,7 @@ static void mt7530_remove(struct mdio_device *mdiodev) { struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev); @@ -433,7 +433,7 @@ Tested-by: Frank Wunderlich if (!priv) return; -@@ -3343,6 +3194,10 @@ mt7530_remove(struct mdio_device *mdiode +@@ -3358,6 +3209,10 @@ mt7530_remove(struct mdio_device *mdiode mt7530_free_irq(priv); dsa_unregister_switch(priv->ds); diff --git a/target/linux/generic/backport-5.15/790-v6.4-0002-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch b/target/linux/generic/backport-5.15/790-v6.4-0002-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch index 8963d93d10..a933d376c8 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0002-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0002-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch @@ -18,7 +18,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2926,26 +2926,56 @@ static const struct regmap_bus mt7531_re +@@ -2941,26 +2941,56 @@ static const struct regmap_bus mt7531_re .reg_update_bits = mt7530_regmap_update_bits, }; @@ -88,7 +88,7 @@ Signed-off-by: David S. Miller int i, ret; /* Initialise the PCS devices */ -@@ -2967,15 +2997,11 @@ mt753x_setup(struct dsa_switch *ds) +@@ -2982,15 +3012,11 @@ mt753x_setup(struct dsa_switch *ds) if (ret && priv->irq) mt7530_free_irq_common(priv); diff --git a/target/linux/generic/backport-5.15/790-v6.4-0003-net-dsa-mt7530-use-unlocked-regmap-accessors.patch b/target/linux/generic/backport-5.15/790-v6.4-0003-net-dsa-mt7530-use-unlocked-regmap-accessors.patch index 1b4a956199..5f6990f117 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0003-net-dsa-mt7530-use-unlocked-regmap-accessors.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0003-net-dsa-mt7530-use-unlocked-regmap-accessors.patch @@ -19,7 +19,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2899,7 +2899,7 @@ static int mt7530_regmap_read(void *cont +@@ -2914,7 +2914,7 @@ static int mt7530_regmap_read(void *cont { struct mt7530_priv *priv = context; @@ -28,7 +28,7 @@ Signed-off-by: David S. Miller return 0; }; -@@ -2907,23 +2907,25 @@ static int mt7530_regmap_write(void *con +@@ -2922,23 +2922,25 @@ static int mt7530_regmap_write(void *con { struct mt7530_priv *priv = context; @@ -62,7 +62,7 @@ Signed-off-by: David S. Miller }; static int -@@ -2949,6 +2951,9 @@ mt7531_create_sgmii(struct mt7530_priv * +@@ -2964,6 +2966,9 @@ mt7531_create_sgmii(struct mt7530_priv * mt7531_pcs_config[i]->reg_stride = 4; mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i); mt7531_pcs_config[i]->max_register = 0x17c; diff --git a/target/linux/generic/backport-5.15/790-v6.4-0004-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch b/target/linux/generic/backport-5.15/790-v6.4-0004-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch index 2d8bab9da6..9499ca598f 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0004-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0004-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch @@ -133,7 +133,7 @@ Signed-off-by: David S. Miller } static void -@@ -2895,22 +2916,6 @@ static const struct phylink_pcs_ops mt75 +@@ -2910,22 +2931,6 @@ static const struct phylink_pcs_ops mt75 .pcs_an_restart = mt7530_pcs_an_restart, }; @@ -156,7 +156,7 @@ Signed-off-by: David S. Miller static void mt7530_mdio_regmap_lock(void *mdio_lock) { -@@ -2923,7 +2928,7 @@ mt7530_mdio_regmap_unlock(void *mdio_loc +@@ -2938,7 +2943,7 @@ mt7530_mdio_regmap_unlock(void *mdio_loc mutex_unlock(mdio_lock); } @@ -165,7 +165,7 @@ Signed-off-by: David S. Miller .reg_write = mt7530_regmap_write, .reg_read = mt7530_regmap_read, }; -@@ -2956,7 +2961,7 @@ mt7531_create_sgmii(struct mt7530_priv * +@@ -2971,7 +2976,7 @@ mt7531_create_sgmii(struct mt7530_priv * mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock; regmap = devm_regmap_init(priv->dev, @@ -174,7 +174,7 @@ Signed-off-by: David S. Miller mt7531_pcs_config[i]); if (IS_ERR(regmap)) { ret = PTR_ERR(regmap); -@@ -3121,6 +3126,7 @@ MODULE_DEVICE_TABLE(of, mt7530_of_match) +@@ -3136,6 +3141,7 @@ MODULE_DEVICE_TABLE(of, mt7530_of_match) static int mt7530_probe(struct mdio_device *mdiodev) { @@ -182,7 +182,7 @@ Signed-off-by: David S. Miller struct mt7530_priv *priv; struct device_node *dn; -@@ -3200,6 +3206,21 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3215,6 +3221,21 @@ mt7530_probe(struct mdio_device *mdiodev mutex_init(&priv->reg_mutex); dev_set_drvdata(&mdiodev->dev, priv); diff --git a/target/linux/generic/backport-5.15/790-v6.4-0005-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch b/target/linux/generic/backport-5.15/790-v6.4-0005-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch index 0bb64c3c5e..44c31a4f6f 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0005-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0005-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch @@ -18,7 +18,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -3007,12 +3007,6 @@ mt753x_setup(struct dsa_switch *ds) +@@ -3022,12 +3022,6 @@ mt753x_setup(struct dsa_switch *ds) if (ret && priv->irq) mt7530_free_irq_common(priv); @@ -31,7 +31,7 @@ Signed-off-by: David S. Miller return ret; } -@@ -3129,6 +3123,7 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3144,6 +3138,7 @@ mt7530_probe(struct mdio_device *mdiodev static struct regmap_config *regmap_config; struct mt7530_priv *priv; struct device_node *dn; @@ -39,7 +39,7 @@ Signed-off-by: David S. Miller dn = mdiodev->dev.of_node; -@@ -3221,6 +3216,12 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3236,6 +3231,12 @@ mt7530_probe(struct mdio_device *mdiodev if (IS_ERR(priv->regmap)) return PTR_ERR(priv->regmap); diff --git a/target/linux/generic/backport-5.15/790-v6.4-0008-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch b/target/linux/generic/backport-5.15/790-v6.4-0008-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch index 34a1bd7372..aeb1e37a1a 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0008-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0008-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch @@ -17,7 +17,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -3135,44 +3135,21 @@ static const struct of_device_id mt7530_ +@@ -3150,44 +3150,21 @@ static const struct of_device_id mt7530_ MODULE_DEVICE_TABLE(of, mt7530_of_match); static int @@ -67,7 +67,7 @@ Signed-off-by: David S. Miller if (!priv->info) return -EINVAL; -@@ -3186,23 +3163,53 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3201,23 +3178,53 @@ mt7530_probe(struct mdio_device *mdiodev return -EINVAL; priv->id = priv->info->id; @@ -131,7 +131,7 @@ Signed-off-by: David S. Miller priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(priv->reset)) { -@@ -3211,12 +3218,15 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3226,12 +3233,15 @@ mt7530_probe(struct mdio_device *mdiodev } } diff --git a/target/linux/generic/backport-5.15/790-v6.4-0009-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch b/target/linux/generic/backport-5.15/790-v6.4-0009-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch index 2881365ec7..2651f45918 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0009-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0009-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch @@ -17,7 +17,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -3253,6 +3253,17 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3268,6 +3268,17 @@ mt7530_probe(struct mdio_device *mdiodev } static void @@ -35,7 +35,7 @@ Signed-off-by: David S. Miller mt7530_remove(struct mdio_device *mdiodev) { struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev); -@@ -3271,16 +3282,11 @@ mt7530_remove(struct mdio_device *mdiode +@@ -3286,16 +3297,11 @@ mt7530_remove(struct mdio_device *mdiode dev_err(priv->dev, "Failed to disable io pwr: %d\n", ret); diff --git a/target/linux/generic/backport-5.15/790-v6.4-0010-net-dsa-mt7530-split-off-common-parts-from-mt7531_se.patch b/target/linux/generic/backport-5.15/790-v6.4-0010-net-dsa-mt7530-split-off-common-parts-from-mt7531_se.patch deleted file mode 100644 index c8e7d93026..0000000000 --- a/target/linux/generic/backport-5.15/790-v6.4-0010-net-dsa-mt7530-split-off-common-parts-from-mt7531_se.patch +++ /dev/null @@ -1,143 +0,0 @@ -From 7f54cc9772ced2d76ac11832f0ada43798443ac9 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 02:19:02 +0100 -Subject: [PATCH 13/16] net: dsa: mt7530: split-off common parts from - mt7531_setup - -MT7988 shares a significant part of the setup function with MT7531. -Split-off those parts into a shared function which is going to be used -also by mt7988_setup. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/dsa/mt7530.c | 99 ++++++++++++++++++++++------------------ - 1 file changed, 55 insertions(+), 44 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2348,11 +2348,64 @@ mt7530_setup(struct dsa_switch *ds) - } - - static int -+mt7531_setup_common(struct dsa_switch *ds) -+{ -+ struct mt7530_priv *priv = ds->priv; -+ struct dsa_port *cpu_dp; -+ int ret, i; -+ -+ /* BPDU to CPU port */ -+ dsa_switch_for_each_cpu_port(cpu_dp, ds) { -+ mt7530_rmw(priv, MT7531_CFC, MT7531_CPU_PMAP_MASK, -+ BIT(cpu_dp->index)); -+ break; -+ } -+ mt7530_rmw(priv, MT753X_BPC, MT753X_BPDU_PORT_FW_MASK, -+ MT753X_BPDU_CPU_ONLY); -+ -+ /* Enable and reset MIB counters */ -+ mt7530_mib_reset(ds); -+ -+ for (i = 0; i < MT7530_NUM_PORTS; i++) { -+ /* Disable forwarding by default on all ports */ -+ mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK, -+ PCR_MATRIX_CLR); -+ -+ /* Disable learning by default on all ports */ -+ mt7530_set(priv, MT7530_PSC_P(i), SA_DIS); -+ -+ mt7530_set(priv, MT7531_DBG_CNT(i), MT7531_DIS_CLR); -+ -+ if (dsa_is_cpu_port(ds, i)) { -+ ret = mt753x_cpu_port_enable(ds, i); -+ if (ret) -+ return ret; -+ } else { -+ mt7530_port_disable(ds, i); -+ -+ /* Set default PVID to 0 on all user ports */ -+ mt7530_rmw(priv, MT7530_PPBV1_P(i), G0_PORT_VID_MASK, -+ G0_PORT_VID_DEF); -+ } -+ -+ /* Enable consistent egress tag */ -+ mt7530_rmw(priv, MT7530_PVC_P(i), PVC_EG_TAG_MASK, -+ PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT)); -+ } -+ -+ /* Flush the FDB table */ -+ ret = mt7530_fdb_cmd(priv, MT7530_FDB_FLUSH, NULL); -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+static int - mt7531_setup(struct dsa_switch *ds) - { - struct mt7530_priv *priv = ds->priv; - struct mt7530_dummy_poll p; -- struct dsa_port *cpu_dp; - u32 val, id; - int ret, i; - -@@ -2426,44 +2479,7 @@ mt7531_setup(struct dsa_switch *ds) - mt7531_ind_c45_phy_write(priv, MT753X_CTRL_PHY_ADDR, MDIO_MMD_VEND2, - CORE_PLL_GROUP4, val); - -- /* BPDU to CPU port */ -- dsa_switch_for_each_cpu_port(cpu_dp, ds) { -- mt7530_rmw(priv, MT7531_CFC, MT7531_CPU_PMAP_MASK, -- BIT(cpu_dp->index)); -- break; -- } -- mt7530_rmw(priv, MT753X_BPC, MT753X_BPDU_PORT_FW_MASK, -- MT753X_BPDU_CPU_ONLY); -- -- /* Enable and reset MIB counters */ -- mt7530_mib_reset(ds); -- -- for (i = 0; i < MT7530_NUM_PORTS; i++) { -- /* Disable forwarding by default on all ports */ -- mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK, -- PCR_MATRIX_CLR); -- -- /* Disable learning by default on all ports */ -- mt7530_set(priv, MT7530_PSC_P(i), SA_DIS); -- -- mt7530_set(priv, MT7531_DBG_CNT(i), MT7531_DIS_CLR); -- -- if (dsa_is_cpu_port(ds, i)) { -- ret = mt753x_cpu_port_enable(ds, i); -- if (ret) -- return ret; -- } else { -- mt7530_port_disable(ds, i); -- -- /* Set default PVID to 0 on all user ports */ -- mt7530_rmw(priv, MT7530_PPBV1_P(i), G0_PORT_VID_MASK, -- G0_PORT_VID_DEF); -- } -- -- /* Enable consistent egress tag */ -- mt7530_rmw(priv, MT7530_PVC_P(i), PVC_EG_TAG_MASK, -- PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT)); -- } -+ mt7531_setup_common(ds); - - /* Setup VLAN ID 0 for VLAN-unaware bridges */ - ret = mt7530_setup_vlan0(priv); -@@ -2473,11 +2489,6 @@ mt7531_setup(struct dsa_switch *ds) - ds->assisted_learning_on_cpu_port = true; - ds->mtu_enforcement_ingress = true; - -- /* Flush the FDB table */ -- ret = mt7530_fdb_cmd(priv, MT7530_FDB_FLUSH, NULL); -- if (ret < 0) -- return ret; -- - return 0; - } - diff --git a/target/linux/generic/backport-5.15/790-v6.4-0011-net-dsa-mt7530-introduce-separate-MDIO-driver.patch b/target/linux/generic/backport-5.15/790-v6.4-0011-net-dsa-mt7530-introduce-separate-MDIO-driver.patch index 96afa041aa..51346d0620 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0011-net-dsa-mt7530-introduce-separate-MDIO-driver.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0011-net-dsa-mt7530-introduce-separate-MDIO-driver.patch @@ -416,7 +416,7 @@ Signed-off-by: David S. Miller static u32 mt7530_mii_read(struct mt7530_priv *priv, u32 reg) { -@@ -2944,72 +2895,6 @@ static const struct phylink_pcs_ops mt75 +@@ -2948,72 +2899,6 @@ static const struct phylink_pcs_ops mt75 .pcs_an_restart = mt7530_pcs_an_restart, }; @@ -489,7 +489,7 @@ Signed-off-by: David S. Miller static int mt753x_setup(struct dsa_switch *ds) { -@@ -3068,7 +2953,7 @@ static int mt753x_set_mac_eee(struct dsa +@@ -3072,7 +2957,7 @@ static int mt753x_set_mac_eee(struct dsa return 0; } @@ -498,7 +498,7 @@ Signed-off-by: David S. Miller .get_tag_protocol = mtk_get_tag_protocol, .setup = mt753x_setup, .get_strings = mt7530_get_strings, -@@ -3102,8 +2987,9 @@ static const struct dsa_switch_ops mt753 +@@ -3106,8 +2991,9 @@ static const struct dsa_switch_ops mt753 .get_mac_eee = mt753x_get_mac_eee, .set_mac_eee = mt753x_set_mac_eee, }; @@ -509,7 +509,7 @@ Signed-off-by: David S. Miller [ID_MT7621] = { .id = ID_MT7621, .pcs_ops = &mt7530_pcs_ops, -@@ -3136,16 +3022,9 @@ static const struct mt753x_info mt753x_t +@@ -3140,16 +3026,9 @@ static const struct mt753x_info mt753x_t .mac_port_config = mt7531_mac_config, }, }; @@ -528,7 +528,7 @@ Signed-off-by: David S. Miller mt7530_probe_common(struct mt7530_priv *priv) { struct device *dev = priv->dev; -@@ -3182,88 +3061,9 @@ mt7530_probe_common(struct mt7530_priv * +@@ -3186,88 +3065,9 @@ mt7530_probe_common(struct mt7530_priv * return 0; } @@ -619,7 +619,7 @@ Signed-off-by: David S. Miller mt7530_remove_common(struct mt7530_priv *priv) { if (priv->irq) -@@ -3274,57 +3074,6 @@ mt7530_remove_common(struct mt7530_priv +@@ -3278,57 +3078,6 @@ mt7530_remove_common(struct mt7530_priv mutex_destroy(&priv->reg_mutex); } diff --git a/target/linux/generic/backport-5.15/790-v6.4-0013-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch b/target/linux/generic/backport-5.15/790-v6.4-0013-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch index 8210aae27c..00f4b25c44 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0013-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0013-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch @@ -250,7 +250,7 @@ Signed-off-by: David S. Miller if (!priv->irq_domain) { dev_err(dev, "failed to create IRQ domain\n"); return -ENOMEM; -@@ -2507,6 +2555,25 @@ static void mt7531_mac_port_get_caps(str +@@ -2511,6 +2559,25 @@ static void mt7531_mac_port_get_caps(str } } @@ -276,7 +276,7 @@ Signed-off-by: David S. Miller static int mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state) { -@@ -2583,6 +2650,17 @@ static bool mt753x_is_mac_port(u32 port) +@@ -2587,6 +2654,17 @@ static bool mt753x_is_mac_port(u32 port) } static int @@ -294,7 +294,7 @@ Signed-off-by: David S. Miller mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode, phy_interface_t interface) { -@@ -2652,7 +2730,8 @@ mt753x_phylink_mac_config(struct dsa_swi +@@ -2656,7 +2734,8 @@ mt753x_phylink_mac_config(struct dsa_swi switch (port) { case 0 ... 4: /* Internal phy */ @@ -304,7 +304,7 @@ Signed-off-by: David S. Miller goto unsupported; break; case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */ -@@ -2730,7 +2809,8 @@ static void mt753x_phylink_mac_link_up(s +@@ -2734,7 +2813,8 @@ static void mt753x_phylink_mac_link_up(s /* MT753x MAC works in 1G full duplex mode for all up-clocked * variants. */ @@ -314,7 +314,7 @@ Signed-off-by: David S. Miller (phy_interface_mode_is_8023z(interface))) { speed = SPEED_1000; duplex = DUPLEX_FULL; -@@ -2810,6 +2890,21 @@ mt7531_cpu_port_config(struct dsa_switch +@@ -2814,6 +2894,21 @@ mt7531_cpu_port_config(struct dsa_switch return 0; } @@ -336,7 +336,7 @@ Signed-off-by: David S. Miller static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port, struct phylink_config *config) { -@@ -2955,6 +3050,27 @@ static int mt753x_set_mac_eee(struct dsa +@@ -2959,6 +3054,27 @@ static int mt753x_set_mac_eee(struct dsa return 0; } @@ -364,7 +364,7 @@ Signed-off-by: David S. Miller const struct dsa_switch_ops mt7530_switch_ops = { .get_tag_protocol = mtk_get_tag_protocol, .setup = mt753x_setup, -@@ -3023,6 +3139,17 @@ const struct mt753x_info mt753x_table[] +@@ -3027,6 +3143,17 @@ const struct mt753x_info mt753x_table[] .mac_port_get_caps = mt7531_mac_port_get_caps, .mac_port_config = mt7531_mac_config, }, diff --git a/target/linux/generic/backport-5.15/790-v6.4-0014-net-dsa-mt7530-fix-support-for-MT7531BE.patch b/target/linux/generic/backport-5.15/790-v6.4-0014-net-dsa-mt7530-fix-support-for-MT7531BE.patch index 5259730996..ed8bca7d1c 100644 --- a/target/linux/generic/backport-5.15/790-v6.4-0014-net-dsa-mt7530-fix-support-for-MT7531BE.patch +++ b/target/linux/generic/backport-5.15/790-v6.4-0014-net-dsa-mt7530-fix-support-for-MT7531BE.patch @@ -73,7 +73,7 @@ Signed-off-by: Jakub Kicinski } --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -3017,6 +3017,12 @@ mt753x_setup(struct dsa_switch *ds) +@@ -3021,6 +3021,12 @@ mt753x_setup(struct dsa_switch *ds) if (ret && priv->irq) mt7530_free_irq_common(priv); diff --git a/target/linux/generic/pending-5.15/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch b/target/linux/generic/pending-5.15/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch index bd806a7a6d..a3274906a4 100644 --- a/target/linux/generic/pending-5.15/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch +++ b/target/linux/generic/pending-5.15/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch @@ -10,12 +10,21 @@ The datasheet [1] explicit describes it as requirement for a reset. Signed-off-by: Alexander Couzens --- - drivers/net/dsa/mt7530.c | 4 ++++ - 1 file changed, 4 insertions(+) + drivers/net/dsa/mt7530.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2440,6 +2440,10 @@ mt7531_setup(struct dsa_switch *ds) +@@ -2412,7 +2412,7 @@ mt7531_setup(struct dsa_switch *ds) + struct mt7530_priv *priv = ds->priv; + struct mt7530_dummy_poll p; + u32 val, id; +- int ret; ++ int ret, i; + + /* Reset whole chip through gpio pin or memory-mapped registers for + * different type of hardware +@@ -2444,6 +2444,10 @@ mt7531_setup(struct dsa_switch *ds) return -ENODEV; } From fc3383a55877150ffe8068c46fe61f6881b1033c Mon Sep 17 00:00:00 2001 From: John Audia Date: Sun, 11 Jun 2023 13:11:52 -0400 Subject: [PATCH 3/6] kernel: add CONFIG_DRM_RCAR_USE_LVDS is not set Added missing symbol. Signed-off-by: John Audia --- target/linux/generic/config-5.15 | 1 + 1 file changed, 1 insertion(+) diff --git a/target/linux/generic/config-5.15 b/target/linux/generic/config-5.15 index 5ca1ff0833..251a6fbcc3 100644 --- a/target/linux/generic/config-5.15 +++ b/target/linux/generic/config-5.15 @@ -1634,6 +1634,7 @@ CONFIG_DQL=y # CONFIG_DRM_RADEON_USERPTR is not set # CONFIG_DRM_RCAR_DW_HDMI is not set # CONFIG_DRM_RCAR_LVDS is not set +# CONFIG_DRM_RCAR_USE_LVDS is not set # CONFIG_DRM_ROCKCHIP is not set # CONFIG_DRM_SII902X is not set # CONFIG_DRM_SII9234 is not set From 5dc78d8f18e8f536317d9438b096a484a9c49862 Mon Sep 17 00:00:00 2001 From: John Audia Date: Sat, 10 Jun 2023 16:57:15 -0400 Subject: [PATCH 4/6] kernel: bump 5.15 to 5.15.116 All patches rebased automatically. Build system: x86_64 Build-tested: ramips/tplink_archer-a6-v3, filogic/xiaomi_redmi-router-ax6000-ubootmod Run-tested: ramips/tplink_archer-a6-v3, filogic/xiaomi_redmi-router-ax6000-ubootmod Signed-off-by: John Audia --- include/kernel-5.15 | 4 ++-- target/linux/ath25/patches-5.15/700-swconfig_mvswitch.patch | 2 +- .../ath79/patches-5.15/910-unaligned_access_hacks.patch | 2 +- ...18-regmap-add-configurable-downshift-for-addresses.patch | 4 ++-- ...gmap-allow-a-defined-reg_base-to-be-added-to-every.patch | 4 ++-- ...gmap-apply-reg_base-and-reg_downshift-for-single-r.patch | 4 ++-- ...t-dsa-provide-switch-operations-for-tracking-the-m.patch | 2 +- ...807-v6.1-0005-nvmem-prefix-all-symbols-with-NVMEM_.patch | 2 +- target/linux/generic/hack-5.15/259-regmap_dynamic.patch | 2 +- .../linux/generic/pending-5.15/630-packet_socket_type.patch | 6 +++--- .../710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch | 2 +- .../patches-5.15/810-uvc-add-iPassion-iP2970-support.patch | 2 +- 12 files changed, 18 insertions(+), 18 deletions(-) diff --git a/include/kernel-5.15 b/include/kernel-5.15 index b8b89583b4..6db270a374 100644 --- a/include/kernel-5.15 +++ b/include/kernel-5.15 @@ -1,2 +1,2 @@ -LINUX_VERSION-5.15 = .115 -LINUX_KERNEL_HASH-5.15.115 = 1b076860779235e90519e867c1ec78c7a34d1125d8fdba787ff495c7c14f1214 +LINUX_VERSION-5.15 = .116 +LINUX_KERNEL_HASH-5.15.116 = f617c9d1bb5326cc93495938f43eb8cb9aea9d2f451e5a99bce2893f296e179a diff --git a/target/linux/ath25/patches-5.15/700-swconfig_mvswitch.patch b/target/linux/ath25/patches-5.15/700-swconfig_mvswitch.patch index 79a4d1c1a0..dcfc019f12 100644 --- a/target/linux/ath25/patches-5.15/700-swconfig_mvswitch.patch +++ b/target/linux/ath25/patches-5.15/700-swconfig_mvswitch.patch @@ -1,6 +1,6 @@ --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig -@@ -95,6 +95,10 @@ config IP17XX_PHY +@@ -96,6 +96,10 @@ config IP17XX_PHY tristate "Driver for IC+ IP17xx switches" select SWCONFIG diff --git a/target/linux/ath79/patches-5.15/910-unaligned_access_hacks.patch b/target/linux/ath79/patches-5.15/910-unaligned_access_hacks.patch index 88693d5f1a..5c659b3d2c 100644 --- a/target/linux/ath79/patches-5.15/910-unaligned_access_hacks.patch +++ b/target/linux/ath79/patches-5.15/910-unaligned_access_hacks.patch @@ -336,7 +336,7 @@ SVN-Revision: 35130 #endif /* _LINUX_TYPES_H */ --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c -@@ -1475,8 +1475,8 @@ struct sk_buff *inet_gro_receive(struct +@@ -1477,8 +1477,8 @@ struct sk_buff *inet_gro_receive(struct if (unlikely(ip_fast_csum((u8 *)iph, 5))) goto out_unlock; diff --git a/target/linux/generic/backport-5.15/350-v5.18-regmap-add-configurable-downshift-for-addresses.patch b/target/linux/generic/backport-5.15/350-v5.18-regmap-add-configurable-downshift-for-addresses.patch index 99cd89ea00..690e85d34b 100644 --- a/target/linux/generic/backport-5.15/350-v5.18-regmap-add-configurable-downshift-for-addresses.patch +++ b/target/linux/generic/backport-5.15/350-v5.18-regmap-add-configurable-downshift-for-addresses.patch @@ -53,7 +53,7 @@ Signed-off-by: Mark Brown map->format.format_write(map, reg, val); trace_regmap_hw_write_start(map, reg, 1); -@@ -2346,6 +2349,7 @@ static int _regmap_raw_multi_reg_write(s +@@ -2348,6 +2351,7 @@ static int _regmap_raw_multi_reg_write(s unsigned int reg = regs[i].reg; unsigned int val = regs[i].def; trace_regmap_hw_write_start(map, reg, 1); @@ -61,7 +61,7 @@ Signed-off-by: Mark Brown map->format.format_reg(u8, reg, map->reg_shift); u8 += reg_bytes + pad_bytes; map->format.format_val(u8, val, 0); -@@ -2673,6 +2677,7 @@ static int _regmap_raw_read(struct regma +@@ -2675,6 +2679,7 @@ static int _regmap_raw_read(struct regma return ret; } diff --git a/target/linux/generic/backport-5.15/351-v5.18-regmap-allow-a-defined-reg_base-to-be-added-to-every.patch b/target/linux/generic/backport-5.15/351-v5.18-regmap-allow-a-defined-reg_base-to-be-added-to-every.patch index 0f32288fca..ffde9e5d0c 100644 --- a/target/linux/generic/backport-5.15/351-v5.18-regmap-allow-a-defined-reg_base-to-be-added-to-every.patch +++ b/target/linux/generic/backport-5.15/351-v5.18-regmap-allow-a-defined-reg_base-to-be-added-to-every.patch @@ -58,7 +58,7 @@ Signed-off-by: Mark Brown reg >>= map->format.reg_downshift; map->format.format_write(map, reg, val); -@@ -2349,6 +2353,7 @@ static int _regmap_raw_multi_reg_write(s +@@ -2351,6 +2355,7 @@ static int _regmap_raw_multi_reg_write(s unsigned int reg = regs[i].reg; unsigned int val = regs[i].def; trace_regmap_hw_write_start(map, reg, 1); @@ -66,7 +66,7 @@ Signed-off-by: Mark Brown reg >>= map->format.reg_downshift; map->format.format_reg(u8, reg, map->reg_shift); u8 += reg_bytes + pad_bytes; -@@ -2677,6 +2682,7 @@ static int _regmap_raw_read(struct regma +@@ -2679,6 +2684,7 @@ static int _regmap_raw_read(struct regma return ret; } diff --git a/target/linux/generic/backport-5.15/352-v6.3-regmap-apply-reg_base-and-reg_downshift-for-single-r.patch b/target/linux/generic/backport-5.15/352-v6.3-regmap-apply-reg_base-and-reg_downshift-for-single-r.patch index 804f68d23c..34b587f558 100644 --- a/target/linux/generic/backport-5.15/352-v6.3-regmap-apply-reg_base-and-reg_downshift-for-single-r.patch +++ b/target/linux/generic/backport-5.15/352-v6.3-regmap-apply-reg_base-and-reg_downshift-for-single-r.patch @@ -37,7 +37,7 @@ Signed-off-by: Mark Brown return map->bus->reg_write(map->bus_context, reg, val); } -@@ -2703,6 +2705,8 @@ static int _regmap_bus_reg_read(void *co +@@ -2705,6 +2707,8 @@ static int _regmap_bus_reg_read(void *co { struct regmap *map = context; @@ -46,7 +46,7 @@ Signed-off-by: Mark Brown return map->bus->reg_read(map->bus_context, reg, val); } -@@ -3078,6 +3082,8 @@ static int _regmap_update_bits(struct re +@@ -3080,6 +3084,8 @@ static int _regmap_update_bits(struct re *change = false; if (regmap_volatile(map, reg) && map->reg_update_bits) { diff --git a/target/linux/generic/backport-5.15/766-v5.18-01-net-dsa-provide-switch-operations-for-tracking-the-m.patch b/target/linux/generic/backport-5.15/766-v5.18-01-net-dsa-provide-switch-operations-for-tracking-the-m.patch index 79e8c1e4e2..bffdcb2881 100644 --- a/target/linux/generic/backport-5.15/766-v5.18-01-net-dsa-provide-switch-operations-for-tracking-the-m.patch +++ b/target/linux/generic/backport-5.15/766-v5.18-01-net-dsa-provide-switch-operations-for-tracking-the-m.patch @@ -68,7 +68,7 @@ Signed-off-by: David S. Miller static inline bool dsa_is_unused_port(struct dsa_switch *ds, int p) { return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_UNUSED; -@@ -977,6 +987,13 @@ struct dsa_switch_ops { +@@ -949,6 +959,13 @@ struct dsa_switch_ops { int (*tag_8021q_vlan_add)(struct dsa_switch *ds, int port, u16 vid, u16 flags); int (*tag_8021q_vlan_del)(struct dsa_switch *ds, int port, u16 vid); diff --git a/target/linux/generic/backport-5.15/807-v6.1-0005-nvmem-prefix-all-symbols-with-NVMEM_.patch b/target/linux/generic/backport-5.15/807-v6.1-0005-nvmem-prefix-all-symbols-with-NVMEM_.patch index ae02439bd7..4410fc4d61 100644 --- a/target/linux/generic/backport-5.15/807-v6.1-0005-nvmem-prefix-all-symbols-with-NVMEM_.patch +++ b/target/linux/generic/backport-5.15/807-v6.1-0005-nvmem-prefix-all-symbols-with-NVMEM_.patch @@ -28,7 +28,7 @@ Signed-off-by: Greg Kroah-Hartman --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig -@@ -1125,10 +1125,10 @@ CONFIG_TI_PIPE3=y +@@ -1124,10 +1124,10 @@ CONFIG_TI_PIPE3=y CONFIG_TWL4030_USB=m CONFIG_RAS=y CONFIG_NVMEM_IMX_OCOTP=y diff --git a/target/linux/generic/hack-5.15/259-regmap_dynamic.patch b/target/linux/generic/hack-5.15/259-regmap_dynamic.patch index 76a5ace6f3..e0820ccfc0 100644 --- a/target/linux/generic/hack-5.15/259-regmap_dynamic.patch +++ b/target/linux/generic/hack-5.15/259-regmap_dynamic.patch @@ -125,7 +125,7 @@ Signed-off-by: Felix Fietkau #include #include #include -@@ -3358,3 +3359,5 @@ static int __init regmap_initcall(void) +@@ -3360,3 +3361,5 @@ static int __init regmap_initcall(void) return 0; } postcore_initcall(regmap_initcall); diff --git a/target/linux/generic/pending-5.15/630-packet_socket_type.patch b/target/linux/generic/pending-5.15/630-packet_socket_type.patch index b95ceebac7..ee13ce2a5c 100644 --- a/target/linux/generic/pending-5.15/630-packet_socket_type.patch +++ b/target/linux/generic/pending-5.15/630-packet_socket_type.patch @@ -87,7 +87,7 @@ Signed-off-by: Felix Fietkau if (!net_eq(dev_net(dev), sock_net(sk))) goto drop; -@@ -3340,6 +3342,7 @@ static int packet_create(struct net *net +@@ -3342,6 +3344,7 @@ static int packet_create(struct net *net mutex_init(&po->pg_vec_lock); po->rollover = NULL; po->prot_hook.func = packet_rcv; @@ -95,7 +95,7 @@ Signed-off-by: Felix Fietkau if (sock->type == SOCK_PACKET) po->prot_hook.func = packet_rcv_spkt; -@@ -3977,6 +3980,16 @@ packet_setsockopt(struct socket *sock, i +@@ -3979,6 +3982,16 @@ packet_setsockopt(struct socket *sock, i WRITE_ONCE(po->xmit, val ? packet_direct_xmit : dev_queue_xmit); return 0; } @@ -112,7 +112,7 @@ Signed-off-by: Felix Fietkau default: return -ENOPROTOOPT; } -@@ -4033,6 +4046,13 @@ static int packet_getsockopt(struct sock +@@ -4035,6 +4048,13 @@ static int packet_getsockopt(struct sock case PACKET_VNET_HDR: val = po->has_vnet_hdr; break; diff --git a/target/linux/generic/pending-5.15/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch b/target/linux/generic/pending-5.15/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch index 2a2ca7f1fa..7e8ed5455d 100644 --- a/target/linux/generic/pending-5.15/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch +++ b/target/linux/generic/pending-5.15/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch @@ -161,7 +161,7 @@ Signed-off-by: Felix Fietkau struct rtnl_link { rtnl_doit_func doit; -@@ -4700,7 +4700,9 @@ int ndo_dflt_bridge_getlink(struct sk_bu +@@ -4706,7 +4706,9 @@ int ndo_dflt_bridge_getlink(struct sk_bu brport_nla_put_flag(skb, flags, mask, IFLA_BRPORT_MCAST_FLOOD, BR_MCAST_FLOOD) || brport_nla_put_flag(skb, flags, mask, diff --git a/target/linux/ramips/patches-5.15/810-uvc-add-iPassion-iP2970-support.patch b/target/linux/ramips/patches-5.15/810-uvc-add-iPassion-iP2970-support.patch index 2d56440610..88809ae68d 100644 --- a/target/linux/ramips/patches-5.15/810-uvc-add-iPassion-iP2970-support.patch +++ b/target/linux/ramips/patches-5.15/810-uvc-add-iPassion-iP2970-support.patch @@ -13,7 +13,7 @@ Signed-off-by: John Crispin --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c -@@ -3152,6 +3152,18 @@ static const struct usb_device_id uvc_id +@@ -3158,6 +3158,18 @@ static const struct usb_device_id uvc_id .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, From 92b8b18c2685e9e509d2b8b797de7e03424d17d1 Mon Sep 17 00:00:00 2001 From: Piotr Dymacz Date: Mon, 12 Jun 2023 21:22:52 +0200 Subject: [PATCH 5/6] CI: labeler: add sifiveu target Add support for 'sifiveu' target and its specific packages in labeler. Signed-off-by: Piotr Dymacz --- .github/labeler.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/labeler.yml b/.github/labeler.yml index 6303fdf7b7..6d53d58106 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -94,6 +94,10 @@ - "target/linux/rockchip/**" - "package/boot/arm-trusted-firmware-rockchip/**" - "package/boot/uboot-rockchip/**" +"target/sifiveu": + - "target/linux/sifiveu/**" + - "package/boot/uboot-sifiveu/**" + - "package/boot/opensbi/**" "target/sunxi": - "target/linux/sunxi/**" - "package/boot/arm-trusted-firmware-sunxi/**" From 244328b19c3943bb145b72f0d85062f535e56fbd Mon Sep 17 00:00:00 2001 From: Etienne Champetier Date: Sat, 10 Jun 2023 23:13:33 -0400 Subject: [PATCH 6/6] kernel: remove bridge offload hack This patch initially introduced in 94b4da9b4aaded6ed8a5bd93bf38a7c92753fe68 breaks mvebu devices when using vlan filtering with kernel 5.15 or 6.1, it was working ok in 5.10. With this patch, frame that should exit untagged from the switch exit tagged. Running 'tcpdump -Q out -evnnli eth1' (eth1 being the dsa interface) - with the hack, frame is sent directly to the destination port 4 with VID 2, so the switch leave the tag as instructed: 11:22:33:44:55:66 > 77:88:99:aa:bb:cc, Marvell EDSA ethertype 0xdada (Unknown), rsvd 0 0, mode From CPU, target dev 0, port 4, tagged, VID 2, FPri 0, ethertype ARP (0x0806), length 50: Ethernet (len 6), IPv4 (len 4), Request who-has 5.6.7.8 tell 1.2.3.4, length 28 - without the hack, frame is sent to the switch that performs the forwarding decision and untagging: 11:22:33:44:55:66 > 77:88:99:aa:bb:cc, Marvell EDSA ethertype 0xdada (Unknown), rsvd 0 0, mode Forward, dev 1, port 0, tagged, VID 2, FPri 0, ethertype ARP (0x0806), length 50: Ethernet (len 6), IPv4 (len 4), Request who-has 5.6.7.8 tell 1.2.3.4, length 28 Removing this patch makes my Turris Omnia usable with vlan filtering, ie wifi device can talk to wired device again. Using kernel 5.15 some broadcast/multicast traffic is still leaked (on a VLAN 2 access port I see tagged VLAN 3 frame), using kernel 6.1 fixes that. People needing the extra performance should try the bridger package. Acked-by: Felix Fietkau Signed-off-by: Etienne Champetier --- .../hack-5.15/600-bridge_offload.patch | 846 ------------------ .../generic/hack-6.1/600-bridge_offload.patch | 846 ------------------ 2 files changed, 1692 deletions(-) delete mode 100644 target/linux/generic/hack-5.15/600-bridge_offload.patch delete mode 100644 target/linux/generic/hack-6.1/600-bridge_offload.patch diff --git a/target/linux/generic/hack-5.15/600-bridge_offload.patch b/target/linux/generic/hack-5.15/600-bridge_offload.patch deleted file mode 100644 index 9d71a741b2..0000000000 --- a/target/linux/generic/hack-5.15/600-bridge_offload.patch +++ /dev/null @@ -1,846 +0,0 @@ -From 11c3fae5afa6cac444d12622e2cf5af60a99c1ef Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 13:43:15 +0200 -Subject: [PATCH] net/bridge: add bridge offload - ---- - include/linux/if_bridge.h | 1 + - net/bridge/Makefile | 2 +- - net/bridge/br.c | 8 + - net/bridge/br_device.c | 2 + - net/bridge/br_fdb.c | 5 + - net/bridge/br_forward.c | 3 + - net/bridge/br_if.c | 6 +- - net/bridge/br_input.c | 5 + - net/bridge/br_offload.c | 438 ++++++++++++++++++++++++++++++++ - net/bridge/br_private.h | 22 +- - net/bridge/br_private_offload.h | 23 ++ - net/bridge/br_stp.c | 3 + - net/bridge/br_sysfs_br.c | 35 +++ - net/bridge/br_sysfs_if.c | 2 + - net/bridge/br_vlan_tunnel.c | 3 + - 15 files changed, 555 insertions(+), 3 deletions(-) - create mode 100644 net/bridge/br_offload.c - create mode 100644 net/bridge/br_private_offload.h - ---- a/include/linux/if_bridge.h -+++ b/include/linux/if_bridge.h -@@ -59,6 +59,7 @@ struct br_ip_list { - #define BR_MRP_LOST_IN_CONT BIT(19) - #define BR_TX_FWD_OFFLOAD BIT(20) - #define BR_BPDU_FILTER BIT(21) -+#define BR_OFFLOAD BIT(22) - - #define BR_DEFAULT_AGEING_TIME (300 * HZ) - ---- a/net/bridge/Makefile -+++ b/net/bridge/Makefile -@@ -5,7 +5,7 @@ - - obj-$(CONFIG_BRIDGE) += bridge.o - --bridge-y := br.o br_device.o br_fdb.o br_forward.o br_if.o br_input.o \ -+bridge-y := br.o br_device.o br_fdb.o br_forward.o br_if.o br_input.o br_offload.o \ - br_ioctl.o br_stp.o br_stp_bpdu.o \ - br_stp_if.o br_stp_timer.o br_netlink.o \ - br_netlink_tunnel.o br_arp_nd_proxy.o ---- a/net/bridge/br.c -+++ b/net/bridge/br.c -@@ -18,6 +18,7 @@ - #include - - #include "br_private.h" -+#include "br_private_offload.h" - - /* - * Handle changes in state of network devices enslaved to a bridge. -@@ -381,6 +382,10 @@ static int __init br_init(void) - if (err) - goto err_out; - -+ err = br_offload_init(); -+ if (err) -+ goto err_out0; -+ - err = register_pernet_subsys(&br_net_ops); - if (err) - goto err_out1; -@@ -430,6 +435,8 @@ err_out3: - err_out2: - unregister_pernet_subsys(&br_net_ops); - err_out1: -+ br_offload_fini(); -+err_out0: - br_fdb_fini(); - err_out: - stp_proto_unregister(&br_stp_proto); -@@ -452,6 +459,7 @@ static void __exit br_deinit(void) - #if IS_ENABLED(CONFIG_ATM_LANE) - br_fdb_test_addr_hook = NULL; - #endif -+ br_offload_fini(); - br_fdb_fini(); - } - ---- a/net/bridge/br_device.c -+++ b/net/bridge/br_device.c -@@ -524,6 +524,8 @@ void br_dev_setup(struct net_device *dev - br->bridge_hello_time = br->hello_time = 2 * HZ; - br->bridge_forward_delay = br->forward_delay = 15 * HZ; - br->bridge_ageing_time = br->ageing_time = BR_DEFAULT_AGEING_TIME; -+ br->offload_cache_size = 128; -+ br->offload_cache_reserved = 8; - dev->max_mtu = ETH_MAX_MTU; - - br_netfilter_rtable_init(br); ---- a/net/bridge/br_fdb.c -+++ b/net/bridge/br_fdb.c -@@ -23,6 +23,7 @@ - #include - #include - #include "br_private.h" -+#include "br_private_offload.h" - - static const struct rhashtable_params br_fdb_rht_params = { - .head_offset = offsetof(struct net_bridge_fdb_entry, rhnode), -@@ -518,6 +519,8 @@ static struct net_bridge_fdb_entry *fdb_ - fdb->key.vlan_id = vid; - fdb->flags = flags; - fdb->updated = fdb->used = jiffies; -+ INIT_HLIST_HEAD(&fdb->offload_in); -+ INIT_HLIST_HEAD(&fdb->offload_out); - if (rhashtable_lookup_insert_fast(&br->fdb_hash_tbl, - &fdb->rhnode, - br_fdb_rht_params)) { -@@ -794,6 +797,8 @@ static void fdb_notify(struct net_bridge - struct sk_buff *skb; - int err = -ENOBUFS; - -+ br_offload_fdb_update(fdb); -+ - if (swdev_notify) - br_switchdev_fdb_notify(br, fdb, type); - ---- a/net/bridge/br_forward.c -+++ b/net/bridge/br_forward.c -@@ -16,6 +16,7 @@ - #include - #include - #include "br_private.h" -+#include "br_private_offload.h" - - /* Don't forward packets to originating port or forwarding disabled */ - static inline int should_deliver(const struct net_bridge_port *p, -@@ -32,6 +33,8 @@ static inline int should_deliver(const s - - int br_dev_queue_push_xmit(struct net *net, struct sock *sk, struct sk_buff *skb) - { -+ br_offload_output(skb); -+ - skb_push(skb, ETH_HLEN); - if (!is_skb_forwardable(skb->dev, skb)) - goto drop; ---- a/net/bridge/br_if.c -+++ b/net/bridge/br_if.c -@@ -25,6 +25,7 @@ - #include - - #include "br_private.h" -+#include "br_private_offload.h" - - /* - * Determine initial path cost based on speed. -@@ -428,7 +429,7 @@ static struct net_bridge_port *new_nbp(s - p->path_cost = port_cost(dev); - p->priority = 0x8000 >> BR_PORT_BITS; - p->port_no = index; -- p->flags = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD; -+ p->flags = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD | BR_OFFLOAD; - br_init_port(p); - br_set_state(p, BR_STATE_DISABLED); - br_stp_port_timer_init(p); -@@ -771,6 +772,9 @@ void br_port_flags_change(struct net_bri - - if (mask & BR_NEIGH_SUPPRESS) - br_recalculate_neigh_suppress_enabled(br); -+ -+ if (mask & BR_OFFLOAD) -+ br_offload_port_state(p); - } - - bool br_port_flag_is_set(const struct net_device *dev, unsigned long flag) ---- a/net/bridge/br_input.c -+++ b/net/bridge/br_input.c -@@ -22,6 +22,7 @@ - #include - #include "br_private.h" - #include "br_private_tunnel.h" -+#include "br_private_offload.h" - - static int - br_netif_receive_skb(struct net *net, struct sock *sk, struct sk_buff *skb) -@@ -171,6 +172,7 @@ int br_handle_frame_finish(struct net *n - dst->used = now; - br_forward(dst->dst, skb, local_rcv, false); - } else { -+ br_offload_skb_disable(skb); - if (!mcast_hit) - br_flood(br, skb, pkt_type, local_rcv, false); - else -@@ -304,6 +306,9 @@ static rx_handler_result_t br_handle_fra - memset(skb->cb, 0, sizeof(struct br_input_skb_cb)); - - p = br_port_get_rcu(skb->dev); -+ if (br_offload_input(p, skb)) -+ return RX_HANDLER_CONSUMED; -+ - if (p->flags & BR_VLAN_TUNNEL) - br_handle_ingress_vlan_tunnel(skb, p, nbp_vlan_group_rcu(p)); - ---- /dev/null -+++ b/net/bridge/br_offload.c -@@ -0,0 +1,438 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+#include -+#include -+#include "br_private.h" -+#include "br_private_offload.h" -+ -+static DEFINE_SPINLOCK(offload_lock); -+ -+struct bridge_flow_key { -+ u8 dest[ETH_ALEN]; -+ u8 src[ETH_ALEN]; -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ u16 vlan_tag; -+ bool vlan_present; -+#endif -+}; -+ -+struct bridge_flow { -+ struct net_bridge_port *port; -+ struct rhash_head node; -+ struct bridge_flow_key key; -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ bool vlan_out_present; -+ u16 vlan_out; -+#endif -+ -+ unsigned long used; -+ struct net_bridge_fdb_entry *fdb_in, *fdb_out; -+ struct hlist_node fdb_list_in, fdb_list_out; -+ -+ struct rcu_head rcu; -+}; -+ -+static const struct rhashtable_params flow_params = { -+ .automatic_shrinking = true, -+ .head_offset = offsetof(struct bridge_flow, node), -+ .key_len = sizeof(struct bridge_flow_key), -+ .key_offset = offsetof(struct bridge_flow, key), -+}; -+ -+static struct kmem_cache *offload_cache __read_mostly; -+ -+static void -+flow_rcu_free(struct rcu_head *head) -+{ -+ struct bridge_flow *flow; -+ -+ flow = container_of(head, struct bridge_flow, rcu); -+ kmem_cache_free(offload_cache, flow); -+} -+ -+static void -+__br_offload_flow_free(struct bridge_flow *flow) -+{ -+ flow->used = 0; -+ hlist_del(&flow->fdb_list_in); -+ hlist_del(&flow->fdb_list_out); -+ -+ call_rcu(&flow->rcu, flow_rcu_free); -+} -+ -+static void -+br_offload_flow_free(struct bridge_flow *flow) -+{ -+ if (rhashtable_remove_fast(&flow->port->offload.rht, &flow->node, -+ flow_params) != 0) -+ return; -+ -+ __br_offload_flow_free(flow); -+} -+ -+static bool -+br_offload_flow_fdb_refresh_time(struct bridge_flow *flow, -+ struct net_bridge_fdb_entry *fdb) -+{ -+ if (!time_after(flow->used, fdb->updated)) -+ return false; -+ -+ fdb->updated = flow->used; -+ -+ return true; -+} -+ -+ -+static void -+br_offload_flow_refresh_time(struct bridge_flow *flow) -+{ -+ br_offload_flow_fdb_refresh_time(flow, flow->fdb_in); -+ br_offload_flow_fdb_refresh_time(flow, flow->fdb_out); -+} -+ -+static void -+br_offload_destroy_cb(void *ptr, void *arg) -+{ -+ struct bridge_flow *flow = ptr; -+ -+ __br_offload_flow_free(flow); -+} -+ -+static bool -+br_offload_need_gc(struct net_bridge_port *p) -+{ -+ return (atomic_read(&p->offload.rht.nelems) + -+ p->br->offload_cache_reserved) >= p->br->offload_cache_size; -+} -+ -+static void -+br_offload_gc_work(struct work_struct *work) -+{ -+ struct rhashtable_iter hti; -+ struct net_bridge_port *p; -+ struct bridge_flow *gc_flow = NULL; -+ struct bridge_flow *flow; -+ unsigned long gc_used; -+ -+ p = container_of(work, struct net_bridge_port, offload.gc_work); -+ -+ if (!br_offload_need_gc(p)) -+ return; -+ -+ rhashtable_walk_enter(&p->offload.rht, &hti); -+ rhashtable_walk_start(&hti); -+ while ((flow = rhashtable_walk_next(&hti)) != NULL) { -+ unsigned long used; -+ -+ if (IS_ERR(flow)) -+ continue; -+ -+ used = READ_ONCE(flow->used); -+ if (!used) -+ continue; -+ -+ if (gc_flow && !time_before(used, gc_used)) -+ continue; -+ -+ gc_flow = flow; -+ gc_used = used; -+ } -+ rhashtable_walk_stop(&hti); -+ rhashtable_walk_exit(&hti); -+ -+ if (!gc_flow) -+ return; -+ -+ spin_lock_bh(&offload_lock); -+ if (br_offload_need_gc(p) && gc_flow && -+ gc_flow->used == gc_used) -+ br_offload_flow_free(gc_flow); -+ if (p->offload.enabled && br_offload_need_gc(p)) -+ queue_work(system_long_wq, work); -+ spin_unlock_bh(&offload_lock); -+ -+} -+ -+void br_offload_port_state(struct net_bridge_port *p) -+{ -+ struct net_bridge_port_offload *o = &p->offload; -+ bool enabled = true; -+ bool flush = false; -+ -+ if (p->state != BR_STATE_FORWARDING || -+ !(p->flags & BR_OFFLOAD)) -+ enabled = false; -+ -+ spin_lock_bh(&offload_lock); -+ if (o->enabled == enabled) -+ goto out; -+ -+ if (enabled) { -+ if (!o->gc_work.func) -+ INIT_WORK(&o->gc_work, br_offload_gc_work); -+ rhashtable_init(&o->rht, &flow_params); -+ } else { -+ flush = true; -+ rhashtable_free_and_destroy(&o->rht, br_offload_destroy_cb, o); -+ } -+ -+ o->enabled = enabled; -+ -+out: -+ spin_unlock_bh(&offload_lock); -+ -+ if (flush) -+ flush_work(&o->gc_work); -+} -+ -+void br_offload_fdb_update(const struct net_bridge_fdb_entry *fdb) -+{ -+ struct bridge_flow *f; -+ struct hlist_node *tmp; -+ -+ spin_lock_bh(&offload_lock); -+ -+ hlist_for_each_entry_safe(f, tmp, &fdb->offload_in, fdb_list_in) -+ br_offload_flow_free(f); -+ -+ hlist_for_each_entry_safe(f, tmp, &fdb->offload_out, fdb_list_out) -+ br_offload_flow_free(f); -+ -+ spin_unlock_bh(&offload_lock); -+} -+ -+static void -+br_offload_prepare_key(struct net_bridge_port *p, struct bridge_flow_key *key, -+ struct sk_buff *skb) -+{ -+ memset(key, 0, sizeof(*key)); -+ memcpy(key, eth_hdr(skb), 2 * ETH_ALEN); -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ if (!br_opt_get(p->br, BROPT_VLAN_ENABLED)) -+ return; -+ -+ if (!skb_vlan_tag_present(skb) || skb->vlan_proto != p->br->vlan_proto) -+ return; -+ -+ key->vlan_present = true; -+ key->vlan_tag = skb_vlan_tag_get_id(skb); -+#endif -+} -+ -+void br_offload_output(struct sk_buff *skb) -+{ -+ struct net_bridge_port_offload *o; -+ struct br_input_skb_cb *cb = (struct br_input_skb_cb *)skb->cb; -+ struct net_bridge_port *p, *inp; -+ struct net_device *dev; -+ struct net_bridge_fdb_entry *fdb_in, *fdb_out; -+ struct net_bridge_vlan_group *vg; -+ struct bridge_flow_key key; -+ struct bridge_flow *flow; -+ u16 vlan; -+ -+ if (!cb->offload) -+ return; -+ -+ rcu_read_lock(); -+ -+ p = br_port_get_rcu(skb->dev); -+ if (!p) -+ goto out; -+ -+ o = &p->offload; -+ if (!o->enabled) -+ goto out; -+ -+ if (atomic_read(&p->offload.rht.nelems) >= p->br->offload_cache_size) -+ goto out; -+ -+ dev = dev_get_by_index_rcu(dev_net(p->br->dev), cb->input_ifindex); -+ if (!dev) -+ goto out; -+ -+ inp = br_port_get_rcu(dev); -+ if (!inp) -+ goto out; -+ -+ vg = nbp_vlan_group_rcu(inp); -+ vlan = cb->input_vlan_present ? cb->input_vlan_tag : br_get_pvid(vg); -+ fdb_in = br_fdb_find_rcu(p->br, eth_hdr(skb)->h_source, vlan); -+ if (!fdb_in || !fdb_in->dst) -+ goto out; -+ -+ vg = nbp_vlan_group_rcu(p); -+ vlan = skb_vlan_tag_present(skb) ? skb_vlan_tag_get_id(skb) : br_get_pvid(vg); -+ fdb_out = br_fdb_find_rcu(p->br, eth_hdr(skb)->h_dest, vlan); -+ if (!fdb_out || !fdb_out->dst) -+ goto out; -+ -+ br_offload_prepare_key(p, &key, skb); -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ key.vlan_present = cb->input_vlan_present; -+ key.vlan_tag = cb->input_vlan_tag; -+#endif -+ -+ flow = kmem_cache_alloc(offload_cache, GFP_ATOMIC); -+ flow->port = inp; -+ memcpy(&flow->key, &key, sizeof(key)); -+ -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ flow->vlan_out_present = skb_vlan_tag_present(skb); -+ flow->vlan_out = skb_vlan_tag_get(skb); -+#endif -+ -+ flow->fdb_in = fdb_in; -+ flow->fdb_out = fdb_out; -+ flow->used = jiffies; -+ -+ spin_lock_bh(&offload_lock); -+ if (!o->enabled || -+ atomic_read(&p->offload.rht.nelems) >= p->br->offload_cache_size || -+ rhashtable_insert_fast(&inp->offload.rht, &flow->node, flow_params)) { -+ kmem_cache_free(offload_cache, flow); -+ goto out_unlock; -+ } -+ -+ hlist_add_head(&flow->fdb_list_in, &fdb_in->offload_in); -+ hlist_add_head(&flow->fdb_list_out, &fdb_out->offload_out); -+ -+ if (br_offload_need_gc(p)) -+ queue_work(system_long_wq, &p->offload.gc_work); -+ -+out_unlock: -+ spin_unlock_bh(&offload_lock); -+ -+out: -+ rcu_read_unlock(); -+} -+ -+bool br_offload_input(struct net_bridge_port *p, struct sk_buff *skb) -+{ -+ struct net_bridge_port_offload *o = &p->offload; -+ struct br_input_skb_cb *cb = (struct br_input_skb_cb *)skb->cb; -+ struct bridge_flow_key key; -+ struct net_bridge_port *dst; -+ struct bridge_flow *flow; -+ unsigned long now = jiffies; -+ bool ret = false; -+ -+ if (skb->len < sizeof(key)) -+ return false; -+ -+ if (!o->enabled) -+ return false; -+ -+ if (is_multicast_ether_addr(eth_hdr(skb)->h_dest)) -+ return false; -+ -+ br_offload_prepare_key(p, &key, skb); -+ -+ rcu_read_lock(); -+ flow = rhashtable_lookup(&o->rht, &key, flow_params); -+ if (!flow) { -+ cb->offload = 1; -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ cb->input_vlan_present = key.vlan_present != 0; -+ cb->input_vlan_tag = key.vlan_tag; -+#endif -+ cb->input_ifindex = p->dev->ifindex; -+ goto out; -+ } -+ -+ if (flow->fdb_in->dst != p) -+ goto out; -+ -+ dst = flow->fdb_out->dst; -+ if (!dst) -+ goto out; -+ -+ ret = true; -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ if (!flow->vlan_out_present && key.vlan_present) { -+ __vlan_hwaccel_clear_tag(skb); -+ } else if (flow->vlan_out_present) { -+ if (skb_vlan_tag_present(skb) && -+ skb->vlan_proto != p->br->vlan_proto) { -+ /* Protocol-mismatch, empty out vlan_tci for new tag */ -+ skb_push(skb, ETH_HLEN); -+ skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, -+ skb_vlan_tag_get(skb)); -+ if (unlikely(!skb)) -+ goto out; -+ -+ skb_pull(skb, ETH_HLEN); -+ skb_reset_mac_len(skb); -+ } -+ -+ __vlan_hwaccel_put_tag(skb, p->br->vlan_proto, -+ flow->vlan_out); -+ } -+#endif -+ -+ skb->dev = dst->dev; -+ skb_push(skb, ETH_HLEN); -+ -+ if (skb_warn_if_lro(skb) || !is_skb_forwardable(skb->dev, skb)) { -+ kfree_skb(skb); -+ goto out; -+ } -+ -+ if (now - flow->used >= HZ) { -+ flow->used = now; -+ br_offload_flow_refresh_time(flow); -+ } -+ -+ skb_forward_csum(skb); -+ dev_queue_xmit(skb); -+ -+out: -+ rcu_read_unlock(); -+ return ret; -+} -+ -+static void -+br_offload_check_gc(struct net_bridge *br) -+{ -+ struct net_bridge_port *p; -+ -+ spin_lock_bh(&br->lock); -+ list_for_each_entry(p, &br->port_list, list) -+ if (br_offload_need_gc(p)) -+ queue_work(system_long_wq, &p->offload.gc_work); -+ spin_unlock_bh(&br->lock); -+} -+ -+ -+int br_offload_set_cache_size(struct net_bridge *br, unsigned long val, -+ struct netlink_ext_ack *extack) -+{ -+ br->offload_cache_size = val; -+ br_offload_check_gc(br); -+ -+ return 0; -+} -+ -+int br_offload_set_cache_reserved(struct net_bridge *br, unsigned long val, -+ struct netlink_ext_ack *extack) -+{ -+ br->offload_cache_reserved = val; -+ br_offload_check_gc(br); -+ -+ return 0; -+} -+ -+int __init br_offload_init(void) -+{ -+ offload_cache = kmem_cache_create("bridge_offload_cache", -+ sizeof(struct bridge_flow), -+ 0, SLAB_HWCACHE_ALIGN, NULL); -+ if (!offload_cache) -+ return -ENOMEM; -+ -+ return 0; -+} -+ -+void br_offload_fini(void) -+{ -+ kmem_cache_destroy(offload_cache); -+} ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -268,7 +268,13 @@ struct net_bridge_fdb_entry { - unsigned long updated ____cacheline_aligned_in_smp; - unsigned long used; - -- struct rcu_head rcu; -+ union { -+ struct { -+ struct hlist_head offload_in; -+ struct hlist_head offload_out; -+ }; -+ struct rcu_head rcu; -+ }; - }; - - #define MDB_PG_FLAGS_PERMANENT BIT(0) -@@ -343,6 +349,12 @@ struct net_bridge_mdb_entry { - struct rcu_head rcu; - }; - -+struct net_bridge_port_offload { -+ struct rhashtable rht; -+ struct work_struct gc_work; -+ bool enabled; -+}; -+ - struct net_bridge_port { - struct net_bridge *br; - struct net_device *dev; -@@ -403,6 +415,7 @@ struct net_bridge_port { - u16 backup_redirected_cnt; - - struct bridge_stp_xstats stp_xstats; -+ struct net_bridge_port_offload offload; - }; - - #define kobj_to_brport(obj) container_of(obj, struct net_bridge_port, kobj) -@@ -519,6 +532,9 @@ struct net_bridge { - struct kobject *ifobj; - u32 auto_cnt; - -+ u32 offload_cache_size; -+ u32 offload_cache_reserved; -+ - #ifdef CONFIG_NET_SWITCHDEV - /* Counter used to make sure that hardware domains get unique - * identifiers in case a bridge spans multiple switchdev instances. -@@ -553,6 +569,10 @@ struct br_input_skb_cb { - #ifdef CONFIG_NETFILTER_FAMILY_BRIDGE - u8 br_netfilter_broute:1; - #endif -+ u8 offload:1; -+ u8 input_vlan_present:1; -+ u16 input_vlan_tag; -+ int input_ifindex; - - #ifdef CONFIG_NET_SWITCHDEV - /* Set if TX data plane offloading is used towards at least one ---- /dev/null -+++ b/net/bridge/br_private_offload.h -@@ -0,0 +1,23 @@ -+#ifndef __BR_OFFLOAD_H -+#define __BR_OFFLOAD_H -+ -+bool br_offload_input(struct net_bridge_port *p, struct sk_buff *skb); -+void br_offload_output(struct sk_buff *skb); -+void br_offload_port_state(struct net_bridge_port *p); -+void br_offload_fdb_update(const struct net_bridge_fdb_entry *fdb); -+int br_offload_init(void); -+void br_offload_fini(void); -+int br_offload_set_cache_size(struct net_bridge *br, unsigned long val, -+ struct netlink_ext_ack *extack); -+int br_offload_set_cache_reserved(struct net_bridge *br, unsigned long val, -+ struct netlink_ext_ack *extack); -+ -+static inline void br_offload_skb_disable(struct sk_buff *skb) -+{ -+ struct br_input_skb_cb *cb = (struct br_input_skb_cb *)skb->cb; -+ -+ if (cb->offload) -+ cb->offload = 0; -+} -+ -+#endif ---- a/net/bridge/br_stp.c -+++ b/net/bridge/br_stp.c -@@ -12,6 +12,7 @@ - - #include "br_private.h" - #include "br_private_stp.h" -+#include "br_private_offload.h" - - /* since time values in bpdu are in jiffies and then scaled (1/256) - * before sending, make sure that is at least one STP tick. -@@ -52,6 +53,8 @@ void br_set_state(struct net_bridge_port - (unsigned int) p->port_no, p->dev->name, - br_port_state_names[p->state]); - -+ br_offload_port_state(p); -+ - if (p->br->stp_enabled == BR_KERNEL_STP) { - switch (p->state) { - case BR_STATE_BLOCKING: ---- a/net/bridge/br_sysfs_br.c -+++ b/net/bridge/br_sysfs_br.c -@@ -18,6 +18,7 @@ - #include - - #include "br_private.h" -+#include "br_private_offload.h" - - /* IMPORTANT: new bridge options must be added with netlink support only - * please do not add new sysfs entries -@@ -930,6 +931,38 @@ static ssize_t vlan_stats_per_port_store - static DEVICE_ATTR_RW(vlan_stats_per_port); - #endif - -+static ssize_t offload_cache_size_show(struct device *d, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct net_bridge *br = to_bridge(d); -+ return sprintf(buf, "%u\n", br->offload_cache_size); -+} -+ -+static ssize_t offload_cache_size_store(struct device *d, -+ struct device_attribute *attr, -+ const char *buf, size_t len) -+{ -+ return store_bridge_parm(d, buf, len, br_offload_set_cache_size); -+} -+static DEVICE_ATTR_RW(offload_cache_size); -+ -+static ssize_t offload_cache_reserved_show(struct device *d, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct net_bridge *br = to_bridge(d); -+ return sprintf(buf, "%u\n", br->offload_cache_reserved); -+} -+ -+static ssize_t offload_cache_reserved_store(struct device *d, -+ struct device_attribute *attr, -+ const char *buf, size_t len) -+{ -+ return store_bridge_parm(d, buf, len, br_offload_set_cache_reserved); -+} -+static DEVICE_ATTR_RW(offload_cache_reserved); -+ - static struct attribute *bridge_attrs[] = { - &dev_attr_forward_delay.attr, - &dev_attr_hello_time.attr, -@@ -984,6 +1017,8 @@ static struct attribute *bridge_attrs[] - &dev_attr_vlan_stats_enabled.attr, - &dev_attr_vlan_stats_per_port.attr, - #endif -+ &dev_attr_offload_cache_size.attr, -+ &dev_attr_offload_cache_reserved.attr, - NULL - }; - ---- a/net/bridge/br_sysfs_if.c -+++ b/net/bridge/br_sysfs_if.c -@@ -241,6 +241,7 @@ BRPORT_ATTR_FLAG(broadcast_flood, BR_BCA - BRPORT_ATTR_FLAG(neigh_suppress, BR_NEIGH_SUPPRESS); - BRPORT_ATTR_FLAG(isolated, BR_ISOLATED); - BRPORT_ATTR_FLAG(bpdu_filter, BR_BPDU_FILTER); -+BRPORT_ATTR_FLAG(offload, BR_OFFLOAD); - - #ifdef CONFIG_BRIDGE_IGMP_SNOOPING - static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf) -@@ -295,6 +296,7 @@ static const struct brport_attribute *br - &brport_attr_isolated, - &brport_attr_bpdu_filter, - &brport_attr_backup_port, -+ &brport_attr_offload, - NULL - }; - ---- a/net/bridge/br_vlan_tunnel.c -+++ b/net/bridge/br_vlan_tunnel.c -@@ -15,6 +15,7 @@ - - #include "br_private.h" - #include "br_private_tunnel.h" -+#include "br_private_offload.h" - - static inline int br_vlan_tunid_cmp(struct rhashtable_compare_arg *arg, - const void *ptr) -@@ -180,6 +181,7 @@ void br_handle_ingress_vlan_tunnel(struc - skb_dst_drop(skb); - - __vlan_hwaccel_put_tag(skb, p->br->vlan_proto, vlan->vid); -+ br_offload_skb_disable(skb); - } - - int br_handle_egress_vlan_tunnel(struct sk_buff *skb, -@@ -201,6 +203,7 @@ int br_handle_egress_vlan_tunnel(struct - if (err) - return err; - -+ br_offload_skb_disable(skb); - tunnel_dst = rcu_dereference(vlan->tinfo.tunnel_dst); - if (tunnel_dst && dst_hold_safe(&tunnel_dst->dst)) - skb_dst_set(skb, &tunnel_dst->dst); diff --git a/target/linux/generic/hack-6.1/600-bridge_offload.patch b/target/linux/generic/hack-6.1/600-bridge_offload.patch deleted file mode 100644 index aa78c96e7f..0000000000 --- a/target/linux/generic/hack-6.1/600-bridge_offload.patch +++ /dev/null @@ -1,846 +0,0 @@ -From 11c3fae5afa6cac444d12622e2cf5af60a99c1ef Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 13:43:15 +0200 -Subject: [PATCH] net/bridge: add bridge offload - ---- - include/linux/if_bridge.h | 1 + - net/bridge/Makefile | 2 +- - net/bridge/br.c | 8 + - net/bridge/br_device.c | 2 + - net/bridge/br_fdb.c | 5 + - net/bridge/br_forward.c | 3 + - net/bridge/br_if.c | 6 +- - net/bridge/br_input.c | 5 + - net/bridge/br_offload.c | 438 ++++++++++++++++++++++++++++++++ - net/bridge/br_private.h | 22 +- - net/bridge/br_private_offload.h | 23 ++ - net/bridge/br_stp.c | 3 + - net/bridge/br_sysfs_br.c | 35 +++ - net/bridge/br_sysfs_if.c | 2 + - net/bridge/br_vlan_tunnel.c | 3 + - 15 files changed, 555 insertions(+), 3 deletions(-) - create mode 100644 net/bridge/br_offload.c - create mode 100644 net/bridge/br_private_offload.h - ---- a/include/linux/if_bridge.h -+++ b/include/linux/if_bridge.h -@@ -60,6 +60,7 @@ struct br_ip_list { - #define BR_TX_FWD_OFFLOAD BIT(20) - #define BR_PORT_LOCKED BIT(21) - #define BR_BPDU_FILTER BIT(22) -+#define BR_OFFLOAD BIT(23) - - #define BR_DEFAULT_AGEING_TIME (300 * HZ) - ---- a/net/bridge/Makefile -+++ b/net/bridge/Makefile -@@ -5,7 +5,7 @@ - - obj-$(CONFIG_BRIDGE) += bridge.o - --bridge-y := br.o br_device.o br_fdb.o br_forward.o br_if.o br_input.o \ -+bridge-y := br.o br_device.o br_fdb.o br_forward.o br_if.o br_input.o br_offload.o \ - br_ioctl.o br_stp.o br_stp_bpdu.o \ - br_stp_if.o br_stp_timer.o br_netlink.o \ - br_netlink_tunnel.o br_arp_nd_proxy.o ---- a/net/bridge/br.c -+++ b/net/bridge/br.c -@@ -18,6 +18,7 @@ - #include - - #include "br_private.h" -+#include "br_private_offload.h" - - /* - * Handle changes in state of network devices enslaved to a bridge. -@@ -389,6 +390,10 @@ static int __init br_init(void) - if (err) - goto err_out; - -+ err = br_offload_init(); -+ if (err) -+ goto err_out0; -+ - err = register_pernet_subsys(&br_net_ops); - if (err) - goto err_out1; -@@ -438,6 +443,8 @@ err_out3: - err_out2: - unregister_pernet_subsys(&br_net_ops); - err_out1: -+ br_offload_fini(); -+err_out0: - br_fdb_fini(); - err_out: - stp_proto_unregister(&br_stp_proto); -@@ -460,6 +467,7 @@ static void __exit br_deinit(void) - #if IS_ENABLED(CONFIG_ATM_LANE) - br_fdb_test_addr_hook = NULL; - #endif -+ br_offload_fini(); - br_fdb_fini(); - } - ---- a/net/bridge/br_device.c -+++ b/net/bridge/br_device.c -@@ -525,6 +525,8 @@ void br_dev_setup(struct net_device *dev - br->bridge_hello_time = br->hello_time = 2 * HZ; - br->bridge_forward_delay = br->forward_delay = 15 * HZ; - br->bridge_ageing_time = br->ageing_time = BR_DEFAULT_AGEING_TIME; -+ br->offload_cache_size = 128; -+ br->offload_cache_reserved = 8; - dev->max_mtu = ETH_MAX_MTU; - - br_netfilter_rtable_init(br); ---- a/net/bridge/br_fdb.c -+++ b/net/bridge/br_fdb.c -@@ -23,6 +23,7 @@ - #include - #include - #include "br_private.h" -+#include "br_private_offload.h" - - static const struct rhashtable_params br_fdb_rht_params = { - .head_offset = offsetof(struct net_bridge_fdb_entry, rhnode), -@@ -185,6 +186,8 @@ static void fdb_notify(struct net_bridge - struct sk_buff *skb; - int err = -ENOBUFS; - -+ br_offload_fdb_update(fdb); -+ - if (swdev_notify) - br_switchdev_fdb_notify(br, fdb, type); - -@@ -393,6 +396,8 @@ static struct net_bridge_fdb_entry *fdb_ - fdb->key.vlan_id = vid; - fdb->flags = flags; - fdb->updated = fdb->used = jiffies; -+ INIT_HLIST_HEAD(&fdb->offload_in); -+ INIT_HLIST_HEAD(&fdb->offload_out); - err = rhashtable_lookup_insert_fast(&br->fdb_hash_tbl, &fdb->rhnode, - br_fdb_rht_params); - if (err) { ---- a/net/bridge/br_forward.c -+++ b/net/bridge/br_forward.c -@@ -16,6 +16,7 @@ - #include - #include - #include "br_private.h" -+#include "br_private_offload.h" - - /* Don't forward packets to originating port or forwarding disabled */ - static inline int should_deliver(const struct net_bridge_port *p, -@@ -32,6 +33,8 @@ static inline int should_deliver(const s - - int br_dev_queue_push_xmit(struct net *net, struct sock *sk, struct sk_buff *skb) - { -+ br_offload_output(skb); -+ - skb_push(skb, ETH_HLEN); - if (!is_skb_forwardable(skb->dev, skb)) - goto drop; ---- a/net/bridge/br_if.c -+++ b/net/bridge/br_if.c -@@ -25,6 +25,7 @@ - #include - - #include "br_private.h" -+#include "br_private_offload.h" - - /* - * Determine initial path cost based on speed. -@@ -437,7 +438,7 @@ static struct net_bridge_port *new_nbp(s - p->path_cost = port_cost(dev); - p->priority = 0x8000 >> BR_PORT_BITS; - p->port_no = index; -- p->flags = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD; -+ p->flags = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD | BR_OFFLOAD; - br_init_port(p); - br_set_state(p, BR_STATE_DISABLED); - br_stp_port_timer_init(p); -@@ -761,6 +762,9 @@ void br_port_flags_change(struct net_bri - - if (mask & BR_NEIGH_SUPPRESS) - br_recalculate_neigh_suppress_enabled(br); -+ -+ if (mask & BR_OFFLOAD) -+ br_offload_port_state(p); - } - - bool br_port_flag_is_set(const struct net_device *dev, unsigned long flag) ---- a/net/bridge/br_input.c -+++ b/net/bridge/br_input.c -@@ -22,6 +22,7 @@ - #include - #include "br_private.h" - #include "br_private_tunnel.h" -+#include "br_private_offload.h" - - static int - br_netif_receive_skb(struct net *net, struct sock *sk, struct sk_buff *skb) -@@ -189,6 +190,7 @@ int br_handle_frame_finish(struct net *n - dst->used = now; - br_forward(dst->dst, skb, local_rcv, false); - } else { -+ br_offload_skb_disable(skb); - if (!mcast_hit) - br_flood(br, skb, pkt_type, local_rcv, false); - else -@@ -322,6 +324,9 @@ static rx_handler_result_t br_handle_fra - memset(skb->cb, 0, sizeof(struct br_input_skb_cb)); - - p = br_port_get_rcu(skb->dev); -+ if (br_offload_input(p, skb)) -+ return RX_HANDLER_CONSUMED; -+ - if (p->flags & BR_VLAN_TUNNEL) - br_handle_ingress_vlan_tunnel(skb, p, nbp_vlan_group_rcu(p)); - ---- /dev/null -+++ b/net/bridge/br_offload.c -@@ -0,0 +1,438 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+#include -+#include -+#include "br_private.h" -+#include "br_private_offload.h" -+ -+static DEFINE_SPINLOCK(offload_lock); -+ -+struct bridge_flow_key { -+ u8 dest[ETH_ALEN]; -+ u8 src[ETH_ALEN]; -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ u16 vlan_tag; -+ bool vlan_present; -+#endif -+}; -+ -+struct bridge_flow { -+ struct net_bridge_port *port; -+ struct rhash_head node; -+ struct bridge_flow_key key; -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ bool vlan_out_present; -+ u16 vlan_out; -+#endif -+ -+ unsigned long used; -+ struct net_bridge_fdb_entry *fdb_in, *fdb_out; -+ struct hlist_node fdb_list_in, fdb_list_out; -+ -+ struct rcu_head rcu; -+}; -+ -+static const struct rhashtable_params flow_params = { -+ .automatic_shrinking = true, -+ .head_offset = offsetof(struct bridge_flow, node), -+ .key_len = sizeof(struct bridge_flow_key), -+ .key_offset = offsetof(struct bridge_flow, key), -+}; -+ -+static struct kmem_cache *offload_cache __read_mostly; -+ -+static void -+flow_rcu_free(struct rcu_head *head) -+{ -+ struct bridge_flow *flow; -+ -+ flow = container_of(head, struct bridge_flow, rcu); -+ kmem_cache_free(offload_cache, flow); -+} -+ -+static void -+__br_offload_flow_free(struct bridge_flow *flow) -+{ -+ flow->used = 0; -+ hlist_del(&flow->fdb_list_in); -+ hlist_del(&flow->fdb_list_out); -+ -+ call_rcu(&flow->rcu, flow_rcu_free); -+} -+ -+static void -+br_offload_flow_free(struct bridge_flow *flow) -+{ -+ if (rhashtable_remove_fast(&flow->port->offload.rht, &flow->node, -+ flow_params) != 0) -+ return; -+ -+ __br_offload_flow_free(flow); -+} -+ -+static bool -+br_offload_flow_fdb_refresh_time(struct bridge_flow *flow, -+ struct net_bridge_fdb_entry *fdb) -+{ -+ if (!time_after(flow->used, fdb->updated)) -+ return false; -+ -+ fdb->updated = flow->used; -+ -+ return true; -+} -+ -+ -+static void -+br_offload_flow_refresh_time(struct bridge_flow *flow) -+{ -+ br_offload_flow_fdb_refresh_time(flow, flow->fdb_in); -+ br_offload_flow_fdb_refresh_time(flow, flow->fdb_out); -+} -+ -+static void -+br_offload_destroy_cb(void *ptr, void *arg) -+{ -+ struct bridge_flow *flow = ptr; -+ -+ __br_offload_flow_free(flow); -+} -+ -+static bool -+br_offload_need_gc(struct net_bridge_port *p) -+{ -+ return (atomic_read(&p->offload.rht.nelems) + -+ p->br->offload_cache_reserved) >= p->br->offload_cache_size; -+} -+ -+static void -+br_offload_gc_work(struct work_struct *work) -+{ -+ struct rhashtable_iter hti; -+ struct net_bridge_port *p; -+ struct bridge_flow *gc_flow = NULL; -+ struct bridge_flow *flow; -+ unsigned long gc_used; -+ -+ p = container_of(work, struct net_bridge_port, offload.gc_work); -+ -+ if (!br_offload_need_gc(p)) -+ return; -+ -+ rhashtable_walk_enter(&p->offload.rht, &hti); -+ rhashtable_walk_start(&hti); -+ while ((flow = rhashtable_walk_next(&hti)) != NULL) { -+ unsigned long used; -+ -+ if (IS_ERR(flow)) -+ continue; -+ -+ used = READ_ONCE(flow->used); -+ if (!used) -+ continue; -+ -+ if (gc_flow && !time_before(used, gc_used)) -+ continue; -+ -+ gc_flow = flow; -+ gc_used = used; -+ } -+ rhashtable_walk_stop(&hti); -+ rhashtable_walk_exit(&hti); -+ -+ if (!gc_flow) -+ return; -+ -+ spin_lock_bh(&offload_lock); -+ if (br_offload_need_gc(p) && gc_flow && -+ gc_flow->used == gc_used) -+ br_offload_flow_free(gc_flow); -+ if (p->offload.enabled && br_offload_need_gc(p)) -+ queue_work(system_long_wq, work); -+ spin_unlock_bh(&offload_lock); -+ -+} -+ -+void br_offload_port_state(struct net_bridge_port *p) -+{ -+ struct net_bridge_port_offload *o = &p->offload; -+ bool enabled = true; -+ bool flush = false; -+ -+ if (p->state != BR_STATE_FORWARDING || -+ !(p->flags & BR_OFFLOAD)) -+ enabled = false; -+ -+ spin_lock_bh(&offload_lock); -+ if (o->enabled == enabled) -+ goto out; -+ -+ if (enabled) { -+ if (!o->gc_work.func) -+ INIT_WORK(&o->gc_work, br_offload_gc_work); -+ rhashtable_init(&o->rht, &flow_params); -+ } else { -+ flush = true; -+ rhashtable_free_and_destroy(&o->rht, br_offload_destroy_cb, o); -+ } -+ -+ o->enabled = enabled; -+ -+out: -+ spin_unlock_bh(&offload_lock); -+ -+ if (flush) -+ flush_work(&o->gc_work); -+} -+ -+void br_offload_fdb_update(const struct net_bridge_fdb_entry *fdb) -+{ -+ struct bridge_flow *f; -+ struct hlist_node *tmp; -+ -+ spin_lock_bh(&offload_lock); -+ -+ hlist_for_each_entry_safe(f, tmp, &fdb->offload_in, fdb_list_in) -+ br_offload_flow_free(f); -+ -+ hlist_for_each_entry_safe(f, tmp, &fdb->offload_out, fdb_list_out) -+ br_offload_flow_free(f); -+ -+ spin_unlock_bh(&offload_lock); -+} -+ -+static void -+br_offload_prepare_key(struct net_bridge_port *p, struct bridge_flow_key *key, -+ struct sk_buff *skb) -+{ -+ memset(key, 0, sizeof(*key)); -+ memcpy(key, eth_hdr(skb), 2 * ETH_ALEN); -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ if (!br_opt_get(p->br, BROPT_VLAN_ENABLED)) -+ return; -+ -+ if (!skb_vlan_tag_present(skb) || skb->vlan_proto != p->br->vlan_proto) -+ return; -+ -+ key->vlan_present = true; -+ key->vlan_tag = skb_vlan_tag_get_id(skb); -+#endif -+} -+ -+void br_offload_output(struct sk_buff *skb) -+{ -+ struct net_bridge_port_offload *o; -+ struct br_input_skb_cb *cb = (struct br_input_skb_cb *)skb->cb; -+ struct net_bridge_port *p, *inp; -+ struct net_device *dev; -+ struct net_bridge_fdb_entry *fdb_in, *fdb_out; -+ struct net_bridge_vlan_group *vg; -+ struct bridge_flow_key key; -+ struct bridge_flow *flow; -+ u16 vlan; -+ -+ if (!cb->offload) -+ return; -+ -+ rcu_read_lock(); -+ -+ p = br_port_get_rcu(skb->dev); -+ if (!p) -+ goto out; -+ -+ o = &p->offload; -+ if (!o->enabled) -+ goto out; -+ -+ if (atomic_read(&p->offload.rht.nelems) >= p->br->offload_cache_size) -+ goto out; -+ -+ dev = dev_get_by_index_rcu(dev_net(p->br->dev), cb->input_ifindex); -+ if (!dev) -+ goto out; -+ -+ inp = br_port_get_rcu(dev); -+ if (!inp) -+ goto out; -+ -+ vg = nbp_vlan_group_rcu(inp); -+ vlan = cb->input_vlan_present ? cb->input_vlan_tag : br_get_pvid(vg); -+ fdb_in = br_fdb_find_rcu(p->br, eth_hdr(skb)->h_source, vlan); -+ if (!fdb_in || !fdb_in->dst) -+ goto out; -+ -+ vg = nbp_vlan_group_rcu(p); -+ vlan = skb_vlan_tag_present(skb) ? skb_vlan_tag_get_id(skb) : br_get_pvid(vg); -+ fdb_out = br_fdb_find_rcu(p->br, eth_hdr(skb)->h_dest, vlan); -+ if (!fdb_out || !fdb_out->dst) -+ goto out; -+ -+ br_offload_prepare_key(p, &key, skb); -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ key.vlan_present = cb->input_vlan_present; -+ key.vlan_tag = cb->input_vlan_tag; -+#endif -+ -+ flow = kmem_cache_alloc(offload_cache, GFP_ATOMIC); -+ flow->port = inp; -+ memcpy(&flow->key, &key, sizeof(key)); -+ -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ flow->vlan_out_present = skb_vlan_tag_present(skb); -+ flow->vlan_out = skb_vlan_tag_get(skb); -+#endif -+ -+ flow->fdb_in = fdb_in; -+ flow->fdb_out = fdb_out; -+ flow->used = jiffies; -+ -+ spin_lock_bh(&offload_lock); -+ if (!o->enabled || -+ atomic_read(&p->offload.rht.nelems) >= p->br->offload_cache_size || -+ rhashtable_insert_fast(&inp->offload.rht, &flow->node, flow_params)) { -+ kmem_cache_free(offload_cache, flow); -+ goto out_unlock; -+ } -+ -+ hlist_add_head(&flow->fdb_list_in, &fdb_in->offload_in); -+ hlist_add_head(&flow->fdb_list_out, &fdb_out->offload_out); -+ -+ if (br_offload_need_gc(p)) -+ queue_work(system_long_wq, &p->offload.gc_work); -+ -+out_unlock: -+ spin_unlock_bh(&offload_lock); -+ -+out: -+ rcu_read_unlock(); -+} -+ -+bool br_offload_input(struct net_bridge_port *p, struct sk_buff *skb) -+{ -+ struct net_bridge_port_offload *o = &p->offload; -+ struct br_input_skb_cb *cb = (struct br_input_skb_cb *)skb->cb; -+ struct bridge_flow_key key; -+ struct net_bridge_port *dst; -+ struct bridge_flow *flow; -+ unsigned long now = jiffies; -+ bool ret = false; -+ -+ if (skb->len < sizeof(key)) -+ return false; -+ -+ if (!o->enabled) -+ return false; -+ -+ if (is_multicast_ether_addr(eth_hdr(skb)->h_dest)) -+ return false; -+ -+ br_offload_prepare_key(p, &key, skb); -+ -+ rcu_read_lock(); -+ flow = rhashtable_lookup(&o->rht, &key, flow_params); -+ if (!flow) { -+ cb->offload = 1; -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ cb->input_vlan_present = key.vlan_present != 0; -+ cb->input_vlan_tag = key.vlan_tag; -+#endif -+ cb->input_ifindex = p->dev->ifindex; -+ goto out; -+ } -+ -+ if (flow->fdb_in->dst != p) -+ goto out; -+ -+ dst = flow->fdb_out->dst; -+ if (!dst) -+ goto out; -+ -+ ret = true; -+#ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ if (!flow->vlan_out_present && key.vlan_present) { -+ __vlan_hwaccel_clear_tag(skb); -+ } else if (flow->vlan_out_present) { -+ if (skb_vlan_tag_present(skb) && -+ skb->vlan_proto != p->br->vlan_proto) { -+ /* Protocol-mismatch, empty out vlan_tci for new tag */ -+ skb_push(skb, ETH_HLEN); -+ skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, -+ skb_vlan_tag_get(skb)); -+ if (unlikely(!skb)) -+ goto out; -+ -+ skb_pull(skb, ETH_HLEN); -+ skb_reset_mac_len(skb); -+ } -+ -+ __vlan_hwaccel_put_tag(skb, p->br->vlan_proto, -+ flow->vlan_out); -+ } -+#endif -+ -+ skb->dev = dst->dev; -+ skb_push(skb, ETH_HLEN); -+ -+ if (skb_warn_if_lro(skb) || !is_skb_forwardable(skb->dev, skb)) { -+ kfree_skb(skb); -+ goto out; -+ } -+ -+ if (now - flow->used >= HZ) { -+ flow->used = now; -+ br_offload_flow_refresh_time(flow); -+ } -+ -+ skb_forward_csum(skb); -+ dev_queue_xmit(skb); -+ -+out: -+ rcu_read_unlock(); -+ return ret; -+} -+ -+static void -+br_offload_check_gc(struct net_bridge *br) -+{ -+ struct net_bridge_port *p; -+ -+ spin_lock_bh(&br->lock); -+ list_for_each_entry(p, &br->port_list, list) -+ if (br_offload_need_gc(p)) -+ queue_work(system_long_wq, &p->offload.gc_work); -+ spin_unlock_bh(&br->lock); -+} -+ -+ -+int br_offload_set_cache_size(struct net_bridge *br, unsigned long val, -+ struct netlink_ext_ack *extack) -+{ -+ br->offload_cache_size = val; -+ br_offload_check_gc(br); -+ -+ return 0; -+} -+ -+int br_offload_set_cache_reserved(struct net_bridge *br, unsigned long val, -+ struct netlink_ext_ack *extack) -+{ -+ br->offload_cache_reserved = val; -+ br_offload_check_gc(br); -+ -+ return 0; -+} -+ -+int __init br_offload_init(void) -+{ -+ offload_cache = kmem_cache_create("bridge_offload_cache", -+ sizeof(struct bridge_flow), -+ 0, SLAB_HWCACHE_ALIGN, NULL); -+ if (!offload_cache) -+ return -ENOMEM; -+ -+ return 0; -+} -+ -+void br_offload_fini(void) -+{ -+ kmem_cache_destroy(offload_cache); -+} ---- a/net/bridge/br_private.h -+++ b/net/bridge/br_private.h -@@ -271,7 +271,13 @@ struct net_bridge_fdb_entry { - unsigned long updated ____cacheline_aligned_in_smp; - unsigned long used; - -- struct rcu_head rcu; -+ union { -+ struct { -+ struct hlist_head offload_in; -+ struct hlist_head offload_out; -+ }; -+ struct rcu_head rcu; -+ }; - }; - - struct net_bridge_fdb_flush_desc { -@@ -353,6 +359,12 @@ struct net_bridge_mdb_entry { - struct rcu_head rcu; - }; - -+struct net_bridge_port_offload { -+ struct rhashtable rht; -+ struct work_struct gc_work; -+ bool enabled; -+}; -+ - struct net_bridge_port { - struct net_bridge *br; - struct net_device *dev; -@@ -414,6 +426,7 @@ struct net_bridge_port { - u16 backup_redirected_cnt; - - struct bridge_stp_xstats stp_xstats; -+ struct net_bridge_port_offload offload; - }; - - #define kobj_to_brport(obj) container_of(obj, struct net_bridge_port, kobj) -@@ -531,6 +544,9 @@ struct net_bridge { - struct kobject *ifobj; - u32 auto_cnt; - -+ u32 offload_cache_size; -+ u32 offload_cache_reserved; -+ - #ifdef CONFIG_NET_SWITCHDEV - /* Counter used to make sure that hardware domains get unique - * identifiers in case a bridge spans multiple switchdev instances. -@@ -565,6 +581,10 @@ struct br_input_skb_cb { - #ifdef CONFIG_NETFILTER_FAMILY_BRIDGE - u8 br_netfilter_broute:1; - #endif -+ u8 offload:1; -+ u8 input_vlan_present:1; -+ u16 input_vlan_tag; -+ int input_ifindex; - - #ifdef CONFIG_NET_SWITCHDEV - /* Set if TX data plane offloading is used towards at least one ---- /dev/null -+++ b/net/bridge/br_private_offload.h -@@ -0,0 +1,23 @@ -+#ifndef __BR_OFFLOAD_H -+#define __BR_OFFLOAD_H -+ -+bool br_offload_input(struct net_bridge_port *p, struct sk_buff *skb); -+void br_offload_output(struct sk_buff *skb); -+void br_offload_port_state(struct net_bridge_port *p); -+void br_offload_fdb_update(const struct net_bridge_fdb_entry *fdb); -+int br_offload_init(void); -+void br_offload_fini(void); -+int br_offload_set_cache_size(struct net_bridge *br, unsigned long val, -+ struct netlink_ext_ack *extack); -+int br_offload_set_cache_reserved(struct net_bridge *br, unsigned long val, -+ struct netlink_ext_ack *extack); -+ -+static inline void br_offload_skb_disable(struct sk_buff *skb) -+{ -+ struct br_input_skb_cb *cb = (struct br_input_skb_cb *)skb->cb; -+ -+ if (cb->offload) -+ cb->offload = 0; -+} -+ -+#endif ---- a/net/bridge/br_stp.c -+++ b/net/bridge/br_stp.c -@@ -12,6 +12,7 @@ - - #include "br_private.h" - #include "br_private_stp.h" -+#include "br_private_offload.h" - - /* since time values in bpdu are in jiffies and then scaled (1/256) - * before sending, make sure that is at least one STP tick. -@@ -58,6 +59,8 @@ void br_set_state(struct net_bridge_port - (unsigned int) p->port_no, p->dev->name, - br_port_state_names[p->state]); - -+ br_offload_port_state(p); -+ - if (p->br->stp_enabled == BR_KERNEL_STP) { - switch (p->state) { - case BR_STATE_BLOCKING: ---- a/net/bridge/br_sysfs_br.c -+++ b/net/bridge/br_sysfs_br.c -@@ -18,6 +18,7 @@ - #include - - #include "br_private.h" -+#include "br_private_offload.h" - - /* IMPORTANT: new bridge options must be added with netlink support only - * please do not add new sysfs entries -@@ -933,6 +934,38 @@ static ssize_t vlan_stats_per_port_store - static DEVICE_ATTR_RW(vlan_stats_per_port); - #endif - -+static ssize_t offload_cache_size_show(struct device *d, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct net_bridge *br = to_bridge(d); -+ return sprintf(buf, "%u\n", br->offload_cache_size); -+} -+ -+static ssize_t offload_cache_size_store(struct device *d, -+ struct device_attribute *attr, -+ const char *buf, size_t len) -+{ -+ return store_bridge_parm(d, buf, len, br_offload_set_cache_size); -+} -+static DEVICE_ATTR_RW(offload_cache_size); -+ -+static ssize_t offload_cache_reserved_show(struct device *d, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct net_bridge *br = to_bridge(d); -+ return sprintf(buf, "%u\n", br->offload_cache_reserved); -+} -+ -+static ssize_t offload_cache_reserved_store(struct device *d, -+ struct device_attribute *attr, -+ const char *buf, size_t len) -+{ -+ return store_bridge_parm(d, buf, len, br_offload_set_cache_reserved); -+} -+static DEVICE_ATTR_RW(offload_cache_reserved); -+ - static struct attribute *bridge_attrs[] = { - &dev_attr_forward_delay.attr, - &dev_attr_hello_time.attr, -@@ -987,6 +1020,8 @@ static struct attribute *bridge_attrs[] - &dev_attr_vlan_stats_enabled.attr, - &dev_attr_vlan_stats_per_port.attr, - #endif -+ &dev_attr_offload_cache_size.attr, -+ &dev_attr_offload_cache_reserved.attr, - NULL - }; - ---- a/net/bridge/br_sysfs_if.c -+++ b/net/bridge/br_sysfs_if.c -@@ -241,6 +241,7 @@ BRPORT_ATTR_FLAG(broadcast_flood, BR_BCA - BRPORT_ATTR_FLAG(neigh_suppress, BR_NEIGH_SUPPRESS); - BRPORT_ATTR_FLAG(isolated, BR_ISOLATED); - BRPORT_ATTR_FLAG(bpdu_filter, BR_BPDU_FILTER); -+BRPORT_ATTR_FLAG(offload, BR_OFFLOAD); - - #ifdef CONFIG_BRIDGE_IGMP_SNOOPING - static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf) -@@ -295,6 +296,7 @@ static const struct brport_attribute *br - &brport_attr_isolated, - &brport_attr_bpdu_filter, - &brport_attr_backup_port, -+ &brport_attr_offload, - NULL - }; - ---- a/net/bridge/br_vlan_tunnel.c -+++ b/net/bridge/br_vlan_tunnel.c -@@ -15,6 +15,7 @@ - - #include "br_private.h" - #include "br_private_tunnel.h" -+#include "br_private_offload.h" - - static inline int br_vlan_tunid_cmp(struct rhashtable_compare_arg *arg, - const void *ptr) -@@ -180,6 +181,7 @@ void br_handle_ingress_vlan_tunnel(struc - skb_dst_drop(skb); - - __vlan_hwaccel_put_tag(skb, p->br->vlan_proto, vlan->vid); -+ br_offload_skb_disable(skb); - } - - int br_handle_egress_vlan_tunnel(struct sk_buff *skb, -@@ -201,6 +203,7 @@ int br_handle_egress_vlan_tunnel(struct - if (err) - return err; - -+ br_offload_skb_disable(skb); - tunnel_dst = rcu_dereference(vlan->tinfo.tunnel_dst); - if (tunnel_dst && dst_hold_safe(&tunnel_dst->dst)) - skb_dst_set(skb, &tunnel_dst->dst);