Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * ASIX AX8817X based USB 2.0 Ethernet Devices
0004  * Copyright (C) 2003-2006 David Hollis <dhollis@davehollis.com>
0005  * Copyright (C) 2005 Phil Chang <pchang23@sbcglobal.net>
0006  * Copyright (C) 2006 James Painter <jamie.painter@iname.com>
0007  * Copyright (c) 2002-2003 TiVo Inc.
0008  */
0009 
0010 #include "asix.h"
0011 
0012 #define AX_HOST_EN_RETRIES  30
0013 
0014 int __must_check asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
0015                    u16 size, void *data, int in_pm)
0016 {
0017     int ret;
0018     int (*fn)(struct usbnet *, u8, u8, u16, u16, void *, u16);
0019 
0020     BUG_ON(!dev);
0021 
0022     if (!in_pm)
0023         fn = usbnet_read_cmd;
0024     else
0025         fn = usbnet_read_cmd_nopm;
0026 
0027     ret = fn(dev, cmd, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0028          value, index, data, size);
0029 
0030     if (unlikely(ret < size)) {
0031         ret = ret < 0 ? ret : -ENODATA;
0032 
0033         netdev_warn(dev->net, "Failed to read reg index 0x%04x: %d\n",
0034                 index, ret);
0035     }
0036 
0037     return ret;
0038 }
0039 
0040 int asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
0041            u16 size, void *data, int in_pm)
0042 {
0043     int ret;
0044     int (*fn)(struct usbnet *, u8, u8, u16, u16, const void *, u16);
0045 
0046     BUG_ON(!dev);
0047 
0048     if (!in_pm)
0049         fn = usbnet_write_cmd;
0050     else
0051         fn = usbnet_write_cmd_nopm;
0052 
0053     ret = fn(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0054          value, index, data, size);
0055 
0056     if (unlikely(ret < 0))
0057         netdev_warn(dev->net, "Failed to write reg index 0x%04x: %d\n",
0058                 index, ret);
0059 
0060     return ret;
0061 }
0062 
0063 void asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index,
0064               u16 size, void *data)
0065 {
0066     usbnet_write_cmd_async(dev, cmd,
0067                    USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0068                    value, index, data, size);
0069 }
0070 
0071 static int asix_set_sw_mii(struct usbnet *dev, int in_pm)
0072 {
0073     int ret;
0074 
0075     ret = asix_write_cmd(dev, AX_CMD_SET_SW_MII, 0x0000, 0, 0, NULL, in_pm);
0076 
0077     if (ret < 0)
0078         netdev_err(dev->net, "Failed to enable software MII access\n");
0079     return ret;
0080 }
0081 
0082 static int asix_set_hw_mii(struct usbnet *dev, int in_pm)
0083 {
0084     int ret;
0085 
0086     ret = asix_write_cmd(dev, AX_CMD_SET_HW_MII, 0x0000, 0, 0, NULL, in_pm);
0087     if (ret < 0)
0088         netdev_err(dev->net, "Failed to enable hardware MII access\n");
0089     return ret;
0090 }
0091 
0092 static int asix_check_host_enable(struct usbnet *dev, int in_pm)
0093 {
0094     int i, ret;
0095     u8 smsr;
0096 
0097     for (i = 0; i < AX_HOST_EN_RETRIES; ++i) {
0098         ret = asix_set_sw_mii(dev, in_pm);
0099         if (ret == -ENODEV || ret == -ETIMEDOUT)
0100             break;
0101         usleep_range(1000, 1100);
0102         ret = asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG,
0103                     0, 0, 1, &smsr, in_pm);
0104         if (ret == -ENODEV)
0105             break;
0106         else if (ret < 0)
0107             continue;
0108         else if (smsr & AX_HOST_EN)
0109             break;
0110     }
0111 
0112     return i >= AX_HOST_EN_RETRIES ? -ETIMEDOUT : ret;
0113 }
0114 
0115 static void reset_asix_rx_fixup_info(struct asix_rx_fixup_info *rx)
0116 {
0117     /* Reset the variables that have a lifetime outside of
0118      * asix_rx_fixup_internal() so that future processing starts from a
0119      * known set of initial conditions.
0120      */
0121 
0122     if (rx->ax_skb) {
0123         /* Discard any incomplete Ethernet frame in the netdev buffer */
0124         kfree_skb(rx->ax_skb);
0125         rx->ax_skb = NULL;
0126     }
0127 
0128     /* Assume the Data header 32-bit word is at the start of the current
0129      * or next URB socket buffer so reset all the state variables.
0130      */
0131     rx->remaining = 0;
0132     rx->split_head = false;
0133     rx->header = 0;
0134 }
0135 
0136 int asix_rx_fixup_internal(struct usbnet *dev, struct sk_buff *skb,
0137                struct asix_rx_fixup_info *rx)
0138 {
0139     int offset = 0;
0140     u16 size;
0141 
0142     /* When an Ethernet frame spans multiple URB socket buffers,
0143      * do a sanity test for the Data header synchronisation.
0144      * Attempt to detect the situation of the previous socket buffer having
0145      * been truncated or a socket buffer was missing. These situations
0146      * cause a discontinuity in the data stream and therefore need to avoid
0147      * appending bad data to the end of the current netdev socket buffer.
0148      * Also avoid unnecessarily discarding a good current netdev socket
0149      * buffer.
0150      */
0151     if (rx->remaining && (rx->remaining + sizeof(u32) <= skb->len)) {
0152         offset = ((rx->remaining + 1) & 0xfffe);
0153         rx->header = get_unaligned_le32(skb->data + offset);
0154         offset = 0;
0155 
0156         size = (u16)(rx->header & 0x7ff);
0157         if (size != ((~rx->header >> 16) & 0x7ff)) {
0158             netdev_err(dev->net, "asix_rx_fixup() Data Header synchronisation was lost, remaining %d\n",
0159                    rx->remaining);
0160             reset_asix_rx_fixup_info(rx);
0161         }
0162     }
0163 
0164     while (offset + sizeof(u16) <= skb->len) {
0165         u16 copy_length;
0166 
0167         if (!rx->remaining) {
0168             if (skb->len - offset == sizeof(u16)) {
0169                 rx->header = get_unaligned_le16(
0170                         skb->data + offset);
0171                 rx->split_head = true;
0172                 offset += sizeof(u16);
0173                 break;
0174             }
0175 
0176             if (rx->split_head == true) {
0177                 rx->header |= (get_unaligned_le16(
0178                         skb->data + offset) << 16);
0179                 rx->split_head = false;
0180                 offset += sizeof(u16);
0181             } else {
0182                 rx->header = get_unaligned_le32(skb->data +
0183                                 offset);
0184                 offset += sizeof(u32);
0185             }
0186 
0187             /* take frame length from Data header 32-bit word */
0188             size = (u16)(rx->header & 0x7ff);
0189             if (size != ((~rx->header >> 16) & 0x7ff)) {
0190                 netdev_err(dev->net, "asix_rx_fixup() Bad Header Length 0x%x, offset %d\n",
0191                        rx->header, offset);
0192                 reset_asix_rx_fixup_info(rx);
0193                 return 0;
0194             }
0195             if (size > dev->net->mtu + ETH_HLEN + VLAN_HLEN) {
0196                 netdev_dbg(dev->net, "asix_rx_fixup() Bad RX Length %d\n",
0197                        size);
0198                 reset_asix_rx_fixup_info(rx);
0199                 return 0;
0200             }
0201 
0202             /* Sometimes may fail to get a netdev socket buffer but
0203              * continue to process the URB socket buffer so that
0204              * synchronisation of the Ethernet frame Data header
0205              * word is maintained.
0206              */
0207             rx->ax_skb = netdev_alloc_skb_ip_align(dev->net, size);
0208 
0209             rx->remaining = size;
0210         }
0211 
0212         if (rx->remaining > skb->len - offset) {
0213             copy_length = skb->len - offset;
0214             rx->remaining -= copy_length;
0215         } else {
0216             copy_length = rx->remaining;
0217             rx->remaining = 0;
0218         }
0219 
0220         if (rx->ax_skb) {
0221             skb_put_data(rx->ax_skb, skb->data + offset,
0222                      copy_length);
0223             if (!rx->remaining) {
0224                 usbnet_skb_return(dev, rx->ax_skb);
0225                 rx->ax_skb = NULL;
0226             }
0227         }
0228 
0229         offset += (copy_length + 1) & 0xfffe;
0230     }
0231 
0232     if (skb->len != offset) {
0233         netdev_err(dev->net, "asix_rx_fixup() Bad SKB Length %d, %d\n",
0234                skb->len, offset);
0235         reset_asix_rx_fixup_info(rx);
0236         return 0;
0237     }
0238 
0239     return 1;
0240 }
0241 
0242 int asix_rx_fixup_common(struct usbnet *dev, struct sk_buff *skb)
0243 {
0244     struct asix_common_private *dp = dev->driver_priv;
0245     struct asix_rx_fixup_info *rx = &dp->rx_fixup_info;
0246 
0247     return asix_rx_fixup_internal(dev, skb, rx);
0248 }
0249 
0250 void asix_rx_fixup_common_free(struct asix_common_private *dp)
0251 {
0252     struct asix_rx_fixup_info *rx;
0253 
0254     if (!dp)
0255         return;
0256 
0257     rx = &dp->rx_fixup_info;
0258 
0259     if (rx->ax_skb) {
0260         kfree_skb(rx->ax_skb);
0261         rx->ax_skb = NULL;
0262     }
0263 }
0264 
0265 struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
0266                   gfp_t flags)
0267 {
0268     int padlen;
0269     int headroom = skb_headroom(skb);
0270     int tailroom = skb_tailroom(skb);
0271     u32 packet_len;
0272     u32 padbytes = 0xffff0000;
0273     void *ptr;
0274 
0275     padlen = ((skb->len + 4) & (dev->maxpacket - 1)) ? 0 : 4;
0276 
0277     /* We need to push 4 bytes in front of frame (packet_len)
0278      * and maybe add 4 bytes after the end (if padlen is 4)
0279      *
0280      * Avoid skb_copy_expand() expensive call, using following rules :
0281      * - We are allowed to push 4 bytes in headroom if skb_header_cloned()
0282      *   is false (and if we have 4 bytes of headroom)
0283      * - We are allowed to put 4 bytes at tail if skb_cloned()
0284      *   is false (and if we have 4 bytes of tailroom)
0285      *
0286      * TCP packets for example are cloned, but __skb_header_release()
0287      * was called in tcp stack, allowing us to use headroom for our needs.
0288      */
0289     if (!skb_header_cloned(skb) &&
0290         !(padlen && skb_cloned(skb)) &&
0291         headroom + tailroom >= 4 + padlen) {
0292         /* following should not happen, but better be safe */
0293         if (headroom < 4 ||
0294             tailroom < padlen) {
0295             skb->data = memmove(skb->head + 4, skb->data, skb->len);
0296             skb_set_tail_pointer(skb, skb->len);
0297         }
0298     } else {
0299         struct sk_buff *skb2;
0300 
0301         skb2 = skb_copy_expand(skb, 4, padlen, flags);
0302         dev_kfree_skb_any(skb);
0303         skb = skb2;
0304         if (!skb)
0305             return NULL;
0306     }
0307 
0308     packet_len = ((skb->len ^ 0x0000ffff) << 16) + skb->len;
0309     ptr = skb_push(skb, 4);
0310     put_unaligned_le32(packet_len, ptr);
0311 
0312     if (padlen) {
0313         put_unaligned_le32(padbytes, skb_tail_pointer(skb));
0314         skb_put(skb, sizeof(padbytes));
0315     }
0316 
0317     usbnet_set_skb_tx_stats(skb, 1, 0);
0318     return skb;
0319 }
0320 
0321 int asix_read_phy_addr(struct usbnet *dev, bool internal)
0322 {
0323     int ret, offset;
0324     u8 buf[2];
0325 
0326     ret = asix_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf, 0);
0327     if (ret < 0)
0328         goto error;
0329 
0330     if (ret < 2) {
0331         ret = -EIO;
0332         goto error;
0333     }
0334 
0335     offset = (internal ? 1 : 0);
0336     ret = buf[offset];
0337 
0338     netdev_dbg(dev->net, "%s PHY address 0x%x\n",
0339            internal ? "internal" : "external", ret);
0340 
0341     return ret;
0342 
0343 error:
0344     netdev_err(dev->net, "Error reading PHY_ID register: %02x\n", ret);
0345 
0346     return ret;
0347 }
0348 
0349 int asix_sw_reset(struct usbnet *dev, u8 flags, int in_pm)
0350 {
0351     int ret;
0352 
0353     ret = asix_write_cmd(dev, AX_CMD_SW_RESET, flags, 0, 0, NULL, in_pm);
0354     if (ret < 0)
0355         netdev_err(dev->net, "Failed to send software reset: %02x\n", ret);
0356 
0357     return ret;
0358 }
0359 
0360 u16 asix_read_rx_ctl(struct usbnet *dev, int in_pm)
0361 {
0362     __le16 v;
0363     int ret = asix_read_cmd(dev, AX_CMD_READ_RX_CTL, 0, 0, 2, &v, in_pm);
0364 
0365     if (ret < 0) {
0366         netdev_err(dev->net, "Error reading RX_CTL register: %02x\n", ret);
0367         goto out;
0368     }
0369     ret = le16_to_cpu(v);
0370 out:
0371     return ret;
0372 }
0373 
0374 int asix_write_rx_ctl(struct usbnet *dev, u16 mode, int in_pm)
0375 {
0376     int ret;
0377 
0378     netdev_dbg(dev->net, "asix_write_rx_ctl() - mode = 0x%04x\n", mode);
0379     ret = asix_write_cmd(dev, AX_CMD_WRITE_RX_CTL, mode, 0, 0, NULL, in_pm);
0380     if (ret < 0)
0381         netdev_err(dev->net, "Failed to write RX_CTL mode to 0x%04x: %02x\n",
0382                mode, ret);
0383 
0384     return ret;
0385 }
0386 
0387 u16 asix_read_medium_status(struct usbnet *dev, int in_pm)
0388 {
0389     __le16 v;
0390     int ret = asix_read_cmd(dev, AX_CMD_READ_MEDIUM_STATUS,
0391                 0, 0, 2, &v, in_pm);
0392 
0393     if (ret < 0) {
0394         netdev_err(dev->net, "Error reading Medium Status register: %02x\n",
0395                ret);
0396         return ret; /* TODO: callers not checking for error ret */
0397     }
0398 
0399     return le16_to_cpu(v);
0400 
0401 }
0402 
0403 int asix_write_medium_mode(struct usbnet *dev, u16 mode, int in_pm)
0404 {
0405     int ret;
0406 
0407     netdev_dbg(dev->net, "asix_write_medium_mode() - mode = 0x%04x\n", mode);
0408     ret = asix_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE,
0409                  mode, 0, 0, NULL, in_pm);
0410     if (ret < 0)
0411         netdev_err(dev->net, "Failed to write Medium Mode mode to 0x%04x: %02x\n",
0412                mode, ret);
0413 
0414     return ret;
0415 }
0416 
0417 /* set MAC link settings according to information from phylib */
0418 void asix_adjust_link(struct net_device *netdev)
0419 {
0420     struct phy_device *phydev = netdev->phydev;
0421     struct usbnet *dev = netdev_priv(netdev);
0422     u16 mode = 0;
0423 
0424     if (phydev->link) {
0425         mode = AX88772_MEDIUM_DEFAULT;
0426 
0427         if (phydev->duplex == DUPLEX_HALF)
0428             mode &= ~AX_MEDIUM_FD;
0429 
0430         if (phydev->speed != SPEED_100)
0431             mode &= ~AX_MEDIUM_PS;
0432     }
0433 
0434     asix_write_medium_mode(dev, mode, 0);
0435     phy_print_status(phydev);
0436     usbnet_link_change(dev, phydev->link, 0);
0437 }
0438 
0439 int asix_write_gpio(struct usbnet *dev, u16 value, int sleep, int in_pm)
0440 {
0441     int ret;
0442 
0443     netdev_dbg(dev->net, "asix_write_gpio() - value = 0x%04x\n", value);
0444     ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, value, 0, 0, NULL, in_pm);
0445     if (ret < 0)
0446         netdev_err(dev->net, "Failed to write GPIO value 0x%04x: %02x\n",
0447                value, ret);
0448 
0449     if (sleep)
0450         msleep(sleep);
0451 
0452     return ret;
0453 }
0454 
0455 /*
0456  * AX88772 & AX88178 have a 16-bit RX_CTL value
0457  */
0458 void asix_set_multicast(struct net_device *net)
0459 {
0460     struct usbnet *dev = netdev_priv(net);
0461     struct asix_data *data = (struct asix_data *)&dev->data;
0462     u16 rx_ctl = AX_DEFAULT_RX_CTL;
0463 
0464     if (net->flags & IFF_PROMISC) {
0465         rx_ctl |= AX_RX_CTL_PRO;
0466     } else if (net->flags & IFF_ALLMULTI ||
0467            netdev_mc_count(net) > AX_MAX_MCAST) {
0468         rx_ctl |= AX_RX_CTL_AMALL;
0469     } else if (netdev_mc_empty(net)) {
0470         /* just broadcast and directed */
0471     } else {
0472         /* We use the 20 byte dev->data
0473          * for our 8 byte filter buffer
0474          * to avoid allocating memory that
0475          * is tricky to free later */
0476         struct netdev_hw_addr *ha;
0477         u32 crc_bits;
0478 
0479         memset(data->multi_filter, 0, AX_MCAST_FILTER_SIZE);
0480 
0481         /* Build the multicast hash filter. */
0482         netdev_for_each_mc_addr(ha, net) {
0483             crc_bits = ether_crc(ETH_ALEN, ha->addr) >> 26;
0484             data->multi_filter[crc_bits >> 3] |=
0485                 1 << (crc_bits & 7);
0486         }
0487 
0488         asix_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0,
0489                    AX_MCAST_FILTER_SIZE, data->multi_filter);
0490 
0491         rx_ctl |= AX_RX_CTL_AM;
0492     }
0493 
0494     asix_write_cmd_async(dev, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL);
0495 }
0496 
0497 static int __asix_mdio_read(struct net_device *netdev, int phy_id, int loc,
0498                 bool in_pm)
0499 {
0500     struct usbnet *dev = netdev_priv(netdev);
0501     __le16 res;
0502     int ret;
0503 
0504     mutex_lock(&dev->phy_mutex);
0505 
0506     ret = asix_check_host_enable(dev, in_pm);
0507     if (ret == -ENODEV || ret == -ETIMEDOUT) {
0508         mutex_unlock(&dev->phy_mutex);
0509         return ret;
0510     }
0511 
0512     ret = asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, (__u16)loc, 2,
0513                 &res, in_pm);
0514     if (ret < 0)
0515         goto out;
0516 
0517     ret = asix_set_hw_mii(dev, in_pm);
0518 out:
0519     mutex_unlock(&dev->phy_mutex);
0520 
0521     netdev_dbg(dev->net, "asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n",
0522             phy_id, loc, le16_to_cpu(res));
0523 
0524     return ret < 0 ? ret : le16_to_cpu(res);
0525 }
0526 
0527 int asix_mdio_read(struct net_device *netdev, int phy_id, int loc)
0528 {
0529     return __asix_mdio_read(netdev, phy_id, loc, false);
0530 }
0531 
0532 static int __asix_mdio_write(struct net_device *netdev, int phy_id, int loc,
0533                  int val, bool in_pm)
0534 {
0535     struct usbnet *dev = netdev_priv(netdev);
0536     __le16 res = cpu_to_le16(val);
0537     int ret;
0538 
0539     netdev_dbg(dev->net, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n",
0540             phy_id, loc, val);
0541 
0542     mutex_lock(&dev->phy_mutex);
0543 
0544     ret = asix_check_host_enable(dev, in_pm);
0545     if (ret == -ENODEV)
0546         goto out;
0547 
0548     ret = asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2,
0549                  &res, in_pm);
0550     if (ret < 0)
0551         goto out;
0552 
0553     ret = asix_set_hw_mii(dev, in_pm);
0554 out:
0555     mutex_unlock(&dev->phy_mutex);
0556 
0557     return ret < 0 ? ret : 0;
0558 }
0559 
0560 void asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val)
0561 {
0562     __asix_mdio_write(netdev, phy_id, loc, val, false);
0563 }
0564 
0565 /* MDIO read and write wrappers for phylib */
0566 int asix_mdio_bus_read(struct mii_bus *bus, int phy_id, int regnum)
0567 {
0568     struct usbnet *priv = bus->priv;
0569 
0570     return __asix_mdio_read(priv->net, phy_id, regnum, false);
0571 }
0572 
0573 int asix_mdio_bus_write(struct mii_bus *bus, int phy_id, int regnum, u16 val)
0574 {
0575     struct usbnet *priv = bus->priv;
0576 
0577     return __asix_mdio_write(priv->net, phy_id, regnum, val, false);
0578 }
0579 
0580 int asix_mdio_read_nopm(struct net_device *netdev, int phy_id, int loc)
0581 {
0582     return __asix_mdio_read(netdev, phy_id, loc, true);
0583 }
0584 
0585 void
0586 asix_mdio_write_nopm(struct net_device *netdev, int phy_id, int loc, int val)
0587 {
0588     __asix_mdio_write(netdev, phy_id, loc, val, true);
0589 }
0590 
0591 void asix_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
0592 {
0593     struct usbnet *dev = netdev_priv(net);
0594     u8 opt;
0595 
0596     if (asix_read_cmd(dev, AX_CMD_READ_MONITOR_MODE,
0597               0, 0, 1, &opt, 0) < 0) {
0598         wolinfo->supported = 0;
0599         wolinfo->wolopts = 0;
0600         return;
0601     }
0602     wolinfo->supported = WAKE_PHY | WAKE_MAGIC;
0603     wolinfo->wolopts = 0;
0604     if (opt & AX_MONITOR_LINK)
0605         wolinfo->wolopts |= WAKE_PHY;
0606     if (opt & AX_MONITOR_MAGIC)
0607         wolinfo->wolopts |= WAKE_MAGIC;
0608 }
0609 
0610 int asix_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
0611 {
0612     struct usbnet *dev = netdev_priv(net);
0613     u8 opt = 0;
0614 
0615     if (wolinfo->wolopts & ~(WAKE_PHY | WAKE_MAGIC))
0616         return -EINVAL;
0617 
0618     if (wolinfo->wolopts & WAKE_PHY)
0619         opt |= AX_MONITOR_LINK;
0620     if (wolinfo->wolopts & WAKE_MAGIC)
0621         opt |= AX_MONITOR_MAGIC;
0622 
0623     if (asix_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE,
0624                   opt, 0, 0, NULL, 0) < 0)
0625         return -EINVAL;
0626 
0627     return 0;
0628 }
0629 
0630 int asix_get_eeprom_len(struct net_device *net)
0631 {
0632     return AX_EEPROM_LEN;
0633 }
0634 
0635 int asix_get_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom,
0636             u8 *data)
0637 {
0638     struct usbnet *dev = netdev_priv(net);
0639     u16 *eeprom_buff;
0640     int first_word, last_word;
0641     int i;
0642 
0643     if (eeprom->len == 0)
0644         return -EINVAL;
0645 
0646     eeprom->magic = AX_EEPROM_MAGIC;
0647 
0648     first_word = eeprom->offset >> 1;
0649     last_word = (eeprom->offset + eeprom->len - 1) >> 1;
0650 
0651     eeprom_buff = kmalloc_array(last_word - first_word + 1, sizeof(u16),
0652                     GFP_KERNEL);
0653     if (!eeprom_buff)
0654         return -ENOMEM;
0655 
0656     /* ax8817x returns 2 bytes from eeprom on read */
0657     for (i = first_word; i <= last_word; i++) {
0658         if (asix_read_cmd(dev, AX_CMD_READ_EEPROM, i, 0, 2,
0659                   &eeprom_buff[i - first_word], 0) < 0) {
0660             kfree(eeprom_buff);
0661             return -EIO;
0662         }
0663     }
0664 
0665     memcpy(data, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len);
0666     kfree(eeprom_buff);
0667     return 0;
0668 }
0669 
0670 int asix_set_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom,
0671             u8 *data)
0672 {
0673     struct usbnet *dev = netdev_priv(net);
0674     u16 *eeprom_buff;
0675     int first_word, last_word;
0676     int i;
0677     int ret;
0678 
0679     netdev_dbg(net, "write EEPROM len %d, offset %d, magic 0x%x\n",
0680            eeprom->len, eeprom->offset, eeprom->magic);
0681 
0682     if (eeprom->len == 0)
0683         return -EINVAL;
0684 
0685     if (eeprom->magic != AX_EEPROM_MAGIC)
0686         return -EINVAL;
0687 
0688     first_word = eeprom->offset >> 1;
0689     last_word = (eeprom->offset + eeprom->len - 1) >> 1;
0690 
0691     eeprom_buff = kmalloc_array(last_word - first_word + 1, sizeof(u16),
0692                     GFP_KERNEL);
0693     if (!eeprom_buff)
0694         return -ENOMEM;
0695 
0696     /* align data to 16 bit boundaries, read the missing data from
0697        the EEPROM */
0698     if (eeprom->offset & 1) {
0699         ret = asix_read_cmd(dev, AX_CMD_READ_EEPROM, first_word, 0, 2,
0700                     &eeprom_buff[0], 0);
0701         if (ret < 0) {
0702             netdev_err(net, "Failed to read EEPROM at offset 0x%02x.\n", first_word);
0703             goto free;
0704         }
0705     }
0706 
0707     if ((eeprom->offset + eeprom->len) & 1) {
0708         ret = asix_read_cmd(dev, AX_CMD_READ_EEPROM, last_word, 0, 2,
0709                     &eeprom_buff[last_word - first_word], 0);
0710         if (ret < 0) {
0711             netdev_err(net, "Failed to read EEPROM at offset 0x%02x.\n", last_word);
0712             goto free;
0713         }
0714     }
0715 
0716     memcpy((u8 *)eeprom_buff + (eeprom->offset & 1), data, eeprom->len);
0717 
0718     /* write data to EEPROM */
0719     ret = asix_write_cmd(dev, AX_CMD_WRITE_ENABLE, 0x0000, 0, 0, NULL, 0);
0720     if (ret < 0) {
0721         netdev_err(net, "Failed to enable EEPROM write\n");
0722         goto free;
0723     }
0724     msleep(20);
0725 
0726     for (i = first_word; i <= last_word; i++) {
0727         netdev_dbg(net, "write to EEPROM at offset 0x%02x, data 0x%04x\n",
0728                i, eeprom_buff[i - first_word]);
0729         ret = asix_write_cmd(dev, AX_CMD_WRITE_EEPROM, i,
0730                      eeprom_buff[i - first_word], 0, NULL, 0);
0731         if (ret < 0) {
0732             netdev_err(net, "Failed to write EEPROM at offset 0x%02x.\n",
0733                    i);
0734             goto free;
0735         }
0736         msleep(20);
0737     }
0738 
0739     ret = asix_write_cmd(dev, AX_CMD_WRITE_DISABLE, 0x0000, 0, 0, NULL, 0);
0740     if (ret < 0) {
0741         netdev_err(net, "Failed to disable EEPROM write\n");
0742         goto free;
0743     }
0744 
0745     ret = 0;
0746 free:
0747     kfree(eeprom_buff);
0748     return ret;
0749 }
0750 
0751 void asix_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info)
0752 {
0753     /* Inherit standard device info */
0754     usbnet_get_drvinfo(net, info);
0755     strlcpy(info->driver, DRIVER_NAME, sizeof(info->driver));
0756     strlcpy(info->version, DRIVER_VERSION, sizeof(info->version));
0757 }
0758 
0759 int asix_set_mac_address(struct net_device *net, void *p)
0760 {
0761     struct usbnet *dev = netdev_priv(net);
0762     struct asix_data *data = (struct asix_data *)&dev->data;
0763     struct sockaddr *addr = p;
0764 
0765     if (netif_running(net))
0766         return -EBUSY;
0767     if (!is_valid_ether_addr(addr->sa_data))
0768         return -EADDRNOTAVAIL;
0769 
0770     eth_hw_addr_set(net, addr->sa_data);
0771 
0772     /* We use the 20 byte dev->data
0773      * for our 6 byte mac buffer
0774      * to avoid allocating memory that
0775      * is tricky to free later */
0776     memcpy(data->mac_addr, addr->sa_data, ETH_ALEN);
0777     asix_write_cmd_async(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN,
0778                             data->mac_addr);
0779 
0780     return 0;
0781 }