abperiasamy / rtl8812AU_8821AU_linux

rtl8812AU_8821AU linux kernel driver for AC1200 (801.11ac) Wireless Dual-Band USB Adapter
GNU General Public License v2.0
1.23k stars 434 forks source link

bcdUSB 2.00 #12

Open throwawayissuereporter opened 10 years ago

throwawayissuereporter commented 10 years ago

The device misreports, under Ubuntu 14.04 x64, as bcdUSB 2.xx, rather than bcdUSB 3.xx. This can be observed in the output of lsusb -vv post-driver compilation. I assume the respective Windows drivers do something to coerce the device into behaving as a proper USB 3.0 device. Can the same thing be achieved as part of this driver?

Edit 1: This user seems to be having the same issue: https://bbs.archlinux.org/viewtopic.php?pid=1398049#p1398049

Edit 2: This user also has the same issue: http://askubuntu.com/questions/389477/edimax-ew-7822uac-not-operating-at-superspeed

KurzonDax commented 10 years ago

I can verify that this issue occurs with both 12.04.3 as well as 14.04. Device is reported as USB 2.0 and operates at USB 2.0 transfer speeds. I have validated the transfer speeds through as many tests as possible to eliminate environmental factors that could affect throughput (i.e. forcing different wireless channels, distances, remove line-of-sight obstacles, etc.) I have also tried this using different USB 3 chipsets (ASMedia 1042 and VIA VL805).

Currently using kernel 3.13.0-30, but problem also manifests with 3.13.0-24 to 3.13.0-29.

I can provide additional information or logging, just let me know what is needed.

thiete commented 9 years ago

I noticed this is also the case for my adapter on (L)ubuntu 15.04. I am using a Linksys WUSB6300 adapter, on kernel 3.19.0-20. Copied below is the relevant output of lsusb -v.

Any advice on how to debug this further would be appreciated. Having a naive look at the code, it seems like the USB2 mode is read out from the hardware device descriptor and it would seem the driver would have to somehow force USB 3 mode as throwawayissuereporter suggests.

Bus 001 Device 004: ID 13b1:003f Linksys Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x13b1 Linksys idProduct 0x003f bcdDevice 0.00 iManufacturer 1 Linksys iProduct 2 WUSB6300 iSerial 3 26 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 53 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 500mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 5 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 255 Vendor Specific Subclass bInterfaceProtocol 255 Vendor Specific Protocol iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x03 EP 3 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x04 EP 4 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x85 EP 5 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 1 Device Qualifier (for other device speed): bLength 10 bDescriptorType 6 bcdUSB 2.00 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 bNumConfigurations 1 Device Status: 0x0002 (Bus Powered) Remote Wakeup Enabled

cracyc commented 9 years ago

It looks like this sequence of control messages will force it into usb 3 mode.

void switchRealtekMode()
{
    unsigned char data = 0x08;
    detachDriver();
    libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, 5, 0x74, 0, &data, 1, 100);
    data = 0x02;
    libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, 5, 0x70, 0, &data, 1, 100);
    data = 0x01;
    libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, 5, 0x3e, 0, &data, 1, 100);
    data = 0x40;
    libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, 5, 0x3d, 0, &data, 1, 100);
    data = 0x80;
    libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, 5, 0x05, 0, &data, 1, 100);
}

Before the descriptor on my device was the same as above but after:

Bus 003 Device 003: ID 0bda:8812 Realtek Semiconductor Corp.
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               3.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0         9
  idVendor           0x0bda Realtek Semiconductor Corp.
  idProduct          0x8812
  bcdDevice            0.00
  iManufacturer           1 Realtek
  iProduct                2 802.11n NIC
  iSerial                 3 123456
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           83
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              200mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           5
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass    255 Vendor Specific Subclass
      bInterfaceProtocol    255 Vendor Specific Protocol
      iInterface              0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0400  1x 1024 bytes
        bInterval               0
        bMaxBurst               4
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0400  1x 1024 bytes
        bInterval               0
        bMaxBurst               4
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x03  EP 3 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0400  1x 1024 bytes
        bInterval               0
        bMaxBurst               4
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x04  EP 4 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0400  1x 1024 bytes
        bInterval               0
        bMaxBurst               4
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x85  EP 5 IN
        bmAttributes           19
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Feedback
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
        bMaxBurst               0
Binary Object Store Descriptor:
  bLength                 5
  bDescriptorType        15
  wTotalLength           22
  bNumDeviceCaps          2
  USB 2.0 Extension Device Capability:
    bLength                 7
    bDescriptorType        16
    bDevCapabilityType      2
    bmAttributes   0x00000002
      Link Power Management (LPM) Supported
  SuperSpeed USB Device Capability:
    bLength                10
    bDescriptorType        16
    bDevCapabilityType      3
    bmAttributes         0x00
      Latency Tolerance Messages (LTM) Supported
    wSpeedsSupported   0x000e
      Device can operate at Full Speed (12Mbps)
      Device can operate at High Speed (480Mbps)
      Device can operate at SuperSpeed (5Gbps)
    bFunctionalitySupport   1
      Lowest fully-functional device speed is Full Speed (12Mbps)
    bU1DevExitLat          10 micro seconds
    bU2DevExitLat         255 micro seconds

