diff options
Diffstat (limited to 'target/linux/generic/pending-6.1')
33 files changed, 781 insertions, 2932 deletions
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 93a2d146b5..ac4a3138a5 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 <nbd@nbd.name> --- 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 <nbd@nbd.name> __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/350-mips-kernel-fix-detect_memory_region-function.patch b/target/linux/generic/pending-6.1/350-mips-kernel-fix-detect_memory_region-function.patch new file mode 100644 index 0000000000..3bf7ae98bf --- /dev/null +++ b/target/linux/generic/pending-6.1/350-mips-kernel-fix-detect_memory_region-function.patch @@ -0,0 +1,74 @@ +From: Shiji Yang <yangshiji66@outlook.com> +Date: Wed, 13 Mar 2024 20:28:37 +0800 +Subject: [PATCH] mips: kernel: fix detect_memory_region() function + +1. Do not use memcmp() on unallocated memory, as the new introduced + fortify dynamic object size check[1] will report unexpected result. +2. Use a fixed pattern instead of a random function pointer as the + magic value. +3. Flip magic value and double check it. +4. Enable this feature only for 32-bit CPUs. Currently, only ath79 and + ralink CPUs are using it. + +[1] 439a1bcac648 ("fortify: Use __builtin_dynamic_object_size() when available") +Signed-off-by: Shiji Yang <yangshiji66@outlook.com> +--- + arch/mips/include/asm/bootinfo.h | 2 ++ + arch/mips/kernel/setup.c | 17 ++++++++++++----- + 2 files changed, 14 insertions(+), 5 deletions(-) + +--- a/arch/mips/include/asm/bootinfo.h ++++ b/arch/mips/include/asm/bootinfo.h +@@ -93,7 +93,9 @@ const char *get_system_type(void); + + extern unsigned long mips_machtype; + ++#ifndef CONFIG_64BIT + extern void detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max); ++#endif + + extern void prom_init(void); + extern void prom_free_prom_memory(void); +--- a/arch/mips/kernel/setup.c ++++ b/arch/mips/kernel/setup.c +@@ -90,21 +90,27 @@ static struct resource bss_resource = { + unsigned long __kaslr_offset __ro_after_init; + EXPORT_SYMBOL(__kaslr_offset); + +-static void *detect_magic __initdata = detect_memory_region; +- + #ifdef CONFIG_MIPS_AUTO_PFN_OFFSET + unsigned long ARCH_PFN_OFFSET; + EXPORT_SYMBOL(ARCH_PFN_OFFSET); + #endif + ++#ifndef CONFIG_64BIT ++static u32 detect_magic __initdata; ++#define MIPS_MEM_TEST_PATTERN 0xaa5555aa ++ + void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max) + { +- void *dm = &detect_magic; ++ void *dm = (void *)KSEG1ADDR(&detect_magic); + phys_addr_t size; + + for (size = sz_min; size < sz_max; size <<= 1) { +- if (!memcmp(dm, dm + size, sizeof(detect_magic))) +- break; ++ __raw_writel(MIPS_MEM_TEST_PATTERN, dm); ++ if (__raw_readl(dm) == __raw_readl(dm + size)) { ++ __raw_writel(~MIPS_MEM_TEST_PATTERN, dm); ++ if (__raw_readl(dm) == __raw_readl(dm + size)) ++ break; ++ } + } + + pr_debug("Memory: %lluMB of RAM detected at 0x%llx (min: %lluMB, max: %lluMB)\n", +@@ -115,6 +121,7 @@ void __init detect_memory_region(phys_ad + + memblock_add(start, size); + } ++#endif /* CONFIG_64BIT */ + + /* + * Manage initrd diff --git a/target/linux/generic/pending-6.1/610-netfilter_match_bypass_default_checks.patch b/target/linux/generic/pending-6.1/610-netfilter_match_bypass_default_checks.patch index 56d62ab8e2..0ab89564ee 100644 --- a/target/linux/generic/pending-6.1/610-netfilter_match_bypass_default_checks.patch +++ b/target/linux/generic/pending-6.1/610-netfilter_match_bypass_default_checks.patch @@ -91,7 +91,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> for (i = sizeof(struct ipt_entry); i < e->target_offset; i += m->u.match_size) { -@@ -1225,12 +1262,15 @@ compat_copy_entry_to_user(struct ipt_ent +@@ -1227,12 +1264,15 @@ compat_copy_entry_to_user(struct ipt_ent compat_uint_t origsize; const struct xt_entry_match *ematch; int ret = 0; diff --git a/target/linux/generic/pending-6.1/655-increase_skb_pad.patch b/target/linux/generic/pending-6.1/655-increase_skb_pad.patch index 8af331cb23..9d77ceaf93 100644 --- a/target/linux/generic/pending-6.1/655-increase_skb_pad.patch +++ b/target/linux/generic/pending-6.1/655-increase_skb_pad.patch @@ -9,7 +9,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h -@@ -3012,7 +3012,7 @@ static inline int pskb_network_may_pull( +@@ -3027,7 +3027,7 @@ static inline int pskb_network_may_pull( * NET_IP_ALIGN(2) + ethernet_header(14) + IP_header(20/40) + ports(8) */ #ifndef NET_SKB_PAD 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 a589fca7a8..0000000000 --- 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 <nbd@nbd.name> -Subject: net: replace GRO optimization patch with a new one that supports VLANs/bridges with different MAC addresses - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - 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 -@@ -2157,6 +2157,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 -@@ -7628,6 +7628,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, -@@ -7679,6 +7721,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); -@@ -7775,6 +7818,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); - -@@ -8827,6 +8871,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 0000000000..f52233fe90 --- /dev/null +++ b/target/linux/generic/pending-6.1/680-net-add-TCP-fraglist-GRO-support.patch @@ -0,0 +1,627 @@ +From: Felix Fietkau <nbd@nbd.name> +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 <nbd@nbd.name> +--- + +--- 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 <linux/indirect_call_wrapper.h> + #include <linux/skbuff.h> ++#include <net/inet6_hashtables.h> + #include <net/gro.h> + #include <net/protocol.h> + #include <net/tcp.h> + #include <net/ip6_checksum.h> + #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/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch b/target/linux/generic/pending-6.1/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch index fb6eb73232..9f8c3d6ff5 100644 --- a/target/linux/generic/pending-6.1/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch +++ b/target/linux/generic/pending-6.1/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch @@ -18,7 +18,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c -@@ -7951,7 +7951,7 @@ static int nft_register_flowtable_net_ho +@@ -7959,7 +7959,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.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 989aca8f35..367c41bff0 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 <nbd@nbd.name> 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 */ @@ -134,7 +134,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> return -EMSGSIZE; timerval = br_timer_value(&p->message_age_timer); -@@ -878,6 +880,7 @@ static const struct nla_policy br_port_p +@@ -879,6 +881,7 @@ static const struct nla_policy br_port_p [IFLA_BRPORT_LOCKED] = { .type = NLA_U8 }, [IFLA_BRPORT_BACKUP_PORT] = { .type = NLA_U32 }, [IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT] = { .type = NLA_U32 }, @@ -142,7 +142,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> }; /* Change the state of the port and notify spanning tree */ -@@ -943,6 +946,7 @@ static int br_setport(struct net_bridge_ +@@ -944,6 +947,7 @@ static int br_setport(struct net_bridge_ br_set_port_flag(p, tb, IFLA_BRPORT_NEIGH_SUPPRESS, BR_NEIGH_SUPPRESS); br_set_port_flag(p, tb, IFLA_BRPORT_ISOLATED, BR_ISOLATED); br_set_port_flag(p, tb, IFLA_BRPORT_LOCKED, BR_PORT_LOCKED); diff --git a/target/linux/generic/pending-6.1/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch b/target/linux/generic/pending-6.1/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch index f5987109f6..05edcc8bf4 100644 --- a/target/linux/generic/pending-6.1/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch +++ b/target/linux/generic/pending-6.1/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch @@ -13,7 +13,15 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org> --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c -@@ -754,6 +754,38 @@ static int rtl8226_match_phy_device(stru +@@ -80,6 +80,7 @@ + + #define RTL_GENERIC_PHYID 0x001cc800 + #define RTL_8211FVD_PHYID 0x001cc878 ++#define RTL_8221B_VB_CG_PHYID 0x001cc849 + + MODULE_DESCRIPTION("Realtek PHY driver"); + MODULE_AUTHOR("Johnson Leung"); +@@ -754,6 +755,38 @@ static int rtl8226_match_phy_device(stru rtlgen_supports_2_5gbps(phydev); } @@ -46,13 +54,13 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org> + id |= val; + } + -+ return (id == 0x001cc849); ++ return (id == RTL_8221B_VB_CG_PHYID); +} + static int rtl822x_probe(struct phy_device *phydev) { struct device *dev = &phydev->mdio.dev; -@@ -1104,7 +1136,7 @@ static struct phy_driver realtek_drvs[] +@@ -1104,7 +1137,7 @@ static struct phy_driver realtek_drvs[] .write_page = rtl821x_write_page, .soft_reset = genphy_soft_reset, }, { 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 a7a4bafbb6..f3725bf7d3 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 <ansuelsmth@gmail.com> --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h -@@ -2192,7 +2192,7 @@ struct net_device { +@@ -2190,7 +2190,7 @@ struct net_device { #if IS_ENABLED(CONFIG_AX25) void *ax25_ptr; #endif diff --git a/target/linux/generic/pending-6.1/741-net-phy-realtek-support-interrupt-of-RTL8221B.patch b/target/linux/generic/pending-6.1/741-net-phy-realtek-support-interrupt-of-RTL8221B.patch index 82cd419a7e..249ba5c496 100644 --- a/target/linux/generic/pending-6.1/741-net-phy-realtek-support-interrupt-of-RTL8221B.patch +++ b/target/linux/generic/pending-6.1/741-net-phy-realtek-support-interrupt-of-RTL8221B.patch @@ -12,7 +12,7 @@ Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com> --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c -@@ -981,6 +981,51 @@ static int rtl8221b_config_init(struct p +@@ -982,6 +982,51 @@ static int rtl8221b_config_init(struct p return 0; } @@ -64,7 +64,7 @@ Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com> static struct phy_driver realtek_drvs[] = { { PHY_ID_MATCH_EXACT(0x00008201), -@@ -1141,6 +1186,8 @@ static struct phy_driver realtek_drvs[] +@@ -1142,6 +1187,8 @@ static struct phy_driver realtek_drvs[] .get_features = rtl822x_get_features, .config_init = rtl8221b_config_init, .config_aneg = rtl822x_config_aneg, diff --git a/target/linux/generic/pending-6.1/742-net-phy-air_en8811h-reset-netdev-rules-when-LED-is-s.patch b/target/linux/generic/pending-6.1/742-net-phy-air_en8811h-reset-netdev-rules-when-LED-is-s.patch new file mode 100644 index 0000000000..500567b4ed --- /dev/null +++ b/target/linux/generic/pending-6.1/742-net-phy-air_en8811h-reset-netdev-rules-when-LED-is-s.patch @@ -0,0 +1,45 @@ +From 9be9a00adfac8118b6d685e71696f83187308c66 Mon Sep 17 00:00:00 2001 +Message-ID: <9be9a00adfac8118b6d685e71696f83187308c66.1715125851.git.daniel@makrotopia.org> +From: Daniel Golle <daniel@makrotopia.org> +Date: Tue, 7 May 2024 22:43:30 +0100 +Subject: [PATCH net] net: phy: air_en8811h: reset netdev rules when LED is set + manually +To: Andrew Lunn <andrew@lunn.ch>, + Heiner Kallweit <hkallweit1@gmail.com>, + Russell King <linux@armlinux.org.uk>, + David S. Miller <davem@davemloft.net>, + Eric Dumazet <edumazet@google.com>, + Jakub Kicinski <kuba@kernel.org>, + Paolo Abeni <pabeni@redhat.com>, + SkyLake Huang <skylake.huang@mediatek.com>, + Eric Woudstra <ericwouds@gmail.com>, + netdev@vger.kernel.org, + linux-kernel@vger.kernel.org + +Setting LED_OFF via the brightness_set should deactivate hw control, +so make sure netdev trigger rules also get cleared in that case. + +Fixes: 71e79430117d ("net: phy: air_en8811h: Add the Airoha EN8811H PHY driver") +Signed-off-by: Daniel Golle <daniel@makrotopia.org> +--- +This is basically a stop-gap measure until unified LED handling has +been implemented accross all MediaTek and Airoha PHYs. +See also +https://patchwork.kernel.org/project/netdevbpf/patch/20240425023325.15586-3-SkyLake.Huang@mediatek.com/ + + drivers/net/phy/air_en8811h.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/net/phy/air_en8811h.c ++++ b/drivers/net/phy/air_en8811h.c +@@ -544,6 +544,10 @@ static int air_hw_led_on_set(struct phy_ + + changed |= (priv->led[index].rules != 0); + ++ /* clear netdev trigger rules in case LED_OFF has been set */ ++ if (!on) ++ priv->led[index].rules = 0; ++ + if (changed) + return phy_modify_mmd(phydev, MDIO_MMD_VEND2, + AIR_PHY_LED_ON(index), diff --git a/target/linux/generic/pending-6.1/750-net-phy-airoha-Add-the-Airoha-EN8811H-PHY-driver.patch b/target/linux/generic/pending-6.1/750-net-phy-airoha-Add-the-Airoha-EN8811H-PHY-driver.patch deleted file mode 100644 index 1dfa1366eb..0000000000 --- a/target/linux/generic/pending-6.1/750-net-phy-airoha-Add-the-Airoha-EN8811H-PHY-driver.patch +++ /dev/null @@ -1,1115 +0,0 @@ -From patchwork Tue Feb 6 19:47:51 2024 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Eric Woudstra <ericwouds@gmail.com> -X-Patchwork-Id: 13547762 -X-Patchwork-Delegate: kuba@kernel.org -From: Eric Woudstra <ericwouds@gmail.com> -To: "David S. Miller" <davem@davemloft.net>, - Eric Dumazet <edumazet@google.com>, - Jakub Kicinski <kuba@kernel.org>, - Paolo Abeni <pabeni@redhat.com>, - Rob Herring <robh+dt@kernel.org>, - Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>, - Conor Dooley <conor+dt@kernel.org>, - Andrew Lunn <andrew@lunn.ch>, - Heiner Kallweit <hkallweit1@gmail.com>, - Russell King <linux@armlinux.org.uk>, - Matthias Brugger <matthias.bgg@gmail.com>, - AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>, - "Frank Wunderlich" <frank-w@public-files.de>, - Daniel Golle <daniel@makrotopia.org>, - Lucien Jheng <lucien.jheng@airoha.com>, - Zhi-Jun You <hujy652@protonmail.com> -Cc: netdev@vger.kernel.org, - devicetree@vger.kernel.org, - Eric Woudstra <ericwouds@gmail.com> -Subject: [PATCH net-next 2/2] net: phy: air_en8811h: Add the Airoha EN8811H - PHY driver -Date: Tue, 6 Feb 2024 20:47:51 +0100 -Message-ID: <20240206194751.1901802-3-ericwouds@gmail.com> -X-Mailer: git-send-email 2.42.1 -In-Reply-To: <20240206194751.1901802-1-ericwouds@gmail.com> -References: <20240206194751.1901802-1-ericwouds@gmail.com> -Precedence: bulk -X-Mailing-List: netdev@vger.kernel.org -List-Id: <netdev.vger.kernel.org> -List-Subscribe: <mailto:netdev+subscribe@vger.kernel.org> -List-Unsubscribe: <mailto:netdev+unsubscribe@vger.kernel.org> -MIME-Version: 1.0 -X-Patchwork-Delegate: kuba@kernel.org - -* Source originated from airoha's en8811h v1.2.1 driver - * Moved air_en8811h.h to air_en8811h.c - * Removed air_pbus_reg_write() as it writes to another device on mdio-bus - * Load firmware from /lib/firmware/airoha/ instead of /lib/firmware/ - * Added .get_rate_matching() - * Use generic phy_read/write() and phy_read/write_mmd() - * Edited .get_features() to use generic C45 functions - * Edited .config_aneg() and .read_status() to use a mix of generic C22/C45 - * Use led handling functions from mediatek-ge-soc.c - * Simplified led handling by storing led rules - * Cleanup macro definitions - * Cleanup code to pass checkpatch.pl - * General code cleanup - -Changes from original RFC patch: - - * Use the correct order in Kconfig and Makefile - * Change some register naming to correspond with datasheet - * Use phy_driver .read_page() and .write_page() - * Use module_phy_driver() - * Use get_unaligned_le16() instead of macro - * In .config_aneg() and .read_status() use genphy_xxx() C22 - * Use another vendor register to read real speed - * Load firmware only once and store firmware version - * Apply 2.5G LPA work-around (firmware before 24011202) - * Read 2.5G LPA from vendor register (firmware 24011202 and later) - -Changes to be committed: - modified: drivers/net/phy/Kconfig - modified: drivers/net/phy/Makefile - new file: drivers/net/phy/air_en8811h.c - -Signed-off-by: Eric Woudstra <ericwouds@gmail.com> ---- - drivers/net/phy/Kconfig | 5 + - drivers/net/phy/Makefile | 1 + - drivers/net/phy/air_en8811h.c | 1006 +++++++++++++++++++++++++++++++++ - 3 files changed, 1012 insertions(+) - create mode 100644 drivers/net/phy/air_en8811h.c - ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -69,6 +69,11 @@ config SFP - - comment "MII PHY device drivers" - -+config AIR_EN8811H_PHY -+ tristate "Airoha EN8811H 2.5 Gigabit PHY" -+ help -+ Currently supports the Airoha EN8811H PHY. -+ - config AMD_PHY - tristate "AMD and Altima PHYs" - help ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -32,6 +32,7 @@ obj-y += $(sfp-obj-y) $(sfp-obj-m) - - obj-$(CONFIG_ADIN_PHY) += adin.o - obj-$(CONFIG_ADIN1100_PHY) += adin1100.o -+obj-$(CONFIG_AIR_EN8811H_PHY) += air_en8811h.o - obj-$(CONFIG_AMD_PHY) += amd.o - obj-$(CONFIG_AQUANTIA_PHY) += aquantia/ - obj-$(CONFIG_AX88796B_PHY) += ax88796b.o ---- /dev/null -+++ b/drivers/net/phy/air_en8811h.c -@@ -0,0 +1,1006 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Driver for Airoha Ethernet PHYs -+ * -+ * Currently supporting the EN8811H. -+ * -+ * Limitations of the EN8811H: -+ * - Only full duplex supported -+ * - Forced speed (AN off) is not supported by hardware (100Mbps) -+ * -+ * Source originated from airoha's en8811h.c and en8811h.h v1.2.1 -+ * -+ * Copyright (C) 2023 Airoha Technology Corp. -+ */ -+ -+#include <linux/phy.h> -+#include <linux/firmware.h> -+#include <linux/property.h> -+#include <asm/unaligned.h> -+ -+#define EN8811H_PHY_ID 0x03a2a411 -+ -+#define EN8811H_MD32_DM "airoha/EthMD32.dm.bin" -+#define EN8811H_MD32_DSP "airoha/EthMD32.DSP.bin" -+ -+#define AIR_FW_ADDR_DM 0x00000000 -+#define AIR_FW_ADDR_DSP 0x00100000 -+ -+/* u32 (DWORD) component macros */ -+#define LOWORD(d) ((u16)(u32)(d)) -+#define HIWORD(d) ((u16)(((u32)(d)) >> 16)) -+ -+/* MII Registers */ -+#define AIR_AUX_CTRL_STATUS 0x1d -+#define AIR_AUX_CTRL_STATUS_SPEED_MASK GENMASK(4, 2) -+#define AIR_AUX_CTRL_STATUS_SPEED_100 0x4 -+#define AIR_AUX_CTRL_STATUS_SPEED_1000 0x8 -+#define AIR_AUX_CTRL_STATUS_SPEED_2500 0xc -+ -+#define AIR_EXT_PAGE_ACCESS 0x1f -+#define AIR_PHY_PAGE_STANDARD 0x0000 -+#define AIR_PHY_PAGE_EXTENDED_4 0x0004 -+ -+/* MII Registers Page 4*/ -+#define AIR_PBUS_MODE 0x10 -+#define AIR_PBUS_MODE_ADDR_FIXED 0x0000 -+#define AIR_PBUS_MODE_ADDR_INCR BIT(15) -+#define AIR_PBUS_WR_ADDR_HIGH 0x11 -+#define AIR_PBUS_WR_ADDR_LOW 0x12 -+#define AIR_PBUS_WR_DATA_HIGH 0x13 -+#define AIR_PBUS_WR_DATA_LOW 0x14 -+#define AIR_PBUS_RD_ADDR_HIGH 0x15 -+#define AIR_PBUS_RD_ADDR_LOW 0x16 -+#define AIR_PBUS_RD_DATA_HIGH 0x17 -+#define AIR_PBUS_RD_DATA_LOW 0x18 -+ -+/* Registers on MDIO_MMD_VEND1 */ -+#define EN8811H_PHY_FW_STATUS 0x8009 -+#define EN8811H_PHY_READY 0x02 -+ -+#define AIR_PHY_HOST_CMD_1 0x800c -+#define AIR_PHY_HOST_CMD_1_MODE1 0x0 -+#define AIR_PHY_HOST_CMD_2 0x800d -+#define AIR_PHY_HOST_CMD_2_MODE1 0x0 -+#define AIR_PHY_HOST_CMD_3 0x800e -+#define AIR_PHY_HOST_CMD_3_MODE1 0x1101 -+#define AIR_PHY_HOST_CMD_3_DOCMD 0x1100 -+#define AIR_PHY_HOST_CMD_4 0x800f -+#define AIR_PHY_HOST_CMD_4_MODE1 0x0002 -+#define AIR_PHY_HOST_CMD_4_INTCLR 0x00e4 -+ -+/* Registers on MDIO_MMD_VEND2 */ -+#define AIR_PHY_LED_BCR 0x021 -+#define AIR_PHY_LED_BCR_MODE_MASK GENMASK(1, 0) -+#define AIR_PHY_LED_BCR_TIME_TEST BIT(2) -+#define AIR_PHY_LED_BCR_CLK_EN BIT(3) -+#define AIR_PHY_LED_BCR_EXT_CTRL BIT(15) -+ -+#define AIR_PHY_LED_DUR_ON 0x022 -+ -+#define AIR_PHY_LED_DUR_BLINK 0x023 -+ -+#define AIR_PHY_LED_ON(i) (0x024 + ((i) * 2)) -+#define AIR_PHY_LED_ON_MASK (GENMASK(6, 0) | BIT(8)) -+#define AIR_PHY_LED_ON_LINK1000 BIT(0) -+#define AIR_PHY_LED_ON_LINK100 BIT(1) -+#define AIR_PHY_LED_ON_LINK10 BIT(2) -+#define AIR_PHY_LED_ON_LINKDOWN BIT(3) -+#define AIR_PHY_LED_ON_FDX BIT(4) /* Full duplex */ -+#define AIR_PHY_LED_ON_HDX BIT(5) /* Half duplex */ -+#define AIR_PHY_LED_ON_FORCE_ON BIT(6) -+#define AIR_PHY_LED_ON_LINK2500 BIT(8) -+#define AIR_PHY_LED_ON_POLARITY BIT(14) -+#define AIR_PHY_LED_ON_ENABLE BIT(15) -+ -+#define AIR_PHY_LED_BLINK(i) (0x025 + ((i) * 2)) -+#define AIR_PHY_LED_BLINK_1000TX BIT(0) -+#define AIR_PHY_LED_BLINK_1000RX BIT(1) -+#define AIR_PHY_LED_BLINK_100TX BIT(2) -+#define AIR_PHY_LED_BLINK_100RX BIT(3) -+#define AIR_PHY_LED_BLINK_10TX BIT(4) -+#define AIR_PHY_LED_BLINK_10RX BIT(5) -+#define AIR_PHY_LED_BLINK_COLLISION BIT(6) -+#define AIR_PHY_LED_BLINK_RX_CRC_ERR BIT(7) -+#define AIR_PHY_LED_BLINK_RX_IDLE_ERR BIT(8) -+#define AIR_PHY_LED_BLINK_FORCE_BLINK BIT(9) -+#define AIR_PHY_LED_BLINK_2500TX BIT(10) -+#define AIR_PHY_LED_BLINK_2500RX BIT(11) -+ -+/* Registers on BUCKPBUS */ -+#define EN8811H_2P5G_LPA 0x3b30 -+#define EN8811H_2P5G_LPA_2P5G BIT(0) -+ -+#define EN8811H_FW_VERSION 0x3b3c -+ -+#define EN8811H_POLARITY 0xca0f8 -+#define EN8811H_POLARITY_TX_NORMAL BIT(0) -+#define EN8811H_POLARITY_RX_REVERSE BIT(1) -+ -+#define EN8811H_GPIO_OUTPUT 0xcf8b8 -+#define EN8811H_GPIO_OUTPUT_345 (BIT(3) | BIT(4) | BIT(5)) -+ -+#define EN8811H_FW_CTRL_1 0x0f0018 -+#define EN8811H_FW_CTRL_1_START 0x0 -+#define EN8811H_FW_CTRL_1_FINISH 0x1 -+#define EN8811H_FW_CTRL_2 0x800000 -+#define EN8811H_FW_CTRL_2_LOADING BIT(11) -+ -+#define EN8811H_LED_COUNT 3 -+ -+/* GPIO5 <-> BASE_T_LED0 -+ * GPIO4 <-> BASE_T_LED1 -+ * GPIO3 <-> BASE_T_LED2 -+ * -+ * Default setup suitable for 2 leds connected: -+ * 100M link up triggers led0, only led0 blinking on traffic -+ * 1000M link up triggers led1, only led1 blinking on traffic -+ * 2500M link up triggers led0 and led1, both blinking on traffic -+ * Also suitable for 1 led connected: -+ * any link up triggers led2 -+ */ -+#define AIR_DEFAULT_TRIGGER_LED0 (BIT(TRIGGER_NETDEV_LINK_2500) | \ -+ BIT(TRIGGER_NETDEV_LINK_100) | \ -+ BIT(TRIGGER_NETDEV_RX) | \ -+ BIT(TRIGGER_NETDEV_TX)) -+#define AIR_DEFAULT_TRIGGER_LED1 (BIT(TRIGGER_NETDEV_LINK_2500) | \ -+ BIT(TRIGGER_NETDEV_LINK_1000) | \ -+ BIT(TRIGGER_NETDEV_RX) | \ -+ BIT(TRIGGER_NETDEV_TX)) -+#define AIR_DEFAULT_TRIGGER_LED2 BIT(TRIGGER_NETDEV_LINK) -+ -+struct led { -+ unsigned long rules; -+ unsigned long state; -+}; -+ -+struct en8811h_priv { -+ u32 firmware_version; -+ struct led led[EN8811H_LED_COUNT]; -+}; -+ -+enum { -+ AIR_PHY_LED_STATE_FORCE_ON, -+ AIR_PHY_LED_STATE_FORCE_BLINK, -+}; -+ -+enum { -+ AIR_PHY_LED_DUR_BLINK_32M, -+ AIR_PHY_LED_DUR_BLINK_64M, -+ AIR_PHY_LED_DUR_BLINK_128M, -+ AIR_PHY_LED_DUR_BLINK_256M, -+ AIR_PHY_LED_DUR_BLINK_512M, -+ AIR_PHY_LED_DUR_BLINK_1024M, -+}; -+ -+enum { -+ AIR_LED_DISABLE, -+ AIR_LED_ENABLE, -+}; -+ -+enum { -+ AIR_ACTIVE_LOW, -+ AIR_ACTIVE_HIGH, -+}; -+ -+enum { -+ AIR_LED_MODE_DISABLE, -+ AIR_LED_MODE_USER_DEFINE, -+}; -+ -+#define AIR_PHY_LED_DUR_UNIT 1024 -+#define AIR_PHY_LED_DUR (AIR_PHY_LED_DUR_UNIT << AIR_PHY_LED_DUR_BLINK_64M) -+ -+static const unsigned long en8811h_led_trig = (BIT(TRIGGER_NETDEV_FULL_DUPLEX) | -+ BIT(TRIGGER_NETDEV_LINK) | -+ BIT(TRIGGER_NETDEV_LINK_10) | -+ BIT(TRIGGER_NETDEV_LINK_100) | -+ BIT(TRIGGER_NETDEV_LINK_1000) | -+ BIT(TRIGGER_NETDEV_LINK_2500) | -+ BIT(TRIGGER_NETDEV_RX) | -+ BIT(TRIGGER_NETDEV_TX)); -+ -+static int air_phy_read_page(struct phy_device *phydev) -+{ -+ return __phy_read(phydev, AIR_EXT_PAGE_ACCESS); -+} -+ -+static int air_phy_write_page(struct phy_device *phydev, int page) -+{ -+ return __phy_write(phydev, AIR_EXT_PAGE_ACCESS, page); -+} -+ -+static int __air_buckpbus_reg_write(struct phy_device *phydev, -+ u32 pbus_address, u32 pbus_data) -+{ -+ int ret; -+ -+ ret = __phy_write(phydev, AIR_PBUS_MODE, AIR_PBUS_MODE_ADDR_FIXED); -+ if (ret < 0) -+ return ret; -+ -+ ret = __phy_write(phydev, AIR_PBUS_WR_ADDR_HIGH, HIWORD(pbus_address)); -+ if (ret < 0) -+ return ret; -+ -+ ret = __phy_write(phydev, AIR_PBUS_WR_ADDR_LOW, LOWORD(pbus_address)); -+ if (ret < 0) -+ return ret; -+ -+ ret = __phy_write(phydev, AIR_PBUS_WR_DATA_HIGH, HIWORD(pbus_data)); -+ if (ret < 0) -+ return ret; -+ -+ ret = __phy_write(phydev, AIR_PBUS_WR_DATA_LOW, LOWORD(pbus_data)); -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+static int air_buckpbus_reg_write(struct phy_device *phydev, -+ u32 pbus_address, u32 pbus_data) -+{ -+ int ret, saved_page; -+ -+ saved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4); -+ -+ ret = __air_buckpbus_reg_write(phydev, pbus_address, pbus_data); -+ if (ret < 0) -+ phydev_err(phydev, "%s 0x%08x failed: %d\n", __func__, -+ pbus_address, ret); -+ -+ return phy_restore_page(phydev, saved_page, ret); -+; -+} -+ -+static int __air_buckpbus_reg_read(struct phy_device *phydev, -+ u32 pbus_address, u32 *pbus_data) -+{ -+ int pbus_data_low, pbus_data_high; -+ int ret; -+ -+ ret = __phy_write(phydev, AIR_PBUS_MODE, AIR_PBUS_MODE_ADDR_FIXED); -+ if (ret < 0) -+ return ret; -+ -+ ret = __phy_write(phydev, AIR_PBUS_RD_ADDR_HIGH, HIWORD(pbus_address)); -+ if (ret < 0) -+ return ret; -+ -+ ret = __phy_write(phydev, AIR_PBUS_RD_ADDR_LOW, LOWORD(pbus_address)); -+ if (ret < 0) -+ return ret; -+ -+ pbus_data_high = __phy_read(phydev, AIR_PBUS_RD_DATA_HIGH); -+ if (pbus_data_high < 0) -+ return ret; -+ -+ pbus_data_low = __phy_read(phydev, AIR_PBUS_RD_DATA_LOW); -+ if (pbus_data_low < 0) -+ return ret; -+ -+ *pbus_data = (u16)pbus_data_low | ((u32)(u16)pbus_data_high << 16); -+ return 0; -+} -+ -+static int air_buckpbus_reg_read(struct phy_device *phydev, -+ u32 pbus_address, u32 *pbus_data) -+{ -+ int ret, saved_page; -+ -+ saved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4); -+ -+ ret = __air_buckpbus_reg_read(phydev, pbus_address, pbus_data); -+ if (ret < 0) -+ phydev_err(phydev, "%s 0x%08x failed: %d\n", __func__, -+ pbus_address, ret); -+ -+ return phy_restore_page(phydev, saved_page, ret); -+} -+ -+static int __air_write_buf(struct phy_device *phydev, u32 address, -+ const struct firmware *fw) -+{ -+ unsigned int offset; -+ int ret; -+ u16 val; -+ -+ ret = __phy_write(phydev, AIR_PBUS_MODE, AIR_PBUS_MODE_ADDR_INCR); -+ if (ret < 0) -+ return ret; -+ -+ ret = __phy_write(phydev, AIR_PBUS_WR_ADDR_HIGH, HIWORD(address)); -+ if (ret < 0) -+ return ret; -+ -+ ret = __phy_write(phydev, AIR_PBUS_WR_ADDR_LOW, LOWORD(address)); -+ if (ret < 0) -+ return ret; -+ -+ for (offset = 0; offset < fw->size; offset += 4) { -+ val = get_unaligned_le16(&fw->data[offset + 2]); -+ ret = __phy_write(phydev, AIR_PBUS_WR_DATA_HIGH, val); -+ if (ret < 0) -+ return ret; -+ -+ val = get_unaligned_le16(&fw->data[offset]); -+ ret = __phy_write(phydev, AIR_PBUS_WR_DATA_LOW, val); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int air_write_buf(struct phy_device *phydev, u32 address, -+ const struct firmware *fw) -+{ -+ int ret, saved_page; -+ -+ saved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4); -+ -+ ret = __air_write_buf(phydev, address, fw); -+ if (ret < 0) -+ phydev_err(phydev, "%s 0x%08x failed: %d\n", __func__, -+ address, ret); -+ -+ return phy_restore_page(phydev, saved_page, ret); -+} -+ -+static int en8811h_load_firmware(struct phy_device *phydev) -+{ -+ struct device *dev = &phydev->mdio.dev; -+ const struct firmware *fw1, *fw2; -+ u32 pbus_value; -+ int ret; -+ -+ ret = request_firmware_direct(&fw1, EN8811H_MD32_DM, dev); -+ if (ret < 0) -+ return ret; -+ -+ ret = request_firmware_direct(&fw2, EN8811H_MD32_DSP, dev); -+ if (ret < 0) -+ goto en8811h_load_firmware_rel1; -+ -+ ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1, -+ EN8811H_FW_CTRL_1_START); -+ if (ret < 0) -+ goto en8811h_load_firmware_out; -+ -+ ret = air_buckpbus_reg_read(phydev, EN8811H_FW_CTRL_2, &pbus_value); -+ if (ret < 0) -+ goto en8811h_load_firmware_out; -+ pbus_value |= EN8811H_FW_CTRL_2_LOADING; -+ ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_2, pbus_value); -+ if (ret < 0) -+ goto en8811h_load_firmware_out; -+ -+ ret = air_write_buf(phydev, AIR_FW_ADDR_DM, fw1); -+ if (ret < 0) -+ goto en8811h_load_firmware_out; -+ -+ ret = air_write_buf(phydev, AIR_FW_ADDR_DSP, fw2); -+ if (ret < 0) -+ goto en8811h_load_firmware_out; -+ -+ ret = air_buckpbus_reg_read(phydev, EN8811H_FW_CTRL_2, &pbus_value); -+ if (ret < 0) -+ goto en8811h_load_firmware_out; -+ pbus_value &= ~EN8811H_FW_CTRL_2_LOADING; -+ ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_2, pbus_value); -+ if (ret < 0) -+ goto en8811h_load_firmware_out; -+ -+ ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1, -+ EN8811H_FW_CTRL_1_FINISH); -+ if (ret < 0) -+ goto en8811h_load_firmware_out; -+ -+ ret = 0; -+ -+en8811h_load_firmware_out: -+ release_firmware(fw2); -+ -+en8811h_load_firmware_rel1: -+ release_firmware(fw1); -+ -+ if (ret < 0) -+ phydev_err(phydev, "Load firmware failed: %d\n", ret); -+ -+ return ret; -+} -+ -+static int en8811h_restart_host(struct phy_device *phydev) -+{ -+ int ret; -+ -+ ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1, -+ EN8811H_FW_CTRL_1_START); -+ if (ret < 0) -+ return ret; -+ -+ return air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1, -+ EN8811H_FW_CTRL_1_FINISH); -+} -+ -+static int air_hw_led_on_set(struct phy_device *phydev, u8 index, bool on) -+{ -+ struct en8811h_priv *priv = phydev->priv; -+ bool changed; -+ -+ if (index >= EN8811H_LED_COUNT) -+ return -EINVAL; -+ -+ if (on) -+ changed = !test_and_set_bit(AIR_PHY_LED_STATE_FORCE_ON, -+ &priv->led[index].state); -+ else -+ changed = !!test_and_clear_bit(AIR_PHY_LED_STATE_FORCE_ON, -+ &priv->led[index].state); -+ -+ changed |= (priv->led[index].rules != 0); -+ -+ if (changed) -+ return phy_modify_mmd(phydev, MDIO_MMD_VEND2, -+ AIR_PHY_LED_ON(index), -+ AIR_PHY_LED_ON_MASK, -+ on ? AIR_PHY_LED_ON_FORCE_ON : 0); -+ -+ return 0; -+} -+ -+static int air_hw_led_blink_set(struct phy_device *phydev, u8 index, -+ bool blinking) -+{ -+ struct en8811h_priv *priv = phydev->priv; -+ bool changed; -+ -+ if (index >= EN8811H_LED_COUNT) -+ return -EINVAL; -+ -+ if (blinking) -+ changed = !test_and_set_bit(AIR_PHY_LED_STATE_FORCE_BLINK, -+ &priv->led[index].state); -+ else -+ changed = !!test_and_clear_bit(AIR_PHY_LED_STATE_FORCE_BLINK, -+ &priv->led[index].state); -+ -+ changed |= (priv->led[index].rules != 0); -+ -+ if (changed) -+ return phy_write_mmd(phydev, MDIO_MMD_VEND2, -+ AIR_PHY_LED_BLINK(index), -+ blinking ? -+ AIR_PHY_LED_BLINK_FORCE_BLINK : 0); -+ else -+ return 0; -+} -+ -+static int air_led_blink_set(struct phy_device *phydev, u8 index, -+ unsigned long *delay_on, -+ unsigned long *delay_off) -+{ -+ struct en8811h_priv *priv = phydev->priv; -+ bool blinking = false; -+ int err; -+ -+ if (index >= EN8811H_LED_COUNT) -+ return -EINVAL; -+ -+ if (delay_on && delay_off && (*delay_on > 0) && (*delay_off > 0)) { -+ blinking = true; -+ *delay_on = 50; -+ *delay_off = 50; -+ } -+ -+ err = air_hw_led_blink_set(phydev, index, blinking); -+ if (err) -+ return err; -+ -+ /* led-blink set, so switch led-on off */ -+ err = air_hw_led_on_set(phydev, index, false); -+ if (err) -+ return err; -+ -+ /* hw-control is off*/ -+ if (!!test_bit(AIR_PHY_LED_STATE_FORCE_BLINK, &priv->led[index].state)) -+ priv->led[index].rules = 0; -+ -+ return 0; -+} -+ -+static int air_led_brightness_set(struct phy_device *phydev, u8 index, -+ enum led_brightness value) -+{ -+ struct en8811h_priv *priv = phydev->priv; -+ int err; -+ -+ if (index >= EN8811H_LED_COUNT) -+ return -EINVAL; -+ -+ /* led-on set, so switch led-blink off */ -+ err = air_hw_led_blink_set(phydev, index, false); -+ if (err) -+ return err; -+ -+ err = air_hw_led_on_set(phydev, index, (value != LED_OFF)); -+ if (err) -+ return err; -+ -+ /* hw-control is off */ -+ if (!!test_bit(AIR_PHY_LED_STATE_FORCE_ON, &priv->led[index].state)) -+ priv->led[index].rules = 0; -+ -+ return 0; -+} -+ -+static int air_led_hw_control_get(struct phy_device *phydev, u8 index, -+ unsigned long *rules) -+{ -+ struct en8811h_priv *priv = phydev->priv; -+ -+ if (index >= EN8811H_LED_COUNT) -+ return -EINVAL; -+ -+ *rules = priv->led[index].rules; -+ -+ return 0; -+}; -+ -+static int air_led_hw_control_set(struct phy_device *phydev, u8 index, -+ unsigned long rules) -+{ -+ struct en8811h_priv *priv = phydev->priv; -+ u16 on = 0, blink = 0; -+ int ret; -+ -+ priv->led[index].rules = rules; -+ -+ if (index >= EN8811H_LED_COUNT) -+ return -EINVAL; -+ -+ if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK))) { -+ on |= AIR_PHY_LED_ON_LINK10; -+ if (rules & BIT(TRIGGER_NETDEV_RX)) -+ blink |= AIR_PHY_LED_BLINK_10RX; -+ if (rules & BIT(TRIGGER_NETDEV_TX)) -+ blink |= AIR_PHY_LED_BLINK_10TX; -+ } -+ -+ if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK))) { -+ on |= AIR_PHY_LED_ON_LINK100; -+ if (rules & BIT(TRIGGER_NETDEV_RX)) -+ blink |= AIR_PHY_LED_BLINK_100RX; -+ if (rules & BIT(TRIGGER_NETDEV_TX)) -+ blink |= AIR_PHY_LED_BLINK_100TX; -+ } -+ -+ if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK))) { -+ on |= AIR_PHY_LED_ON_LINK1000; -+ if (rules & BIT(TRIGGER_NETDEV_RX)) -+ blink |= AIR_PHY_LED_BLINK_1000RX; -+ if (rules & BIT(TRIGGER_NETDEV_TX)) -+ blink |= AIR_PHY_LED_BLINK_1000TX; -+ } -+ -+ if (rules & (BIT(TRIGGER_NETDEV_LINK_2500) | BIT(TRIGGER_NETDEV_LINK))) { -+ on |= AIR_PHY_LED_ON_LINK2500; -+ if (rules & BIT(TRIGGER_NETDEV_RX)) -+ blink |= AIR_PHY_LED_BLINK_2500RX; -+ if (rules & BIT(TRIGGER_NETDEV_TX)) -+ blink |= AIR_PHY_LED_BLINK_2500TX; -+ } -+ -+ if (on == 0) { -+ if (rules & BIT(TRIGGER_NETDEV_RX)) { -+ blink |= AIR_PHY_LED_BLINK_10RX | -+ AIR_PHY_LED_BLINK_100RX | -+ AIR_PHY_LED_BLINK_1000RX | -+ AIR_PHY_LED_BLINK_2500RX; -+ } -+ if (rules & BIT(TRIGGER_NETDEV_TX)) { -+ blink |= AIR_PHY_LED_BLINK_10TX | -+ AIR_PHY_LED_BLINK_100TX | -+ AIR_PHY_LED_BLINK_1000TX | -+ AIR_PHY_LED_BLINK_2500TX; -+ } -+ } -+ -+ if (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX)) -+ on |= AIR_PHY_LED_ON_FDX; -+ -+ if (rules & BIT(TRIGGER_NETDEV_HALF_DUPLEX)) -+ on |= AIR_PHY_LED_ON_HDX; -+ -+ if (blink || on) { -+ /* switch hw-control on, so led-on and led-blink are off */ -+ clear_bit(AIR_PHY_LED_STATE_FORCE_ON, &priv->led[index].state); -+ clear_bit(AIR_PHY_LED_STATE_FORCE_BLINK, &priv->led[index].state); -+ } else { -+ priv->led[index].rules = 0; -+ } -+ -+ ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_ON(index), -+ AIR_PHY_LED_ON_MASK, on); -+ -+ if (ret < 0) -+ return ret; -+ -+ return phy_write_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_BLINK(index), -+ blink); -+}; -+ -+static int air_led_init(struct phy_device *phydev, u8 index, u8 state, u8 pol) -+{ -+ int cl45_data; -+ int err; -+ -+ if (index >= EN8811H_LED_COUNT) -+ return -EINVAL; -+ -+ cl45_data = phy_read_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_ON(index)); -+ if (cl45_data < 0) -+ return cl45_data; -+ -+ if (state == AIR_LED_ENABLE) -+ cl45_data |= AIR_PHY_LED_ON_ENABLE; -+ else -+ cl45_data &= ~AIR_PHY_LED_ON_ENABLE; -+ -+ if (pol == AIR_ACTIVE_HIGH) -+ cl45_data |= AIR_PHY_LED_ON_POLARITY; -+ else -+ cl45_data &= ~AIR_PHY_LED_ON_POLARITY; -+ -+ err = phy_write_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_ON(index), -+ cl45_data); -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+ -+static int air_leds_init(struct phy_device *phydev, int num, int dur, int mode) -+{ -+ struct en8811h_priv *priv = phydev->priv; -+ int cl45_data = dur; -+ int ret, i; -+ -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_DUR_BLINK, -+ cl45_data); -+ if (ret < 0) -+ return ret; -+ -+ cl45_data >>= 1; -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_DUR_ON, -+ cl45_data); -+ if (ret < 0) -+ return ret; -+ -+ cl45_data = phy_read_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_BCR); -+ if (cl45_data < 0) -+ return cl45_data; -+ -+ switch (mode) { -+ case AIR_LED_MODE_DISABLE: -+ cl45_data &= ~AIR_PHY_LED_BCR_EXT_CTRL; -+ cl45_data &= ~AIR_PHY_LED_BCR_MODE_MASK; -+ break; -+ case AIR_LED_MODE_USER_DEFINE: -+ cl45_data |= AIR_PHY_LED_BCR_EXT_CTRL; -+ cl45_data |= AIR_PHY_LED_BCR_CLK_EN; -+ break; -+ default: -+ phydev_err(phydev, "LED mode %d is not supported\n", mode); -+ return -EINVAL; -+ } -+ -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_BCR, cl45_data); -+ if (ret < 0) -+ return ret; -+ -+ for (i = 0; i < num; ++i) { -+ ret = air_led_init(phydev, i, AIR_LED_ENABLE, AIR_ACTIVE_HIGH); -+ if (ret < 0) { -+ phydev_err(phydev, "LED%d init failed: %d\n", i, ret); -+ return ret; -+ } -+ air_led_hw_control_set(phydev, i, priv->led[i].rules); -+ } -+ -+ return 0; -+} -+ -+static int en8811h_led_hw_is_supported(struct phy_device *phydev, u8 index, -+ unsigned long rules) -+{ -+ if (index >= EN8811H_LED_COUNT) -+ return -EINVAL; -+ -+ /* All combinations of the supported triggers are allowed */ -+ if (rules & ~en8811h_led_trig) -+ return -EOPNOTSUPP; -+ -+ return 0; -+}; -+ -+static int en8811h_probe(struct phy_device *phydev) -+{ -+ struct en8811h_priv *priv; -+ -+ priv = devm_kzalloc(&phydev->mdio.dev, sizeof(struct en8811h_priv), -+ GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->led[0].rules = AIR_DEFAULT_TRIGGER_LED0; -+ priv->led[1].rules = AIR_DEFAULT_TRIGGER_LED1; -+ priv->led[2].rules = AIR_DEFAULT_TRIGGER_LED2; -+ -+ phydev->priv = priv; -+ -+ /* MDIO_DEVS1/2 empty, so set mmds_present bits here */ -+ phydev->c45_ids.mmds_present |= MDIO_DEVS_PMAPMD | MDIO_DEVS_AN; -+ -+ return 0; -+} -+ -+static int en8811h_config_init(struct phy_device *phydev) -+{ -+ struct en8811h_priv *priv = phydev->priv; -+ struct device *dev = &phydev->mdio.dev; -+ int ret, pollret, reg_value; -+ u32 pbus_value; -+ -+ if (!priv->firmware_version) -+ ret = en8811h_load_firmware(phydev); -+ else -+ ret = en8811h_restart_host(phydev); -+ if (ret < 0) -+ return ret; -+ -+ /* Because of mdio-lock, may have to wait for multiple loads */ -+ pollret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, -+ EN8811H_PHY_FW_STATUS, reg_value, -+ reg_value == EN8811H_PHY_READY, -+ 20000, 7500000, true); -+ -+ ret = air_buckpbus_reg_read(phydev, EN8811H_FW_VERSION, &pbus_value); -+ if (ret < 0) -+ return ret; -+ -+ if (pollret || !pbus_value) { -+ phydev_err(phydev, "Firmware not ready: 0x%x\n", reg_value); -+ return -ENODEV; -+ } -+ -+ if (!priv->firmware_version) { -+ phydev_info(phydev, "MD32 firmware version: %08x\n", pbus_value); -+ priv->firmware_version = pbus_value; -+ } -+ -+ /* Select mode 1, the only mode supported */ -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_HOST_CMD_1, -+ AIR_PHY_HOST_CMD_1_MODE1); -+ if (ret < 0) -+ return ret; -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_HOST_CMD_2, -+ AIR_PHY_HOST_CMD_2_MODE1); -+ if (ret < 0) -+ return ret; -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_HOST_CMD_3, -+ AIR_PHY_HOST_CMD_3_MODE1); -+ if (ret < 0) -+ return ret; -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_HOST_CMD_4, -+ AIR_PHY_HOST_CMD_4_MODE1); -+ if (ret < 0) -+ return ret; -+ -+ /* Serdes polarity */ -+ ret = air_buckpbus_reg_read(phydev, EN8811H_POLARITY, &pbus_value); -+ if (ret < 0) -+ return ret; -+ if (device_property_read_bool(dev, "airoha,pnswap-rx")) -+ pbus_value |= EN8811H_POLARITY_RX_REVERSE; -+ else -+ pbus_value &= ~EN8811H_POLARITY_RX_REVERSE; -+ if (device_property_read_bool(dev, "airoha,pnswap-tx")) -+ pbus_value &= ~EN8811H_POLARITY_TX_NORMAL; -+ else -+ pbus_value |= EN8811H_POLARITY_TX_NORMAL; -+ ret = air_buckpbus_reg_write(phydev, EN8811H_POLARITY, pbus_value); -+ if (ret < 0) -+ return ret; -+ -+ ret = air_leds_init(phydev, EN8811H_LED_COUNT, AIR_PHY_LED_DUR, -+ AIR_LED_MODE_USER_DEFINE); -+ if (ret < 0) { -+ phydev_err(phydev, "Failed to initialize leds: %d\n", ret); -+ return ret; -+ } -+ -+ ret = air_buckpbus_reg_read(phydev, EN8811H_GPIO_OUTPUT, &pbus_value); -+ if (ret < 0) -+ return ret; -+ pbus_value |= EN8811H_GPIO_OUTPUT_345; -+ ret = air_buckpbus_reg_write(phydev, EN8811H_GPIO_OUTPUT, pbus_value); -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+static int en8811h_get_features(struct phy_device *phydev) -+{ -+ linkmode_set_bit_array(phy_basic_ports_array, -+ ARRAY_SIZE(phy_basic_ports_array), -+ phydev->supported); -+ -+ return genphy_c45_pma_read_abilities(phydev); -+} -+ -+static int en8811h_get_rate_matching(struct phy_device *phydev, -+ phy_interface_t iface) -+{ -+ return RATE_MATCH_PAUSE; -+} -+ -+static int en8811h_config_aneg(struct phy_device *phydev) -+{ -+ bool changed = false; -+ int err, val; -+ -+ val = 0; -+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, -+ phydev->advertising)) -+ val |= MDIO_AN_10GBT_CTRL_ADV2_5G; -+ err = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, -+ MDIO_AN_10GBT_CTRL_ADV2_5G, val); -+ if (err < 0) -+ return err; -+ if (err > 0) -+ changed = true; -+ -+ return __genphy_config_aneg(phydev, changed); -+} -+ -+static int en8811h_read_status(struct phy_device *phydev) -+{ -+ struct en8811h_priv *priv = phydev->priv; -+ u32 pbus_value; -+ int ret, val; -+ -+ ret = genphy_update_link(phydev); -+ if (ret) -+ return ret; -+ -+ phydev->master_slave_get = MASTER_SLAVE_CFG_UNSUPPORTED; -+ phydev->master_slave_state = MASTER_SLAVE_STATE_UNSUPPORTED; -+ phydev->speed = SPEED_UNKNOWN; -+ phydev->duplex = DUPLEX_UNKNOWN; -+ phydev->pause = 0; -+ phydev->asym_pause = 0; -+ -+ ret = genphy_read_master_slave(phydev); -+ if (ret < 0) -+ return ret; -+ -+ ret = genphy_read_lpa(phydev); -+ if (ret < 0) -+ return ret; -+ -+ /* Get link partner 2.5GBASE-T ability from vendor register */ -+ ret = air_buckpbus_reg_read(phydev, EN8811H_2P5G_LPA, &pbus_value); -+ if (ret < 0) -+ return ret; -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, -+ phydev->lp_advertising, -+ pbus_value & EN8811H_2P5G_LPA_2P5G); -+ -+ if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) -+ phy_resolve_aneg_pause(phydev); -+ -+ if (!phydev->link) -+ return 0; -+ -+ /* Get real speed from vendor register */ -+ val = phy_read(phydev, AIR_AUX_CTRL_STATUS); -+ if (val < 0) -+ return val; -+ switch (val & AIR_AUX_CTRL_STATUS_SPEED_MASK) { -+ case AIR_AUX_CTRL_STATUS_SPEED_2500: -+ phydev->speed = SPEED_2500; -+ break; -+ case AIR_AUX_CTRL_STATUS_SPEED_1000: -+ phydev->speed = SPEED_1000; -+ break; -+ case AIR_AUX_CTRL_STATUS_SPEED_100: -+ phydev->speed = SPEED_100; -+ break; -+ } -+ -+ /* BUG in PHY firmware: MDIO_AN_10GBT_STAT_LP2_5G does not get set. -+ * Firmware before version 24011202 has no vendor register 2P5G_LPA. -+ * Assume link partner advertised it if connected at 2500Mbps. -+ */ -+ if (priv->firmware_version < 0x24011202) { -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, -+ phydev->lp_advertising, -+ phydev->speed == SPEED_2500); -+ } -+ -+ /* Only supports full duplex */ -+ phydev->duplex = DUPLEX_FULL; -+ -+ return 0; -+} -+ -+static int en8811h_clear_intr(struct phy_device *phydev) -+{ -+ int ret; -+ -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_HOST_CMD_3, -+ AIR_PHY_HOST_CMD_3_DOCMD); -+ if (ret < 0) -+ return ret; -+ -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_HOST_CMD_4, -+ AIR_PHY_HOST_CMD_4_INTCLR); -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+static irqreturn_t en8811h_handle_interrupt(struct phy_device *phydev) -+{ -+ int ret; -+ -+ ret = en8811h_clear_intr(phydev); -+ if (ret < 0) { -+ phy_error(phydev); -+ return IRQ_NONE; -+ } -+ -+ phy_trigger_machine(phydev); -+ -+ return IRQ_HANDLED; -+} -+ -+static struct phy_driver en8811h_driver[] = { -+{ -+ PHY_ID_MATCH_MODEL(EN8811H_PHY_ID), -+ .name = "Airoha EN8811H", -+ .probe = en8811h_probe, -+ .get_features = en8811h_get_features, -+ .config_init = en8811h_config_init, -+ .get_rate_matching = en8811h_get_rate_matching, -+ .config_aneg = en8811h_config_aneg, -+ .read_status = en8811h_read_status, -+ .config_intr = en8811h_clear_intr, -+ .handle_interrupt = en8811h_handle_interrupt, -+ .led_hw_is_supported = en8811h_led_hw_is_supported, -+ .read_page = air_phy_read_page, -+ .write_page = air_phy_write_page, -+ .led_blink_set = air_led_blink_set, -+ .led_brightness_set = air_led_brightness_set, -+ .led_hw_control_set = air_led_hw_control_set, -+ .led_hw_control_get = air_led_hw_control_get, -+} }; -+ -+module_phy_driver(en8811h_driver); -+ -+static struct mdio_device_id __maybe_unused en8811h_tbl[] = { -+ { PHY_ID_MATCH_MODEL(EN8811H_PHY_ID) }, -+ { } -+}; -+MODULE_DEVICE_TABLE(mdio, en8811h_tbl); -+MODULE_FIRMWARE(EN8811H_MD32_DM); -+MODULE_FIRMWARE(EN8811H_MD32_DSP); -+ -+MODULE_DESCRIPTION("Airoha EN8811H PHY drivers"); -+MODULE_AUTHOR("Airoha"); -+MODULE_AUTHOR("Eric Woudstra <ericwouds@gmail.com>"); -+MODULE_LICENSE("GPL"); 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 2df5e6b28c..6ccc3eb389 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 <nbd@nbd.name> /** * napi_disable - prevent NAPI from scheduling -@@ -3152,6 +3153,7 @@ struct softnet_data { +@@ -3150,6 +3151,7 @@ struct softnet_data { unsigned int processed; unsigned int time_squeeze; unsigned int received_rps; @@ -157,7 +157,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> void netif_napi_add_weight(struct net_device *dev, struct napi_struct *napi, int (*poll)(struct napi_struct *, int), int weight) { -@@ -11171,6 +11242,9 @@ static int dev_cpu_dead(unsigned int old +@@ -11126,6 +11197,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 <nbd@nbd.name> #ifdef CONFIG_RPS remsd = oldsd->rps_ipi_list; oldsd->rps_ipi_list = NULL; -@@ -11483,6 +11557,7 @@ static int __init net_dev_init(void) +@@ -11438,6 +11512,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 <nbd@nbd.name> 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 <nbd@nbd.name> #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/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch b/target/linux/generic/pending-6.1/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch index 9556c90b57..1d4b18653e 100644 --- a/target/linux/generic/pending-6.1/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch +++ b/target/linux/generic/pending-6.1/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch @@ -17,7 +17,7 @@ Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com> --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -7025,6 +7025,7 @@ static int mv88e6xxx_register_switch(str +@@ -7037,6 +7037,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.1/778-net-l2tp-drop-flow-hash-on-forward.patch b/target/linux/generic/pending-6.1/778-net-l2tp-drop-flow-hash-on-forward.patch deleted file mode 100644 index a2c0edcbbf..0000000000 --- a/target/linux/generic/pending-6.1/778-net-l2tp-drop-flow-hash-on-forward.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 4a44a52f16ccd3d03e0cb5fb437a5eb31a5f9f05 Mon Sep 17 00:00:00 2001 -From: David Bauer <mail@david-bauer.net> -Date: Mon, 26 Feb 2024 21:39:34 +0100 -Subject: [PATCH] net l2tp: drop flow hash on forward - -Drop the flow-hash of the skb when forwarding to the L2TP netdev. - -This avoids the L2TP qdisc from using the flow-hash from the outer -packet, which is identical for every flow within the tunnel. - -This does not affect every platform but is specific for the ethernet -driver. It depends on the platform including L4 information in the -flow-hash. - -Signed-off-by: David Bauer <mail@david-bauer.net> ---- - net/l2tp/l2tp_eth.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/net/l2tp/l2tp_eth.c -+++ b/net/l2tp/l2tp_eth.c -@@ -136,6 +136,9 @@ static void l2tp_eth_dev_recv(struct l2t - /* checksums verified by L2TP */ - skb->ip_summed = CHECKSUM_NONE; - -+ /* drop outer flow-hash */ -+ skb_clear_hash(skb); -+ - skb_dst_drop(skb); - nf_reset_ct(skb); - diff --git a/target/linux/generic/pending-6.1/795-01-net-dsa-mt7530-disable-EEE-abilities-on-failure-on-M.patch b/target/linux/generic/pending-6.1/795-01-net-dsa-mt7530-disable-EEE-abilities-on-failure-on-M.patch deleted file mode 100644 index 44cf60cf14..0000000000 --- a/target/linux/generic/pending-6.1/795-01-net-dsa-mt7530-disable-EEE-abilities-on-failure-on-M.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 856e8954a0a88d1a4d2b43e9002b9249131a156f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com> -Date: Mon, 22 Apr 2024 10:15:08 +0300 -Subject: [PATCH 01/15] net: dsa: mt7530: disable EEE abilities on failure on - MT7531 and MT7988 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The MT7531_FORCE_EEE1G and MT7531_FORCE_EEE100 bits let the -PMCR_FORCE_EEE1G and PMCR_FORCE_EEE100 bits determine the 1G/100 EEE -abilities of the MAC. If MT7531_FORCE_EEE1G and MT7531_FORCE_EEE100 are -unset, the abilities are left to be determined by PHY auto polling. - -The commit 40b5d2f15c09 ("net: dsa: mt7530: Add support for EEE features") -made it so that the PMCR_FORCE_EEE1G and PMCR_FORCE_EEE100 bits are set on -mt753x_phylink_mac_link_up(). But it did not set the MT7531_FORCE_EEE1G and -MT7531_FORCE_EEE100 bits. Because of this, the EEE abilities will be -determined by PHY auto polling, regardless of the result of phy_init_eee(). - -Define these bits and add them to the MT7531_FORCE_MODE mask which is set -in mt7531_setup_common(). With this, there won't be any EEE abilities set -when phy_init_eee() returns a negative value. - -Thanks to Russell for explaining when phy_init_eee() could return a -negative value below. - -Looking at phy_init_eee(), it could return a negative value when: - -1. phydev->drv is NULL -2. if genphy_c45_eee_is_active() returns negative -3. if genphy_c45_eee_is_active() returns zero, it returns -EPROTONOSUPPORT -4. if phy_set_bits_mmd() fails (e.g. communication error with the PHY) - -If we then look at genphy_c45_eee_is_active(), then: - -genphy_c45_read_eee_adv() and genphy_c45_read_eee_lpa() propagate their -non-zero return values, otherwise this function returns zero or positive -integer. - -If we then look at genphy_c45_read_eee_adv(), then a failure of -phy_read_mmd() would cause a negative value to be returned. - -Looking at genphy_c45_read_eee_lpa(), the same is true. - -So, it can be summarised as: - -- phydev->drv is NULL -- there is a communication error accessing the PHY -- EEE is not active - -otherwise, it returns zero on success. - -If one wishes to determine whether an error occurred vs EEE not being -supported through negotiation for the negotiated speed, if it returns --EPROTONOSUPPORT in the latter case. Other error codes mean either the -driver has been unloaded or communication error. - -In conclusion, determining the EEE abilities by PHY auto polling shouldn't -result in having any EEE abilities enabled, when one of the last two -situations in the summary happens. And it seems that if phydev->drv is -NULL, there would be bigger problems with the device than a broken link. So -this is not a bugfix. - -Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com> ---- - drivers/net/dsa/mt7530.h | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -328,11 +328,15 @@ enum mt7530_vlan_port_acc_frm { - #define MT7531_FORCE_DPX BIT(29) - #define MT7531_FORCE_RX_FC BIT(28) - #define MT7531_FORCE_TX_FC BIT(27) -+#define MT7531_FORCE_EEE100 BIT(26) -+#define MT7531_FORCE_EEE1G BIT(25) - #define MT7531_FORCE_MODE (MT7531_FORCE_LNK | \ - MT7531_FORCE_SPD | \ - MT7531_FORCE_DPX | \ - MT7531_FORCE_RX_FC | \ -- MT7531_FORCE_TX_FC) -+ MT7531_FORCE_TX_FC | \ -+ MT7531_FORCE_EEE100 | \ -+ MT7531_FORCE_EEE1G) - #define PMCR_LINK_SETTINGS_MASK (PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \ - PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \ - PMCR_TX_FC_EN | PMCR_RX_FC_EN | \ diff --git a/target/linux/generic/pending-6.1/795-02-net-dsa-mt7530-refactor-MT7530_PMCR_P.patch b/target/linux/generic/pending-6.1/795-02-net-dsa-mt7530-refactor-MT7530_PMCR_P.patch deleted file mode 100644 index 3cbd62e929..0000000000 --- a/target/linux/generic/pending-6.1/795-02-net-dsa-mt7530-refactor-MT7530_PMCR_P.patch +++ /dev/null @@ -1,200 +0,0 @@ -From 712ad00d2f43814c81a7abfcbc339690a05fb6a0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com> -Date: Mon, 22 Apr 2024 10:15:09 +0300 -Subject: [PATCH 02/15] net: dsa: mt7530: refactor MT7530_PMCR_P() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The MT7530_PMCR_P() registers are on MT7530, MT7531, and the switch on the -MT7988 SoC. Rename the definition for them to MT753X_PMCR_P(). Bit 15 is -for MT7530 only. Add MT7530 prefix to the definition for bit 15. - -Use GENMASK and FIELD_PREP for PMCR_IFG_XMIT(). - -Rename PMCR_TX_EN and PMCR_RX_EN to PMCR_MAC_TX_EN and PMCR_MAC_TX_EN to -follow the naming on the "MT7621 Giga Switch Programming Guide v0.3", -"MT7531 Reference Manual for Development Board v1.0", and "MT7988A Wi-Fi 7 -Generation Router Platform: Datasheet (Open Version) v0.1" documents. - -These documents show that PMCR_RX_FC_EN is at bit 5. Correct this along -with renaming it to PMCR_FORCE_RX_FC_EN, and the same for PMCR_TX_FC_EN. - -Remove PMCR_SPEED_MASK which doesn't have a use. - -Rename the force mode definitions for MT7531 to FORCE_MODE. Add MASK at the -end for the mask that includes all force mode definitions. - -Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com> ---- - drivers/net/dsa/mt7530.c | 24 ++++++++--------- - drivers/net/dsa/mt7530.h | 58 +++++++++++++++++++++------------------- - 2 files changed, 42 insertions(+), 40 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -889,7 +889,7 @@ static void mt7530_setup_port5(struct ds - val &= ~MHWTRAP_P5_MAC_SEL & ~MHWTRAP_P5_DIS; - - /* Setup the MAC by default for the cpu port */ -- mt7530_write(priv, MT7530_PMCR_P(5), 0x56300); -+ mt7530_write(priv, MT753X_PMCR_P(5), 0x56300); - break; - case P5_INTF_SEL_GMAC5: - /* MT7530_P5_MODE_GMAC: P5 -> External phy or 2nd GMAC */ -@@ -2435,8 +2435,8 @@ mt7530_setup(struct dsa_switch *ds) - /* Clear link settings and enable force mode to force link down - * on all ports until they're enabled later. - */ -- mt7530_rmw(priv, MT7530_PMCR_P(i), PMCR_LINK_SETTINGS_MASK | -- PMCR_FORCE_MODE, PMCR_FORCE_MODE); -+ mt7530_rmw(priv, MT753X_PMCR_P(i), PMCR_LINK_SETTINGS_MASK | -+ MT7530_FORCE_MODE, MT7530_FORCE_MODE); - - /* Disable forwarding by default on all ports */ - mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK, -@@ -2546,8 +2546,8 @@ mt7531_setup_common(struct dsa_switch *d - /* Clear link settings and enable force mode to force link down - * on all ports until they're enabled later. - */ -- mt7530_rmw(priv, MT7530_PMCR_P(i), PMCR_LINK_SETTINGS_MASK | -- MT7531_FORCE_MODE, MT7531_FORCE_MODE); -+ mt7530_rmw(priv, MT753X_PMCR_P(i), PMCR_LINK_SETTINGS_MASK | -+ MT7531_FORCE_MODE_MASK, MT7531_FORCE_MODE_MASK); - - /* Disable forwarding by default on all ports */ - mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK, -@@ -2630,7 +2630,7 @@ mt7531_setup(struct dsa_switch *ds) - - /* Force link down on all ports before internal reset */ - for (i = 0; i < MT7530_NUM_PORTS; i++) -- mt7530_write(priv, MT7530_PMCR_P(i), MT7531_FORCE_LNK); -+ mt7530_write(priv, MT753X_PMCR_P(i), MT7531_FORCE_MODE_LNK); - - /* Reset the switch through internal reset */ - mt7530_write(priv, MT7530_SYS_CTRL, SYS_CTRL_SW_RST | SYS_CTRL_REG_RST); -@@ -2872,7 +2872,7 @@ mt753x_phylink_mac_config(struct phylink - - /* Are we connected to external phy */ - if (port == 5 && dsa_is_user_port(ds, 5)) -- mt7530_set(priv, MT7530_PMCR_P(port), PMCR_EXT_PHY); -+ mt7530_set(priv, MT753X_PMCR_P(port), PMCR_EXT_PHY); - } - - static void mt753x_phylink_mac_link_down(struct phylink_config *config, -@@ -2882,7 +2882,7 @@ static void mt753x_phylink_mac_link_down - struct dsa_port *dp = dsa_phylink_to_port(config); - struct mt7530_priv *priv = dp->ds->priv; - -- mt7530_clear(priv, MT7530_PMCR_P(dp->index), PMCR_LINK_SETTINGS_MASK); -+ mt7530_clear(priv, MT753X_PMCR_P(dp->index), PMCR_LINK_SETTINGS_MASK); - } - - static void mt753x_phylink_mac_link_up(struct phylink_config *config, -@@ -2896,7 +2896,7 @@ static void mt753x_phylink_mac_link_up(s - struct mt7530_priv *priv = dp->ds->priv; - u32 mcr; - -- mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK; -+ mcr = PMCR_MAC_RX_EN | PMCR_MAC_TX_EN | PMCR_FORCE_LNK; - - switch (speed) { - case SPEED_1000: -@@ -2911,9 +2911,9 @@ static void mt753x_phylink_mac_link_up(s - if (duplex == DUPLEX_FULL) { - mcr |= PMCR_FORCE_FDX; - if (tx_pause) -- mcr |= PMCR_TX_FC_EN; -+ mcr |= PMCR_FORCE_TX_FC_EN; - if (rx_pause) -- mcr |= PMCR_RX_FC_EN; -+ mcr |= PMCR_FORCE_RX_FC_EN; - } - - if (mode == MLO_AN_PHY && phydev && phy_init_eee(phydev, false) >= 0) { -@@ -2928,7 +2928,7 @@ static void mt753x_phylink_mac_link_up(s - } - } - -- mt7530_set(priv, MT7530_PMCR_P(dp->index), mcr); -+ mt7530_set(priv, MT753X_PMCR_P(dp->index), mcr); - } - - static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port, ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -304,44 +304,46 @@ enum mt7530_vlan_port_acc_frm { - #define G0_PORT_VID_DEF G0_PORT_VID(0) - - /* Register for port MAC control register */ --#define MT7530_PMCR_P(x) (0x3000 + ((x) * 0x100)) --#define PMCR_IFG_XMIT(x) (((x) & 0x3) << 18) -+#define MT753X_PMCR_P(x) (0x3000 + ((x) * 0x100)) -+#define PMCR_IFG_XMIT_MASK GENMASK(19, 18) -+#define PMCR_IFG_XMIT(x) FIELD_PREP(PMCR_IFG_XMIT_MASK, x) - #define PMCR_EXT_PHY BIT(17) - #define PMCR_MAC_MODE BIT(16) --#define PMCR_FORCE_MODE BIT(15) --#define PMCR_TX_EN BIT(14) --#define PMCR_RX_EN BIT(13) -+#define MT7530_FORCE_MODE BIT(15) -+#define PMCR_MAC_TX_EN BIT(14) -+#define PMCR_MAC_RX_EN BIT(13) - #define PMCR_BACKOFF_EN BIT(9) - #define PMCR_BACKPR_EN BIT(8) - #define PMCR_FORCE_EEE1G BIT(7) - #define PMCR_FORCE_EEE100 BIT(6) --#define PMCR_TX_FC_EN BIT(5) --#define PMCR_RX_FC_EN BIT(4) -+#define PMCR_FORCE_RX_FC_EN BIT(5) -+#define PMCR_FORCE_TX_FC_EN BIT(4) - #define PMCR_FORCE_SPEED_1000 BIT(3) - #define PMCR_FORCE_SPEED_100 BIT(2) - #define PMCR_FORCE_FDX BIT(1) - #define PMCR_FORCE_LNK BIT(0) --#define PMCR_SPEED_MASK (PMCR_FORCE_SPEED_100 | \ -- PMCR_FORCE_SPEED_1000) --#define MT7531_FORCE_LNK BIT(31) --#define MT7531_FORCE_SPD BIT(30) --#define MT7531_FORCE_DPX BIT(29) --#define MT7531_FORCE_RX_FC BIT(28) --#define MT7531_FORCE_TX_FC BIT(27) --#define MT7531_FORCE_EEE100 BIT(26) --#define MT7531_FORCE_EEE1G BIT(25) --#define MT7531_FORCE_MODE (MT7531_FORCE_LNK | \ -- MT7531_FORCE_SPD | \ -- MT7531_FORCE_DPX | \ -- MT7531_FORCE_RX_FC | \ -- MT7531_FORCE_TX_FC | \ -- MT7531_FORCE_EEE100 | \ -- MT7531_FORCE_EEE1G) --#define PMCR_LINK_SETTINGS_MASK (PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \ -- PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \ -- PMCR_TX_FC_EN | PMCR_RX_FC_EN | \ -- PMCR_FORCE_FDX | PMCR_FORCE_LNK | \ -- PMCR_FORCE_EEE1G | PMCR_FORCE_EEE100) -+#define MT7531_FORCE_MODE_LNK BIT(31) -+#define MT7531_FORCE_MODE_SPD BIT(30) -+#define MT7531_FORCE_MODE_DPX BIT(29) -+#define MT7531_FORCE_MODE_RX_FC BIT(28) -+#define MT7531_FORCE_MODE_TX_FC BIT(27) -+#define MT7531_FORCE_MODE_EEE100 BIT(26) -+#define MT7531_FORCE_MODE_EEE1G BIT(25) -+#define MT7531_FORCE_MODE_MASK (MT7531_FORCE_MODE_LNK | \ -+ MT7531_FORCE_MODE_SPD | \ -+ MT7531_FORCE_MODE_DPX | \ -+ MT7531_FORCE_MODE_RX_FC | \ -+ MT7531_FORCE_MODE_TX_FC | \ -+ MT7531_FORCE_MODE_EEE100 | \ -+ MT7531_FORCE_MODE_EEE1G) -+#define PMCR_LINK_SETTINGS_MASK (PMCR_MAC_TX_EN | PMCR_MAC_RX_EN | \ -+ PMCR_FORCE_EEE1G | \ -+ PMCR_FORCE_EEE100 | \ -+ PMCR_FORCE_RX_FC_EN | \ -+ PMCR_FORCE_TX_FC_EN | \ -+ PMCR_FORCE_SPEED_1000 | \ -+ PMCR_FORCE_SPEED_100 | \ -+ PMCR_FORCE_FDX | PMCR_FORCE_LNK) - - #define MT7530_PMEEECR_P(x) (0x3004 + (x) * 0x100) - #define WAKEUP_TIME_1000(x) (((x) & 0xFF) << 24) diff --git a/target/linux/generic/pending-6.1/795-03-net-dsa-mt7530-rename-p5_intf_sel-and-use-only-for-M.patch b/target/linux/generic/pending-6.1/795-03-net-dsa-mt7530-rename-p5_intf_sel-and-use-only-for-M.patch deleted file mode 100644 index 9697e7eb4f..0000000000 --- a/target/linux/generic/pending-6.1/795-03-net-dsa-mt7530-rename-p5_intf_sel-and-use-only-for-M.patch +++ /dev/null @@ -1,185 +0,0 @@ -From 875ec5b67ab88e969b171e6e9ea803e3ed759614 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com> -Date: Mon, 22 Apr 2024 10:15:10 +0300 -Subject: [PATCH 03/15] net: dsa: mt7530: rename p5_intf_sel and use only for - MT7530 switch -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The p5_intf_sel pointer is used to store the information of whether PHY -muxing is used or not. PHY muxing is a feature specific to port 5 of the -MT7530 switch. Do not use it for other switch models. - -Rename the pointer to p5_mode to store the mode the port is being used in. -Rename the p5_interface_select enum to mt7530_p5_mode, the string -representation to mt7530_p5_mode_str, and the enum elements. - -If PHY muxing is not detected, the default mode, GMAC5, will be used. - -Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com> ---- - drivers/net/dsa/mt7530.c | 62 +++++++++++++++++----------------------- - drivers/net/dsa/mt7530.h | 15 +++++----- - 2 files changed, 33 insertions(+), 44 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -850,19 +850,15 @@ mt7530_set_ageing_time(struct dsa_switch - return 0; - } - --static const char *p5_intf_modes(unsigned int p5_interface) -+static const char *mt7530_p5_mode_str(unsigned int mode) - { -- switch (p5_interface) { -- case P5_DISABLED: -- return "DISABLED"; -- case P5_INTF_SEL_PHY_P0: -- return "PHY P0"; -- case P5_INTF_SEL_PHY_P4: -- return "PHY P4"; -- case P5_INTF_SEL_GMAC5: -- return "GMAC5"; -+ switch (mode) { -+ case MUX_PHY_P0: -+ return "MUX PHY P0"; -+ case MUX_PHY_P4: -+ return "MUX PHY P4"; - default: -- return "unknown"; -+ return "GMAC5"; - } - } - -@@ -879,23 +875,23 @@ static void mt7530_setup_port5(struct ds - val |= MHWTRAP_MANUAL | MHWTRAP_P5_MAC_SEL | MHWTRAP_P5_DIS; - val &= ~MHWTRAP_P5_RGMII_MODE & ~MHWTRAP_PHY0_SEL; - -- switch (priv->p5_intf_sel) { -- case P5_INTF_SEL_PHY_P0: -- /* MT7530_P5_MODE_GPHY_P0: 2nd GMAC -> P5 -> P0 */ -+ switch (priv->p5_mode) { -+ /* MUX_PHY_P0: P0 -> P5 -> SoC MAC */ -+ case MUX_PHY_P0: - val |= MHWTRAP_PHY0_SEL; - fallthrough; -- case P5_INTF_SEL_PHY_P4: -- /* MT7530_P5_MODE_GPHY_P4: 2nd GMAC -> P5 -> P4 */ -+ -+ /* MUX_PHY_P4: P4 -> P5 -> SoC MAC */ -+ case MUX_PHY_P4: - val &= ~MHWTRAP_P5_MAC_SEL & ~MHWTRAP_P5_DIS; - - /* Setup the MAC by default for the cpu port */ - mt7530_write(priv, MT753X_PMCR_P(5), 0x56300); - break; -- case P5_INTF_SEL_GMAC5: -- /* MT7530_P5_MODE_GMAC: P5 -> External phy or 2nd GMAC */ -- val &= ~MHWTRAP_P5_DIS; -- break; -+ -+ /* GMAC5: P5 -> SoC MAC or external PHY */ - default: -+ val &= ~MHWTRAP_P5_DIS; - break; - } - -@@ -923,8 +919,8 @@ static void mt7530_setup_port5(struct ds - - mt7530_write(priv, MT7530_MHWTRAP, val); - -- dev_dbg(ds->dev, "Setup P5, HWTRAP=0x%x, intf_sel=%s, phy-mode=%s\n", -- val, p5_intf_modes(priv->p5_intf_sel), phy_modes(interface)); -+ dev_dbg(ds->dev, "Setup P5, HWTRAP=0x%x, mode=%s, phy-mode=%s\n", val, -+ mt7530_p5_mode_str(priv->p5_mode), phy_modes(interface)); - - mutex_unlock(&priv->reg_mutex); - } -@@ -2467,13 +2463,11 @@ mt7530_setup(struct dsa_switch *ds) - if (ret) - return ret; - -- /* Setup port 5 */ -- if (!dsa_is_unused_port(ds, 5)) { -- priv->p5_intf_sel = P5_INTF_SEL_GMAC5; -- } else { -+ /* Check for PHY muxing on port 5 */ -+ if (dsa_is_unused_port(ds, 5)) { - /* Scan the ethernet nodes. Look for GMAC1, lookup the used PHY. -- * Set priv->p5_intf_sel to the appropriate value if PHY muxing -- * is detected. -+ * Set priv->p5_mode to the appropriate value if PHY muxing is -+ * detected. - */ - for_each_child_of_node(dn, mac_np) { - if (!of_device_is_compatible(mac_np, -@@ -2497,17 +2491,16 @@ mt7530_setup(struct dsa_switch *ds) - } - id = of_mdio_parse_addr(ds->dev, phy_node); - if (id == 0) -- priv->p5_intf_sel = P5_INTF_SEL_PHY_P0; -+ priv->p5_mode = MUX_PHY_P0; - if (id == 4) -- priv->p5_intf_sel = P5_INTF_SEL_PHY_P4; -+ priv->p5_mode = MUX_PHY_P4; - } - of_node_put(mac_np); - of_node_put(phy_node); - break; - } - -- if (priv->p5_intf_sel == P5_INTF_SEL_PHY_P0 || -- priv->p5_intf_sel == P5_INTF_SEL_PHY_P4) -+ if (priv->p5_mode == MUX_PHY_P0 || priv->p5_mode == MUX_PHY_P4) - mt7530_setup_port5(ds, interface); - } - -@@ -2645,9 +2638,6 @@ mt7531_setup(struct dsa_switch *ds) - MT7531_EXT_P_MDIO_12); - } - -- if (!dsa_is_unused_port(ds, 5)) -- priv->p5_intf_sel = P5_INTF_SEL_GMAC5; -- - mt7530_rmw(priv, MT7531_GPIO_MODE0, MT7531_GPIO0_MASK, - MT7531_GPIO0_INTERRUPT); - ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -708,12 +708,11 @@ struct mt7530_port { - struct phylink_pcs *sgmii_pcs; - }; - --/* Port 5 interface select definitions */ --enum p5_interface_select { -- P5_DISABLED, -- P5_INTF_SEL_PHY_P0, -- P5_INTF_SEL_PHY_P4, -- P5_INTF_SEL_GMAC5, -+/* Port 5 mode definitions of the MT7530 switch */ -+enum mt7530_p5_mode { -+ GMAC5, -+ MUX_PHY_P0, -+ MUX_PHY_P4, - }; - - struct mt7530_priv; -@@ -769,7 +768,7 @@ struct mt753x_info { - * @ports: Holding the state among ports - * @reg_mutex: The lock for protecting among process accessing - * registers -- * @p5_intf_sel: Holding the current port 5 interface select -+ * @p5_mode: Holding the current mode of port 5 of the MT7530 switch - * @p5_sgmii: Flag for distinguishing if port 5 of the MT7531 switch - * has got SGMII - * @irq: IRQ number of the switch -@@ -791,7 +790,7 @@ struct mt7530_priv { - const struct mt753x_info *info; - unsigned int id; - bool mcm; -- enum p5_interface_select p5_intf_sel; -+ enum mt7530_p5_mode p5_mode; - bool p5_sgmii; - u8 mirror_rx; - u8 mirror_tx; diff --git a/target/linux/generic/pending-6.1/795-04-net-dsa-mt7530-rename-mt753x_bpdu_port_fw-enum-to-mt.patch b/target/linux/generic/pending-6.1/795-04-net-dsa-mt7530-rename-mt753x_bpdu_port_fw-enum-to-mt.patch deleted file mode 100644 index 77a2df8586..0000000000 --- a/target/linux/generic/pending-6.1/795-04-net-dsa-mt7530-rename-mt753x_bpdu_port_fw-enum-to-mt.patch +++ /dev/null @@ -1,169 +0,0 @@ -From 83fe3df057e641cd0e88425e579d7a5a370ca430 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com> -Date: Mon, 22 Apr 2024 10:15:11 +0300 -Subject: [PATCH 04/15] net: dsa: mt7530: rename mt753x_bpdu_port_fw enum to - mt753x_to_cpu_fw -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The mt753x_bpdu_port_fw enum is globally used for manipulating the process -of deciding the forwardable ports, specifically concerning the CPU port(s). -Therefore, rename it and the values in it to mt753x_to_cpu_fw. - -Change FOLLOW_MFC to SYSTEM_DEFAULT to be on par with the switch documents. - -Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com> ---- - drivers/net/dsa/mt7530.c | 44 ++++++++++------------- - drivers/net/dsa/mt7530.h | 76 ++++++++++++++++++++-------------------- - 2 files changed, 56 insertions(+), 64 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -1100,42 +1100,34 @@ mt753x_trap_frames(struct mt7530_priv *p - * VLAN-untagged. - */ - mt7530_rmw(priv, MT753X_BPC, -- MT753X_PAE_BPDU_FR | MT753X_PAE_EG_TAG_MASK | -- MT753X_PAE_PORT_FW_MASK | MT753X_BPDU_EG_TAG_MASK | -- MT753X_BPDU_PORT_FW_MASK, -- MT753X_PAE_BPDU_FR | -- MT753X_PAE_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -- MT753X_PAE_PORT_FW(MT753X_BPDU_CPU_ONLY) | -- MT753X_BPDU_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -- MT753X_BPDU_CPU_ONLY); -+ PAE_BPDU_FR | PAE_EG_TAG_MASK | PAE_PORT_FW_MASK | -+ BPDU_EG_TAG_MASK | BPDU_PORT_FW_MASK, -+ PAE_BPDU_FR | PAE_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -+ PAE_PORT_FW(TO_CPU_FW_CPU_ONLY) | -+ BPDU_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -+ TO_CPU_FW_CPU_ONLY); - - /* Trap frames with :01 and :02 MAC DAs to the CPU port(s) and egress - * them VLAN-untagged. - */ - mt7530_rmw(priv, MT753X_RGAC1, -- MT753X_R02_BPDU_FR | MT753X_R02_EG_TAG_MASK | -- MT753X_R02_PORT_FW_MASK | MT753X_R01_BPDU_FR | -- MT753X_R01_EG_TAG_MASK | MT753X_R01_PORT_FW_MASK, -- MT753X_R02_BPDU_FR | -- MT753X_R02_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -- MT753X_R02_PORT_FW(MT753X_BPDU_CPU_ONLY) | -- MT753X_R01_BPDU_FR | -- MT753X_R01_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -- MT753X_BPDU_CPU_ONLY); -+ R02_BPDU_FR | R02_EG_TAG_MASK | R02_PORT_FW_MASK | -+ R01_BPDU_FR | R01_EG_TAG_MASK | R01_PORT_FW_MASK, -+ R02_BPDU_FR | R02_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -+ R02_PORT_FW(TO_CPU_FW_CPU_ONLY) | R01_BPDU_FR | -+ R01_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -+ TO_CPU_FW_CPU_ONLY); - - /* Trap frames with :03 and :0E MAC DAs to the CPU port(s) and egress - * them VLAN-untagged. - */ - mt7530_rmw(priv, MT753X_RGAC2, -- MT753X_R0E_BPDU_FR | MT753X_R0E_EG_TAG_MASK | -- MT753X_R0E_PORT_FW_MASK | MT753X_R03_BPDU_FR | -- MT753X_R03_EG_TAG_MASK | MT753X_R03_PORT_FW_MASK, -- MT753X_R0E_BPDU_FR | -- MT753X_R0E_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -- MT753X_R0E_PORT_FW(MT753X_BPDU_CPU_ONLY) | -- MT753X_R03_BPDU_FR | -- MT753X_R03_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -- MT753X_BPDU_CPU_ONLY); -+ R0E_BPDU_FR | R0E_EG_TAG_MASK | R0E_PORT_FW_MASK | -+ R03_BPDU_FR | R03_EG_TAG_MASK | R03_PORT_FW_MASK, -+ R0E_BPDU_FR | R0E_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -+ R0E_PORT_FW(TO_CPU_FW_CPU_ONLY) | R03_BPDU_FR | -+ R03_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -+ TO_CPU_FW_CPU_ONLY); - } - - static void ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -67,47 +67,47 @@ enum mt753x_id { - #define MT753X_MIRROR_MASK(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \ - MT7531_MIRROR_MASK : MIRROR_MASK) - --/* Registers for BPDU and PAE frame control*/ -+/* Register for BPDU and PAE frame control */ - #define MT753X_BPC 0x24 --#define MT753X_PAE_BPDU_FR BIT(25) --#define MT753X_PAE_EG_TAG_MASK GENMASK(24, 22) --#define MT753X_PAE_EG_TAG(x) FIELD_PREP(MT753X_PAE_EG_TAG_MASK, x) --#define MT753X_PAE_PORT_FW_MASK GENMASK(18, 16) --#define MT753X_PAE_PORT_FW(x) FIELD_PREP(MT753X_PAE_PORT_FW_MASK, x) --#define MT753X_BPDU_EG_TAG_MASK GENMASK(8, 6) --#define MT753X_BPDU_EG_TAG(x) FIELD_PREP(MT753X_BPDU_EG_TAG_MASK, x) --#define MT753X_BPDU_PORT_FW_MASK GENMASK(2, 0) -+#define PAE_BPDU_FR BIT(25) -+#define PAE_EG_TAG_MASK GENMASK(24, 22) -+#define PAE_EG_TAG(x) FIELD_PREP(PAE_EG_TAG_MASK, x) -+#define PAE_PORT_FW_MASK GENMASK(18, 16) -+#define PAE_PORT_FW(x) FIELD_PREP(PAE_PORT_FW_MASK, x) -+#define BPDU_EG_TAG_MASK GENMASK(8, 6) -+#define BPDU_EG_TAG(x) FIELD_PREP(BPDU_EG_TAG_MASK, x) -+#define BPDU_PORT_FW_MASK GENMASK(2, 0) - --/* Register for :01 and :02 MAC DA frame control */ -+/* Register for 01-80-C2-00-00-[01,02] MAC DA frame control */ - #define MT753X_RGAC1 0x28 --#define MT753X_R02_BPDU_FR BIT(25) --#define MT753X_R02_EG_TAG_MASK GENMASK(24, 22) --#define MT753X_R02_EG_TAG(x) FIELD_PREP(MT753X_R02_EG_TAG_MASK, x) --#define MT753X_R02_PORT_FW_MASK GENMASK(18, 16) --#define MT753X_R02_PORT_FW(x) FIELD_PREP(MT753X_R02_PORT_FW_MASK, x) --#define MT753X_R01_BPDU_FR BIT(9) --#define MT753X_R01_EG_TAG_MASK GENMASK(8, 6) --#define MT753X_R01_EG_TAG(x) FIELD_PREP(MT753X_R01_EG_TAG_MASK, x) --#define MT753X_R01_PORT_FW_MASK GENMASK(2, 0) -+#define R02_BPDU_FR BIT(25) -+#define R02_EG_TAG_MASK GENMASK(24, 22) -+#define R02_EG_TAG(x) FIELD_PREP(R02_EG_TAG_MASK, x) -+#define R02_PORT_FW_MASK GENMASK(18, 16) -+#define R02_PORT_FW(x) FIELD_PREP(R02_PORT_FW_MASK, x) -+#define R01_BPDU_FR BIT(9) -+#define R01_EG_TAG_MASK GENMASK(8, 6) -+#define R01_EG_TAG(x) FIELD_PREP(R01_EG_TAG_MASK, x) -+#define R01_PORT_FW_MASK GENMASK(2, 0) - --/* Register for :03 and :0E MAC DA frame control */ -+/* Register for 01-80-C2-00-00-[03,0E] MAC DA frame control */ - #define MT753X_RGAC2 0x2c --#define MT753X_R0E_BPDU_FR BIT(25) --#define MT753X_R0E_EG_TAG_MASK GENMASK(24, 22) --#define MT753X_R0E_EG_TAG(x) FIELD_PREP(MT753X_R0E_EG_TAG_MASK, x) --#define MT753X_R0E_PORT_FW_MASK GENMASK(18, 16) --#define MT753X_R0E_PORT_FW(x) FIELD_PREP(MT753X_R0E_PORT_FW_MASK, x) --#define MT753X_R03_BPDU_FR BIT(9) --#define MT753X_R03_EG_TAG_MASK GENMASK(8, 6) --#define MT753X_R03_EG_TAG(x) FIELD_PREP(MT753X_R03_EG_TAG_MASK, x) --#define MT753X_R03_PORT_FW_MASK GENMASK(2, 0) -+#define R0E_BPDU_FR BIT(25) -+#define R0E_EG_TAG_MASK GENMASK(24, 22) -+#define R0E_EG_TAG(x) FIELD_PREP(R0E_EG_TAG_MASK, x) -+#define R0E_PORT_FW_MASK GENMASK(18, 16) -+#define R0E_PORT_FW(x) FIELD_PREP(R0E_PORT_FW_MASK, x) -+#define R03_BPDU_FR BIT(9) -+#define R03_EG_TAG_MASK GENMASK(8, 6) -+#define R03_EG_TAG(x) FIELD_PREP(R03_EG_TAG_MASK, x) -+#define R03_PORT_FW_MASK GENMASK(2, 0) - --enum mt753x_bpdu_port_fw { -- MT753X_BPDU_FOLLOW_MFC, -- MT753X_BPDU_CPU_EXCLUDE = 4, -- MT753X_BPDU_CPU_INCLUDE = 5, -- MT753X_BPDU_CPU_ONLY = 6, -- MT753X_BPDU_DROP = 7, -+enum mt753x_to_cpu_fw { -+ TO_CPU_FW_SYSTEM_DEFAULT, -+ TO_CPU_FW_CPU_EXCLUDE = 4, -+ TO_CPU_FW_CPU_INCLUDE = 5, -+ TO_CPU_FW_CPU_ONLY = 6, -+ TO_CPU_FW_DROP = 7, - }; - - /* Registers for address table access */ diff --git a/target/linux/generic/pending-6.1/795-05-net-dsa-mt7530-refactor-MT7530_MFC-and-MT7531_CFC-ad.patch b/target/linux/generic/pending-6.1/795-05-net-dsa-mt7530-refactor-MT7530_MFC-and-MT7531_CFC-ad.patch deleted file mode 100644 index 95cdfac02e..0000000000 --- a/target/linux/generic/pending-6.1/795-05-net-dsa-mt7530-refactor-MT7530_MFC-and-MT7531_CFC-ad.patch +++ /dev/null @@ -1,201 +0,0 @@ -From 1dbc1bdc2869e6d2929235c70d64e393aa5a5fa2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com> -Date: Mon, 22 Apr 2024 10:15:12 +0300 -Subject: [PATCH 05/15] net: dsa: mt7530: refactor MT7530_MFC and MT7531_CFC, - add MT7531_QRY_FFP -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The MT7530_MFC register is on MT7530, MT7531, and the switch on the MT7988 -SoC. Rename it to MT753X_MFC. Bit 7 to 0 differs between MT7530 and -MT7531/MT7988. Add MT7530 prefix to these definitions, and define the -IGMP/MLD Query Frame Flooding Ports mask for MT7531. - -Rename the cases of MIRROR_MASK to MIRROR_PORT_MASK. - -Move mt753x_mirror_port_get() and mt753x_port_mirror_set() to mt7530.h as -macros. - -Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com> ---- - drivers/net/dsa/mt7530.c | 38 ++++++++-------------- - drivers/net/dsa/mt7530.h | 69 +++++++++++++++++++++++++--------------- - 2 files changed, 57 insertions(+), 50 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -1140,7 +1140,7 @@ mt753x_cpu_port_enable(struct dsa_switch - PORT_SPEC_TAG); - - /* Enable flooding on the CPU port */ -- mt7530_set(priv, MT7530_MFC, BC_FFP(BIT(port)) | UNM_FFP(BIT(port)) | -+ mt7530_set(priv, MT753X_MFC, BC_FFP(BIT(port)) | UNM_FFP(BIT(port)) | - UNU_FFP(BIT(port))); - - /* Add the CPU port to the CPU port bitmap for MT7531 and the switch on -@@ -1304,15 +1304,15 @@ mt7530_port_bridge_flags(struct dsa_swit - flags.val & BR_LEARNING ? 0 : SA_DIS); - - if (flags.mask & BR_FLOOD) -- mt7530_rmw(priv, MT7530_MFC, UNU_FFP(BIT(port)), -+ mt7530_rmw(priv, MT753X_MFC, UNU_FFP(BIT(port)), - flags.val & BR_FLOOD ? UNU_FFP(BIT(port)) : 0); - - if (flags.mask & BR_MCAST_FLOOD) -- mt7530_rmw(priv, MT7530_MFC, UNM_FFP(BIT(port)), -+ mt7530_rmw(priv, MT753X_MFC, UNM_FFP(BIT(port)), - flags.val & BR_MCAST_FLOOD ? UNM_FFP(BIT(port)) : 0); - - if (flags.mask & BR_BCAST_FLOOD) -- mt7530_rmw(priv, MT7530_MFC, BC_FFP(BIT(port)), -+ mt7530_rmw(priv, MT753X_MFC, BC_FFP(BIT(port)), - flags.val & BR_BCAST_FLOOD ? BC_FFP(BIT(port)) : 0); - - return 0; -@@ -1848,20 +1848,6 @@ mt7530_port_vlan_del(struct dsa_switch * - return 0; - } - --static int mt753x_mirror_port_get(unsigned int id, u32 val) --{ -- return (id == ID_MT7531 || id == ID_MT7988) ? -- MT7531_MIRROR_PORT_GET(val) : -- MIRROR_PORT(val); --} -- --static int mt753x_mirror_port_set(unsigned int id, u32 val) --{ -- return (id == ID_MT7531 || id == ID_MT7988) ? -- MT7531_MIRROR_PORT_SET(val) : -- MIRROR_PORT(val); --} -- - static int mt753x_port_mirror_add(struct dsa_switch *ds, int port, - struct dsa_mall_mirror_tc_entry *mirror, - bool ingress, struct netlink_ext_ack *extack) -@@ -1877,14 +1863,14 @@ static int mt753x_port_mirror_add(struct - val = mt7530_read(priv, MT753X_MIRROR_REG(priv->id)); - - /* MT7530 only supports one monitor port */ -- monitor_port = mt753x_mirror_port_get(priv->id, val); -+ monitor_port = MT753X_MIRROR_PORT_GET(priv->id, val); - if (val & MT753X_MIRROR_EN(priv->id) && - monitor_port != mirror->to_local_port) - return -EEXIST; - - val |= MT753X_MIRROR_EN(priv->id); -- val &= ~MT753X_MIRROR_MASK(priv->id); -- val |= mt753x_mirror_port_set(priv->id, mirror->to_local_port); -+ val &= ~MT753X_MIRROR_PORT_MASK(priv->id); -+ val |= MT753X_MIRROR_PORT_SET(priv->id, mirror->to_local_port); - mt7530_write(priv, MT753X_MIRROR_REG(priv->id), val); - - val = mt7530_read(priv, MT7530_PCR_P(port)); -@@ -2524,7 +2510,7 @@ mt7531_setup_common(struct dsa_switch *d - mt7530_mib_reset(ds); - - /* Disable flooding on all ports */ -- mt7530_clear(priv, MT7530_MFC, BC_FFP_MASK | UNM_FFP_MASK | -+ mt7530_clear(priv, MT753X_MFC, BC_FFP_MASK | UNM_FFP_MASK | - UNU_FFP_MASK); - - for (i = 0; i < MT7530_NUM_PORTS; i++) { -@@ -3086,10 +3072,12 @@ mt753x_conduit_state_change(struct dsa_s - else - priv->active_cpu_ports &= ~mask; - -- if (priv->active_cpu_ports) -- val = CPU_EN | CPU_PORT(__ffs(priv->active_cpu_ports)); -+ if (priv->active_cpu_ports) { -+ val = MT7530_CPU_EN | -+ MT7530_CPU_PORT(__ffs(priv->active_cpu_ports)); -+ } - -- mt7530_rmw(priv, MT7530_MFC, CPU_EN | CPU_PORT_MASK, val); -+ mt7530_rmw(priv, MT753X_MFC, MT7530_CPU_EN | MT7530_CPU_PORT_MASK, val); - } - - static int mt7988_setup(struct dsa_switch *ds) ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -36,36 +36,55 @@ enum mt753x_id { - #define MT753X_AGC 0xc - #define LOCAL_EN BIT(7) - --/* Registers to mac forward control for unknown frames */ --#define MT7530_MFC 0x10 --#define BC_FFP(x) (((x) & 0xff) << 24) --#define BC_FFP_MASK BC_FFP(~0) --#define UNM_FFP(x) (((x) & 0xff) << 16) --#define UNM_FFP_MASK UNM_FFP(~0) --#define UNU_FFP(x) (((x) & 0xff) << 8) --#define UNU_FFP_MASK UNU_FFP(~0) --#define CPU_EN BIT(7) --#define CPU_PORT_MASK GENMASK(6, 4) --#define CPU_PORT(x) FIELD_PREP(CPU_PORT_MASK, x) --#define MIRROR_EN BIT(3) --#define MIRROR_PORT(x) ((x) & 0x7) --#define MIRROR_MASK 0x7 -+/* Register for MAC forward control */ -+#define MT753X_MFC 0x10 -+#define BC_FFP_MASK GENMASK(31, 24) -+#define BC_FFP(x) FIELD_PREP(BC_FFP_MASK, x) -+#define UNM_FFP_MASK GENMASK(23, 16) -+#define UNM_FFP(x) FIELD_PREP(UNM_FFP_MASK, x) -+#define UNU_FFP_MASK GENMASK(15, 8) -+#define UNU_FFP(x) FIELD_PREP(UNU_FFP_MASK, x) -+#define MT7530_CPU_EN BIT(7) -+#define MT7530_CPU_PORT_MASK GENMASK(6, 4) -+#define MT7530_CPU_PORT(x) FIELD_PREP(MT7530_CPU_PORT_MASK, x) -+#define MT7530_MIRROR_EN BIT(3) -+#define MT7530_MIRROR_PORT_MASK GENMASK(2, 0) -+#define MT7530_MIRROR_PORT_GET(x) FIELD_GET(MT7530_MIRROR_PORT_MASK, x) -+#define MT7530_MIRROR_PORT_SET(x) FIELD_PREP(MT7530_MIRROR_PORT_MASK, x) -+#define MT7531_QRY_FFP_MASK GENMASK(7, 0) -+#define MT7531_QRY_FFP(x) FIELD_PREP(MT7531_QRY_FFP_MASK, x) - --/* Registers for CPU forward control */ -+/* Register for CPU forward control */ - #define MT7531_CFC 0x4 - #define MT7531_MIRROR_EN BIT(19) --#define MT7531_MIRROR_MASK (MIRROR_MASK << 16) --#define MT7531_MIRROR_PORT_GET(x) (((x) >> 16) & MIRROR_MASK) --#define MT7531_MIRROR_PORT_SET(x) (((x) & MIRROR_MASK) << 16) -+#define MT7531_MIRROR_PORT_MASK GENMASK(18, 16) -+#define MT7531_MIRROR_PORT_GET(x) FIELD_GET(MT7531_MIRROR_PORT_MASK, x) -+#define MT7531_MIRROR_PORT_SET(x) FIELD_PREP(MT7531_MIRROR_PORT_MASK, x) - #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) || ((id) == ID_MT7988)) ? \ -- MT7531_CFC : MT7530_MFC) --#define MT753X_MIRROR_EN(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \ -- MT7531_MIRROR_EN : MIRROR_EN) --#define MT753X_MIRROR_MASK(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \ -- MT7531_MIRROR_MASK : MIRROR_MASK) -+#define MT753X_MIRROR_REG(id) ((id == ID_MT7531 || \ -+ id == ID_MT7988) ? \ -+ MT7531_CFC : MT753X_MFC) -+ -+#define MT753X_MIRROR_EN(id) ((id == ID_MT7531 || \ -+ id == ID_MT7988) ? \ -+ MT7531_MIRROR_EN : MT7530_MIRROR_EN) -+ -+#define MT753X_MIRROR_PORT_MASK(id) ((id == ID_MT7531 || \ -+ id == ID_MT7988) ? \ -+ MT7531_MIRROR_PORT_MASK : \ -+ MT7530_MIRROR_PORT_MASK) -+ -+#define MT753X_MIRROR_PORT_GET(id, val) ((id == ID_MT7531 || \ -+ id == ID_MT7988) ? \ -+ MT7531_MIRROR_PORT_GET(val) : \ -+ MT7530_MIRROR_PORT_GET(val)) -+ -+#define MT753X_MIRROR_PORT_SET(id, val) ((id == ID_MT7531 || \ -+ id == ID_MT7988) ? \ -+ MT7531_MIRROR_PORT_SET(val) : \ -+ MT7530_MIRROR_PORT_SET(val)) - - /* Register for BPDU and PAE frame control */ - #define MT753X_BPC 0x24 diff --git a/target/linux/generic/pending-6.1/795-06-net-dsa-mt7530-refactor-MT7530_HWTRAP-and-MT7530_MHW.patch b/target/linux/generic/pending-6.1/795-06-net-dsa-mt7530-refactor-MT7530_HWTRAP-and-MT7530_MHW.patch deleted file mode 100644 index d2497d5c90..0000000000 --- a/target/linux/generic/pending-6.1/795-06-net-dsa-mt7530-refactor-MT7530_HWTRAP-and-MT7530_MHW.patch +++ /dev/null @@ -1,257 +0,0 @@ -From 3ccf67597d35c06a7319e407b1c42f78a7966779 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com> -Date: Mon, 22 Apr 2024 10:15:13 +0300 -Subject: [PATCH 06/15] net: dsa: mt7530: refactor MT7530_HWTRAP and - MT7530_MHWTRAP -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The MT7530_HWTRAP and MT7530_MHWTRAP registers are on MT7530 and MT7531. -It's called hardware trap on MT7530, software trap on MT7531. That's -because some bits of the trap on MT7530 cannot be modified by software -whilst all bits of the trap on MT7531 can. Rename the definitions for them -to MT753X_TRAP and MT753X_MTRAP. Add MT7530 and MT7531 prefixes to the -definitions specific to the switch model. - -Remove the extra parentheses from MT7530_XTAL_40MHZ and MT7530_XTAL_20MHZ. - -Rename MHWTRAP_PHY0_SEL, MHWTRAP_MANUAL, and MHWTRAP_PHY_ACCESS to be on -par with the "MT7621 Giga Switch Programming Guide v0.3" document. - -Make an enumaration for the XTAL frequency. Set the data type of the xtal -variable on mt7531_pll_setup() to it. - -Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com> ---- - drivers/net/dsa/mt7530.c | 59 ++++++++++++++++++++-------------------- - drivers/net/dsa/mt7530.h | 50 ++++++++++++++++------------------ - 2 files changed, 54 insertions(+), 55 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -403,23 +403,23 @@ mt7530_setup_port6(struct dsa_switch *ds - - mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK, P6_INTF_MODE(1)); - -- xtal = mt7530_read(priv, MT7530_MHWTRAP) & HWTRAP_XTAL_MASK; -+ xtal = mt7530_read(priv, MT753X_MTRAP) & MT7530_XTAL_MASK; - -- if (xtal == HWTRAP_XTAL_25MHZ) -+ if (xtal == MT7530_XTAL_25MHZ) - ssc_delta = 0x57; - else - ssc_delta = 0x87; - - if (priv->id == ID_MT7621) { - /* PLL frequency: 125MHz: 1.0GBit */ -- if (xtal == HWTRAP_XTAL_40MHZ) -+ if (xtal == MT7530_XTAL_40MHZ) - ncpo1 = 0x0640; -- if (xtal == HWTRAP_XTAL_25MHZ) -+ if (xtal == MT7530_XTAL_25MHZ) - ncpo1 = 0x0a00; - } else { /* PLL frequency: 250MHz: 2.0Gbit */ -- if (xtal == HWTRAP_XTAL_40MHZ) -+ if (xtal == MT7530_XTAL_40MHZ) - ncpo1 = 0x0c80; -- if (xtal == HWTRAP_XTAL_25MHZ) -+ if (xtal == MT7530_XTAL_25MHZ) - ncpo1 = 0x1400; - } - -@@ -442,19 +442,20 @@ mt7530_setup_port6(struct dsa_switch *ds - static void - mt7531_pll_setup(struct mt7530_priv *priv) - { -+ enum mt7531_xtal_fsel xtal; - u32 top_sig; - u32 hwstrap; -- u32 xtal; - u32 val; - - val = mt7530_read(priv, MT7531_CREV); - top_sig = mt7530_read(priv, MT7531_TOP_SIG_SR); -- hwstrap = mt7530_read(priv, MT7531_HWTRAP); -+ hwstrap = mt7530_read(priv, MT753X_TRAP); - if ((val & CHIP_REV_M) > 0) -- xtal = (top_sig & PAD_MCM_SMI_EN) ? HWTRAP_XTAL_FSEL_40MHZ : -- HWTRAP_XTAL_FSEL_25MHZ; -+ xtal = (top_sig & PAD_MCM_SMI_EN) ? MT7531_XTAL_FSEL_40MHZ : -+ MT7531_XTAL_FSEL_25MHZ; - else -- xtal = hwstrap & HWTRAP_XTAL_FSEL_MASK; -+ xtal = (hwstrap & MT7531_XTAL25) ? MT7531_XTAL_FSEL_25MHZ : -+ MT7531_XTAL_FSEL_40MHZ; - - /* Step 1 : Disable MT7531 COREPLL */ - val = mt7530_read(priv, MT7531_PLLGP_EN); -@@ -483,13 +484,13 @@ mt7531_pll_setup(struct mt7530_priv *pri - usleep_range(25, 35); - - switch (xtal) { -- case HWTRAP_XTAL_FSEL_25MHZ: -+ case MT7531_XTAL_FSEL_25MHZ: - val = mt7530_read(priv, MT7531_PLLGP_CR0); - val &= ~RG_COREPLL_SDM_PCW_M; - val |= 0x140000 << RG_COREPLL_SDM_PCW_S; - mt7530_write(priv, MT7531_PLLGP_CR0, val); - break; -- case HWTRAP_XTAL_FSEL_40MHZ: -+ case MT7531_XTAL_FSEL_40MHZ: - val = mt7530_read(priv, MT7531_PLLGP_CR0); - val &= ~RG_COREPLL_SDM_PCW_M; - val |= 0x190000 << RG_COREPLL_SDM_PCW_S; -@@ -870,20 +871,20 @@ static void mt7530_setup_port5(struct ds - - mutex_lock(&priv->reg_mutex); - -- val = mt7530_read(priv, MT7530_MHWTRAP); -+ val = mt7530_read(priv, MT753X_MTRAP); - -- val |= MHWTRAP_MANUAL | MHWTRAP_P5_MAC_SEL | MHWTRAP_P5_DIS; -- val &= ~MHWTRAP_P5_RGMII_MODE & ~MHWTRAP_PHY0_SEL; -+ val |= MT7530_CHG_TRAP | MT7530_P5_MAC_SEL | MT7530_P5_DIS; -+ val &= ~MT7530_P5_RGMII_MODE & ~MT7530_P5_PHY0_SEL; - - switch (priv->p5_mode) { - /* MUX_PHY_P0: P0 -> P5 -> SoC MAC */ - case MUX_PHY_P0: -- val |= MHWTRAP_PHY0_SEL; -+ val |= MT7530_P5_PHY0_SEL; - fallthrough; - - /* MUX_PHY_P4: P4 -> P5 -> SoC MAC */ - case MUX_PHY_P4: -- val &= ~MHWTRAP_P5_MAC_SEL & ~MHWTRAP_P5_DIS; -+ val &= ~MT7530_P5_MAC_SEL & ~MT7530_P5_DIS; - - /* Setup the MAC by default for the cpu port */ - mt7530_write(priv, MT753X_PMCR_P(5), 0x56300); -@@ -891,13 +892,13 @@ static void mt7530_setup_port5(struct ds - - /* GMAC5: P5 -> SoC MAC or external PHY */ - default: -- val &= ~MHWTRAP_P5_DIS; -+ val &= ~MT7530_P5_DIS; - break; - } - - /* Setup RGMII settings */ - if (phy_interface_mode_is_rgmii(interface)) { -- val |= MHWTRAP_P5_RGMII_MODE; -+ val |= MT7530_P5_RGMII_MODE; - - /* P5 RGMII RX Clock Control: delay setting for 1000M */ - mt7530_write(priv, MT7530_P5RGMIIRXCR, CSR_RGMII_EDGE_ALIGN); -@@ -917,7 +918,7 @@ static void mt7530_setup_port5(struct ds - P5_IO_CLK_DRV(1) | P5_IO_DATA_DRV(1)); - } - -- mt7530_write(priv, MT7530_MHWTRAP, val); -+ mt7530_write(priv, MT753X_MTRAP, val); - - dev_dbg(ds->dev, "Setup P5, HWTRAP=0x%x, mode=%s, phy-mode=%s\n", val, - mt7530_p5_mode_str(priv->p5_mode), phy_modes(interface)); -@@ -2356,7 +2357,7 @@ mt7530_setup(struct dsa_switch *ds) - } - - /* Waiting for MT7530 got to stable */ -- INIT_MT7530_DUMMY_POLL(&p, priv, MT7530_HWTRAP); -+ INIT_MT7530_DUMMY_POLL(&p, priv, MT753X_TRAP); - ret = readx_poll_timeout(_mt7530_read, &p, val, val != 0, - 20, 1000000); - if (ret < 0) { -@@ -2371,7 +2372,7 @@ mt7530_setup(struct dsa_switch *ds) - return -ENODEV; - } - -- if ((val & HWTRAP_XTAL_MASK) == HWTRAP_XTAL_20MHZ) { -+ if ((val & MT7530_XTAL_MASK) == MT7530_XTAL_20MHZ) { - dev_err(priv->dev, - "MT7530 with a 20MHz XTAL is not supported!\n"); - return -EINVAL; -@@ -2392,12 +2393,12 @@ mt7530_setup(struct dsa_switch *ds) - RD_TAP_MASK, RD_TAP(16)); - - /* Enable port 6 */ -- val = mt7530_read(priv, MT7530_MHWTRAP); -- val &= ~MHWTRAP_P6_DIS & ~MHWTRAP_PHY_ACCESS; -- val |= MHWTRAP_MANUAL; -- mt7530_write(priv, MT7530_MHWTRAP, val); -+ val = mt7530_read(priv, MT753X_MTRAP); -+ val &= ~MT7530_P6_DIS & ~MT7530_PHY_INDIRECT_ACCESS; -+ val |= MT7530_CHG_TRAP; -+ mt7530_write(priv, MT753X_MTRAP, val); - -- if ((val & HWTRAP_XTAL_MASK) == HWTRAP_XTAL_40MHZ) -+ if ((val & MT7530_XTAL_MASK) == MT7530_XTAL_40MHZ) - mt7530_pll_setup(priv); - - mt753x_trap_frames(priv); -@@ -2577,7 +2578,7 @@ mt7531_setup(struct dsa_switch *ds) - } - - /* Waiting for MT7530 got to stable */ -- INIT_MT7530_DUMMY_POLL(&p, priv, MT7530_HWTRAP); -+ INIT_MT7530_DUMMY_POLL(&p, priv, MT753X_TRAP); - ret = readx_poll_timeout(_mt7530_read, &p, val, val != 0, - 20, 1000000); - if (ret < 0) { ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -495,32 +495,30 @@ enum mt7531_clk_skew { - MT7531_CLK_SKEW_REVERSE = 3, - }; - --/* Register for hw trap status */ --#define MT7530_HWTRAP 0x7800 --#define HWTRAP_XTAL_MASK (BIT(10) | BIT(9)) --#define HWTRAP_XTAL_25MHZ (BIT(10) | BIT(9)) --#define HWTRAP_XTAL_40MHZ (BIT(10)) --#define HWTRAP_XTAL_20MHZ (BIT(9)) -+/* Register for trap status */ -+#define MT753X_TRAP 0x7800 -+#define MT7530_XTAL_MASK (BIT(10) | BIT(9)) -+#define MT7530_XTAL_25MHZ (BIT(10) | BIT(9)) -+#define MT7530_XTAL_40MHZ BIT(10) -+#define MT7530_XTAL_20MHZ BIT(9) -+#define MT7531_XTAL25 BIT(7) - --#define MT7531_HWTRAP 0x7800 --#define HWTRAP_XTAL_FSEL_MASK BIT(7) --#define HWTRAP_XTAL_FSEL_25MHZ BIT(7) --#define HWTRAP_XTAL_FSEL_40MHZ 0 --/* Unique fields of (M)HWSTRAP for MT7531 */ --#define XTAL_FSEL_S 7 --#define XTAL_FSEL_M BIT(7) --#define PHY_EN BIT(6) --#define CHG_STRAP BIT(8) -+/* Register for trap modification */ -+#define MT753X_MTRAP 0x7804 -+#define MT7530_P5_PHY0_SEL BIT(20) -+#define MT7530_CHG_TRAP BIT(16) -+#define MT7530_P5_MAC_SEL BIT(13) -+#define MT7530_P6_DIS BIT(8) -+#define MT7530_P5_RGMII_MODE BIT(7) -+#define MT7530_P5_DIS BIT(6) -+#define MT7530_PHY_INDIRECT_ACCESS BIT(5) -+#define MT7531_CHG_STRAP BIT(8) -+#define MT7531_PHY_EN BIT(6) - --/* Register for hw trap modification */ --#define MT7530_MHWTRAP 0x7804 --#define MHWTRAP_PHY0_SEL BIT(20) --#define MHWTRAP_MANUAL BIT(16) --#define MHWTRAP_P5_MAC_SEL BIT(13) --#define MHWTRAP_P6_DIS BIT(8) --#define MHWTRAP_P5_RGMII_MODE BIT(7) --#define MHWTRAP_P5_DIS BIT(6) --#define MHWTRAP_PHY_ACCESS BIT(5) -+enum mt7531_xtal_fsel { -+ MT7531_XTAL_FSEL_25MHZ, -+ MT7531_XTAL_FSEL_40MHZ, -+}; - - /* Register for TOP signal control */ - #define MT7530_TOP_SIG_CTRL 0x7808 diff --git a/target/linux/generic/pending-6.1/795-07-net-dsa-mt7530-move-MT753X_MTRAP-operations-for-MT75.patch b/target/linux/generic/pending-6.1/795-07-net-dsa-mt7530-move-MT753X_MTRAP-operations-for-MT75.patch deleted file mode 100644 index e7da939588..0000000000 --- a/target/linux/generic/pending-6.1/795-07-net-dsa-mt7530-move-MT753X_MTRAP-operations-for-MT75.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 2982f395c9a513b168f1e685588f70013cba2f5f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com> -Date: Mon, 22 Apr 2024 10:15:14 +0300 -Subject: [PATCH 07/15] net: dsa: mt7530: move MT753X_MTRAP operations for - MT7530 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -On MT7530, the media-independent interfaces of port 5 and 6 are controlled -by the MT7530_P5_DIS and MT7530_P6_DIS bits of the hardware trap. Deal with -these bits only when the relevant port is being enabled or disabled. This -ensures that these ports will be disabled when they are not in use. - -Do not set MT7530_CHG_TRAP on mt7530_setup_port5() as that's already being -done on mt7530_setup(). - -Instead of globally setting MT7530_P5_MAC_SEL, clear it, then set it only -on the appropriate case. - -If PHY muxing is detected, clear MT7530_P5_DIS before calling -mt7530_setup_port5(). - -Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com> ---- - drivers/net/dsa/mt7530.c | 38 +++++++++++++++++++++++++++----------- - 1 file changed, 27 insertions(+), 11 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -873,8 +873,7 @@ static void mt7530_setup_port5(struct ds - - val = mt7530_read(priv, MT753X_MTRAP); - -- val |= MT7530_CHG_TRAP | MT7530_P5_MAC_SEL | MT7530_P5_DIS; -- val &= ~MT7530_P5_RGMII_MODE & ~MT7530_P5_PHY0_SEL; -+ val &= ~MT7530_P5_PHY0_SEL & ~MT7530_P5_MAC_SEL & ~MT7530_P5_RGMII_MODE; - - switch (priv->p5_mode) { - /* MUX_PHY_P0: P0 -> P5 -> SoC MAC */ -@@ -884,15 +883,13 @@ static void mt7530_setup_port5(struct ds - - /* MUX_PHY_P4: P4 -> P5 -> SoC MAC */ - case MUX_PHY_P4: -- val &= ~MT7530_P5_MAC_SEL & ~MT7530_P5_DIS; -- - /* Setup the MAC by default for the cpu port */ - mt7530_write(priv, MT753X_PMCR_P(5), 0x56300); - break; - - /* GMAC5: P5 -> SoC MAC or external PHY */ - default: -- val &= ~MT7530_P5_DIS; -+ val |= MT7530_P5_MAC_SEL; - break; - } - -@@ -1186,6 +1183,14 @@ mt7530_port_enable(struct dsa_switch *ds - - mutex_unlock(&priv->reg_mutex); - -+ if (priv->id != ID_MT7530 && priv->id != ID_MT7621) -+ return 0; -+ -+ if (port == 5) -+ mt7530_clear(priv, MT753X_MTRAP, MT7530_P5_DIS); -+ else if (port == 6) -+ mt7530_clear(priv, MT753X_MTRAP, MT7530_P6_DIS); -+ - return 0; - } - -@@ -1204,6 +1209,14 @@ mt7530_port_disable(struct dsa_switch *d - PCR_MATRIX_CLR); - - mutex_unlock(&priv->reg_mutex); -+ -+ if (priv->id != ID_MT7530 && priv->id != ID_MT7621) -+ return; -+ -+ if (port == 5) -+ mt7530_set(priv, MT753X_MTRAP, MT7530_P5_DIS); -+ else if (port == 6) -+ mt7530_set(priv, MT753X_MTRAP, MT7530_P6_DIS); - } - - static int -@@ -2392,11 +2405,11 @@ mt7530_setup(struct dsa_switch *ds) - mt7530_rmw(priv, MT7530_TRGMII_RD(i), - RD_TAP_MASK, RD_TAP(16)); - -- /* Enable port 6 */ -- val = mt7530_read(priv, MT753X_MTRAP); -- val &= ~MT7530_P6_DIS & ~MT7530_PHY_INDIRECT_ACCESS; -- val |= MT7530_CHG_TRAP; -- mt7530_write(priv, MT753X_MTRAP, val); -+ /* Allow modifying the trap and directly access PHY registers via the -+ * MDIO bus the switch is on. -+ */ -+ mt7530_rmw(priv, MT753X_MTRAP, MT7530_CHG_TRAP | -+ MT7530_PHY_INDIRECT_ACCESS, MT7530_CHG_TRAP); - - if ((val & MT7530_XTAL_MASK) == MT7530_XTAL_40MHZ) - mt7530_pll_setup(priv); -@@ -2479,8 +2492,11 @@ mt7530_setup(struct dsa_switch *ds) - break; - } - -- if (priv->p5_mode == MUX_PHY_P0 || priv->p5_mode == MUX_PHY_P4) -+ if (priv->p5_mode == MUX_PHY_P0 || -+ priv->p5_mode == MUX_PHY_P4) { -+ mt7530_clear(priv, MT753X_MTRAP, MT7530_P5_DIS); - mt7530_setup_port5(ds, interface); -+ } - } - - #ifdef CONFIG_GPIOLIB diff --git a/target/linux/generic/pending-6.1/795-08-net-dsa-mt7530-return-mt7530_setup_mdio-mt7531_setup.patch b/target/linux/generic/pending-6.1/795-08-net-dsa-mt7530-return-mt7530_setup_mdio-mt7531_setup.patch deleted file mode 100644 index 7cc145327c..0000000000 --- a/target/linux/generic/pending-6.1/795-08-net-dsa-mt7530-return-mt7530_setup_mdio-mt7531_setup.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 1f5669efca65564c7533704917f79003c6b36c9c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com> -Date: Mon, 22 Apr 2024 10:15:15 +0300 -Subject: [PATCH 08/15] net: dsa: mt7530: return mt7530_setup_mdio & - mt7531_setup_common on error -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The mt7530_setup_mdio() and mt7531_setup_common() functions should be -checked for errors. Return if the functions return a non-zero value. - -Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com> ---- - drivers/net/dsa/mt7530.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2658,7 +2658,9 @@ mt7531_setup(struct dsa_switch *ds) - 0); - } - -- mt7531_setup_common(ds); -+ ret = mt7531_setup_common(ds); -+ if (ret) -+ return ret; - - /* Setup VLAN ID 0 for VLAN-unaware bridges */ - ret = mt7530_setup_vlan0(priv); -@@ -3017,6 +3019,8 @@ mt753x_setup(struct dsa_switch *ds) - ret = mt7530_setup_mdio(priv); - if (ret && priv->irq) - mt7530_free_irq_common(priv); -+ if (ret) -+ return ret; - - /* Initialise the PCS devices */ - for (i = 0; i < priv->ds->num_ports; i++) { diff --git a/target/linux/generic/pending-6.1/795-09-net-dsa-mt7530-define-MAC-speed-capabilities-per-swi.patch b/target/linux/generic/pending-6.1/795-09-net-dsa-mt7530-define-MAC-speed-capabilities-per-swi.patch deleted file mode 100644 index f4d19db274..0000000000 --- a/target/linux/generic/pending-6.1/795-09-net-dsa-mt7530-define-MAC-speed-capabilities-per-swi.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 6cc2d4ccd77509df74b7b8ef46bbc6ba0a571318 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com> -Date: Mon, 22 Apr 2024 10:15:16 +0300 -Subject: [PATCH 09/15] net: dsa: mt7530: define MAC speed capabilities per - switch model -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -With the support of the MT7988 SoC switch, the MAC speed capabilities -defined on mt753x_phylink_get_caps() won't apply to all switch models -anymore. Move them to more appropriate locations instead of overwriting -config->mac_capabilities. - -Remove the comment on mt753x_phylink_get_caps() as it's become invalid with -the support of MT7531 and MT7988 SoC switch. - -Add break to case 6 of mt7988_mac_port_get_caps() to be explicit. - -Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com> ---- - drivers/net/dsa/mt7530.c | 15 ++++++++++----- - 1 file changed, 10 insertions(+), 5 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2676,6 +2676,8 @@ mt7531_setup(struct dsa_switch *ds) - static void mt7530_mac_port_get_caps(struct dsa_switch *ds, int port, - struct phylink_config *config) - { -+ config->mac_capabilities |= MAC_10 | MAC_100 | MAC_1000FD; -+ - switch (port) { - /* Ports which are connected to switch PHYs. There is no MII pinout. */ - case 0 ... 4: -@@ -2707,6 +2709,8 @@ static void mt7531_mac_port_get_caps(str - { - struct mt7530_priv *priv = ds->priv; - -+ config->mac_capabilities |= MAC_10 | MAC_100 | MAC_1000FD; -+ - switch (port) { - /* Ports which are connected to switch PHYs. There is no MII pinout. */ - case 0 ... 4: -@@ -2746,14 +2750,17 @@ static void mt7988_mac_port_get_caps(str - case 0 ... 3: - __set_bit(PHY_INTERFACE_MODE_INTERNAL, - config->supported_interfaces); -+ -+ config->mac_capabilities |= MAC_10 | MAC_100 | MAC_1000FD; - break; - - /* Port 6 is connected to SoC's XGMII MAC. There is no MII pinout. */ - case 6: - __set_bit(PHY_INTERFACE_MODE_INTERNAL, - config->supported_interfaces); -- config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | -- MAC_10000FD; -+ -+ config->mac_capabilities |= MAC_10000FD; -+ break; - } - } - -@@ -2923,9 +2930,7 @@ static void mt753x_phylink_get_caps(stru - { - struct mt7530_priv *priv = ds->priv; - -- /* This switch only supports full-duplex at 1Gbps */ -- config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | -- MAC_10 | MAC_100 | MAC_1000FD; -+ config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE; - - /* This driver does not make use of the speed, duplex, pause or the - * advertisement in its mac_config, so it is safe to mark this driver diff --git a/target/linux/generic/pending-6.1/795-10-net-dsa-mt7530-get-rid-of-function-sanity-check.patch b/target/linux/generic/pending-6.1/795-10-net-dsa-mt7530-get-rid-of-function-sanity-check.patch deleted file mode 100644 index 5bb7756c51..0000000000 --- a/target/linux/generic/pending-6.1/795-10-net-dsa-mt7530-get-rid-of-function-sanity-check.patch +++ /dev/null @@ -1,33 +0,0 @@ -From dd0f15fc877c10567699190bce0f55e96f4ad6b5 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com> -Date: Mon, 22 Apr 2024 10:15:17 +0300 -Subject: [PATCH 10/15] net: dsa: mt7530: get rid of function sanity check -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Get rid of checking whether functions are filled properly. priv->info which -is an mt753x_info structure is filled and checked for before this check. -It's unnecessary checking whether it's filled properly. - -Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com> ---- - drivers/net/dsa/mt7530.c | 7 ------- - 1 file changed, 7 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -3220,13 +3220,6 @@ mt7530_probe_common(struct mt7530_priv * - if (!priv->info) - return -EINVAL; - -- /* Sanity check if these required device operations are filled -- * properly. -- */ -- if (!priv->info->sw_setup || !priv->info->phy_read || -- !priv->info->phy_write || !priv->info->mac_port_get_caps) -- return -EINVAL; -- - priv->id = priv->info->id; - priv->dev = dev; - priv->ds->priv = priv; diff --git a/target/linux/generic/pending-6.1/795-11-net-dsa-mt7530-refactor-MT7530_PMEEECR_P.patch b/target/linux/generic/pending-6.1/795-11-net-dsa-mt7530-refactor-MT7530_PMEEECR_P.patch deleted file mode 100644 index f8147b6412..0000000000 --- a/target/linux/generic/pending-6.1/795-11-net-dsa-mt7530-refactor-MT7530_PMEEECR_P.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 2dff9759602b069f97ccc939e15a47ca051b2983 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com> -Date: Mon, 22 Apr 2024 10:15:18 +0300 -Subject: [PATCH 11/15] net: dsa: mt7530: refactor MT7530_PMEEECR_P() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The MT7530_PMEEECR_P() register is on MT7530, MT7531, and the switch on the -MT7988 SoC. Rename the definition for them to MT753X_PMEEECR_P(). Use the -FIELD_PREP and FIELD_GET macros. Rename GET_LPI_THRESH() and -SET_LPI_THRESH() to LPI_THRESH_GET() and LPI_THRESH_SET(). - -Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com> ---- - drivers/net/dsa/mt7530.c | 8 ++++---- - drivers/net/dsa/mt7530.h | 13 +++++++------ - 2 files changed, 11 insertions(+), 10 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -3048,10 +3048,10 @@ static int mt753x_get_mac_eee(struct dsa - struct ethtool_eee *e) - { - struct mt7530_priv *priv = ds->priv; -- u32 eeecr = mt7530_read(priv, MT7530_PMEEECR_P(port)); -+ u32 eeecr = mt7530_read(priv, MT753X_PMEEECR_P(port)); - - e->tx_lpi_enabled = !(eeecr & LPI_MODE_EN); -- e->tx_lpi_timer = GET_LPI_THRESH(eeecr); -+ e->tx_lpi_timer = LPI_THRESH_GET(eeecr); - - return 0; - } -@@ -3065,11 +3065,11 @@ static int mt753x_set_mac_eee(struct dsa - if (e->tx_lpi_timer > 0xFFF) - return -EINVAL; - -- set = SET_LPI_THRESH(e->tx_lpi_timer); -+ set = LPI_THRESH_SET(e->tx_lpi_timer); - if (!e->tx_lpi_enabled) - /* Force LPI Mode without a delay */ - set |= LPI_MODE_EN; -- mt7530_rmw(priv, MT7530_PMEEECR_P(port), mask, set); -+ mt7530_rmw(priv, MT753X_PMEEECR_P(port), mask, set); - - return 0; - } ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -364,13 +364,14 @@ enum mt7530_vlan_port_acc_frm { - PMCR_FORCE_SPEED_100 | \ - PMCR_FORCE_FDX | PMCR_FORCE_LNK) - --#define MT7530_PMEEECR_P(x) (0x3004 + (x) * 0x100) --#define WAKEUP_TIME_1000(x) (((x) & 0xFF) << 24) --#define WAKEUP_TIME_100(x) (((x) & 0xFF) << 16) -+#define MT753X_PMEEECR_P(x) (0x3004 + (x) * 0x100) -+#define WAKEUP_TIME_1000_MASK GENMASK(31, 24) -+#define WAKEUP_TIME_1000(x) FIELD_PREP(WAKEUP_TIME_1000_MASK, x) -+#define WAKEUP_TIME_100_MASK GENMASK(23, 16) -+#define WAKEUP_TIME_100(x) FIELD_PREP(WAKEUP_TIME_100_MASK, x) - #define LPI_THRESH_MASK GENMASK(15, 4) --#define LPI_THRESH_SHT 4 --#define SET_LPI_THRESH(x) (((x) << LPI_THRESH_SHT) & LPI_THRESH_MASK) --#define GET_LPI_THRESH(x) (((x) & LPI_THRESH_MASK) >> LPI_THRESH_SHT) -+#define LPI_THRESH_GET(x) FIELD_GET(LPI_THRESH_MASK, x) -+#define LPI_THRESH_SET(x) FIELD_PREP(LPI_THRESH_MASK, x) - #define LPI_MODE_EN BIT(0) - - #define MT7530_PMSR_P(x) (0x3008 + (x) * 0x100) diff --git a/target/linux/generic/pending-6.1/795-12-net-dsa-mt7530-get-rid-of-mac_port_validate-member-o.patch b/target/linux/generic/pending-6.1/795-12-net-dsa-mt7530-get-rid-of-mac_port_validate-member-o.patch deleted file mode 100644 index 7ce2d4c04e..0000000000 --- a/target/linux/generic/pending-6.1/795-12-net-dsa-mt7530-get-rid-of-mac_port_validate-member-o.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 21d67c2fabfe40baf33202d3287b67b6c16f8382 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com> -Date: Mon, 22 Apr 2024 10:15:19 +0300 -Subject: [PATCH 12/15] net: dsa: mt7530: get rid of mac_port_validate member - of mt753x_info -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The mac_port_validate member of the mt753x_info structure is not being -used, remove it. Improve the member description section in the process. - -Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com> ---- - drivers/net/dsa/mt7530.h | 10 +++------- - 1 file changed, 3 insertions(+), 7 deletions(-) - ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -743,13 +743,12 @@ struct mt753x_pcs { - - /* struct mt753x_info - This is the main data structure for holding the specific - * part for each supported device -+ * @id: Holding the identifier to a switch model -+ * @pcs_ops: Holding the pointer to the MAC PCS operations structure - * @sw_setup: Holding the handler to a device initialization - * @phy_read: Holding the way reading PHY port - * @phy_write: Holding the way writing PHY port -- * @phy_mode_supported: Check if the PHY type is being supported on a certain -- * port -- * @mac_port_validate: Holding the way to set addition validate type for a -- * certan MAC port -+ * @mac_port_get_caps: Holding the handler that provides MAC capabilities - * @mac_port_config: Holding the way setting up the PHY attribute to a - * certain MAC port - */ -@@ -763,9 +762,6 @@ struct mt753x_info { - int (*phy_write)(struct mt7530_priv *priv, int port, int regnum, u16 val); - void (*mac_port_get_caps)(struct dsa_switch *ds, int port, - struct phylink_config *config); -- void (*mac_port_validate)(struct dsa_switch *ds, int port, -- phy_interface_t interface, -- unsigned long *supported); - void (*mac_port_config)(struct dsa_switch *ds, int port, - unsigned int mode, - phy_interface_t interface); diff --git a/target/linux/generic/pending-6.1/795-13-net-dsa-mt7530-use-priv-ds-num_ports-instead-of-MT75.patch b/target/linux/generic/pending-6.1/795-13-net-dsa-mt7530-use-priv-ds-num_ports-instead-of-MT75.patch deleted file mode 100644 index 0037f97499..0000000000 --- a/target/linux/generic/pending-6.1/795-13-net-dsa-mt7530-use-priv-ds-num_ports-instead-of-MT75.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 6efc8ae3eb0363328f479191a0cf0dc12a16e090 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com> -Date: Mon, 22 Apr 2024 10:15:20 +0300 -Subject: [PATCH 13/15] net: dsa: mt7530: use priv->ds->num_ports instead of - MT7530_NUM_PORTS -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use priv->ds->num_ports on all for loops which configure the switch -registers. In the future, the value of MT7530_NUM_PORTS will depend on -priv->id. Therefore, this change prepares the subdriver for a simpler -implementation. - -Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com> ---- - drivers/net/dsa/mt7530.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -1404,7 +1404,7 @@ mt7530_port_set_vlan_unaware(struct dsa_ - mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK, - G0_PORT_VID_DEF); - -- for (i = 0; i < MT7530_NUM_PORTS; i++) { -+ for (i = 0; i < priv->ds->num_ports; i++) { - if (dsa_is_user_port(ds, i) && - dsa_port_is_vlan_filtering(dsa_to_port(ds, i))) { - all_user_ports_removed = false; -@@ -2419,7 +2419,7 @@ mt7530_setup(struct dsa_switch *ds) - /* Enable and reset MIB counters */ - mt7530_mib_reset(ds); - -- for (i = 0; i < MT7530_NUM_PORTS; i++) { -+ for (i = 0; i < priv->ds->num_ports; i++) { - /* Clear link settings and enable force mode to force link down - * on all ports until they're enabled later. - */ -@@ -2530,7 +2530,7 @@ mt7531_setup_common(struct dsa_switch *d - mt7530_clear(priv, MT753X_MFC, BC_FFP_MASK | UNM_FFP_MASK | - UNU_FFP_MASK); - -- for (i = 0; i < MT7530_NUM_PORTS; i++) { -+ for (i = 0; i < priv->ds->num_ports; i++) { - /* Clear link settings and enable force mode to force link down - * on all ports until they're enabled later. - */ -@@ -2617,7 +2617,7 @@ mt7531_setup(struct dsa_switch *ds) - priv->p5_sgmii = !!(val & PAD_DUAL_SGMII_EN); - - /* Force link down on all ports before internal reset */ -- for (i = 0; i < MT7530_NUM_PORTS; i++) -+ for (i = 0; i < priv->ds->num_ports; i++) - mt7530_write(priv, MT753X_PMCR_P(i), MT7531_FORCE_MODE_LNK); - - /* Reset the switch through internal reset */ diff --git a/target/linux/generic/pending-6.1/795-14-net-dsa-mt7530-do-not-pass-port-variable-to-mt7531_r.patch b/target/linux/generic/pending-6.1/795-14-net-dsa-mt7530-do-not-pass-port-variable-to-mt7531_r.patch deleted file mode 100644 index ee8e13ea70..0000000000 --- a/target/linux/generic/pending-6.1/795-14-net-dsa-mt7530-do-not-pass-port-variable-to-mt7531_r.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 4794c12e3aefe05dd0063c2b6b0101854b143bac Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com> -Date: Mon, 22 Apr 2024 10:15:21 +0300 -Subject: [PATCH 14/15] net: dsa: mt7530: do not pass port variable to - mt7531_rgmii_setup() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The mt7531_rgmii_setup() function does not use the port variable, do not -pass the variable to it. - -Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com> ---- - drivers/net/dsa/mt7530.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2776,7 +2776,7 @@ mt7530_mac_config(struct dsa_switch *ds, - mt7530_setup_port6(priv->ds, interface); - } - --static void mt7531_rgmii_setup(struct mt7530_priv *priv, u32 port, -+static void mt7531_rgmii_setup(struct mt7530_priv *priv, - phy_interface_t interface, - struct phy_device *phydev) - { -@@ -2827,7 +2827,7 @@ mt7531_mac_config(struct dsa_switch *ds, - if (phy_interface_mode_is_rgmii(interface)) { - dp = dsa_to_port(ds, port); - phydev = dp->slave->phydev; -- mt7531_rgmii_setup(priv, port, interface, phydev); -+ mt7531_rgmii_setup(priv, interface, phydev); - } - } - diff --git a/target/linux/generic/pending-6.1/795-15-net-dsa-mt7530-explain-exposing-MDIO-bus-of-MT7531AE.patch b/target/linux/generic/pending-6.1/795-15-net-dsa-mt7530-explain-exposing-MDIO-bus-of-MT7531AE.patch deleted file mode 100644 index 666bcb75e8..0000000000 --- a/target/linux/generic/pending-6.1/795-15-net-dsa-mt7530-explain-exposing-MDIO-bus-of-MT7531AE.patch +++ /dev/null @@ -1,33 +0,0 @@ -From c45832fe783f468aaaace09ae95a30cbf0acf724 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com> -Date: Mon, 22 Apr 2024 10:15:22 +0300 -Subject: [PATCH 15/15] net: dsa: mt7530: explain exposing MDIO bus of MT7531AE - better -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Unlike MT7531BE, the GPIO 6-12 pins are not used for RGMII on MT7531AE. -Therefore, the GPIO 11-12 pins are set to function as MDC and MDIO to -expose the MDIO bus of the switch. Replace the comment with a better -explanation. - -Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com> ---- - drivers/net/dsa/mt7530.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2626,7 +2626,10 @@ mt7531_setup(struct dsa_switch *ds) - if (!priv->p5_sgmii) { - mt7531_pll_setup(priv); - } else { -- /* Let ds->slave_mii_bus be able to access external phy. */ -+ /* Unlike MT7531BE, the GPIO 6-12 pins are not used for RGMII on -+ * MT7531AE. Set the GPIO 11-12 pins to function as MDC and MDIO -+ * to expose the MDIO bus of the switch. -+ */ - mt7530_rmw(priv, MT7531_GPIO_MODE1, MT7531_GPIO11_RG_RXD2_MASK, - MT7531_EXT_P_MDC_11); - mt7530_rmw(priv, MT7531_GPIO_MODE1, MT7531_GPIO12_RG_RXD3_MASK, 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 98ea4c06d9..fcb77e5174 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 <nbd@nbd.name> 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 <nbd@nbd.name> /* * 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 <nbd@nbd.name> 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 <nbd@nbd.name> #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/920-mangle_bootargs.patch b/target/linux/generic/pending-6.1/920-mangle_bootargs.patch index 76e3f2544d..ca36d0ccab 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 <kaloz@openwrt.org> /* * 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); |