From 2d7dda799b28995342cff66923ac2df53ebc7675 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Tue, 27 Mar 2007 13:34:53 +0000 Subject: [PATCH] - Implement ieee80211_ack_rate() according to IEEE Std 802.11g-2003 clause 9.6 - Nuke non-standard conforming ACK rate calculation in ral(4), rum(4) and ural(4). Use ieee80211_ack_rate() instead. --- sys/dev/netif/ral/rt2560.c | 42 +----------- sys/dev/netif/ral/rt2661.c | 41 +---------- sys/dev/netif/rum/if_rum.c | 39 +---------- sys/dev/netif/ural/if_ural.c | 39 +---------- sys/netproto/802_11/ieee80211_proto.h | 4 +- sys/netproto/802_11/wlan/ieee80211_output.c | 76 ++++++++++++++++++++- 6 files changed, 88 insertions(+), 153 deletions(-) diff --git a/sys/dev/netif/ral/rt2560.c b/sys/dev/netif/ral/rt2560.c index 062edba833..be837a15fa 100644 --- a/sys/dev/netif/ral/rt2560.c +++ b/sys/dev/netif/ral/rt2560.c @@ -15,7 +15,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $FreeBSD: src/sys/dev/ral/rt2560.c,v 1.3 2006/03/21 21:15:43 damien Exp $ - * $DragonFly: src/sys/dev/netif/ral/rt2560.c,v 1.10 2007/02/06 12:38:30 sephe Exp $ + * $DragonFly: src/sys/dev/netif/ral/rt2560.c,v 1.11 2007/03/27 13:34:53 sephe Exp $ */ /* @@ -97,7 +97,6 @@ static void rt2560_rx_intr(struct rt2560_softc *); static void rt2560_beacon_expire(struct rt2560_softc *); static void rt2560_wakeup_expire(struct rt2560_softc *); static uint8_t rt2560_rxrate(struct rt2560_rx_desc *); -static int rt2560_ack_rate(struct ieee80211com *, int); static uint16_t rt2560_txtime(int, int, uint32_t); static uint8_t rt2560_plcp_signal(int); static void rt2560_setup_tx_desc(struct rt2560_softc *, @@ -1502,40 +1501,6 @@ rt2560_rxrate(struct rt2560_rx_desc *desc) return 2; /* should not get there */ } -/* - * Return the expected ack rate for a frame transmitted at rate `rate'. - * XXX: this should depend on the destination node basic rate set. - */ -static int -rt2560_ack_rate(struct ieee80211com *ic, int rate) -{ - switch (rate) { - /* CCK rates */ - case 2: - return 2; - case 4: - case 11: - case 22: - return (ic->ic_curmode == IEEE80211_MODE_11B) ? 4 : rate; - - /* OFDM rates */ - case 12: - case 18: - return 12; - case 24: - case 36: - return 24; - case 48: - case 72: - case 96: - case 108: - return 48; - } - - /* default to 1Mbps */ - return 2; -} - /* * Compute the duration (in us) needed to transmit `len' bytes at rate `rate'. * The function automatically determines the operating mode depending on the @@ -1851,7 +1816,7 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0, int rtsrate, ackrate; rtsrate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2; - ackrate = rt2560_ack_rate(ic, rate); + ackrate = ieee80211_ack_rate(ni, rate); dur = rt2560_txtime(m0->m_pkthdr.len + 4, rate, ic->ic_flags) + rt2560_txtime(RAL_CTS_SIZE, rtsrate, ic->ic_flags) + @@ -1961,8 +1926,7 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0, if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { flags |= RT2560_TX_ACK; - - dur = rt2560_txtime(RAL_ACK_SIZE, rt2560_ack_rate(ic, rate), + dur = rt2560_txtime(RAL_ACK_SIZE, ieee80211_ack_rate(ni, rate), ic->ic_flags) + RAL_SIFS; *(uint16_t *)wh->i_dur = htole16(dur); } diff --git a/sys/dev/netif/ral/rt2661.c b/sys/dev/netif/ral/rt2661.c index 78d9e382da..217a6d173c 100644 --- a/sys/dev/netif/ral/rt2661.c +++ b/sys/dev/netif/ral/rt2661.c @@ -15,7 +15,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $FreeBSD: src/sys/dev/ral/rt2661.c,v 1.4 2006/03/21 21:15:43 damien Exp $ - * $DragonFly: src/sys/dev/netif/ral/rt2661.c,v 1.13 2007/02/07 12:34:26 sephe Exp $ + * $DragonFly: src/sys/dev/netif/ral/rt2661.c,v 1.14 2007/03/27 13:34:53 sephe Exp $ */ /* @@ -95,7 +95,6 @@ static void rt2661_tx_dma_intr(struct rt2661_softc *, static void rt2661_mcu_beacon_expire(struct rt2661_softc *); static void rt2661_mcu_wakeup(struct rt2661_softc *); static void rt2661_mcu_cmd_intr(struct rt2661_softc *); -static int rt2661_ack_rate(struct ieee80211com *, int); static uint16_t rt2661_txtime(int, int, uint32_t); static uint8_t rt2661_rxrate(struct rt2661_rx_desc *); static uint8_t rt2661_plcp_signal(int); @@ -1393,40 +1392,6 @@ rt2661_rxrate(struct rt2661_rx_desc *desc) return 2; /* should not get there */ } -/* - * Return the expected ack rate for a frame transmitted at rate `rate'. - * XXX: this should depend on the destination node basic rate set. - */ -static int -rt2661_ack_rate(struct ieee80211com *ic, int rate) -{ - switch (rate) { - /* CCK rates */ - case 2: - return 2; - case 4: - case 11: - case 22: - return (ic->ic_curmode == IEEE80211_MODE_11B) ? 4 : rate; - - /* OFDM rates */ - case 12: - case 18: - return 12; - case 24: - case 36: - return 24; - case 48: - case 72: - case 96: - case 108: - return 48; - } - - /* default to 1Mbps */ - return 2; -} - /* * Compute the duration (in us) needed to transmit `len' bytes at rate `rate'. * The function automatically determines the operating mode depending on the @@ -1711,7 +1676,7 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0, int rtsrate, ackrate; rtsrate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2; - ackrate = rt2661_ack_rate(ic, rate); + ackrate = ieee80211_ack_rate(ni, rate); dur = rt2661_txtime(m0->m_pkthdr.len + 4, rate, ic->ic_flags) + rt2661_txtime(RAL_CTS_SIZE, rtsrate, ic->ic_flags) + @@ -1820,7 +1785,7 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0, if (!noack && !IEEE80211_IS_MULTICAST(wh->i_addr1)) { flags |= RT2661_TX_NEED_ACK; - dur = rt2661_txtime(RAL_ACK_SIZE, rt2661_ack_rate(ic, rate), + dur = rt2661_txtime(RAL_ACK_SIZE, ieee80211_ack_rate(ni, rate), ic->ic_flags) + RAL_SIFS; *(uint16_t *)wh->i_dur = htole16(dur); } diff --git a/sys/dev/netif/rum/if_rum.c b/sys/dev/netif/rum/if_rum.c index a4ecfcbf5b..ca00f3feb8 100644 --- a/sys/dev/netif/rum/if_rum.c +++ b/sys/dev/netif/rum/if_rum.c @@ -1,5 +1,5 @@ /* $OpenBSD: if_rum.c,v 1.40 2006/09/18 16:20:20 damien Exp $ */ -/* $DragonFly: src/sys/dev/netif/rum/if_rum.c,v 1.8 2007/03/18 11:49:32 sephe Exp $ */ +/* $DragonFly: src/sys/dev/netif/rum/if_rum.c,v 1.9 2007/03/27 13:34:53 sephe Exp $ */ /*- * Copyright (c) 2005, 2006 Damien Bergamini @@ -131,7 +131,6 @@ Static void rum_txeof(usbd_xfer_handle, usbd_private_handle, Static void rum_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); Static uint8_t rum_rxrate(struct rum_rx_desc *); -Static int rum_ack_rate(struct ieee80211com *, int); Static uint16_t rum_txtime(int, int, uint32_t); Static uint8_t rum_plcp_signal(int); Static void rum_setup_tx_desc(struct rum_softc *, @@ -941,40 +940,6 @@ rum_rxrate(struct rum_rx_desc *desc) return 2; /* should not get there */ } -/* - * Return the expected ack rate for a frame transmitted at rate `rate'. - * XXX: this should depend on the destination node basic rate set. - */ -Static int -rum_ack_rate(struct ieee80211com *ic, int rate) -{ - switch (rate) { - /* CCK rates */ - case 2: - return 2; - case 4: - case 11: - case 22: - return (ic->ic_curmode == IEEE80211_MODE_11B) ? 4 : rate; - - /* OFDM rates */ - case 12: - case 18: - return 12; - case 24: - case 36: - return 24; - case 48: - case 72: - case 96: - case 108: - return 48; - } - - /* default to 1Mbps */ - return 2; -} - /* * Compute the duration (in us) needed to transmit `len' bytes at rate `rate'. * The function automatically determines the operating mode depending on the @@ -1122,7 +1087,7 @@ rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { flags |= RT2573_TX_ACK; - dur = rum_txtime(RUM_ACK_SIZE, rum_ack_rate(ic, rate), + dur = rum_txtime(RUM_ACK_SIZE, ieee80211_ack_rate(ni, rate), ic->ic_flags) + sc->sifs; *(uint16_t *)wh->i_dur = htole16(dur); diff --git a/sys/dev/netif/ural/if_ural.c b/sys/dev/netif/ural/if_ural.c index 31f483bc9c..bb60af3953 100644 --- a/sys/dev/netif/ural/if_ural.c +++ b/sys/dev/netif/ural/if_ural.c @@ -1,5 +1,5 @@ /* $FreeBSD: src/sys/dev/usb/if_ural.c,v 1.10.2.8 2006/07/08 07:48:43 maxim Exp $ */ -/* $DragonFly: src/sys/dev/netif/ural/if_ural.c,v 1.7 2007/03/18 11:49:32 sephe Exp $ */ +/* $DragonFly: src/sys/dev/netif/ural/if_ural.c,v 1.8 2007/03/27 13:34:53 sephe Exp $ */ /*- * Copyright (c) 2005, 2006 @@ -115,7 +115,6 @@ Static void ural_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); Static void ural_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -Static int ural_ack_rate(struct ieee80211com *, int); Static uint16_t ural_txtime(int, int, uint32_t); Static uint8_t ural_plcp_signal(int); Static void ural_setup_tx_desc(struct ural_softc *, @@ -1032,40 +1031,6 @@ skip: /* setup a new transfer */ usbd_transfer(xfer); } -/* - * Return the expected ack rate for a frame transmitted at rate `rate'. - * XXX: this should depend on the destination node basic rate set. - */ -Static int -ural_ack_rate(struct ieee80211com *ic, int rate) -{ - switch (rate) { - /* CCK rates */ - case 2: - return 2; - case 4: - case 11: - case 22: - return (ic->ic_curmode == IEEE80211_MODE_11B) ? 4 : rate; - - /* OFDM rates */ - case 12: - case 18: - return 12; - case 24: - case 36: - return 24; - case 48: - case 72: - case 96: - case 108: - return 48; - } - - /* default to 1Mbps */ - return 2; -} - /* * Compute the duration (in us) needed to transmit `len' bytes at rate `rate'. * The function automatically determines the operating mode depending on the @@ -1330,7 +1295,7 @@ ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) flags |= RAL_TX_ACK; flags |= RAL_TX_RETRY(sc->sc_tx_retries); - dur = ural_txtime(RAL_ACK_SIZE, ural_ack_rate(ic, rate), + dur = ural_txtime(RAL_ACK_SIZE, ieee80211_ack_rate(ni, rate), ic->ic_flags) + RAL_SIFS; *(uint16_t *)wh->i_dur = htole16(dur); } diff --git a/sys/netproto/802_11/ieee80211_proto.h b/sys/netproto/802_11/ieee80211_proto.h index 9a985b253a..6adb62384c 100644 --- a/sys/netproto/802_11/ieee80211_proto.h +++ b/sys/netproto/802_11/ieee80211_proto.h @@ -30,7 +30,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/net80211/ieee80211_proto.h,v 1.11.2.5 2006/02/12 19:00:39 sam Exp $ - * $DragonFly: src/sys/netproto/802_11/ieee80211_proto.h,v 1.8 2007/01/01 08:51:45 sephe Exp $ + * $DragonFly: src/sys/netproto/802_11/ieee80211_proto.h,v 1.9 2007/03/27 13:34:53 sephe Exp $ */ #ifndef _NET80211_IEEE80211_PROTO_H_ #define _NET80211_IEEE80211_PROTO_H_ @@ -254,6 +254,8 @@ int ieee80211_beacon_update(struct ieee80211com *, struct mbuf *ieee80211_probe_resp_alloc(struct ieee80211com *, struct ieee80211_node *); +uint8_t ieee80211_ack_rate(struct ieee80211_node *, uint8_t); + /* * Notification methods called from the 802.11 state machine. * Note that while these are defined here, their implementation diff --git a/sys/netproto/802_11/wlan/ieee80211_output.c b/sys/netproto/802_11/wlan/ieee80211_output.c index 6ef15f867a..a43c62fbe9 100644 --- a/sys/netproto/802_11/wlan/ieee80211_output.c +++ b/sys/netproto/802_11/wlan/ieee80211_output.c @@ -30,7 +30,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/net80211/ieee80211_output.c,v 1.26.2.8 2006/09/02 15:06:04 sam Exp $ - * $DragonFly: src/sys/netproto/802_11/wlan/ieee80211_output.c,v 1.17 2007/03/18 05:35:54 sephe Exp $ + * $DragonFly: src/sys/netproto/802_11/wlan/ieee80211_output.c,v 1.18 2007/03/27 13:34:53 sephe Exp $ */ #include "opt_inet.h" @@ -1801,3 +1801,77 @@ ieee80211_pwrsave(struct ieee80211com *ic, struct ieee80211_node *ni, if (qlen == 1) ic->ic_set_tim(ni, 1); } + +#define IEEE80211_MODTYPE_CCK 0 +#define IEEE80211_MODTYPE_OFDM 1 +#define IEEE80211_MODTYPE_PBCC 2 + +static int +ieee80211_rate2modtype(uint8_t rate) +{ + if (rate == 44) + return IEEE80211_MODTYPE_PBCC; + else if (rate == 22 || rate < 12) + return IEEE80211_MODTYPE_CCK; + else + return IEEE80211_MODTYPE_OFDM; +} + +uint8_t +ieee80211_ack_rate(struct ieee80211_node *ni, uint8_t rate) +{ + const struct ieee80211_rateset *rs = &ni->ni_rates; + uint8_t ack_rate = 0; + int modtype, i; + + modtype = ieee80211_rate2modtype(rate); + + for (i = 0; i < rs->rs_nrates; ++i) { + uint8_t rate1 = IEEE80211_RS_RATE(rs, i); + + if (rate1 > rate) { + if (ack_rate != 0) + return ack_rate; + else + break; + } + + if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) && + ieee80211_rate2modtype(rate1) == modtype) + ack_rate = rate1; + } + + switch (rate) { + /* CCK */ + case 2: + case 4: + case 11: + case 22: + ack_rate = rate; + break; + + /* PBCC */ + case 44: + ack_rate = 22; + break; + + /* OFDM */ + case 12: + case 18: + ack_rate = 12; + break; + case 24: + case 36: + ack_rate = 24; + break; + case 48: + case 72: + case 96: + case 108: + ack_rate = 48; + break; + default: + panic("unsupported rate %d\n", rate); + } + return ack_rate; +} -- 2.41.0