1 #ifndef __LINUX_BCM963XX_NVRAM_H__ 2 #define __LINUX_BCM963XX_NVRAM_H__ 3 4 #include <linux/crc32.h> 5 #include <linux/if_ether.h> 6 #include <linux/sizes.h> 7 #include <linux/types.h> 8 9 /* 10 * Broadcom BCM963xx SoC board nvram data structure. 11 * 12 * The nvram structure varies in size depending on the SoC board version. Use 13 * the appropriate minimum BCM963XX_NVRAM_*_SIZE define for the information 14 * you need instead of sizeof(struct bcm963xx_nvram) as this may change. 15 */ 16 17 #define BCM963XX_NVRAM_V4_SIZE 300 18 #define BCM963XX_NVRAM_V5_SIZE (1 * SZ_1K) 19 20 #define BCM963XX_DEFAULT_PSI_SIZE 64 21 22 enum bcm963xx_nvram_nand_part { 23 BCM963XX_NVRAM_NAND_PART_BOOT = 0, 24 BCM963XX_NVRAM_NAND_PART_ROOTFS_1, 25 BCM963XX_NVRAM_NAND_PART_ROOTFS_2, 26 BCM963XX_NVRAM_NAND_PART_DATA, 27 BCM963XX_NVRAM_NAND_PART_BBT, 28 29 __BCM963XX_NVRAM_NAND_NR_PARTS 30 }; 31 32 struct bcm963xx_nvram { 33 u32 version; 34 char bootline[256]; 35 char name[16]; 36 u32 main_tp_number; 37 u32 psi_size; 38 u32 mac_addr_count; 39 u8 mac_addr_base[ETH_ALEN]; 40 u8 __reserved1[2]; 41 u32 checksum_v4; 42 43 u8 __reserved2[292]; 44 u32 nand_part_offset[__BCM963XX_NVRAM_NAND_NR_PARTS]; 45 u32 nand_part_size[__BCM963XX_NVRAM_NAND_NR_PARTS]; 46 u8 __reserved3[388]; 47 u32 checksum_v5; 48 }; 49 50 #define BCM963XX_NVRAM_NAND_PART_OFFSET(nvram, part) \ 51 bcm963xx_nvram_nand_part_offset(nvram, BCM963XX_NVRAM_NAND_PART_ ##part) 52 53 static inline u64 __pure bcm963xx_nvram_nand_part_offset( 54 const struct bcm963xx_nvram *nvram, 55 enum bcm963xx_nvram_nand_part part) 56 { 57 return nvram->nand_part_offset[part] * SZ_1K; 58 } 59 60 #define BCM963XX_NVRAM_NAND_PART_SIZE(nvram, part) \ 61 bcm963xx_nvram_nand_part_size(nvram, BCM963XX_NVRAM_NAND_PART_ ##part) 62 63 static inline u64 __pure bcm963xx_nvram_nand_part_size( 64 const struct bcm963xx_nvram *nvram, 65 enum bcm963xx_nvram_nand_part part) 66 { 67 return nvram->nand_part_size[part] * SZ_1K; 68 } 69 70 /* 71 * bcm963xx_nvram_checksum - Verify nvram checksum 72 * 73 * @nvram: pointer to full size nvram data structure 74 * @expected_out: optional pointer to store expected checksum value 75 * @actual_out: optional pointer to store actual checksum value 76 * 77 * Return: 0 if the checksum is valid, otherwise -EINVAL 78 */ 79 static int __maybe_unused bcm963xx_nvram_checksum( 80 const struct bcm963xx_nvram *nvram, 81 u32 *expected_out, u32 *actual_out) 82 { 83 u32 expected, actual; 84 size_t len; 85 86 if (nvram->version <= 4) { 87 expected = nvram->checksum_v4; 88 len = BCM963XX_NVRAM_V4_SIZE - sizeof(u32); 89 } else { 90 expected = nvram->checksum_v5; 91 len = BCM963XX_NVRAM_V5_SIZE - sizeof(u32); 92 } 93 94 /* 95 * Calculate the CRC32 value for the nvram with a checksum value 96 * of 0 without modifying or copying the nvram by combining: 97 * - The CRC32 of the nvram without the checksum value 98 * - The CRC32 of a zero checksum value (which is also 0) 99 */ 100 actual = crc32_le_combine( 101 crc32_le(~0, (u8 *)nvram, len), 0, sizeof(u32)); 102 103 if (expected_out) 104 *expected_out = expected; 105 106 if (actual_out) 107 *actual_out = actual; 108 109 return expected == actual ? 0 : -EINVAL; 110 }; 111 112 #endif /* __LINUX_BCM963XX_NVRAM_H__ */ 113