PERFORCE change 140233 for review
Sam Leffler
sam at FreeBSD.org
Sat Apr 19 02:52:25 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=140233
Change 140233 by sam at 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 */
More information about the p4-projects
mailing list