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);
  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        kfree(priv->mdio->irq);
 148        mdiobus_free(priv->mdio);
 149}
 150
 151static const struct net_device_ops ax88172a_netdev_ops = {
 152        .ndo_open               = usbnet_open,
 153        .ndo_stop               = usbnet_stop,
 154        .ndo_start_xmit         = usbnet_start_xmit,
 155        .ndo_tx_timeout         = usbnet_tx_timeout,
 156        .ndo_change_mtu         = usbnet_change_mtu,
 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);
 209        if (ret < 0)
 210                goto err;
 211
 212        msleep(150);
 213        ret = asix_sw_reset(dev, AX_SWRESET_CLEAR);
 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        if (ret < 0)
 221                goto err;
 222
 223        return 0;
 224
 225err:
 226        return ret;
 227}
 228
 229
 230static int ax88172a_bind(struct usbnet *dev, struct usb_interface *intf)
 231{
 232        int ret;
 233        u8 buf[ETH_ALEN];
 234        struct ax88172a_private *priv;
 235
 236        usbnet_get_endpoints(dev, intf);
 237
 238        priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 239        if (!priv)
 240                return -ENOMEM;
 241
 242        dev->driver_priv = priv;
 243
 244        /* Get the MAC address */
 245        ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf);
 246        if (ret < 0) {
 247                netdev_err(dev->net, "Failed to read MAC address: %d\n", ret);
 248                goto free;
 249        }
 250        memcpy(dev->net->dev_addr, buf, ETH_ALEN);
 251
 252        dev->net->netdev_ops = &ax88172a_netdev_ops;
 253        dev->net->ethtool_ops = &ax88172a_ethtool_ops;
 254
 255        /* are we using the internal or the external phy? */
 256        ret = asix_read_cmd(dev, AX_CMD_SW_PHY_STATUS, 0, 0, 1, buf);
 257        if (ret < 0) {
 258                netdev_err(dev->net, "Failed to read software interface selection register: %d\n",
 259                           ret);
 260                goto free;
 261        }
 262
 263        netdev_dbg(dev->net, "AX_CMD_SW_PHY_STATUS = 0x%02x\n", buf[0]);
 264        switch (buf[0] & AX_PHY_SELECT_MASK) {
 265        case AX_PHY_SELECT_INTERNAL:
 266                netdev_dbg(dev->net, "use internal phy\n");
 267                priv->use_embdphy = 1;
 268                break;
 269        case AX_PHY_SELECT_EXTERNAL:
 270                netdev_dbg(dev->net, "use external phy\n");
 271                priv->use_embdphy = 0;
 272                break;
 273        default:
 274                netdev_err(dev->net, "Interface mode not supported by driver\n");
 275                ret = -ENOTSUPP;
 276                goto free;
 277        }
 278
 279        priv->phy_addr = asix_read_phy_addr(dev, priv->use_embdphy);
 280        ax88172a_reset_phy(dev, priv->use_embdphy);
 281
 282        /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */
 283        if (dev->driver_info->flags & FLAG_FRAMING_AX) {
 284                /* hard_mtu  is still the default - the device does not support
 285                   jumbo eth frames */
 286                dev->rx_urb_size = 2048;
 287        }
 288
 289        /* init MDIO bus */
 290        ret = ax88172a_init_mdio(dev);
 291        if (ret)
 292                goto free;
 293
 294        return 0;
 295
 296free:
 297        kfree(priv);
 298        return ret;
 299}
 300
 301static int ax88172a_stop(struct usbnet *dev)
 302{
 303        struct ax88172a_private *priv = dev->driver_priv;
 304
 305        netdev_dbg(dev->net, "Stopping interface\n");
 306
 307        if (priv->phydev) {
 308                netdev_info(dev->net, "Disconnecting from phy %s\n",
 309                            priv->phy_name);
 310                phy_stop(priv->phydev);
 311                phy_disconnect(priv->phydev);
 312        }
 313
 314        return 0;
 315}
 316
 317static void ax88172a_unbind(struct usbnet *dev, struct usb_interface *intf)
 318{
 319        struct ax88172a_private *priv = dev->driver_priv;
 320
 321        ax88172a_remove_mdio(dev);
 322        kfree(priv);
 323}
 324
 325static int ax88172a_reset(struct usbnet *dev)
 326{
 327        struct asix_data *data = (struct asix_data *)&dev->data;
 328        struct ax88172a_private *priv = dev->driver_priv;
 329        int ret;
 330        u16 rx_ctl;
 331
 332        ax88172a_reset_phy(dev, priv->use_embdphy);
 333
 334        msleep(150);
 335        rx_ctl = asix_read_rx_ctl(dev);
 336        netdev_dbg(dev->net, "RX_CTL is 0x%04x after software reset\n", rx_ctl);
 337        ret = asix_write_rx_ctl(dev, 0x0000);
 338        if (ret < 0)
 339                goto out;
 340
 341        rx_ctl = asix_read_rx_ctl(dev);
 342        netdev_dbg(dev->net, "RX_CTL is 0x%04x setting to 0x0000\n", rx_ctl);
 343
 344        msleep(150);
 345
 346        ret = asix_write_cmd(dev, AX_CMD_WRITE_IPG0,
 347                             AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT,
 348                             AX88772_IPG2_DEFAULT, 0, NULL);
 349        if (ret < 0) {
 350                netdev_err(dev->net, "Write IPG,IPG1,IPG2 failed: %d\n", ret);
 351                goto out;
 352        }
 353
 354        /* Rewrite MAC address */
 355        memcpy(data->mac_addr, dev->net->dev_addr, ETH_ALEN);
 356        ret = asix_write_cmd(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN,
 357                             data->mac_addr);
 358        if (ret < 0)
 359                goto out;
 360
 361        /* Set RX_CTL to default values with 2k buffer, and enable cactus */
 362        ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL);
 363        if (ret < 0)
 364                goto out;
 365
 366        rx_ctl = asix_read_rx_ctl(dev);
 367        netdev_dbg(dev->net, "RX_CTL is 0x%04x after all initializations\n",
 368                   rx_ctl);
 369
 370        rx_ctl = asix_read_medium_status(dev);
 371        netdev_dbg(dev->net, "Medium Status is 0x%04x after all initializations\n",
 372                   rx_ctl);
 373
 374        /* Connect to PHY */
 375        snprintf(priv->phy_name, 20, PHY_ID_FMT,
 376                 priv->mdio->id, priv->phy_addr);
 377
 378        priv->phydev = phy_connect(dev->net, priv->phy_name,
 379                                   &ax88172a_adjust_link,
 380                                   PHY_INTERFACE_MODE_MII);
 381        if (IS_ERR(priv->phydev)) {
 382                netdev_err(dev->net, "Could not connect to PHY device %s\n",
 383                           priv->phy_name);
 384                ret = PTR_ERR(priv->phydev);
 385                goto out;
 386        }
 387
 388        netdev_info(dev->net, "Connected to phy %s\n", priv->phy_name);
 389
 390        /* During power-up, the AX88172A set the power down (BMCR_PDOWN)
 391         * bit of the PHY. Bring the PHY up again.
 392         */
 393        genphy_resume(priv->phydev);
 394        phy_start(priv->phydev);
 395
 396        return 0;
 397
 398out:
 399        return ret;
 400
 401}
 402
 403static int ax88172a_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
 404{
 405        struct ax88172a_private *dp = dev->driver_priv;
 406        struct asix_rx_fixup_info *rx = &dp->rx_fixup_info;
 407
 408        return asix_rx_fixup_internal(dev, skb, rx);
 409}
 410
 411const struct driver_info ax88172a_info = {
 412        .description = "ASIX AX88172A USB 2.0 Ethernet",
 413        .bind = ax88172a_bind,
 414        .reset = ax88172a_reset,
 415        .stop = ax88172a_stop,
 416        .unbind = ax88172a_unbind,
 417        .status = ax88172a_status,
 418        .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR |
 419                 FLAG_MULTI_PACKET,
 420        .rx_fixup = ax88172a_rx_fixup,
 421        .tx_fixup = asix_tx_fixup,
 422};
 423