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