From owner-svn-src-stable-11@freebsd.org Sun Aug 27 21:36:45 2017 Return-Path: Delivered-To: svn-src-stable-11@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 9C5EEDF866B; Sun, 27 Aug 2017 21:36:45 +0000 (UTC) (envelope-from marius@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 69B19831EB; Sun, 27 Aug 2017 21:36:45 +0000 (UTC) (envelope-from marius@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v7RLaioL067005; Sun, 27 Aug 2017 21:36:44 GMT (envelope-from marius@FreeBSD.org) Received: (from marius@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v7RLai0I067004; Sun, 27 Aug 2017 21:36:44 GMT (envelope-from marius@FreeBSD.org) Message-Id: <201708272136.v7RLai0I067004@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: marius set sender to marius@FreeBSD.org using -f From: Marius Strobl Date: Sun, 27 Aug 2017 21:36:44 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r322956 - stable/11/sys/dev/e1000 X-SVN-Group: stable-11 X-SVN-Commit-Author: marius X-SVN-Commit-Paths: stable/11/sys/dev/e1000 X-SVN-Commit-Revision: 322956 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-11@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 11-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 27 Aug 2017 21:36:45 -0000 Author: marius Date: Sun Aug 27 21:36:44 2017 New Revision: 322956 URL: https://svnweb.freebsd.org/changeset/base/322956 Log: MFC: r312641 Enable WOL features also for igb(4) class of devices. PR: 208343 Submitted by: Kaho Tashikazu Modified: stable/11/sys/dev/e1000/if_igb.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/dev/e1000/if_igb.c ============================================================================== --- stable/11/sys/dev/e1000/if_igb.c Sun Aug 27 18:18:01 2017 (r322955) +++ stable/11/sys/dev/e1000/if_igb.c Sun Aug 27 21:36:44 2017 (r322956) @@ -719,12 +719,6 @@ igb_detach(device_t dev) igb_release_manageability(adapter); igb_release_hw_control(adapter); - if (adapter->wol) { - E1000_WRITE_REG(&adapter->hw, E1000_WUC, E1000_WUC_PME_EN); - E1000_WRITE_REG(&adapter->hw, E1000_WUFC, adapter->wol); - igb_enable_wakeup(dev); - } - /* Unregister VLAN events */ if (adapter->vlan_attach != NULL) EVENTHANDLER_DEREGISTER(vlan_config, adapter->vlan_attach); @@ -776,13 +770,8 @@ igb_suspend(device_t dev) igb_release_manageability(adapter); igb_release_hw_control(adapter); + igb_enable_wakeup(dev); - if (adapter->wol) { - E1000_WRITE_REG(&adapter->hw, E1000_WUC, E1000_WUC_PME_EN); - E1000_WRITE_REG(&adapter->hw, E1000_WUFC, adapter->wol); - igb_enable_wakeup(dev); - } - IGB_CORE_UNLOCK(adapter); return bus_generic_suspend(dev); @@ -1231,6 +1220,14 @@ igb_ioctl(struct ifnet *ifp, u_long command, caddr_t d ifp->if_capenable ^= IFCAP_LRO; reinit = 1; } + if (mask & IFCAP_WOL) { + if (mask & IFCAP_WOL_MAGIC) + ifp->if_capenable ^= IFCAP_WOL_MAGIC; + if (mask & IFCAP_WOL_MCAST) + ifp->if_capenable ^= IFCAP_WOL_MCAST; + if (mask & IFCAP_WOL_UCAST) + ifp->if_capenable ^= IFCAP_WOL_UCAST; + } if (reinit && (ifp->if_drv_flags & IFF_DRV_RUNNING)) igb_init(adapter); VLAN_CAPABILITIES(ifp); @@ -2290,7 +2287,7 @@ igb_stop(void *arg) } e1000_reset_hw(&adapter->hw); - E1000_WRITE_REG(&adapter->hw, E1000_WUC, 0); + E1000_WRITE_REG(&adapter->hw, E1000_WUFC, 0); e1000_led_off(&adapter->hw); e1000_cleanup_led(&adapter->hw); @@ -3126,7 +3123,7 @@ igb_reset(struct adapter *adapter) /* Issue a global reset */ e1000_reset_hw(hw); - E1000_WRITE_REG(hw, E1000_WUC, 0); + E1000_WRITE_REG(hw, E1000_WUFC, 0); /* Reset for AutoMediaDetect */ if (adapter->flags & IGB_MEDIA_RESET) { @@ -3218,6 +3215,13 @@ igb_setup_interface(device_t dev, struct adapter *adap | IFCAP_VLAN_MTU; /* + * Enable only WOL MAGIC by default if WOL is enabled in EEPROM. + */ + ifp->if_capabilities |= IFCAP_WOL; + if (adapter->wol) + ifp->if_capenable |= IFCAP_WOL_MAGIC; + + /* ** Don't turn this on by default, if vlans are ** created on another pseudo device (eg. lagg) ** then vlan events are not passed thru, breaking @@ -5498,22 +5502,61 @@ igb_is_valid_ether_addr(uint8_t *addr) static void igb_enable_wakeup(device_t dev) { - u16 cap, status; - u8 id; + struct adapter *adapter = device_get_softc(dev); + struct ifnet *ifp = adapter->ifp; + u32 pmc, ctrl, ctrl_ext, rctl, wuc; + u16 status; - /* First find the capabilities pointer*/ - cap = pci_read_config(dev, PCIR_CAP_PTR, 2); - /* Read the PM Capabilities */ - id = pci_read_config(dev, cap, 1); - if (id != PCIY_PMG) /* Something wrong */ + if (pci_find_cap(dev, PCIY_PMG, &pmc) != 0) return; - /* OK, we have the power capabilities, so - now get the status register */ - cap += PCIR_POWER_STATUS; - status = pci_read_config(dev, cap, 2); - status |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE; - pci_write_config(dev, cap, status, 2); - return; + + adapter->wol = E1000_READ_REG(&adapter->hw, E1000_WUFC); + if (ifp->if_capenable & IFCAP_WOL_MAGIC) + adapter->wol |= E1000_WUFC_MAG; + else + adapter->wol &= ~E1000_WUFC_MAG; + + if (ifp->if_capenable & IFCAP_WOL_MCAST) { + 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); + } else + adapter->wol &= ~E1000_WUFC_MC; + + if (ifp->if_capenable & IFCAP_WOL_UCAST) + adapter->wol |= E1000_WUFC_EX; + else + adapter->wol &= ~E1000_WUFC_EX; + + if (!(adapter->wol & (E1000_WUFC_EX | E1000_WUFC_MAG | E1000_WUFC_MC))) + goto pme; + + /* Advertise the wakeup capability */ + ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL); + ctrl |= (E1000_CTRL_SWDPIN2 | E1000_CTRL_SWDPIN3); + E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl); + + /* Keep the laser running on Fiber adapters */ + if (adapter->hw.phy.media_type == e1000_media_type_fiber || + adapter->hw.phy.media_type == e1000_media_type_internal_serdes) { + ctrl_ext = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT); + ctrl_ext |= E1000_CTRL_EXT_SDP3_DATA; + E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT, ctrl_ext); + } + + /* Enable wakeup by the MAC */ + wuc = E1000_READ_REG(&adapter->hw, E1000_WUC); + wuc |= E1000_WUC_PME_EN | E1000_WUC_APME; + E1000_WRITE_REG(&adapter->hw, E1000_WUC, wuc); + E1000_WRITE_REG(&adapter->hw, E1000_WUFC, adapter->wol); + +pme: + status = pci_read_config(dev, pmc + PCIR_POWER_STATUS, 2); + status &= ~(PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE); + if (ifp->if_capenable & IFCAP_WOL) + status |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE; + pci_write_config(dev, pmc + PCIR_POWER_STATUS, status, 2); } static void