@@ -113,6 +113,7 @@ struct mlxsw_core {
113113 struct mlxsw_thermal * thermal ;
114114 struct mlxsw_core_port * ports ;
115115 unsigned int max_ports ;
116+ bool reload_fail ;
116117 unsigned long driver_priv [0 ];
117118 /* driver_priv has to be always the last item */
118119};
@@ -962,7 +963,28 @@ mlxsw_devlink_sb_occ_tc_port_bind_get(struct devlink_port *devlink_port,
962963 pool_type , p_cur , p_max );
963964}
964965
966+ static 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+
965986static const struct devlink_ops mlxsw_devlink_ops = {
987+ .reload = mlxsw_devlink_core_bus_device_reload ,
966988 .port_type_set = mlxsw_devlink_port_type_set ,
967989 .port_split = mlxsw_devlink_port_split ,
968990 .port_unsplit = mlxsw_devlink_port_unsplit ,
@@ -980,23 +1002,26 @@ static const struct devlink_ops mlxsw_devlink_ops = {
9801002
9811003int mlxsw_core_bus_device_register (const struct mlxsw_bus_info * mlxsw_bus_info ,
9821004 const struct mlxsw_bus * mlxsw_bus ,
983- void * bus_priv )
1005+ void * bus_priv , bool reload ,
1006+ struct devlink * devlink )
9841007{
9851008 const char * device_kind = mlxsw_bus_info -> device_kind ;
9861009 struct mlxsw_core * mlxsw_core ;
9871010 struct mlxsw_driver * mlxsw_driver ;
988- struct devlink * devlink ;
9891011 size_t alloc_size ;
9901012 int err ;
9911013
9921014 mlxsw_driver = mlxsw_core_driver_get (device_kind );
9931015 if (!mlxsw_driver )
9941016 return - EINVAL ;
995- alloc_size = sizeof (* mlxsw_core ) + mlxsw_driver -> priv_size ;
996- devlink = devlink_alloc (& mlxsw_devlink_ops , alloc_size );
997- if (!devlink ) {
998- err = - ENOMEM ;
999- goto err_devlink_alloc ;
1017+
1018+ if (!reload ) {
1019+ alloc_size = sizeof (* mlxsw_core ) + mlxsw_driver -> priv_size ;
1020+ devlink = devlink_alloc (& mlxsw_devlink_ops , alloc_size );
1021+ if (!devlink ) {
1022+ err = - ENOMEM ;
1023+ goto err_devlink_alloc ;
1024+ }
10001025 }
10011026
10021027 mlxsw_core = devlink_priv (devlink );
@@ -1012,7 +1037,7 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
10121037 if (err )
10131038 goto err_bus_init ;
10141039
1015- if (mlxsw_driver -> resources_register ) {
1040+ if (mlxsw_driver -> resources_register && ! reload ) {
10161041 err = mlxsw_driver -> resources_register (mlxsw_core );
10171042 if (err )
10181043 goto err_register_resources ;
@@ -1038,9 +1063,11 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
10381063 if (err )
10391064 goto err_emad_init ;
10401065
1041- err = devlink_register (devlink , mlxsw_bus_info -> dev );
1042- if (err )
1043- goto err_devlink_register ;
1066+ if (!reload ) {
1067+ err = devlink_register (devlink , mlxsw_bus_info -> dev );
1068+ if (err )
1069+ goto err_devlink_register ;
1070+ }
10441071
10451072 err = mlxsw_hwmon_init (mlxsw_core , mlxsw_bus_info , & mlxsw_core -> hwmon );
10461073 if (err )
@@ -1063,7 +1090,8 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
10631090 mlxsw_thermal_fini (mlxsw_core -> thermal );
10641091err_thermal_init :
10651092err_hwmon_init :
1066- devlink_unregister (devlink );
1093+ if (!reload )
1094+ devlink_unregister (devlink );
10671095err_devlink_register :
10681096 mlxsw_emad_fini (mlxsw_core );
10691097err_emad_init :
@@ -1073,29 +1101,40 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
10731101err_ports_init :
10741102 mlxsw_bus -> fini (bus_priv );
10751103err_bus_init :
1076- devlink_resources_unregister (devlink , NULL );
1104+ if (!reload )
1105+ devlink_resources_unregister (devlink , NULL );
10771106err_register_resources :
1078- devlink_free (devlink );
1107+ if (!reload )
1108+ devlink_free (devlink );
10791109err_devlink_alloc :
10801110 mlxsw_core_driver_put (device_kind );
10811111 return err ;
10821112}
10831113EXPORT_SYMBOL (mlxsw_core_bus_device_register );
10841114
1085- void mlxsw_core_bus_device_unregister (struct mlxsw_core * mlxsw_core )
1115+ void mlxsw_core_bus_device_unregister (struct mlxsw_core * mlxsw_core ,
1116+ bool reload )
10861117{
10871118 const char * device_kind = mlxsw_core -> bus_info -> device_kind ;
10881119 struct devlink * devlink = priv_to_devlink (mlxsw_core );
10891120
1121+ if (mlxsw_core -> reload_fail )
1122+ goto reload_fail ;
1123+
10901124 if (mlxsw_core -> driver -> fini )
10911125 mlxsw_core -> driver -> fini (mlxsw_core );
10921126 mlxsw_thermal_fini (mlxsw_core -> thermal );
1093- devlink_unregister (devlink );
1127+ if (!reload )
1128+ devlink_unregister (devlink );
10941129 mlxsw_emad_fini (mlxsw_core );
10951130 kfree (mlxsw_core -> lag .mapping );
10961131 mlxsw_ports_fini (mlxsw_core );
1097- devlink_resources_unregister (devlink , NULL );
1132+ if (!reload )
1133+ devlink_resources_unregister (devlink , NULL );
10981134 mlxsw_core -> bus -> fini (mlxsw_core -> bus_priv );
1135+ if (reload )
1136+ return ;
1137+ reload_fail :
10991138 devlink_free (devlink );
11001139 mlxsw_core_driver_put (device_kind );
11011140}
0 commit comments