...
以下にLinux用ixgbeドライバにおけるSFP+ベンダーロックのロジック概要を記載する。
SFP+ベンダーロックの実装は、ixgbeベンダーロック機構は、ixgbe_phy.cのixgbe_identify_sfp_module_generic関数内で実装されている。
...
- SFP/SFP+のEEPROMを取得し、サポート対象外のSFP/SFP+でないことを確認する
- サポートされるOpticsはチップごとに異なるためここには記載しないが、必要に応じてコードを確認のこと
- 10G DACの場合、ベンダーによらずすべてのOpticsを許可する
- 1G SFPのうち、サポート指定ないものが挿入されている場合はエラーとするSFPのうち、サポートしていないものが挿入されている場合はエラーとする
- 82598EBベースのNICの場合、OpticsのベンダーによらずすべてのOpticsを許可する
- NICのEEPROM内に記録されているDEVICE_CAPS(Device Capabilities)を確認し、"IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP" (0x01)のフラグが立っていない場合、以下のチェックを実行する。
- 1G SFPの場合、ベンダーによらずサポートしている種類のトランシーバであれば許可する
- 10G SFP+の場合、SFP+のベンダーコードがIntelのものであれば許可する
- SFP+のベンダーコードがIntelでない場合、ドライバの"allow_unsupported_sfp"オプションを確認し、有効であれば警告メッセージを表示した上で許可する
- 上記の条件にマッチしない場合、エラーとする
- IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP (0x01)のフラグが立っている場合、すべてのトランシーバを許可する
...
また、ixgbe_type.h内のIXGBE_DEVICE_CAPS_ALLOW_ANY_SFP定数によると、このフラグは0x01、すなわち最下位ビットであることがわかる。によると、このフラグは0x01とのANDで取り出されており、すなわち最下位ビットであることがわかる。
IXGBE_DEVICE_CAPSは2bytesの長さをもつが、EEPROM上ではリトルエンディアンで格納されているため、バイト単位でみるとEEPROMの0x58番地の最下位ビットがこのフラグになる。
...
Linuxにおいては、IXGBE_DEVICE_CAPSはSFPのチェックを実行するたびに読み込まれるため、書き換えを完了したら動作に即時反映され、無事にSFP+のベンダーロックを回避することができる。この変更は永続的なものとなり、Windows等ドライバのオプションでは回避が難しいOS上においても動作するものと考えられる。
なお、デュアルポートNIC等では複数のポートが認識されるが、1つのポートに対して書き換えを実施すればすべてのポートで変更が有効となる。
確認
筆者の環境において上記手法を用いた際ののログを以下に記載する。筆者の環境において上記手法を用いた際のログを以下に記載する。
$ sudo ethtool -e eth1 offset 0x58 length 1
Offset Values
------ ------
0x0058: fe
>>> SFP+の抜挿
$ dmesg | tail -n 2
[ 2790.220891] ixgbe 0000:0a:00.0 eth1: WARNING: Intel (R) Network Connections are quality tested using Intel (R) Ethernet Optics. Using untested modules is not supported and may cause unstable operation or damage to the module or the adapter. Intel Corporation is not responsible for any harm caused by using untested modules.
[ 2790.220896] ixgbe 0000:0a:00.0 eth1: detected SFP+: 5
$ sudo ethtool -E eth1 magic 0x15c48086 offset 0x58 value 0xff
$ sudo ethtool -e eth1 offset 0x58 length 1
Offset Values
------ ------
0x0058: ff
>>> SFP+の抜挿
$ dmesg | tail -n 2
[ 2790.220896] ixgbe 0000:0a:00.0 eth1: detected SFP+: 5
[ 3097.967617] ixgbe 0000:0a:00.0 eth1: detected SFP+: 5
...