From nobody@FreeBSD.org  Thu Mar 21 10:27:32 2013
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1])
	by hub.freebsd.org (Postfix) with ESMTP id DD4389AF
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 21 Mar 2013 10:27:32 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22])
	by mx1.freebsd.org (Postfix) with ESMTP id CF4BAAAA
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 21 Mar 2013 10:27:32 +0000 (UTC)
Received: from red.freebsd.org (localhost [127.0.0.1])
	by red.freebsd.org (8.14.5/8.14.5) with ESMTP id r2LARWR5087919
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 21 Mar 2013 10:27:32 GMT
	(envelope-from nobody@red.freebsd.org)
Received: (from nobody@localhost)
	by red.freebsd.org (8.14.5/8.14.5/Submit) id r2LARWel087918;
	Thu, 21 Mar 2013 10:27:32 GMT
	(envelope-from nobody)
Message-Id: <201303211027.r2LARWel087918@red.freebsd.org>
Date: Thu, 21 Mar 2013 10:27:32 GMT
From: Hielke Christian Braun <hcb@unco.de>
To: freebsd-gnats-submit@FreeBSD.org
Subject: patch for bge network driver to enable wake on lan
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         177184
>Category:       kern
>Synopsis:       [bge] [patch] enable wake on lan
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-net
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Thu Mar 21 10:30:00 UTC 2013
>Closed-Date:    
>Last-Modified:  Mon Oct 07 16:03:25 UTC 2013
>Originator:     Hielke Christian Braun
>Release:        9.1-RELEASE-p1
>Organization:
>Environment:
FreeBSD xxx 9.1-RELEASE-p1 FreeBSD 9.1-RELEASE-p1 #48: Fri Mar 15 01:09:33 CET 2013     root@freebsd:/usr/obj/nas4free/usr/src/sys/NAS4FREE-amd64  amd64
>Description:
Hello,

a patch to enable wake-on-lan (with magic packet) in the bge network
driver. Maybe you can add it. Developed this for a HP ProLiant MicroServer
N40L machine with a

bge0: <HP NC107i PCIe Gigabit Server Adapter, ASIC rev. 0x5784100> mem 0xfe9f0000-0xfe9fffff irq 18 at device 0.0 on pci2


Kind regards,
Christian. 
>How-To-Repeat:

>Fix:


Patch attached with submission follows:

--- if_bge.c.orig       2013-03-13 23:42:26.000000000 +0100
+++ if_bge.c    2013-03-14 13:30:08.000000000 +0100
@@ -469,6 +469,7 @@
 static void bge_stop_fw(struct bge_softc *);
 static int bge_reset(struct bge_softc *);
 static void bge_link_upd(struct bge_softc *);
+static void bge_setwol(struct bge_softc *);

 /*
  * The BGE_REGISTER_DEBUG option is only for low-level debugging.  It may
@@ -3335,7 +3336,7 @@
        IFQ_SET_READY(&ifp->if_snd);
        ifp->if_hwassist = sc->bge_csum_features;
        ifp->if_capabilities = IFCAP_HWCSUM | IFCAP_VLAN_HWTAGGING |
-           IFCAP_VLAN_MTU;
+           IFCAP_VLAN_MTU | IFCAP_WOL_MAGIC;
        if ((sc->bge_flags & (BGE_FLAG_TSO | BGE_FLAG_TSO3)) != 0) {
                ifp->if_hwassist |= CSUM_TSO;
                ifp->if_capabilities |= IFCAP_TSO4 | IFCAP_VLAN_HWTSO;
@@ -5537,6 +5538,7 @@
        BGE_LOCK(sc);
        bge_stop(sc);
        bge_reset(sc);
+       bge_setwol(sc);
        BGE_UNLOCK(sc);

        return (0);
@@ -6206,3 +6208,34 @@
        }
        return (*func == NULL ? ENXIO : 0);
 }
+
+static void
+bge_setwol(struct bge_softc *sc)
+{
+       struct ifnet *ifp;
+       uint16_t pmstat;
+       int pmc;
+
+       ifp = sc->bge_ifp;
+
+       if ((ifp->if_capenable & IFCAP_WOL_MAGIC) == 0)
+           return;
+
+       if (pci_find_cap(sc->bge_dev, PCIY_PMG, &pmc) != 0)
+           return;
+
+       BGE_SETBIT(sc, BGE_MAC_MODE, BGE_MACMODE_MAGIC_PKT_ENB);
+
+       BGE_CLRBIT(sc, BGE_MAC_MODE, BGE_MACMODE_PORTMODE);
+       BGE_SETBIT(sc, BGE_MAC_MODE, BGE_PORTMODE_GMII);
+
+       BGE_SETBIT(sc, BGE_RX_MODE, BGE_RXMODE_ENABLE);
+
+       /* Request PME. */
+       pmstat = pci_read_config(sc->bge_dev,
+           pmc + PCIR_POWER_STATUS, 2);
+       pmstat |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE;
+       pci_write_config(sc->bge_dev,
+           pmc + PCIR_POWER_STATUS, pmstat, 2);
+}
+

