@@ -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,26 +1805,164 @@ 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+ }
18151869
1816- static noinline_for_stack void
1817- brcmf_pcie_provide_random_bytes (struct brcmf_pciedev_info * devinfo , u32 address )
1870+ static noinline_for_stack int
1871+ brcmf_pcie_add_random_seed (struct brcmf_pciedev_info * devinfo , u32 * address )
18181872{
1873+ int err ;
18191874 u8 randbuf [BRCMF_RANDOM_SEED_LENGTH ];
18201875
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+
18211886 get_random_bytes (randbuf , BRCMF_RANDOM_SEED_LENGTH );
18221887 memcpy_toio (devinfo -> tcm + address , randbuf , BRCMF_RANDOM_SEED_LENGTH );
1888+
1889+ return 0 ;
1890+ }
1891+
1892+ static int brcmf_pcie_add_signature (struct brcmf_pciedev_info * devinfo ,
1893+ u32 * address , const struct firmware * fwsig )
1894+ {
1895+ int err ;
1896+ struct brcmf_fw_memmap memmap ;
1897+
1898+ brcmf_dbg (PCIE , "Download firmware signature\n" );
1899+
1900+ memset (& memmap , 0 , sizeof (memmap ));
1901+
1902+ memmap .sig_end = * address ;
1903+ err = brcmf_alloc_rtlv (devinfo , address , BRCMF_SIG_MAGIC , fwsig -> size );
1904+ if (err )
1905+ return err ;
1906+ memmap .sig_start = * address ;
1907+
1908+ memmap .vstatus_end = * address ;
1909+ err = brcmf_alloc_rtlv (devinfo , address , BRCMF_VSTATUS_MAGIC , BRCMF_VSTATUS_SIZE );
1910+ if (err )
1911+ return err ;
1912+ memmap .vstatus_start = * address ;
1913+
1914+ err = brcmf_alloc_rtlv (devinfo , address , BRCMF_MEMMAP_MAGIC , sizeof (memmap ));
1915+ if (err )
1916+ return err ;
1917+
1918+ memmap .fw_start = devinfo -> ci -> rambase ;
1919+ memmap .fw_end = memmap .fw_start + devinfo -> fw_size ;
1920+ memmap .heap_start = memmap .fw_end + BRCMF_BL_HEAP_START_GAP ;
1921+ memmap .heap_end = memmap .heap_start + BRCMF_BL_HEAP_SIZE ;
1922+
1923+ if (memmap .heap_end > * address )
1924+ return - ENOMEM ;
1925+
1926+ memcpy_toio (devinfo -> tcm + memmap .sig_start , fwsig -> data , fwsig -> size );
1927+ memset_io (devinfo -> tcm + memmap .vstatus_start , 0 , BRCMF_VSTATUS_SIZE );
1928+ memcpy_toio (devinfo -> tcm + * address , & memmap , sizeof (memmap ));
1929+
1930+ err = brcmf_alloc_rtlv (devinfo , address , BRCMF_END_MAGIC , 0 );
1931+ if (err )
1932+ return err ;
1933+
1934+ return 0 ;
1935+ }
1936+
1937+ static int brcmf_pcie_populate_footers (struct brcmf_pciedev_info * devinfo ,
1938+ u32 * address , const struct firmware * fwsig )
1939+ {
1940+ int err ;
1941+
1942+ /* We only do this for Apple firmwares. If any other
1943+ * production firmwares are found to need this, the condition
1944+ * needs to be adjusted.
1945+ */
1946+ if (!devinfo -> otp .valid )
1947+ return 0 ;
1948+
1949+ err = brcmf_pcie_add_random_seed (devinfo , address );
1950+ if (err )
1951+ return err ;
1952+
1953+ if (fwsig ) {
1954+ err = brcmf_pcie_add_signature (devinfo , address , fwsig );
1955+ if (err )
1956+ return err ;
1957+ }
1958+
1959+ return 0 ;
18231960}
18241961
18251962static int brcmf_pcie_download_fw_nvram (struct brcmf_pciedev_info * devinfo ,
1826- const struct firmware * fw , void * nvram ,
1827- u32 nvram_len )
1963+ const struct firmware * fw ,
1964+ const struct firmware * fwsig ,
1965+ void * nvram , u32 nvram_len )
18281966{
18291967 struct brcmf_bus * bus = dev_get_drvdata (& devinfo -> pdev -> dev );
18301968 u32 sharedram_addr ;
@@ -1844,44 +1982,39 @@ static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo,
18441982 (void * )fw -> data , fw -> size );
18451983
18461984 resetintr = get_unaligned_le32 (fw -> data );
1985+ devinfo -> fw_size = fw -> size ;
18471986 release_firmware (fw );
18481987
18491988 /* reset last 4 bytes of RAM address. to be used for shared
18501989 * area. This identifies when FW is running
18511990 */
18521991 brcmf_pcie_write_ram32 (devinfo , devinfo -> ci -> ramsize - 4 , 0 );
18531992
1993+ address = devinfo -> ci -> rambase + devinfo -> ci -> ramsize ;
1994+
18541995 if (nvram ) {
18551996 brcmf_dbg (PCIE , "Download NVRAM %s\n" , devinfo -> nvram_name );
1856- address = devinfo -> ci -> rambase + devinfo -> ci -> ramsize -
1857- nvram_len ;
1997+ address -= nvram_len ;
18581998 memcpy_toio (devinfo -> tcm + address , nvram , nvram_len );
18591999 brcmf_fw_nvram_free (nvram );
18602000
1861- if (devinfo -> otp .valid ) {
1862- size_t rand_len = BRCMF_RANDOM_SEED_LENGTH ;
1863- struct brcmf_random_seed_footer footer = {
1864- .length = cpu_to_le32 (rand_len ),
1865- .magic = cpu_to_le32 (BRCMF_RANDOM_SEED_MAGIC ),
1866- };
1867-
1868- /* Some Apple chips/firmwares expect a buffer of random
1869- * data to be present before NVRAM
1870- */
1871- brcmf_dbg (PCIE , "Download random seed\n" );
1872-
1873- address -= sizeof (footer );
1874- memcpy_toio (devinfo -> tcm + address , & footer ,
1875- sizeof (footer ));
1876-
1877- address -= rand_len ;
1878- brcmf_pcie_provide_random_bytes (devinfo , address );
1879- }
2001+ err = brcmf_pcie_populate_footers (devinfo , & address , fwsig );
2002+ if (err )
2003+ brcmf_err (bus , "failed to populate firmware footers err=%d\n" , err );
18802004 } else {
18812005 brcmf_dbg (PCIE , "No matching NVRAM file found %s\n" ,
18822006 devinfo -> nvram_name );
18832007 }
18842008
2009+ release_firmware (fwsig );
2010+
2011+ /* Clear free TCM. This isn't really necessary, but it
2012+ * makes debugging memory dumps a lot easier since we
2013+ * don't get a bunch of junk filling up the free space.
2014+ */
2015+ memset_io (devinfo -> tcm + devinfo -> ci -> rambase + devinfo -> fw_size ,
2016+ 0 , address - devinfo -> fw_size - devinfo -> ci -> rambase );
2017+
18852018 sharedram_addr_written = brcmf_pcie_read_ram32 (devinfo ,
18862019 devinfo -> ci -> ramsize -
18872020 4 );
@@ -2267,11 +2400,12 @@ static int brcmf_pcie_read_otp(struct brcmf_pciedev_info *devinfo)
22672400#define BRCMF_PCIE_FW_NVRAM 1
22682401#define BRCMF_PCIE_FW_CLM 2
22692402#define BRCMF_PCIE_FW_TXCAP 3
2403+ #define BRCMF_PCIE_FW_SIG 4
22702404
22712405static void brcmf_pcie_setup (struct device * dev , int ret ,
22722406 struct brcmf_fw_request * fwreq )
22732407{
2274- const struct firmware * fw ;
2408+ const struct firmware * fw , * fwsig ;
22752409 void * nvram ;
22762410 struct brcmf_bus * bus ;
22772411 struct brcmf_pciedev * pcie_bus_dev ;
@@ -2290,6 +2424,7 @@ static void brcmf_pcie_setup(struct device *dev, int ret,
22902424 brcmf_pcie_attach (devinfo );
22912425
22922426 fw = fwreq -> items [BRCMF_PCIE_FW_CODE ].binary ;
2427+ fwsig = fwreq -> items [BRCMF_PCIE_FW_SIG ].binary ;
22932428 nvram = fwreq -> items [BRCMF_PCIE_FW_NVRAM ].nv_data .data ;
22942429 nvram_len = fwreq -> items [BRCMF_PCIE_FW_NVRAM ].nv_data .len ;
22952430 devinfo -> clm_fw = fwreq -> items [BRCMF_PCIE_FW_CLM ].binary ;
@@ -2300,6 +2435,7 @@ static void brcmf_pcie_setup(struct device *dev, int ret,
23002435 if (ret ) {
23012436 brcmf_err (bus , "Failed to get RAM info\n" );
23022437 release_firmware (fw );
2438+ release_firmware (fwsig );
23032439 brcmf_fw_nvram_free (nvram );
23042440 goto fail ;
23052441 }
@@ -2311,7 +2447,7 @@ static void brcmf_pcie_setup(struct device *dev, int ret,
23112447 */
23122448 brcmf_pcie_adjust_ramsize (devinfo , (u8 * )fw -> data , fw -> size );
23132449
2314- ret = brcmf_pcie_download_fw_nvram (devinfo , fw , nvram , nvram_len );
2450+ ret = brcmf_pcie_download_fw_nvram (devinfo , fw , fwsig , nvram , nvram_len );
23152451 if (ret )
23162452 goto fail ;
23172453
@@ -2376,6 +2512,7 @@ brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo)
23762512 { ".txt" , devinfo -> nvram_name },
23772513 { ".clm_blob" , devinfo -> clm_name },
23782514 { ".txcap_blob" , devinfo -> txcap_name },
2515+ { ".sig" , devinfo -> sig_name },
23792516 };
23802517
23812518 fwreq = brcmf_fw_alloc_request (devinfo -> ci -> chip , devinfo -> ci -> chiprev ,
@@ -2386,6 +2523,8 @@ brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo)
23862523 return NULL ;
23872524
23882525 fwreq -> items [BRCMF_PCIE_FW_CODE ].type = BRCMF_FW_TYPE_BINARY ;
2526+ fwreq -> items [BRCMF_PCIE_FW_SIG ].type = BRCMF_FW_TYPE_BINARY ;
2527+ fwreq -> items [BRCMF_PCIE_FW_SIG ].flags = BRCMF_FW_REQF_OPTIONAL ;
23892528 fwreq -> items [BRCMF_PCIE_FW_NVRAM ].type = BRCMF_FW_TYPE_NVRAM ;
23902529 fwreq -> items [BRCMF_PCIE_FW_NVRAM ].flags = BRCMF_FW_REQF_OPTIONAL ;
23912530 fwreq -> items [BRCMF_PCIE_FW_CLM ].type = BRCMF_FW_TYPE_BINARY ;
0 commit comments