Fix Tx queue flushing in iwm(4).
authorstsp <stsp@openbsd.org>
Wed, 30 Jun 2021 09:45:47 +0000 (09:45 +0000)
committerstsp <stsp@openbsd.org>
Wed, 30 Jun 2021 09:45:47 +0000 (09:45 +0000)
iwm(4) was still using an outdated version of the TX_FLUSH command.
Current firmware expects a different version which has the same size but
different semantics. The iwx(4) driver is already using the new version.

Also do not log errors if flushing Tx queues fails. This can happen if
the AP disappeared. Just cope by resetting the device and clearing rings.

Should fix "flushing Tx queues failed" and related firmware errors.

sys/dev/pci/if_iwm.c
sys/dev/pci/if_iwmreg.h

index 9f46f25..a3bf3f8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_iwm.c,v 1.332 2021/06/30 09:44:56 stsp Exp $       */
+/*     $OpenBSD: if_iwm.c,v 1.333 2021/06/30 09:45:47 stsp Exp $       */
 
 /*
  * Copyright (c) 2014, 2016 genua gmbh <info@genua.de>
@@ -6428,8 +6428,8 @@ int
 iwm_flush_tx_path(struct iwm_softc *sc, int tfd_queue_msk)
 {
        struct iwm_tx_path_flush_cmd flush_cmd = {
-               .queues_ctl = htole32(tfd_queue_msk),
-               .flush_ctl = htole16(IWM_DUMP_TX_FIFO_FLUSH),
+               .sta_id = htole32(IWM_STATION_ID),
+               .tid_mask = htole16(0xffff),
        };
        int err;
 
@@ -6859,15 +6859,14 @@ iwm_flush_sta(struct iwm_softc *sc, struct iwm_node *in)
                goto done;
        }
 
+       /*
+        * Flushing Tx rings may fail if the AP has disappeared.
+        * We can rely on iwm_newstate_task() to reset everything and begin
+        * scanning again if we are left with outstanding frames on queues.
+        */
        err = iwm_wait_tx_queues_empty(sc);
-       if (err) {
-               printf("%s: Could not empty Tx queues (error %d)\n",
-                   DEVNAME(sc), err);
-#if 1
-               iwm_dump_driver_status(sc);
-#endif
+       if (err)
                goto done;
-       }
 
        err = iwm_drain_sta(sc, in, 0);
 done:
index 77a8614..a506216 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_iwmreg.h,v 1.52 2021/06/01 18:03:56 stsp Exp $     */
+/*     $OpenBSD: if_iwmreg.h,v 1.53 2021/06/30 09:45:47 stsp Exp $     */
 
 /******************************************************************************
  *
@@ -5009,12 +5009,24 @@ struct iwm_beacon_notif {
  * @flush_ctl: control flags
  * @reserved: reserved
  */
-struct iwm_tx_path_flush_cmd {
+struct iwm_tx_path_flush_cmd_v1 {
        uint32_t queues_ctl;
        uint16_t flush_ctl;
        uint16_t reserved;
 } __packed; /* IWM_TX_PATH_FLUSH_CMD_API_S_VER_1 */
 
+/**
+ * struct iwl_tx_path_flush_cmd -- queue/FIFO flush command
+ * @sta_id: station ID to flush
+ * @tid_mask: TID mask to flush
+ * @reserved: reserved
+ */
+struct iwm_tx_path_flush_cmd {
+       uint32_t sta_id;
+       uint16_t tid_mask;
+       uint16_t reserved;
+} __packed; /* TX_PATH_FLUSH_CMD_API_S_VER_2 */
+
 /**
  * iwm_get_scd_ssn - returns the SSN of the SCD
  * @tx_resp: the Tx response from the fw (agg or non-agg)