mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
Rework beacon handling re-enable run_updateslot().
Drivers which rely on net80211 to create the beacon need to call ieee80211_beacon_update() on iv_update_beacon() calls. This is required that certain bits, e.g. TIM, get updated. A call to ieee80211_beacon_alloc() is not enough because it does not care about flags which can only change during runtime. By design a beacon is supposed to be allocated only once while moving into RUN state. To handle all possible calls to iv_update_beacon() the run_updateslot() function has been revived and run_updateprot() has been added. run_updateslot() handles slot time changes and run_updateprot() changes to protection, both can change while nodes associate/leave. Submitted by: Alexander Zagrebin <alex at zagrebin.ru>, PseudoCylon <moonlightakkiy atyahoo.ca> MFC after: 3 weeks
This commit is contained in:
parent
191470d361
commit
e7d14e9bcc
2 changed files with 78 additions and 9 deletions
|
|
@ -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,9 @@ run_vap_delete(struct ieee80211vap *vap)
|
|||
|
||||
RUN_LOCK(sc);
|
||||
|
||||
m_freem(rvp->beacon_mbuf);
|
||||
rvp->beacon_mbuf = NULL;
|
||||
|
||||
rvp_id = rvp->rvp_id;
|
||||
sc->ratectl_run &= ~(1 << rvp_id);
|
||||
sc->rvp_bmap &= ~(1 << rvp_id);
|
||||
|
|
@ -1790,6 +1795,9 @@ run_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
|
|||
sc->runbmap |= bid;
|
||||
}
|
||||
|
||||
m_freem(rvp->beacon_mbuf);
|
||||
rvp->beacon_mbuf = NULL;
|
||||
|
||||
switch (vap->iv_opmode) {
|
||||
case IEEE80211_M_HOSTAP:
|
||||
case IEEE80211_M_MBSS:
|
||||
|
|
@ -3901,8 +3909,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,6 +3945,7 @@ 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;
|
||||
|
|
@ -3925,8 +3955,17 @@ run_update_beacon_cb(void *arg)
|
|||
if (vap->iv_bss->ni_chan == IEEE80211_CHAN_ANYC)
|
||||
return;
|
||||
|
||||
if ((m = ieee80211_beacon_alloc(vap->iv_bss, &RUN_VAP(vap)->bo)) == NULL)
|
||||
return;
|
||||
/*
|
||||
* No need to call ieee80211_beacon_update(), run_update_beacon()
|
||||
* is taking care of apropriate calls.
|
||||
*/
|
||||
if (rvp->beacon_mbuf == NULL) {
|
||||
rvp->beacon_mbuf = ieee80211_beacon_alloc(vap->iv_bss,
|
||||
&rvp->bo);
|
||||
if (rvp->beacon_mbuf == NULL)
|
||||
return;
|
||||
}
|
||||
m = rvp->beacon_mbuf;
|
||||
|
||||
memset(&txwi, 0, sizeof txwi);
|
||||
txwi.wcid = 0xff;
|
||||
|
|
@ -3941,19 +3980,31 @@ 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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
|
@ -4164,10 +4215,27 @@ 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;
|
||||
|
|
@ -4747,7 +4815,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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue