Re: [EXT] Re: [PATCH v3] aquantia: Remove the build_skb path
On 20/11/2020 1:49 am, Maciej Fijalkowski wrote: > External Email > > -- > On Thu, Nov 19, 2020 at 10:34:48PM +, Ramsay, Lincoln wrote: >> When performing IPv6 forwarding, there is an expectation that SKBs >> will have some headroom. When forwarding a packet from the aquantia >> driver, this does not always happen, triggering a kernel warning. >> >> The build_skb path fails to allow for an SKB header, but the hardware >> buffer it is built around won't allow for this anyway. Just always use > the >> slower codepath that copies memory into an allocated SKB. >> >> Signed-off-by: Lincoln Ramsay >> --- > > (Next time please include in the subject the tree that you're targetting > the patch) > > I feel like it's only a workaround, not a real solution. On previous > thread Igor says: > > "The limitation here is we can't tell HW on granularity less than 1K." > > Are you saying that the minimum headroom that we could provide is 1k? We can tell HW to place packets with 4 bytes granularity addresses, but the problem is the length granularity of this buffer - 1K. This means we can do as Ramsay initially suggested - just offset the packet placement. But then we have to guarantee that 1K after this offset is available to HW. Since normal layout is 1400 packets - we do use 2K (half page) for each packet. This way we reuse each allocated page for at least two packets (and putting skb_shared into the remaining 512b). Obviously we may allocate 4K page for a single packet, and tell HW that it can use 3K for data. This'll give 1K headroom. Quite an overload - assuming IMIX is of 0.5K - 1.4K.. Of course that depends on a usecase. If you know all your traffic is 16K jumbos - putting 1K headroom is very small overhead on memory usage. > Maybe put more pressure on memory side and pull in order-1 pages, provide > this big headroom and tailroom for skb_shared_info and use build_skb by > default? With standard 1500 byte MTU. I know many customers do consider AQC chips in near embedded environments (routers, etc). They really do care about memories. So that could be risky. > This issue would pop up again if this driver would like to support XDP > where 256 byte headroom will have to be provided. Actually it already popped. Thats one of the reasons I'm delaying with xdp patch series for this driver. I think the best tradeoff here would be allocating order 1 or 2 pages (i.e. 8K or 16K), and reuse the page for multiple placements of 2K XDP packets: (256+2048)*3 = 6912 (1K overhead for each 3 packets) (256+2048)*7 = 16128 (200b overhead over 7 packets) Regards, Igor
[PATCH net v2] ipvs: fix possible memory leak in ip_vs_control_net_init
kmemleak report a memory leak as follows: BUG: memory leak unreferenced object 0x8880759ea000 (size 256): comm "syz-executor.3", pid 6484, jiffies 4297476946 (age 48.546s) hex dump (first 32 bytes): 00 00 00 00 01 00 00 00 08 a0 9e 75 80 88 ff ff ...u 08 a0 9e 75 80 88 ff ff 00 00 00 00 ad 4e ad de ...u.N.. backtrace: [] kmem_cache_zalloc include/linux/slab.h:656 [inline] [ ] __proc_create+0x23d/0x7d0 fs/proc/generic.c:421 [<9d718d02>] proc_create_reg+0x8e/0x140 fs/proc/generic.c:535 [<97bbfc4f>] proc_create_net_data+0x8c/0x1b0 fs/proc/proc_net.c:126 [<652480fc>] ip_vs_control_net_init+0x308/0x13a0 net/netfilter/ipvs/ip_vs_ctl.c:4169 [<4c927ebe>] __ip_vs_init+0x211/0x400 net/netfilter/ipvs/ip_vs_core.c:2429 [ ] ops_init+0xa8/0x3c0 net/core/net_namespace.c:151 [<153fd114>] setup_net+0x2de/0x7e0 net/core/net_namespace.c:341 [ ] copy_net_ns+0x27d/0x530 net/core/net_namespace.c:482 [ ] create_new_namespaces+0x382/0xa30 kernel/nsproxy.c:110 [<098a5757>] copy_namespaces+0x2e6/0x3b0 kernel/nsproxy.c:179 [<26ce39e9>] copy_process+0x220a/0x5f00 kernel/fork.c:2072 [ ] _do_fork+0xc7/0xda0 kernel/fork.c:2428 [<2974ee96>] __do_sys_clone3+0x18a/0x280 kernel/fork.c:2703 [<62ac0a4d>] do_syscall_64+0x33/0x40 arch/x86/entry/common.c:46 [<93f1ce2c>] entry_SYSCALL_64_after_hwframe+0x44/0xa9 In the error path of ip_vs_control_net_init(), remove_proc_entry() needs to be called to remove the added proc entry, otherwise a memory leak will occur. Also, add some '#ifdef CONFIG_PROC_FS' because proc_create_net* return NULL when PROC is not used. Fixes: b17fc9963f83 ("IPVS: netns, ip_vs_stats and its procfs") Fixes: 61b1ab4583e2 ("IPVS: netns, add basic init per netns.") Reported-by: Hulk Robot Signed-off-by: Wang Hai --- v1->v2: add some '#ifdef CONFIG_PROC_FS' and check the return value of proc_create_net* net/netfilter/ipvs/ip_vs_ctl.c | 27 +-- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index e279ded4e306..c00394ba20db 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -4167,12 +4167,17 @@ int __net_init ip_vs_control_net_init(struct netns_ipvs *ipvs) spin_lock_init(&ipvs->tot_stats.lock); - proc_create_net("ip_vs", 0, ipvs->net->proc_net, &ip_vs_info_seq_ops, - sizeof(struct ip_vs_iter)); - proc_create_net_single("ip_vs_stats", 0, ipvs->net->proc_net, - ip_vs_stats_show, NULL); - proc_create_net_single("ip_vs_stats_percpu", 0, ipvs->net->proc_net, - ip_vs_stats_percpu_show, NULL); +#ifdef CONFIG_PROC_FS + if (!proc_create_net("ip_vs", 0, ipvs->net->proc_net, &ip_vs_info_seq_ops, + sizeof(struct ip_vs_iter))) + goto err_vs; + if (!proc_create_net_single("ip_vs_stats", 0, ipvs->net->proc_net, + ip_vs_stats_show, NULL)) + goto err_stats; + if (!proc_create_net_single("ip_vs_stats_percpu", 0, ipvs->net->proc_net, + ip_vs_stats_percpu_show, NULL)) + goto err_percpu; +#endif if (ip_vs_control_net_init_sysctl(ipvs)) goto err; @@ -4180,6 +4185,14 @@ int __net_init ip_vs_control_net_init(struct netns_ipvs *ipvs) return 0; err: +#ifdef CONFIG_PROC_FS + remove_proc_entry("ip_vs_stats_percpu", ipvs->net->proc_net); +err_percpu: + remove_proc_entry("ip_vs_stats", ipvs->net->proc_net); +err_stats: + remove_proc_entry("ip_vs", ipvs->net->proc_net); +err_vs: +#endif free_percpu(ipvs->tot_stats.cpustats); return -ENOMEM; } @@ -4188,9 +4201,11 @@ void __net_exit ip_vs_control_net_cleanup(struct netns_ipvs *ipvs) { ip_vs_trash_cleanup(ipvs); ip_vs_control_net_cleanup_sysctl(ipvs); +#ifdef CONFIG_PROC_FS remove_proc_entry("ip_vs_stats_percpu", ipvs->net->proc_net); remove_proc_entry("ip_vs_stats", ipvs->net->proc_net); remove_proc_entry("ip_vs", ipvs->net->proc_net); +#endif free_percpu(ipvs->tot_stats.cpustats); } -- 2.17.1
Re: [PATCH bpf-next V6 2/7] bpf: fix bpf_fib_lookup helper MTU check for SKB ctx
On Wed, 18 Nov 2020 16:29:35 +0100 Jesper Dangaard Brouer wrote: > BPF end-user on Cilium slack-channel (Carlo Carraro) wants to use > bpf_fib_lookup for doing MTU-check, but *prior* to extending packet size, > by adjusting fib_params 'tot_len' with the packet length plus the > expected encap size. (Just like the bpf_check_mtu helper supports). He > discovered that for SKB ctx the param->tot_len was not used, instead > skb->len was used (via MTU check in is_skb_forwardable()). > > Fix this by using fib_params 'tot_len' for MTU check. If not provided > (e.g. zero) then keep existing behaviour intact. Carlo pointed out (in slack) that the logic is not correctly implemented in this patch. I will send a V7. > Fixes: 4c79579b44b1 ("bpf: Change bpf_fib_lookup to return lookup status") > Reported-by: Carlo Carraro > Signed-off-by: Jesper Dangaard Brouer > --- > net/core/filter.c | 12 +++- > 1 file changed, 11 insertions(+), 1 deletion(-) > > diff --git a/net/core/filter.c b/net/core/filter.c > index 1ee97fdeea64..ae1fe8e6069a 100644 > --- a/net/core/filter.c > +++ b/net/core/filter.c > @@ -5567,10 +5567,20 @@ BPF_CALL_4(bpf_skb_fib_lookup, struct sk_buff *, skb, > > if (!rc) { > struct net_device *dev; > + u32 mtu; > > dev = dev_get_by_index_rcu(net, params->ifindex); > - if (!is_skb_forwardable(dev, skb)) > + mtu = dev->mtu; > + > + /* Using tot_len for L3 MTU check if provided by user. Notice at > + * this TC cls_bpf level skb->len contains L2 size, but > + * is_skb_forwardable takes that into account. > + */ > + if (params->tot_len > mtu) { > rc = BPF_FIB_LKUP_RET_FRAG_NEEDED; > + } else if (!is_skb_forwardable(dev, skb)) { > + rc = BPF_FIB_LKUP_RET_FRAG_NEEDED; > + } > } > > return rc; -- Best regards, Jesper Dangaard Brouer MSc.CS, Principal Kernel Engineer at Red Hat LinkedIn: http://www.linkedin.com/in/brouer
Re: [PATCH net] ipvs: fix possible memory leak in ip_vs_control_net_init
在 2020/11/20 2:22, Julian Anastasov 写道: Hello, On Thu, 19 Nov 2020, Wang Hai wrote: kmemleak report a memory leak as follows: BUG: memory leak unreferenced object 0x8880759ea000 (size 256): comm "syz-executor.3", pid 6484, jiffies 4297476946 (age 48.546s) hex dump (first 32 bytes): 00 00 00 00 01 00 00 00 08 a0 9e 75 80 88 ff ff ...u [...] Reported-by: Hulk Robot Signed-off-by: Wang Hai --- net/netfilter/ipvs/ip_vs_ctl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index e279ded4e306..d99bb89e7c25 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -4180,6 +4180,9 @@ int __net_init ip_vs_control_net_init(struct netns_ipvs *ipvs) return 0; May be we should add some #ifdef CONFIG_PROC_FS because proc_create_net* return NULL when PROC is not used. For example: #ifdef CONFIG_PROC_FS if (!proc_create_net... goto err_vs; if (!proc_create_net... goto err_stats; ... #endif ... err: #ifdef CONFIG_PROC_FS + remove_proc_entry("ip_vs_stats_percpu", ipvs->net->proc_net); err_percpu: + remove_proc_entry("ip_vs_stats", ipvs->net->proc_net); err_stats: + remove_proc_entry("ip_vs", ipvs->net->proc_net); err_vs: #endif free_percpu(ipvs->tot_stats.cpustats); return -ENOMEM; } -- Regards -- Julian Anastasov . Thanks for your advice, I just sent v2 “[PATCH net v2] ipvs: fix possible memory leak in ip_vs_control_net_init”
[PATCH net-next v3 0/3] net: ptp: introduce common defines for PTP message types
This series introduces commen defines for PTP event messages. Driver internal defines are removed and some uses of magic numbers are replaced by the new defines. Changes v2 --> v3 -- - extend commit description for ptp_ines (Jacob Keller) Changes v1 --> v2 -- - use defines instead of an enum (Richard Cochran) - no changes necessary for dp63640 - add cover message (Vladimir Oltean)
[PATCH net-next v3 1/3] net: ptp: introduce common defines for PTP message types
Using PTP wide defines will obsolete different driver internal defines and uses of magic numbers. Signed-off-by: Christian Eggers Cc: Kurt Kanzenbach --- include/linux/ptp_classify.h | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/linux/ptp_classify.h b/include/linux/ptp_classify.h index 56b2d7d66177..cc0da0b134a4 100644 --- a/include/linux/ptp_classify.h +++ b/include/linux/ptp_classify.h @@ -31,6 +31,11 @@ #define PTP_CLASS_V2_VLAN (PTP_CLASS_V2 | PTP_CLASS_VLAN) #define PTP_CLASS_L4 (PTP_CLASS_IPV4 | PTP_CLASS_IPV6) +#define PTP_MSGTYPE_SYNC0x0 +#define PTP_MSGTYPE_DELAY_REQ 0x1 +#define PTP_MSGTYPE_PDELAY_REQ 0x2 +#define PTP_MSGTYPE_PDELAY_RESP 0x3 + #define PTP_EV_PORT 319 #define PTP_GEN_BIT 0x08 /* indicates general message, if set in message type */ @@ -138,7 +143,7 @@ static inline u8 ptp_get_msgtype(const struct ptp_header *hdr, /* The return is meaningless. The stub function would not be * executed since no available header from ptp_parse_header. */ - return 0; + return PTP_MSGTYPE_SYNC; } #endif #endif /* _PTP_CLASSIFY_H_ */ -- Christian Eggers Embedded software developer Arnold & Richter Cine Technik GmbH & Co. Betriebs KG Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRA 57918 Persoenlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRB 54477 Geschaeftsfuehrer: Dr. Michael Neuhaeuser; Stephan Schenk; Walter Trauninger; Markus Zeiler
[PATCH net-next v3 2/3] dpaa2-eth: use new PTP_MSGTYPE_* define(s)
Remove usage of magic numbers. Signed-off-by: Christian Eggers Cc: Ioana Ciornei Cc: Ioana Radulescu Cc: Yangbo Lu --- drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c index cf9400a9886d..a0a30c721fe7 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c @@ -686,7 +686,7 @@ static void dpaa2_eth_enable_tx_tstamp(struct dpaa2_eth_priv *priv, if (skb->cb[0] == TX_TSTAMP_ONESTEP_SYNC) { if (dpaa2_eth_ptp_parse(skb, &msgtype, &twostep, &udp, &offset1, &offset2) || - msgtype != 0 || twostep) { + msgtype != PTP_MSGTYPE_SYNC || twostep) { WARN_ONCE(1, "Bad packet for one-step timestamping\n"); return; } @@ -1212,7 +1212,7 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct net_device *net_dev) if (skb->cb[0] == TX_TSTAMP_ONESTEP_SYNC) { if (!dpaa2_eth_ptp_parse(skb, &msgtype, &twostep, &udp, &offset1, &offset2)) - if (msgtype == 0 && twostep == 0) { + if (msgtype == PTP_MSGTYPE_SYNC && twostep == 0) { skb_queue_tail(&priv->tx_skbs, skb); queue_work(priv->dpaa2_ptp_wq, &priv->tx_onestep_tstamp); -- Christian Eggers Embedded software developer Arnold & Richter Cine Technik GmbH & Co. Betriebs KG Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRA 57918 Persoenlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRB 54477 Geschaeftsfuehrer: Dr. Michael Neuhaeuser; Stephan Schenk; Walter Trauninger; Markus Zeiler
[PATCH net-next v3 3/3] ptp: ptp_ines: use new PTP_MSGTYPE_* define(s)
Remove driver internal defines for this. Masking msgtype with 0xf is already done within ptp_get_msgtype(). Signed-off-by: Christian Eggers Cc: Richard Cochran Cc: Kurt Kanzenbach --- drivers/ptp/ptp_ines.c | 19 +++ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/drivers/ptp/ptp_ines.c b/drivers/ptp/ptp_ines.c index 4700ffbdfced..6c7c2843ba0b 100644 --- a/drivers/ptp/ptp_ines.c +++ b/drivers/ptp/ptp_ines.c @@ -108,11 +108,6 @@ MODULE_LICENSE("GPL"); #define MESSAGE_TYPE_P_DELAY_RESP 3 #define MESSAGE_TYPE_DELAY_REQ 4 -#define SYNC 0x0 -#define DELAY_REQ 0x1 -#define PDELAY_REQ 0x2 -#define PDELAY_RESP0x3 - static LIST_HEAD(ines_clocks); static DEFINE_MUTEX(ines_clocks_lock); @@ -683,9 +678,9 @@ static bool is_sync_pdelay_resp(struct sk_buff *skb, int type) msgtype = ptp_get_msgtype(hdr, type); - switch ((msgtype & 0xf)) { - case SYNC: - case PDELAY_RESP: + switch (msgtype) { + case PTP_MSGTYPE_SYNC: + case PTP_MSGTYPE_PDELAY_RESP: return true; default: return false; @@ -696,13 +691,13 @@ static u8 tag_to_msgtype(u8 tag) { switch (tag) { case MESSAGE_TYPE_SYNC: - return SYNC; + return PTP_MSGTYPE_SYNC; case MESSAGE_TYPE_P_DELAY_REQ: - return PDELAY_REQ; + return PTP_MSGTYPE_PDELAY_REQ; case MESSAGE_TYPE_P_DELAY_RESP: - return PDELAY_RESP; + return PTP_MSGTYPE_PDELAY_RESP; case MESSAGE_TYPE_DELAY_REQ: - return DELAY_REQ; + return PTP_MSGTYPE_DELAY_REQ; } return 0xf; } -- Christian Eggers Embedded software developer Arnold & Richter Cine Technik GmbH & Co. Betriebs KG Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRA 57918 Persoenlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRB 54477 Geschaeftsfuehrer: Dr. Michael Neuhaeuser; Stephan Schenk; Walter Trauninger; Markus Zeiler
Re: [PATCH net-next] MAINTAINERS: Update XDP and AF_XDP entries
On Thu, 19 Nov 2020 14:16:20 -0800 Joe Perches wrote: > On Thu, 2020-11-19 at 21:50 +0100, Jesper Dangaard Brouer wrote: > > On Thu, 19 Nov 2020 10:02:10 -0800 > > Jakub Kicinski wrote: > > > > > On Thu, 19 Nov 2020 18:26:40 +0100 Jesper Dangaard Brouer wrote: > > > > Getting too many false positive matches with current use > > > > of the content regex K: and file regex N: patterns. > > > > > > > > This patch drops file match N: and makes K: more restricted. > > > > Some more normal F: file wildcards are added. > > > > > > > > Notice that AF_XDP forgot to some F: files that is also > > > > updated in this patch. > > > > > > > > Suggested-by: Jakub Kicinski > > > > Signed-off-by: Jesper Dangaard Brouer > > > > > > Ah! Sorry, I missed that you sent this before replying to Joe. > > > > > > Would you mind respining with his regex? > > > > Sure, I just send it... with your adjusted '(\b|_)xdp(\b|_)' regex, as > > it seems to do the same thing (and it works with egrep). > > The regexes in MAINTAINERS are perl not egrep and using (\b|_) > creates unnecessary capture groups. > > It _really_ should be (?:\b|_)xdp(?:\b|_) Okay, I will send a V3 patch. I was trying to write a perl oneliner to tests this, but I realized that git-grep supports this directly via --perl-regexp. $ time git grep --files-with-matches --perl-regexp '(\b|_)xdp(\b|_)' | wc -l 297 real0m2,225s user0m0,832s sys 0m2,762s $ time git grep --files-with-matches --perl-regexp '(?:\b|_)xdp(?:\b|_)' | wc -l 297 real0m2,261s user0m0,788s sys 0m2,714s -- Best regards, Jesper Dangaard Brouer MSc.CS, Principal Kernel Engineer at Red Hat LinkedIn: http://www.linkedin.com/in/brouer
[PATCH net-next V3] MAINTAINERS: Update XDP and AF_XDP entries
Getting too many false positive matches with current use of the content regex K: and file regex N: patterns. This patch drops file match N: and makes K: more restricted. Some more normal F: file wildcards are added. Notice that AF_XDP forgot to some F: files that is also updated in this patch. Suggested-by: Jakub Kicinski Signed-off-by: Jesper Dangaard Brouer --- MAINTAINERS | 12 ++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index af9f6a3ab100..f827f504251b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -19105,12 +19105,17 @@ L:netdev@vger.kernel.org L: b...@vger.kernel.org S: Supported F: include/net/xdp.h +F: include/net/xdp_priv.h F: include/trace/events/xdp.h F: kernel/bpf/cpumap.c F: kernel/bpf/devmap.c F: net/core/xdp.c -N: xdp -K: xdp +F: samples/bpf/xdp* +F: tools/testing/selftests/bpf/*xdp* +F: tools/testing/selftests/bpf/*/*xdp* +F: drivers/net/ethernet/*/*/*/*/*xdp* +F: drivers/net/ethernet/*/*/*xdp* +K: (?:\b|_)xdp(?:\b|_) XDP SOCKETS (AF_XDP) M: Björn Töpel @@ -19119,9 +19124,12 @@ R: Jonathan Lemon L: netdev@vger.kernel.org L: b...@vger.kernel.org S: Maintained +F: Documentation/networking/af_xdp.rst F: include/net/xdp_sock* F: include/net/xsk_buff_pool.h F: include/uapi/linux/if_xdp.h +F: include/uapi/linux/xdp_diag.h +F: include/net/netns/xdp.h F: net/xdp/ F: samples/bpf/xdpsock* F: tools/lib/bpf/xsk*
Kernel warning "TX on unused queue" for iwlwifi on 7260 with kernel 5.10-rc2
Output of lspci -nn: 02:00.0 Network controller [0280]: Intel Corporation Wireless 7260 [8086:08b1] (rev 73) > Guy, can you help with this one? I believe there is a bugzilla issue > for this already... I'd like to know this too. -- g
Re: net: phy: Dealing with 88e1543 dual-port mode
On Fri, Nov 20, 2020 at 01:00, Andrew Lunn wrote: >> E.g. at Westermo we make switches with M12/M12X connectors [1] that >> sometimes have a 1G PHY behind a 2-pair M12 connector (for complicated >> legacy reasons). In such cases we have to remove 1000-HD/FD from the >> advertised link modes. Being able to describe that in the DT with >> something like: >> >> ethernet-phy@0 { >> mdi = "2-pair"; >> }; > > We already have a max-speed property which could be used to do this. > It will remove the 1000-HD/FD from the link mode if you set it to 100. > >Andrew Oh wow, well strike that argument then :) Thank you
[PATCH net 4/4] s390/qeth: fix tear down of async TX buffers
When qeth_iqd_tx_complete() detects that a TX buffer requires additional async completion via QAOB, it might fail to replace the queue entry's metadata (and ends up triggering recovery). Assume now that the device gets torn down, overruling the recovery. If the QAOB notification then arrives before the tear down has sufficiently progressed, the buffer state is changed to QETH_QDIO_BUF_HANDLED_DELAYED by qeth_qdio_handle_aob(). The tear down code calls qeth_drain_output_queue(), where qeth_cleanup_handled_pending() will then attempt to replace such a buffer _again_. If it succeeds this time, the buffer ends up dangling in its replacement's ->next_pending list ... where it will never be freed, since there's no further call to qeth_cleanup_handled_pending(). But the second attempt isn't actually needed, we can simply leave the buffer on the queue and re-use it after a potential recovery has completed. The qeth_clear_output_buffer() in qeth_drain_output_queue() will ensure that it's in a clean state again. Fixes: 72861ae792c2 ("qeth: recovery through asynchronous delivery") Signed-off-by: Julian Wiedmann --- drivers/s390/net/qeth_core_main.c | 6 -- 1 file changed, 6 deletions(-) diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 48f9e4a027bf..e27319de7b00 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -500,12 +500,6 @@ static void qeth_cleanup_handled_pending(struct qeth_qdio_out_q *q, int bidx, } } - if (forced_cleanup && (atomic_read(&(q->bufs[bidx]->state)) == - QETH_QDIO_BUF_HANDLED_DELAYED)) { - /* for recovery situations */ - qeth_init_qdio_out_buf(q, bidx); - QETH_CARD_TEXT(q->card, 2, "clprecov"); - } } static void qeth_qdio_handle_aob(struct qeth_card *card, -- 2.17.1
[PATCH net 2/4] s390/qeth: make af_iucv TX notification call more robust
Calling into socket code is ugly already, at least check whether we are dealing with the expected sk_family. Only looking at skb->protocol is bound to cause troubles (consider eg. af_packet). Fixes: b333293058aa ("qeth: add support for af_iucv HiperSockets transport") Signed-off-by: Julian Wiedmann --- drivers/s390/net/qeth_core_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 93c9b30ab17a..715f440bdc7c 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -33,6 +33,7 @@ #include #include +#include #include #include @@ -1405,7 +1406,7 @@ static void qeth_notify_skbs(struct qeth_qdio_out_q *q, skb_queue_walk(&buf->skb_list, skb) { QETH_CARD_TEXT_(q->card, 5, "skbn%d", notification); QETH_CARD_TEXT_(q->card, 5, "%lx", (long) skb); - if (skb->protocol == htons(ETH_P_AF_IUCV) && skb->sk) + if (skb->sk && skb->sk->sk_family == PF_IUCV) iucv_sk(skb->sk)->sk_txnotify(skb, notification); } } -- 2.17.1
[PATCH net 1/4] s390/qeth: Remove pnso workaround
From: Alexandra Winter Remove workaround that supported early hardware implementations of PNSO OC3. Rely on the 'enarf' feature bit instead. Fixes: fa115adff2c1 ("s390/qeth: Detect PNSO OC3 capability") Signed-off-by: Alexandra Winter Reviewed-by: Julian Wiedmann [jwi: use logical instead of bit-wise AND] Signed-off-by: Julian Wiedmann --- drivers/s390/net/qeth_l2_main.c | 18 ++ 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 28f6dda95736..79939ba5d523 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -985,32 +985,19 @@ static void qeth_l2_setup_bridgeport_attrs(struct qeth_card *card) * change notification' and thus can support the learning_sync bridgeport * attribute * @card: qeth_card structure pointer - * - * This is a destructive test and must be called before dev2br or - * bridgeport address notification is enabled! */ static void qeth_l2_detect_dev2br_support(struct qeth_card *card) { struct qeth_priv *priv = netdev_priv(card->dev); bool dev2br_supported; - int rc; QETH_CARD_TEXT(card, 2, "d2brsup"); if (!IS_IQD(card)) return; /* dev2br requires valid cssid,iid,chid */ - if (!card->info.ids_valid) { - dev2br_supported = false; - } else if (css_general_characteristics.enarf) { - dev2br_supported = true; - } else { - /* Old machines don't have the feature bit: -* Probe by testing whether a disable succeeds -*/ - rc = qeth_l2_pnso(card, PNSO_OC_NET_ADDR_INFO, 0, NULL, NULL); - dev2br_supported = !rc; - } + dev2br_supported = card->info.ids_valid && + css_general_characteristics.enarf; QETH_CARD_TEXT_(card, 2, "D2Bsup%02x", dev2br_supported); if (dev2br_supported) @@ -2233,7 +2220,6 @@ static int qeth_l2_set_online(struct qeth_card *card, bool carrier_ok) struct net_device *dev = card->dev; int rc = 0; - /* query before bridgeport_notification may be enabled */ qeth_l2_detect_dev2br_support(card); mutex_lock(&card->sbp_lock); -- 2.17.1
[PATCH net 3/4] s390/qeth: fix af_iucv notification race
The two expected notification sequences are 1. TX_NOTIFY_PENDING with a subsequent TX_NOTIFY_DELAYED_*, when our TX completion code first observed the pending TX and the QAOB then completes at a later time; or 2. TX_NOTIFY_OK, when qeth_qdio_handle_aob() picked up the QAOB completion before our TX completion code even noticed that the TX was pending. But as qeth_iqd_tx_complete() and qeth_qdio_handle_aob() can run concurrently, we may end up with a race that results in a sequence of TX_NOTIFY_DELAYED_* followed by TX_NOTIFY_PENDING. Which would confuse the af_iucv code in its tracking of pending transmits. Rework the notification code, so that qeth_qdio_handle_aob() defers its notification if the TX completion code is still active. Fixes: b333293058aa ("qeth: add support for af_iucv HiperSockets transport") Signed-off-by: Julian Wiedmann --- drivers/s390/net/qeth_core.h | 9 ++-- drivers/s390/net/qeth_core_main.c | 73 ++- 2 files changed, 58 insertions(+), 24 deletions(-) diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index f73b4756ed5e..b235393e091c 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -417,10 +417,13 @@ enum qeth_qdio_out_buffer_state { QETH_QDIO_BUF_EMPTY, /* Filled by driver; owned by hardware in order to be sent. */ QETH_QDIO_BUF_PRIMED, - /* Identified to be pending in TPQ. */ + /* Discovered by the TX completion code: */ QETH_QDIO_BUF_PENDING, - /* Found in completion queue. */ - QETH_QDIO_BUF_IN_CQ, + /* Finished by the TX completion code: */ + QETH_QDIO_BUF_NEED_QAOB, + /* Received QAOB notification on CQ: */ + QETH_QDIO_BUF_QAOB_OK, + QETH_QDIO_BUF_QAOB_ERROR, /* Handled via transfer pending / completion queue. */ QETH_QDIO_BUF_HANDLED_DELAYED, }; diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 715f440bdc7c..48f9e4a027bf 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -511,6 +511,7 @@ static void qeth_cleanup_handled_pending(struct qeth_qdio_out_q *q, int bidx, static void qeth_qdio_handle_aob(struct qeth_card *card, unsigned long phys_aob_addr) { + enum qeth_qdio_out_buffer_state new_state = QETH_QDIO_BUF_QAOB_OK; struct qaob *aob; struct qeth_qdio_out_buffer *buffer; enum iucv_tx_notify notification; @@ -522,22 +523,6 @@ static void qeth_qdio_handle_aob(struct qeth_card *card, buffer = (struct qeth_qdio_out_buffer *) aob->user1; QETH_CARD_TEXT_(card, 5, "%lx", aob->user1); - if (atomic_cmpxchg(&buffer->state, QETH_QDIO_BUF_PRIMED, - QETH_QDIO_BUF_IN_CQ) == QETH_QDIO_BUF_PRIMED) { - notification = TX_NOTIFY_OK; - } else { - WARN_ON_ONCE(atomic_read(&buffer->state) != - QETH_QDIO_BUF_PENDING); - atomic_set(&buffer->state, QETH_QDIO_BUF_IN_CQ); - notification = TX_NOTIFY_DELAYED_OK; - } - - if (aob->aorc != 0) { - QETH_CARD_TEXT_(card, 2, "aorc%02X", aob->aorc); - notification = qeth_compute_cq_notification(aob->aorc, 1); - } - qeth_notify_skbs(buffer->q, buffer, notification); - /* Free dangling allocations. The attached skbs are handled by * qeth_cleanup_handled_pending(). */ @@ -549,7 +534,33 @@ static void qeth_qdio_handle_aob(struct qeth_card *card, if (data && buffer->is_header[i]) kmem_cache_free(qeth_core_header_cache, data); } - atomic_set(&buffer->state, QETH_QDIO_BUF_HANDLED_DELAYED); + + if (aob->aorc) { + QETH_CARD_TEXT_(card, 2, "aorc%02X", aob->aorc); + new_state = QETH_QDIO_BUF_QAOB_ERROR; + } + + switch (atomic_xchg(&buffer->state, new_state)) { + case QETH_QDIO_BUF_PRIMED: + /* Faster than TX completion code. */ + notification = qeth_compute_cq_notification(aob->aorc, 0); + qeth_notify_skbs(buffer->q, buffer, notification); + atomic_set(&buffer->state, QETH_QDIO_BUF_HANDLED_DELAYED); + break; + case QETH_QDIO_BUF_PENDING: + /* TX completion code is active and will handle the async +* completion for us. +*/ + break; + case QETH_QDIO_BUF_NEED_QAOB: + /* TX completion code is already finished. */ + notification = qeth_compute_cq_notification(aob->aorc, 1); + qeth_notify_skbs(buffer->q, buffer, notification); + atomic_set(&buffer->state, QETH_QDIO_BUF_HANDLED_DELAYED); + break; + default: + WARN_ON_ONCE(1); + } qdio_release_aob(a
[PATCH net 0/4] s390/qeth: fixes 2020-11-20
Hi Jakub, please apply the following patch series to netdev's net tree. This brings several fixes for qeth's af_iucv-specific code paths. Also one fix by Alexandra for the recently added BR_LEARNING_SYNC support. We want to trust the feature indication bit, so that HW can mask it out if there's any issues on their end. Thanks, Julian Alexandra Winter (1): s390/qeth: Remove pnso workaround Julian Wiedmann (3): s390/qeth: make af_iucv TX notification call more robust s390/qeth: fix af_iucv notification race s390/qeth: fix tear down of async TX buffers drivers/s390/net/qeth_core.h | 9 ++-- drivers/s390/net/qeth_core_main.c | 82 --- drivers/s390/net/qeth_l2_main.c | 18 +-- 3 files changed, 62 insertions(+), 47 deletions(-) -- 2.17.1
Re: net: phy: Dealing with 88e1543 dual-port mode
On Fri, Nov 20, 2020 at 00:40, Russell King - ARM Linux admin wrote: > I think you're advocating calling the fiber interface "SGMII", which > would be totally wrong. > > SGMII is a Cisco modification of 802.3 1000base-X to allow 10M and 100M > speeds to be used over a single serdes lane in each direction. > > 1000base-X is what you run over a fiber link. This is not SGMII. Using > "SGMII" for 1000base-X is incorrect, but a common abuse of the term in > industry. Abusing a term does not make it correct, especially when it > comes to defining further standards. > > (This is one of my pet peaves, sorry.) Nomenclature is very important, no excuse necessary. You are right that SGMII is not the term I am looking for, but I am not sure 1000base-X is either. I am looking for a word that describes the serial interface that can run in either 1000base-X or 100base-FX mode (and possibly other ancient/proprietary modes). Maybe just "serdes"?
Re: [PATCH] usbnet: ipheth: fix connectivity with iOS 14
Hello! On 19.11.2020 20:24, Yves-Alexis Perez wrote: Starting with iOS 14 released in September 2020, connectivity using the personal hotspot USB tethering function of iOS devices is broken. Communication between the host and the device (for example ICMP traffic or DNS resolution using the DNS service running in the device itself) works fine, but communication to endpoints further away doesn't work. Investigation on the matter shows that UDP and ICMP traffic from the ^ "no" missing? tethered host is reaching the Internet at all. For TCP traffic there are exchanges between tethered host and server but packets are modified in transit leading to impossible communication. After some trials Matti Vuorela discovered that reducing the URB buffer size by two bytes restored the previous behavior. While a better solution might exist to fix the issue, since the protocol is not publicly documented and considering the small size of the fix, let's do that. Tested-by: Matti Vuorela Signed-off-by: Yves-Alexis Perez Link: https://lore.kernel.org/linux-usb/caan0qaxmysj9vx3zemkviv_b19ju-_exn8yn_usefxpjs6g...@mail.gmail.com/ Link: https://github.com/libimobiledevice/libimobiledevice/issues/1038 Cc: sta...@vger.kernel.org [...] MBR, Sergei
[PATCH net-next 2/5] net: hns3: add support for mapping device memory
For device who has device memory accessed through the PCI BAR4, IO descriptor push of NIC and direct WQE(Work Queue Element) of RoCE will use this device memory, so add support for mapping this device memory, and add this info to the RoCE client whose new feature needs. Signed-off-by: Huazhong Tan --- drivers/net/ethernet/hisilicon/hns3/hnae3.h| 1 + .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 33 ++ .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h| 1 + .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 33 ++ .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h | 1 + 5 files changed, 69 insertions(+) diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index f9d4d23..5bae5e8 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -689,6 +689,7 @@ struct hnae3_knic_private_info { struct hnae3_roce_private_info { struct net_device *netdev; void __iomem *roce_io_base; + void __iomem *roce_mem_base; int base_vector; int num_vectors; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 892e7f6..9989930 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -2436,6 +2436,7 @@ static int hclge_init_roce_base_info(struct hclge_vport *vport) roce->rinfo.netdev = nic->kinfo.netdev; roce->rinfo.roce_io_base = vport->back->hw.io_base; + roce->rinfo.roce_mem_base = vport->back->hw.mem_base; roce->pdev = nic->pdev; roce->ae_algo = nic->ae_algo; @@ -9890,6 +9891,28 @@ static void hclge_uninit_client_instance(struct hnae3_client *client, } } +static int hclge_dev_mem_map(struct hclge_dev *hdev) +{ +#define HCLGE_MEM_BAR 4 + + struct pci_dev *pdev = hdev->pdev; + struct hclge_hw *hw = &hdev->hw; + + /* for device does not have device memory, return directly */ + if (!(pci_select_bars(pdev, IORESOURCE_MEM) & BIT(HCLGE_MEM_BAR))) + return 0; + + hw->mem_base = devm_ioremap_wc(&pdev->dev, + pci_resource_start(pdev, HCLGE_MEM_BAR), + pci_resource_len(pdev, HCLGE_MEM_BAR)); + if (!hw->mem_base) { + dev_err(&pdev->dev, "failed to map device memroy\n"); + return -EFAULT; + } + + return 0; +} + static int hclge_pci_init(struct hclge_dev *hdev) { struct pci_dev *pdev = hdev->pdev; @@ -9928,9 +9951,16 @@ static int hclge_pci_init(struct hclge_dev *hdev) goto err_clr_master; } + ret = hclge_dev_mem_map(hdev); + if (ret) + goto err_unmap_io_base; + hdev->num_req_vfs = pci_sriov_get_totalvfs(pdev); return 0; + +err_unmap_io_base: + pcim_iounmap(pdev, hdev->hw.io_base); err_clr_master: pci_clear_master(pdev); pci_release_regions(pdev); @@ -9944,6 +9974,9 @@ static void hclge_pci_uninit(struct hclge_dev *hdev) { struct pci_dev *pdev = hdev->pdev; + if (hdev->hw.mem_base) + devm_iounmap(&pdev->dev, hdev->hw.mem_base); + pcim_iounmap(pdev, hdev->hw.io_base); pci_free_irq_vectors(pdev); pci_clear_master(pdev); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index 64e6afd..3ed4e84 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -278,6 +278,7 @@ struct hclge_mac { struct hclge_hw { void __iomem *io_base; + void __iomem *mem_base; struct hclge_mac mac; int num_vec; struct hclge_cmq cmq; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index 5ac5c35..5d6b419 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -2442,6 +2442,7 @@ static int hclgevf_init_roce_base_info(struct hclgevf_dev *hdev) roce->rinfo.netdev = nic->kinfo.netdev; roce->rinfo.roce_io_base = hdev->hw.io_base; + roce->rinfo.roce_mem_base = hdev->hw.mem_base; roce->pdev = nic->pdev; roce->ae_algo = nic->ae_algo; @@ -2887,6 +2888,29 @@ static void hclgevf_uninit_client_instance(struct hnae3_client *client, } } +static int hclgevf_dev_mem_map(struct hclgevf_dev *hdev) +{ +#define HCLGEVF_MEM_BAR4 + + struct pci_dev *pdev = hdev->pdev; + struct hclgevf_hw *hw = &hdev->hw; + + /* for device does not have device memory, return directly */ + if (!(pci_select_bars(pdev, IORESOUR
[PATCH net-next 5/5] net: hns3: adds debugfs to dump more info of shaping parameters
From: Yonglong Liu Adds debugfs to dump new shaping parameters: rate and flag. Signed-off-by: Yonglong Liu Signed-off-by: Huazhong Tan --- .../net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c | 18 -- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c index c82d2ca..bedbc11 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c @@ -498,6 +498,9 @@ static void hclge_dbg_dump_tm_pg(struct hclge_dev *hdev) dev_info(&hdev->pdev->dev, "PG_P pg_id: %u\n", pg_shap_cfg_cmd->pg_id); dev_info(&hdev->pdev->dev, "PG_P pg_shapping: 0x%x\n", le32_to_cpu(pg_shap_cfg_cmd->pg_shapping_para)); + dev_info(&hdev->pdev->dev, "PG_P flag: %#x\n", pg_shap_cfg_cmd->flag); + dev_info(&hdev->pdev->dev, "PG_P pg_rate: %u(Mbps)\n", +le32_to_cpu(pg_shap_cfg_cmd->pg_rate)); cmd = HCLGE_OPC_TM_PORT_SHAPPING; hclge_cmd_setup_basic_desc(&desc, cmd, true); @@ -508,6 +511,9 @@ static void hclge_dbg_dump_tm_pg(struct hclge_dev *hdev) port_shap_cfg_cmd = (struct hclge_port_shapping_cmd *)desc.data; dev_info(&hdev->pdev->dev, "PORT port_shapping: 0x%x\n", le32_to_cpu(port_shap_cfg_cmd->port_shapping_para)); + dev_info(&hdev->pdev->dev, "PORT flag: %#x\n", port_shap_cfg_cmd->flag); + dev_info(&hdev->pdev->dev, "PORT port_rate: %u(Mbps)\n", +le32_to_cpu(port_shap_cfg_cmd->port_rate)); cmd = HCLGE_OPC_TM_PG_SCH_MODE_CFG; hclge_cmd_setup_basic_desc(&desc, cmd, true); @@ -655,6 +661,9 @@ static void hclge_dbg_dump_tm(struct hclge_dev *hdev) dev_info(&hdev->pdev->dev, "PRI_C pri_id: %u\n", shap_cfg_cmd->pri_id); dev_info(&hdev->pdev->dev, "PRI_C pri_shapping: 0x%x\n", le32_to_cpu(shap_cfg_cmd->pri_shapping_para)); + dev_info(&hdev->pdev->dev, "PRI_C flag: %#x\n", shap_cfg_cmd->flag); + dev_info(&hdev->pdev->dev, "PRI_C pri_rate: %u(Mbps)\n", +le32_to_cpu(shap_cfg_cmd->pri_rate)); cmd = HCLGE_OPC_TM_PRI_P_SHAPPING; hclge_cmd_setup_basic_desc(&desc, cmd, true); @@ -666,6 +675,9 @@ static void hclge_dbg_dump_tm(struct hclge_dev *hdev) dev_info(&hdev->pdev->dev, "PRI_P pri_id: %u\n", shap_cfg_cmd->pri_id); dev_info(&hdev->pdev->dev, "PRI_P pri_shapping: 0x%x\n", le32_to_cpu(shap_cfg_cmd->pri_shapping_para)); + dev_info(&hdev->pdev->dev, "PRI_P flag: %#x\n", shap_cfg_cmd->flag); + dev_info(&hdev->pdev->dev, "PRI_P pri_rate: %u(Mbps)\n", +le32_to_cpu(shap_cfg_cmd->pri_rate)); hclge_dbg_dump_tm_pg(hdev); @@ -1401,6 +1413,7 @@ static void hclge_dbg_dump_qs_shaper_single(struct hclge_dev *hdev, u16 qsid) u8 ir_u, ir_b, ir_s, bs_b, bs_s; struct hclge_desc desc; u32 shapping_para; + u32 rate; int ret; hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_QCN_SHAPPING_CFG, true); @@ -1422,10 +1435,11 @@ static void hclge_dbg_dump_qs_shaper_single(struct hclge_dev *hdev, u16 qsid) ir_s = hclge_tm_get_field(shapping_para, IR_S); bs_b = hclge_tm_get_field(shapping_para, BS_B); bs_s = hclge_tm_get_field(shapping_para, BS_S); + rate = le32_to_cpu(shap_cfg_cmd->qs_rate); dev_info(&hdev->pdev->dev, -"qs%u ir_b:%u, ir_u:%u, ir_s:%u, bs_b:%u, bs_s:%u\n", -qsid, ir_b, ir_u, ir_s, bs_b, bs_s); +"qs%u ir_b:%u, ir_u:%u, ir_s:%u, bs_b:%u, bs_s:%u, flag:%#x, rate:%u(Mbps)\n", +qsid, ir_b, ir_u, ir_s, bs_b, bs_s, shap_cfg_cmd->flag, rate); } static void hclge_dbg_dump_qs_shaper_all(struct hclge_dev *hdev) -- 2.7.4
[PATCH net-next 3/5] net: hns3: add support for pf querying new interrupt resources
From: Yufeng Mo For HNAE3_DEVICE_VERSION_V3, a maximum of 1281 interrupt resources are supported. To utilize these new resources, extend the corresponding field or variable to 16bit type, and remove the restriction of NIC client that only use a maximum of 65 interrupt vectors. In addition, the I/O address of the extended interrupt resources are different, so an extra handler is needed. Currently, the total number of interrupts is the sum of RoCE's number and RoCE's offset (RoCE is in front of NIC), since the number of both NIC and RoCE are same. For readability, rewrite the corresponding field of the command, rename the RoCE's offset field as the number of NIC interrupts, then the total number of interrupts is sum of the number of RoCE and NIC, and replace vport->back with hdev in hclge_init_roce_base_info() for simplifying the code. Signed-off-by: Yufeng Mo Signed-off-by: Huazhong Tan --- drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 3 - .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h | 16 ++-- .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 100 - .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h| 3 +- 4 files changed, 69 insertions(+), 53 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index 999a2aa..632ad42 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -3645,8 +3645,6 @@ static int hns3_nic_init_vector_data(struct hns3_nic_priv *priv) static int hns3_nic_alloc_vector_data(struct hns3_nic_priv *priv) { -#define HNS3_VECTOR_PF_MAX_NUM 64 - struct hnae3_handle *h = priv->ae_handle; struct hns3_enet_tqp_vector *tqp_vector; struct hnae3_vector_info *vector; @@ -3659,7 +3657,6 @@ static int hns3_nic_alloc_vector_data(struct hns3_nic_priv *priv) /* RSS size, cpu online and vector_num should be the same */ /* Should consider 2p/4p later */ vector_num = min_t(u16, num_online_cpus(), tqp_num); - vector_num = min_t(u16, vector_num, HNS3_VECTOR_PF_MAX_NUM); vector = devm_kcalloc(&pdev->dev, vector_num, sizeof(*vector), GFP_KERNEL); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h index f458d32..6d7ba20 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h @@ -339,7 +339,9 @@ enum hclge_int_type { }; struct hclge_ctrl_vector_chain_cmd { - u8 int_vector_id; +#define HCLGE_VECTOR_ID_L_S0 +#define HCLGE_VECTOR_ID_L_MGENMASK(7, 0) + u8 int_vector_id_l; u8 int_cause_num; #define HCLGE_INT_TYPE_S 0 #define HCLGE_INT_TYPE_M GENMASK(1, 0) @@ -349,7 +351,9 @@ struct hclge_ctrl_vector_chain_cmd { #define HCLGE_INT_GL_IDX_M GENMASK(14, 13) __le16 tqp_type_and_id[HCLGE_VECTOR_ELEMENTS_PER_CMD]; u8 vfid; - u8 rsv; +#define HCLGE_VECTOR_ID_H_S8 +#define HCLGE_VECTOR_ID_H_MGENMASK(15, 8) + u8 int_vector_id_h; }; #define HCLGE_MAX_TC_NUM 8 @@ -473,12 +477,8 @@ struct hclge_pf_res_cmd { __le16 tqp_num; __le16 buf_size; __le16 msixcap_localid_ba_nic; - __le16 msixcap_localid_ba_rocee; -#define HCLGE_MSIX_OFT_ROCEE_S 0 -#define HCLGE_MSIX_OFT_ROCEE_M GENMASK(15, 0) -#define HCLGE_PF_VEC_NUM_S 0 -#define HCLGE_PF_VEC_NUM_M GENMASK(7, 0) - __le16 pf_intr_vector_number; + __le16 msixcap_localid_number_nic; + __le16 pf_intr_vector_number_roce; __le16 pf_own_fun_number; __le16 tx_buf_size; __le16 dv_buf_size; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 9989930..500cc19 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -906,35 +906,24 @@ static int hclge_query_pf_resource(struct hclge_dev *hdev) hdev->dv_buf_size = roundup(hdev->dv_buf_size, HCLGE_BUF_SIZE_UNIT); + hdev->num_nic_msi = le16_to_cpu(req->msixcap_localid_number_nic); + if (hdev->num_nic_msi < HNAE3_MIN_VECTOR_NUM) { + dev_err(&hdev->pdev->dev, + "only %u msi resources available, not enough for pf(min:2).\n", + hdev->num_nic_msi); + return -EINVAL; + } + if (hnae3_dev_roce_supported(hdev)) { - hdev->roce_base_msix_offset = - hnae3_get_field(le16_to_cpu(req->msixcap_localid_ba_rocee), - HCLGE_MSIX_OFT_ROCEE_M, HCLGE_MSIX_OFT_ROCEE_S); hdev->num_roce_msi = - hnae3_get_field(le16_to_cpu(req->pf_intr_vector_number), - HC
[PATCH net-next 0/5] net: hns3: misc updates for -next
This series includes some misc updates for the HNS3 ethernet driver. #1 adds support for 1280 queues #2 adds mapping for BAR45 which is needed by RoCE client. #3 extend the interrupt resources. #4 add support to query firmware's calculated shaping parameters. Huazhong Tan (1): net: hns3: add support for mapping device memory Yonglong Liu (3): net: hns3: add support for 1280 queues net: hns3: add support to utilize the firmware calculated shaping parameters net: hns3: adds debugfs to dump more info of shaping parameters Yufeng Mo (1): net: hns3: add support for pf querying new interrupt resources drivers/net/ethernet/hisilicon/hns3/hnae3.h| 1 + drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 3 - .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h | 23 +-- .../ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c | 48 ++- .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 160 ++--- .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h| 4 +- .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c | 80 --- .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h | 26 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h | 3 + .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 49 ++- .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h | 1 + 11 files changed, 310 insertions(+), 88 deletions(-) -- 2.7.4
[PATCH net-next 4/5] net: hns3: add support to utilize the firmware calculated shaping parameters
From: Yonglong Liu Since the calculation of the driver is fixed, if the number of queue or clock changed, the calculated result may be inaccurate. So for compatible and maintainable, add a new flag to tell the firmware to calculate the shaping parameters with the specified rate. Signed-off-by: Yonglong Liu Signed-off-by: Huazhong Tan --- .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c | 43 -- .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h | 15 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c index b50b079..54767b0 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c @@ -395,7 +395,7 @@ static u32 hclge_tm_get_shapping_para(u8 ir_b, u8 ir_u, u8 ir_s, static int hclge_tm_pg_shapping_cfg(struct hclge_dev *hdev, enum hclge_shap_bucket bucket, u8 pg_id, - u32 shapping_para) + u32 shapping_para, u32 rate) { struct hclge_pg_shapping_cmd *shap_cfg_cmd; enum hclge_opcode_type opcode; @@ -411,6 +411,10 @@ static int hclge_tm_pg_shapping_cfg(struct hclge_dev *hdev, shap_cfg_cmd->pg_shapping_para = cpu_to_le32(shapping_para); + hnae3_set_bit(shap_cfg_cmd->flag, HCLGE_TM_RATE_VLD, 1); + + shap_cfg_cmd->pg_rate = cpu_to_le32(rate); + return hclge_cmd_send(&hdev->hw, &desc, 1); } @@ -438,12 +442,16 @@ static int hclge_tm_port_shaper_cfg(struct hclge_dev *hdev) shap_cfg_cmd->port_shapping_para = cpu_to_le32(shapping_para); + hnae3_set_bit(shap_cfg_cmd->flag, HCLGE_TM_RATE_VLD, 1); + + shap_cfg_cmd->port_rate = cpu_to_le32(hdev->hw.mac.speed); + return hclge_cmd_send(&hdev->hw, &desc, 1); } static int hclge_tm_pri_shapping_cfg(struct hclge_dev *hdev, enum hclge_shap_bucket bucket, u8 pri_id, -u32 shapping_para) +u32 shapping_para, u32 rate) { struct hclge_pri_shapping_cmd *shap_cfg_cmd; enum hclge_opcode_type opcode; @@ -460,6 +468,10 @@ static int hclge_tm_pri_shapping_cfg(struct hclge_dev *hdev, shap_cfg_cmd->pri_shapping_para = cpu_to_le32(shapping_para); + hnae3_set_bit(shap_cfg_cmd->flag, HCLGE_TM_RATE_VLD, 1); + + shap_cfg_cmd->pri_rate = cpu_to_le32(rate); + return hclge_cmd_send(&hdev->hw, &desc, 1); } @@ -561,6 +573,9 @@ int hclge_tm_qs_shaper_cfg(struct hclge_vport *vport, int max_tx_rate) shap_cfg_cmd->qs_id = cpu_to_le16(vport->qs_offset + i); shap_cfg_cmd->qs_shapping_para = cpu_to_le32(shaper_para); + hnae3_set_bit(shap_cfg_cmd->flag, HCLGE_TM_RATE_VLD, 1); + shap_cfg_cmd->qs_rate = cpu_to_le32(max_tx_rate); + ret = hclge_cmd_send(&hdev->hw, &desc, 1); if (ret) { dev_err(&hdev->pdev->dev, @@ -762,9 +777,10 @@ static int hclge_tm_pg_shaper_cfg(struct hclge_dev *hdev) /* Pg to pri */ for (i = 0; i < hdev->tm_info.num_pg; i++) { + u32 rate = hdev->tm_info.pg_info[i].bw_limit; + /* Calc shaper para */ - ret = hclge_shaper_para_calc(hdev->tm_info.pg_info[i].bw_limit, -HCLGE_SHAPER_LVL_PG, + ret = hclge_shaper_para_calc(rate, HCLGE_SHAPER_LVL_PG, &ir_para, max_tm_rate); if (ret) return ret; @@ -774,7 +790,7 @@ static int hclge_tm_pg_shaper_cfg(struct hclge_dev *hdev) HCLGE_SHAPER_BS_S_DEF); ret = hclge_tm_pg_shapping_cfg(hdev, HCLGE_TM_SHAP_C_BUCKET, i, - shaper_para); + shaper_para, rate); if (ret) return ret; @@ -785,7 +801,7 @@ static int hclge_tm_pg_shaper_cfg(struct hclge_dev *hdev) HCLGE_SHAPER_BS_S_DEF); ret = hclge_tm_pg_shapping_cfg(hdev, HCLGE_TM_SHAP_P_BUCKET, i, - shaper_para); + shaper_para, rate); if (ret) return ret; } @@ -891,8 +907,9 @@ static int hclge_tm_pri_tc_base_shaper_cfg(struct hclge_dev *hdev) u32 i; for (i = 0; i < hdev->tm_info.num_tc; i++) { - ret = hclge_shaper_para_calc(hdev->tm_info.tc_info[i].bw_limit, -
[PATCH net-next 1/5] net: hns3: add support for 1280 queues
From: Yonglong Liu For DEVICE_VERSION_V1/2, there are total 1024 queues and queue sets. For DEVICE_VERSION_V3, it increases to 1280, and can be assigned to one pf, so remove the limitation of 1024. To keep compatible with DEVICE_VERSION_V1/2 and old driver version, the queue number is split into two part: tqp_num(range 0~1023) and ext_tqp_num(range 1024~1279). Signed-off-by: Yonglong Liu Signed-off-by: Huazhong Tan --- .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h | 7 ++-- .../ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c | 30 +++--- .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 29 - .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c | 37 ++ .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h | 11 +++ .../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h | 3 ++ .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 16 -- 7 files changed, 111 insertions(+), 22 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h index 5b7967c..f458d32 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h @@ -307,6 +307,9 @@ enum hclge_opcode_type { #define HCLGE_TQP_REG_OFFSET 0x8 #define HCLGE_TQP_REG_SIZE 0x200 +#define HCLGE_TQP_MAX_SIZE_DEV_V2 1024 +#define HCLGE_TQP_EXT_REG_OFFSET 0x100 + #define HCLGE_RCB_INIT_QUERY_TIMEOUT 10 #define HCLGE_RCB_INIT_FLAG_EN_B 0 #define HCLGE_RCB_INIT_FLAG_FINI_B 8 @@ -479,7 +482,8 @@ struct hclge_pf_res_cmd { __le16 pf_own_fun_number; __le16 tx_buf_size; __le16 dv_buf_size; - __le32 rsv[2]; + __le16 ext_tqp_num; + u8 rsv[6]; }; #define HCLGE_CFG_OFFSET_S 0 @@ -643,7 +647,6 @@ struct hclge_config_mac_speed_dup_cmd { u8 rsv[22]; }; -#define HCLGE_RING_ID_MASK GENMASK(9, 0) #define HCLGE_TQP_ENABLE_B 0 #define HCLGE_MAC_CFG_AN_EN_B 0 diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c index 16df050..c82d2ca 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c @@ -681,14 +681,17 @@ static void hclge_dbg_dump_tm_map(struct hclge_dev *hdev, { struct hclge_bp_to_qs_map_cmd *bp_to_qs_map_cmd; struct hclge_nq_to_qs_link_cmd *nq_to_qs_map; + u32 qset_mapping[HCLGE_BP_EXT_GRP_NUM]; struct hclge_qs_to_pri_link_cmd *map; struct hclge_tqp_tx_queue_tc_cmd *tc; enum hclge_opcode_type cmd; struct hclge_desc desc; int queue_id, group_id; - u32 qset_mapping[32]; int tc_id, qset_id; int pri_id, ret; + u16 qs_id_l; + u16 qs_id_h; + u8 grp_num; u32 i; ret = kstrtouint(cmd_buf, 0, &queue_id); @@ -701,7 +704,24 @@ static void hclge_dbg_dump_tm_map(struct hclge_dev *hdev, ret = hclge_cmd_send(&hdev->hw, &desc, 1); if (ret) goto err_tm_map_cmd_send; - qset_id = le16_to_cpu(nq_to_qs_map->qset_id) & 0x3FF; + qset_id = le16_to_cpu(nq_to_qs_map->qset_id); + + /* convert qset_id to the following format, drop the vld bit +*| qs_id_h | vld | qs_id_l | +* qset_id: | 15 ~ 11 | 10 | 9 ~ 0 | +* \ \ / / +* \ \ / / +* qset_id: | 15 | 14 ~ 10 | 9 ~ 0 | +*/ + qs_id_l = hnae3_get_field(qset_id, HCLGE_TM_QS_ID_L_MSK, + HCLGE_TM_QS_ID_L_S); + qs_id_h = hnae3_get_field(qset_id, HCLGE_TM_QS_ID_H_EXT_MSK, + HCLGE_TM_QS_ID_H_EXT_S); + qset_id = 0; + hnae3_set_field(qset_id, HCLGE_TM_QS_ID_L_MSK, HCLGE_TM_QS_ID_L_S, + qs_id_l); + hnae3_set_field(qset_id, HCLGE_TM_QS_ID_H_MSK, HCLGE_TM_QS_ID_H_S, + qs_id_h); cmd = HCLGE_OPC_TM_QS_TO_PRI_LINK; map = (struct hclge_qs_to_pri_link_cmd *)desc.data; @@ -731,9 +751,11 @@ static void hclge_dbg_dump_tm_map(struct hclge_dev *hdev, return; } + grp_num = hdev->num_tqps <= HCLGE_TQP_MAX_SIZE_DEV_V2 ? + HCLGE_BP_GRP_NUM : HCLGE_BP_EXT_GRP_NUM; cmd = HCLGE_OPC_TM_BP_TO_QSET_MAPPING; bp_to_qs_map_cmd = (struct hclge_bp_to_qs_map_cmd *)desc.data; - for (group_id = 0; group_id < 32; group_id++) { + for (group_id = 0; group_id < grp_num; group_id++) { hclge_cmd_setup_basic_desc(&desc, cmd, true); bp_to_qs_map_cmd->tc_id = tc_id; bp_to_qs_map_cmd->qs_group_id = group_id; @@ -748,7 +770,7 @@ static void hclge_dbg_dump_tm_map(struct hclge_dev *hdev, dev_info(&hdev->pdev->dev, "
[PATCH net-next V7] net: Variable SLAAC: SLAAC with prefixes of arbitrary length in PIO
Variable SLAAC: SLAAC with prefixes of arbitrary length in PIO (randomly generated hostID or stable privacy + privacy extensions). The main problem is that SLAAC RA or PD allocates a /64 by the Wireless carrier 4G, 5G to a mobile hotspot, however segmentation of the /64 via SLAAC is required so that downstream interfaces can be further subnetted. Example: uCPE device (4G + WI-FI enabled) receives /64 via Wireless, and assigns /72 to VNF-Firewall, /72 to WIFI, /72 to VNF-Router, /72 to Load-Balancer and /72 to wired connected devices. IETF document that defines problem statement: draft-mishra-v6ops-variable-slaac-problem-stmt IETF document that specifies variable slaac: draft-mishra-6man-variable-slaac Signed-off-by: Dmytro Shytyi --- diff -rupN net-next-5.10.0-rc2/net/ipv6/addrconf.c net-next-patch-5.10.0-rc2/net/ipv6/addrconf.c --- net-next-5.10.0-rc2/net/ipv6/addrconf.c 2020-11-10 08:46:01.075193379 +0100 +++ net-next-patch-5.10.0-rc2/net/ipv6/addrconf.c 2020-11-19 21:26:39.770872898 +0100 @@ -142,7 +142,6 @@ static int ipv6_count_addresses(const st static int ipv6_generate_stable_address(struct in6_addr *addr, u8 dad_count, const struct inet6_dev *idev); - #define IN6_ADDR_HSIZE_SHIFT 8 #define IN6_ADDR_HSIZE (1 << IN6_ADDR_HSIZE_SHIFT) /* @@ -1315,6 +1314,7 @@ static int ipv6_create_tempaddr(struct i struct ifa6_config cfg; long max_desync_factor; struct in6_addr addr; + struct in6_addr temp; int ret = 0; write_lock_bh(&idev->lock); @@ -1340,9 +1340,16 @@ retry: goto out; } in6_ifa_hold(ifp); - memcpy(addr.s6_addr, ifp->addr.s6_addr, 8); - ipv6_gen_rnd_iid(&addr); + if (ifp->prefix_len == 64) { + memcpy(addr.s6_addr, ifp->addr.s6_addr, 8); + ipv6_gen_rnd_iid(&addr); + } else if (ifp->prefix_len > 0 && ifp->prefix_len <= 128) { + memcpy(addr.s6_addr32, ifp->addr.s6_addr, 16); + get_random_bytes(temp.s6_addr32, 16); + ipv6_addr_prefix_copy(&temp, &addr, ifp->prefix_len); + memcpy(addr.s6_addr, temp.s6_addr, 16); + } age = (now - ifp->tstamp) / HZ; regen_advance = idev->cnf.regen_max_retry * @@ -2569,6 +2576,41 @@ static bool is_addr_mode_generate_stable idev->cnf.addr_gen_mode == IN6_ADDR_GEN_MODE_RANDOM; } +static struct inet6_ifaddr *ipv6_cmp_rcvd_prsnt_prfxs(struct inet6_ifaddr *ifp, + struct inet6_dev *in6_dev, + struct net *net, + const struct prefix_info *pinfo) +{ + struct inet6_ifaddr *result_base = NULL; + struct inet6_ifaddr *result = NULL; + struct in6_addr curr_net_prfx; + struct in6_addr net_prfx; + bool prfxs_equal; + + result_base = result; + rcu_read_lock(); + list_for_each_entry_rcu(ifp, &in6_dev->addr_list, if_list) { + if (!net_eq(dev_net(ifp->idev->dev), net)) + continue; + ipv6_addr_prefix_copy(&net_prfx, &pinfo->prefix, pinfo->prefix_len); + ipv6_addr_prefix_copy(&curr_net_prfx, &ifp->addr, pinfo->prefix_len); + prfxs_equal = + ipv6_prefix_equal(&net_prfx, &curr_net_prfx, pinfo->prefix_len); + if (prfxs_equal && pinfo->prefix_len == ifp->prefix_len) { + result = ifp; + in6_ifa_hold(ifp); + break; + } + } + rcu_read_unlock(); + if (result_base != result) + ifp = result; + else + ifp = NULL; + + return ifp; +} + int addrconf_prefix_rcv_add_addr(struct net *net, struct net_device *dev, const struct prefix_info *pinfo, struct inet6_dev *in6_dev, @@ -2576,9 +2618,16 @@ int addrconf_prefix_rcv_add_addr(struct u32 addr_flags, bool sllao, bool tokenized, __u32 valid_lft, u32 prefered_lft) { - struct inet6_ifaddr *ifp = ipv6_get_ifaddr(net, addr, dev, 1); + struct inet6_ifaddr *ifp = NULL; + int plen = pinfo->prefix_len; int create = 0; + if (plen > 0 && plen <= 128 && plen != 64 && + in6_dev->cnf.addr_gen_mode != IN6_ADDR_GEN_MODE_STABLE_PRIVACY) + ifp = ipv6_cmp_rcvd_prsnt_prfxs(ifp, in6_dev, net, pinfo); + else + ifp = ipv6_get_ifaddr(net, addr, dev, 1); + if (!ifp && valid_lft) { int max_addresses = in6_dev->cnf.max_addresses; struct ifa6_config cfg = { @@ -2657,6 +2706,91 @@ int addrconf_prefix_rcv_add_addr(struct } EXPORT_SYMBOL_GPL(addrconf_prefix_rc
[PATCH] veth: fix memleak in veth_newlink()
I got a memleak report when doing fault-inject test: unreferenced object 0x88810ace9000 (size 1024): comm "ip", pid 4622, jiffies 4295457037 (age 43.378s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 backtrace: [<008abe41>] __kmalloc+0x10f/0x210 [<5d3533a6>] veth_dev_init+0x140/0x310 [<88353c64>] register_netdevice+0x496/0x7a0 [<1324d322>] veth_newlink+0x40b/0x960 [] __rtnl_newlink+0xd8c/0x1360 [ ] rtnl_newlink+0x6b/0xa0 [ ] rtnetlink_rcv_msg+0x3cc/0x9e0 [<9eeff98b>] netlink_rcv_skb+0x130/0x3a0 [<500f8be1>] netlink_unicast+0x4da/0x700 [<666c03b3>] netlink_sendmsg+0x7fe/0xcb0 [<73b28103>] sock_sendmsg+0x143/0x180 [ ] sys_sendmsg+0x677/0x810 [<87dd98e5>] ___sys_sendmsg+0x105/0x180 [<028dd365>] __sys_sendmsg+0xf0/0x1c0 [ ] do_syscall_64+0x33/0x40 [ ] entry_SYSCALL_64_after_hwframe+0x44/0xa9 If call_netdevice_notifiers() failed in register_netdevice(), dev->priv_destructor() is not called, it will cause memleak. Fix this by assigning ndo_uninit with veth_dev_free(), so the memory can be freed in rollback_registered(); Reported-by: Hulk Robot Signed-off-by: Yang Yingliang --- drivers/net/veth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 8c737668008a..537d9a60028a 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -1217,6 +1217,7 @@ static int veth_xdp(struct net_device *dev, struct netdev_bpf *xdp) static const struct net_device_ops veth_netdev_ops = { .ndo_init= veth_dev_init, + .ndo_uninit = veth_dev_free, .ndo_open= veth_open, .ndo_stop= veth_close, .ndo_start_xmit = veth_xmit, @@ -1260,7 +1261,6 @@ static void veth_setup(struct net_device *dev) NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX); dev->needs_free_netdev = true; - dev->priv_destructor = veth_dev_free; dev->max_mtu = ETH_MAX_MTU; dev->hw_features = VETH_FEATURES; -- 2.17.1
Re: net: phy: Dealing with 88e1543 dual-port mode
Hi Tobias, On Fri, 20 Nov 2020 01:11:12 +0100 Tobias Waldekranz wrote: >On Thu, Nov 19, 2020 at 23:16, Russell King - ARM Linux admin > wrote: >> On Thu, Nov 19, 2020 at 11:43:39PM +0100, Tobias Waldekranz wrote: >>> On Thu, Nov 19, 2020 at 16:24, Maxime Chevallier >>> wrote: >>> > I don't think we have a way to distinguish from the DT if we are in >>> > SGMII-to-Fibre or in SGMII-to-{Copper + Fibre}, since the description is >>> > the same, we don't have any information in DT about wether or not the >>> > PHY is wired to a Copper RJ45 port. >>> > >>> > Maybe we should have a way to indicate if a PHY is wired to a Copper >>> > port in DT ? >>> >>> Do you mean something like: >>> >>> SGMII->SGMII (Fibre): >>> ethernet-phy@0 { >>>sfp = <&sfp0>; >>> }; >>> >>> SGMII->MDI (Copper): >>> ethernet-phy@0 { >>> mdi; >>> }; >>> >>> SGMII->Auto Media Detect >>> ethernet-phy@0 { >>> mdi; >>> sfp = <&sfp0>; >>> }; >> >> This isn't something we could realistically do - think about how many >> DT files are out there today which would not have this for an existing >> PHY. The default has to be that today's DT descriptions continue to work >> as-is, and that includes ones which already support copper and fibre >> either with or without a sfp property. >> >> So, we can't draw any conclusion about whether the fiber interface is >> wired from whether there is a sfp property or not. >> >> We also can't draw a conclusion about whether the copper side is wired >> using a "mdi" property, or whether there is a "sfp" property or not. >> >> The only thing we could realistically do today is to introduce a >> property like: >> >> mdi = "disabled" | "okay"; >> >> to indicate whether the copper port can be used, and maybe something >> similar for the fiber interface. Maybe as you suggest, not "okay" >> but specifying the number of connected pairs would be a good idea, >> or maybe that should be a separate property? > >Maybe you could have optional media nodes under the PHY instead, so that >you don't involve the SFP property in the logic (SGMII can be connected >to lots of things after all): > >ethernet-phy@0 { >... > >sgmii { >status = "okay"; >preferred; >}; > >mdi { > status = "okay"; > pairs = <2>; >}; >}; I like that approach too, and I agree that we do need to be very careful with not breaking existing PHYs, where most of the time we assume that a PHY simply has a 8P8C (RJ45) connector. Maybe the term MDI is a bit misused here, my understanding was that MDI, standing for "Media Dependent Interface" represents the media-side interface in general, and not a particular technology such as xxxBaseT/X/K or Copper of Fibre. So maybe we could be a bit more generic, with something along these lines : ethernet-phy@0 { ... mdi { port@0 { media = "10baseT", "100baseT", "1000baseT"; pairs = <1>; }; port@1 { media = "1000baseX", "10gbaseR" }; }; }; This would allow us to explicitely indicate which modes are supported by each port. And in absence of the mdi node, we indeed fallback to the usual behaviour. >In the absence of any media declarations, you fall back to the driver's >default behavior (keeping compatibility with older DTs). But you can >still add support for more configurations if the information is >available. I also like the idea of having a way to express the "preferred" media, although I wonder if that's something we want to include in DT or that we would want to tweak at runtime, through ethtool for example. What do you think ? Thanks, Maxime
[PATCH net-next] MAINTAINERS: Update page pool entry
Add some file F: matches that is related to page_pool. Signed-off-by: Jesper Dangaard Brouer --- MAINTAINERS |2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index f827f504251b..efcdc68a03b1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13179,6 +13179,8 @@ L: netdev@vger.kernel.org S: Supported F: include/net/page_pool.h F: net/core/page_pool.c +F: include/trace/events/page_pool.h +F: Documentation/networking/page_pool.rst PANASONIC LAPTOP ACPI EXTRAS DRIVER M: Harald Welte
RE: [EXT] Re: [RFC, net-next] net: qos: introduce a redundancy flow action
On 2020-11-18 3:01 Joergen Andreasen wrote: > > Hi Xiaoliang, > > I like your idea about using filter actions for FRER configuration. > > I think this is a good starting point but I think that this approach will > only allow us to configure end systems and not relay systems in > bridges/switches. > > In the following I refer to sections and figures in 802.1CB-2017. > > I am missing the following possibilities: > Configure split without adding an r-tag (Figure C-4 Relay system C). > Configure recovery without popping the r-tag (Figure C4 Relay system F). > Disable flooding and learning per VLAN (Section C.7). > Select between vector and match recovery algorithm (Section 7.4.3.4 and > 7.4.3.5). > Configure history length if vector algorithm is used (Section 10.4.1.6). > Configure reset timeout (Section 10.4.1.7). > Adding an individual recovery function (Section 7.5). > Counters to be used for latent error detection (Section 7.4.4). > > I would prefer to use the term 'frer' instead of 'red' or 'redundancy' > in all definitions and functions except for 'redundancy-tag'. Thanks for your suggestion, it's very useful to me. I ignored frer on relay system. I will study sections and features you mentioned on Spec. If using a new tc-frer action is ok, I will perfect and update it. Regards, Xiaoliang
[PATCH] octeontx2-af: Add support for RSS hashing based on Transport protocol field
Add support to choose RSS flow key algorithm with IPv4 transport protocol field included in hashing input data. This will be enabled by default. There-by enabling 3/5 tuple hash Signed-off-by: Sunil Kovvuri Goutham Signed-off-by: George Cherian --- drivers/net/ethernet/marvell/octeontx2/af/mbox.h | 1 + drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c | 7 +++ drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c | 3 ++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h index f46de8419b77..97c8566b7da8 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h @@ -644,6 +644,7 @@ struct nix_rss_flowkey_cfg { #define NIX_FLOW_KEY_TYPE_INNR_SCTP BIT(16) #define NIX_FLOW_KEY_TYPE_INNR_ETH_DMAC BIT(17) #define NIX_FLOW_KEY_TYPE_VLAN BIT(20) +#define NIX_FLOW_KEY_TYPE_IPV4_PROTO BIT(21) u32 flowkey_cfg; /* Flowkey types selected */ u8 group; /* RSS context or group */ }; diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c index 8bac1dd3a1c2..ef016521b277 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c @@ -2429,6 +2429,13 @@ static int set_flowkey_fields(struct nix_rx_flowkey_alg *alg, u32 flow_cfg) /* This should be set to 1, when SEL_CHAN is set */ field->bytesm1 = 1; break; + case NIX_FLOW_KEY_TYPE_IPV4_PROTO: + field->lid = NPC_LID_LC; + field->hdr_offset = 9; /* offset */ + field->bytesm1 = 0; /* 1 byte */ + field->ltype_match = NPC_LT_LC_IP; + field->ltype_mask = 0xF; + break; case NIX_FLOW_KEY_TYPE_IPV4: case NIX_FLOW_KEY_TYPE_INNR_IPV4: field->lid = NPC_LID_LC; diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c index 9f3d6715748e..2ab927408656 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c @@ -355,7 +355,8 @@ int otx2_rss_init(struct otx2_nic *pfvf) rss->flowkey_cfg = rss->enable ? rss->flowkey_cfg : NIX_FLOW_KEY_TYPE_IPV4 | NIX_FLOW_KEY_TYPE_IPV6 | NIX_FLOW_KEY_TYPE_TCP | NIX_FLOW_KEY_TYPE_UDP | - NIX_FLOW_KEY_TYPE_SCTP | NIX_FLOW_KEY_TYPE_VLAN; + NIX_FLOW_KEY_TYPE_SCTP | NIX_FLOW_KEY_TYPE_VLAN | + NIX_FLOW_KEY_TYPE_IPV4_PROTO; ret = otx2_set_flowkey_cfg(pfvf); if (ret) -- 2.25.1
Re: [EXT] Re: [RFC, net-next] net: qos: introduce a redundancy flow action
On Fri, Nov 20, 2020 at 09:39:12AM +, Xiaoliang Yang wrote: > On 2020-11-18 3:01 Joergen Andreasen wrote: > > I like your idea about using filter actions for FRER configuration. > > > > I think this is a good starting point but I think that this approach > > will only allow us to configure end systems and not relay systems in > > bridges/switches. > > > > In the following I refer to sections and figures in 802.1CB-2017. > > > > I am missing the following possibilities: > > Configure split without adding an r-tag (Figure C-4 Relay system C). > > Configure recovery without popping the r-tag (Figure C4 Relay system F). > > Disable flooding and learning per VLAN (Section C.7). > > Select between vector and match recovery algorithm (Section 7.4.3.4 and > > 7.4.3.5). > > Configure history length if vector algorithm is used (Section 10.4.1.6). > > Configure reset timeout (Section 10.4.1.7). > > Adding an individual recovery function (Section 7.5). > > Counters to be used for latent error detection (Section 7.4.4). > > > > I would prefer to use the term 'frer' instead of 'red' or 'redundancy' > > in all definitions and functions except for 'redundancy-tag'. > > Thanks for your suggestion, it's very useful to me. I ignored frer on > relay system. I will study sections and features you mentioned on > Spec. If using a new tc-frer action is ok, I will perfect and update > it. Is replicated IP multicast (with IGMP/MLD snooping) something that is going to work using your current abstraction? I think this is one area that is required to work at a higher level than the level of a physical port.
[PATCH v2] brcmfmac: expose firmware config files through modinfo
From: Matthias Brugger Apart from a firmware binary the chip needs a config file used by the FW. Add the config files to modinfo so that they can be read by userspace. Signed-off-by: Matthias Brugger --- Changes in v2: In comparison to first version [0] we use wildcards to enumerate the firmware configuration files. Wildcard support was added to dracut recently [1]. [0] https://lore.kernel.org/linux-wireless/20200701153123.25602-1-matthias@kernel.org/ [1] https://github.com/dracutdevs/dracut/pull/860 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index 99987a789e7e..dd6d287b1b00 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -625,6 +625,15 @@ BRCMF_FW_DEF(4359, "brcmfmac4359-sdio"); BRCMF_FW_DEF(4373, "brcmfmac4373-sdio"); BRCMF_FW_DEF(43012, "brcmfmac43012-sdio"); +/* firmware config files */ +MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcm/brcmfmac4330-sdio.*.txt"); +MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcm/brcmfmac43340-sdio.*.txt"); +MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcm/brcmfmac43362-sdio.*.txt"); +MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcm/brcmfmac43430a0-sdio.*.txt"); +MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcm/brcmfmac43430-sdio.*.txt"); +MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcm/brcmfmac43455-sdio.*.txt"); +MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcm/brcmfmac4356-pcie.*.txt"); + static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = { BRCMF_FW_ENTRY(BRCM_CC_43143_CHIP_ID, 0x, 43143), BRCMF_FW_ENTRY(BRCM_CC_43241_CHIP_ID, 0x001F, 43241B0), -- 2.29.2
Re: [PATCH v2] brcmfmac: expose firmware config files through modinfo
20.11.2020 12:52, matthias@kernel.org пишет: > From: Matthias Brugger > > Apart from a firmware binary the chip needs a config file used by the > FW. Add the config files to modinfo so that they can be read by > userspace. > > Signed-off-by: Matthias Brugger > > --- > > Changes in v2: > In comparison to first version [0] we use wildcards to enumerate the > firmware configuration files. Wildcard support was added to dracut > recently [1]. > [0] > https://lore.kernel.org/linux-wireless/20200701153123.25602-1-matthias@kernel.org/ > [1] https://github.com/dracutdevs/dracut/pull/860 > > drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 9 + > 1 file changed, 9 insertions(+) > > diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c > b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c > index 99987a789e7e..dd6d287b1b00 100644 > --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c > +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c > @@ -625,6 +625,15 @@ BRCMF_FW_DEF(4359, "brcmfmac4359-sdio"); > BRCMF_FW_DEF(4373, "brcmfmac4373-sdio"); > BRCMF_FW_DEF(43012, "brcmfmac43012-sdio"); > > +/* firmware config files */ > +MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcm/brcmfmac4330-sdio.*.txt"); > +MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcm/brcmfmac43340-sdio.*.txt"); > +MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcm/brcmfmac43362-sdio.*.txt"); > +MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcm/brcmfmac43430a0-sdio.*.txt"); > +MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcm/brcmfmac43430-sdio.*.txt"); > +MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcm/brcmfmac43455-sdio.*.txt"); > +MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcm/brcmfmac4356-pcie.*.txt"); This doesn't cover all hardware models. Note that the upstream linux-firmware has files only for a few hardware models. I suppose that the correct mask should be "brcm/brcmfmac*-sdio.*.txt".
[PATCH net] net/af_iucv: set correct sk_protocol for child sockets
Child sockets erroneously inherit their parent's sk_type (ie. SOCK_*), instead of the PF_IUCV protocol that the parent was created with in iucv_sock_create(). We're currently not using sk->sk_protocol ourselves, so this shouldn't have much impact (except eg. getting the output in skb_dump() right). Fixes: eac3731bd04c ("[S390]: Add AF_IUCV socket support") Signed-off-by: Julian Wiedmann --- net/iucv/af_iucv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 047238f01ba6..db7d888914fa 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c @@ -1645,7 +1645,7 @@ static int iucv_callback_connreq(struct iucv_path *path, } /* Create the new socket */ - nsk = iucv_sock_alloc(NULL, sk->sk_type, GFP_ATOMIC, 0); + nsk = iucv_sock_alloc(NULL, sk->sk_protocol, GFP_ATOMIC, 0); if (!nsk) { err = pr_iucv->path_sever(path, user_data); iucv_path_free(path); @@ -1851,7 +1851,7 @@ static int afiucv_hs_callback_syn(struct sock *sk, struct sk_buff *skb) goto out; } - nsk = iucv_sock_alloc(NULL, sk->sk_type, GFP_ATOMIC, 0); + nsk = iucv_sock_alloc(NULL, sk->sk_protocol, GFP_ATOMIC, 0); bh_lock_sock(sk); if ((sk->sk_state != IUCV_LISTEN) || sk_acceptq_is_full(sk) || -- 2.17.1
Re: [PATCH net-next V3] MAINTAINERS: Update XDP and AF_XDP entries
On 2020-11-20 09:53, Jesper Dangaard Brouer wrote: Getting too many false positive matches with current use of the content regex K: and file regex N: patterns. This patch drops file match N: and makes K: more restricted. Some more normal F: file wildcards are added. Notice that AF_XDP forgot to some F: files that is also updated in this patch. Suggested-by: Jakub Kicinski Signed-off-by: Jesper Dangaard Brouer Thanks Jesper! Acked-by: Björn Töpel --- MAINTAINERS | 12 ++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index af9f6a3ab100..f827f504251b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -19105,12 +19105,17 @@ L:netdev@vger.kernel.org L:b...@vger.kernel.org S:Supported F:include/net/xdp.h +F: include/net/xdp_priv.h F:include/trace/events/xdp.h F:kernel/bpf/cpumap.c F:kernel/bpf/devmap.c F:net/core/xdp.c -N: xdp -K: xdp +F: samples/bpf/xdp* +F: tools/testing/selftests/bpf/*xdp* +F: tools/testing/selftests/bpf/*/*xdp* +F: drivers/net/ethernet/*/*/*/*/*xdp* +F: drivers/net/ethernet/*/*/*xdp* +K: (?:\b|_)xdp(?:\b|_) XDP SOCKETS (AF_XDP) M:Björn Töpel @@ -19119,9 +19124,12 @@ R: Jonathan Lemon L:netdev@vger.kernel.org L:b...@vger.kernel.org S:Maintained +F: Documentation/networking/af_xdp.rst F:include/net/xdp_sock* F:include/net/xsk_buff_pool.h F:include/uapi/linux/if_xdp.h +F: include/uapi/linux/xdp_diag.h +F: include/net/netns/xdp.h F:net/xdp/ F:samples/bpf/xdpsock* F:tools/lib/bpf/xsk*
Re: [PATCH net-next] ip_gre: remove CRC flag from dev features in gre_gso_segment
On Fri, Nov 20, 2020 at 1:24 AM Alexander Duyck wrote: > > On Wed, Nov 18, 2020 at 9:53 PM Xin Long wrote: > > > > On Thu, Nov 19, 2020 at 4:35 AM Alexander Duyck > > wrote: > > > > > > On Mon, Nov 16, 2020 at 1:17 AM Xin Long wrote: > > > > > > > > This patch is to let it always do CRC checksum in sctp_gso_segment() > > > > by removing CRC flag from the dev features in gre_gso_segment() for > > > > SCTP over GRE, just as it does in Commit 527beb8ef9c0 ("udp: support > > > > sctp over udp in skb_udp_tunnel_segment") for SCTP over UDP. > > > > It could set csum/csum_start in GSO CB properly in sctp_gso_segment() > > > > after that commit, so it would do checksum with gso_make_checksum() > > > > in gre_gso_segment(), and Commit 622e32b7d4a6 ("net: gre: recompute > > > > gre csum for sctp over gre tunnels") can be reverted now. > > > > > > > > Signed-off-by: Xin Long > > > > --- > > > > net/ipv4/gre_offload.c | 14 +++--- > > > > 1 file changed, 3 insertions(+), 11 deletions(-) > > > > > > > > diff --git a/net/ipv4/gre_offload.c b/net/ipv4/gre_offload.c > > > > index e0a2465..a5935d4 100644 > > > > --- a/net/ipv4/gre_offload.c > > > > +++ b/net/ipv4/gre_offload.c > > > > @@ -15,12 +15,12 @@ static struct sk_buff *gre_gso_segment(struct > > > > sk_buff *skb, > > > >netdev_features_t features) > > > > { > > > > int tnl_hlen = skb_inner_mac_header(skb) - > > > > skb_transport_header(skb); > > > > - bool need_csum, need_recompute_csum, gso_partial; > > > > struct sk_buff *segs = ERR_PTR(-EINVAL); > > > > u16 mac_offset = skb->mac_header; > > > > __be16 protocol = skb->protocol; > > > > u16 mac_len = skb->mac_len; > > > > int gre_offset, outer_hlen; > > > > + bool need_csum, gso_partial; > > > > > > > > if (!skb->encapsulation) > > > > goto out; > > > > @@ -41,10 +41,10 @@ static struct sk_buff *gre_gso_segment(struct > > > > sk_buff *skb, > > > > skb->protocol = skb->inner_protocol; > > > > > > > > need_csum = !!(skb_shinfo(skb)->gso_type & SKB_GSO_GRE_CSUM); > > > > - need_recompute_csum = skb->csum_not_inet; > > > > skb->encap_hdr_csum = need_csum; > > > > > > > > features &= skb->dev->hw_enc_features; > > > > + features &= ~NETIF_F_SCTP_CRC; > > > > > > > > /* segment inner packet. */ > > > > segs = skb_mac_gso_segment(skb, features); > > > > > > Why just blindly strip NETIF_F_SCTP_CRC? It seems like it would make > > > more sense if there was an explanation as to why you are stripping the > > > offload. I know there are many NICs that could very easily perform > > > SCTP CRC offload on the inner data as long as they didn't have to > > > offload the outer data. For example the Intel NICs should be able to > > > do it, although when I wrote the code up enabling their offloads I > > > think it is only looking at the outer headers so that might require > > > updating to get it to not use the software fallback. > > > > > > It really seems like we should only be clearing NETIF_F_SCTP_CRC if > > > need_csum is true since we must compute the CRC before we can compute > > > the GRE checksum. > > Right, it's also what Jakub commented, thanks. > > > > > > > > > @@ -99,15 +99,7 @@ static struct sk_buff *gre_gso_segment(struct > > > > sk_buff *skb, > > > > } > > > > > > > > *(pcsum + 1) = 0; > > > > - if (need_recompute_csum && !skb_is_gso(skb)) { > > > > - __wsum csum; > > > > - > > > > - csum = skb_checksum(skb, gre_offset, > > > > - skb->len - gre_offset, 0); > > > > - *pcsum = csum_fold(csum); > > > > - } else { > > > > - *pcsum = gso_make_checksum(skb, 0); > > > > - } > > > > + *pcsum = gso_make_checksum(skb, 0); > > > > } while ((skb = skb->next)); > > > > out: > > > > return segs; > > > > > > This change doesn't make much sense to me. How are we expecting > > > gso_make_checksum to be able to generate a valid checksum when we are > > > dealing with a SCTP frame? From what I can tell it looks like it is > > > just setting the checksum to ~0 and checksum start to the transport > > > header which isn't true because SCTP is using a CRC, not a 1's > > > complement checksum, or am I missing something? As such in order to > > > get the gre checksum we would need to compute it over the entire > > > payload data wouldn't we? Has this been tested with an actual GRE > > > tunnel that had checksums enabled? If so was it verified that the GSO > > > frames were actually being segmented at the NIC level and not at the > > > GRE tunnel level? > > Hi Alex, > > > > I think you're looking at net.git? As on net-next.git, > > sctp_gso_make_checksum() > > has been fixed to set csum/csum_start properly by C
Re: net: phy: Dealing with 88e1543 dual-port mode
On Fri, Nov 20, 2020 at 10:36:01AM +0100, Maxime Chevallier wrote: > So maybe we could be a bit more generic, with something along these lines : > > ethernet-phy@0 { > ... > > mdi { > port@0 { > media = "10baseT", "100baseT", "1000baseT"; > pairs = <1>; > }; > > port@1 { > media = "1000baseX", "10gbaseR" > }; > }; > }; Don't forget that TP requires a minimum of two pairs. However, as Andrew pointed out, we already have max-speed which can be used to limit the speed below that which requires four pairs. I have untested patches that allow the 88x3310 to be reconfigured between 10GBASE-R and 1000BASE-X depending on the SFP connected - untested because the I2C pull-ups on the Macchiatobin boards I have are way too strong and it results in SFP EEPROM corruption and/or failure to read the EEPROM. > I also like the idea of having a way to express the "preferred" media, > although I wonder if that's something we want to include in DT or that > we would want to tweak at runtime, through ethtool for example. I think preferred media should be configurable through ethtool - which is preferred will be specific to the user's application. However, there may be scope for DT to be able to specify the default preferred media. -- RMK's Patch system: https://www.armlinux.org.uk/developer/patches/ FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
[PATCH net] vsock/virtio: discard packets only when socket is really closed
Starting from commit 8692cefc433f ("virtio_vsock: Fix race condition in virtio_transport_recv_pkt"), we discard packets in virtio_transport_recv_pkt() if the socket has been released. When the socket is connected, we schedule a delayed work to wait the RST packet from the other peer, also if SHUTDOWN_MASK is set in sk->sk_shutdown. This is done to complete the virtio-vsock shutdown algorithm, releasing the port assigned to the socket definitively only when the other peer has consumed all the packets. If we discard the RST packet received, the socket will be closed only when the VSOCK_CLOSE_TIMEOUT is reached. Sergio discovered the issue while running ab(1) HTTP benchmark using libkrun [1] and observing a latency increase with that commit. To avoid this issue, we discard packet only if the socket is really closed (SOCK_DONE flag is set). We also set SOCK_DONE in virtio_transport_release() when we don't need to wait any packets from the other peer (we didn't schedule the delayed work). In this case we remove the socket from the vsock lists, releasing the port assigned. [1] https://github.com/containers/libkrun Fixes: 8692cefc433f ("virtio_vsock: Fix race condition in virtio_transport_recv_pkt") Cc: justin...@arm.com Reported-by: Sergio Lopez Tested-by: Sergio Lopez Signed-off-by: Stefano Garzarella --- net/vmw_vsock/virtio_transport_common.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c index 0edda1edf988..5956939eebb7 100644 --- a/net/vmw_vsock/virtio_transport_common.c +++ b/net/vmw_vsock/virtio_transport_common.c @@ -841,8 +841,10 @@ void virtio_transport_release(struct vsock_sock *vsk) virtio_transport_free_pkt(pkt); } - if (remove_sock) + if (remove_sock) { + sock_set_flag(sk, SOCK_DONE); vsock_remove_sock(vsk); + } } EXPORT_SYMBOL_GPL(virtio_transport_release); @@ -1132,8 +1134,8 @@ void virtio_transport_recv_pkt(struct virtio_transport *t, lock_sock(sk); - /* Check if sk has been released before lock_sock */ - if (sk->sk_shutdown == SHUTDOWN_MASK) { + /* Check if sk has been closed before lock_sock */ + if (sock_flag(sk, SOCK_DONE)) { (void)virtio_transport_reset_no_sock(t, pkt); release_sock(sk); sock_put(sk); -- 2.26.2
Re: net: phy: Dealing with 88e1543 dual-port mode
On Fri, Nov 20, 2020 at 10:25, Russell King - ARM Linux admin wrote: > On Fri, Nov 20, 2020 at 10:36:01AM +0100, Maxime Chevallier wrote: >> So maybe we could be a bit more generic, with something along these lines : >> >> ethernet-phy@0 { >> ... >> >> mdi { >> port@0 { >> media = "10baseT", "100baseT", "1000baseT"; >> pairs = <1>; >> }; >> >> port@1 { >> media = "1000baseX", "10gbaseR" >> }; >> }; >> }; Yeah that looks even better. Though "pairs" is redundant if you can specify the list of supported link modes. I guess not specifying "media" should mean "use all modes supported by the PHY". And if, for example, media is set to 10-T+100-TX, that means that only two pairs will be used. > Don't forget that TP requires a minimum of two pairs. However, as > Andrew pointed out, we already have max-speed which can be used to > limit the speed below that which requires four pairs. Maybe "max-speed" is how you solve this in the absense of explicit an MDI declaration? Because in the multi-port case, the setting could be different for the two ports, so you would source the information from the "media" property instead. > I have untested patches that allow the 88x3310 to be reconfigured > between 10GBASE-R and 1000BASE-X depending on the SFP connected - > untested because the I2C pull-ups on the Macchiatobin boards I have > are way too strong and it results in SFP EEPROM corruption and/or > failure to read the EEPROM. > >> I also like the idea of having a way to express the "preferred" media, >> although I wonder if that's something we want to include in DT or that >> we would want to tweak at runtime, through ethtool for example. > > I think preferred media should be configurable through ethtool - > which is preferred will be specific to the user's application. Yeah I half-regretted putting that in there right after I hit "send" :) It should definitely be configurable from ethtool. > However, there may be scope for DT to be able to specify the default > preferred media. This is where I was coming from. The vendor could potentially have more information on what the default should be. But I guess you could also argue that there is value in having Linux behave the same across all devices.
Re: [PATCH v2] brcmfmac: expose firmware config files through modinfo
On 20/11/2020 11:05, Dmitry Osipenko wrote: 20.11.2020 12:52, matthias@kernel.org пишет: From: Matthias Brugger Apart from a firmware binary the chip needs a config file used by the FW. Add the config files to modinfo so that they can be read by userspace. Signed-off-by: Matthias Brugger --- Changes in v2: In comparison to first version [0] we use wildcards to enumerate the firmware configuration files. Wildcard support was added to dracut recently [1]. [0] https://lore.kernel.org/linux-wireless/20200701153123.25602-1-matthias@kernel.org/ [1] https://github.com/dracutdevs/dracut/pull/860 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index 99987a789e7e..dd6d287b1b00 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -625,6 +625,15 @@ BRCMF_FW_DEF(4359, "brcmfmac4359-sdio"); BRCMF_FW_DEF(4373, "brcmfmac4373-sdio"); BRCMF_FW_DEF(43012, "brcmfmac43012-sdio"); +/* firmware config files */ +MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcm/brcmfmac4330-sdio.*.txt"); +MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcm/brcmfmac43340-sdio.*.txt"); +MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcm/brcmfmac43362-sdio.*.txt"); +MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcm/brcmfmac43430a0-sdio.*.txt"); +MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcm/brcmfmac43430-sdio.*.txt"); +MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcm/brcmfmac43455-sdio.*.txt"); +MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcm/brcmfmac4356-pcie.*.txt"); This doesn't cover all hardware models. Note that the upstream linux-firmware has files only for a few hardware models. I suppose that the correct mask should be "brcm/brcmfmac*-sdio.*.txt". We can use the two "brcm/brcmfmac*-sdio.*.txt" and "brcm/brcmfmac*-pcie.*.txt" to also include firmware files for chips that don't have any config file in linux-firmware. I'm indifferent to that, although I think we should make incentivize to upstream firmware config files to linux-firmware. Regards, Matthias
[PATCH v8] tcp: fix race condition when creating child sockets from syncookies
When the TCP stack is in SYN flood mode, the server child socket is created from the SYN cookie received in a TCP packet with the ACK flag set. The child socket is created when the server receives the first TCP packet with a valid SYN cookie from the client. Usually, this packet corresponds to the final step of the TCP 3-way handshake, the ACK packet. But is also possible to receive a valid SYN cookie from the first TCP data packet sent by the client, and thus create a child socket from that SYN cookie. Since a client socket is ready to send data as soon as it receives the SYN+ACK packet from the server, the client can send the ACK packet (sent by the TCP stack code), and the first data packet (sent by the userspace program) almost at the same time, and thus the server will equally receive the two TCP packets with valid SYN cookies almost at the same instant. When such event happens, the TCP stack code has a race condition that occurs between the momement a lookup is done to the established connections hashtable to check for the existence of a connection for the same client, and the moment that the child socket is added to the established connections hashtable. As a consequence, this race condition can lead to a situation where we add two child sockets to the established connections hashtable and deliver two sockets to the userspace program to the same client. This patch fixes the race condition by checking if an existing child socket exists for the same client when we are adding the second child socket to the established connections socket. If an existing child socket exists, we drop the packet and discard the second child socket to the same client. Signed-off-by: Ricardo Dias --- v8 (2020-11-20): * Implemented the approach suggested by Eric where we drop the packet in case we found an already existing socket for the same connection. * Updated the commit message to match the new approach. v7 (2020-11-19): * Changed the approach to re-use the first (existing) socket created from thge syncookie. Instead of returning the existing socket in tcp_(v4|v6)_syn_recv_sock and continue the protocol state machine execution, tcp_(v4|v6)_syn_recv_sock signals that already exists a socket, and tells tcp_(v4|v6)_rcv to lookup the socket again in the established connections table. This new approach fixes the errors reported by Eric for the previous version of the patch. * Also fixes the memory leaks by making sure that the newly created socket in syn_recv_sock is destroyed in case an already existing socket exists. v6 (2020-11-17): * Moved the ehash bucket list search for its own helper function. v5 (2020-11-16): - Not considered for review - v4 (2020-11-12): * Added `struct sock **esk) parameter to `inet_ehash_insert`. * Fixed ref count increment in `inet_ehash_insert`. * Fixed callers of inet_ehash_nolisten. v3 (2020-11-11): * Fixed IPv6 handling in inet_ehash_insert * Removed unecessary comparison while traversing the ehash bucket list. v2 (2020-11-09): * Changed the author's email domain. * Removed the helper function inet_ehash_insert_chk_dup and moved the logic to the existing inet_ehash_insert. * Updated the callers of iner_ehash_nolisten to deal with the new logic. include/net/inet_hashtables.h | 5 ++- net/dccp/ipv4.c | 2 +- net/dccp/ipv6.c | 2 +- net/ipv4/inet_connection_sock.c | 2 +- net/ipv4/inet_hashtables.c | 68 + net/ipv4/tcp_ipv4.c | 15 +++- net/ipv6/tcp_ipv6.c | 13 ++- 7 files changed, 91 insertions(+), 16 deletions(-) diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index 92560974ea67..ca6a3ea9057e 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h @@ -247,8 +247,9 @@ void inet_hashinfo2_init(struct inet_hashinfo *h, const char *name, unsigned long high_limit); int inet_hashinfo2_init_mod(struct inet_hashinfo *h); -bool inet_ehash_insert(struct sock *sk, struct sock *osk); -bool inet_ehash_nolisten(struct sock *sk, struct sock *osk); +bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk); +bool inet_ehash_nolisten(struct sock *sk, struct sock *osk, +bool *found_dup_sk); int __inet_hash(struct sock *sk, struct sock *osk); int inet_hash(struct sock *sk); void inet_unhash(struct sock *sk); diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 9c28c8251125..098bae35ab76 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -427,7 +427,7 @@ struct sock *dccp_v4_request_recv_sock(const struct sock *sk, if (__inet_inherit_port(sk, newsk) < 0) goto put_and_exit; - *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash)); + *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash), NULL); if (*own_req) ireq->i
[PATCH net-next] net: bridge: switch to net core statistics counters handling
Use netdev->tstats instead of a member of net_bridge for storing a pointer to the per-cpu counters. This allows us to use core functionality for statistics handling. Signed-off-by: Heiner Kallweit --- net/bridge/br_device.c | 31 +-- net/bridge/br_input.c | 6 +- net/bridge/br_private.h | 1 - 3 files changed, 10 insertions(+), 28 deletions(-) diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 77bcc8487..adb674a86 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -30,7 +30,6 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) struct net_bridge *br = netdev_priv(dev); struct net_bridge_fdb_entry *dst; struct net_bridge_mdb_entry *mdst; - struct pcpu_sw_netstats *brstats = this_cpu_ptr(br->stats); const struct nf_br_ops *nf_ops; u8 state = BR_STATE_FORWARDING; const unsigned char *dest; @@ -45,10 +44,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } - u64_stats_update_begin(&brstats->syncp); - brstats->tx_packets++; - brstats->tx_bytes += skb->len; - u64_stats_update_end(&brstats->syncp); + dev_sw_netstats_tx_add(dev, 1, skb->len); br_switchdev_frame_unmark(skb); BR_INPUT_SKB_CB(skb)->brdev = dev; @@ -119,26 +115,26 @@ static int br_dev_init(struct net_device *dev) struct net_bridge *br = netdev_priv(dev); int err; - br->stats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); - if (!br->stats) + dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); + if (!dev->tstats) return -ENOMEM; err = br_fdb_hash_init(br); if (err) { - free_percpu(br->stats); + free_percpu(dev->tstats); return err; } err = br_mdb_hash_init(br); if (err) { - free_percpu(br->stats); + free_percpu(dev->tstats); br_fdb_hash_fini(br); return err; } err = br_vlan_init(br); if (err) { - free_percpu(br->stats); + free_percpu(dev->tstats); br_mdb_hash_fini(br); br_fdb_hash_fini(br); return err; @@ -146,7 +142,7 @@ static int br_dev_init(struct net_device *dev) err = br_multicast_init_stats(br); if (err) { - free_percpu(br->stats); + free_percpu(dev->tstats); br_vlan_flush(br); br_mdb_hash_fini(br); br_fdb_hash_fini(br); @@ -165,7 +161,7 @@ static void br_dev_uninit(struct net_device *dev) br_vlan_flush(br); br_mdb_hash_fini(br); br_fdb_hash_fini(br); - free_percpu(br->stats); + free_percpu(dev->tstats); } static int br_dev_open(struct net_device *dev) @@ -202,15 +198,6 @@ static int br_dev_stop(struct net_device *dev) return 0; } -static void br_get_stats64(struct net_device *dev, - struct rtnl_link_stats64 *stats) -{ - struct net_bridge *br = netdev_priv(dev); - - netdev_stats_to_stats64(stats, &dev->stats); - dev_fetch_sw_netstats(stats, br->stats); -} - static int br_change_mtu(struct net_device *dev, int new_mtu) { struct net_bridge *br = netdev_priv(dev); @@ -404,7 +391,7 @@ static const struct net_device_ops br_netdev_ops = { .ndo_init= br_dev_init, .ndo_uninit = br_dev_uninit, .ndo_start_xmit = br_dev_xmit, - .ndo_get_stats64 = br_get_stats64, + .ndo_get_stats64 = dev_get_tstats64, .ndo_set_mac_address = br_set_mac_address, .ndo_set_rx_mode = br_dev_set_multicast_list, .ndo_change_rx_flags = br_dev_change_rx_flags, diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 21808985f..8ca1f1bc6 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -35,12 +35,8 @@ static int br_pass_frame_up(struct sk_buff *skb) struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev; struct net_bridge *br = netdev_priv(brdev); struct net_bridge_vlan_group *vg; - struct pcpu_sw_netstats *brstats = this_cpu_ptr(br->stats); - u64_stats_update_begin(&brstats->syncp); - brstats->rx_packets++; - brstats->rx_bytes += skb->len; - u64_stats_update_end(&brstats->syncp); + dev_sw_netstats_rx_add(brdev, skb->len); vg = br_vlan_group_rcu(br); /* Bridge is just like any other port. Make sure the diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 6f2818cb2..9a99af59b 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -385,7 +385,6 @@ struct net_bridge { spinlock_t hash_lock; struct hlist_head
[PATCH net-next 0/4] dt-bindings: net: dsa: microchip: convert KSZ bindings to yaml
These patches are orginally from the series "net: dsa: microchip: PTP support for KSZ956x" As the the device tree conversion to yaml is not really related to the PTP patches and the original series is going to take more time than I expected, I would like to split this. Changes (original series -> v1) - dts: moved "allOf" below "maintainers" - dts: use "unevaluatedProperties" instead of "additionalProperties" - dts: removed "spi-cpha" and "spi-cpol" flags as the hardware is fixed - ksz8795: setup SPI for mode 3 - ksz9477: dito
[PATCH net-next 1/4] dt-bindings: net: dsa: convert ksz bindings document to yaml
Convert the bindings document for Microchip KSZ Series Ethernet switches from txt to yaml. Removed spi-cpha and spi-cpol flags is this should be handled by the device driver. Signed-off-by: Christian Eggers --- .../devicetree/bindings/net/dsa/ksz.txt | 125 --- .../bindings/net/dsa/microchip,ksz.yaml | 148 ++ MAINTAINERS | 2 +- 3 files changed, 149 insertions(+), 126 deletions(-) delete mode 100644 Documentation/devicetree/bindings/net/dsa/ksz.txt create mode 100644 Documentation/devicetree/bindings/net/dsa/microchip,ksz.yaml diff --git a/Documentation/devicetree/bindings/net/dsa/ksz.txt b/Documentation/devicetree/bindings/net/dsa/ksz.txt deleted file mode 100644 index 95e91e84151c.. --- a/Documentation/devicetree/bindings/net/dsa/ksz.txt +++ /dev/null @@ -1,125 +0,0 @@ -Microchip KSZ Series Ethernet switches -== - -Required properties: - -- compatible: For external switch chips, compatible string must be exactly one - of the following: - - "microchip,ksz8765" - - "microchip,ksz8794" - - "microchip,ksz8795" - - "microchip,ksz9477" - - "microchip,ksz9897" - - "microchip,ksz9896" - - "microchip,ksz9567" - - "microchip,ksz8565" - - "microchip,ksz9893" - - "microchip,ksz9563" - - "microchip,ksz8563" - -Optional properties: - -- reset-gpios : Should be a gpio specifier for a reset line -- microchip,synclko-125 : Set if the output SYNCLKO frequency should be set to - 125MHz instead of 25MHz. - -See Documentation/devicetree/bindings/net/dsa/dsa.txt for a list of additional -required and optional properties. - -Examples: - -Ethernet switch connected via SPI to the host, CPU port wired to eth0: - - eth0: ethernet@10001000 { - fixed-link { - speed = <1000>; - full-duplex; - }; - }; - - spi1: spi@f8008000 { - pinctrl-0 = <&pinctrl_spi_ksz>; - cs-gpios = <&pioC 25 0>; - id = <1>; - - ksz9477: ksz9477@0 { - compatible = "microchip,ksz9477"; - reg = <0>; - - spi-max-frequency = <4400>; - spi-cpha; - spi-cpol; - - ports { - #address-cells = <1>; - #size-cells = <0>; - port@0 { - reg = <0>; - label = "lan1"; - }; - port@1 { - reg = <1>; - label = "lan2"; - }; - port@2 { - reg = <2>; - label = "lan3"; - }; - port@3 { - reg = <3>; - label = "lan4"; - }; - port@4 { - reg = <4>; - label = "lan5"; - }; - port@5 { - reg = <5>; - label = "cpu"; - ethernet = <ð0>; - fixed-link { - speed = <1000>; - full-duplex; - }; - }; - }; - }; - ksz8565: ksz8565@0 { - compatible = "microchip,ksz8565"; - reg = <0>; - - spi-max-frequency = <4400>; - spi-cpha; - spi-cpol; - - ports { - #address-cells = <1>; - #size-cells = <0>; - port@0 { - reg = <0>; - label = "lan1"; - }; - port@1 { - reg = <1>; - label = "lan2"; - }; - port@2 { - reg = <2>; - label = "lan3"; - }; - port@3 { - reg = <3>; -
[PATCH net-next 2/4] net: dsa: microchip: support for "ethernet-ports" node
The dsa.yaml device tree binding allows "ethernet-ports" (preferred) and "ports". Signed-off-by: Christian Eggers Reviewed-by: Vladimir Oltean --- drivers/net/dsa/microchip/ksz_common.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index 71cd1828e25d..a135fd5a9264 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -427,7 +427,9 @@ int ksz_switch_register(struct ksz_device *dev, ret = of_get_phy_mode(dev->dev->of_node, &interface); if (ret == 0) dev->compat_interface = interface; - ports = of_get_child_by_name(dev->dev->of_node, "ports"); + ports = of_get_child_by_name(dev->dev->of_node, "ethernet-ports"); + if (!ports) + ports = of_get_child_by_name(dev->dev->of_node, "ports"); if (ports) for_each_available_child_of_node(ports, port) { if (of_property_read_u32(port, "reg", -- Christian Eggers Embedded software developer Arnold & Richter Cine Technik GmbH & Co. Betriebs KG Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRA 57918 Persoenlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRB 54477 Geschaeftsfuehrer: Dr. Michael Neuhaeuser; Stephan Schenk; Walter Trauninger; Markus Zeiler
[PATCH net-next 3/4] net: dsa: microchip: ksz9477: setup SPI mode
This should be done in the device driver instead of the device tree. Signed-off-by: Christian Eggers --- drivers/net/dsa/microchip/ksz9477_spi.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/dsa/microchip/ksz9477_spi.c b/drivers/net/dsa/microchip/ksz9477_spi.c index 1142768969c2..15bc11b3cda4 100644 --- a/drivers/net/dsa/microchip/ksz9477_spi.c +++ b/drivers/net/dsa/microchip/ksz9477_spi.c @@ -48,6 +48,12 @@ static int ksz9477_spi_probe(struct spi_device *spi) if (spi->dev.platform_data) dev->pdata = spi->dev.platform_data; + /* setup spi */ + spi->mode = SPI_MODE_3; + ret = spi_setup(spi); + if (ret) + return ret; + ret = ksz9477_switch_register(dev); /* Main DSA driver may not be started yet. */ -- Christian Eggers Embedded software developer Arnold & Richter Cine Technik GmbH & Co. Betriebs KG Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRA 57918 Persoenlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRB 54477 Geschaeftsfuehrer: Dr. Michael Neuhaeuser; Stephan Schenk; Walter Trauninger; Markus Zeiler
[PATCH net-next 4/4] net: dsa: microchip: ksz8795: setup SPI mode
This should be done in the device driver instead of the device tree. Signed-off-by: Christian Eggers --- drivers/net/dsa/microchip/ksz8795_spi.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/dsa/microchip/ksz8795_spi.c b/drivers/net/dsa/microchip/ksz8795_spi.c index 8b00f8e6c02f..f98432a3e2b5 100644 --- a/drivers/net/dsa/microchip/ksz8795_spi.c +++ b/drivers/net/dsa/microchip/ksz8795_spi.c @@ -49,6 +49,12 @@ static int ksz8795_spi_probe(struct spi_device *spi) if (spi->dev.platform_data) dev->pdata = spi->dev.platform_data; + /* setup spi */ + spi->mode = SPI_MODE_3; + ret = spi_setup(spi); + if (ret) + return ret; + ret = ksz8795_switch_register(dev); /* Main DSA driver may not be started yet. */ -- Christian Eggers Embedded software developer Arnold & Richter Cine Technik GmbH & Co. Betriebs KG Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRA 57918 Persoenlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRB 54477 Geschaeftsfuehrer: Dr. Michael Neuhaeuser; Stephan Schenk; Walter Trauninger; Markus Zeiler
[PATCH net] MAINTAINERS: Change Solarflare maintainers
Email from solarflare.com will stop working. Update the maintainers. A replacement for linux-net-driv...@solarflare.com is not working yet, for now remove it. Signed-off-by: Martin Habets Signed-off-by: Edward Cree --- MAINTAINERS |5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 8cb1aae96bdf..72eb0525c88f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15790,9 +15790,8 @@ F: drivers/slimbus/ F: include/linux/slimbus.h SFC NETWORK DRIVER -M: Solarflare linux maintainers -M: Edward Cree -M: Martin Habets +M: Edward Cree +M: Martin Habets L: netdev@vger.kernel.org S: Supported F: drivers/net/ethernet/sfc/
[PATCH bpf] xsk: fix umem cleanup bug at socket destruct
From: Magnus Karlsson Fix a bug that is triggered when a partially setup socket is destroyed. For a fully setup socket, a socket that has been bound to a device, the cleanup of the umem is performed at the end of the buffer pool's cleanup work queue item. This has to be performed in a work queue, and not in RCU cleanup, as it is doing a vunmap that cannot execute in interrupt context. However, when a socket has only been partially set up so that a umem has been created but the buffer pool has not, the code erroneously directly calls the umem cleanup function instead of using a work queue, and this leads to a BUG_ON() in vunmap(). As there in this case is no buffer pool, we cannot use its work queue, so we need to introduce a work queue for the umem and schedule this for the cleanup. So in the case there is no pool, we are going to use the umem's own work queue to schedule the cleanup. But if there is a pool, the cleanup of the umem is still being performed by the pool's work queue, as it is important that the umem is cleaned up after the pool. Fixes: e5e1a4bc916d ("xsk: Fix possible memory leak at socket close") Reported-by: Marek Majtyka Tested-by: Marek Majtyka Signed-off-by: Magnus Karlsson --- include/net/xdp_sock.h | 1 + net/xdp/xdp_umem.c | 19 --- net/xdp/xdp_umem.h | 2 +- net/xdp/xsk.c | 2 +- net/xdp/xsk_buff_pool.c | 2 +- 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/include/net/xdp_sock.h b/include/net/xdp_sock.h index 1a9559c..4f4e93b 100644 --- a/include/net/xdp_sock.h +++ b/include/net/xdp_sock.h @@ -31,6 +31,7 @@ struct xdp_umem { struct page **pgs; int id; struct list_head xsk_dma_list; + struct work_struct work; }; struct xsk_map { diff --git a/net/xdp/xdp_umem.c b/net/xdp/xdp_umem.c index 56d052b..56a28a6 100644 --- a/net/xdp/xdp_umem.c +++ b/net/xdp/xdp_umem.c @@ -66,18 +66,31 @@ static void xdp_umem_release(struct xdp_umem *umem) kfree(umem); } +static void xdp_umem_release_deferred(struct work_struct *work) +{ + struct xdp_umem *umem = container_of(work, struct xdp_umem, work); + + xdp_umem_release(umem); +} + void xdp_get_umem(struct xdp_umem *umem) { refcount_inc(&umem->users); } -void xdp_put_umem(struct xdp_umem *umem) +void xdp_put_umem(struct xdp_umem *umem, bool defer_cleanup) { if (!umem) return; - if (refcount_dec_and_test(&umem->users)) - xdp_umem_release(umem); + if (refcount_dec_and_test(&umem->users)) { + if (defer_cleanup) { + INIT_WORK(&umem->work, xdp_umem_release_deferred); + schedule_work(&umem->work); + } else { + xdp_umem_release(umem); + } + } } static int xdp_umem_pin_pages(struct xdp_umem *umem, unsigned long address) diff --git a/net/xdp/xdp_umem.h b/net/xdp/xdp_umem.h index 181fdda..aa9fe27 100644 --- a/net/xdp/xdp_umem.h +++ b/net/xdp/xdp_umem.h @@ -9,7 +9,7 @@ #include void xdp_get_umem(struct xdp_umem *umem); -void xdp_put_umem(struct xdp_umem *umem); +void xdp_put_umem(struct xdp_umem *umem, bool defer_cleanup); struct xdp_umem *xdp_umem_create(struct xdp_umem_reg *mr); #endif /* XDP_UMEM_H_ */ diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c index cfbec39..5a6cdf7 100644 --- a/net/xdp/xsk.c +++ b/net/xdp/xsk.c @@ -1147,7 +1147,7 @@ static void xsk_destruct(struct sock *sk) return; if (!xp_put_pool(xs->pool)) - xdp_put_umem(xs->umem); + xdp_put_umem(xs->umem, !xs->pool); sk_refcnt_debug_dec(sk); } diff --git a/net/xdp/xsk_buff_pool.c b/net/xdp/xsk_buff_pool.c index 8a3bf4e..3c5a142 100644 --- a/net/xdp/xsk_buff_pool.c +++ b/net/xdp/xsk_buff_pool.c @@ -242,7 +242,7 @@ static void xp_release_deferred(struct work_struct *work) pool->cq = NULL; } - xdp_put_umem(pool->umem); + xdp_put_umem(pool->umem, false); xp_destroy(pool); } -- 2.7.4
Re: [PATCH V5 5/5] can: flexcan: add CAN wakeup function for i.MX8QM
On 11/6/20 11:56 AM, Joakim Zhang wrote: > The System Controller Firmware (SCFW) is a low-level system function > which runs on a dedicated Cortex-M core to provide power, clock, and > resource management. It exists on some i.MX8 processors. e.g. i.MX8QM > (QM, QP), and i.MX8QX (QXP, DX). SCU driver manages the IPC interface > between host CPU and the SCU firmware running on M4. > > For i.MX8QM, stop mode request is controlled by System Controller Unit(SCU) > firmware, this patch introduces FLEXCAN_QUIRK_SETUP_STOP_MODE_SCFW quirk > for this function. > > Signed-off-by: Joakim Zhang Who is upstreaming this? Marc -- Pengutronix e.K. | Marc Kleine-Budde | Embedded Linux | https://www.pengutronix.de | Vertretung West/Dortmund | Phone: +49-231-2826-924 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | signature.asc Description: OpenPGP digital signature
[PATCH net-next,v5 1/9] netfilter: flowtable: add hash offset field to tuple
Add a placeholder field to calculate hash tuple offset. Similar to 2c407aca6497 ("netfilter: conntrack: avoid gcc-10 zero-length-bounds warning"). Signed-off-by: Pablo Neira Ayuso --- v5: no changes include/net/netfilter/nf_flow_table.h | 4 net/netfilter/nf_flow_table_core.c| 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h index 16e8b2f8d006..54c4d5c908a5 100644 --- a/include/net/netfilter/nf_flow_table.h +++ b/include/net/netfilter/nf_flow_table.h @@ -107,6 +107,10 @@ struct flow_offload_tuple { u8 l3proto; u8 l4proto; + + /* All members above are keys for lookups, see flow_offload_hash(). */ + struct { } __hash; + u8 dir; u16 mtu; diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c index 513f78db3cb2..55fca71ace26 100644 --- a/net/netfilter/nf_flow_table_core.c +++ b/net/netfilter/nf_flow_table_core.c @@ -191,14 +191,14 @@ static u32 flow_offload_hash(const void *data, u32 len, u32 seed) { const struct flow_offload_tuple *tuple = data; - return jhash(tuple, offsetof(struct flow_offload_tuple, dir), seed); + return jhash(tuple, offsetof(struct flow_offload_tuple, __hash), seed); } static u32 flow_offload_hash_obj(const void *data, u32 len, u32 seed) { const struct flow_offload_tuple_rhash *tuplehash = data; - return jhash(&tuplehash->tuple, offsetof(struct flow_offload_tuple, dir), seed); + return jhash(&tuplehash->tuple, offsetof(struct flow_offload_tuple, __hash), seed); } static int flow_offload_hash_cmp(struct rhashtable_compare_arg *arg, @@ -207,7 +207,7 @@ static int flow_offload_hash_cmp(struct rhashtable_compare_arg *arg, const struct flow_offload_tuple *tuple = arg->key; const struct flow_offload_tuple_rhash *x = ptr; - if (memcmp(&x->tuple, tuple, offsetof(struct flow_offload_tuple, dir))) + if (memcmp(&x->tuple, tuple, offsetof(struct flow_offload_tuple, __hash))) return 1; return 0; -- 2.20.1
[PATCH net-next,v5 7/9] netfilter: flowtable: use dev_fill_forward_path() to obtain egress device
The egress device in the tuple is obtained from route. Use dev_fill_forward_path() instead to provide the real egress device for this flow whenever this is available. The new FLOW_OFFLOAD_XMIT_DIRECT type uses dev_queue_xmit() to transmit ethernet frames. Cache the source and destination hardware address to use dev_queue_xmit() to transfer packets. The FLOW_OFFLOAD_XMIT_DIRECT replaces FLOW_OFFLOAD_XMIT_NEIGH if dev_fill_forward_path() finds a direct transmit path. In case of topology updates, if peer is moved to different bridge port, the connection will time out, reconnect will result in a new entry with the correct path. Snooping fdb updates would allow for cleaning up stale flowtable entries. Signed-off-by: Pablo Neira Ayuso --- v5: add note on fdb topology updates, per Jakub Kicinski. include/net/netfilter/nf_flow_table.h | 16 +- net/netfilter/nf_flow_table_core.c| 35 ++--- net/netfilter/nf_flow_table_ip.c | 72 +-- net/netfilter/nft_flow_offload.c | 25 -- 4 files changed, 118 insertions(+), 30 deletions(-) diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h index 963f99fb1c06..83110e4705c0 100644 --- a/include/net/netfilter/nf_flow_table.h +++ b/include/net/netfilter/nf_flow_table.h @@ -92,6 +92,7 @@ enum flow_offload_tuple_dir { enum flow_offload_xmit_type { FLOW_OFFLOAD_XMIT_NEIGH = 0, FLOW_OFFLOAD_XMIT_XFRM, + FLOW_OFFLOAD_XMIT_DIRECT, }; struct flow_offload_tuple { @@ -120,8 +121,14 @@ struct flow_offload_tuple { xmit_type:2; u16 mtu; - - struct dst_entry*dst_cache; + union { + struct dst_entry*dst_cache; + struct { + u32 ifidx; + u8 h_source[ETH_ALEN]; + u8 h_dest[ETH_ALEN]; + } out; + }; }; struct flow_offload_tuple_rhash { @@ -168,6 +175,11 @@ struct nf_flow_route { struct { u32 ifindex; } in; + struct { + u32 ifindex; + u8 h_source[ETH_ALEN]; + u8 h_dest[ETH_ALEN]; + } out; enum flow_offload_xmit_type xmit_type; } tuple[FLOW_OFFLOAD_DIR_MAX]; }; diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c index 27b4315d7b96..751bc1c27c16 100644 --- a/net/netfilter/nf_flow_table_core.c +++ b/net/netfilter/nf_flow_table_core.c @@ -81,9 +81,6 @@ static int flow_offload_fill_route(struct flow_offload *flow, struct flow_offload_tuple *flow_tuple = &flow->tuplehash[dir].tuple; struct dst_entry *dst = route->tuple[dir].dst; - if (!dst_hold_safe(route->tuple[dir].dst)) - return -1; - switch (flow_tuple->l3proto) { case NFPROTO_IPV4: flow_tuple->mtu = ip_dst_mtu_maybe_forward(dst, true); @@ -94,12 +91,36 @@ static int flow_offload_fill_route(struct flow_offload *flow, } flow_tuple->iifidx = route->tuple[dir].in.ifindex; + + switch (route->tuple[dir].xmit_type) { + case FLOW_OFFLOAD_XMIT_DIRECT: + memcpy(flow_tuple->out.h_dest, route->tuple[dir].out.h_dest, + ETH_ALEN); + memcpy(flow_tuple->out.h_source, route->tuple[dir].out.h_source, + ETH_ALEN); + flow_tuple->out.ifidx = route->tuple[dir].out.ifindex; + break; + case FLOW_OFFLOAD_XMIT_XFRM: + case FLOW_OFFLOAD_XMIT_NEIGH: + if (!dst_hold_safe(route->tuple[dir].dst)) + return -1; + + flow_tuple->dst_cache = dst; + break; + } flow_tuple->xmit_type = route->tuple[dir].xmit_type; - flow_tuple->dst_cache = dst; return 0; } +static void nft_flow_dst_release(struct flow_offload *flow, +enum flow_offload_tuple_dir dir) +{ + if (flow->tuplehash[dir].tuple.xmit_type == FLOW_OFFLOAD_XMIT_NEIGH || + flow->tuplehash[dir].tuple.xmit_type == FLOW_OFFLOAD_XMIT_XFRM) + dst_release(flow->tuplehash[dir].tuple.dst_cache); +} + int flow_offload_route_init(struct flow_offload *flow, const struct nf_flow_route *route) { @@ -118,7 +139,7 @@ int flow_offload_route_init(struct flow_offload *flow, return 0; err_route_reply: - dst_release(route->tuple[FLOW_OFFLOAD_DIR_ORIGINAL].dst); + nft_flow_dst_release(flow, FLOW_OFFLOAD_DIR_ORIGINAL); return err; } @@ -169,8 +190,8 @@ static void flow_offload_fixup_ct(struct nf_conn *ct) static void flow_offload_route_relea
[PATCH net-next,v5 3/9] net: resolve forwarding path from virtual netdevice and HW destination address
This patch adds dev_fill_forward_path() which resolves the path to reach the real netdevice from the IP forwarding side. This function takes as input the netdevice and the destination hardware address and it walks down the devices calling .ndo_fill_forward_path() for each device until the real device is found. For instance, assuming the following topology: IP forwarding / \ br0 eth0 / \ eth1 eth2 . . . ethX ab:cd:ef:ab:cd:ef where eth1 and eth2 are bridge ports and eth0 provides WAN connectivity. ethX is the interface in another box which is connected to the eth1 bridge port. For packets going through IP forwarding to br0 whose destination MAC address is ab:cd:ef:ab:cd:ef, dev_fill_forward_path() provides the following path: br0 -> eth1 .ndo_fill_forward_path for br0 looks up at the FDB for the bridge port from the destination MAC address to get the bridge port eth1. This information allows to create a fast path that bypasses the classic bridge and IP forwarding paths, so packets go directly from the bridge port eth1 to eth0 (wan interface) and vice versa. fast path .. / \ | IP forwarding | | / \ \/ | br0 eth0 . / \ -> eth1 eth2 . . . ethX ab:cd:ef:ab:cd:ef Signed-off-by: Pablo Neira Ayuso --- v5: Fix possible off-by-one path stack access, per Florian Westphal. include/linux/netdevice.h | 27 +++ net/core/dev.c| 46 +++ 2 files changed, 73 insertions(+) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 03433a4c929e..ef4fc0eefee0 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -833,6 +833,27 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev, struct sk_buff *skb, struct net_device *sb_dev); +enum net_device_path_type { + DEV_PATH_ETHERNET = 0, +}; + +struct net_device_path { + enum net_device_path_type type; + const struct net_device *dev; +}; + +#define NET_DEVICE_PATH_STACK_MAX 5 + +struct net_device_path_stack { + int num_paths; + struct net_device_path path[NET_DEVICE_PATH_STACK_MAX]; +}; + +struct net_device_path_ctx { + const struct net_device *dev; + const u8*daddr; +}; + enum tc_setup_type { TC_SETUP_QDISC_MQPRIO, TC_SETUP_CLSU32, @@ -1279,6 +1300,8 @@ struct netdev_net_notifier { * struct net_device *(*ndo_get_peer_dev)(struct net_device *dev); * If a device is paired with a peer device, return the peer instance. * The caller must be under RCU read context. + * int (*ndo_fill_forward_path)(struct net_device_path_ctx *ctx, struct net_device_path *path); + * Get the forwarding path to reach the real device from the HW destination address */ struct net_device_ops { int (*ndo_init)(struct net_device *dev); @@ -1487,6 +1510,8 @@ struct net_device_ops { int (*ndo_tunnel_ctl)(struct net_device *dev, struct ip_tunnel_parm *p, int cmd); struct net_device * (*ndo_get_peer_dev)(struct net_device *dev); + int (*ndo_fill_forward_path)(struct net_device_path_ctx *ctx, +struct net_device_path *path); }; /** @@ -2824,6 +2849,8 @@ void dev_remove_offload(struct packet_offload *po); int dev_get_iflink(const struct net_device *dev); int dev_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb); +int dev_fill_forward_path(const struct net_device *dev, const u8 *daddr, + struct net_device_path_stack *stack); struct net_device *__dev_get_by_flags(struct net *net, unsigned short flags, unsigned short mask); struct net_device *dev_get_by_name(struct net *net, const char *name); diff --git a/net/core/dev.c b/net/core/dev.c index 4bfdcd6b20e8..3bbc68f76902 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -846,6 +846,52 @@ int dev_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb) } EXPORT_SYMBOL_GPL(dev_fill_metadata_dst); +static struct net_device_path *dev_fwd_path(struct net_device_path_stack *stack) +{ + int k = stack->num_paths++; + + if (WARN_ON_ONCE(k >= NET_DEVICE_PATH_STACK_MAX)) + return NULL; + + return &stack->path[k]; +} + +int dev_fill_forward_path(const struct net_device *dev, const u8 *daddr, + struct net_device_path_stack *stack) +{ + const struct net_device *last_dev; + struct ne
[PATCH net-next,v5 8/9] netfilter: flowtable: add vlan support
Add the vlan id and protocol to the flow tuple to uniquely identify flows from the receive path. For the transmit path, dev_hard_header() on the vlan device push the headers. This patch includes support for two VLAN headers (QinQ) from the ingress path. Signed-off-by: Pablo Neira Ayuso --- v5: no changes. include/net/netfilter/nf_flow_table.h | 15 +++- net/netfilter/nf_flow_table_core.c| 6 ++ net/netfilter/nf_flow_table_ip.c | 108 +- net/netfilter/nft_flow_offload.c | 25 +- 4 files changed, 131 insertions(+), 23 deletions(-) diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h index 83110e4705c0..e65bbbd982cb 100644 --- a/include/net/netfilter/nf_flow_table.h +++ b/include/net/netfilter/nf_flow_table.h @@ -95,6 +95,8 @@ enum flow_offload_xmit_type { FLOW_OFFLOAD_XMIT_DIRECT, }; +#define NF_FLOW_TABLE_VLAN_MAX 2 + struct flow_offload_tuple { union { struct in_addr src_v4; @@ -113,13 +115,17 @@ struct flow_offload_tuple { u8 l3proto; u8 l4proto; + struct { + u16 id; + __be16 proto; + } in_vlan[NF_FLOW_TABLE_VLAN_MAX]; /* All members above are keys for lookups, see flow_offload_hash(). */ struct { } __hash; - u8 dir:6, - xmit_type:2; - + u8 dir:4, + xmit_type:2, + in_vlan_num:2; u16 mtu; union { struct dst_entry*dst_cache; @@ -174,6 +180,9 @@ struct nf_flow_route { struct dst_entry*dst; struct { u32 ifindex; + u16 vid[NF_FLOW_TABLE_VLAN_MAX]; + __be16 vproto[NF_FLOW_TABLE_VLAN_MAX]; + u8 num_vlans; } in; struct { u32 ifindex; diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c index 751bc1c27c16..c4322aeb3557 100644 --- a/net/netfilter/nf_flow_table_core.c +++ b/net/netfilter/nf_flow_table_core.c @@ -80,6 +80,7 @@ static int flow_offload_fill_route(struct flow_offload *flow, { struct flow_offload_tuple *flow_tuple = &flow->tuplehash[dir].tuple; struct dst_entry *dst = route->tuple[dir].dst; + int i; switch (flow_tuple->l3proto) { case NFPROTO_IPV4: @@ -91,6 +92,11 @@ static int flow_offload_fill_route(struct flow_offload *flow, } flow_tuple->iifidx = route->tuple[dir].in.ifindex; + for (i = 0; i < route->tuple[dir].in.num_vlans; i++) { + flow_tuple->in_vlan[i].id = route->tuple[dir].in.vid[i]; + flow_tuple->in_vlan[i].proto = route->tuple[dir].in.vproto[i]; + } + flow_tuple->in_vlan_num = route->tuple[dir].in.num_vlans; switch (route->tuple[dir].xmit_type) { case FLOW_OFFLOAD_XMIT_DIRECT: diff --git a/net/netfilter/nf_flow_table_ip.c b/net/netfilter/nf_flow_table_ip.c index ae0b008c639a..6bbf78c3e6ac 100644 --- a/net/netfilter/nf_flow_table_ip.c +++ b/net/netfilter/nf_flow_table_ip.c @@ -159,17 +159,35 @@ static bool ip_has_options(unsigned int thoff) return thoff != sizeof(struct iphdr); } +static void nf_flow_tuple_vlan(struct sk_buff *skb, + struct flow_offload_tuple *tuple) +{ + if (skb_vlan_tag_present(skb)) { + tuple->in_vlan[0].id = skb_vlan_tag_get(skb); + tuple->in_vlan[0].proto = skb->vlan_proto; + } + if (skb->protocol == htons(ETH_P_8021Q)) { + struct vlan_ethhdr *veth = (struct vlan_ethhdr *)skb_mac_header(skb); + + tuple->in_vlan[1].id = ntohs(veth->h_vlan_TCI); + tuple->in_vlan[1].proto = skb->protocol; + } +} + static int nf_flow_tuple_ip(struct sk_buff *skb, const struct net_device *dev, struct flow_offload_tuple *tuple) { - unsigned int thoff, hdrsize; + unsigned int thoff, hdrsize, offset = 0; struct flow_ports *ports; struct iphdr *iph; - if (!pskb_may_pull(skb, sizeof(*iph))) + if (skb->protocol == htons(ETH_P_8021Q)) + offset += VLAN_HLEN; + + if (!pskb_may_pull(skb, sizeof(*iph) + offset)) return -1; - iph = ip_hdr(skb); + iph = (struct iphdr *)(skb_network_header(skb) + offset); thoff = iph->ihl * 4; if (ip_is_fragment(iph) || @@ -191,11 +209,11 @@ static int nf_flow_tuple_ip(struct sk_buff *skb, const
[PATCH net-next,v5 6/9] netfilter: flowtable: use dev_fill_forward_path() to obtain ingress device
Obtain the ingress device in the tuple from the route in the reply direction. Use dev_fill_forward_path() instead to get the real ingress device for this flow. Fall back to use the ingress device that the IP forwarding route provides if: - dev_fill_forward_path() finds no real ingress device. - the ingress device that is obtained is not part of the flowtable devices. - this route has a xfrm policy. Signed-off-by: Pablo Neira Ayuso --- v5: no changes. include/net/netfilter/nf_flow_table.h | 3 + net/netfilter/nf_flow_table_core.c| 3 +- net/netfilter/nft_flow_offload.c | 101 +- 3 files changed, 102 insertions(+), 5 deletions(-) diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h index 7d477be06913..963f99fb1c06 100644 --- a/include/net/netfilter/nf_flow_table.h +++ b/include/net/netfilter/nf_flow_table.h @@ -165,6 +165,9 @@ static inline __s32 nf_flow_timeout_delta(unsigned int timeout) struct nf_flow_route { struct { struct dst_entry*dst; + struct { + u32 ifindex; + } in; enum flow_offload_xmit_type xmit_type; } tuple[FLOW_OFFLOAD_DIR_MAX]; }; diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c index 57dd8e40e474..27b4315d7b96 100644 --- a/net/netfilter/nf_flow_table_core.c +++ b/net/netfilter/nf_flow_table_core.c @@ -79,7 +79,6 @@ static int flow_offload_fill_route(struct flow_offload *flow, enum flow_offload_tuple_dir dir) { struct flow_offload_tuple *flow_tuple = &flow->tuplehash[dir].tuple; - struct dst_entry *other_dst = route->tuple[!dir].dst; struct dst_entry *dst = route->tuple[dir].dst; if (!dst_hold_safe(route->tuple[dir].dst)) @@ -94,7 +93,7 @@ static int flow_offload_fill_route(struct flow_offload *flow, break; } - flow_tuple->iifidx = other_dst->dev->ifindex; + flow_tuple->iifidx = route->tuple[dir].in.ifindex; flow_tuple->xmit_type = route->tuple[dir].xmit_type; flow_tuple->dst_cache = dst; diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c index 1da2bb24f6c0..15f5a3b38253 100644 --- a/net/netfilter/nft_flow_offload.c +++ b/net/netfilter/nft_flow_offload.c @@ -31,14 +31,103 @@ static void nft_default_forward_path(struct nf_flow_route *route, struct dst_entry *dst_cache, enum ip_conntrack_dir dir) { + route->tuple[!dir].in.ifindex = dst_cache->dev->ifindex; route->tuple[dir].dst = dst_cache; route->tuple[dir].xmit_type = nft_xmit_type(dst_cache); } +static int nft_dev_fill_forward_path(const struct nf_flow_route *route, +const struct dst_entry *dst_cache, +const struct nf_conn *ct, +enum ip_conntrack_dir dir, +struct net_device_path_stack *stack) +{ + const void *daddr = &ct->tuplehash[!dir].tuple.src.u3; + struct net_device *dev = dst_cache->dev; + unsigned char ha[ETH_ALEN]; + struct neighbour *n; + u8 nud_state; + + n = dst_neigh_lookup(dst_cache, daddr); + if (!n) + return -1; + + read_lock_bh(&n->lock); + nud_state = n->nud_state; + ether_addr_copy(ha, n->ha); + read_unlock_bh(&n->lock); + neigh_release(n); + + if (!(nud_state & NUD_VALID)) + return -1; + + return dev_fill_forward_path(dev, ha, stack); +} + +struct nft_forward_info { + const struct net_device *indev; +}; + +static void nft_dev_path_info(const struct net_device_path_stack *stack, + struct nft_forward_info *info) +{ + const struct net_device_path *path; + int i; + + for (i = stack->num_paths - 1; i >= 0; i--) { + path = &stack->path[i]; + switch (path->type) { + case DEV_PATH_ETHERNET: + info->indev = path->dev; + break; + case DEV_PATH_VLAN: + break; + case DEV_PATH_BRIDGE: + break; + } + } +} + +static bool nft_flowtable_find_dev(const struct net_device *dev, + struct nft_flowtable *ft) +{ + struct nft_hook *hook; + bool found = false; + + list_for_each_entry_rcu(hook, &ft->hook_list, list) { + if (hook->ops.dev != dev) + continue; + + found = true; + break; + } + + return found; +} + +static void nft_dev_forward_path(struct nf_flow_route *route, +const struct nf_con
[PATCH net-next,v5 5/9] bridge: resolve forwarding path for bridge devices
Add .ndo_fill_forward_path for bridge devices. Signed-off-by: Pablo Neira Ayuso --- v5: no changes. include/linux/netdevice.h | 1 + net/bridge/br_device.c| 27 +++ 2 files changed, 28 insertions(+) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index e9690e1a6559..281551c70536 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -836,6 +836,7 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev, enum net_device_path_type { DEV_PATH_ETHERNET = 0, DEV_PATH_VLAN, + DEV_PATH_BRIDGE, }; struct net_device_path { diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 77bcc84875af..8fee4db770b3 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -392,6 +392,32 @@ static int br_del_slave(struct net_device *dev, struct net_device *slave_dev) return br_del_if(br, slave_dev); } +static int br_fill_forward_path(struct net_device_path_ctx *ctx, + struct net_device_path *path) +{ + struct net_bridge_fdb_entry *f; + struct net_bridge_port *dst; + struct net_bridge *br; + + if (netif_is_bridge_port(ctx->dev)) + return -1; + + br = netdev_priv(ctx->dev); + f = br_fdb_find_rcu(br, ctx->daddr, 0); + if (!f || !f->dst) + return -1; + + dst = READ_ONCE(f->dst); + if (!dst) + return -1; + + path->type = DEV_PATH_BRIDGE; + path->dev = dst->br->dev; + ctx->dev = dst->dev; + + return 0; +} + static const struct ethtool_ops br_ethtool_ops = { .get_drvinfo = br_getinfo, .get_link= ethtool_op_get_link, @@ -426,6 +452,7 @@ static const struct net_device_ops br_netdev_ops = { .ndo_bridge_setlink = br_setlink, .ndo_bridge_dellink = br_dellink, .ndo_features_check = passthru_features_check, + .ndo_fill_forward_path = br_fill_forward_path, }; static struct device_type br_type = { -- 2.20.1
[PATCH net-next,v5 0/9] netfilter: flowtable bridge and vlan enhancements
Hi, The following patchset augments the Netfilter flowtable fastpath to support for network topologies that combine IP forwarding, bridge and VLAN devices. This v5 includes updates for: - Patch #2: fix incorrect xmit type in IPv6 path, per Florian Westphal. - Patch #3: fix possible off by one in dev_fill_forward_path() stack logic, per Florian Westphal. - Patch #7: add a note to patch description to specify that FDB topology updates are not supported at this stage, per Jakub Kicinski. A typical scenario that can benefit from this infrastructure is composed of several VMs connected to bridge ports where the bridge master device 'br0' has an IP address. A DHCP server is also assumed to be running to provide connectivity to the VMs. The VMs reach the Internet through 'br0' as default gateway, which makes the packet enter the IP forwarding path. Then, netfilter is used to NAT the packets before they leave through the wan device. Something like this: fast path .. / \ | IP forwarding | | / \ . | br0 eth0 . / \ -- veth1 veth2 . . . eth0 ab:cd:ef:ab:cd:ef VM The idea is to accelerate forwarding by building a fast path that takes packets from the ingress path of the bridge port and place them in the egress path of the wan device (and vice versa). Hence, skipping the classic bridge and IP stack paths. This patchset is composed of: Patch #1 adds a placeholder for the hash calculation, instead of using the dir field. Patch #2 adds the transmit path type field to the flow tuple. Two transmit paths are supported so far: the neighbour and the xfrm transmit paths. This patch comes in preparation to add a new direct ethernet transmit path (see patch #7). Patch #3 adds dev_fill_forward_path() and .ndo_fill_forward_path() to netdev_ops. This new function describes the list of netdevice hops to reach a given destination MAC address in the local network topology, e.g. IP forwarding / \ br0 eth0 / \ veth1 veth2 . . . eth0 ab:cd:ef:ab:cd:ef where veth1 and veth2 are bridge ports and eth0 provides Internet connectivity. eth0 is the interface in the VM which is connected to the veth1 bridge port. Then, for packets going to br0 whose destination MAC address is ab:cd:ef:ab:cd:ef, dev_fill_forward_path() provides the following path: br0 -> veth1. Patch #4 adds .ndo_fill_forward_path for VLAN devices, which provides the next device hop via vlan->real_dev. This annotates the VLAN id and protocol. This is useful to know what VLAN headers are expected from the ingress device. This also provides information regarding the VLAN headers to be pushed in the egress path. Patch #5 adds .ndo_fill_forward_path for bridge devices, which allows to make lookups to the FDB to locate the next device hop (bridge port) in the forwarding path. Patch #6 updates the flowtable to use the dev_fill_forward_path() infrastructure to obtain the ingress device in the fastpath. Patch #7 updates the flowtable to use dev_fill_forward_path() to obtain the egress device in the forwarding path. This also adds the direct ethernet transmit path, which pushes the ethernet header to the packet and send it through dev_queue_xmit(). This patch adds support for the bridge, so bridge ports use this direct xmit path. Patch #8 adds ingress VLAN support (up to 2 VLAN tags, QinQ). The VLAN information is also provided by dev_fill_forward_path(). Store the VLAN id and protocol in the flow tuple for hash lookups. The VLAN support in the xmit path is achieved by annotating the first vlan device found in the xmit path and by calling dev_hard_header() (previous patch #7) before dev_queue_xmit(). Patch #9 extends nft_flowtable.sh selftest: This is adding a test to cover bridge and vlan support coming in this patchset. = Performance numbers My testbed environment consists of three containers: 192.168.20.2 .20.1 .10.1 10.141.10.2 veth0 veth0 veth1 veth0 ns1 <-> nsr1 <> ns2 SNAT iperf -c iperf -s where nsr1 is used for forwarding. There is a bridge device br0 in nsr1, veth0 is a port of br0. SNAT is perfo
[PATCH net-next,v5 2/9] netfilter: flowtable: add xmit path types
Add the xmit_type field that defines the two supported xmit paths in the flowtable data plane, which are the neighbour and the xfrm xmit paths. This patch prepares for new flowtable xmit path types to come. Signed-off-by: Pablo Neira Ayuso --- v5: fix incorrect xmit type in IPv6 datapath, per Florian Westphal. include/net/netfilter/nf_flow_table.h | 11 +++-- net/netfilter/nf_flow_table_core.c| 1 + net/netfilter/nf_flow_table_ip.c | 32 ++- net/netfilter/nft_flow_offload.c | 20 +++-- 4 files changed, 50 insertions(+), 14 deletions(-) diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h index 54c4d5c908a5..7d477be06913 100644 --- a/include/net/netfilter/nf_flow_table.h +++ b/include/net/netfilter/nf_flow_table.h @@ -89,6 +89,11 @@ enum flow_offload_tuple_dir { FLOW_OFFLOAD_DIR_MAX = IP_CT_DIR_MAX }; +enum flow_offload_xmit_type { + FLOW_OFFLOAD_XMIT_NEIGH = 0, + FLOW_OFFLOAD_XMIT_XFRM, +}; + struct flow_offload_tuple { union { struct in_addr src_v4; @@ -111,7 +116,8 @@ struct flow_offload_tuple { /* All members above are keys for lookups, see flow_offload_hash(). */ struct { } __hash; - u8 dir; + u8 dir:6, + xmit_type:2; u16 mtu; @@ -158,7 +164,8 @@ static inline __s32 nf_flow_timeout_delta(unsigned int timeout) struct nf_flow_route { struct { - struct dst_entry*dst; + struct dst_entry*dst; + enum flow_offload_xmit_type xmit_type; } tuple[FLOW_OFFLOAD_DIR_MAX]; }; diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c index 55fca71ace26..57dd8e40e474 100644 --- a/net/netfilter/nf_flow_table_core.c +++ b/net/netfilter/nf_flow_table_core.c @@ -95,6 +95,7 @@ static int flow_offload_fill_route(struct flow_offload *flow, } flow_tuple->iifidx = other_dst->dev->ifindex; + flow_tuple->xmit_type = route->tuple[dir].xmit_type; flow_tuple->dst_cache = dst; return 0; diff --git a/net/netfilter/nf_flow_table_ip.c b/net/netfilter/nf_flow_table_ip.c index a698dbe28ef5..af49672bd38d 100644 --- a/net/netfilter/nf_flow_table_ip.c +++ b/net/netfilter/nf_flow_table_ip.c @@ -220,10 +220,20 @@ static bool nf_flow_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu) return true; } -static int nf_flow_offload_dst_check(struct dst_entry *dst) +static inline struct dst_entry * +nft_flow_dst(struct flow_offload_tuple_rhash *tuplehash) { - if (unlikely(dst_xfrm(dst))) + return tuplehash->tuple.dst_cache; +} + +static int nf_flow_offload_dst_check(struct flow_offload_tuple_rhash *tuplehash) +{ + struct dst_entry *dst; + + if (unlikely(tuplehash->tuple.xmit_type == FLOW_OFFLOAD_XMIT_XFRM)) { + dst = nft_flow_dst(tuplehash); return dst_check(dst, 0) ? 0 : -1; + } return 0; } @@ -265,8 +275,6 @@ nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb, dir = tuplehash->tuple.dir; flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]); - rt = (struct rtable *)flow->tuplehash[dir].tuple.dst_cache; - outdev = rt->dst.dev; if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu))) return NF_ACCEPT; @@ -280,7 +288,7 @@ nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb, flow_offload_refresh(flow_table, flow); - if (nf_flow_offload_dst_check(&rt->dst)) { + if (nf_flow_offload_dst_check(tuplehash)) { flow_offload_teardown(flow); return NF_ACCEPT; } @@ -295,13 +303,16 @@ nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb, if (flow_table->flags & NF_FLOWTABLE_COUNTER) nf_ct_acct_update(flow->ct, tuplehash->tuple.dir, skb->len); - if (unlikely(dst_xfrm(&rt->dst))) { + rt = (struct rtable *)tuplehash->tuple.dst_cache; + + if (unlikely(tuplehash->tuple.xmit_type == FLOW_OFFLOAD_XMIT_XFRM)) { memset(skb->cb, 0, sizeof(struct inet_skb_parm)); IPCB(skb)->iif = skb->dev->ifindex; IPCB(skb)->flags = IPSKB_FORWARDED; return nf_flow_xmit_xfrm(skb, state, &rt->dst); } + outdev = rt->dst.dev; skb->dev = outdev; nexthop = rt_nexthop(rt, flow->tuplehash[!dir].tuple.src_v4.s_addr); skb_dst_set_noref(skb, &rt->dst); @@ -506,8 +517,6 @@ nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb, dir = tuplehash->tuple.dir; flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]); - rt = (struct rt6_info *)flow->tuplehash[dir].tuple.dst_c
[PATCH net-next,v5 9/9] selftests: netfilter: flowtable bridge and VLAN support
This patch adds two new tests to cover bridge and VLAN support: - Add a bridge device to the Router1 (nsr1) container and attach the veth0 device to the bridge. Set the IP address to the bridge device to exercise the bridge forwarding path. - Add VLAN encapsulation between to the bridge device in the Router1 and one of the sender containers (ns1). Signed-off-by: Pablo Neira Ayuso --- v5: no changes. .../selftests/netfilter/nft_flowtable.sh | 82 +++ 1 file changed, 82 insertions(+) diff --git a/tools/testing/selftests/netfilter/nft_flowtable.sh b/tools/testing/selftests/netfilter/nft_flowtable.sh index 431296c0f91c..427d94816f2d 100755 --- a/tools/testing/selftests/netfilter/nft_flowtable.sh +++ b/tools/testing/selftests/netfilter/nft_flowtable.sh @@ -371,6 +371,88 @@ else ip netns exec nsr1 nft list ruleset fi +# Another test: +# Add bridge interface br0 to Router1, with NAT enabled. +ip -net nsr1 link add name br0 type bridge +ip -net nsr1 addr flush dev veth0 +ip -net nsr1 link set up dev veth0 +ip -net nsr1 link set veth0 master br0 +ip -net nsr1 addr add 10.0.1.1/24 dev br0 +ip -net nsr1 addr add dead:1::1/64 dev br0 +ip -net nsr1 link set up dev br0 + +ip netns exec nsr1 sysctl net.ipv4.conf.br0.forwarding=1 > /dev/null + +# br0 with NAT enabled. +ip netns exec nsr1 nft -f - <&2 + ip netns exec nsr1 nft list ruleset + ret=1 +fi + +# Another test: +# Add bridge interface br0 to Router1, with NAT and VLAN. +ip -net nsr1 link set veth0 nomaster +ip -net nsr1 link set down dev veth0 +ip -net nsr1 link add link veth0 name veth0.10 type vlan id 10 +ip -net nsr1 link set up dev veth0 +ip -net nsr1 link set up dev veth0.10 +ip -net nsr1 link set veth0.10 master br0 + +ip -net ns1 addr flush dev eth0 +ip -net ns1 link add link eth0 name eth0.10 type vlan id 10 +ip -net ns1 link set eth0 up +ip -net ns1 link set eth0.10 up +ip -net ns1 addr add 10.0.1.99/24 dev eth0.10 +ip -net ns1 route add default via 10.0.1.1 +ip -net ns1 addr add dead:1::99/64 dev eth0.10 + +if test_tcp_forwarding_nat ns1 ns2; then + echo "PASS: flow offloaded for ns1/ns2 with bridge NAT and VLAN" +else + echo "FAIL: flow offload for ns1/ns2 with bridge NAT and VLAN" 1>&2 + ip netns exec nsr1 nft list ruleset + ret=1 +fi + +# restore test topology (remove bridge and VLAN) +ip -net nsr1 link set veth0 nomaster +ip -net nsr1 link set veth0 down +ip -net nsr1 link set veth0.10 down +ip -net nsr1 link delete veth0.10 type vlan +ip -net nsr1 link delete br0 type bridge +ip -net ns1 addr flush dev eth0.10 +ip -net ns1 link set eth0.10 down +ip -net ns1 link set eth0 down +ip -net ns1 link delete eth0.10 type vlan + +# restore address in ns1 and nsr1 +ip -net ns1 link set eth0 up +ip -net ns1 addr add 10.0.1.99/24 dev eth0 +ip -net ns1 route add default via 10.0.1.1 +ip -net ns1 addr add dead:1::99/64 dev eth0 +ip -net ns1 route add default via dead:1::1 +ip -net nsr1 addr add 10.0.1.1/24 dev veth0 +ip -net nsr1 addr add dead:1::1/64 dev veth0 +ip -net nsr1 link set up dev veth0 + KEY_SHA="0x"$(ps -xaf | sha1sum | cut -d " " -f 1) KEY_AES="0x"$(ps -xaf | md5sum | cut -d " " -f 1) SPI1=$RANDOM -- 2.20.1
[PATCH net-next,v5 4/9] net: 8021q: resolve forwarding path for vlan devices
Add .ndo_fill_forward_path for vlan devices. For instance, assuming the following topology: IP forwarding / \ eth0.100 eth0 | eth0 . . . ethX ab:cd:ef:ab:cd:ef For packets going through IP forwarding to eth0.100 whose destination MAC address is ab:cd:ef:ab:cd:ef, dev_fill_forward_path() provides the following path: eth0.100 -> eth0 Signed-off-by: Pablo Neira Ayuso --- v5: no changes. include/linux/netdevice.h | 7 +++ net/8021q/vlan_dev.c | 15 +++ 2 files changed, 22 insertions(+) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index ef4fc0eefee0..e9690e1a6559 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -835,11 +835,18 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev, enum net_device_path_type { DEV_PATH_ETHERNET = 0, + DEV_PATH_VLAN, }; struct net_device_path { enum net_device_path_type type; const struct net_device *dev; + union { + struct { + u16 id; + __be16 proto; + } vlan; + }; }; #define NET_DEVICE_PATH_STACK_MAX 5 diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index ec8408d1638f..f06a507557f9 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -767,6 +767,20 @@ static int vlan_dev_get_iflink(const struct net_device *dev) return real_dev->ifindex; } +static int vlan_dev_fill_forward_path(struct net_device_path_ctx *ctx, + struct net_device_path *path) +{ + struct vlan_dev_priv *vlan = vlan_dev_priv(ctx->dev); + + path->type = DEV_PATH_VLAN; + path->vlan.id = vlan->vlan_id; + path->vlan.proto = vlan->vlan_proto; + path->dev = ctx->dev; + ctx->dev = vlan->real_dev; + + return 0; +} + static const struct ethtool_ops vlan_ethtool_ops = { .get_link_ksettings = vlan_ethtool_get_link_ksettings, .get_drvinfo= vlan_ethtool_get_drvinfo, @@ -805,6 +819,7 @@ static const struct net_device_ops vlan_netdev_ops = { #endif .ndo_fix_features = vlan_dev_fix_features, .ndo_get_iflink = vlan_dev_get_iflink, + .ndo_fill_forward_path = vlan_dev_fill_forward_path, }; static void vlan_dev_free(struct net_device *dev) -- 2.20.1
Re: [PATCH bpf-next 2/2] bpf: sanitize BTF data pointer after module is loaded
+++ Andrii Nakryiko [19/11/20 10:26 -0800]: Given .BTF section is not allocatable, it will get trimmed after module is loaded. BPF system handles that properly by creating an independent copy of data. But prevent any accidental misused by resetting the pointer to BTF data. Suggested-by: Jessica Yu Fixes: 36e68442d1af ("bpf: Load and verify kernel module BTFs") Cc: Greg Kroah-Hartman Signed-off-by: Andrii Nakryiko Thanks, Andrii! Acked-by: Jessica Yu --- kernel/module.c | 5 + 1 file changed, 5 insertions(+) diff --git a/kernel/module.c b/kernel/module.c index f2996b02ab2e..18f259d61d14 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -3709,6 +3709,11 @@ static noinline int do_init_module(struct module *mod) mod->init_layout.ro_size = 0; mod->init_layout.ro_after_init_size = 0; mod->init_layout.text_size = 0; +#ifdef CONFIG_DEBUG_INFO_BTF_MODULES + /* .BTF is not SHF_ALLOC and will get removed, so sanitize pointer */ + mod->btf_data = NULL; + mod->btf_data_size = 0; +#endif /* * We want to free module_init, but be aware that kallsyms may be * walking this with preempt disabled. In all the failure paths, we -- 2.24.1
Re: [PATCH v1 net-next] net: dsa: qca: ar9331: add ethtool stats support
On Mon, Nov 16, 2020 at 04:28:44PM -0800, Jakub Kicinski wrote: > On Tue, 17 Nov 2020 02:10:05 +0200 Vladimir Oltean wrote: > > On Mon, Nov 16, 2020 at 04:02:13PM -0800, Jakub Kicinski wrote: > > > For a while now we have been pushing back on stats which have a proper > > > interface to be added to ethtool -S. So I'd expect the list of stats > > > exposed via ethtool will end up being shorter than in this patch. > > > > Hmm, not sure if that's ever going to be the case. Even with drivers > > that are going to expose standardized forms of counters, I'm not sure > > it's going to be nice to remove them from ethtool -S. > > Not remove, but also not accept adding them to new drivers. > > > Testing teams all > > over the world have scripts that grep for those. Unfortunately I think > > ethtool -S will always remain a dumping ground of hell, and the place > > where you search for a counter based on its name from the hardware block > > guide as opposed to its standardized name/function. And that might mean > > there's no reason to not accept Oleksij's patch right away. Even if he > > might volunteer to actually follow up with a patch where he exposes the > > .ndo_get_stats64 from DSA towards drivers, as well as implements > > .ndo_has_offload_stats and .ndo_get_offload_stats within DSA, that will > > most likely be done as separate patches to this one, and not change in > > any way how this patch looks. Ok, so what is the plan for me? Implement .ndo_get_stats64 before this one? Regards, Oleksij -- Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- |
[PATCH bpf-next v2 5/5] selftests/bpf: xsk selftests - Bi-directional Sockets - SKB, DRV
Adds following tests: 1. AF_XDP SKB mode d. Bi-directional Sockets Configure sockets as bi-directional tx/rx sockets, sets up fill and completion rings on each socket, tx/rx in both directions. Only nopoll mode is used 2. AF_XDP DRV/Native mode d. Bi-directional Sockets * Only copy mode is supported because veth does not currently support zero-copy mode Signed-off-by: Weqaar Janjua --- tools/testing/selftests/bpf/Makefile | 4 +- .../bpf/test_xsk_drv_bidirectional.sh | 23 .../selftests/bpf/test_xsk_drv_teardown.sh| 3 - .../bpf/test_xsk_skb_bidirectional.sh | 20 tools/testing/selftests/bpf/xdpxceiver.c | 100 +- tools/testing/selftests/bpf/xdpxceiver.h | 4 + 6 files changed, 126 insertions(+), 28 deletions(-) create mode 100755 tools/testing/selftests/bpf/test_xsk_drv_bidirectional.sh create mode 100755 tools/testing/selftests/bpf/test_xsk_skb_bidirectional.sh diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 515b29d321d7..258bd72812e0 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -78,7 +78,9 @@ TEST_PROGS := test_kmod.sh \ test_xsk_drv_nopoll.sh \ test_xsk_drv_poll.sh \ test_xsk_skb_teardown.sh \ - test_xsk_drv_teardown.sh + test_xsk_drv_teardown.sh \ + test_xsk_skb_bidirectional.sh \ + test_xsk_drv_bidirectional.sh TEST_PROGS_EXTENDED := with_addr.sh \ with_tunnels.sh \ diff --git a/tools/testing/selftests/bpf/test_xsk_drv_bidirectional.sh b/tools/testing/selftests/bpf/test_xsk_drv_bidirectional.sh new file mode 100755 index ..d3a7e2934d83 --- /dev/null +++ b/tools/testing/selftests/bpf/test_xsk_drv_bidirectional.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright(c) 2020 Intel Corporation. + +# See test_xsk_prerequisites.sh for detailed information on tests + +. xsk_prereqs.sh +. xsk_env.sh + +TEST_NAME="DRV BIDIRECTIONAL SOCKETS" + +vethXDPnative ${VETH0} ${VETH1} ${NS1} + +params=("-N" "-B") +execxdpxceiver params + +retval=$? +test_status $retval "${TEST_NAME}" + +# Must be called in the last test to execute +cleanup_exit ${VETH0} ${VETH1} ${NS1} + +test_exit $retval 0 diff --git a/tools/testing/selftests/bpf/test_xsk_drv_teardown.sh b/tools/testing/selftests/bpf/test_xsk_drv_teardown.sh index 28bf730b589e..7f11033747ac 100755 --- a/tools/testing/selftests/bpf/test_xsk_drv_teardown.sh +++ b/tools/testing/selftests/bpf/test_xsk_drv_teardown.sh @@ -17,7 +17,4 @@ execxdpxceiver params retval=$? test_status $retval "${TEST_NAME}" -# Must be called in the last test to execute -cleanup_exit ${VETH0} ${VETH1} ${NS1} - test_exit $retval 0 diff --git a/tools/testing/selftests/bpf/test_xsk_skb_bidirectional.sh b/tools/testing/selftests/bpf/test_xsk_skb_bidirectional.sh new file mode 100755 index ..8ae1b6694f02 --- /dev/null +++ b/tools/testing/selftests/bpf/test_xsk_skb_bidirectional.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright(c) 2020 Intel Corporation. + +# See test_xsk_prerequisites.sh for detailed information on tests + +. xsk_prereqs.sh +. xsk_env.sh + +TEST_NAME="SKB BIDIRECTIONAL SOCKETS" + +vethXDPgeneric ${VETH0} ${VETH1} ${NS1} + +params=("-S" "-B") +execxdpxceiver params + +retval=$? +test_status $retval "${TEST_NAME}" + +test_exit $retval 0 diff --git a/tools/testing/selftests/bpf/xdpxceiver.c b/tools/testing/selftests/bpf/xdpxceiver.c index ba5de1ef9f64..277d9344ce34 100644 --- a/tools/testing/selftests/bpf/xdpxceiver.c +++ b/tools/testing/selftests/bpf/xdpxceiver.c @@ -29,6 +29,10 @@ *c. Socket Teardown * Create a Tx and a Rx socket, Tx from one socket, Rx on another. Destroy * both sockets, then repeat multiple times. Only nopoll mode is used + *d. Bi-directional sockets + * Configure sockets as bi-directional tx/rx sockets, sets up fill and + * completion rings on each socket, tx/rx in both directions. Only nopoll + * mode is used * * 2. AF_XDP DRV/Native mode *Works on any netdevice with XDP_REDIRECT support, driver dependent. Processes @@ -37,10 +41,11 @@ *a. nopoll *b. poll *c. Socket Teardown + *d. Bi-directional sockets *- Only copy mode is supported because veth does not currently support * zero-copy mode * - * Total tests: 6 + * Total tests: 8 * * Flow: * - @@ -100,8 +105,9 @@ static void __exit_with_error(int error, const char *file, const char *func, int #define exit_with_error(error) __exit_with_error(error, __FILE__, __func__, __LINE__) #define print_ksft_result(void)\ - (ksft_test_result_pass("PASS: %s %s %s\n", uut ? "DRV" : "SKB", opt_poll ? "POLL" :\ - "NOPOLL", opt_teardown ? "Socket Teardown" : "")) + (ksft_test_result_pass("PASS: %s %s %s%s\n", uut ? "DRV" : "SKB",
[PATCH bpf-next v2 0/5] selftests/bpf: xsk selftests
This patch set adds AF_XDP selftests based on veth to selftests/bpf. # Topology: # - # --- # _ | Process | _ # / --- \ # /|\ #/ | \ # --- | --- # | Thread1 | | | Thread2 | # --- | --- # | | | # --- | --- # | xskX | | | xskY | # --- | --- # | | | # --- | -- # | vethX | - | vethY | # --- peer-- # | | | # namespaceX | namespaceY These selftests test AF_XDP SKB and Native/DRV modes using veth Virtual Ethernet interfaces. The test program contains two threads, each thread is single socket with a unique UMEM. It validates in-order packet delivery and packet content by sending packets to each other. Prerequisites setup by script test_xsk_prerequisites.sh: Set up veth interfaces as per the topology shown ^^: * setup two veth interfaces and one namespace ** veth in root namespace ** veth in af_xdp namespace ** namespace af_xdp * create a spec file veth.spec that includes this run-time configuration that is read by test scripts - filenames prefixed with test_xsk_ *** and are randomly generated 4 digit numbers used to avoid conflict with any existing interface The following tests are provided: 1. AF_XDP SKB mode Generic mode XDP is driver independent, used when the driver does not have support for XDP. Works on any netdevice using sockets and generic XDP path. XDP hook from netif_receive_skb(). a. nopoll - soft-irq processing b. poll - using poll() syscall c. Socket Teardown Create a Tx and a Rx socket, Tx from one socket, Rx on another. Destroy both sockets, then repeat multiple times. Only nopoll mode is used d. Bi-directional Sockets Configure sockets as bi-directional tx/rx sockets, sets up fill and completion rings on each socket, tx/rx in both directions. Only nopoll mode is used 2. AF_XDP DRV/Native mode Works on any netdevice with XDP_REDIRECT support, driver dependent. Processes packets before SKB allocation. Provides better performance than SKB. Driver hook available just after DMA of buffer descriptor. a. nopoll b. poll c. Socket Teardown d. Bi-directional Sockets * Only copy mode is supported because veth does not currently support zero-copy mode Total tests: 8 Flow: * Single process spawns two threads: Tx and Rx * Each of these two threads attach to a veth interface within their assigned namespaces * Each thread creates one AF_XDP socket connected to a unique umem for each veth interface * Tx thread transmits 10k packets from veth to veth * Rx thread verifies if all 10k packets were received and delivered in-order, and have the right content v2 changes: * Move selftests/xsk to selftests/bpf * Remove Makefiles under selftests/xsk, and utilize selftests/bpf/Makefile Structure of the patch set: Patch 1: This patch adds XSK Selftests framework under selftests/bpf Patch 2: Adds tests: SKB poll and nopoll mode, and mac-ip-udp debug Patch 3: Adds tests: DRV poll and nopoll mode Patch 4: Adds tests: SKB and DRV Socket Teardown Patch 5: Adds tests: SKB and DRV Bi-directional Sockets Thanks: Weqaar Weqaar Janjua (5): selftests/bpf: xsk selftests framework selftests/bpf: xsk selftests - SKB POLL, NOPOLL selftests/bpf: xsk selftests - DRV POLL, NOPOLL selftests/bpf: xsk selftests - Socket Teardown - SKB, DRV selftests/bpf: xsk selftests - Bi-directional Sockets - SKB, DRV tools/testing/selftests/bpf/Makefile | 15 +- .../bpf/test_xsk_drv_bidirectional.sh | 23 + .../selftests/bpf/test_xsk_drv_nopoll.sh | 20 + .../selftests/bpf/test_xsk_drv_poll.sh| 20 + .../selftests/bpf/test_xsk_drv_teardown.sh| 20 + .../selftests/bpf/test_xsk_prerequisites.sh | 127 ++ .../bpf/test_xsk_skb_bidirectional.sh | 20 + .../selftests/bpf/test_xsk_skb_nopoll.sh | 20 + .../selftests/bpf/test_xsk_skb_poll.sh| 20 + .../selftests/bpf/test_xsk_skb_teardown.sh| 20 + tools/testing/selftests/bpf/xdpxceiver.c | 1056 + tools/testing/selftests/bpf/xdpxceiver.h | 158 +++ tools/testing/selftests/bpf/xsk_env.sh| 28 + tools/testing/selftests/bpf/xsk_prereqs.sh| 119 ++ 14 files changed, 1664 insertions(+), 2 deletions(-) create mode 100755 tools/testing/selftests/bpf/test_xsk_drv_bidirectional.sh create mode 100755 tools/testing/selftests/bpf/test_xsk_drv_nopoll.sh create mode 100755 tools/testing/selftests/bpf/test_xsk_drv_poll.sh create mode 100755 tools/testing/selftests/bpf/test_xsk_drv_teardown.sh create mode
[PATCH bpf-next v2 4/5] selftests/bpf: xsk selftests - Socket Teardown - SKB, DRV
Adds following tests: 1. AF_XDP SKB mode c. Socket Teardown Create a Tx and a Rx socket, Tx from one socket, Rx on another. Destroy both sockets, then repeat multiple times. Only nopoll mode is used 2. AF_XDP DRV/Native mode c. Socket Teardown * Only copy mode is supported because veth does not currently support zero-copy mode Signed-off-by: Weqaar Janjua --- tools/testing/selftests/bpf/Makefile | 4 ++- .../selftests/bpf/test_xsk_drv_poll.sh| 3 -- .../selftests/bpf/test_xsk_drv_teardown.sh| 23 .../selftests/bpf/test_xsk_skb_teardown.sh| 20 +++ tools/testing/selftests/bpf/xdpxceiver.c | 35 --- tools/testing/selftests/bpf/xdpxceiver.h | 2 ++ 6 files changed, 79 insertions(+), 8 deletions(-) create mode 100755 tools/testing/selftests/bpf/test_xsk_drv_teardown.sh create mode 100755 tools/testing/selftests/bpf/test_xsk_skb_teardown.sh diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 9dd3f3b9014f..515b29d321d7 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -76,7 +76,9 @@ TEST_PROGS := test_kmod.sh \ test_xsk_skb_nopoll.sh \ test_xsk_skb_poll.sh \ test_xsk_drv_nopoll.sh \ - test_xsk_drv_poll.sh + test_xsk_drv_poll.sh \ + test_xsk_skb_teardown.sh \ + test_xsk_drv_teardown.sh TEST_PROGS_EXTENDED := with_addr.sh \ with_tunnels.sh \ diff --git a/tools/testing/selftests/bpf/test_xsk_drv_poll.sh b/tools/testing/selftests/bpf/test_xsk_drv_poll.sh index 1fe488d5794a..46e0ae0cabed 100755 --- a/tools/testing/selftests/bpf/test_xsk_drv_poll.sh +++ b/tools/testing/selftests/bpf/test_xsk_drv_poll.sh @@ -17,7 +17,4 @@ execxdpxceiver params retval=$? test_status $retval "${TEST_NAME}" -# Must be called in the last test to execute -cleanup_exit ${VETH0} ${VETH1} ${NS1} - test_exit $retval 0 diff --git a/tools/testing/selftests/bpf/test_xsk_drv_teardown.sh b/tools/testing/selftests/bpf/test_xsk_drv_teardown.sh new file mode 100755 index ..28bf730b589e --- /dev/null +++ b/tools/testing/selftests/bpf/test_xsk_drv_teardown.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright(c) 2020 Intel Corporation. + +# See test_xsk_prerequisites.sh for detailed information on tests + +. xsk_prereqs.sh +. xsk_env.sh + +TEST_NAME="DRV SOCKET TEARDOWN" + +vethXDPnative ${VETH0} ${VETH1} ${NS1} + +params=("-N" "-T") +execxdpxceiver params + +retval=$? +test_status $retval "${TEST_NAME}" + +# Must be called in the last test to execute +cleanup_exit ${VETH0} ${VETH1} ${NS1} + +test_exit $retval 0 diff --git a/tools/testing/selftests/bpf/test_xsk_skb_teardown.sh b/tools/testing/selftests/bpf/test_xsk_skb_teardown.sh new file mode 100755 index ..3ceda125647b --- /dev/null +++ b/tools/testing/selftests/bpf/test_xsk_skb_teardown.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright(c) 2020 Intel Corporation. + +# See test_xsk_prerequisites.sh for detailed information on tests + +. xsk_prereqs.sh +. xsk_env.sh + +TEST_NAME="SKB SOCKET TEARDOWN" + +vethXDPgeneric ${VETH0} ${VETH1} ${NS1} + +params=("-S" "-T") +execxdpxceiver params + +retval=$? +test_status $retval "${TEST_NAME}" + +test_exit $retval 0 diff --git a/tools/testing/selftests/bpf/xdpxceiver.c b/tools/testing/selftests/bpf/xdpxceiver.c index e998200502de..ba5de1ef9f64 100644 --- a/tools/testing/selftests/bpf/xdpxceiver.c +++ b/tools/testing/selftests/bpf/xdpxceiver.c @@ -26,6 +26,9 @@ *generic XDP path. XDP hook from netif_receive_skb(). *a. nopoll - soft-irq processing *b. poll - using poll() syscall + *c. Socket Teardown + * Create a Tx and a Rx socket, Tx from one socket, Rx on another. Destroy + * both sockets, then repeat multiple times. Only nopoll mode is used * * 2. AF_XDP DRV/Native mode *Works on any netdevice with XDP_REDIRECT support, driver dependent. Processes @@ -33,10 +36,11 @@ *hook available just after DMA of buffer descriptor. *a. nopoll *b. poll + *c. Socket Teardown *- Only copy mode is supported because veth does not currently support * zero-copy mode * - * Total tests: 4 + * Total tests: 6 * * Flow: * - @@ -96,7 +100,8 @@ static void __exit_with_error(int error, const char *file, const char *func, int #define exit_with_error(error) __exit_with_error(error, __FILE__, __func__, __LINE__) #define print_ksft_result(void)\ - (ksft_test_result_pass("PASS: %s %s\n", uut ? "DRV" : "SKB", opt_poll ? "POLL" : "NOPOLL")) + (ksft_test_result_pass("PASS: %s %s %s\n", uut ? "DRV" : "SKB", opt_poll ? "POLL" :\ + "NOPOLL", opt_teardown ? "Socket Teardown" : "")) static void pthread_init_mutex(void) { @@ -321,6 +326,7 @@ static struct option long_options[] = { {"xdp-skb", no_argu
[PATCH bpf-next v2 2/5] selftests/bpf: xsk selftests - SKB POLL, NOPOLL
Adds following tests: 1. AF_XDP SKB mode Generic mode XDP is driver independent, used when the driver does not have support for XDP. Works on any netdevice using sockets and generic XDP path. XDP hook from netif_receive_skb(). a. nopoll - soft-irq processing b. poll - using poll() syscall Signed-off-by: Weqaar Janjua --- tools/testing/selftests/bpf/Makefile | 5 +- .../selftests/bpf/test_xsk_prerequisites.sh | 15 +- .../selftests/bpf/test_xsk_skb_nopoll.sh | 20 + ..._xsk_framework.sh => test_xsk_skb_poll.sh} | 12 +- tools/testing/selftests/bpf/xdpxceiver.c | 961 ++ tools/testing/selftests/bpf/xdpxceiver.h | 151 +++ tools/testing/selftests/bpf/xsk_env.sh| 17 + 7 files changed, 1174 insertions(+), 7 deletions(-) create mode 100755 tools/testing/selftests/bpf/test_xsk_skb_nopoll.sh rename tools/testing/selftests/bpf/{test_xsk_framework.sh => test_xsk_skb_poll.sh} (61%) create mode 100644 tools/testing/selftests/bpf/xdpxceiver.c create mode 100644 tools/testing/selftests/bpf/xdpxceiver.h diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 51436db24f32..17af570a32d7 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -73,7 +73,8 @@ TEST_PROGS := test_kmod.sh \ test_bpftool.sh \ test_bpftool_metadata.sh \ test_xsk_prerequisites.sh \ - test_xsk_framework.sh + test_xsk_skb_nopoll.sh \ + test_xsk_skb_poll.sh TEST_PROGS_EXTENDED := with_addr.sh \ with_tunnels.sh \ @@ -84,7 +85,7 @@ TEST_PROGS_EXTENDED := with_addr.sh \ # Compile but not part of 'make run_tests' TEST_GEN_PROGS_EXTENDED = test_sock_addr test_skb_cgroup_id_user \ flow_dissector_load test_flow_dissector test_tcp_check_syncookie_user \ - test_lirc_mode2_user xdping test_cpp runqslower bench + test_lirc_mode2_user xdping test_cpp runqslower bench xdpxceiver TEST_CUSTOM_PROGS = urandom_read diff --git a/tools/testing/selftests/bpf/test_xsk_prerequisites.sh b/tools/testing/selftests/bpf/test_xsk_prerequisites.sh index 00bfcf53127c..a9ce8887dffc 100755 --- a/tools/testing/selftests/bpf/test_xsk_prerequisites.sh +++ b/tools/testing/selftests/bpf/test_xsk_prerequisites.sh @@ -8,8 +8,17 @@ # # Topology: # - -# --- --- -# | xskX | - | xskY | +# --- +# _ | Process | _ +# / --- \ +# /|\ +#/ | \ +# --- | --- +# | Thread1 | | | Thread2 | +# --- | --- +# | | | +# --- | --- +# | xskX | | | xskY | # --- | --- # | | | # --- | -- @@ -40,6 +49,8 @@ # conflict with any existing interface # * tests the veth and xsk layers of the topology # +# See the source xdpxceiver.c for information on each test +# # Kernel configuration: # - # See "config" file for recommended kernel config options. diff --git a/tools/testing/selftests/bpf/test_xsk_skb_nopoll.sh b/tools/testing/selftests/bpf/test_xsk_skb_nopoll.sh new file mode 100755 index ..96600b0f5136 --- /dev/null +++ b/tools/testing/selftests/bpf/test_xsk_skb_nopoll.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright(c) 2020 Intel Corporation. + +# See test_xsk_prerequisites.sh for detailed information on tests + +. xsk_prereqs.sh +. xsk_env.sh + +TEST_NAME="SKB NOPOLL" + +vethXDPgeneric ${VETH0} ${VETH1} ${NS1} + +params=("-S") +execxdpxceiver params + +retval=$? +test_status $retval "${TEST_NAME}" + +test_exit $retval 0 diff --git a/tools/testing/selftests/bpf/test_xsk_framework.sh b/tools/testing/selftests/bpf/test_xsk_skb_poll.sh similarity index 61% rename from tools/testing/selftests/bpf/test_xsk_framework.sh rename to tools/testing/selftests/bpf/test_xsk_skb_poll.sh index 2e3f099d001c..d152c8a24251 100755 --- a/tools/testing/selftests/bpf/test_xsk_framework.sh +++ b/tools/testing/selftests/bpf/test_xsk_skb_poll.sh @@ -7,11 +7,17 @@ . xsk_prereqs.sh . xsk_env.sh -TEST_NAME="XSK FRAMEWORK" +TEST_NAME="SKB POLL" -test_status $ksft_pass "${TEST_NAME}" +vethXDPgeneric ${VETH0} ${VETH1} ${NS1} + +params=("-S" "-p") +execxdpxceiver params + +retval=$? +test_status $retval "${TEST_NAME}" # Must be called in the last test to execute cleanup_exit ${VETH0} ${VETH1} ${NS1} -test_exit $ksft_pass 0 +test_exit $retval 0 diff --git a/tools/testing/selftests/bpf/xdpxceiver.c b/tools/testing/selftests/bpf/xdpxceiver.c new file mode 100644 index ..106307155bbe --- /dev/null +++ b/tools/testing/selftests/bpf/xdpxceiver.c @@ -0,0 +1,961 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyri
[PATCH bpf-next v2 1/5] selftests/bpf: xsk selftests framework
This patch adds AF_XDP selftests framework under selftests/bpf. Prerequisites setup by script test_xsk_prerequisites.sh: Set up veth interfaces as per the topology shown ^^: * setup two veth interfaces and one namespace ** veth in root namespace ** veth in af_xdp namespace ** namespace af_xdp * create a spec file veth.spec that includes this run-time configuration that is read by test scripts - filenames prefixed with test_xsk_ *** and are randomly generated 4 digit numbers used to avoid conflict with any existing interface * tests the veth and xsk layers of the topology Signed-off-by: Weqaar Janjua --- tools/testing/selftests/bpf/Makefile | 6 +- .../selftests/bpf/test_xsk_framework.sh | 17 +++ .../selftests/bpf/test_xsk_prerequisites.sh | 116 + tools/testing/selftests/bpf/xsk_env.sh| 11 ++ tools/testing/selftests/bpf/xsk_prereqs.sh| 119 ++ 5 files changed, 268 insertions(+), 1 deletion(-) create mode 100755 tools/testing/selftests/bpf/test_xsk_framework.sh create mode 100755 tools/testing/selftests/bpf/test_xsk_prerequisites.sh create mode 100755 tools/testing/selftests/bpf/xsk_env.sh create mode 100755 tools/testing/selftests/bpf/xsk_prereqs.sh diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 3d5940cd110d..51436db24f32 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -46,7 +46,9 @@ endif TEST_GEN_FILES = TEST_FILES = test_lwt_ip_encap.o \ - test_tc_edt.o + test_tc_edt.o \ + xsk_prereqs.sh \ + xsk_env.sh # Order correspond to 'make run_tests' order TEST_PROGS := test_kmod.sh \ @@ -70,6 +72,8 @@ TEST_PROGS := test_kmod.sh \ test_bpftool_build.sh \ test_bpftool.sh \ test_bpftool_metadata.sh \ + test_xsk_prerequisites.sh \ + test_xsk_framework.sh TEST_PROGS_EXTENDED := with_addr.sh \ with_tunnels.sh \ diff --git a/tools/testing/selftests/bpf/test_xsk_framework.sh b/tools/testing/selftests/bpf/test_xsk_framework.sh new file mode 100755 index ..2e3f099d001c --- /dev/null +++ b/tools/testing/selftests/bpf/test_xsk_framework.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright(c) 2020 Intel Corporation. + +# See test_xsk_prerequisites.sh for detailed information on tests + +. xsk_prereqs.sh +. xsk_env.sh + +TEST_NAME="XSK FRAMEWORK" + +test_status $ksft_pass "${TEST_NAME}" + +# Must be called in the last test to execute +cleanup_exit ${VETH0} ${VETH1} ${NS1} + +test_exit $ksft_pass 0 diff --git a/tools/testing/selftests/bpf/test_xsk_prerequisites.sh b/tools/testing/selftests/bpf/test_xsk_prerequisites.sh new file mode 100755 index ..00bfcf53127c --- /dev/null +++ b/tools/testing/selftests/bpf/test_xsk_prerequisites.sh @@ -0,0 +1,116 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright(c) 2020 Intel Corporation, Weqaar Janjua + +# AF_XDP selftests based on veth +# +# End-to-end AF_XDP over Veth test +# +# Topology: +# - +# --- --- +# | xskX | - | xskY | +# --- | --- +# | | | +# --- | -- +# | vethX | - | vethY | +# --- peer-- +# | | | +# namespaceX | namespaceY +# +# AF_XDP is an address family optimized for high performance packet processing, +# it is XDP’s user-space interface. +# +# An AF_XDP socket is linked to a single UMEM which is a region of virtual +# contiguous memory, divided into equal-sized frames. +# +# Refer to AF_XDP Kernel Documentation for detailed information: +# https://www.kernel.org/doc/html/latest/networking/af_xdp.html +# +# Prerequisites setup by script test_xsk_prerequisites.sh: +# +# Set up veth interfaces as per the topology shown ^^: +# * setup two veth interfaces and one namespace +# ** veth in root namespace +# ** veth in af_xdp namespace +# ** namespace af_xdp +# * create a spec file veth.spec that includes this run-time configuration +# that is read by test scripts - filenames prefixed with test_xsk_ +# *** and are randomly generated 4 digit numbers used to avoid +# conflict with any existing interface +# * tests the veth and xsk layers of the topology +# +# Kernel configuration: +# - +# See "config" file for recommended kernel config options. +# +# Turn on XDP sockets and veth support when compiling i.e. +# Networking support --> +# Networking options --> +# [ * ] XDP sockets +# +# Executing Tests: +# +# Must run with CAP_NET_ADMIN capability. +# +# Run (summary only): +# sudo make summary=1 run_tests +# +# Run (full color-coded output): +# sudo make colorconsole=1 run_tests +# +# R
[PATCH bpf-next v2 3/5] selftests/bpf: xsk selftests - DRV POLL, NOPOLL
Adds following tests: 2. AF_XDP DRV/Native mode Works on any netdevice with XDP_REDIRECT support, driver dependent. Processes packets before SKB allocation. Provides better performance than SKB. Driver hook available just after DMA of buffer descriptor. a. nopoll b. poll * Only copy mode is supported because veth does not currently support zero-copy mode Signed-off-by: Weqaar Janjua --- tools/testing/selftests/bpf/Makefile | 4 +++- .../selftests/bpf/test_xsk_drv_nopoll.sh | 20 .../selftests/bpf/test_xsk_drv_poll.sh| 23 +++ .../selftests/bpf/test_xsk_skb_poll.sh| 3 --- tools/testing/selftests/bpf/xdpxceiver.c | 22 +++--- tools/testing/selftests/bpf/xdpxceiver.h | 1 + 6 files changed, 66 insertions(+), 7 deletions(-) create mode 100755 tools/testing/selftests/bpf/test_xsk_drv_nopoll.sh create mode 100755 tools/testing/selftests/bpf/test_xsk_drv_poll.sh diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 17af570a32d7..9dd3f3b9014f 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -74,7 +74,9 @@ TEST_PROGS := test_kmod.sh \ test_bpftool_metadata.sh \ test_xsk_prerequisites.sh \ test_xsk_skb_nopoll.sh \ - test_xsk_skb_poll.sh + test_xsk_skb_poll.sh \ + test_xsk_drv_nopoll.sh \ + test_xsk_drv_poll.sh TEST_PROGS_EXTENDED := with_addr.sh \ with_tunnels.sh \ diff --git a/tools/testing/selftests/bpf/test_xsk_drv_nopoll.sh b/tools/testing/selftests/bpf/test_xsk_drv_nopoll.sh new file mode 100755 index ..a7e895bc4bfd --- /dev/null +++ b/tools/testing/selftests/bpf/test_xsk_drv_nopoll.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright(c) 2020 Intel Corporation. + +# See test_xsk_prerequisites.sh for detailed information on tests + +. xsk_prereqs.sh +. xsk_env.sh + +TEST_NAME="DRV NOPOLL" + +vethXDPnative ${VETH0} ${VETH1} ${NS1} + +params=("-N") +execxdpxceiver params + +retval=$? +test_status $retval "${TEST_NAME}" + +test_exit $retval 0 diff --git a/tools/testing/selftests/bpf/test_xsk_drv_poll.sh b/tools/testing/selftests/bpf/test_xsk_drv_poll.sh new file mode 100755 index ..1fe488d5794a --- /dev/null +++ b/tools/testing/selftests/bpf/test_xsk_drv_poll.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright(c) 2020 Intel Corporation. + +# See test_xsk_prerequisites.sh for detailed information on tests + +. xsk_prereqs.sh +. xsk_env.sh + +TEST_NAME="DRV POLL" + +vethXDPnative ${VETH0} ${VETH1} ${NS1} + +params=("-N" "-p") +execxdpxceiver params + +retval=$? +test_status $retval "${TEST_NAME}" + +# Must be called in the last test to execute +cleanup_exit ${VETH0} ${VETH1} ${NS1} + +test_exit $retval 0 diff --git a/tools/testing/selftests/bpf/test_xsk_skb_poll.sh b/tools/testing/selftests/bpf/test_xsk_skb_poll.sh index d152c8a24251..962a89b40a32 100755 --- a/tools/testing/selftests/bpf/test_xsk_skb_poll.sh +++ b/tools/testing/selftests/bpf/test_xsk_skb_poll.sh @@ -17,7 +17,4 @@ execxdpxceiver params retval=$? test_status $retval "${TEST_NAME}" -# Must be called in the last test to execute -cleanup_exit ${VETH0} ${VETH1} ${NS1} - test_exit $retval 0 diff --git a/tools/testing/selftests/bpf/xdpxceiver.c b/tools/testing/selftests/bpf/xdpxceiver.c index 106307155bbe..e998200502de 100644 --- a/tools/testing/selftests/bpf/xdpxceiver.c +++ b/tools/testing/selftests/bpf/xdpxceiver.c @@ -27,7 +27,16 @@ *a. nopoll - soft-irq processing *b. poll - using poll() syscall * - * Total tests: 2 + * 2. AF_XDP DRV/Native mode + *Works on any netdevice with XDP_REDIRECT support, driver dependent. Processes + *packets before SKB allocation. Provides better performance than SKB. Driver + *hook available just after DMA of buffer descriptor. + *a. nopoll + *b. poll + *- Only copy mode is supported because veth does not currently support + * zero-copy mode + * + * Total tests: 4 * * Flow: * - @@ -87,7 +96,7 @@ static void __exit_with_error(int error, const char *file, const char *func, int #define exit_with_error(error) __exit_with_error(error, __FILE__, __func__, __LINE__) #define print_ksft_result(void)\ - (ksft_test_result_pass("PASS: %s %s\n", uut ? "" : "SKB", opt_poll ? "POLL" : "NOPOLL")) + (ksft_test_result_pass("PASS: %s %s\n", uut ? "DRV" : "SKB", opt_poll ? "POLL" : "NOPOLL")) static void pthread_init_mutex(void) { @@ -310,6 +319,7 @@ static struct option long_options[] = { {"queue", optional_argument, 0, 'q'}, {"poll", no_argument, 0, 'p'}, {"xdp-skb", no_argument, 0, 'S'}, + {"xdp-native", no_argument, 0, 'N'}, {"copy", no_argument, 0, 'c'}, {"debug", optional_argument, 0, 'D'}, {"tx-pkt-count", optional_argument, 0, 'C'}, @@ -325,6 +335,7 @@ s
Re: [PATCH bpf-next V6 2/7] bpf: fix bpf_fib_lookup helper MTU check for SKB ctx
Hi I report here the issue with the previous patch. The code is now checking against params->tot_len but then it is still using is_skb_forwardable. Consider this case where I shrink the packet: skb->len == 1520 dev->mtu == 1500 params->tot_len == 1480 So the incoming pkt has len 1520, and the out interface has mtu 1500. In this case fragmentation is not needed because params->tot_len < dev->mtu. However the code calls is_skb_forwardable and may return false because skb->len > dev->mtu, resulting in BPF_FIB_LKUP_RET_FRAG_NEEDED. What I propose is using params->tot_len only if provided, without falling back to use is_skb_forwardable when provided. Something like this: if (params->tot_len > 0) { if (params->tot_len > mtu) rc = BPF_FIB_LKUP_RET_FRAG_NEEDED; } else if (!is_skb_forwardable(dev, skb)) { rc = BPF_FIB_LKUP_RET_FRAG_NEEDED; } However, doing so we are skipping more relaxed MTU checks inside is_skb_forwardable, so I'm not sure about this. Please comment Il giorno ven 20 nov 2020 alle ore 09:26 Jesper Dangaard Brouer ha scritto: > > On Wed, 18 Nov 2020 16:29:35 +0100 > Jesper Dangaard Brouer wrote: > > > BPF end-user on Cilium slack-channel (Carlo Carraro) wants to use > > bpf_fib_lookup for doing MTU-check, but *prior* to extending packet size, > > by adjusting fib_params 'tot_len' with the packet length plus the > > expected encap size. (Just like the bpf_check_mtu helper supports). He > > discovered that for SKB ctx the param->tot_len was not used, instead > > skb->len was used (via MTU check in is_skb_forwardable()). > > > > Fix this by using fib_params 'tot_len' for MTU check. If not provided > > (e.g. zero) then keep existing behaviour intact. > > Carlo pointed out (in slack) that the logic is not correctly > implemented in this patch. > > I will send a V7. > > > > Fixes: 4c79579b44b1 ("bpf: Change bpf_fib_lookup to return lookup status") > > Reported-by: Carlo Carraro > > Signed-off-by: Jesper Dangaard Brouer > > --- > > net/core/filter.c | 12 +++- > > 1 file changed, 11 insertions(+), 1 deletion(-) > > > > diff --git a/net/core/filter.c b/net/core/filter.c > > index 1ee97fdeea64..ae1fe8e6069a 100644 > > --- a/net/core/filter.c > > +++ b/net/core/filter.c > > @@ -5567,10 +5567,20 @@ BPF_CALL_4(bpf_skb_fib_lookup, struct sk_buff *, > > skb, > > > > if (!rc) { > > struct net_device *dev; > > + u32 mtu; > > > > dev = dev_get_by_index_rcu(net, params->ifindex); > > - if (!is_skb_forwardable(dev, skb)) > > + mtu = dev->mtu; > > + > > + /* Using tot_len for L3 MTU check if provided by user. Notice > > at > > + * this TC cls_bpf level skb->len contains L2 size, but > > + * is_skb_forwardable takes that into account. > > + */ > > + if (params->tot_len > mtu) { > > rc = BPF_FIB_LKUP_RET_FRAG_NEEDED; > > + } else if (!is_skb_forwardable(dev, skb)) { > > + rc = BPF_FIB_LKUP_RET_FRAG_NEEDED; > > + } > > } > > > > return rc; > > -- > Best regards, > Jesper Dangaard Brouer > MSc.CS, Principal Kernel Engineer at Red Hat > LinkedIn: http://www.linkedin.com/in/brouer >
Re: [PATCH net-next 2/4] net: dsa: Link aggregation support
On Thu, Nov 19, 2020 at 06:43:38PM -0800, Florian Fainelli wrote: > > > On 11/19/2020 4:30 PM, Andrew Lunn wrote: > >> +static struct dsa_lag *dsa_lag_get(struct dsa_switch_tree *dst, > >> + struct net_device *dev) > >> +{ > >> + unsigned long busy = 0; > >> + struct dsa_lag *lag; > >> + int id; > >> + > >> + list_for_each_entry(lag, &dst->lags, list) { > >> + set_bit(lag->id, &busy); > >> + > >> + if (lag->dev == dev) { > >> + kref_get(&lag->refcount); > >> + return lag; > >> + } > >> + } > >> + > >> + id = find_first_zero_bit(&busy, BITS_PER_LONG); > >> + if (id >= BITS_PER_LONG) > >> + return ERR_PTR(-ENOSPC); > >> + > >> + lag = kzalloc(sizeof(*lag), GFP_KERNEL); > >> + if (!lag) > >> + return ERR_PTR(-ENOMEM); > > > > Hi Tobias > > > > My comment last time was to statically allocated them at probe > > time. Worse case scenario is each port is alone in a LAG. Pointless, > > but somebody could configure it. In dsa_tree_setup_switches() you can > > count the number of ports and then allocate an array, or while setting > > up a port, add one more lag to the list of lags. > > The allocation is allowed to sleep (have not checked the calling context > of dsa_lag_get() whether this is OK) so what would be the upside of > doing upfront dsa_lag allocation which could be wasteful? Hi Florian It fits the pattern for the rest of the DSA core. We never allocate anything at runtime. That keeps the error handling simple, we don't need to deal with ENOMEM errors, undoing whatever we might of done, implementing transactions etc. And the memory involved here is small. I guess around 80 bytes per lag? So even for a 10 port switch, we are only talking about 800 bytes. That is not a lot. Andrew
pull-request: can-next 2020-11-20
Hello Jakub, hello David, here's a pull request of 25 patches for net-next/master. The first patch is by Yegor Yefremov and he improves the j1939 documentaton by adding tables for the CAN identifier and its fields. Then there are 8 patches by Oliver Hartkopp targeting the CAN driver infrastructure and drivers. These add support for optional DLC element to the Classical CAN frame structure. See patch ea7800565a12 ("can: add optional DLC element to Classical CAN frame structure") for details. Oliver's last patch adds len8_dlc support to several drivers. Stefan Mätje provides a patch to add len8_dlc support to the esd_usb2 driver. The next patch is by Oliver Hartkopp, too and adds support for modification of Classical CAN DLCs to CAN GW sockets. The next 3 patches target the nxp,flexcan DT bindings. One patch by my adds the missing uint32 reference to the clock-frequency property. Joakim Zhang's patches fix the fsl,clk-source property and add the IMX_SC_R_CAN() macro to the imx firmware header file, which will be used in the flexcan driver later. Another patch by Joakim Zhang prepares the flexcan driver for SCU based stop-mode, by giving the existing, GPR based stop-mode, a _GPR postfix. The next 5 patches are by me, target the flexcan driver, and clean up the .ndo_open and .ndo_stop callbacks. These patches try to fix a sporadically hanging flexcan_close() during simultanious ifdown, sending of CAN messages and probably open CAN bus. I was never aber to reproduce, but these seem to fix the problem at the reporting user. As these changes are rather big, I'd like to mainline them via net-next/master. The next patches are by Jimmy Assarsson and Christer Beskow, they add support for new USB devices to the existing kvaser_usb driver. The last patch is by Kaixu Xia and simplifies the return in the mcp251xfd_chip_softreset() function in the mcp251xfd driver. regrads, Marc --- The following changes since commit 4082c502bf9c8a6afe4268c654d4e93ab7dfeb69: Merge branch 'enetc-clean-endianness-warnings-up' (2020-11-19 22:05:44 -0800) are available in the Git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next.git tags/linux-can-next-for-5.11-20201120 for you to fetch changes up to 275f6010b6994ad286a859062c03be050e8073ad: can: mcp251xfd: remove useless code in mcp251xfd_chip_softreset (2020-11-20 12:06:47 +0100) ---- linux-can-next-for-5.11-20201120 Christer Beskow (1): can: kvaser_usb: kvaser_usb_hydra: Add support for new device variant Jimmy Assarsson (3): can: kvaser_usb: Add USB_{LEAF,HYDRA}_PRODUCT_ID_END defines can: kvaser_usb: Add new Kvaser Leaf v2 devices can: kvaser_usb: Add new Kvaser hydra devices Joakim Zhang (3): dt-bindings: can: fsl,flexcan: fix fsl,clk-source property dt-bindings: firmware: add IMX_SC_R_CAN(x) macro for CAN can: flexcan: rename macro FLEXCAN_QUIRK_SETUP_STOP_MODE -> FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR Kaixu Xia (1): can: mcp251xfd: remove useless code in mcp251xfd_chip_softreset Marc Kleine-Budde (6): dt-bindings: can: fsl,flexcan: add uint32 reference to clock-frequency property can: flexcan: factor out enabling and disabling of interrupts into separate function can: flexcan: move enabling/disabling of interrupts from flexcan_chip_{start,stop}() to callers can: flexcan: flexcan_rx_offload_setup(): factor out mailbox and rx-offload setup into separate function can: flexcan: flexcan_open(): completely initialize controller before requesting IRQ can: flexcan: flexcan_close(): change order if commands to properly shut down the controller Oliver Hartkopp (9): can: add optional DLC element to Classical CAN frame structure can: rename get_can_dlc() macro with can_cc_dlc2len() can: remove obsolete get_canfd_dlc() macro can: replace can_dlc as variable/element for payload length can: rename CAN FD related can_len2dlc and can_dlc2len helpers can: update documentation for DLC usage in Classical CAN can: drivers: introduce helpers to access Classical CAN DLC values can: drivers: add len8_dlc support for various CAN adapters can: gw: support modification of Classical CAN DLCs Stefan Mätje (1): can: drivers: add len8_dlc support for esd_usb2 CAN adapter Yegor Yefremov (1): can: j1939: add tables for the CAN identifier and its fields .../devicetree/bindings/net/can/fsl,flexcan.yaml | 5 +- Documentation/networking/can.rst | 70 ++--- Documentation/networking/j1939.rst | 46 +- drivers/net/can/at91_can.c | 14 +- drivers/net/can/c_can/c_can.c | 20 +-- drivers/net/can/cc770/cc770.c
[net-next 07/25] can: update documentation for DLC usage in Classical CAN
From: Oliver Hartkopp The extension of struct can_frame with the len8_dlc element and the can_dlc naming issue required an update of the documentation. Additionally introduce the term 'Classical CAN' which has been established by CAN in Automation to separate the original CAN2.0 A/B from CAN FD. Updated some data structures and flags. Signed-off-by: Oliver Hartkopp Link: https://lore.kernel.org/r/20201110101852.1973-7-socket...@hartkopp.net Signed-off-by: Marc Kleine-Budde --- Documentation/networking/can.rst | 68 1 file changed, 52 insertions(+), 16 deletions(-) diff --git a/Documentation/networking/can.rst b/Documentation/networking/can.rst index 4895b0dd2714..f8dae662e454 100644 --- a/Documentation/networking/can.rst +++ b/Documentation/networking/can.rst @@ -228,20 +228,36 @@ send(2), sendto(2), sendmsg(2) and the recv* counterpart operations on the socket as usual. There are also CAN specific socket options described below. -The basic CAN frame structure and the sockaddr structure are defined -in include/linux/can.h: +The Classical CAN frame structure (aka CAN 2.0B), the CAN FD frame structure +and the sockaddr structure are defined in include/linux/can.h: .. code-block:: C struct can_frame { canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */ -__u8can_dlc; /* frame payload length in byte (0 .. 8) */ +union { +/* CAN frame payload length in byte (0 .. CAN_MAX_DLEN) + * was previously named can_dlc so we need to carry that + * name for legacy support + */ +__u8 len; +__u8 can_dlc; /* deprecated */ +}; __u8__pad; /* padding */ __u8__res0; /* reserved / padding */ -__u8__res1; /* reserved / padding */ +__u8len8_dlc; /* optional DLC for 8 byte payload length (9 .. 15) */ __u8data[8] __attribute__((aligned(8))); }; +Remark: The len element contains the payload length in bytes and should be +used instead of can_dlc. The deprecated can_dlc was misleadingly named as +it always contained the plain payload length in bytes and not the so called +'data length code' (DLC). + +To pass the raw DLC from/to a Classical CAN network device the len8_dlc +element can contain values 9 .. 15 when the len element is 8 (the real +payload length for all DLC values greater or equal to 8). + The alignment of the (linear) payload data[] to a 64bit boundary allows the user to define their own structs and unions to easily access the CAN payload. There is no given byteorder on the CAN bus by @@ -260,6 +276,23 @@ PF_PACKET socket, that also binds to a specific interface: /* transport protocol class address info (e.g. ISOTP) */ struct { canid_t rx_id, tx_id; } tp; +/* J1939 address information */ +struct { +/* 8 byte name when using dynamic addressing */ +__u64 name; + +/* pgn: + * 8 bit: PS in PDU2 case, else 0 + * 8 bit: PF + * 1 bit: DP + * 1 bit: reserved + */ +__u32 pgn; + +/* 1 byte address */ +__u8 addr; +} j1939; + /* reserved for future CAN protocols address information */ } can_addr; }; @@ -371,7 +404,7 @@ kernel interfaces (ABI) which heavily rely on the CAN frame with fixed eight bytes of payload (struct can_frame) like the CAN_RAW socket. Therefore e.g. the CAN_RAW socket supports a new socket option CAN_RAW_FD_FRAMES that switches the socket into a mode that allows the handling of CAN FD frames -and (legacy) CAN frames simultaneously (see :ref:`socketcan-rawfd`). +and Classical CAN frames simultaneously (see :ref:`socketcan-rawfd`). The struct canfd_frame is defined in include/linux/can.h: @@ -397,7 +430,7 @@ code (DLC) of the struct can_frame was used as a length information as the length and the DLC has a 1:1 mapping in the range of 0 .. 8. To preserve the easy handling of the length information the canfd_frame.len element contains a plain length value from 0 .. 64. So both canfd_frame.len and -can_frame.can_dlc are equal and contain a length information and no DLC. +can_frame.len are equal and contain a length information and no DLC. For details about the distinction of CAN and CAN FD capable devices and the mapping to the bus-relevant data length code (DLC), see :ref:`socketcan-can-fd-driver`. @@ -407,7 +440,7 @@ definitions are specified for CAN specific MTUs in include/linux/can.h: .. code-block:: C - #define CAN_MTU (
[net-next 02/25] can: add optional DLC element to Classical CAN frame structure
From: Oliver Hartkopp ISO 11898-1 Chapter 8.4.2.3 defines a 4 bit data length code (DLC) table which maps the DLC to the payload length of the CAN frame in bytes: DLC -> payload length 0 .. 8 -> 0 .. 8 9 .. 15 -> 8 Although the DLC values 8 .. 15 in Classical CAN always result in a payload length of 8 bytes these DLC values are transparently transmitted on the CAN bus. As the struct can_frame only provides a 'len' element (formerly 'can_dlc') which contains the plain payload length ( 0 .. 8 ) of the CAN frame, the raw DLC is not visible to the application programmer, e.g. for testing use-cases. To access the raw DLC values 9 .. 15 the len8_dlc element is introduced, which is only valid when the payload length 'len' is 8 and the DLC is greater than 8. The len8_dlc element is filled by the CAN interface driver and used for CAN frame creation by the CAN driver when the CAN_CTRLMODE_CC_LEN8_DLC flag is supported by the driver and enabled via netlink configuration interface. Reported-by: Vincent Mailhol Signed-off-by: Oliver Hartkopp Link: https://lore.kernel.org/r/20201110101852.1973-2-socket...@hartkopp.net Signed-off-by: Marc Kleine-Budde --- include/uapi/linux/can.h | 38 include/uapi/linux/can/netlink.h | 1 + 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/include/uapi/linux/can.h b/include/uapi/linux/can.h index 6a6d2c7655ff..f75238ac6dce 100644 --- a/include/uapi/linux/can.h +++ b/include/uapi/linux/can.h @@ -84,6 +84,7 @@ typedef __u32 can_err_mask_t; /* CAN payload length and DLC definitions according to ISO 11898-1 */ #define CAN_MAX_DLC 8 +#define CAN_MAX_RAW_DLC 15 #define CAN_MAX_DLEN 8 /* CAN FD payload length and DLC definitions according to ISO 11898-7 */ @@ -91,23 +92,32 @@ typedef __u32 can_err_mask_t; #define CANFD_MAX_DLEN 64 /** - * struct can_frame - basic CAN frame structure - * @can_id: CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition - * @can_dlc: frame payload length in byte (0 .. 8) aka data length code - * N.B. the DLC field from ISO 11898-1 Chapter 8.4.2.3 has a 1:1 - * mapping of the 'data length code' to the real payload length - * @__pad: padding - * @__res0: reserved / padding - * @__res1: reserved / padding - * @data:CAN frame payload (up to 8 byte) + * struct can_frame - Classical CAN frame structure (aka CAN 2.0B) + * @can_id: CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition + * @len: CAN frame payload length in byte (0 .. 8) + * @can_dlc: deprecated name for CAN frame payload length in byte (0 .. 8) + * @__pad:padding + * @__res0: reserved / padding + * @len8_dlc: optional DLC value (9 .. 15) at 8 byte payload length + *len8_dlc contains values from 9 .. 15 when the payload length is + *8 bytes but the DLC value (see ISO 11898-1) is greater then 8. + *CAN_CTRLMODE_CC_LEN8_DLC flag has to be enabled in CAN driver. + * @data: CAN frame payload (up to 8 byte) */ struct can_frame { canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */ - __u8can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */ - __u8__pad; /* padding */ - __u8__res0; /* reserved / padding */ - __u8__res1; /* reserved / padding */ - __u8data[CAN_MAX_DLEN] __attribute__((aligned(8))); + union { + /* CAN frame payload length in byte (0 .. CAN_MAX_DLEN) +* was previously named can_dlc so we need to carry that +* name for legacy support +*/ + __u8 len; + __u8 can_dlc; /* deprecated */ + }; + __u8 __pad; /* padding */ + __u8 __res0; /* reserved / padding */ + __u8 len8_dlc; /* optional DLC for 8 byte payload length (9 .. 15) */ + __u8 data[CAN_MAX_DLEN] __attribute__((aligned(8))); }; /* diff --git a/include/uapi/linux/can/netlink.h b/include/uapi/linux/can/netlink.h index 6f598b73839e..f730d443b918 100644 --- a/include/uapi/linux/can/netlink.h +++ b/include/uapi/linux/can/netlink.h @@ -100,6 +100,7 @@ struct can_ctrlmode { #define CAN_CTRLMODE_FD0x20/* CAN FD mode */ #define CAN_CTRLMODE_PRESUME_ACK 0x40/* Ignore missing CAN ACKs */ #define CAN_CTRLMODE_FD_NON_ISO0x80/* CAN FD in non-ISO mode */ +#define CAN_CTRLMODE_CC_LEN8_DLC 0x100 /* Classic CAN DLC option */ /* * CAN device statistics -- 2.29.2
[net-next 13/25] dt-bindings: can: fsl,flexcan: fix fsl,clk-source property
From: Joakim Zhang Correct fsl,clk-source example since flexcan driver uses "of_property_read_u8" to get this property. Fixes: 9d733992772d ("dt-bindings: can: flexcan: add PE clock source property to device tree") Signed-off-by: Joakim Zhang Link: https://lore.kernel.org/r/20201106105627.31061-2-qiangqing.zh...@nxp.com Signed-off-by: Marc Kleine-Budde --- Documentation/devicetree/bindings/net/can/fsl,flexcan.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/net/can/fsl,flexcan.yaml b/Documentation/devicetree/bindings/net/can/fsl,flexcan.yaml index 0133d777e78e..0d2df30f19db 100644 --- a/Documentation/devicetree/bindings/net/can/fsl,flexcan.yaml +++ b/Documentation/devicetree/bindings/net/can/fsl,flexcan.yaml @@ -100,7 +100,7 @@ properties: by default. 0: clock source 0 (oscillator clock) 1: clock source 1 (peripheral clock) -$ref: /schemas/types.yaml#/definitions/uint32 +$ref: /schemas/types.yaml#/definitions/uint8 default: 1 minimum: 0 maximum: 1 @@ -125,7 +125,7 @@ examples: interrupts = <48 0x2>; interrupt-parent = <&mpic>; clock-frequency = <2>; -fsl,clk-source = <0>; +fsl,clk-source = /bits/ 8 <0>; }; - | #include -- 2.29.2
[net-next 24/25] can: kvaser_usb: Add new Kvaser hydra devices
From: Jimmy Assarsson Add new Kvaser hydra devices. Signed-off-by: Jimmy Assarsson Link: https://lore.kernel.org/r/20201115163027.16851-6-jimmyassars...@gmail.com Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/Kconfig | 3 +++ drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | 8 +++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/usb/Kconfig b/drivers/net/can/usb/Kconfig index 161f15e5218d..c1e5d5b570b6 100644 --- a/drivers/net/can/usb/Kconfig +++ b/drivers/net/can/usb/Kconfig @@ -74,6 +74,9 @@ config CAN_KVASER_USB - Kvaser USBcan Light 4xHS - Kvaser USBcan Pro 2xHS v2 - Kvaser USBcan Pro 5xHS + - Kvaser U100 + - Kvaser U100P + - Kvaser U100S - ATI Memorator Pro 2xHS v2 - ATI USBcan Pro 2xHS v2 diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c index ad66a3b1a29d..e2d58846c40c 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c @@ -83,8 +83,11 @@ #define USB_ATI_USBCAN_PRO_2HS_V2_PRODUCT_ID 268 #define USB_ATI_MEMO_PRO_2HS_V2_PRODUCT_ID 269 #define USB_HYBRID_PRO_CANLIN_PRODUCT_ID 270 +#define USB_U100_PRODUCT_ID273 +#define USB_U100P_PRODUCT_ID 274 +#define USB_U100S_PRODUCT_ID 275 #define USB_HYDRA_PRODUCT_ID_END \ - USB_HYBRID_PRO_CANLIN_PRODUCT_ID + USB_U100S_PRODUCT_ID static inline bool kvaser_is_leaf(const struct usb_device_id *id) { @@ -187,6 +190,9 @@ static const struct usb_device_id kvaser_usb_table[] = { { USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_USBCAN_PRO_2HS_V2_PRODUCT_ID) }, { USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_MEMO_PRO_2HS_V2_PRODUCT_ID) }, { USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_PRO_CANLIN_PRODUCT_ID) }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_U100_PRODUCT_ID) }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_U100P_PRODUCT_ID) }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_U100S_PRODUCT_ID) }, { } }; MODULE_DEVICE_TABLE(usb, kvaser_usb_table); -- 2.29.2
[net-next 23/25] can: kvaser_usb: kvaser_usb_hydra: Add support for new device variant
From: Christer Beskow Add support for a new variant of devices using the hydra platform, based on NXP i.MX RT (flexcan). Signed-off-by: Christer Beskow Signed-off-by: Jimmy Assarsson Link: https://lore.kernel.org/r/20201115163027.16851-5-jimmyassars...@gmail.com Signed-off-by: Marc Kleine-Budde --- .../net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 37 +++ 1 file changed, 37 insertions(+) diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c index 107b205b77ab..480bd2ecb296 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c @@ -34,6 +34,7 @@ /* Forward declarations */ static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_kcan; static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_flexc; +static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_rt; #define KVASER_USB_HYDRA_BULK_EP_IN_ADDR 0x82 #define KVASER_USB_HYDRA_BULK_EP_OUT_ADDR 0x02 @@ -135,6 +136,7 @@ struct kvaser_cmd_sw_detail_req { #define KVASER_USB_HYDRA_SW_FLAG_CANFD BIT(10) #define KVASER_USB_HYDRA_SW_FLAG_NONISOBIT(11) #define KVASER_USB_HYDRA_SW_FLAG_EXT_CAP BIT(12) +#define KVASER_USB_HYDRA_SW_FLAG_CAN_FREQ_80M BIT(13) struct kvaser_cmd_sw_detail_res { __le32 sw_flags; __le32 sw_version; @@ -383,6 +385,30 @@ static const struct can_bittiming_const kvaser_usb_hydra_flexc_bittiming_c = { .brp_inc = 1, }; +static const struct can_bittiming_const kvaser_usb_hydra_rt_bittiming_c = { + .name = "kvaser_usb_rt", + .tseg1_min = 2, + .tseg1_max = 96, + .tseg2_min = 2, + .tseg2_max = 32, + .sjw_max = 32, + .brp_min = 1, + .brp_max = 1024, + .brp_inc = 1, +}; + +static const struct can_bittiming_const kvaser_usb_hydra_rtd_bittiming_c = { + .name = "kvaser_usb_rt", + .tseg1_min = 2, + .tseg1_max = 39, + .tseg2_min = 2, + .tseg2_max = 8, + .sjw_max = 8, + .brp_min = 1, + .brp_max = 1024, + .brp_inc = 1, +}; + #define KVASER_USB_HYDRA_TRANSID_BITS 12 #define KVASER_USB_HYDRA_TRANSID_MASK \ GENMASK(KVASER_USB_HYDRA_TRANSID_BITS - 1, 0) @@ -1727,6 +1753,8 @@ static int kvaser_usb_hydra_get_software_details(struct kvaser_usb *dev) if (flags & KVASER_USB_HYDRA_SW_FLAG_FREQ_80M) dev->cfg = &kvaser_usb_hydra_dev_cfg_kcan; + else if (flags & KVASER_USB_HYDRA_SW_FLAG_CAN_FREQ_80M) + dev->cfg = &kvaser_usb_hydra_dev_cfg_rt; else dev->cfg = &kvaser_usb_hydra_dev_cfg_flexc; @@ -2026,3 +2054,12 @@ static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_flexc = { .timestamp_freq = 1, .bittiming_const = &kvaser_usb_hydra_flexc_bittiming_c, }; + +static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_rt = { + .clock = { + .freq = 8000, + }, + .timestamp_freq = 24, + .bittiming_const = &kvaser_usb_hydra_rt_bittiming_c, + .data_bittiming_const = &kvaser_usb_hydra_rtd_bittiming_c, +}; -- 2.29.2
[net-next 18/25] can: flexcan: flexcan_rx_offload_setup(): factor out mailbox and rx-offload setup into separate function
In an upcoming patch the order of operations in flexcan_open() are changed. Introduce convenience function to make that patch simpler. Link: https://lore.kernel.org/r/20201119100917.3013281-4-...@pengutronix.de Signed-off-by: Marc Kleine-Budde --- drivers/net/can/flexcan.c | 74 ++- 1 file changed, 42 insertions(+), 32 deletions(-) diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 64c174aa868b..0705b6384e49 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -1346,6 +1346,47 @@ static void flexcan_ram_init(struct net_device *dev) priv->write(reg_ctrl2, ®s->ctrl2); } +static int flexcan_rx_offload_setup(struct net_device *dev) +{ + struct flexcan_priv *priv = netdev_priv(dev); + int err; + + if (priv->can.ctrlmode & CAN_CTRLMODE_FD) + priv->mb_size = sizeof(struct flexcan_mb) + CANFD_MAX_DLEN; + else + priv->mb_size = sizeof(struct flexcan_mb) + CAN_MAX_DLEN; + priv->mb_count = (sizeof(priv->regs->mb[0]) / priv->mb_size) + +(sizeof(priv->regs->mb[1]) / priv->mb_size); + + if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) + priv->tx_mb_reserved = + flexcan_get_mb(priv, FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP); + else + priv->tx_mb_reserved = + flexcan_get_mb(priv, FLEXCAN_TX_MB_RESERVED_OFF_FIFO); + priv->tx_mb_idx = priv->mb_count - 1; + priv->tx_mb = flexcan_get_mb(priv, priv->tx_mb_idx); + priv->tx_mask = FLEXCAN_IFLAG_MB(priv->tx_mb_idx); + + priv->offload.mailbox_read = flexcan_mailbox_read; + + if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { + priv->offload.mb_first = FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST; + priv->offload.mb_last = priv->mb_count - 2; + + priv->rx_mask = GENMASK_ULL(priv->offload.mb_last, + priv->offload.mb_first); + err = can_rx_offload_add_timestamp(dev, &priv->offload); + } else { + priv->rx_mask = FLEXCAN_IFLAG_RX_FIFO_OVERFLOW | + FLEXCAN_IFLAG_RX_FIFO_AVAILABLE; + err = can_rx_offload_add_fifo(dev, &priv->offload, + FLEXCAN_NAPI_WEIGHT); + } + + return err; +} + static void flexcan_chip_interrupts_enable(const struct net_device *dev) { const struct flexcan_priv *priv = netdev_priv(dev); @@ -1675,38 +1716,7 @@ static int flexcan_open(struct net_device *dev) if (err) goto out_transceiver_disable; - if (priv->can.ctrlmode & CAN_CTRLMODE_FD) - priv->mb_size = sizeof(struct flexcan_mb) + CANFD_MAX_DLEN; - else - priv->mb_size = sizeof(struct flexcan_mb) + CAN_MAX_DLEN; - priv->mb_count = (sizeof(priv->regs->mb[0]) / priv->mb_size) + -(sizeof(priv->regs->mb[1]) / priv->mb_size); - - if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) - priv->tx_mb_reserved = - flexcan_get_mb(priv, FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP); - else - priv->tx_mb_reserved = - flexcan_get_mb(priv, FLEXCAN_TX_MB_RESERVED_OFF_FIFO); - priv->tx_mb_idx = priv->mb_count - 1; - priv->tx_mb = flexcan_get_mb(priv, priv->tx_mb_idx); - priv->tx_mask = FLEXCAN_IFLAG_MB(priv->tx_mb_idx); - - priv->offload.mailbox_read = flexcan_mailbox_read; - - if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { - priv->offload.mb_first = FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST; - priv->offload.mb_last = priv->mb_count - 2; - - priv->rx_mask = GENMASK_ULL(priv->offload.mb_last, - priv->offload.mb_first); - err = can_rx_offload_add_timestamp(dev, &priv->offload); - } else { - priv->rx_mask = FLEXCAN_IFLAG_RX_FIFO_OVERFLOW | - FLEXCAN_IFLAG_RX_FIFO_AVAILABLE; - err = can_rx_offload_add_fifo(dev, &priv->offload, - FLEXCAN_NAPI_WEIGHT); - } + err = flexcan_rx_offload_setup(dev); if (err) goto out_free_irq; -- 2.29.2
[net-next 01/25] can: j1939: add tables for the CAN identifier and its fields
From: Yegor Yefremov Use table markup to show the structure of the CAN identifier, PGN, PDU1, and PDU2 formats. Also add introductory sentence. Signed-off-by: Yegor Yefremov Link: https://lore.kernel.org/r/20201104155730.25196-1-yegorsli...@googlemail.com [mkl: removed trailing whitespace] Signed-off-by: Marc Kleine-Budde --- Documentation/networking/j1939.rst | 46 +++--- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/Documentation/networking/j1939.rst b/Documentation/networking/j1939.rst index 0a4b73b03b99..b705d2801e9c 100644 --- a/Documentation/networking/j1939.rst +++ b/Documentation/networking/j1939.rst @@ -69,18 +69,56 @@ J1939 concepts PGN --- +The J1939 protocol uses the 29-bit CAN identifier with the following structure: + + == + 29 bit CAN-ID + -- + Bit positions within the CAN-ID + -- + 28 ... 26 25 ... 87 ... 0 + == + Priority PGN SA (Source Address) + == + The PGN (Parameter Group Number) is a number to identify a packet. The PGN is composed as follows: -1 bit : Reserved Bit -1 bit : Data Page -8 bits : PF (PDU Format) -8 bits : PS (PDU Specific) + + == = = + PGN + -- + Bit positions within the CAN-ID + -- + 2524 23 ... 16 15 ... 8 + == = = + R (Reserved) DP (Data Page) PF (PDU Format)PS (PDU Specific) + == = = In J1939-21 distinction is made between PDU1 format (where PF < 240) and PDU2 format (where PF >= 240). Furthermore, when using the PDU2 format, the PS-field contains a so-called Group Extension, which is part of the PGN. When using PDU2 format, the Group Extension is set in the PS-field. + == + PDU1 Format (specific) (peer to peer) + + Bit positions within the CAN-ID + + 23 ... 16 15 ... 8 + == + 00h ... EFh DA (Destination address) + == + + == + PDU2 Format (global) (broadcast) + + Bit positions within the CAN-ID + + 23 ... 16 15 ... 8 + == + F0h ... FFh GE (Group Extenstion) + == + On the other hand, when using PDU1 format, the PS-field contains a so-called Destination Address, which is _not_ part of the PGN. When communicating a PGN from user space to kernel (or vice versa) and PDU2 format is used, the PS-field base-commit: 4082c502bf9c8a6afe4268c654d4e93ab7dfeb69 -- 2.29.2
[net-next 14/25] dt-bindings: firmware: add IMX_SC_R_CAN(x) macro for CAN
From: Joakim Zhang Add IMX_SC_R_CAN(x) macro for CAN. Suggested-by: Marc Kleine-Budde Acked-by: Shawn Guo Signed-off-by: Joakim Zhang Link: https://lore.kernel.org/r/20201106105627.31061-5-qiangqing.zh...@nxp.com Signed-off-by: Marc Kleine-Budde --- include/dt-bindings/firmware/imx/rsrc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dt-bindings/firmware/imx/rsrc.h b/include/dt-bindings/firmware/imx/rsrc.h index 54278d5c1856..43885056557c 100644 --- a/include/dt-bindings/firmware/imx/rsrc.h +++ b/include/dt-bindings/firmware/imx/rsrc.h @@ -111,6 +111,7 @@ #define IMX_SC_R_CAN_0 105 #define IMX_SC_R_CAN_1 106 #define IMX_SC_R_CAN_2 107 +#define IMX_SC_R_CAN(x)(IMX_SC_R_CAN_0 + (x)) #define IMX_SC_R_DMA_1_CH0 108 #define IMX_SC_R_DMA_1_CH1 109 #define IMX_SC_R_DMA_1_CH2 110 -- 2.29.2
[net-next 16/25] can: flexcan: factor out enabling and disabling of interrupts into separate function
The upcoming patches are going to move the enabling and disabling of the interrupts. Introduce convenience functions to make these patches simpler. Link: https://lore.kernel.org/r/20201119100917.3013281-2-...@pengutronix.de Signed-off-by: Marc Kleine-Budde --- drivers/net/can/flexcan.c | 41 ++- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 56a6bcc6d9d7..681a4d82681c 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -1346,6 +1346,31 @@ static void flexcan_ram_init(struct net_device *dev) priv->write(reg_ctrl2, ®s->ctrl2); } +static void flexcan_chip_interrupts_enable(const struct net_device *dev) +{ + const struct flexcan_priv *priv = netdev_priv(dev); + struct flexcan_regs __iomem *regs = priv->regs; + u64 reg_imask; + + disable_irq(dev->irq); + priv->write(priv->reg_ctrl_default, ®s->ctrl); + reg_imask = priv->rx_mask | priv->tx_mask; + priv->write(upper_32_bits(reg_imask), ®s->imask2); + priv->write(lower_32_bits(reg_imask), ®s->imask1); + enable_irq(dev->irq); +} + +static void flexcan_chip_interrupts_disable(const struct net_device *dev) +{ + const struct flexcan_priv *priv = netdev_priv(dev); + struct flexcan_regs __iomem *regs = priv->regs; + + priv->write(0, ®s->imask2); + priv->write(0, ®s->imask1); + priv->write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL, + ®s->ctrl); +} + /* flexcan_chip_start * * this functions is entered with clocks enabled @@ -1356,7 +1381,6 @@ static int flexcan_chip_start(struct net_device *dev) struct flexcan_priv *priv = netdev_priv(dev); struct flexcan_regs __iomem *regs = priv->regs; u32 reg_mcr, reg_ctrl, reg_ctrl2, reg_mecr; - u64 reg_imask; int err, i; struct flexcan_mb __iomem *mb; @@ -1574,13 +1598,7 @@ static int flexcan_chip_start(struct net_device *dev) priv->can.state = CAN_STATE_ERROR_ACTIVE; - /* enable interrupts atomically */ - disable_irq(dev->irq); - priv->write(priv->reg_ctrl_default, ®s->ctrl); - reg_imask = priv->rx_mask | priv->tx_mask; - priv->write(upper_32_bits(reg_imask), ®s->imask2); - priv->write(lower_32_bits(reg_imask), ®s->imask1); - enable_irq(dev->irq); + flexcan_chip_interrupts_enable(dev); /* print chip status */ netdev_dbg(dev, "%s: reading mcr=0x%08x ctrl=0x%08x\n", __func__, @@ -1600,7 +1618,6 @@ static int flexcan_chip_start(struct net_device *dev) static int __flexcan_chip_stop(struct net_device *dev, bool disable_on_error) { struct flexcan_priv *priv = netdev_priv(dev); - struct flexcan_regs __iomem *regs = priv->regs; int err; /* freeze + disable module */ @@ -1611,11 +1628,7 @@ static int __flexcan_chip_stop(struct net_device *dev, bool disable_on_error) if (err && !disable_on_error) goto out_chip_unfreeze; - /* Disable all interrupts */ - priv->write(0, ®s->imask2); - priv->write(0, ®s->imask1); - priv->write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL, - ®s->ctrl); + flexcan_chip_interrupts_disable(dev); priv->can.state = CAN_STATE_STOPPED; -- 2.29.2
[net-next 19/25] can: flexcan: flexcan_open(): completely initialize controller before requesting IRQ
This patch changes the order in which the flexcan controller is brought up during flexcan_open(). It makes sure that the chip is completely initialized before the IRQs are requested and finally enabled. Link: https://lore.kernel.org/r/20201119100917.3013281-5-...@pengutronix.de Signed-off-by: Marc Kleine-Budde --- drivers/net/can/flexcan.c | 21 +++-- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 0705b6384e49..e98368be1669 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -1712,32 +1712,33 @@ static int flexcan_open(struct net_device *dev) if (err) goto out_close; - err = request_irq(dev->irq, flexcan_irq, IRQF_SHARED, dev->name, dev); + err = flexcan_rx_offload_setup(dev); if (err) goto out_transceiver_disable; - err = flexcan_rx_offload_setup(dev); + err = flexcan_chip_start(dev); if (err) - goto out_free_irq; + goto out_can_rx_offload_del; - /* start chip and queuing */ - err = flexcan_chip_start(dev); + can_rx_offload_enable(&priv->offload); + + err = request_irq(dev->irq, flexcan_irq, IRQF_SHARED, dev->name, dev); if (err) - goto out_offload_del; + goto out_can_rx_offload_disable; flexcan_chip_interrupts_enable(dev); can_led_event(dev, CAN_LED_EVENT_OPEN); - can_rx_offload_enable(&priv->offload); netif_start_queue(dev); return 0; - out_offload_del: + out_can_rx_offload_disable: + can_rx_offload_disable(&priv->offload); + flexcan_chip_stop(dev); + out_can_rx_offload_del: can_rx_offload_del(&priv->offload); - out_free_irq: - free_irq(dev->irq, dev); out_transceiver_disable: flexcan_transceiver_disable(priv); out_close: -- 2.29.2
[net-next 11/25] can: gw: support modification of Classical CAN DLCs
From: Oliver Hartkopp Add support for data length code modifications for Classical CAN. The netlink configuration interface always allowed to pass any value that fits into a byte, therefore only the modification process had to be extended to handle the raw DLC represenation of Classical CAN frames. When a DLC value from 0 .. F is provided for Classical CAN frame modifications the 'len' value is modified as-is with the exception that potentially existing 9 .. F DLC values in the len8_dlc element are moved to the 'len' element for the modification operation by mod_retrieve_ccdlc(). After the modification the Classical CAN frame DLC information is brought back into the correct format by mod_store_ccdlc() which is filling 'len' and 'len8_dlc' accordingly. Signed-off-by: Oliver Hartkopp Link: https://lore.kernel.org/r/20201119084921.2621-1-socket...@hartkopp.net Signed-off-by: Marc Kleine-Budde --- include/uapi/linux/can/gw.h | 4 +- net/can/gw.c| 78 + 2 files changed, 72 insertions(+), 10 deletions(-) diff --git a/include/uapi/linux/can/gw.h b/include/uapi/linux/can/gw.h index c2190bbe21d8..e4f0957554f3 100644 --- a/include/uapi/linux/can/gw.h +++ b/include/uapi/linux/can/gw.h @@ -98,8 +98,8 @@ enum { /* CAN frame elements that are affected by curr. 3 CAN frame modifications */ #define CGW_MOD_ID 0x01 -#define CGW_MOD_DLC0x02/* contains the data length in bytes */ -#define CGW_MOD_LENCGW_MOD_DLC /* CAN FD length representation */ +#define CGW_MOD_DLC0x02/* Classical CAN data length code */ +#define CGW_MOD_LENCGW_MOD_DLC /* CAN FD (plain) data length */ #define CGW_MOD_DATA 0x04 #define CGW_MOD_FLAGS 0x08/* CAN FD flags */ diff --git a/net/can/gw.c b/net/can/gw.c index de5e8859ec9b..8598d9da0e5f 100644 --- a/net/can/gw.c +++ b/net/can/gw.c @@ -199,6 +199,68 @@ static void mod_set_fddata(struct canfd_frame *cf, struct cf_mod *mod) memcpy(cf->data, mod->modframe.set.data, CANFD_MAX_DLEN); } +/* retrieve valid CC DLC value and store it into 'len' */ +static void mod_retrieve_ccdlc(struct canfd_frame *cf) +{ + struct can_frame *ccf = (struct can_frame *)cf; + + /* len8_dlc is only valid if len == CAN_MAX_DLEN */ + if (ccf->len != CAN_MAX_DLEN) + return; + + /* do we have a valid len8_dlc value from 9 .. 15 ? */ + if (ccf->len8_dlc > CAN_MAX_DLEN && ccf->len8_dlc <= CAN_MAX_RAW_DLC) + ccf->len = ccf->len8_dlc; +} + +/* convert valid CC DLC value in 'len' into struct can_frame elements */ +static void mod_store_ccdlc(struct canfd_frame *cf) +{ + struct can_frame *ccf = (struct can_frame *)cf; + + /* clear potential leftovers */ + ccf->len8_dlc = 0; + + /* plain data length 0 .. 8 - that was easy */ + if (ccf->len <= CAN_MAX_DLEN) + return; + + /* potentially broken values are catched in can_can_gw_rcv() */ + if (ccf->len > CAN_MAX_RAW_DLC) + return; + + /* we have a valid dlc value from 9 .. 15 in ccf->len */ + ccf->len8_dlc = ccf->len; + ccf->len = CAN_MAX_DLEN; +} + +static void mod_and_ccdlc(struct canfd_frame *cf, struct cf_mod *mod) +{ + mod_retrieve_ccdlc(cf); + mod_and_len(cf, mod); + mod_store_ccdlc(cf); +} + +static void mod_or_ccdlc(struct canfd_frame *cf, struct cf_mod *mod) +{ + mod_retrieve_ccdlc(cf); + mod_or_len(cf, mod); + mod_store_ccdlc(cf); +} + +static void mod_xor_ccdlc(struct canfd_frame *cf, struct cf_mod *mod) +{ + mod_retrieve_ccdlc(cf); + mod_xor_len(cf, mod); + mod_store_ccdlc(cf); +} + +static void mod_set_ccdlc(struct canfd_frame *cf, struct cf_mod *mod) +{ + mod_set_len(cf, mod); + mod_store_ccdlc(cf); +} + static void canframecpy(struct canfd_frame *dst, struct can_frame *src) { /* Copy the struct members separately to ensure that no uninitialized @@ -842,8 +904,8 @@ static int cgw_parse_attr(struct nlmsghdr *nlh, struct cf_mod *mod, if (mb.modtype & CGW_MOD_ID) mod->modfunc[modidx++] = mod_and_id; - if (mb.modtype & CGW_MOD_LEN) - mod->modfunc[modidx++] = mod_and_len; + if (mb.modtype & CGW_MOD_DLC) + mod->modfunc[modidx++] = mod_and_ccdlc; if (mb.modtype & CGW_MOD_DATA) mod->modfunc[modidx++] = mod_and_data; @@ -858,8 +920,8 @@ static int cgw_parse_attr(struct nlmsghdr *nlh, struct cf_mod *mod, if (mb.modtype & CGW_MOD_ID) mod->modfunc[modidx++] = mod_or_id; - if (mb.modtype & CGW_MOD_LEN) - mod->modfunc[modidx++] = mod_or_len; + if (mb.modtype & CGW_MOD_DLC) +
[net-next 15/25] can: flexcan: rename macro FLEXCAN_QUIRK_SETUP_STOP_MODE -> FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR
From: Joakim Zhang This patch intends to rename FLEXCAN_QUIRK_SETUP_STOP_MODE quirk to FLEXCAN_QUIRK_SETUP_STOP_MODE_GRP for non-scu SoCs, coming patch will add quirk for scu SoCs. For non-scu SoCs, setup stop mode with GPR register. For scu SoCs, setup stop mode with SCU firmware. Signed-off-by: Joakim Zhang Link: https://lore.kernel.org/r/20201106105627.31061-4-qiangqing.zh...@nxp.com Signed-off-by: Marc Kleine-Budde --- drivers/net/can/flexcan.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 6f3555381230..56a6bcc6d9d7 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -236,8 +236,8 @@ #define FLEXCAN_QUIRK_BROKEN_PERR_STATE BIT(6) /* default to BE register access */ #define FLEXCAN_QUIRK_DEFAULT_BIG_ENDIAN BIT(7) -/* Setup stop mode to support wakeup */ -#define FLEXCAN_QUIRK_SETUP_STOP_MODE BIT(8) +/* Setup stop mode with GPR to support wakeup */ +#define FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR BIT(8) /* Support CAN-FD mode */ #define FLEXCAN_QUIRK_SUPPORT_FD BIT(9) /* support memory detection and correction */ @@ -381,7 +381,7 @@ static const struct flexcan_devtype_data fsl_imx28_devtype_data = { static const struct flexcan_devtype_data fsl_imx6q_devtype_data = { .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_BROKEN_PERR_STATE | - FLEXCAN_QUIRK_SETUP_STOP_MODE, + FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR, }; static const struct flexcan_devtype_data fsl_imx8qm_devtype_data = { @@ -393,7 +393,7 @@ static const struct flexcan_devtype_data fsl_imx8qm_devtype_data = { static struct flexcan_devtype_data fsl_imx8mp_devtype_data = { .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | - FLEXCAN_QUIRK_BROKEN_PERR_STATE | FLEXCAN_QUIRK_SETUP_STOP_MODE | + FLEXCAN_QUIRK_BROKEN_PERR_STATE | FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR | FLEXCAN_QUIRK_SUPPORT_FD | FLEXCAN_QUIRK_SUPPORT_ECC, }; @@ -2047,7 +2047,7 @@ static int flexcan_probe(struct platform_device *pdev) of_can_transceiver(dev); devm_can_led_init(dev); - if (priv->devtype_data->quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE) { + if (priv->devtype_data->quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR) { err = flexcan_setup_stop_mode(pdev); if (err) dev_dbg(&pdev->dev, "failed to setup stop-mode\n"); -- 2.29.2
[net-next 12/25] dt-bindings: can: fsl,flexcan: add uint32 reference to clock-frequency property
This patch adds the missing reference to the clock-frequency property. The driver uses a of_property_read_u32() to read the property to mark it as uint32. Fixes: e5ab9aa7e49b ("dt-bindings: can: flexcan: convert fsl,*flexcan bindings to yaml") Link: https://lore.kernel.org/r/20201119073357.2858925-1-...@pengutronix.de Cc: Joakim Zhang Cc: Oleksij Rempel Signed-off-by: Marc Kleine-Budde --- Documentation/devicetree/bindings/net/can/fsl,flexcan.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/net/can/fsl,flexcan.yaml b/Documentation/devicetree/bindings/net/can/fsl,flexcan.yaml index 13875eab2ed6..0133d777e78e 100644 --- a/Documentation/devicetree/bindings/net/can/fsl,flexcan.yaml +++ b/Documentation/devicetree/bindings/net/can/fsl,flexcan.yaml @@ -57,6 +57,7 @@ properties: - const: per clock-frequency: +$ref: /schemas/types.yaml#/definitions/uint32 description: | The oscillator frequency driving the flexcan device, filled in by the boot loader. This property should only be used the used operating system -- 2.29.2
[net-next 21/25] can: kvaser_usb: Add USB_{LEAF,HYDRA}_PRODUCT_ID_END defines
From: Jimmy Assarsson Add USB_{LEAF,HYDRA}_PRODUCT_ID_END defines, representing the last USB PID entry in respectively family. This removes the need to update the kvaser_is_{leaf,hydra}() functions whenever new devices are added. Signed-off-by: Jimmy Assarsson Link: https://lore.kernel.org/r/20201115163027.16851-3-jimmyassars...@gmail.com Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c index d6e18bcb1a7f..1dffcd19c456 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c @@ -58,6 +58,8 @@ #define USB_LEAF_LIGHT_HS_V2_OEM_PRODUCT_ID290 #define USB_USBCAN_LIGHT_2HS_PRODUCT_ID291 #define USB_MINI_PCIE_2HS_PRODUCT_ID 292 +#define USB_LEAF_PRODUCT_ID_END \ + USB_MINI_PCIE_2HS_PRODUCT_ID /* Kvaser USBCan-II devices product ids */ #define USB_USBCAN_REVB_PRODUCT_ID 2 @@ -78,13 +80,15 @@ #define USB_ATI_USBCAN_PRO_2HS_V2_PRODUCT_ID 268 #define USB_ATI_MEMO_PRO_2HS_V2_PRODUCT_ID 269 #define USB_HYBRID_PRO_CANLIN_PRODUCT_ID 270 +#define USB_HYDRA_PRODUCT_ID_END \ + USB_HYBRID_PRO_CANLIN_PRODUCT_ID static inline bool kvaser_is_leaf(const struct usb_device_id *id) { return (id->idProduct >= USB_LEAF_DEVEL_PRODUCT_ID && id->idProduct <= USB_CAN_R_PRODUCT_ID) || (id->idProduct >= USB_LEAF_LITE_V2_PRODUCT_ID && -id->idProduct <= USB_MINI_PCIE_2HS_PRODUCT_ID); +id->idProduct <= USB_LEAF_PRODUCT_ID_END); } static inline bool kvaser_is_usbcan(const struct usb_device_id *id) @@ -96,7 +100,7 @@ static inline bool kvaser_is_usbcan(const struct usb_device_id *id) static inline bool kvaser_is_hydra(const struct usb_device_id *id) { return id->idProduct >= USB_BLACKBIRD_V2_PRODUCT_ID && - id->idProduct <= USB_HYBRID_PRO_CANLIN_PRODUCT_ID; + id->idProduct <= USB_HYDRA_PRODUCT_ID_END; } static const struct usb_device_id kvaser_usb_table[] = { -- 2.29.2
[net-next 22/25] can: kvaser_usb: Add new Kvaser Leaf v2 devices
From: Jimmy Assarsson Add new Kvaser Leaf v2 devices. Signed-off-by: Jimmy Assarsson Link: https://lore.kernel.org/r/20201115163027.16851-4-jimmyassars...@gmail.com Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/Kconfig | 2 ++ drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | 8 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/usb/Kconfig b/drivers/net/can/usb/Kconfig index bcb331b0c958..161f15e5218d 100644 --- a/drivers/net/can/usb/Kconfig +++ b/drivers/net/can/usb/Kconfig @@ -52,7 +52,9 @@ config CAN_KVASER_USB - Kvaser Leaf Light "China" - Kvaser BlackBird SemiPro - Kvaser USBcan R + - Kvaser USBcan R v2 - Kvaser Leaf Light v2 + - Kvaser Leaf Light R v2 - Kvaser Mini PCI Express HS - Kvaser Mini PCI Express 2xHS - Kvaser USBcan Light 2xHS diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c index 1dffcd19c456..ad66a3b1a29d 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c @@ -58,8 +58,11 @@ #define USB_LEAF_LIGHT_HS_V2_OEM_PRODUCT_ID290 #define USB_USBCAN_LIGHT_2HS_PRODUCT_ID291 #define USB_MINI_PCIE_2HS_PRODUCT_ID 292 +#define USB_USBCAN_R_V2_PRODUCT_ID 294 +#define USB_LEAF_LIGHT_R_V2_PRODUCT_ID 295 +#define USB_LEAF_LIGHT_HS_V2_OEM2_PRODUCT_ID 296 #define USB_LEAF_PRODUCT_ID_END \ - USB_MINI_PCIE_2HS_PRODUCT_ID + USB_LEAF_LIGHT_HS_V2_OEM2_PRODUCT_ID /* Kvaser USBCan-II devices product ids */ #define USB_USBCAN_REVB_PRODUCT_ID 2 @@ -157,6 +160,9 @@ static const struct usb_device_id kvaser_usb_table[] = { { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM_PRODUCT_ID) }, { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_2HS_PRODUCT_ID) }, { USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_2HS_PRODUCT_ID) }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_R_V2_PRODUCT_ID) }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_R_V2_PRODUCT_ID) }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM2_PRODUCT_ID) }, /* USBCANII USB product IDs */ { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN2_PRODUCT_ID), -- 2.29.2
[net-next 20/25] can: flexcan: flexcan_close(): change order if commands to properly shut down the controller
There haven been reports, that the flexcan_close() soradically hangs during simultanious ifdown, sending of CAN messages and probably open CAN bus: | (__schedule) from [<808bbd34>] (schedule+0x90/0xb8) | (schedule) from [<808bf274>] (schedule_timeout+0x1f8/0x24c) | (schedule_timeout) from [<8016be44>] (msleep+0x18/0x1c) | (msleep) from [<80746a64>] (napi_disable+0x60/0x70) | (napi_disable) from [<8052fdd0>] (flexcan_close+0x2c/0x140) | (flexcan_close) from [<80744930>] (__dev_close_many+0xb8/0xd8) | (__dev_close_many) from [<8074db9c>] (__dev_change_flags+0xd0/0x1a0) | (__dev_change_flags) from [<8074dc84>] (dev_change_flags+0x18/0x48) | (dev_change_flags) from [<80760c24>] (do_setlink+0x44c/0x7b4) | (do_setlink) from [<80761560>] (rtnl_newlink+0x374/0x68c) I was unable to reproduce the issue, but a cleanup of the flexcan close sequence has probably fixed the problem at the reporting user. This patch changes the sequence in flexcan_close() to: - stop the TX queue - disable the interrupts on the chip level and wait via free_irq() synchronously for the interrupt handler to finish - disable RX offload, which disables synchronously NAPI - disable the flexcan on the chip level - free RX offload - disable the transceiver - close the CAN device - disable the clocks Link: https://lore.kernel.org/r/20201119100917.3013281-6-...@pengutronix.de Signed-off-by: Marc Kleine-Budde --- drivers/net/can/flexcan.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index e98368be1669..e85f20d18d67 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -1754,15 +1754,15 @@ static int flexcan_close(struct net_device *dev) struct flexcan_priv *priv = netdev_priv(dev); netif_stop_queue(dev); + flexcan_chip_interrupts_disable(dev); + free_irq(dev->irq, dev); can_rx_offload_disable(&priv->offload); flexcan_chip_stop_disable_on_error(dev); - flexcan_chip_interrupts_disable(dev); can_rx_offload_del(&priv->offload); - free_irq(dev->irq, dev); flexcan_transceiver_disable(priv); - close_candev(dev); + pm_runtime_put(priv->dev); can_led_event(dev, CAN_LED_EVENT_STOP); -- 2.29.2
[net-next 17/25] can: flexcan: move enabling/disabling of interrupts from flexcan_chip_{start,stop}() to callers
The function flexcan_chip_start() first configures the CAN controller and then enables the interrupt, flexcan_chip_stop() does the opposite. In an upcoming patch the order of operations in flexcan_open() and flexcan_close() are changed. This requires flexcan_chip_start()/flexcan_chip_stop_disable_on_error() and flexcan_chip_interrupts_{enable,disable}() to be independent of each other. This patch moves the enabling of the interrupts from flexcan_chip_start() to its callers flexcan_open() and flexcan_resume(). Likewise the disabling of the interrupts is moved from __flexcan_chip_stop() to its indirect callers flexcan_close() and flexcan_suspend(). Link: https://lore.kernel.org/r/20201119100917.3013281-3-...@pengutronix.de Signed-off-by: Marc Kleine-Budde --- drivers/net/can/flexcan.c | 13 + 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 681a4d82681c..64c174aa868b 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -1598,8 +1598,6 @@ static int flexcan_chip_start(struct net_device *dev) priv->can.state = CAN_STATE_ERROR_ACTIVE; - flexcan_chip_interrupts_enable(dev); - /* print chip status */ netdev_dbg(dev, "%s: reading mcr=0x%08x ctrl=0x%08x\n", __func__, priv->read(®s->mcr), priv->read(®s->ctrl)); @@ -1628,8 +1626,6 @@ static int __flexcan_chip_stop(struct net_device *dev, bool disable_on_error) if (err && !disable_on_error) goto out_chip_unfreeze; - flexcan_chip_interrupts_disable(dev); - priv->can.state = CAN_STATE_STOPPED; return 0; @@ -1719,6 +1715,8 @@ static int flexcan_open(struct net_device *dev) if (err) goto out_offload_del; + flexcan_chip_interrupts_enable(dev); + can_led_event(dev, CAN_LED_EVENT_OPEN); can_rx_offload_enable(&priv->offload); @@ -1747,6 +1745,7 @@ static int flexcan_close(struct net_device *dev) netif_stop_queue(dev); can_rx_offload_disable(&priv->offload); flexcan_chip_stop_disable_on_error(dev); + flexcan_chip_interrupts_disable(dev); can_rx_offload_del(&priv->offload); free_irq(dev->irq, dev); @@ -1770,6 +1769,8 @@ static int flexcan_set_mode(struct net_device *dev, enum can_mode mode) if (err) return err; + flexcan_chip_interrupts_enable(dev); + netif_wake_queue(dev); break; @@ -2108,6 +2109,8 @@ static int __maybe_unused flexcan_suspend(struct device *device) if (err) return err; + flexcan_chip_interrupts_disable(dev); + err = pinctrl_pm_select_sleep_state(device); if (err) return err; @@ -2143,6 +2146,8 @@ static int __maybe_unused flexcan_resume(struct device *device) err = flexcan_chip_start(dev); if (err) return err; + + flexcan_chip_interrupts_enable(dev); } } -- 2.29.2
[net-next 09/25] can: drivers: add len8_dlc support for various CAN adapters
From: Oliver Hartkopp Support the Classical CAN raw DLC functionality to send and receive DLC values from 9 .. 15 on various Classical CAN capable CAN network drivers: - sja1000 - gs_usb - pcan_usb - pcan_usb_fd - usb_8dev Signed-off-by: Oliver Hartkopp Tested-by: Oliver Hartkopp Link: https://lore.kernel.org/r/2020095923.2535-1-socket...@hartkopp.net [mkl: usb_8dev: changed indention] Signed-off-by: Marc Kleine-Budde --- drivers/net/can/sja1000/sja1000.c | 10 - drivers/net/can/usb/gs_usb.c | 7 +++--- drivers/net/can/usb/peak_usb/pcan_usb.c| 8 --- drivers/net/can/usb/peak_usb/pcan_usb_fd.c | 25 ++ drivers/net/can/usb/usb_8dev.c | 7 +++--- 5 files changed, 34 insertions(+), 23 deletions(-) diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c index d55394aa0b95..e60329972d70 100644 --- a/drivers/net/can/sja1000/sja1000.c +++ b/drivers/net/can/sja1000/sja1000.c @@ -284,7 +284,6 @@ static netdev_tx_t sja1000_start_xmit(struct sk_buff *skb, struct sja1000_priv *priv = netdev_priv(dev); struct can_frame *cf = (struct can_frame *)skb->data; uint8_t fi; - uint8_t dlc; canid_t id; uint8_t dreg; u8 cmd_reg_val = 0x00; @@ -295,7 +294,7 @@ static netdev_tx_t sja1000_start_xmit(struct sk_buff *skb, netif_stop_queue(dev); - fi = dlc = cf->len; + fi = can_get_cc_dlc(cf, priv->can.ctrlmode); id = cf->can_id; if (id & CAN_RTR_FLAG) @@ -316,7 +315,7 @@ static netdev_tx_t sja1000_start_xmit(struct sk_buff *skb, priv->write_reg(priv, SJA1000_ID2, (id & 0x0007) << 5); } - for (i = 0; i < dlc; i++) + for (i = 0; i < cf->len; i++) priv->write_reg(priv, dreg++, cf->data[i]); can_put_echo_skb(skb, dev, 0); @@ -367,7 +366,7 @@ static void sja1000_rx(struct net_device *dev) | (priv->read_reg(priv, SJA1000_ID2) >> 5); } - cf->len = can_cc_dlc2len(fi & 0x0F); + can_frame_set_cc_len(cf, fi & 0x0F, priv->can.ctrlmode); if (fi & SJA1000_FI_RTR) { id |= CAN_RTR_FLAG; } else { @@ -638,7 +637,8 @@ struct net_device *alloc_sja1000dev(int sizeof_priv) CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_ONE_SHOT | CAN_CTRLMODE_BERR_REPORTING | - CAN_CTRLMODE_PRESUME_ACK; + CAN_CTRLMODE_PRESUME_ACK | + CAN_CTRLMODE_CC_LEN8_DLC; spin_lock_init(&priv->cmdreg_lock); diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index d6a68b7046eb..b3431c3feba1 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c @@ -331,7 +331,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) cf->can_id = hf->can_id; - cf->len = can_cc_dlc2len(hf->can_dlc); + can_frame_set_cc_len(cf, hf->can_dlc, dev->can.ctrlmode); memcpy(cf->data, hf->data, 8); /* ERROR frames tell us information about the controller */ @@ -504,7 +504,8 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb, cf = (struct can_frame *)skb->data; hf->can_id = cf->can_id; - hf->can_dlc = cf->len; + hf->can_dlc = can_get_cc_dlc(cf, dev->can.ctrlmode); + memcpy(hf->data, cf->data, cf->len); usb_fill_bulk_urb(urb, dev->udev, @@ -858,7 +859,7 @@ static struct gs_can *gs_make_candev(unsigned int channel, dev->can.bittiming_const = &dev->bt_const; dev->can.do_set_bittiming = gs_usb_set_bittiming; - dev->can.ctrlmode_supported = 0; + dev->can.ctrlmode_supported = CAN_CTRLMODE_CC_LEN8_DLC; if (bt_const->feature & GS_CAN_FEATURE_LISTEN_ONLY) dev->can.ctrlmode_supported |= CAN_CTRLMODE_LISTENONLY; diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c index ec34f87cc02c..e6c1e5d33924 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb.c @@ -734,7 +734,7 @@ static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len) cf->can_id = le16_to_cpu(tmp16) >> 5; } - cf->len = can_cc_dlc2len(rec_len); + can_frame_set_cc_len(cf, rec_len, mc->pdev->dev.can.ctrlmode); /* Only first packet timestamp is a word */ if (pcan_usb_decode_ts(mc, !mc->rec_ts_idx)) @@ -838,7 +838,8 @@ static int pcan_usb_encode_msg(struct peak_usb_device *dev, struct sk_buff *skb, pc = obuf + PCAN_USB_MSG_HEADER_LEN; /* status/len byte */ - *pc = cf->len; + *pc = can_get_cc_dlc(cf, dev->can.ctrlmode); + if (cf->can_id & CAN_RTR_FLAG)
[net-next 10/25] can: drivers: add len8_dlc support for esd_usb2 CAN adapter
From: Stefan Mätje Support the Classical CAN raw DLC functionality to send and receive DLC values from 9 .. 15 for the Classical CAN capable CAN network driver esd_usb that supports the esd CAN-USB/2 and CAN-USB/Micro devices: - esd_usb2 Signed-off-by: Stefan Mätje Tested-by: Stefan Mätje Link: https://lore.kernel.org/r/20201116184430.25462-2-stefan.mae...@esd.eu [mkl: rewrapped some long lines] Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/esd_usb2.c | 14 -- 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb2.c index 3643a8ee03cf..9eed75a4b678 100644 --- a/drivers/net/can/usb/esd_usb2.c +++ b/drivers/net/can/usb/esd_usb2.c @@ -183,7 +183,7 @@ struct esd_usb2_net_priv; struct esd_tx_urb_context { struct esd_usb2_net_priv *priv; u32 echo_index; - int dlc; + int len;/* CAN payload length */ }; struct esd_usb2 { @@ -321,7 +321,8 @@ static void esd_usb2_rx_can_msg(struct esd_usb2_net_priv *priv, } cf->can_id = id & ESD_IDMASK; - cf->len = can_cc_dlc2len(msg->msg.rx.dlc & ~ESD_RTR); + can_frame_set_cc_len(cf, msg->msg.rx.dlc & ~ESD_RTR, +priv->can.ctrlmode); if (id & ESD_EXTID) cf->can_id |= CAN_EFF_FLAG; @@ -355,7 +356,7 @@ static void esd_usb2_tx_done_msg(struct esd_usb2_net_priv *priv, if (!msg->msg.txdone.status) { stats->tx_packets++; - stats->tx_bytes += context->dlc; + stats->tx_bytes += context->len; can_get_echo_skb(netdev, context->echo_index); } else { stats->tx_errors++; @@ -737,7 +738,7 @@ static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb, msg->msg.hdr.len = 3; /* minimal length */ msg->msg.hdr.cmd = CMD_CAN_TX; msg->msg.tx.net = priv->index; - msg->msg.tx.dlc = cf->len; + msg->msg.tx.dlc = can_get_cc_dlc(cf, priv->can.ctrlmode); msg->msg.tx.id = cpu_to_le32(cf->can_id & CAN_ERR_MASK); if (cf->can_id & CAN_RTR_FLAG) @@ -769,7 +770,7 @@ static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb, context->priv = priv; context->echo_index = i; - context->dlc = cf->len; + context->len = cf->len; /* hnd must not be 0 - MSB is stripped in txdone handling */ msg->msg.tx.hnd = 0x8000 | i; /* returned in TX done message */ @@ -988,7 +989,8 @@ static int esd_usb2_probe_one_net(struct usb_interface *intf, int index) priv->index = index; priv->can.state = CAN_STATE_STOPPED; - priv->can.ctrlmode_supported = CAN_CTRLMODE_LISTENONLY; + priv->can.ctrlmode_supported = CAN_CTRLMODE_LISTENONLY | + CAN_CTRLMODE_CC_LEN8_DLC; if (le16_to_cpu(dev->udev->descriptor.idProduct) == USB_CANUSBM_PRODUCT_ID) -- 2.29.2
[net-next 06/25] can: rename CAN FD related can_len2dlc and can_dlc2len helpers
From: Oliver Hartkopp The helper functions can_len2dlc and can_dlc2len are only relevant for CAN FD data length code (DLC) conversion. To fit the introduced can_cc_dlc2len for Classical CAN we rename: can_dlc2len -> can_fd_dlc2len to get the payload length from the DLC can_len2dlc -> can_fd_len2dlc to get the DLC from the payload length Suggested-by: Vincent Mailhol Signed-off-by: Oliver Hartkopp Link: https://lore.kernel.org/r/20201110101852.1973-6-socket...@hartkopp.net Signed-off-by: Marc Kleine-Budde --- Documentation/networking/can.rst | 2 +- drivers/net/can/dev.c | 8 drivers/net/can/flexcan.c | 4 ++-- drivers/net/can/ifi_canfd/ifi_canfd.c | 4 ++-- drivers/net/can/kvaser_pciefd.c | 6 +++--- drivers/net/can/m_can/m_can.c | 6 +++--- drivers/net/can/peak_canfd/peak_canfd.c | 4 ++-- drivers/net/can/rcar/rcar_canfd.c | 4 ++-- drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c| 8 drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 6 +++--- drivers/net/can/usb/peak_usb/pcan_usb_fd.c| 4 ++-- drivers/net/can/xilinx_can.c | 4 ++-- include/linux/can/dev.h | 4 ++-- 13 files changed, 32 insertions(+), 32 deletions(-) diff --git a/Documentation/networking/can.rst b/Documentation/networking/can.rst index ff05cbd05e0d..4895b0dd2714 100644 --- a/Documentation/networking/can.rst +++ b/Documentation/networking/can.rst @@ -1332,7 +1332,7 @@ layer is a plain value from 0 .. 64 instead of the CAN 'data length code'. The data length code was a 1:1 mapping to the payload length in the legacy CAN frames anyway. The payload length to the bus-relevant DLC mapping is only performed inside the CAN drivers, preferably with the helper -functions can_dlc2len() and can_len2dlc(). +functions can_fd_dlc2len() and can_fd_len2dlc(). The CAN netdevice driver capabilities can be distinguished by the network devices maximum transfer unit (MTU):: diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 806e8b646b12..3486704c8a95 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -31,11 +31,11 @@ static const u8 dlc2len[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64}; /* get data length from raw data length code (DLC) */ -u8 can_dlc2len(u8 dlc) +u8 can_fd_dlc2len(u8 dlc) { return dlc2len[dlc & 0x0F]; } -EXPORT_SYMBOL_GPL(can_dlc2len); +EXPORT_SYMBOL_GPL(can_fd_dlc2len); static const u8 len2dlc[] = {0, 1, 2, 3, 4, 5, 6, 7, 8,/* 0 - 8 */ 9, 9, 9, 9,/* 9 - 12 */ @@ -49,14 +49,14 @@ static const u8 len2dlc[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, /* 0 - 8 */ 15, 15, 15, 15, 15, 15, 15, 15}; /* 57 - 64 */ /* map the sanitized data length to an appropriate data length code */ -u8 can_len2dlc(u8 len) +u8 can_fd_len2dlc(u8 len) { if (unlikely(len > 64)) return 0xF; return len2dlc[len]; } -EXPORT_SYMBOL_GPL(can_len2dlc); +EXPORT_SYMBOL_GPL(can_fd_len2dlc); #ifdef CONFIG_CAN_CALC_BITTIMING #define CAN_CALC_MAX_ERROR 50 /* in one-tenth of a percent */ diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 985569f946e5..6f3555381230 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -746,7 +746,7 @@ static netdev_tx_t flexcan_start_xmit(struct sk_buff *skb, struct net_device *de struct canfd_frame *cfd = (struct canfd_frame *)skb->data; u32 can_id; u32 data; - u32 ctrl = FLEXCAN_MB_CODE_TX_DATA | ((can_len2dlc(cfd->len)) << 16); + u32 ctrl = FLEXCAN_MB_CODE_TX_DATA | ((can_fd_len2dlc(cfd->len)) << 16); int i; if (can_dropped_invalid_skb(dev, skb)) @@ -1000,7 +1000,7 @@ static struct sk_buff *flexcan_mailbox_read(struct can_rx_offload *offload, cfd->can_id = (reg_id >> 18) & CAN_SFF_MASK; if (reg_ctrl & FLEXCAN_MB_CNT_EDL) { - cfd->len = can_dlc2len((reg_ctrl >> 16) & 0xf); + cfd->len = can_fd_dlc2len((reg_ctrl >> 16) & 0xf); if (reg_ctrl & FLEXCAN_MB_CNT_BRS) cfd->flags |= CANFD_BRS; diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c index 3df55b0e4ef3..86b0e1406a21 100644 --- a/drivers/net/can/ifi_canfd/ifi_canfd.c +++ b/drivers/net/can/ifi_canfd/ifi_canfd.c @@ -271,7 +271,7 @@ static void ifi_canfd_read_fifo(struct net_device *ndev) dlc = (rxdlc >> IFI_CANFD_RXFIFO_DLC_DLC_OFFSET) & IFI_CANFD_RXFIFO_DLC_DLC_MASK; if (rxdlc & IFI_CANFD_RXFIFO_DLC_EDL) - cf->len = can_dlc2len(dlc); + cf->len = can_fd_dlc2len(dlc); else cf->len = can_cc_dlc2len(dlc); @@ -900,7 +900,7 @@ stati
[net-next 05/25] can: replace can_dlc as variable/element for payload length
From: Oliver Hartkopp The naming of can_dlc as element of struct can_frame and also as variable name is misleading as it claims to be a 'data length CODE' but in reality it always was a plain data length. With the indroduction of a new 'len' element in struct can_frame we can now remove can_dlc as name and make clear which of the former uses was a plain length (-> 'len') or a data length code (-> 'dlc') value. Signed-off-by: Oliver Hartkopp Link: https://lore.kernel.org/r/20201120100444.3199-1-socket...@hartkopp.net [mkl: gs_usb: keep struct gs_host_frame::can_dlc as is] Signed-off-by: Marc Kleine-Budde --- drivers/net/can/at91_can.c| 14 drivers/net/can/c_can/c_can.c | 20 ++-- drivers/net/can/cc770/cc770.c | 14 drivers/net/can/dev.c | 10 +++--- drivers/net/can/grcan.c | 10 +++--- drivers/net/can/ifi_canfd/ifi_canfd.c | 4 +-- drivers/net/can/janz-ican3.c | 20 ++-- drivers/net/can/kvaser_pciefd.c | 4 +-- drivers/net/can/m_can/m_can.c | 4 +-- drivers/net/can/mscan/mscan.c | 20 ++-- drivers/net/can/pch_can.c | 12 +++ drivers/net/can/peak_canfd/peak_canfd.c | 12 +++ drivers/net/can/rcar/rcar_can.c | 14 drivers/net/can/rcar/rcar_canfd.c | 4 +-- drivers/net/can/rx-offload.c | 2 +- drivers/net/can/sja1000/sja1000.c | 10 +++--- drivers/net/can/slcan.c | 32 +-- drivers/net/can/softing/softing_fw.c | 2 +- drivers/net/can/softing/softing_main.c| 14 drivers/net/can/spi/hi311x.c | 20 ++-- drivers/net/can/spi/mcp251x.c | 18 +-- drivers/net/can/sun4i_can.c | 10 +++--- drivers/net/can/ti_hecc.c | 8 ++--- drivers/net/can/usb/ems_usb.c | 16 +- drivers/net/can/usb/esd_usb2.c| 16 +- drivers/net/can/usb/gs_usb.c | 8 ++--- .../net/can/usb/kvaser_usb/kvaser_usb_core.c | 2 +- .../net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 16 +- .../net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 22 ++--- drivers/net/can/usb/mcba_usb.c| 10 +++--- drivers/net/can/usb/peak_usb/pcan_usb.c | 14 drivers/net/can/usb/peak_usb/pcan_usb_fd.c| 10 +++--- drivers/net/can/usb/peak_usb/pcan_usb_pro.c | 14 drivers/net/can/usb/ucan.c| 14 drivers/net/can/usb/usb_8dev.c| 14 drivers/net/can/xilinx_can.c | 10 +++--- include/linux/can/dev.h | 4 +-- net/can/af_can.c | 2 +- net/can/gw.c | 2 +- net/can/j1939/main.c | 4 +-- 40 files changed, 228 insertions(+), 228 deletions(-) diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index db06254f8eb7..5284f0ab3b06 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -468,7 +468,7 @@ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev) } reg_mid = at91_can_id_to_reg_mid(cf->can_id); reg_mcr = ((cf->can_id & CAN_RTR_FLAG) ? AT91_MCR_MRTR : 0) | - (cf->can_dlc << 16) | AT91_MCR_MTCR; + (cf->len << 16) | AT91_MCR_MTCR; /* disable MB while writing ID (see datasheet) */ set_mb_mode(priv, mb, AT91_MB_MODE_DISABLED); @@ -481,7 +481,7 @@ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev) /* This triggers transmission */ at91_write(priv, AT91_MCR(mb), reg_mcr); - stats->tx_bytes += cf->can_dlc; + stats->tx_bytes += cf->len; /* _NOTE_: subtract AT91_MB_TX_FIRST offset from mb! */ can_put_echo_skb(skb, dev, mb - get_mb_tx_first(priv)); @@ -554,7 +554,7 @@ static void at91_rx_overflow_err(struct net_device *dev) cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; stats->rx_packets++; - stats->rx_bytes += cf->can_dlc; + stats->rx_bytes += cf->len; netif_receive_skb(skb); } @@ -580,7 +580,7 @@ static void at91_read_mb(struct net_device *dev, unsigned int mb, cf->can_id = (reg_mid >> 18) & CAN_SFF_MASK; reg_msr = at91_read(priv, AT91_MSR(mb)); - cf->can_dlc = can_cc_dlc2len((reg_msr >> 16) & 0xf); + cf->len = can_cc_dlc2len((reg_msr >> 16) & 0xf); if (reg_msr & AT91_MSR_MRTR) cf->can_id |= CAN_RTR_FLAG; @@ -619,7 +619,7 @@ static void at91_read_msg(struct net_device *dev, unsigned int mb) at91_read_mb(dev, mb, cf); stats->rx_packets++; - stats->rx_bytes += cf->can_dlc; + stats->rx_bytes += cf->len;
[net-next 03/25] can: rename get_can_dlc() macro with can_cc_dlc2len()
From: Oliver Hartkopp The get_can_dlc() macro is used to ensure the payload length information of the Classical CAN frame to be max 8 bytes (the CAN_MAX_DLEN). Rename the macro and use the correct constant in preparation of the len/dlc cleanup for Classical CAN frames. Signed-off-by: Oliver Hartkopp Link: https://lore.kernel.org/r/20201110101852.1973-3-socket...@hartkopp.net Signed-off-by: Marc Kleine-Budde --- drivers/net/can/at91_can.c| 2 +- drivers/net/can/c_can/c_can.c | 2 +- drivers/net/can/cc770/cc770.c | 2 +- drivers/net/can/flexcan.c | 2 +- drivers/net/can/grcan.c | 2 +- drivers/net/can/ifi_canfd/ifi_canfd.c | 2 +- drivers/net/can/janz-ican3.c | 4 ++-- drivers/net/can/m_can/m_can.c | 2 +- drivers/net/can/mscan/mscan.c | 2 +- drivers/net/can/pch_can.c | 4 ++-- drivers/net/can/peak_canfd/peak_canfd.c | 2 +- drivers/net/can/rcar/rcar_can.c | 2 +- drivers/net/can/rcar/rcar_canfd.c | 4 ++-- drivers/net/can/sja1000/sja1000.c | 2 +- drivers/net/can/softing/softing_main.c| 2 +- drivers/net/can/spi/hi311x.c | 2 +- drivers/net/can/spi/mcp251x.c | 4 ++-- drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c| 2 +- drivers/net/can/sun4i_can.c | 2 +- drivers/net/can/ti_hecc.c | 2 +- drivers/net/can/usb/ems_usb.c | 2 +- drivers/net/can/usb/esd_usb2.c| 2 +- drivers/net/can/usb/gs_usb.c | 2 +- drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 4 ++-- drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 4 ++-- drivers/net/can/usb/mcba_usb.c| 2 +- drivers/net/can/usb/peak_usb/pcan_usb.c | 2 +- drivers/net/can/usb/peak_usb/pcan_usb_fd.c| 2 +- drivers/net/can/usb/ucan.c| 8 drivers/net/can/usb/usb_8dev.c| 2 +- drivers/net/can/xilinx_can.c | 4 ++-- include/linux/can/dev.h | 8 32 files changed, 45 insertions(+), 45 deletions(-) diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index c14de95d2ca7..db06254f8eb7 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -580,7 +580,7 @@ static void at91_read_mb(struct net_device *dev, unsigned int mb, cf->can_id = (reg_mid >> 18) & CAN_SFF_MASK; reg_msr = at91_read(priv, AT91_MSR(mb)); - cf->can_dlc = get_can_dlc((reg_msr >> 16) & 0xf); + cf->can_dlc = can_cc_dlc2len((reg_msr >> 16) & 0xf); if (reg_msr & AT91_MSR_MRTR) cf->can_id |= CAN_RTR_FLAG; diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index 1ccdbe89585b..56cc705959ea 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c @@ -397,7 +397,7 @@ static int c_can_read_msg_object(struct net_device *dev, int iface, u32 ctrl) return -ENOMEM; } - frame->can_dlc = get_can_dlc(ctrl & 0x0F); + frame->can_dlc = can_cc_dlc2len(ctrl & 0x0F); arb = priv->read_reg32(priv, C_CAN_IFACE(ARB1_REG, iface)); diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c index 07e2b8df5153..3fd2a276dd93 100644 --- a/drivers/net/can/cc770/cc770.c +++ b/drivers/net/can/cc770/cc770.c @@ -486,7 +486,7 @@ static void cc770_rx(struct net_device *dev, unsigned int mo, u8 ctrl1) } cf->can_id = id; - cf->can_dlc = get_can_dlc((config & 0xf0) >> 4); + cf->can_dlc = can_cc_dlc2len((config & 0xf0) >> 4); for (i = 0; i < cf->can_dlc; i++) cf->data[i] = cc770_read_reg(priv, msgobj[mo].data[i]); } diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 99e5f272205d..50ccd18170c8 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -1005,7 +1005,7 @@ static struct sk_buff *flexcan_mailbox_read(struct can_rx_offload *offload, if (reg_ctrl & FLEXCAN_MB_CNT_BRS) cfd->flags |= CANFD_BRS; } else { - cfd->len = get_can_dlc((reg_ctrl >> 16) & 0xf); + cfd->len = can_cc_dlc2len((reg_ctrl >> 16) & 0xf); if (reg_ctrl & FLEXCAN_MB_CNT_RTR) cfd->can_id |= CAN_RTR_FLAG; diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c index 39802f107eb1..c71c9b8683d5 100644 --- a/drivers/net/can/grcan.c +++ b/drivers/net/can/grcan.c @@ -1201,7 +1201,7 @@ static int grcan_receive(struct net_device *dev, int budget) cf->can_id = ((slot[0] & GRCAN_MSG_BID)
[net-next 08/25] can: drivers: introduce helpers to access Classical CAN DLC values
From: Oliver Hartkopp This patch adds the following helper to functions to access Classical CAN DLC values. can_get_cc_dlc(): get the data length code for Classical CAN raw DLC access can_frame_set_cc_len(): set len and len8_dlc value for Classical CAN raw DLC access Signed-off-by: Oliver Hartkopp Link: https://lore.kernel.org/r/20201110154913.1404582-2-...@pengutronix.de Signed-off-by: Marc Kleine-Budde --- include/linux/can/dev.h | 25 + 1 file changed, 25 insertions(+) diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h index e767a96ae075..197a79535cc2 100644 --- a/include/linux/can/dev.h +++ b/include/linux/can/dev.h @@ -170,6 +170,31 @@ static inline bool can_is_canfd_skb(const struct sk_buff *skb) return skb->len == CANFD_MTU; } +/* helper to get the data length code (DLC) for Classical CAN raw DLC access */ +static inline u8 can_get_cc_dlc(const struct can_frame *cf, const u32 ctrlmode) +{ + /* return len8_dlc as dlc value only if all conditions apply */ + if ((ctrlmode & CAN_CTRLMODE_CC_LEN8_DLC) && + (cf->len == CAN_MAX_DLEN) && + (cf->len8_dlc > CAN_MAX_DLEN && cf->len8_dlc <= CAN_MAX_RAW_DLC)) + return cf->len8_dlc; + + /* return the payload length as dlc value */ + return cf->len; +} + +/* helper to set len and len8_dlc value for Classical CAN raw DLC access */ +static inline void can_frame_set_cc_len(struct can_frame *cf, const u8 dlc, + const u32 ctrlmode) +{ + /* the caller already ensured that dlc is a value from 0 .. 15 */ + if (ctrlmode & CAN_CTRLMODE_CC_LEN8_DLC && dlc > CAN_MAX_DLEN) + cf->len8_dlc = dlc; + + /* limit the payload length 'len' to CAN_MAX_DLEN */ + cf->len = can_cc_dlc2len(dlc); +} + /* helper to define static CAN controller features at device creation time */ static inline void can_set_static_ctrlmode(struct net_device *dev, u32 static_mode) -- 2.29.2
[net-next 04/25] can: remove obsolete get_canfd_dlc() macro
From: Oliver Hartkopp The macro was always used together with can_dlc2len() which sanitizes the given dlc value on its own. Signed-off-by: Oliver Hartkopp Link: https://lore.kernel.org/r/20201110101852.1973-4-socket...@hartkopp.net Signed-off-by: Marc Kleine-Budde --- drivers/net/can/flexcan.c | 2 +- drivers/net/can/peak_canfd/peak_canfd.c | 2 +- drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c| 2 +- drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 2 +- drivers/net/can/usb/peak_usb/pcan_usb_fd.c| 2 +- include/linux/can/dev.h | 1 - include/linux/can/dev/peak_canfd.h| 2 +- 7 files changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 50ccd18170c8..985569f946e5 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -1000,7 +1000,7 @@ static struct sk_buff *flexcan_mailbox_read(struct can_rx_offload *offload, cfd->can_id = (reg_id >> 18) & CAN_SFF_MASK; if (reg_ctrl & FLEXCAN_MB_CNT_EDL) { - cfd->len = can_dlc2len(get_canfd_dlc((reg_ctrl >> 16) & 0xf)); + cfd->len = can_dlc2len((reg_ctrl >> 16) & 0xf); if (reg_ctrl & FLEXCAN_MB_CNT_BRS) cfd->flags |= CANFD_BRS; diff --git a/drivers/net/can/peak_canfd/peak_canfd.c b/drivers/net/can/peak_canfd/peak_canfd.c index 9ea2adea3f0f..c6077e07214e 100644 --- a/drivers/net/can/peak_canfd/peak_canfd.c +++ b/drivers/net/can/peak_canfd/peak_canfd.c @@ -257,7 +257,7 @@ static int pucan_handle_can_rx(struct peak_canfd_priv *priv, u8 cf_len; if (rx_msg_flags & PUCAN_MSG_EXT_DATA_LEN) - cf_len = can_dlc2len(get_canfd_dlc(pucan_msg_get_dlc(msg))); + cf_len = can_dlc2len(pucan_msg_get_dlc(msg)); else cf_len = can_cc_dlc2len(pucan_msg_get_dlc(msg)); diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c index c0a08400f444..3bac7274ee5b 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c @@ -1405,7 +1405,7 @@ mcp251xfd_hw_rx_obj_to_skb(const struct mcp251xfd_priv *priv, cfd->flags |= CANFD_BRS; dlc = FIELD_GET(MCP251XFD_OBJ_FLAGS_DLC, hw_rx_obj->flags); - cfd->len = can_dlc2len(get_canfd_dlc(dlc)); + cfd->len = can_dlc2len(dlc); } else { if (hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_RTR) cfd->can_id |= CAN_RTR_FLAG; diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c index 493a614bf333..843e2e1392e8 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c @@ -1251,7 +1251,7 @@ static void kvaser_usb_hydra_rx_msg_ext(const struct kvaser_usb *dev, kvaser_usb_can_rx_over_error(priv->netdev); if (flags & KVASER_USB_HYDRA_CF_FLAG_FDF) { - cf->len = can_dlc2len(get_canfd_dlc(dlc)); + cf->len = can_dlc2len(dlc); if (flags & KVASER_USB_HYDRA_CF_FLAG_BRS) cf->flags |= CANFD_BRS; if (flags & KVASER_USB_HYDRA_CF_FLAG_ESI) diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c index 1f08dd22b3d5..1233ef20646a 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c @@ -492,7 +492,7 @@ static int pcan_usb_fd_decode_canmsg(struct pcan_usb_fd_if *usb_if, if (rx_msg_flags & PUCAN_MSG_ERROR_STATE_IND) cfd->flags |= CANFD_ESI; - cfd->len = can_dlc2len(get_canfd_dlc(pucan_msg_get_dlc(rm))); + cfd->len = can_dlc2len(pucan_msg_get_dlc(rm)); } else { /* CAN 2.0 frame case */ skb = alloc_can_skb(netdev, (struct can_frame **)&cfd); diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h index 9bc84c6978ec..802606e36b58 100644 --- a/include/linux/can/dev.h +++ b/include/linux/can/dev.h @@ -105,7 +105,6 @@ static inline unsigned int can_bit_time(const struct can_bittiming *bt) * ISO 11898-1 Chapter 8.4.2.3 (DLC field) */ #define can_cc_dlc2len(dlc)(min_t(u8, (dlc), CAN_MAX_DLEN)) -#define get_canfd_dlc(dlc) (min_t(u8, (dlc), CANFD_MAX_DLC)) /* Check for outgoing skbs that have not been created by the CAN subsystem */ static inline bool can_skb_headroom_valid(struct net_device *dev, diff --git a/include/linux/can/dev/peak_canfd.h b/include/linux/can/dev/peak_canfd.h index 5fd627e9da19..f38772fd0c07 100644 --- a/include/linux/can/dev/peak_canfd.h +++ b/include/linux/can/dev/peak_canfd.h @@ -282,7 +282,7 @@ static inline int pucan_msg_get_channel(const struct pucan_rx_msg *msg)
Re: [PATCH net-next v3 0/3] net: ptp: introduce common defines for PTP message types
On Fri, Nov 20, 2020 at 09:41:03AM +0100, Christian Eggers wrote: > This series introduces commen defines for PTP event messages. Driver > internal defines are removed and some uses of magic numbers are replaced > by the new defines. Nice cleanup! Reviewed-by: Richard Cochran Thanks, Richard
Re: [RFC net-next 1/2] ethtool: add support for controling the type of adaptive coalescing
On Fri, Nov 20, 2020 at 08:23:22AM +0100, Michal Kubecek wrote: > On Fri, Nov 20, 2020 at 10:59:59AM +0800, tanhuazhong wrote: > > On 2020/11/20 6:02, Michal Kubecek wrote: > > > > > > We could use a similar approach as struct ethtool_link_ksettings, e.g. > > > > > > struct kernel_ethtool_coalesce { > > > struct ethtool_coalesce base; > > > /* new members which are not part of UAPI */ > > > } > > > > > > get_coalesce() and set_coalesce() would get pointer to struct > > > kernel_ethtool_coalesce and ioctl code would be modified to only touch > > > the base (legacy?) part. > > > > While already changing the ops arguments, we could also add extack > > > pointer, either as a separate argument or as struct member (I slightly > > > prefer the former). > > > > If changing the ops arguments, each driver who implement > > set_coalesce/get_coalesce of ethtool_ops need to be updated. Is it > > acceptable adding two new ops to get/set ext_coalesce info (like > > ecc31c60240b ("ethtool: Add link extended state") does)? Maybe i can send V2 > > in this way, and then could you help to see which one is more suitable? > > If it were just this one case, adding an extra op would be perfectly > fine. But from long term point of view, we should expect extending also > other existing ethtool requests and going this way for all of them would > essentially double the number of callbacks in struct ethtool_ops. coccinella might be useful here. Andrew
[PATCH net] devlink: Fix reload stats structure
Fix reload stats structure exposed to the user. Change stats structure hierarchy to have the reload action as a parent of the stat entry and then stat entry includes value per limit. This will also help to avoid string concatenation on iproute2 output. Reload stats structure before this fix: "stats": { "reload": { "driver_reinit": 2, "fw_activate": 1, "fw_activate_no_reset": 0 } } After this fix: "stats": { "reload": { "driver_reinit": { "unspecified": 2 }, "fw_activate": { "unspecified": 1, "no_reset": 0 } } Fixes: a254c264267e ("devlink: Add reload stats") Signed-off-by: Moshe Shemesh Reviewed-by: Jiri Pirko --- include/uapi/linux/devlink.h | 2 ++ net/core/devlink.c | 48 +++- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h index 0113bc4db9f5..5203f54a2be1 100644 --- a/include/uapi/linux/devlink.h +++ b/include/uapi/linux/devlink.h @@ -526,6 +526,8 @@ enum devlink_attr { DEVLINK_ATTR_RELOAD_STATS_LIMIT,/* u8 */ DEVLINK_ATTR_RELOAD_STATS_VALUE,/* u32 */ DEVLINK_ATTR_REMOTE_RELOAD_STATS, /* nested */ + DEVLINK_ATTR_RELOAD_ACTION_INFO,/* nested */ + DEVLINK_ATTR_RELOAD_ACTION_STATS, /* nested */ /* add new attributes above here, update the policy in devlink.c */ diff --git a/net/core/devlink.c b/net/core/devlink.c index ab4b1368904f..34d38abd74ee 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c @@ -517,8 +517,7 @@ devlink_reload_limit_is_supported(struct devlink *devlink, enum devlink_reload_l return test_bit(limit, &devlink->ops->reload_limits); } -static int devlink_reload_stat_put(struct sk_buff *msg, enum devlink_reload_action action, - enum devlink_reload_limit limit, u32 value) +static int devlink_reload_stat_put(struct sk_buff *msg, enum devlink_reload_limit limit, u32 value) { struct nlattr *reload_stats_entry; @@ -526,8 +525,7 @@ static int devlink_reload_stat_put(struct sk_buff *msg, enum devlink_reload_acti if (!reload_stats_entry) return -EMSGSIZE; - if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_ACTION, action) || - nla_put_u8(msg, DEVLINK_ATTR_RELOAD_STATS_LIMIT, limit) || + if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_STATS_LIMIT, limit) || nla_put_u32(msg, DEVLINK_ATTR_RELOAD_STATS_VALUE, value)) goto nla_put_failure; nla_nest_end(msg, reload_stats_entry); @@ -540,7 +538,7 @@ static int devlink_reload_stat_put(struct sk_buff *msg, enum devlink_reload_acti static int devlink_reload_stats_put(struct sk_buff *msg, struct devlink *devlink, bool is_remote) { - struct nlattr *reload_stats_attr; + struct nlattr *reload_stats_attr, *action_info_attr, *action_stats_attr; int i, j, stat_idx; u32 value; @@ -552,17 +550,27 @@ static int devlink_reload_stats_put(struct sk_buff *msg, struct devlink *devlink if (!reload_stats_attr) return -EMSGSIZE; - for (j = 0; j <= DEVLINK_RELOAD_LIMIT_MAX; j++) { - /* Remote stats are shown even if not locally supported. Stats -* of actions with unspecified limit are shown though drivers -* don't need to register unspecified limit. -*/ - if (!is_remote && j != DEVLINK_RELOAD_LIMIT_UNSPEC && - !devlink_reload_limit_is_supported(devlink, j)) + for (i = 0; i <= DEVLINK_RELOAD_ACTION_MAX; i++) { + if ((!is_remote && !devlink_reload_action_is_supported(devlink, i)) || + i == DEVLINK_RELOAD_ACTION_UNSPEC) continue; - for (i = 0; i <= DEVLINK_RELOAD_ACTION_MAX; i++) { - if ((!is_remote && !devlink_reload_action_is_supported(devlink, i)) || - i == DEVLINK_RELOAD_ACTION_UNSPEC || + action_info_attr = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_INFO); + if (!action_info_attr) + goto nla_put_failure; + + if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_ACTION, i)) + goto action_info_nest_cancel; + action_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_STATS); + if (!action_stats_attr) + goto action_info_nest_cancel; + + for (j = 0; j <= DEVLINK_RELOAD_LIMIT_MAX; j++) { + /* Remote stats are shown even if not locally supported. Stats +* of actions with unspecified limit are shown though drivers +* don't need to register unspecified limit. +*/ + if ((!is_remote && j != DEVLINK_RELO
[PATCH 25/25] can: mcp251xfd: remove useless code in mcp251xfd_chip_softreset
From: Kaixu Xia It would directly return if the variable err equals to 0 or other errors. Only when the err equals to -ETIMEDOUT it can reach the 'if (err)' statement, so the 'if (err)' and last 'return -ETIMEDOUT' statements are useless. Romove them. Reported-by: Tosk Robot Signed-off-by: Kaixu Xia Link: https://lore.kernel.org/r/1605605352-25298-1-git-send-email-kaixu...@tencent.com Signed-off-by: Marc Kleine-Budde --- Hello, I had to manually resend the patch, as it was lost for unknown reasons. regards, Marc drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c index afa8cfc729b5..3297eb7ecc9c 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c @@ -644,10 +644,7 @@ static int mcp251xfd_chip_softreset(const struct mcp251xfd_priv *priv) return 0; } - if (err) - return err; - - return -ETIMEDOUT; + return err; } static int mcp251xfd_chip_clock_init(const struct mcp251xfd_priv *priv) -- 2.29.2