brintos

brintos / linux-shallow public Read only

0
0
Text · 44.9 KiB · 07f4f34 Raw
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