diff --git a/sys/dev/ral/rt2560.c b/sys/dev/ral/rt2560.c index e8823b126c8..d012b8f9dd1 100644 --- a/sys/dev/ral/rt2560.c +++ b/sys/dev/ral/rt2560.c @@ -1238,7 +1238,8 @@ rt2560_decryption_intr(struct rt2560_softc *sc) htole64(((uint64_t)tsf_hi << 32) | tsf_lo); tap->wr_flags = 0; tap->wr_rate = ieee80211_plcp2rate(desc->rate, - le32toh(desc->flags) & RT2560_RX_OFDM); + (desc->flags & htole32(RT2560_RX_OFDM)) ? + IEEE80211_T_OFDM : IEEE80211_T_CCK); tap->wr_antenna = sc->rx_ant; tap->wr_antsignal = RT2560_RSSI(sc, desc->rssi); @@ -1433,6 +1434,29 @@ rt2560_intr(void *arg) #define RT2560_TXRX_TURNAROUND 10 /* us */ +static uint8_t +rt2560_plcp_signal(int rate) +{ + switch (rate) { + /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ + case 12: return 0xb; + case 18: return 0xf; + case 24: return 0xa; + case 36: return 0xe; + case 48: return 0x9; + case 72: return 0xd; + case 96: return 0x8; + case 108: return 0xc; + + /* CCK rates (NB: not IEEE std, device-specific) */ + case 2: return 0x0; + case 4: return 0x1; + case 11: return 0x2; + case 22: return 0x3; + } + return 0xff; /* XXX unsupported/unknown rate */ +} + static void rt2560_setup_tx_desc(struct rt2560_softc *sc, struct rt2560_tx_desc *desc, uint32_t flags, int len, int rate, int encrypt, bus_addr_t physaddr) @@ -1452,7 +1476,7 @@ rt2560_setup_tx_desc(struct rt2560_softc *sc, struct rt2560_tx_desc *desc, RT2560_LOGCWMAX(8)); /* setup PLCP fields */ - desc->plcp_signal = ieee80211_rate2plcp(rate); + desc->plcp_signal = rt2560_plcp_signal(rate); desc->plcp_service = 4; len += IEEE80211_CRC_LEN; diff --git a/sys/dev/ral/rt2661.c b/sys/dev/ral/rt2661.c index 7dfb63516f2..cc89d165f2f 100644 --- a/sys/dev/ral/rt2661.c +++ b/sys/dev/ral/rt2661.c @@ -1119,7 +1119,8 @@ rt2661_rx_intr(struct rt2661_softc *sc) htole64(((uint64_t)tsf_hi << 32) | tsf_lo); tap->wr_flags = 0; tap->wr_rate = ieee80211_plcp2rate(desc->rate, - le32toh(desc->flags) & RT2661_RX_OFDM); + (desc->flags & htole32(RT2661_RX_OFDM)) ? + IEEE80211_T_OFDM : IEEE80211_T_CCK); tap->wr_antsignal = rssi < 0 ? 0 : rssi; bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); @@ -1246,6 +1247,29 @@ rt2661_intr(void *arg) RAL_UNLOCK(sc); } +static uint8_t +rt2661_plcp_signal(int rate) +{ + switch (rate) { + /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ + case 12: return 0xb; + case 18: return 0xf; + case 24: return 0xa; + case 36: return 0xe; + case 48: return 0x9; + case 72: return 0xd; + case 96: return 0x8; + case 108: return 0xc; + + /* CCK rates (NB: not IEEE std, device-specific) */ + case 2: return 0x0; + case 4: return 0x1; + case 11: return 0x2; + case 22: return 0x3; + } + return 0xff; /* XXX unsupported/unknown rate */ +} + static void rt2661_setup_tx_desc(struct rt2661_softc *sc, struct rt2661_tx_desc *desc, uint32_t flags, uint16_t xflags, int len, int rate, @@ -1277,7 +1301,7 @@ rt2661_setup_tx_desc(struct rt2661_softc *sc, struct rt2661_tx_desc *desc, desc->qid = ac; /* setup PLCP fields */ - desc->plcp_signal = ieee80211_rate2plcp(rate); + desc->plcp_signal = rt2661_plcp_signal(rate); desc->plcp_service = 4; len += IEEE80211_CRC_LEN; diff --git a/sys/dev/usb/if_rum.c b/sys/dev/usb/if_rum.c index 522b8ce84e0..3c68d49b54d 100644 --- a/sys/dev/usb/if_rum.c +++ b/sys/dev/usb/if_rum.c @@ -937,7 +937,8 @@ rum_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) tap->wr_flags = IEEE80211_RADIOTAP_F_FCS; tap->wr_rate = ieee80211_plcp2rate(desc->rate, - le32toh(desc->flags) & RT2573_RX_OFDM); + (desc->flags & htole32(RT2573_RX_OFDM)) ? + IEEE80211_T_OFDM : IEEE80211_T_CCK); tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); tap->wr_antenna = sc->rx_ant; @@ -964,6 +965,29 @@ skip: /* setup a new transfer */ usbd_transfer(xfer); } +static uint8_t +rum_plcp_signal(int rate) +{ + switch (rate) { + /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ + case 12: return 0xb; + case 18: return 0xf; + case 24: return 0xa; + case 36: return 0xe; + case 48: return 0x9; + case 72: return 0xd; + case 96: return 0x8; + case 108: return 0xc; + + /* CCK rates (NB: not IEEE std, device-specific) */ + case 2: return 0x0; + case 4: return 0x1; + case 11: return 0x2; + case 22: return 0x3; + } + return 0xff; /* XXX unsupported/unknown rate */ +} + static void rum_setup_tx_desc(struct rum_softc *sc, struct rum_tx_desc *desc, uint32_t flags, uint16_t xflags, int len, int rate) @@ -983,7 +1007,7 @@ rum_setup_tx_desc(struct rum_softc *sc, struct rum_tx_desc *desc, RT2573_LOGCWMIN(4) | RT2573_LOGCWMAX(10)); /* setup PLCP fields */ - desc->plcp_signal = ieee80211_rate2plcp(rate); + desc->plcp_signal = rum_plcp_signal(rate); desc->plcp_service = 4; len += IEEE80211_CRC_LEN; diff --git a/sys/dev/usb/if_ural.c b/sys/dev/usb/if_ural.c index d19c93e6e20..b072fa0acc9 100644 --- a/sys/dev/usb/if_ural.c +++ b/sys/dev/usb/if_ural.c @@ -967,7 +967,8 @@ ural_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) tap->wr_flags = IEEE80211_RADIOTAP_F_FCS; tap->wr_rate = ieee80211_plcp2rate(desc->rate, - le32toh(desc->flags) & RAL_RX_OFDM); + (desc->flags & htole32(RAL_RX_OFDM)) ? + IEEE80211_T_OFDM : IEEE80211_T_CCK); tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); tap->wr_antenna = sc->rx_ant; @@ -995,6 +996,29 @@ skip: /* setup a new transfer */ usbd_transfer(xfer); } +static uint8_t +ural_plcp_signal(int rate) +{ + switch (rate) { + /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ + case 12: return 0xb; + case 18: return 0xf; + case 24: return 0xa; + case 36: return 0xe; + case 48: return 0x9; + case 72: return 0xd; + case 96: return 0x8; + case 108: return 0xc; + + /* CCK rates (NB: not IEEE std, device-specific) */ + case 2: return 0x0; + case 4: return 0x1; + case 11: return 0x2; + case 22: return 0x3; + } + return 0xff; /* XXX unsupported/unknown rate */ +} + static void ural_setup_tx_desc(struct ural_softc *sc, struct ural_tx_desc *desc, uint32_t flags, int len, int rate) @@ -1012,7 +1036,7 @@ ural_setup_tx_desc(struct ural_softc *sc, struct ural_tx_desc *desc, desc->wme |= htole16(RAL_IVOFFSET(sizeof (struct ieee80211_frame))); /* setup PLCP fields */ - desc->plcp_signal = ieee80211_rate2plcp(rate); + desc->plcp_signal = ural_plcp_signal(rate); desc->plcp_service = 4; len += IEEE80211_CRC_LEN; diff --git a/sys/dev/usb/if_zyd.c b/sys/dev/usb/if_zyd.c index 1e059528e2d..70629697e34 100644 --- a/sys/dev/usb/if_zyd.c +++ b/sys/dev/usb/if_zyd.c @@ -1987,7 +1987,8 @@ zyd_rx_data(struct zyd_softc *sc, const uint8_t *buf, uint16_t len) if (stat->flags & ZYD_RX_DECRYPTERR) tap->wr_flags |= IEEE80211_RADIOTAP_F_BADFCS; tap->wr_rate = ieee80211_plcp2rate(plcp->signal, - stat->flags & ZYD_RX_OFDM); + (stat->flags & ZYD_RX_OFDM) ? + IEEE80211_T_OFDM : IEEE80211_T_CCK); tap->wr_antsignal = stat->rssi + -95; tap->wr_antnoise = -95; /* XXX */ @@ -2064,6 +2065,29 @@ skip: /* setup a new transfer */ (void)usbd_transfer(xfer); } +static uint8_t +zyd_plcp_signal(int rate) +{ + switch (rate) { + /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ + case 12: return 0xb; + case 18: return 0xf; + case 24: return 0xa; + case 36: return 0xe; + case 48: return 0x9; + case 72: return 0xd; + case 96: return 0x8; + case 108: return 0xc; + + /* CCK rates (NB: not IEEE std, device-specific) */ + case 2: return 0x0; + case 4: return 0x1; + case 11: return 0x2; + case 22: return 0x3; + } + return 0xff; /* XXX unsupported/unknown rate */ +} + static int zyd_tx_mgt(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) { @@ -2124,7 +2148,7 @@ zyd_tx_mgt(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_PS_POLL)) desc->flags |= ZYD_TX_FLAG_TYPE(ZYD_TX_TYPE_PS_POLL); - desc->phy = ieee80211_rate2plcp(rate); + desc->phy = zyd_plcp_signal(rate); if (ZYD_RATE_IS_OFDM(rate)) { desc->phy |= ZYD_TX_PHY_OFDM; if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) @@ -2295,7 +2319,7 @@ zyd_tx_data(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_PS_POLL)) desc->flags |= ZYD_TX_FLAG_TYPE(ZYD_TX_TYPE_PS_POLL); - desc->phy = ieee80211_rate2plcp(rate); + desc->phy = zyd_plcp_signal(rate); if (ZYD_RATE_IS_OFDM(rate)) { desc->phy |= ZYD_TX_PHY_OFDM; if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) diff --git a/sys/net80211/ieee80211_phy.c b/sys/net80211/ieee80211_phy.c index e1c847fb415..4dd4b975c7d 100644 --- a/sys/net80211/ieee80211_phy.c +++ b/sys/net80211/ieee80211_phy.c @@ -309,9 +309,9 @@ ieee80211_get_ratetable(struct ieee80211_channel *c) * XXX might be a candidate for inline */ uint8_t -ieee80211_plcp2rate(uint8_t plcp, int ofdm) +ieee80211_plcp2rate(uint8_t plcp, enum ieee80211_phytype type) { - if (ofdm) { + if (type == IEEE80211_T_OFDM) { static const uint8_t ofdm_plcp2rate[16] = { [0xb] = 12, [0xf] = 18, @@ -323,7 +323,8 @@ ieee80211_plcp2rate(uint8_t plcp, int ofdm) [0xc] = 108 }; return ofdm_plcp2rate[plcp & 0xf]; - } else { + } + if (type == IEEE80211_T_CCK) { static const uint8_t cck_plcp2rate[16] = { [0xa] = 2, /* 0x0a */ [0x4] = 4, /* 0x14 */ @@ -333,21 +334,17 @@ ieee80211_plcp2rate(uint8_t plcp, int ofdm) }; return cck_plcp2rate[plcp & 0xf]; } + return 0; } /* * Covert 802.11 rate to PLCP signal. */ uint8_t -ieee80211_rate2plcp(int rate) +ieee80211_rate2plcp(int rate, enum ieee80211_phytype type) { + /* XXX ignore type for now since rates are unique */ switch (rate) { - /* CCK rates (returned values are device-dependent) */ - case 2: return 0x0; - case 4: return 0x1; - case 11: return 0x2; - case 22: return 0x3; - /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ case 12: return 0xb; case 18: return 0xf; @@ -357,9 +354,17 @@ ieee80211_rate2plcp(int rate) case 72: return 0xd; case 96: return 0x8; case 108: return 0xc; + /* CCK rates (IEEE Std 802.11b-1999 page 15, subclause 18.2.3.3) */ + case 2: return 10; + case 4: return 20; + case 11: return 55; + case 22: return 110; + /* IEEE Std 802.11g-2003 page 19, subclause 19.3.2.1 */ + case 44: return 220; } - return 0xff; /* XXX unsupported/unknown rate */ + return 0; /* XXX unsupported/unknown rate */ } + /* * Compute the time to transmit a frame of length frameLen bytes * using the specified rate, phy, and short preamble setting. diff --git a/sys/net80211/ieee80211_phy.h b/sys/net80211/ieee80211_phy.h index 2b5adcf4a5f..9e1f532ec3d 100644 --- a/sys/net80211/ieee80211_phy.h +++ b/sys/net80211/ieee80211_phy.h @@ -140,10 +140,10 @@ uint16_t ieee80211_compute_duration(const struct ieee80211_rate_table *, /* * Convert PLCP signal/rate field to 802.11 rate code (.5Mbits/s) */ -uint8_t ieee80211_plcp2rate(uint8_t, int); +uint8_t ieee80211_plcp2rate(uint8_t, enum ieee80211_phytype); /* * Convert 802.11 rate code to PLCP signal. */ -uint8_t ieee80211_rate2plcp(int); +uint8_t ieee80211_rate2plcp(int, enum ieee80211_phytype); #endif /* _KERNEL */ #endif /* !_NET80211_IEEE80211_PHY_H_ */