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 int new_state = 0; 756 757 if (pdata->phy.link) { 758 /* Flow control support */ 759 pdata->pause_autoneg = pdata->phy.pause_autoneg; 760 761 if (pdata->tx_pause != pdata->phy.tx_pause) { 762 new_state = 1; 763 pdata->hw_if.config_tx_flow_control(pdata); 764 pdata->tx_pause = pdata->phy.tx_pause; 765 } 766 767 if (pdata->rx_pause != pdata->phy.rx_pause) { 768 new_state = 1; 769 pdata->hw_if.config_rx_flow_control(pdata); 770 pdata->rx_pause = pdata->phy.rx_pause; 771 } 772 773 /* Speed support */ 774 if (pdata->phy_speed != pdata->phy.speed) { 775 new_state = 1; 776 pdata->phy_speed = pdata->phy.speed; 777 } 778 779 if (pdata->phy_link != pdata->phy.link) { 780 new_state = 1; 781 pdata->phy_link = pdata->phy.link; 782 } 783 } else if (pdata->phy_link) { 784 new_state = 1; 785 pdata->phy_link = 0; 786 pdata->phy_speed = SPEED_UNKNOWN; 787 } 788 } 789 790 static int xgbe_phy_config_fixed(struct xgbe_prv_data *pdata) 791 { 792 793 /* Disable auto-negotiation */ 794 xgbe_disable_an(pdata); 795 796 /* Validate/Set specified speed */ 797 switch (pdata->phy.speed) { 798 case SPEED_10000: 799 xgbe_set_mode(pdata, XGBE_MODE_KR); 800 break; 801 802 case SPEED_2500: 803 case SPEED_1000: 804 xgbe_set_mode(pdata, XGBE_MODE_KX); 805 break; 806 807 default: 808 return -EINVAL; 809 } 810 811 /* Validate duplex mode */ 812 if (pdata->phy.duplex != DUPLEX_FULL) 813 return -EINVAL; 814 815 return 0; 816 } 817 818 static int __xgbe_phy_config_aneg(struct xgbe_prv_data *pdata) 819 { 820 set_bit(XGBE_LINK_INIT, &pdata->dev_state); 821 pdata->link_check = ticks; 822 823 if (pdata->phy.autoneg != AUTONEG_ENABLE) 824 return xgbe_phy_config_fixed(pdata); 825 826 /* Disable auto-negotiation interrupt */ 827 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0); 828 829 /* Clear any auto-negotitation interrupts */ 830 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0); 831 832 /* Start auto-negotiation in a supported mode */ 833 if (pdata->phy.advertising & ADVERTISED_10000baseKR_Full) { 834 xgbe_set_mode(pdata, XGBE_MODE_KR); 835 } else if ((pdata->phy.advertising & ADVERTISED_1000baseKX_Full) || 836 (pdata->phy.advertising & ADVERTISED_2500baseX_Full)) { 837 xgbe_set_mode(pdata, XGBE_MODE_KX); 838 } else { 839 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0x07); 840 return -EINVAL; 841 } 842 843 /* Disable and stop any in progress auto-negotiation */ 844 xgbe_disable_an(pdata); 845 846 /* Clear any auto-negotitation interrupts */ 847 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0); 848 849 pdata->an_result = XGBE_AN_READY; 850 pdata->an_state = XGBE_AN_READY; 851 pdata->kr_state = XGBE_RX_BPA; 852 pdata->kx_state = XGBE_RX_BPA; 853 854 /* Re-enable auto-negotiation interrupt */ 855 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0x07); 856 857 /* Set up advertisement registers based on current settings */ 858 xgbe_an_init(pdata); 859 860 /* Enable and start auto-negotiation */ 861 xgbe_restart_an(pdata); 862 863 return 0; 864 } 865 866 static int xgbe_phy_config_aneg(struct xgbe_prv_data *pdata) 867 { 868 int ret; 869 870 sx_xlock(&pdata->an_mutex); 871 872 ret = __xgbe_phy_config_aneg(pdata); 873 if (ret) 874 set_bit(XGBE_LINK_ERR, &pdata->dev_state); 875 else 876 clear_bit(XGBE_LINK_ERR, &pdata->dev_state); 877 878 sx_unlock(&pdata->an_mutex); 879 880 return ret; 881 } 882 883 static bool xgbe_phy_aneg_done(struct xgbe_prv_data *pdata) 884 { 885 return (pdata->an_result == XGBE_AN_COMPLETE); 886 } 887 888 static void xgbe_check_link_timeout(struct xgbe_prv_data *pdata) 889 { 890 unsigned long link_timeout; 891 892 link_timeout = pdata->link_check + (XGBE_LINK_TIMEOUT * hz); 893 if ((int)(ticks - link_timeout) >= 0) { 894 xgbe_phy_config_aneg(pdata); 895 } 896 } 897 898 static void xgbe_phy_status_force(struct xgbe_prv_data *pdata) 899 { 900 if (xgbe_in_kr_mode(pdata)) { 901 pdata->phy.speed = SPEED_10000; 902 } else { 903 switch (pdata->speed_set) { 904 case XGBE_SPEEDSET_1000_10000: 905 pdata->phy.speed = SPEED_1000; 906 break; 907 908 case XGBE_SPEEDSET_2500_10000: 909 pdata->phy.speed = SPEED_2500; 910 break; 911 } 912 } 913 pdata->phy.duplex = DUPLEX_FULL; 914 } 915 916 static void xgbe_phy_status_aneg(struct xgbe_prv_data *pdata) 917 { 918 unsigned int ad_reg, lp_reg; 919 920 pdata->phy.lp_advertising = 0; 921 922 if ((pdata->phy.autoneg != AUTONEG_ENABLE) || pdata->parallel_detect) 923 return xgbe_phy_status_force(pdata); 924 925 pdata->phy.lp_advertising |= ADVERTISED_Autoneg; 926 pdata->phy.lp_advertising |= ADVERTISED_Backplane; 927 928 /* Compare Advertisement and Link Partner register 1 */ 929 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE); 930 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA); 931 if (lp_reg & 0x400) 932 pdata->phy.lp_advertising |= ADVERTISED_Pause; 933 if (lp_reg & 0x800) 934 pdata->phy.lp_advertising |= ADVERTISED_Asym_Pause; 935 936 if (pdata->phy.pause_autoneg) { 937 /* Set flow control based on auto-negotiation result */ 938 pdata->phy.tx_pause = 0; 939 pdata->phy.rx_pause = 0; 940 941 if (ad_reg & lp_reg & 0x400) { 942 pdata->phy.tx_pause = 1; 943 pdata->phy.rx_pause = 1; 944 } else if (ad_reg & lp_reg & 0x800) { 945 if (ad_reg & 0x400) 946 pdata->phy.rx_pause = 1; 947 else if (lp_reg & 0x400) 948 pdata->phy.tx_pause = 1; 949 } 950 } 951 952 /* Compare Advertisement and Link Partner register 2 */ 953 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1); 954 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 1); 955 if (lp_reg & 0x80) 956 pdata->phy.lp_advertising |= ADVERTISED_10000baseKR_Full; 957 if (lp_reg & 0x20) { 958 switch (pdata->speed_set) { 959 case XGBE_SPEEDSET_1000_10000: 960 pdata->phy.lp_advertising |= ADVERTISED_1000baseKX_Full; 961 break; 962 case XGBE_SPEEDSET_2500_10000: 963 pdata->phy.lp_advertising |= ADVERTISED_2500baseX_Full; 964 break; 965 } 966 } 967 968 ad_reg &= lp_reg; 969 if (ad_reg & 0x80) { 970 pdata->phy.speed = SPEED_10000; 971 xgbe_set_mode(pdata, XGBE_MODE_KR); 972 } else if (ad_reg & 0x20) { 973 switch (pdata->speed_set) { 974 case XGBE_SPEEDSET_1000_10000: 975 pdata->phy.speed = SPEED_1000; 976 break; 977 978 case XGBE_SPEEDSET_2500_10000: 979 pdata->phy.speed = SPEED_2500; 980 break; 981 } 982 983 xgbe_set_mode(pdata, XGBE_MODE_KX); 984 } else { 985 pdata->phy.speed = SPEED_UNKNOWN; 986 } 987 988 /* Compare Advertisement and Link Partner register 3 */ 989 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2); 990 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 2); 991 } 992 993 static void xgbe_phy_status(struct xgbe_prv_data *pdata) 994 { 995 unsigned int reg, link_aneg; 996 997 if (test_bit(XGBE_LINK_ERR, &pdata->dev_state)) { 998 pdata->phy.link = 0; 999 goto adjust_link; 1000 } 1001 1002 link_aneg = (pdata->phy.autoneg == AUTONEG_ENABLE); 1003 1004 /* Get the link status. Link status is latched low, so read 1005 * once to clear and then read again to get current state 1006 */ 1007 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); 1008 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); 1009 pdata->phy.link = (reg & MDIO_STAT1_LSTATUS) ? 1 : 0; 1010 1011 if (pdata->phy.link) { 1012 if (link_aneg && !xgbe_phy_aneg_done(pdata)) { 1013 xgbe_check_link_timeout(pdata); 1014 return; 1015 } 1016 1017 xgbe_phy_status_aneg(pdata); 1018 1019 if (test_bit(XGBE_LINK_INIT, &pdata->dev_state)) 1020 clear_bit(XGBE_LINK_INIT, &pdata->dev_state); 1021 } else { 1022 if (test_bit(XGBE_LINK_INIT, &pdata->dev_state)) { 1023 xgbe_check_link_timeout(pdata); 1024 1025 if (link_aneg) 1026 return; 1027 } 1028 1029 xgbe_phy_status_aneg(pdata); 1030 } 1031 1032 adjust_link: 1033 xgbe_phy_adjust_link(pdata); 1034 } 1035 1036 static void xgbe_phy_stop(struct xgbe_prv_data *pdata) 1037 { 1038 1039 /* Disable auto-negotiation */ 1040 xgbe_disable_an(pdata); 1041 1042 /* Disable auto-negotiation interrupts */ 1043 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0); 1044 1045 bus_teardown_intr(pdata->dev, pdata->an_irq_res, pdata->an_irq_tag); 1046 1047 pdata->phy.link = 0; 1048 1049 xgbe_phy_adjust_link(pdata); 1050 } 1051 1052 static int xgbe_phy_start(struct xgbe_prv_data *pdata) 1053 { 1054 int ret; 1055 1056 ret = bus_setup_intr(pdata->dev, pdata->an_irq_res, 1057 INTR_MPSAFE | INTR_TYPE_NET, NULL, xgbe_an_isr, pdata, 1058 &pdata->an_irq_tag); 1059 if (ret) { 1060 return -ret; 1061 } 1062 1063 /* Set initial mode - call the mode setting routines 1064 * directly to insure we are properly configured 1065 */ 1066 if (xgbe_use_xgmii_mode(pdata)) { 1067 xgbe_xgmii_mode(pdata); 1068 } else if (xgbe_use_gmii_mode(pdata)) { 1069 xgbe_gmii_mode(pdata); 1070 } else if (xgbe_use_gmii_2500_mode(pdata)) { 1071 xgbe_gmii_2500_mode(pdata); 1072 } else { 1073 ret = -EINVAL; 1074 goto err_irq; 1075 } 1076 1077 /* Set up advertisement registers based on current settings */ 1078 xgbe_an_init(pdata); 1079 1080 /* Enable auto-negotiation interrupts */ 1081 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0x07); 1082 1083 return xgbe_phy_config_aneg(pdata); 1084 1085 err_irq: 1086 bus_teardown_intr(pdata->dev, pdata->an_irq_res, pdata->an_irq_tag); 1087 1088 return ret; 1089 } 1090 1091 static int xgbe_phy_reset(struct xgbe_prv_data *pdata) 1092 { 1093 unsigned int count, reg; 1094 1095 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1); 1096 reg |= MDIO_CTRL1_RESET; 1097 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg); 1098 1099 count = 50; 1100 do { 1101 DELAY(20); 1102 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1); 1103 } while ((reg & MDIO_CTRL1_RESET) && --count); 1104 1105 if (reg & MDIO_CTRL1_RESET) 1106 return -ETIMEDOUT; 1107 1108 /* Disable auto-negotiation for now */ 1109 xgbe_disable_an(pdata); 1110 1111 /* Clear auto-negotiation interrupts */ 1112 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0); 1113 1114 return 0; 1115 } 1116 1117 static void xgbe_phy_init(struct xgbe_prv_data *pdata) 1118 { 1119 sx_init(&pdata->an_mutex, "axgbe AN lock"); 1120 pdata->mdio_mmd = MDIO_MMD_PCS; 1121 1122 /* Initialize supported features */ 1123 pdata->phy.supported = SUPPORTED_Autoneg; 1124 pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; 1125 pdata->phy.supported |= SUPPORTED_Backplane; 1126 pdata->phy.supported |= SUPPORTED_10000baseKR_Full; 1127 switch (pdata->speed_set) { 1128 case XGBE_SPEEDSET_1000_10000: 1129 pdata->phy.supported |= SUPPORTED_1000baseKX_Full; 1130 break; 1131 case XGBE_SPEEDSET_2500_10000: 1132 pdata->phy.supported |= SUPPORTED_2500baseX_Full; 1133 break; 1134 } 1135 1136 pdata->fec_ability = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, 1137 MDIO_PMA_10GBR_FECABLE); 1138 pdata->fec_ability &= (MDIO_PMA_10GBR_FECABLE_ABLE | 1139 MDIO_PMA_10GBR_FECABLE_ERRABLE); 1140 if (pdata->fec_ability & MDIO_PMA_10GBR_FECABLE_ABLE) 1141 pdata->phy.supported |= SUPPORTED_10000baseR_FEC; 1142 1143 pdata->phy.advertising = pdata->phy.supported; 1144 1145 pdata->phy.address = 0; 1146 1147 pdata->phy.autoneg = AUTONEG_ENABLE; 1148 pdata->phy.speed = SPEED_UNKNOWN; 1149 pdata->phy.duplex = DUPLEX_UNKNOWN; 1150 1151 pdata->phy.link = 0; 1152 1153 pdata->phy.pause_autoneg = pdata->pause_autoneg; 1154 pdata->phy.tx_pause = pdata->tx_pause; 1155 pdata->phy.rx_pause = pdata->rx_pause; 1156 1157 /* Fix up Flow Control advertising */ 1158 pdata->phy.advertising &= ~ADVERTISED_Pause; 1159 pdata->phy.advertising &= ~ADVERTISED_Asym_Pause; 1160 1161 if (pdata->rx_pause) { 1162 pdata->phy.advertising |= ADVERTISED_Pause; 1163 pdata->phy.advertising |= ADVERTISED_Asym_Pause; 1164 } 1165 1166 if (pdata->tx_pause) 1167 pdata->phy.advertising ^= ADVERTISED_Asym_Pause; 1168 } 1169 1170 void xgbe_init_function_ptrs_phy(struct xgbe_phy_if *phy_if) 1171 { 1172 phy_if->phy_init = xgbe_phy_init; 1173 1174 phy_if->phy_reset = xgbe_phy_reset; 1175 phy_if->phy_start = xgbe_phy_start; 1176 phy_if->phy_stop = xgbe_phy_stop; 1177 1178 phy_if->phy_status = xgbe_phy_status; 1179 phy_if->phy_config_aneg = xgbe_phy_config_aneg; 1180 } 1181