include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[safe/jmp/linux-2.6] / drivers / net / usb / dm9601.c
index 49a30bd..04b2810 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/usb.h>
 #include <linux/crc32.h>
 #include <linux/usb/usbnet.h>
+#include <linux/slab.h>
 
 /* datasheet:
  http://ptm2.cc.utu.fi/ftp/network/cards/DM9601/From_NET/DM9601-DS-P01-930914.pdf
@@ -58,7 +59,7 @@ static int dm_read(struct usbnet *dev, u8 reg, u16 length, void *data)
        void *buf;
        int err = -ENOMEM;
 
-       devdbg(dev, "dm_read() reg=0x%02x length=%d", reg, length);
+       netdev_dbg(dev->net, "dm_read() reg=0x%02x length=%d\n", reg, length);
 
        buf = kmalloc(length, GFP_KERNEL);
        if (!buf)
@@ -89,7 +90,7 @@ static int dm_write(struct usbnet *dev, u8 reg, u16 length, void *data)
        void *buf = NULL;
        int err = -ENOMEM;
 
-       devdbg(dev, "dm_write() reg=0x%02x, length=%d", reg, length);
+       netdev_dbg(dev->net, "dm_write() reg=0x%02x, length=%d\n", reg, length);
 
        if (data) {
                buf = kmalloc(length, GFP_KERNEL);
@@ -112,7 +113,8 @@ static int dm_write(struct usbnet *dev, u8 reg, u16 length, void *data)
 
 static int dm_write_reg(struct usbnet *dev, u8 reg, u8 value)
 {
-       devdbg(dev, "dm_write_reg() reg=0x%02x, value=0x%02x", reg, value);
+       netdev_dbg(dev->net, "dm_write_reg() reg=0x%02x, value=0x%02x\n",
+                  reg, value);
        return usb_control_msg(dev->udev,
                               usb_sndctrlpipe(dev->udev, 0),
                               DM_WRITE_REG,
@@ -142,13 +144,13 @@ static void dm_write_async_helper(struct usbnet *dev, u8 reg, u8 value,
 
        urb = usb_alloc_urb(0, GFP_ATOMIC);
        if (!urb) {
-               deverr(dev, "Error allocating URB in dm_write_async_helper!");
+               netdev_err(dev->net, "Error allocating URB in dm_write_async_helper!\n");
                return;
        }
 
        req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC);
        if (!req) {
-               deverr(dev, "Failed to allocate memory for control request");
+               netdev_err(dev->net, "Failed to allocate memory for control request\n");
                usb_free_urb(urb);
                return;
        }
@@ -166,8 +168,8 @@ static void dm_write_async_helper(struct usbnet *dev, u8 reg, u8 value,
 
        status = usb_submit_urb(urb, GFP_ATOMIC);
        if (status < 0) {
-               deverr(dev, "Error submitting the control message: status=%d",
-                      status);
+               netdev_err(dev->net, "Error submitting the control message: status=%d\n",
+                          status);
                kfree(req);
                usb_free_urb(urb);
        }
@@ -175,15 +177,15 @@ static void dm_write_async_helper(struct usbnet *dev, u8 reg, u8 value,
 
 static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data)
 {
-       devdbg(dev, "dm_write_async() reg=0x%02x length=%d", reg, length);
+       netdev_dbg(dev->net, "dm_write_async() reg=0x%02x length=%d\n", reg, length);
 
        dm_write_async_helper(dev, reg, 0, length, data);
 }
 
 static void dm_write_reg_async(struct usbnet *dev, u8 reg, u8 value)
 {
-       devdbg(dev, "dm_write_reg_async() reg=0x%02x value=0x%02x",
-              reg, value);
+       netdev_dbg(dev->net, "dm_write_reg_async() reg=0x%02x value=0x%02x\n",
+                  reg, value);
 
        dm_write_async_helper(dev, reg, value, 0, NULL);
 }
@@ -211,7 +213,7 @@ static int dm_read_shared_word(struct usbnet *dev, int phy, u8 reg, __le16 *valu
        }
 
        if (i == DM_TIMEOUT) {
-               deverr(dev, "%s read timed out!", phy ? "phy" : "eeprom");
+               netdev_err(dev->net, "%s read timed out!\n", phy ? "phy" : "eeprom");
                ret = -EIO;
                goto out;
        }
@@ -219,8 +221,8 @@ static int dm_read_shared_word(struct usbnet *dev, int phy, u8 reg, __le16 *valu
        dm_write_reg(dev, DM_SHARED_CTRL, 0x0);
        ret = dm_read(dev, DM_SHARED_DATA, 2, value);
 
-       devdbg(dev, "read shared %d 0x%02x returned 0x%04x, %d",
-              phy, reg, *value, ret);
+       netdev_dbg(dev->net, "read shared %d 0x%02x returned 0x%04x, %d\n",
+                  phy, reg, *value, ret);
 
  out:
        mutex_unlock(&dev->phy_mutex);
@@ -254,7 +256,7 @@ static int dm_write_shared_word(struct usbnet *dev, int phy, u8 reg, __le16 valu
        }
 
        if (i == DM_TIMEOUT) {
-               deverr(dev, "%s write timed out!", phy ? "phy" : "eeprom");
+               netdev_err(dev->net, "%s write timed out!\n", phy ? "phy" : "eeprom");
                ret = -EIO;
                goto out;
        }
@@ -304,15 +306,15 @@ static int dm9601_mdio_read(struct net_device *netdev, int phy_id, int loc)
        __le16 res;
 
        if (phy_id) {
-               devdbg(dev, "Only internal phy supported");
+               netdev_dbg(dev->net, "Only internal phy supported\n");
                return 0;
        }
 
        dm_read_shared_word(dev, 1, loc, &res);
 
-       devdbg(dev,
-              "dm9601_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x",
-              phy_id, loc, le16_to_cpu(res));
+       netdev_dbg(dev->net,
+                  "dm9601_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n",
+                  phy_id, loc, le16_to_cpu(res));
 
        return le16_to_cpu(res);
 }
@@ -324,12 +326,12 @@ static void dm9601_mdio_write(struct net_device *netdev, int phy_id, int loc,
        __le16 res = cpu_to_le16(val);
 
        if (phy_id) {
-               devdbg(dev, "Only internal phy supported");
+               netdev_dbg(dev->net, "Only internal phy supported\n");
                return;
        }
 
-       devdbg(dev,"dm9601_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x",
-              phy_id, loc, val);
+       netdev_dbg(dev->net, "dm9601_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n",
+                  phy_id, loc, val);
 
        dm_write_shared_word(dev, 1, loc, res);
 }
@@ -356,7 +358,7 @@ static int dm9601_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
        return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
 }
 
-static struct ethtool_ops dm9601_ethtool_ops = {
+static const struct ethtool_ops dm9601_ethtool_ops = {
        .get_drvinfo    = dm9601_get_drvinfo,
        .get_link       = dm9601_get_link,
        .get_msglevel   = usbnet_get_msglevel,
@@ -381,13 +383,13 @@ static void dm9601_set_multicast(struct net_device *net)
 
        if (net->flags & IFF_PROMISC) {
                rx_ctl |= 0x02;
-       } else if (net->flags & IFF_ALLMULTI || net->mc_count > DM_MAX_MCAST) {
+       } else if (net->flags & IFF_ALLMULTI ||
+                  netdev_mc_count(net) > DM_MAX_MCAST) {
                rx_ctl |= 0x04;
-       } else if (net->mc_count) {
-               struct dev_mc_list *mc_list = net->mc_list;
-               int i;
+       } else if (!netdev_mc_empty(net)) {
+               struct dev_mc_list *mc_list;
 
-               for (i = 0; i < net->mc_count; i++, mc_list = mc_list->next) {
+               netdev_for_each_mc_addr(mc_list, net) {
                        u32 crc = ether_crc(ETH_ALEN, mc_list->dmi_addr) >> 26;
                        hashes[crc >> 3] |= 1 << (crc & 0x7);
                }
@@ -397,20 +399,40 @@ static void dm9601_set_multicast(struct net_device *net)
        dm_write_reg_async(dev, DM_RX_CTRL, rx_ctl);
 }
 
+static void __dm9601_set_mac_address(struct usbnet *dev)
+{
+       dm_write_async(dev, DM_PHY_ADDR, ETH_ALEN, dev->net->dev_addr);
+}
+
 static int dm9601_set_mac_address(struct net_device *net, void *p)
 {
        struct sockaddr *addr = p;
        struct usbnet *dev = netdev_priv(net);
 
-       if (!is_valid_ether_addr(addr->sa_data))
+       if (!is_valid_ether_addr(addr->sa_data)) {
+               dev_err(&net->dev, "not setting invalid mac address %pM\n",
+                                                               addr->sa_data);
                return -EINVAL;
+       }
 
        memcpy(net->dev_addr, addr->sa_data, net->addr_len);
-       dm_write_async(dev, DM_PHY_ADDR, net->addr_len, net->dev_addr);
+       __dm9601_set_mac_address(dev);
 
        return 0;
 }
 
+static const struct net_device_ops dm9601_netdev_ops = {
+       .ndo_open               = usbnet_open,
+       .ndo_stop               = usbnet_stop,
+       .ndo_start_xmit         = usbnet_start_xmit,
+       .ndo_tx_timeout         = usbnet_tx_timeout,
+       .ndo_change_mtu         = usbnet_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_do_ioctl           = dm9601_ioctl,
+       .ndo_set_multicast_list = dm9601_set_multicast,
+       .ndo_set_mac_address    = dm9601_set_mac_address,
+};
+
 static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf)
 {
        int ret;
@@ -420,9 +442,7 @@ static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf)
        if (ret)
                goto out;
 
-       dev->net->do_ioctl = dm9601_ioctl;
-       dev->net->set_multicast_list = dm9601_set_multicast;
-       dev->net->set_mac_address = dm9601_set_mac_address;
+       dev->net->netdev_ops = &dm9601_netdev_ops;
        dev->net->ethtool_ops = &dm9601_ethtool_ops;
        dev->net->hard_header_len += DM_TX_OVERHEAD;
        dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
@@ -450,6 +470,12 @@ static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf)
         */
        if (is_valid_ether_addr(mac))
                memcpy(dev->net->dev_addr, mac, ETH_ALEN);
