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 | |
| 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>
| -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 | ||
