From 135a8a4d25a2937b2727e3857471f305d78496da Mon Sep 17 00:00:00 2001 From: Stefano Garzarella Date: Wed, 14 May 2025 16:19:26 +0200 Subject: [PATCH 01/16] vsock/test: retry send() to avoid occasional failure in sigpipe test When the other peer calls shutdown(SHUT_RD), there is a chance that the send() call could occur before the message carrying the close information arrives over the transport. In such cases, the send() might still succeed. To avoid this race, let's retry the send() call a few times, ensuring the test is more reliable. Sleep a little before trying again to avoid flooding the other peer and filling its receive buffer, causing false-negative. Signed-off-by: Stefano Garzarella Link: https://patch.msgid.link/20250514141927.159456-3-sgarzare@redhat.com Signed-off-by: Jakub Kicinski --- tools/testing/vsock/vsock_test.c | 38 +++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c index 613551132a96..920867b17965 100644 --- a/tools/testing/vsock/vsock_test.c +++ b/tools/testing/vsock/vsock_test.c @@ -1058,17 +1058,34 @@ static void sigpipe(int signo) have_sigpipe = 1; } +#define SEND_SLEEP_USEC (10 * 1000) + static void test_stream_check_sigpipe(int fd) { ssize_t res; have_sigpipe = 0; - res = send(fd, "A", 1, 0); - if (res != -1) { - fprintf(stderr, "expected send(2) failure, got %zi\n", res); - exit(EXIT_FAILURE); + /* When the other peer calls shutdown(SHUT_RD), there is a chance that + * the send() call could occur before the message carrying the close + * information arrives over the transport. In such cases, the send() + * might still succeed. To avoid this race, let's retry the send() call + * a few times, ensuring the test is more reliable. + */ + timeout_begin(TIMEOUT); + while(1) { + res = send(fd, "A", 1, 0); + if (res == -1) + break; + + /* Sleep a little before trying again to avoid flooding the + * other peer and filling its receive buffer, causing + * false-negative. + */ + timeout_usleep(SEND_SLEEP_USEC); + timeout_check("send"); } + timeout_end(); if (!have_sigpipe) { fprintf(stderr, "SIGPIPE expected\n"); @@ -1077,11 +1094,16 @@ static void test_stream_check_sigpipe(int fd) have_sigpipe = 0; - res = send(fd, "A", 1, MSG_NOSIGNAL); - if (res != -1) { - fprintf(stderr, "expected send(2) failure, got %zi\n", res); - exit(EXIT_FAILURE); + timeout_begin(TIMEOUT); + while(1) { + res = send(fd, "A", 1, MSG_NOSIGNAL); + if (res == -1) + break; + + timeout_usleep(SEND_SLEEP_USEC); + timeout_check("send"); } + timeout_end(); if (have_sigpipe) { fprintf(stderr, "SIGPIPE not expected\n"); -- 2.51.0 From 3c6abbe85bccd8efb5d9147a022b1d4012cb1809 Mon Sep 17 00:00:00 2001 From: Stefano Garzarella Date: Wed, 14 May 2025 16:19:27 +0200 Subject: [PATCH 02/16] vsock/test: check also expected errno on sigpipe test In the sigpipe test, we expect send() to fail, but we do not check if send() fails with the errno we expect (EPIPE). Add this check and repeat the send() in case of EINTR as we do in other tests. Signed-off-by: Stefano Garzarella Link: https://patch.msgid.link/20250514141927.159456-4-sgarzare@redhat.com Signed-off-by: Jakub Kicinski --- tools/testing/vsock/vsock_test.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c index 920867b17965..9ea33b78b9fc 100644 --- a/tools/testing/vsock/vsock_test.c +++ b/tools/testing/vsock/vsock_test.c @@ -1075,7 +1075,7 @@ static void test_stream_check_sigpipe(int fd) timeout_begin(TIMEOUT); while(1) { res = send(fd, "A", 1, 0); - if (res == -1) + if (res == -1 && errno != EINTR) break; /* Sleep a little before trying again to avoid flooding the @@ -1087,6 +1087,10 @@ static void test_stream_check_sigpipe(int fd) } timeout_end(); + if (errno != EPIPE) { + fprintf(stderr, "unexpected send(2) errno %d\n", errno); + exit(EXIT_FAILURE); + } if (!have_sigpipe) { fprintf(stderr, "SIGPIPE expected\n"); exit(EXIT_FAILURE); @@ -1097,7 +1101,7 @@ static void test_stream_check_sigpipe(int fd) timeout_begin(TIMEOUT); while(1) { res = send(fd, "A", 1, MSG_NOSIGNAL); - if (res == -1) + if (res == -1 && errno != EINTR) break; timeout_usleep(SEND_SLEEP_USEC); @@ -1105,6 +1109,10 @@ static void test_stream_check_sigpipe(int fd) } timeout_end(); + if (errno != EPIPE) { + fprintf(stderr, "unexpected send(2) errno %d\n", errno); + exit(EXIT_FAILURE); + } if (have_sigpipe) { fprintf(stderr, "SIGPIPE not expected\n"); exit(EXIT_FAILURE); -- 2.51.0 From a462903fa22541f212134fba81084315ad843e6e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 16 May 2025 13:59:27 +0200 Subject: [PATCH 03/16] net: netlink: reduce extack cookie size Seems like the extack cookie hasn't found any users outside of wireless, which always uses nl_set_extack_cookie_u64(). Thus, allocating 20 bytes for it is pointless, reduce that to 8 bytes, and add a BUILD_BUG_ON() to ensure it's enough (obviously it is, for a u64, but in case it changes again.) Signed-off-by: Johannes Berg Link: https://patch.msgid.link/20250516115927.38209-2-johannes@sipsolutions.net Signed-off-by: Jakub Kicinski --- include/linux/netlink.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/linux/netlink.h b/include/linux/netlink.h index c3ae84a77e16..882e9c1b6c1d 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -63,7 +63,7 @@ netlink_kernel_create(struct net *net, int unit, struct netlink_kernel_cfg *cfg) } /* this can be increased when necessary - don't expose to userland */ -#define NETLINK_MAX_COOKIE_LEN 20 +#define NETLINK_MAX_COOKIE_LEN 8 #define NETLINK_MAX_FMTMSG_LEN 80 /** @@ -212,6 +212,7 @@ static inline void nl_set_extack_cookie_u64(struct netlink_ext_ack *extack, { if (!extack) return; + BUILD_BUG_ON(sizeof(extack->cookie) < sizeof(cookie)); memcpy(extack->cookie, &cookie, sizeof(cookie)); extack->cookie_len = sizeof(cookie); } -- 2.51.0 From c6a957d067912f1ab4e3be4c92d3730c21d1ddb8 Mon Sep 17 00:00:00 2001 From: Sumanth Gavini Date: Fri, 16 May 2025 15:51:48 -0700 Subject: [PATCH 04/16] selftests: drv-net: Fix "envirnoments" to "environments" Fix misspelling reported by codespell Signed-off-by: Sumanth Gavini Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250516225156.1122058-1-sumanth.gavini@yahoo.com Signed-off-by: Jakub Kicinski --- tools/testing/selftests/drivers/net/lib/py/env.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/drivers/net/lib/py/env.py b/tools/testing/selftests/drivers/net/lib/py/env.py index ad5ff645183a..3bccddf8cbc5 100644 --- a/tools/testing/selftests/drivers/net/lib/py/env.py +++ b/tools/testing/selftests/drivers/net/lib/py/env.py @@ -12,7 +12,7 @@ from .remote import Remote class NetDrvEnvBase: """ - Base class for a NIC / host envirnoments + Base class for a NIC / host environments Attributes: test_dir: Path to the source directory of the test -- 2.51.0 From 84b21e61ebd64931d865ce3df49d930db8c9e2cd Mon Sep 17 00:00:00 2001 From: Gur Stavi Date: Sun, 18 May 2025 13:00:54 +0300 Subject: [PATCH 05/16] queue_api: reduce risk of name collision over txq Rename local variable in macros from txq to _txq. When macro parameter get_desc is expended it is likely to have a txq token that refers to a different txq variable at the caller's site. Signed-off-by: Gur Stavi Reviewed-by: Jakub Kicinski Link: https://patch.msgid.link/95b60d218f004308486d92ed17c8cc6f28bac09d.1747559621.git.gur.stavi@huawei.com Signed-off-by: Jakub Kicinski --- include/net/netdev_queues.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/include/net/netdev_queues.h b/include/net/netdev_queues.h index 069ff35a72de..ba2eaf39089b 100644 --- a/include/net/netdev_queues.h +++ b/include/net/netdev_queues.h @@ -288,27 +288,27 @@ netdev_txq_completed_mb(struct netdev_queue *dev_queue, #define netif_subqueue_try_stop(dev, idx, get_desc, start_thrs) \ ({ \ - struct netdev_queue *txq; \ + struct netdev_queue *_txq; \ \ - txq = netdev_get_tx_queue(dev, idx); \ - netif_txq_try_stop(txq, get_desc, start_thrs); \ + _txq = netdev_get_tx_queue(dev, idx); \ + netif_txq_try_stop(_txq, get_desc, start_thrs); \ }) #define netif_subqueue_maybe_stop(dev, idx, get_desc, stop_thrs, start_thrs) \ ({ \ - struct netdev_queue *txq; \ + struct netdev_queue *_txq; \ \ - txq = netdev_get_tx_queue(dev, idx); \ - netif_txq_maybe_stop(txq, get_desc, stop_thrs, start_thrs); \ + _txq = netdev_get_tx_queue(dev, idx); \ + netif_txq_maybe_stop(_txq, get_desc, stop_thrs, start_thrs); \ }) #define netif_subqueue_completed_wake(dev, idx, pkts, bytes, \ get_desc, start_thrs) \ ({ \ - struct netdev_queue *txq; \ + struct netdev_queue *_txq; \ \ - txq = netdev_get_tx_queue(dev, idx); \ - netif_txq_completed_wake(txq, pkts, bytes, \ + _txq = netdev_get_tx_queue(dev, idx); \ + netif_txq_completed_wake(_txq, pkts, bytes, \ get_desc, start_thrs); \ }) -- 2.51.0 From 31be641d74267d98317ef5a2b90e6200511cabb3 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Thu, 15 May 2025 10:11:54 +0200 Subject: [PATCH 06/16] net: phy: make mdio consumer / device layer a separate module After having factored out the provider part from mdio_bus.c, we can make the mdio consumer / device layer a separate module. This also allows to remove Kconfig symbol MDIO_DEVICE. The module init / exit functions from mdio_bus.c no longer have to be called from phy_device.c. The link order defined in drivers/net/phy/Makefile ensures that init / exit functions are called in the right order. Signed-off-by: Heiner Kallweit Link: https://patch.msgid.link/dba6b156-5748-44ce-b5e2-e8dc2fcee5a7@gmail.com Signed-off-by: Paolo Abeni --- drivers/net/mdio/Kconfig | 16 ++-------------- drivers/net/phy/Kconfig | 2 +- drivers/net/phy/Makefile | 18 +++++------------- drivers/net/phy/mdio_bus.c | 14 ++++++-------- drivers/net/phy/mdio_device.c | 1 + drivers/net/phy/phy_device.c | 11 ++--------- include/linux/phy.h | 3 --- 7 files changed, 17 insertions(+), 48 deletions(-) diff --git a/drivers/net/mdio/Kconfig b/drivers/net/mdio/Kconfig index d3219ca194ec..7db40aaa079d 100644 --- a/drivers/net/mdio/Kconfig +++ b/drivers/net/mdio/Kconfig @@ -3,21 +3,10 @@ # MDIO Layer Configuration # -menuconfig MDIO_DEVICE - tristate "MDIO bus device drivers" - help - MDIO devices and driver infrastructure code. - -if MDIO_DEVICE - config MDIO_BUS - tristate - default m if PHYLIB=m - default MDIO_DEVICE + tristate "MDIO bus consumer layer" help - This internal symbol is used for link time dependencies and it - reflects whether the mdio_bus/mdio_device code is built as a - loadable module or built-in. + MDIO bus consumer layer if PHYLIB @@ -291,4 +280,3 @@ config MDIO_BUS_MUX_MMIOREG endif -endif diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 677d56e06539..127a9fd0feb9 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -14,7 +14,7 @@ config PHYLINK menuconfig PHYLIB tristate "PHY Device support and infrastructure" - select MDIO_DEVICE + select MDIO_BUS help Ethernet controllers are usually attached to PHY devices. This option provides infrastructure for diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index 59ac3a9a3177..7de69320a3a7 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -6,27 +6,19 @@ libphy-y := phy.o phy-c45.o phy-core.o phy_device.o \ phy_package.o phy_caps.o mdio_bus_provider.o mdio-bus-y += mdio_bus.o mdio_device.o -ifdef CONFIG_MDIO_DEVICE -obj-y += mdio-boardinfo.o -endif - -# PHYLIB implies MDIO_DEVICE, in that case, we have a bunch of circular -# dependencies that does not make it possible to split mdio-bus objects into a -# dedicated loadable module, so we bundle them all together into libphy.ko ifdef CONFIG_PHYLIB -libphy-y += $(mdio-bus-y) -# the stubs are built-in whenever PHYLIB is built-in or module -obj-y += stubs.o -else -obj-$(CONFIG_MDIO_DEVICE) += mdio-bus.o +# built-in whenever PHYLIB is built-in or module +obj-y += stubs.o mdio-boardinfo.o endif -obj-$(CONFIG_PHYLIB) += mdio_devres.o + libphy-$(CONFIG_SWPHY) += swphy.o libphy-$(CONFIG_LED_TRIGGER_PHY) += phy_led_triggers.o libphy-$(CONFIG_OPEN_ALLIANCE_HELPERS) += open_alliance_helpers.o +obj-$(CONFIG_MDIO_BUS) += mdio-bus.o obj-$(CONFIG_PHYLINK) += phylink.o obj-$(CONFIG_PHYLIB) += libphy.o +obj-$(CONFIG_PHYLIB) += mdio_devres.o obj-$(CONFIG_NETWORK_PHY_TIMESTAMPING) += mii_timestamper.o diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index f5ccbe33a384..a6bcb0fee863 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -988,7 +988,7 @@ const struct bus_type mdio_bus_type = { }; EXPORT_SYMBOL(mdio_bus_type); -int __init mdio_bus_init(void) +static int __init mdio_bus_init(void) { int ret; @@ -1002,16 +1002,14 @@ int __init mdio_bus_init(void) return ret; } -#if IS_ENABLED(CONFIG_PHYLIB) -void mdio_bus_exit(void) +static void __exit mdio_bus_exit(void) { class_unregister(&mdio_bus_class); bus_unregister(&mdio_bus_type); } -EXPORT_SYMBOL_GPL(mdio_bus_exit); -#else -module_init(mdio_bus_init); -/* no module_exit, intentional */ + +subsys_initcall(mdio_bus_init); +module_exit(mdio_bus_exit); + MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("MDIO bus/device layer"); -#endif diff --git a/drivers/net/phy/mdio_device.c b/drivers/net/phy/mdio_device.c index e747ee63c665..cce3f405d1a4 100644 --- a/drivers/net/phy/mdio_device.c +++ b/drivers/net/phy/mdio_device.c @@ -45,6 +45,7 @@ int mdio_device_bus_match(struct device *dev, const struct device_driver *drv) return strcmp(mdiodev->modalias, drv->name) == 0; } +EXPORT_SYMBOL_GPL(mdio_device_bus_match); struct mdio_device *mdio_device_create(struct mii_bus *bus, int addr) { diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 2eb735e68dd8..781dfa6680eb 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -3557,19 +3557,15 @@ static int __init phy_init(void) phylib_register_stubs(); rtnl_unlock(); - rc = mdio_bus_init(); - if (rc) - goto err_ethtool_phy_ops; - rc = phy_caps_init(); if (rc) - goto err_mdio_bus; + goto err_ethtool_phy_ops; features_init(); rc = phy_driver_register(&genphy_c45_driver, THIS_MODULE); if (rc) - goto err_mdio_bus; + goto err_ethtool_phy_ops; rc = phy_driver_register(&genphy_driver, THIS_MODULE); if (rc) @@ -3579,8 +3575,6 @@ static int __init phy_init(void) err_c45: phy_driver_unregister(&genphy_c45_driver); -err_mdio_bus: - mdio_bus_exit(); err_ethtool_phy_ops: rtnl_lock(); phylib_unregister_stubs(); @@ -3594,7 +3588,6 @@ static void __exit phy_exit(void) { phy_driver_unregister(&genphy_c45_driver); phy_driver_unregister(&genphy_driver); - mdio_bus_exit(); rtnl_lock(); phylib_unregister_stubs(); ethtool_set_ethtool_phy_ops(NULL); diff --git a/include/linux/phy.h b/include/linux/phy.h index 7c29d346d4b3..92a88b5ce356 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -2033,9 +2033,6 @@ int phy_ethtool_set_link_ksettings(struct net_device *ndev, const struct ethtool_link_ksettings *cmd); int phy_ethtool_nway_reset(struct net_device *ndev); -int __init mdio_bus_init(void); -void mdio_bus_exit(void); - int phy_ethtool_get_strings(struct phy_device *phydev, u8 *data); int phy_ethtool_get_sset_count(struct phy_device *phydev); int phy_ethtool_get_stats(struct phy_device *phydev, -- 2.51.0 From 9ab0ac0e532afd167b3bec39b2eb25c53486dcb5 Mon Sep 17 00:00:00 2001 From: Subbaraya Sundeep Date: Thu, 15 May 2025 23:14:08 +0530 Subject: [PATCH 07/16] octeontx2-pf: Add tracepoint for NIX_PARSE_S The NIX_PARSE_S structure populated by hardware in the NIX RX CQE has parsing information for the received packet. A tracepoint to dump the all words of NIX_PARSE_S is helpful in debugging packet parser. Signed-off-by: Subbaraya Sundeep Signed-off-by: Ratheesh Kannoth Link: https://patch.msgid.link/1747331048-15347-1-git-send-email-sbhatta@marvell.com Signed-off-by: Paolo Abeni --- .../ethernet/marvell/octeontx2/af/rvu_trace.c | 1 + .../ethernet/marvell/octeontx2/af/rvu_trace.h | 26 +++++++++++++++++++ .../marvell/octeontx2/nic/otx2_txrx.c | 6 ++++- 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_trace.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_trace.c index 5f69380ccc82..19e0d16b12f6 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_trace.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_trace.c @@ -12,3 +12,4 @@ EXPORT_TRACEPOINT_SYMBOL(otx2_msg_alloc); EXPORT_TRACEPOINT_SYMBOL(otx2_msg_interrupt); EXPORT_TRACEPOINT_SYMBOL(otx2_msg_process); EXPORT_TRACEPOINT_SYMBOL(otx2_msg_status); +EXPORT_TRACEPOINT_SYMBOL(otx2_parse_dump); diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_trace.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu_trace.h index db02b4d6ed4b..4cd0fc4b0d20 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_trace.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_trace.h @@ -133,6 +133,32 @@ TRACE_EVENT(otx2_msg_status, __get_str(str), __entry->num_msgs) ); +TRACE_EVENT(otx2_parse_dump, + TP_PROTO(const struct pci_dev *pdev, char *msg, u64 *word), + TP_ARGS(pdev, msg, word), + TP_STRUCT__entry(__string(dev, pci_name(pdev)) + __string(str, msg) + __field(u64, w0) + __field(u64, w1) + __field(u64, w2) + __field(u64, w3) + __field(u64, w4) + __field(u64, w5) + ), + TP_fast_assign(__assign_str(dev); + __assign_str(str); + __entry->w0 = *(word + 0); + __entry->w1 = *(word + 1); + __entry->w2 = *(word + 2); + __entry->w3 = *(word + 3); + __entry->w4 = *(word + 4); + __entry->w5 = *(word + 5); + ), + TP_printk("[%s] nix parse %s W0:%#llx W1:%#llx W2:%#llx W3:%#llx W4:%#llx W5:%#llx\n", + __get_str(dev), __get_str(str), __entry->w0, __entry->w1, __entry->w2, + __entry->w3, __entry->w4, __entry->w5) +); + #endif /* __RVU_TRACE_H */ #undef TRACE_INCLUDE_PATH diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c index 9593627b35a3..99ace381cc78 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c @@ -335,6 +335,7 @@ static void otx2_rcv_pkt_handler(struct otx2_nic *pfvf, struct nix_rx_parse_s *parse = &cqe->parse; struct nix_rx_sg_s *sg = &cqe->sg; struct sk_buff *skb = NULL; + u64 *word = (u64 *)parse; void *end, *start; u32 metasize = 0; u64 *seg_addr; @@ -342,9 +343,12 @@ static void otx2_rcv_pkt_handler(struct otx2_nic *pfvf, int seg; if (unlikely(parse->errlev || parse->errcode)) { - if (otx2_check_rcv_errors(pfvf, cqe, cq->cq_idx)) + if (otx2_check_rcv_errors(pfvf, cqe, cq->cq_idx)) { + trace_otx2_parse_dump(pfvf->pdev, "Err:", word); return; + } } + trace_otx2_parse_dump(pfvf->pdev, "", word); if (pfvf->xdp_prog) if (otx2_xdp_rcv_pkt_handler(pfvf, pfvf->xdp_prog, cqe, cq, -- 2.51.0 From b98b70c103dec4b321864f81678d4415521750f3 Mon Sep 17 00:00:00 2001 From: Wei Fang Date: Fri, 16 May 2025 13:27:34 +0800 Subject: [PATCH 08/16] net: enetc: fix the error handling in enetc4_pf_netdev_create() Fix the handling of err_wq_init and err_reg_netdev paths in enetc4_pf_netdev_create() function. Fixes: 6c5bafba347b ("net: enetc: add MAC filtering for i.MX95 ENETC PF") Signed-off-by: Wei Fang Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250516052734.3624191-1-wei.fang@nxp.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/freescale/enetc/enetc4_pf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c index c16378eb50bc..b3dc1afeefd1 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c +++ b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c @@ -971,8 +971,9 @@ static int enetc4_pf_netdev_create(struct enetc_si *si) return 0; err_reg_netdev: - enetc4_link_deinit(priv); + destroy_workqueue(si->workqueue); err_wq_init: + enetc4_link_deinit(priv); err_link_init: enetc_free_msix(priv); err_alloc_msix: -- 2.51.0 From 83d9623161283f5f6883ee3fdb88ef2177b8a5f1 Mon Sep 17 00:00:00 2001 From: ChunHao Lin Date: Fri, 16 May 2025 13:56:22 +0800 Subject: [PATCH 09/16] net: phy: realtek: add RTL8127-internal PHY RTL8127-internal PHY is RTL8261C which is a integrated 10Gbps PHY with ID 0x001cc890. It follows the code path of RTL8125/RTL8126 internal NBase-T PHY. Signed-off-by: ChunHao Lin Reviewed-by: Andrew Lunn Link: https://patch.msgid.link/20250516055622.3772-1-hau@realtek.com Signed-off-by: Jakub Kicinski --- drivers/net/phy/realtek/realtek_main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c index 301fbe141b9b..b5e00cdf0123 100644 --- a/drivers/net/phy/realtek/realtek_main.c +++ b/drivers/net/phy/realtek/realtek_main.c @@ -158,6 +158,7 @@ #define RTL_8221B_VB_CG 0x001cc849 #define RTL_8221B_VN_CG 0x001cc84a #define RTL_8251B 0x001cc862 +#define RTL_8261C 0x001cc890 /* RTL8211E and RTL8211F support up to three LEDs */ #define RTL8211x_LED_COUNT 3 @@ -1370,6 +1371,7 @@ static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev) case RTL_GENERIC_PHYID: case RTL_8221B: case RTL_8251B: + case RTL_8261C: case 0x001cc841: break; default: -- 2.51.0 From af295892a7abbf05a3c2ba7abc4d81bb448623d6 Mon Sep 17 00:00:00 2001 From: Petr Malat Date: Fri, 16 May 2025 10:17:28 +0200 Subject: [PATCH 10/16] sctp: Do not wake readers in __sctp_write_space() Function __sctp_write_space() doesn't set poll key, which leads to ep_poll_callback() waking up all waiters, not only these waiting for the socket being writable. Set the key properly using wake_up_interruptible_poll(), which is preferred over the sync variant, as writers are not woken up before at least half of the queue is available. Also, TCP does the same. Signed-off-by: Petr Malat Acked-by: Xin Long Link: https://patch.msgid.link/20250516081727.1361451-1-oss@malat.biz Signed-off-by: Jakub Kicinski --- net/sctp/socket.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 85a9dfeff4d6..90b75d4ec329 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -9100,7 +9100,8 @@ static void __sctp_write_space(struct sctp_association *asoc) wq = rcu_dereference(sk->sk_wq); if (wq) { if (waitqueue_active(&wq->wait)) - wake_up_interruptible(&wq->wait); + wake_up_interruptible_poll(&wq->wait, EPOLLOUT | + EPOLLWRNORM | EPOLLWRBAND); /* Note that we try to include the Async I/O support * here by modeling from the current TCP/UDP code. -- 2.51.0 From 6d243c80fe9178878f4924804d35f1ed24f590cb Mon Sep 17 00:00:00 2001 From: Sky Huang Date: Fri, 16 May 2025 18:23:26 +0800 Subject: [PATCH 11/16] net: phy: mediatek: Sort config and file names in Kconfig and Makefile Sort config and file names in Kconfig and Makefile in drivers/net/phy/mediatek/ in alphabetical order. Signed-off-by: Sky Huang Reviewed-by: Andrew Lunn Link: https://patch.msgid.link/20250516102327.2014531-2-SkyLake.Huang@mediatek.com Signed-off-by: Jakub Kicinski --- drivers/net/phy/mediatek/Kconfig | 6 +++--- drivers/net/phy/mediatek/Makefile | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/phy/mediatek/Kconfig b/drivers/net/phy/mediatek/Kconfig index 4308002bb82c..f879925b30ce 100644 --- a/drivers/net/phy/mediatek/Kconfig +++ b/drivers/net/phy/mediatek/Kconfig @@ -1,7 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -config MTK_NET_PHYLIB - tristate - config MEDIATEK_GE_PHY tristate "MediaTek Gigabit Ethernet PHYs" select MTK_NET_PHYLIB @@ -26,3 +23,6 @@ config MEDIATEK_GE_SOC_PHY the MT7981 and MT7988 SoCs. These PHYs need calibration data present in the SoCs efuse and will dynamically calibrate VCM (common-mode voltage) during startup. + +config MTK_NET_PHYLIB + tristate diff --git a/drivers/net/phy/mediatek/Makefile b/drivers/net/phy/mediatek/Makefile index 814879d0abe5..14b2c17b3f8f 100644 --- a/drivers/net/phy/mediatek/Makefile +++ b/drivers/net/phy/mediatek/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_MTK_NET_PHYLIB) += mtk-phy-lib.o obj-$(CONFIG_MEDIATEK_GE_PHY) += mtk-ge.o obj-$(CONFIG_MEDIATEK_GE_SOC_PHY) += mtk-ge-soc.o +obj-$(CONFIG_MTK_NET_PHYLIB) += mtk-phy-lib.o -- 2.51.0 From 26948c2430412b667fcc2302dcff15ca45b3cd52 Mon Sep 17 00:00:00 2001 From: Sky Huang Date: Fri, 16 May 2025 18:23:27 +0800 Subject: [PATCH 12/16] net: phy: mediatek: add driver for built-in 2.5G ethernet PHY on MT7988 Add support for internal 2.5Gphy on MT7988. This driver will load necessary firmware and add appropriate time delay to make sure that firmware works stably. The firmware loading procedure takes about 11ms in this driver. Signed-off-by: Sky Huang Reviewed-by: Andrew Lunn Link: https://patch.msgid.link/20250516102327.2014531-3-SkyLake.Huang@mediatek.com Signed-off-by: Jakub Kicinski --- MAINTAINERS | 1 + drivers/net/phy/mediatek/Kconfig | 11 + drivers/net/phy/mediatek/Makefile | 1 + drivers/net/phy/mediatek/mtk-2p5ge.c | 321 +++++++++++++++++++++++++++ 4 files changed, 334 insertions(+) create mode 100644 drivers/net/phy/mediatek/mtk-2p5ge.c diff --git a/MAINTAINERS b/MAINTAINERS index c8e91820b527..536a81712c71 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15034,6 +15034,7 @@ M: Qingfang Deng M: SkyLake Huang L: netdev@vger.kernel.org S: Maintained +F: drivers/net/phy/mediatek/mtk-2p5ge.c F: drivers/net/phy/mediatek/mtk-ge-soc.c F: drivers/net/phy/mediatek/mtk-phy-lib.c F: drivers/net/phy/mediatek/mtk-ge.c diff --git a/drivers/net/phy/mediatek/Kconfig b/drivers/net/phy/mediatek/Kconfig index f879925b30ce..9f30a91be8dd 100644 --- a/drivers/net/phy/mediatek/Kconfig +++ b/drivers/net/phy/mediatek/Kconfig @@ -1,4 +1,15 @@ # SPDX-License-Identifier: GPL-2.0-only +config MEDIATEK_2P5GE_PHY + tristate "MediaTek 2.5Gb Ethernet PHYs" + depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST + select MTK_NET_PHYLIB + help + Supports MediaTek SoC built-in 2.5Gb Ethernet PHYs. + + This will load necessary firmware and add appropriate time delay. + Accelerate this procedure through internal pbus instead of MDIO + bus. Certain link-up issues will also be fixed here. + config MEDIATEK_GE_PHY tristate "MediaTek Gigabit Ethernet PHYs" select MTK_NET_PHYLIB diff --git a/drivers/net/phy/mediatek/Makefile b/drivers/net/phy/mediatek/Makefile index 14b2c17b3f8f..ac57ecc799fc 100644 --- a/drivers/net/phy/mediatek/Makefile +++ b/drivers/net/phy/mediatek/Makefile @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_MEDIATEK_2P5GE_PHY) += mtk-2p5ge.o obj-$(CONFIG_MEDIATEK_GE_PHY) += mtk-ge.o obj-$(CONFIG_MEDIATEK_GE_SOC_PHY) += mtk-ge-soc.o obj-$(CONFIG_MTK_NET_PHYLIB) += mtk-phy-lib.o diff --git a/drivers/net/phy/mediatek/mtk-2p5ge.c b/drivers/net/phy/mediatek/mtk-2p5ge.c new file mode 100644 index 000000000000..e147eab523ef --- /dev/null +++ b/drivers/net/phy/mediatek/mtk-2p5ge.c @@ -0,0 +1,321 @@ +// SPDX-License-Identifier: GPL-2.0+ +#include +#include +#include +#include +#include +#include +#include + +#include "mtk.h" + +#define MTK_2P5GPHY_ID_MT7988 0x00339c11 + +#define MT7988_2P5GE_PMB_FW "mediatek/mt7988/i2p5ge-phy-pmb.bin" +#define MT7988_2P5GE_PMB_FW_SIZE 0x20000 +#define MT7988_2P5GE_PMB_FW_BASE 0x0f100000 +#define MT7988_2P5GE_PMB_FW_LEN 0x20000 +#define MTK_2P5GPHY_MCU_CSR_BASE 0x0f0f0000 +#define MTK_2P5GPHY_MCU_CSR_LEN 0x20 +#define MD32_EN_CFG 0x18 +#define MD32_EN BIT(0) + +#define BASE100T_STATUS_EXTEND 0x10 +#define BASE1000T_STATUS_EXTEND 0x11 +#define EXTEND_CTRL_AND_STATUS 0x16 + +#define PHY_AUX_CTRL_STATUS 0x1d +#define PHY_AUX_DPX_MASK GENMASK(5, 5) +#define PHY_AUX_SPEED_MASK GENMASK(4, 2) + +/* Registers on MDIO_MMD_VEND1 */ +#define MTK_PHY_LPI_PCS_DSP_CTRL 0x121 +#define MTK_PHY_LPI_SIG_EN_LO_THRESH100_MASK GENMASK(12, 8) + +#define MTK_PHY_HOST_CMD1 0x800e +#define MTK_PHY_HOST_CMD2 0x800f +/* Registers on Token Ring debug nodes */ +/* ch_addr = 0x0, node_addr = 0xf, data_addr = 0x3c */ +#define AUTO_NP_10XEN BIT(6) + +enum { + PHY_AUX_SPD_10 = 0, + PHY_AUX_SPD_100, + PHY_AUX_SPD_1000, + PHY_AUX_SPD_2500, +}; + +static int mt798x_2p5ge_phy_load_fw(struct phy_device *phydev) +{ + struct device *dev = &phydev->mdio.dev; + void __iomem *mcu_csr_base, *pmb_addr; + const struct firmware *fw; + int ret, i; + u32 reg; + + pmb_addr = ioremap(MT7988_2P5GE_PMB_FW_BASE, MT7988_2P5GE_PMB_FW_LEN); + if (!pmb_addr) + return -ENOMEM; + mcu_csr_base = ioremap(MTK_2P5GPHY_MCU_CSR_BASE, + MTK_2P5GPHY_MCU_CSR_LEN); + if (!mcu_csr_base) { + ret = -ENOMEM; + goto free_pmb; + } + + ret = request_firmware_direct(&fw, MT7988_2P5GE_PMB_FW, dev); + if (ret) { + dev_err(dev, "failed to load firmware: %s, ret: %d\n", + MT7988_2P5GE_PMB_FW, ret); + goto free; + } + + if (fw->size != MT7988_2P5GE_PMB_FW_SIZE) { + dev_err(dev, "Firmware size 0x%zx != 0x%x\n", + fw->size, MT7988_2P5GE_PMB_FW_SIZE); + ret = -EINVAL; + goto release_fw; + } + + reg = readw(mcu_csr_base + MD32_EN_CFG); + if (reg & MD32_EN) { + phy_set_bits(phydev, MII_BMCR, BMCR_RESET); + usleep_range(10000, 11000); + } + phy_set_bits(phydev, MII_BMCR, BMCR_PDOWN); + + /* Write magic number to safely stall MCU */ + phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_HOST_CMD1, 0x1100); + phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_HOST_CMD2, 0x00df); + + for (i = 0; i < MT7988_2P5GE_PMB_FW_SIZE - 1; i += 4) + writel(*((uint32_t *)(fw->data + i)), pmb_addr + i); + + writew(reg & ~MD32_EN, mcu_csr_base + MD32_EN_CFG); + writew(reg | MD32_EN, mcu_csr_base + MD32_EN_CFG); + phy_set_bits(phydev, MII_BMCR, BMCR_RESET); + /* We need a delay here to stabilize initialization of MCU */ + usleep_range(7000, 8000); + + dev_info(dev, "Firmware date code: %x/%x/%x, version: %x.%x\n", + be16_to_cpu(*((__be16 *)(fw->data + + MT7988_2P5GE_PMB_FW_SIZE - 8))), + *(fw->data + MT7988_2P5GE_PMB_FW_SIZE - 6), + *(fw->data + MT7988_2P5GE_PMB_FW_SIZE - 5), + *(fw->data + MT7988_2P5GE_PMB_FW_SIZE - 2), + *(fw->data + MT7988_2P5GE_PMB_FW_SIZE - 1)); + +release_fw: + release_firmware(fw); +free: + iounmap(mcu_csr_base); +free_pmb: + iounmap(pmb_addr); + + return ret; +} + +static int mt798x_2p5ge_phy_config_init(struct phy_device *phydev) +{ + /* Check if PHY interface type is compatible */ + if (phydev->interface != PHY_INTERFACE_MODE_INTERNAL) + return -ENODEV; + + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LPI_PCS_DSP_CTRL, + MTK_PHY_LPI_SIG_EN_LO_THRESH100_MASK, 0); + + /* Enable 16-bit next page exchange bit if 1000-BT isn't advertising */ + mtk_tr_modify(phydev, 0x0, 0xf, 0x3c, AUTO_NP_10XEN, + FIELD_PREP(AUTO_NP_10XEN, 0x1)); + + /* Enable HW auto downshift */ + phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED_1, + MTK_PHY_AUX_CTRL_AND_STATUS, + 0, MTK_PHY_ENABLE_DOWNSHIFT); + + return 0; +} + +static int mt798x_2p5ge_phy_config_aneg(struct phy_device *phydev) +{ + bool changed = false; + u32 adv; + int ret; + + ret = genphy_c45_an_config_aneg(phydev); + if (ret < 0) + return ret; + if (ret > 0) + changed = true; + + /* Clause 45 doesn't define 1000BaseT support. Use Clause 22 instead in + * our design. + */ + adv = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising); + ret = phy_modify_changed(phydev, MII_CTRL1000, ADVERTISE_1000FULL, adv); + if (ret < 0) + return ret; + if (ret > 0) + changed = true; + + return genphy_c45_check_and_restart_aneg(phydev, changed); +} + +static int mt798x_2p5ge_phy_get_features(struct phy_device *phydev) +{ + int ret; + + ret = genphy_c45_pma_read_abilities(phydev); + if (ret) + return ret; + + /* This phy can't handle collision, and neither can (XFI)MAC it's + * connected to. Although it can do HDX handshake, it doesn't support + * CSMA/CD that HDX requires. + */ + linkmode_clear_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, + phydev->supported); + + return 0; +} + +static int mt798x_2p5ge_phy_read_status(struct phy_device *phydev) +{ + int ret; + + /* When MDIO_STAT1_LSTATUS is raised genphy_c45_read_link(), this phy + * actually hasn't finished AN. So use CL22's link update function + * instead. + */ + ret = genphy_update_link(phydev); + if (ret) + return ret; + + phydev->speed = SPEED_UNKNOWN; + phydev->duplex = DUPLEX_UNKNOWN; + phydev->pause = 0; + phydev->asym_pause = 0; + + /* We'll read link speed through vendor specific registers down below. + * So remove phy_resolve_aneg_linkmode (AN on) & genphy_c45_read_pma + * (AN off). + */ + if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) { + ret = genphy_c45_read_lpa(phydev); + if (ret < 0) + return ret; + + /* Clause 45 doesn't define 1000BaseT support. Read the link + * partner's 1G advertisement via Clause 22. + */ + ret = phy_read(phydev, MII_STAT1000); + if (ret < 0) + return ret; + mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, ret); + } else if (phydev->autoneg == AUTONEG_DISABLE) { + linkmode_zero(phydev->lp_advertising); + } + + if (phydev->link) { + ret = phy_read(phydev, PHY_AUX_CTRL_STATUS); + if (ret < 0) + return ret; + + switch (FIELD_GET(PHY_AUX_SPEED_MASK, ret)) { + case PHY_AUX_SPD_10: + phydev->speed = SPEED_10; + break; + case PHY_AUX_SPD_100: + phydev->speed = SPEED_100; + break; + case PHY_AUX_SPD_1000: + phydev->speed = SPEED_1000; + break; + case PHY_AUX_SPD_2500: + phydev->speed = SPEED_2500; + break; + } + + phydev->duplex = DUPLEX_FULL; + phydev->rate_matching = RATE_MATCH_PAUSE; + } + + return 0; +} + +static int mt798x_2p5ge_phy_get_rate_matching(struct phy_device *phydev, + phy_interface_t iface) +{ + return RATE_MATCH_PAUSE; +} + +static int mt798x_2p5ge_phy_probe(struct phy_device *phydev) +{ + struct pinctrl *pinctrl; + int ret; + + switch (phydev->drv->phy_id) { + case MTK_2P5GPHY_ID_MT7988: + /* This built-in 2.5GbE hardware only sets MDIO_DEVS_PMAPMD. + * Set the rest by this driver since PCS/AN/VEND1/VEND2 MDIO + * manageable devices actually exist. + */ + phydev->c45_ids.mmds_present |= MDIO_DEVS_PCS | + MDIO_DEVS_AN | + MDIO_DEVS_VEND1 | + MDIO_DEVS_VEND2; + break; + default: + return -EINVAL; + } + + ret = mt798x_2p5ge_phy_load_fw(phydev); + if (ret < 0) + return ret; + + /* Setup LED */ + phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL, + MTK_PHY_LED_ON_POLARITY | MTK_PHY_LED_ON_LINK10 | + MTK_PHY_LED_ON_LINK100 | MTK_PHY_LED_ON_LINK1000 | + MTK_PHY_LED_ON_LINK2500); + phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED1_ON_CTRL, + MTK_PHY_LED_ON_FDX | MTK_PHY_LED_ON_HDX); + + /* Switch pinctrl after setting polarity to avoid bogus blinking */ + pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "i2p5gbe-led"); + if (IS_ERR(pinctrl)) + dev_err(&phydev->mdio.dev, "Fail to set LED pins!\n"); + + return 0; +} + +static struct phy_driver mtk_2p5gephy_driver[] = { + { + PHY_ID_MATCH_MODEL(MTK_2P5GPHY_ID_MT7988), + .name = "MediaTek MT7988 2.5GbE PHY", + .probe = mt798x_2p5ge_phy_probe, + .config_init = mt798x_2p5ge_phy_config_init, + .config_aneg = mt798x_2p5ge_phy_config_aneg, + .get_features = mt798x_2p5ge_phy_get_features, + .read_status = mt798x_2p5ge_phy_read_status, + .get_rate_matching = mt798x_2p5ge_phy_get_rate_matching, + .suspend = genphy_suspend, + .resume = genphy_resume, + .read_page = mtk_phy_read_page, + .write_page = mtk_phy_write_page, + }, +}; + +module_phy_driver(mtk_2p5gephy_driver); + +static struct mdio_device_id __maybe_unused mtk_2p5ge_phy_tbl[] = { + { PHY_ID_MATCH_VENDOR(0x00339c00) }, + { } +}; + +MODULE_DESCRIPTION("MediaTek 2.5Gb Ethernet PHY driver"); +MODULE_AUTHOR("SkyLake Huang "); +MODULE_LICENSE("GPL"); + +MODULE_DEVICE_TABLE(mdio, mtk_2p5ge_phy_tbl); +MODULE_FIRMWARE(MT7988_2P5GE_PMB_FW); -- 2.51.0 From fa919a30dd471364db09d7cf6a02c487352fda4e Mon Sep 17 00:00:00 2001 From: Lee Trager Date: Fri, 16 May 2025 09:46:41 -0700 Subject: [PATCH 13/16] eth: fbnic: Replace kzalloc/fbnic_fw_init_cmpl with fbnic_fw_alloc_cmpl Replace the pattern of calling and validating kzalloc then fbnic_fw_init_cmpl with a single function, fbnic_fw_alloc_cmpl. Signed-off-by: Lee Trager Reviewed-by: Jacob Keller Link: https://patch.msgid.link/20250516164804.741348-1-lee@trager.us Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/meta/fbnic/fbnic_devlink.c | 6 ++---- drivers/net/ethernet/meta/fbnic/fbnic_fw.c | 17 ++++++++++++----- drivers/net/ethernet/meta/fbnic/fbnic_fw.h | 3 +-- drivers/net/ethernet/meta/fbnic/fbnic_mac.c | 5 +---- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_devlink.c b/drivers/net/ethernet/meta/fbnic/fbnic_devlink.c index 71d9461a0d1b..4c4938eedd7b 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_devlink.c +++ b/drivers/net/ethernet/meta/fbnic/fbnic_devlink.c @@ -166,11 +166,10 @@ fbnic_flash_start(struct fbnic_dev *fbd, struct pldmfw_component *component) struct fbnic_fw_completion *cmpl; int err; - cmpl = kzalloc(sizeof(*cmpl), GFP_KERNEL); + cmpl = fbnic_fw_alloc_cmpl(FBNIC_TLV_MSG_ID_FW_START_UPGRADE_REQ); if (!cmpl) return -ENOMEM; - fbnic_fw_init_cmpl(cmpl, FBNIC_TLV_MSG_ID_FW_START_UPGRADE_REQ); err = fbnic_fw_xmit_fw_start_upgrade(fbd, cmpl, component->identifier, component->component_size); @@ -237,11 +236,10 @@ fbnic_flash_component(struct pldmfw *context, * Setup completions for write before issuing the start message so * the driver can catch both messages. */ - cmpl = kzalloc(sizeof(*cmpl), GFP_KERNEL); + cmpl = fbnic_fw_alloc_cmpl(FBNIC_TLV_MSG_ID_FW_WRITE_CHUNK_REQ); if (!cmpl) return -ENOMEM; - fbnic_fw_init_cmpl(cmpl, FBNIC_TLV_MSG_ID_FW_WRITE_CHUNK_REQ); err = fbnic_mbx_set_cmpl(fbd, cmpl); if (err) goto cmpl_free; diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c index 6a803a59dc25..e2368075ab8c 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c +++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c @@ -1232,12 +1232,19 @@ void fbnic_get_fw_ver_commit_str(struct fbnic_dev *fbd, char *fw_version, fw_version, str_sz); } -void fbnic_fw_init_cmpl(struct fbnic_fw_completion *fw_cmpl, - u32 msg_type) +struct fbnic_fw_completion *fbnic_fw_alloc_cmpl(u32 msg_type) { - fw_cmpl->msg_type = msg_type; - init_completion(&fw_cmpl->done); - kref_init(&fw_cmpl->ref_count); + struct fbnic_fw_completion *cmpl; + + cmpl = kzalloc(sizeof(*cmpl), GFP_KERNEL); + if (!cmpl) + return NULL; + + cmpl->msg_type = msg_type; + init_completion(&cmpl->done); + kref_init(&cmpl->ref_count); + + return cmpl; } void fbnic_fw_clear_cmpl(struct fbnic_dev *fbd, diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw.h b/drivers/net/ethernet/meta/fbnic/fbnic_fw.h index 6baac10fd688..08bc4b918de7 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_fw.h +++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw.h @@ -80,8 +80,7 @@ int fbnic_fw_xmit_fw_write_chunk(struct fbnic_dev *fbd, int cancel_error); int fbnic_fw_xmit_tsene_read_msg(struct fbnic_dev *fbd, struct fbnic_fw_completion *cmpl_data); -void fbnic_fw_init_cmpl(struct fbnic_fw_completion *cmpl_data, - u32 msg_type); +struct fbnic_fw_completion *fbnic_fw_alloc_cmpl(u32 msg_type); void fbnic_fw_clear_cmpl(struct fbnic_dev *fbd, struct fbnic_fw_completion *cmpl_data); void fbnic_fw_put_cmpl(struct fbnic_fw_completion *cmpl_data); diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_mac.c b/drivers/net/ethernet/meta/fbnic/fbnic_mac.c index 4ba6f8d10775..10e108c1fcd0 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_mac.c +++ b/drivers/net/ethernet/meta/fbnic/fbnic_mac.c @@ -687,13 +687,10 @@ static int fbnic_mac_get_sensor_asic(struct fbnic_dev *fbd, int id, int err = 0, retries = 5; s32 *sensor; - fw_cmpl = kzalloc(sizeof(*fw_cmpl), GFP_KERNEL); + fw_cmpl = fbnic_fw_alloc_cmpl(FBNIC_TLV_MSG_ID_TSENE_READ_RESP); if (!fw_cmpl) return -ENOMEM; - /* Initialize completion and queue it for FW to process */ - fbnic_fw_init_cmpl(fw_cmpl, FBNIC_TLV_MSG_ID_TSENE_READ_RESP); - switch (id) { case FBNIC_SENSOR_TEMP: sensor = &fw_cmpl->u.tsene.millidegrees; -- 2.51.0 From f792709e0baad67224180d73d51c2f090003adde Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Fri, 16 May 2025 16:22:05 -0700 Subject: [PATCH 14/16] selftests: net: validate team flags propagation Cover three recent cases: 1. missing ops locking for the lowers during netdev_sync_lower_features 2. missing locking for dev_set_promiscuity (plus netdev_ops_assert_locked with a comment on why/when it's needed) 3. rcu lock during team_change_rx_flags Verified that each one triggers when the respective fix is reverted. Not sure about the placement, but since it all relies on teaming, added to the teaming directory. One ugly bit is that I add NETIF_F_LRO to netdevsim; there is no way to trigger netdev_sync_lower_features without it. Signed-off-by: Stanislav Fomichev Link: https://patch.msgid.link/20250516232205.539266-1-stfomichev@gmail.com Signed-off-by: Jakub Kicinski --- drivers/net/netdevsim/netdev.c | 2 + net/core/dev.c | 10 ++- .../selftests/drivers/net/team/Makefile | 2 +- .../testing/selftests/drivers/net/team/config | 1 + .../selftests/drivers/net/team/propagation.sh | 80 +++++++++++++++++++ 5 files changed, 93 insertions(+), 2 deletions(-) create mode 100755 tools/testing/selftests/drivers/net/team/propagation.sh diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c index 2aa999345fe1..af545d42961c 100644 --- a/drivers/net/netdevsim/netdev.c +++ b/drivers/net/netdevsim/netdev.c @@ -881,11 +881,13 @@ static void nsim_setup(struct net_device *dev) NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HW_CSUM | + NETIF_F_LRO | NETIF_F_TSO; dev->hw_features |= NETIF_F_HW_TC | NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HW_CSUM | + NETIF_F_LRO | NETIF_F_TSO; dev->max_mtu = ETH_MAX_MTU; dev->xdp_features = NETDEV_XDP_ACT_HW_OFFLOAD; diff --git a/net/core/dev.c b/net/core/dev.c index fccf2167b235..6d1a238dd440 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -9278,8 +9278,16 @@ static int __dev_set_promiscuity(struct net_device *dev, int inc, bool notify) dev_change_rx_flags(dev, IFF_PROMISC); } - if (notify) + if (notify) { + /* The ops lock is only required to ensure consistent locking + * for `NETDEV_CHANGE` notifiers. This function is sometimes + * called without the lock, even for devices that are ops + * locked, such as in `dev_uc_sync_multiple` when using + * bonding or teaming. + */ + netdev_ops_assert_locked(dev); __dev_notify_flags(dev, old_flags, IFF_PROMISC, 0, NULL); + } return 0; } diff --git a/tools/testing/selftests/drivers/net/team/Makefile b/tools/testing/selftests/drivers/net/team/Makefile index 2d5a76d99181..eaf6938f100e 100644 --- a/tools/testing/selftests/drivers/net/team/Makefile +++ b/tools/testing/selftests/drivers/net/team/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 # Makefile for net selftests -TEST_PROGS := dev_addr_lists.sh +TEST_PROGS := dev_addr_lists.sh propagation.sh TEST_INCLUDES := \ ../bonding/lag_lib.sh \ diff --git a/tools/testing/selftests/drivers/net/team/config b/tools/testing/selftests/drivers/net/team/config index b5e3a3aad4bf..636b3525b679 100644 --- a/tools/testing/selftests/drivers/net/team/config +++ b/tools/testing/selftests/drivers/net/team/config @@ -1,5 +1,6 @@ CONFIG_DUMMY=y CONFIG_IPV6=y CONFIG_MACVLAN=y +CONFIG_NETDEVSIM=m CONFIG_NET_TEAM=y CONFIG_NET_TEAM_MODE_LOADBALANCE=y diff --git a/tools/testing/selftests/drivers/net/team/propagation.sh b/tools/testing/selftests/drivers/net/team/propagation.sh new file mode 100755 index 000000000000..4bea75b79878 --- /dev/null +++ b/tools/testing/selftests/drivers/net/team/propagation.sh @@ -0,0 +1,80 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +set -e + +NSIM_LRO_ID=$((256 + RANDOM % 256)) +NSIM_LRO_SYS=/sys/bus/netdevsim/devices/netdevsim$NSIM_LRO_ID + +NSIM_DEV_SYS_NEW=/sys/bus/netdevsim/new_device +NSIM_DEV_SYS_DEL=/sys/bus/netdevsim/del_device + +cleanup() +{ + set +e + ip link del dummyteam &>/dev/null + ip link del team0 &>/dev/null + echo $NSIM_LRO_ID > $NSIM_DEV_SYS_DEL + modprobe -r netdevsim +} + +# Trigger LRO propagation to the lower. +# https://lore.kernel.org/netdev/aBvOpkIoxcr9PfDg@mini-arch/ +team_lro() +{ + # using netdevsim because it supports NETIF_F_LRO + NSIM_LRO_NAME=$(find $NSIM_LRO_SYS/net -maxdepth 1 -type d ! \ + -path $NSIM_LRO_SYS/net -exec basename {} \;) + + ip link add name team0 type team + ip link set $NSIM_LRO_NAME down + ip link set dev $NSIM_LRO_NAME master team0 + ip link set team0 up + ethtool -K team0 large-receive-offload off + + ip link del team0 +} + +# Trigger promisc propagation to the lower during IFLA_MASTER. +# https://lore.kernel.org/netdev/20250506032328.3003050-1-sdf@fomichev.me/ +team_promisc() +{ + ip link add name dummyteam type dummy + ip link add name team0 type team + ip link set dummyteam down + ip link set team0 promisc on + ip link set dev dummyteam master team0 + ip link set team0 up + + ip link del team0 + ip link del dummyteam +} + +# Trigger promisc propagation to the lower via netif_change_flags (aka +# ndo_change_rx_flags). +# https://lore.kernel.org/netdev/20250514220319.3505158-1-stfomichev@gmail.com/ +team_change_flags() +{ + ip link add name dummyteam type dummy + ip link add name team0 type team + ip link set dummyteam down + ip link set dev dummyteam master team0 + ip link set team0 up + ip link set team0 promisc on + + # Make sure we can add more L2 addresses without any issues. + ip link add link team0 address 00:00:00:00:00:01 team0.1 type macvlan + ip link set team0.1 up + + ip link del team0.1 + ip link del team0 + ip link del dummyteam +} + +trap cleanup EXIT +modprobe netdevsim || : +echo $NSIM_LRO_ID > $NSIM_DEV_SYS_NEW +udevadm settle +team_lro +team_promisc +team_change_flags -- 2.51.0 From 20d9b73217c6109ae69679ebb28ccfaf87e55c14 Mon Sep 17 00:00:00 2001 From: Sumanth Gavini Date: Fri, 16 May 2025 18:59:37 -0700 Subject: [PATCH 15/16] selftests: nci: Fix "Electrnoics" to "Electronics" Fix misspelling reported by codespell Signed-off-by: Sumanth Gavini Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250517020003.1159640-1-sumanth.gavini@yahoo.com Signed-off-by: Jakub Kicinski --- tools/testing/selftests/nci/nci_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/nci/nci_dev.c b/tools/testing/selftests/nci/nci_dev.c index 1562aa7d60b0..6dec59d64083 100644 --- a/tools/testing/selftests/nci/nci_dev.c +++ b/tools/testing/selftests/nci/nci_dev.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (C) 2021 Samsung Electrnoics + * Copyright (C) 2021 Samsung Electronics * Bongsu Jeon * * Test code for nci -- 2.51.0 From 6a7e8b5d632834f2722cdabf81bd0b9eef3a214d Mon Sep 17 00:00:00 2001 From: Sumanth Gavini Date: Fri, 16 May 2025 20:25:33 -0700 Subject: [PATCH 16/16] selftests: net: Fix spellings Fix "withouth" to "without" Fix "instaces" to "instances" Signed-off-by: Sumanth Gavini Reviewed-by: Andrea Mayer Link: https://patch.msgid.link/20250517032535.1176351-1-sumanth.gavini@yahoo.com Signed-off-by: Jakub Kicinski --- tools/testing/selftests/net/srv6_end_flavors_test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/net/srv6_end_flavors_test.sh b/tools/testing/selftests/net/srv6_end_flavors_test.sh index 50563443a4ad..318487eda671 100755 --- a/tools/testing/selftests/net/srv6_end_flavors_test.sh +++ b/tools/testing/selftests/net/srv6_end_flavors_test.sh @@ -399,7 +399,7 @@ __get_srv6_rtcfg_id() # Given the description of a router as an input, the function returns # the token which represents the operation (e.g. End behavior with or -# withouth flavors) configured for the node. +# without flavors) configured for the node. # Note that when the operation represents an End behavior with a list of # flavors, the output is the ordered version of that list. @@ -480,7 +480,7 @@ setup_rt_local_sids() # all SIDs start with a common locator. Routes and SRv6 Endpoint - # behavior instaces are grouped together in the 'localsid' table. + # behavior instances are grouped together in the 'localsid' table. ip -netns "${nsname}" -6 rule \ add to "${LOCATOR_SERVICE}::/16" \ lookup "${LOCALSID_TABLE_ID}" prio 999 -- 2.51.0