Make iwn(4) put the correct traffic identifier (TID) into the Tx command
when sending block ack request (BAR) frames.

This is not critical but occasionally I have seen the firmware send a
BAR frame with a bogus TID value, which the receiver will simply discard.
Writing the correct TID into the Tx command seems to fix this.

The bogus value was always 8, which matches IWN_NONQOS_TID and is the
default value for the variable 'tid' seen in the diff below; 'tid' will
be copied to the Tx command later. 
 
diff 807e4f4b605ac66e215f436cbcf9b39590b82cab 
0eca04344da7ad4deb76485dcef00cdf88803be4
blob - 2a1f1c261914ed847c02c9e9f39d9acb1dabbd0e
blob + 14c2d9a35e2973feb1ec2347eeef3d6041864291
--- sys/dev/pci/if_iwn.c
+++ sys/dev/pci/if_iwn.c
@@ -3422,8 +3422,17 @@ iwn_tx(struct iwn_softc *sc, struct mbuf *m, struct ie
                        flags |= IWN_TX_NEED_ACK;
        }
        if (type == IEEE80211_FC0_TYPE_CTL &&
-           subtype == IEEE80211_FC0_SUBTYPE_BAR)
+           subtype == IEEE80211_FC0_SUBTYPE_BAR) {
+               struct ieee80211_frame_min *mwh;
+               uint8_t *barfrm;
+               uint16_t ctl;
+               mwh = mtod(m, struct ieee80211_frame_min *);
+               barfrm = (uint8_t *)&mwh[1];
+               ctl = LE_READ_2(barfrm);
+               tid = (ctl & IEEE80211_BA_TID_INFO_MASK) >>
+                   IEEE80211_BA_TID_INFO_SHIFT;
                flags |= (IWN_TX_NEED_ACK | IWN_TX_IMM_BA);
+       }
 
        if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
                flags |= IWN_TX_MORE_FRAG;      /* Cannot happen yet. */

Reply via email to