Index | Thread | Search

From:
Stefan Sperling <stsp@stsp.name>
Subject:
qwx(4) suspend/hibernate + resume
To:
tech@openbsd.org
Date:
Wed, 21 Feb 2024 16:13:21 +0100

Download raw body.

Thread
This patch adds suspend/hibernate + resume support to qwx(4).

Without this patch, upon resume the qwx0 interface remains apparently
associated to the previous AP (as displayed by ifconfig) but no traffic
will pass until the user runs: ifconfig qwx0 down up

With this patch, the qwx0 interface begins scanning for APs upon resume
without requiring user interaction.

On the Z13 I can only test hibernate, which works as expected.
Could someone test suspend, e.g. on the X13s? Thanks!

diff 5d222591396a4298c24273941b8f06dafeb24bf3 6dc955176d769c398ad467a99b6434d9c54d57b8
commit - 5d222591396a4298c24273941b8f06dafeb24bf3
commit + 6dc955176d769c398ad467a99b6434d9c54d57b8
blob - 66827a4458b4ce35d2d14d38e770482959311866
blob + b1c0c1a5f3627951ac086c6d403fbbd57d8f8b1b
--- sys/dev/ic/qwx.c
+++ sys/dev/ic/qwx.c
@@ -24762,3 +24762,33 @@ qwx_dmamem_free(bus_dma_tag_t dmat, struct qwx_dmamem 
 	bus_dmamap_destroy(dmat, adm->map);
 	free(adm, M_DEVBUF, sizeof(*adm));
 }
+
+int
+qwx_activate(struct device *self, int act)
+{
+	struct qwx_softc *sc = (struct qwx_softc *)self;
+	struct ifnet *ifp = &sc->sc_ic.ic_if;
+	int err = 0;
+
+	switch (act) {
+	case DVACT_QUIESCE:
+		if (ifp->if_flags & IFF_RUNNING) {
+			rw_enter_write(&sc->ioctl_rwl);
+			qwx_stop(ifp);
+			rw_exit(&sc->ioctl_rwl);
+		}
+		break;
+	case DVACT_RESUME:
+		break;
+	case DVACT_WAKEUP:
+		if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == IFF_UP) {
+			err = qwx_init(ifp);
+			if (err)
+				printf("%s: could not initialize hardware\n",
+				    sc->sc_dev.dv_xname);
+		}
+		break;
+	}
+
+	return 0;
+}
blob - 6d81b9cf6b0ddbe8e67fb0d78d6b4cd4b7944dac
blob + f7f429fa27e3fc5f63cb9345a9e90f46d5fbf15d
--- sys/dev/ic/qwxvar.h
+++ sys/dev/ic/qwxvar.h
@@ -1901,6 +1901,7 @@ int	qwx_dp_service_srng(struct qwx_softc *, int);
 int	qwx_init_hw_params(struct qwx_softc *);
 int	qwx_attach(struct qwx_softc *);
 void	qwx_detach(struct qwx_softc *);
+int	qwx_activate(struct device *, int);
 
 void	qwx_core_deinit(struct qwx_softc *);
 void	qwx_ce_cleanup_pipes(struct qwx_softc *);
blob - 05cab4d0fc248d6c48d48ac9aad36fa6aa30c328
blob + 9fd14232402e064ea2c520f63ba8d6afd0b36431
--- sys/dev/pci/if_qwx_pci.c
+++ sys/dev/pci/if_qwx_pci.c
@@ -402,7 +402,6 @@ int	qwx_pci_match(struct device *, void *, void *);
 void	qwx_pci_attach(struct device *, struct device *, void *);
 int	qwx_pci_detach(struct device *, int);
 void	qwx_pci_attach_hook(struct device *);
-int	qwx_pci_activate(struct device *, int);
 void	qwx_pci_free_xfer_rings(struct qwx_pci_softc *);
 int	qwx_pci_alloc_xfer_ring(struct qwx_softc *, struct qwx_pci_xfer_ring *,
 	    uint32_t, uint32_t, uint32_t, size_t);
@@ -526,7 +525,7 @@ const struct cfattach qwx_pci_ca = {
 	qwx_pci_match,
 	qwx_pci_attach,
 	qwx_pci_detach,
-	qwx_pci_activate
+	qwx_activate
 };
 
 /* XXX pcidev */
@@ -1204,19 +1203,6 @@ qwx_pci_attach_hook(struct device *self)
 	splx(s);
 }
 
-int
-qwx_pci_activate(struct device *self, int act)
-{
-	switch (act) {
-	case DVACT_SUSPEND:
-		break;
-	case DVACT_WAKEUP:
-		break;
-	}
-
-	return 0;
-}
-
 void
 qwx_pci_free_xfer_rings(struct qwx_pci_softc *psc)
 {