sfc: Add efx_nic member with fixed netdev features
authorAndrew Rybchenko <Andrew.Rybchenko@oktetlabs.ru>
Wed, 15 Jun 2016 16:43:20 +0000 (17:43 +0100)
committerDavid S. Miller <davem@davemloft.net>
Thu, 16 Jun 2016 05:26:25 +0000 (22:26 -0700)
It allows to change set of fixed features on datapath reset.

Signed-off-by: Edward Cree <ecree@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/sfc/efx.c
drivers/net/ethernet/sfc/net_driver.h

index 097f363f16309583412b97021e94244b926c9498..2eecd2873c79686eae669a9d49ce1588c86f219f 100644 (file)
@@ -600,6 +600,7 @@ fail:
  */
 static void efx_start_datapath(struct efx_nic *efx)
 {
+       netdev_features_t old_features = efx->net_dev->features;
        bool old_rx_scatter = efx->rx_scatter;
        struct efx_tx_queue *tx_queue;
        struct efx_rx_queue *rx_queue;
@@ -644,6 +645,15 @@ static void efx_start_datapath(struct efx_nic *efx)
                          efx->rx_dma_len, efx->rx_page_buf_step,
                          efx->rx_bufs_per_page, efx->rx_pages_per_batch);
 
+       /* Restore previously fixed features in hw_features and remove
+        * features which are fixed now
+        */
+       efx->net_dev->hw_features |= efx->net_dev->features;
+       efx->net_dev->hw_features &= ~efx->fixed_features;
+       efx->net_dev->features |= efx->fixed_features;
+       if (efx->net_dev->features != old_features)
+               netdev_features_change(efx->net_dev);
+
        /* RX filters may also have scatter-enabled flags */
        if (efx->rx_scatter != old_rx_scatter)
                efx->type->filter_update_rx_scatter(efx);
@@ -3147,17 +3157,17 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
                return -ENOMEM;
        efx = netdev_priv(net_dev);
        efx->type = (const struct efx_nic_type *) entry->driver_data;
+       efx->fixed_features |= NETIF_F_HIGHDMA;
        net_dev->features |= (efx->type->offload_features | NETIF_F_SG |
-                             NETIF_F_HIGHDMA | NETIF_F_TSO |
-                             NETIF_F_RXCSUM);
+                             NETIF_F_TSO | NETIF_F_RXCSUM);
        if (efx->type->offload_features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM))
                net_dev->features |= NETIF_F_TSO6;
        /* Mask for features that also apply to VLAN devices */
        net_dev->vlan_features |= (NETIF_F_HW_CSUM | NETIF_F_SG |
                                   NETIF_F_HIGHDMA | NETIF_F_ALL_TSO |
                                   NETIF_F_RXCSUM);
-       /* All offloads can be toggled */
-       net_dev->hw_features = net_dev->features & ~NETIF_F_HIGHDMA;
+       net_dev->features |= efx->fixed_features;
+       net_dev->hw_features = net_dev->features & ~efx->fixed_features;
        pci_set_drvdata(pci_dev, efx);
        SET_NETDEV_DEV(net_dev, &pci_dev->dev);
        rc = efx_init_struct(efx, pci_dev, net_dev);
index 77cd23cda3f3bcef385ecc2a920245816c261020..26abb5c47fc62bd41afd8c6d5669ce45d7cc22e5 100644 (file)
@@ -868,6 +868,7 @@ struct vfdi_status;
  *     be held to modify it.
  * @port_initialized: Port initialized?
  * @net_dev: Operating system network device. Consider holding the rtnl lock
+ * @fixed_features: Features which cannot be turned off
  * @stats_buffer: DMA buffer for statistics
  * @phy_type: PHY type
  * @phy_op: PHY interface
@@ -1007,6 +1008,8 @@ struct efx_nic {
        bool port_initialized;
        struct net_device *net_dev;
 
+       netdev_features_t fixed_features;
+
        struct efx_buffer stats_buffer;
        u64 rx_nodesc_drops_total;
        u64 rx_nodesc_drops_while_down;