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. */