Linux kernel and device drivers for NXP i.MX platforms
 help / color / mirror / Atom feed
From: wei.fang@oss.nxp.com
To: claudiu.manoil@nxp.com, vladimir.oltean@nxp.com,
	xiaoning.wang@nxp.com, andrew@lunn.ch, olteanv@gmail.com,
	andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
	kuba@kernel.org, pabeni@redhat.com, linux@armlinux.org.uk
Cc: wei.fang@nxp.com, imx@lists.linux.dev, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: [PATCH v3 net-next 04/15] net: enetc: add link speed message support to PF driver
Date: Mon, 31 Aug 2026 10:54:30 +0800	[thread overview]
Message-ID: <20260831025441.635045-5-wei.fang@oss.nxp.com> (raw)
In-Reply-To: <20260831025441.635045-1-wei.fang@oss.nxp.com>

From: Wei Fang <wei.fang@nxp.com>

When a VF is driven by DPDK, the VF relies on the PF to provide accurate
link speed information so that the VF-side user space application can
make correct forwarding and configuration decisions.

Therefore, add link speed message support for DPDK-owned VF. The PF will
reply the current link speed when it receives the get link speed message
from VF.

With this enhancement, VFs controlled by DPDK can obtain real-time link
speed information from the PF, improving overall link state visibility,
synchronization between PF/VF, and enabling more accurate performance
adjustments in VF-side applications.

The PSI-to-VSI message is 16 bits and the high 8 bits are the message
class ID. For link speed message, the low bits are the speed code, so
the message supports up to 255 speed values (ENETC_MSG_SPEED_MAX = 0xff).

Instead of enumerating every speed value greater than 5Gbps explicitly,
introduce a formula-based approach:

  speed_code = (link_speed - 5000) / 1000 + ENETC_MSG_SPEED_5G

This removes the explicit enum entries for 10G, 25G, 40G,50G, 100G and
so on. Making it easy to support any future high speed without modifying
the enum or the switch statement.

Note that currently the link speed change notification is not supported.

Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
 .../ethernet/freescale/enetc/enetc_mailbox.h  | 36 ++++++++
 .../net/ethernet/freescale/enetc/enetc_msg.c  | 91 +++++++++++++++++++
 2 files changed, 127 insertions(+)

diff --git a/drivers/net/ethernet/freescale/enetc/enetc_mailbox.h b/drivers/net/ethernet/freescale/enetc/enetc_mailbox.h
index 846998f07989..bd669543e96c 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_mailbox.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_mailbox.h
@@ -91,6 +91,7 @@
  * The class code for the following messages is 8-bit.
  * 1. Get IP revision messages
  * 2. Link status messages
+ * 3. Link speed messages
  */
 #define ENETC_PF_MSG_CLASS_CODE_U8		GENMASK(7, 0)
 #define ENETC_PF_MSG_CLASS_ID			GENMASK(15, 8)
@@ -112,6 +113,7 @@ enum enetc_msg_class_id {
 	/* Common Class ID for PSI-to-VSI and VSI-to-PSI messages */
 	ENETC_MSG_CLASS_ID_MAC_FILTER		= 0x20,
 	ENETC_MSG_CLASS_ID_LINK_STATUS		= 0x80,
+	ENETC_MSG_CLASS_ID_LINK_SPEED		= 0x81,
 	ENETC_MSG_CLASS_ID_IP_REVISION		= 0xf0,
 };
 
@@ -129,6 +131,13 @@ enum enetc_msg_link_status_cmd_id {
 	ENETC_MSG_UNREGISTER_LINK_CHANGE_NOTIFIER,
 };
 
