net80211: Fix traffic hang on STA/AP VAPs on a multi-VAP interface
This took an embarrasingly long time to find.
The state changes for a radio with a STA /and/ AP VAP gets a bit messy.
The AP maps are marked as waiting, waiting for the STA AP to find a
channel to use before the AP VAPs become active.
However, the code path that clears the OACTIVE flag on a VAP only runs
during a successful run of ieee80211_newstate_cb().
So here is how it goes:
- the STA VAP goes down and needs to scan;
- the AP vap goes RUN->INIT; but it doesn't YET call ieee80211_newstate_cb();
- meanwhile - a send on the AP VAP causes the VAP to set the OACTIVE flag here;
- then the STA VAP finishes scan and goes to RUN;
- which will call wakeupwaiting() as part of the STA VAP transition to RUN;
- .. then the AP VAP goes INIT->RUN directly via a call to hostap_newstate in wakeupwaiting rather than it being through the deferred path;
- /then/ the ieee80211_newstate_cb() is called, but it sees the state go RUN->RUN;
- .. which results in the OACTIVE flag never being cleared.
This clears the OACTIVE flag when a VAP transitions RUN->RUN; the
driver layer or net80211 layer can set it if required in a subsequent
transmit.
Differential Revision: https://reviews.freebsd.org/D34920
Reviewed by: bz