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 __FBSDID("$FreeBSD$"); 116 117 #include "xgbe.h" 118 #include "xgbe-common.h" 119 120 struct xgbe_phy_data { 121 /* 1000/10000 vs 2500/10000 indicator */ 122 unsigned int speed_set; 123 124 /* SerDes UEFI configurable settings. 125 * Switching between modes/speeds requires new values for some 126 * SerDes settings. The values can be supplied as device 127 * properties in array format. The first array entry is for 128 * 1GbE, second for 2.5GbE and third for 10GbE 129 */ 130 uint32_t blwc[XGBE_SPEEDS]; 131 uint32_t cdr_rate[XGBE_SPEEDS]; 132 uint32_t pq_skew[XGBE_SPEEDS]; 133 uint32_t tx_amp[XGBE_SPEEDS]; 134 uint32_t dfe_tap_cfg[XGBE_SPEEDS]; 135 uint32_t dfe_tap_ena[XGBE_SPEEDS]; 136 }; 137 138 static void 139 xgbe_phy_kr_training_pre(struct xgbe_prv_data *pdata) 140 { 141 XSIR0_IOWRITE_BITS(pdata, SIR0_KR_RT_1, RESET, 1); 142 } 143 144 static void 145 xgbe_phy_kr_training_post(struct xgbe_prv_data *pdata) 146 { 147 XSIR0_IOWRITE_BITS(pdata, SIR0_KR_RT_1, RESET, 0); 148 } 149 150 static enum xgbe_mode 151 xgbe_phy_an_outcome(struct xgbe_prv_data *pdata) 152 { 153 struct xgbe_phy_data *phy_data = pdata->phy_data; 154 enum xgbe_mode mode; 155 unsigned int ad_reg, lp_reg; 156 157 XGBE_SET_LP_ADV(&pdata->phy, Autoneg); 158 XGBE_SET_LP_ADV(&pdata->phy, Backplane); 159 160 /* Compare Advertisement and Link Partner register 1 */ 161 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE); 162 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA); 163 if (lp_reg & 0x400) 164 XGBE_SET_LP_ADV(&pdata->phy, Pause); 165 if (lp_reg & 0x800) 166 XGBE_SET_LP_ADV(&pdata->phy, Asym_Pause); 167 168 axgbe_printf(1, "%s: pause_autoneg %d ad_reg 0x%x lp_reg 0x%x\n", 169 __func__, pdata->phy.pause_autoneg, ad_reg, lp_reg); 170 171 if (pdata->phy.pause_autoneg) { 172 /* Set flow control based on auto-negotiation result */ 173 pdata->phy.tx_pause = 0; 174 pdata->phy.rx_pause = 0; 175 176 if (ad_reg & lp_reg & 0x400) { 177 pdata->phy.tx_pause = 1; 178 pdata->phy.rx_pause = 1; 179 } else if (ad_reg & lp_reg & 0x800) { 180 if (ad_reg & 0x400) 181 pdata->phy.rx_pause = 1; 182 else if (lp_reg & 0x400) 183 pdata->phy.tx_pause = 1; 184 } 185 } 186 187 /* Compare Advertisement and Link Partner register 2 */ 188 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1); 189 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 1); 190 if (lp_reg & 0x80) 191 XGBE_SET_LP_ADV(&pdata->phy, 10000baseKR_Full); 192 if (lp_reg & 0x20) { 193 if (phy_data->speed_set == XGBE_SPEEDSET_2500_10000) 194 XGBE_SET_LP_ADV(&pdata->phy, 2500baseX_Full); 195 else 196 XGBE_SET_LP_ADV(&pdata->phy, 1000baseKX_Full); 197 } 198 199 ad_reg &= lp_reg; 200 if (ad_reg & 0x80) { 201 pdata->phy.speed = SPEED_10000; 202 mode = XGBE_MODE_KR; 203 } else if (ad_reg & 0x20) { 204 switch (pdata->speed_set) { 205 case XGBE_SPEEDSET_1000_10000: 206 pdata->phy.speed = SPEED_1000; 207 mode = XGBE_MODE_KX_1000; 208 break; 209 210 case XGBE_SPEEDSET_2500_10000: 211 pdata->phy.speed = SPEED_2500; 212 mode = XGBE_MODE_KX_2500; 213 break; 214 } 215 } else { 216 mode = XGBE_MODE_UNKNOWN; 217 pdata->phy.speed = SPEED_UNKNOWN; 218 } 219 220 /* Compare Advertisement and Link Partner register 3 */ 221 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2); 222 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 2); 223 if (lp_reg & 0xc000) 224 XGBE_SET_LP_ADV(&pdata->phy, 10000baseR_FEC); 225 226 return (mode); 227 } 228 229 static void 230 xgbe_phy_an_advertising(struct xgbe_prv_data *pdata, struct xgbe_phy *dphy) 231 { 232 XGBE_LM_COPY(dphy, advertising, &pdata->phy, advertising); 233 } 234 235 static int 236 xgbe_phy_an_config(struct xgbe_prv_data *pdata) 237 { 238 /* Nothing uniquely required for an configuration */ 239 return (0); 240 } 241 242 static enum xgbe_an_mode 243 xgbe_phy_an_mode(struct xgbe_prv_data *pdata) 244 { 245 return (XGBE_AN_MODE_CL73); 246 } 247 248 static void 249 xgbe_phy_pcs_power_cycle(struct xgbe_prv_data *pdata) 250 { 251 unsigned int reg; 252 253 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1); 254 255 reg |= MDIO_CTRL1_LPOWER; 256 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg); 257 258 DELAY(75); 259 260 reg &= ~MDIO_CTRL1_LPOWER; 261 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg); 262 } 263 264 static void 265 xgbe_phy_start_ratechange(struct xgbe_prv_data *pdata) 266 { 267 /* Assert Rx and Tx ratechange */ 268 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, RATECHANGE, 1); 269 } 270 271 static void 272 xgbe_phy_complete_ratechange(struct xgbe_prv_data *pdata) 273 { 274 unsigned int wait; 275 uint16_t status; 276 277 /* Release Rx and Tx ratechange */ 278 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, RATECHANGE, 0); 279 280 /* Wait for Rx and Tx ready */ 281 wait = XGBE_RATECHANGE_COUNT; 282 while (wait--) { 283 DELAY(50); 284 285 status = XSIR0_IOREAD(pdata, SIR0_STATUS); 286 if (XSIR_GET_BITS(status, SIR0_STATUS, RX_READY) && 287 XSIR_GET_BITS(status, SIR0_STATUS, TX_READY)) 288 goto rx_reset; 289 } 290 291 axgbe_printf(2, "SerDes rx/tx not ready (%#hx)\n", status); 292 293 rx_reset: 294 /* Perform Rx reset for the DFE changes */ 295 XRXTX_IOWRITE_BITS(pdata, RXTX_REG6, RESETB_RXD, 0); 296 XRXTX_IOWRITE_BITS(pdata, RXTX_REG6, RESETB_RXD, 1); 297 } 298 299 static void 300 xgbe_phy_kr_mode(struct xgbe_prv_data *pdata) 301 { 302 struct xgbe_phy_data *phy_data = pdata->phy_data; 303 unsigned int reg; 304 305 /* Set PCS to KR/10G speed */ 306 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL2); 307 reg &= ~MDIO_PCS_CTRL2_TYPE; 308 reg |= MDIO_PCS_CTRL2_10GBR; 309 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL2, reg); 310 311 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1); 312 reg &= ~MDIO_CTRL1_SPEEDSEL; 313 reg |= MDIO_CTRL1_SPEED10G; 314 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg); 315 316 xgbe_phy_pcs_power_cycle(pdata); 317 318 /* Set SerDes to 10G speed */ 319 xgbe_phy_start_ratechange(pdata); 320 321 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, DATARATE, XGBE_SPEED_10000_RATE); 322 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, WORDMODE, XGBE_SPEED_10000_WORD); 323 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, PLLSEL, XGBE_SPEED_10000_PLL); 324 325 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, CDR_RATE, 326 phy_data->cdr_rate[XGBE_SPEED_10000]); 327 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, TXAMP, 328 phy_data->tx_amp[XGBE_SPEED_10000]); 329 XRXTX_IOWRITE_BITS(pdata, RXTX_REG20, BLWC_ENA, 330 phy_data->blwc[XGBE_SPEED_10000]); 331 XRXTX_IOWRITE_BITS(pdata, RXTX_REG114, PQ_REG, 332 phy_data->pq_skew[XGBE_SPEED_10000]); 333 XRXTX_IOWRITE_BITS(pdata, RXTX_REG129, RXDFE_CONFIG, 334 phy_data->dfe_tap_cfg[XGBE_SPEED_10000]); 335 XRXTX_IOWRITE(pdata, RXTX_REG22, 336 phy_data->dfe_tap_ena[XGBE_SPEED_10000]); 337 338 xgbe_phy_complete_ratechange(pdata); 339 340 axgbe_printf(2, "10GbE KR mode set\n"); 341 } 342 343 static void 344 xgbe_phy_kx_2500_mode(struct xgbe_prv_data *pdata) 345 { 346 struct xgbe_phy_data *phy_data = pdata->phy_data; 347 unsigned int reg; 348 349 /* Set PCS to KX/1G speed */ 350 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL2); 351 reg &= ~MDIO_PCS_CTRL2_TYPE; 352 reg |= MDIO_PCS_CTRL2_10GBX; 353 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL2, reg); 354 355 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1); 356 reg &= ~MDIO_CTRL1_SPEEDSEL; 357 reg |= MDIO_CTRL1_SPEED1G; 358 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg); 359 360 xgbe_phy_pcs_power_cycle(pdata); 361 362 /* Set SerDes to 2.5G speed */ 363 xgbe_phy_start_ratechange(pdata); 364 365 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, DATARATE, XGBE_SPEED_2500_RATE); 366 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, WORDMODE, XGBE_SPEED_2500_WORD); 367 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, PLLSEL, XGBE_SPEED_2500_PLL); 368 369 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, CDR_RATE, 370 phy_data->cdr_rate[XGBE_SPEED_2500]); 371 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, TXAMP, 372 phy_data->tx_amp[XGBE_SPEED_2500]); 373 XRXTX_IOWRITE_BITS(pdata, RXTX_REG20, BLWC_ENA, 374 phy_data->blwc[XGBE_SPEED_2500]); 375 XRXTX_IOWRITE_BITS(pdata, RXTX_REG114, PQ_REG, 376 phy_data->pq_skew[XGBE_SPEED_2500]); 377 XRXTX_IOWRITE_BITS(pdata, RXTX_REG129, RXDFE_CONFIG, 378 phy_data->dfe_tap_cfg[XGBE_SPEED_2500]); 379 XRXTX_IOWRITE(pdata, RXTX_REG22, 380 phy_data->dfe_tap_ena[XGBE_SPEED_2500]); 381 382 xgbe_phy_complete_ratechange(pdata); 383 384 axgbe_printf(2, "2.5GbE KX mode set\n"); 385 } 386 387 static void 388 xgbe_phy_kx_1000_mode(struct xgbe_prv_data *pdata) 389 { 390 struct xgbe_phy_data *phy_data = pdata->phy_data; 391 unsigned int reg; 392 393 /* Set PCS to KX/1G speed */ 394 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL2); 395 reg &= ~MDIO_PCS_CTRL2_TYPE; 396 reg |= MDIO_PCS_CTRL2_10GBX; 397 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL2, reg); 398 399 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1); 400 reg &= ~MDIO_CTRL1_SPEEDSEL; 401 reg |= MDIO_CTRL1_SPEED1G; 402 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg); 403 404 xgbe_phy_pcs_power_cycle(pdata); 405 406 /* Set SerDes to 1G speed */ 407 xgbe_phy_start_ratechange(pdata); 408 409 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, DATARATE, XGBE_SPEED_1000_RATE); 410 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, WORDMODE, XGBE_SPEED_1000_WORD); 411 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, PLLSEL, XGBE_SPEED_1000_PLL); 412 413 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, CDR_RATE, 414 phy_data->cdr_rate[XGBE_SPEED_1000]); 415 XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, TXAMP, 416 phy_data->tx_amp[XGBE_SPEED_1000]); 417 XRXTX_IOWRITE_BITS(pdata, RXTX_REG20, BLWC_ENA, 418 phy_data->blwc[XGBE_SPEED_1000]); 419 XRXTX_IOWRITE_BITS(pdata, RXTX_REG114, PQ_REG, 420 phy_data->pq_skew[XGBE_SPEED_1000]); 421 XRXTX_IOWRITE_BITS(pdata, RXTX_REG129, RXDFE_CONFIG, 422 phy_data->dfe_tap_cfg[XGBE_SPEED_1000]); 423 XRXTX_IOWRITE(pdata, RXTX_REG22, 424 phy_data->dfe_tap_ena[XGBE_SPEED_1000]); 425 426 xgbe_phy_complete_ratechange(pdata); 427 428 axgbe_printf(2, "1GbE KX mode set\n"); 429 } 430 431 static enum xgbe_mode 432 xgbe_phy_cur_mode(struct xgbe_prv_data *pdata) 433 { 434 struct xgbe_phy_data *phy_data = pdata->phy_data; 435 enum xgbe_mode mode; 436 unsigned int reg; 437 438 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL2); 439 reg &= MDIO_PCS_CTRL2_TYPE; 440 441 if (reg == MDIO_PCS_CTRL2_10GBR) { 442 mode = XGBE_MODE_KR; 443 } else { 444 if (phy_data->speed_set == XGBE_SPEEDSET_2500_10000) 445 mode = XGBE_MODE_KX_2500; 446 else 447 mode = XGBE_MODE_KX_1000; 448 } 449 450 return (mode); 451 } 452 453 static enum xgbe_mode 454 xgbe_phy_switch_mode(struct xgbe_prv_data *pdata) 455 { 456 struct xgbe_phy_data *phy_data = pdata->phy_data; 457 enum xgbe_mode mode; 458 459 /* If we are in KR switch to KX, and vice-versa */ 460 if (xgbe_phy_cur_mode(pdata) == XGBE_MODE_KR) { 461 if (phy_data->speed_set == XGBE_SPEEDSET_2500_10000) 462 mode = XGBE_MODE_KX_2500; 463 else 464 mode = XGBE_MODE_KX_1000; 465 } else { 466 mode = XGBE_MODE_KR; 467 } 468 469 return (mode); 470 } 471 472 static enum xgbe_mode 473 xgbe_phy_get_mode(struct xgbe_prv_data *pdata, int speed) 474 { 475 struct xgbe_phy_data *phy_data = pdata->phy_data; 476 477 switch (speed) { 478 case SPEED_1000: 479 return ((phy_data->speed_set == XGBE_SPEEDSET_1000_10000) 480 ? XGBE_MODE_KX_1000 : XGBE_MODE_UNKNOWN); 481 case SPEED_2500: 482 return ((phy_data->speed_set == XGBE_SPEEDSET_2500_10000) 483 ? XGBE_MODE_KX_2500 : XGBE_MODE_UNKNOWN); 484 case SPEED_10000: 485 return (XGBE_MODE_KR); 486 default: 487 return (XGBE_MODE_UNKNOWN); 488 } 489 } 490 491 static void 492 xgbe_phy_set_mode(struct xgbe_prv_data *pdata, enum xgbe_mode mode) 493 { 494 switch (mode) { 495 case XGBE_MODE_KX_1000: 496 xgbe_phy_kx_1000_mode(pdata); 497 break; 498 case XGBE_MODE_KX_2500: 499 xgbe_phy_kx_2500_mode(pdata); 500 break; 501 case XGBE_MODE_KR: 502 xgbe_phy_kr_mode(pdata); 503 break; 504 default: 505 break; 506 } 507 } 508 509 static void 510 xgbe_phy_get_type(struct xgbe_prv_data *pdata, struct ifmediareq * ifmr) 511 { 512 513 switch (pdata->phy.speed) { 514 case SPEED_10000: 515 ifmr->ifm_active |= IFM_10G_KR; 516 break; 517 case SPEED_2500: 518 ifmr->ifm_active |= IFM_2500_KX; 519 break; 520 case SPEED_1000: 521 ifmr->ifm_active |= IFM_1000_KX; 522 break; 523 default: 524 ifmr->ifm_active |= IFM_OTHER; 525 break; 526 } 527 } 528 529 static bool 530 xgbe_phy_check_mode(struct xgbe_prv_data *pdata, enum xgbe_mode mode, bool advert) 531 { 532 533 if (pdata->phy.autoneg == AUTONEG_ENABLE) 534 return (advert); 535 else { 536 enum xgbe_mode cur_mode; 537 538 cur_mode = xgbe_phy_get_mode(pdata, pdata->phy.speed); 539 if (cur_mode == mode) 540 return (true); 541 } 542 543 return (false); 544 } 545 546 static bool 547 xgbe_phy_use_mode(struct xgbe_prv_data *pdata, enum xgbe_mode mode) 548 { 549 550 switch (mode) { 551 case XGBE_MODE_KX_1000: 552 return (xgbe_phy_check_mode(pdata, mode, 553 XGBE_ADV(&pdata->phy, 1000baseKX_Full))); 554 case XGBE_MODE_KX_2500: 555 return (xgbe_phy_check_mode(pdata, mode, 556 XGBE_ADV(&pdata->phy, 2500baseX_Full))); 557 case XGBE_MODE_KR: 558 return (xgbe_phy_check_mode(pdata, mode, 559 XGBE_ADV(&pdata->phy, 10000baseKR_Full))); 560 default: 561 return (false); 562 } 563 } 564 565 static bool 566 xgbe_phy_valid_speed(struct xgbe_prv_data *pdata, int speed) 567 { 568 struct xgbe_phy_data *phy_data = pdata->phy_data; 569 570 switch (speed) { 571 case SPEED_1000: 572 if (phy_data->speed_set != XGBE_SPEEDSET_1000_10000) 573 return (false); 574 return (true); 575 case SPEED_2500: 576 if (phy_data->speed_set != XGBE_SPEEDSET_2500_10000) 577 return (false); 578 return (true); 579 case SPEED_10000: 580 return (true); 581 default: 582 return (false); 583 } 584 } 585 586 static int 587 xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart) 588 { 589 unsigned int reg; 590 591 *an_restart = 0; 592 593 /* Link status is latched low, so read once to clear 594 * and then read again to get current state 595 */ 596 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); 597 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); 598 599 return ((reg & MDIO_STAT1_LSTATUS) ? 1 : 0); 600 } 601 602 static void 603 xgbe_phy_stop(struct xgbe_prv_data *pdata) 604 { 605 /* Nothing uniquely required for stop */ 606 } 607 608 static int 609 xgbe_phy_start(struct xgbe_prv_data *pdata) 610 { 611 /* Nothing uniquely required for start */ 612 return (0); 613 } 614 615 static int 616 xgbe_phy_reset(struct xgbe_prv_data *pdata) 617 { 618 unsigned int reg, count; 619 620 /* Perform a software reset of the PCS */ 621 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1); 622 reg |= MDIO_CTRL1_RESET; 623 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg); 624 625 count = 50; 626 do { 627 DELAY(20); 628 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1); 629 } while ((reg & MDIO_CTRL1_RESET) && --count); 630 631 if (reg & MDIO_CTRL1_RESET) 632 return (-ETIMEDOUT); 633 634 return (0); 635 } 636 637 static void 638 xgbe_phy_exit(struct xgbe_prv_data *pdata) 639 { 640 /* Nothing uniquely required for exit */ 641 } 642 643 static int 644 xgbe_phy_init(struct xgbe_prv_data *pdata) 645 { 646 struct xgbe_phy_data *phy_data; 647 648 phy_data = malloc(sizeof(*phy_data), M_AXGBE, M_WAITOK | M_ZERO); 649 650 /* Initialize supported features */ 651 XGBE_ZERO_SUP(&pdata->phy); 652 XGBE_SET_SUP(&pdata->phy, Autoneg); 653 XGBE_SET_SUP(&pdata->phy, Pause); 654 XGBE_SET_SUP(&pdata->phy, Asym_Pause); 655 XGBE_SET_SUP(&pdata->phy, Backplane); 656 XGBE_SET_SUP(&pdata->phy, 10000baseKR_Full); 657 switch (phy_data->speed_set) { 658 case XGBE_SPEEDSET_1000_10000: 659 XGBE_SET_SUP(&pdata->phy, 1000baseKX_Full); 660 break; 661 case XGBE_SPEEDSET_2500_10000: 662 XGBE_SET_SUP(&pdata->phy, 2500baseX_Full); 663 break; 664 } 665 666 if (pdata->fec_ability & MDIO_PMA_10GBR_FECABLE_ABLE) 667 XGBE_SET_SUP(&pdata->phy, 10000baseR_FEC); 668 669 pdata->phy_data = phy_data; 670 671 return (0); 672 } 673 674 void 675 xgbe_init_function_ptrs_phy_v1(struct xgbe_phy_if *phy_if) 676 { 677 struct xgbe_phy_impl_if *phy_impl = &phy_if->phy_impl; 678 679 phy_impl->init = xgbe_phy_init; 680 phy_impl->exit = xgbe_phy_exit; 681 682 phy_impl->reset = xgbe_phy_reset; 683 phy_impl->start = xgbe_phy_start; 684 phy_impl->stop = xgbe_phy_stop; 685 686 phy_impl->link_status = xgbe_phy_link_status; 687 688 phy_impl->valid_speed = xgbe_phy_valid_speed; 689 690 phy_impl->use_mode = xgbe_phy_use_mode; 691 phy_impl->set_mode = xgbe_phy_set_mode; 692 phy_impl->get_mode = xgbe_phy_get_mode; 693 phy_impl->switch_mode = xgbe_phy_switch_mode; 694 phy_impl->cur_mode = xgbe_phy_cur_mode; 695 phy_impl->get_type = xgbe_phy_get_type; 696 697 phy_impl->an_mode = xgbe_phy_an_mode; 698 699 phy_impl->an_config = xgbe_phy_an_config; 700 701 phy_impl->an_advertising = xgbe_phy_an_advertising; 702 703 phy_impl->an_outcome = xgbe_phy_an_outcome; 704 705 phy_impl->kr_training_pre = xgbe_phy_kr_training_pre; 706 phy_impl->kr_training_post = xgbe_phy_kr_training_post; 707 } 708