Index: sys/dev/ixgbe/if_ix.c =================================================================== --- sys/dev/ixgbe/if_ix.c +++ sys/dev/ixgbe/if_ix.c @@ -1135,10 +1135,11 @@ * ixgbe_check_wol_support * * Checks whether the adapter's ports are capable of - * Wake On LAN by reading the adapter's NVM. + * Wake On LAN by reading the adapter's NVM (X540 and newer) + * or by device ID. * * Sets each port's hw->wol_enabled value depending - * on the value read here. + * on the capability determined here. ************************************************************************/ static void ixgbe_check_wol_support(struct adapter *adapter) @@ -1146,17 +1147,76 @@ struct ixgbe_hw *hw = &adapter->hw; u16 dev_caps = 0; - /* Find out WoL support for port */ adapter->wol_support = hw->wol_enabled = 0; - ixgbe_get_device_caps(hw, &dev_caps); - if ((dev_caps & IXGBE_DEVICE_CAPS_WOL_PORT0_1) || - ((dev_caps & IXGBE_DEVICE_CAPS_WOL_PORT0) && - hw->bus.func == 0)) - adapter->wol_support = hw->wol_enabled = 1; /* Save initial wake up filter configuration */ adapter->wufc = IXGBE_READ_REG(hw, IXGBE_WUFC); + /* WoL is not supported on 82598 */ + if (hw->mac.type == ixgbe_mac_82598EB) + return; + + /* For X540 and newer, WoL capability is reported in EEPROM */ + if (hw->mac.type >= ixgbe_mac_X540) { + ixgbe_get_device_caps(hw, &dev_caps); + if ((dev_caps & IXGBE_DEVICE_CAPS_WOL_PORT0_1) || + ((dev_caps & IXGBE_DEVICE_CAPS_WOL_PORT0) && + hw->bus.func == 0)) + goto wol_capable; + return; + } + + /* For 82599, WoL capability is determined based on device IDs */ + switch (hw->device_id) { + case IXGBE_DEV_ID_82599_SFP: + switch (hw->subsystem_device_id) { + /* These subdevices support WoL only on first port */ + case IXGBE_SUBDEV_ID_82599_560FLR: + case IXGBE_SUBDEV_ID_82599_LOM_SNAP6: + case IXGBE_SUBDEV_ID_82599_SFP_WOL0: + case IXGBE_SUBDEV_ID_82599_SFP_2OCP: + if (hw->bus.func != 0) + return; + /* else: fall through */ + + /* These subdevices support WoL on all ports */ + case IXGBE_SUBDEV_ID_82599_SP_560FLR: + case IXGBE_SUBDEV_ID_82599_SFP: + case IXGBE_SUBDEV_ID_82599_RNDC: + case IXGBE_SUBDEV_ID_82599_ECNA_DP: + case IXGBE_SUBDEV_ID_82599_SFP_1OCP: + case IXGBE_SUBDEV_ID_82599_SFP_LOM_OEM1: + case IXGBE_SUBDEV_ID_82599_SFP_LOM_OEM2: + goto wol_capable; + } + break; + + case IXGBE_DEV_ID_82599EN_SFP: + /* These subdevices support WoL on all ports */ + switch (hw->subsystem_device_id) { + case IXGBE_SUBDEV_ID_82599EN_SFP_OCP1: + goto wol_capable; + } + break; + + case IXGBE_DEV_ID_82599_COMBO_BACKPLANE: + /* All except this subdevice support WoL */ + if (hw->subsystem_device_id != + IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ) + goto wol_capable; + break; + + case IXGBE_DEV_ID_82599_KX4: + /* This device supports WoL */ + goto wol_capable; + break; + + default: + break; + } + +wol_capable: + adapter->wol_support = hw->wol_enabled = 1; return; } /* ixgbe_check_wol_support */ @@ -2557,7 +2617,7 @@ "I", "DMA Coalesce"); /* for WoL-capable devices */ - if (hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T) { + if (adapter->wol_support) { SYSCTL_ADD_PROC(ctx_list, child, OID_AUTO, "wol_enable", CTLTYPE_INT | CTLFLAG_RW, adapter, 0, ixgbe_sysctl_wol_enable, "I", "Enable/Disable Wake on LAN"); @@ -2684,8 +2744,8 @@ if (hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T && hw->phy.ops.enter_lplu) { /* Turn off support for APM wakeup. (Using ACPI instead) */ - IXGBE_WRITE_REG(hw, IXGBE_GRC, - IXGBE_READ_REG(hw, IXGBE_GRC) & ~(u32)2); + IXGBE_WRITE_REG(hw, IXGBE_GRC_BY_MAC(hw), + IXGBE_READ_REG(hw, IXGBE_GRC_BY_MAC(hw)) & ~(u32)2); /* * Clear Wake Up Status register to prevent any previous wakeup @@ -3526,7 +3586,8 @@ /* Update DMA coalescing config */ ixgbe_config_dmac(adapter); /* should actually be negotiated value */ - iflib_link_state_change(ctx, LINK_STATE_UP, IF_Gbps(10)); + iflib_link_state_change(ctx, LINK_STATE_UP, + ixgbe_link_speed_to_baudrate(adapter->link_speed)); if (adapter->feat_en & IXGBE_FEATURE_SRIOV) ixgbe_ping_all_vfs(adapter); Index: sys/dev/ixgbe/if_ixv.c =================================================================== --- sys/dev/ixgbe/if_ixv.c +++ sys/dev/ixgbe/if_ixv.c @@ -932,7 +932,7 @@ "Full Duplex"); adapter->link_active = TRUE; iflib_link_state_change(ctx, LINK_STATE_UP, - IF_Gbps(10)); + ixgbe_link_speed_to_baudrate(adapter->link_speed)); } } else { /* Link down */ if (adapter->link_active == TRUE) { Index: sys/dev/ixgbe/ixgbe.h =================================================================== --- sys/dev/ixgbe/ixgbe.h +++ sys/dev/ixgbe/ixgbe.h @@ -574,6 +574,8 @@ return (status); } +uint64_t ixgbe_link_speed_to_baudrate(ixgbe_link_speed speed); + /* Shared Prototypes */ int ixgbe_allocate_queues(struct adapter *); Index: sys/dev/ixgbe/ixgbe_osdep.c =================================================================== --- sys/dev/ixgbe/ixgbe_osdep.c +++ sys/dev/ixgbe/ixgbe_osdep.c @@ -76,3 +76,37 @@ ((struct adapter *)hw->back)->osdep.mem_bus_space_handle, reg + (offset << 2), val); } + +uint64_t +ixgbe_link_speed_to_baudrate(ixgbe_link_speed speed) +{ + uint64_t baudrate; + + switch (speed) { + case IXGBE_LINK_SPEED_10GB_FULL: + baudrate = IF_Gbps(10); + break; + case IXGBE_LINK_SPEED_5GB_FULL: + baudrate = IF_Gbps(5); + break; + case IXGBE_LINK_SPEED_2_5GB_FULL: + baudrate = IF_Mbps(2500); + break; + case IXGBE_LINK_SPEED_1GB_FULL: + baudrate = IF_Gbps(1); + break; + case IXGBE_LINK_SPEED_100_FULL: + baudrate = IF_Mbps(100); + break; + case IXGBE_LINK_SPEED_10_FULL: + baudrate = IF_Mbps(10); + break; + case IXGBE_LINK_SPEED_UNKNOWN: + default: + baudrate = 0; + break; + } + + return baudrate; +} +