aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/catas.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c44
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h3
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/core.c30
-rw-r--r--drivers/net/netdevsim/dev.c13
-rw-r--r--include/net/devlink.h8
-rw-r--r--include/uapi/linux/devlink.h2
-rw-r--r--net/core/devlink.c35
8 files changed, 106 insertions, 31 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/catas.c b/drivers/net/ethernet/mellanox/mlx4/catas.c
index 87e90b5d4d7d..5b11557f1ae4 100644
--- a/drivers/net/ethernet/mellanox/mlx4/catas.c
+++ b/drivers/net/ethernet/mellanox/mlx4/catas.c
@@ -210,7 +210,7 @@ static void mlx4_handle_error_state(struct mlx4_dev_persistent *persist)
210 mutex_lock(&persist->interface_state_mutex); 210 mutex_lock(&persist->interface_state_mutex);
211 if (persist->interface_state & MLX4_INTERFACE_STATE_UP && 211 if (persist->interface_state & MLX4_INTERFACE_STATE_UP &&
212 !(persist->interface_state & MLX4_INTERFACE_STATE_DELETION)) { 212 !(persist->interface_state & MLX4_INTERFACE_STATE_DELETION)) {
213 err = mlx4_restart_one(persist->pdev, false, NULL); 213 err = mlx4_restart_one(persist->pdev);
214 mlx4_info(persist->dev, "mlx4_restart_one was ended, ret=%d\n", 214 mlx4_info(persist->dev, "mlx4_restart_one was ended, ret=%d\n",
215 err); 215 err);
216 } 216 }
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 07c204bd3fc4..ef3f3d06ff1e 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -3931,26 +3931,43 @@ static void mlx4_devlink_param_load_driverinit_values(struct devlink *devlink)
3931 } 3931 }
3932} 3932}
3933 3933
3934static int mlx4_devlink_reload(struct devlink *devlink, 3934static void mlx4_restart_one_down(struct pci_dev *pdev);
3935 struct netlink_ext_ack *extack) 3935static int mlx4_restart_one_up(struct pci_dev *pdev, bool reload,
3936 struct devlink *devlink);
3937
3938static int mlx4_devlink_reload_down(struct devlink *devlink,
3939 struct netlink_ext_ack *extack)
3936{ 3940{
3937 struct mlx4_priv *priv = devlink_priv(devlink); 3941 struct mlx4_priv *priv = devlink_priv(devlink);
3938 struct mlx4_dev *dev = &priv->dev; 3942 struct mlx4_dev *dev = &priv->dev;
3939 struct mlx4_dev_persistent *persist = dev->persist; 3943 struct mlx4_dev_persistent *persist = dev->persist;
3940 int err;
3941 3944
3942 if (persist->num_vfs) 3945 if (persist->num_vfs)
3943 mlx4_warn(persist->dev, "Reload performed on PF, will cause reset on operating Virtual Functions\n"); 3946 mlx4_warn(persist->dev, "Reload performed on PF, will cause reset on operating Virtual Functions\n");
3944 err = mlx4_restart_one(persist->pdev, true, devlink); 3947 mlx4_restart_one_down(persist->pdev);
3948 return 0;
3949}
3950
3951static int mlx4_devlink_reload_up(struct devlink *devlink,
3952 struct netlink_ext_ack *extack)
3953{
3954 struct mlx4_priv *priv = devlink_priv(devlink);
3955 struct mlx4_dev *dev = &priv->dev;
3956 struct mlx4_dev_persistent *persist = dev->persist;
3957 int err;
3958
3959 err = mlx4_restart_one_up(persist->pdev, true, devlink);
3945 if (err) 3960 if (err)
3946 mlx4_err(persist->dev, "mlx4_restart_one failed, ret=%d\n", err); 3961 mlx4_err(persist->dev, "mlx4_restart_one_up failed, ret=%d\n",
3962 err);
3947 3963
3948 return err; 3964 return err;
3949} 3965}
3950 3966
3951static const struct devlink_ops mlx4_devlink_ops = { 3967static const struct devlink_ops mlx4_devlink_ops = {
3952 .port_type_set = mlx4_devlink_port_type_set, 3968 .port_type_set = mlx4_devlink_port_type_set,
3953 .reload = mlx4_devlink_reload, 3969 .reload_down = mlx4_devlink_reload_down,
3970 .reload_up = mlx4_devlink_reload_up,
3954}; 3971};
3955 3972
3956static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) 3973static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -4163,7 +4180,13 @@ static int restore_current_port_types(struct mlx4_dev *dev,
4163 return err; 4180 return err;
4164} 4181}
4165 4182
4166int mlx4_restart_one(struct pci_dev *pdev, bool reload, struct devlink *devlink) 4183static void mlx4_restart_one_down(struct pci_dev *pdev)
4184{
4185 mlx4_unload_one(pdev);
4186}
4187
4188static int mlx4_restart_one_up(struct pci_dev *pdev, bool reload,
4189 struct devlink *devlink)
4167{ 4190{
4168 struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev); 4191 struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev);
4169 struct mlx4_dev *dev = persist->dev; 4192 struct mlx4_dev *dev = persist->dev;
@@ -4175,7 +4198,6 @@ int mlx4_restart_one(struct pci_dev *pdev, bool reload, struct devlink *devlink)
4175 total_vfs = dev->persist->num_vfs; 4198 total_vfs = dev->persist->num_vfs;
4176 memcpy(nvfs, dev->persist->nvfs, sizeof(dev->persist->nvfs)); 4199 memcpy(nvfs, dev->persist->nvfs, sizeof(dev->persist->nvfs));
4177 4200
4178 mlx4_unload_one(pdev);
4179 if (reload) 4201 if (reload)
4180 mlx4_devlink_param_load_driverinit_values(devlink); 4202 mlx4_devlink_param_load_driverinit_values(devlink);
4181 err = mlx4_load_one(pdev, pci_dev_data, total_vfs, nvfs, priv, 1); 4203 err = mlx4_load_one(pdev, pci_dev_data, total_vfs, nvfs, priv, 1);
@@ -4194,6 +4216,12 @@ int mlx4_restart_one(struct pci_dev *pdev, bool reload, struct devlink *devlink)
4194 return err; 4216 return err;
4195} 4217}
4196 4218
4219int mlx4_restart_one(struct pci_dev *pdev)
4220{
4221 mlx4_restart_one_down(pdev);
4222 return mlx4_restart_one_up(pdev, false, NULL);
4223}
4224
4197#define MLX_SP(id) { PCI_VDEVICE(MELLANOX, id), MLX4_PCI_DEV_FORCE_SENSE_PORT } 4225#define MLX_SP(id) { PCI_VDEVICE(MELLANOX, id), MLX4_PCI_DEV_FORCE_SENSE_PORT }
4198#define MLX_VF(id) { PCI_VDEVICE(MELLANOX, id), MLX4_PCI_DEV_IS_VF } 4226#define MLX_VF(id) { PCI_VDEVICE(MELLANOX, id), MLX4_PCI_DEV_IS_VF }
4199#define MLX_GN(id) { PCI_VDEVICE(MELLANOX, id), 0 } 4227#define MLX_GN(id) { PCI_VDEVICE(MELLANOX, id), 0 }
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index 23f1b5b512c2..527b52e48276 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -1043,8 +1043,7 @@ int mlx4_catas_init(struct mlx4_dev *dev);
1043void mlx4_catas_end(struct mlx4_dev *dev); 1043void mlx4_catas_end(struct mlx4_dev *dev);
1044int mlx4_crdump_init(struct mlx4_dev *dev); 1044int mlx4_crdump_init(struct mlx4_dev *dev);
1045void mlx4_crdump_end(struct mlx4_dev *dev); 1045void mlx4_crdump_end(struct mlx4_dev *dev);
1046int mlx4_restart_one(struct pci_dev *pdev, bool reload, 1046int mlx4_restart_one(struct pci_dev *pdev);
1047 struct devlink *devlink);
1048int mlx4_register_device(struct mlx4_dev *dev); 1047int mlx4_register_device(struct mlx4_dev *dev);
1049void mlx4_unregister_device(struct mlx4_dev *dev); 1048void mlx4_unregister_device(struct mlx4_dev *dev);
1050void mlx4_dispatch_event(struct mlx4_dev *dev, enum mlx4_dev_event type, 1049void mlx4_dispatch_event(struct mlx4_dev *dev, enum mlx4_dev_event type,
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
index 963a2b4b61b1..3fa96076e8a5 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
@@ -80,7 +80,6 @@ struct mlxsw_core {
80 struct mlxsw_thermal *thermal; 80 struct mlxsw_thermal *thermal;
81 struct mlxsw_core_port *ports; 81 struct mlxsw_core_port *ports;
82 unsigned int max_ports; 82 unsigned int max_ports;
83 bool reload_fail;
84 bool fw_flash_in_progress; 83 bool fw_flash_in_progress;
85 unsigned long driver_priv[0]; 84 unsigned long driver_priv[0];
86 /* driver_priv has to be always the last item */ 85 /* driver_priv has to be always the last item */
@@ -984,23 +983,29 @@ mlxsw_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
984 return 0; 983 return 0;
985} 984}
986 985
987static int mlxsw_devlink_core_bus_device_reload(struct devlink *devlink, 986static int
988 struct netlink_ext_ack *extack) 987mlxsw_devlink_core_bus_device_reload_down(struct devlink *devlink,
988 struct netlink_ext_ack *extack)
989{ 989{
990 struct mlxsw_core *mlxsw_core = devlink_priv(devlink); 990 struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
991 int err;
992 991
993 if (!(mlxsw_core->bus->features & MLXSW_BUS_F_RESET)) 992 if (!(mlxsw_core->bus->features & MLXSW_BUS_F_RESET))
994 return -EOPNOTSUPP; 993 return -EOPNOTSUPP;
995 994
996 mlxsw_core_bus_device_unregister(mlxsw_core, true); 995 mlxsw_core_bus_device_unregister(mlxsw_core, true);
997 err = mlxsw_core_bus_device_register(mlxsw_core->bus_info, 996 return 0;
998 mlxsw_core->bus, 997}
999 mlxsw_core->bus_priv, true,
1000 devlink);
1001 mlxsw_core->reload_fail = !!err;
1002 998
1003 return err; 999static int
1000mlxsw_devlink_core_bus_device_reload_up(struct devlink *devlink,
1001 struct netlink_ext_ack *extack)
1002{
1003 struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
1004
1005 return mlxsw_core_bus_device_register(mlxsw_core->bus_info,
1006 mlxsw_core->bus,
1007 mlxsw_core->bus_priv, true,
1008 devlink);
1004} 1009}
1005 1010
1006static int mlxsw_devlink_flash_update(struct devlink *devlink, 1011static int mlxsw_devlink_flash_update(struct devlink *devlink,
@@ -1066,7 +1071,8 @@ mlxsw_devlink_trap_group_init(struct devlink *devlink,
1066} 1071}
1067 1072
1068static const struct devlink_ops mlxsw_devlink_ops = { 1073static const struct devlink_ops mlxsw_devlink_ops = {
1069 .reload = mlxsw_devlink_core_bus_device_reload, 1074 .reload_down = mlxsw_devlink_core_bus_device_reload_down,
1075 .reload_up = mlxsw_devlink_core_bus_device_reload_up,
1070 .port_type_set = mlxsw_devlink_port_type_set, 1076 .port_type_set = mlxsw_devlink_port_type_set,
1071 .port_split = mlxsw_devlink_port_split, 1077 .port_split = mlxsw_devlink_port_split,
1072 .port_unsplit = mlxsw_devlink_port_unsplit, 1078 .port_unsplit = mlxsw_devlink_port_unsplit,
@@ -1243,7 +1249,7 @@ void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core,
1243{ 1249{
1244 struct devlink *devlink = priv_to_devlink(mlxsw_core); 1250 struct devlink *devlink = priv_to_devlink(mlxsw_core);
1245 1251
1246 if (mlxsw_core->reload_fail) { 1252 if (devlink_is_reload_failed(devlink)) {
1247 if (!reload) 1253 if (!reload)
1248 /* Only the parts that were not de-initialized in the 1254 /* Only the parts that were not de-initialized in the
1249 * failed reload attempt need to be de-initialized. 1255 * failed reload attempt need to be de-initialized.
diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
index 39cdb6c18ec0..7fba7b271a57 100644
--- a/drivers/net/netdevsim/dev.c
+++ b/drivers/net/netdevsim/dev.c
@@ -521,8 +521,14 @@ static void nsim_dev_traps_exit(struct devlink *devlink)
521 kfree(nsim_dev->trap_data); 521 kfree(nsim_dev->trap_data);
522} 522}
523 523
524static int nsim_dev_reload(struct devlink *devlink, 524static int nsim_dev_reload_down(struct devlink *devlink,
525 struct netlink_ext_ack *extack) 525 struct netlink_ext_ack *extack)
526{
527 return 0;
528}
529
530static int nsim_dev_reload_up(struct devlink *devlink,
531 struct netlink_ext_ack *extack)
526{ 532{
527 enum nsim_resource_id res_ids[] = { 533 enum nsim_resource_id res_ids[] = {
528 NSIM_RESOURCE_IPV4_FIB, NSIM_RESOURCE_IPV4_FIB_RULES, 534 NSIM_RESOURCE_IPV4_FIB, NSIM_RESOURCE_IPV4_FIB_RULES,
@@ -638,7 +644,8 @@ nsim_dev_devlink_trap_action_set(struct devlink *devlink,
638} 644}
639 645
640static const struct devlink_ops nsim_dev_devlink_ops = { 646static const struct devlink_ops nsim_dev_devlink_ops = {
641 .reload = nsim_dev_reload, 647 .reload_down = nsim_dev_reload_down,
648 .reload_up = nsim_dev_reload_up,
642 .flash_update = nsim_dev_flash_update, 649 .flash_update = nsim_dev_flash_update,
643 .trap_init = nsim_dev_devlink_trap_init, 650 .trap_init = nsim_dev_devlink_trap_init,
644 .trap_action_set = nsim_dev_devlink_trap_action_set, 651 .trap_action_set = nsim_dev_devlink_trap_action_set,
diff --git a/include/net/devlink.h b/include/net/devlink.h
index 03e4d9244ff3..23e4b65ec9df 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -38,6 +38,7 @@ struct devlink {
38 struct device *dev; 38 struct device *dev;
39 possible_net_t _net; 39 possible_net_t _net;
40 struct mutex lock; 40 struct mutex lock;
41 bool reload_failed;
41 char priv[0] __aligned(NETDEV_ALIGN); 42 char priv[0] __aligned(NETDEV_ALIGN);
42}; 43};
43 44
@@ -642,7 +643,10 @@ enum devlink_trap_group_generic_id {
642 } 643 }
643 644
644struct devlink_ops { 645struct devlink_ops {
645 int (*reload)(struct devlink *devlink, struct netlink_ext_ack *extack); 646 int (*reload_down)(struct devlink *devlink,
647 struct netlink_ext_ack *extack);
648 int (*reload_up)(struct devlink *devlink,
649 struct netlink_ext_ack *extack);
646 int (*port_type_set)(struct devlink_port *devlink_port, 650 int (*port_type_set)(struct devlink_port *devlink_port,
647 enum devlink_port_type port_type); 651 enum devlink_port_type port_type);
648 int (*port_split)(struct devlink *devlink, unsigned int port_index, 652 int (*port_split)(struct devlink *devlink, unsigned int port_index,
@@ -942,6 +946,8 @@ void
942devlink_health_reporter_state_update(struct devlink_health_reporter *reporter, 946devlink_health_reporter_state_update(struct devlink_health_reporter *reporter,
943 enum devlink_health_reporter_state state); 947 enum devlink_health_reporter_state state);
944 948
949bool devlink_is_reload_failed(const struct devlink *devlink);
950
945void devlink_flash_update_begin_notify(struct devlink *devlink); 951void devlink_flash_update_begin_notify(struct devlink *devlink);
946void devlink_flash_update_end_notify(struct devlink *devlink); 952void devlink_flash_update_end_notify(struct devlink *devlink);
947void devlink_flash_update_status_notify(struct devlink *devlink, 953void devlink_flash_update_status_notify(struct devlink *devlink,
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index 8da5365850cd..580b7a2e40e1 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -419,6 +419,8 @@ enum devlink_attr {
419 DEVLINK_ATTR_TRAP_METADATA, /* nested */ 419 DEVLINK_ATTR_TRAP_METADATA, /* nested */
420 DEVLINK_ATTR_TRAP_GROUP_NAME, /* string */ 420 DEVLINK_ATTR_TRAP_GROUP_NAME, /* string */
421 421
422 DEVLINK_ATTR_RELOAD_FAILED, /* u8 0 or 1 */
423
422 /* add new attributes above here, update the policy in devlink.c */ 424 /* add new attributes above here, update the policy in devlink.c */
423 425
424 __DEVLINK_ATTR_MAX, 426 __DEVLINK_ATTR_MAX,
diff --git a/net/core/devlink.c b/net/core/devlink.c
index 4a2fb94c44cf..e48680efe54a 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -471,6 +471,8 @@ static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
471 471
472 if (devlink_nl_put_handle(msg, devlink)) 472 if (devlink_nl_put_handle(msg, devlink))
473 goto nla_put_failure; 473 goto nla_put_failure;
474 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_FAILED, devlink->reload_failed))
475 goto nla_put_failure;
474 476
475 genlmsg_end(msg, hdr); 477 genlmsg_end(msg, hdr);
476 return 0; 478 return 0;
@@ -2672,12 +2674,32 @@ devlink_resources_validate(struct devlink *devlink,
2672 return err; 2674 return err;
2673} 2675}
2674 2676
2677static bool devlink_reload_supported(struct devlink *devlink)
2678{
2679 return devlink->ops->reload_down && devlink->ops->reload_up;
2680}
2681
2682static void devlink_reload_failed_set(struct devlink *devlink,
2683 bool reload_failed)
2684{
2685 if (devlink->reload_failed == reload_failed)
2686 return;
2687 devlink->reload_failed = reload_failed;
2688 devlink_notify(devlink, DEVLINK_CMD_NEW);
2689}
2690
2691bool devlink_is_reload_failed(const struct devlink *devlink)
2692{
2693 return devlink->reload_failed;
2694}
2695EXPORT_SYMBOL_GPL(devlink_is_reload_failed);
2696
2675static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info) 2697static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)
2676{ 2698{
2677 struct devlink *devlink = info->user_ptr[0]; 2699 struct devlink *devlink = info->user_ptr[0];
2678 int err; 2700 int err;
2679 2701
2680 if (!devlink->ops->reload) 2702 if (!devlink_reload_supported(devlink))
2681 return -EOPNOTSUPP; 2703 return -EOPNOTSUPP;
2682 2704
2683 err = devlink_resources_validate(devlink, NULL, info); 2705 err = devlink_resources_validate(devlink, NULL, info);
@@ -2685,7 +2707,12 @@ static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)
2685 NL_SET_ERR_MSG_MOD(info->extack, "resources size validation failed"); 2707 NL_SET_ERR_MSG_MOD(info->extack, "resources size validation failed");
2686 return err; 2708 return err;
2687 } 2709 }
2688 return devlink->ops->reload(devlink, info->extack); 2710 err = devlink->ops->reload_down(devlink, info->extack);
2711 if (err)
2712 return err;
2713 err = devlink->ops->reload_up(devlink, info->extack);
2714 devlink_reload_failed_set(devlink, !!err);
2715 return err;
2689} 2716}
2690 2717
2691static int devlink_nl_flash_update_fill(struct sk_buff *msg, 2718static int devlink_nl_flash_update_fill(struct sk_buff *msg,
@@ -7150,7 +7177,7 @@ __devlink_param_driverinit_value_set(struct devlink *devlink,
7150int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id, 7177int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
7151 union devlink_param_value *init_val) 7178 union devlink_param_value *init_val)
7152{ 7179{
7153 if (!devlink->ops->reload) 7180 if (!devlink_reload_supported(devlink))
7154 return -EOPNOTSUPP; 7181 return -EOPNOTSUPP;
7155 7182
7156 return __devlink_param_driverinit_value_get(&devlink->param_list, 7183 return __devlink_param_driverinit_value_get(&devlink->param_list,
@@ -7197,7 +7224,7 @@ int devlink_port_param_driverinit_value_get(struct devlink_port *devlink_port,
7197{ 7224{
7198 struct devlink *devlink = devlink_port->devlink; 7225 struct devlink *devlink = devlink_port->devlink;
7199 7226
7200 if (!devlink->ops->reload) 7227 if (!devlink_reload_supported(devlink))
7201 return -EOPNOTSUPP; 7228 return -EOPNOTSUPP;
7202 7229
7203 return __devlink_param_driverinit_value_get(&devlink_port->param_list, 7230 return __devlink_param_driverinit_value_get(&devlink_port->param_list,