1124 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Driver for Aquantia PHY4 *5 * Author: Shaohui Xie <Shaohui.Xie@freescale.com>6 *7 * Copyright 2015 Freescale Semiconductor, Inc.8 */9 10#include <linux/kernel.h>11#include <linux/module.h>12#include <linux/delay.h>13#include <linux/bitfield.h>14#include <linux/phy.h>15 16#include "aquantia.h"17 18#define PHY_ID_AQ1202 0x03a1b44519#define PHY_ID_AQ2104 0x03a1b46020#define PHY_ID_AQR105 0x03a1b4a221#define PHY_ID_AQR106 0x03a1b4d022#define PHY_ID_AQR107 0x03a1b4e023#define PHY_ID_AQCS109 0x03a1b5c224#define PHY_ID_AQR405 0x03a1b4b025#define PHY_ID_AQR111 0x03a1b61026#define PHY_ID_AQR111B0 0x03a1b61227#define PHY_ID_AQR112 0x03a1b66228#define PHY_ID_AQR412 0x03a1b71229#define PHY_ID_AQR113 0x31c31c4030#define PHY_ID_AQR113C 0x31c31c1231#define PHY_ID_AQR114C 0x31c31c2232#define PHY_ID_AQR115C 0x31c31c3333#define PHY_ID_AQR813 0x31c31cb234 35#define MDIO_PHYXS_VEND_IF_STATUS 0xe81236#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3)37#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR 038#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KX 139#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI 240#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII 341#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI 442#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII 643#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI 744#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII 1045 46#define MDIO_AN_VEND_PROV 0xc40047#define MDIO_AN_VEND_PROV_1000BASET_FULL BIT(15)48#define MDIO_AN_VEND_PROV_1000BASET_HALF BIT(14)49#define MDIO_AN_VEND_PROV_5000BASET_FULL BIT(11)50#define MDIO_AN_VEND_PROV_2500BASET_FULL BIT(10)51#define MDIO_AN_VEND_PROV_DOWNSHIFT_EN BIT(4)52#define MDIO_AN_VEND_PROV_DOWNSHIFT_MASK GENMASK(3, 0)53#define MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT 454 55#define MDIO_AN_TX_VEND_STATUS1 0xc80056#define MDIO_AN_TX_VEND_STATUS1_RATE_MASK GENMASK(3, 1)57#define MDIO_AN_TX_VEND_STATUS1_10BASET 058#define MDIO_AN_TX_VEND_STATUS1_100BASETX 159#define MDIO_AN_TX_VEND_STATUS1_1000BASET 260#define MDIO_AN_TX_VEND_STATUS1_10GBASET 361#define MDIO_AN_TX_VEND_STATUS1_2500BASET 462#define MDIO_AN_TX_VEND_STATUS1_5000BASET 563#define MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX BIT(0)64 65#define MDIO_AN_TX_VEND_INT_STATUS1 0xcc0066#define MDIO_AN_TX_VEND_INT_STATUS1_DOWNSHIFT BIT(1)67 68#define MDIO_AN_TX_VEND_INT_STATUS2 0xcc0169#define MDIO_AN_TX_VEND_INT_STATUS2_MASK BIT(0)70 71#define MDIO_AN_TX_VEND_INT_MASK2 0xd40172#define MDIO_AN_TX_VEND_INT_MASK2_LINK BIT(0)73 74#define MDIO_AN_RX_LP_STAT1 0xe82075#define MDIO_AN_RX_LP_STAT1_1000BASET_FULL BIT(15)76#define MDIO_AN_RX_LP_STAT1_1000BASET_HALF BIT(14)77#define MDIO_AN_RX_LP_STAT1_SHORT_REACH BIT(13)78#define MDIO_AN_RX_LP_STAT1_AQRATE_DOWNSHIFT BIT(12)79#define MDIO_AN_RX_LP_STAT1_AQ_PHY BIT(2)80 81#define MDIO_AN_RX_LP_STAT4 0xe82382#define MDIO_AN_RX_LP_STAT4_FW_MAJOR GENMASK(15, 8)83#define MDIO_AN_RX_LP_STAT4_FW_MINOR GENMASK(7, 0)84 85#define MDIO_AN_RX_VEND_STAT3 0xe83286#define MDIO_AN_RX_VEND_STAT3_AFR BIT(0)87 88/* Sleep and timeout for checking if the Processor-Intensive89 * MDIO operation is finished90 */91#define AQR107_OP_IN_PROG_SLEEP 100092#define AQR107_OP_IN_PROG_TIMEOUT 10000093 94static int aqr107_get_sset_count(struct phy_device *phydev)95{96 return AQR107_SGMII_STAT_SZ;97}98 99static void aqr107_get_strings(struct phy_device *phydev, u8 *data)100{101 int i;102 103 for (i = 0; i < AQR107_SGMII_STAT_SZ; i++)104 strscpy(data + i * ETH_GSTRING_LEN, aqr107_hw_stats[i].name,105 ETH_GSTRING_LEN);106}107 108static u64 aqr107_get_stat(struct phy_device *phydev, int index)109{110 const struct aqr107_hw_stat *stat = aqr107_hw_stats + index;111 int len_l = min(stat->size, 16);112 int len_h = stat->size - len_l;113 u64 ret;114 int val;115 116 val = phy_read_mmd(phydev, MDIO_MMD_C22EXT, stat->reg);117 if (val < 0)118 return U64_MAX;119 120 ret = val & GENMASK(len_l - 1, 0);121 if (len_h) {122 val = phy_read_mmd(phydev, MDIO_MMD_C22EXT, stat->reg + 1);123 if (val < 0)124 return U64_MAX;125 126 ret += (val & GENMASK(len_h - 1, 0)) << 16;127 }128 129 return ret;130}131 132static void aqr107_get_stats(struct phy_device *phydev,133 struct ethtool_stats *stats, u64 *data)134{135 struct aqr107_priv *priv = phydev->priv;136 u64 val;137 int i;138 139 for (i = 0; i < AQR107_SGMII_STAT_SZ; i++) {140 val = aqr107_get_stat(phydev, i);141 if (val == U64_MAX)142 phydev_err(phydev, "Reading HW Statistics failed for %s\n",143 aqr107_hw_stats[i].name);144 else145 priv->sgmii_stats[i] += val;146 147 data[i] = priv->sgmii_stats[i];148 }149}150 151static int aqr_config_aneg(struct phy_device *phydev)152{153 bool changed = false;154 u16 reg;155 int ret;156 157 if (phydev->autoneg == AUTONEG_DISABLE)158 return genphy_c45_pma_setup_forced(phydev);159 160 ret = genphy_c45_an_config_aneg(phydev);161 if (ret < 0)162 return ret;163 if (ret > 0)164 changed = true;165 166 /* Clause 45 has no standardized support for 1000BaseT, therefore167 * use vendor registers for this mode.168 */169 reg = 0;170 if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,171 phydev->advertising))172 reg |= MDIO_AN_VEND_PROV_1000BASET_FULL;173 174 if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,175 phydev->advertising))176 reg |= MDIO_AN_VEND_PROV_1000BASET_HALF;177 178 /* Handle the case when the 2.5G and 5G speeds are not advertised */179 if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,180 phydev->advertising))181 reg |= MDIO_AN_VEND_PROV_2500BASET_FULL;182 183 if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,184 phydev->advertising))185 reg |= MDIO_AN_VEND_PROV_5000BASET_FULL;186 187 ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV,188 MDIO_AN_VEND_PROV_1000BASET_HALF |189 MDIO_AN_VEND_PROV_1000BASET_FULL |190 MDIO_AN_VEND_PROV_2500BASET_FULL |191 MDIO_AN_VEND_PROV_5000BASET_FULL, reg);192 if (ret < 0)193 return ret;194 if (ret > 0)195 changed = true;196 197 return genphy_c45_check_and_restart_aneg(phydev, changed);198}199 200static int aqr_config_intr(struct phy_device *phydev)201{202 bool en = phydev->interrupts == PHY_INTERRUPT_ENABLED;203 int err;204 205 if (en) {206 /* Clear any pending interrupts before enabling them */207 err = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_STATUS2);208 if (err < 0)209 return err;210 }211 212 err = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_MASK2,213 en ? MDIO_AN_TX_VEND_INT_MASK2_LINK : 0);214 if (err < 0)215 return err;216 217 err = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_INT_STD_MASK,218 en ? VEND1_GLOBAL_INT_STD_MASK_ALL : 0);219 if (err < 0)220 return err;221 222 err = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_INT_VEND_MASK,223 en ? VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 |224 VEND1_GLOBAL_INT_VEND_MASK_AN : 0);225 if (err < 0)226 return err;227 228 if (!en) {229 /* Clear any pending interrupts after we have disabled them */230 err = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_STATUS2);231 if (err < 0)232 return err;233 }234 235 return 0;236}237 238static irqreturn_t aqr_handle_interrupt(struct phy_device *phydev)239{240 int irq_status;241 242 irq_status = phy_read_mmd(phydev, MDIO_MMD_AN,243 MDIO_AN_TX_VEND_INT_STATUS2);244 if (irq_status < 0) {245 phy_error(phydev);246 return IRQ_NONE;247 }248 249 if (!(irq_status & MDIO_AN_TX_VEND_INT_STATUS2_MASK))250 return IRQ_NONE;251 252 phy_trigger_machine(phydev);253 254 return IRQ_HANDLED;255}256 257static int aqr_read_status(struct phy_device *phydev)258{259 int val;260 261 if (phydev->autoneg == AUTONEG_ENABLE) {262 val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT1);263 if (val < 0)264 return val;265 266 linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,267 phydev->lp_advertising,268 val & MDIO_AN_RX_LP_STAT1_1000BASET_FULL);269 linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,270 phydev->lp_advertising,271 val & MDIO_AN_RX_LP_STAT1_1000BASET_HALF);272 }273 274 return genphy_c45_read_status(phydev);275}276 277static int aqr107_read_rate(struct phy_device *phydev)278{279 u32 config_reg;280 int val;281 282 val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_STATUS1);283 if (val < 0)284 return val;285 286 if (val & MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX)287 phydev->duplex = DUPLEX_FULL;288 else289 phydev->duplex = DUPLEX_HALF;290 291 switch (FIELD_GET(MDIO_AN_TX_VEND_STATUS1_RATE_MASK, val)) {292 case MDIO_AN_TX_VEND_STATUS1_10BASET:293 phydev->speed = SPEED_10;294 config_reg = VEND1_GLOBAL_CFG_10M;295 break;296 case MDIO_AN_TX_VEND_STATUS1_100BASETX:297 phydev->speed = SPEED_100;298 config_reg = VEND1_GLOBAL_CFG_100M;299 break;300 case MDIO_AN_TX_VEND_STATUS1_1000BASET:301 phydev->speed = SPEED_1000;302 config_reg = VEND1_GLOBAL_CFG_1G;303 break;304 case MDIO_AN_TX_VEND_STATUS1_2500BASET:305 phydev->speed = SPEED_2500;306 config_reg = VEND1_GLOBAL_CFG_2_5G;307 break;308 case MDIO_AN_TX_VEND_STATUS1_5000BASET:309 phydev->speed = SPEED_5000;310 config_reg = VEND1_GLOBAL_CFG_5G;311 break;312 case MDIO_AN_TX_VEND_STATUS1_10GBASET:313 phydev->speed = SPEED_10000;314 config_reg = VEND1_GLOBAL_CFG_10G;315 break;316 default:317 phydev->speed = SPEED_UNKNOWN;318 return 0;319 }320 321 val = phy_read_mmd(phydev, MDIO_MMD_VEND1, config_reg);322 if (val < 0)323 return val;324 325 if (FIELD_GET(VEND1_GLOBAL_CFG_RATE_ADAPT, val) ==326 VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE)327 phydev->rate_matching = RATE_MATCH_PAUSE;328 else329 phydev->rate_matching = RATE_MATCH_NONE;330 331 return 0;332}333 334static int aqr107_read_status(struct phy_device *phydev)335{336 int val, ret;337 338 ret = aqr_read_status(phydev);339 if (ret)340 return ret;341 342 if (!phydev->link || phydev->autoneg == AUTONEG_DISABLE)343 return 0;344 345 val = phy_read_mmd(phydev, MDIO_MMD_PHYXS, MDIO_PHYXS_VEND_IF_STATUS);346 if (val < 0)347 return val;348 349 switch (FIELD_GET(MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK, val)) {350 case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR:351 phydev->interface = PHY_INTERFACE_MODE_10GKR;352 break;353 case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KX:354 phydev->interface = PHY_INTERFACE_MODE_1000BASEKX;355 break;356 case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI:357 phydev->interface = PHY_INTERFACE_MODE_10GBASER;358 break;359 case MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII:360 phydev->interface = PHY_INTERFACE_MODE_USXGMII;361 break;362 case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI:363 phydev->interface = PHY_INTERFACE_MODE_XAUI;364 break;365 case MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII:366 phydev->interface = PHY_INTERFACE_MODE_SGMII;367 break;368 case MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI:369 phydev->interface = PHY_INTERFACE_MODE_RXAUI;370 break;371 case MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII:372 phydev->interface = PHY_INTERFACE_MODE_2500BASEX;373 break;374 default:375 phydev->interface = PHY_INTERFACE_MODE_NA;376 break;377 }378 379 /* Read possibly downshifted rate from vendor register */380 return aqr107_read_rate(phydev);381}382 383static int aqr107_get_downshift(struct phy_device *phydev, u8 *data)384{385 int val, cnt, enable;386 387 val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV);388 if (val < 0)389 return val;390 391 enable = FIELD_GET(MDIO_AN_VEND_PROV_DOWNSHIFT_EN, val);392 cnt = FIELD_GET(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, val);393 394 *data = enable && cnt ? cnt : DOWNSHIFT_DEV_DISABLE;395 396 return 0;397}398 399static int aqr107_set_downshift(struct phy_device *phydev, u8 cnt)400{401 int val = 0;402 403 if (!FIELD_FIT(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, cnt))404 return -E2BIG;405 406 if (cnt != DOWNSHIFT_DEV_DISABLE) {407 val = MDIO_AN_VEND_PROV_DOWNSHIFT_EN;408 val |= FIELD_PREP(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, cnt);409 }410 411 return phy_modify_mmd(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV,412 MDIO_AN_VEND_PROV_DOWNSHIFT_EN |413 MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, val);414}415 416static int aqr107_get_tunable(struct phy_device *phydev,417 struct ethtool_tunable *tuna, void *data)418{419 switch (tuna->id) {420 case ETHTOOL_PHY_DOWNSHIFT:421 return aqr107_get_downshift(phydev, data);422 default:423 return -EOPNOTSUPP;424 }425}426 427static int aqr107_set_tunable(struct phy_device *phydev,428 struct ethtool_tunable *tuna, const void *data)429{430 switch (tuna->id) {431 case ETHTOOL_PHY_DOWNSHIFT:432 return aqr107_set_downshift(phydev, *(const u8 *)data);433 default:434 return -EOPNOTSUPP;435 }436}437 438#define AQR_FW_WAIT_SLEEP_US 20000439#define AQR_FW_WAIT_TIMEOUT_US 2000000440 441/* If we configure settings whilst firmware is still initializing the chip,442 * then these settings may be overwritten. Therefore make sure chip443 * initialization has completed. Use presence of the firmware ID as444 * indicator for initialization having completed.445 * The chip also provides a "reset completed" bit, but it's cleared after446 * read. Therefore function would time out if called again.447 */448int aqr_wait_reset_complete(struct phy_device *phydev)449{450 int ret, val;451 452 ret = read_poll_timeout(phy_read_mmd, val, val != 0,453 AQR_FW_WAIT_SLEEP_US, AQR_FW_WAIT_TIMEOUT_US,454 false, phydev, MDIO_MMD_VEND1,455 VEND1_GLOBAL_FW_ID);456 if (val < 0) {457 phydev_err(phydev, "Failed to read VEND1_GLOBAL_FW_ID: %pe\n",458 ERR_PTR(val));459 return val;460 }461 462 return ret;463}464 465static void aqr107_chip_info(struct phy_device *phydev)466{467 u8 fw_major, fw_minor, build_id, prov_id;468 int val;469 470 val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_FW_ID);471 if (val < 0)472 return;473 474 fw_major = FIELD_GET(VEND1_GLOBAL_FW_ID_MAJOR, val);475 fw_minor = FIELD_GET(VEND1_GLOBAL_FW_ID_MINOR, val);476 477 val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_RSVD_STAT1);478 if (val < 0)479 return;480 481 build_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID, val);482 prov_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_PROV_ID, val);483 484 phydev_dbg(phydev, "FW %u.%u, Build %u, Provisioning %u\n",485 fw_major, fw_minor, build_id, prov_id);486}487 488static int aqr107_config_init(struct phy_device *phydev)489{490 struct aqr107_priv *priv = phydev->priv;491 u32 led_active_low;492 int ret;493 494 /* Check that the PHY interface type is compatible */495 if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&496 phydev->interface != PHY_INTERFACE_MODE_1000BASEKX &&497 phydev->interface != PHY_INTERFACE_MODE_2500BASEX &&498 phydev->interface != PHY_INTERFACE_MODE_XGMII &&499 phydev->interface != PHY_INTERFACE_MODE_USXGMII &&500 phydev->interface != PHY_INTERFACE_MODE_10GKR &&501 phydev->interface != PHY_INTERFACE_MODE_10GBASER &&502 phydev->interface != PHY_INTERFACE_MODE_XAUI &&503 phydev->interface != PHY_INTERFACE_MODE_RXAUI)504 return -ENODEV;505 506 WARN(phydev->interface == PHY_INTERFACE_MODE_XGMII,507 "Your devicetree is out of date, please update it. The AQR107 family doesn't support XGMII, maybe you mean USXGMII.\n");508 509 ret = aqr_wait_reset_complete(phydev);510 if (!ret)511 aqr107_chip_info(phydev);512 513 ret = aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);514 if (ret)515 return ret;516 517 /* Restore LED polarity state after reset */518 for_each_set_bit(led_active_low, &priv->leds_active_low, AQR_MAX_LEDS) {519 ret = aqr_phy_led_active_low_set(phydev, led_active_low, true);520 if (ret)521 return ret;522 }523 524 return 0;525}526 527static int aqcs109_config_init(struct phy_device *phydev)528{529 int ret;530 531 /* Check that the PHY interface type is compatible */532 if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&533 phydev->interface != PHY_INTERFACE_MODE_2500BASEX)534 return -ENODEV;535 536 ret = aqr_wait_reset_complete(phydev);537 if (!ret)538 aqr107_chip_info(phydev);539 540 return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);541}542 543static void aqr107_link_change_notify(struct phy_device *phydev)544{545 u8 fw_major, fw_minor;546 bool downshift, short_reach, afr;547 int mode, val;548 549 if (phydev->state != PHY_RUNNING || phydev->autoneg == AUTONEG_DISABLE)550 return;551 552 val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT1);553 /* call failed or link partner is no Aquantia PHY */554 if (val < 0 || !(val & MDIO_AN_RX_LP_STAT1_AQ_PHY))555 return;556 557 short_reach = val & MDIO_AN_RX_LP_STAT1_SHORT_REACH;558 downshift = val & MDIO_AN_RX_LP_STAT1_AQRATE_DOWNSHIFT;559 560 val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT4);561 if (val < 0)562 return;563 564 fw_major = FIELD_GET(MDIO_AN_RX_LP_STAT4_FW_MAJOR, val);565 fw_minor = FIELD_GET(MDIO_AN_RX_LP_STAT4_FW_MINOR, val);566 567 val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_VEND_STAT3);568 if (val < 0)569 return;570 571 afr = val & MDIO_AN_RX_VEND_STAT3_AFR;572 573 phydev_dbg(phydev, "Link partner is Aquantia PHY, FW %u.%u%s%s%s\n",574 fw_major, fw_minor,575 short_reach ? ", short reach mode" : "",576 downshift ? ", fast-retrain downshift advertised" : "",577 afr ? ", fast reframe advertised" : "");578 579 val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_RSVD_STAT9);580 if (val < 0)581 return;582 583 mode = FIELD_GET(VEND1_GLOBAL_RSVD_STAT9_MODE, val);584 if (mode == VEND1_GLOBAL_RSVD_STAT9_1000BT2)585 phydev_info(phydev, "Aquantia 1000Base-T2 mode active\n");586}587 588static int aqr107_wait_processor_intensive_op(struct phy_device *phydev)589{590 int val, err;591 592 /* The datasheet notes to wait at least 1ms after issuing a593 * processor intensive operation before checking.594 * We cannot use the 'sleep_before_read' parameter of read_poll_timeout595 * because that just determines the maximum time slept, not the minimum.596 */597 usleep_range(1000, 5000);598 599 err = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,600 VEND1_GLOBAL_GEN_STAT2, val,601 !(val & VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG),602 AQR107_OP_IN_PROG_SLEEP,603 AQR107_OP_IN_PROG_TIMEOUT, false);604 if (err) {605 phydev_err(phydev, "timeout: processor-intensive MDIO operation\n");606 return err;607 }608 609 return 0;610}611 612static int aqr107_get_rate_matching(struct phy_device *phydev,613 phy_interface_t iface)614{615 if (iface == PHY_INTERFACE_MODE_10GBASER ||616 iface == PHY_INTERFACE_MODE_2500BASEX ||617 iface == PHY_INTERFACE_MODE_NA)618 return RATE_MATCH_PAUSE;619 return RATE_MATCH_NONE;620}621 622static int aqr107_suspend(struct phy_device *phydev)623{624 int err;625 626 err = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1,627 MDIO_CTRL1_LPOWER);628 if (err)629 return err;630 631 return aqr107_wait_processor_intensive_op(phydev);632}633 634static int aqr107_resume(struct phy_device *phydev)635{636 int err;637 638 err = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1,639 MDIO_CTRL1_LPOWER);640 if (err)641 return err;642 643 return aqr107_wait_processor_intensive_op(phydev);644}645 646static const u16 aqr_global_cfg_regs[] = {647 VEND1_GLOBAL_CFG_10M,648 VEND1_GLOBAL_CFG_100M,649 VEND1_GLOBAL_CFG_1G,650 VEND1_GLOBAL_CFG_2_5G,651 VEND1_GLOBAL_CFG_5G,652 VEND1_GLOBAL_CFG_10G653};654 655static int aqr107_fill_interface_modes(struct phy_device *phydev)656{657 unsigned long *possible = phydev->possible_interfaces;658 unsigned int serdes_mode, rate_adapt;659 phy_interface_t interface;660 int i, val;661 662 /* Walk the media-speed configuration registers to determine which663 * host-side serdes modes may be used by the PHY depending on the664 * negotiated media speed.665 */666 for (i = 0; i < ARRAY_SIZE(aqr_global_cfg_regs); i++) {667 val = phy_read_mmd(phydev, MDIO_MMD_VEND1,668 aqr_global_cfg_regs[i]);669 if (val < 0)670 return val;671 672 serdes_mode = FIELD_GET(VEND1_GLOBAL_CFG_SERDES_MODE, val);673 rate_adapt = FIELD_GET(VEND1_GLOBAL_CFG_RATE_ADAPT, val);674 675 switch (serdes_mode) {676 case VEND1_GLOBAL_CFG_SERDES_MODE_XFI:677 if (rate_adapt == VEND1_GLOBAL_CFG_RATE_ADAPT_USX)678 interface = PHY_INTERFACE_MODE_USXGMII;679 else680 interface = PHY_INTERFACE_MODE_10GBASER;681 break;682 683 case VEND1_GLOBAL_CFG_SERDES_MODE_XFI5G:684 interface = PHY_INTERFACE_MODE_5GBASER;685 break;686 687 case VEND1_GLOBAL_CFG_SERDES_MODE_OCSGMII:688 interface = PHY_INTERFACE_MODE_2500BASEX;689 break;690 691 case VEND1_GLOBAL_CFG_SERDES_MODE_SGMII:692 interface = PHY_INTERFACE_MODE_SGMII;693 break;694 695 default:696 phydev_warn(phydev, "unrecognised serdes mode %u\n",697 serdes_mode);698 interface = PHY_INTERFACE_MODE_NA;699 break;700 }701 702 if (interface != PHY_INTERFACE_MODE_NA)703 __set_bit(interface, possible);704 }705 706 return 0;707}708 709static int aqr113c_fill_interface_modes(struct phy_device *phydev)710{711 int val, ret;712 713 /* It's been observed on some models that - when coming out of suspend714 * - the FW signals that the PHY is ready but the GLOBAL_CFG registers715 * continue on returning zeroes for some time. Let's poll the 100M716 * register until it returns a real value as both 113c and 115c support717 * this mode.718 */719 ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,720 VEND1_GLOBAL_CFG_100M, val, val != 0,721 1000, 100000, false);722 if (ret)723 return ret;724 725 return aqr107_fill_interface_modes(phydev);726}727 728static int aqr115c_get_features(struct phy_device *phydev)729{730 unsigned long *supported = phydev->supported;731 732 /* PHY supports speeds up to 2.5G with autoneg. PMA capabilities733 * are not useful.734 */735 linkmode_or(supported, supported, phy_gbit_features);736 linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, supported);737 738 return 0;739}740 741static int aqr111_get_features(struct phy_device *phydev)742{743 /* PHY supports speeds up to 5G with autoneg. PMA capabilities744 * are not useful.745 */746 aqr115c_get_features(phydev);747 linkmode_set_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,748 phydev->supported);749 750 return 0;751}752 753static int aqr113c_config_init(struct phy_device *phydev)754{755 int ret;756 757 ret = aqr107_config_init(phydev);758 if (ret < 0)759 return ret;760 761 ret = phy_clear_bits_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_TXDIS,762 MDIO_PMD_TXDIS_GLOBAL);763 if (ret)764 return ret;765 766 ret = aqr107_wait_processor_intensive_op(phydev);767 if (ret)768 return ret;769 770 return aqr113c_fill_interface_modes(phydev);771}772 773static int aqr107_probe(struct phy_device *phydev)774{775 int ret;776 777 phydev->priv = devm_kzalloc(&phydev->mdio.dev,778 sizeof(struct aqr107_priv), GFP_KERNEL);779 if (!phydev->priv)780 return -ENOMEM;781 782 ret = aqr_firmware_load(phydev);783 if (ret)784 return ret;785 786 return aqr_hwmon_probe(phydev);787}788 789 790static struct phy_driver aqr_driver[] = {791{792 PHY_ID_MATCH_MODEL(PHY_ID_AQ1202),793 .name = "Aquantia AQ1202",794 .config_aneg = aqr_config_aneg,795 .config_intr = aqr_config_intr,796 .handle_interrupt = aqr_handle_interrupt,797 .read_status = aqr_read_status,798},799{800 PHY_ID_MATCH_MODEL(PHY_ID_AQ2104),801 .name = "Aquantia AQ2104",802 .config_aneg = aqr_config_aneg,803 .config_intr = aqr_config_intr,804 .handle_interrupt = aqr_handle_interrupt,805 .read_status = aqr_read_status,806},807{808 PHY_ID_MATCH_MODEL(PHY_ID_AQR105),809 .name = "Aquantia AQR105",810 .config_aneg = aqr_config_aneg,811 .config_intr = aqr_config_intr,812 .handle_interrupt = aqr_handle_interrupt,813 .read_status = aqr_read_status,814 .suspend = aqr107_suspend,815 .resume = aqr107_resume,816},817{818 PHY_ID_MATCH_MODEL(PHY_ID_AQR106),819 .name = "Aquantia AQR106",820 .config_aneg = aqr_config_aneg,821 .config_intr = aqr_config_intr,822 .handle_interrupt = aqr_handle_interrupt,823 .read_status = aqr_read_status,824},825{826 PHY_ID_MATCH_MODEL(PHY_ID_AQR107),827 .name = "Aquantia AQR107",828 .probe = aqr107_probe,829 .get_rate_matching = aqr107_get_rate_matching,830 .config_init = aqr107_config_init,831 .config_aneg = aqr_config_aneg,832 .config_intr = aqr_config_intr,833 .handle_interrupt = aqr_handle_interrupt,834 .read_status = aqr107_read_status,835 .get_tunable = aqr107_get_tunable,836 .set_tunable = aqr107_set_tunable,837 .suspend = aqr107_suspend,838 .resume = aqr107_resume,839 .get_sset_count = aqr107_get_sset_count,840 .get_strings = aqr107_get_strings,841 .get_stats = aqr107_get_stats,842 .link_change_notify = aqr107_link_change_notify,843 .led_brightness_set = aqr_phy_led_brightness_set,844 .led_hw_is_supported = aqr_phy_led_hw_is_supported,845 .led_hw_control_set = aqr_phy_led_hw_control_set,846 .led_hw_control_get = aqr_phy_led_hw_control_get,847 .led_polarity_set = aqr_phy_led_polarity_set,848},849{850 PHY_ID_MATCH_MODEL(PHY_ID_AQCS109),851 .name = "Aquantia AQCS109",852 .probe = aqr107_probe,853 .get_rate_matching = aqr107_get_rate_matching,854 .config_init = aqcs109_config_init,855 .config_aneg = aqr_config_aneg,856 .config_intr = aqr_config_intr,857 .handle_interrupt = aqr_handle_interrupt,858 .read_status = aqr107_read_status,859 .get_tunable = aqr107_get_tunable,860 .set_tunable = aqr107_set_tunable,861 .suspend = aqr107_suspend,862 .resume = aqr107_resume,863 .get_sset_count = aqr107_get_sset_count,864 .get_strings = aqr107_get_strings,865 .get_stats = aqr107_get_stats,866 .get_features = aqr115c_get_features,867 .link_change_notify = aqr107_link_change_notify,868 .led_brightness_set = aqr_phy_led_brightness_set,869 .led_hw_is_supported = aqr_phy_led_hw_is_supported,870 .led_hw_control_set = aqr_phy_led_hw_control_set,871 .led_hw_control_get = aqr_phy_led_hw_control_get,872 .led_polarity_set = aqr_phy_led_polarity_set,873},874{875 PHY_ID_MATCH_MODEL(PHY_ID_AQR111),876 .name = "Aquantia AQR111",877 .probe = aqr107_probe,878 .get_rate_matching = aqr107_get_rate_matching,879 .config_init = aqr107_config_init,880 .config_aneg = aqr_config_aneg,881 .config_intr = aqr_config_intr,882 .handle_interrupt = aqr_handle_interrupt,883 .read_status = aqr107_read_status,884 .get_tunable = aqr107_get_tunable,885 .set_tunable = aqr107_set_tunable,886 .suspend = aqr107_suspend,887 .resume = aqr107_resume,888 .get_sset_count = aqr107_get_sset_count,889 .get_strings = aqr107_get_strings,890 .get_stats = aqr107_get_stats,891 .get_features = aqr111_get_features,892 .link_change_notify = aqr107_link_change_notify,893 .led_brightness_set = aqr_phy_led_brightness_set,894 .led_hw_is_supported = aqr_phy_led_hw_is_supported,895 .led_hw_control_set = aqr_phy_led_hw_control_set,896 .led_hw_control_get = aqr_phy_led_hw_control_get,897 .led_polarity_set = aqr_phy_led_polarity_set,898},899{900 PHY_ID_MATCH_MODEL(PHY_ID_AQR111B0),901 .name = "Aquantia AQR111B0",902 .probe = aqr107_probe,903 .get_rate_matching = aqr107_get_rate_matching,904 .config_init = aqr107_config_init,905 .config_aneg = aqr_config_aneg,906 .config_intr = aqr_config_intr,907 .handle_interrupt = aqr_handle_interrupt,908 .read_status = aqr107_read_status,909 .get_tunable = aqr107_get_tunable,910 .set_tunable = aqr107_set_tunable,911 .suspend = aqr107_suspend,912 .resume = aqr107_resume,913 .get_sset_count = aqr107_get_sset_count,914 .get_strings = aqr107_get_strings,915 .get_stats = aqr107_get_stats,916 .get_features = aqr111_get_features,917 .link_change_notify = aqr107_link_change_notify,918 .led_brightness_set = aqr_phy_led_brightness_set,919 .led_hw_is_supported = aqr_phy_led_hw_is_supported,920 .led_hw_control_set = aqr_phy_led_hw_control_set,921 .led_hw_control_get = aqr_phy_led_hw_control_get,922 .led_polarity_set = aqr_phy_led_polarity_set,923},924{925 PHY_ID_MATCH_MODEL(PHY_ID_AQR405),926 .name = "Aquantia AQR405",927 .config_aneg = aqr_config_aneg,928 .config_intr = aqr_config_intr,929 .handle_interrupt = aqr_handle_interrupt,930 .read_status = aqr_read_status,931},932{933 PHY_ID_MATCH_MODEL(PHY_ID_AQR112),934 .name = "Aquantia AQR112",935 .probe = aqr107_probe,936 .config_aneg = aqr_config_aneg,937 .config_intr = aqr_config_intr,938 .handle_interrupt = aqr_handle_interrupt,939 .get_tunable = aqr107_get_tunable,940 .set_tunable = aqr107_set_tunable,941 .suspend = aqr107_suspend,942 .resume = aqr107_resume,943 .read_status = aqr107_read_status,944 .get_rate_matching = aqr107_get_rate_matching,945 .get_sset_count = aqr107_get_sset_count,946 .get_strings = aqr107_get_strings,947 .get_stats = aqr107_get_stats,948 .link_change_notify = aqr107_link_change_notify,949 .led_brightness_set = aqr_phy_led_brightness_set,950 .led_hw_is_supported = aqr_phy_led_hw_is_supported,951 .led_hw_control_set = aqr_phy_led_hw_control_set,952 .led_hw_control_get = aqr_phy_led_hw_control_get,953 .led_polarity_set = aqr_phy_led_polarity_set,954},955{956 PHY_ID_MATCH_MODEL(PHY_ID_AQR412),957 .name = "Aquantia AQR412",958 .probe = aqr107_probe,959 .config_aneg = aqr_config_aneg,960 .config_intr = aqr_config_intr,961 .handle_interrupt = aqr_handle_interrupt,962 .get_tunable = aqr107_get_tunable,963 .set_tunable = aqr107_set_tunable,964 .suspend = aqr107_suspend,965 .resume = aqr107_resume,966 .read_status = aqr107_read_status,967 .get_rate_matching = aqr107_get_rate_matching,968 .get_sset_count = aqr107_get_sset_count,969 .get_strings = aqr107_get_strings,970 .get_stats = aqr107_get_stats,971 .link_change_notify = aqr107_link_change_notify,972},973{974 PHY_ID_MATCH_MODEL(PHY_ID_AQR113),975 .name = "Aquantia AQR113",976 .probe = aqr107_probe,977 .get_rate_matching = aqr107_get_rate_matching,978 .config_init = aqr113c_config_init,979 .config_aneg = aqr_config_aneg,980 .config_intr = aqr_config_intr,981 .handle_interrupt = aqr_handle_interrupt,982 .read_status = aqr107_read_status,983 .get_tunable = aqr107_get_tunable,984 .set_tunable = aqr107_set_tunable,985 .suspend = aqr107_suspend,986 .resume = aqr107_resume,987 .get_sset_count = aqr107_get_sset_count,988 .get_strings = aqr107_get_strings,989 .get_stats = aqr107_get_stats,990 .link_change_notify = aqr107_link_change_notify,991 .led_brightness_set = aqr_phy_led_brightness_set,992 .led_hw_is_supported = aqr_phy_led_hw_is_supported,993 .led_hw_control_set = aqr_phy_led_hw_control_set,994 .led_hw_control_get = aqr_phy_led_hw_control_get,995 .led_polarity_set = aqr_phy_led_polarity_set,996},997{998 PHY_ID_MATCH_MODEL(PHY_ID_AQR113C),999 .name = "Aquantia AQR113C",1000 .probe = aqr107_probe,1001 .get_rate_matching = aqr107_get_rate_matching,1002 .config_init = aqr113c_config_init,1003 .config_aneg = aqr_config_aneg,1004 .config_intr = aqr_config_intr,1005 .handle_interrupt = aqr_handle_interrupt,1006 .read_status = aqr107_read_status,1007 .get_tunable = aqr107_get_tunable,1008 .set_tunable = aqr107_set_tunable,1009 .suspend = aqr107_suspend,1010 .resume = aqr107_resume,1011 .get_sset_count = aqr107_get_sset_count,1012 .get_strings = aqr107_get_strings,1013 .get_stats = aqr107_get_stats,1014 .link_change_notify = aqr107_link_change_notify,1015 .led_brightness_set = aqr_phy_led_brightness_set,1016 .led_hw_is_supported = aqr_phy_led_hw_is_supported,1017 .led_hw_control_set = aqr_phy_led_hw_control_set,1018 .led_hw_control_get = aqr_phy_led_hw_control_get,1019 .led_polarity_set = aqr_phy_led_polarity_set,1020},1021{1022 PHY_ID_MATCH_MODEL(PHY_ID_AQR114C),1023 .name = "Aquantia AQR114C",1024 .probe = aqr107_probe,1025 .get_rate_matching = aqr107_get_rate_matching,1026 .config_init = aqr107_config_init,1027 .config_aneg = aqr_config_aneg,1028 .config_intr = aqr_config_intr,1029 .handle_interrupt = aqr_handle_interrupt,1030 .read_status = aqr107_read_status,1031 .get_tunable = aqr107_get_tunable,1032 .set_tunable = aqr107_set_tunable,1033 .suspend = aqr107_suspend,1034 .resume = aqr107_resume,1035 .get_sset_count = aqr107_get_sset_count,1036 .get_strings = aqr107_get_strings,1037 .get_stats = aqr107_get_stats,1038 .get_features = aqr111_get_features,1039 .link_change_notify = aqr107_link_change_notify,1040 .led_brightness_set = aqr_phy_led_brightness_set,1041 .led_hw_is_supported = aqr_phy_led_hw_is_supported,1042 .led_hw_control_set = aqr_phy_led_hw_control_set,1043 .led_hw_control_get = aqr_phy_led_hw_control_get,1044 .led_polarity_set = aqr_phy_led_polarity_set,1045},1046{1047 PHY_ID_MATCH_MODEL(PHY_ID_AQR115C),1048 .name = "Aquantia AQR115C",1049 .probe = aqr107_probe,1050 .get_rate_matching = aqr107_get_rate_matching,1051 .config_init = aqr113c_config_init,1052 .config_aneg = aqr_config_aneg,1053 .config_intr = aqr_config_intr,1054 .handle_interrupt = aqr_handle_interrupt,1055 .read_status = aqr107_read_status,1056 .get_tunable = aqr107_get_tunable,1057 .set_tunable = aqr107_set_tunable,1058 .suspend = aqr107_suspend,1059 .resume = aqr107_resume,1060 .get_sset_count = aqr107_get_sset_count,1061 .get_strings = aqr107_get_strings,1062 .get_stats = aqr107_get_stats,1063 .get_features = aqr115c_get_features,1064 .link_change_notify = aqr107_link_change_notify,1065 .led_brightness_set = aqr_phy_led_brightness_set,1066 .led_hw_is_supported = aqr_phy_led_hw_is_supported,1067 .led_hw_control_set = aqr_phy_led_hw_control_set,1068 .led_hw_control_get = aqr_phy_led_hw_control_get,1069 .led_polarity_set = aqr_phy_led_polarity_set,1070},1071{1072 PHY_ID_MATCH_MODEL(PHY_ID_AQR813),1073 .name = "Aquantia AQR813",1074 .probe = aqr107_probe,1075 .get_rate_matching = aqr107_get_rate_matching,1076 .config_init = aqr107_config_init,1077 .config_aneg = aqr_config_aneg,1078 .config_intr = aqr_config_intr,1079 .handle_interrupt = aqr_handle_interrupt,1080 .read_status = aqr107_read_status,1081 .get_tunable = aqr107_get_tunable,1082 .set_tunable = aqr107_set_tunable,1083 .suspend = aqr107_suspend,1084 .resume = aqr107_resume,1085 .get_sset_count = aqr107_get_sset_count,1086 .get_strings = aqr107_get_strings,1087 .get_stats = aqr107_get_stats,1088 .link_change_notify = aqr107_link_change_notify,1089 .led_brightness_set = aqr_phy_led_brightness_set,1090 .led_hw_is_supported = aqr_phy_led_hw_is_supported,1091 .led_hw_control_set = aqr_phy_led_hw_control_set,1092 .led_hw_control_get = aqr_phy_led_hw_control_get,1093 .led_polarity_set = aqr_phy_led_polarity_set,1094},1095};1096 1097module_phy_driver(aqr_driver);1098 1099static struct mdio_device_id __maybe_unused aqr_tbl[] = {1100 { PHY_ID_MATCH_MODEL(PHY_ID_AQ1202) },1101 { PHY_ID_MATCH_MODEL(PHY_ID_AQ2104) },1102 { PHY_ID_MATCH_MODEL(PHY_ID_AQR105) },1103 { PHY_ID_MATCH_MODEL(PHY_ID_AQR106) },1104 { PHY_ID_MATCH_MODEL(PHY_ID_AQR107) },1105 { PHY_ID_MATCH_MODEL(PHY_ID_AQCS109) },1106 { PHY_ID_MATCH_MODEL(PHY_ID_AQR405) },1107 { PHY_ID_MATCH_MODEL(PHY_ID_AQR111) },1108 { PHY_ID_MATCH_MODEL(PHY_ID_AQR111B0) },1109 { PHY_ID_MATCH_MODEL(PHY_ID_AQR112) },1110 { PHY_ID_MATCH_MODEL(PHY_ID_AQR412) },1111 { PHY_ID_MATCH_MODEL(PHY_ID_AQR113) },1112 { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) },1113 { PHY_ID_MATCH_MODEL(PHY_ID_AQR114C) },1114 { PHY_ID_MATCH_MODEL(PHY_ID_AQR115C) },1115 { PHY_ID_MATCH_MODEL(PHY_ID_AQR813) },1116 { }1117};1118 1119MODULE_DEVICE_TABLE(mdio, aqr_tbl);1120 1121MODULE_DESCRIPTION("Aquantia PHY driver");1122MODULE_AUTHOR("Shaohui Xie <Shaohui.Xie@freescale.com>");1123MODULE_LICENSE("GPL v2");1124