]> Pileus Git - ~andy/linux/blobdiff - net/core/dev.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[~andy/linux] / net / core / dev.c
index 0ce469e5ec8057c674901b404db13061fe8b7392..2bee80591f9ab5a1845a3b8c8c2ba46f9dea5ea1 100644 (file)
@@ -480,7 +480,7 @@ EXPORT_SYMBOL(dev_add_offload);
  *     and must not be freed until after all the CPU's have gone
  *     through a quiescent state.
  */
-void __dev_remove_offload(struct packet_offload *po)
+static void __dev_remove_offload(struct packet_offload *po)
 {
        struct list_head *head = &offload_base;
        struct packet_offload *po1;
@@ -498,7 +498,6 @@ void __dev_remove_offload(struct packet_offload *po)
 out:
        spin_unlock(&offload_lock);
 }
-EXPORT_SYMBOL(__dev_remove_offload);
 
 /**
  *     dev_remove_offload       - remove packet offload handler
@@ -1566,14 +1565,14 @@ EXPORT_SYMBOL(unregister_netdevice_notifier);
  *     are as for raw_notifier_call_chain().
  */
 
-int call_netdevice_notifiers_info(unsigned long val, struct net_device *dev,
-                                 struct netdev_notifier_info *info)
+static int call_netdevice_notifiers_info(unsigned long val,
+                                        struct net_device *dev,
+                                        struct netdev_notifier_info *info)
 {
        ASSERT_RTNL();
        netdev_notifier_info_init(info, dev);
        return raw_notifier_call_chain(&netdev_chain, val, info);
 }
-EXPORT_SYMBOL(call_netdevice_notifiers_info);
 
 /**
  *     call_netdevice_notifiers - call all network notifier blocks
@@ -2145,30 +2144,42 @@ void __netif_schedule(struct Qdisc *q)
 }
 EXPORT_SYMBOL(__netif_schedule);
 
-void dev_kfree_skb_irq(struct sk_buff *skb)
+struct dev_kfree_skb_cb {
+       enum skb_free_reason reason;
+};
+
+static struct dev_kfree_skb_cb *get_kfree_skb_cb(const struct sk_buff *skb)
+{
+       return (struct dev_kfree_skb_cb *)skb->cb;
+}
+
+void __dev_kfree_skb_irq(struct sk_buff *skb, enum skb_free_reason reason)
 {
-       if (atomic_dec_and_test(&skb->users)) {
-               struct softnet_data *sd;
-               unsigned long flags;
+       unsigned long flags;
 
-               local_irq_save(flags);
-               sd = &__get_cpu_var(softnet_data);
-               skb->next = sd->completion_queue;
-               sd->completion_queue = skb;
-               raise_softirq_irqoff(NET_TX_SOFTIRQ);
-               local_irq_restore(flags);
+       if (likely(atomic_read(&skb->users) == 1)) {
+               smp_rmb();
+               atomic_set(&skb->users, 0);
+       } else if (likely(!atomic_dec_and_test(&skb->users))) {
+               return;
        }
+       get_kfree_skb_cb(skb)->reason = reason;
+       local_irq_save(flags);
+       skb->next = __this_cpu_read(softnet_data.completion_queue);
+       __this_cpu_write(softnet_data.completion_queue, skb);
+       raise_softirq_irqoff(NET_TX_SOFTIRQ);
+       local_irq_restore(flags);
 }
-EXPORT_SYMBOL(dev_kfree_skb_irq);
+EXPORT_SYMBOL(__dev_kfree_skb_irq);
 
-void dev_kfree_skb_any(struct sk_buff *skb)
+void __dev_kfree_skb_any(struct sk_buff *skb, enum skb_free_reason reason)
 {
        if (in_irq() || irqs_disabled())
-               dev_kfree_skb_irq(skb);
+               __dev_kfree_skb_irq(skb, reason);
        else
                dev_kfree_skb(skb);
 }
-EXPORT_SYMBOL(dev_kfree_skb_any);
+EXPORT_SYMBOL(__dev_kfree_skb_any);
 
 
 /**
@@ -2442,13 +2453,8 @@ static void dev_gso_skb_destructor(struct sk_buff *skb)
 {
        struct dev_gso_cb *cb;
 
-       do {
-               struct sk_buff *nskb = skb->next;
-
-               skb->next = nskb->next;
-               nskb->next = NULL;
-               kfree_skb(nskb);
-       } while (skb->next);
+       kfree_skb_list(skb->next);
+       skb->next = NULL;
 
        cb = DEV_GSO_CB(skb);
        if (cb->destructor)
@@ -2523,21 +2529,6 @@ netdev_features_t netif_skb_features(struct sk_buff *skb)
 }
 EXPORT_SYMBOL(netif_skb_features);
 
-/*
- * Returns true if either:
- *     1. skb has frag_list and the device doesn't support FRAGLIST, or
- *     2. skb is fragmented and the device does not support SG.
- */
-static inline int skb_needs_linearize(struct sk_buff *skb,
-                                     netdev_features_t features)
-{
-       return skb_is_nonlinear(skb) &&
-                       ((skb_has_frag_list(skb) &&
-                               !(features & NETIF_F_FRAGLIST)) ||
-                       (skb_shinfo(skb)->nr_frags &&
-                               !(features & NETIF_F_SG)));
-}
-
 int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
                        struct netdev_queue *txq)
 {
@@ -2744,7 +2735,7 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
        return rc;
 }
 