+       else {
+               printk(KERN_WARNING
+                       "dm9601: No valid MAC address in EEPROM, using %pM\n",
+                       dev->net->dev_addr);
+               __dm9601_set_mac_address(dev);
+       }
 
        /* power up phy */
        dm_write_reg(dev, DM_GPR_CTRL, 1);
@@ -473,10 +499,10 @@ static int dm9601_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
        int len;
 
        /* format:
-          b0: rx status
-          b1: packet length (incl crc) low
-          b2: packet length (incl crc) high
-          b3..n-4: packet data
+          b1: rx status
+          b2: packet length (incl crc) low
+          b3: packet length (incl crc) high
+          b4..n-4: packet data
           bn-3..bn: ethernet crc
         */
 
@@ -489,11 +515,11 @@ static int dm9601_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
        len = (skb->data[1] | (skb->data[2] << 8)) - 4;
 
        if (unlikely(status & 0xbf)) {
-               if (status & 0x01) dev->stats.rx_fifo_errors++;
-               if (status & 0x02) dev->stats.rx_crc_errors++;
-               if (status & 0x04) dev->stats.rx_frame_errors++;
-               if (status & 0x20) dev->stats.rx_missed_errors++;
-               if (status & 0x90) dev->stats.rx_length_errors++;
+               if (status & 0x01) dev->net->stats.rx_fifo_errors++;
+               if (status & 0x02) dev->net->stats.rx_crc_errors++;
+               if (status & 0x04) dev->net->stats.rx_frame_errors++;
+               if (status & 0x20) dev->net->stats.rx_missed_errors++;
+               if (status & 0x90) dev->net->stats.rx_length_errors++;
                return 0;
        }
 
