This adds support for SR400ac NVRAM and fixes /sys/class/ieee80211/*/macaddress Signed-off-by: Rafał Miłecki <zajec5@gmail.com> SVN-Revision: 45928master
parent
a1340b5cce
commit
da01dbff70
@ -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;
|
@ -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);
|
@ -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))
|
Loading…
Reference in new issue