D-Link DWM-222 USB LTE Dongle
-
I have a D-Link DWM-222 USB 4G LTE dongle that has been running perfectly on a Linux machine, and now im looking to use it as a backup WAN interface on pfSense 2.4.3.
The problem is that the dongle dosent appear as a modem/network device and is similar to this thread.
I have installed usb_modeswitch and the USB dongle seems to be in the correct mode (0x7e35 is the same mode that works in Linux) but when checking dmesg the system references a storage device. When the device was setup for Linux i had to run echo "2001 7e35" > /sys/bus/usb-serial/drivers/option1/new_id before any devices appeared under /dev. Is there a pfSense/BSD counterpart?
The thread i linked to mentioned recompiling the pfSense kernel with the latest version of u3g, but its a 2 year old thread so i imagine that that particular version of u3g is now included.
Any tips/ideas?
usbconfig -d ugen2.2 dump_device_desc ugen2.2: <Mobile Connect Mobile Connect> at usbus2, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (500mA) bLength = 0x0012 bDescriptorType = 0x0001 bcdUSB = 0x0201 bDeviceClass = 0x0000 <Probed by interface class> bDeviceSubClass = 0x0000 bDeviceProtocol = 0x0000 bMaxPacketSize0 = 0x0040 idVendor = 0x2001 idProduct = 0x7e35 bcdDevice = 0x0228 iManufacturer = 0x0001 <Mobile Connect> iProduct = 0x0002 <Mobile Connect> iSerialNumber = 0x0003 <0123456789ABCDEF> bNumConfigurations = 0x0001
ugen2.2: <Mobile Connect Mobile Connect> at usbus2 umass0 on uhub5 umass0: <Mass Storage> on usbus2 da1 at umass-sim0 bus 0 scbus4 target 0 lun 0 da1: < SD Storage 0000> Removable Direct Access SCSI-2 device da1: 40.000MB/s transfers da1: Attempt to query device size failed: ILLEGAL REQUEST, Invalid command operation da1: quirks=0x2<NO_6_BYTE>
-
What does this show?:
usbconfog -d ugen2.2 dump_all_config_desc
That appears to be the correct mode at least.
Steve
-
Hi @stephenw10
Here is the output you requested:
usbconfig -d ugen2.2 dump_all_config_desc ugen2.2: <Mobile Connect Mobile Connect> at usbus2, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (500mA) Configuration index 0 bLength = 0x0009 bDescriptorType = 0x0002 wTotalLength = 0x00e8 bNumInterfaces = 0x0006 bConfigurationValue = 0x0001 iConfiguration = 0x0000 <no string> bmAttributes = 0x0080 bMaxPower = 0x00fa Interface 0 bLength = 0x0009 bDescriptorType = 0x0004 bInterfaceNumber = 0x0000 bAlternateSetting = 0x0000 bNumEndpoints = 0x0002 bInterfaceClass = 0x00ff <Vendor specific> bInterfaceSubClass = 0x00ff bInterfaceProtocol = 0x00ff iInterface = 0x0000 <no string> Endpoint 0 bLength = 0x0007 bDescriptorType = 0x0005 bEndpointAddress = 0x0081 <IN> bmAttributes = 0x0002 <BULK> wMaxPacketSize = 0x0200 bInterval = 0x0000 bRefresh = 0x0000 bSynchAddress = 0x0000 Endpoint 1 bLength = 0x0007 bDescriptorType = 0x0005 bEndpointAddress = 0x0001 <OUT> bmAttributes = 0x0002 <BULK> wMaxPacketSize = 0x0200 bInterval = 0x0000 bRefresh = 0x0000 bSynchAddress = 0x0000 Interface 1 bLength = 0x0009 bDescriptorType = 0x0004 bInterfaceNumber = 0x0001 bAlternateSetting = 0x0000 bNumEndpoints = 0x0003 bInterfaceClass = 0x00ff <Vendor specific> bInterfaceSubClass = 0x0000 bInterfaceProtocol = 0x0000 iInterface = 0x0000 <no string> Additional Descriptor bLength = 0x05 bDescriptorType = 0x24 bDescriptorSubType = 0x00 RAW dump: 0x00 | 0x05, 0x24, 0x00, 0x10, 0x01 Additional Descriptor bLength = 0x05 bDescriptorType = 0x24 bDescriptorSubType = 0x01 RAW dump: 0x00 | 0x05, 0x24, 0x01, 0x00, 0x00 Additional Descriptor bLength = 0x04 bDescriptorType = 0x24 bDescriptorSubType = 0x02 RAW dump: 0x00 | 0x04, 0x24, 0x02, 0x02 Additional Descriptor bLength = 0x05 bDescriptorType = 0x24 bDescriptorSubType = 0x06 RAW dump: 0x00 | 0x05, 0x24, 0x06, 0x00, 0x00 Endpoint 0 bLength = 0x0007 bDescriptorType = 0x0005 bEndpointAddress = 0x0083 <IN> bmAttributes = 0x0003 <INTERRUPT> wMaxPacketSize = 0x000a bInterval = 0x0009 bRefresh = 0x0000 bSynchAddress = 0x0000 Endpoint 1 bLength = 0x0007 bDescriptorType = 0x0005 bEndpointAddress = 0x0082 <IN> bmAttributes = 0x0002 <BULK> wMaxPacketSize = 0x0200 bInterval = 0x0000 bRefresh = 0x0000 bSynchAddress = 0x0000 Endpoint 2 bLength = 0x0007 bDescriptorType = 0x0005 bEndpointAddress = 0x0002 <OUT> bmAttributes = 0x0002 <BULK> wMaxPacketSize = 0x0200 bInterval = 0x0000 bRefresh = 0x0000 bSynchAddress = 0x0000 Interface 2 bLength = 0x0009 bDescriptorType = 0x0004 bInterfaceNumber = 0x0002 bAlternateSetting = 0x0000 bNumEndpoints = 0x0003 bInterfaceClass = 0x00ff <Vendor specific> bInterfaceSubClass = 0x0000 bInterfaceProtocol = 0x0000 iInterface = 0x0000 <no string> Additional Descriptor bLength = 0x05 bDescriptorType = 0x24 bDescriptorSubType = 0x00 RAW dump: 0x00 | 0x05, 0x24, 0x00, 0x10, 0x01 Additional Descriptor bLength = 0x05 bDescriptorType = 0x24 bDescriptorSubType = 0x01 RAW dump: 0x00 | 0x05, 0x24, 0x01, 0x00, 0x00 Additional Descriptor bLength = 0x04 bDescriptorType = 0x24 bDescriptorSubType = 0x02 RAW dump: 0x00 | 0x04, 0x24, 0x02, 0x02 Additional Descriptor bLength = 0x05 bDescriptorType = 0x24 bDescriptorSubType = 0x06 RAW dump: 0x00 | 0x05, 0x24, 0x06, 0x00, 0x00 Endpoint 0 bLength = 0x0007 bDescriptorType = 0x0005 bEndpointAddress = 0x0085 <IN> bmAttributes = 0x0003 <INTERRUPT> wMaxPacketSize = 0x000a bInterval = 0x0009 bRefresh = 0x0000 bSynchAddress = 0x0000 Endpoint 1 bLength = 0x0007 bDescriptorType = 0x0005 bEndpointAddress = 0x0084 <IN> bmAttributes = 0x0002 <BULK> wMaxPacketSize = 0x0200 bInterval = 0x0000 bRefresh = 0x0000 bSynchAddress = 0x0000 Endpoint 2 bLength = 0x0007 bDescriptorType = 0x0005 bEndpointAddress = 0x0003 <OUT> bmAttributes = 0x0002 <BULK> wMaxPacketSize = 0x0200 bInterval = 0x0000 bRefresh = 0x0000 bSynchAddress = 0x0000 Interface 3 bLength = 0x0009 bDescriptorType = 0x0004 bInterfaceNumber = 0x0003 bAlternateSetting = 0x0000 bNumEndpoints = 0x0003 bInterfaceClass = 0x00ff <Vendor specific> bInterfaceSubClass = 0x0000 bInterfaceProtocol = 0x0000 iInterface = 0x0000 <no string> Additional Descriptor bLength = 0x05 bDescriptorType = 0x24 bDescriptorSubType = 0x00 RAW dump: 0x00 | 0x05, 0x24, 0x00, 0x10, 0x01 Additional Descriptor bLength = 0x05 bDescriptorType = 0x24 bDescriptorSubType = 0x01 RAW dump: 0x00 | 0x05, 0x24, 0x01, 0x00, 0x00 Additional Descriptor bLength = 0x04 bDescriptorType = 0x24 bDescriptorSubType = 0x02 RAW dump: 0x00 | 0x04, 0x24, 0x02, 0x02 Additional Descriptor bLength = 0x05 bDescriptorType = 0x24 bDescriptorSubType = 0x06 RAW dump: 0x00 | 0x05, 0x24, 0x06, 0x00, 0x00 Endpoint 0 bLength = 0x0007 bDescriptorType = 0x0005 bEndpointAddress = 0x0087 <IN> bmAttributes = 0x0003 <INTERRUPT> wMaxPacketSize = 0x000a bInterval = 0x0009 bRefresh = 0x0000 bSynchAddress = 0x0000 Endpoint 1 bLength = 0x0007 bDescriptorType = 0x0005 bEndpointAddress = 0x0086 <IN> bmAttributes = 0x0002 <BULK> wMaxPacketSize = 0x0200 bInterval = 0x0000 bRefresh = 0x0000 bSynchAddress = 0x0000 Endpoint 2 bLength = 0x0007 bDescriptorType = 0x0005 bEndpointAddress = 0x0004 <OUT> bmAttributes = 0x0002 <BULK> wMaxPacketSize = 0x0200 bInterval = 0x0000 bRefresh = 0x0000 bSynchAddress = 0x0000 Interface 4 bLength = 0x0009 bDescriptorType = 0x0004 bInterfaceNumber = 0x0004 bAlternateSetting = 0x0000 bNumEndpoints = 0x0003 bInterfaceClass = 0x00ff <Vendor specific> bInterfaceSubClass = 0x00ff bInterfaceProtocol = 0x00ff iInterface = 0x0000 <no string> Endpoint 0 bLength = 0x0007 bDescriptorType = 0x0005 bEndpointAddress = 0x0089 <IN> bmAttributes = 0x0003 <INTERRUPT> wMaxPacketSize = 0x0008 bInterval = 0x0009 bRefresh = 0x0000 bSynchAddress = 0x0000 Endpoint 1 bLength = 0x0007 bDescriptorType = 0x0005 bEndpointAddress = 0x0088 <IN> bmAttributes = 0x0002 <BULK> wMaxPacketSize = 0x0200 bInterval = 0x0000 bRefresh = 0x0000 bSynchAddress = 0x0000 Endpoint 2 bLength = 0x0007 bDescriptorType = 0x0005 bEndpointAddress = 0x0005 <OUT> bmAttributes = 0x0002 <BULK> wMaxPacketSize = 0x0200 bInterval = 0x0000 bRefresh = 0x0000 bSynchAddress = 0x0000 Interface 5 bLength = 0x0009 bDescriptorType = 0x0004 bInterfaceNumber = 0x0005 bAlternateSetting = 0x0000 bNumEndpoints = 0x0002 bInterfaceClass = 0x0008 <Mass storage> bInterfaceSubClass = 0x0006 bInterfaceProtocol = 0x0050 iInterface = 0x0004 <Mass Storage> Endpoint 0 bLength = 0x0007 bDescriptorType = 0x0005 bEndpointAddress = 0x008a <IN> bmAttributes = 0x0002 <BULK> wMaxPacketSize = 0x0200 bInterval = 0x0000 bRefresh = 0x0000 bSynchAddress = 0x0000 Endpoint 1 bLength = 0x0007 bDescriptorType = 0x0005 bEndpointAddress = 0x0006 <OUT> bmAttributes = 0x0002 <BULK> wMaxPacketSize = 0x0200 bInterval = 0x0001 bRefresh = 0x0000 bSynchAddress = 0x0000
-
Hmm, I was hoping there might have been more than one config index.
It's unclear if that can be attached directly as a serial device or if it only operates in QMI mode. FreeBSD/pfSense has no support for QMI so the latter would be nothing we could do anything about.
This seems to imply at has a direct AT interface though:
http://www.draisberghof.de/usb_modeswitch/bb/viewtopic.php?p=17090&sid=c42d79fffb93e20cc475b6402655039b#p17090It is shown in current FreeBSD dev lists though:
https://github.com/freebsd/freebsd/blob/9e7534ea78acf644eb328d5ba27aca2cab72c915/sys/dev/usb/usbdevs#L1722...and in u3g so it probably would work with FreeBSD 12:
https://github.com/freebsd/freebsd/blob/9e7534ea78acf644eb328d5ba27aca2cab72c915/sys/dev/usb/serial/u3g.c#L241It was not in 11.2 though so will not be supported by pfSense 2.4.4 without back-porting that change to u3g.
Steve
-
@stephenw10 when i was using the dongle in Linux i belive it was being used as a serial device so id like to give that a try. Any thoughts on how i can attach it directly as a serial device in BSD/pfSense? I also attempted to do some testing on FreeBSD 11.1, but no success.
-
First thing would be to try a FreeBSD 12 snapshot to confirm it is recognised and working there. No point wasting time otherwise. https://download.freebsd.org/ftp/snapshots/ISO-IMAGES/12.0/
Recompiling to get that into 2.4.4 is non-trival though.
Steve
-
@stephenw10 said in D-Link DWM-222 USB LTE Dongle:
First thing would be to try a FreeBSD 12 snapshot to confirm it is recognised and working there. No point wasting time otherwise. https://download.freebsd.org/ftp/snapshots/ISO-IMAGES/12.0/
Recompiling to get that into 2.4.4 is non-trival though.
Steve
Any updates on this @stephenw10?
I have the same modem ...
# usbconfig
ugen0.1: <Intel XHCI root HUB> at usbus0, cfg=0 md=HOST spd=SUPER (5.0Gbps) pwr=SAVE (0mA) ugen2.1: <Intel EHCI root HUB> at usbus2, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA) ugen1.1: <Intel EHCI root HUB> at usbus1, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA) ugen2.2: <vendor 0x8087 product 0x8000> at usbus2, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA) ugen1.2: <vendor 0x8087 product 0x8008> at usbus1, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA) ugen0.2: <Mobile Connect Mobile Connect> at usbus0, cfg=255 md=HOST spd=HIGH (480Mbps) pwr=ON (500mA)
I also noticed:
# cat /usr/local/share/usb_modeswitch/2001:ac01
# D-Link DWM-222 A2 TargetVendor=0x2001 TargetProduct=0x7e3d StandardEject=1
Using Pfsense on non-Netgate hardware:
2.7.2-RELEASE (amd64) built on Thu Dec 7 7:10:00 AEDT 2023 FreeBSD 14.0-CURRENT
-
-
@stephenw10, I also just found these announcements saying D-Link DWM-222 has been supported since FreeBSD 11.4; however, I am using Pfsense 2.7.2 which is on top of FreeBSD 14, and it doesn't seem to work at all.
-
What are the actual USB IDs of your device? Manufacturers often change the hardware and use the same model name unfortunately.
That device is listed: https://github.com/pfsense/FreeBSD-src/blob/RELENG_2_7_2/sys/dev/usb/usbdevs#L1762
-
@stephenw10 I'm not sure if this is the right way to identify it as my experience with FreeBSD is very limited, but I got this: usbconfig_dump_device_desc.txt
If I connect it to a Windows 11 laptop, I get this from the Device Manager:
I also found these logs: system.log.txt
And attempted a mode switch without success: attempt_modeswitch.txt
Sorry I had to attach logs as files, but this forum is flagging everything I try to post as spam.
Cheers,
Gabriel. -
@stephenw10 As an additional experiment, I created a VM with FreeBSD 14 using a Proxmox environment I have and passed the entire USB through to it.
On that one, I have this: experiment.txt
I can see that it then shows
cfg=0
, which is different fromcfg=255
that I got on the Pfsense machine. However, it still only seems to see one config? -
OK so it shows up as a different product ID in pfSense/FreeBSD:
idVendor = 0x2001 idProduct = 0xac01
If it has more than one config index you can force it use a different one. You can check that with, for example:
usbconfig -d ugen0.2 dump_all_config_desc
Anyway
ac01
is the device before it has been modeswitched:
product DLINK DWM222_CD_2 0xac01 DWM-222 CD-ROM Mode
You may simply be able to eject the virtual CD to switch it or run usbmodeswitch. Then recheck the usbconfig output to make sure it changed.
However u3g should be doing that already:
https://github.com/pfsense/FreeBSD-src/blob/RELENG_2_7_2/sys/dev/usb/serial/u3g.c#L247I would try unplugging it then plugging it back in and checking the system logs. I'd expect to see u3g trying to switch it and attach to the ports.
-
@stephenw10 said in D-Link DWM-222 USB LTE Dongle:
You may simply be able to eject the virtual CD to switch it or run usbmodeswitch
How would you do the eject exactly? And the modeswitch?
Unplugging it and then plugging it again gives me only this in
/var/log/system.log
.Apr 1 09:41:14 pfSense kernel: ugen0.2: <Mobile Connect Mobile Connect> at usbus0 (disconnected) Apr 1 09:42:03 pfSense kernel: ugen0.2: <Mobile Connect Mobile Connect> at usbus0
Nothing changes for
usbconfig -d ugen0.2 dump_all_config_desc
:[2.7.2-RELEASE][admin@pfSense.home.arpa]/root: usbconfig -d ugen0.2 dump_all_config_desc ugen0.2: <Mobile Connect Mobile Connect> at usbus0, cfg=255 md=HOST spd=HIGH (480Mbps) pwr=ON (500mA) Configuration index 0 bLength = 0x0009 bDescriptorType = 0x0002 wTotalLength = 0x0020 bNumInterfaces = 0x0001 bConfigurationValue = 0x0001 iConfiguration = 0x0000 <no string> bmAttributes = 0x0080 bMaxPower = 0x00fa Interface 0 bLength = 0x0009 bDescriptorType = 0x0004 bInterfaceNumber = 0x0000 bAlternateSetting = 0x0000 bNumEndpoints = 0x0002 bInterfaceClass = 0x0008 <Mass storage> bInterfaceSubClass = 0x0006 bInterfaceProtocol = 0x0050 iInterface = 0x0004 <Mass Storage> Endpoint 0 bLength = 0x0007 bDescriptorType = 0x0005 bEndpointAddress = 0x0081 <IN> bmAttributes = 0x0002 <BULK> wMaxPacketSize = 0x0200 bInterval = 0x0000 bRefresh = 0x0000 bSynchAddress = 0x0000 Endpoint 1 bLength = 0x0007 bDescriptorType = 0x0005 bEndpointAddress = 0x0001 <OUT> bmAttributes = 0x0002 <BULK> wMaxPacketSize = 0x0200 bInterval = 0x0001 bRefresh = 0x0000 bSynchAddress = 0x0000
I don't see any messages with
u3g
in any file under/var/log
. I searched for it everywhere. What would those logs look like? How do I know thatu3g
is running and/or working as exected?I also added this to
/boot/loader.conf
:u3g_load="YES" hw.usb.ehci.iaadbug="1" hw.usb.ehci.debug="1" hw.usb.xhci.debug="1"
But nothing new was printed to
/var/log/system.log
. -
u3g is in-kernel you shouldn't need to load it.
You don't see the virtual CD drive either? You would need to see that in order to eject it.
The config does show a mass storage device which might be a uSD card slot for example. You don't see that logged either though?
If u3g works as expected you would see something like:
u3g0: Found 5 ports. u3g0: <Huawei Mobile Connect - Modem> on usbus0 u3g0 on uhub0
-
@stephenw10 said in D-Link DWM-222 USB LTE Dongle:
You don't see the virtual CD drive either? You would need to see that in order to eject it.
Do you mean with
camcontrol
? If so, this is what I see:[2.7.2-RELEASE][admin@pfSense.home.arpa]/root: camcontrol devlist -v scbus0 on ahcich0 bus 0: <ST500DM002-1BD142 KC66> at scbus0 target 0 lun 0 (ada0,pass0) <> at scbus0 target -1 lun ffffffff () scbus1 on ahcich2 bus 0: <hp CDDVDW SN-208FB HJ10> at scbus1 target 0 lun 0 (cd0,pass1) <> at scbus1 target -1 lun ffffffff () scbus2 on ahciem0 bus 0: <AHCI SGPIO Enclosure 2.00 0001> at scbus2 target 0 lun 0 (ses0,pass2) <> at scbus2 target -1 lun ffffffff () scbus-1 on xpt0 bus 0: <> at scbus-1 target -1 lun ffffffff (xpt0)
The config does show a mass storage device which might be a uSD card slot for example. You don't see that logged either though?
If u3g works as expected you would see something like:
u3g0: Found 5 ports. u3g0: <Huawei Mobile Connect - Modem> on usbus0 u3g0 on uhub0
I have zero logs from
u3g
. I searched with:grep -lr "u3g" /var/log
And it found nothing.
Now, as an experiment, I installed FreeBSD 14 (not Pfsense) on a VM and passed the entire USB port to it. This is not on the same hardware I am using with Pfsense. I managed to make it work with the VM as discussed here: https://forums.freebsd.org/threads/issues-with-d-link-dwm-222.92946/
Notice that on this successful experiment, I found messages from
u3g
in/var/log/messages
in the plain FreeBSD installation. However, in Pfsense, I don't even have a/var/log/messages
file. Why's that?Then, I created a second VM with the Pfsense ISO instead of plain FreeBSD, and I managed to reproduce the exact same problem I am having with Pfsense on the bare metal.
In the VM, I passed the entire USB through to Pfsense, and I got: pfsense-vm.txt
There, I equally have no
/var/log/messages
and no logs fromu3g
. -
Hmm, seems like that device might be in some odd mode then. The virtual CD drive function doesn't require any sort of driver. The USB ID implies it should be there but isn't for some reason.
I would check it in Windows. If it has some setup utility make sure it hasn't been set with something odd.