LANポートがないLinuxマシンを有線接続したく、手持ちのUSB Type-C to RJ45 のアダプタを使おうとしたけれど、ちょっと苦労したよという話。
対象のアダプタ
もはやいつ買ったかわからないコレ。
利用環境
- ハードウェア: Surface Go (初代)
- OS : Kali linux
- Kernel : 6.11.2
とりあえず挿したら動いたが
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とのことで、その線で探すとチップメーカーのサイトにファームがあったのでダウンロード。
ドライバをインストール
展開して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。
なかなか苦労してしまったが、解決してよかった。
