Re: cdc_ncm: Specific Huawei E3372h firmware version stuck in NTB-32

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux