903 lines · c
1// SPDX-License-Identifier: GPL-2.02/* NXP TJA1100 BroadRReach PHY driver3 *4 * Copyright (C) 2018 Marek Vasut <marex@denx.de>5 */6#include <linux/delay.h>7#include <linux/ethtool.h>8#include <linux/ethtool_netlink.h>9#include <linux/kernel.h>10#include <linux/mdio.h>11#include <linux/mii.h>12#include <linux/module.h>13#include <linux/of.h>14#include <linux/phy.h>15#include <linux/hwmon.h>16#include <linux/bitfield.h>17#include <linux/of_mdio.h>18#include <linux/of_irq.h>19 20#define PHY_ID_MASK 0xfffffff021#define PHY_ID_TJA1100 0x0180dc4022#define PHY_ID_TJA1101 0x0180dd0023#define PHY_ID_TJA1102 0x0180dc8024 25#define MII_ECTRL 1726#define MII_ECTRL_LINK_CONTROL BIT(15)27#define MII_ECTRL_POWER_MODE_MASK GENMASK(14, 11)28#define MII_ECTRL_POWER_MODE_NO_CHANGE (0x0 << 11)29#define MII_ECTRL_POWER_MODE_NORMAL (0x3 << 11)30#define MII_ECTRL_POWER_MODE_STANDBY (0xc << 11)31#define MII_ECTRL_CABLE_TEST BIT(5)32#define MII_ECTRL_CONFIG_EN BIT(2)33#define MII_ECTRL_WAKE_REQUEST BIT(0)34 35#define MII_CFG1 1836#define MII_CFG1_MASTER_SLAVE BIT(15)37#define MII_CFG1_AUTO_OP BIT(14)38#define MII_CFG1_INTERFACE_MODE_MASK GENMASK(9, 8)39#define MII_CFG1_MII_MODE (0x0 << 8)40#define MII_CFG1_RMII_MODE_REFCLK_IN BIT(8)41#define MII_CFG1_RMII_MODE_REFCLK_OUT BIT(9)42#define MII_CFG1_REVMII_MODE GENMASK(9, 8)43#define MII_CFG1_SLEEP_CONFIRM BIT(6)44#define MII_CFG1_LED_MODE_MASK GENMASK(5, 4)45#define MII_CFG1_LED_MODE_LINKUP 046#define MII_CFG1_LED_ENABLE BIT(3)47 48#define MII_CFG2 1949#define MII_CFG2_SLEEP_REQUEST_TO GENMASK(1, 0)50#define MII_CFG2_SLEEP_REQUEST_TO_16MS 0x351 52#define MII_INTSRC 2153#define MII_INTSRC_LINK_FAIL BIT(10)54#define MII_INTSRC_LINK_UP BIT(9)55#define MII_INTSRC_MASK (MII_INTSRC_LINK_FAIL | MII_INTSRC_LINK_UP)56#define MII_INTSRC_UV_ERR BIT(3)57#define MII_INTSRC_TEMP_ERR BIT(1)58 59#define MII_INTEN 2260#define MII_INTEN_LINK_FAIL BIT(10)61#define MII_INTEN_LINK_UP BIT(9)62#define MII_INTEN_UV_ERR BIT(3)63#define MII_INTEN_TEMP_ERR BIT(1)64 65#define MII_COMMSTAT 2366#define MII_COMMSTAT_LINK_UP BIT(15)67#define MII_COMMSTAT_SQI_STATE GENMASK(7, 5)68#define MII_COMMSTAT_SQI_MAX 769 70#define MII_GENSTAT 2471#define MII_GENSTAT_PLL_LOCKED BIT(14)72 73#define MII_EXTSTAT 2574#define MII_EXTSTAT_SHORT_DETECT BIT(8)75#define MII_EXTSTAT_OPEN_DETECT BIT(7)76#define MII_EXTSTAT_POLARITY_DETECT BIT(6)77 78#define MII_COMMCFG 2779#define MII_COMMCFG_AUTO_OP BIT(15)80 81/* Configure REF_CLK as input in RMII mode */82#define TJA110X_RMII_MODE_REFCLK_IN BIT(0)83 84struct tja11xx_priv {85 char *hwmon_name;86 struct device *hwmon_dev;87 struct phy_device *phydev;88 struct work_struct phy_register_work;89 u32 flags;90};91 92struct tja11xx_phy_stats {93 const char *string;94 u8 reg;95 u8 off;96 u16 mask;97};98 99static struct tja11xx_phy_stats tja11xx_hw_stats[] = {100 { "phy_symbol_error_count", 20, 0, GENMASK(15, 0) },101 { "phy_polarity_detect", 25, 6, BIT(6) },102 { "phy_open_detect", 25, 7, BIT(7) },103 { "phy_short_detect", 25, 8, BIT(8) },104 { "phy_rem_rcvr_count", 26, 0, GENMASK(7, 0) },105 { "phy_loc_rcvr_count", 26, 8, GENMASK(15, 8) },106};107 108static int tja11xx_check(struct phy_device *phydev, u8 reg, u16 mask, u16 set)109{110 int val;111 112 return phy_read_poll_timeout(phydev, reg, val, (val & mask) == set,113 150, 30000, false);114}115 116static int phy_modify_check(struct phy_device *phydev, u8 reg,117 u16 mask, u16 set)118{119 int ret;120 121 ret = phy_modify(phydev, reg, mask, set);122 if (ret)123 return ret;124 125 return tja11xx_check(phydev, reg, mask, set);126}127 128static int tja11xx_enable_reg_write(struct phy_device *phydev)129{130 return phy_set_bits(phydev, MII_ECTRL, MII_ECTRL_CONFIG_EN);131}132 133static int tja11xx_enable_link_control(struct phy_device *phydev)134{135 return phy_set_bits(phydev, MII_ECTRL, MII_ECTRL_LINK_CONTROL);136}137 138static int tja11xx_disable_link_control(struct phy_device *phydev)139{140 return phy_clear_bits(phydev, MII_ECTRL, MII_ECTRL_LINK_CONTROL);141}142 143static int tja11xx_wakeup(struct phy_device *phydev)144{145 int ret;146 147 ret = phy_read(phydev, MII_ECTRL);148 if (ret < 0)149 return ret;150 151 switch (ret & MII_ECTRL_POWER_MODE_MASK) {152 case MII_ECTRL_POWER_MODE_NO_CHANGE:153 break;154 case MII_ECTRL_POWER_MODE_NORMAL:155 ret = phy_set_bits(phydev, MII_ECTRL, MII_ECTRL_WAKE_REQUEST);156 if (ret)157 return ret;158 159 ret = phy_clear_bits(phydev, MII_ECTRL, MII_ECTRL_WAKE_REQUEST);160 if (ret)161 return ret;162 break;163 case MII_ECTRL_POWER_MODE_STANDBY:164 ret = phy_modify_check(phydev, MII_ECTRL,165 MII_ECTRL_POWER_MODE_MASK,166 MII_ECTRL_POWER_MODE_STANDBY);167 if (ret)168 return ret;169 170 ret = phy_modify(phydev, MII_ECTRL, MII_ECTRL_POWER_MODE_MASK,171 MII_ECTRL_POWER_MODE_NORMAL);172 if (ret)173 return ret;174 175 ret = phy_modify_check(phydev, MII_GENSTAT,176 MII_GENSTAT_PLL_LOCKED,177 MII_GENSTAT_PLL_LOCKED);178 if (ret)179 return ret;180 181 return tja11xx_enable_link_control(phydev);182 default:183 break;184 }185 186 return 0;187}188 189static int tja11xx_soft_reset(struct phy_device *phydev)190{191 int ret;192 193 ret = tja11xx_enable_reg_write(phydev);194 if (ret)195 return ret;196 197 return genphy_soft_reset(phydev);198}199 200static int tja11xx_config_aneg_cable_test(struct phy_device *phydev)201{202 bool finished = false;203 int ret;204 205 if (phydev->link)206 return 0;207 208 if (!phydev->drv->cable_test_start ||209 !phydev->drv->cable_test_get_status)210 return 0;211 212 ret = ethnl_cable_test_alloc(phydev, ETHTOOL_MSG_CABLE_TEST_NTF);213 if (ret)214 return ret;215 216 ret = phydev->drv->cable_test_start(phydev);217 if (ret)218 return ret;219 220 /* According to the documentation this test takes 100 usec */221 usleep_range(100, 200);222 223 ret = phydev->drv->cable_test_get_status(phydev, &finished);224 if (ret)225 return ret;226 227 if (finished)228 ethnl_cable_test_finished(phydev);229 230 return 0;231}232 233static int tja11xx_config_aneg(struct phy_device *phydev)234{235 int ret, changed = 0;236 u16 ctl = 0;237 238 switch (phydev->master_slave_set) {239 case MASTER_SLAVE_CFG_MASTER_FORCE:240 ctl |= MII_CFG1_MASTER_SLAVE;241 break;242 case MASTER_SLAVE_CFG_SLAVE_FORCE:243 break;244 case MASTER_SLAVE_CFG_UNKNOWN:245 case MASTER_SLAVE_CFG_UNSUPPORTED:246 goto do_test;247 default:248 phydev_warn(phydev, "Unsupported Master/Slave mode\n");249 return -ENOTSUPP;250 }251 252 changed = phy_modify_changed(phydev, MII_CFG1, MII_CFG1_MASTER_SLAVE, ctl);253 if (changed < 0)254 return changed;255 256do_test:257 ret = tja11xx_config_aneg_cable_test(phydev);258 if (ret)259 return ret;260 261 return __genphy_config_aneg(phydev, changed);262}263 264static int tja11xx_get_interface_mode(struct phy_device *phydev)265{266 struct tja11xx_priv *priv = phydev->priv;267 int mii_mode;268 269 switch (phydev->interface) {270 case PHY_INTERFACE_MODE_MII:271 mii_mode = MII_CFG1_MII_MODE;272 break;273 case PHY_INTERFACE_MODE_REVMII:274 mii_mode = MII_CFG1_REVMII_MODE;275 break;276 case PHY_INTERFACE_MODE_RMII:277 if (priv->flags & TJA110X_RMII_MODE_REFCLK_IN)278 mii_mode = MII_CFG1_RMII_MODE_REFCLK_IN;279 else280 mii_mode = MII_CFG1_RMII_MODE_REFCLK_OUT;281 break;282 default:283 return -EINVAL;284 }285 286 return mii_mode;287}288 289static int tja11xx_config_init(struct phy_device *phydev)290{291 u16 reg_mask, reg_val;292 int ret;293 294 ret = tja11xx_enable_reg_write(phydev);295 if (ret)296 return ret;297 298 phydev->autoneg = AUTONEG_DISABLE;299 phydev->speed = SPEED_100;300 phydev->duplex = DUPLEX_FULL;301 302 switch (phydev->phy_id & PHY_ID_MASK) {303 case PHY_ID_TJA1100:304 reg_mask = MII_CFG1_AUTO_OP | MII_CFG1_LED_MODE_MASK |305 MII_CFG1_LED_ENABLE;306 reg_val = MII_CFG1_AUTO_OP | MII_CFG1_LED_MODE_LINKUP |307 MII_CFG1_LED_ENABLE;308 309 reg_mask |= MII_CFG1_INTERFACE_MODE_MASK;310 ret = tja11xx_get_interface_mode(phydev);311 if (ret < 0)312 return ret;313 314 reg_val |= (ret & 0xffff);315 ret = phy_modify(phydev, MII_CFG1, reg_mask, reg_val);316 if (ret)317 return ret;318 break;319 case PHY_ID_TJA1101:320 reg_mask = MII_CFG1_INTERFACE_MODE_MASK;321 ret = tja11xx_get_interface_mode(phydev);322 if (ret < 0)323 return ret;324 325 reg_val = ret & 0xffff;326 ret = phy_modify(phydev, MII_CFG1, reg_mask, reg_val);327 if (ret)328 return ret;329 fallthrough;330 case PHY_ID_TJA1102:331 ret = phy_set_bits(phydev, MII_COMMCFG, MII_COMMCFG_AUTO_OP);332 if (ret)333 return ret;334 break;335 default:336 return -EINVAL;337 }338 339 ret = phy_clear_bits(phydev, MII_CFG1, MII_CFG1_SLEEP_CONFIRM);340 if (ret)341 return ret;342 343 ret = phy_modify(phydev, MII_CFG2, MII_CFG2_SLEEP_REQUEST_TO,344 MII_CFG2_SLEEP_REQUEST_TO_16MS);345 if (ret)346 return ret;347 348 ret = tja11xx_wakeup(phydev);349 if (ret < 0)350 return ret;351 352 /* ACK interrupts by reading the status register */353 ret = phy_read(phydev, MII_INTSRC);354 if (ret < 0)355 return ret;356 357 return 0;358}359 360static int tja11xx_read_status(struct phy_device *phydev)361{362 int ret;363 364 phydev->master_slave_get = MASTER_SLAVE_CFG_UNKNOWN;365 phydev->master_slave_state = MASTER_SLAVE_STATE_UNSUPPORTED;366 367 ret = genphy_update_link(phydev);368 if (ret)369 return ret;370 371 ret = phy_read(phydev, MII_CFG1);372 if (ret < 0)373 return ret;374 375 if (ret & MII_CFG1_MASTER_SLAVE)376 phydev->master_slave_get = MASTER_SLAVE_CFG_MASTER_FORCE;377 else378 phydev->master_slave_get = MASTER_SLAVE_CFG_SLAVE_FORCE;379 380 if (phydev->link) {381 ret = phy_read(phydev, MII_COMMSTAT);382 if (ret < 0)383 return ret;384 385 if (!(ret & MII_COMMSTAT_LINK_UP))386 phydev->link = 0;387 }388 389 return 0;390}391 392static int tja11xx_get_sqi(struct phy_device *phydev)393{394 int ret;395 396 ret = phy_read(phydev, MII_COMMSTAT);397 if (ret < 0)398 return ret;399 400 return FIELD_GET(MII_COMMSTAT_SQI_STATE, ret);401}402 403static int tja11xx_get_sqi_max(struct phy_device *phydev)404{405 return MII_COMMSTAT_SQI_MAX;406}407 408static int tja11xx_get_sset_count(struct phy_device *phydev)409{410 return ARRAY_SIZE(tja11xx_hw_stats);411}412 413static void tja11xx_get_strings(struct phy_device *phydev, u8 *data)414{415 int i;416 417 for (i = 0; i < ARRAY_SIZE(tja11xx_hw_stats); i++)418 ethtool_puts(&data, tja11xx_hw_stats[i].string);419}420 421static void tja11xx_get_stats(struct phy_device *phydev,422 struct ethtool_stats *stats, u64 *data)423{424 int i, ret;425 426 for (i = 0; i < ARRAY_SIZE(tja11xx_hw_stats); i++) {427 ret = phy_read(phydev, tja11xx_hw_stats[i].reg);428 if (ret < 0)429 data[i] = U64_MAX;430 else {431 data[i] = ret & tja11xx_hw_stats[i].mask;432 data[i] >>= tja11xx_hw_stats[i].off;433 }434 }435}436 437static int tja11xx_hwmon_read(struct device *dev,438 enum hwmon_sensor_types type,439 u32 attr, int channel, long *value)440{441 struct phy_device *phydev = dev_get_drvdata(dev);442 int ret;443 444 if (type == hwmon_in && attr == hwmon_in_lcrit_alarm) {445 ret = phy_read(phydev, MII_INTSRC);446 if (ret < 0)447 return ret;448 449 *value = !!(ret & MII_INTSRC_TEMP_ERR);450 return 0;451 }452 453 if (type == hwmon_temp && attr == hwmon_temp_crit_alarm) {454 ret = phy_read(phydev, MII_INTSRC);455 if (ret < 0)456 return ret;457 458 *value = !!(ret & MII_INTSRC_UV_ERR);459 return 0;460 }461 462 return -EOPNOTSUPP;463}464 465static umode_t tja11xx_hwmon_is_visible(const void *data,466 enum hwmon_sensor_types type,467 u32 attr, int channel)468{469 if (type == hwmon_in && attr == hwmon_in_lcrit_alarm)470 return 0444;471 472 if (type == hwmon_temp && attr == hwmon_temp_crit_alarm)473 return 0444;474 475 return 0;476}477 478static const struct hwmon_channel_info * const tja11xx_hwmon_info[] = {479 HWMON_CHANNEL_INFO(in, HWMON_I_LCRIT_ALARM),480 HWMON_CHANNEL_INFO(temp, HWMON_T_CRIT_ALARM),481 NULL482};483 484static const struct hwmon_ops tja11xx_hwmon_hwmon_ops = {485 .is_visible = tja11xx_hwmon_is_visible,486 .read = tja11xx_hwmon_read,487};488 489static const struct hwmon_chip_info tja11xx_hwmon_chip_info = {490 .ops = &tja11xx_hwmon_hwmon_ops,491 .info = tja11xx_hwmon_info,492};493 494static int tja11xx_hwmon_register(struct phy_device *phydev,495 struct tja11xx_priv *priv)496{497 struct device *dev = &phydev->mdio.dev;498 499 priv->hwmon_name = devm_hwmon_sanitize_name(dev, dev_name(dev));500 if (IS_ERR(priv->hwmon_name))501 return PTR_ERR(priv->hwmon_name);502 503 priv->hwmon_dev =504 devm_hwmon_device_register_with_info(dev, priv->hwmon_name,505 phydev,506 &tja11xx_hwmon_chip_info,507 NULL);508 509 return PTR_ERR_OR_ZERO(priv->hwmon_dev);510}511 512static int tja11xx_parse_dt(struct phy_device *phydev)513{514 struct device_node *node = phydev->mdio.dev.of_node;515 struct tja11xx_priv *priv = phydev->priv;516 517 if (!IS_ENABLED(CONFIG_OF_MDIO))518 return 0;519 520 if (of_property_read_bool(node, "nxp,rmii-refclk-in"))521 priv->flags |= TJA110X_RMII_MODE_REFCLK_IN;522 523 return 0;524}525 526static int tja11xx_probe(struct phy_device *phydev)527{528 struct device *dev = &phydev->mdio.dev;529 struct tja11xx_priv *priv;530 int ret;531 532 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);533 if (!priv)534 return -ENOMEM;535 536 priv->phydev = phydev;537 phydev->priv = priv;538 539 ret = tja11xx_parse_dt(phydev);540 if (ret)541 return ret;542 543 return tja11xx_hwmon_register(phydev, priv);544}545 546static void tja1102_p1_register(struct work_struct *work)547{548 struct tja11xx_priv *priv = container_of(work, struct tja11xx_priv,549 phy_register_work);550 struct phy_device *phydev_phy0 = priv->phydev;551 struct mii_bus *bus = phydev_phy0->mdio.bus;552 struct device *dev = &phydev_phy0->mdio.dev;553 struct device_node *np = dev->of_node;554 struct device_node *child;555 int ret;556 557 for_each_available_child_of_node(np, child) {558 struct phy_device *phy;559 int addr;560 561 addr = of_mdio_parse_addr(dev, child);562 if (addr < 0) {563 dev_err(dev, "Can't parse addr\n");564 continue;565 } else if (addr != phydev_phy0->mdio.addr + 1) {566 /* Currently we care only about double PHY chip TJA1102.567 * If some day NXP will decide to bring chips with more568 * PHYs, this logic should be reworked.569 */570 dev_err(dev, "Unexpected address. Should be: %i\n",571 phydev_phy0->mdio.addr + 1);572 continue;573 }574 575 if (mdiobus_is_registered_device(bus, addr)) {576 dev_err(dev, "device is already registered\n");577 continue;578 }579 580 /* Real PHY ID of Port 1 is 0 */581 phy = phy_device_create(bus, addr, PHY_ID_TJA1102, false, NULL);582 if (IS_ERR(phy)) {583 dev_err(dev, "Can't create PHY device for Port 1: %i\n",584 addr);585 continue;586 }587 588 /* Overwrite parent device. phy_device_create() set parent to589 * the mii_bus->dev, which is not correct in case.590 */591 phy->mdio.dev.parent = dev;592 593 ret = of_mdiobus_phy_device_register(bus, phy, child, addr);594 if (ret) {595 /* All resources needed for Port 1 should be already596 * available for Port 0. Both ports use the same597 * interrupt line, so -EPROBE_DEFER would make no sense598 * here.599 */600 dev_err(dev, "Can't register Port 1. Unexpected error: %i\n",601 ret);602 phy_device_free(phy);603 }604 }605}606 607static int tja1102_p0_probe(struct phy_device *phydev)608{609 struct device *dev = &phydev->mdio.dev;610 struct tja11xx_priv *priv;611 int ret;612 613 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);614 if (!priv)615 return -ENOMEM;616 617 priv->phydev = phydev;618 INIT_WORK(&priv->phy_register_work, tja1102_p1_register);619 620 ret = tja11xx_hwmon_register(phydev, priv);621 if (ret)622 return ret;623 624 schedule_work(&priv->phy_register_work);625 626 return 0;627}628 629static int tja1102_match_phy_device(struct phy_device *phydev, bool port0)630{631 int ret;632 633 if ((phydev->phy_id & PHY_ID_MASK) != PHY_ID_TJA1102)634 return 0;635 636 ret = phy_read(phydev, MII_PHYSID2);637 if (ret < 0)638 return ret;639 640 /* TJA1102 Port 1 has phyid 0 and doesn't support temperature641 * and undervoltage alarms.642 */643 if (port0)644 return ret ? 1 : 0;645 646 return !ret;647}648 649static int tja1102_p0_match_phy_device(struct phy_device *phydev)650{651 return tja1102_match_phy_device(phydev, true);652}653 654static int tja1102_p1_match_phy_device(struct phy_device *phydev)655{656 return tja1102_match_phy_device(phydev, false);657}658 659static int tja11xx_ack_interrupt(struct phy_device *phydev)660{661 int ret;662 663 ret = phy_read(phydev, MII_INTSRC);664 665 return (ret < 0) ? ret : 0;666}667 668static int tja11xx_config_intr(struct phy_device *phydev)669{670 int value = 0;671 int err;672 673 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {674 err = tja11xx_ack_interrupt(phydev);675 if (err)676 return err;677 678 value = MII_INTEN_LINK_FAIL | MII_INTEN_LINK_UP |679 MII_INTEN_UV_ERR | MII_INTEN_TEMP_ERR;680 err = phy_write(phydev, MII_INTEN, value);681 } else {682 err = phy_write(phydev, MII_INTEN, value);683 if (err)684 return err;685 686 err = tja11xx_ack_interrupt(phydev);687 }688 689 return err;690}691 692static irqreturn_t tja11xx_handle_interrupt(struct phy_device *phydev)693{694 struct device *dev = &phydev->mdio.dev;695 int irq_status;696 697 irq_status = phy_read(phydev, MII_INTSRC);698 if (irq_status < 0) {699 phy_error(phydev);700 return IRQ_NONE;701 }702 703 if (irq_status & MII_INTSRC_TEMP_ERR)704 dev_warn(dev, "Overtemperature error detected (temp > 155C°).\n");705 if (irq_status & MII_INTSRC_UV_ERR)706 dev_warn(dev, "Undervoltage error detected.\n");707 708 if (!(irq_status & MII_INTSRC_MASK))709 return IRQ_NONE;710 711 phy_trigger_machine(phydev);712 713 return IRQ_HANDLED;714}715 716static int tja11xx_cable_test_start(struct phy_device *phydev)717{718 int ret;719 720 ret = phy_clear_bits(phydev, MII_COMMCFG, MII_COMMCFG_AUTO_OP);721 if (ret)722 return ret;723 724 ret = tja11xx_wakeup(phydev);725 if (ret < 0)726 return ret;727 728 ret = tja11xx_disable_link_control(phydev);729 if (ret < 0)730 return ret;731 732 return phy_set_bits(phydev, MII_ECTRL, MII_ECTRL_CABLE_TEST);733}734 735/*736 * | BI_DA+ | BI_DA- | Result737 * | open | open | open738 * | + short to - | - short to + | short739 * | short to Vdd | open | open740 * | open | shot to Vdd | open741 * | short to Vdd | short to Vdd | short742 * | shot to GND | open | open743 * | open | shot to GND | open744 * | short to GND | shot to GND | short745 * | connected to active link partner (master) | shot and open746 */747static int tja11xx_cable_test_report_trans(u32 result)748{749 u32 mask = MII_EXTSTAT_SHORT_DETECT | MII_EXTSTAT_OPEN_DETECT;750 751 if ((result & mask) == mask) {752 /* connected to active link partner (master) */753 return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;754 } else if ((result & mask) == 0) {755 return ETHTOOL_A_CABLE_RESULT_CODE_OK;756 } else if (result & MII_EXTSTAT_SHORT_DETECT) {757 return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT;758 } else if (result & MII_EXTSTAT_OPEN_DETECT) {759 return ETHTOOL_A_CABLE_RESULT_CODE_OPEN;760 } else {761 return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;762 }763}764 765static int tja11xx_cable_test_report(struct phy_device *phydev)766{767 int ret;768 769 ret = phy_read(phydev, MII_EXTSTAT);770 if (ret < 0)771 return ret;772 773 ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A,774 tja11xx_cable_test_report_trans(ret));775 776 return 0;777}778 779static int tja11xx_cable_test_get_status(struct phy_device *phydev,780 bool *finished)781{782 int ret;783 784 *finished = false;785 786 ret = phy_read(phydev, MII_ECTRL);787 if (ret < 0)788 return ret;789 790 if (!(ret & MII_ECTRL_CABLE_TEST)) {791 *finished = true;792 793 ret = phy_set_bits(phydev, MII_COMMCFG, MII_COMMCFG_AUTO_OP);794 if (ret)795 return ret;796 797 return tja11xx_cable_test_report(phydev);798 }799 800 return 0;801}802 803static struct phy_driver tja11xx_driver[] = {804 {805 PHY_ID_MATCH_MODEL(PHY_ID_TJA1100),806 .name = "NXP TJA1100",807 .features = PHY_BASIC_T1_FEATURES,808 .probe = tja11xx_probe,809 .soft_reset = tja11xx_soft_reset,810 .config_aneg = tja11xx_config_aneg,811 .config_init = tja11xx_config_init,812 .read_status = tja11xx_read_status,813 .get_sqi = tja11xx_get_sqi,814 .get_sqi_max = tja11xx_get_sqi_max,815 .suspend = genphy_suspend,816 .resume = genphy_resume,817 .set_loopback = genphy_loopback,818 /* Statistics */819 .get_sset_count = tja11xx_get_sset_count,820 .get_strings = tja11xx_get_strings,821 .get_stats = tja11xx_get_stats,822 }, {823 PHY_ID_MATCH_MODEL(PHY_ID_TJA1101),824 .name = "NXP TJA1101",825 .features = PHY_BASIC_T1_FEATURES,826 .probe = tja11xx_probe,827 .soft_reset = tja11xx_soft_reset,828 .config_aneg = tja11xx_config_aneg,829 .config_init = tja11xx_config_init,830 .read_status = tja11xx_read_status,831 .get_sqi = tja11xx_get_sqi,832 .get_sqi_max = tja11xx_get_sqi_max,833 .suspend = genphy_suspend,834 .resume = genphy_resume,835 .set_loopback = genphy_loopback,836 /* Statistics */837 .get_sset_count = tja11xx_get_sset_count,838 .get_strings = tja11xx_get_strings,839 .get_stats = tja11xx_get_stats,840 }, {841 .name = "NXP TJA1102 Port 0",842 .features = PHY_BASIC_T1_FEATURES,843 .flags = PHY_POLL_CABLE_TEST,844 .probe = tja1102_p0_probe,845 .soft_reset = tja11xx_soft_reset,846 .config_aneg = tja11xx_config_aneg,847 .config_init = tja11xx_config_init,848 .read_status = tja11xx_read_status,849 .get_sqi = tja11xx_get_sqi,850 .get_sqi_max = tja11xx_get_sqi_max,851 .match_phy_device = tja1102_p0_match_phy_device,852 .suspend = genphy_suspend,853 .resume = genphy_resume,854 .set_loopback = genphy_loopback,855 /* Statistics */856 .get_sset_count = tja11xx_get_sset_count,857 .get_strings = tja11xx_get_strings,858 .get_stats = tja11xx_get_stats,859 .config_intr = tja11xx_config_intr,860 .handle_interrupt = tja11xx_handle_interrupt,861 .cable_test_start = tja11xx_cable_test_start,862 .cable_test_get_status = tja11xx_cable_test_get_status,863 }, {864 .name = "NXP TJA1102 Port 1",865 .features = PHY_BASIC_T1_FEATURES,866 .flags = PHY_POLL_CABLE_TEST,867 /* currently no probe for Port 1 is need */868 .soft_reset = tja11xx_soft_reset,869 .config_aneg = tja11xx_config_aneg,870 .config_init = tja11xx_config_init,871 .read_status = tja11xx_read_status,872 .get_sqi = tja11xx_get_sqi,873 .get_sqi_max = tja11xx_get_sqi_max,874 .match_phy_device = tja1102_p1_match_phy_device,875 .suspend = genphy_suspend,876 .resume = genphy_resume,877 .set_loopback = genphy_loopback,878 /* Statistics */879 .get_sset_count = tja11xx_get_sset_count,880 .get_strings = tja11xx_get_strings,881 .get_stats = tja11xx_get_stats,882 .config_intr = tja11xx_config_intr,883 .handle_interrupt = tja11xx_handle_interrupt,884 .cable_test_start = tja11xx_cable_test_start,885 .cable_test_get_status = tja11xx_cable_test_get_status,886 }887};888 889module_phy_driver(tja11xx_driver);890 891static struct mdio_device_id __maybe_unused tja11xx_tbl[] = {892 { PHY_ID_MATCH_MODEL(PHY_ID_TJA1100) },893 { PHY_ID_MATCH_MODEL(PHY_ID_TJA1101) },894 { PHY_ID_MATCH_MODEL(PHY_ID_TJA1102) },895 { }896};897 898MODULE_DEVICE_TABLE(mdio, tja11xx_tbl);899 900MODULE_AUTHOR("Marek Vasut <marex@denx.de>");901MODULE_DESCRIPTION("NXP TJA11xx BoardR-Reach PHY driver");902MODULE_LICENSE("GPL");903