PERFORCE change 127216 for review
Sam Leffler
sam at FreeBSD.org
Thu Oct 4 21:56:14 PDT 2007
http://perforce.freebsd.org/chv.cgi?CH=127216
Change 127216 by sam at 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;
More information about the p4-projects
mailing list