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
|
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
|
config ETH_NXP_ENET_QOS_TX_BUFFER_DESCRIPTORS
|
||||||
int "Number of tx buffer descriptors"
|
int "Number of tx buffer descriptors"
|
||||||
default 4
|
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/net/phy.h>
|
||||||
#include <zephyr/kernel/thread_stack.h>
|
#include <zephyr/kernel/thread_stack.h>
|
||||||
#include <zephyr/sys_clock.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 <ethernet/eth_stats.h>
|
||||||
#include "../eth.h"
|
#include "../eth.h"
|
||||||
#include "nxp_enet_qos_priv.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;
|
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)
|
static int eth_nxp_enet_qos_mac_init(const struct device *dev)
|
||||||
{
|
{
|
||||||
const struct nxp_enet_qos_mac_config *config = dev->config;
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Random mac therefore overrides local mac that may have been initialized */
|
if (config->mac_addr_source == NXP_ENET_QOS_MAC_ADDR_SOURCE_LOCAL) {
|
||||||
if (config->random_mac) {
|
/* 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,
|
gen_random_mac(data->mac_addr.addr,
|
||||||
NXP_OUI_BYTE_0, NXP_OUI_BYTE_1, NXP_OUI_BYTE_2);
|
NXP_OUI_BYTE_0, NXP_OUI_BYTE_1, NXP_OUI_BYTE_2);
|
||||||
}
|
}
|
||||||
|
|
@ -626,56 +660,59 @@ static const struct ethernet_api api_funcs = {
|
||||||
.set_config = eth_nxp_enet_qos_set_config,
|
.set_config = eth_nxp_enet_qos_set_config,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NXP_ENET_QOS_NODE_HAS_MAC_ADDR_CHECK(n) \
|
#define NXP_ENET_QOS_NODE_HAS_MAC_ADDR_CHECK(n) \
|
||||||
BUILD_ASSERT(NODE_HAS_VALID_MAC_ADDR(DT_DRV_INST(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) || \
|
||||||
"MAC address not specified on ENET QOS DT node");
|
DT_INST_PROP(n, nxp_unique_mac), \
|
||||||
|
"MAC address not specified on ENET QOS DT node");
|
||||||
|
|
||||||
#define NXP_ENET_QOS_CONNECT_IRQS(node_id, prop, idx) \
|
#define NXP_ENET_QOS_MAC_ADDR_SOURCE(n) \
|
||||||
do { \
|
COND_CODE_1(DT_NODE_HAS_PROP(DT_DRV_INST(n), local_mac_address), \
|
||||||
IRQ_CONNECT(DT_IRQN_BY_IDX(node_id, idx), \
|
(NXP_ENET_QOS_MAC_ADDR_SOURCE_LOCAL), \
|
||||||
DT_IRQ_BY_IDX(node_id, idx, priority), \
|
(COND_CODE_1(DT_INST_PROP(n, zephyr_random_mac_address), \
|
||||||
eth_nxp_enet_qos_mac_isr, \
|
(NXP_ENET_QOS_MAC_ADDR_SOURCE_RANDOM), \
|
||||||
DEVICE_DT_GET(node_id), \
|
(COND_CODE_1(DT_INST_PROP(n, nxp_unique_mac), \
|
||||||
0); \
|
(NXP_ENET_QOS_MAC_ADDR_SOURCE_UNIQUE), \
|
||||||
irq_enable(DT_IRQN_BY_IDX(node_id, idx)); \
|
(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_enable(DT_IRQN_BY_IDX(node_id, idx)); \
|
||||||
} while (false);
|
} while (false);
|
||||||
|
|
||||||
#define NXP_ENET_QOS_IRQ_CONFIG_FUNC(n) \
|
#define NXP_ENET_QOS_IRQ_CONFIG_FUNC(n) \
|
||||||
static void nxp_enet_qos_##n##_irq_config_func(void) \
|
static void nxp_enet_qos_##n##_irq_config_func(void) \
|
||||||
{ \
|
{ \
|
||||||
DT_FOREACH_PROP_ELEM(DT_DRV_INST(n), \
|
DT_FOREACH_PROP_ELEM(DT_DRV_INST(n), interrupt_names, NXP_ENET_QOS_CONNECT_IRQS) \
|
||||||
interrupt_names, \
|
|
||||||
NXP_ENET_QOS_CONNECT_IRQS) \
|
|
||||||
}
|
}
|
||||||
|
#define NXP_ENET_QOS_DRIVER_STRUCTS_INIT(n) \
|
||||||
#define NXP_ENET_QOS_DRIVER_STRUCTS_INIT(n) \
|
static const struct nxp_enet_qos_mac_config enet_qos_##n##_mac_config = { \
|
||||||
static const struct nxp_enet_qos_mac_config enet_qos_##n##_mac_config = { \
|
.enet_dev = DEVICE_DT_GET(DT_INST_PARENT(n)), \
|
||||||
.enet_dev = DEVICE_DT_GET(DT_INST_PARENT(n)), \
|
.phy_dev = DEVICE_DT_GET(DT_INST_PHANDLE(n, phy_handle)), \
|
||||||
.phy_dev = DEVICE_DT_GET(DT_INST_PHANDLE(n, phy_handle)), \
|
.base = (enet_qos_t *)DT_REG_ADDR(DT_INST_PARENT(n)), \
|
||||||
.base = (enet_qos_t *)DT_REG_ADDR(DT_INST_PARENT(n)), \
|
.hw_info = \
|
||||||
.hw_info = { \
|
{ \
|
||||||
.max_frame_len = ENET_QOS_MAX_NORMAL_FRAME_LEN, \
|
.max_frame_len = ENET_QOS_MAX_NORMAL_FRAME_LEN, \
|
||||||
}, \
|
}, \
|
||||||
.irq_config_func = nxp_enet_qos_##n##_irq_config_func, \
|
.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}), \
|
||||||
{ \
|
|
||||||
.mac_addr.addr = DT_INST_PROP_OR(n, local_mac_address, {0}), \
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NXP_ENET_QOS_DRIVER_INIT(n) \
|
#define NXP_ENET_QOS_DRIVER_INIT(n) \
|
||||||
NXP_ENET_QOS_NODE_HAS_MAC_ADDR_CHECK(n) \
|
NXP_ENET_QOS_NODE_HAS_MAC_ADDR_CHECK(n) \
|
||||||
NXP_ENET_QOS_IRQ_CONFIG_FUNC(n) \
|
NXP_ENET_QOS_IRQ_CONFIG_FUNC(n) \
|
||||||
NXP_ENET_QOS_DRIVER_STRUCTS_INIT(n)
|
NXP_ENET_QOS_DRIVER_STRUCTS_INIT(n)
|
||||||
|
|
||||||
DT_INST_FOREACH_STATUS_OKAY(NXP_ENET_QOS_DRIVER_INIT)
|
DT_INST_FOREACH_STATUS_OKAY(NXP_ENET_QOS_DRIVER_INIT)
|
||||||
|
|
||||||
#define NXP_ENET_QOS_MAC_DEVICE_DEFINE(n) \
|
#define NXP_ENET_QOS_MAC_DEVICE_DEFINE(n) \
|
||||||
ETH_NET_DEVICE_DT_INST_DEFINE(n, eth_nxp_enet_qos_mac_init, NULL, \
|
ETH_NET_DEVICE_DT_INST_DEFINE(n, eth_nxp_enet_qos_mac_init, NULL, \
|
||||||
&enet_qos_##n##_mac_data, &enet_qos_##n##_mac_config, \
|
&enet_qos_##n##_mac_data, &enet_qos_##n##_mac_config, \
|
||||||
CONFIG_ETH_INIT_PRIORITY, &api_funcs, NET_ETH_MTU);
|
CONFIG_ETH_INIT_PRIORITY, &api_funcs, NET_ETH_MTU);
|
||||||
|
|
||||||
DT_INST_FOREACH_STATUS_OKAY(NXP_ENET_QOS_MAC_DEVICE_DEFINE)
|
DT_INST_FOREACH_STATUS_OKAY(NXP_ENET_QOS_MAC_DEVICE_DEFINE)
|
||||||
|
|
|
||||||
|
|
@ -85,13 +85,20 @@ struct nxp_enet_qos_hw_info {
|
||||||
uint16_t max_frame_len;
|
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 {
|
struct nxp_enet_qos_mac_config {
|
||||||
const struct device *enet_dev;
|
const struct device *enet_dev;
|
||||||
const struct device *phy_dev;
|
const struct device *phy_dev;
|
||||||
enet_qos_t *base;
|
enet_qos_t *base;
|
||||||
struct nxp_enet_qos_hw_info hw_info;
|
struct nxp_enet_qos_hw_info hw_info;
|
||||||
void (*irq_config_func)(void);
|
void (*irq_config_func)(void);
|
||||||
bool random_mac;
|
enum mac_address_source mac_addr_source;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nxp_enet_qos_tx_data {
|
struct nxp_enet_qos_tx_data {
|
||||||
|
|
|
||||||
|
|
@ -13,3 +13,15 @@ properties:
|
||||||
|
|
||||||
interrupt-names:
|
interrupt-names:
|
||||||
required: true
|
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