|
27 | 27 | #define DP83TD510E_AN_STAT_1 0x60c
|
28 | 28 | #define DP83TD510E_MASTER_SLAVE_RESOL_FAIL BIT(15)
|
29 | 29 |
|
| 30 | +#define DP83TD510E_MSE_DETECT 0xa85 |
| 31 | + |
| 32 | +#define DP83TD510_SQI_MAX 7 |
| 33 | + |
| 34 | +/* Register values are converted to SNR(dB) as suggested by |
| 35 | + * "Application Report - DP83TD510E Cable Diagnostics Toolkit": |
| 36 | + * SNR(dB) = -10 * log10 (VAL/2^17) - 1.76 dB. |
| 37 | + * SQI ranges are implemented according to "OPEN ALLIANCE - Advanced diagnostic |
| 38 | + * features for 100BASE-T1 automotive Ethernet PHYs" |
| 39 | + */ |
| 40 | +static const u16 dp83td510_mse_sqi_map[] = { |
| 41 | + 0x0569, /* < 18dB */ |
| 42 | + 0x044c, /* 18dB =< SNR < 19dB */ |
| 43 | + 0x0369, /* 19dB =< SNR < 20dB */ |
| 44 | + 0x02b6, /* 20dB =< SNR < 21dB */ |
| 45 | + 0x0227, /* 21dB =< SNR < 22dB */ |
| 46 | + 0x01b6, /* 22dB =< SNR < 23dB */ |
| 47 | + 0x015b, /* 23dB =< SNR < 24dB */ |
| 48 | + 0x0000 /* 24dB =< SNR */ |
| 49 | +}; |
| 50 | + |
30 | 51 | static int dp83td510_config_intr(struct phy_device *phydev)
|
31 | 52 | {
|
32 | 53 | int ret;
|
@@ -164,6 +185,32 @@ static int dp83td510_config_aneg(struct phy_device *phydev)
|
164 | 185 | return genphy_c45_check_and_restart_aneg(phydev, changed);
|
165 | 186 | }
|
166 | 187 |
|
| 188 | +static int dp83td510_get_sqi(struct phy_device *phydev) |
| 189 | +{ |
| 190 | + int sqi, ret; |
| 191 | + u16 mse_val; |
| 192 | + |
| 193 | + if (!phydev->link) |
| 194 | + return 0; |
| 195 | + |
| 196 | + ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_MSE_DETECT); |
| 197 | + if (ret < 0) |
| 198 | + return ret; |
| 199 | + |
| 200 | + mse_val = 0xFFFF & ret; |
| 201 | + for (sqi = 0; sqi < ARRAY_SIZE(dp83td510_mse_sqi_map); sqi++) { |
| 202 | + if (mse_val >= dp83td510_mse_sqi_map[sqi]) |
| 203 | + return sqi; |
| 204 | + } |
| 205 | + |
| 206 | + return -EINVAL; |
| 207 | +} |
| 208 | + |
| 209 | +static int dp83td510_get_sqi_max(struct phy_device *phydev) |
| 210 | +{ |
| 211 | + return DP83TD510_SQI_MAX; |
| 212 | +} |
| 213 | + |
167 | 214 | static int dp83td510_get_features(struct phy_device *phydev)
|
168 | 215 | {
|
169 | 216 | /* This PHY can't respond on MDIO bus if no RMII clock is enabled.
|
@@ -192,6 +239,8 @@ static struct phy_driver dp83td510_driver[] = {
|
192 | 239 | .get_features = dp83td510_get_features,
|
193 | 240 | .config_intr = dp83td510_config_intr,
|
194 | 241 | .handle_interrupt = dp83td510_handle_interrupt,
|
| 242 | + .get_sqi = dp83td510_get_sqi, |
| 243 | + .get_sqi_max = dp83td510_get_sqi_max, |
195 | 244 |
|
196 | 245 | .suspend = genphy_suspend,
|
197 | 246 | .resume = genphy_resume,
|
|
0 commit comments