PERFORCE change 137687 for review

Sam Leffler sam at FreeBSD.org
Fri Mar 14 05:28:17 UTC 2008


http://perforce.freebsd.org/chv.cgi?CH=137687

Change 137687 by sam at sam_ebb on 2008/03/14 05:27:25

	o track amrr changes
	o add gross hack for dealing with newstate broken-ness (must
	  be fixed before stuff moves to cvs)
	o reorder code in detach to avoid races

Affected files ...

.. //depot/projects/vap/sys/dev/usb/if_rum.c#9 edit
.. //depot/projects/vap/sys/dev/usb/if_rumvar.h#6 edit
.. //depot/projects/vap/sys/dev/usb/if_ural.c#11 edit
.. //depot/projects/vap/sys/dev/usb/if_uralvar.h#8 edit

Differences ...

==== //depot/projects/vap/sys/dev/usb/if_rum.c#9 (text+ko) ====

@@ -195,6 +195,8 @@
 			    struct ieee80211vap *);
 static int		rum_raw_xmit(struct ieee80211_node *, struct mbuf *,
 			    const struct ieee80211_bpf_params *);
+static struct ieee80211_node *rum_node_alloc(struct ieee80211_node_table *);
+static void		rum_newassoc(struct ieee80211_node *, int);
 static void		rum_scan_start(struct ieee80211com *);
 static void		rum_scan_end(struct ieee80211com *);
 static void		rum_set_channel(struct ieee80211com *);
@@ -512,7 +514,9 @@
 	ieee80211_init_channels(ic, NULL, &bands);
 
 	ieee80211_ifattach(ic);
+	ic->ic_newassoc = rum_newassoc;
 	ic->ic_raw_xmit = rum_raw_xmit;
+	ic->ic_node_alloc = rum_node_alloc;
 	ic->ic_scan_start = rum_scan_start;
 	ic->ic_scan_end = rum_scan_end;
 	ic->ic_set_channel = rum_set_channel;
@@ -545,6 +549,9 @@
 	struct ifnet *ifp = ic->ic_ifp;
 
 	rum_stop(sc);
+	bpfdetach(ifp);
+	ieee80211_ifdetach(ic);
+
 	usb_rem_task(sc->sc_udev, &sc->sc_task);
 	usb_rem_task(sc->sc_udev, &sc->sc_scantask);
 	callout_stop(&sc->watchdog_ch);
@@ -566,10 +573,7 @@
 	rum_free_rx_list(sc);
 	rum_free_tx_list(sc);
 
-	bpfdetach(ifp);
-	ieee80211_ifdetach(ic);
 	if_free(ifp);
-
 	mtx_destroy(&sc->sc_mtx);
 
 	return 0;
@@ -602,7 +606,8 @@
 	callout_init(&rvp->amrr_ch, 0);
 	ieee80211_amrr_init(&rvp->amrr, vap,
 	    IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
-	    IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD);
+	    IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
+	    1000 /* 1 sec */);
 
 	/* complete setup */
 	ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
@@ -616,6 +621,7 @@
 	struct rum_vap *rvp = RUM_VAP(vap);
 
 	callout_stop(&rvp->amrr_ch);
+	ieee80211_amrr_cleanup(&rvp->amrr);
 	ieee80211_vap_detach(vap);
 	free(rvp, M_80211_VAP);
 }
@@ -784,10 +790,9 @@
 		if (vap->iv_opmode != IEEE80211_M_MONITOR)
 			rum_enable_tsf_sync(sc);
 
-		/* enable automatic rate adaptation in STA mode */
+		/* enable automatic rate adaptation */
 		tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
-		if (vap->iv_opmode == IEEE80211_M_STA &&
-		    tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
+		if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
 			rum_amrr_start(sc, ni);
 		break;
 	default:
@@ -796,7 +801,14 @@
 
 	RUM_UNLOCK(sc);
 
+	IEEE80211_LOCK(ic);	/*XXX*/
 	rvp->newstate(vap, sc->sc_state, sc->sc_arg);
+	if (sc->sc_state == IEEE80211_S_RUN) {
+		/* XXX compensate for deferred handling of newstate */
+		vap->iv_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+		if_start(vap->iv_ifp);
+	}
+	IEEE80211_UNLOCK(ic);
 }
 
 static int
