I wrote:
> nbd asked me earlier today what sort of txpower I was seeing from ath9k on
> ar71xx/WNDR3700. Even with CONFIG_ATH_USER_REGD set, I see 20dBm on both
> radios. This is at trunk r23883 (current).
>
> The intersection stuff is still clamping everything to 20dBm.
I figured out why I’m seeing intersection even with ATH_USER_REGD #defined. The
problem is that I’ve got two cards, and during system boot, both of them are
coming online at just about the same time. There winds up being a race in the
regulatory code, because cfg80211 is tracking the state of the last request
made to CRDA, but also assuming that it will be synchronized with data set by
CRDA. There is no guarantee that CRDA will actually do anything in any specific
amount of time, or at all.
Here are the different passes through reg_process_hint:
1. There is no last_request and a pending_request comes in from regulatory_init
(via regulatory_hint_core) during cfg80211 initialization with initiator
NL80211_REGDOM_SET_BY_CORE and alpha2 "00". There is no previous last_request,
so ignore_request returns 0. call_crda calls CRDA, and CRDA provides regulatory
data. This sets the regulatory domain to "world."
2. The first card comes online, and a pending_request comes in with initiator
NL80211_REGDOM_SET_BY_DRIVER and alpha2 "US". The last request’s initiator was
NL80211_REGDOM_SET_BY_CORE, and regdom_changes is true (switching from "00" to
"US"), so ignore_request returns 0. call_crda calls CRDA, but CRDA doesn’t
provide regulatory data yet, because
3. The second card comes online just after the first, and another identical
pending_request comes in. This time, the last request’s initiator was
NL80211_REGDOM_SET_BY_DRIVER (from the first card, step 2 above), and
regdom_changes appears true (because CRDA hasn’t provided any data from step 2
yet and the regulatory domain is still "00"), so ignore_request returns
REG_INTERSECT. reg_process_hint sets last_request->intersect to true, and then
calls call_crda to call CRDA.
When CRDA finally provides data in response to the NL80211_REGDOM_SET_BY_DRIVER
request from either card, it comes into set_regdom, which calls __set_regdom,
which consults last_request->intersect. Since there is only one last_request,
it will indicate that intersection should be performed.
The race is between CRDA providing updated regulatory data in response to the
first card's request, and the second card making its own request.
I see this behavior even with ATH_USER_REGD #defined, and regardless of whether
I try to manually configure countries in /etc/config/wireless. The ath9k driver
calls regulatory_hint from ath9k_init_device, after getting regulatory data
from ath_regd_init, which sets CTRY_UNITED_STATES as a default, and in the
cases I’m seeing. Since both of my cards are initialized at about the same time
during boot-up, before CRDA can service either request, I see a race that
results in intersection.
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel