1702 lines · c
1/*2 * AMD 10Gb Ethernet driver3 *4 * This file is available to you under your choice of the following two5 * licenses:6 *7 * License 1: GPLv28 *9 * Copyright (c) 2014-2016 Advanced Micro Devices, Inc.10 *11 * This file is free software; you may copy, redistribute and/or modify12 * it under the terms of the GNU General Public License as published by13 * the Free Software Foundation, either version 2 of the License, or (at14 * your option) any later version.15 *16 * This file is distributed in the hope that it will be useful, but17 * WITHOUT ANY WARRANTY; without even the implied warranty of18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU19 * General Public License for more details.20 *21 * You should have received a copy of the GNU General Public License22 * along with this program. If not, see <http://www.gnu.org/licenses/>.23 *24 * This file incorporates work covered by the following copyright and25 * permission notice:26 * The Synopsys DWC ETHER XGMAC Software Driver and documentation27 * (hereinafter "Software") is an unsupported proprietary work of Synopsys,28 * Inc. unless otherwise expressly agreed to in writing between Synopsys29 * and you.30 *31 * The Software IS NOT an item of Licensed Software or Licensed Product32 * under any End User Software License Agreement or Agreement for Licensed33 * Product with Synopsys or any supplement thereto. Permission is hereby34 * granted, free of charge, to any person obtaining a copy of this software35 * annotated with this license and the Software, to deal in the Software36 * without restriction, including without limitation the rights to use,37 * copy, modify, merge, publish, distribute, sublicense, and/or sell copies38 * of the Software, and to permit persons to whom the Software is furnished39 * to do so, subject to the following conditions:40 *41 * The above copyright notice and this permission notice shall be included42 * 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 LIMITED46 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A47 * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS48 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR49 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF50 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS51 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN52 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)53 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF54 * THE POSSIBILITY OF SUCH DAMAGE.55 *56 *57 * License 2: Modified BSD58 *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 without63 * modification, are permitted provided that the following conditions are met:64 * * Redistributions of source code must retain the above copyright65 * notice, this list of conditions and the following disclaimer.66 * * Redistributions in binary form must reproduce the above copyright67 * notice, this list of conditions and the following disclaimer in the68 * documentation and/or other materials provided with the distribution.69 * * Neither the name of Advanced Micro Devices, Inc. nor the70 * names of its contributors may be used to endorse or promote products71 * 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, THE75 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE76 * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY77 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES78 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;79 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND80 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT81 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF82 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.83 *84 * This file incorporates work covered by the following copyright and85 * permission notice:86 * The Synopsys DWC ETHER XGMAC Software Driver and documentation87 * (hereinafter "Software") is an unsupported proprietary work of Synopsys,88 * Inc. unless otherwise expressly agreed to in writing between Synopsys89 * and you.90 *91 * The Software IS NOT an item of Licensed Software or Licensed Product92 * under any End User Software License Agreement or Agreement for Licensed93 * Product with Synopsys or any supplement thereto. Permission is hereby94 * granted, free of charge, to any person obtaining a copy of this software95 * annotated with this license and the Software, to deal in the Software96 * without restriction, including without limitation the rights to use,97 * copy, modify, merge, publish, distribute, sublicense, and/or sell copies98 * of the Software, and to permit persons to whom the Software is furnished99 * to do so, subject to the following conditions:100 *101 * The above copyright notice and this permission notice shall be included102 * 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 LIMITED106 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A107 * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS108 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR109 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF110 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS111 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN112 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)113 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF114 * THE POSSIBILITY OF SUCH DAMAGE.115 */116 117#include <linux/interrupt.h>118#include <linux/module.h>119#include <linux/kmod.h>120#include <linux/mdio.h>121#include <linux/phy.h>122#include <linux/of.h>123#include <linux/bitops.h>124#include <linux/jiffies.h>125 126#include "xgbe.h"127#include "xgbe-common.h"128 129static int xgbe_phy_module_eeprom(struct xgbe_prv_data *pdata,130 struct ethtool_eeprom *eeprom, u8 *data)131{132 if (!pdata->phy_if.phy_impl.module_eeprom)133 return -ENXIO;134 135 return pdata->phy_if.phy_impl.module_eeprom(pdata, eeprom, data);136}137 138static int xgbe_phy_module_info(struct xgbe_prv_data *pdata,139 struct ethtool_modinfo *modinfo)140{141 if (!pdata->phy_if.phy_impl.module_info)142 return -ENXIO;143 144 return pdata->phy_if.phy_impl.module_info(pdata, modinfo);145}146 147static void xgbe_an37_clear_interrupts(struct xgbe_prv_data *pdata)148{149 int reg;150 151 reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_STAT);152 reg &= ~XGBE_AN_CL37_INT_MASK;153 XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_STAT, reg);154}155 156static void xgbe_an37_disable_interrupts(struct xgbe_prv_data *pdata)157{158 int reg;159 160 reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL);161 reg &= ~XGBE_AN_CL37_INT_MASK;162 XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL, reg);163 164 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_PCS_DIG_CTRL);165 reg &= ~XGBE_PCS_CL37_BP;166 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_PCS_DIG_CTRL, reg);167}168 169static void xgbe_an37_enable_interrupts(struct xgbe_prv_data *pdata)170{171 int reg;172 173 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_PCS_DIG_CTRL);174 reg |= XGBE_PCS_CL37_BP;175 XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_PCS_DIG_CTRL, reg);176 177 reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL);178 reg |= XGBE_AN_CL37_INT_MASK;179 XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL, reg);180}181 182static void xgbe_an73_clear_interrupts(struct xgbe_prv_data *pdata)183{184 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0);185}186 187static void xgbe_an73_disable_interrupts(struct xgbe_prv_data *pdata)188{189 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0);190}191 192static void xgbe_an73_enable_interrupts(struct xgbe_prv_data *pdata)193{194 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, XGBE_AN_CL73_INT_MASK);195}196 197static void xgbe_an_enable_interrupts(struct xgbe_prv_data *pdata)198{199 switch (pdata->an_mode) {200 case XGBE_AN_MODE_CL73:201 case XGBE_AN_MODE_CL73_REDRV:202 xgbe_an73_enable_interrupts(pdata);203 break;204 case XGBE_AN_MODE_CL37:205 case XGBE_AN_MODE_CL37_SGMII:206 xgbe_an37_enable_interrupts(pdata);207 break;208 default:209 break;210 }211}212 213static void xgbe_an_clear_interrupts_all(struct xgbe_prv_data *pdata)214{215 xgbe_an73_clear_interrupts(pdata);216 xgbe_an37_clear_interrupts(pdata);217}218 219static void xgbe_kr_mode(struct xgbe_prv_data *pdata)220{221 /* Set MAC to 10G speed */222 pdata->hw_if.set_speed(pdata, SPEED_10000);223 224 /* Call PHY implementation support to complete rate change */225 pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_KR);226}227 228static void xgbe_kx_2500_mode(struct xgbe_prv_data *pdata)229{230 /* Set MAC to 2.5G speed */231 pdata->hw_if.set_speed(pdata, SPEED_2500);232 233 /* Call PHY implementation support to complete rate change */234 pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_KX_2500);235}236 237static void xgbe_kx_1000_mode(struct xgbe_prv_data *pdata)238{239 /* Set MAC to 1G speed */240 pdata->hw_if.set_speed(pdata, SPEED_1000);241 242 /* Call PHY implementation support to complete rate change */243 pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_KX_1000);244}245 246static void xgbe_sfi_mode(struct xgbe_prv_data *pdata)247{248 /* If a KR re-driver is present, change to KR mode instead */249 if (pdata->kr_redrv)250 return xgbe_kr_mode(pdata);251 252 /* Set MAC to 10G speed */253 pdata->hw_if.set_speed(pdata, SPEED_10000);254 255 /* Call PHY implementation support to complete rate change */256 pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_SFI);257}258 259static void xgbe_x_mode(struct xgbe_prv_data *pdata)260{261 /* Set MAC to 1G speed */262 pdata->hw_if.set_speed(pdata, SPEED_1000);263 264 /* Call PHY implementation support to complete rate change */265 pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_X);266}267 268static void xgbe_sgmii_1000_mode(struct xgbe_prv_data *pdata)269{270 /* Set MAC to 1G speed */271 pdata->hw_if.set_speed(pdata, SPEED_1000);272 273 /* Call PHY implementation support to complete rate change */274 pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_SGMII_1000);275}276 277static void xgbe_sgmii_10_mode(struct xgbe_prv_data *pdata)278{279 /* Set MAC to 10M speed */280 pdata->hw_if.set_speed(pdata, SPEED_10);281 282 /* Call PHY implementation support to complete rate change */283 pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_SGMII_10);284}285 286static void xgbe_sgmii_100_mode(struct xgbe_prv_data *pdata)287{288 /* Set MAC to 1G speed */289 pdata->hw_if.set_speed(pdata, SPEED_1000);290 291 /* Call PHY implementation support to complete rate change */292 pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_SGMII_100);293}294 295static enum xgbe_mode xgbe_cur_mode(struct xgbe_prv_data *pdata)296{297 return pdata->phy_if.phy_impl.cur_mode(pdata);298}299 300static bool xgbe_in_kr_mode(struct xgbe_prv_data *pdata)301{302 return (xgbe_cur_mode(pdata) == XGBE_MODE_KR);303}304 305static void xgbe_change_mode(struct xgbe_prv_data *pdata,306 enum xgbe_mode mode)307{308 switch (mode) {309 case XGBE_MODE_KX_1000:310 xgbe_kx_1000_mode(pdata);311 break;312 case XGBE_MODE_KX_2500:313 xgbe_kx_2500_mode(pdata);314 break;315 case XGBE_MODE_KR:316 xgbe_kr_mode(pdata);317 break;318 case XGBE_MODE_SGMII_10:319 xgbe_sgmii_10_mode(pdata);320 break;321 case XGBE_MODE_SGMII_100:322 xgbe_sgmii_100_mode(pdata);323 break;324 case XGBE_MODE_SGMII_1000:325 xgbe_sgmii_1000_mode(pdata);326 break;327 case XGBE_MODE_X:328 xgbe_x_mode(pdata);329 break;330 case XGBE_MODE_SFI:331 xgbe_sfi_mode(pdata);332 break;333 case XGBE_MODE_UNKNOWN:334 break;335 default:336 netif_dbg(pdata, link, pdata->netdev,337 "invalid operation mode requested (%u)\n", mode);338 }339}340 341static void xgbe_switch_mode(struct xgbe_prv_data *pdata)342{343 xgbe_change_mode(pdata, pdata->phy_if.phy_impl.switch_mode(pdata));344}345 346static bool xgbe_set_mode(struct xgbe_prv_data *pdata,347 enum xgbe_mode mode)348{349 if (mode == xgbe_cur_mode(pdata))350 return false;351 352 xgbe_change_mode(pdata, mode);353 354 return true;355}356 357static bool xgbe_use_mode(struct xgbe_prv_data *pdata,358 enum xgbe_mode mode)359{360 return pdata->phy_if.phy_impl.use_mode(pdata, mode);361}362 363static void xgbe_an37_set(struct xgbe_prv_data *pdata, bool enable,364 bool restart)365{366 unsigned int reg;367 368 reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_CTRL1);369 reg &= ~MDIO_VEND2_CTRL1_AN_ENABLE;370 371 if (enable)372 reg |= MDIO_VEND2_CTRL1_AN_ENABLE;373 374 if (restart)375 reg |= MDIO_VEND2_CTRL1_AN_RESTART;376 377 XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_CTRL1, reg);378}379 380static void xgbe_an37_restart(struct xgbe_prv_data *pdata)381{382 xgbe_an37_enable_interrupts(pdata);383 xgbe_an37_set(pdata, true, true);384 385 netif_dbg(pdata, link, pdata->netdev, "CL37 AN enabled/restarted\n");386}387 388static void xgbe_an37_disable(struct xgbe_prv_data *pdata)389{390 xgbe_an37_set(pdata, false, false);391 xgbe_an37_disable_interrupts(pdata);392 393 netif_dbg(pdata, link, pdata->netdev, "CL37 AN disabled\n");394}395 396static void xgbe_an73_set(struct xgbe_prv_data *pdata, bool enable,397 bool restart)398{399 unsigned int reg;400 401 /* Disable KR training for now */402 reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL);403 reg &= ~XGBE_KR_TRAINING_ENABLE;404 XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg);405 406 /* Update AN settings */407 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_CTRL1);408 reg &= ~MDIO_AN_CTRL1_ENABLE;409 410 if (enable)411 reg |= MDIO_AN_CTRL1_ENABLE;412 413 if (restart)414 reg |= MDIO_AN_CTRL1_RESTART;415 416 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_CTRL1, reg);417}418 419static void xgbe_an73_restart(struct xgbe_prv_data *pdata)420{421 xgbe_an73_enable_interrupts(pdata);422 xgbe_an73_set(pdata, true, true);423 424 netif_dbg(pdata, link, pdata->netdev, "CL73 AN enabled/restarted\n");425}426 427static void xgbe_an73_disable(struct xgbe_prv_data *pdata)428{429 xgbe_an73_set(pdata, false, false);430 xgbe_an73_disable_interrupts(pdata);431 432 pdata->an_start = 0;433 434 netif_dbg(pdata, link, pdata->netdev, "CL73 AN disabled\n");435}436 437static void xgbe_an_restart(struct xgbe_prv_data *pdata)438{439 if (pdata->phy_if.phy_impl.an_pre)440 pdata->phy_if.phy_impl.an_pre(pdata);441 442 switch (pdata->an_mode) {443 case XGBE_AN_MODE_CL73:444 case XGBE_AN_MODE_CL73_REDRV:445 xgbe_an73_restart(pdata);446 break;447 case XGBE_AN_MODE_CL37:448 case XGBE_AN_MODE_CL37_SGMII:449 xgbe_an37_restart(pdata);450 break;451 default:452 break;453 }454}455 456static void xgbe_an_disable(struct xgbe_prv_data *pdata)457{458 if (pdata->phy_if.phy_impl.an_post)459 pdata->phy_if.phy_impl.an_post(pdata);460 461 switch (pdata->an_mode) {462 case XGBE_AN_MODE_CL73:463 case XGBE_AN_MODE_CL73_REDRV:464 xgbe_an73_disable(pdata);465 break;466 case XGBE_AN_MODE_CL37:467 case XGBE_AN_MODE_CL37_SGMII:468 xgbe_an37_disable(pdata);469 break;470 default:471 break;472 }473}474 475static void xgbe_an_disable_all(struct xgbe_prv_data *pdata)476{477 xgbe_an73_disable(pdata);478 xgbe_an37_disable(pdata);479}480 481static enum xgbe_an xgbe_an73_tx_training(struct xgbe_prv_data *pdata,482 enum xgbe_rx *state)483{484 unsigned int ad_reg, lp_reg, reg;485 486 *state = XGBE_RX_COMPLETE;487 488 /* If we're not in KR mode then we're done */489 if (!xgbe_in_kr_mode(pdata))490 return XGBE_AN_PAGE_RECEIVED;491 492 /* Enable/Disable FEC */493 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2);494 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 2);495 496 reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FECCTRL);497 reg &= ~(MDIO_PMA_10GBR_FECABLE_ABLE | MDIO_PMA_10GBR_FECABLE_ERRABLE);498 if ((ad_reg & 0xc000) && (lp_reg & 0xc000))499 reg |= pdata->fec_ability;500 501 XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FECCTRL, reg);502 503 /* Start KR training */504 if (pdata->phy_if.phy_impl.kr_training_pre)505 pdata->phy_if.phy_impl.kr_training_pre(pdata);506 507 reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL);508 reg |= XGBE_KR_TRAINING_ENABLE;509 reg |= XGBE_KR_TRAINING_START;510 XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg);511 pdata->kr_start_time = jiffies;512 513 netif_dbg(pdata, link, pdata->netdev,514 "KR training initiated\n");515 516 if (pdata->phy_if.phy_impl.kr_training_post)517 pdata->phy_if.phy_impl.kr_training_post(pdata);518 519 return XGBE_AN_PAGE_RECEIVED;520}521 522static enum xgbe_an xgbe_an73_tx_xnp(struct xgbe_prv_data *pdata,523 enum xgbe_rx *state)524{525 u16 msg;526 527 *state = XGBE_RX_XNP;528 529 msg = XGBE_XNP_MCF_NULL_MESSAGE;530 msg |= XGBE_XNP_MP_FORMATTED;531 532 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_XNP + 2, 0);533 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_XNP + 1, 0);534 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_XNP, msg);535 536 return XGBE_AN_PAGE_RECEIVED;537}538 539static enum xgbe_an xgbe_an73_rx_bpa(struct xgbe_prv_data *pdata,540 enum xgbe_rx *state)541{542 unsigned int link_support;543 unsigned int reg, ad_reg, lp_reg;544 545 /* Read Base Ability register 2 first */546 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 1);547 548 /* Check for a supported mode, otherwise restart in a different one */549 link_support = xgbe_in_kr_mode(pdata) ? 0x80 : 0x20;550 if (!(reg & link_support))551 return XGBE_AN_INCOMPAT_LINK;552 553 /* Check Extended Next Page support */554 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE);555 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA);556 557 return ((ad_reg & XGBE_XNP_NP_EXCHANGE) ||558 (lp_reg & XGBE_XNP_NP_EXCHANGE))559 ? xgbe_an73_tx_xnp(pdata, state)560 : xgbe_an73_tx_training(pdata, state);561}562 563static enum xgbe_an xgbe_an73_rx_xnp(struct xgbe_prv_data *pdata,564 enum xgbe_rx *state)565{566 unsigned int ad_reg, lp_reg;567 568 /* Check Extended Next Page support */569 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_XNP);570 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPX);571 572 return ((ad_reg & XGBE_XNP_NP_EXCHANGE) ||573 (lp_reg & XGBE_XNP_NP_EXCHANGE))574 ? xgbe_an73_tx_xnp(pdata, state)575 : xgbe_an73_tx_training(pdata, state);576}577 578static enum xgbe_an xgbe_an73_page_received(struct xgbe_prv_data *pdata)579{580 enum xgbe_rx *state;581 unsigned long an_timeout;582 enum xgbe_an ret;583 584 if (!pdata->an_start) {585 pdata->an_start = jiffies;586 } else {587 an_timeout = pdata->an_start +588 msecs_to_jiffies(XGBE_AN_MS_TIMEOUT);589 if (time_after(jiffies, an_timeout)) {590 /* Auto-negotiation timed out, reset state */591 pdata->kr_state = XGBE_RX_BPA;592 pdata->kx_state = XGBE_RX_BPA;593 594 pdata->an_start = jiffies;595 596 netif_dbg(pdata, link, pdata->netdev,597 "CL73 AN timed out, resetting state\n");598 }599 }600 601 state = xgbe_in_kr_mode(pdata) ? &pdata->kr_state602 : &pdata->kx_state;603 604 switch (*state) {605 case XGBE_RX_BPA:606 ret = xgbe_an73_rx_bpa(pdata, state);607 break;608 609 case XGBE_RX_XNP:610 ret = xgbe_an73_rx_xnp(pdata, state);611 break;612 613 default:614 ret = XGBE_AN_ERROR;615 }616 617 return ret;618}619 620static enum xgbe_an xgbe_an73_incompat_link(struct xgbe_prv_data *pdata)621{622 struct ethtool_link_ksettings *lks = &pdata->phy.lks;623 624 /* Be sure we aren't looping trying to negotiate */625 if (xgbe_in_kr_mode(pdata)) {626 pdata->kr_state = XGBE_RX_ERROR;627 628 if (!XGBE_ADV(lks, 1000baseKX_Full) &&629 !XGBE_ADV(lks, 2500baseX_Full))630 return XGBE_AN_NO_LINK;631 632 if (pdata->kx_state != XGBE_RX_BPA)633 return XGBE_AN_NO_LINK;634 } else {635 pdata->kx_state = XGBE_RX_ERROR;636 637 if (!XGBE_ADV(lks, 10000baseKR_Full))638 return XGBE_AN_NO_LINK;639 640 if (pdata->kr_state != XGBE_RX_BPA)641 return XGBE_AN_NO_LINK;642 }643 644 xgbe_an_disable(pdata);645 646 xgbe_switch_mode(pdata);647 648 pdata->an_result = XGBE_AN_READY;649 650 xgbe_an_restart(pdata);651 652 return XGBE_AN_INCOMPAT_LINK;653}654 655static void xgbe_an37_isr(struct xgbe_prv_data *pdata)656{657 unsigned int reg;658 659 /* Disable AN interrupts */660 xgbe_an37_disable_interrupts(pdata);661 662 /* Save the interrupt(s) that fired */663 reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_STAT);664 pdata->an_int = reg & XGBE_AN_CL37_INT_MASK;665 pdata->an_status = reg & ~XGBE_AN_CL37_INT_MASK;666 667 if (pdata->an_int) {668 /* Clear the interrupt(s) that fired and process them */669 reg &= ~XGBE_AN_CL37_INT_MASK;670 XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_STAT, reg);671 672 queue_work(pdata->an_workqueue, &pdata->an_irq_work);673 } else {674 /* Enable AN interrupts */675 xgbe_an37_enable_interrupts(pdata);676 677 /* Reissue interrupt if status is not clear */678 if (pdata->vdata->irq_reissue_support)679 XP_IOWRITE(pdata, XP_INT_REISSUE_EN, 1 << 3);680 }681}682 683static void xgbe_an73_isr(struct xgbe_prv_data *pdata)684{685 /* Disable AN interrupts */686 xgbe_an73_disable_interrupts(pdata);687 688 /* Save the interrupt(s) that fired */689 pdata->an_int = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_INT);690 691 if (pdata->an_int) {692 /* Clear the interrupt(s) that fired and process them */693 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, ~pdata->an_int);694 695 queue_work(pdata->an_workqueue, &pdata->an_irq_work);696 } else {697 /* Enable AN interrupts */698 xgbe_an73_enable_interrupts(pdata);699 700 /* Reissue interrupt if status is not clear */701 if (pdata->vdata->irq_reissue_support)702 XP_IOWRITE(pdata, XP_INT_REISSUE_EN, 1 << 3);703 }704}705 706static void xgbe_an_isr_bh_work(struct work_struct *work)707{708 struct xgbe_prv_data *pdata = from_work(pdata, work, an_bh_work);709 710 netif_dbg(pdata, intr, pdata->netdev, "AN interrupt received\n");711 712 switch (pdata->an_mode) {713 case XGBE_AN_MODE_CL73:714 case XGBE_AN_MODE_CL73_REDRV:715 xgbe_an73_isr(pdata);716 break;717 case XGBE_AN_MODE_CL37:718 case XGBE_AN_MODE_CL37_SGMII:719 xgbe_an37_isr(pdata);720 break;721 default:722 break;723 }724}725 726static irqreturn_t xgbe_an_isr(int irq, void *data)727{728 struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)data;729 730 if (pdata->isr_as_bh_work)731 queue_work(system_bh_wq, &pdata->an_bh_work);732 else733 xgbe_an_isr_bh_work(&pdata->an_bh_work);734 735 return IRQ_HANDLED;736}737 738static irqreturn_t xgbe_an_combined_isr(struct xgbe_prv_data *pdata)739{740 xgbe_an_isr_bh_work(&pdata->an_bh_work);741 742 return IRQ_HANDLED;743}744 745static void xgbe_an_irq_work(struct work_struct *work)746{747 struct xgbe_prv_data *pdata = container_of(work,748 struct xgbe_prv_data,749 an_irq_work);750 751 /* Avoid a race between enabling the IRQ and exiting the work by752 * waiting for the work to finish and then queueing it753 */754 flush_work(&pdata->an_work);755 queue_work(pdata->an_workqueue, &pdata->an_work);756}757 758static const char *xgbe_state_as_string(enum xgbe_an state)759{760 switch (state) {761 case XGBE_AN_READY:762 return "Ready";763 case XGBE_AN_PAGE_RECEIVED:764 return "Page-Received";765 case XGBE_AN_INCOMPAT_LINK:766 return "Incompatible-Link";767 case XGBE_AN_COMPLETE:768 return "Complete";769 case XGBE_AN_NO_LINK:770 return "No-Link";771 case XGBE_AN_ERROR:772 return "Error";773 default:774 return "Undefined";775 }776}777 778static void xgbe_an37_state_machine(struct xgbe_prv_data *pdata)779{780 enum xgbe_an cur_state = pdata->an_state;781 782 if (!pdata->an_int)783 return;784 785 if (pdata->an_int & XGBE_AN_CL37_INT_CMPLT) {786 pdata->an_state = XGBE_AN_COMPLETE;787 pdata->an_int &= ~XGBE_AN_CL37_INT_CMPLT;788 789 /* If SGMII is enabled, check the link status */790 if ((pdata->an_mode == XGBE_AN_MODE_CL37_SGMII) &&791 !(pdata->an_status & XGBE_SGMII_AN_LINK_STATUS))792 pdata->an_state = XGBE_AN_NO_LINK;793 }794 795 netif_dbg(pdata, link, pdata->netdev, "CL37 AN %s\n",796 xgbe_state_as_string(pdata->an_state));797 798 cur_state = pdata->an_state;799 800 switch (pdata->an_state) {801 case XGBE_AN_READY:802 break;803 804 case XGBE_AN_COMPLETE:805 netif_dbg(pdata, link, pdata->netdev,806 "Auto negotiation successful\n");807 break;808 809 case XGBE_AN_NO_LINK:810 break;811 812 default:813 pdata->an_state = XGBE_AN_ERROR;814 }815 816 if (pdata->an_state == XGBE_AN_ERROR) {817 netdev_err(pdata->netdev,818 "error during auto-negotiation, state=%u\n",819 cur_state);820 821 pdata->an_int = 0;822 xgbe_an37_clear_interrupts(pdata);823 }824 825 if (pdata->an_state >= XGBE_AN_COMPLETE) {826 pdata->an_result = pdata->an_state;827 pdata->an_state = XGBE_AN_READY;828 829 if (pdata->phy_if.phy_impl.an_post)830 pdata->phy_if.phy_impl.an_post(pdata);831 832 netif_dbg(pdata, link, pdata->netdev, "CL37 AN result: %s\n",833 xgbe_state_as_string(pdata->an_result));834 }835 836 xgbe_an37_enable_interrupts(pdata);837}838 839static void xgbe_an73_state_machine(struct xgbe_prv_data *pdata)840{841 enum xgbe_an cur_state = pdata->an_state;842 843 if (!pdata->an_int)844 return;845 846next_int:847 if (pdata->an_int & XGBE_AN_CL73_PG_RCV) {848 pdata->an_state = XGBE_AN_PAGE_RECEIVED;849 pdata->an_int &= ~XGBE_AN_CL73_PG_RCV;850 } else if (pdata->an_int & XGBE_AN_CL73_INC_LINK) {851 pdata->an_state = XGBE_AN_INCOMPAT_LINK;852 pdata->an_int &= ~XGBE_AN_CL73_INC_LINK;853 } else if (pdata->an_int & XGBE_AN_CL73_INT_CMPLT) {854 pdata->an_state = XGBE_AN_COMPLETE;855 pdata->an_int &= ~XGBE_AN_CL73_INT_CMPLT;856 } else {857 pdata->an_state = XGBE_AN_ERROR;858 }859 860again:861 netif_dbg(pdata, link, pdata->netdev, "CL73 AN %s\n",862 xgbe_state_as_string(pdata->an_state));863 864 cur_state = pdata->an_state;865 866 switch (pdata->an_state) {867 case XGBE_AN_READY:868 pdata->an_supported = 0;869 break;870 871 case XGBE_AN_PAGE_RECEIVED:872 pdata->an_state = xgbe_an73_page_received(pdata);873 pdata->an_supported++;874 break;875 876 case XGBE_AN_INCOMPAT_LINK:877 pdata->an_supported = 0;878 pdata->parallel_detect = 0;879 pdata->an_state = xgbe_an73_incompat_link(pdata);880 break;881 882 case XGBE_AN_COMPLETE:883 pdata->parallel_detect = pdata->an_supported ? 0 : 1;884 netif_dbg(pdata, link, pdata->netdev, "%s successful\n",885 pdata->an_supported ? "Auto negotiation"886 : "Parallel detection");887 break;888 889 case XGBE_AN_NO_LINK:890 break;891 892 default:893 pdata->an_state = XGBE_AN_ERROR;894 }895 896 if (pdata->an_state == XGBE_AN_NO_LINK) {897 pdata->an_int = 0;898 xgbe_an73_clear_interrupts(pdata);899 } else if (pdata->an_state == XGBE_AN_ERROR) {900 netdev_err(pdata->netdev,901 "error during auto-negotiation, state=%u\n",902 cur_state);903 904 pdata->an_int = 0;905 xgbe_an73_clear_interrupts(pdata);906 }907 908 if (pdata->an_state >= XGBE_AN_COMPLETE) {909 pdata->an_result = pdata->an_state;910 pdata->an_state = XGBE_AN_READY;911 pdata->kr_state = XGBE_RX_BPA;912 pdata->kx_state = XGBE_RX_BPA;913 pdata->an_start = 0;914 915 if (pdata->phy_if.phy_impl.an_post)916 pdata->phy_if.phy_impl.an_post(pdata);917 918 netif_dbg(pdata, link, pdata->netdev, "CL73 AN result: %s\n",919 xgbe_state_as_string(pdata->an_result));920 }921 922 if (cur_state != pdata->an_state)923 goto again;924 925 if (pdata->an_int)926 goto next_int;927 928 xgbe_an73_enable_interrupts(pdata);929}930 931static void xgbe_an_state_machine(struct work_struct *work)932{933 struct xgbe_prv_data *pdata = container_of(work,934 struct xgbe_prv_data,935 an_work);936 937 mutex_lock(&pdata->an_mutex);938 939 switch (pdata->an_mode) {940 case XGBE_AN_MODE_CL73:941 case XGBE_AN_MODE_CL73_REDRV:942 xgbe_an73_state_machine(pdata);943 break;944 case XGBE_AN_MODE_CL37:945 case XGBE_AN_MODE_CL37_SGMII:946 xgbe_an37_state_machine(pdata);947 break;948 default:949 break;950 }951 952 /* Reissue interrupt if status is not clear */953 if (pdata->vdata->irq_reissue_support)954 XP_IOWRITE(pdata, XP_INT_REISSUE_EN, 1 << 3);955 956 mutex_unlock(&pdata->an_mutex);957}958 959static void xgbe_an37_init(struct xgbe_prv_data *pdata)960{961 struct ethtool_link_ksettings lks;962 unsigned int reg;963 964 pdata->phy_if.phy_impl.an_advertising(pdata, &lks);965 966 /* Set up Advertisement register */967 reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_ADVERTISE);968 if (XGBE_ADV(&lks, Pause))969 reg |= 0x100;970 else971 reg &= ~0x100;972 973 if (XGBE_ADV(&lks, Asym_Pause))974 reg |= 0x80;975 else976 reg &= ~0x80;977 978 /* Full duplex, but not half */979 reg |= XGBE_AN_CL37_FD_MASK;980 reg &= ~XGBE_AN_CL37_HD_MASK;981 982 XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_ADVERTISE, reg);983 984 /* Set up the Control register */985 reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL);986 reg &= ~XGBE_AN_CL37_TX_CONFIG_MASK;987 reg &= ~XGBE_AN_CL37_PCS_MODE_MASK;988 989 switch (pdata->an_mode) {990 case XGBE_AN_MODE_CL37:991 reg |= XGBE_AN_CL37_PCS_MODE_BASEX;992 break;993 case XGBE_AN_MODE_CL37_SGMII:994 reg |= XGBE_AN_CL37_PCS_MODE_SGMII;995 break;996 default:997 break;998 }999 1000 reg |= XGBE_AN_CL37_MII_CTRL_8BIT;1001 1002 XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_CTRL, reg);1003 1004 netif_dbg(pdata, link, pdata->netdev, "CL37 AN (%s) initialized\n",1005 (pdata->an_mode == XGBE_AN_MODE_CL37) ? "BaseX" : "SGMII");1006}1007 1008static void xgbe_an73_init(struct xgbe_prv_data *pdata)1009{1010 struct ethtool_link_ksettings lks;1011 unsigned int reg;1012 1013 pdata->phy_if.phy_impl.an_advertising(pdata, &lks);1014 1015 /* Set up Advertisement register 3 first */1016 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2);1017 if (XGBE_ADV(&lks, 10000baseR_FEC))1018 reg |= 0xc000;1019 else1020 reg &= ~0xc000;1021 1022 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2, reg);1023 1024 /* Set up Advertisement register 2 next */1025 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1);1026 if (XGBE_ADV(&lks, 10000baseKR_Full))1027 reg |= 0x80;1028 else1029 reg &= ~0x80;1030 1031 if (XGBE_ADV(&lks, 1000baseKX_Full) ||1032 XGBE_ADV(&lks, 2500baseX_Full))1033 reg |= 0x20;1034 else1035 reg &= ~0x20;1036 1037 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1, reg);1038 1039 /* Set up Advertisement register 1 last */1040 reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE);1041 if (XGBE_ADV(&lks, Pause))1042 reg |= 0x400;1043 else1044 reg &= ~0x400;1045 1046 if (XGBE_ADV(&lks, Asym_Pause))1047 reg |= 0x800;1048 else1049 reg &= ~0x800;1050 1051 /* We don't intend to perform XNP */1052 reg &= ~XGBE_XNP_NP_EXCHANGE;1053 1054 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg);1055 1056 netif_dbg(pdata, link, pdata->netdev, "CL73 AN initialized\n");1057}1058 1059static void xgbe_an_init(struct xgbe_prv_data *pdata)1060{1061 /* Set up advertisement registers based on current settings */1062 pdata->an_mode = pdata->phy_if.phy_impl.an_mode(pdata);1063 switch (pdata->an_mode) {1064 case XGBE_AN_MODE_CL73:1065 case XGBE_AN_MODE_CL73_REDRV:1066 xgbe_an73_init(pdata);1067 break;1068 case XGBE_AN_MODE_CL37:1069 case XGBE_AN_MODE_CL37_SGMII:1070 xgbe_an37_init(pdata);1071 break;1072 default:1073 break;1074 }1075}1076 1077static const char *xgbe_phy_fc_string(struct xgbe_prv_data *pdata)1078{1079 if (pdata->tx_pause && pdata->rx_pause)1080 return "rx/tx";1081 else if (pdata->rx_pause)1082 return "rx";1083 else if (pdata->tx_pause)1084 return "tx";1085 else1086 return "off";1087}1088 1089static const char *xgbe_phy_speed_string(int speed)1090{1091 switch (speed) {1092 case SPEED_10:1093 return "10Mbps";1094 case SPEED_100:1095 return "100Mbps";1096 case SPEED_1000:1097 return "1Gbps";1098 case SPEED_2500:1099 return "2.5Gbps";1100 case SPEED_10000:1101 return "10Gbps";1102 case SPEED_UNKNOWN:1103 return "Unknown";1104 default:1105 return "Unsupported";1106 }1107}1108 1109static void xgbe_phy_print_status(struct xgbe_prv_data *pdata)1110{1111 if (pdata->phy.link)1112 netdev_info(pdata->netdev,1113 "Link is Up - %s/%s - flow control %s\n",1114 xgbe_phy_speed_string(pdata->phy.speed),1115 pdata->phy.duplex == DUPLEX_FULL ? "Full" : "Half",1116 xgbe_phy_fc_string(pdata));1117 else1118 netdev_info(pdata->netdev, "Link is Down\n");1119}1120 1121static void xgbe_phy_adjust_link(struct xgbe_prv_data *pdata)1122{1123 int new_state = 0;1124 1125 if (pdata->phy.link) {1126 /* Flow control support */1127 pdata->pause_autoneg = pdata->phy.pause_autoneg;1128 1129 if (pdata->tx_pause != pdata->phy.tx_pause) {1130 new_state = 1;1131 pdata->tx_pause = pdata->phy.tx_pause;1132 pdata->hw_if.config_tx_flow_control(pdata);1133 }1134 1135 if (pdata->rx_pause != pdata->phy.rx_pause) {1136 new_state = 1;1137 pdata->rx_pause = pdata->phy.rx_pause;1138 pdata->hw_if.config_rx_flow_control(pdata);1139 }1140 1141 /* Speed support */1142 if (pdata->phy_speed != pdata->phy.speed) {1143 new_state = 1;1144 pdata->phy_speed = pdata->phy.speed;1145 }1146 1147 if (pdata->phy_link != pdata->phy.link) {1148 new_state = 1;1149 pdata->phy_link = pdata->phy.link;1150 }1151 } else if (pdata->phy_link) {1152 new_state = 1;1153 pdata->phy_link = 0;1154 pdata->phy_speed = SPEED_UNKNOWN;1155 }1156 1157 if (new_state && netif_msg_link(pdata))1158 xgbe_phy_print_status(pdata);1159}1160 1161static bool xgbe_phy_valid_speed(struct xgbe_prv_data *pdata, int speed)1162{1163 return pdata->phy_if.phy_impl.valid_speed(pdata, speed);1164}1165 1166static int xgbe_phy_config_fixed(struct xgbe_prv_data *pdata)1167{1168 enum xgbe_mode mode;1169 1170 netif_dbg(pdata, link, pdata->netdev, "fixed PHY configuration\n");1171 1172 /* Disable auto-negotiation */1173 xgbe_an_disable(pdata);1174 1175 /* Set specified mode for specified speed */1176 mode = pdata->phy_if.phy_impl.get_mode(pdata, pdata->phy.speed);1177 switch (mode) {1178 case XGBE_MODE_KX_1000:1179 case XGBE_MODE_KX_2500:1180 case XGBE_MODE_KR:1181 case XGBE_MODE_SGMII_10:1182 case XGBE_MODE_SGMII_100:1183 case XGBE_MODE_SGMII_1000:1184 case XGBE_MODE_X:1185 case XGBE_MODE_SFI:1186 break;1187 case XGBE_MODE_UNKNOWN:1188 default:1189 return -EINVAL;1190 }1191 1192 /* Validate duplex mode */1193 if (pdata->phy.duplex != DUPLEX_FULL)1194 return -EINVAL;1195 1196 /* Force the mode change for SFI in Fixed PHY config.1197 * Fixed PHY configs needs PLL to be enabled while doing mode set.1198 * When the SFP module isn't connected during boot, driver assumes1199 * AN is ON and attempts autonegotiation. However, if the connected1200 * SFP comes up in Fixed PHY config, the link will not come up as1201 * PLL isn't enabled while the initial mode set command is issued.1202 * So, force the mode change for SFI in Fixed PHY configuration to1203 * fix link issues.1204 */1205 if (mode == XGBE_MODE_SFI)1206 xgbe_change_mode(pdata, mode);1207 else1208 xgbe_set_mode(pdata, mode);1209 1210 return 0;1211}1212 1213static int __xgbe_phy_config_aneg(struct xgbe_prv_data *pdata, bool set_mode)1214{1215 int ret;1216 1217 mutex_lock(&pdata->an_mutex);1218 1219 set_bit(XGBE_LINK_INIT, &pdata->dev_state);1220 pdata->link_check = jiffies;1221 1222 ret = pdata->phy_if.phy_impl.an_config(pdata);1223 if (ret)1224 goto out;1225 1226 if (pdata->phy.autoneg != AUTONEG_ENABLE) {1227 ret = xgbe_phy_config_fixed(pdata);1228 if (ret || !pdata->kr_redrv)1229 goto out;1230 1231 netif_dbg(pdata, link, pdata->netdev, "AN redriver support\n");1232 } else {1233 netif_dbg(pdata, link, pdata->netdev, "AN PHY configuration\n");1234 }1235 1236 /* Disable auto-negotiation interrupt */1237 disable_irq(pdata->an_irq);1238 1239 if (set_mode) {1240 /* Start auto-negotiation in a supported mode */1241 if (xgbe_use_mode(pdata, XGBE_MODE_KR)) {1242 xgbe_set_mode(pdata, XGBE_MODE_KR);1243 } else if (xgbe_use_mode(pdata, XGBE_MODE_KX_2500)) {1244 xgbe_set_mode(pdata, XGBE_MODE_KX_2500);1245 } else if (xgbe_use_mode(pdata, XGBE_MODE_KX_1000)) {1246 xgbe_set_mode(pdata, XGBE_MODE_KX_1000);1247 } else if (xgbe_use_mode(pdata, XGBE_MODE_SFI)) {1248 xgbe_set_mode(pdata, XGBE_MODE_SFI);1249 } else if (xgbe_use_mode(pdata, XGBE_MODE_X)) {1250 xgbe_set_mode(pdata, XGBE_MODE_X);1251 } else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_1000)) {1252 xgbe_set_mode(pdata, XGBE_MODE_SGMII_1000);1253 } else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_100)) {1254 xgbe_set_mode(pdata, XGBE_MODE_SGMII_100);1255 } else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_10)) {1256 xgbe_set_mode(pdata, XGBE_MODE_SGMII_10);1257 } else {1258 enable_irq(pdata->an_irq);1259 ret = -EINVAL;1260 goto out;1261 }1262 }1263 1264 /* Disable and stop any in progress auto-negotiation */1265 xgbe_an_disable_all(pdata);1266 1267 /* Clear any auto-negotitation interrupts */1268 xgbe_an_clear_interrupts_all(pdata);1269 1270 pdata->an_result = XGBE_AN_READY;1271 pdata->an_state = XGBE_AN_READY;1272 pdata->kr_state = XGBE_RX_BPA;1273 pdata->kx_state = XGBE_RX_BPA;1274 1275 /* Re-enable auto-negotiation interrupt */1276 enable_irq(pdata->an_irq);1277 1278 xgbe_an_init(pdata);1279 xgbe_an_restart(pdata);1280 1281out:1282 if (ret)1283 set_bit(XGBE_LINK_ERR, &pdata->dev_state);1284 else1285 clear_bit(XGBE_LINK_ERR, &pdata->dev_state);1286 1287 mutex_unlock(&pdata->an_mutex);1288 1289 return ret;1290}1291 1292static int xgbe_phy_config_aneg(struct xgbe_prv_data *pdata)1293{1294 return __xgbe_phy_config_aneg(pdata, true);1295}1296 1297static int xgbe_phy_reconfig_aneg(struct xgbe_prv_data *pdata)1298{1299 return __xgbe_phy_config_aneg(pdata, false);1300}1301 1302static bool xgbe_phy_aneg_done(struct xgbe_prv_data *pdata)1303{1304 return (pdata->an_result == XGBE_AN_COMPLETE);1305}1306 1307static void xgbe_check_link_timeout(struct xgbe_prv_data *pdata)1308{1309 unsigned long link_timeout;1310 unsigned long kr_time;1311 int wait;1312 1313 link_timeout = pdata->link_check + (XGBE_LINK_TIMEOUT * HZ);1314 if (time_after(jiffies, link_timeout)) {1315 if ((xgbe_cur_mode(pdata) == XGBE_MODE_KR) &&1316 pdata->phy.autoneg == AUTONEG_ENABLE) {1317 /* AN restart should not happen while KR training is in progress.1318 * The while loop ensures no AN restart during KR training,1319 * waits up to 500ms and AN restart is triggered only if KR1320 * training is failed.1321 */1322 wait = XGBE_KR_TRAINING_WAIT_ITER;1323 while (wait--) {1324 kr_time = pdata->kr_start_time +1325 msecs_to_jiffies(XGBE_AN_MS_TIMEOUT);1326 if (time_after(jiffies, kr_time))1327 break;1328 /* AN restart is not required, if AN result is COMPLETE */1329 if (pdata->an_result == XGBE_AN_COMPLETE)1330 return;1331 usleep_range(10000, 11000);1332 }1333 }1334 netif_dbg(pdata, link, pdata->netdev, "AN link timeout\n");1335 xgbe_phy_config_aneg(pdata);1336 }1337}1338 1339static enum xgbe_mode xgbe_phy_status_aneg(struct xgbe_prv_data *pdata)1340{1341 return pdata->phy_if.phy_impl.an_outcome(pdata);1342}1343 1344static bool xgbe_phy_status_result(struct xgbe_prv_data *pdata)1345{1346 struct ethtool_link_ksettings *lks = &pdata->phy.lks;1347 enum xgbe_mode mode;1348 1349 XGBE_ZERO_LP_ADV(lks);1350 1351 if ((pdata->phy.autoneg != AUTONEG_ENABLE) || pdata->parallel_detect)1352 mode = xgbe_cur_mode(pdata);1353 else1354 mode = xgbe_phy_status_aneg(pdata);1355 1356 switch (mode) {1357 case XGBE_MODE_SGMII_10:1358 pdata->phy.speed = SPEED_10;1359 break;1360 case XGBE_MODE_SGMII_100:1361 pdata->phy.speed = SPEED_100;1362 break;1363 case XGBE_MODE_X:1364 case XGBE_MODE_KX_1000:1365 case XGBE_MODE_SGMII_1000:1366 pdata->phy.speed = SPEED_1000;1367 break;1368 case XGBE_MODE_KX_2500:1369 pdata->phy.speed = SPEED_2500;1370 break;1371 case XGBE_MODE_KR:1372 case XGBE_MODE_SFI:1373 pdata->phy.speed = SPEED_10000;1374 break;1375 case XGBE_MODE_UNKNOWN:1376 default:1377 pdata->phy.speed = SPEED_UNKNOWN;1378 }1379 1380 pdata->phy.duplex = DUPLEX_FULL;1381 1382 if (!xgbe_set_mode(pdata, mode))1383 return false;1384 1385 if (pdata->an_again)1386 xgbe_phy_reconfig_aneg(pdata);1387 1388 return true;1389}1390 1391static void xgbe_phy_status(struct xgbe_prv_data *pdata)1392{1393 unsigned int link_aneg;1394 int an_restart;1395 1396 if (test_bit(XGBE_LINK_ERR, &pdata->dev_state)) {1397 netif_carrier_off(pdata->netdev);1398 1399 pdata->phy.link = 0;1400 goto adjust_link;1401 }1402 1403 link_aneg = (pdata->phy.autoneg == AUTONEG_ENABLE);1404 1405 pdata->phy.link = pdata->phy_if.phy_impl.link_status(pdata,1406 &an_restart);1407 if (an_restart) {1408 xgbe_phy_config_aneg(pdata);1409 goto adjust_link;1410 }1411 1412 if (pdata->phy.link) {1413 if (link_aneg && !xgbe_phy_aneg_done(pdata)) {1414 xgbe_check_link_timeout(pdata);1415 return;1416 }1417 1418 if (xgbe_phy_status_result(pdata))1419 return;1420 1421 if (test_bit(XGBE_LINK_INIT, &pdata->dev_state))1422 clear_bit(XGBE_LINK_INIT, &pdata->dev_state);1423 1424 netif_carrier_on(pdata->netdev);1425 } else {1426 if (test_bit(XGBE_LINK_INIT, &pdata->dev_state)) {1427 xgbe_check_link_timeout(pdata);1428 1429 if (link_aneg)1430 return;1431 }1432 1433 xgbe_phy_status_result(pdata);1434 1435 netif_carrier_off(pdata->netdev);1436 }1437 1438adjust_link:1439 xgbe_phy_adjust_link(pdata);1440}1441 1442static void xgbe_phy_stop(struct xgbe_prv_data *pdata)1443{1444 netif_dbg(pdata, link, pdata->netdev, "stopping PHY\n");1445 1446 if (!pdata->phy_started)1447 return;1448 1449 /* Indicate the PHY is down */1450 pdata->phy_started = 0;1451 1452 /* Disable auto-negotiation */1453 xgbe_an_disable_all(pdata);1454 1455 if (pdata->dev_irq != pdata->an_irq) {1456 devm_free_irq(pdata->dev, pdata->an_irq, pdata);1457 cancel_work_sync(&pdata->an_bh_work);1458 }1459 1460 pdata->phy_if.phy_impl.stop(pdata);1461 1462 pdata->phy.link = 0;1463 1464 xgbe_phy_adjust_link(pdata);1465}1466 1467static int xgbe_phy_start(struct xgbe_prv_data *pdata)1468{1469 struct net_device *netdev = pdata->netdev;1470 int ret;1471 1472 netif_dbg(pdata, link, pdata->netdev, "starting PHY\n");1473 1474 ret = pdata->phy_if.phy_impl.start(pdata);1475 if (ret)1476 return ret;1477 1478 /* If we have a separate AN irq, enable it */1479 if (pdata->dev_irq != pdata->an_irq) {1480 INIT_WORK(&pdata->an_bh_work, xgbe_an_isr_bh_work);1481 1482 ret = devm_request_irq(pdata->dev, pdata->an_irq,1483 xgbe_an_isr, 0, pdata->an_name,1484 pdata);1485 if (ret) {1486 netdev_err(netdev, "phy irq request failed\n");1487 goto err_stop;1488 }1489 }1490 1491 /* Set initial mode - call the mode setting routines1492 * directly to insure we are properly configured1493 */1494 if (xgbe_use_mode(pdata, XGBE_MODE_KR)) {1495 xgbe_kr_mode(pdata);1496 } else if (xgbe_use_mode(pdata, XGBE_MODE_KX_2500)) {1497 xgbe_kx_2500_mode(pdata);1498 } else if (xgbe_use_mode(pdata, XGBE_MODE_KX_1000)) {1499 xgbe_kx_1000_mode(pdata);1500 } else if (xgbe_use_mode(pdata, XGBE_MODE_SFI)) {1501 xgbe_sfi_mode(pdata);1502 } else if (xgbe_use_mode(pdata, XGBE_MODE_X)) {1503 xgbe_x_mode(pdata);1504 } else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_1000)) {1505 xgbe_sgmii_1000_mode(pdata);1506 } else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_100)) {1507 xgbe_sgmii_100_mode(pdata);1508 } else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_10)) {1509 xgbe_sgmii_10_mode(pdata);1510 } else {1511 ret = -EINVAL;1512 goto err_irq;1513 }1514 1515 /* Indicate the PHY is up and running */1516 pdata->phy_started = 1;1517 1518 xgbe_an_init(pdata);1519 xgbe_an_enable_interrupts(pdata);1520 1521 return xgbe_phy_config_aneg(pdata);1522 1523err_irq:1524 if (pdata->dev_irq != pdata->an_irq)1525 devm_free_irq(pdata->dev, pdata->an_irq, pdata);1526 1527err_stop:1528 pdata->phy_if.phy_impl.stop(pdata);1529 1530 return ret;1531}1532 1533static int xgbe_phy_reset(struct xgbe_prv_data *pdata)1534{1535 int ret;1536 1537 ret = pdata->phy_if.phy_impl.reset(pdata);1538 if (ret)1539 return ret;1540 1541 /* Disable auto-negotiation for now */1542 xgbe_an_disable_all(pdata);1543 1544 /* Clear auto-negotiation interrupts */1545 xgbe_an_clear_interrupts_all(pdata);1546 1547 return 0;1548}1549 1550static void xgbe_dump_phy_registers(struct xgbe_prv_data *pdata)1551{1552 struct device *dev = pdata->dev;1553 1554 dev_dbg(dev, "\n************* PHY Reg dump **********************\n");1555 1556 dev_dbg(dev, "PCS Control Reg (%#06x) = %#06x\n", MDIO_CTRL1,1557 XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1));1558 dev_dbg(dev, "PCS Status Reg (%#06x) = %#06x\n", MDIO_STAT1,1559 XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1));1560 dev_dbg(dev, "Phy Id (PHYS ID 1 %#06x)= %#06x\n", MDIO_DEVID1,1561 XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_DEVID1));1562 dev_dbg(dev, "Phy Id (PHYS ID 2 %#06x)= %#06x\n", MDIO_DEVID2,1563 XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_DEVID2));1564 dev_dbg(dev, "Devices in Package (%#06x)= %#06x\n", MDIO_DEVS1,1565 XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_DEVS1));1566 dev_dbg(dev, "Devices in Package (%#06x)= %#06x\n", MDIO_DEVS2,1567 XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_DEVS2));1568 1569 dev_dbg(dev, "Auto-Neg Control Reg (%#06x) = %#06x\n", MDIO_CTRL1,1570 XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_CTRL1));1571 dev_dbg(dev, "Auto-Neg Status Reg (%#06x) = %#06x\n", MDIO_STAT1,1572 XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_STAT1));1573 dev_dbg(dev, "Auto-Neg Ad Reg 1 (%#06x) = %#06x\n",1574 MDIO_AN_ADVERTISE,1575 XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE));1576 dev_dbg(dev, "Auto-Neg Ad Reg 2 (%#06x) = %#06x\n",1577 MDIO_AN_ADVERTISE + 1,1578 XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1));1579 dev_dbg(dev, "Auto-Neg Ad Reg 3 (%#06x) = %#06x\n",1580 MDIO_AN_ADVERTISE + 2,1581 XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2));1582 dev_dbg(dev, "Auto-Neg Completion Reg (%#06x) = %#06x\n",1583 MDIO_AN_COMP_STAT,1584 XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_COMP_STAT));1585 1586 dev_dbg(dev, "\n*************************************************\n");1587}1588 1589static int xgbe_phy_best_advertised_speed(struct xgbe_prv_data *pdata)1590{1591 struct ethtool_link_ksettings *lks = &pdata->phy.lks;1592 1593 if (XGBE_ADV(lks, 10000baseKR_Full))1594 return SPEED_10000;1595 else if (XGBE_ADV(lks, 10000baseT_Full))1596 return SPEED_10000;1597 else if (XGBE_ADV(lks, 2500baseX_Full))1598 return SPEED_2500;1599 else if (XGBE_ADV(lks, 2500baseT_Full))1600 return SPEED_2500;1601 else if (XGBE_ADV(lks, 1000baseKX_Full))1602 return SPEED_1000;1603 else if (XGBE_ADV(lks, 1000baseT_Full))1604 return SPEED_1000;1605 else if (XGBE_ADV(lks, 100baseT_Full))1606 return SPEED_100;1607 else if (XGBE_ADV(lks, 10baseT_Full))1608 return SPEED_10;1609 1610 return SPEED_UNKNOWN;1611}1612 1613static void xgbe_phy_exit(struct xgbe_prv_data *pdata)1614{1615 pdata->phy_if.phy_impl.exit(pdata);1616}1617 1618static int xgbe_phy_init(struct xgbe_prv_data *pdata)1619{1620 struct ethtool_link_ksettings *lks = &pdata->phy.lks;1621 int ret;1622 1623 mutex_init(&pdata->an_mutex);1624 INIT_WORK(&pdata->an_irq_work, xgbe_an_irq_work);1625 INIT_WORK(&pdata->an_work, xgbe_an_state_machine);1626 pdata->mdio_mmd = MDIO_MMD_PCS;1627 1628 /* Check for FEC support */1629 pdata->fec_ability = XMDIO_READ(pdata, MDIO_MMD_PMAPMD,1630 MDIO_PMA_10GBR_FECABLE);1631 pdata->fec_ability &= (MDIO_PMA_10GBR_FECABLE_ABLE |1632 MDIO_PMA_10GBR_FECABLE_ERRABLE);1633 1634 /* Setup the phy (including supported features) */1635 ret = pdata->phy_if.phy_impl.init(pdata);1636 if (ret)1637 return ret;1638 1639 /* Copy supported link modes to advertising link modes */1640 XGBE_LM_COPY(lks, advertising, lks, supported);1641 1642 pdata->phy.address = 0;1643 1644 if (XGBE_ADV(lks, Autoneg)) {1645 pdata->phy.autoneg = AUTONEG_ENABLE;1646 pdata->phy.speed = SPEED_UNKNOWN;1647 pdata->phy.duplex = DUPLEX_UNKNOWN;1648 } else {1649 pdata->phy.autoneg = AUTONEG_DISABLE;1650 pdata->phy.speed = xgbe_phy_best_advertised_speed(pdata);1651 pdata->phy.duplex = DUPLEX_FULL;1652 }1653 1654 pdata->phy.link = 0;1655 1656 pdata->phy.pause_autoneg = pdata->pause_autoneg;1657 pdata->phy.tx_pause = pdata->tx_pause;1658 pdata->phy.rx_pause = pdata->rx_pause;1659 1660 /* Fix up Flow Control advertising */1661 XGBE_CLR_ADV(lks, Pause);1662 XGBE_CLR_ADV(lks, Asym_Pause);1663 1664 if (pdata->rx_pause) {1665 XGBE_SET_ADV(lks, Pause);1666 XGBE_SET_ADV(lks, Asym_Pause);1667 }1668 1669 if (pdata->tx_pause) {1670 /* Equivalent to XOR of Asym_Pause */1671 if (XGBE_ADV(lks, Asym_Pause))1672 XGBE_CLR_ADV(lks, Asym_Pause);1673 else1674 XGBE_SET_ADV(lks, Asym_Pause);1675 }1676 1677 if (netif_msg_drv(pdata))1678 xgbe_dump_phy_registers(pdata);1679 1680 return 0;1681}1682 1683void xgbe_init_function_ptrs_phy(struct xgbe_phy_if *phy_if)1684{1685 phy_if->phy_init = xgbe_phy_init;1686 phy_if->phy_exit = xgbe_phy_exit;1687 1688 phy_if->phy_reset = xgbe_phy_reset;1689 phy_if->phy_start = xgbe_phy_start;1690 phy_if->phy_stop = xgbe_phy_stop;1691 1692 phy_if->phy_status = xgbe_phy_status;1693 phy_if->phy_config_aneg = xgbe_phy_config_aneg;1694 1695 phy_if->phy_valid_speed = xgbe_phy_valid_speed;1696 1697 phy_if->an_isr = xgbe_an_combined_isr;1698 1699 phy_if->module_info = xgbe_phy_module_info;1700 phy_if->module_eeprom = xgbe_phy_module_eeprom;1701}1702