summaryrefslogtreecommitdiffstats
path: root/sys/net80211
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2013-08-08 05:09:35 +0000
committeradrian <adrian@FreeBSD.org>2013-08-08 05:09:35 +0000
commitaa68907edaaef774817c1bf625fa8ca0424f4e84 (patch)
tree4291a4d39d439572a02fc5815d3ee2df5166c80a /sys/net80211
parent541895143dbcbc415fa4b23bf8f4db2d9996ba12 (diff)
downloadFreeBSD-src-aa68907edaaef774817c1bf625fa8ca0424f4e84.zip
FreeBSD-src-aa68907edaaef774817c1bf625fa8ca0424f4e84.tar.gz
Convert net80211 over to using if_transmit for the dispatch from the
upper layer(s). This eliminates the if_snd queue from net80211. Yay! This unfortunately has a few side effects: * It breaks ALTQ to net80211 for now - sorry everyone, but fixing parallelism and eliminating the if_snd queue is more important than supporting this broken traffic scheduling model. :-) * There's no VAP and IC flush methods just yet - I think I'll add some NULL methods for now just as placeholders. * It reduces throughput a little because now net80211 will drop packets rather than buffer them if the driver doesn't do its own buffering. This will be addressed in the future as I implement per-node software queues. Tested: * ath(4) and iwn(4) in STA operation
Diffstat (limited to 'sys/net80211')
-rw-r--r--sys/net80211/ieee80211.c7
-rw-r--r--sys/net80211/ieee80211_freebsd.c7
-rw-r--r--sys/net80211/ieee80211_freebsd.h4
-rw-r--r--sys/net80211/ieee80211_hostap.c10
-rw-r--r--sys/net80211/ieee80211_hwmp.c2
-rw-r--r--sys/net80211/ieee80211_mesh.c2
-rw-r--r--sys/net80211/ieee80211_output.c61
-rw-r--r--sys/net80211/ieee80211_power.c4
-rw-r--r--sys/net80211/ieee80211_proto.c11
-rw-r--r--sys/net80211/ieee80211_proto.h3
-rw-r--r--sys/net80211/ieee80211_superg.c2
-rw-r--r--sys/net80211/ieee80211_wds.c2
12 files changed, 54 insertions, 61 deletions
diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c
index a7546c9..aaadb92 100644
--- a/sys/net80211/ieee80211.c
+++ b/sys/net80211/ieee80211.c
@@ -433,13 +433,10 @@ ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap,
if_initname(ifp, name, unit);
ifp->if_softc = vap; /* back pointer */
ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
- ifp->if_start = ieee80211_start;
+ ifp->if_transmit = ieee80211_vap_transmit;
+ ifp->if_qflush = ieee80211_vap_qflush;
ifp->if_ioctl = ieee80211_ioctl;
ifp->if_init = ieee80211_init;
- /* NB: input+output filled in by ether_ifattach */
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
- IFQ_SET_READY(&ifp->if_snd);
vap->iv_ifp = ifp;
vap->iv_ic = ic;
diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c
index 4415b62..b616c44 100644
--- a/sys/net80211/ieee80211_freebsd.c
+++ b/sys/net80211/ieee80211_freebsd.c
@@ -511,7 +511,7 @@ ieee80211_process_callback(struct ieee80211_node *ni,
* (the callers will first need modifying.)
*/
int
-ieee80211_parent_transmit(struct ieee80211com *ic,
+ieee80211_parent_xmitpkt(struct ieee80211com *ic,
struct mbuf *m)
{
struct ifnet *parent = ic->ic_ifp;
@@ -528,7 +528,7 @@ ieee80211_parent_transmit(struct ieee80211com *ic,
* Transmit a frame to the VAP interface.
*/
int
-ieee80211_vap_transmit(struct ieee80211vap *vap, struct mbuf *m)
+ieee80211_vap_xmitpkt(struct ieee80211vap *vap, struct mbuf *m)
{
struct ifnet *ifp = vap->iv_ifp;
@@ -809,7 +809,8 @@ static void
bpf_track(void *arg, struct ifnet *ifp, int dlt, int attach)
{
/* NB: identify vap's by if_start */
- if (dlt == DLT_IEEE802_11_RADIO && ifp->if_start == ieee80211_start) {
+ if (dlt == DLT_IEEE802_11_RADIO &&
+ ifp->if_transmit == ieee80211_vap_transmit) {
struct ieee80211vap *vap = ifp->if_softc;
/*
* Track bpf radiotap listener state. We mark the vap
diff --git a/sys/net80211/ieee80211_freebsd.h b/sys/net80211/ieee80211_freebsd.h
index 3ea117b..ec3cbca 100644
--- a/sys/net80211/ieee80211_freebsd.h
+++ b/sys/net80211/ieee80211_freebsd.h
@@ -297,8 +297,8 @@ int ieee80211_add_callback(struct mbuf *m,
void ieee80211_process_callback(struct ieee80211_node *, struct mbuf *, int);
struct ieee80211com;
-int ieee80211_parent_transmit(struct ieee80211com *, struct mbuf *);
-int ieee80211_vap_transmit(struct ieee80211vap *, struct mbuf *);
+int ieee80211_parent_xmitpkt(struct ieee80211com *, struct mbuf *);
+int ieee80211_vap_xmitpkt(struct ieee80211vap *, struct mbuf *);
void get_random_bytes(void *, size_t);
diff --git a/sys/net80211/ieee80211_hostap.c b/sys/net80211/ieee80211_hostap.c
index fe83ebb..ee17527 100644
--- a/sys/net80211/ieee80211_hostap.c
+++ b/sys/net80211/ieee80211_hostap.c
@@ -412,7 +412,7 @@ hostap_deliver_data(struct ieee80211vap *vap,
if (mcopy != NULL) {
int len, err;
len = mcopy->m_pkthdr.len;
- err = ieee80211_vap_transmit(vap, mcopy);
+ err = ieee80211_vap_xmitpkt(vap, mcopy);
if (err) {
/* NB: IFQ_HANDOFF reclaims mcopy */
} else {
@@ -2322,13 +2322,13 @@ ieee80211_recv_pspoll(struct ieee80211_node *ni, struct mbuf *m0)
/*
* Do the right thing; if it's an encap'ed frame then
- * call ieee80211_parent_transmit() (and free the ref) else
- * call ieee80211_vap_transmit().
+ * call ieee80211_parent_xmitpkt() (and free the ref) else
+ * call ieee80211_vap_xmitpkt().
*/
if (m->m_flags & M_ENCAP) {
- if (ieee80211_parent_transmit(ic, m) != 0)
+ if (ieee80211_parent_xmitpkt(ic, m) != 0)
ieee80211_free_node(ni);
} else {
- (void) ieee80211_vap_transmit(vap, m);
+ (void) ieee80211_vap_xmitpkt(vap, m);
}
}
diff --git a/sys/net80211/ieee80211_hwmp.c b/sys/net80211/ieee80211_hwmp.c
index 8c481da..751f1e7 100644
--- a/sys/net80211/ieee80211_hwmp.c
+++ b/sys/net80211/ieee80211_hwmp.c
@@ -1467,7 +1467,7 @@ hwmp_recv_prep(struct ieee80211vap *vap, struct ieee80211_node *ni,
* If the mbuf has M_ENCAP set, ensure we free it.
* Note that after if_transmit() is called, m is invalid.
*/
- (void) ieee80211_vap_transmit(vap, m);
+ (void) ieee80211_vap_xmitpkt(vap, m);
}
#undef IS_PROXY
#undef PROXIED_BY_US
diff --git a/sys/net80211/ieee80211_mesh.c b/sys/net80211/ieee80211_mesh.c
index 417747b..1d03c1a 100644
--- a/sys/net80211/ieee80211_mesh.c
+++ b/sys/net80211/ieee80211_mesh.c
@@ -1243,7 +1243,7 @@ mesh_forward(struct ieee80211vap *vap, struct mbuf *m,
* to do here; we'll have to re-think this soon.
*/
IEEE80211_TX_LOCK(ic);
- err = ieee80211_parent_transmit(ic, mcopy);
+ err = ieee80211_parent_xmitpkt(ic, mcopy);
IEEE80211_TX_UNLOCK(ic);
if (err != 0) {
/* NB: IFQ_HANDOFF reclaims mbuf */
diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c
index 0b86ecc..7a88018 100644
--- a/sys/net80211/ieee80211_output.c
+++ b/sys/net80211/ieee80211_output.c
@@ -236,7 +236,7 @@ ieee80211_vap_pkt_send_dest(struct ieee80211vap *vap, struct mbuf *m,
return (ENOBUFS);
}
}
- error = ieee80211_parent_transmit(ic, m);
+ error = ieee80211_parent_xmitpkt(ic, m);
/*
* Unlock at this point - no need to hold it across
@@ -397,13 +397,12 @@ ieee80211_start_pkt(struct ieee80211vap *vap, struct mbuf *m)
* through here. We handle common processing of the packets
* before dispatching them to the underlying device.
*/
-void
-ieee80211_start(struct ifnet *ifp)
+int
+ieee80211_vap_transmit(struct ifnet *ifp, struct mbuf *m)
{
struct ieee80211vap *vap = ifp->if_softc;
struct ieee80211com *ic = vap->iv_ic;
struct ifnet *parent = ic->ic_ifp;
- struct mbuf *m;
/* NB: parent must be up and running */
if (!IFNET_IS_UP_RUNNING(parent)) {
@@ -411,14 +410,14 @@ ieee80211_start(struct ifnet *ifp)
"%s: ignore queue, parent %s not up+running\n",
__func__, parent->if_xname);
/* XXX stat */
- return;
+ return (EINVAL);
}
if (vap->iv_state == IEEE80211_S_SLEEP) {
/*
* In power save, wakeup device for transmit.
*/
ieee80211_new_state(vap, IEEE80211_S_RUN, 0);
- return;
+ return (0);
}
/*
* No data frames go out unless we're running.
@@ -435,34 +434,35 @@ ieee80211_start(struct ifnet *ifp)
__func__, ieee80211_state_name[vap->iv_state]);
vap->iv_stats.is_tx_badstate++;
IEEE80211_UNLOCK(ic);
- IFQ_LOCK(&ifp->if_snd);
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- IFQ_UNLOCK(&ifp->if_snd);
- return;
+ return (EINVAL);
}
IEEE80211_UNLOCK(ic);
}
- for (;;) {
- IFQ_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
- /*
- * Sanitize mbuf flags for net80211 use. We cannot
- * clear M_PWR_SAV or M_MORE_DATA because these may
- * be set for frames that are re-submitted from the
- * power save queue.
- *
- * NB: This must be done before ieee80211_classify as
- * it marks EAPOL in frames with M_EAPOL.
- */
- m->m_flags &= ~(M_80211_TX - M_PWR_SAV - M_MORE_DATA);
- /*
- * Bump to the packet transmission path.
- */
- (void) ieee80211_start_pkt(vap, m);
- /* mbuf is consumed here */
- }
+ /*
+ * Sanitize mbuf flags for net80211 use. We cannot
+ * clear M_PWR_SAV or M_MORE_DATA because these may
+ * be set for frames that are re-submitted from the
+ * power save queue.
+ *
+ * NB: This must be done before ieee80211_classify as
+ * it marks EAPOL in frames with M_EAPOL.
+ */
+ m->m_flags &= ~(M_80211_TX - M_PWR_SAV - M_MORE_DATA);
+
+ /*
+ * Bump to the packet transmission path.
+ * The mbuf will be consumed here.
+ */
+ return (ieee80211_start_pkt(vap, m));
+}
+
+void
+ieee80211_vap_qflush(struct ifnet *ifp)
+{
+
+ /* Empty for now */
}
/*
@@ -500,9 +500,7 @@ ieee80211_output(struct ifnet *ifp, struct mbuf *m,
int error;
int ret;
- IFQ_LOCK(&ifp->if_snd);
if (ifp->if_drv_flags & IFF_DRV_OACTIVE) {
- IFQ_UNLOCK(&ifp->if_snd);
/*
* Short-circuit requests if the vap is marked OACTIVE
* as this can happen because a packet came down through
@@ -513,7 +511,6 @@ ieee80211_output(struct ifnet *ifp, struct mbuf *m,
*/
senderr(ENETDOWN);
}
- IFQ_UNLOCK(&ifp->if_snd);
vap = ifp->if_softc;
ic = vap->iv_ic;
/*
diff --git a/sys/net80211/ieee80211_power.c b/sys/net80211/ieee80211_power.c
index 995aa88..d14d8f4 100644
--- a/sys/net80211/ieee80211_power.c
+++ b/sys/net80211/ieee80211_power.c
@@ -464,7 +464,7 @@ pwrsave_flushq(struct ieee80211_node *ni)
* For encaped frames, we need to free the node
* reference upon failure.
*/
- if (ieee80211_parent_transmit(ic, m) != 0)
+ if (ieee80211_parent_xmitpkt(ic, m) != 0)
ieee80211_free_node(ni);
}
}
@@ -476,7 +476,7 @@ pwrsave_flushq(struct ieee80211_node *ni)
ifp_q = m->m_nextpkt;
KASSERT((!(m->m_flags & M_ENCAP)),
("%s: vapq with M_ENCAP frame!\n", __func__));
- (void) ieee80211_vap_transmit(vap, m);
+ (void) ieee80211_vap_xmitpkt(vap, m);
}
}
}
diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c
index 3a2b5c7..61aef7a 100644
--- a/sys/net80211/ieee80211_proto.c
+++ b/sys/net80211/ieee80211_proto.c
@@ -1784,15 +1784,11 @@ ieee80211_newstate_cb(void *xvap, int npending)
* Note this can also happen as a result of SLEEP->RUN
* (i.e. coming out of power save mode).
*/
- IF_LOCK(&vap->iv_ifp->if_snd);
vap->iv_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- IF_UNLOCK(&vap->iv_ifp->if_snd);
/*
- * XXX Kick-start a VAP queue - this should be a method,
- * not if_start()!
+ * XXX TODO Kick-start a VAP queue - this should be a method!
*/
- if_start(vap->iv_ifp);
/* bring up any vaps waiting on us */
wakeupwaiting(vap);
@@ -1805,8 +1801,9 @@ ieee80211_newstate_cb(void *xvap, int npending)
*/
ieee80211_scan_flush(vap);
- /* XXX NB: cast for altq */
- ieee80211_flush_ifq((struct ifqueue *)&ic->ic_ifp->if_snd, vap);
+ /*
+ * XXX TODO: ic/vap queue flush
+ */
}
done:
IEEE80211_UNLOCK(ic);
diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h
index 4d993b6..ae21087 100644
--- a/sys/net80211/ieee80211_proto.h
+++ b/sys/net80211/ieee80211_proto.h
@@ -110,7 +110,8 @@ int ieee80211_raw_output(struct ieee80211vap *, struct ieee80211_node *,
void ieee80211_send_setup(struct ieee80211_node *, struct mbuf *, int, int,
const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN],
const uint8_t [IEEE80211_ADDR_LEN]);
-void ieee80211_start(struct ifnet *ifp);
+int ieee80211_vap_transmit(struct ifnet *ifp, struct mbuf *m);
+void ieee80211_vap_qflush(struct ifnet *ifp);
int ieee80211_send_nulldata(struct ieee80211_node *);
int ieee80211_classify(struct ieee80211_node *, struct mbuf *m);
struct mbuf *ieee80211_mbuf_adjust(struct ieee80211vap *, int,
diff --git a/sys/net80211/ieee80211_superg.c b/sys/net80211/ieee80211_superg.c
index d8083c2..5c72393 100644
--- a/sys/net80211/ieee80211_superg.c
+++ b/sys/net80211/ieee80211_superg.c
@@ -511,7 +511,7 @@ ff_transmit(struct ieee80211_node *ni, struct mbuf *m)
if (m != NULL) {
struct ifnet *ifp = vap->iv_ifp;
- error = ieee80211_parent_transmit(ic, m);;
+ error = ieee80211_parent_xmitpkt(ic, m);;
if (error != 0) {
/* NB: IFQ_HANDOFF reclaims mbuf */
ieee80211_free_node(ni);
diff --git a/sys/net80211/ieee80211_wds.c b/sys/net80211/ieee80211_wds.c
index ad88a05..8e0cb06 100644
--- a/sys/net80211/ieee80211_wds.c
+++ b/sys/net80211/ieee80211_wds.c
@@ -295,7 +295,7 @@ ieee80211_dwds_mcast(struct ieee80211vap *vap0, struct mbuf *m)
mcopy->m_flags |= M_MCAST;
mcopy->m_pkthdr.rcvif = (void *) ni;
- err = ieee80211_parent_transmit(ic, mcopy);
+ err = ieee80211_parent_xmitpkt(ic, mcopy);
if (err) {
/* NB: IFQ_HANDOFF reclaims mbuf */
ifp->if_oerrors++;
OpenPOWER on IntegriCloud