Merge branch 'sfc-3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/bwh/sfc
authorDavid S. Miller <davem@davemloft.net>
Tue, 17 Sep 2013 01:42:37 +0000 (21:42 -0400)
committerDavid S. Miller <davem@davemloft.net>
Tue, 17 Sep 2013 01:43:54 +0000 (21:43 -0400)
Ben Hutchings says:

====================
Some bug fixes and future-proofing for the recently added SFC9120
support:

1. Minimal support for the 40G configuration.
2. Disable the incomplete PTP/hardware timestamping support.
3. Reset MAC stats properly after a firmware upgrade.
4. Re-check the datapath firmware capabilities after the controller is
reset.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/sfc/Kconfig
drivers/net/ethernet/sfc/ef10.c
drivers/net/ethernet/sfc/mcdi_port.c
drivers/net/ethernet/sfc/nic.h

index 8b7152565c5e27bed528dc7ea5b2e104efd3abb1..0889212944486f9978c2c9f404bd3c87b4b5777f 100644 (file)
@@ -7,7 +7,7 @@ config SFC
        select I2C_ALGOBIT
        select PTP_1588_CLOCK
        ---help---
-         This driver supports 10-gigabit Ethernet cards based on
+         This driver supports 10/40-gigabit Ethernet cards based on
          the Solarflare SFC4000, SFC9000-family and SFC9100-family
          controllers.
 
index 5f42313b4965a3013f5e28c907895783aa5206cb..9f18ae984f9ed38386b16e5284d4d10864687c4b 100644 (file)
@@ -94,7 +94,7 @@ static unsigned int efx_ef10_mem_map_size(struct efx_nic *efx)
        return resource_size(&efx->pci_dev->resource[EFX_MEM_BAR]);
 }
 
-static int efx_ef10_init_capabilities(struct efx_nic *efx)
+static int efx_ef10_init_datapath_caps(struct efx_nic *efx)
 {
        MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CAPABILITIES_OUT_LEN);
        struct efx_ef10_nic_data *nic_data = efx->nic_data;
@@ -107,16 +107,27 @@ static int efx_ef10_init_capabilities(struct efx_nic *efx)
                          outbuf, sizeof(outbuf), &outlen);
        if (rc)
                return rc;
+       if (outlen < sizeof(outbuf)) {
+               netif_err(efx, drv, efx->net_dev,
+                         "unable to read datapath firmware capabilities\n");
+               return -EIO;
+       }
 
