5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Raspberry Piで、UX302NCをEthernetとして認識する

Last updated at Posted at 2016-04-11

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

…となっているので、新たなデバイスタイプを定義してみる。

drivers/usb/serial/qcserial.c
--- 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

こちらは、

drivers/net/usb/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)

…とのことなので、これをそのまま活用して、

drivers/net/usb/qmi_wwan.c
--- 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

おお。今度はうまく行きそうだ。

接続

/etc/qmi-network.conf
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の深い罠が…という話は、成功時に別途。
まだデュアルスタック接続に成功していない、というオチであった…。

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?