On 14 April 2015 at 20:10, Arend van Spriel <[email protected]> wrote:
> @@ -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/ */
You most likely know what you're doing, but just for sure: are there
any devices using "pcie/" prefix *without* a devpath? I got an
impression that Broadcom first started using devpath-s and then
(later) started using "pcie/" prefix (instead of "pci/").
> @@ -192,12 +214,136 @@ static int brcmf_init_nvram_parser(struct nvram_parser
> *nvp,
> 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 guess while should also check nvp->nvram_len to avoid crashing with
malformed NVRAM content. Same in _v2 function.
> + 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++;
Same here.
> +/* 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;
> +}
I guess you could consider implementing a one generic function that
will accept sth like a "char *prefix" argument. First check for a
devpathX=$prefix entry and use X: instead of prefix: or not.
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html