linux/drivers/net/ethernet/amd/xgbe/xgbe-phy-v1.c
<<
>>
Prefs
   1/*
   2 * AMD 10Gb Ethernet driver
   3 *
   4 * This file is available to you under your choice of the following two
   5 * licenses:
   6 *
   7 * License 1: GPLv2
   8 *
   9 * Copyright (c) 2016 Advanced Micro Devices, Inc.
  10 *
  11 * This file is free software; you may copy, redistribute and/or modify
  12 * it under the terms of the GNU General Public License as published by
  13 * the Free Software Foundation, either version 2 of the License, or (at
  14 * your option) any later version.
  15 *
  16 * This file is distributed in the hope that it will be useful, but
  17 * WITHOUT ANY WARRANTY; without even the implied warranty of
  18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  19 * General Public License for more details.
  20 *
  21 * You should have received a copy of the GNU General Public License
  22 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  23 *
  24 * This file incorporates work covered by the following copyright and
  25 * permission notice:
  26 *     The Synopsys DWC ETHER XGMAC Software Driver and documentation
  27 *     (hereinafter "Software") is an unsupported proprietary work of Synopsys,
  28 *     Inc. unless otherwise expressly agreed to in writing between Synopsys
  29 *     and you.
  30 *
  31 *     The Software IS NOT an item of Licensed Software or Licensed Product
  32 *     under any End User Software License Agreement or Agreement for Licensed
  33 *     Product with Synopsys or any supplement thereto.  Permission is hereby
  34 *     granted, free of charge, to any person obtaining a copy of this software
  35 *     annotated with this license and the Software, to deal in the Software
  36 *     without restriction, including without limitation the rights to use,
  37 *     copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  38 *     of the Software, and to permit persons to whom the Software is furnished
  39 *     to do so, subject to the following conditions:
  40 *
  41 *     The above copyright notice and this permission notice shall be included
  42 *     in all copies or substantial portions of the Software.
  43 *
  44 *     THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
  45 *     BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  46 *     TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  47 *     PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
  48 *     BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  49 *     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  50 *     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  51 *     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  52 *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  53 *     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  54 *     THE POSSIBILITY OF SUCH DAMAGE.
  55 *
  56 *
  57 * License 2: Modified BSD
  58 *
  59 * Copyright (c) 2016 Advanced Micro Devices, Inc.
  60 * All rights reserved.
  61 *
  62 * Redistribution and use in source and binary forms, with or without
  63 * modification, are permitted provided that the following conditions are met:
  64 *     * Redistributions of source code must retain the above copyright
  65 *       notice, this list of conditions and the following disclaimer.
  66 *     * Redistributions in binary form must reproduce the above copyright
  67 *       notice, this list of conditions and the following disclaimer in the
  68 *       documentation and/or other materials provided with the distribution.
  69 *     * Neither the name of Advanced Micro Devices, Inc. nor the
  70 *       names of its contributors may be used to endorse or promote products
  71 *       derived from this software without specific prior written permission.
  72 *
  73 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  74 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  75 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  76 * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  77 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  78 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  79 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  80 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  81 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  82 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  83 *
  84 * This file incorporates work covered by the following copyright and
  85 * permission notice:
  86 *     The Synopsys DWC ETHER XGMAC Software Driver and documentation
  87 *     (hereinafter "Software") is an unsupported proprietary work of Synopsys,
  88 *     Inc. unless otherwise expressly agreed to in writing between Synopsys
  89 *     and you.
  90 *
  91 *     The Software IS NOT an item of Licensed Software or Licensed Product
  92 *     under any End User Software License Agreement or Agreement for Licensed
  93 *     Product with Synopsys or any supplement thereto.  Permission is hereby
  94 *     granted, free of charge, to any person obtaining a copy of this software
  95 *     annotated with this license and the Software, to deal in the Software
  96 *     without restriction, including without limitation the rights to use,
  97 *     copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  98 *     of the Software, and to permit persons to whom the Software is furnished
  99 *     to do so, subject to the following conditions:
 100 *
 101 *     The above copyright notice and this permission notice shall be included
 102 *     in all copies or substantial portions of the Software.
 103 *
 104 *     THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
 105 *     BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 106 *     TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 107 *     PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
 108 *     BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 109 *     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 110 *     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 111 *     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 112 *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 113 *     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 114 *     THE POSSIBILITY OF SUCH DAMAGE.
 115 */
 116
 117#include <linux/module.h>
 118#include <linux/kmod.h>
 119#include <linux/device.h>
 120#include <linux/property.h>
 121#include <linux/mdio.h>
 122#include <linux/phy.h>
 123
 124#include "xgbe.h"
 125#include "xgbe-common.h"
 126
 127#define XGBE_BLWC_PROPERTY              "amd,serdes-blwc"
 128#define XGBE_CDR_RATE_PROPERTY          "amd,serdes-cdr-rate"
 129#define XGBE_PQ_SKEW_PROPERTY           "amd,serdes-pq-skew"
 130#define XGBE_TX_AMP_PROPERTY            "amd,serdes-tx-amp"
 131#define XGBE_DFE_CFG_PROPERTY           "amd,serdes-dfe-tap-config"
 132#define XGBE_DFE_ENA_PROPERTY           "amd,serdes-dfe-tap-enable"
 133
 134/* Default SerDes settings */
 135#define XGBE_SPEED_1000_BLWC            1
 136#define XGBE_SPEED_1000_CDR             0x2
 137#define XGBE_SPEED_1000_PLL             0x0
 138#define XGBE_SPEED_1000_PQ              0xa
 139#define XGBE_SPEED_1000_RATE            0x3
 140#define XGBE_SPEED_1000_TXAMP           0xf
 141#define XGBE_SPEED_1000_WORD            0x1
 142#define XGBE_SPEED_1000_DFE_TAP_CONFIG  0x3
 143#define XGBE_SPEED_1000_DFE_TAP_ENABLE  0x0
 144
 145#define XGBE_SPEED_2500_BLWC            1
 146#define XGBE_SPEED_2500_CDR             0x2
 147#define XGBE_SPEED_2500_PLL             0x0
 148#define XGBE_SPEED_2500_PQ              0xa
 149#define XGBE_SPEED_2500_RATE            0x1
 150#define XGBE_SPEED_2500_TXAMP           0xf
 151#define XGBE_SPEED_2500_WORD            0x1
 152#define XGBE_SPEED_2500_DFE_TAP_CONFIG  0x3
 153#define XGBE_SPEED_2500_DFE_TAP_ENABLE  0x0
 154
 155#define XGBE_SPEED_10000_BLWC           0
 156#define XGBE_SPEED_10000_CDR            0x7
 157#define XGBE_SPEED_10000_PLL            0x1
 158#define XGBE_SPEED_10000_PQ             0x12
 159#define XGBE_SPEED_10000_RATE           0x0
 160#define XGBE_SPEED_10000_TXAMP          0xa
 161#define XGBE_SPEED_10000_WORD           0x7
 162#define XGBE_SPEED_10000_DFE_TAP_CONFIG 0x1
 163#define XGBE_SPEED_10000_DFE_TAP_ENABLE 0x7f
 164
 165/* Rate-change complete wait/retry count */
 166#define XGBE_RATECHANGE_COUNT           500
 167
 168static const u32 xgbe_phy_blwc[] = {
 169        XGBE_SPEED_1000_BLWC,
 170        XGBE_SPEED_2500_BLWC,
 171        XGBE_SPEED_10000_BLWC,
 172};
 173
 174static const u32 xgbe_phy_cdr_rate[] = {
 175        XGBE_SPEED_1000_CDR,
 176        XGBE_SPEED_2500_CDR,
 177        XGBE_SPEED_10000_CDR,
 178};
 179
 180static const u32 xgbe_phy_pq_skew[] = {
 181        XGBE_SPEED_1000_PQ,
 182        XGBE_SPEED_2500_PQ,
 183        XGBE_SPEED_10000_PQ,
 184};
 185
 186static const u32 xgbe_phy_tx_amp[] = {
 187        XGBE_SPEED_1000_TXAMP,
 188        XGBE_SPEED_2500_TXAMP,
 189        XGBE_SPEED_10000_TXAMP,
 190};
 191
 192static const u32 xgbe_phy_dfe_tap_cfg[] = {
 193        XGBE_SPEED_1000_DFE_TAP_CONFIG,
 194        XGBE_SPEED_2500_DFE_TAP_CONFIG,
 195        XGBE_SPEED_10000_DFE_TAP_CONFIG,
 196};
 197
 198static const u32 xgbe_phy_dfe_tap_ena[] = {
 199        XGBE_SPEED_1000_DFE_TAP_ENABLE,
 200        XGBE_SPEED_2500_DFE_TAP_ENABLE,
 201        XGBE_SPEED_10000_DFE_TAP_ENABLE,
 202};
 203
 204struct xgbe_phy_data {
 205        /* 1000/10000 vs 2500/10000 indicator */
 206        unsigned int speed_set;
 207
 208        /* SerDes UEFI configurable settings.
 209         *   Switching between modes/speeds requires new values for some
 210         *   SerDes settings.  The values can be supplied as device
 211         *   properties in array format.  The first array entry is for
 212         *   1GbE, second for 2.5GbE and third for 10GbE
 213         */
 214        u32 blwc[XGBE_SPEEDS];
 215        u32 cdr_rate[XGBE_SPEEDS];
 216        u32 pq_skew[XGBE_SPEEDS];
 217        u32 tx_amp[XGBE_SPEEDS];
 218        u32 dfe_tap_cfg[XGBE_SPEEDS];
 219        u32 dfe_tap_ena[XGBE_SPEEDS];
 220};
 221
 222static void xgbe_phy_kr_training_pre(struct xgbe_prv_data *pdata)
 223{
 224                XSIR0_IOWRITE_BITS(pdata, SIR0_KR_RT_1, RESET, 1);
 225}
 226
 227static void xgbe_phy_kr_training_post(struct xgbe_prv_data *pdata)
 228{
 229                XSIR0_IOWRITE_BITS(pdata, SIR0_KR_RT_1, RESET, 0);
 230}
 231
 232static enum xgbe_mode xgbe_phy_an_outcome(struct xgbe_prv_data *pdata)
 233{
 234        struct ethtool_link_ksettings *lks = &pdata->phy.lks;
 235        struct xgbe_phy_data *phy_data = pdata->phy_data;
 236        enum xgbe_mode mode;
 237        unsigned int ad_reg, lp_reg;
 238
 239        XGBE_SET_LP_ADV(lks, Autoneg);
 240        XGBE_SET_LP_ADV(lks, Backplane);
 241
 242        /* Compare Advertisement and Link Partner register 1 */
 243        ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
 244        lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA);
 245        if (lp_reg & 0x400)
 246                XGBE_SET_LP_ADV(lks, Pause);
 247        if (lp_reg & 0x800)
 248                XGBE_SET_LP_ADV(lks, Asym_Pause);
 249
 250        if (pdata->phy.pause_autoneg) {
 251                /* Set flow control based on auto-negotiation result */
 252                pdata->phy.tx_pause = 0;
 253                pdata->phy.rx_pause = 0;
 254
 255                if (ad_reg & lp_reg & 0x400) {
 256                        pdata->phy.tx_pause = 1;
 257                        pdata->phy.rx_pause = 1;
 258                } else if (ad_reg & lp_reg & 0x800) {
 259                        if (ad_reg & 0x400)
 260                                pdata->phy.rx_pause = 1;
 261                        else if (lp_reg & 0x400)
 262                                pdata->phy.tx_pause = 1;
 263                }
 264        }
 265
 266        /* Compare Advertisement and Link Partner register 2 */
 267        ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1);
 268        lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 1);
 269        if (lp_reg & 0x80)
 270                XGBE_SET_LP_ADV(lks, 10000baseKR_Full);
 271        if (lp_reg & 0x20) {
 272                if (phy_data->speed_set == XGBE_SPEEDSET_2500_10000)
 273                        XGBE_SET_LP_ADV(lks, 2500baseX_Full);
 274                else
 275                        XGBE_SET_LP_ADV(lks, 1000baseKX_Full);
 276        }
 277
 278        ad_reg &= lp_reg;
 279        if (ad_reg & 0x80) {
 280                mode = XGBE_MODE_KR;
 281        } else if (ad_reg & 0x20) {
 282                if (phy_data->speed_set == XGBE_SPEEDSET_2500_10000)
 283                        mode = XGBE_MODE_KX_2500;
 284                else
 285                        mode = XGBE_MODE_KX_1000;
 286        } else {
 287                mode = XGBE_MODE_UNKNOWN;
 288        }
 289
 290        /* Compare Advertisement and Link Partner register 3 */
 291        ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2);
 292        lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 2);
 293        if (lp_reg & 0xc000)
 294                XGBE_SET_LP_ADV(lks, 10000baseR_FEC);
 295
 296        return mode;
 297}
 298
 299static void xgbe_phy_an_advertising(struct xgbe_prv_data *pdata,
 300                                    struct ethtool_link_ksettings *dlks)
 301{
 302        struct ethtool_link_ksettings *slks = &pdata->phy.lks;
 303
 304        XGBE_LM_COPY(dlks, advertising, slks, advertising);
 305}
 306
 307static int xgbe_phy_an_config(struct xgbe_prv_data *pdata)
 308{
 309        /* Nothing uniquely required for an configuration */
 310        return 0;
 311}
 312
 313static enum xgbe_an_mode xgbe_phy_an_mode(struct xgbe_prv_data *pdata)
 314{
 315        return XGBE_AN_MODE_CL73;
 316}
 317
 318static void xgbe_phy_pcs_power_cycle(struct xgbe_prv_data *pdata)
 319{
 320        unsigned int reg;
 321
 322        reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1);
 323
 324        reg |= MDIO_CTRL1_LPOWER;
 325        XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg);
 326
 327        usleep_range(75, 100);
 328
 329        reg &= ~MDIO_CTRL1_LPOWER;
 330        XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg);
 331}
 332
 333static void xgbe_phy_start_ratechange(struct xgbe_prv_data *pdata)
 334{
 335        /* Assert Rx and Tx ratechange */
 336        XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, RATECHANGE, 1);
 337}
 338
 339static void xgbe_phy_complete_ratechange(struct xgbe_prv_data *pdata)
 340{
 341        unsigned int wait;
 342        u16 status;
 343
 344        /* Release Rx and Tx ratechange */
 345        XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, RATECHANGE, 0);
 346
 347        /* Wait for Rx and Tx ready */
 348        wait = XGBE_RATECHANGE_COUNT;
 349        while (wait--) {
 350                usleep_range(50, 75);
 351
 352                status = XSIR0_IOREAD(pdata, SIR0_STATUS);
 353                if (XSIR_GET_BITS(status, SIR0_STATUS, RX_READY) &&
 354                    XSIR_GET_BITS(status, SIR0_STATUS, TX_READY))
 355                        goto rx_reset;
 356        }
 357
 358        netif_dbg(pdata, link, pdata->netdev, "SerDes rx/tx not ready (%#hx)\n",
 359                  status);
 360
 361rx_reset:
 362        /* Perform Rx reset for the DFE changes */
 363        XRXTX_IOWRITE_BITS(pdata, RXTX_REG6, RESETB_RXD, 0);
 364        XRXTX_IOWRITE_BITS(pdata, RXTX_REG6, RESETB_RXD, 1);
 365}
 366
 367static void xgbe_phy_kr_mode(struct xgbe_prv_data *pdata)
 368{
 369        struct xgbe_phy_data *phy_data = pdata->phy_data;
 370        unsigned int reg;
 371
 372        /* Set PCS to KR/10G speed */
 373        reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL2);
 374        reg &= ~MDIO_PCS_CTRL2_TYPE;
 375        reg |= MDIO_PCS_CTRL2_10GBR;
 376        XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL2, reg);
 377
 378        reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1);
 379        reg &= ~MDIO_CTRL1_SPEEDSEL;
 380        reg |= MDIO_CTRL1_SPEED10G;
 381        XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg);
 382
 383        xgbe_phy_pcs_power_cycle(pdata);
 384
 385        /* Set SerDes to 10G speed */
 386        xgbe_phy_start_ratechange(pdata);
 387
 388        XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, DATARATE, XGBE_SPEED_10000_RATE);
 389        XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, WORDMODE, XGBE_SPEED_10000_WORD);
 390        XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, PLLSEL, XGBE_SPEED_10000_PLL);
 391
 392        XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, CDR_RATE,
 393                           phy_data->cdr_rate[XGBE_SPEED_10000]);
 394        XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, TXAMP,
 395                           phy_data->tx_amp[XGBE_SPEED_10000]);
 396        XRXTX_IOWRITE_BITS(pdata, RXTX_REG20, BLWC_ENA,
 397                           phy_data->blwc[XGBE_SPEED_10000]);
 398        XRXTX_IOWRITE_BITS(pdata, RXTX_REG114, PQ_REG,
 399                           phy_data->pq_skew[XGBE_SPEED_10000]);
 400        XRXTX_IOWRITE_BITS(pdata, RXTX_REG129, RXDFE_CONFIG,
 401                           phy_data->dfe_tap_cfg[XGBE_SPEED_10000]);
 402        XRXTX_IOWRITE(pdata, RXTX_REG22,
 403                      phy_data->dfe_tap_ena[XGBE_SPEED_10000]);
 404
 405        xgbe_phy_complete_ratechange(pdata);
 406
 407        netif_dbg(pdata, link, pdata->netdev, "10GbE KR mode set\n");
 408}
 409
 410static void xgbe_phy_kx_2500_mode(struct xgbe_prv_data *pdata)
 411{
 412        struct xgbe_phy_data *phy_data = pdata->phy_data;
 413        unsigned int reg;
 414
 415        /* Set PCS to KX/1G speed */
 416        reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL2);
 417        reg &= ~MDIO_PCS_CTRL2_TYPE;
 418        reg |= MDIO_PCS_CTRL2_10GBX;
 419        XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL2, reg);
 420
 421        reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1);
 422        reg &= ~MDIO_CTRL1_SPEEDSEL;
 423        reg |= MDIO_CTRL1_SPEED1G;
 424        XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg);
 425
 426        xgbe_phy_pcs_power_cycle(pdata);
 427
 428        /* Set SerDes to 2.5G speed */
 429        xgbe_phy_start_ratechange(pdata);
 430
 431        XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, DATARATE, XGBE_SPEED_2500_RATE);
 432        XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, WORDMODE, XGBE_SPEED_2500_WORD);
 433        XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, PLLSEL, XGBE_SPEED_2500_PLL);
 434
 435        XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, CDR_RATE,
 436                           phy_data->cdr_rate[XGBE_SPEED_2500]);
 437        XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, TXAMP,
 438                           phy_data->tx_amp[XGBE_SPEED_2500]);
 439        XRXTX_IOWRITE_BITS(pdata, RXTX_REG20, BLWC_ENA,
 440                           phy_data->blwc[XGBE_SPEED_2500]);
 441        XRXTX_IOWRITE_BITS(pdata, RXTX_REG114, PQ_REG,
 442                           phy_data->pq_skew[XGBE_SPEED_2500]);
 443        XRXTX_IOWRITE_BITS(pdata, RXTX_REG129, RXDFE_CONFIG,
 444                           phy_data->dfe_tap_cfg[XGBE_SPEED_2500]);
 445        XRXTX_IOWRITE(pdata, RXTX_REG22,
 446                      phy_data->dfe_tap_ena[XGBE_SPEED_2500]);
 447
 448        xgbe_phy_complete_ratechange(pdata);
 449
 450        netif_dbg(pdata, link, pdata->netdev, "2.5GbE KX mode set\n");
 451}
 452
 453static void xgbe_phy_kx_1000_mode(struct xgbe_prv_data *pdata)
 454{
 455        struct xgbe_phy_data *phy_data = pdata->phy_data;
 456        unsigned int reg;
 457
 458        /* Set PCS to KX/1G speed */
 459        reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL2);
 460        reg &= ~MDIO_PCS_CTRL2_TYPE;
 461        reg |= MDIO_PCS_CTRL2_10GBX;
 462        XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL2, reg);
 463
 464        reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1);
 465        reg &= ~MDIO_CTRL1_SPEEDSEL;
 466        reg |= MDIO_CTRL1_SPEED1G;
 467        XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg);
 468
 469        xgbe_phy_pcs_power_cycle(pdata);
 470
 471        /* Set SerDes to 1G speed */
 472        xgbe_phy_start_ratechange(pdata);
 473
 474        XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, DATARATE, XGBE_SPEED_1000_RATE);
 475        XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, WORDMODE, XGBE_SPEED_1000_WORD);
 476        XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, PLLSEL, XGBE_SPEED_1000_PLL);
 477
 478        XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, CDR_RATE,
 479                           phy_data->cdr_rate[XGBE_SPEED_1000]);
 480        XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, TXAMP,
 481                           phy_data->tx_amp[XGBE_SPEED_1000]);
 482        XRXTX_IOWRITE_BITS(pdata, RXTX_REG20, BLWC_ENA,
 483                           phy_data->blwc[XGBE_SPEED_1000]);
 484        XRXTX_IOWRITE_BITS(pdata, RXTX_REG114, PQ_REG,
 485                           phy_data->pq_skew[XGBE_SPEED_1000]);
 486        XRXTX_IOWRITE_BITS(pdata, RXTX_REG129, RXDFE_CONFIG,
 487                           phy_data->dfe_tap_cfg[XGBE_SPEED_1000]);
 488        XRXTX_IOWRITE(pdata, RXTX_REG22,
 489                      phy_data->dfe_tap_ena[XGBE_SPEED_1000]);
 490
 491        xgbe_phy_complete_ratechange(pdata);
 492
 493        netif_dbg(pdata, link, pdata->netdev, "1GbE KX mode set\n");
 494}
 495
 496static enum xgbe_mode xgbe_phy_cur_mode(struct xgbe_prv_data *pdata)
 497{
 498        struct xgbe_phy_data *phy_data = pdata->phy_data;
 499        enum xgbe_mode mode;
 500        unsigned int reg;
 501
 502        reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL2);
 503        reg &= MDIO_PCS_CTRL2_TYPE;
 504
 505        if (reg == MDIO_PCS_CTRL2_10GBR) {
 506                mode = XGBE_MODE_KR;
 507        } else {
 508                if (phy_data->speed_set == XGBE_SPEEDSET_2500_10000)
 509                        mode = XGBE_MODE_KX_2500;
 510                else
 511                        mode = XGBE_MODE_KX_1000;
 512        }
 513
 514        return mode;
 515}
 516
 517static enum xgbe_mode xgbe_phy_switch_mode(struct xgbe_prv_data *pdata)
 518{
 519        struct xgbe_phy_data *phy_data = pdata->phy_data;
 520        enum xgbe_mode mode;
 521
 522        /* If we are in KR switch to KX, and vice-versa */
 523        if (xgbe_phy_cur_mode(pdata) == XGBE_MODE_KR) {
 524                if (phy_data->speed_set == XGBE_SPEEDSET_2500_10000)
 525                        mode = XGBE_MODE_KX_2500;
 526                else
 527                        mode = XGBE_MODE_KX_1000;
 528        } else {
 529                mode = XGBE_MODE_KR;
 530        }
 531
 532        return mode;
 533}
 534
 535static enum xgbe_mode xgbe_phy_get_mode(struct xgbe_prv_data *pdata,
 536                                        int speed)
 537{
 538        struct xgbe_phy_data *phy_data = pdata->phy_data;
 539
 540        switch (speed) {
 541        case SPEED_1000:
 542                return (phy_data->speed_set == XGBE_SPEEDSET_1000_10000)
 543                        ? XGBE_MODE_KX_1000 : XGBE_MODE_UNKNOWN;
 544        case SPEED_2500:
 545                return (phy_data->speed_set == XGBE_SPEEDSET_2500_10000)
 546                        ? XGBE_MODE_KX_2500 : XGBE_MODE_UNKNOWN;
 547        case SPEED_10000:
 548                return XGBE_MODE_KR;
 549        default:
 550                return XGBE_MODE_UNKNOWN;
 551        }
 552}
 553
 554static void xgbe_phy_set_mode(struct xgbe_prv_data *pdata, enum xgbe_mode mode)
 555{
 556        switch (mode) {
 557        case XGBE_MODE_KX_1000:
 558                xgbe_phy_kx_1000_mode(pdata);
 559                break;
 560        case XGBE_MODE_KX_2500:
 561                xgbe_phy_kx_2500_mode(pdata);
 562                break;
 563        case XGBE_MODE_KR:
 564                xgbe_phy_kr_mode(pdata);
 565                break;
 566        default:
 567                break;
 568        }
 569}
 570
 571static bool xgbe_phy_check_mode(struct xgbe_prv_data *pdata,
 572                                enum xgbe_mode mode, bool advert)
 573{
 574        if (pdata->phy.autoneg == AUTONEG_ENABLE) {
 575                return advert;
 576        } else {
 577                enum xgbe_mode cur_mode;
 578
 579                cur_mode = xgbe_phy_get_mode(pdata, pdata->phy.speed);
 580                if (cur_mode == mode)
 581                        return true;
 582        }
 583
 584        return false;
 585}
 586
 587static bool xgbe_phy_use_mode(struct xgbe_prv_data *pdata, enum xgbe_mode mode)
 588{
 589        struct ethtool_link_ksettings *lks = &pdata->phy.lks;
 590
 591        switch (mode) {
 592        case XGBE_MODE_KX_1000:
 593                return xgbe_phy_check_mode(pdata, mode,
 594                                           XGBE_ADV(lks, 1000baseKX_Full));
 595        case XGBE_MODE_KX_2500:
 596                return xgbe_phy_check_mode(pdata, mode,
 597                                           XGBE_ADV(lks, 2500baseX_Full));
 598        case XGBE_MODE_KR:
 599                return xgbe_phy_check_mode(pdata, mode,
 600                                           XGBE_ADV(lks, 10000baseKR_Full));
 601        default:
 602                return false;
 603        }
 604}
 605
 606static bool xgbe_phy_valid_speed(struct xgbe_prv_data *pdata, int speed)
 607{
 608        struct xgbe_phy_data *phy_data = pdata->phy_data;
 609
 610        switch (speed) {
 611        case SPEED_1000:
 612                if (phy_data->speed_set != XGBE_SPEEDSET_1000_10000)
 613                        return false;
 614                return true;
 615        case SPEED_2500:
 616                if (phy_data->speed_set != XGBE_SPEEDSET_2500_10000)
 617                        return false;
 618                return true;
 619        case SPEED_10000:
 620                return true;
 621        default:
 622                return false;
 623        }
 624}
 625
 626static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart)
 627{
 628        unsigned int reg;
 629
 630        *an_restart = 0;
 631
 632        /* Link status is latched low, so read once to clear
 633         * and then read again to get current state
 634         */
 635        reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
 636        reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
 637
 638        return (reg & MDIO_STAT1_LSTATUS) ? 1 : 0;
 639}
 640
 641static void xgbe_phy_stop(struct xgbe_prv_data *pdata)
 642{
 643        /* Nothing uniquely required for stop */
 644}
 645
 646static int xgbe_phy_start(struct xgbe_prv_data *pdata)
 647{
 648        /* Nothing uniquely required for start */
 649        return 0;
 650}
 651
 652static int xgbe_phy_reset(struct xgbe_prv_data *pdata)
 653{
 654        unsigned int reg, count;
 655
 656        /* Perform a software reset of the PCS */
 657        reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1);
 658        reg |= MDIO_CTRL1_RESET;
 659        XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg);
 660
 661        count = 50;
 662        do {
 663                msleep(20);
 664                reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1);
 665        } while ((reg & MDIO_CTRL1_RESET) && --count);
 666
 667        if (reg & MDIO_CTRL1_RESET)
 668                return -ETIMEDOUT;
 669
 670        return 0;
 671}
 672
 673static void xgbe_phy_exit(struct xgbe_prv_data *pdata)
 674{
 675        /* Nothing uniquely required for exit */
 676}
 677
 678static int xgbe_phy_init(struct xgbe_prv_data *pdata)
 679{
 680        struct ethtool_link_ksettings *lks = &pdata->phy.lks;
 681        struct xgbe_phy_data *phy_data;
 682        int ret;
 683
 684        phy_data = devm_kzalloc(pdata->dev, sizeof(*phy_data), GFP_KERNEL);
 685        if (!phy_data)
 686                return -ENOMEM;
 687
 688        /* Retrieve the PHY speedset */
 689        ret = device_property_read_u32(pdata->phy_dev, XGBE_SPEEDSET_PROPERTY,
 690                                       &phy_data->speed_set);
 691        if (ret) {
 692                dev_err(pdata->dev, "invalid %s property\n",
 693                        XGBE_SPEEDSET_PROPERTY);
 694                return ret;
 695        }
 696
 697        switch (phy_data->speed_set) {
 698        case XGBE_SPEEDSET_1000_10000:
 699        case XGBE_SPEEDSET_2500_10000:
 700                break;
 701        default:
 702                dev_err(pdata->dev, "invalid %s property\n",
 703                        XGBE_SPEEDSET_PROPERTY);
 704                return -EINVAL;
 705        }
 706
 707        /* Retrieve the PHY configuration properties */
 708        if (device_property_present(pdata->phy_dev, XGBE_BLWC_PROPERTY)) {
 709                ret = device_property_read_u32_array(pdata->phy_dev,
 710                                                     XGBE_BLWC_PROPERTY,
 711                                                     phy_data->blwc,
 712                                                     XGBE_SPEEDS);
 713                if (ret) {
 714                        dev_err(pdata->dev, "invalid %s property\n",
 715                                XGBE_BLWC_PROPERTY);
 716                        return ret;
 717                }
 718        } else {
 719                memcpy(phy_data->blwc, xgbe_phy_blwc,
 720                       sizeof(phy_data->blwc));
 721        }
 722
 723        if (device_property_present(pdata->phy_dev, XGBE_CDR_RATE_PROPERTY)) {
 724                ret = device_property_read_u32_array(pdata->phy_dev,
 725                                                     XGBE_CDR_RATE_PROPERTY,
 726                                                     phy_data->cdr_rate,
 727                                                     XGBE_SPEEDS);
 728                if (ret) {
 729                        dev_err(pdata->dev, "invalid %s property\n",
 730                                XGBE_CDR_RATE_PROPERTY);
 731                        return ret;
 732                }
 733        } else {
 734                memcpy(phy_data->cdr_rate, xgbe_phy_cdr_rate,
 735                       sizeof(phy_data->cdr_rate));
 736        }
 737
 738        if (device_property_present(pdata->phy_dev, XGBE_PQ_SKEW_PROPERTY)) {
 739                ret = device_property_read_u32_array(pdata->phy_dev,
 740                                                     XGBE_PQ_SKEW_PROPERTY,
 741                                                     phy_data->pq_skew,
 742                                                     XGBE_SPEEDS);
 743                if (ret) {
 744                        dev_err(pdata->dev, "invalid %s property\n",
 745                                XGBE_PQ_SKEW_PROPERTY);
 746                        return ret;
 747                }
 748        } else {
 749                memcpy(phy_data->pq_skew, xgbe_phy_pq_skew,
 750                       sizeof(phy_data->pq_skew));
 751        }
 752
 753        if (device_property_present(pdata->phy_dev, XGBE_TX_AMP_PROPERTY)) {
 754                ret = device_property_read_u32_array(pdata->phy_dev,
 755                                                     XGBE_TX_AMP_PROPERTY,
 756                                                     phy_data->tx_amp,
 757                                                     XGBE_SPEEDS);
 758                if (ret) {
 759                        dev_err(pdata->dev, "invalid %s property\n",
 760                                XGBE_TX_AMP_PROPERTY);
 761                        return ret;
 762                }
 763        } else {
 764                memcpy(phy_data->tx_amp, xgbe_phy_tx_amp,
 765                       sizeof(phy_data->tx_amp));
 766        }
 767
 768        if (device_property_present(pdata->phy_dev, XGBE_DFE_CFG_PROPERTY)) {
 769                ret = device_property_read_u32_array(pdata->phy_dev,
 770                                                     XGBE_DFE_CFG_PROPERTY,
 771                                                     phy_data->dfe_tap_cfg,
 772                                                     XGBE_SPEEDS);
 773                if (ret) {
 774                        dev_err(pdata->dev, "invalid %s property\n",
 775                                XGBE_DFE_CFG_PROPERTY);
 776                        return ret;
 777                }
 778        } else {
 779                memcpy(phy_data->dfe_tap_cfg, xgbe_phy_dfe_tap_cfg,
 780                       sizeof(phy_data->dfe_tap_cfg));
 781        }
 782
 783        if (device_property_present(pdata->phy_dev, XGBE_DFE_ENA_PROPERTY)) {
 784                ret = device_property_read_u32_array(pdata->phy_dev,
 785                                                     XGBE_DFE_ENA_PROPERTY,
 786                                                     phy_data->dfe_tap_ena,
 787                                                     XGBE_SPEEDS);
 788                if (ret) {
 789                        dev_err(pdata->dev, "invalid %s property\n",
 790                                XGBE_DFE_ENA_PROPERTY);
 791                        return ret;
 792                }
 793        } else {
 794                memcpy(phy_data->dfe_tap_ena, xgbe_phy_dfe_tap_ena,
 795                       sizeof(phy_data->dfe_tap_ena));
 796        }
 797
 798        /* Initialize supported features */
 799        XGBE_ZERO_SUP(lks);
 800        XGBE_SET_SUP(lks, Autoneg);
 801        XGBE_SET_SUP(lks, Pause);
 802        XGBE_SET_SUP(lks, Asym_Pause);
 803        XGBE_SET_SUP(lks, Backplane);
 804        XGBE_SET_SUP(lks, 10000baseKR_Full);
 805        switch (phy_data->speed_set) {
 806        case XGBE_SPEEDSET_1000_10000:
 807                XGBE_SET_SUP(lks, 1000baseKX_Full);
 808                break;
 809        case XGBE_SPEEDSET_2500_10000:
 810                XGBE_SET_SUP(lks, 2500baseX_Full);
 811                break;
 812        }
 813
 814        if (pdata->fec_ability & MDIO_PMA_10GBR_FECABLE_ABLE)
 815                XGBE_SET_SUP(lks, 10000baseR_FEC);
 816
 817        pdata->phy_data = phy_data;
 818
 819        return 0;
 820}
 821
 822void xgbe_init_function_ptrs_phy_v1(struct xgbe_phy_if *phy_if)
 823{
 824        struct xgbe_phy_impl_if *phy_impl = &phy_if->phy_impl;
 825
 826        phy_impl->init                  = xgbe_phy_init;
 827        phy_impl->exit                  = xgbe_phy_exit;
 828
 829        phy_impl->reset                 = xgbe_phy_reset;
 830        phy_impl->start                 = xgbe_phy_start;
 831        phy_impl->stop                  = xgbe_phy_stop;
 832
 833        phy_impl->link_status           = xgbe_phy_link_status;
 834
 835        phy_impl->valid_speed           = xgbe_phy_valid_speed;
 836
 837        phy_impl->use_mode              = xgbe_phy_use_mode;
 838        phy_impl->set_mode              = xgbe_phy_set_mode;
 839        phy_impl->get_mode              = xgbe_phy_get_mode;
 840        phy_impl->switch_mode           = xgbe_phy_switch_mode;
 841        phy_impl->cur_mode              = xgbe_phy_cur_mode;
 842
 843        phy_impl->an_mode               = xgbe_phy_an_mode;
 844
 845        phy_impl->an_config             = xgbe_phy_an_config;
 846
 847        phy_impl->an_advertising        = xgbe_phy_an_advertising;
 848
 849        phy_impl->an_outcome            = xgbe_phy_an_outcome;
 850
 851        phy_impl->kr_training_pre       = xgbe_phy_kr_training_pre;
 852        phy_impl->kr_training_post      = xgbe_phy_kr_training_post;
 853}
 854