2025/01/19

LinuxマシンでUSBのLANアダプタを使いたい

 LANポートがないLinuxマシンを有線接続したく、手持ちのUSB Type-C to RJ45 のアダプタを使おうとしたけれど、ちょっと苦労したよという話。

対象のアダプタ

もはやいつ買ったかわからないコレ。

利用環境

とりあえず挿したら動いたが

IFはUPしたようなので見てみると、

$ inxi -n             
Network:
  Device-2: ASIX AX88179 Gigabit Ethernet driver: cdc_ncm
    type: USB
  IF: eth0 state: up speed: 1000 Mbps duplex: half
    mac: 20:7b:d2:63:b2:d0

IPアドレスは取れており、通信もできるものの、久しぶりに見たduplex half …!

どうも、標準のドライバであるcdc_ncmでとりあえずは動いているけれど、auto negoに対応しておらず、halfで上がってしまっている模様。

以下いずれもコマンド通らず。

$ ethtool -s eth0 duplex full
$ ethtool -s eth0 autoneg on

さすがに解決したいので、専用ドライバを入れることに。

ドライバを探す

UGREENのサイトにあるはずが、以下のダウンロードサイトはJPサイトにリダイレクトされ、たどり着けない。

https://www.ugreen.com/pages/download

OSの言語を変えてもUS経由でアクセスしてもリダイレクトされるのでよくわからず諦める。

Amazonの製品仕様を見ると、チップセットはAX88179aとのことで、その線で探すとチップメーカーのサイトにファームがあったのでダウンロード。

www.asix.com.tw

ドライバをインストール

展開してmakeする。

$ tar -jxvf ASIX_USB_NIC_Linux_Driver_Source_v3.4.0.tar.bz2
$ cd ASIX_USB_NIC_Linux_Driver_Source_v3.4.0
$ make

make -C /lib/modules/6.11.2-amd64/build M=/home/hit/Downloads/ASIX_USB_NIC_Linux_Driver_Source_v3.4.0 modules
make[1]: Entering directory '/usr/lib/modules/6.11.2-amd64/build'
make[1]: *** No rule to make target 'modules'.  Stop.
make[1]: Leaving directory '/usr/lib/modules/6.11.2-amd64/build'
make: *** [Makefile:75: all] Error 2

おおっとエラー。

/usr/lib/modules/カーネル/ の下にbuildがないとかmoduleがとか言ってきたら、カーネルヘッダが入っていないことが原因と思われるので、確認の上インストール。

$ sudo apt update
$ sudo apt install linux-headers-$(uname -r)

その上であらためてmakeする。

$ make
$ make install

インストールされ、ロードされていることを確認する。名前は「ax_usb_nic」。

$ lsmod | grep ax_usb_nic

もしロードされていなければ、手動でロードする。

$sudo modprobe ax_usb_nic

また、自動ロードされるように/etc/modules-load.d/modules.confに「ax_usb_nic」を追記しておく。

$ echo "ax_usb_nic" | sudo tee -a /etc/modules-load.d/modules.conf
$ cat /etc/modules-load.d/modules.conf

また、ロードされていると、USB NICを接続した状態で、以下の場所にドライバが見える。

$ ls /sys/bus/usb/drivers/
ax88179_178a  btusb      cdc_mbim  cdc_wdm  usb    usbhid
ax_usb_nic    cdc_ether  cdc_ncm   hub      usbfs

USBを抜き再接続して、ドライバが適用されるか確認してみる。

$ lsusb -t
(中略)
/:  Bus 002.Port 001: Dev 001, Class=root_hub, Driver=xhci_hcd/6p, 5000M
    |__ Port 001: Dev 002, If 0, Class=Communications, Driver=cdc_ncm, 5000M
    |__ Port 001: Dev 002, If 1, Class=CDC Data, Driver=cdc_ncm, 5000M

だめ。専用ドライバがあるのに、cdc_ncmがあたってしまう。

ドライバを手動で当てて動作を確認する

しかたがないので、まずは手動でドライバを当てて確認してみる。lsusb -tの結果から、当該デバイスはBus2のPort1のIF1ということで、当たりをつけつつ正しいIF番号を確認。

$ ls /sys/bus/usb/devices/              
1-0:1.0  1-5:1.0  1-7      1-7:1.1  1-7:1.3  2-1      usb1
1-5      1-5:1.1  1-7:1.0  1-7:1.2  2-0:1.0  2-1:1.0  usb2

対象は「2-1:1.0」で良さそう。このIFに対して、cdc_ncmをアンバインドし、ax_usb_nicをバインドする。

$ echo -n "2-1:1.0" | sudo tee /sys/bus/usb/drivers/cdc_ncm/unbind
$ echo -n "2-1:1.0" | sudo tee /sys/bus/usb/drivers/ax_usb_nic/bind

あらためて、あたっているドライバを確認し、auto negoになったか、FullでUPしたかを確認。

$ inxi -n     
Network:
Device-2: ASIX AX88179 Gigabit Ethernet driver: ax_usb_nic type: USB
  IF: eth0 state: up speed: 1000 Mbps duplex: full mac: 20:7b:d2:63:b2:d0

$ ethtool eth0
Settings for eth0:
(中略)
      Speed: 1000Mb/s
        Duplex: Full
        Auto-negotiation: on

問題解決!!

しかしこのままだと、USBを抜き差しするとまた標準ドライバがあたってしまう。

ドライバを自動で当たるようにする

まずcdc_ncmが自動適用されないよう、modprobeのブラックリストに入れてしまう。

$ echo "blacklist cdc_ncm" | sudo tee /etc/modprobe.d/blacklist-cdc_ncm.conf

次に、ax_usb_nicが対象デバイスに当たるよう、udevルールを作成し適用する。VendorID, ProductIDは環境に合わせて適宜記述。

$ sudo vi /etc/udev/rules.d/90-ax_usb_nic.rules
# 以下の内容を記述し保存する
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="0b95", ATTR{idProduct}=="1790", RUN+="/sbin/modprobe ax_usb_nic"
 
$ sudo udevadm control --reload-rules
$ sudo udevadm trigger

USB抜き差しや再起動をして、ax_usb_nicが自動であたればOK。

なかなか苦労してしまったが、解決してよかった。