When moving from AUTH state to INIT or SCAN state the iwx(4) driver performs the following two steps:
1. Remove the formerly chosen access point from the firmware's station table 2. Flush firmware Tx queues This order of operations was inherited from iwm(4) where it works fine. But iwx(4) firmware has changed how the flushing step works. Flushing the Tx path now depends on the station being present in the firmware's station table. So the driver should flush the Tx path before removing the station. Otherwise, we get a fatal firmware error when the driver moves out of AUTH state. I came across this bug while testing unrelated changes. Perhaps it's been triggered in the wild, perhaps not. There are worse problems in this driver which I haven't figured out yet. But this one was easy to figure out and fix. ok? diff 17409ae76a1a51c4975a1efea612708ad984b8df 087785340de686b7a85b51f5f1137690e3b88c2f blob - dd72733d9028d10a3e8dfdce7f1211c72475843f blob + 7a9e711abbc6814dfbc2bafc8c72ed8244f53d57 --- sys/dev/pci/if_iwx.c +++ sys/dev/pci/if_iwx.c @@ -5681,6 +5681,12 @@ iwx_deauth(struct iwx_softc *sc) iwx_unprotect_session(sc, in); if (sc->sc_flags & IWX_FLAG_STA_ACTIVE) { + err = iwx_flush_tx_path(sc); + if (err) { + printf("%s: could not flush Tx path (error %d)\n", + DEVNAME(sc), err); + return err; + } err = iwx_rm_sta_cmd(sc, in); if (err) { printf("%s: could not remove STA (error %d)\n", @@ -5688,13 +5694,6 @@ iwx_deauth(struct iwx_softc *sc) return err; } sc->sc_flags &= ~IWX_FLAG_STA_ACTIVE; - } - - err = iwx_flush_tx_path(sc); - if (err) { - printf("%s: could not flush Tx path (error %d)\n", - DEVNAME(sc), err); - return err; } if (sc->sc_flags & IWX_FLAG_BINDING_ACTIVE) {