Date: Sat, 19 Apr 2008 02:52:24 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 140233 for review Message-ID: <200804190252.m3J2qOAI031612@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=140233 Change 140233 by sam@sam_ebb on 2008/04/19 02:51:27 o convert to use common phy code o fixup ioctl path o fix rate selection in xmit path Now my 4309 can associate w/ wpa and pass traffic before it gets confused and stops working. Affected files ... .. //depot/projects/vap/sys/dev/bwi/bwimac.c#4 edit .. //depot/projects/vap/sys/dev/bwi/if_bwi.c#8 edit .. //depot/projects/vap/sys/dev/bwi/if_bwivar.h#5 edit Differences ... ==== //depot/projects/vap/sys/dev/bwi/bwimac.c#4 (text+ko) ==== @@ -66,6 +66,7 @@ #include <net80211/ieee80211_var.h> #include <net80211/ieee80211_radiotap.h> #include <net80211/ieee80211_amrr.h> +#include <net80211/ieee80211_phy.h> #include <machine/bus.h> @@ -89,6 +90,7 @@ static void bwi_mac_set_retry_lim(struct bwi_mac *, const struct bwi_retry_lim *); static void bwi_mac_set_ackrates(struct bwi_mac *, + const struct ieee80211_rate_table *rt, const struct ieee80211_rateset *); static int bwi_mac_gpio_init(struct bwi_mac *); @@ -1344,6 +1346,7 @@ struct bwi_phy *phy = &mac->mac_phy; struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; + const struct ieee80211_rate_table *rt; struct bwi_retry_lim lim; uint16_t cw_min; @@ -1366,14 +1369,21 @@ /* * XXX MAC level acknowledge and CW min/max should depend * on the char rateset of the IBSS/BSS to join. + * XXX this is all wrong; should be done on channel change */ + if (phy->phy_mode == IEEE80211_MODE_11B) { + rt = ieee80211_get_ratetable( + ieee80211_find_channel(ic, 2412, IEEE80211_CHAN_B)); + bwi_mac_set_ackrates(mac, rt, + &ic->ic_sup_rates[IEEE80211_MODE_11B]); + } else { + rt = ieee80211_get_ratetable( + ieee80211_find_channel(ic, 2412, IEEE80211_CHAN_G)); + bwi_mac_set_ackrates(mac, rt, + &ic->ic_sup_rates[IEEE80211_MODE_11G]); + } /* - * Set MAC level acknowledge rates - */ - bwi_mac_set_ackrates(mac, &ic->ic_sup_rates[phy->phy_mode]); - - /* * Set CW min */ if (phy->phy_mode == IEEE80211_MODE_11B) @@ -1406,21 +1416,22 @@ } static void -bwi_mac_set_ackrates(struct bwi_mac *mac, const struct ieee80211_rateset *rs) +bwi_mac_set_ackrates(struct bwi_mac *mac, const struct ieee80211_rate_table *rt, + const struct ieee80211_rateset *rs) { int i; /* XXX not standard conforming */ for (i = 0; i < rs->rs_nrates; ++i) { - enum ieee80211_modtype modtype; + enum ieee80211_phytype modtype; uint16_t ofs; - modtype = ieee80211_rate2modtype(rs->rs_rates[i]); + modtype = ieee80211_rate2phytype(rt, rs->rs_rates[i]); switch (modtype) { - case IEEE80211_MODTYPE_DS: + case IEEE80211_T_DS: ofs = 0x4c0; break; - case IEEE80211_MODTYPE_OFDM: + case IEEE80211_T_OFDM: ofs = 0x480; break; default: ==== //depot/projects/vap/sys/dev/bwi/if_bwi.c#8 (text+ko) ==== @@ -65,6 +65,7 @@ #include <net80211/ieee80211_radiotap.h> #include <net80211/ieee80211_regdomain.h> #include <net80211/ieee80211_amrr.h> +#include <net80211/ieee80211_phy.h> #include <net/bpf.h> @@ -523,6 +524,8 @@ ic->ic_scan_end = bwi_scan_end; ic->ic_set_channel = bwi_set_channel; + sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan); + /* * Attach bpf. */ @@ -1301,8 +1304,6 @@ bwi_enable_intrs(sc, BWI_INIT_INTRS); BWI_UNLOCK(sc); - - ieee80211_start_all(ic); /* start all vap's */ return; bad: bwi_stop(sc, 1); @@ -1317,7 +1318,7 @@ struct bwi_softc *sc = ifp->if_softc; struct ieee80211com *ic = ifp->if_l2com; struct ifreq *ifr = (struct ifreq *)req; - int error = 0; + int error = 0, startall = 0; BWI_LOCK(sc); @@ -1347,17 +1348,15 @@ } if (ifp->if_flags & IFF_UP) { - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { bwi_init(sc); + startall = 1; + } } else { if (ifp->if_drv_flags & IFF_DRV_RUNNING) bwi_stop(sc, 1); } break; - case SIOCADDMULTI: - case SIOCDELMULTI: - /* XXX */ - break; case SIOCGIFMEDIA: case SIOCSIFMEDIA: error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); @@ -1369,6 +1368,8 @@ BWI_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); return error; #undef IS_RUNNING } @@ -1715,7 +1716,7 @@ bwi_set_channel(struct ieee80211com *ic) { struct bwi_softc *sc = ic->ic_ifp->if_softc; - const struct ieee80211_channel *c = ic->ic_curchan; + struct ieee80211_channel *c = ic->ic_curchan; struct bwi_mac *mac; BWI_LOCK(sc); @@ -1724,6 +1725,8 @@ mac = (struct bwi_mac *)sc->sc_cur_regwin; bwi_rf_set_chan(mac, ieee80211_chan2ieee(ic, c), 0); + sc->sc_rates = ieee80211_get_ratetable(c); + /* * Setup radio tap channel freq and flags */ @@ -2936,18 +2939,18 @@ } static __inline void -bwi_plcp_header(void *plcp, int pkt_len, uint8_t rate) +bwi_plcp_header(const struct ieee80211_rate_table *rt, + void *plcp, int pkt_len, uint8_t rate) { - enum ieee80211_modtype modtype; + enum ieee80211_phytype modtype; /* * Assume caller has zeroed 'plcp' */ - - modtype = ieee80211_rate2modtype(rate); - if (modtype == IEEE80211_MODTYPE_OFDM) + modtype = ieee80211_rate2phytype(rt, rate); + if (modtype == IEEE80211_T_OFDM) bwi_ofdm_plcp_header(plcp, pkt_len, rate); - else if (modtype == IEEE80211_MODTYPE_DS) + else if (modtype == IEEE80211_T_DS) bwi_ds_plcp_header(plcp, pkt_len, rate); else panic("unsupport modulation type %u\n", modtype); @@ -2971,7 +2974,7 @@ uint32_t mac_ctrl; uint16_t phy_ctrl; bus_addr_t paddr; - int pkt_len, error; + int type, ismcast, pkt_len, error; #if 0 const uint8_t *p; int i; @@ -2982,6 +2985,8 @@ mac = (struct bwi_mac *)sc->sc_cur_regwin; wh = mtod(m, struct ieee80211_frame *); + type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; + ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); /* Get 802.11 frame len before prepending TX header */ pkt_len = m->m_pkthdr.len + IEEE80211_CRC_LEN; @@ -2991,13 +2996,13 @@ */ bzero(tb->tb_rate_idx, sizeof(tb->tb_rate_idx)); tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; - if (IEEE80211_IS_MULTICAST(wh->i_addr1)) + if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL)) { + rate = rate_fb = tp->mgmtrate; + } else if (ismcast) { rate = rate_fb = tp->mcastrate; - else if (m->m_flags & M_EAPOL) - rate = rate_fb = tp->mgmtrate; - else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) + } else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) { rate = rate_fb = tp->ucastrate; - else { + } else { tb->tb_rate_idx[0] = ieee80211_amrr_choose(ni, &BWI_NODE(ni)->amn); rate = ni->ni_txrate; @@ -3020,7 +3025,7 @@ sc->sc_tx_th.wt_flags = 0; if (wh->i_fc[1] & IEEE80211_FC1_WEP) sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP; - if (ieee80211_rate2modtype(rate) == IEEE80211_MODTYPE_DS && + if (ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_DS && (ic->ic_flags & IEEE80211_F_SHPREAMBLE) && rate != (1 * 2)) { sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; @@ -3045,14 +3050,11 @@ bcopy(wh->i_fc, hdr->txh_fc, sizeof(hdr->txh_fc)); bcopy(wh->i_addr1, hdr->txh_addr1, sizeof(hdr->txh_addr1)); - if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { + if (!ismcast) { uint16_t dur; - uint8_t ack_rate; - ack_rate = ieee80211_ack_rate(ni, rate_fb); - dur = ieee80211_txtime(ni, - sizeof(struct ieee80211_frame_ack) + IEEE80211_CRC_LEN, - ack_rate, ic->ic_flags & ~IEEE80211_F_SHPREAMBLE); + dur = ieee80211_ack_duration(sc->sc_rates, rate, + ic->ic_flags & ~IEEE80211_F_SHPREAMBLE); hdr->txh_fb_duration = htole16(dur); } @@ -3060,20 +3062,20 @@ hdr->txh_id = __SHIFTIN(BWI_TX_DATA_RING, BWI_TXH_ID_RING_MASK) | __SHIFTIN(idx, BWI_TXH_ID_IDX_MASK); - bwi_plcp_header(hdr->txh_plcp, pkt_len, rate); - bwi_plcp_header(hdr->txh_fb_plcp, pkt_len, rate_fb); + bwi_plcp_header(sc->sc_rates, hdr->txh_plcp, pkt_len, rate); + bwi_plcp_header(sc->sc_rates, hdr->txh_fb_plcp, pkt_len, rate_fb); phy_ctrl = __SHIFTIN(mac->mac_rf.rf_ant_mode, BWI_TXH_PHY_C_ANTMODE_MASK); - if (ieee80211_rate2modtype(rate) == IEEE80211_MODTYPE_OFDM) + if (ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM) phy_ctrl |= BWI_TXH_PHY_C_OFDM; else if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && rate != (2 * 1)) phy_ctrl |= BWI_TXH_PHY_C_SHPREAMBLE; mac_ctrl = BWI_TXH_MAC_C_HWSEQ | BWI_TXH_MAC_C_FIRST_FRAG; - if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) + if (!ismcast) mac_ctrl |= BWI_TXH_MAC_C_ACK; - if (ieee80211_rate2modtype(rate_fb) == IEEE80211_MODTYPE_OFDM) + if (ieee80211_rate2phytype(sc->sc_rates, rate_fb) == IEEE80211_T_OFDM) mac_ctrl |= BWI_TXH_MAC_C_FB_OFDM; hdr->txh_mac_ctrl = htole32(mac_ctrl); @@ -3218,13 +3220,8 @@ mac_ctrl = BWI_TXH_MAC_C_HWSEQ | BWI_TXH_MAC_C_FIRST_FRAG; if (!ismcast && (params->ibp_flags & IEEE80211_BPF_NOACK) == 0) { uint16_t dur; - uint8_t ack_rate; - /* XXX rate_fb? */ - ack_rate = ieee80211_ack_rate(ni, rate_fb); - dur = ieee80211_txtime(ni, - sizeof(struct ieee80211_frame_ack) + IEEE80211_CRC_LEN, - ack_rate, 0); + dur = ieee80211_ack_duration(sc->sc_rates, rate_fb, 0); hdr->txh_fb_duration = htole16(dur); mac_ctrl |= BWI_TXH_MAC_C_ACK; @@ -3233,12 +3230,12 @@ hdr->txh_id = __SHIFTIN(BWI_TX_DATA_RING, BWI_TXH_ID_RING_MASK) | __SHIFTIN(idx, BWI_TXH_ID_IDX_MASK); - bwi_plcp_header(hdr->txh_plcp, pkt_len, rate); - bwi_plcp_header(hdr->txh_fb_plcp, pkt_len, rate_fb); + bwi_plcp_header(sc->sc_rates, hdr->txh_plcp, pkt_len, rate); + bwi_plcp_header(sc->sc_rates, hdr->txh_fb_plcp, pkt_len, rate_fb); phy_ctrl = __SHIFTIN(mac->mac_rf.rf_ant_mode, BWI_TXH_PHY_C_ANTMODE_MASK); - if (ieee80211_rate2modtype(rate) == IEEE80211_MODTYPE_OFDM) { + if (ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM) { phy_ctrl |= BWI_TXH_PHY_C_OFDM; mac_ctrl |= BWI_TXH_MAC_C_FB_OFDM; } else if (params->ibp_flags & IEEE80211_BPF_SHORTPRE) @@ -3798,8 +3795,6 @@ return bwi_rf_calc_rssi(mac, hdr); } -extern uint8_t ieee80211_plcp2rate(uint8_t, int); /* XXX temp */ - static __inline uint8_t bwi_ofdm_plcp2rate(const uint32_t *plcp0) { @@ -4052,163 +4047,6 @@ sc->sc_led_blinking = 0; } -enum ieee80211_modtype -ieee80211_rate2modtype(uint8_t rate) -{ - rate &= IEEE80211_RATE_VAL; - if (rate == 22 || rate < 12) - return IEEE80211_MODTYPE_DS; - else if (rate == 44) - return IEEE80211_MODTYPE_PBCC; - 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; - enum ieee80211_modtype modtype; - int i; - - rate &= IEEE80211_RATE_VAL; - - modtype = ieee80211_rate2modtype(rate); - - for (i = 0; i < rs->rs_nrates; ++i) { - uint8_t rate1 = rs->rs_rates[i] & IEEE80211_RATE_VAL; - - 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; -} - -/* IEEE Std 802.11a-1999, page 9, table 79 */ -#define IEEE80211_OFDM_SYM_TIME 4 -#define IEEE80211_OFDM_PREAMBLE_TIME 16 -#define IEEE80211_OFDM_SIGNAL_TIME 4 -/* IEEE Std 802.11g-2003, page 44 */ -#define IEEE80211_OFDM_SIGNAL_EXT_TIME 6 - -/* IEEE Std 802.11a-1999, page 7, figure 107 */ -#define IEEE80211_OFDM_PLCP_SERVICE_NBITS 16 -#define IEEE80211_OFDM_TAIL_NBITS 6 - -#define IEEE80211_OFDM_NBITS(frmlen) \ - (IEEE80211_OFDM_PLCP_SERVICE_NBITS + \ - ((frmlen) * NBBY) + \ - IEEE80211_OFDM_TAIL_NBITS) - -#define IEEE80211_OFDM_NBITS_PER_SYM(kbps) \ - (((kbps) * IEEE80211_OFDM_SYM_TIME) / 1000) - -#define IEEE80211_OFDM_NSYMS(kbps, frmlen) \ - howmany(IEEE80211_OFDM_NBITS((frmlen)), \ - IEEE80211_OFDM_NBITS_PER_SYM((kbps))) - -#define IEEE80211_OFDM_TXTIME(kbps, frmlen) \ - (IEEE80211_OFDM_PREAMBLE_TIME + \ - IEEE80211_OFDM_SIGNAL_TIME + \ - (IEEE80211_OFDM_NSYMS((kbps), (frmlen)) * IEEE80211_OFDM_SYM_TIME)) - -/* IEEE Std 802.11b-1999, page 28, subclause 18.3.4 */ -#define IEEE80211_CCK_PREAMBLE_LEN 144 -#define IEEE80211_CCK_PLCP_HDR_TIME 48 -#define IEEE80211_CCK_SHPREAMBLE_LEN 72 -#define IEEE80211_CCK_SHPLCP_HDR_TIME 24 - -#define IEEE80211_CCK_NBITS(frmlen) ((frmlen) * NBBY) -#define IEEE80211_CCK_TXTIME(kbps, frmlen) \ - (((IEEE80211_CCK_NBITS((frmlen)) * 1000) + (kbps) - 1) / (kbps)) - -uint16_t -ieee80211_txtime(struct ieee80211_node *ni, u_int len, uint8_t rs_rate, - uint32_t flags) -{ - struct ieee80211com *ic = ni->ni_ic; - enum ieee80211_modtype modtype; - uint16_t txtime; - int rate; - - rs_rate &= IEEE80211_RATE_VAL; - - rate = rs_rate * 500; /* ieee80211 rate -> kbps */ - - modtype = ieee80211_rate2modtype(rs_rate); - if (modtype == IEEE80211_MODTYPE_OFDM) { - /* - * IEEE Std 802.11a-1999, page 37, equation (29) - * IEEE Std 802.11g-2003, page 44, equation (42) - */ - txtime = IEEE80211_OFDM_TXTIME(rate, len); - if (ic->ic_curmode == IEEE80211_MODE_11G) - txtime += IEEE80211_OFDM_SIGNAL_EXT_TIME; - } else { - /* - * IEEE Std 802.11b-1999, page 28, subclause 18.3.4 - * IEEE Std 802.11g-2003, page 45, equation (43) - */ - if (modtype == IEEE80211_MODTYPE_PBCC) - ++len; - txtime = IEEE80211_CCK_TXTIME(rate, len); - - /* - * Short preamble is not applicable for DS 1Mbits/s - */ - if (rs_rate != 2 && (flags & IEEE80211_F_SHPREAMBLE)) { - txtime += IEEE80211_CCK_SHPREAMBLE_LEN + - IEEE80211_CCK_SHPLCP_HDR_TIME; - } else { - txtime += IEEE80211_CCK_PREAMBLE_LEN + - IEEE80211_CCK_PLCP_HDR_TIME; - } - } - return txtime; -} - static void bwi_restart(void *xsc, int pending) { ==== //depot/projects/vap/sys/dev/bwi/if_bwivar.h#5 (text+ko) ==== @@ -609,6 +609,7 @@ struct bwi_txstats_data *sc_txstats; int sc_tx_timer; + const struct ieee80211_rate_table *sc_rates; struct bwi_tx_radiotap_hdr sc_tx_th; int sc_tx_th_len; @@ -697,38 +698,6 @@ #define abs(a) __builtin_abs(a) -enum ieee80211_modtype { - IEEE80211_MODTYPE_DS, - IEEE80211_MODTYPE_PBCC, - IEEE80211_MODTYPE_OFDM -}; -#define IEEE80211_MODTYPE_CCK IEEE80211_MODTYPE_DS - -/* - * Contention window (slots). - */ -#define IEEE80211_CW_MAX 1023 /* aCWmax */ -#define IEEE80211_CW_MIN_0 31 /* DS/CCK aCWmin, ERP aCWmin(0) */ -#define IEEE80211_CW_MIN_1 15 /* OFDM aCWmin, ERP aCWmin(1) */ - -/* - * SIFS (microseconds). - */ -#define IEEE80211_DUR_SIFS 10 /* DS/CCK/ERP SIFS */ -#define IEEE80211_DUR_OFDM_SIFS 16 /* OFDM SIFS */ - -/* - * Slot time (microseconds). - */ -#define IEEE80211_DUR_SLOT 20 /* DS/CCK slottime, ERP long slottime */ -#define IEEE80211_DUR_SHSLOT 9 /* ERP short slottime */ -#define IEEE80211_DUR_OFDM_SLOT 9 /* OFDM slottime */ - -/* - * DIFS (microseconds). - */ -#define IEEE80211_DUR_DIFS(sifs, slot) ((sifs) + 2 * (slot)) - /* XXX does not belong here */ struct ieee80211_ds_plcp_hdr { uint8_t i_signal; @@ -737,9 +706,4 @@ uint16_t i_crc; } __packed; -enum ieee80211_modtype ieee80211_rate2modtype(uint8_t rate); -uint8_t ieee80211_ack_rate(struct ieee80211_node *ni, uint8_t rate); -uint16_t ieee80211_txtime(struct ieee80211_node *ni, u_int len, - uint8_t rs_rate, uint32_t flags); - #endif /* !_IF_BWIVAR_H */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200804190252.m3J2qOAI031612>