LinuxでRealtek製USB NICを使用する方法
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ルールファイルだけ拝借して反映させる。
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