2011-12-07 13:53:33

by Rajkumar Manoharan

[permalink] [raw]
Subject: [PATCH 1/4] ath: add a helper for processing reg data on init

From: "Luis R. Rodriguez" <[email protected]>

This has no functional change. The helper can be used later
for other things like country IE changes and following the CTL
for different countries.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath/regd.c | 22 +++++++++++++++++-----
1 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c
index 65ecb5b..ed4966f 100644
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -508,11 +508,7 @@ static void ath_regd_sanitize(struct ath_regulatory *reg)
reg->current_rd = 0x64;
}

-int
-ath_regd_init(struct ath_regulatory *reg,
- struct wiphy *wiphy,
- int (*reg_notifier)(struct wiphy *wiphy,
- struct regulatory_request *request))
+static int __ath_regd_init(struct ath_regulatory *reg)
{
struct country_code_to_enum_rd *country = NULL;
u16 regdmn;
@@ -583,7 +579,23 @@ ath_regd_init(struct ath_regulatory *reg,
printk(KERN_DEBUG "ath: Regpair used: 0x%0x\n",
reg->regpair->regDmnEnum);

+ return 0;
+}
+
+int
+ath_regd_init(struct ath_regulatory *reg,
+ struct wiphy *wiphy,
+ int (*reg_notifier)(struct wiphy *wiphy,
+ struct regulatory_request *request))
+{
+ int r;
+
+ r = __ath_regd_init(reg);
+ if (r)
+ return r;
+
ath_regd_init_wiphy(reg, wiphy, reg_notifier);
+
return 0;
}
EXPORT_SYMBOL(ath_regd_init);
--
1.7.8



2011-12-08 08:16:42

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 3/4] ath9k: Restore EEPROM regulatory upon STA disconnect

