diff --git a/sys/dev/bwi/if_bwi.c b/sys/dev/bwi/if_bwi.c --- a/sys/dev/bwi/if_bwi.c +++ b/sys/dev/bwi/if_bwi.c @@ -1364,7 +1364,6 @@ (m = mbufq_dequeue(&sc->sc_snd)) != NULL) { ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; wh = mtod(m, struct ieee80211_frame *); - ieee80211_output_seqno_assign(ni, -1, m); if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) != 0 && ieee80211_crypto_encap(ni, m) == NULL) { if_inc_counter(ni->ni_vap->iv_ifp, @@ -2903,6 +2902,12 @@ panic("unsupported modulation type %u\n", modtype); } +/* + * @brief Encapsulate a frame for transmit. + * + * Note that this must be called inside the same lock / path + * as the crypto encap call in the transmit path. + */ static int bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m, struct ieee80211_node *ni) @@ -2937,6 +2942,12 @@ /* Get 802.11 frame len before prepending TX header */ pkt_len = m->m_pkthdr.len + IEEE80211_CRC_LEN; + /* + * Assign sequence number - must be done in lock-step with + * cipher encap. + */ + ieee80211_output_seqno_assign(ni, -1, m); + /* * Find TX rate */ @@ -3117,6 +3128,9 @@ /* Get 802.11 frame len before prepending TX header */ pkt_len = m->m_pkthdr.len + IEEE80211_CRC_LEN; + /* Assign sequence number. */ + ieee80211_output_seqno_assign(ni, -1, m); + /* * Find TX rate */ diff --git a/sys/dev/bwn/if_bwn.c b/sys/dev/bwn/if_bwn.c --- a/sys/dev/bwn/if_bwn.c +++ b/sys/dev/bwn/if_bwn.c @@ -1000,7 +1000,6 @@ continue; } wh = mtod(m, struct ieee80211_frame *); - ieee80211_output_seqno_assign(ni, -1, m); if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { k = ieee80211_crypto_encap(ni, m); if (k == NULL) { @@ -1053,6 +1052,12 @@ return (1); } +/* + * @brief Queue the give frame for transmit. + * + * This must be called in the same lock/path as the crypto encap call + * to avoid reordering issues. + */ static int bwn_tx_start(struct bwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m) { @@ -1066,6 +1071,8 @@ return (ENXIO); } + ieee80211_output_seqno_assign(ni, -1, m); + error = (mac->mac_flags & BWN_MAC_FLAG_DMA) ? bwn_dma_tx_start(mac, ni, &m) : bwn_pio_tx_start(mac, ni, &m); if (error) { diff --git a/sys/dev/ral/rt2560.c b/sys/dev/ral/rt2560.c --- a/sys/dev/ral/rt2560.c +++ b/sys/dev/ral/rt2560.c @@ -1675,6 +1675,8 @@ flags |= RT2560_TX_LONG_RETRY | RT2560_TX_IFS_SIFS; } + ieee80211_output_seqno_assign(ni, -1, m0); + error = bus_dmamap_load_mbuf_sg(sc->prioq.data_dmat, data->map, m0, segs, &nsegs, 0); if (error != 0) { diff --git a/sys/dev/ral/rt2860.c b/sys/dev/ral/rt2860.c --- a/sys/dev/ral/rt2860.c +++ b/sys/dev/ral/rt2860.c @@ -1755,6 +1755,8 @@ return EINVAL; } + ieee80211_output_seqno_assign(ni, -1, m); + qid = params->ibp_pri & 3; ring = &sc->txq[qid]; diff --git a/sys/dev/usb/wlan/if_ural.c b/sys/dev/usb/wlan/if_ural.c --- a/sys/dev/usb/wlan/if_ural.c +++ b/sys/dev/usb/wlan/if_ural.c @@ -1189,6 +1189,8 @@ STAILQ_REMOVE_HEAD(&sc->tx_free, next); sc->tx_nfree--; + ieee80211_output_seqno_assign(ni, -1, m0); + data->m = m0; data->ni = ni; data->rate = rate;