mirror of
https://github.com/torvalds/linux
synced 2024-10-27 13:48:49 +00:00
brcmfmac: reduce allocations needed during nvram data download
The nvram data is preprocessed before being sent to the device and just before sending an additional allocation was done that assured word alignment of the data. This has moved to the preprocessing step to reduce allocations and subsequent copying of the nvram data. Reviewed-by: Franky Lin <frankyl@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
d610cde30b
commit
6d4ef68086
|
@ -3339,9 +3339,7 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen)
|
||||||
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;
|
||||||
u32 varsize;
|
|
||||||
u32 varaddr;
|
u32 varaddr;
|
||||||
u8 *vbuffer;
|
|
||||||
u32 varsizew;
|
u32 varsizew;
|
||||||
__le32 varsizew_le;
|
__le32 varsizew_le;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -3350,56 +3348,44 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus)
|
||||||
|
|
||||||
/* Even if there are no vars are to be written, we still
|
/* Even if there are no vars are to be written, we still
|
||||||
need to set the ramsize. */
|
need to set the ramsize. */
|
||||||
varsize = bus->varsz ? roundup(bus->varsz, 4) : 0;
|
varaddr = (bus->ramsize - 4) - bus->varsz;
|
||||||
varaddr = (bus->ramsize - 4) - varsize;
|
|
||||||
|
|
||||||
if (bus->vars) {
|
if (bus->vars) {
|
||||||
vbuffer = kzalloc(varsize, GFP_ATOMIC);
|
|
||||||
if (!vbuffer)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
memcpy(vbuffer, bus->vars, bus->varsz);
|
|
||||||
|
|
||||||
/* Write the vars list */
|
/* Write the vars list */
|
||||||
bcmerror =
|
bcmerror = brcmf_sdbrcm_membytes(bus, true, varaddr,
|
||||||
brcmf_sdbrcm_membytes(bus, true, varaddr, vbuffer, varsize);
|
bus->vars, bus->varsz);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
/* Verify NVRAM bytes */
|
/* Verify NVRAM bytes */
|
||||||
brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n", varsize);
|
brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n",
|
||||||
nvram_ularray = kmalloc(varsize, GFP_ATOMIC);
|
bus->varsz);
|
||||||
if (!nvram_ularray) {
|
nvram_ularray = kmalloc(bus->varsz, GFP_ATOMIC);
|
||||||
kfree(vbuffer);
|
if (!nvram_ularray)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
|
||||||
|
|
||||||
/* Upload image to verify downloaded contents. */
|
/* Upload image to verify downloaded contents. */
|
||||||
memset(nvram_ularray, 0xaa, varsize);
|
memset(nvram_ularray, 0xaa, bus->varsz);
|
||||||
|
|
||||||
/* Read the vars list to temp buffer for comparison */
|
/* Read the vars list to temp buffer for comparison */
|
||||||
bcmerror =
|
bcmerror = brcmf_sdbrcm_membytes(bus, false, varaddr,
|
||||||
brcmf_sdbrcm_membytes(bus, false, varaddr, nvram_ularray,
|
nvram_ularray, bus->varsz);
|
||||||
varsize);
|
|
||||||
if (bcmerror) {
|
if (bcmerror) {
|
||||||
brcmf_dbg(ERROR, "error %d on reading %d nvram bytes at 0x%08x\n",
|
brcmf_dbg(ERROR, "error %d on reading %d nvram bytes at 0x%08x\n",
|
||||||
bcmerror, varsize, varaddr);
|
bcmerror, bus->varsz, varaddr);
|
||||||
}
|
}
|
||||||
/* Compare the org NVRAM with the one read from RAM */
|
/* Compare the org NVRAM with the one read from RAM */
|
||||||
if (memcmp(vbuffer, nvram_ularray, varsize))
|
if (memcmp(bus->vars, nvram_ularray, bus->varsz))
|
||||||
brcmf_dbg(ERROR, "Downloaded NVRAM image is corrupted\n");
|
brcmf_dbg(ERROR, "Downloaded NVRAM image is corrupted\n");
|
||||||
else
|
else
|
||||||
brcmf_dbg(ERROR, "Download/Upload/Compare of NVRAM ok\n");
|
brcmf_dbg(ERROR, "Download/Upload/Compare of NVRAM ok\n");
|
||||||
|
|
||||||
kfree(nvram_ularray);
|
kfree(nvram_ularray);
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
kfree(vbuffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* adjust to the user specified RAM */
|
/* adjust to the user specified RAM */
|
||||||
brcmf_dbg(INFO, "Physical memory size: %d\n", bus->ramsize);
|
brcmf_dbg(INFO, "Physical memory size: %d\n", bus->ramsize);
|
||||||
brcmf_dbg(INFO, "Vars are at %d, orig varsize is %d\n",
|
brcmf_dbg(INFO, "Vars are at %d, orig varsize is %d\n",
|
||||||
varaddr, varsize);
|
varaddr, bus->varsz);
|
||||||
varsize = ((bus->ramsize - 4) - varaddr);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine the length token:
|
* Determine the length token:
|
||||||
|
@ -3410,13 +3396,13 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus)
|
||||||
varsizew = 0;
|
varsizew = 0;
|
||||||
varsizew_le = cpu_to_le32(0);
|
varsizew_le = cpu_to_le32(0);
|
||||||
} else {
|
} else {
|
||||||
varsizew = varsize / 4;
|
varsizew = bus->varsz / 4;
|
||||||
varsizew = (~varsizew << 16) | (varsizew & 0x0000FFFF);
|
varsizew = (~varsizew << 16) | (varsizew & 0x0000FFFF);
|
||||||
varsizew_le = cpu_to_le32(varsizew);
|
varsizew_le = cpu_to_le32(varsizew);
|
||||||
}
|
}
|
||||||
|
|
||||||
brcmf_dbg(INFO, "New varsize is %d, length token=0x%08x\n",
|
brcmf_dbg(INFO, "New varsize is %d, length token=0x%08x\n",
|
||||||
varsize, varsizew);
|
bus->varsz, varsizew);
|
||||||
|
|
||||||
/* Write the length token to the last word */
|
/* Write the length token to the last word */
|
||||||
bcmerror = brcmf_sdbrcm_membytes(bus, true, (bus->ramsize - 4),
|
bcmerror = brcmf_sdbrcm_membytes(bus, true, (bus->ramsize - 4),
|
||||||
|
@ -3587,8 +3573,8 @@ static int brcmf_process_nvram_vars(struct brcmf_sdio *bus)
|
||||||
*dp++ = 0;
|
*dp++ = 0;
|
||||||
|
|
||||||
kfree(bus->vars);
|
kfree(bus->vars);
|
||||||
|
/* roundup needed for download to device */
|
||||||
bus->varsz = buf_len + 1;
|
bus->varsz = roundup(buf_len + 1, 4);
|
||||||
bus->vars = kmalloc(bus->varsz, GFP_KERNEL);
|
bus->vars = kmalloc(bus->varsz, GFP_KERNEL);
|
||||||
if (bus->vars == NULL) {
|
if (bus->vars == NULL) {
|
||||||
bus->varsz = 0;
|
bus->varsz = 0;
|
||||||
|
|
Loading…
Reference in a new issue