@@ -87,13 +87,31 @@ static const char *mlxsw_linecard_type_name(struct mlxsw_linecard *linecard)
8787 return linecard -> name ;
8888}
8989
90+ struct mlxsw_linecard_device_info {
91+ u16 fw_major ;
92+ u16 fw_minor ;
93+ u16 fw_sub_minor ;
94+ };
95+
9096struct mlxsw_linecard_device {
9197 struct list_head list ;
9298 u8 index ;
9399 struct mlxsw_linecard * linecard ;
94100 struct devlink_linecard_device * devlink_device ;
101+ struct mlxsw_linecard_device_info info ;
95102};
96103
104+ static struct mlxsw_linecard_device *
105+ mlxsw_linecard_device_lookup (struct mlxsw_linecard * linecard , u8 index )
106+ {
107+ struct mlxsw_linecard_device * device ;
108+
109+ list_for_each_entry (device , & linecard -> device_list , list )
110+ if (device -> index == index )
111+ return device ;
112+ return NULL ;
113+ }
114+
97115static int mlxsw_linecard_device_attach (struct mlxsw_core * mlxsw_core ,
98116 struct mlxsw_linecard * linecard ,
99117 u8 device_index , bool flash_owner )
@@ -108,7 +126,7 @@ static int mlxsw_linecard_device_attach(struct mlxsw_core *mlxsw_core,
108126 device -> linecard = linecard ;
109127
110128 device -> devlink_device = devlink_linecard_device_create (linecard -> devlink_linecard ,
111- device_index , NULL );
129+ device_index , device );
112130 if (IS_ERR (device -> devlink_device )) {
113131 err = PTR_ERR (device -> devlink_device );
114132 goto err_devlink_linecard_device_attach ;
@@ -177,6 +195,77 @@ static int mlxsw_linecard_devices_attach(struct mlxsw_linecard *linecard)
177195 return err ;
178196}
179197
198+ static void mlxsw_linecard_device_update (struct mlxsw_linecard * linecard ,
199+ u8 device_index ,
200+ struct mlxsw_linecard_device_info * info )
201+ {
202+ struct mlxsw_linecard_device * device ;
203+
204+ device = mlxsw_linecard_device_lookup (linecard , device_index );
205+ if (!device )
206+ return ;
207+ device -> info = * info ;
208+ }
209+
210+ static int mlxsw_linecard_devices_update (struct mlxsw_linecard * linecard )
211+ {
212+ struct mlxsw_core * mlxsw_core = linecard -> linecards -> mlxsw_core ;
213+ u8 msg_seq = 0 ;
214+
215+ do {
216+ struct mlxsw_linecard_device_info info ;
217+ char mddq_pl [MLXSW_REG_MDDQ_LEN ];
218+ bool data_valid ;
219+ u8 device_index ;
220+ int err ;
221+
222+ mlxsw_reg_mddq_device_info_pack (mddq_pl , linecard -> slot_index ,
223+ msg_seq );
224+ err = mlxsw_reg_query (mlxsw_core , MLXSW_REG (mddq ), mddq_pl );
225+ if (err )
226+ return err ;
227+ mlxsw_reg_mddq_device_info_unpack (mddq_pl , & msg_seq ,
228+ & data_valid , NULL ,
229+ & device_index ,
230+ & info .fw_major ,
231+ & info .fw_minor ,
232+ & info .fw_sub_minor );
233+ if (!data_valid )
234+ break ;
235+ mlxsw_linecard_device_update (linecard , device_index , & info );
236+ } while (msg_seq );
237+
238+ return 0 ;
239+ }
240+
241+ static int
242+ mlxsw_linecard_device_info_get (struct devlink_linecard_device * devlink_linecard_device ,
243+ void * priv , struct devlink_info_req * req ,
244+ struct netlink_ext_ack * extack )
245+ {
246+ struct mlxsw_linecard_device * device = priv ;
247+ struct mlxsw_linecard_device_info * info ;
248+ struct mlxsw_linecard * linecard ;
249+ char buf [32 ];
250+
251+ linecard = device -> linecard ;
252+ mutex_lock (& linecard -> lock );
253+ if (!linecard -> active ) {
254+ mutex_unlock (& linecard -> lock );
255+ return 0 ;
256+ }
257+
258+ info = & device -> info ;
259+
260+ sprintf (buf , "%u.%u.%u" , info -> fw_major , info -> fw_minor ,
261+ info -> fw_sub_minor );
262+ mutex_unlock (& linecard -> lock );
263+
264+ return devlink_info_version_running_put (req ,
265+ DEVLINK_INFO_VERSION_GENERIC_FW ,
266+ buf );
267+ }
268+
180269static void mlxsw_linecard_provision_fail (struct mlxsw_linecard * linecard )
181270{
182271 linecard -> provisioned = false;
@@ -390,11 +479,18 @@ static int mlxsw_linecard_ready_clear(struct mlxsw_linecard *linecard)
390479 return 0 ;
391480}
392481
393- static void mlxsw_linecard_active_set (struct mlxsw_linecard * linecard )
482+ static int mlxsw_linecard_active_set (struct mlxsw_linecard * linecard )
394483{
484+ int err ;
485+
486+ err = mlxsw_linecard_devices_update (linecard );
487+ if (err )
488+ return err ;
489+
395490 mlxsw_linecard_active_ops_call (linecard );
396491 linecard -> active = true;
397492 devlink_linecard_activate (linecard -> devlink_linecard );
493+ return 0 ;
398494}
399495
400496static void mlxsw_linecard_active_clear (struct mlxsw_linecard * linecard )
@@ -443,8 +539,11 @@ static int mlxsw_linecard_status_process(struct mlxsw_linecards *linecards,
443539 goto out ;
444540 }
445541
446- if (active && linecard -> active != active )
447- mlxsw_linecard_active_set (linecard );
542+ if (active && linecard -> active != active ) {
543+ err = mlxsw_linecard_active_set (linecard );
544+ if (err )
545+ goto out ;
546+ }
448547
449548 if (!active && linecard -> active != active )
450549 mlxsw_linecard_active_clear (linecard );
@@ -872,6 +971,7 @@ static const struct devlink_linecard_ops mlxsw_linecard_ops = {
872971 .types_count = mlxsw_linecard_types_count ,
873972 .types_get = mlxsw_linecard_types_get ,
874973 .info_get = mlxsw_linecard_info_get ,
974+ .device_info_get = mlxsw_linecard_device_info_get ,
875975};
876976
877977struct mlxsw_linecard_status_event {
0 commit comments