@@ -594,12 +594,18 @@ static int dpaa2_switch_port_change_mtu(struct net_device *netdev, int mtu)
594594	return  0 ;
595595}
596596
597- static  int  dpaa2_switch_port_carrier_state_sync (struct  net_device  * netdev )
597+ static  int  dpaa2_switch_port_link_state_update (struct  net_device  * netdev )
598598{
599599	struct  ethsw_port_priv  * port_priv  =  netdev_priv (netdev );
600600	struct  dpsw_link_state  state ;
601601	int  err ;
602602
603+ 	/* When we manage the MAC/PHY using phylink there is no need 
604+ 	 * to manually update the netif_carrier. 
605+ 	 */ 
606+ 	if  (dpaa2_switch_port_is_type_phy (port_priv ))
607+ 		return  0 ;
608+ 
603609	/* Interrupts are received even though no one issued an 'ifconfig up' 
604610	 * on the switch interface. Ignore these link state update interrupts 
605611	 */ 
@@ -677,12 +683,14 @@ static int dpaa2_switch_port_open(struct net_device *netdev)
677683	struct  ethsw_core  * ethsw  =  port_priv -> ethsw_data ;
678684	int  err ;
679685
680- 	/* Explicitly set carrier off, otherwise 
681- 	 * netif_carrier_ok() will return true and cause 'ip link show' 
682- 	 * to report the LOWER_UP flag, even though the link 
683- 	 * notification wasn't even received. 
684- 	 */ 
685- 	netif_carrier_off (netdev );
686+ 	if  (!dpaa2_switch_port_is_type_phy (port_priv )) {
687+ 		/* Explicitly set carrier off, otherwise 
688+ 		 * netif_carrier_ok() will return true and cause 'ip link show' 
689+ 		 * to report the LOWER_UP flag, even though the link 
690+ 		 * notification wasn't even received. 
691+ 		 */ 
692+ 		netif_carrier_off (netdev );
693+ 	}
686694
687695	err  =  dpsw_if_enable (port_priv -> ethsw_data -> mc_io , 0 ,
688696			     port_priv -> ethsw_data -> dpsw_handle ,
@@ -692,23 +700,12 @@ static int dpaa2_switch_port_open(struct net_device *netdev)
692700		return  err ;
693701	}
694702
695- 	/* sync carrier state */ 
696- 	err  =  dpaa2_switch_port_carrier_state_sync (netdev );
697- 	if  (err ) {
698- 		netdev_err (netdev ,
699- 			   "dpaa2_switch_port_carrier_state_sync err %d\n" , err );
700- 		goto err_carrier_sync ;
701- 	}
702- 
703703	dpaa2_switch_enable_ctrl_if_napi (ethsw );
704704
705- 	return  0 ;
705+ 	if  (dpaa2_switch_port_is_type_phy (port_priv ))
706+ 		phylink_start (port_priv -> mac -> phylink );
706707
707- err_carrier_sync :
708- 	dpsw_if_disable (port_priv -> ethsw_data -> mc_io , 0 ,
709- 			port_priv -> ethsw_data -> dpsw_handle ,
710- 			port_priv -> idx );
711- 	return  err ;
708+ 	return  0 ;
712709}
713710
714711static  int  dpaa2_switch_port_stop (struct  net_device  * netdev )
@@ -717,6 +714,13 @@ static int dpaa2_switch_port_stop(struct net_device *netdev)
717714	struct  ethsw_core  * ethsw  =  port_priv -> ethsw_data ;
718715	int  err ;
719716
717+ 	if  (dpaa2_switch_port_is_type_phy (port_priv )) {
718+ 		phylink_stop (port_priv -> mac -> phylink );
719+ 	} else  {
720+ 		netif_tx_stop_all_queues (netdev );
721+ 		netif_carrier_off (netdev );
722+ 	}
723+ 
720724	err  =  dpsw_if_disable (port_priv -> ethsw_data -> mc_io , 0 ,
721725			      port_priv -> ethsw_data -> dpsw_handle ,
722726			      port_priv -> idx );
@@ -1419,41 +1423,103 @@ bool dpaa2_switch_port_dev_check(const struct net_device *netdev)
14191423	return  netdev -> netdev_ops  ==  & dpaa2_switch_port_ops ;
14201424}
14211425
1422- static  void   dpaa2_switch_links_state_update (struct  ethsw_core   * ethsw )
1426+ static  int   dpaa2_switch_port_connect_mac (struct  ethsw_port_priv   * port_priv )
14231427{
1424- 	int  i ;
1428+ 	struct  fsl_mc_device  * dpsw_port_dev , * dpmac_dev ;
1429+ 	struct  dpaa2_mac  * mac ;
1430+ 	int  err ;
14251431
1426- 	for  (i  =  0 ; i  <  ethsw -> sw_attr .num_ifs ; i ++ ) {
1427- 		dpaa2_switch_port_carrier_state_sync (ethsw -> ports [i ]-> netdev );
1428- 		dpaa2_switch_port_set_mac_addr (ethsw -> ports [i ]);
1432+ 	dpsw_port_dev  =  to_fsl_mc_device (port_priv -> netdev -> dev .parent );
1433+ 	dpmac_dev  =  fsl_mc_get_endpoint (dpsw_port_dev , port_priv -> idx );
1434+ 
1435+ 	if  (PTR_ERR (dpmac_dev ) ==  - EPROBE_DEFER )
1436+ 		return  PTR_ERR (dpmac_dev );
1437+ 
1438+ 	if  (IS_ERR (dpmac_dev ) ||  dpmac_dev -> dev .type  !=  & fsl_mc_bus_dpmac_type )
1439+ 		return  0 ;
1440+ 
1441+ 	mac  =  kzalloc (sizeof (* mac ), GFP_KERNEL );
1442+ 	if  (!mac )
1443+ 		return  - ENOMEM ;
1444+ 
1445+ 	mac -> mc_dev  =  dpmac_dev ;
1446+ 	mac -> mc_io  =  port_priv -> ethsw_data -> mc_io ;
1447+ 	mac -> net_dev  =  port_priv -> netdev ;
1448+ 
1449+ 	err  =  dpaa2_mac_open (mac );
1450+ 	if  (err )
1451+ 		goto err_free_mac ;
1452+ 	port_priv -> mac  =  mac ;
1453+ 
1454+ 	if  (dpaa2_switch_port_is_type_phy (port_priv )) {
1455+ 		err  =  dpaa2_mac_connect (mac );
1456+ 		if  (err ) {
1457+ 			netdev_err (port_priv -> netdev ,
1458+ 				   "Error connecting to the MAC endpoint %pe\n" ,
1459+ 				   ERR_PTR (err ));
1460+ 			goto err_close_mac ;
1461+ 		}
14291462	}
1463+ 
1464+ 	return  0 ;
1465+ 
1466+ err_close_mac :
1467+ 	dpaa2_mac_close (mac );
1468+ 	port_priv -> mac  =  NULL ;
1469+ err_free_mac :
1470+ 	kfree (mac );
1471+ 	return  err ;
1472+ }
1473+ 
1474+ static  void  dpaa2_switch_port_disconnect_mac (struct  ethsw_port_priv  * port_priv )
1475+ {
1476+ 	if  (dpaa2_switch_port_is_type_phy (port_priv ))
1477+ 		dpaa2_mac_disconnect (port_priv -> mac );
1478+ 
1479+ 	if  (!dpaa2_switch_port_has_mac (port_priv ))
1480+ 		return ;
1481+ 
1482+ 	dpaa2_mac_close (port_priv -> mac );
1483+ 	kfree (port_priv -> mac );
1484+ 	port_priv -> mac  =  NULL ;
14301485}
14311486
14321487static  irqreturn_t  dpaa2_switch_irq0_handler_thread (int  irq_num , void  * arg )
14331488{
14341489	struct  device  * dev  =  (struct  device  * )arg ;
14351490	struct  ethsw_core  * ethsw  =  dev_get_drvdata (dev );
1436- 
1437- 	/* Mask the events and the if_id reserved bits to be cleared on read */ 
1438- 	u32  status  =  DPSW_IRQ_EVENT_LINK_CHANGED  | 0xFFFF0000 ;
1439- 	int  err ;
1491+ 	struct  ethsw_port_priv  * port_priv ;
1492+ 	u32  status  =  ~0 ;
1493+ 	int  err , if_id ;
14401494
14411495	err  =  dpsw_get_irq_status (ethsw -> mc_io , 0 , ethsw -> dpsw_handle ,
14421496				  DPSW_IRQ_INDEX_IF , & status );
14431497	if  (err ) {
14441498		dev_err (dev , "Can't get irq status (err %d)\n" , err );
1445- 
1446- 		err  =  dpsw_clear_irq_status (ethsw -> mc_io , 0 , ethsw -> dpsw_handle ,
1447- 					    DPSW_IRQ_INDEX_IF , 0xFFFFFFFF );
1448- 		if  (err )
1449- 			dev_err (dev , "Can't clear irq status (err %d)\n" , err );
14501499		goto out ;
14511500	}
14521501
1453- 	if  (status  &  DPSW_IRQ_EVENT_LINK_CHANGED )
1454- 		dpaa2_switch_links_state_update (ethsw );
1502+ 	if_id  =  (status  &  0xFFFF0000 ) >> 16 ;
1503+ 	port_priv  =  ethsw -> ports [if_id ];
1504+ 
1505+ 	if  (status  &  DPSW_IRQ_EVENT_LINK_CHANGED ) {
1506+ 		dpaa2_switch_port_link_state_update (port_priv -> netdev );
1507+ 		dpaa2_switch_port_set_mac_addr (port_priv );
1508+ 	}
1509+ 
1510+ 	if  (status  &  DPSW_IRQ_EVENT_ENDPOINT_CHANGED ) {
1511+ 		if  (dpaa2_switch_port_has_mac (port_priv ))
1512+ 			dpaa2_switch_port_disconnect_mac (port_priv );
1513+ 		else 
1514+ 			dpaa2_switch_port_connect_mac (port_priv );
1515+ 	}
14551516
14561517out :
1518+ 	err  =  dpsw_clear_irq_status (ethsw -> mc_io , 0 , ethsw -> dpsw_handle ,
1519+ 				    DPSW_IRQ_INDEX_IF , status );
1520+ 	if  (err )
1521+ 		dev_err (dev , "Can't clear irq status (err %d)\n" , err );
1522+ 
14571523	return  IRQ_HANDLED ;
14581524}
14591525
@@ -3133,6 +3199,7 @@ static int dpaa2_switch_remove(struct fsl_mc_device *sw_dev)
31333199	for  (i  =  0 ; i  <  ethsw -> sw_attr .num_ifs ; i ++ ) {
31343200		port_priv  =  ethsw -> ports [i ];
31353201		unregister_netdev (port_priv -> netdev );
3202+ 		dpaa2_switch_port_disconnect_mac (port_priv );
31363203		free_netdev (port_priv -> netdev );
31373204	}
31383205
@@ -3212,6 +3279,10 @@ static int dpaa2_switch_probe_port(struct ethsw_core *ethsw,
32123279		goto err_port_probe ;
32133280	port_priv -> learn_ena  =  false;
32143281
3282+ 	err  =  dpaa2_switch_port_connect_mac (port_priv );
3283+ 	if  (err )
3284+ 		goto err_port_probe ;
3285+ 
32153286	return  0 ;
32163287
32173288err_port_probe :
@@ -3288,12 +3359,6 @@ static int dpaa2_switch_probe(struct fsl_mc_device *sw_dev)
32883359			       & ethsw -> fq [i ].napi , dpaa2_switch_poll ,
32893360			       NAPI_POLL_WEIGHT );
32903361
3291- 	err  =  dpsw_enable (ethsw -> mc_io , 0 , ethsw -> dpsw_handle );
3292- 	if  (err ) {
3293- 		dev_err (ethsw -> dev , "dpsw_enable err %d\n" , err );
3294- 		goto err_free_netdev ;
3295- 	}
3296- 
32973362	/* Setup IRQs */ 
32983363	err  =  dpaa2_switch_setup_irqs (sw_dev );
32993364	if  (err )
0 commit comments