On Wed, Dec 7, 2011 at 10:02 PM, Rajkumar Manoharan
<[email protected]> wrote:
> On Wed, Dec 07, 2011 at 01:37:49PM -0800, Luis R. Rodriguez wrote:
>> On Wed, Dec 7, 2011 at 5:53 AM, Rajkumar Manoharan
>> <[email protected]> wrote:
>> > The current regulatory for world roaming mode cards might be
>> > overriden by country IE from the assiciated AP. But these
>> > regulatory values are failed to be restored on disconnection.
>> > This patch ensures to resotre regulatry values at driver side.
>> >
>> > Signed-off-by: Rajkumar Manoharan <[email protected]>
>> > ---
>> >  drivers/net/wireless/ath/ath9k/main.c |    8 ++++++++
>> >  1 files changed, 8 insertions(+), 0 deletions(-)
>> >
>> > diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
>> > index 424289f..a4dbb7b 100644
>> > --- a/drivers/net/wireless/ath/ath9k/main.c
>> > +++ b/drivers/net/wireless/ath/ath9k/main.c
>> > @@ -2046,6 +2046,14 @@ static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif)
>> >                sc->sc_flags &= ~SC_OP_ANI_RUN;
>> >                del_timer_sync(&common->ani.timer);
>> >                memset(&sc->caldata, 0, sizeof(sc->caldata));
>> > +               /*
>> > +                * Restore regulatory values that might be updated
>> > +                * by country IEs.
>> > +                */
>> > +               if (!ath_is_world_regd(&common->regulatory) &&
>> > +                   ath_is_world_regd(&common->reg_world_copy))
>> > +                       memcpy(&common->regulatory, &common->reg_world_copy,
>> > +                              sizeof(struct ath_regulatory));
>> >        }
>>
>> NACK, this patch should not be required given that patch [2/4] in this
>> series restores this on the reg_notifier() for the
>> NL80211_REGDOM_SET_BY_CORE case -- the trick is that when cfg80211
>> detects not only a disconnect, but any regulatory restore, it will
>> *always* send a reg core hint! Again the hunk from patch [2/4] was:
>>
>> @@ -363,14 +381,37 @@ int ath_reg_notifier_apply(struct wiphy *wiphy,
>>                return 0;
>>
>>        switch (request->initiator) {
>> -       case NL80211_REGDOM_SET_BY_DRIVER:
>>        case NL80211_REGDOM_SET_BY_CORE:
>> +               /*
>> +                * If common->reg_world_copy is world roaming it means we *were*
>> +                * world roaming... so we now have to restore that data.
>> +                */
>> +               if (!ath_is_world_regd(&common->reg_world_copy))
>> +                       break;
>> +
>> +               memcpy(reg, &common->reg_world_copy,
>> +                      sizeof(struct ath_regulatory));
>> +               break;
>> +       case NL80211_REGDOM_SET_BY_DRIVER:
>>        case NL80211_REGDOM_SET_BY_USER:
>>                break;
>>
>> Can you please test without this patch and ensure you get the data
>> properly restored?
>>
> But the regulatory updates are ignored for CUSTOM_REGULATORY cards
> at wiphy_update_regulatory. Isn't it?
>
>        if (initiator == NL80211_REGDOM_SET_BY_CORE &&
>            wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) {
>                REG_DBG_PRINT("Ignoring regulatory request %s "
>                              "since the driver uses its own custom "
>                              "regulatory domain\n",
>                              reg_initiator_name(initiator));
>                return true;
>
> To ensure that the regulatory is restored always, I did it at bss_info_change.

Ah yes, good point. In that case, please instead modify
net/wireless/reg.c to call at least the reg_notifier() even if nothing
is done. That way not only ath9k but all the other ath drivers benefit
from this change.

Luis

2011-12-07 13:53:40

by Rajkumar Manoharan

[permalink] [raw]
Subject: [PATCH 2/4] ath: optimize processing of CTLs for country IEs for world roaming cards

From: "Luis R. Rodriguez" <[email protected]>

When we receive a country IE hint and we have a world roaming card
we can optimize output power further by ensuring that we use the
calibrated data for the country by using that country's own CTL data.
That is -- when world roaming and when we process a country IE we
no longer need to use the lowest output power of all CTLs instead
we use an optimized CTL output power for that specific country.

We accomplish this by copying the regulatory data prior on init
and restoring it when cfg80211 tells us it gets a core hint. Core
hints are only sent on init and when it wants to restore reguulatory
settings. We take advantage of this fact and apply the cached
regulatory data when we get a core hint. When we get a country IE
hint though we process the regulatory data as if programmed for
a specific country.

Tested-by: Rajkumar Manoharan <[email protected]>
Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath/ath.h | 1 +
drivers/net/wireless/ath/regd.c | 55 ++++++++++++++++++++++++++++++++++++---
2 files changed, 52 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index 4596c33..3e4dd2d 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -152,6 +152,7 @@ struct ath_common {
struct ath_cycle_counters cc_survey;

struct ath_regulatory regulatory;
+ struct ath_regulatory reg_world_copy;
const struct ath_ops *ops;
const struct ath_bus_ops *bus_ops;

diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c
index ed4966f..10dea37 100644
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -21,6 +21,8 @@
#include "regd.h"
#include "regd_common.h"

+static int __ath_regd_init(struct ath_regulatory *reg);
+
/*
* This is a set of common rules used by our world regulatory domains.
* We have 12 world regulatory domains. To save space we consolidate
@@ -347,10 +349,26 @@ static void ath_reg_apply_world_flags(struct wiphy *wiphy,
}
}

+static u16 ath_regd_find_country_by_name(char *alpha2)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
+ if (!memcmp(allCountries[i].isoName, alpha2, 2))
+ return allCountries[i].countryCode;
+ }
+
+ return -1;
+}
+
int ath_reg_notifier_apply(struct wiphy *wiphy,
struct regulatory_request *request,
struct ath_regulatory *reg)
{
+ struct ath_common *common = container_of(reg, struct ath_common,
+ regulatory);
+ u16 country_code;
+
/* We always apply this */
ath_reg_apply_radar_flags(wiphy);

@@ -363,14 +381,37 @@ int ath_reg_notifier_apply(struct wiphy *wiphy,
return 0;

switch (request->initiator) {
- case NL80211_REGDOM_SET_BY_DRIVER:
case NL80211_REGDOM_SET_BY_CORE:
+ /*
+ * If common->reg_world_copy is world roaming it means we *were*
+ * world roaming... so we now have to restore that data.
+ */
+ if (!ath_is_world_regd(&common->reg_world_copy))
+ break;
+
+ memcpy(reg, &common->reg_world_copy,
+ sizeof(struct ath_regulatory));
+ break;
+ case NL80211_REGDOM_SET_BY_DRIVER:
case NL80211_REGDOM_SET_BY_USER:
break;
case NL80211_REGDOM_SET_BY_COUNTRY_IE:
- if (ath_is_world_regd(reg))
- ath_reg_apply_world_flags(wiphy, request->initiator,
- reg);
+ if (!ath_is_world_regd(reg))
+ break;
+
+ country_code = ath_regd_find_country_by_name(request->alpha2);
+ if (country_code == (u16) -1)
+ break;
+
+ reg->current_rd = COUNTRY_ERD_FLAG;
+ reg->current_rd |= country_code;
+
+ printk(KERN_DEBUG "ath: regdomain 0x%0x updated by CountryIE\n",
+ reg->current_rd);
+ __ath_regd_init(reg);
+
+ ath_reg_apply_world_flags(wiphy, request->initiator, reg);
+
break;
}

@@ -588,12 +629,18 @@ ath_regd_init(struct ath_regulatory *reg,
int (*reg_notifier)(struct wiphy *wiphy,
struct regulatory_request *request))
{
+ struct ath_common *common = container_of(reg, struct ath_common,
+ regulatory);
int r;

r = __ath_regd_init(reg);
if (r)
return r;

+ if (ath_is_world_regd(reg))
+ memcpy(&common->reg_world_copy, reg,
+ sizeof(struct ath_regulatory));
+
ath_regd_init_wiphy(reg, wiphy, reg_notifier);

return 0;
--
1.7.8


2011-12-07 13:55:28

by Rajkumar Manoharan

[permalink] [raw]
Subject: [PATCH 3/4] ath9k: Restore EEPROM regulatory upon STA disconnect

The current regulatory for world roaming mode cards might be
overriden by country IE from the assiciated AP. But these
regulatory values are failed to be restored on disconnection.
This patch ensures to resotre regulatry values at driver side.

Signed-off-by: Rajkumar Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/main.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 424289f..a4dbb7b 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2046,6 +2046,14 @@ static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif)
sc->sc_flags &= ~SC_OP_ANI_RUN;
del_timer_sync(&common->ani.timer);
memset(&sc->caldata, 0, sizeof(sc->caldata));
+ /*
+ * Restore regulatory values that might be updated
+ * by country IEs.
+ */
+ if (!ath_is_world_regd(&common->regulatory) &&
+ ath_is_world_regd(&common->reg_world_copy))
+ memcpy(&common->regulatory, &common->reg_world_copy,
+ sizeof(struct ath_regulatory));
}
}

--
1.7.8


2011-12-07 21:39:33

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 4/4] ath9k: Reconfigure tx power on regulatory update

On Wed, Dec 7, 2011 at 5:53 AM, Rajkumar Manoharan
<[email protected]> wrote:
> Whenever the regulatory got updated by country IE for the world
> roaming cards, need to reconfigure the tx power immediately to
> increase the power level.
>
> Signed-off-by: Rajkumar Manoharan <[email protected]>

I ACK all except patch [3/4].

Acked-by: Luis R. Rodriguez <[email protected]>

Luis

2011-12-08 10:01:20

by Rajkumar Manoharan

[permalink] [raw]
Subject: Re: [PATCH 3/4] ath9k: Restore EEPROM regulatory upon STA disconnect

On Thu, Dec 08, 2011 at 12:16:21AM -0800, Luis R. Rodriguez wrote:
> On Wed, Dec 7, 2011 at 10:02 PM, Rajkumar Manoharan
> <[email protected]> wrote:
> > On Wed, Dec 07, 2011 at 01:37:49PM -0800, Luis R. Rodriguez wrote:
> >> On Wed, Dec 7, 2011 at 5:53 AM, Rajkumar Manoharan
> >> <[email protected]> wrote:
> >> > The current regulatory for world roaming mode cards might be
> >> > overriden by country IE from the assiciated AP. But these
> >> > regulatory values are failed to be restored on disconnection.
> >> > This patch ensures to resotre regulatry values at driver side.
> >> >
> >> > Signed-off-by: Rajkumar Manoharan <[email protected]>
> >> > ---
> >> > ?drivers/net/wireless/ath/ath9k/main.c | ? ?8 ++++++++
> >> > ?1 files changed, 8 insertions(+), 0 deletions(-)
> >> >
> >> > diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
> >> > index 424289f..a4dbb7b 100644
> >> > --- a/drivers/net/wireless/ath/ath9k/main.c
> >> > +++ b/drivers/net/wireless/ath/ath9k/main.c
> >> > @@ -2046,6 +2046,14 @@ static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif)
> >> > ? ? ? ? ? ? ? ?sc->sc_flags &= ~SC_OP_ANI_RUN;
> >> > ? ? ? ? ? ? ? ?del_timer_sync(&common->ani.timer);
> >> > ? ? ? ? ? ? ? ?memset(&sc->caldata, 0, sizeof(sc->caldata));
> >> > + ? ? ? ? ? ? ? /*
> >> > + ? ? ? ? ? ? ? ?* Restore regulatory values that might be updated
> >> > + ? ? ? ? ? ? ? ?* by country IEs.
> >> > + ? ? ? ? ? ? ? ?*/
> >> > + ? ? ? ? ? ? ? if (!ath_is_world_regd(&common->regulatory) &&
> >> > + ? ? ? ? ? ? ? ? ? ath_is_world_regd(&common->reg_world_copy))
> >> > + ? ? ? ? ? ? ? ? ? ? ? memcpy(&common->regulatory, &common->reg_world_copy,
> >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sizeof(struct ath_regulatory));
> >> > ? ? ? ?}
> >>
> >> NACK, this patch should not be required given that patch [2/4] in this
> >> series restores this on the reg_notifier() for the
> >> NL80211_REGDOM_SET_BY_CORE case -- the trick is that when cfg80211
> >> detects not only a disconnect, but any regulatory restore, it will
> >> *always* send a reg core hint! Again the hunk from patch [2/4] was:
> >>
> >> @@ -363,14 +381,37 @@ int ath_reg_notifier_apply(struct wiphy *wiphy,
> >> ? ? ? ? ? ? ? ?return 0;
> >>
> >> ? ? ? ?switch (request->initiator) {
> >> - ? ? ? case NL80211_REGDOM_SET_BY_DRIVER:
> >> ? ? ? ?case NL80211_REGDOM_SET_BY_CORE:
> >> + ? ? ? ? ? ? ? /*
> >> + ? ? ? ? ? ? ? ?* If common->reg_world_copy is world roaming it means we *were*
> >> + ? ? ? ? ? ? ? ?* world roaming... so we now have to restore that data.
> >> + ? ? ? ? ? ? ? ?*/
> >> + ? ? ? ? ? ? ? if (!ath_is_world_regd(&common->reg_world_copy))
> >> + ? ? ? ? ? ? ? ? ? ? ? break;
> >> +
> >> + ? ? ? ? ? ? ? memcpy(reg, &common->reg_world_copy,
> >> + ? ? ? ? ? ? ? ? ? ? ?sizeof(struct ath_regulatory));
> >> + ? ? ? ? ? ? ? break;
> >> + ? ? ? case NL80211_REGDOM_SET_BY_DRIVER:
> >> ? ? ? ?case NL80211_REGDOM_SET_BY_USER:
> >> ? ? ? ? ? ? ? ?break;
> >>
> >> Can you please test without this patch and ensure you get the data
> >> properly restored?
> >>
> > But the regulatory updates are ignored for CUSTOM_REGULATORY cards
> > at wiphy_update_regulatory. Isn't it?
> >
> > ? ? ? ?if (initiator == NL80211_REGDOM_SET_BY_CORE &&
> > ? ? ? ? ? ?wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) {
> > ? ? ? ? ? ? ? ?REG_DBG_PRINT("Ignoring regulatory request %s "
> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"since the driver uses its own custom "
> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"regulatory domain\n",
> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?reg_initiator_name(initiator));
> > ? ? ? ? ? ? ? ?return true;
> >
> > To ensure that the regulatory is restored always, I did it at bss_info_change.
>
> Ah yes, good point. In that case, please instead modify
> net/wireless/reg.c to call at least the reg_notifier() even if nothing
> is done. That way not only ath9k but all the other ath drivers benefit
> from this change.
>
Then I will send it as separate one. Thanks for the comments.

John,

Please drop this patch alone from the series.

--
Rajkumar

2011-12-07 13:53:57

by Rajkumar Manoharan

[permalink] [raw]
Subject: [PATCH 4/4] ath9k: Reconfigure tx power on regulatory update

Whenever the regulatory got updated by country IE for the world
roaming cards, need to reconfigure the tx power immediately to
increase the power level.

Signed-off-by: Rajkumar Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/init.c | 17 +++++++++++++++--
1 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 41b72fa..999fdc0 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -297,9 +297,22 @@ static int ath9k_reg_notifier(struct wiphy *wiphy,
{
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
struct ath_softc *sc = hw->priv;
- struct ath_regulatory *reg = ath9k_hw_regulatory(sc->sc_ah);
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
+ int ret;
+
+ ret = ath_reg_notifier_apply(wiphy, request, reg);

- return ath_reg_notifier_apply(wiphy, request, reg);
+ /* Set tx power */
+ if (ah->curchan)
+ sc->config.txpowlimit = 2 * ah->curchan->chan->max_power;
+
+ ath9k_ps_wakeup(sc);
+ ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit, false);
+ sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
+ ath9k_ps_restore(sc);
+
+ return ret;
}

/*
--
1.7.8


2011-12-07 21:38:12

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 3/4] ath9k: Restore EEPROM regulatory upon STA disconnect

On Wed, Dec 7, 2011 at 5:53 AM, Rajkumar Manoharan
<[email protected]> wrote:
> The current regulatory for world roaming mode cards might be
> overriden by country IE from the assiciated AP. But these
> regulatory values are failed to be restored on disconnection.
> This patch ensures to resotre regulatry values at driver side.
>
> Signed-off-by: Rajkumar Manoharan <[email protected]>
> ---
>  drivers/net/wireless/ath/ath9k/main.c |    8 ++++++++
>  1 files changed, 8 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
> index 424289f..a4dbb7b 100644
> --- a/drivers/net/wireless/ath/ath9k/main.c
> +++ b/drivers/net/wireless/ath/ath9k/main.c
> @@ -2046,6 +2046,14 @@ static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif)
>                sc->sc_flags &= ~SC_OP_ANI_RUN;
>                del_timer_sync(&common->ani.timer);
>                memset(&sc->caldata, 0, sizeof(sc->caldata));
> +               /*
> +                * Restore regulatory values that might be updated
> +                * by country IEs.
> +                */
> +               if (!ath_is_world_regd(&common->regulatory) &&
> +                   ath_is_world_regd(&common->reg_world_copy))
> +                       memcpy(&common->regulatory, &common->reg_world_copy,
> +                              sizeof(struct ath_regulatory));
>        }

NACK, this patch should not be required given that patch [2/4] in this
series restores this on the reg_notifier() for the
NL80211_REGDOM_SET_BY_CORE case -- the trick is that when cfg80211
detects not only a disconnect, but any regulatory restore, it will
*always* send a reg core hint! Again the hunk from patch [2/4] was:

@@ -363,14 +381,37 @@ int ath_reg_notifier_apply(struct wiphy *wiphy,
return 0;

switch (request->initiator) {
- case NL80211_REGDOM_SET_BY_DRIVER:
case NL80211_REGDOM_SET_BY_CORE:
+ /*
+ * If common->reg_world_copy is world roaming it means we *were*
+ * world roaming... so we now have to restore that data.
+ */
+ if (!ath_is_world_regd(&common->reg_world_copy))
+ break;
+
+ memcpy(reg, &common->reg_world_copy,
+ sizeof(struct ath_regulatory));
+ break;
+ case NL80211_REGDOM_SET_BY_DRIVER:
case NL80211_REGDOM_SET_BY_USER:
break;

Can you please test without this patch and ensure you get the data
properly restored?

Luis

2011-12-08 06:02:38

by Rajkumar Manoharan

[permalink] [raw]
Subject: Re: [PATCH 3/4] ath9k: Restore EEPROM regulatory upon STA disconnect

On Wed, Dec 07, 2011 at 01:37:49PM -0800, Luis R. Rodriguez wrote:
> On Wed, Dec 7, 2011 at 5:53 AM, Rajkumar Manoharan
> <[email protected]> wrote:
> > The current regulatory for world roaming mode cards might be
> > overriden by country IE from the assiciated AP. But these
> > regulatory values are failed to be restored on disconnection.
> > This patch ensures to resotre regulatry values at driver side.
> >
> > Signed-off-by: Rajkumar Manoharan <[email protected]>
> > ---
> > ?drivers/net/wireless/ath/ath9k/main.c | ? ?8 ++++++++
> > ?1 files changed, 8 insertions(+), 0 deletions(-)
> >
> > diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
> > index 424289f..a4dbb7b 100644
> > --- a/drivers/net/wireless/ath/ath9k/main.c
> > +++ b/drivers/net/wireless/ath/ath9k/main.c
> > @@ -2046,6 +2046,14 @@ static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif)
> > ? ? ? ? ? ? ? ?sc->sc_flags &= ~SC_OP_ANI_RUN;
> > ? ? ? ? ? ? ? ?del_timer_sync(&common->ani.timer);
> > ? ? ? ? ? ? ? ?memset(&sc->caldata, 0, sizeof(sc->caldata));
> > + ? ? ? ? ? ? ? /*
> > + ? ? ? ? ? ? ? ?* Restore regulatory values that might be updated
> > + ? ? ? ? ? ? ? ?* by country IEs.
> > + ? ? ? ? ? ? ? ?*/
> > + ? ? ? ? ? ? ? if (!ath_is_world_regd(&common->regulatory) &&
> > + ? ? ? ? ? ? ? ? ? ath_is_world_regd(&common->reg_world_copy))
> > + ? ? ? ? ? ? ? ? ? ? ? memcpy(&common->regulatory, &common->reg_world_copy,
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sizeof(struct ath_regulatory));
> > ? ? ? ?}
>
> NACK, this patch should not be required given that patch [2/4] in this
> series restores this on the reg_notifier() for the
> NL80211_REGDOM_SET_BY_CORE case -- the trick is that when cfg80211
> detects not only a disconnect, but any regulatory restore, it will
> *always* send a reg core hint! Again the hunk from patch [2/4] was:
>
> @@ -363,14 +381,37 @@ int ath_reg_notifier_apply(struct wiphy *wiphy,
> return 0;
>
> switch (request->initiator) {
> - case NL80211_REGDOM_SET_BY_DRIVER:
> case NL80211_REGDOM_SET_BY_CORE:
> + /*
> + * If common->reg_world_copy is world roaming it means we *were*
> + * world roaming... so we now have to restore that data.
> + */
> + if (!ath_is_world_regd(&common->reg_world_copy))
> + break;
> +
> + memcpy(reg, &common->reg_world_copy,
> + sizeof(struct ath_regulatory));
> + break;
> + case NL80211_REGDOM_SET_BY_DRIVER:
> case NL80211_REGDOM_SET_BY_USER:
> break;
>
> Can you please test without this patch and ensure you get the data
> properly restored?
>
But the regulatory updates are ignored for CUSTOM_REGULATORY cards
at wiphy_update_regulatory. Isn't it?

if (initiator == NL80211_REGDOM_SET_BY_CORE &&
wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) {
REG_DBG_PRINT("Ignoring regulatory request %s "
"since the driver uses its own custom "
"regulatory domain\n",
reg_initiator_name(initiator));
return true;

To ensure that the regulatory is restored always, I did it at bss_info_change.

--
Rajkumar