1 /* 2 * AMD 10Gb Ethernet driver 3 * 4 * This file is available to you under your choice of the following two 5 * licenses: 6 * 7 * License 1: GPLv2 8 * 9 * Copyright (c) 2014-2016 Advanced Micro Devices, Inc. 10 * 11 * This file is free software; you may copy, redistribute and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation, either version 2 of the License, or (at 14 * your option) any later version. 15 * 16 * This file is distributed in the hope that it will be useful, but 17 * WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 * General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program. If not, see <http://www.gnu.org/licenses/>. 23 * 24 * This file incorporates work covered by the following copyright and 25 * permission notice: 26 * The Synopsys DWC ETHER XGMAC Software Driver and documentation 27 * (hereinafter "Software") is an unsupported proprietary work of Synopsys, 28 * Inc. unless otherwise expressly agreed to in writing between Synopsys 29 * and you. 30 * 31 * The Software IS NOT an item of Licensed Software or Licensed Product 32 * under any End User Software License Agreement or Agreement for Licensed 33 * Product with Synopsys or any supplement thereto. Permission is hereby 34 * granted, free of charge, to any person obtaining a copy of this software 35 * annotated with this license and the Software, to deal in the Software 36 * without restriction, including without limitation the rights to use, 37 * copy, modify, merge, publish, distribute, sublicense, and/or sell copies 38 * of the Software, and to permit persons to whom the Software is furnished 39 * to do so, subject to the following conditions: 40 * 41 * The above copyright notice and this permission notice shall be included 42 * in all copies or substantial portions of the Software. 43 * 44 * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" 45 * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 46 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 47 * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 48 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 49 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 50 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 51 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 52 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 53 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 54 * THE POSSIBILITY OF SUCH DAMAGE. 55 * 56 * 57 * License 2: Modified BSD 58 * 59 * Copyright (c) 2014-2016 Advanced Micro Devices, Inc. 60 * All rights reserved. 61 * 62 * Redistribution and use in source and binary forms, with or without 63 * modification, are permitted provided that the following conditions are met: 64 * * Redistributions of source code must retain the above copyright 65 * notice, this list of conditions and the following disclaimer. 66 * * Redistributions in binary form must reproduce the above copyright 67 * notice, this list of conditions and the following disclaimer in the 68 * documentation and/or other materials provided with the distribution. 69 * * Neither the name of Advanced Micro Devices, Inc. nor the 70 * names of its contributors may be used to endorse or promote products 71 * derived from this software without specific prior written permission. 72 * 73 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 74 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 75 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 76 * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY 77 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 78 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 79 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 80 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 81 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 82 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 83 * 84 * This file incorporates work covered by the following copyright and 85 * permission notice: 86 * The Synopsys DWC ETHER XGMAC Software Driver and documentation 87 * (hereinafter "Software") is an unsupported proprietary work of Synopsys, 88 * Inc. unless otherwise expressly agreed to in writing between Synopsys 89 * and you. 90 * 91 * The Software IS NOT an item of Licensed Software or Licensed Product 92 * under any End User Software License Agreement or Agreement for Licensed 93 * Product with Synopsys or any supplement thereto. Permission is hereby 94 * granted, free of charge, to any person obtaining a copy of this software 95 * annotated with this license and the Software, to deal in the Software 96 * without restriction, including without limitation the rights to use, 97 * copy, modify, merge, publish, distribute, sublicense, and/or sell copies 98 * of the Software, and to permit persons to whom the Software is furnished 99 * to do so, subject to the following conditions: 100 * 101 * The above copyright notice and this permission notice shall be included 102 * in all copies or substantial portions of the Software. 103 * 104 * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" 105 * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 106 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 107 * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 108 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 109 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 110 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 111 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 112 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 113 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 114 * THE POSSIBILITY OF SUCH DAMAGE. 115 */ 116 117 #include <sys/cdefs.h> 118 __FBSDID("$FreeBSD$"); 119 120 #include <sys/param.h> 121 #include <sys/kernel.h> 122 123 #include "xgbe.h" 124 #include "xgbe-common.h" 125 126 static void xgbe_an_state_machine(struct xgbe_prv_data *pdata); 127 128 static void xgbe_an_enable_kr_training(struct xgbe_prv_data *pdata) 129 { 130 unsigned int reg; 131 132 reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL); 133 134 reg |= XGBE_KR_TRAINING_ENABLE; 135 XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg); 136 } 137 138 static void xgbe_an_disable_kr_training(struct xgbe_prv_data *pdata) 139 { 140 unsigned int reg; 141 142 reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL); 143 144 reg &= ~XGBE_KR_TRAINING_ENABLE; 145 XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg); 146 } 147 148 static void xgbe_pcs_power_cycle(struct xgbe_prv_data *pdata) 149 { 150 unsigned int reg; 151 152 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1); 153 154 reg |= MDIO_CTRL1_LPOWER; 155 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg); 156 157 DELAY(75); 158 159 reg &= ~MDIO_CTRL1_LPOWER; 160 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg); 161 } 162 163 static void xgbe_serdes_start_ratechange(struct xgbe_prv_data *pdata) 164 { 165 /* Assert Rx and Tx ratechange */ 166 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, RATECHANGE, 1); 167 } 168 169 static void xgbe_serdes_complete_ratechange(struct xgbe_prv_data *pdata) 170 { 171 unsigned int wait; 172 u16 status; 173 174 /* Release Rx and Tx ratechange */ 175 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, RATECHANGE, 0); 176 177 /* Wait for Rx and Tx ready */ 178 wait = XGBE_RATECHANGE_COUNT; 179 while (wait--) { 180 DELAY(50); 181 182 status = XSIR0_IOREAD(pdata, SIR0_STATUS); 183 if (XSIR_GET_BITS(status, SIR0_STATUS, RX_READY) && 184 XSIR_GET_BITS(status, SIR0_STATUS, TX_READY)) 185 goto rx_reset; 186 } 187 188 rx_reset: 189 /* Perform Rx reset for the DFE changes */ 190 XRXTX_IOWRITE_BITS(pdata, RXTX_REG6, RESETB_RXD, 0); 191 XRXTX_IOWRITE_BITS(pdata, RXTX_REG6, RESETB_RXD, 1); 192 } 193 194 static void xgbe_xgmii_mode(struct xgbe_prv_data *pdata) 195 { 196 unsigned int reg; 197 198 /* Enable KR training */ 199 xgbe_an_enable_kr_training(pdata); 200 201 /* Set MAC to 10G speed */ 202 pdata->hw_if.set_xgmii_speed(pdata); 203 204 /* Set PCS to KR/10G speed */ 205 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL2); 206 reg &= ~MDIO_PCS_CTRL2_TYPE; 207 reg |= MDIO_PCS_CTRL2_10GBR; 208 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL2, reg); 209 210 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1); 211 reg &= ~MDIO_CTRL1_SPEEDSEL; 212 reg |= MDIO_CTRL1_SPEED10G; 213 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg); 214 215 xgbe_pcs_power_cycle(pdata); 216 217 /* Set SerDes to 10G speed */ 218 xgbe_serdes_start_ratechange(pdata); 219 220 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, DATARATE, XGBE_SPEED_10000_RATE); 221 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, WORDMODE, XGBE_SPEED_10000_WORD); 222 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, PLLSEL, XGBE_SPEED_10000_PLL); 223 224 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, CDR_RATE, 225 pdata->serdes_cdr_rate[XGBE_SPEED_10000]); 226 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, TXAMP, 227 pdata->serdes_tx_amp[XGBE_SPEED_10000]); 228 XRXTX_IOWRITE_BITS(pdata, RXTX_REG20, BLWC_ENA, 229 pdata->serdes_blwc[XGBE_SPEED_10000]); 230 XRXTX_IOWRITE_BITS(pdata, RXTX_REG114, PQ_REG, 231 pdata->serdes_pq_skew[XGBE_SPEED_10000]); 232 XRXTX_IOWRITE_BITS(pdata, RXTX_REG129, RXDFE_CONFIG, 233 pdata->serdes_dfe_tap_cfg[XGBE_SPEED_10000]); 234 XRXTX_IOWRITE(pdata, RXTX_REG22, 235 pdata->serdes_dfe_tap_ena[XGBE_SPEED_10000]); 236 237 xgbe_serdes_complete_ratechange(pdata); 238 } 239 240 static void xgbe_gmii_2500_mode(struct xgbe_prv_data *pdata) 241 { 242 unsigned int reg; 243 244 /* Disable KR training */ 245 xgbe_an_disable_kr_training(pdata); 246 247 /* Set MAC to 2.5G speed */ 248 pdata->hw_if.set_gmii_2500_speed(pdata); 249 250 /* Set PCS to KX/1G speed */ 251 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL2); 252 reg &= ~MDIO_PCS_CTRL2_TYPE; 253 reg |= MDIO_PCS_CTRL2_10GBX; 254 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL2, reg); 255 256 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1); 257 reg &= ~MDIO_CTRL1_SPEEDSEL; 258 reg |= MDIO_CTRL1_SPEED1G; 259 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg); 260 261 xgbe_pcs_power_cycle(pdata); 262 263 /* Set SerDes to 2.5G speed */ 264 xgbe_serdes_start_ratechange(pdata); 265 266 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, DATARATE, XGBE_SPEED_2500_RATE); 267 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, WORDMODE, XGBE_SPEED_2500_WORD); 268 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, PLLSEL, XGBE_SPEED_2500_PLL); 269 270 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, CDR_RATE, 271 pdata->serdes_cdr_rate[XGBE_SPEED_2500]); 272 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, TXAMP, 273 pdata->serdes_tx_amp[XGBE_SPEED_2500]); 274 XRXTX_IOWRITE_BITS(pdata, RXTX_REG20, BLWC_ENA, 275 pdata->serdes_blwc[XGBE_SPEED_2500]); 276 XRXTX_IOWRITE_BITS(pdata, RXTX_REG114, PQ_REG, 277 pdata->serdes_pq_skew[XGBE_SPEED_2500]); 278 XRXTX_IOWRITE_BITS(pdata, RXTX_REG129, RXDFE_CONFIG, 279 pdata->serdes_dfe_tap_cfg[XGBE_SPEED_2500]); 280 XRXTX_IOWRITE(pdata, RXTX_REG22, 281 pdata->serdes_dfe_tap_ena[XGBE_SPEED_2500]); 282 283 xgbe_serdes_complete_ratechange(pdata); 284 } 285 286 static void xgbe_gmii_mode(struct xgbe_prv_data *pdata) 287 { 288 unsigned int reg; 289 290 /* Disable KR training */ 291 xgbe_an_disable_kr_training(pdata); 292 293 /* Set MAC to 1G speed */ 294 pdata->hw_if.set_gmii_speed(pdata); 295 296 /* Set PCS to KX/1G speed */ 297 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL2); 298 reg &= ~MDIO_PCS_CTRL2_TYPE; 299 reg |= MDIO_PCS_CTRL2_10GBX; 300 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL2, reg); 301 302 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1); 303 reg &= ~MDIO_CTRL1_SPEEDSEL; 304 reg |= MDIO_CTRL1_SPEED1G; 305 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg); 306 307 xgbe_pcs_power_cycle(pdata); 308 309 /* Set SerDes to 1G speed */ 310 xgbe_serdes_start_ratechange(pdata); 311 312 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, DATARATE, XGBE_SPEED_1000_RATE); 313 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, WORDMODE, XGBE_SPEED_1000_WORD); 314 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, PLLSEL, XGBE_SPEED_1000_PLL); 315 316 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, CDR_RATE, 317 pdata->serdes_cdr_rate[XGBE_SPEED_1000]); 318 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, TXAMP, 319 pdata->serdes_tx_amp[XGBE_SPEED_1000]); 320 XRXTX_IOWRITE_BITS(pdata, RXTX_REG20, BLWC_ENA, 321 pdata->serdes_blwc[XGBE_SPEED_1000]); 322 XRXTX_IOWRITE_BITS(pdata, RXTX_REG114, PQ_REG, 323 pdata->serdes_pq_skew[XGBE_SPEED_1000]); 324 XRXTX_IOWRITE_BITS(pdata, RXTX_REG129, RXDFE_CONFIG, 325 pdata->serdes_dfe_tap_cfg[XGBE_SPEED_1000]); 326 XRXTX_IOWRITE(pdata, RXTX_REG22, 327 pdata->serdes_dfe_tap_ena[XGBE_SPEED_1000]); 328 329 xgbe_serdes_complete_ratechange(pdata); 330 } 331 332 static void xgbe_cur_mode(struct xgbe_prv_data *pdata, 333 enum xgbe_mode *mode) 334 { 335 unsigned int reg; 336 337 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL2); 338 if ((reg & MDIO_PCS_CTRL2_TYPE) == MDIO_PCS_CTRL2_10GBR) 339 *mode = XGBE_MODE_KR; 340 else 341 *mode = XGBE_MODE_KX; 342 } 343 344 static bool xgbe_in_kr_mode(struct xgbe_prv_data *pdata) 345 { 346 enum xgbe_mode mode; 347 348 xgbe_cur_mode(pdata, &mode); 349 350 return (mode == XGBE_MODE_KR); 351 } 352 353 static void xgbe_switch_mode(struct xgbe_prv_data *pdata) 354 { 355 /* If we are in KR switch to KX, and vice-versa */ 356 if (xgbe_in_kr_mode(pdata)) { 357 if (pdata->speed_set == XGBE_SPEEDSET_1000_10000) 358 xgbe_gmii_mode(pdata); 359 else 360 xgbe_gmii_2500_mode(pdata); 361 } else { 362 xgbe_xgmii_mode(pdata); 363 } 364 } 365 366 static void xgbe_set_mode(struct xgbe_prv_data *pdata, 367 enum xgbe_mode mode) 368 { 369 enum xgbe_mode cur_mode; 370 371 xgbe_cur_mode(pdata, &cur_mode); 372 if (mode != cur_mode) 373 xgbe_switch_mode(pdata); 374 } 375 376 static bool xgbe_use_xgmii_mode(struct xgbe_prv_data *pdata) 377 { 378 if (pdata->phy.autoneg == AUTONEG_ENABLE) { 379 if (pdata->phy.advertising & ADVERTISED_10000baseKR_Full) 380 return true; 381 } else { 382 if (pdata->phy.speed == SPEED_10000) 383 return true; 384 } 385 386 return false; 387 } 388 389 static bool xgbe_use_gmii_2500_mode(struct xgbe_prv_data *pdata) 390 { 391 if (pdata->phy.autoneg == AUTONEG_ENABLE) { 392 if (pdata->phy.advertising & ADVERTISED_2500baseX_Full) 393 return true; 394 } else { 395 if (pdata->phy.speed == SPEED_2500) 396 return true; 397 } 398 399 return false; 400 } 401 402 static bool xgbe_use_gmii_mode(struct xgbe_prv_data *pdata) 403 { 404 if (pdata->phy.autoneg == AUTONEG_ENABLE) { 405 if (pdata->phy.advertising & ADVERTISED_1000baseKX_Full) 406 return true; 407 } else { 408 if (pdata->phy.speed == SPEED_1000) 409 return true; 410 } 411 412 return false; 413 } 414 415 static void xgbe_set_an(struct xgbe_prv_data *pdata, bool enable, bool restart) 416 { 417 unsigned int reg; 418 419 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_CTRL1); 420 reg &= ~MDIO_AN_CTRL1_ENABLE; 421 422 if (enable) 423 reg |= MDIO_AN_CTRL1_ENABLE; 424 425 if (restart) 426 reg |= MDIO_AN_CTRL1_RESTART; 427 428 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_CTRL1, reg); 429 } 430 431 static void xgbe_restart_an(struct xgbe_prv_data *pdata) 432 { 433 xgbe_set_an(pdata, true, true); 434 } 435 436 static void xgbe_disable_an(struct xgbe_prv_data *pdata) 437 { 438 xgbe_set_an(pdata, false, false); 439 } 440 441 static enum xgbe_an xgbe_an_tx_training(struct xgbe_prv_data *pdata, 442 enum xgbe_rx *state) 443 { 444 unsigned int ad_reg, lp_reg, reg; 445 446 *state = XGBE_RX_COMPLETE; 447 448 /* If we're not in KR mode then we're done */ 449 if (!xgbe_in_kr_mode(pdata)) 450 return XGBE_AN_PAGE_RECEIVED; 451 452 /* Enable/Disable FEC */ 453 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2); 454 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 2); 455 456 reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FECCTRL); 457 reg &= ~(MDIO_PMA_10GBR_FECABLE_ABLE | MDIO_PMA_10GBR_FECABLE_ERRABLE); 458 if ((ad_reg & 0xc000) && (lp_reg & 0xc000)) 459 reg |= pdata->fec_ability; 460 461 XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FECCTRL, reg); 462 463 /* Start KR training */ 464 reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL); 465 if (reg & XGBE_KR_TRAINING_ENABLE) { 466 XSIR0_IOWRITE_BITS(pdata, SIR0_KR_RT_1, RESET, 1); 467 468 reg |= XGBE_KR_TRAINING_START; 469 XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, 470 reg); 471 472 XSIR0_IOWRITE_BITS(pdata, SIR0_KR_RT_1, RESET, 0); 473 } 474 475 return XGBE_AN_PAGE_RECEIVED; 476 } 477 478 static enum xgbe_an xgbe_an_tx_xnp(struct xgbe_prv_data *pdata, 479 enum xgbe_rx *state) 480 { 481 u16 msg; 482 483 *state = XGBE_RX_XNP; 484 485 msg = XGBE_XNP_MCF_NULL_MESSAGE; 486 msg |= XGBE_XNP_MP_FORMATTED; 487 488 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_XNP + 2, 0); 489 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_XNP + 1, 0); 490 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_XNP, msg); 491 492 return XGBE_AN_PAGE_RECEIVED; 493 } 494 495 static enum xgbe_an xgbe_an_rx_bpa(struct xgbe_prv_data *pdata, 496 enum xgbe_rx *state) 497 { 498 unsigned int link_support; 499 unsigned int reg, ad_reg, lp_reg; 500 501 /* Read Base Ability register 2 first */ 502 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 1); 503 504 /* Check for a supported mode, otherwise restart in a different one */ 505 link_support = xgbe_in_kr_mode(pdata) ? 0x80 : 0x20; 506 if (!(reg & link_support)) 507 return XGBE_AN_INCOMPAT_LINK; 508 509 /* Check Extended Next Page support */ 510 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE); 511 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA); 512 513 return ((ad_reg & XGBE_XNP_NP_EXCHANGE) || 514 (lp_reg & XGBE_XNP_NP_EXCHANGE)) 515 ? xgbe_an_tx_xnp(pdata, state) 516 : xgbe_an_tx_training(pdata, state); 517 } 518 519 static enum xgbe_an xgbe_an_rx_xnp(struct xgbe_prv_data *pdata, 520 enum xgbe_rx *state) 521 { 522 unsigned int ad_reg, lp_reg; 523 524 /* Check Extended Next Page support */ 525 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_XNP); 526 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPX); 527 528 return ((ad_reg & XGBE_XNP_NP_EXCHANGE) || 529 (lp_reg & XGBE_XNP_NP_EXCHANGE)) 530 ? xgbe_an_tx_xnp(pdata, state) 531 : xgbe_an_tx_training(pdata, state); 532 } 533 534 static enum xgbe_an xgbe_an_page_received(struct xgbe_prv_data *pdata) 535 { 536 enum xgbe_rx *state; 537 unsigned long an_timeout; 538 enum xgbe_an ret; 539 540 if (!pdata->an_start) { 541 pdata->an_start = ticks; 542 } else { 543 an_timeout = pdata->an_start + 544 ((uint64_t)XGBE_AN_MS_TIMEOUT * (uint64_t)hz) / 1000ull; 545 if ((int)(ticks - an_timeout) > 0) { 546 /* Auto-negotiation timed out, reset state */ 547 pdata->kr_state = XGBE_RX_BPA; 548 pdata->kx_state = XGBE_RX_BPA; 549 550 pdata->an_start = ticks; 551 } 552 } 553 554 state = xgbe_in_kr_mode(pdata) ? &pdata->kr_state 555 : &pdata->kx_state; 556 557 switch (*state) { 558 case XGBE_RX_BPA: 559 ret = xgbe_an_rx_bpa(pdata, state); 560 break; 561 562 case XGBE_RX_XNP: 563 ret = xgbe_an_rx_xnp(pdata, state); 564 break; 565 566 default: 567 ret = XGBE_AN_ERROR; 568 } 569 570 return ret; 571 } 572 573 static enum xgbe_an xgbe_an_incompat_link(struct xgbe_prv_data *pdata) 574 { 575 /* Be sure we aren't looping trying to negotiate */ 576 if (xgbe_in_kr_mode(pdata)) { 577 pdata->kr_state = XGBE_RX_ERROR; 578 579 if (!(pdata->phy.advertising & ADVERTISED_1000baseKX_Full) && 580 !(pdata->phy.advertising & ADVERTISED_2500baseX_Full)) 581 return XGBE_AN_NO_LINK; 582 583 if (pdata->kx_state != XGBE_RX_BPA) 584 return XGBE_AN_NO_LINK; 585 } else { 586 pdata->kx_state = XGBE_RX_ERROR; 587 588 if (!(pdata->phy.advertising & ADVERTISED_10000baseKR_Full)) 589 return XGBE_AN_NO_LINK; 590 591 if (pdata->kr_state != XGBE_RX_BPA) 592 return XGBE_AN_NO_LINK; 593 } 594 595 xgbe_disable_an(pdata); 596 597 xgbe_switch_mode(pdata); 598 599 xgbe_restart_an(pdata); 600 601 return XGBE_AN_INCOMPAT_LINK; 602 } 603 604 static void xgbe_an_isr(void *data) 605 { 606 struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)data; 607 608 /* Disable AN interrupts */ 609 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0); 610 611 /* Save the interrupt(s) that fired */ 612 pdata->an_int = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_INT); 613 614 if (pdata->an_int) { 615 /* Clear the interrupt(s) that fired and process them */ 616 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, ~pdata->an_int); 617 618 xgbe_an_state_machine(pdata); 619 } else { 620 /* Enable AN interrupts */ 621 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 622 XGBE_AN_INT_MASK); 623 } 624 } 625 626 static void xgbe_an_state_machine(struct xgbe_prv_data *pdata) 627 { 628 enum xgbe_an cur_state = pdata->an_state; 629 630 sx_xlock(&pdata->an_mutex); 631 632 if (!pdata->an_int) 633 goto out; 634 635 next_int: 636 if (pdata->an_int & XGBE_AN_PG_RCV) { 637 pdata->an_state = XGBE_AN_PAGE_RECEIVED; 638 pdata->an_int &= ~XGBE_AN_PG_RCV; 639 } else if (pdata->an_int & XGBE_AN_INC_LINK) { 640 pdata->an_state = XGBE_AN_INCOMPAT_LINK; 641 pdata->an_int &= ~XGBE_AN_INC_LINK; 642 } else if (pdata->an_int & XGBE_AN_INT_CMPLT) { 643 pdata->an_state = XGBE_AN_COMPLETE; 644 pdata->an_int &= ~XGBE_AN_INT_CMPLT; 645 } else { 646 pdata->an_state = XGBE_AN_ERROR; 647 } 648 649 pdata->an_result = pdata->an_state; 650 651 again: 652 cur_state = pdata->an_state; 653 654 switch (pdata->an_state) { 655 case XGBE_AN_READY: 656 pdata->an_supported = 0; 657 break; 658 659 case XGBE_AN_PAGE_RECEIVED: 660 pdata->an_state = xgbe_an_page_received(pdata); 661 pdata->an_supported++; 662 break; 663 664 case XGBE_AN_INCOMPAT_LINK: 665 pdata->an_supported = 0; 666 pdata->parallel_detect = 0; 667 pdata->an_state = xgbe_an_incompat_link(pdata); 668 break; 669 670 case XGBE_AN_COMPLETE: 671 pdata->parallel_detect = pdata->an_supported ? 0 : 1; 672 break; 673 674 case XGBE_AN_NO_LINK: 675 break; 676 677 default: 678 pdata->an_state = XGBE_AN_ERROR; 679 } 680 681 if (pdata->an_state == XGBE_AN_NO_LINK) { 682 pdata->an_int = 0; 683 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0); 684 } else if (pdata->an_state == XGBE_AN_ERROR) { 685 pdata->an_int = 0; 686 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0); 687 } 688 689 if (pdata->an_state >= XGBE_AN_COMPLETE) { 690 pdata->an_result = pdata->an_state; 691 pdata->an_state = XGBE_AN_READY; 692 pdata->kr_state = XGBE_RX_BPA; 693 pdata->kx_state = XGBE_RX_BPA; 694 pdata->an_start = 0; 695 } 696 697 if (cur_state != pdata->an_state) 698 goto again; 699 700 if (pdata->an_int) 701 goto next_int; 702 703 out: 704 /* Enable AN interrupts on the way out */ 705 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, XGBE_AN_INT_MASK); 706 707 sx_xunlock(&pdata->an_mutex); 708 } 709 710 static void xgbe_an_init(struct xgbe_prv_data *pdata) 711 { 712 unsigned int reg; 713 714 /* Set up Advertisement register 3 first */ 715 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2); 716 reg &= ~0xc000; 717 718 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2, reg); 719 720 /* Set up Advertisement register 2 next */ 721 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1); 722 if (pdata->phy.advertising & ADVERTISED_10000baseKR_Full) 723 reg |= 0x80; 724 else 725 reg &= ~0x80; 726 727 if ((pdata->phy.advertising & ADVERTISED_1000baseKX_Full) || 728 (pdata->phy.advertising & ADVERTISED_2500baseX_Full)) 729 reg |= 0x20; 730 else 731 reg &= ~0x20; 732 733 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1, reg); 734 735 /* Set up Advertisement register 1 last */ 736 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE); 737 if (pdata->phy.advertising & ADVERTISED_Pause) 738 reg |= 0x400; 739 else 740 reg &= ~0x400; 741 742 if (pdata->phy.advertising & ADVERTISED_Asym_Pause) 743 reg |= 0x800; 744 else 745 reg &= ~0x800; 746 747 /* We don't intend to perform XNP */ 748 reg &= ~XGBE_XNP_NP_EXCHANGE; 749 750 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg); 751 } 752 753 static void xgbe_phy_adjust_link(struct xgbe_prv_data *pdata) 754 { 755 756 if (pdata->phy.link) { 757 /* Flow control support */ 758 pdata->pause_autoneg = pdata->phy.pause_autoneg; 759 760 if (pdata->tx_pause != pdata->phy.tx_pause) { 761 pdata->hw_if.config_tx_flow_control(pdata); 762 pdata->tx_pause = pdata->phy.tx_pause; 763 } 764 765 if (pdata->rx_pause != pdata->phy.rx_pause) { 766 pdata->hw_if.config_rx_flow_control(pdata); 767 pdata->rx_pause = pdata->phy.rx_pause; 768 } 769 770 /* Speed support */ 771 if (pdata->phy_speed != pdata->phy.speed) { 772 pdata->phy_speed = pdata->phy.speed; 773 } 774 775 if (pdata->phy_link != pdata->phy.link) { 776 pdata->phy_link = pdata->phy.link; 777 } 778 } else if (pdata->phy_link) { 779 pdata->phy_link = 0; 780 pdata->phy_speed = SPEED_UNKNOWN; 781 } 782 } 783 784 static int xgbe_phy_config_fixed(struct xgbe_prv_data *pdata) 785 { 786 787 /* Disable auto-negotiation */ 788 xgbe_disable_an(pdata); 789 790 /* Validate/Set specified speed */ 791 switch (pdata->phy.speed) { 792 case SPEED_10000: 793 xgbe_set_mode(pdata, XGBE_MODE_KR); 794 break; 795 796 case SPEED_2500: 797 case SPEED_1000: 798 xgbe_set_mode(pdata, XGBE_MODE_KX); 799 break; 800 801 default: 802 return -EINVAL; 803 } 804 805 /* Validate duplex mode */ 806 if (pdata->phy.duplex != DUPLEX_FULL) 807 return -EINVAL; 808 809 return 0; 810 } 811 812 static int __xgbe_phy_config_aneg(struct xgbe_prv_data *pdata) 813 { 814 set_bit(XGBE_LINK_INIT, &pdata->dev_state); 815 pdata->link_check = ticks; 816 817 if (pdata->phy.autoneg != AUTONEG_ENABLE) 818 return xgbe_phy_config_fixed(pdata); 819 820 /* Disable auto-negotiation interrupt */ 821 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0); 822 823 /* Clear any auto-negotitation interrupts */ 824 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0); 825 826 /* Start auto-negotiation in a supported mode */ 827 if (pdata->phy.advertising & ADVERTISED_10000baseKR_Full) { 828 xgbe_set_mode(pdata, XGBE_MODE_KR); 829 } else if ((pdata->phy.advertising & ADVERTISED_1000baseKX_Full) || 830 (pdata->phy.advertising & ADVERTISED_2500baseX_Full)) { 831 xgbe_set_mode(pdata, XGBE_MODE_KX); 832 } else { 833 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0x07); 834 return -EINVAL; 835 } 836 837 /* Disable and stop any in progress auto-negotiation */ 838 xgbe_disable_an(pdata); 839 840 /* Clear any auto-negotitation interrupts */ 841 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0); 842 843 pdata->an_result = XGBE_AN_READY; 844 pdata->an_state = XGBE_AN_READY; 845 pdata->kr_state = XGBE_RX_BPA; 846 pdata->kx_state = XGBE_RX_BPA; 847 848 /* Re-enable auto-negotiation interrupt */ 849 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0x07); 850 851 /* Set up advertisement registers based on current settings */ 852 xgbe_an_init(pdata); 853 854 /* Enable and start auto-negotiation */ 855 xgbe_restart_an(pdata); 856 857 return 0; 858 } 859 860 static int xgbe_phy_config_aneg(struct xgbe_prv_data *pdata) 861 { 862 int ret; 863 864 sx_xlock(&pdata->an_mutex); 865 866 ret = __xgbe_phy_config_aneg(pdata); 867 if (ret) 868 set_bit(XGBE_LINK_ERR, &pdata->dev_state); 869 else 870 clear_bit(XGBE_LINK_ERR, &pdata->dev_state); 871 872 sx_unlock(&pdata->an_mutex); 873 874 return ret; 875 } 876 877 static bool xgbe_phy_aneg_done(struct xgbe_prv_data *pdata) 878 { 879 return (pdata->an_result == XGBE_AN_COMPLETE); 880 } 881 882 static void xgbe_check_link_timeout(struct xgbe_prv_data *pdata) 883 { 884 unsigned long link_timeout; 885 886 link_timeout = pdata->link_check + (XGBE_LINK_TIMEOUT * hz); 887 if ((int)(ticks - link_timeout) >= 0) { 888 xgbe_phy_config_aneg(pdata); 889 } 890 } 891 892 static void xgbe_phy_status_force(struct xgbe_prv_data *pdata) 893 { 894 if (xgbe_in_kr_mode(pdata)) { 895 pdata->phy.speed = SPEED_10000; 896 } else { 897 switch (pdata->speed_set) { 898 case XGBE_SPEEDSET_1000_10000: 899 pdata->phy.speed = SPEED_1000; 900 break; 901 902 case XGBE_SPEEDSET_2500_10000: 903 pdata->phy.speed = SPEED_2500; 904 break; 905 } 906 } 907 pdata->phy.duplex = DUPLEX_FULL; 908 } 909 910 static void xgbe_phy_status_aneg(struct xgbe_prv_data *pdata) 911 { 912 unsigned int ad_reg, lp_reg; 913 914 pdata->phy.lp_advertising = 0; 915 916 if ((pdata->phy.autoneg != AUTONEG_ENABLE) || pdata->parallel_detect) 917 return xgbe_phy_status_force(pdata); 918 919 pdata->phy.lp_advertising |= ADVERTISED_Autoneg; 920 pdata->phy.lp_advertising |= ADVERTISED_Backplane; 921 922 /* Compare Advertisement and Link Partner register 1 */ 923 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE); 924 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA); 925 if (lp_reg & 0x400) 926 pdata->phy.lp_advertising |= ADVERTISED_Pause; 927 if (lp_reg & 0x800) 928 pdata->phy.lp_advertising |= ADVERTISED_Asym_Pause; 929 930 if (pdata->phy.pause_autoneg) { 931 /* Set flow control based on auto-negotiation result */ 932 pdata->phy.tx_pause = 0; 933 pdata->phy.rx_pause = 0; 934 935 if (ad_reg & lp_reg & 0x400) { 936 pdata->phy.tx_pause = 1; 937 pdata->phy.rx_pause = 1; 938 } else if (ad_reg & lp_reg & 0x800) { 939 if (ad_reg & 0x400) 940 pdata->phy.rx_pause = 1; 941 else if (lp_reg & 0x400) 942 pdata->phy.tx_pause = 1; 943 } 944 } 945 946 /* Compare Advertisement and Link Partner register 2 */ 947 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1); 948 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 1); 949 if (lp_reg & 0x80) 950 pdata->phy.lp_advertising |= ADVERTISED_10000baseKR_Full; 951 if (lp_reg & 0x20) { 952 switch (pdata->speed_set) { 953 case XGBE_SPEEDSET_1000_10000: 954 pdata->phy.lp_advertising |= ADVERTISED_1000baseKX_Full; 955 break; 956 case XGBE_SPEEDSET_2500_10000: 957 pdata->phy.lp_advertising |= ADVERTISED_2500baseX_Full; 958 break; 959 } 960 } 961 962 ad_reg &= lp_reg; 963 if (ad_reg & 0x80) { 964 pdata->phy.speed = SPEED_10000; 965 xgbe_set_mode(pdata, XGBE_MODE_KR); 966 } else if (ad_reg & 0x20) { 967 switch (pdata->speed_set) { 968 case XGBE_SPEEDSET_1000_10000: 969 pdata->phy.speed = SPEED_1000; 970 break; 971 972 case XGBE_SPEEDSET_2500_10000: 973 pdata->phy.speed = SPEED_2500; 974 break; 975 } 976 977 xgbe_set_mode(pdata, XGBE_MODE_KX); 978 } else { 979 pdata->phy.speed = SPEED_UNKNOWN; 980 } 981 982 /* Compare Advertisement and Link Partner register 3 */ 983 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2); 984 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 2); 985 } 986 987 static void xgbe_phy_status(struct xgbe_prv_data *pdata) 988 { 989 unsigned int reg, link_aneg; 990 991 if (test_bit(XGBE_LINK_ERR, &pdata->dev_state)) { 992 pdata->phy.link = 0; 993 goto adjust_link; 994 } 995 996 link_aneg = (pdata->phy.autoneg == AUTONEG_ENABLE); 997 998 /* Get the link status. Link status is latched low, so read 999 * once to clear and then read again to get current state 1000 */ 1001 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); 1002 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); 1003 pdata->phy.link = (reg & MDIO_STAT1_LSTATUS) ? 1 : 0; 1004 1005 if (pdata->phy.link) { 1006 if (link_aneg && !xgbe_phy_aneg_done(pdata)) { 1007 xgbe_check_link_timeout(pdata); 1008 return; 1009 } 1010 1011 xgbe_phy_status_aneg(pdata); 1012 1013 if (test_bit(XGBE_LINK_INIT, &pdata->dev_state)) 1014 clear_bit(XGBE_LINK_INIT, &pdata->dev_state); 1015 } else { 1016 if (test_bit(XGBE_LINK_INIT, &pdata->dev_state)) { 1017 xgbe_check_link_timeout(pdata); 1018 1019 if (link_aneg) 1020 return; 1021 } 1022 1023 xgbe_phy_status_aneg(pdata); 1024 } 1025 1026 adjust_link: 1027 xgbe_phy_adjust_link(pdata); 1028 } 1029 1030 static void xgbe_phy_stop(struct xgbe_prv_data *pdata) 1031 { 1032 1033 /* Disable auto-negotiation */ 1034 xgbe_disable_an(pdata); 1035 1036 /* Disable auto-negotiation interrupts */ 1037 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0); 1038 1039 bus_teardown_intr(pdata->dev, pdata->an_irq_res, pdata->an_irq_tag); 1040 1041 pdata->phy.link = 0; 1042 1043 xgbe_phy_adjust_link(pdata); 1044 } 1045 1046 static int xgbe_phy_start(struct xgbe_prv_data *pdata) 1047 { 1048 int ret; 1049 1050 ret = bus_setup_intr(pdata->dev, pdata->an_irq_res, 1051 INTR_MPSAFE | INTR_TYPE_NET, NULL, xgbe_an_isr, pdata, 1052 &pdata->an_irq_tag); 1053 if (ret) { 1054 return -ret; 1055 } 1056 1057 /* Set initial mode - call the mode setting routines 1058 * directly to insure we are properly configured 1059 */ 1060 if (xgbe_use_xgmii_mode(pdata)) { 1061 xgbe_xgmii_mode(pdata); 1062 } else if (xgbe_use_gmii_mode(pdata)) { 1063 xgbe_gmii_mode(pdata); 1064 } else if (xgbe_use_gmii_2500_mode(pdata)) { 1065 xgbe_gmii_2500_mode(pdata); 1066 } else { 1067 ret = -EINVAL; 1068 goto err_irq; 1069 } 1070 1071 /* Set up advertisement registers based on current settings */ 1072 xgbe_an_init(pdata); 1073 1074 /* Enable auto-negotiation interrupts */ 1075 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0x07); 1076 1077 return xgbe_phy_config_aneg(pdata); 1078 1079 err_irq: 1080 bus_teardown_intr(pdata->dev, pdata->an_irq_res, pdata->an_irq_tag); 1081 1082 return ret; 1083 } 1084 1085 static int xgbe_phy_reset(struct xgbe_prv_data *pdata) 1086 { 1087 unsigned int count, reg; 1088 1089 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1); 1090 reg |= MDIO_CTRL1_RESET; 1091 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg); 1092 1093 count = 50; 1094 do { 1095 DELAY(20); 1096 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1); 1097 } while ((reg & MDIO_CTRL1_RESET) && --count); 1098 1099 if (reg & MDIO_CTRL1_RESET) 1100 return -ETIMEDOUT; 1101 1102 /* Disable auto-negotiation for now */ 1103 xgbe_disable_an(pdata); 1104 1105 /* Clear auto-negotiation interrupts */ 1106 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0); 1107 1108 return 0; 1109 } 1110 1111 static void xgbe_phy_init(struct xgbe_prv_data *pdata) 1112 { 1113 sx_init(&pdata->an_mutex, "axgbe AN lock"); 1114 pdata->mdio_mmd = MDIO_MMD_PCS; 1115 1116 /* Initialize supported features */ 1117 pdata->phy.supported = SUPPORTED_Autoneg; 1118 pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; 1119 pdata->phy.supported |= SUPPORTED_Backplane; 1120 pdata->phy.supported |= SUPPORTED_10000baseKR_Full; 1121 switch (pdata->speed_set) { 1122 case XGBE_SPEEDSET_1000_10000: 1123 pdata->phy.supported |= SUPPORTED_1000baseKX_Full; 1124 break; 1125 case XGBE_SPEEDSET_2500_10000: 1126 pdata->phy.supported |= SUPPORTED_2500baseX_Full; 1127 break; 1128 } 1129 1130 pdata->fec_ability = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, 1131 MDIO_PMA_10GBR_FECABLE); 1132 pdata->fec_ability &= (MDIO_PMA_10GBR_FECABLE_ABLE | 1133 MDIO_PMA_10GBR_FECABLE_ERRABLE); 1134 if (pdata->fec_ability & MDIO_PMA_10GBR_FECABLE_ABLE) 1135 pdata->phy.supported |= SUPPORTED_10000baseR_FEC; 1136 1137 pdata->phy.advertising = pdata->phy.supported; 1138 1139 pdata->phy.address = 0; 1140 1141 pdata->phy.autoneg = AUTONEG_ENABLE; 1142 pdata->phy.speed = SPEED_UNKNOWN; 1143 pdata->phy.duplex = DUPLEX_UNKNOWN; 1144 1145 pdata->phy.link = 0; 1146 1147 pdata->phy.pause_autoneg = pdata->pause_autoneg; 1148 pdata->phy.tx_pause = pdata->tx_pause; 1149 pdata->phy.rx_pause = pdata->rx_pause; 1150 1151 /* Fix up Flow Control advertising */ 1152 pdata->phy.advertising &= ~ADVERTISED_Pause; 1153 pdata->phy.advertising &= ~ADVERTISED_Asym_Pause; 1154 1155 if (pdata->rx_pause) { 1156 pdata->phy.advertising |= ADVERTISED_Pause; 1157 pdata->phy.advertising |= ADVERTISED_Asym_Pause; 1158 } 1159 1160 if (pdata->tx_pause) 1161 pdata->phy.advertising ^= ADVERTISED_Asym_Pause; 1162 } 1163 1164 void xgbe_init_function_ptrs_phy(struct xgbe_phy_if *phy_if) 1165 { 1166 phy_if->phy_init = xgbe_phy_init; 1167 1168 phy_if->phy_reset = xgbe_phy_reset; 1169 phy_if->phy_start = xgbe_phy_start; 1170 phy_if->phy_stop = xgbe_phy_stop; 1171 1172 phy_if->phy_status = xgbe_phy_status; 1173 phy_if->phy_config_aneg = xgbe_phy_config_aneg; 1174 } 1175