Re: sys/qwz: shutdown firmware after autoconf

Kirill A. Korinsky <[email protected]>
Newsgroups gmane.os.openbsd.tech
Message-ID <[email protected]>
On Mon, 01 Jun 2026 22:27:27 +0200,
Marcus Glocker <[email protected]> wrote:
> 
> On Mon, Jun 01, 2026 at 09:50:48PM +0200, Kirill A. Korinsky wrote:
> 
> > tech@,
> > 
> > seems that I had figured out why we need a hack to keep qwz running after
> > autoconf.
> > 
> > So, here I reset pending MHI transfers and the command ring queue counter
> > during shutdown, and remove fw_initialized so the next ifconfig up performs
> > a full firmware boot.
> > 
> > Thoughts? Ok?
> 
> I just gave it a quick spin, but it re-introduces the issue I faced
> before on a NWID switch attempt:
> 
> ifconfig: SIOCS80211NWID: Resource temporarily unavailable
> ifconfig: qwz0: SIOCS80211WPAPSK: Resource temporarily unavailable
> 
> ***
> 
> qwz0: tx credits timeout
> qwz0: failed to send WMI_PDEV_SET_PARAM cmd
> qwz0: failed to enable MESH MCAST ENABLE for pdev 0: 35
> qwz0: tx credits timeout
> qwz0: failed to send WMI_PDEV_SET_PARAM cmd
> qwz0: failed to enable MESH MCAST ENABLE for pdev 0: 35
> qwz0: tx credits timeout
> qwz0: failed to send WMI_PDEV_SET_PARAM cmd
> qwz0: failed to enable MESH MCAST ENABLE for pdev 0: 35
> qwz0: tx credits timeout
> qwz0: failed to send WMI_PDEV_SET_PARAM cmd
> qwz0: failed to enable MESH MCAST ENABLE for pdev 0: 35
>

Does switch from NWID/AP really work on your device?

On my machine I can connect only to one AP per boot. Anything else is ended
with "Resource temporarily unavailable"

