Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d610cde3 authored by Franky Lin's avatar Franky Lin Committed by John W. Linville
Browse files

brcmfmac: use firmware data buffer directly for nvram



The nvram file could be parsed directly in the data buffer in the
firmware structure passed by request_firmware function. This patch
gets rid of the redundant memcpy.

Reviewed-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarFranky Lin <frankyl@broadcom.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent c3d2bc35
Loading
Loading
Loading
Loading
+30 −67
Original line number Diff line number Diff line
@@ -3336,39 +3336,6 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen)
	return rxlen ? (int)rxlen : -ETIMEDOUT;
}

static int brcmf_sdbrcm_downloadvars(struct brcmf_sdio *bus, void *arg, int len)
{
	int bcmerror = 0;

	brcmf_dbg(TRACE, "Enter\n");

	/* Basic sanity checks */
	if (bus->sdiodev->bus_if->drvr_up) {
		bcmerror = -EISCONN;
		goto err;
	}
	if (!len) {
		bcmerror = -EOVERFLOW;
		goto err;
	}

	/* Free the old ones and replace with passed variables */
	kfree(bus->vars);

	bus->vars = kmalloc(len, GFP_ATOMIC);
	bus->varsz = bus->vars ? len : 0;
	if (bus->vars == NULL) {
		bcmerror = -ENOMEM;
		goto err;
	}

	/* Copy the passed variables, which should include the
		 terminating double-null */
	memcpy(bus->vars, arg, bus->varsz);
err:
	return bcmerror;
}

static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus)
{
	int bcmerror = 0;
@@ -3573,13 +3540,21 @@ err:
 * by two NULs.
*/

static uint brcmf_process_nvram_vars(char *varbuf, uint len)
static int brcmf_process_nvram_vars(struct brcmf_sdio *bus)
{
	char *varbuf;
	char *dp;
	bool findNewline;
	int column;
	uint buf_len, n;
	int ret = 0;
	uint buf_len, n, len;

	len = bus->firmware->size;
	varbuf = vmalloc(len);
	if (!varbuf)
		return -ENOMEM;

	memcpy(varbuf, bus->firmware->data, len);
	dp = varbuf;

	findNewline = false;
@@ -3608,56 +3583,44 @@ static uint brcmf_process_nvram_vars(char *varbuf, uint len)
		column++;
	}
	buf_len = dp - varbuf;

	while (dp < varbuf + n)
		*dp++ = 0;

	return buf_len;
	kfree(bus->vars);

	bus->varsz = buf_len + 1;
	bus->vars = kmalloc(bus->varsz, GFP_KERNEL);
	if (bus->vars == NULL) {
		bus->varsz = 0;
		ret = -ENOMEM;
		goto err;
	}

	/* copy the processed variables and add null termination */
	memcpy(bus->vars, varbuf, buf_len);
	bus->vars[buf_len] = 0;
err:
	vfree(varbuf);
	return ret;
}

static int brcmf_sdbrcm_download_nvram(struct brcmf_sdio *bus)
{
	uint len;
	char *memblock = NULL;
	char *bufp;
	int ret;

	if (bus->sdiodev->bus_if->drvr_up)
		return -EISCONN;

	ret = request_firmware(&bus->firmware, BRCMF_SDIO_NV_NAME,
			       &bus->sdiodev->func[2]->dev);
	if (ret) {
		brcmf_dbg(ERROR, "Fail to request nvram %d\n", ret);
		return ret;
	}
	bus->fw_ptr = 0;

	memblock = kmalloc(MEMBLOCK, GFP_ATOMIC);
	if (memblock == NULL) {
		ret = -ENOMEM;
		goto err;
	}

	len = brcmf_sdbrcm_get_image(memblock, MEMBLOCK, bus);

	if (len > 0 && len < MEMBLOCK) {
		bufp = (char *)memblock;
		bufp[len] = 0;
		len = brcmf_process_nvram_vars(bufp, len);
		bufp += len;
		*bufp++ = 0;
		if (len)
			ret = brcmf_sdbrcm_downloadvars(bus, memblock, len + 1);
		if (ret)
			brcmf_dbg(ERROR, "error downloading vars: %d\n", ret);
	} else {
		brcmf_dbg(ERROR, "error reading nvram file: %d\n", len);
		ret = -EIO;
	}

err:
	kfree(memblock);
	ret = brcmf_process_nvram_vars(bus);

	release_firmware(bus->firmware);
	bus->fw_ptr = 0;

	return ret;
}