aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/tenxpress.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/net/sfc/tenxpress.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/net/sfc/tenxpress.c')
-rw-r--r--drivers/net/sfc/tenxpress.c434
1 files changed, 31 insertions, 403 deletions
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index 6791be90c2fe..7b0fd89e7b85 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -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-2009 Solarflare Communications Inc. 3 * Copyright 2007-2011 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
@@ -15,14 +15,9 @@
15#include "mdio_10g.h" 15#include "mdio_10g.h"
16#include "nic.h" 16#include "nic.h"
17#include "phy.h" 17#include "phy.h"
18#include "regs.h"
19#include "workarounds.h" 18#include "workarounds.h"
20#include "selftest.h"
21 19
22/* We expect these MMDs to be in the package. SFT9001 also has a 20/* We expect these MMDs to be in the package. */
23 * clause 22 extension MMD, but since it doesn't have all the generic
24 * MMD registers it is pointless to include it here.
25 */
26#define TENXPRESS_REQUIRED_DEVS (MDIO_DEVS_PMAPMD | \ 21#define TENXPRESS_REQUIRED_DEVS (MDIO_DEVS_PMAPMD | \
27 MDIO_DEVS_PCS | \ 22 MDIO_DEVS_PCS | \
28 MDIO_DEVS_PHYXS | \ 23 MDIO_DEVS_PHYXS | \
@@ -33,12 +28,6 @@
33 (1 << LOOPBACK_PMAPMD) | \ 28 (1 << LOOPBACK_PMAPMD) | \
34 (1 << LOOPBACK_PHYXS_WS)) 29 (1 << LOOPBACK_PHYXS_WS))
35 30
36#define SFT9001_LOOPBACKS ((1 << LOOPBACK_GPHY) | \
37 (1 << LOOPBACK_PHYXS) | \
38 (1 << LOOPBACK_PCS) | \
39 (1 << LOOPBACK_PMAPMD) | \
40 (1 << LOOPBACK_PHYXS_WS))
41
42/* We complain if we fail to see the link partner as 10G capable this many 31/* We complain if we fail to see the link partner as 10G capable this many
43 * times in a row (must be > 1 as sampling the autoneg. registers is racy) 32 * times in a row (must be > 1 as sampling the autoneg. registers is racy)
44 */ 33 */
@@ -50,9 +39,8 @@
50#define PMA_PMD_EXT_GMII_EN_WIDTH 1 39#define PMA_PMD_EXT_GMII_EN_WIDTH 1
51#define PMA_PMD_EXT_CLK_OUT_LBN 2 40#define PMA_PMD_EXT_CLK_OUT_LBN 2
52#define PMA_PMD_EXT_CLK_OUT_WIDTH 1 41#define PMA_PMD_EXT_CLK_OUT_WIDTH 1
53#define PMA_PMD_LNPGA_POWERDOWN_LBN 8 /* SFX7101 only */ 42#define PMA_PMD_LNPGA_POWERDOWN_LBN 8
54#define PMA_PMD_LNPGA_POWERDOWN_WIDTH 1 43#define PMA_PMD_LNPGA_POWERDOWN_WIDTH 1
55#define PMA_PMD_EXT_CLK312_LBN 8 /* SFT9001 only */
56#define PMA_PMD_EXT_CLK312_WIDTH 1 44#define PMA_PMD_EXT_CLK312_WIDTH 1
57#define PMA_PMD_EXT_LPOWER_LBN 12 45#define PMA_PMD_EXT_LPOWER_LBN 12
58#define PMA_PMD_EXT_LPOWER_WIDTH 1 46#define PMA_PMD_EXT_LPOWER_WIDTH 1
@@ -84,7 +72,6 @@
84#define PMA_PMD_LED_FLASH (3) 72#define PMA_PMD_LED_FLASH (3)
85#define PMA_PMD_LED_MASK 3 73#define PMA_PMD_LED_MASK 3
86/* All LEDs under hardware control */ 74/* All LEDs under hardware control */
87#define SFT9001_PMA_PMD_LED_DEFAULT 0
88/* Green and Amber under hardware control, Red off */ 75/* Green and Amber under hardware control, Red off */
89#define SFX7101_PMA_PMD_LED_DEFAULT (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN) 76#define SFX7101_PMA_PMD_LED_DEFAULT (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN)
90 77
@@ -98,31 +85,7 @@
98#define PMA_PMD_SPEED_LBN 4 85#define PMA_PMD_SPEED_LBN 4
99#define PMA_PMD_SPEED_WIDTH 4 86#define PMA_PMD_SPEED_WIDTH 4
100 87
101/* Cable diagnostics - SFT9001 only */ 88/* Misc register defines */
102#define PMA_PMD_CDIAG_CTRL_REG 49213
103#define CDIAG_CTRL_IMMED_LBN 15
104#define CDIAG_CTRL_BRK_LINK_LBN 12
105#define CDIAG_CTRL_IN_PROG_LBN 11
106#define CDIAG_CTRL_LEN_UNIT_LBN 10
107#define CDIAG_CTRL_LEN_METRES 1
108#define PMA_PMD_CDIAG_RES_REG 49174
109#define CDIAG_RES_A_LBN 12
110#define CDIAG_RES_B_LBN 8
111#define CDIAG_RES_C_LBN 4
112#define CDIAG_RES_D_LBN 0
113#define CDIAG_RES_WIDTH 4
114#define CDIAG_RES_OPEN 2
115#define CDIAG_RES_OK 1
116#define CDIAG_RES_INVALID 0
117/* Set of 4 registers for pairs A-D */
118#define PMA_PMD_CDIAG_LEN_REG 49175
119
120/* Serdes control registers - SFT9001 only */
121#define PMA_PMD_CSERDES_CTRL_REG 64258
122/* Set the 156.25 MHz output to 312.5 MHz to drive Falcon's XMAC */
123#define PMA_PMD_CSERDES_DEFAULT 0x000f
124
125/* Misc register defines - SFX7101 only */
126#define PCS_CLOCK_CTRL_REG 55297 89#define PCS_CLOCK_CTRL_REG 55297
127#define PLL312_RST_N_LBN 2 90#define PLL312_RST_N_LBN 2
128 91
@@ -185,121 +148,17 @@ struct tenxpress_phy_data {
185 int bad_lp_tries; 148 int bad_lp_tries;
186}; 149};
187 150
188static ssize_t show_phy_short_reach(struct device *dev,
189 struct device_attribute *attr, char *buf)
190{
191 struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
192 int reg;
193
194 reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR);
195 return sprintf(buf, "%d\n", !!(reg & MDIO_PMA_10GBT_TXPWR_SHORT));
196}
197
198static ssize_t set_phy_short_reach(struct device *dev,
199 struct device_attribute *attr,
200 const char *buf, size_t count)
201{
202 struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
203 int rc;
204
205 rtnl_lock();
206 if (efx->state != STATE_RUNNING) {
207 rc = -EBUSY;
208 } else {
209 efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR,
210 MDIO_PMA_10GBT_TXPWR_SHORT,
211 count != 0 && *buf != '0');
212 rc = efx_reconfigure_port(efx);
213 }
214 rtnl_unlock();
215
216 return rc < 0 ? rc : (ssize_t)count;
217}
218
219static DEVICE_ATTR(phy_short_reach, 0644, show_phy_short_reach,
220 set_phy_short_reach);
221
222int sft9001_wait_boot(struct efx_nic *efx)
223{
224 unsigned long timeout = jiffies + HZ + 1;
225 int boot_stat;
226
227 for (;;) {
228 boot_stat = efx_mdio_read(efx, MDIO_MMD_PCS,
229 PCS_BOOT_STATUS_REG);
230 if (boot_stat >= 0) {
231 netif_dbg(efx, hw, efx->net_dev,
232 "PHY boot status = %#x\n", boot_stat);
233 switch (boot_stat &
234 ((1 << PCS_BOOT_FATAL_ERROR_LBN) |
235 (3 << PCS_BOOT_PROGRESS_LBN) |
236 (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN) |
237 (1 << PCS_BOOT_CODE_STARTED_LBN))) {
238 case ((1 << PCS_BOOT_FATAL_ERROR_LBN) |
239 (PCS_BOOT_PROGRESS_CHECKSUM <<
240 PCS_BOOT_PROGRESS_LBN)):
241 case ((1 << PCS_BOOT_FATAL_ERROR_LBN) |
242 (PCS_BOOT_PROGRESS_INIT <<
243 PCS_BOOT_PROGRESS_LBN) |
244 (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN)):
245 return -EINVAL;
246 case ((PCS_BOOT_PROGRESS_WAIT_MDIO <<
247 PCS_BOOT_PROGRESS_LBN) |
248 (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN)):
249 return (efx->phy_mode & PHY_MODE_SPECIAL) ?
250 0 : -EIO;
251 case ((PCS_BOOT_PROGRESS_JUMP <<
252 PCS_BOOT_PROGRESS_LBN) |
253 (1 << PCS_BOOT_CODE_STARTED_LBN)):
254 case ((PCS_BOOT_PROGRESS_JUMP <<
255 PCS_BOOT_PROGRESS_LBN) |
256 (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN) |
257 (1 << PCS_BOOT_CODE_STARTED_LBN)):
258 return (efx->phy_mode & PHY_MODE_SPECIAL) ?
259 -EIO : 0;
260 default:
261 if (boot_stat & (1 << PCS_BOOT_FATAL_ERROR_LBN))
262 return -EIO;
263 break;
264 }
265 }
266
267 if (time_after_eq(jiffies, timeout))
268 return -ETIMEDOUT;
269
270 msleep(50);
271 }
272}
273
274static int tenxpress_init(struct efx_nic *efx) 151static int tenxpress_init(struct efx_nic *efx)
275{ 152{
276 int reg; 153 /* Enable 312.5 MHz clock */
277 154 efx_mdio_write(efx, MDIO_MMD_PCS, PCS_TEST_SELECT_REG,
278 if (efx->phy_type == PHY_TYPE_SFX7101) { 155 1 << CLK312_EN_LBN);
279 /* Enable 312.5 MHz clock */
280 efx_mdio_write(efx, MDIO_MMD_PCS, PCS_TEST_SELECT_REG,
281 1 << CLK312_EN_LBN);
282 } else {
283 /* Enable 312.5 MHz clock and GMII */
284 reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG);
285 reg |= ((1 << PMA_PMD_EXT_GMII_EN_LBN) |
286 (1 << PMA_PMD_EXT_CLK_OUT_LBN) |
287 (1 << PMA_PMD_EXT_CLK312_LBN) |
288 (1 << PMA_PMD_EXT_ROBUST_LBN));
289
290 efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg);
291 efx_mdio_set_flag(efx, MDIO_MMD_C22EXT,
292 GPHY_XCONTROL_REG, 1 << GPHY_ISOLATE_LBN,
293 false);
294 }
295 156
296 /* Set the LEDs up as: Green = Link, Amber = Link/Act, Red = Off */ 157 /* Set the LEDs up as: Green = Link, Amber = Link/Act, Red = Off */
297 if (efx->phy_type == PHY_TYPE_SFX7101) { 158 efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_CTRL_REG,
298 efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_CTRL_REG, 159 1 << PMA_PMA_LED_ACTIVITY_LBN, true);
299 1 << PMA_PMA_LED_ACTIVITY_LBN, true); 160 efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG,
300 efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG, 161 SFX7101_PMA_PMD_LED_DEFAULT);
301 SFX7101_PMA_PMD_LED_DEFAULT);
302 }
303 162
304 return 0; 163 return 0;
305} 164}
@@ -307,7 +166,6 @@ static int tenxpress_init(struct efx_nic *efx)
307static int tenxpress_phy_probe(struct efx_nic *efx) 166static int tenxpress_phy_probe(struct efx_nic *efx)
308{ 167{
309 struct tenxpress_phy_data *phy_data; 168 struct tenxpress_phy_data *phy_data;
310 int rc;
311 169
312 /* Allocate phy private storage */ 170 /* Allocate phy private storage */
313 phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL); 171 phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL);
@@ -316,42 +174,15 @@ static int tenxpress_phy_probe(struct efx_nic *efx)
316 efx->phy_data = phy_data; 174 efx->phy_data = phy_data;
317 phy_data->phy_mode = efx->phy_mode; 175 phy_data->phy_mode = efx->phy_mode;
318 176
319 /* Create any special files */ 177 efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS;
320 if (efx->phy_type == PHY_TYPE_SFT9001B) { 178 efx->mdio.mode_support = MDIO_SUPPORTS_C45;
321 rc = device_create_file(&efx->pci_dev->dev,
322 &dev_attr_phy_short_reach);
323 if (rc)
324 goto fail;
325 }
326
327 if (efx->phy_type == PHY_TYPE_SFX7101) {
328 efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS;
329 efx->mdio.mode_support = MDIO_SUPPORTS_C45;
330
331 efx->loopback_modes = SFX7101_LOOPBACKS | FALCON_XMAC_LOOPBACKS;
332 179
333 efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg | 180 efx->loopback_modes = SFX7101_LOOPBACKS | FALCON_XMAC_LOOPBACKS;
334 ADVERTISED_10000baseT_Full);
335 } else {
336 efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS;
337 efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
338 181
339 efx->loopback_modes = (SFT9001_LOOPBACKS | 182 efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg |
340 FALCON_XMAC_LOOPBACKS | 183 ADVERTISED_10000baseT_Full);
341 FALCON_GMAC_LOOPBACKS);
342
343 efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg |
344 ADVERTISED_10000baseT_Full |
345 ADVERTISED_1000baseT_Full |
346 ADVERTISED_100baseT_Full);
347 }
348 184
349 return 0; 185 return 0;
350
351fail:
352 kfree(efx->phy_data);
353 efx->phy_data = NULL;
354 return rc;
355} 186}
356 187
357static int tenxpress_phy_init(struct efx_nic *efx) 188static int tenxpress_phy_init(struct efx_nic *efx)
@@ -361,21 +192,11 @@ static int tenxpress_phy_init(struct efx_nic *efx)
361 falcon_board(efx)->type->init_phy(efx); 192 falcon_board(efx)->type->init_phy(efx);
362 193
363 if (!(efx->phy_mode & PHY_MODE_SPECIAL)) { 194 if (!(efx->phy_mode & PHY_MODE_SPECIAL)) {
364 if (efx->phy_type == PHY_TYPE_SFT9001A) {
365 int reg;
366 reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD,
367 PMA_PMD_XCONTROL_REG);
368 reg |= (1 << PMA_PMD_EXT_SSR_LBN);
369 efx_mdio_write(efx, MDIO_MMD_PMAPMD,
370 PMA_PMD_XCONTROL_REG, reg);
371 mdelay(200);
372 }
373
374 rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS); 195 rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS);
375 if (rc < 0) 196 if (rc < 0)
376 return rc; 197 return rc;
377 198
378 rc = efx_mdio_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0); 199 rc = efx_mdio_check_mmds(efx, TENXPRESS_REQUIRED_DEVS);
379 if (rc < 0) 200 if (rc < 0)
380 return rc; 201 return rc;
381 } 202 }
@@ -403,7 +224,7 @@ static int tenxpress_special_reset(struct efx_nic *efx)
403{ 224{
404 int rc, reg; 225 int rc, reg;
405 226
406 /* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so 227 /* The XGMAC clock is driven from the SFX7101 312MHz clock, so
407 * a special software reset can glitch the XGMAC sufficiently for stats 228 * a special software reset can glitch the XGMAC sufficiently for stats
408 * requests to fail. */ 229 * requests to fail. */
409 falcon_stop_nic_stats(efx); 230 falcon_stop_nic_stats(efx);
@@ -484,53 +305,18 @@ static bool sfx7101_link_ok(struct efx_nic *efx)
484 MDIO_DEVS_PHYXS); 305 MDIO_DEVS_PHYXS);
485} 306}
486 307
487static bool sft9001_link_ok(struct efx_nic *efx, struct ethtool_cmd *ecmd)
488{
489 u32 reg;
490
491 if (efx_phy_mode_disabled(efx->phy_mode))
492 return false;
493 else if (efx->loopback_mode == LOOPBACK_GPHY)
494 return true;
495 else if (efx->loopback_mode)
496 return efx_mdio_links_ok(efx,
497 MDIO_DEVS_PMAPMD |
498 MDIO_DEVS_PHYXS);
499
500 /* We must use the same definition of link state as LASI,
501 * otherwise we can miss a link state transition
502 */
503 if (ecmd->speed == 10000) {
504 reg = efx_mdio_read(efx, MDIO_MMD_PCS, MDIO_PCS_10GBRT_STAT1);
505 return reg & MDIO_PCS_10GBRT_STAT1_BLKLK;
506 } else {
507 reg = efx_mdio_read(efx, MDIO_MMD_C22EXT, C22EXT_STATUS_REG);
508 return reg & (1 << C22EXT_STATUS_LINK_LBN);
509 }
510}
511
512static void tenxpress_ext_loopback(struct efx_nic *efx) 308static void tenxpress_ext_loopback(struct efx_nic *efx)
513{ 309{
514 efx_mdio_set_flag(efx, MDIO_MMD_PHYXS, PHYXS_TEST1, 310 efx_mdio_set_flag(efx, MDIO_MMD_PHYXS, PHYXS_TEST1,
515 1 << LOOPBACK_NEAR_LBN, 311 1 << LOOPBACK_NEAR_LBN,
516 efx->loopback_mode == LOOPBACK_PHYXS); 312 efx->loopback_mode == LOOPBACK_PHYXS);
517 if (efx->phy_type != PHY_TYPE_SFX7101)
518 efx_mdio_set_flag(efx, MDIO_MMD_C22EXT, GPHY_XCONTROL_REG,
519 1 << GPHY_LOOPBACK_NEAR_LBN,
520 efx->loopback_mode == LOOPBACK_GPHY);
521} 313}
522 314
523static void tenxpress_low_power(struct efx_nic *efx) 315static void tenxpress_low_power(struct efx_nic *efx)
524{ 316{
525 if (efx->phy_type == PHY_TYPE_SFX7101) 317 efx_mdio_set_mmds_lpower(
526 efx_mdio_set_mmds_lpower( 318 efx, !!(efx->phy_mode & PHY_MODE_LOW_POWER),
527 efx, !!(efx->phy_mode & PHY_MODE_LOW_POWER), 319 TENXPRESS_REQUIRED_DEVS);
528 TENXPRESS_REQUIRED_DEVS);
529 else
530 efx_mdio_set_flag(
531 efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG,
532 1 << PMA_PMD_EXT_LPOWER_LBN,
533 !!(efx->phy_mode & PHY_MODE_LOW_POWER));
534} 320}
535 321
536static int tenxpress_phy_reconfigure(struct efx_nic *efx) 322static int tenxpress_phy_reconfigure(struct efx_nic *efx)
@@ -550,12 +336,7 @@ static int tenxpress_phy_reconfigure(struct efx_nic *efx)
550 336
551 if (loop_reset || phy_mode_change) { 337 if (loop_reset || phy_mode_change) {
552 tenxpress_special_reset(efx); 338 tenxpress_special_reset(efx);
553 339 falcon_reset_xaui(efx);
554 /* Reset XAUI if we were in 10G, and are staying
555 * in 10G. If we're moving into and out of 10G
556 * then xaui will be reset anyway */
557 if (EFX_IS10G(efx))
558 falcon_reset_xaui(efx);
559 } 340 }
560 341
561 tenxpress_low_power(efx); 342 tenxpress_low_power(efx);
@@ -578,29 +359,12 @@ static bool tenxpress_phy_poll(struct efx_nic *efx)
578{ 359{
579 struct efx_link_state old_state = efx->link_state; 360 struct efx_link_state old_state = efx->link_state;
580 361
581 if (efx->phy_type == PHY_TYPE_SFX7101) { 362 efx->link_state.up = sfx7101_link_ok(efx);
582 efx->link_state.up = sfx7101_link_ok(efx); 363 efx->link_state.speed = 10000;
583 efx->link_state.speed = 10000; 364 efx->link_state.fd = true;
584 efx->link_state.fd = true; 365 efx->link_state.fc = efx_mdio_get_pause(efx);
585 efx->link_state.fc = efx_mdio_get_pause(efx);
586
587 sfx7101_check_bad_lp(efx, efx->link_state.up);
588 } else {
589 struct ethtool_cmd ecmd;
590
591 /* Check the LASI alarm first */
592 if (efx->loopback_mode == LOOPBACK_NONE &&
593 !(efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_STAT) &
594 MDIO_PMA_LASI_LSALARM))
595 return false;
596 366
597 tenxpress_get_settings(efx, &ecmd); 367 sfx7101_check_bad_lp(efx, efx->link_state.up);
598
599 efx->link_state.up = sft9001_link_ok(efx, &ecmd);
600 efx->link_state.speed = ecmd.speed;
601 efx->link_state.fd = (ecmd.duplex == DUPLEX_FULL);
602 efx->link_state.fc = efx_mdio_get_pause(efx);
603 }
604 368
605 return !efx_link_state_equal(&efx->link_state, &old_state); 369 return !efx_link_state_equal(&efx->link_state, &old_state);
606} 370}
@@ -621,10 +385,6 @@ static void sfx7101_phy_fini(struct efx_nic *efx)
621 385
622static void tenxpress_phy_remove(struct efx_nic *efx) 386static void tenxpress_phy_remove(struct efx_nic *efx)
623{ 387{
624 if (efx->phy_type == PHY_TYPE_SFT9001B)
625 device_remove_file(&efx->pci_dev->dev,
626 &dev_attr_phy_short_reach);
627
628 kfree(efx->phy_data); 388 kfree(efx->phy_data);
629 efx->phy_data = NULL; 389 efx->phy_data = NULL;
630} 390}
@@ -647,10 +407,7 @@ void tenxpress_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
647 (PMA_PMD_LED_ON << PMA_PMD_LED_LINK_LBN); 407 (PMA_PMD_LED_ON << PMA_PMD_LED_LINK_LBN);
648 break; 408 break;
649 default: 409 default:
650 if (efx->phy_type == PHY_TYPE_SFX7101) 410 reg = SFX7101_PMA_PMD_LED_DEFAULT;
651 reg = SFX7101_PMA_PMD_LED_DEFAULT;
652 else
653 reg = SFT9001_PMA_PMD_LED_DEFAULT;
654 break; 411 break;
655 } 412 }
656 413
@@ -685,102 +442,12 @@ sfx7101_run_tests(struct efx_nic *efx, int *results, unsigned flags)
685 return rc; 442 return rc;
686} 443}
687 444
688static const char *const sft9001_test_names[] = {
689 "bist",
690 "cable.pairA.status",
691 "cable.pairB.status",
692 "cable.pairC.status",
693 "cable.pairD.status",
694 "cable.pairA.length",
695 "cable.pairB.length",
696 "cable.pairC.length",
697 "cable.pairD.length",
698};
699
700static const char *sft9001_test_name(struct efx_nic *efx, unsigned int index)
701{
702 if (index < ARRAY_SIZE(sft9001_test_names))
703 return sft9001_test_names[index];
704 return NULL;
705}
706
707static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags)
708{
709 int rc = 0, rc2, i, ctrl_reg, res_reg;
710
711 /* Initialise cable diagnostic results to unknown failure */
712 for (i = 1; i < 9; ++i)
713 results[i] = -1;
714
715 /* Run cable diagnostics; wait up to 5 seconds for them to complete.
716 * A cable fault is not a self-test failure, but a timeout is. */
717 ctrl_reg = ((1 << CDIAG_CTRL_IMMED_LBN) |
718 (CDIAG_CTRL_LEN_METRES << CDIAG_CTRL_LEN_UNIT_LBN));
719 if (flags & ETH_TEST_FL_OFFLINE) {
720 /* Break the link in order to run full diagnostics. We
721 * must reset the PHY to resume normal service. */
722 ctrl_reg |= (1 << CDIAG_CTRL_BRK_LINK_LBN);
723 }
724 efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_CTRL_REG,
725 ctrl_reg);
726 i = 0;
727 while (efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_CTRL_REG) &
728 (1 << CDIAG_CTRL_IN_PROG_LBN)) {
729 if (++i == 50) {
730 rc = -ETIMEDOUT;
731 goto out;
732 }
733 msleep(100);
734 }
735 res_reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_RES_REG);
736 for (i = 0; i < 4; i++) {
737 int pair_res =
738 (res_reg >> (CDIAG_RES_A_LBN - i * CDIAG_RES_WIDTH))
739 & ((1 << CDIAG_RES_WIDTH) - 1);
740 int len_reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD,
741 PMA_PMD_CDIAG_LEN_REG + i);
742 if (pair_res == CDIAG_RES_OK)
743 results[1 + i] = 1;
744 else if (pair_res == CDIAG_RES_INVALID)
745 results[1 + i] = -1;
746 else
747 results[1 + i] = -pair_res;
748 if (pair_res != CDIAG_RES_INVALID &&
749 pair_res != CDIAG_RES_OPEN &&
750 len_reg != 0xffff)
751 results[5 + i] = len_reg;
752 }
753
754out:
755 if (flags & ETH_TEST_FL_OFFLINE) {
756 /* Reset, running the BIST and then resuming normal service. */
757 rc2 = tenxpress_special_reset(efx);
758 results[0] = rc2 ? -1 : 1;
759 if (!rc)
760 rc = rc2;
761
762 efx_mdio_an_reconfigure(efx);
763 }
764
765 return rc;
766}
767
768static void 445static void
769tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) 446tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
770{ 447{
771 u32 adv = 0, lpa = 0; 448 u32 adv = 0, lpa = 0;
772 int reg; 449 int reg;
773 450
774 if (efx->phy_type != PHY_TYPE_SFX7101) {
775 reg = efx_mdio_read(efx, MDIO_MMD_C22EXT, C22EXT_MSTSLV_CTRL);
776 if (reg & (1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN))
777 adv |= ADVERTISED_1000baseT_Full;
778 reg = efx_mdio_read(efx, MDIO_MMD_C22EXT, C22EXT_MSTSLV_STATUS);
779 if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN))
780 lpa |= ADVERTISED_1000baseT_Half;
781 if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN))
782 lpa |= ADVERTISED_1000baseT_Full;
783 }
784 reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL); 451 reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL);
785 if (reg & MDIO_AN_10GBT_CTRL_ADV10G) 452 if (reg & MDIO_AN_10GBT_CTRL_ADV10G)
786 adv |= ADVERTISED_10000baseT_Full; 453 adv |= ADVERTISED_10000baseT_Full;
@@ -790,24 +457,10 @@ tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
790 457
791 mdio45_ethtool_gset_npage(&efx->mdio, ecmd, adv, lpa); 458 mdio45_ethtool_gset_npage(&efx->mdio, ecmd, adv, lpa);
792 459
793 if (efx->phy_type != PHY_TYPE_SFX7101) {
794 ecmd->supported |= (SUPPORTED_100baseT_Full |
795 SUPPORTED_1000baseT_Full);
796 if (ecmd->speed != SPEED_10000) {
797 ecmd->eth_tp_mdix =
798 (efx_mdio_read(efx, MDIO_MMD_PMAPMD,
799 PMA_PMD_XSTATUS_REG) &
800 (1 << PMA_PMD_XSTAT_MDIX_LBN))
801 ? ETH_TP_MDI_X : ETH_TP_MDI;
802 }
803 }
804
805 /* In loopback, the PHY automatically brings up the correct interface, 460 /* In loopback, the PHY automatically brings up the correct interface,
806 * but doesn't advertise the correct speed. So override it */ 461 * but doesn't advertise the correct speed. So override it */
807 if (efx->loopback_mode == LOOPBACK_GPHY) 462 if (LOOPBACK_EXTERNAL(efx))
808 ecmd->speed = SPEED_1000; 463 ethtool_cmd_speed_set(ecmd, SPEED_10000);
809 else if (LOOPBACK_EXTERNAL(efx))
810 ecmd->speed = SPEED_10000;
811} 464}
812 465
813static int tenxpress_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) 466static int tenxpress_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
@@ -825,17 +478,7 @@ static void sfx7101_set_npage_adv(struct efx_nic *efx, u32 advertising)
825 advertising & ADVERTISED_10000baseT_Full); 478 advertising & ADVERTISED_10000baseT_Full);
826} 479}
827 480
828static void sft9001_set_npage_adv(struct efx_nic *efx, u32 advertising) 481const struct efx_phy_operations falcon_sfx7101_phy_ops = {
829{
830 efx_mdio_set_flag(efx, MDIO_MMD_C22EXT, C22EXT_MSTSLV_CTRL,
831 1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN,
832 advertising & ADVERTISED_1000baseT_Full);
833 efx_mdio_set_flag(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
834 MDIO_AN_10GBT_CTRL_ADV10G,
835 advertising & ADVERTISED_10000baseT_Full);
836}
837
838struct efx_phy_operations falcon_sfx7101_phy_ops = {
839 .probe = tenxpress_phy_probe, 482 .probe = tenxpress_phy_probe,
840 .init = tenxpress_phy_init, 483 .init = tenxpress_phy_init,
841 .reconfigure = tenxpress_phy_reconfigure, 484 .reconfigure = tenxpress_phy_reconfigure,
@@ -849,18 +492,3 @@ struct efx_phy_operations falcon_sfx7101_phy_ops = {
849 .test_name = sfx7101_test_name, 492 .test_name = sfx7101_test_name,
850 .run_tests = sfx7101_run_tests, 493 .run_tests = sfx7101_run_tests,
851}; 494};
852
853struct efx_phy_operations falcon_sft9001_phy_ops = {
854 .probe = tenxpress_phy_probe,
855 .init = tenxpress_phy_init,
856 .reconfigure = tenxpress_phy_reconfigure,
857 .poll = tenxpress_phy_poll,
858 .fini = efx_port_dummy_op_void,
859 .remove = tenxpress_phy_remove,
860 .get_settings = tenxpress_get_settings,
861 .set_settings = tenxpress_set_settings,
862 .set_npage_adv = sft9001_set_npage_adv,
863 .test_alive = efx_mdio_test_alive,
864 .test_name = sft9001_test_name,
865 .run_tests = sft9001_run_tests,
866};