aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/core.c73
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/core.h5
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/i2c.c5
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/pci.c5
4 files changed, 65 insertions, 23 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
index c93512b16121..3529b545675d 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
@@ -113,6 +113,7 @@ struct mlxsw_core {
113 struct mlxsw_thermal *thermal; 113 struct mlxsw_thermal *thermal;
114 struct mlxsw_core_port *ports; 114 struct mlxsw_core_port *ports;
115 unsigned int max_ports; 115 unsigned int max_ports;
116 bool reload_fail;
116 unsigned long driver_priv[0]; 117 unsigned long driver_priv[0];
117 /* driver_priv has to be always the last item */ 118 /* driver_priv has to be always the last item */
118}; 119};
@@ -962,7 +963,28 @@ mlxsw_devlink_sb_occ_tc_port_bind_get(struct devlink_port *devlink_port,
962 pool_type, p_cur, p_max); 963 pool_type, p_cur, p_max);
963} 964}
964 965
966static int mlxsw_devlink_core_bus_device_reload(struct devlink *devlink)
967{
968 struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
969 const struct mlxsw_bus *mlxsw_bus = mlxsw_core->bus;
970 int err;
971
972 if (!mlxsw_bus->reset)
973 return -EOPNOTSUPP;
974
975 mlxsw_core_bus_device_unregister(mlxsw_core, true);
976 mlxsw_bus->reset(mlxsw_core->bus_priv);
977 err = mlxsw_core_bus_device_register(mlxsw_core->bus_info,
978 mlxsw_core->bus,
979 mlxsw_core->bus_priv, true,
980 devlink);
981 if (err)
982 mlxsw_core->reload_fail = true;
983 return err;
984}
985
965static const struct devlink_ops mlxsw_devlink_ops = { 986static const struct devlink_ops mlxsw_devlink_ops = {
987 .reload = mlxsw_devlink_core_bus_device_reload,
966 .port_type_set = mlxsw_devlink_port_type_set, 988 .port_type_set = mlxsw_devlink_port_type_set,
967 .port_split = mlxsw_devlink_port_split, 989 .port_split = mlxsw_devlink_port_split,
968 .port_unsplit = mlxsw_devlink_port_unsplit, 990 .port_unsplit = mlxsw_devlink_port_unsplit,
@@ -980,23 +1002,26 @@ static const struct devlink_ops mlxsw_devlink_ops = {
980 1002
981int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info, 1003int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
982 const struct mlxsw_bus *mlxsw_bus, 1004 const struct mlxsw_bus *mlxsw_bus,
983 void *bus_priv) 1005 void *bus_priv, bool reload,
1006 struct devlink *devlink)
984{ 1007{
985 const char *device_kind = mlxsw_bus_info->device_kind; 1008 const char *device_kind = mlxsw_bus_info->device_kind;
986 struct mlxsw_core *mlxsw_core; 1009 struct mlxsw_core *mlxsw_core;
987 struct mlxsw_driver *mlxsw_driver; 1010 struct mlxsw_driver *mlxsw_driver;
988 struct devlink *devlink;
989 size_t alloc_size; 1011 size_t alloc_size;
990 int err; 1012 int err;
991 1013
992 mlxsw_driver = mlxsw_core_driver_get(device_kind); 1014 mlxsw_driver = mlxsw_core_driver_get(device_kind);
993 if (!mlxsw_driver) 1015 if (!mlxsw_driver)
994 return -EINVAL; 1016 return -EINVAL;
995 alloc_size = sizeof(*mlxsw_core) + mlxsw_driver->priv_size; 1017
996 devlink = devlink_alloc(&mlxsw_devlink_ops, alloc_size); 1018 if (!reload) {
997 if (!devlink) { 1019 alloc_size = sizeof(*mlxsw_core) + mlxsw_driver->priv_size;
998 err = -ENOMEM; 1020 devlink = devlink_alloc(&mlxsw_devlink_ops, alloc_size);
999 goto err_devlink_alloc; 1021 if (!devlink) {
1022 err = -ENOMEM;
1023 goto err_devlink_alloc;
1024 }
1000 } 1025 }
1001 1026
1002 mlxsw_core = devlink_priv(devlink); 1027 mlxsw_core = devlink_priv(devlink);
@@ -1012,7 +1037,7 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
1012 if (err) 1037 if (err)
1013 goto err_bus_init; 1038 goto err_bus_init;
1014 1039
1015 if (mlxsw_driver->resources_register) { 1040 if (mlxsw_driver->resources_register && !reload) {
1016 err = mlxsw_driver->resources_register(mlxsw_core); 1041 err = mlxsw_driver->resources_register(mlxsw_core);
1017 if (err) 1042 if (err)
1018 goto err_register_resources; 1043 goto err_register_resources;
@@ -1038,9 +1063,11 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
1038 if (err) 1063 if (err)
1039 goto err_emad_init; 1064 goto err_emad_init;
1040 1065
1041 err = devlink_register(devlink, mlxsw_bus_info->dev); 1066 if (!reload) {
1042 if (err) 1067 err = devlink_register(devlink, mlxsw_bus_info->dev);
1043 goto err_devlink_register; 1068 if (err)
1069 goto err_devlink_register;
1070 }
1044 1071
1045 err = mlxsw_hwmon_init(mlxsw_core, mlxsw_bus_info, &mlxsw_core->hwmon); 1072 err = mlxsw_hwmon_init(mlxsw_core, mlxsw_bus_info, &mlxsw_core->hwmon);
1046 if (err) 1073 if (err)
@@ -1063,7 +1090,8 @@ err_driver_init:
1063 mlxsw_thermal_fini(mlxsw_core->thermal); 1090 mlxsw_thermal_fini(mlxsw_core->thermal);
1064err_thermal_init: 1091err_thermal_init:
1065err_hwmon_init: 1092err_hwmon_init:
1066 devlink_unregister(devlink); 1093 if (!reload)
1094 devlink_unregister(devlink);
1067err_devlink_register: 1095err_devlink_register:
1068 mlxsw_emad_fini(mlxsw_core); 1096 mlxsw_emad_fini(mlxsw_core);
1069err_emad_init: 1097err_emad_init:
@@ -1073,29 +1101,40 @@ err_alloc_lag_mapping:
1073err_ports_init: 1101err_ports_init:
1074 mlxsw_bus->fini(bus_priv); 1102 mlxsw_bus->fini(bus_priv);
1075err_bus_init: 1103err_bus_init:
1076 devlink_resources_unregister(devlink, NULL); 1104 if (!reload)
1105 devlink_resources_unregister(devlink, NULL);
1077err_register_resources: 1106err_register_resources:
1078 devlink_free(devlink); 1107 if (!reload)
1108 devlink_free(devlink);
1079err_devlink_alloc: 1109err_devlink_alloc:
1080 mlxsw_core_driver_put(device_kind); 1110 mlxsw_core_driver_put(device_kind);
1081 return err; 1111 return err;
1082} 1112}
1083EXPORT_SYMBOL(mlxsw_core_bus_device_register); 1113EXPORT_SYMBOL(mlxsw_core_bus_device_register);
1084 1114
1085void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core) 1115void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core,
1116 bool reload)
1086{ 1117{
1087 const char *device_kind = mlxsw_core->bus_info->device_kind; 1118 const char *device_kind = mlxsw_core->bus_info->device_kind;
1088 struct devlink *devlink = priv_to_devlink(mlxsw_core); 1119 struct devlink *devlink = priv_to_devlink(mlxsw_core);
1089 1120
1121 if (mlxsw_core->reload_fail)
1122 goto reload_fail;
1123
1090 if (mlxsw_core->driver->fini) 1124 if (mlxsw_core->driver->fini)
1091 mlxsw_core->driver->fini(mlxsw_core); 1125 mlxsw_core->driver->fini(mlxsw_core);
1092 mlxsw_thermal_fini(mlxsw_core->thermal); 1126 mlxsw_thermal_fini(mlxsw_core->thermal);
1093 devlink_unregister(devlink); 1127 if (!reload)
1128 devlink_unregister(devlink);
1094 mlxsw_emad_fini(mlxsw_core); 1129 mlxsw_emad_fini(mlxsw_core);
1095 kfree(mlxsw_core->lag.mapping); 1130 kfree(mlxsw_core->lag.mapping);
1096 mlxsw_ports_fini(mlxsw_core); 1131 mlxsw_ports_fini(mlxsw_core);
1097 devlink_resources_unregister(devlink, NULL); 1132 if (!reload)
1133 devlink_resources_unregister(devlink, NULL);
1098 mlxsw_core->bus->fini(mlxsw_core->bus_priv); 1134 mlxsw_core->bus->fini(mlxsw_core->bus_priv);
1135 if (reload)
1136 return;
1137reload_fail:
1099 devlink_free(devlink); 1138 devlink_free(devlink);
1100 mlxsw_core_driver_put(device_kind); 1139 mlxsw_core_driver_put(device_kind);
1101} 1140}
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h
index e44061dfe8c7..5ddafd74dc00 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.h
@@ -66,8 +66,9 @@ void mlxsw_core_driver_unregister(struct mlxsw_driver *mlxsw_driver);
66 66
67int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info, 67int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
68 const struct mlxsw_bus *mlxsw_bus, 68 const struct mlxsw_bus *mlxsw_bus,
69 void *bus_priv); 69 void *bus_priv, bool reload,
70void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core); 70 struct devlink *devlink);
71void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core, bool reload);
71 72
72struct mlxsw_tx_info { 73struct mlxsw_tx_info {
73 u8 local_port; 74 u8 local_port;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/i2c.c b/drivers/net/ethernet/mellanox/mlxsw/i2c.c
index c0dcfa05b077..25f9915ebd82 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/i2c.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/i2c.c
@@ -539,7 +539,8 @@ static int mlxsw_i2c_probe(struct i2c_client *client,
539 mlxsw_i2c->dev = &client->dev; 539 mlxsw_i2c->dev = &client->dev;
540 540
541 err = mlxsw_core_bus_device_register(&mlxsw_i2c->bus_info, 541 err = mlxsw_core_bus_device_register(&mlxsw_i2c->bus_info,
542 &mlxsw_i2c_bus, mlxsw_i2c); 542 &mlxsw_i2c_bus, mlxsw_i2c, false,
543 NULL);
543 if (err) { 544 if (err) {
544 dev_err(&client->dev, "Fail to register core bus\n"); 545 dev_err(&client->dev, "Fail to register core bus\n");
545 return err; 546 return err;
@@ -557,7 +558,7 @@ static int mlxsw_i2c_remove(struct i2c_client *client)
557{ 558{
558 struct mlxsw_i2c *mlxsw_i2c = i2c_get_clientdata(client); 559 struct mlxsw_i2c *mlxsw_i2c = i2c_get_clientdata(client);
559 560
560 mlxsw_core_bus_device_unregister(mlxsw_i2c->core); 561 mlxsw_core_bus_device_unregister(mlxsw_i2c->core, false);
561 mutex_destroy(&mlxsw_i2c->cmd.lock); 562 mutex_destroy(&mlxsw_i2c->cmd.lock);
562 563
563 return 0; 564 return 0;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c
index 58ab18845928..85faa87bf42d 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/pci.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c
@@ -1739,7 +1739,8 @@ static int mlxsw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1739 mlxsw_pci->id = id; 1739 mlxsw_pci->id = id;
1740 1740
1741 err = mlxsw_core_bus_device_register(&mlxsw_pci->bus_info, 1741 err = mlxsw_core_bus_device_register(&mlxsw_pci->bus_info,
1742 &mlxsw_pci_bus, mlxsw_pci); 1742 &mlxsw_pci_bus, mlxsw_pci, false,
1743 NULL);
1743 if (err) { 1744 if (err) {
1744 dev_err(&pdev->dev, "cannot register bus device\n"); 1745 dev_err(&pdev->dev, "cannot register bus device\n");
1745 goto err_bus_device_register; 1746 goto err_bus_device_register;
@@ -1767,7 +1768,7 @@ static void mlxsw_pci_remove(struct pci_dev *pdev)
1767{ 1768{
1768 struct mlxsw_pci *mlxsw_pci = pci_get_drvdata(pdev); 1769 struct mlxsw_pci *mlxsw_pci = pci_get_drvdata(pdev);
1769 1770
1770 mlxsw_core_bus_device_unregister(mlxsw_pci->core); 1771 mlxsw_core_bus_device_unregister(mlxsw_pci->core, false);
1771 mlxsw_pci_free_irq_vectors(mlxsw_pci); 1772 mlxsw_pci_free_irq_vectors(mlxsw_pci);
1772 iounmap(mlxsw_pci->hw_addr); 1773 iounmap(mlxsw_pci->hw_addr);
1773 pci_release_regions(mlxsw_pci->pdev); 1774 pci_release_regions(mlxsw_pci->pdev);