Long story short: If you can test the diff below on iwn(4) (n, not m),
on a WPA2 network in 11n mode, then please do.


QoS wifi frames are generally used for two different things:
traffic prioritization, and A-MPDU frame aggregation.

Actual QoS is all about traffic prioritization, e.g. for lower latency with
voice over IP, where data frames of different importance get distinct traffic
identifiers (TID) assigned in the QoS frame header. The AP can then tell which
of several frames it might have buffered from us need to be forwarded first.

For some reason A-MPDUs are layered on top of this QoS mechanism to emulate
packet flows. Aggregated frames need a sequence number space that is distinct
from regular individual data frames. The QoS TID acts like a "data stream ID".
This is required because frames may end up arriving out of order if subframes
of aggregates are lost. And the data stream needs to be re-assembled in order.

Our net80211 stack does not make use of traffic prioritization at all.
While actual QoS could be added in the future, for now we only use such frames
for A-MPDU aggregation. However, we already do send individual QoS frames
before an aggregation agreement has been established with the peer!
Getting individual QoS frames sent out was a first step I took when A-MPDU
support was first implemented. This works because our peer is able to receive
QoS frames just fine even while we don't have a aggregation set up yet.
Those frames appear just like actual OoS frames with the TID set to some
arbitrary priority, until aggregation kicks in and the TID changes meaning.

Right now I am working on adding Tx-aggregation to iwm(4). Aggregation can
be arbitrarily switched on and off during an active association and I am
currently looking in detail at that particular problem.

Sending non-aggregated QoS frames does not actually buy us anything and
makes it much harder for me to look at packet captures and tell whether
frames sent by an OpenBSD machine were in fact aggregated or not.
So not using QoS unless aggregation is active helps me with debugging.
Hopefully not just now during development, but also later when analyzing
bug reports.
It should also help in case an AP gets confused about the meaning of the
TID switching back and forth between "QoS priority" and "aggregation".

This diff works fine with my WIP iwm(4) aggregation code, but there is
also the older iwn(4) driver where Tx aggregation is already supported
which needs to be tested.
Since I currently don't have any iwn(4) hardware with me I would appreciate
if someone could test this diff with iwn(4) in 11n mode.
Just checking whether an 11n wifi connection on a WPA2 network still works
is good enough for testing this. Thanks!

diff b4bae439ee6fa70ab214b2e3a790bb4649da93c9 /usr/src
blob - 6880f7fc2d77946b688d907e8be78bac3c029778
file + sys/net80211/ieee80211_output.c
--- sys/net80211/ieee80211_output.c
+++ sys/net80211/ieee80211_output.c
@@ -578,13 +578,12 @@ ieee80211_encap(struct ifnet *ifp, struct mbuf *m, str
                struct ieee80211_tx_ba *ba;
                tid = ieee80211_classify(ic, m);
                ba = &ni->ni_tx_ba[tid];
-               /*
-                * Don't use TID's sequence number space while an ADDBA
-                * request is in progress.
-                */
-               if (ba->ba_state == IEEE80211_BA_REQUESTED) {
+               /* We use QoS data frames for aggregation only. */
+               if (ba->ba_state != IEEE80211_BA_AGREED) {
                        hdrlen = sizeof(struct ieee80211_frame);
                        addqos = 0;
+                       if (ieee80211_can_use_ampdu(ic, ni))
+                               ieee80211_node_trigger_addba_req(ni, tid);
                } else {
                        hdrlen = sizeof(struct ieee80211_qosframe);
                        addqos = 1;
@@ -613,15 +612,13 @@ ieee80211_encap(struct ifnet *ifp, struct mbuf *m, str
                struct ieee80211_qosframe *qwh =
                    (struct ieee80211_qosframe *)wh;
                u_int16_t qos = tid;
-               struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid];
 
                if (ic->ic_tid_noack & (1 << tid))
                        qos |= IEEE80211_QOS_ACK_POLICY_NOACK;
-               else if (ba->ba_state == IEEE80211_BA_AGREED) {
+               else {
                        /* Use HT immediate block-ack. */
                        qos |= IEEE80211_QOS_ACK_POLICY_NORMAL;
-               } else if (ieee80211_can_use_ampdu(ic, ni))
-                       ieee80211_node_trigger_addba_req(ni, tid);
+               }
                qwh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_QOS;
                *(u_int16_t *)qwh->i_qos = htole16(qos);
                *(u_int16_t *)qwh->i_seq =

Reply via email to