2016-08-02 12:21:06

by Bartosz Markowski

[permalink] [raw]
Subject: [PATCH 0/2] platform regulatory support

Hardware or platform manufacturers may want to use a persistent
memory storage to program ragulatory settings via e.g. bios, uefi, acpi.

This patch set implements methods to retrieve the platform regulatory
settings (via ACPI calls) and use them to override the wifi chip
eeprom default settings.

This has been developed and tested on Skylake (Chromebook) platform, where the
persistent area containing "region" value is called VPD.

Bartosz Markowski (1):
ath10k: add platform regulatory domain support

Michal Kazior (1):
ath: export alpha2 helper

drivers/net/wireless/ath/ath10k/core.h | 1 +
drivers/net/wireless/ath/ath10k/mac.c | 117 +++++++++++++++++++++++++++++++++
drivers/net/wireless/ath/ath10k/wmi.c | 2 +-
drivers/net/wireless/ath/regd.c | 3 +-
drivers/net/wireless/ath/regd.h | 1 +
5 files changed, 122 insertions(+), 2 deletions(-)

--
2.1.2



2016-08-02 12:21:08

by Bartosz Markowski

[permalink] [raw]
Subject: [PATCH 2/2] ath10k: add platform regulatory domain support

This overrides whatever regulatory the device
EEPROM contains and uses what the platform says
instead - in this implementation the ACPI driver.

In case the hint is not programmed or corrupted (0xffff)
the device falls back to the eeprom programmed settings.

Signed-off-by: Bartosz Markowski <[email protected]>
---
drivers/net/wireless/ath/ath10k/core.h | 1 +
drivers/net/wireless/ath/ath10k/mac.c | 117 +++++++++++++++++++++++++++++++++
drivers/net/wireless/ath/ath10k/wmi.c | 2 +-
3 files changed, 119 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 30ae5bf81611..1df7c600a2bb 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -692,6 +692,7 @@ struct ath10k {
u32 phy_capability;
u32 hw_min_tx_power;
u32 hw_max_tx_power;
+ u32 hw_eeprom_rd;
u32 ht_cap_info;
u32 vht_cap_info;
u32 num_rf_chains;
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index fb8e38df9446..b6b8a0b2046b 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -19,6 +19,7 @@

#include <net/mac80211.h>
#include <linux/etherdevice.h>
+#include <linux/acpi.h>

#include "hif.h"
#include "core.h"
@@ -7751,6 +7752,116 @@ struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id)
return arvif_iter.arvif;
}

