eth_nxp_enet_qos_mac: implement the nxp,unique-mac address feature
This implements to generate the MAC address of the device UUID. The UUID is hashed to reduce the size to 3 bytes. Ideas taken from eth_nxp_enet.c Adding dependencies on: HWInfo and CRC Signed-off-by: Adib Taraben <theadib@gmail.com>
This commit is contained in:
parent
cf91c1b84f
commit
cce082626e
4 changed files with 111 additions and 44 deletions
|
|
@ -23,6 +23,17 @@ config ETH_NXP_ENET_QOS_MAC
|
|||
|
||||
if ETH_NXP_ENET_QOS_MAC
|
||||
|
||||
DT_PROP_NXP_ENET_QOS_MAC_UNIQUE_MAC := nxp,unique-mac
|
||||
|
||||
config ETH_NXP_ENET_QOS_MAC_UNIQUE_MAC_ADDRESS
|
||||
bool "Unique MAC address support"
|
||||
default y if $(dt_compat_any_has_prop,$(DT_COMPAT_NXP_ENET_QOS_MAC),$(DT_PROP_NXP_ENET_QOS_MAC_UNIQUE_MAC),True)
|
||||
select HWINFO
|
||||
select CRC
|
||||
help
|
||||
Enable Unique MAC address support based on device UUID.
|
||||
|
||||
|
||||
config ETH_NXP_ENET_QOS_TX_BUFFER_DESCRIPTORS
|
||||
int "Number of tx buffer descriptors"
|
||||
default 4
|
||||
|
|
|
|||
|
|
@ -12,6 +12,10 @@ LOG_MODULE_REGISTER(eth_nxp_enet_qos_mac, CONFIG_ETHERNET_LOG_LEVEL);
|
|||
#include <zephyr/net/phy.h>
|
||||
#include <zephyr/kernel/thread_stack.h>
|
||||
#include <zephyr/sys_clock.h>
|
||||
#if defined(CONFIG_ETH_NXP_ENET_QOS_MAC_UNIQUE_MAC_ADDRESS)
|
||||
#include <zephyr/sys/crc.h>
|
||||
#include <zephyr/drivers/hwinfo.h>
|
||||
#endif
|
||||
#include <ethernet/eth_stats.h>
|
||||
#include "../eth.h"
|
||||
#include "nxp_enet_qos_priv.h"
|
||||
|
|
@ -480,6 +484,33 @@ static inline int enet_qos_rx_desc_init(enet_qos_t *base, struct nxp_enet_qos_rx
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ETH_NXP_ENET_QOS_MAC_UNIQUE_MAC_ADDRESS)
|
||||
/* Note this is not universally unique, it just is probably unique on a network */
|
||||
static inline void nxp_enet_unique_mac(uint8_t *mac_addr)
|
||||
{
|
||||
uint8_t unique_device_ID_16_bytes[16] = {0};
|
||||
ssize_t uuid_length =
|
||||
hwinfo_get_device_id(unique_device_ID_16_bytes, sizeof(unique_device_ID_16_bytes));
|
||||
uint32_t hash = 0;
|
||||
|
||||
if (uuid_length > 0) {
|
||||
hash = crc24_pgp((uint8_t *)unique_device_ID_16_bytes, uuid_length);
|
||||
} else {
|
||||
LOG_ERR("No unique MAC can be provided in this platform");
|
||||
}
|
||||
|
||||
/* Setting LAA bit because it is not guaranteed universally unique */
|
||||
mac_addr[0] = NXP_OUI_BYTE_0 | 0x02;
|
||||
mac_addr[1] = NXP_OUI_BYTE_1;
|
||||
mac_addr[2] = NXP_OUI_BYTE_2;
|
||||
mac_addr[3] = FIELD_GET(0xFF0000, hash);
|
||||
mac_addr[4] = FIELD_GET(0x00FF00, hash);
|
||||
mac_addr[5] = FIELD_GET(0x0000FF, hash);
|
||||
}
|
||||
#else
|
||||
#define nxp_enet_unique_mac(arg)
|
||||
#endif
|
||||
|
||||
static int eth_nxp_enet_qos_mac_init(const struct device *dev)
|
||||
{
|
||||
const struct nxp_enet_qos_mac_config *config = dev->config;
|
||||
|
|
@ -501,8 +532,11 @@ static int eth_nxp_enet_qos_mac_init(const struct device *dev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Random mac therefore overrides local mac that may have been initialized */
|
||||
if (config->random_mac) {
|
||||
if (config->mac_addr_source == NXP_ENET_QOS_MAC_ADDR_SOURCE_LOCAL) {
|
||||
/* Use the mac address provided in the devicetree */
|
||||
} else if (config->mac_addr_source == NXP_ENET_QOS_MAC_ADDR_SOURCE_UNIQUE) {
|
||||
nxp_enet_unique_mac(data->mac_addr.addr);
|
||||
} else {
|
||||
gen_random_mac(data->mac_addr.addr,
|
||||
NXP_OUI_BYTE_0, NXP_OUI_BYTE_1, NXP_OUI_BYTE_2);
|
||||
}
|
||||
|
|
@ -628,41 +662,44 @@ static const struct ethernet_api api_funcs = {
|
|||
|
||||
#define NXP_ENET_QOS_NODE_HAS_MAC_ADDR_CHECK(n) \
|
||||
BUILD_ASSERT(NODE_HAS_VALID_MAC_ADDR(DT_DRV_INST(n)) || \
|
||||
DT_INST_PROP(n, zephyr_random_mac_address), \
|
||||
DT_INST_PROP(n, zephyr_random_mac_address) || \
|
||||
DT_INST_PROP(n, nxp_unique_mac), \
|
||||
"MAC address not specified on ENET QOS DT node");
|
||||
|
||||
#define NXP_ENET_QOS_MAC_ADDR_SOURCE(n) \
|
||||
COND_CODE_1(DT_NODE_HAS_PROP(DT_DRV_INST(n), local_mac_address), \
|
||||
(NXP_ENET_QOS_MAC_ADDR_SOURCE_LOCAL), \
|
||||
(COND_CODE_1(DT_INST_PROP(n, zephyr_random_mac_address), \
|
||||
(NXP_ENET_QOS_MAC_ADDR_SOURCE_RANDOM), \
|
||||
(COND_CODE_1(DT_INST_PROP(n, nxp_unique_mac), \
|
||||
(NXP_ENET_QOS_MAC_ADDR_SOURCE_UNIQUE), \
|
||||
(NXP_ENET_QOS_MAC_ADDR_SOURCE_INVALID))))))
|
||||
|
||||
#define NXP_ENET_QOS_CONNECT_IRQS(node_id, prop, idx) \
|
||||
do { \
|
||||
IRQ_CONNECT(DT_IRQN_BY_IDX(node_id, idx), \
|
||||
DT_IRQ_BY_IDX(node_id, idx, priority), \
|
||||
eth_nxp_enet_qos_mac_isr, \
|
||||
DEVICE_DT_GET(node_id), \
|
||||
0); \
|
||||
IRQ_CONNECT(DT_IRQN_BY_IDX(node_id, idx), DT_IRQ_BY_IDX(node_id, idx, priority), \
|
||||
eth_nxp_enet_qos_mac_isr, DEVICE_DT_GET(node_id), 0); \
|
||||
irq_enable(DT_IRQN_BY_IDX(node_id, idx)); \
|
||||
} while (false);
|
||||
|
||||
#define NXP_ENET_QOS_IRQ_CONFIG_FUNC(n) \
|
||||
static void nxp_enet_qos_##n##_irq_config_func(void) \
|
||||
{ \
|
||||
DT_FOREACH_PROP_ELEM(DT_DRV_INST(n), \
|
||||
interrupt_names, \
|
||||
NXP_ENET_QOS_CONNECT_IRQS) \
|
||||
DT_FOREACH_PROP_ELEM(DT_DRV_INST(n), interrupt_names, NXP_ENET_QOS_CONNECT_IRQS) \
|
||||
}
|
||||
|
||||
#define NXP_ENET_QOS_DRIVER_STRUCTS_INIT(n) \
|
||||
static const struct nxp_enet_qos_mac_config enet_qos_##n##_mac_config = { \
|
||||
.enet_dev = DEVICE_DT_GET(DT_INST_PARENT(n)), \
|
||||
.phy_dev = DEVICE_DT_GET(DT_INST_PHANDLE(n, phy_handle)), \
|
||||
.base = (enet_qos_t *)DT_REG_ADDR(DT_INST_PARENT(n)), \
|
||||
.hw_info = { \
|
||||
.hw_info = \
|
||||
{ \
|
||||
.max_frame_len = ENET_QOS_MAX_NORMAL_FRAME_LEN, \
|
||||
}, \
|
||||
.irq_config_func = nxp_enet_qos_##n##_irq_config_func, \
|
||||
.random_mac = DT_INST_PROP(n, zephyr_random_mac_address), \
|
||||
.mac_addr_source = NXP_ENET_QOS_MAC_ADDR_SOURCE(n), \
|
||||
}; \
|
||||
\
|
||||
static struct nxp_enet_qos_mac_data enet_qos_##n##_mac_data = \
|
||||
{ \
|
||||
static struct nxp_enet_qos_mac_data enet_qos_##n##_mac_data = { \
|
||||
.mac_addr.addr = DT_INST_PROP_OR(n, local_mac_address, {0}), \
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -85,13 +85,20 @@ struct nxp_enet_qos_hw_info {
|
|||
uint16_t max_frame_len;
|
||||
};
|
||||
|
||||
enum mac_address_source {
|
||||
NXP_ENET_QOS_MAC_ADDR_SOURCE_LOCAL,
|
||||
NXP_ENET_QOS_MAC_ADDR_SOURCE_RANDOM,
|
||||
NXP_ENET_QOS_MAC_ADDR_SOURCE_UNIQUE,
|
||||
NXP_ENET_QOS_MAC_ADDR_SOURCE_INVALID,
|
||||
};
|
||||
|
||||
struct nxp_enet_qos_mac_config {
|
||||
const struct device *enet_dev;
|
||||
const struct device *phy_dev;
|
||||
enet_qos_t *base;
|
||||
struct nxp_enet_qos_hw_info hw_info;
|
||||
void (*irq_config_func)(void);
|
||||
bool random_mac;
|
||||
enum mac_address_source mac_addr_source;
|
||||
};
|
||||
|
||||
struct nxp_enet_qos_tx_data {
|
||||
|
|
|
|||
|
|
@ -13,3 +13,15 @@ properties:
|
|||
|
||||
interrupt-names:
|
||||
required: true
|
||||
|
||||
nxp,unique-mac:
|
||||
type: boolean
|
||||
description: |
|
||||
Use part of the unique silicon ID to generate the MAC.
|
||||
This property will be overridden if the node has
|
||||
zephyr,random-mac-address or local-mac-address also.
|
||||
This option is intended for cases where a very low likelihood
|
||||
that the mac address is the same as another on the network
|
||||
is sufficient, such as, testing, bringup, demos, etc.
|
||||
The first 3 bytes will be the freescale OUI and the next
|
||||
3 bytes will come from the chip's unique ID.
|
||||
|
|
|
|||
Loading…
Reference in a new issue