Overhaul monitor mode handling:
o replace DLT_IEEE802_11 support in net80211 with DLT_IEEE802_11_RADIO and remove explicit bpf support from wireless drivers; drivers now use ieee80211_radiotap_attach to setup shared data structures that hold the radiotap header for each packet tx/rx o remove rx timestamp from the rx path; it was used only by the tdma support for debugging and was mostly useless due to it being 32-bits and mostly unavailable o track DLT_IEEE80211_RADIO bpf attachments and maintain per-vap and per-com state when there are active taps o track the number of monitor mode vaps o use bpf tap and monitor mode vap state to decide when to collect radiotap state and dispatch frames; drivers no longer explicitly directly check bpf state or use bpf calls to tap frames o handle radiotap state updates on channel change in net80211; drivers should not do this (unless they bypass net80211 which is almost always a mistake) o update various drivers to be more consistent/correct in handling radiotap o update ral to include TSF in radiotap'd frames o add promisc mode callback to wi Reviewed by: cbzimmer, rpaulo, thompsa
This commit is contained in:
parent
df90a80062
commit
68f7a1034a
@ -2218,6 +2218,7 @@ net80211/ieee80211_output.c optional wlan
|
|||||||
net80211/ieee80211_phy.c optional wlan
|
net80211/ieee80211_phy.c optional wlan
|
||||||
net80211/ieee80211_power.c optional wlan
|
net80211/ieee80211_power.c optional wlan
|
||||||
net80211/ieee80211_proto.c optional wlan
|
net80211/ieee80211_proto.c optional wlan
|
||||||
|
net80211/ieee80211_radiotap.c optional wlan
|
||||||
net80211/ieee80211_regdomain.c optional wlan
|
net80211/ieee80211_regdomain.c optional wlan
|
||||||
net80211/ieee80211_rssadapt.c optional wlan wlan_rssadapt
|
net80211/ieee80211_rssadapt.c optional wlan wlan_rssadapt
|
||||||
net80211/ieee80211_scan.c optional wlan
|
net80211/ieee80211_scan.c optional wlan
|
||||||
|
@ -172,7 +172,7 @@ static void ath_node_getsignal(const struct ieee80211_node *,
|
|||||||
int8_t *, int8_t *);
|
int8_t *, int8_t *);
|
||||||
static int ath_rxbuf_init(struct ath_softc *, struct ath_buf *);
|
static int ath_rxbuf_init(struct ath_softc *, struct ath_buf *);
|
||||||
static void ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
|
static void ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
|
||||||
int subtype, int rssi, int noise, u_int32_t rstamp);
|
int subtype, int rssi, int nf);
|
||||||
static void ath_setdefantenna(struct ath_softc *, u_int);
|
static void ath_setdefantenna(struct ath_softc *, u_int);
|
||||||
static void ath_rx_proc(void *, int);
|
static void ath_rx_proc(void *, int);
|
||||||
static void ath_txq_init(struct ath_softc *sc, struct ath_txq *, int);
|
static void ath_txq_init(struct ath_softc *sc, struct ath_txq *, int);
|
||||||
@ -214,7 +214,6 @@ static void ath_setcurmode(struct ath_softc *, enum ieee80211_phymode);
|
|||||||
static void ath_sysctlattach(struct ath_softc *);
|
static void ath_sysctlattach(struct ath_softc *);
|
||||||
static int ath_raw_xmit(struct ieee80211_node *,
|
static int ath_raw_xmit(struct ieee80211_node *,
|
||||||
struct mbuf *, const struct ieee80211_bpf_params *);
|
struct mbuf *, const struct ieee80211_bpf_params *);
|
||||||
static void ath_bpfattach(struct ath_softc *);
|
|
||||||
static void ath_announce(struct ath_softc *);
|
static void ath_announce(struct ath_softc *);
|
||||||
|
|
||||||
#ifdef IEEE80211_SUPPORT_TDMA
|
#ifdef IEEE80211_SUPPORT_TDMA
|
||||||
@ -715,7 +714,12 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
|
|||||||
ic->ic_scan_end = ath_scan_end;
|
ic->ic_scan_end = ath_scan_end;
|
||||||
ic->ic_set_channel = ath_set_channel;
|
ic->ic_set_channel = ath_set_channel;
|
||||||
|
|
||||||
ath_bpfattach(sc);
|
ieee80211_radiotap_attach(ic,
|
||||||
|
&sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
|
||||||
|
ATH_TX_RADIOTAP_PRESENT,
|
||||||
|
&sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
|
||||||
|
ATH_RX_RADIOTAP_PRESENT);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup dynamic sysctl's now that country code and
|
* Setup dynamic sysctl's now that country code and
|
||||||
* regdomain are available from the hal.
|
* regdomain are available from the hal.
|
||||||
@ -753,8 +757,6 @@ ath_detach(struct ath_softc *sc)
|
|||||||
* insure callbacks into the driver to delete global
|
* insure callbacks into the driver to delete global
|
||||||
* key cache entries can be handled
|
* key cache entries can be handled
|
||||||
* o free the taskqueue which drains any pending tasks
|
* o free the taskqueue which drains any pending tasks
|
||||||
* o reclaim the bpf tap now that we know nothing will use
|
|
||||||
* it (e.g. rx processing from the task q thread)
|
|
||||||
* o reclaim the tx queue data structures after calling
|
* o reclaim the tx queue data structures after calling
|
||||||
* the 802.11 layer as we'll get called back to reclaim
|
* the 802.11 layer as we'll get called back to reclaim
|
||||||
* node state and potentially want to use them
|
* node state and potentially want to use them
|
||||||
@ -765,7 +767,6 @@ ath_detach(struct ath_softc *sc)
|
|||||||
ath_stop(ifp);
|
ath_stop(ifp);
|
||||||
ieee80211_ifdetach(ifp->if_l2com);
|
ieee80211_ifdetach(ifp->if_l2com);
|
||||||
taskqueue_free(sc->sc_tq);
|
taskqueue_free(sc->sc_tq);
|
||||||
bpfdetach(ifp);
|
|
||||||
#ifdef ATH_TX99_DIAG
|
#ifdef ATH_TX99_DIAG
|
||||||
if (sc->sc_tx99 != NULL)
|
if (sc->sc_tx99 != NULL)
|
||||||
sc->sc_tx99->detach(sc->sc_tx99);
|
sc->sc_tx99->detach(sc->sc_tx99);
|
||||||
@ -2353,6 +2354,7 @@ ath_calcrxfilter(struct ath_softc *sc)
|
|||||||
rfilt |= HAL_RX_FILTER_PHYERR;
|
rfilt |= HAL_RX_FILTER_PHYERR;
|
||||||
if (ic->ic_opmode != IEEE80211_M_STA)
|
if (ic->ic_opmode != IEEE80211_M_STA)
|
||||||
rfilt |= HAL_RX_FILTER_PROBEREQ;
|
rfilt |= HAL_RX_FILTER_PROBEREQ;
|
||||||
|
/* XXX ic->ic_monvaps != 0? */
|
||||||
if (ic->ic_opmode == IEEE80211_M_MONITOR || (ifp->if_flags & IFF_PROMISC))
|
if (ic->ic_opmode == IEEE80211_M_MONITOR || (ifp->if_flags & IFF_PROMISC))
|
||||||
rfilt |= HAL_RX_FILTER_PROM;
|
rfilt |= HAL_RX_FILTER_PROM;
|
||||||
if (ic->ic_opmode == IEEE80211_M_STA ||
|
if (ic->ic_opmode == IEEE80211_M_STA ||
|
||||||
@ -3573,7 +3575,7 @@ ath_extend_tsf(u_int32_t rstamp, u_int64_t tsf)
|
|||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
|
ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
|
||||||
int subtype, int rssi, int noise, u_int32_t rstamp)
|
int subtype, int rssi, int nf)
|
||||||
{
|
{
|
||||||
struct ieee80211vap *vap = ni->ni_vap;
|
struct ieee80211vap *vap = ni->ni_vap;
|
||||||
struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc;
|
struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc;
|
||||||
@ -3582,7 +3584,7 @@ ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
|
|||||||
* Call up first so subsequent work can use information
|
* Call up first so subsequent work can use information
|
||||||
* potentially stored in the node (e.g. for ibss merge).
|
* potentially stored in the node (e.g. for ibss merge).
|
||||||
*/
|
*/
|
||||||
ATH_VAP(vap)->av_recv_mgmt(ni, m, subtype, rssi, noise, rstamp);
|
ATH_VAP(vap)->av_recv_mgmt(ni, m, subtype, rssi, nf);
|
||||||
switch (subtype) {
|
switch (subtype) {
|
||||||
case IEEE80211_FC0_SUBTYPE_BEACON:
|
case IEEE80211_FC0_SUBTYPE_BEACON:
|
||||||
/* update rssi statistics for use by the hal */
|
/* update rssi statistics for use by the hal */
|
||||||
@ -3599,6 +3601,7 @@ ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
|
|||||||
case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
|
case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
|
||||||
if (vap->iv_opmode == IEEE80211_M_IBSS &&
|
if (vap->iv_opmode == IEEE80211_M_IBSS &&
|
||||||
vap->iv_state == IEEE80211_S_RUN) {
|
vap->iv_state == IEEE80211_S_RUN) {
|
||||||
|
uint32_t rstamp = sc->sc_lastrs->rs_tstamp;
|
||||||
u_int64_t tsf = ath_extend_tsf(rstamp,
|
u_int64_t tsf = ath_extend_tsf(rstamp,
|
||||||
ath_hal_gettsf64(sc->sc_ah));
|
ath_hal_gettsf64(sc->sc_ah));
|
||||||
/*
|
/*
|
||||||
@ -3639,7 +3642,7 @@ ath_setdefantenna(struct ath_softc *sc, u_int antenna)
|
|||||||
sc->sc_rxotherant = 0;
|
sc->sc_rxotherant = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
ath_rx_tap(struct ifnet *ifp, struct mbuf *m,
|
ath_rx_tap(struct ifnet *ifp, struct mbuf *m,
|
||||||
const struct ath_rx_status *rs, u_int64_t tsf, int16_t nf)
|
const struct ath_rx_status *rs, u_int64_t tsf, int16_t nf)
|
||||||
{
|
{
|
||||||
@ -3651,15 +3654,6 @@ ath_rx_tap(struct ifnet *ifp, struct mbuf *m,
|
|||||||
const HAL_RATE_TABLE *rt;
|
const HAL_RATE_TABLE *rt;
|
||||||
uint8_t rix;
|
uint8_t rix;
|
||||||
|
|
||||||
/*
|
|
||||||
* Discard anything shorter than an ack or cts.
|
|
||||||
*/
|
|
||||||
if (m->m_pkthdr.len < IEEE80211_ACK_LEN) {
|
|
||||||
DPRINTF(sc, ATH_DEBUG_RECV, "%s: runt packet %d\n",
|
|
||||||
__func__, m->m_pkthdr.len);
|
|
||||||
sc->sc_stats.ast_rx_tooshort++;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
rt = sc->sc_currates;
|
rt = sc->sc_currates;
|
||||||
KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
|
KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
|
||||||
rix = rt->rateCodeToIndex[rs->rs_rate];
|
rix = rt->rateCodeToIndex[rs->rs_rate];
|
||||||
@ -3684,13 +3678,9 @@ ath_rx_tap(struct ifnet *ifp, struct mbuf *m,
|
|||||||
if (rs->rs_status & HAL_RXERR_CRC)
|
if (rs->rs_status & HAL_RXERR_CRC)
|
||||||
sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_BADFCS;
|
sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_BADFCS;
|
||||||
/* XXX propagate other error flags from descriptor */
|
/* XXX propagate other error flags from descriptor */
|
||||||
sc->sc_rx_th.wr_antsignal = rs->rs_rssi + nf;
|
|
||||||
sc->sc_rx_th.wr_antnoise = nf;
|
sc->sc_rx_th.wr_antnoise = nf;
|
||||||
|
sc->sc_rx_th.wr_antsignal = nf + rs->rs_rssi;
|
||||||
sc->sc_rx_th.wr_antenna = rs->rs_antenna;
|
sc->sc_rx_th.wr_antenna = rs->rs_antenna;
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, &sc->sc_rx_th, sc->sc_rx_th_len, m);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
#undef CHAN_HT
|
#undef CHAN_HT
|
||||||
#undef CHAN_HT20
|
#undef CHAN_HT20
|
||||||
#undef CHAN_HT40U
|
#undef CHAN_HT40U
|
||||||
@ -3812,7 +3802,7 @@ ath_rx_proc(void *arg, int npending)
|
|||||||
sc->sc_stats.ast_rx_badmic++;
|
sc->sc_stats.ast_rx_badmic++;
|
||||||
/*
|
/*
|
||||||
* Do minimal work required to hand off
|
* Do minimal work required to hand off
|
||||||
* the 802.11 header for notifcation.
|
* the 802.11 header for notification.
|
||||||
*/
|
*/
|
||||||
/* XXX frag's and qos frames */
|
/* XXX frag's and qos frames */
|
||||||
len = rs->rs_datalen;
|
len = rs->rs_datalen;
|
||||||
@ -3841,14 +3831,15 @@ rx_error:
|
|||||||
* pass decrypt+mic errors but others may be
|
* pass decrypt+mic errors but others may be
|
||||||
* interesting (e.g. crc).
|
* interesting (e.g. crc).
|
||||||
*/
|
*/
|
||||||
if (bpf_peers_present(ifp->if_bpf) &&
|
if (ieee80211_radiotap_active(ic) &&
|
||||||
(rs->rs_status & sc->sc_monpass)) {
|
(rs->rs_status & sc->sc_monpass)) {
|
||||||
bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap,
|
bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap,
|
||||||
BUS_DMASYNC_POSTREAD);
|
BUS_DMASYNC_POSTREAD);
|
||||||
/* NB: bpf needs the mbuf length setup */
|
/* NB: bpf needs the mbuf length setup */
|
||||||
len = rs->rs_datalen;
|
len = rs->rs_datalen;
|
||||||
m->m_pkthdr.len = m->m_len = len;
|
m->m_pkthdr.len = m->m_len = len;
|
||||||
(void) ath_rx_tap(ifp, m, rs, tsf, nf);
|
ath_rx_tap(ifp, m, rs, tsf, nf);
|
||||||
|
ieee80211_radiotap_rx_all(ic, m);
|
||||||
}
|
}
|
||||||
/* XXX pass MIC errors up for s/w reclaculation */
|
/* XXX pass MIC errors up for s/w reclaculation */
|
||||||
goto rx_next;
|
goto rx_next;
|
||||||
@ -3906,20 +3897,29 @@ rx_accept:
|
|||||||
ifp->if_ipackets++;
|
ifp->if_ipackets++;
|
||||||
sc->sc_stats.ast_ant_rx[rs->rs_antenna]++;
|
sc->sc_stats.ast_ant_rx[rs->rs_antenna]++;
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf) &&
|
/*
|
||||||
!ath_rx_tap(ifp, m, rs, tsf, nf)) {
|
* Populate the rx status block. When there are bpf
|
||||||
m_freem(m); /* XXX reclaim */
|
* listeners we do the additional work to provide
|
||||||
goto rx_next;
|
* complete status. Otherwise we fill in only the
|
||||||
}
|
* material required by ieee80211_input. Note that
|
||||||
|
* noise setting is filled in above.
|
||||||
|
*/
|
||||||
|
if (ieee80211_radiotap_active(ic))
|
||||||
|
ath_rx_tap(ifp, m, rs, tsf, nf);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* From this point on we assume the frame is at least
|
* From this point on we assume the frame is at least
|
||||||
* as large as ieee80211_frame_min; verify that.
|
* as large as ieee80211_frame_min; verify that.
|
||||||
*/
|
*/
|
||||||
if (len < IEEE80211_MIN_LEN) {
|
if (len < IEEE80211_MIN_LEN) {
|
||||||
DPRINTF(sc, ATH_DEBUG_RECV, "%s: short packet %d\n",
|
if (!ieee80211_radiotap_active(ic)) {
|
||||||
__func__, len);
|
DPRINTF(sc, ATH_DEBUG_RECV,
|
||||||
|
"%s: short packet %d\n", __func__, len);
|
||||||
sc->sc_stats.ast_rx_tooshort++;
|
sc->sc_stats.ast_rx_tooshort++;
|
||||||
|
} else {
|
||||||
|
/* NB: in particular this captures ack's */
|
||||||
|
ieee80211_radiotap_rx_all(ic, m);
|
||||||
|
}
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
goto rx_next;
|
goto rx_next;
|
||||||
}
|
}
|
||||||
@ -3947,11 +3947,8 @@ rx_accept:
|
|||||||
/*
|
/*
|
||||||
* Sending station is known, dispatch directly.
|
* Sending station is known, dispatch directly.
|
||||||
*/
|
*/
|
||||||
#ifdef IEEE80211_SUPPORT_TDMA
|
sc->sc_lastrs = rs;
|
||||||
sc->sc_tdmars = rs;
|
type = ieee80211_input(ni, m, rs->rs_rssi, nf);
|
||||||
#endif
|
|
||||||
type = ieee80211_input(ni, m,
|
|
||||||
rs->rs_rssi, nf, rs->rs_tstamp);
|
|
||||||
ieee80211_free_node(ni);
|
ieee80211_free_node(ni);
|
||||||
/*
|
/*
|
||||||
* Arrange to update the last rx timestamp only for
|
* Arrange to update the last rx timestamp only for
|
||||||
@ -3963,8 +3960,7 @@ rx_accept:
|
|||||||
rs->rs_keyix != HAL_RXKEYIX_INVALID)
|
rs->rs_keyix != HAL_RXKEYIX_INVALID)
|
||||||
ngood++;
|
ngood++;
|
||||||
} else {
|
} else {
|
||||||
type = ieee80211_input_all(ic, m,
|
type = ieee80211_input_all(ic, m, rs->rs_rssi, nf);
|
||||||
rs->rs_rssi, nf, rs->rs_tstamp);
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Track rx rssi and do any rx antenna management.
|
* Track rx rssi and do any rx antenna management.
|
||||||
@ -4781,7 +4777,7 @@ ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf
|
|||||||
ieee80211_dump_pkt(ic, mtod(m0, const uint8_t *), m0->m_len,
|
ieee80211_dump_pkt(ic, mtod(m0, const uint8_t *), m0->m_len,
|
||||||
sc->sc_hwmap[rix].ieeerate, -1);
|
sc->sc_hwmap[rix].ieeerate, -1);
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active_vap(vap)) {
|
||||||
u_int64_t tsf = ath_hal_gettsf64(ah);
|
u_int64_t tsf = ath_hal_gettsf64(ah);
|
||||||
|
|
||||||
sc->sc_tx_th.wt_tsf = htole64(tsf);
|
sc->sc_tx_th.wt_tsf = htole64(tsf);
|
||||||
@ -4794,7 +4790,7 @@ ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf
|
|||||||
sc->sc_tx_th.wt_txpower = ni->ni_txpower;
|
sc->sc_tx_th.wt_txpower = ni->ni_txpower;
|
||||||
sc->sc_tx_th.wt_antenna = sc->sc_txantenna;
|
sc->sc_tx_th.wt_antenna = sc->sc_txantenna;
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, &sc->sc_tx_th, sc->sc_tx_th_len, m0);
|
ieee80211_radiotap_tx(vap, m0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -5289,15 +5285,6 @@ ath_chan_change(struct ath_softc *sc, struct ieee80211_channel *chan)
|
|||||||
if (mode != sc->sc_curmode)
|
if (mode != sc->sc_curmode)
|
||||||
ath_setcurmode(sc, mode);
|
ath_setcurmode(sc, mode);
|
||||||
sc->sc_curchan = chan;
|
sc->sc_curchan = chan;
|
||||||
|
|
||||||
sc->sc_rx_th.wr_chan_flags = htole32(chan->ic_flags);
|
|
||||||
sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags;
|
|
||||||
sc->sc_rx_th.wr_chan_freq = htole16(chan->ic_freq);
|
|
||||||
sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq;
|
|
||||||
sc->sc_rx_th.wr_chan_ieee = chan->ic_ieee;
|
|
||||||
sc->sc_tx_th.wt_chan_ieee = sc->sc_rx_th.wr_chan_ieee;
|
|
||||||
sc->sc_rx_th.wr_chan_maxpow = chan->ic_maxregpower;
|
|
||||||
sc->sc_tx_th.wt_chan_maxpow = sc->sc_rx_th.wr_chan_maxpow;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -5988,10 +5975,7 @@ ath_setcurmode(struct ath_softc *sc, enum ieee80211_phymode mode)
|
|||||||
if (rt->info[i].shortPreamble ||
|
if (rt->info[i].shortPreamble ||
|
||||||
rt->info[i].phy == IEEE80211_T_OFDM)
|
rt->info[i].phy == IEEE80211_T_OFDM)
|
||||||
sc->sc_hwmap[i].txflags |= IEEE80211_RADIOTAP_F_SHORTPRE;
|
sc->sc_hwmap[i].txflags |= IEEE80211_RADIOTAP_F_SHORTPRE;
|
||||||
/* NB: receive frames include FCS */
|
sc->sc_hwmap[i].rxflags = sc->sc_hwmap[i].txflags;
|
||||||
sc->sc_hwmap[i].rxflags = sc->sc_hwmap[i].txflags |
|
|
||||||
IEEE80211_RADIOTAP_F_FCS;
|
|
||||||
/* setup blink rate table to avoid per-packet lookup */
|
|
||||||
for (j = 0; j < N(blinkrates)-1; j++)
|
for (j = 0; j < N(blinkrates)-1; j++)
|
||||||
if (blinkrates[j].rate == sc->sc_hwmap[i].ieeerate)
|
if (blinkrates[j].rate == sc->sc_hwmap[i].ieeerate)
|
||||||
break;
|
break;
|
||||||
@ -6627,31 +6611,6 @@ ath_sysctlattach(struct ath_softc *sc)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
ath_bpfattach(struct ath_softc *sc)
|
|
||||||
{
|
|
||||||
struct ifnet *ifp = sc->sc_ifp;
|
|
||||||
|
|
||||||
bpfattach(ifp, DLT_IEEE802_11_RADIO,
|
|
||||||
sizeof(struct ieee80211_frame) + sizeof(sc->sc_tx_th));
|
|
||||||
/*
|
|
||||||
* Initialize constant fields.
|
|
||||||
* XXX make header lengths a multiple of 32-bits so subsequent
|
|
||||||
* headers are properly aligned; this is a kludge to keep
|
|
||||||
* certain applications happy.
|
|
||||||
*
|
|
||||||
* NB: the channel is setup each time we transition to the
|
|
||||||
* RUN state to avoid filling it in for each frame.
|
|
||||||
*/
|
|
||||||
sc->sc_tx_th_len = roundup(sizeof(sc->sc_tx_th), sizeof(u_int32_t));
|
|
||||||
sc->sc_tx_th.wt_ihdr.it_len = htole16(sc->sc_tx_th_len);
|
|
||||||
sc->sc_tx_th.wt_ihdr.it_present = htole32(ATH_TX_RADIOTAP_PRESENT);
|
|
||||||
|
|
||||||
sc->sc_rx_th_len = roundup(sizeof(sc->sc_rx_th), sizeof(u_int32_t));
|
|
||||||
sc->sc_rx_th.wr_ihdr.it_len = htole16(sc->sc_rx_th_len);
|
|
||||||
sc->sc_rx_th.wr_ihdr.it_present = htole32(ATH_RX_RADIOTAP_PRESENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni,
|
ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni,
|
||||||
struct ath_buf *bf, struct mbuf *m0,
|
struct ath_buf *bf, struct mbuf *m0,
|
||||||
@ -6660,6 +6619,7 @@ ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni,
|
|||||||
struct ifnet *ifp = sc->sc_ifp;
|
struct ifnet *ifp = sc->sc_ifp;
|
||||||
struct ieee80211com *ic = ifp->if_l2com;
|
struct ieee80211com *ic = ifp->if_l2com;
|
||||||
struct ath_hal *ah = sc->sc_ah;
|
struct ath_hal *ah = sc->sc_ah;
|
||||||
|
struct ieee80211vap *vap = ni->ni_vap;
|
||||||
int error, ismcast, ismrr;
|
int error, ismcast, ismrr;
|
||||||
int keyix, hdrlen, pktlen, try0, txantenna;
|
int keyix, hdrlen, pktlen, try0, txantenna;
|
||||||
u_int8_t rix, cix, txrate, ctsrate, rate1, rate2, rate3;
|
u_int8_t rix, cix, txrate, ctsrate, rate1, rate2, rate3;
|
||||||
@ -6791,18 +6751,20 @@ ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni,
|
|||||||
ieee80211_dump_pkt(ic, mtod(m0, caddr_t), m0->m_len,
|
ieee80211_dump_pkt(ic, mtod(m0, caddr_t), m0->m_len,
|
||||||
sc->sc_hwmap[rix].ieeerate, -1);
|
sc->sc_hwmap[rix].ieeerate, -1);
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active_vap(vap)) {
|
||||||
u_int64_t tsf = ath_hal_gettsf64(ah);
|
u_int64_t tsf = ath_hal_gettsf64(ah);
|
||||||
|
|
||||||
sc->sc_tx_th.wt_tsf = htole64(tsf);
|
sc->sc_tx_th.wt_tsf = htole64(tsf);
|
||||||
sc->sc_tx_th.wt_flags = sc->sc_hwmap[rix].txflags;
|
sc->sc_tx_th.wt_flags = sc->sc_hwmap[rix].txflags;
|
||||||
if (wh->i_fc[1] & IEEE80211_FC1_WEP)
|
if (wh->i_fc[1] & IEEE80211_FC1_WEP)
|
||||||
sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
|
sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
|
||||||
|
if (m0->m_flags & M_FRAG)
|
||||||
|
sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_FRAG;
|
||||||
sc->sc_tx_th.wt_rate = sc->sc_hwmap[rix].ieeerate;
|
sc->sc_tx_th.wt_rate = sc->sc_hwmap[rix].ieeerate;
|
||||||
sc->sc_tx_th.wt_txpower = ni->ni_txpower;
|
sc->sc_tx_th.wt_txpower = ni->ni_txpower;
|
||||||
sc->sc_tx_th.wt_antenna = sc->sc_txantenna;
|
sc->sc_tx_th.wt_antenna = sc->sc_txantenna;
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, &sc->sc_tx_th, sc->sc_tx_th_len, m0);
|
ieee80211_radiotap_tx(vap, m0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -7141,8 +7103,9 @@ ath_tdma_update(struct ieee80211_node *ni,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* extend rx timestamp to 64 bits */
|
/* extend rx timestamp to 64 bits */
|
||||||
|
rs = sc->sc_lastrs;
|
||||||
tsf = ath_hal_gettsf64(ah);
|
tsf = ath_hal_gettsf64(ah);
|
||||||
rstamp = ath_extend_tsf(ni->ni_rstamp, tsf);
|
rstamp = ath_extend_tsf(rs->rs_tstamp, tsf);
|
||||||
/*
|
/*
|
||||||
* The rx timestamp is set by the hardware on completing
|
* The rx timestamp is set by the hardware on completing
|
||||||
* reception (at the point where the rx descriptor is DMA'd
|
* reception (at the point where the rx descriptor is DMA'd
|
||||||
@ -7150,7 +7113,6 @@ ath_tdma_update(struct ieee80211_node *ni,
|
|||||||
* must adjust this time by the time required to send
|
* must adjust this time by the time required to send
|
||||||
* the packet just received.
|
* the packet just received.
|
||||||
*/
|
*/
|
||||||
rs = sc->sc_tdmars;
|
|
||||||
rix = rt->rateCodeToIndex[rs->rs_rate];
|
rix = rt->rateCodeToIndex[rs->rs_rate];
|
||||||
txtime = ath_hal_computetxtime(ah, rt, rs->rs_datalen, rix,
|
txtime = ath_hal_computetxtime(ah, rt, rs->rs_datalen, rix,
|
||||||
rt->info[rix].shortPreamble);
|
rt->info[rix].shortPreamble);
|
||||||
|
@ -187,7 +187,7 @@ struct ath_vap {
|
|||||||
struct ath_txq av_mcastq; /* buffered mcast s/w queue */
|
struct ath_txq av_mcastq; /* buffered mcast s/w queue */
|
||||||
|
|
||||||
void (*av_recv_mgmt)(struct ieee80211_node *,
|
void (*av_recv_mgmt)(struct ieee80211_node *,
|
||||||
struct mbuf *, int, int, int, u_int32_t);
|
struct mbuf *, int, int, int);
|
||||||
int (*av_newstate)(struct ieee80211vap *,
|
int (*av_newstate)(struct ieee80211vap *,
|
||||||
enum ieee80211_state, int);
|
enum ieee80211_state, int);
|
||||||
void (*av_bmiss)(struct ieee80211vap *);
|
void (*av_bmiss)(struct ieee80211vap *);
|
||||||
@ -284,12 +284,6 @@ struct ath_softc {
|
|||||||
u_int sc_rfsilentpin; /* GPIO pin for rfkill int */
|
u_int sc_rfsilentpin; /* GPIO pin for rfkill int */
|
||||||
u_int sc_rfsilentpol; /* pin setting for rfkill on */
|
u_int sc_rfsilentpol; /* pin setting for rfkill on */
|
||||||
|
|
||||||
struct ath_tx_radiotap_header sc_tx_th;
|
|
||||||
int sc_tx_th_len;
|
|
||||||
struct ath_rx_radiotap_header sc_rx_th;
|
|
||||||
int sc_rx_th_len;
|
|
||||||
u_int sc_monpass; /* frames to pass in mon.mode */
|
|
||||||
|
|
||||||
struct ath_descdma sc_rxdma; /* RX descriptors */
|
struct ath_descdma sc_rxdma; /* RX descriptors */
|
||||||
ath_bufhead sc_rxbuf; /* receive buffer */
|
ath_bufhead sc_rxbuf; /* receive buffer */
|
||||||
struct mbuf *sc_rxpending; /* pending receive data */
|
struct mbuf *sc_rxpending; /* pending receive data */
|
||||||
@ -298,6 +292,10 @@ struct ath_softc {
|
|||||||
u_int8_t sc_defant; /* current default antenna */
|
u_int8_t sc_defant; /* current default antenna */
|
||||||
u_int8_t sc_rxotherant; /* rx's on non-default antenna*/
|
u_int8_t sc_rxotherant; /* rx's on non-default antenna*/
|
||||||
u_int64_t sc_lastrx; /* tsf at last rx'd frame */
|
u_int64_t sc_lastrx; /* tsf at last rx'd frame */
|
||||||
|
struct ath_rx_status *sc_lastrs; /* h/w status of last rx */
|
||||||
|
struct ath_rx_radiotap_header sc_rx_th;
|
||||||
|
int sc_rx_th_len;
|
||||||
|
u_int sc_monpass; /* frames to pass in mon.mode */
|
||||||
|
|
||||||
struct ath_descdma sc_txdma; /* TX descriptors */
|
struct ath_descdma sc_txdma; /* TX descriptors */
|
||||||
ath_bufhead sc_txbuf; /* transmit buffer */
|
ath_bufhead sc_txbuf; /* transmit buffer */
|
||||||
@ -310,6 +308,8 @@ struct ath_softc {
|
|||||||
struct task sc_txtask; /* tx int processing */
|
struct task sc_txtask; /* tx int processing */
|
||||||
int sc_wd_timer; /* count down for wd timer */
|
int sc_wd_timer; /* count down for wd timer */
|
||||||
struct callout sc_wd_ch; /* tx watchdog timer */
|
struct callout sc_wd_ch; /* tx watchdog timer */
|
||||||
|
struct ath_tx_radiotap_header sc_tx_th;
|
||||||
|
int sc_tx_th_len;
|
||||||
|
|
||||||
struct ath_descdma sc_bdma; /* beacon descriptors */
|
struct ath_descdma sc_bdma; /* beacon descriptors */
|
||||||
ath_bufhead sc_bbuf; /* beacon buffers */
|
ath_bufhead sc_bbuf; /* beacon buffers */
|
||||||
@ -338,7 +338,6 @@ struct ath_softc {
|
|||||||
u_int32_t sc_tdmabintval; /* TDMA beacon interval (TU) */
|
u_int32_t sc_tdmabintval; /* TDMA beacon interval (TU) */
|
||||||
u_int32_t sc_tdmaguard; /* TDMA guard time (usec) */
|
u_int32_t sc_tdmaguard; /* TDMA guard time (usec) */
|
||||||
u_int sc_tdmaslotlen; /* TDMA slot length (usec) */
|
u_int sc_tdmaslotlen; /* TDMA slot length (usec) */
|
||||||
struct ath_rx_status *sc_tdmars; /* TDMA status of last rx */
|
|
||||||
u_int32_t sc_avgtsfdeltap;/* TDMA slot adjust (+) */
|
u_int32_t sc_avgtsfdeltap;/* TDMA slot adjust (+) */
|
||||||
u_int32_t sc_avgtsfdeltam;/* TDMA slot adjust (-) */
|
u_int32_t sc_avgtsfdeltam;/* TDMA slot adjust (-) */
|
||||||
};
|
};
|
||||||
|
@ -123,7 +123,7 @@ static int bwi_calc_rssi(struct bwi_softc *, const struct bwi_rxbuf_hdr *);
|
|||||||
static int bwi_calc_noise(struct bwi_softc *);
|
static int bwi_calc_noise(struct bwi_softc *);
|
||||||
static __inline uint8_t bwi_ofdm_plcp2rate(const uint32_t *);
|
static __inline uint8_t bwi_ofdm_plcp2rate(const uint32_t *);
|
||||||
static __inline uint8_t bwi_ds_plcp2rate(const struct ieee80211_ds_plcp_hdr *);
|
static __inline uint8_t bwi_ds_plcp2rate(const struct ieee80211_ds_plcp_hdr *);
|
||||||
static void bwi_rx_radiotap(struct ifnet *, struct mbuf *,
|
static void bwi_rx_radiotap(struct bwi_softc *, struct mbuf *,
|
||||||
struct bwi_rxbuf_hdr *, const void *, int, int, int);
|
struct bwi_rxbuf_hdr *, const void *, int, int, int);
|
||||||
|
|
||||||
static void bwi_restart(void *, int);
|
static void bwi_restart(void *, int);
|
||||||
@ -532,19 +532,11 @@ bwi_attach(struct bwi_softc *sc)
|
|||||||
|
|
||||||
sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan);
|
sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan);
|
||||||
|
|
||||||
/*
|
ieee80211_radiotap_attach(ic,
|
||||||
* Attach bpf.
|
&sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
|
||||||
*/
|
BWI_TX_RADIOTAP_PRESENT,
|
||||||
bpfattach(ifp, DLT_IEEE802_11_RADIO,
|
&sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
|
||||||
sizeof(struct ieee80211_frame) + sizeof(sc->sc_tx_th));
|
BWI_RX_RADIOTAP_PRESENT);
|
||||||
|
|
||||||
sc->sc_tx_th_len = roundup(sizeof(sc->sc_tx_th), sizeof(uint32_t));
|
|
||||||
sc->sc_tx_th.wt_ihdr.it_len = htole16(sc->sc_tx_th_len);
|
|
||||||
sc->sc_tx_th.wt_ihdr.it_present = htole32(BWI_TX_RADIOTAP_PRESENT);
|
|
||||||
|
|
||||||
sc->sc_rx_th_len = roundup(sizeof(sc->sc_rx_th), sizeof(uint32_t));
|
|
||||||
sc->sc_rx_th.wr_ihdr.it_len = htole16(sc->sc_rx_th_len);
|
|
||||||
sc->sc_rx_th.wr_ihdr.it_present = htole32(BWI_RX_RADIOTAP_PRESENT);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add sysctl nodes
|
* Add sysctl nodes
|
||||||
@ -2675,8 +2667,8 @@ bwi_rxeof(struct bwi_softc *sc, int end_idx)
|
|||||||
rate = bwi_ds_plcp2rate(plcp);
|
rate = bwi_ds_plcp2rate(plcp);
|
||||||
|
|
||||||
/* RX radio tap */
|
/* RX radio tap */
|
||||||
if (bpf_peers_present(ifp->if_bpf))
|
if (ieee80211_radiotap_active(ic))
|
||||||
bwi_rx_radiotap(ifp, m, hdr, plcp, rate, rssi, noise);
|
bwi_rx_radiotap(sc, m, hdr, plcp, rate, rssi, noise);
|
||||||
|
|
||||||
m_adj(m, -IEEE80211_CRC_LEN);
|
m_adj(m, -IEEE80211_CRC_LEN);
|
||||||
|
|
||||||
@ -2685,11 +2677,10 @@ bwi_rxeof(struct bwi_softc *sc, int end_idx)
|
|||||||
wh = mtod(m, struct ieee80211_frame_min *);
|
wh = mtod(m, struct ieee80211_frame_min *);
|
||||||
ni = ieee80211_find_rxnode(ic, wh);
|
ni = ieee80211_find_rxnode(ic, wh);
|
||||||
if (ni != NULL) {
|
if (ni != NULL) {
|
||||||
type = ieee80211_input(ni, m, rssi - noise, noise, 0);
|
type = ieee80211_input(ni, m, rssi - noise, noise);
|
||||||
ieee80211_free_node(ni);
|
ieee80211_free_node(ni);
|
||||||
} else
|
} else
|
||||||
type = ieee80211_input_all(ic, m, rssi - noise,
|
type = ieee80211_input_all(ic, m, rssi - noise, noise);
|
||||||
noise, 0);
|
|
||||||
if (type == IEEE80211_FC0_TYPE_DATA) {
|
if (type == IEEE80211_FC0_TYPE_DATA) {
|
||||||
rx_data = 1;
|
rx_data = 1;
|
||||||
sc->sc_rx_rate = rate;
|
sc->sc_rx_rate = rate;
|
||||||
@ -3001,7 +2992,7 @@ bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m,
|
|||||||
/*
|
/*
|
||||||
* TX radio tap
|
* TX radio tap
|
||||||
*/
|
*/
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active_vap(vap)) {
|
||||||
sc->sc_tx_th.wt_flags = 0;
|
sc->sc_tx_th.wt_flags = 0;
|
||||||
if (wh->i_fc[1] & IEEE80211_FC1_WEP)
|
if (wh->i_fc[1] & IEEE80211_FC1_WEP)
|
||||||
sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
|
sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
|
||||||
@ -3012,7 +3003,7 @@ bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m,
|
|||||||
}
|
}
|
||||||
sc->sc_tx_th.wt_rate = rate;
|
sc->sc_tx_th.wt_rate = rate;
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, &sc->sc_tx_th, sc->sc_tx_th_len, m);
|
ieee80211_radiotap_tx(vap, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3134,6 +3125,7 @@ bwi_encap_raw(struct bwi_softc *sc, int idx, struct mbuf *m,
|
|||||||
struct ieee80211_node *ni, const struct ieee80211_bpf_params *params)
|
struct ieee80211_node *ni, const struct ieee80211_bpf_params *params)
|
||||||
{
|
{
|
||||||
struct ifnet *ifp = sc->sc_ifp;
|
struct ifnet *ifp = sc->sc_ifp;
|
||||||
|
struct ieee80211vap *vap = ni->ni_vap;
|
||||||
struct bwi_ring_data *rd = &sc->sc_tx_rdata[BWI_TX_DATA_RING];
|
struct bwi_ring_data *rd = &sc->sc_tx_rdata[BWI_TX_DATA_RING];
|
||||||
struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING];
|
struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING];
|
||||||
struct bwi_txbuf *tb = &tbd->tbd_buf[idx];
|
struct bwi_txbuf *tb = &tbd->tbd_buf[idx];
|
||||||
@ -3169,7 +3161,7 @@ bwi_encap_raw(struct bwi_softc *sc, int idx, struct mbuf *m,
|
|||||||
/*
|
/*
|
||||||
* TX radio tap
|
* TX radio tap
|
||||||
*/
|
*/
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active_vap(vap)) {
|
||||||
sc->sc_tx_th.wt_flags = 0;
|
sc->sc_tx_th.wt_flags = 0;
|
||||||
/* XXX IEEE80211_BPF_CRYPTO */
|
/* XXX IEEE80211_BPF_CRYPTO */
|
||||||
if (wh->i_fc[1] & IEEE80211_FC1_WEP)
|
if (wh->i_fc[1] & IEEE80211_FC1_WEP)
|
||||||
@ -3178,7 +3170,7 @@ bwi_encap_raw(struct bwi_softc *sc, int idx, struct mbuf *m,
|
|||||||
sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
|
sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
|
||||||
sc->sc_tx_th.wt_rate = rate;
|
sc->sc_tx_th.wt_rate = rate;
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, &sc->sc_tx_th, sc->sc_tx_th_len, m);
|
ieee80211_radiotap_tx(vap, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3806,10 +3798,9 @@ bwi_ds_plcp2rate(const struct ieee80211_ds_plcp_hdr *hdr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bwi_rx_radiotap(struct ifnet *ifp, struct mbuf *m,
|
bwi_rx_radiotap(struct bwi_softc *sc, struct mbuf *m,
|
||||||
struct bwi_rxbuf_hdr *hdr, const void *plcp, int rate, int rssi, int noise)
|
struct bwi_rxbuf_hdr *hdr, const void *plcp, int rate, int rssi, int noise)
|
||||||
{
|
{
|
||||||
struct bwi_softc *sc = ifp->if_softc;
|
|
||||||
const struct ieee80211_frame_min *wh;
|
const struct ieee80211_frame_min *wh;
|
||||||
|
|
||||||
sc->sc_rx_th.wr_flags = IEEE80211_RADIOTAP_F_FCS;
|
sc->sc_rx_th.wr_flags = IEEE80211_RADIOTAP_F_FCS;
|
||||||
@ -3824,8 +3815,6 @@ bwi_rx_radiotap(struct ifnet *ifp, struct mbuf *m,
|
|||||||
sc->sc_rx_th.wr_rate = rate;
|
sc->sc_rx_th.wr_rate = rate;
|
||||||
sc->sc_rx_th.wr_antsignal = rssi;
|
sc->sc_rx_th.wr_antsignal = rssi;
|
||||||
sc->sc_rx_th.wr_antnoise = noise;
|
sc->sc_rx_th.wr_antnoise = noise;
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, &sc->sc_rx_th, sc->sc_rx_th_len, m);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -615,9 +615,7 @@ struct bwi_softc {
|
|||||||
const struct ieee80211_rate_table *sc_rates;
|
const struct ieee80211_rate_table *sc_rates;
|
||||||
|
|
||||||
struct bwi_tx_radiotap_hdr sc_tx_th;
|
struct bwi_tx_radiotap_hdr sc_tx_th;
|
||||||
int sc_tx_th_len;
|
|
||||||
struct bwi_rx_radiotap_hdr sc_rx_th;
|
struct bwi_rx_radiotap_hdr sc_rx_th;
|
||||||
int sc_rx_th_len;
|
|
||||||
|
|
||||||
struct taskqueue *sc_tq;
|
struct taskqueue *sc_tq;
|
||||||
struct task sc_restart_task;
|
struct task sc_restart_task;
|
||||||
|
@ -346,16 +346,11 @@ ipw_attach(device_t dev)
|
|||||||
ic->ic_vap_create = ipw_vap_create;
|
ic->ic_vap_create = ipw_vap_create;
|
||||||
ic->ic_vap_delete = ipw_vap_delete;
|
ic->ic_vap_delete = ipw_vap_delete;
|
||||||
|
|
||||||
bpfattach(ifp, DLT_IEEE802_11_RADIO,
|
ieee80211_radiotap_attach(ic,
|
||||||
sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap));
|
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
|
||||||
|
IPW_TX_RADIOTAP_PRESENT,
|
||||||
sc->sc_rxtap_len = sizeof sc->sc_rxtap;
|
&sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
|
||||||
sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
|
IPW_RX_RADIOTAP_PRESENT);
|
||||||
sc->sc_rxtap.wr_ihdr.it_present = htole32(IPW_RX_RADIOTAP_PRESENT);
|
|
||||||
|
|
||||||
sc->sc_txtap_len = sizeof sc->sc_txtap;
|
|
||||||
sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
|
|
||||||
sc->sc_txtap.wt_ihdr.it_present = htole32(IPW_TX_RADIOTAP_PRESENT);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add a few sysctl knobs.
|
* Add a few sysctl knobs.
|
||||||
@ -407,7 +402,6 @@ ipw_detach(device_t dev)
|
|||||||
ieee80211_draintask(ic, &sc->sc_init_task);
|
ieee80211_draintask(ic, &sc->sc_init_task);
|
||||||
ipw_stop(sc);
|
ipw_stop(sc);
|
||||||
|
|
||||||
bpfdetach(ifp);
|
|
||||||
ieee80211_ifdetach(ic);
|
ieee80211_ifdetach(ic);
|
||||||
|
|
||||||
callout_drain(&sc->sc_wdtimer);
|
callout_drain(&sc->sc_wdtimer);
|
||||||
@ -1107,10 +1101,7 @@ ipw_setcurchan(struct ipw_softc *sc, struct ieee80211_channel *chan)
|
|||||||
struct ieee80211com *ic = ifp->if_l2com;
|
struct ieee80211com *ic = ifp->if_l2com;
|
||||||
|
|
||||||
ic->ic_curchan = chan;
|
ic->ic_curchan = chan;
|
||||||
sc->sc_rxtap.wr_chan_freq = sc->sc_txtap.wt_chan_freq =
|
ieee80211_radiotap_chan_change(ic);
|
||||||
htole16(ic->ic_curchan->ic_freq);
|
|
||||||
sc->sc_rxtap.wr_chan_flags = sc->sc_txtap.wt_chan_flags =
|
|
||||||
htole16(ic->ic_curchan->ic_flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1172,6 +1163,7 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status,
|
|||||||
struct ieee80211_node *ni;
|
struct ieee80211_node *ni;
|
||||||
bus_addr_t physaddr;
|
bus_addr_t physaddr;
|
||||||
int error;
|
int error;
|
||||||
|
int8_t rssi, nf;
|
||||||
IPW_LOCK_DECL;
|
IPW_LOCK_DECL;
|
||||||
|
|
||||||
DPRINTFN(5, ("received frame len=%u, rssi=%u\n", le32toh(status->len),
|
DPRINTFN(5, ("received frame len=%u, rssi=%u\n", le32toh(status->len),
|
||||||
@ -1226,15 +1218,14 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status,
|
|||||||
m->m_pkthdr.rcvif = ifp;
|
m->m_pkthdr.rcvif = ifp;
|
||||||
m->m_pkthdr.len = m->m_len = le32toh(status->len);
|
m->m_pkthdr.len = m->m_len = le32toh(status->len);
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
rssi = status->rssi + IPW_RSSI_TO_DBM;
|
||||||
|
nf = -95;
|
||||||
|
if (ieee80211_radiotap_active(ic)) {
|
||||||
struct ipw_rx_radiotap_header *tap = &sc->sc_rxtap;
|
struct ipw_rx_radiotap_header *tap = &sc->sc_rxtap;
|
||||||
|
|
||||||
tap->wr_flags = 0;
|
tap->wr_flags = 0;
|
||||||
tap->wr_antsignal = status->rssi + IPW_RSSI_TO_DBM;
|
tap->wr_antsignal = rssi;
|
||||||
tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
|
tap->wr_antnoise = nf;
|
||||||
tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
|
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sc->flags & IPW_FLAG_SCANNING)
|
if (sc->flags & IPW_FLAG_SCANNING)
|
||||||
@ -1243,10 +1234,10 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status,
|
|||||||
IPW_UNLOCK(sc);
|
IPW_UNLOCK(sc);
|
||||||
ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
|
ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
|
||||||
if (ni != NULL) {
|
if (ni != NULL) {
|
||||||
(void) ieee80211_input(ni, m, status->rssi, -95, 0);
|
(void) ieee80211_input(ni, m, rssi, nf);
|
||||||
ieee80211_free_node(ni);
|
ieee80211_free_node(ni);
|
||||||
} else
|
} else
|
||||||
(void) ieee80211_input_all(ic, m, status->rssi, -95, 0);
|
(void) ieee80211_input_all(ic, m, rssi, nf);
|
||||||
IPW_LOCK(sc);
|
IPW_LOCK(sc);
|
||||||
|
|
||||||
bus_dmamap_sync(sc->rbd_dmat, sc->rbd_map, BUS_DMASYNC_PREWRITE);
|
bus_dmamap_sync(sc->rbd_dmat, sc->rbd_map, BUS_DMASYNC_PREWRITE);
|
||||||
@ -1570,6 +1561,7 @@ ipw_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni)
|
|||||||
{
|
{
|
||||||
struct ipw_softc *sc = ifp->if_softc;
|
struct ipw_softc *sc = ifp->if_softc;
|
||||||
struct ieee80211com *ic = ifp->if_l2com;
|
struct ieee80211com *ic = ifp->if_l2com;
|
||||||
|
struct ieee80211vap *vap = ni->ni_vap;
|
||||||
struct ieee80211_frame *wh;
|
struct ieee80211_frame *wh;
|
||||||
struct ipw_soft_bd *sbd;
|
struct ipw_soft_bd *sbd;
|
||||||
struct ipw_soft_hdr *shdr;
|
struct ipw_soft_hdr *shdr;
|
||||||
@ -1592,14 +1584,12 @@ ipw_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni)
|
|||||||
wh = mtod(m0, struct ieee80211_frame *);
|
wh = mtod(m0, struct ieee80211_frame *);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active_vap(vap)) {
|
||||||
struct ipw_tx_radiotap_header *tap = &sc->sc_txtap;
|
struct ipw_tx_radiotap_header *tap = &sc->sc_txtap;
|
||||||
|
|
||||||
tap->wt_flags = 0;
|
tap->wt_flags = 0;
|
||||||
tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
|
|
||||||
tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
|
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
|
ieee80211_radiotap_tx(vap, m0);
|
||||||
}
|
}
|
||||||
|
|
||||||
shdr = SLIST_FIRST(&sc->free_shdr);
|
shdr = SLIST_FIRST(&sc->free_shdr);
|
||||||
|
@ -57,13 +57,15 @@ struct ipw_rx_radiotap_header {
|
|||||||
uint8_t wr_flags;
|
uint8_t wr_flags;
|
||||||
uint16_t wr_chan_freq;
|
uint16_t wr_chan_freq;
|
||||||
uint16_t wr_chan_flags;
|
uint16_t wr_chan_flags;
|
||||||
uint8_t wr_antsignal;
|
int8_t wr_antsignal;
|
||||||
|
int8_t wr_antnoise;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IPW_RX_RADIOTAP_PRESENT \
|
#define IPW_RX_RADIOTAP_PRESENT \
|
||||||
((1 << IEEE80211_RADIOTAP_FLAGS) | \
|
((1 << IEEE80211_RADIOTAP_FLAGS) | \
|
||||||
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
||||||
(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL))
|
(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \
|
||||||
|
(1 << IEEE80211_RADIOTAP_DB_ANTNOISE))
|
||||||
|
|
||||||
struct ipw_tx_radiotap_header {
|
struct ipw_tx_radiotap_header {
|
||||||
struct ieee80211_radiotap_header wt_ihdr;
|
struct ieee80211_radiotap_header wt_ihdr;
|
||||||
@ -155,10 +157,7 @@ struct ipw_softc {
|
|||||||
int txfree;
|
int txfree;
|
||||||
|
|
||||||
struct ipw_rx_radiotap_header sc_rxtap;
|
struct ipw_rx_radiotap_header sc_rxtap;
|
||||||
int sc_rxtap_len;
|
|
||||||
|
|
||||||
struct ipw_tx_radiotap_header sc_txtap;
|
struct ipw_tx_radiotap_header sc_txtap;
|
||||||
int sc_txtap_len;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -419,16 +419,11 @@ iwi_attach(device_t dev)
|
|||||||
ic->ic_vap_create = iwi_vap_create;
|
ic->ic_vap_create = iwi_vap_create;
|
||||||
ic->ic_vap_delete = iwi_vap_delete;
|
ic->ic_vap_delete = iwi_vap_delete;
|
||||||
|
|
||||||
bpfattach(ifp, DLT_IEEE802_11_RADIO,
|
ieee80211_radiotap_attach(ic,
|
||||||
sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap));
|
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
|
||||||
|
IWI_TX_RADIOTAP_PRESENT,
|
||||||
sc->sc_rxtap_len = sizeof sc->sc_rxtap;
|
&sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
|
||||||
sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
|
IWI_RX_RADIOTAP_PRESENT);
|
||||||
sc->sc_rxtap.wr_ihdr.it_present = htole32(IWI_RX_RADIOTAP_PRESENT);
|
|
||||||
|
|
||||||
sc->sc_txtap_len = sizeof sc->sc_txtap;
|
|
||||||
sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
|
|
||||||
sc->sc_txtap.wt_ihdr.it_present = htole32(IWI_TX_RADIOTAP_PRESENT);
|
|
||||||
|
|
||||||
iwi_sysctlattach(sc);
|
iwi_sysctlattach(sc);
|
||||||
iwi_ledattach(sc);
|
iwi_ledattach(sc);
|
||||||
@ -468,7 +463,6 @@ iwi_detach(device_t dev)
|
|||||||
|
|
||||||
iwi_stop(sc);
|
iwi_stop(sc);
|
||||||
|
|
||||||
bpfdetach(ifp);
|
|
||||||
ieee80211_ifdetach(ic);
|
ieee80211_ifdetach(ic);
|
||||||
|
|
||||||
iwi_put_firmware(sc);
|
iwi_put_firmware(sc);
|
||||||
@ -1196,11 +1190,7 @@ iwi_setcurchan(struct iwi_softc *sc, int chan)
|
|||||||
struct ieee80211com *ic = ifp->if_l2com;
|
struct ieee80211com *ic = ifp->if_l2com;
|
||||||
|
|
||||||
sc->curchan = chan;
|
sc->curchan = chan;
|
||||||
|
ieee80211_radiotap_chan_change(ic);
|
||||||
sc->sc_rxtap.wr_chan_freq = sc->sc_txtap.wt_chan_freq =
|
|
||||||
htole16(ic->ic_curchan->ic_freq);
|
|
||||||
sc->sc_rxtap.wr_chan_flags = sc->sc_txtap.wt_chan_flags =
|
|
||||||
htole16(ic->ic_curchan->ic_flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1212,6 +1202,7 @@ iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_data *data, int i,
|
|||||||
struct mbuf *mnew, *m;
|
struct mbuf *mnew, *m;
|
||||||
struct ieee80211_node *ni;
|
struct ieee80211_node *ni;
|
||||||
int type, error, framelen;
|
int type, error, framelen;
|
||||||
|
int8_t rssi, nf;
|
||||||
IWI_LOCK_DECL;
|
IWI_LOCK_DECL;
|
||||||
|
|
||||||
framelen = le16toh(frame->len);
|
framelen = le16toh(frame->len);
|
||||||
@ -1283,24 +1274,25 @@ iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_data *data, int i,
|
|||||||
|
|
||||||
m_adj(m, sizeof (struct iwi_hdr) + sizeof (struct iwi_frame));
|
m_adj(m, sizeof (struct iwi_hdr) + sizeof (struct iwi_frame));
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
rssi = frame->signal;
|
||||||
|
nf = -95;
|
||||||
|
if (ieee80211_radiotap_active(ic)) {
|
||||||
struct iwi_rx_radiotap_header *tap = &sc->sc_rxtap;
|
struct iwi_rx_radiotap_header *tap = &sc->sc_rxtap;
|
||||||
|
|
||||||
tap->wr_flags = 0;
|
tap->wr_flags = 0;
|
||||||
|
tap->wr_antsignal = rssi;
|
||||||
|
tap->wr_antnoise = nf;
|
||||||
tap->wr_rate = iwi_cvtrate(frame->rate);
|
tap->wr_rate = iwi_cvtrate(frame->rate);
|
||||||
tap->wr_antsignal = frame->signal;
|
|
||||||
tap->wr_antenna = frame->antenna;
|
tap->wr_antenna = frame->antenna;
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
|
|
||||||
}
|
}
|
||||||
IWI_UNLOCK(sc);
|
IWI_UNLOCK(sc);
|
||||||
|
|
||||||
ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
|
ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
|
||||||
if (ni != NULL) {
|
if (ni != NULL) {
|
||||||
type = ieee80211_input(ni, m, frame->rssi_dbm, 0, 0);
|
type = ieee80211_input(ni, m, rssi, nf);
|
||||||
ieee80211_free_node(ni);
|
ieee80211_free_node(ni);
|
||||||
} else
|
} else
|
||||||
type = ieee80211_input_all(ic, m, frame->rssi_dbm, 0, 0);
|
type = ieee80211_input_all(ic, m, rssi, nf);
|
||||||
|
|
||||||
IWI_LOCK(sc);
|
IWI_LOCK(sc);
|
||||||
if (sc->sc_softled) {
|
if (sc->sc_softled) {
|
||||||
@ -1852,12 +1844,12 @@ iwi_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni,
|
|||||||
wh = mtod(m0, struct ieee80211_frame *);
|
wh = mtod(m0, struct ieee80211_frame *);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active_vap(vap)) {
|
||||||
struct iwi_tx_radiotap_header *tap = &sc->sc_txtap;
|
struct iwi_tx_radiotap_header *tap = &sc->sc_txtap;
|
||||||
|
|
||||||
tap->wt_flags = 0;
|
tap->wt_flags = 0;
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
|
ieee80211_radiotap_tx(vap, m0);
|
||||||
}
|
}
|
||||||
|
|
||||||
data = &txq->data[txq->cur];
|
data = &txq->data[txq->cur];
|
||||||
|
@ -33,7 +33,8 @@ struct iwi_rx_radiotap_header {
|
|||||||
uint8_t wr_rate;
|
uint8_t wr_rate;
|
||||||
uint16_t wr_chan_freq;
|
uint16_t wr_chan_freq;
|
||||||
uint16_t wr_chan_flags;
|
uint16_t wr_chan_flags;
|
||||||
uint8_t wr_antsignal;
|
int8_t wr_antsignal;
|
||||||
|
int8_t wr_antnoise;
|
||||||
uint8_t wr_antenna;
|
uint8_t wr_antenna;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -42,6 +43,7 @@ struct iwi_rx_radiotap_header {
|
|||||||
(1 << IEEE80211_RADIOTAP_RATE) | \
|
(1 << IEEE80211_RADIOTAP_RATE) | \
|
||||||
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
||||||
(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \
|
(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \
|
||||||
|
(1 << IEEE80211_RADIOTAP_DB_ANTNOISE) | \
|
||||||
(1 << IEEE80211_RADIOTAP_ANTENNA))
|
(1 << IEEE80211_RADIOTAP_ANTENNA))
|
||||||
|
|
||||||
struct iwi_tx_radiotap_header {
|
struct iwi_tx_radiotap_header {
|
||||||
@ -213,10 +215,7 @@ struct iwi_softc {
|
|||||||
int sc_busy_timer; /* firmware cmd timer */
|
int sc_busy_timer; /* firmware cmd timer */
|
||||||
|
|
||||||
struct iwi_rx_radiotap_header sc_rxtap;
|
struct iwi_rx_radiotap_header sc_rxtap;
|
||||||
int sc_rxtap_len;
|
|
||||||
|
|
||||||
struct iwi_tx_radiotap_header sc_txtap;
|
struct iwi_tx_radiotap_header sc_txtap;
|
||||||
int sc_txtap_len;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IWI_STATE_BEGIN(_sc, _state) do { \
|
#define IWI_STATE_BEGIN(_sc, _state) do { \
|
||||||
|
@ -185,7 +185,6 @@ static void iwn_scan_mindwell(struct ieee80211_scan_state *);
|
|||||||
static void iwn_hwreset(void *, int);
|
static void iwn_hwreset(void *, int);
|
||||||
static void iwn_radioon(void *, int);
|
static void iwn_radioon(void *, int);
|
||||||
static void iwn_radiooff(void *, int);
|
static void iwn_radiooff(void *, int);
|
||||||
static void iwn_bpfattach(struct iwn_softc *);
|
|
||||||
static void iwn_sysctlattach(struct iwn_softc *);
|
static void iwn_sysctlattach(struct iwn_softc *);
|
||||||
|
|
||||||
#define IWN_DEBUG
|
#define IWN_DEBUG
|
||||||
@ -426,7 +425,12 @@ iwn_attach(device_t dev)
|
|||||||
ic->ic_scan_curchan = iwn_scan_curchan;
|
ic->ic_scan_curchan = iwn_scan_curchan;
|
||||||
ic->ic_scan_mindwell = iwn_scan_mindwell;
|
ic->ic_scan_mindwell = iwn_scan_mindwell;
|
||||||
|
|
||||||
iwn_bpfattach(sc);
|
ieee80211_radiotap_attach(ic,
|
||||||
|
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
|
||||||
|
IWN_TX_RADIOTAP_PRESENT,
|
||||||
|
&sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
|
||||||
|
IWN_RX_RADIOTAP_PRESENT);
|
||||||
|
|
||||||
iwn_sysctlattach(sc);
|
iwn_sysctlattach(sc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -471,7 +475,6 @@ iwn_cleanup(device_t dev)
|
|||||||
if (ifp != NULL) {
|
if (ifp != NULL) {
|
||||||
iwn_stop(sc);
|
iwn_stop(sc);
|
||||||
callout_drain(&sc->sc_timer_to);
|
callout_drain(&sc->sc_timer_to);
|
||||||
bpfdetach(ifp);
|
|
||||||
ieee80211_ifdetach(ic);
|
ieee80211_ifdetach(ic);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1472,29 +1475,26 @@ iwn_rx_intr(struct iwn_softc *sc, struct iwn_rx_desc *desc,
|
|||||||
nf = (ni != NULL && ni->ni_vap->iv_state == IEEE80211_S_RUN &&
|
nf = (ni != NULL && ni->ni_vap->iv_state == IEEE80211_S_RUN &&
|
||||||
(ic->ic_flags & IEEE80211_F_SCAN) == 0) ? sc->noise : -95;
|
(ic->ic_flags & IEEE80211_F_SCAN) == 0) ? sc->noise : -95;
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active(ic)) {
|
||||||
struct iwn_rx_radiotap_header *tap = &sc->sc_rxtap;
|
struct iwn_rx_radiotap_header *tap = &sc->sc_rxtap;
|
||||||
|
|
||||||
tap->wr_flags = 0;
|
|
||||||
tap->wr_dbm_antsignal = rssi;
|
|
||||||
tap->wr_dbm_antnoise = nf;
|
|
||||||
tap->wr_rate = maprate(stat->rate);
|
|
||||||
tap->wr_tsft = htole64(stat->tstamp);
|
tap->wr_tsft = htole64(stat->tstamp);
|
||||||
|
tap->wr_flags = 0;
|
||||||
if (stat->flags & htole16(IWN_CONFIG_SHPREAMBLE))
|
if (stat->flags & htole16(IWN_CONFIG_SHPREAMBLE))
|
||||||
tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
|
tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
|
||||||
|
tap->wr_rate = maprate(stat->rate);
|
||||||
bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
|
tap->wr_dbm_antsignal = rssi;
|
||||||
|
tap->wr_dbm_antnoise = nf;
|
||||||
}
|
}
|
||||||
|
|
||||||
IWN_UNLOCK(sc);
|
IWN_UNLOCK(sc);
|
||||||
|
|
||||||
/* send the frame to the 802.11 layer */
|
/* send the frame to the 802.11 layer */
|
||||||
if (ni != NULL) {
|
if (ni != NULL) {
|
||||||
(void) ieee80211_input(ni, m, rssi - nf, nf, 0);
|
(void) ieee80211_input(ni, m, rssi - nf, nf);
|
||||||
ieee80211_free_node(ni);
|
ieee80211_free_node(ni);
|
||||||
} else
|
} else
|
||||||
(void) ieee80211_input_all(ic, m, rssi - nf, nf, 0);
|
(void) ieee80211_input_all(ic, m, rssi - nf, nf);
|
||||||
|
|
||||||
IWN_LOCK(sc);
|
IWN_LOCK(sc);
|
||||||
}
|
}
|
||||||
@ -1931,7 +1931,7 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
|
|||||||
} else
|
} else
|
||||||
k = NULL;
|
k = NULL;
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active_vap(vap)) {
|
||||||
struct iwn_tx_radiotap_header *tap = &sc->sc_txtap;
|
struct iwn_tx_radiotap_header *tap = &sc->sc_txtap;
|
||||||
|
|
||||||
tap->wt_flags = 0;
|
tap->wt_flags = 0;
|
||||||
@ -1939,7 +1939,7 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
|
|||||||
if (k != NULL)
|
if (k != NULL)
|
||||||
tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
|
tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
|
ieee80211_radiotap_tx(vap, m0);
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = IWN_TX_AUTO_SEQ;
|
flags = IWN_TX_AUTO_SEQ;
|
||||||
@ -2226,7 +2226,7 @@ iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m0,
|
|||||||
struct ieee80211_node *ni, struct iwn_tx_ring *ring,
|
struct ieee80211_node *ni, struct iwn_tx_ring *ring,
|
||||||
const struct ieee80211_bpf_params *params)
|
const struct ieee80211_bpf_params *params)
|
||||||
{
|
{
|
||||||
struct ifnet *ifp = sc->sc_ifp;
|
struct ieee80211vap *vap = ni->ni_vap;
|
||||||
struct iwn_tx_cmd *cmd;
|
struct iwn_tx_cmd *cmd;
|
||||||
struct iwn_cmd_data *tx;
|
struct iwn_cmd_data *tx;
|
||||||
struct ieee80211_frame *wh;
|
struct ieee80211_frame *wh;
|
||||||
@ -2264,13 +2264,13 @@ iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m0,
|
|||||||
/* pick a tx rate */
|
/* pick a tx rate */
|
||||||
rate = params->ibp_rate0;
|
rate = params->ibp_rate0;
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active_vap(vap)) {
|
||||||
struct iwn_tx_radiotap_header *tap = &sc->sc_txtap;
|
struct iwn_tx_radiotap_header *tap = &sc->sc_txtap;
|
||||||
|
|
||||||
tap->wt_flags = 0;
|
tap->wt_flags = 0;
|
||||||
tap->wt_rate = rate;
|
tap->wt_rate = rate;
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
|
ieee80211_radiotap_tx(vap, m0);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = &ring->cmd[ring->cur];
|
cmd = &ring->cmd[ring->cur];
|
||||||
@ -4411,23 +4411,6 @@ iwn_radiooff(void *arg0, int pending)
|
|||||||
IWN_UNLOCK(sc);
|
IWN_UNLOCK(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
iwn_bpfattach(struct iwn_softc *sc)
|
|
||||||
{
|
|
||||||
struct ifnet *ifp = sc->sc_ifp;
|
|
||||||
|
|
||||||
bpfattach(ifp, DLT_IEEE802_11_RADIO,
|
|
||||||
sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap));
|
|
||||||
|
|
||||||
sc->sc_rxtap_len = sizeof sc->sc_rxtap;
|
|
||||||
sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
|
|
||||||
sc->sc_rxtap.wr_ihdr.it_present = htole32(IWN_RX_RADIOTAP_PRESENT);
|
|
||||||
|
|
||||||
sc->sc_txtap_len = sizeof sc->sc_txtap;
|
|
||||||
sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
|
|
||||||
sc->sc_txtap.wt_ihdr.it_present = htole32(IWN_TX_RADIOTAP_PRESENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
iwn_sysctlattach(struct iwn_softc *sc)
|
iwn_sysctlattach(struct iwn_softc *sc)
|
||||||
{
|
{
|
||||||
|
@ -144,9 +144,7 @@ struct iwn_softc {
|
|||||||
const struct ieee80211_channel *sc_curchan;
|
const struct ieee80211_channel *sc_curchan;
|
||||||
|
|
||||||
struct iwn_rx_radiotap_header sc_rxtap;
|
struct iwn_rx_radiotap_header sc_rxtap;
|
||||||
int sc_rxtap_len;
|
|
||||||
struct iwn_tx_radiotap_header sc_txtap;
|
struct iwn_tx_radiotap_header sc_txtap;
|
||||||
int sc_txtap_len;
|
|
||||||
|
|
||||||
/* locks */
|
/* locks */
|
||||||
struct mtx sc_mtx;
|
struct mtx sc_mtx;
|
||||||
|
@ -144,7 +144,6 @@ static void malo_scan_end(struct ieee80211com *);
|
|||||||
static void malo_set_channel(struct ieee80211com *);
|
static void malo_set_channel(struct ieee80211com *);
|
||||||
static int malo_raw_xmit(struct ieee80211_node *, struct mbuf *,
|
static int malo_raw_xmit(struct ieee80211_node *, struct mbuf *,
|
||||||
const struct ieee80211_bpf_params *);
|
const struct ieee80211_bpf_params *);
|
||||||
static void malo_bpfattach(struct malo_softc *);
|
|
||||||
static void malo_sysctlattach(struct malo_softc *);
|
static void malo_sysctlattach(struct malo_softc *);
|
||||||
static void malo_announce(struct malo_softc *);
|
static void malo_announce(struct malo_softc *);
|
||||||
static void malo_dma_cleanup(struct malo_softc *);
|
static void malo_dma_cleanup(struct malo_softc *);
|
||||||
@ -317,7 +316,11 @@ malo_attach(uint16_t devid, struct malo_softc *sc)
|
|||||||
|
|
||||||
sc->malo_invalid = 0; /* ready to go, enable int handling */
|
sc->malo_invalid = 0; /* ready to go, enable int handling */
|
||||||
|
|
||||||
malo_bpfattach(sc);
|
ieee80211_radiotap_attach(ic,
|
||||||
|
&sc->malo_tx_th.wt_ihdr, sizeof(sc->malo_tx_th),
|
||||||
|
MALO_TX_RADIOTAP_PRESENT,
|
||||||
|
&sc->malo_rx_th.wr_ihdr, sizeof(sc->malo_rx_th),
|
||||||
|
MALO_RX_RADIOTAP_PRESENT);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup dynamic sysctl's.
|
* Setup dynamic sysctl's.
|
||||||
@ -1091,6 +1094,7 @@ malo_tx_start(struct malo_softc *sc, struct ieee80211_node *ni,
|
|||||||
struct ieee80211_frame *wh;
|
struct ieee80211_frame *wh;
|
||||||
struct ifnet *ifp = sc->malo_ifp;
|
struct ifnet *ifp = sc->malo_ifp;
|
||||||
struct ieee80211com *ic = ifp->if_l2com;
|
struct ieee80211com *ic = ifp->if_l2com;
|
||||||
|
struct ieee80211vap *vap = ni->ni_vap;
|
||||||
struct malo_txdesc *ds;
|
struct malo_txdesc *ds;
|
||||||
struct malo_txrec *tr;
|
struct malo_txrec *tr;
|
||||||
struct malo_txq *txq;
|
struct malo_txq *txq;
|
||||||
@ -1148,14 +1152,14 @@ malo_tx_start(struct malo_softc *sc, struct ieee80211_node *ni,
|
|||||||
wh = mtod(m0, struct ieee80211_frame *);
|
wh = mtod(m0, struct ieee80211_frame *);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active_vap(vap)) {
|
||||||
sc->malo_tx_th.wt_flags = 0; /* XXX */
|
sc->malo_tx_th.wt_flags = 0; /* XXX */
|
||||||
if (iswep)
|
if (iswep)
|
||||||
sc->malo_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
|
sc->malo_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
|
||||||
sc->malo_tx_th.wt_txpower = ni->ni_txpower;
|
sc->malo_tx_th.wt_txpower = ni->ni_txpower;
|
||||||
sc->malo_tx_th.wt_antenna = sc->malo_txantenna;
|
sc->malo_tx_th.wt_antenna = sc->malo_txantenna;
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, &sc->malo_tx_th, sc->malo_tx_th_len, m0);
|
ieee80211_radiotap_tx(vap, m0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1899,32 +1903,6 @@ malo_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
malo_bpfattach(struct malo_softc *sc)
|
|
||||||
{
|
|
||||||
struct ifnet *ifp = sc->malo_ifp;
|
|
||||||
|
|
||||||
bpfattach(ifp, DLT_IEEE802_11_RADIO,
|
|
||||||
sizeof(struct ieee80211_frame) + sizeof(sc->malo_tx_th));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize constant fields.
|
|
||||||
* XXX make header lengths a multiple of 32-bits so subsequent
|
|
||||||
* headers are properly aligned; this is a kludge to keep
|
|
||||||
* certain applications happy.
|
|
||||||
*
|
|
||||||
* NB: the channel is setup each time we transition to the
|
|
||||||
* RUN state to avoid filling it in for each frame.
|
|
||||||
*/
|
|
||||||
sc->malo_tx_th_len = roundup(sizeof(sc->malo_tx_th), sizeof(uint32_t));
|
|
||||||
sc->malo_tx_th.wt_ihdr.it_len = htole16(sc->malo_tx_th_len);
|
|
||||||
sc->malo_tx_th.wt_ihdr.it_present = htole32(MALO_TX_RADIOTAP_PRESENT);
|
|
||||||
|
|
||||||
sc->malo_rx_th_len = roundup(sizeof(sc->malo_rx_th), sizeof(uint32_t));
|
|
||||||
sc->malo_rx_th.wr_ihdr.it_len = htole16(sc->malo_rx_th_len);
|
|
||||||
sc->malo_rx_th.wr_ihdr.it_present = htole32(MALO_RX_RADIOTAP_PRESENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
malo_sysctlattach(struct malo_softc *sc)
|
malo_sysctlattach(struct malo_softc *sc)
|
||||||
{
|
{
|
||||||
@ -2173,14 +2151,11 @@ malo_rx_proc(void *arg, int npending)
|
|||||||
*(uint16_t *)wh->i_qos = ds->qosctrl;
|
*(uint16_t *)wh->i_qos = ds->qosctrl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sc->malo_drvbpf != NULL) {
|
if (ieee80211_radiotap_active(ic)) {
|
||||||
sc->malo_rx_th.wr_flags = 0;
|
sc->malo_rx_th.wr_flags = 0;
|
||||||
sc->malo_rx_th.wr_rate = ds->rate;
|
sc->malo_rx_th.wr_rate = ds->rate;
|
||||||
sc->malo_rx_th.wr_antsignal = rssi;
|
sc->malo_rx_th.wr_antsignal = rssi;
|
||||||
sc->malo_rx_th.wr_antnoise = ds->nf;
|
sc->malo_rx_th.wr_antnoise = ds->nf;
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, &sc->malo_rx_th,
|
|
||||||
sc->malo_rx_th_len, m);
|
|
||||||
}
|
}
|
||||||
#ifdef MALO_DEBUG
|
#ifdef MALO_DEBUG
|
||||||
if (IFF_DUMPPKTS_RECV(sc, wh)) {
|
if (IFF_DUMPPKTS_RECV(sc, wh)) {
|
||||||
@ -2194,10 +2169,10 @@ malo_rx_proc(void *arg, int npending)
|
|||||||
ni = ieee80211_find_rxnode(ic,
|
ni = ieee80211_find_rxnode(ic,
|
||||||
(struct ieee80211_frame_min *)wh);
|
(struct ieee80211_frame_min *)wh);
|
||||||
if (ni != NULL) {
|
if (ni != NULL) {
|
||||||
(void) ieee80211_input(ni, m, rssi, ds->nf, 0);
|
(void) ieee80211_input(ni, m, rssi, ds->nf);
|
||||||
ieee80211_free_node(ni);
|
ieee80211_free_node(ni);
|
||||||
} else
|
} else
|
||||||
(void) ieee80211_input_all(ic, m, rssi, ds->nf, 0);
|
(void) ieee80211_input_all(ic, m, rssi, ds->nf);
|
||||||
rx_next:
|
rx_next:
|
||||||
/* NB: ignore ENOMEM so we process more descriptors */
|
/* NB: ignore ENOMEM so we process more descriptors */
|
||||||
(void) malo_rxbuf_init(sc, bf);
|
(void) malo_rxbuf_init(sc, bf);
|
||||||
@ -2253,8 +2228,6 @@ malo_detach(struct malo_softc *sc)
|
|||||||
sc->malo_tq = NULL;
|
sc->malo_tq = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bpfdetach(ifp);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NB: the order of these is important:
|
* NB: the order of these is important:
|
||||||
* o call the 802.11 layer before detaching the hal to
|
* o call the 802.11 layer before detaching the hal to
|
||||||
|
@ -551,11 +551,8 @@ struct malo_softc {
|
|||||||
struct malo_txq malo_txq[MALO_NUM_TX_QUEUES];
|
struct malo_txq malo_txq[MALO_NUM_TX_QUEUES];
|
||||||
struct task malo_txtask; /* tx int processing */
|
struct task malo_txtask; /* tx int processing */
|
||||||
|
|
||||||
struct bpf_if *malo_drvbpf;
|
|
||||||
struct malo_tx_radiotap_header malo_tx_th;
|
struct malo_tx_radiotap_header malo_tx_th;
|
||||||
int malo_tx_th_len;
|
|
||||||
struct malo_rx_radiotap_header malo_rx_th;
|
struct malo_rx_radiotap_header malo_rx_th;
|
||||||
int malo_rx_th_len;
|
|
||||||
|
|
||||||
struct malo_stats malo_stats; /* interface statistics */
|
struct malo_stats malo_stats; /* interface statistics */
|
||||||
int malo_debug;
|
int malo_debug;
|
||||||
|
@ -144,6 +144,7 @@ static void rt2560_set_chan(struct rt2560_softc *,
|
|||||||
static void rt2560_disable_rf_tune(struct rt2560_softc *);
|
static void rt2560_disable_rf_tune(struct rt2560_softc *);
|
||||||
#endif
|
#endif
|
||||||
static void rt2560_enable_tsf_sync(struct rt2560_softc *);
|
static void rt2560_enable_tsf_sync(struct rt2560_softc *);
|
||||||
|
static void rt2560_enable_tsf(struct rt2560_softc *);
|
||||||
static void rt2560_update_plcp(struct rt2560_softc *);
|
static void rt2560_update_plcp(struct rt2560_softc *);
|
||||||
static void rt2560_update_slot(struct ifnet *);
|
static void rt2560_update_slot(struct ifnet *);
|
||||||
static void rt2560_set_basicrates(struct rt2560_softc *);
|
static void rt2560_set_basicrates(struct rt2560_softc *);
|
||||||
@ -313,16 +314,11 @@ rt2560_attach(device_t dev, int id)
|
|||||||
ic->ic_vap_create = rt2560_vap_create;
|
ic->ic_vap_create = rt2560_vap_create;
|
||||||
ic->ic_vap_delete = rt2560_vap_delete;
|
ic->ic_vap_delete = rt2560_vap_delete;
|
||||||
|
|
||||||
bpfattach(ifp, DLT_IEEE802_11_RADIO,
|
ieee80211_radiotap_attach(ic,
|
||||||
sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap));
|
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
|
||||||
|
RT2560_TX_RADIOTAP_PRESENT,
|
||||||
sc->sc_rxtap_len = sizeof sc->sc_rxtap;
|
&sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
|
||||||
sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
|
RT2560_RX_RADIOTAP_PRESENT);
|
||||||
sc->sc_rxtap.wr_ihdr.it_present = htole32(RT2560_RX_RADIOTAP_PRESENT);
|
|
||||||
|
|
||||||
sc->sc_txtap_len = sizeof sc->sc_txtap;
|
|
||||||
sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
|
|
||||||
sc->sc_txtap.wt_ihdr.it_present = htole32(RT2560_TX_RADIOTAP_PRESENT);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add a few sysctl knobs.
|
* Add a few sysctl knobs.
|
||||||
@ -364,7 +360,6 @@ rt2560_detach(void *xsc)
|
|||||||
|
|
||||||
rt2560_stop(sc);
|
rt2560_stop(sc);
|
||||||
|
|
||||||
bpfdetach(ifp);
|
|
||||||
ieee80211_ifdetach(ic);
|
ieee80211_ifdetach(ic);
|
||||||
|
|
||||||
rt2560_free_tx_ring(sc, &sc->txq);
|
rt2560_free_tx_ring(sc, &sc->txq);
|
||||||
@ -833,6 +828,8 @@ rt2560_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
|
|||||||
|
|
||||||
if (vap->iv_opmode != IEEE80211_M_MONITOR)
|
if (vap->iv_opmode != IEEE80211_M_MONITOR)
|
||||||
rt2560_enable_tsf_sync(sc);
|
rt2560_enable_tsf_sync(sc);
|
||||||
|
else
|
||||||
|
rt2560_enable_tsf(sc);
|
||||||
}
|
}
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@ -1146,6 +1143,7 @@ rt2560_decryption_intr(struct rt2560_softc *sc)
|
|||||||
struct ieee80211_node *ni;
|
struct ieee80211_node *ni;
|
||||||
struct mbuf *mnew, *m;
|
struct mbuf *mnew, *m;
|
||||||
int hw, error;
|
int hw, error;
|
||||||
|
int8_t rssi, nf;
|
||||||
|
|
||||||
/* retrieve last decriptor index processed by cipher engine */
|
/* retrieve last decriptor index processed by cipher engine */
|
||||||
hw = RAL_READ(sc, RT2560_SECCSR0) - sc->rxq.physaddr;
|
hw = RAL_READ(sc, RT2560_SECCSR0) - sc->rxq.physaddr;
|
||||||
@ -1222,7 +1220,9 @@ rt2560_decryption_intr(struct rt2560_softc *sc)
|
|||||||
m->m_pkthdr.len = m->m_len =
|
m->m_pkthdr.len = m->m_len =
|
||||||
(le32toh(desc->flags) >> 16) & 0xfff;
|
(le32toh(desc->flags) >> 16) & 0xfff;
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
rssi = RT2560_RSSI(sc, desc->rssi);
|
||||||
|
nf = RT2560_NOISE_FLOOR;
|
||||||
|
if (ieee80211_radiotap_active(ic)) {
|
||||||
struct rt2560_rx_radiotap_header *tap = &sc->sc_rxtap;
|
struct rt2560_rx_radiotap_header *tap = &sc->sc_rxtap;
|
||||||
uint32_t tsf_lo, tsf_hi;
|
uint32_t tsf_lo, tsf_hi;
|
||||||
|
|
||||||
@ -1237,9 +1237,8 @@ rt2560_decryption_intr(struct rt2560_softc *sc)
|
|||||||
(desc->flags & htole32(RT2560_RX_OFDM)) ?
|
(desc->flags & htole32(RT2560_RX_OFDM)) ?
|
||||||
IEEE80211_T_OFDM : IEEE80211_T_CCK);
|
IEEE80211_T_OFDM : IEEE80211_T_CCK);
|
||||||
tap->wr_antenna = sc->rx_ant;
|
tap->wr_antenna = sc->rx_ant;
|
||||||
tap->wr_antsignal = RT2560_RSSI(sc, desc->rssi);
|
tap->wr_antsignal = nf + rssi;
|
||||||
|
tap->wr_antnoise = nf;
|
||||||
bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sc->sc_flags |= RT2560_F_INPUT_RUNNING;
|
sc->sc_flags |= RT2560_F_INPUT_RUNNING;
|
||||||
@ -1248,12 +1247,10 @@ rt2560_decryption_intr(struct rt2560_softc *sc)
|
|||||||
ni = ieee80211_find_rxnode(ic,
|
ni = ieee80211_find_rxnode(ic,
|
||||||
(struct ieee80211_frame_min *)wh);
|
(struct ieee80211_frame_min *)wh);
|
||||||
if (ni != NULL) {
|
if (ni != NULL) {
|
||||||
(void) ieee80211_input(ni, m,
|
(void) ieee80211_input(ni, m, rssi, nf);
|
||||||
RT2560_RSSI(sc, desc->rssi), RT2560_NOISE_FLOOR, 0);
|
|
||||||
ieee80211_free_node(ni);
|
ieee80211_free_node(ni);
|
||||||
} else
|
} else
|
||||||
(void) ieee80211_input_all(ic, m,
|
(void) ieee80211_input_all(ic, m, rssi, nf);
|
||||||
RT2560_RSSI(sc, desc->rssi), RT2560_NOISE_FLOOR, 0);
|
|
||||||
|
|
||||||
RAL_LOCK(sc);
|
RAL_LOCK(sc);
|
||||||
sc->sc_flags &= ~RT2560_F_INPUT_RUNNING;
|
sc->sc_flags &= ~RT2560_F_INPUT_RUNNING;
|
||||||
@ -1507,8 +1504,6 @@ rt2560_tx_bcn(struct rt2560_softc *sc, struct mbuf *m0,
|
|||||||
struct ieee80211_node *ni)
|
struct ieee80211_node *ni)
|
||||||
{
|
{
|
||||||
struct ieee80211vap *vap = ni->ni_vap;
|
struct ieee80211vap *vap = ni->ni_vap;
|
||||||
struct ieee80211com *ic = ni->ni_ic;
|
|
||||||
struct ifnet *ifp = sc->sc_ifp;
|
|
||||||
struct rt2560_tx_desc *desc;
|
struct rt2560_tx_desc *desc;
|
||||||
struct rt2560_tx_data *data;
|
struct rt2560_tx_data *data;
|
||||||
bus_dma_segment_t segs[RT2560_MAX_SCATTER];
|
bus_dma_segment_t segs[RT2560_MAX_SCATTER];
|
||||||
@ -1529,16 +1524,14 @@ rt2560_tx_bcn(struct rt2560_softc *sc, struct mbuf *m0,
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active_vap(vap)) {
|
||||||
struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap;
|
struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap;
|
||||||
|
|
||||||
tap->wt_flags = 0;
|
tap->wt_flags = 0;
|
||||||
tap->wt_rate = rate;
|
tap->wt_rate = rate;
|
||||||
tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
|
|
||||||
tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
|
|
||||||
tap->wt_antenna = sc->tx_ant;
|
tap->wt_antenna = sc->tx_ant;
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
|
ieee80211_radiotap_tx(vap, m0);
|
||||||
}
|
}
|
||||||
|
|
||||||
data->m = m0;
|
data->m = m0;
|
||||||
@ -1565,7 +1558,6 @@ rt2560_tx_mgt(struct rt2560_softc *sc, struct mbuf *m0,
|
|||||||
{
|
{
|
||||||
struct ieee80211vap *vap = ni->ni_vap;
|
struct ieee80211vap *vap = ni->ni_vap;
|
||||||
struct ieee80211com *ic = ni->ni_ic;
|
struct ieee80211com *ic = ni->ni_ic;
|
||||||
struct ifnet *ifp = sc->sc_ifp;
|
|
||||||
struct rt2560_tx_desc *desc;
|
struct rt2560_tx_desc *desc;
|
||||||
struct rt2560_tx_data *data;
|
struct rt2560_tx_data *data;
|
||||||
struct ieee80211_frame *wh;
|
struct ieee80211_frame *wh;
|
||||||
@ -1599,16 +1591,14 @@ rt2560_tx_mgt(struct rt2560_softc *sc, struct mbuf *m0,
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active_vap(vap)) {
|
||||||
struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap;
|
struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap;
|
||||||
|
|
||||||
tap->wt_flags = 0;
|
tap->wt_flags = 0;
|
||||||
tap->wt_rate = rate;
|
tap->wt_rate = rate;
|
||||||
tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
|
|
||||||
tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
|
|
||||||
tap->wt_antenna = sc->tx_ant;
|
tap->wt_antenna = sc->tx_ant;
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
|
ieee80211_radiotap_tx(vap, m0);
|
||||||
}
|
}
|
||||||
|
|
||||||
data->m = m0;
|
data->m = m0;
|
||||||
@ -1724,8 +1714,7 @@ static int
|
|||||||
rt2560_tx_raw(struct rt2560_softc *sc, struct mbuf *m0,
|
rt2560_tx_raw(struct rt2560_softc *sc, struct mbuf *m0,
|
||||||
struct ieee80211_node *ni, const struct ieee80211_bpf_params *params)
|
struct ieee80211_node *ni, const struct ieee80211_bpf_params *params)
|
||||||
{
|
{
|
||||||
struct ifnet *ifp = sc->sc_ifp;
|
struct ieee80211vap *vap = ni->ni_vap;
|
||||||
struct ieee80211com *ic = ifp->if_l2com;
|
|
||||||
struct rt2560_tx_desc *desc;
|
struct rt2560_tx_desc *desc;
|
||||||
struct rt2560_tx_data *data;
|
struct rt2560_tx_data *data;
|
||||||
bus_dma_segment_t segs[RT2560_MAX_SCATTER];
|
bus_dma_segment_t segs[RT2560_MAX_SCATTER];
|
||||||
@ -1767,16 +1756,14 @@ rt2560_tx_raw(struct rt2560_softc *sc, struct mbuf *m0,
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active_vap(vap)) {
|
||||||
struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap;
|
struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap;
|
||||||
|
|
||||||
tap->wt_flags = 0;
|
tap->wt_flags = 0;
|
||||||
tap->wt_rate = rate;
|
tap->wt_rate = rate;
|
||||||
tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
|
|
||||||
tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
|
|
||||||
tap->wt_antenna = sc->tx_ant;
|
tap->wt_antenna = sc->tx_ant;
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
|
ieee80211_radiotap_tx(ni->ni_vap, m0);
|
||||||
}
|
}
|
||||||
|
|
||||||
data->m = m0;
|
data->m = m0;
|
||||||
@ -1808,7 +1795,6 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0,
|
|||||||
{
|
{
|
||||||
struct ieee80211vap *vap = ni->ni_vap;
|
struct ieee80211vap *vap = ni->ni_vap;
|
||||||
struct ieee80211com *ic = ni->ni_ic;
|
struct ieee80211com *ic = ni->ni_ic;
|
||||||
struct ifnet *ifp = sc->sc_ifp;
|
|
||||||
struct rt2560_tx_desc *desc;
|
struct rt2560_tx_desc *desc;
|
||||||
struct rt2560_tx_data *data;
|
struct rt2560_tx_data *data;
|
||||||
struct ieee80211_frame *wh;
|
struct ieee80211_frame *wh;
|
||||||
@ -1897,14 +1883,14 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0,
|
|||||||
wh = mtod(m0, struct ieee80211_frame *);
|
wh = mtod(m0, struct ieee80211_frame *);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active_vap(vap)) {
|
||||||
struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap;
|
struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap;
|
||||||
|
|
||||||
tap->wt_flags = 0;
|
tap->wt_flags = 0;
|
||||||
tap->wt_rate = rate;
|
tap->wt_rate = rate;
|
||||||
tap->wt_antenna = sc->tx_ant;
|
tap->wt_antenna = sc->tx_ant;
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
|
ieee80211_radiotap_tx(vap, m0);
|
||||||
}
|
}
|
||||||
|
|
||||||
data->m = m0;
|
data->m = m0;
|
||||||
@ -2234,11 +2220,6 @@ rt2560_set_channel(struct ieee80211com *ic)
|
|||||||
|
|
||||||
RAL_LOCK(sc);
|
RAL_LOCK(sc);
|
||||||
rt2560_set_chan(sc, ic->ic_curchan);
|
rt2560_set_chan(sc, ic->ic_curchan);
|
||||||
|
|
||||||
sc->sc_txtap.wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
|
|
||||||
sc->sc_txtap.wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
|
|
||||||
sc->sc_rxtap.wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
|
|
||||||
sc->sc_rxtap.wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
|
|
||||||
RAL_UNLOCK(sc);
|
RAL_UNLOCK(sc);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -2302,6 +2283,14 @@ rt2560_enable_tsf_sync(struct rt2560_softc *sc)
|
|||||||
DPRINTF(sc, "%s", "enabling TSF synchronization\n");
|
DPRINTF(sc, "%s", "enabling TSF synchronization\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rt2560_enable_tsf(struct rt2560_softc *sc)
|
||||||
|
{
|
||||||
|
RAL_WRITE(sc, RT2560_CSR14, 0);
|
||||||
|
RAL_WRITE(sc, RT2560_CSR14,
|
||||||
|
RT2560_ENABLE_TSF_SYNC(2) | RT2560_ENABLE_TSF);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rt2560_update_plcp(struct rt2560_softc *sc)
|
rt2560_update_plcp(struct rt2560_softc *sc)
|
||||||
{
|
{
|
||||||
|
@ -24,8 +24,9 @@ struct rt2560_rx_radiotap_header {
|
|||||||
uint8_t wr_rate;
|
uint8_t wr_rate;
|
||||||
uint16_t wr_chan_freq;
|
uint16_t wr_chan_freq;
|
||||||
uint16_t wr_chan_flags;
|
uint16_t wr_chan_flags;
|
||||||
|
int8_t wr_antsignal;
|
||||||
|
int8_t wr_antnoise;
|
||||||
uint8_t wr_antenna;
|
uint8_t wr_antenna;
|
||||||
uint8_t wr_antsignal;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define RT2560_RX_RADIOTAP_PRESENT \
|
#define RT2560_RX_RADIOTAP_PRESENT \
|
||||||
@ -34,7 +35,8 @@ struct rt2560_rx_radiotap_header {
|
|||||||
(1 << IEEE80211_RADIOTAP_RATE) | \
|
(1 << IEEE80211_RADIOTAP_RATE) | \
|
||||||
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
||||||
(1 << IEEE80211_RADIOTAP_ANTENNA) | \
|
(1 << IEEE80211_RADIOTAP_ANTENNA) | \
|
||||||
(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL))
|
(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \
|
||||||
|
(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE))
|
||||||
|
|
||||||
struct rt2560_tx_radiotap_header {
|
struct rt2560_tx_radiotap_header {
|
||||||
struct ieee80211_radiotap_header wt_ihdr;
|
struct ieee80211_radiotap_header wt_ihdr;
|
||||||
|
@ -169,6 +169,7 @@ static int rt2661_radar_stop(struct rt2661_softc *);
|
|||||||
static int rt2661_prepare_beacon(struct rt2661_softc *,
|
static int rt2661_prepare_beacon(struct rt2661_softc *,
|
||||||
struct ieee80211vap *);
|
struct ieee80211vap *);
|
||||||
static void rt2661_enable_tsf_sync(struct rt2661_softc *);
|
static void rt2661_enable_tsf_sync(struct rt2661_softc *);
|
||||||
|
static void rt2661_enable_tsf(struct rt2661_softc *);
|
||||||
static int rt2661_get_rssi(struct rt2661_softc *, uint8_t);
|
static int rt2661_get_rssi(struct rt2661_softc *, uint8_t);
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
@ -319,16 +320,11 @@ rt2661_attach(device_t dev, int id)
|
|||||||
ic->ic_vap_create = rt2661_vap_create;
|
ic->ic_vap_create = rt2661_vap_create;
|
||||||
ic->ic_vap_delete = rt2661_vap_delete;
|
ic->ic_vap_delete = rt2661_vap_delete;
|
||||||
|
|
||||||
bpfattach(ifp, DLT_IEEE802_11_RADIO,
|
ieee80211_radiotap_attach(ic,
|
||||||
sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap));
|
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
|
||||||
|
RT2661_TX_RADIOTAP_PRESENT,
|
||||||
sc->sc_rxtap_len = sizeof sc->sc_rxtap;
|
&sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
|
||||||
sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
|
RT2661_RX_RADIOTAP_PRESENT);
|
||||||
sc->sc_rxtap.wr_ihdr.it_present = htole32(RT2661_RX_RADIOTAP_PRESENT);
|
|
||||||
|
|
||||||
sc->sc_txtap_len = sizeof sc->sc_txtap;
|
|
||||||
sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
|
|
||||||
sc->sc_txtap.wt_ihdr.it_present = htole32(RT2661_TX_RADIOTAP_PRESENT);
|
|
||||||
|
|
||||||
#ifdef RAL_DEBUG
|
#ifdef RAL_DEBUG
|
||||||
SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
|
SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
|
||||||
@ -359,7 +355,6 @@ rt2661_detach(void *xsc)
|
|||||||
rt2661_stop_locked(sc);
|
rt2661_stop_locked(sc);
|
||||||
RAL_UNLOCK(sc);
|
RAL_UNLOCK(sc);
|
||||||
|
|
||||||
bpfdetach(ifp);
|
|
||||||
ieee80211_ifdetach(ic);
|
ieee80211_ifdetach(ic);
|
||||||
|
|
||||||
rt2661_free_tx_ring(sc, &sc->txq[0]);
|
rt2661_free_tx_ring(sc, &sc->txq[0]);
|
||||||
@ -830,6 +825,8 @@ rt2661_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
|
|||||||
}
|
}
|
||||||
if (vap->iv_opmode != IEEE80211_M_MONITOR)
|
if (vap->iv_opmode != IEEE80211_M_MONITOR)
|
||||||
rt2661_enable_tsf_sync(sc);
|
rt2661_enable_tsf_sync(sc);
|
||||||
|
else
|
||||||
|
rt2661_enable_tsf(sc);
|
||||||
}
|
}
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@ -1025,7 +1022,7 @@ rt2661_rx_intr(struct rt2661_softc *sc)
|
|||||||
BUS_DMASYNC_POSTREAD);
|
BUS_DMASYNC_POSTREAD);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int rssi;
|
int8_t rssi, nf;
|
||||||
|
|
||||||
desc = &sc->rxq.desc[sc->rxq.cur];
|
desc = &sc->rxq.desc[sc->rxq.cur];
|
||||||
data = &sc->rxq.data[sc->rxq.cur];
|
data = &sc->rxq.data[sc->rxq.cur];
|
||||||
@ -1100,8 +1097,12 @@ rt2661_rx_intr(struct rt2661_softc *sc)
|
|||||||
(le32toh(desc->flags) >> 16) & 0xfff;
|
(le32toh(desc->flags) >> 16) & 0xfff;
|
||||||
|
|
||||||
rssi = rt2661_get_rssi(sc, desc->rssi);
|
rssi = rt2661_get_rssi(sc, desc->rssi);
|
||||||
|
/* Error happened during RSSI conversion. */
|
||||||
|
if (rssi < 0)
|
||||||
|
rssi = -30; /* XXX ignored by net80211 */
|
||||||
|
nf = RT2661_NOISE_FLOOR;
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active(ic)) {
|
||||||
struct rt2661_rx_radiotap_header *tap = &sc->sc_rxtap;
|
struct rt2661_rx_radiotap_header *tap = &sc->sc_rxtap;
|
||||||
uint32_t tsf_lo, tsf_hi;
|
uint32_t tsf_lo, tsf_hi;
|
||||||
|
|
||||||
@ -1115,9 +1116,8 @@ rt2661_rx_intr(struct rt2661_softc *sc)
|
|||||||
tap->wr_rate = ieee80211_plcp2rate(desc->rate,
|
tap->wr_rate = ieee80211_plcp2rate(desc->rate,
|
||||||
(desc->flags & htole32(RT2661_RX_OFDM)) ?
|
(desc->flags & htole32(RT2661_RX_OFDM)) ?
|
||||||
IEEE80211_T_OFDM : IEEE80211_T_CCK);
|
IEEE80211_T_OFDM : IEEE80211_T_CCK);
|
||||||
tap->wr_antsignal = rssi < 0 ? 0 : rssi;
|
tap->wr_antsignal = nf + rssi;
|
||||||
|
tap->wr_antnoise = nf;
|
||||||
bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
|
|
||||||
}
|
}
|
||||||
sc->sc_flags |= RAL_INPUT_RUNNING;
|
sc->sc_flags |= RAL_INPUT_RUNNING;
|
||||||
RAL_UNLOCK(sc);
|
RAL_UNLOCK(sc);
|
||||||
@ -1127,16 +1127,10 @@ rt2661_rx_intr(struct rt2661_softc *sc)
|
|||||||
ni = ieee80211_find_rxnode(ic,
|
ni = ieee80211_find_rxnode(ic,
|
||||||
(struct ieee80211_frame_min *)wh);
|
(struct ieee80211_frame_min *)wh);
|
||||||
if (ni != NULL) {
|
if (ni != NULL) {
|
||||||
/* Error happened during RSSI conversion. */
|
(void) ieee80211_input(ni, m, rssi, nf);
|
||||||
if (rssi < 0)
|
|
||||||
rssi = -30; /* XXX ignored by net80211 */
|
|
||||||
|
|
||||||
(void) ieee80211_input(ni, m, rssi,
|
|
||||||
RT2661_NOISE_FLOOR, 0);
|
|
||||||
ieee80211_free_node(ni);
|
ieee80211_free_node(ni);
|
||||||
} else
|
} else
|
||||||
(void) ieee80211_input_all(ic, m, rssi,
|
(void) ieee80211_input_all(ic, m, rssi, nf);
|
||||||
RT2661_NOISE_FLOOR, 0);
|
|
||||||
|
|
||||||
RAL_LOCK(sc);
|
RAL_LOCK(sc);
|
||||||
sc->sc_flags &= ~RAL_INPUT_RUNNING;
|
sc->sc_flags &= ~RAL_INPUT_RUNNING;
|
||||||
@ -1332,7 +1326,6 @@ rt2661_tx_mgt(struct rt2661_softc *sc, struct mbuf *m0,
|
|||||||
{
|
{
|
||||||
struct ieee80211vap *vap = ni->ni_vap;
|
struct ieee80211vap *vap = ni->ni_vap;
|
||||||
struct ieee80211com *ic = ni->ni_ic;
|
struct ieee80211com *ic = ni->ni_ic;
|
||||||
struct ifnet *ifp = sc->sc_ifp;
|
|
||||||
struct rt2661_tx_desc *desc;
|
struct rt2661_tx_desc *desc;
|
||||||
struct rt2661_tx_data *data;
|
struct rt2661_tx_data *data;
|
||||||
struct ieee80211_frame *wh;
|
struct ieee80211_frame *wh;
|
||||||
@ -1366,13 +1359,13 @@ rt2661_tx_mgt(struct rt2661_softc *sc, struct mbuf *m0,
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active_vap(vap)) {
|
||||||
struct rt2661_tx_radiotap_header *tap = &sc->sc_txtap;
|
struct rt2661_tx_radiotap_header *tap = &sc->sc_txtap;
|
||||||
|
|
||||||
tap->wt_flags = 0;
|
tap->wt_flags = 0;
|
||||||
tap->wt_rate = rate;
|
tap->wt_rate = rate;
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
|
ieee80211_radiotap_tx(vap, m0);
|
||||||
}
|
}
|
||||||
|
|
||||||
data->m = m0;
|
data->m = m0;
|
||||||
@ -1587,15 +1580,13 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0,
|
|||||||
wh = mtod(m0, struct ieee80211_frame *);
|
wh = mtod(m0, struct ieee80211_frame *);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active_vap(vap)) {
|
||||||
struct rt2661_tx_radiotap_header *tap = &sc->sc_txtap;
|
struct rt2661_tx_radiotap_header *tap = &sc->sc_txtap;
|
||||||
|
|
||||||
tap->wt_flags = 0;
|
tap->wt_flags = 0;
|
||||||
tap->wt_rate = rate;
|
tap->wt_rate = rate;
|
||||||
tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
|
|
||||||
tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
|
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
|
ieee80211_radiotap_tx(vap, m0);
|
||||||
}
|
}
|
||||||
|
|
||||||
data->m = m0;
|
data->m = m0;
|
||||||
@ -2789,6 +2780,14 @@ rt2661_enable_tsf_sync(struct rt2661_softc *sc)
|
|||||||
RAL_WRITE(sc, RT2661_TXRX_CSR9, tmp);
|
RAL_WRITE(sc, RT2661_TXRX_CSR9, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rt2661_enable_tsf(struct rt2661_softc *sc)
|
||||||
|
{
|
||||||
|
RAL_WRITE(sc, RT2661_TXRX_CSR9,
|
||||||
|
(RAL_READ(sc, RT2661_TXRX_CSR9) & 0xff000000)
|
||||||
|
| RT2661_TSF_TICKING | RT2661_TSF_MODE(2));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Retrieve the "Received Signal Strength Indicator" from the raw values
|
* Retrieve the "Received Signal Strength Indicator" from the raw values
|
||||||
* contained in Rx descriptors. The computation depends on which band the
|
* contained in Rx descriptors. The computation depends on which band the
|
||||||
@ -2869,11 +2868,6 @@ rt2661_set_channel(struct ieee80211com *ic)
|
|||||||
|
|
||||||
RAL_LOCK(sc);
|
RAL_LOCK(sc);
|
||||||
rt2661_set_chan(sc, ic->ic_curchan);
|
rt2661_set_chan(sc, ic->ic_curchan);
|
||||||
|
|
||||||
sc->sc_txtap.wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
|
|
||||||
sc->sc_txtap.wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
|
|
||||||
sc->sc_rxtap.wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
|
|
||||||
sc->sc_rxtap.wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
|
|
||||||
RAL_UNLOCK(sc);
|
RAL_UNLOCK(sc);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,8 @@ struct rt2661_rx_radiotap_header {
|
|||||||
uint8_t wr_rate;
|
uint8_t wr_rate;
|
||||||
uint16_t wr_chan_freq;
|
uint16_t wr_chan_freq;
|
||||||
uint16_t wr_chan_flags;
|
uint16_t wr_chan_flags;
|
||||||
uint8_t wr_antsignal;
|
int8_t wr_antsignal;
|
||||||
|
int8_t wr_antnoise;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
#define RT2661_RX_RADIOTAP_PRESENT \
|
#define RT2661_RX_RADIOTAP_PRESENT \
|
||||||
@ -32,7 +33,8 @@ struct rt2661_rx_radiotap_header {
|
|||||||
(1 << IEEE80211_RADIOTAP_FLAGS) | \
|
(1 << IEEE80211_RADIOTAP_FLAGS) | \
|
||||||
(1 << IEEE80211_RADIOTAP_RATE) | \
|
(1 << IEEE80211_RADIOTAP_RATE) | \
|
||||||
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
||||||
(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL))
|
(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \
|
||||||
|
(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE))
|
||||||
|
|
||||||
struct rt2661_tx_radiotap_header {
|
struct rt2661_tx_radiotap_header {
|
||||||
struct ieee80211_radiotap_header wt_ihdr;
|
struct ieee80211_radiotap_header wt_ihdr;
|
||||||
|
@ -196,6 +196,7 @@ static void rum_select_band(struct rum_softc *,
|
|||||||
static void rum_set_chan(struct rum_softc *,
|
static void rum_set_chan(struct rum_softc *,
|
||||||
struct ieee80211_channel *);
|
struct ieee80211_channel *);
|
||||||
static void rum_enable_tsf_sync(struct rum_softc *);
|
static void rum_enable_tsf_sync(struct rum_softc *);
|
||||||
|
static void rum_enable_tsf(struct rum_softc *);
|
||||||
static void rum_update_slot(struct ifnet *);
|
static void rum_update_slot(struct ifnet *);
|
||||||
static void rum_set_bssid(struct rum_softc *, const uint8_t *);
|
static void rum_set_bssid(struct rum_softc *, const uint8_t *);
|
||||||
static void rum_set_macaddr(struct rum_softc *, const uint8_t *);
|
static void rum_set_macaddr(struct rum_softc *, const uint8_t *);
|
||||||
@ -522,16 +523,11 @@ rum_attach(device_t self)
|
|||||||
ic->ic_vap_create = rum_vap_create;
|
ic->ic_vap_create = rum_vap_create;
|
||||||
ic->ic_vap_delete = rum_vap_delete;
|
ic->ic_vap_delete = rum_vap_delete;
|
||||||
|
|
||||||
bpfattach(ifp, DLT_IEEE802_11_RADIO,
|
ieee80211_radiotap_attach(ic,
|
||||||
sizeof (struct ieee80211_frame) + sizeof(sc->sc_txtap));
|
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
|
||||||
|
RT2573_TX_RADIOTAP_PRESENT,
|
||||||
sc->sc_rxtap_len = sizeof sc->sc_rxtap;
|
&sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
|
||||||
sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
|
RT2573_RX_RADIOTAP_PRESENT);
|
||||||
sc->sc_rxtap.wr_ihdr.it_present = htole32(RT2573_RX_RADIOTAP_PRESENT);
|
|
||||||
|
|
||||||
sc->sc_txtap_len = sizeof sc->sc_txtap;
|
|
||||||
sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
|
|
||||||
sc->sc_txtap.wt_ihdr.it_present = htole32(RT2573_TX_RADIOTAP_PRESENT);
|
|
||||||
|
|
||||||
if (bootverbose)
|
if (bootverbose)
|
||||||
ieee80211_announce(ic);
|
ieee80211_announce(ic);
|
||||||
@ -560,7 +556,6 @@ rum_detach(device_t self)
|
|||||||
|
|
||||||
if (ifp) {
|
if (ifp) {
|
||||||
ic = ifp->if_l2com;
|
ic = ifp->if_l2com;
|
||||||
bpfdetach(ifp);
|
|
||||||
ieee80211_ifdetach(ic);
|
ieee80211_ifdetach(ic);
|
||||||
if_free(ifp);
|
if_free(ifp);
|
||||||
}
|
}
|
||||||
@ -752,9 +747,11 @@ rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
|
|||||||
|
|
||||||
if (vap->iv_opmode != IEEE80211_M_MONITOR)
|
if (vap->iv_opmode != IEEE80211_M_MONITOR)
|
||||||
rum_enable_tsf_sync(sc);
|
rum_enable_tsf_sync(sc);
|
||||||
|
else
|
||||||
|
rum_enable_tsf(sc);
|
||||||
|
|
||||||
/* enable automatic rate adaptation */
|
/* enable automatic rate adaptation */
|
||||||
tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
|
tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
|
||||||
if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
|
if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
|
||||||
rum_amrr_start(sc, ni);
|
rum_amrr_start(sc, ni);
|
||||||
break;
|
break;
|
||||||
@ -771,8 +768,7 @@ rum_bulk_write_callback(struct usb2_xfer *xfer)
|
|||||||
{
|
{
|
||||||
struct rum_softc *sc = xfer->priv_sc;
|
struct rum_softc *sc = xfer->priv_sc;
|
||||||
struct ifnet *ifp = sc->sc_ifp;
|
struct ifnet *ifp = sc->sc_ifp;
|
||||||
struct ieee80211com *ic = ifp->if_l2com;
|
struct ieee80211vap *vap;
|
||||||
struct ieee80211_channel *c = ic->ic_curchan;
|
|
||||||
struct rum_tx_data *data;
|
struct rum_tx_data *data;
|
||||||
struct mbuf *m;
|
struct mbuf *m;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
@ -807,16 +803,15 @@ tr_setup:
|
|||||||
usb2_m_copy_in(xfer->frbuffers, RT2573_TX_DESC_SIZE, m,
|
usb2_m_copy_in(xfer->frbuffers, RT2573_TX_DESC_SIZE, m,
|
||||||
0, m->m_pkthdr.len);
|
0, m->m_pkthdr.len);
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
vap = data->ni->ni_vap;
|
||||||
|
if (ieee80211_radiotap_active_vap(vap)) {
|
||||||
struct rum_tx_radiotap_header *tap = &sc->sc_txtap;
|
struct rum_tx_radiotap_header *tap = &sc->sc_txtap;
|
||||||
|
|
||||||
tap->wt_flags = 0;
|
tap->wt_flags = 0;
|
||||||
tap->wt_rate = data->rate;
|
tap->wt_rate = data->rate;
|
||||||
tap->wt_chan_freq = htole16(c->ic_freq);
|
|
||||||
tap->wt_chan_flags = htole16(c->ic_flags);
|
|
||||||
tap->wt_antenna = sc->tx_ant;
|
tap->wt_antenna = sc->tx_ant;
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m);
|
ieee80211_radiotap_tx(vap, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* align end on a 4-bytes boundary */
|
/* align end on a 4-bytes boundary */
|
||||||
@ -911,19 +906,17 @@ rum_bulk_read_callback(struct usb2_xfer *xfer)
|
|||||||
m->m_pkthdr.rcvif = ifp;
|
m->m_pkthdr.rcvif = ifp;
|
||||||
m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff;
|
m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff;
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active(ic)) {
|
||||||
struct rum_rx_radiotap_header *tap = &sc->sc_rxtap;
|
struct rum_rx_radiotap_header *tap = &sc->sc_rxtap;
|
||||||
|
|
||||||
tap->wr_flags = IEEE80211_RADIOTAP_F_FCS;
|
/* XXX read tsf */
|
||||||
|
tap->wr_flags = 0;
|
||||||
tap->wr_rate = ieee80211_plcp2rate(sc->sc_rx_desc.rate,
|
tap->wr_rate = ieee80211_plcp2rate(sc->sc_rx_desc.rate,
|
||||||
(flags & RT2573_RX_OFDM) ?
|
(flags & RT2573_RX_OFDM) ?
|
||||||
IEEE80211_T_OFDM : IEEE80211_T_CCK);
|
IEEE80211_T_OFDM : IEEE80211_T_CCK);
|
||||||
tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
|
tap->wr_antsignal = RT2573_NOISE_FLOOR + rssi;
|
||||||
tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
|
tap->wr_antnoise = RT2573_NOISE_FLOOR;
|
||||||
tap->wr_antenna = sc->rx_ant;
|
tap->wr_antenna = sc->rx_ant;
|
||||||
tap->wr_antsignal = rssi;
|
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
|
|
||||||
}
|
}
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case USB_ST_SETUP:
|
case USB_ST_SETUP:
|
||||||
@ -942,11 +935,11 @@ tr_setup:
|
|||||||
mtod(m, struct ieee80211_frame_min *));
|
mtod(m, struct ieee80211_frame_min *));
|
||||||
if (ni != NULL) {
|
if (ni != NULL) {
|
||||||
(void) ieee80211_input(ni, m, rssi,
|
(void) ieee80211_input(ni, m, rssi,
|
||||||
RT2573_NOISE_FLOOR, 0);
|
RT2573_NOISE_FLOOR);
|
||||||
ieee80211_free_node(ni);
|
ieee80211_free_node(ni);
|
||||||
} else
|
} else
|
||||||
(void) ieee80211_input_all(ic, m, rssi,
|
(void) ieee80211_input_all(ic, m, rssi,
|
||||||
RT2573_NOISE_FLOOR, 0);
|
RT2573_NOISE_FLOOR);
|
||||||
RUM_LOCK(sc);
|
RUM_LOCK(sc);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -1736,6 +1729,14 @@ rum_enable_tsf_sync(struct rum_softc *sc)
|
|||||||
rum_write(sc, RT2573_TXRX_CSR9, tmp);
|
rum_write(sc, RT2573_TXRX_CSR9, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rum_enable_tsf(struct rum_softc *sc)
|
||||||
|
{
|
||||||
|
rum_write(sc, RT2573_TXRX_CSR9,
|
||||||
|
(rum_read(sc, RT2573_TXRX_CSR9) & 0xff000000) |
|
||||||
|
RT2573_TSF_TICKING | RT2573_TSF_MODE(2));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rum_update_slot(struct ifnet *ifp)
|
rum_update_slot(struct ifnet *ifp)
|
||||||
{
|
{
|
||||||
|
@ -26,16 +26,19 @@ struct rum_rx_radiotap_header {
|
|||||||
uint8_t wr_rate;
|
uint8_t wr_rate;
|
||||||
uint16_t wr_chan_freq;
|
uint16_t wr_chan_freq;
|
||||||
uint16_t wr_chan_flags;
|
uint16_t wr_chan_flags;
|
||||||
|
int8_t wr_antsignal;
|
||||||
|
int8_t wr_antnoise;
|
||||||
uint8_t wr_antenna;
|
uint8_t wr_antenna;
|
||||||
uint8_t wr_antsignal;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define RT2573_RX_RADIOTAP_PRESENT \
|
#define RT2573_RX_RADIOTAP_PRESENT \
|
||||||
((1 << IEEE80211_RADIOTAP_FLAGS) | \
|
((1 << IEEE80211_RADIOTAP_FLAGS) | \
|
||||||
(1 << IEEE80211_RADIOTAP_RATE) | \
|
(1 << IEEE80211_RADIOTAP_RATE) | \
|
||||||
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
||||||
|
(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \
|
||||||
|
(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \
|
||||||
(1 << IEEE80211_RADIOTAP_ANTENNA) | \
|
(1 << IEEE80211_RADIOTAP_ANTENNA) | \
|
||||||
(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL))
|
0)
|
||||||
|
|
||||||
struct rum_tx_radiotap_header {
|
struct rum_tx_radiotap_header {
|
||||||
struct ieee80211_radiotap_header wt_ihdr;
|
struct ieee80211_radiotap_header wt_ihdr;
|
||||||
|
@ -481,16 +481,11 @@ uath_attach(device_t dev)
|
|||||||
ic->ic_update_mcast = uath_update_mcast;
|
ic->ic_update_mcast = uath_update_mcast;
|
||||||
ic->ic_update_promisc = uath_update_promisc;
|
ic->ic_update_promisc = uath_update_promisc;
|
||||||
|
|
||||||
bpfattach(ifp, DLT_IEEE802_11_RADIO,
|
ieee80211_radiotap_attach(ic,
|
||||||
sizeof (struct ieee80211_frame) + sizeof(sc->sc_txtap));
|
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
|
||||||
|
UATH_TX_RADIOTAP_PRESENT,
|
||||||
sc->sc_rxtap_len = sizeof sc->sc_rxtap;
|
&sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
|
||||||
sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
|
UATH_RX_RADIOTAP_PRESENT);
|
||||||
sc->sc_rxtap.wr_ihdr.it_present = htole32(UATH_RX_RADIOTAP_PRESENT);
|
|
||||||
|
|
||||||
sc->sc_txtap_len = sizeof sc->sc_txtap;
|
|
||||||
sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
|
|
||||||
sc->sc_txtap.wt_ihdr.it_present = htole32(UATH_TX_RADIOTAP_PRESENT);
|
|
||||||
|
|
||||||
if (bootverbose)
|
if (bootverbose)
|
||||||
ieee80211_announce(ic);
|
ieee80211_announce(ic);
|
||||||
@ -531,7 +526,6 @@ uath_detach(device_t dev)
|
|||||||
uath_free_cmd_list(sc, sc->sc_cmd, UATH_CMD_LIST_COUNT);
|
uath_free_cmd_list(sc, sc->sc_cmd, UATH_CMD_LIST_COUNT);
|
||||||
UATH_UNLOCK(sc);
|
UATH_UNLOCK(sc);
|
||||||
|
|
||||||
bpfdetach(ifp);
|
|
||||||
if_free(ifp);
|
if_free(ifp);
|
||||||
mtx_destroy(&sc->sc_mtx);
|
mtx_destroy(&sc->sc_mtx);
|
||||||
return (0);
|
return (0);
|
||||||
@ -1601,8 +1595,6 @@ static int
|
|||||||
uath_tx_start(struct uath_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
|
uath_tx_start(struct uath_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
|
||||||
struct uath_data *data)
|
struct uath_data *data)
|
||||||
{
|
{
|
||||||
struct ifnet *ifp = sc->sc_ifp;
|
|
||||||
struct ieee80211com *ic = ifp->if_l2com;
|
|
||||||
struct ieee80211vap *vap = ni->ni_vap;
|
struct ieee80211vap *vap = ni->ni_vap;
|
||||||
struct uath_chunk *chunk;
|
struct uath_chunk *chunk;
|
||||||
struct uath_tx_desc *desc;
|
struct uath_tx_desc *desc;
|
||||||
@ -1617,16 +1609,14 @@ uath_tx_start(struct uath_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
|
|||||||
chunk = (struct uath_chunk *)data->buf;
|
chunk = (struct uath_chunk *)data->buf;
|
||||||
desc = (struct uath_tx_desc *)(chunk + 1);
|
desc = (struct uath_tx_desc *)(chunk + 1);
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active_vap(vap)) {
|
||||||
struct uath_tx_radiotap_header *tap = &sc->sc_txtap;
|
struct uath_tx_radiotap_header *tap = &sc->sc_txtap;
|
||||||
|
|
||||||
tap->wt_flags = 0;
|
tap->wt_flags = 0;
|
||||||
if (m0->m_flags & M_FRAG)
|
if (m0->m_flags & M_FRAG)
|
||||||
tap->wt_flags |= IEEE80211_RADIOTAP_F_FRAG;
|
tap->wt_flags |= IEEE80211_RADIOTAP_F_FRAG;
|
||||||
tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
|
|
||||||
tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
|
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
|
ieee80211_radiotap_tx(vap, m0);
|
||||||
}
|
}
|
||||||
|
|
||||||
wh = mtod(m0, struct ieee80211_frame *);
|
wh = mtod(m0, struct ieee80211_frame *);
|
||||||
@ -1921,7 +1911,7 @@ uath_set_channel(struct ieee80211com *ic)
|
|||||||
static int
|
static int
|
||||||
uath_set_rxmulti_filter(struct uath_softc *sc)
|
uath_set_rxmulti_filter(struct uath_softc *sc)
|
||||||
{
|
{
|
||||||
|
/* XXX broken */
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
static void
|
static void
|
||||||
@ -1929,13 +1919,14 @@ uath_update_mcast(struct ifnet *ifp)
|
|||||||
{
|
{
|
||||||
struct uath_softc *sc = ifp->if_softc;
|
struct uath_softc *sc = ifp->if_softc;
|
||||||
|
|
||||||
|
UATH_LOCK(sc);
|
||||||
/*
|
/*
|
||||||
* this is for avoiding the race condition when we're try to
|
* this is for avoiding the race condition when we're try to
|
||||||
* connect to the AP with WPA.
|
* connect to the AP with WPA.
|
||||||
*/
|
*/
|
||||||
if (!(sc->sc_flags & UATH_FLAG_INITDONE))
|
if (sc->sc_flags & UATH_FLAG_INITDONE)
|
||||||
return;
|
|
||||||
(void)uath_set_rxmulti_filter(sc);
|
(void)uath_set_rxmulti_filter(sc);
|
||||||
|
UATH_UNLOCK(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1943,13 +1934,15 @@ uath_update_promisc(struct ifnet *ifp)
|
|||||||
{
|
{
|
||||||
struct uath_softc *sc = ifp->if_softc;
|
struct uath_softc *sc = ifp->if_softc;
|
||||||
|
|
||||||
if (!(sc->sc_flags & UATH_FLAG_INITDONE))
|
UATH_LOCK(sc);
|
||||||
return;
|
if (sc->sc_flags & UATH_FLAG_INITDONE) {
|
||||||
uath_set_rxfilter(sc,
|
uath_set_rxfilter(sc,
|
||||||
UATH_FILTER_RX_UCAST | UATH_FILTER_RX_MCAST |
|
UATH_FILTER_RX_UCAST | UATH_FILTER_RX_MCAST |
|
||||||
UATH_FILTER_RX_BCAST | UATH_FILTER_RX_BEACON |
|
UATH_FILTER_RX_BCAST | UATH_FILTER_RX_BEACON |
|
||||||
UATH_FILTER_RX_PROM, UATH_FILTER_OP_SET);
|
UATH_FILTER_RX_PROM, UATH_FILTER_OP_SET);
|
||||||
}
|
}
|
||||||
|
UATH_UNLOCK(sc);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
uath_create_connection(struct uath_softc *sc, uint32_t connid)
|
uath_create_connection(struct uath_softc *sc, uint32_t connid)
|
||||||
@ -2653,14 +2646,22 @@ uath_data_rxeof(struct usb2_xfer *xfer, struct uath_data *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* there are a lot more fields in the RX descriptor */
|
/* there are a lot more fields in the RX descriptor */
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active(ic)) {
|
||||||
struct uath_rx_radiotap_header *tap = &sc->sc_rxtap;
|
struct uath_rx_radiotap_header *tap = &sc->sc_rxtap;
|
||||||
|
uint32_t tsf_hi = be32toh(desc->tstamp_high);
|
||||||
|
uint32_t tsf_lo = be32toh(desc->tstamp_low);
|
||||||
|
|
||||||
tap->wr_chan_freq = htole16(be32toh(desc->channel));
|
/* XXX only get low order 24bits of tsf from h/w */
|
||||||
tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
|
tap->wr_tsf = htole64(((uint64_t)tsf_hi << 32) | tsf_lo);
|
||||||
tap->wr_dbm_antsignal = (int8_t)be32toh(desc->rssi);
|
tap->wr_flags = 0;
|
||||||
|
if (be32toh(desc->status) == UATH_STATUS_CRC_ERR)
|
||||||
bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
|
tap->wr_flags |= IEEE80211_RADIOTAP_F_BADFCS;
|
||||||
|
/* XXX map other status to BADFCS? */
|
||||||
|
/* XXX ath h/w rate code, need to map */
|
||||||
|
tap->wr_rate = be32toh(desc->rate);
|
||||||
|
tap->wr_antenna = be32toh(desc->antenna);
|
||||||
|
tap->wr_antsignal = -95 + be32toh(desc->rssi);
|
||||||
|
tap->wr_antnoise = -95;
|
||||||
}
|
}
|
||||||
|
|
||||||
ifp->if_ipackets++;
|
ifp->if_ipackets++;
|
||||||
@ -2721,12 +2722,12 @@ setup:
|
|||||||
nf = -95; /* XXX */
|
nf = -95; /* XXX */
|
||||||
if (ni != NULL) {
|
if (ni != NULL) {
|
||||||
(void) ieee80211_input(ni, m,
|
(void) ieee80211_input(ni, m,
|
||||||
(int)be32toh(desc->rssi), nf, 0);
|
(int)be32toh(desc->rssi), nf);
|
||||||
/* node is no longer needed */
|
/* node is no longer needed */
|
||||||
ieee80211_free_node(ni);
|
ieee80211_free_node(ni);
|
||||||
} else
|
} else
|
||||||
(void) ieee80211_input_all(ic, m,
|
(void) ieee80211_input_all(ic, m,
|
||||||
(int)be32toh(desc->rssi), nf, 0);
|
(int)be32toh(desc->rssi), nf);
|
||||||
m = NULL;
|
m = NULL;
|
||||||
desc = NULL;
|
desc = NULL;
|
||||||
}
|
}
|
||||||
|
@ -44,16 +44,25 @@ enum {
|
|||||||
|
|
||||||
struct uath_rx_radiotap_header {
|
struct uath_rx_radiotap_header {
|
||||||
struct ieee80211_radiotap_header wr_ihdr;
|
struct ieee80211_radiotap_header wr_ihdr;
|
||||||
uint8_t wr_flags;
|
u_int64_t wr_tsf;
|
||||||
|
u_int8_t wr_flags;
|
||||||
|
u_int8_t wr_rate;
|
||||||
uint16_t wr_chan_freq;
|
uint16_t wr_chan_freq;
|
||||||
uint16_t wr_chan_flags;
|
uint16_t wr_chan_flags;
|
||||||
int8_t wr_dbm_antsignal;
|
int8_t wr_antsignal;
|
||||||
|
int8_t wr_antnoise;
|
||||||
|
u_int8_t wr_antenna;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
#define UATH_RX_RADIOTAP_PRESENT \
|
#define UATH_RX_RADIOTAP_PRESENT ( \
|
||||||
((1 << IEEE80211_RADIOTAP_FLAGS) | \
|
(1 << IEEE80211_RADIOTAP_TSFT) | \
|
||||||
|
(1 << IEEE80211_RADIOTAP_FLAGS) | \
|
||||||
|
(1 << IEEE80211_RADIOTAP_RATE) | \
|
||||||
|
(1 << IEEE80211_RADIOTAP_ANTENNA) | \
|
||||||
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
||||||
(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL))
|
(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \
|
||||||
|
(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \
|
||||||
|
0)
|
||||||
|
|
||||||
struct uath_tx_radiotap_header {
|
struct uath_tx_radiotap_header {
|
||||||
struct ieee80211_radiotap_header wt_ihdr;
|
struct ieee80211_radiotap_header wt_ihdr;
|
||||||
|
@ -367,14 +367,11 @@ upgt_attach(device_t dev)
|
|||||||
ic->ic_vap_delete = upgt_vap_delete;
|
ic->ic_vap_delete = upgt_vap_delete;
|
||||||
ic->ic_update_mcast = upgt_update_mcast;
|
ic->ic_update_mcast = upgt_update_mcast;
|
||||||
|
|
||||||
bpfattach(ifp, DLT_IEEE802_11_RADIO,
|
ieee80211_radiotap_attach(ic,
|
||||||
sizeof(struct ieee80211_frame) + sizeof(sc->sc_txtap));
|
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
|
||||||
sc->sc_rxtap_len = sizeof(sc->sc_rxtap);
|
UPGT_TX_RADIOTAP_PRESENT,
|
||||||
sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
|
&sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
|
||||||
sc->sc_rxtap.wr_ihdr.it_present = htole32(UPGT_RX_RADIOTAP_PRESENT);
|
UPGT_RX_RADIOTAP_PRESENT);
|
||||||
sc->sc_txtap_len = sizeof(sc->sc_txtap);
|
|
||||||
sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
|
|
||||||
sc->sc_txtap.wt_ihdr.it_present = htole32(UPGT_TX_RADIOTAP_PRESENT);
|
|
||||||
|
|
||||||
upgt_sysctl_node(sc);
|
upgt_sysctl_node(sc);
|
||||||
|
|
||||||
@ -1507,16 +1504,12 @@ upgt_rx(struct upgt_softc *sc, uint8_t *data, int pkglen, int *rssi)
|
|||||||
m->m_len = m->m_pkthdr.len = pkglen - IEEE80211_CRC_LEN;
|
m->m_len = m->m_pkthdr.len = pkglen - IEEE80211_CRC_LEN;
|
||||||
m->m_pkthdr.rcvif = ifp;
|
m->m_pkthdr.rcvif = ifp;
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active(ic)) {
|
||||||
struct upgt_rx_radiotap_header *tap = &sc->sc_rxtap;
|
struct upgt_rx_radiotap_header *tap = &sc->sc_rxtap;
|
||||||
|
|
||||||
tap->wr_flags = 0;
|
tap->wr_flags = 0;
|
||||||
tap->wr_rate = upgt_rx_rate(sc, rxdesc->rate);
|
tap->wr_rate = upgt_rx_rate(sc, rxdesc->rate);
|
||||||
tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
|
|
||||||
tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
|
|
||||||
tap->wr_antsignal = rxdesc->rssi;
|
tap->wr_antsignal = rxdesc->rssi;
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
|
|
||||||
}
|
}
|
||||||
ifp->if_ipackets++;
|
ifp->if_ipackets++;
|
||||||
|
|
||||||
@ -2011,7 +2004,6 @@ upgt_detach(device_t dev)
|
|||||||
upgt_free_rx(sc);
|
upgt_free_rx(sc);
|
||||||
upgt_free_tx(sc);
|
upgt_free_tx(sc);
|
||||||
|
|
||||||
bpfdetach(ifp);
|
|
||||||
if_free(ifp);
|
if_free(ifp);
|
||||||
mtx_destroy(&sc->sc_mtx);
|
mtx_destroy(&sc->sc_mtx);
|
||||||
|
|
||||||
@ -2157,11 +2149,11 @@ static int
|
|||||||
upgt_tx_start(struct upgt_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
|
upgt_tx_start(struct upgt_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
|
||||||
struct upgt_data *data)
|
struct upgt_data *data)
|
||||||
{
|
{
|
||||||
|
struct ieee80211vap *vap = ni->ni_vap;
|
||||||
int error = 0, len;
|
int error = 0, len;
|
||||||
struct ieee80211_frame *wh;
|
struct ieee80211_frame *wh;
|
||||||
struct ieee80211_key *k;
|
struct ieee80211_key *k;
|
||||||
struct ifnet *ifp = sc->sc_ifp;
|
struct ifnet *ifp = sc->sc_ifp;
|
||||||
struct ieee80211com *ic = ifp->if_l2com;
|
|
||||||
struct upgt_lmac_mem *mem;
|
struct upgt_lmac_mem *mem;
|
||||||
struct upgt_lmac_tx_desc *txdesc;
|
struct upgt_lmac_tx_desc *txdesc;
|
||||||
|
|
||||||
@ -2211,15 +2203,13 @@ upgt_tx_start(struct upgt_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
|
|||||||
txdesc->type = htole32(UPGT_TX_DESC_TYPE_DATA);
|
txdesc->type = htole32(UPGT_TX_DESC_TYPE_DATA);
|
||||||
txdesc->pad3[0] = UPGT_TX_DESC_PAD3_SIZE;
|
txdesc->pad3[0] = UPGT_TX_DESC_PAD3_SIZE;
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active_vap(vap)) {
|
||||||
struct upgt_tx_radiotap_header *tap = &sc->sc_txtap;
|
struct upgt_tx_radiotap_header *tap = &sc->sc_txtap;
|
||||||
|
|
||||||
tap->wt_flags = 0;
|
tap->wt_flags = 0;
|
||||||
tap->wt_rate = 0; /* XXX where to get from? */
|
tap->wt_rate = 0; /* XXX where to get from? */
|
||||||
tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
|
|
||||||
tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
|
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m);
|
ieee80211_radiotap_tx(vap, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy frame below our TX descriptor header */
|
/* copy frame below our TX descriptor header */
|
||||||
@ -2299,11 +2289,11 @@ setup:
|
|||||||
(struct ieee80211_frame_min *)wh);
|
(struct ieee80211_frame_min *)wh);
|
||||||
nf = -95; /* XXX */
|
nf = -95; /* XXX */
|
||||||
if (ni != NULL) {
|
if (ni != NULL) {
|
||||||
(void) ieee80211_input(ni, m, rssi, nf, 0);
|
(void) ieee80211_input(ni, m, rssi, nf);
|
||||||
/* node is no longer needed */
|
/* node is no longer needed */
|
||||||
ieee80211_free_node(ni);
|
ieee80211_free_node(ni);
|
||||||
} else
|
} else
|
||||||
(void) ieee80211_input_all(ic, m, rssi, nf, 0);
|
(void) ieee80211_input_all(ic, m, rssi, nf);
|
||||||
m = NULL;
|
m = NULL;
|
||||||
}
|
}
|
||||||
UPGT_LOCK(sc);
|
UPGT_LOCK(sc);
|
||||||
|
@ -176,6 +176,7 @@ static void ural_set_chan(struct ural_softc *,
|
|||||||
struct ieee80211_channel *);
|
struct ieee80211_channel *);
|
||||||
static void ural_disable_rf_tune(struct ural_softc *);
|
static void ural_disable_rf_tune(struct ural_softc *);
|
||||||
static void ural_enable_tsf_sync(struct ural_softc *);
|
static void ural_enable_tsf_sync(struct ural_softc *);
|
||||||
|
static void ural_enable_tsf(struct ural_softc *);
|
||||||
static void ural_update_slot(struct ifnet *);
|
static void ural_update_slot(struct ifnet *);
|
||||||
static void ural_set_txpreamble(struct ural_softc *);
|
static void ural_set_txpreamble(struct ural_softc *);
|
||||||
static void ural_set_basicrates(struct ural_softc *,
|
static void ural_set_basicrates(struct ural_softc *,
|
||||||
@ -513,16 +514,11 @@ ural_attach(device_t self)
|
|||||||
ic->ic_vap_create = ural_vap_create;
|
ic->ic_vap_create = ural_vap_create;
|
||||||
ic->ic_vap_delete = ural_vap_delete;
|
ic->ic_vap_delete = ural_vap_delete;
|
||||||
|
|
||||||
bpfattach(ifp, DLT_IEEE802_11_RADIO,
|
ieee80211_radiotap_attach(ic,
|
||||||
sizeof (struct ieee80211_frame) + sizeof(sc->sc_txtap));
|
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
|
||||||
|
RAL_TX_RADIOTAP_PRESENT,
|
||||||
sc->sc_rxtap_len = sizeof sc->sc_rxtap;
|
&sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
|
||||||
sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
|
RAL_RX_RADIOTAP_PRESENT);
|
||||||
sc->sc_rxtap.wr_ihdr.it_present = htole32(RAL_RX_RADIOTAP_PRESENT);
|
|
||||||
|
|
||||||
sc->sc_txtap_len = sizeof sc->sc_txtap;
|
|
||||||
sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
|
|
||||||
sc->sc_txtap.wt_ihdr.it_present = htole32(RAL_TX_RADIOTAP_PRESENT);
|
|
||||||
|
|
||||||
if (bootverbose)
|
if (bootverbose)
|
||||||
ieee80211_announce(ic);
|
ieee80211_announce(ic);
|
||||||
@ -551,7 +547,6 @@ ural_detach(device_t self)
|
|||||||
|
|
||||||
if (ifp) {
|
if (ifp) {
|
||||||
ic = ifp->if_l2com;
|
ic = ifp->if_l2com;
|
||||||
bpfdetach(ifp);
|
|
||||||
ieee80211_ifdetach(ic);
|
ieee80211_ifdetach(ic);
|
||||||
if_free(ifp);
|
if_free(ifp);
|
||||||
}
|
}
|
||||||
@ -761,9 +756,12 @@ ural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
|
|||||||
|
|
||||||
if (vap->iv_opmode != IEEE80211_M_MONITOR)
|
if (vap->iv_opmode != IEEE80211_M_MONITOR)
|
||||||
ural_enable_tsf_sync(sc);
|
ural_enable_tsf_sync(sc);
|
||||||
|
else
|
||||||
|
ural_enable_tsf(sc);
|
||||||
|
|
||||||
/* enable automatic rate adaptation */
|
/* enable automatic rate adaptation */
|
||||||
tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
|
/* XXX should use ic_bsschan but not valid until after newstate call below */
|
||||||
|
tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
|
||||||
if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
|
if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
|
||||||
ural_amrr_start(sc, ni);
|
ural_amrr_start(sc, ni);
|
||||||
|
|
||||||
@ -783,8 +781,7 @@ ural_bulk_write_callback(struct usb2_xfer *xfer)
|
|||||||
{
|
{
|
||||||
struct ural_softc *sc = xfer->priv_sc;
|
struct ural_softc *sc = xfer->priv_sc;
|
||||||
struct ifnet *ifp = sc->sc_ifp;
|
struct ifnet *ifp = sc->sc_ifp;
|
||||||
struct ieee80211com *ic = ifp->if_l2com;
|
struct ieee80211vap *vap;
|
||||||
struct ieee80211_channel *c = ic->ic_curchan;
|
|
||||||
struct ural_tx_data *data;
|
struct ural_tx_data *data;
|
||||||
struct mbuf *m;
|
struct mbuf *m;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
@ -819,16 +816,15 @@ tr_setup:
|
|||||||
usb2_m_copy_in(xfer->frbuffers, RAL_TX_DESC_SIZE, m, 0,
|
usb2_m_copy_in(xfer->frbuffers, RAL_TX_DESC_SIZE, m, 0,
|
||||||
m->m_pkthdr.len);
|
m->m_pkthdr.len);
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
vap = data->ni->ni_vap;
|
||||||
|
if (ieee80211_radiotap_active_vap(vap)) {
|
||||||
struct ural_tx_radiotap_header *tap = &sc->sc_txtap;
|
struct ural_tx_radiotap_header *tap = &sc->sc_txtap;
|
||||||
|
|
||||||
tap->wt_flags = 0;
|
tap->wt_flags = 0;
|
||||||
tap->wt_rate = data->rate;
|
tap->wt_rate = data->rate;
|
||||||
tap->wt_chan_freq = htole16(c->ic_freq);
|
|
||||||
tap->wt_chan_flags = htole16(c->ic_flags);
|
|
||||||
tap->wt_antenna = sc->tx_ant;
|
tap->wt_antenna = sc->tx_ant;
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m);
|
ieee80211_radiotap_tx(vap, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* xfer length needs to be a multiple of two! */
|
/* xfer length needs to be a multiple of two! */
|
||||||
@ -877,7 +873,7 @@ ural_bulk_read_callback(struct usb2_xfer *xfer)
|
|||||||
struct ieee80211_node *ni;
|
struct ieee80211_node *ni;
|
||||||
struct mbuf *m = NULL;
|
struct mbuf *m = NULL;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
uint8_t rssi = 0;
|
int8_t rssi = 0, nf = 0;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
|
|
||||||
switch (USB_GET_STATE(xfer)) {
|
switch (USB_GET_STATE(xfer)) {
|
||||||
@ -899,6 +895,7 @@ ural_bulk_read_callback(struct usb2_xfer *xfer)
|
|||||||
RAL_RX_DESC_SIZE);
|
RAL_RX_DESC_SIZE);
|
||||||
|
|
||||||
rssi = URAL_RSSI(sc->sc_rx_desc.rssi);
|
rssi = URAL_RSSI(sc->sc_rx_desc.rssi);
|
||||||
|
nf = RAL_NOISE_FLOOR;
|
||||||
flags = le32toh(sc->sc_rx_desc.flags);
|
flags = le32toh(sc->sc_rx_desc.flags);
|
||||||
if (flags & (RAL_RX_PHY_ERROR | RAL_RX_CRC_ERROR)) {
|
if (flags & (RAL_RX_PHY_ERROR | RAL_RX_CRC_ERROR)) {
|
||||||
/*
|
/*
|
||||||
@ -923,19 +920,17 @@ ural_bulk_read_callback(struct usb2_xfer *xfer)
|
|||||||
m->m_pkthdr.rcvif = ifp;
|
m->m_pkthdr.rcvif = ifp;
|
||||||
m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff;
|
m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff;
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active(ic)) {
|
||||||
struct ural_rx_radiotap_header *tap = &sc->sc_rxtap;
|
struct ural_rx_radiotap_header *tap = &sc->sc_rxtap;
|
||||||
|
|
||||||
tap->wr_flags = IEEE80211_RADIOTAP_F_FCS;
|
/* XXX set once */
|
||||||
|
tap->wr_flags = 0;
|
||||||
tap->wr_rate = ieee80211_plcp2rate(sc->sc_rx_desc.rate,
|
tap->wr_rate = ieee80211_plcp2rate(sc->sc_rx_desc.rate,
|
||||||
(flags & RAL_RX_OFDM) ?
|
(flags & RAL_RX_OFDM) ?
|
||||||
IEEE80211_T_OFDM : IEEE80211_T_CCK);
|
IEEE80211_T_OFDM : IEEE80211_T_CCK);
|
||||||
tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
|
|
||||||
tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
|
|
||||||
tap->wr_antenna = sc->rx_ant;
|
tap->wr_antenna = sc->rx_ant;
|
||||||
tap->wr_antsignal = rssi;
|
tap->wr_antsignal = nf + rssi;
|
||||||
|
tap->wr_antnoise = nf;
|
||||||
bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
|
|
||||||
}
|
}
|
||||||
/* Strip trailing 802.11 MAC FCS. */
|
/* Strip trailing 802.11 MAC FCS. */
|
||||||
m_adj(m, -IEEE80211_CRC_LEN);
|
m_adj(m, -IEEE80211_CRC_LEN);
|
||||||
@ -956,12 +951,10 @@ tr_setup:
|
|||||||
ni = ieee80211_find_rxnode(ic,
|
ni = ieee80211_find_rxnode(ic,
|
||||||
mtod(m, struct ieee80211_frame_min *));
|
mtod(m, struct ieee80211_frame_min *));
|
||||||
if (ni != NULL) {
|
if (ni != NULL) {
|
||||||
(void) ieee80211_input(ni, m, rssi,
|
(void) ieee80211_input(ni, m, rssi, nf);
|
||||||
RAL_NOISE_FLOOR, 0);
|
|
||||||
ieee80211_free_node(ni);
|
ieee80211_free_node(ni);
|
||||||
} else
|
} else
|
||||||
(void) ieee80211_input_all(ic, m, rssi,
|
(void) ieee80211_input_all(ic, m, rssi, nf);
|
||||||
RAL_NOISE_FLOOR, 0);
|
|
||||||
RAL_LOCK(sc);
|
RAL_LOCK(sc);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -1799,6 +1792,14 @@ ural_enable_tsf_sync(struct ural_softc *sc)
|
|||||||
DPRINTF("enabling TSF synchronization\n");
|
DPRINTF("enabling TSF synchronization\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ural_enable_tsf(struct ural_softc *sc)
|
||||||
|
{
|
||||||
|
/* first, disable TSF synchronization */
|
||||||
|
ural_write(sc, RAL_TXRX_CSR19, 0);
|
||||||
|
ural_write(sc, RAL_TXRX_CSR19, RAL_ENABLE_TSF | RAL_ENABLE_TSF_SYNC(2));
|
||||||
|
}
|
||||||
|
|
||||||
#define RAL_RXTX_TURNAROUND 5 /* us */
|
#define RAL_RXTX_TURNAROUND 5 /* us */
|
||||||
static void
|
static void
|
||||||
ural_update_slot(struct ifnet *ifp)
|
ural_update_slot(struct ifnet *ifp)
|
||||||
|
@ -31,8 +31,9 @@ struct ural_rx_radiotap_header {
|
|||||||
uint8_t wr_rate;
|
uint8_t wr_rate;
|
||||||
uint16_t wr_chan_freq;
|
uint16_t wr_chan_freq;
|
||||||
uint16_t wr_chan_flags;
|
uint16_t wr_chan_flags;
|
||||||
|
int8_t wr_antsignal;
|
||||||
|
int8_t wr_antnoise;
|
||||||
uint8_t wr_antenna;
|
uint8_t wr_antenna;
|
||||||
uint8_t wr_antsignal;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define RAL_RX_RADIOTAP_PRESENT \
|
#define RAL_RX_RADIOTAP_PRESENT \
|
||||||
@ -40,7 +41,8 @@ struct ural_rx_radiotap_header {
|
|||||||
(1 << IEEE80211_RADIOTAP_RATE) | \
|
(1 << IEEE80211_RADIOTAP_RATE) | \
|
||||||
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
||||||
(1 << IEEE80211_RADIOTAP_ANTENNA) | \
|
(1 << IEEE80211_RADIOTAP_ANTENNA) | \
|
||||||
(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL))
|
(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \
|
||||||
|
(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE))
|
||||||
|
|
||||||
struct ural_tx_radiotap_header {
|
struct ural_tx_radiotap_header {
|
||||||
struct ieee80211_radiotap_header wt_ihdr;
|
struct ieee80211_radiotap_header wt_ihdr;
|
||||||
|
@ -421,14 +421,11 @@ zyd_attach(device_t dev)
|
|||||||
ic->ic_update_mcast = zyd_update_mcast;
|
ic->ic_update_mcast = zyd_update_mcast;
|
||||||
ic->ic_update_promisc = zyd_update_mcast;
|
ic->ic_update_promisc = zyd_update_mcast;
|
||||||
|
|
||||||
bpfattach(ifp, DLT_IEEE802_11_RADIO,
|
ieee80211_radiotap_attach(ic,
|
||||||
sizeof(struct ieee80211_frame) + sizeof(sc->sc_txtap));
|
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
|
||||||
sc->sc_rxtap_len = sizeof(sc->sc_rxtap);
|
ZYD_TX_RADIOTAP_PRESENT,
|
||||||
sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
|
&sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
|
||||||
sc->sc_rxtap.wr_ihdr.it_present = htole32(ZYD_RX_RADIOTAP_PRESENT);
|
ZYD_RX_RADIOTAP_PRESENT);
|
||||||
sc->sc_txtap_len = sizeof(sc->sc_txtap);
|
|
||||||
sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
|
|
||||||
sc->sc_txtap.wt_ihdr.it_present = htole32(ZYD_TX_RADIOTAP_PRESENT);
|
|
||||||
|
|
||||||
if (bootverbose)
|
if (bootverbose)
|
||||||
ieee80211_announce(ic);
|
ieee80211_announce(ic);
|
||||||
@ -455,7 +452,6 @@ zyd_detach(device_t dev)
|
|||||||
|
|
||||||
if (ifp) {
|
if (ifp) {
|
||||||
ic = ifp->if_l2com;
|
ic = ifp->if_l2com;
|
||||||
bpfdetach(ifp);
|
|
||||||
ieee80211_ifdetach(ic);
|
ieee80211_ifdetach(ic);
|
||||||
if_free(ifp);
|
if_free(ifp);
|
||||||
}
|
}
|
||||||
@ -2132,6 +2128,7 @@ zyd_rx_data(struct usb2_xfer *xfer, int offset, uint16_t len)
|
|||||||
{
|
{
|
||||||
struct zyd_softc *sc = xfer->priv_sc;
|
struct zyd_softc *sc = xfer->priv_sc;
|
||||||
struct ifnet *ifp = sc->sc_ifp;
|
struct ifnet *ifp = sc->sc_ifp;
|
||||||
|
struct ieee80211com *ic = ifp->if_l2com;
|
||||||
struct zyd_plcphdr plcp;
|
struct zyd_plcphdr plcp;
|
||||||
struct zyd_rx_stat stat;
|
struct zyd_rx_stat stat;
|
||||||
struct mbuf *m;
|
struct mbuf *m;
|
||||||
@ -2180,7 +2177,7 @@ zyd_rx_data(struct usb2_xfer *xfer, int offset, uint16_t len)
|
|||||||
usb2_copy_out(xfer->frbuffers, offset + sizeof(plcp),
|
usb2_copy_out(xfer->frbuffers, offset + sizeof(plcp),
|
||||||
mtod(m, uint8_t *), rlen);
|
mtod(m, uint8_t *), rlen);
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active(ic)) {
|
||||||
struct zyd_rx_radiotap_header *tap = &sc->sc_rxtap;
|
struct zyd_rx_radiotap_header *tap = &sc->sc_rxtap;
|
||||||
|
|
||||||
tap->wr_flags = 0;
|
tap->wr_flags = 0;
|
||||||
@ -2194,8 +2191,6 @@ zyd_rx_data(struct usb2_xfer *xfer, int offset, uint16_t len)
|
|||||||
IEEE80211_T_OFDM : IEEE80211_T_CCK);
|
IEEE80211_T_OFDM : IEEE80211_T_CCK);
|
||||||
tap->wr_antsignal = stat.rssi + -95;
|
tap->wr_antsignal = stat.rssi + -95;
|
||||||
tap->wr_antnoise = -95; /* XXX */
|
tap->wr_antnoise = -95; /* XXX */
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
|
|
||||||
}
|
}
|
||||||
rssi = (stat.rssi > 63) ? 127 : 2 * stat.rssi;
|
rssi = (stat.rssi > 63) ? 127 : 2 * stat.rssi;
|
||||||
|
|
||||||
@ -2272,10 +2267,10 @@ tr_setup:
|
|||||||
ni = ieee80211_find_rxnode(ic,
|
ni = ieee80211_find_rxnode(ic,
|
||||||
mtod(m, struct ieee80211_frame_min *));
|
mtod(m, struct ieee80211_frame_min *));
|
||||||
if (ni != NULL) {
|
if (ni != NULL) {
|
||||||
(void)ieee80211_input(ni, m, rssi, nf, 0);
|
(void)ieee80211_input(ni, m, rssi, nf);
|
||||||
ieee80211_free_node(ni);
|
ieee80211_free_node(ni);
|
||||||
} else
|
} else
|
||||||
(void)ieee80211_input_all(ic, m, rssi, nf, 0);
|
(void)ieee80211_input_all(ic, m, rssi, nf);
|
||||||
}
|
}
|
||||||
ZYD_LOCK(sc);
|
ZYD_LOCK(sc);
|
||||||
break;
|
break;
|
||||||
@ -2331,7 +2326,6 @@ zyd_tx_mgt(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
|
|||||||
{
|
{
|
||||||
struct ieee80211vap *vap = ni->ni_vap;
|
struct ieee80211vap *vap = ni->ni_vap;
|
||||||
struct ieee80211com *ic = ni->ni_ic;
|
struct ieee80211com *ic = ni->ni_ic;
|
||||||
struct ifnet *ifp = sc->sc_ifp;
|
|
||||||
struct zyd_tx_desc *desc;
|
struct zyd_tx_desc *desc;
|
||||||
struct zyd_tx_data *data;
|
struct zyd_tx_data *data;
|
||||||
struct ieee80211_frame *wh;
|
struct ieee80211_frame *wh;
|
||||||
@ -2409,13 +2403,13 @@ zyd_tx_mgt(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
|
|||||||
desc->plcp_service |= ZYD_PLCP_LENGEXT;
|
desc->plcp_service |= ZYD_PLCP_LENGEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active_vap(vap)) {
|
||||||
struct zyd_tx_radiotap_header *tap = &sc->sc_txtap;
|
struct zyd_tx_radiotap_header *tap = &sc->sc_txtap;
|
||||||
|
|
||||||
tap->wt_flags = 0;
|
tap->wt_flags = 0;
|
||||||
tap->wt_rate = rate;
|
tap->wt_rate = rate;
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
|
ieee80211_radiotap_tx(vap, m0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINTF(sc, ZYD_DEBUG_XMIT,
|
DPRINTF(sc, ZYD_DEBUG_XMIT,
|
||||||
@ -2434,8 +2428,7 @@ zyd_bulk_write_callback(struct usb2_xfer *xfer)
|
|||||||
{
|
{
|
||||||
struct zyd_softc *sc = xfer->priv_sc;
|
struct zyd_softc *sc = xfer->priv_sc;
|
||||||
struct ifnet *ifp = sc->sc_ifp;
|
struct ifnet *ifp = sc->sc_ifp;
|
||||||
struct ieee80211com *ic = ifp->if_l2com;
|
struct ieee80211vap *vap;
|
||||||
struct ieee80211_channel *c = ic->ic_curchan;
|
|
||||||
struct zyd_tx_data *data;
|
struct zyd_tx_data *data;
|
||||||
struct mbuf *m;
|
struct mbuf *m;
|
||||||
|
|
||||||
@ -2470,15 +2463,14 @@ tr_setup:
|
|||||||
usb2_m_copy_in(xfer->frbuffers, ZYD_TX_DESC_SIZE, m, 0,
|
usb2_m_copy_in(xfer->frbuffers, ZYD_TX_DESC_SIZE, m, 0,
|
||||||
m->m_pkthdr.len);
|
m->m_pkthdr.len);
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
vap = data->ni->ni_vap;
|
||||||
|
if (ieee80211_radiotap_active_vap(vap)) {
|
||||||
struct zyd_tx_radiotap_header *tap = &sc->sc_txtap;
|
struct zyd_tx_radiotap_header *tap = &sc->sc_txtap;
|
||||||
|
|
||||||
tap->wt_flags = 0;
|
tap->wt_flags = 0;
|
||||||
tap->wt_rate = data->rate;
|
tap->wt_rate = data->rate;
|
||||||
tap->wt_chan_freq = htole16(c->ic_freq);
|
|
||||||
tap->wt_chan_flags = htole16(c->ic_flags);
|
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m);
|
ieee80211_radiotap_tx(vap, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
xfer->frlengths[0] = ZYD_TX_DESC_SIZE + m->m_pkthdr.len;
|
xfer->frlengths[0] = ZYD_TX_DESC_SIZE + m->m_pkthdr.len;
|
||||||
|
@ -121,9 +121,10 @@ static int wi_start_tx(struct ifnet *ifp, struct wi_frame *frmhdr,
|
|||||||
static int wi_raw_xmit(struct ieee80211_node *, struct mbuf *,
|
static int wi_raw_xmit(struct ieee80211_node *, struct mbuf *,
|
||||||
const struct ieee80211_bpf_params *);
|
const struct ieee80211_bpf_params *);
|
||||||
static int wi_newstate_sta(struct ieee80211vap *, enum ieee80211_state, int);
|
static int wi_newstate_sta(struct ieee80211vap *, enum ieee80211_state, int);
|
||||||
static int wi_newstate_hostap(struct ieee80211vap *, enum ieee80211_state, int);
|
static int wi_newstate_hostap(struct ieee80211vap *, enum ieee80211_state,
|
||||||
|
int);
|
||||||
static void wi_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
|
static void wi_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
|
||||||
int subtype, int rssi, int noise, u_int32_t rstamp);
|
int subtype, int rssi, int nf);
|
||||||
static int wi_reset(struct wi_softc *);
|
static int wi_reset(struct wi_softc *);
|
||||||
static void wi_watchdog(void *);
|
static void wi_watchdog(void *);
|
||||||
static int wi_ioctl(struct ifnet *, u_long, caddr_t);
|
static int wi_ioctl(struct ifnet *, u_long, caddr_t);
|
||||||
@ -139,6 +140,7 @@ static int wi_write_txrate(struct wi_softc *, struct ieee80211vap *);
|
|||||||
static int wi_write_wep(struct wi_softc *, struct ieee80211vap *);
|
static int wi_write_wep(struct wi_softc *, struct ieee80211vap *);
|
||||||
static int wi_write_multi(struct wi_softc *);
|
static int wi_write_multi(struct wi_softc *);
|
||||||
static void wi_update_mcast(struct ifnet *);
|
static void wi_update_mcast(struct ifnet *);
|
||||||
|
static void wi_update_promisc(struct ifnet *);
|
||||||
static int wi_alloc_fid(struct wi_softc *, int, int *);
|
static int wi_alloc_fid(struct wi_softc *, int, int *);
|
||||||
static void wi_read_nicid(struct wi_softc *);
|
static void wi_read_nicid(struct wi_softc *);
|
||||||
static int wi_write_ssid(struct wi_softc *, int, u_int8_t *, int);
|
static int wi_write_ssid(struct wi_softc *, int, u_int8_t *, int);
|
||||||
@ -455,25 +457,13 @@ wi_attach(device_t dev)
|
|||||||
ic->ic_vap_create = wi_vap_create;
|
ic->ic_vap_create = wi_vap_create;
|
||||||
ic->ic_vap_delete = wi_vap_delete;
|
ic->ic_vap_delete = wi_vap_delete;
|
||||||
ic->ic_update_mcast = wi_update_mcast;
|
ic->ic_update_mcast = wi_update_mcast;
|
||||||
|
ic->ic_update_promisc = wi_update_promisc;
|
||||||
|
|
||||||
bpfattach(ifp, DLT_IEEE802_11_RADIO,
|
ieee80211_radiotap_attach(ic,
|
||||||
sizeof(struct ieee80211_frame) + sizeof(sc->sc_tx_th));
|
&sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
|
||||||
/*
|
WI_TX_RADIOTAP_PRESENT,
|
||||||
* Initialize constant fields.
|
&sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
|
||||||
* XXX make header lengths a multiple of 32-bits so subsequent
|
WI_RX_RADIOTAP_PRESENT);
|
||||||
* headers are properly aligned; this is a kludge to keep
|
|
||||||
* certain applications happy.
|
|
||||||
*
|
|
||||||
* NB: the channel is setup each time we transition to the
|
|
||||||
* RUN state to avoid filling it in for each frame.
|
|
||||||
*/
|
|
||||||
sc->sc_tx_th_len = roundup(sizeof(sc->sc_tx_th), sizeof(u_int32_t));
|
|
||||||
sc->sc_tx_th.wt_ihdr.it_len = htole16(sc->sc_tx_th_len);
|
|
||||||
sc->sc_tx_th.wt_ihdr.it_present = htole32(WI_TX_RADIOTAP_PRESENT);
|
|
||||||
|
|
||||||
sc->sc_rx_th_len = roundup(sizeof(sc->sc_rx_th), sizeof(u_int32_t));
|
|
||||||
sc->sc_rx_th.wr_ihdr.it_len = htole16(sc->sc_rx_th_len);
|
|
||||||
sc->sc_rx_th.wr_ihdr.it_present = htole32(WI_RX_RADIOTAP_PRESENT);
|
|
||||||
|
|
||||||
if (bootverbose)
|
if (bootverbose)
|
||||||
ieee80211_announce(ic);
|
ieee80211_announce(ic);
|
||||||
@ -482,7 +472,6 @@ wi_attach(device_t dev)
|
|||||||
NULL, wi_intr, sc, &sc->wi_intrhand);
|
NULL, wi_intr, sc, &sc->wi_intrhand);
|
||||||
if (error) {
|
if (error) {
|
||||||
device_printf(dev, "bus_setup_intr() failed! (%d)\n", error);
|
device_printf(dev, "bus_setup_intr() failed! (%d)\n", error);
|
||||||
bpfdetach(ifp);
|
|
||||||
ieee80211_ifdetach(ic);
|
ieee80211_ifdetach(ic);
|
||||||
if_free(sc->sc_ifp);
|
if_free(sc->sc_ifp);
|
||||||
wi_free(dev);
|
wi_free(dev);
|
||||||
@ -506,7 +495,6 @@ wi_detach(device_t dev)
|
|||||||
|
|
||||||
wi_stop_locked(sc, 0);
|
wi_stop_locked(sc, 0);
|
||||||
WI_UNLOCK(sc);
|
WI_UNLOCK(sc);
|
||||||
bpfdetach(ifp);
|
|
||||||
ieee80211_ifdetach(ic);
|
ieee80211_ifdetach(ic);
|
||||||
|
|
||||||
bus_teardown_intr(dev, sc->irq, sc->wi_intrhand);
|
bus_teardown_intr(dev, sc->irq, sc->wi_intrhand);
|
||||||
@ -761,11 +749,6 @@ wi_set_channel(struct ieee80211com *ic)
|
|||||||
WI_LOCK(sc);
|
WI_LOCK(sc);
|
||||||
wi_write_val(sc, WI_RID_OWN_CHNL,
|
wi_write_val(sc, WI_RID_OWN_CHNL,
|
||||||
ieee80211_chan2ieee(ic, ic->ic_curchan));
|
ieee80211_chan2ieee(ic, ic->ic_curchan));
|
||||||
|
|
||||||
sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
|
|
||||||
htole16(ic->ic_curchan->ic_freq);
|
|
||||||
sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
|
|
||||||
htole16(ic->ic_curchan->ic_flags);
|
|
||||||
WI_UNLOCK(sc);
|
WI_UNLOCK(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -812,7 +795,7 @@ wi_scan_end(struct ieee80211com *ic)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
wi_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
|
wi_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
|
||||||
int subtype, int rssi, int noise, u_int32_t rstamp)
|
int subtype, int rssi, int nf)
|
||||||
{
|
{
|
||||||
struct ieee80211vap *vap = ni->ni_vap;
|
struct ieee80211vap *vap = ni->ni_vap;
|
||||||
|
|
||||||
@ -823,7 +806,7 @@ wi_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
|
|||||||
/* NB: filter frames that trigger state changes */
|
/* NB: filter frames that trigger state changes */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
WI_VAP(vap)->wv_recv_mgmt(ni, m, subtype, rssi, noise, rstamp);
|
WI_VAP(vap)->wv_recv_mgmt(ni, m, subtype, rssi, nf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -1025,10 +1008,9 @@ wi_start_locked(struct ifnet *ifp)
|
|||||||
frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_NOCRYPT);
|
frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_NOCRYPT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active_vap(ni->ni_vap)) {
|
||||||
sc->sc_tx_th.wt_rate = ni->ni_txrate;
|
sc->sc_tx_th.wt_rate = ni->ni_txrate;
|
||||||
bpf_mtap2(ifp->if_bpf,
|
ieee80211_radiotap_tx(ni->ni_vap, m0);
|
||||||
&sc->sc_tx_th, sc->sc_tx_th_len, m0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_copydata(m0, 0, sizeof(struct ieee80211_frame),
|
m_copydata(m0, 0, sizeof(struct ieee80211_frame),
|
||||||
@ -1088,6 +1070,7 @@ wi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m0,
|
|||||||
{
|
{
|
||||||
struct ieee80211com *ic = ni->ni_ic;
|
struct ieee80211com *ic = ni->ni_ic;
|
||||||
struct ifnet *ifp = ic->ic_ifp;
|
struct ifnet *ifp = ic->ic_ifp;
|
||||||
|
struct ieee80211vap *vap = ni->ni_vap;
|
||||||
struct wi_softc *sc = ifp->if_softc;
|
struct wi_softc *sc = ifp->if_softc;
|
||||||
struct ieee80211_key *k;
|
struct ieee80211_key *k;
|
||||||
struct ieee80211_frame *wh;
|
struct ieee80211_frame *wh;
|
||||||
@ -1127,9 +1110,9 @@ wi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m0,
|
|||||||
}
|
}
|
||||||
frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_NOCRYPT);
|
frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_NOCRYPT);
|
||||||
}
|
}
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active_vap(vap)) {
|
||||||
sc->sc_tx_th.wt_rate = ni->ni_txrate;
|
sc->sc_tx_th.wt_rate = ni->ni_txrate;
|
||||||
bpf_mtap2(ifp->if_bpf, &sc->sc_tx_th, sc->sc_tx_th_len, m0);
|
ieee80211_radiotap_tx(vap, m0);
|
||||||
}
|
}
|
||||||
m_copydata(m0, 0, sizeof(struct ieee80211_frame),
|
m_copydata(m0, 0, sizeof(struct ieee80211_frame),
|
||||||
(caddr_t)&frmhdr.wi_whdr);
|
(caddr_t)&frmhdr.wi_whdr);
|
||||||
@ -1328,10 +1311,10 @@ wi_rx_intr(struct wi_softc *sc)
|
|||||||
struct mbuf *m;
|
struct mbuf *m;
|
||||||
struct ieee80211_frame *wh;
|
struct ieee80211_frame *wh;
|
||||||
struct ieee80211_node *ni;
|
struct ieee80211_node *ni;
|
||||||
int fid, len, off, rssi;
|
int fid, len, off;
|
||||||
u_int8_t dir;
|
u_int8_t dir;
|
||||||
u_int16_t status;
|
u_int16_t status;
|
||||||
u_int32_t rstamp;
|
int8_t rssi, nf;
|
||||||
|
|
||||||
fid = CSR_READ_2(sc, WI_RX_FID);
|
fid = CSR_READ_2(sc, WI_RX_FID);
|
||||||
|
|
||||||
@ -1353,9 +1336,6 @@ wi_rx_intr(struct wi_softc *sc)
|
|||||||
DPRINTF(("wi_rx_intr: fid %x error status %x\n", fid, status));
|
DPRINTF(("wi_rx_intr: fid %x error status %x\n", fid, status));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rssi = frmhdr.wi_rx_signal;
|
|
||||||
rstamp = (le16toh(frmhdr.wi_rx_tstamp0) << 16) |
|
|
||||||
le16toh(frmhdr.wi_rx_tstamp1);
|
|
||||||
|
|
||||||
len = le16toh(frmhdr.wi_dat_len);
|
len = le16toh(frmhdr.wi_dat_len);
|
||||||
off = ALIGN(sizeof(struct ieee80211_frame));
|
off = ALIGN(sizeof(struct ieee80211_frame));
|
||||||
@ -1393,17 +1373,24 @@ wi_rx_intr(struct wi_softc *sc)
|
|||||||
|
|
||||||
CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
|
CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
rssi = frmhdr.wi_rx_signal;
|
||||||
|
nf = frmhdr.wi_rx_silence;
|
||||||
|
if (ieee80211_radiotap_active(ic)) {
|
||||||
|
struct wi_rx_radiotap_header *tap = &sc->sc_rx_th;
|
||||||
|
uint32_t rstamp;
|
||||||
|
|
||||||
|
rstamp = (le16toh(frmhdr.wi_rx_tstamp0) << 16) |
|
||||||
|
le16toh(frmhdr.wi_rx_tstamp1);
|
||||||
|
tap->wr_tsf = htole64(rstamp);
|
||||||
/* XXX replace divide by table */
|
/* XXX replace divide by table */
|
||||||
sc->sc_rx_th.wr_rate = frmhdr.wi_rx_rate / 5;
|
tap->wr_rate = frmhdr.wi_rx_rate / 5;
|
||||||
sc->sc_rx_th.wr_antsignal = frmhdr.wi_rx_signal;
|
tap->wr_flags = 0;
|
||||||
sc->sc_rx_th.wr_antnoise = frmhdr.wi_rx_silence;
|
|
||||||
sc->sc_rx_th.wr_flags = 0;
|
|
||||||
if (frmhdr.wi_status & WI_STAT_PCF)
|
if (frmhdr.wi_status & WI_STAT_PCF)
|
||||||
sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_CFP;
|
tap->wr_flags |= IEEE80211_RADIOTAP_F_CFP;
|
||||||
if (m->m_flags & M_WEP)
|
if (m->m_flags & M_WEP)
|
||||||
sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
|
tap->wr_flags |= IEEE80211_RADIOTAP_F_WEP;
|
||||||
bpf_mtap2(ifp->if_bpf, &sc->sc_rx_th, sc->sc_rx_th_len, m);
|
tap->wr_antsignal = rssi;
|
||||||
|
tap->wr_antnoise = nf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* synchronize driver's BSSID with firmware's BSSID */
|
/* synchronize driver's BSSID with firmware's BSSID */
|
||||||
@ -1416,10 +1403,10 @@ wi_rx_intr(struct wi_softc *sc)
|
|||||||
|
|
||||||
ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
|
ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
|
||||||
if (ni != NULL) {
|
if (ni != NULL) {
|
||||||
(void) ieee80211_input(ni, m, rssi, -95/*XXX*/, rstamp);
|
(void) ieee80211_input(ni, m, rssi, nf);
|
||||||
ieee80211_free_node(ni);
|
ieee80211_free_node(ni);
|
||||||
} else
|
} else
|
||||||
(void) ieee80211_input_all(ic, m, rssi, -95/*XXX*/, rstamp);
|
(void) ieee80211_input_all(ic, m, rssi, nf);
|
||||||
|
|
||||||
WI_LOCK(sc);
|
WI_LOCK(sc);
|
||||||
}
|
}
|
||||||
@ -1614,6 +1601,20 @@ wi_update_mcast(struct ifnet *ifp)
|
|||||||
wi_write_multi(ifp->if_softc);
|
wi_write_multi(ifp->if_softc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
wi_update_promisc(struct ifnet *ifp)
|
||||||
|
{
|
||||||
|
struct wi_softc *sc = ifp->if_softc;
|
||||||
|
struct ieee80211com *ic = ifp->if_l2com;
|
||||||
|
|
||||||
|
WI_LOCK(sc);
|
||||||
|
/* XXX handle WEP special case handling? */
|
||||||
|
wi_write_val(sc, WI_RID_PROMISC,
|
||||||
|
(ic->ic_opmode == IEEE80211_M_MONITOR ||
|
||||||
|
(ifp->if_flags & IFF_PROMISC)));
|
||||||
|
WI_UNLOCK(sc);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
wi_read_nicid(struct wi_softc *sc)
|
wi_read_nicid(struct wi_softc *sc)
|
||||||
{
|
{
|
||||||
|
@ -691,7 +691,8 @@ struct wi_frame {
|
|||||||
* Radio capture format for Prism.
|
* Radio capture format for Prism.
|
||||||
*/
|
*/
|
||||||
#define WI_RX_RADIOTAP_PRESENT \
|
#define WI_RX_RADIOTAP_PRESENT \
|
||||||
((1 << IEEE80211_RADIOTAP_FLAGS) | \
|
((1 << IEEE80211_RADIOTAP_TSFT) | \
|
||||||
|
(1 << IEEE80211_RADIOTAP_FLAGS) | \
|
||||||
(1 << IEEE80211_RADIOTAP_RATE) | \
|
(1 << IEEE80211_RADIOTAP_RATE) | \
|
||||||
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
||||||
(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \
|
(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \
|
||||||
@ -699,6 +700,7 @@ struct wi_frame {
|
|||||||
|
|
||||||
struct wi_rx_radiotap_header {
|
struct wi_rx_radiotap_header {
|
||||||
struct ieee80211_radiotap_header wr_ihdr;
|
struct ieee80211_radiotap_header wr_ihdr;
|
||||||
|
u_int64_t wr_tsf;
|
||||||
u_int8_t wr_flags;
|
u_int8_t wr_flags;
|
||||||
u_int8_t wr_rate;
|
u_int8_t wr_rate;
|
||||||
u_int16_t wr_chan_freq;
|
u_int16_t wr_chan_freq;
|
||||||
|
@ -60,8 +60,8 @@ struct wi_vap {
|
|||||||
struct ieee80211vap wv_vap;
|
struct ieee80211vap wv_vap;
|
||||||
struct ieee80211_beacon_offsets wv_bo;
|
struct ieee80211_beacon_offsets wv_bo;
|
||||||
|
|
||||||
void (*wv_recv_mgmt)(struct ieee80211_node *,
|
void (*wv_recv_mgmt)(struct ieee80211_node *, struct mbuf *,
|
||||||
struct mbuf *, int, int, int, u_int32_t);
|
int, int, int);
|
||||||
int (*wv_newstate)(struct ieee80211vap *,
|
int (*wv_newstate)(struct ieee80211vap *,
|
||||||
enum ieee80211_state, int);
|
enum ieee80211_state, int);
|
||||||
};
|
};
|
||||||
@ -141,9 +141,7 @@ struct wi_softc {
|
|||||||
u_int16_t sc_txbuf[IEEE80211_MAX_LEN/2];
|
u_int16_t sc_txbuf[IEEE80211_MAX_LEN/2];
|
||||||
|
|
||||||
struct wi_tx_radiotap_header sc_tx_th;
|
struct wi_tx_radiotap_header sc_tx_th;
|
||||||
int sc_tx_th_len;
|
|
||||||
struct wi_rx_radiotap_header sc_rx_th;
|
struct wi_rx_radiotap_header sc_rx_th;
|
||||||
int sc_rx_th_len;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* maximum consecutive false change-of-BSSID indications */
|
/* maximum consecutive false change-of-BSSID indications */
|
||||||
|
@ -681,16 +681,11 @@ wpi_attach(device_t dev)
|
|||||||
ic->ic_vap_create = wpi_vap_create;
|
ic->ic_vap_create = wpi_vap_create;
|
||||||
ic->ic_vap_delete = wpi_vap_delete;
|
ic->ic_vap_delete = wpi_vap_delete;
|
||||||
|
|
||||||
bpfattach(ifp, DLT_IEEE802_11_RADIO,
|
ieee80211_radiotap_attach(ic,
|
||||||
sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap));
|
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
|
||||||
|
WPI_TX_RADIOTAP_PRESENT,
|
||||||
sc->sc_rxtap_len = sizeof sc->sc_rxtap;
|
&sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
|
||||||
sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
|
WPI_RX_RADIOTAP_PRESENT);
|
||||||
sc->sc_rxtap.wr_ihdr.it_present = htole32(WPI_RX_RADIOTAP_PRESENT);
|
|
||||||
|
|
||||||
sc->sc_txtap_len = sizeof sc->sc_txtap;
|
|
||||||
sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
|
|
||||||
sc->sc_txtap.wt_ihdr.it_present = htole32(WPI_TX_RADIOTAP_PRESENT);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Hook our interrupt after all initialization is complete.
|
* Hook our interrupt after all initialization is complete.
|
||||||
@ -728,7 +723,6 @@ wpi_detach(device_t dev)
|
|||||||
wpi_stop(sc);
|
wpi_stop(sc);
|
||||||
callout_drain(&sc->watchdog_to);
|
callout_drain(&sc->watchdog_to);
|
||||||
callout_drain(&sc->calib_to);
|
callout_drain(&sc->calib_to);
|
||||||
bpfdetach(ifp);
|
|
||||||
ieee80211_ifdetach(ic);
|
ieee80211_ifdetach(ic);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1519,7 +1513,7 @@ wpi_rx_intr(struct wpi_softc *sc, struct wpi_rx_desc *desc,
|
|||||||
/* update Rx descriptor */
|
/* update Rx descriptor */
|
||||||
ring->desc[ring->cur] = htole32(paddr);
|
ring->desc[ring->cur] = htole32(paddr);
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active(ic)) {
|
||||||
struct wpi_rx_radiotap_header *tap = &sc->sc_rxtap;
|
struct wpi_rx_radiotap_header *tap = &sc->sc_rxtap;
|
||||||
|
|
||||||
tap->wr_flags = 0;
|
tap->wr_flags = 0;
|
||||||
@ -1551,18 +1545,16 @@ wpi_rx_intr(struct wpi_softc *sc, struct wpi_rx_desc *desc,
|
|||||||
}
|
}
|
||||||
if (le16toh(head->flags) & 0x4)
|
if (le16toh(head->flags) & 0x4)
|
||||||
tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
|
tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WPI_UNLOCK(sc);
|
WPI_UNLOCK(sc);
|
||||||
|
|
||||||
ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
|
ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
|
||||||
if (ni != NULL) {
|
if (ni != NULL) {
|
||||||
(void) ieee80211_input(ni, m, stat->rssi, 0, 0);
|
(void) ieee80211_input(ni, m, stat->rssi, 0);
|
||||||
ieee80211_free_node(ni);
|
ieee80211_free_node(ni);
|
||||||
} else
|
} else
|
||||||
(void) ieee80211_input_all(ic, m, stat->rssi, 0, 0);
|
(void) ieee80211_input_all(ic, m, stat->rssi, 0);
|
||||||
|
|
||||||
WPI_LOCK(sc);
|
WPI_LOCK(sc);
|
||||||
}
|
}
|
||||||
@ -1938,17 +1930,15 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
|
|||||||
tx->data_ntries = 15; /* XXX way too high */
|
tx->data_ntries = 15; /* XXX way too high */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (bpf_peers_present(ifp->if_bpf)) {
|
if (ieee80211_radiotap_active_vap(vap)) {
|
||||||
struct wpi_tx_radiotap_header *tap = &sc->sc_txtap;
|
struct wpi_tx_radiotap_header *tap = &sc->sc_txtap;
|
||||||
tap->wt_flags = 0;
|
tap->wt_flags = 0;
|
||||||
tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq);
|
|
||||||
tap->wt_chan_flags = htole16(ni->ni_chan->ic_flags);
|
|
||||||
tap->wt_rate = rate;
|
tap->wt_rate = rate;
|
||||||
tap->wt_hwqueue = ac;
|
tap->wt_hwqueue = ac;
|
||||||
if (wh->i_fc[1] & IEEE80211_FC1_WEP)
|
if (wh->i_fc[1] & IEEE80211_FC1_WEP)
|
||||||
tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
|
tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
|
||||||
|
|
||||||
bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
|
ieee80211_radiotap_tx(vap, m0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* save and trim IEEE802.11 header */
|
/* save and trim IEEE802.11 header */
|
||||||
|
@ -182,9 +182,7 @@ struct wpi_softc {
|
|||||||
struct bpf_if *sc_drvbpf;
|
struct bpf_if *sc_drvbpf;
|
||||||
|
|
||||||
struct wpi_rx_radiotap_header sc_rxtap;
|
struct wpi_rx_radiotap_header sc_rxtap;
|
||||||
int sc_rxtap_len;
|
|
||||||
struct wpi_tx_radiotap_header sc_txtap;
|
struct wpi_tx_radiotap_header sc_txtap;
|
||||||
int sc_txtap_len;
|
|
||||||
|
|
||||||
/* firmware image */
|
/* firmware image */
|
||||||
const struct firmware *fw_fp;
|
const struct firmware *fw_fp;
|
||||||
|
@ -465,6 +465,7 @@ ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap,
|
|||||||
ieee80211_ht_vattach(vap);
|
ieee80211_ht_vattach(vap);
|
||||||
ieee80211_scan_vattach(vap);
|
ieee80211_scan_vattach(vap);
|
||||||
ieee80211_regdomain_vattach(vap);
|
ieee80211_regdomain_vattach(vap);
|
||||||
|
ieee80211_radiotap_vattach(vap);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -509,10 +510,11 @@ ieee80211_vap_attach(struct ieee80211vap *vap,
|
|||||||
vap->iv_output = ifp->if_output;
|
vap->iv_output = ifp->if_output;
|
||||||
ifp->if_output = ieee80211_output;
|
ifp->if_output = ieee80211_output;
|
||||||
/* NB: if_mtu set by ether_ifattach to ETHERMTU */
|
/* NB: if_mtu set by ether_ifattach to ETHERMTU */
|
||||||
bpfattach2(ifp, DLT_IEEE802_11, ifp->if_hdrlen, &vap->iv_rawbpf);
|
|
||||||
|
|
||||||
IEEE80211_LOCK(ic);
|
IEEE80211_LOCK(ic);
|
||||||
TAILQ_INSERT_TAIL(&ic->ic_vaps, vap, iv_next);
|
TAILQ_INSERT_TAIL(&ic->ic_vaps, vap, iv_next);
|
||||||
|
if (vap->iv_opmode == IEEE80211_M_MONITOR)
|
||||||
|
ic->ic_monvaps++;
|
||||||
ieee80211_syncflag_locked(ic, IEEE80211_F_WME);
|
ieee80211_syncflag_locked(ic, IEEE80211_F_WME);
|
||||||
#ifdef IEEE80211_SUPPORT_SUPERG
|
#ifdef IEEE80211_SUPPORT_SUPERG
|
||||||
ieee80211_syncflag_locked(ic, IEEE80211_F_TURBOP);
|
ieee80211_syncflag_locked(ic, IEEE80211_F_TURBOP);
|
||||||
@ -573,6 +575,8 @@ ieee80211_vap_detach(struct ieee80211vap *vap)
|
|||||||
IEEE80211_LOCK(ic);
|
IEEE80211_LOCK(ic);
|
||||||
KASSERT(vap->iv_state == IEEE80211_S_INIT , ("vap still running"));
|
KASSERT(vap->iv_state == IEEE80211_S_INIT , ("vap still running"));
|
||||||
TAILQ_REMOVE(&ic->ic_vaps, vap, iv_next);
|
TAILQ_REMOVE(&ic->ic_vaps, vap, iv_next);
|
||||||
|
if (vap->iv_opmode == IEEE80211_M_MONITOR)
|
||||||
|
ic->ic_monvaps--;
|
||||||
ieee80211_syncflag_locked(ic, IEEE80211_F_WME);
|
ieee80211_syncflag_locked(ic, IEEE80211_F_WME);
|
||||||
#ifdef IEEE80211_SUPPORT_SUPERG
|
#ifdef IEEE80211_SUPPORT_SUPERG
|
||||||
ieee80211_syncflag_locked(ic, IEEE80211_F_TURBOP);
|
ieee80211_syncflag_locked(ic, IEEE80211_F_TURBOP);
|
||||||
@ -581,16 +585,19 @@ ieee80211_vap_detach(struct ieee80211vap *vap)
|
|||||||
ieee80211_syncflag_locked(ic, IEEE80211_F_BURST);
|
ieee80211_syncflag_locked(ic, IEEE80211_F_BURST);
|
||||||
ieee80211_syncflag_ext_locked(ic, IEEE80211_FEXT_HT);
|
ieee80211_syncflag_ext_locked(ic, IEEE80211_FEXT_HT);
|
||||||
ieee80211_syncflag_ext_locked(ic, IEEE80211_FEXT_USEHT40);
|
ieee80211_syncflag_ext_locked(ic, IEEE80211_FEXT_USEHT40);
|
||||||
|
/* NB: this handles the bpfdetach done below */
|
||||||
|
ieee80211_syncflag_ext_locked(ic, IEEE80211_FEXT_BPF);
|
||||||
ieee80211_syncifflag_locked(ic, IFF_PROMISC);
|
ieee80211_syncifflag_locked(ic, IFF_PROMISC);
|
||||||
ieee80211_syncifflag_locked(ic, IFF_ALLMULTI);
|
ieee80211_syncifflag_locked(ic, IFF_ALLMULTI);
|
||||||
IEEE80211_UNLOCK(ic);
|
IEEE80211_UNLOCK(ic);
|
||||||
|
|
||||||
/* XXX can't hold com lock */
|
/* XXX can't hold com lock */
|
||||||
/* NB: bpfattach is called by ether_ifdetach and claims all taps */
|
/* NB: bpfdetach is called by ether_ifdetach and claims all taps */
|
||||||
ether_ifdetach(ifp);
|
ether_ifdetach(ifp);
|
||||||
|
|
||||||
ifmedia_removeall(&vap->iv_media);
|
ifmedia_removeall(&vap->iv_media);
|
||||||
|
|
||||||
|
ieee80211_radiotap_vdetach(vap);
|
||||||
ieee80211_regdomain_vdetach(vap);
|
ieee80211_regdomain_vdetach(vap);
|
||||||
ieee80211_scan_vdetach(vap);
|
ieee80211_scan_vdetach(vap);
|
||||||
#ifdef IEEE80211_SUPPORT_SUPERG
|
#ifdef IEEE80211_SUPPORT_SUPERG
|
||||||
|
@ -68,12 +68,11 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
static void adhoc_vattach(struct ieee80211vap *);
|
static void adhoc_vattach(struct ieee80211vap *);
|
||||||
static int adhoc_newstate(struct ieee80211vap *, enum ieee80211_state, int);
|
static int adhoc_newstate(struct ieee80211vap *, enum ieee80211_state, int);
|
||||||
static int adhoc_input(struct ieee80211_node *, struct mbuf *,
|
static int adhoc_input(struct ieee80211_node *, struct mbuf *, int, int);
|
||||||
int rssi, int noise, uint32_t rstamp);
|
|
||||||
static void adhoc_recv_mgmt(struct ieee80211_node *, struct mbuf *,
|
static void adhoc_recv_mgmt(struct ieee80211_node *, struct mbuf *,
|
||||||
int subtype, int rssi, int noise, uint32_t rstamp);
|
int subtype, int, int);
|
||||||
static void ahdemo_recv_mgmt(struct ieee80211_node *, struct mbuf *,
|
static void ahdemo_recv_mgmt(struct ieee80211_node *, struct mbuf *,
|
||||||
int subtype, int rssi, int noise, uint32_t rstamp);
|
int subtype, int, int);
|
||||||
static void adhoc_recv_ctl(struct ieee80211_node *, struct mbuf *, int subtype);
|
static void adhoc_recv_ctl(struct ieee80211_node *, struct mbuf *, int subtype);
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -284,8 +283,7 @@ doprint(struct ieee80211vap *vap, int subtype)
|
|||||||
* by the 802.11 layer.
|
* by the 802.11 layer.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
adhoc_input(struct ieee80211_node *ni, struct mbuf *m,
|
adhoc_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
|
||||||
int rssi, int noise, uint32_t rstamp)
|
|
||||||
{
|
{
|
||||||
#define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0)
|
#define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0)
|
||||||
#define HAS_SEQ(type) ((type & 0x4) == 0)
|
#define HAS_SEQ(type) ((type & 0x4) == 0)
|
||||||
@ -408,8 +406,7 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
|
IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
|
||||||
ni->ni_noise = noise;
|
ni->ni_noise = nf;
|
||||||
ni->ni_rstamp = rstamp;
|
|
||||||
if (HAS_SEQ(type)) {
|
if (HAS_SEQ(type)) {
|
||||||
uint8_t tid = ieee80211_gettid(wh);
|
uint8_t tid = ieee80211_gettid(wh);
|
||||||
if (IEEE80211_QOS_HAS_SEQ(wh) &&
|
if (IEEE80211_QOS_HAS_SEQ(wh) &&
|
||||||
@ -536,8 +533,8 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* copy to listener after decrypt */
|
/* copy to listener after decrypt */
|
||||||
if (bpf_peers_present(vap->iv_rawbpf))
|
if (ieee80211_radiotap_active_vap(vap))
|
||||||
bpf_mtap(vap->iv_rawbpf, m);
|
ieee80211_radiotap_rx(vap, m);
|
||||||
need_tap = 0;
|
need_tap = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -640,7 +637,7 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m,
|
|||||||
vap->iv_stats.is_rx_mgtdiscard++; /* XXX */
|
vap->iv_stats.is_rx_mgtdiscard++; /* XXX */
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
vap->iv_recv_mgmt(ni, m, subtype, rssi, noise, rstamp);
|
vap->iv_recv_mgmt(ni, m, subtype, rssi, nf);
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
case IEEE80211_FC0_TYPE_CTL:
|
case IEEE80211_FC0_TYPE_CTL:
|
||||||
@ -659,8 +656,8 @@ err:
|
|||||||
ifp->if_ierrors++;
|
ifp->if_ierrors++;
|
||||||
out:
|
out:
|
||||||
if (m != NULL) {
|
if (m != NULL) {
|
||||||
if (need_tap && bpf_peers_present(vap->iv_rawbpf))
|
if (need_tap)
|
||||||
bpf_mtap(vap->iv_rawbpf, m);
|
ieee80211_radiotap_rx(vap, m);
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
}
|
}
|
||||||
return type;
|
return type;
|
||||||
@ -686,7 +683,7 @@ is11bclient(const uint8_t *rates, const uint8_t *xrates)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
|
adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
|
||||||
int subtype, int rssi, int noise, uint32_t rstamp)
|
int subtype, int rssi, int nf)
|
||||||
{
|
{
|
||||||
struct ieee80211vap *vap = ni->ni_vap;
|
struct ieee80211vap *vap = ni->ni_vap;
|
||||||
struct ieee80211com *ic = ni->ni_ic;
|
struct ieee80211com *ic = ni->ni_ic;
|
||||||
@ -731,8 +728,7 @@ adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
|
|||||||
ieee80211_probe_curchan(vap, 1);
|
ieee80211_probe_curchan(vap, 1);
|
||||||
ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN;
|
ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN;
|
||||||
}
|
}
|
||||||
ieee80211_add_scan(vap, &scan, wh,
|
ieee80211_add_scan(vap, &scan, wh, subtype, rssi, nf);
|
||||||
subtype, rssi, noise, rstamp);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (scan.capinfo & IEEE80211_CAPINFO_IBSS) {
|
if (scan.capinfo & IEEE80211_CAPINFO_IBSS) {
|
||||||
@ -756,8 +752,7 @@ adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
|
|||||||
}
|
}
|
||||||
if (ni != NULL) {
|
if (ni != NULL) {
|
||||||
IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
|
IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
|
||||||
ni->ni_noise = noise;
|
ni->ni_noise = nf;
|
||||||
ni->ni_rstamp = rstamp;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -912,7 +907,7 @@ adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
ahdemo_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
|
ahdemo_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
|
||||||
int subtype, int rssi, int noise, uint32_t rstamp)
|
int subtype, int rssi, int nf)
|
||||||
{
|
{
|
||||||
struct ieee80211vap *vap = ni->ni_vap;
|
struct ieee80211vap *vap = ni->ni_vap;
|
||||||
struct ieee80211com *ic = ni->ni_ic;
|
struct ieee80211com *ic = ni->ni_ic;
|
||||||
@ -922,7 +917,7 @@ ahdemo_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
|
|||||||
* a site-survey.
|
* a site-survey.
|
||||||
*/
|
*/
|
||||||
if (ic->ic_flags & IEEE80211_F_SCAN)
|
if (ic->ic_flags & IEEE80211_F_SCAN)
|
||||||
adhoc_recv_mgmt(ni, m0, subtype, rssi, noise, rstamp);
|
adhoc_recv_mgmt(ni, m0, subtype, rssi, nf);
|
||||||
else
|
else
|
||||||
vap->iv_stats.is_rx_mgtdiscard++;
|
vap->iv_stats.is_rx_mgtdiscard++;
|
||||||
}
|
}
|
||||||
|
@ -255,9 +255,9 @@ _db_show_sta(const struct ieee80211_node *ni)
|
|||||||
db_printf("\trxfrag[0] %p rxfrag[1] %p rxfrag[2] %p\n",
|
db_printf("\trxfrag[0] %p rxfrag[1] %p rxfrag[2] %p\n",
|
||||||
ni->ni_rxfrag[0], ni->ni_rxfrag[1], ni->ni_rxfrag[2]);
|
ni->ni_rxfrag[0], ni->ni_rxfrag[1], ni->ni_rxfrag[2]);
|
||||||
_db_show_key("\tucastkey", 0, &ni->ni_ucastkey);
|
_db_show_key("\tucastkey", 0, &ni->ni_ucastkey);
|
||||||
db_printf("\trstamp %u avgrssi 0x%x (rssi %d) noise %d\n",
|
db_printf("\tavgrssi 0x%x (rssi %d) noise %d\n",
|
||||||
ni->ni_rstamp, ni->ni_avgrssi,
|
ni->ni_avgrssi, IEEE80211_RSSI_GET(ni->ni_avgrssi),
|
||||||
IEEE80211_RSSI_GET(ni->ni_avgrssi), ni->ni_noise);
|
ni->ni_noise);
|
||||||
db_printf("\tintval %u capinfo %b\n",
|
db_printf("\tintval %u capinfo %b\n",
|
||||||
ni->ni_intval, ni->ni_capinfo, IEEE80211_CAPINFO_BITS);
|
ni->ni_intval, ni->ni_capinfo, IEEE80211_CAPINFO_BITS);
|
||||||
db_printf("\tbssid %s", ether_sprintf(ni->ni_bssid));
|
db_printf("\tbssid %s", ether_sprintf(ni->ni_bssid));
|
||||||
|
@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/vimage.h>
|
#include <sys/vimage.h>
|
||||||
|
|
||||||
|
#include <net/bpf.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <net/if_dl.h>
|
#include <net/if_dl.h>
|
||||||
#include <net/if_clone.h>
|
#include <net/if_clone.h>
|
||||||
@ -726,6 +727,29 @@ ieee80211_load_module(const char *modname)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static eventhandler_tag wlan_bpfevent;
|
||||||
|
|
||||||
|
static void
|
||||||
|
bpf_track(void *arg, struct ifnet *ifp, int attach)
|
||||||
|
{
|
||||||
|
/* NB: identify vap's by if_start */
|
||||||
|
if (ifp->if_start == ieee80211_start) {
|
||||||
|
struct ieee80211vap *vap = ifp->if_softc;
|
||||||
|
/*
|
||||||
|
* Track bpf radiotap listener state. We mark the vap
|
||||||
|
* to indicate if any listener is present and the com
|
||||||
|
* to indicate if any listener exists on any associated
|
||||||
|
* vap. This flag is used by drivers to prepare radiotap
|
||||||
|
* state only when needed.
|
||||||
|
*/
|
||||||
|
if (attach)
|
||||||
|
ieee80211_syncflag_ext(vap, IEEE80211_FEXT_BPF);
|
||||||
|
/* NB: if_softc is NULL on vap detach */
|
||||||
|
else if (vap != NULL && !bpf_peers_present(vap->iv_rawbpf))
|
||||||
|
ieee80211_syncflag_ext(vap, -IEEE80211_FEXT_BPF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Module glue.
|
* Module glue.
|
||||||
*
|
*
|
||||||
@ -738,12 +762,17 @@ wlan_modevent(module_t mod, int type, void *unused)
|
|||||||
case MOD_LOAD:
|
case MOD_LOAD:
|
||||||
if (bootverbose)
|
if (bootverbose)
|
||||||
printf("wlan: <802.11 Link Layer>\n");
|
printf("wlan: <802.11 Link Layer>\n");
|
||||||
|
wlan_bpfevent = EVENTHANDLER_REGISTER(bpf_track,
|
||||||
|
bpf_track, 0, EVENTHANDLER_PRI_ANY);
|
||||||
|
if (wlan_bpfevent == NULL)
|
||||||
|
return ENOMEM;
|
||||||
if_clone_attach(&wlan_cloner);
|
if_clone_attach(&wlan_cloner);
|
||||||
if_register_com_alloc(IFT_IEEE80211, wlan_alloc, wlan_free);
|
if_register_com_alloc(IFT_IEEE80211, wlan_alloc, wlan_free);
|
||||||
return 0;
|
return 0;
|
||||||
case MOD_UNLOAD:
|
case MOD_UNLOAD:
|
||||||
if_deregister_com_alloc(IFT_IEEE80211);
|
if_deregister_com_alloc(IFT_IEEE80211);
|
||||||
if_clone_detach(&wlan_cloner);
|
if_clone_detach(&wlan_cloner);
|
||||||
|
EVENTHANDLER_DEREGISTER(bpf_track, wlan_bpfevent);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
@ -67,11 +67,11 @@ __FBSDID("$FreeBSD$");
|
|||||||
static void hostap_vattach(struct ieee80211vap *);
|
static void hostap_vattach(struct ieee80211vap *);
|
||||||
static int hostap_newstate(struct ieee80211vap *, enum ieee80211_state, int);
|
static int hostap_newstate(struct ieee80211vap *, enum ieee80211_state, int);
|
||||||
static int hostap_input(struct ieee80211_node *ni, struct mbuf *m,
|
static int hostap_input(struct ieee80211_node *ni, struct mbuf *m,
|
||||||
int rssi, int noise, uint32_t rstamp);
|
int rssi, int nf);
|
||||||
static void hostap_deliver_data(struct ieee80211vap *,
|
static void hostap_deliver_data(struct ieee80211vap *,
|
||||||
struct ieee80211_node *, struct mbuf *);
|
struct ieee80211_node *, struct mbuf *);
|
||||||
static void hostap_recv_mgmt(struct ieee80211_node *, struct mbuf *,
|
static void hostap_recv_mgmt(struct ieee80211_node *, struct mbuf *,
|
||||||
int subtype, int rssi, int noise, uint32_t rstamp);
|
int subtype, int rssi, int nf);
|
||||||
static void hostap_recv_ctl(struct ieee80211_node *, struct mbuf *, int);
|
static void hostap_recv_ctl(struct ieee80211_node *, struct mbuf *, int);
|
||||||
static void hostap_recv_pspoll(struct ieee80211_node *, struct mbuf *);
|
static void hostap_recv_pspoll(struct ieee80211_node *, struct mbuf *);
|
||||||
|
|
||||||
@ -418,8 +418,7 @@ doprint(struct ieee80211vap *vap, int subtype)
|
|||||||
* by the 802.11 layer.
|
* by the 802.11 layer.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
hostap_input(struct ieee80211_node *ni, struct mbuf *m,
|
hostap_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
|
||||||
int rssi, int noise, uint32_t rstamp)
|
|
||||||
{
|
{
|
||||||
#define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0)
|
#define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0)
|
||||||
#define HAS_SEQ(type) ((type & 0x4) == 0)
|
#define HAS_SEQ(type) ((type & 0x4) == 0)
|
||||||
@ -515,8 +514,7 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m,
|
|||||||
}
|
}
|
||||||
|
|
||||||
IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
|
IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
|
||||||
ni->ni_noise = noise;
|
ni->ni_noise = nf;
|
||||||
ni->ni_rstamp = rstamp;
|
|
||||||
if (HAS_SEQ(type)) {
|
if (HAS_SEQ(type)) {
|
||||||
uint8_t tid = ieee80211_gettid(wh);
|
uint8_t tid = ieee80211_gettid(wh);
|
||||||
if (IEEE80211_QOS_HAS_SEQ(wh) &&
|
if (IEEE80211_QOS_HAS_SEQ(wh) &&
|
||||||
@ -699,8 +697,8 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
/* copy to listener after decrypt */
|
/* copy to listener after decrypt */
|
||||||
if (bpf_peers_present(vap->iv_rawbpf))
|
if (ieee80211_radiotap_active_vap(vap))
|
||||||
bpf_mtap(vap->iv_rawbpf, m);
|
ieee80211_radiotap_rx(vap, m);
|
||||||
need_tap = 0;
|
need_tap = 0;
|
||||||
/*
|
/*
|
||||||
* Finally, strip the 802.11 header.
|
* Finally, strip the 802.11 header.
|
||||||
@ -834,7 +832,7 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m,
|
|||||||
wh = mtod(m, struct ieee80211_frame *);
|
wh = mtod(m, struct ieee80211_frame *);
|
||||||
wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
|
wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
|
||||||
}
|
}
|
||||||
vap->iv_recv_mgmt(ni, m, subtype, rssi, noise, rstamp);
|
vap->iv_recv_mgmt(ni, m, subtype, rssi, nf);
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
case IEEE80211_FC0_TYPE_CTL:
|
case IEEE80211_FC0_TYPE_CTL:
|
||||||
@ -852,8 +850,8 @@ err:
|
|||||||
ifp->if_ierrors++;
|
ifp->if_ierrors++;
|
||||||
out:
|
out:
|
||||||
if (m != NULL) {
|
if (m != NULL) {
|
||||||
if (need_tap && bpf_peers_present(vap->iv_rawbpf))
|
if (need_tap)
|
||||||
bpf_mtap(vap->iv_rawbpf, m);
|
ieee80211_radiotap_rx(vap, m);
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
}
|
}
|
||||||
return type;
|
return type;
|
||||||
@ -862,7 +860,7 @@ out:
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
hostap_auth_open(struct ieee80211_node *ni, struct ieee80211_frame *wh,
|
hostap_auth_open(struct ieee80211_node *ni, struct ieee80211_frame *wh,
|
||||||
int rssi, int noise, uint32_t rstamp, uint16_t seq, uint16_t status)
|
int rssi, int nf, uint16_t seq, uint16_t status)
|
||||||
{
|
{
|
||||||
struct ieee80211vap *vap = ni->ni_vap;
|
struct ieee80211vap *vap = ni->ni_vap;
|
||||||
|
|
||||||
@ -940,7 +938,7 @@ hostap_auth_open(struct ieee80211_node *ni, struct ieee80211_frame *wh,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
hostap_auth_shared(struct ieee80211_node *ni, struct ieee80211_frame *wh,
|
hostap_auth_shared(struct ieee80211_node *ni, struct ieee80211_frame *wh,
|
||||||
uint8_t *frm, uint8_t *efrm, int rssi, int noise, uint32_t rstamp,
|
uint8_t *frm, uint8_t *efrm, int rssi, int nf,
|
||||||
uint16_t seq, uint16_t status)
|
uint16_t seq, uint16_t status)
|
||||||
{
|
{
|
||||||
struct ieee80211vap *vap = ni->ni_vap;
|
struct ieee80211vap *vap = ni->ni_vap;
|
||||||
@ -1042,8 +1040,7 @@ hostap_auth_shared(struct ieee80211_node *ni, struct ieee80211_frame *wh,
|
|||||||
*/
|
*/
|
||||||
ni->ni_flags |= IEEE80211_NODE_ASSOCID;
|
ni->ni_flags |= IEEE80211_NODE_ASSOCID;
|
||||||
IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
|
IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
|
||||||
ni->ni_noise = noise;
|
ni->ni_noise = nf;
|
||||||
ni->ni_rstamp = rstamp;
|
|
||||||
if (!ieee80211_alloc_challenge(ni)) {
|
if (!ieee80211_alloc_challenge(ni)) {
|
||||||
/* NB: don't return error so they rexmit */
|
/* NB: don't return error so they rexmit */
|
||||||
return;
|
return;
|
||||||
@ -1624,7 +1621,7 @@ is11bclient(const uint8_t *rates, const uint8_t *xrates)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
|
hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
|
||||||
int subtype, int rssi, int noise, uint32_t rstamp)
|
int subtype, int rssi, int nf)
|
||||||
{
|
{
|
||||||
struct ieee80211vap *vap = ni->ni_vap;
|
struct ieee80211vap *vap = ni->ni_vap;
|
||||||
struct ieee80211com *ic = ni->ni_ic;
|
struct ieee80211com *ic = ni->ni_ic;
|
||||||
@ -1679,8 +1676,7 @@ hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
|
|||||||
ieee80211_probe_curchan(vap, 1);
|
ieee80211_probe_curchan(vap, 1);
|
||||||
ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN;
|
ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN;
|
||||||
}
|
}
|
||||||
ieee80211_add_scan(vap, &scan, wh,
|
ieee80211_add_scan(vap, &scan, wh, subtype, rssi, nf);
|
||||||
subtype, rssi, noise, rstamp);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -1843,11 +1839,10 @@ hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (algo == IEEE80211_AUTH_ALG_SHARED)
|
if (algo == IEEE80211_AUTH_ALG_SHARED)
|
||||||
hostap_auth_shared(ni, wh, frm + 6, efrm, rssi,
|
hostap_auth_shared(ni, wh, frm + 6, efrm, rssi, nf,
|
||||||
noise, rstamp, seq, status);
|
|
||||||
else if (algo == IEEE80211_AUTH_ALG_OPEN)
|
|
||||||
hostap_auth_open(ni, wh, rssi, noise, rstamp,
|
|
||||||
seq, status);
|
seq, status);
|
||||||
|
else if (algo == IEEE80211_AUTH_ALG_OPEN)
|
||||||
|
hostap_auth_open(ni, wh, rssi, nf, seq, status);
|
||||||
else if (algo == IEEE80211_AUTH_ALG_LEAP) {
|
else if (algo == IEEE80211_AUTH_ALG_LEAP) {
|
||||||
authalgreject(ni, wh, algo,
|
authalgreject(ni, wh, algo,
|
||||||
seq+1, IEEE80211_STATUS_ALG);
|
seq+1, IEEE80211_STATUS_ALG);
|
||||||
@ -2063,8 +2058,7 @@ hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
|
IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
|
||||||
ni->ni_noise = noise;
|
ni->ni_noise = nf;
|
||||||
ni->ni_rstamp = rstamp;
|
|
||||||
ni->ni_intval = lintval;
|
ni->ni_intval = lintval;
|
||||||
ni->ni_capinfo = capinfo;
|
ni->ni_capinfo = capinfo;
|
||||||
ni->ni_fhdwell = vap->iv_bss->ni_fhdwell;
|
ni->ni_fhdwell = vap->iv_bss->ni_fhdwell;
|
||||||
|
@ -364,8 +364,8 @@ static __inline void
|
|||||||
ampdu_dispatch(struct ieee80211_node *ni, struct mbuf *m)
|
ampdu_dispatch(struct ieee80211_node *ni, struct mbuf *m)
|
||||||
{
|
{
|
||||||
m->m_flags |= M_AMPDU_MPDU; /* bypass normal processing */
|
m->m_flags |= M_AMPDU_MPDU; /* bypass normal processing */
|
||||||
/* NB: rssi, noise, and rstamp are ignored w/ M_AMPDU_MPDU set */
|
/* NB: rssi and noise are ignored w/ M_AMPDU_MPDU set */
|
||||||
(void) ieee80211_input(ni, m, 0, 0, 0);
|
(void) ieee80211_input(ni, m, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -55,8 +55,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
ieee80211_input_all(struct ieee80211com *ic,
|
ieee80211_input_all(struct ieee80211com *ic, struct mbuf *m, int rssi, int nf)
|
||||||
struct mbuf *m, int rssi, int noise, u_int32_t rstamp)
|
|
||||||
{
|
{
|
||||||
struct ieee80211vap *vap;
|
struct ieee80211vap *vap;
|
||||||
int type = -1;
|
int type = -1;
|
||||||
@ -89,7 +88,7 @@ ieee80211_input_all(struct ieee80211com *ic,
|
|||||||
m = NULL;
|
m = NULL;
|
||||||
}
|
}
|
||||||
ni = ieee80211_ref_node(vap->iv_bss);
|
ni = ieee80211_ref_node(vap->iv_bss);
|
||||||
type = ieee80211_input(ni, mcopy, rssi, noise, rstamp);
|
type = ieee80211_input(ni, mcopy, rssi, nf);
|
||||||
ieee80211_free_node(ni);
|
ieee80211_free_node(ni);
|
||||||
}
|
}
|
||||||
if (m != NULL) /* no vaps, reclaim mbuf */
|
if (m != NULL) /* no vaps, reclaim mbuf */
|
||||||
|
@ -60,7 +60,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
static void monitor_vattach(struct ieee80211vap *);
|
static void monitor_vattach(struct ieee80211vap *);
|
||||||
static int monitor_newstate(struct ieee80211vap *, enum ieee80211_state, int);
|
static int monitor_newstate(struct ieee80211vap *, enum ieee80211_state, int);
|
||||||
static int monitor_input(struct ieee80211_node *ni, struct mbuf *m,
|
static int monitor_input(struct ieee80211_node *ni, struct mbuf *m,
|
||||||
int rssi, int noise, uint32_t rstamp);
|
int rssi, int nf);
|
||||||
|
|
||||||
void
|
void
|
||||||
ieee80211_monitor_attach(struct ieee80211com *ic)
|
ieee80211_monitor_attach(struct ieee80211com *ic)
|
||||||
@ -124,13 +124,11 @@ monitor_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
|
|||||||
* Process a received frame in monitor mode.
|
* Process a received frame in monitor mode.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
monitor_input(struct ieee80211_node *ni, struct mbuf *m,
|
monitor_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
|
||||||
int rssi, int noise, uint32_t rstamp)
|
|
||||||
{
|
{
|
||||||
struct ieee80211vap *vap = ni->ni_vap;
|
struct ieee80211vap *vap = ni->ni_vap;
|
||||||
|
|
||||||
if (bpf_peers_present(vap->iv_rawbpf))
|
ieee80211_radiotap_rx(vap, m);
|
||||||
bpf_mtap(vap->iv_rawbpf, m);
|
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -631,6 +631,7 @@ ieee80211_sync_curchan(struct ieee80211com *ic)
|
|||||||
ic->ic_rt = ieee80211_get_ratetable(ic->ic_curchan);
|
ic->ic_rt = ieee80211_get_ratetable(ic->ic_curchan);
|
||||||
IEEE80211_UNLOCK(ic);
|
IEEE80211_UNLOCK(ic);
|
||||||
ic->ic_set_channel(ic);
|
ic->ic_set_channel(ic);
|
||||||
|
ieee80211_radiotap_chan_change(ic);
|
||||||
IEEE80211_LOCK(ic);
|
IEEE80211_LOCK(ic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -754,7 +755,6 @@ ieee80211_sta_join(struct ieee80211vap *vap, struct ieee80211_channel *chan,
|
|||||||
IEEE80211_ADDR_COPY(ni->ni_bssid, se->se_bssid);
|
IEEE80211_ADDR_COPY(ni->ni_bssid, se->se_bssid);
|
||||||
ni->ni_esslen = se->se_ssid[1];
|
ni->ni_esslen = se->se_ssid[1];
|
||||||
memcpy(ni->ni_essid, se->se_ssid+2, ni->ni_esslen);
|
memcpy(ni->ni_essid, se->se_ssid+2, ni->ni_esslen);
|
||||||
ni->ni_rstamp = se->se_rstamp;
|
|
||||||
ni->ni_tstamp.tsf = se->se_tstamp.tsf;
|
ni->ni_tstamp.tsf = se->se_tstamp.tsf;
|
||||||
ni->ni_intval = se->se_intval;
|
ni->ni_intval = se->se_intval;
|
||||||
ni->ni_capinfo = se->se_capinfo;
|
ni->ni_capinfo = se->se_capinfo;
|
||||||
@ -2125,8 +2125,8 @@ ieee80211_dump_node(struct ieee80211_node_table *nt, struct ieee80211_node *ni)
|
|||||||
ni->ni_rxseqs[IEEE80211_NONQOS_TID] >> IEEE80211_SEQ_SEQ_SHIFT,
|
ni->ni_rxseqs[IEEE80211_NONQOS_TID] >> IEEE80211_SEQ_SEQ_SHIFT,
|
||||||
ni->ni_rxseqs[IEEE80211_NONQOS_TID] & IEEE80211_SEQ_FRAG_MASK,
|
ni->ni_rxseqs[IEEE80211_NONQOS_TID] & IEEE80211_SEQ_FRAG_MASK,
|
||||||
ni->ni_rxfragstamp);
|
ni->ni_rxfragstamp);
|
||||||
printf("\trstamp %u rssi %d noise %d intval %u capinfo 0x%x\n",
|
printf("\trssi %d noise %d intval %u capinfo 0x%x\n",
|
||||||
ni->ni_rstamp, node_getrssi(ni), ni->ni_noise,
|
node_getrssi(ni), ni->ni_noise,
|
||||||
ni->ni_intval, ni->ni_capinfo);
|
ni->ni_intval, ni->ni_capinfo);
|
||||||
printf("\tbssid %s essid \"%.*s\" channel %u:0x%x\n",
|
printf("\tbssid %s essid \"%.*s\" channel %u:0x%x\n",
|
||||||
ether_sprintf(ni->ni_bssid),
|
ether_sprintf(ni->ni_bssid),
|
||||||
|
@ -145,7 +145,6 @@ struct ieee80211_node {
|
|||||||
struct ieee80211_key ni_ucastkey; /* unicast key */
|
struct ieee80211_key ni_ucastkey; /* unicast key */
|
||||||
|
|
||||||
/* hardware */
|
/* hardware */
|
||||||
uint32_t ni_rstamp; /* recv timestamp */
|
|
||||||
uint32_t ni_avgrssi; /* recv ssi state */
|
uint32_t ni_avgrssi; /* recv ssi state */
|
||||||
int8_t ni_noise; /* noise floor */
|
int8_t ni_noise; /* noise floor */
|
||||||
|
|
||||||
|
@ -307,10 +307,6 @@ ieee80211_start(struct ifnet *ifp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX fragmented frames not handled */
|
|
||||||
if (bpf_peers_present(vap->iv_rawbpf))
|
|
||||||
bpf_mtap(vap->iv_rawbpf, m);
|
|
||||||
|
|
||||||
error = parent->if_transmit(parent, m);
|
error = parent->if_transmit(parent, m);
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
/* NB: IFQ_HANDOFF reclaims mbuf */
|
/* NB: IFQ_HANDOFF reclaims mbuf */
|
||||||
@ -420,9 +416,6 @@ ieee80211_output(struct ifnet *ifp, struct mbuf *m,
|
|||||||
if (ieee80211_classify(ni, m))
|
if (ieee80211_classify(ni, m))
|
||||||
senderr(EIO); /* XXX */
|
senderr(EIO); /* XXX */
|
||||||
|
|
||||||
if (bpf_peers_present(vap->iv_rawbpf))
|
|
||||||
bpf_mtap(vap->iv_rawbpf, m);
|
|
||||||
|
|
||||||
IEEE80211_NODE_STAT(ni, tx_data);
|
IEEE80211_NODE_STAT(ni, tx_data);
|
||||||
if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
|
if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
|
||||||
IEEE80211_NODE_STAT(ni, tx_mcast);
|
IEEE80211_NODE_STAT(ni, tx_mcast);
|
||||||
|
@ -1107,6 +1107,7 @@ update_channel(void *arg, int npending)
|
|||||||
struct ieee80211com *ic = arg;
|
struct ieee80211com *ic = arg;
|
||||||
|
|
||||||
ic->ic_set_channel(ic);
|
ic->ic_set_channel(ic);
|
||||||
|
ieee80211_radiotap_chan_change(ic);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -60,10 +60,9 @@ void ieee80211_syncifflag_locked(struct ieee80211com *, int flag);
|
|||||||
void ieee80211_syncflag(struct ieee80211vap *, int flag);
|
void ieee80211_syncflag(struct ieee80211vap *, int flag);
|
||||||
void ieee80211_syncflag_ext(struct ieee80211vap *, int flag);
|
void ieee80211_syncflag_ext(struct ieee80211vap *, int flag);
|
||||||
|
|
||||||
#define ieee80211_input(ni, m, rssi, noise, rstamp) \
|
#define ieee80211_input(ni, m, rssi, nf) \
|
||||||
((ni)->ni_vap->iv_input(ni, m, rssi, noise, rstamp))
|
((ni)->ni_vap->iv_input(ni, m, rssi, nf))
|
||||||
int ieee80211_input_all(struct ieee80211com *, struct mbuf *,
|
int ieee80211_input_all(struct ieee80211com *, struct mbuf *, int, int);
|
||||||
int, int, uint32_t);
|
|
||||||
struct ieee80211_bpf_params;
|
struct ieee80211_bpf_params;
|
||||||
int ieee80211_mgmt_output(struct ieee80211_node *, struct mbuf *, int,
|
int ieee80211_mgmt_output(struct ieee80211_node *, struct mbuf *, int,
|
||||||
struct ieee80211_bpf_params *);
|
struct ieee80211_bpf_params *);
|
||||||
|
325
sys/net80211/ieee80211_radiotap.c
Normal file
325
sys/net80211/ieee80211_radiotap.c
Normal file
@ -0,0 +1,325 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2009 Sam Leffler, Errno Consulting
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IEEE 802.11 radiotap support.
|
||||||
|
*/
|
||||||
|
#include "opt_wlan.h"
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/systm.h>
|
||||||
|
#include <sys/mbuf.h>
|
||||||
|
#include <sys/malloc.h>
|
||||||
|
#include <sys/endian.h>
|
||||||
|
#include <sys/kernel.h>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include <net/bpf.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <net/if_llc.h>
|
||||||
|
#include <net/if_media.h>
|
||||||
|
|
||||||
|
#include <net80211/ieee80211_var.h>
|
||||||
|
|
||||||
|
static int radiotap_offset(struct ieee80211_radiotap_header *, int);
|
||||||
|
|
||||||
|
void
|
||||||
|
ieee80211_radiotap_attach(struct ieee80211com *ic,
|
||||||
|
struct ieee80211_radiotap_header *th, int tlen, uint32_t tx_radiotap,
|
||||||
|
struct ieee80211_radiotap_header *rh, int rlen, uint32_t rx_radiotap)
|
||||||
|
{
|
||||||
|
#define B(_v) (1<<(_v))
|
||||||
|
int off;
|
||||||
|
|
||||||
|
th->it_len = htole16(roundup2(tlen, sizeof(uint32_t)));
|
||||||
|
th->it_present = htole32(tx_radiotap);
|
||||||
|
ic->ic_th = th;
|
||||||
|
/* calculate offset to channel data */
|
||||||
|
off = -1;
|
||||||
|
if (tx_radiotap & B(IEEE80211_RADIOTAP_CHANNEL))
|
||||||
|
off = radiotap_offset(th, IEEE80211_RADIOTAP_CHANNEL);
|
||||||
|
else if (tx_radiotap & B(IEEE80211_RADIOTAP_XCHANNEL))
|
||||||
|
off = radiotap_offset(th, IEEE80211_RADIOTAP_XCHANNEL);
|
||||||
|
if (off == -1) {
|
||||||
|
if_printf(ic->ic_ifp, "%s: no tx channel, radiotap 0x%x",
|
||||||
|
__func__, tx_radiotap);
|
||||||
|
/* NB: we handle this case but data will have no chan spec */
|
||||||
|
} else
|
||||||
|
ic->ic_txchan = ((uint8_t *) th) + off;
|
||||||
|
|
||||||
|
rh->it_len = htole16(roundup2(rlen, sizeof(uint32_t)));
|
||||||
|
rh->it_present = htole32(rx_radiotap);
|
||||||
|
ic->ic_rh = rh;
|
||||||
|
/* calculate offset to channel data */
|
||||||
|
off = -1;
|
||||||
|
if (rx_radiotap & B(IEEE80211_RADIOTAP_CHANNEL))
|
||||||
|
off = radiotap_offset(rh, IEEE80211_RADIOTAP_CHANNEL);
|
||||||
|
else if (rx_radiotap & B(IEEE80211_RADIOTAP_XCHANNEL))
|
||||||
|
off = radiotap_offset(rh, IEEE80211_RADIOTAP_XCHANNEL);
|
||||||
|
if (off == -1) {
|
||||||
|
if_printf(ic->ic_ifp, "%s: no rx channel, radiotap 0x%x",
|
||||||
|
__func__, rx_radiotap);
|
||||||
|
/* NB: we handle this case but data will have no chan spec */
|
||||||
|
} else
|
||||||
|
ic->ic_rxchan = ((uint8_t *) rh) + off;
|
||||||
|
#undef B
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ieee80211_radiotap_detach(struct ieee80211com *ic)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ieee80211_radiotap_vattach(struct ieee80211vap *vap)
|
||||||
|
{
|
||||||
|
struct ieee80211com *ic = vap->iv_ic;
|
||||||
|
struct ieee80211_radiotap_header *th = ic->ic_th;
|
||||||
|
|
||||||
|
KASSERT(th != NULL, ("no radiotap setup"));
|
||||||
|
|
||||||
|
/* radiotap DLT for raw 802.11 frames */
|
||||||
|
bpfattach2(vap->iv_ifp, DLT_IEEE802_11_RADIO,
|
||||||
|
sizeof(struct ieee80211_frame) + le16toh(th->it_len),
|
||||||
|
&vap->iv_rawbpf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ieee80211_radiotap_vdetach(struct ieee80211vap *vap)
|
||||||
|
{
|
||||||
|
/* NB: bpfattach is called by ether_ifdetach and claims all taps */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_channel(void *p, const struct ieee80211_channel *c)
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
uint16_t freq;
|
||||||
|
uint16_t flags;
|
||||||
|
} *rc = p;
|
||||||
|
|
||||||
|
rc->freq = htole16(c->ic_freq);
|
||||||
|
rc->flags = htole16(c->ic_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_xchannel(void *p, const struct ieee80211_channel *c)
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
uint32_t flags;
|
||||||
|
uint16_t freq;
|
||||||
|
uint8_t ieee;
|
||||||
|
uint8_t maxpow;
|
||||||
|
} *rc = p;
|
||||||
|
|
||||||
|
rc->flags = htole32(c->ic_flags);
|
||||||
|
rc->freq = htole16(c->ic_freq);
|
||||||
|
rc->ieee = c->ic_ieee;
|
||||||
|
rc->maxpow = c->ic_maxregpower;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update radiotap state on channel change.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ieee80211_radiotap_chan_change(struct ieee80211com *ic)
|
||||||
|
{
|
||||||
|
if (ic->ic_rxchan != NULL) {
|
||||||
|
struct ieee80211_radiotap_header *rh = ic->ic_rh;
|
||||||
|
|
||||||
|
if (rh->it_present & (1<<IEEE80211_RADIOTAP_XCHANNEL))
|
||||||
|
set_xchannel(ic->ic_rxchan, ic->ic_curchan);
|
||||||
|
else if (rh->it_present & (1<<IEEE80211_RADIOTAP_CHANNEL))
|
||||||
|
set_channel(ic->ic_rxchan, ic->ic_curchan);
|
||||||
|
}
|
||||||
|
if (ic->ic_txchan != NULL) {
|
||||||
|
struct ieee80211_radiotap_header *th = ic->ic_th;
|
||||||
|
|
||||||
|
if (th->it_present & (1<<IEEE80211_RADIOTAP_XCHANNEL))
|
||||||
|
set_xchannel(ic->ic_txchan, ic->ic_curchan);
|
||||||
|
else if (th->it_present & (1<<IEEE80211_RADIOTAP_CHANNEL))
|
||||||
|
set_channel(ic->ic_txchan, ic->ic_curchan);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dispatch_radiotap(struct ieee80211vap *vap0, struct mbuf *m,
|
||||||
|
struct ieee80211_radiotap_header *rh)
|
||||||
|
{
|
||||||
|
struct ieee80211com *ic = vap0->iv_ic;
|
||||||
|
int len = le16toh(rh->it_len);
|
||||||
|
|
||||||
|
if (ieee80211_radiotap_active_vap(vap0))
|
||||||
|
bpf_mtap2(vap0->iv_rawbpf, rh, len, m);
|
||||||
|
if (ic->ic_monvaps) {
|
||||||
|
struct ieee80211vap *vap;
|
||||||
|
TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
|
||||||
|
if (vap->iv_opmode == IEEE80211_M_MONITOR &&
|
||||||
|
vap != vap0 && ieee80211_radiotap_active_vap(vap))
|
||||||
|
bpf_mtap2(vap->iv_rawbpf, rh, len, m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dispatch radiotap data for transmitted packet.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ieee80211_radiotap_tx(struct ieee80211vap *vap0, struct mbuf *m)
|
||||||
|
{
|
||||||
|
dispatch_radiotap(vap0, m, vap0->iv_ic->ic_th);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dispatch radiotap data for received packet.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ieee80211_radiotap_rx(struct ieee80211vap *vap0, struct mbuf *m)
|
||||||
|
{
|
||||||
|
dispatch_radiotap(vap0, m, vap0->iv_ic->ic_rh);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dispatch radiotap data for a packet received outside the normal
|
||||||
|
* rx processing path; this is used, for example, to handle frames
|
||||||
|
* received with errors that would otherwise be dropped.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ieee80211_radiotap_rx_all(struct ieee80211com *ic, struct mbuf *m)
|
||||||
|
{
|
||||||
|
struct ieee80211_radiotap_header *rh = ic->ic_rh;
|
||||||
|
int len = le16toh(rh->it_len);
|
||||||
|
struct ieee80211vap *vap;
|
||||||
|
|
||||||
|
/* XXX locking? */
|
||||||
|
TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
|
||||||
|
if (ieee80211_radiotap_active_vap(vap))
|
||||||
|
bpf_mtap2(vap->iv_rawbpf, rh, len, m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the offset of the specified item in the radiotap
|
||||||
|
* header description. If the item is not present or is not
|
||||||
|
* known -1 is returned.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
radiotap_offset(struct ieee80211_radiotap_header *rh, int item)
|
||||||
|
{
|
||||||
|
static const struct {
|
||||||
|
size_t align, width;
|
||||||
|
} items[] = {
|
||||||
|
[IEEE80211_RADIOTAP_TSFT] = {
|
||||||
|
.align = sizeof(uint64_t),
|
||||||
|
.width = sizeof(uint64_t),
|
||||||
|
},
|
||||||
|
[IEEE80211_RADIOTAP_FLAGS] = {
|
||||||
|
.align = sizeof(uint8_t),
|
||||||
|
.width = sizeof(uint8_t),
|
||||||
|
},
|
||||||
|
[IEEE80211_RADIOTAP_RATE] = {
|
||||||
|
.align = sizeof(uint8_t),
|
||||||
|
.width = sizeof(uint8_t),
|
||||||
|
},
|
||||||
|
[IEEE80211_RADIOTAP_CHANNEL] = {
|
||||||
|
.align = sizeof(uint16_t),
|
||||||
|
.width = 2*sizeof(uint16_t),
|
||||||
|
},
|
||||||
|
[IEEE80211_RADIOTAP_FHSS] = {
|
||||||
|
.align = sizeof(uint16_t),
|
||||||
|
.width = sizeof(uint16_t),
|
||||||
|
},
|
||||||
|
[IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = {
|
||||||
|
.align = sizeof(uint8_t),
|
||||||
|
.width = sizeof(uint8_t),
|
||||||
|
},
|
||||||
|
[IEEE80211_RADIOTAP_DBM_ANTNOISE] = {
|
||||||
|
.align = sizeof(uint8_t),
|
||||||
|
.width = sizeof(uint8_t),
|
||||||
|
},
|
||||||
|
[IEEE80211_RADIOTAP_LOCK_QUALITY] = {
|
||||||
|
.align = sizeof(uint16_t),
|
||||||
|
.width = sizeof(uint16_t),
|
||||||
|
},
|
||||||
|
[IEEE80211_RADIOTAP_TX_ATTENUATION] = {
|
||||||
|
.align = sizeof(uint16_t),
|
||||||
|
.width = sizeof(uint16_t),
|
||||||
|
},
|
||||||
|
[IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = {
|
||||||
|
.align = sizeof(uint16_t),
|
||||||
|
.width = sizeof(uint16_t),
|
||||||
|
},
|
||||||
|
[IEEE80211_RADIOTAP_DBM_TX_POWER] = {
|
||||||
|
.align = sizeof(uint8_t),
|
||||||
|
.width = sizeof(uint8_t),
|
||||||
|
},
|
||||||
|
[IEEE80211_RADIOTAP_ANTENNA] = {
|
||||||
|
.align = sizeof(uint8_t),
|
||||||
|
.width = sizeof(uint8_t),
|
||||||
|
},
|
||||||
|
[IEEE80211_RADIOTAP_DB_ANTSIGNAL] = {
|
||||||
|
.align = sizeof(uint8_t),
|
||||||
|
.width = sizeof(uint8_t),
|
||||||
|
},
|
||||||
|
[IEEE80211_RADIOTAP_DB_ANTNOISE] = {
|
||||||
|
.align = sizeof(uint8_t),
|
||||||
|
.width = sizeof(uint8_t),
|
||||||
|
},
|
||||||
|
[IEEE80211_RADIOTAP_XCHANNEL] = {
|
||||||
|
.align = sizeof(uint32_t),
|
||||||
|
.width = 2*sizeof(uint32_t),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
uint32_t present = le32toh(rh->it_present);
|
||||||
|
int off, i;
|
||||||
|
|
||||||
|
off = sizeof(struct ieee80211_radiotap_header);
|
||||||
|
for (i = 0; i < IEEE80211_RADIOTAP_EXT; i++) {
|
||||||
|
if ((present & (1<<i)) == 0)
|
||||||
|
continue;
|
||||||
|
if (items[i].align == 0) {
|
||||||
|
/* NB: unidentified element, don't guess */
|
||||||
|
printf("%s: unknown item %d\n", __func__, i);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
off = roundup2(off, items[i].align);
|
||||||
|
if (i == item) {
|
||||||
|
if (off + items[i].width > le16toh(rh->it_len)) {
|
||||||
|
/* NB: item does not fit in header data */
|
||||||
|
printf("%s: item %d not in header data, "
|
||||||
|
"off %d width %zu len %d\n", __func__, i,
|
||||||
|
off, items[i].width, le16toh(rh->it_len));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return off;
|
||||||
|
}
|
||||||
|
off += items[i].width;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
@ -920,6 +920,7 @@ scan_task(void *arg, int pending)
|
|||||||
* completed the channel change.
|
* completed the channel change.
|
||||||
*/
|
*/
|
||||||
ic->ic_set_channel(ic);
|
ic->ic_set_channel(ic);
|
||||||
|
ieee80211_radiotap_chan_change(ic);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Scan curchan. Drivers for "intelligent hardware"
|
* Scan curchan. Drivers for "intelligent hardware"
|
||||||
@ -966,6 +967,7 @@ scan_task(void *arg, int pending)
|
|||||||
ieee80211_setupcurchan(ic, ic->ic_bsschan);
|
ieee80211_setupcurchan(ic, ic->ic_bsschan);
|
||||||
IEEE80211_UNLOCK(ic);
|
IEEE80211_UNLOCK(ic);
|
||||||
ic->ic_set_channel(ic);
|
ic->ic_set_channel(ic);
|
||||||
|
ieee80211_radiotap_chan_change(ic);
|
||||||
IEEE80211_LOCK(ic);
|
IEEE80211_LOCK(ic);
|
||||||
}
|
}
|
||||||
/* clear internal flags and any indication of a pick */
|
/* clear internal flags and any indication of a pick */
|
||||||
@ -1095,7 +1097,7 @@ void
|
|||||||
ieee80211_add_scan(struct ieee80211vap *vap,
|
ieee80211_add_scan(struct ieee80211vap *vap,
|
||||||
const struct ieee80211_scanparams *sp,
|
const struct ieee80211_scanparams *sp,
|
||||||
const struct ieee80211_frame *wh,
|
const struct ieee80211_frame *wh,
|
||||||
int subtype, int rssi, int noise, int rstamp)
|
int subtype, int rssi, int noise)
|
||||||
{
|
{
|
||||||
struct ieee80211com *ic = vap->iv_ic;
|
struct ieee80211com *ic = vap->iv_ic;
|
||||||
struct ieee80211_scan_state *ss = ic->ic_scan;
|
struct ieee80211_scan_state *ss = ic->ic_scan;
|
||||||
@ -1115,7 +1117,7 @@ ieee80211_add_scan(struct ieee80211vap *vap,
|
|||||||
dump_probe_beacon(subtype, 1, wh->i_addr2, sp, rssi);
|
dump_probe_beacon(subtype, 1, wh->i_addr2, sp, rssi);
|
||||||
#endif
|
#endif
|
||||||
if (ss->ss_ops != NULL &&
|
if (ss->ss_ops != NULL &&
|
||||||
ss->ss_ops->scan_add(ss, sp, wh, subtype, rssi, noise, rstamp)) {
|
ss->ss_ops->scan_add(ss, sp, wh, subtype, rssi, noise)) {
|
||||||
/*
|
/*
|
||||||
* If we've reached the min dwell time terminate
|
* If we've reached the min dwell time terminate
|
||||||
* the timer so we'll switch to the next channel.
|
* the timer so we'll switch to the next channel.
|
||||||
|
@ -150,7 +150,7 @@ struct ieee80211_scanparams;
|
|||||||
void ieee80211_add_scan(struct ieee80211vap *,
|
void ieee80211_add_scan(struct ieee80211vap *,
|
||||||
const struct ieee80211_scanparams *,
|
const struct ieee80211_scanparams *,
|
||||||
const struct ieee80211_frame *,
|
const struct ieee80211_frame *,
|
||||||
int subtype, int rssi, int noise, int rstamp);
|
int subtype, int rssi, int noise);
|
||||||
void ieee80211_scan_timeout(struct ieee80211com *);
|
void ieee80211_scan_timeout(struct ieee80211com *);
|
||||||
|
|
||||||
void ieee80211_scan_assoc_success(struct ieee80211vap *,
|
void ieee80211_scan_assoc_success(struct ieee80211vap *,
|
||||||
@ -224,7 +224,6 @@ struct ieee80211_scan_entry {
|
|||||||
uint8_t se_ssid[2+IEEE80211_NWID_LEN];
|
uint8_t se_ssid[2+IEEE80211_NWID_LEN];
|
||||||
uint8_t se_rates[2+IEEE80211_RATE_MAXSIZE];
|
uint8_t se_rates[2+IEEE80211_RATE_MAXSIZE];
|
||||||
uint8_t se_xrates[2+IEEE80211_RATE_MAXSIZE];
|
uint8_t se_xrates[2+IEEE80211_RATE_MAXSIZE];
|
||||||
uint32_t se_rstamp; /* recv timestamp */
|
|
||||||
union {
|
union {
|
||||||
uint8_t data[8];
|
uint8_t data[8];
|
||||||
u_int64_t tsf;
|
u_int64_t tsf;
|
||||||
@ -269,7 +268,7 @@ struct ieee80211_scanner {
|
|||||||
int (*scan_add)(struct ieee80211_scan_state *,
|
int (*scan_add)(struct ieee80211_scan_state *,
|
||||||
const struct ieee80211_scanparams *,
|
const struct ieee80211_scanparams *,
|
||||||
const struct ieee80211_frame *,
|
const struct ieee80211_frame *,
|
||||||
int subtype, int rssi, int noise, int rstamp);
|
int subtype, int rssi, int noise);
|
||||||
/* age and/or purge entries in the cache */
|
/* age and/or purge entries in the cache */
|
||||||
void (*scan_age)(struct ieee80211_scan_state *);
|
void (*scan_age)(struct ieee80211_scan_state *);
|
||||||
/* note that association failed for an entry */
|
/* note that association failed for an entry */
|
||||||
|
@ -219,7 +219,7 @@ static int
|
|||||||
sta_add(struct ieee80211_scan_state *ss,
|
sta_add(struct ieee80211_scan_state *ss,
|
||||||
const struct ieee80211_scanparams *sp,
|
const struct ieee80211_scanparams *sp,
|
||||||
const struct ieee80211_frame *wh,
|
const struct ieee80211_frame *wh,
|
||||||
int subtype, int rssi, int noise, int rstamp)
|
int subtype, int rssi, int noise)
|
||||||
{
|
{
|
||||||
#define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
|
#define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
|
||||||
#define PICK1ST(_ss) \
|
#define PICK1ST(_ss) \
|
||||||
@ -278,7 +278,6 @@ found:
|
|||||||
ise->se_rssi = IEEE80211_RSSI_GET(se->se_avgrssi);
|
ise->se_rssi = IEEE80211_RSSI_GET(se->se_avgrssi);
|
||||||
ise->se_noise = noise;
|
ise->se_noise = noise;
|
||||||
}
|
}
|
||||||
ise->se_rstamp = rstamp;
|
|
||||||
memcpy(ise->se_tstamp.data, sp->tstamp, sizeof(ise->se_tstamp));
|
memcpy(ise->se_tstamp.data, sp->tstamp, sizeof(ise->se_tstamp));
|
||||||
ise->se_intval = sp->bintval;
|
ise->se_intval = sp->bintval;
|
||||||
ise->se_capinfo = sp->capinfo;
|
ise->se_capinfo = sp->capinfo;
|
||||||
|
@ -66,10 +66,9 @@ __FBSDID("$FreeBSD$");
|
|||||||
static void sta_vattach(struct ieee80211vap *);
|
static void sta_vattach(struct ieee80211vap *);
|
||||||
static void sta_beacon_miss(struct ieee80211vap *);
|
static void sta_beacon_miss(struct ieee80211vap *);
|
||||||
static int sta_newstate(struct ieee80211vap *, enum ieee80211_state, int);
|
static int sta_newstate(struct ieee80211vap *, enum ieee80211_state, int);
|
||||||
static int sta_input(struct ieee80211_node *, struct mbuf *,
|
static int sta_input(struct ieee80211_node *, struct mbuf *, int, int);
|
||||||
int rssi, int noise, uint32_t rstamp);
|
|
||||||
static void sta_recv_mgmt(struct ieee80211_node *, struct mbuf *,
|
static void sta_recv_mgmt(struct ieee80211_node *, struct mbuf *,
|
||||||
int subtype, int rssi, int noise, uint32_t rstamp);
|
int subtype, int rssi, int nf);
|
||||||
static void sta_recv_ctl(struct ieee80211_node *, struct mbuf *, int subtype);
|
static void sta_recv_ctl(struct ieee80211_node *, struct mbuf *, int subtype);
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -490,8 +489,7 @@ doprint(struct ieee80211vap *vap, int subtype)
|
|||||||
* by the 802.11 layer.
|
* by the 802.11 layer.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
sta_input(struct ieee80211_node *ni, struct mbuf *m,
|
sta_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
|
||||||
int rssi, int noise, uint32_t rstamp)
|
|
||||||
{
|
{
|
||||||
#define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0)
|
#define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0)
|
||||||
#define HAS_SEQ(type) ((type & 0x4) == 0)
|
#define HAS_SEQ(type) ((type & 0x4) == 0)
|
||||||
@ -566,8 +564,7 @@ sta_input(struct ieee80211_node *ni, struct mbuf *m,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
|
IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
|
||||||
ni->ni_noise = noise;
|
ni->ni_noise = nf;
|
||||||
ni->ni_rstamp = rstamp;
|
|
||||||
if (HAS_SEQ(type)) {
|
if (HAS_SEQ(type)) {
|
||||||
uint8_t tid = ieee80211_gettid(wh);
|
uint8_t tid = ieee80211_gettid(wh);
|
||||||
if (IEEE80211_QOS_HAS_SEQ(wh) &&
|
if (IEEE80211_QOS_HAS_SEQ(wh) &&
|
||||||
@ -743,8 +740,8 @@ sta_input(struct ieee80211_node *ni, struct mbuf *m,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* copy to listener after decrypt */
|
/* copy to listener after decrypt */
|
||||||
if (bpf_peers_present(vap->iv_rawbpf))
|
if (ieee80211_radiotap_active_vap(vap))
|
||||||
bpf_mtap(vap->iv_rawbpf, m);
|
ieee80211_radiotap_tx(vap, m);
|
||||||
need_tap = 0;
|
need_tap = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -869,7 +866,7 @@ sta_input(struct ieee80211_node *ni, struct mbuf *m,
|
|||||||
wh = mtod(m, struct ieee80211_frame *);
|
wh = mtod(m, struct ieee80211_frame *);
|
||||||
wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
|
wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
|
||||||
}
|
}
|
||||||
vap->iv_recv_mgmt(ni, m, subtype, rssi, noise, rstamp);
|
vap->iv_recv_mgmt(ni, m, subtype, rssi, nf);
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
case IEEE80211_FC0_TYPE_CTL:
|
case IEEE80211_FC0_TYPE_CTL:
|
||||||
@ -888,8 +885,8 @@ err:
|
|||||||
ifp->if_ierrors++;
|
ifp->if_ierrors++;
|
||||||
out:
|
out:
|
||||||
if (m != NULL) {
|
if (m != NULL) {
|
||||||
if (need_tap && bpf_peers_present(vap->iv_rawbpf))
|
if (need_tap)
|
||||||
bpf_mtap(vap->iv_rawbpf, m);
|
ieee80211_radiotap_rx(vap, m);
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
}
|
}
|
||||||
return type;
|
return type;
|
||||||
@ -898,7 +895,7 @@ out:
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
sta_auth_open(struct ieee80211_node *ni, struct ieee80211_frame *wh,
|
sta_auth_open(struct ieee80211_node *ni, struct ieee80211_frame *wh,
|
||||||
int rssi, int noise, uint32_t rstamp, uint16_t seq, uint16_t status)
|
int rssi, int nf, uint16_t seq, uint16_t status)
|
||||||
{
|
{
|
||||||
struct ieee80211vap *vap = ni->ni_vap;
|
struct ieee80211vap *vap = ni->ni_vap;
|
||||||
|
|
||||||
@ -927,7 +924,7 @@ sta_auth_open(struct ieee80211_node *ni, struct ieee80211_frame *wh,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
sta_auth_shared(struct ieee80211_node *ni, struct ieee80211_frame *wh,
|
sta_auth_shared(struct ieee80211_node *ni, struct ieee80211_frame *wh,
|
||||||
uint8_t *frm, uint8_t *efrm, int rssi, int noise, uint32_t rstamp,
|
uint8_t *frm, uint8_t *efrm, int rssi, int nf,
|
||||||
uint16_t seq, uint16_t status)
|
uint16_t seq, uint16_t status)
|
||||||
{
|
{
|
||||||
struct ieee80211vap *vap = ni->ni_vap;
|
struct ieee80211vap *vap = ni->ni_vap;
|
||||||
@ -1128,7 +1125,7 @@ startbgscan(struct ieee80211vap *vap)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
|
sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
|
||||||
int subtype, int rssi, int noise, uint32_t rstamp)
|
int subtype, int rssi, int nf)
|
||||||
{
|
{
|
||||||
#define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
|
#define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
|
||||||
#define ISREASSOC(_st) ((_st) == IEEE80211_FC0_SUBTYPE_REASSOC_RESP)
|
#define ISREASSOC(_st) ((_st) == IEEE80211_FC0_SUBTYPE_REASSOC_RESP)
|
||||||
@ -1264,7 +1261,7 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
|
|||||||
*/
|
*/
|
||||||
if (ic->ic_flags & IEEE80211_F_SCAN) {
|
if (ic->ic_flags & IEEE80211_F_SCAN) {
|
||||||
ieee80211_add_scan(vap, &scan, wh,
|
ieee80211_add_scan(vap, &scan, wh,
|
||||||
subtype, rssi, noise, rstamp);
|
subtype, rssi, nf);
|
||||||
} else if (contbgscan(vap)) {
|
} else if (contbgscan(vap)) {
|
||||||
ieee80211_bg_scan(vap, 0);
|
ieee80211_bg_scan(vap, 0);
|
||||||
} else if (startbgscan(vap)) {
|
} else if (startbgscan(vap)) {
|
||||||
@ -1293,8 +1290,7 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
|
|||||||
ieee80211_probe_curchan(vap, 1);
|
ieee80211_probe_curchan(vap, 1);
|
||||||
ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN;
|
ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN;
|
||||||
}
|
}
|
||||||
ieee80211_add_scan(vap, &scan, wh,
|
ieee80211_add_scan(vap, &scan, wh, subtype, rssi, nf);
|
||||||
subtype, rssi, noise, rstamp);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1329,11 +1325,10 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (algo == IEEE80211_AUTH_ALG_SHARED)
|
if (algo == IEEE80211_AUTH_ALG_SHARED)
|
||||||
sta_auth_shared(ni, wh, frm + 6, efrm, rssi,
|
sta_auth_shared(ni, wh, frm + 6, efrm, rssi, nf,
|
||||||
noise, rstamp, seq, status);
|
|
||||||
else if (algo == IEEE80211_AUTH_ALG_OPEN)
|
|
||||||
sta_auth_open(ni, wh, rssi, noise, rstamp,
|
|
||||||
seq, status);
|
seq, status);
|
||||||
|
else if (algo == IEEE80211_AUTH_ALG_OPEN)
|
||||||
|
sta_auth_open(ni, wh, rssi, nf, seq, status);
|
||||||
else {
|
else {
|
||||||
IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
|
IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
|
||||||
wh, "auth", "unsupported alg %d", algo);
|
wh, "auth", "unsupported alg %d", algo);
|
||||||
|
@ -503,9 +503,6 @@ ff_transmit(struct ieee80211_node *ni, struct mbuf *m)
|
|||||||
struct ifnet *ifp = vap->iv_ifp;
|
struct ifnet *ifp = vap->iv_ifp;
|
||||||
struct ifnet *parent = ni->ni_ic->ic_ifp;
|
struct ifnet *parent = ni->ni_ic->ic_ifp;
|
||||||
|
|
||||||
if (bpf_peers_present(vap->iv_rawbpf))
|
|
||||||
bpf_mtap(vap->iv_rawbpf, m);
|
|
||||||
|
|
||||||
error = parent->if_transmit(parent, m);
|
error = parent->if_transmit(parent, m);
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
/* NB: IFQ_HANDOFF reclaims mbuf */
|
/* NB: IFQ_HANDOFF reclaims mbuf */
|
||||||
@ -835,6 +832,7 @@ ieee80211_dturbo_switch(struct ieee80211vap *vap, int newflags)
|
|||||||
ic->ic_curchan = chan;
|
ic->ic_curchan = chan;
|
||||||
ic->ic_rt = ieee80211_get_ratetable(chan);
|
ic->ic_rt = ieee80211_get_ratetable(chan);
|
||||||
ic->ic_set_channel(ic);
|
ic->ic_set_channel(ic);
|
||||||
|
ieee80211_radiotap_chan_change(ic);
|
||||||
/* NB: do not need to reset ERP state 'cuz we're in sta mode */
|
/* NB: do not need to reset ERP state 'cuz we're in sta mode */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,12 +108,12 @@ static void tdma_vdetach(struct ieee80211vap *vap);
|
|||||||
static int tdma_newstate(struct ieee80211vap *, enum ieee80211_state, int);
|
static int tdma_newstate(struct ieee80211vap *, enum ieee80211_state, int);
|
||||||
static void tdma_beacon_miss(struct ieee80211vap *vap);
|
static void tdma_beacon_miss(struct ieee80211vap *vap);
|
||||||
static void tdma_recv_mgmt(struct ieee80211_node *, struct mbuf *,
|
static void tdma_recv_mgmt(struct ieee80211_node *, struct mbuf *,
|
||||||
int subtype, int rssi, int noise, uint32_t rstamp);
|
int subtype, int rssi, int nf);
|
||||||
static int tdma_update(struct ieee80211vap *vap,
|
static int tdma_update(struct ieee80211vap *vap,
|
||||||
const struct ieee80211_tdma_param *tdma, struct ieee80211_node *ni,
|
const struct ieee80211_tdma_param *tdma, struct ieee80211_node *ni,
|
||||||
int pickslot);
|
int pickslot);
|
||||||
static int tdma_process_params(struct ieee80211_node *ni,
|
static int tdma_process_params(struct ieee80211_node *ni,
|
||||||
const u_int8_t *ie, u_int32_t rstamp, const struct ieee80211_frame *wh);
|
const u_int8_t *ie, int rssi, int nf, const struct ieee80211_frame *wh);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
settxparms(struct ieee80211vap *vap, enum ieee80211_phymode mode, int rate)
|
settxparms(struct ieee80211vap *vap, enum ieee80211_phymode mode, int rate)
|
||||||
@ -304,7 +304,7 @@ tdma_beacon_miss(struct ieee80211vap *vap)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
tdma_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
|
tdma_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
|
||||||
int subtype, int rssi, int noise, uint32_t rstamp)
|
int subtype, int rssi, int nf)
|
||||||
{
|
{
|
||||||
struct ieee80211com *ic = ni->ni_ic;
|
struct ieee80211com *ic = ni->ni_ic;
|
||||||
struct ieee80211vap *vap = ni->ni_vap;
|
struct ieee80211vap *vap = ni->ni_vap;
|
||||||
@ -367,7 +367,7 @@ tdma_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
|
|||||||
* Process tdma ie. The contents are used to sync
|
* Process tdma ie. The contents are used to sync
|
||||||
* the slot timing, reconfigure the bss, etc.
|
* the slot timing, reconfigure the bss, etc.
|
||||||
*/
|
*/
|
||||||
(void) tdma_process_params(ni, scan.tdma, rstamp, wh);
|
(void) tdma_process_params(ni, scan.tdma, rssi, nf, wh);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -375,7 +375,7 @@ tdma_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
|
|||||||
* 2x parsing of the frame but should happen infrequently
|
* 2x parsing of the frame but should happen infrequently
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
ts->tdma_recv_mgmt(ni, m0, subtype, rssi, noise, rstamp);
|
ts->tdma_recv_mgmt(ni, m0, subtype, rssi, nf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -497,8 +497,8 @@ tdma_update(struct ieee80211vap *vap, const struct ieee80211_tdma_param *tdma,
|
|||||||
* Process received TDMA parameters.
|
* Process received TDMA parameters.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
tdma_process_params(struct ieee80211_node *ni,
|
tdma_process_params(struct ieee80211_node *ni, const u_int8_t *ie,
|
||||||
const u_int8_t *ie, u_int32_t rstamp, const struct ieee80211_frame *wh)
|
int rssi, int nf, const struct ieee80211_frame *wh)
|
||||||
{
|
{
|
||||||
struct ieee80211vap *vap = ni->ni_vap;
|
struct ieee80211vap *vap = ni->ni_vap;
|
||||||
struct ieee80211_tdma_state *ts = vap->iv_tdma;
|
struct ieee80211_tdma_state *ts = vap->iv_tdma;
|
||||||
@ -563,12 +563,16 @@ tdma_process_params(struct ieee80211_node *ni,
|
|||||||
/* XXX reschedule swbmiss timer on parameter change */
|
/* XXX reschedule swbmiss timer on parameter change */
|
||||||
} else if (tdma->tdma_slot == ts->tdma_slot+1) {
|
} else if (tdma->tdma_slot == ts->tdma_slot+1) {
|
||||||
uint64_t tstamp;
|
uint64_t tstamp;
|
||||||
|
#if 0
|
||||||
|
uint32_t rstamp = (uint32_t) le64toh(rs->tsf);
|
||||||
int32_t rtt;
|
int32_t rtt;
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
* Use returned timstamp to calculate the
|
* Use returned timstamp to calculate the
|
||||||
* roundtrip time.
|
* roundtrip time.
|
||||||
*/
|
*/
|
||||||
memcpy(&tstamp, tdma->tdma_tstamp, 8);
|
memcpy(&tstamp, tdma->tdma_tstamp, 8);
|
||||||
|
#if 0
|
||||||
/* XXX use only 15 bits of rstamp */
|
/* XXX use only 15 bits of rstamp */
|
||||||
rtt = rstamp - (le64toh(tstamp) & 0x7fff);
|
rtt = rstamp - (le64toh(tstamp) & 0x7fff);
|
||||||
if (rtt < 0)
|
if (rtt < 0)
|
||||||
@ -578,6 +582,7 @@ tdma_process_params(struct ieee80211_node *ni,
|
|||||||
"tdma rtt %5u [rstamp %5u tstamp %llu]\n",
|
"tdma rtt %5u [rstamp %5u tstamp %llu]\n",
|
||||||
rtt, rstamp,
|
rtt, rstamp,
|
||||||
(unsigned long long) le64toh(tstamp));
|
(unsigned long long) le64toh(tstamp));
|
||||||
|
#endif
|
||||||
} else if (tdma->tdma_slot == ts->tdma_slot &&
|
} else if (tdma->tdma_slot == ts->tdma_slot &&
|
||||||
le64toh(ni->ni_tstamp.tsf) > vap->iv_bss->ni_tstamp.tsf) {
|
le64toh(ni->ni_tstamp.tsf) > vap->iv_bss->ni_tstamp.tsf) {
|
||||||
/*
|
/*
|
||||||
|
@ -81,7 +81,7 @@ struct ieee80211_tdma_state {
|
|||||||
int (*tdma_newstate)(struct ieee80211vap *, enum ieee80211_state,
|
int (*tdma_newstate)(struct ieee80211vap *, enum ieee80211_state,
|
||||||
int arg);
|
int arg);
|
||||||
void (*tdma_recv_mgmt)(struct ieee80211_node *,
|
void (*tdma_recv_mgmt)(struct ieee80211_node *,
|
||||||
struct mbuf *, int, int, int, uint32_t);
|
struct mbuf *, int, int, int);
|
||||||
void (*tdma_opdetach)(struct ieee80211vap *);
|
void (*tdma_opdetach)(struct ieee80211vap *);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
#include <net80211/ieee80211_power.h>
|
#include <net80211/ieee80211_power.h>
|
||||||
#include <net80211/ieee80211_node.h>
|
#include <net80211/ieee80211_node.h>
|
||||||
#include <net80211/ieee80211_proto.h>
|
#include <net80211/ieee80211_proto.h>
|
||||||
|
#include <net80211/ieee80211_radiotap.h>
|
||||||
#include <net80211/ieee80211_scan.h>
|
#include <net80211/ieee80211_scan.h>
|
||||||
|
|
||||||
#define IEEE80211_TXPOWER_MAX 100 /* .5 dbM (XXX units?) */
|
#define IEEE80211_TXPOWER_MAX 100 /* .5 dbM (XXX units?) */
|
||||||
@ -209,6 +210,13 @@ struct ieee80211com {
|
|||||||
/* optional state for Atheros SuperG protocol extensions */
|
/* optional state for Atheros SuperG protocol extensions */
|
||||||
struct ieee80211_superg *ic_superg;
|
struct ieee80211_superg *ic_superg;
|
||||||
|
|
||||||
|
/* radiotap handling */
|
||||||
|
struct ieee80211_radiotap_header *ic_th;/* tx radiotap headers */
|
||||||
|
void *ic_txchan; /* channel state in ic_th */
|
||||||
|
struct ieee80211_radiotap_header *ic_rh;/* rx radiotap headers */
|
||||||
|
void *ic_rxchan; /* channel state in ic_rh */
|
||||||
|
int ic_monvaps; /* # monitor mode vaps */
|
||||||
|
|
||||||
/* virtual ap create/delete */
|
/* virtual ap create/delete */
|
||||||
struct ieee80211vap* (*ic_vap_create)(struct ieee80211com *,
|
struct ieee80211vap* (*ic_vap_create)(struct ieee80211com *,
|
||||||
const char name[IFNAMSIZ], int unit,
|
const char name[IFNAMSIZ], int unit,
|
||||||
@ -421,10 +429,9 @@ struct ieee80211vap {
|
|||||||
void (*iv_opdetach)(struct ieee80211vap *);
|
void (*iv_opdetach)(struct ieee80211vap *);
|
||||||
/* receive processing */
|
/* receive processing */
|
||||||
int (*iv_input)(struct ieee80211_node *,
|
int (*iv_input)(struct ieee80211_node *,
|
||||||
struct mbuf *, int rssi, int noise,
|
struct mbuf *, int, int);
|
||||||
uint32_t rstamp);
|
|
||||||
void (*iv_recv_mgmt)(struct ieee80211_node *,
|
void (*iv_recv_mgmt)(struct ieee80211_node *,
|
||||||
struct mbuf *, int, int, int, uint32_t);
|
struct mbuf *, int, int, int);
|
||||||
void (*iv_recv_ctl)(struct ieee80211_node *,
|
void (*iv_recv_ctl)(struct ieee80211_node *,
|
||||||
struct mbuf *, int);
|
struct mbuf *, int);
|
||||||
void (*iv_deliver_data)(struct ieee80211vap *,
|
void (*iv_deliver_data)(struct ieee80211vap *,
|
||||||
@ -522,6 +529,7 @@ MALLOC_DECLARE(M_80211_VAP);
|
|||||||
#define IEEE80211_FEXT_DOTD 0x00001000 /* CONF: 11d enabled */
|
#define IEEE80211_FEXT_DOTD 0x00001000 /* CONF: 11d enabled */
|
||||||
#define IEEE80211_FEXT_STATEWAIT 0x00002000 /* STATUS: awaiting state chg */
|
#define IEEE80211_FEXT_STATEWAIT 0x00002000 /* STATUS: awaiting state chg */
|
||||||
#define IEEE80211_FEXT_REINIT 0x00004000 /* STATUS: INIT state first */
|
#define IEEE80211_FEXT_REINIT 0x00004000 /* STATUS: INIT state first */
|
||||||
|
#define IEEE80211_FEXT_BPF 0x00008000 /* STATUS: BPF tap present */
|
||||||
/* NB: immutable: should be set only when creating a vap */
|
/* NB: immutable: should be set only when creating a vap */
|
||||||
#define IEEE80211_FEXT_WDSLEGACY 0x00010000 /* CONF: legacy WDS operation */
|
#define IEEE80211_FEXT_WDSLEGACY 0x00010000 /* CONF: legacy WDS operation */
|
||||||
#define IEEE80211_FEXT_PROBECHAN 0x00020000 /* CONF: probe passive channel*/
|
#define IEEE80211_FEXT_PROBECHAN 0x00020000 /* CONF: probe passive channel*/
|
||||||
@ -540,7 +548,7 @@ MALLOC_DECLARE(M_80211_VAP);
|
|||||||
#define IEEE80211_FEXT_BITS \
|
#define IEEE80211_FEXT_BITS \
|
||||||
"\20\1NONHT_PR\2INACT\3SCANWAIT\4BGSCAN\5WPS\6TSN\7SCANREQ\10RESUME" \
|
"\20\1NONHT_PR\2INACT\3SCANWAIT\4BGSCAN\5WPS\6TSN\7SCANREQ\10RESUME" \
|
||||||
"\0114ADDR\12NONEPR_PR\13SWBMISS\14DFS\15DOTD\16STATEWAIT\17REINIT" \
|
"\0114ADDR\12NONEPR_PR\13SWBMISS\14DFS\15DOTD\16STATEWAIT\17REINIT" \
|
||||||
"\22WDSLEGACY\23PROBECHAN\24HT\25AMDPU_TX\26AMPDU_TX\27AMSDU_TX" \
|
"\20BPF\21WDSLEGACY\22PROBECHAN\24HT\25AMDPU_TX\26AMPDU_TX\27AMSDU_TX" \
|
||||||
"\30AMSDU_RX\31USEHT40\32PUREN\33SHORTGI20\34SHORTGI40\35HTCOMPAT" \
|
"\30AMSDU_RX\31USEHT40\32PUREN\33SHORTGI20\34SHORTGI40\35HTCOMPAT" \
|
||||||
"\36RIFS"
|
"\36RIFS"
|
||||||
|
|
||||||
@ -637,6 +645,31 @@ struct ieee80211_channel *ieee80211_find_channel_byieee(struct ieee80211com *,
|
|||||||
int ieee80211_setmode(struct ieee80211com *, enum ieee80211_phymode);
|
int ieee80211_setmode(struct ieee80211com *, enum ieee80211_phymode);
|
||||||
enum ieee80211_phymode ieee80211_chan2mode(const struct ieee80211_channel *);
|
enum ieee80211_phymode ieee80211_chan2mode(const struct ieee80211_channel *);
|
||||||
|
|
||||||
|
void ieee80211_radiotap_attach(struct ieee80211com *,
|
||||||
|
struct ieee80211_radiotap_header *th, int tlen,
|
||||||
|
uint32_t tx_radiotap,
|
||||||
|
struct ieee80211_radiotap_header *rh, int rlen,
|
||||||
|
uint32_t rx_radiotap);
|
||||||
|
void ieee80211_radiotap_detach(struct ieee80211com *);
|
||||||
|
void ieee80211_radiotap_vattach(struct ieee80211vap *);
|
||||||
|
void ieee80211_radiotap_vdetach(struct ieee80211vap *);
|
||||||
|
void ieee80211_radiotap_chan_change(struct ieee80211com *);
|
||||||
|
void ieee80211_radiotap_tx(struct ieee80211vap *, struct mbuf *);
|
||||||
|
void ieee80211_radiotap_rx(struct ieee80211vap *, struct mbuf *);
|
||||||
|
void ieee80211_radiotap_rx_all(struct ieee80211com *, struct mbuf *);
|
||||||
|
|
||||||
|
static __inline int
|
||||||
|
ieee80211_radiotap_active(const struct ieee80211com *ic)
|
||||||
|
{
|
||||||
|
return (ic->ic_flags_ext & IEEE80211_FEXT_BPF) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline int
|
||||||
|
ieee80211_radiotap_active_vap(const struct ieee80211vap *vap)
|
||||||
|
{
|
||||||
|
return (vap->iv_flags_ext & IEEE80211_FEXT_BPF) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enqueue a task on the state thread.
|
* Enqueue a task on the state thread.
|
||||||
*/
|
*/
|
||||||
|
@ -63,10 +63,9 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
static void wds_vattach(struct ieee80211vap *);
|
static void wds_vattach(struct ieee80211vap *);
|
||||||
static int wds_newstate(struct ieee80211vap *, enum ieee80211_state, int);
|
static int wds_newstate(struct ieee80211vap *, enum ieee80211_state, int);
|
||||||
static int wds_input(struct ieee80211_node *ni, struct mbuf *m,
|
static int wds_input(struct ieee80211_node *ni, struct mbuf *m, int, int);
|
||||||
int rssi, int noise, uint32_t rstamp);
|
|
||||||
static void wds_recv_mgmt(struct ieee80211_node *, struct mbuf *,
|
static void wds_recv_mgmt(struct ieee80211_node *, struct mbuf *,
|
||||||
int subtype, int rssi, int noise, u_int32_t rstamp);
|
int subtype, int, int);
|
||||||
|
|
||||||
void
|
void
|
||||||
ieee80211_wds_attach(struct ieee80211com *ic)
|
ieee80211_wds_attach(struct ieee80211com *ic)
|
||||||
@ -199,12 +198,12 @@ ieee80211_create_wds(struct ieee80211vap *vap, struct ieee80211_channel *chan)
|
|||||||
* Flush pending frames now that were setup.
|
* Flush pending frames now that were setup.
|
||||||
*/
|
*/
|
||||||
if (ni != NULL && IEEE80211_NODE_WDSQ_QLEN(ni) != 0) {
|
if (ni != NULL && IEEE80211_NODE_WDSQ_QLEN(ni) != 0) {
|
||||||
int8_t rssi, noise;
|
int8_t rssi, nf;
|
||||||
|
|
||||||
IEEE80211_NOTE(vap, IEEE80211_MSG_WDS, ni,
|
IEEE80211_NOTE(vap, IEEE80211_MSG_WDS, ni,
|
||||||
"flush wds queue, %u packets queued",
|
"flush wds queue, %u packets queued",
|
||||||
IEEE80211_NODE_WDSQ_QLEN(ni));
|
IEEE80211_NODE_WDSQ_QLEN(ni));
|
||||||
ic->ic_node_getsignal(ni, &rssi, &noise);
|
ic->ic_node_getsignal(ni, &rssi, &nf);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
struct mbuf *m;
|
struct mbuf *m;
|
||||||
|
|
||||||
@ -213,8 +212,7 @@ ieee80211_create_wds(struct ieee80211vap *vap, struct ieee80211_channel *chan)
|
|||||||
IEEE80211_NODE_WDSQ_UNLOCK(ni);
|
IEEE80211_NODE_WDSQ_UNLOCK(ni);
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
break;
|
break;
|
||||||
/* XXX cheat and re-use last rstamp */
|
ieee80211_input(ni, m, rssi, nf);
|
||||||
ieee80211_input(ni, m, rssi, noise, ni->ni_rstamp);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (ni == NULL ? ENOENT : 0);
|
return (ni == NULL ? ENOENT : 0);
|
||||||
@ -292,9 +290,6 @@ ieee80211_dwds_mcast(struct ieee80211vap *vap0, struct mbuf *m)
|
|||||||
mcopy->m_flags |= M_MCAST;
|
mcopy->m_flags |= M_MCAST;
|
||||||
mcopy->m_pkthdr.rcvif = (void *) ni;
|
mcopy->m_pkthdr.rcvif = (void *) ni;
|
||||||
|
|
||||||
if (bpf_peers_present(vap->iv_rawbpf))
|
|
||||||
bpf_mtap(vap->iv_rawbpf, m);
|
|
||||||
|
|
||||||
err = parent->if_transmit(parent, mcopy);
|
err = parent->if_transmit(parent, mcopy);
|
||||||
if (err) {
|
if (err) {
|
||||||
/* NB: IFQ_HANDOFF reclaims mbuf */
|
/* NB: IFQ_HANDOFF reclaims mbuf */
|
||||||
@ -470,8 +465,7 @@ wds_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
|
|||||||
* by the 802.11 layer.
|
* by the 802.11 layer.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
wds_input(struct ieee80211_node *ni, struct mbuf *m,
|
wds_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
|
||||||
int rssi, int noise, uint32_t rstamp)
|
|
||||||
{
|
{
|
||||||
#define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0)
|
#define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0)
|
||||||
#define HAS_SEQ(type) ((type & 0x4) == 0)
|
#define HAS_SEQ(type) ((type & 0x4) == 0)
|
||||||
@ -553,8 +547,7 @@ wds_input(struct ieee80211_node *ni, struct mbuf *m,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
|
IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
|
||||||
ni->ni_noise = noise;
|
ni->ni_noise = nf;
|
||||||
ni->ni_rstamp = rstamp;
|
|
||||||
if (HAS_SEQ(type)) {
|
if (HAS_SEQ(type)) {
|
||||||
uint8_t tid = ieee80211_gettid(wh);
|
uint8_t tid = ieee80211_gettid(wh);
|
||||||
if (IEEE80211_QOS_HAS_SEQ(wh) &&
|
if (IEEE80211_QOS_HAS_SEQ(wh) &&
|
||||||
@ -686,8 +679,8 @@ wds_input(struct ieee80211_node *ni, struct mbuf *m,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* copy to listener after decrypt */
|
/* copy to listener after decrypt */
|
||||||
if (bpf_peers_present(vap->iv_rawbpf))
|
if (ieee80211_radiotap_active_vap(vap))
|
||||||
bpf_mtap(vap->iv_rawbpf, m);
|
ieee80211_radiotap_rx(vap, m);
|
||||||
need_tap = 0;
|
need_tap = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -786,16 +779,14 @@ wds_input(struct ieee80211_node *ni, struct mbuf *m,
|
|||||||
vap->iv_stats.is_rx_mgtdiscard++; /* XXX */
|
vap->iv_stats.is_rx_mgtdiscard++; /* XXX */
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (bpf_peers_present(vap->iv_rawbpf))
|
vap->iv_recv_mgmt(ni, m, subtype, rssi, nf);
|
||||||
bpf_mtap(vap->iv_rawbpf, m);
|
goto out;
|
||||||
vap->iv_recv_mgmt(ni, m, subtype, rssi, noise, rstamp);
|
|
||||||
m_freem(m);
|
|
||||||
return IEEE80211_FC0_TYPE_MGT;
|
|
||||||
|
|
||||||
case IEEE80211_FC0_TYPE_CTL:
|
case IEEE80211_FC0_TYPE_CTL:
|
||||||
vap->iv_stats.is_rx_ctl++;
|
vap->iv_stats.is_rx_ctl++;
|
||||||
IEEE80211_NODE_STAT(ni, rx_ctrl);
|
IEEE80211_NODE_STAT(ni, rx_ctrl);
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
|
IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
|
||||||
wh, "bad", "frame type 0x%x", type);
|
wh, "bad", "frame type 0x%x", type);
|
||||||
@ -806,8 +797,8 @@ err:
|
|||||||
ifp->if_ierrors++;
|
ifp->if_ierrors++;
|
||||||
out:
|
out:
|
||||||
if (m != NULL) {
|
if (m != NULL) {
|
||||||
if (bpf_peers_present(vap->iv_rawbpf) && need_tap)
|
if (need_tap)
|
||||||
bpf_mtap(vap->iv_rawbpf, m);
|
ieee80211_radiotap_rx(vap, m);
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
}
|
}
|
||||||
return type;
|
return type;
|
||||||
@ -816,7 +807,7 @@ out:
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
wds_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
|
wds_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
|
||||||
int subtype, int rssi, int noise, u_int32_t rstamp)
|
int subtype, int rssi, int nf)
|
||||||
{
|
{
|
||||||
struct ieee80211vap *vap = ni->ni_vap;
|
struct ieee80211vap *vap = ni->ni_vap;
|
||||||
struct ieee80211com *ic = ni->ni_ic;
|
struct ieee80211com *ic = ni->ni_ic;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user