1 /* 2 * AMD 10Gb Ethernet driver 3 * 4 * Copyright (c) 2020 Advanced Micro Devices, Inc. 5 * 6 * This file is available to you under your choice of the following two 7 * licenses: 8 * 9 * License 1: GPLv2 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 * Redistribution and use in source and binary forms, with or without 60 * modification, are permitted provided that the following conditions are met: 61 * * Redistributions of source code must retain the above copyright 62 * notice, this list of conditions and the following disclaimer. 63 * * Redistributions in binary form must reproduce the above copyright 64 * notice, this list of conditions and the following disclaimer in the 65 * documentation and/or other materials provided with the distribution. 66 * * Neither the name of Advanced Micro Devices, Inc. nor the 67 * names of its contributors may be used to endorse or promote products 68 * derived from this software without specific prior written permission. 69 * 70 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 71 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 72 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 73 * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY 74 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 75 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 76 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 77 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 78 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 79 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 80 * 81 * This file incorporates work covered by the following copyright and 82 * permission notice: 83 * The Synopsys DWC ETHER XGMAC Software Driver and documentation 84 * (hereinafter "Software") is an unsupported proprietary work of Synopsys, 85 * Inc. unless otherwise expressly agreed to in writing between Synopsys 86 * and you. 87 * 88 * The Software IS NOT an item of Licensed Software or Licensed Product 89 * under any End User Software License Agreement or Agreement for Licensed 90 * Product with Synopsys or any supplement thereto. Permission is hereby 91 * granted, free of charge, to any person obtaining a copy of this software 92 * annotated with this license and the Software, to deal in the Software 93 * without restriction, including without limitation the rights to use, 94 * copy, modify, merge, publish, distribute, sublicense, and/or sell copies 95 * of the Software, and to permit persons to whom the Software is furnished 96 * to do so, subject to the following conditions: 97 * 98 * The above copyright notice and this permission notice shall be included 99 * in all copies or substantial portions of the Software. 100 * 101 * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" 102 * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 103 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 104 * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS 105 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 106 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 107 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 108 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 109 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 110 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 111 * THE POSSIBILITY OF SUCH DAMAGE. 112 */ 113 114 #include <sys/cdefs.h> 115 #include "xgbe.h" 116 #include "xgbe-common.h" 117 118 struct xgbe_phy_data { 119 /* 1000/10000 vs 2500/10000 indicator */ 120 unsigned int speed_set; 121 122 /* SerDes UEFI configurable settings. 123 * Switching between modes/speeds requires new values for some 124 * SerDes settings. The values can be supplied as device 125 * properties in array format. The first array entry is for 126 * 1GbE, second for 2.5GbE and third for 10GbE 127 */ 128 uint32_t blwc[XGBE_SPEEDS]; 129 uint32_t cdr_rate[XGBE_SPEEDS]; 130 uint32_t pq_skew[XGBE_SPEEDS]; 131 uint32_t tx_amp[XGBE_SPEEDS]; 132 uint32_t dfe_tap_cfg[XGBE_SPEEDS]; 133 uint32_t dfe_tap_ena[XGBE_SPEEDS]; 134 }; 135 136 static void 137 xgbe_phy_kr_training_pre(struct xgbe_prv_data *pdata) 138 { 139 XSIR0_IOWRITE_BITS(pdata, SIR0_KR_RT_1, RESET, 1); 140 } 141 142 static void 143 xgbe_phy_kr_training_post(struct xgbe_prv_data *pdata) 144 { 145 XSIR0_IOWRITE_BITS(pdata, SIR0_KR_RT_1, RESET, 0); 146 } 147 148 static enum xgbe_mode 149 xgbe_phy_an_outcome(struct xgbe_prv_data *pdata) 150 { 151 struct xgbe_phy_data *phy_data = pdata->phy_data; 152 enum xgbe_mode mode; 153 unsigned int ad_reg, lp_reg; 154 155 XGBE_SET_LP_ADV(&pdata->phy, Autoneg); 156 XGBE_SET_LP_ADV(&pdata->phy, Backplane); 157 158 /* Compare Advertisement and Link Partner register 1 */ 159 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE); 160 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA); 161 if (lp_reg & 0x400) 162 XGBE_SET_LP_ADV(&pdata->phy, Pause); 163 if (lp_reg & 0x800) 164 XGBE_SET_LP_ADV(&pdata->phy, Asym_Pause); 165 166 axgbe_printf(1, "%s: pause_autoneg %d ad_reg 0x%x lp_reg 0x%x\n", 167 __func__, pdata->phy.pause_autoneg, ad_reg, lp_reg); 168 169 if (pdata->phy.pause_autoneg) { 170 /* Set flow control based on auto-negotiation result */ 171 pdata->phy.tx_pause = 0; 172 pdata->phy.rx_pause = 0; 173 174 if (ad_reg & lp_reg & 0x400) { 175 pdata->phy.tx_pause = 1; 176 pdata->phy.rx_pause = 1; 177 } else if (ad_reg & lp_reg & 0x800) { 178 if (ad_reg & 0x400) 179 pdata->phy.rx_pause = 1; 180 else if (lp_reg & 0x400) 181 pdata->phy.tx_pause = 1; 182 } 183 } 184 185 /* Compare Advertisement and Link Partner register 2 */ 186 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1); 187 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 1); 188 if (lp_reg & 0x80) 189 XGBE_SET_LP_ADV(&pdata->phy, 10000baseKR_Full); 190 if (lp_reg & 0x20) { 191 if (phy_data->speed_set == XGBE_SPEEDSET_2500_10000) 192 XGBE_SET_LP_ADV(&pdata->phy, 2500baseX_Full); 193 else 194 XGBE_SET_LP_ADV(&pdata->phy, 1000baseKX_Full); 195 } 196 197 ad_reg &= lp_reg; 198 if (ad_reg & 0x80) { 199 pdata->phy.speed = SPEED_10000; 200 mode = XGBE_MODE_KR; 201 } else if (ad_reg & 0x20) { 202 switch (pdata->speed_set) { 203 case XGBE_SPEEDSET_1000_10000: 204 pdata->phy.speed = SPEED_1000; 205 mode = XGBE_MODE_KX_1000; 206 break; 207 208 case XGBE_SPEEDSET_2500_10000: 209 pdata->phy.speed = SPEED_2500; 210 mode = XGBE_MODE_KX_2500; 211 break; 212 } 213 } else { 214 mode = XGBE_MODE_UNKNOWN; 215 pdata->phy.speed = SPEED_UNKNOWN; 216 } 217 218 /* Compare Advertisement and Link Partner register 3 */ 219 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2); 220 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 2); 221 if (lp_reg & 0xc000) 222 XGBE_SET_LP_ADV(&pdata->phy, 10000baseR_FEC); 223 224 return (mode); 225 } 226 227 static void 228 xgbe_phy_an_advertising(struct xgbe_prv_data *pdata, struct xgbe_phy *dphy) 229 { 230 XGBE_LM_COPY(dphy, advertising, &pdata->phy, advertising); 231 } 232 233 static int 234 xgbe_phy_an_config(struct xgbe_prv_data *pdata) 235 { 236 /* Nothing uniquely required for an configuration */ 237 return (0); 238 } 239 240 static enum xgbe_an_mode 241 xgbe_phy_an_mode(struct xgbe_prv_data *pdata) 242 { 243 return (XGBE_AN_MODE_CL73); 244 } 245 246 static void 247 xgbe_phy_pcs_power_cycle(struct xgbe_prv_data *pdata) 248 { 249 unsigned int reg; 250 251 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1); 252 253 reg |= MDIO_CTRL1_LPOWER; 254 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg); 255 256 DELAY(75); 257 258 reg &= ~MDIO_CTRL1_LPOWER; 259 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg); 260 } 261 262 static void 263 xgbe_phy_start_ratechange(struct xgbe_prv_data *pdata) 264 { 265 /* Assert Rx and Tx ratechange */ 266 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, RATECHANGE, 1); 267 } 268 269 static void 270 xgbe_phy_complete_ratechange(struct xgbe_prv_data *pdata) 271 { 272 unsigned int wait; 273 uint16_t status; 274 275 /* Release Rx and Tx ratechange */ 276 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, RATECHANGE, 0); 277 278 /* Wait for Rx and Tx ready */ 279 wait = XGBE_RATECHANGE_COUNT; 280 while (wait--) { 281 DELAY(50); 282 283 status = XSIR0_IOREAD(pdata, SIR0_STATUS); 284 if (XSIR_GET_BITS(status, SIR0_STATUS, RX_READY) && 285 XSIR_GET_BITS(status, SIR0_STATUS, TX_READY)) 286 goto rx_reset; 287 } 288 289 axgbe_printf(2, "SerDes rx/tx not ready (%#hx)\n", status); 290 291 rx_reset: 292 /* Perform Rx reset for the DFE changes */ 293 XRXTX_IOWRITE_BITS(pdata, RXTX_REG6, RESETB_RXD, 0); 294 XRXTX_IOWRITE_BITS(pdata, RXTX_REG6, RESETB_RXD, 1); 295 } 296 297 static void 298 xgbe_phy_kr_mode(struct xgbe_prv_data *pdata) 299 { 300 struct xgbe_phy_data *phy_data = pdata->phy_data; 301 unsigned int reg; 302 303 /* Set PCS to KR/10G speed */ 304 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL2); 305 reg &= ~MDIO_PCS_CTRL2_TYPE; 306 reg |= MDIO_PCS_CTRL2_10GBR; 307 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL2, reg); 308 309 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1); 310 reg &= ~MDIO_CTRL1_SPEEDSEL; 311 reg |= MDIO_CTRL1_SPEED10G; 312 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg); 313 314 xgbe_phy_pcs_power_cycle(pdata); 315 316 /* Set SerDes to 10G speed */ 317 xgbe_phy_start_ratechange(pdata); 318 319 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, DATARATE, XGBE_SPEED_10000_RATE); 320 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, WORDMODE, XGBE_SPEED_10000_WORD); 321 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, PLLSEL, XGBE_SPEED_10000_PLL); 322 323 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, CDR_RATE, 324 phy_data->cdr_rate[XGBE_SPEED_10000]); 325 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, TXAMP, 326 phy_data->tx_amp[XGBE_SPEED_10000]); 327 XRXTX_IOWRITE_BITS(pdata, RXTX_REG20, BLWC_ENA, 328 phy_data->blwc[XGBE_SPEED_10000]); 329 XRXTX_IOWRITE_BITS(pdata, RXTX_REG114, PQ_REG, 330 phy_data->pq_skew[XGBE_SPEED_10000]); 331 XRXTX_IOWRITE_BITS(pdata, RXTX_REG129, RXDFE_CONFIG, 332 phy_data->dfe_tap_cfg[XGBE_SPEED_10000]); 333 XRXTX_IOWRITE(pdata, RXTX_REG22, 334 phy_data->dfe_tap_ena[XGBE_SPEED_10000]); 335 336 xgbe_phy_complete_ratechange(pdata); 337 338 axgbe_printf(2, "10GbE KR mode set\n"); 339 } 340 341 static void 342 xgbe_phy_kx_2500_mode(struct xgbe_prv_data *pdata) 343 { 344 struct xgbe_phy_data *phy_data = pdata->phy_data; 345 unsigned int reg; 346 347 /* Set PCS to KX/1G speed */ 348 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL2); 349 reg &= ~MDIO_PCS_CTRL2_TYPE; 350 reg |= MDIO_PCS_CTRL2_10GBX; 351 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL2, reg); 352 353 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1); 354 reg &= ~MDIO_CTRL1_SPEEDSEL; 355 reg |= MDIO_CTRL1_SPEED1G; 356 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg); 357 358 xgbe_phy_pcs_power_cycle(pdata); 359 360 /* Set SerDes to 2.5G speed */ 361 xgbe_phy_start_ratechange(pdata); 362 363 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, DATARATE, XGBE_SPEED_2500_RATE); 364 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, WORDMODE, XGBE_SPEED_2500_WORD); 365 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, PLLSEL, XGBE_SPEED_2500_PLL); 366 367 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, CDR_RATE, 368 phy_data->cdr_rate[XGBE_SPEED_2500]); 369 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, TXAMP, 370 phy_data->tx_amp[XGBE_SPEED_2500]); 371 XRXTX_IOWRITE_BITS(pdata, RXTX_REG20, BLWC_ENA, 372 phy_data->blwc[XGBE_SPEED_2500]); 373 XRXTX_IOWRITE_BITS(pdata, RXTX_REG114, PQ_REG, 374 phy_data->pq_skew[XGBE_SPEED_2500]); 375 XRXTX_IOWRITE_BITS(pdata, RXTX_REG129, RXDFE_CONFIG, 376 phy_data->dfe_tap_cfg[XGBE_SPEED_2500]); 377 XRXTX_IOWRITE(pdata, RXTX_REG22, 378 phy_data->dfe_tap_ena[XGBE_SPEED_2500]); 379 380 xgbe_phy_complete_ratechange(pdata); 381 382 axgbe_printf(2, "2.5GbE KX mode set\n"); 383 } 384 385 static void 386 xgbe_phy_kx_1000_mode(struct xgbe_prv_data *pdata) 387 { 388 struct xgbe_phy_data *phy_data = pdata->phy_data; 389 unsigned int reg; 390 391 /* Set PCS to KX/1G speed */ 392 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL2); 393 reg &= ~MDIO_PCS_CTRL2_TYPE; 394 reg |= MDIO_PCS_CTRL2_10GBX; 395 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL2, reg); 396 397 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1); 398 reg &= ~MDIO_CTRL1_SPEEDSEL; 399 reg |= MDIO_CTRL1_SPEED1G; 400 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg); 401 402 xgbe_phy_pcs_power_cycle(pdata); 403 404 /* Set SerDes to 1G speed */ 405 xgbe_phy_start_ratechange(pdata); 406 407 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, DATARATE, XGBE_SPEED_1000_RATE); 408 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, WORDMODE, XGBE_SPEED_1000_WORD); 409 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, PLLSEL, XGBE_SPEED_1000_PLL); 410 411 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, CDR_RATE, 412 phy_data->cdr_rate[XGBE_SPEED_1000]); 413 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, TXAMP, 414 phy_data->tx_amp[XGBE_SPEED_1000]); 415 XRXTX_IOWRITE_BITS(pdata, RXTX_REG20, BLWC_ENA, 416 phy_data->blwc[XGBE_SPEED_1000]); 417 XRXTX_IOWRITE_BITS(pdata, RXTX_REG114, PQ_REG, 418 phy_data->pq_skew[XGBE_SPEED_1000]); 419 XRXTX_IOWRITE_BITS(pdata, RXTX_REG129, RXDFE_CONFIG, 420 phy_data->dfe_tap_cfg[XGBE_SPEED_1000]); 421 XRXTX_IOWRITE(pdata, RXTX_REG22, 422 phy_data->dfe_tap_ena[XGBE_SPEED_1000]); 423 424 xgbe_phy_complete_ratechange(pdata); 425 426 axgbe_printf(2, "1GbE KX mode set\n"); 427 } 428 429 static enum xgbe_mode 430 xgbe_phy_cur_mode(struct xgbe_prv_data *pdata) 431 { 432 struct xgbe_phy_data *phy_data = pdata->phy_data; 433 enum xgbe_mode mode; 434 unsigned int reg; 435 436 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL2); 437 reg &= MDIO_PCS_CTRL2_TYPE; 438 439 if (reg == MDIO_PCS_CTRL2_10GBR) { 440 mode = XGBE_MODE_KR; 441 } else { 442 if (phy_data->speed_set == XGBE_SPEEDSET_2500_10000) 443 mode = XGBE_MODE_KX_2500; 444 else 445 mode = XGBE_MODE_KX_1000; 446 } 447 448 return (mode); 449 } 450 451 static enum xgbe_mode 452 xgbe_phy_switch_mode(struct xgbe_prv_data *pdata) 453 { 454 struct xgbe_phy_data *phy_data = pdata->phy_data; 455 enum xgbe_mode mode; 456 457 /* If we are in KR switch to KX, and vice-versa */ 458 if (xgbe_phy_cur_mode(pdata) == XGBE_MODE_KR) { 459 if (phy_data->speed_set == XGBE_SPEEDSET_2500_10000) 460 mode = XGBE_MODE_KX_2500; 461 else 462 mode = XGBE_MODE_KX_1000; 463 } else { 464 mode = XGBE_MODE_KR; 465 } 466 467 return (mode); 468 } 469 470 static enum xgbe_mode 471 xgbe_phy_get_mode(struct xgbe_prv_data *pdata, int speed) 472 { 473 struct xgbe_phy_data *phy_data = pdata->phy_data; 474 475 switch (speed) { 476 case SPEED_1000: 477 return ((phy_data->speed_set == XGBE_SPEEDSET_1000_10000) 478 ? XGBE_MODE_KX_1000 : XGBE_MODE_UNKNOWN); 479 case SPEED_2500: 480 return ((phy_data->speed_set == XGBE_SPEEDSET_2500_10000) 481 ? XGBE_MODE_KX_2500 : XGBE_MODE_UNKNOWN); 482 case SPEED_10000: 483 return (XGBE_MODE_KR); 484 default: 485 return (XGBE_MODE_UNKNOWN); 486 } 487 } 488 489 static void 490 xgbe_phy_set_mode(struct xgbe_prv_data *pdata, enum xgbe_mode mode) 491 { 492 switch (mode) { 493 case XGBE_MODE_KX_1000: 494 xgbe_phy_kx_1000_mode(pdata); 495 break; 496 case XGBE_MODE_KX_2500: 497 xgbe_phy_kx_2500_mode(pdata); 498 break; 499 case XGBE_MODE_KR: 500 xgbe_phy_kr_mode(pdata); 501 break; 502 default: 503 break; 504 } 505 } 506 507 static void 508 xgbe_phy_get_type(struct xgbe_prv_data *pdata, struct ifmediareq * ifmr) 509 { 510 511 switch (pdata->phy.speed) { 512 case SPEED_10000: 513 ifmr->ifm_active |= IFM_10G_KR; 514 break; 515 case SPEED_2500: 516 ifmr->ifm_active |= IFM_2500_KX; 517 break; 518 case SPEED_1000: 519 ifmr->ifm_active |= IFM_1000_KX; 520 break; 521 default: 522 ifmr->ifm_active |= IFM_OTHER; 523 break; 524 } 525 } 526 527 static bool 528 xgbe_phy_check_mode(struct xgbe_prv_data *pdata, enum xgbe_mode mode, bool advert) 529 { 530 531 if (pdata->phy.autoneg == AUTONEG_ENABLE) 532 return (advert); 533 else { 534 enum xgbe_mode cur_mode; 535 536 cur_mode = xgbe_phy_get_mode(pdata, pdata->phy.speed); 537 if (cur_mode == mode) 538 return (true); 539 } 540 541 return (false); 542 } 543 544 static bool 545 xgbe_phy_use_mode(struct xgbe_prv_data *pdata, enum xgbe_mode mode) 546 { 547 548 switch (mode) { 549 case XGBE_MODE_KX_1000: 550 return (xgbe_phy_check_mode(pdata, mode, 551 XGBE_ADV(&pdata->phy, 1000baseKX_Full))); 552 case XGBE_MODE_KX_2500: 553 return (xgbe_phy_check_mode(pdata, mode, 554 XGBE_ADV(&pdata->phy, 2500baseX_Full))); 555 case XGBE_MODE_KR: 556 return (xgbe_phy_check_mode(pdata, mode, 557 XGBE_ADV(&pdata->phy, 10000baseKR_Full))); 558 default: 559 return (false); 560 } 561 } 562 563 static bool 564 xgbe_phy_valid_speed(struct xgbe_prv_data *pdata, int speed) 565 { 566 struct xgbe_phy_data *phy_data = pdata->phy_data; 567 568 switch (speed) { 569 case SPEED_1000: 570 if (phy_data->speed_set != XGBE_SPEEDSET_1000_10000) 571 return (false); 572 return (true); 573 case SPEED_2500: 574 if (phy_data->speed_set != XGBE_SPEEDSET_2500_10000) 575 return (false); 576 return (true); 577 case SPEED_10000: 578 return (true); 579 default: 580 return (false); 581 } 582 } 583 584 static int 585 xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart) 586 { 587 unsigned int reg; 588 589 *an_restart = 0; 590 591 /* Link status is latched low, so read once to clear 592 * and then read again to get current state 593 */ 594 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); 595 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); 596 597 return ((reg & MDIO_STAT1_LSTATUS) ? 1 : 0); 598 } 599 600 static void 601 xgbe_phy_stop(struct xgbe_prv_data *pdata) 602 { 603 /* Nothing uniquely required for stop */ 604 } 605 606 static int 607 xgbe_phy_start(struct xgbe_prv_data *pdata) 608 { 609 /* Nothing uniquely required for start */ 610 return (0); 611 } 612 613 static int 614 xgbe_phy_reset(struct xgbe_prv_data *pdata) 615 { 616 unsigned int reg, count; 617 618 /* Perform a software reset of the PCS */ 619 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1); 620 reg |= MDIO_CTRL1_RESET; 621 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg); 622 623 count = 50; 624 do { 625 DELAY(20); 626 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1); 627 } while ((reg & MDIO_CTRL1_RESET) && --count); 628 629 if (reg & MDIO_CTRL1_RESET) 630 return (-ETIMEDOUT); 631 632 return (0); 633 } 634 635 static void 636 xgbe_phy_exit(struct xgbe_prv_data *pdata) 637 { 638 /* Nothing uniquely required for exit */ 639 } 640 641 static int 642 xgbe_phy_init(struct xgbe_prv_data *pdata) 643 { 644 struct xgbe_phy_data *phy_data; 645 646 phy_data = malloc(sizeof(*phy_data), M_AXGBE, M_WAITOK | M_ZERO); 647 648 /* Initialize supported features */ 649 XGBE_ZERO_SUP(&pdata->phy); 650 XGBE_SET_SUP(&pdata->phy, Autoneg); 651 XGBE_SET_SUP(&pdata->phy, Pause); 652 XGBE_SET_SUP(&pdata->phy, Asym_Pause); 653 XGBE_SET_SUP(&pdata->phy, Backplane); 654 XGBE_SET_SUP(&pdata->phy, 10000baseKR_Full); 655 switch (phy_data->speed_set) { 656 case XGBE_SPEEDSET_1000_10000: 657 XGBE_SET_SUP(&pdata->phy, 1000baseKX_Full); 658 break; 659 case XGBE_SPEEDSET_2500_10000: 660 XGBE_SET_SUP(&pdata->phy, 2500baseX_Full); 661 break; 662 } 663 664 if (pdata->fec_ability & MDIO_PMA_10GBR_FECABLE_ABLE) 665 XGBE_SET_SUP(&pdata->phy, 10000baseR_FEC); 666 667 pdata->phy_data = phy_data; 668 669 return (0); 670 } 671 672 void 673 xgbe_init_function_ptrs_phy_v1(struct xgbe_phy_if *phy_if) 674 { 675 struct xgbe_phy_impl_if *phy_impl = &phy_if->phy_impl; 676 677 phy_impl->init = xgbe_phy_init; 678 phy_impl->exit = xgbe_phy_exit; 679 680 phy_impl->reset = xgbe_phy_reset; 681 phy_impl->start = xgbe_phy_start; 682 phy_impl->stop = xgbe_phy_stop; 683 684 phy_impl->link_status = xgbe_phy_link_status; 685 686 phy_impl->valid_speed = xgbe_phy_valid_speed; 687 688 phy_impl->use_mode = xgbe_phy_use_mode; 689 phy_impl->set_mode = xgbe_phy_set_mode; 690 phy_impl->get_mode = xgbe_phy_get_mode; 691 phy_impl->switch_mode = xgbe_phy_switch_mode; 692 phy_impl->cur_mode = xgbe_phy_cur_mode; 693 phy_impl->get_type = xgbe_phy_get_type; 694 695 phy_impl->an_mode = xgbe_phy_an_mode; 696 697 phy_impl->an_config = xgbe_phy_an_config; 698 699 phy_impl->an_advertising = xgbe_phy_an_advertising; 700 701 phy_impl->an_outcome = xgbe_phy_an_outcome; 702 703 phy_impl->kr_training_pre = xgbe_phy_kr_training_pre; 704 phy_impl->kr_training_post = xgbe_phy_kr_training_post; 705 } 706