Date: Mon, 7 Feb 2011 17:18:30 -0800 (PST) From: PseudoCylon <moonlightakkiy@yahoo.ca> To: Bernhard Schmidt <bschmidt@freebsd.org> Cc: freebsd-net@freebsd.org, Alexander Zagrebin <alex@zagrebin.ru> Subject: Re: if_run in hostap mode: issue with stations in the power save mode Message-ID: <95679.17379.qm@web39320.mail.mud.yahoo.com> In-Reply-To: <201102061142.43865.bschmidt@freebsd.org> References: <20110204060808.GA97298@gw.zagrebin.ru> <201102041314.17939.bschmidt@freebsd.org> <147585.89029.qm@web39304.mail.mud.yahoo.com> <201102061142.43865.bschmidt@freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
----- Original Message ----
> From: Bernhard Schmidt <bschmidt@freebsd.org>
> To: PseudoCylon <moonlightakkiy@yahoo.ca>
> Cc: Alexander Zagrebin <alex@zagrebin.ru>; freebsd-net@freebsd.org
> Sent: Sun, February 6, 2011 3:42:43 AM
> Subject: Re: if_run in hostap mode: issue with stations in the power save mode
Afaik iwn(4) doesn't use PS, never got around implementing that.
>
> > I'd like to move ieee80211_beacon_alloc() into iv_vap_alloc(). Then
> > we don't need to test beacon_mbuf == NULL in run_update_beacon_cb(),
> > and there is already switch we can use for conditionally alloc mem.
>
> Sounds fine with we.
>
Oops, there is switch before malloc vap. the test is still
in run_update_beacon_cb()
> Can I talk you into integrating that into Alexander's patch?
>
The patch is attached. (diff to HEAD) Bit long, just because there is
a couple of new call back functions to avoid LOR.
AK
[-- Attachment #2 --]
diff --git a/dev/usb/wlan/if_run.c b/dev/usb/wlan/if_run.c
index df72f72..1cd1591 100644
--- a/dev/usb/wlan/if_run.c
+++ b/dev/usb/wlan/if_run.c
@@ -388,6 +388,7 @@ static void run_scan_end(struct ieee80211com *);
static void run_update_beacon(struct ieee80211vap *, int);
static void run_update_beacon_cb(void *);
static void run_updateprot(struct ieee80211com *);
+static void run_updateprot_cb(void *);
static void run_usb_timeout_cb(void *);
static void run_reset_livelock(struct run_softc *);
static void run_enable_tsf_sync(struct run_softc *);
@@ -398,6 +399,7 @@ static void run_set_leds(struct run_softc *, uint16_t);
static void run_set_bssid(struct run_softc *, const uint8_t *);
static void run_set_macaddr(struct run_softc *, const uint8_t *);
static void run_updateslot(struct ifnet *);
+static void run_updateslot_cb(void *);
static void run_update_mcast(struct ifnet *);
static int8_t run_rssi2dbm(struct run_softc *, uint8_t, uint8_t);
static void run_update_promisc_locked(struct ifnet *);
@@ -674,7 +676,7 @@ run_attach(device_t self)
ic->ic_set_channel = run_set_channel;
ic->ic_node_alloc = run_node_alloc;
ic->ic_newassoc = run_newassoc;
- //ic->ic_updateslot = run_updateslot;
+ ic->ic_updateslot = run_updateslot;
ic->ic_update_mcast = run_update_mcast;
ic->ic_wme.wme_update = run_wme_update;
ic->ic_raw_xmit = run_raw_xmit;
@@ -856,6 +858,8 @@ run_vap_delete(struct ieee80211vap *vap)
RUN_LOCK(sc);
+ m_freem(rvp->beacon_mbuf);
+
rvp_id = rvp->rvp_id;
sc->ratectl_run &= ~(1 << rvp_id);
sc->rvp_bmap &= ~(1 << rvp_id);
@@ -3901,8 +3905,29 @@ run_update_beacon(struct ieee80211vap *vap, int item)
{
struct ieee80211com *ic = vap->iv_ic;
struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_vap *rvp = RUN_VAP(vap);
+ int mcast = 0;
uint32_t i;
+ KASSERT(vap != NULL, ("no beacon"));
+
+ switch (item) {
+ case IEEE80211_BEACON_ERP:
+ run_updateslot(ic->ic_ifp);
+ break;
+ case IEEE80211_BEACON_HTINFO:
+ run_updateprot(ic);
+ break;
+ case IEEE80211_BEACON_TIM:
+ mcast = 1; /*TODO*/
+ break;
+ default:
+ break;
+ }
+
+ setbit(rvp->bo.bo_flags, item);
+ ieee80211_beacon_update(vap->iv_bss, &rvp->bo, rvp->beacon_mbuf, mcast);
+
i = RUN_CMDQ_GET(&sc->cmdq_store);
DPRINTF("cmdq_store=%d\n", i);
sc->cmdq[i].func = run_update_beacon_cb;
@@ -3916,17 +3941,25 @@ static void
run_update_beacon_cb(void *arg)
{
struct ieee80211vap *vap = arg;
+ struct run_vap *rvp = RUN_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
struct run_softc *sc = ic->ic_ifp->if_softc;
struct rt2860_txwi txwi;
- struct mbuf *m;
+ struct mbuf *m = rvp->beacon_mbuf;
uint8_t ridx;
if (vap->iv_bss->ni_chan == IEEE80211_CHAN_ANYC)
return;
- if ((m = ieee80211_beacon_alloc(vap->iv_bss, &RUN_VAP(vap)->bo)) == NULL)
- return;
+ /*
+ * ieee80211_beacon_update() is called in run_update_beacon()
+ * 'rvp->beacon_mbuf == NULL' means nothing to update (called first time)
+ */
+ if (rvp->beacon_mbuf == NULL) {
+ if ((rvp->beacon_mbuf = m =
+ ieee80211_beacon_alloc(vap->iv_bss, &rvp->bo)) == NULL)
+ return;
+ }
memset(&txwi, 0, sizeof txwi);
txwi.wcid = 0xff;
@@ -3941,13 +3974,11 @@ run_update_beacon_cb(void *arg)
txwi.flags = RT2860_TX_TS;
txwi.xflags = RT2860_TX_NSEQ;
- run_write_region_1(sc, RT2860_BCN_BASE(RUN_VAP(vap)->rvp_id),
+ run_write_region_1(sc, RT2860_BCN_BASE(rvp->rvp_id),
(uint8_t *)&txwi, sizeof txwi);
- run_write_region_1(sc, RT2860_BCN_BASE(RUN_VAP(vap)->rvp_id) + sizeof txwi,
+ run_write_region_1(sc, RT2860_BCN_BASE(rvp->rvp_id) + sizeof txwi,
mtod(m, uint8_t *), (m->m_pkthdr.len + 1) & ~1); /* roundup len */
- m_freem(m);
-
return;
}
@@ -3955,6 +3986,20 @@ static void
run_updateprot(struct ieee80211com *ic)
{
struct run_softc *sc = ic->ic_ifp->if_softc;
+ uint32_t i;
+
+ i = RUN_CMDQ_GET(&sc->cmdq_store);
+ DPRINTF("cmdq_store=%d\n", i);
+ sc->cmdq[i].func = run_updateprot_cb;
+ sc->cmdq[i].arg0 = ic;
+ ieee80211_runtask(ic, &sc->cmdq_task);
+}
+
+static void
+run_updateprot_cb(void *arg)
+{
+ struct ieee80211com *ic = arg;
+ struct run_softc *sc = ic->ic_ifp->if_softc;
uint32_t tmp;
tmp = RT2860_RTSTH_EN | RT2860_PROT_NAV_SHORT | RT2860_TXOP_ALLOW_ALL;
@@ -4164,12 +4209,29 @@ run_set_macaddr(struct run_softc *sc, const uint8_t *addr)
addr[4] | addr[5] << 8 | 0xff << 16);
}
-/* ARGSUSED */
static void
run_updateslot(struct ifnet *ifp)
{
struct run_softc *sc = ifp->if_softc;
struct ieee80211com *ic = ifp->if_l2com;
+ uint32_t i;
+
+ i = RUN_CMDQ_GET(&sc->cmdq_store);
+ DPRINTF("cmdq_store=%d\n", i);
+ sc->cmdq[i].func = run_updateslot_cb;
+ sc->cmdq[i].arg0 = ifp;
+ ieee80211_runtask(ic, &sc->cmdq_task);
+
+ return;
+}
+
+/* ARGSUSED */
+static void
+run_updateslot_cb(void *arg)
+{
+ struct ifnet *ifp = arg;
+ struct run_softc *sc = ifp->if_softc;
+ struct ieee80211com *ic = ifp->if_l2com;
uint32_t tmp;
run_read(sc, RT2860_BKOFF_SLOT_CFG, &tmp);
@@ -4747,7 +4809,7 @@ run_init_locked(struct run_softc *sc)
run_set_chan(sc, ic->ic_curchan);
/* setup initial protection mode */
- run_updateprot(ic);
+ run_updateprot_cb(ic);
/* turn radio LED on */
run_set_leds(sc, RT2860_LED_RADIO);
diff --git a/dev/usb/wlan/if_runvar.h b/dev/usb/wlan/if_runvar.h
index 39addbf..cc65b1f 100644
--- a/dev/usb/wlan/if_runvar.h
+++ b/dev/usb/wlan/if_runvar.h
@@ -121,6 +121,7 @@ struct run_cmdq {
struct run_vap {
struct ieee80211vap vap;
struct ieee80211_beacon_offsets bo;
+ struct mbuf *beacon_mbuf;
int (*newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?95679.17379.qm>
