From aa68907edaaef774817c1bf625fa8ca0424f4e84 Mon Sep 17 00:00:00 2001 From: adrian Date: Thu, 8 Aug 2013 05:09:35 +0000 Subject: 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 --- sys/net80211/ieee80211.c | 7 ++--- sys/net80211/ieee80211_freebsd.c | 7 +++-- sys/net80211/ieee80211_freebsd.h | 4 +-- sys/net80211/ieee80211_hostap.c | 10 +++---- sys/net80211/ieee80211_hwmp.c | 2 +- sys/net80211/ieee80211_mesh.c | 2 +- sys/net80211/ieee80211_output.c | 61 +++++++++++++++++++--------------------- sys/net80211/ieee80211_power.c | 4 +-- sys/net80211/ieee80211_proto.c | 11 +++----- sys/net80211/ieee80211_proto.h | 3 +- sys/net80211/ieee80211_superg.c | 2 +- sys/net80211/ieee80211_wds.c | 2 +- 12 files changed, 54 insertions(+), 61 deletions(-) (limited to 'sys/net80211') 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++; -- cgit v1.1