aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sfc')
-rw-r--r--drivers/net/sfc/boards.h2
-rw-r--r--drivers/net/sfc/efx.c3
-rw-r--r--drivers/net/sfc/falcon_xmac.c15
-rw-r--r--drivers/net/sfc/mdio_10g.c4
-rw-r--r--drivers/net/sfc/net_driver.h21
-rw-r--r--drivers/net/sfc/phy.h8
-rw-r--r--drivers/net/sfc/sfe4001.c186
-rw-r--r--drivers/net/sfc/tenxpress.c46
-rw-r--r--drivers/net/sfc/xfp_phy.c9
9 files changed, 171 insertions, 123 deletions
diff --git a/drivers/net/sfc/boards.h b/drivers/net/sfc/boards.h
index e5e844359ce7..c6e01b64bfb4 100644
--- a/drivers/net/sfc/boards.h
+++ b/drivers/net/sfc/boards.h
@@ -21,7 +21,5 @@ enum efx_board_type {
21 21
22extern int efx_set_board_info(struct efx_nic *efx, u16 revision_info); 22extern int efx_set_board_info(struct efx_nic *efx, u16 revision_info);
23extern int sfe4001_init(struct efx_nic *efx); 23extern int sfe4001_init(struct efx_nic *efx);
24/* Are we putting the PHY into flash config mode */
25extern unsigned int sfe4001_phy_flash_cfg;
26 24
27#endif 25#endif
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 864095ea5b37..d41a6e34da7d 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -1296,6 +1296,9 @@ static int efx_net_open(struct net_device *net_dev)
1296 EFX_LOG(efx, "opening device %s on CPU %d\n", net_dev->name, 1296 EFX_LOG(efx, "opening device %s on CPU %d\n", net_dev->name,
1297 raw_smp_processor_id()); 1297 raw_smp_processor_id());
1298 1298
1299 if (efx->phy_mode & PHY_MODE_SPECIAL)
1300 return -EBUSY;
1301
1299 efx_start_all(efx); 1302 efx_start_all(efx);
1300 return 0; 1303 return 0;
1301} 1304}
diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c
index be5a86f0e5cf..5620d9d13925 100644
--- a/drivers/net/sfc/falcon_xmac.c
+++ b/drivers/net/sfc/falcon_xmac.c
@@ -69,10 +69,6 @@ static int falcon_reset_xmac(struct efx_nic *efx)
69 udelay(10); 69 udelay(10);
70 } 70 }
71 71
72 /* This often fails when DSP is disabled, ignore it */
73 if (sfe4001_phy_flash_cfg)
74 return 0;
75
76 EFX_ERR(efx, "timed out waiting for XMAC core reset\n"); 72 EFX_ERR(efx, "timed out waiting for XMAC core reset\n");
77 return -ETIMEDOUT; 73 return -ETIMEDOUT;
78} 74}
@@ -444,7 +440,8 @@ static bool falcon_check_xaui_link_up(struct efx_nic *efx)
444 max_tries = tries; 440 max_tries = tries;
445 441
446 if ((efx->loopback_mode == LOOPBACK_NETWORK) || 442 if ((efx->loopback_mode == LOOPBACK_NETWORK) ||
447 (efx->phy_type == PHY_TYPE_NONE)) 443 (efx->phy_type == PHY_TYPE_NONE) ||
444 efx_phy_mode_disabled(efx->phy_mode))
448 return false; 445 return false;
449 446
450 while (tries) { 447 while (tries) {
@@ -471,7 +468,11 @@ void falcon_reconfigure_xmac(struct efx_nic *efx)
471 468
472 falcon_deconfigure_mac_wrapper(efx); 469 falcon_deconfigure_mac_wrapper(efx);
473 470
474 efx->tx_disabled = LOOPBACK_INTERNAL(efx); 471 /* Reconfigure the PHY, disabling transmit in mac level loopback. */
472 if (LOOPBACK_INTERNAL(efx))
473 efx->phy_mode |= PHY_MODE_TX_DISABLED;
474 else
475 efx->phy_mode &= ~PHY_MODE_TX_DISABLED;
475 efx->phy_op->reconfigure(efx); 476 efx->phy_op->reconfigure(efx);
476 477
477 falcon_reconfigure_xgxs_core(efx); 478 falcon_reconfigure_xgxs_core(efx);
@@ -566,7 +567,7 @@ int falcon_check_xmac(struct efx_nic *efx)
566 int rc; 567 int rc;
567 568
568 if ((efx->loopback_mode == LOOPBACK_NETWORK) || 569 if ((efx->loopback_mode == LOOPBACK_NETWORK) ||
569 (efx->phy_type == PHY_TYPE_NONE)) 570 efx_phy_mode_disabled(efx->phy_mode))
570 return 0; 571 return 0;
571 572
572 falcon_mask_status_intr(efx, false); 573 falcon_mask_status_intr(efx, false);
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index 406494684bb8..003e48dcb2f3 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -172,6 +172,8 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
172 return true; 172 return true;
173 else if (efx->loopback_mode == LOOPBACK_NETWORK) 173 else if (efx->loopback_mode == LOOPBACK_NETWORK)
174 return false; 174 return false;
175 else if (efx_phy_mode_disabled(efx->phy_mode))
176 return false;
175 else if (efx->loopback_mode == LOOPBACK_PHYXS) 177 else if (efx->loopback_mode == LOOPBACK_PHYXS)
176 mmd_mask &= ~(MDIO_MMDREG_DEVS0_PHYXS | 178 mmd_mask &= ~(MDIO_MMDREG_DEVS0_PHYXS |
177 MDIO_MMDREG_DEVS0_PCS | 179 MDIO_MMDREG_DEVS0_PCS |
@@ -206,7 +208,7 @@ void mdio_clause45_transmit_disable(struct efx_nic *efx)
206 208
207 ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, 209 ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
208 MDIO_MMDREG_TXDIS); 210 MDIO_MMDREG_TXDIS);
209 if (efx->tx_disabled) 211 if (efx->phy_mode & PHY_MODE_TX_DISABLED)
210 ctrl2 |= (1 << MDIO_MMDREG_TXDIS_GLOBAL_LBN); 212 ctrl2 |= (1 << MDIO_MMDREG_TXDIS_GLOBAL_LBN);
211 else 213 else
212 ctrl1 &= ~(1 << MDIO_MMDREG_TXDIS_GLOBAL_LBN); 214 ctrl1 &= ~(1 << MDIO_MMDREG_TXDIS_GLOBAL_LBN);
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index e65d6617beea..df863bcc06f8 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -519,6 +519,23 @@ struct efx_phy_operations {
519 unsigned loopbacks; 519 unsigned loopbacks;
520}; 520};
521 521
522/**
523 * @enum efx_phy_mode - PHY operating mode flags
524 * @PHY_MODE_NORMAL: on and should pass traffic
525 * @PHY_MODE_TX_DISABLED: on with TX disabled
526 * @PHY_MODE_SPECIAL: on but will not pass traffic
527 */
528enum efx_phy_mode {
529 PHY_MODE_NORMAL = 0,
530 PHY_MODE_TX_DISABLED = 1,
531 PHY_MODE_SPECIAL = 8,
532};
533
534static inline bool efx_phy_mode_disabled(enum efx_phy_mode mode)
535{
536 return (mode & ~PHY_MODE_TX_DISABLED) != 0;
537}
538
522/* 539/*
523 * Efx extended statistics 540 * Efx extended statistics
524 * 541 *
@@ -661,7 +678,7 @@ union efx_multicast_hash {
661 * @phy_op: PHY interface 678 * @phy_op: PHY interface
662 * @phy_data: PHY private data (including PHY-specific stats) 679 * @phy_data: PHY private data (including PHY-specific stats)
663 * @mii: PHY interface 680 * @mii: PHY interface
664 * @tx_disabled: PHY transmitter turned off 681 * @phy_mode: PHY operating mode
665 * @link_up: Link status 682 * @link_up: Link status
666 * @link_options: Link options (MII/GMII format) 683 * @link_options: Link options (MII/GMII format)
667 * @n_link_state_changes: Number of times the link has changed state 684 * @n_link_state_changes: Number of times the link has changed state
@@ -735,7 +752,7 @@ struct efx_nic {
735 struct efx_phy_operations *phy_op; 752 struct efx_phy_operations *phy_op;
736 void *phy_data; 753 void *phy_data;
737 struct mii_if_info mii; 754 struct mii_if_info mii;
738 bool tx_disabled; 755 enum efx_phy_mode phy_mode;
739 756
740 bool link_up; 757 bool link_up;
741 unsigned int link_options; 758 unsigned int link_options;
diff --git a/drivers/net/sfc/phy.h b/drivers/net/sfc/phy.h
index 25bd18ec7046..f746536f4ffa 100644
--- a/drivers/net/sfc/phy.h
+++ b/drivers/net/sfc/phy.h
@@ -15,14 +15,6 @@
15 */ 15 */
16extern struct efx_phy_operations falcon_tenxpress_phy_ops; 16extern struct efx_phy_operations falcon_tenxpress_phy_ops;
17 17
18enum tenxpress_state {
19 TENXPRESS_STATUS_OFF = 0,
20 TENXPRESS_STATUS_OTEMP = 1,
21 TENXPRESS_STATUS_NORMAL = 2,
22};
23
24extern void tenxpress_set_state(struct efx_nic *efx,
25 enum tenxpress_state state);
26extern void tenxpress_phy_blink(struct efx_nic *efx, bool blink); 18extern void tenxpress_phy_blink(struct efx_nic *efx, bool blink);
27extern void tenxpress_crc_err(struct efx_nic *efx); 19extern void tenxpress_crc_err(struct efx_nic *efx);
28 20
diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c
index f9272816437d..d90fab59f83e 100644
--- a/drivers/net/sfc/sfe4001.c
+++ b/drivers/net/sfc/sfe4001.c
@@ -13,6 +13,7 @@
13 * the PHY 13 * the PHY
14 */ 14 */
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include "net_driver.h"
16#include "efx.h" 17#include "efx.h"
17#include "phy.h" 18#include "phy.h"
18#include "boards.h" 19#include "boards.h"
@@ -120,52 +121,15 @@ static void sfe4001_poweroff(struct efx_nic *efx)
120 i2c_smbus_read_byte_data(hwmon_client, RSL); 121 i2c_smbus_read_byte_data(hwmon_client, RSL);
121} 122}
122 123
123static void sfe4001_fini(struct efx_nic *efx) 124static int sfe4001_poweron(struct efx_nic *efx)
124{ 125{
125 EFX_INFO(efx, "%s\n", __func__); 126 struct i2c_client *hwmon_client = efx->board_info.hwmon_client;
126 127 struct i2c_client *ioexp_client = efx->board_info.ioexp_client;
127 sfe4001_poweroff(efx);
128 i2c_unregister_device(efx->board_info.ioexp_client);
129 i2c_unregister_device(efx->board_info.hwmon_client);
130}
131
132/* The P0_EN_3V3X line on SFE4001 boards (from A2 onward) is connected
133 * to the FLASH_CFG_1 input on the DSP. We must keep it high at power-
134 * up to allow writing the flash (done through MDIO from userland).
135 */
136unsigned int sfe4001_phy_flash_cfg;
137module_param_named(phy_flash_cfg, sfe4001_phy_flash_cfg, uint, 0444);
138MODULE_PARM_DESC(phy_flash_cfg,
139 "Force PHY to enter flash configuration mode");
140
141/* This board uses an I2C expander to provider power to the PHY, which needs to
142 * be turned on before the PHY can be used.
143 * Context: Process context, rtnl lock held
144 */
145int sfe4001_init(struct efx_nic *efx)
146{
147 struct i2c_client *hwmon_client, *ioexp_client;
148 unsigned int i, j; 128 unsigned int i, j;
149 int rc; 129 int rc;
150 u8 out; 130 u8 out;
151 efx_dword_t reg; 131 efx_dword_t reg;
152 132
153 hwmon_client = i2c_new_dummy(&efx->i2c_adap, MAX6647);
154 if (!hwmon_client)
155 return -EIO;
156 efx->board_info.hwmon_client = hwmon_client;
157
158 ioexp_client = i2c_new_dummy(&efx->i2c_adap, PCA9539);
159 if (!ioexp_client) {
160 rc = -EIO;
161 goto fail_hwmon;
162 }
163 efx->board_info.ioexp_client = ioexp_client;
164
165 /* 10Xpress has fixed-function LED pins, so there is no board-specific
166 * blink code. */
167 efx->board_info.blink = tenxpress_phy_blink;
168
169 /* Ensure that XGXS and XAUI SerDes are held in reset */ 133 /* Ensure that XGXS and XAUI SerDes are held in reset */
170 EFX_POPULATE_DWORD_7(reg, XX_PWRDNA_EN, 1, 134 EFX_POPULATE_DWORD_7(reg, XX_PWRDNA_EN, 1,
171 XX_PWRDNB_EN, 1, 135 XX_PWRDNB_EN, 1,
@@ -177,33 +141,15 @@ int sfe4001_init(struct efx_nic *efx)
177 falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC); 141 falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
178 udelay(10); 142 udelay(10);
179 143
180 efx->board_info.fini = sfe4001_fini;
181
182 /* Set DSP over-temperature alert threshold */
183 EFX_INFO(efx, "DSP cut-out at %dC\n", xgphy_max_temperature);
184 rc = i2c_smbus_write_byte_data(hwmon_client, WLHO,
185 xgphy_max_temperature);
186 if (rc)
187 goto fail_ioexp;
188
189 /* Read it back and verify */
190 rc = i2c_smbus_read_byte_data(hwmon_client, RLHN);
191 if (rc < 0)
192 goto fail_ioexp;
193 if (rc != xgphy_max_temperature) {
194 rc = -EFAULT;
195 goto fail_ioexp;
196 }
197
198 /* Clear any previous over-temperature alert */ 144 /* Clear any previous over-temperature alert */
199 rc = i2c_smbus_read_byte_data(hwmon_client, RSL); 145 rc = i2c_smbus_read_byte_data(hwmon_client, RSL);
200 if (rc < 0) 146 if (rc < 0)
201 goto fail_ioexp; 147 return rc;
202 148
203 /* Enable port 0 and port 1 outputs on IO expander */ 149 /* Enable port 0 and port 1 outputs on IO expander */
204 rc = i2c_smbus_write_byte_data(ioexp_client, P0_CONFIG, 0x00); 150 rc = i2c_smbus_write_byte_data(ioexp_client, P0_CONFIG, 0x00);
205 if (rc) 151 if (rc)
206 goto fail_ioexp; 152 return rc;
207 rc = i2c_smbus_write_byte_data(ioexp_client, P1_CONFIG, 153 rc = i2c_smbus_write_byte_data(ioexp_client, P1_CONFIG,
208 0xff & ~(1 << P1_SPARE_LBN)); 154 0xff & ~(1 << P1_SPARE_LBN));
209 if (rc) 155 if (rc)
@@ -231,7 +177,7 @@ int sfe4001_init(struct efx_nic *efx)
231 out = 0xff & ~((1 << P0_EN_1V2_LBN) | (1 << P0_EN_2V5_LBN) | 177 out = 0xff & ~((1 << P0_EN_1V2_LBN) | (1 << P0_EN_2V5_LBN) |
232 (1 << P0_EN_3V3X_LBN) | (1 << P0_EN_5V_LBN) | 178 (1 << P0_EN_3V3X_LBN) | (1 << P0_EN_5V_LBN) |
233 (1 << P0_X_TRST_LBN)); 179 (1 << P0_X_TRST_LBN));
234 if (sfe4001_phy_flash_cfg) 180 if (efx->phy_mode & PHY_MODE_SPECIAL)
235 out |= 1 << P0_EN_3V3X_LBN; 181 out |= 1 << P0_EN_3V3X_LBN;
236 182
237 rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out); 183 rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out);
@@ -250,9 +196,9 @@ int sfe4001_init(struct efx_nic *efx)
250 /* In flash config mode, DSP does not turn on AFE, so 196 /* In flash config mode, DSP does not turn on AFE, so
251 * just wait 1 second. 197 * just wait 1 second.
252 */ 198 */
253 if (sfe4001_phy_flash_cfg) { 199 if (efx->phy_mode & PHY_MODE_SPECIAL) {
254 schedule_timeout_uninterruptible(HZ); 200 schedule_timeout_uninterruptible(HZ);
255 goto done; 201 return 0;
256 } 202 }
257 203
258 for (j = 0; j < 10; ++j) { 204 for (j = 0; j < 10; ++j) {
@@ -263,23 +209,127 @@ int sfe4001_init(struct efx_nic *efx)
263 if (rc < 0) 209 if (rc < 0)
264 goto fail_on; 210 goto fail_on;
265 if (rc & (1 << P1_AFE_PWD_LBN)) 211 if (rc & (1 << P1_AFE_PWD_LBN))
266 goto done; 212 return 0;
267 } 213 }
268 } 214 }
269 215
270 EFX_INFO(efx, "timed out waiting for DSP boot\n"); 216 EFX_INFO(efx, "timed out waiting for DSP boot\n");
271 rc = -ETIMEDOUT; 217 rc = -ETIMEDOUT;
272 goto fail_on; 218fail_on:
219 sfe4001_poweroff(efx);
220 return rc;
221}
222
223/* On SFE4001 rev A2 and later, we can control the FLASH_CFG_1 pin
224 * using the 3V3X output of the IO-expander. Allow the user to set
225 * this when the device is stopped, and keep it stopped then.
226 */
227
228static ssize_t show_phy_flash_cfg(struct device *dev,
229 struct device_attribute *attr, char *buf)
230{
231 struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
232 return sprintf(buf, "%d\n", !!(efx->phy_mode & PHY_MODE_SPECIAL));
233}
234
235static ssize_t set_phy_flash_cfg(struct device *dev,
236 struct device_attribute *attr,
237 const char *buf, size_t count)
238{
239 struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
240 enum efx_phy_mode old_mode, new_mode;
241 int err;
242
243 rtnl_lock();
244 old_mode = efx->phy_mode;
245 if (count == 0 || *buf == '0')
246 new_mode = old_mode & ~PHY_MODE_SPECIAL;
247 else
248 new_mode = PHY_MODE_SPECIAL;
249 if (old_mode == new_mode) {
250 err = 0;
251 } else if (efx->state != STATE_RUNNING || netif_running(efx->net_dev)) {
252 err = -EBUSY;
253 } else {
254 efx->phy_mode = new_mode;
255 err = sfe4001_poweron(efx);
256 efx_reconfigure_port(efx);
257 }
258 rtnl_unlock();
259
260 return err ? err : count;
261}
262
263static DEVICE_ATTR(phy_flash_cfg, 0644, show_phy_flash_cfg, set_phy_flash_cfg);
264
265static void sfe4001_fini(struct efx_nic *efx)
266{
267 EFX_INFO(efx, "%s\n", __func__);
268
269 device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
270 sfe4001_poweroff(efx);
271 i2c_unregister_device(efx->board_info.ioexp_client);
272 i2c_unregister_device(efx->board_info.hwmon_client);
273}
274
275/* This board uses an I2C expander to provider power to the PHY, which needs to
276 * be turned on before the PHY can be used.
277 * Context: Process context, rtnl lock held
278 */
279int sfe4001_init(struct efx_nic *efx)
280{
281 struct i2c_client *hwmon_client;
282 int rc;
283
284 hwmon_client = i2c_new_dummy(&efx->i2c_adap, MAX6647);
285 if (!hwmon_client)
286 return -EIO;
287 efx->board_info.hwmon_client = hwmon_client;
288
289 /* Set DSP over-temperature alert threshold */
290 EFX_INFO(efx, "DSP cut-out at %dC\n", xgphy_max_temperature);
291 rc = i2c_smbus_write_byte_data(hwmon_client, WLHO,
292 xgphy_max_temperature);
293 if (rc)
294 goto fail_ioexp;
295
296 /* Read it back and verify */
297 rc = i2c_smbus_read_byte_data(hwmon_client, RLHN);
298 if (rc < 0)
299 goto fail_ioexp;
300 if (rc != xgphy_max_temperature) {
301 rc = -EFAULT;
302 goto fail_ioexp;
303 }
304
305 efx->board_info.ioexp_client = i2c_new_dummy(&efx->i2c_adap, PCA9539);
306 if (!efx->board_info.ioexp_client) {
307 rc = -EIO;
308 goto fail_hwmon;
309 }
310
311 /* 10Xpress has fixed-function LED pins, so there is no board-specific
312 * blink code. */
313 efx->board_info.blink = tenxpress_phy_blink;
314
315 efx->board_info.fini = sfe4001_fini;
316
317 rc = sfe4001_poweron(efx);
318 if (rc)
319 goto fail_ioexp;
320
321 rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
322 if (rc)
323 goto fail_on;
273 324
274done:
275 EFX_INFO(efx, "PHY is powered on\n"); 325 EFX_INFO(efx, "PHY is powered on\n");
276 return 0; 326 return 0;
277 327
278fail_on: 328fail_on:
279 sfe4001_poweroff(efx); 329 sfe4001_poweroff(efx);
280fail_ioexp: 330fail_ioexp:
281 i2c_unregister_device(ioexp_client); 331 i2c_unregister_device(efx->board_info.ioexp_client);
282fail_hwmon: 332fail_hwmon:
283 i2c_unregister_device(hwmon_client); 333 i2c_unregister_device(hwmon_client);
284 return rc; 334 return rc;
285} 335}
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index b92b24bba9e8..499e127f6dd5 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -119,27 +119,12 @@ MODULE_PARM_DESC(crc_error_reset_threshold,
119 "Max number of CRC errors before XAUI reset"); 119 "Max number of CRC errors before XAUI reset");
120 120
121struct tenxpress_phy_data { 121struct tenxpress_phy_data {
122 enum tenxpress_state state;
123 enum efx_loopback_mode loopback_mode; 122 enum efx_loopback_mode loopback_mode;
124 atomic_t bad_crc_count; 123 atomic_t bad_crc_count;
125 bool tx_disabled; 124 enum efx_phy_mode phy_mode;
126 int bad_lp_tries; 125 int bad_lp_tries;
127}; 126};
128 127
129static int tenxpress_state_is(struct efx_nic *efx, int state)
130{
131 struct tenxpress_phy_data *phy_data = efx->phy_data;
132 return (phy_data != NULL) && (state == phy_data->state);
133}
134
135void tenxpress_set_state(struct efx_nic *efx,
136 enum tenxpress_state state)
137{
138 struct tenxpress_phy_data *phy_data = efx->phy_data;
139 if (phy_data != NULL)
140 phy_data->state = state;
141}
142
143void tenxpress_crc_err(struct efx_nic *efx) 128void tenxpress_crc_err(struct efx_nic *efx)
144{ 129{
145 struct tenxpress_phy_data *phy_data = efx->phy_data; 130 struct tenxpress_phy_data *phy_data = efx->phy_data;
@@ -214,15 +199,12 @@ static int tenxpress_phy_init(struct efx_nic *efx)
214 if (!phy_data) 199 if (!phy_data)
215 return -ENOMEM; 200 return -ENOMEM;
216 efx->phy_data = phy_data; 201 efx->phy_data = phy_data;
202 phy_data->phy_mode = efx->phy_mode;
217 203
218 tenxpress_set_state(efx, TENXPRESS_STATUS_NORMAL); 204 rc = mdio_clause45_wait_reset_mmds(efx,
219 205 TENXPRESS_REQUIRED_DEVS);
220 if (!sfe4001_phy_flash_cfg) { 206 if (rc < 0)
221 rc = mdio_clause45_wait_reset_mmds(efx, 207 goto fail;
222 TENXPRESS_REQUIRED_DEVS);
223 if (rc < 0)
224 goto fail;
225 }
226 208
227 rc = mdio_clause45_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0); 209 rc = mdio_clause45_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0);
228 if (rc < 0) 210 if (rc < 0)
@@ -370,13 +352,16 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
370 bool loop_change = LOOPBACK_OUT_OF(phy_data, efx, 352 bool loop_change = LOOPBACK_OUT_OF(phy_data, efx,
371 TENXPRESS_LOOPBACKS); 353 TENXPRESS_LOOPBACKS);
372 354
373 if (!tenxpress_state_is(efx, TENXPRESS_STATUS_NORMAL)) 355 if (efx->phy_mode & PHY_MODE_SPECIAL) {
356 phy_data->phy_mode = efx->phy_mode;
374 return; 357 return;
358 }
375 359
376 /* When coming out of transmit disable, coming out of low power 360 /* When coming out of transmit disable, coming out of low power
377 * mode, or moving out of any PHY internal loopback mode, 361 * mode, or moving out of any PHY internal loopback mode,
378 * perform a special software reset */ 362 * perform a special software reset */
379 if ((phy_data->tx_disabled && !efx->tx_disabled) || 363 if ((efx->phy_mode == PHY_MODE_NORMAL &&
364 phy_data->phy_mode != PHY_MODE_NORMAL) ||
380 loop_change) { 365 loop_change) {
381 tenxpress_special_reset(efx); 366 tenxpress_special_reset(efx);
382 falcon_reset_xaui(efx); 367 falcon_reset_xaui(efx);
@@ -386,8 +371,8 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
386 mdio_clause45_phy_reconfigure(efx); 371 mdio_clause45_phy_reconfigure(efx);
387 tenxpress_phyxs_loopback(efx); 372 tenxpress_phyxs_loopback(efx);
388 373
389 phy_data->tx_disabled = efx->tx_disabled;
390 phy_data->loopback_mode = efx->loopback_mode; 374 phy_data->loopback_mode = efx->loopback_mode;
375 phy_data->phy_mode = efx->phy_mode;
391 efx->link_up = tenxpress_link_ok(efx, false); 376 efx->link_up = tenxpress_link_ok(efx, false);
392 efx->link_options = GM_LPA_10000FULL; 377 efx->link_options = GM_LPA_10000FULL;
393} 378}
@@ -402,16 +387,15 @@ static void tenxpress_phy_clear_interrupt(struct efx_nic *efx)
402static int tenxpress_phy_check_hw(struct efx_nic *efx) 387static int tenxpress_phy_check_hw(struct efx_nic *efx)
403{ 388{
404 struct tenxpress_phy_data *phy_data = efx->phy_data; 389 struct tenxpress_phy_data *phy_data = efx->phy_data;
405 bool phy_up = tenxpress_state_is(efx, TENXPRESS_STATUS_NORMAL);
406 bool link_ok; 390 bool link_ok;
407 391
408 link_ok = phy_up && tenxpress_link_ok(efx, true); 392 link_ok = (phy_data->phy_mode == PHY_MODE_NORMAL &&
393 tenxpress_link_ok(efx, true));
409 394
410 if (link_ok != efx->link_up) 395 if (link_ok != efx->link_up)
411 falcon_xmac_sim_phy_event(efx); 396 falcon_xmac_sim_phy_event(efx);
412 397
413 /* Nothing to check if we've already shut down the PHY */ 398 if (phy_data->phy_mode != PHY_MODE_NORMAL)
414 if (!phy_up)
415 return 0; 399 return 0;
416 400
417 if (atomic_read(&phy_data->bad_crc_count) > crc_error_reset_threshold) { 401 if (atomic_read(&phy_data->bad_crc_count) > crc_error_reset_threshold) {
diff --git a/drivers/net/sfc/xfp_phy.c b/drivers/net/sfc/xfp_phy.c
index fd4045b4d9d0..f6edecc2e588 100644
--- a/drivers/net/sfc/xfp_phy.c
+++ b/drivers/net/sfc/xfp_phy.c
@@ -40,7 +40,7 @@ void xfp_set_led(struct efx_nic *p, int led, int mode)
40} 40}
41 41
42struct xfp_phy_data { 42struct xfp_phy_data {
43 bool tx_disabled; 43 enum efx_phy_mode phy_mode;
44}; 44};
45 45
46#define XFP_MAX_RESET_TIME 500 46#define XFP_MAX_RESET_TIME 500
@@ -93,7 +93,7 @@ static int xfp_phy_init(struct efx_nic *efx)
93 " %x)\n", devid, MDIO_ID_OUI(devid), MDIO_ID_MODEL(devid), 93 " %x)\n", devid, MDIO_ID_OUI(devid), MDIO_ID_MODEL(devid),
94 MDIO_ID_REV(devid)); 94 MDIO_ID_REV(devid));
95 95
96 phy_data->tx_disabled = efx->tx_disabled; 96 phy_data->phy_mode = efx->phy_mode;
97 97
98 rc = xfp_reset_phy(efx); 98 rc = xfp_reset_phy(efx);
99 99
@@ -136,13 +136,14 @@ static void xfp_phy_reconfigure(struct efx_nic *efx)
136 struct xfp_phy_data *phy_data = efx->phy_data; 136 struct xfp_phy_data *phy_data = efx->phy_data;
137 137
138 /* Reset the PHY when moving from tx off to tx on */ 138 /* Reset the PHY when moving from tx off to tx on */
139 if (phy_data->tx_disabled && !efx->tx_disabled) 139 if (!(efx->phy_mode & PHY_MODE_TX_DISABLED) &&
140 (phy_data->phy_mode & PHY_MODE_TX_DISABLED))
140 xfp_reset_phy(efx); 141 xfp_reset_phy(efx);
141 142
142 mdio_clause45_transmit_disable(efx); 143 mdio_clause45_transmit_disable(efx);
143 mdio_clause45_phy_reconfigure(efx); 144 mdio_clause45_phy_reconfigure(efx);
144 145
145 phy_data->tx_disabled = efx->tx_disabled; 146 phy_data->phy_mode = efx->phy_mode;
146 efx->link_up = xfp_link_ok(efx); 147 efx->link_up = xfp_link_ok(efx);
147 efx->link_options = GM_LPA_10000FULL; 148 efx->link_options = GM_LPA_10000FULL;
148} 149}