mac80211: backport today's brcmfmac changes

This adds support for SR400ac NVRAM and fixes
/sys/class/ieee80211/*/macaddress

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>

SVN-Revision: 45928
This commit is contained in:
Rafał Miłecki 2015-06-08 12:50:38 +00:00
parent a1340b5cce
commit da01dbff70
3 changed files with 223 additions and 0 deletions

View file

@ -0,0 +1,56 @@
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
Date: Thu, 28 May 2015 14:19:21 +0200
Subject: [PATCH] brcmfmac: support NVRAMs containing pci devpaths (instead of
pcie)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Recently Broadcom added support for NVRAMs with entries for multiple
PCIe devices. One of the supported formats is based on prefixes defined
like: devpath0=pcie/1/4/ and entries like 0:foo=bar 0:baz=qux etc.
Unfortunately there are also a bit older devices using different way of
defining prefixes, e.g. SmartRG SR400ac (2 x BCM43602) with entries:
devpath0=pci/1/1/
devpath1=pci/2/1
Broadcom stated this old format will never be used/supported by brcmfmac
but given the simplicity of this patch I'll insist on supporting it.
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
--- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
@@ -232,6 +232,8 @@ static void brcmf_fw_strip_multi_v1(stru
u16 bus_nr)
{
/* Device path with a leading '=' key-value separator */
+ char pci_path[] = "=pci/?/?";
+ size_t pci_len;
char pcie_path[] = "=pcie/?/?";
size_t pcie_len;
@@ -251,6 +253,9 @@ static void brcmf_fw_strip_multi_v1(stru
/* First search for the devpathX and see if it is the configuration
* for domain_nr/bus_nr. Search complete nvp
*/
+ snprintf(pci_path, sizeof(pci_path), "=pci/%d/%d", domain_nr,
+ bus_nr);
+ pci_len = strlen(pci_path);
snprintf(pcie_path, sizeof(pcie_path), "=pcie/%d/%d", domain_nr,
bus_nr);
pcie_len = strlen(pcie_path);
@@ -260,8 +265,9 @@ static void brcmf_fw_strip_multi_v1(stru
/* Format: devpathX=pcie/Y/Z/
* Y = domain_nr, Z = bus_nr, X = virtual ID
*/
- if ((strncmp(&nvp->nvram[i], "devpath", 7) == 0) &&
- (strncmp(&nvp->nvram[i + 8], pcie_path, pcie_len) == 0)) {
+ if (strncmp(&nvp->nvram[i], "devpath", 7) == 0 &&
+ (!strncmp(&nvp->nvram[i + 8], pci_path, pci_len) ||
+ !strncmp(&nvp->nvram[i + 8], pcie_path, pcie_len))) {
id = nvp->nvram[i + 7] - '0';
found = true;
break;

View file

@ -0,0 +1,23 @@
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
Date: Sun, 31 May 2015 02:52:26 +0200
Subject: [PATCH] brcmfmac: set wiphy perm_addr to hardware MAC address
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This allows e.g. user space to use /sys/class/ieee80211/*/macaddress
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
@@ -6070,6 +6070,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802
brcmf_err("Could not allocate wiphy device\n");
return NULL;
}
+ memcpy(wiphy->perm_addr, drvr->mac, ETH_ALEN);
set_wiphy_dev(wiphy, busdev);
cfg = wiphy_priv(wiphy);

View file

@ -0,0 +1,144 @@
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
Date: Thu, 4 Jun 2015 22:11:07 +0200
Subject: [PATCH] brcmfmac: use direct data pointer in NVRAM parser struct
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
As we plan to add support for platform NVRAM we should store direct
data pointer without the extra struct firmware layer. This will allow
us to support other sources with the only requirement being u8 buffer.
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Acked-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
--- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
@@ -43,7 +43,7 @@ enum nvram_parser_state {
* struct nvram_parser - internal info for parser.
*
* @state: current parser state.
- * @fwnv: input buffer being parsed.
+ * @data: input buffer being parsed.
* @nvram: output buffer with parse result.
* @nvram_len: lenght of parse result.
* @line: current line.
@@ -55,7 +55,7 @@ enum nvram_parser_state {
*/
struct nvram_parser {
enum nvram_parser_state state;
- const struct firmware *fwnv;
+ const u8 *data;
u8 *nvram;
u32 nvram_len;
u32 line;
@@ -91,7 +91,7 @@ static enum nvram_parser_state brcmf_nvr
{
char c;
- c = nvp->fwnv->data[nvp->pos];
+ c = nvp->data[nvp->pos];
if (c == '\n')
return COMMENT;
if (is_whitespace(c))
@@ -115,16 +115,16 @@ static enum nvram_parser_state brcmf_nvr
enum nvram_parser_state st = nvp->state;
char c;
- c = nvp->fwnv->data[nvp->pos];
+ c = nvp->data[nvp->pos];
if (c == '=') {
/* ignore RAW1 by treating as comment */
- if (strncmp(&nvp->fwnv->data[nvp->entry], "RAW1", 4) == 0)
+ if (strncmp(&nvp->data[nvp->entry], "RAW1", 4) == 0)
st = COMMENT;
else
st = VALUE;
- if (strncmp(&nvp->fwnv->data[nvp->entry], "devpath", 7) == 0)
+ if (strncmp(&nvp->data[nvp->entry], "devpath", 7) == 0)
nvp->multi_dev_v1 = true;
- if (strncmp(&nvp->fwnv->data[nvp->entry], "pcie/", 5) == 0)
+ if (strncmp(&nvp->data[nvp->entry], "pcie/", 5) == 0)
nvp->multi_dev_v2 = true;
} else if (!is_nvram_char(c) || c == ' ') {
brcmf_dbg(INFO, "warning: ln=%d:col=%d: '=' expected, skip invalid key entry\n",
@@ -145,11 +145,11 @@ brcmf_nvram_handle_value(struct nvram_pa
char *ekv;
u32 cplen;
- c = nvp->fwnv->data[nvp->pos];
+ c = nvp->data[nvp->pos];
if (!is_nvram_char(c)) {
/* key,value pair complete */
- ekv = (u8 *)&nvp->fwnv->data[nvp->pos];
- skv = (u8 *)&nvp->fwnv->data[nvp->entry];
+ ekv = (u8 *)&nvp->data[nvp->pos];
+ skv = (u8 *)&nvp->data[nvp->entry];
cplen = ekv - skv;
if (nvp->nvram_len + cplen + 1 >= BRCMF_FW_MAX_NVRAM_SIZE)
return END;
@@ -170,7 +170,7 @@ brcmf_nvram_handle_comment(struct nvram_
{
char *eoc, *sol;
- sol = (char *)&nvp->fwnv->data[nvp->pos];
+ sol = (char *)&nvp->data[nvp->pos];
eoc = strchr(sol, '\n');
if (!eoc) {
eoc = strchr(sol, '\0');
@@ -201,17 +201,17 @@ static enum nvram_parser_state
};
static int brcmf_init_nvram_parser(struct nvram_parser *nvp,
- const struct firmware *nv)
+ const u8 *data, size_t data_len)
{
size_t size;
memset(nvp, 0, sizeof(*nvp));
- nvp->fwnv = nv;
+ nvp->data = data;
/* Limit size to MAX_NVRAM_SIZE, some files contain lot of comment */
- if (nv->size > BRCMF_FW_MAX_NVRAM_SIZE)
+ if (data_len > BRCMF_FW_MAX_NVRAM_SIZE)
size = BRCMF_FW_MAX_NVRAM_SIZE;
else
- size = nv->size;
+ size = data_len;
/* Alloc for extra 0 byte + roundup by 4 + length field */
size += 1 + 3 + sizeof(u32);
nvp->nvram = kzalloc(size, GFP_KERNEL);
@@ -362,18 +362,18 @@ fail:
* and converts newlines to NULs. Shortens buffer as needed and pads with NULs.
* End of buffer is completed with token identifying length of buffer.
*/
-static void *brcmf_fw_nvram_strip(const struct firmware *nv, u32 *new_length,
- u16 domain_nr, u16 bus_nr)
+static void *brcmf_fw_nvram_strip(const u8 *data, size_t data_len,
+ u32 *new_length, u16 domain_nr, u16 bus_nr)
{
struct nvram_parser nvp;
u32 pad;
u32 token;
__le32 token_le;
- if (brcmf_init_nvram_parser(&nvp, nv) < 0)
+ if (brcmf_init_nvram_parser(&nvp, data, data_len) < 0)
return NULL;
- while (nvp.pos < nv->size) {
+ while (nvp.pos < data_len) {
nvp.state = nv_parser_states[nvp.state](&nvp);
if (nvp.state == END)
break;
@@ -432,7 +432,7 @@ static void brcmf_fw_request_nvram_done(
goto fail;
if (fw) {
- nvram = brcmf_fw_nvram_strip(fw, &nvram_length,
+ nvram = brcmf_fw_nvram_strip(fw->data, fw->size, &nvram_length,
fwctx->domain_nr, fwctx->bus_nr);
release_firmware(fw);
if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))