Since my recent commit to fix Tx reporting in iwn(4) I have observed a
continously rising CCMP decryption error counter in 'netstat -W athn0'
while running tcpbench from iwn(4) towards an athn(4) hostap.

Eventually iwn(4) will send a frame which pushes the CCMP packet number
(a nonce used to detect replays) upwards way out of range, with subsequent
frames having incrementing packet numbers in the expected range again.
Then the link gets stuck since every subsequent CCMP encrypted frame is
discarded by the AP as a replay based on its packet number.

Note that iwn(4) hands off CCMP encryption to hardware.

This diff seems to fix the problem. The ccmp error counter on the AP now
remains at zero. It seems iwn firmware doesn't like it if we reset the
Tx scheduler slot for a frame which is still within the firmware's
block ack window, even if the frame has already been ACKed.
So frames now get cleared off the Tx queue only when the block ack window
has moved past them, which is good enough.

ok?

diff a41d2ed2e84e5db614fcd9a9fdc2f9168577d88c /usr/src
blob - 1751328768da8596f73e42dd81d88482a1fcc13d
file + sys/dev/pci/if_iwn.c
--- sys/dev/pci/if_iwn.c
+++ sys/dev/pci/if_iwn.c
@@ -2259,7 +2259,6 @@ void
 iwn_rx_compressed_ba(struct iwn_softc *sc, struct iwn_rx_desc *desc,
     struct iwn_rx_data *data)
 {
-       struct iwn_ops *ops = &sc->ops;
        struct iwn_compressed_ba *cba = (struct iwn_compressed_ba *)(desc + 1);
        struct ieee80211com *ic = &sc->sc_ic;
        struct ieee80211_node *ni;
@@ -2322,9 +2321,9 @@ iwn_rx_compressed_ba(struct iwn_softc *sc, struct iwn_
                idx = IWN_AGG_SSN_TO_TXQ_IDX(ssn);
                while (nsent && idx != end_idx) {
                        struct iwn_tx_data *txdata = &txq->data[idx];
-                       int have_ack = (le64toh(cba->bitmap) & (1 << bit++));
+                       int have_ack = (le64toh(cba->bitmap) & (1 << bit));
 
-                       if (txdata->m != NULL) {
+                       if ((ba->ba_bitmap & (1 << bit)) == 0) {
                                /*
                                 * Don't report frames to MiRA which were sent
                                 * at a different Tx rate than ni->ni_txmcs.
@@ -2339,18 +2338,15 @@ iwn_rx_compressed_ba(struct iwn_softc *sc, struct iwn_
                                        if (!have_ack || txdata->txfail > 0)
                                                wn->mn.txfail++;
                                }
-                               if (have_ack) {
+                               if (have_ack)
                                        ieee80211_output_ba_record_ack(ic,
                                            ni, cba->tid, ssn);
-                                       ops->reset_sched(sc, qid, idx);
-                                       iwn_tx_done_free_txdata(sc, txdata);
-                                       txq->queued--;
-                               }
                        }
 
                        idx = (idx + 1) % IWN_TX_RING_COUNT;
                        ssn = (ssn + 1) % 0xfff;
                        nsent--;
+                       bit++;
                }
 
                if (wn->mn.ampdu_size > 0)

Reply via email to