Bug 192345 - [u3g] [cdce] patch for huawei 4G/LTE modems: E3272, E3372
Summary: [u3g] [cdce] patch for huawei 4G/LTE modems: E3272, E3372
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: usb (show other bugs)
Version: 11.1-STABLE
Hardware: Any Any
: --- Affects Many People
Assignee: Hans Petter Selasky
Depends on:
Reported: 2014-08-02 20:41 UTC by Ivan Rozhuk
Modified: 2019-08-14 14:50 UTC (History)
5 users (show)

See Also:

patch (6.95 KB, patch)
2014-08-02 20:42 UTC, Ivan Rozhuk
no flags Details | Diff
add cdc 46 code (7.17 KB, patch)
2014-08-03 00:53 UTC, Ivan Rozhuk
no flags Details | Diff
UISUBCLASS_ABSTRACT_CONTROL_MODEL -> 0x02, some cosmetic (7.19 KB, patch)
2014-08-03 02:25 UTC, Ivan Rozhuk
no flags Details | Diff
typo fix in comment (7.19 KB, patch)
2014-08-03 19:27 UTC, Ivan Rozhuk
no flags Details | Diff
Same patch but reduced to including only E3272 related changes; the rest was committed. (4.53 KB, patch)
2014-08-05 10:20 UTC, Nick Hibma
no flags Details | Diff
E3272, E3372 (2.05 KB, patch)
2017-11-26 02:21 UTC, Ivan Rozhuk
no flags Details | Diff
Add InterfaceSubClass 0x03, InterfaceProtocol 0x16 (2.75 KB, patch)
2017-11-26 02:47 UTC, Ivan Rozhuk
no flags Details | Diff
move usbd_set_parent_iface() (2.75 KB, patch)
2017-12-02 22:50 UTC, Ivan Rozhuk
no flags Details | Diff
move usbd_set_parent_iface() fixed (3.65 KB, patch)
2017-12-03 02:03 UTC, Ivan Rozhuk
no flags Details | Diff
use BUS_PROBE_DEFAULT for cdce (3.65 KB, patch)
2017-12-03 02:13 UTC, Ivan Rozhuk
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Ivan Rozhuk 2014-08-02 20:41:48 UTC
Updates huawei usb mode switch (code from usb-modeswitch-2.2.0).
New switch code and modems without initial CD-ROM only mode - use vendor specific InterfaceClass.
Tested on E3272 with different FW.

Details: http://4pda.ru/forum/index.php?showtopic=508842&view=findpost&p=33295644
Comment 1 Ivan Rozhuk 2014-08-02 20:42:22 UTC
Created attachment 145259 [details]
Comment 2 Ivan Rozhuk 2014-08-03 00:53:47 UTC
Created attachment 145278 [details]
add cdc 46 code
Comment 3 Ivan Rozhuk 2014-08-03 02:25:25 UTC
Created attachment 145289 [details]
Comment 4 Ivan Rozhuk 2014-08-03 19:27:09 UTC
Created attachment 145319 [details]
typo fix in comment
Comment 5 Nick Hibma freebsd_committer 2014-08-05 10:20:01 UTC
Created attachment 145389 [details]
Same patch but reduced to including only E3272 related changes; the rest was committed.

The attached patch has been reduced to the stuff which has not yet been committed. Please note that this patch can not be applied as is to the sources due to me picking out the rest of the patch and committing that.

This patch I am not quite sure how it works: It looks like the u3g driver is used to do the eject and ignore the device afterwards. The change around line 857 in u3g.c I don't like. Could you attach the output of


after attaching the device? And the output of

   usbconfig -d ugenX.Y dump_device_desc

Thanks for the other changes! They have been committed (in some form).
Comment 6 Ivan Rozhuk 2014-08-05 10:50:55 UTC
Modem can be configured in two ways:
1. With initial CD-ROM: AT^SETPORT="A1;10,12,16,A1,A2", here we need send special code to switch from A1 to 10,12,16,A1,A2 devices
2. Without initial CD-ROM: AT^SETPORT="FF;10,12,16,A1,A2", after modem bootup we get 10,12,16,A1,A2 devices, no need send mode switch code.

