1 /* 2 * mdio.c: Generic support for MDIO-compatible transceivers 3 * Copyright 2006-2009 Solarflare Communications Inc. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 as published 7 * by the Free Software Foundation, incorporated herein by reference. 8 */ 9 10 #include <linux/kernel.h> 11 #include <linux/capability.h> 12 #include <linux/errno.h> 13 #include <linux/ethtool.h> 14 #include <linux/mdio.h> 15 #include <linux/module.h> 16 17 MODULE_DESCRIPTION("Generic support for MDIO-compatible transceivers"); 18 MODULE_AUTHOR("Copyright 2006-2009 Solarflare Communications Inc."); 19 MODULE_LICENSE("GPL"); 20 21 /** 22 * mdio45_probe - probe for an MDIO (clause 45) device 23 * @mdio: MDIO interface 24 * @prtad: Expected PHY address 25 * 26 * This sets @prtad and @mmds in the MDIO interface if successful. 27 * Returns 0 on success, negative on error. 28 */ 29 int mdio45_probe(struct mdio_if_info *mdio, int prtad) 30 { 31 int mmd, stat2, devs1, devs2; 32 33 /* Assume PHY must have at least one of PMA/PMD, WIS, PCS, PHY 34 * XS or DTE XS; give up if none is present. */ 35 for (mmd = 1; mmd <= 5; mmd++) { 36 /* Is this MMD present? */ 37 stat2 = mdio->mdio_read(mdio->dev, prtad, mmd, MDIO_STAT2); 38 if (stat2 < 0 || 39 (stat2 & MDIO_STAT2_DEVPRST) != MDIO_STAT2_DEVPRST_VAL) 40 continue; 41 42 /* It should tell us about all the other MMDs */ 43 devs1 = mdio->mdio_read(mdio->dev, prtad, mmd, MDIO_DEVS1); 44 devs2 = mdio->mdio_read(mdio->dev, prtad, mmd, MDIO_DEVS2); 45 if (devs1 < 0 || devs2 < 0) 46 continue; 47 48 mdio->prtad = prtad; 49 mdio->mmds = devs1 | (devs2 << 16); 50 return 0; 51 } 52 53 return -ENODEV; 54 } 55 EXPORT_SYMBOL(mdio45_probe); 56 57 /** 58 * mdio_set_flag - set or clear flag in an MDIO register 59 * @mdio: MDIO interface 60 * @prtad: PHY address 61 * @devad: MMD address 62 * @addr: Register address 63 * @mask: Mask for flag (single bit set) 64 * @sense: New value of flag 65 * 66 * This debounces changes: it does not write the register if the flag 67 * already has the proper value. Returns 0 on success, negative on error. 68 */ 69 int mdio_set_flag(const struct mdio_if_info *mdio, 70 int prtad, int devad, u16 addr, int mask, 71 bool sense) 72 { 73 int old_val = mdio->mdio_read(mdio->dev, prtad, devad, addr); 74 int new_val; 75 76 if (old_val < 0) 77 return old_val; 78 if (sense) 79 new_val = old_val | mask; 80 else 81 new_val = old_val & ~mask; 82 if (old_val == new_val) 83 return 0; 84 return mdio->mdio_write(mdio->dev, prtad, devad, addr, new_val); 85 } 86 EXPORT_SYMBOL(mdio_set_flag); 87 88 /** 89 * mdio_link_ok - is link status up/OK 90 * @mdio: MDIO interface 91 * @mmd_mask: Mask for MMDs to check 92 * 93 * Returns 1 if the PHY reports link status up/OK, 0 otherwise. 94 * @mmd_mask is normally @mdio->mmds, but if loopback is enabled 95 * the MMDs being bypassed should be excluded from the mask. 96 */ 97 int mdio45_links_ok(const struct mdio_if_info *mdio, u32 mmd_mask) 98 { 99 int devad, reg; 100 101 if (!mmd_mask) { 102 /* Use absence of XGMII faults in lieu of link state */ 103 reg = mdio->mdio_read(mdio->dev, mdio->prtad, 104 MDIO_MMD_PHYXS, MDIO_STAT2); 105 return reg >= 0 && !(reg & MDIO_STAT2_RXFAULT); 106 } 107 108 for (devad = 0; mmd_mask; devad++) { 109 if (mmd_mask & (1 << devad)) { 110 mmd_mask &= ~(1 << devad); 111 112 /* Read twice because link state is latched and a 113 * read moves the current state into the register */ 114 mdio->mdio_read(mdio->dev, mdio->prtad, 115 devad, MDIO_STAT1); 116 reg = mdio->mdio_read(mdio->dev, mdio->prtad, 117 devad, MDIO_STAT1); 118 if (reg < 0 || !(reg & MDIO_STAT1_LSTATUS)) 119 return false; 120 } 121 } 122 123 return true; 124 } 125 EXPORT_SYMBOL(mdio45_links_ok); 126 127 /** 128 * mdio45_nway_restart - restart auto-negotiation for this interface 129 * @mdio: MDIO interface 130 * 131 * Returns 0 on success, negative on error. 132 */ 133 int mdio45_nway_restart(const struct mdio_if_info *mdio) 134 { 135 if (!(mdio->mmds & MDIO_DEVS_AN)) 136 return -EOPNOTSUPP; 137 138 mdio_set_flag(mdio, mdio->prtad, MDIO_MMD_AN, MDIO_CTRL1, 139 MDIO_AN_CTRL1_RESTART, true); 140 return 0; 141 } 142 EXPORT_SYMBOL(mdio45_nway_restart); 143 144 static u32 mdio45_get_an(const struct mdio_if_info *mdio, u16 addr) 145 { 146 u32 result = 0; 147 int reg; 148 149 reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_AN, addr); 150 if (reg & ADVERTISE_10HALF) 151 result |= ADVERTISED_10baseT_Half; 152 if (reg & ADVERTISE_10FULL) 153 result |= ADVERTISED_10baseT_Full; 154 if (reg & ADVERTISE_100HALF) 155 result |= ADVERTISED_100baseT_Half; 156 if (reg & ADVERTISE_100FULL) 157 result |= ADVERTISED_100baseT_Full; 158 return result; 159 } 160 161 /** 162 * mdio45_ethtool_gset_npage - get settings for ETHTOOL_GSET 163 * @mdio: MDIO interface 164 * @ecmd: Ethtool request structure 165 * @npage_adv: Modes currently advertised on next pages 166 * @npage_lpa: Modes advertised by link partner on next pages 167 * 168 * Since the CSRs for auto-negotiation using next pages are not fully 169 * standardised, this function does not attempt to decode them. The 170 * caller must pass them in. 171 */ 172 void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio, 173 struct ethtool_cmd *ecmd, 174 u32 npage_adv, u32 npage_lpa) 175 { 176 int reg; 177 178 ecmd->transceiver = XCVR_INTERNAL; 179 ecmd->phy_address = mdio->prtad; 180 ecmd->mdio_support = 181 mdio->mode_support & (MDIO_SUPPORTS_C45 | MDIO_SUPPORTS_C22); 182 183 reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD, 184 MDIO_CTRL2); 185 switch (reg & MDIO_PMA_CTRL2_TYPE) { 186 case MDIO_PMA_CTRL2_10GBT: 187 case MDIO_PMA_CTRL2_1000BT: 188 case MDIO_PMA_CTRL2_100BTX: 189 case MDIO_PMA_CTRL2_10BT: 190 ecmd->port = PORT_TP; 191 ecmd->supported = SUPPORTED_TP; 192 reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD, 193 MDIO_SPEED); 194 if (reg & MDIO_SPEED_10G) 195 ecmd->supported |= SUPPORTED_10000baseT_Full; 196 if (reg & MDIO_PMA_SPEED_1000) 197 ecmd->supported |= (SUPPORTED_1000baseT_Full | 198 SUPPORTED_1000baseT_Half); 199 if (reg & MDIO_PMA_SPEED_100) 200 ecmd->supported |= (SUPPORTED_100baseT_Full | 201 SUPPORTED_100baseT_Half); 202 if (reg & MDIO_PMA_SPEED_10) 203 ecmd->supported |= (SUPPORTED_10baseT_Full | 204 SUPPORTED_10baseT_Half); 205 ecmd->advertising = ADVERTISED_TP; 206 break; 207 208 case MDIO_PMA_CTRL2_10GBCX4: 209 ecmd->port = PORT_OTHER; 210 ecmd->supported = 0; 211 ecmd->advertising = 0; 212 break; 213 214 case MDIO_PMA_CTRL2_10GBKX4: 215 case MDIO_PMA_CTRL2_10GBKR: 216 case MDIO_PMA_CTRL2_1000BKX: 217 ecmd->port = PORT_OTHER; 218 ecmd->supported = SUPPORTED_Backplane; 219 reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD, 220 MDIO_PMA_EXTABLE); 221 if (reg & MDIO_PMA_EXTABLE_10GBKX4) 222 ecmd->supported |= SUPPORTED_10000baseKX4_Full; 223 if (reg & MDIO_PMA_EXTABLE_10GBKR) 224 ecmd->supported |= SUPPORTED_10000baseKR_Full; 225 if (reg & MDIO_PMA_EXTABLE_1000BKX) 226 ecmd->supported |= SUPPORTED_1000baseKX_Full; 227 reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD, 228 MDIO_PMA_10GBR_FECABLE); 229 if (reg & MDIO_PMA_10GBR_FECABLE_ABLE) 230 ecmd->supported |= SUPPORTED_10000baseR_FEC; 231 ecmd->advertising = ADVERTISED_Backplane; 232 break; 233 234 /* All the other defined modes are flavours of optical */ 235 default: 236 ecmd->port = PORT_FIBRE; 237 ecmd->supported = SUPPORTED_FIBRE; 238 ecmd->advertising = ADVERTISED_FIBRE; 239 break; 240 } 241 242 if (mdio->mmds & MDIO_DEVS_AN) { 243 ecmd->supported |= SUPPORTED_Autoneg; 244 reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_AN, 245 MDIO_CTRL1); 246 if (reg & MDIO_AN_CTRL1_ENABLE) { 247 ecmd->autoneg = AUTONEG_ENABLE; 248 ecmd->advertising |= 249 ADVERTISED_Autoneg | 250 mdio45_get_an(mdio, MDIO_AN_ADVERTISE) | 251 npage_adv; 252 } else { 253 ecmd->autoneg = AUTONEG_DISABLE; 254 } 255 } else { 256 ecmd->autoneg = AUTONEG_DISABLE; 257 } 258 259 if (ecmd->autoneg) { 260 u32 modes = 0; 261 int an_stat = mdio->mdio_read(mdio->dev, mdio->prtad, 262 MDIO_MMD_AN, MDIO_STAT1); 263 264 /* If AN is complete and successful, report best common 265 * mode, otherwise report best advertised mode. */ 266 if (an_stat & MDIO_AN_STAT1_COMPLETE) { 267 ecmd->lp_advertising = 268 mdio45_get_an(mdio, MDIO_AN_LPA) | npage_lpa; 269 if (an_stat & MDIO_AN_STAT1_LPABLE) 270 ecmd->lp_advertising |= ADVERTISED_Autoneg; 271 modes = ecmd->advertising & ecmd->lp_advertising; 272 } 273 if ((modes & ~ADVERTISED_Autoneg) == 0) 274 modes = ecmd->advertising; 275 276 if (modes & (ADVERTISED_10000baseT_Full | 277 ADVERTISED_10000baseKX4_Full | 278 ADVERTISED_10000baseKR_Full)) { 279 ecmd->speed = SPEED_10000; 280 ecmd->duplex = DUPLEX_FULL; 281 } else if (modes & (ADVERTISED_1000baseT_Full | 282 ADVERTISED_1000baseT_Half | 283 ADVERTISED_1000baseKX_Full)) { 284 ecmd->speed = SPEED_1000; 285 ecmd->duplex = !(modes & ADVERTISED_1000baseT_Half); 286 } else if (modes & (ADVERTISED_100baseT_Full | 287 ADVERTISED_100baseT_Half)) { 288 ecmd->speed = SPEED_100; 289 ecmd->duplex = !!(modes & ADVERTISED_100baseT_Full); 290 } else { 291 ecmd->speed = SPEED_10; 292 ecmd->duplex = !!(modes & ADVERTISED_10baseT_Full); 293 } 294 } else { 295 /* Report forced settings */ 296 reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD, 297 MDIO_CTRL1); 298 ecmd->speed = (((reg & MDIO_PMA_CTRL1_SPEED1000) ? 100 : 1) * 299 ((reg & MDIO_PMA_CTRL1_SPEED100) ? 100 : 10)); 300 ecmd->duplex = (reg & MDIO_CTRL1_FULLDPLX || 301 ecmd->speed == SPEED_10000); 302 } 303 304 /* 10GBASE-T MDI/MDI-X */ 305 if (ecmd->port == PORT_TP && ecmd->speed == SPEED_10000) { 306 switch (mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD, 307 MDIO_PMA_10GBT_SWAPPOL)) { 308 case MDIO_PMA_10GBT_SWAPPOL_ABNX | MDIO_PMA_10GBT_SWAPPOL_CDNX: 309 ecmd->eth_tp_mdix = ETH_TP_MDI; 310 break; 311 case 0: 312 ecmd->eth_tp_mdix = ETH_TP_MDI_X; 313 break; 314 default: 315 /* It's complicated... */ 316 ecmd->eth_tp_mdix = ETH_TP_MDI_INVALID; 317 break; 318 } 319 } 320 } 321 EXPORT_SYMBOL(mdio45_ethtool_gset_npage); 322 323 /** 324 * mdio45_ethtool_spauseparam_an - set auto-negotiated pause parameters 325 * @mdio: MDIO interface 326 * @ecmd: Ethtool request structure 327 * 328 * This function assumes that the PHY has an auto-negotiation MMD. It 329 * will enable and disable advertising of flow control as appropriate. 330 */ 331 void mdio45_ethtool_spauseparam_an(const struct mdio_if_info *mdio, 332 const struct ethtool_pauseparam *ecmd) 333 { 334 int adv, old_adv; 335 336 WARN_ON(!(mdio->mmds & MDIO_DEVS_AN)); 337 338 old_adv = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_AN, 339 MDIO_AN_ADVERTISE); 340 adv = old_adv & ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); 341 if (ecmd->autoneg) 342 adv |= mii_advertise_flowctrl( 343 (ecmd->rx_pause ? FLOW_CTRL_RX : 0) | 344 (ecmd->tx_pause ? FLOW_CTRL_TX : 0)); 345 if (adv != old_adv) { 346 mdio->mdio_write(mdio->dev, mdio->prtad, MDIO_MMD_AN, 347 MDIO_AN_ADVERTISE, adv); 348 mdio45_nway_restart(mdio); 349 } 350 } 351 EXPORT_SYMBOL(mdio45_ethtool_spauseparam_an); 352 353 /** 354 * mdio_mii_ioctl - MII ioctl interface for MDIO (clause 22 or 45) PHYs 355 * @mdio: MDIO interface 356 * @mii_data: MII ioctl data structure 357 * @cmd: MII ioctl command 358 * 359 * Returns 0 on success, negative on error. 360 */ 361 int mdio_mii_ioctl(const struct mdio_if_info *mdio, 362 struct mii_ioctl_data *mii_data, int cmd) 363 { 364 int prtad, devad; 365 u16 addr = mii_data->reg_num; 366 367 /* Validate/convert cmd to one of SIOC{G,S}MIIREG */ 368 switch (cmd) { 369 case SIOCGMIIPHY: 370 if (mdio->prtad == MDIO_PRTAD_NONE) 371 return -EOPNOTSUPP; 372 mii_data->phy_id = mdio->prtad; 373 cmd = SIOCGMIIREG; 374 break; 375 case SIOCGMIIREG: 376 break; 377 case SIOCSMIIREG: 378 if (!capable(CAP_NET_ADMIN)) 379 return -EPERM; 380 break; 381 default: 382 return -EOPNOTSUPP; 383 } 384 385 /* Validate/convert phy_id */ 386 if ((mdio->mode_support & MDIO_SUPPORTS_C45) && 387 mdio_phy_id_is_c45(mii_data->phy_id)) { 388 prtad = mdio_phy_id_prtad(mii_data->phy_id); 389 devad = mdio_phy_id_devad(mii_data->phy_id); 390 } else if ((mdio->mode_support & MDIO_SUPPORTS_C22) && 391 mii_data->phy_id < 0x20) { 392 prtad = mii_data->phy_id; 393 devad = MDIO_DEVAD_NONE; 394 addr &= 0x1f; 395 } else if ((mdio->mode_support & MDIO_EMULATE_C22) && 396 mdio->prtad != MDIO_PRTAD_NONE && 397 mii_data->phy_id == mdio->prtad) { 398 /* Remap commonly-used MII registers. */ 399 prtad = mdio->prtad; 400 switch (addr) { 401 case MII_BMCR: 402 case MII_BMSR: 403 case MII_PHYSID1: 404 case MII_PHYSID2: 405 devad = __ffs(mdio->mmds); 406 break; 407 case MII_ADVERTISE: 408 case MII_LPA: 409 if (!(mdio->mmds & MDIO_DEVS_AN)) 410 return -EINVAL; 411 devad = MDIO_MMD_AN; 412 if (addr == MII_ADVERTISE) 413 addr = MDIO_AN_ADVERTISE; 414 else 415 addr = MDIO_AN_LPA; 416 break; 417 default: 418 return -EINVAL; 419 } 420 } else { 421 return -EINVAL; 422 } 423 424 if (cmd == SIOCGMIIREG) { 425 int rc = mdio->mdio_read(mdio->dev, prtad, devad, addr); 426 if (rc < 0) 427 return rc; 428 mii_data->val_out = rc; 429 return 0; 430 } else { 431 return mdio->mdio_write(mdio->dev, prtad, devad, addr, 432 mii_data->val_in); 433 } 434 } 435 EXPORT_SYMBOL(mdio_mii_ioctl); 436