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

Reply via email to