From bffabe88ef3a00120a706467d77eae707f789ad5 Mon Sep 17 00:00:00 2001 From: DHDAXCW Date: Mon, 6 May 2024 11:12:28 +0800 Subject: [PATCH] kernel: bump 6.1 to 6.1.90 --- include/kernel-6.1 | 4 +- ...v6-ext-headers-without-frag0-invalid.patch | 107 +++ ...ush-check-in-udp_gro_receive_segment.patch | 48 ++ ...lter-flowtable-validate-pppoe-header.patch | 87 --- ...lter-flowtable-incorrect-pppoe-tuple.patch | 24 - ...t-dsa-mt7530-use-external-PCS-driver.patch | 24 +- ...a-mt7530-refactor-SGMII-PCS-creation.patch | 4 +- ...mt7530-use-unlocked-regmap-accessors.patch | 6 +- ...se-regmap-to-access-switch-register-.patch | 14 +- ...ove-SGMII-PCS-creation-to-mt7530_pro.patch | 6 +- ...t-dsa-mt7530-introduce-mutex-helpers.patch | 28 +- ...ove-p5_intf_modes-function-to-mt7530.patch | 4 +- ...ntroduce-mt7530_probe_common-helper-.patch | 6 +- ...ntroduce-mt7530_remove_common-helper.patch | 4 +- ...t7530-introduce-separate-MDIO-driver.patch | 16 +- ...ntroduce-driver-for-MT7988-built-in-.patch | 24 +- ...-dsa-mt7530-fix-support-for-MT7531BE.patch | 8 +- ...v6-ext-headers-without-frag0-invalid.patch | 107 +++ ...bad-offset-in-socket-lookup-by-addin.patch | 178 +++++ ...ush-check-in-udp_gro_receive_segment.patch | 48 ++ ...lter-flowtable-validate-pppoe-header.patch | 87 --- ...lter-flowtable-incorrect-pppoe-tuple.patch | 24 - ..._wed-do-not-assume-offload-callbacks.patch | 4 +- ..._wed-introduce-versioning-utility-ro.patch | 30 +- ..._wed-do-not-configure-rx-offload-if-.patch | 20 +- ...k_wed-add-mtk_wed_soc_data-structure.patch | 22 +- ..._wed-introduce-WED-support-for-MT798.patch | 34 +- ..._wed-refactor-mtk_wed_check_wfdma_rx.patch | 4 +- ..._wed-introduce-partial-AMSDU-offload.patch | 8 +- ..._wed-introduce-hw_rro-support-for-MT.patch | 8 +- ...et-mtk_wed-add-wed-3.0-reset-support.patch | 20 +- ...et-stmmac-improve-TX-timer-arm-logic.patch | 2 +- ...c-move-TX-timer-arm-after-DMA-enable.patch | 16 +- .../generic/hack-6.1/600-bridge_offload.patch | 6 +- ...0-net-enable-fraglist-GRO-by-default.patch | 24 + ...of_net-add-mac-address-ascii-support.patch | 4 +- .../721-net-add-packet-mangeling.patch | 8 +- .../780-usb-net-MeigLink_modem_support.patch | 4 +- .../hack-6.1/901-debloat_sock_diag.patch | 4 +- .../generic/hack-6.1/902-debloat_proc.patch | 2 +- .../hack-6.1/930-usb-net-for-fm350.patch | 4 +- ...-linux-kernel-to-support-shortcut-fe.patch | 2 +- ...0-net-enable-fraglist-GRO-by-default.patch | 24 + ...-dsa-mv88e6xxx-disable-ATU-violation.patch | 2 +- .../780-usb-net-MeigLink_modem_support.patch | 4 +- .../hack-6.6/901-debloat_sock_diag.patch | 4 +- .../generic/hack-6.6/902-debloat_proc.patch | 2 +- .../hack-6.6/930-usb-net-for-fm350.patch | 4 +- ...ge_allow_receiption_on_disabled_port.patch | 4 +- ...T-skip-GRO-for-foreign-MAC-addresses.patch | 151 ----- ...680-net-add-TCP-fraglist-GRO-support.patch | 627 ++++++++++++++++++ ...ulticast-to-unicast-with-fraglist-GS.patch | 23 + ...skb_copy-_expand-for-fraglist-GSO-sk.patch | 59 ++ ...et-add-mac-address-increment-support.patch | 90 --- ...83-of_net-add-mac-address-to-of-tree.patch | 30 +- ...t-do-mac-address-increment-only-once.patch | 31 - ...d-knob-for-filtering-rx-tx-BPDU-pack.patch | 2 +- ...e-all-MACs-are-powered-down-before-r.patch | 2 +- ...0211_ptr-even-with-no-CFG82111-suppo.patch | 2 +- ...ional-threading-for-backlog-processi.patch | 14 +- ...gister-OF-node-for-internal-MDIO-bus.patch | 4 +- .../811-pci_disable_usb_common_quirks.patch | 8 +- .../901-usb-add-more-modem-support.patch | 21 +- .../pending-6.1/920-mangle_bootargs.patch | 2 +- ...ge_allow_receiption_on_disabled_port.patch | 4 +- ...T-skip-GRO-for-foreign-MAC-addresses.patch | 151 ----- ...680-net-add-TCP-fraglist-GRO-support.patch | 578 ++++++++++++++++ ...ulticast-to-unicast-with-fraglist-GS.patch | 23 + ...skb_copy-_expand-for-fraglist-GSO-sk.patch | 59 ++ ...et-add-mac-address-increment-support.patch | 90 --- ...83-of_net-add-mac-address-to-of-tree.patch | 30 +- ...les-ignore-EOPNOTSUPP-on-flowtable-d.patch | 2 +- ...d-knob-for-filtering-rx-tx-BPDU-pack.patch | 2 +- ...e-all-MACs-are-powered-down-before-r.patch | 2 +- ...ional-threading-for-backlog-processi.patch | 8 +- ...equest-assisted-learning-on-CPU-port.patch | 2 +- ...gister-OF-node-for-internal-MDIO-bus.patch | 4 +- .../811-pci_disable_usb_common_quirks.patch | 2 +- .../901-usb-add-more-modem-support.patch | 28 + .../pending-6.6/920-mangle_bootargs.patch | 2 +- ...-Rockchip-3588001-erratum-workaround.patch | 6 +- ...-Rockchip-3588001-erratum-workaround.patch | 2 +- ...nps-pcie3-rk3568-update-fw-when-init.patch | 6 +- ...1-erratum-workaround-to-rk356x-as-we.patch | 2 +- ...d-GFP_DMA32-flag-for-memory-allocate.patch | 4 +- 85 files changed, 2220 insertions(+), 981 deletions(-) create mode 100644 target/linux/generic/backport-6.1/600-v6.9-01-net-gro-parse-ipv6-ext-headers-without-frag0-invalid.patch create mode 100644 target/linux/generic/backport-6.1/600-v6.9-03-net-gro-add-flush-check-in-udp_gro_receive_segment.patch delete mode 100644 target/linux/generic/backport-6.1/740-v6.9-01-netfilter-flowtable-validate-pppoe-header.patch delete mode 100644 target/linux/generic/backport-6.1/740-v6.9-02-netfilter-flowtable-incorrect-pppoe-tuple.patch create mode 100644 target/linux/generic/backport-6.6/600-v6.9-01-net-gro-parse-ipv6-ext-headers-without-frag0-invalid.patch create mode 100644 target/linux/generic/backport-6.6/600-v6.9-02-net-gro-fix-udp-bad-offset-in-socket-lookup-by-addin.patch create mode 100644 target/linux/generic/backport-6.6/600-v6.9-03-net-gro-add-flush-check-in-udp_gro_receive_segment.patch delete mode 100644 target/linux/generic/backport-6.6/740-v6.9-01-netfilter-flowtable-validate-pppoe-header.patch delete mode 100644 target/linux/generic/backport-6.6/740-v6.9-02-netfilter-flowtable-incorrect-pppoe-tuple.patch create mode 100644 target/linux/generic/hack-6.1/600-net-enable-fraglist-GRO-by-default.patch create mode 100644 target/linux/generic/hack-6.6/600-net-enable-fraglist-GRO-by-default.patch delete mode 100644 target/linux/generic/pending-6.1/680-NET-skip-GRO-for-foreign-MAC-addresses.patch create mode 100644 target/linux/generic/pending-6.1/680-net-add-TCP-fraglist-GRO-support.patch create mode 100644 target/linux/generic/pending-6.1/681-net-bridge-fix-multicast-to-unicast-with-fraglist-GS.patch create mode 100644 target/linux/generic/pending-6.1/682-net-core-reject-skb_copy-_expand-for-fraglist-GSO-sk.patch delete mode 100644 target/linux/generic/pending-6.1/682-of_net-add-mac-address-increment-support.patch delete mode 100644 target/linux/generic/pending-6.1/684-of_net-do-mac-address-increment-only-once.patch delete mode 100644 target/linux/generic/pending-6.6/680-NET-skip-GRO-for-foreign-MAC-addresses.patch create mode 100644 target/linux/generic/pending-6.6/680-net-add-TCP-fraglist-GRO-support.patch create mode 100644 target/linux/generic/pending-6.6/681-net-bridge-fix-multicast-to-unicast-with-fraglist-GS.patch create mode 100644 target/linux/generic/pending-6.6/682-net-core-reject-skb_copy-_expand-for-fraglist-GSO-sk.patch delete mode 100644 target/linux/generic/pending-6.6/682-of_net-add-mac-address-increment-support.patch create mode 100644 target/linux/generic/pending-6.6/901-usb-add-more-modem-support.patch diff --git a/include/kernel-6.1 b/include/kernel-6.1 index aff0994e8..7dc45f9b7 100644 --- a/include/kernel-6.1 +++ b/include/kernel-6.1 @@ -1,2 +1,2 @@ -LINUX_VERSION-6.1 = .87 -LINUX_KERNEL_HASH-6.1.87 = fc7af16a72e8aee4790b796f1bf5003cb0de6095ea1ffd7d7c7c9a5678d95124 +LINUX_VERSION-6.1 = .90 +LINUX_KERNEL_HASH-6.1.90 = 83a3d72e764fceda2c1fc68a4ea6b91253a28da56a688a2b61776b0d19788e1d diff --git a/target/linux/generic/backport-6.1/600-v6.9-01-net-gro-parse-ipv6-ext-headers-without-frag0-invalid.patch b/target/linux/generic/backport-6.1/600-v6.9-01-net-gro-parse-ipv6-ext-headers-without-frag0-invalid.patch new file mode 100644 index 000000000..6dbec3c75 --- /dev/null +++ b/target/linux/generic/backport-6.1/600-v6.9-01-net-gro-parse-ipv6-ext-headers-without-frag0-invalid.patch @@ -0,0 +1,107 @@ +From: Richard Gobert +Date: Wed, 3 Jan 2024 15:44:21 +0100 +Subject: [PATCH] net: gro: parse ipv6 ext headers without frag0 invalidation + +The existing code always pulls the IPv6 header and sets the transport +offset initially. Then optionally again pulls any extension headers in +ipv6_gso_pull_exthdrs and sets the transport offset again on return from +that call. skb->data is set at the start of the first extension header +before calling ipv6_gso_pull_exthdrs, and must disable the frag0 +optimization because that function uses pskb_may_pull/pskb_pull instead of +skb_gro_ helpers. It sets the GRO offset to the TCP header with +skb_gro_pull and sets the transport header. Then returns skb->data to its +position before this block. + +This commit introduces a new helper function - ipv6_gro_pull_exthdrs - +which is used in ipv6_gro_receive to pull ipv6 ext headers instead of +ipv6_gso_pull_exthdrs. Thus, there is no modification of skb->data, all +operations use skb_gro_* helpers, and the frag0 fast path can be taken for +IPv6 packets with ext headers. + +Signed-off-by: Richard Gobert +Reviewed-by: Willem de Bruijn +Reviewed-by: David Ahern +Reviewed-by: Eric Dumazet +Link: https://lore.kernel.org/r/504130f6-b56c-4dcc-882c-97942c59f5b7@gmail.com +Signed-off-by: Jakub Kicinski +--- + +--- a/net/ipv6/ip6_offload.c ++++ b/net/ipv6/ip6_offload.c +@@ -36,6 +36,40 @@ + INDIRECT_CALL_L4(cb, f2, f1, head, skb); \ + }) + ++static int ipv6_gro_pull_exthdrs(struct sk_buff *skb, int off, int proto) ++{ ++ const struct net_offload *ops = NULL; ++ struct ipv6_opt_hdr *opth; ++ ++ for (;;) { ++ int len; ++ ++ ops = rcu_dereference(inet6_offloads[proto]); ++ ++ if (unlikely(!ops)) ++ break; ++ ++ if (!(ops->flags & INET6_PROTO_GSO_EXTHDR)) ++ break; ++ ++ opth = skb_gro_header(skb, off + sizeof(*opth), off); ++ if (unlikely(!opth)) ++ break; ++ ++ len = ipv6_optlen(opth); ++ ++ opth = skb_gro_header(skb, off + len, off); ++ if (unlikely(!opth)) ++ break; ++ proto = opth->nexthdr; ++ ++ off += len; ++ } ++ ++ skb_gro_pull(skb, off - skb_network_offset(skb)); ++ return proto; ++} ++ + static int ipv6_gso_pull_exthdrs(struct sk_buff *skb, int proto) + { + const struct net_offload *ops = NULL; +@@ -224,28 +258,25 @@ INDIRECT_CALLABLE_SCOPE struct sk_buff * + goto out; + + skb_set_network_header(skb, off); +- skb_gro_pull(skb, sizeof(*iph)); +- skb_set_transport_header(skb, skb_gro_offset(skb)); + +- flush += ntohs(iph->payload_len) != skb_gro_len(skb); ++ flush += ntohs(iph->payload_len) != skb->len - hlen; + + proto = iph->nexthdr; + ops = rcu_dereference(inet6_offloads[proto]); + if (!ops || !ops->callbacks.gro_receive) { +- pskb_pull(skb, skb_gro_offset(skb)); +- skb_gro_frag0_invalidate(skb); +- proto = ipv6_gso_pull_exthdrs(skb, proto); +- skb_gro_pull(skb, -skb_transport_offset(skb)); +- skb_reset_transport_header(skb); +- __skb_push(skb, skb_gro_offset(skb)); ++ proto = ipv6_gro_pull_exthdrs(skb, hlen, proto); + + ops = rcu_dereference(inet6_offloads[proto]); + if (!ops || !ops->callbacks.gro_receive) + goto out; + +- iph = ipv6_hdr(skb); ++ iph = skb_gro_network_header(skb); ++ } else { ++ skb_gro_pull(skb, sizeof(*iph)); + } + ++ skb_set_transport_header(skb, skb_gro_offset(skb)); ++ + NAPI_GRO_CB(skb)->proto = proto; + + flush--; diff --git a/target/linux/generic/backport-6.1/600-v6.9-03-net-gro-add-flush-check-in-udp_gro_receive_segment.patch b/target/linux/generic/backport-6.1/600-v6.9-03-net-gro-add-flush-check-in-udp_gro_receive_segment.patch new file mode 100644 index 000000000..55dac85df --- /dev/null +++ b/target/linux/generic/backport-6.1/600-v6.9-03-net-gro-add-flush-check-in-udp_gro_receive_segment.patch @@ -0,0 +1,48 @@ +From: Richard Gobert +Date: Tue, 30 Apr 2024 16:35:55 +0200 +Subject: [PATCH] net: gro: add flush check in udp_gro_receive_segment + +GRO-GSO path is supposed to be transparent and as such L3 flush checks are +relevant to all UDP flows merging in GRO. This patch uses the same logic +and code from tcp_gro_receive, terminating merge if flush is non zero. + +Fixes: e20cf8d3f1f7 ("udp: implement GRO for plain UDP sockets.") +Signed-off-by: Richard Gobert +Reviewed-by: Willem de Bruijn +Signed-off-by: Paolo Abeni +--- + +--- a/net/ipv4/udp_offload.c ++++ b/net/ipv4/udp_offload.c +@@ -463,6 +463,7 @@ static struct sk_buff *udp_gro_receive_s + struct sk_buff *p; + unsigned int ulen; + int ret = 0; ++ int flush; + + /* requires non zero csum, for symmetry with GSO */ + if (!uh->check) { +@@ -496,13 +497,22 @@ static struct sk_buff *udp_gro_receive_s + return p; + } + ++ flush = NAPI_GRO_CB(p)->flush; ++ ++ if (NAPI_GRO_CB(p)->flush_id != 1 || ++ NAPI_GRO_CB(p)->count != 1 || ++ !NAPI_GRO_CB(p)->is_atomic) ++ flush |= NAPI_GRO_CB(p)->flush_id; ++ else ++ NAPI_GRO_CB(p)->is_atomic = false; ++ + /* Terminate the flow on len mismatch or if it grow "too much". + * Under small packet flood GRO count could elsewhere grow a lot + * leading to excessive truesize values. + * On len mismatch merge the first packet shorter than gso_size, + * otherwise complete the GRO packet. + */ +- if (ulen > ntohs(uh2->len)) { ++ if (ulen > ntohs(uh2->len) || flush) { + pp = p; + } else { + if (NAPI_GRO_CB(skb)->is_flist) { diff --git a/target/linux/generic/backport-6.1/740-v6.9-01-netfilter-flowtable-validate-pppoe-header.patch b/target/linux/generic/backport-6.1/740-v6.9-01-netfilter-flowtable-validate-pppoe-header.patch deleted file mode 100644 index 29f211e8a..000000000 --- a/target/linux/generic/backport-6.1/740-v6.9-01-netfilter-flowtable-validate-pppoe-header.patch +++ /dev/null @@ -1,87 +0,0 @@ -From: Pablo Neira Ayuso -Date: Thu, 11 Apr 2024 13:28:59 +0200 -Subject: [PATCH] netfilter: flowtable: validate pppoe header - -Ensure there is sufficient room to access the protocol field of the -PPPoe header. Validate it once before the flowtable lookup, then use a -helper function to access protocol field. - -Reported-by: syzbot+b6f07e1c07ef40199081@syzkaller.appspotmail.com -Fixes: 72efd585f714 ("netfilter: flowtable: add pppoe support") -Signed-off-by: Pablo Neira Ayuso ---- - ---- a/include/net/netfilter/nf_flow_table.h -+++ b/include/net/netfilter/nf_flow_table.h -@@ -335,7 +335,7 @@ int nf_flow_rule_route_ipv6(struct net * - int nf_flow_table_offload_init(void); - void nf_flow_table_offload_exit(void); - --static inline __be16 nf_flow_pppoe_proto(const struct sk_buff *skb) -+static inline __be16 __nf_flow_pppoe_proto(const struct sk_buff *skb) - { - __be16 proto; - -@@ -351,6 +351,16 @@ static inline __be16 nf_flow_pppoe_proto - return 0; - } - -+static inline bool nf_flow_pppoe_proto(struct sk_buff *skb, __be16 *inner_proto) -+{ -+ if (!pskb_may_pull(skb, PPPOE_SES_HLEN)) -+ return false; -+ -+ *inner_proto = __nf_flow_pppoe_proto(skb); -+ -+ return true; -+} -+ - #define NF_FLOW_TABLE_STAT_INC(net, count) __this_cpu_inc((net)->ft.stat->count) - #define NF_FLOW_TABLE_STAT_DEC(net, count) __this_cpu_dec((net)->ft.stat->count) - #define NF_FLOW_TABLE_STAT_INC_ATOMIC(net, count) \ ---- a/net/netfilter/nf_flow_table_inet.c -+++ b/net/netfilter/nf_flow_table_inet.c -@@ -21,7 +21,8 @@ nf_flow_offload_inet_hook(void *priv, st - proto = veth->h_vlan_encapsulated_proto; - break; - case htons(ETH_P_PPP_SES): -- proto = nf_flow_pppoe_proto(skb); -+ if (!nf_flow_pppoe_proto(skb, &proto)) -+ return NF_ACCEPT; - break; - default: - proto = skb->protocol; ---- a/net/netfilter/nf_flow_table_ip.c -+++ b/net/netfilter/nf_flow_table_ip.c -@@ -267,10 +267,11 @@ static unsigned int nf_flow_xmit_xfrm(st - return NF_STOLEN; - } - --static bool nf_flow_skb_encap_protocol(const struct sk_buff *skb, __be16 proto, -+static bool nf_flow_skb_encap_protocol(struct sk_buff *skb, __be16 proto, - u32 *offset) - { - struct vlan_ethhdr *veth; -+ __be16 inner_proto; - - switch (skb->protocol) { - case htons(ETH_P_8021Q): -@@ -281,7 +282,8 @@ static bool nf_flow_skb_encap_protocol(c - } - break; - case htons(ETH_P_PPP_SES): -- if (nf_flow_pppoe_proto(skb) == proto) { -+ if (nf_flow_pppoe_proto(skb, &inner_proto) && -+ inner_proto == proto) { - *offset += PPPOE_SES_HLEN; - return true; - } -@@ -310,7 +312,7 @@ static void nf_flow_encap_pop(struct sk_ - skb_reset_network_header(skb); - break; - case htons(ETH_P_PPP_SES): -- skb->protocol = nf_flow_pppoe_proto(skb); -+ skb->protocol = __nf_flow_pppoe_proto(skb); - skb_pull(skb, PPPOE_SES_HLEN); - skb_reset_network_header(skb); - break; diff --git a/target/linux/generic/backport-6.1/740-v6.9-02-netfilter-flowtable-incorrect-pppoe-tuple.patch b/target/linux/generic/backport-6.1/740-v6.9-02-netfilter-flowtable-incorrect-pppoe-tuple.patch deleted file mode 100644 index 3b822b169..000000000 --- a/target/linux/generic/backport-6.1/740-v6.9-02-netfilter-flowtable-incorrect-pppoe-tuple.patch +++ /dev/null @@ -1,24 +0,0 @@ -From: Pablo Neira Ayuso -Date: Thu, 11 Apr 2024 13:29:00 +0200 -Subject: [PATCH] netfilter: flowtable: incorrect pppoe tuple - -pppoe traffic reaching ingress path does not match the flowtable entry -because the pppoe header is expected to be at the network header offset. -This bug causes a mismatch in the flow table lookup, so pppoe packets -enter the classical forwarding path. - -Fixes: 72efd585f714 ("netfilter: flowtable: add pppoe support") -Signed-off-by: Pablo Neira Ayuso ---- - ---- a/net/netfilter/nf_flow_table_ip.c -+++ b/net/netfilter/nf_flow_table_ip.c -@@ -156,7 +156,7 @@ static void nf_flow_tuple_encap(struct s - tuple->encap[i].proto = skb->protocol; - break; - case htons(ETH_P_PPP_SES): -- phdr = (struct pppoe_hdr *)skb_mac_header(skb); -+ phdr = (struct pppoe_hdr *)skb_network_header(skb); - tuple->encap[i].id = ntohs(phdr->sid); - tuple->encap[i].proto = skb->protocol; - break; diff --git a/target/linux/generic/backport-6.1/788-v6.3-net-dsa-mt7530-use-external-PCS-driver.patch b/target/linux/generic/backport-6.1/788-v6.3-net-dsa-mt7530-use-external-PCS-driver.patch index 17da2fe05..c6570badd 100644 --- a/target/linux/generic/backport-6.1/788-v6.3-net-dsa-mt7530-use-external-PCS-driver.patch +++ b/target/linux/generic/backport-6.1/788-v6.3-net-dsa-mt7530-use-external-PCS-driver.patch @@ -81,7 +81,7 @@ Tested-by: Frank Wunderlich #include #include #include -@@ -2812,128 +2813,11 @@ static int mt7531_rgmii_setup(struct mt7 +@@ -2839,128 +2840,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) -@@ -2956,11 +2840,11 @@ mt7531_mac_config(struct dsa_switch *ds, +@@ -2983,11 +2867,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; } -@@ -2985,11 +2869,11 @@ mt753x_phylink_mac_select_pcs(struct dsa +@@ -3012,11 +2896,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; } -@@ -3230,86 +3114,6 @@ static void mt7530_pcs_get_state(struct +@@ -3257,86 +3141,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, -@@ -3329,18 +3133,57 @@ static const struct phylink_pcs_ops mt75 +@@ -3356,18 +3160,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 */ -@@ -3348,8 +3191,6 @@ mt753x_setup(struct dsa_switch *ds) +@@ -3375,8 +3218,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); -@@ -3364,6 +3205,16 @@ mt753x_setup(struct dsa_switch *ds) +@@ -3391,6 +3232,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; } -@@ -3455,7 +3306,7 @@ static const struct mt753x_info mt753x_t +@@ -3483,7 +3334,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, -@@ -3563,7 +3414,7 @@ static void +@@ -3591,7 +3442,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; -@@ -3582,6 +3433,10 @@ mt7530_remove(struct mdio_device *mdiode +@@ -3610,6 +3461,10 @@ mt7530_remove(struct mdio_device *mdiode mt7530_free_irq(priv); dsa_unregister_switch(priv->ds); @@ -446,7 +446,7 @@ Tested-by: Frank Wunderlich --- a/drivers/net/dsa/mt7530.h +++ b/drivers/net/dsa/mt7530.h -@@ -396,47 +396,8 @@ enum mt7530_vlan_port_acc_frm { +@@ -401,47 +401,8 @@ enum mt7530_vlan_port_acc_frm { CCR_TX_OCT_CNT_BAD) /* MT7531 SGMII register group */ @@ -496,7 +496,7 @@ Tested-by: Frank Wunderlich /* Register for system reset */ #define MT7530_SYS_CTRL 0x7000 -@@ -735,13 +696,13 @@ struct mt7530_fdb { +@@ -741,13 +702,13 @@ struct mt7530_fdb { * @pm: The matrix used to show all connections with the port. * @pvid: The VLAN specified is to be considered a PVID at ingress. Any * untagged frames will be assigned to the related VLAN. diff --git a/target/linux/generic/backport-6.1/790-v6.4-0002-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch b/target/linux/generic/backport-6.1/790-v6.4-0002-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch index 9ff8c6ce9..ef0bdeedd 100644 --- a/target/linux/generic/backport-6.1/790-v6.4-0002-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch +++ b/target/linux/generic/backport-6.1/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 -@@ -3165,26 +3165,56 @@ static const struct regmap_bus mt7531_re +@@ -3192,26 +3192,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 */ -@@ -3206,15 +3236,11 @@ mt753x_setup(struct dsa_switch *ds) +@@ -3233,15 +3263,11 @@ mt753x_setup(struct dsa_switch *ds) if (ret && priv->irq) mt7530_free_irq_common(priv); diff --git a/target/linux/generic/backport-6.1/790-v6.4-0003-net-dsa-mt7530-use-unlocked-regmap-accessors.patch b/target/linux/generic/backport-6.1/790-v6.4-0003-net-dsa-mt7530-use-unlocked-regmap-accessors.patch index 424d0a560..dad12607a 100644 --- a/target/linux/generic/backport-6.1/790-v6.4-0003-net-dsa-mt7530-use-unlocked-regmap-accessors.patch +++ b/target/linux/generic/backport-6.1/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 -@@ -3138,7 +3138,7 @@ static int mt7530_regmap_read(void *cont +@@ -3165,7 +3165,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; }; -@@ -3146,23 +3146,25 @@ static int mt7530_regmap_write(void *con +@@ -3173,23 +3173,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 -@@ -3188,6 +3190,9 @@ mt7531_create_sgmii(struct mt7530_priv * +@@ -3215,6 +3217,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-6.1/790-v6.4-0004-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch b/target/linux/generic/backport-6.1/790-v6.4-0004-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch index fa8dfabd0..7dc524dbb 100644 --- a/target/linux/generic/backport-6.1/790-v6.4-0004-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch +++ b/target/linux/generic/backport-6.1/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 -@@ -3134,22 +3155,6 @@ static const struct phylink_pcs_ops mt75 +@@ -3161,22 +3182,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) { -@@ -3162,7 +3167,7 @@ mt7530_mdio_regmap_unlock(void *mdio_loc +@@ -3189,7 +3194,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, }; -@@ -3195,7 +3200,7 @@ mt7531_create_sgmii(struct mt7530_priv * +@@ -3222,7 +3227,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); -@@ -3360,6 +3365,7 @@ MODULE_DEVICE_TABLE(of, mt7530_of_match) +@@ -3388,6 +3393,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; -@@ -3439,6 +3445,21 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3467,6 +3473,21 @@ mt7530_probe(struct mdio_device *mdiodev mutex_init(&priv->reg_mutex); dev_set_drvdata(&mdiodev->dev, priv); @@ -206,7 +206,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/dsa/mt7530.h +++ b/drivers/net/dsa/mt7530.h -@@ -779,6 +779,7 @@ struct mt753x_info { +@@ -785,6 +785,7 @@ struct mt753x_info { * @dev: The device pointer * @ds: The pointer to the dsa core structure * @bus: The bus used for the device and built-in PHY @@ -214,7 +214,7 @@ Signed-off-by: David S. Miller * @rstc: The pointer to reset control used by MCM * @core_pwr: The power supplied into the core * @io_pwr: The power supplied into the I/O -@@ -799,6 +800,7 @@ struct mt7530_priv { +@@ -805,6 +806,7 @@ struct mt7530_priv { struct device *dev; struct dsa_switch *ds; struct mii_bus *bus; diff --git a/target/linux/generic/backport-6.1/790-v6.4-0005-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch b/target/linux/generic/backport-6.1/790-v6.4-0005-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch index 38a2cd0a6..a9fefab77 100644 --- a/target/linux/generic/backport-6.1/790-v6.4-0005-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch +++ b/target/linux/generic/backport-6.1/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 -@@ -3246,12 +3246,6 @@ mt753x_setup(struct dsa_switch *ds) +@@ -3273,12 +3273,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; } -@@ -3368,6 +3362,7 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3396,6 +3390,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; -@@ -3460,6 +3455,12 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3488,6 +3483,12 @@ mt7530_probe(struct mdio_device *mdiodev if (IS_ERR(priv->regmap)) return PTR_ERR(priv->regmap); diff --git a/target/linux/generic/backport-6.1/790-v6.4-0006-net-dsa-mt7530-introduce-mutex-helpers.patch b/target/linux/generic/backport-6.1/790-v6.4-0006-net-dsa-mt7530-introduce-mutex-helpers.patch index 7a9bbb527..a063f78bb 100644 --- a/target/linux/generic/backport-6.1/790-v6.4-0006-net-dsa-mt7530-introduce-mutex-helpers.patch +++ b/target/linux/generic/backport-6.1/790-v6.4-0006-net-dsa-mt7530-introduce-mutex-helpers.patch @@ -114,7 +114,7 @@ Signed-off-by: David S. Miller } static void -@@ -645,14 +649,13 @@ static int +@@ -659,14 +663,13 @@ static int mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad, int regnum) { @@ -130,7 +130,7 @@ Signed-off-by: David S. Miller ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val, !(val & MT7531_PHY_ACS_ST), 20, 100000); -@@ -685,7 +688,7 @@ mt7531_ind_c45_phy_read(struct mt7530_pr +@@ -699,7 +702,7 @@ mt7531_ind_c45_phy_read(struct mt7530_pr ret = val & MT7531_MDIO_RW_DATA_MASK; out: @@ -139,7 +139,7 @@ Signed-off-by: David S. Miller return ret; } -@@ -694,14 +697,13 @@ static int +@@ -708,14 +711,13 @@ static int mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad, int regnum, u32 data) { @@ -155,7 +155,7 @@ Signed-off-by: David S. Miller ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val, !(val & MT7531_PHY_ACS_ST), 20, 100000); -@@ -733,7 +735,7 @@ mt7531_ind_c45_phy_write(struct mt7530_p +@@ -747,7 +749,7 @@ mt7531_ind_c45_phy_write(struct mt7530_p } out: @@ -164,7 +164,7 @@ Signed-off-by: David S. Miller return ret; } -@@ -741,14 +743,13 @@ out: +@@ -755,14 +757,13 @@ out: static int mt7531_ind_c22_phy_read(struct mt7530_priv *priv, int port, int regnum) { @@ -180,7 +180,7 @@ Signed-off-by: David S. Miller ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val, !(val & MT7531_PHY_ACS_ST), 20, 100000); -@@ -771,7 +772,7 @@ mt7531_ind_c22_phy_read(struct mt7530_pr +@@ -785,7 +786,7 @@ mt7531_ind_c22_phy_read(struct mt7530_pr ret = val & MT7531_MDIO_RW_DATA_MASK; out: @@ -189,7 +189,7 @@ Signed-off-by: David S. Miller return ret; } -@@ -780,14 +781,13 @@ static int +@@ -794,14 +795,13 @@ static int mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum, u16 data) { @@ -205,7 +205,7 @@ Signed-off-by: David S. Miller ret = readx_poll_timeout(_mt7530_unlocked_read, &p, reg, !(reg & MT7531_PHY_ACS_ST), 20, 100000); -@@ -809,7 +809,7 @@ mt7531_ind_c22_phy_write(struct mt7530_p +@@ -823,7 +823,7 @@ mt7531_ind_c22_phy_write(struct mt7530_p } out: @@ -214,7 +214,7 @@ Signed-off-by: David S. Miller return ret; } -@@ -1322,7 +1322,6 @@ static int +@@ -1343,7 +1343,6 @@ static int mt7530_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) { struct mt7530_priv *priv = ds->priv; @@ -222,7 +222,7 @@ Signed-off-by: David S. Miller int length; u32 val; -@@ -1333,7 +1332,7 @@ mt7530_port_change_mtu(struct dsa_switch +@@ -1354,7 +1353,7 @@ mt7530_port_change_mtu(struct dsa_switch if (!dsa_is_cpu_port(ds, port)) return 0; @@ -231,7 +231,7 @@ Signed-off-by: David S. Miller val = mt7530_mii_read(priv, MT7530_GMACCR); val &= ~MAX_RX_PKT_LEN_MASK; -@@ -1354,7 +1353,7 @@ mt7530_port_change_mtu(struct dsa_switch +@@ -1375,7 +1374,7 @@ mt7530_port_change_mtu(struct dsa_switch mt7530_mii_write(priv, MT7530_GMACCR, val); @@ -240,7 +240,7 @@ Signed-off-by: David S. Miller return 0; } -@@ -2155,10 +2154,10 @@ mt7530_irq_thread_fn(int irq, void *dev_ +@@ -2176,10 +2175,10 @@ mt7530_irq_thread_fn(int irq, void *dev_ u32 val; int p; @@ -253,7 +253,7 @@ Signed-off-by: David S. Miller for (p = 0; p < MT7530_NUM_PHYS; p++) { if (BIT(p) & val) { -@@ -2194,7 +2193,7 @@ mt7530_irq_bus_lock(struct irq_data *d) +@@ -2215,7 +2214,7 @@ mt7530_irq_bus_lock(struct irq_data *d) { struct mt7530_priv *priv = irq_data_get_irq_chip_data(d); @@ -262,7 +262,7 @@ Signed-off-by: David S. Miller } static void -@@ -2203,7 +2202,7 @@ mt7530_irq_bus_sync_unlock(struct irq_da +@@ -2224,7 +2223,7 @@ mt7530_irq_bus_sync_unlock(struct irq_da struct mt7530_priv *priv = irq_data_get_irq_chip_data(d); mt7530_mii_write(priv, MT7530_SYS_INT_EN, priv->irq_enable); diff --git a/target/linux/generic/backport-6.1/790-v6.4-0007-net-dsa-mt7530-move-p5_intf_modes-function-to-mt7530.patch b/target/linux/generic/backport-6.1/790-v6.4-0007-net-dsa-mt7530-move-p5_intf_modes-function-to-mt7530.patch index ac03f6425..cc5ca5167 100644 --- a/target/linux/generic/backport-6.1/790-v6.4-0007-net-dsa-mt7530-move-p5_intf_modes-function-to-mt7530.patch +++ b/target/linux/generic/backport-6.1/790-v6.4-0007-net-dsa-mt7530-move-p5_intf_modes-function-to-mt7530.patch @@ -21,7 +21,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -950,6 +950,24 @@ mt7530_set_ageing_time(struct dsa_switch +@@ -964,6 +964,24 @@ mt7530_set_ageing_time(struct dsa_switch return 0; } @@ -48,7 +48,7 @@ Signed-off-by: David S. Miller struct mt7530_priv *priv = ds->priv; --- a/drivers/net/dsa/mt7530.h +++ b/drivers/net/dsa/mt7530.h -@@ -714,24 +714,6 @@ enum p5_interface_select { +@@ -720,24 +720,6 @@ enum p5_interface_select { P5_INTF_SEL_GMAC5_SGMII, }; diff --git a/target/linux/generic/backport-6.1/790-v6.4-0008-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch b/target/linux/generic/backport-6.1/790-v6.4-0008-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch index 55f595fd6..3dc6f389c 100644 --- a/target/linux/generic/backport-6.1/790-v6.4-0008-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch +++ b/target/linux/generic/backport-6.1/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 -@@ -3374,44 +3374,21 @@ static const struct of_device_id mt7530_ +@@ -3402,44 +3402,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; -@@ -3425,23 +3402,53 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3453,23 +3430,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)) { -@@ -3450,12 +3457,15 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3478,12 +3485,15 @@ mt7530_probe(struct mdio_device *mdiodev } } diff --git a/target/linux/generic/backport-6.1/790-v6.4-0009-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch b/target/linux/generic/backport-6.1/790-v6.4-0009-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch index 869bea071..9c9f1ac7f 100644 --- a/target/linux/generic/backport-6.1/790-v6.4-0009-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch +++ b/target/linux/generic/backport-6.1/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 -@@ -3492,6 +3492,17 @@ mt7530_probe(struct mdio_device *mdiodev +@@ -3520,6 +3520,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); -@@ -3510,15 +3521,10 @@ mt7530_remove(struct mdio_device *mdiode +@@ -3538,15 +3549,10 @@ 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-6.1/790-v6.4-0010-net-dsa-mt7530-introduce-separate-MDIO-driver.patch b/target/linux/generic/backport-6.1/790-v6.4-0010-net-dsa-mt7530-introduce-separate-MDIO-driver.patch index 44edd9556..82008223e 100644 --- a/target/linux/generic/backport-6.1/790-v6.4-0010-net-dsa-mt7530-introduce-separate-MDIO-driver.patch +++ b/target/linux/generic/backport-6.1/790-v6.4-0010-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) { -@@ -3172,72 +3123,6 @@ static const struct phylink_pcs_ops mt75 +@@ -3199,72 +3150,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) { -@@ -3296,7 +3181,7 @@ static int mt753x_set_mac_eee(struct dsa +@@ -3323,7 +3208,7 @@ static int mt753x_set_mac_eee(struct dsa return 0; } @@ -497,8 +497,8 @@ Signed-off-by: David S. Miller +const struct dsa_switch_ops mt7530_switch_ops = { .get_tag_protocol = mtk_get_tag_protocol, .setup = mt753x_setup, - .get_strings = mt7530_get_strings, -@@ -3330,8 +3215,9 @@ static const struct dsa_switch_ops mt753 + .preferred_default_local_cpu_port = mt753x_preferred_default_local_cpu_port, +@@ -3358,8 +3243,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, -@@ -3364,16 +3250,9 @@ static const struct mt753x_info mt753x_t +@@ -3392,16 +3278,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; -@@ -3410,88 +3289,9 @@ mt7530_probe_common(struct mt7530_priv * +@@ -3438,88 +3317,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) -@@ -3501,55 +3301,7 @@ mt7530_remove_common(struct mt7530_priv +@@ -3529,55 +3329,7 @@ mt7530_remove_common(struct mt7530_priv mutex_destroy(&priv->reg_mutex); } @@ -678,7 +678,7 @@ Signed-off-by: David S. Miller MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch"); --- a/drivers/net/dsa/mt7530.h +++ b/drivers/net/dsa/mt7530.h -@@ -839,4 +839,10 @@ static inline void INIT_MT7530_DUMMY_POL +@@ -845,4 +845,10 @@ static inline void INIT_MT7530_DUMMY_POL p->reg = reg; } diff --git a/target/linux/generic/backport-6.1/790-v6.4-0012-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch b/target/linux/generic/backport-6.1/790-v6.4-0012-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch index c3944f22e..1819b78ae 100644 --- a/target/linux/generic/backport-6.1/790-v6.4-0012-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch +++ b/target/linux/generic/backport-6.1/790-v6.4-0012-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch @@ -184,7 +184,7 @@ Signed-off-by: David S. Miller +MODULE_LICENSE("GPL"); --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2202,6 +2202,47 @@ static const struct irq_domain_ops mt753 +@@ -2223,6 +2223,47 @@ static const struct irq_domain_ops mt753 }; static void @@ -232,7 +232,7 @@ Signed-off-by: David S. Miller mt7530_setup_mdio_irq(struct mt7530_priv *priv) { struct dsa_switch *ds = priv->ds; -@@ -2235,8 +2276,15 @@ mt7530_setup_irq(struct mt7530_priv *pri +@@ -2256,8 +2297,15 @@ mt7530_setup_irq(struct mt7530_priv *pri return priv->irq ? : -EINVAL; } @@ -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; -@@ -2735,6 +2783,25 @@ static void mt7531_mac_port_get_caps(str +@@ -2762,6 +2810,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) { -@@ -2811,6 +2878,17 @@ static bool mt753x_is_mac_port(u32 port) +@@ -2838,6 +2905,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) { -@@ -2880,7 +2958,8 @@ mt753x_phylink_mac_config(struct dsa_swi +@@ -2907,7 +2985,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 */ -@@ -2958,7 +3037,8 @@ static void mt753x_phylink_mac_link_up(s +@@ -2985,7 +3064,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; -@@ -3038,6 +3118,21 @@ mt7531_cpu_port_config(struct dsa_switch +@@ -3065,6 +3145,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) { -@@ -3183,6 +3278,27 @@ static int mt753x_set_mac_eee(struct dsa +@@ -3210,6 +3305,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, -@@ -3251,6 +3367,17 @@ const struct mt753x_info mt753x_table[] +@@ -3279,6 +3395,17 @@ const struct mt753x_info mt753x_table[] .mac_port_get_caps = mt7531_mac_port_get_caps, .mac_port_config = mt7531_mac_config, }, @@ -392,9 +392,9 @@ Signed-off-by: David S. Miller }; #define NUM_TRGMII_CTRL 5 -@@ -54,11 +55,11 @@ enum mt753x_id { - #define MT7531_MIRROR_PORT_SET(x) (((x) & MIRROR_MASK) << 16) +@@ -59,11 +60,11 @@ enum mt753x_id { #define MT7531_CPU_PMAP_MASK GENMASK(7, 0) + #define MT7531_CPU_PMAP(x) FIELD_PREP(MT7531_CPU_PMAP_MASK, x) -#define MT753X_MIRROR_REG(id) (((id) == ID_MT7531) ? \ +#define MT753X_MIRROR_REG(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \ @@ -407,7 +407,7 @@ Signed-off-by: David S. Miller MT7531_MIRROR_MASK : MIRROR_MASK) /* Registers for BPDU and PAE frame control*/ -@@ -327,9 +328,8 @@ enum mt7530_vlan_port_acc_frm { +@@ -332,9 +333,8 @@ enum mt7530_vlan_port_acc_frm { MT7531_FORCE_DPX | \ MT7531_FORCE_RX_FC | \ MT7531_FORCE_TX_FC) diff --git a/target/linux/generic/backport-6.1/790-v6.4-0013-net-dsa-mt7530-fix-support-for-MT7531BE.patch b/target/linux/generic/backport-6.1/790-v6.4-0013-net-dsa-mt7530-fix-support-for-MT7531BE.patch index ea342f02d..35f8cf939 100644 --- a/target/linux/generic/backport-6.1/790-v6.4-0013-net-dsa-mt7530-fix-support-for-MT7531BE.patch +++ b/target/linux/generic/backport-6.1/790-v6.4-0013-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 -@@ -3245,6 +3245,12 @@ mt753x_setup(struct dsa_switch *ds) +@@ -3272,6 +3272,12 @@ mt753x_setup(struct dsa_switch *ds) if (ret && priv->irq) mt7530_free_irq_common(priv); @@ -88,7 +88,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/dsa/mt7530.h +++ b/drivers/net/dsa/mt7530.h -@@ -773,10 +773,10 @@ struct mt753x_info { +@@ -779,10 +779,10 @@ struct mt753x_info { * registers * @p6_interface Holding the current port 6 interface * @p5_intf_sel: Holding the current port 5 interface select @@ -100,7 +100,7 @@ Signed-off-by: Jakub Kicinski */ struct mt7530_priv { struct device *dev; -@@ -795,7 +795,6 @@ struct mt7530_priv { +@@ -801,7 +801,6 @@ struct mt7530_priv { unsigned int p5_intf_sel; u8 mirror_rx; u8 mirror_tx; @@ -108,7 +108,7 @@ Signed-off-by: Jakub Kicinski struct mt7530_port ports[MT7530_NUM_PORTS]; struct mt753x_pcs pcs[MT7530_NUM_PORTS]; /* protect among processes for registers access*/ -@@ -803,6 +802,7 @@ struct mt7530_priv { +@@ -809,6 +808,7 @@ struct mt7530_priv { int irq; struct irq_domain *irq_domain; u32 irq_enable; diff --git a/target/linux/generic/backport-6.6/600-v6.9-01-net-gro-parse-ipv6-ext-headers-without-frag0-invalid.patch b/target/linux/generic/backport-6.6/600-v6.9-01-net-gro-parse-ipv6-ext-headers-without-frag0-invalid.patch new file mode 100644 index 000000000..d0fed0200 --- /dev/null +++ b/target/linux/generic/backport-6.6/600-v6.9-01-net-gro-parse-ipv6-ext-headers-without-frag0-invalid.patch @@ -0,0 +1,107 @@ +From: Richard Gobert +Date: Wed, 3 Jan 2024 15:44:21 +0100 +Subject: [PATCH] net: gro: parse ipv6 ext headers without frag0 invalidation + +The existing code always pulls the IPv6 header and sets the transport +offset initially. Then optionally again pulls any extension headers in +ipv6_gso_pull_exthdrs and sets the transport offset again on return from +that call. skb->data is set at the start of the first extension header +before calling ipv6_gso_pull_exthdrs, and must disable the frag0 +optimization because that function uses pskb_may_pull/pskb_pull instead of +skb_gro_ helpers. It sets the GRO offset to the TCP header with +skb_gro_pull and sets the transport header. Then returns skb->data to its +position before this block. + +This commit introduces a new helper function - ipv6_gro_pull_exthdrs - +which is used in ipv6_gro_receive to pull ipv6 ext headers instead of +ipv6_gso_pull_exthdrs. Thus, there is no modification of skb->data, all +operations use skb_gro_* helpers, and the frag0 fast path can be taken for +IPv6 packets with ext headers. + +Signed-off-by: Richard Gobert +Reviewed-by: Willem de Bruijn +Reviewed-by: David Ahern +Reviewed-by: Eric Dumazet +Link: https://lore.kernel.org/r/504130f6-b56c-4dcc-882c-97942c59f5b7@gmail.com +Signed-off-by: Jakub Kicinski +--- + +--- a/net/ipv6/ip6_offload.c ++++ b/net/ipv6/ip6_offload.c +@@ -37,6 +37,40 @@ + INDIRECT_CALL_L4(cb, f2, f1, head, skb); \ + }) + ++static int ipv6_gro_pull_exthdrs(struct sk_buff *skb, int off, int proto) ++{ ++ const struct net_offload *ops = NULL; ++ struct ipv6_opt_hdr *opth; ++ ++ for (;;) { ++ int len; ++ ++ ops = rcu_dereference(inet6_offloads[proto]); ++ ++ if (unlikely(!ops)) ++ break; ++ ++ if (!(ops->flags & INET6_PROTO_GSO_EXTHDR)) ++ break; ++ ++ opth = skb_gro_header(skb, off + sizeof(*opth), off); ++ if (unlikely(!opth)) ++ break; ++ ++ len = ipv6_optlen(opth); ++ ++ opth = skb_gro_header(skb, off + len, off); ++ if (unlikely(!opth)) ++ break; ++ proto = opth->nexthdr; ++ ++ off += len; ++ } ++ ++ skb_gro_pull(skb, off - skb_network_offset(skb)); ++ return proto; ++} ++ + static int ipv6_gso_pull_exthdrs(struct sk_buff *skb, int proto) + { + const struct net_offload *ops = NULL; +@@ -206,28 +240,25 @@ INDIRECT_CALLABLE_SCOPE struct sk_buff * + goto out; + + skb_set_network_header(skb, off); +- skb_gro_pull(skb, sizeof(*iph)); +- skb_set_transport_header(skb, skb_gro_offset(skb)); + +- flush += ntohs(iph->payload_len) != skb_gro_len(skb); ++ flush += ntohs(iph->payload_len) != skb->len - hlen; + + proto = iph->nexthdr; + ops = rcu_dereference(inet6_offloads[proto]); + if (!ops || !ops->callbacks.gro_receive) { +- pskb_pull(skb, skb_gro_offset(skb)); +- skb_gro_frag0_invalidate(skb); +- proto = ipv6_gso_pull_exthdrs(skb, proto); +- skb_gro_pull(skb, -skb_transport_offset(skb)); +- skb_reset_transport_header(skb); +- __skb_push(skb, skb_gro_offset(skb)); ++ proto = ipv6_gro_pull_exthdrs(skb, hlen, proto); + + ops = rcu_dereference(inet6_offloads[proto]); + if (!ops || !ops->callbacks.gro_receive) + goto out; + +- iph = ipv6_hdr(skb); ++ iph = skb_gro_network_header(skb); ++ } else { ++ skb_gro_pull(skb, sizeof(*iph)); + } + ++ skb_set_transport_header(skb, skb_gro_offset(skb)); ++ + NAPI_GRO_CB(skb)->proto = proto; + + flush--; diff --git a/target/linux/generic/backport-6.6/600-v6.9-02-net-gro-fix-udp-bad-offset-in-socket-lookup-by-addin.patch b/target/linux/generic/backport-6.6/600-v6.9-02-net-gro-fix-udp-bad-offset-in-socket-lookup-by-addin.patch new file mode 100644 index 000000000..c5d8497de --- /dev/null +++ b/target/linux/generic/backport-6.6/600-v6.9-02-net-gro-fix-udp-bad-offset-in-socket-lookup-by-addin.patch @@ -0,0 +1,178 @@ +From: Richard Gobert +Date: Tue, 30 Apr 2024 16:35:54 +0200 +Subject: [PATCH] net: gro: fix udp bad offset in socket lookup by adding + {inner_}network_offset to napi_gro_cb + +Commits a602456 ("udp: Add GRO functions to UDP socket") and 57c67ff ("udp: +additional GRO support") introduce incorrect usage of {ip,ipv6}_hdr in the +complete phase of gro. The functions always return skb->network_header, +which in the case of encapsulated packets at the gro complete phase, is +always set to the innermost L3 of the packet. That means that calling +{ip,ipv6}_hdr for skbs which completed the GRO receive phase (both in +gro_list and *_gro_complete) when parsing an encapsulated packet's _outer_ +L3/L4 may return an unexpected value. + +This incorrect usage leads to a bug in GRO's UDP socket lookup. +udp{4,6}_lib_lookup_skb functions use ip_hdr/ipv6_hdr respectively. These +*_hdr functions return network_header which will point to the innermost L3, +resulting in the wrong offset being used in __udp{4,6}_lib_lookup with +encapsulated packets. + +This patch adds network_offset and inner_network_offset to napi_gro_cb, and +makes sure both are set correctly. + +To fix the issue, network_offsets union is used inside napi_gro_cb, in +which both the outer and the inner network offsets are saved. + +Reproduction example: + +Endpoint configuration example (fou + local address bind) + + # ip fou add port 6666 ipproto 4 + # ip link add name tun1 type ipip remote 2.2.2.1 local 2.2.2.2 encap fou encap-dport 5555 encap-sport 6666 mode ipip + # ip link set tun1 up + # ip a add 1.1.1.2/24 dev tun1 + +Netperf TCP_STREAM result on net-next before patch is applied: + +net-next main, GRO enabled: + $ netperf -H 1.1.1.2 -t TCP_STREAM -l 5 + Recv Send Send + Socket Socket Message Elapsed + Size Size Size Time Throughput + bytes bytes bytes secs. 10^6bits/sec + + 131072 16384 16384 5.28 2.37 + +net-next main, GRO disabled: + $ netperf -H 1.1.1.2 -t TCP_STREAM -l 5 + Recv Send Send + Socket Socket Message Elapsed + Size Size Size Time Throughput + bytes bytes bytes secs. 10^6bits/sec + + 131072 16384 16384 5.01 2745.06 + +patch applied, GRO enabled: + $ netperf -H 1.1.1.2 -t TCP_STREAM -l 5 + Recv Send Send + Socket Socket Message Elapsed + Size Size Size Time Throughput + bytes bytes bytes secs. 10^6bits/sec + + 131072 16384 16384 5.01 2877.38 + +Fixes: a6024562ffd7 ("udp: Add GRO functions to UDP socket") +Signed-off-by: Richard Gobert +Reviewed-by: Eric Dumazet +Reviewed-by: Willem de Bruijn +Signed-off-by: Paolo Abeni +--- + +--- a/include/net/gro.h ++++ b/include/net/gro.h +@@ -86,6 +86,15 @@ struct napi_gro_cb { + + /* used to support CHECKSUM_COMPLETE for tunneling protocols */ + __wsum csum; ++ ++ /* L3 offsets */ ++ union { ++ struct { ++ u16 network_offset; ++ u16 inner_network_offset; ++ }; ++ u16 network_offsets[2]; ++ }; + }; + + #define NAPI_GRO_CB(skb) ((struct napi_gro_cb *)(skb)->cb) +--- a/net/8021q/vlan_core.c ++++ b/net/8021q/vlan_core.c +@@ -478,6 +478,8 @@ static struct sk_buff *vlan_gro_receive( + if (unlikely(!vhdr)) + goto out; + ++ NAPI_GRO_CB(skb)->network_offsets[NAPI_GRO_CB(skb)->encap_mark] = hlen; ++ + type = vhdr->h_vlan_encapsulated_proto; + + ptype = gro_find_receive_by_type(type); +--- a/net/core/gro.c ++++ b/net/core/gro.c +@@ -373,6 +373,7 @@ static inline void skb_gro_reset_offset( + const struct skb_shared_info *pinfo = skb_shinfo(skb); + const skb_frag_t *frag0 = &pinfo->frags[0]; + ++ NAPI_GRO_CB(skb)->network_offset = 0; + NAPI_GRO_CB(skb)->data_offset = 0; + NAPI_GRO_CB(skb)->frag0 = NULL; + NAPI_GRO_CB(skb)->frag0_len = 0; +--- a/net/ipv4/af_inet.c ++++ b/net/ipv4/af_inet.c +@@ -1571,6 +1571,7 @@ struct sk_buff *inet_gro_receive(struct + /* The above will be needed by the transport layer if there is one + * immediately following this IP hdr. + */ ++ NAPI_GRO_CB(skb)->inner_network_offset = off; + + /* Note : No need to call skb_gro_postpull_rcsum() here, + * as we already checked checksum over ipv4 header was 0 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -534,7 +534,8 @@ static inline struct sock *__udp4_lib_lo + struct sock *udp4_lib_lookup_skb(const struct sk_buff *skb, + __be16 sport, __be16 dport) + { +- const struct iphdr *iph = ip_hdr(skb); ++ const u16 offset = NAPI_GRO_CB(skb)->network_offsets[skb->encapsulation]; ++ const struct iphdr *iph = (struct iphdr *)(skb->data + offset); + struct net *net = dev_net(skb->dev); + int iif, sdif; + +--- a/net/ipv4/udp_offload.c ++++ b/net/ipv4/udp_offload.c +@@ -718,7 +718,8 @@ EXPORT_SYMBOL(udp_gro_complete); + + INDIRECT_CALLABLE_SCOPE int udp4_gro_complete(struct sk_buff *skb, int nhoff) + { +- const struct iphdr *iph = ip_hdr(skb); ++ const u16 offset = NAPI_GRO_CB(skb)->network_offsets[skb->encapsulation]; ++ const struct iphdr *iph = (struct iphdr *)(skb->data + offset); + struct udphdr *uh = (struct udphdr *)(skb->data + nhoff); + + /* do fraglist only if there is no outer UDP encap (or we already processed it) */ +--- a/net/ipv6/ip6_offload.c ++++ b/net/ipv6/ip6_offload.c +@@ -240,6 +240,7 @@ INDIRECT_CALLABLE_SCOPE struct sk_buff * + goto out; + + skb_set_network_header(skb, off); ++ NAPI_GRO_CB(skb)->inner_network_offset = off; + + flush += ntohs(iph->payload_len) != skb->len - hlen; + +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -275,7 +275,8 @@ static struct sock *__udp6_lib_lookup_sk + struct sock *udp6_lib_lookup_skb(const struct sk_buff *skb, + __be16 sport, __be16 dport) + { +- const struct ipv6hdr *iph = ipv6_hdr(skb); ++ const u16 offset = NAPI_GRO_CB(skb)->network_offsets[skb->encapsulation]; ++ const struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + offset); + struct net *net = dev_net(skb->dev); + int iif, sdif; + +--- a/net/ipv6/udp_offload.c ++++ b/net/ipv6/udp_offload.c +@@ -164,7 +164,8 @@ flush: + + INDIRECT_CALLABLE_SCOPE int udp6_gro_complete(struct sk_buff *skb, int nhoff) + { +- const struct ipv6hdr *ipv6h = ipv6_hdr(skb); ++ const u16 offset = NAPI_GRO_CB(skb)->network_offsets[skb->encapsulation]; ++ const struct ipv6hdr *ipv6h = (struct ipv6hdr *)(skb->data + offset); + struct udphdr *uh = (struct udphdr *)(skb->data + nhoff); + + /* do fraglist only if there is no outer UDP encap (or we already processed it) */ diff --git a/target/linux/generic/backport-6.6/600-v6.9-03-net-gro-add-flush-check-in-udp_gro_receive_segment.patch b/target/linux/generic/backport-6.6/600-v6.9-03-net-gro-add-flush-check-in-udp_gro_receive_segment.patch new file mode 100644 index 000000000..72b76dd93 --- /dev/null +++ b/target/linux/generic/backport-6.6/600-v6.9-03-net-gro-add-flush-check-in-udp_gro_receive_segment.patch @@ -0,0 +1,48 @@ +From: Richard Gobert +Date: Tue, 30 Apr 2024 16:35:55 +0200 +Subject: [PATCH] net: gro: add flush check in udp_gro_receive_segment + +GRO-GSO path is supposed to be transparent and as such L3 flush checks are +relevant to all UDP flows merging in GRO. This patch uses the same logic +and code from tcp_gro_receive, terminating merge if flush is non zero. + +Fixes: e20cf8d3f1f7 ("udp: implement GRO for plain UDP sockets.") +Signed-off-by: Richard Gobert +Reviewed-by: Willem de Bruijn +Signed-off-by: Paolo Abeni +--- + +--- a/net/ipv4/udp_offload.c ++++ b/net/ipv4/udp_offload.c +@@ -471,6 +471,7 @@ static struct sk_buff *udp_gro_receive_s + struct sk_buff *p; + unsigned int ulen; + int ret = 0; ++ int flush; + + /* requires non zero csum, for symmetry with GSO */ + if (!uh->check) { +@@ -504,13 +505,22 @@ static struct sk_buff *udp_gro_receive_s + return p; + } + ++ flush = NAPI_GRO_CB(p)->flush; ++ ++ if (NAPI_GRO_CB(p)->flush_id != 1 || ++ NAPI_GRO_CB(p)->count != 1 || ++ !NAPI_GRO_CB(p)->is_atomic) ++ flush |= NAPI_GRO_CB(p)->flush_id; ++ else ++ NAPI_GRO_CB(p)->is_atomic = false; ++ + /* Terminate the flow on len mismatch or if it grow "too much". + * Under small packet flood GRO count could elsewhere grow a lot + * leading to excessive truesize values. + * On len mismatch merge the first packet shorter than gso_size, + * otherwise complete the GRO packet. + */ +- if (ulen > ntohs(uh2->len)) { ++ if (ulen > ntohs(uh2->len) || flush) { + pp = p; + } else { + if (NAPI_GRO_CB(skb)->is_flist) { diff --git a/target/linux/generic/backport-6.6/740-v6.9-01-netfilter-flowtable-validate-pppoe-header.patch b/target/linux/generic/backport-6.6/740-v6.9-01-netfilter-flowtable-validate-pppoe-header.patch deleted file mode 100644 index 8a8773b71..000000000 --- a/target/linux/generic/backport-6.6/740-v6.9-01-netfilter-flowtable-validate-pppoe-header.patch +++ /dev/null @@ -1,87 +0,0 @@ -From: Pablo Neira Ayuso -Date: Thu, 11 Apr 2024 13:28:59 +0200 -Subject: [PATCH] netfilter: flowtable: validate pppoe header - -Ensure there is sufficient room to access the protocol field of the -PPPoe header. Validate it once before the flowtable lookup, then use a -helper function to access protocol field. - -Reported-by: syzbot+b6f07e1c07ef40199081@syzkaller.appspotmail.com -Fixes: 72efd585f714 ("netfilter: flowtable: add pppoe support") -Signed-off-by: Pablo Neira Ayuso ---- - ---- a/include/net/netfilter/nf_flow_table.h -+++ b/include/net/netfilter/nf_flow_table.h -@@ -335,7 +335,7 @@ int nf_flow_rule_route_ipv6(struct net * - int nf_flow_table_offload_init(void); - void nf_flow_table_offload_exit(void); - --static inline __be16 nf_flow_pppoe_proto(const struct sk_buff *skb) -+static inline __be16 __nf_flow_pppoe_proto(const struct sk_buff *skb) - { - __be16 proto; - -@@ -351,6 +351,16 @@ static inline __be16 nf_flow_pppoe_proto - return 0; - } - -+static inline bool nf_flow_pppoe_proto(struct sk_buff *skb, __be16 *inner_proto) -+{ -+ if (!pskb_may_pull(skb, PPPOE_SES_HLEN)) -+ return false; -+ -+ *inner_proto = __nf_flow_pppoe_proto(skb); -+ -+ return true; -+} -+ - #define NF_FLOW_TABLE_STAT_INC(net, count) __this_cpu_inc((net)->ft.stat->count) - #define NF_FLOW_TABLE_STAT_DEC(net, count) __this_cpu_dec((net)->ft.stat->count) - #define NF_FLOW_TABLE_STAT_INC_ATOMIC(net, count) \ ---- a/net/netfilter/nf_flow_table_inet.c -+++ b/net/netfilter/nf_flow_table_inet.c -@@ -21,7 +21,8 @@ nf_flow_offload_inet_hook(void *priv, st - proto = veth->h_vlan_encapsulated_proto; - break; - case htons(ETH_P_PPP_SES): -- proto = nf_flow_pppoe_proto(skb); -+ if (!nf_flow_pppoe_proto(skb, &proto)) -+ return NF_ACCEPT; - break; - default: - proto = skb->protocol; ---- a/net/netfilter/nf_flow_table_ip.c -+++ b/net/netfilter/nf_flow_table_ip.c -@@ -273,10 +273,11 @@ static unsigned int nf_flow_xmit_xfrm(st - return NF_STOLEN; - } - --static bool nf_flow_skb_encap_protocol(const struct sk_buff *skb, __be16 proto, -+static bool nf_flow_skb_encap_protocol(struct sk_buff *skb, __be16 proto, - u32 *offset) - { - struct vlan_ethhdr *veth; -+ __be16 inner_proto; - - switch (skb->protocol) { - case htons(ETH_P_8021Q): -@@ -287,7 +288,8 @@ static bool nf_flow_skb_encap_protocol(c - } - break; - case htons(ETH_P_PPP_SES): -- if (nf_flow_pppoe_proto(skb) == proto) { -+ if (nf_flow_pppoe_proto(skb, &inner_proto) && -+ inner_proto == proto) { - *offset += PPPOE_SES_HLEN; - return true; - } -@@ -316,7 +318,7 @@ static void nf_flow_encap_pop(struct sk_ - skb_reset_network_header(skb); - break; - case htons(ETH_P_PPP_SES): -- skb->protocol = nf_flow_pppoe_proto(skb); -+ skb->protocol = __nf_flow_pppoe_proto(skb); - skb_pull(skb, PPPOE_SES_HLEN); - skb_reset_network_header(skb); - break; diff --git a/target/linux/generic/backport-6.6/740-v6.9-02-netfilter-flowtable-incorrect-pppoe-tuple.patch b/target/linux/generic/backport-6.6/740-v6.9-02-netfilter-flowtable-incorrect-pppoe-tuple.patch deleted file mode 100644 index 20ac222de..000000000 --- a/target/linux/generic/backport-6.6/740-v6.9-02-netfilter-flowtable-incorrect-pppoe-tuple.patch +++ /dev/null @@ -1,24 +0,0 @@ -From: Pablo Neira Ayuso -Date: Thu, 11 Apr 2024 13:29:00 +0200 -Subject: [PATCH] netfilter: flowtable: incorrect pppoe tuple - -pppoe traffic reaching ingress path does not match the flowtable entry -because the pppoe header is expected to be at the network header offset. -This bug causes a mismatch in the flow table lookup, so pppoe packets -enter the classical forwarding path. - -Fixes: 72efd585f714 ("netfilter: flowtable: add pppoe support") -Signed-off-by: Pablo Neira Ayuso ---- - ---- a/net/netfilter/nf_flow_table_ip.c -+++ b/net/netfilter/nf_flow_table_ip.c -@@ -157,7 +157,7 @@ static void nf_flow_tuple_encap(struct s - tuple->encap[i].proto = skb->protocol; - break; - case htons(ETH_P_PPP_SES): -- phdr = (struct pppoe_hdr *)skb_mac_header(skb); -+ phdr = (struct pppoe_hdr *)skb_network_header(skb); - tuple->encap[i].id = ntohs(phdr->sid); - tuple->encap[i].proto = skb->protocol; - break; diff --git a/target/linux/generic/backport-6.6/752-05-v6.7-net-ethernet-mtk_wed-do-not-assume-offload-callbacks.patch b/target/linux/generic/backport-6.6/752-05-v6.7-net-ethernet-mtk_wed-do-not-assume-offload-callbacks.patch index d6ef40cd5..b9d3582a7 100644 --- a/target/linux/generic/backport-6.6/752-05-v6.7-net-ethernet-mtk_wed-do-not-assume-offload-callbacks.patch +++ b/target/linux/generic/backport-6.6/752-05-v6.7-net-ethernet-mtk_wed-do-not-assume-offload-callbacks.patch @@ -14,7 +14,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/ethernet/mediatek/mtk_wed.c +++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -1713,19 +1713,20 @@ mtk_wed_irq_set_mask(struct mtk_wed_devi +@@ -1709,19 +1709,20 @@ mtk_wed_irq_set_mask(struct mtk_wed_devi int mtk_wed_flow_add(int index) { struct mtk_wed_hw *hw = hw_list[index]; @@ -44,7 +44,7 @@ Signed-off-by: David S. Miller goto out; } -@@ -1744,14 +1745,15 @@ void mtk_wed_flow_remove(int index) +@@ -1740,14 +1741,15 @@ void mtk_wed_flow_remove(int index) { struct mtk_wed_hw *hw = hw_list[index]; diff --git a/target/linux/generic/backport-6.6/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch b/target/linux/generic/backport-6.6/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch index af4600a98..6d1d9a406 100644 --- a/target/linux/generic/backport-6.6/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch +++ b/target/linux/generic/backport-6.6/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch @@ -52,15 +52,15 @@ Signed-off-by: Paolo Abeni wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); @@ -606,7 +606,7 @@ mtk_wed_stop(struct mtk_wed_device *dev) + wdma_w32(dev, MTK_WDMA_INT_MASK, 0); wdma_w32(dev, MTK_WDMA_INT_GRP2, 0); - wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0); - if (dev->hw->version == 1) + if (mtk_wed_is_v1(dev->hw)) return; wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0); -@@ -625,7 +625,7 @@ mtk_wed_deinit(struct mtk_wed_device *de +@@ -624,7 +624,7 @@ mtk_wed_deinit(struct mtk_wed_device *de MTK_WED_CTRL_WED_TX_BM_EN | MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); @@ -69,7 +69,7 @@ Signed-off-by: Paolo Abeni return; wed_clr(dev, MTK_WED_CTRL, -@@ -731,7 +731,7 @@ mtk_wed_bus_init(struct mtk_wed_device * +@@ -730,7 +730,7 @@ mtk_wed_bus_init(struct mtk_wed_device * static void mtk_wed_set_wpdma(struct mtk_wed_device *dev) { @@ -78,7 +78,7 @@ Signed-off-by: Paolo Abeni wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys); } else { mtk_wed_bus_init(dev); -@@ -762,7 +762,7 @@ mtk_wed_hw_init_early(struct mtk_wed_dev +@@ -761,7 +761,7 @@ mtk_wed_hw_init_early(struct mtk_wed_dev MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY; wed_m32(dev, MTK_WED_WDMA_GLO_CFG, mask, set); @@ -87,7 +87,7 @@ Signed-off-by: Paolo Abeni u32 offset = dev->hw->index ? 0x04000400 : 0; wdma_set(dev, MTK_WDMA_GLO_CFG, -@@ -935,7 +935,7 @@ mtk_wed_hw_init(struct mtk_wed_device *d +@@ -934,7 +934,7 @@ mtk_wed_hw_init(struct mtk_wed_device *d wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE); @@ -96,7 +96,7 @@ Signed-off-by: Paolo Abeni wed_w32(dev, MTK_WED_TX_BM_TKID, FIELD_PREP(MTK_WED_TX_BM_TKID_START, dev->wlan.token_start) | -@@ -968,7 +968,7 @@ mtk_wed_hw_init(struct mtk_wed_device *d +@@ -967,7 +967,7 @@ mtk_wed_hw_init(struct mtk_wed_device *d mtk_wed_reset(dev, MTK_WED_RESET_TX_BM); @@ -105,7 +105,7 @@ Signed-off-by: Paolo Abeni wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_TX_BM_EN | MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); -@@ -1218,7 +1218,7 @@ mtk_wed_reset_dma(struct mtk_wed_device +@@ -1217,7 +1217,7 @@ mtk_wed_reset_dma(struct mtk_wed_device } dev->init_done = false; @@ -114,7 +114,7 @@ Signed-off-by: Paolo Abeni return; if (!busy) { -@@ -1344,7 +1344,7 @@ mtk_wed_configure_irq(struct mtk_wed_dev +@@ -1343,7 +1343,7 @@ mtk_wed_configure_irq(struct mtk_wed_dev MTK_WED_CTRL_WED_TX_BM_EN | MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); @@ -123,7 +123,7 @@ Signed-off-by: Paolo Abeni wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, MTK_WED_PCIE_INT_TRIGGER_STATUS); -@@ -1417,7 +1417,7 @@ mtk_wed_dma_enable(struct mtk_wed_device +@@ -1416,7 +1416,7 @@ mtk_wed_dma_enable(struct mtk_wed_device MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | MTK_WDMA_GLO_CFG_RX_INFO2_PRERES); @@ -132,7 +132,7 @@ Signed-off-by: Paolo Abeni wdma_set(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); } else { -@@ -1466,7 +1466,7 @@ mtk_wed_start(struct mtk_wed_device *dev +@@ -1465,7 +1465,7 @@ mtk_wed_start(struct mtk_wed_device *dev mtk_wed_set_ext_int(dev, true); @@ -141,7 +141,7 @@ Signed-off-by: Paolo Abeni u32 val = dev->wlan.wpdma_phys | MTK_PCIE_MIRROR_MAP_EN | FIELD_PREP(MTK_PCIE_MIRROR_MAP_WED_ID, dev->hw->index); -@@ -1551,7 +1551,7 @@ mtk_wed_attach(struct mtk_wed_device *de +@@ -1550,7 +1550,7 @@ mtk_wed_attach(struct mtk_wed_device *de } mtk_wed_hw_init_early(dev); @@ -150,7 +150,7 @@ Signed-off-by: Paolo Abeni regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, BIT(hw->index), 0); } else { -@@ -1619,7 +1619,7 @@ static int +@@ -1618,7 +1618,7 @@ static int mtk_wed_txfree_ring_setup(struct mtk_wed_device *dev, void __iomem *regs) { struct mtk_wed_ring *ring = &dev->txfree_ring; @@ -159,7 +159,7 @@ Signed-off-by: Paolo Abeni /* * For txfree event handling, the same DMA ring is shared between WED -@@ -1677,7 +1677,7 @@ mtk_wed_irq_get(struct mtk_wed_device *d +@@ -1676,7 +1676,7 @@ mtk_wed_irq_get(struct mtk_wed_device *d { u32 val, ext_mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK; @@ -168,7 +168,7 @@ Signed-off-by: Paolo Abeni ext_mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR; else ext_mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH | -@@ -1844,7 +1844,7 @@ mtk_wed_setup_tc(struct mtk_wed_device * +@@ -1840,7 +1840,7 @@ mtk_wed_setup_tc(struct mtk_wed_device * { struct mtk_wed_hw *hw = wed->hw; @@ -177,7 +177,7 @@ Signed-off-by: Paolo Abeni return -EOPNOTSUPP; switch (type) { -@@ -1918,9 +1918,9 @@ void mtk_wed_add_hw(struct device_node * +@@ -1914,9 +1914,9 @@ void mtk_wed_add_hw(struct device_node * hw->wdma = wdma; hw->index = index; hw->irq = irq; diff --git a/target/linux/generic/backport-6.6/752-07-v6.7-net-ethernet-mtk_wed-do-not-configure-rx-offload-if-.patch b/target/linux/generic/backport-6.6/752-07-v6.7-net-ethernet-mtk_wed-do-not-configure-rx-offload-if-.patch index d5bacde32..02ef4e640 100644 --- a/target/linux/generic/backport-6.6/752-07-v6.7-net-ethernet-mtk_wed-do-not-configure-rx-offload-if-.patch +++ b/target/linux/generic/backport-6.6/752-07-v6.7-net-ethernet-mtk_wed-do-not-configure-rx-offload-if-.patch @@ -16,15 +16,15 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/ethernet/mediatek/mtk_wed.c +++ b/drivers/net/ethernet/mediatek/mtk_wed.c @@ -606,7 +606,7 @@ mtk_wed_stop(struct mtk_wed_device *dev) + wdma_w32(dev, MTK_WDMA_INT_MASK, 0); wdma_w32(dev, MTK_WDMA_INT_GRP2, 0); - wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0); - if (mtk_wed_is_v1(dev->hw)) + if (!mtk_wed_get_rx_capa(dev)) return; wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0); -@@ -733,16 +733,21 @@ mtk_wed_set_wpdma(struct mtk_wed_device +@@ -732,16 +732,21 @@ mtk_wed_set_wpdma(struct mtk_wed_device { if (mtk_wed_is_v1(dev->hw)) { wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys); @@ -55,7 +55,7 @@ Signed-off-by: Paolo Abeni } static void -@@ -974,15 +979,17 @@ mtk_wed_hw_init(struct mtk_wed_device *d +@@ -973,15 +978,17 @@ mtk_wed_hw_init(struct mtk_wed_device *d MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); } else { wed_clr(dev, MTK_WED_TX_TKID_CTRL, MTK_WED_TX_TKID_CTRL_PAUSE); @@ -82,7 +82,7 @@ Signed-off-by: Paolo Abeni } wed_clr(dev, MTK_WED_TX_BM_CTRL, MTK_WED_TX_BM_CTRL_PAUSE); -@@ -1354,8 +1361,6 @@ mtk_wed_configure_irq(struct mtk_wed_dev +@@ -1353,8 +1360,6 @@ mtk_wed_configure_irq(struct mtk_wed_dev wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask); } else { @@ -91,7 +91,7 @@ Signed-off-by: Paolo Abeni /* initail tx interrupt trigger */ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX, MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN | -@@ -1374,15 +1379,20 @@ mtk_wed_configure_irq(struct mtk_wed_dev +@@ -1373,15 +1378,20 @@ mtk_wed_configure_irq(struct mtk_wed_dev FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_TRIG, dev->wlan.txfree_tbit)); @@ -121,7 +121,7 @@ Signed-off-by: Paolo Abeni wed_w32(dev, MTK_WED_WDMA_INT_CLR, wdma_mask); wed_set(dev, MTK_WED_WDMA_INT_CTRL, -@@ -1401,6 +1411,8 @@ mtk_wed_configure_irq(struct mtk_wed_dev +@@ -1400,6 +1410,8 @@ mtk_wed_configure_irq(struct mtk_wed_dev static void mtk_wed_dma_enable(struct mtk_wed_device *dev) { @@ -130,7 +130,7 @@ Signed-off-by: Paolo Abeni wed_set(dev, MTK_WED_WPDMA_INT_CTRL, MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV); wed_set(dev, MTK_WED_GLO_CFG, -@@ -1420,33 +1432,33 @@ mtk_wed_dma_enable(struct mtk_wed_device +@@ -1419,33 +1431,33 @@ mtk_wed_dma_enable(struct mtk_wed_device if (mtk_wed_is_v1(dev->hw)) { wdma_set(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); @@ -186,7 +186,7 @@ Signed-off-by: Paolo Abeni } static void -@@ -1473,7 +1485,7 @@ mtk_wed_start(struct mtk_wed_device *dev +@@ -1472,7 +1484,7 @@ mtk_wed_start(struct mtk_wed_device *dev val |= BIT(0) | (BIT(1) * !!dev->hw->index); regmap_write(dev->hw->mirror, dev->hw->index * 4, val); @@ -195,7 +195,7 @@ Signed-off-by: Paolo Abeni /* driver set mid ready and only once */ wed_w32(dev, MTK_WED_EXT_INT_MASK1, MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY); -@@ -1485,7 +1497,6 @@ mtk_wed_start(struct mtk_wed_device *dev +@@ -1484,7 +1496,6 @@ mtk_wed_start(struct mtk_wed_device *dev if (mtk_wed_rro_cfg(dev)) return; @@ -203,7 +203,7 @@ Signed-off-by: Paolo Abeni } mtk_wed_set_512_support(dev, dev->wlan.wcid_512); -@@ -1551,13 +1562,14 @@ mtk_wed_attach(struct mtk_wed_device *de +@@ -1550,13 +1561,14 @@ mtk_wed_attach(struct mtk_wed_device *de } mtk_wed_hw_init_early(dev); diff --git a/target/linux/generic/backport-6.6/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch b/target/linux/generic/backport-6.6/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch index 71b32c545..3e750ec1d 100644 --- a/target/linux/generic/backport-6.6/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch +++ b/target/linux/generic/backport-6.6/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch @@ -38,7 +38,7 @@ Signed-off-by: Paolo Abeni static void wed_m32(struct mtk_wed_device *dev, u32 reg, u32 mask, u32 val) { -@@ -747,7 +767,7 @@ mtk_wed_set_wpdma(struct mtk_wed_device +@@ -746,7 +766,7 @@ mtk_wed_set_wpdma(struct mtk_wed_device return; wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo); @@ -47,7 +47,7 @@ Signed-off-by: Paolo Abeni } static void -@@ -941,22 +961,10 @@ mtk_wed_hw_init(struct mtk_wed_device *d +@@ -940,22 +960,10 @@ mtk_wed_hw_init(struct mtk_wed_device *d wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE); if (mtk_wed_is_v1(dev->hw)) { @@ -70,7 +70,7 @@ Signed-off-by: Paolo Abeni wed_w32(dev, MTK_WED_TX_BM_DYN_THR, FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO_V2, 0) | MTK_WED_TX_BM_DYN_THR_HI_V2); -@@ -971,6 +979,11 @@ mtk_wed_hw_init(struct mtk_wed_device *d +@@ -970,6 +978,11 @@ mtk_wed_hw_init(struct mtk_wed_device *d MTK_WED_TX_TKID_DYN_THR_HI); } @@ -82,7 +82,7 @@ Signed-off-by: Paolo Abeni mtk_wed_reset(dev, MTK_WED_RESET_TX_BM); if (mtk_wed_is_v1(dev->hw)) { -@@ -1105,13 +1118,8 @@ mtk_wed_rx_reset(struct mtk_wed_device * +@@ -1104,13 +1117,8 @@ mtk_wed_rx_reset(struct mtk_wed_device * if (ret) { mtk_wed_reset(dev, MTK_WED_RESET_WED_RX_DMA); } else { @@ -98,7 +98,7 @@ Signed-off-by: Paolo Abeni wed_w32(dev, MTK_WED_RESET_IDX, 0); } -@@ -1164,7 +1172,8 @@ mtk_wed_reset_dma(struct mtk_wed_device +@@ -1163,7 +1171,8 @@ mtk_wed_reset_dma(struct mtk_wed_device if (busy) { mtk_wed_reset(dev, MTK_WED_RESET_WED_TX_DMA); } else { @@ -108,7 +108,7 @@ Signed-off-by: Paolo Abeni wed_w32(dev, MTK_WED_RESET_IDX, 0); } -@@ -1256,7 +1265,6 @@ static int +@@ -1255,7 +1264,6 @@ static int mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size, bool reset) { @@ -116,7 +116,7 @@ Signed-off-by: Paolo Abeni struct mtk_wed_ring *wdma; if (idx >= ARRAY_SIZE(dev->rx_wdma)) -@@ -1264,7 +1272,7 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_we +@@ -1263,7 +1271,7 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_we wdma = &dev->rx_wdma[idx]; if (!reset && mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, @@ -125,7 +125,7 @@ Signed-off-by: Paolo Abeni return -ENOMEM; wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE, -@@ -1285,7 +1293,6 @@ static int +@@ -1284,7 +1292,6 @@ static int mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size, bool reset) { @@ -133,7 +133,7 @@ Signed-off-by: Paolo Abeni struct mtk_wed_ring *wdma; if (idx >= ARRAY_SIZE(dev->tx_wdma)) -@@ -1293,7 +1300,7 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we +@@ -1292,7 +1299,7 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we wdma = &dev->tx_wdma[idx]; if (!reset && mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, @@ -142,7 +142,7 @@ Signed-off-by: Paolo Abeni return -ENOMEM; wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE, -@@ -1932,7 +1939,12 @@ void mtk_wed_add_hw(struct device_node * +@@ -1928,7 +1935,12 @@ void mtk_wed_add_hw(struct device_node * hw->irq = irq; hw->version = eth->soc->version; @@ -156,7 +156,7 @@ Signed-off-by: Paolo Abeni hw->mirror = syscon_regmap_lookup_by_phandle(eth_np, "mediatek,pcie-mirror"); hw->hifsys = syscon_regmap_lookup_by_phandle(eth_np, -@@ -1946,6 +1958,8 @@ void mtk_wed_add_hw(struct device_node * +@@ -1942,6 +1954,8 @@ void mtk_wed_add_hw(struct device_node * regmap_write(hw->mirror, 0, 0); regmap_write(hw->mirror, 4, 0); } diff --git a/target/linux/generic/backport-6.6/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch b/target/linux/generic/backport-6.6/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch index 12733b142..5a271a562 100644 --- a/target/linux/generic/backport-6.6/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch +++ b/target/linux/generic/backport-6.6/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch @@ -302,7 +302,7 @@ Signed-off-by: Paolo Abeni } mtk_wed_set_512_support(dev, false); -@@ -652,6 +699,14 @@ mtk_wed_deinit(struct mtk_wed_device *de +@@ -651,6 +698,14 @@ mtk_wed_deinit(struct mtk_wed_device *de MTK_WED_CTRL_RX_ROUTE_QM_EN | MTK_WED_CTRL_WED_RX_BM_EN | MTK_WED_CTRL_RX_RRO_QM_EN); @@ -317,7 +317,7 @@ Signed-off-by: Paolo Abeni } static void -@@ -701,21 +756,37 @@ mtk_wed_detach(struct mtk_wed_device *de +@@ -700,21 +755,37 @@ mtk_wed_detach(struct mtk_wed_device *de mutex_unlock(&hw_lock); } @@ -362,7 +362,7 @@ Signed-off-by: Paolo Abeni wed_w32(dev, MTK_WED_PCIE_INT_CTRL, FIELD_PREP(MTK_WED_PCIE_INT_CTRL_POLL_EN, 2)); -@@ -723,19 +794,9 @@ mtk_wed_bus_init(struct mtk_wed_device * +@@ -722,19 +793,9 @@ mtk_wed_bus_init(struct mtk_wed_device * /* pcie interrupt control: pola/source selection */ wed_set(dev, MTK_WED_PCIE_INT_CTRL, MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA | @@ -385,7 +385,7 @@ Signed-off-by: Paolo Abeni break; } case MTK_WED_BUS_AXI: -@@ -773,18 +834,19 @@ mtk_wed_set_wpdma(struct mtk_wed_device +@@ -772,18 +833,19 @@ mtk_wed_set_wpdma(struct mtk_wed_device static void mtk_wed_hw_init_early(struct mtk_wed_device *dev) { @@ -412,7 +412,7 @@ Signed-off-by: Paolo Abeni wed_m32(dev, MTK_WED_WDMA_GLO_CFG, mask, set); if (mtk_wed_is_v1(dev->hw)) { -@@ -932,11 +994,18 @@ mtk_wed_route_qm_hw_init(struct mtk_wed_ +@@ -931,11 +993,18 @@ mtk_wed_route_qm_hw_init(struct mtk_wed_ } /* configure RX_ROUTE_QM */ @@ -436,7 +436,7 @@ Signed-off-by: Paolo Abeni /* enable RX_ROUTE_QM */ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN); } -@@ -949,22 +1018,30 @@ mtk_wed_hw_init(struct mtk_wed_device *d +@@ -948,22 +1017,30 @@ mtk_wed_hw_init(struct mtk_wed_device *d dev->init_done = true; mtk_wed_set_ext_int(dev, false); @@ -475,7 +475,7 @@ Signed-off-by: Paolo Abeni wed_w32(dev, MTK_WED_TX_BM_DYN_THR, FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO_V2, 0) | MTK_WED_TX_BM_DYN_THR_HI_V2); -@@ -974,9 +1051,6 @@ mtk_wed_hw_init(struct mtk_wed_device *d +@@ -973,9 +1050,6 @@ mtk_wed_hw_init(struct mtk_wed_device *d dev->tx_buf_ring.size / 128) | FIELD_PREP(MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM, dev->tx_buf_ring.size / 128)); @@ -485,7 +485,7 @@ Signed-off-by: Paolo Abeni } wed_w32(dev, dev->hw->soc->regmap.tx_bm_tkid, -@@ -986,26 +1060,62 @@ mtk_wed_hw_init(struct mtk_wed_device *d +@@ -985,26 +1059,62 @@ mtk_wed_hw_init(struct mtk_wed_device *d mtk_wed_reset(dev, MTK_WED_RESET_TX_BM); @@ -561,7 +561,7 @@ Signed-off-by: Paolo Abeni } static void -@@ -1303,6 +1413,24 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we +@@ -1302,6 +1412,24 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we dev->hw->soc->wdma_desc_size, true)) return -ENOMEM; @@ -586,7 +586,7 @@ Signed-off-by: Paolo Abeni wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE, wdma->desc_phys); wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_COUNT, -@@ -1368,6 +1496,9 @@ mtk_wed_configure_irq(struct mtk_wed_dev +@@ -1367,6 +1495,9 @@ mtk_wed_configure_irq(struct mtk_wed_dev wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask); } else { @@ -596,7 +596,7 @@ Signed-off-by: Paolo Abeni /* initail tx interrupt trigger */ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX, MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN | -@@ -1420,33 +1551,60 @@ mtk_wed_dma_enable(struct mtk_wed_device +@@ -1419,33 +1550,60 @@ mtk_wed_dma_enable(struct mtk_wed_device { int i; @@ -668,7 +668,7 @@ Signed-off-by: Paolo Abeni wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP | MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV); -@@ -1458,11 +1616,22 @@ mtk_wed_dma_enable(struct mtk_wed_device +@@ -1457,11 +1615,22 @@ mtk_wed_dma_enable(struct mtk_wed_device MTK_WED_WDMA_GLO_CFG_TX_DRV_EN | MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK); @@ -693,7 +693,7 @@ Signed-off-by: Paolo Abeni for (i = 0; i < MTK_WED_RX_QUEUES; i++) mtk_wed_check_wfdma_rx_fill(dev, i); -@@ -1502,6 +1671,12 @@ mtk_wed_start(struct mtk_wed_device *dev +@@ -1501,6 +1670,12 @@ mtk_wed_start(struct mtk_wed_device *dev wed_r32(dev, MTK_WED_EXT_INT_MASK1); wed_r32(dev, MTK_WED_EXT_INT_MASK2); @@ -706,7 +706,7 @@ Signed-off-by: Paolo Abeni if (mtk_wed_rro_cfg(dev)) return; } -@@ -1553,6 +1728,7 @@ mtk_wed_attach(struct mtk_wed_device *de +@@ -1552,6 +1727,7 @@ mtk_wed_attach(struct mtk_wed_device *de dev->irq = hw->irq; dev->wdma_idx = hw->index; dev->version = hw->version; @@ -714,7 +714,7 @@ Signed-off-by: Paolo Abeni if (hw->eth->dma_dev == hw->eth->dev && of_dma_is_coherent(hw->eth->dev->of_node)) -@@ -1620,6 +1796,23 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev +@@ -1619,6 +1795,23 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev ring->reg_base = MTK_WED_RING_TX(idx); ring->wpdma = regs; @@ -738,7 +738,7 @@ Signed-off-by: Paolo Abeni /* WED -> WPDMA */ wpdma_tx_w32(dev, idx, MTK_WED_RING_OFS_BASE, ring->desc_phys); wpdma_tx_w32(dev, idx, MTK_WED_RING_OFS_COUNT, MTK_WED_TX_RING_SIZE); -@@ -1694,15 +1887,13 @@ mtk_wed_rx_ring_setup(struct mtk_wed_dev +@@ -1693,15 +1886,13 @@ mtk_wed_rx_ring_setup(struct mtk_wed_dev static u32 mtk_wed_irq_get(struct mtk_wed_device *dev, u32 mask) { @@ -759,7 +759,7 @@ Signed-off-by: Paolo Abeni val = wed_r32(dev, MTK_WED_EXT_INT_STATUS); wed_w32(dev, MTK_WED_EXT_INT_STATUS, val); -@@ -1943,6 +2134,9 @@ void mtk_wed_add_hw(struct device_node * +@@ -1939,6 +2130,9 @@ void mtk_wed_add_hw(struct device_node * case 2: hw->soc = &mt7986_data; break; diff --git a/target/linux/generic/backport-6.6/752-15-v6.7-net-ethernet-mtk_wed-refactor-mtk_wed_check_wfdma_rx.patch b/target/linux/generic/backport-6.6/752-15-v6.7-net-ethernet-mtk_wed-refactor-mtk_wed_check_wfdma_rx.patch index 5e12343de..aa2f952b8 100644 --- a/target/linux/generic/backport-6.6/752-15-v6.7-net-ethernet-mtk_wed-refactor-mtk_wed_check_wfdma_rx.patch +++ b/target/linux/generic/backport-6.6/752-15-v6.7-net-ethernet-mtk_wed-refactor-mtk_wed_check_wfdma_rx.patch @@ -56,7 +56,7 @@ Signed-off-by: Paolo Abeni } static void -@@ -1546,6 +1537,7 @@ mtk_wed_configure_irq(struct mtk_wed_dev +@@ -1545,6 +1536,7 @@ mtk_wed_configure_irq(struct mtk_wed_dev wed_w32(dev, MTK_WED_INT_MASK, irq_mask); } @@ -64,7 +64,7 @@ Signed-off-by: Paolo Abeni static void mtk_wed_dma_enable(struct mtk_wed_device *dev) { -@@ -1633,8 +1625,26 @@ mtk_wed_dma_enable(struct mtk_wed_device +@@ -1632,8 +1624,26 @@ mtk_wed_dma_enable(struct mtk_wed_device wdma_set(dev, MTK_WDMA_WRBK_TX_CFG, MTK_WDMA_WRBK_TX_CFG_WRBK_EN); } diff --git a/target/linux/generic/backport-6.6/752-16-v6.7-net-ethernet-mtk_wed-introduce-partial-AMSDU-offload.patch b/target/linux/generic/backport-6.6/752-16-v6.7-net-ethernet-mtk_wed-introduce-partial-AMSDU-offload.patch index f70886aa0..4e72ea128 100644 --- a/target/linux/generic/backport-6.6/752-16-v6.7-net-ethernet-mtk_wed-introduce-partial-AMSDU-offload.patch +++ b/target/linux/generic/backport-6.6/752-16-v6.7-net-ethernet-mtk_wed-introduce-partial-AMSDU-offload.patch @@ -248,7 +248,7 @@ Signed-off-by: Paolo Abeni mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev) { u32 desc_size = dev->hw->soc->tx_ring_desc_size; -@@ -709,6 +840,7 @@ __mtk_wed_detach(struct mtk_wed_device * +@@ -708,6 +839,7 @@ __mtk_wed_detach(struct mtk_wed_device * mtk_wdma_rx_reset(dev); mtk_wed_reset(dev, MTK_WED_RESET_WED); @@ -256,7 +256,7 @@ Signed-off-by: Paolo Abeni mtk_wed_free_tx_buffer(dev); mtk_wed_free_tx_rings(dev); -@@ -1129,23 +1261,6 @@ mtk_wed_ring_reset(struct mtk_wed_ring * +@@ -1128,23 +1260,6 @@ mtk_wed_ring_reset(struct mtk_wed_ring * } } @@ -280,7 +280,7 @@ Signed-off-by: Paolo Abeni static int mtk_wed_rx_reset(struct mtk_wed_device *dev) { -@@ -1692,6 +1807,7 @@ mtk_wed_start(struct mtk_wed_device *dev +@@ -1691,6 +1806,7 @@ mtk_wed_start(struct mtk_wed_device *dev } mtk_wed_set_512_support(dev, dev->wlan.wcid_512); @@ -288,7 +288,7 @@ Signed-off-by: Paolo Abeni mtk_wed_dma_enable(dev); dev->running = true; -@@ -1748,6 +1864,10 @@ mtk_wed_attach(struct mtk_wed_device *de +@@ -1747,6 +1863,10 @@ mtk_wed_attach(struct mtk_wed_device *de if (ret) goto out; diff --git a/target/linux/generic/backport-6.6/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch b/target/linux/generic/backport-6.6/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch index 5c3015c33..f035f8fc0 100644 --- a/target/linux/generic/backport-6.6/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch +++ b/target/linux/generic/backport-6.6/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch @@ -173,7 +173,7 @@ Signed-off-by: Paolo Abeni } static void -@@ -935,6 +1056,8 @@ mtk_wed_bus_init(struct mtk_wed_device * +@@ -934,6 +1055,8 @@ mtk_wed_bus_init(struct mtk_wed_device * static void mtk_wed_set_wpdma(struct mtk_wed_device *dev) { @@ -182,7 +182,7 @@ Signed-off-by: Paolo Abeni if (mtk_wed_is_v1(dev->hw)) { wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys); return; -@@ -952,6 +1075,15 @@ mtk_wed_set_wpdma(struct mtk_wed_device +@@ -951,6 +1074,15 @@ mtk_wed_set_wpdma(struct mtk_wed_device wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo); wed_w32(dev, dev->hw->soc->regmap.wpdma_rx_ring0, dev->wlan.wpdma_rx); @@ -198,7 +198,7 @@ Signed-off-by: Paolo Abeni } static void -@@ -1763,6 +1895,165 @@ mtk_wed_dma_enable(struct mtk_wed_device +@@ -1762,6 +1894,165 @@ mtk_wed_dma_enable(struct mtk_wed_device } static void @@ -364,7 +364,7 @@ Signed-off-by: Paolo Abeni mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask) { int i; -@@ -2216,6 +2507,10 @@ void mtk_wed_add_hw(struct device_node * +@@ -2212,6 +2503,10 @@ void mtk_wed_add_hw(struct device_node * .detach = mtk_wed_detach, .ppe_check = mtk_wed_ppe_check, .setup_tc = mtk_wed_setup_tc, diff --git a/target/linux/generic/backport-6.6/752-20-v6.7-net-ethernet-mtk_wed-add-wed-3.0-reset-support.patch b/target/linux/generic/backport-6.6/752-20-v6.7-net-ethernet-mtk_wed-add-wed-3.0-reset-support.patch index 18aa4107d..7dad2102a 100644 --- a/target/linux/generic/backport-6.6/752-20-v6.7-net-ethernet-mtk_wed-add-wed-3.0-reset-support.patch +++ b/target/linux/generic/backport-6.6/752-20-v6.7-net-ethernet-mtk_wed-add-wed-3.0-reset-support.patch @@ -205,7 +205,7 @@ Signed-off-by: Paolo Abeni wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX); wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); -@@ -1406,13 +1570,33 @@ mtk_wed_rx_reset(struct mtk_wed_device * +@@ -1405,13 +1569,33 @@ mtk_wed_rx_reset(struct mtk_wed_device * if (ret) return ret; @@ -239,7 +239,7 @@ Signed-off-by: Paolo Abeni wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, MTK_WED_WPDMA_RX_D_RST_CRX_IDX | MTK_WED_WPDMA_RX_D_RST_DRV_IDX); -@@ -1440,23 +1624,52 @@ mtk_wed_rx_reset(struct mtk_wed_device * +@@ -1439,23 +1623,52 @@ mtk_wed_rx_reset(struct mtk_wed_device * wed_w32(dev, MTK_WED_RROQM_RST_IDX, 0); } @@ -298,7 +298,7 @@ Signed-off-by: Paolo Abeni mtk_wed_reset(dev, MTK_WED_RESET_WDMA_TX_DRV); /* reset wed rx dma */ -@@ -1477,6 +1690,14 @@ mtk_wed_rx_reset(struct mtk_wed_device * +@@ -1476,6 +1689,14 @@ mtk_wed_rx_reset(struct mtk_wed_device * MTK_WED_CTRL_WED_RX_BM_BUSY); mtk_wed_reset(dev, MTK_WED_RESET_RX_BM); @@ -313,7 +313,7 @@ Signed-off-by: Paolo Abeni /* wo change to enable state */ val = MTK_WED_WO_STATE_ENABLE; ret = mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, -@@ -1494,6 +1715,7 @@ mtk_wed_rx_reset(struct mtk_wed_device * +@@ -1493,6 +1714,7 @@ mtk_wed_rx_reset(struct mtk_wed_device * false); } mtk_wed_free_rx_buffer(dev); @@ -321,7 +321,7 @@ Signed-off-by: Paolo Abeni return 0; } -@@ -1527,15 +1749,41 @@ mtk_wed_reset_dma(struct mtk_wed_device +@@ -1526,15 +1748,41 @@ mtk_wed_reset_dma(struct mtk_wed_device /* 2. reset WDMA rx DMA */ busy = !!mtk_wdma_rx_reset(dev); @@ -364,7 +364,7 @@ Signed-off-by: Paolo Abeni wed_w32(dev, MTK_WED_WDMA_RESET_IDX, MTK_WED_WDMA_RESET_IDX_RX | MTK_WED_WDMA_RESET_IDX_DRV); wed_w32(dev, MTK_WED_WDMA_RESET_IDX, 0); -@@ -1551,8 +1799,13 @@ mtk_wed_reset_dma(struct mtk_wed_device +@@ -1550,8 +1798,13 @@ mtk_wed_reset_dma(struct mtk_wed_device wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); for (i = 0; i < 100; i++) { @@ -380,7 +380,7 @@ Signed-off-by: Paolo Abeni break; } -@@ -1574,6 +1827,8 @@ mtk_wed_reset_dma(struct mtk_wed_device +@@ -1573,6 +1826,8 @@ mtk_wed_reset_dma(struct mtk_wed_device mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT); mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_TX_DRV); mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_RX_DRV); @@ -389,7 +389,7 @@ Signed-off-by: Paolo Abeni } else { wed_w32(dev, MTK_WED_WPDMA_RESET_IDX, MTK_WED_WPDMA_RESET_IDX_TX | -@@ -1590,7 +1845,14 @@ mtk_wed_reset_dma(struct mtk_wed_device +@@ -1589,7 +1844,14 @@ mtk_wed_reset_dma(struct mtk_wed_device wed_w32(dev, MTK_WED_RESET_IDX, 0); } @@ -405,7 +405,7 @@ Signed-off-by: Paolo Abeni } static int -@@ -1842,6 +2104,7 @@ mtk_wed_dma_enable(struct mtk_wed_device +@@ -1841,6 +2103,7 @@ mtk_wed_dma_enable(struct mtk_wed_device MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNS_VER_FORCE_4); wdma_set(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN); @@ -413,7 +413,7 @@ Signed-off-by: Paolo Abeni } wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, -@@ -1905,6 +2168,12 @@ mtk_wed_start_hw_rro(struct mtk_wed_devi +@@ -1904,6 +2167,12 @@ mtk_wed_start_hw_rro(struct mtk_wed_devi if (!mtk_wed_get_rx_capa(dev) || !dev->wlan.hw_rro) return; diff --git a/target/linux/generic/backport-6.6/771-v6.7-01-net-stmmac-improve-TX-timer-arm-logic.patch b/target/linux/generic/backport-6.6/771-v6.7-01-net-stmmac-improve-TX-timer-arm-logic.patch index 3951715fc..a7da409ae 100644 --- a/target/linux/generic/backport-6.6/771-v6.7-01-net-stmmac-improve-TX-timer-arm-logic.patch +++ b/target/linux/generic/backport-6.6/771-v6.7-01-net-stmmac-improve-TX-timer-arm-logic.patch @@ -46,7 +46,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -3003,13 +3003,25 @@ static void stmmac_tx_timer_arm(struct s +@@ -2988,13 +2988,25 @@ static void stmmac_tx_timer_arm(struct s { struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; u32 tx_coal_timer = priv->tx_coal_timer[queue]; diff --git a/target/linux/generic/backport-6.6/771-v6.7-02-net-stmmac-move-TX-timer-arm-after-DMA-enable.patch b/target/linux/generic/backport-6.6/771-v6.7-02-net-stmmac-move-TX-timer-arm-after-DMA-enable.patch index ce39895b4..60dfe4c03 100644 --- a/target/linux/generic/backport-6.6/771-v6.7-02-net-stmmac-move-TX-timer-arm-after-DMA-enable.patch +++ b/target/linux/generic/backport-6.6/771-v6.7-02-net-stmmac-move-TX-timer-arm-after-DMA-enable.patch @@ -18,7 +18,7 @@ Signed-off-by: Paolo Abeni --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -2551,9 +2551,13 @@ static void stmmac_bump_dma_threshold(st +@@ -2536,9 +2536,13 @@ static void stmmac_bump_dma_threshold(st * @priv: driver private structure * @budget: napi budget limiting this functions packet handling * @queue: TX queue index @@ -33,7 +33,7 @@ Signed-off-by: Paolo Abeni { struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[queue]; -@@ -2713,7 +2717,7 @@ static int stmmac_tx_clean(struct stmmac +@@ -2698,7 +2702,7 @@ static int stmmac_tx_clean(struct stmmac /* We still have pending packets, let's call for a new scheduling */ if (tx_q->dirty_tx != tx_q->cur_tx) @@ -42,7 +42,7 @@ Signed-off-by: Paolo Abeni u64_stats_update_begin(&txq_stats->napi_syncp); u64_stats_add(&txq_stats->napi.tx_packets, tx_packets); -@@ -5605,6 +5609,7 @@ static int stmmac_napi_poll_tx(struct na +@@ -5590,6 +5594,7 @@ static int stmmac_napi_poll_tx(struct na container_of(napi, struct stmmac_channel, tx_napi); struct stmmac_priv *priv = ch->priv_data; struct stmmac_txq_stats *txq_stats; @@ -50,7 +50,7 @@ Signed-off-by: Paolo Abeni u32 chan = ch->index; int work_done; -@@ -5613,7 +5618,7 @@ static int stmmac_napi_poll_tx(struct na +@@ -5598,7 +5603,7 @@ static int stmmac_napi_poll_tx(struct na u64_stats_inc(&txq_stats->napi.poll); u64_stats_update_end(&txq_stats->napi_syncp); @@ -59,7 +59,7 @@ Signed-off-by: Paolo Abeni work_done = min(work_done, budget); if (work_done < budget && napi_complete_done(napi, work_done)) { -@@ -5624,6 +5629,10 @@ static int stmmac_napi_poll_tx(struct na +@@ -5609,6 +5614,10 @@ static int stmmac_napi_poll_tx(struct na spin_unlock_irqrestore(&ch->lock, flags); } @@ -70,7 +70,7 @@ Signed-off-by: Paolo Abeni return work_done; } -@@ -5632,6 +5641,7 @@ static int stmmac_napi_poll_rxtx(struct +@@ -5617,6 +5626,7 @@ static int stmmac_napi_poll_rxtx(struct struct stmmac_channel *ch = container_of(napi, struct stmmac_channel, rxtx_napi); struct stmmac_priv *priv = ch->priv_data; @@ -78,7 +78,7 @@ Signed-off-by: Paolo Abeni int rx_done, tx_done, rxtx_done; struct stmmac_rxq_stats *rxq_stats; struct stmmac_txq_stats *txq_stats; -@@ -5647,7 +5657,7 @@ static int stmmac_napi_poll_rxtx(struct +@@ -5632,7 +5642,7 @@ static int stmmac_napi_poll_rxtx(struct u64_stats_inc(&txq_stats->napi.poll); u64_stats_update_end(&txq_stats->napi_syncp); @@ -87,7 +87,7 @@ Signed-off-by: Paolo Abeni tx_done = min(tx_done, budget); rx_done = stmmac_rx_zc(priv, budget, chan); -@@ -5672,6 +5682,10 @@ static int stmmac_napi_poll_rxtx(struct +@@ -5657,6 +5667,10 @@ static int stmmac_napi_poll_rxtx(struct spin_unlock_irqrestore(&ch->lock, flags); } diff --git a/target/linux/generic/hack-6.1/600-bridge_offload.patch b/target/linux/generic/hack-6.1/600-bridge_offload.patch index 0fe560484..e6b8879e1 100644 --- a/target/linux/generic/hack-6.1/600-bridge_offload.patch +++ b/target/linux/generic/hack-6.1/600-bridge_offload.patch @@ -179,7 +179,7 @@ Subject: [PATCH] net/bridge: add bridge offload 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 +@@ -194,6 +195,7 @@ int br_handle_frame_finish(struct net *n dst->used = now; br_forward(dst->dst, skb, local_rcv, false); } else { @@ -187,7 +187,7 @@ Subject: [PATCH] net/bridge: add bridge offload 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 +@@ -327,6 +329,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); @@ -686,7 +686,7 @@ Subject: [PATCH] net/bridge: add bridge offload #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 { +@@ -566,6 +582,10 @@ struct br_input_skb_cb { #ifdef CONFIG_NETFILTER_FAMILY_BRIDGE u8 br_netfilter_broute:1; #endif diff --git a/target/linux/generic/hack-6.1/600-net-enable-fraglist-GRO-by-default.patch b/target/linux/generic/hack-6.1/600-net-enable-fraglist-GRO-by-default.patch new file mode 100644 index 000000000..51f990039 --- /dev/null +++ b/target/linux/generic/hack-6.1/600-net-enable-fraglist-GRO-by-default.patch @@ -0,0 +1,24 @@ +From: Felix Fietkau +Date: Tue, 23 Apr 2024 12:35:21 +0200 +Subject: [PATCH] net: enable fraglist GRO by default + +This can significantly improve performance for packet forwarding/bridging + +Signed-off-by: Felix Fietkau +--- + +--- a/include/linux/netdev_features.h ++++ b/include/linux/netdev_features.h +@@ -242,10 +242,10 @@ static inline int find_next_netdev_featu + #define NETIF_F_UPPER_DISABLES NETIF_F_LRO + + /* changeable features with no special hardware requirements */ +-#define NETIF_F_SOFT_FEATURES (NETIF_F_GSO | NETIF_F_GRO) ++#define NETIF_F_SOFT_FEATURES (NETIF_F_GSO | NETIF_F_GRO | NETIF_F_GRO_FRAGLIST) + + /* Changeable features with no special hardware requirements that defaults to off. */ +-#define NETIF_F_SOFT_FEATURES_OFF (NETIF_F_GRO_FRAGLIST | NETIF_F_GRO_UDP_FWD) ++#define NETIF_F_SOFT_FEATURES_OFF (NETIF_F_GRO_UDP_FWD) + + #define NETIF_F_VLAN_FEATURES (NETIF_F_HW_VLAN_CTAG_FILTER | \ + NETIF_F_HW_VLAN_CTAG_RX | \ diff --git a/target/linux/generic/hack-6.1/601-of_net-add-mac-address-ascii-support.patch b/target/linux/generic/hack-6.1/601-of_net-add-mac-address-ascii-support.patch index bb4312de9..366e1f65c 100644 --- a/target/linux/generic/hack-6.1/601-of_net-add-mac-address-ascii-support.patch +++ b/target/linux/generic/hack-6.1/601-of_net-add-mac-address-ascii-support.patch @@ -11,7 +11,7 @@ Submitted-by: Yousong Zhou --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c -@@ -531,6 +531,63 @@ int eth_platform_get_mac_address(struct +@@ -505,6 +505,63 @@ int eth_platform_get_mac_address(struct } EXPORT_SYMBOL(eth_platform_get_mac_address); @@ -75,7 +75,7 @@ Submitted-by: Yousong Zhou /** * platform_get_ethdev_address - Set netdev's MAC address from a given device * @dev: Pointer to the device -@@ -564,19 +621,23 @@ int nvmem_get_mac_address(struct device +@@ -538,19 +595,23 @@ int nvmem_get_mac_address(struct device { struct nvmem_cell *cell; const void *mac; diff --git a/target/linux/generic/hack-6.1/721-net-add-packet-mangeling.patch b/target/linux/generic/hack-6.1/721-net-add-packet-mangeling.patch index b09c06f32..53044e2b3 100644 --- a/target/linux/generic/hack-6.1/721-net-add-packet-mangeling.patch +++ b/target/linux/generic/hack-6.1/721-net-add-packet-mangeling.patch @@ -47,7 +47,7 @@ Signed-off-by: Felix Fietkau const struct header_ops *header_ops; unsigned char operstate; -@@ -2184,6 +2191,10 @@ struct net_device { +@@ -2182,6 +2189,10 @@ struct net_device { struct mctp_dev __rcu *mctp_ptr; #endif @@ -60,7 +60,7 @@ Signed-off-by: Felix Fietkau */ --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h -@@ -3046,6 +3046,10 @@ static inline int pskb_trim(struct sk_bu +@@ -3045,6 +3045,10 @@ static inline int pskb_trim(struct sk_bu return (len < skb->len) ? __pskb_trim(skb, len) : 0; } @@ -71,7 +71,7 @@ Signed-off-by: Felix Fietkau /** * pskb_trim_unique - remove end from a paged unique (not cloned) buffer * @skb: buffer to alter -@@ -3195,16 +3199,6 @@ static inline struct sk_buff *dev_alloc_ +@@ -3194,16 +3198,6 @@ static inline struct sk_buff *dev_alloc_ } @@ -152,7 +152,7 @@ Signed-off-by: Felix Fietkau { --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c -@@ -171,6 +171,12 @@ __be16 eth_type_trans(struct sk_buff *sk +@@ -159,6 +159,12 @@ __be16 eth_type_trans(struct sk_buff *sk const struct ethhdr *eth; skb->dev = dev; diff --git a/target/linux/generic/hack-6.1/780-usb-net-MeigLink_modem_support.patch b/target/linux/generic/hack-6.1/780-usb-net-MeigLink_modem_support.patch index dfbe88e8e..2729a0ec3 100644 --- a/target/linux/generic/hack-6.1/780-usb-net-MeigLink_modem_support.patch +++ b/target/linux/generic/hack-6.1/780-usb-net-MeigLink_modem_support.patch @@ -43,7 +43,7 @@ Subject: [PATCH] net/usb/qmi_wwan: add MeigLink modem support #define QUECTEL_VENDOR_ID 0x2c7c /* These Quectel products use Quectel's vendor ID */ -@@ -1152,6 +1157,11 @@ static const struct usb_device_id option +@@ -1156,6 +1161,11 @@ static const struct usb_device_id option { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000), /* SIMCom SIM5218 */ .driver_info = NCTRL(0) | NCTRL(1) | NCTRL(2) | NCTRL(3) | RSVD(4) }, @@ -55,7 +55,7 @@ Subject: [PATCH] net/usb/qmi_wwan: add MeigLink modem support /* Quectel products using Qualcomm vendor ID */ { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC15)}, { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC20), -@@ -1193,6 +1203,11 @@ static const struct usb_device_id option +@@ -1197,6 +1207,11 @@ static const struct usb_device_id option .driver_info = ZLP }, { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96), .driver_info = RSVD(4) }, diff --git a/target/linux/generic/hack-6.1/901-debloat_sock_diag.patch b/target/linux/generic/hack-6.1/901-debloat_sock_diag.patch index 4f2c26438..c1a36b613 100644 --- a/target/linux/generic/hack-6.1/901-debloat_sock_diag.patch +++ b/target/linux/generic/hack-6.1/901-debloat_sock_diag.patch @@ -60,7 +60,7 @@ Signed-off-by: Felix Fietkau static void sock_def_write_space_wfree(struct sock *sk); static void sock_def_write_space(struct sock *sk); -@@ -585,6 +587,18 @@ discard_and_relse: +@@ -586,6 +588,18 @@ discard_and_relse: } EXPORT_SYMBOL(__sk_receive_skb); @@ -79,7 +79,7 @@ Signed-off-by: Felix Fietkau INDIRECT_CALLABLE_DECLARE(struct dst_entry *ip6_dst_check(struct dst_entry *, u32)); INDIRECT_CALLABLE_DECLARE(struct dst_entry *ipv4_dst_check(struct dst_entry *, -@@ -2188,9 +2202,11 @@ static void __sk_free(struct sock *sk) +@@ -2189,9 +2203,11 @@ static void __sk_free(struct sock *sk) if (likely(sk->sk_net_refcnt)) sock_inuse_add(sock_net(sk), -1); diff --git a/target/linux/generic/hack-6.1/902-debloat_proc.patch b/target/linux/generic/hack-6.1/902-debloat_proc.patch index ff0ee4884..322f2622b 100644 --- a/target/linux/generic/hack-6.1/902-debloat_proc.patch +++ b/target/linux/generic/hack-6.1/902-debloat_proc.patch @@ -330,7 +330,7 @@ Signed-off-by: Felix Fietkau --- a/net/core/sock.c +++ b/net/core/sock.c -@@ -4114,6 +4114,8 @@ static __net_initdata struct pernet_oper +@@ -4115,6 +4115,8 @@ static __net_initdata struct pernet_oper static int __init proto_init(void) { diff --git a/target/linux/generic/hack-6.1/930-usb-net-for-fm350.patch b/target/linux/generic/hack-6.1/930-usb-net-for-fm350.patch index cb73be972..cb59cdff5 100644 --- a/target/linux/generic/hack-6.1/930-usb-net-for-fm350.patch +++ b/target/linux/generic/hack-6.1/930-usb-net-for-fm350.patch @@ -1,6 +1,6 @@ --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c -@@ -642,6 +642,7 @@ static void option_instat_callback(struc +@@ -646,6 +646,7 @@ static void option_instat_callback(struc static const struct usb_device_id option_ids[] = { @@ -8,7 +8,7 @@ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_LIGHT) }, -@@ -2385,6 +2386,15 @@ static int option_probe(struct usb_seria +@@ -2423,6 +2424,15 @@ static int option_probe(struct usb_seria if (device_flags & NUMEP2 && iface_desc->bNumEndpoints != 2) return -ENODEV; diff --git a/target/linux/generic/hack-6.1/953-net-patch-linux-kernel-to-support-shortcut-fe.patch b/target/linux/generic/hack-6.1/953-net-patch-linux-kernel-to-support-shortcut-fe.patch index 72e5d3c95..bc089c851 100644 --- a/target/linux/generic/hack-6.1/953-net-patch-linux-kernel-to-support-shortcut-fe.patch +++ b/target/linux/generic/hack-6.1/953-net-patch-linux-kernel-to-support-shortcut-fe.patch @@ -12,7 +12,7 @@ struct list_head *br_ip_list); --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h -@@ -990,6 +990,10 @@ struct sk_buff { +@@ -989,6 +989,10 @@ struct sk_buff { __u8 csum_not_inet:1; __u8 scm_io_uring:1; diff --git a/target/linux/generic/hack-6.6/600-net-enable-fraglist-GRO-by-default.patch b/target/linux/generic/hack-6.6/600-net-enable-fraglist-GRO-by-default.patch new file mode 100644 index 000000000..51f990039 --- /dev/null +++ b/target/linux/generic/hack-6.6/600-net-enable-fraglist-GRO-by-default.patch @@ -0,0 +1,24 @@ +From: Felix Fietkau +Date: Tue, 23 Apr 2024 12:35:21 +0200 +Subject: [PATCH] net: enable fraglist GRO by default + +This can significantly improve performance for packet forwarding/bridging + +Signed-off-by: Felix Fietkau +--- + +--- a/include/linux/netdev_features.h ++++ b/include/linux/netdev_features.h +@@ -242,10 +242,10 @@ static inline int find_next_netdev_featu + #define NETIF_F_UPPER_DISABLES NETIF_F_LRO + + /* changeable features with no special hardware requirements */ +-#define NETIF_F_SOFT_FEATURES (NETIF_F_GSO | NETIF_F_GRO) ++#define NETIF_F_SOFT_FEATURES (NETIF_F_GSO | NETIF_F_GRO | NETIF_F_GRO_FRAGLIST) + + /* Changeable features with no special hardware requirements that defaults to off. */ +-#define NETIF_F_SOFT_FEATURES_OFF (NETIF_F_GRO_FRAGLIST | NETIF_F_GRO_UDP_FWD) ++#define NETIF_F_SOFT_FEATURES_OFF (NETIF_F_GRO_UDP_FWD) + + #define NETIF_F_VLAN_FEATURES (NETIF_F_HW_VLAN_CTAG_FILTER | \ + NETIF_F_HW_VLAN_CTAG_RX | \ diff --git a/target/linux/generic/hack-6.6/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch b/target/linux/generic/hack-6.6/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch index 6a2c60107..69e19c3b4 100644 --- a/target/linux/generic/hack-6.6/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch +++ b/target/linux/generic/hack-6.6/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch @@ -9,7 +9,7 @@ Subject: [PATCH] net/dsa/mv88e6xxx: disable ATU violation --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -3305,6 +3305,9 @@ static int mv88e6xxx_setup_port(struct m +@@ -3353,6 +3353,9 @@ static int mv88e6xxx_setup_port(struct m else reg = 1 << port; diff --git a/target/linux/generic/hack-6.6/780-usb-net-MeigLink_modem_support.patch b/target/linux/generic/hack-6.6/780-usb-net-MeigLink_modem_support.patch index 9b2ecba1c..d010231e4 100644 --- a/target/linux/generic/hack-6.6/780-usb-net-MeigLink_modem_support.patch +++ b/target/linux/generic/hack-6.6/780-usb-net-MeigLink_modem_support.patch @@ -43,7 +43,7 @@ Subject: [PATCH] net/usb/qmi_wwan: add MeigLink modem support #define QUECTEL_VENDOR_ID 0x2c7c /* These Quectel products use Quectel's vendor ID */ -@@ -1152,6 +1157,11 @@ static const struct usb_device_id option +@@ -1156,6 +1161,11 @@ static const struct usb_device_id option { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000), /* SIMCom SIM5218 */ .driver_info = NCTRL(0) | NCTRL(1) | NCTRL(2) | NCTRL(3) | RSVD(4) }, @@ -55,7 +55,7 @@ Subject: [PATCH] net/usb/qmi_wwan: add MeigLink modem support /* Quectel products using Qualcomm vendor ID */ { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC15)}, { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC20), -@@ -1193,6 +1203,11 @@ static const struct usb_device_id option +@@ -1197,6 +1207,11 @@ static const struct usb_device_id option .driver_info = ZLP }, { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96), .driver_info = RSVD(4) }, diff --git a/target/linux/generic/hack-6.6/901-debloat_sock_diag.patch b/target/linux/generic/hack-6.6/901-debloat_sock_diag.patch index b0054da2e..af000f76f 100644 --- a/target/linux/generic/hack-6.6/901-debloat_sock_diag.patch +++ b/target/linux/generic/hack-6.6/901-debloat_sock_diag.patch @@ -61,7 +61,7 @@ Signed-off-by: Felix Fietkau static void sock_def_write_space_wfree(struct sock *sk); static void sock_def_write_space(struct sock *sk); -@@ -589,6 +591,21 @@ discard_and_relse: +@@ -590,6 +592,21 @@ discard_and_relse: } EXPORT_SYMBOL(__sk_receive_skb); @@ -83,7 +83,7 @@ Signed-off-by: Felix Fietkau INDIRECT_CALLABLE_DECLARE(struct dst_entry *ip6_dst_check(struct dst_entry *, u32)); INDIRECT_CALLABLE_DECLARE(struct dst_entry *ipv4_dst_check(struct dst_entry *, -@@ -2246,9 +2263,11 @@ static void __sk_free(struct sock *sk) +@@ -2247,9 +2264,11 @@ static void __sk_free(struct sock *sk) if (likely(sk->sk_net_refcnt)) sock_inuse_add(sock_net(sk), -1); diff --git a/target/linux/generic/hack-6.6/902-debloat_proc.patch b/target/linux/generic/hack-6.6/902-debloat_proc.patch index 6b59fd674..2a311d327 100644 --- a/target/linux/generic/hack-6.6/902-debloat_proc.patch +++ b/target/linux/generic/hack-6.6/902-debloat_proc.patch @@ -330,7 +330,7 @@ Signed-off-by: Felix Fietkau --- a/net/core/sock.c +++ b/net/core/sock.c -@@ -4144,6 +4144,8 @@ static __net_initdata struct pernet_oper +@@ -4145,6 +4145,8 @@ static __net_initdata struct pernet_oper static int __init proto_init(void) { diff --git a/target/linux/generic/hack-6.6/930-usb-net-for-fm350.patch b/target/linux/generic/hack-6.6/930-usb-net-for-fm350.patch index fa4f4044e..cb59cdff5 100644 --- a/target/linux/generic/hack-6.6/930-usb-net-for-fm350.patch +++ b/target/linux/generic/hack-6.6/930-usb-net-for-fm350.patch @@ -1,6 +1,6 @@ --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c -@@ -642,6 +642,7 @@ static void option_instat_callback(struc +@@ -646,6 +646,7 @@ static void option_instat_callback(struc static const struct usb_device_id option_ids[] = { @@ -8,7 +8,7 @@ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_LIGHT) }, -@@ -2379,6 +2380,15 @@ static int option_probe(struct usb_seria +@@ -2423,6 +2424,15 @@ static int option_probe(struct usb_seria if (device_flags & NUMEP2 && iface_desc->bNumEndpoints != 2) return -ENODEV; diff --git a/target/linux/generic/pending-6.1/150-bridge_allow_receiption_on_disabled_port.patch b/target/linux/generic/pending-6.1/150-bridge_allow_receiption_on_disabled_port.patch index 93a2d146b..ac4a3138a 100644 --- a/target/linux/generic/pending-6.1/150-bridge_allow_receiption_on_disabled_port.patch +++ b/target/linux/generic/pending-6.1/150-bridge_allow_receiption_on_disabled_port.patch @@ -15,7 +15,7 @@ Signed-off-by: Felix Fietkau --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c -@@ -222,6 +222,9 @@ static void __br_handle_local_finish(str +@@ -227,6 +227,9 @@ static void __br_handle_local_finish(str /* note: already called with rcu_read_lock */ static int br_handle_local_finish(struct net *net, struct sock *sk, struct sk_buff *skb) { @@ -25,7 +25,7 @@ Signed-off-by: Felix Fietkau __br_handle_local_finish(skb); /* return 1 to signal the okfn() was called so it's ok to use the skb */ -@@ -390,6 +393,17 @@ forward: +@@ -397,6 +400,17 @@ forward: goto defer_stp_filtering; switch (p->state) { diff --git a/target/linux/generic/pending-6.1/680-NET-skip-GRO-for-foreign-MAC-addresses.patch b/target/linux/generic/pending-6.1/680-NET-skip-GRO-for-foreign-MAC-addresses.patch deleted file mode 100644 index 4b053fe87..000000000 --- a/target/linux/generic/pending-6.1/680-NET-skip-GRO-for-foreign-MAC-addresses.patch +++ /dev/null @@ -1,151 +0,0 @@ -From: Felix Fietkau -Subject: net: replace GRO optimization patch with a new one that supports VLANs/bridges with different MAC addresses - -Signed-off-by: Felix Fietkau ---- - include/linux/netdevice.h | 2 ++ - include/linux/skbuff.h | 3 ++- - net/core/dev.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++ - net/ethernet/eth.c | 18 +++++++++++++++++- - 4 files changed, 69 insertions(+), 2 deletions(-) - ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -2135,6 +2135,8 @@ struct net_device { - struct netdev_hw_addr_list mc; - struct netdev_hw_addr_list dev_addrs; - -+ unsigned char local_addr_mask[MAX_ADDR_LEN]; -+ - #ifdef CONFIG_SYSFS - struct kset *queues_kset; - #endif ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -967,6 +967,7 @@ struct sk_buff { - #ifdef CONFIG_IPV6_NDISC_NODETYPE - __u8 ndisc_nodetype:2; - #endif -+ __u8 gro_skip:1; - - __u8 ipvs_property:1; - __u8 inner_protocol_type:1; ---- a/net/core/gro.c -+++ b/net/core/gro.c -@@ -492,6 +492,9 @@ static enum gro_result dev_gro_receive(s - int same_flow; - int grow; - -+ if (skb->gro_skip) -+ goto normal; -+ - if (netif_elide_gro(skb->dev)) - goto normal; - ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -7643,6 +7643,48 @@ static void __netdev_adjacent_dev_unlink - &upper_dev->adj_list.lower); - } - -+static void __netdev_addr_mask(unsigned char *mask, const unsigned char *addr, -+ struct net_device *dev) -+{ -+ int i; -+ -+ for (i = 0; i < dev->addr_len; i++) -+ mask[i] |= addr[i] ^ dev->dev_addr[i]; -+} -+ -+static void __netdev_upper_mask(unsigned char *mask, struct net_device *dev, -+ struct net_device *lower) -+{ -+ struct net_device *cur; -+ struct list_head *iter; -+ -+ netdev_for_each_upper_dev_rcu(dev, cur, iter) { -+ __netdev_addr_mask(mask, cur->dev_addr, lower); -+ __netdev_upper_mask(mask, cur, lower); -+ } -+} -+ -+static void __netdev_update_addr_mask(struct net_device *dev) -+{ -+ unsigned char mask[MAX_ADDR_LEN]; -+ struct net_device *cur; -+ struct list_head *iter; -+ -+ memset(mask, 0, sizeof(mask)); -+ __netdev_upper_mask(mask, dev, dev); -+ memcpy(dev->local_addr_mask, mask, dev->addr_len); -+ -+ netdev_for_each_lower_dev(dev, cur, iter) -+ __netdev_update_addr_mask(cur); -+} -+ -+static void netdev_update_addr_mask(struct net_device *dev) -+{ -+ rcu_read_lock(); -+ __netdev_update_addr_mask(dev); -+ rcu_read_unlock(); -+} -+ - static int __netdev_upper_dev_link(struct net_device *dev, - struct net_device *upper_dev, bool master, - void *upper_priv, void *upper_info, -@@ -7694,6 +7736,7 @@ static int __netdev_upper_dev_link(struc - if (ret) - return ret; - -+ netdev_update_addr_mask(dev); - ret = call_netdevice_notifiers_info(NETDEV_CHANGEUPPER, - &changeupper_info.info); - ret = notifier_to_errno(ret); -@@ -7790,6 +7833,7 @@ static void __netdev_upper_dev_unlink(st - - __netdev_adjacent_dev_unlink_neighbour(dev, upper_dev); - -+ netdev_update_addr_mask(dev); - call_netdevice_notifiers_info(NETDEV_CHANGEUPPER, - &changeupper_info.info); - -@@ -8842,6 +8886,7 @@ int dev_set_mac_address(struct net_devic - if (err) - return err; - dev->addr_assign_type = NET_ADDR_SET; -+ netdev_update_addr_mask(dev); - call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); - add_device_randomness(dev->dev_addr, dev->addr_len); - return 0; ---- a/net/ethernet/eth.c -+++ b/net/ethernet/eth.c -@@ -143,6 +143,18 @@ u32 eth_get_headlen(const struct net_dev - } - EXPORT_SYMBOL(eth_get_headlen); - -+static inline bool -+eth_check_local_mask(const void *addr1, const void *addr2, const void *mask) -+{ -+ const u16 *a1 = addr1; -+ const u16 *a2 = addr2; -+ const u16 *m = mask; -+ -+ return (((a1[0] ^ a2[0]) & ~m[0]) | -+ ((a1[1] ^ a2[1]) & ~m[1]) | -+ ((a1[2] ^ a2[2]) & ~m[2])); -+} -+ - /** - * eth_type_trans - determine the packet's protocol ID. - * @skb: received socket data -@@ -174,6 +186,10 @@ __be16 eth_type_trans(struct sk_buff *sk - } else { - skb->pkt_type = PACKET_OTHERHOST; - } -+ -+ if (eth_check_local_mask(eth->h_dest, dev->dev_addr, -+ dev->local_addr_mask)) -+ skb->gro_skip = 1; - } - - /* diff --git a/target/linux/generic/pending-6.1/680-net-add-TCP-fraglist-GRO-support.patch b/target/linux/generic/pending-6.1/680-net-add-TCP-fraglist-GRO-support.patch new file mode 100644 index 000000000..f52233fe9 --- /dev/null +++ b/target/linux/generic/pending-6.1/680-net-add-TCP-fraglist-GRO-support.patch @@ -0,0 +1,627 @@ +From: Felix Fietkau +Date: Tue, 23 Apr 2024 11:23:03 +0200 +Subject: [PATCH] net: add TCP fraglist GRO support + +When forwarding TCP after GRO, software segmentation is very expensive, +especially when the checksum needs to be recalculated. +One case where that's currently unavoidable is when routing packets over +PPPoE. Performance improves significantly when using fraglist GRO +implemented in the same way as for UDP. + +Here's a measurement of running 2 TCP streams through a MediaTek MT7622 +device (2-core Cortex-A53), which runs NAT with flow offload enabled from +one ethernet port to PPPoE on another ethernet port + cake qdisc set to +1Gbps. + +rx-gro-list off: 630 Mbit/s, CPU 35% idle +rx-gro-list on: 770 Mbit/s, CPU 40% idle + +Signe-off-by: Felix Fietkau +--- + +--- a/include/net/gro.h ++++ b/include/net/gro.h +@@ -424,6 +424,7 @@ static inline __wsum ip6_gro_compute_pse + } + + int skb_gro_receive(struct sk_buff *p, struct sk_buff *skb); ++int skb_gro_receive_list(struct sk_buff *p, struct sk_buff *skb); + + /* Pass the currently batched GRO_NORMAL SKBs up to the stack. */ + static inline void gro_normal_list(struct napi_struct *napi) +@@ -446,5 +447,48 @@ static inline void gro_normal_one(struct + gro_normal_list(napi); + } + ++/* This function is the alternative of 'inet_iif' and 'inet_sdif' ++ * functions in case we can not rely on fields of IPCB. ++ * ++ * The caller must verify skb_valid_dst(skb) is false and skb->dev is initialized. ++ * The caller must hold the RCU read lock. ++ */ ++static inline void inet_get_iif_sdif(const struct sk_buff *skb, int *iif, int *sdif) ++{ ++ *iif = inet_iif(skb) ?: skb->dev->ifindex; ++ *sdif = 0; ++ ++#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV) ++ if (netif_is_l3_slave(skb->dev)) { ++ struct net_device *master = netdev_master_upper_dev_get_rcu(skb->dev); ++ ++ *sdif = *iif; ++ *iif = master ? master->ifindex : 0; ++ } ++#endif ++} ++ ++/* This function is the alternative of 'inet6_iif' and 'inet6_sdif' ++ * functions in case we can not rely on fields of IP6CB. ++ * ++ * The caller must verify skb_valid_dst(skb) is false and skb->dev is initialized. ++ * The caller must hold the RCU read lock. ++ */ ++static inline void inet6_get_iif_sdif(const struct sk_buff *skb, int *iif, int *sdif) ++{ ++ /* using skb->dev->ifindex because skb_dst(skb) is not initialized */ ++ *iif = skb->dev->ifindex; ++ *sdif = 0; ++ ++#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV) ++ if (netif_is_l3_slave(skb->dev)) { ++ struct net_device *master = netdev_master_upper_dev_get_rcu(skb->dev); ++ ++ *sdif = *iif; ++ *iif = master ? master->ifindex : 0; ++ } ++#endif ++} ++ + + #endif /* _NET_IPV6_GRO_H */ +--- a/include/net/tcp.h ++++ b/include/net/tcp.h +@@ -2057,7 +2057,10 @@ void tcp_v4_destroy_sock(struct sock *sk + + struct sk_buff *tcp_gso_segment(struct sk_buff *skb, + netdev_features_t features); +-struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb); ++struct tcphdr *tcp_gro_pull_header(struct sk_buff *skb); ++struct sk_buff *tcp_gro_lookup(struct list_head *head, struct tcphdr *th); ++struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb, ++ struct tcphdr *th); + INDIRECT_CALLABLE_DECLARE(int tcp4_gro_complete(struct sk_buff *skb, int thoff)); + INDIRECT_CALLABLE_DECLARE(struct sk_buff *tcp4_gro_receive(struct list_head *head, struct sk_buff *skb)); + INDIRECT_CALLABLE_DECLARE(int tcp6_gro_complete(struct sk_buff *skb, int thoff)); +--- a/net/core/gro.c ++++ b/net/core/gro.c +@@ -290,6 +290,33 @@ done: + return 0; + } + ++int skb_gro_receive_list(struct sk_buff *p, struct sk_buff *skb) ++{ ++ if (unlikely(p->len + skb->len >= 65536)) ++ return -E2BIG; ++ ++ if (NAPI_GRO_CB(p)->last == p) ++ skb_shinfo(p)->frag_list = skb; ++ else ++ NAPI_GRO_CB(p)->last->next = skb; ++ ++ skb_pull(skb, skb_gro_offset(skb)); ++ ++ NAPI_GRO_CB(p)->last = skb; ++ NAPI_GRO_CB(p)->count++; ++ p->data_len += skb->len; ++ ++ /* sk ownership - if any - completely transferred to the aggregated packet */ ++ skb->destructor = NULL; ++ skb->sk = NULL; ++ p->truesize += skb->truesize; ++ p->len += skb->len; ++ ++ NAPI_GRO_CB(skb)->same_flow = 1; ++ ++ return 0; ++} ++ + + static void napi_gro_complete(struct napi_struct *napi, struct sk_buff *skb) + { +--- a/net/ipv4/tcp_offload.c ++++ b/net/ipv4/tcp_offload.c +@@ -27,6 +27,70 @@ static void tcp_gso_tstamp(struct sk_buf + } + } + ++static void __tcpv4_gso_segment_csum(struct sk_buff *seg, ++ __be32 *oldip, __be32 newip, ++ __be16 *oldport, __be16 newport) ++{ ++ struct tcphdr *th; ++ struct iphdr *iph; ++ ++ if (*oldip == newip && *oldport == newport) ++ return; ++ ++ th = tcp_hdr(seg); ++ iph = ip_hdr(seg); ++ ++ inet_proto_csum_replace4(&th->check, seg, *oldip, newip, true); ++ inet_proto_csum_replace2(&th->check, seg, *oldport, newport, false); ++ *oldport = newport; ++ ++ csum_replace4(&iph->check, *oldip, newip); ++ *oldip = newip; ++} ++ ++static struct sk_buff *__tcpv4_gso_segment_list_csum(struct sk_buff *segs) ++{ ++ const struct tcphdr *th; ++ const struct iphdr *iph; ++ struct sk_buff *seg; ++ struct tcphdr *th2; ++ struct iphdr *iph2; ++ ++ seg = segs; ++ th = tcp_hdr(seg); ++ iph = ip_hdr(seg); ++ th2 = tcp_hdr(seg->next); ++ iph2 = ip_hdr(seg->next); ++ ++ if (!(*(const u32 *)&th->source ^ *(const u32 *)&th2->source) && ++ iph->daddr == iph2->daddr && iph->saddr == iph2->saddr) ++ return segs; ++ ++ while ((seg = seg->next)) { ++ th2 = tcp_hdr(seg); ++ iph2 = ip_hdr(seg); ++ ++ __tcpv4_gso_segment_csum(seg, ++ &iph2->saddr, iph->saddr, ++ &th2->source, th->source); ++ __tcpv4_gso_segment_csum(seg, ++ &iph2->daddr, iph->daddr, ++ &th2->dest, th->dest); ++ } ++ ++ return segs; ++} ++ ++static struct sk_buff *__tcp4_gso_segment_list(struct sk_buff *skb, ++ netdev_features_t features) ++{ ++ skb = skb_segment_list(skb, features, skb_mac_header_len(skb)); ++ if (IS_ERR(skb)) ++ return skb; ++ ++ return __tcpv4_gso_segment_list_csum(skb); ++} ++ + static struct sk_buff *tcp4_gso_segment(struct sk_buff *skb, + netdev_features_t features) + { +@@ -36,6 +100,9 @@ static struct sk_buff *tcp4_gso_segment( + if (!pskb_may_pull(skb, sizeof(struct tcphdr))) + return ERR_PTR(-EINVAL); + ++ if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST) ++ return __tcp4_gso_segment_list(skb, features); ++ + if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) { + const struct iphdr *iph = ip_hdr(skb); + struct tcphdr *th = tcp_hdr(skb); +@@ -177,61 +244,76 @@ out: + return segs; + } + +-struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb) ++struct sk_buff *tcp_gro_lookup(struct list_head *head, struct tcphdr *th) + { +- struct sk_buff *pp = NULL; ++ struct tcphdr *th2; + struct sk_buff *p; ++ ++ list_for_each_entry(p, head, list) { ++ if (!NAPI_GRO_CB(p)->same_flow) ++ continue; ++ ++ th2 = tcp_hdr(p); ++ if (*(u32 *)&th->source ^ *(u32 *)&th2->source) { ++ NAPI_GRO_CB(p)->same_flow = 0; ++ continue; ++ } ++ ++ return p; ++ } ++ ++ return NULL; ++} ++ ++struct tcphdr *tcp_gro_pull_header(struct sk_buff *skb) ++{ ++ unsigned int thlen, hlen, off; + struct tcphdr *th; +- struct tcphdr *th2; +- unsigned int len; +- unsigned int thlen; +- __be32 flags; +- unsigned int mss = 1; +- unsigned int hlen; +- unsigned int off; +- int flush = 1; +- int i; + + off = skb_gro_offset(skb); + hlen = off + sizeof(*th); + th = skb_gro_header(skb, hlen, off); + if (unlikely(!th)) +- goto out; ++ return NULL; + + thlen = th->doff * 4; + if (thlen < sizeof(*th)) +- goto out; ++ return NULL; + + hlen = off + thlen; + if (skb_gro_header_hard(skb, hlen)) { + th = skb_gro_header_slow(skb, hlen, off); + if (unlikely(!th)) +- goto out; ++ return NULL; + } + + skb_gro_pull(skb, thlen); + +- len = skb_gro_len(skb); +- flags = tcp_flag_word(th); +- +- list_for_each_entry(p, head, list) { +- if (!NAPI_GRO_CB(p)->same_flow) +- continue; ++ return th; ++} + +- th2 = tcp_hdr(p); ++struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb, ++ struct tcphdr *th) ++{ ++ unsigned int thlen = th->doff * 4; ++ struct sk_buff *pp = NULL; ++ struct sk_buff *p; ++ struct tcphdr *th2; ++ unsigned int len; ++ __be32 flags; ++ unsigned int mss = 1; ++ int flush = 1; ++ int i; + +- if (*(u32 *)&th->source ^ *(u32 *)&th2->source) { +- NAPI_GRO_CB(p)->same_flow = 0; +- continue; +- } ++ len = skb_gro_len(skb); ++ flags = tcp_flag_word(th); + +- goto found; +- } +- p = NULL; +- goto out_check_final; ++ p = tcp_gro_lookup(head, th); ++ if (!p) ++ goto out_check_final; + +-found: + /* Include the IP ID check below from the inner most IP hdr */ ++ th2 = tcp_hdr(p); + flush = NAPI_GRO_CB(p)->flush; + flush |= (__force int)(flags & TCP_FLAG_CWR); + flush |= (__force int)((flags ^ tcp_flag_word(th2)) & +@@ -268,6 +350,19 @@ found: + flush |= p->decrypted ^ skb->decrypted; + #endif + ++ if (unlikely(NAPI_GRO_CB(p)->is_flist)) { ++ flush |= (__force int)(flags ^ tcp_flag_word(th2)); ++ flush |= skb->ip_summed != p->ip_summed; ++ flush |= skb->csum_level != p->csum_level; ++ flush |= !pskb_may_pull(skb, skb_gro_offset(skb)); ++ flush |= NAPI_GRO_CB(p)->count >= 64; ++ ++ if (flush || skb_gro_receive_list(p, skb)) ++ mss = 1; ++ ++ goto out_check_final; ++ } ++ + if (flush || skb_gro_receive(p, skb)) { + mss = 1; + goto out_check_final; +@@ -289,7 +384,6 @@ out_check_final: + if (p && (!NAPI_GRO_CB(skb)->same_flow || flush)) + pp = p; + +-out: + NAPI_GRO_CB(skb)->flush |= (flush != 0); + + return pp; +@@ -315,18 +409,58 @@ int tcp_gro_complete(struct sk_buff *skb + } + EXPORT_SYMBOL(tcp_gro_complete); + ++static void tcp4_check_fraglist_gro(struct list_head *head, struct sk_buff *skb, ++ struct tcphdr *th) ++{ ++ const struct iphdr *iph; ++ struct sk_buff *p; ++ struct sock *sk; ++ struct net *net; ++ int iif, sdif; ++ ++ if (!(skb->dev->features & NETIF_F_GRO_FRAGLIST)) ++ return; ++ ++ p = tcp_gro_lookup(head, th); ++ if (p) { ++ NAPI_GRO_CB(skb)->is_flist = NAPI_GRO_CB(p)->is_flist; ++ return; ++ } ++ ++ inet_get_iif_sdif(skb, &iif, &sdif); ++ iph = skb_gro_network_header(skb); ++ net = dev_net(skb->dev); ++ sk = __inet_lookup_established(net, net->ipv4.tcp_death_row.hashinfo, ++ iph->saddr, th->source, ++ iph->daddr, ntohs(th->dest), ++ iif, sdif); ++ NAPI_GRO_CB(skb)->is_flist = !sk; ++ if (sk) ++ sock_put(sk); ++} ++ + INDIRECT_CALLABLE_SCOPE + struct sk_buff *tcp4_gro_receive(struct list_head *head, struct sk_buff *skb) + { ++ struct tcphdr *th; ++ + /* Don't bother verifying checksum if we're going to flush anyway. */ + if (!NAPI_GRO_CB(skb)->flush && + skb_gro_checksum_validate(skb, IPPROTO_TCP, +- inet_gro_compute_pseudo)) { +- NAPI_GRO_CB(skb)->flush = 1; +- return NULL; +- } ++ inet_gro_compute_pseudo)) ++ goto flush; ++ ++ th = tcp_gro_pull_header(skb); ++ if (!th) ++ goto flush; + +- return tcp_gro_receive(head, skb); ++ tcp4_check_fraglist_gro(head, skb, th); ++ ++ return tcp_gro_receive(head, skb, th); ++ ++flush: ++ NAPI_GRO_CB(skb)->flush = 1; ++ return NULL; + } + + INDIRECT_CALLABLE_SCOPE int tcp4_gro_complete(struct sk_buff *skb, int thoff) +@@ -334,6 +468,15 @@ INDIRECT_CALLABLE_SCOPE int tcp4_gro_com + const struct iphdr *iph = ip_hdr(skb); + struct tcphdr *th = tcp_hdr(skb); + ++ if (unlikely(NAPI_GRO_CB(skb)->is_flist)) { ++ skb_shinfo(skb)->gso_type |= SKB_GSO_FRAGLIST | SKB_GSO_TCPV4; ++ skb_shinfo(skb)->gso_segs = NAPI_GRO_CB(skb)->count; ++ ++ __skb_incr_checksum_unnecessary(skb); ++ ++ return 0; ++ } ++ + th->check = ~tcp_v4_check(skb->len - thoff, iph->saddr, + iph->daddr, 0); + skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV4; +--- a/net/ipv4/udp_offload.c ++++ b/net/ipv4/udp_offload.c +@@ -425,33 +425,6 @@ out: + return segs; + } + +-static int skb_gro_receive_list(struct sk_buff *p, struct sk_buff *skb) +-{ +- if (unlikely(p->len + skb->len >= 65536)) +- return -E2BIG; +- +- if (NAPI_GRO_CB(p)->last == p) +- skb_shinfo(p)->frag_list = skb; +- else +- NAPI_GRO_CB(p)->last->next = skb; +- +- skb_pull(skb, skb_gro_offset(skb)); +- +- NAPI_GRO_CB(p)->last = skb; +- NAPI_GRO_CB(p)->count++; +- p->data_len += skb->len; +- +- /* sk ownership - if any - completely transferred to the aggregated packet */ +- skb->destructor = NULL; +- skb->sk = NULL; +- p->truesize += skb->truesize; +- p->len += skb->len; +- +- NAPI_GRO_CB(skb)->same_flow = 1; +- +- return 0; +-} +- + + #define UDP_GRO_CNT_MAX 64 + static struct sk_buff *udp_gro_receive_segment(struct list_head *head, +--- a/net/ipv6/tcpv6_offload.c ++++ b/net/ipv6/tcpv6_offload.c +@@ -7,24 +7,67 @@ + */ + #include + #include ++#include + #include + #include + #include + #include + #include "ip6_offload.h" + ++static void tcp6_check_fraglist_gro(struct list_head *head, struct sk_buff *skb, ++ struct tcphdr *th) ++{ ++#if IS_ENABLED(CONFIG_IPV6) ++ const struct ipv6hdr *hdr; ++ struct sk_buff *p; ++ struct sock *sk; ++ struct net *net; ++ int iif, sdif; ++ ++ if (!(skb->dev->features & NETIF_F_GRO_FRAGLIST)) ++ return; ++ ++ p = tcp_gro_lookup(head, th); ++ if (p) { ++ NAPI_GRO_CB(skb)->is_flist = NAPI_GRO_CB(p)->is_flist; ++ return; ++ } ++ ++ inet6_get_iif_sdif(skb, &iif, &sdif); ++ hdr = skb_gro_network_header(skb); ++ net = dev_net(skb->dev); ++ sk = __inet6_lookup_established(net, net->ipv4.tcp_death_row.hashinfo, ++ &hdr->saddr, th->source, ++ &hdr->daddr, ntohs(th->dest), ++ iif, sdif); ++ NAPI_GRO_CB(skb)->is_flist = !sk; ++ if (sk) ++ sock_put(sk); ++#endif /* IS_ENABLED(CONFIG_IPV6) */ ++} ++ + INDIRECT_CALLABLE_SCOPE + struct sk_buff *tcp6_gro_receive(struct list_head *head, struct sk_buff *skb) + { ++ struct tcphdr *th; ++ + /* Don't bother verifying checksum if we're going to flush anyway. */ + if (!NAPI_GRO_CB(skb)->flush && + skb_gro_checksum_validate(skb, IPPROTO_TCP, +- ip6_gro_compute_pseudo)) { +- NAPI_GRO_CB(skb)->flush = 1; +- return NULL; +- } ++ ip6_gro_compute_pseudo)) ++ goto flush; + +- return tcp_gro_receive(head, skb); ++ th = tcp_gro_pull_header(skb); ++ if (!th) ++ goto flush; ++ ++ tcp6_check_fraglist_gro(head, skb, th); ++ ++ return tcp_gro_receive(head, skb, th); ++ ++flush: ++ NAPI_GRO_CB(skb)->flush = 1; ++ return NULL; + } + + INDIRECT_CALLABLE_SCOPE int tcp6_gro_complete(struct sk_buff *skb, int thoff) +@@ -32,6 +75,15 @@ INDIRECT_CALLABLE_SCOPE int tcp6_gro_com + const struct ipv6hdr *iph = ipv6_hdr(skb); + struct tcphdr *th = tcp_hdr(skb); + ++ if (unlikely(NAPI_GRO_CB(skb)->is_flist)) { ++ skb_shinfo(skb)->gso_type |= SKB_GSO_FRAGLIST | SKB_GSO_TCPV6; ++ skb_shinfo(skb)->gso_segs = NAPI_GRO_CB(skb)->count; ++ ++ __skb_incr_checksum_unnecessary(skb); ++ ++ return 0; ++ } ++ + th->check = ~tcp_v6_check(skb->len - thoff, &iph->saddr, + &iph->daddr, 0); + skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV6; +@@ -39,6 +91,61 @@ INDIRECT_CALLABLE_SCOPE int tcp6_gro_com + return tcp_gro_complete(skb); + } + ++static void __tcpv6_gso_segment_csum(struct sk_buff *seg, ++ __be16 *oldport, __be16 newport) ++{ ++ struct tcphdr *th; ++ ++ if (*oldport == newport) ++ return; ++ ++ th = tcp_hdr(seg); ++ inet_proto_csum_replace2(&th->check, seg, *oldport, newport, false); ++ *oldport = newport; ++} ++ ++static struct sk_buff *__tcpv6_gso_segment_list_csum(struct sk_buff *segs) ++{ ++ const struct tcphdr *th; ++ const struct ipv6hdr *iph; ++ struct sk_buff *seg; ++ struct tcphdr *th2; ++ struct ipv6hdr *iph2; ++ ++ seg = segs; ++ th = tcp_hdr(seg); ++ iph = ipv6_hdr(seg); ++ th2 = tcp_hdr(seg->next); ++ iph2 = ipv6_hdr(seg->next); ++ ++ if (!(*(const u32 *)&th->source ^ *(const u32 *)&th2->source) && ++ ipv6_addr_equal(&iph->saddr, &iph2->saddr) && ++ ipv6_addr_equal(&iph->daddr, &iph2->daddr)) ++ return segs; ++ ++ while ((seg = seg->next)) { ++ th2 = tcp_hdr(seg); ++ iph2 = ipv6_hdr(seg); ++ ++ iph2->saddr = iph->saddr; ++ iph2->daddr = iph->daddr; ++ __tcpv6_gso_segment_csum(seg, &th2->source, th->source); ++ __tcpv6_gso_segment_csum(seg, &th2->dest, th->dest); ++ } ++ ++ return segs; ++} ++ ++static struct sk_buff *__tcp6_gso_segment_list(struct sk_buff *skb, ++ netdev_features_t features) ++{ ++ skb = skb_segment_list(skb, features, skb_mac_header_len(skb)); ++ if (IS_ERR(skb)) ++ return skb; ++ ++ return __tcpv6_gso_segment_list_csum(skb); ++} ++ + static struct sk_buff *tcp6_gso_segment(struct sk_buff *skb, + netdev_features_t features) + { +@@ -50,6 +157,9 @@ static struct sk_buff *tcp6_gso_segment( + if (!pskb_may_pull(skb, sizeof(*th))) + return ERR_PTR(-EINVAL); + ++ if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST) ++ return __tcp6_gso_segment_list(skb, features); ++ + if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) { + const struct ipv6hdr *ipv6h = ipv6_hdr(skb); + struct tcphdr *th = tcp_hdr(skb); diff --git a/target/linux/generic/pending-6.1/681-net-bridge-fix-multicast-to-unicast-with-fraglist-GS.patch b/target/linux/generic/pending-6.1/681-net-bridge-fix-multicast-to-unicast-with-fraglist-GS.patch new file mode 100644 index 000000000..6a53a678d --- /dev/null +++ b/target/linux/generic/pending-6.1/681-net-bridge-fix-multicast-to-unicast-with-fraglist-GS.patch @@ -0,0 +1,23 @@ +From: Felix Fietkau +Date: Sat, 27 Apr 2024 18:54:25 +0200 +Subject: [PATCH] net: bridge: fix multicast-to-unicast with fraglist GSO + +Calling skb_copy on a SKB_GSO_FRAGLIST skb is not valid, since it returns +an invalid linearized skb. This code only needs to change the ethernet +header, so pskb_copy is the right function to call here. + +Fixes: 6db6f0eae605 ("bridge: multicast to unicast") +Signed-off-by: Felix Fietkau +--- + +--- a/net/bridge/br_forward.c ++++ b/net/bridge/br_forward.c +@@ -261,7 +261,7 @@ static void maybe_deliver_addr(struct ne + if (skb->dev == p->dev && ether_addr_equal(src, addr)) + return; + +- skb = skb_copy(skb, GFP_ATOMIC); ++ skb = pskb_copy(skb, GFP_ATOMIC); + if (!skb) { + DEV_STATS_INC(dev, tx_dropped); + return; diff --git a/target/linux/generic/pending-6.1/682-net-core-reject-skb_copy-_expand-for-fraglist-GSO-sk.patch b/target/linux/generic/pending-6.1/682-net-core-reject-skb_copy-_expand-for-fraglist-GSO-sk.patch new file mode 100644 index 000000000..719cac9bc --- /dev/null +++ b/target/linux/generic/pending-6.1/682-net-core-reject-skb_copy-_expand-for-fraglist-GSO-sk.patch @@ -0,0 +1,59 @@ +From: Felix Fietkau +Date: Sat, 27 Apr 2024 19:29:45 +0200 +Subject: [PATCH] net: core: reject skb_copy(_expand) for fraglist GSO skbs + +SKB_GSO_FRAGLIST skbs must not be linearized, otherwise they become +invalid. Return NULL if such an skb is passed to skb_copy or +skb_copy_expand, in order to prevent a crash on a potential later +call to skb_gso_segment. + +Fixes: 3a1296a38d0c ("net: Support GRO/GSO fraglist chaining.") +Signed-off-by: Felix Fietkau +--- + +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -1720,11 +1720,17 @@ static inline int skb_alloc_rx_flag(cons + + struct sk_buff *skb_copy(const struct sk_buff *skb, gfp_t gfp_mask) + { +- int headerlen = skb_headroom(skb); +- unsigned int size = skb_end_offset(skb) + skb->data_len; +- struct sk_buff *n = __alloc_skb(size, gfp_mask, +- skb_alloc_rx_flag(skb), NUMA_NO_NODE); ++ struct sk_buff *n; ++ unsigned int size; ++ int headerlen; + ++ if (WARN_ON_ONCE(skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST)) ++ return NULL; ++ ++ headerlen = skb_headroom(skb); ++ size = skb_end_offset(skb) + skb->data_len; ++ n = __alloc_skb(size, gfp_mask, ++ skb_alloc_rx_flag(skb), NUMA_NO_NODE); + if (!n) + return NULL; + +@@ -2037,12 +2043,17 @@ struct sk_buff *skb_copy_expand(const st + /* + * Allocate the copy buffer + */ +- struct sk_buff *n = __alloc_skb(newheadroom + skb->len + newtailroom, +- gfp_mask, skb_alloc_rx_flag(skb), +- NUMA_NO_NODE); +- int oldheadroom = skb_headroom(skb); + int head_copy_len, head_copy_off; ++ struct sk_buff *n; ++ int oldheadroom; ++ ++ if (WARN_ON_ONCE(skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST)) ++ return NULL; + ++ oldheadroom = skb_headroom(skb); ++ n = __alloc_skb(newheadroom + skb->len + newtailroom, ++ gfp_mask, skb_alloc_rx_flag(skb), ++ NUMA_NO_NODE); + if (!n) + return NULL; + diff --git a/target/linux/generic/pending-6.1/682-of_net-add-mac-address-increment-support.patch b/target/linux/generic/pending-6.1/682-of_net-add-mac-address-increment-support.patch deleted file mode 100644 index f6ae9f31f..000000000 --- a/target/linux/generic/pending-6.1/682-of_net-add-mac-address-increment-support.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 844c273286f328acf0dab5fbd5d864366b4904dc Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Tue, 30 Mar 2021 18:21:14 +0200 -Subject: [PATCH] of_net: add mac-address-increment support - -Lots of embedded devices use the mac-address of other interface -extracted from nvmem cells and increments it by one or two. Add two -bindings to integrate this and directly use the right mac-address for -the interface. Some example are some routers that use the gmac -mac-address stored in the art partition and increments it by one for the -wifi. mac-address-increment-byte bindings is used to tell what byte of -the mac-address has to be increased (if not defined the last byte is -increased) and mac-address-increment tells how much the byte decided -early has to be increased. - -Signed-off-by: Ansuel Smith ---- - net/core/of_net.c | 43 +++++++++++++++++++++++++++++++++++++++---- - 1 file changed, 39 insertions(+), 4 deletions(-) - ---- a/net/core/of_net.c -+++ b/net/core/of_net.c -@@ -119,28 +119,63 @@ static int of_get_mac_addr_nvmem(struct - * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists - * but is all zeros. - * -+ * DT can tell the system to increment the mac-address after is extracted by -+ * using: -+ * - mac-address-increment-byte to decide what byte to increase -+ * (if not defined is increased the last byte) -+ * - mac-address-increment to decide how much to increase. The value WILL -+ * overflow to other bytes if the increment is over 255 or the total -+ * increment will exceed 255 of the current byte. -+ * (example 00:01:02:03:04:ff + 1 == 00:01:02:03:05:00) -+ * (example 00:01:02:03:04:fe + 5 == 00:01:02:03:05:03) -+ * - * Return: 0 on success and errno in case of error. - */ - int of_get_mac_address(struct device_node *np, u8 *addr) - { -+ u32 inc_idx, mac_inc, mac_val; - int ret; - -+ /* Check first if the increment byte is present and valid. -+ * If not set assume to increment the last byte if found. -+ */ -+ if (of_property_read_u32(np, "mac-address-increment-byte", &inc_idx)) -+ inc_idx = 5; -+ if (inc_idx < 3 || inc_idx > 5) -+ return -EINVAL; -+ - if (!np) - return -ENODEV; - - ret = of_get_mac_addr(np, "mac-address", addr); - if (!ret) -- return 0; -+ goto found; - - ret = of_get_mac_addr(np, "local-mac-address", addr); - if (!ret) -- return 0; -+ goto found; - - ret = of_get_mac_addr(np, "address", addr); - if (!ret) -- return 0; -+ goto found; -+ -+ ret = of_get_mac_addr_nvmem(np, addr); -+ if (ret) -+ return ret; -+ -+found: -+ if (!of_property_read_u32(np, "mac-address-increment", &mac_inc)) { -+ /* Convert to a contiguous value */ -+ mac_val = (addr[3] << 16) + (addr[4] << 8) + addr[5]; -+ mac_val += mac_inc << 8 * (5-inc_idx); -+ -+ /* Apply the incremented value handling overflow case */ -+ addr[3] = (mac_val >> 16) & 0xff; -+ addr[4] = (mac_val >> 8) & 0xff; -+ addr[5] = (mac_val >> 0) & 0xff; -+ } - -- return of_get_mac_addr_nvmem(np, addr); -+ return ret; - } - EXPORT_SYMBOL(of_get_mac_address); - diff --git a/target/linux/generic/pending-6.1/683-of_net-add-mac-address-to-of-tree.patch b/target/linux/generic/pending-6.1/683-of_net-add-mac-address-to-of-tree.patch index f7ef06a14..03ee537fb 100644 --- a/target/linux/generic/pending-6.1/683-of_net-add-mac-address-to-of-tree.patch +++ b/target/linux/generic/pending-6.1/683-of_net-add-mac-address-to-of-tree.patch @@ -45,11 +45,31 @@ property. This way, the MAC address can be accessed using procfs. /** * of_get_mac_address() * @np: Caller's Device Node -@@ -175,6 +196,7 @@ found: - addr[5] = (mac_val >> 0) & 0xff; - } +@@ -130,17 +151,23 @@ int of_get_mac_address(struct device_nod -+ of_add_mac_address(np, addr); - return ret; + ret = of_get_mac_addr(np, "mac-address", addr); + if (!ret) +- return 0; ++ goto found; + + ret = of_get_mac_addr(np, "local-mac-address", addr); + if (!ret) +- return 0; ++ goto found; + + ret = of_get_mac_addr(np, "address", addr); + if (!ret) +- return 0; ++ goto found; + +- return of_get_mac_addr_nvmem(np, addr); ++ ret = of_get_mac_addr_nvmem(np, addr); ++ if (ret) ++ return ret; ++ ++found: ++ ret = of_add_mac_address(np, addr); ++ return ret; } EXPORT_SYMBOL(of_get_mac_address); + diff --git a/target/linux/generic/pending-6.1/684-of_net-do-mac-address-increment-only-once.patch b/target/linux/generic/pending-6.1/684-of_net-do-mac-address-increment-only-once.patch deleted file mode 100644 index 44d88e31a..000000000 --- a/target/linux/generic/pending-6.1/684-of_net-do-mac-address-increment-only-once.patch +++ /dev/null @@ -1,31 +0,0 @@ -From dd07dd394d8bfdb5d527fab18ca54f20815ec4e4 Mon Sep 17 00:00:00 2001 -From: Will Moss -Date: Wed, 3 Aug 2022 13:48:55 +0000 -Subject: [PATCH] of_net: do mac-address-increment only once - -Remove mac-address-increment and mac-address-increment-byte -DT property after incrementing process to make sure MAC address -would not get incremented more if this function is stared again. -It could happen if device initialization is deferred after -unsuccessful attempt. - -Signed-off-by: Will Moss ---- - drivers/of/of_net.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/net/core/of_net.c -+++ b/net/core/of_net.c -@@ -194,6 +194,12 @@ found: - addr[3] = (mac_val >> 16) & 0xff; - addr[4] = (mac_val >> 8) & 0xff; - addr[5] = (mac_val >> 0) & 0xff; -+ -+ /* Remove mac-address-increment and mac-address-increment-byte -+ * DT property to make sure MAC address would not get incremented -+ * more if this function is stared again. */ -+ of_remove_property(np, of_find_property(np, "mac-address-increment", NULL)); -+ of_remove_property(np, of_find_property(np, "mac-address-increment-byte", NULL)); - } - - of_add_mac_address(np, addr); diff --git a/target/linux/generic/pending-6.1/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch b/target/linux/generic/pending-6.1/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch index 989aca8f3..20d1c1304 100644 --- a/target/linux/generic/pending-6.1/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch +++ b/target/linux/generic/pending-6.1/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch @@ -45,7 +45,7 @@ Signed-off-by: Felix Fietkau if (!(p->flags & BR_BCAST_FLOOD) && skb->dev != br->dev) --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c -@@ -344,6 +344,8 @@ static rx_handler_result_t br_handle_fra +@@ -349,6 +349,8 @@ static rx_handler_result_t br_handle_fra fwd_mask |= p->group_fwd_mask; switch (dest[5]) { case 0x00: /* Bridge Group Address */ diff --git a/target/linux/generic/pending-6.1/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch b/target/linux/generic/pending-6.1/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch index ba0e8c778..d8440d7aa 100644 --- a/target/linux/generic/pending-6.1/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch +++ b/target/linux/generic/pending-6.1/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch @@ -15,7 +15,7 @@ Signed-off-by: Alexander Couzens --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2449,6 +2449,10 @@ mt7530_setup(struct dsa_switch *ds) +@@ -2470,6 +2470,10 @@ mt7530_setup(struct dsa_switch *ds) return -ENODEV; } diff --git a/target/linux/generic/pending-6.1/731-net-permit-ieee80211_ptr-even-with-no-CFG82111-suppo.patch b/target/linux/generic/pending-6.1/731-net-permit-ieee80211_ptr-even-with-no-CFG82111-suppo.patch index d1203d76c..2c1ec55d0 100644 --- a/target/linux/generic/pending-6.1/731-net-permit-ieee80211_ptr-even-with-no-CFG82111-suppo.patch +++ b/target/linux/generic/pending-6.1/731-net-permit-ieee80211_ptr-even-with-no-CFG82111-suppo.patch @@ -17,7 +17,7 @@ Signed-off-by: Christian Marangi --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h -@@ -2170,7 +2170,7 @@ struct net_device { +@@ -2168,7 +2168,7 @@ struct net_device { #if IS_ENABLED(CONFIG_AX25) void *ax25_ptr; #endif diff --git a/target/linux/generic/pending-6.1/760-net-core-add-optional-threading-for-backlog-processi.patch b/target/linux/generic/pending-6.1/760-net-core-add-optional-threading-for-backlog-processi.patch index e5b32956c..652c0329c 100644 --- a/target/linux/generic/pending-6.1/760-net-core-add-optional-threading-for-backlog-processi.patch +++ b/target/linux/generic/pending-6.1/760-net-core-add-optional-threading-for-backlog-processi.patch @@ -20,7 +20,7 @@ Signed-off-by: Felix Fietkau /** * napi_disable - prevent NAPI from scheduling -@@ -3130,6 +3131,7 @@ struct softnet_data { +@@ -3128,6 +3129,7 @@ struct softnet_data { unsigned int processed; unsigned int time_squeeze; unsigned int received_rps; @@ -157,7 +157,7 @@ Signed-off-by: Felix Fietkau void netif_napi_add_weight(struct net_device *dev, struct napi_struct *napi, int (*poll)(struct napi_struct *, int), int weight) { -@@ -11186,6 +11257,9 @@ static int dev_cpu_dead(unsigned int old +@@ -11141,6 +11212,9 @@ static int dev_cpu_dead(unsigned int old raise_softirq_irqoff(NET_TX_SOFTIRQ); local_irq_enable(); @@ -167,7 +167,7 @@ Signed-off-by: Felix Fietkau #ifdef CONFIG_RPS remsd = oldsd->rps_ipi_list; oldsd->rps_ipi_list = NULL; -@@ -11498,6 +11572,7 @@ static int __init net_dev_init(void) +@@ -11453,6 +11527,7 @@ static int __init net_dev_init(void) INIT_CSD(&sd->defer_csd, trigger_rx_softirq, sd); spin_lock_init(&sd->defer_lock); @@ -177,15 +177,15 @@ Signed-off-by: Felix Fietkau sd->backlog.weight = weight_p; --- a/net/core/sysctl_net_core.c +++ b/net/core/sysctl_net_core.c -@@ -29,6 +29,7 @@ static int int_3600 = 3600; - static int min_sndbuf = SOCK_MIN_SNDBUF; +@@ -30,6 +30,7 @@ static int min_sndbuf = SOCK_MIN_SNDBUF; static int min_rcvbuf = SOCK_MIN_RCVBUF; static int max_skb_frags = MAX_SKB_FRAGS; + static int min_mem_pcpu_rsv = SK_MEMORY_PCPU_RESERVE; +static int backlog_threaded; static int net_msg_warn; /* Unused, but still a sysctl */ -@@ -112,6 +113,23 @@ static int rps_sock_flow_sysctl(struct c +@@ -113,6 +114,23 @@ static int rps_sock_flow_sysctl(struct c } #endif /* CONFIG_RPS */ @@ -209,7 +209,7 @@ Signed-off-by: Felix Fietkau #ifdef CONFIG_NET_FLOW_LIMIT static DEFINE_MUTEX(flow_limit_update_mutex); -@@ -473,6 +491,15 @@ static struct ctl_table net_core_table[] +@@ -482,6 +500,15 @@ static struct ctl_table net_core_table[] .proc_handler = rps_sock_flow_sysctl }, #endif diff --git a/target/linux/generic/pending-6.1/795-mt7530-register-OF-node-for-internal-MDIO-bus.patch b/target/linux/generic/pending-6.1/795-mt7530-register-OF-node-for-internal-MDIO-bus.patch index a5f5cfb0f..df52a6ac2 100644 --- a/target/linux/generic/pending-6.1/795-mt7530-register-OF-node-for-internal-MDIO-bus.patch +++ b/target/linux/generic/pending-6.1/795-mt7530-register-OF-node-for-internal-MDIO-bus.patch @@ -16,7 +16,7 @@ Signed-off-by: David Bauer --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2339,10 +2339,13 @@ mt7530_setup_mdio(struct mt7530_priv *pr +@@ -2360,10 +2360,13 @@ mt7530_setup_mdio(struct mt7530_priv *pr { struct dsa_switch *ds = priv->ds; struct device *dev = priv->dev; @@ -30,7 +30,7 @@ Signed-off-by: David Bauer bus = devm_mdiobus_alloc(dev); if (!bus) return -ENOMEM; -@@ -2359,7 +2362,9 @@ mt7530_setup_mdio(struct mt7530_priv *pr +@@ -2380,7 +2383,9 @@ mt7530_setup_mdio(struct mt7530_priv *pr if (priv->irq) mt7530_setup_mdio_irq(priv); diff --git a/target/linux/generic/pending-6.1/811-pci_disable_usb_common_quirks.patch b/target/linux/generic/pending-6.1/811-pci_disable_usb_common_quirks.patch index 98ea4c06d..fcb77e517 100644 --- a/target/linux/generic/pending-6.1/811-pci_disable_usb_common_quirks.patch +++ b/target/linux/generic/pending-6.1/811-pci_disable_usb_common_quirks.patch @@ -19,7 +19,7 @@ Signed-off-by: Felix Fietkau static struct amd_chipset_info { struct pci_dev *nb_dev; struct pci_dev *smbus_dev; -@@ -633,6 +635,10 @@ bool usb_amd_pt_check_port(struct device +@@ -631,6 +633,10 @@ bool usb_amd_pt_check_port(struct device } EXPORT_SYMBOL_GPL(usb_amd_pt_check_port); @@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau /* * Make sure the controller is completely inactive, unable to * generate interrupts or do DMA. -@@ -712,8 +718,17 @@ reset_needed: +@@ -710,8 +716,17 @@ reset_needed: uhci_reset_hc(pdev, base); return 1; } @@ -48,7 +48,7 @@ Signed-off-by: Felix Fietkau static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask) { u16 cmd; -@@ -1285,3 +1300,4 @@ static void quirk_usb_early_handoff(stru +@@ -1283,3 +1298,4 @@ static void quirk_usb_early_handoff(stru } DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_SERIAL_USB, 8, quirk_usb_early_handoff); @@ -98,7 +98,7 @@ Signed-off-by: Felix Fietkau #endif /* __LINUX_USB_PCI_QUIRKS_H */ --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h -@@ -483,7 +483,14 @@ extern int usb_hcd_pci_probe(struct pci_ +@@ -484,7 +484,14 @@ extern int usb_hcd_pci_probe(struct pci_ extern void usb_hcd_pci_remove(struct pci_dev *dev); extern void usb_hcd_pci_shutdown(struct pci_dev *dev); diff --git a/target/linux/generic/pending-6.1/901-usb-add-more-modem-support.patch b/target/linux/generic/pending-6.1/901-usb-add-more-modem-support.patch index 30d19e511..3a8cf03df 100644 --- a/target/linux/generic/pending-6.1/901-usb-add-more-modem-support.patch +++ b/target/linux/generic/pending-6.1/901-usb-add-more-modem-support.patch @@ -12,16 +12,17 @@ {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c -@@ -2277,6 +2277,12 @@ static const struct usb_device_id option - { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a3, 0xff) }, /* Fibocom FM101-GL (laptop MBIM) */ - { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a4, 0xff), /* Fibocom FM101-GL (laptop MBIM) */ - .driver_info = RSVD(4) }, -+ { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a04, 0xff), /* Fibocom FM650 ECM */ -+ .driver_info = RSVD(5) }, -+ { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a05, 0xff), /* Fibocom FM650 NCM */ -+ .driver_info = RSVD(6) }, -+ { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a06, 0xff), /* Fibocom FM650 RNDIS */ -+ .driver_info = RSVD(6) }, +@@ -2310,9 +2310,13 @@ static const struct usb_device_id option + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a06, 0xff) }, /* Fibocom FM650-CN (RNDIS mode) */ + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a07, 0xff) }, /* Fibocom FM650-CN (MBIM mode) */ { USB_DEVICE_INTERFACE_CLASS(0x2df3, 0x9d03, 0xff) }, /* LongSung M5710 */ ++ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1402, 0xff) }, /* GosunCn GM800 (Download mode) */ ++ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1403, 0xff) }, /* GosunCn GM800 (rmnet, old) */ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */ + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) }, /* GosunCn GM500 ECM/NCM */ ++ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1421, 0xff) }, /* GosunCn GM800 (rmnet) */ ++ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1422, 0xff) }, /* GosunCn GM800 (EAP) */ + { USB_DEVICE(0x33f8, 0x0104), /* Rolling RW101-GL (laptop RMNET) */ + .driver_info = RSVD(4) | RSVD(5) }, + { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x01a2, 0xff) }, /* Rolling RW101-GL (laptop MBIM) */ diff --git a/target/linux/generic/pending-6.1/920-mangle_bootargs.patch b/target/linux/generic/pending-6.1/920-mangle_bootargs.patch index 76e3f2544..ca36d0cca 100644 --- a/target/linux/generic/pending-6.1/920-mangle_bootargs.patch +++ b/target/linux/generic/pending-6.1/920-mangle_bootargs.patch @@ -61,7 +61,7 @@ Signed-off-by: Imre Kaloz /* * We need to store the untouched command line for future reference. * We also need to store the touched command line since the parameter -@@ -959,6 +982,7 @@ asmlinkage __visible void __init __no_sa +@@ -961,6 +984,7 @@ asmlinkage __visible void __init __no_sa pr_notice("%s", linux_banner); early_security_init(); setup_arch(&command_line); diff --git a/target/linux/generic/pending-6.6/150-bridge_allow_receiption_on_disabled_port.patch b/target/linux/generic/pending-6.6/150-bridge_allow_receiption_on_disabled_port.patch index b23cae1f5..d8fd9cdf4 100644 --- a/target/linux/generic/pending-6.6/150-bridge_allow_receiption_on_disabled_port.patch +++ b/target/linux/generic/pending-6.6/150-bridge_allow_receiption_on_disabled_port.patch @@ -15,7 +15,7 @@ Signed-off-by: Felix Fietkau --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c -@@ -239,6 +239,9 @@ static void __br_handle_local_finish(str +@@ -244,6 +244,9 @@ static void __br_handle_local_finish(str /* note: already called with rcu_read_lock */ static int br_handle_local_finish(struct net *net, struct sock *sk, struct sk_buff *skb) { @@ -25,7 +25,7 @@ Signed-off-by: Felix Fietkau __br_handle_local_finish(skb); /* return 1 to signal the okfn() was called so it's ok to use the skb */ -@@ -408,6 +411,17 @@ forward: +@@ -415,6 +418,17 @@ forward: goto defer_stp_filtering; switch (p->state) { diff --git a/target/linux/generic/pending-6.6/680-NET-skip-GRO-for-foreign-MAC-addresses.patch b/target/linux/generic/pending-6.6/680-NET-skip-GRO-for-foreign-MAC-addresses.patch deleted file mode 100644 index 0859e217c..000000000 --- a/target/linux/generic/pending-6.6/680-NET-skip-GRO-for-foreign-MAC-addresses.patch +++ /dev/null @@ -1,151 +0,0 @@ -From: Felix Fietkau -Subject: net: replace GRO optimization patch with a new one that supports VLANs/bridges with different MAC addresses - -Signed-off-by: Felix Fietkau ---- - include/linux/netdevice.h | 2 ++ - include/linux/skbuff.h | 3 ++- - net/core/dev.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++ - net/ethernet/eth.c | 18 +++++++++++++++++- - 4 files changed, 69 insertions(+), 2 deletions(-) - ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -2210,6 +2210,8 @@ struct net_device { - struct netdev_hw_addr_list mc; - struct netdev_hw_addr_list dev_addrs; - -+ unsigned char local_addr_mask[MAX_ADDR_LEN]; -+ - #ifdef CONFIG_SYSFS - struct kset *queues_kset; - #endif ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -959,6 +959,7 @@ struct sk_buff { - #ifdef CONFIG_IPV6_NDISC_NODETYPE - __u8 ndisc_nodetype:2; - #endif -+ __u8 gro_skip:1; - - #if IS_ENABLED(CONFIG_IP_VS) - __u8 ipvs_property:1; ---- a/net/core/gro.c -+++ b/net/core/gro.c -@@ -446,6 +446,9 @@ static enum gro_result dev_gro_receive(s - enum gro_result ret; - int same_flow; - -+ if (skb->gro_skip) -+ goto normal; -+ - if (netif_elide_gro(skb->dev)) - goto normal; - ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -7689,6 +7689,48 @@ static void __netdev_adjacent_dev_unlink - &upper_dev->adj_list.lower); - } - -+static void __netdev_addr_mask(unsigned char *mask, const unsigned char *addr, -+ struct net_device *dev) -+{ -+ int i; -+ -+ for (i = 0; i < dev->addr_len; i++) -+ mask[i] |= addr[i] ^ dev->dev_addr[i]; -+} -+ -+static void __netdev_upper_mask(unsigned char *mask, struct net_device *dev, -+ struct net_device *lower) -+{ -+ struct net_device *cur; -+ struct list_head *iter; -+ -+ netdev_for_each_upper_dev_rcu(dev, cur, iter) { -+ __netdev_addr_mask(mask, cur->dev_addr, lower); -+ __netdev_upper_mask(mask, cur, lower); -+ } -+} -+ -+static void __netdev_update_addr_mask(struct net_device *dev) -+{ -+ unsigned char mask[MAX_ADDR_LEN]; -+ struct net_device *cur; -+ struct list_head *iter; -+ -+ memset(mask, 0, sizeof(mask)); -+ __netdev_upper_mask(mask, dev, dev); -+ memcpy(dev->local_addr_mask, mask, dev->addr_len); -+ -+ netdev_for_each_lower_dev(dev, cur, iter) -+ __netdev_update_addr_mask(cur); -+} -+ -+static void netdev_update_addr_mask(struct net_device *dev) -+{ -+ rcu_read_lock(); -+ __netdev_update_addr_mask(dev); -+ rcu_read_unlock(); -+} -+ - static int __netdev_upper_dev_link(struct net_device *dev, - struct net_device *upper_dev, bool master, - void *upper_priv, void *upper_info, -@@ -7740,6 +7782,7 @@ static int __netdev_upper_dev_link(struc - if (ret) - return ret; - -+ netdev_update_addr_mask(dev); - ret = call_netdevice_notifiers_info(NETDEV_CHANGEUPPER, - &changeupper_info.info); - ret = notifier_to_errno(ret); -@@ -7836,6 +7879,7 @@ static void __netdev_upper_dev_unlink(st - - __netdev_adjacent_dev_unlink_neighbour(dev, upper_dev); - -+ netdev_update_addr_mask(dev); - call_netdevice_notifiers_info(NETDEV_CHANGEUPPER, - &changeupper_info.info); - -@@ -8892,6 +8936,7 @@ int dev_set_mac_address(struct net_devic - return err; - } - dev->addr_assign_type = NET_ADDR_SET; -+ netdev_update_addr_mask(dev); - call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); - add_device_randomness(dev->dev_addr, dev->addr_len); - return 0; ---- a/net/ethernet/eth.c -+++ b/net/ethernet/eth.c -@@ -143,6 +143,18 @@ u32 eth_get_headlen(const struct net_dev - } - EXPORT_SYMBOL(eth_get_headlen); - -+static inline bool -+eth_check_local_mask(const void *addr1, const void *addr2, const void *mask) -+{ -+ const u16 *a1 = addr1; -+ const u16 *a2 = addr2; -+ const u16 *m = mask; -+ -+ return (((a1[0] ^ a2[0]) & ~m[0]) | -+ ((a1[1] ^ a2[1]) & ~m[1]) | -+ ((a1[2] ^ a2[2]) & ~m[2])); -+} -+ - /** - * eth_type_trans - determine the packet's protocol ID. - * @skb: received socket data -@@ -174,6 +186,10 @@ __be16 eth_type_trans(struct sk_buff *sk - } else { - skb->pkt_type = PACKET_OTHERHOST; - } -+ -+ if (eth_check_local_mask(eth->h_dest, dev->dev_addr, -+ dev->local_addr_mask)) -+ skb->gro_skip = 1; - } - - /* diff --git a/target/linux/generic/pending-6.6/680-net-add-TCP-fraglist-GRO-support.patch b/target/linux/generic/pending-6.6/680-net-add-TCP-fraglist-GRO-support.patch new file mode 100644 index 000000000..cd7762667 --- /dev/null +++ b/target/linux/generic/pending-6.6/680-net-add-TCP-fraglist-GRO-support.patch @@ -0,0 +1,578 @@ +From: Felix Fietkau +Date: Tue, 23 Apr 2024 11:23:03 +0200 +Subject: [PATCH] net: add TCP fraglist GRO support + +When forwarding TCP after GRO, software segmentation is very expensive, +especially when the checksum needs to be recalculated. +One case where that's currently unavoidable is when routing packets over +PPPoE. Performance improves significantly when using fraglist GRO +implemented in the same way as for UDP. + +Here's a measurement of running 2 TCP streams through a MediaTek MT7622 +device (2-core Cortex-A53), which runs NAT with flow offload enabled from +one ethernet port to PPPoE on another ethernet port + cake qdisc set to +1Gbps. + +rx-gro-list off: 630 Mbit/s, CPU 35% idle +rx-gro-list on: 770 Mbit/s, CPU 40% idle + +Signe-off-by: Felix Fietkau +--- + +--- a/include/net/gro.h ++++ b/include/net/gro.h +@@ -439,6 +439,7 @@ static inline __wsum ip6_gro_compute_pse + } + + int skb_gro_receive(struct sk_buff *p, struct sk_buff *skb); ++int skb_gro_receive_list(struct sk_buff *p, struct sk_buff *skb); + + /* Pass the currently batched GRO_NORMAL SKBs up to the stack. */ + static inline void gro_normal_list(struct napi_struct *napi) +--- a/include/net/tcp.h ++++ b/include/net/tcp.h +@@ -2082,7 +2082,10 @@ void tcp_v4_destroy_sock(struct sock *sk + + struct sk_buff *tcp_gso_segment(struct sk_buff *skb, + netdev_features_t features); +-struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb); ++struct tcphdr *tcp_gro_pull_header(struct sk_buff *skb); ++struct sk_buff *tcp_gro_lookup(struct list_head *head, struct tcphdr *th); ++struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb, ++ struct tcphdr *th); + INDIRECT_CALLABLE_DECLARE(int tcp4_gro_complete(struct sk_buff *skb, int thoff)); + INDIRECT_CALLABLE_DECLARE(struct sk_buff *tcp4_gro_receive(struct list_head *head, struct sk_buff *skb)); + INDIRECT_CALLABLE_DECLARE(int tcp6_gro_complete(struct sk_buff *skb, int thoff)); +--- a/net/core/gro.c ++++ b/net/core/gro.c +@@ -233,6 +233,33 @@ done: + return 0; + } + ++int skb_gro_receive_list(struct sk_buff *p, struct sk_buff *skb) ++{ ++ if (unlikely(p->len + skb->len >= 65536)) ++ return -E2BIG; ++ ++ if (NAPI_GRO_CB(p)->last == p) ++ skb_shinfo(p)->frag_list = skb; ++ else ++ NAPI_GRO_CB(p)->last->next = skb; ++ ++ skb_pull(skb, skb_gro_offset(skb)); ++ ++ NAPI_GRO_CB(p)->last = skb; ++ NAPI_GRO_CB(p)->count++; ++ p->data_len += skb->len; ++ ++ /* sk ownership - if any - completely transferred to the aggregated packet */ ++ skb->destructor = NULL; ++ skb->sk = NULL; ++ p->truesize += skb->truesize; ++ p->len += skb->len; ++ ++ NAPI_GRO_CB(skb)->same_flow = 1; ++ ++ return 0; ++} ++ + + static void napi_gro_complete(struct napi_struct *napi, struct sk_buff *skb) + { +--- a/net/ipv4/tcp_offload.c ++++ b/net/ipv4/tcp_offload.c +@@ -28,6 +28,70 @@ static void tcp_gso_tstamp(struct sk_buf + } + } + ++static void __tcpv4_gso_segment_csum(struct sk_buff *seg, ++ __be32 *oldip, __be32 newip, ++ __be16 *oldport, __be16 newport) ++{ ++ struct tcphdr *th; ++ struct iphdr *iph; ++ ++ if (*oldip == newip && *oldport == newport) ++ return; ++ ++ th = tcp_hdr(seg); ++ iph = ip_hdr(seg); ++ ++ inet_proto_csum_replace4(&th->check, seg, *oldip, newip, true); ++ inet_proto_csum_replace2(&th->check, seg, *oldport, newport, false); ++ *oldport = newport; ++ ++ csum_replace4(&iph->check, *oldip, newip); ++ *oldip = newip; ++} ++ ++static struct sk_buff *__tcpv4_gso_segment_list_csum(struct sk_buff *segs) ++{ ++ const struct tcphdr *th; ++ const struct iphdr *iph; ++ struct sk_buff *seg; ++ struct tcphdr *th2; ++ struct iphdr *iph2; ++ ++ seg = segs; ++ th = tcp_hdr(seg); ++ iph = ip_hdr(seg); ++ th2 = tcp_hdr(seg->next); ++ iph2 = ip_hdr(seg->next); ++ ++ if (!(*(const u32 *)&th->source ^ *(const u32 *)&th2->source) && ++ iph->daddr == iph2->daddr && iph->saddr == iph2->saddr) ++ return segs; ++ ++ while ((seg = seg->next)) { ++ th2 = tcp_hdr(seg); ++ iph2 = ip_hdr(seg); ++ ++ __tcpv4_gso_segment_csum(seg, ++ &iph2->saddr, iph->saddr, ++ &th2->source, th->source); ++ __tcpv4_gso_segment_csum(seg, ++ &iph2->daddr, iph->daddr, ++ &th2->dest, th->dest); ++ } ++ ++ return segs; ++} ++ ++static struct sk_buff *__tcp4_gso_segment_list(struct sk_buff *skb, ++ netdev_features_t features) ++{ ++ skb = skb_segment_list(skb, features, skb_mac_header_len(skb)); ++ if (IS_ERR(skb)) ++ return skb; ++ ++ return __tcpv4_gso_segment_list_csum(skb); ++} ++ + static struct sk_buff *tcp4_gso_segment(struct sk_buff *skb, + netdev_features_t features) + { +@@ -37,6 +101,9 @@ static struct sk_buff *tcp4_gso_segment( + if (!pskb_may_pull(skb, sizeof(struct tcphdr))) + return ERR_PTR(-EINVAL); + ++ if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST) ++ return __tcp4_gso_segment_list(skb, features); ++ + if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) { + const struct iphdr *iph = ip_hdr(skb); + struct tcphdr *th = tcp_hdr(skb); +@@ -178,61 +245,76 @@ out: + return segs; + } + +-struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb) ++struct sk_buff *tcp_gro_lookup(struct list_head *head, struct tcphdr *th) + { +- struct sk_buff *pp = NULL; ++ struct tcphdr *th2; + struct sk_buff *p; ++ ++ list_for_each_entry(p, head, list) { ++ if (!NAPI_GRO_CB(p)->same_flow) ++ continue; ++ ++ th2 = tcp_hdr(p); ++ if (*(u32 *)&th->source ^ *(u32 *)&th2->source) { ++ NAPI_GRO_CB(p)->same_flow = 0; ++ continue; ++ } ++ ++ return p; ++ } ++ ++ return NULL; ++} ++ ++struct tcphdr *tcp_gro_pull_header(struct sk_buff *skb) ++{ ++ unsigned int thlen, hlen, off; + struct tcphdr *th; +- struct tcphdr *th2; +- unsigned int len; +- unsigned int thlen; +- __be32 flags; +- unsigned int mss = 1; +- unsigned int hlen; +- unsigned int off; +- int flush = 1; +- int i; + + off = skb_gro_offset(skb); + hlen = off + sizeof(*th); + th = skb_gro_header(skb, hlen, off); + if (unlikely(!th)) +- goto out; ++ return NULL; + + thlen = th->doff * 4; + if (thlen < sizeof(*th)) +- goto out; ++ return NULL; + + hlen = off + thlen; + if (skb_gro_header_hard(skb, hlen)) { + th = skb_gro_header_slow(skb, hlen, off); + if (unlikely(!th)) +- goto out; ++ return NULL; + } + + skb_gro_pull(skb, thlen); + +- len = skb_gro_len(skb); +- flags = tcp_flag_word(th); +- +- list_for_each_entry(p, head, list) { +- if (!NAPI_GRO_CB(p)->same_flow) +- continue; ++ return th; ++} + +- th2 = tcp_hdr(p); ++struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb, ++ struct tcphdr *th) ++{ ++ unsigned int thlen = th->doff * 4; ++ struct sk_buff *pp = NULL; ++ struct sk_buff *p; ++ struct tcphdr *th2; ++ unsigned int len; ++ __be32 flags; ++ unsigned int mss = 1; ++ int flush = 1; ++ int i; + +- if (*(u32 *)&th->source ^ *(u32 *)&th2->source) { +- NAPI_GRO_CB(p)->same_flow = 0; +- continue; +- } ++ len = skb_gro_len(skb); ++ flags = tcp_flag_word(th); + +- goto found; +- } +- p = NULL; +- goto out_check_final; ++ p = tcp_gro_lookup(head, th); ++ if (!p) ++ goto out_check_final; + +-found: + /* Include the IP ID check below from the inner most IP hdr */ ++ th2 = tcp_hdr(p); + flush = NAPI_GRO_CB(p)->flush; + flush |= (__force int)(flags & TCP_FLAG_CWR); + flush |= (__force int)((flags ^ tcp_flag_word(th2)) & +@@ -269,6 +351,19 @@ found: + flush |= p->decrypted ^ skb->decrypted; + #endif + ++ if (unlikely(NAPI_GRO_CB(p)->is_flist)) { ++ flush |= (__force int)(flags ^ tcp_flag_word(th2)); ++ flush |= skb->ip_summed != p->ip_summed; ++ flush |= skb->csum_level != p->csum_level; ++ flush |= !pskb_may_pull(skb, skb_gro_offset(skb)); ++ flush |= NAPI_GRO_CB(p)->count >= 64; ++ ++ if (flush || skb_gro_receive_list(p, skb)) ++ mss = 1; ++ ++ goto out_check_final; ++ } ++ + if (flush || skb_gro_receive(p, skb)) { + mss = 1; + goto out_check_final; +@@ -290,7 +385,6 @@ out_check_final: + if (p && (!NAPI_GRO_CB(skb)->same_flow || flush)) + pp = p; + +-out: + NAPI_GRO_CB(skb)->flush |= (flush != 0); + + return pp; +@@ -314,18 +408,58 @@ void tcp_gro_complete(struct sk_buff *sk + } + EXPORT_SYMBOL(tcp_gro_complete); + ++static void tcp4_check_fraglist_gro(struct list_head *head, struct sk_buff *skb, ++ struct tcphdr *th) ++{ ++ const struct iphdr *iph; ++ struct sk_buff *p; ++ struct sock *sk; ++ struct net *net; ++ int iif, sdif; ++ ++ if (!(skb->dev->features & NETIF_F_GRO_FRAGLIST)) ++ return; ++ ++ p = tcp_gro_lookup(head, th); ++ if (p) { ++ NAPI_GRO_CB(skb)->is_flist = NAPI_GRO_CB(p)->is_flist; ++ return; ++ } ++ ++ inet_get_iif_sdif(skb, &iif, &sdif); ++ iph = skb_gro_network_header(skb); ++ net = dev_net(skb->dev); ++ sk = __inet_lookup_established(net, net->ipv4.tcp_death_row.hashinfo, ++ iph->saddr, th->source, ++ iph->daddr, ntohs(th->dest), ++ iif, sdif); ++ NAPI_GRO_CB(skb)->is_flist = !sk; ++ if (sk) ++ sock_put(sk); ++} ++ + INDIRECT_CALLABLE_SCOPE + struct sk_buff *tcp4_gro_receive(struct list_head *head, struct sk_buff *skb) + { ++ struct tcphdr *th; ++ + /* Don't bother verifying checksum if we're going to flush anyway. */ + if (!NAPI_GRO_CB(skb)->flush && + skb_gro_checksum_validate(skb, IPPROTO_TCP, +- inet_gro_compute_pseudo)) { +- NAPI_GRO_CB(skb)->flush = 1; +- return NULL; +- } ++ inet_gro_compute_pseudo)) ++ goto flush; ++ ++ th = tcp_gro_pull_header(skb); ++ if (!th) ++ goto flush; + +- return tcp_gro_receive(head, skb); ++ tcp4_check_fraglist_gro(head, skb, th); ++ ++ return tcp_gro_receive(head, skb, th); ++ ++flush: ++ NAPI_GRO_CB(skb)->flush = 1; ++ return NULL; + } + + INDIRECT_CALLABLE_SCOPE int tcp4_gro_complete(struct sk_buff *skb, int thoff) +@@ -333,6 +467,15 @@ INDIRECT_CALLABLE_SCOPE int tcp4_gro_com + const struct iphdr *iph = ip_hdr(skb); + struct tcphdr *th = tcp_hdr(skb); + ++ if (unlikely(NAPI_GRO_CB(skb)->is_flist)) { ++ skb_shinfo(skb)->gso_type |= SKB_GSO_FRAGLIST | SKB_GSO_TCPV4; ++ skb_shinfo(skb)->gso_segs = NAPI_GRO_CB(skb)->count; ++ ++ __skb_incr_checksum_unnecessary(skb); ++ ++ return 0; ++ } ++ + th->check = ~tcp_v4_check(skb->len - thoff, iph->saddr, + iph->daddr, 0); + skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV4; +--- a/net/ipv4/udp_offload.c ++++ b/net/ipv4/udp_offload.c +@@ -433,33 +433,6 @@ out: + return segs; + } + +-static int skb_gro_receive_list(struct sk_buff *p, struct sk_buff *skb) +-{ +- if (unlikely(p->len + skb->len >= 65536)) +- return -E2BIG; +- +- if (NAPI_GRO_CB(p)->last == p) +- skb_shinfo(p)->frag_list = skb; +- else +- NAPI_GRO_CB(p)->last->next = skb; +- +- skb_pull(skb, skb_gro_offset(skb)); +- +- NAPI_GRO_CB(p)->last = skb; +- NAPI_GRO_CB(p)->count++; +- p->data_len += skb->len; +- +- /* sk ownership - if any - completely transferred to the aggregated packet */ +- skb->destructor = NULL; +- skb->sk = NULL; +- p->truesize += skb->truesize; +- p->len += skb->len; +- +- NAPI_GRO_CB(skb)->same_flow = 1; +- +- return 0; +-} +- + + #define UDP_GRO_CNT_MAX 64 + static struct sk_buff *udp_gro_receive_segment(struct list_head *head, +--- a/net/ipv6/tcpv6_offload.c ++++ b/net/ipv6/tcpv6_offload.c +@@ -7,24 +7,67 @@ + */ + #include + #include ++#include + #include + #include + #include + #include + #include "ip6_offload.h" + ++static void tcp6_check_fraglist_gro(struct list_head *head, struct sk_buff *skb, ++ struct tcphdr *th) ++{ ++#if IS_ENABLED(CONFIG_IPV6) ++ const struct ipv6hdr *hdr; ++ struct sk_buff *p; ++ struct sock *sk; ++ struct net *net; ++ int iif, sdif; ++ ++ if (!(skb->dev->features & NETIF_F_GRO_FRAGLIST)) ++ return; ++ ++ p = tcp_gro_lookup(head, th); ++ if (p) { ++ NAPI_GRO_CB(skb)->is_flist = NAPI_GRO_CB(p)->is_flist; ++ return; ++ } ++ ++ inet6_get_iif_sdif(skb, &iif, &sdif); ++ hdr = skb_gro_network_header(skb); ++ net = dev_net(skb->dev); ++ sk = __inet6_lookup_established(net, net->ipv4.tcp_death_row.hashinfo, ++ &hdr->saddr, th->source, ++ &hdr->daddr, ntohs(th->dest), ++ iif, sdif); ++ NAPI_GRO_CB(skb)->is_flist = !sk; ++ if (sk) ++ sock_put(sk); ++#endif /* IS_ENABLED(CONFIG_IPV6) */ ++} ++ + INDIRECT_CALLABLE_SCOPE + struct sk_buff *tcp6_gro_receive(struct list_head *head, struct sk_buff *skb) + { ++ struct tcphdr *th; ++ + /* Don't bother verifying checksum if we're going to flush anyway. */ + if (!NAPI_GRO_CB(skb)->flush && + skb_gro_checksum_validate(skb, IPPROTO_TCP, +- ip6_gro_compute_pseudo)) { +- NAPI_GRO_CB(skb)->flush = 1; +- return NULL; +- } ++ ip6_gro_compute_pseudo)) ++ goto flush; + +- return tcp_gro_receive(head, skb); ++ th = tcp_gro_pull_header(skb); ++ if (!th) ++ goto flush; ++ ++ tcp6_check_fraglist_gro(head, skb, th); ++ ++ return tcp_gro_receive(head, skb, th); ++ ++flush: ++ NAPI_GRO_CB(skb)->flush = 1; ++ return NULL; + } + + INDIRECT_CALLABLE_SCOPE int tcp6_gro_complete(struct sk_buff *skb, int thoff) +@@ -32,6 +75,15 @@ INDIRECT_CALLABLE_SCOPE int tcp6_gro_com + const struct ipv6hdr *iph = ipv6_hdr(skb); + struct tcphdr *th = tcp_hdr(skb); + ++ if (unlikely(NAPI_GRO_CB(skb)->is_flist)) { ++ skb_shinfo(skb)->gso_type |= SKB_GSO_FRAGLIST | SKB_GSO_TCPV6; ++ skb_shinfo(skb)->gso_segs = NAPI_GRO_CB(skb)->count; ++ ++ __skb_incr_checksum_unnecessary(skb); ++ ++ return 0; ++ } ++ + th->check = ~tcp_v6_check(skb->len - thoff, &iph->saddr, + &iph->daddr, 0); + skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV6; +@@ -40,6 +92,61 @@ INDIRECT_CALLABLE_SCOPE int tcp6_gro_com + return 0; + } + ++static void __tcpv6_gso_segment_csum(struct sk_buff *seg, ++ __be16 *oldport, __be16 newport) ++{ ++ struct tcphdr *th; ++ ++ if (*oldport == newport) ++ return; ++ ++ th = tcp_hdr(seg); ++ inet_proto_csum_replace2(&th->check, seg, *oldport, newport, false); ++ *oldport = newport; ++} ++ ++static struct sk_buff *__tcpv6_gso_segment_list_csum(struct sk_buff *segs) ++{ ++ const struct tcphdr *th; ++ const struct ipv6hdr *iph; ++ struct sk_buff *seg; ++ struct tcphdr *th2; ++ struct ipv6hdr *iph2; ++ ++ seg = segs; ++ th = tcp_hdr(seg); ++ iph = ipv6_hdr(seg); ++ th2 = tcp_hdr(seg->next); ++ iph2 = ipv6_hdr(seg->next); ++ ++ if (!(*(const u32 *)&th->source ^ *(const u32 *)&th2->source) && ++ ipv6_addr_equal(&iph->saddr, &iph2->saddr) && ++ ipv6_addr_equal(&iph->daddr, &iph2->daddr)) ++ return segs; ++ ++ while ((seg = seg->next)) { ++ th2 = tcp_hdr(seg); ++ iph2 = ipv6_hdr(seg); ++ ++ iph2->saddr = iph->saddr; ++ iph2->daddr = iph->daddr; ++ __tcpv6_gso_segment_csum(seg, &th2->source, th->source); ++ __tcpv6_gso_segment_csum(seg, &th2->dest, th->dest); ++ } ++ ++ return segs; ++} ++ ++static struct sk_buff *__tcp6_gso_segment_list(struct sk_buff *skb, ++ netdev_features_t features) ++{ ++ skb = skb_segment_list(skb, features, skb_mac_header_len(skb)); ++ if (IS_ERR(skb)) ++ return skb; ++ ++ return __tcpv6_gso_segment_list_csum(skb); ++} ++ + static struct sk_buff *tcp6_gso_segment(struct sk_buff *skb, + netdev_features_t features) + { +@@ -51,6 +158,9 @@ static struct sk_buff *tcp6_gso_segment( + if (!pskb_may_pull(skb, sizeof(*th))) + return ERR_PTR(-EINVAL); + ++ if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST) ++ return __tcp6_gso_segment_list(skb, features); ++ + if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) { + const struct ipv6hdr *ipv6h = ipv6_hdr(skb); + struct tcphdr *th = tcp_hdr(skb); diff --git a/target/linux/generic/pending-6.6/681-net-bridge-fix-multicast-to-unicast-with-fraglist-GS.patch b/target/linux/generic/pending-6.6/681-net-bridge-fix-multicast-to-unicast-with-fraglist-GS.patch new file mode 100644 index 000000000..8361bb16a --- /dev/null +++ b/target/linux/generic/pending-6.6/681-net-bridge-fix-multicast-to-unicast-with-fraglist-GS.patch @@ -0,0 +1,23 @@ +From: Felix Fietkau +Date: Sat, 27 Apr 2024 18:54:25 +0200 +Subject: [PATCH] net: bridge: fix multicast-to-unicast with fraglist GSO + +Calling skb_copy on a SKB_GSO_FRAGLIST skb is not valid, since it returns +an invalid linearized skb. This code only needs to change the ethernet +header, so pskb_copy is the right function to call here. + +Fixes: 6db6f0eae605 ("bridge: multicast to unicast") +Signed-off-by: Felix Fietkau +--- + +--- a/net/bridge/br_forward.c ++++ b/net/bridge/br_forward.c +@@ -266,7 +266,7 @@ static void maybe_deliver_addr(struct ne + if (skb->dev == p->dev && ether_addr_equal(src, addr)) + return; + +- skb = skb_copy(skb, GFP_ATOMIC); ++ skb = pskb_copy(skb, GFP_ATOMIC); + if (!skb) { + DEV_STATS_INC(dev, tx_dropped); + return; diff --git a/target/linux/generic/pending-6.6/682-net-core-reject-skb_copy-_expand-for-fraglist-GSO-sk.patch b/target/linux/generic/pending-6.6/682-net-core-reject-skb_copy-_expand-for-fraglist-GSO-sk.patch new file mode 100644 index 000000000..215b4756a --- /dev/null +++ b/target/linux/generic/pending-6.6/682-net-core-reject-skb_copy-_expand-for-fraglist-GSO-sk.patch @@ -0,0 +1,59 @@ +From: Felix Fietkau +Date: Sat, 27 Apr 2024 19:29:45 +0200 +Subject: [PATCH] net: core: reject skb_copy(_expand) for fraglist GSO skbs + +SKB_GSO_FRAGLIST skbs must not be linearized, otherwise they become +invalid. Return NULL if such an skb is passed to skb_copy or +skb_copy_expand, in order to prevent a crash on a potential later +call to skb_gso_segment. + +Fixes: 3a1296a38d0c ("net: Support GRO/GSO fraglist chaining.") +Signed-off-by: Felix Fietkau +--- + +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -1971,11 +1971,17 @@ static inline int skb_alloc_rx_flag(cons + + struct sk_buff *skb_copy(const struct sk_buff *skb, gfp_t gfp_mask) + { +- int headerlen = skb_headroom(skb); +- unsigned int size = skb_end_offset(skb) + skb->data_len; +- struct sk_buff *n = __alloc_skb(size, gfp_mask, +- skb_alloc_rx_flag(skb), NUMA_NO_NODE); ++ struct sk_buff *n; ++ unsigned int size; ++ int headerlen; + ++ if (WARN_ON_ONCE(skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST)) ++ return NULL; ++ ++ headerlen = skb_headroom(skb); ++ size = skb_end_offset(skb) + skb->data_len; ++ n = __alloc_skb(size, gfp_mask, ++ skb_alloc_rx_flag(skb), NUMA_NO_NODE); + if (!n) + return NULL; + +@@ -2303,12 +2309,17 @@ struct sk_buff *skb_copy_expand(const st + /* + * Allocate the copy buffer + */ +- struct sk_buff *n = __alloc_skb(newheadroom + skb->len + newtailroom, +- gfp_mask, skb_alloc_rx_flag(skb), +- NUMA_NO_NODE); +- int oldheadroom = skb_headroom(skb); + int head_copy_len, head_copy_off; ++ struct sk_buff *n; ++ int oldheadroom; ++ ++ if (WARN_ON_ONCE(skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST)) ++ return NULL; + ++ oldheadroom = skb_headroom(skb); ++ n = __alloc_skb(newheadroom + skb->len + newtailroom, ++ gfp_mask, skb_alloc_rx_flag(skb), ++ NUMA_NO_NODE); + if (!n) + return NULL; + diff --git a/target/linux/generic/pending-6.6/682-of_net-add-mac-address-increment-support.patch b/target/linux/generic/pending-6.6/682-of_net-add-mac-address-increment-support.patch deleted file mode 100644 index 24c04a19b..000000000 --- a/target/linux/generic/pending-6.6/682-of_net-add-mac-address-increment-support.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 844c273286f328acf0dab5fbd5d864366b4904dc Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Tue, 30 Mar 2021 18:21:14 +0200 -Subject: [PATCH] of_net: add mac-address-increment support - -Lots of embedded devices use the mac-address of other interface -extracted from nvmem cells and increments it by one or two. Add two -bindings to integrate this and directly use the right mac-address for -the interface. Some example are some routers that use the gmac -mac-address stored in the art partition and increments it by one for the -wifi. mac-address-increment-byte bindings is used to tell what byte of -the mac-address has to be increased (if not defined the last byte is -increased) and mac-address-increment tells how much the byte decided -early has to be increased. - -Signed-off-by: Ansuel Smith ---- - net/core/of_net.c | 43 +++++++++++++++++++++++++++++++++++++++---- - 1 file changed, 39 insertions(+), 4 deletions(-) - ---- a/net/core/of_net.c -+++ b/net/core/of_net.c -@@ -121,28 +121,63 @@ EXPORT_SYMBOL(of_get_mac_address_nvmem); - * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists - * but is all zeros. - * -+ * DT can tell the system to increment the mac-address after is extracted by -+ * using: -+ * - mac-address-increment-byte to decide what byte to increase -+ * (if not defined is increased the last byte) -+ * - mac-address-increment to decide how much to increase. The value WILL -+ * overflow to other bytes if the increment is over 255 or the total -+ * increment will exceed 255 of the current byte. -+ * (example 00:01:02:03:04:ff + 1 == 00:01:02:03:05:00) -+ * (example 00:01:02:03:04:fe + 5 == 00:01:02:03:05:03) -+ * - * Return: 0 on success and errno in case of error. - */ - int of_get_mac_address(struct device_node *np, u8 *addr) - { -+ u32 inc_idx, mac_inc, mac_val; - int ret; - -+ /* Check first if the increment byte is present and valid. -+ * If not set assume to increment the last byte if found. -+ */ -+ if (of_property_read_u32(np, "mac-address-increment-byte", &inc_idx)) -+ inc_idx = 5; -+ if (inc_idx < 3 || inc_idx > 5) -+ return -EINVAL; -+ - if (!np) - return -ENODEV; - - ret = of_get_mac_addr(np, "mac-address", addr); - if (!ret) -- return 0; -+ goto found; - - ret = of_get_mac_addr(np, "local-mac-address", addr); - if (!ret) -- return 0; -+ goto found; - - ret = of_get_mac_addr(np, "address", addr); - if (!ret) -- return 0; -+ goto found; -+ -+ ret = of_get_mac_address_nvmem(np, addr); -+ if (ret) -+ return ret; -+ -+found: -+ if (!of_property_read_u32(np, "mac-address-increment", &mac_inc)) { -+ /* Convert to a contiguous value */ -+ mac_val = (addr[3] << 16) + (addr[4] << 8) + addr[5]; -+ mac_val += mac_inc << 8 * (5-inc_idx); -+ -+ /* Apply the incremented value handling overflow case */ -+ addr[3] = (mac_val >> 16) & 0xff; -+ addr[4] = (mac_val >> 8) & 0xff; -+ addr[5] = (mac_val >> 0) & 0xff; -+ } - -- return of_get_mac_address_nvmem(np, addr); -+ return ret; - } - EXPORT_SYMBOL(of_get_mac_address); - diff --git a/target/linux/generic/pending-6.6/683-of_net-add-mac-address-to-of-tree.patch b/target/linux/generic/pending-6.6/683-of_net-add-mac-address-to-of-tree.patch index 89b4d70c1..0fb02dbb6 100644 --- a/target/linux/generic/pending-6.6/683-of_net-add-mac-address-to-of-tree.patch +++ b/target/linux/generic/pending-6.6/683-of_net-add-mac-address-to-of-tree.patch @@ -45,11 +45,31 @@ property. This way, the MAC address can be accessed using procfs. /** * of_get_mac_address() * @np: Caller's Device Node -@@ -177,6 +198,7 @@ found: - addr[5] = (mac_val >> 0) & 0xff; - } +@@ -132,17 +153,23 @@ int of_get_mac_address(struct device_nod -+ of_add_mac_address(np, addr); - return ret; + ret = of_get_mac_addr(np, "mac-address", addr); + if (!ret) +- return 0; ++ goto found; + + ret = of_get_mac_addr(np, "local-mac-address", addr); + if (!ret) +- return 0; ++ goto found; + + ret = of_get_mac_addr(np, "address", addr); + if (!ret) +- return 0; ++ goto found; + +- return of_get_mac_address_nvmem(np, addr); ++ ret = of_get_mac_address_nvmem(np, addr); ++ if (ret) ++ return ret; ++ ++found: ++ ret = of_add_mac_address(np, addr); ++ return ret; } EXPORT_SYMBOL(of_get_mac_address); + diff --git a/target/linux/generic/pending-6.6/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch b/target/linux/generic/pending-6.6/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch index e54dcdadb..07e923b69 100644 --- a/target/linux/generic/pending-6.6/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch +++ b/target/linux/generic/pending-6.6/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch @@ -18,7 +18,7 @@ Signed-off-by: Felix Fietkau --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c -@@ -8260,7 +8260,7 @@ static int nft_register_flowtable_net_ho +@@ -8268,7 +8268,7 @@ static int nft_register_flowtable_net_ho err = flowtable->data.type->setup(&flowtable->data, hook->ops.dev, FLOW_BLOCK_BIND); diff --git a/target/linux/generic/pending-6.6/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch b/target/linux/generic/pending-6.6/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch index 05711780f..dd5608b24 100644 --- a/target/linux/generic/pending-6.6/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch +++ b/target/linux/generic/pending-6.6/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch @@ -45,7 +45,7 @@ Signed-off-by: Felix Fietkau if (!(p->flags & BR_BCAST_FLOOD) && skb->dev != br->dev) --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c -@@ -362,6 +362,8 @@ static rx_handler_result_t br_handle_fra +@@ -367,6 +367,8 @@ static rx_handler_result_t br_handle_fra fwd_mask |= p->group_fwd_mask; switch (dest[5]) { case 0x00: /* Bridge Group Address */ diff --git a/target/linux/generic/pending-6.6/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch b/target/linux/generic/pending-6.6/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch index 96eec71f5..14095f208 100644 --- a/target/linux/generic/pending-6.6/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch +++ b/target/linux/generic/pending-6.6/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch @@ -15,7 +15,7 @@ Signed-off-by: Alexander Couzens --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2465,6 +2465,10 @@ mt7530_setup(struct dsa_switch *ds) +@@ -2467,6 +2467,10 @@ mt7530_setup(struct dsa_switch *ds) return -ENODEV; } diff --git a/target/linux/generic/pending-6.6/760-net-core-add-optional-threading-for-backlog-processi.patch b/target/linux/generic/pending-6.6/760-net-core-add-optional-threading-for-backlog-processi.patch index a918ba31d..e456133a1 100644 --- a/target/linux/generic/pending-6.6/760-net-core-add-optional-threading-for-backlog-processi.patch +++ b/target/linux/generic/pending-6.6/760-net-core-add-optional-threading-for-backlog-processi.patch @@ -177,15 +177,15 @@ Signed-off-by: Felix Fietkau sd->backlog.weight = weight_p; --- a/net/core/sysctl_net_core.c +++ b/net/core/sysctl_net_core.c -@@ -30,6 +30,7 @@ static int int_3600 = 3600; - static int min_sndbuf = SOCK_MIN_SNDBUF; +@@ -31,6 +31,7 @@ static int min_sndbuf = SOCK_MIN_SNDBUF; static int min_rcvbuf = SOCK_MIN_RCVBUF; static int max_skb_frags = MAX_SKB_FRAGS; + static int min_mem_pcpu_rsv = SK_MEMORY_PCPU_RESERVE; +static int backlog_threaded; static int net_msg_warn; /* Unused, but still a sysctl */ -@@ -188,6 +189,23 @@ static int rps_sock_flow_sysctl(struct c +@@ -189,6 +190,23 @@ static int rps_sock_flow_sysctl(struct c } #endif /* CONFIG_RPS */ @@ -209,7 +209,7 @@ Signed-off-by: Felix Fietkau #ifdef CONFIG_NET_FLOW_LIMIT static DEFINE_MUTEX(flow_limit_update_mutex); -@@ -532,6 +550,15 @@ static struct ctl_table net_core_table[] +@@ -541,6 +559,15 @@ static struct ctl_table net_core_table[] .proc_handler = rps_sock_flow_sysctl }, #endif diff --git a/target/linux/generic/pending-6.6/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch b/target/linux/generic/pending-6.6/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch index d11e0eda6..28d89eb0f 100644 --- a/target/linux/generic/pending-6.6/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch +++ b/target/linux/generic/pending-6.6/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch @@ -17,7 +17,7 @@ Signed-off-by: Tobias Waldekranz --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -6887,6 +6887,7 @@ static int mv88e6xxx_register_switch(str +@@ -6935,6 +6935,7 @@ static int mv88e6xxx_register_switch(str ds->ops = &mv88e6xxx_switch_ops; ds->ageing_time_min = chip->info->age_time_coeff; ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX; diff --git a/target/linux/generic/pending-6.6/795-mt7530-register-OF-node-for-internal-MDIO-bus.patch b/target/linux/generic/pending-6.6/795-mt7530-register-OF-node-for-internal-MDIO-bus.patch index 82ab924e2..1ddfd0af7 100644 --- a/target/linux/generic/pending-6.6/795-mt7530-register-OF-node-for-internal-MDIO-bus.patch +++ b/target/linux/generic/pending-6.6/795-mt7530-register-OF-node-for-internal-MDIO-bus.patch @@ -16,7 +16,7 @@ Signed-off-by: David Bauer --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c -@@ -2353,10 +2353,13 @@ mt7530_setup_mdio(struct mt7530_priv *pr +@@ -2355,10 +2355,13 @@ mt7530_setup_mdio(struct mt7530_priv *pr { struct dsa_switch *ds = priv->ds; struct device *dev = priv->dev; @@ -30,7 +30,7 @@ Signed-off-by: David Bauer bus = devm_mdiobus_alloc(dev); if (!bus) return -ENOMEM; -@@ -2375,7 +2378,9 @@ mt7530_setup_mdio(struct mt7530_priv *pr +@@ -2377,7 +2380,9 @@ mt7530_setup_mdio(struct mt7530_priv *pr if (priv->irq) mt7530_setup_mdio_irq(priv); diff --git a/target/linux/generic/pending-6.6/811-pci_disable_usb_common_quirks.patch b/target/linux/generic/pending-6.6/811-pci_disable_usb_common_quirks.patch index 4c271a7bd..e91d1ef6b 100644 --- a/target/linux/generic/pending-6.6/811-pci_disable_usb_common_quirks.patch +++ b/target/linux/generic/pending-6.6/811-pci_disable_usb_common_quirks.patch @@ -98,7 +98,7 @@ Signed-off-by: Felix Fietkau #endif /* __LINUX_USB_PCI_QUIRKS_H */ --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h -@@ -484,7 +484,14 @@ extern int usb_hcd_pci_probe(struct pci_ +@@ -485,7 +485,14 @@ extern int usb_hcd_pci_probe(struct pci_ extern void usb_hcd_pci_remove(struct pci_dev *dev); extern void usb_hcd_pci_shutdown(struct pci_dev *dev); diff --git a/target/linux/generic/pending-6.6/901-usb-add-more-modem-support.patch b/target/linux/generic/pending-6.6/901-usb-add-more-modem-support.patch new file mode 100644 index 000000000..66b5640a1 --- /dev/null +++ b/target/linux/generic/pending-6.6/901-usb-add-more-modem-support.patch @@ -0,0 +1,28 @@ +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -1431,6 +1431,9 @@ static const struct usb_device_id produc + {QMI_FIXED_INTF(0x2692, 0x9025, 4)}, /* Cellient MPL200 (rebranded Qualcomm 05c6:9025) */ + {QMI_QUIRK_SET_DTR(0x1546, 0x1312, 4)}, /* u-blox LARA-R6 01B */ + {QMI_QUIRK_SET_DTR(0x1546, 0x1342, 4)}, /* u-blox LARA-L6 */ ++ {QMI_FIXED_INTF(0x2077, 0x2002, 4)}, /* T&W TW04C */ ++ {QMI_FIXED_INTF(0x2077, 0x2003, 4)}, /* T&W TW12G */ ++ {QMI_FIXED_INTF(0x2077, 0x2004, 4)}, /* T&W TW510M */ + + /* 4. Gobi 1000 devices */ + {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -2310,9 +2310,13 @@ static const struct usb_device_id option + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a06, 0xff) }, /* Fibocom FM650-CN (RNDIS mode) */ + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a07, 0xff) }, /* Fibocom FM650-CN (MBIM mode) */ + { USB_DEVICE_INTERFACE_CLASS(0x2df3, 0x9d03, 0xff) }, /* LongSung M5710 */ ++ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1402, 0xff) }, /* GosunCn GM800 (Download mode) */ ++ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1403, 0xff) }, /* GosunCn GM800 (rmnet, old) */ + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */ + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */ + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) }, /* GosunCn GM500 ECM/NCM */ ++ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1421, 0xff) }, /* GosunCn GM800 (rmnet) */ ++ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1422, 0xff) }, /* GosunCn GM800 (EAP) */ + { USB_DEVICE(0x33f8, 0x0104), /* Rolling RW101-GL (laptop RMNET) */ + .driver_info = RSVD(4) | RSVD(5) }, + { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x01a2, 0xff) }, /* Rolling RW101-GL (laptop MBIM) */ diff --git a/target/linux/generic/pending-6.6/920-mangle_bootargs.patch b/target/linux/generic/pending-6.6/920-mangle_bootargs.patch index 519d0b76d..75f626579 100644 --- a/target/linux/generic/pending-6.6/920-mangle_bootargs.patch +++ b/target/linux/generic/pending-6.6/920-mangle_bootargs.patch @@ -61,7 +61,7 @@ Signed-off-by: Imre Kaloz /* * We need to store the untouched command line for future reference. * We also need to store the touched command line since the parameter -@@ -896,6 +919,7 @@ void start_kernel(void) +@@ -898,6 +921,7 @@ void start_kernel(void) pr_notice("%s", linux_banner); early_security_init(); setup_arch(&command_line); diff --git a/target/linux/rockchip/patches-6.1/040-01-v6.4-irqchip-gic-v3-Add-Rockchip-3588001-erratum-workaround.patch b/target/linux/rockchip/patches-6.1/040-01-v6.4-irqchip-gic-v3-Add-Rockchip-3588001-erratum-workaround.patch index 7e7cdd46d..96f25876d 100644 --- a/target/linux/rockchip/patches-6.1/040-01-v6.4-irqchip-gic-v3-Add-Rockchip-3588001-erratum-workaround.patch +++ b/target/linux/rockchip/patches-6.1/040-01-v6.4-irqchip-gic-v3-Add-Rockchip-3588001-erratum-workaround.patch @@ -105,7 +105,7 @@ Link: https://lore.kernel.org/r/20230418142109.49762-2-sebastian.reichel@collabo if (!(tmp & GICR_PENDBASER_SHAREABILITY_MASK)) { /* * The HW reports non-shareable, we must remove the -@@ -4731,6 +4742,19 @@ static bool __maybe_unused its_enable_qu +@@ -4726,6 +4737,19 @@ static bool __maybe_unused its_enable_qu return true; } @@ -125,7 +125,7 @@ Link: https://lore.kernel.org/r/20230418142109.49762-2-sebastian.reichel@collabo static const struct gic_quirk its_quirks[] = { #ifdef CONFIG_CAVIUM_ERRATUM_22375 { -@@ -4777,6 +4801,14 @@ static const struct gic_quirk its_quirks +@@ -4772,6 +4796,14 @@ static const struct gic_quirk its_quirks .init = its_enable_quirk_hip07_161600802, }, #endif @@ -140,7 +140,7 @@ Link: https://lore.kernel.org/r/20230418142109.49762-2-sebastian.reichel@collabo { } }; -@@ -5116,6 +5148,9 @@ static int __init its_probe_one(struct r +@@ -5111,6 +5143,9 @@ static int __init its_probe_one(struct r gits_write_cbaser(baser, its->base + GITS_CBASER); tmp = gits_read_cbaser(its->base + GITS_CBASER); diff --git a/target/linux/rockchip/patches-6.1/040-02-v6.5-irqchip-gic-v3-Enable-Rockchip-3588001-erratum-workaround.patch b/target/linux/rockchip/patches-6.1/040-02-v6.5-irqchip-gic-v3-Enable-Rockchip-3588001-erratum-workaround.patch index 98b7c4928..65c56ca33 100644 --- a/target/linux/rockchip/patches-6.1/040-02-v6.5-irqchip-gic-v3-Enable-Rockchip-3588001-erratum-workaround.patch +++ b/target/linux/rockchip/patches-6.1/040-02-v6.5-irqchip-gic-v3-Enable-Rockchip-3588001-erratum-workaround.patch @@ -21,7 +21,7 @@ Link: https://lore.kernel.org/r/20230703164129.193991-1-sebastian.reichel@collab --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c -@@ -4746,7 +4746,8 @@ static bool __maybe_unused its_enable_rk +@@ -4741,7 +4741,8 @@ static bool __maybe_unused its_enable_rk { struct its_node *its = data; diff --git a/target/linux/rockchip/patches-6.1/700-phy-rockchip-snps-pcie3-rk3568-update-fw-when-init.patch b/target/linux/rockchip/patches-6.1/700-phy-rockchip-snps-pcie3-rk3568-update-fw-when-init.patch index bb1b79198..b4fb45902 100644 --- a/target/linux/rockchip/patches-6.1/700-phy-rockchip-snps-pcie3-rk3568-update-fw-when-init.patch +++ b/target/linux/rockchip/patches-6.1/700-phy-rockchip-snps-pcie3-rk3568-update-fw-when-init.patch @@ -25,7 +25,7 @@ Change-Id: I6624b6af2ede3c2fca61c0f753a08a33ce69a6d2 #define GRF_PCIE30PHY_CON6 0x18 #define GRF_PCIE30PHY_CON9 0x24 #define GRF_PCIE30PHY_DA_OCM (BIT(15) | BIT(31)) -@@ -63,6 +64,10 @@ struct rockchip_p3phy_ops { +@@ -65,6 +66,10 @@ struct rockchip_p3phy_ops { int (*phy_init)(struct rockchip_p3phy_priv *priv); }; @@ -36,7 +36,7 @@ Change-Id: I6624b6af2ede3c2fca61c0f753a08a33ce69a6d2 static int rockchip_p3phy_set_mode(struct phy *phy, enum phy_mode mode, int submode) { struct rockchip_p3phy_priv *priv = phy_get_drvdata(phy); -@@ -87,13 +92,14 @@ static int rockchip_p3phy_rk3568_init(st +@@ -89,13 +94,14 @@ static int rockchip_p3phy_rk3568_init(st { struct phy *phy = priv->phy; bool bifurcation = false; @@ -52,7 +52,7 @@ Change-Id: I6624b6af2ede3c2fca61c0f753a08a33ce69a6d2 dev_info(&phy->dev, "lane number %d, val %d\n", i, priv->lanes[i]); if (priv->lanes[i] > 1) bifurcation = true; -@@ -112,16 +118,35 @@ static int rockchip_p3phy_rk3568_init(st +@@ -114,16 +120,35 @@ static int rockchip_p3phy_rk3568_init(st GRF_PCIE30PHY_WR_EN & ~RK3568_BIFURCATION_LANE_0_1); } diff --git a/target/linux/rockchip/patches-6.1/701-apply-rockchip-3588001-erratum-workaround-to-rk356x-as-we.patch b/target/linux/rockchip/patches-6.1/701-apply-rockchip-3588001-erratum-workaround-to-rk356x-as-we.patch index f84f19628..7339be65e 100644 --- a/target/linux/rockchip/patches-6.1/701-apply-rockchip-3588001-erratum-workaround-to-rk356x-as-we.patch +++ b/target/linux/rockchip/patches-6.1/701-apply-rockchip-3588001-erratum-workaround-to-rk356x-as-we.patch @@ -1,6 +1,6 @@ --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c -@@ -4750,7 +4750,9 @@ static bool __maybe_unused its_enable_rk +@@ -4745,7 +4745,9 @@ static bool __maybe_unused its_enable_rk { struct its_node *its = data; diff --git a/target/linux/rockchip/patches-6.1/702-irqchip-gic-v3-its-add-GFP_DMA32-flag-for-memory-allocate.patch b/target/linux/rockchip/patches-6.1/702-irqchip-gic-v3-its-add-GFP_DMA32-flag-for-memory-allocate.patch index 2f6b78d5c..87305ab41 100644 --- a/target/linux/rockchip/patches-6.1/702-irqchip-gic-v3-its-add-GFP_DMA32-flag-for-memory-allocate.patch +++ b/target/linux/rockchip/patches-6.1/702-irqchip-gic-v3-its-add-GFP_DMA32-flag-for-memory-allocate.patch @@ -83,7 +83,7 @@ Signed-off-by: XiaoDong Huang if (alloc_lpis) { lpi_map = its_lpi_alloc(nvecs, &lpi_base, &nr_lpis); if (lpi_map) -@@ -5071,6 +5087,7 @@ static int __init its_probe_one(struct r +@@ -5066,6 +5082,7 @@ static int __init its_probe_one(struct r struct page *page; u32 ctlr; int err; @@ -91,7 +91,7 @@ Signed-off-by: XiaoDong Huang its_base = its_map_one(res, &err); if (!its_base) -@@ -5124,7 +5141,10 @@ static int __init its_probe_one(struct r +@@ -5119,7 +5136,10 @@ static int __init its_probe_one(struct r its->numa_node = numa_node;