diff options
Diffstat (limited to 'drivers/net/usb')
| -rw-r--r-- | drivers/net/usb/Kconfig | 6 | ||||
| -rw-r--r-- | drivers/net/usb/dm9601.c | 44 | ||||
| -rw-r--r-- | drivers/net/usb/hso.c | 13 | ||||
| -rw-r--r-- | drivers/net/usb/mcs7830.c | 19 |
4 files changed, 50 insertions, 32 deletions
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 85e4a01670f0..47b0f732b0b1 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig | |||
| @@ -276,12 +276,12 @@ config USB_NET_CDC_MBIM | |||
| 276 | module will be called cdc_mbim. | 276 | module will be called cdc_mbim. |
| 277 | 277 | ||
| 278 | config USB_NET_DM9601 | 278 | config USB_NET_DM9601 |
| 279 | tristate "Davicom DM9601 based USB 1.1 10/100 ethernet devices" | 279 | tristate "Davicom DM96xx based USB 10/100 ethernet devices" |
| 280 | depends on USB_USBNET | 280 | depends on USB_USBNET |
| 281 | select CRC32 | 281 | select CRC32 |
| 282 | help | 282 | help |
| 283 | This option adds support for Davicom DM9601 based USB 1.1 | 283 | This option adds support for Davicom DM9601/DM9620/DM9621A |
| 284 | 10/100 Ethernet adapters. | 284 | based USB 10/100 Ethernet adapters. |
| 285 | 285 | ||
| 286 | config USB_NET_SR9700 | 286 | config USB_NET_SR9700 |
| 287 | tristate "CoreChip-sz SR9700 based USB 1.1 10/100 ethernet devices" | 287 | tristate "CoreChip-sz SR9700 based USB 1.1 10/100 ethernet devices" |
diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index c6867f926cff..14aa48fa8d7e 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Davicom DM9601 USB 1.1 10/100Mbps ethernet devices | 2 | * Davicom DM96xx USB 10/100Mbps ethernet devices |
| 3 | * | 3 | * |
| 4 | * Peter Korsgaard <jacmet@sunsite.dk> | 4 | * Peter Korsgaard <jacmet@sunsite.dk> |
| 5 | * | 5 | * |
| @@ -364,7 +364,12 @@ static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf) | |||
| 364 | dev->net->ethtool_ops = &dm9601_ethtool_ops; | 364 | dev->net->ethtool_ops = &dm9601_ethtool_ops; |
| 365 | dev->net->hard_header_len += DM_TX_OVERHEAD; | 365 | dev->net->hard_header_len += DM_TX_OVERHEAD; |
| 366 | dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; | 366 | dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; |
| 367 | dev->rx_urb_size = dev->net->mtu + ETH_HLEN + DM_RX_OVERHEAD; | 367 | |
| 368 | /* dm9620/21a require room for 4 byte padding, even in dm9601 | ||
| 369 | * mode, so we need +1 to be able to receive full size | ||
| 370 | * ethernet frames. | ||
| 371 | */ | ||
| 372 | dev->rx_urb_size = dev->net->mtu + ETH_HLEN + DM_RX_OVERHEAD + 1; | ||
| 368 | 373 | ||
| 369 | dev->mii.dev = dev->net; | 374 | dev->mii.dev = dev->net; |
| 370 | dev->mii.mdio_read = dm9601_mdio_read; | 375 | dev->mii.mdio_read = dm9601_mdio_read; |
| @@ -468,7 +473,7 @@ static int dm9601_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
| 468 | static struct sk_buff *dm9601_tx_fixup(struct usbnet *dev, struct sk_buff *skb, | 473 | static struct sk_buff *dm9601_tx_fixup(struct usbnet *dev, struct sk_buff *skb, |
| 469 | gfp_t flags) | 474 | gfp_t flags) |
| 470 | { | 475 | { |
| 471 | int len; | 476 | int len, pad; |
| 472 | 477 | ||
| 473 | /* format: | 478 | /* format: |
| 474 | b1: packet length low | 479 | b1: packet length low |
| @@ -476,12 +481,23 @@ static struct sk_buff *dm9601_tx_fixup(struct usbnet *dev, struct sk_buff *skb, | |||
| 476 | b3..n: packet data | 481 | b3..n: packet data |
| 477 | */ | 482 | */ |
| 478 | 483 | ||
| 479 | len = skb->len; | 484 | len = skb->len + DM_TX_OVERHEAD; |
| 485 | |||
| 486 | /* workaround for dm962x errata with tx fifo getting out of | ||
| 487 | * sync if a USB bulk transfer retry happens right after a | ||
| 488 | * packet with odd / maxpacket length by adding up to 3 bytes | ||
| 489 | * padding. | ||
| 490 | */ | ||
| 491 | while ((len & 1) || !(len % dev->maxpacket)) | ||
| 492 | len++; | ||
| 480 | 493 | ||
| 481 | if (skb_headroom(skb) < DM_TX_OVERHEAD) { | 494 | len -= DM_TX_OVERHEAD; /* hw header doesn't count as part of length */ |
| 495 | pad = len - skb->len; | ||
| 496 | |||
| 497 | if (skb_headroom(skb) < DM_TX_OVERHEAD || skb_tailroom(skb) < pad) { | ||
| 482 | struct sk_buff *skb2; | 498 | struct sk_buff *skb2; |
| 483 | 499 | ||
| 484 | skb2 = skb_copy_expand(skb, DM_TX_OVERHEAD, 0, flags); | 500 | skb2 = skb_copy_expand(skb, DM_TX_OVERHEAD, pad, flags); |
| 485 | dev_kfree_skb_any(skb); | 501 | dev_kfree_skb_any(skb); |
| 486 | skb = skb2; | 502 | skb = skb2; |
| 487 | if (!skb) | 503 | if (!skb) |
| @@ -490,10 +506,10 @@ static struct sk_buff *dm9601_tx_fixup(struct usbnet *dev, struct sk_buff *skb, | |||
| 490 | 506 | ||
| 491 | __skb_push(skb, DM_TX_OVERHEAD); | 507 | __skb_push(skb, DM_TX_OVERHEAD); |
| 492 | 508 | ||
| 493 | /* usbnet adds padding if length is a multiple of packet size | 509 | if (pad) { |
| 494 | if so, adjust length value in header */ | 510 | memset(skb->data + skb->len, 0, pad); |
| 495 | if ((skb->len % dev->maxpacket) == 0) | 511 | __skb_put(skb, pad); |
| 496 | len++; | 512 | } |
| 497 | 513 | ||
| 498 | skb->data[0] = len; | 514 | skb->data[0] = len; |
| 499 | skb->data[1] = len >> 8; | 515 | skb->data[1] = len >> 8; |
| @@ -543,7 +559,7 @@ static int dm9601_link_reset(struct usbnet *dev) | |||
| 543 | } | 559 | } |
| 544 | 560 | ||
| 545 | static const struct driver_info dm9601_info = { | 561 | static const struct driver_info dm9601_info = { |
| 546 | .description = "Davicom DM9601 USB Ethernet", | 562 | .description = "Davicom DM96xx USB 10/100 Ethernet", |
| 547 | .flags = FLAG_ETHER | FLAG_LINK_INTR, | 563 | .flags = FLAG_ETHER | FLAG_LINK_INTR, |
| 548 | .bind = dm9601_bind, | 564 | .bind = dm9601_bind, |
| 549 | .rx_fixup = dm9601_rx_fixup, | 565 | .rx_fixup = dm9601_rx_fixup, |
| @@ -594,6 +610,10 @@ static const struct usb_device_id products[] = { | |||
| 594 | USB_DEVICE(0x0a46, 0x9620), /* DM9620 USB to Fast Ethernet Adapter */ | 610 | USB_DEVICE(0x0a46, 0x9620), /* DM9620 USB to Fast Ethernet Adapter */ |
| 595 | .driver_info = (unsigned long)&dm9601_info, | 611 | .driver_info = (unsigned long)&dm9601_info, |
| 596 | }, | 612 | }, |
| 613 | { | ||
| 614 | USB_DEVICE(0x0a46, 0x9621), /* DM9621A USB to Fast Ethernet Adapter */ | ||
| 615 | .driver_info = (unsigned long)&dm9601_info, | ||
| 616 | }, | ||
| 597 | {}, // END | 617 | {}, // END |
| 598 | }; | 618 | }; |
| 599 | 619 | ||
| @@ -612,5 +632,5 @@ static struct usb_driver dm9601_driver = { | |||
| 612 | module_usb_driver(dm9601_driver); | 632 | module_usb_driver(dm9601_driver); |
| 613 | 633 | ||
| 614 | MODULE_AUTHOR("Peter Korsgaard <jacmet@sunsite.dk>"); | 634 | MODULE_AUTHOR("Peter Korsgaard <jacmet@sunsite.dk>"); |
| 615 | MODULE_DESCRIPTION("Davicom DM9601 USB 1.1 ethernet devices"); | 635 | MODULE_DESCRIPTION("Davicom DM96xx USB 10/100 ethernet devices"); |
| 616 | MODULE_LICENSE("GPL"); | 636 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 86292e6aaf49..1a482344b3f5 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
| @@ -185,7 +185,6 @@ enum rx_ctrl_state{ | |||
| 185 | #define BM_REQUEST_TYPE (0xa1) | 185 | #define BM_REQUEST_TYPE (0xa1) |
| 186 | #define B_NOTIFICATION (0x20) | 186 | #define B_NOTIFICATION (0x20) |
| 187 | #define W_VALUE (0x0) | 187 | #define W_VALUE (0x0) |
| 188 | #define W_INDEX (0x2) | ||
| 189 | #define W_LENGTH (0x2) | 188 | #define W_LENGTH (0x2) |
| 190 | 189 | ||
| 191 | #define B_OVERRUN (0x1<<6) | 190 | #define B_OVERRUN (0x1<<6) |
| @@ -1487,6 +1486,7 @@ static void tiocmget_intr_callback(struct urb *urb) | |||
| 1487 | struct uart_icount *icount; | 1486 | struct uart_icount *icount; |
| 1488 | struct hso_serial_state_notification *serial_state_notification; | 1487 | struct hso_serial_state_notification *serial_state_notification; |
| 1489 | struct usb_device *usb; | 1488 | struct usb_device *usb; |
| 1489 | int if_num; | ||
| 1490 | 1490 | ||
| 1491 | /* Sanity checks */ | 1491 | /* Sanity checks */ |
| 1492 | if (!serial) | 1492 | if (!serial) |
| @@ -1495,15 +1495,24 @@ static void tiocmget_intr_callback(struct urb *urb) | |||
| 1495 | handle_usb_error(status, __func__, serial->parent); | 1495 | handle_usb_error(status, __func__, serial->parent); |
| 1496 | return; | 1496 | return; |
| 1497 | } | 1497 | } |
| 1498 | |||
| 1499 | /* tiocmget is only supported on HSO_PORT_MODEM */ | ||
| 1498 | tiocmget = serial->tiocmget; | 1500 | tiocmget = serial->tiocmget; |
| 1499 | if (!tiocmget) | 1501 | if (!tiocmget) |
| 1500 | return; | 1502 | return; |
| 1503 | BUG_ON((serial->parent->port_spec & HSO_PORT_MASK) != HSO_PORT_MODEM); | ||
| 1504 | |||
| 1501 | usb = serial->parent->usb; | 1505 | usb = serial->parent->usb; |
| 1506 | if_num = serial->parent->interface->altsetting->desc.bInterfaceNumber; | ||
| 1507 | |||
| 1508 | /* wIndex should be the USB interface number of the port to which the | ||
| 1509 | * notification applies, which should always be the Modem port. | ||
| 1510 | */ | ||
| 1502 | serial_state_notification = &tiocmget->serial_state_notification; | 1511 | serial_state_notification = &tiocmget->serial_state_notification; |
| 1503 | if (serial_state_notification->bmRequestType != BM_REQUEST_TYPE || | 1512 | if (serial_state_notification->bmRequestType != BM_REQUEST_TYPE || |
| 1504 | serial_state_notification->bNotification != B_NOTIFICATION || | 1513 | serial_state_notification->bNotification != B_NOTIFICATION || |
| 1505 | le16_to_cpu(serial_state_notification->wValue) != W_VALUE || | 1514 | le16_to_cpu(serial_state_notification->wValue) != W_VALUE || |
| 1506 | le16_to_cpu(serial_state_notification->wIndex) != W_INDEX || | 1515 | le16_to_cpu(serial_state_notification->wIndex) != if_num || |
| 1507 | le16_to_cpu(serial_state_notification->wLength) != W_LENGTH) { | 1516 | le16_to_cpu(serial_state_notification->wLength) != W_LENGTH) { |
| 1508 | dev_warn(&usb->dev, | 1517 | dev_warn(&usb->dev, |
| 1509 | "hso received invalid serial state notification\n"); | 1518 | "hso received invalid serial state notification\n"); |
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c index 03832d3780aa..f54637828574 100644 --- a/drivers/net/usb/mcs7830.c +++ b/drivers/net/usb/mcs7830.c | |||
| @@ -117,7 +117,6 @@ enum { | |||
| 117 | struct mcs7830_data { | 117 | struct mcs7830_data { |
| 118 | u8 multi_filter[8]; | 118 | u8 multi_filter[8]; |
| 119 | u8 config; | 119 | u8 config; |
| 120 | u8 link_counter; | ||
| 121 | }; | 120 | }; |
| 122 | 121 | ||
| 123 | static const char driver_name[] = "MOSCHIP usb-ethernet driver"; | 122 | static const char driver_name[] = "MOSCHIP usb-ethernet driver"; |
| @@ -561,26 +560,16 @@ static void mcs7830_status(struct usbnet *dev, struct urb *urb) | |||
| 561 | { | 560 | { |
| 562 | u8 *buf = urb->transfer_buffer; | 561 | u8 *buf = urb->transfer_buffer; |
| 563 | bool link, link_changed; | 562 | bool link, link_changed; |
| 564 | struct mcs7830_data *data = mcs7830_get_data(dev); | ||
| 565 | 563 | ||
| 566 | if (urb->actual_length < 16) | 564 | if (urb->actual_length < 16) |
| 567 | return; | 565 | return; |
| 568 | 566 | ||
| 569 | link = !(buf[1] & 0x20); | 567 | link = !(buf[1] == 0x20); |
| 570 | link_changed = netif_carrier_ok(dev->net) != link; | 568 | link_changed = netif_carrier_ok(dev->net) != link; |
| 571 | if (link_changed) { | 569 | if (link_changed) { |
| 572 | data->link_counter++; | 570 | usbnet_link_change(dev, link, 0); |
| 573 | /* | 571 | netdev_dbg(dev->net, "Link Status is: %d\n", link); |
| 574 | track link state 20 times to guard against erroneous | 572 | } |
| 575 | link state changes reported sometimes by the chip | ||
| 576 | */ | ||
| 577 | if (data->link_counter > 20) { | ||
| 578 | data->link_counter = 0; | ||
| 579 | usbnet_link_change(dev, link, 0); | ||
| 580 | netdev_dbg(dev->net, "Link Status is: %d\n", link); | ||
| 581 | } | ||
| 582 | } else | ||
| 583 | data->link_counter = 0; | ||
| 584 | } | 573 | } |
| 585 | 574 | ||
| 586 | static const struct driver_info moschip_info = { | 575 | static const struct driver_info moschip_info = { |
