summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/wlan/if_run.c
diff options
context:
space:
mode:
authorngie <ngie@FreeBSD.org>2015-10-05 00:11:49 +0000
committerngie <ngie@FreeBSD.org>2015-10-05 00:11:49 +0000
commite3bac3a30a41f56ac36f4791a7df260f2155c8db (patch)
treeac20948d4aa368300bc16ece67336a1bed25e992 /sys/dev/usb/wlan/if_run.c
parentca6cf0ba737487849f2ee102afce74545600850c (diff)
parent85fa330dc74592563cea8d7cf0e628fd30683993 (diff)
downloadFreeBSD-src-e3bac3a30a41f56ac36f4791a7df260f2155c8db.zip
FreeBSD-src-e3bac3a30a41f56ac36f4791a7df260f2155c8db.tar.gz
MFhead @ r281414
Diffstat (limited to 'sys/dev/usb/wlan/if_run.c')
-rw-r--r--sys/dev/usb/wlan/if_run.c117
1 files changed, 84 insertions, 33 deletions
diff --git a/sys/dev/usb/wlan/if_run.c b/sys/dev/usb/wlan/if_run.c
index c8707c4..83d4a88 100644
--- a/sys/dev/usb/wlan/if_run.c
+++ b/sys/dev/usb/wlan/if_run.c
@@ -382,8 +382,7 @@ static int run_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static int run_wme_update(struct ieee80211com *);
static void run_wme_update_cb(void *);
static void run_key_set_cb(void *);
-static int run_key_set(struct ieee80211vap *, struct ieee80211_key *,
- const uint8_t mac[IEEE80211_ADDR_LEN]);
+static int run_key_set(struct ieee80211vap *, struct ieee80211_key *);
static void run_key_delete_cb(void *);
static int run_key_delete(struct ieee80211vap *, struct ieee80211_key *);
static void run_ratectl_to(void *);
@@ -392,6 +391,8 @@ static void run_drain_fifo(void *);
static void run_iter_func(void *, struct ieee80211_node *);
static void run_newassoc_cb(void *);
static void run_newassoc(struct ieee80211_node *, int);
+static void run_recv_mgmt(struct ieee80211_node *, struct mbuf *, int,
+ const struct ieee80211_rx_stats *, int, int);
static void run_rx_frame(struct run_softc *, struct mbuf *, uint32_t);
static void run_tx_free(struct run_endpoint_queue *pq,
struct run_tx_data *, int);
@@ -830,6 +831,21 @@ detach:
return (ENXIO);
}
+static void
+run_drain_mbufq(struct run_softc *sc)
+{
+ struct mbuf *m;
+ struct ieee80211_node *ni;
+
+ RUN_LOCK_ASSERT(sc, MA_OWNED);
+ while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
+ ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
+ m->m_pkthdr.rcvif = NULL;
+ ieee80211_free_node(ni);
+ m_freem(m);
+ }
+}
+
static int
run_detach(device_t self)
{
@@ -851,6 +867,9 @@ run_detach(device_t self)
/* free TX list, if any */
for (i = 0; i != RUN_EP_QUEUES; i++)
run_unsetup_tx_list(sc, &sc->sc_epq[i]);
+
+ /* Free TX queue */
+ run_drain_mbufq(sc);
RUN_UNLOCK(sc);
if (sc->sc_ic.ic_softc == sc) {
@@ -861,7 +880,6 @@ run_detach(device_t self)
ieee80211_ifdetach(ic);
}
- mbufq_drain(&sc->sc_snd);
mtx_destroy(&sc->sc_mtx);
return (0);
@@ -939,6 +957,10 @@ run_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
/* override state transition machine */
rvp->newstate = vap->iv_newstate;
vap->iv_newstate = run_newstate;
+ if (opmode == IEEE80211_M_IBSS) {
+ rvp->recv_mgmt = vap->iv_recv_mgmt;
+ vap->iv_recv_mgmt = run_recv_mgmt;
+ }
ieee80211_ratectl_init(vap);
ieee80211_ratectl_setinterval(vap, 1000 /* 1 sec */);
@@ -1670,14 +1692,14 @@ run_get_txpower(struct run_softc *sc)
/* Fix broken Tx power entries. */
for (i = 0; i < 14; i++) {
if (sc->mac_ver >= 0x5390) {
- if (sc->txpow1[i] < 0 || sc->txpow1[i] > 27)
+ if (sc->txpow1[i] < 0 || sc->txpow1[i] > 39)
sc->txpow1[i] = 5;
} else {
if (sc->txpow1[i] < 0 || sc->txpow1[i] > 31)
sc->txpow1[i] = 5;
}
if (sc->mac_ver > 0x5390) {
- if (sc->txpow2[i] < 0 || sc->txpow2[i] > 27)
+ if (sc->txpow2[i] < 0 || sc->txpow2[i] > 39)
sc->txpow2[i] = 5;
} else if (sc->mac_ver < 0x5390) {
if (sc->txpow2[i] < 0 || sc->txpow2[i] > 31)
@@ -2157,7 +2179,8 @@ run_wme_update_cb(void *arg)
{
struct ieee80211com *ic = arg;
struct run_softc *sc = ic->ic_softc;
- struct ieee80211_wme_state *wmesp = &ic->ic_wme;
+ const struct wmeParams *ac =
+ ic->ic_wme.wme_chanParams.cap_wmeParams;
int aci, error = 0;
RUN_LOCK_ASSERT(sc, MA_OWNED);
@@ -2165,39 +2188,39 @@ run_wme_update_cb(void *arg)
/* update MAC TX configuration registers */
for (aci = 0; aci < WME_NUM_AC; aci++) {
error = run_write(sc, RT2860_EDCA_AC_CFG(aci),
- wmesp->wme_params[aci].wmep_logcwmax << 16 |
- wmesp->wme_params[aci].wmep_logcwmin << 12 |
- wmesp->wme_params[aci].wmep_aifsn << 8 |
- wmesp->wme_params[aci].wmep_txopLimit);
+ ac[aci].wmep_logcwmax << 16 |
+ ac[aci].wmep_logcwmin << 12 |
+ ac[aci].wmep_aifsn << 8 |
+ ac[aci].wmep_txopLimit);
if (error) goto err;
}
/* update SCH/DMA registers too */
error = run_write(sc, RT2860_WMM_AIFSN_CFG,
- wmesp->wme_params[WME_AC_VO].wmep_aifsn << 12 |
- wmesp->wme_params[WME_AC_VI].wmep_aifsn << 8 |
- wmesp->wme_params[WME_AC_BK].wmep_aifsn << 4 |
- wmesp->wme_params[WME_AC_BE].wmep_aifsn);
+ ac[WME_AC_VO].wmep_aifsn << 12 |
+ ac[WME_AC_VI].wmep_aifsn << 8 |
+ ac[WME_AC_BK].wmep_aifsn << 4 |
+ ac[WME_AC_BE].wmep_aifsn);
if (error) goto err;
error = run_write(sc, RT2860_WMM_CWMIN_CFG,
- wmesp->wme_params[WME_AC_VO].wmep_logcwmin << 12 |
- wmesp->wme_params[WME_AC_VI].wmep_logcwmin << 8 |
- wmesp->wme_params[WME_AC_BK].wmep_logcwmin << 4 |
- wmesp->wme_params[WME_AC_BE].wmep_logcwmin);
+ ac[WME_AC_VO].wmep_logcwmin << 12 |
+ ac[WME_AC_VI].wmep_logcwmin << 8 |
+ ac[WME_AC_BK].wmep_logcwmin << 4 |
+ ac[WME_AC_BE].wmep_logcwmin);
if (error) goto err;
error = run_write(sc, RT2860_WMM_CWMAX_CFG,
- wmesp->wme_params[WME_AC_VO].wmep_logcwmax << 12 |
- wmesp->wme_params[WME_AC_VI].wmep_logcwmax << 8 |
- wmesp->wme_params[WME_AC_BK].wmep_logcwmax << 4 |
- wmesp->wme_params[WME_AC_BE].wmep_logcwmax);
+ ac[WME_AC_VO].wmep_logcwmax << 12 |
+ ac[WME_AC_VI].wmep_logcwmax << 8 |
+ ac[WME_AC_BK].wmep_logcwmax << 4 |
+ ac[WME_AC_BE].wmep_logcwmax);
if (error) goto err;
error = run_write(sc, RT2860_WMM_TXOP0_CFG,
- wmesp->wme_params[WME_AC_BK].wmep_txopLimit << 16 |
- wmesp->wme_params[WME_AC_BE].wmep_txopLimit);
+ ac[WME_AC_BK].wmep_txopLimit << 16 |
+ ac[WME_AC_BE].wmep_txopLimit);
if (error) goto err;
error = run_write(sc, RT2860_WMM_TXOP1_CFG,
- wmesp->wme_params[WME_AC_VO].wmep_txopLimit << 16 |
- wmesp->wme_params[WME_AC_VI].wmep_txopLimit);
+ ac[WME_AC_VO].wmep_txopLimit << 16 |
+ ac[WME_AC_VI].wmep_txopLimit);
err:
if (error)
@@ -2355,8 +2378,7 @@ run_key_set_cb(void *arg)
* return 0 on error
*/
static int
-run_key_set(struct ieee80211vap *vap, struct ieee80211_key *k,
- const uint8_t mac[IEEE80211_ADDR_LEN])
+run_key_set(struct ieee80211vap *vap, struct ieee80211_key *k)
{
struct ieee80211com *ic = vap->iv_ic;
struct run_softc *sc = ic->ic_softc;
@@ -2368,7 +2390,7 @@ run_key_set(struct ieee80211vap *vap, struct ieee80211_key *k,
sc->cmdq[i].arg0 = NULL;
sc->cmdq[i].arg1 = vap;
sc->cmdq[i].k = k;
- IEEE80211_ADDR_COPY(sc->cmdq[i].mac, mac);
+ IEEE80211_ADDR_COPY(sc->cmdq[i].mac, k->wk_macaddr);
ieee80211_runtask(ic, &sc->cmdq_task);
/*
@@ -2725,6 +2747,34 @@ run_maxrssi_chain(struct run_softc *sc, const struct rt2860_rxwi *rxwi)
}
static void
+run_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, int subtype,
+ const struct ieee80211_rx_stats *rxs, int rssi, int nf)
+{
+ struct ieee80211vap *vap = ni->ni_vap;
+ struct run_softc *sc = vap->iv_ic->ic_softc;
+ struct run_vap *rvp = RUN_VAP(vap);
+ uint64_t ni_tstamp, rx_tstamp;
+
+ rvp->recv_mgmt(ni, m, subtype, rxs, rssi, nf);
+
+ if (vap->iv_state == IEEE80211_S_RUN &&
+ (subtype == IEEE80211_FC0_SUBTYPE_BEACON ||
+ subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)) {
+ ni_tstamp = le64toh(ni->ni_tstamp.tsf);
+ RUN_LOCK(sc);
+ run_get_tsf(sc, &rx_tstamp);
+ RUN_UNLOCK(sc);
+ rx_tstamp = le64toh(rx_tstamp);
+
+ if (ni_tstamp >= rx_tstamp) {
+ DPRINTF("ibss merge, tsf %ju tstamp %ju\n",
+ (uintmax_t)rx_tstamp, (uintmax_t)ni_tstamp);
+ (void) ieee80211_ibss_merge(ni);
+ }
+ }
+}
+
+static void
run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen)
{
struct ieee80211com *ic = &sc->sc_ic;
@@ -4834,11 +4884,11 @@ run_update_beacon(struct ieee80211vap *vap, int item)
setbit(bo->bo_flags, item);
if (rvp->beacon_mbuf == NULL) {
- rvp->beacon_mbuf = ieee80211_beacon_alloc(ni, bo);
+ rvp->beacon_mbuf = ieee80211_beacon_alloc(ni);
if (rvp->beacon_mbuf == NULL)
return;
}
- ieee80211_beacon_update(ni, bo, rvp->beacon_mbuf, mcast);
+ ieee80211_beacon_update(ni, rvp->beacon_mbuf, mcast);
i = RUN_CMDQ_GET(&sc->cmdq_store);
DPRINTF("cmdq_store=%d\n", i);
@@ -4872,8 +4922,7 @@ run_update_beacon_cb(void *arg)
* is taking care of apropriate calls.
*/
if (rvp->beacon_mbuf == NULL) {
- rvp->beacon_mbuf = ieee80211_beacon_alloc(ni,
- &vap->iv_bcn_off);
+ rvp->beacon_mbuf = ieee80211_beacon_alloc(ni);
if (rvp->beacon_mbuf == NULL)
return;
}
@@ -6140,6 +6189,8 @@ run_stop(void *arg)
RUN_LOCK(sc);
+ run_drain_mbufq(sc);
+
if (sc->rx_m != NULL) {
m_free(sc->rx_m);
sc->rx_m = NULL;
OpenPOWER on IntegriCloud