@@ -1300,8 +1312,10 @@
 		rate = tp->mcastrate;
 	else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
 		rate = tp->ucastrate;
-	else
-		rate = ni->ni_rates.rs_rates[ni->ni_txrate];
+	else {
+		(void) ieee80211_amrr_choose(ni, &RUM_NODE(ni)->amn);
+		rate = ni->ni_txrate;
+	}
 
 	rate &= IEEE80211_RATE_VAL;
 
@@ -2303,19 +2317,12 @@
 {
 	struct ieee80211vap *vap = ni->ni_vap;
 	struct rum_vap *rvp = RUM_VAP(vap);
-	int i;
 
 	/* clear statistic registers (STA_CSR0 to STA_CSR5) */
 	rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta);
 
-	ieee80211_amrr_node_init(&rvp->amrr, &rvp->amn);
+	ieee80211_amrr_node_init(&rvp->amrr, &RUM_NODE(ni)->amn, ni);
 
-	/* 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;
-
 	callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, vap);
 }
 
@@ -2349,6 +2356,7 @@
 	struct rum_vap *rvp = RUM_VAP(vap);
 	struct ifnet *ifp = vap->iv_ic->ic_ifp;
 	struct rum_softc *sc = ifp->if_softc;
+	int ok, fail;
 
 	if (status != USBD_NORMAL_COMPLETION) {
 		device_printf(sc->sc_dev, "could not retrieve Tx statistics - "
@@ -2356,21 +2364,34 @@
 		return;
 	}
 
-	/* count TX retry-fail as Tx errors */
-	ifp->if_oerrors += le32toh(sc->sta[5]) >> 16;
+	ok = (le32toh(sc->sta[4]) >> 16) +	/* TX ok w/o retry */
+	    (le32toh(sc->sta[5]) & 0xffff);	/* TX ok w/ retry */
+	fail = (le32toh(sc->sta[5]) >> 16);	/* TX retry-fail count */
+
+	ieee80211_amrr_tx_update(&RUM_NODE(vap->iv_bss)->amn,
+	    ok+fail, ok, (le32toh(sc->sta[5]) & 0xffff) + fail);
+
+	ifp->if_oerrors += fail;	/* count TX retry-fail as Tx errors */
+
+	callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, vap);
+}
 
-	rvp->amn.amn_retrycnt =
-	    (le32toh(sc->sta[4]) >> 16) +	/* TX one-retry ok count */
-	    (le32toh(sc->sta[5]) & 0xffff) +	/* TX more-retry ok count */
-	    (le32toh(sc->sta[5]) >> 16);	/* TX retry-fail count */
+/* ARGUSED */
+static struct ieee80211_node *
+rum_node_alloc(struct ieee80211_node_table *nt __unused)
+{
+	struct rum_node *rn;
 
-	rvp->amn.amn_txcnt =
-	    rvp->amn.amn_retrycnt +
-	    (le32toh(sc->sta[4]) & 0xffff);	/* TX no-retry ok count */
+	rn = malloc(sizeof(struct rum_node), M_80211_NODE, M_NOWAIT | M_ZERO);
+	return rn != NULL ? &rn->ni : NULL;
+}
 
-	ieee80211_amrr_choose(&rvp->amrr, vap->iv_bss, &rvp->amn);
+static void
+rum_newassoc(struct ieee80211_node *ni, int isnew)
+{
+	struct ieee80211vap *vap = ni->ni_vap;
 
-	callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, vap);
+	ieee80211_amrr_node_init(&RUM_VAP(vap)->amrr, &RUM_NODE(ni)->amn, ni);
 }
 
 static void

==== //depot/projects/vap/sys/dev/usb/if_rumvar.h#6 (text+ko) ====

@@ -69,11 +69,16 @@
 	struct mbuf		*m;
 };
 
+struct rum_node {
+	struct ieee80211_node	ni;
+	struct ieee80211_amrr_node amn;
+};
+#define	RUM_NODE(ni)	((struct rum_node *)(ni))
+
 struct rum_vap {
 	struct ieee80211vap		vap;
 	struct ieee80211_beacon_offsets	bo;
 	struct ieee80211_amrr		amrr;
-	struct ieee80211_amrr_node	amn;
 	struct callout			amrr_ch;
 
 	int				(*newstate)(struct ieee80211vap *,

==== //depot/projects/vap/sys/dev/usb/if_ural.c#11 (text+ko) ====

@@ -159,6 +159,8 @@
 static void		ural_bbp_write(struct ural_softc *, uint8_t, uint8_t);
 static uint8_t		ural_bbp_read(struct ural_softc *, uint8_t);
 static void		ural_rf_write(struct ural_softc *, uint8_t, uint32_t);
+static struct ieee80211_node *ural_node_alloc(struct ieee80211_node_table *);
+static void		ural_newassoc(struct ieee80211_node *, int);
 static void		ural_scan_start(struct ieee80211com *);
 static void		ural_scan_end(struct ieee80211com *);
 static void		ural_set_channel(struct ieee80211com *);
@@ -501,7 +503,9 @@
 	ieee80211_init_channels(ic, NULL, &bands);
 
 	ieee80211_ifattach(ic);
+	ic->ic_newassoc = ural_newassoc;
 	ic->ic_raw_xmit = ural_raw_xmit;
+	ic->ic_node_alloc = ural_node_alloc;
 	ic->ic_scan_start = ural_scan_start;
 	ic->ic_scan_end = ural_scan_end;
 	ic->ic_set_channel = ural_set_channel;
@@ -534,6 +538,9 @@
 	struct ifnet *ifp = ic->ic_ifp;
 
 	ural_stop(sc);
+	bpfdetach(ifp);
+	ieee80211_ifdetach(ic);
+
 	usb_rem_task(sc->sc_udev, &sc->sc_task);
 	callout_stop(&sc->watchdog_ch);
 
@@ -555,10 +562,7 @@
 	ural_free_rx_list(sc);
 	ural_free_tx_list(sc);
 
-	bpfdetach(ifp);
-	ieee80211_ifdetach(ic);
 	if_free(ifp);
-
 	mtx_destroy(&sc->sc_mtx);
 
 	return 0;
@@ -591,7 +595,8 @@
 	callout_init(&uvp->amrr_ch, 0);
 	ieee80211_amrr_init(&uvp->amrr, vap,
 	    IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
-	    IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD);
+	    IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
+	    1000 /* 1 sec */);
 
 	/* complete setup */
 	ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
@@ -605,6 +610,7 @@
 	struct ural_vap *uvp = URAL_VAP(vap);
 
 	callout_stop(&uvp->amrr_ch);
+	ieee80211_amrr_cleanup(&uvp->amrr);
 	ieee80211_vap_detach(vap);
 	free(uvp, M_80211_VAP);
 }
@@ -789,10 +795,9 @@
 		if (vap->iv_opmode != IEEE80211_M_MONITOR)
 			ural_enable_tsf_sync(sc);
 
-		/* enable automatic rate adaptation in STA mode */
+		/* enable automatic rate adaptation */
 		tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
-		if (vap->iv_opmode == IEEE80211_M_STA &&
-		    tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
+		if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
 			ural_amrr_start(sc, ni);
 
 		break;
@@ -805,6 +810,11 @@
 
 	IEEE80211_LOCK(ic);	/*XXX*/
 	uvp->newstate(vap, sc->sc_state, sc->sc_arg);
+	if (sc->sc_state == IEEE80211_S_RUN) {
+		/* XXX compensate for deferred handling of newstate */
+		vap->iv_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+		if_start(vap->iv_ifp);
+	}
 	IEEE80211_UNLOCK(ic);
 }
 
@@ -1406,8 +1416,7 @@
 	else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
 		rate = tp->ucastrate;
 	else
-		rate = ni->ni_rates.rs_rates[ni->ni_txrate];
-	rate &= IEEE80211_RATE_VAL;
+		rate = ni->ni_txrate;
 
 	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
 		k = ieee80211_crypto_encap(ni, m0);
@@ -1751,7 +1760,25 @@
 	DPRINTFN(15, ("RF R[%u] <- 0x%05x\n", reg & 0x3, val & 0xfffff));
 }
 