-#if IS_ENABLED(CONFIG_NETPRIO_CGROUP)
+#if IS_ENABLED(CONFIG_CGROUP_NET_PRIO)
 static void skb_update_prio(struct sk_buff *skb)
 {
        struct netprio_map *map = rcu_dereference_bh(skb->dev->priomap);
@@ -3014,7 +3005,7 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb,
        }
 
        skb_reset_network_header(skb);
-       if (!skb_get_rxhash(skb))
+       if (!skb_get_hash(skb))
                goto done;
 
        flow_table = rcu_dereference(rxqueue->rps_flow_table);
@@ -3159,7 +3150,7 @@ static bool skb_flow_limit(struct sk_buff *skb, unsigned int qlen)
        rcu_read_lock();
        fl = rcu_dereference(sd->flow_limit);
        if (fl) {
-               new_flow = skb_get_rxhash(skb) & (fl->num_buckets - 1);
+               new_flow = skb_get_hash(skb) & (fl->num_buckets - 1);
                old_flow = fl->history[fl->history_head];
                fl->history[fl->history_head] = new_flow;
 
@@ -3311,7 +3302,10 @@ static void net_tx_action(struct softirq_action *h)
                        clist = clist->next;
 
                        WARN_ON(atomic_read(&skb->users));
-                       trace_kfree_skb(skb, net_tx_action);
+                       if (likely(get_kfree_skb_cb(skb)->reason == SKB_REASON_CONSUMED))
+                               trace_consume_skb(skb);
+                       else
+                               trace_kfree_skb(skb, net_tx_action);
                        __kfree_skb(skb);
                }
        }
@@ -3757,7 +3751,7 @@ static int napi_gro_complete(struct sk_buff *skb)
                if (ptype->type != type || !ptype->callbacks.gro_complete)
                        continue;
 
-               err = ptype->callbacks.gro_complete(skb);
+               err = ptype->callbacks.gro_complete(skb, 0);
                break;
        }
        rcu_read_unlock();
@@ -3823,6 +3817,23 @@ static void gro_list_prepare(struct napi_struct *napi, struct sk_buff *skb)
        }
 }
 
