1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * ASIX AX88172A based USB 2.0 Ethernet Devices 4 * Copyright (C) 2012 OMICRON electronics GmbH 5 * 6 * Supports external PHYs via phylib. Based on the driver for the 7 * AX88772. Original copyrights follow: 8 * 9 * Copyright (C) 2003-2006 David Hollis <dhollis@davehollis.com> 10 * Copyright (C) 2005 Phil Chang <pchang23@sbcglobal.net> 11 * Copyright (C) 2006 James Painter <jamie.painter@iname.com> 12 * Copyright (c) 2002-2003 TiVo Inc. 13 */ 14 15 #include "asix.h" 16 #include <linux/phy.h> 17 18 struct ax88172a_private { 19 struct mii_bus *mdio; 20 struct phy_device *phydev; 21 char phy_name[20]; 22 u16 phy_addr; 23 u16 oldmode; 24 int use_embdphy; 25 struct asix_rx_fixup_info rx_fixup_info; 26 }; 27 28 /* MDIO read and write wrappers for phylib */ 29 static int asix_mdio_bus_read(struct mii_bus *bus, int phy_id, int regnum) 30 { 31 return asix_mdio_read(((struct usbnet *)bus->priv)->net, phy_id, 32 regnum); 33 } 34 35 static int asix_mdio_bus_write(struct mii_bus *bus, int phy_id, int regnum, 36 u16 val) 37 { 38 asix_mdio_write(((struct usbnet *)bus->priv)->net, phy_id, regnum, val); 39 return 0; 40 } 41 42 static int ax88172a_ioctl(struct net_device *net, struct ifreq *rq, int cmd) 43 { 44 if (!netif_running(net)) 45 return -EINVAL; 46 47 if (!net->phydev) 48 return -ENODEV; 49 50 return phy_mii_ioctl(net->phydev, rq, cmd); 51 } 52 53 /* set MAC link settings according to information from phylib */ 54 static void ax88172a_adjust_link(struct net_device *netdev) 55 { 56 struct phy_device *phydev = netdev->phydev; 57 struct usbnet *dev = netdev_priv(netdev); 58 struct ax88172a_private *priv = dev->driver_priv; 59 u16 mode = 0; 60 61 if (phydev->link) { 62 mode = AX88772_MEDIUM_DEFAULT; 63 64 if (phydev->duplex == DUPLEX_HALF) 65 mode &= ~AX_MEDIUM_FD; 66 67 if (phydev->speed != SPEED_100) 68 mode &= ~AX_MEDIUM_PS; 69 } 70 71 if (mode != priv->oldmode) { 72 asix_write_medium_mode(dev, mode, 0); 73 priv->oldmode = mode; 74 netdev_dbg(netdev, "speed %u duplex %d, setting mode to 0x%04x\n", 75 phydev->speed, phydev->duplex, mode); 76 phy_print_status(phydev); 77 } 78 } 79 80 static void ax88172a_status(struct usbnet *dev, struct urb *urb) 81 { 82 /* link changes are detected by polling the phy */ 83 } 84 85 /* use phylib infrastructure */ 86 static int ax88172a_init_mdio(struct usbnet *dev) 87 { 88 struct ax88172a_private *priv = dev->driver_priv; 89 int ret; 90 91 priv->mdio = mdiobus_alloc(); 92 if (!priv->mdio) { 93 netdev_err(dev->net, "Could not allocate MDIO bus\n"); 94 return -ENOMEM; 95 } 96 97 priv->mdio->priv = (void *)dev; 98 priv->mdio->read = &asix_mdio_bus_read; 99 priv->mdio->write = &asix_mdio_bus_write; 100 priv->mdio->name = "Asix MDIO Bus"; 101 /* mii bus name is usb-<usb bus number>-<usb device number> */ 102 snprintf(priv->mdio->id, MII_BUS_ID_SIZE, "usb-%03d:%03d", 103 dev->udev->bus->busnum, dev->udev->devnum); 104 105 ret = mdiobus_register(priv->mdio); 106 if (ret) { 107 netdev_err(dev->net, "Could not register MDIO bus\n"); 108 goto mfree; 109 } 110 111 netdev_info(dev->net, "registered mdio bus %s\n", priv->mdio->id); 112 return 0; 113 114 mfree: 115 mdiobus_free(priv->mdio); 116 return ret; 117 } 118 119 static void ax88172a_remove_mdio(struct usbnet *dev) 120 { 121 struct ax88172a_private *priv = dev->driver_priv; 122 123 netdev_info(dev->net, "deregistering mdio bus %s\n", priv->mdio->id); 124 mdiobus_unregister(priv->mdio); 125 mdiobus_free(priv->mdio); 126 } 127 128 static const struct net_device_ops ax88172a_netdev_ops = { 129 .ndo_open = usbnet_open, 130 .ndo_stop = usbnet_stop, 131 .ndo_start_xmit = usbnet_start_xmit, 132 .ndo_tx_timeout = usbnet_tx_timeout, 133 .ndo_change_mtu = usbnet_change_mtu, 134 .ndo_get_stats64 = usbnet_get_stats64, 135 .ndo_set_mac_address = asix_set_mac_address, 136 .ndo_validate_addr = eth_validate_addr, 137 .ndo_do_ioctl = ax88172a_ioctl, 138 .ndo_set_rx_mode = asix_set_multicast, 139 }; 140 141 static const struct ethtool_ops ax88172a_ethtool_ops = { 142 .get_drvinfo = asix_get_drvinfo, 143 .get_link = usbnet_get_link, 144 .get_msglevel = usbnet_get_msglevel, 145 .set_msglevel = usbnet_set_msglevel, 146 .get_wol = asix_get_wol, 147 .set_wol = asix_set_wol, 148 .get_eeprom_len = asix_get_eeprom_len, 149 .get_eeprom = asix_get_eeprom, 150 .set_eeprom = asix_set_eeprom, 151 .nway_reset = phy_ethtool_nway_reset, 152 .get_link_ksettings = phy_ethtool_get_link_ksettings, 153 .set_link_ksettings = phy_ethtool_set_link_ksettings, 154 }; 155 156 static int ax88172a_reset_phy(struct usbnet *dev, int embd_phy) 157 { 158 int ret; 159 160 ret = asix_sw_reset(dev, AX_SWRESET_IPPD, 0); 161 if (ret < 0) 162 goto err; 163 164 msleep(150); 165 ret = asix_sw_reset(dev, AX_SWRESET_CLEAR, 0); 166 if (ret < 0) 167 goto err; 168 169 msleep(150); 170 171 ret = asix_sw_reset(dev, embd_phy ? AX_SWRESET_IPRL : AX_SWRESET_IPPD, 172 0); 173 if (ret < 0) 174 goto err; 175 176 return 0; 177 178 err: 179 return ret; 180 } 181 182 183 static int ax88172a_bind(struct usbnet *dev, struct usb_interface *intf) 184 { 185 int ret; 186 u8 buf[ETH_ALEN]; 187 struct ax88172a_private *priv; 188 189 usbnet_get_endpoints(dev, intf); 190 191 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 192 if (!priv) 193 return -ENOMEM; 194 195 dev->driver_priv = priv; 196 197 /* Get the MAC address */ 198 ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf, 0); 199 if (ret < ETH_ALEN) { 200 netdev_err(dev->net, "Failed to read MAC address: %d\n", ret); 201 goto free; 202 } 203 memcpy(dev->net->dev_addr, buf, ETH_ALEN); 204 205 dev->net->netdev_ops = &ax88172a_netdev_ops; 206 dev->net->ethtool_ops = &ax88172a_ethtool_ops; 207 208 /* are we using the internal or the external phy? */ 209 ret = asix_read_cmd(dev, AX_CMD_SW_PHY_STATUS, 0, 0, 1, buf, 0); 210 if (ret < 0) { 211 netdev_err(dev->net, "Failed to read software interface selection register: %d\n", 212 ret); 213 goto free; 214 } 215 216 netdev_dbg(dev->net, "AX_CMD_SW_PHY_STATUS = 0x%02x\n", buf[0]); 217 switch (buf[0] & AX_PHY_SELECT_MASK) { 218 case AX_PHY_SELECT_INTERNAL: 219 netdev_dbg(dev->net, "use internal phy\n"); 220 priv->use_embdphy = 1; 221 break; 222 case AX_PHY_SELECT_EXTERNAL: 223 netdev_dbg(dev->net, "use external phy\n"); 224 priv->use_embdphy = 0; 225 break; 226 default: 227 netdev_err(dev->net, "Interface mode not supported by driver\n"); 228 ret = -ENOTSUPP; 229 goto free; 230 } 231 232 priv->phy_addr = asix_read_phy_addr(dev, priv->use_embdphy); 233 ax88172a_reset_phy(dev, priv->use_embdphy); 234 235 /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */ 236 if (dev->driver_info->flags & FLAG_FRAMING_AX) { 237 /* hard_mtu is still the default - the device does not support 238 jumbo eth frames */ 239 dev->rx_urb_size = 2048; 240 } 241 242 /* init MDIO bus */ 243 ret = ax88172a_init_mdio(dev); 244 if (ret) 245 goto free; 246 247 return 0; 248 249 free: 250 kfree(priv); 251 return ret; 252 } 253 254 static int ax88172a_stop(struct usbnet *dev) 255 { 256 struct ax88172a_private *priv = dev->driver_priv; 257 258 netdev_dbg(dev->net, "Stopping interface\n"); 259 260 if (priv->phydev) { 261 netdev_info(dev->net, "Disconnecting from phy %s\n", 262 priv->phy_name); 263 phy_stop(priv->phydev); 264 phy_disconnect(priv->phydev); 265 } 266 267 return 0; 268 } 269 270 static void ax88172a_unbind(struct usbnet *dev, struct usb_interface *intf) 271 { 272 struct ax88172a_private *priv = dev->driver_priv; 273 274 ax88172a_remove_mdio(dev); 275 kfree(priv); 276 } 277 278 static int ax88172a_reset(struct usbnet *dev) 279 { 280 struct asix_data *data = (struct asix_data *)&dev->data; 281 struct ax88172a_private *priv = dev->driver_priv; 282 int ret; 283 u16 rx_ctl; 284 285 ax88172a_reset_phy(dev, priv->use_embdphy); 286 287 msleep(150); 288 rx_ctl = asix_read_rx_ctl(dev, 0); 289 netdev_dbg(dev->net, "RX_CTL is 0x%04x after software reset\n", rx_ctl); 290 ret = asix_write_rx_ctl(dev, 0x0000, 0); 291 if (ret < 0) 292 goto out; 293 294 rx_ctl = asix_read_rx_ctl(dev, 0); 295 netdev_dbg(dev->net, "RX_CTL is 0x%04x setting to 0x0000\n", rx_ctl); 296 297 msleep(150); 298 299 ret = asix_write_cmd(dev, AX_CMD_WRITE_IPG0, 300 AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT, 301 AX88772_IPG2_DEFAULT, 0, NULL, 0); 302 if (ret < 0) { 303 netdev_err(dev->net, "Write IPG,IPG1,IPG2 failed: %d\n", ret); 304 goto out; 305 } 306 307 /* Rewrite MAC address */ 308 memcpy(data->mac_addr, dev->net->dev_addr, ETH_ALEN); 309 ret = asix_write_cmd(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, 310 data->mac_addr, 0); 311 if (ret < 0) 312 goto out; 313 314 /* Set RX_CTL to default values with 2k buffer, and enable cactus */ 315 ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL, 0); 316 if (ret < 0) 317 goto out; 318 319 rx_ctl = asix_read_rx_ctl(dev, 0); 320 netdev_dbg(dev->net, "RX_CTL is 0x%04x after all initializations\n", 321 rx_ctl); 322 323 rx_ctl = asix_read_medium_status(dev, 0); 324 netdev_dbg(dev->net, "Medium Status is 0x%04x after all initializations\n", 325 rx_ctl); 326 327 /* Connect to PHY */ 328 snprintf(priv->phy_name, 20, PHY_ID_FMT, 329 priv->mdio->id, priv->phy_addr); 330 331 priv->phydev = phy_connect(dev->net, priv->phy_name, 332 &ax88172a_adjust_link, 333 PHY_INTERFACE_MODE_MII); 334 if (IS_ERR(priv->phydev)) { 335 netdev_err(dev->net, "Could not connect to PHY device %s\n", 336 priv->phy_name); 337 ret = PTR_ERR(priv->phydev); 338 goto out; 339 } 340 341 netdev_info(dev->net, "Connected to phy %s\n", priv->phy_name); 342 343 /* During power-up, the AX88172A set the power down (BMCR_PDOWN) 344 * bit of the PHY. Bring the PHY up again. 345 */ 346 genphy_resume(priv->phydev); 347 phy_start(priv->phydev); 348 349 return 0; 350 351 out: 352 return ret; 353 354 } 355 356 static int ax88172a_rx_fixup(struct usbnet *dev, struct sk_buff *skb) 357 { 358 struct ax88172a_private *dp = dev->driver_priv; 359 struct asix_rx_fixup_info *rx = &dp->rx_fixup_info; 360 361 return asix_rx_fixup_internal(dev, skb, rx); 362 } 363 364 const struct driver_info ax88172a_info = { 365 .description = "ASIX AX88172A USB 2.0 Ethernet", 366 .bind = ax88172a_bind, 367 .reset = ax88172a_reset, 368 .stop = ax88172a_stop, 369 .unbind = ax88172a_unbind, 370 .status = ax88172a_status, 371 .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | 372 FLAG_MULTI_PACKET, 373 .rx_fixup = ax88172a_rx_fixup, 374 .tx_fixup = asix_tx_fixup, 375 }; 376