diff --git a/sys/dev/bwn/if_bwn.c b/sys/dev/bwn/if_bwn.c index 0e78bc936fea..17865a808ecd 100644 --- a/sys/dev/bwn/if_bwn.c +++ b/sys/dev/bwn/if_bwn.c @@ -6401,15 +6401,14 @@ bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni, struct bwn_softc *sc = mac->mac_sc; struct ieee80211_frame *wh; struct ieee80211_frame *protwh; - struct ieee80211_frame_cts *cts; - struct ieee80211_frame_rts *rts; const struct ieee80211_txparam *tp = ni->ni_txparms; struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = &sc->sc_ic; struct mbuf *mprot; + uint8_t *prot_ptr; unsigned int len; uint32_t macctl = 0; - int protdur, rts_rate, rts_rate_fb, ismcast, isshort, rix, type; + int rts_rate, rts_rate_fb, ismcast, isshort, rix, type; uint16_t phyctl = 0; uint8_t rate, rate_fb; int fill_phy_ctl1 = 0; @@ -6528,7 +6527,8 @@ bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni, m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) macctl |= BWN_TX_MAC_LONGFRAME; - if (ic->ic_flags & IEEE80211_F_USEPROT) { + if ((ic->ic_flags & IEEE80211_F_USEPROT) && + ic->ic_protmode != IEEE80211_PROT_NONE) { /* Note: don't fall back to CCK rates for 5G */ if (phy->gmode) rts_rate = BWN_CCK_RATE_1MB; @@ -6537,60 +6537,34 @@ bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni, rts_rate_fb = bwn_get_fbrate(rts_rate); /* XXX 'rate' here is hardware rate now, not the net80211 rate */ - protdur = ieee80211_compute_duration(ic->ic_rt, - m->m_pkthdr.len, rate, isshort) + - + ieee80211_ack_duration(ic->ic_rt, rate, isshort); + mprot = ieee80211_alloc_prot(ni, m, rate, ic->ic_protmode); + if (mprot == NULL) { + if_inc_counter(vap->iv_ifp, IFCOUNTER_OERRORS, 1); + device_printf(sc->sc_dev, + "could not allocate mbuf for protection mode %d\n", + ic->ic_protmode); + return (ENOBUFS); + } + + switch (mac->mac_fw.fw_hdr_format) { + case BWN_FW_HDR_351: + prot_ptr = txhdr->body.r351.rts_frame; + break; + case BWN_FW_HDR_410: + prot_ptr = txhdr->body.r410.rts_frame; + break; + case BWN_FW_HDR_598: + prot_ptr = txhdr->body.r598.rts_frame; + break; + } + + bcopy(mtod(mprot, uint8_t *), prot_ptr, mprot->m_pkthdr.len); + m_freem(mprot); if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) { - - switch (mac->mac_fw.fw_hdr_format) { - case BWN_FW_HDR_351: - cts = (struct ieee80211_frame_cts *) - txhdr->body.r351.rts_frame; - break; - case BWN_FW_HDR_410: - cts = (struct ieee80211_frame_cts *) - txhdr->body.r410.rts_frame; - break; - case BWN_FW_HDR_598: - cts = (struct ieee80211_frame_cts *) - txhdr->body.r598.rts_frame; - break; - } - - mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, - protdur); - KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); - bcopy(mtod(mprot, uint8_t *), (uint8_t *)cts, - mprot->m_pkthdr.len); - m_freem(mprot); macctl |= BWN_TX_MAC_SEND_CTSTOSELF; len = sizeof(struct ieee80211_frame_cts); } else { - switch (mac->mac_fw.fw_hdr_format) { - case BWN_FW_HDR_351: - rts = (struct ieee80211_frame_rts *) - txhdr->body.r351.rts_frame; - break; - case BWN_FW_HDR_410: - rts = (struct ieee80211_frame_rts *) - txhdr->body.r410.rts_frame; - break; - case BWN_FW_HDR_598: - rts = (struct ieee80211_frame_rts *) - txhdr->body.r598.rts_frame; - break; - } - - /* XXX rate/rate_fb is the hardware rate */ - protdur += ieee80211_ack_duration(ic->ic_rt, rate, - isshort); - mprot = ieee80211_alloc_rts(ic, wh->i_addr1, - wh->i_addr2, protdur); - KASSERT(mprot != NULL, ("failed to alloc mbuf\n")); - bcopy(mtod(mprot, uint8_t *), (uint8_t *)rts, - mprot->m_pkthdr.len); - m_freem(mprot); macctl |= BWN_TX_MAC_SEND_RTSCTS; len = sizeof(struct ieee80211_frame_rts); } diff --git a/sys/dev/ral/rt2560.c b/sys/dev/ral/rt2560.c index 9da26a8f581a..af684ef2bada 100644 --- a/sys/dev/ral/rt2560.c +++ b/sys/dev/ral/rt2560.c @@ -1594,38 +1594,18 @@ rt2560_sendprot(struct rt2560_softc *sc, const struct mbuf *m, struct ieee80211_node *ni, int prot, int rate) { struct ieee80211com *ic = ni->ni_ic; - const struct ieee80211_frame *wh; struct rt2560_tx_desc *desc; struct rt2560_tx_data *data; struct mbuf *mprot; - int protrate, ackrate, pktlen, flags, isshort, error; - uint16_t dur; + int protrate, flags, error; bus_dma_segment_t segs[RT2560_MAX_SCATTER]; int nsegs; - KASSERT(prot == IEEE80211_PROT_RTSCTS || prot == IEEE80211_PROT_CTSONLY, - ("protection %d", prot)); - - wh = mtod(m, const struct ieee80211_frame *); - pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN; - - protrate = ieee80211_ctl_rate(ic->ic_rt, rate); - ackrate = ieee80211_ack_rate(ic->ic_rt, rate); - - isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; - dur = ieee80211_compute_duration(ic->ic_rt, pktlen, rate, isshort) - + ieee80211_ack_duration(ic->ic_rt, rate, isshort); - flags = RT2560_TX_MORE_FRAG; - if (prot == IEEE80211_PROT_RTSCTS) { - /* NB: CTS is the same size as an ACK */ - dur += ieee80211_ack_duration(ic->ic_rt, rate, isshort); - flags |= RT2560_TX_ACK; - mprot = ieee80211_alloc_rts(ic, wh->i_addr1, wh->i_addr2, dur); - } else { - mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur); - } + mprot = ieee80211_alloc_prot(ni, m, rate, prot); if (mprot == NULL) { - /* XXX stat + msg */ + if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1); + device_printf(sc->sc_dev, + "could not allocate mbuf for protection mode %d\n", prot); return ENOBUFS; } @@ -1646,6 +1626,11 @@ rt2560_sendprot(struct rt2560_softc *sc, /* ctl frames are not taken into account for amrr */ data->rix = IEEE80211_FIXED_RATE_NONE; + protrate = ieee80211_ctl_rate(ic->ic_rt, rate); + flags = RT2560_TX_MORE_FRAG; + if (prot == IEEE80211_PROT_RTSCTS) + flags |= RT2560_TX_ACK; + rt2560_setup_tx_desc(sc, desc, flags, mprot->m_pkthdr.len, protrate, 1, segs->ds_addr); diff --git a/sys/dev/ral/rt2661.c b/sys/dev/ral/rt2661.c index aab385a5855f..a65551eea40b 100644 --- a/sys/dev/ral/rt2661.c +++ b/sys/dev/ral/rt2661.c @@ -1361,38 +1361,18 @@ rt2661_sendprot(struct rt2661_softc *sc, int ac, { struct ieee80211com *ic = ni->ni_ic; struct rt2661_tx_ring *txq = &sc->txq[ac]; - const struct ieee80211_frame *wh; struct rt2661_tx_desc *desc; struct rt2661_tx_data *data; struct mbuf *mprot; - int protrate, ackrate, pktlen, flags, isshort, error; - uint16_t dur; + int protrate, flags, error; bus_dma_segment_t segs[RT2661_MAX_SCATTER]; int nsegs; - KASSERT(prot == IEEE80211_PROT_RTSCTS || prot == IEEE80211_PROT_CTSONLY, - ("protection %d", prot)); - - wh = mtod(m, const struct ieee80211_frame *); - pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN; - - protrate = ieee80211_ctl_rate(ic->ic_rt, rate); - ackrate = ieee80211_ack_rate(ic->ic_rt, rate); - - isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; - dur = ieee80211_compute_duration(ic->ic_rt, pktlen, rate, isshort) - + ieee80211_ack_duration(ic->ic_rt, rate, isshort); - flags = RT2661_TX_MORE_FRAG; - if (prot == IEEE80211_PROT_RTSCTS) { - /* NB: CTS is the same size as an ACK */ - dur += ieee80211_ack_duration(ic->ic_rt, rate, isshort); - flags |= RT2661_TX_NEED_ACK; - mprot = ieee80211_alloc_rts(ic, wh->i_addr1, wh->i_addr2, dur); - } else { - mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur); - } + mprot = ieee80211_alloc_prot(ni, m, rate, prot); if (mprot == NULL) { - /* XXX stat + msg */ + if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1); + device_printf(sc->sc_dev, + "could not allocate mbuf for protection mode %d\n", prot); return ENOBUFS; } @@ -1413,6 +1393,11 @@ rt2661_sendprot(struct rt2661_softc *sc, int ac, /* ctl frames are not taken into account for amrr */ data->rix = IEEE80211_FIXED_RATE_NONE; + protrate = ieee80211_ctl_rate(ic->ic_rt, rate); + flags = RT2661_TX_MORE_FRAG; + if (prot == IEEE80211_PROT_RTSCTS) + flags |= RT2661_TX_NEED_ACK; + rt2661_setup_tx_desc(sc, desc, flags, 0, mprot->m_pkthdr.len, protrate, segs, 1, ac); diff --git a/sys/dev/usb/wlan/if_rum.c b/sys/dev/usb/wlan/if_rum.c index 152d9d80c44f..572e88579b88 100644 --- a/sys/dev/usb/wlan/if_rum.c +++ b/sys/dev/usb/wlan/if_rum.c @@ -1419,37 +1419,25 @@ rum_sendprot(struct rum_softc *sc, const struct mbuf *m, struct ieee80211_node *ni, int prot, int rate) { struct ieee80211com *ic = ni->ni_ic; - const struct ieee80211_frame *wh; struct rum_tx_data *data; struct mbuf *mprot; - int protrate, pktlen, flags, isshort; - uint16_t dur; + int protrate, flags; RUM_LOCK_ASSERT(sc); - KASSERT(prot == IEEE80211_PROT_RTSCTS || prot == IEEE80211_PROT_CTSONLY, - ("protection %d", prot)); - wh = mtod(m, const struct ieee80211_frame *); - pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN; - - protrate = ieee80211_ctl_rate(ic->ic_rt, rate); - - isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; - dur = ieee80211_compute_duration(ic->ic_rt, pktlen, rate, isshort) - + ieee80211_ack_duration(ic->ic_rt, rate, isshort); - flags = 0; - if (prot == IEEE80211_PROT_RTSCTS) { - /* NB: CTS is the same size as an ACK */ - dur += ieee80211_ack_duration(ic->ic_rt, rate, isshort); - flags |= RT2573_TX_NEED_ACK; - mprot = ieee80211_alloc_rts(ic, wh->i_addr1, wh->i_addr2, dur); - } else { - mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur); - } + mprot = ieee80211_alloc_prot(ni, m, rate, prot); if (mprot == NULL) { - /* XXX stat + msg */ + if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1); + device_printf(sc->sc_dev, + "could not allocate mbuf for protection mode %d\n", prot); return (ENOBUFS); } + + protrate = ieee80211_ctl_rate(ic->ic_rt, rate); + flags = 0; + if (prot == IEEE80211_PROT_RTSCTS) + flags |= RT2573_TX_NEED_ACK; + data = STAILQ_FIRST(&sc->tx_free); STAILQ_REMOVE_HEAD(&sc->tx_free, next); sc->tx_nfree--; diff --git a/sys/dev/usb/wlan/if_run.c b/sys/dev/usb/wlan/if_run.c index b40e4d2ff850..3a6fc0960e62 100644 --- a/sys/dev/usb/wlan/if_run.c +++ b/sys/dev/usb/wlan/if_run.c @@ -3543,57 +3543,35 @@ run_sendprot(struct run_softc *sc, const struct mbuf *m, struct ieee80211_node *ni, int prot, int rate) { struct ieee80211com *ic = ni->ni_ic; - struct ieee80211_frame *wh; struct run_tx_data *data; struct rt2870_txd *txd; struct rt2860_txwi *txwi; struct mbuf *mprot; int ridx; int protrate; - int ackrate; - int pktlen; - int isshort; - uint16_t dur; - uint8_t type; uint8_t wflags = 0; uint8_t xflags = 0; RUN_LOCK_ASSERT(sc, MA_OWNED); - KASSERT(prot == IEEE80211_PROT_RTSCTS || prot == IEEE80211_PROT_CTSONLY, - ("protection %d", prot)); - - wh = mtod(m, struct ieee80211_frame *); - pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN; - type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; - - protrate = ieee80211_ctl_rate(ic->ic_rt, rate); - ackrate = ieee80211_ack_rate(ic->ic_rt, rate); - - isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; - dur = ieee80211_compute_duration(ic->ic_rt, pktlen, rate, isshort) - + ieee80211_ack_duration(ic->ic_rt, rate, isshort); - wflags = RT2860_TX_FRAG; - /* check that there are free slots before allocating the mbuf */ if (sc->sc_epq[0].tx_nfree == 0) /* let caller free mbuf */ return (ENOBUFS); - if (prot == IEEE80211_PROT_RTSCTS) { - /* NB: CTS is the same size as an ACK */ - dur += ieee80211_ack_duration(ic->ic_rt, rate, isshort); - xflags |= RT2860_TX_ACK; - mprot = ieee80211_alloc_rts(ic, wh->i_addr1, wh->i_addr2, dur); - } else { - mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur); - } + mprot = ieee80211_alloc_prot(ni, m, rate, prot); if (mprot == NULL) { if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1); RUN_DPRINTF(sc, RUN_DEBUG_XMIT, "could not allocate mbuf\n"); return (ENOBUFS); } + protrate = ieee80211_ctl_rate(ic->ic_rt, rate); + wflags = RT2860_TX_FRAG; + xflags = 0; + if (prot == IEEE80211_PROT_RTSCTS) + xflags |= RT2860_TX_ACK; + data = STAILQ_FIRST(&sc->sc_epq[0].tx_fh); STAILQ_REMOVE_HEAD(&sc->sc_epq[0].tx_fh, next); sc->sc_epq[0].tx_nfree--; diff --git a/sys/dev/usb/wlan/if_ural.c b/sys/dev/usb/wlan/if_ural.c index b3eaa5d0dd86..e163c51e1702 100644 --- a/sys/dev/usb/wlan/if_ural.c +++ b/sys/dev/usb/wlan/if_ural.c @@ -1130,37 +1130,23 @@ ural_sendprot(struct ural_softc *sc, const struct mbuf *m, struct ieee80211_node *ni, int prot, int rate) { struct ieee80211com *ic = ni->ni_ic; - const struct ieee80211_frame *wh; struct ural_tx_data *data; struct mbuf *mprot; - int protrate, ackrate, pktlen, flags, isshort; - uint16_t dur; + int protrate, flags; - KASSERT(prot == IEEE80211_PROT_RTSCTS || prot == IEEE80211_PROT_CTSONLY, - ("protection %d", prot)); - - wh = mtod(m, const struct ieee80211_frame *); - pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN; - - protrate = ieee80211_ctl_rate(ic->ic_rt, rate); - ackrate = ieee80211_ack_rate(ic->ic_rt, rate); - - isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; - dur = ieee80211_compute_duration(ic->ic_rt, pktlen, rate, isshort) - + ieee80211_ack_duration(ic->ic_rt, rate, isshort); - flags = RAL_TX_RETRY(7); - if (prot == IEEE80211_PROT_RTSCTS) { - /* NB: CTS is the same size as an ACK */ - dur += ieee80211_ack_duration(ic->ic_rt, rate, isshort); - flags |= RAL_TX_ACK; - mprot = ieee80211_alloc_rts(ic, wh->i_addr1, wh->i_addr2, dur); - } else { - mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur); - } + mprot = ieee80211_alloc_prot(ni, m, rate, prot); if (mprot == NULL) { - /* XXX stat + msg */ + if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1); + device_printf(sc->sc_dev, + "could not allocate mbuf for protection mode %d\n", prot); return ENOBUFS; } + + protrate = ieee80211_ctl_rate(ic->ic_rt, rate); + flags = RAL_TX_RETRY(7); + if (prot == IEEE80211_PROT_RTSCTS) + flags |= RAL_TX_ACK; + data = STAILQ_FIRST(&sc->tx_free); STAILQ_REMOVE_HEAD(&sc->tx_free, next); sc->tx_nfree--; diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c index b720fcc969a5..a2421e33fff2 100644 --- a/sys/net80211/ieee80211_output.c +++ b/sys/net80211/ieee80211_output.c @@ -3088,6 +3088,39 @@ ieee80211_alloc_cts(struct ieee80211com *ic, return m; } +/* + * Wrapper for CTS/RTS frame allocation. + */ +struct mbuf * +ieee80211_alloc_prot(struct ieee80211_node *ni, const struct mbuf *m, + uint8_t rate, int prot) +{ + struct ieee80211com *ic = ni->ni_ic; + const struct ieee80211_frame *wh; + struct mbuf *mprot; + uint16_t dur; + int pktlen, isshort; + + KASSERT(prot == IEEE80211_PROT_RTSCTS || + prot == IEEE80211_PROT_CTSONLY, + ("wrong protection type %d", prot)); + + wh = mtod(m, const struct ieee80211_frame *); + pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN; + isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; + dur = ieee80211_compute_duration(ic->ic_rt, pktlen, rate, isshort) + + ieee80211_ack_duration(ic->ic_rt, rate, isshort); + + if (prot == IEEE80211_PROT_RTSCTS) { + /* NB: CTS is the same size as an ACK */ + dur += ieee80211_ack_duration(ic->ic_rt, rate, isshort); + mprot = ieee80211_alloc_rts(ic, wh->i_addr1, wh->i_addr2, dur); + } else + mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur); + + return (mprot); +} + static void ieee80211_tx_mgt_timeout(void *arg) { diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h index 28238ce86eea..c1637c5740f8 100644 --- a/sys/net80211/ieee80211_proto.h +++ b/sys/net80211/ieee80211_proto.h @@ -140,6 +140,8 @@ struct mbuf *ieee80211_alloc_rts(struct ieee80211com *ic, const uint8_t [IEEE80211_ADDR_LEN], uint16_t); struct mbuf *ieee80211_alloc_cts(struct ieee80211com *, const uint8_t [IEEE80211_ADDR_LEN], uint16_t); +struct mbuf *ieee80211_alloc_prot(struct ieee80211_node *, + const struct mbuf *, uint8_t, int); uint8_t *ieee80211_add_rates(uint8_t *, const struct ieee80211_rateset *); uint8_t *ieee80211_add_xrates(uint8_t *, const struct ieee80211_rateset *);