+enum enetc_msg_link_speed_cmd_id {
+	ENETC_MSG_GET_CURRENT_LINK_SPEED,
+	/* The following command IDs are not currently supported */
+	ENETC_MSG_REGISTER_SPEED_CHANGE_NOTIFIER,
+	ENETC_MSG_UNREGISTER_SPEED_CHANGE_NOTIFIER,
+};
+
 /* Class-specific error return codes of MAC filter */
 enum enetc_mac_filter_class_code {
 	ENETC_MF_CLASS_CODE_INVALID_MAC,
@@ -138,6 +147,28 @@ enum enetc_mac_filter_class_code {
 #define ENETC_CLASS_CODE_LINK_DOWN		BIT(0)
 #define ENETC_CLASS_CODE_TX_PAUSE_EN		BIT(1)
 
+/* Class-specific notifications/codes of link speed */
+enum enetc_link_speed_class_code {
+	ENETC_MSG_SPEED_UNKNOWN,
+	ENETC_MSG_SPEED_10M_HD,
+	ENETC_MSG_SPEED_10M_FD,
+	ENETC_MSG_SPEED_100M_HD,
+	ENETC_MSG_SPEED_100M_FD,
+	ENETC_MSG_SPEED_1000M,
+	ENETC_MSG_SPEED_2500M,
+	ENETC_MSG_SPEED_5G,
+	/* Do not add enumeration values for any speed greater than
+	 * 5Gbps. For any speed greater than 5Gbps, its speed class
+	 * code should follow the formula below.
+	 *
+	 * SPEED = (link_speed - 5000) / 1000 + ENETC_MSG_SPEED_5G
+	 *
+	 * The unit of link_speed should be Mbps, the max SPEED
+	 * should <= ENETC_MSG_SPEED_MAX.
+	 */
+	ENETC_MSG_SPEED_MAX = 0xff,
+};
+
 struct enetc_msg_swbd {
 	void *vaddr;
 	dma_addr_t dma;
@@ -181,6 +212,11 @@ struct enetc_msg_mac_exact_filter {
  * cmd_id 0x0: get the current link status
  * cmd_id 0x1: register link status change notification
  * cmd_id 0x2: unregister link status change notification
+ *
+ * Link speed message, class_id 0x81.
+ * cmd_id 0x0: get the current link speed.
+ * cmd_id 0x1: register link speed change notification, not supported yet
+ * cmd_id 0x2: unregister link speed change notification, not supported yet
  */
 struct enetc_msg_generic {
 	struct enetc_msg_header hdr;
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_msg.c b/drivers/net/ethernet/freescale/enetc/enetc_msg.c
index e21414acdc0d..c3ae4c024f34 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_msg.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_msg.c
@@ -280,6 +280,93 @@ static u16 enetc_msg_handle_link_status(struct enetc_pf *pf, int vf_id,
 	return 0;
 }
 
+static u16 enetc_build_link_speed_msg(int speed, int duplex)
+{
+	u32 speed_code = ENETC_MSG_SPEED_UNKNOWN;
+
+	switch (speed) {
+	case SPEED_10:
+		if (duplex == DUPLEX_HALF)
+			speed_code = ENETC_MSG_SPEED_10M_HD;
+		else if (duplex == DUPLEX_FULL)
+			speed_code = ENETC_MSG_SPEED_10M_FD;
+		break;
+	case SPEED_100:
+		if (duplex == DUPLEX_HALF)
+			speed_code = ENETC_MSG_SPEED_100M_HD;
+		else if (duplex == DUPLEX_FULL)
+			speed_code = ENETC_MSG_SPEED_100M_FD;
+		break;
+	case SPEED_1000:
+		speed_code = ENETC_MSG_SPEED_1000M;
+		break;
+	case SPEED_2500:
+		speed_code = ENETC_MSG_SPEED_2500M;
+		break;
+	case SPEED_5000:
+		speed_code = ENETC_MSG_SPEED_5G;
+		break;
+	default:
+		if (speed < SPEED_5000)
+			break;
+
+		speed_code = (speed - SPEED_5000) / SPEED_1000 +
+			     ENETC_MSG_SPEED_5G;
+		if (speed_code > ENETC_MSG_SPEED_MAX)
+			speed_code = ENETC_MSG_SPEED_UNKNOWN;
+	}
+
+	return FIELD_PREP(ENETC_PF_MSG_CLASS_ID,
+			  ENETC_MSG_CLASS_ID_LINK_SPEED) |
+	       FIELD_PREP(ENETC_PF_MSG_CLASS_CODE_U8, speed_code);
+}
+
+static u16 enetc_msg_get_link_speed(struct enetc_pf *pf, int vf_id)
+{
+	struct enetc_ndev_priv *priv = netdev_priv(pf->si->ndev);
+	struct enetc_vf_state *vf_state = &pf->vf_state[vf_id];
+	struct ethtool_link_ksettings link_info = {};
+
+	/* A malicious or malfunctioning VM could potentially spam these
+	 * messages in a tight loop causing global rtnl_lock contention,
+	 * which may severely starve other processes on the host that
+	 * require rtnl_lock for routine network configuration, resulting
+	 * in a system-wide control-plane denial of service. Therefore,
+	 * we expect the VF query for link speed to be trusted. There's no
+	 * need to consider the transition from trusted to untrusted here,
+	 * as this won't cause rtnl_lock() to be called frequently.
+	 */
+	mutex_lock(&vf_state->lock);
+	if (!(vf_state->flags & ENETC_VF_FLAG_TRUSTED)) {
+		mutex_unlock(&vf_state->lock);
+
+		return ENETC_PF_MSG_PERM_DENY;
+	}
+	mutex_unlock(&vf_state->lock);
+
+	rtnl_lock();
+	phylink_ethtool_ksettings_get(priv->phylink, &link_info);
+	rtnl_unlock();
+
+	return enetc_build_link_speed_msg(link_info.base.speed,
+					  link_info.base.duplex);
+}
+
+static u16 enetc_msg_handle_link_speed(struct enetc_pf *pf, int vf_id,
+				       void *vf_msg)
+{
+	struct enetc_msg_header *msg_hdr = vf_msg;
+
+	switch (msg_hdr->cmd_id) {
+	case ENETC_MSG_GET_CURRENT_LINK_SPEED:
+		return enetc_msg_get_link_speed(pf, vf_id);
+	case ENETC_MSG_REGISTER_SPEED_CHANGE_NOTIFIER:
+	case ENETC_MSG_UNREGISTER_SPEED_CHANGE_NOTIFIER:
+	default:
+		return ENETC_PF_MSG_NOTSUPP;
+	}
+}
+
 /* If *pf_msg is set to 0, it means that PF has responded to VF in
  * enetc_msg_handle_rxmsg() through enetc_pf_reply_msg(), which also
  * clears the corresponding VF MR bit in PSIIDR.
@@ -362,6 +449,9 @@ static void enetc_msg_handle_rxmsg(struct enetc_pf *pf, int vf_id,
 	case ENETC_MSG_CLASS_ID_LINK_STATUS:
 		*pf_msg = enetc_msg_handle_link_status(pf, vf_id, msg);
 		break;
+	case ENETC_MSG_CLASS_ID_LINK_SPEED:
+		*pf_msg = enetc_msg_handle_link_speed(pf, vf_id, msg);
+		break;
 	default:
 		dev_err_ratelimited(dev,
 				    "Unsupported message class ID: 0x%x\n",
@@ -546,6 +636,7 @@ int enetc_sriov_configure(struct pci_dev *pdev, int num_vfs)
 			dev_err(&pdev->dev, "pci_enable_sriov err %d\n", err);
 			goto err_en_sriov;
 		}
+
 	}
 
 	return num_vfs;
-- 
2.34.1


  parent reply	other threads:[~2026-08-31  3:22 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-31  2:54 [PATCH v3 net-next 00/15] net: enetc: SR-IOV improvements and ENETC v4 VF support wei.fang
2026-08-31  2:54 ` [PATCH v3 net-next 01/15] net: enetc: add trusted " wei.fang
2026-09-01  3:23   ` sashiko-bot
2026-09-01  6:13     ` Wei Fang (OSS)
2026-09-03 23:44   ` netdev-bot+sashiko
2026-09-04  6:29     ` Wei Fang
2026-08-31  2:54 ` [PATCH v3 net-next 02/15] net: enetc: move msg_task and msg_int_name to struct enetc_si wei.fang
2026-08-31  2:54 ` [PATCH v3 net-next 03/15] net: enetc: add link status message support to PF driver wei.fang
2026-08-31 12:00   ` Andrew Lunn
2026-09-01  2:31     ` Wei Fang
2026-09-01  3:05       ` Andrew Lunn
2026-09-01  3:40         ` Wei Fang
2026-09-01  3:23   ` sashiko-bot
2026-09-01  6:46     ` Wei Fang (OSS)
2026-09-03 23:44   ` netdev-bot+sashiko
2026-09-04  7:16     ` Wei Fang
2026-08-31  2:54 ` wei.fang [this message]
2026-09-03 23:44   ` [PATCH v3 net-next 04/15] net: enetc: add link speed " netdev-bot+sashiko
2026-09-04  7:52     ` Wei Fang
2026-08-31  2:54 ` [PATCH v3 net-next 05/15] net: enetc: use enetc_set_si_hw_addr() to set VF MAC address wei.fang
2026-08-31  2:54 ` [PATCH v3 net-next 06/15] net: enetc: relocate enetc_pf_set_vf_mac() for common PF support wei.fang
2026-08-31  2:54 ` [PATCH v3 net-next 07/15] net: enetc: add .ndo_set_vf_mac() to the enetc v4 driver wei.fang
2026-09-01  3:23   ` sashiko-bot
2026-09-01  6:59     ` Wei Fang (OSS)
2026-08-31  2:54 ` [PATCH v3 net-next 08/15] net: enetc: move mac_filter from struct enetc_pf to struct enetc_si wei.fang
2026-08-31  2:54 ` [PATCH v3 net-next 09/15] net: enetc: add MAC address filtering support for VFs of ENETC v4 wei.fang
2026-09-03 23:44   ` netdev-bot+sashiko
2026-08-31  2:54 ` [PATCH v3 net-next 10/15] net: enetc: simplify and rename PSIIER enable/disable helpers wei.fang
2026-08-31  2:54 ` [PATCH v3 net-next 11/15] net: enetc: restore VF MAC promiscuous mode after FLR for ENETC v4 wei.fang
2026-09-03 23:44   ` netdev-bot+sashiko
2026-09-04  8:40     ` Wei Fang
2026-08-31  2:54 ` [PATCH v3 net-next 12/15] net: enetc: add VF support for i.MX94 and i.MX95 wei.fang
2026-09-03 23:44   ` netdev-bot+sashiko
2026-09-04  9:05     ` Wei Fang
2026-08-31  2:54 ` [PATCH v3 net-next 13/15] net: enetc: implement ndo_set_rx_mode_async for ENETC v4 VF wei.fang
2026-09-03 23:44   ` netdev-bot+sashiko
2026-09-04  9:53     ` Wei Fang
2026-08-31  2:54 ` [PATCH v3 net-next 14/15] net: enetc: add PSI-to-VSI link status notification support for VF wei.fang
2026-09-01  3:23   ` sashiko-bot
2026-09-03 23:44   ` netdev-bot+sashiko
2026-09-04 10:47     ` Wei Fang
2026-08-31  2:54 ` [PATCH v3 net-next 15/15] net: enetc: add ndo_get_vf_config() support wei.fang
2026-09-03 23:44   ` netdev-bot+sashiko
2026-09-03  2:56 ` [PATCH v3 net-next 00/15] net: enetc: SR-IOV improvements and ENETC v4 VF support Jakub Kicinski
2026-09-03  3:24   ` Wei Fang (OSS)
2026-09-03 23:22     ` Jakub Kicinski
2026-09-04  2:02       ` Wei Fang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260831025441.635045-5-wei.fang@oss.nxp.com \
    --to=wei.fang@oss.nxp.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=andrew@lunn.ch \
    --cc=claudiu.manoil@nxp.com \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=imx@lists.linux.dev \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=netdev@vger.kernel.org \
    --cc=olteanv@gmail.com \
    --cc=pabeni@redhat.com \
    --cc=vladimir.oltean@nxp.com \
    --cc=wei.fang@nxp.com \
    --cc=xiaoning.wang@nxp.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox