diff options
Diffstat (limited to 'package/kernel/mac80211/patches/363-brcmfmac-Add-support-for-multiple-PCIE-devices-in-nv.patch')
-rw-r--r-- | package/kernel/mac80211/patches/363-brcmfmac-Add-support-for-multiple-PCIE-devices-in-nv.patch | 351 |
1 files changed, 0 insertions, 351 deletions
diff --git a/package/kernel/mac80211/patches/363-brcmfmac-Add-support-for-multiple-PCIE-devices-in-nv.patch b/package/kernel/mac80211/patches/363-brcmfmac-Add-support-for-multiple-PCIE-devices-in-nv.patch deleted file mode 100644 index 5f9bbea..0000000 --- a/package/kernel/mac80211/patches/363-brcmfmac-Add-support-for-multiple-PCIE-devices-in-nv.patch +++ /dev/null @@ -1,351 +0,0 @@ -From: Hante Meuleman <meuleman@broadcom.com> -Date: Tue, 14 Apr 2015 20:10:33 +0200 -Subject: [PATCH] brcmfmac: Add support for multiple PCIE devices in - nvram. - -With PCIE it is possible to support multiple devices with the -same device type. They all load the same nvram file. In order to -support this the nvram can specify which part of the nvram is -for which pcie device. This patch adds support for these new -types of nvram files. - -Reviewed-by: Arend Van Spriel <arend@broadcom.com> -Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com> -Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> -Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com> -Signed-off-by: Hante Meuleman <meuleman@broadcom.com> -Signed-off-by: Arend van Spriel <arend@broadcom.com> ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c -@@ -23,6 +23,10 @@ - #include "debug.h" - #include "firmware.h" - -+#define BRCMF_FW_MAX_NVRAM_SIZE 64000 -+#define BRCMF_FW_NVRAM_DEVPATH_LEN 19 /* devpath0=pcie/1/4/ */ -+#define BRCMF_FW_NVRAM_PCIEDEV_LEN 9 /* pcie/1/4/ */ -+ - char brcmf_firmware_path[BRCMF_FW_PATH_LEN]; - module_param_string(firmware_path, brcmf_firmware_path, - BRCMF_FW_PATH_LEN, 0440); -@@ -46,6 +50,8 @@ enum nvram_parser_state { - * @column: current column in line. - * @pos: byte offset in input buffer. - * @entry: start position of key,value entry. -+ * @multi_dev_v1: detect pcie multi device v1 (compressed). -+ * @multi_dev_v2: detect pcie multi device v2. - */ - struct nvram_parser { - enum nvram_parser_state state; -@@ -56,6 +62,8 @@ struct nvram_parser { - u32 column; - u32 pos; - u32 entry; -+ bool multi_dev_v1; -+ bool multi_dev_v2; - }; - - static bool is_nvram_char(char c) -@@ -108,6 +116,10 @@ static enum nvram_parser_state brcmf_nvr - st = COMMENT; - else - st = VALUE; -+ if (strncmp(&nvp->fwnv->data[nvp->entry], "devpath", 7) == 0) -+ nvp->multi_dev_v1 = true; -+ if (strncmp(&nvp->fwnv->data[nvp->entry], "pcie/", 5) == 0) -+ nvp->multi_dev_v2 = true; - } else if (!is_nvram_char(c)) { - brcmf_dbg(INFO, "warning: ln=%d:col=%d: '=' expected, skip invalid key entry\n", - nvp->line, nvp->column); -@@ -133,6 +145,8 @@ brcmf_nvram_handle_value(struct nvram_pa - ekv = (u8 *)&nvp->fwnv->data[nvp->pos]; - skv = (u8 *)&nvp->fwnv->data[nvp->entry]; - cplen = ekv - skv; -+ if (nvp->nvram_len + cplen + 1 >= BRCMF_FW_MAX_NVRAM_SIZE) -+ return END; - /* copy to output buffer */ - memcpy(&nvp->nvram[nvp->nvram_len], skv, cplen); - nvp->nvram_len += cplen; -@@ -180,10 +194,18 @@ static enum nvram_parser_state - static int brcmf_init_nvram_parser(struct nvram_parser *nvp, - const struct firmware *nv) - { -+ size_t size; -+ - memset(nvp, 0, sizeof(*nvp)); - nvp->fwnv = nv; -+ /* Limit size to MAX_NVRAM_SIZE, some files contain lot of comment */ -+ if (nv->size > BRCMF_FW_MAX_NVRAM_SIZE) -+ size = BRCMF_FW_MAX_NVRAM_SIZE; -+ else -+ size = nv->size; - /* Alloc for extra 0 byte + roundup by 4 + length field */ -- nvp->nvram = kzalloc(nv->size + 1 + 3 + sizeof(u32), GFP_KERNEL); -+ size += 1 + 3 + sizeof(u32); -+ nvp->nvram = kzalloc(size, GFP_KERNEL); - if (!nvp->nvram) - return -ENOMEM; - -@@ -192,12 +214,136 @@ static int brcmf_init_nvram_parser(struc - return 0; - } - -+/* brcmf_fw_strip_multi_v1 :Some nvram files contain settings for multiple -+ * devices. Strip it down for one device, use domain_nr/bus_nr to determine -+ * which data is to be returned. v1 is the version where nvram is stored -+ * compressed and "devpath" maps to index for valid entries. -+ */ -+static void brcmf_fw_strip_multi_v1(struct nvram_parser *nvp, u16 domain_nr, -+ u16 bus_nr) -+{ -+ u32 i, j; -+ bool found; -+ u8 *nvram; -+ u8 id; -+ -+ nvram = kzalloc(nvp->nvram_len + 1 + 3 + sizeof(u32), GFP_KERNEL); -+ if (!nvram) -+ goto fail; -+ -+ /* min length: devpath0=pcie/1/4/ + 0:x=y */ -+ if (nvp->nvram_len < BRCMF_FW_NVRAM_DEVPATH_LEN + 6) -+ goto fail; -+ -+ /* First search for the devpathX and see if it is the configuration -+ * for domain_nr/bus_nr. Search complete nvp -+ */ -+ found = false; -+ i = 0; -+ while (i < nvp->nvram_len - BRCMF_FW_NVRAM_DEVPATH_LEN) { -+ /* 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/", 6) == 0)) { -+ if (((nvp->nvram[i + 14] - '0') == domain_nr) && -+ ((nvp->nvram[i + 16] - '0') == bus_nr)) { -+ id = nvp->nvram[i + 7] - '0'; -+ found = true; -+ break; -+ } -+ } -+ while (nvp->nvram[i] != 0) -+ i++; -+ i++; -+ } -+ if (!found) -+ goto fail; -+ -+ /* Now copy all valid entries, release old nvram and assign new one */ -+ i = 0; -+ j = 0; -+ while (i < nvp->nvram_len) { -+ if ((nvp->nvram[i] - '0' == id) && (nvp->nvram[i + 1] == ':')) { -+ i += 2; -+ while (nvp->nvram[i] != 0) { -+ nvram[j] = nvp->nvram[i]; -+ i++; -+ j++; -+ } -+ nvram[j] = 0; -+ j++; -+ } -+ while (nvp->nvram[i] != 0) -+ i++; -+ i++; -+ } -+ kfree(nvp->nvram); -+ nvp->nvram = nvram; -+ nvp->nvram_len = j; -+ return; -+ -+fail: -+ kfree(nvram); -+ nvp->nvram_len = 0; -+} -+ -+/* brcmf_fw_strip_multi_v2 :Some nvram files contain settings for multiple -+ * devices. Strip it down for one device, use domain_nr/bus_nr to determine -+ * which data is to be returned. v2 is the version where nvram is stored -+ * uncompressed, all relevant valid entries are identified by -+ * pcie/domain_nr/bus_nr: -+ */ -+static void brcmf_fw_strip_multi_v2(struct nvram_parser *nvp, u16 domain_nr, -+ u16 bus_nr) -+{ -+ u32 i, j; -+ u8 *nvram; -+ -+ nvram = kzalloc(nvp->nvram_len + 1 + 3 + sizeof(u32), GFP_KERNEL); -+ if (!nvram) -+ goto fail; -+ -+ /* Copy all valid entries, release old nvram and assign new one. -+ * Valid entries are of type pcie/X/Y/ where X = domain_nr and -+ * Y = bus_nr. -+ */ -+ i = 0; -+ j = 0; -+ while (i < nvp->nvram_len - BRCMF_FW_NVRAM_PCIEDEV_LEN) { -+ if ((strncmp(&nvp->nvram[i], "pcie/", 5) == 0) && -+ (nvp->nvram[i + 6] == '/') && (nvp->nvram[i + 8] == '/') && -+ ((nvp->nvram[i + 5] - '0') == domain_nr) && -+ ((nvp->nvram[i + 7] - '0') == bus_nr)) { -+ i += BRCMF_FW_NVRAM_PCIEDEV_LEN; -+ while (nvp->nvram[i] != 0) { -+ nvram[j] = nvp->nvram[i]; -+ i++; -+ j++; -+ } -+ nvram[j] = 0; -+ j++; -+ } -+ while (nvp->nvram[i] != 0) -+ i++; -+ i++; -+ } -+ kfree(nvp->nvram); -+ nvp->nvram = nvram; -+ nvp->nvram_len = j; -+ return; -+fail: -+ kfree(nvram); -+ nvp->nvram_len = 0; -+} -+ - /* brcmf_nvram_strip :Takes a buffer of "<var>=<value>\n" lines read from a fil - * and ending in a NUL. Removes carriage returns, empty lines, comment lines, - * 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) -+static void *brcmf_fw_nvram_strip(const struct firmware *nv, u32 *new_length, -+ u16 domain_nr, u16 bus_nr) - { - struct nvram_parser nvp; - u32 pad; -@@ -212,6 +358,16 @@ static void *brcmf_fw_nvram_strip(const - if (nvp.state == END) - break; - } -+ if (nvp.multi_dev_v1) -+ brcmf_fw_strip_multi_v1(&nvp, domain_nr, bus_nr); -+ else if (nvp.multi_dev_v2) -+ brcmf_fw_strip_multi_v2(&nvp, domain_nr, bus_nr); -+ -+ if (nvp.nvram_len == 0) { -+ kfree(nvp.nvram); -+ return NULL; -+ } -+ - pad = nvp.nvram_len; - *new_length = roundup(nvp.nvram_len + 1, 4); - while (pad != *new_length) { -@@ -239,6 +395,8 @@ struct brcmf_fw { - 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); - }; -@@ -254,7 +412,8 @@ 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, &nvram_length, -+ fwctx->domain_nr, fwctx->bus_nr); - release_firmware(fw); - if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL)) - goto fail; -@@ -309,11 +468,12 @@ fail: - kfree(fwctx); - } - --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)) -+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), -+ u16 domain_nr, u16 bus_nr) - { - struct brcmf_fw *fwctx; - -@@ -333,8 +493,21 @@ int brcmf_fw_get_firmwares(struct device - fwctx->done = fw_cb; - if (flags & BRCMF_FW_REQUEST_NVRAM) - fwctx->nvram_name = nvram; -+ fwctx->domain_nr = domain_nr; -+ fwctx->bus_nr = bus_nr; - - return request_firmware_nowait(THIS_MODULE, true, code, dev, - GFP_KERNEL, fwctx, - brcmf_fw_request_code_done); - } -+ -+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)) -+{ -+ return brcmf_fw_get_firmwares_pcie(dev, flags, code, nvram, fw_cb, 0, -+ 0); -+} -+ ---- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.h -+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.h -@@ -32,6 +32,12 @@ void brcmf_fw_nvram_free(void *nvram); - * fails it will not use the callback, but call device_release_driver() - * instead which will call the driver .remove() callback. - */ -+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), -+ 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, ---- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -@@ -1649,8 +1649,13 @@ brcmf_pcie_probe(struct pci_dev *pdev, c - struct brcmf_pciedev_info *devinfo; - struct brcmf_pciedev *pcie_bus_dev; - struct brcmf_bus *bus; -+ u16 domain_nr; -+ u16 bus_nr; - -- brcmf_dbg(PCIE, "Enter %x:%x\n", pdev->vendor, pdev->device); -+ domain_nr = pci_domain_nr(pdev->bus) + 1; -+ bus_nr = pdev->bus->number; -+ brcmf_dbg(PCIE, "Enter %x:%x (%d/%d)\n", pdev->vendor, pdev->device, -+ domain_nr, bus_nr); - - ret = -ENOMEM; - devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL); -@@ -1699,10 +1704,10 @@ brcmf_pcie_probe(struct pci_dev *pdev, c - if (ret) - goto fail_bus; - -- ret = brcmf_fw_get_firmwares(bus->dev, BRCMF_FW_REQUEST_NVRAM | -- BRCMF_FW_REQ_NV_OPTIONAL, -- devinfo->fw_name, devinfo->nvram_name, -- brcmf_pcie_setup); -+ ret = brcmf_fw_get_firmwares_pcie(bus->dev, BRCMF_FW_REQUEST_NVRAM | -+ BRCMF_FW_REQ_NV_OPTIONAL, -+ devinfo->fw_name, devinfo->nvram_name, -+ brcmf_pcie_setup, domain_nr, bus_nr); - if (ret == 0) - return 0; - fail_bus: |