@@ -343,7 +343,7 @@ static int ax88772_reset(struct usbnet *dev)
343343 if (ret < 0 )
344344 goto out ;
345345
346- phy_start (priv -> phydev );
346+ phylink_start (priv -> phylink );
347347
348348 return 0 ;
349349
@@ -590,8 +590,11 @@ static void ax88772_suspend(struct usbnet *dev)
590590 struct asix_common_private * priv = dev -> driver_priv ;
591591 u16 medium ;
592592
593- if (netif_running (dev -> net ))
594- phy_stop (priv -> phydev );
593+ if (netif_running (dev -> net )) {
594+ rtnl_lock ();
595+ phylink_suspend (priv -> phylink , false);
596+ rtnl_unlock ();
597+ }
595598
596599 /* Stop MAC operation */
597600 medium = asix_read_medium_status (dev , 1 );
@@ -622,8 +625,11 @@ static void ax88772_resume(struct usbnet *dev)
622625 if (!priv -> reset (dev , 1 ))
623626 break ;
624627
625- if (netif_running (dev -> net ))
626- phy_start (priv -> phydev );
628+ if (netif_running (dev -> net )) {
629+ rtnl_lock ();
630+ phylink_resume (priv -> phylink );
631+ rtnl_unlock ();
632+ }
627633}
628634
629635static int asix_resume (struct usb_interface * intf )
@@ -667,8 +673,7 @@ static int ax88772_init_phy(struct usbnet *dev)
667673 return - ENODEV ;
668674 }
669675
670- ret = phy_connect_direct (dev -> net , priv -> phydev , & asix_adjust_link ,
671- PHY_INTERFACE_MODE_INTERNAL );
676+ ret = phylink_connect_phy (priv -> phylink , priv -> phydev );
672677 if (ret ) {
673678 netdev_err (dev -> net , "Could not connect PHY\n" );
674679 return ret ;
@@ -688,6 +693,9 @@ static int ax88772_init_phy(struct usbnet *dev)
688693 */
689694 priv -> phydev_int = mdiobus_get_phy (priv -> mdio , AX_EMBD_PHY_ADDR );
690695 if (!priv -> phydev_int ) {
696+ rtnl_lock ();
697+ phylink_disconnect_phy (priv -> phylink );
698+ rtnl_unlock ();
691699 netdev_err (dev -> net , "Could not find internal PHY\n" );
692700 return - ENODEV ;
693701 }
@@ -698,6 +706,89 @@ static int ax88772_init_phy(struct usbnet *dev)
698706 return 0 ;
699707}
700708
709+ static void ax88772_mac_config (struct phylink_config * config , unsigned int mode ,
710+ const struct phylink_link_state * state )
711+ {
712+ /* Nothing to do */
713+ }
714+
715+ static void ax88772_mac_link_down (struct phylink_config * config ,
716+ unsigned int mode , phy_interface_t interface )
717+ {
718+ struct usbnet * dev = netdev_priv (to_net_dev (config -> dev ));
719+
720+ asix_write_medium_mode (dev , 0 , 0 );
721+ usbnet_link_change (dev , false, false);
722+ }
723+
724+ static void ax88772_mac_link_up (struct phylink_config * config ,
725+ struct phy_device * phy ,
726+ unsigned int mode , phy_interface_t interface ,
727+ int speed , int duplex ,
728+ bool tx_pause , bool rx_pause )
729+ {
730+ struct usbnet * dev = netdev_priv (to_net_dev (config -> dev ));
731+ u16 m = AX_MEDIUM_AC | AX_MEDIUM_RE ;
732+
733+ m |= duplex ? AX_MEDIUM_FD : 0 ;
734+
735+ switch (speed ) {
736+ case SPEED_100 :
737+ m |= AX_MEDIUM_PS ;
738+ break ;
739+ case SPEED_10 :
740+ break ;
741+ default :
742+ return ;
743+ }
744+
745+ if (tx_pause )
746+ m |= AX_MEDIUM_TFC ;
747+
748+ if (rx_pause )
749+ m |= AX_MEDIUM_RFC ;
750+
751+ asix_write_medium_mode (dev , m , 0 );
752+ usbnet_link_change (dev , true, false);
753+ }
754+
755+ static const struct phylink_mac_ops ax88772_phylink_mac_ops = {
756+ .validate = phylink_generic_validate ,
757+ .mac_config = ax88772_mac_config ,
758+ .mac_link_down = ax88772_mac_link_down ,
759+ .mac_link_up = ax88772_mac_link_up ,
760+ };
761+
762+ static int ax88772_phylink_setup (struct usbnet * dev )
763+ {
764+ struct asix_common_private * priv = dev -> driver_priv ;
765+ phy_interface_t phy_if_mode ;
766+ struct phylink * phylink ;
767+
768+ priv -> phylink_config .dev = & dev -> net -> dev ;
769+ priv -> phylink_config .type = PHYLINK_NETDEV ;
770+ priv -> phylink_config .mac_capabilities = MAC_SYM_PAUSE | MAC_ASYM_PAUSE |
771+ MAC_10 | MAC_100 ;
772+
773+ __set_bit (PHY_INTERFACE_MODE_INTERNAL ,
774+ priv -> phylink_config .supported_interfaces );
775+ __set_bit (PHY_INTERFACE_MODE_RMII ,
776+ priv -> phylink_config .supported_interfaces );
777+
778+ if (priv -> embd_phy )
779+ phy_if_mode = PHY_INTERFACE_MODE_INTERNAL ;
780+ else
781+ phy_if_mode = PHY_INTERFACE_MODE_RMII ;
782+
783+ phylink = phylink_create (& priv -> phylink_config , dev -> net -> dev .fwnode ,
784+ phy_if_mode , & ax88772_phylink_mac_ops );
785+ if (IS_ERR (phylink ))
786+ return PTR_ERR (phylink );
787+
788+ priv -> phylink = phylink ;
789+ return 0 ;
790+ }
791+
701792static int ax88772_bind (struct usbnet * dev , struct usb_interface * intf )
702793{
703794 struct asix_common_private * priv ;
@@ -788,14 +879,22 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
788879 if (ret )
789880 return ret ;
790881
791- return ax88772_init_phy (dev );
882+ ret = ax88772_phylink_setup (dev );
883+ if (ret )
884+ return ret ;
885+
886+ ret = ax88772_init_phy (dev );
887+ if (ret )
888+ phylink_destroy (priv -> phylink );
889+
890+ return ret ;
792891}
793892
794893static int ax88772_stop (struct usbnet * dev )
795894{
796895 struct asix_common_private * priv = dev -> driver_priv ;
797896
798- phy_stop (priv -> phydev );
897+ phylink_stop (priv -> phylink );
799898
800899 return 0 ;
801900}
@@ -804,7 +903,10 @@ static void ax88772_unbind(struct usbnet *dev, struct usb_interface *intf)
804903{
805904 struct asix_common_private * priv = dev -> driver_priv ;
806905
807- phy_disconnect (priv -> phydev );
906+ rtnl_lock ();
907+ phylink_disconnect_phy (priv -> phylink );
908+ rtnl_unlock ();
909+ phylink_destroy (priv -> phylink );
808910 asix_rx_fixup_common_free (dev -> driver_priv );
809911}
810912
0 commit comments