diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2012-09-12 20:11:25 -0400 |
---|---|---|
committer | Ben Hutchings <bhutchings@solarflare.com> | 2013-08-21 11:35:06 -0400 |
commit | 9dd3a13b885fef7dca0d2f27517a50b5fb5097c6 (patch) | |
tree | c386a99c10844e33700351fa3f819f1c27cf30b1 | |
parent | e847b53e9e3c6f7818fe2fcd1082148423020ccc (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.c | 23 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/falcon.c | 26 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/net_driver.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/nic.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/workarounds.h | 2 |
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 | ||
500 | void falcon_drain_tx_fifo(struct efx_nic *efx) | 500 | static 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 | |||
688 | static 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 | |||
694 | static 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); | |||
298 | extern bool efx_nic_event_present(struct efx_channel *channel); | 298 | extern bool efx_nic_event_present(struct efx_channel *channel); |
299 | 299 | ||
300 | /* MAC/PHY */ | 300 | /* MAC/PHY */ |
301 | extern void falcon_drain_tx_fifo(struct efx_nic *efx); | ||
302 | extern void falcon_reconfigure_mac_wrapper(struct efx_nic *efx); | 301 | extern void falcon_reconfigure_mac_wrapper(struct efx_nic *efx); |
303 | extern bool falcon_xmac_check_fault(struct efx_nic *efx); | 302 | extern bool falcon_xmac_check_fault(struct efx_nic *efx); |
304 | extern int falcon_reconfigure_xmac(struct efx_nic *efx); | 303 | extern 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 */ |