Skip to content

Commit dbe23a8

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 17bd762 commit dbe23a8

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
@@ -1861,35 +1861,58 @@ struct brcmf_rtlv_footer {
18611861
__le32 magic;
18621862
};
18631863

1864-
struct brcmf_fw_memmap {
1865-
u32 pad1[8];
1866-
u32 vstatus_start;
1867-
u32 vstatus_end;
1868-
u32 fw_start;
1869-
u32 fw_end;
1870-
u32 sig_start;
1871-
u32 sig_end;
1872-
u32 heap_start;
1873-
u32 heap_end;
1874-
u32 pad2[6];
1864+
/** struct brcmf_fw_memmap_region - start/end of memory regions for chip
1865+
*/
1866+
struct brcmf_fw_memmap_region {
1867+
u32 start;
1868+
u32 end;
18751869
};
18761870

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

18781899
#define BRCMF_BL_HEAP_START_GAP 0x1000
18791900
#define BRCMF_BL_HEAP_SIZE 0x10000
18801901
#define BRCMF_RANDOM_SEED_MAGIC 0xfeedc0de
18811902
#define BRCMF_RANDOM_SEED_LENGTH 0x100
1882-
#define BRCMF_SIG_MAGIC 0xfeedfe51
1903+
#define BRCMF_FW_SIG_MAGIC 0xfeedfe51
1904+
#define BRCMF_NVRAM_SIG_MAGIC 0xfeedfe52
1905+
#define BRCMF_MEMMAP_MAGIC 0xfeedfe53
18831906
#define BRCMF_VSTATUS_MAGIC 0xfeedfe54
18841907
#define BRCMF_VSTATUS_SIZE 0x28
1885-
#define BRCMF_MEMMAP_MAGIC 0xfeedfe53
18861908
#define BRCMF_END_MAGIC 0xfeed0e2d
18871909

1888-
static int brcmf_alloc_rtlv(struct brcmf_pciedev_info *devinfo, u32 *address, u32 type, size_t length)
1910+
static int brcmf_alloc_rtlv(struct brcmf_pciedev_info *devinfo, u32 *address, u32 type, u32 length)
18891911
{
18901912
struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev);
1891-
u32 boundary = devinfo->ci->rambase + devinfo->fw_size +
1892-
BRCMF_BL_HEAP_START_GAP + BRCMF_BL_HEAP_SIZE;
1913+
u32 fw_top = devinfo->ci->rambase + devinfo->fw_size;
1914+
u32 ram_start = ALIGN(fw_top + BRCMF_BL_HEAP_START_GAP, 4);
1915+
u32 ram_end = ram_start + BRCMF_BL_HEAP_SIZE;
18931916
u32 start_addr;
18941917
struct brcmf_rtlv_footer footer = {
18951918
.magic = type,
@@ -1898,8 +1921,8 @@ static int brcmf_alloc_rtlv(struct brcmf_pciedev_info *devinfo, u32 *address, u3
18981921
length = ALIGN(length, 4);
18991922
start_addr = *address - length - sizeof(struct brcmf_rtlv_footer);
19001923

1901-
if (length > 0xffff || start_addr > *address || start_addr < boundary) {
1902-
brcmf_err(bus, "failed to allocate 0x%zx bytes for rTLV type 0x%x\n",
1924+
if (length > 0xffff || start_addr > *address || start_addr < ram_end) {
1925+
brcmf_err(bus, "failed to allocate 0x%x bytes for rTLV type 0x%x\n",
19031926
length, type);
19041927
return -ENOMEM;
19051928
}
@@ -1950,32 +1973,32 @@ static int brcmf_pcie_add_signature(struct brcmf_pciedev_info *devinfo,
19501973

19511974
memset(&memmap, 0, sizeof(memmap));
19521975

1953-
memmap.sig_end = *address;
1954-
err = brcmf_alloc_rtlv(devinfo, address, BRCMF_SIG_MAGIC, fwsig->size);
1976+
memmap.sig.end = *address;
1977+
err = brcmf_alloc_rtlv(devinfo, address, BRCMF_FW_SIG_MAGIC, fwsig->size);
19551978
if (err)
19561979
return err;
1957-
memmap.sig_start = *address;
1980+
memmap.sig.start = *address;
19581981

1959-
memmap.vstatus_end = *address;
1982+
memmap.vstatus.end = *address;
19601983
err = brcmf_alloc_rtlv(devinfo, address, BRCMF_VSTATUS_MAGIC, BRCMF_VSTATUS_SIZE);
19611984
if (err)
19621985
return err;
1963-
memmap.vstatus_start = *address;
1986+
memmap.vstatus.start = *address;
19641987

19651988
err = brcmf_alloc_rtlv(devinfo, address, BRCMF_MEMMAP_MAGIC, sizeof(memmap));
19661989
if (err)
19671990
return err;
19681991

1969-
memmap.fw_start = devinfo->ci->rambase;
1970-
memmap.fw_end = memmap.fw_start + devinfo->fw_size;
1971-
memmap.heap_start = memmap.fw_end + BRCMF_BL_HEAP_START_GAP;
1972-
memmap.heap_end = memmap.heap_start + BRCMF_BL_HEAP_SIZE;
1992+
memmap.fw.start = devinfo->ci->rambase;
1993+
memmap.fw.end = memmap.fw.start + devinfo->fw_size;
1994+
memmap.heap.start = ALIGN(memmap.fw.end + BRCMF_BL_HEAP_START_GAP, 4);
1995+
memmap.heap.end = memmap.heap.start + BRCMF_BL_HEAP_SIZE;
19731996

1974-
if (memmap.heap_end > *address)
1997+
if (memmap.heap.end > *address)
19751998
return -ENOMEM;
19761999

1977-
memcpy_toio(devinfo->tcm + memmap.sig_start, fwsig->data, fwsig->size);
1978-
memset_io(devinfo->tcm + memmap.vstatus_start, 0, BRCMF_VSTATUS_SIZE);
2000+
memcpy_toio(devinfo->tcm + memmap.sig.start, fwsig->data, fwsig->size);
2001+
memset_io(devinfo->tcm + memmap.vstatus.start, 0, BRCMF_VSTATUS_SIZE);
19792002
memcpy_toio(devinfo->tcm + *address, &memmap, sizeof(memmap));
19802003

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

0 commit comments

Comments
 (0)