@@ -119,6 +119,7 @@ int hclge_devlink_init(struct hclge_dev *hdev)
priv->hdev = hdev;
hdev->devlink = devlink;
+ devlink_set_features(devlink, DEVLINK_F_RELOAD);
devlink_register(devlink);
devlink_reload_enable(devlink);
return 0;
@@ -121,6 +121,7 @@ int hclgevf_devlink_init(struct hclgevf_dev *hdev)
priv->hdev = hdev;
hdev->devlink = devlink;
+ devlink_set_features(devlink, DEVLINK_F_RELOAD);
devlink_register(devlink);
devlink_reload_enable(devlink);
return 0;
@@ -4025,6 +4025,7 @@ static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
goto err_params_unregister;
pci_save_state(pdev);
+ devlink_set_features(devlink, DEVLINK_F_RELOAD);
devlink_register(devlink);
devlink_reload_enable(devlink);
return 0;
@@ -813,6 +813,7 @@ int mlx5_devlink_register(struct devlink *devlink)
if (err)
goto traps_reg_err;
+ devlink_set_features(devlink, DEVLINK_F_RELOAD);
return 0;
traps_reg_err:
@@ -2008,6 +2008,7 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
}
if (!reload) {
+ devlink_set_features(devlink, DEVLINK_F_RELOAD);
devlink_register(devlink);
devlink_reload_enable(devlink);
}
@@ -1511,6 +1511,7 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev)
goto err_psample_exit;
nsim_dev->esw_mode = DEVLINK_ESWITCH_MODE_LEGACY;
+ devlink_set_features(devlink, DEVLINK_F_RELOAD);
devlink_register(devlink);
devlink_reload_enable(devlink);
return 0;
@@ -1186,6 +1186,11 @@ enum devlink_trap_group_generic_id {
.min_burst = _min_burst, \
}
+enum {
+ /* device supports reload operations */
+ DEVLINK_F_RELOAD = 1UL << 0,
+};
+
struct devlink_ops {
/**
* @supported_flash_update_params:
@@ -1503,6 +1508,7 @@ static inline struct devlink *devlink_alloc(const struct devlink_ops *ops,
{
return devlink_alloc_ns(ops, priv_size, &init_net, dev);
}
+void devlink_set_features(struct devlink *devlink, u64 features);
void devlink_register(struct devlink *devlink);
void devlink_unregister(struct devlink *devlink);
void devlink_reload_enable(struct devlink *devlink);
@@ -54,6 +54,7 @@ struct devlink {
struct list_head trap_group_list;
struct list_head trap_policer_list;
const struct devlink_ops *ops;
+ u64 features;
struct xarray snapshot_ids;
struct devlink_dev_stats stats;
struct device *dev;
@@ -4032,7 +4033,7 @@ static int devlink_reload(struct devlink *devlink, struct net *dest_net,
struct net *curr_net;
int err;
- if (!devlink->reload_enabled)
+ if (!devlink->reload_enabled || !(devlink->features & DEVLINK_F_RELOAD))
return -EOPNOTSUPP;
memcpy(remote_reload_stats, devlink->stats.remote_reload_stats,
@@ -8985,6 +8986,25 @@ static bool devlink_reload_actions_valid(const struct devlink_ops *ops)
return true;
}
+/**
+ * devlink_set_features - Set devlink supported features
+ *
+ * @devlink: devlink
+ * @features: devlink support features
+ *
+ * This interface allows us to set reload ops separatelly from
+ * the devlink_alloc.
+ */
+void devlink_set_features(struct devlink *devlink, u64 features)
+{
+ ASSERT_DEVLINK_NOT_REGISTERED(devlink);
+
+ WARN_ON(features & DEVLINK_F_RELOAD &&
+ !devlink_reload_supported(devlink->ops));
+ devlink->features = features;
+}
+EXPORT_SYMBOL_GPL(devlink_set_features);
+
/**
* devlink_alloc_ns - Allocate new devlink instance resources
* in specific namespace
@@ -9155,7 +9175,7 @@ void devlink_unregister(struct devlink *devlink)
wait_for_completion(&devlink->comp);
mutex_lock(&devlink_mutex);
- WARN_ON(devlink_reload_supported(devlink->ops) &&
+ WARN_ON(devlink->features & DEVLINK_F_RELOAD &&
devlink->reload_enabled);
devlink_notify_unregister(devlink);
xa_clear_mark(&devlinks, devlink->index, DEVLINK_REGISTERED);