+static void skb_gro_reset_offset(struct sk_buff *skb)
+{
+       const struct skb_shared_info *pinfo = skb_shinfo(skb);
+       const skb_frag_t *frag0 = &pinfo->frags[0];
+
+       NAPI_GRO_CB(skb)->data_offset = 0;
+       NAPI_GRO_CB(skb)->frag0 = NULL;
+       NAPI_GRO_CB(skb)->frag0_len = 0;
+
+       if (skb_mac_header(skb) == skb_tail_pointer(skb) &&
+           pinfo->nr_frags &&
+           !PageHighMem(skb_frag_page(frag0))) {
+               NAPI_GRO_CB(skb)->frag0 = skb_frag_address(frag0);
+               NAPI_GRO_CB(skb)->frag0_len = skb_frag_size(frag0);
+       }
+}
+
 static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
 {
        struct sk_buff **pp = NULL;
@@ -3838,7 +3849,9 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff
        if (skb_is_gso(skb) || skb_has_frag_list(skb))
                goto normal;
 
+       skb_gro_reset_offset(skb);
        gro_list_prepare(napi, skb);
+       NAPI_GRO_CB(skb)->csum = skb->csum; /* Needed for CHECKSUM_COMPLETE */
 
        rcu_read_lock();
        list_for_each_entry_rcu(ptype, head, list) {
@@ -3874,10 +3887,23 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff
        if (same_flow)
                goto ok;
 
-       if (NAPI_GRO_CB(skb)->flush || napi->gro_count >= MAX_GRO_SKBS)
+       if (NAPI_GRO_CB(skb)->flush)
                goto normal;
 
-       napi->gro_count++;
+       if (unlikely(napi->gro_count >= MAX_GRO_SKBS)) {
+               struct sk_buff *nskb = napi->gro_list;
+
+               /* locate the end of the list to select the 'oldest' flow */
+               while (nskb->next) {
+                       pp = &nskb->next;
+                       nskb = *pp;
+               }
+               *pp = NULL;
+               nskb->next = NULL;
+               napi_gro_complete(nskb);
+       } else {
+               napi->gro_count++;
+       }
        NAPI_GRO_CB(skb)->count = 1;
        NAPI_GRO_CB(skb)->age = jiffies;
        skb_shinfo(skb)->gso_size = skb_gro_len(skb);
@@ -3915,6 +3941,31 @@ normal:
        goto pull;
 }
 
+struct packet_offload *gro_find_receive_by_type(__be16 type)
+{
+       struct list_head *offload_head = &offload_base;
+       struct packet_offload *ptype;
+
+       list_for_each_entry_rcu(ptype, offload_head, list) {
+               if (ptype->type != type || !ptype->callbacks.gro_receive)
+                       continue;
+               return ptype;
+       }
+       return NULL;
+}
+
+struct packet_offload *gro_find_complete_by_type(__be16 type)
+{
+       struct list_head *offload_head = &offload_base;
+       struct packet_offload *ptype;
+
+       list_for_each_entry_rcu(ptype, offload_head, list) {
+               if (ptype->type != type || !ptype->callbacks.gro_complete)
+                       continue;
+               return ptype;
+       }
+       return NULL;
+}
 
 static gro_result_t napi_skb_finish(gro_result_t ret, struct sk_buff *skb)
 {
@@ -3943,27 +3994,8 @@ static gro_result_t napi_skb_finish(gro_result_t ret, struct sk_buff *skb)
        return ret;
 }
 
-static void skb_gro_reset_offset(struct sk_buff *skb)
-{
-       const struct skb_shared_info *pinfo = skb_shinfo(skb);
-       const skb_frag_t *frag0 = &pinfo->frags[0];
-
-       NAPI_GRO_CB(skb)->data_offset = 0;
-       NAPI_GRO_CB(skb)->frag0 = NULL;
-       NAPI_GRO_CB(skb)->frag0_len = 0;
-
-       if (skb_mac_header(skb) == skb_tail_pointer(skb) &&
-           pinfo->nr_frags &&
-           !PageHighMem(skb_frag_page(frag0))) {
-               NAPI_GRO_CB(skb)->frag0 = skb_frag_address(frag0);
-               NAPI_GRO_CB(skb)->frag0_len = skb_frag_size(frag0);
-       }
-}
-
 gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
 {
-       skb_gro_reset_offset(skb);
-
        return napi_skb_finish(dev_gro_receive(napi, skb), skb);
 }
 EXPORT_SYMBOL(napi_gro_receive);
@@ -3986,8 +4018,7 @@ struct sk_buff *napi_get_frags(struct napi_struct *napi)
 
        if (!skb) {
                skb = netdev_alloc_skb_ip_align(napi->dev, GRO_MAX_HEAD);
-               if (skb)
-                       napi->skb = skb;
+               napi->skb = skb;
        }
        return skb;
 }
