18
18
#include <zephyr/logging/log.h>
19
19
LOG_MODULE_REGISTER (phy_mii , CONFIG_PHY_LOG_LEVEL );
20
20
21
+ #define ANY_DYNAMIC_LINK UTIL_NOT(DT_ALL_INST_HAS_PROP_STATUS_OKAY(fixed_link))
22
+ #define ANY_FIXED_LINK DT_ANY_INST_HAS_PROP_STATUS_OKAY(fixed_link)
23
+
21
24
struct phy_mii_dev_config {
22
25
uint8_t phy_addr ;
23
26
bool no_reset ;
@@ -30,12 +33,14 @@ struct phy_mii_dev_data {
30
33
const struct device * dev ;
31
34
phy_callback_t cb ;
32
35
void * cb_data ;
33
- struct k_work_delayable monitor_work ;
34
- struct k_work_delayable autoneg_work ;
35
36
struct phy_link_state state ;
36
37
struct k_sem sem ;
38
+ #if ANY_DYNAMIC_LINK
39
+ struct k_work_delayable monitor_work ;
40
+ struct k_work_delayable autoneg_work ;
37
41
bool gigabit_supported ;
38
42
uint32_t autoneg_timeout ;
43
+ #endif
39
44
};
40
45
41
46
/* Offset to align capabilities bits of 1000BASE-T Control and Status regs */
@@ -46,9 +51,9 @@ struct phy_mii_dev_data {
46
51
/* How often to poll auto-negotiation status while waiting for it to complete */
47
52
#define MII_AUTONEG_POLL_INTERVAL_MS 100
48
53
49
- static int phy_mii_get_link_state (const struct device * dev ,
50
- struct phy_link_state * state );
54
+ static void invoke_link_cb (const struct device * dev );
51
55
56
+ #if ANY_DYNAMIC_LINK
52
57
static inline int phy_mii_reg_read (const struct device * dev , uint16_t reg_addr ,
53
58
uint16_t * value )
54
59
{
@@ -284,20 +289,6 @@ static int check_autonegotiation_completion(const struct device *dev)
284
289
return 0 ;
285
290
}
286
291
287
- static void invoke_link_cb (const struct device * dev )
288
- {
289
- struct phy_mii_dev_data * const data = dev -> data ;
290
- struct phy_link_state state ;
291
-
292
- if (data -> cb == NULL ) {
293
- return ;
294
- }
295
-
296
- phy_mii_get_link_state (dev , & state );
297
-
298
- data -> cb (data -> dev , & state , data -> cb_data );
299
- }
300
-
301
292
static void monitor_work_handler (struct k_work * work )
302
293
{
303
294
struct k_work_delayable * dwork = k_work_delayable_from_work (work );
@@ -465,6 +456,7 @@ static int phy_mii_cfg_link(const struct device *dev,
465
456
466
457
return 0 ;
467
458
}
459
+ #endif /* ANY_DYNAMIC_LINK */
468
460
469
461
static int phy_mii_get_link_state (const struct device * dev ,
470
462
struct phy_link_state * state )
@@ -480,6 +472,20 @@ static int phy_mii_get_link_state(const struct device *dev,
480
472
return 0 ;
481
473
}
482
474
475
+ static void invoke_link_cb (const struct device * dev )
476
+ {
477
+ struct phy_mii_dev_data * const data = dev -> data ;
478
+ struct phy_link_state state ;
479
+
480
+ if (data -> cb == NULL ) {
481
+ return ;
482
+ }
483
+
484
+ phy_mii_get_link_state (dev , & state );
485
+
486
+ data -> cb (dev , & state , data -> cb_data );
487
+ }
488
+
483
489
static int phy_mii_link_cb_set (const struct device * dev , phy_callback_t cb ,
484
490
void * user_data )
485
491
{
@@ -497,83 +503,88 @@ static int phy_mii_link_cb_set(const struct device *dev, phy_callback_t cb,
497
503
return 0 ;
498
504
}
499
505
500
- static int phy_mii_initialize (const struct device * dev )
506
+ #if ANY_FIXED_LINK
507
+ static int phy_mii_initialize_fixed_link (const struct device * dev )
501
508
{
502
509
const struct phy_mii_dev_config * const cfg = dev -> config ;
503
510
struct phy_mii_dev_data * const data = dev -> data ;
504
- uint32_t phy_id ;
505
-
506
- k_sem_init (& data -> sem , 1 , 1 );
507
-
508
- data -> dev = dev ;
509
- data -> cb = NULL ;
510
511
511
512
/**
512
513
* If this is a *fixed* link then we don't need to communicate
513
514
* with a PHY. We set the link parameters as configured
514
515
* and set link state to up.
515
516
*/
516
- if (cfg -> fixed ) {
517
- const static int speed_to_phy_link_speed [] = {
518
- LINK_HALF_10BASE ,
519
- LINK_FULL_10BASE ,
520
- LINK_HALF_100BASE ,
521
- LINK_FULL_100BASE ,
522
- LINK_HALF_1000BASE ,
523
- LINK_FULL_1000BASE ,
524
- };
525
-
526
- data -> state .speed = speed_to_phy_link_speed [cfg -> fixed_speed ];
527
- data -> state .is_up = true;
528
- } else {
529
- data -> state .is_up = false;
530
517
531
- mdio_bus_enable (cfg -> mdio );
518
+ const static int speed_to_phy_link_speed [] = {
519
+ LINK_HALF_10BASE ,
520
+ LINK_FULL_10BASE ,
521
+ LINK_HALF_100BASE ,
522
+ LINK_FULL_100BASE ,
523
+ LINK_HALF_1000BASE ,
524
+ LINK_FULL_1000BASE ,
525
+ };
532
526
533
- if (cfg -> no_reset == false) {
534
- reset (dev );
535
- }
527
+ data -> state .speed = speed_to_phy_link_speed [cfg -> fixed_speed ];
528
+ data -> state .is_up = true;
529
+
530
+ return 0 ;
531
+ }
532
+ #endif /* ANY_FIXED_LINK */
533
+
534
+ #if ANY_DYNAMIC_LINK
535
+ static int phy_mii_initialize_dynamic_link (const struct device * dev )
536
+ {
537
+ const struct phy_mii_dev_config * const cfg = dev -> config ;
538
+ struct phy_mii_dev_data * const data = dev -> data ;
539
+ uint32_t phy_id ;
536
540
537
- if (get_id (dev , & phy_id ) == 0 ) {
538
- if (phy_id == MII_INVALID_PHY_ID ) {
539
- LOG_ERR ("No PHY found at address %d" ,
540
- cfg -> phy_addr );
541
+ data -> state .is_up = false;
541
542
542
- return - EINVAL ;
543
- }
543
+ mdio_bus_enable (cfg -> mdio );
544
544
545
- LOG_INF ("PHY (%d) ID %X" , cfg -> phy_addr , phy_id );
545
+ if (cfg -> no_reset == false) {
546
+ reset (dev );
547
+ }
548
+
549
+ if (get_id (dev , & phy_id ) == 0 ) {
550
+ if (phy_id == MII_INVALID_PHY_ID ) {
551
+ LOG_ERR ("No PHY found at address %d" , cfg -> phy_addr );
552
+
553
+ return - EINVAL ;
546
554
}
547
555
548
- data -> gigabit_supported = is_gigabit_supported (dev );
556
+ LOG_INF ("PHY (%d) ID %X" , cfg -> phy_addr , phy_id );
557
+ }
558
+
559
+ data -> gigabit_supported = is_gigabit_supported (dev );
549
560
550
- /* Advertise all speeds */
551
- phy_mii_cfg_link (dev , LINK_HALF_10BASE |
552
- LINK_FULL_10BASE |
553
- LINK_HALF_100BASE |
554
- LINK_FULL_100BASE |
555
- LINK_HALF_1000BASE |
556
- LINK_FULL_1000BASE );
561
+ /* Advertise all speeds */
562
+ phy_mii_cfg_link (dev , LINK_HALF_10BASE |
563
+ LINK_FULL_10BASE |
564
+ LINK_HALF_100BASE |
565
+ LINK_FULL_100BASE |
566
+ LINK_HALF_1000BASE |
567
+ LINK_FULL_1000BASE );
557
568
558
- k_work_init_delayable (& data -> monitor_work ,
559
- monitor_work_handler );
560
- k_work_init_delayable (& data -> autoneg_work ,
561
- autoneg_work_handler );
569
+ k_work_init_delayable (& data -> monitor_work , monitor_work_handler );
570
+ k_work_init_delayable (& data -> autoneg_work , autoneg_work_handler );
562
571
563
- monitor_work_handler (& data -> monitor_work .work );
564
- }
572
+ monitor_work_handler (& data -> monitor_work .work );
565
573
566
574
return 0 ;
567
575
}
576
+ #endif /* ANY_DYNAMIC_LINK */
568
577
569
578
#define IS_FIXED_LINK (n ) DT_INST_NODE_HAS_PROP(n, fixed_link)
570
579
571
580
static DEVICE_API (ethphy , phy_mii_driver_api ) = {
572
581
.get_link = phy_mii_get_link_state ,
573
- .cfg_link = phy_mii_cfg_link ,
574
582
.link_cb_set = phy_mii_link_cb_set ,
583
+ #if ANY_DYNAMIC_LINK
584
+ .cfg_link = phy_mii_cfg_link ,
575
585
.read = phy_mii_read ,
576
586
.write = phy_mii_write ,
587
+ #endif
577
588
};
578
589
579
590
#define PHY_MII_CONFIG (n ) \
@@ -586,11 +597,22 @@ static const struct phy_mii_dev_config phy_mii_dev_config_##n = { \
586
597
DEVICE_DT_GET(DT_INST_BUS(n))) \
587
598
};
588
599
600
+ #define PHY_MII_DATA (n ) \
601
+ static struct phy_mii_dev_data phy_mii_dev_data_##n = { \
602
+ .dev = DEVICE_DT_INST_GET(n), \
603
+ .cb = NULL, \
604
+ .sem = Z_SEM_INITIALIZER(phy_mii_dev_data_##n.sem, 1, 1), \
605
+ };
606
+
607
+ #define PHY_MII_INIT (n ) \
608
+ COND_CODE_1(IS_FIXED_LINK(n), (&phy_mii_initialize_fixed_link), \
609
+ (&phy_mii_initialize_dynamic_link))
610
+
589
611
#define PHY_MII_DEVICE (n ) \
590
612
PHY_MII_CONFIG(n); \
591
- static struct phy_mii_dev_data phy_mii_dev_data_##n; \
613
+ PHY_MII_DATA(n); \
592
614
DEVICE_DT_INST_DEFINE(n, \
593
- &phy_mii_initialize, \
615
+ PHY_MII_INIT(n), \
594
616
NULL, \
595
617
&phy_mii_dev_data_##n, \
596
618
&phy_mii_dev_config_##n, POST_KERNEL, \
0 commit comments