diff options
author | Peter Korsgaard <jacmet@sunsite.dk> | 2013-01-27 07:34:22 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-01-28 00:18:04 -0500 |
commit | 6642f91c92da07369cf1e582503ea3ccb4a7f1a9 (patch) | |
tree | e9c2518e78f98808ff97c4b2fb4af2fab70fe43a /drivers | |
parent | 5f19d1219a5b96c7b00ad5c3f889030093a8d1a3 (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.c | 30 |
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 = { | |||
348 | static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf) | 354 | static 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 | ||