Skip to content

Commit ab0042e

Browse files
dberlinjannau
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 <dberlin@dberlin.org>
1 parent f617b5f commit ab0042e

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
@@ -1868,35 +1868,58 @@ struct brcmf_rtlv_footer {
18681868
__le32 magic;
18691869
};
18701870

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

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

18851906
#define BRCMF_BL_HEAP_START_GAP 0x1000
18861907
#define BRCMF_BL_HEAP_SIZE 0x10000
18871908
#define BRCMF_RANDOM_SEED_MAGIC 0xfeedc0de
18881909
#define BRCMF_RANDOM_SEED_LENGTH 0x100
1889-
#define BRCMF_SIG_MAGIC 0xfeedfe51
1910+
#define BRCMF_FW_SIG_MAGIC 0xfeedfe51
1911+
#define BRCMF_NVRAM_SIG_MAGIC 0xfeedfe52
1912+
#define BRCMF_MEMMAP_MAGIC 0xfeedfe53
18901913
#define BRCMF_VSTATUS_MAGIC 0xfeedfe54
18911914
#define BRCMF_VSTATUS_SIZE 0x28
1892-
#define BRCMF_MEMMAP_MAGIC 0xfeedfe53
18931915
#define BRCMF_END_MAGIC 0xfeed0e2d
18941916

1895-
static int brcmf_alloc_rtlv(struct brcmf_pciedev_info *devinfo, u32 *address, u32 type, size_t length)
1917+
static int brcmf_alloc_rtlv(struct brcmf_pciedev_info *devinfo, u32 *address, u32 type, u32 length)
18961918
{
18971919
struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev);
1898-
u32 boundary = devinfo->ci->rambase + devinfo->fw_size +
1899-
BRCMF_BL_HEAP_START_GAP + BRCMF_BL_HEAP_SIZE;
1920+
u32 fw_top = devinfo->ci->rambase + devinfo->fw_size;
1921+
u32 ram_start = ALIGN(fw_top + BRCMF_BL_HEAP_START_GAP, 4);
1922+
u32 ram_end = ram_start + BRCMF_BL_HEAP_SIZE;
19001923
u32 start_addr;
19011924
struct brcmf_rtlv_footer footer = {
19021925
.magic = type,
@@ -1905,8 +1928,8 @@ static int brcmf_alloc_rtlv(struct brcmf_pciedev_info *devinfo, u32 *address, u3
19051928
length = ALIGN(length, 4);
19061929
start_addr = *address - length - sizeof(struct brcmf_rtlv_footer);
19071930

1908-
if (length > 0xffff || start_addr > *address || start_addr < boundary) {
1909-
brcmf_err(bus, "failed to allocate 0x%zx bytes for rTLV type 0x%x\n",
1931+
if (length > 0xffff || start_addr > *address || start_addr < ram_end) {
1932+
brcmf_err(bus, "failed to allocate 0x%x bytes for rTLV type 0x%x\n",
19101933
length, type);
19111934
return -ENOMEM;
19121935
}
@@ -1957,32 +1980,32 @@ static int brcmf_pcie_add_signature(struct brcmf_pciedev_info *devinfo,
19571980

19581981
memset(&memmap, 0, sizeof(memmap));
19591982

1960-
memmap.sig_end = *address;
1961-
err = brcmf_alloc_rtlv(devinfo, address, BRCMF_SIG_MAGIC, fwsig->size);
1983+
memmap.sig.end = *address;
1984+
err = brcmf_alloc_rtlv(devinfo, address, BRCMF_FW_SIG_MAGIC, fwsig->size);
19621985
if (err)
19631986
return err;
1964-
memmap.sig_start = *address;
1987+
memmap.sig.start = *address;
19651988

1966-
memmap.vstatus_end = *address;
1989+
memmap.vstatus.end = *address;
19671990
err = brcmf_alloc_rtlv(devinfo, address, BRCMF_VSTATUS_MAGIC, BRCMF_VSTATUS_SIZE);
19681991
if (err)
19691992
return err;
1970-
memmap.vstatus_start = *address;
1993+
memmap.vstatus.start = *address;
19711994

19721995
err = brcmf_alloc_rtlv(devinfo, address, BRCMF_MEMMAP_MAGIC, sizeof(memmap));
19731996
if (err)
19741997
return err;
19751998

1976-
memmap.fw_start = devinfo->ci->rambase;
1977-
memmap.fw_end = memmap.fw_start + devinfo->fw_size;
1978-
memmap.heap_start = memmap.fw_end + BRCMF_BL_HEAP_START_GAP;
1979-
memmap.heap_end = memmap.heap_start + BRCMF_BL_HEAP_SIZE;
1999+
memmap.fw.start = devinfo->ci->rambase;
2000+
memmap.fw.end = memmap.fw.start + devinfo->fw_size;
2001+
memmap.heap.start = ALIGN(memmap.fw.end + BRCMF_BL_HEAP_START_GAP, 4);
2002+
memmap.heap.end = memmap.heap.start + BRCMF_BL_HEAP_SIZE;
19802003

1981-
if (memmap.heap_end > *address)
2004+
if (memmap.heap.end > *address)
19822005
return -ENOMEM;
19832006

1984-
memcpy_toio(devinfo->tcm + memmap.sig_start, fwsig->data, fwsig->size);
1985-
memset_io(devinfo->tcm + memmap.vstatus_start, 0, BRCMF_VSTATUS_SIZE);
2007+
memcpy_toio(devinfo->tcm + memmap.sig.start, fwsig->data, fwsig->size);
2008+
memset_io(devinfo->tcm + memmap.vstatus.start, 0, BRCMF_VSTATUS_SIZE);
19862009
memcpy_toio(devinfo->tcm + *address, &memmap, sizeof(memmap));
19872010

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

0 commit comments

Comments
 (0)