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: Arend van Spriel <arend@broadcom.com> Signed-off-by: Franky Lin <frankyl@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
committed by
John W. Linville
parent
c3d2bc35e5
commit
d610cde30b
@@ -3336,39 +3336,6 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen)
|
|||||||
return rxlen ? (int)rxlen : -ETIMEDOUT;
|
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)
|
static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus)
|
||||||
{
|
{
|
||||||
int bcmerror = 0;
|
int bcmerror = 0;
|
||||||
@@ -3573,13 +3540,21 @@ err:
|
|||||||
* by two NULs.
|
* 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;
|
char *dp;
|
||||||
bool findNewline;
|
bool findNewline;
|
||||||
int column;
|
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;
|
dp = varbuf;
|
||||||
|
|
||||||
findNewline = false;
|
findNewline = false;
|
||||||
@@ -3608,56 +3583,44 @@ static uint brcmf_process_nvram_vars(char *varbuf, uint len)
|
|||||||
column++;
|
column++;
|
||||||
}
|
}
|
||||||
buf_len = dp - varbuf;
|
buf_len = dp - varbuf;
|
||||||
|
|
||||||
while (dp < varbuf + n)
|
while (dp < varbuf + n)
|
||||||
*dp++ = 0;
|
*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)
|
static int brcmf_sdbrcm_download_nvram(struct brcmf_sdio *bus)
|
||||||
{
|
{
|
||||||
uint len;
|
|
||||||
char *memblock = NULL;
|
|
||||||
char *bufp;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (bus->sdiodev->bus_if->drvr_up)
|
||||||
|
return -EISCONN;
|
||||||
|
|
||||||
ret = request_firmware(&bus->firmware, BRCMF_SDIO_NV_NAME,
|
ret = request_firmware(&bus->firmware, BRCMF_SDIO_NV_NAME,
|
||||||
&bus->sdiodev->func[2]->dev);
|
&bus->sdiodev->func[2]->dev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
brcmf_dbg(ERROR, "Fail to request nvram %d\n", ret);
|
brcmf_dbg(ERROR, "Fail to request nvram %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
bus->fw_ptr = 0;
|
|
||||||
|
|
||||||
memblock = kmalloc(MEMBLOCK, GFP_ATOMIC);
|
ret = brcmf_process_nvram_vars(bus);
|
||||||
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);
|
|
||||||
|
|
||||||
release_firmware(bus->firmware);
|
release_firmware(bus->firmware);
|
||||||
bus->fw_ptr = 0;
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user