[CCing Enrico]
Christian Panton <[email protected]> writes:
> 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.
OK, then all bets regarding specs are off since this is a vendor
specific function. They can do whatever they want with it.
>> 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.
No, that is expected in this case. The huawei_cdc_ncm driver already
enforce this.
>> 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.”
Yes, and violating this is known to cause issues with other devices.
> 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)
> }
Maybe we can do that? GET_NTB_FORMAT is allowed in altsetting 1 if the
device supports multiple formats. And as it should always return
USB_CDC_NCM_NTB16_FORMAT (0) here, the SET_NTB_FORMAT will never be
sent unless the device is buggy. So we do not violate the spec.
What do you think, Enrico?
Bjørn
--
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