1 // SPDX-License-Identifier: GPL-2.0+ 2 3 #include <linux/phy.h> 4 #include <linux/module.h> 5 6 #include "qcom.h" 7 8 /* ADC threshold */ 9 #define QCA808X_PHY_DEBUG_ADC_THRESHOLD 0x2c80 10 #define QCA808X_ADC_THRESHOLD_MASK GENMASK(7, 0) 11 #define QCA808X_ADC_THRESHOLD_80MV 0 12 #define QCA808X_ADC_THRESHOLD_100MV 0xf0 13 #define QCA808X_ADC_THRESHOLD_200MV 0x0f 14 #define QCA808X_ADC_THRESHOLD_300MV 0xff 15 16 /* CLD control */ 17 #define QCA808X_PHY_MMD3_ADDR_CLD_CTRL7 0x8007 18 #define QCA808X_8023AZ_AFE_CTRL_MASK GENMASK(8, 4) 19 #define QCA808X_8023AZ_AFE_EN 0x90 20 21 /* AZ control */ 22 #define QCA808X_PHY_MMD3_AZ_TRAINING_CTRL 0x8008 23 #define QCA808X_MMD3_AZ_TRAINING_VAL 0x1c32 24 25 #define QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB 0x8014 26 #define QCA808X_MSE_THRESHOLD_20DB_VALUE 0x529 27 28 #define QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB 0x800E 29 #define QCA808X_MSE_THRESHOLD_17DB_VALUE 0x341 30 31 #define QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB 0x801E 32 #define QCA808X_MSE_THRESHOLD_27DB_VALUE 0x419 33 34 #define QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB 0x8020 35 #define QCA808X_MSE_THRESHOLD_28DB_VALUE 0x341 36 37 #define QCA808X_PHY_MMD7_TOP_OPTION1 0x901c 38 #define QCA808X_TOP_OPTION1_DATA 0x0 39 40 #define QCA808X_PHY_MMD3_DEBUG_1 0xa100 41 #define QCA808X_MMD3_DEBUG_1_VALUE 0x9203 42 #define QCA808X_PHY_MMD3_DEBUG_2 0xa101 43 #define QCA808X_MMD3_DEBUG_2_VALUE 0x48ad 44 #define QCA808X_PHY_MMD3_DEBUG_3 0xa103 45 #define QCA808X_MMD3_DEBUG_3_VALUE 0x1698 46 #define QCA808X_PHY_MMD3_DEBUG_4 0xa105 47 #define QCA808X_MMD3_DEBUG_4_VALUE 0x8001 48 #define QCA808X_PHY_MMD3_DEBUG_5 0xa106 49 #define QCA808X_MMD3_DEBUG_5_VALUE 0x1111 50 #define QCA808X_PHY_MMD3_DEBUG_6 0xa011 51 #define QCA808X_MMD3_DEBUG_6_VALUE 0x5f85 52 53 /* master/slave seed config */ 54 #define QCA808X_PHY_DEBUG_LOCAL_SEED 9 55 #define QCA808X_MASTER_SLAVE_SEED_ENABLE BIT(1) 56 #define QCA808X_MASTER_SLAVE_SEED_CFG GENMASK(12, 2) 57 #define QCA808X_MASTER_SLAVE_SEED_RANGE 0x32 58 59 /* Hibernation yields lower power consumpiton in contrast with normal operation mode. 60 * when the copper cable is unplugged, the PHY enters into hibernation mode in about 10s. 61 */ 62 #define QCA808X_DBG_AN_TEST 0xb 63 #define QCA808X_HIBERNATION_EN BIT(15) 64 65 #define QCA808X_MMD7_LED2_CTRL 0x8074 66 #define QCA808X_MMD7_LED2_FORCE_CTRL 0x8075 67 #define QCA808X_MMD7_LED1_CTRL 0x8076 68 #define QCA808X_MMD7_LED1_FORCE_CTRL 0x8077 69 #define QCA808X_MMD7_LED0_CTRL 0x8078 70 #define QCA808X_MMD7_LED_CTRL(x) (0x8078 - ((x) * 2)) 71 72 #define QCA808X_MMD7_LED0_FORCE_CTRL 0x8079 73 #define QCA808X_MMD7_LED_FORCE_CTRL(x) (0x8079 - ((x) * 2)) 74 75 #define QCA808X_MMD7_LED_POLARITY_CTRL 0x901a 76 /* QSDK sets by default 0x46 to this reg that sets BIT 6 for 77 * LED to active high. It's not clear what BIT 3 and BIT 4 does. 78 */ 79 #define QCA808X_LED_ACTIVE_HIGH BIT(6) 80 81 /* QCA808X 1G chip type */ 82 #define QCA808X_PHY_MMD7_CHIP_TYPE 0x901d 83 #define QCA808X_PHY_CHIP_TYPE_1G BIT(0) 84 85 #define QCA8081_PHY_SERDES_MMD1_FIFO_CTRL 0x9072 86 #define QCA8081_PHY_FIFO_RSTN BIT(11) 87 88 #define QCA8081_PHY_ID 0x004dd101 89 90 /* led_polarity_mode otherwise holds a PHY_LED_ACTIVE_* value */ 91 #define QCA808X_PHY_LED_UNSET -1 92 93 MODULE_DESCRIPTION("Qualcomm Atheros QCA808X PHY driver"); 94 MODULE_AUTHOR("Matus Ujhelyi"); 95 MODULE_LICENSE("GPL"); 96 97 struct qca808x_priv { 98 int led_polarity_mode; 99 struct qcom_phy_hw_stats hw_stats; 100 }; 101 102 static int qca808x_phy_fast_retrain_config(struct phy_device *phydev) 103 { 104 int ret; 105 106 /* Enable fast retrain */ 107 ret = genphy_c45_fast_retrain(phydev, true); 108 if (ret) 109 return ret; 110 111 phy_write_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_TOP_OPTION1, 112 QCA808X_TOP_OPTION1_DATA); 113 phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB, 114 QCA808X_MSE_THRESHOLD_20DB_VALUE); 115 phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB, 116 QCA808X_MSE_THRESHOLD_17DB_VALUE); 117 phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB, 118 QCA808X_MSE_THRESHOLD_27DB_VALUE); 119 phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB, 120 QCA808X_MSE_THRESHOLD_28DB_VALUE); 121 phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_1, 122 QCA808X_MMD3_DEBUG_1_VALUE); 123 phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_4, 124 QCA808X_MMD3_DEBUG_4_VALUE); 125 phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_5, 126 QCA808X_MMD3_DEBUG_5_VALUE); 127 phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_3, 128 QCA808X_MMD3_DEBUG_3_VALUE); 129 phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_6, 130 QCA808X_MMD3_DEBUG_6_VALUE); 131 phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_2, 132 QCA808X_MMD3_DEBUG_2_VALUE); 133 134 return 0; 135 } 136 137 static int qca808x_phy_ms_seed_enable(struct phy_device *phydev, bool enable) 138 { 139 u16 seed_value; 140 141 if (!enable) 142 return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED, 143 QCA808X_MASTER_SLAVE_SEED_ENABLE, 0); 144 145 seed_value = get_random_u32_below(QCA808X_MASTER_SLAVE_SEED_RANGE); 146 return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED, 147 QCA808X_MASTER_SLAVE_SEED_CFG | QCA808X_MASTER_SLAVE_SEED_ENABLE, 148 FIELD_PREP(QCA808X_MASTER_SLAVE_SEED_CFG, seed_value) | 149 QCA808X_MASTER_SLAVE_SEED_ENABLE); 150 } 151 152 static bool qca808x_is_prefer_master(struct phy_device *phydev) 153 { 154 return (phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_FORCE) || 155 (phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_PREFERRED); 156 } 157 158 static bool qca808x_has_fast_retrain_or_slave_seed(struct phy_device *phydev) 159 { 160 return linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported); 161 } 162 163 static bool qca808x_is_1g_only(struct phy_device *phydev) 164 { 165 int ret; 166 167 ret = phy_read_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_CHIP_TYPE); 168 if (ret < 0) 169 return true; 170 171 return !!(QCA808X_PHY_CHIP_TYPE_1G & ret); 172 } 173 174 static void qca808x_fill_possible_interfaces(struct phy_device *phydev) 175 { 176 unsigned long *possible = phydev->possible_interfaces; 177 178 __set_bit(PHY_INTERFACE_MODE_SGMII, possible); 179 180 if (!qca808x_is_1g_only(phydev)) 181 __set_bit(PHY_INTERFACE_MODE_2500BASEX, possible); 182 } 183 184 static int qca808x_probe(struct phy_device *phydev) 185 { 186 struct device *dev = &phydev->mdio.dev; 187 struct qca808x_priv *priv; 188 189 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 190 if (!priv) 191 return -ENOMEM; 192 193 priv->led_polarity_mode = QCA808X_PHY_LED_UNSET; 194 195 phydev->priv = priv; 196 197 return 0; 198 } 199 200 static int qca808x_config_init(struct phy_device *phydev) 201 { 202 struct qca808x_priv *priv = phydev->priv; 203 int ret; 204 205 /* Set LED Active High unless active-low was requested in DT */ 206 if (priv->led_polarity_mode != PHY_LED_ACTIVE_LOW) { 207 ret = phy_set_bits_mmd(phydev, MDIO_MMD_AN, 208 QCA808X_MMD7_LED_POLARITY_CTRL, 209 QCA808X_LED_ACTIVE_HIGH); 210 if (ret) 211 return ret; 212 } 213 214 /* Active adc&vga on 802.3az for the link 1000M and 100M */ 215 ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_ADDR_CLD_CTRL7, 216 QCA808X_8023AZ_AFE_CTRL_MASK, QCA808X_8023AZ_AFE_EN); 217 if (ret) 218 return ret; 219 220 /* Adjust the threshold on 802.3az for the link 1000M */ 221 ret = phy_write_mmd(phydev, MDIO_MMD_PCS, 222 QCA808X_PHY_MMD3_AZ_TRAINING_CTRL, 223 QCA808X_MMD3_AZ_TRAINING_VAL); 224 if (ret) 225 return ret; 226 227 if (qca808x_has_fast_retrain_or_slave_seed(phydev)) { 228 /* Config the fast retrain for the link 2500M */ 229 ret = qca808x_phy_fast_retrain_config(phydev); 230 if (ret) 231 return ret; 232 233 ret = genphy_read_master_slave(phydev); 234 if (ret < 0) 235 return ret; 236 237 if (!qca808x_is_prefer_master(phydev)) { 238 /* Enable seed and configure lower ramdom seed to make phy 239 * linked as slave mode. 240 */ 241 ret = qca808x_phy_ms_seed_enable(phydev, true); 242 if (ret) 243 return ret; 244 } 245 } 246 247 qca808x_fill_possible_interfaces(phydev); 248 249 ret = qcom_phy_counter_config(phydev); 250 if (ret) 251 return ret; 252 253 /* Configure adc threshold as 100mv for the link 10M */ 254 return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_ADC_THRESHOLD, 255 QCA808X_ADC_THRESHOLD_MASK, 256 QCA808X_ADC_THRESHOLD_100MV); 257 } 258 259 static int qca808x_read_status(struct phy_device *phydev) 260 { 261 struct at803x_ss_mask ss_mask = { 0 }; 262 int ret; 263 264 ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT); 265 if (ret < 0) 266 return ret; 267 268 linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->lp_advertising, 269 ret & MDIO_AN_10GBT_STAT_LP2_5G); 270 271 ret = genphy_read_status(phydev); 272 if (ret) 273 return ret; 274 275 /* qca8081 takes the different bits for speed value from at803x */ 276 ss_mask.speed_mask = QCA808X_SS_SPEED_MASK; 277 ss_mask.speed_shift = __bf_shf(QCA808X_SS_SPEED_MASK); 278 ret = at803x_read_specific_status(phydev, ss_mask); 279 if (ret < 0) 280 return ret; 281 282 if (phydev->link) { 283 if (phydev->speed == SPEED_2500) 284 phydev->interface = PHY_INTERFACE_MODE_2500BASEX; 285 else 286 phydev->interface = PHY_INTERFACE_MODE_SGMII; 287 } else { 288 /* generate seed as a lower random value to make PHY linked as SLAVE easily, 289 * except for master/slave configuration fault detected or the master mode 290 * preferred. 291 * 292 * the reason for not putting this code into the function link_change_notify is 293 * the corner case where the link partner is also the qca8081 PHY and the seed 294 * value is configured as the same value, the link can't be up and no link change 295 * occurs. 296 */ 297 if (qca808x_has_fast_retrain_or_slave_seed(phydev)) { 298 if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR || 299 qca808x_is_prefer_master(phydev)) { 300 qca808x_phy_ms_seed_enable(phydev, false); 301 } else { 302 qca808x_phy_ms_seed_enable(phydev, true); 303 } 304 } 305 } 306 307 return 0; 308 } 309 310 static int qca808x_soft_reset(struct phy_device *phydev) 311 { 312 int ret; 313 314 ret = genphy_soft_reset(phydev); 315 if (ret < 0) 316 return ret; 317 318 if (qca808x_has_fast_retrain_or_slave_seed(phydev)) 319 ret = qca808x_phy_ms_seed_enable(phydev, true); 320 321 return ret; 322 } 323 324 static int qca808x_cable_test_start(struct phy_device *phydev) 325 { 326 int ret; 327 328 /* perform CDT with the following configs: 329 * 1. disable hibernation. 330 * 2. force PHY working in MDI mode. 331 * 3. for PHY working in 1000BaseT. 332 * 4. configure the threshold. 333 */ 334 335 ret = at803x_debug_reg_mask(phydev, QCA808X_DBG_AN_TEST, QCA808X_HIBERNATION_EN, 0); 336 if (ret < 0) 337 return ret; 338 339 ret = at803x_config_mdix(phydev, ETH_TP_MDI); 340 if (ret < 0) 341 return ret; 342 343 /* Force 1000base-T needs to configure PMA/PMD and MII_BMCR */ 344 phydev->duplex = DUPLEX_FULL; 345 phydev->speed = SPEED_1000; 346 ret = genphy_c45_pma_setup_forced(phydev); 347 if (ret < 0) 348 return ret; 349 350 ret = genphy_setup_forced(phydev); 351 if (ret < 0) 352 return ret; 353 354 /* configure the thresholds for open, short, pair ok test */ 355 phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8074, 0xc040); 356 phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8076, 0xc040); 357 phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8077, 0xa060); 358 phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8078, 0xc050); 359 phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807a, 0xc060); 360 phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807e, 0xb060); 361 362 return 0; 363 } 364 365 static int qca808x_get_features(struct phy_device *phydev) 366 { 367 int ret; 368 369 ret = genphy_c45_pma_read_abilities(phydev); 370 if (ret) 371 return ret; 372 373 /* The autoneg ability is not existed in bit3 of MMD7.1, 374 * but it is supported by qca808x PHY, so we add it here 375 * manually. 376 */ 377 linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported); 378 379 /* As for the qca8081 1G version chip, the 2500baseT ability is also 380 * existed in the bit0 of MMD1.21, we need to remove it manually if 381 * it is the qca8081 1G chip according to the bit0 of MMD7.0x901d. 382 */ 383 if (qca808x_is_1g_only(phydev)) 384 linkmode_clear_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported); 385 386 return 0; 387 } 388 389 static int qca808x_config_aneg(struct phy_device *phydev) 390 { 391 int phy_ctrl = 0; 392 int ret; 393 394 ret = at803x_prepare_config_aneg(phydev); 395 if (ret) 396 return ret; 397 398 /* The reg MII_BMCR also needs to be configured for force mode, the 399 * genphy_config_aneg is also needed. 400 */ 401 if (phydev->autoneg == AUTONEG_DISABLE) 402 genphy_c45_pma_setup_forced(phydev); 403 404 if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->advertising)) 405 phy_ctrl = MDIO_AN_10GBT_CTRL_ADV2_5G; 406 407 ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, 408 MDIO_AN_10GBT_CTRL_ADV2_5G, phy_ctrl); 409 if (ret < 0) 410 return ret; 411 412 return __genphy_config_aneg(phydev, ret); 413 } 414 415 static void qca808x_link_change_notify(struct phy_device *phydev) 416 { 417 /* Assert interface sgmii fifo on link down, deassert it on link up, 418 * the interface device address is always phy address added by 1. 419 */ 420 mdiobus_c45_modify_changed(phydev->mdio.bus, phydev->mdio.addr + 1, 421 MDIO_MMD_PMAPMD, QCA8081_PHY_SERDES_MMD1_FIFO_CTRL, 422 QCA8081_PHY_FIFO_RSTN, 423 phydev->link ? QCA8081_PHY_FIFO_RSTN : 0); 424 } 425 426 static int qca808x_led_parse_netdev(struct phy_device *phydev, unsigned long rules, 427 u16 *offload_trigger) 428 { 429 /* Parsing specific to netdev trigger */ 430 if (test_bit(TRIGGER_NETDEV_TX, &rules)) 431 *offload_trigger |= QCA808X_LED_TX_BLINK; 432 if (test_bit(TRIGGER_NETDEV_RX, &rules)) 433 *offload_trigger |= QCA808X_LED_RX_BLINK; 434 if (test_bit(TRIGGER_NETDEV_LINK_10, &rules)) 435 *offload_trigger |= QCA808X_LED_SPEED10_ON; 436 if (test_bit(TRIGGER_NETDEV_LINK_100, &rules)) 437 *offload_trigger |= QCA808X_LED_SPEED100_ON; 438 if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules)) 439 *offload_trigger |= QCA808X_LED_SPEED1000_ON; 440 if (test_bit(TRIGGER_NETDEV_LINK_2500, &rules)) 441 *offload_trigger |= QCA808X_LED_SPEED2500_ON; 442 if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules)) 443 *offload_trigger |= QCA808X_LED_HALF_DUPLEX_ON; 444 if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules)) 445 *offload_trigger |= QCA808X_LED_FULL_DUPLEX_ON; 446 447 if (rules && !*offload_trigger) 448 return -EOPNOTSUPP; 449 450 /* Enable BLINK_CHECK_BYPASS by default to make the LED 451 * blink even with duplex or speed mode not enabled. 452 */ 453 *offload_trigger |= QCA808X_LED_BLINK_CHECK_BYPASS; 454 455 return 0; 456 } 457 458 static int qca808x_led_hw_control_enable(struct phy_device *phydev, u8 index) 459 { 460 u16 reg; 461 462 if (index > 2) 463 return -EINVAL; 464 465 reg = QCA808X_MMD7_LED_FORCE_CTRL(index); 466 return qca808x_led_reg_hw_control_enable(phydev, reg); 467 } 468 469 static int qca808x_led_hw_is_supported(struct phy_device *phydev, u8 index, 470 unsigned long rules) 471 { 472 u16 offload_trigger = 0; 473 474 if (index > 2) 475 return -EINVAL; 476 477 return qca808x_led_parse_netdev(phydev, rules, &offload_trigger); 478 } 479 480 static int qca808x_led_hw_control_set(struct phy_device *phydev, u8 index, 481 unsigned long rules) 482 { 483 u16 reg, offload_trigger = 0; 484 int ret; 485 486 if (index > 2) 487 return -EINVAL; 488 489 reg = QCA808X_MMD7_LED_CTRL(index); 490 491 ret = qca808x_led_parse_netdev(phydev, rules, &offload_trigger); 492 if (ret) 493 return ret; 494 495 ret = qca808x_led_hw_control_enable(phydev, index); 496 if (ret) 497 return ret; 498 499 return phy_modify_mmd(phydev, MDIO_MMD_AN, reg, 500 QCA808X_LED_PATTERN_MASK, 501 offload_trigger); 502 } 503 504 static bool qca808x_led_hw_control_status(struct phy_device *phydev, u8 index) 505 { 506 u16 reg; 507 508 if (index > 2) 509 return false; 510 511 reg = QCA808X_MMD7_LED_FORCE_CTRL(index); 512 return qca808x_led_reg_hw_control_status(phydev, reg); 513 } 514 515 static int qca808x_led_hw_control_get(struct phy_device *phydev, u8 index, 516 unsigned long *rules) 517 { 518 u16 reg; 519 int val; 520 521 if (index > 2) 522 return -EINVAL; 523 524 /* Check if we have hw control enabled */ 525 if (qca808x_led_hw_control_status(phydev, index)) 526 return -EINVAL; 527 528 reg = QCA808X_MMD7_LED_CTRL(index); 529 530 val = phy_read_mmd(phydev, MDIO_MMD_AN, reg); 531 if (val & QCA808X_LED_TX_BLINK) 532 set_bit(TRIGGER_NETDEV_TX, rules); 533 if (val & QCA808X_LED_RX_BLINK) 534 set_bit(TRIGGER_NETDEV_RX, rules); 535 if (val & QCA808X_LED_SPEED10_ON) 536 set_bit(TRIGGER_NETDEV_LINK_10, rules); 537 if (val & QCA808X_LED_SPEED100_ON) 538 set_bit(TRIGGER_NETDEV_LINK_100, rules); 539 if (val & QCA808X_LED_SPEED1000_ON) 540 set_bit(TRIGGER_NETDEV_LINK_1000, rules); 541 if (val & QCA808X_LED_SPEED2500_ON) 542 set_bit(TRIGGER_NETDEV_LINK_2500, rules); 543 if (val & QCA808X_LED_HALF_DUPLEX_ON) 544 set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules); 545 if (val & QCA808X_LED_FULL_DUPLEX_ON) 546 set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules); 547 548 return 0; 549 } 550 551 static int qca808x_led_hw_control_reset(struct phy_device *phydev, u8 index) 552 { 553 u16 reg; 554 555 if (index > 2) 556 return -EINVAL; 557 558 reg = QCA808X_MMD7_LED_CTRL(index); 559 560 return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg, 561 QCA808X_LED_PATTERN_MASK); 562 } 563 564 static int qca808x_led_brightness_set(struct phy_device *phydev, 565 u8 index, enum led_brightness value) 566 { 567 u16 reg; 568 int ret; 569 570 if (index > 2) 571 return -EINVAL; 572 573 if (!value) { 574 ret = qca808x_led_hw_control_reset(phydev, index); 575 if (ret) 576 return ret; 577 } 578 579 reg = QCA808X_MMD7_LED_FORCE_CTRL(index); 580 return qca808x_led_reg_brightness_set(phydev, reg, value); 581 } 582 583 static int qca808x_led_blink_set(struct phy_device *phydev, u8 index, 584 unsigned long *delay_on, 585 unsigned long *delay_off) 586 { 587 u16 reg; 588 589 if (index > 2) 590 return -EINVAL; 591 592 reg = QCA808X_MMD7_LED_FORCE_CTRL(index); 593 return qca808x_led_reg_blink_set(phydev, reg, delay_on, delay_off); 594 } 595 596 static int qca808x_led_polarity_set(struct phy_device *phydev, int index, 597 unsigned long modes) 598 { 599 struct qca808x_priv *priv = phydev->priv; 600 bool active_low = false; 601 u32 mode; 602 603 for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) { 604 switch (mode) { 605 case PHY_LED_ACTIVE_LOW: 606 active_low = true; 607 break; 608 case PHY_LED_ACTIVE_HIGH: 609 active_low = false; 610 break; 611 default: 612 return -EINVAL; 613 } 614 } 615 616 /* PHY polarity is global and can't be set per LED. 617 * To detect this, check if last requested polarity mode 618 * match the new one. 619 */ 620 if (priv->led_polarity_mode != QCA808X_PHY_LED_UNSET && 621 priv->led_polarity_mode != active_low) { 622 phydev_err(phydev, "PHY polarity is global. Mismatched polarity on different LED\n"); 623 return -EINVAL; 624 } 625 626 /* Save the last PHY polarity mode */ 627 priv->led_polarity_mode = active_low; 628 629 return phy_modify_mmd(phydev, MDIO_MMD_AN, 630 QCA808X_MMD7_LED_POLARITY_CTRL, 631 QCA808X_LED_ACTIVE_HIGH, 632 active_low ? 0 : QCA808X_LED_ACTIVE_HIGH); 633 } 634 635 static int qca808x_update_stats(struct phy_device *phydev) 636 { 637 struct qca808x_priv *priv = phydev->priv; 638 639 return qcom_phy_update_stats(phydev, &priv->hw_stats); 640 } 641 642 static void qca808x_get_phy_stats(struct phy_device *phydev, 643 struct ethtool_eth_phy_stats *eth_stats, 644 struct ethtool_phy_stats *stats) 645 { 646 struct qca808x_priv *priv = phydev->priv; 647 648 qcom_phy_get_stats(stats, priv->hw_stats); 649 } 650 651 static struct phy_driver qca808x_driver[] = { 652 { 653 /* Qualcomm QCA8081 */ 654 PHY_ID_MATCH_EXACT(QCA8081_PHY_ID), 655 .name = "Qualcomm QCA8081", 656 .flags = PHY_POLL_CABLE_TEST, 657 .probe = qca808x_probe, 658 .config_intr = at803x_config_intr, 659 .handle_interrupt = at803x_handle_interrupt, 660 .get_tunable = at803x_get_tunable, 661 .set_tunable = at803x_set_tunable, 662 .set_wol = at8031_set_wol, 663 .get_wol = at803x_get_wol, 664 .get_features = qca808x_get_features, 665 .config_aneg = qca808x_config_aneg, 666 .suspend = genphy_suspend, 667 .resume = genphy_resume, 668 .read_status = qca808x_read_status, 669 .config_init = qca808x_config_init, 670 .soft_reset = qca808x_soft_reset, 671 .cable_test_start = qca808x_cable_test_start, 672 .cable_test_get_status = qca808x_cable_test_get_status, 673 .link_change_notify = qca808x_link_change_notify, 674 .led_brightness_set = qca808x_led_brightness_set, 675 .led_blink_set = qca808x_led_blink_set, 676 .led_hw_is_supported = qca808x_led_hw_is_supported, 677 .led_hw_control_set = qca808x_led_hw_control_set, 678 .led_hw_control_get = qca808x_led_hw_control_get, 679 .led_polarity_set = qca808x_led_polarity_set, 680 .update_stats = qca808x_update_stats, 681 .get_phy_stats = qca808x_get_phy_stats, 682 }, }; 683 684 module_phy_driver(qca808x_driver); 685 686 static const struct mdio_device_id __maybe_unused qca808x_tbl[] = { 687 { PHY_ID_MATCH_EXACT(QCA8081_PHY_ID) }, 688 { } 689 }; 690 691 MODULE_DEVICE_TABLE(mdio, qca808x_tbl); 692