with init (eject) code: 11060000000000000000000000000000
idProduct = 0x1c1e
    Interface 0
      bInterfaceClass = 0x0002
      bInterfaceSubClass = 0x0002
      bInterfaceProtocol = 0x00ff
on newer FW, like 153-21.470.05.00.00, modem is hang

11062000000101000100000000000000 (from usb-modeswitch-2.2.0)
or in mode without init CD (AT^SETPORT="FF;10,12,16,A1,A2")

idProduct = 0x1506
    Interface 0
      bInterfaceClass = 0x00ff
      bInterfaceSubClass = 0x0002
      bInterfaceProtocol = 0x0061
(looks like this is default behavior in new FW/modems)

scsi_huawei_eject2 - That's what I did, it was first thought, but Huawei seems to have made a new code backwards compatible with the old, and usb-modeswitch brought upon the idea that only one code.
Another problem with the two codes initialization - hard to see which one you want to send.

Without U3G_HUAWEI_IS_CDC u3d try attach cdc device as ucom.

device_printf(dev, "port %d supports modem control",
missing /n ?

What about NOVATEL MC990D?
It works too.
Comment 7 Nick Hibma freebsd_committer 2014-08-05 11:01:05 UTC
I've committed the device_printf and Novatel changes.
Comment 8 Ivan Rozhuk 2014-08-05 11:15:39 UTC
On different FW:


^SETPORT:7C: SerialC
^SETPORT:78: Shell A
^SETPORT:79: Shell B
^SETPORT:7B: SerialB
^SETPORT:7A: SerialA

These codes used in:
AT^SETPORT="A1;10,12,16,A1,A2" - modem config
and with new usb-modeswitch code (11062000000101000100000000000000) thes codes is in devs proto ID
idProduct = 0x1506
    Interface 0
      bInterfaceClass = 0x00ff
      bInterfaceSubClass = 0x0002
      bInterfaceProtocol = 0x0061

bInterfaceProtocol = 0x0061 = ^SETPORT:61: 4G MODEM

so without update modeswitch code and U3G_HUAWEI_IS_CDC modems will not work!!!

In linux thes codes used in linux cdc-ncm http://lxr.free-electrons.com/source/drivers/net/usb/huawei_cdc_ncm.c?v=3.13
see huawei_cdc_ncm_devs[]
Comment 9 Nick Hibma freebsd_committer 2014-08-05 11:44:21 UTC
I've added your mode switch code to the CDCE driver. That is better than hacking u3g to ignore the switched device.

What version can you test this change with?

- 10.0-RELEASE

I've implemented a patch against 11-CURRENT but can send you patched sources for the others if you like.
Comment 10 commit-hook freebsd_committer 2014-08-05 12:09:51 UTC
A commit references this bug:

Author: n_hibma
Date: Tue Aug  5 12:08:51 UTC 2014
New revision: 269584
URL: http://svnweb.freebsd.org/changeset/base/269584

  Add support for Huawei E3272 modems which are supported by the CDC
  ethernet class.

  Note: This is untested as I do not have a device like this. That is
  reflected in the MFC timeout.

  PR:		192345
  Submitted by:	rozhuk.im gmail.com
  MFC after:	4 weeks

Comment 11 Ivan Rozhuk 2014-08-05 13:14:02 UTC
I can test with 10.0-STABLE and 11-CURRENT.

What is now in the database will work like this: modem with fresh firmware if u3g send initialization code (old) first, the modem hangs up.

For initializing the modem responds u3g and do not need to do it somewhere else either.
Can be ignored in the device driver u3g not the best way, but add mode switching in cdce much worse.

Huawei announce the device as a specific vendor, this means that the driver must have the code that handles this specificity. 
Now u3g attaches ucom indiscriminately on everything and it's not right. 

If you are confused by the difference initialization code - see the discussion in the usb-modeswitch, and why they decided to keep only one code.
Comment 12 Ivan Rozhuk 2014-08-05 13:26:28 UTC
I can give you full access to my test computer with FreeBSD 10/11 and the connected modem (1-2 gigabytes of traffic through the modem is not the problem), so that you yourself can test everything.
More I can flash the modem to an older firmware that does not hang from the old initialization code, and vice versa.
Comment 13 Gavin Atkinson freebsd_committer freebsd_triage 2014-10-07 20:04:54 UTC
Hi Nick,

I'm having difficulty here picking out exactly what the status with this PR is, but:

I think I agree with the submitter about the modeswitch stuff - it appears that the second quirk is not necessary (r269576). usb_modeswitch switched on the recommendation of Huawei, and I think we should switch over too.

I also think something similar to the submitter's suggestion needs committing to the u3g driver in order to stop it from claiming devices incorrectly.  See http://www.dd-wrt.com/wiki/index.php/3G_/_3.5G and search for 12d1:1506 for example - note how some have the protocol "ncm" (and therefore are cdce devices) and some have other protocols listed .  I quite like the submitter's method of achieving this.

Comment 14 Nick Hibma freebsd_committer 2014-10-08 12:28:47 UTC

I've implemented part of his suggested patch and changed the other part to something more to my liking.

The problem I see with his approach is that he stuffs something into u3g which belongs in the ucdc driver.

I haven;t had time lately to work on this, but intend to pick this up when time permits.
Comment 15 Ivan Rozhuk 2014-11-03 21:06:48 UTC
Possible to argue long what the correct initialization code, and you can take and rewrite u3g to accept arbitrary code via sysctl.

u3g.VEN_ID.initcode="INIT CODE IN HEX" - defailt init code for vendor
u3g.VEN_ID.DEV_ID.initcode="INIT CODE IN HEX" - init code for specific device
u3g.VEN_ID.DEV_ID.init_mode="0" - as example of params.

No need to do initialization in if_cdce (remove it out of there), for this is u3g, he plays the role usb-modeswitch.
No need to keep all staff in u3g and usb_msctest.c.

I can take for the implementation of that described above, if my patches will not be cut into pieces break my ideas in general.
Comment 16 Nick Hibma freebsd_committer 2014-11-03 21:33:49 UTC
I won't be able to work on this. I am not happy with the fact that CDCE related code ends up in the U3G driver, but I can't justify blocking this either.

I'll leave the decision the HPS.
Comment 17 Mark Linimon freebsd_committer freebsd_triage 2015-03-12 03:38:27 UTC
Canonicalize assignment.
Comment 18 Hans Petter Selasky freebsd_committer 2015-03-12 06:48:09 UTC

Are the magic device class numbers documented anywhere?

Comment 19 Hans Petter Selasky freebsd_committer 2015-03-12 07:12:29 UTC
Basically the patch looks OK. I see some values come from the Linux CDC driver.

Have you tried the opposite, adding those umodem.c ID's to the U3G driver instead?

We have some workarounds like in r271492 for HUAWEI devices in the u3g driver which are not in the CDC modem driver.


Comment 20 Glen Barber freebsd_committer 2015-07-08 18:32:18 UTC
To originators/assignees of this PR:

A commit to the tree references this PR, however the PR is still in a non-closed state.

Please review this PR and close as appropriate, or if closing the PR requires a merge to stable/10, please let re@ know as soon as possible.

Thank you.

Comment 21 Ivan Rozhuk 2017-11-26 02:21:51 UTC
Created attachment 188286 [details]
E3272, E3372

All other, except userial already in base r11.1.
E3131 share PID with E3372 (at lest with few firmwares), but U3GINIT_HUAWEISCSI2 should work and with older modems.

I check patch only with E3272 and E3372.
Comment 22 Ivan Rozhuk 2017-11-26 02:47:03 UTC
Created attachment 188288 [details]
Add InterfaceSubClass 0x03, InterfaceProtocol 0x16

Add bInterfaceSubClass == 0x03 bInterfaceProtocol == 0x16 from linux:
Comment 23 Hans Petter Selasky freebsd_committer 2017-11-27 13:14:29 UTC

The "U3G_HUAWEI_IS_CDC" macro should be converted into a new quirk in the usb_quirk.c . Can you do that instead of adding specific code for this? Then new ID's can easily be added later on.

Comment 24 Ivan Rozhuk 2017-11-27 18:08:56 UTC
I see usb_quirk.c but not found how to add device Interfaces ID.
U3G_HUAWEI_IS_CDC() macro catch only specific device interfaces, that specified in if_cdce, but I dont know how to add if_cdce probe/attach in u3g like this done for ucom.
Comment 25 Hans Petter Selasky freebsd_committer 2017-11-27 18:50:18 UTC
For now, simply add in "usb_test_quirk_by_info()" by code:

if (quirk == UQ_CDC_HUAWEI) {
 if (XXXX)
   return (1),

And make sure the UQ_XXX value gets defined as described in usb_quirk.h

I see the quirk table is currently not advanced enough to contain this quirk.
Comment 26 Ivan Rozhuk 2017-11-27 21:33:22 UTC
I think add to u3g module depend if_cdce, [export and] call cdce_probe to check is device cdce is more proper way than playing with quirk.
u3g already cam handle ucom and add if_cdce handle is good way.
Comment 27 Hans Petter Selasky freebsd_committer 2017-11-27 21:54:59 UTC
There is another way. You can set different probe priority too. I'm not sure how well it is to mix these USB drivers together.

Comment 28 Ivan Rozhuk 2017-12-02 22:48:37 UTC
First modem interface in huawei cases is serial.
FBSD call probe() and u3g wins.
FBSD call attach() and u3g attach to all interfaces.
No more probe() call, all interfaces marked as u3g child.

There is 3 ways:
1. Now I move usbd_set_parent_iface(uaa->device, i, uaa->info.bIfaceIndex); after usbd_transfer_setup(), witch probably success only with serial devices.

2. u3g will atach only to one device per attach() call, so some modems will generate fews u3g devices.

3. Add check, that will call cdce probe() from u3g and on success will skip interface.
(Same thing was done in first patch, but instead of cdce probe() call code with dev check was duplicated)
Comment 29 Ivan Rozhuk 2017-12-02 22:50:03 UTC
Created attachment 188479 [details]
move usbd_set_parent_iface()
Comment 30 Ivan Rozhuk 2017-12-03 02:03:40 UTC
Created attachment 188484 [details]
move usbd_set_parent_iface() fixed
Comment 31 Ivan Rozhuk 2017-12-03 02:13:17 UTC
Created attachment 188485 [details]
use BUS_PROBE_DEFAULT for cdce
Comment 32 Ivan Rozhuk 2017-12-18 13:27:22 UTC
Comment 33 Hans Petter Selasky freebsd_committer 2017-12-18 13:57:48 UTC

The patch looks OK, but I see a problem with /etc/devd/usb.conf, that the widening of the matching and USB bus probe default might cause the wrong driver to be loaded by devd ...

devd usually only expects one match when loading a driver.

Comment 34 Ivan Rozhuk 2017-12-18 15:19:17 UTC
(In reply to Hans Petter Selasky from comment #33)

IMHO it is different problem, that user can fix by manual loading cdce or add it to loader.conf[.local] or to kld_list in rc.conf[.local].
We can add cdce to u3g as required module or patch devd to load 2 modules/drivers. I prefer to change devd config :)

Half of patch is not huawei specific, it affect all other devices that handled by u3g+cdce and that have serial interface before cdce interface.
Comment 35 Hans Petter Selasky freebsd_committer 2017-12-18 16:56:45 UTC
OK. I see. I'll try to give your patch the needed attention this week.
Thanks for the reminder.

Comment 36 Hans Petter Selasky freebsd_committer 2018-01-16 16:06:05 UTC
Still on my todo. Has been very hectic.
Comment 37 commit-hook freebsd_committer 2018-01-19 12:59:29 UTC
A commit references this bug:

Author: hselasky
Date: Fri Jan 19 12:59:14 UTC 2018
New revision: 328162
URL: https://svnweb.freebsd.org/changeset/base/328162

  Improve support for USB based 3G/4G/5G dongles from Huawei.

  PR:		192345
  Sponsored by:	Mellanox Technologies

Comment 38 Hans Petter Selasky freebsd_committer 2018-01-19 12:59:46 UTC
Check if the submitted patch works for you.

Comment 39 Ivan Rozhuk 2018-01-19 14:05:48 UTC
You re implement my first solution, U3G_HUAWEI_IS_CDC() = u3g_huawei_is_cdc() is same.

My last patch does not need this function to work.
See: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=192345#c28

We do not need compare device id~s, we need only one simple thing: call
usbd_set_parent_iface(uaa->device, i, uaa->info.bIfaceIndex);
only after some serial sub device is attached.

Current code call: usbd_set_parent_iface(uaa->device, i, uaa->info.bIfaceIndex);
then try attach and if it fail then device still marked as "no need to driver probe".

Also my patch on probe() fail return more proper code.
Comment 40 Hans Petter Selasky freebsd_committer 2018-01-19 14:11:18 UTC
Yes, I know. Because I think drivers should only have one probe success. The approach with multiple probes returning a match, and then falling back to the best, is not good. It will also confuse devd.

My question to you: Does my patch work or not?
Comment 41 commit-hook freebsd_committer 2018-03-19 04:04:39 UTC
A commit references this bug:

Author: eadler
Date: Mon Mar 19 04:03:55 UTC 2018
New revision: 331176
URL: https://svnweb.freebsd.org/changeset/base/331176

  MFC r328162:

  Improve support for USB based 3G/4G/5G dongles from Huawei.

  PR:		192345

_U  stable/11/
Comment 42 Mark Linimon freebsd_committer freebsd_triage 2018-08-05 05:34:20 UTC
Committed 2018-03-19.
Comment 43 jeff 2019-08-13 09:42:18 UTC
Hi ,
  We have a Alix 2d13 i386 with pfsense 2.3.5 which is based on freebsd 10.3..netgate stop its support on nanobsd based on i386 so I cant upgrade it anything newer than pfsense 2.3.5 freebsd 10.3..My problem is we want to use it with 4g e3372 converted with stick firmware 21.300 (non hilink). When plug it on my alix  here's dmesg:

ugen1.2: <HUAWEIMOBILE> at usbus1
u3g0: <NCM Network Control Model> on usbus1
u3g0: Found 2 ports

No ue0/cdc inteface came up..I tried it with vm pfsense 2.4.4 freebsd 11 and modem was detected , I see ue0/cdc interface came up..
my 3372 modem has 0x12d1 Sub=03 Prot=16t . and I think there's no cdc module for 0x12d1 Sub=03 Prot=16 on 10.3,

I just want to ask if I can compile this cdce driver for 10.3 and apply this patch??Hope someone could help.I can donate for some beers,,
Comment 44 Hans Petter Selasky freebsd_committer 2019-08-13 10:01:49 UTC
If the code compiles it should work for this case.
Comment 45 jeff 2019-08-13 10:22:03 UTC
Do i need to apply this patch to u3g as well? after compilation , Can I load patched u3g and cdc module on our pfsense 2.3.5??
Comment 46 jeff 2019-08-13 10:34:15 UTC
I use vmware freebsd 10.3 and download sources.Can someone please guide me in applying this patch and compiling it on 10.3
Comment 47 jeff 2019-08-14 08:20:04 UTC
I patched and compiled cdce driver on 10.3 box..Then I attached the e3372 and it was detected and ue0 interface came up..I copy if_cdce.ko to /boot/kernel folder on pfsense 10.3 and add this this line if_cdce_load="YES" to boot/loader.conf..but still same issue..no ue0 interface .. any ideas ??
Comment 48 Hans Petter Selasky freebsd_committer 2019-08-14 08:33:10 UTC
Did you unload the if_cdce driver before installing new one?

Anything printed in dmesg?
Comment 49 jeff 2019-08-14 14:50:05 UTC
I tried first on vm fresh install pf 2.3.5..load this driver on boot.no ue0 inteface..here's the dmesg

BIOS 640kB/261120kB available memory

FreeBSD/x86 bootstrap loader, Revision 1.1
(root@ce23-i386-builder, Tue Oct 24 04:52:46 CDT 2017)
Loading /boot/defaults/loader.conf
/boot/kernel/kernel text=0x122025a data=0x84738c+0xd9688 syms=[0x4+0xf3aa0+0x4+0                                                                                        x16b822]
/boot/kernel/if_cdce.ko text=0x35e0 data=0x164+0x4 syms=[0x4+0x920+0x4+0x9ff]

.then I tried it again on vm fress install 10.3 , load this driver on boot..ue0 interface came up..