Date: Sat, 27 Oct 2012 16:18:11 -0700 From: Adrian Chadd <adrian@freebsd.org> To: freebsd-wireless@freebsd.org Cc: FreeBSD Net <freebsd-net@freebsd.org>, freebsd-arch@freebsd.org Subject: request for help: 'fixing' the 802.11 TX path Message-ID: <CAJ-VmokuUnMOBa6_uD_1=J9DJR38-2L0ETB_7j3Dnx63yCOvnQ@mail.gmail.com>
next in thread | raw e-mail | index | archive | help
Hi all, I'd like to try and sort out the last remaining niggles in the 802.11 code - this email is focusing on the TX path. The TX path has a few problems: * there's a normal versus raw TX path (for raw frames, management frames, etc) - the raw path doesn't necessarily queue frames into the raw TX queue, so it's a kind of "side path" to the driver. This causes frame ordering problems with things like sequence number allocation. * there's limited locking in the TX path, primarily because you can't _really_ fine grain lock the TX path. Since you have multiple TX thread contexts all sending into the same driver queue and that queue has to share incrementing sequence number, aggregate status and CCMP encryption replay counters, you _have_ to either use some long-held mutexes to enforce this _or_ throw all sending into a TX thread and run that. * raw TX requires some extra state to be glued (the bpf_params info); I'd like to glue that into mbufs as an option, so the driver can use those instead of interpreting their own 802.11 header contents. And the one I'd like to discuss here: * Fragment transmission is totally broken and causes mbufs to be just leaked. The problem with sending fragments (at least for the ath drivr) is the packet duration calcluation requires the _next_ fragment to be available. Now, this is a design hold-over from the previous, pre-vap scheme. The driver netif would be handed a raw mbuf frame, which it would then pass through the net80211 encapsulation code and that would potentially generate 802.11 fragments. The rest of the driver TX path would then see that it was handed a fragment list and TX those. Fragments were chained together using m_nextpkt, like a normal mbuf list. This doesn't happen any longer. The net80211 vap gets the raw frame, which then sends that to the driver netif after doing the vap and 802.11 state / encapsulation work. But since all the wifi drivers use if_start() right now, m_nextpkt gets blanked on both encap and decap.. and thus things leak. Now I can't really see a way around this, without doing dirty hacks with mbuf attributes to link the fragments together. The only clean way I can see is to force all wifi drivers to use if_transmit(), and then have if_transmit() interpret a chain of frames as "the fragment list." I'm tempted to just create a new TX ic method which does what if_transmit does(), and ignore the if_start/if_transmit stuff altogether. That way any changes to if_transmit() in the future (where people may decide to have if_transmit() take a _list_ of frames to transmit) doesn't screw me. Right now if_transmit() API just sends a single frame to the driver in question, so I also don't want to abuse the semantics there to include "oh, and also fragments." I'd like to get this in soon as I'm going to have to change a bunch of wireless code in all the drivers as well as the wifi stack and this is likely going to have some fallout. I'd like to do his before 10.0 branches. I'm open to suggestions/comments. :-) Thanks! Adrian
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAJ-VmokuUnMOBa6_uD_1=J9DJR38-2L0ETB_7j3Dnx63yCOvnQ>