aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorPeter Korsgaard <jacmet@sunsite.dk>2013-01-27 07:34:22 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-28 00:18:04 -0500
commit6642f91c92da07369cf1e582503ea3ccb4a7f1a9 (patch)
treee9c2518e78f98808ff97c4b2fb4af2fab70fe43a /drivers
parent5f19d1219a5b96c7b00ad5c3f889030093a8d1a3 (diff)
dm9601: support dm9620 variant
dm9620 is a newer variant of dm9601 with more features (usb 2.0, checksum offload, ..), but it can also be put in a dm9601 compatible mode, allowing us to reuse the existing driver. This does mean that the extended features like checksum offload cannot be used, but that's hardly critical on a 100mbps interface. Thanks to SÅ‚awek Wernikowski <slawek@wernikowski.net> for providing me with a dm9620 based device to test. Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/usb/dm9601.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c
index 011410f39c90..d7e99445518e 100644
--- a/drivers/net/usb/dm9601.c
+++ b/drivers/net/usb/dm9601.c
@@ -45,6 +45,12 @@
45#define DM_MCAST_ADDR 0x16 /* 8 bytes */ 45#define DM_MCAST_ADDR 0x16 /* 8 bytes */
46#define DM_GPR_CTRL 0x1e 46#define DM_GPR_CTRL 0x1e
47#define DM_GPR_DATA 0x1f 47#define DM_GPR_DATA 0x1f
48#define DM_CHIP_ID 0x2c
49#define DM_MODE_CTRL 0x91 /* only on dm9620 */
50
51/* chip id values */
52#define ID_DM9601 0
53#define ID_DM9620 1
48 54
49#define DM_MAX_MCAST 64 55#define DM_MAX_MCAST 64
50#define DM_MCAST_SIZE 8 56#define DM_MCAST_SIZE 8
@@ -348,7 +354,7 @@ static const struct net_device_ops dm9601_netdev_ops = {
348static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf) 354static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf)
349{ 355{
350 int ret; 356 int ret;
351 u8 mac[ETH_ALEN]; 357 u8 mac[ETH_ALEN], id;
352 358
353 ret = usbnet_get_endpoints(dev, intf); 359 ret = usbnet_get_endpoints(dev, intf);
354 if (ret) 360 if (ret)
@@ -389,6 +395,24 @@ static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf)
389 __dm9601_set_mac_address(dev); 395 __dm9601_set_mac_address(dev);
390 } 396 }
391 397
398 if (dm_read_reg(dev, DM_CHIP_ID, &id) < 0) {
399 netdev_err(dev->net, "Error reading chip ID\n");
400 ret = -ENODEV;
401 goto out;
402 }
403
404 /* put dm9620 devices in dm9601 mode */
405 if (id == ID_DM9620) {
406 u8 mode;
407
408 if (dm_read_reg(dev, DM_MODE_CTRL, &mode) < 0) {
409 netdev_err(dev->net, "Error reading MODE_CTRL\n");
410 ret = -ENODEV;
411 goto out;
412 }
413 dm_write_reg(dev, DM_MODE_CTRL, mode & 0x7f);
414 }
415
392 /* power up phy */ 416 /* power up phy */
393 dm_write_reg(dev, DM_GPR_CTRL, 1); 417 dm_write_reg(dev, DM_GPR_CTRL, 1);
394 dm_write_reg(dev, DM_GPR_DATA, 0); 418 dm_write_reg(dev, DM_GPR_DATA, 0);
@@ -571,6 +595,10 @@ static const struct usb_device_id products[] = {
571 USB_DEVICE(0x0a46, 0x9000), /* DM9000E */ 595 USB_DEVICE(0x0a46, 0x9000), /* DM9000E */
572 .driver_info = (unsigned long)&dm9601_info, 596 .driver_info = (unsigned long)&dm9601_info,
573 }, 597 },
598 {
599 USB_DEVICE(0x0a46, 0x9620), /* DM9620 USB to Fast Ethernet Adapter */
600 .driver_info = (unsigned long)&dm9601_info,
601 },
574 {}, // END 602 {}, // END
575}; 603};
576 604