xref: /kernel/linux/linux-5.10/arch/c6x/kernel/soc.c (revision 8c2ecf20)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 *  Miscellaneous SoC-specific hooks.
4 *
5 *  Copyright (C) 2011 Texas Instruments Incorporated
6 *  Author: Mark Salter <msalter@redhat.com>
7 */
8#include <linux/module.h>
9#include <linux/ctype.h>
10#include <linux/etherdevice.h>
11#include <asm/setup.h>
12#include <asm/soc.h>
13
14struct soc_ops soc_ops;
15
16int soc_get_exception(void)
17{
18	if (!soc_ops.get_exception)
19		return -1;
20	return soc_ops.get_exception();
21}
22
23void soc_assert_event(unsigned int evt)
24{
25	if (soc_ops.assert_event)
26		soc_ops.assert_event(evt);
27}
28
29static u8 cmdline_mac[6];
30
31static int __init get_mac_addr_from_cmdline(char *str)
32{
33	int count, i, val;
34
35	for (count = 0; count < 6 && *str; count++, str += 3) {
36		if (!isxdigit(str[0]) || !isxdigit(str[1]))
37			return 0;
38		if (str[2] != ((count < 5) ? ':' : '\0'))
39			return 0;
40
41		for (i = 0, val = 0; i < 2; i++) {
42			val = val << 4;
43			val |= isdigit(str[i]) ?
44				str[i] - '0' : toupper(str[i]) - 'A' + 10;
45		}
46		cmdline_mac[count] = val;
47	}
48	return 1;
49}
50__setup("emac_addr=", get_mac_addr_from_cmdline);
51
52/*
53 * Setup the MAC address for SoC ethernet devices.
54 *
55 * Before calling this function, the ethernet driver will have
56 * initialized the addr with local-mac-address from the device
57 * tree (if found). Allow command line to override, but not
58 * the fused address.
59 */
60int soc_mac_addr(unsigned int index, u8 *addr)
61{
62	int i, have_dt_mac = 0, have_cmdline_mac = 0, have_fuse_mac = 0;
63
64	for (i = 0; i < 6; i++) {
65		if (cmdline_mac[i])
66			have_cmdline_mac = 1;
67		if (c6x_fuse_mac[i])
68			have_fuse_mac = 1;
69		if (addr[i])
70			have_dt_mac = 1;
71	}
72
73	/* cmdline overrides all */
74	if (have_cmdline_mac)
75		memcpy(addr, cmdline_mac, 6);
76	else if (!have_dt_mac) {
77		if (have_fuse_mac)
78			memcpy(addr, c6x_fuse_mac, 6);
79		else
80			eth_random_addr(addr);
81	}
82
83	/* adjust for specific EMAC device */
84	addr[5] += index * c6x_num_cores;
85	return 1;
86}
87EXPORT_SYMBOL_GPL(soc_mac_addr);
88