68
68
#define ADIN1300_EEE_CAP_REG 0x8000
69
69
#define ADIN1300_EEE_ADV_REG 0x8001
70
70
#define ADIN1300_EEE_LPABLE_REG 0x8002
71
+
72
+ #define ADIN1300_FLD_EN_REG 0x8E27
73
+ #define ADIN1300_FLD_PCS_ERR_100_EN BIT(7)
74
+ #define ADIN1300_FLD_PCS_ERR_1000_EN BIT(6)
75
+ #define ADIN1300_FLD_SLCR_OUT_STUCK_100_EN BIT(5)
76
+ #define ADIN1300_FLD_SLCR_OUT_STUCK_1000_EN BIT(4)
77
+ #define ADIN1300_FLD_SLCR_IN_ZDET_100_EN BIT(3)
78
+ #define ADIN1300_FLD_SLCR_IN_ZDET_1000_EN BIT(2)
79
+ #define ADIN1300_FLD_SLCR_IN_INVLD_100_EN BIT(1)
80
+ #define ADIN1300_FLD_SLCR_IN_INVLD_1000_EN BIT(0)
81
+ /* These bits are the ones which are enabled by default. */
82
+ #define ADIN1300_FLD_EN_ON \
83
+ (ADIN1300_FLD_SLCR_OUT_STUCK_100_EN | \
84
+ ADIN1300_FLD_SLCR_OUT_STUCK_1000_EN | \
85
+ ADIN1300_FLD_SLCR_IN_ZDET_100_EN | \
86
+ ADIN1300_FLD_SLCR_IN_ZDET_1000_EN | \
87
+ ADIN1300_FLD_SLCR_IN_INVLD_1000_EN)
88
+
71
89
#define ADIN1300_CLOCK_STOP_REG 0x9400
72
90
#define ADIN1300_LPI_WAKE_ERR_CNT_REG 0xa000
73
91
@@ -416,6 +434,37 @@ static int adin_set_edpd(struct phy_device *phydev, u16 tx_interval)
416
434
val );
417
435
}
418
436
437
+ static int adin_get_fast_down (struct phy_device * phydev , u8 * msecs )
438
+ {
439
+ int reg ;
440
+
441
+ reg = phy_read_mmd (phydev , MDIO_MMD_VEND1 , ADIN1300_FLD_EN_REG );
442
+ if (reg < 0 )
443
+ return reg ;
444
+
445
+ if (reg & ADIN1300_FLD_EN_ON )
446
+ * msecs = ETHTOOL_PHY_FAST_LINK_DOWN_ON ;
447
+ else
448
+ * msecs = ETHTOOL_PHY_FAST_LINK_DOWN_OFF ;
449
+
450
+ return 0 ;
451
+ }
452
+
453
+ static int adin_set_fast_down (struct phy_device * phydev , const u8 * msecs )
454
+ {
455
+ if (* msecs == ETHTOOL_PHY_FAST_LINK_DOWN_ON )
456
+ return phy_set_bits_mmd (phydev , MDIO_MMD_VEND1 ,
457
+ ADIN1300_FLD_EN_REG ,
458
+ ADIN1300_FLD_EN_ON );
459
+
460
+ if (* msecs == ETHTOOL_PHY_FAST_LINK_DOWN_OFF )
461
+ return phy_clear_bits_mmd (phydev , MDIO_MMD_VEND1 ,
462
+ ADIN1300_FLD_EN_REG ,
463
+ ADIN1300_FLD_EN_ON );
464
+
465
+ return - EINVAL ;
466
+ }
467
+
419
468
static int adin_get_tunable (struct phy_device * phydev ,
420
469
struct ethtool_tunable * tuna , void * data )
421
470
{
@@ -424,6 +473,8 @@ static int adin_get_tunable(struct phy_device *phydev,
424
473
return adin_get_downshift (phydev , data );
425
474
case ETHTOOL_PHY_EDPD :
426
475
return adin_get_edpd (phydev , data );
476
+ case ETHTOOL_PHY_FAST_LINK_DOWN :
477
+ return adin_get_fast_down (phydev , data );
427
478
default :
428
479
return - EOPNOTSUPP ;
429
480
}
@@ -437,6 +488,8 @@ static int adin_set_tunable(struct phy_device *phydev,
437
488
return adin_set_downshift (phydev , * (const u8 * )data );
438
489
case ETHTOOL_PHY_EDPD :
439
490
return adin_set_edpd (phydev , * (const u16 * )data );
491
+ case ETHTOOL_PHY_FAST_LINK_DOWN :
492
+ return adin_set_fast_down (phydev , data );
440
493
default :
441
494
return - EOPNOTSUPP ;
442
495
}
0 commit comments