+#ifdef CONFIG_ACPI
+#define WRD_METHOD "WRDD"
+#define WRDD_WIFI (0x07)
+
+static u32 ath10k_mac_wrdd_get_mcc(struct ath10k *ar, union acpi_object *wrdd)
+{
+ union acpi_object *mcc_pkg;
+ union acpi_object *domain_type;
+ union acpi_object *mcc_value;
+ u32 i;
+
+ if (wrdd->type != ACPI_TYPE_PACKAGE ||
+ wrdd->package.count < 2 ||
+ wrdd->package.elements[0].type != ACPI_TYPE_INTEGER ||
+ wrdd->package.elements[0].integer.value != 0) {
+ ath10k_warn(ar, "ignoring malformed/unsupported wrdd structure\n");
+ return 0;
+ }
+
+ for (i = 1; i < wrdd->package.count; ++i) {
+ mcc_pkg = &wrdd->package.elements[i];
+
+ if (mcc_pkg->type != ACPI_TYPE_PACKAGE)
+ continue;
+ if (mcc_pkg->package.count < 2)
+ continue;
+ if (mcc_pkg->package.elements[0].type != ACPI_TYPE_INTEGER ||
+ mcc_pkg->package.elements[1].type != ACPI_TYPE_INTEGER)
+ continue;
+
+ domain_type = &mcc_pkg->package.elements[0];
+ if (domain_type->integer.value != WRDD_WIFI)
+ continue;
+
+ mcc_value = &mcc_pkg->package.elements[1];
+ return mcc_value->integer.value;
+ }
+ return 0;
+}
+
+static u16 ath10k_mac_get_wrdd_regulatory(struct ath10k *ar)
+{
+ u16 rd;
+ acpi_handle root_handle;
+ acpi_handle handle;
+ struct acpi_buffer wrdd = {ACPI_ALLOCATE_BUFFER, NULL};
+ acpi_status status;
+ u32 alpha2_code;
+ char alpha2[3];
+ struct pci_dev *pdev = to_pci_dev(ar->dev);
+
+ root_handle = ACPI_HANDLE(&pdev->dev);
+ if (!root_handle) {
+ ath10k_warn(ar, "failed to get root port acpi handle\n");
+ return -1;
+ }
+
+ status = acpi_get_handle(root_handle, (acpi_string)WRD_METHOD, &handle);
+ if (ACPI_FAILURE(status)) {
+ ath10k_warn(ar, "failed to get wrd method %d\n", status);
+ return -1;
+ }
+
+ status = acpi_evaluate_object(handle, NULL, NULL, &wrdd);
+ if (ACPI_FAILURE(status)) {
+ ath10k_warn(ar, "failed to call wrdc %d\n", status);
+ return -1;
+ }
+
+ alpha2_code = ath10k_mac_wrdd_get_mcc(ar, wrdd.pointer);
+ kfree(wrdd.pointer);
+ if (!alpha2_code)
+ return -1;
+
+ alpha2[0] = (alpha2_code >> 8) & 0xff;
+ alpha2[1] = (alpha2_code >> 0) & 0xff;
+ alpha2[2] = '\0';
+
+ ath10k_info(ar, "regulatory hint from WRDD (alpha2-code): %s\n", alpha2);
+
+ rd = ath_regd_find_country_by_name(alpha2);
+ if (rd == 0xffff)
+ return rd;
+
+ rd |= COUNTRY_ERD_FLAG;
+ return rd;
+}
+
+#else
+static u16 ath10k_mac_get_wrdd_regulatory(struct ath10k *ar)
+{
+ /* fallback to default eeprom settings */
+ return -1;
+}
+#endif
+
+static int ath10k_mac_init_rd(struct ath10k *ar)
+{
+ u16 rd;
+
+ rd = ath10k_mac_get_wrdd_regulatory(ar);
+ if (rd == 0xffff) {
+ ath10k_info(ar, "fallback to eeprom programmed regulatory settings\n");
+ rd = ar->hw_eeprom_rd;
+ }
+
+ ar->ath_common.regulatory.current_rd = rd;
+ return 0;
+}
+
int ath10k_mac_register(struct ath10k *ar)
{
static const u32 cipher_suites[] = {
@@ -7974,6 +8085,12 @@ int ath10k_mac_register(struct ath10k *ar)
ar->running_fw->fw_file.fw_features))
ar->ops->wake_tx_queue = NULL;

+ ret = ath10k_mac_init_rd(ar);
+ if (ret) {
+ ath10k_err(ar, "failed to derive regdom: %d\n", ret);
+ goto err_dfs_detector_exit;
+ }
+
ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy,
ath10k_reg_notifier);
if (ret) {
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 169cd2e783eb..e9aadc85ad1b 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -4635,7 +4635,7 @@ static void ath10k_wmi_event_service_ready_work(struct work_struct *work)
ar->fw_version_build = (__le32_to_cpu(arg.sw_ver1) & 0x0000ffff);
ar->phy_capability = __le32_to_cpu(arg.phy_capab);
ar->num_rf_chains = __le32_to_cpu(arg.num_rf_chains);
- ar->ath_common.regulatory.current_rd = __le32_to_cpu(arg.eeprom_rd);
+ ar->hw_eeprom_rd = __le32_to_cpu(arg.eeprom_rd);

ath10k_dbg_dump(ar, ATH10K_DBG_WMI, NULL, "wmi svc: ",
arg.service_map, arg.service_map_len);
--
2.1.2


2016-08-02 12:21:07

by Bartosz Markowski

[permalink] [raw]
Subject: [PATCH 1/2] ath: export alpha2 helper

From: Michal Kazior <[email protected]>

This will be helpful for drivers that can acquire
alpha2 regulatory codes.

Signed-off-by: Michal Kazior <[email protected]>
Signed-off-by: Bartosz Markowski <[email protected]>
---
drivers/net/wireless/ath/regd.c | 3 ++-
drivers/net/wireless/ath/regd.h | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c
index 7e15ed9ed31f..820bf880ada3 100644
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -449,7 +449,7 @@ static void ath_reg_apply_world_flags(struct wiphy *wiphy,
}
}

