sfc: Move details of a Falcon bug workaround out of ethtool.c
authorBen Hutchings <bhutchings@solarflare.com>
Thu, 13 Sep 2012 00:11:25 +0000 (01:11 +0100)
committerBen Hutchings <bhutchings@solarflare.com>
Wed, 21 Aug 2013 15:35:06 +0000 (16:35 +0100)
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
drivers/net/ethernet/sfc/ethtool.c
drivers/net/ethernet/sfc/falcon.c
drivers/net/ethernet/sfc/net_driver.h
drivers/net/ethernet/sfc/nic.h
drivers/net/ethernet/sfc/workarounds.h

index 1fc21458413d50ade70be1ff1ee9481aca7cf987..4db37f7b0ef98aed3731c1417bbab2cae3e45175 100644 (file)
@@ -709,7 +709,6 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
        struct efx_nic *efx = netdev_priv(net_dev);
        u8 wanted_fc, old_fc;
        u32 old_adv;
-       bool reset;
        int rc = 0;
 
        mutex_lock(&efx->mac_lock);
@@ -732,24 +731,10 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
                goto out;
        }
 
-       /* TX flow control may automatically turn itself off if the
-        * link partner (intermittently) stops responding to pause
-        * frames. There isn't any indication that this has happened,
-        * so the best we do is leave it up to the user to spot this
-        * and fix it be cycling transmit flow control on this end. */
-       reset = (wanted_fc & EFX_FC_TX) && !(efx->wanted_fc & EFX_FC_TX);
-       if (EFX_WORKAROUND_11482(efx) && reset) {
-               if (efx_nic_rev(efx) == EFX_REV_FALCON_B0) {
-                       /* Recover by resetting the EM block */
-                       falcon_stop_nic_stats(efx);
-                       falcon_drain_tx_fifo(efx);
-                       falcon_reconfigure_xmac(efx);
-                       falcon_start_nic_stats(efx);
-               } else {
-                       /* Schedule a reset to recover */
-                       efx_schedule_reset(efx, RESET_TYPE_INVISIBLE);
-               }
-       }
+       /* Hook for Falcon bug 11482 workaround */
+       if (efx->type->prepare_enable_fc_tx &&
+           (wanted_fc & EFX_FC_TX) && !(efx->wanted_fc & EFX_FC_TX))
+               efx->type->prepare_enable_fc_tx(efx);
 
        old_adv = efx->link_advertising;
        old_fc = efx->wanted_fc;
index 71998e7995d9b3af015653eee2a80f1ec097c3ab..6b6ac6d174aa65dcac15d96c1ea0c38632149ccc 100644 (file)
@@ -497,7 +497,7 @@ static void falcon_reset_macs(struct efx_nic *efx)
        falcon_setup_xaui(efx);
 }
 
-void falcon_drain_tx_fifo(struct efx_nic *efx)
+static void falcon_drain_tx_fifo(struct efx_nic *efx)
 {
        efx_oword_t reg;
 
@@ -678,6 +678,28 @@ static int falcon_reconfigure_port(struct efx_nic *efx)
        return 0;
 }
 
