aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-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 */