aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/tenxpress.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sfc/tenxpress.c')
-rw-r--r--drivers/net/sfc/tenxpress.c308
1 files changed, 175 insertions, 133 deletions
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index f4d509015f75..f21efe7bd316 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-2008 Solarflare Communications Inc. 3 * Copyright 2007-2009 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
@@ -10,12 +10,12 @@
10#include <linux/delay.h> 10#include <linux/delay.h>
11#include <linux/rtnetlink.h> 11#include <linux/rtnetlink.h>
12#include <linux/seq_file.h> 12#include <linux/seq_file.h>
13#include <linux/slab.h>
13#include "efx.h" 14#include "efx.h"
14#include "mdio_10g.h" 15#include "mdio_10g.h"
15#include "falcon.h" 16#include "nic.h"
16#include "phy.h" 17#include "phy.h"
17#include "falcon_hwdefs.h" 18#include "regs.h"
18#include "boards.h"
19#include "workarounds.h" 19#include "workarounds.h"
20#include "selftest.h" 20#include "selftest.h"
21 21
@@ -31,13 +31,13 @@
31#define SFX7101_LOOPBACKS ((1 << LOOPBACK_PHYXS) | \ 31#define SFX7101_LOOPBACKS ((1 << LOOPBACK_PHYXS) | \
32 (1 << LOOPBACK_PCS) | \ 32 (1 << LOOPBACK_PCS) | \
33 (1 << LOOPBACK_PMAPMD) | \ 33 (1 << LOOPBACK_PMAPMD) | \
34 (1 << LOOPBACK_NETWORK)) 34 (1 << LOOPBACK_PHYXS_WS))
35 35
36#define SFT9001_LOOPBACKS ((1 << LOOPBACK_GPHY) | \ 36#define SFT9001_LOOPBACKS ((1 << LOOPBACK_GPHY) | \
37 (1 << LOOPBACK_PHYXS) | \ 37 (1 << LOOPBACK_PHYXS) | \
38 (1 << LOOPBACK_PCS) | \ 38 (1 << LOOPBACK_PCS) | \
39 (1 << LOOPBACK_PMAPMD) | \ 39 (1 << LOOPBACK_PMAPMD) | \
40 (1 << LOOPBACK_NETWORK)) 40 (1 << LOOPBACK_PHYXS_WS))
41 41
42/* We complain if we fail to see the link partner as 10G capable this many 42/* 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) 43 * times in a row (must be > 1 as sampling the autoneg. registers is racy)
@@ -84,9 +84,9 @@
84#define PMA_PMD_LED_FLASH (3) 84#define PMA_PMD_LED_FLASH (3)
85#define PMA_PMD_LED_MASK 3 85#define PMA_PMD_LED_MASK 3
86/* All LEDs under hardware control */ 86/* All LEDs under hardware control */
87#define PMA_PMD_LED_FULL_AUTO (0) 87#define SFT9001_PMA_PMD_LED_DEFAULT 0
88/* Green and Amber under hardware control, Red off */ 88/* Green and Amber under hardware control, Red off */
89#define PMA_PMD_LED_DEFAULT (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN) 89#define SFX7101_PMA_PMD_LED_DEFAULT (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN)
90 90
91#define PMA_PMD_SPEED_ENABLE_REG 49192 91#define PMA_PMD_SPEED_ENABLE_REG 49192
92#define PMA_PMD_100TX_ADV_LBN 1 92#define PMA_PMD_100TX_ADV_LBN 1
@@ -200,15 +200,20 @@ static ssize_t set_phy_short_reach(struct device *dev,
200 const char *buf, size_t count) 200 const char *buf, size_t count)
201{ 201{
202 struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev)); 202 struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
203 int rc;
203 204
204 rtnl_lock(); 205 rtnl_lock();
205 efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR, 206 if (efx->state != STATE_RUNNING) {
206 MDIO_PMA_10GBT_TXPWR_SHORT, 207 rc = -EBUSY;
207 count != 0 && *buf != '0'); 208 } else {
208 efx_reconfigure_port(efx); 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 }
209 rtnl_unlock(); 214 rtnl_unlock();
210 215
211 return count; 216 return rc < 0 ? rc : (ssize_t)count;
212} 217}
213 218
214static DEVICE_ATTR(phy_short_reach, 0644, show_phy_short_reach, 219static DEVICE_ATTR(phy_short_reach, 0644, show_phy_short_reach,
@@ -292,23 +297,68 @@ static int tenxpress_init(struct efx_nic *efx)
292 efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_CTRL_REG, 297 efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_CTRL_REG,
293 1 << PMA_PMA_LED_ACTIVITY_LBN, true); 298 1 << PMA_PMA_LED_ACTIVITY_LBN, true);
294 efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG, 299 efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG,
295 PMA_PMD_LED_DEFAULT); 300 SFX7101_PMA_PMD_LED_DEFAULT);
296 } 301 }
297 302
298 return 0; 303 return 0;
299} 304}
300 305
301static int tenxpress_phy_init(struct efx_nic *efx) 306static int tenxpress_phy_probe(struct efx_nic *efx)
302{ 307{
303 struct tenxpress_phy_data *phy_data; 308 struct tenxpress_phy_data *phy_data;
304 int rc = 0; 309 int rc;
305 310
311 /* Allocate phy private storage */
306 phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL); 312 phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL);
307 if (!phy_data) 313 if (!phy_data)
308 return -ENOMEM; 314 return -ENOMEM;
309 efx->phy_data = phy_data; 315 efx->phy_data = phy_data;
310 phy_data->phy_mode = efx->phy_mode; 316 phy_data->phy_mode = efx->phy_mode;
311 317
318 /* Create any special files */
319 if (efx->phy_type == PHY_TYPE_SFT9001B) {
320 rc = device_create_file(&efx->pci_dev->dev,
321 &dev_attr_phy_short_reach);
322 if (rc)
323 goto fail;
324 }
325
326 if (efx->phy_type == PHY_TYPE_SFX7101) {
327 efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS;
328 efx->mdio.mode_support = MDIO_SUPPORTS_C45;
329
330 efx->loopback_modes = SFX7101_LOOPBACKS | FALCON_XMAC_LOOPBACKS;
331
332 efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg |
333 ADVERTISED_10000baseT_Full);
334 } else {
335 efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS;
336 efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
337
338 efx->loopback_modes = (SFT9001_LOOPBACKS |
339 FALCON_XMAC_LOOPBACKS |
340 FALCON_GMAC_LOOPBACKS);
341
342 efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg |
343 ADVERTISED_10000baseT_Full |
344 ADVERTISED_1000baseT_Full |
345 ADVERTISED_100baseT_Full);
346 }
347
348 return 0;
349
350fail:
351 kfree(efx->phy_data);
352 efx->phy_data = NULL;
353 return rc;
354}
355
356static int tenxpress_phy_init(struct efx_nic *efx)
357{
358 int rc;
359
360 falcon_board(efx)->type->init_phy(efx);
361
312 if (!(efx->phy_mode & PHY_MODE_SPECIAL)) { 362 if (!(efx->phy_mode & PHY_MODE_SPECIAL)) {
313 if (efx->phy_type == PHY_TYPE_SFT9001A) { 363 if (efx->phy_type == PHY_TYPE_SFT9001A) {
314 int reg; 364 int reg;
@@ -322,23 +372,20 @@ static int tenxpress_phy_init(struct efx_nic *efx)
322 372
323 rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS); 373 rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS);
324 if (rc < 0) 374 if (rc < 0)
325 goto fail; 375 return rc;
326 376
327 rc = efx_mdio_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0); 377 rc = efx_mdio_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0);
328 if (rc < 0) 378 if (rc < 0)
329 goto fail; 379 return rc;
330 } 380 }
331 381
332 rc = tenxpress_init(efx); 382 rc = tenxpress_init(efx);
333 if (rc < 0) 383 if (rc < 0)
334 goto fail; 384 return rc;
335 385
336 if (efx->phy_type == PHY_TYPE_SFT9001B) { 386 /* Reinitialise flow control settings */
337 rc = device_create_file(&efx->pci_dev->dev, 387 efx_link_set_wanted_fc(efx, efx->wanted_fc);
338 &dev_attr_phy_short_reach); 388 efx_mdio_an_reconfigure(efx);
339 if (rc)
340 goto fail;
341 }
342 389
343 schedule_timeout_uninterruptible(HZ / 5); /* 200ms */ 390 schedule_timeout_uninterruptible(HZ / 5); /* 200ms */
344 391
@@ -346,11 +393,6 @@ static int tenxpress_phy_init(struct efx_nic *efx)
346 falcon_reset_xaui(efx); 393 falcon_reset_xaui(efx);
347 394
348 return 0; 395 return 0;
349
350 fail:
351 kfree(efx->phy_data);
352 efx->phy_data = NULL;
353 return rc;
354} 396}
355 397
356/* Perform a "special software reset" on the PHY. The caller is 398/* Perform a "special software reset" on the PHY. The caller is
@@ -363,7 +405,7 @@ static int tenxpress_special_reset(struct efx_nic *efx)
363 /* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so 405 /* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so
364 * a special software reset can glitch the XGMAC sufficiently for stats 406 * a special software reset can glitch the XGMAC sufficiently for stats
365 * requests to fail. */ 407 * requests to fail. */
366 efx_stats_disable(efx); 408 falcon_stop_nic_stats(efx);
367 409
368 /* Initiate reset */ 410 /* Initiate reset */
369 reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG); 411 reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG);
@@ -385,7 +427,7 @@ static int tenxpress_special_reset(struct efx_nic *efx)
385 /* Wait for the XGXS state machine to churn */ 427 /* Wait for the XGXS state machine to churn */
386 mdelay(10); 428 mdelay(10);
387out: 429out:
388 efx_stats_enable(efx); 430 falcon_start_nic_stats(efx);
389 return rc; 431 return rc;
390} 432}
391 433
@@ -489,133 +531,126 @@ static void tenxpress_low_power(struct efx_nic *efx)
489 !!(efx->phy_mode & PHY_MODE_LOW_POWER)); 531 !!(efx->phy_mode & PHY_MODE_LOW_POWER));
490} 532}
491 533
492static void tenxpress_phy_reconfigure(struct efx_nic *efx) 534static int tenxpress_phy_reconfigure(struct efx_nic *efx)
493{ 535{
494 struct tenxpress_phy_data *phy_data = efx->phy_data; 536 struct tenxpress_phy_data *phy_data = efx->phy_data;
495 struct ethtool_cmd ecmd;
496 bool phy_mode_change, loop_reset; 537 bool phy_mode_change, loop_reset;
497 538
498 if (efx->phy_mode & (PHY_MODE_OFF | PHY_MODE_SPECIAL)) { 539 if (efx->phy_mode & (PHY_MODE_OFF | PHY_MODE_SPECIAL)) {
499 phy_data->phy_mode = efx->phy_mode; 540 phy_data->phy_mode = efx->phy_mode;
500 return; 541 return 0;
501 } 542 }
502 543
503 tenxpress_low_power(efx);
504
505 phy_mode_change = (efx->phy_mode == PHY_MODE_NORMAL && 544 phy_mode_change = (efx->phy_mode == PHY_MODE_NORMAL &&
506 phy_data->phy_mode != PHY_MODE_NORMAL); 545 phy_data->phy_mode != PHY_MODE_NORMAL);
507 loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, efx->phy_op->loopbacks) || 546 loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, LOOPBACKS_EXTERNAL(efx)) ||
508 LOOPBACK_CHANGED(phy_data, efx, 1 << LOOPBACK_GPHY)); 547 LOOPBACK_CHANGED(phy_data, efx, 1 << LOOPBACK_GPHY));
509 548
510 if (loop_reset || phy_mode_change) { 549 if (loop_reset || phy_mode_change) {
511 int rc; 550 tenxpress_special_reset(efx);
512
513 efx->phy_op->get_settings(efx, &ecmd);
514
515 if (loop_reset || phy_mode_change) {
516 tenxpress_special_reset(efx);
517
518 /* Reset XAUI if we were in 10G, and are staying
519 * in 10G. If we're moving into and out of 10G
520 * then xaui will be reset anyway */
521 if (EFX_IS10G(efx))
522 falcon_reset_xaui(efx);
523 }
524 551
525 rc = efx->phy_op->set_settings(efx, &ecmd); 552 /* Reset XAUI if we were in 10G, and are staying
526 WARN_ON(rc); 553 * in 10G. If we're moving into and out of 10G
554 * then xaui will be reset anyway */
555 if (EFX_IS10G(efx))
556 falcon_reset_xaui(efx);
527 } 557 }
528 558
559 tenxpress_low_power(efx);
529 efx_mdio_transmit_disable(efx); 560 efx_mdio_transmit_disable(efx);
530 efx_mdio_phy_reconfigure(efx); 561 efx_mdio_phy_reconfigure(efx);
531 tenxpress_ext_loopback(efx); 562 tenxpress_ext_loopback(efx);
563 efx_mdio_an_reconfigure(efx);
532 564
533 phy_data->loopback_mode = efx->loopback_mode; 565 phy_data->loopback_mode = efx->loopback_mode;
534 phy_data->phy_mode = efx->phy_mode; 566 phy_data->phy_mode = efx->phy_mode;
535 567
536 if (efx->phy_type == PHY_TYPE_SFX7101) { 568 return 0;
537 efx->link_speed = 10000;
538 efx->link_fd = true;
539 efx->link_up = sfx7101_link_ok(efx);
540 } else {
541 efx->phy_op->get_settings(efx, &ecmd);
542 efx->link_speed = ecmd.speed;
543 efx->link_fd = ecmd.duplex == DUPLEX_FULL;
544 efx->link_up = sft9001_link_ok(efx, &ecmd);
545 }
546 efx->link_fc = efx_mdio_get_pause(efx);
547} 569}
548 570
549/* Poll PHY for interrupt */ 571static void
550static void tenxpress_phy_poll(struct efx_nic *efx) 572tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd);
573
574/* Poll for link state changes */
575static bool tenxpress_phy_poll(struct efx_nic *efx)
551{ 576{
552 struct tenxpress_phy_data *phy_data = efx->phy_data; 577 struct efx_link_state old_state = efx->link_state;
553 bool change = false;
554 578
555 if (efx->phy_type == PHY_TYPE_SFX7101) { 579 if (efx->phy_type == PHY_TYPE_SFX7101) {
556 bool link_ok = sfx7101_link_ok(efx); 580 efx->link_state.up = sfx7101_link_ok(efx);
557 if (link_ok != efx->link_up) { 581 efx->link_state.speed = 10000;
558 change = true; 582 efx->link_state.fd = true;
559 } else { 583 efx->link_state.fc = efx_mdio_get_pause(efx);
560 unsigned int link_fc = efx_mdio_get_pause(efx); 584
561 if (link_fc != efx->link_fc) 585 sfx7101_check_bad_lp(efx, efx->link_state.up);
562 change = true;
563 }
564 sfx7101_check_bad_lp(efx, link_ok);
565 } else if (efx->loopback_mode) {
566 bool link_ok = sft9001_link_ok(efx, NULL);
567 if (link_ok != efx->link_up)
568 change = true;
569 } else { 586 } else {
570 int status = efx_mdio_read(efx, MDIO_MMD_PMAPMD, 587 struct ethtool_cmd ecmd;
571 MDIO_PMA_LASI_STAT);
572 if (status & MDIO_PMA_LASI_LSALARM)
573 change = true;
574 }
575 588
576 if (change) 589 /* Check the LASI alarm first */
577 falcon_sim_phy_event(efx); 590 if (efx->loopback_mode == LOOPBACK_NONE &&
591 !(efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_STAT) &
592 MDIO_PMA_LASI_LSALARM))
593 return false;
578 594
579 if (phy_data->phy_mode != PHY_MODE_NORMAL) 595 tenxpress_get_settings(efx, &ecmd);
580 return; 596
597 efx->link_state.up = sft9001_link_ok(efx, &ecmd);
598 efx->link_state.speed = ecmd.speed;
599 efx->link_state.fd = (ecmd.duplex == DUPLEX_FULL);
600 efx->link_state.fc = efx_mdio_get_pause(efx);
601 }
602
603 return !efx_link_state_equal(&efx->link_state, &old_state);
581} 604}
582 605
583static void tenxpress_phy_fini(struct efx_nic *efx) 606static void sfx7101_phy_fini(struct efx_nic *efx)
584{ 607{
585 int reg; 608 int reg;
586 609
610 /* Power down the LNPGA */
611 reg = (1 << PMA_PMD_LNPGA_POWERDOWN_LBN);
612 efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg);
613
614 /* Waiting here ensures that the board fini, which can turn
615 * off the power to the PHY, won't get run until the LNPGA
616 * powerdown has been given long enough to complete. */
617 schedule_timeout_uninterruptible(LNPGA_PDOWN_WAIT); /* 200 ms */
618}
619
620static void tenxpress_phy_remove(struct efx_nic *efx)
621{
587 if (efx->phy_type == PHY_TYPE_SFT9001B) 622 if (efx->phy_type == PHY_TYPE_SFT9001B)
588 device_remove_file(&efx->pci_dev->dev, 623 device_remove_file(&efx->pci_dev->dev,
589 &dev_attr_phy_short_reach); 624 &dev_attr_phy_short_reach);
590 625
591 if (efx->phy_type == PHY_TYPE_SFX7101) {
592 /* Power down the LNPGA */
593 reg = (1 << PMA_PMD_LNPGA_POWERDOWN_LBN);
594 efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg);
595
596 /* Waiting here ensures that the board fini, which can turn
597 * off the power to the PHY, won't get run until the LNPGA
598 * powerdown has been given long enough to complete. */
599 schedule_timeout_uninterruptible(LNPGA_PDOWN_WAIT); /* 200 ms */
600 }
601
602 kfree(efx->phy_data); 626 kfree(efx->phy_data);
603 efx->phy_data = NULL; 627 efx->phy_data = NULL;
604} 628}
605 629
606 630
607/* Set the RX and TX LEDs and Link LED flashing. The other LEDs 631/* Override the RX, TX and link LEDs */
608 * (which probably aren't wired anyway) are left in AUTO mode */ 632void tenxpress_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
609void tenxpress_phy_blink(struct efx_nic *efx, bool blink)
610{ 633{
611 int reg; 634 int reg;
612 635
613 if (blink) 636 switch (mode) {
614 reg = (PMA_PMD_LED_FLASH << PMA_PMD_LED_TX_LBN) | 637 case EFX_LED_OFF:
615 (PMA_PMD_LED_FLASH << PMA_PMD_LED_RX_LBN) | 638 reg = (PMA_PMD_LED_OFF << PMA_PMD_LED_TX_LBN) |
616 (PMA_PMD_LED_FLASH << PMA_PMD_LED_LINK_LBN); 639 (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN) |
617 else 640 (PMA_PMD_LED_OFF << PMA_PMD_LED_LINK_LBN);
618 reg = PMA_PMD_LED_DEFAULT; 641 break;
642 case EFX_LED_ON:
643 reg = (PMA_PMD_LED_ON << PMA_PMD_LED_TX_LBN) |
644 (PMA_PMD_LED_ON << PMA_PMD_LED_RX_LBN) |
645 (PMA_PMD_LED_ON << PMA_PMD_LED_LINK_LBN);
646 break;
647 default:
648 if (efx->phy_type == PHY_TYPE_SFX7101)
649 reg = SFX7101_PMA_PMD_LED_DEFAULT;
650 else
651 reg = SFT9001_PMA_PMD_LED_DEFAULT;
652 break;
653 }
619 654
620 efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG, reg); 655 efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG, reg);
621} 656}
@@ -624,6 +659,13 @@ static const char *const sfx7101_test_names[] = {
624 "bist" 659 "bist"
625}; 660};
626 661
662static const char *sfx7101_test_name(struct efx_nic *efx, unsigned int index)
663{
664 if (index < ARRAY_SIZE(sfx7101_test_names))
665 return sfx7101_test_names[index];
666 return NULL;
667}
668
627static int 669static int
628sfx7101_run_tests(struct efx_nic *efx, int *results, unsigned flags) 670sfx7101_run_tests(struct efx_nic *efx, int *results, unsigned flags)
629{ 671{
@@ -635,6 +677,9 @@ sfx7101_run_tests(struct efx_nic *efx, int *results, unsigned flags)
635 /* BIST is automatically run after a special software reset */ 677 /* BIST is automatically run after a special software reset */
636 rc = tenxpress_special_reset(efx); 678 rc = tenxpress_special_reset(efx);
637 results[0] = rc ? -1 : 1; 679 results[0] = rc ? -1 : 1;
680
681 efx_mdio_an_reconfigure(efx);
682
638 return rc; 683 return rc;
639} 684}
640 685
@@ -650,14 +695,17 @@ static const char *const sft9001_test_names[] = {
650 "cable.pairD.length", 695 "cable.pairD.length",
651}; 696};
652 697
698static const char *sft9001_test_name(struct efx_nic *efx, unsigned int index)
699{
700 if (index < ARRAY_SIZE(sft9001_test_names))
701 return sft9001_test_names[index];
702 return NULL;
703}
704
653static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags) 705static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags)
654{ 706{
655 struct ethtool_cmd ecmd;
656 int rc = 0, rc2, i, ctrl_reg, res_reg; 707 int rc = 0, rc2, i, ctrl_reg, res_reg;
657 708
658 if (flags & ETH_TEST_FL_OFFLINE)
659 efx->phy_op->get_settings(efx, &ecmd);
660
661 /* Initialise cable diagnostic results to unknown failure */ 709 /* Initialise cable diagnostic results to unknown failure */
662 for (i = 1; i < 9; ++i) 710 for (i = 1; i < 9; ++i)
663 results[i] = -1; 711 results[i] = -1;
@@ -709,9 +757,7 @@ out:
709 if (!rc) 757 if (!rc)
710 rc = rc2; 758 rc = rc2;
711 759
712 rc2 = efx->phy_op->set_settings(efx, &ecmd); 760 efx_mdio_an_reconfigure(efx);
713 if (!rc)
714 rc = rc2;
715 } 761 }
716 762
717 return rc; 763 return rc;
@@ -758,7 +804,7 @@ tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
758 * but doesn't advertise the correct speed. So override it */ 804 * but doesn't advertise the correct speed. So override it */
759 if (efx->loopback_mode == LOOPBACK_GPHY) 805 if (efx->loopback_mode == LOOPBACK_GPHY)
760 ecmd->speed = SPEED_1000; 806 ecmd->speed = SPEED_1000;
761 else if (LOOPBACK_MASK(efx) & efx->phy_op->loopbacks) 807 else if (LOOPBACK_EXTERNAL(efx))
762 ecmd->speed = SPEED_10000; 808 ecmd->speed = SPEED_10000;
763} 809}
764 810
@@ -788,35 +834,31 @@ static void sft9001_set_npage_adv(struct efx_nic *efx, u32 advertising)
788} 834}
789 835
790struct efx_phy_operations falcon_sfx7101_phy_ops = { 836struct efx_phy_operations falcon_sfx7101_phy_ops = {
791 .macs = EFX_XMAC, 837 .probe = tenxpress_phy_probe,
792 .init = tenxpress_phy_init, 838 .init = tenxpress_phy_init,
793 .reconfigure = tenxpress_phy_reconfigure, 839 .reconfigure = tenxpress_phy_reconfigure,
794 .poll = tenxpress_phy_poll, 840 .poll = tenxpress_phy_poll,
795 .fini = tenxpress_phy_fini, 841 .fini = sfx7101_phy_fini,
796 .clear_interrupt = efx_port_dummy_op_void, 842 .remove = tenxpress_phy_remove,
797 .get_settings = tenxpress_get_settings, 843 .get_settings = tenxpress_get_settings,
798 .set_settings = tenxpress_set_settings, 844 .set_settings = tenxpress_set_settings,
799 .set_npage_adv = sfx7101_set_npage_adv, 845 .set_npage_adv = sfx7101_set_npage_adv,
800 .num_tests = ARRAY_SIZE(sfx7101_test_names), 846 .test_alive = efx_mdio_test_alive,
801 .test_names = sfx7101_test_names, 847 .test_name = sfx7101_test_name,
802 .run_tests = sfx7101_run_tests, 848 .run_tests = sfx7101_run_tests,
803 .mmds = TENXPRESS_REQUIRED_DEVS,
804 .loopbacks = SFX7101_LOOPBACKS,
805}; 849};
806 850
807struct efx_phy_operations falcon_sft9001_phy_ops = { 851struct efx_phy_operations falcon_sft9001_phy_ops = {
808 .macs = EFX_GMAC | EFX_XMAC, 852 .probe = tenxpress_phy_probe,
809 .init = tenxpress_phy_init, 853 .init = tenxpress_phy_init,
810 .reconfigure = tenxpress_phy_reconfigure, 854 .reconfigure = tenxpress_phy_reconfigure,
811 .poll = tenxpress_phy_poll, 855 .poll = tenxpress_phy_poll,
812 .fini = tenxpress_phy_fini, 856 .fini = efx_port_dummy_op_void,
813 .clear_interrupt = efx_port_dummy_op_void, 857 .remove = tenxpress_phy_remove,
814 .get_settings = tenxpress_get_settings, 858 .get_settings = tenxpress_get_settings,
815 .set_settings = tenxpress_set_settings, 859 .set_settings = tenxpress_set_settings,
816 .set_npage_adv = sft9001_set_npage_adv, 860 .set_npage_adv = sft9001_set_npage_adv,
817 .num_tests = ARRAY_SIZE(sft9001_test_names), 861 .test_alive = efx_mdio_test_alive,
818 .test_names = sft9001_test_names, 862 .test_name = sft9001_test_name,
819 .run_tests = sft9001_run_tests, 863 .run_tests = sft9001_run_tests,
820 .mmds = TENXPRESS_REQUIRED_DEVS,
821 .loopbacks = SFT9001_LOOPBACKS,
822}; 864};