1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (C) 2018 Microchip Technology 3 4 #include <linux/kernel.h> 5 #include <linux/module.h> 6 #include <linux/delay.h> 7 #include <linux/mii.h> 8 #include <linux/phy.h> 9 #include <linux/ethtool.h> 10 #include <linux/ethtool_netlink.h> 11 #include <linux/bitfield.h> 12 13 #define PHY_ID_LAN87XX 0x0007c150 14 #define PHY_ID_LAN937X 0x0007c180 15 16 /* External Register Control Register */ 17 #define LAN87XX_EXT_REG_CTL (0x14) 18 #define LAN87XX_EXT_REG_CTL_RD_CTL (0x1000) 19 #define LAN87XX_EXT_REG_CTL_WR_CTL (0x0800) 20 #define LAN87XX_REG_BANK_SEL_MASK GENMASK(10, 8) 21 #define LAN87XX_REG_ADDR_MASK GENMASK(7, 0) 22 23 /* External Register Read Data Register */ 24 #define LAN87XX_EXT_REG_RD_DATA (0x15) 25 26 /* External Register Write Data Register */ 27 #define LAN87XX_EXT_REG_WR_DATA (0x16) 28 29 /* Interrupt Source Register */ 30 #define LAN87XX_INTERRUPT_SOURCE (0x18) 31 #define LAN87XX_INTERRUPT_SOURCE_2 (0x08) 32 33 /* Interrupt Mask Register */ 34 #define LAN87XX_INTERRUPT_MASK (0x19) 35 #define LAN87XX_MASK_LINK_UP (0x0004) 36 #define LAN87XX_MASK_LINK_DOWN (0x0002) 37 38 #define LAN87XX_INTERRUPT_MASK_2 (0x09) 39 #define LAN87XX_MASK_COMM_RDY BIT(10) 40 41 /* MISC Control 1 Register */ 42 #define LAN87XX_CTRL_1 (0x11) 43 #define LAN87XX_MASK_RGMII_TXC_DLY_EN (0x4000) 44 #define LAN87XX_MASK_RGMII_RXC_DLY_EN (0x2000) 45 46 /* phyaccess nested types */ 47 #define PHYACC_ATTR_MODE_READ 0 48 #define PHYACC_ATTR_MODE_WRITE 1 49 #define PHYACC_ATTR_MODE_MODIFY 2 50 #define PHYACC_ATTR_MODE_POLL 3 51 52 #define PHYACC_ATTR_BANK_SMI 0 53 #define PHYACC_ATTR_BANK_MISC 1 54 #define PHYACC_ATTR_BANK_PCS 2 55 #define PHYACC_ATTR_BANK_AFE 3 56 #define PHYACC_ATTR_BANK_DSP 4 57 #define PHYACC_ATTR_BANK_MAX 7 58 59 /* measurement defines */ 60 #define LAN87XX_CABLE_TEST_OK 0 61 #define LAN87XX_CABLE_TEST_OPEN 1 62 #define LAN87XX_CABLE_TEST_SAME_SHORT 2 63 64 /* T1 Registers */ 65 #define T1_AFE_PORT_CFG1_REG 0x0B 66 #define T1_POWER_DOWN_CONTROL_REG 0x1A 67 #define T1_SLV_FD_MULT_CFG_REG 0x18 68 #define T1_CDR_CFG_PRE_LOCK_REG 0x05 69 #define T1_CDR_CFG_POST_LOCK_REG 0x06 70 #define T1_LCK_STG2_MUFACT_CFG_REG 0x1A 71 #define T1_LCK_STG3_MUFACT_CFG_REG 0x1B 72 #define T1_POST_LCK_MUFACT_CFG_REG 0x1C 73 #define T1_TX_RX_FIFO_CFG_REG 0x02 74 #define T1_TX_LPF_FIR_CFG_REG 0x55 75 #define T1_COEF_CLK_PWR_DN_CFG 0x04 76 #define T1_COEF_RW_CTL_CFG 0x0D 77 #define T1_SQI_CONFIG_REG 0x2E 78 #define T1_SQI_CONFIG2_REG 0x4A 79 #define T1_DCQ_SQI_REG 0xC3 80 #define T1_DCQ_SQI_MSK GENMASK(3, 1) 81 #define T1_MDIO_CONTROL2_REG 0x10 82 #define T1_INTERRUPT_SOURCE_REG 0x18 83 #define T1_INTERRUPT2_SOURCE_REG 0x08 84 #define T1_EQ_FD_STG1_FRZ_CFG 0x69 85 #define T1_EQ_FD_STG2_FRZ_CFG 0x6A 86 #define T1_EQ_FD_STG3_FRZ_CFG 0x6B 87 #define T1_EQ_FD_STG4_FRZ_CFG 0x6C 88 #define T1_EQ_WT_FD_LCK_FRZ_CFG 0x6D 89 #define T1_PST_EQ_LCK_STG1_FRZ_CFG 0x6E 90 91 #define T1_MODE_STAT_REG 0x11 92 #define T1_LINK_UP_MSK BIT(0) 93 94 /* SQI defines */ 95 #define LAN87XX_MAX_SQI 0x07 96 97 #define DRIVER_AUTHOR "Nisar Sayed <nisar.sayed@microchip.com>" 98 #define DRIVER_DESC "Microchip LAN87XX/LAN937x T1 PHY driver" 99 100 struct access_ereg_val { 101 u8 mode; 102 u8 bank; 103 u8 offset; 104 u16 val; 105 u16 mask; 106 }; 107 108 static int lan937x_dsp_workaround(struct phy_device *phydev, u16 ereg, u8 bank) 109 { 110 u8 prev_bank; 111 int rc = 0; 112 u16 val; 113 114 mutex_lock(&phydev->lock); 115 /* Read previous selected bank */ 116 rc = phy_read(phydev, LAN87XX_EXT_REG_CTL); 117 if (rc < 0) 118 goto out_unlock; 119 120 /* store the prev_bank */ 121 prev_bank = FIELD_GET(LAN87XX_REG_BANK_SEL_MASK, rc); 122 123 if (bank != prev_bank && bank == PHYACC_ATTR_BANK_DSP) { 124 val = ereg & ~LAN87XX_REG_ADDR_MASK; 125 126 val &= ~LAN87XX_EXT_REG_CTL_WR_CTL; 127 val |= LAN87XX_EXT_REG_CTL_RD_CTL; 128 129 /* access twice for DSP bank change,dummy access */ 130 rc = phy_write(phydev, LAN87XX_EXT_REG_CTL, val); 131 } 132 133 out_unlock: 134 mutex_unlock(&phydev->lock); 135 136 return rc; 137 } 138 139 static int access_ereg(struct phy_device *phydev, u8 mode, u8 bank, 140 u8 offset, u16 val) 141 { 142 u16 ereg = 0; 143 int rc = 0; 144 145 if (mode > PHYACC_ATTR_MODE_WRITE || bank > PHYACC_ATTR_BANK_MAX) 146 return -EINVAL; 147 148 if (bank == PHYACC_ATTR_BANK_SMI) { 149 if (mode == PHYACC_ATTR_MODE_WRITE) 150 rc = phy_write(phydev, offset, val); 151 else 152 rc = phy_read(phydev, offset); 153 return rc; 154 } 155 156 if (mode == PHYACC_ATTR_MODE_WRITE) { 157 ereg = LAN87XX_EXT_REG_CTL_WR_CTL; 158 rc = phy_write(phydev, LAN87XX_EXT_REG_WR_DATA, val); 159 if (rc < 0) 160 return rc; 161 } else { 162 ereg = LAN87XX_EXT_REG_CTL_RD_CTL; 163 } 164 165 ereg |= (bank << 8) | offset; 166 167 /* DSP bank access workaround for lan937x */ 168 if (phydev->phy_id == PHY_ID_LAN937X) { 169 rc = lan937x_dsp_workaround(phydev, ereg, bank); 170 if (rc < 0) 171 return rc; 172 } 173 174 rc = phy_write(phydev, LAN87XX_EXT_REG_CTL, ereg); 175 if (rc < 0) 176 return rc; 177 178 if (mode == PHYACC_ATTR_MODE_READ) 179 rc = phy_read(phydev, LAN87XX_EXT_REG_RD_DATA); 180 181 return rc; 182 } 183 184 static int access_ereg_modify_changed(struct phy_device *phydev, 185 u8 bank, u8 offset, u16 val, u16 mask) 186 { 187 int new = 0, rc = 0; 188 189 if (bank > PHYACC_ATTR_BANK_MAX) 190 return -EINVAL; 191 192 rc = access_ereg(phydev, PHYACC_ATTR_MODE_READ, bank, offset, val); 193 if (rc < 0) 194 return rc; 195 196 new = val | (rc & (mask ^ 0xFFFF)); 197 rc = access_ereg(phydev, PHYACC_ATTR_MODE_WRITE, bank, offset, new); 198 199 return rc; 200 } 201 202 static int access_smi_poll_timeout(struct phy_device *phydev, 203 u8 offset, u16 mask, u16 clr) 204 { 205 int val; 206 207 return phy_read_poll_timeout(phydev, offset, val, (val & mask) == clr, 208 150, 30000, true); 209 } 210 211 static int lan87xx_config_rgmii_delay(struct phy_device *phydev) 212 { 213 int rc; 214 215 if (!phy_interface_is_rgmii(phydev)) 216 return 0; 217 218 rc = access_ereg(phydev, PHYACC_ATTR_MODE_READ, 219 PHYACC_ATTR_BANK_MISC, LAN87XX_CTRL_1, 0); 220 if (rc < 0) 221 return rc; 222 223 switch (phydev->interface) { 224 case PHY_INTERFACE_MODE_RGMII: 225 rc &= ~LAN87XX_MASK_RGMII_TXC_DLY_EN; 226 rc &= ~LAN87XX_MASK_RGMII_RXC_DLY_EN; 227 break; 228 case PHY_INTERFACE_MODE_RGMII_ID: 229 rc |= LAN87XX_MASK_RGMII_TXC_DLY_EN; 230 rc |= LAN87XX_MASK_RGMII_RXC_DLY_EN; 231 break; 232 case PHY_INTERFACE_MODE_RGMII_RXID: 233 rc &= ~LAN87XX_MASK_RGMII_TXC_DLY_EN; 234 rc |= LAN87XX_MASK_RGMII_RXC_DLY_EN; 235 break; 236 case PHY_INTERFACE_MODE_RGMII_TXID: 237 rc |= LAN87XX_MASK_RGMII_TXC_DLY_EN; 238 rc &= ~LAN87XX_MASK_RGMII_RXC_DLY_EN; 239 break; 240 default: 241 return 0; 242 } 243 244 return access_ereg(phydev, PHYACC_ATTR_MODE_WRITE, 245 PHYACC_ATTR_BANK_MISC, LAN87XX_CTRL_1, rc); 246 } 247 248 static int lan87xx_phy_init_cmd(struct phy_device *phydev, 249 const struct access_ereg_val *cmd_seq, int cnt) 250 { 251 int ret, i; 252 253 for (i = 0; i < cnt; i++) { 254 if (cmd_seq[i].mode == PHYACC_ATTR_MODE_POLL && 255 cmd_seq[i].bank == PHYACC_ATTR_BANK_SMI) { 256 ret = access_smi_poll_timeout(phydev, 257 cmd_seq[i].offset, 258 cmd_seq[i].val, 259 cmd_seq[i].mask); 260 } else { 261 ret = access_ereg(phydev, cmd_seq[i].mode, 262 cmd_seq[i].bank, cmd_seq[i].offset, 263 cmd_seq[i].val); 264 } 265 if (ret < 0) 266 return ret; 267 } 268 269 return ret; 270 } 271 272 static int lan87xx_phy_init(struct phy_device *phydev) 273 { 274 static const struct access_ereg_val hw_init[] = { 275 /* TXPD/TXAMP6 Configs */ 276 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_AFE, 277 T1_AFE_PORT_CFG1_REG, 0x002D, 0 }, 278 /* HW_Init Hi and Force_ED */ 279 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_SMI, 280 T1_POWER_DOWN_CONTROL_REG, 0x0308, 0 }, 281 }; 282 283 static const struct access_ereg_val slave_init[] = { 284 /* Equalizer Full Duplex Freeze - T1 Slave */ 285 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 286 T1_EQ_FD_STG1_FRZ_CFG, 0x0002, 0 }, 287 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 288 T1_EQ_FD_STG2_FRZ_CFG, 0x0002, 0 }, 289 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 290 T1_EQ_FD_STG3_FRZ_CFG, 0x0002, 0 }, 291 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 292 T1_EQ_FD_STG4_FRZ_CFG, 0x0002, 0 }, 293 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 294 T1_EQ_WT_FD_LCK_FRZ_CFG, 0x0002, 0 }, 295 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 296 T1_PST_EQ_LCK_STG1_FRZ_CFG, 0x0002, 0 }, 297 }; 298 299 static const struct access_ereg_val phy_init[] = { 300 /* Slave Full Duplex Multi Configs */ 301 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 302 T1_SLV_FD_MULT_CFG_REG, 0x0D53, 0 }, 303 /* CDR Pre and Post Lock Configs */ 304 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 305 T1_CDR_CFG_PRE_LOCK_REG, 0x0AB2, 0 }, 306 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 307 T1_CDR_CFG_POST_LOCK_REG, 0x0AB3, 0 }, 308 /* Lock Stage 2-3 Multi Factor Config */ 309 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 310 T1_LCK_STG2_MUFACT_CFG_REG, 0x0AEA, 0 }, 311 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 312 T1_LCK_STG3_MUFACT_CFG_REG, 0x0AEB, 0 }, 313 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 314 T1_POST_LCK_MUFACT_CFG_REG, 0x0AEB, 0 }, 315 /* Pointer delay */ 316 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 317 T1_TX_RX_FIFO_CFG_REG, 0x1C00, 0 }, 318 /* Tx iir edits */ 319 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 320 T1_TX_LPF_FIR_CFG_REG, 0x1000, 0 }, 321 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 322 T1_TX_LPF_FIR_CFG_REG, 0x1861, 0 }, 323 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 324 T1_TX_LPF_FIR_CFG_REG, 0x1061, 0 }, 325 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 326 T1_TX_LPF_FIR_CFG_REG, 0x1922, 0 }, 327 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 328 T1_TX_LPF_FIR_CFG_REG, 0x1122, 0 }, 329 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 330 T1_TX_LPF_FIR_CFG_REG, 0x1983, 0 }, 331 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 332 T1_TX_LPF_FIR_CFG_REG, 0x1183, 0 }, 333 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 334 T1_TX_LPF_FIR_CFG_REG, 0x1944, 0 }, 335 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 336 T1_TX_LPF_FIR_CFG_REG, 0x1144, 0 }, 337 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 338 T1_TX_LPF_FIR_CFG_REG, 0x18c5, 0 }, 339 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 340 T1_TX_LPF_FIR_CFG_REG, 0x10c5, 0 }, 341 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 342 T1_TX_LPF_FIR_CFG_REG, 0x1846, 0 }, 343 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 344 T1_TX_LPF_FIR_CFG_REG, 0x1046, 0 }, 345 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 346 T1_TX_LPF_FIR_CFG_REG, 0x1807, 0 }, 347 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 348 T1_TX_LPF_FIR_CFG_REG, 0x1007, 0 }, 349 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 350 T1_TX_LPF_FIR_CFG_REG, 0x1808, 0 }, 351 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 352 T1_TX_LPF_FIR_CFG_REG, 0x1008, 0 }, 353 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 354 T1_TX_LPF_FIR_CFG_REG, 0x1809, 0 }, 355 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 356 T1_TX_LPF_FIR_CFG_REG, 0x1009, 0 }, 357 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 358 T1_TX_LPF_FIR_CFG_REG, 0x180A, 0 }, 359 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 360 T1_TX_LPF_FIR_CFG_REG, 0x100A, 0 }, 361 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 362 T1_TX_LPF_FIR_CFG_REG, 0x180B, 0 }, 363 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 364 T1_TX_LPF_FIR_CFG_REG, 0x100B, 0 }, 365 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 366 T1_TX_LPF_FIR_CFG_REG, 0x180C, 0 }, 367 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 368 T1_TX_LPF_FIR_CFG_REG, 0x100C, 0 }, 369 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 370 T1_TX_LPF_FIR_CFG_REG, 0x180D, 0 }, 371 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 372 T1_TX_LPF_FIR_CFG_REG, 0x100D, 0 }, 373 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 374 T1_TX_LPF_FIR_CFG_REG, 0x180E, 0 }, 375 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 376 T1_TX_LPF_FIR_CFG_REG, 0x100E, 0 }, 377 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 378 T1_TX_LPF_FIR_CFG_REG, 0x180F, 0 }, 379 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 380 T1_TX_LPF_FIR_CFG_REG, 0x100F, 0 }, 381 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 382 T1_TX_LPF_FIR_CFG_REG, 0x1810, 0 }, 383 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 384 T1_TX_LPF_FIR_CFG_REG, 0x1010, 0 }, 385 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 386 T1_TX_LPF_FIR_CFG_REG, 0x1811, 0 }, 387 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 388 T1_TX_LPF_FIR_CFG_REG, 0x1011, 0 }, 389 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 390 T1_TX_LPF_FIR_CFG_REG, 0x1000, 0 }, 391 /* Setup SQI measurement */ 392 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 393 T1_COEF_CLK_PWR_DN_CFG, 0x16d6, 0 }, 394 /* SQI enable */ 395 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 396 T1_SQI_CONFIG_REG, 0x9572, 0 }, 397 /* SQI select mode 5 */ 398 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 399 T1_SQI_CONFIG2_REG, 0x0001, 0 }, 400 /* Throws the first SQI reading */ 401 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 402 T1_COEF_RW_CTL_CFG, 0x0301, 0 }, 403 { PHYACC_ATTR_MODE_READ, PHYACC_ATTR_BANK_DSP, 404 T1_DCQ_SQI_REG, 0, 0 }, 405 /* Flag LPS and WUR as idle errors */ 406 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_SMI, 407 T1_MDIO_CONTROL2_REG, 0x0014, 0 }, 408 /* HW_Init toggle, undo force ED, TXPD off */ 409 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_SMI, 410 T1_POWER_DOWN_CONTROL_REG, 0x0200, 0 }, 411 /* Reset PCS to trigger hardware initialization */ 412 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_SMI, 413 T1_MDIO_CONTROL2_REG, 0x0094, 0 }, 414 /* Poll till Hardware is initialized */ 415 { PHYACC_ATTR_MODE_POLL, PHYACC_ATTR_BANK_SMI, 416 T1_MDIO_CONTROL2_REG, 0x0080, 0 }, 417 /* Tx AMP - 0x06 */ 418 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_AFE, 419 T1_AFE_PORT_CFG1_REG, 0x000C, 0 }, 420 /* Read INTERRUPT_SOURCE Register */ 421 { PHYACC_ATTR_MODE_READ, PHYACC_ATTR_BANK_SMI, 422 T1_INTERRUPT_SOURCE_REG, 0, 0 }, 423 /* Read INTERRUPT_SOURCE Register */ 424 { PHYACC_ATTR_MODE_READ, PHYACC_ATTR_BANK_MISC, 425 T1_INTERRUPT2_SOURCE_REG, 0, 0 }, 426 /* HW_Init Hi */ 427 { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_SMI, 428 T1_POWER_DOWN_CONTROL_REG, 0x0300, 0 }, 429 }; 430 int rc; 431 432 /* phy Soft reset */ 433 rc = genphy_soft_reset(phydev); 434 if (rc < 0) 435 return rc; 436 437 /* PHY Initialization */ 438 rc = lan87xx_phy_init_cmd(phydev, hw_init, ARRAY_SIZE(hw_init)); 439 if (rc < 0) 440 return rc; 441 442 rc = genphy_read_master_slave(phydev); 443 if (rc) 444 return rc; 445 446 /* The following squence needs to run only if phydev is in 447 * slave mode. 448 */ 449 if (phydev->master_slave_state == MASTER_SLAVE_STATE_SLAVE) { 450 rc = lan87xx_phy_init_cmd(phydev, slave_init, 451 ARRAY_SIZE(slave_init)); 452 if (rc < 0) 453 return rc; 454 } 455 456 rc = lan87xx_phy_init_cmd(phydev, phy_init, ARRAY_SIZE(phy_init)); 457 if (rc < 0) 458 return rc; 459 460 return lan87xx_config_rgmii_delay(phydev); 461 } 462 463 static int lan87xx_phy_config_intr(struct phy_device *phydev) 464 { 465 int rc, val = 0; 466 467 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { 468 /* clear all interrupt */ 469 rc = phy_write(phydev, LAN87XX_INTERRUPT_MASK, val); 470 if (rc < 0) 471 return rc; 472 473 rc = phy_read(phydev, LAN87XX_INTERRUPT_SOURCE); 474 if (rc < 0) 475 return rc; 476 477 rc = access_ereg(phydev, PHYACC_ATTR_MODE_WRITE, 478 PHYACC_ATTR_BANK_MISC, 479 LAN87XX_INTERRUPT_MASK_2, val); 480 if (rc < 0) 481 return rc; 482 483 rc = access_ereg(phydev, PHYACC_ATTR_MODE_READ, 484 PHYACC_ATTR_BANK_MISC, 485 LAN87XX_INTERRUPT_SOURCE_2, 0); 486 if (rc < 0) 487 return rc; 488 489 /* enable link down and comm ready interrupt */ 490 val = LAN87XX_MASK_LINK_DOWN; 491 rc = phy_write(phydev, LAN87XX_INTERRUPT_MASK, val); 492 if (rc < 0) 493 return rc; 494 495 val = LAN87XX_MASK_COMM_RDY; 496 rc = access_ereg(phydev, PHYACC_ATTR_MODE_WRITE, 497 PHYACC_ATTR_BANK_MISC, 498 LAN87XX_INTERRUPT_MASK_2, val); 499 } else { 500 rc = phy_write(phydev, LAN87XX_INTERRUPT_MASK, val); 501 if (rc < 0) 502 return rc; 503 504 rc = phy_read(phydev, LAN87XX_INTERRUPT_SOURCE); 505 if (rc < 0) 506 return rc; 507 508 rc = access_ereg(phydev, PHYACC_ATTR_MODE_WRITE, 509 PHYACC_ATTR_BANK_MISC, 510 LAN87XX_INTERRUPT_MASK_2, val); 511 if (rc < 0) 512 return rc; 513 514 rc = access_ereg(phydev, PHYACC_ATTR_MODE_READ, 515 PHYACC_ATTR_BANK_MISC, 516 LAN87XX_INTERRUPT_SOURCE_2, 0); 517 } 518 519 return rc < 0 ? rc : 0; 520 } 521 522 static irqreturn_t lan87xx_handle_interrupt(struct phy_device *phydev) 523 { 524 int irq_status; 525 526 irq_status = access_ereg(phydev, PHYACC_ATTR_MODE_READ, 527 PHYACC_ATTR_BANK_MISC, 528 LAN87XX_INTERRUPT_SOURCE_2, 0); 529 if (irq_status < 0) { 530 phy_error(phydev); 531 return IRQ_NONE; 532 } 533 534 irq_status = phy_read(phydev, LAN87XX_INTERRUPT_SOURCE); 535 if (irq_status < 0) { 536 phy_error(phydev); 537 return IRQ_NONE; 538 } 539 540 if (irq_status == 0) 541 return IRQ_NONE; 542 543 phy_trigger_machine(phydev); 544 545 return IRQ_HANDLED; 546 } 547 548 static int lan87xx_config_init(struct phy_device *phydev) 549 { 550 int rc = lan87xx_phy_init(phydev); 551 552 return rc < 0 ? rc : 0; 553 } 554 555 static int microchip_cable_test_start_common(struct phy_device *phydev) 556 { 557 int bmcr, bmsr, ret; 558 559 /* If auto-negotiation is enabled, but not complete, the cable 560 * test never completes. So disable auto-neg. 561 */ 562 bmcr = phy_read(phydev, MII_BMCR); 563 if (bmcr < 0) 564 return bmcr; 565 566 bmsr = phy_read(phydev, MII_BMSR); 567 568 if (bmsr < 0) 569 return bmsr; 570 571 if (bmcr & BMCR_ANENABLE) { 572 ret = phy_modify(phydev, MII_BMCR, BMCR_ANENABLE, 0); 573 if (ret < 0) 574 return ret; 575 ret = genphy_soft_reset(phydev); 576 if (ret < 0) 577 return ret; 578 } 579 580 /* If the link is up, allow it some time to go down */ 581 if (bmsr & BMSR_LSTATUS) 582 msleep(1500); 583 584 return 0; 585 } 586 587 static int lan87xx_cable_test_start(struct phy_device *phydev) 588 { 589 static const struct access_ereg_val cable_test[] = { 590 /* min wait */ 591 {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 93, 592 0, 0}, 593 /* max wait */ 594 {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 94, 595 10, 0}, 596 /* pulse cycle */ 597 {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 95, 598 90, 0}, 599 /* cable diag thresh */ 600 {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 92, 601 60, 0}, 602 /* max gain */ 603 {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 79, 604 31, 0}, 605 /* clock align for each iteration */ 606 {PHYACC_ATTR_MODE_MODIFY, PHYACC_ATTR_BANK_DSP, 55, 607 0, 0x0038}, 608 /* max cycle wait config */ 609 {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 94, 610 70, 0}, 611 /* start cable diag*/ 612 {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP, 90, 613 1, 0}, 614 }; 615 int rc, i; 616 617 rc = microchip_cable_test_start_common(phydev); 618 if (rc < 0) 619 return rc; 620 621 /* start cable diag */ 622 /* check if part is alive - if not, return diagnostic error */ 623 rc = access_ereg(phydev, PHYACC_ATTR_MODE_READ, PHYACC_ATTR_BANK_SMI, 624 0x00, 0); 625 if (rc < 0) 626 return rc; 627 628 /* master/slave specific configs */ 629 rc = access_ereg(phydev, PHYACC_ATTR_MODE_READ, PHYACC_ATTR_BANK_SMI, 630 0x0A, 0); 631 if (rc < 0) 632 return rc; 633 634 if ((rc & 0x4000) != 0x4000) { 635 /* DUT is Slave */ 636 rc = access_ereg_modify_changed(phydev, PHYACC_ATTR_BANK_AFE, 637 0x0E, 0x5, 0x7); 638 if (rc < 0) 639 return rc; 640 rc = access_ereg_modify_changed(phydev, PHYACC_ATTR_BANK_SMI, 641 0x1A, 0x8, 0x8); 642 if (rc < 0) 643 return rc; 644 } else { 645 /* DUT is Master */ 646 rc = access_ereg_modify_changed(phydev, PHYACC_ATTR_BANK_SMI, 647 0x10, 0x8, 0x40); 648 if (rc < 0) 649 return rc; 650 } 651 652 for (i = 0; i < ARRAY_SIZE(cable_test); i++) { 653 if (cable_test[i].mode == PHYACC_ATTR_MODE_MODIFY) { 654 rc = access_ereg_modify_changed(phydev, 655 cable_test[i].bank, 656 cable_test[i].offset, 657 cable_test[i].val, 658 cable_test[i].mask); 659 /* wait 50ms */ 660 msleep(50); 661 } else { 662 rc = access_ereg(phydev, cable_test[i].mode, 663 cable_test[i].bank, 664 cable_test[i].offset, 665 cable_test[i].val); 666 } 667 if (rc < 0) 668 return rc; 669 } 670 /* cable diag started */ 671 672 return 0; 673 } 674 675 static int lan87xx_cable_test_report_trans(u32 result) 676 { 677 switch (result) { 678 case LAN87XX_CABLE_TEST_OK: 679 return ETHTOOL_A_CABLE_RESULT_CODE_OK; 680 case LAN87XX_CABLE_TEST_OPEN: 681 return ETHTOOL_A_CABLE_RESULT_CODE_OPEN; 682 case LAN87XX_CABLE_TEST_SAME_SHORT: 683 return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT; 684 default: 685 /* DIAGNOSTIC_ERROR */ 686 return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC; 687 } 688 } 689 690 static int lan87xx_cable_test_report(struct phy_device *phydev) 691 { 692 int pos_peak_cycle = 0, pos_peak_in_phases = 0, pos_peak_phase = 0; 693 int neg_peak_cycle = 0, neg_peak_in_phases = 0, neg_peak_phase = 0; 694 int noise_margin = 20, time_margin = 89, jitter_var = 30; 695 int min_time_diff = 96, max_time_diff = 96 + time_margin; 696 bool fault = false, check_a = false, check_b = false; 697 int gain_idx = 0, pos_peak = 0, neg_peak = 0; 698 int pos_peak_time = 0, neg_peak_time = 0; 699 int pos_peak_in_phases_hybrid = 0; 700 int detect = -1; 701 702 gain_idx = access_ereg(phydev, PHYACC_ATTR_MODE_READ, 703 PHYACC_ATTR_BANK_DSP, 151, 0); 704 /* read non-hybrid results */ 705 pos_peak = access_ereg(phydev, PHYACC_ATTR_MODE_READ, 706 PHYACC_ATTR_BANK_DSP, 153, 0); 707 neg_peak = access_ereg(phydev, PHYACC_ATTR_MODE_READ, 708 PHYACC_ATTR_BANK_DSP, 154, 0); 709 pos_peak_time = access_ereg(phydev, PHYACC_ATTR_MODE_READ, 710 PHYACC_ATTR_BANK_DSP, 156, 0); 711 neg_peak_time = access_ereg(phydev, PHYACC_ATTR_MODE_READ, 712 PHYACC_ATTR_BANK_DSP, 157, 0); 713 714 pos_peak_cycle = (pos_peak_time >> 7) & 0x7F; 715 /* calculate non-hybrid values */ 716 pos_peak_phase = pos_peak_time & 0x7F; 717 pos_peak_in_phases = (pos_peak_cycle * 96) + pos_peak_phase; 718 neg_peak_cycle = (neg_peak_time >> 7) & 0x7F; 719 neg_peak_phase = neg_peak_time & 0x7F; 720 neg_peak_in_phases = (neg_peak_cycle * 96) + neg_peak_phase; 721 722 /* process values */ 723 check_a = 724 ((pos_peak_in_phases - neg_peak_in_phases) >= min_time_diff) && 725 ((pos_peak_in_phases - neg_peak_in_phases) < max_time_diff) && 726 pos_peak_in_phases_hybrid < pos_peak_in_phases && 727 (pos_peak_in_phases_hybrid < (neg_peak_in_phases + jitter_var)); 728 check_b = 729 ((neg_peak_in_phases - pos_peak_in_phases) >= min_time_diff) && 730 ((neg_peak_in_phases - pos_peak_in_phases) < max_time_diff) && 731 pos_peak_in_phases_hybrid < neg_peak_in_phases && 732 (pos_peak_in_phases_hybrid < (pos_peak_in_phases + jitter_var)); 733 734 if (pos_peak_in_phases > neg_peak_in_phases && check_a) 735 detect = 2; 736 else if ((neg_peak_in_phases > pos_peak_in_phases) && check_b) 737 detect = 1; 738 739 if (pos_peak > noise_margin && neg_peak > noise_margin && 740 gain_idx >= 0) { 741 if (detect == 1 || detect == 2) 742 fault = true; 743 } 744 745 if (!fault) 746 detect = 0; 747 748 ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A, 749 lan87xx_cable_test_report_trans(detect)); 750 751 return 0; 752 } 753 754 static int lan87xx_cable_test_get_status(struct phy_device *phydev, 755 bool *finished) 756 { 757 int rc = 0; 758 759 *finished = false; 760 761 /* check if cable diag was finished */ 762 rc = access_ereg(phydev, PHYACC_ATTR_MODE_READ, PHYACC_ATTR_BANK_DSP, 763 90, 0); 764 if (rc < 0) 765 return rc; 766 767 if ((rc & 2) == 2) { 768 /* stop cable diag*/ 769 rc = access_ereg(phydev, PHYACC_ATTR_MODE_WRITE, 770 PHYACC_ATTR_BANK_DSP, 771 90, 0); 772 if (rc < 0) 773 return rc; 774 775 *finished = true; 776 777 return lan87xx_cable_test_report(phydev); 778 } 779 780 return 0; 781 } 782 783 static int lan87xx_read_status(struct phy_device *phydev) 784 { 785 int rc = 0; 786 787 rc = phy_read(phydev, T1_MODE_STAT_REG); 788 if (rc < 0) 789 return rc; 790 791 if (rc & T1_LINK_UP_MSK) 792 phydev->link = 1; 793 else 794 phydev->link = 0; 795 796 phydev->speed = SPEED_UNKNOWN; 797 phydev->duplex = DUPLEX_UNKNOWN; 798 phydev->pause = 0; 799 phydev->asym_pause = 0; 800 801 rc = genphy_read_master_slave(phydev); 802 if (rc < 0) 803 return rc; 804 805 rc = genphy_read_status_fixed(phydev); 806 if (rc < 0) 807 return rc; 808 809 return rc; 810 } 811 812 static int lan87xx_config_aneg(struct phy_device *phydev) 813 { 814 u16 ctl = 0; 815 int ret; 816 817 switch (phydev->master_slave_set) { 818 case MASTER_SLAVE_CFG_MASTER_FORCE: 819 ctl |= CTL1000_AS_MASTER; 820 break; 821 case MASTER_SLAVE_CFG_SLAVE_FORCE: 822 break; 823 case MASTER_SLAVE_CFG_UNKNOWN: 824 case MASTER_SLAVE_CFG_UNSUPPORTED: 825 return 0; 826 default: 827 phydev_warn(phydev, "Unsupported Master/Slave mode\n"); 828 return -EOPNOTSUPP; 829 } 830 831 ret = phy_modify_changed(phydev, MII_CTRL1000, CTL1000_AS_MASTER, ctl); 832 if (ret == 1) 833 return phy_init_hw(phydev); 834 835 return ret; 836 } 837 838 static int lan87xx_get_sqi(struct phy_device *phydev) 839 { 840 u8 sqi_value = 0; 841 int rc; 842 843 rc = access_ereg(phydev, PHYACC_ATTR_MODE_WRITE, 844 PHYACC_ATTR_BANK_DSP, T1_COEF_RW_CTL_CFG, 0x0301); 845 if (rc < 0) 846 return rc; 847 848 rc = access_ereg(phydev, PHYACC_ATTR_MODE_READ, 849 PHYACC_ATTR_BANK_DSP, T1_DCQ_SQI_REG, 0x0); 850 if (rc < 0) 851 return rc; 852 853 sqi_value = FIELD_GET(T1_DCQ_SQI_MSK, rc); 854 855 return sqi_value; 856 } 857 858 static int lan87xx_get_sqi_max(struct phy_device *phydev) 859 { 860 return LAN87XX_MAX_SQI; 861 } 862 863 static struct phy_driver microchip_t1_phy_driver[] = { 864 { 865 PHY_ID_MATCH_MODEL(PHY_ID_LAN87XX), 866 .name = "Microchip LAN87xx T1", 867 .flags = PHY_POLL_CABLE_TEST, 868 .features = PHY_BASIC_T1_FEATURES, 869 .config_init = lan87xx_config_init, 870 .config_intr = lan87xx_phy_config_intr, 871 .handle_interrupt = lan87xx_handle_interrupt, 872 .suspend = genphy_suspend, 873 .resume = genphy_resume, 874 .config_aneg = lan87xx_config_aneg, 875 .read_status = lan87xx_read_status, 876 .get_sqi = lan87xx_get_sqi, 877 .get_sqi_max = lan87xx_get_sqi_max, 878 .cable_test_start = lan87xx_cable_test_start, 879 .cable_test_get_status = lan87xx_cable_test_get_status, 880 }, 881 { 882 PHY_ID_MATCH_MODEL(PHY_ID_LAN937X), 883 .name = "Microchip LAN937x T1", 884 .flags = PHY_POLL_CABLE_TEST, 885 .features = PHY_BASIC_T1_FEATURES, 886 .config_init = lan87xx_config_init, 887 .config_intr = lan87xx_phy_config_intr, 888 .handle_interrupt = lan87xx_handle_interrupt, 889 .suspend = genphy_suspend, 890 .resume = genphy_resume, 891 .config_aneg = lan87xx_config_aneg, 892 .read_status = lan87xx_read_status, 893 .get_sqi = lan87xx_get_sqi, 894 .get_sqi_max = lan87xx_get_sqi_max, 895 .cable_test_start = lan87xx_cable_test_start, 896 .cable_test_get_status = lan87xx_cable_test_get_status, 897 } 898 }; 899 900 module_phy_driver(microchip_t1_phy_driver); 901 902 static struct mdio_device_id __maybe_unused microchip_t1_tbl[] = { 903 { PHY_ID_MATCH_MODEL(PHY_ID_LAN87XX) }, 904 { PHY_ID_MATCH_MODEL(PHY_ID_LAN937X) }, 905 { } 906 }; 907 908 MODULE_DEVICE_TABLE(mdio, microchip_t1_tbl); 909 910 MODULE_AUTHOR(DRIVER_AUTHOR); 911 MODULE_DESCRIPTION(DRIVER_DESC); 912 MODULE_LICENSE("GPL"); 913