+/* TX flow control may automatically turn itself off if the link
+ * partner (intermittently) stops responding to pause frames. There
+ * isn't any indication that this has happened, so the best we do is
+ * leave it up to the user to spot this and fix it by cycling transmit
+ * flow control on this end.
+ */
+
+static void falcon_a1_prepare_enable_fc_tx(struct efx_nic *efx)
+{
+       /* Schedule a reset to recover */
+       efx_schedule_reset(efx, RESET_TYPE_INVISIBLE);
+}
+
+static void falcon_b0_prepare_enable_fc_tx(struct efx_nic *efx)
+{
+       /* Recover by resetting the EM block */
+       falcon_stop_nic_stats(efx);
+       falcon_drain_tx_fifo(efx);
+       falcon_reconfigure_xmac(efx);
+       falcon_start_nic_stats(efx);
+}
+
 /**************************************************************************
  *
  * PHY access via GMII
@@ -1798,6 +1820,7 @@ const struct efx_nic_type falcon_a1_nic_type = {
        .set_id_led = falcon_set_id_led,
        .push_irq_moderation = falcon_push_irq_moderation,
        .reconfigure_port = falcon_reconfigure_port,
+       .prepare_enable_fc_tx = falcon_a1_prepare_enable_fc_tx,
        .reconfigure_mac = falcon_reconfigure_xmac,
        .check_mac_fault = falcon_xmac_check_fault,
        .get_wol = falcon_get_wol,
@@ -1842,6 +1865,7 @@ const struct efx_nic_type falcon_b0_nic_type = {
        .set_id_led = falcon_set_id_led,
        .push_irq_moderation = falcon_push_irq_moderation,
        .reconfigure_port = falcon_reconfigure_port,
+       .prepare_enable_fc_tx = falcon_b0_prepare_enable_fc_tx,
        .reconfigure_mac = falcon_reconfigure_xmac,
        .check_mac_fault = falcon_xmac_check_fault,
        .get_wol = falcon_get_wol,
index f4c7e6b67743b93eaa8d2c318705a05dd3302f8b..bdded38cbf125d42a0d45846e76b016efbc40211 100644 (file)
@@ -946,6 +946,7 @@ static inline unsigned int efx_port_num(struct efx_nic *efx)
  * @set_id_led: Set state of identifying LED or revert to automatic function
  * @push_irq_moderation: Apply interrupt moderation value
  * @reconfigure_port: Push loopback/power/txdis changes to the MAC and PHY
+ * @prepare_enable_fc_tx: Prepare MAC to enable pause frame TX (may be %NULL)
  * @reconfigure_mac: Push MAC address, MTU, flow control and filter settings
  *     to the hardware.  Serialised by the mac_lock.
  * @check_mac_fault: Check MAC fault state. True if fault present.
@@ -995,6 +996,7 @@ struct efx_nic_type {
        void (*set_id_led)(struct efx_nic *efx, enum efx_led_mode mode);
        void (*push_irq_moderation)(struct efx_channel *channel);
        int (*reconfigure_port)(struct efx_nic *efx);
+       void (*prepare_enable_fc_tx)(struct efx_nic *efx);
        int (*reconfigure_mac)(struct efx_nic *efx);
        bool (*check_mac_fault)(struct efx_nic *efx);
        void (*get_wol)(struct efx_nic *efx, struct ethtool_wolinfo *wol);
index d63c2991a75105767487aa66ae1cbe284fc6abc1..a78436320ab277c83540b66c4e8f061eed3a91a0 100644 (file)
@@ -298,7 +298,6 @@ extern void efx_nic_eventq_read_ack(struct efx_channel *channel);
 extern bool efx_nic_event_present(struct efx_channel *channel);
 
 /* MAC/PHY */
-extern void falcon_drain_tx_fifo(struct efx_nic *efx);
 extern void falcon_reconfigure_mac_wrapper(struct efx_nic *efx);
 extern bool falcon_xmac_check_fault(struct efx_nic *efx);
 extern int falcon_reconfigure_xmac(struct efx_nic *efx);
index e4dd3a7f304b5b70e874530fda18d251cc4515b1..dff565a476ffe1e6dd4b09be72c38db6ac7d9790 100644 (file)
@@ -30,8 +30,6 @@
 /* TX_EV_PKT_ERR can be caused by a dangling TX descriptor
  * or a PCIe error (bug 11028) */
 #define EFX_WORKAROUND_10727 EFX_WORKAROUND_ALWAYS
-/* Transmit flow control may get disabled */
-#define EFX_WORKAROUND_11482 EFX_WORKAROUND_FALCON_AB
 /* Truncated IPv4 packets can confuse the TX packet parser */
 #define EFX_WORKAROUND_15592 EFX_WORKAROUND_FALCON_AB
 /* Legacy ISR read can return zero once */