Date: Fri, 1 Mar 2013 04:51:44 +0000 (UTC) From: Adrian Chadd <adrian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r247529 - user/adrian/net80211_tx/sys/net80211 Message-ID: <201303010451.r214piLe093816@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: adrian Date: Fri Mar 1 04:51:44 2013 New Revision: 247529 URL: http://svnweb.freebsd.org/changeset/base/247529 Log: Defer the main frame TX through a per-vap task. The task runs in the ieee80211com task, so vaps are still serialised with each other as well as the rest of the ic state. This doesn't serialise the raw xmit path or any of the raw xmit state setup. It also doesn't touch the other paths (fast frames deferred handling/flush; ageq and power save handling; mesh TX handling.) These will come next. Tested: * AR5416, STA mode * AR9280, STA mode Modified: user/adrian/net80211_tx/sys/net80211/ieee80211.c user/adrian/net80211_tx/sys/net80211/ieee80211_freebsd.c user/adrian/net80211_tx/sys/net80211/ieee80211_output.c user/adrian/net80211_tx/sys/net80211/ieee80211_proto.c user/adrian/net80211_tx/sys/net80211/ieee80211_proto.h user/adrian/net80211_tx/sys/net80211/ieee80211_var.h Modified: user/adrian/net80211_tx/sys/net80211/ieee80211.c ============================================================================== --- user/adrian/net80211_tx/sys/net80211/ieee80211.c Fri Mar 1 04:21:22 2013 (r247528) +++ user/adrian/net80211_tx/sys/net80211/ieee80211.c Fri Mar 1 04:51:44 2013 (r247529) @@ -427,7 +427,8 @@ ieee80211_vap_setup(struct ieee80211com 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 */ @@ -622,6 +623,7 @@ ieee80211_vap_detach(struct ieee80211vap */ ieee80211_draintask(ic, &vap->iv_nstate_task); ieee80211_draintask(ic, &vap->iv_swbmiss_task); + ieee80211_draintask(ic, &vap->iv_tx_task); /* XXX band-aid until ifnet handles this for us */ taskqueue_drain(taskqueue_swi, &ifp->if_linktask); Modified: user/adrian/net80211_tx/sys/net80211/ieee80211_freebsd.c ============================================================================== --- user/adrian/net80211_tx/sys/net80211/ieee80211_freebsd.c Fri Mar 1 04:21:22 2013 (r247528) +++ user/adrian/net80211_tx/sys/net80211/ieee80211_freebsd.c Fri Mar 1 04:51:44 2013 (r247529) @@ -761,7 +761,7 @@ 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 Modified: user/adrian/net80211_tx/sys/net80211/ieee80211_output.c ============================================================================== --- user/adrian/net80211_tx/sys/net80211/ieee80211_output.c Fri Mar 1 04:21:22 2013 (r247528) +++ user/adrian/net80211_tx/sys/net80211/ieee80211_output.c Fri Mar 1 04:51:44 2013 (r247529) @@ -133,16 +133,6 @@ ieee80211_start_pkt(struct ieee80211vap int error; /* - * 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); - /* * Cancel any background scan. */ if (ic->ic_flags & IEEE80211_F_SCAN) @@ -370,14 +360,81 @@ ieee80211_start_pkt(struct ieee80211vap } /* + * Entry point for transmission for all VAPs. + * + * This sanitises the mbuf flags and queues it into the transmit + * queue. + */ +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; + + /* NB: parent must be up and running */ + if (!IFNET_IS_UP_RUNNING(parent)) { + IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT, + "%s: ignore queue, parent %s not up+running\n", + __func__, parent->if_xname); + /* XXX stat */ + m_free(m); + return (EINVAL);/* XXX errno? */ + } + + IF_LOCK(&ifp->if_snd); + + /* Enforce queue limits */ + if (_IF_QFULL(&ifp->if_snd)) { + IF_UNLOCK(&ifp->if_snd); + m_free(m); + return (ENOBUFS); /* XXX errno? */ + } + + /* + * 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. + * + * XXX TODO: for VAP frames coming in from the stack + * itself, we should just inject them directly into + * the vap rather than via ieee80211_vap_transmit(). + * Yes, they still need to go into the ifnet queue + * and be dequeued, but we can skip this particular + * check as they're already "in" the net80211 layer. + */ + m->m_flags &= ~(M_80211_TX - M_PWR_SAV - M_MORE_DATA); + _IF_ENQUEUE(&ifp->if_snd, m); + IF_UNLOCK(&ifp->if_snd); + + /* Schedule the deferred TX task */ + ieee80211_runtask(ic, &vap->iv_tx_task); + + return (0); +} + +void +ieee80211_vap_qflush(struct ifnet *ifp) +{ + + /* XXX TODO */ +} + + +/* * Start method for vap's. All packets from the stack come * through here. We handle common processing of the packets * before dispatching them to the underlying device. */ void -ieee80211_start(struct ifnet *ifp) +ieee80211_vap_tx_task(void *arg, int npending) { - struct ieee80211vap *vap = ifp->if_softc; + struct ieee80211vap *vap = (struct ieee80211vap *) arg; + struct ifnet *ifp = vap->iv_ifp; struct ieee80211com *ic = vap->iv_ic; struct ifnet *parent = ic->ic_ifp; struct mbuf *m; Modified: user/adrian/net80211_tx/sys/net80211/ieee80211_proto.c ============================================================================== --- user/adrian/net80211_tx/sys/net80211/ieee80211_proto.c Fri Mar 1 04:21:22 2013 (r247528) +++ user/adrian/net80211_tx/sys/net80211/ieee80211_proto.c Fri Mar 1 04:51:44 2013 (r247529) @@ -199,6 +199,7 @@ ieee80211_proto_vattach(struct ieee80211 callout_init(&vap->iv_mgtsend, CALLOUT_MPSAFE); TASK_INIT(&vap->iv_nstate_task, 0, ieee80211_newstate_cb, vap); TASK_INIT(&vap->iv_swbmiss_task, 0, beacon_swmiss, vap); + TASK_INIT(&vap->iv_tx_task, 0, ieee80211_vap_tx_task, vap); /* * Install default tx rate handling: no fixed rate, lowest * supported rate for mgmt and multicast frames. Default @@ -1792,7 +1793,7 @@ ieee80211_newstate_cb(void *xvap, int np * XXX Kick-start a VAP queue - this should be a method, * not if_start()! */ - if_start(vap->iv_ifp); + ieee80211_runtask(ic, &vap->iv_tx_task); /* bring up any vaps waiting on us */ wakeupwaiting(vap); Modified: user/adrian/net80211_tx/sys/net80211/ieee80211_proto.h ============================================================================== --- user/adrian/net80211_tx/sys/net80211/ieee80211_proto.h Fri Mar 1 04:21:22 2013 (r247528) +++ user/adrian/net80211_tx/sys/net80211/ieee80211_proto.h Fri Mar 1 04:51:44 2013 (r247529) @@ -103,7 +103,9 @@ int ieee80211_raw_output(struct ieee8021 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 *); +int ieee80211_vap_transmit(struct ifnet *ifp, struct mbuf *m); +void ieee80211_vap_qflush(struct ifnet *ifp); +void ieee80211_vap_tx_task(void *, int); int ieee80211_send_nulldata(struct ieee80211_node *); int ieee80211_classify(struct ieee80211_node *, struct mbuf *m); struct mbuf *ieee80211_mbuf_adjust(struct ieee80211vap *, int, Modified: user/adrian/net80211_tx/sys/net80211/ieee80211_var.h ============================================================================== --- user/adrian/net80211_tx/sys/net80211/ieee80211_var.h Fri Mar 1 04:21:22 2013 (r247528) +++ user/adrian/net80211_tx/sys/net80211/ieee80211_var.h Fri Mar 1 04:51:44 2013 (r247529) @@ -362,6 +362,7 @@ struct ieee80211vap { int iv_nstate_arg; /* pending state arg */ struct task iv_nstate_task; /* deferred state processing */ struct task iv_swbmiss_task;/* deferred iv_bmiss call */ + struct task iv_tx_task; /* VAP deferred TX task */ struct callout iv_mgtsend; /* mgmt frame response timer */ /* inactivity timer settings */ int iv_inact_init; /* setting for new station */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201303010451.r214piLe093816>