Setting the data to 0x04 on the first transfer (0x74) will likely switch back to usb2 mode although I haven't tested it.

thiete commented 9 years ago

cracyc, that looks promising! I'm out of my depth here - where/when would the control messages have to be sent? Would you be able to make a patch including this code?

cracyc commented 9 years ago

I put it into usb_modeswitch for my use but I'm not sure the best way to add it to the driver. The commands can be sent before the firmware is sent but the device is restarted so the driver will redetect it. I think it would be better for someone with more knowledge of this driver to make the changes

harshavardhana commented 9 years ago

I think it would be better for someone with more knowledge of this driver to make the changes

feel free to send your changes, we can review and accept if it works for everyone.

cracyc commented 9 years ago

Writing a patch wouldn't be hard, I just don't know where it should go as the device disappears after the last command and I can't do any testing right now. Here is the patch to usb_modeswitch 2.2.5 I did use.

--- usb_modeswitch.c.orig   2015-07-16 16:31:27.000000000 -0500
+++ usb_modeswitch.c    2015-07-23 10:43:59.017854450 -0500
@@ -136,6 +136,7 @@
 #define BLACKBERRY_MODE        0x00000800
 #define PANTECH_MODE       0x00001000
 #define HUAWEINEW_MODE     0x00002000
+#define REALTEK_MODE       0x00004000

 int PantechMode=0;
 char verbose=0, show_progress=1, ResetUSB=0, CheckSuccess=0, config_read=0;
@@ -228,6 +229,7 @@
    ParseParamBoolMap(configFilename, QisdaMode, ModeMap, QISDA_MODE);
    ParseParamBoolMap(configFilename, QuantaMode, ModeMap, QUANTA_MODE);
    ParseParamBoolMap(configFilename, BlackberryMode, ModeMap, BLACKBERRY_MODE);
+   ParseParamBoolMap(configFilename, RealtekMode, ModeMap, REALTEK_MODE);
    ParseParamInt(configFilename, PantechMode);
    if (PantechMode)
        ModeMap |= PANTECH_MODE;
@@ -340,7 +342,7 @@

    while (1)
    {
-       c = getopt_long (argc, argv, "hejWQDndKHJSOBEGTNALZF:RItv:p:V:P:C:m:M:2:3:w:r:c:i:u:a:s:f:b:g:",
+       c = getopt_long (argc, argv, "hejWQDndKHJSOBEGTNALZF:RItv:p:V:P:C:m:M:2:3:w:r:c:i:u:a:s:f:b:g:k:",
                    long_options, &option_index);

        /* Detect the end of the options. */
@@ -378,6 +380,7 @@
            case 'Z': ModeMap = ModeMap + BLACKBERRY_MODE; break;
            case 'F': ModeMap = ModeMap + PANTECH_MODE;
                        PantechMode = strtol(optarg, NULL, 10); break;
+           case 'k': ModeMap = ModeMap + REALTEK_MODE; break;
            case 'c': readConfigFile(optarg); break;
            case 't': readConfigFile("stdin"); break;
            case 'W': verbose = 1; show_progress = 1; count--; break;
@@ -712,6 +715,8 @@
        CheckSuccess = 0; /* separate and implied success control */
        sonySuccess = switchSonyMode();
    }
+   if(ModeMap & REALTEK_MODE)
+       switchRealtekMode();

    if (StandardEject) {
        SHOW_PROGRESS(output,"Sending standard EJECT sequence\n");
@@ -1444,6 +1449,20 @@
    return 1;
 }

+void switchRealtekMode()
+{
+   unsigned char data = 0x08;
+   detachDriver();
+   libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, 5, 0x74, 0, &data, 1, 100);
+   data = 0x02;
+   libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, 5, 0x70, 0, &data, 1, 100);
+   data = 0x01;
+   libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, 5, 0x3e, 0, &data, 1, 100);
+   data = 0x40;
+   libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, 5, 0x3d, 0, &data, 1, 100);
+   data = 0x80;
+   libusb_control_transfer(devh, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, 5, 0x05, 0, &data, 1, 100);
+}

 /* Detach driver
  */

Run it with "./usb_modeswitch -v -p -k 1" before starting the interface.

thiete commented 9 years ago

So I finally got around to looking into this.

Cracyc's patch there does work and this is not a problem with this driver per se, but rather with the device needing to be told to report as USB3. I now have my adapter automatically switching to USB 3 mode.

Here's what I had to do:

My device's descriptor in lsusb is:

Bus 002 Device 002: ID 13b1:003f Linksys 

The 13b1 is the vendor id and the 003f is the device ID. Adjust as appropriate for your device.

At this point, calling usb_modeswitch -v 13b1 -p 003f -k 1 does switch the device into USB 3 mode

To make it automatic, I had to add the following rule to /lib/udev/rules.d/40-usb_modeswitch.rules :

ATTR{idVendor}=="13b1", ATTR{idProduct}=="003f", RUN+="usb_modeswitch '%b/%k'"

And then create a config file in /usr/share/usb_modeswitch called 13b1:003f with the contents:

DefaultVendor= 0x13b1 
DefaultProduct=0x003f

RealtekMode=1

Thank you again cracyc for figuring this out!