The sequence numbers for QoS data frames sent with Tx aggregation
are implicitly initialized to 0 when the system boots. From then on
the counters will simply keep incrementing with a wrap after 0xfff.

This isn't a problem with iwn(4) or iwm(4) because we always send the
current value in 'add block ack' (ADDBA) request frames generated by
net80211. And there is no requirement for the sequence to begin at zero.

However, iwx(4) will generate ADDBA frames in firmware, and such frames
will use the firmware's internal sequence number counter. Once a block ack
agreement has been established any corresponding data frames will be stamped
with the kernel's idea of the sequence number.

The first time we connect after rebooting the values used by firmware and
the kernel will match. Once we disconnect and connect to another network,
the firmware's counters are reset to zero as part of resetting the device.
But the kernel's counters (in the ni->ni_qos_txseqs[] array) won't be reset.

This seems to be the reason for 'SYSASSERT 0x00001096' errors seen with
my iwx Tx aggregation patch. I realized this because I found a hint that
error code 0x1096 is related to sequence numbers, see here:
https://patchwork.kernel.org/project/linux-wireless/patch/iwlwifi.20210122144849.fe927ec939c6.I103d3321fb55da7e6c6c51582cfadf94eb8b6c58@changeid/
(FYI, I have already sent a couple of such error codes to Linux developers
who work at Intel and asked for help with interpreting them. I never received
a response. If anyone out there has information about how to interpret these
magic numbers it would help to speed up my progress on our drivers.)

The patch below resets the counter to the start of the Tx BA window when a
new block ack agreement is established. This in turn will allow the iwx
driver to initialize the sequence number such that it corresponds to what
the firmware expects (not shown here; this will become part of my Tx agg
support patch for the driver). With these changes I have so far failed to
trigger SYSASSERT 0x00001096 on iwx with Tx agg enabled.

Note that ba->ba_winstart is set to ni->ni_qos_txseqs[tid] when a new Tx
agg agreement is initiated in ieee80211_node_addba_request(). So unless the
driver resets ba->ba_winstart before ieee80211_addba_resp_accept() runs,
which is what iwx will do, the assignment added with this patch is a no-op.

ok?

diff 3254fd38d6813d6bbc6bd56d7c2828c85827b086 /usr/src
blob - e66a661a1a4bf99439d79b76e7e116f070e3b97b
file + sys/net80211/ieee80211_input.c
--- sys/net80211/ieee80211_input.c
+++ sys/net80211/ieee80211_input.c
@@ -3018,6 +3018,8 @@ ieee80211_addba_resp_accept(struct ieee80211com *ic,
        /* Reset ADDBA request interval. */
        ni->ni_addba_req_intval[tid] = 1;
 
+       ni->ni_qos_txseqs[tid] = ba->ba_winstart;
+
        /* start Block Ack inactivity timeout */
        if (ba->ba_timeout_val != 0)
                timeout_add_usec(&ba->ba_to, ba->ba_timeout_val);

Reply via email to