+/* ARGUSED */
+static struct ieee80211_node *
+ural_node_alloc(struct ieee80211_node_table *nt __unused)
+{
+	struct ural_node *un;
+
+	un = malloc(sizeof(struct ural_node), M_80211_NODE, M_NOWAIT | M_ZERO);
+	return un != NULL ? &un->ni : NULL;
+}
+
 static void
+ural_newassoc(struct ieee80211_node *ni, int isnew)
+{
+	struct ieee80211vap *vap = ni->ni_vap;
+
+	ieee80211_amrr_node_init(&URAL_VAP(vap)->amrr, &URAL_NODE(ni)->amn, ni);
+}
+
+static void
 ural_scan_start(struct ieee80211com *ic)
 {
 	struct ural_softc *sc = ic->ic_ifp->if_softc;
@@ -2403,19 +2430,12 @@
 {
 	struct ieee80211vap *vap = ni->ni_vap;
 	struct ural_vap *uvp = URAL_VAP(vap);
-	int i;
 
 	/* clear statistic registers (STA_CSR0 to STA_CSR10) */
 	ural_read_multi(sc, RAL_STA_CSR0, sc->sta, sizeof sc->sta);
 
-	ieee80211_amrr_node_init(&uvp->amrr, &uvp->amn);
+	ieee80211_amrr_node_init(&uvp->amrr, &URAL_NODE(ni)->amn, ni);
 
-	/* 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;
-
 	callout_reset(&uvp->amrr_ch, hz, ural_amrr_timeout, vap);
 }
 
@@ -2449,6 +2469,8 @@
 	struct ural_vap *uvp = URAL_VAP(vap);
 	struct ifnet *ifp = vap->iv_ic->ic_ifp;
 	struct ural_softc *sc = ifp->if_softc;
+	struct ieee80211_node *ni = vap->iv_bss;
+	int ok, fail;
 
 	if (status != USBD_NORMAL_COMPLETION) {
 		device_printf(sc->sc_dev, "could not retrieve Tx statistics - "
@@ -2456,19 +2478,15 @@
 		return;
 	}
 
-	/* count TX retry-fail as Tx errors */
-	ifp->if_oerrors += sc->sta[9];
+	ok = sc->sta[7] +		/* TX ok w/o retry */
+	     sc->sta[8];		/* TX ok w/ retry */
+	fail = sc->sta[9];		/* TX retry-fail count */
 
-	uvp->amn.amn_retrycnt =
-	    sc->sta[7] +	/* TX one-retry ok count */
-	    sc->sta[8] +	/* TX more-retry ok count */
-	    sc->sta[9];		/* TX retry-fail count */
+	ieee80211_amrr_tx_update(&URAL_NODE(ni)->amn,
+	    ok+fail, ok, sc->sta[8] + fail);
+	(void) ieee80211_amrr_choose(ni, &URAL_NODE(ni)->amn);
 
-	uvp->amn.amn_txcnt =
-	    uvp->amn.amn_retrycnt +
-	    sc->sta[6];		/* TX no-retry ok count */
-
-	ieee80211_amrr_choose(&uvp->amrr, vap->iv_bss, &uvp->amn);
+	ifp->if_oerrors += fail;	/* count TX retry-fail as Tx errors */
 
 	callout_reset(&uvp->amrr_ch, hz, ural_amrr_timeout, vap);
 }

==== //depot/projects/vap/sys/dev/usb/if_uralvar.h#8 (text+ko) ====

@@ -74,11 +74,16 @@
 	struct mbuf		*m;
 };
 
+struct ural_node {
+	struct ieee80211_node		ni;
+	struct ieee80211_amrr_node	amn;
+};
+#define	URAL_NODE(ni)	((struct ural_node *)(ni))
+
 struct ural_vap {
 	struct ieee80211vap		vap;
 	struct ieee80211_beacon_offsets	bo;
 	struct ieee80211_amrr		amrr;
-	struct ieee80211_amrr_node	amn;
 	struct callout			amrr_ch;
 
 	int				(*newstate)(struct ieee80211vap *,


More information about the p4-projects mailing list