0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include "asix.h"
0016 #include <linux/phy.h>
0017
0018 struct ax88172a_private {
0019 struct mii_bus *mdio;
0020 struct phy_device *phydev;
0021 char phy_name[20];
0022 u16 phy_addr;
0023 u16 oldmode;
0024 int use_embdphy;
0025 struct asix_rx_fixup_info rx_fixup_info;
0026 };
0027
0028
0029 static void ax88172a_adjust_link(struct net_device *netdev)
0030 {
0031 struct phy_device *phydev = netdev->phydev;
0032 struct usbnet *dev = netdev_priv(netdev);
0033 struct ax88172a_private *priv = dev->driver_priv;
0034 u16 mode = 0;
0035
0036 if (phydev->link) {
0037 mode = AX88772_MEDIUM_DEFAULT;
0038
0039 if (phydev->duplex == DUPLEX_HALF)
0040 mode &= ~AX_MEDIUM_FD;
0041
0042 if (phydev->speed != SPEED_100)
0043 mode &= ~AX_MEDIUM_PS;
0044 }
0045
0046 if (mode != priv->oldmode) {
0047 asix_write_medium_mode(dev, mode, 0);
0048 priv->oldmode = mode;
0049 netdev_dbg(netdev, "speed %u duplex %d, setting mode to 0x%04x\n",
0050 phydev->speed, phydev->duplex, mode);
0051 phy_print_status(phydev);
0052 }
0053 }
0054
0055 static void ax88172a_status(struct usbnet *dev, struct urb *urb)
0056 {
0057
0058 }
0059
0060
0061 static int ax88172a_init_mdio(struct usbnet *dev)
0062 {
0063 struct ax88172a_private *priv = dev->driver_priv;
0064 int ret;
0065
0066 priv->mdio = mdiobus_alloc();
0067 if (!priv->mdio) {
0068 netdev_err(dev->net, "Could not allocate MDIO bus\n");
0069 return -ENOMEM;
0070 }
0071
0072 priv->mdio->priv = (void *)dev;
0073 priv->mdio->read = &asix_mdio_bus_read;
0074 priv->mdio->write = &asix_mdio_bus_write;
0075 priv->mdio->name = "Asix MDIO Bus";
0076
0077 snprintf(priv->mdio->id, MII_BUS_ID_SIZE, "usb-%03d:%03d",
0078 dev->udev->bus->busnum, dev->udev->devnum);
0079
0080 ret = mdiobus_register(priv->mdio);
0081 if (ret) {
0082 netdev_err(dev->net, "Could not register MDIO bus\n");
0083 goto mfree;
0084 }
0085
0086 netdev_info(dev->net, "registered mdio bus %s\n", priv->mdio->id);
0087 return 0;
0088
0089 mfree:
0090 mdiobus_free(priv->mdio);
0091 return ret;
0092 }
0093
0094 static void ax88172a_remove_mdio(struct usbnet *dev)
0095 {
0096 struct ax88172a_private *priv = dev->driver_priv;
0097
0098 netdev_info(dev->net, "deregistering mdio bus %s\n", priv->mdio->id);
0099 mdiobus_unregister(priv->mdio);
0100 mdiobus_free(priv->mdio);
0101 }
0102
0103 static const struct net_device_ops ax88172a_netdev_ops = {
0104 .ndo_open = usbnet_open,
0105 .ndo_stop = usbnet_stop,
0106 .ndo_start_xmit = usbnet_start_xmit,
0107 .ndo_tx_timeout = usbnet_tx_timeout,
0108 .ndo_change_mtu = usbnet_change_mtu,
0109 .ndo_get_stats64 = dev_get_tstats64,
0110 .ndo_set_mac_address = asix_set_mac_address,
0111 .ndo_validate_addr = eth_validate_addr,
0112 .ndo_eth_ioctl = phy_do_ioctl_running,
0113 .ndo_set_rx_mode = asix_set_multicast,
0114 };
0115
0116 static const struct ethtool_ops ax88172a_ethtool_ops = {
0117 .get_drvinfo = asix_get_drvinfo,
0118 .get_link = usbnet_get_link,
0119 .get_msglevel = usbnet_get_msglevel,
0120 .set_msglevel = usbnet_set_msglevel,
0121 .get_wol = asix_get_wol,
0122 .set_wol = asix_set_wol,
0123 .get_eeprom_len = asix_get_eeprom_len,
0124 .get_eeprom = asix_get_eeprom,
0125 .set_eeprom = asix_set_eeprom,
0126 .nway_reset = phy_ethtool_nway_reset,
0127 .get_link_ksettings = phy_ethtool_get_link_ksettings,
0128 .set_link_ksettings = phy_ethtool_set_link_ksettings,
0129 };
0130
0131 static int ax88172a_reset_phy(struct usbnet *dev, int embd_phy)
0132 {
0133 int ret;
0134
0135 ret = asix_sw_reset(dev, AX_SWRESET_IPPD, 0);
0136 if (ret < 0)
0137 goto err;
0138
0139 msleep(150);
0140 ret = asix_sw_reset(dev, AX_SWRESET_CLEAR, 0);
0141 if (ret < 0)
0142 goto err;
0143
0144 msleep(150);
0145
0146 ret = asix_sw_reset(dev, embd_phy ? AX_SWRESET_IPRL : AX_SWRESET_IPPD,
0147 0);
0148 if (ret < 0)
0149 goto err;
0150
0151 return 0;
0152
0153 err:
0154 return ret;
0155 }
0156
0157
0158 static int ax88172a_bind(struct usbnet *dev, struct usb_interface *intf)
0159 {
0160 int ret;
0161 u8 buf[ETH_ALEN];
0162 struct ax88172a_private *priv;
0163
0164 usbnet_get_endpoints(dev, intf);
0165
0166 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
0167 if (!priv)
0168 return -ENOMEM;
0169
0170 dev->driver_priv = priv;
0171
0172
0173 ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf, 0);
0174 if (ret < ETH_ALEN) {
0175 netdev_err(dev->net, "Failed to read MAC address: %d\n", ret);
0176 ret = -EIO;
0177 goto free;
0178 }
0179 eth_hw_addr_set(dev->net, buf);
0180
0181 dev->net->netdev_ops = &ax88172a_netdev_ops;
0182 dev->net->ethtool_ops = &ax88172a_ethtool_ops;
0183
0184
0185 ret = asix_read_cmd(dev, AX_CMD_SW_PHY_STATUS, 0, 0, 1, buf, 0);
0186 if (ret < 0) {
0187 netdev_err(dev->net, "Failed to read software interface selection register: %d\n",
0188 ret);
0189 goto free;
0190 }
0191
0192 netdev_dbg(dev->net, "AX_CMD_SW_PHY_STATUS = 0x%02x\n", buf[0]);
0193 switch (buf[0] & AX_PHY_SELECT_MASK) {
0194 case AX_PHY_SELECT_INTERNAL:
0195 netdev_dbg(dev->net, "use internal phy\n");
0196 priv->use_embdphy = 1;
0197 break;
0198 case AX_PHY_SELECT_EXTERNAL:
0199 netdev_dbg(dev->net, "use external phy\n");
0200 priv->use_embdphy = 0;
0201 break;
0202 default:
0203 netdev_err(dev->net, "Interface mode not supported by driver\n");
0204 ret = -ENOTSUPP;
0205 goto free;
0206 }
0207
0208 ret = asix_read_phy_addr(dev, priv->use_embdphy);
0209 if (ret < 0)
0210 goto free;
0211
0212 priv->phy_addr = ret;
0213
0214 ax88172a_reset_phy(dev, priv->use_embdphy);
0215
0216
0217 if (dev->driver_info->flags & FLAG_FRAMING_AX) {
0218
0219
0220 dev->rx_urb_size = 2048;
0221 }
0222
0223
0224 ret = ax88172a_init_mdio(dev);
0225 if (ret)
0226 goto free;
0227
0228 return 0;
0229
0230 free:
0231 kfree(priv);
0232 return ret;
0233 }
0234
0235 static int ax88172a_stop(struct usbnet *dev)
0236 {
0237 struct ax88172a_private *priv = dev->driver_priv;
0238
0239 netdev_dbg(dev->net, "Stopping interface\n");
0240
0241 if (priv->phydev) {
0242 netdev_info(dev->net, "Disconnecting from phy %s\n",
0243 priv->phy_name);
0244 phy_stop(priv->phydev);
0245 phy_disconnect(priv->phydev);
0246 }
0247
0248 return 0;
0249 }
0250
0251 static void ax88172a_unbind(struct usbnet *dev, struct usb_interface *intf)
0252 {
0253 struct ax88172a_private *priv = dev->driver_priv;
0254
0255 ax88172a_remove_mdio(dev);
0256 kfree(priv);
0257 }
0258
0259 static int ax88172a_reset(struct usbnet *dev)
0260 {
0261 struct asix_data *data = (struct asix_data *)&dev->data;
0262 struct ax88172a_private *priv = dev->driver_priv;
0263 int ret;
0264 u16 rx_ctl;
0265
0266 ax88172a_reset_phy(dev, priv->use_embdphy);
0267
0268 msleep(150);
0269 rx_ctl = asix_read_rx_ctl(dev, 0);
0270 netdev_dbg(dev->net, "RX_CTL is 0x%04x after software reset\n", rx_ctl);
0271 ret = asix_write_rx_ctl(dev, 0x0000, 0);
0272 if (ret < 0)
0273 goto out;
0274
0275 rx_ctl = asix_read_rx_ctl(dev, 0);
0276 netdev_dbg(dev->net, "RX_CTL is 0x%04x setting to 0x0000\n", rx_ctl);
0277
0278 msleep(150);
0279
0280 ret = asix_write_cmd(dev, AX_CMD_WRITE_IPG0,
0281 AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT,
0282 AX88772_IPG2_DEFAULT, 0, NULL, 0);
0283 if (ret < 0) {
0284 netdev_err(dev->net, "Write IPG,IPG1,IPG2 failed: %d\n", ret);
0285 goto out;
0286 }
0287
0288
0289 memcpy(data->mac_addr, dev->net->dev_addr, ETH_ALEN);
0290 ret = asix_write_cmd(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN,
0291 data->mac_addr, 0);
0292 if (ret < 0)
0293 goto out;
0294
0295
0296 ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL, 0);
0297 if (ret < 0)
0298 goto out;
0299
0300 rx_ctl = asix_read_rx_ctl(dev, 0);
0301 netdev_dbg(dev->net, "RX_CTL is 0x%04x after all initializations\n",
0302 rx_ctl);
0303
0304 rx_ctl = asix_read_medium_status(dev, 0);
0305 netdev_dbg(dev->net, "Medium Status is 0x%04x after all initializations\n",
0306 rx_ctl);
0307
0308
0309 snprintf(priv->phy_name, 20, PHY_ID_FMT,
0310 priv->mdio->id, priv->phy_addr);
0311
0312 priv->phydev = phy_connect(dev->net, priv->phy_name,
0313 &ax88172a_adjust_link,
0314 PHY_INTERFACE_MODE_MII);
0315 if (IS_ERR(priv->phydev)) {
0316 netdev_err(dev->net, "Could not connect to PHY device %s\n",
0317 priv->phy_name);
0318 ret = PTR_ERR(priv->phydev);
0319 goto out;
0320 }
0321
0322 netdev_info(dev->net, "Connected to phy %s\n", priv->phy_name);
0323
0324
0325
0326
0327 genphy_resume(priv->phydev);
0328 phy_start(priv->phydev);
0329
0330 return 0;
0331
0332 out:
0333 return ret;
0334
0335 }
0336
0337 static int ax88172a_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
0338 {
0339 struct ax88172a_private *dp = dev->driver_priv;
0340 struct asix_rx_fixup_info *rx = &dp->rx_fixup_info;
0341
0342 return asix_rx_fixup_internal(dev, skb, rx);
0343 }
0344
0345 const struct driver_info ax88172a_info = {
0346 .description = "ASIX AX88172A USB 2.0 Ethernet",
0347 .bind = ax88172a_bind,
0348 .reset = ax88172a_reset,
0349 .stop = ax88172a_stop,
0350 .unbind = ax88172a_unbind,
0351 .status = ax88172a_status,
0352 .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR |
0353 FLAG_MULTI_PACKET,
0354 .rx_fixup = ax88172a_rx_fixup,
0355 .tx_fixup = asix_tx_fixup,
0356 };