@@ -3998,12 +4029,7 @@ static gro_result_t napi_frags_finish(struct napi_struct *napi, struct sk_buff *
 {
        switch (ret) {
        case GRO_NORMAL:
-       case GRO_HELD:
-               skb->protocol = eth_type_trans(skb, skb->dev);
-
-               if (ret == GRO_HELD)
-                       skb_gro_pull(skb, -ETH_HLEN);
-               else if (netif_receive_skb(skb))
+               if (netif_receive_skb(skb))
                        ret = GRO_DROP;
                break;
 
@@ -4012,6 +4038,7 @@ static gro_result_t napi_frags_finish(struct napi_struct *napi, struct sk_buff *
                napi_reuse_skb(napi, skb);
                break;
 
+       case GRO_HELD:
        case GRO_MERGED:
                break;
        }
@@ -4022,36 +4049,15 @@ static gro_result_t napi_frags_finish(struct napi_struct *napi, struct sk_buff *
 static struct sk_buff *napi_frags_skb(struct napi_struct *napi)
 {
        struct sk_buff *skb = napi->skb;
-       struct ethhdr *eth;
-       unsigned int hlen;
-       unsigned int off;
 
        napi->skb = NULL;
 
-       skb_reset_mac_header(skb);
-       skb_gro_reset_offset(skb);
-
-       off = skb_gro_offset(skb);
-       hlen = off + sizeof(*eth);
-       eth = skb_gro_header_fast(skb, off);
-       if (skb_gro_header_hard(skb, hlen)) {
-               eth = skb_gro_header_slow(skb, hlen, off);
-               if (unlikely(!eth)) {
-                       napi_reuse_skb(napi, skb);
-                       skb = NULL;
-                       goto out;
-               }
+       if (unlikely(!pskb_may_pull(skb, sizeof(struct ethhdr)))) {
+               napi_reuse_skb(napi, skb);
+               return NULL;
        }
+       skb->protocol = eth_type_trans(skb, skb->dev);
 
-       skb_gro_pull(skb, sizeof(*eth));
-
-       /*
-        * This works because the only protocols we care about don't require
-        * special handling.  We'll fix it up properly at the end.
-        */
-       skb->protocol = eth->h_proto;
-
-out:
        return skb;
 }
 
@@ -4067,7 +4073,7 @@ gro_result_t napi_gro_frags(struct napi_struct *napi)
 EXPORT_SYMBOL(napi_gro_frags);
 
 /*
- * net_rps_action sends any pending IPI's for rps.
+ * net_rps_action_and_irq_enable sends any pending IPI's for rps.
  * Note: called with local irq disabled, but exits with local irq enabled.
  */
 static void net_rps_action_and_irq_enable(struct softnet_data *sd)
@@ -4272,17 +4278,10 @@ EXPORT_SYMBOL(netif_napi_add);
 
 void netif_napi_del(struct napi_struct *napi)
 {
-       struct sk_buff *skb, *next;
-
        list_del_init(&napi->dev_list);
        napi_free_frags(napi);
 
-       for (skb = napi->gro_list; skb; skb = next) {
-               next = skb->next;
-               skb->next = NULL;
-               kfree_skb(skb);
-       }
-
+       kfree_skb_list(napi->gro_list);
        napi->gro_list = NULL;
        napi->gro_count = 0;
 }
@@ -4399,19 +4398,6 @@ struct netdev_adjacent {
        struct rcu_head rcu;
 };
 
-static struct netdev_adjacent *__netdev_find_adj_rcu(struct net_device *dev,
-                                                    struct net_device *adj_dev,
-                                                    struct list_head *adj_list)
-{
-       struct netdev_adjacent *adj;
-
-       list_for_each_entry_rcu(adj, adj_list, list) {
-               if (adj->dev == adj_dev)
-                       return adj;
-       }
-       return NULL;
-}
-
 static struct netdev_adjacent *__netdev_find_adj(struct net_device *dev,
                                                 struct net_device *adj_dev,
                                                 struct list_head *adj_list)
@@ -4450,13 +4436,12 @@ EXPORT_SYMBOL(netdev_has_upper_dev);
  * Find out if a device is linked to an upper device and return true in case
  * it is. The caller must hold the RTNL lock.
  */
-bool netdev_has_any_upper_dev(struct net_device *dev)
+static bool netdev_has_any_upper_dev(struct net_device *dev)
 {
        ASSERT_RTNL();
 
        return !list_empty(&dev->all_adj_list.upper);
 }
-EXPORT_SYMBOL(netdev_has_any_upper_dev);
 
 /**
  * netdev_master_upper_dev_get - Get master upper device
@@ -4575,6 +4560,27 @@ void *netdev_lower_get_next_private_rcu(struct net_device *dev,
 }
 EXPORT_SYMBOL(netdev_lower_get_next_private_rcu);
 
+/**
+ * netdev_lower_get_first_private_rcu - Get the first ->private from the
+ *                                    lower neighbour list, RCU
+ *                                    variant
+ * @dev: device
+ *
+ * Gets the first netdev_adjacent->private from the dev's lower neighbour
+ * list. The caller must hold RCU read lock.
+ */
+void *netdev_lower_get_first_private_rcu(struct net_device *dev)
+{
+       struct netdev_adjacent *lower;
+
+       lower = list_first_or_null_rcu(&dev->adj_list.lower,
+                       struct netdev_adjacent, list);
+       if (lower)
+               return lower->private;
+       return NULL;
+}
+EXPORT_SYMBOL(netdev_lower_get_first_private_rcu);
+
 /**
  * netdev_master_upper_dev_get_rcu - Get master upper device
  * @dev: device
@@ -4667,9 +4673,9 @@ free_adj:
        return ret;
 }
 
-void __netdev_adjacent_dev_remove(struct net_device *dev,
-                                 struct net_device *adj_dev,
-                                 struct list_head *dev_list)
+static void __netdev_adjacent_dev_remove(struct net_device *dev,
+                                        struct net_device *adj_dev,
+                                        struct list_head *dev_list)
 {
        struct netdev_adjacent *adj;
        char linkname[IFNAMSIZ+7];
@@ -4707,11 +4713,11 @@ void __netdev_adjacent_dev_remove(struct net_device *dev,
        kfree_rcu(adj, rcu);
 }
 
-int __netdev_adjacent_dev_link_lists(struct net_device *dev,
-                                    struct net_device *upper_dev,
-                                    struct list_head *up_list,
-                                    struct list_head *down_list,
-                                    void *private, bool master)
+static int __netdev_adjacent_dev_link_lists(struct net_device *dev,
+                                           struct net_device *upper_dev,
+                                           struct list_head *up_list,
+                                           struct list_head *down_list,
+                                           void *private, bool master)
 {
        int ret;
 
@@ -4730,8 +4736,8 @@ int __netdev_adjacent_dev_link_lists(struct net_device *dev,
        return 0;
 }
 
-int __netdev_adjacent_dev_link(struct net_device *dev,
-                              struct net_device *upper_dev)
+static int __netdev_adjacent_dev_link(struct net_device *dev,
+                                     struct net_device *upper_dev)
 {
        return __netdev_adjacent_dev_link_lists(dev, upper_dev,
                                                &dev->all_adj_list.upper,
@@ -4739,26 +4745,26 @@ int __netdev_adjacent_dev_link(struct net_device *dev,
                                                NULL, false);
 }
 
-void __netdev_adjacent_dev_unlink_lists(struct net_device *dev,
-                                       struct net_device *upper_dev,
-                                       struct list_head *up_list,
-                                       struct list_head *down_list)
+static void __netdev_adjacent_dev_unlink_lists(struct net_device *dev,
+                                              struct net_device *upper_dev,
+                                              struct list_head *up_list,
+                                              struct list_head *down_list)
 {
        __netdev_adjacent_dev_remove(dev, upper_dev, up_list);
        __netdev_adjacent_dev_remove(upper_dev, dev, down_list);
 }
 
-void __netdev_adjacent_dev_unlink(struct net_device *dev,
-                                 struct net_device *upper_dev)
+static void __netdev_adjacent_dev_unlink(struct net_device *dev,
+                                        struct net_device *upper_dev)
 {
        __netdev_adjacent_dev_unlink_lists(dev, upper_dev,
                                           &dev->all_adj_list.upper,
                                           &upper_dev->all_adj_list.lower);
 }
 
-int __netdev_adjacent_dev_link_neighbour(struct net_device *dev,
-                                        struct net_device *upper_dev,
-                                        void *private, bool master)
+static int __netdev_adjacent_dev_link_neighbour(struct net_device *dev,
+                                               struct net_device *upper_dev,
+                                               void *private, bool master)
 {
        int ret = __netdev_adjacent_dev_link(dev, upper_dev);
 
@@ -4777,8 +4783,8 @@ int __netdev_adjacent_dev_link_neighbour(struct net_device *dev,
        return 0;
 }
 
-void __netdev_adjacent_dev_unlink_neighbour(struct net_device *dev,
-                                           struct net_device *upper_dev)
+static void __netdev_adjacent_dev_unlink_neighbour(struct net_device *dev,
+                                                  struct net_device *upper_dev)
 {
        __netdev_adjacent_dev_unlink(dev, upper_dev);
        __netdev_adjacent_dev_unlink_lists(dev, upper_dev,
@@ -4967,21 +4973,6 @@ void netdev_upper_dev_unlink(struct net_device *dev,
 }
 EXPORT_SYMBOL(netdev_upper_dev_unlink);
 
-void *netdev_lower_dev_get_private_rcu(struct net_device *dev,
-                                      struct net_device *lower_dev)
-{
-       struct netdev_adjacent *lower;
-
-       if (!lower_dev)
-               return NULL;
-       lower = __netdev_find_adj_rcu(dev, lower_dev, &dev->adj_list.lower);
-       if (!lower)
-               return NULL;
-
-       return lower->private;
-}
-EXPORT_SYMBOL(netdev_lower_dev_get_private_rcu);
-
 void *netdev_lower_dev_get_private(struct net_device *dev,
                                   struct net_device *lower_dev)
 {
@@ -5314,6 +5305,17 @@ int dev_change_flags(struct net_device *dev, unsigned int flags)
 }
 EXPORT_SYMBOL(dev_change_flags);
 
+static int __dev_set_mtu(struct net_device *dev, int new_mtu)
+{
+       const struct net_device_ops *ops = dev->netdev_ops;
+
+       if (ops->ndo_change_mtu)
+               return ops->ndo_change_mtu(dev, new_mtu);
+
+       dev->mtu = new_mtu;
+       return 0;
+}
+
 /**
  *     dev_set_mtu - Change maximum transfer unit
  *     @dev: device
@@ -5323,8 +5325,7 @@ EXPORT_SYMBOL(dev_change_flags);
  */
 int dev_set_mtu(struct net_device *dev, int new_mtu)
 {
-       const struct net_device_ops *ops = dev->netdev_ops;
-       int err;
+       int err, orig_mtu;
 
        if (new_mtu == dev->mtu)
                return 0;
@@ -5336,14 +5337,20 @@ int dev_set_mtu(struct net_device *dev, int new_mtu)
        if (!netif_device_present(dev))
                return -ENODEV;
 
-       err = 0;
-       if (ops->ndo_change_mtu)
-               err = ops->ndo_change_mtu(dev, new_mtu);
-       else
-               dev->mtu = new_mtu;
+       orig_mtu = dev->mtu;
+       err = __dev_set_mtu(dev, new_mtu);
 
-       if (!err)
-               call_netdevice_notifiers(NETDEV_CHANGEMTU, dev);
+       if (!err) {
+               err = call_netdevice_notifiers(NETDEV_CHANGEMTU, dev);
+               err = notifier_to_errno(err);
+               if (err) {
+                       /* setting mtu back and notifying everyone again,
+                        * so that they have a chance to revert changes.
+                        */
+                       __dev_set_mtu(dev, orig_mtu);
+                       call_netdevice_notifiers(NETDEV_CHANGEMTU, dev);
+               }
+       }
        return err;
 }
 EXPORT_SYMBOL(dev_set_mtu);
@@ -5836,13 +5843,8 @@ int register_netdevice(struct net_device *dev)
        dev->features |= NETIF_F_SOFT_FEATURES;
        dev->wanted_features = dev->features & dev->hw_features;
 
-       /* Turn on no cache copy if HW is doing checksum */
        if (!(dev->flags & IFF_LOOPBACK)) {
                dev->hw_features |= NETIF_F_NOCACHE_COPY;
-               if (dev->features & NETIF_F_ALL_CSUM) {
-                       dev->wanted_features |= NETIF_F_NOCACHE_COPY;
-                       dev->features |= NETIF_F_NOCACHE_COPY;
-               }
        }
 
        /* Make NETIF_F_HIGHDMA inheritable to VLAN devices.