UX302NC購入
前回でL-03DでのEthernet接続がギブアップ気味となり、UX302NC購入宣言となった。世に情報もあるし、あっさりつながるだろう。Ethernetに見えれば、夢のIPv4/IPv6デュアルスタックだ。たぶん。
udev設定
こちらのありがたい先人の知恵を、まずはそのまま適用してみる。udevのrulesにATTR{idVendor}
とATTR{idProduct}
でIDを記載するため、ドライバー修正が不要なところがありがたい。
動作確認
pi@raspberrypi:~ $ usb-devices
:
T: Bus=01 Lev=02 Prnt=02 Port=01 Cnt=02 Dev#= 5 Spd=480 MxCh= 0
D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=11f6 ProdID=1034 Rev=02.32
S: Manufacturer=NCXX Inc.
S: Product=NCXX UX302NC
C: #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr=500mA
I: If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
I: If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qcserial
I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qcserial
I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qcserial
あれ、qmi_wwanが居ないではないか…。カーネルバージョンで変わったか、デバイスのファームが変わったか、持ち前の運の悪さか。1つずれているのか?
修正
結局、If#の0〜2がqcserialで、3がqmi_wwanになるようにudevで認識させる方法が分からないので、ええい、面倒だ、ドライバーをいじってしまえ。まさか前回の調査が生きることになるとは…。
qcserial.c
前回のL-03DではGOBI1Kの定義をそのまま使ってしまったが、UX302NCの場合、Windowsドライバの認識では、
- HS-USB Diagnostics = MI_00 (COMポート)
- HS-USB Modem = MI_01 (ATコマンドのCOMポート)
- HS-USB Application = MI_02 (COMポート)
- Ethernet Adapter = MI_03
…となっているので、新たなデバイスタイプを定義してみる。
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -30,6 +30,7 @@ enum qcserial_layouts {
QCSERIAL_G1K = 1, /* Gobi 1000 */
QCSERIAL_SWI = 2, /* Sierra Wireless */
QCSERIAL_HWI = 3, /* Huawei */
+ QCSERIAL_NCX = 4, /* NCXX */
};
#define DEVICE_G1K(v, p) \
@@ -38,6 +39,8 @@ enum qcserial_layouts {
USB_DEVICE(v, p), .driver_info = QCSERIAL_SWI
#define DEVICE_HWI(v, p) \
USB_DEVICE(v, p), .driver_info = QCSERIAL_HWI
+#define DEVICE_NCX(v, p) \
+ USB_DEVICE(v, p), .driver_info = QCSERIAL_NCX
static const struct usb_device_id id_table[] = {
/* Gobi 1000 devices */
@@ -170,6 +173,10 @@ static const struct usb_device_id id_table[] = {
/* Huawei devices */
{DEVICE_HWI(0x03f0, 0x581d)}, /* HP lt4112 LTE/HSPA+ Gobi 4G Modem (Huawei me906e) */
+ /* NCXX devices */
+ {DEVICE_NCX(0x11f6, 0x1034)}, /* NCXX UX302NC */
+ {DEVICE_NCX(0x1004, 0x6326)}, /* NTT docomo L-03D */
+
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, id_table);
@@ -379,6 +386,30 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
intf->desc.bInterfaceProtocol);
}
break;
+ case QCSERIAL_NCX:
+ /*
+ * NCXX layout:
+ * 0: DM/DIAG (use libqcdm from ModemManager for communication)
+ * 1: AT-capable modem port
+ * 2: Application
+ * 3: QMI/net
+ */
+ switch (ifnum) {
+ case 0:
+ dev_dbg(dev, "DM/DIAG interface found\n");
+ break;
+ case 1:
+ dev_dbg(dev, "Modem port found\n");
+ break;
+ case 2:
+ dev_dbg(dev, "Application interface found\n");
+ break;
+ default:
+ /* don't claim any unsupported interface */
+ altsetting = -1;
+ break;
+ }
+ break;
default:
dev_err(dev, "unsupported device layout type: %lu\n",
id->driver_info);
L-03Dも、結局0〜2がserialで3がEthernetという配置は同じなので、dev_dbg()のメッセージの違いは無視して、定義をまとめてしまった。
この直し方が正しいかは不明。前にリセットした気がする…。
qmi_wwan.c
こちらは、
/* Gobi 1000 QMI/wwan interface number is 3 according to qcserial */
#define QMI_GOBI1K_DEVICE(vend, prod) \
QMI_FIXED_INTF(vend, prod, 3)
…とのことなので、これをそのまま活用して、
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -812,6 +812,8 @@ static const struct usb_device_id products[] = {
{QMI_GOBI1K_DEVICE(0x05c6, 0x9203)}, /* Generic Gobi Modem device */
{QMI_GOBI1K_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */
{QMI_GOBI1K_DEVICE(0x05c6, 0x9009)}, /* Generic Gobi Modem device */
+ {QMI_GOBI1K_DEVICE(0x1004, 0x6326)}, /* NTT docomo L-03D */
+ {QMI_GOBI1K_DEVICE(0x11f6, 0x1034)}, /* NCXX UX302NC */
/* 5. Gobi 2000 and 3000 devices */
{QMI_GOBI_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */
…としてみる。
udev
UX302NCは、eject
によるイジェクトがうまく行かなかったので、rulesのsg_raw
の行だけは生かしておき、CD-ROM認識時にイジェエクトさせる。
再び動作確認
Ethernet認識
pi@raspberrypi:~ $ usb-devices
:
T: Bus=01 Lev=02 Prnt=02 Port=01 Cnt=02 Dev#= 5 Spd=480 MxCh= 0
D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=11f6 ProdID=1034 Rev=02.32
S: Manufacturer=NCXX Inc.
S: Product=NCXX UX302NC
C: #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr=500mA
I: If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=qcserial
I: If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qcserial
I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qcserial
I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan
おお。今度はうまく行きそうだ。
接続
APN=iijmio.jp,CHAP,mio@iij,iij
pi@raspberrypi:~ $ sudo qmi-network /dev/cdc-wdm0 start
Loading profile...
APN: iijmio.jp,CHAP,mio@iij,iij
Starting network with 'qmicli -d /dev/cdc-wdm0 --wds-start-network=iijmio.jp,CHAP,mio@iij,iij --client-no-release-cid'...
Saving state... (CID: 10)
Saving state... (PDH: 90627728)
Network started successfully
めでたしめでたし。
IPv4/IPv6デュアルスタック接続への道
Ethernetで認識できたので、PDPtype=IPV4V6にして、めでたくデュアルスタックの運び…となるはずだったのに、ならないのだ、これが。
まず、OSXのUX302NC Data Connection Managerは、IPv4, IPv6, PPPの3択で、IPv4v6が無い。
さらに、libqmiのQmiWdsIpFamily
では、QMI_WDS_IP_FAMILY_IPV4
, QMI_WDS_IP_FAMILY_IPV6
, QMI_WDS_IP_FAMILY_UNSPECIFIED
の3択。
しかも、Raspberry PiからATコマンドが使えない…このドライバーの修正が悪いのか?
このあたりを読むと、QMIの深い罠が…という話は、成功時に別途。
まだデュアルスタック接続に成功していない、というオチであった…。