From patchwork Wed Jan 6 23:20:52 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= X-Patchwork-Id: 7972021 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 1770F9F32E for ; Wed, 6 Jan 2016 23:21:17 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C0B9A20154 for ; Wed, 6 Jan 2016 23:21:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 641A62014A for ; Wed, 6 Jan 2016 23:21:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752149AbcAFXVN (ORCPT ); Wed, 6 Jan 2016 18:21:13 -0500 Received: from mail-lb0-f172.google.com ([209.85.217.172]:33235 "EHLO mail-lb0-f172.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751924AbcAFXVL (ORCPT ); Wed, 6 Jan 2016 18:21:11 -0500 Received: by mail-lb0-f172.google.com with SMTP id sv6so191609796lbb.0 for ; Wed, 06 Jan 2016 15:21:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:mime-version:content-type :content-transfer-encoding; bh=GswmZh2Oa+oCKekNuGOwP9Ca/NZLW201g9SdzRvGH1s=; b=Zsj/iMOtsg/axAAHFCu0h1ZtVWY18s7QnCAJ20dKlZfkfG6YcOmw78tnOX5cYAbqmI uR8uZs4z8I7QwXHy211uZ7E2KuIfYa//LwfvFKLo29SbIeKLIqE+yh9y7iubl+dwdZwl 1eNP+30SiPCJqhRINsgGyMSrwYsJWi1JH+BP8OFOA+8b3cSdrd0xehRxj4q0ZdgQM+sk oxSvJeymvFBXd7uhrhDdKu7SRnYZJ1mzJMYiInzQ+u2JWyXXMt38LNlHeQlgQ3rXcd/Z y/9U/3B28+QgaOhDa/V49lec3KmZ/L3RaHUKgPdO4jAGBV36dXmdGHCfNqTtsTOROYN7 eFVA== X-Received: by 10.112.141.70 with SMTP id rm6mr29342990lbb.94.1452122469788; Wed, 06 Jan 2016 15:21:09 -0800 (PST) Received: from linux-samsung.lan (ip-194-187-74-233.konfederacka.maverick.com.pl. [194.187.74.233]) by smtp.gmail.com with ESMTPSA id d10sm11109891lfd.11.2016.01.06.15.21.08 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 06 Jan 2016 15:21:09 -0800 (PST) From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= To: linux-wireless@vger.kernel.org Cc: brcm80211-dev-list@broadcom.com, =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Subject: [RFC HACK][PATCH] brcmfmac: provide country found in NVRAM as regulatory hint Date: Thu, 7 Jan 2016 00:20:52 +0100 Message-Id: <1452122452-20732-1-git-send-email-zajec5@gmail.com> X-Mailer: git-send-email 1.8.4.5 MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP NVRAM may contain info about device country. Example from SR40ac (US): wl_country_code=US wl0_country_code=US wl1_country_code=US or Netgear R8000 (Canada): wl0_country_code=CA wl1_country_code=CA wl2_country_code=CA Read it when parsing NVRAM and provide to regulatory. Signed-off-by: Rafa? Mi?ecki --- This is HACKy code, do not apply! Hi, I wanted to post this suggestion for improving brcmfmac. It's bothering OpenWrt users that have to set country manually. This code is ugly. I think done callback is getting too complex and I don't like the way of referencing wiphy in pcie.c. But it gives a basic idea and I'd like to see if there will be any comments. --- .../broadcom/brcm80211/brcmfmac/cfg80211.h | 3 ++ .../broadcom/brcm80211/brcmfmac/firmware.c | 53 ++++++++++++++-------- .../broadcom/brcm80211/brcmfmac/firmware.h | 6 ++- .../wireless/broadcom/brcm80211/brcmfmac/pcie.c | 16 ++++++- .../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 3 +- .../net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 3 +- 6 files changed, 59 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h index c17b6d5..cb96f68 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h @@ -20,6 +20,9 @@ /* for brcmu_d11inf */ #include +#include "fwil_types.h" +#include "p2p.h" + #define WL_NUM_SCAN_MAX 10 #define WL_TLV_INFO_MAX 1024 #define WL_BSS_INFO_MAX 2048 diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c index 1e4d5f6..6692ef1 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c @@ -32,6 +32,19 @@ static char brcmf_firmware_path[BRCMF_FW_NAME_LEN]; module_param_string(alternative_fw_path, brcmf_firmware_path, BRCMF_FW_NAME_LEN, 0440); +struct brcmf_fw { + struct device *dev; + u16 flags; + const struct firmware *code; + const char *nvram_name; + u16 domain_nr; + u16 bus_nr; + char alpha2[2]; + void (*done)(struct device *dev, const struct firmware *fw, + void *nvram_image, u32 nvram_len, const char *alpha2); + struct completion *completion; +}; + enum nvram_parser_state { IDLE, KEY, @@ -65,6 +78,7 @@ struct nvram_parser { u32 entry; bool multi_dev_v1; bool multi_dev_v2; + char alpha2[2]; }; /** @@ -127,6 +141,11 @@ static enum nvram_parser_state brcmf_nvram_handle_key(struct nvram_parser *nvp) nvp->multi_dev_v1 = true; if (strncmp(&nvp->data[nvp->entry], "pcie/", 5) == 0) nvp->multi_dev_v2 = true; + /* TODO: Use wl%d_country_code */ + if (!strncmp(&nvp->data[nvp->entry], "wl0_country_code", 16)) { + nvp->alpha2[0] = nvp->data[nvp->pos + 1]; + nvp->alpha2[1] = nvp->data[nvp->pos + 2]; + } } else if (!is_nvram_char(c) || c == ' ') { brcmf_dbg(INFO, "warning: ln=%d:col=%d: '=' expected, skip invalid key entry\n", nvp->line, nvp->column); @@ -364,7 +383,7 @@ fail: * End of buffer is completed with token identifying length of buffer. */ static void *brcmf_fw_nvram_strip(const u8 *data, size_t data_len, - u32 *new_length, u16 domain_nr, u16 bus_nr) + u32 *new_length, struct brcmf_fw *fwctx) { struct nvram_parser nvp; u32 pad; @@ -380,9 +399,14 @@ static void *brcmf_fw_nvram_strip(const u8 *data, size_t data_len, break; } if (nvp.multi_dev_v1) - brcmf_fw_strip_multi_v1(&nvp, domain_nr, bus_nr); + brcmf_fw_strip_multi_v1(&nvp, fwctx->domain_nr, fwctx->bus_nr); else if (nvp.multi_dev_v2) - brcmf_fw_strip_multi_v2(&nvp, domain_nr, bus_nr); + brcmf_fw_strip_multi_v2(&nvp, fwctx->domain_nr, fwctx->bus_nr); + + if (nvp.alpha2[0]) { + fwctx->alpha2[0] = nvp.alpha2[0]; + fwctx->alpha2[1] = nvp.alpha2[1]; + } if (nvp.nvram_len == 0) { kfree(nvp.nvram); @@ -411,17 +435,6 @@ void brcmf_fw_nvram_free(void *nvram) kfree(nvram); } -struct brcmf_fw { - struct device *dev; - u16 flags; - const struct firmware *code; - const char *nvram_name; - u16 domain_nr; - u16 bus_nr; - void (*done)(struct device *dev, const struct firmware *fw, - void *nvram_image, u32 nvram_len); -}; - static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx) { struct brcmf_fw *fwctx = ctx; @@ -445,7 +458,7 @@ static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx) if (data) nvram = brcmf_fw_nvram_strip(data, data_len, &nvram_length, - fwctx->domain_nr, fwctx->bus_nr); + fwctx); if (raw_nvram) bcm47xx_nvram_release_contents(data); @@ -453,7 +466,7 @@ static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx) if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL)) goto fail; - fwctx->done(fwctx->dev, fwctx->code, nvram, nvram_length); + fwctx->done(fwctx->dev, fwctx->code, nvram, nvram_length, fwctx->alpha2[0] ? fwctx->alpha2 : NULL); kfree(fwctx); return; @@ -475,7 +488,7 @@ static void brcmf_fw_request_code_done(const struct firmware *fw, void *ctx) /* only requested code so done here */ if (!(fwctx->flags & BRCMF_FW_REQUEST_NVRAM)) { - fwctx->done(fwctx->dev, fw, NULL, 0); + fwctx->done(fwctx->dev, fw, NULL, 0, NULL); kfree(fwctx); return; } @@ -500,7 +513,8 @@ int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags, const char *code, const char *nvram, void (*fw_cb)(struct device *dev, const struct firmware *fw, - void *nvram_image, u32 nvram_len), + void *nvram_image, u32 nvram_len, + const char *alpha2), u16 domain_nr, u16 bus_nr) { struct brcmf_fw *fwctx; @@ -533,7 +547,8 @@ int brcmf_fw_get_firmwares(struct device *dev, u16 flags, const char *code, const char *nvram, void (*fw_cb)(struct device *dev, const struct firmware *fw, - void *nvram_image, u32 nvram_len)) + void *nvram_image, u32 nvram_len, + const char *alpha2)) { return brcmf_fw_get_firmwares_pcie(dev, flags, code, nvram, fw_cb, 0, 0); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h index ef06f57..963e929 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h @@ -76,12 +76,14 @@ int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags, const char *code, const char *nvram, void (*fw_cb)(struct device *dev, const struct firmware *fw, - void *nvram_image, u32 nvram_len), + void *nvram_image, u32 nvram_len, + const char *alpha2), u16 domain_nr, u16 bus_nr); int brcmf_fw_get_firmwares(struct device *dev, u16 flags, const char *code, const char *nvram, void (*fw_cb)(struct device *dev, const struct firmware *fw, - void *nvram_image, u32 nvram_len)); + void *nvram_image, u32 nvram_len, + const char *alpha2)); #endif /* BRCMFMAC_FIRMWARE_H */ diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c index 3d2d790..1980416 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c @@ -1682,8 +1682,11 @@ static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = { .write32 = brcmf_pcie_buscore_write32, }; +#include "core.h" +#include "cfg80211.h" + static void brcmf_pcie_setup(struct device *dev, const struct firmware *fw, - void *nvram, u32 nvram_len) + void *nvram, u32 nvram_len, const char *alpha2) { struct brcmf_bus *bus = dev_get_drvdata(dev); struct brcmf_pciedev *pcie_bus_dev = bus->bus_priv.pcie; @@ -1734,8 +1737,17 @@ static void brcmf_pcie_setup(struct device *dev, const struct firmware *fw, init_waitqueue_head(&devinfo->mbdata_resp_wait); brcmf_pcie_intr_enable(devinfo); - if (brcmf_pcie_attach_bus(bus->dev) == 0) + if (brcmf_pcie_attach_bus(bus->dev) == 0) { + if (alpha2) { + struct brcmf_bus *bus_if = dev_get_drvdata(bus->dev); + struct brcmf_pub *drvr = bus_if->drvr; + struct brcmf_cfg80211_info *cfg = drvr->config; + + regulatory_hint(cfg->wiphy, alpha2); + } + return; + } brcmf_pcie_bus_console_read(devinfo); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index ceb2a75..e8552ac 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -3928,7 +3928,8 @@ static const struct brcmf_bus_ops brcmf_sdio_bus_ops = { static void brcmf_sdio_firmware_callback(struct device *dev, const struct firmware *code, - void *nvram, u32 nvram_len) + void *nvram, u32 nvram_len, + const char *alpha2) { struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c index 66c26a9..78ae9d3 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c @@ -1159,7 +1159,8 @@ fail: static void brcmf_usb_probe_phase2(struct device *dev, const struct firmware *fw, - void *nvram, u32 nvlen) + void *nvram, u32 nvlen, + const char *alpha2) { struct brcmf_bus *bus = dev_get_drvdata(dev); struct brcmf_usbdev_info *devinfo;