🪛

LinuxでRealtek製USB NICを使用する方法

2023/11/30に公開

Realtek USB FE / GBE / 2.5G / Gaming Ethernet Family ControllerをLinuxで正しく認識させる方法

まず前提としてRealtek USB FE / GBE / 2.5G / Gaming Ethernet Family Controllerとは、RTL8156 / RTL8156B(S)(G) / RTL8153 / RTL8153B / RTL8154 / RTL8154B / RTL8152B のRealtekチップセットを搭載したUSB NICのこと(らしい)。

Linux上で上記のRealtekチップセットを搭載したUSB NICを指すとcdc_ncmというドライバが優先して読み込まれてしまい、一応は動くものの速度が遅かったり完全動作しない。

自分の場合はRTL8156チップセットのUSB NICを使用したところ、Speed/Duplexが1000/Halfになってしまった。

  • Driver=cdc_ncmになっている
# lsusb -t -v
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/6p, 10000M
    ID 1d6b:0003 Linux Foundation 3.0 root hub
    |__ Port 4: Dev 3, If 0, Class=Vendor Specific Class, Driver=cdc_ncm, 5000M
        ID 0bda:8156 Realtek Semiconductor Corp.

調べたところcdc_ncmというのはUSB接続デバイスをNICとして認識させるための標準規格だそうで、いわゆる「挿しただけでNICとして認識するUSBデバイス」はこの規格に準拠しているが故にcdc_ncmドライバが読み込まれる。LinuxはRealtek専用ドライバを内臓しているにも関わらず、接続方式がUSBだとcdc_ncmの汎用ドライバが優先されてしまう。

対策としてudevルールファイルを使用して、cdc_ncmの汎用ドライバではなくRealtek用の専用ドライバを読み込むように設定変更する。

具体的な手順としては、Realtek公式サイトで公開されているドライバファイルの中に、上記の問題を解決するためのudevルールファイルが含まれているので、udevルールファイルだけ拝借して反映させる。

https://www.realtek.com/ja/component/zoo/category/network-interface-controllers-10-100-1000m-gigabit-ethernet-usb-3-0-software

cat << '_EOL_' >/etc/udev/rules.d/50-usb-realtek-net.rules
# This is used to change the default configuration of Realtek USB ethernet adapters

ACTION!="add", GOTO="usb_realtek_net_end"
SUBSYSTEM!="usb", GOTO="usb_realtek_net_end"
ENV{DEVTYPE}!="usb_device", GOTO="usb_realtek_net_end"

# Modify this to change the default value
ENV{REALTEK_MODE1}="1"
ENV{REALTEK_MODE2}="3"

# Realtek
ATTR{idVendor}=="0bda", ATTR{idProduct}=="815[2,3,5,6]", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}"
ATTR{idVendor}=="0bda", ATTR{idProduct}=="8053", ATTR{bcdDevice}=="e???", ATTR{bConfigurationValue}!="$env{REALTEK_MODE2}", ATTR{bConfigurationValue}="$env{REALTEK_MODE2}"

# Samsung
ATTR{idVendor}=="04e8", ATTR{idProduct}=="a101", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}"

# Lenovo
ATTR{idVendor}=="17ef", ATTR{idProduct}=="304f", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}"
ATTR{idVendor}=="17ef", ATTR{idProduct}=="3052", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}"
ATTR{idVendor}=="17ef", ATTR{idProduct}=="3054", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}"
ATTR{idVendor}=="17ef", ATTR{idProduct}=="3057", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}"
ATTR{idVendor}=="17ef", ATTR{idProduct}=="3062", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}"
ATTR{idVendor}=="17ef", ATTR{idProduct}=="3069", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}"
ATTR{idVendor}=="17ef", ATTR{idProduct}=="3082", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}"
ATTR{idVendor}=="17ef", ATTR{idProduct}=="3098", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}"
ATTR{idVendor}=="17ef", ATTR{idProduct}=="7205", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}"
ATTR{idVendor}=="17ef", ATTR{idProduct}=="720a", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}"
ATTR{idVendor}=="17ef", ATTR{idProduct}=="720b", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}"
ATTR{idVendor}=="17ef", ATTR{idProduct}=="720c", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}"
ATTR{idVendor}=="17ef", ATTR{idProduct}=="7214", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}"
ATTR{idVendor}=="17ef", ATTR{idProduct}=="721e", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}"
ATTR{idVendor}=="17ef", ATTR{idProduct}=="8153", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}"
ATTR{idVendor}=="17ef", ATTR{idProduct}=="a359", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}"
ATTR{idVendor}=="17ef", ATTR{idProduct}=="a387", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}"

# TP-LINK
ATTR{idVendor}=="2357", ATTR{idProduct}=="0601", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}"

# Nvidia
ATTR{idVendor}=="0955", ATTR{idProduct}=="09ff", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}"

# LINKSYS
ATTR{idVendor}=="13b1", ATTR{idProduct}=="0041", ATTR{bConfigurationValue}!="$env{REALTEK_MODE1}", ATTR{bConfigurationValue}="$env{REALTEK_MODE1}"

LABEL="usb_realtek_net_end"
_EOL_

後はOS再起動すれば、正しく認識されるはず

cdc_ncmからRealtekドライバに切り替わっていたら成功

  • Driver=r8152になっている
# lsusb -t -v
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/6p, 10000M
    ID 1d6b:0003 Linux Foundation 3.0 root hub
    |__ Port 4: Dev 3, If 0, Class=Vendor Specific Class, Driver=r8152, 5000M
        ID 0bda:8156 Realtek Semiconductor Corp.

なお、ノンブランドの中華製USB NICなどidVenderとidProductを何も書き換えていない格安品は上記のudevルールファイルで正しく動作するが、大手メーカーなどで販売されている商品だとidVenderやidProductを独自の値に書き換えているため、上記のルールではマッチせず正しく読み込まれないことがあるようなので注意。

Discussion