[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250120004913.2154398-2-aryan.srivastava@alliedtelesis.co.nz>
Date: Mon, 20 Jan 2025 13:49:11 +1300
From: Aryan Srivastava <aryan.srivastava@...iedtelesis.co.nz>
To: Jiri Pirko <jiri@...nulli.us>,
Andrew Lunn <andrew@...n.ch>
Cc: netdev@...r.kernel.org,
linux-kernel@...r.kernel.org,
Aryan Srivastava <aryan.srivastava@...iedtelesis.co.nz>,
"David S. Miller" <davem@...emloft.net>,
Eric Dumazet <edumazet@...gle.com>,
Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>,
Simon Horman <horms@...nel.org>
Subject: [RFC net-next v1 1/2] net: devlink: Add port function for bridge offload
Add configurable devlink port attr for HW offloading. Most drivers (and
DSA framework) will offload a bridge port to HW if there is mechanism
available to do so. Adding a configurable devlink attr allows users to
change this default setting, in cases where HW offload of a bridge port
is not desired.
Signed-off-by: Aryan Srivastava <aryan.srivastava@...iedtelesis.co.nz>
---
include/net/devlink.h | 13 ++++++++++++
include/uapi/linux/devlink.h | 2 ++
net/devlink/port.c | 41 ++++++++++++++++++++++++++++++++++++
3 files changed, 56 insertions(+)
diff --git a/include/net/devlink.h b/include/net/devlink.h
index b8783126c1ed..79211b3cdc1a 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -1627,6 +1627,15 @@ void devlink_free(struct devlink *devlink);
* of event queues. Should be used by device drivers to
* configure maximum number of event queues
* of a function managed by the devlink port.
+ * @port_fn_bridge_offload_get: Callback used to get port function's bridge
+ * offload capability. Should be used by device drivers
+ * to report the current state of offload
+ * capability of a function managed by the devlink
+ * port.
+ * @port_fn_bridge_offload_get: Callback used to set port function's bridge
+ * offload capability. Should be used by device drivers to
+ * enable/disable offload capability of a
+ * function managed by the devlink port.
*
* Note: Driver should return -EOPNOTSUPP if it doesn't support
* port function (@port_fn_*) handling for a particular port.
@@ -1682,6 +1691,10 @@ struct devlink_port_ops {
int (*port_fn_max_io_eqs_set)(struct devlink_port *devlink_port,
u32 max_eqs,
struct netlink_ext_ack *extack);
+ void (*port_fn_bridge_offload_get)(struct devlink_port *devlink_port,
+ bool *is_enable);
+ void (*port_fn_bridge_offload_set)(struct devlink_port *devlink_port,
+ bool enable);
};
void devlink_port_init(struct devlink *devlink,
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index 9401aa343673..e2682bc9ecb1 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -668,6 +668,7 @@ enum devlink_port_fn_attr_cap {
DEVLINK_PORT_FN_ATTR_CAP_MIGRATABLE_BIT,
DEVLINK_PORT_FN_ATTR_CAP_IPSEC_CRYPTO_BIT,
DEVLINK_PORT_FN_ATTR_CAP_IPSEC_PACKET_BIT,
+ DEVLINK_PORT_FN_ATTR_CAP_BRIDGE_OFFLOAD_BIT,
/* Add new caps above */
__DEVLINK_PORT_FN_ATTR_CAPS_MAX,
@@ -678,6 +679,7 @@ enum devlink_port_fn_attr_cap {
_BITUL(DEVLINK_PORT_FN_ATTR_CAP_MIGRATABLE_BIT)
#define DEVLINK_PORT_FN_CAP_IPSEC_CRYPTO _BITUL(DEVLINK_PORT_FN_ATTR_CAP_IPSEC_CRYPTO_BIT)
#define DEVLINK_PORT_FN_CAP_IPSEC_PACKET _BITUL(DEVLINK_PORT_FN_ATTR_CAP_IPSEC_PACKET_BIT)
+#define DEVLINK_PORT_FN_CAP_BRIDGE_OFFLOAD _BITUL(DEVLINK_PORT_FN_ATTR_CAP_BRIDGE_OFFLOAD_BIT)
enum devlink_port_function_attr {
DEVLINK_PORT_FUNCTION_ATTR_UNSPEC,
diff --git a/net/devlink/port.c b/net/devlink/port.c
index 939081a0e615..8009c94e06e5 100644
--- a/net/devlink/port.c
+++ b/net/devlink/port.c
@@ -148,6 +148,21 @@ static int devlink_port_fn_ipsec_packet_fill(struct devlink_port *devlink_port,
return 0;
}
+static int devlink_port_bridge_offload_fill(struct devlink_port *devlink_port,
+ struct nla_bitfield32 *caps)
+{
+ bool is_enable;
+
+ if (!devlink_port->ops->port_fn_bridge_offload_get ||
+ devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_PHYSICAL)
+ return 0;
+
+ devlink_port->ops->port_fn_bridge_offload_get(devlink_port, &is_enable);
+
+ devlink_port_fn_cap_fill(caps, DEVLINK_PORT_FN_CAP_BRIDGE_OFFLOAD, is_enable);
+ return 0;
+}
+
static int devlink_port_fn_caps_fill(struct devlink_port *devlink_port,
struct sk_buff *msg,
struct netlink_ext_ack *extack,
@@ -172,6 +187,10 @@ static int devlink_port_fn_caps_fill(struct devlink_port *devlink_port,
if (err)
return err;
+ err = devlink_port_bridge_offload_fill(devlink_port, &caps);
+ if (err)
+ return err;
+
if (!caps.selector)
return 0;
err = nla_put_bitfield32(msg, DEVLINK_PORT_FN_ATTR_CAPS, caps.value,
@@ -393,6 +412,12 @@ devlink_port_fn_ipsec_packet_set(struct devlink_port *devlink_port, bool enable,
return devlink_port->ops->port_fn_ipsec_packet_set(devlink_port, enable, extack);
}
+static void
+devlink_port_fn_bridge_offload_set(struct devlink_port *devlink_port, bool enable)
+{
+ return devlink_port->ops->port_fn_bridge_offload_set(devlink_port, enable);
+}
+
static int devlink_port_fn_caps_set(struct devlink_port *devlink_port,
const struct nlattr *attr,
struct netlink_ext_ack *extack)
@@ -431,6 +456,10 @@ static int devlink_port_fn_caps_set(struct devlink_port *devlink_port,
if (err)
return err;
}
+ if (caps.selector & DEVLINK_PORT_FN_CAP_BRIDGE_OFFLOAD) {
+ devlink_port_fn_bridge_offload_set(devlink_port, caps_value &
+ DEVLINK_PORT_FN_CAP_BRIDGE_OFFLOAD);
+ }
return 0;
}
@@ -765,6 +794,18 @@ static int devlink_port_function_validate(struct devlink_port *devlink_port,
return -EOPNOTSUPP;
}
}
+ if (caps.selector & DEVLINK_PORT_FN_CAP_BRIDGE_OFFLOAD) {
+ if (!ops->port_fn_bridge_offload_set) {
+ NL_SET_ERR_MSG_ATTR(extack, attr,
+ "Port doesn't support bridge offload function attribute");
+ return -EOPNOTSUPP;
+ }
+ if (devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_PHYSICAL) {
+ NL_SET_ERR_MSG_ATTR(extack, attr,
+ "bridge offload function attribute supported for physical ports only");
+ return -EOPNOTSUPP;
+ }
+ }
}
if (tb[DEVLINK_PORT_FN_ATTR_MAX_IO_EQS] &&
!ops->port_fn_max_io_eqs_set) {
--
2.47.1
Powered by blists - more mailing lists