aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2012-09-12 20:11:25 -0400
committerBen Hutchings <bhutchings@solarflare.com>2013-08-21 11:35:06 -0400
commit9dd3a13b885fef7dca0d2f27517a50b5fb5097c6 (patch)
treec386a99c10844e33700351fa3f819f1c27cf30b1
parente847b53e9e3c6f7818fe2fcd1082148423020ccc (diff)
sfc: Move details of a Falcon bug workaround out of ethtool.c
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
-rw-r--r--drivers/net/ethernet/sfc/ethtool.c23
-rw-r--r--drivers/net/ethernet/sfc/falcon.c26
-rw-r--r--drivers/net/ethernet/sfc/net_driver.h2
-rw-r--r--drivers/net/ethernet/sfc/nic.h1
-rw-r--r--drivers/net/ethernet/sfc/workarounds.h2
5 files changed, 31 insertions, 23 deletions
diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c
index 1fc21458413d..4db37f7b0ef9 100644
--- a/drivers/net/ethernet/sfc/ethtool.c
+++ b/drivers/net/ethernet/sfc/ethtool.c
@@ -709,7 +709,6 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
709 struct efx_nic *efx = netdev_priv(net_dev); 709 struct efx_nic *efx = netdev_priv(net_dev);
710 u8 wanted_fc, old_fc; 710 u8 wanted_fc, old_fc;
711 u32 old_adv; 711 u32 old_adv;
712 bool reset;
713 int rc = 0; 712 int rc = 0;
714 713
715 mutex_lock(&efx->mac_lock); 714 mutex_lock(&efx->mac_lock);
@@ -732,24 +731,10 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
732 goto out; 731 goto out;
733 } 732 }
734 733
735 /* TX flow control may automatically turn itself off if the 734 /* Hook for Falcon bug 11482 workaround */
736 * link partner (intermittently) stops responding to pause 735 if (efx->type->prepare_enable_fc_tx &&
737 * frames. There isn't any indication that this has happened, 736 (wanted_fc & EFX_FC_TX) && !(efx->wanted_fc & EFX_FC_TX))
738 * so the best we do is leave it up to the user to spot this 737 efx->type->prepare_enable_fc_tx(efx);
739 * and fix it be cycling transmit flow control on this end. */
740 reset = (wanted_fc & EFX_FC_TX) && !(efx->wanted_fc & EFX_FC_TX);
741 if (EFX_WORKAROUND_11482(efx) && reset) {
742 if (efx_nic_rev(efx) == EFX_REV_FALCON_B0) {
743 /* Recover by resetting the EM block */
744 falcon_stop_nic_stats(efx);
745 falcon_drain_tx_fifo(efx);
746 falcon_reconfigure_xmac(efx);
747 falcon_start_nic_stats(efx);
748 } else {
749 /* Schedule a reset to recover */
750 efx_schedule_reset(efx, RESET_TYPE_INVISIBLE);
751 }
752 }
753 738
754 old_adv = efx->link_advertising; 739 old_adv = efx->link_advertising;
755 old_fc = efx->wanted_fc; 740 old_fc = efx->wanted_fc;
diff --git a/drivers/net/ethernet/sfc/falcon.c b/drivers/net/ethernet/sfc/falcon.c
index 71998e7995d9..6b6ac6d174aa 100644
--- a/drivers/net/ethernet/sfc/falcon.c
+++ b/drivers/net/ethernet/sfc/falcon.c
@@ -497,7 +497,7 @@ static void falcon_reset_macs(struct efx_nic *efx)
497 falcon_setup_xaui(efx); 497 falcon_setup_xaui(efx);
498} 498}
499 499
500void falcon_drain_tx_fifo(struct efx_nic *efx) 500static void falcon_drain_tx_fifo(struct efx_nic *efx)
501{ 501{
502 efx_oword_t reg; 502 efx_oword_t reg;
503 503
@@ -678,6 +678,28 @@ static int falcon_reconfigure_port(struct efx_nic *efx)
678 return 0; 678 return 0;
679} 679}
680 680
681/* TX flow control may automatically turn itself off if the link
682 * partner (intermittently) stops responding to pause frames. There
683 * isn't any indication that this has happened, so the best we do is
684 * leave it up to the user to spot this and fix it by cycling transmit
685 * flow control on this end.
686 */
687
688static void falcon_a1_prepare_enable_fc_tx(struct efx_nic *efx)
689{
690 /* Schedule a reset to recover */
691 efx_schedule_reset(efx, RESET_TYPE_INVISIBLE);
692}
693
694static void falcon_b0_prepare_enable_fc_tx(struct efx_nic *efx)
695{
696 /* Recover by resetting the EM block */
697 falcon_stop_nic_stats(efx);
698 falcon_drain_tx_fifo(efx);
699 falcon_reconfigure_xmac(efx);
700 falcon_start_nic_stats(efx);
701}
702
681/************************************************************************** 703/**************************************************************************
682 * 704 *
683 * PHY access via GMII 705 * PHY access via GMII
@@ -1798,6 +1820,7 @@ const struct efx_nic_type falcon_a1_nic_type = {
1798 .set_id_led = falcon_set_id_led, 1820 .set_id_led = falcon_set_id_led,
1799 .push_irq_moderation = falcon_push_irq_moderation, 1821 .push_irq_moderation = falcon_push_irq_moderation,
1800 .reconfigure_port = falcon_reconfigure_port, 1822 .reconfigure_port = falcon_reconfigure_port,
1823 .prepare_enable_fc_tx = falcon_a1_prepare_enable_fc_tx,
1801 .reconfigure_mac = falcon_reconfigure_xmac, 1824 .reconfigure_mac = falcon_reconfigure_xmac,
1802 .check_mac_fault = falcon_xmac_check_fault, 1825 .check_mac_fault = falcon_xmac_check_fault,
1803 .get_wol = falcon_get_wol, 1826 .get_wol = falcon_get_wol,
@@ -1842,6 +1865,7 @@ const struct efx_nic_type falcon_b0_nic_type = {
1842 .set_id_led = falcon_set_id_led, 1865 .set_id_led = falcon_set_id_led,
1843 .push_irq_moderation = falcon_push_irq_moderation, 1866 .push_irq_moderation = falcon_push_irq_moderation,
1844 .reconfigure_port = falcon_reconfigure_port, 1867 .reconfigure_port = falcon_reconfigure_port,
1868 .prepare_enable_fc_tx = falcon_b0_prepare_enable_fc_tx,
1845 .reconfigure_mac = falcon_reconfigure_xmac, 1869 .reconfigure_mac = falcon_reconfigure_xmac,
1846 .check_mac_fault = falcon_xmac_check_fault, 1870 .check_mac_fault = falcon_xmac_check_fault,
1847 .get_wol = falcon_get_wol, 1871 .get_wol = falcon_get_wol,
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index f4c7e6b67743..bdded38cbf12 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -946,6 +946,7 @@ static inline unsigned int efx_port_num(struct efx_nic *efx)
946 * @set_id_led: Set state of identifying LED or revert to automatic function 946 * @set_id_led: Set state of identifying LED or revert to automatic function
947 * @push_irq_moderation: Apply interrupt moderation value 947 * @push_irq_moderation: Apply interrupt moderation value
948 * @reconfigure_port: Push loopback/power/txdis changes to the MAC and PHY 948 * @reconfigure_port: Push loopback/power/txdis changes to the MAC and PHY
949 * @prepare_enable_fc_tx: Prepare MAC to enable pause frame TX (may be %NULL)
949 * @reconfigure_mac: Push MAC address, MTU, flow control and filter settings 950 * @reconfigure_mac: Push MAC address, MTU, flow control and filter settings
950 * to the hardware. Serialised by the mac_lock. 951 * to the hardware. Serialised by the mac_lock.
951 * @check_mac_fault: Check MAC fault state. True if fault present. 952 * @check_mac_fault: Check MAC fault state. True if fault present.
@@ -995,6 +996,7 @@ struct efx_nic_type {
995 void (*set_id_led)(struct efx_nic *efx, enum efx_led_mode mode); 996 void (*set_id_led)(struct efx_nic *efx, enum efx_led_mode mode);
996 void (*push_irq_moderation)(struct efx_channel *channel); 997 void (*push_irq_moderation)(struct efx_channel *channel);
997 int (*reconfigure_port)(struct efx_nic *efx); 998 int (*reconfigure_port)(struct efx_nic *efx);
999 void (*prepare_enable_fc_tx)(struct efx_nic *efx);
998 int (*reconfigure_mac)(struct efx_nic *efx); 1000 int (*reconfigure_mac)(struct efx_nic *efx);
999 bool (*check_mac_fault)(struct efx_nic *efx); 1001 bool (*check_mac_fault)(struct efx_nic *efx);
1000 void (*get_wol)(struct efx_nic *efx, struct ethtool_wolinfo *wol); 1002 void (*get_wol)(struct efx_nic *efx, struct ethtool_wolinfo *wol);
diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h
index d63c2991a751..a78436320ab2 100644
--- a/drivers/net/ethernet/sfc/nic.h
+++ b/drivers/net/ethernet/sfc/nic.h
@@ -298,7 +298,6 @@ extern void efx_nic_eventq_read_ack(struct efx_channel *channel);
298extern bool efx_nic_event_present(struct efx_channel *channel); 298extern bool efx_nic_event_present(struct efx_channel *channel);
299 299
300/* MAC/PHY */ 300/* MAC/PHY */
301extern void falcon_drain_tx_fifo(struct efx_nic *efx);
302extern void falcon_reconfigure_mac_wrapper(struct efx_nic *efx); 301extern void falcon_reconfigure_mac_wrapper(struct efx_nic *efx);
303extern bool falcon_xmac_check_fault(struct efx_nic *efx); 302extern bool falcon_xmac_check_fault(struct efx_nic *efx);
304extern int falcon_reconfigure_xmac(struct efx_nic *efx); 303extern int falcon_reconfigure_xmac(struct efx_nic *efx);
diff --git a/drivers/net/ethernet/sfc/workarounds.h b/drivers/net/ethernet/sfc/workarounds.h
index e4dd3a7f304b..dff565a476ff 100644
--- a/drivers/net/ethernet/sfc/workarounds.h
+++ b/drivers/net/ethernet/sfc/workarounds.h
@@ -30,8 +30,6 @@
30/* TX_EV_PKT_ERR can be caused by a dangling TX descriptor 30/* TX_EV_PKT_ERR can be caused by a dangling TX descriptor
31 * or a PCIe error (bug 11028) */ 31 * or a PCIe error (bug 11028) */
32#define EFX_WORKAROUND_10727 EFX_WORKAROUND_ALWAYS 32#define EFX_WORKAROUND_10727 EFX_WORKAROUND_ALWAYS
33/* Transmit flow control may get disabled */
34#define EFX_WORKAROUND_11482 EFX_WORKAROUND_FALCON_AB
35/* Truncated IPv4 packets can confuse the TX packet parser */ 33/* Truncated IPv4 packets can confuse the TX packet parser */
36#define EFX_WORKAROUND_15592 EFX_WORKAROUND_FALCON_AB 34#define EFX_WORKAROUND_15592 EFX_WORKAROUND_FALCON_AB
37/* Legacy ISR read can return zero once */ 35/* Legacy ISR read can return zero once */