> > Index: sys/dev/ic/qwz.c
> > ===================================================================
> > RCS file: /home/cvs/src/sys/dev/ic/qwz.c,v
> > diff -u -p -r1.38 qwz.c
> > --- sys/dev/ic/qwz.c	26 May 2026 14:55:16 -0000	1.38
> > +++ sys/dev/ic/qwz.c	1 Jun 2026 19:26:04 -0000
> > @@ -159,6 +159,7 @@ int qwz_wmi_vdev_install_key(struct qwz_
> >  int qwz_dp_peer_rx_pn_replay_config(struct qwz_softc *, struct qwz_vif *,
> >      struct ieee80211_node *, struct ieee80211_key *, int);
> >  void qwz_setkey_clear(struct qwz_softc *);
> > +void qwz_vif_free_all(struct qwz_softc *);
> >  
> >  int qwz_scan(struct qwz_softc *);
> >  void qwz_scan_abort(struct qwz_softc *);
> > @@ -185,20 +186,6 @@ qwz_init(struct ifnet *ifp)
> >  	struct qwz_softc *sc = ifp->if_softc;
> >  	struct ieee80211com *ic = &sc->sc_ic;
> >  
> > -	/* Firmware stays running across ifconfig down/up; only re-scan. */
> > -	if (sc->fw_initialized) {
> > -		ic->ic_state = IEEE80211_S_INIT;
> > -		sc->ns_nstate = IEEE80211_S_INIT;
> > -		sc->scan.state = ATH12K_SCAN_IDLE;
> > -		if (ifp->if_flags & IFF_UP) {
> > -			refcnt_init(&sc->task_refs);
> > -			ifq_clr_oactive(&ifp->if_snd);
> > -			ifp->if_flags |= IFF_RUNNING;
> > -			ieee80211_begin_scan(ifp);
> > -		}
> > -		return 0;
> > -	}
> > -
> >  	sc->fw_mode = ATH12K_FIRMWARE_MODE_NORMAL;
> >  	/*
> >  	 * There are several known hardware/software crypto issues
> > @@ -300,7 +287,6 @@ qwz_init(struct ifnet *ifp)
> >  		ieee80211_begin_scan(ifp);
> >  	}
> >  
> > -	sc->fw_initialized = 1;
> >  	return 0;
> >  }
> >  
> > @@ -370,12 +356,10 @@ qwz_stop(struct ifnet *ifp)
> >  	sc->scan.state = ATH12K_SCAN_IDLE;
> >  	sc->vdev_id_11d_scan = QWZ_11D_INVALID_VDEV_ID;
> >  
> > -	/*
> > -	 * Firmware stays running across ifconfig down/up; the chip is
> > -	 * only released on driver detach.  Do not clear pdevs_active
> > -	 * or call qwz_core_deinit() here.
> > -	 */
> > +	sc->pdevs_active = 0;
> >  
> > +	qwz_core_deinit(sc);
> > +	qwz_vif_free_all(sc);
> >  	splx(s);
> >  }
> >  
> > @@ -18703,8 +18687,6 @@ qwz_core_deinit(struct qwz_softc *sc)
> >  
> >  	hal->num_shadow_reg_configured = 0;
> >  
> > -	sc->fw_initialized = 0;
> > -
> >  	splx(s);
> >  }
> >  
> > @@ -21787,6 +21769,18 @@ qwz_vif_free(struct qwz_softc *sc, struc
> >  	}
> >  
> >  	free(arvif, M_DEVBUF, sizeof(*arvif));
> > +}
> > +
> > +void
> > +qwz_vif_free_all(struct qwz_softc *sc)
> > +{
> > +	struct qwz_vif *arvif;
> > +
> > +	while (!TAILQ_EMPTY(&sc->vif_list)) {
> > +		arvif = TAILQ_FIRST(&sc->vif_list);
> > +		TAILQ_REMOVE(&sc->vif_list, arvif, entry);
> > +		qwz_vif_free(sc, arvif);
> > +	}
> >  }
> >  
> >  struct qwz_vif *
> > Index: sys/dev/ic/qwzvar.h
> > ===================================================================
> > RCS file: /home/cvs/src/sys/dev/ic/qwzvar.h,v
> > diff -u -p -r1.18 qwzvar.h
> > --- sys/dev/ic/qwzvar.h	26 May 2026 14:55:16 -0000	1.18
> > +++ sys/dev/ic/qwzvar.h	1 Jun 2026 19:26:14 -0000
> > @@ -1971,7 +1971,6 @@ struct qwz_softc {
> >  	struct qwz_survey_info	survey[IEEE80211_CHAN_MAX];
> >  
> >  	int			attached;
> > -	int			fw_initialized;
> >  	struct {
> >  		u_char *data;
> >  		size_t size;
> > Index: sys/dev/pci/if_qwz_pci.c
> > ===================================================================
> > RCS file: /home/cvs/src/sys/dev/pci/if_qwz_pci.c,v
> > diff -u -p -r1.13 if_qwz_pci.c
> > --- sys/dev/pci/if_qwz_pci.c	26 May 2026 14:55:16 -0000	1.13
> > +++ sys/dev/pci/if_qwz_pci.c	1 Jun 2026 19:30:15 -0000
> > @@ -430,6 +430,7 @@ void	qwz_mhi_init_xfer_rings(struct qwz_
> >  void	qwz_mhi_init_event_rings(struct qwz_pci_softc *);
> >  void	qwz_mhi_init_cmd_ring(struct qwz_pci_softc *);
> >  void	qwz_mhi_init_dev_ctxt(struct qwz_pci_softc *);
> > +void	qwz_mhi_reset_xfer_rings(struct qwz_pci_softc *);
> >  int	qwz_mhi_send_cmd(struct qwz_pci_softc *psc, uint32_t, uint32_t);
> >  void *	qwz_pci_xfer_ring_get_elem(struct qwz_pci_xfer_ring *, uint64_t);
> >  struct qwz_xfer_data *qwz_pci_xfer_ring_get_data(struct qwz_pci_xfer_ring *,
> > @@ -2445,6 +2446,7 @@ qwz_mhi_init_cmd_ring(struct qwz_pci_sof
> >  	len = ring->size;
> >  
> >  	ring->rp = ring->wp = paddr;
> > +	ring->queued = 0;
> >  
> >  	c = (struct qwz_mhi_cmd_ctxt *)QWZ_DMA_KVA(psc->cmd_ctxt);
> >  	c->rbase = htole64(paddr);
> > @@ -2464,6 +2466,58 @@ qwz_mhi_init_dev_ctxt(struct qwz_pci_sof
> >  	qwz_mhi_init_cmd_ring(psc);
> >  }
> >  
> > +void
> > +qwz_mhi_reset_xfer_rings(struct qwz_pci_softc *psc)
> > +{
> > +	struct qwz_softc *sc = &psc->sc_sc;
> > +	struct qwz_pci_xfer_ring *ring;
> > +	struct qwz_xfer_data *xfer;
> > +	uint64_t paddr;
> > +	int i, j;
> > +
> > +	for (i = 0; i < nitems(psc->xfer_rings); i++) {
> > +		ring = &psc->xfer_rings[i];
> > +		if (ring->dmamem == NULL)
> > +			continue;
> > +
> > +		for (j = 0; j < ring->num_elements; j++) {
> > +			xfer = &ring->data[j];
> > +			if (ring->mhi_chan_direction == MHI_CHAN_TYPE_OUTBOUND) {
> > +				if (xfer->m == NULL)
> > +					continue;
> > +				bus_dmamap_sync(sc->sc_dmat, xfer->map, 0,
> > +				    xfer->map->dm_mapsize,
> > +				    BUS_DMASYNC_POSTWRITE);
> > +				bus_dmamap_unload(sc->sc_dmat, xfer->map);
> > +				m_freem(xfer->m);
> > +				xfer->m = NULL;
> > +			} else if (xfer->m != NULL) {
> > +				bus_dmamap_sync(sc->sc_dmat, xfer->map, 0,
> > +				    QWZ_PCI_XFER_MAX_DATA_SIZE,
> > +				    BUS_DMASYNC_POSTREAD);
> > +				xfer->m->m_len = xfer->m->m_pkthdr.len =
> > +				    QWZ_PCI_XFER_MAX_DATA_SIZE;
> > +				bus_dmamap_sync(sc->sc_dmat, xfer->map, 0,
> > +				    QWZ_PCI_XFER_MAX_DATA_SIZE,
> > +				    BUS_DMASYNC_PREREAD);
> > +			}
> > +		}
> > +
> > +		paddr = QWZ_DMA_DVA(ring->dmamem);
> > +		ring->rp = ring->wp = paddr;
> > +		ring->queued = 0;
> > +		ring->cmd_status = MHI_EV_CC_INVALID;
> > +		if (ring->chan_ctxt != NULL) {
> > +			ring->chan_ctxt->rp = htole64(paddr);
> > +			ring->chan_ctxt->wp = htole64(paddr);
> > +		}
> > +	}
> > +
> > +	if (psc->chan_ctxt != NULL)
> > +		bus_dmamap_sync(sc->sc_dmat, QWZ_DMA_MAP(psc->chan_ctxt), 0,
> > +		    QWZ_DMA_LEN(psc->chan_ctxt), BUS_DMASYNC_PREWRITE);
> > +}
> > +
> >  void *
> >  qwz_pci_cmd_ring_get_elem(struct qwz_pci_cmd_ring *ring, uint64_t ptr)
> >  {
> > @@ -2847,6 +2901,7 @@ void
> >  qwz_mhi_stop(struct qwz_softc *sc)
> >  {
> >  	qwz_mhi_reset_device(sc, 1);
> > +	qwz_mhi_reset_xfer_rings((struct qwz_pci_softc *)sc);
> >  }
> >  
> >  int
> > 
> > 
> > 
> > -- 
> > wbr, Kirill
> > 

-- 
wbr, Kirill
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.