-       if (outlen >= sizeof(outbuf)) {
-               nic_data->datapath_caps =
-                       MCDI_DWORD(outbuf, GET_CAPABILITIES_OUT_FLAGS1);
-               if (!(nic_data->datapath_caps &
-                    (1 << MC_CMD_GET_CAPABILITIES_OUT_TX_TSO_LBN))) {
-                       netif_err(efx, drv, efx->net_dev,
-                                 "Capabilities don't indicate TSO support.\n");
-                       return -ENODEV;
-               }
+       nic_data->datapath_caps =
+               MCDI_DWORD(outbuf, GET_CAPABILITIES_OUT_FLAGS1);
+
+       if (!(nic_data->datapath_caps &
+             (1 << MC_CMD_GET_CAPABILITIES_OUT_TX_TSO_LBN))) {
+               netif_err(efx, drv, efx->net_dev,
+                         "current firmware does not support TSO\n");
+               return -ENODEV;
+       }
+
+       if (!(nic_data->datapath_caps &
+             (1 << MC_CMD_GET_CAPABILITIES_OUT_RX_PREFIX_LEN_14_LBN))) {
+               netif_err(efx, probe, efx->net_dev,
+                         "current firmware does not support an RX prefix\n");
+               return -ENODEV;
        }
 
        return 0;
@@ -217,21 +228,13 @@ static int efx_ef10_probe(struct efx_nic *efx)
        if (rc)
                goto fail3;
 
-       rc = efx_ef10_init_capabilities(efx);
+       rc = efx_ef10_init_datapath_caps(efx);
        if (rc < 0)
                goto fail3;
 
        efx->rx_packet_len_offset =
                ES_DZ_RX_PREFIX_PKTLEN_OFST - ES_DZ_RX_PREFIX_SIZE;
 
-       if (!(nic_data->datapath_caps &
-             (1 << MC_CMD_GET_CAPABILITIES_OUT_RX_PREFIX_LEN_14_LBN))) {
-               netif_err(efx, probe, efx->net_dev,
-                         "current firmware does not support an RX prefix\n");
-               rc = -ENODEV;
-               goto fail3;
-       }
-
        rc = efx_mcdi_port_get_number(efx);
        if (rc < 0)
                goto fail3;
@@ -260,8 +263,6 @@ static int efx_ef10_probe(struct efx_nic *efx)
        if (rc)
                goto fail3;
 
-       efx_ptp_probe(efx);
-
        return 0;
 
 fail3:
@@ -342,6 +343,13 @@ static int efx_ef10_init_nic(struct efx_nic *efx)
        struct efx_ef10_nic_data *nic_data = efx->nic_data;
        int rc;
 
+       if (nic_data->must_check_datapath_caps) {
+               rc = efx_ef10_init_datapath_caps(efx);
+               if (rc)
+                       return rc;
+               nic_data->must_check_datapath_caps = false;
+       }
+
        if (nic_data->must_realloc_vis) {
                /* We cannot let the number of VIs change now */
                rc = efx_ef10_alloc_vis(efx, nic_data->n_allocated_vis,
@@ -710,6 +718,14 @@ static int efx_ef10_mcdi_poll_reboot(struct efx_nic *efx)
        nic_data->must_restore_filters = true;
        nic_data->rx_rss_context = EFX_EF10_RSS_CONTEXT_INVALID;
 
+       /* The datapath firmware might have been changed */
+       nic_data->must_check_datapath_caps = true;
+
+       /* MAC statistics have been cleared on the NIC; clear the local
+        * statistic that we update with efx_update_diff_stat().
+        */
+       nic_data->stats[EF10_STAT_rx_bad_bytes] = 0;
+
        return -EIO;
 }
 
index 8d33da6697fbef6fefa40955d8fb01231b3c9c79..7b6be61d549fd57f81d1d7a31b6ef374d0f5acfb 100644 (file)
@@ -556,6 +556,7 @@ static int efx_mcdi_phy_set_settings(struct efx_nic *efx, struct ethtool_cmd *ec
                case 100:   caps = 1 << MC_CMD_PHY_CAP_100FDX_LBN;   break;
                case 1000:  caps = 1 << MC_CMD_PHY_CAP_1000FDX_LBN;  break;
                case 10000: caps = 1 << MC_CMD_PHY_CAP_10000FDX_LBN; break;
+               case 40000: caps = 1 << MC_CMD_PHY_CAP_40000FDX_LBN; break;
                default:    return -EINVAL;
                }
        } else {
@@ -841,6 +842,7 @@ static unsigned int efx_mcdi_event_link_speed[] = {
        [MCDI_EVENT_LINKCHANGE_SPEED_100M] = 100,
        [MCDI_EVENT_LINKCHANGE_SPEED_1G] = 1000,
        [MCDI_EVENT_LINKCHANGE_SPEED_10G] = 10000,
+       [MCDI_EVENT_LINKCHANGE_SPEED_40G] = 40000,
 };
 
 void efx_mcdi_process_link_change(struct efx_nic *efx, efx_qword_t *ev)
index 4b1e188f7a2fc51a640bc03f79752428867ad33b..fda29d39032f422d2c395a4fe68a4c5091654006 100644 (file)
@@ -400,6 +400,8 @@ enum {
  * @rx_rss_context: Firmware handle for our RSS context
  * @stats: Hardware statistics
  * @workaround_35388: Flag: firmware supports workaround for bug 35388
+ * @must_check_datapath_caps: Flag: @datapath_caps needs to be revalidated
+ *     after MC reboot
  * @datapath_caps: Capabilities of datapath firmware (FLAGS1 field of
  *     %MC_CMD_GET_CAPABILITIES response)
  */
@@ -413,6 +415,7 @@ struct efx_ef10_nic_data {
        u32 rx_rss_context;
        u64 stats[EF10_STAT_COUNT];
        bool workaround_35388;
+       bool must_check_datapath_caps;
        u32 datapath_caps;
 };