-static u16 ath_regd_find_country_by_name(char *alpha2)
+u16 ath_regd_find_country_by_name(char *alpha2)
{
unsigned int i;

@@ -460,6 +460,7 @@ static u16 ath_regd_find_country_by_name(char *alpha2)

return -1;
}
+EXPORT_SYMBOL(ath_regd_find_country_by_name);

static int __ath_reg_dyn_country(struct wiphy *wiphy,
struct ath_regulatory *reg,
diff --git a/drivers/net/wireless/ath/regd.h b/drivers/net/wireless/ath/regd.h
index 565d3075f06e..5d80be213fac 100644
--- a/drivers/net/wireless/ath/regd.h
+++ b/drivers/net/wireless/ath/regd.h
@@ -251,6 +251,7 @@ enum CountryCode {

bool ath_is_world_regd(struct ath_regulatory *reg);
bool ath_is_49ghz_allowed(u16 redomain);
+u16 ath_regd_find_country_by_name(char *alpha2);
int ath_regd_init(struct ath_regulatory *reg, struct wiphy *wiphy,
void (*reg_notifier)(struct wiphy *wiphy,
struct regulatory_request *request));
--
2.1.2


2016-09-14 07:07:17

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 2/2] ath10k: add platform regulatory domain support

Bartosz Markowski <[email protected]> writes:

> On 12 September 2016 at 17:35, Valo, Kalle <[email protected]> wrote=
:
>
>> > +#ifdef CONFIG_ACPI
>> > +#define WRD_METHOD "WRDD"
>> > +#define WRDD_WIFI (0x07)
>> > +
>> > +static u32 ath10k_mac_wrdd_get_mcc(struct ath10k *ar, union acpi_obje=
ct *wrdd)
>> > +{
>>
>> I don't think the ifdef is really necessary, acpi.h should handle that
>> (hopefully). Also I changed the error handling to use standard error
>> values and changed the info messages to dbg, they are too spammy in my
>> opinion. Please check carefully my changes in the pending branch:
>>
>> https://git.kernel.org/cgit/linux/kernel/git/kvalo/ath.git/commit/?h=3Dp=
ending&id=3Dfe91745381ec3999d8de6dedb07b396c82539717
>
> I'm OK with the changes, I have not tried that though, except of
> reviewing and compiling it (do not have access to the chromebook for
> next few days). If you want to wait with it until I test it, it's fine
> too.

Ok, I'll wait for few days in case you have time to test it.

--=20
Kalle Valo=

2016-09-12 15:39:07

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 2/2] ath10k: add platform regulatory domain support

Bartosz Markowski <[email protected]> writes:

> This overrides whatever regulatory the device
> EEPROM contains and uses what the platform says
> instead - in this implementation the ACPI driver.
>
> In case the hint is not programmed or corrupted (0xffff)
> the device falls back to the eeprom programmed settings.
>
> Signed-off-by: Bartosz Markowski <[email protected]>

[...]

> +#ifdef CONFIG_ACPI
> +#define WRD_METHOD "WRDD"
> +#define WRDD_WIFI (0x07)
> +
> +static u32 ath10k_mac_wrdd_get_mcc(struct ath10k *ar, union acpi_object =
*wrdd)
> +{

I don't think the ifdef is really necessary, acpi.h should handle that
(hopefully). Also I changed the error handling to use standard error
values and changed the info messages to dbg, they are too spammy in my
opinion. Please check carefully my changes in the pending branch:

https://git.kernel.org/cgit/linux/kernel/git/kvalo/ath.git/commit/?h=3Dpend=
ing&id=3Dfe91745381ec3999d8de6dedb07b396c82539717

--=20
Kalle Valo=

2016-09-13 13:57:19

by Bartosz Markowski

[permalink] [raw]
Subject: Re: [PATCH 2/2] ath10k: add platform regulatory domain support

On 12 September 2016 at 17:35, Valo, Kalle <[email protected]> wrote:

[...]

> > +#ifdef CONFIG_ACPI
> > +#define WRD_METHOD "WRDD"
> > +#define WRDD_WIFI (0x07)
> > +
> > +static u32 ath10k_mac_wrdd_get_mcc(struct ath10k *ar, union acpi_object *wrdd)
> > +{
>
> I don't think the ifdef is really necessary, acpi.h should handle that
> (hopefully). Also I changed the error handling to use standard error
> values and changed the info messages to dbg, they are too spammy in my
> opinion. Please check carefully my changes in the pending branch:
>
> https://git.kernel.org/cgit/linux/kernel/git/kvalo/ath.git/commit/?h=pending&id=fe91745381ec3999d8de6dedb07b396c82539717

I'm OK with the changes, I have not tried that though, except of
reviewing and compiling it (do not have access to the chromebook for
next few days). If you want to wait with it until I test it, it's fine
too.

Bartosz

2016-10-03 07:43:19

by Bartosz Markowski

[permalink] [raw]
Subject: Re: [PATCH 2/2] ath10k: add platform regulatory domain support

On 14 September 2016 at 09:06, Valo, Kalle <[email protected]> wrote:
>
> Bartosz Markowski <[email protected]> writes:
>
> > On 12 September 2016 at 17:35, Valo, Kalle <[email protected]> wrote:
> >
> >> > +#ifdef CONFIG_ACPI
> >> > +#define WRD_METHOD "WRDD"
> >> > +#define WRDD_WIFI (0x07)
> >> > +
> >> > +static u32 ath10k_mac_wrdd_get_mcc(struct ath10k *ar, union acpi_object *wrdd)
> >> > +{
> >>
> >> I don't think the ifdef is really necessary, acpi.h should handle that
> >> (hopefully). Also I changed the error handling to use standard error
> >> values and changed the info messages to dbg, they are too spammy in my
> >> opinion. Please check carefully my changes in the pending branch:
> >>
> >> https://git.kernel.org/cgit/linux/kernel/git/kvalo/ath.git/commit/?h=pending&id=fe91745381ec3999d8de6dedb07b396c82539717
> >
> > I'm OK with the changes, I have not tried that though, except of
> > reviewing and compiling it (do not have access to the chromebook for
> > next few days). If you want to wait with it until I test it, it's fine
> > too.
>
> Ok, I'll wait for few days in case you have time to test it.


Sorry, it took so long. I've final check this and can confirm the patch.

Bartosz

2016-10-04 15:02:43

by Kalle Valo

[permalink] [raw]
Subject: Re: [1/2] ath: export alpha2 helper

Bartosz Markowski <[email protected]> wrote:
> From: Michal Kazior <[email protected]>
>
> This will be helpful for drivers that can acquire
> alpha2 regulatory codes.
>
> Signed-off-by: Michal Kazior <[email protected]>
> Signed-off-by: Bartosz Markowski <[email protected]>

2 patches applied to ath-next branch of ath.git, thanks.

d291d8e0592a ath: export alpha2 helper
209b2a68de76 ath10k: add platform regulatory domain support

--
https://patchwork.kernel.org/patch/9256535/

Documentation about submitting wireless patches and checking status
from patchwork:

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

2016-10-03 07:52:57

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 2/2] ath10k: add platform regulatory domain support

Bartosz Markowski <[email protected]> writes:

> On 14 September 2016 at 09:06, Valo, Kalle <[email protected]> wrote=
:
>>
>> Bartosz Markowski <[email protected]> writes:
>>
>> > On 12 September 2016 at 17:35, Valo, Kalle <[email protected]> wr=
ote:
>> >
>> >> > +#ifdef CONFIG_ACPI
>> >> > +#define WRD_METHOD "WRDD"
>> >> > +#define WRDD_WIFI (0x07)
>> >> > +
>> >> > +static u32 ath10k_mac_wrdd_get_mcc(struct ath10k *ar, union acpi_o=
bject *wrdd)
>> >> > +{
>> >>
>> >> I don't think the ifdef is really necessary, acpi.h should handle tha=
t
>> >> (hopefully). Also I changed the error handling to use standard error
>> >> values and changed the info messages to dbg, they are too spammy in m=
y
>> >> opinion. Please check carefully my changes in the pending branch:
>> >>
>> >> https://git.kernel.org/cgit/linux/kernel/git/kvalo/ath.git/commit/?h=
=3Dpending&id=3Dfe91745381ec3999d8de6dedb07b396c82539717
>> >
>> > I'm OK with the changes, I have not tried that though, except of
>> > reviewing and compiling it (do not have access to the chromebook for
>> > next few days). If you want to wait with it until I test it, it's fine
>> > too.
>>
>> Ok, I'll wait for few days in case you have time to test it.
>
>
> Sorry, it took so long. I've final check this and can confirm the patch.

Thanks, I'll apply the patch soon. Do note that I changed more of the
warnings messages to debug level.

--=20
Kalle Valo=