Skip to content

Commit 3271e61

Browse files
nomisralfbaechle
authored andcommitted
MIPS: bcm963xx: Add Broadcom BCM963xx board nvram data structure
Broadcom BCM963xx boards have multiple nvram variants across different SoCs with additional checksum fields added whenever the size of the nvram was extended. Add this structure as a header file so that multiple drivers can use it. Signed-off-by: Simon Arlott <simon@fire.lp0.eu> Cc: David Woodhouse <dwmw2@infradead.org> Cc: Brian Norris <computersforpeace@gmail.com> Cc: Kevin Cernekee <cernekee@gmail.com> Cc: Florian Fainelli <f.fainelli@gmail.com> Cc: Jonas Gorski <jogo@openwrt.org> Cc: Linux Kernel Mailing List <linux-kernel@vger.kernel.org> Cc: MIPS Mailing List <linux-mips@linux-mips.org> Cc: MTD Maling List <linux-mtd@lists.infradead.org> Patchwork: https://patchwork.linux-mips.org/patch/11830/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
1 parent bfd3d53 commit 3271e61

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2376,6 +2376,7 @@ F: arch/mips/kernel/*bmips*
23762376
F: arch/mips/boot/dts/brcm/bcm*.dts*
23772377
F: drivers/irqchip/irq-bcm7*
23782378
F: drivers/irqchip/irq-brcmstb*
2379+
F: include/linux/bcm963xx_nvram.h
23792380

23802381
BROADCOM TG3 GIGABIT ETHERNET DRIVER
23812382
M: Prashant Sreedharan <prashant@broadcom.com>

include/linux/bcm963xx_nvram.h

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
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__ */

0 commit comments

Comments
 (0)