aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ar9170/usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ar9170/usb.c')
-rw-r--r--drivers/net/wireless/ar9170/usb.c114
1 files changed, 94 insertions, 20 deletions
diff --git a/drivers/net/wireless/ar9170/usb.c b/drivers/net/wireless/ar9170/usb.c
index ad296840893..fddda477095 100644
--- a/drivers/net/wireless/ar9170/usb.c
+++ b/drivers/net/wireless/ar9170/usb.c
@@ -59,6 +59,8 @@ static struct usb_device_id ar9170_usb_ids[] = {
59 { USB_DEVICE(0x0cf3, 0x9170) }, 59 { USB_DEVICE(0x0cf3, 0x9170) },
60 /* Atheros TG121N */ 60 /* Atheros TG121N */
61 { USB_DEVICE(0x0cf3, 0x1001) }, 61 { USB_DEVICE(0x0cf3, 0x1001) },
62 /* Cace Airpcap NX */
63 { USB_DEVICE(0xcace, 0x0300) },
62 /* D-Link DWA 160A */ 64 /* D-Link DWA 160A */
63 { USB_DEVICE(0x07d1, 0x3c10) }, 65 { USB_DEVICE(0x07d1, 0x3c10) },
64 /* Netgear WNDA3100 */ 66 /* Netgear WNDA3100 */
@@ -67,6 +69,8 @@ static struct usb_device_id ar9170_usb_ids[] = {
67 { USB_DEVICE(0x0846, 0x9001) }, 69 { USB_DEVICE(0x0846, 0x9001) },
68 /* Zydas ZD1221 */ 70 /* Zydas ZD1221 */
69 { USB_DEVICE(0x0ace, 0x1221) }, 71 { USB_DEVICE(0x0ace, 0x1221) },
72 /* ZyXEL NWD271N */
73 { USB_DEVICE(0x0586, 0x3417) },
70 /* Z-Com UB81 BG */ 74 /* Z-Com UB81 BG */
71 { USB_DEVICE(0x0cde, 0x0023) }, 75 { USB_DEVICE(0x0cde, 0x0023) },
72 /* Z-Com UB82 ABG */ 76 /* Z-Com UB82 ABG */
@@ -619,6 +623,39 @@ static int ar9170_usb_open(struct ar9170 *ar)
619 return 0; 623 return 0;
620} 624}
621 625
626static int ar9170_usb_init_device(struct ar9170_usb *aru)
627{
628 int err;
629
630 err = ar9170_usb_alloc_rx_irq_urb(aru);
631 if (err)
632 goto err_out;
633
634 err = ar9170_usb_alloc_rx_bulk_urbs(aru);
635 if (err)
636 goto err_unrx;
637
638 err = ar9170_usb_upload_firmware(aru);
639 if (err) {
640 err = ar9170_echo_test(&aru->common, 0x60d43110);
641 if (err) {
642 /* force user invention, by disabling the device */
643 err = usb_driver_set_configuration(aru->udev, -1);
644 dev_err(&aru->udev->dev, "device is in a bad state. "
645 "please reconnect it!\n");
646 goto err_unrx;
647 }
648 }
649
650 return 0;
651
652err_unrx:
653 ar9170_usb_cancel_urbs(aru);
654
655err_out:
656 return err;
657}
658
622static int ar9170_usb_probe(struct usb_interface *intf, 659static int ar9170_usb_probe(struct usb_interface *intf,
623 const struct usb_device_id *id) 660 const struct usb_device_id *id)
624{ 661{
@@ -654,32 +691,16 @@ static int ar9170_usb_probe(struct usb_interface *intf,
654 691
655 err = ar9170_usb_reset(aru); 692 err = ar9170_usb_reset(aru);
656 if (err) 693 if (err)
657 goto err_unlock; 694 goto err_freehw;
658 695
659 err = ar9170_usb_request_firmware(aru); 696 err = ar9170_usb_request_firmware(aru);
660 if (err) 697 if (err)
661 goto err_unlock; 698 goto err_freehw;
662 699
663 err = ar9170_usb_alloc_rx_irq_urb(aru); 700 err = ar9170_usb_init_device(aru);
664 if (err) 701 if (err)
665 goto err_freefw; 702 goto err_freefw;
666 703
667 err = ar9170_usb_alloc_rx_bulk_urbs(aru);
668 if (err)
669 goto err_unrx;
670
671 err = ar9170_usb_upload_firmware(aru);
672 if (err) {
673 err = ar9170_echo_test(&aru->common, 0x60d43110);
674 if (err) {
675 /* force user invention, by disabling the device */
676 err = usb_driver_set_configuration(aru->udev, -1);
677 dev_err(&aru->udev->dev, "device is in a bad state. "
678 "please reconnect it!\n");
679 goto err_unrx;
680 }
681 }
682
683 err = ar9170_usb_open(ar); 704 err = ar9170_usb_open(ar);
684 if (err) 705 if (err)
685 goto err_unrx; 706 goto err_unrx;
@@ -699,7 +720,7 @@ err_freefw:
699 release_firmware(aru->init_values); 720 release_firmware(aru->init_values);
700 release_firmware(aru->firmware); 721 release_firmware(aru->firmware);
701 722
702err_unlock: 723err_freehw:
703 usb_set_intfdata(intf, NULL); 724 usb_set_intfdata(intf, NULL);
704 usb_put_dev(udev); 725 usb_put_dev(udev);
705 ieee80211_free_hw(ar->hw); 726 ieee80211_free_hw(ar->hw);
@@ -726,12 +747,65 @@ static void ar9170_usb_disconnect(struct usb_interface *intf)
726 ieee80211_free_hw(aru->common.hw); 747 ieee80211_free_hw(aru->common.hw);
727} 748}
728 749
750#ifdef CONFIG_PM
751static int ar9170_suspend(struct usb_interface *intf,
752 pm_message_t message)
753{
754 struct ar9170_usb *aru = usb_get_intfdata(intf);
755
756 if (!aru)
757 return -ENODEV;
758
759 aru->common.state = AR9170_IDLE;
760 ar9170_usb_cancel_urbs(aru);
761
762 return 0;
763}
764
765static int ar9170_resume(struct usb_interface *intf)
766{
767 struct ar9170_usb *aru = usb_get_intfdata(intf);
768 int err;
769
770 if (!aru)
771 return -ENODEV;
772
773 usb_unpoison_anchored_urbs(&aru->rx_submitted);
774 usb_unpoison_anchored_urbs(&aru->tx_submitted);
775
776 /*
777 * FIXME: firmware upload will fail on resume.
778 * but this is better than a hang!
779 */
780
781 err = ar9170_usb_init_device(aru);
782 if (err)
783 goto err_unrx;
784
785 err = ar9170_usb_open(&aru->common);
786 if (err)
787 goto err_unrx;
788
789 return 0;
790
791err_unrx:
792 aru->common.state = AR9170_IDLE;
793 ar9170_usb_cancel_urbs(aru);
794
795 return err;
796}
797#endif /* CONFIG_PM */
798
729static struct usb_driver ar9170_driver = { 799static struct usb_driver ar9170_driver = {
730 .name = "ar9170usb", 800 .name = "ar9170usb",
731 .probe = ar9170_usb_probe, 801 .probe = ar9170_usb_probe,
732 .disconnect = ar9170_usb_disconnect, 802 .disconnect = ar9170_usb_disconnect,
733 .id_table = ar9170_usb_ids, 803 .id_table = ar9170_usb_ids,
734 .soft_unbind = 1, 804 .soft_unbind = 1,
805#ifdef CONFIG_PM
806 .suspend = ar9170_suspend,
807 .resume = ar9170_resume,
808#endif /* CONFIG_PM */
735}; 809};
736 810
737static int __init ar9170_init(void) 811static int __init ar9170_init(void)