aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2008-12-13 01:00:17 -0500
committerDavid S. Miller <davem@davemloft.net>2008-12-13 01:00:17 -0500
commite6fa2eb789f49dc51a20d3db0d410bc8158abb43 (patch)
tree4b61712a720b2f90b47fe69127a76f258e3322f8 /drivers
parent766ca0fa6bf1600bdf4bc7726c74f14c8455c6b8 (diff)
sfc: Add support for Solarflare 10Xpress SFT9001
Add type codes for the new PHY and rename the SFX7101 type code. Add definition of clause 22 extension MMD. Adapt the 10Xpress SFX7101 code to support the SFT9001 as well. Clean up register definitions. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/sfc/enum.h3
-rw-r--r--drivers/net/sfc/ethtool.c3
-rw-r--r--drivers/net/sfc/falcon.c10
-rw-r--r--drivers/net/sfc/mdio_10g.h8
-rw-r--r--drivers/net/sfc/net_driver.h4
-rw-r--r--drivers/net/sfc/phy.h7
-rw-r--r--drivers/net/sfc/tenxpress.c528
-rw-r--r--drivers/net/sfc/workarounds.h9
8 files changed, 467 insertions, 105 deletions
diff --git a/drivers/net/sfc/enum.h b/drivers/net/sfc/enum.h
index 0c2e41ce8b4a..60cbc6e1e66b 100644
--- a/drivers/net/sfc/enum.h
+++ b/drivers/net/sfc/enum.h
@@ -58,6 +58,9 @@ extern const char *efx_loopback_mode_names[];
58#define LOOPBACK_INTERNAL(_efx) \ 58#define LOOPBACK_INTERNAL(_efx) \
59 (!!(LOOPBACKS_INTERNAL & LOOPBACK_MASK(_efx))) 59 (!!(LOOPBACKS_INTERNAL & LOOPBACK_MASK(_efx)))
60 60
61#define LOOPBACK_CHANGED(_from, _to, _mask) \
62 (!!((LOOPBACK_MASK(_from) ^ LOOPBACK_MASK(_to)) & (_mask)))
63
61#define LOOPBACK_OUT_OF(_from, _to, _mask) \ 64#define LOOPBACK_OUT_OF(_from, _to, _mask) \
62 ((LOOPBACK_MASK(_from) & (_mask)) && !(LOOPBACK_MASK(_to) & (_mask))) 65 ((LOOPBACK_MASK(_from) & (_mask)) && !(LOOPBACK_MASK(_to) & (_mask)))
63 66
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index 0e81af6d8348..aad0d1b36e1c 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -219,6 +219,9 @@ int efx_ethtool_set_settings(struct net_device *net_dev,
219 struct efx_nic *efx = netdev_priv(net_dev); 219 struct efx_nic *efx = netdev_priv(net_dev);
220 int rc; 220 int rc;
221 221
222 if (EFX_WORKAROUND_13963(efx) && !ecmd->autoneg)
223 return -EINVAL;
224
222 /* Falcon GMAC does not support 1000Mbps HD */ 225 /* Falcon GMAC does not support 1000Mbps HD */
223 if (ecmd->speed == SPEED_1000 && ecmd->duplex != DUPLEX_FULL) { 226 if (ecmd->speed == SPEED_1000 && ecmd->duplex != DUPLEX_FULL) {
224 EFX_LOG(efx, "rejecting unsupported 1000Mbps HD" 227 EFX_LOG(efx, "rejecting unsupported 1000Mbps HD"
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 5a70ee7e8142..db8e147f00b2 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -826,7 +826,7 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
826#endif 826#endif
827 827
828 if (unlikely(rx_ev_eth_crc_err && EFX_WORKAROUND_10750(efx) && 828 if (unlikely(rx_ev_eth_crc_err && EFX_WORKAROUND_10750(efx) &&
829 efx->phy_type == PHY_TYPE_10XPRESS)) 829 efx->phy_type == PHY_TYPE_SFX7101))
830 tenxpress_crc_err(efx); 830 tenxpress_crc_err(efx);
831} 831}
832 832
@@ -2245,8 +2245,12 @@ static void falcon_init_mdio(struct mii_if_info *gmii)
2245static int falcon_probe_phy(struct efx_nic *efx) 2245static int falcon_probe_phy(struct efx_nic *efx)
2246{ 2246{
2247 switch (efx->phy_type) { 2247 switch (efx->phy_type) {
2248 case PHY_TYPE_10XPRESS: 2248 case PHY_TYPE_SFX7101:
2249 efx->phy_op = &falcon_tenxpress_phy_ops; 2249 efx->phy_op = &falcon_sfx7101_phy_ops;
2250 break;
2251 case PHY_TYPE_SFT9001A:
2252 case PHY_TYPE_SFT9001B:
2253 efx->phy_op = &falcon_sft9001_phy_ops;
2250 break; 2254 break;
2251 case PHY_TYPE_XFP: 2255 case PHY_TYPE_XFP:
2252 efx->phy_op = &falcon_xfp_phy_ops; 2256 efx->phy_op = &falcon_xfp_phy_ops;
diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h
index 80c63dde8864..409118228b1d 100644
--- a/drivers/net/sfc/mdio_10g.h
+++ b/drivers/net/sfc/mdio_10g.h
@@ -33,6 +33,8 @@
33#define MDIO_MMD_TC (6) 33#define MDIO_MMD_TC (6)
34/* Auto negotiation */ 34/* Auto negotiation */
35#define MDIO_MMD_AN (7) 35#define MDIO_MMD_AN (7)
36/* Clause 22 extension */
37#define MDIO_MMD_C22EXT 29
36 38
37/* Generic register locations */ 39/* Generic register locations */
38#define MDIO_MMDREG_CTRL1 (0) 40#define MDIO_MMDREG_CTRL1 (0)
@@ -82,6 +84,7 @@
82#define MDIO_MMDREG_DEVS_PCS DEV_PRESENT_BIT(MDIO_MMD_PCS) 84#define MDIO_MMDREG_DEVS_PCS DEV_PRESENT_BIT(MDIO_MMD_PCS)
83#define MDIO_MMDREG_DEVS_PMAPMD DEV_PRESENT_BIT(MDIO_MMD_PMAPMD) 85#define MDIO_MMDREG_DEVS_PMAPMD DEV_PRESENT_BIT(MDIO_MMD_PMAPMD)
84#define MDIO_MMDREG_DEVS_AN DEV_PRESENT_BIT(MDIO_MMD_AN) 86#define MDIO_MMDREG_DEVS_AN DEV_PRESENT_BIT(MDIO_MMD_AN)
87#define MDIO_MMDREG_DEVS_C22EXT DEV_PRESENT_BIT(MDIO_MMD_C22EXT)
85 88
86/* Bits in MMDREG_SPEED */ 89/* Bits in MMDREG_SPEED */
87#define MDIO_MMDREG_SPEED_10G_LBN 0 90#define MDIO_MMDREG_SPEED_10G_LBN 0
@@ -125,6 +128,11 @@
125#define MDIO_PMAPMD_CTRL2_10_BT (0xf) 128#define MDIO_PMAPMD_CTRL2_10_BT (0xf)
126#define MDIO_PMAPMD_CTRL2_TYPE_MASK (0xf) 129#define MDIO_PMAPMD_CTRL2_TYPE_MASK (0xf)
127 130
131/* PMA 10GBT registers */
132#define MDIO_PMAPMD_10GBT_TXPWR (131)
133#define MDIO_PMAPMD_10GBT_TXPWR_SHORT_LBN (0)
134#define MDIO_PMAPMD_10GBT_TXPWR_SHORT_WIDTH (1)
135
128/* PHY XGXS lane state */ 136/* PHY XGXS lane state */
129#define MDIO_PHYXS_LANE_STATE (0x18) 137#define MDIO_PHYXS_LANE_STATE (0x18)
130#define MDIO_PHYXS_LANE_ALIGNED_LBN (12) 138#define MDIO_PHYXS_LANE_ALIGNED_LBN (12)
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 61d09a2fa724..17283293302a 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -455,9 +455,11 @@ enum phy_type {
455 PHY_TYPE_NONE = 0, 455 PHY_TYPE_NONE = 0,
456 PHY_TYPE_CX4_RTMR = 1, 456 PHY_TYPE_CX4_RTMR = 1,
457 PHY_TYPE_1G_ALASKA = 2, 457 PHY_TYPE_1G_ALASKA = 2,
458 PHY_TYPE_10XPRESS = 3, 458 PHY_TYPE_SFX7101 = 3,
459 PHY_TYPE_XFP = 4, 459 PHY_TYPE_XFP = 4,
460 PHY_TYPE_PM8358 = 6, 460 PHY_TYPE_PM8358 = 6,
461 PHY_TYPE_SFT9001A = 8,
462 PHY_TYPE_SFT9001B = 10,
461 PHY_TYPE_MAX /* Insert any new items before this */ 463 PHY_TYPE_MAX /* Insert any new items before this */
462}; 464};
463 465
diff --git a/drivers/net/sfc/phy.h b/drivers/net/sfc/phy.h
index f746536f4ffa..58c493ef81bb 100644
--- a/drivers/net/sfc/phy.h
+++ b/drivers/net/sfc/phy.h
@@ -1,6 +1,6 @@
1/**************************************************************************** 1/****************************************************************************
2 * Driver for Solarflare Solarstorm network controllers and boards 2 * Driver for Solarflare Solarstorm network controllers and boards
3 * Copyright 2007 Solarflare Communications Inc. 3 * Copyright 2007-2008 Solarflare Communications Inc.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published 6 * under the terms of the GNU General Public License version 2 as published
@@ -11,9 +11,10 @@
11#define EFX_PHY_H 11#define EFX_PHY_H
12 12
13/**************************************************************************** 13/****************************************************************************
14 * 10Xpress (SFX7101) PHY 14 * 10Xpress (SFX7101 and SFT9001) PHYs
15 */ 15 */
16extern struct efx_phy_operations falcon_tenxpress_phy_ops; 16extern struct efx_phy_operations falcon_sfx7101_phy_ops;
17extern struct efx_phy_operations falcon_sft9001_phy_ops;
17 18
18extern void tenxpress_phy_blink(struct efx_nic *efx, bool blink); 19extern void tenxpress_phy_blink(struct efx_nic *efx, bool blink);
19extern void tenxpress_crc_err(struct efx_nic *efx); 20extern void tenxpress_crc_err(struct efx_nic *efx);
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index 7256ea4abf9c..b3ca2dc8040d 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -15,38 +15,71 @@
15#include "phy.h" 15#include "phy.h"
16#include "falcon_hwdefs.h" 16#include "falcon_hwdefs.h"
17#include "boards.h" 17#include "boards.h"
18#include "workarounds.h"
19#include "selftest.h"
18 20
19/* We expect these MMDs to be in the package */ 21/* We expect these MMDs to be in the package. SFT9001 also has a
22 * clause 22 extension MMD, but since it doesn't have all the generic
23 * MMD registers it is pointless to include it here.
24 */
20#define TENXPRESS_REQUIRED_DEVS (MDIO_MMDREG_DEVS_PMAPMD | \ 25#define TENXPRESS_REQUIRED_DEVS (MDIO_MMDREG_DEVS_PMAPMD | \
21 MDIO_MMDREG_DEVS_PCS | \ 26 MDIO_MMDREG_DEVS_PCS | \
22 MDIO_MMDREG_DEVS_PHYXS | \ 27 MDIO_MMDREG_DEVS_PHYXS | \
23 MDIO_MMDREG_DEVS_AN) 28 MDIO_MMDREG_DEVS_AN)
24 29
25#define TENXPRESS_LOOPBACKS ((1 << LOOPBACK_PHYXS) | \ 30#define SFX7101_LOOPBACKS ((1 << LOOPBACK_PHYXS) | \
26 (1 << LOOPBACK_PCS) | \ 31 (1 << LOOPBACK_PCS) | \
27 (1 << LOOPBACK_PMAPMD) | \ 32 (1 << LOOPBACK_PMAPMD) | \
28 (1 << LOOPBACK_NETWORK)) 33 (1 << LOOPBACK_NETWORK))
34
35#define SFT9001_LOOPBACKS ((1 << LOOPBACK_GPHY) | \
36 (1 << LOOPBACK_PHYXS) | \
37 (1 << LOOPBACK_PCS) | \
38 (1 << LOOPBACK_PMAPMD) | \
39 (1 << LOOPBACK_NETWORK))
29 40
30/* We complain if we fail to see the link partner as 10G capable this many 41/* We complain if we fail to see the link partner as 10G capable this many
31 * times in a row (must be > 1 as sampling the autoneg. registers is racy) 42 * times in a row (must be > 1 as sampling the autoneg. registers is racy)
32 */ 43 */
33#define MAX_BAD_LP_TRIES (5) 44#define MAX_BAD_LP_TRIES (5)
34 45
46/* LASI Control */
47#define PMA_PMD_LASI_CTRL 36866
48#define PMA_PMD_LASI_STATUS 36869
49#define PMA_PMD_LS_ALARM_LBN 0
50#define PMA_PMD_LS_ALARM_WIDTH 1
51#define PMA_PMD_TX_ALARM_LBN 1
52#define PMA_PMD_TX_ALARM_WIDTH 1
53#define PMA_PMD_RX_ALARM_LBN 2
54#define PMA_PMD_RX_ALARM_WIDTH 1
55#define PMA_PMD_AN_ALARM_LBN 3
56#define PMA_PMD_AN_ALARM_WIDTH 1
57
35/* Extended control register */ 58/* Extended control register */
36#define PMA_PMD_XCONTROL_REG 0xc000 59#define PMA_PMD_XCONTROL_REG 49152
37#define PMA_PMD_LNPGA_POWERDOWN_LBN 8 60#define PMA_PMD_EXT_GMII_EN_LBN 1
38#define PMA_PMD_LNPGA_POWERDOWN_WIDTH 1 61#define PMA_PMD_EXT_GMII_EN_WIDTH 1
62#define PMA_PMD_EXT_CLK_OUT_LBN 2
63#define PMA_PMD_EXT_CLK_OUT_WIDTH 1
64#define PMA_PMD_LNPGA_POWERDOWN_LBN 8 /* SFX7101 only */
65#define PMA_PMD_LNPGA_POWERDOWN_WIDTH 1
66#define PMA_PMD_EXT_CLK312_LBN 8 /* SFT9001 only */
67#define PMA_PMD_EXT_CLK312_WIDTH 1
68#define PMA_PMD_EXT_LPOWER_LBN 12
69#define PMA_PMD_EXT_LPOWER_WIDTH 1
70#define PMA_PMD_EXT_SSR_LBN 15
71#define PMA_PMD_EXT_SSR_WIDTH 1
39 72
40/* extended status register */ 73/* extended status register */
41#define PMA_PMD_XSTATUS_REG 0xc001 74#define PMA_PMD_XSTATUS_REG 49153
42#define PMA_PMD_XSTAT_FLP_LBN (12) 75#define PMA_PMD_XSTAT_FLP_LBN (12)
43 76
44/* LED control register */ 77/* LED control register */
45#define PMA_PMD_LED_CTRL_REG (0xc007) 78#define PMA_PMD_LED_CTRL_REG 49159
46#define PMA_PMA_LED_ACTIVITY_LBN (3) 79#define PMA_PMA_LED_ACTIVITY_LBN (3)
47 80
48/* LED function override register */ 81/* LED function override register */
49#define PMA_PMD_LED_OVERR_REG (0xc009) 82#define PMA_PMD_LED_OVERR_REG 49161
50/* Bit positions for different LEDs (there are more but not wired on SFE4001)*/ 83/* Bit positions for different LEDs (there are more but not wired on SFE4001)*/
51#define PMA_PMD_LED_LINK_LBN (0) 84#define PMA_PMD_LED_LINK_LBN (0)
52#define PMA_PMD_LED_SPEED_LBN (2) 85#define PMA_PMD_LED_SPEED_LBN (2)
@@ -63,36 +96,74 @@
63/* Green and Amber under hardware control, Red off */ 96/* Green and Amber under hardware control, Red off */
64#define PMA_PMD_LED_DEFAULT (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN) 97#define PMA_PMD_LED_DEFAULT (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN)
65 98
66 99#define PMA_PMD_SPEED_ENABLE_REG 49192
67/* Special Software reset register */ 100#define PMA_PMD_100TX_ADV_LBN 1
68#define PMA_PMD_EXT_CTRL_REG 49152 101#define PMA_PMD_100TX_ADV_WIDTH 1
69#define PMA_PMD_EXT_SSR_LBN 15 102#define PMA_PMD_1000T_ADV_LBN 2
70 103#define PMA_PMD_1000T_ADV_WIDTH 1
71/* Misc register defines */ 104#define PMA_PMD_10000T_ADV_LBN 3
72#define PCS_CLOCK_CTRL_REG 0xd801 105#define PMA_PMD_10000T_ADV_WIDTH 1
106#define PMA_PMD_SPEED_LBN 4
107#define PMA_PMD_SPEED_WIDTH 4
108
109/* Serdes control registers - SFT9001 only */
110#define PMA_PMD_CSERDES_CTRL_REG 64258
111/* Set the 156.25 MHz output to 312.5 MHz to drive Falcon's XMAC */
112#define PMA_PMD_CSERDES_DEFAULT 0x000f
113
114/* Misc register defines - SFX7101 only */
115#define PCS_CLOCK_CTRL_REG 55297
73#define PLL312_RST_N_LBN 2 116#define PLL312_RST_N_LBN 2
74 117
75#define PCS_SOFT_RST2_REG 0xd806 118#define PCS_SOFT_RST2_REG 55302
76#define SERDES_RST_N_LBN 13 119#define SERDES_RST_N_LBN 13
77#define XGXS_RST_N_LBN 12 120#define XGXS_RST_N_LBN 12
78 121
79#define PCS_TEST_SELECT_REG 0xd807 /* PRM 10.5.8 */ 122#define PCS_TEST_SELECT_REG 55303 /* PRM 10.5.8 */
80#define CLK312_EN_LBN 3 123#define CLK312_EN_LBN 3
81 124
82/* PHYXS registers */ 125/* PHYXS registers */
126#define PHYXS_XCONTROL_REG 49152
127#define PHYXS_RESET_LBN 15
128#define PHYXS_RESET_WIDTH 1
129
83#define PHYXS_TEST1 (49162) 130#define PHYXS_TEST1 (49162)
84#define LOOPBACK_NEAR_LBN (8) 131#define LOOPBACK_NEAR_LBN (8)
85#define LOOPBACK_NEAR_WIDTH (1) 132#define LOOPBACK_NEAR_WIDTH (1)
86 133
134#define PCS_10GBASET_STAT1 32
135#define PCS_10GBASET_BLKLK_LBN 0
136#define PCS_10GBASET_BLKLK_WIDTH 1
137
87/* Boot status register */ 138/* Boot status register */
88#define PCS_BOOT_STATUS_REG (0xd000) 139#define PCS_BOOT_STATUS_REG 53248
89#define PCS_BOOT_FATAL_ERR_LBN (0) 140#define PCS_BOOT_FATAL_ERR_LBN (0)
90#define PCS_BOOT_PROGRESS_LBN (1) 141#define PCS_BOOT_PROGRESS_LBN (1)
91#define PCS_BOOT_PROGRESS_WIDTH (2) 142#define PCS_BOOT_PROGRESS_WIDTH (2)
92#define PCS_BOOT_COMPLETE_LBN (3) 143#define PCS_BOOT_COMPLETE_LBN (3)
144
93#define PCS_BOOT_MAX_DELAY (100) 145#define PCS_BOOT_MAX_DELAY (100)
94#define PCS_BOOT_POLL_DELAY (10) 146#define PCS_BOOT_POLL_DELAY (10)
95 147
148/* 100M/1G PHY registers */
149#define GPHY_XCONTROL_REG 49152
150#define GPHY_ISOLATE_LBN 10
151#define GPHY_ISOLATE_WIDTH 1
152#define GPHY_DUPLEX_LBN 8
153#define GPHY_DUPLEX_WIDTH 1
154#define GPHY_LOOPBACK_NEAR_LBN 14
155#define GPHY_LOOPBACK_NEAR_WIDTH 1
156
157#define C22EXT_STATUS_REG 49153
158#define C22EXT_STATUS_LINK_LBN 2
159#define C22EXT_STATUS_LINK_WIDTH 1
160
161#define C22EXT_MSTSLV_REG 49162
162#define C22EXT_MSTSLV_1000_HD_LBN 10
163#define C22EXT_MSTSLV_1000_HD_WIDTH 1
164#define C22EXT_MSTSLV_1000_FD_LBN 11
165#define C22EXT_MSTSLV_1000_FD_WIDTH 1
166
96/* Time to wait between powering down the LNPGA and turning off the power 167/* Time to wait between powering down the LNPGA and turning off the power
97 * rails */ 168 * rails */
98#define LNPGA_PDOWN_WAIT (HZ / 5) 169#define LNPGA_PDOWN_WAIT (HZ / 5)
@@ -116,6 +187,38 @@ void tenxpress_crc_err(struct efx_nic *efx)
116 atomic_inc(&phy_data->bad_crc_count); 187 atomic_inc(&phy_data->bad_crc_count);
117} 188}
118 189
190static ssize_t show_phy_short_reach(struct device *dev,
191 struct device_attribute *attr, char *buf)
192{
193 struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
194 int reg;
195
196 reg = mdio_clause45_read(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
197 MDIO_PMAPMD_10GBT_TXPWR);
198 return sprintf(buf, "%d\n",
199 !!(reg & (1 << MDIO_PMAPMD_10GBT_TXPWR_SHORT_LBN)));
200}
201
202static ssize_t set_phy_short_reach(struct device *dev,
203 struct device_attribute *attr,
204 const char *buf, size_t count)
205{
206 struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
207
208 rtnl_lock();
209 mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
210 MDIO_PMAPMD_10GBT_TXPWR,
211 MDIO_PMAPMD_10GBT_TXPWR_SHORT_LBN,
212 count != 0 && *buf != '0');
213 efx_reconfigure_port(efx);
214 rtnl_unlock();
215
216 return count;
217}
218
219static DEVICE_ATTR(phy_short_reach, 0644, show_phy_short_reach,
220 set_phy_short_reach);
221
119/* Check that the C166 has booted successfully */ 222/* Check that the C166 has booted successfully */
120static int tenxpress_phy_check(struct efx_nic *efx) 223static int tenxpress_phy_check(struct efx_nic *efx)
121{ 224{
@@ -147,27 +250,42 @@ static int tenxpress_phy_check(struct efx_nic *efx)
147 250
148static int tenxpress_init(struct efx_nic *efx) 251static int tenxpress_init(struct efx_nic *efx)
149{ 252{
150 int rc, reg; 253 int phy_id = efx->mii.phy_id;
254 int reg;
255 int rc;
151 256
152 /* Turn on the clock */ 257 if (efx->phy_type == PHY_TYPE_SFX7101) {
153 reg = (1 << CLK312_EN_LBN); 258 /* Enable 312.5 MHz clock */
154 mdio_clause45_write(efx, efx->mii.phy_id, 259 mdio_clause45_write(efx, phy_id,
155 MDIO_MMD_PCS, PCS_TEST_SELECT_REG, reg); 260 MDIO_MMD_PCS, PCS_TEST_SELECT_REG,
261 1 << CLK312_EN_LBN);
262 } else {
263 /* Enable 312.5 MHz clock and GMII */
264 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
265 PMA_PMD_XCONTROL_REG);
266 reg |= ((1 << PMA_PMD_EXT_GMII_EN_LBN) |
267 (1 << PMA_PMD_EXT_CLK_OUT_LBN) |
268 (1 << PMA_PMD_EXT_CLK312_LBN));
269 mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
270 PMA_PMD_XCONTROL_REG, reg);
271 mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
272 GPHY_XCONTROL_REG, GPHY_ISOLATE_LBN,
273 false);
274 }
156 275
157 rc = tenxpress_phy_check(efx); 276 rc = tenxpress_phy_check(efx);
158 if (rc < 0) 277 if (rc < 0)
159 return rc; 278 return rc;
160 279
161 /* Set the LEDs up as: Green = Link, Amber = Link/Act, Red = Off */ 280 /* Set the LEDs up as: Green = Link, Amber = Link/Act, Red = Off */
162 reg = mdio_clause45_read(efx, efx->mii.phy_id, 281 if (efx->phy_type == PHY_TYPE_SFX7101) {
163 MDIO_MMD_PMAPMD, PMA_PMD_LED_CTRL_REG); 282 mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PMAPMD,
164 reg |= (1 << PMA_PMA_LED_ACTIVITY_LBN); 283 PMA_PMD_LED_CTRL_REG,
165 mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, 284 PMA_PMA_LED_ACTIVITY_LBN,
166 PMA_PMD_LED_CTRL_REG, reg); 285 true);
167 286 mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
168 reg = PMA_PMD_LED_DEFAULT; 287 PMA_PMD_LED_OVERR_REG, PMA_PMD_LED_DEFAULT);
169 mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, 288 }
170 PMA_PMD_LED_OVERR_REG, reg);
171 289
172 return rc; 290 return rc;
173} 291}
@@ -183,22 +301,43 @@ static int tenxpress_phy_init(struct efx_nic *efx)
183 efx->phy_data = phy_data; 301 efx->phy_data = phy_data;
184 phy_data->phy_mode = efx->phy_mode; 302 phy_data->phy_mode = efx->phy_mode;
185 303
186 rc = mdio_clause45_wait_reset_mmds(efx, 304 if (!(efx->phy_mode & PHY_MODE_SPECIAL)) {
187 TENXPRESS_REQUIRED_DEVS); 305 if (efx->phy_type == PHY_TYPE_SFT9001A) {
188 if (rc < 0) 306 int reg;
189 goto fail; 307 reg = mdio_clause45_read(efx, efx->mii.phy_id,
308 MDIO_MMD_PMAPMD,
309 PMA_PMD_XCONTROL_REG);
310 reg |= (1 << PMA_PMD_EXT_SSR_LBN);
311 mdio_clause45_write(efx, efx->mii.phy_id,
312 MDIO_MMD_PMAPMD,
313 PMA_PMD_XCONTROL_REG, reg);
314 mdelay(200);
315 }
190 316
191 rc = mdio_clause45_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0); 317 rc = mdio_clause45_wait_reset_mmds(efx,
192 if (rc < 0) 318 TENXPRESS_REQUIRED_DEVS);
193 goto fail; 319 if (rc < 0)
320 goto fail;
321
322 rc = mdio_clause45_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0);
323 if (rc < 0)
324 goto fail;
325 }
194 326
195 rc = tenxpress_init(efx); 327 rc = tenxpress_init(efx);
196 if (rc < 0) 328 if (rc < 0)
197 goto fail; 329 goto fail;
198 330
331 if (efx->phy_type == PHY_TYPE_SFT9001B) {
332 rc = device_create_file(&efx->pci_dev->dev,
333 &dev_attr_phy_short_reach);
334 if (rc)
335 goto fail;
336 }
337
199 schedule_timeout_uninterruptible(HZ / 5); /* 200ms */ 338 schedule_timeout_uninterruptible(HZ / 5); /* 200ms */
200 339
201 /* Let XGXS and SerDes out of reset and resets 10XPress */ 340 /* Let XGXS and SerDes out of reset */
202 falcon_reset_xaui(efx); 341 falcon_reset_xaui(efx);
203 342
204 return 0; 343 return 0;
@@ -209,21 +348,24 @@ static int tenxpress_phy_init(struct efx_nic *efx)
209 return rc; 348 return rc;
210} 349}
211 350
351/* Perform a "special software reset" on the PHY. The caller is
352 * responsible for saving and restoring the PHY hardware registers
353 * properly, and masking/unmasking LASI */
212static int tenxpress_special_reset(struct efx_nic *efx) 354static int tenxpress_special_reset(struct efx_nic *efx)
213{ 355{
214 int rc, reg; 356 int rc, reg;
215 357
216 /* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so 358 /* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so
217 * a special software reset can glitch the XGMAC sufficiently for stats 359 * a special software reset can glitch the XGMAC sufficiently for stats
218 * requests to fail. Since we don't ofen special_reset, just lock. */ 360 * requests to fail. Since we don't often special_reset, just lock. */
219 spin_lock(&efx->stats_lock); 361 spin_lock(&efx->stats_lock);
220 362
221 /* Initiate reset */ 363 /* Initiate reset */
222 reg = mdio_clause45_read(efx, efx->mii.phy_id, 364 reg = mdio_clause45_read(efx, efx->mii.phy_id,
223 MDIO_MMD_PMAPMD, PMA_PMD_EXT_CTRL_REG); 365 MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG);
224 reg |= (1 << PMA_PMD_EXT_SSR_LBN); 366 reg |= (1 << PMA_PMD_EXT_SSR_LBN);
225 mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, 367 mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
226 PMA_PMD_EXT_CTRL_REG, reg); 368 PMA_PMD_XCONTROL_REG, reg);
227 369
228 mdelay(200); 370 mdelay(200);
229 371
@@ -238,12 +380,14 @@ static int tenxpress_special_reset(struct efx_nic *efx)
238 if (rc < 0) 380 if (rc < 0)
239 goto unlock; 381 goto unlock;
240 382
383 /* Wait for the XGXS state machine to churn */
384 mdelay(10);
241unlock: 385unlock:
242 spin_unlock(&efx->stats_lock); 386 spin_unlock(&efx->stats_lock);
243 return rc; 387 return rc;
244} 388}
245 389
246static void tenxpress_check_bad_lp(struct efx_nic *efx, bool link_ok) 390static void sfx7101_check_bad_lp(struct efx_nic *efx, bool link_ok)
247{ 391{
248 struct tenxpress_phy_data *pd = efx->phy_data; 392 struct tenxpress_phy_data *pd = efx->phy_data;
249 int phy_id = efx->mii.phy_id; 393 int phy_id = efx->mii.phy_id;
@@ -288,63 +432,142 @@ static void tenxpress_check_bad_lp(struct efx_nic *efx, bool link_ok)
288 } 432 }
289} 433}
290 434
291static bool tenxpress_link_ok(struct efx_nic *efx) 435static bool sfx7101_link_ok(struct efx_nic *efx)
292{ 436{
293 if (efx->loopback_mode == LOOPBACK_NONE) 437 return mdio_clause45_links_ok(efx,
294 return mdio_clause45_links_ok(efx, MDIO_MMDREG_DEVS_AN); 438 MDIO_MMDREG_DEVS_PMAPMD |
295 else 439 MDIO_MMDREG_DEVS_PCS |
440 MDIO_MMDREG_DEVS_PHYXS);
441}
442
443static bool sft9001_link_ok(struct efx_nic *efx, struct ethtool_cmd *ecmd)
444{
445 int phy_id = efx->mii.phy_id;
446 u32 reg;
447
448 if (efx->loopback_mode == LOOPBACK_GPHY)
449 return true;
450 else if (efx_phy_mode_disabled(efx->phy_mode))
451 return false;
452 else if (efx->loopback_mode)
296 return mdio_clause45_links_ok(efx, 453 return mdio_clause45_links_ok(efx,
297 MDIO_MMDREG_DEVS_PMAPMD | 454 MDIO_MMDREG_DEVS_PMAPMD |
298 MDIO_MMDREG_DEVS_PCS | 455 MDIO_MMDREG_DEVS_PCS |
299 MDIO_MMDREG_DEVS_PHYXS); 456 MDIO_MMDREG_DEVS_PHYXS);
457
458 /* We must use the same definition of link state as LASI,
459 * otherwise we can miss a link state transition
460 */
461 if (ecmd->speed == 10000) {
462 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS,
463 PCS_10GBASET_STAT1);
464 return reg & (1 << PCS_10GBASET_BLKLK_LBN);
465 } else {
466 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
467 C22EXT_STATUS_REG);
468 return reg & (1 << C22EXT_STATUS_LINK_LBN);
469 }
300} 470}
301 471
302static void tenxpress_phyxs_loopback(struct efx_nic *efx) 472static void tenxpress_ext_loopback(struct efx_nic *efx)
303{ 473{
304 int phy_id = efx->mii.phy_id; 474 int phy_id = efx->mii.phy_id;
305 int ctrl1, ctrl2;
306 475
307 ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS, 476 mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PHYXS,
308 PHYXS_TEST1); 477 PHYXS_TEST1, LOOPBACK_NEAR_LBN,
309 if (efx->loopback_mode == LOOPBACK_PHYXS) 478 efx->loopback_mode == LOOPBACK_PHYXS);
310 ctrl2 |= (1 << LOOPBACK_NEAR_LBN); 479 if (efx->phy_type != PHY_TYPE_SFX7101)
480 mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
481 GPHY_XCONTROL_REG,
482 GPHY_LOOPBACK_NEAR_LBN,
483 efx->loopback_mode == LOOPBACK_GPHY);
484}
485
486static void tenxpress_low_power(struct efx_nic *efx)
487{
488 int phy_id = efx->mii.phy_id;
489
490 if (efx->phy_type == PHY_TYPE_SFX7101)
491 mdio_clause45_set_mmds_lpower(
492 efx, !!(efx->phy_mode & PHY_MODE_LOW_POWER),
493 TENXPRESS_REQUIRED_DEVS);
311 else 494 else
312 ctrl2 &= ~(1 << LOOPBACK_NEAR_LBN); 495 mdio_clause45_set_flag(
313 if (ctrl1 != ctrl2) 496 efx, phy_id, MDIO_MMD_PMAPMD,
314 mdio_clause45_write(efx, phy_id, MDIO_MMD_PHYXS, 497 PMA_PMD_XCONTROL_REG, PMA_PMD_EXT_LPOWER_LBN,
315 PHYXS_TEST1, ctrl2); 498 !!(efx->phy_mode & PHY_MODE_LOW_POWER));
316} 499}
317 500
318static void tenxpress_phy_reconfigure(struct efx_nic *efx) 501static void tenxpress_phy_reconfigure(struct efx_nic *efx)
319{ 502{
320 struct tenxpress_phy_data *phy_data = efx->phy_data; 503 struct tenxpress_phy_data *phy_data = efx->phy_data;
321 bool loop_change = LOOPBACK_OUT_OF(phy_data, efx, 504 struct ethtool_cmd ecmd;
322 TENXPRESS_LOOPBACKS); 505 bool phy_mode_change, loop_reset, loop_toggle, loopback;
323 506
324 if (efx->phy_mode & PHY_MODE_SPECIAL) { 507 if (efx->phy_mode & (PHY_MODE_OFF | PHY_MODE_SPECIAL)) {
325 phy_data->phy_mode = efx->phy_mode; 508 phy_data->phy_mode = efx->phy_mode;
326 return; 509 return;
327 } 510 }
328 511
329 /* When coming out of transmit disable, coming out of low power 512 tenxpress_low_power(efx);
330 * mode, or moving out of any PHY internal loopback mode, 513
331 * perform a special software reset */ 514 phy_mode_change = (efx->phy_mode == PHY_MODE_NORMAL &&
332 if ((efx->phy_mode == PHY_MODE_NORMAL && 515 phy_data->phy_mode != PHY_MODE_NORMAL);
333 phy_data->phy_mode != PHY_MODE_NORMAL) || 516 loopback = LOOPBACK_MASK(efx) & efx->phy_op->loopbacks;
334 loop_change) { 517 loop_toggle = LOOPBACK_CHANGED(phy_data, efx, efx->phy_op->loopbacks);
335 tenxpress_special_reset(efx); 518 loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, efx->phy_op->loopbacks) ||
336 falcon_reset_xaui(efx); 519 LOOPBACK_CHANGED(phy_data, efx, 1 << LOOPBACK_GPHY));
520
521 if (loop_reset || loop_toggle || loopback || phy_mode_change) {
522 int rc;
523
524 efx->phy_op->get_settings(efx, &ecmd);
525
526 if (loop_reset || phy_mode_change) {
527 tenxpress_special_reset(efx);
528
529 /* Reset XAUI if we were in 10G, and are staying
530 * in 10G. If we're moving into and out of 10G
531 * then xaui will be reset anyway */
532 if (EFX_IS10G(efx))
533 falcon_reset_xaui(efx);
534 }
535
536 if (efx->phy_type != PHY_TYPE_SFX7101) {
537 /* Only change autoneg once, on coming out or
538 * going into loopback */
539 if (loop_toggle)
540 ecmd.autoneg = !loopback;
541 if (loopback) {
542 ecmd.duplex = DUPLEX_FULL;
543 if (efx->loopback_mode == LOOPBACK_GPHY)
544 ecmd.speed = SPEED_1000;
545 else
546 ecmd.speed = SPEED_10000;
547 }
548 }
549
550 rc = efx->phy_op->set_settings(efx, &ecmd);
551 WARN_ON(rc);
337 } 552 }
338 553
339 mdio_clause45_transmit_disable(efx); 554 mdio_clause45_transmit_disable(efx);
340 mdio_clause45_phy_reconfigure(efx); 555 mdio_clause45_phy_reconfigure(efx);
341 tenxpress_phyxs_loopback(efx); 556 tenxpress_ext_loopback(efx);
342 557
343 phy_data->loopback_mode = efx->loopback_mode; 558 phy_data->loopback_mode = efx->loopback_mode;
344 phy_data->phy_mode = efx->phy_mode; 559 phy_data->phy_mode = efx->phy_mode;
345 efx->link_up = tenxpress_link_ok(efx); 560
346 efx->link_speed = 10000; 561 if (efx->phy_type == PHY_TYPE_SFX7101) {
347 efx->link_fd = true; 562 efx->link_speed = 10000;
563 efx->link_fd = true;
564 efx->link_up = sfx7101_link_ok(efx);
565 } else {
566 efx->phy_op->get_settings(efx, &ecmd);
567 efx->link_speed = ecmd.speed;
568 efx->link_fd = ecmd.duplex == DUPLEX_FULL;
569 efx->link_up = sft9001_link_ok(efx, &ecmd);
570 }
348 efx->link_fc = mdio_clause45_get_pause(efx); 571 efx->link_fc = mdio_clause45_get_pause(efx);
349} 572}
350 573
@@ -355,15 +578,23 @@ static void tenxpress_phy_poll(struct efx_nic *efx)
355 bool change = false, link_ok; 578 bool change = false, link_ok;
356 unsigned link_fc; 579 unsigned link_fc;
357 580
358 link_ok = tenxpress_link_ok(efx); 581 if (efx->phy_type == PHY_TYPE_SFX7101) {
359 if (link_ok != efx->link_up) { 582 link_ok = sfx7101_link_ok(efx);
360 change = true; 583 if (link_ok != efx->link_up) {
584 change = true;
585 } else {
586 link_fc = mdio_clause45_get_pause(efx);
587 if (link_fc != efx->link_fc)
588 change = true;
589 }
590 sfx7101_check_bad_lp(efx, link_ok);
361 } else { 591 } else {
362 link_fc = mdio_clause45_get_pause(efx); 592 u32 status = mdio_clause45_read(efx, efx->mii.phy_id,
363 if (link_fc != efx->link_fc) 593 MDIO_MMD_PMAPMD,
594 PMA_PMD_LASI_STATUS);
595 if (status & (1 << PMA_PMD_LS_ALARM_LBN))
364 change = true; 596 change = true;
365 } 597 }
366 tenxpress_check_bad_lp(efx, link_ok);
367 598
368 if (change) 599 if (change)
369 falcon_sim_phy_event(efx); 600 falcon_sim_phy_event(efx);
@@ -371,7 +602,8 @@ static void tenxpress_phy_poll(struct efx_nic *efx)
371 if (phy_data->phy_mode != PHY_MODE_NORMAL) 602 if (phy_data->phy_mode != PHY_MODE_NORMAL)
372 return; 603 return;
373 604
374 if (atomic_read(&phy_data->bad_crc_count) > crc_error_reset_threshold) { 605 if (EFX_WORKAROUND_10750(efx) &&
606 atomic_read(&phy_data->bad_crc_count) > crc_error_reset_threshold) {
375 EFX_ERR(efx, "Resetting XAUI due to too many CRC errors\n"); 607 EFX_ERR(efx, "Resetting XAUI due to too many CRC errors\n");
376 falcon_reset_xaui(efx); 608 falcon_reset_xaui(efx);
377 atomic_set(&phy_data->bad_crc_count, 0); 609 atomic_set(&phy_data->bad_crc_count, 0);
@@ -382,15 +614,20 @@ static void tenxpress_phy_fini(struct efx_nic *efx)
382{ 614{
383 int reg; 615 int reg;
384 616
385 /* Power down the LNPGA */ 617 if (efx->phy_type == PHY_TYPE_SFT9001B) {
386 reg = (1 << PMA_PMD_LNPGA_POWERDOWN_LBN); 618 device_remove_file(&efx->pci_dev->dev,
387 mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, 619 &dev_attr_phy_short_reach);
388 PMA_PMD_XCONTROL_REG, reg); 620 } else {
389 621 /* Power down the LNPGA */
390 /* Waiting here ensures that the board fini, which can turn off the 622 reg = (1 << PMA_PMD_LNPGA_POWERDOWN_LBN);
391 * power to the PHY, won't get run until the LNPGA powerdown has been 623 mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
392 * given long enough to complete. */ 624 PMA_PMD_XCONTROL_REG, reg);
393 schedule_timeout_uninterruptible(LNPGA_PDOWN_WAIT); /* 200 ms */ 625
626 /* Waiting here ensures that the board fini, which can turn
627 * off the power to the PHY, won't get run until the LNPGA
628 * powerdown has been given long enough to complete. */
629 schedule_timeout_uninterruptible(LNPGA_PDOWN_WAIT); /* 200 ms */
630 }
394 631
395 kfree(efx->phy_data); 632 kfree(efx->phy_data);
396 efx->phy_data = NULL; 633 efx->phy_data = NULL;
@@ -426,14 +663,21 @@ static u32 tenxpress_get_xnp_lpa(struct efx_nic *efx)
426 u32 lpa = 0; 663 u32 lpa = 0;
427 int reg; 664 int reg;
428 665
666 if (efx->phy_type != PHY_TYPE_SFX7101) {
667 reg = mdio_clause45_read(efx, phy, MDIO_MMD_C22EXT,
668 C22EXT_MSTSLV_REG);
669 if (reg & (1 << C22EXT_MSTSLV_1000_HD_LBN))
670 lpa |= ADVERTISED_1000baseT_Half;
671 if (reg & (1 << C22EXT_MSTSLV_1000_FD_LBN))
672 lpa |= ADVERTISED_1000baseT_Full;
673 }
429 reg = mdio_clause45_read(efx, phy, MDIO_MMD_AN, MDIO_AN_10GBT_STATUS); 674 reg = mdio_clause45_read(efx, phy, MDIO_MMD_AN, MDIO_AN_10GBT_STATUS);
430 if (reg & (1 << MDIO_AN_10GBT_STATUS_LP_10G_LBN)) 675 if (reg & (1 << MDIO_AN_10GBT_STATUS_LP_10G_LBN))
431 lpa |= ADVERTISED_10000baseT_Full; 676 lpa |= ADVERTISED_10000baseT_Full;
432 return lpa; 677 return lpa;
433} 678}
434 679
435static void 680static void sfx7101_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
436tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
437{ 681{
438 mdio_clause45_get_settings_ext(efx, ecmd, ADVERTISED_10000baseT_Full, 682 mdio_clause45_get_settings_ext(efx, ecmd, ADVERTISED_10000baseT_Full,
439 tenxpress_get_xnp_lpa(efx)); 683 tenxpress_get_xnp_lpa(efx));
@@ -441,7 +685,82 @@ tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
441 ecmd->advertising |= ADVERTISED_10000baseT_Full; 685 ecmd->advertising |= ADVERTISED_10000baseT_Full;
442} 686}
443 687
444struct efx_phy_operations falcon_tenxpress_phy_ops = { 688static void sft9001_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
689{
690 int phy_id = efx->mii.phy_id;
691 u32 xnp_adv = 0;
692 int reg;
693
694 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
695 PMA_PMD_SPEED_ENABLE_REG);
696 if (EFX_WORKAROUND_13204(efx) && (reg & (1 << PMA_PMD_100TX_ADV_LBN)))
697 xnp_adv |= ADVERTISED_100baseT_Full;
698 if (reg & (1 << PMA_PMD_1000T_ADV_LBN))
699 xnp_adv |= ADVERTISED_1000baseT_Full;
700 if (reg & (1 << PMA_PMD_10000T_ADV_LBN))
701 xnp_adv |= ADVERTISED_10000baseT_Full;
702
703 mdio_clause45_get_settings_ext(efx, ecmd, xnp_adv,
704 tenxpress_get_xnp_lpa(efx));
705
706 ecmd->supported |= (SUPPORTED_100baseT_Half |
707 SUPPORTED_100baseT_Full |
708 SUPPORTED_1000baseT_Full);
709
710 /* Use the vendor defined C22ext register for duplex settings */
711 if (ecmd->speed != SPEED_10000 && !ecmd->autoneg) {
712 reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
713 GPHY_XCONTROL_REG);
714 ecmd->duplex = (reg & (1 << GPHY_DUPLEX_LBN) ?
715 DUPLEX_FULL : DUPLEX_HALF);
716 }
717}
718
719static int sft9001_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
720{
721 int phy_id = efx->mii.phy_id;
722 int rc;
723
724 rc = mdio_clause45_set_settings(efx, ecmd);
725 if (rc)
726 return rc;
727
728 if (ecmd->speed != SPEED_10000 && !ecmd->autoneg)
729 mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
730 GPHY_XCONTROL_REG, GPHY_DUPLEX_LBN,
731 ecmd->duplex == DUPLEX_FULL);
732
733 return rc;
734}
735
736static bool sft9001_set_xnp_advertise(struct efx_nic *efx, u32 advertising)
737{
738 int phy = efx->mii.phy_id;
739 int reg = mdio_clause45_read(efx, phy, MDIO_MMD_PMAPMD,
740 PMA_PMD_SPEED_ENABLE_REG);
741 bool enabled;
742
743 reg &= ~((1 << 2) | (1 << 3));
744 if (EFX_WORKAROUND_13204(efx) &&
745 (advertising & ADVERTISED_100baseT_Full))
746 reg |= 1 << PMA_PMD_100TX_ADV_LBN;
747 if (advertising & ADVERTISED_1000baseT_Full)
748 reg |= 1 << PMA_PMD_1000T_ADV_LBN;
749 if (advertising & ADVERTISED_10000baseT_Full)
750 reg |= 1 << PMA_PMD_10000T_ADV_LBN;
751 mdio_clause45_write(efx, phy, MDIO_MMD_PMAPMD,
752 PMA_PMD_SPEED_ENABLE_REG, reg);
753
754 enabled = (advertising &
755 (ADVERTISED_1000baseT_Half |
756 ADVERTISED_1000baseT_Full |
757 ADVERTISED_10000baseT_Full));
758 if (EFX_WORKAROUND_13204(efx))
759 enabled |= (advertising & ADVERTISED_100baseT_Full);
760 return enabled;
761}
762
763struct efx_phy_operations falcon_sfx7101_phy_ops = {
445 .macs = EFX_XMAC, 764 .macs = EFX_XMAC,
446 .init = tenxpress_phy_init, 765 .init = tenxpress_phy_init,
447 .reconfigure = tenxpress_phy_reconfigure, 766 .reconfigure = tenxpress_phy_reconfigure,
@@ -449,8 +768,23 @@ struct efx_phy_operations falcon_tenxpress_phy_ops = {
449 .fini = tenxpress_phy_fini, 768 .fini = tenxpress_phy_fini,
450 .clear_interrupt = efx_port_dummy_op_void, 769 .clear_interrupt = efx_port_dummy_op_void,
451 .test = tenxpress_phy_test, 770 .test = tenxpress_phy_test,
452 .get_settings = tenxpress_get_settings, 771 .get_settings = sfx7101_get_settings,
453 .set_settings = mdio_clause45_set_settings, 772 .set_settings = mdio_clause45_set_settings,
454 .mmds = TENXPRESS_REQUIRED_DEVS, 773 .mmds = TENXPRESS_REQUIRED_DEVS,
455 .loopbacks = TENXPRESS_LOOPBACKS, 774 .loopbacks = SFX7101_LOOPBACKS,
775};
776
777struct efx_phy_operations falcon_sft9001_phy_ops = {
778 .macs = EFX_GMAC | EFX_XMAC,
779 .init = tenxpress_phy_init,
780 .reconfigure = tenxpress_phy_reconfigure,
781 .poll = tenxpress_phy_poll,
782 .fini = tenxpress_phy_fini,
783 .clear_interrupt = efx_port_dummy_op_void,
784 .test = tenxpress_phy_test,
785 .get_settings = sft9001_get_settings,
786 .set_settings = sft9001_set_settings,
787 .set_xnp_advertise = sft9001_set_xnp_advertise,
788 .mmds = TENXPRESS_REQUIRED_DEVS,
789 .loopbacks = SFT9001_LOOPBACKS,
456}; 790};
diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h
index ec50b90f4285..ecebff211a74 100644
--- a/drivers/net/sfc/workarounds.h
+++ b/drivers/net/sfc/workarounds.h
@@ -17,6 +17,8 @@
17 17
18#define EFX_WORKAROUND_ALWAYS(efx) 1 18#define EFX_WORKAROUND_ALWAYS(efx) 1
19#define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1) 19#define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1)
20#define EFX_WORKAROUND_SFX7101(efx) ((efx)->phy_type == PHY_TYPE_SFX7101)
21#define EFX_WORKAROUND_SFT9001A(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A)
20 22
21/* XAUI resets if link not detected */ 23/* XAUI resets if link not detected */
22#define EFX_WORKAROUND_5147 EFX_WORKAROUND_ALWAYS 24#define EFX_WORKAROUND_5147 EFX_WORKAROUND_ALWAYS
@@ -27,7 +29,7 @@
27/* TX pkt parser problem with <= 16 byte TXes */ 29/* TX pkt parser problem with <= 16 byte TXes */
28#define EFX_WORKAROUND_9141 EFX_WORKAROUND_ALWAYS 30#define EFX_WORKAROUND_9141 EFX_WORKAROUND_ALWAYS
29/* Low rate CRC errors require XAUI reset */ 31/* Low rate CRC errors require XAUI reset */
30#define EFX_WORKAROUND_10750 EFX_WORKAROUND_ALWAYS 32#define EFX_WORKAROUND_10750 EFX_WORKAROUND_SFX7101
31/* TX_EV_PKT_ERR can be caused by a dangling TX descriptor 33/* TX_EV_PKT_ERR can be caused by a dangling TX descriptor
32 * or a PCIe error (bug 11028) */ 34 * or a PCIe error (bug 11028) */
33#define EFX_WORKAROUND_10727 EFX_WORKAROUND_ALWAYS 35#define EFX_WORKAROUND_10727 EFX_WORKAROUND_ALWAYS
@@ -51,4 +53,9 @@
51/* Leak overlength packets rather than free */ 53/* Leak overlength packets rather than free */
52#define EFX_WORKAROUND_8071 EFX_WORKAROUND_FALCON_A 54#define EFX_WORKAROUND_8071 EFX_WORKAROUND_FALCON_A
53 55
56/* Need to send XNP pages for 100BaseT */
57#define EFX_WORKAROUND_13204 EFX_WORKAROUND_SFT9001A
58/* Need to keep AN enabled */
59#define EFX_WORKAROUND_13963 EFX_WORKAROUND_SFT9001A
60
54#endif /* EFX_WORKAROUNDS_H */ 61#endif /* EFX_WORKAROUNDS_H */