@@ -466,6 +466,12 @@ struct lan8842_priv {
466466 u16 rev ;
467467};
468468
469+ struct lanphy_reg_data {
470+ int page ;
471+ u16 addr ;
472+ u16 val ;
473+ };
474+
469475static const struct kszphy_type lan8814_type = {
470476 .led_mode_reg = ~LAN8814_LED_CTRL_1 ,
471477 .cable_diag_reg = LAN8814_CABLE_DIAG ,
@@ -2835,6 +2841,13 @@ static int ksz886x_cable_test_get_status(struct phy_device *phydev,
28352841 */
28362842#define LAN8814_PAGE_PCS_DIGITAL 2
28372843
2844+ /**
2845+ * LAN8814_PAGE_EEE - Selects Extended Page 3.
2846+ *
2847+ * This page contains EEE registers
2848+ */
2849+ #define LAN8814_PAGE_EEE 3
2850+
28382851/**
28392852 * LAN8814_PAGE_COMMON_REGS - Selects Extended Page 4.
28402853 *
@@ -2853,6 +2866,13 @@ static int ksz886x_cable_test_get_status(struct phy_device *phydev,
28532866 */
28542867#define LAN8814_PAGE_PORT_REGS 5
28552868
2869+ /**
2870+ * LAN8814_PAGE_POWER_REGS - Selects Extended Page 28.
2871+ *
2872+ * This page contains analog control registers and power mode registers.
2873+ */
2874+ #define LAN8814_PAGE_POWER_REGS 28
2875+
28562876/**
28572877 * LAN8814_PAGE_SYSTEM_CTRL - Selects Extended Page 31.
28582878 *
@@ -5884,6 +5904,144 @@ static int lan8842_probe(struct phy_device *phydev)
58845904 return 0 ;
58855905}
58865906
5907+ #define LAN8814_POWER_MGMT_MODE_3_ANEG_MDI 0x13
5908+ #define LAN8814_POWER_MGMT_MODE_4_ANEG_MDIX 0x14
5909+ #define LAN8814_POWER_MGMT_MODE_5_10BT_MDI 0x15
5910+ #define LAN8814_POWER_MGMT_MODE_6_10BT_MDIX 0x16
5911+ #define LAN8814_POWER_MGMT_MODE_7_100BT_TRAIN 0x17
5912+ #define LAN8814_POWER_MGMT_MODE_8_100BT_MDI 0x18
5913+ #define LAN8814_POWER_MGMT_MODE_9_100BT_EEE_MDI_TX 0x19
5914+ #define LAN8814_POWER_MGMT_MODE_10_100BT_EEE_MDI_RX 0x1a
5915+ #define LAN8814_POWER_MGMT_MODE_11_100BT_MDIX 0x1b
5916+ #define LAN8814_POWER_MGMT_MODE_12_100BT_EEE_MDIX_TX 0x1c
5917+ #define LAN8814_POWER_MGMT_MODE_13_100BT_EEE_MDIX_RX 0x1d
5918+ #define LAN8814_POWER_MGMT_MODE_14_100BTX_EEE_TX_RX 0x1e
5919+
5920+ #define LAN8814_POWER_MGMT_DLLPD_D BIT(0)
5921+ #define LAN8814_POWER_MGMT_ADCPD_D BIT(1)
5922+ #define LAN8814_POWER_MGMT_PGAPD_D BIT(2)
5923+ #define LAN8814_POWER_MGMT_TXPD_D BIT(3)
5924+ #define LAN8814_POWER_MGMT_DLLPD_C BIT(4)
5925+ #define LAN8814_POWER_MGMT_ADCPD_C BIT(5)
5926+ #define LAN8814_POWER_MGMT_PGAPD_C BIT(6)
5927+ #define LAN8814_POWER_MGMT_TXPD_C BIT(7)
5928+ #define LAN8814_POWER_MGMT_DLLPD_B BIT(8)
5929+ #define LAN8814_POWER_MGMT_ADCPD_B BIT(9)
5930+ #define LAN8814_POWER_MGMT_PGAPD_B BIT(10)
5931+ #define LAN8814_POWER_MGMT_TXPD_B BIT(11)
5932+ #define LAN8814_POWER_MGMT_DLLPD_A BIT(12)
5933+ #define LAN8814_POWER_MGMT_ADCPD_A BIT(13)
5934+ #define LAN8814_POWER_MGMT_PGAPD_A BIT(14)
5935+ #define LAN8814_POWER_MGMT_TXPD_A BIT(15)
5936+
5937+ #define LAN8814_POWER_MGMT_C_D (LAN8814_POWER_MGMT_DLLPD_D | \
5938+ LAN8814_POWER_MGMT_ADCPD_D | \
5939+ LAN8814_POWER_MGMT_PGAPD_D | \
5940+ LAN8814_POWER_MGMT_DLLPD_C | \
5941+ LAN8814_POWER_MGMT_ADCPD_C | \
5942+ LAN8814_POWER_MGMT_PGAPD_C)
5943+
5944+ #define LAN8814_POWER_MGMT_B_C_D (LAN8814_POWER_MGMT_C_D | \
5945+ LAN8814_POWER_MGMT_DLLPD_B | \
5946+ LAN8814_POWER_MGMT_ADCPD_B | \
5947+ LAN8814_POWER_MGMT_PGAPD_B)
5948+
5949+ #define LAN8814_POWER_MGMT_VAL1 (LAN8814_POWER_MGMT_C_D | \
5950+ LAN8814_POWER_MGMT_ADCPD_B | \
5951+ LAN8814_POWER_MGMT_PGAPD_B | \
5952+ LAN8814_POWER_MGMT_ADCPD_A | \
5953+ LAN8814_POWER_MGMT_PGAPD_A)
5954+
5955+ #define LAN8814_POWER_MGMT_VAL2 LAN8814_POWER_MGMT_C_D
5956+
5957+ #define LAN8814_POWER_MGMT_VAL3 (LAN8814_POWER_MGMT_C_D | \
5958+ LAN8814_POWER_MGMT_DLLPD_B | \
5959+ LAN8814_POWER_MGMT_ADCPD_B | \
5960+ LAN8814_POWER_MGMT_PGAPD_A)
5961+
5962+ #define LAN8814_POWER_MGMT_VAL4 (LAN8814_POWER_MGMT_B_C_D | \
5963+ LAN8814_POWER_MGMT_ADCPD_A | \
5964+ LAN8814_POWER_MGMT_PGAPD_A)
5965+
5966+ #define LAN8814_POWER_MGMT_VAL5 LAN8814_POWER_MGMT_B_C_D
5967+
5968+ #define LAN8814_EEE_WAKE_TX_TIMER 0x0e
5969+ #define LAN8814_EEE_WAKE_TX_TIMER_MAX_VAL 0x1f
5970+
5971+ static const struct lanphy_reg_data short_center_tap_errata [] = {
5972+ { LAN8814_PAGE_POWER_REGS ,
5973+ LAN8814_POWER_MGMT_MODE_3_ANEG_MDI ,
5974+ LAN8814_POWER_MGMT_VAL1 },
5975+ { LAN8814_PAGE_POWER_REGS ,
5976+ LAN8814_POWER_MGMT_MODE_4_ANEG_MDIX ,
5977+ LAN8814_POWER_MGMT_VAL1 },
5978+ { LAN8814_PAGE_POWER_REGS ,
5979+ LAN8814_POWER_MGMT_MODE_5_10BT_MDI ,
5980+ LAN8814_POWER_MGMT_VAL1 },
5981+ { LAN8814_PAGE_POWER_REGS ,
5982+ LAN8814_POWER_MGMT_MODE_6_10BT_MDIX ,
5983+ LAN8814_POWER_MGMT_VAL1 },
5984+ { LAN8814_PAGE_POWER_REGS ,
5985+ LAN8814_POWER_MGMT_MODE_7_100BT_TRAIN ,
5986+ LAN8814_POWER_MGMT_VAL2 },
5987+ { LAN8814_PAGE_POWER_REGS ,
5988+ LAN8814_POWER_MGMT_MODE_8_100BT_MDI ,
5989+ LAN8814_POWER_MGMT_VAL3 },
5990+ { LAN8814_PAGE_POWER_REGS ,
5991+ LAN8814_POWER_MGMT_MODE_9_100BT_EEE_MDI_TX ,
5992+ LAN8814_POWER_MGMT_VAL3 },
5993+ { LAN8814_PAGE_POWER_REGS ,
5994+ LAN8814_POWER_MGMT_MODE_10_100BT_EEE_MDI_RX ,
5995+ LAN8814_POWER_MGMT_VAL4 },
5996+ { LAN8814_PAGE_POWER_REGS ,
5997+ LAN8814_POWER_MGMT_MODE_11_100BT_MDIX ,
5998+ LAN8814_POWER_MGMT_VAL5 },
5999+ { LAN8814_PAGE_POWER_REGS ,
6000+ LAN8814_POWER_MGMT_MODE_12_100BT_EEE_MDIX_TX ,
6001+ LAN8814_POWER_MGMT_VAL5 },
6002+ { LAN8814_PAGE_POWER_REGS ,
6003+ LAN8814_POWER_MGMT_MODE_13_100BT_EEE_MDIX_RX ,
6004+ LAN8814_POWER_MGMT_VAL4 },
6005+ { LAN8814_PAGE_POWER_REGS ,
6006+ LAN8814_POWER_MGMT_MODE_14_100BTX_EEE_TX_RX ,
6007+ LAN8814_POWER_MGMT_VAL4 },
6008+ };
6009+
6010+ static const struct lanphy_reg_data waketx_timer_errata [] = {
6011+ { LAN8814_PAGE_EEE ,
6012+ LAN8814_EEE_WAKE_TX_TIMER ,
6013+ LAN8814_EEE_WAKE_TX_TIMER_MAX_VAL },
6014+ };
6015+
6016+ static int lanphy_write_reg_data (struct phy_device * phydev ,
6017+ const struct lanphy_reg_data * data ,
6018+ size_t num )
6019+ {
6020+ int ret = 0 ;
6021+
6022+ while (num -- ) {
6023+ ret = lanphy_write_page_reg (phydev , data -> page , data -> addr ,
6024+ data -> val );
6025+ if (ret )
6026+ break ;
6027+ }
6028+
6029+ return ret ;
6030+ }
6031+
6032+ static int lan8842_erratas (struct phy_device * phydev )
6033+ {
6034+ int ret ;
6035+
6036+ ret = lanphy_write_reg_data (phydev , short_center_tap_errata ,
6037+ ARRAY_SIZE (short_center_tap_errata ));
6038+ if (ret )
6039+ return ret ;
6040+
6041+ return lanphy_write_reg_data (phydev , waketx_timer_errata ,
6042+ ARRAY_SIZE (waketx_timer_errata ));
6043+ }
6044+
58876045static int lan8842_config_init (struct phy_device * phydev )
58886046{
58896047 int ret ;
@@ -5896,6 +6054,11 @@ static int lan8842_config_init(struct phy_device *phydev)
58966054 if (ret < 0 )
58976055 return ret ;
58986056
6057+ /* Apply the erratas for this device */
6058+ ret = lan8842_erratas (phydev );
6059+ if (ret < 0 )
6060+ return ret ;
6061+
58996062 /* Even if the GPIOs are set to control the LEDs the behaviour of the
59006063 * LEDs is wrong, they are not blinking when there is traffic.
59016064 * To fix this it is required to set extended LED mode
0 commit comments