1*b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2680e58f8SSam Ravnborg /*
3680e58f8SSam Ravnborg * idprom.c: Routines to load the idprom into kernel addresses and
4680e58f8SSam Ravnborg * interpret the data contained within.
5680e58f8SSam Ravnborg *
6680e58f8SSam Ravnborg * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
7680e58f8SSam Ravnborg */
8680e58f8SSam Ravnborg
9680e58f8SSam Ravnborg #include <linux/kernel.h>
10680e58f8SSam Ravnborg #include <linux/types.h>
11680e58f8SSam Ravnborg #include <linux/init.h>
12066bcacaSPaul Gortmaker #include <linux/export.h>
13c7f5d105SDavid S. Miller #include <linux/etherdevice.h>
14680e58f8SSam Ravnborg
15680e58f8SSam Ravnborg #include <asm/oplib.h>
16680e58f8SSam Ravnborg #include <asm/idprom.h>
17680e58f8SSam Ravnborg
18680e58f8SSam Ravnborg struct idprom *idprom;
196943f3daSSam Ravnborg EXPORT_SYMBOL(idprom);
206943f3daSSam Ravnborg
21680e58f8SSam Ravnborg static struct idprom idprom_buffer;
22680e58f8SSam Ravnborg
23680e58f8SSam Ravnborg #ifdef CONFIG_SPARC32
24680e58f8SSam Ravnborg #include <asm/machines.h> /* Fun with Sun released architectures. */
25680e58f8SSam Ravnborg
26680e58f8SSam Ravnborg /* Here is the master table of Sun machines which use some implementation
27680e58f8SSam Ravnborg * of the Sparc CPU and have a meaningful IDPROM machtype value that we
28680e58f8SSam Ravnborg * know about. See asm-sparc/machines.h for empirical constants.
29680e58f8SSam Ravnborg */
3058fa4dcbSDavid S. Miller static struct Sun_Machine_Models Sun_Machines[] = {
3158fa4dcbSDavid S. Miller /* First, Leon */
320fd7ef1fSKonrad Eisele { .name = "Leon3 System-on-a-Chip", .id_machtype = (M_LEON | M_LEON3_SOC) },
33680e58f8SSam Ravnborg /* Finally, early Sun4m's */
34680e58f8SSam Ravnborg { .name = "Sun4m SparcSystem600", .id_machtype = (SM_SUN4M | SM_4M_SS60) },
35680e58f8SSam Ravnborg { .name = "Sun4m SparcStation10/20", .id_machtype = (SM_SUN4M | SM_4M_SS50) },
36680e58f8SSam Ravnborg { .name = "Sun4m SparcStation5", .id_machtype = (SM_SUN4M | SM_4M_SS40) },
37680e58f8SSam Ravnborg /* One entry for the OBP arch's which are sun4d, sun4e, and newer sun4m's */
38680e58f8SSam Ravnborg { .name = "Sun4M OBP based system", .id_machtype = (SM_SUN4M_OBP | 0x0) } };
39680e58f8SSam Ravnborg
display_system_type(unsigned char machtype)40680e58f8SSam Ravnborg static void __init display_system_type(unsigned char machtype)
41680e58f8SSam Ravnborg {
42680e58f8SSam Ravnborg char sysname[128];
43680e58f8SSam Ravnborg register int i;
44680e58f8SSam Ravnborg
4558fa4dcbSDavid S. Miller for (i = 0; i < ARRAY_SIZE(Sun_Machines); i++) {
46680e58f8SSam Ravnborg if (Sun_Machines[i].id_machtype == machtype) {
47680e58f8SSam Ravnborg if (machtype != (SM_SUN4M_OBP | 0x00) ||
48680e58f8SSam Ravnborg prom_getproperty(prom_root_node, "banner-name",
49680e58f8SSam Ravnborg sysname, sizeof(sysname)) <= 0)
50680e58f8SSam Ravnborg printk(KERN_WARNING "TYPE: %s\n",
51680e58f8SSam Ravnborg Sun_Machines[i].name);
52680e58f8SSam Ravnborg else
53680e58f8SSam Ravnborg printk(KERN_WARNING "TYPE: %s\n", sysname);
54680e58f8SSam Ravnborg return;
55680e58f8SSam Ravnborg }
56680e58f8SSam Ravnborg }
57680e58f8SSam Ravnborg
58680e58f8SSam Ravnborg prom_printf("IDPROM: Warning, bogus id_machtype value, 0x%x\n", machtype);
59680e58f8SSam Ravnborg }
60680e58f8SSam Ravnborg #else
display_system_type(unsigned char machtype)61680e58f8SSam Ravnborg static void __init display_system_type(unsigned char machtype)
62680e58f8SSam Ravnborg {
63680e58f8SSam Ravnborg }
64680e58f8SSam Ravnborg #endif
65c7f5d105SDavid S. Miller
arch_get_platform_mac_address(void)66c7f5d105SDavid S. Miller unsigned char *arch_get_platform_mac_address(void)
67c7f5d105SDavid S. Miller {
68c7f5d105SDavid S. Miller return idprom->id_ethaddr;
69c7f5d105SDavid S. Miller }
70c7f5d105SDavid S. Miller
71680e58f8SSam Ravnborg /* Calculate the IDPROM checksum (xor of the data bytes). */
calc_idprom_cksum(struct idprom * idprom)72680e58f8SSam Ravnborg static unsigned char __init calc_idprom_cksum(struct idprom *idprom)
73680e58f8SSam Ravnborg {
74680e58f8SSam Ravnborg unsigned char cksum, i, *ptr = (unsigned char *)idprom;
75680e58f8SSam Ravnborg
76680e58f8SSam Ravnborg for (i = cksum = 0; i <= 0x0E; i++)
77680e58f8SSam Ravnborg cksum ^= *ptr++;
78680e58f8SSam Ravnborg
79680e58f8SSam Ravnborg return cksum;
80680e58f8SSam Ravnborg }
81680e58f8SSam Ravnborg
82680e58f8SSam Ravnborg /* Create a local IDPROM copy, verify integrity, and display information. */
idprom_init(void)83680e58f8SSam Ravnborg void __init idprom_init(void)
84680e58f8SSam Ravnborg {
85680e58f8SSam Ravnborg prom_get_idprom((char *) &idprom_buffer, sizeof(idprom_buffer));
86680e58f8SSam Ravnborg
87680e58f8SSam Ravnborg idprom = &idprom_buffer;
88680e58f8SSam Ravnborg
89680e58f8SSam Ravnborg if (idprom->id_format != 0x01)
90680e58f8SSam Ravnborg prom_printf("IDPROM: Warning, unknown format type!\n");
91680e58f8SSam Ravnborg
92680e58f8SSam Ravnborg if (idprom->id_cksum != calc_idprom_cksum(idprom))
93680e58f8SSam Ravnborg prom_printf("IDPROM: Warning, checksum failure (nvram=%x, calc=%x)!\n",
94680e58f8SSam Ravnborg idprom->id_cksum, calc_idprom_cksum(idprom));
95680e58f8SSam Ravnborg
96680e58f8SSam Ravnborg display_system_type(idprom->id_machtype);
97680e58f8SSam Ravnborg
98e3c6d4eeSDavid S. Miller printk(KERN_WARNING "Ethernet address: %pM\n", idprom->id_ethaddr);
99680e58f8SSam Ravnborg }
100