sysmocom-odu: read mac addresses from EEPROM
Signed-off-by: Jan Luebbe <jluebbe@debian.org>
This commit is contained in:
parent
1f07bf18ed
commit
208d53ef9e
|
@ -32,6 +32,9 @@
|
||||||
#include <mach/am33xx-generic.h>
|
#include <mach/am33xx-generic.h>
|
||||||
#include <mach/am33xx-silicon.h>
|
#include <mach/am33xx-silicon.h>
|
||||||
#include <mach/bbu.h>
|
#include <mach/bbu.h>
|
||||||
|
#include <net.h>
|
||||||
|
|
||||||
|
#include "sob_odu_eeprom.h"
|
||||||
|
|
||||||
static int physom_coredevice_init(void)
|
static int physom_coredevice_init(void)
|
||||||
{
|
{
|
||||||
|
@ -124,3 +127,58 @@ static int physom_devices_init(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
device_initcall(physom_devices_init);
|
device_initcall(physom_devices_init);
|
||||||
|
|
||||||
|
#define CRCPOLY_LE 0xedb88320
|
||||||
|
static inline u32 __pure crc32_le_generic(u32 crc, unsigned char const *p,
|
||||||
|
size_t len, u32 polynomial)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
while (len--) {
|
||||||
|
crc ^= *p++;
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
crc = (crc >> 1) ^ ((crc & 1) ? polynomial : 0);
|
||||||
|
}
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
|
||||||
|
{
|
||||||
|
return crc32_le_generic(crc, p, len, CRCPOLY_LE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sob_odu_eeprom_init(void)
|
||||||
|
{
|
||||||
|
struct sob_odu_eeprom soe;
|
||||||
|
uint32_t crc32_comp;
|
||||||
|
struct cdev *cdev;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!of_machine_is_compatible("sysmocom,odu"))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
cdev = cdev_by_name("eeprom0");
|
||||||
|
if (!cdev)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
ret = cdev_read(cdev, &soe, sizeof(soe), 0, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (soe.magic != SOBJB_EE_MAGIC || soe.version != SOBJB_EE_VERSION) {
|
||||||
|
pr_err("EEPROM magic/version wrong\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
crc32_comp = crc32_le(0xffffffff, (void *)(&soe) + 8, sizeof(soe)-8);
|
||||||
|
if (soe.crc32 != crc32_comp) {
|
||||||
|
pr_err("EEPROM CRC32 mismatch (eeprom=0x%08x, computed=0x%08x)\n",
|
||||||
|
soe.crc32, crc32_comp);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
pr_info("SOB-ODU board v%u, serial number %u, mfg %u, hw_options=0x%08x\n",
|
||||||
|
soe.model, soe.serial, soe.manuf_date, soe.hw_options);
|
||||||
|
|
||||||
|
eth_register_ethaddr(0, soe.mac_eth0);
|
||||||
|
eth_register_ethaddr(1, soe.mac_eth1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
late_initcall(sob_odu_eeprom_init);
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define MAC_ADDR_LEN 6
|
||||||
|
|
||||||
|
#define SOBJB_EE_MAGIC 0x50b0d0ee
|
||||||
|
#define SOBJB_EE_VERSION 1
|
||||||
|
|
||||||
|
#define SOB_ODU_V1 1
|
||||||
|
#define SOB_ODU_V2 2
|
||||||
|
#define SOB_ODU_V3 3
|
||||||
|
|
||||||
|
struct sob_odu_eeprom {
|
||||||
|
uint32_t magic; /* SOBJB_EE_MAGIC */
|
||||||
|
uint32_t crc32; /* crc32_le */
|
||||||
|
|
||||||
|
uint16_t len; /* sizeof(struct sob_odu_eeprom) */
|
||||||
|
uint8_t version; /* SOBJB_EE_VERSION */
|
||||||
|
uint8_t model; /* SOB_ODU_V* */
|
||||||
|
|
||||||
|
uint32_t serial;
|
||||||
|
uint32_t manuf_date;
|
||||||
|
uint32_t hw_options;
|
||||||
|
|
||||||
|
uint8_t mac_eth0[MAC_ADDR_LEN];
|
||||||
|
uint8_t mac_eth1[MAC_ADDR_LEN];
|
||||||
|
uint8_t mac_wlan0[MAC_ADDR_LEN];
|
||||||
|
uint8_t mac_wlan1[MAC_ADDR_LEN];
|
||||||
|
} __attribute__ ((packed));
|
Loading…
Reference in New Issue