>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-net 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Thu Mar 21 13:25:19 UTC 2013 
Responsible-Changed-Why:  
Over to maintainer(s). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=177184 
Responsible-Changed-From-To: freebsd-net->hiren 
Responsible-Changed-By: hiren 
Responsible-Changed-When: Tue May 7 04:48:09 UTC 2013 
Responsible-Changed-Why:  
Grab. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=177184 

From: hiren panchasara <hiren@FreeBSD.org>
To: bug-followup@FreeBSD.org, hcb@unco.de
Cc:  
Subject: Re: kern/177184: [bge] [patch] enable wake on lan
Date: Mon, 7 Oct 2013 08:59:18 -0700

 This is a bit updated patch from submitter which applied on a few
 months old CURRENT.
 
 Index: sys/dev/bge/if_bge.c
 ===================================================================
 --- sys/dev/bge/if_bge.c (revision 250303)
 +++ sys/dev/bge/if_bge.c (working copy)
 @@ -475,6 +475,7 @@
  static void bge_stop_fw(struct bge_softc *);
  static int bge_reset(struct bge_softc *);
  static void bge_link_upd(struct bge_softc *);
 +static void bge_setwol(struct bge_softc *);
 
  static void bge_ape_lock_init(struct bge_softc *);
  static void bge_ape_read_fw_ver(struct bge_softc *);
 @@ -3663,7 +3664,7 @@
   IFQ_SET_READY(&ifp->if_snd);
   ifp->if_hwassist = sc->bge_csum_features;
   ifp->if_capabilities = IFCAP_HWCSUM | IFCAP_VLAN_HWTAGGING |
 -    IFCAP_VLAN_MTU;
 +    IFCAP_VLAN_MTU | IFCAP_WOL_MAGIC;
   if ((sc->bge_flags & (BGE_FLAG_TSO | BGE_FLAG_TSO3)) != 0) {
   ifp->if_hwassist |= CSUM_TSO;
   ifp->if_capabilities |= IFCAP_TSO4 | IFCAP_VLAN_HWTSO;
 @@ -5914,6 +5915,8 @@
   sc = device_get_softc(dev);
   BGE_LOCK(sc);
   bge_stop(sc);
 + bge_reset(sc);
 + bge_setwol(sc);
   BGE_UNLOCK(sc);
 
   return (0);
 @@ -6612,3 +6615,33 @@
   }
   return (*func == NULL ? ENXIO : 0);
  }
 +
 +static void
 +bge_setwol(struct bge_softc *sc)
 +{
 +       struct ifnet *ifp;
 +       uint16_t pmstat;
 +       int pmc;
 +
 +       ifp = sc->bge_ifp;
 +
 +       if ((ifp->if_capenable & IFCAP_WOL_MAGIC) == 0)
 +           return;
 +
 +       if (pci_find_cap(sc->bge_dev, PCIY_PMG, &pmc) != 0)
 +           return;
 +
 +       BGE_SETBIT(sc, BGE_MAC_MODE, BGE_MACMODE_MAGIC_PKT_ENB);
 +
 +       BGE_CLRBIT(sc, BGE_MAC_MODE, BGE_MACMODE_PORTMODE);
 +       BGE_SETBIT(sc, BGE_MAC_MODE, BGE_PORTMODE_GMII);
 +
 +       BGE_SETBIT(sc, BGE_RX_MODE, BGE_RXMODE_ENABLE);
 +
 +       /* Request PME. */
 +       pmstat = pci_read_config(sc->bge_dev,
 +           pmc + PCIR_POWER_STATUS, 2);
 +       pmstat |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE;
 +       pci_write_config(sc->bge_dev,
 +           pmc + PCIR_POWER_STATUS, pmstat, 2);
 +}
 
 
 According to yongari@:
 "The patch is not enough to cover other high-end controllers. The
 patch may work on consumer grade controllers used on Notebooks but it
 will break advanced controllers with ASF/IPMI firmware as well as
 TBI/Fiber PHY interface. Before adding support for WOL, bge(4) needs a
 reliable way to suspend/resume the controller and should have
 controller firmware know driver state as well as saving/restoring
 reference clock. If suspend/resume does not work its firmware will
 take over controller's functionality programmed by driver and WOL
 wouldn't work as expected.  That part of magic is mostly undocumented
 and different controller requires different procedures."
 
 I guess its much more work than I can handle atm. I will put it back
 to the queue.
 
 Thanks to Pyun for his inputs and my bad for hanging on to this bug for so long.
Responsible-Changed-From-To: hiren->freebsd-net 
Responsible-Changed-By: hiren 
Responsible-Changed-When: Mon Oct 7 16:02:38 UTC 2013 
Responsible-Changed-Why:  


http://www.freebsd.org/cgi/query-pr.cgi?pr=177184 
>Unformatted:
