Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * AMD 10Gb Ethernet driver
0003  *
0004  * This file is available to you under your choice of the following two
0005  * licenses:
0006  *
0007  * License 1: GPLv2
0008  *
0009  * Copyright (c) 2016 Advanced Micro Devices, Inc.
0010  *
0011  * This file is free software; you may copy, redistribute and/or modify
0012  * it under the terms of the GNU General Public License as published by
0013  * the Free Software Foundation, either version 2 of the License, or (at
0014  * your option) any later version.
0015  *
0016  * This file is distributed in the hope that it will be useful, but
0017  * WITHOUT ANY WARRANTY; without even the implied warranty of
0018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0019  * General Public License for more details.
0020  *
0021  * You should have received a copy of the GNU General Public License
0022  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0023  *
0024  * This file incorporates work covered by the following copyright and
0025  * permission notice:
0026  *     The Synopsys DWC ETHER XGMAC Software Driver and documentation
0027  *     (hereinafter "Software") is an unsupported proprietary work of Synopsys,
0028  *     Inc. unless otherwise expressly agreed to in writing between Synopsys
0029  *     and you.
0030  *
0031  *     The Software IS NOT an item of Licensed Software or Licensed Product
0032  *     under any End User Software License Agreement or Agreement for Licensed
0033  *     Product with Synopsys or any supplement thereto.  Permission is hereby
0034  *     granted, free of charge, to any person obtaining a copy of this software
0035  *     annotated with this license and the Software, to deal in the Software
0036  *     without restriction, including without limitation the rights to use,
0037  *     copy, modify, merge, publish, distribute, sublicense, and/or sell copies
0038  *     of the Software, and to permit persons to whom the Software is furnished
0039  *     to do so, subject to the following conditions:
0040  *
0041  *     The above copyright notice and this permission notice shall be included
0042  *     in all copies or substantial portions of the Software.
0043  *
0044  *     THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
0045  *     BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
0046  *     TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
0047  *     PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
0048  *     BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0049  *     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0050  *     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0051  *     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0052  *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0053  *     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
0054  *     THE POSSIBILITY OF SUCH DAMAGE.
0055  *
0056  *
0057  * License 2: Modified BSD
0058  *
0059  * Copyright (c) 2016 Advanced Micro Devices, Inc.
0060  * All rights reserved.
0061  *
0062  * Redistribution and use in source and binary forms, with or without
0063  * modification, are permitted provided that the following conditions are met:
0064  *     * Redistributions of source code must retain the above copyright
0065  *       notice, this list of conditions and the following disclaimer.
0066  *     * Redistributions in binary form must reproduce the above copyright
0067  *       notice, this list of conditions and the following disclaimer in the
0068  *       documentation and/or other materials provided with the distribution.
0069  *     * Neither the name of Advanced Micro Devices, Inc. nor the
0070  *       names of its contributors may be used to endorse or promote products
0071  *       derived from this software without specific prior written permission.
0072  *
0073  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0074  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0075  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0076  * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
0077  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
0078  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
0079  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0080  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0081  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0082  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0083  *
0084  * This file incorporates work covered by the following copyright and
0085  * permission notice:
0086  *     The Synopsys DWC ETHER XGMAC Software Driver and documentation
0087  *     (hereinafter "Software") is an unsupported proprietary work of Synopsys,
0088  *     Inc. unless otherwise expressly agreed to in writing between Synopsys
0089  *     and you.
0090  *
0091  *     The Software IS NOT an item of Licensed Software or Licensed Product
0092  *     under any End User Software License Agreement or Agreement for Licensed
0093  *     Product with Synopsys or any supplement thereto.  Permission is hereby
0094  *     granted, free of charge, to any person obtaining a copy of this software
0095  *     annotated with this license and the Software, to deal in the Software
0096  *     without restriction, including without limitation the rights to use,
0097  *     copy, modify, merge, publish, distribute, sublicense, and/or sell copies
0098  *     of the Software, and to permit persons to whom the Software is furnished
0099  *     to do so, subject to the following conditions:
0100  *
0101  *     The above copyright notice and this permission notice shall be included
0102  *     in all copies or substantial portions of the Software.
0103  *
0104  *     THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
0105  *     BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
0106  *     TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
0107  *     PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
0108  *     BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0109  *     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0110  *     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0111  *     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0112  *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0113  *     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
0114  *     THE POSSIBILITY OF SUCH DAMAGE.
0115  */
0116 
0117 #include <linux/module.h>
0118 #include <linux/kmod.h>
0119 #include <linux/device.h>
0120 #include <linux/property.h>
0121 #include <linux/mdio.h>
0122 #include <linux/phy.h>
0123 
0124 #include "xgbe.h"
0125 #include "xgbe-common.h"
0126 
0127 #define XGBE_BLWC_PROPERTY      "amd,serdes-blwc"
0128 #define XGBE_CDR_RATE_PROPERTY      "amd,serdes-cdr-rate"
0129 #define XGBE_PQ_SKEW_PROPERTY       "amd,serdes-pq-skew"
0130 #define XGBE_TX_AMP_PROPERTY        "amd,serdes-tx-amp"
0131 #define XGBE_DFE_CFG_PROPERTY       "amd,serdes-dfe-tap-config"
0132 #define XGBE_DFE_ENA_PROPERTY       "amd,serdes-dfe-tap-enable"
0133 
0134 /* Default SerDes settings */
0135 #define XGBE_SPEED_1000_BLWC        1
0136 #define XGBE_SPEED_1000_CDR     0x2
0137 #define XGBE_SPEED_1000_PLL     0x0
0138 #define XGBE_SPEED_1000_PQ      0xa
0139 #define XGBE_SPEED_1000_RATE        0x3
0140 #define XGBE_SPEED_1000_TXAMP       0xf
0141 #define XGBE_SPEED_1000_WORD        0x1
0142 #define XGBE_SPEED_1000_DFE_TAP_CONFIG  0x3
0143 #define XGBE_SPEED_1000_DFE_TAP_ENABLE  0x0
0144 
0145 #define XGBE_SPEED_2500_BLWC        1
0146 #define XGBE_SPEED_2500_CDR     0x2
0147 #define XGBE_SPEED_2500_PLL     0x0
0148 #define XGBE_SPEED_2500_PQ      0xa
0149 #define XGBE_SPEED_2500_RATE        0x1
0150 #define XGBE_SPEED_2500_TXAMP       0xf
0151 #define XGBE_SPEED_2500_WORD        0x1
0152 #define XGBE_SPEED_2500_DFE_TAP_CONFIG  0x3
0153 #define XGBE_SPEED_2500_DFE_TAP_ENABLE  0x0
0154 
0155 #define XGBE_SPEED_10000_BLWC       0
0156 #define XGBE_SPEED_10000_CDR        0x7
0157 #define XGBE_SPEED_10000_PLL        0x1
0158 #define XGBE_SPEED_10000_PQ     0x12
0159 #define XGBE_SPEED_10000_RATE       0x0
0160 #define XGBE_SPEED_10000_TXAMP      0xa
0161 #define XGBE_SPEED_10000_WORD       0x7
0162 #define XGBE_SPEED_10000_DFE_TAP_CONFIG 0x1
0163 #define XGBE_SPEED_10000_DFE_TAP_ENABLE 0x7f
0164 
0165 /* Rate-change complete wait/retry count */
0166 #define XGBE_RATECHANGE_COUNT       500
0167 
0168 static const u32 xgbe_phy_blwc[] = {
0169     XGBE_SPEED_1000_BLWC,
0170     XGBE_SPEED_2500_BLWC,
0171     XGBE_SPEED_10000_BLWC,
0172 };
0173 
0174 static const u32 xgbe_phy_cdr_rate[] = {
0175     XGBE_SPEED_1000_CDR,
0176     XGBE_SPEED_2500_CDR,
0177     XGBE_SPEED_10000_CDR,
0178 };
0179 
0180 static const u32 xgbe_phy_pq_skew[] = {
0181     XGBE_SPEED_1000_PQ,
0182     XGBE_SPEED_2500_PQ,
0183     XGBE_SPEED_10000_PQ,
0184 };
0185 
0186 static const u32 xgbe_phy_tx_amp[] = {
0187     XGBE_SPEED_1000_TXAMP,
0188     XGBE_SPEED_2500_TXAMP,
0189     XGBE_SPEED_10000_TXAMP,
0190 };
0191 
0192 static const u32 xgbe_phy_dfe_tap_cfg[] = {
0193     XGBE_SPEED_1000_DFE_TAP_CONFIG,
0194     XGBE_SPEED_2500_DFE_TAP_CONFIG,
0195     XGBE_SPEED_10000_DFE_TAP_CONFIG,
0196 };
0197 
0198 static const u32 xgbe_phy_dfe_tap_ena[] = {
0199     XGBE_SPEED_1000_DFE_TAP_ENABLE,
0200     XGBE_SPEED_2500_DFE_TAP_ENABLE,
0201     XGBE_SPEED_10000_DFE_TAP_ENABLE,
0202 };
0203 
0204 struct xgbe_phy_data {
0205     /* 1000/10000 vs 2500/10000 indicator */
0206     unsigned int speed_set;
0207 
0208     /* SerDes UEFI configurable settings.
0209      *   Switching between modes/speeds requires new values for some
0210      *   SerDes settings.  The values can be supplied as device
0211      *   properties in array format.  The first array entry is for
0212      *   1GbE, second for 2.5GbE and third for 10GbE
0213      */
0214     u32 blwc[XGBE_SPEEDS];
0215     u32 cdr_rate[XGBE_SPEEDS];
0216     u32 pq_skew[XGBE_SPEEDS];
0217     u32 tx_amp[XGBE_SPEEDS];
0218     u32 dfe_tap_cfg[XGBE_SPEEDS];
0219     u32 dfe_tap_ena[XGBE_SPEEDS];
0220 };
0221 
0222 static void xgbe_phy_kr_training_pre(struct xgbe_prv_data *pdata)
0223 {
0224         XSIR0_IOWRITE_BITS(pdata, SIR0_KR_RT_1, RESET, 1);
0225 }
0226 
0227 static void xgbe_phy_kr_training_post(struct xgbe_prv_data *pdata)
0228 {
0229         XSIR0_IOWRITE_BITS(pdata, SIR0_KR_RT_1, RESET, 0);
0230 }
0231 
0232 static enum xgbe_mode xgbe_phy_an_outcome(struct xgbe_prv_data *pdata)
0233 {
0234     struct ethtool_link_ksettings *lks = &pdata->phy.lks;
0235     struct xgbe_phy_data *phy_data = pdata->phy_data;
0236     enum xgbe_mode mode;
0237     unsigned int ad_reg, lp_reg;
0238 
0239     XGBE_SET_LP_ADV(lks, Autoneg);
0240     XGBE_SET_LP_ADV(lks, Backplane);
0241 
0242     /* Compare Advertisement and Link Partner register 1 */
0243     ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
0244     lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA);
0245     if (lp_reg & 0x400)
0246         XGBE_SET_LP_ADV(lks, Pause);
0247     if (lp_reg & 0x800)
0248         XGBE_SET_LP_ADV(lks, Asym_Pause);
0249 
0250     if (pdata->phy.pause_autoneg) {
0251         /* Set flow control based on auto-negotiation result */
0252         pdata->phy.tx_pause = 0;
0253         pdata->phy.rx_pause = 0;
0254 
0255         if (ad_reg & lp_reg & 0x400) {
0256             pdata->phy.tx_pause = 1;
0257             pdata->phy.rx_pause = 1;
0258         } else if (ad_reg & lp_reg & 0x800) {
0259             if (ad_reg & 0x400)
0260                 pdata->phy.rx_pause = 1;
0261             else if (lp_reg & 0x400)
0262                 pdata->phy.tx_pause = 1;
0263         }
0264     }
0265 
0266     /* Compare Advertisement and Link Partner register 2 */
0267     ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1);
0268     lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 1);
0269     if (lp_reg & 0x80)
0270         XGBE_SET_LP_ADV(lks, 10000baseKR_Full);
0271     if (lp_reg & 0x20) {
0272         if (phy_data->speed_set == XGBE_SPEEDSET_2500_10000)
0273             XGBE_SET_LP_ADV(lks, 2500baseX_Full);
0274         else
0275             XGBE_SET_LP_ADV(lks, 1000baseKX_Full);
0276     }
0277 
0278     ad_reg &= lp_reg;
0279     if (ad_reg & 0x80) {
0280         mode = XGBE_MODE_KR;
0281     } else if (ad_reg & 0x20) {
0282         if (phy_data->speed_set == XGBE_SPEEDSET_2500_10000)
0283             mode = XGBE_MODE_KX_2500;
0284         else
0285             mode = XGBE_MODE_KX_1000;
0286     } else {
0287         mode = XGBE_MODE_UNKNOWN;
0288     }
0289 
0290     /* Compare Advertisement and Link Partner register 3 */
0291     ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2);
0292     lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 2);
0293     if (lp_reg & 0xc000)
0294         XGBE_SET_LP_ADV(lks, 10000baseR_FEC);
0295 
0296     return mode;
0297 }
0298 
0299 static void xgbe_phy_an_advertising(struct xgbe_prv_data *pdata,
0300                     struct ethtool_link_ksettings *dlks)
0301 {
0302     struct ethtool_link_ksettings *slks = &pdata->phy.lks;
0303 
0304     XGBE_LM_COPY(dlks, advertising, slks, advertising);
0305 }
0306 
0307 static int xgbe_phy_an_config(struct xgbe_prv_data *pdata)
0308 {
0309     /* Nothing uniquely required for an configuration */
0310     return 0;
0311 }
0312 
0313 static enum xgbe_an_mode xgbe_phy_an_mode(struct xgbe_prv_data *pdata)
0314 {
0315     return XGBE_AN_MODE_CL73;
0316 }
0317 
0318 static void xgbe_phy_pcs_power_cycle(struct xgbe_prv_data *pdata)
0319 {
0320     unsigned int reg;
0321 
0322     reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1);
0323 
0324     reg |= MDIO_CTRL1_LPOWER;
0325     XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg);
0326 
0327     usleep_range(75, 100);
0328 
0329     reg &= ~MDIO_CTRL1_LPOWER;
0330     XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg);
0331 }
0332 
0333 static void xgbe_phy_start_ratechange(struct xgbe_prv_data *pdata)
0334 {
0335     /* Assert Rx and Tx ratechange */
0336     XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, RATECHANGE, 1);
0337 }
0338 
0339 static void xgbe_phy_complete_ratechange(struct xgbe_prv_data *pdata)
0340 {
0341     unsigned int wait;
0342     u16 status;
0343 
0344     /* Release Rx and Tx ratechange */
0345     XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, RATECHANGE, 0);
0346 
0347     /* Wait for Rx and Tx ready */
0348     wait = XGBE_RATECHANGE_COUNT;
0349     while (wait--) {
0350         usleep_range(50, 75);
0351 
0352         status = XSIR0_IOREAD(pdata, SIR0_STATUS);
0353         if (XSIR_GET_BITS(status, SIR0_STATUS, RX_READY) &&
0354             XSIR_GET_BITS(status, SIR0_STATUS, TX_READY))
0355             goto rx_reset;
0356     }
0357 
0358     netif_dbg(pdata, link, pdata->netdev, "SerDes rx/tx not ready (%#hx)\n",
0359           status);
0360 
0361 rx_reset:
0362     /* Perform Rx reset for the DFE changes */
0363     XRXTX_IOWRITE_BITS(pdata, RXTX_REG6, RESETB_RXD, 0);
0364     XRXTX_IOWRITE_BITS(pdata, RXTX_REG6, RESETB_RXD, 1);
0365 }
0366 
0367 static void xgbe_phy_kr_mode(struct xgbe_prv_data *pdata)
0368 {
0369     struct xgbe_phy_data *phy_data = pdata->phy_data;
0370     unsigned int reg;
0371 
0372     /* Set PCS to KR/10G speed */
0373     reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL2);
0374     reg &= ~MDIO_PCS_CTRL2_TYPE;
0375     reg |= MDIO_PCS_CTRL2_10GBR;
0376     XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL2, reg);
0377 
0378     reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1);
0379     reg &= ~MDIO_CTRL1_SPEEDSEL;
0380     reg |= MDIO_CTRL1_SPEED10G;
0381     XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg);
0382 
0383     xgbe_phy_pcs_power_cycle(pdata);
0384 
0385     /* Set SerDes to 10G speed */
0386     xgbe_phy_start_ratechange(pdata);
0387 
0388     XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, DATARATE, XGBE_SPEED_10000_RATE);
0389     XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, WORDMODE, XGBE_SPEED_10000_WORD);
0390     XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, PLLSEL, XGBE_SPEED_10000_PLL);
0391 
0392     XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, CDR_RATE,
0393                phy_data->cdr_rate[XGBE_SPEED_10000]);
0394     XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, TXAMP,
0395                phy_data->tx_amp[XGBE_SPEED_10000]);
0396     XRXTX_IOWRITE_BITS(pdata, RXTX_REG20, BLWC_ENA,
0397                phy_data->blwc[XGBE_SPEED_10000]);
0398     XRXTX_IOWRITE_BITS(pdata, RXTX_REG114, PQ_REG,
0399                phy_data->pq_skew[XGBE_SPEED_10000]);
0400     XRXTX_IOWRITE_BITS(pdata, RXTX_REG129, RXDFE_CONFIG,
0401                phy_data->dfe_tap_cfg[XGBE_SPEED_10000]);
0402     XRXTX_IOWRITE(pdata, RXTX_REG22,
0403               phy_data->dfe_tap_ena[XGBE_SPEED_10000]);
0404 
0405     xgbe_phy_complete_ratechange(pdata);
0406 
0407     netif_dbg(pdata, link, pdata->netdev, "10GbE KR mode set\n");
0408 }
0409 
0410 static void xgbe_phy_kx_2500_mode(struct xgbe_prv_data *pdata)
0411 {
0412     struct xgbe_phy_data *phy_data = pdata->phy_data;
0413     unsigned int reg;
0414 
0415     /* Set PCS to KX/1G speed */
0416     reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL2);
0417     reg &= ~MDIO_PCS_CTRL2_TYPE;
0418     reg |= MDIO_PCS_CTRL2_10GBX;
0419     XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL2, reg);
0420 
0421     reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1);
0422     reg &= ~MDIO_CTRL1_SPEEDSEL;
0423     reg |= MDIO_CTRL1_SPEED1G;
0424     XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg);
0425 
0426     xgbe_phy_pcs_power_cycle(pdata);
0427 
0428     /* Set SerDes to 2.5G speed */
0429     xgbe_phy_start_ratechange(pdata);
0430 
0431     XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, DATARATE, XGBE_SPEED_2500_RATE);
0432     XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, WORDMODE, XGBE_SPEED_2500_WORD);
0433     XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, PLLSEL, XGBE_SPEED_2500_PLL);
0434 
0435     XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, CDR_RATE,
0436                phy_data->cdr_rate[XGBE_SPEED_2500]);
0437     XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, TXAMP,
0438                phy_data->tx_amp[XGBE_SPEED_2500]);
0439     XRXTX_IOWRITE_BITS(pdata, RXTX_REG20, BLWC_ENA,
0440                phy_data->blwc[XGBE_SPEED_2500]);
0441     XRXTX_IOWRITE_BITS(pdata, RXTX_REG114, PQ_REG,
0442                phy_data->pq_skew[XGBE_SPEED_2500]);
0443     XRXTX_IOWRITE_BITS(pdata, RXTX_REG129, RXDFE_CONFIG,
0444                phy_data->dfe_tap_cfg[XGBE_SPEED_2500]);
0445     XRXTX_IOWRITE(pdata, RXTX_REG22,
0446               phy_data->dfe_tap_ena[XGBE_SPEED_2500]);
0447 
0448     xgbe_phy_complete_ratechange(pdata);
0449 
0450     netif_dbg(pdata, link, pdata->netdev, "2.5GbE KX mode set\n");
0451 }
0452 
0453 static void xgbe_phy_kx_1000_mode(struct xgbe_prv_data *pdata)
0454 {
0455     struct xgbe_phy_data *phy_data = pdata->phy_data;
0456     unsigned int reg;
0457 
0458     /* Set PCS to KX/1G speed */
0459     reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL2);
0460     reg &= ~MDIO_PCS_CTRL2_TYPE;
0461     reg |= MDIO_PCS_CTRL2_10GBX;
0462     XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL2, reg);
0463 
0464     reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1);
0465     reg &= ~MDIO_CTRL1_SPEEDSEL;
0466     reg |= MDIO_CTRL1_SPEED1G;
0467     XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg);
0468 
0469     xgbe_phy_pcs_power_cycle(pdata);
0470 
0471     /* Set SerDes to 1G speed */
0472     xgbe_phy_start_ratechange(pdata);
0473 
0474     XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, DATARATE, XGBE_SPEED_1000_RATE);
0475     XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, WORDMODE, XGBE_SPEED_1000_WORD);
0476     XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, PLLSEL, XGBE_SPEED_1000_PLL);
0477 
0478     XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, CDR_RATE,
0479                phy_data->cdr_rate[XGBE_SPEED_1000]);
0480     XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, TXAMP,
0481                phy_data->tx_amp[XGBE_SPEED_1000]);
0482     XRXTX_IOWRITE_BITS(pdata, RXTX_REG20, BLWC_ENA,
0483                phy_data->blwc[XGBE_SPEED_1000]);
0484     XRXTX_IOWRITE_BITS(pdata, RXTX_REG114, PQ_REG,
0485                phy_data->pq_skew[XGBE_SPEED_1000]);
0486     XRXTX_IOWRITE_BITS(pdata, RXTX_REG129, RXDFE_CONFIG,
0487                phy_data->dfe_tap_cfg[XGBE_SPEED_1000]);
0488     XRXTX_IOWRITE(pdata, RXTX_REG22,
0489               phy_data->dfe_tap_ena[XGBE_SPEED_1000]);
0490 
0491     xgbe_phy_complete_ratechange(pdata);
0492 
0493     netif_dbg(pdata, link, pdata->netdev, "1GbE KX mode set\n");
0494 }
0495 
0496 static enum xgbe_mode xgbe_phy_cur_mode(struct xgbe_prv_data *pdata)
0497 {
0498     struct xgbe_phy_data *phy_data = pdata->phy_data;
0499     enum xgbe_mode mode;
0500     unsigned int reg;
0501 
0502     reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL2);
0503     reg &= MDIO_PCS_CTRL2_TYPE;
0504 
0505     if (reg == MDIO_PCS_CTRL2_10GBR) {
0506         mode = XGBE_MODE_KR;
0507     } else {
0508         if (phy_data->speed_set == XGBE_SPEEDSET_2500_10000)
0509             mode = XGBE_MODE_KX_2500;
0510         else
0511             mode = XGBE_MODE_KX_1000;
0512     }
0513 
0514     return mode;
0515 }
0516 
0517 static enum xgbe_mode xgbe_phy_switch_mode(struct xgbe_prv_data *pdata)
0518 {
0519     struct xgbe_phy_data *phy_data = pdata->phy_data;
0520     enum xgbe_mode mode;
0521 
0522     /* If we are in KR switch to KX, and vice-versa */
0523     if (xgbe_phy_cur_mode(pdata) == XGBE_MODE_KR) {
0524         if (phy_data->speed_set == XGBE_SPEEDSET_2500_10000)
0525             mode = XGBE_MODE_KX_2500;
0526         else
0527             mode = XGBE_MODE_KX_1000;
0528     } else {
0529         mode = XGBE_MODE_KR;
0530     }
0531 
0532     return mode;
0533 }
0534 
0535 static enum xgbe_mode xgbe_phy_get_mode(struct xgbe_prv_data *pdata,
0536                     int speed)
0537 {
0538     struct xgbe_phy_data *phy_data = pdata->phy_data;
0539 
0540     switch (speed) {
0541     case SPEED_1000:
0542         return (phy_data->speed_set == XGBE_SPEEDSET_1000_10000)
0543             ? XGBE_MODE_KX_1000 : XGBE_MODE_UNKNOWN;
0544     case SPEED_2500:
0545         return (phy_data->speed_set == XGBE_SPEEDSET_2500_10000)
0546             ? XGBE_MODE_KX_2500 : XGBE_MODE_UNKNOWN;
0547     case SPEED_10000:
0548         return XGBE_MODE_KR;
0549     default:
0550         return XGBE_MODE_UNKNOWN;
0551     }
0552 }
0553 
0554 static void xgbe_phy_set_mode(struct xgbe_prv_data *pdata, enum xgbe_mode mode)
0555 {
0556     switch (mode) {
0557     case XGBE_MODE_KX_1000:
0558         xgbe_phy_kx_1000_mode(pdata);
0559         break;
0560     case XGBE_MODE_KX_2500:
0561         xgbe_phy_kx_2500_mode(pdata);
0562         break;
0563     case XGBE_MODE_KR:
0564         xgbe_phy_kr_mode(pdata);
0565         break;
0566     default:
0567         break;
0568     }
0569 }
0570 
0571 static bool xgbe_phy_check_mode(struct xgbe_prv_data *pdata,
0572                 enum xgbe_mode mode, bool advert)
0573 {
0574     if (pdata->phy.autoneg == AUTONEG_ENABLE) {
0575         return advert;
0576     } else {
0577         enum xgbe_mode cur_mode;
0578 
0579         cur_mode = xgbe_phy_get_mode(pdata, pdata->phy.speed);
0580         if (cur_mode == mode)
0581             return true;
0582     }
0583 
0584     return false;
0585 }
0586 
0587 static bool xgbe_phy_use_mode(struct xgbe_prv_data *pdata, enum xgbe_mode mode)
0588 {
0589     struct ethtool_link_ksettings *lks = &pdata->phy.lks;
0590 
0591     switch (mode) {
0592     case XGBE_MODE_KX_1000:
0593         return xgbe_phy_check_mode(pdata, mode,
0594                        XGBE_ADV(lks, 1000baseKX_Full));
0595     case XGBE_MODE_KX_2500:
0596         return xgbe_phy_check_mode(pdata, mode,
0597                        XGBE_ADV(lks, 2500baseX_Full));
0598     case XGBE_MODE_KR:
0599         return xgbe_phy_check_mode(pdata, mode,
0600                        XGBE_ADV(lks, 10000baseKR_Full));
0601     default:
0602         return false;
0603     }
0604 }
0605 
0606 static bool xgbe_phy_valid_speed(struct xgbe_prv_data *pdata, int speed)
0607 {
0608     struct xgbe_phy_data *phy_data = pdata->phy_data;
0609 
0610     switch (speed) {
0611     case SPEED_1000:
0612         if (phy_data->speed_set != XGBE_SPEEDSET_1000_10000)
0613             return false;
0614         return true;
0615     case SPEED_2500:
0616         if (phy_data->speed_set != XGBE_SPEEDSET_2500_10000)
0617             return false;
0618         return true;
0619     case SPEED_10000:
0620         return true;
0621     default:
0622         return false;
0623     }
0624 }
0625 
0626 static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart)
0627 {
0628     unsigned int reg;
0629 
0630     *an_restart = 0;
0631 
0632     /* Link status is latched low, so read once to clear
0633      * and then read again to get current state
0634      */
0635     reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
0636     reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
0637 
0638     return (reg & MDIO_STAT1_LSTATUS) ? 1 : 0;
0639 }
0640 
0641 static void xgbe_phy_stop(struct xgbe_prv_data *pdata)
0642 {
0643     /* Nothing uniquely required for stop */
0644 }
0645 
0646 static int xgbe_phy_start(struct xgbe_prv_data *pdata)
0647 {
0648     /* Nothing uniquely required for start */
0649     return 0;
0650 }
0651 
0652 static int xgbe_phy_reset(struct xgbe_prv_data *pdata)
0653 {
0654     unsigned int reg, count;
0655 
0656     /* Perform a software reset of the PCS */
0657     reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1);
0658     reg |= MDIO_CTRL1_RESET;
0659     XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg);
0660 
0661     count = 50;
0662     do {
0663         msleep(20);
0664         reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1);
0665     } while ((reg & MDIO_CTRL1_RESET) && --count);
0666 
0667     if (reg & MDIO_CTRL1_RESET)
0668         return -ETIMEDOUT;
0669 
0670     return 0;
0671 }
0672 
0673 static void xgbe_phy_exit(struct xgbe_prv_data *pdata)
0674 {
0675     /* Nothing uniquely required for exit */
0676 }
0677 
0678 static int xgbe_phy_init(struct xgbe_prv_data *pdata)
0679 {
0680     struct ethtool_link_ksettings *lks = &pdata->phy.lks;
0681     struct xgbe_phy_data *phy_data;
0682     int ret;
0683 
0684     phy_data = devm_kzalloc(pdata->dev, sizeof(*phy_data), GFP_KERNEL);
0685     if (!phy_data)
0686         return -ENOMEM;
0687 
0688     /* Retrieve the PHY speedset */
0689     ret = device_property_read_u32(pdata->phy_dev, XGBE_SPEEDSET_PROPERTY,
0690                        &phy_data->speed_set);
0691     if (ret) {
0692         dev_err(pdata->dev, "invalid %s property\n",
0693             XGBE_SPEEDSET_PROPERTY);
0694         return ret;
0695     }
0696 
0697     switch (phy_data->speed_set) {
0698     case XGBE_SPEEDSET_1000_10000:
0699     case XGBE_SPEEDSET_2500_10000:
0700         break;
0701     default:
0702         dev_err(pdata->dev, "invalid %s property\n",
0703             XGBE_SPEEDSET_PROPERTY);
0704         return -EINVAL;
0705     }
0706 
0707     /* Retrieve the PHY configuration properties */
0708     if (device_property_present(pdata->phy_dev, XGBE_BLWC_PROPERTY)) {
0709         ret = device_property_read_u32_array(pdata->phy_dev,
0710                              XGBE_BLWC_PROPERTY,
0711                              phy_data->blwc,
0712                              XGBE_SPEEDS);
0713         if (ret) {
0714             dev_err(pdata->dev, "invalid %s property\n",
0715                 XGBE_BLWC_PROPERTY);
0716             return ret;
0717         }
0718     } else {
0719         memcpy(phy_data->blwc, xgbe_phy_blwc,
0720                sizeof(phy_data->blwc));
0721     }
0722 
0723     if (device_property_present(pdata->phy_dev, XGBE_CDR_RATE_PROPERTY)) {
0724         ret = device_property_read_u32_array(pdata->phy_dev,
0725                              XGBE_CDR_RATE_PROPERTY,
0726                              phy_data->cdr_rate,
0727                              XGBE_SPEEDS);
0728         if (ret) {
0729             dev_err(pdata->dev, "invalid %s property\n",
0730                 XGBE_CDR_RATE_PROPERTY);
0731             return ret;
0732         }
0733     } else {
0734         memcpy(phy_data->cdr_rate, xgbe_phy_cdr_rate,
0735                sizeof(phy_data->cdr_rate));
0736     }
0737 
0738     if (device_property_present(pdata->phy_dev, XGBE_PQ_SKEW_PROPERTY)) {
0739         ret = device_property_read_u32_array(pdata->phy_dev,
0740                              XGBE_PQ_SKEW_PROPERTY,
0741                              phy_data->pq_skew,
0742                              XGBE_SPEEDS);
0743         if (ret) {
0744             dev_err(pdata->dev, "invalid %s property\n",
0745                 XGBE_PQ_SKEW_PROPERTY);
0746             return ret;
0747         }
0748     } else {
0749         memcpy(phy_data->pq_skew, xgbe_phy_pq_skew,
0750                sizeof(phy_data->pq_skew));
0751     }
0752 
0753     if (device_property_present(pdata->phy_dev, XGBE_TX_AMP_PROPERTY)) {
0754         ret = device_property_read_u32_array(pdata->phy_dev,
0755                              XGBE_TX_AMP_PROPERTY,
0756                              phy_data->tx_amp,
0757                              XGBE_SPEEDS);
0758         if (ret) {
0759             dev_err(pdata->dev, "invalid %s property\n",
0760                 XGBE_TX_AMP_PROPERTY);
0761             return ret;
0762         }
0763     } else {
0764         memcpy(phy_data->tx_amp, xgbe_phy_tx_amp,
0765                sizeof(phy_data->tx_amp));
0766     }
0767 
0768     if (device_property_present(pdata->phy_dev, XGBE_DFE_CFG_PROPERTY)) {
0769         ret = device_property_read_u32_array(pdata->phy_dev,
0770                              XGBE_DFE_CFG_PROPERTY,
0771                              phy_data->dfe_tap_cfg,
0772                              XGBE_SPEEDS);
0773         if (ret) {
0774             dev_err(pdata->dev, "invalid %s property\n",
0775                 XGBE_DFE_CFG_PROPERTY);
0776             return ret;
0777         }
0778     } else {
0779         memcpy(phy_data->dfe_tap_cfg, xgbe_phy_dfe_tap_cfg,
0780                sizeof(phy_data->dfe_tap_cfg));
0781     }
0782 
0783     if (device_property_present(pdata->phy_dev, XGBE_DFE_ENA_PROPERTY)) {
0784         ret = device_property_read_u32_array(pdata->phy_dev,
0785                              XGBE_DFE_ENA_PROPERTY,
0786                              phy_data->dfe_tap_ena,
0787                              XGBE_SPEEDS);
0788         if (ret) {
0789             dev_err(pdata->dev, "invalid %s property\n",
0790                 XGBE_DFE_ENA_PROPERTY);
0791             return ret;
0792         }
0793     } else {
0794         memcpy(phy_data->dfe_tap_ena, xgbe_phy_dfe_tap_ena,
0795                sizeof(phy_data->dfe_tap_ena));
0796     }
0797 
0798     /* Initialize supported features */
0799     XGBE_ZERO_SUP(lks);
0800     XGBE_SET_SUP(lks, Autoneg);
0801     XGBE_SET_SUP(lks, Pause);
0802     XGBE_SET_SUP(lks, Asym_Pause);
0803     XGBE_SET_SUP(lks, Backplane);
0804     XGBE_SET_SUP(lks, 10000baseKR_Full);
0805     switch (phy_data->speed_set) {
0806     case XGBE_SPEEDSET_1000_10000:
0807         XGBE_SET_SUP(lks, 1000baseKX_Full);
0808         break;
0809     case XGBE_SPEEDSET_2500_10000:
0810         XGBE_SET_SUP(lks, 2500baseX_Full);
0811         break;
0812     }
0813 
0814     if (pdata->fec_ability & MDIO_PMA_10GBR_FECABLE_ABLE)
0815         XGBE_SET_SUP(lks, 10000baseR_FEC);
0816 
0817     pdata->phy_data = phy_data;
0818 
0819     return 0;
0820 }
0821 
0822 void xgbe_init_function_ptrs_phy_v1(struct xgbe_phy_if *phy_if)
0823 {
0824     struct xgbe_phy_impl_if *phy_impl = &phy_if->phy_impl;
0825 
0826     phy_impl->init          = xgbe_phy_init;
0827     phy_impl->exit          = xgbe_phy_exit;
0828 
0829     phy_impl->reset         = xgbe_phy_reset;
0830     phy_impl->start         = xgbe_phy_start;
0831     phy_impl->stop          = xgbe_phy_stop;
0832 
0833     phy_impl->link_status       = xgbe_phy_link_status;
0834 
0835     phy_impl->valid_speed       = xgbe_phy_valid_speed;
0836 
0837     phy_impl->use_mode      = xgbe_phy_use_mode;
0838     phy_impl->set_mode      = xgbe_phy_set_mode;
0839     phy_impl->get_mode      = xgbe_phy_get_mode;
0840     phy_impl->switch_mode       = xgbe_phy_switch_mode;
0841     phy_impl->cur_mode      = xgbe_phy_cur_mode;
0842 
0843     phy_impl->an_mode       = xgbe_phy_an_mode;
0844 
0845     phy_impl->an_config     = xgbe_phy_an_config;
0846 
0847     phy_impl->an_advertising    = xgbe_phy_an_advertising;
0848 
0849     phy_impl->an_outcome        = xgbe_phy_an_outcome;
0850 
0851     phy_impl->kr_training_pre   = xgbe_phy_kr_training_pre;
0852     phy_impl->kr_training_post  = xgbe_phy_kr_training_post;
0853 }