1 // SPDX-License-Identifier: GPL-2.0 2 3 #include <linux/phy.h> 4 #include <linux/module.h> 5 6 #include <linux/netdevice.h> 7 #include <linux/etherdevice.h> 8 9 #include "qcom.h" 10 11 MODULE_DESCRIPTION("Qualcomm PHY driver Common Functions"); 12 MODULE_AUTHOR("Matus Ujhelyi"); 13 MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>"); 14 MODULE_LICENSE("GPL"); 15 16 int at803x_debug_reg_read(struct phy_device *phydev, u16 reg) 17 { 18 int ret; 19 20 ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg); 21 if (ret < 0) 22 return ret; 23 24 return phy_read(phydev, AT803X_DEBUG_DATA); 25 } 26 EXPORT_SYMBOL_GPL(at803x_debug_reg_read); 27 28 int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg, 29 u16 clear, u16 set) 30 { 31 u16 val; 32 int ret; 33 34 ret = at803x_debug_reg_read(phydev, reg); 35 if (ret < 0) 36 return ret; 37 38 val = ret & 0xffff; 39 val &= ~clear; 40 val |= set; 41 42 return phy_write(phydev, AT803X_DEBUG_DATA, val); 43 } 44 EXPORT_SYMBOL_GPL(at803x_debug_reg_mask); 45 46 int at803x_debug_reg_write(struct phy_device *phydev, u16 reg, u16 data) 47 { 48 int ret; 49 50 ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg); 51 if (ret < 0) 52 return ret; 53 54 return phy_write(phydev, AT803X_DEBUG_DATA, data); 55 } 56 EXPORT_SYMBOL_GPL(at803x_debug_reg_write); 57 58 int at803x_set_wol(struct phy_device *phydev, 59 struct ethtool_wolinfo *wol) 60 { 61 int ret, irq_enabled; 62 63 if (wol->wolopts & WAKE_MAGIC) { 64 struct net_device *ndev = phydev->attached_dev; 65 const u8 *mac; 66 unsigned int i; 67 static const unsigned int offsets[] = { 68 AT803X_LOC_MAC_ADDR_32_47_OFFSET, 69 AT803X_LOC_MAC_ADDR_16_31_OFFSET, 70 AT803X_LOC_MAC_ADDR_0_15_OFFSET, 71 }; 72 73 if (!ndev) 74 return -ENODEV; 75 76 mac = (const u8 *)ndev->dev_addr; 77 78 if (!is_valid_ether_addr(mac)) 79 return -EINVAL; 80 81 for (i = 0; i < 3; i++) 82 phy_write_mmd(phydev, MDIO_MMD_PCS, offsets[i], 83 mac[(i * 2) + 1] | (mac[(i * 2)] << 8)); 84 85 /* Enable WOL interrupt */ 86 ret = phy_modify(phydev, AT803X_INTR_ENABLE, 0, AT803X_INTR_ENABLE_WOL); 87 if (ret) 88 return ret; 89 } else { 90 /* Disable WOL interrupt */ 91 ret = phy_modify(phydev, AT803X_INTR_ENABLE, AT803X_INTR_ENABLE_WOL, 0); 92 if (ret) 93 return ret; 94 } 95 96 /* Clear WOL status */ 97 ret = phy_read(phydev, AT803X_INTR_STATUS); 98 if (ret < 0) 99 return ret; 100 101 /* Check if there are other interrupts except for WOL triggered when PHY is 102 * in interrupt mode, only the interrupts enabled by AT803X_INTR_ENABLE can 103 * be passed up to the interrupt PIN. 104 */ 105 irq_enabled = phy_read(phydev, AT803X_INTR_ENABLE); 106 if (irq_enabled < 0) 107 return irq_enabled; 108 109 irq_enabled &= ~AT803X_INTR_ENABLE_WOL; 110 if (ret & irq_enabled && !phy_polling_mode(phydev)) 111 phy_trigger_machine(phydev); 112 113 return 0; 114 } 115 EXPORT_SYMBOL_GPL(at803x_set_wol); 116 117 void at803x_get_wol(struct phy_device *phydev, 118 struct ethtool_wolinfo *wol) 119 { 120 int value; 121 122 wol->supported = WAKE_MAGIC; 123 wol->wolopts = 0; 124 125 value = phy_read(phydev, AT803X_INTR_ENABLE); 126 if (value < 0) 127 return; 128 129 if (value & AT803X_INTR_ENABLE_WOL) 130 wol->wolopts |= WAKE_MAGIC; 131 } 132 EXPORT_SYMBOL_GPL(at803x_get_wol); 133 134 int at803x_ack_interrupt(struct phy_device *phydev) 135 { 136 int err; 137 138 err = phy_read(phydev, AT803X_INTR_STATUS); 139 140 return (err < 0) ? err : 0; 141 } 142 EXPORT_SYMBOL_GPL(at803x_ack_interrupt); 143 144 int at803x_config_intr(struct phy_device *phydev) 145 { 146 int err; 147 int value; 148 149 value = phy_read(phydev, AT803X_INTR_ENABLE); 150 151 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { 152 /* Clear any pending interrupts */ 153 err = at803x_ack_interrupt(phydev); 154 if (err) 155 return err; 156 157 value |= AT803X_INTR_ENABLE_AUTONEG_ERR; 158 value |= AT803X_INTR_ENABLE_SPEED_CHANGED; 159 value |= AT803X_INTR_ENABLE_DUPLEX_CHANGED; 160 value |= AT803X_INTR_ENABLE_LINK_FAIL; 161 value |= AT803X_INTR_ENABLE_LINK_SUCCESS; 162 163 err = phy_write(phydev, AT803X_INTR_ENABLE, value); 164 } else { 165 err = phy_write(phydev, AT803X_INTR_ENABLE, 0); 166 if (err) 167 return err; 168 169 /* Clear any pending interrupts */ 170 err = at803x_ack_interrupt(phydev); 171 } 172 173 return err; 174 } 175 EXPORT_SYMBOL_GPL(at803x_config_intr); 176 177 irqreturn_t at803x_handle_interrupt(struct phy_device *phydev) 178 { 179 int irq_status, int_enabled; 180 181 irq_status = phy_read(phydev, AT803X_INTR_STATUS); 182 if (irq_status < 0) { 183 phy_error(phydev); 184 return IRQ_NONE; 185 } 186 187 /* Read the current enabled interrupts */ 188 int_enabled = phy_read(phydev, AT803X_INTR_ENABLE); 189 if (int_enabled < 0) { 190 phy_error(phydev); 191 return IRQ_NONE; 192 } 193 194 /* See if this was one of our enabled interrupts */ 195 if (!(irq_status & int_enabled)) 196 return IRQ_NONE; 197 198 phy_trigger_machine(phydev); 199 200 return IRQ_HANDLED; 201 } 202 EXPORT_SYMBOL_GPL(at803x_handle_interrupt); 203 204 int at803x_read_specific_status(struct phy_device *phydev, 205 struct at803x_ss_mask ss_mask) 206 { 207 int ss; 208 209 /* Read the AT8035 PHY-Specific Status register, which indicates the 210 * speed and duplex that the PHY is actually using, irrespective of 211 * whether we are in autoneg mode or not. 212 */ 213 ss = phy_read(phydev, AT803X_SPECIFIC_STATUS); 214 if (ss < 0) 215 return ss; 216 217 if (ss & AT803X_SS_SPEED_DUPLEX_RESOLVED) { 218 int sfc, speed; 219 220 sfc = phy_read(phydev, AT803X_SPECIFIC_FUNCTION_CONTROL); 221 if (sfc < 0) 222 return sfc; 223 224 speed = ss & ss_mask.speed_mask; 225 speed >>= ss_mask.speed_shift; 226 227 switch (speed) { 228 case AT803X_SS_SPEED_10: 229 phydev->speed = SPEED_10; 230 break; 231 case AT803X_SS_SPEED_100: 232 phydev->speed = SPEED_100; 233 break; 234 case AT803X_SS_SPEED_1000: 235 phydev->speed = SPEED_1000; 236 break; 237 case QCA808X_SS_SPEED_2500: 238 phydev->speed = SPEED_2500; 239 break; 240 } 241 if (ss & AT803X_SS_DUPLEX) 242 phydev->duplex = DUPLEX_FULL; 243 else 244 phydev->duplex = DUPLEX_HALF; 245 246 if (ss & AT803X_SS_MDIX) 247 phydev->mdix = ETH_TP_MDI_X; 248 else 249 phydev->mdix = ETH_TP_MDI; 250 251 switch (FIELD_GET(AT803X_SFC_MDI_CROSSOVER_MODE_M, sfc)) { 252 case AT803X_SFC_MANUAL_MDI: 253 phydev->mdix_ctrl = ETH_TP_MDI; 254 break; 255 case AT803X_SFC_MANUAL_MDIX: 256 phydev->mdix_ctrl = ETH_TP_MDI_X; 257 break; 258 case AT803X_SFC_AUTOMATIC_CROSSOVER: 259 phydev->mdix_ctrl = ETH_TP_MDI_AUTO; 260 break; 261 } 262 } 263 264 return 0; 265 } 266 EXPORT_SYMBOL_GPL(at803x_read_specific_status); 267 268 int at803x_config_mdix(struct phy_device *phydev, u8 ctrl) 269 { 270 u16 val; 271 272 switch (ctrl) { 273 case ETH_TP_MDI: 274 val = AT803X_SFC_MANUAL_MDI; 275 break; 276 case ETH_TP_MDI_X: 277 val = AT803X_SFC_MANUAL_MDIX; 278 break; 279 case ETH_TP_MDI_AUTO: 280 val = AT803X_SFC_AUTOMATIC_CROSSOVER; 281 break; 282 default: 283 return 0; 284 } 285 286 return phy_modify_changed(phydev, AT803X_SPECIFIC_FUNCTION_CONTROL, 287 AT803X_SFC_MDI_CROSSOVER_MODE_M, 288 FIELD_PREP(AT803X_SFC_MDI_CROSSOVER_MODE_M, val)); 289 } 290 EXPORT_SYMBOL_GPL(at803x_config_mdix); 291 292 int at803x_prepare_config_aneg(struct phy_device *phydev) 293 { 294 int ret; 295 296 ret = at803x_config_mdix(phydev, phydev->mdix_ctrl); 297 if (ret < 0) 298 return ret; 299 300 /* Changes of the midx bits are disruptive to the normal operation; 301 * therefore any changes to these registers must be followed by a 302 * software reset to take effect. 303 */ 304 if (ret == 1) { 305 ret = genphy_soft_reset(phydev); 306 if (ret < 0) 307 return ret; 308 } 309 310 return 0; 311 } 312 EXPORT_SYMBOL_GPL(at803x_prepare_config_aneg); 313 314 static int at803x_get_downshift(struct phy_device *phydev, u8 *d) 315 { 316 int val; 317 318 val = phy_read(phydev, AT803X_SMART_SPEED); 319 if (val < 0) 320 return val; 321 322 if (val & AT803X_SMART_SPEED_ENABLE) 323 *d = FIELD_GET(AT803X_SMART_SPEED_RETRY_LIMIT_MASK, val) + 2; 324 else 325 *d = DOWNSHIFT_DEV_DISABLE; 326 327 return 0; 328 } 329 330 static int at803x_set_downshift(struct phy_device *phydev, u8 cnt) 331 { 332 u16 mask, set; 333 int ret; 334 335 switch (cnt) { 336 case DOWNSHIFT_DEV_DEFAULT_COUNT: 337 cnt = AT803X_DEFAULT_DOWNSHIFT; 338 fallthrough; 339 case AT803X_MIN_DOWNSHIFT ... AT803X_MAX_DOWNSHIFT: 340 set = AT803X_SMART_SPEED_ENABLE | 341 AT803X_SMART_SPEED_BYPASS_TIMER | 342 FIELD_PREP(AT803X_SMART_SPEED_RETRY_LIMIT_MASK, cnt - 2); 343 mask = AT803X_SMART_SPEED_RETRY_LIMIT_MASK; 344 break; 345 case DOWNSHIFT_DEV_DISABLE: 346 set = 0; 347 mask = AT803X_SMART_SPEED_ENABLE | 348 AT803X_SMART_SPEED_BYPASS_TIMER; 349 break; 350 default: 351 return -EINVAL; 352 } 353 354 ret = phy_modify_changed(phydev, AT803X_SMART_SPEED, mask, set); 355 356 /* After changing the smart speed settings, we need to perform a 357 * software reset, use phy_init_hw() to make sure we set the 358 * reapply any values which might got lost during software reset. 359 */ 360 if (ret == 1) 361 ret = phy_init_hw(phydev); 362 363 return ret; 364 } 365 366 int at803x_get_tunable(struct phy_device *phydev, 367 struct ethtool_tunable *tuna, void *data) 368 { 369 switch (tuna->id) { 370 case ETHTOOL_PHY_DOWNSHIFT: 371 return at803x_get_downshift(phydev, data); 372 default: 373 return -EOPNOTSUPP; 374 } 375 } 376 EXPORT_SYMBOL_GPL(at803x_get_tunable); 377 378 int at803x_set_tunable(struct phy_device *phydev, 379 struct ethtool_tunable *tuna, const void *data) 380 { 381 switch (tuna->id) { 382 case ETHTOOL_PHY_DOWNSHIFT: 383 return at803x_set_downshift(phydev, *(const u8 *)data); 384 default: 385 return -EOPNOTSUPP; 386 } 387 } 388 EXPORT_SYMBOL_GPL(at803x_set_tunable); 389 390 int at803x_cdt_fault_length(int dt) 391 { 392 /* According to the datasheet the distance to the fault is 393 * DELTA_TIME * 0.824 meters. 394 * 395 * The author suspect the correct formula is: 396 * 397 * fault_distance = DELTA_TIME * (c * VF) / 125MHz / 2 398 * 399 * where c is the speed of light, VF is the velocity factor of 400 * the twisted pair cable, 125MHz the counter frequency and 401 * we need to divide by 2 because the hardware will measure the 402 * round trip time to the fault and back to the PHY. 403 * 404 * With a VF of 0.69 we get the factor 0.824 mentioned in the 405 * datasheet. 406 */ 407 return (dt * 824) / 10; 408 } 409 EXPORT_SYMBOL_GPL(at803x_cdt_fault_length); 410 411 int at803x_cdt_start(struct phy_device *phydev, u32 cdt_start) 412 { 413 return phy_write(phydev, AT803X_CDT, cdt_start); 414 } 415 EXPORT_SYMBOL_GPL(at803x_cdt_start); 416 417 int at803x_cdt_wait_for_completion(struct phy_device *phydev, 418 u32 cdt_en) 419 { 420 int val, ret; 421 422 /* One test run takes about 25ms */ 423 ret = phy_read_poll_timeout(phydev, AT803X_CDT, val, 424 !(val & cdt_en), 425 30000, 100000, true); 426 427 return ret < 0 ? ret : 0; 428 } 429 EXPORT_SYMBOL_GPL(at803x_cdt_wait_for_completion); 430