@@ -12,6 +12,10 @@ LOG_MODULE_REGISTER(eth_nxp_enet_qos_mac, CONFIG_ETHERNET_LOG_LEVEL);
12
12
#include <zephyr/net/phy.h>
13
13
#include <zephyr/kernel/thread_stack.h>
14
14
#include <zephyr/sys_clock.h>
15
+ #if defined(CONFIG_ETH_NXP_ENET_QOS_MAC_UNIQUE_MAC_ADDRESS )
16
+ #include <zephyr/sys/crc.h>
17
+ #include <zephyr/drivers/hwinfo.h>
18
+ #endif
15
19
#include <ethernet/eth_stats.h>
16
20
#include "../eth.h"
17
21
#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
480
484
return 0 ;
481
485
}
482
486
487
+ #if defined(CONFIG_ETH_NXP_ENET_QOS_MAC_UNIQUE_MAC_ADDRESS )
488
+ /* Note this is not universally unique, it just is probably unique on a network */
489
+ static inline void nxp_enet_unique_mac (uint8_t * mac_addr )
490
+ {
491
+ uint8_t unique_device_ID_16_bytes [16 ] = {0 };
492
+ ssize_t uuid_length =
493
+ hwinfo_get_device_id (unique_device_ID_16_bytes , sizeof (unique_device_ID_16_bytes ));
494
+ uint32_t hash = 0 ;
495
+
496
+ if (uuid_length > 0 ) {
497
+ hash = crc24_pgp ((uint8_t * )unique_device_ID_16_bytes , uuid_length );
498
+ } else {
499
+ LOG_ERR ("No unique MAC can be provided in this platform" );
500
+ }
501
+
502
+ /* Setting LAA bit because it is not guaranteed universally unique */
503
+ mac_addr [0 ] = NXP_OUI_BYTE_0 | 0x02 ;
504
+ mac_addr [1 ] = NXP_OUI_BYTE_1 ;
505
+ mac_addr [2 ] = NXP_OUI_BYTE_2 ;
506
+ mac_addr [3 ] = FIELD_GET (0xFF0000 , hash );
507
+ mac_addr [4 ] = FIELD_GET (0x00FF00 , hash );
508
+ mac_addr [5 ] = FIELD_GET (0x0000FF , hash );
509
+ }
510
+ #else
511
+ #define nxp_enet_unique_mac (arg )
512
+ #endif
513
+
483
514
static int eth_nxp_enet_qos_mac_init (const struct device * dev )
484
515
{
485
516
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)
501
532
return ret ;
502
533
}
503
534
504
- /* Random mac therefore overrides local mac that may have been initialized */
505
- if (config -> random_mac ) {
535
+ if (config -> mac_addr_source == NXP_ENET_QOS_MAC_ADDR_SOURCE_LOCAL ) {
536
+ /* Use the mac address provided in the devicetree */
537
+ } else if (config -> mac_addr_source == NXP_ENET_QOS_MAC_ADDR_SOURCE_UNIQUE ) {
538
+ nxp_enet_unique_mac (data -> mac_addr .addr );
539
+ } else {
506
540
gen_random_mac (data -> mac_addr .addr ,
507
541
NXP_OUI_BYTE_0 , NXP_OUI_BYTE_1 , NXP_OUI_BYTE_2 );
508
542
}
@@ -626,56 +660,59 @@ static const struct ethernet_api api_funcs = {
626
660
.set_config = eth_nxp_enet_qos_set_config ,
627
661
};
628
662
629
- #define NXP_ENET_QOS_NODE_HAS_MAC_ADDR_CHECK (n ) \
630
- BUILD_ASSERT(NODE_HAS_VALID_MAC_ADDR(DT_DRV_INST(n)) || \
631
- DT_INST_PROP(n, zephyr_random_mac_address), \
632
- "MAC address not specified on ENET QOS DT node");
633
-
634
- #define NXP_ENET_QOS_CONNECT_IRQS (node_id , prop , idx ) \
635
- do { \
636
- IRQ_CONNECT(DT_IRQN_BY_IDX(node_id, idx), \
637
- DT_IRQ_BY_IDX(node_id, idx, priority), \
638
- eth_nxp_enet_qos_mac_isr, \
639
- DEVICE_DT_GET(node_id), \
640
- 0); \
641
- irq_enable(DT_IRQN_BY_IDX(node_id, idx)); \
663
+ #define NXP_ENET_QOS_NODE_HAS_MAC_ADDR_CHECK (n ) \
664
+ BUILD_ASSERT(NODE_HAS_VALID_MAC_ADDR(DT_DRV_INST(n)) || \
665
+ DT_INST_PROP(n, zephyr_random_mac_address) || \
666
+ DT_INST_PROP(n, nxp_unique_mac), \
667
+ "MAC address not specified on ENET QOS DT node");
668
+
669
+ #define NXP_ENET_QOS_MAC_ADDR_SOURCE (n ) \
670
+ COND_CODE_1(DT_NODE_HAS_PROP(DT_DRV_INST(n), local_mac_address), \
671
+ (NXP_ENET_QOS_MAC_ADDR_SOURCE_LOCAL), \
672
+ (COND_CODE_1(DT_INST_PROP(n, zephyr_random_mac_address), \
673
+ (NXP_ENET_QOS_MAC_ADDR_SOURCE_RANDOM), \
674
+ (COND_CODE_1(DT_INST_PROP(n, nxp_unique_mac), \
675
+ (NXP_ENET_QOS_MAC_ADDR_SOURCE_UNIQUE), \
676
+ (NXP_ENET_QOS_MAC_ADDR_SOURCE_INVALID))))))
677
+
678
+ #define NXP_ENET_QOS_CONNECT_IRQS (node_id , prop , idx ) \
679
+ do { \
680
+ IRQ_CONNECT(DT_IRQN_BY_IDX(node_id, idx), DT_IRQ_BY_IDX(node_id, idx, priority), \
681
+ eth_nxp_enet_qos_mac_isr, DEVICE_DT_GET(node_id), 0); \
682
+ irq_enable(DT_IRQN_BY_IDX(node_id, idx)); \
642
683
} while (false);
643
684
644
- #define NXP_ENET_QOS_IRQ_CONFIG_FUNC (n ) \
645
- static void nxp_enet_qos_##n##_irq_config_func(void) \
646
- { \
647
- DT_FOREACH_PROP_ELEM(DT_DRV_INST(n), \
648
- interrupt_names, \
649
- NXP_ENET_QOS_CONNECT_IRQS) \
685
+ #define NXP_ENET_QOS_IRQ_CONFIG_FUNC (n ) \
686
+ static void nxp_enet_qos_##n##_irq_config_func(void) \
687
+ { \
688
+ DT_FOREACH_PROP_ELEM(DT_DRV_INST(n), interrupt_names, NXP_ENET_QOS_CONNECT_IRQS) \
650
689
}
651
-
652
- #define NXP_ENET_QOS_DRIVER_STRUCTS_INIT (n ) \
653
- static const struct nxp_enet_qos_mac_config enet_qos_##n##_mac_config = { \
654
- .enet_dev = DEVICE_DT_GET(DT_INST_PARENT(n)), \
655
- .phy_dev = DEVICE_DT_GET(DT_INST_PHANDLE(n, phy_handle)), \
656
- .base = (enet_qos_t *)DT_REG_ADDR(DT_INST_PARENT(n)), \
657
- .hw_info = { \
658
- .max_frame_len = ENET_QOS_MAX_NORMAL_FRAME_LEN, \
659
- }, \
660
- .irq_config_func = nxp_enet_qos_##n##_irq_config_func, \
661
- .random_mac = DT_INST_PROP(n, zephyr_random_mac_address), \
662
- }; \
663
- \
664
- static struct nxp_enet_qos_mac_data enet_qos_##n##_mac_data = \
665
- { \
666
- .mac_addr.addr = DT_INST_PROP_OR(n, local_mac_address, {0}), \
690
+ #define NXP_ENET_QOS_DRIVER_STRUCTS_INIT (n ) \
691
+ static const struct nxp_enet_qos_mac_config enet_qos_##n##_mac_config = { \
692
+ .enet_dev = DEVICE_DT_GET(DT_INST_PARENT(n)), \
693
+ .phy_dev = DEVICE_DT_GET(DT_INST_PHANDLE(n, phy_handle)), \
694
+ .base = (enet_qos_t *)DT_REG_ADDR(DT_INST_PARENT(n)), \
695
+ .hw_info = \
696
+ { \
697
+ .max_frame_len = ENET_QOS_MAX_NORMAL_FRAME_LEN, \
698
+ }, \
699
+ .irq_config_func = nxp_enet_qos_##n##_irq_config_func, \
700
+ .mac_addr_source = NXP_ENET_QOS_MAC_ADDR_SOURCE(n), \
701
+ }; \
702
+ static struct nxp_enet_qos_mac_data enet_qos_##n##_mac_data = { \
703
+ .mac_addr.addr = DT_INST_PROP_OR(n, local_mac_address, {0}), \
667
704
};
668
705
669
- #define NXP_ENET_QOS_DRIVER_INIT (n ) \
670
- NXP_ENET_QOS_NODE_HAS_MAC_ADDR_CHECK(n) \
671
- NXP_ENET_QOS_IRQ_CONFIG_FUNC(n) \
706
+ #define NXP_ENET_QOS_DRIVER_INIT (n ) \
707
+ NXP_ENET_QOS_NODE_HAS_MAC_ADDR_CHECK(n) \
708
+ NXP_ENET_QOS_IRQ_CONFIG_FUNC(n) \
672
709
NXP_ENET_QOS_DRIVER_STRUCTS_INIT(n)
673
710
674
711
DT_INST_FOREACH_STATUS_OKAY (NXP_ENET_QOS_DRIVER_INIT )
675
712
676
- #define NXP_ENET_QOS_MAC_DEVICE_DEFINE (n ) \
677
- ETH_NET_DEVICE_DT_INST_DEFINE(n, eth_nxp_enet_qos_mac_init, NULL, \
678
- &enet_qos_##n##_mac_data, &enet_qos_##n##_mac_config, \
679
- CONFIG_ETH_INIT_PRIORITY, &api_funcs, NET_ETH_MTU);
713
+ #define NXP_ENET_QOS_MAC_DEVICE_DEFINE (n ) \
714
+ ETH_NET_DEVICE_DT_INST_DEFINE(n, eth_nxp_enet_qos_mac_init, NULL, \
715
+ &enet_qos_##n##_mac_data, &enet_qos_##n##_mac_config, \
716
+ CONFIG_ETH_INIT_PRIORITY, &api_funcs, NET_ETH_MTU);
680
717
681
718
DT_INST_FOREACH_STATUS_OKAY (NXP_ENET_QOS_MAC_DEVICE_DEFINE )
0 commit comments