Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/bwh/sfc...
authorDavid S. Miller <davem@davemloft.net>
Sat, 14 Dec 2013 06:11:22 +0000 (01:11 -0500)
committerDavid S. Miller <davem@davemloft.net>
Sat, 14 Dec 2013 06:11:22 +0000 (01:11 -0500)
Ben Hutchings says:

====================
An assortment of changes for Linux 3.14:

1. Merge the sfc fixes that you have already merged into net.git.
   (The branch point for those was such that this does not bring in any
   other changes.)
2. Reduce log level for a generally useless warning message, from
   Robert Stonehouse.
3. Include BISTs in ethtool offline self-test for EF10 and recover from
   BISTs initiated through other functions, from Jon Cooper.
4. Improve a sanity check on RX completions.
5. Avoid incrementing RX dropped count while the interface is down, from
   Jon Cooper.
6. Improve hardware sensor naming and log messages, from Edward Cree.
7. Log all unexpected errors returned by firmware, from Edward Cree.
8. Expose another NVRAM partition to userland.
9. Some refactoring of the PTP code in preparation for EF10 support.
10. Various minor cleanups.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
1  2 
drivers/net/ethernet/sfc/efx.c

index 12f60e7828683aed7646178abe63702f9619f997,893cd78c3a6c12f8d3dfcc73df56f06455de164b..191ac8378effc2b71e0d58629c8e8f59276ae6ef
@@@ -83,6 -83,7 +83,7 @@@ const char *const efx_reset_type_names[
        [RESET_TYPE_DMA_ERROR]          = "DMA_ERROR",
        [RESET_TYPE_TX_SKIP]            = "TX_SKIP",
        [RESET_TYPE_MC_FAILURE]         = "MC_FAILURE",
+       [RESET_TYPE_MC_BIST]            = "MC_BIST",
  };
  
  /* Reset workqueue. If any NIC has a hardware failure then a reset will be
   */
  static struct workqueue_struct *reset_workqueue;
  
+ /* How often and how many times to poll for a reset while waiting for a
+  * BIST that another function started to complete.
+  */
+ #define BIST_WAIT_DELAY_MS    100
+ #define BIST_WAIT_DELAY_COUNT 100
  /**************************************************************************
   *
   * Configurable values
@@@ -246,7 -253,7 +253,7 @@@ static int efx_process_channel(struct e
                        efx_channel_get_rx_queue(channel);
  
                efx_rx_flush_packet(channel);
-               efx_fast_push_rx_descriptors(rx_queue);
+               efx_fast_push_rx_descriptors(rx_queue, true);
        }
  
        return spent;
@@@ -585,7 -592,7 +592,7 @@@ static void efx_start_datapath(struct e
                           EFX_MAX_FRAME_LEN(efx->net_dev->mtu) +
                           efx->type->rx_buffer_padding);
        rx_buf_len = (sizeof(struct efx_rx_page_state) +
-                     NET_IP_ALIGN + efx->rx_dma_len);
+                     efx->rx_ip_align + efx->rx_dma_len);
        if (rx_buf_len <= PAGE_SIZE) {
                efx->rx_scatter = efx->type->always_rx_scatter;
                efx->rx_buffer_order = 0;
                efx_for_each_channel_rx_queue(rx_queue, channel) {
                        efx_init_rx_queue(rx_queue);
                        atomic_inc(&efx->active_queues);
-                       efx_nic_generate_fill_event(rx_queue);
+                       efx_stop_eventq(channel);
+                       efx_fast_push_rx_descriptors(rx_queue, false);
+                       efx_start_eventq(channel);
                }
  
                WARN_ON(channel->rx_pkt_n_frags);
        }
  
+       efx_ptp_start_datapath(efx);
        if (netif_device_present(efx->net_dev))
                netif_tx_wake_all_queues(efx->net_dev);
  }
@@@ -659,6 -670,8 +670,8 @@@ static void efx_stop_datapath(struct ef
        EFX_ASSERT_RESET_SERIALISED(efx);
        BUG_ON(efx->port_enabled);
  
+       efx_ptp_stop_datapath(efx);
        /* Stop RX refill */
        efx_for_each_channel(channel, efx) {
                efx_for_each_channel_rx_queue(rx_queue, channel)
@@@ -1047,18 -1060,23 +1060,23 @@@ static void efx_start_port(struct efx_n
        mutex_lock(&efx->mac_lock);
        efx->port_enabled = true;
  
-       /* efx_mac_work() might have been scheduled after efx_stop_port(),
-        * and then cancelled by efx_flush_all() */
+       /* Ensure MAC ingress/egress is enabled */
        efx->type->reconfigure_mac(efx);
  
        mutex_unlock(&efx->mac_lock);
  }
  
- /* Prevent efx_mac_work() and efx_monitor() from working */
+ /* Cancel work for MAC reconfiguration, periodic hardware monitoring
+  * and the async self-test, wait for them to finish and prevent them
+  * being scheduled again.  This doesn't cover online resets, which
+  * should only be cancelled when removing the device.
+  */
  static void efx_stop_port(struct efx_nic *efx)
  {
        netif_dbg(efx, ifdown, efx->net_dev, "stop port\n");
  
+       EFX_ASSERT_RESET_SERIALISED(efx);
        mutex_lock(&efx->mac_lock);
        efx->port_enabled = false;
        mutex_unlock(&efx->mac_lock);
        /* Serialise against efx_set_multicast_list() */
        netif_addr_lock_bh(efx->net_dev);
        netif_addr_unlock_bh(efx->net_dev);
+       cancel_delayed_work_sync(&efx->monitor_work);
+       efx_selftest_async_cancel(efx);
+       cancel_work_sync(&efx->mac_work);
  }
  
  static void efx_fini_port(struct efx_nic *efx)
@@@ -1671,18 -1693,10 +1693,10 @@@ static void efx_start_all(struct efx_ni
        }
  
        efx->type->start_stats(efx);
- }
- /* Flush all delayed work. Should only be called when no more delayed work
-  * will be scheduled. This doesn't flush pending online resets (efx_reset),
-  * since we're holding the rtnl_lock at this point. */
- static void efx_flush_all(struct efx_nic *efx)
- {
-       /* Make sure the hardware monitor and event self-test are stopped */
-       cancel_delayed_work_sync(&efx->monitor_work);
-       efx_selftest_async_cancel(efx);
-       /* Stop scheduled port reconfigurations */
-       cancel_work_sync(&efx->mac_work);
+       efx->type->pull_stats(efx);
+       spin_lock_bh(&efx->stats_lock);
+       efx->type->update_stats(efx, NULL, NULL);
+       spin_unlock_bh(&efx->stats_lock);
  }
  
  /* Quiesce the hardware and software data path, and regular activity
@@@ -1698,12 -1712,16 +1712,16 @@@ static void efx_stop_all(struct efx_ni
        if (!efx->port_enabled)
                return;
  
+       /* update stats before we go down so we can accurately count
+        * rx_nodesc_drops
+        */
+       efx->type->pull_stats(efx);
+       spin_lock_bh(&efx->stats_lock);
+       efx->type->update_stats(efx, NULL, NULL);
+       spin_unlock_bh(&efx->stats_lock);
        efx->type->stop_stats(efx);
        efx_stop_port(efx);
  
