aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/sfc/efx.c63
-rw-r--r--drivers/net/sfc/falcon.c20
-rw-r--r--drivers/net/sfc/falcon_gmac.c8
-rw-r--r--drivers/net/sfc/falcon_hwdefs.h2
-rw-r--r--drivers/net/sfc/falcon_xmac.c42
-rw-r--r--drivers/net/sfc/net_driver.h24
-rw-r--r--drivers/net/sfc/selftest.c6
-rw-r--r--drivers/net/sfc/tenxpress.c44
-rw-r--r--drivers/net/sfc/xfp_phy.c16
9 files changed, 111 insertions, 114 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 7214ea6f7e1d..ce1c7d3cd12e 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -612,10 +612,9 @@ void efx_reconfigure_port(struct efx_nic *efx)
612/* Asynchronous efx_reconfigure_port work item. To speed up efx_flush_all() 612/* Asynchronous efx_reconfigure_port work item. To speed up efx_flush_all()
613 * we don't efx_reconfigure_port() if the port is disabled. Care is taken 613 * we don't efx_reconfigure_port() if the port is disabled. Care is taken
614 * in efx_stop_all() and efx_start_port() to prevent PHY events being lost */ 614 * in efx_stop_all() and efx_start_port() to prevent PHY events being lost */
615static void efx_reconfigure_work(struct work_struct *data) 615static void efx_phy_work(struct work_struct *data)
616{ 616{
617 struct efx_nic *efx = container_of(data, struct efx_nic, 617 struct efx_nic *efx = container_of(data, struct efx_nic, phy_work);
618 reconfigure_work);
619 618
620 mutex_lock(&efx->mac_lock); 619 mutex_lock(&efx->mac_lock);
621 if (efx->port_enabled) 620 if (efx->port_enabled)
@@ -623,6 +622,16 @@ static void efx_reconfigure_work(struct work_struct *data)
623 mutex_unlock(&efx->mac_lock); 622 mutex_unlock(&efx->mac_lock);
624} 623}
625 624
625static void efx_mac_work(struct work_struct *data)
626{
627 struct efx_nic *efx = container_of(data, struct efx_nic, mac_work);
628
629 mutex_lock(&efx->mac_lock);
630 if (efx->port_enabled)
631 efx->mac_op->irq(efx);
632 mutex_unlock(&efx->mac_lock);
633}
634
626static int efx_probe_port(struct efx_nic *efx) 635static int efx_probe_port(struct efx_nic *efx)
627{ 636{
628 int rc; 637 int rc;
@@ -688,7 +697,7 @@ fail:
688 697
689/* Allow efx_reconfigure_port() to be scheduled, and close the window 698/* Allow efx_reconfigure_port() to be scheduled, and close the window
690 * between efx_stop_port and efx_flush_all whereby a previously scheduled 699 * between efx_stop_port and efx_flush_all whereby a previously scheduled
691 * efx_reconfigure_port() may have been cancelled */ 700 * efx_phy_work()/efx_mac_work() may have been cancelled */
692static void efx_start_port(struct efx_nic *efx) 701static void efx_start_port(struct efx_nic *efx)
693{ 702{
694 EFX_LOG(efx, "start port\n"); 703 EFX_LOG(efx, "start port\n");
@@ -697,13 +706,14 @@ static void efx_start_port(struct efx_nic *efx)
697 mutex_lock(&efx->mac_lock); 706 mutex_lock(&efx->mac_lock);
698 efx->port_enabled = true; 707 efx->port_enabled = true;
699 __efx_reconfigure_port(efx); 708 __efx_reconfigure_port(efx);
709 efx->mac_op->irq(efx);
700 mutex_unlock(&efx->mac_lock); 710 mutex_unlock(&efx->mac_lock);
701} 711}
702 712
703/* Prevent efx_reconfigure_work and efx_monitor() from executing, and 713/* Prevent efx_phy_work, efx_mac_work, and efx_monitor() from executing,
704 * efx_set_multicast_list() from scheduling efx_reconfigure_work. 714 * and efx_set_multicast_list() from scheduling efx_phy_work. efx_phy_work
705 * efx_reconfigure_work can still be scheduled via NAPI processing 715 * and efx_mac_work may still be scheduled via NAPI processing until
706 * until efx_flush_all() is called */ 716 * efx_flush_all() is called */
707static void efx_stop_port(struct efx_nic *efx) 717static void efx_stop_port(struct efx_nic *efx)
708{ 718{
709 EFX_LOG(efx, "stop port\n"); 719 EFX_LOG(efx, "stop port\n");
@@ -1094,7 +1104,8 @@ static void efx_flush_all(struct efx_nic *efx)
1094 cancel_delayed_work_sync(&rx_queue->work); 1104 cancel_delayed_work_sync(&rx_queue->work);
1095 1105
1096 /* Stop scheduled port reconfigurations */ 1106 /* Stop scheduled port reconfigurations */
1097 cancel_work_sync(&efx->reconfigure_work); 1107 cancel_work_sync(&efx->mac_work);
1108 cancel_work_sync(&efx->phy_work);
1098 1109
1099} 1110}
1100 1111
@@ -1131,7 +1142,7 @@ static void efx_stop_all(struct efx_nic *efx)
1131 * window to loose phy events */ 1142 * window to loose phy events */
1132 efx_stop_port(efx); 1143 efx_stop_port(efx);
1133 1144
1134 /* Flush reconfigure_work, refill_workqueue, monitor_work */ 1145 /* Flush efx_phy_work, efx_mac_work, refill_workqueue, monitor_work */
1135 efx_flush_all(efx); 1146 efx_flush_all(efx);
1136 1147
1137 /* Isolate the MAC from the TX and RX engines, so that queue 1148 /* Isolate the MAC from the TX and RX engines, so that queue
@@ -1203,24 +1214,31 @@ static void efx_monitor(struct work_struct *data)
1203{ 1214{
1204 struct efx_nic *efx = container_of(data, struct efx_nic, 1215 struct efx_nic *efx = container_of(data, struct efx_nic,
1205 monitor_work.work); 1216 monitor_work.work);
1217 int rc;
1206 1218
1207 EFX_TRACE(efx, "hardware monitor executing on CPU %d\n", 1219 EFX_TRACE(efx, "hardware monitor executing on CPU %d\n",
1208 raw_smp_processor_id()); 1220 raw_smp_processor_id());
1209 1221
1210
1211 /* If the mac_lock is already held then it is likely a port 1222 /* If the mac_lock is already held then it is likely a port
1212 * reconfiguration is already in place, which will likely do 1223 * reconfiguration is already in place, which will likely do
1213 * most of the work of check_hw() anyway. */ 1224 * most of the work of check_hw() anyway. */
1214 if (!mutex_trylock(&efx->mac_lock)) { 1225 if (!mutex_trylock(&efx->mac_lock))
1215 queue_delayed_work(efx->workqueue, &efx->monitor_work, 1226 goto out_requeue;
1216 efx_monitor_interval); 1227 if (!efx->port_enabled)
1217 return; 1228 goto out_unlock;
1229 rc = efx->board_info.monitor(efx);
1230 if (rc) {
1231 EFX_ERR(efx, "Board sensor %s; shutting down PHY\n",
1232 (rc == -ERANGE) ? "reported fault" : "failed");
1233 efx->phy_mode |= PHY_MODE_LOW_POWER;
1234 falcon_sim_phy_event(efx);
1218 } 1235 }
1236 efx->phy_op->poll(efx);
1237 efx->mac_op->poll(efx);
1219 1238
1220 if (efx->port_enabled) 1239out_unlock:
1221 efx->mac_op->check_hw(efx);
1222 mutex_unlock(&efx->mac_lock); 1240 mutex_unlock(&efx->mac_lock);
1223 1241out_requeue:
1224 queue_delayed_work(efx->workqueue, &efx->monitor_work, 1242 queue_delayed_work(efx->workqueue, &efx->monitor_work,
1225 efx_monitor_interval); 1243 efx_monitor_interval);
1226} 1244}
@@ -1477,7 +1495,7 @@ static void efx_set_multicast_list(struct net_device *net_dev)
1477 return; 1495 return;
1478 1496
1479 if (changed) 1497 if (changed)
1480 queue_work(efx->workqueue, &efx->reconfigure_work); 1498 queue_work(efx->workqueue, &efx->phy_work);
1481 1499
1482 /* Create and activate new global multicast hash table */ 1500 /* Create and activate new global multicast hash table */
1483 falcon_set_multicast_hash(efx); 1501 falcon_set_multicast_hash(efx);
@@ -1800,12 +1818,14 @@ void efx_port_dummy_op_blink(struct efx_nic *efx, bool blink) {}
1800 1818
1801static struct efx_mac_operations efx_dummy_mac_operations = { 1819static struct efx_mac_operations efx_dummy_mac_operations = {
1802 .reconfigure = efx_port_dummy_op_void, 1820 .reconfigure = efx_port_dummy_op_void,
1821 .poll = efx_port_dummy_op_void,
1822 .irq = efx_port_dummy_op_void,
1803}; 1823};
1804 1824
1805static struct efx_phy_operations efx_dummy_phy_operations = { 1825static struct efx_phy_operations efx_dummy_phy_operations = {
1806 .init = efx_port_dummy_op_int, 1826 .init = efx_port_dummy_op_int,
1807 .reconfigure = efx_port_dummy_op_void, 1827 .reconfigure = efx_port_dummy_op_void,
1808 .check_hw = efx_port_dummy_op_int, 1828 .poll = efx_port_dummy_op_void,
1809 .fini = efx_port_dummy_op_void, 1829 .fini = efx_port_dummy_op_void,
1810 .clear_interrupt = efx_port_dummy_op_void, 1830 .clear_interrupt = efx_port_dummy_op_void,
1811}; 1831};
@@ -1857,7 +1877,8 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
1857 efx->mac_op = &efx_dummy_mac_operations; 1877 efx->mac_op = &efx_dummy_mac_operations;
1858 efx->phy_op = &efx_dummy_phy_operations; 1878 efx->phy_op = &efx_dummy_phy_operations;
1859 efx->mii.dev = net_dev; 1879 efx->mii.dev = net_dev;
1860 INIT_WORK(&efx->reconfigure_work, efx_reconfigure_work); 1880 INIT_WORK(&efx->phy_work, efx_phy_work);
1881 INIT_WORK(&efx->mac_work, efx_mac_work);
1861 atomic_set(&efx->netif_stop_count, 1); 1882 atomic_set(&efx->netif_stop_count, 1);
1862 1883
1863 for (i = 0; i < EFX_MAX_CHANNELS; i++) { 1884 for (i = 0; i < EFX_MAX_CHANNELS; i++) {
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index fde4e7912c39..5a70ee7e8142 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -910,22 +910,20 @@ static void falcon_handle_global_event(struct efx_channel *channel,
910 efx_qword_t *event) 910 efx_qword_t *event)
911{ 911{
912 struct efx_nic *efx = channel->efx; 912 struct efx_nic *efx = channel->efx;
913 bool is_phy_event = false, handled = false; 913 bool handled = false;
914 914
915 /* Check for interrupt on either port. Some boards have a
916 * single PHY wired to the interrupt line for port 1. */
917 if (EFX_QWORD_FIELD(*event, G_PHY0_INTR) || 915 if (EFX_QWORD_FIELD(*event, G_PHY0_INTR) ||
918 EFX_QWORD_FIELD(*event, G_PHY1_INTR) || 916 EFX_QWORD_FIELD(*event, G_PHY1_INTR) ||
919 EFX_QWORD_FIELD(*event, XG_PHY_INTR)) 917 EFX_QWORD_FIELD(*event, XG_PHY_INTR) ||
920 is_phy_event = true; 918 EFX_QWORD_FIELD(*event, XFP_PHY_INTR)) {
919 efx->phy_op->clear_interrupt(efx);
920 queue_work(efx->workqueue, &efx->phy_work);
921 handled = true;
922 }
921 923
922 if ((falcon_rev(efx) >= FALCON_REV_B0) && 924 if ((falcon_rev(efx) >= FALCON_REV_B0) &&
923 EFX_QWORD_FIELD(*event, XG_MNT_INTR_B0)) 925 EFX_QWORD_FIELD(*event, XG_MNT_INTR_B0)) {
924 is_phy_event = true; 926 queue_work(efx->workqueue, &efx->mac_work);
925
926 if (is_phy_event) {
927 efx->phy_op->clear_interrupt(efx);
928 queue_work(efx->workqueue, &efx->reconfigure_work);
929 handled = true; 927 handled = true;
930 } 928 }
931 929
diff --git a/drivers/net/sfc/falcon_gmac.c b/drivers/net/sfc/falcon_gmac.c
index b6e6eb963905..8865eae20ac5 100644
--- a/drivers/net/sfc/falcon_gmac.c
+++ b/drivers/net/sfc/falcon_gmac.c
@@ -221,13 +221,9 @@ static void falcon_update_stats_gmac(struct efx_nic *efx)
221 mac_stats->rx_lt64 = mac_stats->rx_good_lt64 + mac_stats->rx_bad_lt64; 221 mac_stats->rx_lt64 = mac_stats->rx_good_lt64 + mac_stats->rx_bad_lt64;
222} 222}
223 223
224static int falcon_check_gmac(struct efx_nic *efx)
225{
226 return efx->phy_op->check_hw(efx);
227}
228
229struct efx_mac_operations falcon_gmac_operations = { 224struct efx_mac_operations falcon_gmac_operations = {
230 .reconfigure = falcon_reconfigure_gmac, 225 .reconfigure = falcon_reconfigure_gmac,
231 .update_stats = falcon_update_stats_gmac, 226 .update_stats = falcon_update_stats_gmac,
232 .check_hw = falcon_check_gmac, 227 .irq = efx_port_dummy_op_void,
228 .poll = efx_port_dummy_op_void,
233}; 229};
diff --git a/drivers/net/sfc/falcon_hwdefs.h b/drivers/net/sfc/falcon_hwdefs.h
index 5553df888b84..a58c627f51aa 100644
--- a/drivers/net/sfc/falcon_hwdefs.h
+++ b/drivers/net/sfc/falcon_hwdefs.h
@@ -1051,6 +1051,8 @@
1051#define XG_MNT_INTR_B0_WIDTH 1 1051#define XG_MNT_INTR_B0_WIDTH 1
1052#define RX_RECOVERY_A1_LBN 11 1052#define RX_RECOVERY_A1_LBN 11
1053#define RX_RECOVERY_A1_WIDTH 1 1053#define RX_RECOVERY_A1_WIDTH 1
1054#define XFP_PHY_INTR_LBN 10
1055#define XFP_PHY_INTR_WIDTH 1
1054#define XG_PHY_INTR_LBN 9 1056#define XG_PHY_INTR_LBN 9
1055#define XG_PHY_INTR_WIDTH 1 1057#define XG_PHY_INTR_WIDTH 1
1056#define G_PHY1_INTR_LBN 8 1058#define G_PHY1_INTR_LBN 8
diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c
index 0ce8f015386c..5a03713685ac 100644
--- a/drivers/net/sfc/falcon_xmac.c
+++ b/drivers/net/sfc/falcon_xmac.c
@@ -342,33 +342,35 @@ static void falcon_update_stats_xmac(struct efx_nic *efx)
342 mac_stats->rx_control * 64); 342 mac_stats->rx_control * 64);
343} 343}
344 344
345static int falcon_check_xmac(struct efx_nic *efx) 345static void falcon_xmac_irq(struct efx_nic *efx)
346{ 346{
347 bool xaui_link_ok; 347 /* The XGMII link has a transient fault, which indicates either:
348 int rc; 348 * - there's a transient xgmii fault
349 * - falcon's end of the xaui link may need a kick
350 * - the wire-side link may have gone down, but the lasi/poll()
351 * hasn't noticed yet.
352 *
353 * We only want to even bother polling XAUI if we're confident it's
354 * not (1) or (3). In both cases, the only reliable way to spot this
355 * is to wait a bit. We do this here by forcing the mac link state
356 * to down, and waiting for the mac poll to come round and check
357 */
358 efx->mac_up = false;
359}
349 360
350 if ((efx->loopback_mode == LOOPBACK_NETWORK) || 361static void falcon_poll_xmac(struct efx_nic *efx)
351 efx_phy_mode_disabled(efx->phy_mode)) 362{
352 return 0; 363 if (!EFX_WORKAROUND_5147(efx) || !efx->link_up || efx->mac_up)
364 return;
353 365
354 falcon_mask_status_intr(efx, false); 366 falcon_mask_status_intr(efx, false);
355 xaui_link_ok = falcon_xaui_link_ok(efx); 367 falcon_check_xaui_link_up(efx, 1);
356 368 falcon_mask_status_intr(efx, true);
357 if (EFX_WORKAROUND_5147(efx) && !xaui_link_ok)
358 falcon_reset_xaui(efx);
359
360 /* Call the PHY check_hw routine */
361 rc = efx->phy_op->check_hw(efx);
362
363 /* Unmask interrupt if everything was (and still is) ok */
364 if (xaui_link_ok && efx->link_up)
365 falcon_mask_status_intr(efx, true);
366
367 return rc;
368} 369}
369 370
370struct efx_mac_operations falcon_xmac_operations = { 371struct efx_mac_operations falcon_xmac_operations = {
371 .reconfigure = falcon_reconfigure_xmac, 372 .reconfigure = falcon_reconfigure_xmac,
372 .update_stats = falcon_update_stats_xmac, 373 .update_stats = falcon_update_stats_xmac,
373 .check_hw = falcon_check_xmac, 374 .irq = falcon_xmac_irq,
375 .poll = falcon_poll_xmac,
374}; 376};
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index fb8d72527a34..61d09a2fa724 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -544,12 +544,14 @@ static inline enum efx_fc_type efx_fc_resolve(enum efx_fc_type wanted_fc,
544 * struct efx_mac_operations - Efx MAC operations table 544 * struct efx_mac_operations - Efx MAC operations table
545 * @reconfigure: Reconfigure MAC. Serialised by the mac_lock 545 * @reconfigure: Reconfigure MAC. Serialised by the mac_lock
546 * @update_stats: Update statistics 546 * @update_stats: Update statistics
547 * @check_hw: Check hardware. Serialised by the mac_lock 547 * @irq: Hardware MAC event callback. Serialised by the mac_lock
548 * @poll: Poll for hardware state. Serialised by the mac_lock
548 */ 549 */
549struct efx_mac_operations { 550struct efx_mac_operations {
550 void (*reconfigure) (struct efx_nic *efx); 551 void (*reconfigure) (struct efx_nic *efx);
551 void (*update_stats) (struct efx_nic *efx); 552 void (*update_stats) (struct efx_nic *efx);
552 int (*check_hw) (struct efx_nic *efx); 553 void (*irq) (struct efx_nic *efx);
554 void (*poll) (struct efx_nic *efx);
553}; 555};
554 556
555/** 557/**
@@ -559,7 +561,7 @@ struct efx_mac_operations {
559 * @reconfigure: Reconfigure PHY (e.g. for new link parameters) 561 * @reconfigure: Reconfigure PHY (e.g. for new link parameters)
560 * @clear_interrupt: Clear down interrupt 562 * @clear_interrupt: Clear down interrupt
561 * @blink: Blink LEDs 563 * @blink: Blink LEDs
562 * @check_hw: Check hardware 564 * @poll: Poll for hardware state. Serialised by the mac_lock.
563 * @get_settings: Get ethtool settings. Serialised by the mac_lock. 565 * @get_settings: Get ethtool settings. Serialised by the mac_lock.
564 * @set_settings: Set ethtool settings. Serialised by the mac_lock. 566 * @set_settings: Set ethtool settings. Serialised by the mac_lock.
565 * @set_xnp_advertise: Set abilities advertised in Extended Next Page 567 * @set_xnp_advertise: Set abilities advertised in Extended Next Page
@@ -573,7 +575,7 @@ struct efx_phy_operations {
573 void (*fini) (struct efx_nic *efx); 575 void (*fini) (struct efx_nic *efx);
574 void (*reconfigure) (struct efx_nic *efx); 576 void (*reconfigure) (struct efx_nic *efx);
575 void (*clear_interrupt) (struct efx_nic *efx); 577 void (*clear_interrupt) (struct efx_nic *efx);
576 int (*check_hw) (struct efx_nic *efx); 578 void (*poll) (struct efx_nic *efx);
577 int (*test) (struct efx_nic *efx); 579 int (*test) (struct efx_nic *efx);
578 void (*get_settings) (struct efx_nic *efx, 580 void (*get_settings) (struct efx_nic *efx,
579 struct ethtool_cmd *ecmd); 581 struct ethtool_cmd *ecmd);
@@ -728,10 +730,10 @@ union efx_multicast_hash {
728 * @mac_lock: MAC access lock. Protects @port_enabled, @phy_mode, 730 * @mac_lock: MAC access lock. Protects @port_enabled, @phy_mode,
729 * @port_inhibited, efx_monitor() and efx_reconfigure_port() 731 * @port_inhibited, efx_monitor() and efx_reconfigure_port()
730 * @port_enabled: Port enabled indicator. 732 * @port_enabled: Port enabled indicator.
731 * Serialises efx_stop_all(), efx_start_all() and efx_monitor() and 733 * Serialises efx_stop_all(), efx_start_all(), efx_monitor(),
732 * efx_reconfigure_work with kernel interfaces. Safe to read under any 734 * efx_phy_work(), and efx_mac_work() with kernel interfaces. Safe to read
733 * one of the rtnl_lock, mac_lock, or netif_tx_lock, but all three must 735 * under any one of the rtnl_lock, mac_lock, or netif_tx_lock, but all
734 * be held to modify it. 736 * three must be held to modify it.
735 * @port_inhibited: If set, the netif_carrier is always off. Hold the mac_lock 737 * @port_inhibited: If set, the netif_carrier is always off. Hold the mac_lock
736 * @port_initialized: Port initialized? 738 * @port_initialized: Port initialized?
737 * @net_dev: Operating system network device. Consider holding the rtnl lock 739 * @net_dev: Operating system network device. Consider holding the rtnl lock
@@ -762,7 +764,8 @@ union efx_multicast_hash {
762 * @promiscuous: Promiscuous flag. Protected by netif_tx_lock. 764 * @promiscuous: Promiscuous flag. Protected by netif_tx_lock.
763 * @multicast_hash: Multicast hash table 765 * @multicast_hash: Multicast hash table
764 * @wanted_fc: Wanted flow control flags 766 * @wanted_fc: Wanted flow control flags
765 * @reconfigure_work: work item for dealing with PHY events 767 * @phy_work: work item for dealing with PHY events
768 * @mac_work: work item for dealing with MAC events
766 * @loopback_mode: Loopback status 769 * @loopback_mode: Loopback status
767 * @loopback_modes: Supported loopback mode bitmask 770 * @loopback_modes: Supported loopback mode bitmask
768 * @loopback_selftest: Offline self-test private state 771 * @loopback_selftest: Offline self-test private state
@@ -810,6 +813,7 @@ struct efx_nic {
810 struct falcon_nic_data *nic_data; 813 struct falcon_nic_data *nic_data;
811 814
812 struct mutex mac_lock; 815 struct mutex mac_lock;
816 struct work_struct mac_work;
813 bool port_enabled; 817 bool port_enabled;
814 bool port_inhibited; 818 bool port_inhibited;
815 819
@@ -830,6 +834,7 @@ struct efx_nic {
830 834
831 enum phy_type phy_type; 835 enum phy_type phy_type;
832 spinlock_t phy_lock; 836 spinlock_t phy_lock;
837 struct work_struct phy_work;
833 struct efx_phy_operations *phy_op; 838 struct efx_phy_operations *phy_op;
834 void *phy_data; 839 void *phy_data;
835 struct mii_if_info mii; 840 struct mii_if_info mii;
@@ -845,7 +850,6 @@ struct efx_nic {
845 bool promiscuous; 850 bool promiscuous;
846 union efx_multicast_hash multicast_hash; 851 union efx_multicast_hash multicast_hash;
847 enum efx_fc_type wanted_fc; 852 enum efx_fc_type wanted_fc;
848 struct work_struct reconfigure_work;
849 853
850 atomic_t rx_reset; 854 atomic_t rx_reset;
851 enum efx_loopback_mode loopback_mode; 855 enum efx_loopback_mode loopback_mode;
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c
index 8142e37a518f..578b7f410ed4 100644
--- a/drivers/net/sfc/selftest.c
+++ b/drivers/net/sfc/selftest.c
@@ -594,12 +594,14 @@ static int efx_test_loopbacks(struct efx_nic *efx, struct ethtool_cmd ecmd,
594 efx->loopback_mode = mode; 594 efx->loopback_mode = mode;
595 efx_reconfigure_port(efx); 595 efx_reconfigure_port(efx);
596 596
597 /* Wait for the PHY to signal the link is up */ 597 /* Wait for the PHY to signal the link is up. Interrupts
598 * are enabled for PHY's using LASI, otherwise we poll()
599 * quickly */
598 count = 0; 600 count = 0;
599 do { 601 do {
600 struct efx_channel *channel = &efx->channel[0]; 602 struct efx_channel *channel = &efx->channel[0];
601 603
602 efx->mac_op->check_hw(efx); 604 efx->phy_op->poll(efx);
603 schedule_timeout_uninterruptible(HZ / 10); 605 schedule_timeout_uninterruptible(HZ / 10);
604 if (channel->work_pending) 606 if (channel->work_pending)
605 efx_process_channel_now(channel); 607 efx_process_channel_now(channel);
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index 634ff9198823..7256ea4abf9c 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -348,50 +348,34 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
348 efx->link_fc = mdio_clause45_get_pause(efx); 348 efx->link_fc = mdio_clause45_get_pause(efx);
349} 349}
350 350
351static void tenxpress_phy_clear_interrupt(struct efx_nic *efx)
352{
353 /* Nothing done here - LASI interrupts aren't reliable so poll */
354}
355
356
357/* Poll PHY for interrupt */ 351/* Poll PHY for interrupt */
358static int tenxpress_phy_check_hw(struct efx_nic *efx) 352static void tenxpress_phy_poll(struct efx_nic *efx)
359{ 353{
360 struct tenxpress_phy_data *phy_data = efx->phy_data; 354 struct tenxpress_phy_data *phy_data = efx->phy_data;
361 bool link_ok; 355 bool change = false, link_ok;
362 int rc = 0; 356 unsigned link_fc;
363 357
364 link_ok = tenxpress_link_ok(efx); 358 link_ok = tenxpress_link_ok(efx);
359 if (link_ok != efx->link_up) {
360 change = true;
361 } else {
362 link_fc = mdio_clause45_get_pause(efx);
363 if (link_fc != efx->link_fc)
364 change = true;
365 }
365 tenxpress_check_bad_lp(efx, link_ok); 366 tenxpress_check_bad_lp(efx, link_ok);
366 367
367 if (link_ok != efx->link_up) 368 if (change)
368 falcon_sim_phy_event(efx); 369 falcon_sim_phy_event(efx);
369 370
370 if (phy_data->phy_mode != PHY_MODE_NORMAL) 371 if (phy_data->phy_mode != PHY_MODE_NORMAL)
371 return 0; 372 return;
372 373
373 if (atomic_read(&phy_data->bad_crc_count) > crc_error_reset_threshold) { 374 if (atomic_read(&phy_data->bad_crc_count) > crc_error_reset_threshold) {
374 EFX_ERR(efx, "Resetting XAUI due to too many CRC errors\n"); 375 EFX_ERR(efx, "Resetting XAUI due to too many CRC errors\n");
375 falcon_reset_xaui(efx); 376 falcon_reset_xaui(efx);
376 atomic_set(&phy_data->bad_crc_count, 0); 377 atomic_set(&phy_data->bad_crc_count, 0);
377 } 378 }
378
379 rc = efx->board_info.monitor(efx);
380 if (rc) {
381 EFX_ERR(efx, "Board sensor %s; shutting down PHY\n",
382 (rc == -ERANGE) ? "reported fault" : "failed");
383 if (efx->phy_mode & PHY_MODE_OFF) {
384 /* Assume that board has shut PHY off */
385 phy_data->phy_mode = PHY_MODE_OFF;
386 } else {
387 efx->phy_mode |= PHY_MODE_LOW_POWER;
388 mdio_clause45_set_mmds_lpower(efx, true,
389 efx->phy_op->mmds);
390 phy_data->phy_mode |= PHY_MODE_LOW_POWER;
391 }
392 }
393
394 return rc;
395} 379}
396 380
397static void tenxpress_phy_fini(struct efx_nic *efx) 381static void tenxpress_phy_fini(struct efx_nic *efx)
@@ -461,9 +445,9 @@ struct efx_phy_operations falcon_tenxpress_phy_ops = {
461 .macs = EFX_XMAC, 445 .macs = EFX_XMAC,
462 .init = tenxpress_phy_init, 446 .init = tenxpress_phy_init,
463 .reconfigure = tenxpress_phy_reconfigure, 447 .reconfigure = tenxpress_phy_reconfigure,
464 .check_hw = tenxpress_phy_check_hw, 448 .poll = tenxpress_phy_poll,
465 .fini = tenxpress_phy_fini, 449 .fini = tenxpress_phy_fini,
466 .clear_interrupt = tenxpress_phy_clear_interrupt, 450 .clear_interrupt = efx_port_dummy_op_void,
467 .test = tenxpress_phy_test, 451 .test = tenxpress_phy_test,
468 .get_settings = tenxpress_get_settings, 452 .get_settings = tenxpress_get_settings,
469 .set_settings = mdio_clause45_set_settings, 453 .set_settings = mdio_clause45_set_settings,
diff --git a/drivers/net/sfc/xfp_phy.c b/drivers/net/sfc/xfp_phy.c
index fbe8e25a1ed5..345ffc310dca 100644
--- a/drivers/net/sfc/xfp_phy.c
+++ b/drivers/net/sfc/xfp_phy.c
@@ -119,24 +119,12 @@ static int xfp_link_ok(struct efx_nic *efx)
119 return mdio_clause45_links_ok(efx, XFP_REQUIRED_DEVS); 119 return mdio_clause45_links_ok(efx, XFP_REQUIRED_DEVS);
120} 120}
121 121
122static int xfp_phy_check_hw(struct efx_nic *efx) 122static void xfp_phy_poll(struct efx_nic *efx)
123{ 123{
124 int rc = 0;
125 int link_up = xfp_link_ok(efx); 124 int link_up = xfp_link_ok(efx);
126 /* Simulate a PHY event if link state has changed */ 125 /* Simulate a PHY event if link state has changed */
127 if (link_up != efx->link_up) 126 if (link_up != efx->link_up)
128 falcon_sim_phy_event(efx); 127 falcon_sim_phy_event(efx);
129
130 rc = efx->board_info.monitor(efx);
131 if (rc) {
132 struct xfp_phy_data *phy_data = efx->phy_data;
133 EFX_ERR(efx, "XFP sensor alert; putting PHY into low power\n");
134 efx->phy_mode |= PHY_MODE_LOW_POWER;
135 mdio_clause45_set_mmds_lpower(efx, 1, XFP_REQUIRED_DEVS);
136 phy_data->phy_mode |= PHY_MODE_LOW_POWER;
137 }
138
139 return rc;
140} 128}
141 129
142static void xfp_phy_reconfigure(struct efx_nic *efx) 130static void xfp_phy_reconfigure(struct efx_nic *efx)
@@ -173,7 +161,7 @@ struct efx_phy_operations falcon_xfp_phy_ops = {
173 .macs = EFX_XMAC, 161 .macs = EFX_XMAC,
174 .init = xfp_phy_init, 162 .init = xfp_phy_init,
175 .reconfigure = xfp_phy_reconfigure, 163 .reconfigure = xfp_phy_reconfigure,
176 .check_hw = xfp_phy_check_hw, 164 .poll = xfp_phy_poll,
177 .fini = xfp_phy_fini, 165 .fini = xfp_phy_fini,
178 .clear_interrupt = xfp_phy_clear_interrupt, 166 .clear_interrupt = xfp_phy_clear_interrupt,
179 .get_settings = mdio_clause45_get_settings, 167 .get_settings = mdio_clause45_get_settings,