WOLが有効にならなかったので、いろいろいじって有効にしたときのメモ。
LinuxではethtoolでWake on LANを有効にするが、FreeBSDはifconfigで有効にできる。
ifconfig igb0 wol_magic
だが、FreeBSD 13.0-RELEASE-p5 (GENERIC) で上記コマンドは通るがMAGICパケットを送っても起動しない。ifconfigの出力にはWOL_MAGICのフラグは立っている。
% ifconfig | grep WOL
options=4e527bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,WOL_MAGIC,VLAN_HWFILTER,VLAN_HWTSO,RXCSUM_IPV6,TXCSUM_IPV6,NOMAP>
FreeBSD Bugzilla で検索するとズバリっぽいのを見つけた。
早速、Comment 23にあるドライバにパッチをComment 24と同じように一部省いて当ててカーネルを再構築したらWOLできるようになった。
微妙にそのままパッチが当たらなかったので念の為ここに貼っておく。
--- if_em.c.orig 2021-11-21 09:29:47.470457000 +0900
+++ if_em.c 2021-11-27 20:08:00.085251000 +0900
@@ -2654,12 +2654,8 @@
/* Issue a global reset */
e1000_reset_hw(hw);
- if (adapter->hw.mac.type >= igb_mac_min) {
- E1000_WRITE_REG(hw, E1000_WUC, 0);
- } else {
- E1000_WRITE_REG(hw, E1000_WUFC, 0);
- em_disable_aspm(adapter);
- }
+ em_disable_aspm(adapter);
+
if (adapter->flags & IGB_MEDIA_RESET) {
e1000_setup_init_funcs(hw, TRUE);
e1000_get_bus_info(hw);
@@ -3750,13 +3746,18 @@
*/
if ((if_getcapenable(ifp) & IFCAP_WOL_MAGIC) == 0)
adapter->wol &= ~E1000_WUFC_MAG;
+ else
+ adapter->wol |= E1000_WUFC_MAG;
if ((if_getcapenable(ifp) & IFCAP_WOL_UCAST) == 0)
adapter->wol &= ~E1000_WUFC_EX;
+ else
+ adapter->wol |= E1000_WUFC_EX;
if ((if_getcapenable(ifp) & IFCAP_WOL_MCAST) == 0)
adapter->wol &= ~E1000_WUFC_MC;
else {
+ adapter->wol |= E1000_WUFC_MC;
rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
rctl |= E1000_RCTL_MPE;
E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl);
@@ -3903,7 +3904,20 @@
{
int base, reg;
u16 link_cap,link_ctrl;
+ u32 wuc;
device_t dev = adapter->dev;
+ struct e1000_hw *hw = &adapter->hw;
+
+ /*
+ * untouch PME_EN and APME bits
+ * wake on lan isn't fully disabled but any events isn't connectted
+ */
+ wuc = E1000_READ_REG(hw, E1000_WUC);
+ wuc &= (E1000_WUC_PME_EN | E1000_WUC_APME);
+ E1000_WRITE_REG(hw, E1000_WUC, wuc);
+
+ /* disconnet all events from wakeup */
+ E1000_WRITE_REG(hw, E1000_WUFC, 0);
switch (adapter->hw.mac.type) {
case e1000_82573:
ついでにpatch当て+再構築手順。confファイルは変えないのでGENERICのまま。同じGENERICでもuname -vで識別できるので特に問題なし。
cd /usr/src/sys/dev/e1000/ cp -p if_em.c if_em.c.orig cp -p /root/if_em.c . cd /usr/src/sys/amd64/conf/ config GENERIC cd ../compile/GENERIC/ make cleandepend && make depend cd /usr/src make buildkernel make installkernel