Found a solution.
>> I have two mobile broadband Huawei E3372h devices, one with firmware
>> 21.200.07.01.26 (aka the 200-version) and one with firmware
>> 21.318.01.00.541 (aka the 318-version).
>>
>> Whereas the 200-version works perfectly with a recent kernel (4.10),
>> the latter never manages to exchange any IP-packets. Upon debugging
>> USB-traces, I found that the 200-version correctly switches to NTB-16,
>> whereas the 318-version stays in NTB-32 mode.
>
> And both these firmwares use the cdc_ncm class driver directly, and not
> the huawei_cdc_ncm driver? I.e. they appear as true CDC NCM class
> devices
They appear to use the huawei_cdc_ncm driver. I am not at all familiar with
driver nor kernel architecture, so I am sorry if I am being a bit vague.
> Could you test if
>
> echo Y >/sys/class/net/xxx/cdc_ncm/ndp_to_end
>
> makes any difference, where xxx is the name of your wwan netdev?
It did not make any difference. See root cause below.
> Section 7.2 "Using Alternate Settings to Reset an NCM Function":
>
> "Whenever alternate setting 0 is selected by the host, the function
> shall:
> ..
> - reset the NTB format to NTB-16
> “
I downloaded the spec, and started to investigate. Comparing Windows driver
traces to the spec, I noticed that the Windows driver queried GET_NTB_FORMAT,
prior to setting it to NTB-32. It was always 0x0001h (aka. NTB-32), directly
after coming out of alternate setting = 0.
So I threw together a small python-usb script, to see what was different
between the two devices I had.
My testing sequence is:
alt_setting = 1
alt_setting = 0
GET_NTB_PARAMETERS
GET_NTB_FORMAT (#A)
SET_CRC_MODE
SET_NTB_FORMAT
GET_NTB_FORMAT (#B)
alt_setting = 1
GET_NTB_FORMAT (#C)
SET_NTB_FORMAT
GET_NTB_FORMAT (#D)
BOTH devices come out of alt_setting = 0 (after step #A) with GET_NTB_FORMAT =
0x0001h!
Readout of GET_NTB_FORMAT:
#A 200: 0x0001 318: 0x0001 <— bug in both
#B 200: 0x0000 318: 0x0000
#C 200: 0x0000 318: 0x0001 <— bug in 318
#D 200: 0x0000 318: 0x0000
So it is clear, that the 318-firmware resets to NTB-32 after alt_setting = 1
It is clearly non-standard behaviour.
The spec concerning SET_NTB_FORMAT reads:
"The host shall only send this command while the NCM Data Interface is in
alternate setting 0.”
So I blindly added:
usbnet_write_cmd(dev, USB_CDC_SET_NTB_FORMAT,
USB_TYPE_CLASS | USB_DIR_OUT
| USB_RECIP_INTERFACE,
USB_CDC_NCM_NTB16_FORMAT,
iface_no, NULL, 0);
in cdc_ncm_bind_common after the interface was switched back with alt_setting
= 1. Now the device works.
I have zero experience whether this should or could be implemented in the
driver, nor do I have any kernel development experience.
A solution in pseudocode:
If GET_NTB_FORMAT == 0x0001 { // no restraints on alt setting according to spec
// device is still in NTB-32 mode, which clearly indicates
// a firmware that is not in the accordance with the spec
Run SET_NTB_FORMAT(0x0000)
}
> We cannot make vendors fix their firmwares, but we can vote for less
> buggy firmware with our wallets…
Sadly I did not investigate this prior to my purchase, otherwise I would have
stayed clear of these devices.
Its been a long and convoluted journey. But I learned a lot.
Thank you for your hints and guidance,
Christian --
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html