aboutsummaryrefslogtreecommitdiff
path: root/sys/net80211
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net80211')
-rw-r--r--sys/net80211/ieee80211.c154
-rw-r--r--sys/net80211/ieee80211.h6
-rw-r--r--sys/net80211/ieee80211_acl.c19
-rw-r--r--sys/net80211/ieee80211_adhoc.c29
-rw-r--r--sys/net80211/ieee80211_amrr.c12
-rw-r--r--sys/net80211/ieee80211_crypto_ccmp.c6
-rw-r--r--sys/net80211/ieee80211_crypto_tkip.c6
-rw-r--r--sys/net80211/ieee80211_crypto_wep.c6
-rw-r--r--sys/net80211/ieee80211_ddb.c1
-rw-r--r--sys/net80211/ieee80211_dfs.c22
-rw-r--r--sys/net80211/ieee80211_freebsd.c126
-rw-r--r--sys/net80211/ieee80211_freebsd.h80
-rw-r--r--sys/net80211/ieee80211_hostap.c21
-rw-r--r--sys/net80211/ieee80211_ht.c17
-rw-r--r--sys/net80211/ieee80211_hwmp.c33
-rw-r--r--sys/net80211/ieee80211_input.c17
-rw-r--r--sys/net80211/ieee80211_input.h1
-rw-r--r--sys/net80211/ieee80211_ioctl.c41
-rw-r--r--sys/net80211/ieee80211_mesh.c75
-rw-r--r--sys/net80211/ieee80211_mesh.h4
-rw-r--r--sys/net80211/ieee80211_monitor.c5
-rw-r--r--sys/net80211/ieee80211_node.c46
-rw-r--r--sys/net80211/ieee80211_output.c28
-rw-r--r--sys/net80211/ieee80211_power.c7
-rw-r--r--sys/net80211/ieee80211_proto.c13
-rw-r--r--sys/net80211/ieee80211_proto.h12
-rw-r--r--sys/net80211/ieee80211_radiotap.c9
-rw-r--r--sys/net80211/ieee80211_ratectl_none.c2
-rw-r--r--sys/net80211/ieee80211_regdomain.c18
-rw-r--r--sys/net80211/ieee80211_rssadapt.c12
-rw-r--r--sys/net80211/ieee80211_scan.c57
-rw-r--r--sys/net80211/ieee80211_scan.h33
-rw-r--r--sys/net80211/ieee80211_scan_sta.c25
-rw-r--r--sys/net80211/ieee80211_scan_sw.c114
-rw-r--r--sys/net80211/ieee80211_scan_sw.h29
-rw-r--r--sys/net80211/ieee80211_sta.c33
-rw-r--r--sys/net80211/ieee80211_superg.c6
-rw-r--r--sys/net80211/ieee80211_tdma.c16
-rw-r--r--sys/net80211/ieee80211_tdma.h3
-rw-r--r--sys/net80211/ieee80211_var.h28
-rw-r--r--sys/net80211/ieee80211_wds.c16
41 files changed, 716 insertions, 472 deletions
diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c
index 2fa7e9affb8e..3902227e8c43 100644
--- a/sys/net80211/ieee80211.c
+++ b/sys/net80211/ieee80211.c
@@ -35,9 +35,10 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
-
#include <sys/socket.h>
+#include <machine/stdarg.h>
+
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_dl.h>
@@ -81,7 +82,7 @@ const int ieee80211_opcap[IEEE80211_OPMODE_MAX] = {
#endif
};
-static const uint8_t ieee80211broadcastaddr[IEEE80211_ADDR_LEN] =
+const uint8_t ieee80211broadcastaddr[IEEE80211_ADDR_LEN] =
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
static void ieee80211_syncflag_locked(struct ieee80211com *ic, int flag);
@@ -94,6 +95,7 @@ static void ieee80211com_media_status(struct ifnet *, struct ifmediareq *);
static int ieee80211com_media_change(struct ifnet *);
static int media_status(enum ieee80211_opmode,
const struct ieee80211_channel *);
+static uint64_t ieee80211_get_counter(struct ifnet *, ift_counter);
MALLOC_DEFINE(M_80211_VAP, "80211vap", "802.11 vap state");
@@ -223,15 +225,17 @@ ieee80211_chan_init(struct ieee80211com *ic)
}
static void
-null_update_mcast(struct ifnet *ifp)
+null_update_mcast(struct ieee80211com *ic)
{
- if_printf(ifp, "need multicast update callback\n");
+
+ ic_printf(ic, "need multicast update callback\n");
}
static void
-null_update_promisc(struct ifnet *ifp)
+null_update_promisc(struct ieee80211com *ic)
{
- if_printf(ifp, "need promiscuous mode update callback\n");
+
+ ic_printf(ic, "need promiscuous mode update callback\n");
}
static int
@@ -242,15 +246,9 @@ null_transmit(struct ifnet *ifp, struct mbuf *m)
return EACCES; /* XXX EIO/EPERM? */
}
-#if __FreeBSD_version >= 1000031
static int
null_output(struct ifnet *ifp, struct mbuf *m,
const struct sockaddr *dst, struct route *ro)
-#else
-static int
-null_output(struct ifnet *ifp, struct mbuf *m,
- struct sockaddr *dst, struct route *ro)
-#endif
{
if_printf(ifp, "discard raw packet\n");
return null_transmit(ifp, m);
@@ -267,7 +265,20 @@ static void
null_update_chw(struct ieee80211com *ic)
{
- if_printf(ic->ic_ifp, "%s: need callback\n", __func__);
+ ic_printf(ic, "%s: need callback\n", __func__);
+}
+
+int
+ic_printf(struct ieee80211com *ic, const char * fmt, ...)
+{
+ va_list ap;
+ int retval;
+
+ retval = printf("%s: ", ic->ic_name);
+ va_start(ap, fmt);
+ retval += vprintf(fmt, ap);
+ va_end(ap);
+ return (retval);
}
/*
@@ -284,15 +295,17 @@ ieee80211_ifattach(struct ieee80211com *ic,
KASSERT(ifp->if_type == IFT_IEEE80211, ("if_type %d", ifp->if_type));
- IEEE80211_LOCK_INIT(ic, ifp->if_xname);
- IEEE80211_TX_LOCK_INIT(ic, ifp->if_xname);
+ IEEE80211_LOCK_INIT(ic, ic->ic_name);
+ IEEE80211_TX_LOCK_INIT(ic, ic->ic_name);
TAILQ_INIT(&ic->ic_vaps);
/* Create a taskqueue for all state changes */
ic->ic_tq = taskqueue_create("ic_taskq", M_WAITOK | M_ZERO,
taskqueue_thread_enqueue, &ic->ic_tq);
taskqueue_start_threads(&ic->ic_tq, 1, PI_NET, "%s net80211 taskq",
- ifp->if_xname);
+ ic->ic_name);
+ ic->ic_ierrors = counter_u64_alloc(M_WAITOK);
+ ic->ic_oerrors = counter_u64_alloc(M_WAITOK);
/*
* Fill in 802.11 available channel set, mark all
* available channels as active, and pick a default
@@ -391,6 +404,8 @@ ieee80211_ifdetach(struct ieee80211com *ic)
/* XXX VNET needed? */
ifmedia_removeall(&ic->ic_media);
+ counter_u64_free(ic->ic_ierrors);
+ counter_u64_free(ic->ic_oerrors);
taskqueue_free(ic->ic_tq);
IEEE80211_TX_LOCK_DESTROY(ic);
@@ -413,6 +428,31 @@ default_reset(struct ieee80211vap *vap, u_long cmd)
}
/*
+ * Add underlying device errors to vap errors.
+ */
+static uint64_t
+ieee80211_get_counter(struct ifnet *ifp, ift_counter cnt)
+{
+ struct ieee80211vap *vap = ifp->if_softc;
+ struct ieee80211com *ic = vap->iv_ic;
+ uint64_t rv;
+
+ rv = if_get_counter_default(ifp, cnt);
+ switch (cnt) {
+ case IFCOUNTER_OERRORS:
+ rv += counter_u64_fetch(ic->ic_oerrors);
+ break;
+ case IFCOUNTER_IERRORS:
+ rv += counter_u64_fetch(ic->ic_ierrors);
+ break;
+ default:
+ break;
+ }
+
+ return (rv);
+}
+
+/*
* Prepare a vap for use. Drivers use this call to
* setup net80211 state in new vap's prior attaching
* them with ieee80211_vap_attach (below).
@@ -427,7 +467,7 @@ ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap,
ifp = if_alloc(IFT_ETHER);
if (ifp == NULL) {
- if_printf(ic->ic_ifp, "%s: unable to allocate ifnet\n",
+ ic_printf(ic, "%s: unable to allocate ifnet\n",
__func__);
return ENOMEM;
}
@@ -438,6 +478,7 @@ ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap,
ifp->if_qflush = ieee80211_vap_qflush;
ifp->if_ioctl = ieee80211_ioctl;
ifp->if_init = ieee80211_init;
+ ifp->if_get_counter = ieee80211_get_counter;
vap->iv_ifp = ifp;
vap->iv_ic = ic;
@@ -551,7 +592,7 @@ ieee80211_vap_attach(struct ieee80211vap *vap,
IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE,
"%s: %s parent %s flags 0x%x flags_ext 0x%x\n",
__func__, ieee80211_opmode_name[vap->iv_opmode],
- ic->ic_ifp->if_xname, vap->iv_flags, vap->iv_flags_ext);
+ ic->ic_name, vap->iv_flags, vap->iv_flags_ext);
/*
* Do late attach work that cannot happen until after
@@ -607,8 +648,7 @@ ieee80211_vap_detach(struct ieee80211vap *vap)
CURVNET_SET(ifp->if_vnet);
IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s parent %s\n",
- __func__, ieee80211_opmode_name[vap->iv_opmode],
- ic->ic_ifp->if_xname);
+ __func__, ieee80211_opmode_name[vap->iv_opmode], ic->ic_name);
/* NB: bpfdetach is called by ether_ifdetach and claims all taps */
ether_ifdetach(ifp);
@@ -900,7 +940,7 @@ int
ieee80211_chan2ieee(struct ieee80211com *ic, const struct ieee80211_channel *c)
{
if (c == NULL) {
- if_printf(ic->ic_ifp, "invalid channel (NULL)\n");
+ ic_printf(ic, "invalid channel (NULL)\n");
return 0; /* XXX */
}
return (c == IEEE80211_CHAN_ANYC ? IEEE80211_CHAN_ANY : c->ic_ieee);
@@ -991,6 +1031,75 @@ ieee80211_find_channel_byieee(struct ieee80211com *ic, int ieee, int flags)
return NULL;
}
+/*
+ * Lookup a channel suitable for the given rx status.
+ *
+ * This is used to find a channel for a frame (eg beacon, probe
+ * response) based purely on the received PHY information.
+ *
+ * For now it tries to do it based on R_FREQ / R_IEEE.
+ * This is enough for 11bg and 11a (and thus 11ng/11na)
+ * but it will not be enough for GSM, PSB channels and the
+ * like. It also doesn't know about legacy-turbog and
+ * legacy-turbo modes, which some offload NICs actually
+ * support in weird ways.
+ *
+ * Takes the ic and rxstatus; returns the channel or NULL
+ * if not found.
+ *
+ * XXX TODO: Add support for that when the need arises.
+ */
+struct ieee80211_channel *
+ieee80211_lookup_channel_rxstatus(struct ieee80211vap *vap,
+ const struct ieee80211_rx_stats *rxs)
+{
+ struct ieee80211com *ic = vap->iv_ic;
+ uint32_t flags;
+ struct ieee80211_channel *c;
+
+ if (rxs == NULL)
+ return (NULL);
+
+ /*
+ * Strictly speaking we only use freq for now,
+ * however later on we may wish to just store
+ * the ieee for verification.
+ */
+ if ((rxs->r_flags & IEEE80211_R_FREQ) == 0)
+ return (NULL);
+ if ((rxs->r_flags & IEEE80211_R_IEEE) == 0)
+ return (NULL);
+
+ /*
+ * If the rx status contains a valid ieee/freq, then
+ * ensure we populate the correct channel information
+ * in rxchan before passing it up to the scan infrastructure.
+ * Offload NICs will pass up beacons from all channels
+ * during background scans.
+ */
+
+ /* Determine a band */
+ /* XXX should be done by the driver? */
+ if (rxs->c_freq < 3000) {
+ flags = IEEE80211_CHAN_G;
+ } else {
+ flags = IEEE80211_CHAN_A;
+ }
+
+ /* Channel lookup */
+ c = ieee80211_find_channel(ic, rxs->c_freq, flags);
+
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_INPUT,
+ "%s: freq=%d, ieee=%d, flags=0x%08x; c=%p\n",
+ __func__,
+ (int) rxs->c_freq,
+ (int) rxs->c_ieee,
+ flags,
+ c);
+
+ return (c);
+}
+
static void
addmedia(struct ifmedia *media, int caps, int addsta, int mode, int mword)
{
@@ -1169,7 +1278,6 @@ ieee80211_get_suprates(struct ieee80211com *ic, const struct ieee80211_channel *
void
ieee80211_announce(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
int i, rate, mword;
enum ieee80211_phymode mode;
const struct ieee80211_rateset *rs;
@@ -1178,7 +1286,7 @@ ieee80211_announce(struct ieee80211com *ic)
for (mode = IEEE80211_MODE_AUTO+1; mode < IEEE80211_MODE_11NA; mode++) {
if (isclr(ic->ic_modecaps, mode))
continue;
- if_printf(ifp, "%s rates: ", ieee80211_phymode_name[mode]);
+ ic_printf(ic, "%s rates: ", ieee80211_phymode_name[mode]);
rs = &ic->ic_sup_rates[mode];
for (i = 0; i < rs->rs_nrates; i++) {
mword = ieee80211_rate2media(ic, rs->rs_rates[i], mode);
diff --git a/sys/net80211/ieee80211.h b/sys/net80211/ieee80211.h
index 8e586bdd0152..64d0754f358d 100644
--- a/sys/net80211/ieee80211.h
+++ b/sys/net80211/ieee80211.h
@@ -36,6 +36,10 @@
/* is 802.11 address multicast/broadcast? */
#define IEEE80211_IS_MULTICAST(_a) (*(_a) & 0x01)
+#ifdef _KERNEL
+extern const uint8_t ieee80211broadcastaddr[];
+#endif
+
typedef uint16_t ieee80211_seq;
/* IEEE 802.11 PLCP header */
@@ -812,7 +816,7 @@ struct ieee80211_csa_ie {
#define IEEE80211_RATE_BASIC 0x80
#define IEEE80211_RATE_VAL 0x7f
-/* EPR information element flags */
+/* ERP information element flags */
#define IEEE80211_ERP_NON_ERP_PRESENT 0x01
#define IEEE80211_ERP_USE_PROTECTION 0x02
#define IEEE80211_ERP_LONG_PREAMBLE 0x04
diff --git a/sys/net80211/ieee80211_acl.c b/sys/net80211/ieee80211_acl.c
index ac604fb09206..eeb7f0bc68da 100644
--- a/sys/net80211/ieee80211_acl.c
+++ b/sys/net80211/ieee80211_acl.c
@@ -99,8 +99,8 @@ acl_attach(struct ieee80211vap *vap)
{
struct aclstate *as;
- as = (struct aclstate *) malloc(sizeof(struct aclstate),
- M_80211_ACL, M_NOWAIT | M_ZERO);
+ as = (struct aclstate *) IEEE80211_MALLOC(sizeof(struct aclstate),
+ M_80211_ACL, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (as == NULL)
return 0;
ACL_LOCK_INIT(as, "acl");
@@ -123,7 +123,7 @@ acl_detach(struct ieee80211vap *vap)
acl_free_all(vap);
vap->iv_as = NULL;
ACL_LOCK_DESTROY(as);
- free(as, M_80211_ACL);
+ IEEE80211_FREE(as, M_80211_ACL);
}
static __inline struct acl *
@@ -147,7 +147,7 @@ _acl_free(struct aclstate *as, struct acl *acl)
TAILQ_REMOVE(&as->as_list, acl, acl_list);
LIST_REMOVE(acl, acl_hash);
- free(acl, M_80211_ACL);
+ IEEE80211_FREE(acl, M_80211_ACL);
as->as_nacls--;
}
@@ -175,7 +175,8 @@ acl_add(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
struct acl *acl, *new;
int hash;
- new = (struct acl *) malloc(sizeof(struct acl), M_80211_ACL, M_NOWAIT | M_ZERO);
+ new = (struct acl *) IEEE80211_MALLOC(sizeof(struct acl),
+ M_80211_ACL, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (new == NULL) {
IEEE80211_DPRINTF(vap, IEEE80211_MSG_ACL,
"ACL: add %s failed, no memory\n", ether_sprintf(mac));
@@ -188,7 +189,7 @@ acl_add(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
LIST_FOREACH(acl, &as->as_hash[hash], acl_hash) {
if (IEEE80211_ADDR_EQ(acl->acl_macaddr, mac)) {
ACL_UNLOCK(as);
- free(new, M_80211_ACL);
+ IEEE80211_FREE(new, M_80211_ACL);
IEEE80211_DPRINTF(vap, IEEE80211_MSG_ACL,
"ACL: add %s failed, already present\n",
ether_sprintf(mac));
@@ -302,8 +303,8 @@ acl_getioctl(struct ieee80211vap *vap, struct ieee80211req *ireq)
ireq->i_len = space; /* return required space */
return 0; /* NB: must not error */
}
- ap = (struct ieee80211req_maclist *) malloc(space,
- M_TEMP, M_NOWAIT);
+ ap = (struct ieee80211req_maclist *) IEEE80211_MALLOC(space,
+ M_TEMP, IEEE80211_M_NOWAIT);
if (ap == NULL)
return ENOMEM;
i = 0;
@@ -318,7 +319,7 @@ acl_getioctl(struct ieee80211vap *vap, struct ieee80211req *ireq)
ireq->i_len = space;
} else
error = copyout(ap, ireq->i_data, ireq->i_len);
- free(ap, M_TEMP);
+ IEEE80211_FREE(ap, M_TEMP);
return error;
}
return EINVAL;
diff --git a/sys/net80211/ieee80211_adhoc.c b/sys/net80211/ieee80211_adhoc.c
index 0d761c4af985..d31ad9be0de6 100644
--- a/sys/net80211/ieee80211_adhoc.c
+++ b/sys/net80211/ieee80211_adhoc.c
@@ -70,11 +70,12 @@ __FBSDID("$FreeBSD$");
static void adhoc_vattach(struct ieee80211vap *);
static int adhoc_newstate(struct ieee80211vap *, enum ieee80211_state, int);
-static int adhoc_input(struct ieee80211_node *, struct mbuf *, int, int);
+static int adhoc_input(struct ieee80211_node *, struct mbuf *,
+ const struct ieee80211_rx_stats *, int, int);
static void adhoc_recv_mgmt(struct ieee80211_node *, struct mbuf *,
- int subtype, int, int);
+ int subtype, const struct ieee80211_rx_stats *, int, int);
static void ahdemo_recv_mgmt(struct ieee80211_node *, struct mbuf *,
- int subtype, int, int);
+ int subtype, const struct ieee80211_rx_stats *rxs, int, int);
static void adhoc_recv_ctl(struct ieee80211_node *, struct mbuf *, int subtype);
void
@@ -289,7 +290,8 @@ doprint(struct ieee80211vap *vap, int subtype)
* by the 802.11 layer.
*/
static int
-adhoc_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
+adhoc_input(struct ieee80211_node *ni, struct mbuf *m,
+ const struct ieee80211_rx_stats *rxs, int rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
@@ -642,7 +644,7 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
vap->iv_stats.is_rx_mgtdiscard++; /* XXX */
goto out;
}
- vap->iv_recv_mgmt(ni, m, subtype, rssi, nf);
+ vap->iv_recv_mgmt(ni, m, subtype, rxs, rssi, nf);
goto out;
case IEEE80211_FC0_TYPE_CTL:
@@ -687,10 +689,11 @@ is11bclient(const uint8_t *rates, const uint8_t *xrates)
static void
adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
- int subtype, int rssi, int nf)
+ int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
+ struct ieee80211_channel *rxchan = ic->ic_curchan;
struct ieee80211_frame *wh;
uint8_t *frm, *efrm, *sfrm;
uint8_t *ssid, *rates, *xrates;
@@ -705,11 +708,17 @@ adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
case IEEE80211_FC0_SUBTYPE_BEACON: {
struct ieee80211_scanparams scan;
+ struct ieee80211_channel *c;
/*
* We process beacon/probe response
* frames to discover neighbors.
*/
- if (ieee80211_parse_beacon(ni, m0, &scan) != 0)
+ if (rxs != NULL) {
+ c = ieee80211_lookup_channel_rxstatus(vap, rxs);
+ if (c != NULL)
+ rxchan = c;
+ }
+ if (ieee80211_parse_beacon(ni, m0, rxchan, &scan) != 0)
return;
/*
* Count frame now that we know it's to be processed.
@@ -735,7 +744,7 @@ adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
ieee80211_probe_curchan(vap, 1);
ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN;
}
- ieee80211_add_scan(vap, ic->ic_curchan, &scan, wh,
+ ieee80211_add_scan(vap, rxchan, &scan, wh,
subtype, rssi, nf);
return;
}
@@ -911,7 +920,7 @@ adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
static void
ahdemo_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
- int subtype, int rssi, int nf)
+ int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
@@ -922,7 +931,7 @@ ahdemo_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
* a site-survey.
*/
if (ic->ic_flags & IEEE80211_F_SCAN)
- adhoc_recv_mgmt(ni, m0, subtype, rssi, nf);
+ adhoc_recv_mgmt(ni, m0, subtype, rxs, rssi, nf);
else {
wh = mtod(m0, struct ieee80211_frame *);
switch (subtype) {
diff --git a/sys/net80211/ieee80211_amrr.c b/sys/net80211/ieee80211_amrr.c
index b1d92c880fc0..b7c11fd2417b 100644
--- a/sys/net80211/ieee80211_amrr.c
+++ b/sys/net80211/ieee80211_amrr.c
@@ -113,8 +113,8 @@ amrr_init(struct ieee80211vap *vap)
KASSERT(vap->iv_rs == NULL, ("%s called multiple times", __func__));
- amrr = vap->iv_rs = malloc(sizeof(struct ieee80211_amrr),
- M_80211_RATECTL, M_NOWAIT|M_ZERO);
+ amrr = vap->iv_rs = IEEE80211_MALLOC(sizeof(struct ieee80211_amrr),
+ M_80211_RATECTL, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (amrr == NULL) {
if_printf(vap->iv_ifp, "couldn't alloc ratectl structure\n");
return;
@@ -128,7 +128,7 @@ amrr_init(struct ieee80211vap *vap)
static void
amrr_deinit(struct ieee80211vap *vap)
{
- free(vap->iv_rs, M_80211_RATECTL);
+ IEEE80211_FREE(vap->iv_rs, M_80211_RATECTL);
}
/*
@@ -160,8 +160,8 @@ amrr_node_init(struct ieee80211_node *ni)
uint8_t rate;
if (ni->ni_rctls == NULL) {
- ni->ni_rctls = amn = malloc(sizeof(struct ieee80211_amrr_node),
- M_80211_RATECTL, M_NOWAIT|M_ZERO);
+ ni->ni_rctls = amn = IEEE80211_MALLOC(sizeof(struct ieee80211_amrr_node),
+ M_80211_RATECTL, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (amn == NULL) {
if_printf(vap->iv_ifp, "couldn't alloc per-node ratectl "
"structure\n");
@@ -225,7 +225,7 @@ amrr_node_init(struct ieee80211_node *ni)
static void
amrr_node_deinit(struct ieee80211_node *ni)
{
- free(ni->ni_rctls, M_80211_RATECTL);
+ IEEE80211_FREE(ni->ni_rctls, M_80211_RATECTL);
}
static int
diff --git a/sys/net80211/ieee80211_crypto_ccmp.c b/sys/net80211/ieee80211_crypto_ccmp.c
index cb9ed0af0149..89ca6d07e8e7 100644
--- a/sys/net80211/ieee80211_crypto_ccmp.c
+++ b/sys/net80211/ieee80211_crypto_ccmp.c
@@ -96,8 +96,8 @@ ccmp_attach(struct ieee80211vap *vap, struct ieee80211_key *k)
{
struct ccmp_ctx *ctx;
- ctx = (struct ccmp_ctx *) malloc(sizeof(struct ccmp_ctx),
- M_80211_CRYPTO, M_NOWAIT | M_ZERO);
+ ctx = (struct ccmp_ctx *) IEEE80211_MALLOC(sizeof(struct ccmp_ctx),
+ M_80211_CRYPTO, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (ctx == NULL) {
vap->iv_stats.is_crypto_nomem++;
return NULL;
@@ -113,7 +113,7 @@ ccmp_detach(struct ieee80211_key *k)
{
struct ccmp_ctx *ctx = k->wk_private;
- free(ctx, M_80211_CRYPTO);
+ IEEE80211_FREE(ctx, M_80211_CRYPTO);
KASSERT(nrefs > 0, ("imbalanced attach/detach"));
nrefs--; /* NB: we assume caller locking */
}
diff --git a/sys/net80211/ieee80211_crypto_tkip.c b/sys/net80211/ieee80211_crypto_tkip.c
index 05d9c74bdf28..c6d2f541c87a 100644
--- a/sys/net80211/ieee80211_crypto_tkip.c
+++ b/sys/net80211/ieee80211_crypto_tkip.c
@@ -109,8 +109,8 @@ tkip_attach(struct ieee80211vap *vap, struct ieee80211_key *k)
{
struct tkip_ctx *ctx;
- ctx = (struct tkip_ctx *) malloc(sizeof(struct tkip_ctx),
- M_80211_CRYPTO, M_NOWAIT | M_ZERO);
+ ctx = (struct tkip_ctx *) IEEE80211_MALLOC(sizeof(struct tkip_ctx),
+ M_80211_CRYPTO, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (ctx == NULL) {
vap->iv_stats.is_crypto_nomem++;
return NULL;
@@ -126,7 +126,7 @@ tkip_detach(struct ieee80211_key *k)
{
struct tkip_ctx *ctx = k->wk_private;
- free(ctx, M_80211_CRYPTO);
+ IEEE80211_FREE(ctx, M_80211_CRYPTO);
KASSERT(nrefs > 0, ("imbalanced attach/detach"));
nrefs--; /* NB: we assume caller locking */
}
diff --git a/sys/net80211/ieee80211_crypto_wep.c b/sys/net80211/ieee80211_crypto_wep.c
index 07c1797571a2..587cf39ce35d 100644
--- a/sys/net80211/ieee80211_crypto_wep.c
+++ b/sys/net80211/ieee80211_crypto_wep.c
@@ -87,8 +87,8 @@ wep_attach(struct ieee80211vap *vap, struct ieee80211_key *k)
{
struct wep_ctx *ctx;
- ctx = (struct wep_ctx *) malloc(sizeof(struct wep_ctx),
- M_80211_CRYPTO, M_NOWAIT | M_ZERO);
+ ctx = (struct wep_ctx *) IEEE80211_MALLOC(sizeof(struct wep_ctx),
+ M_80211_CRYPTO, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (ctx == NULL) {
vap->iv_stats.is_crypto_nomem++;
return NULL;
@@ -106,7 +106,7 @@ wep_detach(struct ieee80211_key *k)
{
struct wep_ctx *ctx = k->wk_private;
- free(ctx, M_80211_CRYPTO);
+ IEEE80211_FREE(ctx, M_80211_CRYPTO);
KASSERT(nrefs > 0, ("imbalanced attach/detach"));
nrefs--; /* NB: we assume caller locking */
}
diff --git a/sys/net80211/ieee80211_ddb.c b/sys/net80211/ieee80211_ddb.c
index 74e82e545135..e646cf2b7417 100644
--- a/sys/net80211/ieee80211_ddb.c
+++ b/sys/net80211/ieee80211_ddb.c
@@ -521,6 +521,7 @@ _db_show_com(const struct ieee80211com *ic, int showvaps, int showsta,
db_printf(" %s(%p)", vap->iv_ifp->if_xname, vap);
db_printf("\n");
db_printf("\tifp %p(%s)", ic->ic_ifp, ic->ic_ifp->if_xname);
+ db_printf("\tname %s", ic->ic_name);
db_printf(" comlock %p", &ic->ic_comlock);
db_printf("\n");
db_printf("\theadroom %d", ic->ic_headroom);
diff --git a/sys/net80211/ieee80211_dfs.c b/sys/net80211/ieee80211_dfs.c
index 5fa9ba4b5c3a..232ceb7c6c0e 100644
--- a/sys/net80211/ieee80211_dfs.c
+++ b/sys/net80211/ieee80211_dfs.c
@@ -253,8 +253,8 @@ dfs_timeout(void *arg)
* msg instead of one for every channel
* table entry.
*/
- if_printf(ic->ic_ifp, "radar on channel"
- " %u (%u MHz) cleared after timeout\n",
+ ic_printf(ic, "radar on channel %u "
+ "(%u MHz) cleared after timeout\n",
c->ic_ieee, c->ic_freq);
/* notify user space */
c->ic_state &=
@@ -272,14 +272,14 @@ dfs_timeout(void *arg)
}
static void
-announce_radar(struct ifnet *ifp, const struct ieee80211_channel *curchan,
+announce_radar(struct ieee80211com *ic, const struct ieee80211_channel *curchan,
const struct ieee80211_channel *newchan)
{
if (newchan == NULL)
- if_printf(ifp, "radar detected on channel %u (%u MHz)\n",
+ ic_printf(ic, "radar detected on channel %u (%u MHz)\n",
curchan->ic_ieee, curchan->ic_freq);
else
- if_printf(ifp, "radar detected on channel %u (%u MHz), "
+ ic_printf(ic, "radar detected on channel %u (%u MHz), "
"moving to channel %u (%u MHz)\n",
curchan->ic_ieee, curchan->ic_freq,
newchan->ic_ieee, newchan->ic_freq);
@@ -309,7 +309,7 @@ ieee80211_dfs_notify_radar(struct ieee80211com *ic, struct ieee80211_channel *ch
* along merrily.
*/
if (ieee80211_dfs_debug == DFS_DBG_NOCSANOL) {
- announce_radar(ic->ic_ifp, chan, chan);
+ announce_radar(ic, chan, chan);
ieee80211_notify_radar(ic, chan);
return;
}
@@ -364,7 +364,7 @@ ieee80211_dfs_notify_radar(struct ieee80211com *ic, struct ieee80211_channel *ch
else
dfs->newchan = chan;
- announce_radar(ic->ic_ifp, chan, dfs->newchan);
+ announce_radar(ic, chan, dfs->newchan);
if (callout_pending(&dfs->cac_timer))
callout_schedule(&dfs->cac_timer, 0);
@@ -380,7 +380,7 @@ ieee80211_dfs_notify_radar(struct ieee80211com *ic, struct ieee80211_channel *ch
* on the NOL to expire.
*/
/*XXX*/
- if_printf(ic->ic_ifp, "%s: No free channels; waiting for entry "
+ ic_printf(ic, "%s: No free channels; waiting for entry "
"on NOL to expire\n", __func__);
}
} else {
@@ -390,9 +390,9 @@ ieee80211_dfs_notify_radar(struct ieee80211com *ic, struct ieee80211_channel *ch
if (dfs->lastchan != chan) {
dfs->lastchan = chan;
dfs->cureps = 0;
- announce_radar(ic->ic_ifp, chan, NULL);
+ announce_radar(ic, chan, NULL);
} else if (ppsratecheck(&dfs->lastevent, &dfs->cureps, 1)) {
- announce_radar(ic->ic_ifp, chan, NULL);
+ announce_radar(ic, chan, NULL);
}
}
}
@@ -434,6 +434,6 @@ ieee80211_dfs_pickchannel(struct ieee80211com *ic)
(c->ic_flags & flags) == flags)
return c;
}
- if_printf(ic->ic_ifp, "HELP, no channel located to switch to!\n");
+ ic_printf(ic, "HELP, no channel located to switch to!\n");
return NULL;
}
diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c
index 7a2abf85a23f..3af75dfc78c0 100644
--- a/sys/net80211/ieee80211_freebsd.c
+++ b/sys/net80211/ieee80211_freebsd.c
@@ -66,10 +66,8 @@ SYSCTL_INT(_net_wlan, OID_AUTO, debug, CTLFLAG_RW, &ieee80211_debug,
static MALLOC_DEFINE(M_80211_COM, "80211com", "802.11 com state");
-#if __FreeBSD_version >= 1000020
static const char wlanname[] = "wlan";
static struct if_clone *wlan_cloner;
-#endif
/*
* Allocate/free com structure in conjunction with ifnet;
@@ -82,7 +80,8 @@ wlan_alloc(u_char type, struct ifnet *ifp)
{
struct ieee80211com *ic;
- ic = malloc(sizeof(struct ieee80211com), M_80211_COM, M_WAITOK|M_ZERO);
+ ic = IEEE80211_MALLOC(sizeof(struct ieee80211com), M_80211_COM,
+ IEEE80211_M_WAITOK | IEEE80211_M_ZERO);
ic->ic_ifp = ifp;
return (ic);
@@ -91,7 +90,7 @@ wlan_alloc(u_char type, struct ifnet *ifp)
static void
wlan_free(void *ic, u_char type)
{
- free(ic, M_80211_COM);
+ IEEE80211_FREE(ic, M_80211_COM);
}
static int
@@ -135,18 +134,10 @@ wlan_clone_create(struct if_clone *ifc, int unit, caddr_t params)
if_printf(ifp, "TDMA not supported\n");
return EOPNOTSUPP;
}
-#if __FreeBSD_version >= 1000020
vap = ic->ic_vap_create(ic, wlanname, unit,
cp.icp_opmode, cp.icp_flags, cp.icp_bssid,
cp.icp_flags & IEEE80211_CLONE_MACADDR ?
cp.icp_macaddr : (const uint8_t *)IF_LLADDR(ifp));
-#else
- vap = ic->ic_vap_create(ic, ifc->ifc_name, unit,
- cp.icp_opmode, cp.icp_flags, cp.icp_bssid,
- cp.icp_flags & IEEE80211_CLONE_MACADDR ?
- cp.icp_macaddr : (const uint8_t *)IF_LLADDR(ifp));
-
-#endif
return (vap == NULL ? EIO : 0);
}
@@ -160,19 +151,11 @@ wlan_clone_destroy(struct ifnet *ifp)
ic->ic_vap_delete(vap);
}
-#if __FreeBSD_version < 1000020
-IFC_SIMPLE_DECLARE(wlan, 0);
-#endif
-
void
ieee80211_vap_destroy(struct ieee80211vap *vap)
{
CURVNET_SET(vap->iv_ifp->if_vnet);
-#if __FreeBSD_version >= 1000020
if_clone_destroyif(wlan_cloner, vap->iv_ifp);
-#else
- if_clone_destroyif(&wlan_cloner, vap->iv_ifp);
-#endif
CURVNET_RESTORE();
}
@@ -207,9 +190,8 @@ static int
ieee80211_sysctl_parent(SYSCTL_HANDLER_ARGS)
{
struct ieee80211com *ic = arg1;
- const char *name = ic->ic_ifp->if_xname;
- return SYSCTL_OUT_STR(req, name);
+ return SYSCTL_OUT_STR(req, ic->ic_name);
}
static int
@@ -245,8 +227,8 @@ ieee80211_sysctl_vattach(struct ieee80211vap *vap)
struct sysctl_oid *oid;
char num[14]; /* sufficient for 32 bits */
- ctx = (struct sysctl_ctx_list *) malloc(sizeof(struct sysctl_ctx_list),
- M_DEVBUF, M_NOWAIT | M_ZERO);
+ ctx = (struct sysctl_ctx_list *) IEEE80211_MALLOC(sizeof(struct sysctl_ctx_list),
+ M_DEVBUF, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (ctx == NULL) {
if_printf(ifp, "%s: cannot allocate sysctl context!\n",
__func__);
@@ -321,7 +303,7 @@ ieee80211_sysctl_vdetach(struct ieee80211vap *vap)
if (vap->iv_sysctl != NULL) {
sysctl_ctx_free(vap->iv_sysctl);
- free(vap->iv_sysctl, M_DEVBUF);
+ IEEE80211_FREE(vap->iv_sysctl, M_DEVBUF);
vap->iv_sysctl = NULL;
}
}
@@ -492,6 +474,40 @@ ieee80211_add_callback(struct mbuf *m,
return 1;
}
+int
+ieee80211_add_xmit_params(struct mbuf *m,
+ const struct ieee80211_bpf_params *params)
+{
+ struct m_tag *mtag;
+ struct ieee80211_tx_params *tx;
+
+ mtag = m_tag_alloc(MTAG_ABI_NET80211, NET80211_TAG_XMIT_PARAMS,
+ sizeof(struct ieee80211_tx_params), M_NOWAIT);
+ if (mtag == NULL)
+ return (0);
+
+ tx = (struct ieee80211_tx_params *)(mtag+1);
+ memcpy(&tx->params, params, sizeof(struct ieee80211_bpf_params));
+ m_tag_prepend(m, mtag);
+ return (1);
+}
+
+int
+ieee80211_get_xmit_params(struct mbuf *m,
+ struct ieee80211_bpf_params *params)
+{
+ struct m_tag *mtag;
+ struct ieee80211_tx_params *tx;
+
+ mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_XMIT_PARAMS,
+ NULL);
+ if (mtag == NULL)
+ return (-1);
+ tx = (struct ieee80211_tx_params *)(mtag + 1);
+ memcpy(params, &tx->params, sizeof(struct ieee80211_bpf_params));
+ return (0);
+}
+
void
ieee80211_process_callback(struct ieee80211_node *ni,
struct mbuf *m, int status)
@@ -694,8 +710,9 @@ void
ieee80211_notify_csa(struct ieee80211com *ic,
const struct ieee80211_channel *c, int mode, int count)
{
- struct ifnet *ifp = ic->ic_ifp;
struct ieee80211_csa_event iev;
+ struct ieee80211vap *vap;
+ struct ifnet *ifp;
memset(&iev, 0, sizeof(iev));
iev.iev_flags = c->ic_flags;
@@ -703,42 +720,53 @@ ieee80211_notify_csa(struct ieee80211com *ic,
iev.iev_ieee = c->ic_ieee;
iev.iev_mode = mode;
iev.iev_count = count;
- CURVNET_SET(ifp->if_vnet);
- rt_ieee80211msg(ifp, RTM_IEEE80211_CSA, &iev, sizeof(iev));
- CURVNET_RESTORE();
+ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
+ ifp = vap->iv_ifp;
+ CURVNET_SET(ifp->if_vnet);
+ rt_ieee80211msg(ifp, RTM_IEEE80211_CSA, &iev, sizeof(iev));
+ CURVNET_RESTORE();
+ }
}
void
ieee80211_notify_radar(struct ieee80211com *ic,
const struct ieee80211_channel *c)
{
- struct ifnet *ifp = ic->ic_ifp;
struct ieee80211_radar_event iev;
+ struct ieee80211vap *vap;
+ struct ifnet *ifp;
memset(&iev, 0, sizeof(iev));
iev.iev_flags = c->ic_flags;
iev.iev_freq = c->ic_freq;
iev.iev_ieee = c->ic_ieee;
- CURVNET_SET(ifp->if_vnet);
- rt_ieee80211msg(ifp, RTM_IEEE80211_RADAR, &iev, sizeof(iev));
- CURVNET_RESTORE();
+ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
+ ifp = vap->iv_ifp;
+ CURVNET_SET(ifp->if_vnet);
+ rt_ieee80211msg(ifp, RTM_IEEE80211_RADAR, &iev, sizeof(iev));
+ CURVNET_RESTORE();
+ }
}
void
ieee80211_notify_cac(struct ieee80211com *ic,
const struct ieee80211_channel *c, enum ieee80211_notify_cac_event type)
{
- struct ifnet *ifp = ic->ic_ifp;
struct ieee80211_cac_event iev;
+ struct ieee80211vap *vap;
+ struct ifnet *ifp;
memset(&iev, 0, sizeof(iev));
iev.iev_flags = c->ic_flags;
iev.iev_freq = c->ic_freq;
iev.iev_ieee = c->ic_ieee;
iev.iev_type = type;
- CURVNET_SET(ifp->if_vnet);
- rt_ieee80211msg(ifp, RTM_IEEE80211_CAC, &iev, sizeof(iev));
- CURVNET_RESTORE();
+ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
+ ifp = vap->iv_ifp;
+ CURVNET_SET(ifp->if_vnet);
+ rt_ieee80211msg(ifp, RTM_IEEE80211_CAC, &iev, sizeof(iev));
+ CURVNET_RESTORE();
+ }
}
void
@@ -782,14 +810,18 @@ ieee80211_notify_country(struct ieee80211vap *vap,
void
ieee80211_notify_radio(struct ieee80211com *ic, int state)
{
- struct ifnet *ifp = ic->ic_ifp;
struct ieee80211_radio_event iev;
+ struct ieee80211vap *vap;
+ struct ifnet *ifp;
memset(&iev, 0, sizeof(iev));
iev.iev_state = state;
- CURVNET_SET(ifp->if_vnet);
- rt_ieee80211msg(ifp, RTM_IEEE80211_RADIO, &iev, sizeof(iev));
- CURVNET_RESTORE();
+ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
+ ifp = vap->iv_ifp;
+ CURVNET_SET(ifp->if_vnet);
+ rt_ieee80211msg(ifp, RTM_IEEE80211_RADIO, &iev, sizeof(iev));
+ CURVNET_RESTORE();
+ }
}
void
@@ -875,21 +907,13 @@ wlan_modevent(module_t mod, int type, void *unused)
bpf_track, 0, EVENTHANDLER_PRI_ANY);
wlan_ifllevent = EVENTHANDLER_REGISTER(iflladdr_event,
wlan_iflladdr, NULL, EVENTHANDLER_PRI_ANY);
-#if __FreeBSD_version >= 1000020
wlan_cloner = if_clone_simple(wlanname, wlan_clone_create,
wlan_clone_destroy, 0);
-#else
- if_clone_attach(&wlan_cloner);
-#endif
if_register_com_alloc(IFT_IEEE80211, wlan_alloc, wlan_free);
return 0;
case MOD_UNLOAD:
if_deregister_com_alloc(IFT_IEEE80211);
-#if __FreeBSD_version >= 1000020
if_clone_detach(wlan_cloner);
-#else
- if_clone_detach(&wlan_cloner);
-#endif
EVENTHANDLER_DEREGISTER(bpf_track, wlan_bpfevent);
EVENTHANDLER_DEREGISTER(iflladdr_event, wlan_ifllevent);
return 0;
@@ -898,11 +922,7 @@ wlan_modevent(module_t mod, int type, void *unused)
}
static moduledata_t wlan_mod = {
-#if __FreeBSD_version >= 1000020
wlanname,
-#else
- "wlan",
-#endif
wlan_modevent,
0
};
diff --git a/sys/net80211/ieee80211_freebsd.h b/sys/net80211/ieee80211_freebsd.h
index aa21f3b9e218..162cf4309d49 100644
--- a/sys/net80211/ieee80211_freebsd.h
+++ b/sys/net80211/ieee80211_freebsd.h
@@ -28,7 +28,9 @@
#define _NET80211_IEEE80211_FREEBSD_H_
#ifdef _KERNEL
-#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/counter.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/rwlock.h>
@@ -183,6 +185,34 @@ typedef struct mtx ieee80211_scan_table_lock_t;
#define IEEE80211_SCAN_TABLE_LOCK(_st) mtx_lock(&(_st)->st_lock)
#define IEEE80211_SCAN_TABLE_UNLOCK(_st) mtx_unlock(&(_st)->st_lock)
+typedef struct mtx ieee80211_scan_iter_lock_t;
+#define IEEE80211_SCAN_ITER_LOCK_INIT(_st, _name) \
+ mtx_init(&(_st)->st_scanlock, _name, "802.11 scangen", MTX_DEF)
+#define IEEE80211_SCAN_ITER_LOCK_DESTROY(_st) mtx_destroy(&(_st)->st_scanlock)
+#define IEEE80211_SCAN_ITER_LOCK(_st) mtx_lock(&(_st)->st_scanlock)
+#define IEEE80211_SCAN_ITER_UNLOCK(_st) mtx_unlock(&(_st)->st_scanlock)
+
+/*
+ * Mesh node/routing definitions.
+ */
+typedef struct mtx ieee80211_rte_lock_t;
+#define MESH_RT_ENTRY_LOCK_INIT(_rt, _name) \
+ mtx_init(&(rt)->rt_lock, _name, "802.11s route entry", MTX_DEF)
+#define MESH_RT_ENTRY_LOCK_DESTROY(_rt) \
+ mtx_destroy(&(_rt)->rt_lock)
+#define MESH_RT_ENTRY_LOCK(rt) mtx_lock(&(rt)->rt_lock)
+#define MESH_RT_ENTRY_LOCK_ASSERT(rt) mtx_assert(&(rt)->rt_lock, MA_OWNED)
+#define MESH_RT_ENTRY_UNLOCK(rt) mtx_unlock(&(rt)->rt_lock)
+
+typedef struct mtx ieee80211_rt_lock_t;
+#define MESH_RT_LOCK(ms) mtx_lock(&(ms)->ms_rt_lock)
+#define MESH_RT_LOCK_ASSERT(ms) mtx_assert(&(ms)->ms_rt_lock, MA_OWNED)
+#define MESH_RT_UNLOCK(ms) mtx_unlock(&(ms)->ms_rt_lock)
+#define MESH_RT_LOCK_INIT(ms, name) \
+ mtx_init(&(ms)->ms_rt_lock, name, "802.11s routing table", MTX_DEF)
+#define MESH_RT_LOCK_DESTROY(ms) \
+ mtx_destroy(&(ms)->ms_rt_lock)
+
/*
* Node reference counting definitions.
*
@@ -234,21 +264,9 @@ struct mbuf *ieee80211_getmgtframe(uint8_t **frm, int headroom, int pktlen);
#define M_FF M_PROTO6 /* fast frame */
#define M_TXCB M_PROTO7 /* do tx complete callback */
#define M_AMPDU_MPDU M_PROTO8 /* ok for A-MPDU aggregation */
-
-/*
- * FreeBSD-HEAD from 1000046 retired M_*FRAG* flags and turned them
- * into header flags instead. So, we use the new protocol-specific
- * flags.
- *
- * Earlier FreeBSD versions overload M_FRAG, M_FIRSTFRAG and M_LASTFRAG.
- *
- * XXX TODO: rename these fields so there are no namespace clashes!
- */
-#if __FreeBSD_version >= 1000046
#define M_FRAG M_PROTO9 /* frame fragmentation */
#define M_FIRSTFRAG M_PROTO10 /* first frame fragment */
#define M_LASTFRAG M_PROTO11 /* last frame fragment */
-#endif
#define M_80211_TX \
(M_ENCAP|M_EAPOL|M_PWR_SAV|M_MORE_DATA|M_FF|M_TXCB| \
@@ -262,18 +280,10 @@ struct mbuf *ieee80211_getmgtframe(uint8_t **frm, int headroom, int pktlen);
#endif
#define M_80211_RX (M_AMPDU|M_WEP|M_AMPDU_MPDU)
-#if __FreeBSD_version >= 1000046
#define IEEE80211_MBUF_TX_FLAG_BITS \
M_FLAG_BITS \
"\15M_ENCAP\17M_EAPOL\20M_PWR_SAV\21M_MORE_DATA\22M_FF\23M_TXCB" \
"\24M_AMPDU_MPDU\25M_FRAG\26M_FIRSTFRAG\27M_LASTFRAG"
-#else
-/* There aren't any flag bits available for versions before this */
-/* XXX TODO: implement M_FLAG_BITS for this! */
-#define IEEE80211_MBUF_TX_FLAG_BITS \
- "\15M_ENCAP\17M_EAPOL\20M_PWR_SAV\21M_MORE_DATA\22M_FF\23M_TXCB" \
- "\24M_AMPDU_MPDU"
-#endif
#define IEEE80211_MBUF_RX_FLAG_BITS \
M_FLAG_BITS \
@@ -317,6 +327,9 @@ int ieee80211_add_callback(struct mbuf *m,
void (*func)(struct ieee80211_node *, void *, int), void *arg);
void ieee80211_process_callback(struct ieee80211_node *, struct mbuf *, int);
+#define NET80211_TAG_XMIT_PARAMS 1
+/* See below; this is after the bpf_params definition */
+
struct ieee80211com;
int ieee80211_parent_xmitpkt(struct ieee80211com *, struct mbuf *);
int ieee80211_vap_xmitpkt(struct ieee80211vap *, struct mbuf *);
@@ -596,4 +609,29 @@ struct ieee80211_bpf_params {
uint8_t ibp_try3; /* series 4 try count */
uint8_t ibp_rate3; /* series 4 IEEE tx rate */
};
+
+#ifdef _KERNEL
+struct ieee80211_tx_params {
+ struct ieee80211_bpf_params params;
+};
+int ieee80211_add_xmit_params(struct mbuf *m,
+ const struct ieee80211_bpf_params *);
+int ieee80211_get_xmit_params(struct mbuf *m,
+ struct ieee80211_bpf_params *);
+#endif /* _KERNEL */
+
+/*
+ * Malloc API. Other BSD operating systems have slightly
+ * different malloc/free namings (eg DragonflyBSD.)
+ */
+#define IEEE80211_MALLOC malloc
+#define IEEE80211_FREE free
+
+/* XXX TODO: get rid of WAITOK, fix all the users of it? */
+#define IEEE80211_M_NOWAIT M_NOWAIT
+#define IEEE80211_M_WAITOK M_WAITOK
+#define IEEE80211_M_ZERO M_ZERO
+
+/* XXX TODO: the type fields */
+
#endif /* _NET80211_IEEE80211_FREEBSD_H_ */
diff --git a/sys/net80211/ieee80211_hostap.c b/sys/net80211/ieee80211_hostap.c
index a625b4e95a22..ccb31abc6666 100644
--- a/sys/net80211/ieee80211_hostap.c
+++ b/sys/net80211/ieee80211_hostap.c
@@ -68,11 +68,12 @@ __FBSDID("$FreeBSD$");
static void hostap_vattach(struct ieee80211vap *);
static int hostap_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static int hostap_input(struct ieee80211_node *ni, struct mbuf *m,
+ const struct ieee80211_rx_stats *,
int rssi, int nf);
static void hostap_deliver_data(struct ieee80211vap *,
struct ieee80211_node *, struct mbuf *);
static void hostap_recv_mgmt(struct ieee80211_node *, struct mbuf *,
- int subtype, int rssi, int nf);
+ int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf);
static void hostap_recv_ctl(struct ieee80211_node *, struct mbuf *, int);
void
@@ -356,12 +357,8 @@ hostap_deliver_data(struct ieee80211vap *vap,
struct ifnet *ifp = vap->iv_ifp;
/* clear driver/net80211 flags before passing up */
-#if __FreeBSD_version >= 1000046
m->m_flags &= ~(M_MCAST | M_BCAST);
m_clrprotoflags(m);
-#else
- m->m_flags &= ~(M_80211_RX | M_MCAST | M_BCAST);
-#endif
KASSERT(vap->iv_opmode == IEEE80211_M_HOSTAP,
("gack, opmode %d", vap->iv_opmode));
@@ -476,7 +473,8 @@ doprint(struct ieee80211vap *vap, int subtype)
* by the 802.11 layer.
*/
static int
-hostap_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
+hostap_input(struct ieee80211_node *ni, struct mbuf *m,
+ const struct ieee80211_rx_stats *rxs, int rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
@@ -893,7 +891,7 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
if (ieee80211_radiotap_active_vap(vap))
ieee80211_radiotap_rx(vap, m);
need_tap = 0;
- vap->iv_recv_mgmt(ni, m, subtype, rssi, nf);
+ vap->iv_recv_mgmt(ni, m, subtype, rxs, rssi, nf);
goto out;
case IEEE80211_FC0_TYPE_CTL:
@@ -937,7 +935,7 @@ hostap_auth_open(struct ieee80211_node *ni, struct ieee80211_frame *wh,
* open auth is attempted.
*/
if (ni->ni_challenge != NULL) {
- free(ni->ni_challenge, M_80211_NODE);
+ IEEE80211_FREE(ni->ni_challenge, M_80211_NODE);
ni->ni_challenge = NULL;
}
/* XXX hack to workaround calling convention */
@@ -1681,7 +1679,7 @@ is11bclient(const uint8_t *rates, const uint8_t *xrates)
static void
hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
- int subtype, int rssi, int nf)
+ int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
@@ -1709,7 +1707,8 @@ hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
return;
}
/* NB: accept off-channel frames */
- if (ieee80211_parse_beacon(ni, m0, &scan) &~ IEEE80211_BPARSE_OFFCHAN)
+ /* XXX TODO: use rxstatus to determine off-channel details */
+ if (ieee80211_parse_beacon(ni, m0, ic->ic_curchan, &scan) &~ IEEE80211_BPARSE_OFFCHAN)
return;
/*
* Count frame now that we know it's to be processed.
@@ -2039,7 +2038,7 @@ hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
return;
/* discard challenge after association */
if (ni->ni_challenge != NULL) {
- free(ni->ni_challenge, M_80211_NODE);
+ IEEE80211_FREE(ni->ni_challenge, M_80211_NODE);
ni->ni_challenge = NULL;
}
/* NB: 802.11 spec says to ignore station's privacy bit */
diff --git a/sys/net80211/ieee80211_ht.c b/sys/net80211/ieee80211_ht.c
index 0700de8cc7bb..d83cf6511f2f 100644
--- a/sys/net80211/ieee80211_ht.c
+++ b/sys/net80211/ieee80211_ht.c
@@ -354,7 +354,6 @@ static struct printranges {
static void
ht_rateprint(struct ieee80211com *ic, enum ieee80211_phymode mode, int ratetype)
{
- struct ifnet *ifp = ic->ic_ifp;
int minrate, maxrate;
struct printranges *range;
@@ -369,12 +368,12 @@ ht_rateprint(struct ieee80211com *ic, enum ieee80211_phymode mode, int ratetype)
minrate = ht_getrate(ic, range->minmcs, mode, ratetype);
maxrate = ht_getrate(ic, range->maxmcs, mode, ratetype);
if (range->maxmcs) {
- if_printf(ifp, "MCS %d-%d: %d%sMbps - %d%sMbps\n",
+ ic_printf(ic, "MCS %d-%d: %d%sMbps - %d%sMbps\n",
range->minmcs, range->maxmcs,
minrate/2, ((minrate & 0x1) != 0 ? ".5" : ""),
maxrate/2, ((maxrate & 0x1) != 0 ? ".5" : ""));
} else {
- if_printf(ifp, "MCS %d: %d%sMbps\n", range->minmcs,
+ ic_printf(ic, "MCS %d: %d%sMbps\n", range->minmcs,
minrate/2, ((minrate & 0x1) != 0 ? ".5" : ""));
}
}
@@ -383,22 +382,21 @@ ht_rateprint(struct ieee80211com *ic, enum ieee80211_phymode mode, int ratetype)
static void
ht_announce(struct ieee80211com *ic, enum ieee80211_phymode mode)
{
- struct ifnet *ifp = ic->ic_ifp;
const char *modestr = ieee80211_phymode_name[mode];
- if_printf(ifp, "%s MCS 20MHz\n", modestr);
+ ic_printf(ic, "%s MCS 20MHz\n", modestr);
ht_rateprint(ic, mode, 0);
if (ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI20) {
- if_printf(ifp, "%s MCS 20MHz SGI\n", modestr);
+ ic_printf(ic, "%s MCS 20MHz SGI\n", modestr);
ht_rateprint(ic, mode, 1);
}
if (ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) {
- if_printf(ifp, "%s MCS 40MHz:\n", modestr);
+ ic_printf(ic, "%s MCS 40MHz:\n", modestr);
ht_rateprint(ic, mode, 2);
}
if ((ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) &&
(ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI40)) {
- if_printf(ifp, "%s MCS 40MHz SGI:\n", modestr);
+ ic_printf(ic, "%s MCS 40MHz SGI:\n", modestr);
ht_rateprint(ic, mode, 3);
}
}
@@ -406,11 +404,10 @@ ht_announce(struct ieee80211com *ic, enum ieee80211_phymode mode)
void
ieee80211_ht_announce(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
if (isset(ic->ic_modecaps, IEEE80211_MODE_11NA) ||
isset(ic->ic_modecaps, IEEE80211_MODE_11NG))
- if_printf(ifp, "%dT%dR\n", ic->ic_txstream, ic->ic_rxstream);
+ ic_printf(ic, "%dT%dR\n", ic->ic_txstream, ic->ic_rxstream);
if (isset(ic->ic_modecaps, IEEE80211_MODE_11NA))
ht_announce(ic, IEEE80211_MODE_11NA);
if (isset(ic->ic_modecaps, IEEE80211_MODE_11NG))
diff --git a/sys/net80211/ieee80211_hwmp.c b/sys/net80211/ieee80211_hwmp.c
index 601b848310d6..6bbc32c634dc 100644
--- a/sys/net80211/ieee80211_hwmp.c
+++ b/sys/net80211/ieee80211_hwmp.c
@@ -268,8 +268,8 @@ hwmp_vattach(struct ieee80211vap *vap)
KASSERT(vap->iv_opmode == IEEE80211_M_MBSS,
("not a mesh vap, opmode %d", vap->iv_opmode));
- hs = malloc(sizeof(struct ieee80211_hwmp_state), M_80211_VAP,
- M_NOWAIT | M_ZERO);
+ hs = IEEE80211_MALLOC(sizeof(struct ieee80211_hwmp_state), M_80211_VAP,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (hs == NULL) {
printf("%s: couldn't alloc HWMP state\n", __func__);
return;
@@ -285,7 +285,7 @@ hwmp_vdetach(struct ieee80211vap *vap)
struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
callout_drain(&hs->hs_roottimer);
- free(vap->iv_hwmp, M_80211_VAP);
+ IEEE80211_FREE(vap->iv_hwmp, M_80211_VAP);
vap->iv_hwmp = NULL;
}
@@ -429,9 +429,10 @@ hwmp_recv_action_meshpath(struct ieee80211_node *ni,
vap->iv_stats.is_rx_mgtdiscard++;
break;
}
- preq = malloc(sizeof(*preq) +
+ preq = IEEE80211_MALLOC(sizeof(*preq) +
(ndest - 1) * sizeof(*preq->preq_targets),
- M_80211_MESH_PREQ, M_NOWAIT | M_ZERO);
+ M_80211_MESH_PREQ,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
KASSERT(preq != NULL, ("preq == NULL"));
preq->preq_ie = *iefrm_t++;
@@ -464,7 +465,7 @@ hwmp_recv_action_meshpath(struct ieee80211_node *ni,
}
hwmp_recv_preq(vap, ni, wh, preq);
- free(preq, M_80211_MESH_PREQ);
+ IEEE80211_FREE(preq, M_80211_MESH_PREQ);
found++;
break;
}
@@ -476,8 +477,9 @@ hwmp_recv_action_meshpath(struct ieee80211_node *ni,
vap->iv_stats.is_rx_mgtdiscard++;
break;
}
- prep = malloc(sizeof(*prep),
- M_80211_MESH_PREP, M_NOWAIT | M_ZERO);
+ prep = IEEE80211_MALLOC(sizeof(*prep),
+ M_80211_MESH_PREP,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
KASSERT(prep != NULL, ("prep == NULL"));
prep->prep_ie = *iefrm_t++;
@@ -501,7 +503,7 @@ hwmp_recv_action_meshpath(struct ieee80211_node *ni,
prep->prep_origseq = LE_READ_4(iefrm_t); iefrm_t += 4;
hwmp_recv_prep(vap, ni, wh, prep);
- free(prep, M_80211_MESH_PREP);
+ IEEE80211_FREE(prep, M_80211_MESH_PREP);
found++;
break;
}
@@ -515,9 +517,10 @@ hwmp_recv_action_meshpath(struct ieee80211_node *ni,
vap->iv_stats.is_rx_mgtdiscard++;
break;
}
- perr = malloc(sizeof(*perr) +
+ perr = IEEE80211_MALLOC(sizeof(*perr) +
(ndest - 1) * sizeof(*perr->perr_dests),
- M_80211_MESH_PERR, M_NOWAIT | M_ZERO);
+ M_80211_MESH_PERR,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
KASSERT(perr != NULL, ("perr == NULL"));
perr->perr_ie = *iefrm_t++;
@@ -546,7 +549,7 @@ hwmp_recv_action_meshpath(struct ieee80211_node *ni,
}
hwmp_recv_perr(vap, ni, wh, perr);
- free(perr, M_80211_MESH_PERR);
+ IEEE80211_FREE(perr, M_80211_MESH_PERR);
found++;
break;
}
@@ -1556,8 +1559,8 @@ hwmp_recv_perr(struct ieee80211vap *vap, struct ieee80211_node *ni,
*/
if (ms->ms_flags & IEEE80211_MESHFLAGS_FWD) {
forward = 1;
- pperr = malloc(sizeof(*perr) + 31*sizeof(*perr->perr_dests),
- M_80211_MESH_PERR, M_NOWAIT); /* XXX: magic number, 32 err dests */
+ pperr = IEEE80211_MALLOC(sizeof(*perr) + 31*sizeof(*perr->perr_dests),
+ M_80211_MESH_PERR, IEEE80211_M_NOWAIT); /* XXX: magic number, 32 err dests */
}
/*
@@ -1632,7 +1635,7 @@ hwmp_recv_perr(struct ieee80211vap *vap, struct ieee80211_node *ni,
}
done:
if (pperr != NULL)
- free(pperr, M_80211_MESH_PERR);
+ IEEE80211_FREE(pperr, M_80211_MESH_PERR);
}
#undef PERR_DFLAGS
#undef PERR_DADDR
diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c
index a0f737dc2036..b757ae635f9f 100644
--- a/sys/net80211/ieee80211_input.c
+++ b/sys/net80211/ieee80211_input.c
@@ -88,7 +88,8 @@ ieee80211_input_mimo(struct ieee80211_node *ni, struct mbuf *m,
{
/* XXX should assert IEEE80211_R_NF and IEEE80211_R_RSSI are set */
ieee80211_process_mimo(ni, rx);
- return ieee80211_input(ni, m, rx->rssi, rx->nf);
+ //return ieee80211_input(ni, m, rx->rssi, rx->nf);
+ return ni->ni_vap->iv_input(ni, m, rx, rx->rssi, rx->nf);
}
int
@@ -252,9 +253,7 @@ ieee80211_deliver_data(struct ieee80211vap *vap,
/* clear driver/net80211 flags before passing up */
m->m_flags &= ~(M_MCAST | M_BCAST);
-#if __FreeBSD_version >= 1000046
m_clrprotoflags(m);
-#endif
/* NB: see hostap_deliver_data, this path doesn't handle hostap */
KASSERT(vap->iv_opmode != IEEE80211_M_HOSTAP, ("gack, hostap"));
@@ -448,8 +447,9 @@ int
ieee80211_alloc_challenge(struct ieee80211_node *ni)
{
if (ni->ni_challenge == NULL)
- ni->ni_challenge = (uint32_t *) malloc(IEEE80211_CHALLENGE_LEN,
- M_80211_NODE, M_NOWAIT);
+ ni->ni_challenge = (uint32_t *)
+ IEEE80211_MALLOC(IEEE80211_CHALLENGE_LEN,
+ M_80211_NODE, IEEE80211_M_NOWAIT);
if (ni->ni_challenge == NULL) {
IEEE80211_NOTE(ni->ni_vap,
IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, ni,
@@ -468,7 +468,7 @@ ieee80211_alloc_challenge(struct ieee80211_node *ni)
*/
int
ieee80211_parse_beacon(struct ieee80211_node *ni, struct mbuf *m,
- struct ieee80211_scanparams *scan)
+ struct ieee80211_channel *rxchan, struct ieee80211_scanparams *scan)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
@@ -505,7 +505,7 @@ ieee80211_parse_beacon(struct ieee80211_node *ni, struct mbuf *m,
scan->tstamp = frm; frm += 8;
scan->bintval = le16toh(*(uint16_t *)frm); frm += 2;
scan->capinfo = le16toh(*(uint16_t *)frm); frm += 2;
- scan->bchan = ieee80211_chan2ieee(ic, ic->ic_curchan);
+ scan->bchan = ieee80211_chan2ieee(ic, rxchan);
scan->chan = scan->bchan;
scan->ies = frm;
scan->ies_len = efrm - frm;
@@ -648,7 +648,8 @@ ieee80211_parse_beacon(struct ieee80211_node *ni, struct mbuf *m,
*/
IEEE80211_DISCARD(vap,
IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT,
- wh, NULL, "for off-channel %u", scan->chan);
+ wh, NULL, "for off-channel %u (bchan=%u)",
+ scan->chan, scan->bchan);
vap->iv_stats.is_rx_chanmismatch++;
scan->status |= IEEE80211_BPARSE_OFFCHAN;
}
diff --git a/sys/net80211/ieee80211_input.h b/sys/net80211/ieee80211_input.h
index f3d569efd582..72fd25b4ffc9 100644
--- a/sys/net80211/ieee80211_input.h
+++ b/sys/net80211/ieee80211_input.h
@@ -255,6 +255,7 @@ void ieee80211_send_error(struct ieee80211_node *,
const uint8_t mac[IEEE80211_ADDR_LEN], int subtype, int arg);
int ieee80211_alloc_challenge(struct ieee80211_node *);
int ieee80211_parse_beacon(struct ieee80211_node *, struct mbuf *,
+ struct ieee80211_channel *,
struct ieee80211_scanparams *);
int ieee80211_parse_action(struct ieee80211_node *, struct mbuf *);
#endif /* _NET80211_IEEE80211_INPUT_H_ */
diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c
index 2798d8089b89..54ab39072ecc 100644
--- a/sys/net80211/ieee80211_ioctl.c
+++ b/sys/net80211/ieee80211_ioctl.c
@@ -323,14 +323,15 @@ ieee80211_ioctl_getscanresults(struct ieee80211vap *vap,
space = req.space;
/* XXX M_WAITOK after driver lock released */
- p = malloc(space, M_TEMP, M_NOWAIT | M_ZERO);
+ p = IEEE80211_MALLOC(space, M_TEMP,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (p == NULL)
return ENOMEM;
req.sr = p;
ieee80211_scan_iterate(vap, get_scan_result, &req);
ireq->i_len = space - req.space;
error = copyout(p, ireq->i_data, ireq->i_len);
- free(p, M_TEMP);
+ IEEE80211_FREE(p, M_TEMP);
} else
ireq->i_len = 0;
@@ -473,7 +474,8 @@ getstainfo_common(struct ieee80211vap *vap, struct ieee80211req *ireq,
if (req.space > 0) {
space = req.space;
/* XXX M_WAITOK after driver lock released */
- p = malloc(space, M_TEMP, M_NOWAIT | M_ZERO);
+ p = IEEE80211_MALLOC(space, M_TEMP,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (p == NULL) {
error = ENOMEM;
goto bad;
@@ -485,7 +487,7 @@ getstainfo_common(struct ieee80211vap *vap, struct ieee80211req *ireq,
get_sta_info(&req, ni);
ireq->i_len = space - req.space;
error = copyout(p, (uint8_t *) ireq->i_data+off, ireq->i_len);
- free(p, M_TEMP);
+ IEEE80211_FREE(p, M_TEMP);
} else
ireq->i_len = 0;
bad:
@@ -697,7 +699,8 @@ ieee80211_ioctl_getdevcaps(struct ieee80211com *ic,
if (maxchans > 2048)
maxchans = 2048;
dc = (struct ieee80211_devcaps_req *)
- malloc(IEEE80211_DEVCAPS_SIZE(maxchans), M_TEMP, M_NOWAIT | M_ZERO);
+ IEEE80211_MALLOC(IEEE80211_DEVCAPS_SIZE(maxchans), M_TEMP,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (dc == NULL)
return ENOMEM;
dc->dc_drivercaps = ic->ic_caps;
@@ -709,7 +712,7 @@ ieee80211_ioctl_getdevcaps(struct ieee80211com *ic,
("nchans %d maxchans %d", ci->ic_nchans, maxchans));
ieee80211_sort_channels(ci->ic_chans, ci->ic_nchans);
error = copyout(dc, ireq->i_data, IEEE80211_DEVCAPS_SPACE(dc));
- free(dc, M_TEMP);
+ IEEE80211_FREE(dc, M_TEMP);
return error;
}
@@ -1666,13 +1669,13 @@ ieee80211_ioctl_setchanlist(struct ieee80211vap *vap, struct ieee80211req *ireq)
if (ireq->i_len > sizeof(ic->ic_chan_active))
ireq->i_len = sizeof(ic->ic_chan_active);
- list = malloc(ireq->i_len + IEEE80211_CHAN_BYTES, M_TEMP,
- M_NOWAIT | M_ZERO);
+ list = IEEE80211_MALLOC(ireq->i_len + IEEE80211_CHAN_BYTES, M_TEMP,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (list == NULL)
return ENOMEM;
error = copyin(ireq->i_data, list, ireq->i_len);
if (error) {
- free(list, M_TEMP);
+ IEEE80211_FREE(list, M_TEMP);
return error;
}
nchan = 0;
@@ -1691,7 +1694,7 @@ ieee80211_ioctl_setchanlist(struct ieee80211vap *vap, struct ieee80211req *ireq)
}
}
if (nchan == 0) {
- free(list, M_TEMP);
+ IEEE80211_FREE(list, M_TEMP);
return EINVAL;
}
if (ic->ic_bsschan != IEEE80211_CHAN_ANYC && /* XXX */
@@ -1699,7 +1702,7 @@ ieee80211_ioctl_setchanlist(struct ieee80211vap *vap, struct ieee80211req *ireq)
ic->ic_bsschan = IEEE80211_CHAN_ANYC;
memcpy(ic->ic_chan_active, chanlist, IEEE80211_CHAN_BYTES);
ieee80211_scan_flush(vap);
- free(list, M_TEMP);
+ IEEE80211_FREE(list, M_TEMP);
return ENETRESET;
}
@@ -2112,7 +2115,8 @@ ieee80211_ioctl_setregdomain(struct ieee80211vap *vap,
return EINVAL;
}
reg = (struct ieee80211_regdomain_req *)
- malloc(IEEE80211_REGDOMAIN_SIZE(nchans), M_TEMP, M_NOWAIT);
+ IEEE80211_MALLOC(IEEE80211_REGDOMAIN_SIZE(nchans), M_TEMP,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (reg == NULL) {
IEEE80211_DPRINTF(vap, IEEE80211_MSG_IOCTL,
"%s: no memory, nchans %d\n", __func__, nchans);
@@ -2129,7 +2133,7 @@ ieee80211_ioctl_setregdomain(struct ieee80211vap *vap,
} else
error = ieee80211_setregdomain(vap, reg);
}
- free(reg, M_TEMP);
+ IEEE80211_FREE(reg, M_TEMP);
return (error == 0 ? ENETRESET : error);
}
@@ -2246,7 +2250,7 @@ setappie(struct ieee80211_appie **aie, const struct ieee80211req *ireq)
if (ireq->i_len == 0) { /* delete any existing ie */
if (app != NULL) {
*aie = NULL; /* XXX racey */
- free(app, M_80211_NODE_IE);
+ IEEE80211_FREE(app, M_80211_NODE_IE);
}
return 0;
}
@@ -2260,20 +2264,21 @@ setappie(struct ieee80211_appie **aie, const struct ieee80211req *ireq)
*
* XXX bad bad bad
*/
- napp = (struct ieee80211_appie *) malloc(
- sizeof(struct ieee80211_appie) + ireq->i_len, M_80211_NODE_IE, M_NOWAIT);
+ napp = (struct ieee80211_appie *) IEEE80211_MALLOC(
+ sizeof(struct ieee80211_appie) + ireq->i_len, M_80211_NODE_IE,
+ IEEE80211_M_NOWAIT);
if (napp == NULL)
return ENOMEM;
/* XXX holding ic lock */
error = copyin(ireq->i_data, napp->ie_data, ireq->i_len);
if (error) {
- free(napp, M_80211_NODE_IE);
+ IEEE80211_FREE(napp, M_80211_NODE_IE);
return error;
}
napp->ie_len = ireq->i_len;
*aie = napp;
if (app != NULL)
- free(app, M_80211_NODE_IE);
+ IEEE80211_FREE(app, M_80211_NODE_IE);
return 0;
}
diff --git a/sys/net80211/ieee80211_mesh.c b/sys/net80211/ieee80211_mesh.c
index 5ffd50bc7ade..ef811845fc91 100644
--- a/sys/net80211/ieee80211_mesh.c
+++ b/sys/net80211/ieee80211_mesh.c
@@ -85,9 +85,10 @@ static void mesh_transmit_to_gate(struct ieee80211vap *, struct mbuf *,
struct ieee80211_mesh_route *);
static void mesh_forward(struct ieee80211vap *, struct mbuf *,
const struct ieee80211_meshcntl *);
-static int mesh_input(struct ieee80211_node *, struct mbuf *, int, int);
+static int mesh_input(struct ieee80211_node *, struct mbuf *,
+ const struct ieee80211_rx_stats *rxs, int, int);
static void mesh_recv_mgmt(struct ieee80211_node *, struct mbuf *, int,
- int, int);
+ const struct ieee80211_rx_stats *rxs, int, int);
static void mesh_recv_ctl(struct ieee80211_node *, struct mbuf *, int);
static void mesh_peer_timeout_setup(struct ieee80211_node *);
static void mesh_peer_timeout_backoff(struct ieee80211_node *);
@@ -161,14 +162,6 @@ static const struct ieee80211_mesh_proto_metric mesh_metric_airtime = {
static struct ieee80211_mesh_proto_path mesh_proto_paths[4];
static struct ieee80211_mesh_proto_metric mesh_proto_metrics[4];
-#define RT_ENTRY_LOCK(rt) mtx_lock(&(rt)->rt_lock)
-#define RT_ENTRY_LOCK_ASSERT(rt) mtx_assert(&(rt)->rt_lock, MA_OWNED)
-#define RT_ENTRY_UNLOCK(rt) mtx_unlock(&(rt)->rt_lock)
-
-#define MESH_RT_LOCK(ms) mtx_lock(&(ms)->ms_rt_lock)
-#define MESH_RT_LOCK_ASSERT(ms) mtx_assert(&(ms)->ms_rt_lock, MA_OWNED)
-#define MESH_RT_UNLOCK(ms) mtx_unlock(&(ms)->ms_rt_lock)
-
MALLOC_DEFINE(M_80211_MESH_PREQ, "80211preq", "802.11 MESH Path Request frame");
MALLOC_DEFINE(M_80211_MESH_PREP, "80211prep", "802.11 MESH Path Reply frame");
MALLOC_DEFINE(M_80211_MESH_PERR, "80211perr", "802.11 MESH Path Error frame");
@@ -210,13 +203,14 @@ mesh_rt_add_locked(struct ieee80211vap *vap,
MESH_RT_LOCK_ASSERT(ms);
- rt = malloc(ALIGN(sizeof(struct ieee80211_mesh_route)) +
- ms->ms_ppath->mpp_privlen, M_80211_MESH_RT, M_NOWAIT | M_ZERO);
+ rt = IEEE80211_MALLOC(ALIGN(sizeof(struct ieee80211_mesh_route)) +
+ ms->ms_ppath->mpp_privlen, M_80211_MESH_RT,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (rt != NULL) {
rt->rt_vap = vap;
IEEE80211_ADDR_COPY(rt->rt_dest, dest);
rt->rt_priv = (void *)ALIGN(&rt[1]);
- mtx_init(&rt->rt_lock, "MBSS_RT", "802.11s route entry", MTX_DEF);
+ MESH_RT_ENTRY_LOCK_INIT(rt, "MBSS_RT");
callout_init(&rt->rt_discovery, 1);
rt->rt_updtime = ticks; /* create time */
TAILQ_INSERT_TAIL(&ms->ms_routes, rt, rt_next);
@@ -269,11 +263,11 @@ ieee80211_mesh_rt_update(struct ieee80211_mesh_route *rt, int new_lifetime)
KASSERT(rt != NULL, ("route is NULL"));
now = ticks;
- RT_ENTRY_LOCK(rt);
+ MESH_RT_ENTRY_LOCK(rt);
/* dont clobber a proxy entry gated by us */
if (rt->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY && rt->rt_nhops == 0) {
- RT_ENTRY_UNLOCK(rt);
+ MESH_RT_ENTRY_UNLOCK(rt);
return rt->rt_lifetime;
}
@@ -294,7 +288,7 @@ ieee80211_mesh_rt_update(struct ieee80211_mesh_route *rt, int new_lifetime)
new_lifetime, rt->rt_lifetime);
}
lifetime = rt->rt_lifetime;
- RT_ENTRY_UNLOCK(rt);
+ MESH_RT_ENTRY_UNLOCK(rt);
return lifetime;
}
@@ -356,10 +350,10 @@ mesh_rt_del(struct ieee80211_mesh_state *ms, struct ieee80211_mesh_route *rt)
* Grab the lock before destroying it, to be sure no one else
* is holding the route.
*/
- RT_ENTRY_LOCK(rt);
+ MESH_RT_ENTRY_LOCK(rt);
callout_drain(&rt->rt_discovery);
- mtx_destroy(&rt->rt_lock);
- free(rt, M_80211_MESH_RT);
+ MESH_RT_ENTRY_LOCK_DESTROY(rt);
+ IEEE80211_FREE(rt, M_80211_MESH_RT);
}
void
@@ -651,9 +645,9 @@ mesh_vdetach(struct ieee80211vap *vap)
ieee80211_iterate_nodes(&vap->iv_ic->ic_sta, mesh_vdetach_peers,
NULL);
ieee80211_mesh_rt_flush(vap);
- mtx_destroy(&ms->ms_rt_lock);
+ MESH_RT_LOCK_DESTROY(ms);
ms->ms_ppath->mpp_vdetach(vap);
- free(vap->iv_mesh, M_80211_VAP);
+ IEEE80211_FREE(vap->iv_mesh, M_80211_VAP);
vap->iv_mesh = NULL;
}
@@ -666,8 +660,8 @@ mesh_vattach(struct ieee80211vap *vap)
vap->iv_opdetach = mesh_vdetach;
vap->iv_recv_mgmt = mesh_recv_mgmt;
vap->iv_recv_ctl = mesh_recv_ctl;
- ms = malloc(sizeof(struct ieee80211_mesh_state), M_80211_VAP,
- M_NOWAIT | M_ZERO);
+ ms = IEEE80211_MALLOC(sizeof(struct ieee80211_mesh_state), M_80211_VAP,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (ms == NULL) {
printf("%s: couldn't alloc MBSS state\n", __func__);
return;
@@ -678,7 +672,7 @@ mesh_vattach(struct ieee80211vap *vap)
ms->ms_ttl = IEEE80211_MESH_DEFAULT_TTL;
TAILQ_INIT(&ms->ms_known_gates);
TAILQ_INIT(&ms->ms_routes);
- mtx_init(&ms->ms_rt_lock, "MBSS", "802.11s routing table", MTX_DEF);
+ MESH_RT_LOCK_INIT(ms, "MBSS");
callout_init(&ms->ms_cleantimer, 1);
callout_init(&ms->ms_gatetimer, 1);
ms->ms_gateseq = 0;
@@ -884,8 +878,9 @@ ieee80211_mesh_mark_gate(struct ieee80211vap *vap, const uint8_t *addr,
/* New mesh gate add it to known table. */
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, addr,
"%s", "stored new gate information from pro-PREQ.");
- gr = malloc(ALIGN(sizeof(struct ieee80211_mesh_gate_route)),
- M_80211_MESH_GT_RT, M_NOWAIT | M_ZERO);
+ gr = IEEE80211_MALLOC(ALIGN(sizeof(struct ieee80211_mesh_gate_route)),
+ M_80211_MESH_GT_RT,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
IEEE80211_ADDR_COPY(gr->gr_addr, addr);
TAILQ_INSERT_TAIL(&ms->ms_known_gates, gr, gr_next);
}
@@ -1532,7 +1527,8 @@ mesh_recv_group_data(struct ieee80211vap *vap, struct mbuf *m,
}
static int
-mesh_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
+mesh_input(struct ieee80211_node *ni, struct mbuf *m,
+ const struct ieee80211_rx_stats *rxs, int rssi, int nf)
{
#define HAS_SEQ(type) ((type & 0x4) == 0)
#define MC01(mc) ((const struct ieee80211_meshcntl_ae01 *)mc)
@@ -1831,7 +1827,7 @@ mesh_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
vap->iv_stats.is_rx_mgtdiscard++; /* XXX */
goto out;
}
- vap->iv_recv_mgmt(ni, m, subtype, rssi, nf);
+ vap->iv_recv_mgmt(ni, m, subtype, rxs, rssi, nf);
goto out;
case IEEE80211_FC0_TYPE_CTL:
vap->iv_stats.is_rx_ctl++;
@@ -1859,11 +1855,12 @@ out:
static void
mesh_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype,
- int rssi, int nf)
+ const struct ieee80211_rx_stats *rxs, int rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_mesh_state *ms = vap->iv_mesh;
struct ieee80211com *ic = ni->ni_ic;
+ struct ieee80211_channel *rxchan = ic->ic_curchan;
struct ieee80211_frame *wh;
struct ieee80211_mesh_route *rt;
uint8_t *frm, *efrm;
@@ -1876,11 +1873,17 @@ mesh_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype,
case IEEE80211_FC0_SUBTYPE_BEACON:
{
struct ieee80211_scanparams scan;
+ struct ieee80211_channel *c;
/*
* We process beacon/probe response
* frames to discover neighbors.
*/
- if (ieee80211_parse_beacon(ni, m0, &scan) != 0)
+ if (rxs != NULL) {
+ c = ieee80211_lookup_channel_rxstatus(vap, rxs);
+ if (c != NULL)
+ rxchan = c;
+ }
+ if (ieee80211_parse_beacon(ni, m0, rxchan, &scan) != 0)
return;
/*
* Count frame now that we know it's to be processed.
@@ -1906,7 +1909,7 @@ mesh_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype,
ieee80211_probe_curchan(vap, 1);
ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN;
}
- ieee80211_add_scan(vap, ic->ic_curchan, &scan, wh,
+ ieee80211_add_scan(vap, rxchan, &scan, wh,
subtype, rssi, nf);
return;
}
@@ -2634,8 +2637,9 @@ mesh_recv_action_meshgate(struct ieee80211_node *ni,
/* this GANN is from a new mesh Gate add it to known table. */
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, ie.gann_addr,
"stored new GANN information, seq %u.", ie.gann_seq);
- gr = malloc(ALIGN(sizeof(struct ieee80211_mesh_gate_route)),
- M_80211_MESH_GT_RT, M_NOWAIT | M_ZERO);
+ gr = IEEE80211_MALLOC(ALIGN(sizeof(struct ieee80211_mesh_gate_route)),
+ M_80211_MESH_GT_RT,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
IEEE80211_ADDR_COPY(gr->gr_addr, ie.gann_addr);
TAILQ_INSERT_TAIL(&ms->ms_known_gates, gr, gr_next);
}
@@ -3482,7 +3486,8 @@ mesh_ioctl_get80211(struct ieee80211vap *vap, struct ieee80211req *ireq)
}
ireq->i_len = len;
/* XXX M_WAIT? */
- p = malloc(len, M_TEMP, M_NOWAIT | M_ZERO);
+ p = IEEE80211_MALLOC(len, M_TEMP,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (p == NULL)
return ENOMEM;
off = 0;
@@ -3507,7 +3512,7 @@ mesh_ioctl_get80211(struct ieee80211vap *vap, struct ieee80211req *ireq)
MESH_RT_UNLOCK(ms);
error = copyout(p, (uint8_t *)ireq->i_data,
ireq->i_len);
- free(p, M_TEMP);
+ IEEE80211_FREE(p, M_TEMP);
break;
case IEEE80211_MESH_RTCMD_FLUSH:
case IEEE80211_MESH_RTCMD_ADD:
diff --git a/sys/net80211/ieee80211_mesh.h b/sys/net80211/ieee80211_mesh.h
index 5dc2b2c12b17..2253af0060a4 100644
--- a/sys/net80211/ieee80211_mesh.h
+++ b/sys/net80211/ieee80211_mesh.h
@@ -418,7 +418,7 @@ MALLOC_DECLARE(M_80211_MESH_GT_RT);
struct ieee80211_mesh_route {
TAILQ_ENTRY(ieee80211_mesh_route) rt_next;
struct ieee80211vap *rt_vap;
- struct mtx rt_lock; /* fine grained route lock */
+ ieee80211_rte_lock_t rt_lock; /* fine grained route lock */
struct callout rt_discovery; /* discovery timeout */
int rt_updtime; /* last update time */
uint8_t rt_dest[IEEE80211_ADDR_LEN];
@@ -515,7 +515,7 @@ struct ieee80211_mesh_state {
#define IEEE80211_MESHFLAGS_FWD 0x04 /* forward packets */
#define IEEE80211_MESHFLAGS_ROOT 0x08 /* configured as root */
uint8_t ms_flags;
- struct mtx ms_rt_lock;
+ ieee80211_rt_lock_t ms_rt_lock;
struct callout ms_cleantimer;
struct callout ms_gatetimer;
ieee80211_mesh_seq ms_gateseq;
diff --git a/sys/net80211/ieee80211_monitor.c b/sys/net80211/ieee80211_monitor.c
index 8909339bde29..e0778461fd42 100644
--- a/sys/net80211/ieee80211_monitor.c
+++ b/sys/net80211/ieee80211_monitor.c
@@ -61,7 +61,7 @@ __FBSDID("$FreeBSD$");
static void monitor_vattach(struct ieee80211vap *);
static int monitor_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static int monitor_input(struct ieee80211_node *ni, struct mbuf *m,
- int rssi, int nf);
+ const struct ieee80211_rx_stats *rxs, int rssi, int nf);
void
ieee80211_monitor_attach(struct ieee80211com *ic)
@@ -125,7 +125,8 @@ monitor_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
* Process a received frame in monitor mode.
*/
static int
-monitor_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
+monitor_input(struct ieee80211_node *ni, struct mbuf *m,
+ const struct ieee80211_rx_stats *rxs, int rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ifnet *ifp = vap->iv_ifp;
diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c
index fbb8e9343125..82cfccfaee79 100644
--- a/sys/net80211/ieee80211_node.c
+++ b/sys/net80211/ieee80211_node.c
@@ -172,9 +172,10 @@ ieee80211_node_latevattach(struct ieee80211vap *vap)
"WARNING: max aid too small, changed to %d\n",
vap->iv_max_aid);
}
- vap->iv_aid_bitmap = (uint32_t *) malloc(
+ vap->iv_aid_bitmap = (uint32_t *) IEEE80211_MALLOC(
howmany(vap->iv_max_aid, 32) * sizeof(uint32_t),
- M_80211_NODE, M_NOWAIT | M_ZERO);
+ M_80211_NODE,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (vap->iv_aid_bitmap == NULL) {
/* XXX no way to recover */
printf("%s: no memory for AID bitmap, max aid %d!\n",
@@ -199,7 +200,7 @@ ieee80211_node_vdetach(struct ieee80211vap *vap)
vap->iv_bss = NULL;
}
if (vap->iv_aid_bitmap != NULL) {
- free(vap->iv_aid_bitmap, M_80211_NODE);
+ IEEE80211_FREE(vap->iv_aid_bitmap, M_80211_NODE);
vap->iv_aid_bitmap = NULL;
}
}
@@ -892,8 +893,8 @@ node_alloc(struct ieee80211vap *vap, const uint8_t macaddr[IEEE80211_ADDR_LEN])
{
struct ieee80211_node *ni;
- ni = (struct ieee80211_node *) malloc(sizeof(struct ieee80211_node),
- M_80211_NODE, M_NOWAIT | M_ZERO);
+ ni = (struct ieee80211_node *) IEEE80211_MALLOC(sizeof(struct ieee80211_node),
+ M_80211_NODE, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
return ni;
}
@@ -910,11 +911,12 @@ ieee80211_ies_init(struct ieee80211_ies *ies, const uint8_t *data, int len)
memset(ies, 0, offsetof(struct ieee80211_ies, data));
if (ies->data != NULL && ies->len != len) {
/* data size changed */
- free(ies->data, M_80211_NODE_IE);
+ IEEE80211_FREE(ies->data, M_80211_NODE_IE);
ies->data = NULL;
}
if (ies->data == NULL) {
- ies->data = (uint8_t *) malloc(len, M_80211_NODE_IE, M_NOWAIT);
+ ies->data = (uint8_t *) IEEE80211_MALLOC(len, M_80211_NODE_IE,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (ies->data == NULL) {
ies->len = 0;
/* NB: pointers have already been zero'd above */
@@ -933,7 +935,7 @@ void
ieee80211_ies_cleanup(struct ieee80211_ies *ies)
{
if (ies->data != NULL)
- free(ies->data, M_80211_NODE_IE);
+ IEEE80211_FREE(ies->data, M_80211_NODE_IE);
}
/*
@@ -1045,7 +1047,7 @@ node_cleanup(struct ieee80211_node *ni)
ni->ni_associd = 0;
if (ni->ni_challenge != NULL) {
- free(ni->ni_challenge, M_80211_NODE);
+ IEEE80211_FREE(ni->ni_challenge, M_80211_NODE);
ni->ni_challenge = NULL;
}
/*
@@ -1080,7 +1082,7 @@ node_free(struct ieee80211_node *ni)
ic->ic_node_cleanup(ni);
ieee80211_ies_cleanup(&ni->ni_ies);
ieee80211_psq_cleanup(&ni->ni_psq);
- free(ni, M_80211_NODE);
+ IEEE80211_FREE(ni, M_80211_NODE);
}
static void
@@ -1908,22 +1910,22 @@ ieee80211_node_table_init(struct ieee80211com *ic,
struct ieee80211_node_table *nt,
const char *name, int inact, int keyixmax)
{
- struct ifnet *ifp = ic->ic_ifp;
nt->nt_ic = ic;
- IEEE80211_NODE_LOCK_INIT(nt, ifp->if_xname);
- IEEE80211_NODE_ITERATE_LOCK_INIT(nt, ifp->if_xname);
+ IEEE80211_NODE_LOCK_INIT(nt, ic->ic_name);
+ IEEE80211_NODE_ITERATE_LOCK_INIT(nt, ic->ic_name);
TAILQ_INIT(&nt->nt_node);
nt->nt_name = name;
nt->nt_scangen = 1;
nt->nt_inact_init = inact;
nt->nt_keyixmax = keyixmax;
if (nt->nt_keyixmax > 0) {
- nt->nt_keyixmap = (struct ieee80211_node **) malloc(
+ nt->nt_keyixmap = (struct ieee80211_node **) IEEE80211_MALLOC(
keyixmax * sizeof(struct ieee80211_node *),
- M_80211_NODE, M_NOWAIT | M_ZERO);
+ M_80211_NODE,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (nt->nt_keyixmap == NULL)
- if_printf(ic->ic_ifp,
+ ic_printf(ic,
"Cannot allocate key index map with %u entries\n",
keyixmax);
} else
@@ -1980,7 +1982,7 @@ ieee80211_node_table_cleanup(struct ieee80211_node_table *nt)
printf("%s: %s[%u] still active\n", __func__,
nt->nt_name, i);
#endif
- free(nt->nt_keyixmap, M_80211_NODE);
+ IEEE80211_FREE(nt->nt_keyixmap, M_80211_NODE);
nt->nt_keyixmap = NULL;
}
IEEE80211_NODE_ITERATE_LOCK_DESTROY(nt);
@@ -2256,8 +2258,8 @@ ieee80211_iterate_nt(struct ieee80211_node_table *nt,
TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {
if (i >= max_aid) {
ret = E2BIG;
- if_printf(nt->nt_ic->ic_ifp,
- "Node array overflow: max=%u", max_aid);
+ ic_printf(nt->nt_ic, "Node array overflow: max=%u",
+ max_aid);
break;
}
ni_arr[i] = ieee80211_ref_node(ni);
@@ -2319,8 +2321,8 @@ ieee80211_iterate_nodes(struct ieee80211_node_table *nt,
max_aid = vap->iv_max_aid;
size = max_aid * sizeof(struct ieee80211_node *);
- ni_arr = (struct ieee80211_node **) malloc(size, M_80211_NODE,
- M_NOWAIT | M_ZERO);
+ ni_arr = (struct ieee80211_node **) IEEE80211_MALLOC(size, M_80211_NODE,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (ni_arr == NULL)
return;
@@ -2343,7 +2345,7 @@ ieee80211_iterate_nodes(struct ieee80211_node_table *nt,
}
done:
- free(ni_arr, M_80211_NODE);
+ IEEE80211_FREE(ni_arr, M_80211_NODE);
}
void
diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c
index 2158bee56ca0..d11628df04ac 100644
--- a/sys/net80211/ieee80211_output.c
+++ b/sys/net80211/ieee80211_output.c
@@ -508,6 +508,26 @@ ieee80211_raw_output(struct ieee80211vap *vap, struct ieee80211_node *ni,
{
struct ieee80211com *ic = vap->iv_ic;
+ /*
+ * Set node - the caller has taken a reference, so ensure
+ * that the mbuf has the same node value that
+ * it would if it were going via the normal path.
+ */
+ m->m_pkthdr.rcvif = (void *)ni;
+
+ /*
+ * Attempt to add bpf transmit parameters.
+ *
+ * For now it's ok to fail; the raw_xmit api still takes
+ * them as an option.
+ *
+ * Later on when ic_raw_xmit() has params removed,
+ * they'll have to be added - so fail the transmit if
+ * they can't be.
+ */
+ if (params)
+ (void) ieee80211_add_xmit_params(m, params);
+
return (ic->ic_raw_xmit(ni, m, params));
}
@@ -516,15 +536,9 @@ ieee80211_raw_output(struct ieee80211vap *vap, struct ieee80211_node *ni,
* connect bpf write calls to the 802.11 layer for injecting
* raw 802.11 frames.
*/
-#if __FreeBSD_version >= 1000031
int
ieee80211_output(struct ifnet *ifp, struct mbuf *m,
const struct sockaddr *dst, struct route *ro)
-#else
-int
-ieee80211_output(struct ifnet *ifp, struct mbuf *m,
- struct sockaddr *dst, struct route *ro)
-#endif
{
#define senderr(e) do { error = (e); goto bad;} while (0)
struct ieee80211_node *ni = NULL;
@@ -1950,7 +1964,7 @@ ieee80211_add_countryie(uint8_t *frm, struct ieee80211com *ic)
* re-calculation.
*/
if (ic->ic_countryie != NULL)
- free(ic->ic_countryie, M_80211_NODE_IE);
+ IEEE80211_FREE(ic->ic_countryie, M_80211_NODE_IE);
ic->ic_countryie = ieee80211_alloc_countryie(ic);
if (ic->ic_countryie == NULL)
return frm;
diff --git a/sys/net80211/ieee80211_power.c b/sys/net80211/ieee80211_power.c
index 812cd7053ce9..91668cc7c0d2 100644
--- a/sys/net80211/ieee80211_power.c
+++ b/sys/net80211/ieee80211_power.c
@@ -83,8 +83,9 @@ ieee80211_power_latevattach(struct ieee80211vap *vap)
*/
if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
vap->iv_tim_len = howmany(vap->iv_max_aid,8) * sizeof(uint8_t);
- vap->iv_tim_bitmap = (uint8_t *) malloc(vap->iv_tim_len,
- M_80211_POWER, M_NOWAIT | M_ZERO);
+ vap->iv_tim_bitmap = (uint8_t *) IEEE80211_MALLOC(vap->iv_tim_len,
+ M_80211_POWER,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (vap->iv_tim_bitmap == NULL) {
printf("%s: no memory for TIM bitmap!\n", __func__);
/* XXX good enough to keep from crashing? */
@@ -97,7 +98,7 @@ void
ieee80211_power_vdetach(struct ieee80211vap *vap)
{
if (vap->iv_tim_bitmap != NULL) {
- free(vap->iv_tim_bitmap, M_80211_POWER);
+ IEEE80211_FREE(vap->iv_tim_bitmap, M_80211_POWER);
vap->iv_tim_bitmap = NULL;
}
}
diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c
index 1f096168d927..01c60e1614e5 100644
--- a/sys/net80211/ieee80211_proto.c
+++ b/sys/net80211/ieee80211_proto.c
@@ -113,9 +113,8 @@ static int
null_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
- struct ifnet *ifp = ni->ni_ic->ic_ifp;
- if_printf(ifp, "missing ic_raw_xmit callback, drop frame\n");
+ ic_printf(ni->ni_ic, "missing ic_raw_xmit callback, drop frame\n");
m_freem(m);
return ENETDOWN;
}
@@ -251,7 +250,7 @@ ieee80211_proto_vdetach(struct ieee80211vap *vap)
{
#define FREEAPPIE(ie) do { \
if (ie != NULL) \
- free(ie, M_80211_NODE_IE); \
+ IEEE80211_FREE(ie, M_80211_NODE_IE); \
} while (0)
/*
* Detach operating mode module.
@@ -651,7 +650,7 @@ ieee80211_set_shortslottime(struct ieee80211com *ic, int onoff)
ic->ic_flags &= ~IEEE80211_F_SHSLOT;
/* notify driver */
if (ic->ic_updateslot != NULL)
- ic->ic_updateslot(ic->ic_ifp);
+ ic->ic_updateslot(ic);
}
/*
@@ -1165,18 +1164,16 @@ static void
update_mcast(void *arg, int npending)
{
struct ieee80211com *ic = arg;
- struct ifnet *parent = ic->ic_ifp;
- ic->ic_update_mcast(parent);
+ ic->ic_update_mcast(ic);
}
static void
update_promisc(void *arg, int npending)
{
struct ieee80211com *ic = arg;
- struct ifnet *parent = ic->ic_ifp;
- ic->ic_update_promisc(parent);
+ ic->ic_update_promisc(ic);
}
static void
diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h
index 3b46ac4b1ecd..a8123931588f 100644
--- a/sys/net80211/ieee80211_proto.h
+++ b/sys/net80211/ieee80211_proto.h
@@ -68,6 +68,9 @@ void ieee80211_syncflag_ext(struct ieee80211vap *, int flag);
#define IEEE80211_R_C_RSSI 0x0000010 /* per-chain RSSI value valid */
#define IEEE80211_R_C_EVM 0x0000020 /* per-chain EVM valid */
#define IEEE80211_R_C_HT40 0x0000040 /* RX'ed packet is 40mhz, pilots 4,5 valid */
+#define IEEE80211_R_FREQ 0x0000080 /* Freq value populated, MHz */
+#define IEEE80211_R_IEEE 0x0000100 /* IEEE value populated */
+#define IEEE80211_R_BAND 0x0000200 /* Frequency band populated */
struct ieee80211_rx_stats {
uint32_t r_flags; /* IEEE80211_R_* flags */
@@ -80,10 +83,12 @@ struct ieee80211_rx_stats {
uint8_t rssi; /* global RSSI */
uint8_t evm[IEEE80211_MAX_CHAINS][IEEE80211_MAX_EVM_PILOTS];
/* per-chain, per-pilot EVM values */
+ uint16_t c_freq;
+ uint8_t c_ieee;
};
#define ieee80211_input(ni, m, rssi, nf) \
- ((ni)->ni_vap->iv_input(ni, m, rssi, nf))
+ ((ni)->ni_vap->iv_input(ni, m, NULL, rssi, nf))
int ieee80211_input_all(struct ieee80211com *, struct mbuf *, int, int);
int ieee80211_input_mimo(struct ieee80211_node *, struct mbuf *,
@@ -96,13 +101,8 @@ int ieee80211_mgmt_output(struct ieee80211_node *, struct mbuf *, int,
struct ieee80211_bpf_params *);
int ieee80211_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
-#if __FreeBSD_version >= 1000031
int ieee80211_output(struct ifnet *, struct mbuf *,
const struct sockaddr *, struct route *ro);
-#else
-int ieee80211_output(struct ifnet *, struct mbuf *,
- struct sockaddr *, struct route *ro);
-#endif
int ieee80211_vap_pkt_send_dest(struct ieee80211vap *, struct mbuf *,
struct ieee80211_node *);
int ieee80211_raw_output(struct ieee80211vap *, struct ieee80211_node *,
diff --git a/sys/net80211/ieee80211_radiotap.c b/sys/net80211/ieee80211_radiotap.c
index 5638f52c2ca9..eb218dd4ffba 100644
--- a/sys/net80211/ieee80211_radiotap.c
+++ b/sys/net80211/ieee80211_radiotap.c
@@ -43,7 +43,6 @@ __FBSDID("$FreeBSD$");
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_var.h>
-#include <net/if_llc.h>
#include <net/if_media.h>
#include <net/ethernet.h>
@@ -80,8 +79,8 @@ ieee80211_radiotap_attachv(struct ieee80211com *ic,
else if (tx_radiotap & B(IEEE80211_RADIOTAP_XCHANNEL))
off = radiotap_offset(th, n_tx_v, IEEE80211_RADIOTAP_XCHANNEL);
if (off == -1) {
- if_printf(ic->ic_ifp, "%s: no tx channel, radiotap 0x%x\n",
- __func__, tx_radiotap);
+ ic_printf(ic, "%s: no tx channel, radiotap 0x%x\n", __func__,
+ tx_radiotap);
/* NB: we handle this case but data will have no chan spec */
} else
ic->ic_txchan = ((uint8_t *) th) + off;
@@ -96,8 +95,8 @@ ieee80211_radiotap_attachv(struct ieee80211com *ic,
else if (rx_radiotap & B(IEEE80211_RADIOTAP_XCHANNEL))
off = radiotap_offset(rh, n_rx_v, IEEE80211_RADIOTAP_XCHANNEL);
if (off == -1) {
- if_printf(ic->ic_ifp, "%s: no rx channel, radiotap 0x%x\n",
- __func__, rx_radiotap);
+ ic_printf(ic, "%s: no rx channel, radiotap 0x%x\n", __func__,
+ rx_radiotap);
/* NB: we handle this case but data will have no chan spec */
} else
ic->ic_rxchan = ((uint8_t *) rh) + off;
diff --git a/sys/net80211/ieee80211_ratectl_none.c b/sys/net80211/ieee80211_ratectl_none.c
index a0056f3f5355..5a45a74ea7a3 100644
--- a/sys/net80211/ieee80211_ratectl_none.c
+++ b/sys/net80211/ieee80211_ratectl_none.c
@@ -56,7 +56,7 @@ none_init(struct ieee80211vap *vap)
static void
none_deinit(struct ieee80211vap *vap)
{
- free(vap->iv_rs, M_80211_RATECTL);
+ IEEE80211_FREE(vap->iv_rs, M_80211_RATECTL);
}
static void
diff --git a/sys/net80211/ieee80211_regdomain.c b/sys/net80211/ieee80211_regdomain.c
index ed7f4227ef53..9dfef2c5f168 100644
--- a/sys/net80211/ieee80211_regdomain.c
+++ b/sys/net80211/ieee80211_regdomain.c
@@ -84,7 +84,7 @@ void
ieee80211_regdomain_detach(struct ieee80211com *ic)
{
if (ic->ic_countryie != NULL) {
- free(ic->ic_countryie, M_80211_NODE_IE);
+ IEEE80211_FREE(ic->ic_countryie, M_80211_NODE_IE);
ic->ic_countryie = NULL;
}
}
@@ -301,19 +301,19 @@ ieee80211_alloc_countryie(struct ieee80211com *ic)
struct ieee80211_country_ie *ie;
int i, skip, nruns;
- aie = malloc(IEEE80211_COUNTRY_MAX_SIZE, M_80211_NODE_IE,
- M_NOWAIT | M_ZERO);
+ aie = IEEE80211_MALLOC(IEEE80211_COUNTRY_MAX_SIZE, M_80211_NODE_IE,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (aie == NULL) {
- if_printf(ic->ic_ifp,
- "%s: unable to allocate memory for country ie\n", __func__);
+ ic_printf(ic, "%s: unable to allocate memory for country ie\n",
+ __func__);
/* XXX stat */
return NULL;
}
ie = (struct ieee80211_country_ie *) aie->ie_data;
ie->ie = IEEE80211_ELEMID_COUNTRY;
if (rd->isocc[0] == '\0') {
- if_printf(ic->ic_ifp, "no ISO country string for cc %d; "
- "using blanks\n", rd->country);
+ ic_printf(ic, "no ISO country string for cc %d; using blanks\n",
+ rd->country);
ie->cc[0] = ie->cc[1] = ' ';
} else {
ie->cc[0] = rd->isocc[0];
@@ -350,7 +350,7 @@ ieee80211_alloc_countryie(struct ieee80211com *ic)
if (c->ic_ieee != nextchan ||
c->ic_maxregpower != frm[-1]) { /* new run */
if (nruns == IEEE80211_COUNTRY_MAX_BANDS) {
- if_printf(ic->ic_ifp, "%s: country ie too big, "
+ ic_printf(ic, "%s: country ie too big, "
"runs > max %d, truncating\n",
__func__, IEEE80211_COUNTRY_MAX_BANDS);
/* XXX stat? fail? */
@@ -493,7 +493,7 @@ ieee80211_setregdomain(struct ieee80211vap *vap,
* Invalidate channel-related state.
*/
if (ic->ic_countryie != NULL) {
- free(ic->ic_countryie, M_80211_NODE_IE);
+ IEEE80211_FREE(ic->ic_countryie, M_80211_NODE_IE);
ic->ic_countryie = NULL;
}
ieee80211_scan_flush(vap);
diff --git a/sys/net80211/ieee80211_rssadapt.c b/sys/net80211/ieee80211_rssadapt.c
index f230f60d8f4f..b5fdb86b69b4 100644
--- a/sys/net80211/ieee80211_rssadapt.c
+++ b/sys/net80211/ieee80211_rssadapt.c
@@ -132,8 +132,8 @@ rssadapt_init(struct ieee80211vap *vap)
KASSERT(vap->iv_rs == NULL, ("%s: iv_rs already initialized",
__func__));
- vap->iv_rs = rs = malloc(sizeof(struct ieee80211_rssadapt),
- M_80211_RATECTL, M_NOWAIT|M_ZERO);
+ vap->iv_rs = rs = IEEE80211_MALLOC(sizeof(struct ieee80211_rssadapt),
+ M_80211_RATECTL, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (rs == NULL) {
if_printf(vap->iv_ifp, "couldn't alloc ratectl structure\n");
return;
@@ -146,7 +146,7 @@ rssadapt_init(struct ieee80211vap *vap)
static void
rssadapt_deinit(struct ieee80211vap *vap)
{
- free(vap->iv_rs, M_80211_RATECTL);
+ IEEE80211_FREE(vap->iv_rs, M_80211_RATECTL);
}
static void
@@ -175,8 +175,8 @@ rssadapt_node_init(struct ieee80211_node *ni)
if (ni->ni_rctls == NULL) {
ni->ni_rctls = ra =
- malloc(sizeof(struct ieee80211_rssadapt_node),
- M_80211_RATECTL, M_NOWAIT|M_ZERO);
+ IEEE80211_MALLOC(sizeof(struct ieee80211_rssadapt_node),
+ M_80211_RATECTL, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (ra == NULL) {
if_printf(vap->iv_ifp, "couldn't alloc per-node ratectl "
"structure\n");
@@ -204,7 +204,7 @@ static void
rssadapt_node_deinit(struct ieee80211_node *ni)
{
- free(ni->ni_rctls, M_80211_RATECTL);
+ IEEE80211_FREE(ni->ni_rctls, M_80211_RATECTL);
}
static __inline int
diff --git a/sys/net80211/ieee80211_scan.c b/sys/net80211/ieee80211_scan.c
index 6c950d6bc88d..f28a9829d60d 100644
--- a/sys/net80211/ieee80211_scan.c
+++ b/sys/net80211/ieee80211_scan.c
@@ -71,15 +71,14 @@ __FBSDID("$FreeBSD$");
void
ieee80211_scan_attach(struct ieee80211com *ic)
{
-
/*
- * For now, the swscan module does both the
- * allocation (so it can pad it) and sets up the net80211
- * bits.
- *
- * I'll split this stuff later.
+ * If there's no scan method pointer, attach the
+ * swscan set as a default.
*/
- ieee80211_swscan_attach(ic);
+ if (ic->ic_scan_methods == NULL)
+ ieee80211_swscan_attach(ic);
+ else
+ ic->ic_scan_methods->sc_attach(ic);
}
void
@@ -88,12 +87,11 @@ ieee80211_scan_detach(struct ieee80211com *ic)
/*
* Ideally we'd do the ss_ops detach call here;
- * but then ieee80211_swscan_detach would need
- * to be split in two.
+ * but then sc_detach() would need to be split in two.
*
* I'll do that later.
*/
- ieee80211_swscan_detach(ic);
+ ic->ic_scan_methods->sc_detach(ic);
}
static const struct ieee80211_roamparam defroam[IEEE80211_MODE_MAX] = {
@@ -122,6 +120,8 @@ static const struct ieee80211_roamparam defroam[IEEE80211_MODE_MAX] = {
void
ieee80211_scan_vattach(struct ieee80211vap *vap)
{
+ struct ieee80211com *ic = vap->iv_ic;
+
vap->iv_bgscanidle = (IEEE80211_BGSCAN_IDLE_DEFAULT*1000)/hz;
vap->iv_bgscanintvl = IEEE80211_BGSCAN_INTVAL_DEFAULT*hz;
vap->iv_scanvalid = IEEE80211_SCAN_VALID_DEFAULT*hz;
@@ -129,7 +129,7 @@ ieee80211_scan_vattach(struct ieee80211vap *vap)
vap->iv_roaming = IEEE80211_ROAMING_AUTO;
memcpy(vap->iv_roamparms, defroam, sizeof(defroam));
- ieee80211_swscan_vattach(vap);
+ ic->ic_scan_methods->sc_vattach(vap);
}
void
@@ -141,7 +141,7 @@ ieee80211_scan_vdetach(struct ieee80211vap *vap)
IEEE80211_LOCK(ic);
ss = ic->ic_scan;
- ieee80211_swscan_vdetach(vap);
+ ic->ic_scan_methods->sc_vdetach(vap);
if (ss != NULL && ss->ss_vap == vap) {
if (ss->ss_ops != NULL) {
@@ -314,6 +314,7 @@ ieee80211_start_scan(struct ieee80211vap *vap, int flags,
u_int nssid, const struct ieee80211_scan_ssid ssids[])
{
const struct ieee80211_scanner *scan;
+ struct ieee80211com *ic = vap->iv_ic;
scan = ieee80211_scanner_get(vap->iv_opmode);
if (scan == NULL) {
@@ -324,8 +325,7 @@ ieee80211_start_scan(struct ieee80211vap *vap, int flags,
return 0;
}
- /* XXX ops */
- return ieee80211_swscan_start_scan(scan, vap, flags, duration,
+ return ic->ic_scan_methods->sc_start_scan(scan, vap, flags, duration,
mindwell, maxdwell, nssid, ssids);
}
@@ -376,11 +376,10 @@ ieee80211_check_scan(struct ieee80211vap *vap, int flags,
/*
* XXX TODO: separate things out a bit better.
- * XXX TODO: ops
*/
ieee80211_scan_update_locked(vap, scan);
- result = ieee80211_swscan_check_scan(scan, vap, flags, duration,
+ result = ic->ic_scan_methods->sc_check_scan(scan, vap, flags, duration,
mindwell, maxdwell, nssid, ssids);
IEEE80211_UNLOCK(ic);
@@ -408,6 +407,7 @@ ieee80211_check_scan_current(struct ieee80211vap *vap)
int
ieee80211_bg_scan(struct ieee80211vap *vap, int flags)
{
+ struct ieee80211com *ic = vap->iv_ic;
const struct ieee80211_scanner *scan;
// IEEE80211_UNLOCK_ASSERT(sc);
@@ -425,10 +425,8 @@ ieee80211_bg_scan(struct ieee80211vap *vap, int flags)
* XXX TODO: pull apart the bgscan logic into whatever
* belongs here and whatever belongs in the software
* scanner.
- *
- * XXX TODO: ops
*/
- return (ieee80211_swscan_bg_scan(scan, vap, flags));
+ return (ic->ic_scan_methods->sc_bg_scan(scan, vap, flags));
}
/*
@@ -437,9 +435,9 @@ ieee80211_bg_scan(struct ieee80211vap *vap, int flags)
void
ieee80211_cancel_scan(struct ieee80211vap *vap)
{
+ struct ieee80211com *ic = vap->iv_ic;
- /* XXX TODO: ops */
- ieee80211_swscan_cancel_scan(vap);
+ ic->ic_scan_methods->sc_cancel_scan(vap);
}
/*
@@ -448,9 +446,9 @@ ieee80211_cancel_scan(struct ieee80211vap *vap)
void
ieee80211_cancel_anyscan(struct ieee80211vap *vap)
{
+ struct ieee80211com *ic = vap->iv_ic;
- /* XXX TODO: ops */
- ieee80211_swscan_cancel_anyscan(vap);
+ ic->ic_scan_methods->sc_cancel_anyscan(vap);
}
/*
@@ -460,9 +458,9 @@ ieee80211_cancel_anyscan(struct ieee80211vap *vap)
void
ieee80211_scan_next(struct ieee80211vap *vap)
{
+ struct ieee80211com *ic = vap->iv_ic;
- /* XXX TODO: ops */
- ieee80211_swscan_scan_next(vap);
+ ic->ic_scan_methods->sc_scan_next(vap);
}
/*
@@ -481,8 +479,7 @@ ieee80211_scan_done(struct ieee80211vap *vap)
ss = ic->ic_scan;
ss->ss_next = ss->ss_last; /* all channels are complete */
- /* XXX TODO: ops */
- ieee80211_swscan_scan_done(vap);
+ ic->ic_scan_methods->sc_scan_done(vap);
IEEE80211_UNLOCK(ic);
}
@@ -504,8 +501,7 @@ ieee80211_probe_curchan(struct ieee80211vap *vap, int force)
return;
}
- /* XXX TODO: ops */
- ieee80211_swscan_probe_curchan(vap, force);
+ ic->ic_scan_methods->sc_scan_probe_curchan(vap, force);
}
#ifdef IEEE80211_DEBUG
@@ -567,8 +563,9 @@ ieee80211_add_scan(struct ieee80211vap *vap,
const struct ieee80211_frame *wh,
int subtype, int rssi, int noise)
{
+ struct ieee80211com *ic = vap->iv_ic;
- return (ieee80211_swscan_add_scan(vap, curchan, sp, wh, subtype,
+ return (ic->ic_scan_methods->sc_add_scan(vap, curchan, sp, wh, subtype,
rssi, noise));
}
diff --git a/sys/net80211/ieee80211_scan.h b/sys/net80211/ieee80211_scan.h
index 8b54186af517..f568b651151c 100644
--- a/sys/net80211/ieee80211_scan.h
+++ b/sys/net80211/ieee80211_scan.h
@@ -80,6 +80,39 @@ struct ieee80211_scan_ssid {
#define IEEE80211_SCAN_MAX_SSID 1 /* max # ssid's to probe */
/*
+ * High-level implementation visible to ieee80211_scan.[ch].
+ *
+ * The default scanner (ieee80211_scan_sw.[ch]) implements a software
+ * driven scanner. Firmware driven scanning needs a different set of
+ * behaviours.
+ */
+struct ieee80211_scan_methods {
+ void (*sc_attach)(struct ieee80211com *);
+ void (*sc_detach)(struct ieee80211com *);
+ void (*sc_vattach)(struct ieee80211vap *);
+ void (*sc_vdetach)(struct ieee80211vap *);
+ void (*sc_set_scan_duration)(struct ieee80211vap *, u_int);
+ int (*sc_start_scan)(const struct ieee80211_scanner *,
+ struct ieee80211vap *, int, u_int, u_int, u_int, u_int,
+ const struct ieee80211_scan_ssid ssids[]);
+ int (*sc_check_scan)(const struct ieee80211_scanner *,
+ struct ieee80211vap *, int, u_int, u_int, u_int, u_int,
+ const struct ieee80211_scan_ssid ssids[]);
+ int (*sc_bg_scan)(const struct ieee80211_scanner *,
+ struct ieee80211vap *, int);
+ void (*sc_cancel_scan)(struct ieee80211vap *);
+ void (*sc_cancel_anyscan)(struct ieee80211vap *);
+ void (*sc_scan_next)(struct ieee80211vap *);
+ void (*sc_scan_done)(struct ieee80211vap *);
+ void (*sc_scan_probe_curchan)(struct ieee80211vap *, int);
+ void (*sc_add_scan)(struct ieee80211vap *,
+ struct ieee80211_channel *,
+ const struct ieee80211_scanparams *,
+ const struct ieee80211_frame *,
+ int, int, int);
+};
+
+/*
* Scan state visible to the 802.11 layer. Scan parameters and
* results are stored in this data structure. The ieee80211_scan_state
* structure is extended with space that is maintained private to
diff --git a/sys/net80211/ieee80211_scan_sta.c b/sys/net80211/ieee80211_scan_sta.c
index 1fb45b098e31..c0cbb7d2de4f 100644
--- a/sys/net80211/ieee80211_scan_sta.c
+++ b/sys/net80211/ieee80211_scan_sta.c
@@ -102,7 +102,7 @@ struct sta_table {
ieee80211_scan_table_lock_t st_lock; /* on scan table */
TAILQ_HEAD(, sta_entry) st_entry; /* all entries */
LIST_HEAD(, sta_entry) st_hash[STA_HASHSIZE];
- struct mtx st_scanlock; /* on st_scaniter */
+ ieee80211_scan_iter_lock_t st_scanlock; /* on st_scaniter */
u_int st_scaniter; /* gen# for iterator */
u_int st_scangen; /* scan generation # */
int st_newscan;
@@ -159,12 +159,13 @@ sta_attach(struct ieee80211_scan_state *ss)
{
struct sta_table *st;
- st = (struct sta_table *) malloc(sizeof(struct sta_table),
- M_80211_SCAN, M_NOWAIT | M_ZERO);
+ st = (struct sta_table *) IEEE80211_MALLOC(sizeof(struct sta_table),
+ M_80211_SCAN,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (st == NULL)
return 0;
IEEE80211_SCAN_TABLE_LOCK_INIT(st, "scantable");
- mtx_init(&st->st_scanlock, "scangen", "802.11 scangen", MTX_DEF);
+ IEEE80211_SCAN_ITER_LOCK_INIT(st, "scangen");
TAILQ_INIT(&st->st_entry);
ss->ss_priv = st;
nrefs++; /* NB: we assume caller locking */
@@ -182,8 +183,8 @@ sta_detach(struct ieee80211_scan_state *ss)
if (st != NULL) {
sta_flush_table(st);
IEEE80211_SCAN_TABLE_LOCK_DESTROY(st);
- mtx_destroy(&st->st_scanlock);
- free(st, M_80211_SCAN);
+ IEEE80211_SCAN_ITER_LOCK_DESTROY(st);
+ IEEE80211_FREE(st, M_80211_SCAN);
KASSERT(nrefs > 0, ("imbalanced attach/detach"));
nrefs--; /* NB: we assume caller locking */
}
@@ -217,7 +218,7 @@ sta_flush_table(struct sta_table *st)
TAILQ_REMOVE(&st->st_entry, se, se_list);
LIST_REMOVE(se, se_hash);
ieee80211_ies_cleanup(&se->base.se_ies);
- free(se, M_80211_SCAN);
+ IEEE80211_FREE(se, M_80211_SCAN);
}
memset(st->st_maxrssi, 0, sizeof(st->st_maxrssi));
}
@@ -252,8 +253,8 @@ sta_add(struct ieee80211_scan_state *ss,
LIST_FOREACH(se, &st->st_hash[hash], se_hash)
if (IEEE80211_ADDR_EQ(se->base.se_macaddr, macaddr))
goto found;
- se = (struct sta_entry *) malloc(sizeof(struct sta_entry),
- M_80211_SCAN, M_NOWAIT | M_ZERO);
+ se = (struct sta_entry *) IEEE80211_MALLOC(sizeof(struct sta_entry),
+ M_80211_SCAN, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (se == NULL) {
IEEE80211_SCAN_TABLE_UNLOCK(st);
return 0;
@@ -1402,7 +1403,7 @@ sta_iterate(struct ieee80211_scan_state *ss,
struct sta_entry *se;
u_int gen;
- mtx_lock(&st->st_scanlock);
+ IEEE80211_SCAN_ITER_LOCK(st);
gen = st->st_scaniter++;
restart:
IEEE80211_SCAN_TABLE_LOCK(st);
@@ -1418,7 +1419,7 @@ restart:
}
IEEE80211_SCAN_TABLE_UNLOCK(st);
- mtx_unlock(&st->st_scanlock);
+ IEEE80211_SCAN_ITER_UNLOCK(st);
}
static void
@@ -1680,7 +1681,7 @@ adhoc_age(struct ieee80211_scan_state *ss)
TAILQ_REMOVE(&st->st_entry, se, se_list);
LIST_REMOVE(se, se_hash);
ieee80211_ies_cleanup(&se->base.se_ies);
- free(se, M_80211_SCAN);
+ IEEE80211_FREE(se, M_80211_SCAN);
}
}
IEEE80211_SCAN_TABLE_UNLOCK(st);
diff --git a/sys/net80211/ieee80211_scan_sw.c b/sys/net80211/ieee80211_scan_sw.c
index 70b4673294f9..eb58386fc907 100644
--- a/sys/net80211/ieee80211_scan_sw.c
+++ b/sys/net80211/ieee80211_scan_sw.c
@@ -102,33 +102,7 @@ static void scan_task(void *, int);
MALLOC_DEFINE(M_80211_SCAN, "80211scan", "802.11 scan state");
-void
-ieee80211_swscan_attach(struct ieee80211com *ic)
-{
- struct scan_state *ss;
-
- ss = (struct scan_state *) malloc(sizeof(struct scan_state),
- M_80211_SCAN, M_NOWAIT | M_ZERO);
- if (ss == NULL) {
- ic->ic_scan = NULL;
- return;
- }
- callout_init_mtx(&ss->ss_scan_timer, IEEE80211_LOCK_OBJ(ic), 0);
- cv_init(&ss->ss_scan_cv, "scan");
- TASK_INIT(&ss->ss_scan_task, 0, scan_task, ss);
-
- ic->ic_scan = &ss->base;
- ss->base.ss_ic = ic;
-
- ic->ic_scan_curchan = scan_curchan;
- ic->ic_scan_mindwell = scan_mindwell;
-
- /*
- * TODO: all of the non-vap scan calls should be methods!
- */
-}
-
-void
+static void
ieee80211_swscan_detach(struct ieee80211com *ic)
{
struct ieee80211_scan_state *ss = ic->ic_scan;
@@ -155,11 +129,11 @@ ieee80211_swscan_detach(struct ieee80211com *ic)
ss->ss_ops = NULL;
}
ic->ic_scan = NULL;
- free(SCAN_PRIVATE(ss), M_80211_SCAN);
+ IEEE80211_FREE(SCAN_PRIVATE(ss), M_80211_SCAN);
}
}
-void
+static void
ieee80211_swscan_vattach(struct ieee80211vap *vap)
{
/* nothing to do for now */
@@ -169,7 +143,7 @@ ieee80211_swscan_vattach(struct ieee80211vap *vap)
}
-void
+static void
ieee80211_swscan_vdetach(struct ieee80211vap *vap)
{
struct ieee80211com *ic = vap->iv_ic;
@@ -185,7 +159,7 @@ ieee80211_swscan_vdetach(struct ieee80211vap *vap)
}
}
-void
+static void
ieee80211_swscan_set_scan_duration(struct ieee80211vap *vap, u_int duration)
{
struct ieee80211com *ic = vap->iv_ic;
@@ -198,17 +172,6 @@ ieee80211_swscan_set_scan_duration(struct ieee80211vap *vap, u_int duration)
SCAN_PRIVATE(ss)->ss_duration = duration;
}
-void
-ieee80211_swscan_run_scan_task(struct ieee80211vap *vap)
-{
- struct ieee80211com *ic = vap->iv_ic;
- struct ieee80211_scan_state *ss = ic->ic_scan;
-
- IEEE80211_LOCK_ASSERT(ic);
-
- ieee80211_runtask(ic, &SCAN_PRIVATE(ss)->ss_scan_task);
-}
-
/*
* Start a scan unless one is already going.
*/
@@ -272,7 +235,7 @@ ieee80211_swscan_start_scan_locked(const struct ieee80211_scanner *scan,
ic->ic_flags |= IEEE80211_F_SCAN;
/* Start scan task */
- ieee80211_swscan_run_scan_task(vap);
+ ieee80211_runtask(ic, &SCAN_PRIVATE(ss)->ss_scan_task);
}
return 1;
} else {
@@ -289,7 +252,7 @@ ieee80211_swscan_start_scan_locked(const struct ieee80211_scanner *scan,
*
* Called without the comlock held; grab the comlock as appropriate.
*/
-int
+static int
ieee80211_swscan_start_scan(const struct ieee80211_scanner *scan,
struct ieee80211vap *vap, int flags,
u_int duration, u_int mindwell, u_int maxdwell,
@@ -316,7 +279,7 @@ ieee80211_swscan_start_scan(const struct ieee80211_scanner *scan,
*
* XXX TODO: split out!
*/
-int
+static int
ieee80211_swscan_check_scan(const struct ieee80211_scanner *scan,
struct ieee80211vap *vap, int flags,
u_int duration, u_int mindwell, u_int maxdwell,
@@ -374,7 +337,7 @@ ieee80211_swscan_check_scan(const struct ieee80211_scanner *scan,
* Restart a previous scan. If the previous scan completed
* then we start again using the existing channel list.
*/
-int
+static int
ieee80211_swscan_bg_scan(const struct ieee80211_scanner *scan,
struct ieee80211vap *vap, int flags)
{
@@ -465,7 +428,7 @@ ieee80211_swscan_bg_scan(const struct ieee80211_scanner *scan,
/*
* Cancel any scan currently going on for the specified vap.
*/
-void
+static void
ieee80211_swscan_cancel_scan(struct ieee80211vap *vap)
{
struct ieee80211com *ic = vap->iv_ic;
@@ -499,7 +462,7 @@ ieee80211_swscan_cancel_scan(struct ieee80211vap *vap)
/*
* Cancel any scan currently going on.
*/
-void
+static void
ieee80211_swscan_cancel_anyscan(struct ieee80211vap *vap)
{
struct ieee80211com *ic = vap->iv_ic;
@@ -533,7 +496,7 @@ ieee80211_swscan_cancel_anyscan(struct ieee80211vap *vap)
* Public access to scan_next for drivers that manage
* scanning themselves (e.g. for firmware-based devices).
*/
-void
+static void
ieee80211_swscan_scan_next(struct ieee80211vap *vap)
{
struct ieee80211com *ic = vap->iv_ic;
@@ -551,7 +514,7 @@ ieee80211_swscan_scan_next(struct ieee80211vap *vap)
* Public access to scan_next for drivers that are not able to scan single
* channels (e.g. for firmware-based devices).
*/
-void
+static void
ieee80211_swscan_scan_done(struct ieee80211vap *vap)
{
struct ieee80211com *ic = vap->iv_ic;
@@ -570,7 +533,7 @@ ieee80211_swscan_scan_done(struct ieee80211vap *vap)
* listen for beacons on the channel; if we receive something
* then we'll transmit a probe request.
*/
-void
+static void
ieee80211_swscan_probe_curchan(struct ieee80211vap *vap, int force)
{
struct ieee80211com *ic = vap->iv_ic;
@@ -898,7 +861,7 @@ done:
/*
* Process a beacon or probe response frame.
*/
-void
+static void
ieee80211_swscan_add_scan(struct ieee80211vap *vap,
struct ieee80211_channel *curchan,
const struct ieee80211_scanparams *sp,
@@ -946,3 +909,50 @@ ieee80211_swscan_add_scan(struct ieee80211vap *vap,
}
}
+static struct ieee80211_scan_methods swscan_methods = {
+ .sc_attach = ieee80211_swscan_attach,
+ .sc_detach = ieee80211_swscan_detach,
+ .sc_vattach = ieee80211_swscan_vattach,
+ .sc_vdetach = ieee80211_swscan_vdetach,
+ .sc_set_scan_duration = ieee80211_swscan_set_scan_duration,
+ .sc_start_scan = ieee80211_swscan_start_scan,
+ .sc_check_scan = ieee80211_swscan_check_scan,
+ .sc_bg_scan = ieee80211_swscan_bg_scan,
+ .sc_cancel_scan = ieee80211_swscan_cancel_scan,
+ .sc_cancel_anyscan = ieee80211_swscan_cancel_anyscan,
+ .sc_scan_next = ieee80211_swscan_scan_next,
+ .sc_scan_done = ieee80211_swscan_scan_done,
+ .sc_scan_probe_curchan = ieee80211_swscan_probe_curchan,
+ .sc_add_scan = ieee80211_swscan_add_scan
+};
+
+/*
+ * Default scan attach method.
+ */
+void
+ieee80211_swscan_attach(struct ieee80211com *ic)
+{
+ struct scan_state *ss;
+
+ /*
+ * Setup the default methods
+ */
+ ic->ic_scan_methods = &swscan_methods;
+
+ /* Allocate initial scan state */
+ ss = (struct scan_state *) IEEE80211_MALLOC(sizeof(struct scan_state),
+ M_80211_SCAN, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
+ if (ss == NULL) {
+ ic->ic_scan = NULL;
+ return;
+ }
+ callout_init_mtx(&ss->ss_scan_timer, IEEE80211_LOCK_OBJ(ic), 0);
+ cv_init(&ss->ss_scan_cv, "scan");
+ TASK_INIT(&ss->ss_scan_task, 0, scan_task, ss);
+
+ ic->ic_scan = &ss->base;
+ ss->base.ss_ic = ic;
+
+ ic->ic_scan_curchan = scan_curchan;
+ ic->ic_scan_mindwell = scan_mindwell;
+}
diff --git a/sys/net80211/ieee80211_scan_sw.h b/sys/net80211/ieee80211_scan_sw.h
index 7bb0cc378642..8408933bfeb3 100644
--- a/sys/net80211/ieee80211_scan_sw.h
+++ b/sys/net80211/ieee80211_scan_sw.h
@@ -28,34 +28,5 @@
#define __NET80211_IEEE80211_SCAN_SW_H__
extern void ieee80211_swscan_attach(struct ieee80211com *ic);
-extern void ieee80211_swscan_detach(struct ieee80211com *ic);
-
-extern void ieee80211_swscan_vattach(struct ieee80211vap *vap);
-extern void ieee80211_swscan_vdetach(struct ieee80211vap *vap);
-
-extern int ieee80211_swscan_start_scan(const struct ieee80211_scanner *scan,
- struct ieee80211vap *vap, int flags,
- u_int duration, u_int mindwell, u_int maxdwell,
- u_int nssid, const struct ieee80211_scan_ssid ssids[]);
-extern void ieee80211_swscan_set_scan_duration(struct ieee80211vap *vap,
- u_int duration);
-extern void ieee80211_swscan_run_scan_task(struct ieee80211vap *vap);
-extern int ieee80211_swscan_check_scan(const struct ieee80211_scanner *scan,
- struct ieee80211vap *vap, int flags,
- u_int duration, u_int mindwell, u_int maxdwell,
- u_int nssid, const struct ieee80211_scan_ssid ssids[]);
-extern int ieee80211_swscan_bg_scan(const struct ieee80211_scanner *scan,
- struct ieee80211vap *vap, int flags);
-extern void ieee80211_swscan_cancel_scan(struct ieee80211vap *vap);
-extern void ieee80211_swscan_cancel_anyscan(struct ieee80211vap *vap);
-extern void ieee80211_swscan_scan_next(struct ieee80211vap *vap);
-extern void ieee80211_swscan_scan_done(struct ieee80211vap *vap);
-extern void ieee80211_swscan_probe_curchan(struct ieee80211vap *vap,
- int force);
-extern void ieee80211_swscan_add_scan(struct ieee80211vap *vap,
- struct ieee80211_channel *curchan,
- const struct ieee80211_scanparams *sp,
- const struct ieee80211_frame *wh,
- int subtype, int rssi, int noise);
#endif /* __NET80211_IEEE80211_SCAN_SW_H__ */
diff --git a/sys/net80211/ieee80211_sta.c b/sys/net80211/ieee80211_sta.c
index 267ad1149d73..81d75596b81b 100644
--- a/sys/net80211/ieee80211_sta.c
+++ b/sys/net80211/ieee80211_sta.c
@@ -70,9 +70,10 @@ __FBSDID("$FreeBSD$");
static void sta_vattach(struct ieee80211vap *);
static void sta_beacon_miss(struct ieee80211vap *);
static int sta_newstate(struct ieee80211vap *, enum ieee80211_state, int);
-static int sta_input(struct ieee80211_node *, struct mbuf *, int, int);
+static int sta_input(struct ieee80211_node *, struct mbuf *,
+ const struct ieee80211_rx_stats *, int, int);
static void sta_recv_mgmt(struct ieee80211_node *, struct mbuf *,
- int subtype, int rssi, int nf);
+ int subtype, const struct ieee80211_rx_stats *, int rssi, int nf);
static void sta_recv_ctl(struct ieee80211_node *, struct mbuf *, int subtype);
void
@@ -525,7 +526,8 @@ doprint(struct ieee80211vap *vap, int subtype)
* by the 802.11 layer.
*/
static int
-sta_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
+sta_input(struct ieee80211_node *ni, struct mbuf *m,
+ const struct ieee80211_rx_stats *rxs, int rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
@@ -922,7 +924,7 @@ sta_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
wh = mtod(m, struct ieee80211_frame *);
wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED;
}
- vap->iv_recv_mgmt(ni, m, subtype, rssi, nf);
+ vap->iv_recv_mgmt(ni, m, subtype, rxs, rssi, nf);
goto out;
case IEEE80211_FC0_TYPE_CTL:
@@ -1058,7 +1060,7 @@ sta_auth_shared(struct ieee80211_node *ni, struct ieee80211_frame *wh,
switch (seq) {
case IEEE80211_AUTH_SHARED_PASS:
if (ni->ni_challenge != NULL) {
- free(ni->ni_challenge, M_80211_NODE);
+ IEEE80211_FREE(ni->ni_challenge, M_80211_NODE);
ni->ni_challenge = NULL;
}
if (status != 0) {
@@ -1285,13 +1287,15 @@ startbgscan(struct ieee80211vap *vap)
}
static void
-sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
- int subtype, int rssi, int nf)
+sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype,
+ const struct ieee80211_rx_stats *rxs,
+ int rssi, int nf)
{
#define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
#define ISREASSOC(_st) ((_st) == IEEE80211_FC0_SUBTYPE_REASSOC_RESP)
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
+ struct ieee80211_channel *rxchan = ic->ic_curchan;
struct ieee80211_frame *wh;
uint8_t *frm, *efrm;
uint8_t *rates, *xrates, *wme, *htcap, *htinfo;
@@ -1305,6 +1309,7 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
case IEEE80211_FC0_SUBTYPE_BEACON: {
struct ieee80211_scanparams scan;
+ struct ieee80211_channel *c;
/*
* We process beacon/probe response frames:
* o when scanning, or
@@ -1316,8 +1321,16 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
vap->iv_stats.is_rx_mgtdiscard++;
return;
}
+
+ /* Override RX channel as appropriate */
+ if (rxs != NULL) {
+ c = ieee80211_lookup_channel_rxstatus(vap, rxs);
+ if (c != NULL)
+ rxchan = c;
+ }
+
/* XXX probe response in sta mode when !scanning? */
- if (ieee80211_parse_beacon(ni, m0, &scan) != 0) {
+ if (ieee80211_parse_beacon(ni, m0, rxchan, &scan) != 0) {
if (! (ic->ic_flags & IEEE80211_F_SCAN))
vap->iv_stats.is_beacon_bad++;
return;
@@ -1484,7 +1497,7 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
* our ap.
*/
if (ic->ic_flags & IEEE80211_F_SCAN) {
- ieee80211_add_scan(vap, ic->ic_curchan,
+ ieee80211_add_scan(vap, rxchan,
&scan, wh, subtype, rssi, nf);
} else if (contbgscan(vap)) {
ieee80211_bg_scan(vap, 0);
@@ -1529,7 +1542,7 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
ieee80211_probe_curchan(vap, 1);
ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN;
}
- ieee80211_add_scan(vap, ic->ic_curchan, &scan, wh,
+ ieee80211_add_scan(vap, rxchan, &scan, wh,
subtype, rssi, nf);
return;
}
diff --git a/sys/net80211/ieee80211_superg.c b/sys/net80211/ieee80211_superg.c
index 81a4b43075f3..2e2bbd18be84 100644
--- a/sys/net80211/ieee80211_superg.c
+++ b/sys/net80211/ieee80211_superg.c
@@ -100,9 +100,9 @@ ieee80211_superg_attach(struct ieee80211com *ic)
struct ieee80211_superg *sg;
if (ic->ic_caps & IEEE80211_C_FF) {
- sg = (struct ieee80211_superg *) malloc(
+ sg = (struct ieee80211_superg *) IEEE80211_MALLOC(
sizeof(struct ieee80211_superg), M_80211_VAP,
- M_NOWAIT | M_ZERO);
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (sg == NULL) {
printf("%s: cannot allocate SuperG state block\n",
__func__);
@@ -117,7 +117,7 @@ void
ieee80211_superg_detach(struct ieee80211com *ic)
{
if (ic->ic_superg != NULL) {
- free(ic->ic_superg, M_80211_VAP);
+ IEEE80211_FREE(ic->ic_superg, M_80211_VAP);
ic->ic_superg = NULL;
}
}
diff --git a/sys/net80211/ieee80211_tdma.c b/sys/net80211/ieee80211_tdma.c
index 08acc3897c51..278decf97b9a 100644
--- a/sys/net80211/ieee80211_tdma.c
+++ b/sys/net80211/ieee80211_tdma.c
@@ -115,7 +115,7 @@ static void tdma_vdetach(struct ieee80211vap *vap);
static int tdma_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static void tdma_beacon_miss(struct ieee80211vap *vap);
static void tdma_recv_mgmt(struct ieee80211_node *, struct mbuf *,
- int subtype, int rssi, int nf);
+ int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf);
static int tdma_update(struct ieee80211vap *vap,
const struct ieee80211_tdma_param *tdma, struct ieee80211_node *ni,
int pickslot);
@@ -149,8 +149,9 @@ ieee80211_tdma_vattach(struct ieee80211vap *vap)
KASSERT(vap->iv_caps & IEEE80211_C_TDMA,
("not a tdma vap, caps 0x%x", vap->iv_caps));
- ts = (struct ieee80211_tdma_state *) malloc(
- sizeof(struct ieee80211_tdma_state), M_80211_VAP, M_NOWAIT | M_ZERO);
+ ts = (struct ieee80211_tdma_state *) IEEE80211_MALLOC(
+ sizeof(struct ieee80211_tdma_state), M_80211_VAP,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (ts == NULL) {
printf("%s: cannot allocate TDMA state block\n", __func__);
/* NB: fall back to adhdemo mode */
@@ -199,7 +200,7 @@ tdma_vdetach(struct ieee80211vap *vap)
return;
}
ts->tdma_opdetach(vap);
- free(vap->iv_tdma, M_80211_VAP);
+ IEEE80211_FREE(vap->iv_tdma, M_80211_VAP);
vap->iv_tdma = NULL;
setackpolicy(vap->iv_ic, 0); /* enable ACK's */
@@ -320,7 +321,7 @@ tdma_beacon_miss(struct ieee80211vap *vap)
static void
tdma_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
- int subtype, int rssi, int nf)
+ int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf)
{
struct ieee80211com *ic = ni->ni_ic;
struct ieee80211vap *vap = ni->ni_vap;
@@ -331,7 +332,8 @@ tdma_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
struct ieee80211_frame *wh = mtod(m0, struct ieee80211_frame *);
struct ieee80211_scanparams scan;
- if (ieee80211_parse_beacon(ni, m0, &scan) != 0)
+ /* XXX TODO: use rxstatus to determine off-channel beacons */
+ if (ieee80211_parse_beacon(ni, m0, ic->ic_curchan, &scan) != 0)
return;
if (scan.tdma == NULL) {
/*
@@ -391,7 +393,7 @@ tdma_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
* 2x parsing of the frame but should happen infrequently
*/
}
- ts->tdma_recv_mgmt(ni, m0, subtype, rssi, nf);
+ ts->tdma_recv_mgmt(ni, m0, subtype, rxs, rssi, nf);
}
/*
diff --git a/sys/net80211/ieee80211_tdma.h b/sys/net80211/ieee80211_tdma.h
index 2fe591f73e3e..76b9ed1c3b00 100644
--- a/sys/net80211/ieee80211_tdma.h
+++ b/sys/net80211/ieee80211_tdma.h
@@ -81,7 +81,8 @@ struct ieee80211_tdma_state {
int (*tdma_newstate)(struct ieee80211vap *, enum ieee80211_state,
int arg);
void (*tdma_recv_mgmt)(struct ieee80211_node *,
- struct mbuf *, int, int, int);
+ struct mbuf *, int,
+ const struct ieee80211_rx_stats *rxs, int, int);
void (*tdma_opdetach)(struct ieee80211vap *);
};
diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h
index 471069702324..26238b88e4f1 100644
--- a/sys/net80211/ieee80211_var.h
+++ b/sys/net80211/ieee80211_var.h
@@ -117,6 +117,8 @@ struct ieee80211_frame;
struct ieee80211com {
struct ifnet *ic_ifp; /* associated device */
+ void *ic_softc; /* driver softc */
+ const char *ic_name; /* usually device name */
ieee80211_com_lock_t ic_comlock; /* state update lock */
ieee80211_tx_lock_t ic_txlock; /* ic/vap TX lock */
TAILQ_HEAD(, ieee80211vap) ic_vaps; /* list of vap instances */
@@ -133,6 +135,9 @@ struct ieee80211com {
struct task ic_bmiss_task; /* deferred beacon miss hndlr */
struct task ic_chw_task; /* deferred HT CHW update */
+ counter_u64_t ic_ierrors; /* input errors */
+ counter_u64_t ic_oerrors; /* output errors */
+
uint32_t ic_flags; /* state flags */
uint32_t ic_flags_ext; /* extended state flags */
uint32_t ic_flags_ht; /* HT state flags */
@@ -192,6 +197,7 @@ struct ieee80211com {
struct ieee80211_dfs_state ic_dfs; /* DFS state */
struct ieee80211_scan_state *ic_scan; /* scan state */
+ struct ieee80211_scan_methods *ic_scan_methods; /* scan methods */
int ic_lastdata; /* time of last data frame */
int ic_lastscan; /* time last scan completed */
@@ -256,11 +262,11 @@ struct ieee80211com {
struct mbuf *,
const struct ieee80211_bpf_params *);
/* update device state for 802.11 slot time change */
- void (*ic_updateslot)(struct ifnet *);
+ void (*ic_updateslot)(struct ieee80211com *);
/* handle multicast state changes */
- void (*ic_update_mcast)(struct ifnet *);
+ void (*ic_update_mcast)(struct ieee80211com *);
/* handle promiscuous mode changes */
- void (*ic_update_promisc)(struct ifnet *);
+ void (*ic_update_promisc)(struct ieee80211com *);
/* new station association callback/notification */
void (*ic_newassoc)(struct ieee80211_node *, int);
/* TDMA update notification */
@@ -466,9 +472,13 @@ struct ieee80211vap {
void (*iv_opdetach)(struct ieee80211vap *);
/* receive processing */
int (*iv_input)(struct ieee80211_node *,
- struct mbuf *, int, int);
+ struct mbuf *,
+ const struct ieee80211_rx_stats *,
+ int, int);
void (*iv_recv_mgmt)(struct ieee80211_node *,
- struct mbuf *, int, int, int);
+ struct mbuf *, int,
+ const struct ieee80211_rx_stats *,
+ int, int);
void (*iv_recv_ctl)(struct ieee80211_node *,
struct mbuf *, int);
void (*iv_deliver_data)(struct ieee80211vap *,
@@ -496,13 +506,8 @@ struct ieee80211vap {
int (*iv_newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
/* 802.3 output method for raw frame xmit */
-#if __FreeBSD_version >= 1000031
int (*iv_output)(struct ifnet *, struct mbuf *,
const struct sockaddr *, struct route *);
-#else
- int (*iv_output)(struct ifnet *, struct mbuf *,
- struct sockaddr *, struct route *);
-#endif
uint64_t iv_spare[6];
};
MALLOC_DECLARE(M_80211_VAP);
@@ -675,6 +680,7 @@ MALLOC_DECLARE(M_80211_VAP);
"\20\1LDPC\2CHWIDTH40\5GREENFIELD\6SHORTGI20\7SHORTGI40\10TXSTBC" \
"\21AMPDU\22AMSDU\23HT\24SMPS\25RIFS"
+int ic_printf(struct ieee80211com *, const char *, ...) __printflike(2, 3);
void ieee80211_ifattach(struct ieee80211com *,
const uint8_t macaddr[IEEE80211_ADDR_LEN]);
void ieee80211_ifdetach(struct ieee80211com *);
@@ -707,6 +713,8 @@ struct ieee80211_channel *ieee80211_find_channel(struct ieee80211com *,
int freq, int flags);
struct ieee80211_channel *ieee80211_find_channel_byieee(struct ieee80211com *,
int ieee, int flags);
+struct ieee80211_channel *ieee80211_lookup_channel_rxstatus(struct ieee80211vap *,
+ const struct ieee80211_rx_stats *);
int ieee80211_setmode(struct ieee80211com *, enum ieee80211_phymode);
enum ieee80211_phymode ieee80211_chan2mode(const struct ieee80211_channel *);
uint32_t ieee80211_mac_hash(const struct ieee80211com *,
diff --git a/sys/net80211/ieee80211_wds.c b/sys/net80211/ieee80211_wds.c
index fc7725948b84..1d3f30a7a48e 100644
--- a/sys/net80211/ieee80211_wds.c
+++ b/sys/net80211/ieee80211_wds.c
@@ -64,9 +64,10 @@ __FBSDID("$FreeBSD$");
static void wds_vattach(struct ieee80211vap *);
static int wds_newstate(struct ieee80211vap *, enum ieee80211_state, int);
-static int wds_input(struct ieee80211_node *ni, struct mbuf *m, int, int);
-static void wds_recv_mgmt(struct ieee80211_node *, struct mbuf *,
- int subtype, int, int);
+static int wds_input(struct ieee80211_node *ni, struct mbuf *m,
+ const struct ieee80211_rx_stats *rxs, int, int);
+static void wds_recv_mgmt(struct ieee80211_node *, struct mbuf *, int subtype,
+ const struct ieee80211_rx_stats *, int, int);
void
ieee80211_wds_attach(struct ieee80211com *ic)
@@ -408,7 +409,8 @@ wds_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
* by the 802.11 layer.
*/
static int
-wds_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
+wds_input(struct ieee80211_node *ni, struct mbuf *m,
+ const struct ieee80211_rx_stats *rxs, int rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
@@ -718,7 +720,7 @@ wds_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
vap->iv_stats.is_rx_mgtdiscard++; /* XXX */
goto out;
}
- vap->iv_recv_mgmt(ni, m, subtype, rssi, nf);
+ vap->iv_recv_mgmt(ni, m, subtype, rxs, rssi, nf);
goto out;
case IEEE80211_FC0_TYPE_CTL:
@@ -744,8 +746,8 @@ out:
}
static void
-wds_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
- int subtype, int rssi, int nf)
+wds_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype,
+ const struct ieee80211_rx_stats *rxs, int rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;