Skip to content

Commit fc17dc4

Browse files
dberlinmarcan
authored andcommitted
[brcmfmac] Finish firmware mem map, fix heap start calculation bug.
This patch fixes the firmware memory map structure to be complete. Along the way, we fix a failure to align the heap memory start address, which causes failures with the newest apple wifi firmware. With this patch, we can load the latest (sonoma 14.0 as of right now) apple wifi firmware. Signed-off-by: Daniel Berlin <[email protected]>
1 parent 3db8b05 commit fc17dc4

1 file changed

Lines changed: 53 additions & 30 deletions

File tree

  • drivers/net/wireless/broadcom/brcm80211/brcmfmac

drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c

Lines changed: 53 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1866,35 +1866,58 @@ struct brcmf_rtlv_footer {
18661866
__le32 magic;
18671867
};
18681868

1869-
struct brcmf_fw_memmap {
1870-
u32 pad1[8];
1871-
u32 vstatus_start;
1872-
u32 vstatus_end;
1873-
u32 fw_start;
1874-
u32 fw_end;
1875-
u32 sig_start;
1876-
u32 sig_end;
1877-
u32 heap_start;
1878-
u32 heap_end;
1879-
u32 pad2[6];
1869+
/** struct brcmf_fw_memmap_region - start/end of memory regions for chip
1870+
*/
1871+
struct brcmf_fw_memmap_region {
1872+
u32 start;
1873+
u32 end;
18801874
};
18811875

1876+
/** struct brcmf_fw_memmap
1877+
*
1878+
* @reset_vec - Reset vector - read only
1879+
* @int_vec - copied from ram, jumps here on success
1880+
* @rom - bootloader at rom start
1881+
* @mmap - struct/memory map written by host
1882+
* @vstatus - verification status
1883+
* @fw - firmware
1884+
* @sig - firwmare signature
1885+
* @heap - region for heap allocations
1886+
* @stack - region for stack allocations
1887+
* @prng - PRNG data, may be 0 length
1888+
* @nvram - NVRAM data
1889+
*/
1890+
struct brcmf_fw_memmap {
1891+
struct brcmf_fw_memmap_region reset_vec;
1892+
struct brcmf_fw_memmap_region int_vec;
1893+
struct brcmf_fw_memmap_region rom;
1894+
struct brcmf_fw_memmap_region mmap;
1895+
struct brcmf_fw_memmap_region vstatus;
1896+
struct brcmf_fw_memmap_region fw;
1897+
struct brcmf_fw_memmap_region sig;
1898+
struct brcmf_fw_memmap_region heap;
1899+
struct brcmf_fw_memmap_region stack;
1900+
struct brcmf_fw_memmap_region prng;
1901+
struct brcmf_fw_memmap_region nvram;
1902+
};
18821903

18831904
#define BRCMF_BL_HEAP_START_GAP 0x1000
18841905
#define BRCMF_BL_HEAP_SIZE 0x10000
18851906
#define BRCMF_RANDOM_SEED_MAGIC 0xfeedc0de
18861907
#define BRCMF_RANDOM_SEED_LENGTH 0x100
1887-
#define BRCMF_SIG_MAGIC 0xfeedfe51
1908+
#define BRCMF_FW_SIG_MAGIC 0xfeedfe51
1909+
#define BRCMF_NVRAM_SIG_MAGIC 0xfeedfe52
1910+
#define BRCMF_MEMMAP_MAGIC 0xfeedfe53
18881911
#define BRCMF_VSTATUS_MAGIC 0xfeedfe54
18891912
#define BRCMF_VSTATUS_SIZE 0x28
1890-
#define BRCMF_MEMMAP_MAGIC 0xfeedfe53
18911913
#define BRCMF_END_MAGIC 0xfeed0e2d
18921914

1893-
static int brcmf_alloc_rtlv(struct brcmf_pciedev_info *devinfo, u32 *address, u32 type, size_t length)
1915+
static int brcmf_alloc_rtlv(struct brcmf_pciedev_info *devinfo, u32 *address, u32 type, u32 length)
18941916
{
18951917
struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev);
1896-
u32 boundary = devinfo->ci->rambase + devinfo->fw_size +
1897-
BRCMF_BL_HEAP_START_GAP + BRCMF_BL_HEAP_SIZE;
1918+
u32 fw_top = devinfo->ci->rambase + devinfo->fw_size;
1919+
u32 ram_start = ALIGN(fw_top + BRCMF_BL_HEAP_START_GAP, 4);
1920+
u32 ram_end = ram_start + BRCMF_BL_HEAP_SIZE;
18981921
u32 start_addr;
18991922
struct brcmf_rtlv_footer footer = {
19001923
.magic = type,
@@ -1903,8 +1926,8 @@ static int brcmf_alloc_rtlv(struct brcmf_pciedev_info *devinfo, u32 *address, u3
19031926
length = ALIGN(length, 4);
19041927
start_addr = *address - length - sizeof(struct brcmf_rtlv_footer);
19051928

1906-
if (length > 0xffff || start_addr > *address || start_addr < boundary) {
1907-
brcmf_err(bus, "failed to allocate 0x%zx bytes for rTLV type 0x%x\n",
1929+
if (length > 0xffff || start_addr > *address || start_addr < ram_end) {
1930+
brcmf_err(bus, "failed to allocate 0x%x bytes for rTLV type 0x%x\n",
19081931
length, type);
19091932
return -ENOMEM;
19101933
}
@@ -1960,32 +1983,32 @@ static int brcmf_pcie_add_signature(struct brcmf_pciedev_info *devinfo,
19601983

19611984
memset(&memmap, 0, sizeof(memmap));
19621985

1963-
memmap.sig_end = *address;
1964-
err = brcmf_alloc_rtlv(devinfo, address, BRCMF_SIG_MAGIC, fwsig->size);
1986+
memmap.sig.end = *address;
1987+
err = brcmf_alloc_rtlv(devinfo, address, BRCMF_FW_SIG_MAGIC, fwsig->size);
19651988
if (err)
19661989
return err;
1967-
memmap.sig_start = *address;
1990+
memmap.sig.start = *address;
19681991

1969-
memmap.vstatus_end = *address;
1992+
memmap.vstatus.end = *address;
19701993
err = brcmf_alloc_rtlv(devinfo, address, BRCMF_VSTATUS_MAGIC, BRCMF_VSTATUS_SIZE);
19711994
if (err)
19721995
return err;
1973-
memmap.vstatus_start = *address;
1996+
memmap.vstatus.start = *address;
19741997

19751998
err = brcmf_alloc_rtlv(devinfo, address, BRCMF_MEMMAP_MAGIC, sizeof(memmap));
19761999
if (err)
19772000
return err;
19782001

1979-
memmap.fw_start = devinfo->ci->rambase;
1980-
memmap.fw_end = memmap.fw_start + devinfo->fw_size;
1981-
memmap.heap_start = memmap.fw_end + BRCMF_BL_HEAP_START_GAP;
1982-
memmap.heap_end = memmap.heap_start + BRCMF_BL_HEAP_SIZE;
2002+
memmap.fw.start = devinfo->ci->rambase;
2003+
memmap.fw.end = memmap.fw.start + devinfo->fw_size;
2004+
memmap.heap.start = ALIGN(memmap.fw.end + BRCMF_BL_HEAP_START_GAP, 4);
2005+
memmap.heap.end = memmap.heap.start + BRCMF_BL_HEAP_SIZE;
19832006

1984-
if (memmap.heap_end > *address)
2007+
if (memmap.heap.end > *address)
19852008
return -ENOMEM;
19862009

1987-
memcpy_toio(devinfo->tcm + memmap.sig_start, fwsig->data, fwsig->size);
1988-
memset_io(devinfo->tcm + memmap.vstatus_start, 0, BRCMF_VSTATUS_SIZE);
2010+
memcpy_toio(devinfo->tcm + memmap.sig.start, fwsig->data, fwsig->size);
2011+
memset_io(devinfo->tcm + memmap.vstatus.start, 0, BRCMF_VSTATUS_SIZE);
19892012
memcpy_toio(devinfo->tcm + *address, &memmap, sizeof(memmap));
19902013

19912014
err = brcmf_alloc_rtlv(devinfo, address, BRCMF_END_MAGIC, 0);

0 commit comments

Comments
 (0)