@@ -285,45 +285,23 @@ static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf)
285285
286286static const struct ethtool_ops ax88772_ethtool_ops = {
287287 .get_drvinfo = asix_get_drvinfo ,
288- .get_link = asix_get_link ,
288+ .get_link = usbnet_get_link ,
289289 .get_msglevel = usbnet_get_msglevel ,
290290 .set_msglevel = usbnet_set_msglevel ,
291291 .get_wol = asix_get_wol ,
292292 .set_wol = asix_set_wol ,
293293 .get_eeprom_len = asix_get_eeprom_len ,
294294 .get_eeprom = asix_get_eeprom ,
295295 .set_eeprom = asix_set_eeprom ,
296- .nway_reset = usbnet_nway_reset ,
297- .get_link_ksettings = usbnet_get_link_ksettings_mii ,
298- .set_link_ksettings = usbnet_set_link_ksettings_mii ,
296+ .nway_reset = phy_ethtool_nway_reset ,
297+ .get_link_ksettings = phy_ethtool_get_link_ksettings ,
298+ .set_link_ksettings = phy_ethtool_set_link_ksettings ,
299299};
300300
301- static int ax88772_link_reset (struct usbnet * dev )
302- {
303- u16 mode ;
304- struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
305-
306- mii_check_media (& dev -> mii , 1 , 1 );
307- mii_ethtool_gset (& dev -> mii , & ecmd );
308- mode = AX88772_MEDIUM_DEFAULT ;
309-
310- if (ethtool_cmd_speed (& ecmd ) != SPEED_100 )
311- mode &= ~AX_MEDIUM_PS ;
312-
313- if (ecmd .duplex != DUPLEX_FULL )
314- mode &= ~AX_MEDIUM_FD ;
315-
316- netdev_dbg (dev -> net , "ax88772_link_reset() speed: %u duplex: %d setting mode to 0x%04x\n" ,
317- ethtool_cmd_speed (& ecmd ), ecmd .duplex , mode );
318-
319- asix_write_medium_mode (dev , mode , 0 );
320-
321- return 0 ;
322- }
323-
324301static int ax88772_reset (struct usbnet * dev )
325302{
326303 struct asix_data * data = (struct asix_data * )& dev -> data ;
304+ struct asix_common_private * priv = dev -> driver_priv ;
327305 int ret ;
328306
329307 /* Rewrite MAC address */
@@ -342,6 +320,8 @@ static int ax88772_reset(struct usbnet *dev)
342320 if (ret < 0 )
343321 goto out ;
344322
323+ phy_start (priv -> phydev );
324+
345325 return 0 ;
346326
347327out :
@@ -586,7 +566,7 @@ static const struct net_device_ops ax88772_netdev_ops = {
586566 .ndo_get_stats64 = dev_get_tstats64 ,
587567 .ndo_set_mac_address = asix_set_mac_address ,
588568 .ndo_validate_addr = eth_validate_addr ,
589- .ndo_do_ioctl = asix_ioctl ,
569+ .ndo_do_ioctl = phy_do_ioctl_running ,
590570 .ndo_set_rx_mode = asix_set_multicast ,
591571};
592572
@@ -677,12 +657,57 @@ static int asix_resume(struct usb_interface *intf)
677657 return usbnet_resume (intf );
678658}
679659
660+ static int ax88772_init_mdio (struct usbnet * dev )
661+ {
662+ struct asix_common_private * priv = dev -> driver_priv ;
663+
664+ priv -> mdio = devm_mdiobus_alloc (& dev -> udev -> dev );
665+ if (!priv -> mdio )
666+ return - ENOMEM ;
667+
668+ priv -> mdio -> priv = dev ;
669+ priv -> mdio -> read = & asix_mdio_bus_read ;
670+ priv -> mdio -> write = & asix_mdio_bus_write ;
671+ priv -> mdio -> name = "Asix MDIO Bus" ;
672+ /* mii bus name is usb-<usb bus number>-<usb device number> */
673+ snprintf (priv -> mdio -> id , MII_BUS_ID_SIZE , "usb-%03d:%03d" ,
674+ dev -> udev -> bus -> busnum , dev -> udev -> devnum );
675+
676+ return devm_mdiobus_register (& dev -> udev -> dev , priv -> mdio );
677+ }
678+
679+ static int ax88772_init_phy (struct usbnet * dev )
680+ {
681+ struct asix_common_private * priv = dev -> driver_priv ;
682+ int ret ;
683+
684+ priv -> phy_addr = asix_read_phy_addr (dev , true);
685+ if (priv -> phy_addr < 0 )
686+ return priv -> phy_addr ;
687+
688+ snprintf (priv -> phy_name , sizeof (priv -> phy_name ), PHY_ID_FMT ,
689+ priv -> mdio -> id , priv -> phy_addr );
690+
691+ priv -> phydev = phy_connect (dev -> net , priv -> phy_name , & asix_adjust_link ,
692+ PHY_INTERFACE_MODE_INTERNAL );
693+ if (IS_ERR (priv -> phydev )) {
694+ netdev_err (dev -> net , "Could not connect to PHY device %s\n" ,
695+ priv -> phy_name );
696+ ret = PTR_ERR (priv -> phydev );
697+ return ret ;
698+ }
699+
700+ phy_attached_info (priv -> phydev );
701+
702+ return 0 ;
703+ }
704+
680705static int ax88772_bind (struct usbnet * dev , struct usb_interface * intf )
681706{
682- int ret , i ;
683707 u8 buf [ETH_ALEN ] = {0 }, chipcode = 0 ;
684- u32 phyid ;
685708 struct asix_common_private * priv ;
709+ int ret , i ;
710+ u32 phyid ;
686711
687712 usbnet_get_endpoints (dev , intf );
688713
@@ -714,17 +739,6 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
714739
715740 asix_set_netdev_dev_addr (dev , buf );
716741
717- /* Initialize MII structure */
718- dev -> mii .dev = dev -> net ;
719- dev -> mii .mdio_read = asix_mdio_read ;
720- dev -> mii .mdio_write = asix_mdio_write ;
721- dev -> mii .phy_id_mask = 0x1f ;
722- dev -> mii .reg_num_mask = 0x1f ;
723-
724- dev -> mii .phy_id = asix_read_phy_addr (dev , true);
725- if (dev -> mii .phy_id < 0 )
726- return dev -> mii .phy_id ;
727-
728742 dev -> net -> netdev_ops = & ax88772_netdev_ops ;
729743 dev -> net -> ethtool_ops = & ax88772_ethtool_ops ;
730744 dev -> net -> needed_headroom = 4 ; /* cf asix_tx_fixup() */
@@ -768,11 +782,31 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
768782 priv -> suspend = ax88772_suspend ;
769783 }
770784
785+ ret = ax88772_init_mdio (dev );
786+ if (ret )
787+ return ret ;
788+
789+ return ax88772_init_phy (dev );
790+ }
791+
792+ static int ax88772_stop (struct usbnet * dev )
793+ {
794+ struct asix_common_private * priv = dev -> driver_priv ;
795+
796+ /* On unplugged USB, we will get MDIO communication errors and the
797+ * PHY will be set in to PHY_HALTED state.
798+ */
799+ if (priv -> phydev -> state != PHY_HALTED )
800+ phy_stop (priv -> phydev );
801+
771802 return 0 ;
772803}
773804
774805static void ax88772_unbind (struct usbnet * dev , struct usb_interface * intf )
775806{
807+ struct asix_common_private * priv = dev -> driver_priv ;
808+
809+ phy_disconnect (priv -> phydev );
776810 asix_rx_fixup_common_free (dev -> driver_priv );
777811}
778812
@@ -1161,8 +1195,8 @@ static const struct driver_info ax88772_info = {
11611195 .bind = ax88772_bind ,
11621196 .unbind = ax88772_unbind ,
11631197 .status = asix_status ,
1164- .link_reset = ax88772_link_reset ,
11651198 .reset = ax88772_reset ,
1199+ .stop = ax88772_stop ,
11661200 .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | FLAG_MULTI_PACKET ,
11671201 .rx_fixup = asix_rx_fixup_common ,
11681202 .tx_fixup = asix_tx_fixup ,
@@ -1173,7 +1207,6 @@ static const struct driver_info ax88772b_info = {
11731207 .bind = ax88772_bind ,
11741208 .unbind = ax88772_unbind ,
11751209 .status = asix_status ,
1176- .link_reset = ax88772_link_reset ,
11771210 .reset = ax88772_reset ,
11781211 .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR |
11791212 FLAG_MULTI_PACKET ,
@@ -1209,7 +1242,6 @@ static const struct driver_info hg20f9_info = {
12091242 .bind = ax88772_bind ,
12101243 .unbind = ax88772_unbind ,
12111244 .status = asix_status ,
1212- .link_reset = ax88772_link_reset ,
12131245 .reset = ax88772_reset ,
12141246 .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR |
12151247 FLAG_MULTI_PACKET ,
0 commit comments