-       /* Flush efx_mac_work(), refill_workqueue, monitor_work */
-       efx_flush_all(efx);
        /* Stop the kernel transmit interface.  This is only valid if
         * the device is stopped or detached; otherwise the watchdog
         * may fire immediately.
@@@ -2385,6 -2403,24 +2403,24 @@@ int efx_try_recovery(struct efx_nic *ef
        return 0;
  }
  
+ static void efx_wait_for_bist_end(struct efx_nic *efx)
+ {
+       int i;
+       for (i = 0; i < BIST_WAIT_DELAY_COUNT; ++i) {
+               if (efx_mcdi_poll_reboot(efx))
+                       goto out;
+               msleep(BIST_WAIT_DELAY_MS);
+       }
+       netif_err(efx, drv, efx->net_dev, "Warning: No MC reboot after BIST mode\n");
+ out:
+       /* Either way unset the BIST flag. If we found no reboot we probably
+        * won't recover, but we should try.
+        */
+       efx->mc_bist_for_other_fn = false;
+ }
  /* The worker thread exists so that code that cannot sleep can
   * schedule a reset for later.
   */
@@@ -2397,6 -2433,9 +2433,9 @@@ static void efx_reset_work(struct work_
        pending = ACCESS_ONCE(efx->reset_pending);
        method = fls(pending) - 1;
  
+       if (method == RESET_TYPE_MC_BIST)
+               efx_wait_for_bist_end(efx);
        if ((method == RESET_TYPE_RECOVER_OR_DISABLE ||
             method == RESET_TYPE_RECOVER_OR_ALL) &&
            efx_try_recovery(efx))
@@@ -2435,6 -2474,7 +2474,7 @@@ void efx_schedule_reset(struct efx_nic 
        case RESET_TYPE_WORLD:
        case RESET_TYPE_DISABLE:
        case RESET_TYPE_RECOVER_OR_DISABLE:
+       case RESET_TYPE_MC_BIST:
                method = type;
                netif_dbg(efx, drv, efx->net_dev, "scheduling %s reset\n",
                          RESET_TYPE(method));
@@@ -2542,6 -2582,8 +2582,8 @@@ static int efx_init_struct(struct efx_n
  
        efx->net_dev = net_dev;
        efx->rx_prefix_size = efx->type->rx_prefix_size;
+       efx->rx_ip_align =
+               NET_IP_ALIGN ? (efx->rx_prefix_size + NET_IP_ALIGN) % 4 : 0;
        efx->rx_packet_hash_offset =
                efx->type->rx_hash_offset - efx->type->rx_prefix_size;
        spin_lock_init(&efx->stats_lock);
@@@ -2643,6 -2685,7 +2685,6 @@@ static void efx_pci_remove(struct pci_d
        netif_dbg(efx, drv, efx->net_dev, "shutdown successful\n");
  
        efx_fini_struct(efx);
 -      pci_set_drvdata(pci_dev, NULL);
        free_netdev(efx->net_dev);
  
        pci_disable_pcie_error_reporting(pci_dev);
@@@ -2836,6 -2879,7 +2878,6 @@@ static int efx_pci_probe(struct pci_de
   fail2:
        efx_fini_struct(efx);
   fail1:
 -      pci_set_drvdata(pci_dev, NULL);
        WARN_ON(rc > 0);
        netif_dbg(efx, drv, efx->net_dev, "initialisation failed. rc=%d\n", rc);
        free_netdev(net_dev);