@@ -251,47 +251,19 @@ static void dsa_tree_teardown_default_cpu(struct dsa_switch_tree *dst)
251251
252252static int dsa_port_setup (struct dsa_port * dp )
253253{
254- struct dsa_switch * ds = dp -> ds ;
255- struct dsa_switch_tree * dst = ds -> dst ;
256- const unsigned char * id = (const unsigned char * )& dst -> index ;
257- const unsigned char len = sizeof (dst -> index );
258254 struct devlink_port * dlp = & dp -> devlink_port ;
259255 bool dsa_port_link_registered = false;
260- bool devlink_port_registered = false;
261- struct devlink_port_attrs attrs = {};
262- struct devlink * dl = ds -> devlink ;
263256 bool dsa_port_enabled = false;
264257 int err = 0 ;
265258
266- attrs .phys .port_number = dp -> index ;
267- memcpy (attrs .switch_id .id , id , len );
268- attrs .switch_id .id_len = len ;
269-
270259 if (dp -> setup )
271260 return 0 ;
272261
273262 switch (dp -> type ) {
274263 case DSA_PORT_TYPE_UNUSED :
275- memset (dlp , 0 , sizeof (* dlp ));
276- attrs .flavour = DEVLINK_PORT_FLAVOUR_UNUSED ;
277- devlink_port_attrs_set (dlp , & attrs );
278- err = devlink_port_register (dl , dlp , dp -> index );
279- if (err )
280- break ;
281-
282- devlink_port_registered = true;
283-
284264 dsa_port_disable (dp );
285265 break ;
286266 case DSA_PORT_TYPE_CPU :
287- memset (dlp , 0 , sizeof (* dlp ));
288- attrs .flavour = DEVLINK_PORT_FLAVOUR_CPU ;
289- devlink_port_attrs_set (dlp , & attrs );
290- err = devlink_port_register (dl , dlp , dp -> index );
291- if (err )
292- break ;
293- devlink_port_registered = true;
294-
295267 err = dsa_port_link_register_of (dp );
296268 if (err )
297269 break ;
@@ -304,14 +276,6 @@ static int dsa_port_setup(struct dsa_port *dp)
304276
305277 break ;
306278 case DSA_PORT_TYPE_DSA :
307- memset (dlp , 0 , sizeof (* dlp ));
308- attrs .flavour = DEVLINK_PORT_FLAVOUR_DSA ;
309- devlink_port_attrs_set (dlp , & attrs );
310- err = devlink_port_register (dl , dlp , dp -> index );
311- if (err )
312- break ;
313- devlink_port_registered = true;
314-
315279 err = dsa_port_link_register_of (dp );
316280 if (err )
317281 break ;
@@ -324,14 +288,6 @@ static int dsa_port_setup(struct dsa_port *dp)
324288
325289 break ;
326290 case DSA_PORT_TYPE_USER :
327- memset (dlp , 0 , sizeof (* dlp ));
328- attrs .flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL ;
329- devlink_port_attrs_set (dlp , & attrs );
330- err = devlink_port_register (dl , dlp , dp -> index );
331- if (err )
332- break ;
333- devlink_port_registered = true;
334-
335291 dp -> mac = of_get_mac_address (dp -> dn );
336292 err = dsa_slave_create (dp );
337293 if (err )
@@ -345,8 +301,6 @@ static int dsa_port_setup(struct dsa_port *dp)
345301 dsa_port_disable (dp );
346302 if (err && dsa_port_link_registered )
347303 dsa_port_link_unregister_of (dp );
348- if (err && devlink_port_registered )
349- devlink_port_unregister (dlp );
350304 if (err )
351305 return err ;
352306
@@ -355,30 +309,66 @@ static int dsa_port_setup(struct dsa_port *dp)
355309 return 0 ;
356310}
357311
358- static void dsa_port_teardown (struct dsa_port * dp )
312+ static int dsa_port_devlink_setup (struct dsa_port * dp )
359313{
360314 struct devlink_port * dlp = & dp -> devlink_port ;
315+ struct dsa_switch_tree * dst = dp -> ds -> dst ;
316+ struct devlink_port_attrs attrs = {};
317+ struct devlink * dl = dp -> ds -> devlink ;
318+ const unsigned char * id ;
319+ unsigned char len ;
320+ int err ;
361321
322+ id = (const unsigned char * )& dst -> index ;
323+ len = sizeof (dst -> index );
324+
325+ attrs .phys .port_number = dp -> index ;
326+ memcpy (attrs .switch_id .id , id , len );
327+ attrs .switch_id .id_len = len ;
328+ memset (dlp , 0 , sizeof (* dlp ));
329+
330+ switch (dp -> type ) {
331+ case DSA_PORT_TYPE_UNUSED :
332+ attrs .flavour = DEVLINK_PORT_FLAVOUR_UNUSED ;
333+ break ;
334+ case DSA_PORT_TYPE_CPU :
335+ attrs .flavour = DEVLINK_PORT_FLAVOUR_CPU ;
336+ break ;
337+ case DSA_PORT_TYPE_DSA :
338+ attrs .flavour = DEVLINK_PORT_FLAVOUR_DSA ;
339+ break ;
340+ case DSA_PORT_TYPE_USER :
341+ attrs .flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL ;
342+ break ;
343+ }
344+
345+ devlink_port_attrs_set (dlp , & attrs );
346+ err = devlink_port_register (dl , dlp , dp -> index );
347+
348+ if (!err )
349+ dp -> devlink_port_setup = true;
350+
351+ return err ;
352+ }
353+
354+ static void dsa_port_teardown (struct dsa_port * dp )
355+ {
362356 if (!dp -> setup )
363357 return ;
364358
365359 switch (dp -> type ) {
366360 case DSA_PORT_TYPE_UNUSED :
367- devlink_port_unregister (dlp );
368361 break ;
369362 case DSA_PORT_TYPE_CPU :
370363 dsa_port_disable (dp );
371364 dsa_tag_driver_put (dp -> tag_ops );
372- devlink_port_unregister (dlp );
373365 dsa_port_link_unregister_of (dp );
374366 break ;
375367 case DSA_PORT_TYPE_DSA :
376368 dsa_port_disable (dp );
377- devlink_port_unregister (dlp );
378369 dsa_port_link_unregister_of (dp );
379370 break ;
380371 case DSA_PORT_TYPE_USER :
381- devlink_port_unregister (dlp );
382372 if (dp -> slave ) {
383373 dsa_slave_destroy (dp -> slave );
384374 dp -> slave = NULL ;
@@ -389,6 +379,15 @@ static void dsa_port_teardown(struct dsa_port *dp)
389379 dp -> setup = false;
390380}
391381
382+ static void dsa_port_devlink_teardown (struct dsa_port * dp )
383+ {
384+ struct devlink_port * dlp = & dp -> devlink_port ;
385+
386+ if (dp -> devlink_port_setup )
387+ devlink_port_unregister (dlp );
388+ dp -> devlink_port_setup = false;
389+ }
390+
392391static int dsa_devlink_info_get (struct devlink * dl ,
393392 struct devlink_info_req * req ,
394393 struct netlink_ext_ack * extack )
@@ -408,6 +407,7 @@ static const struct devlink_ops dsa_devlink_ops = {
408407static int dsa_switch_setup (struct dsa_switch * ds )
409408{
410409 struct dsa_devlink_priv * dl_priv ;
410+ struct dsa_port * dp ;
411411 int err ;
412412
413413 if (ds -> setup )
@@ -433,9 +433,20 @@ static int dsa_switch_setup(struct dsa_switch *ds)
433433 if (err )
434434 goto free_devlink ;
435435
436+ /* Setup devlink port instances now, so that the switch
437+ * setup() can register regions etc, against the ports
438+ */
439+ list_for_each_entry (dp , & ds -> dst -> ports , list ) {
440+ if (dp -> ds == ds ) {
441+ err = dsa_port_devlink_setup (dp );
442+ if (err )
443+ goto unregister_devlink_ports ;
444+ }
445+ }
446+
436447 err = dsa_switch_register_notifier (ds );
437448 if (err )
438- goto unregister_devlink ;
449+ goto unregister_devlink_ports ;
439450
440451 err = ds -> ops -> setup (ds );
441452 if (err < 0 )
@@ -463,7 +474,10 @@ static int dsa_switch_setup(struct dsa_switch *ds)
463474
464475unregister_notifier :
465476 dsa_switch_unregister_notifier (ds );
466- unregister_devlink :
477+ unregister_devlink_ports :
478+ list_for_each_entry (dp , & ds -> dst -> ports , list )
479+ if (dp -> ds == ds )
480+ dsa_port_devlink_teardown (dp );
467481 devlink_unregister (ds -> devlink );
468482free_devlink :
469483 devlink_free (ds -> devlink );
@@ -474,6 +488,8 @@ static int dsa_switch_setup(struct dsa_switch *ds)
474488
475489static void dsa_switch_teardown (struct dsa_switch * ds )
476490{
491+ struct dsa_port * dp ;
492+
477493 if (!ds -> setup )
478494 return ;
479495
@@ -486,6 +502,9 @@ static void dsa_switch_teardown(struct dsa_switch *ds)
486502 ds -> ops -> teardown (ds );
487503
488504 if (ds -> devlink ) {
505+ list_for_each_entry (dp , & ds -> dst -> ports , list )
506+ if (dp -> ds == ds )
507+ dsa_port_devlink_teardown (dp );
489508 devlink_unregister (ds -> devlink );
490509 devlink_free (ds -> devlink );
491510 ds -> devlink = NULL ;
0 commit comments