summaryrefslogtreecommitdiff
path: root/board/tqm8xx/load_sernum_ethaddr.c
blob: 98baf7f67db37a76b0fdbe79783a58a6d4c69037 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/*
 * (C) Copyright 2000, 2001, 2002
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>
#include <mpc8xx.h>

/*-----------------------------------------------------------------------
 * Process Hardware Information Block:
 *
 * If we boot on a system fresh from factory, check if the Hardware
 * Information Block exists and save the information it contains.
 *
 * The TQM8xxL / TQM82xx Hardware Information Block is defined as
 * follows:
 * - located in first flash bank
 * - starts at offset 0x0003FFC0
 * - size 0x00000040
 *
 * Internal structure:
 * - sequence of ASCII character strings
 * - fields separated by a single space character (0x20)
 * - last field terminated by NUL character (0x00)
 * - remaining space filled with NUL characters (0x00)
 *
 * Fields in Hardware Information Block:
 * 1) Module Type
 * 2) Serial Number
 * 3) First MAC Address
 * 4) Number of additional MAC addresses
 */

void load_sernum_ethaddr (void)
{
	unsigned char *hwi;
	unsigned char  serial [CFG_HWINFO_SIZE];
	unsigned char  ethaddr[CFG_HWINFO_SIZE];
	unsigned short ih, is, ie, part;

	hwi = (unsigned char *)(CFG_FLASH_BASE + CFG_HWINFO_OFFSET);
	ih = is = ie = 0;

	if (*((unsigned long *)hwi) != (unsigned long)CFG_HWINFO_MAGIC) {
		return;
	}

	part = 1;

	/* copy serial # / MAC address */
	while ((hwi[ih] != '\0') && (ih < CFG_HWINFO_SIZE)) {
		if (hwi[ih] < ' ' || hwi[ih] > '~') { /* ASCII strings! */
			return;
		}
		switch (part) {
		default:		/* Copy serial # */
			if (hwi[ih] == ' ') {
				++part;
			}
			serial[is++] = hwi[ih];
			break;
		case 3:			/* Copy MAC address */
			if (hwi[ih] == ' ') {
				++part;
				break;
			}
			ethaddr[ie++] = hwi[ih];
			if ((ie % 3) == 2)
				ethaddr[ie++] = ':';
			break;
		}
		++ih;
	}
	serial[is]  = '\0';
	if (ie && ethaddr[ie-1] == ':')
		--ie;
	ethaddr[ie] = '\0';

	/* set serial# and ethaddr if not yet defined */
	if (getenv("serial#") == NULL) {
		setenv ("serial#", serial);
	}

	if (getenv("ethaddr") == NULL) {
		setenv ("ethaddr", ethaddr);
	}
}