@@ -509,8 +535,8 @@ static struct sk_buff *dm9601_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
        int len;
 
        /* format:
-          b0: packet length low
-          b1: packet length high
+          b1: packet length low
+          b2: packet length high
           b3..n: packet data
        */
 
@@ -568,7 +594,7 @@ static void dm9601_status(struct usbnet *dev, struct urb *urb)
                }
                else
                        netif_carrier_off(dev->net);
-               devdbg(dev, "Link Status is: %d", link);
+               netdev_dbg(dev->net, "Link Status is: %d\n", link);
        }
 }
 
@@ -579,15 +605,15 @@ static int dm9601_link_reset(struct usbnet *dev)
        mii_check_media(&dev->mii, 1, 1);
        mii_ethtool_gset(&dev->mii, &ecmd);
 
-       devdbg(dev, "link_reset() speed: %d duplex: %d",
-              ecmd.speed, ecmd.duplex);
+       netdev_dbg(dev->net, "link_reset() speed: %d duplex: %d\n",
+                  ecmd.speed, ecmd.duplex);
 
        return 0;
 }
 
 static const struct driver_info dm9601_info = {
        .description    = "Davicom DM9601 USB Ethernet",
-       .flags          = FLAG_ETHER,
+       .flags          = FLAG_ETHER | FLAG_LINK_INTR,
        .bind           = dm9601_bind,
        .rx_fixup       = dm9601_rx_fixup,
        .tx_fixup       = dm9601_tx_fixup,
@@ -621,6 +647,14 @@ static const struct usb_device_id products[] = {
        USB_DEVICE(0x0a47, 0x9601),     /* Hirose USB-100 */
        .driver_info = (unsigned long)&dm9601_info,
         },
+       {
+       USB_DEVICE(0x0fe6, 0x8101),     /* DM9601 USB to Fast Ethernet Adapter */
+       .driver_info = (unsigned long)&dm9601_info,
+        },
+       {
+        USB_DEVICE(0x0a46, 0x9000),    /* DM9000E */
+        .driver_info = (unsigned long)&dm9601_info,
+        },
        {},                     // END
 };