Users needed to test Wi-Fi stability on Linksys WRT3200ACM & WRT32X on OpenWrt 21.02

These are the changes I'm making:

--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -448,12 +448,12 @@ static void sta_addba_resp_timer_expired(struct timer_list *t)
        ieee80211_stop_tx_ba_session(&sta->sta, tid);
 }

-static void ieee80211_send_addba_with_timeout(struct sta_info *sta,
-                                             struct tid_ampdu_tx *tid_tx)
+static void ieee80211_send_addba_with_timeout(struct sta_info *sta, int tid,
+                                             struct tid_ampdu_tx *tid_tx,
+                                             u16 ssn)
 {
        struct ieee80211_sub_if_data *sdata = sta->sdata;
        struct ieee80211_local *local = sta->local;
-       u8 tid = tid_tx->tid;
        u16 buf_size;

        /* activate the timer for the recipient's addBA response */
@@ -478,10 +478,15 @@ static void ieee80211_send_addba_with_timeout(struct sta_info *sta,
                buf_size = IEEE80211_MAX_AMPDU_BUF_HT;
        }

+       if (tid != tid_tx->tid)
+               pr_warn_ratelimited("ieee80211_send_addba_with_timeout: mismatch tid=%dr, tid_tx->tid=%d\n",
+                                   tid, tid_tx->tid);
+       if (ssn != sta->tid_seq[tid])
+               pr_warn_ratelimited("ieee80211_send_addba_with_timeout: mismatch ssn=%dr, sta->tid_seq[tid] >> 4=%d\n",
+                                   ssn, sta->tid_seq[tid] >> 4);
        /* send AddBA request */
        ieee80211_send_addba_request(sdata, sta->sta.addr, tid,
-                                    tid_tx->dialog_token,
-                                    sta->tid_seq[tid] >> 4,
+                                    tid_tx->dialog_token, ssn,
                                     buf_size, tid_tx->timeout);
 }

@@ -544,7 +549,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
                return;
        }

-       ieee80211_send_addba_with_timeout(sta, tid_tx);
+       ieee80211_send_addba_with_timeout(sta, tid, tid_tx, params.ssn);
 }

 /*

There are two changes in the offending commit that caught my attention: two parameters to the ieee80211_send_addba_request() call:
the ssn (session number?) was changed from params.ssn to sta->tid_seq[tid] >> 4. While the initial value of params.ssn was indeed sta->tid_seq[tid] >> 4, the very next line makes a call to
ret = drv_ampdu_action(local, sdata, &params) that may have changed params.ssn. I haven't studied the way this works at all, but found a candidate for change in mac80211.c in mwlwifi that appears to do it.

The tid change is less likely to have caused it, but the changes assumes that the tid parameter passed to ieee80211_tx_ba_session_handle_start() has the same value of tid_tx->tid. tid_tx is taken from rcu_dereference_protected_tid_tx(sta, tid). I have almost zero knowledge of these parts of the kernel, so I may be shooting at the wrong target.

Anyway, I've added code to log a warning if the values of the parameters don't match. If the warning show up, then we know where the problem with this change is.

3 Likes