Date: Fri, 5 Oct 2007 04:56:12 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 127216 for review Message-ID: <200710050456.l954uCTX047861@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=127216 Change 127216 by sam@sam_ebb on 2007/10/05 04:55:38 Checkpoint work: o add amrr rate control; need to check if data_txcnt is the retry count (for now assume it's tries and -1) o hold node for tx mgt frames and implement M_TXCB o fix 4-byte register read that should be 2 bytes (noticed in obsd commit) Affected files ... .. //depot/projects/wifi/sys/dev/bwi/bwimac.c#2 edit .. //depot/projects/wifi/sys/dev/bwi/bwiphy.c#2 edit .. //depot/projects/wifi/sys/dev/bwi/bwirf.c#2 edit .. //depot/projects/wifi/sys/dev/bwi/if_bwi.c#2 edit .. //depot/projects/wifi/sys/dev/bwi/if_bwi_pci.c#2 edit .. //depot/projects/wifi/sys/dev/bwi/if_bwivar.h#2 edit Differences ... ==== //depot/projects/wifi/sys/dev/bwi/bwimac.c#2 (text+ko) ==== @@ -64,6 +64,7 @@ #include <net80211/ieee80211_var.h> #include <net80211/ieee80211_radiotap.h> +#include <net80211/ieee80211_amrr.h> #include <machine/bus.h> @@ -345,7 +346,7 @@ /* * Initialize PHY */ - CSR_WRITE_4(sc, BWI_BBP_ATTEN, 0); + CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0); bwi_phy_init(mac); /* TODO: interference mitigation */ ==== //depot/projects/wifi/sys/dev/bwi/bwiphy.c#2 (text+ko) ==== @@ -61,6 +61,7 @@ #include <net80211/ieee80211_var.h> #include <net80211/ieee80211_radiotap.h> +#include <net80211/ieee80211_amrr.h> #include <machine/bus.h> ==== //depot/projects/wifi/sys/dev/bwi/bwirf.c#2 (text+ko) ==== @@ -61,6 +61,7 @@ #include <net80211/ieee80211_var.h> #include <net80211/ieee80211_radiotap.h> +#include <net80211/ieee80211_amrr.h> #include <machine/bus.h> ==== //depot/projects/wifi/sys/dev/bwi/if_bwi.c#2 (text+ko) ==== @@ -62,6 +62,7 @@ #include <net80211/ieee80211_var.h> #include <net80211/ieee80211_radiotap.h> #include <net80211/ieee80211_regdomain.h> +#include <net80211/ieee80211_amrr.h> #include <net/bpf.h> @@ -100,6 +101,9 @@ static void bwi_scan_end(struct ieee80211com *); static int bwi_newstate(struct ieee80211com *, enum ieee80211_state, int); static void bwi_updateslot(struct ifnet *); +static struct ieee80211_node *bwi_node_alloc(struct ieee80211_node_table *); +static void bwi_newassoc(struct ieee80211_node *, int); +static void bwi_amrr_timeout(void *); static int bwi_media_change(struct ifnet *); static void bwi_calibrate(void *); @@ -355,6 +359,7 @@ device_get_unit(sc->sc_dev)); callout_init(&sc->sc_calib_ch, CALLOUT_MPSAFE); + callout_init(&sc->sc_amrr_ch, CALLOUT_MPSAFE); ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; @@ -428,8 +433,13 @@ ic->ic_scan_start = bwi_scan_start; ic->ic_scan_end = bwi_scan_end; ic->ic_set_channel = bwi_set_channel; + ic->ic_node_alloc = bwi_node_alloc; + ic->ic_newassoc = bwi_newassoc; /* complete initialization */ ieee80211_media_init(ic, bwi_media_change, ieee80211_media_status); + ieee80211_amrr_init(&sc->sc_amrr, ic, + IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, + IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD); /* * Attach radio tap @@ -462,6 +472,7 @@ int i; bwi_stop(sc); + callout_stop(&sc->sc_amrr_ch); ieee80211_ifdetach(&sc->sc_ic); for (i = 0; i < sc->sc_nmac; ++i) @@ -1207,14 +1218,11 @@ struct ieee80211_frame *wh; struct ieee80211_node *ni; struct mbuf *m; - int mgt_pkt = 0; IF_DEQUEUE(&ic->ic_mgtq, m); if (m != NULL) { ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; m->m_pkthdr.rcvif = NULL; - - mgt_pkt = 1; } else { struct ether_header *eh; @@ -1267,11 +1275,6 @@ } wh = NULL; /* Catch any invalid use */ - if (mgt_pkt) { - ieee80211_free_node(ni); - ni = NULL; - } - if (bwi_encap(sc, idx, m, ni) != 0) { /* 'm' is freed in bwi_encap() if we reach here */ if (ni != NULL) @@ -1520,6 +1523,7 @@ BWI_LOCK(sc); callout_stop(&sc->sc_calib_ch); + callout_stop(&sc->sc_amrr_ch); if (nstate == IEEE80211_S_INIT) goto back; @@ -1537,6 +1541,11 @@ /* Initial TX power calibration */ bwi_mac_calibrate_txpower(mac); + + /* start automatic rate control timer */ + if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) + callout_reset(&sc->sc_amrr_ch, hz / 2, + bwi_amrr_timeout, sc); } else { bwi_set_bssid(sc, bwi_zero_addr); } @@ -1553,6 +1562,56 @@ return error; } +/* ARGUSED */ +static struct ieee80211_node * +bwi_node_alloc(struct ieee80211_node_table *nt __unused) +{ + struct bwi_node *bn; + + bn = malloc(sizeof(struct bwi_node), M_80211_NODE, M_NOWAIT | M_ZERO); + return bn != NULL ? &bn->ni : NULL; +} + +static void +bwi_newassoc(struct ieee80211_node *ni, int isnew) +{ + struct bwi_softc *sc = ni->ni_ic->ic_ifp->if_softc; + int i; + + ieee80211_amrr_node_init(&sc->sc_amrr, &((struct bwi_node *)ni)->amn); + + /* set rate to some reasonable initial value */ + for (i = ni->ni_rates.rs_nrates - 1; + i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72; + i--); + ni->ni_txrate = i; +} + +static void +bwi_iter_func(void *arg, struct ieee80211_node *ni) +{ + struct bwi_softc *sc = arg; + struct bwi_node *bn = (struct bwi_node *)ni; + + ieee80211_amrr_choose(&sc->sc_amrr, ni, &bn->amn); +} + +static void +bwi_amrr_timeout(void *arg) +{ + struct bwi_softc *sc = arg; + struct ieee80211com *ic = &sc->sc_ic; + + BWI_LOCK(sc); + if (ic->ic_opmode == IEEE80211_M_STA) + bwi_iter_func(sc, ic->ic_bss); + else + ieee80211_iterate_nodes(&ic->ic_sta, bwi_iter_func, sc); + BWI_UNLOCK(sc); + + callout_reset(&sc->sc_amrr_ch, hz / 2, bwi_amrr_timeout, sc); +} + static int bwi_media_change(struct ifnet *ifp) { @@ -2736,28 +2795,15 @@ * Find TX rate */ bzero(tb->tb_rate_idx, sizeof(tb->tb_rate_idx)); - if (ni != NULL) { - if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) { - /* NB: no fallback */ - rate = rate_fb = ic->ic_fixed_rate; - } else { - /* TODO: TX rate control */ - rate = rate_fb = (1 * 2); - } - } else { - /* Fixed at 1Mbits/s for mgt frames */ - rate = rate_fb = (1 * 2); - } - if (IEEE80211_IS_MULTICAST(wh->i_addr1)) rate = rate_fb = ic->ic_mcast_rate; + else if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) { + rate = ni->ni_rates.rs_rates[ni->ni_txrate] & IEEE80211_RATE_VAL; + rate_fb = (ni->ni_txrate > 0) ? + ni->ni_rates.rs_rates[ni->ni_txrate-1] & IEEE80211_RATE_VAL : rate; + } else + rate = rate_fb = ic->ic_fixed_rate; - if (rate == 0 || rate_fb == 0) { - if_printf(ic->ic_ifp, "invalid rate %u or fallback rate %u", - rate, rate_fb); - rate = rate_fb = (1 * 2); /* Force 1Mbits/s */ - } - /* * TX radio tap */ @@ -2790,14 +2836,14 @@ bcopy(wh->i_fc, hdr->txh_fc, sizeof(hdr->txh_fc)); bcopy(wh->i_addr1, hdr->txh_addr1, sizeof(hdr->txh_addr1)); - if (ni != NULL && !IEEE80211_IS_MULTICAST(wh->i_addr1)) { + if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 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); + sizeof(struct ieee80211_frame_ack) + IEEE80211_CRC_LEN, + ack_rate, ic->ic_flags & ~IEEE80211_F_SHPREAMBLE); hdr->txh_fb_duration = htole16(dur); } @@ -2940,6 +2986,7 @@ struct bwi_txbuf_data *tbd; struct bwi_txbuf *tb; int ring_idx, buf_idx; + struct ieee80211_node *ni; if (tx_id == 0) { if_printf(ifp, "zero tx id\n"); @@ -2966,14 +3013,30 @@ tb = &tbd->tbd_buf[buf_idx]; bus_dmamap_unload(sc->sc_buf_dtag, tb->tb_dmap); - m_freem(tb->tb_mbuf); - tb->tb_mbuf = NULL; + ni = tb->tb_ni; if (tb->tb_ni != NULL) { + struct bwi_node *bn = (struct bwi_node *) tb->tb_ni; + + /* XXX only for unicast frames */ /* Feed back 'acked and data_txcnt' */ + if (acked) + bn->amn.amn_success++; + bn->amn.amn_txcnt++; + bn->amn.amn_retrycnt += data_txcnt-1; + + /* + * Do any tx complete callback. Note this must + * be done before releasing the node reference. + */ + if (tb->tb_mbuf->m_flags & M_TXCB) + ieee80211_process_callback(ni, tb->tb_mbuf, !acked); + ieee80211_free_node(tb->tb_ni); tb->tb_ni = NULL; } + m_freem(tb->tb_mbuf); + tb->tb_mbuf = NULL; if (tbd->tbd_used == 0) sc->sc_tx_timer = 0; ==== //depot/projects/wifi/sys/dev/bwi/if_bwi_pci.c#2 (text+ko) ==== @@ -55,6 +55,7 @@ #include <net80211/ieee80211_var.h> #include <net80211/ieee80211_radiotap.h> +#include <net80211/ieee80211_amrr.h> #include <dev/pci/pcivar.h> #include <dev/pci/pcireg.h> @@ -285,3 +286,4 @@ MODULE_VERSION(if_bwi, 1); MODULE_DEPEND(if_bwi, wlan, 1, 1, 1); /* 802.11 media layer */ MODULE_DEPEND(if_bwi, firmware, 1, 1, 1); /* firmware support */ +MODULE_DEPEND(if_bwi, wlan_amrr, 1, 1, 1); ==== //depot/projects/wifi/sys/dev/bwi/if_bwivar.h#2 (text+ko) ==== @@ -488,9 +488,15 @@ /* TODO: sq */ }; +struct bwi_node { + struct ieee80211_node ni; /* must be the first */ + struct ieee80211_amrr_node amn; +}; + struct bwi_softc { struct ifnet *sc_ifp; struct ieee80211com sc_ic; + struct ieee80211_amrr sc_amrr; uint32_t sc_flags; /* BWI_F_ */ device_t sc_dev; struct mtx sc_mtx; @@ -520,6 +526,7 @@ bus_space_handle_t sc_mem_bh; struct callout sc_calib_ch; + struct callout sc_amrr_ch; struct bwi_regwin *sc_cur_regwin; struct bwi_regwin sc_com_regwin;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200710050456.l954uCTX047861>