Hi all,
This patch series converts SWITCHDEV_PORT_ATTR_{GET,SET} to use a
blocking notifier, similar to how SWITCHDEV_PORT_OBJ_{ADD,DEL} has been
changed recently by Petr.
This was suggested by Ido to help with a particular use case I have
where I want to be able to veto a switchdev bridge attribute from a
driver (multicast_snooping).
Please review since I may not have gotten the driver abstraction right,
especially for mlx5e and nfp since these are *hum* *hum* large drivers.
Florian Fainelli (13):
switchdev: Add SWITCHDEV_PORT_ATTR_SET, SWITCHDEV_PORT_ATTR_GET
rocker: Handle SWITCHDEV_PORT_ATTR_GET/SET
net: dsa: Handle SWITCHDEV_PORT_ATTR_GET/SET
mlxsw: spectrum_switchdev: Handle SWITCHDEV_PORT_ATTR_GET/SET
net: mscc: ocelot: Handle SWITCHDEV_PORT_ATTR_GET/SET
staging: fsl-dpaa2: ethsw: Handle SWITCHDEV_PORT_ATTR_GET/SET
bnxt: Handle SWITCHDEV_PORT_ATTR_GET event
liquidio: Handle SWITCHDEV_PORT_ATTR_GET event
mlxsw: switchx2: Handle SWITCHDEV_PORT_ATTR_GET event
net/mlx5e: Handle SWITCHDEV_PORT_ATTR_GET event
nfp: Handle SWITCHDEV_PORT_ATTR_GET event
netdevsim: Handle SWITCHDEV_PORT_ATTR_GET event
net: switchdev: Replace port attr get/set SDO with a notification
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 63 ++++++++++-
drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c | 9 +-
drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.h | 8 ++
.../net/ethernet/cavium/liquidio/lio_main.c | 53 ++++++++-
.../net/ethernet/cavium/liquidio/lio_vf_rep.c | 48 +++++++-
.../net/ethernet/mellanox/mlx5/core/en_main.c | 4 +-
.../net/ethernet/mellanox/mlx5/core/en_rep.c | 50 ++++++--
.../net/ethernet/mellanox/mlx5/core/en_rep.h | 2 +-
.../net/ethernet/mellanox/mlxsw/spectrum.c | 12 --
.../net/ethernet/mellanox/mlxsw/spectrum.h | 2 -
.../mellanox/mlxsw/spectrum_switchdev.c | 36 +++---
.../net/ethernet/mellanox/mlxsw/switchx2.c | 46 +++++++-
drivers/net/ethernet/mscc/ocelot.c | 30 ++++-
drivers/net/ethernet/netronome/nfp/nfp_main.c | 14 ++-
drivers/net/ethernet/netronome/nfp/nfp_net.h | 3 +
.../ethernet/netronome/nfp/nfp_net_common.c | 19 +++-
.../net/ethernet/netronome/nfp/nfp_net_repr.c | 2 -
drivers/net/ethernet/netronome/nfp/nfp_port.c | 17 ++-
drivers/net/ethernet/netronome/nfp/nfp_port.h | 5 +-
drivers/net/ethernet/rocker/rocker_main.c | 30 ++++-
drivers/net/netdevsim/netdev.c | 46 +++++++-
drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 30 ++++-
include/linux/netdevice.h | 3 -
include/net/switchdev.h | 28 ++---
net/dsa/slave.c | 30 ++++-
net/switchdev/switchdev.c | 107 ++++++------------
26 files changed, 503 insertions(+), 194 deletions(-)
--
2.17.1
In preparation for allowing switchdev enabled drivers to veto specific
attribute settings from within the context of the caller, introduce a
new switchdev notifier type for port attributes.
Suggested-by: Ido Schimmel <[email protected]>
Signed-off-by: Florian Fainelli <[email protected]>
---
include/net/switchdev.h | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index 63843ae5dc81..e62fb2693e00 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -145,6 +145,9 @@ enum switchdev_notifier_type {
SWITCHDEV_VXLAN_FDB_ADD_TO_DEVICE,
SWITCHDEV_VXLAN_FDB_DEL_TO_DEVICE,
SWITCHDEV_VXLAN_FDB_OFFLOADED,
+
+ SWITCHDEV_PORT_ATTR_SET, /* Blocking. */
+ SWITCHDEV_PORT_ATTR_GET, /* Blocking. */
};
struct switchdev_notifier_info {
@@ -167,6 +170,13 @@ struct switchdev_notifier_port_obj_info {
bool handled;
};
+struct switchdev_notifier_port_attr_info {
+ struct switchdev_notifier_info info; /* must be first */
+ struct switchdev_attr *attr;
+ struct switchdev_trans *trans;
+ bool handled;
+};
+
static inline struct net_device *
switchdev_notifier_info_to_dev(const struct switchdev_notifier_info *info)
{
--
2.17.1
Following patches will change the way we communicate getting or setting
a port's attribute and use a blocking notifier to perform those tasks.
Prepare bnxt to support receiving notifier events targeting
SWITCHDEV_PORT_ATTR_GET and simply translate that into the existing
switchdev_ops::switchdev_port_attr_get operation.
We register a single blocking switchdev notifier for the entire driver
instance and we differentiate a PF from a VF by comparing the network
device's netdev_ops with the ones that this driver manages.
Signed-off-by: Florian Fainelli <[email protected]>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 58 ++++++++++++++++++-
drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c | 4 +-
drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.h | 8 +++
3 files changed, 67 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 6a512871176b..c3178ca4a004 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -10045,6 +10045,45 @@ static const struct net_device_ops bnxt_netdev_ops = {
.ndo_get_phys_port_name = bnxt_get_phys_port_name
};
+static int bnxt_swdev_port_attr_event(unsigned long event,
+ struct net_device *dev,
+ struct switchdev_notifier_port_attr_info *port_attr_info)
+{
+ int rc;
+
+ if (event != SWITCHDEV_PORT_ATTR_GET)
+ return NOTIFY_DONE;
+
+ if (bnxt_dev_is_vf_rep(dev))
+ rc = bnxt_vf_rep_port_attr_get(dev, port_attr_info->attr);
+ else
+ rc = bnxt_port_attr_get(netdev_priv(dev), port_attr_info->attr);
+
+ port_attr_info->handled = true;
+ return notifier_from_errno(rc);
+}
+
+static int bnxt_switchdev_blocking_event(struct notifier_block *nb,
+ unsigned long event, void *ptr)
+{
+ struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
+
+ if (dev->netdev_ops != &bnxt_netdev_ops &&
+ !bnxt_dev_is_vf_rep(dev))
+ return NOTIFY_DONE;
+
+ switch (event) {
+ case SWITCHDEV_PORT_ATTR_GET:
+ return bnxt_swdev_port_attr_event(event, dev, ptr);
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block bnxt_swdev_blocking_nb = {
+ .notifier_call = bnxt_switchdev_blocking_event,
+};
+
static void bnxt_remove_one(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
@@ -10817,8 +10856,24 @@ static struct pci_driver bnxt_pci_driver = {
static int __init bnxt_init(void)
{
+ int rc;
+
bnxt_debug_init();
- return pci_register_driver(&bnxt_pci_driver);
+ rc = register_switchdev_blocking_notifier(&bnxt_swdev_blocking_nb);
+ if (rc)
+ goto err_debug;
+
+ rc = pci_register_driver(&bnxt_pci_driver);
+ if (rc)
+ goto err_unreg_notifier;
+
+ return rc;
+
+err_unreg_notifier:
+ unregister_switchdev_notifier(&bnxt_swdev_blocking_nb);
+err_debug:
+ bnxt_debug_exit();
+ return rc;
}
static void __exit bnxt_exit(void)
@@ -10826,6 +10881,7 @@ static void __exit bnxt_exit(void)
pci_unregister_driver(&bnxt_pci_driver);
if (bnxt_pf_wq)
destroy_workqueue(bnxt_pf_wq);
+ unregister_switchdev_notifier(&bnxt_swdev_blocking_nb);
bnxt_debug_exit();
}
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
index 9a25c05aa571..a06f93b49dd5 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
@@ -237,8 +237,8 @@ static void bnxt_vf_rep_get_drvinfo(struct net_device *dev,
strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version));
}
-static int bnxt_vf_rep_port_attr_get(struct net_device *dev,
- struct switchdev_attr *attr)
+int bnxt_vf_rep_port_attr_get(struct net_device *dev,
+ struct switchdev_attr *attr)
{
struct bnxt_vf_rep *vf_rep = netdev_priv(dev);
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.h
index d7287651422f..ba24ac222182 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.h
@@ -32,6 +32,8 @@ bool bnxt_dev_is_vf_rep(struct net_device *dev);
int bnxt_dl_eswitch_mode_get(struct devlink *devlink, u16 *mode);
int bnxt_dl_eswitch_mode_set(struct devlink *devlink, u16 mode,
struct netlink_ext_ack *extack);
+int bnxt_vf_rep_port_attr_get(struct net_device *dev,
+ struct switchdev_attr *attr);
#else
@@ -61,5 +63,11 @@ static inline bool bnxt_dev_is_vf_rep(struct net_device *dev)
{
return false;
}
+
+static inline int bnxt_vf_rep_port_attr_get(struct net_device *dev,
+ struct switchdev_attr *attr)
+{
+ return -EOPNOTSUPP;
+}
#endif /* CONFIG_BNXT_SRIOV */
#endif /* BNXT_VFR_H */
--
2.17.1
Following patches will change the way we communicate getting or setting
a port's attribute and use a blocking notifier to perform those tasks.
Prepare bnxt to support receiving notifier events targeting
SWITCHDEV_PORT_ATTR_GET and simply translate that into the existing
switchdev_ops::switchdev_port_attr_get operation.
We register a single blocking switchdev notifier for the entire driver
instance and check that thet network device maps to the one that
switchx2 manages.
Signed-off-by: Florian Fainelli <[email protected]>
---
.../net/ethernet/mellanox/mlxsw/switchx2.c | 43 ++++++++++++++++++-
1 file changed, 42 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
index 2d4f213e154d..82fb8f1bb6e9 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
@@ -923,6 +923,36 @@ static const struct switchdev_ops mlxsw_sx_port_switchdev_ops = {
.switchdev_port_attr_get = mlxsw_sx_port_attr_get,
};
+static int mlxsw_sx_port_attr_event(unsigned long event,
+ struct net_device *dev,
+ struct switchdev_notifier_port_attr_info *port_attr_info)
+{
+ int rc;
+
+ if (event != SWITCHDEV_PORT_ATTR_GET)
+ return NOTIFY_DONE;
+
+ rc = mlxsw_sx_port_attr_get(dev, port_attr_info->attr);
+ port_attr_info->handled = true;
+ return notifier_from_errno(rc);
+}
+
+static int mlxsw_sx_swdev_blocking_event(struct notifier_block *nb,
+ unsigned long event, void *ptr)
+{
+ struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
+
+ if (dev->netdev_ops != &mlxsw_sx_port_netdev_ops)
+ return NOTIFY_DONE;
+
+ switch (event) {
+ case SWITCHDEV_PORT_ATTR_GET:
+ return mlxsw_sx_port_attr_event(event, dev, ptr);
+ }
+
+ return NOTIFY_DONE;
+}
+
static int mlxsw_sx_hw_id_get(struct mlxsw_sx *mlxsw_sx)
{
char spad_pl[MLXSW_REG_SPAD_LEN] = {0};
@@ -1638,6 +1668,10 @@ static void mlxsw_sx_fini(struct mlxsw_core *mlxsw_core)
mlxsw_sx_ports_remove(mlxsw_sx);
}
+static struct notifier_block mlxsw_sx_swdev_nb = {
+ .notifier_call = mlxsw_sx_swdev_blocking_event,
+};
+
static const struct mlxsw_config_profile mlxsw_sx_config_profile = {
.used_max_vepa_channels = 1,
.max_vepa_channels = 0,
@@ -1698,10 +1732,14 @@ static int __init mlxsw_sx_module_init(void)
{
int err;
- err = mlxsw_core_driver_register(&mlxsw_sx_driver);
+ err = register_switchdev_blocking_notifier(&mlxsw_sx_swdev_nb);
if (err)
return err;
+ err = mlxsw_core_driver_register(&mlxsw_sx_driver);
+ if (err)
+ goto err_unregister_notifier;
+
err = mlxsw_pci_driver_register(&mlxsw_sx_pci_driver);
if (err)
goto err_pci_driver_register;
@@ -1710,6 +1748,8 @@ static int __init mlxsw_sx_module_init(void)
err_pci_driver_register:
mlxsw_core_driver_unregister(&mlxsw_sx_driver);
+err_unregister_notifier:
+ unregister_switchdev_blocking_notifier(&mlxsw_sx_swdev_nb);
return err;
}
@@ -1717,6 +1757,7 @@ static void __exit mlxsw_sx_module_exit(void)
{
mlxsw_pci_driver_unregister(&mlxsw_sx_pci_driver);
mlxsw_core_driver_unregister(&mlxsw_sx_driver);
+ unregister_switchdev_blocking_notifier(&mlxsw_sx_swdev_nb);
}
module_init(mlxsw_sx_module_init);
--
2.17.1
Following patches will change the way we communicate getting or setting
a port's attribute and use a blocking notifier to perform those tasks.
Prepare nfp to support receiving notifier events targeting
SWITCHDEV_PORT_ATTR_GET and simply translate that into the existing
switchdev_ops::switchdev_port_attr_get operation.
We register a single blocking switchdev notifier for the entire driver
instance and we differentiate a "net" from a "repr" by comparing the
network device's netdev_ops with the ones that this driver manages.
Signed-off-by: Florian Fainelli <[email protected]>
---
drivers/net/ethernet/netronome/nfp/nfp_main.c | 14 +++++++++++++-
drivers/net/ethernet/netronome/nfp/nfp_net.h | 3 +++
.../net/ethernet/netronome/nfp/nfp_net_common.c | 17 +++++++++++++++++
drivers/net/ethernet/netronome/nfp/nfp_port.c | 15 +++++++++++++++
drivers/net/ethernet/netronome/nfp/nfp_port.h | 5 ++++-
5 files changed, 52 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.c b/drivers/net/ethernet/netronome/nfp/nfp_main.c
index 6c10e8d119e4..50c111280cd4 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_main.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_main.c
@@ -17,6 +17,7 @@
#include <linux/vermagic.h>
#include <linux/vmalloc.h>
#include <net/devlink.h>
+#include <net/switchdev.h>
#include "nfpcore/nfp.h"
#include "nfpcore/nfp_cpp.h"
@@ -708,6 +709,10 @@ static void nfp_pci_remove(struct pci_dev *pdev)
pci_disable_device(pdev);
}
+static struct notifier_block nfp_swdev_blocking_nb = {
+ .notifier_call = nfp_switchdev_blocking_event,
+};
+
static struct pci_driver nfp_pci_driver = {
.name = nfp_driver_name,
.id_table = nfp_pci_device_ids,
@@ -725,9 +730,13 @@ static int __init nfp_main_init(void)
nfp_net_debugfs_create();
+ err = register_switchdev_blocking_notifier(&nfp_swdev_blocking_nb);
+ if (err)
+ goto err_destroy_debugfs;
+
err = pci_register_driver(&nfp_pci_driver);
if (err < 0)
- goto err_destroy_debugfs;
+ goto err_unreg_notifier;
err = pci_register_driver(&nfp_netvf_pci_driver);
if (err)
@@ -737,6 +746,8 @@ static int __init nfp_main_init(void)
err_unreg_pf:
pci_unregister_driver(&nfp_pci_driver);
+err_unreg_notifier:
+ unregister_switchdev_blocking_notifier(&nfp_swdev_blocking_nb);
err_destroy_debugfs:
nfp_net_debugfs_destroy();
return err;
@@ -746,6 +757,7 @@ static void __exit nfp_main_exit(void)
{
pci_unregister_driver(&nfp_netvf_pci_driver);
pci_unregister_driver(&nfp_pci_driver);
+ unregister_switchdev_blocking_notifier(&nfp_swdev_blocking_nb);
nfp_net_debugfs_destroy();
}
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net.h b/drivers/net/ethernet/netronome/nfp/nfp_net.h
index be37c2d6151c..57f7d6d634ea 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net.h
@@ -915,4 +915,7 @@ static inline void nfp_net_debugfs_dir_clean(struct dentry **dir)
}
#endif /* CONFIG_NFP_DEBUG */
+int nfp_switchdev_blocking_event(struct notifier_block *nb,
+ unsigned long event, void *ptr);
+
#endif /* _NFP_NET_H_ */
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index 7d2d4241498f..c2c5e7e3aab0 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -3955,3 +3955,20 @@ void nfp_net_clean(struct nfp_net *nn)
unregister_netdev(nn->dp.netdev);
nfp_net_reconfig_wait_posted(nn);
}
+
+int nfp_switchdev_blocking_event(struct notifier_block *nb,
+ unsigned long event, void *ptr)
+{
+ struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
+
+ if (!nfp_netdev_is_nfp_repr(dev) &&
+ !nfp_netdev_is_nfp_net(dev))
+ return NOTIFY_DONE;
+
+ switch (event) {
+ case SWITCHDEV_PORT_ATTR_GET:
+ return nfp_port_switchdev_attr_event(event, dev, ptr);
+ }
+
+ return NOTIFY_DONE;
+}
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_port.c b/drivers/net/ethernet/netronome/nfp/nfp_port.c
index 86bc149ca231..578477242ae9 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_port.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_port.c
@@ -59,6 +59,21 @@ const struct switchdev_ops nfp_port_switchdev_ops = {
.switchdev_port_attr_get = nfp_port_attr_get,
};
+int nfp_port_switchdev_attr_event(unsigned long event,
+ struct net_device *netdev,
+ struct switchdev_notifier_port_attr_info *port_attr_info)
+{
+ int rc;
+
+ if (event != SWITCHDEV_PORT_ATTR_GET)
+ return NOTIFY_DONE;
+
+ rc = nfp_port_attr_get(netdev, port_attr_info->attr);
+ port_attr_info->handled = true;
+
+ return notifier_from_errno(rc);
+}
+
int nfp_port_setup_tc(struct net_device *netdev, enum tc_setup_type type,
void *type_data)
{
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_port.h b/drivers/net/ethernet/netronome/nfp/nfp_port.h
index b2479a2a49e5..35342f88f715 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_port.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_port.h
@@ -10,6 +10,7 @@ struct net_device;
struct nfp_app;
struct nfp_pf;
struct nfp_port;
+struct switchdev_notifier_port_attr_info;
/**
* enum nfp_port_type - type of port NFP can switch traffic to
@@ -90,7 +91,9 @@ struct nfp_port {
};
extern const struct ethtool_ops nfp_port_ethtool_ops;
-extern const struct switchdev_ops nfp_port_switchdev_ops;
+
+int nfp_port_switchdev_attr_event(unsigned long event, struct net_device *dev,
+ struct switchdev_notifier_port_attr_info *port_attr_info);
__printf(2, 3) u8 *nfp_pr_et(u8 *data, const char *fmt, ...);
--
2.17.1
Drop switchdev_ops.switchdev_port_attr_get and _set. Drop the uses of
this field from all clients, which were migrated to use switchdev
notification in the previous patches.
Add a new function switchdev_port_attr_notify() that sends the switchdev
notifications SWITCHDEV_PORT_ATTR_GET and _SET.
Update switchdev_port_attr_get() to dispatch to this new function. Drop
__switchdev_port_attr_set() and update switchdev_port_attr_set()
likewise.
Signed-off-by: Florian Fainelli <[email protected]>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 5 -
drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c | 5 -
.../net/ethernet/cavium/liquidio/lio_main.c | 5 -
.../net/ethernet/cavium/liquidio/lio_vf_rep.c | 5 -
.../net/ethernet/mellanox/mlx5/core/en_rep.c | 7 --
.../net/ethernet/mellanox/mlxsw/spectrum.c | 12 --
.../net/ethernet/mellanox/mlxsw/spectrum.h | 2 -
.../mellanox/mlxsw/spectrum_switchdev.c | 13 ---
.../net/ethernet/mellanox/mlxsw/switchx2.c | 5 -
drivers/net/ethernet/mscc/ocelot.c | 6 -
.../ethernet/netronome/nfp/nfp_net_common.c | 2 -
.../net/ethernet/netronome/nfp/nfp_net_repr.c | 2 -
drivers/net/ethernet/netronome/nfp/nfp_port.c | 4 -
drivers/net/ethernet/rocker/rocker_main.c | 6 -
drivers/net/netdevsim/netdev.c | 5 -
drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 6 -
include/linux/netdevice.h | 3 -
include/net/switchdev.h | 18 ---
net/dsa/slave.c | 6 -
net/switchdev/switchdev.c | 107 ++++++------------
20 files changed, 37 insertions(+), 187 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index c3178ca4a004..78d2d76de1a7 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -10007,10 +10007,6 @@ static int bnxt_swdev_port_attr_get(struct net_device *dev,
return bnxt_port_attr_get(netdev_priv(dev), attr);
}
-static const struct switchdev_ops bnxt_switchdev_ops = {
- .switchdev_port_attr_get = bnxt_swdev_port_attr_get
-};
-
static const struct net_device_ops bnxt_netdev_ops = {
.ndo_open = bnxt_open,
.ndo_start_xmit = bnxt_start_xmit,
@@ -10439,7 +10435,6 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->netdev_ops = &bnxt_netdev_ops;
dev->watchdog_timeo = BNXT_TX_TIMEOUT;
dev->ethtool_ops = &bnxt_ethtool_ops;
- SWITCHDEV_SET_OPS(dev, &bnxt_switchdev_ops);
pci_set_drvdata(pdev, dev);
rc = bnxt_alloc_hwrm_resources(bp);
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
index a06f93b49dd5..13db3bf4271f 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
@@ -248,10 +248,6 @@ int bnxt_vf_rep_port_attr_get(struct net_device *dev,
return bnxt_port_attr_get(vf_rep->bp, attr);
}
-static const struct switchdev_ops bnxt_vf_rep_switchdev_ops = {
- .switchdev_port_attr_get = bnxt_vf_rep_port_attr_get
-};
-
static const struct ethtool_ops bnxt_vf_rep_ethtool_ops = {
.get_drvinfo = bnxt_vf_rep_get_drvinfo
};
@@ -392,7 +388,6 @@ static void bnxt_vf_rep_netdev_init(struct bnxt *bp, struct bnxt_vf_rep *vf_rep,
dev->netdev_ops = &bnxt_vf_rep_netdev_ops;
dev->ethtool_ops = &bnxt_vf_rep_ethtool_ops;
- SWITCHDEV_SET_OPS(dev, &bnxt_vf_rep_switchdev_ops);
/* Just inherit all the featues of the parent PF as the VF-R
* uses the RX/TX rings of the parent PF
*/
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c
index b9d48e4181fc..19ebf2a3aa49 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
@@ -3222,10 +3222,6 @@ lio_pf_switchdev_attr_get(struct net_device *dev, struct switchdev_attr *attr)
return 0;
}
-static const struct switchdev_ops lio_pf_switchdev_ops = {
- .switchdev_port_attr_get = lio_pf_switchdev_attr_get,
-};
-
static int liquidio_get_vf_stats(struct net_device *netdev, int vfidx,
struct ifla_vf_stats *vf_stats)
{
@@ -3580,7 +3576,6 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
* netdev tasks.
*/
netdev->netdev_ops = &lionetdevops;
- SWITCHDEV_SET_OPS(netdev, &lio_pf_switchdev_ops);
retval = netif_set_real_num_rx_queues(netdev, num_oqueues);
if (retval) {
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c b/drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c
index d396c004c1be..0aa64ffae8b6 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c
@@ -464,10 +464,6 @@ lio_vf_rep_attr_get(struct net_device *dev, struct switchdev_attr *attr)
return 0;
}
-static const struct switchdev_ops lio_vf_rep_switchdev_ops = {
- .switchdev_port_attr_get = lio_vf_rep_attr_get,
-};
-
static int lio_vf_rep_swdev_port_attr_event(unsigned long event,
struct net_device *dev,
struct switchdev_notifier_port_attr_info *port_attr_info)
@@ -539,7 +535,6 @@ lio_vf_rep_create(struct octeon_device *oct)
ndev->min_mtu = LIO_MIN_MTU_SIZE;
ndev->max_mtu = LIO_MAX_MTU_SIZE;
ndev->netdev_ops = &lio_vf_rep_ndev_ops;
- SWITCHDEV_SET_OPS(ndev, &lio_vf_rep_switchdev_ops);
vf_rep = netdev_priv(ndev);
memset(vf_rep, 0, sizeof(*vf_rep));
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
index 9bac78e111c6..1925ab62631c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
@@ -1285,10 +1285,6 @@ static int mlx5e_uplink_rep_set_mac(struct net_device *netdev, void *addr)
return 0;
}
-static const struct switchdev_ops mlx5e_rep_switchdev_ops = {
- .switchdev_port_attr_get = mlx5e_attr_get,
-};
-
static int mlx5e_rep_swdev_port_attr_event(unsigned long event,
struct net_device *dev,
struct switchdev_notifier_port_attr_info *port_attr_info)
@@ -1423,9 +1419,6 @@ static void mlx5e_build_rep_netdev(struct net_device *netdev)
netdev->watchdog_timeo = 15 * HZ;
-
- netdev->switchdev_ops = &mlx5e_rep_switchdev_ops;
-
netdev->features |= NETIF_F_HW_TC | NETIF_F_NETNS_LOCAL;
netdev->hw_features |= NETIF_F_HW_TC;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index a88169738b4a..e87a5e634fc1 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -3207,7 +3207,6 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
}
mlxsw_sp_port->default_vlan = mlxsw_sp_port_vlan;
- mlxsw_sp_port_switchdev_init(mlxsw_sp_port);
mlxsw_sp->ports[local_port] = mlxsw_sp_port;
err = register_netdev(dev);
if (err) {
@@ -3224,7 +3223,6 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
err_register_netdev:
mlxsw_sp->ports[local_port] = NULL;
- mlxsw_sp_port_switchdev_fini(mlxsw_sp_port);
mlxsw_sp_port_vlan_destroy(mlxsw_sp_port_vlan);
err_port_vlan_create:
err_port_pvid_set:
@@ -3267,7 +3265,6 @@ static void mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u8 local_port)
mlxsw_core_port_clear(mlxsw_sp->core, local_port, mlxsw_sp);
unregister_netdev(mlxsw_sp_port->dev); /* This calls ndo_stop */
mlxsw_sp->ports[local_port] = NULL;
- mlxsw_sp_port_switchdev_fini(mlxsw_sp_port);
mlxsw_sp_port_vlan_flush(mlxsw_sp_port, true);
mlxsw_sp_port_nve_fini(mlxsw_sp_port);
mlxsw_sp_tc_qdisc_fini(mlxsw_sp_port);
@@ -3988,12 +3985,6 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
goto err_span_init;
}
- err = mlxsw_sp_switchdev_init(mlxsw_sp);
- if (err) {
- dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize switchdev\n");
- goto err_switchdev_init;
- }
-
err = mlxsw_sp_counter_pool_init(mlxsw_sp);
if (err) {
dev_err(mlxsw_sp->bus_info->dev, "Failed to init counter pool\n");
@@ -4064,8 +4055,6 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
err_afa_init:
mlxsw_sp_counter_pool_fini(mlxsw_sp);
err_counter_pool_init:
- mlxsw_sp_switchdev_fini(mlxsw_sp);
-err_switchdev_init:
mlxsw_sp_span_fini(mlxsw_sp);
err_span_init:
mlxsw_sp_lag_fini(mlxsw_sp);
@@ -4128,7 +4117,6 @@ static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core)
mlxsw_sp_nve_fini(mlxsw_sp);
mlxsw_sp_afa_fini(mlxsw_sp);
mlxsw_sp_counter_pool_fini(mlxsw_sp);
- mlxsw_sp_switchdev_fini(mlxsw_sp);
mlxsw_sp_span_fini(mlxsw_sp);
mlxsw_sp_lag_fini(mlxsw_sp);
mlxsw_sp_buffers_fini(mlxsw_sp);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
index 1fa5c81b209f..f81914203098 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
@@ -375,8 +375,6 @@ u32 mlxsw_sp_bytes_cells(const struct mlxsw_sp *mlxsw_sp, u32 bytes);
/* spectrum_switchdev.c */
int mlxsw_sp_switchdev_init(struct mlxsw_sp *mlxsw_sp);
void mlxsw_sp_switchdev_fini(struct mlxsw_sp *mlxsw_sp);
-void mlxsw_sp_port_switchdev_init(struct mlxsw_sp_port *mlxsw_sp_port);
-void mlxsw_sp_port_switchdev_fini(struct mlxsw_sp_port *mlxsw_sp_port);
int mlxsw_sp_rif_fdb_op(struct mlxsw_sp *mlxsw_sp, const char *mac, u16 fid,
bool adding);
void
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index 7c0df736587c..19f647c4c4df 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -1962,11 +1962,6 @@ static struct mlxsw_sp_port *mlxsw_sp_lag_rep_port(struct mlxsw_sp *mlxsw_sp,
return NULL;
}
-static const struct switchdev_ops mlxsw_sp_port_switchdev_ops = {
- .switchdev_port_attr_get = mlxsw_sp_port_attr_get,
- .switchdev_port_attr_set = mlxsw_sp_port_attr_set,
-};
-
static int
mlxsw_sp_bridge_8021q_port_join(struct mlxsw_sp_bridge_device *bridge_device,
struct mlxsw_sp_bridge_port *bridge_port,
@@ -3575,11 +3570,3 @@ void mlxsw_sp_switchdev_fini(struct mlxsw_sp *mlxsw_sp)
kfree(mlxsw_sp->bridge);
}
-void mlxsw_sp_port_switchdev_init(struct mlxsw_sp_port *mlxsw_sp_port)
-{
- mlxsw_sp_port->dev->switchdev_ops = &mlxsw_sp_port_switchdev_ops;
-}
-
-void mlxsw_sp_port_switchdev_fini(struct mlxsw_sp_port *mlxsw_sp_port)
-{
-}
diff --git a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
index 82fb8f1bb6e9..1f1aca664b73 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
@@ -919,10 +919,6 @@ static int mlxsw_sx_port_attr_get(struct net_device *dev,
return 0;
}
-static const struct switchdev_ops mlxsw_sx_port_switchdev_ops = {
- .switchdev_port_attr_get = mlxsw_sx_port_attr_get,
-};
-
static int mlxsw_sx_port_attr_event(unsigned long event,
struct net_device *dev,
struct switchdev_notifier_port_attr_info *port_attr_info)
@@ -1064,7 +1060,6 @@ static int __mlxsw_sx_port_eth_create(struct mlxsw_sx *mlxsw_sx, u8 local_port,
dev->netdev_ops = &mlxsw_sx_port_netdev_ops;
dev->ethtool_ops = &mlxsw_sx_port_ethtool_ops;
- dev->switchdev_ops = &mlxsw_sx_port_switchdev_ops;
err = mlxsw_sx_port_dev_addr_get(mlxsw_sx_port);
if (err) {
diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
index 8043347a1ed4..1b7833ee8cc6 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -1330,11 +1330,6 @@ static int ocelot_port_obj_del(struct net_device *dev,
return ret;
}
-static const struct switchdev_ops ocelot_port_switchdev_ops = {
- .switchdev_port_attr_get = ocelot_port_attr_get,
- .switchdev_port_attr_set = ocelot_port_attr_set,
-};
-
static int ocelot_port_bridge_join(struct ocelot_port *ocelot_port,
struct net_device *bridge)
{
@@ -1664,7 +1659,6 @@ int ocelot_probe_port(struct ocelot *ocelot, u8 port,
dev->netdev_ops = &ocelot_port_netdev_ops;
dev->ethtool_ops = &ocelot_ethtool_ops;
- dev->switchdev_ops = &ocelot_port_switchdev_ops;
dev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_RXFCS;
dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index c2c5e7e3aab0..46f0f29e31cd 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -3815,8 +3815,6 @@ static void nfp_net_netdev_init(struct nfp_net *nn)
netdev->netdev_ops = &nfp_net_netdev_ops;
netdev->watchdog_timeo = msecs_to_jiffies(5 * 1000);
- SWITCHDEV_SET_OPS(netdev, &nfp_port_switchdev_ops);
-
/* MTU range: 68 - hw-specific max */
netdev->min_mtu = ETH_MIN_MTU;
netdev->max_mtu = nn->max_mtu;
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
index 69d7aebda09b..eb6e95cc460e 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
@@ -336,8 +336,6 @@ int nfp_repr_init(struct nfp_app *app, struct net_device *netdev,
netdev->max_mtu = pf_netdev->max_mtu;
- SWITCHDEV_SET_OPS(netdev, &nfp_port_switchdev_ops);
-
/* Set features the lower device can support with representors */
if (repr_cap & NFP_NET_CFG_CTRL_LIVE_ADDR)
netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_port.c b/drivers/net/ethernet/netronome/nfp/nfp_port.c
index 578477242ae9..77781fc2eaa6 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_port.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_port.c
@@ -55,10 +55,6 @@ nfp_port_attr_get(struct net_device *netdev, struct switchdev_attr *attr)
return 0;
}
-const struct switchdev_ops nfp_port_switchdev_ops = {
- .switchdev_port_attr_get = nfp_port_attr_get,
-};
-
int nfp_port_switchdev_attr_event(unsigned long event,
struct net_device *netdev,
struct switchdev_notifier_port_attr_info *port_attr_info)
diff --git a/drivers/net/ethernet/rocker/rocker_main.c b/drivers/net/ethernet/rocker/rocker_main.c
index f25f7b4345b8..52082c7690ea 100644
--- a/drivers/net/ethernet/rocker/rocker_main.c
+++ b/drivers/net/ethernet/rocker/rocker_main.c
@@ -2139,11 +2139,6 @@ static int rocker_port_obj_del(struct net_device *dev,
return err;
}
-static const struct switchdev_ops rocker_port_switchdev_ops = {
- .switchdev_port_attr_get = rocker_port_attr_get,
- .switchdev_port_attr_set = rocker_port_attr_set,
-};
-
struct rocker_fib_event_work {
struct work_struct work;
union {
@@ -2597,7 +2592,6 @@ static int rocker_probe_port(struct rocker *rocker, unsigned int port_number)
rocker_port_dev_addr_init(rocker_port);
dev->netdev_ops = &rocker_port_netdev_ops;
dev->ethtool_ops = &rocker_port_ethtool_ops;
- dev->switchdev_ops = &rocker_port_switchdev_ops;
netif_tx_napi_add(dev, &rocker_port->napi_tx, rocker_port_poll_tx,
NAPI_POLL_WEIGHT);
netif_napi_add(dev, &rocker_port->napi_rx, rocker_port_poll_rx,
diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c
index 817d94cec90f..b0dca4f99018 100644
--- a/drivers/net/netdevsim/netdev.c
+++ b/drivers/net/netdevsim/netdev.c
@@ -164,10 +164,6 @@ nsim_port_attr_get(struct net_device *dev, struct switchdev_attr *attr)
}
}
-static const struct switchdev_ops nsim_switchdev_ops = {
- .switchdev_port_attr_get = nsim_port_attr_get,
-};
-
static int nsim_switchdev_port_attr_event(unsigned long event,
struct net_device *dev,
struct switchdev_notifier_port_attr_info *port_attr_info)
@@ -228,7 +224,6 @@ static int nsim_init(struct net_device *dev)
goto err_bpf_uninit;
SET_NETDEV_DEV(dev, &ns->dev);
- SWITCHDEV_SET_OPS(dev, &nsim_switchdev_ops);
err = nsim_devlink_setup(ns);
if (err)
diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
index b18e112d84e6..4d0eb2ed062d 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
@@ -924,11 +924,6 @@ static int swdev_port_obj_del(struct net_device *netdev,
return err;
}
-static const struct switchdev_ops ethsw_port_switchdev_ops = {
- .switchdev_port_attr_get = swdev_port_attr_get,
- .switchdev_port_attr_set = swdev_port_attr_set,
-};
-
/* For the moment, only flood setting needs to be updated */
static int port_bridge_join(struct net_device *netdev,
struct net_device *upper_dev)
@@ -1458,7 +1453,6 @@ static int ethsw_probe_port(struct ethsw_core *ethsw, u16 port_idx)
SET_NETDEV_DEV(port_netdev, dev);
port_netdev->netdev_ops = ðsw_port_ops;
port_netdev->ethtool_ops = ðsw_port_ethtool_ops;
- port_netdev->switchdev_ops = ðsw_port_switchdev_ops;
/* Set MTU limits */
port_netdev->min_mtu = ETH_MIN_MTU;
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index a57b9a853aab..1176292f3d62 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1826,9 +1826,6 @@ struct net_device {
#endif
const struct net_device_ops *netdev_ops;
const struct ethtool_ops *ethtool_ops;
-#ifdef CONFIG_NET_SWITCHDEV
- const struct switchdev_ops *switchdev_ops;
-#endif
#ifdef CONFIG_NET_L3_MASTER_DEV
const struct l3mdev_ops *l3mdev_ops;
#endif
diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index e62fb2693e00..61a97f2a8fb0 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -115,21 +115,6 @@ void *switchdev_trans_item_dequeue(struct switchdev_trans *trans);
typedef int switchdev_obj_dump_cb_t(struct switchdev_obj *obj);
-/**
- * struct switchdev_ops - switchdev operations
- *
- * @switchdev_port_attr_get: Get a port attribute (see switchdev_attr).
- *
- * @switchdev_port_attr_set: Set a port attribute (see switchdev_attr).
- */
-struct switchdev_ops {
- int (*switchdev_port_attr_get)(struct net_device *dev,
- struct switchdev_attr *attr);
- int (*switchdev_port_attr_set)(struct net_device *dev,
- const struct switchdev_attr *attr,
- struct switchdev_trans *trans);
-};
-
enum switchdev_notifier_type {
SWITCHDEV_FDB_ADD_TO_BRIDGE = 1,
SWITCHDEV_FDB_DEL_TO_BRIDGE,
@@ -234,7 +219,6 @@ int switchdev_handle_port_obj_del(struct net_device *dev,
int (*del_cb)(struct net_device *dev,
const struct switchdev_obj *obj));
-#define SWITCHDEV_SET_OPS(netdev, ops) ((netdev)->switchdev_ops = (ops))
#else
static inline void switchdev_deferred_process(void)
@@ -333,8 +317,6 @@ switchdev_handle_port_obj_del(struct net_device *dev,
return 0;
}
-#define SWITCHDEV_SET_OPS(netdev, ops) do {} while (0)
-
#endif
#endif /* _LINUX_SWITCHDEV_H_ */
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index bc7d5092a1c7..a11f9678610c 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -1048,11 +1048,6 @@ static const struct net_device_ops dsa_slave_netdev_ops = {
.ndo_get_stats64 = dsa_slave_get_stats64,
};
-static const struct switchdev_ops dsa_slave_switchdev_ops = {
- .switchdev_port_attr_get = dsa_slave_port_attr_get,
- .switchdev_port_attr_set = dsa_slave_port_attr_set,
-};
-
static struct device_type dsa_type = {
.name = "dsa",
};
@@ -1312,7 +1307,6 @@ int dsa_slave_create(struct dsa_port *port)
eth_hw_addr_inherit(slave_dev, master);
slave_dev->priv_flags |= IFF_NO_QUEUE;
slave_dev->netdev_ops = &dsa_slave_netdev_ops;
- slave_dev->switchdev_ops = &dsa_slave_switchdev_ops;
slave_dev->min_mtu = 0;
slave_dev->max_mtu = ETH_MAX_MTU;
SET_NETDEV_DEVTYPE(slave_dev, &dsa_type);
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index cd78253de31d..b7f1cf0c7f4c 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -174,81 +174,31 @@ static int switchdev_deferred_enqueue(struct net_device *dev,
return 0;
}
-/**
- * switchdev_port_attr_get - Get port attribute
- *
- * @dev: port device
- * @attr: attribute to get
- */
-int switchdev_port_attr_get(struct net_device *dev, struct switchdev_attr *attr)
+static int switchdev_port_attr_notify(enum switchdev_notifier_type nt,
+ struct net_device *dev,
+ struct switchdev_attr *attr,
+ struct switchdev_trans *trans)
{
- const struct switchdev_ops *ops = dev->switchdev_ops;
- struct net_device *lower_dev;
- struct list_head *iter;
- struct switchdev_attr first = {
- .id = SWITCHDEV_ATTR_ID_UNDEFINED
- };
- int err = -EOPNOTSUPP;
+ int err;
+ int rc;
- if (ops && ops->switchdev_port_attr_get)
- return ops->switchdev_port_attr_get(dev, attr);
+ struct switchdev_notifier_port_attr_info attr_info = {
+ .attr = attr,
+ .trans = trans,
+ .handled = false,
+ };
- if (attr->flags & SWITCHDEV_F_NO_RECURSE)
+ rc = call_switchdev_blocking_notifiers(nt, dev, &attr_info.info, NULL);
+ err = notifier_to_errno(rc);
+ if (err) {
+ WARN_ON(!attr_info.handled);
return err;
-
- /* Switch device port(s) may be stacked under
- * bond/team/vlan dev, so recurse down to get attr on
- * each port. Return -ENODATA if attr values don't
- * compare across ports.
- */
-
- netdev_for_each_lower_dev(dev, lower_dev, iter) {
- err = switchdev_port_attr_get(lower_dev, attr);
- if (err)
- break;
- if (first.id == SWITCHDEV_ATTR_ID_UNDEFINED)
- first = *attr;
- else if (memcmp(&first, attr, sizeof(*attr)))
- return -ENODATA;
- }
-
- return err;
-}
-EXPORT_SYMBOL_GPL(switchdev_port_attr_get);
-
-static int __switchdev_port_attr_set(struct net_device *dev,
- const struct switchdev_attr *attr,
- struct switchdev_trans *trans)
-{
- const struct switchdev_ops *ops = dev->switchdev_ops;
- struct net_device *lower_dev;
- struct list_head *iter;
- int err = -EOPNOTSUPP;
-
- if (ops && ops->switchdev_port_attr_set) {
- err = ops->switchdev_port_attr_set(dev, attr, trans);
- goto done;
- }
-
- if (attr->flags & SWITCHDEV_F_NO_RECURSE)
- goto done;
-
- /* Switch device port(s) may be stacked under
- * bond/team/vlan dev, so recurse down to set attr on
- * each port.
- */
-
- netdev_for_each_lower_dev(dev, lower_dev, iter) {
- err = __switchdev_port_attr_set(lower_dev, attr, trans);
- if (err)
- break;
}
-done:
- if (err == -EOPNOTSUPP && attr->flags & SWITCHDEV_F_SKIP_EOPNOTSUPP)
- err = 0;
+ if (!attr_info.handled)
+ return -EOPNOTSUPP;
- return err;
+ return 0;
}
static int switchdev_port_attr_set_now(struct net_device *dev,
@@ -267,7 +217,9 @@ static int switchdev_port_attr_set_now(struct net_device *dev,
*/
trans.ph_prepare = true;
- err = __switchdev_port_attr_set(dev, attr, &trans);
+ err = switchdev_port_attr_notify(SWITCHDEV_PORT_ATTR_SET,
+ dev, (struct switchdev_attr *)attr,
+ &trans);
if (err) {
/* Prepare phase failed: abort the transaction. Any
* resources reserved in the prepare phase are
@@ -286,7 +238,9 @@ static int switchdev_port_attr_set_now(struct net_device *dev,
*/
trans.ph_prepare = false;
- err = __switchdev_port_attr_set(dev, attr, &trans);
+ err = switchdev_port_attr_notify(SWITCHDEV_PORT_ATTR_SET,
+ dev, (struct switchdev_attr *)attr,
+ &trans);
WARN(err, "%s: Commit of attribute (id=%d) failed.\n",
dev->name, attr->id);
switchdev_trans_items_warn_destroy(dev, &trans);
@@ -338,6 +292,19 @@ int switchdev_port_attr_set(struct net_device *dev,
}
EXPORT_SYMBOL_GPL(switchdev_port_attr_set);
+/**
+ * switchdev_port_attr_get - Get port attribute
+ *
+ * @dev: port device
+ * @attr: attribute to get
+ */
+int switchdev_port_attr_get(struct net_device *dev, struct switchdev_attr *attr)
+{
+ return switchdev_port_attr_notify(SWITCHDEV_PORT_ATTR_GET, dev,
+ attr, NULL);
+}
+EXPORT_SYMBOL_GPL(switchdev_port_attr_get);
+
static size_t switchdev_obj_size(const struct switchdev_obj *obj)
{
switch (obj->id) {
--
2.17.1
Following patches will change the way we communicate getting or setting
a port's attribute and use a blocking notifier to perform those tasks.
Prepare netdevsim to support receiving notifier events targeting
SWITCHDEV_PORT_ATTR_GET and simply translate that into the existing
switchdev_ops::switchdev_port_attr_get operation.
We register a single blocking switchdev notifier for the entire driver
instance.
Signed-off-by: Florian Fainelli <[email protected]>
---
drivers/net/netdevsim/netdev.c | 43 +++++++++++++++++++++++++++++++++-
1 file changed, 42 insertions(+), 1 deletion(-)
diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c
index 8d8e2b3f263e..817d94cec90f 100644
--- a/drivers/net/netdevsim/netdev.c
+++ b/drivers/net/netdevsim/netdev.c
@@ -168,6 +168,20 @@ static const struct switchdev_ops nsim_switchdev_ops = {
.switchdev_port_attr_get = nsim_port_attr_get,
};
+static int nsim_switchdev_port_attr_event(unsigned long event,
+ struct net_device *dev,
+ struct switchdev_notifier_port_attr_info *port_attr_info)
+{
+ int rc;
+
+ if (event != SWITCHDEV_PORT_ATTR_GET)
+ return NOTIFY_DONE;
+
+ rc = nsim_port_attr_get(dev, port_attr_info->attr);
+ port_attr_info->handled = true;
+ return notifier_from_errno(rc);
+}
+
static int nsim_init(struct net_device *dev)
{
char sdev_ddir_name[10], sdev_link_name[32];
@@ -495,6 +509,26 @@ static const struct net_device_ops nsim_netdev_ops = {
.ndo_bpf = nsim_bpf,
};
+static int nsim_swdev_blocking_event(struct notifier_block *nb,
+ unsigned long event, void *ptr)
+{
+ struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
+
+ if (dev->netdev_ops != &nsim_netdev_ops)
+ return NOTIFY_DONE;
+
+ switch (event) {
+ case SWITCHDEV_PORT_ATTR_GET:
+ return nsim_switchdev_port_attr_event(event, dev, ptr);
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block nsim_swdev_blocking_nb = {
+ .notifier_call = nsim_swdev_blocking_event,
+};
+
static void nsim_setup(struct net_device *dev)
{
ether_setup(dev);
@@ -583,10 +617,14 @@ static int __init nsim_module_init(void)
goto err_debugfs_destroy;
}
- err = bus_register(&nsim_bus);
+ err = register_switchdev_blocking_notifier(&nsim_swdev_blocking_nb);
if (err)
goto err_sdir_destroy;
+ err = bus_register(&nsim_bus);
+ if (err)
+ goto err_unreg_notifier;
+
err = nsim_devlink_init();
if (err)
goto err_unreg_bus;
@@ -601,6 +639,8 @@ static int __init nsim_module_init(void)
nsim_devlink_exit();
err_unreg_bus:
bus_unregister(&nsim_bus);
+err_unreg_notifier:
+ unregister_switchdev_blocking_notifier(&nsim_swdev_blocking_nb);
err_sdir_destroy:
debugfs_remove_recursive(nsim_sdev_ddir);
err_debugfs_destroy:
@@ -613,6 +653,7 @@ static void __exit nsim_module_exit(void)
rtnl_link_unregister(&nsim_link_ops);
nsim_devlink_exit();
bus_unregister(&nsim_bus);
+ unregister_switchdev_blocking_notifier(&nsim_swdev_blocking_nb);
debugfs_remove_recursive(nsim_sdev_ddir);
debugfs_remove_recursive(nsim_ddir);
}
--
2.17.1
Following patches will change the way we communicate getting or setting
a port's attribute and use a blocking notifier to perform those tasks.
Prepare mlx5e/en_rep.c to support receiving notifier events targeting
SWITCHDEV_PORT_ATTR_GET and simply translate that into the existing
switchdev_ops::switchdev_port_attr_get operation.
We register a single blocking switchdev notifier for the entire set of
representors given that mlx5e_rep_register_vport_reps() gets called for
an Ethernet device.
Signed-off-by: Florian Fainelli <[email protected]>
---
.../net/ethernet/mellanox/mlx5/core/en_main.c | 4 +-
.../net/ethernet/mellanox/mlx5/core/en_rep.c | 45 ++++++++++++++++++-
.../net/ethernet/mellanox/mlx5/core/en_rep.h | 2 +-
3 files changed, 48 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index dee0c8f3d4e9..fcfe1c9d3575 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -5036,7 +5036,9 @@ static void *mlx5e_add(struct mlx5_core_dev *mdev)
#ifdef CONFIG_MLX5_ESWITCH
if (MLX5_ESWITCH_MANAGER(mdev) &&
mlx5_eswitch_mode(mdev->priv.eswitch) == SRIOV_OFFLOADS) {
- mlx5e_rep_register_vport_reps(mdev);
+ err = mlx5e_rep_register_vport_reps(mdev);
+ if (err)
+ return NULL;
return mdev;
}
#endif
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
index 04736212a21c..9bac78e111c6 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
@@ -1289,6 +1289,21 @@ static const struct switchdev_ops mlx5e_rep_switchdev_ops = {
.switchdev_port_attr_get = mlx5e_attr_get,
};
+static int mlx5e_rep_swdev_port_attr_event(unsigned long event,
+ struct net_device *dev,
+ struct switchdev_notifier_port_attr_info *port_attr_info)
+{
+ int rc;
+
+ if (event != SWITCHDEV_PORT_ATTR_GET)
+ return NOTIFY_DONE;
+
+ rc = mlx5e_attr_get(dev, port_attr_info->attr);
+ port_attr_info->handled = true;
+
+ return notifier_from_errno(rc);
+}
+
static const struct net_device_ops mlx5e_netdev_ops_vf_rep = {
.ndo_open = mlx5e_vf_rep_open,
.ndo_stop = mlx5e_vf_rep_close,
@@ -1321,6 +1336,22 @@ static const struct net_device_ops mlx5e_netdev_ops_uplink_rep = {
.ndo_get_vf_stats = mlx5e_get_vf_stats,
};
+static int mlx5e_rep_swdev_blocking_event(struct notifier_block *nb,
+ unsigned long event, void *ptr)
+{
+ struct net_device *netdev = switchdev_notifier_info_to_dev(ptr);
+
+ if (netdev->netdev_ops != &mlx5e_netdev_ops_vf_rep)
+ return NOTIFY_DONE;
+
+ switch (event) {
+ case SWITCHDEV_PORT_ATTR_GET:
+ return mlx5e_rep_swdev_port_attr_event(event, netdev, ptr);
+ }
+
+ return NOTIFY_DONE;
+}
+
bool mlx5e_eswitch_rep(struct net_device *netdev)
{
if (netdev->netdev_ops == &mlx5e_netdev_ops_vf_rep ||
@@ -1798,11 +1829,20 @@ static void *mlx5e_vport_rep_get_proto_dev(struct mlx5_eswitch_rep *rep)
return rpriv->netdev;
}
-void mlx5e_rep_register_vport_reps(struct mlx5_core_dev *mdev)
+static struct notifier_block mlx5e_rep_swdev_nb = {
+ .notifier_call = mlx5e_rep_swdev_blocking_event,
+};
+
+int mlx5e_rep_register_vport_reps(struct mlx5_core_dev *mdev)
{
struct mlx5_eswitch *esw = mdev->priv.eswitch;
int total_vfs = MLX5_TOTAL_VPORTS(mdev);
int vport;
+ int rc;
+
+ rc = register_switchdev_blocking_notifier(&mlx5e_rep_swdev_nb);
+ if (rc)
+ return rc;
for (vport = 0; vport < total_vfs; vport++) {
struct mlx5_eswitch_rep_if rep_if = {};
@@ -1812,6 +1852,8 @@ void mlx5e_rep_register_vport_reps(struct mlx5_core_dev *mdev)
rep_if.get_proto_dev = mlx5e_vport_rep_get_proto_dev;
mlx5_eswitch_register_vport_rep(esw, vport, &rep_if, REP_ETH);
}
+
+ return rc;
}
void mlx5e_rep_unregister_vport_reps(struct mlx5_core_dev *mdev)
@@ -1822,4 +1864,5 @@ void mlx5e_rep_unregister_vport_reps(struct mlx5_core_dev *mdev)
for (vport = total_vfs - 1; vport >= 0; vport--)
mlx5_eswitch_unregister_vport_rep(esw, vport, REP_ETH);
+ unregister_switchdev_blocking_notifier(&mlx5e_rep_swdev_nb);
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h
index edd722824697..b9e0507f6100 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h
@@ -162,7 +162,7 @@ struct mlx5e_rep_sq {
};
void *mlx5e_alloc_nic_rep_priv(struct mlx5_core_dev *mdev);
-void mlx5e_rep_register_vport_reps(struct mlx5_core_dev *mdev);
+int mlx5e_rep_register_vport_reps(struct mlx5_core_dev *mdev);
void mlx5e_rep_unregister_vport_reps(struct mlx5_core_dev *mdev);
bool mlx5e_is_uplink_rep(struct mlx5e_priv *priv);
int mlx5e_add_sqs_fwd_rules(struct mlx5e_priv *priv);
--
2.17.1
Following patches will change the way we communicate getting or setting
a port's attribute and use a blocking notifier to perform those tasks.
Prepare mlxsw to support receiving notifier events targeting
SWITCHDEV_PORT_ATTR_GET/SET and simply translate that into the existing
mlxsw_sp_port_attr_{set,get} calls.
Signed-off-by: Florian Fainelli <[email protected]>
---
.../mellanox/mlxsw/spectrum_switchdev.c | 23 +++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index 0f4e68d31cc3..7c0df736587c 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -3442,6 +3442,26 @@ mlxsw_sp_switchdev_handle_vxlan_obj_del(struct net_device *vxlan_dev,
}
}
+static int
+mlxsw_sp_switchdev_port_attr_event(unsigned long event, struct net_device *dev,
+ struct switchdev_notifier_port_attr_info *port_attr_info)
+{
+ int err = -EOPNOTSUPP;
+
+ switch (event) {
+ case SWITCHDEV_PORT_ATTR_SET:
+ err = mlxsw_sp_port_attr_set(dev, port_attr_info->attr,
+ port_attr_info->trans);
+ break;
+ case SWITCHDEV_PORT_ATTR_GET:
+ err = mlxsw_sp_port_attr_get(dev, port_attr_info->attr);
+ break;
+ }
+
+ port_attr_info->handled = true;
+ return notifier_from_errno(err);
+}
+
static int mlxsw_sp_switchdev_blocking_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{
@@ -3465,6 +3485,9 @@ static int mlxsw_sp_switchdev_blocking_event(struct notifier_block *unused,
mlxsw_sp_port_dev_check,
mlxsw_sp_port_obj_del);
return notifier_from_errno(err);
+ case SWITCHDEV_PORT_ATTR_SET:
+ case SWITCHDEV_PORT_ATTR_GET:
+ return mlxsw_sp_switchdev_port_attr_event(event, dev, ptr);
}
return NOTIFY_DONE;
--
2.17.1
Following patches will change the way we communicate getting or setting
a port's attribute and use a blocking notifier to perform those tasks.
Prepare ocelot to support receiving notifier events targeting
SWITCHDEV_PORT_ATTR_GET/SET and simply translate that into the existing
ocelot_port_attr_{set,get} calls.
Signed-off-by: Florian Fainelli <[email protected]>
---
drivers/net/ethernet/mscc/ocelot.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
index c6a575eb0ff5..8043347a1ed4 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -1589,6 +1589,27 @@ struct notifier_block ocelot_netdevice_nb __read_mostly = {
};
EXPORT_SYMBOL(ocelot_netdevice_nb);
+static int
+ocelot_switchdev_port_attr_event(unsigned long event,
+ struct net_device *netdev,
+ struct switchdev_notifier_port_attr_info *port_attr_info)
+{
+ int err = -EOPNOTSUPP;
+
+ switch (event) {
+ case SWITCHDEV_PORT_ATTR_SET:
+ err = ocelot_port_attr_set(netdev, port_attr_info->attr,
+ port_attr_info->trans);
+ break;
+ case SWITCHDEV_PORT_ATTR_GET:
+ err = ocelot_port_attr_get(netdev, port_attr_info->attr);
+ break;
+ }
+
+ port_attr_info->handled = true;
+ return notifier_from_errno(err);
+}
+
static int ocelot_switchdev_blocking_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{
@@ -1607,6 +1628,9 @@ static int ocelot_switchdev_blocking_event(struct notifier_block *unused,
ocelot_netdevice_dev_check,
ocelot_port_obj_del);
return notifier_from_errno(err);
+ case SWITCHDEV_PORT_ATTR_SET:
+ case SWITCHDEV_PORT_ATTR_GET:
+ return ocelot_switchdev_port_attr_event(event, dev, ptr);
}
return NOTIFY_DONE;
--
2.17.1
Following patches will change the way we communicate getting or setting
a port's attribute and use a blocking notifier to perform those tasks.
Prepare bnxt to support receiving notifier events targeting
SWITCHDEV_PORT_ATTR_GET and simply translate that into the existing
switchdev_ops::switchdev_port_attr_get operation.
We register a single blocking switchdev notifier for the PF part of the
driver, and we register another blocking switchdev notifier, following
what was done with the existing netdevice notifier within the VF
representor driver.
Signed-off-by: Florian Fainelli <[email protected]>
---
.../net/ethernet/cavium/liquidio/lio_main.c | 48 ++++++++++++++++++-
.../net/ethernet/cavium/liquidio/lio_vf_rep.c | 45 ++++++++++++++++-
2 files changed, 91 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c
index 3d24133e5e49..b9d48e4181fc 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
@@ -162,6 +162,8 @@ static int liquidio_set_vf_link_state(struct net_device *netdev, int vfidx,
static struct handshake handshake[MAX_OCTEON_DEVICES];
static struct completion first_stage;
+static int liquidio_switchdev_blocking_event(struct notifier_block *nb,
+ unsigned long event, void *ptr);
static void octeon_droq_bh(unsigned long pdev)
{
@@ -469,12 +471,25 @@ static struct pci_driver liquidio_pci_driver = {
#endif
};
+static struct notifier_block liquidio_blocking_nb = {
+ .notifier_call = liquidio_switchdev_blocking_event,
+};
+
/**
* \brief register PCI driver
*/
static int liquidio_init_pci(void)
{
- return pci_register_driver(&liquidio_pci_driver);
+ int rc;
+
+ rc = register_switchdev_blocking_notifier(&liquidio_blocking_nb);
+ if (rc)
+ return rc;
+ rc = pci_register_driver(&liquidio_pci_driver);
+ if (rc)
+ unregister_switchdev_blocking_notifier(&liquidio_blocking_nb);
+
+ return rc;
}
/**
@@ -483,6 +498,7 @@ static int liquidio_init_pci(void)
static void liquidio_deinit_pci(void)
{
pci_unregister_driver(&liquidio_pci_driver);
+ unregister_switchdev_blocking_notifier(&liquidio_blocking_nb);
}
/**
@@ -3261,6 +3277,36 @@ static const struct net_device_ops lionetdevops = {
.ndo_get_vf_stats = liquidio_get_vf_stats,
};
+static int lio_pf_attr_event(unsigned long event, struct net_device *dev,
+ struct switchdev_notifier_port_attr_info *port_attr_info)
+{
+ int rc;
+
+ if (event != SWITCHDEV_PORT_ATTR_GET)
+ return NOTIFY_DONE;
+
+ rc = lio_pf_switchdev_attr_get(dev, port_attr_info->attr);
+
+ port_attr_info->handled = true;
+ return notifier_from_errno(rc);
+}
+
+static int liquidio_switchdev_blocking_event(struct notifier_block *nb,
+ unsigned long event, void *ptr)
+{
+ struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
+
+ if (dev->netdev_ops != &lionetdevops)
+ return NOTIFY_DONE;
+
+ switch (event) {
+ case SWITCHDEV_PORT_ATTR_GET:
+ return lio_pf_attr_event(event, dev, ptr);
+ }
+
+ return NOTIFY_DONE;
+}
+
/** \brief Entry point for the liquidio module
*/
static int __init liquidio_init(void)
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c b/drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c
index de61060721c4..d396c004c1be 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c
@@ -468,6 +468,21 @@ static const struct switchdev_ops lio_vf_rep_switchdev_ops = {
.switchdev_port_attr_get = lio_vf_rep_attr_get,
};
+static int lio_vf_rep_swdev_port_attr_event(unsigned long event,
+ struct net_device *dev,
+ struct switchdev_notifier_port_attr_info *port_attr_info)
+{
+ int rc;
+
+ if (event != SWITCHDEV_PORT_ATTR_GET)
+ return NOTIFY_DONE;
+
+ rc = lio_vf_rep_attr_get(dev, port_attr_info->attr);
+ port_attr_info->handled = true;
+
+ return notifier_from_errno(rc);
+}
+
static void
lio_vf_rep_fetch_stats(struct work_struct *work)
{
@@ -538,7 +553,6 @@ lio_vf_rep_create(struct octeon_device *oct)
if (register_netdev(ndev)) {
dev_err(&oct->pci_dev->dev, "VF rep nerdev registration failed\n");
-
free_netdev(ndev);
goto cleanup;
}
@@ -664,20 +678,49 @@ static struct notifier_block lio_vf_rep_netdev_notifier = {
.notifier_call = lio_vf_rep_netdev_event,
};
+static int lio_vf_rep_swdev_event(struct notifier_block *nb,
+ unsigned long event, void *ptr)
+{
+ struct net_device *ndev = switchdev_notifier_info_to_dev(ptr);
+
+ if (ndev->netdev_ops != &lio_vf_rep_ndev_ops)
+ return NOTIFY_DONE;
+
+ switch (event) {
+ case SWITCHDEV_PORT_ATTR_GET:
+ return lio_vf_rep_swdev_port_attr_event(event, ndev, ptr);
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block lio_vf_rep_swdev_nb = {
+ .notifier_call = lio_vf_rep_swdev_event,
+};
+
int
lio_vf_rep_modinit(void)
{
+ int rc;
+
if (register_netdevice_notifier(&lio_vf_rep_netdev_notifier)) {
pr_err("netdev notifier registration failed\n");
return -EFAULT;
}
+ rc = register_switchdev_blocking_notifier(&lio_vf_rep_swdev_nb);
+ if (rc) {
+ unregister_netdevice_notifier(&lio_vf_rep_netdev_notifier);
+ return rc;
+ }
+
return 0;
}
void
lio_vf_rep_modexit(void)
{
+ unregister_switchdev_blocking_notifier(&lio_vf_rep_swdev_nb);
if (unregister_netdevice_notifier(&lio_vf_rep_netdev_notifier))
pr_err("netdev notifier unregister failed\n");
}
--
2.17.1
Following patches will change the way we communicate getting or setting
a port's attribute and use a blocking notifier to perform those tasks.
Prepare ethsw to support receiving notifier events targeting
SWITCHDEV_PORT_ATTR_GET/SET and simply translate that into the existing
swdev_port_attr_{set,get} calls.
Signed-off-by: Florian Fainelli <[email protected]>
---
drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
index daabaceeea52..b18e112d84e6 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
@@ -1103,6 +1103,27 @@ ethsw_switchdev_port_obj_event(unsigned long event, struct net_device *netdev,
return notifier_from_errno(err);
}
+static int
+ethsw_switchdev_port_attr_event(unsigned long event,
+ struct net_device *netdev,
+ struct switchdev_notifier_port_attr_info *port_attr_info)
+{
+ int err = -EOPNOTSUPP;
+
+ switch (event) {
+ case SWITCHDEV_PORT_ATTR_SET:
+ err = swdev_port_attr_set(netdev, port_attr_info->attr,
+ port_attr_info->trans);
+ break;
+ case SWITCHDEV_PORT_ATTR_GET:
+ err = swdev_port_attr_get(netdev, port_attr_info->attr);
+ break;
+ }
+
+ port_attr_info->handled = true;
+ return notifier_from_errno(err);
+}
+
static int port_switchdev_blocking_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{
@@ -1115,6 +1136,9 @@ static int port_switchdev_blocking_event(struct notifier_block *unused,
case SWITCHDEV_PORT_OBJ_ADD: /* fall through */
case SWITCHDEV_PORT_OBJ_DEL:
return ethsw_switchdev_port_obj_event(event, dev, ptr);
+ case SWITCHDEV_PORT_ATTR_SET:
+ case SWITCHDEV_PORT_ATTR_GET:
+ return ethsw_switchdev_port_attr_event(event, dev, ptr);
}
return NOTIFY_DONE;
--
2.17.1
Following patches will change the way we communicate getting or setting
a port's attribute and use a blocking notifier to perform those tasks.
Prepare DSA to support receiving notifier events targeting
SWITCHDEV_PORT_ATTR_GET/SET and simply translate that into the existing
dsa_slave_port_attr_{set,get} calls.
Signed-off-by: Florian Fainelli <[email protected]>
---
net/dsa/slave.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 91de3a663226..bc7d5092a1c7 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -1549,6 +1549,27 @@ dsa_slave_switchdev_port_obj_event(unsigned long event,
return notifier_from_errno(err);
}
+static int
+dsa_slave_switchdev_port_attr_event(unsigned long event,
+ struct net_device *netdev,
+ struct switchdev_notifier_port_attr_info *port_attr_info)
+{
+ int err = -EOPNOTSUPP;
+
+ switch (event) {
+ case SWITCHDEV_PORT_ATTR_SET:
+ err = dsa_slave_port_attr_set(netdev, port_attr_info->attr,
+ port_attr_info->trans);
+ break;
+ case SWITCHDEV_PORT_ATTR_GET:
+ err = dsa_slave_port_attr_get(netdev, port_attr_info->attr);
+ break;
+ }
+
+ port_attr_info->handled = true;
+ return notifier_from_errno(err);
+}
+
static int dsa_slave_switchdev_blocking_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{
@@ -1561,6 +1582,9 @@ static int dsa_slave_switchdev_blocking_event(struct notifier_block *unused,
case SWITCHDEV_PORT_OBJ_ADD: /* fall through */
case SWITCHDEV_PORT_OBJ_DEL:
return dsa_slave_switchdev_port_obj_event(event, dev, ptr);
+ case SWITCHDEV_PORT_ATTR_SET: /* fallthrough */
+ case SWITCHDEV_PORT_ATTR_GET:
+ return dsa_slave_switchdev_port_attr_event(event, dev, ptr);
}
return NOTIFY_DONE;
--
2.17.1
Following patches will change the way we communicate getting or setting
a port's attribute and use a blocking notifier to perform those tasks.
Prepare rocker to support receiving notifier events targeting
SWITCHDEV_PORT_ATTR_GET/SET and simply translate that into the existing
rocker_port_attr_{set,get} calls.
Signed-off-by: Florian Fainelli <[email protected]>
---
drivers/net/ethernet/rocker/rocker_main.c | 24 +++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/drivers/net/ethernet/rocker/rocker_main.c b/drivers/net/ethernet/rocker/rocker_main.c
index 62a205eba9f7..f25f7b4345b8 100644
--- a/drivers/net/ethernet/rocker/rocker_main.c
+++ b/drivers/net/ethernet/rocker/rocker_main.c
@@ -2827,6 +2827,27 @@ rocker_switchdev_port_obj_event(unsigned long event, struct net_device *netdev,
return notifier_from_errno(err);
}
+static int
+rocker_switchdev_port_attr_event(unsigned long event, struct net_device *netdev,
+ struct switchdev_notifier_port_attr_info
+ *port_attr_info)
+{
+ int err = -EOPNOTSUPP;
+
+ switch (event) {
+ case SWITCHDEV_PORT_ATTR_SET:
+ err = rocker_port_attr_set(netdev, port_attr_info->attr,
+ port_attr_info->trans);
+ break;
+ case SWITCHDEV_PORT_ATTR_GET:
+ err = rocker_port_attr_get(netdev, port_attr_info->attr);
+ break;
+ }
+
+ port_attr_info->handled = true;
+ return notifier_from_errno(err);
+}
+
static int rocker_switchdev_blocking_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{
@@ -2839,6 +2860,9 @@ static int rocker_switchdev_blocking_event(struct notifier_block *unused,
case SWITCHDEV_PORT_OBJ_ADD:
case SWITCHDEV_PORT_OBJ_DEL:
return rocker_switchdev_port_obj_event(event, dev, ptr);
+ case SWITCHDEV_PORT_ATTR_SET:
+ case SWITCHDEV_PORT_ATTR_GET:
+ return rocker_switchdev_port_attr_event(event, dev, ptr);
}
return NOTIFY_DONE;
--
2.17.1
On Fri, 1 Feb 2019 14:06:55 -0800, Florian Fainelli wrote:
> Following patches will change the way we communicate getting or setting
> a port's attribute and use a blocking notifier to perform those tasks.
>
> Prepare nfp to support receiving notifier events targeting
> SWITCHDEV_PORT_ATTR_GET and simply translate that into the existing
> switchdev_ops::switchdev_port_attr_get operation.
>
> We register a single blocking switchdev notifier for the entire driver
> instance and we differentiate a "net" from a "repr" by comparing the
> network device's netdev_ops with the ones that this driver manages.
>
> Signed-off-by: Florian Fainelli <[email protected]>
Thanks Florian, the code looks good, only nit I have is - could you
move nfp_switchdev_blocking_event() to nfp_port.c and nfp_port.h?
We shouldn't touch nfp_net_common.c here.
In general calling a notifier to get the parent_id (which is the only
thing all these SR-IOV NIC drivers implement) seems a tad heavy. It's
an immutable, read-only attribute of a port, perhaps we can break it
out? Could we make it an NDO, perhaps?
That's just my knee jerk reaction, given that NIC drivers don't
implement any of the bridging side of switchdev I may not have a full
appreciation of the abstraction you are building here :)
Le 2/1/19 à 7:45 PM, Jakub Kicinski a écrit :
> On Fri, 1 Feb 2019 14:06:55 -0800, Florian Fainelli wrote:
>> Following patches will change the way we communicate getting or setting
>> a port's attribute and use a blocking notifier to perform those tasks.
>>
>> Prepare nfp to support receiving notifier events targeting
>> SWITCHDEV_PORT_ATTR_GET and simply translate that into the existing
>> switchdev_ops::switchdev_port_attr_get operation.
>>
>> We register a single blocking switchdev notifier for the entire driver
>> instance and we differentiate a "net" from a "repr" by comparing the
>> network device's netdev_ops with the ones that this driver manages.
>>
>> Signed-off-by: Florian Fainelli <[email protected]>
>
> Thanks Florian, the code looks good, only nit I have is - could you
> move nfp_switchdev_blocking_event() to nfp_port.c and nfp_port.h?
> We shouldn't touch nfp_net_common.c here.
Sounds good, thanks for the suggestion.
>
> In general calling a notifier to get the parent_id (which is the only
> thing all these SR-IOV NIC drivers implement) seems a tad heavy. It's
> an immutable, read-only attribute of a port, perhaps we can break it
> out? Could we make it an NDO, perhaps?
A NDO would be fine with me, Ido, what do you think?
>
> That's just my knee jerk reaction, given that NIC drivers don't
> implement any of the bridging side of switchdev I may not have a full
> appreciation of the abstraction you are building here :)
>
Ido convinced me to convert the switchdev_port_attr_set() into a
blocking notifier such that we could veto operations in switch drivers,
once you do that, leaving the getter as switchdev_ops became pointless
:) but yes, it's a lot of code just to get there.
--
Florian
Fri, Feb 01, 2019 at 11:06:45PM CET, [email protected] wrote:
>In preparation for allowing switchdev enabled drivers to veto specific
>attribute settings from within the context of the caller, introduce a
>new switchdev notifier type for port attributes.
>
>Suggested-by: Ido Schimmel <[email protected]>
>Signed-off-by: Florian Fainelli <[email protected]>
>---
> include/net/switchdev.h | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
>diff --git a/include/net/switchdev.h b/include/net/switchdev.h
>index 63843ae5dc81..e62fb2693e00 100644
>--- a/include/net/switchdev.h
>+++ b/include/net/switchdev.h
>@@ -145,6 +145,9 @@ enum switchdev_notifier_type {
> SWITCHDEV_VXLAN_FDB_ADD_TO_DEVICE,
> SWITCHDEV_VXLAN_FDB_DEL_TO_DEVICE,
> SWITCHDEV_VXLAN_FDB_OFFLOADED,
>+
>+ SWITCHDEV_PORT_ATTR_SET, /* Blocking. */
>+ SWITCHDEV_PORT_ATTR_GET, /* Blocking. */
Not an UAPI, so you can put this right next to PORT_OBJ_* if needed.
> };
>
> struct switchdev_notifier_info {
>@@ -167,6 +170,13 @@ struct switchdev_notifier_port_obj_info {
> bool handled;
> };
>
>+struct switchdev_notifier_port_attr_info {
>+ struct switchdev_notifier_info info; /* must be first */
>+ struct switchdev_attr *attr;
>+ struct switchdev_trans *trans;
>+ bool handled;
>+};
>+
> static inline struct net_device *
> switchdev_notifier_info_to_dev(const struct switchdev_notifier_info *info)
> {
>--
>2.17.1
>
Fri, Feb 01, 2019 at 11:06:44PM CET, [email protected] wrote:
>Hi all,
>
>This patch series converts SWITCHDEV_PORT_ATTR_{GET,SET} to use a
>blocking notifier, similar to how SWITCHDEV_PORT_OBJ_{ADD,DEL} has been
>changed recently by Petr.
>
>This was suggested by Ido to help with a particular use case I have
>where I want to be able to veto a switchdev bridge attribute from a
>driver (multicast_snooping).
>
>Please review since I may not have gotten the driver abstraction right,
>especially for mlx5e and nfp since these are *hum* *hum* large drivers.
Looks fine. Thanks!