1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Marvell 10G 88x3310 PHY driver 4 * 5 * Based upon the ID registers, this PHY appears to be a mixture of IPs 6 * from two different companies. 7 * 8 * There appears to be several different data paths through the PHY which 9 * are automatically managed by the PHY. The following has been determined 10 * via observation and experimentation for a setup using single-lane Serdes: 11 * 12 * SGMII PHYXS -- BASE-T PCS -- 10G PMA -- AN -- Copper (for <= 1G) 13 * 10GBASE-KR PHYXS -- BASE-T PCS -- 10G PMA -- AN -- Copper (for 10G) 14 * 10GBASE-KR PHYXS -- BASE-R PCS -- Fiber 15 * 16 * With XAUI, observation shows: 17 * 18 * XAUI PHYXS -- <appropriate PCS as above> 19 * 20 * and no switching of the host interface mode occurs. 21 * 22 * If both the fiber and copper ports are connected, the first to gain 23 * link takes priority and the other port is completely locked out. 24 */ 25 #include <linux/ctype.h> 26 #include <linux/delay.h> 27 #include <linux/hwmon.h> 28 #include <linux/marvell_phy.h> 29 #include <linux/phy.h> 30 #include <linux/sfp.h> 31 #include <linux/netdevice.h> 32 33 #define MV_PHY_ALASKA_NBT_QUIRK_MASK 0xfffffffe 34 #define MV_PHY_ALASKA_NBT_QUIRK_REV (MARVELL_PHY_ID_88X3310 | 0xa) 35 36 enum { 37 MV_PMA_FW_VER0 = 0xc011, 38 MV_PMA_FW_VER1 = 0xc012, 39 MV_PMA_21X0_PORT_CTRL = 0xc04a, 40 MV_PMA_21X0_PORT_CTRL_SWRST = BIT(15), 41 MV_PMA_21X0_PORT_CTRL_MACTYPE_MASK = 0x7, 42 MV_PMA_21X0_PORT_CTRL_MACTYPE_USXGMII = 0x0, 43 MV_PMA_2180_PORT_CTRL_MACTYPE_DXGMII = 0x1, 44 MV_PMA_2180_PORT_CTRL_MACTYPE_QXGMII = 0x2, 45 MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER = 0x4, 46 MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER_NO_SGMII_AN = 0x5, 47 MV_PMA_21X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH = 0x6, 48 MV_PMA_BOOT = 0xc050, 49 MV_PMA_BOOT_FATAL = BIT(0), 50 51 MV_PCS_BASE_T = 0x0000, 52 MV_PCS_BASE_R = 0x1000, 53 MV_PCS_1000BASEX = 0x2000, 54 55 MV_PCS_CSCR1 = 0x8000, 56 MV_PCS_CSCR1_ED_MASK = 0x0300, 57 MV_PCS_CSCR1_ED_OFF = 0x0000, 58 MV_PCS_CSCR1_ED_RX = 0x0200, 59 MV_PCS_CSCR1_ED_NLP = 0x0300, 60 MV_PCS_CSCR1_MDIX_MASK = 0x0060, 61 MV_PCS_CSCR1_MDIX_MDI = 0x0000, 62 MV_PCS_CSCR1_MDIX_MDIX = 0x0020, 63 MV_PCS_CSCR1_MDIX_AUTO = 0x0060, 64 65 MV_PCS_CSSR1 = 0x8008, 66 MV_PCS_CSSR1_SPD1_MASK = 0xc000, 67 MV_PCS_CSSR1_SPD1_SPD2 = 0xc000, 68 MV_PCS_CSSR1_SPD1_1000 = 0x8000, 69 MV_PCS_CSSR1_SPD1_100 = 0x4000, 70 MV_PCS_CSSR1_SPD1_10 = 0x0000, 71 MV_PCS_CSSR1_DUPLEX_FULL= BIT(13), 72 MV_PCS_CSSR1_RESOLVED = BIT(11), 73 MV_PCS_CSSR1_MDIX = BIT(6), 74 MV_PCS_CSSR1_SPD2_MASK = 0x000c, 75 MV_PCS_CSSR1_SPD2_5000 = 0x0008, 76 MV_PCS_CSSR1_SPD2_2500 = 0x0004, 77 MV_PCS_CSSR1_SPD2_10000 = 0x0000, 78 79 /* Temperature read register (88E2110 only) */ 80 MV_PCS_TEMP = 0x8042, 81 82 /* Number of ports on the device */ 83 MV_PCS_PORT_INFO = 0xd00d, 84 MV_PCS_PORT_INFO_NPORTS_MASK = 0x0380, 85 MV_PCS_PORT_INFO_NPORTS_SHIFT = 7, 86 87 /* These registers appear at 0x800X and 0xa00X - the 0xa00X control 88 * registers appear to set themselves to the 0x800X when AN is 89 * restarted, but status registers appear readable from either. 90 */ 91 MV_AN_CTRL1000 = 0x8000, /* 1000base-T control register */ 92 MV_AN_STAT1000 = 0x8001, /* 1000base-T status register */ 93 94 /* Vendor2 MMD registers */ 95 MV_V2_PORT_CTRL = 0xf001, 96 MV_V2_PORT_CTRL_PWRDOWN = BIT(11), 97 MV_V2_33X0_PORT_CTRL_SWRST = BIT(15), 98 MV_V2_33X0_PORT_CTRL_MACTYPE_MASK = 0x7, 99 MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI = 0x0, 100 MV_V2_3310_PORT_CTRL_MACTYPE_XAUI_RATE_MATCH = 0x1, 101 MV_V2_3340_PORT_CTRL_MACTYPE_RXAUI_NO_SGMII_AN = 0x1, 102 MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI_RATE_MATCH = 0x2, 103 MV_V2_3310_PORT_CTRL_MACTYPE_XAUI = 0x3, 104 MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER = 0x4, 105 MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_NO_SGMII_AN = 0x5, 106 MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH = 0x6, 107 MV_V2_33X0_PORT_CTRL_MACTYPE_USXGMII = 0x7, 108 MV_V2_PORT_INTR_STS = 0xf040, 109 MV_V2_PORT_INTR_MASK = 0xf043, 110 MV_V2_PORT_INTR_STS_WOL_EN = BIT(8), 111 MV_V2_MAGIC_PKT_WORD0 = 0xf06b, 112 MV_V2_MAGIC_PKT_WORD1 = 0xf06c, 113 MV_V2_MAGIC_PKT_WORD2 = 0xf06d, 114 /* Wake on LAN registers */ 115 MV_V2_WOL_CTRL = 0xf06e, 116 MV_V2_WOL_CTRL_CLEAR_STS = BIT(15), 117 MV_V2_WOL_CTRL_MAGIC_PKT_EN = BIT(0), 118 /* Temperature control/read registers (88X3310 only) */ 119 MV_V2_TEMP_CTRL = 0xf08a, 120 MV_V2_TEMP_CTRL_MASK = 0xc000, 121 MV_V2_TEMP_CTRL_SAMPLE = 0x0000, 122 MV_V2_TEMP_CTRL_DISABLE = 0xc000, 123 MV_V2_TEMP = 0xf08c, 124 MV_V2_TEMP_UNKNOWN = 0x9600, /* unknown function */ 125 }; 126 127 struct mv3310_chip { 128 void (*init_supported_interfaces)(unsigned long *mask); 129 int (*get_mactype)(struct phy_device *phydev); 130 int (*init_interface)(struct phy_device *phydev, int mactype); 131 132 #ifdef CONFIG_HWMON 133 int (*hwmon_read_temp_reg)(struct phy_device *phydev); 134 #endif 135 }; 136 137 struct mv3310_priv { 138 DECLARE_BITMAP(supported_interfaces, PHY_INTERFACE_MODE_MAX); 139 140 u32 firmware_ver; 141 bool rate_match; 142 phy_interface_t const_interface; 143 144 struct device *hwmon_dev; 145 char *hwmon_name; 146 }; 147 148 static const struct mv3310_chip *to_mv3310_chip(struct phy_device *phydev) 149 { 150 return phydev->drv->driver_data; 151 } 152 153 #ifdef CONFIG_HWMON 154 static umode_t mv3310_hwmon_is_visible(const void *data, 155 enum hwmon_sensor_types type, 156 u32 attr, int channel) 157 { 158 if (type == hwmon_chip && attr == hwmon_chip_update_interval) 159 return 0444; 160 if (type == hwmon_temp && attr == hwmon_temp_input) 161 return 0444; 162 return 0; 163 } 164 165 static int mv3310_hwmon_read_temp_reg(struct phy_device *phydev) 166 { 167 return phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_TEMP); 168 } 169 170 static int mv2110_hwmon_read_temp_reg(struct phy_device *phydev) 171 { 172 return phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_TEMP); 173 } 174 175 static int mv3310_hwmon_read(struct device *dev, enum hwmon_sensor_types type, 176 u32 attr, int channel, long *value) 177 { 178 struct phy_device *phydev = dev_get_drvdata(dev); 179 const struct mv3310_chip *chip = to_mv3310_chip(phydev); 180 int temp; 181 182 if (type == hwmon_chip && attr == hwmon_chip_update_interval) { 183 *value = MSEC_PER_SEC; 184 return 0; 185 } 186 187 if (type == hwmon_temp && attr == hwmon_temp_input) { 188 temp = chip->hwmon_read_temp_reg(phydev); 189 if (temp < 0) 190 return temp; 191 192 *value = ((temp & 0xff) - 75) * 1000; 193 194 return 0; 195 } 196 197 return -EOPNOTSUPP; 198 } 199 200 static const struct hwmon_ops mv3310_hwmon_ops = { 201 .is_visible = mv3310_hwmon_is_visible, 202 .read = mv3310_hwmon_read, 203 }; 204 205 static u32 mv3310_hwmon_chip_config[] = { 206 HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL, 207 0, 208 }; 209 210 static const struct hwmon_channel_info mv3310_hwmon_chip = { 211 .type = hwmon_chip, 212 .config = mv3310_hwmon_chip_config, 213 }; 214 215 static u32 mv3310_hwmon_temp_config[] = { 216 HWMON_T_INPUT, 217 0, 218 }; 219 220 static const struct hwmon_channel_info mv3310_hwmon_temp = { 221 .type = hwmon_temp, 222 .config = mv3310_hwmon_temp_config, 223 }; 224 225 static const struct hwmon_channel_info *mv3310_hwmon_info[] = { 226 &mv3310_hwmon_chip, 227 &mv3310_hwmon_temp, 228 NULL, 229 }; 230 231 static const struct hwmon_chip_info mv3310_hwmon_chip_info = { 232 .ops = &mv3310_hwmon_ops, 233 .info = mv3310_hwmon_info, 234 }; 235 236 static int mv3310_hwmon_config(struct phy_device *phydev, bool enable) 237 { 238 u16 val; 239 int ret; 240 241 if (phydev->drv->phy_id != MARVELL_PHY_ID_88X3310) 242 return 0; 243 244 ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, MV_V2_TEMP, 245 MV_V2_TEMP_UNKNOWN); 246 if (ret < 0) 247 return ret; 248 249 val = enable ? MV_V2_TEMP_CTRL_SAMPLE : MV_V2_TEMP_CTRL_DISABLE; 250 251 return phy_modify_mmd(phydev, MDIO_MMD_VEND2, MV_V2_TEMP_CTRL, 252 MV_V2_TEMP_CTRL_MASK, val); 253 } 254 255 static int mv3310_hwmon_probe(struct phy_device *phydev) 256 { 257 struct device *dev = &phydev->mdio.dev; 258 struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev); 259 int i, j, ret; 260 261 priv->hwmon_name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL); 262 if (!priv->hwmon_name) 263 return -ENODEV; 264 265 for (i = j = 0; priv->hwmon_name[i]; i++) { 266 if (isalnum(priv->hwmon_name[i])) { 267 if (i != j) 268 priv->hwmon_name[j] = priv->hwmon_name[i]; 269 j++; 270 } 271 } 272 priv->hwmon_name[j] = '\0'; 273 274 ret = mv3310_hwmon_config(phydev, true); 275 if (ret) 276 return ret; 277 278 priv->hwmon_dev = devm_hwmon_device_register_with_info(dev, 279 priv->hwmon_name, phydev, 280 &mv3310_hwmon_chip_info, NULL); 281 282 return PTR_ERR_OR_ZERO(priv->hwmon_dev); 283 } 284 #else 285 static inline int mv3310_hwmon_config(struct phy_device *phydev, bool enable) 286 { 287 return 0; 288 } 289 290 static int mv3310_hwmon_probe(struct phy_device *phydev) 291 { 292 return 0; 293 } 294 #endif 295 296 static int mv3310_power_down(struct phy_device *phydev) 297 { 298 return phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL, 299 MV_V2_PORT_CTRL_PWRDOWN); 300 } 301 302 static int mv3310_power_up(struct phy_device *phydev) 303 { 304 struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev); 305 int ret; 306 307 ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL, 308 MV_V2_PORT_CTRL_PWRDOWN); 309 310 if (phydev->drv->phy_id != MARVELL_PHY_ID_88X3310 || 311 priv->firmware_ver < 0x00030000) 312 return ret; 313 314 return phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL, 315 MV_V2_33X0_PORT_CTRL_SWRST); 316 } 317 318 static int mv3310_reset(struct phy_device *phydev, u32 unit) 319 { 320 int val, err; 321 322 err = phy_modify_mmd(phydev, MDIO_MMD_PCS, unit + MDIO_CTRL1, 323 MDIO_CTRL1_RESET, MDIO_CTRL1_RESET); 324 if (err < 0) 325 return err; 326 327 return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_PCS, 328 unit + MDIO_CTRL1, val, 329 !(val & MDIO_CTRL1_RESET), 330 5000, 100000, true); 331 } 332 333 static int mv3310_get_edpd(struct phy_device *phydev, u16 *edpd) 334 { 335 int val; 336 337 val = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_CSCR1); 338 if (val < 0) 339 return val; 340 341 switch (val & MV_PCS_CSCR1_ED_MASK) { 342 case MV_PCS_CSCR1_ED_NLP: 343 *edpd = 1000; 344 break; 345 case MV_PCS_CSCR1_ED_RX: 346 *edpd = ETHTOOL_PHY_EDPD_NO_TX; 347 break; 348 default: 349 *edpd = ETHTOOL_PHY_EDPD_DISABLE; 350 break; 351 } 352 return 0; 353 } 354 355 static int mv3310_set_edpd(struct phy_device *phydev, u16 edpd) 356 { 357 u16 val; 358 int err; 359 360 switch (edpd) { 361 case 1000: 362 case ETHTOOL_PHY_EDPD_DFLT_TX_MSECS: 363 val = MV_PCS_CSCR1_ED_NLP; 364 break; 365 366 case ETHTOOL_PHY_EDPD_NO_TX: 367 val = MV_PCS_CSCR1_ED_RX; 368 break; 369 370 case ETHTOOL_PHY_EDPD_DISABLE: 371 val = MV_PCS_CSCR1_ED_OFF; 372 break; 373 374 default: 375 return -EINVAL; 376 } 377 378 err = phy_modify_mmd_changed(phydev, MDIO_MMD_PCS, MV_PCS_CSCR1, 379 MV_PCS_CSCR1_ED_MASK, val); 380 if (err > 0) 381 err = mv3310_reset(phydev, MV_PCS_BASE_T); 382 383 return err; 384 } 385 386 static int mv3310_sfp_insert(void *upstream, const struct sfp_eeprom_id *id) 387 { 388 struct phy_device *phydev = upstream; 389 __ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, }; 390 phy_interface_t iface; 391 392 sfp_parse_support(phydev->sfp_bus, id, support); 393 iface = sfp_select_interface(phydev->sfp_bus, support); 394 395 if (iface != PHY_INTERFACE_MODE_10GBASER) { 396 dev_err(&phydev->mdio.dev, "incompatible SFP module inserted\n"); 397 return -EINVAL; 398 } 399 return 0; 400 } 401 402 static const struct sfp_upstream_ops mv3310_sfp_ops = { 403 .attach = phy_sfp_attach, 404 .detach = phy_sfp_detach, 405 .module_insert = mv3310_sfp_insert, 406 }; 407 408 static int mv3310_probe(struct phy_device *phydev) 409 { 410 const struct mv3310_chip *chip = to_mv3310_chip(phydev); 411 struct mv3310_priv *priv; 412 u32 mmd_mask = MDIO_DEVS_PMAPMD | MDIO_DEVS_AN; 413 int ret; 414 415 if (!phydev->is_c45 || 416 (phydev->c45_ids.devices_in_package & mmd_mask) != mmd_mask) 417 return -ENODEV; 418 419 ret = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_BOOT); 420 if (ret < 0) 421 return ret; 422 423 if (ret & MV_PMA_BOOT_FATAL) { 424 dev_warn(&phydev->mdio.dev, 425 "PHY failed to boot firmware, status=%04x\n", ret); 426 return -ENODEV; 427 } 428 429 priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL); 430 if (!priv) 431 return -ENOMEM; 432 433 dev_set_drvdata(&phydev->mdio.dev, priv); 434 435 ret = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_FW_VER0); 436 if (ret < 0) 437 return ret; 438 439 priv->firmware_ver = ret << 16; 440 441 ret = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_FW_VER1); 442 if (ret < 0) 443 return ret; 444 445 priv->firmware_ver |= ret; 446 447 phydev_info(phydev, "Firmware version %u.%u.%u.%u\n", 448 priv->firmware_ver >> 24, (priv->firmware_ver >> 16) & 255, 449 (priv->firmware_ver >> 8) & 255, priv->firmware_ver & 255); 450 451 /* Powering down the port when not in use saves about 600mW */ 452 ret = mv3310_power_down(phydev); 453 if (ret) 454 return ret; 455 456 ret = mv3310_hwmon_probe(phydev); 457 if (ret) 458 return ret; 459 460 chip->init_supported_interfaces(priv->supported_interfaces); 461 462 return phy_sfp_probe(phydev, &mv3310_sfp_ops); 463 } 464 465 static void mv3310_remove(struct phy_device *phydev) 466 { 467 mv3310_hwmon_config(phydev, false); 468 } 469 470 static int mv3310_suspend(struct phy_device *phydev) 471 { 472 return mv3310_power_down(phydev); 473 } 474 475 static int mv3310_resume(struct phy_device *phydev) 476 { 477 int ret; 478 479 ret = mv3310_power_up(phydev); 480 if (ret) 481 return ret; 482 483 return mv3310_hwmon_config(phydev, true); 484 } 485 486 /* Some PHYs in the Alaska family such as the 88X3310 and the 88E2010 487 * don't set bit 14 in PMA Extended Abilities (1.11), although they do 488 * support 2.5GBASET and 5GBASET. For these models, we can still read their 489 * 2.5G/5G extended abilities register (1.21). We detect these models based on 490 * the PMA device identifier, with a mask matching models known to have this 491 * issue 492 */ 493 static bool mv3310_has_pma_ngbaset_quirk(struct phy_device *phydev) 494 { 495 if (!(phydev->c45_ids.devices_in_package & MDIO_DEVS_PMAPMD)) 496 return false; 497 498 /* Only some revisions of the 88X3310 family PMA seem to be impacted */ 499 return (phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] & 500 MV_PHY_ALASKA_NBT_QUIRK_MASK) == MV_PHY_ALASKA_NBT_QUIRK_REV; 501 } 502 503 static int mv2110_get_mactype(struct phy_device *phydev) 504 { 505 int mactype; 506 507 mactype = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_21X0_PORT_CTRL); 508 if (mactype < 0) 509 return mactype; 510 511 return mactype & MV_PMA_21X0_PORT_CTRL_MACTYPE_MASK; 512 } 513 514 static int mv3310_get_mactype(struct phy_device *phydev) 515 { 516 int mactype; 517 518 mactype = phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL); 519 if (mactype < 0) 520 return mactype; 521 522 return mactype & MV_V2_33X0_PORT_CTRL_MACTYPE_MASK; 523 } 524 525 static int mv2110_init_interface(struct phy_device *phydev, int mactype) 526 { 527 struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev); 528 529 priv->rate_match = false; 530 531 if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH) 532 priv->rate_match = true; 533 534 if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_USXGMII) 535 priv->const_interface = PHY_INTERFACE_MODE_USXGMII; 536 else if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH) 537 priv->const_interface = PHY_INTERFACE_MODE_10GBASER; 538 else if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER || 539 mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER_NO_SGMII_AN) 540 priv->const_interface = PHY_INTERFACE_MODE_NA; 541 else 542 return -EINVAL; 543 544 return 0; 545 } 546 547 static int mv3310_init_interface(struct phy_device *phydev, int mactype) 548 { 549 struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev); 550 551 priv->rate_match = false; 552 553 if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH || 554 mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI_RATE_MATCH || 555 mactype == MV_V2_3310_PORT_CTRL_MACTYPE_XAUI_RATE_MATCH) 556 priv->rate_match = true; 557 558 if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_USXGMII) 559 priv->const_interface = PHY_INTERFACE_MODE_USXGMII; 560 else if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH || 561 mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_NO_SGMII_AN || 562 mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER) 563 priv->const_interface = PHY_INTERFACE_MODE_10GBASER; 564 else if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI_RATE_MATCH || 565 mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI) 566 priv->const_interface = PHY_INTERFACE_MODE_RXAUI; 567 else if (mactype == MV_V2_3310_PORT_CTRL_MACTYPE_XAUI_RATE_MATCH || 568 mactype == MV_V2_3310_PORT_CTRL_MACTYPE_XAUI) 569 priv->const_interface = PHY_INTERFACE_MODE_XAUI; 570 else 571 return -EINVAL; 572 573 return 0; 574 } 575 576 static int mv3340_init_interface(struct phy_device *phydev, int mactype) 577 { 578 struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev); 579 int err = 0; 580 581 priv->rate_match = false; 582 583 if (mactype == MV_V2_3340_PORT_CTRL_MACTYPE_RXAUI_NO_SGMII_AN) 584 priv->const_interface = PHY_INTERFACE_MODE_RXAUI; 585 else 586 err = mv3310_init_interface(phydev, mactype); 587 588 return err; 589 } 590 591 static int mv3310_config_init(struct phy_device *phydev) 592 { 593 struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev); 594 const struct mv3310_chip *chip = to_mv3310_chip(phydev); 595 int err, mactype; 596 597 /* Check that the PHY interface type is compatible */ 598 if (!test_bit(phydev->interface, priv->supported_interfaces)) 599 return -ENODEV; 600 601 phydev->mdix_ctrl = ETH_TP_MDI_AUTO; 602 603 /* Power up so reset works */ 604 err = mv3310_power_up(phydev); 605 if (err) 606 return err; 607 608 mactype = chip->get_mactype(phydev); 609 if (mactype < 0) 610 return mactype; 611 612 err = chip->init_interface(phydev, mactype); 613 if (err) { 614 phydev_err(phydev, "MACTYPE configuration invalid\n"); 615 return err; 616 } 617 618 /* Enable EDPD mode - saving 600mW */ 619 return mv3310_set_edpd(phydev, ETHTOOL_PHY_EDPD_DFLT_TX_MSECS); 620 } 621 622 static int mv3310_get_features(struct phy_device *phydev) 623 { 624 int ret, val; 625 626 ret = genphy_c45_pma_read_abilities(phydev); 627 if (ret) 628 return ret; 629 630 if (mv3310_has_pma_ngbaset_quirk(phydev)) { 631 val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, 632 MDIO_PMA_NG_EXTABLE); 633 if (val < 0) 634 return val; 635 636 linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, 637 phydev->supported, 638 val & MDIO_PMA_NG_EXTABLE_2_5GBT); 639 640 linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, 641 phydev->supported, 642 val & MDIO_PMA_NG_EXTABLE_5GBT); 643 } 644 645 return 0; 646 } 647 648 static int mv3310_config_mdix(struct phy_device *phydev) 649 { 650 u16 val; 651 int err; 652 653 switch (phydev->mdix_ctrl) { 654 case ETH_TP_MDI_AUTO: 655 val = MV_PCS_CSCR1_MDIX_AUTO; 656 break; 657 case ETH_TP_MDI_X: 658 val = MV_PCS_CSCR1_MDIX_MDIX; 659 break; 660 case ETH_TP_MDI: 661 val = MV_PCS_CSCR1_MDIX_MDI; 662 break; 663 default: 664 return -EINVAL; 665 } 666 667 err = phy_modify_mmd_changed(phydev, MDIO_MMD_PCS, MV_PCS_CSCR1, 668 MV_PCS_CSCR1_MDIX_MASK, val); 669 if (err > 0) 670 err = mv3310_reset(phydev, MV_PCS_BASE_T); 671 672 return err; 673 } 674 675 static int mv3310_config_aneg(struct phy_device *phydev) 676 { 677 bool changed = false; 678 u16 reg; 679 int ret; 680 681 ret = mv3310_config_mdix(phydev); 682 if (ret < 0) 683 return ret; 684 685 if (phydev->autoneg == AUTONEG_DISABLE) 686 return genphy_c45_pma_setup_forced(phydev); 687 688 ret = genphy_c45_an_config_aneg(phydev); 689 if (ret < 0) 690 return ret; 691 if (ret > 0) 692 changed = true; 693 694 /* Clause 45 has no standardized support for 1000BaseT, therefore 695 * use vendor registers for this mode. 696 */ 697 reg = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising); 698 ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MV_AN_CTRL1000, 699 ADVERTISE_1000FULL | ADVERTISE_1000HALF, reg); 700 if (ret < 0) 701 return ret; 702 if (ret > 0) 703 changed = true; 704 705 return genphy_c45_check_and_restart_aneg(phydev, changed); 706 } 707 708 static int mv3310_aneg_done(struct phy_device *phydev) 709 { 710 int val; 711 712 val = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_BASE_R + MDIO_STAT1); 713 if (val < 0) 714 return val; 715 716 if (val & MDIO_STAT1_LSTATUS) 717 return 1; 718 719 return genphy_c45_aneg_done(phydev); 720 } 721 722 static void mv3310_update_interface(struct phy_device *phydev) 723 { 724 struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev); 725 726 if (!phydev->link) 727 return; 728 729 /* In all of the "* with Rate Matching" modes the PHY interface is fixed 730 * at 10Gb. The PHY adapts the rate to actual wire speed with help of 731 * internal 16KB buffer. 732 * 733 * In USXGMII mode the PHY interface mode is also fixed. 734 */ 735 if (priv->rate_match || 736 priv->const_interface == PHY_INTERFACE_MODE_USXGMII) { 737 phydev->interface = priv->const_interface; 738 return; 739 } 740 741 /* The PHY automatically switches its serdes interface (and active PHYXS 742 * instance) between Cisco SGMII, 2500BaseX, 5GBase-R and 10GBase-R / 743 * xaui / rxaui modes according to the speed. 744 * Florian suggests setting phydev->interface to communicate this to the 745 * MAC. Only do this if we are already in one of the above modes. 746 */ 747 switch (phydev->speed) { 748 case SPEED_10000: 749 phydev->interface = priv->const_interface; 750 break; 751 case SPEED_5000: 752 phydev->interface = PHY_INTERFACE_MODE_5GBASER; 753 break; 754 case SPEED_2500: 755 phydev->interface = PHY_INTERFACE_MODE_2500BASEX; 756 break; 757 case SPEED_1000: 758 case SPEED_100: 759 case SPEED_10: 760 phydev->interface = PHY_INTERFACE_MODE_SGMII; 761 break; 762 default: 763 break; 764 } 765 } 766 767 /* 10GBASE-ER,LR,LRM,SR do not support autonegotiation. */ 768 static int mv3310_read_status_10gbaser(struct phy_device *phydev) 769 { 770 phydev->link = 1; 771 phydev->speed = SPEED_10000; 772 phydev->duplex = DUPLEX_FULL; 773 phydev->port = PORT_FIBRE; 774 775 return 0; 776 } 777 778 static int mv3310_read_status_copper(struct phy_device *phydev) 779 { 780 int cssr1, speed, val; 781 782 val = genphy_c45_read_link(phydev); 783 if (val < 0) 784 return val; 785 786 val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1); 787 if (val < 0) 788 return val; 789 790 cssr1 = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_CSSR1); 791 if (cssr1 < 0) 792 return val; 793 794 /* If the link settings are not resolved, mark the link down */ 795 if (!(cssr1 & MV_PCS_CSSR1_RESOLVED)) { 796 phydev->link = 0; 797 return 0; 798 } 799 800 /* Read the copper link settings */ 801 speed = cssr1 & MV_PCS_CSSR1_SPD1_MASK; 802 if (speed == MV_PCS_CSSR1_SPD1_SPD2) 803 speed |= cssr1 & MV_PCS_CSSR1_SPD2_MASK; 804 805 switch (speed) { 806 case MV_PCS_CSSR1_SPD1_SPD2 | MV_PCS_CSSR1_SPD2_10000: 807 phydev->speed = SPEED_10000; 808 break; 809 810 case MV_PCS_CSSR1_SPD1_SPD2 | MV_PCS_CSSR1_SPD2_5000: 811 phydev->speed = SPEED_5000; 812 break; 813 814 case MV_PCS_CSSR1_SPD1_SPD2 | MV_PCS_CSSR1_SPD2_2500: 815 phydev->speed = SPEED_2500; 816 break; 817 818 case MV_PCS_CSSR1_SPD1_1000: 819 phydev->speed = SPEED_1000; 820 break; 821 822 case MV_PCS_CSSR1_SPD1_100: 823 phydev->speed = SPEED_100; 824 break; 825 826 case MV_PCS_CSSR1_SPD1_10: 827 phydev->speed = SPEED_10; 828 break; 829 } 830 831 phydev->duplex = cssr1 & MV_PCS_CSSR1_DUPLEX_FULL ? 832 DUPLEX_FULL : DUPLEX_HALF; 833 phydev->port = PORT_TP; 834 phydev->mdix = cssr1 & MV_PCS_CSSR1_MDIX ? 835 ETH_TP_MDI_X : ETH_TP_MDI; 836 837 if (val & MDIO_AN_STAT1_COMPLETE) { 838 val = genphy_c45_read_lpa(phydev); 839 if (val < 0) 840 return val; 841 842 /* Read the link partner's 1G advertisement */ 843 val = phy_read_mmd(phydev, MDIO_MMD_AN, MV_AN_STAT1000); 844 if (val < 0) 845 return val; 846 847 mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, val); 848 849 /* Update the pause status */ 850 phy_resolve_aneg_pause(phydev); 851 } 852 853 return 0; 854 } 855 856 static int mv3310_read_status(struct phy_device *phydev) 857 { 858 int err, val; 859 860 phydev->speed = SPEED_UNKNOWN; 861 phydev->duplex = DUPLEX_UNKNOWN; 862 linkmode_zero(phydev->lp_advertising); 863 phydev->link = 0; 864 phydev->pause = 0; 865 phydev->asym_pause = 0; 866 phydev->mdix = ETH_TP_MDI_INVALID; 867 868 val = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_BASE_R + MDIO_STAT1); 869 if (val < 0) 870 return val; 871 872 if (val & MDIO_STAT1_LSTATUS) 873 err = mv3310_read_status_10gbaser(phydev); 874 else 875 err = mv3310_read_status_copper(phydev); 876 if (err < 0) 877 return err; 878 879 if (phydev->link) 880 mv3310_update_interface(phydev); 881 882 return 0; 883 } 884 885 static int mv3310_get_tunable(struct phy_device *phydev, 886 struct ethtool_tunable *tuna, void *data) 887 { 888 switch (tuna->id) { 889 case ETHTOOL_PHY_EDPD: 890 return mv3310_get_edpd(phydev, data); 891 default: 892 return -EOPNOTSUPP; 893 } 894 } 895 896 static int mv3310_set_tunable(struct phy_device *phydev, 897 struct ethtool_tunable *tuna, const void *data) 898 { 899 switch (tuna->id) { 900 case ETHTOOL_PHY_EDPD: 901 return mv3310_set_edpd(phydev, *(u16 *)data); 902 default: 903 return -EOPNOTSUPP; 904 } 905 } 906 907 static void mv3310_init_supported_interfaces(unsigned long *mask) 908 { 909 __set_bit(PHY_INTERFACE_MODE_SGMII, mask); 910 __set_bit(PHY_INTERFACE_MODE_2500BASEX, mask); 911 __set_bit(PHY_INTERFACE_MODE_5GBASER, mask); 912 __set_bit(PHY_INTERFACE_MODE_XAUI, mask); 913 __set_bit(PHY_INTERFACE_MODE_RXAUI, mask); 914 __set_bit(PHY_INTERFACE_MODE_10GBASER, mask); 915 __set_bit(PHY_INTERFACE_MODE_USXGMII, mask); 916 } 917 918 static void mv3340_init_supported_interfaces(unsigned long *mask) 919 { 920 __set_bit(PHY_INTERFACE_MODE_SGMII, mask); 921 __set_bit(PHY_INTERFACE_MODE_2500BASEX, mask); 922 __set_bit(PHY_INTERFACE_MODE_5GBASER, mask); 923 __set_bit(PHY_INTERFACE_MODE_RXAUI, mask); 924 __set_bit(PHY_INTERFACE_MODE_10GBASER, mask); 925 __set_bit(PHY_INTERFACE_MODE_USXGMII, mask); 926 } 927 928 static void mv2110_init_supported_interfaces(unsigned long *mask) 929 { 930 __set_bit(PHY_INTERFACE_MODE_SGMII, mask); 931 __set_bit(PHY_INTERFACE_MODE_2500BASEX, mask); 932 __set_bit(PHY_INTERFACE_MODE_5GBASER, mask); 933 __set_bit(PHY_INTERFACE_MODE_10GBASER, mask); 934 __set_bit(PHY_INTERFACE_MODE_USXGMII, mask); 935 } 936 937 static void mv2111_init_supported_interfaces(unsigned long *mask) 938 { 939 __set_bit(PHY_INTERFACE_MODE_SGMII, mask); 940 __set_bit(PHY_INTERFACE_MODE_2500BASEX, mask); 941 __set_bit(PHY_INTERFACE_MODE_10GBASER, mask); 942 __set_bit(PHY_INTERFACE_MODE_USXGMII, mask); 943 } 944 945 static const struct mv3310_chip mv3310_type = { 946 .init_supported_interfaces = mv3310_init_supported_interfaces, 947 .get_mactype = mv3310_get_mactype, 948 .init_interface = mv3310_init_interface, 949 950 #ifdef CONFIG_HWMON 951 .hwmon_read_temp_reg = mv3310_hwmon_read_temp_reg, 952 #endif 953 }; 954 955 static const struct mv3310_chip mv3340_type = { 956 .init_supported_interfaces = mv3340_init_supported_interfaces, 957 .get_mactype = mv3310_get_mactype, 958 .init_interface = mv3340_init_interface, 959 960 #ifdef CONFIG_HWMON 961 .hwmon_read_temp_reg = mv3310_hwmon_read_temp_reg, 962 #endif 963 }; 964 965 static const struct mv3310_chip mv2110_type = { 966 .init_supported_interfaces = mv2110_init_supported_interfaces, 967 .get_mactype = mv2110_get_mactype, 968 .init_interface = mv2110_init_interface, 969 970 #ifdef CONFIG_HWMON 971 .hwmon_read_temp_reg = mv2110_hwmon_read_temp_reg, 972 #endif 973 }; 974 975 static const struct mv3310_chip mv2111_type = { 976 .init_supported_interfaces = mv2111_init_supported_interfaces, 977 .get_mactype = mv2110_get_mactype, 978 .init_interface = mv2110_init_interface, 979 980 #ifdef CONFIG_HWMON 981 .hwmon_read_temp_reg = mv2110_hwmon_read_temp_reg, 982 #endif 983 }; 984 985 static int mv3310_get_number_of_ports(struct phy_device *phydev) 986 { 987 int ret; 988 989 ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_PORT_INFO); 990 if (ret < 0) 991 return ret; 992 993 ret &= MV_PCS_PORT_INFO_NPORTS_MASK; 994 ret >>= MV_PCS_PORT_INFO_NPORTS_SHIFT; 995 996 return ret + 1; 997 } 998 999 static int mv3310_match_phy_device(struct phy_device *phydev) 1000 { 1001 if ((phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] & 1002 MARVELL_PHY_ID_MASK) != MARVELL_PHY_ID_88X3310) 1003 return 0; 1004 1005 return mv3310_get_number_of_ports(phydev) == 1; 1006 } 1007 1008 static int mv3340_match_phy_device(struct phy_device *phydev) 1009 { 1010 if ((phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] & 1011 MARVELL_PHY_ID_MASK) != MARVELL_PHY_ID_88X3310) 1012 return 0; 1013 1014 return mv3310_get_number_of_ports(phydev) == 4; 1015 } 1016 1017 static int mv211x_match_phy_device(struct phy_device *phydev, bool has_5g) 1018 { 1019 int val; 1020 1021 if ((phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] & 1022 MARVELL_PHY_ID_MASK) != MARVELL_PHY_ID_88E2110) 1023 return 0; 1024 1025 val = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_SPEED); 1026 if (val < 0) 1027 return val; 1028 1029 return !!(val & MDIO_PCS_SPEED_5G) == has_5g; 1030 } 1031 1032 static int mv2110_match_phy_device(struct phy_device *phydev) 1033 { 1034 return mv211x_match_phy_device(phydev, true); 1035 } 1036 1037 static int mv2111_match_phy_device(struct phy_device *phydev) 1038 { 1039 return mv211x_match_phy_device(phydev, false); 1040 } 1041 1042 static void mv3110_get_wol(struct phy_device *phydev, 1043 struct ethtool_wolinfo *wol) 1044 { 1045 int ret; 1046 1047 wol->supported = WAKE_MAGIC; 1048 wol->wolopts = 0; 1049 1050 ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_WOL_CTRL); 1051 if (ret < 0) 1052 return; 1053 1054 if (ret & MV_V2_WOL_CTRL_MAGIC_PKT_EN) 1055 wol->wolopts |= WAKE_MAGIC; 1056 } 1057 1058 static int mv3110_set_wol(struct phy_device *phydev, 1059 struct ethtool_wolinfo *wol) 1060 { 1061 int ret; 1062 1063 if (wol->wolopts & WAKE_MAGIC) { 1064 /* Enable the WOL interrupt */ 1065 ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, 1066 MV_V2_PORT_INTR_MASK, 1067 MV_V2_PORT_INTR_STS_WOL_EN); 1068 if (ret < 0) 1069 return ret; 1070 1071 /* Store the device address for the magic packet */ 1072 ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, 1073 MV_V2_MAGIC_PKT_WORD2, 1074 ((phydev->attached_dev->dev_addr[5] << 8) | 1075 phydev->attached_dev->dev_addr[4])); 1076 if (ret < 0) 1077 return ret; 1078 1079 ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, 1080 MV_V2_MAGIC_PKT_WORD1, 1081 ((phydev->attached_dev->dev_addr[3] << 8) | 1082 phydev->attached_dev->dev_addr[2])); 1083 if (ret < 0) 1084 return ret; 1085 1086 ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, 1087 MV_V2_MAGIC_PKT_WORD0, 1088 ((phydev->attached_dev->dev_addr[1] << 8) | 1089 phydev->attached_dev->dev_addr[0])); 1090 if (ret < 0) 1091 return ret; 1092 1093 /* Clear WOL status and enable magic packet matching */ 1094 ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, 1095 MV_V2_WOL_CTRL, 1096 MV_V2_WOL_CTRL_MAGIC_PKT_EN | 1097 MV_V2_WOL_CTRL_CLEAR_STS); 1098 if (ret < 0) 1099 return ret; 1100 } else { 1101 /* Disable magic packet matching & reset WOL status bit */ 1102 ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, 1103 MV_V2_WOL_CTRL, 1104 MV_V2_WOL_CTRL_MAGIC_PKT_EN, 1105 MV_V2_WOL_CTRL_CLEAR_STS); 1106 if (ret < 0) 1107 return ret; 1108 } 1109 1110 /* Reset the clear WOL status bit as it does not self-clear */ 1111 return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, 1112 MV_V2_WOL_CTRL, 1113 MV_V2_WOL_CTRL_CLEAR_STS); 1114 } 1115 1116 static struct phy_driver mv3310_drivers[] = { 1117 { 1118 .phy_id = MARVELL_PHY_ID_88X3310, 1119 .phy_id_mask = MARVELL_PHY_ID_MASK, 1120 .match_phy_device = mv3310_match_phy_device, 1121 .name = "mv88x3310", 1122 .driver_data = &mv3310_type, 1123 .get_features = mv3310_get_features, 1124 .config_init = mv3310_config_init, 1125 .probe = mv3310_probe, 1126 .suspend = mv3310_suspend, 1127 .resume = mv3310_resume, 1128 .config_aneg = mv3310_config_aneg, 1129 .aneg_done = mv3310_aneg_done, 1130 .read_status = mv3310_read_status, 1131 .get_tunable = mv3310_get_tunable, 1132 .set_tunable = mv3310_set_tunable, 1133 .remove = mv3310_remove, 1134 .set_loopback = genphy_c45_loopback, 1135 .get_wol = mv3110_get_wol, 1136 .set_wol = mv3110_set_wol, 1137 }, 1138 { 1139 .phy_id = MARVELL_PHY_ID_88X3310, 1140 .phy_id_mask = MARVELL_PHY_ID_MASK, 1141 .match_phy_device = mv3340_match_phy_device, 1142 .name = "mv88x3340", 1143 .driver_data = &mv3340_type, 1144 .get_features = mv3310_get_features, 1145 .config_init = mv3310_config_init, 1146 .probe = mv3310_probe, 1147 .suspend = mv3310_suspend, 1148 .resume = mv3310_resume, 1149 .config_aneg = mv3310_config_aneg, 1150 .aneg_done = mv3310_aneg_done, 1151 .read_status = mv3310_read_status, 1152 .get_tunable = mv3310_get_tunable, 1153 .set_tunable = mv3310_set_tunable, 1154 .remove = mv3310_remove, 1155 .set_loopback = genphy_c45_loopback, 1156 }, 1157 { 1158 .phy_id = MARVELL_PHY_ID_88E2110, 1159 .phy_id_mask = MARVELL_PHY_ID_MASK, 1160 .match_phy_device = mv2110_match_phy_device, 1161 .name = "mv88e2110", 1162 .driver_data = &mv2110_type, 1163 .probe = mv3310_probe, 1164 .suspend = mv3310_suspend, 1165 .resume = mv3310_resume, 1166 .config_init = mv3310_config_init, 1167 .config_aneg = mv3310_config_aneg, 1168 .aneg_done = mv3310_aneg_done, 1169 .read_status = mv3310_read_status, 1170 .get_tunable = mv3310_get_tunable, 1171 .set_tunable = mv3310_set_tunable, 1172 .remove = mv3310_remove, 1173 .set_loopback = genphy_c45_loopback, 1174 .get_wol = mv3110_get_wol, 1175 .set_wol = mv3110_set_wol, 1176 }, 1177 { 1178 .phy_id = MARVELL_PHY_ID_88E2110, 1179 .phy_id_mask = MARVELL_PHY_ID_MASK, 1180 .match_phy_device = mv2111_match_phy_device, 1181 .name = "mv88e2111", 1182 .driver_data = &mv2111_type, 1183 .probe = mv3310_probe, 1184 .suspend = mv3310_suspend, 1185 .resume = mv3310_resume, 1186 .config_init = mv3310_config_init, 1187 .config_aneg = mv3310_config_aneg, 1188 .aneg_done = mv3310_aneg_done, 1189 .read_status = mv3310_read_status, 1190 .get_tunable = mv3310_get_tunable, 1191 .set_tunable = mv3310_set_tunable, 1192 .remove = mv3310_remove, 1193 .set_loopback = genphy_c45_loopback, 1194 }, 1195 }; 1196 1197 module_phy_driver(mv3310_drivers); 1198 1199 static struct mdio_device_id __maybe_unused mv3310_tbl[] = { 1200 { MARVELL_PHY_ID_88X3310, MARVELL_PHY_ID_MASK }, 1201 { MARVELL_PHY_ID_88E2110, MARVELL_PHY_ID_MASK }, 1202 { }, 1203 }; 1204 MODULE_DEVICE_TABLE(mdio, mv3310_tbl); 1205 MODULE_DESCRIPTION("Marvell Alaska X/M multi-gigabit Ethernet PHY driver"); 1206 MODULE_LICENSE("GPL"); 1207