Download raw body.
sys/qwz: shutdown firmware after autoconf
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
> 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
>
sys/qwz: shutdown firmware after autoconf