@@ -393,6 +393,7 @@ struct brcmf_pciedev_info {
393393 bool in_irq ;
394394 struct pci_dev * pdev ;
395395 char fw_name [BRCMF_FW_NAME_LEN ];
396+ char sig_name [BRCMF_FW_NAME_LEN ];
396397 char nvram_name [BRCMF_FW_NAME_LEN ];
397398 char clm_name [BRCMF_FW_NAME_LEN ];
398399 char txcap_name [BRCMF_FW_NAME_LEN ];
@@ -401,8 +402,7 @@ struct brcmf_pciedev_info {
401402 const struct brcmf_pcie_reginfo * reginfo ;
402403 void __iomem * regs ;
403404 void __iomem * tcm ;
404- u32 ram_base ;
405- u32 ram_size ;
405+ u32 fw_size ;
406406 struct brcmf_chip * ci ;
407407 u32 coreid ;
408408 struct brcmf_pcie_shared_info shared ;
@@ -1805,17 +1805,169 @@ brcmf_pcie_init_share_ram_info(struct brcmf_pciedev_info *devinfo,
18051805 return 0 ;
18061806}
18071807
1808- struct brcmf_random_seed_footer {
1808+ struct brcmf_rtlv_footer {
18091809 __le32 length ;
18101810 __le32 magic ;
18111811};
18121812
1813+ struct brcmf_fw_memmap {
1814+ u32 pad1 [8 ];
1815+ u32 vstatus_start ;
1816+ u32 vstatus_end ;
1817+ u32 fw_start ;
1818+ u32 fw_end ;
1819+ u32 sig_start ;
1820+ u32 sig_end ;
1821+ u32 heap_start ;
1822+ u32 heap_end ;
1823+ u32 pad2 [6 ];
1824+ };
1825+
1826+
1827+ #define BRCMF_BL_HEAP_START_GAP 0x1000
1828+ #define BRCMF_BL_HEAP_SIZE 0x10000
18131829#define BRCMF_RANDOM_SEED_MAGIC 0xfeedc0de
18141830#define BRCMF_RANDOM_SEED_LENGTH 0x100
1831+ #define BRCMF_SIG_MAGIC 0xfeedfe51
1832+ #define BRCMF_VSTATUS_MAGIC 0xfeedfe54
1833+ #define BRCMF_VSTATUS_SIZE 0x28
1834+ #define BRCMF_MEMMAP_MAGIC 0xfeedfe53
1835+ #define BRCMF_END_MAGIC 0xfeed0e2d
1836+
1837+ static int brcmf_alloc_rtlv (struct brcmf_pciedev_info * devinfo , u32 * address , u32 type , size_t length )
1838+ {
1839+ struct brcmf_bus * bus = dev_get_drvdata (& devinfo -> pdev -> dev );
1840+ u32 boundary = devinfo -> ci -> rambase + devinfo -> fw_size +
1841+ BRCMF_BL_HEAP_START_GAP + BRCMF_BL_HEAP_SIZE ;
1842+ u32 start_addr ;
1843+ struct brcmf_rtlv_footer footer = {
1844+ .magic = type ,
1845+ };
1846+
1847+ length = ALIGN (length , 4 );
1848+ start_addr = * address - length - sizeof (struct brcmf_rtlv_footer );
1849+
1850+ if (length > 0xffff || start_addr > * address || start_addr < boundary ) {
1851+ brcmf_err (bus , "failed to allocate 0x%zx bytes for rTLV type 0x%x\n" ,
1852+ length , type );
1853+ return - ENOMEM ;
1854+ }
1855+
1856+ /* Random seed does not use the length check code */
1857+ if (type == BRCMF_RANDOM_SEED_MAGIC )
1858+ footer .length = length ;
1859+ else
1860+ footer .length = length | ((length ^ 0xffff ) << 16 );
1861+
1862+ memcpy_toio (devinfo -> tcm + * address - sizeof (struct brcmf_rtlv_footer ),
1863+ & footer , sizeof (struct brcmf_rtlv_footer ));
1864+
1865+ * address = start_addr ;
1866+
1867+ return 0 ;
1868+ }
1869+
1870+ static int brcmf_pcie_add_random_seed (struct brcmf_pciedev_info * devinfo ,
1871+ u32 * address )
1872+ {
1873+ int err ;
1874+ void * randbuf ;
1875+
1876+ err = brcmf_alloc_rtlv (devinfo , address ,
1877+ BRCMF_RANDOM_SEED_MAGIC , BRCMF_RANDOM_SEED_LENGTH );
1878+ if (err )
1879+ return err ;
1880+
1881+ /* Some Apple chips/firmwares expect a buffer of random
1882+ * data to be present before NVRAM
1883+ */
1884+ brcmf_dbg (PCIE , "Download random seed\n" );
1885+
1886+ randbuf = kzalloc (BRCMF_RANDOM_SEED_LENGTH , GFP_KERNEL );
1887+ if (!randbuf )
1888+ return - ENOMEM ;
1889+
1890+ get_random_bytes (randbuf , BRCMF_RANDOM_SEED_LENGTH );
1891+ memcpy_toio (devinfo -> tcm + * address , randbuf , BRCMF_RANDOM_SEED_LENGTH );
1892+ kfree (randbuf );
1893+
1894+ return 0 ;
1895+ }
1896+
1897+ static int brcmf_pcie_add_signature (struct brcmf_pciedev_info * devinfo ,
1898+ u32 * address , const struct firmware * fwsig )
1899+ {
1900+ int err ;
1901+ struct brcmf_fw_memmap memmap ;
1902+
1903+ brcmf_dbg (PCIE , "Download firmware signature\n" );
1904+
1905+ memset (& memmap , 0 , sizeof (memmap ));
1906+
1907+ memmap .sig_end = * address ;
1908+ err = brcmf_alloc_rtlv (devinfo , address , BRCMF_SIG_MAGIC , fwsig -> size );
1909+ if (err )
1910+ return err ;
1911+ memmap .sig_start = * address ;
1912+
1913+ memmap .vstatus_end = * address ;
1914+ err = brcmf_alloc_rtlv (devinfo , address , BRCMF_VSTATUS_MAGIC , BRCMF_VSTATUS_SIZE );
1915+ if (err )
1916+ return err ;
1917+ memmap .vstatus_start = * address ;
1918+
1919+ err = brcmf_alloc_rtlv (devinfo , address , BRCMF_MEMMAP_MAGIC , sizeof (memmap ));
1920+ if (err )
1921+ return err ;
1922+
1923+ memmap .fw_start = devinfo -> ci -> rambase ;
1924+ memmap .fw_end = memmap .fw_start + devinfo -> fw_size ;
1925+ memmap .heap_start = memmap .fw_end + BRCMF_BL_HEAP_START_GAP ;
1926+ memmap .heap_end = memmap .heap_start + BRCMF_BL_HEAP_SIZE ;
1927+
1928+ if (memmap .heap_end > * address )
1929+ return - ENOMEM ;
1930+
1931+ memcpy_toio (devinfo -> tcm + memmap .sig_start , fwsig -> data , fwsig -> size );
1932+ memset_io (devinfo -> tcm + memmap .vstatus_start , 0 , BRCMF_VSTATUS_SIZE );
1933+ memcpy_toio (devinfo -> tcm + * address , & memmap , sizeof (memmap ));
1934+
1935+ err = brcmf_alloc_rtlv (devinfo , address , BRCMF_END_MAGIC , 0 );
1936+ if (err )
1937+ return err ;
1938+
1939+ return 0 ;
1940+ }
1941+
1942+ static int brcmf_pcie_populate_footers (struct brcmf_pciedev_info * devinfo ,
1943+ u32 * address , const struct firmware * fwsig )
1944+ {
1945+ int err ;
1946+
1947+ /* We only do this for Apple firmwares. If any other
1948+ * production firmwares are found to need this, the condition
1949+ * needs to be adjusted.
1950+ */
1951+ if (!devinfo -> otp .valid )
1952+ return 0 ;
1953+
1954+ err = brcmf_pcie_add_random_seed (devinfo , address );
1955+ if (err )
1956+ return err ;
1957+
1958+ if (fwsig ) {
1959+ err = brcmf_pcie_add_signature (devinfo , address , fwsig );
1960+ if (err )
1961+ return err ;
1962+ }
1963+
1964+ return 0 ;
1965+ }
18151966
18161967static int brcmf_pcie_download_fw_nvram (struct brcmf_pciedev_info * devinfo ,
1817- const struct firmware * fw , void * nvram ,
1818- u32 nvram_len )
1968+ const struct firmware * fw ,
1969+ const struct firmware * fwsig ,
1970+ void * nvram , u32 nvram_len )
18191971{
18201972 struct brcmf_bus * bus = dev_get_drvdata (& devinfo -> pdev -> dev );
18211973 u32 sharedram_addr ;
@@ -1835,6 +1987,7 @@ static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo,
18351987 (void * )fw -> data , fw -> size );
18361988
18371989 resetintr = get_unaligned_le32 (fw -> data );
1990+ devinfo -> fw_size = fw -> size ;
18381991 release_firmware (fw );
18391992
18401993 /* reset last 4 bytes of RAM address. to be used for shared
@@ -1849,34 +2002,23 @@ static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo,
18492002 memcpy_toio (devinfo -> tcm + address , nvram , nvram_len );
18502003 brcmf_fw_nvram_free (nvram );
18512004
1852- if (devinfo -> otp .valid ) {
1853- size_t rand_len = BRCMF_RANDOM_SEED_LENGTH ;
1854- struct brcmf_random_seed_footer footer = {
1855- .length = cpu_to_le32 (rand_len ),
1856- .magic = cpu_to_le32 (BRCMF_RANDOM_SEED_MAGIC ),
1857- };
1858- void * randbuf ;
1859-
1860- /* Some Apple chips/firmwares expect a buffer of random
1861- * data to be present before NVRAM
1862- */
1863- brcmf_dbg (PCIE , "Download random seed\n" );
1864-
1865- address -= sizeof (footer );
1866- memcpy_toio (devinfo -> tcm + address , & footer ,
1867- sizeof (footer ));
1868-
1869- address -= rand_len ;
1870- randbuf = kzalloc (rand_len , GFP_KERNEL );
1871- get_random_bytes (randbuf , rand_len );
1872- memcpy_toio (devinfo -> tcm + address , randbuf , rand_len );
1873- kfree (randbuf );
1874- }
2005+ err = brcmf_pcie_populate_footers (devinfo , & address , fwsig );
2006+ if (err )
2007+ brcmf_err (bus , "failed to populate firmware footers err=%d\n" , err );
18752008 } else {
18762009 brcmf_dbg (PCIE , "No matching NVRAM file found %s\n" ,
18772010 devinfo -> nvram_name );
18782011 }
18792012
2013+ release_firmware (fwsig );
2014+
2015+ /* Clear free TCM. This isn't really necessary, but it
2016+ * makes debugging memory dumps a lot easier since we
2017+ * don't get a bunch of junk filling up the free space.
2018+ */
2019+ memset_io (devinfo -> tcm + devinfo -> ci -> rambase + devinfo -> fw_size ,
2020+ 0 , address - devinfo -> fw_size - devinfo -> ci -> rambase );
2021+
18802022 sharedram_addr_written = brcmf_pcie_read_ram32 (devinfo ,
18812023 devinfo -> ci -> ramsize -
18822024 4 );
@@ -2262,11 +2404,12 @@ static int brcmf_pcie_read_otp(struct brcmf_pciedev_info *devinfo)
22622404#define BRCMF_PCIE_FW_NVRAM 1
22632405#define BRCMF_PCIE_FW_CLM 2
22642406#define BRCMF_PCIE_FW_TXCAP 3
2407+ #define BRCMF_PCIE_FW_SIG 4
22652408
22662409static void brcmf_pcie_setup (struct device * dev , int ret ,
22672410 struct brcmf_fw_request * fwreq )
22682411{
2269- const struct firmware * fw ;
2412+ const struct firmware * fw , * fwsig ;
22702413 void * nvram ;
22712414 struct brcmf_bus * bus ;
22722415 struct brcmf_pciedev * pcie_bus_dev ;
@@ -2285,6 +2428,7 @@ static void brcmf_pcie_setup(struct device *dev, int ret,
22852428 brcmf_pcie_attach (devinfo );
22862429
22872430 fw = fwreq -> items [BRCMF_PCIE_FW_CODE ].binary ;
2431+ fwsig = fwreq -> items [BRCMF_PCIE_FW_SIG ].binary ;
22882432 nvram = fwreq -> items [BRCMF_PCIE_FW_NVRAM ].nv_data .data ;
22892433 nvram_len = fwreq -> items [BRCMF_PCIE_FW_NVRAM ].nv_data .len ;
22902434 devinfo -> clm_fw = fwreq -> items [BRCMF_PCIE_FW_CLM ].binary ;
@@ -2295,6 +2439,7 @@ static void brcmf_pcie_setup(struct device *dev, int ret,
22952439 if (ret ) {
22962440 brcmf_err (bus , "Failed to get RAM info\n" );
22972441 release_firmware (fw );
2442+ release_firmware (fwsig );
22982443 brcmf_fw_nvram_free (nvram );
22992444 goto fail ;
23002445 }
@@ -2306,7 +2451,7 @@ static void brcmf_pcie_setup(struct device *dev, int ret,
23062451 */
23072452 brcmf_pcie_adjust_ramsize (devinfo , (u8 * )fw -> data , fw -> size );
23082453
2309- ret = brcmf_pcie_download_fw_nvram (devinfo , fw , nvram , nvram_len );
2454+ ret = brcmf_pcie_download_fw_nvram (devinfo , fw , fwsig , nvram , nvram_len );
23102455 if (ret )
23112456 goto fail ;
23122457
@@ -2371,6 +2516,7 @@ brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo)
23712516 { ".txt" , devinfo -> nvram_name },
23722517 { ".clm_blob" , devinfo -> clm_name },
23732518 { ".txcap_blob" , devinfo -> txcap_name },
2519+ { ".sig" , devinfo -> sig_name },
23742520 };
23752521
23762522 fwreq = brcmf_fw_alloc_request (devinfo -> ci -> chip , devinfo -> ci -> chiprev ,
@@ -2381,6 +2527,8 @@ brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo)
23812527 return NULL ;
23822528
23832529 fwreq -> items [BRCMF_PCIE_FW_CODE ].type = BRCMF_FW_TYPE_BINARY ;
2530+ fwreq -> items [BRCMF_PCIE_FW_SIG ].type = BRCMF_FW_TYPE_BINARY ;
2531+ fwreq -> items [BRCMF_PCIE_FW_SIG ].flags = BRCMF_FW_REQF_OPTIONAL ;
23842532 fwreq -> items [BRCMF_PCIE_FW_NVRAM ].type = BRCMF_FW_TYPE_NVRAM ;
23852533 fwreq -> items [BRCMF_PCIE_FW_NVRAM ].flags = BRCMF_FW_REQF_OPTIONAL ;
23862534 fwreq -> items [BRCMF_PCIE_FW_CLM ].type = BRCMF_FW_TYPE_BINARY ;
0 commit comments