18ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings/****************************************************************************
2177dfcd80f28f8fbc3e22c2d8b24d21cb86f1d97Ben Hutchings * Driver for Solarflare Solarstorm network controllers and boards
30a6f40c66ba388e6349a11bea146955716c4d492Ben Hutchings * Copyright 2007-2011 Solarflare Communications Inc.
48ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings *
58ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings * This program is free software; you can redistribute it and/or modify it
68ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings * under the terms of the GNU General Public License version 2 as published
78ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings * by the Free Software Foundation, incorporated herein by reference.
88ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings */
98ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
108ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#include <linux/delay.h>
11da3bc07171dff957906cbe2ad5abb443eccf57c4Herbert Xu#include <linux/rtnetlink.h>
128ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#include <linux/seq_file.h>
135a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
148ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#include "efx.h"
158ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#include "mdio_10g.h"
16744093c98363f8a65853aed39708c9effc80f8ffBen Hutchings#include "nic.h"
178ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#include "phy.h"
18e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#include "workarounds.h"
198ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
208fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings/* We expect these MMDs to be in the package. */
2168e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings#define TENXPRESS_REQUIRED_DEVS (MDIO_DEVS_PMAPMD	| \
2268e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings				 MDIO_DEVS_PCS		| \
2368e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings				 MDIO_DEVS_PHYXS	| \
2468e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings				 MDIO_DEVS_AN)
258ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
26e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define SFX7101_LOOPBACKS ((1 << LOOPBACK_PHYXS) |	\
27e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings			   (1 << LOOPBACK_PCS) |	\
28e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings			   (1 << LOOPBACK_PMAPMD) |	\
29e58f69f4082f60076885798fae8f3a17ea713bf6Ben Hutchings			   (1 << LOOPBACK_PHYXS_WS))
30e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings
318ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings/* We complain if we fail to see the link partner as 10G capable this many
328ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings * times in a row (must be > 1 as sampling the autoneg. registers is racy)
338ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings */
348ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#define MAX_BAD_LP_TRIES	(5)
358ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
368ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings/* Extended control register */
37e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define PMA_PMD_XCONTROL_REG	49152
38e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define PMA_PMD_EXT_GMII_EN_LBN	1
39e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define PMA_PMD_EXT_GMII_EN_WIDTH 1
40e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define PMA_PMD_EXT_CLK_OUT_LBN	2
41e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define PMA_PMD_EXT_CLK_OUT_WIDTH 1
428fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings#define PMA_PMD_LNPGA_POWERDOWN_LBN 8
43e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define PMA_PMD_LNPGA_POWERDOWN_WIDTH 1
44e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define PMA_PMD_EXT_CLK312_WIDTH 1
45e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define PMA_PMD_EXT_LPOWER_LBN  12
46e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define PMA_PMD_EXT_LPOWER_WIDTH 1
47869b5b3888fbd2024af632e3648c00860ba3cca6Steve Hodgson#define PMA_PMD_EXT_ROBUST_LBN	14
48869b5b3888fbd2024af632e3648c00860ba3cca6Steve Hodgson#define PMA_PMD_EXT_ROBUST_WIDTH 1
49e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define PMA_PMD_EXT_SSR_LBN	15
50e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define PMA_PMD_EXT_SSR_WIDTH	1
518ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
528ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings/* extended status register */
53e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define PMA_PMD_XSTATUS_REG	49153
54e762cd70efad6b6236b084ff7e5ce54a5f524320Ben Hutchings#define PMA_PMD_XSTAT_MDIX_LBN	14
558ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#define PMA_PMD_XSTAT_FLP_LBN   (12)
568ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
578ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings/* LED control register */
58e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define PMA_PMD_LED_CTRL_REG	49159
598ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#define PMA_PMA_LED_ACTIVITY_LBN	(3)
608ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
618ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings/* LED function override register */
62e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define PMA_PMD_LED_OVERR_REG	49161
638ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings/* Bit positions for different LEDs (there are more but not wired on SFE4001)*/
648ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#define PMA_PMD_LED_LINK_LBN	(0)
658ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#define PMA_PMD_LED_SPEED_LBN	(2)
668ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#define PMA_PMD_LED_TX_LBN	(4)
678ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#define PMA_PMD_LED_RX_LBN	(6)
688ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings/* Override settings */
698ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#define	PMA_PMD_LED_AUTO	(0)	/* H/W control */
708ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#define	PMA_PMD_LED_ON		(1)
718ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#define	PMA_PMD_LED_OFF		(2)
728ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#define PMA_PMD_LED_FLASH	(3)
7304cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings#define PMA_PMD_LED_MASK	3
748ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings/* All LEDs under hardware control */
758ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings/* Green and Amber under hardware control, Red off */
76dcf477b2d205abb8ccdb3b1cb668a0db2de202c0Ben Hutchings#define SFX7101_PMA_PMD_LED_DEFAULT (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN)
778ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
78e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define PMA_PMD_SPEED_ENABLE_REG 49192
79e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define PMA_PMD_100TX_ADV_LBN    1
80e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define PMA_PMD_100TX_ADV_WIDTH  1
81e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define PMA_PMD_1000T_ADV_LBN    2
82e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define PMA_PMD_1000T_ADV_WIDTH  1
83e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define PMA_PMD_10000T_ADV_LBN   3
84e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define PMA_PMD_10000T_ADV_WIDTH 1
85e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define PMA_PMD_SPEED_LBN        4
86e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define PMA_PMD_SPEED_WIDTH      4
87e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings
888fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings/* Misc register defines */
89e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define PCS_CLOCK_CTRL_REG	55297
908ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#define PLL312_RST_N_LBN 2
918ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
92e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define PCS_SOFT_RST2_REG	55302
938ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#define SERDES_RST_N_LBN 13
948ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#define XGXS_RST_N_LBN 12
958ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
96e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define	PCS_TEST_SELECT_REG	55303	/* PRM 10.5.8 */
978ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#define	CLK312_EN_LBN 3
988ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
993273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings/* PHYXS registers */
100e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define PHYXS_XCONTROL_REG	49152
101e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define PHYXS_RESET_LBN		15
102e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define PHYXS_RESET_WIDTH	1
103e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings
1043273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings#define PHYXS_TEST1         (49162)
1053273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings#define LOOPBACK_NEAR_LBN   (8)
1063273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings#define LOOPBACK_NEAR_WIDTH (1)
1073273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings
1088ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings/* Boot status register */
109190dbcfd6806c7c88fc028acda95731ffd43979dBen Hutchings#define PCS_BOOT_STATUS_REG		53248
110190dbcfd6806c7c88fc028acda95731ffd43979dBen Hutchings#define PCS_BOOT_FATAL_ERROR_LBN	0
111190dbcfd6806c7c88fc028acda95731ffd43979dBen Hutchings#define PCS_BOOT_PROGRESS_LBN		1
112190dbcfd6806c7c88fc028acda95731ffd43979dBen Hutchings#define PCS_BOOT_PROGRESS_WIDTH		2
113190dbcfd6806c7c88fc028acda95731ffd43979dBen Hutchings#define PCS_BOOT_PROGRESS_INIT		0
114190dbcfd6806c7c88fc028acda95731ffd43979dBen Hutchings#define PCS_BOOT_PROGRESS_WAIT_MDIO	1
115190dbcfd6806c7c88fc028acda95731ffd43979dBen Hutchings#define PCS_BOOT_PROGRESS_CHECKSUM	2
116190dbcfd6806c7c88fc028acda95731ffd43979dBen Hutchings#define PCS_BOOT_PROGRESS_JUMP		3
117190dbcfd6806c7c88fc028acda95731ffd43979dBen Hutchings#define PCS_BOOT_DOWNLOAD_WAIT_LBN	3
118190dbcfd6806c7c88fc028acda95731ffd43979dBen Hutchings#define PCS_BOOT_CODE_STARTED_LBN	4
1198ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
120e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings/* 100M/1G PHY registers */
121e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define GPHY_XCONTROL_REG	49152
122e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define GPHY_ISOLATE_LBN	10
123e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define GPHY_ISOLATE_WIDTH	1
1249c636baf8518d0f986004b40669b75506459beacBen Hutchings#define GPHY_DUPLEX_LBN		8
125e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define GPHY_DUPLEX_WIDTH	1
126e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define GPHY_LOOPBACK_NEAR_LBN	14
127e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define GPHY_LOOPBACK_NEAR_WIDTH 1
128e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings
129e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define C22EXT_STATUS_REG       49153
130e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define C22EXT_STATUS_LINK_LBN  2
131e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings#define C22EXT_STATUS_LINK_WIDTH 1
132e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings
133af4ad9bca0c4039355b20d760b4fd39afa48c59dBen Hutchings#define C22EXT_MSTSLV_CTRL			49161
134af4ad9bca0c4039355b20d760b4fd39afa48c59dBen Hutchings#define C22EXT_MSTSLV_CTRL_ADV_1000_HD_LBN	8
135af4ad9bca0c4039355b20d760b4fd39afa48c59dBen Hutchings#define C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN	9
136af4ad9bca0c4039355b20d760b4fd39afa48c59dBen Hutchings
137af4ad9bca0c4039355b20d760b4fd39afa48c59dBen Hutchings#define C22EXT_MSTSLV_STATUS			49162
138af4ad9bca0c4039355b20d760b4fd39afa48c59dBen Hutchings#define C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN	10
139af4ad9bca0c4039355b20d760b4fd39afa48c59dBen Hutchings#define C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN	11
140e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings
1418ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings/* Time to wait between powering down the LNPGA and turning off the power
1428ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings * rails */
1438ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings#define LNPGA_PDOWN_WAIT	(HZ / 5)
1448ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
1458ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchingsstruct tenxpress_phy_data {
1463273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings	enum efx_loopback_mode loopback_mode;
147f8b87c17017f2ce1890fb9a7f85fb0fbf5643e37Ben Hutchings	enum efx_phy_mode phy_mode;
1488ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	int bad_lp_tries;
1498ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings};
1508ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
1518ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchingsstatic int tenxpress_init(struct efx_nic *efx)
1528ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
1538fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings	/* Enable 312.5 MHz clock */
1548fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings	efx_mdio_write(efx, MDIO_MMD_PCS, PCS_TEST_SELECT_REG,
1558fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings		       1 << CLK312_EN_LBN);
1568ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
1578ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Set the LEDs up as: Green = Link, Amber = Link/Act, Red = Off */
1588fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings	efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_CTRL_REG,
1598fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings			  1 << PMA_PMA_LED_ACTIVITY_LBN, true);
1608fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings	efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG,
1618fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings		       SFX7101_PMA_PMD_LED_DEFAULT);
1628ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
163190dbcfd6806c7c88fc028acda95731ffd43979dBen Hutchings	return 0;
1648ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
1658ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
166ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgsonstatic int tenxpress_phy_probe(struct efx_nic *efx)
167c1c4f453b61463df4df16f7aa5782fc0cfe05b9eBen Hutchings{
168ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson	struct tenxpress_phy_data *phy_data;
169ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson
170ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson	/* Allocate phy private storage */
171ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson	phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL);
172ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson	if (!phy_data)
173ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson		return -ENOMEM;
174ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson	efx->phy_data = phy_data;
175ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson	phy_data->phy_mode = efx->phy_mode;
176ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson
1778fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings	efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS;
1788fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings	efx->mdio.mode_support = MDIO_SUPPORTS_C45;
179ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson
1808fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings	efx->loopback_modes = SFX7101_LOOPBACKS | FALCON_XMAC_LOOPBACKS;
181ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson
1828fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings	efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg |
1838fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings				 ADVERTISED_10000baseT_Full);
184c1c4f453b61463df4df16f7aa5782fc0cfe05b9eBen Hutchings
185c1c4f453b61463df4df16f7aa5782fc0cfe05b9eBen Hutchings	return 0;
186c1c4f453b61463df4df16f7aa5782fc0cfe05b9eBen Hutchings}
187c1c4f453b61463df4df16f7aa5782fc0cfe05b9eBen Hutchings
1888ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchingsstatic int tenxpress_phy_init(struct efx_nic *efx)
1898ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
190ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson	int rc;
1918ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
19244838a447de3b1541cbf845853c4f8999310b0ddBen Hutchings	falcon_board(efx)->type->init_phy(efx);
193981fc1b4b8cc6bfe8c6f0c07052e25738d959c68Ben Hutchings
194e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings	if (!(efx->phy_mode & PHY_MODE_SPECIAL)) {
19568e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings		rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS);
196e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings		if (rc < 0)
197ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson			return rc;
198e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings
199a461103ba2e22cbb70771588b36f40df39a50f46Ben Hutchings		rc = efx_mdio_check_mmds(efx, TENXPRESS_REQUIRED_DEVS);
200e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings		if (rc < 0)
201ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson			return rc;
202e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings	}
2038ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
2048ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	rc = tenxpress_init(efx);
2058ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	if (rc < 0)
206ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson		return rc;
2078ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
208ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson	/* Reinitialise flow control settings */
209d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	efx_link_set_wanted_fc(efx, efx->wanted_fc);
210d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	efx_mdio_an_reconfigure(efx);
211c634263df5890daafe0ea470faee3305736bbc3dBen Hutchings
2128ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	schedule_timeout_uninterruptible(HZ / 5); /* 200ms */
2138ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
214e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings	/* Let XGXS and SerDes out of reset */
2158ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	falcon_reset_xaui(efx);
2168ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
2178ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	return 0;
2188ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
2198ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
220e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings/* Perform a "special software reset" on the PHY. The caller is
221e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings * responsible for saving and restoring the PHY hardware registers
222e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings * properly, and masking/unmasking LASI */
2233273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchingsstatic int tenxpress_special_reset(struct efx_nic *efx)
2243273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings{
2253273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings	int rc, reg;
2263273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings
2278fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings	/* The XGMAC clock is driven from the SFX7101 312MHz clock, so
228c8fcc49c542a2312c706ebf76dcfe5266b39ee13Ben Hutchings	 * a special software reset can glitch the XGMAC sufficiently for stats
2291974cc205e63cec4a17a6b3fca31fa4240ded77eBen Hutchings	 * requests to fail. */
23055edc6e6ff728681ebc10d418222740705376664Ben Hutchings	falcon_stop_nic_stats(efx);
2313273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings
2323273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings	/* Initiate reset */
23368e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG);
2343273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings	reg |= (1 << PMA_PMD_EXT_SSR_LBN);
23568e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg);
2363273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings
237c8fcc49c542a2312c706ebf76dcfe5266b39ee13Ben Hutchings	mdelay(200);
2383273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings
2393273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings	/* Wait for the blocks to come out of reset */
24068e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS);
2413273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings	if (rc < 0)
2421974cc205e63cec4a17a6b3fca31fa4240ded77eBen Hutchings		goto out;
2433273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings
2443273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings	/* Try and reconfigure the device */
2453273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings	rc = tenxpress_init(efx);
2463273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings	if (rc < 0)
2471974cc205e63cec4a17a6b3fca31fa4240ded77eBen Hutchings		goto out;
2483273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings
249e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings	/* Wait for the XGXS state machine to churn */
250e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings	mdelay(10);
2511974cc205e63cec4a17a6b3fca31fa4240ded77eBen Hutchingsout:
25255edc6e6ff728681ebc10d418222740705376664Ben Hutchings	falcon_start_nic_stats(efx);
253c8fcc49c542a2312c706ebf76dcfe5266b39ee13Ben Hutchings	return rc;
2543273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings}
2553273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings
256e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchingsstatic void sfx7101_check_bad_lp(struct efx_nic *efx, bool link_ok)
2578ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
2588ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	struct tenxpress_phy_data *pd = efx->phy_data;
25904cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings	bool bad_lp;
2608ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	int reg;
2618ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
26204cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings	if (link_ok) {
26304cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings		bad_lp = false;
26404cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings	} else {
26504cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings		/* Check that AN has started but not completed. */
26668e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings		reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_STAT1);
26768e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings		if (!(reg & MDIO_AN_STAT1_LPABLE))
26804cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings			return; /* LP status is unknown */
26968e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings		bad_lp = !(reg & MDIO_AN_STAT1_COMPLETE);
27004cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings		if (bad_lp)
27104cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings			pd->bad_lp_tries++;
27204cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings	}
27304cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings
2748ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	/* Nothing to do if all is well and was previously so. */
27504cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings	if (!pd->bad_lp_tries)
2768ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings		return;
2778ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
27804cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings	/* Use the RX (red) LED as an error indicator once we've seen AN
27904cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings	 * failure several times in a row, and also log a message. */
28004cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings	if (!bad_lp || pd->bad_lp_tries == MAX_BAD_LP_TRIES) {
28168e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings		reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD,
28268e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings				    PMA_PMD_LED_OVERR_REG);
28304cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings		reg &= ~(PMA_PMD_LED_MASK << PMA_PMD_LED_RX_LBN);
28404cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings		if (!bad_lp) {
28504cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings			reg |= PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN;
28604cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings		} else {
28704cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings			reg |= PMA_PMD_LED_FLASH << PMA_PMD_LED_RX_LBN;
28862776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings			netif_err(efx, link, efx->net_dev,
28962776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings				  "appears to be plugged into a port"
29062776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings				  " that is not 10GBASE-T capable. The PHY"
29162776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings				  " supports 10GBASE-T ONLY, so no link can"
29262776d034cc40c49bafdb3551a6ba35f78e3f08dBen Hutchings				  " be established\n");
29304cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings		}
29468e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings		efx_mdio_write(efx, MDIO_MMD_PMAPMD,
29568e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings			       PMA_PMD_LED_OVERR_REG, reg);
29604cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings		pd->bad_lp_tries = bad_lp;
2978ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	}
2988ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
2998ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
300e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchingsstatic bool sfx7101_link_ok(struct efx_nic *efx)
3018ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
30268e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	return efx_mdio_links_ok(efx,
30368e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings				 MDIO_DEVS_PMAPMD |
30468e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings				 MDIO_DEVS_PCS |
30568e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings				 MDIO_DEVS_PHYXS);
306e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings}
307e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings
308e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchingsstatic void tenxpress_ext_loopback(struct efx_nic *efx)
3093273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings{
31068e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	efx_mdio_set_flag(efx, MDIO_MMD_PHYXS, PHYXS_TEST1,
31168e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings			  1 << LOOPBACK_NEAR_LBN,
31268e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings			  efx->loopback_mode == LOOPBACK_PHYXS);
313e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings}
314e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings
315e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchingsstatic void tenxpress_low_power(struct efx_nic *efx)
316e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings{
3178fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings	efx_mdio_set_mmds_lpower(
3188fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings		efx, !!(efx->phy_mode & PHY_MODE_LOW_POWER),
3198fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings		TENXPRESS_REQUIRED_DEVS);
3203273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings}
3213273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings
322d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchingsstatic int tenxpress_phy_reconfigure(struct efx_nic *efx)
3238ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
3243273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings	struct tenxpress_phy_data *phy_data = efx->phy_data;
3258b9dc8dd447cfe27c0214761ced22a8e4aa58f5eSteve Hodgson	bool phy_mode_change, loop_reset;
3263273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings
327e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings	if (efx->phy_mode & (PHY_MODE_OFF | PHY_MODE_SPECIAL)) {
328f8b87c17017f2ce1890fb9a7f85fb0fbf5643e37Ben Hutchings		phy_data->phy_mode = efx->phy_mode;
329d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings		return 0;
330f8b87c17017f2ce1890fb9a7f85fb0fbf5643e37Ben Hutchings	}
3318ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
332e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings	phy_mode_change = (efx->phy_mode == PHY_MODE_NORMAL &&
333e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings			   phy_data->phy_mode != PHY_MODE_NORMAL);
334c1c4f453b61463df4df16f7aa5782fc0cfe05b9eBen Hutchings	loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, LOOPBACKS_EXTERNAL(efx)) ||
335e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings		      LOOPBACK_CHANGED(phy_data, efx, 1 << LOOPBACK_GPHY));
336e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings
3378b9dc8dd447cfe27c0214761ced22a8e4aa58f5eSteve Hodgson	if (loop_reset || phy_mode_change) {
338d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings		tenxpress_special_reset(efx);
3398fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings		falcon_reset_xaui(efx);
3403273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings	}
3413273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings
342d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	tenxpress_low_power(efx);
34368e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	efx_mdio_transmit_disable(efx);
34468e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	efx_mdio_phy_reconfigure(efx);
345e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings	tenxpress_ext_loopback(efx);
346d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	efx_mdio_an_reconfigure(efx);
3473273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings
3483273c2e8c66a21ae1c53b0c730ee937c6efde7e2Ben Hutchings	phy_data->loopback_mode = efx->loopback_mode;
349f8b87c17017f2ce1890fb9a7f85fb0fbf5643e37Ben Hutchings	phy_data->phy_mode = efx->phy_mode;
350d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings
351d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	return 0;
3528ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
3538ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
354fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgsonstatic void
355fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgsontenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd);
356fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson
357fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson/* Poll for link state changes */
358fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgsonstatic bool tenxpress_phy_poll(struct efx_nic *efx)
3598ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
360fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson	struct efx_link_state old_state = efx->link_state;
3618ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
3628fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings	efx->link_state.up = sfx7101_link_ok(efx);
3638fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings	efx->link_state.speed = 10000;
3648fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings	efx->link_state.fd = true;
3658fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings	efx->link_state.fc = efx_mdio_get_pause(efx);
3668ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
3678fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings	sfx7101_check_bad_lp(efx, efx->link_state.up);
368fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson
369fdaa9aed21c8c8b529f3c94a5ffa138bf3360b75Steve Hodgson	return !efx_link_state_equal(&efx->link_state, &old_state);
3708ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
3718ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
372ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgsonstatic void sfx7101_phy_fini(struct efx_nic *efx)
3738ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
3748ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	int reg;
3758ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
376ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson	/* Power down the LNPGA */
377ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson	reg = (1 << PMA_PMD_LNPGA_POWERDOWN_LBN);
378ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson	efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg);
379ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson
380ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson	/* Waiting here ensures that the board fini, which can turn
381ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson	 * off the power to the PHY, won't get run until the LNPGA
382ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson	 * powerdown has been given long enough to complete. */
383ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson	schedule_timeout_uninterruptible(LNPGA_PDOWN_WAIT); /* 200 ms */
384ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson}
385ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson
386ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgsonstatic void tenxpress_phy_remove(struct efx_nic *efx)
387ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson{
3888ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	kfree(efx->phy_data);
3898ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	efx->phy_data = NULL;
3908ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
3918ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
3928ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
393398468ed1b5c61fe8bcbc8cc1ed323e3c23b58efBen Hutchings/* Override the RX, TX and link LEDs */
394398468ed1b5c61fe8bcbc8cc1ed323e3c23b58efBen Hutchingsvoid tenxpress_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
3958ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings{
3968ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	int reg;
3978ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
398398468ed1b5c61fe8bcbc8cc1ed323e3c23b58efBen Hutchings	switch (mode) {
399398468ed1b5c61fe8bcbc8cc1ed323e3c23b58efBen Hutchings	case EFX_LED_OFF:
400398468ed1b5c61fe8bcbc8cc1ed323e3c23b58efBen Hutchings		reg = (PMA_PMD_LED_OFF << PMA_PMD_LED_TX_LBN) |
401398468ed1b5c61fe8bcbc8cc1ed323e3c23b58efBen Hutchings			(PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN) |
402398468ed1b5c61fe8bcbc8cc1ed323e3c23b58efBen Hutchings			(PMA_PMD_LED_OFF << PMA_PMD_LED_LINK_LBN);
403398468ed1b5c61fe8bcbc8cc1ed323e3c23b58efBen Hutchings		break;
404398468ed1b5c61fe8bcbc8cc1ed323e3c23b58efBen Hutchings	case EFX_LED_ON:
405398468ed1b5c61fe8bcbc8cc1ed323e3c23b58efBen Hutchings		reg = (PMA_PMD_LED_ON << PMA_PMD_LED_TX_LBN) |
406398468ed1b5c61fe8bcbc8cc1ed323e3c23b58efBen Hutchings			(PMA_PMD_LED_ON << PMA_PMD_LED_RX_LBN) |
407398468ed1b5c61fe8bcbc8cc1ed323e3c23b58efBen Hutchings			(PMA_PMD_LED_ON << PMA_PMD_LED_LINK_LBN);
408398468ed1b5c61fe8bcbc8cc1ed323e3c23b58efBen Hutchings		break;
409398468ed1b5c61fe8bcbc8cc1ed323e3c23b58efBen Hutchings	default:
4108fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings		reg = SFX7101_PMA_PMD_LED_DEFAULT;
411398468ed1b5c61fe8bcbc8cc1ed323e3c23b58efBen Hutchings		break;
412398468ed1b5c61fe8bcbc8cc1ed323e3c23b58efBen Hutchings	}
4138ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
41468e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG, reg);
4158ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings}
4168ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings
417307505e9a4ce0b13b2f996385669039806e07390Ben Hutchingsstatic const char *const sfx7101_test_names[] = {
4181796721a5a691a5d392abf8070ad40a0b787b667Ben Hutchings	"bist"
4191796721a5a691a5d392abf8070ad40a0b787b667Ben Hutchings};
4201796721a5a691a5d392abf8070ad40a0b787b667Ben Hutchings
421c1c4f453b61463df4df16f7aa5782fc0cfe05b9eBen Hutchingsstatic const char *sfx7101_test_name(struct efx_nic *efx, unsigned int index)
422c1c4f453b61463df4df16f7aa5782fc0cfe05b9eBen Hutchings{
423c1c4f453b61463df4df16f7aa5782fc0cfe05b9eBen Hutchings	if (index < ARRAY_SIZE(sfx7101_test_names))
424c1c4f453b61463df4df16f7aa5782fc0cfe05b9eBen Hutchings		return sfx7101_test_names[index];
425c1c4f453b61463df4df16f7aa5782fc0cfe05b9eBen Hutchings	return NULL;
426c1c4f453b61463df4df16f7aa5782fc0cfe05b9eBen Hutchings}
427c1c4f453b61463df4df16f7aa5782fc0cfe05b9eBen Hutchings
4281796721a5a691a5d392abf8070ad40a0b787b667Ben Hutchingsstatic int
429307505e9a4ce0b13b2f996385669039806e07390Ben Hutchingssfx7101_run_tests(struct efx_nic *efx, int *results, unsigned flags)
4308c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings{
4311796721a5a691a5d392abf8070ad40a0b787b667Ben Hutchings	int rc;
4321796721a5a691a5d392abf8070ad40a0b787b667Ben Hutchings
4331796721a5a691a5d392abf8070ad40a0b787b667Ben Hutchings	if (!(flags & ETH_TEST_FL_OFFLINE))
4341796721a5a691a5d392abf8070ad40a0b787b667Ben Hutchings		return 0;
4351796721a5a691a5d392abf8070ad40a0b787b667Ben Hutchings
4368c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings	/* BIST is automatically run after a special software reset */
4371796721a5a691a5d392abf8070ad40a0b787b667Ben Hutchings	rc = tenxpress_special_reset(efx);
4381796721a5a691a5d392abf8070ad40a0b787b667Ben Hutchings	results[0] = rc ? -1 : 1;
439d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings
440d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings	efx_mdio_an_reconfigure(efx);
441d3245b28ef2a45ec4e115062a38100bd06229289Ben Hutchings
4421796721a5a691a5d392abf8070ad40a0b787b667Ben Hutchings	return rc;
4438c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings}
4448c8661e4cefdd1ddbfe7d5120f046694555d9e5cBen Hutchings
445af4ad9bca0c4039355b20d760b4fd39afa48c59dBen Hutchingsstatic void
446af4ad9bca0c4039355b20d760b4fd39afa48c59dBen Hutchingstenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
44704cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings{
448af4ad9bca0c4039355b20d760b4fd39afa48c59dBen Hutchings	u32 adv = 0, lpa = 0;
44904cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings	int reg;
45004cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings
45168e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL);
45268e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	if (reg & MDIO_AN_10GBT_CTRL_ADV10G)
453af4ad9bca0c4039355b20d760b4fd39afa48c59dBen Hutchings		adv |= ADVERTISED_10000baseT_Full;
45468e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_10GBT_STAT);
45568e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	if (reg & MDIO_AN_10GBT_STAT_LP10G)
45604cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings		lpa |= ADVERTISED_10000baseT_Full;
45704cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings
45868e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	mdio45_ethtool_gset_npage(&efx->mdio, ecmd, adv, lpa);
459e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings
4608b9dc8dd447cfe27c0214761ced22a8e4aa58f5eSteve Hodgson	/* In loopback, the PHY automatically brings up the correct interface,
4618b9dc8dd447cfe27c0214761ced22a8e4aa58f5eSteve Hodgson	 * but doesn't advertise the correct speed. So override it */
4628fbca791309b5a57bec53e5fd7da912c16416ed3Ben Hutchings	if (LOOPBACK_EXTERNAL(efx))
463707394972093e2056e1e8cc39be19cf9bcb3e7b3David Decotigny		ethtool_cmd_speed_set(ecmd, SPEED_10000);
46404cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings}
46504cc8cacb01c09fba2297faf1477cd570ba43f0bBen Hutchings
466af4ad9bca0c4039355b20d760b4fd39afa48c59dBen Hutchingsstatic int tenxpress_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
467e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings{
468af4ad9bca0c4039355b20d760b4fd39afa48c59dBen Hutchings	if (!ecmd->autoneg)
469af4ad9bca0c4039355b20d760b4fd39afa48c59dBen Hutchings		return -EINVAL;
470e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings
47168e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	return efx_mdio_set_settings(efx, ecmd);
472e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings}
473e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings
474af4ad9bca0c4039355b20d760b4fd39afa48c59dBen Hutchingsstatic void sfx7101_set_npage_adv(struct efx_nic *efx, u32 advertising)
475e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings{
47668e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings	efx_mdio_set_flag(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
47768e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings			  MDIO_AN_10GBT_CTRL_ADV10G,
47868e7f45e118f98b77cfa007aa2d97b5dac69fe6bBen Hutchings			  advertising & ADVERTISED_10000baseT_Full);
479e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings}
480e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings
4816c8c2513c86c589a819c161c9abbdea2a3d56f5estephen hemmingerconst struct efx_phy_operations falcon_sfx7101_phy_ops = {
482ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson	.probe		  = tenxpress_phy_probe,
4838ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	.init             = tenxpress_phy_init,
4848ceee660aacb29721e26f08e336c58dc4847d1bdBen Hutchings	.reconfigure      = tenxpress_phy_reconfigure,
485766ca0fa6bf1600bdf4bc7726c74f14c8455c6b8Ben Hutchings	.poll             = tenxpress_phy_poll,
486ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson	.fini             = sfx7101_phy_fini,
487ff3b00a0fcaab89ff885e9f0f4ad83c4ced788f4Steve Hodgson	.remove		  = tenxpress_phy_remove,
488af4ad9bca0c4039355b20d760b4fd39afa48c59dBen Hutchings	.get_settings	  = tenxpress_get_settings,
489af4ad9bca0c4039355b20d760b4fd39afa48c59dBen Hutchings	.set_settings	  = tenxpress_set_settings,
490af4ad9bca0c4039355b20d760b4fd39afa48c59dBen Hutchings	.set_npage_adv    = sfx7101_set_npage_adv,
4914f16c0739145476ba37a7fa9eea0c33850efc2ceBen Hutchings	.test_alive	  = efx_mdio_test_alive,
492c1c4f453b61463df4df16f7aa5782fc0cfe05b9eBen Hutchings	.test_name	  = sfx7101_test_name,
493307505e9a4ce0b13b2f996385669039806e07390Ben Hutchings	.run_tests	  = sfx7101_run_tests,
494e6fa2eb789f49dc51a20d3db0d410bc8158abb43Ben Hutchings};
495