Skip to content

Commit 6a20588

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 368b23a commit 6a20588

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
@@ -1864,35 +1864,58 @@ struct brcmf_rtlv_footer {
18641864
__le32 magic;
18651865
};
18661866

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

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

18811902
#define BRCMF_BL_HEAP_START_GAP 0x1000
18821903
#define BRCMF_BL_HEAP_SIZE 0x10000
18831904
#define BRCMF_RANDOM_SEED_MAGIC 0xfeedc0de
18841905
#define BRCMF_RANDOM_SEED_LENGTH 0x100
1885-
#define BRCMF_SIG_MAGIC 0xfeedfe51
1906+
#define BRCMF_FW_SIG_MAGIC 0xfeedfe51
1907+
#define BRCMF_NVRAM_SIG_MAGIC 0xfeedfe52
1908+
#define BRCMF_MEMMAP_MAGIC 0xfeedfe53
18861909
#define BRCMF_VSTATUS_MAGIC 0xfeedfe54
18871910
#define BRCMF_VSTATUS_SIZE 0x28
1888-
#define BRCMF_MEMMAP_MAGIC 0xfeedfe53
18891911
#define BRCMF_END_MAGIC 0xfeed0e2d
18901912

1891-
static int brcmf_alloc_rtlv(struct brcmf_pciedev_info *devinfo, u32 *address, u32 type, size_t length)
1913+
static int brcmf_alloc_rtlv(struct brcmf_pciedev_info *devinfo, u32 *address, u32 type, u32 length)
18921914
{
18931915
struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev);
1894-
u32 boundary = devinfo->ci->rambase + devinfo->fw_size +
1895-
BRCMF_BL_HEAP_START_GAP + BRCMF_BL_HEAP_SIZE;
1916+
u32 fw_top = devinfo->ci->rambase + devinfo->fw_size;
1917+
u32 ram_start = ALIGN(fw_top + BRCMF_BL_HEAP_START_GAP, 4);
1918+
u32 ram_end = ram_start + BRCMF_BL_HEAP_SIZE;
18961919
u32 start_addr;
18971920
struct brcmf_rtlv_footer footer = {
18981921
.magic = type,
@@ -1901,8 +1924,8 @@ static int brcmf_alloc_rtlv(struct brcmf_pciedev_info *devinfo, u32 *address, u3
19011924
length = ALIGN(length, 4);
19021925
start_addr = *address - length - sizeof(struct brcmf_rtlv_footer);
19031926

1904-
if (length > 0xffff || start_addr > *address || start_addr < boundary) {
1905-
brcmf_err(bus, "failed to allocate 0x%zx bytes for rTLV type 0x%x\n",
1927+
if (length > 0xffff || start_addr > *address || start_addr < ram_end) {
1928+
brcmf_err(bus, "failed to allocate 0x%x bytes for rTLV type 0x%x\n",
19061929
length, type);
19071930
return -ENOMEM;
19081931
}
@@ -1953,32 +1976,32 @@ static int brcmf_pcie_add_signature(struct brcmf_pciedev_info *devinfo,
19531976

19541977
memset(&memmap, 0, sizeof(memmap));
19551978

1956-
memmap.sig_end = *address;
1957-
err = brcmf_alloc_rtlv(devinfo, address, BRCMF_SIG_MAGIC, fwsig->size);
1979+
memmap.sig.end = *address;
1980+
err = brcmf_alloc_rtlv(devinfo, address, BRCMF_FW_SIG_MAGIC, fwsig->size);
19581981
if (err)
19591982
return err;
1960-
memmap.sig_start = *address;
1983+
memmap.sig.start = *address;
19611984

1962-
memmap.vstatus_end = *address;
1985+
memmap.vstatus.end = *address;
19631986
err = brcmf_alloc_rtlv(devinfo, address, BRCMF_VSTATUS_MAGIC, BRCMF_VSTATUS_SIZE);
19641987
if (err)
19651988
return err;
1966-
memmap.vstatus_start = *address;
1989+
memmap.vstatus.start = *address;
19671990

19681991
err = brcmf_alloc_rtlv(devinfo, address, BRCMF_MEMMAP_MAGIC, sizeof(memmap));
19691992
if (err)
19701993
return err;
19711994

1972-
memmap.fw_start = devinfo->ci->rambase;
1973-
memmap.fw_end = memmap.fw_start + devinfo->fw_size;
1974-
memmap.heap_start = memmap.fw_end + BRCMF_BL_HEAP_START_GAP;
1975-
memmap.heap_end = memmap.heap_start + BRCMF_BL_HEAP_SIZE;
1995+
memmap.fw.start = devinfo->ci->rambase;
1996+
memmap.fw.end = memmap.fw.start + devinfo->fw_size;
1997+
memmap.heap.start = ALIGN(memmap.fw.end + BRCMF_BL_HEAP_START_GAP, 4);
1998+
memmap.heap.end = memmap.heap.start + BRCMF_BL_HEAP_SIZE;
19761999

1977-
if (memmap.heap_end > *address)
2000+
if (memmap.heap.end > *address)
19782001
return -ENOMEM;
19792002

1980-
memcpy_toio(devinfo->tcm + memmap.sig_start, fwsig->data, fwsig->size);
1981-
memset_io(devinfo->tcm + memmap.vstatus_start, 0, BRCMF_VSTATUS_SIZE);
2003+
memcpy_toio(devinfo->tcm + memmap.sig.start, fwsig->data, fwsig->size);
2004+
memset_io(devinfo->tcm + memmap.vstatus.start, 0, BRCMF_VSTATUS_SIZE);
19822005
memcpy_toio(devinfo->tcm + *address, &memmap, sizeof(memmap));
19832006

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

0 commit comments

Comments
 (0)