@@ -600,6 +600,12 @@ static int dpaa2_switch_port_link_state_update(struct net_device *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 ,
@@ -694,6 +702,9 @@ static int dpaa2_switch_port_open(struct net_device *netdev)
694702
695703 dpaa2_switch_enable_ctrl_if_napi (ethsw );
696704
705+ if (dpaa2_switch_port_is_type_phy (port_priv ))
706+ phylink_start (port_priv -> mac -> phylink );
707+
697708 return 0 ;
698709}
699710
@@ -703,6 +714,13 @@ static int dpaa2_switch_port_stop(struct net_device *netdev)
703714 struct ethsw_core * ethsw = port_priv -> ethsw_data ;
704715 int err ;
705716
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+
706724 err = dpsw_if_disable (port_priv -> ethsw_data -> mc_io , 0 ,
707725 port_priv -> ethsw_data -> dpsw_handle ,
708726 port_priv -> idx );
@@ -1405,6 +1423,67 @@ bool dpaa2_switch_port_dev_check(const struct net_device *netdev)
14051423 return netdev -> netdev_ops == & dpaa2_switch_port_ops ;
14061424}
14071425
1426+ static int dpaa2_switch_port_connect_mac (struct ethsw_port_priv * port_priv )
1427+ {
1428+ struct fsl_mc_device * dpsw_port_dev , * dpmac_dev ;
1429+ struct dpaa2_mac * mac ;
1430+ int err ;
1431+
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+ }
1462+ }
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 ;
1485+ }
1486+
14081487static irqreturn_t dpaa2_switch_irq0_handler_thread (int irq_num , void * arg )
14091488{
14101489 struct device * dev = (struct device * )arg ;
@@ -1427,6 +1506,14 @@ static irqreturn_t dpaa2_switch_irq0_handler_thread(int irq_num, void *arg)
14271506 dpaa2_switch_port_link_state_update (port_priv -> netdev );
14281507 dpaa2_switch_port_set_mac_addr (port_priv );
14291508 }
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+ }
1516+
14301517out :
14311518 err = dpsw_clear_irq_status (ethsw -> mc_io , 0 , ethsw -> dpsw_handle ,
14321519 DPSW_IRQ_INDEX_IF , status );
@@ -3112,6 +3199,7 @@ static int dpaa2_switch_remove(struct fsl_mc_device *sw_dev)
31123199 for (i = 0 ; i < ethsw -> sw_attr .num_ifs ; i ++ ) {
31133200 port_priv = ethsw -> ports [i ];
31143201 unregister_netdev (port_priv -> netdev );
3202+ dpaa2_switch_port_disconnect_mac (port_priv );
31153203 free_netdev (port_priv -> netdev );
31163204 }
31173205
@@ -3191,6 +3279,10 @@ static int dpaa2_switch_probe_port(struct ethsw_core *ethsw,
31913279 goto err_port_probe ;
31923280 port_priv -> learn_ena = false;
31933281
3282+ err = dpaa2_switch_port_connect_mac (port_priv );
3283+ if (err )
3284+ goto err_port_probe ;
3285+
31943286 return 0 ;
31953287
31963288err_port_probe :
0 commit comments