linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / net / core / dev.c
index 50eff37..034b57e 100644 (file)
@@ -81,7 +81,6 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/mutex.h>
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/socket.h>
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/socket.h>
 #include <linux/netpoll.h>
 #include <linux/rcupdate.h>
 #include <linux/delay.h>
 #include <linux/netpoll.h>
 #include <linux/rcupdate.h>
 #include <linux/delay.h>
-#include <linux/wireless.h>
+#ifdef CONFIG_NET_RADIO
+#include <linux/wireless.h>            /* Note : will define WIRELESS_EXT */
 #include <net/iw_handler.h>
 #include <net/iw_handler.h>
-#include <asm/current.h>
-#include <linux/audit.h>
-#include <linux/err.h>
+#endif /* CONFIG_NET_RADIO */
 #include <linux/vs_network.h>
 #include <linux/vs_network.h>
-
-#ifdef CONFIG_XEN
-#include <net/ip.h>
-#include <linux/tcp.h>
-#include <linux/udp.h>
-#endif
+#include <asm/current.h>
 
 /*
  *     The list of packet types we will receive (as opposed to discard)
 
 /*
  *     The list of packet types we will receive (as opposed to discard)
  *             sure which should go first, but I bet it won't make much
  *             difference if we are running VLANs.  The good news is that
  *             this protocol won't be in the list unless compiled in, so
  *             sure which should go first, but I bet it won't make much
  *             difference if we are running VLANs.  The good news is that
  *             this protocol won't be in the list unless compiled in, so
- *             the average user (w/out VLANs) will not be adversely affected.
+ *             the average user (w/out VLANs) will not be adversly affected.
  *             --BLG
  *
  *             0800    IP
  *             --BLG
  *
  *             0800    IP
@@ -157,7 +150,7 @@ static struct list_head ptype_base[16];     /* 16 way hashed list */
 static struct list_head ptype_all;             /* Taps */
 
 /*
 static struct list_head ptype_all;             /* Taps */
 
 /*
- * The @dev_base list is protected by @dev_base_lock and the rtnl
+ * The @dev_base list is protected by @dev_base_lock and the rtln
  * semaphore.
  *
  * Pure readers hold dev_base_lock for reading.
  * semaphore.
  *
  * Pure readers hold dev_base_lock for reading.
@@ -201,7 +194,7 @@ static inline struct hlist_head *dev_index_hash(int ifindex)
  *     Our notifier list
  */
 
  *     Our notifier list
  */
 
-static RAW_NOTIFIER_HEAD(netdev_chain);
+static struct notifier_block *netdev_chain;
 
 /*
  *     Device drivers call our routines to queue packets here. We empty the
 
 /*
  *     Device drivers call our routines to queue packets here. We empty the
@@ -649,12 +642,10 @@ int dev_valid_name(const char *name)
  *     @name: name format string
  *
  *     Passed a format string - eg "lt%d" it will try and find a suitable
  *     @name: name format string
  *
  *     Passed a format string - eg "lt%d" it will try and find a suitable
- *     id. It scans list of devices to build up a free map, then chooses
- *     the first empty slot. The caller must hold the dev_base or rtnl lock
- *     while allocating the name and adding the device in order to avoid
- *     duplicates.
- *     Limited to bits_per_byte * page size devices (ie 32K on most platforms).
- *     Returns the number of the unit assigned or a negative errno code.
+ *     id. Not efficient for many devices, not called a lot. The caller
+ *     must hold the dev_base or rtnl lock while allocating the name and
+ *     adding the device in order to avoid duplicates. Returns the number
+ *     of the unit assigned or a negative errno code.
  */
 
 int dev_alloc_name(struct net_device *dev, const char *name)
  */
 
 int dev_alloc_name(struct net_device *dev, const char *name)
@@ -746,22 +737,21 @@ int dev_change_name(struct net_device *dev, char *newname)
        if (!err) {
                hlist_del(&dev->name_hlist);
                hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name));
        if (!err) {
                hlist_del(&dev->name_hlist);
                hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name));
-               raw_notifier_call_chain(&netdev_chain,
-                               NETDEV_CHANGENAME, dev);
+               notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev);
        }
 
        return err;
 }
 
 /**
        }
 
        return err;
 }
 
 /**
- *     netdev_features_change - device changes features
+ *     netdev_features_change - device changes fatures
  *     @dev: device to cause notification
  *
  *     Called to indicate a device has changed features.
  */
 void netdev_features_change(struct net_device *dev)
 {
  *     @dev: device to cause notification
  *
  *     Called to indicate a device has changed features.
  */
 void netdev_features_change(struct net_device *dev)
 {
-       raw_notifier_call_chain(&netdev_chain, NETDEV_FEAT_CHANGE, dev);
+       notifier_call_chain(&netdev_chain, NETDEV_FEAT_CHANGE, dev);
 }
 EXPORT_SYMBOL(netdev_features_change);
 
 }
 EXPORT_SYMBOL(netdev_features_change);
 
@@ -776,8 +766,7 @@ EXPORT_SYMBOL(netdev_features_change);
 void netdev_state_change(struct net_device *dev)
 {
        if (dev->flags & IFF_UP) {
 void netdev_state_change(struct net_device *dev)
 {
        if (dev->flags & IFF_UP) {
-               raw_notifier_call_chain(&netdev_chain,
-                               NETDEV_CHANGE, dev);
+               notifier_call_chain(&netdev_chain, NETDEV_CHANGE, dev);
                rtmsg_ifinfo(RTM_NEWLINK, dev, 0);
        }
 }
                rtmsg_ifinfo(RTM_NEWLINK, dev, 0);
        }
 }
@@ -874,7 +863,7 @@ int dev_open(struct net_device *dev)
                /*
                 *      ... and announce new interface.
                 */
                /*
                 *      ... and announce new interface.
                 */
-               raw_notifier_call_chain(&netdev_chain, NETDEV_UP, dev);
+               notifier_call_chain(&netdev_chain, NETDEV_UP, dev);
        }
        return ret;
 }
        }
        return ret;
 }
@@ -897,7 +886,7 @@ int dev_close(struct net_device *dev)
         *      Tell people we are going down, so that they can
         *      prepare to death, when device is still operating.
         */
         *      Tell people we are going down, so that they can
         *      prepare to death, when device is still operating.
         */
-       raw_notifier_call_chain(&netdev_chain, NETDEV_GOING_DOWN, dev);
+       notifier_call_chain(&netdev_chain, NETDEV_GOING_DOWN, dev);
 
        dev_deactivate(dev);
 
 
        dev_deactivate(dev);
 
@@ -934,7 +923,7 @@ int dev_close(struct net_device *dev)
        /*
         * Tell people we are down
         */
        /*
         * Tell people we are down
         */
-       raw_notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev);
+       notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev);
 
        return 0;
 }
 
        return 0;
 }
@@ -965,7 +954,7 @@ int register_netdevice_notifier(struct notifier_block *nb)
        int err;
 
        rtnl_lock();
        int err;
 
        rtnl_lock();
-       err = raw_notifier_chain_register(&netdev_chain, nb);
+       err = notifier_chain_register(&netdev_chain, nb);
        if (!err) {
                for (dev = dev_base; dev; dev = dev->next) {
                        nb->notifier_call(nb, NETDEV_REGISTER, dev);
        if (!err) {
                for (dev = dev_base; dev; dev = dev->next) {
                        nb->notifier_call(nb, NETDEV_REGISTER, dev);
@@ -990,12 +979,7 @@ int register_netdevice_notifier(struct notifier_block *nb)
 
 int unregister_netdevice_notifier(struct notifier_block *nb)
 {
 
 int unregister_netdevice_notifier(struct notifier_block *nb)
 {
-       int err;
-
-       rtnl_lock();
-       err = raw_notifier_chain_unregister(&netdev_chain, nb);
-       rtnl_unlock();
-       return err;
+       return notifier_chain_unregister(&netdev_chain, nb);
 }
 
 /**
 }
 
 /**
@@ -1004,12 +988,12 @@ int unregister_netdevice_notifier(struct notifier_block *nb)
  *      @v:   pointer passed unmodified to notifier function
  *
  *     Call all network notifier blocks.  Parameters and return value
  *      @v:   pointer passed unmodified to notifier function
  *
  *     Call all network notifier blocks.  Parameters and return value
- *     are as for raw_notifier_call_chain().
+ *     are as for notifier_call_chain().
  */
 
 int call_netdevice_notifiers(unsigned long val, void *v)
 {
  */
 
 int call_netdevice_notifiers(unsigned long val, void *v)
 {
-       return raw_notifier_call_chain(&netdev_chain, val, v);
+       return notifier_call_chain(&netdev_chain, val, v);
 }
 
 /* When > 0 there are consumers of rx skb time stamps */
 }
 
 /* When > 0 there are consumers of rx skb time stamps */
@@ -1050,8 +1034,10 @@ static inline void net_timestamp(struct sk_buff *skb)
  */
 
 #if !((defined(CONFIG_VNET) || defined(CONFIG_VNET_MODULE)))
  */
 
 #if !((defined(CONFIG_VNET) || defined(CONFIG_VNET_MODULE)))
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
 static
 #endif
 static
 #endif
+#endif
 void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
 {
        struct packet_type *ptype;
 void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
 {
        struct packet_type *ptype;
@@ -1093,70 +1079,6 @@ void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
        rcu_read_unlock();
 }
 
        rcu_read_unlock();
 }
 
-
-void __netif_schedule(struct net_device *dev)
-{
-       if (!test_and_set_bit(__LINK_STATE_SCHED, &dev->state)) {
-               unsigned long flags;
-               struct softnet_data *sd;
-
-               local_irq_save(flags);
-               sd = &__get_cpu_var(softnet_data);
-               dev->next_sched = sd->output_queue;
-               sd->output_queue = dev;
-               raise_softirq_irqoff(NET_TX_SOFTIRQ);
-               local_irq_restore(flags);
-       }
-}
-EXPORT_SYMBOL(__netif_schedule);
-
-void __netif_rx_schedule(struct net_device *dev)
-{
-       unsigned long flags;
-
-       local_irq_save(flags);
-       dev_hold(dev);
-       list_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list);
-       if (dev->quota < 0)
-               dev->quota += dev->weight;
-       else
-               dev->quota = dev->weight;
-       __raise_softirq_irqoff(NET_RX_SOFTIRQ);
-       local_irq_restore(flags);
-}
-EXPORT_SYMBOL(__netif_rx_schedule);
-
-void dev_kfree_skb_any(struct sk_buff *skb)
-{
-       if (in_irq() || irqs_disabled())
-               dev_kfree_skb_irq(skb);
-       else
-               dev_kfree_skb(skb);
-}
-EXPORT_SYMBOL(dev_kfree_skb_any);
-
-
-/* Hot-plugging. */
-void netif_device_detach(struct net_device *dev)
-{
-       if (test_and_clear_bit(__LINK_STATE_PRESENT, &dev->state) &&
-           netif_running(dev)) {
-               netif_stop_queue(dev);
-       }
-}
-EXPORT_SYMBOL(netif_device_detach);
-
-void netif_device_attach(struct net_device *dev)
-{
-       if (!test_and_set_bit(__LINK_STATE_PRESENT, &dev->state) &&
-           netif_running(dev)) {
-               netif_wake_queue(dev);
-               __netdev_watchdog_up(dev);
-       }
-}
-EXPORT_SYMBOL(netif_device_attach);
-
-
 /*
  * Invalidate hardware checksum when packet is to be mangled, and
  * complete checksum manually on outgoing path.
 /*
  * Invalidate hardware checksum when packet is to be mangled, and
  * complete checksum manually on outgoing path.
@@ -1190,45 +1112,6 @@ out:
        return ret;
 }
 
        return ret;
 }
 
-/**
- *     skb_gso_segment - Perform segmentation on skb.
- *     @skb: buffer to segment
- *     @features: features for the output path (see dev->features)
- *
- *     This function segments the given skb and returns a list of segments.
- *
- *     It may return NULL if the skb requires no segmentation.  This is
- *     only possible when GSO is used for verifying header integrity.
- */
-struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features)
-{
-       struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
-       struct packet_type *ptype;
-       int type = skb->protocol;
-
-       BUG_ON(skb_shinfo(skb)->frag_list);
-       BUG_ON(skb->ip_summed != CHECKSUM_HW);
-
-       skb->mac.raw = skb->data;
-       skb->mac_len = skb->nh.raw - skb->data;
-       __skb_pull(skb, skb->mac_len);
-
-       rcu_read_lock();
-       list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type) & 15], list) {
-               if (ptype->type == type && !ptype->dev && ptype->gso_segment) {
-                       segs = ptype->gso_segment(skb, features);
-                       break;
-               }
-       }
-       rcu_read_unlock();
-
-       __skb_push(skb, skb->data - skb->mac.raw);
-
-       return segs;
-}
-
-EXPORT_SYMBOL(skb_gso_segment);
-
 /* Take action when hardware reception checksum errors are detected. */
 #ifdef CONFIG_BUG
 void netdev_rx_csum_fault(struct net_device *dev)
 /* Take action when hardware reception checksum errors are detected. */
 #ifdef CONFIG_BUG
 void netdev_rx_csum_fault(struct net_device *dev)
@@ -1265,148 +1148,79 @@ static inline int illegal_highdma(struct net_device *dev, struct sk_buff *skb)
 #define illegal_highdma(dev, skb)      (0)
 #endif
 
 #define illegal_highdma(dev, skb)      (0)
 #endif
 
-struct dev_gso_cb {
-       void (*destructor)(struct sk_buff *skb);
-};
-
-#define DEV_GSO_CB(skb) ((struct dev_gso_cb *)(skb)->cb)
-
-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);
-
-       cb = DEV_GSO_CB(skb);
-       if (cb->destructor)
-               cb->destructor(skb);
-}
-
-/**
- *     dev_gso_segment - Perform emulated hardware segmentation on skb.
- *     @skb: buffer to segment
- *
- *     This function segments the given skb and stores the list of segments
- *     in skb->next.
- */
-static int dev_gso_segment(struct sk_buff *skb)
-{
-       struct net_device *dev = skb->dev;
-       struct sk_buff *segs;
-       int features = dev->features & ~(illegal_highdma(dev, skb) ?
-                                        NETIF_F_SG : 0);
-
-       segs = skb_gso_segment(skb, features);
-
-       /* Verifying header integrity only. */
-       if (!segs)
-               return 0;
-
-       if (unlikely(IS_ERR(segs)))
-               return PTR_ERR(segs);
-
-       skb->next = segs;
-       DEV_GSO_CB(skb)->destructor = skb->destructor;
-       skb->destructor = dev_gso_skb_destructor;
-
-       return 0;
-}
-
-int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-       if (likely(!skb->next)) {
-               if (netdev_nit)
-                       dev_queue_xmit_nit(skb, dev);
-
-               if (netif_needs_gso(dev, skb)) {
-                       if (unlikely(dev_gso_segment(skb)))
-                               goto out_kfree_skb;
-                       if (skb->next)
-                               goto gso;
-               }
-
-               return dev->hard_start_xmit(skb, dev);
-       }
-
-gso:
-       do {
-               struct sk_buff *nskb = skb->next;
-               int rc;
-
-               skb->next = nskb->next;
-               nskb->next = NULL;
-               rc = dev->hard_start_xmit(nskb, dev);
-               if (unlikely(rc)) {
-                       nskb->next = skb->next;
-                       skb->next = nskb;
-                       return rc;
-               }
-               if (unlikely(netif_queue_stopped(dev) && skb->next))
-                       return NETDEV_TX_BUSY;
-       } while (skb->next);
-       
-       skb->destructor = DEV_GSO_CB(skb)->destructor;
-
-out_kfree_skb:
-       kfree_skb(skb);
+/* Keep head the same: replace data */
+int __skb_linearize(struct sk_buff *skb, gfp_t gfp_mask)
+{
+       unsigned int size;
+       u8 *data;
+       long offset;
+       struct skb_shared_info *ninfo;
+       int headerlen = skb->data - skb->head;
+       int expand = (skb->tail + skb->data_len) - skb->end;
+
+       if (skb_shared(skb))
+               BUG();
+
+       if (expand <= 0)
+               expand = 0;
+
+       size = skb->end - skb->head + expand;
+       size = SKB_DATA_ALIGN(size);
+       data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
+       if (!data)
+               return -ENOMEM;
+
+       /* Copy entire thing */
+       if (skb_copy_bits(skb, -headerlen, data, headerlen + skb->len))
+               BUG();
+
+       /* Set up shinfo */
+       ninfo = (struct skb_shared_info*)(data + size);
+       atomic_set(&ninfo->dataref, 1);
+       ninfo->tso_size = skb_shinfo(skb)->tso_size;
+       ninfo->tso_segs = skb_shinfo(skb)->tso_segs;
+       ninfo->ufo_size = skb_shinfo(skb)->ufo_size;
+       ninfo->nr_frags = 0;
+       ninfo->frag_list = NULL;
+
+       /* Offset between the two in bytes */
+       offset = data - skb->head;
+
+       /* Free old data. */
+       skb_release_data(skb);
+
+       skb->head = data;
+       skb->end  = data + size;
+
+       /* Set up new pointers */
+       skb->h.raw   += offset;
+       skb->nh.raw  += offset;
+       skb->mac.raw += offset;
+       skb->tail    += offset;
+       skb->data    += offset;
+
+       /* We are no longer a clone, even if we were. */
+       skb->cloned    = 0;
+
+       skb->tail     += skb->data_len;
+       skb->data_len  = 0;
        return 0;
 }
 
 #define HARD_TX_LOCK(dev, cpu) {                       \
        if ((dev->features & NETIF_F_LLTX) == 0) {      \
        return 0;
 }
 
 #define HARD_TX_LOCK(dev, cpu) {                       \
        if ((dev->features & NETIF_F_LLTX) == 0) {      \
-               netif_tx_lock(dev);                     \
+               spin_lock(&dev->xmit_lock);             \
+               dev->xmit_lock_owner = cpu;             \
        }                                               \
 }
 
 #define HARD_TX_UNLOCK(dev) {                          \
        if ((dev->features & NETIF_F_LLTX) == 0) {      \
        }                                               \
 }
 
 #define HARD_TX_UNLOCK(dev) {                          \
        if ((dev->features & NETIF_F_LLTX) == 0) {      \
-               netif_tx_unlock(dev);                   \
+               dev->xmit_lock_owner = -1;              \
+               spin_unlock(&dev->xmit_lock);           \
        }                                               \
 }
 
        }                                               \
 }
 
-#ifdef CONFIG_XEN
-inline int skb_checksum_setup(struct sk_buff *skb)
-{
-       if (skb->proto_csum_blank) {
-               if (skb->protocol != htons(ETH_P_IP))
-                       goto out;
-               skb->h.raw = (unsigned char *)skb->nh.iph + 4*skb->nh.iph->ihl;
-               if (skb->h.raw >= skb->tail)
-                       goto out;
-               switch (skb->nh.iph->protocol) {
-               case IPPROTO_TCP:
-                       skb->csum = offsetof(struct tcphdr, check);
-                       break;
-               case IPPROTO_UDP:
-                       skb->csum = offsetof(struct udphdr, check);
-                       break;
-               default:
-                       if (net_ratelimit())
-                               printk(KERN_ERR "Attempting to checksum a non-"
-                                      "TCP/UDP packet, dropping a protocol"
-                                      " %d packet", skb->nh.iph->protocol);
-                       goto out;
-               }
-               if ((skb->h.raw + skb->csum + 2) > skb->tail)
-                       goto out;
-               skb->ip_summed = CHECKSUM_HW;
-               skb->proto_csum_blank = 0;
-       }
-       return 0;
-out:
-       return -EPROTO;
-}
-#else
-inline int skb_checksum_setup(struct sk_buff *skb) { return 0; }
-#endif
-
-
 /**
  *     dev_queue_xmit - transmit a buffer
  *     @skb: buffer to transmit
 /**
  *     dev_queue_xmit - transmit a buffer
  *     @skb: buffer to transmit
@@ -1439,19 +1253,9 @@ int dev_queue_xmit(struct sk_buff *skb)
        struct Qdisc *q;
        int rc = -ENOMEM;
 
        struct Qdisc *q;
        int rc = -ENOMEM;
 
-       /* If a checksum-deferred packet is forwarded to a device that needs a
-        * checksum, correct the pointers and force checksumming.
-        */
-       if (skb_checksum_setup(skb))
-               goto out_kfree_skb;
-
-       /* GSO will handle the following emulations directly. */
-       if (netif_needs_gso(dev, skb))
-               goto gso;
-
        if (skb_shinfo(skb)->frag_list &&
            !(dev->features & NETIF_F_FRAGLIST) &&
        if (skb_shinfo(skb)->frag_list &&
            !(dev->features & NETIF_F_FRAGLIST) &&
-           __skb_linearize(skb))
+           __skb_linearize(skb, GFP_ATOMIC))
                goto out_kfree_skb;
 
        /* Fragmented skb is linearized if device does not support SG,
                goto out_kfree_skb;
 
        /* Fragmented skb is linearized if device does not support SG,
@@ -1460,26 +1264,25 @@ int dev_queue_xmit(struct sk_buff *skb)
         */
        if (skb_shinfo(skb)->nr_frags &&
            (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) &&
         */
        if (skb_shinfo(skb)->nr_frags &&
            (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) &&
-           __skb_linearize(skb))
+           __skb_linearize(skb, GFP_ATOMIC))
                goto out_kfree_skb;
 
        /* If packet is not checksummed and device does not support
         * checksumming for this protocol, complete checksumming here.
         */
        if (skb->ip_summed == CHECKSUM_HW &&
                goto out_kfree_skb;
 
        /* If packet is not checksummed and device does not support
         * checksumming for this protocol, complete checksumming here.
         */
        if (skb->ip_summed == CHECKSUM_HW &&
-           (!(dev->features & NETIF_F_GEN_CSUM) &&
+           (!(dev->features & (NETIF_F_HW_CSUM | NETIF_F_NO_CSUM)) &&
             (!(dev->features & NETIF_F_IP_CSUM) ||
              skb->protocol != htons(ETH_P_IP))))
                if (skb_checksum_help(skb, 0))
                        goto out_kfree_skb;
 
             (!(dev->features & NETIF_F_IP_CSUM) ||
              skb->protocol != htons(ETH_P_IP))))
                if (skb_checksum_help(skb, 0))
                        goto out_kfree_skb;
 
-gso:
        spin_lock_prefetch(&dev->queue_lock);
 
        /* Disable soft irqs for various locks below. Also 
         * stops preemption for RCU. 
         */
        spin_lock_prefetch(&dev->queue_lock);
 
        /* Disable soft irqs for various locks below. Also 
         * stops preemption for RCU. 
         */
-       rcu_read_lock_bh(); 
+       local_bh_disable(); 
 
        /* Updates of qdisc are serialized by queue_lock. 
         * The struct Qdisc which is pointed to by qdisc is now a 
 
        /* Updates of qdisc are serialized by queue_lock. 
         * The struct Qdisc which is pointed to by qdisc is now a 
@@ -1500,21 +1303,23 @@ gso:
        if (q->enqueue) {
                /* Grab device queue */
                spin_lock(&dev->queue_lock);
        if (q->enqueue) {
                /* Grab device queue */
                spin_lock(&dev->queue_lock);
+               q = dev->qdisc;
+               if (q->enqueue) {
+                       rc = q->enqueue(skb, q);
+                       qdisc_run(dev);
+                       spin_unlock(&dev->queue_lock);
 
 
-               rc = q->enqueue(skb, q);
-
-               qdisc_run(dev);
-
+                       rc = rc == NET_XMIT_BYPASS ? NET_XMIT_SUCCESS : rc;
+                       goto out;
+               }
                spin_unlock(&dev->queue_lock);
                spin_unlock(&dev->queue_lock);
-               rc = rc == NET_XMIT_BYPASS ? NET_XMIT_SUCCESS : rc;
-               goto out;
        }
 
        /* The device has no queue. Common case for software devices:
           loopback, all the sorts of tunnels...
 
        }
 
        /* The device has no queue. Common case for software devices:
           loopback, all the sorts of tunnels...
 
-          Really, it is unlikely that netif_tx_lock protection is necessary
-          here.  (f.e. loopback and IP tunnels are clean ignoring statistics
+          Really, it is unlikely that xmit_lock protection is necessary here.
+          (f.e. loopback and IP tunnels are clean ignoring statistics
           counters.)
           However, it is possible, that they rely on protection
           made by us here.
           counters.)
           However, it is possible, that they rely on protection
           made by us here.
@@ -1530,8 +1335,11 @@ gso:
                        HARD_TX_LOCK(dev, cpu);
 
                        if (!netif_queue_stopped(dev)) {
                        HARD_TX_LOCK(dev, cpu);
 
                        if (!netif_queue_stopped(dev)) {
+                               if (netdev_nit)
+                                       dev_queue_xmit_nit(skb, dev);
+
                                rc = 0;
                                rc = 0;
-                               if (!dev_hard_start_xmit(skb, dev)) {
+                               if (!dev->hard_start_xmit(skb, dev)) {
                                        HARD_TX_UNLOCK(dev);
                                        goto out;
                                }
                                        HARD_TX_UNLOCK(dev);
                                        goto out;
                                }
@@ -1550,13 +1358,13 @@ gso:
        }
 
        rc = -ENETDOWN;
        }
 
        rc = -ENETDOWN;
-       rcu_read_unlock_bh();
+       local_bh_enable();
 
 out_kfree_skb:
        kfree_skb(skb);
        return rc;
 out:
 
 out_kfree_skb:
        kfree_skb(skb);
        return rc;
 out:
-       rcu_read_unlock_bh();
+       local_bh_enable();
        return rc;
 }
 
        return rc;
 }
 
@@ -1649,29 +1457,8 @@ static inline struct net_device *skb_bond(struct sk_buff *skb)
 {
        struct net_device *dev = skb->dev;
 
 {
        struct net_device *dev = skb->dev;
 
-       if (dev->master) {
-               /*
-                * On bonding slaves other than the currently active
-                * slave, suppress duplicates except for 802.3ad
-                * ETH_P_SLOW and alb non-mcast/bcast.
-                */
-               if (dev->priv_flags & IFF_SLAVE_INACTIVE) {
-                       if (dev->master->priv_flags & IFF_MASTER_ALB) {
-                               if (skb->pkt_type != PACKET_BROADCAST &&
-                                   skb->pkt_type != PACKET_MULTICAST)
-                                       goto keep;
-                       }
-
-                       if (dev->master->priv_flags & IFF_MASTER_8023AD &&
-                           skb->protocol == __constant_htons(ETH_P_SLOW))
-                               goto keep;
-               
-                       kfree_skb(skb);
-                       return NULL;
-               }
-keep:
+       if (dev->master)
                skb->dev = dev->master;
                skb->dev = dev->master;
-       }
 
        return dev;
 }
 
        return dev;
 }
@@ -1815,9 +1602,6 @@ int netif_receive_skb(struct sk_buff *skb)
 
        orig_dev = skb_bond(skb);
 
 
        orig_dev = skb_bond(skb);
 
-       if (!orig_dev)
-               return NET_RX_DROP;
-
        __get_cpu_var(netdev_rx_stat).total++;
 
        skb->h.raw = skb->nh.raw = skb->data;
        __get_cpu_var(netdev_rx_stat).total++;
 
        skb->h.raw = skb->nh.raw = skb->data;
@@ -1834,19 +1618,6 @@ int netif_receive_skb(struct sk_buff *skb)
        }
 #endif
 
        }
 #endif
 
-#ifdef CONFIG_XEN
-       switch (skb->ip_summed) {
-       case CHECKSUM_UNNECESSARY:
-               skb->proto_data_valid = 1;
-               break;
-       case CHECKSUM_HW:
-               /* XXX Implement me. */
-       default:
-               skb->proto_data_valid = 0;
-               break;
-       }
-#endif
-
        list_for_each_entry_rcu(ptype, &ptype_all, list) {
                if (!ptype->dev || ptype->dev == skb->dev) {
                        if (pt_prev) 
        list_for_each_entry_rcu(ptype, &ptype_all, list) {
                if (!ptype->dev || ptype->dev == skb->dev) {
                        if (pt_prev) 
@@ -1975,7 +1746,8 @@ static void net_rx_action(struct softirq_action *h)
                if (dev->quota <= 0 || dev->poll(dev, &budget)) {
                        netpoll_poll_unlock(have);
                        local_irq_disable();
                if (dev->quota <= 0 || dev->poll(dev, &budget)) {
                        netpoll_poll_unlock(have);
                        local_irq_disable();
-                       list_move_tail(&dev->poll_list, &queue->poll_list);
+                       list_del(&dev->poll_list);
+                       list_add_tail(&dev->poll_list, &queue->poll_list);
                        if (dev->quota < 0)
                                dev->quota += dev->weight;
                        else
                        if (dev->quota < 0)
                                dev->quota += dev->weight;
                        else
@@ -2272,7 +2044,7 @@ static struct file_operations softnet_seq_fops = {
        .release = seq_release,
 };
 
        .release = seq_release,
 };
 
-#ifdef CONFIG_WIRELESS_EXT
+#ifdef WIRELESS_EXT
 extern int wireless_proc_init(void);
 #else
 #define wireless_proc_init() 0
 extern int wireless_proc_init(void);
 #else
 #define wireless_proc_init() 0
@@ -2346,7 +2118,7 @@ int netdev_set_master(struct net_device *slave, struct net_device *master)
  *     @dev: device
  *     @inc: modifier
  *
  *     @dev: device
  *     @inc: modifier
  *
- *     Add or remove promiscuity from a device. While the count in the device
+ *     Add or remove promsicuity from a device. While the count in the device
  *     remains above zero the interface remains promiscuous. Once it hits zero
  *     the device reverts back to normal filtering operation. A negative inc
  *     value is used to drop promiscuity on the device.
  *     remains above zero the interface remains promiscuous. Once it hits zero
  *     the device reverts back to normal filtering operation. A negative inc
  *     value is used to drop promiscuity on the device.
@@ -2364,12 +2136,6 @@ void dev_set_promiscuity(struct net_device *dev, int inc)
                printk(KERN_INFO "device %s %s promiscuous mode\n",
                       dev->name, (dev->flags & IFF_PROMISC) ? "entered" :
                                                               "left");
                printk(KERN_INFO "device %s %s promiscuous mode\n",
                       dev->name, (dev->flags & IFF_PROMISC) ? "entered" :
                                                               "left");
-               audit_log(current->audit_context, GFP_ATOMIC,
-                       AUDIT_ANOM_PROMISCUOUS,
-                       "dev=%s prom=%d old_prom=%d auid=%u",
-                       dev->name, (dev->flags & IFF_PROMISC),
-                       (old_flags & IFF_PROMISC),
-                       audit_get_loginuid(current->audit_context)); 
        }
 }
 
        }
 }
 
@@ -2402,20 +2168,12 @@ unsigned dev_get_flags(const struct net_device *dev)
 
        flags = (dev->flags & ~(IFF_PROMISC |
                                IFF_ALLMULTI |
 
        flags = (dev->flags & ~(IFF_PROMISC |
                                IFF_ALLMULTI |
-                               IFF_RUNNING |
-                               IFF_LOWER_UP |
-                               IFF_DORMANT)) |
+                               IFF_RUNNING)) | 
                (dev->gflags & (IFF_PROMISC |
                                IFF_ALLMULTI));
 
                (dev->gflags & (IFF_PROMISC |
                                IFF_ALLMULTI));
 
-       if (netif_running(dev)) {
-               if (netif_oper_up(dev))
-                       flags |= IFF_RUNNING;
-               if (netif_carrier_ok(dev))
-                       flags |= IFF_LOWER_UP;
-               if (netif_dormant(dev))
-                       flags |= IFF_DORMANT;
-       }
+       if (netif_running(dev) && netif_carrier_ok(dev))
+               flags |= IFF_RUNNING;
 
        return flags;
 }
 
        return flags;
 }
@@ -2458,8 +2216,7 @@ int dev_change_flags(struct net_device *dev, unsigned flags)
        if (dev->flags & IFF_UP &&
            ((old_flags ^ dev->flags) &~ (IFF_UP | IFF_PROMISC | IFF_ALLMULTI |
                                          IFF_VOLATILE)))
        if (dev->flags & IFF_UP &&
            ((old_flags ^ dev->flags) &~ (IFF_UP | IFF_PROMISC | IFF_ALLMULTI |
                                          IFF_VOLATILE)))
-               raw_notifier_call_chain(&netdev_chain,
-                               NETDEV_CHANGE, dev);
+               notifier_call_chain(&netdev_chain, NETDEV_CHANGE, dev);
 
        if ((flags ^ dev->gflags) & IFF_PROMISC) {
                int inc = (flags & IFF_PROMISC) ? +1 : -1;
 
        if ((flags ^ dev->gflags) & IFF_PROMISC) {
                int inc = (flags & IFF_PROMISC) ? +1 : -1;
@@ -2503,8 +2260,8 @@ int dev_set_mtu(struct net_device *dev, int new_mtu)
        else
                dev->mtu = new_mtu;
        if (!err && dev->flags & IFF_UP)
        else
                dev->mtu = new_mtu;
        if (!err && dev->flags & IFF_UP)
-               raw_notifier_call_chain(&netdev_chain,
-                               NETDEV_CHANGEMTU, dev);
+               notifier_call_chain(&netdev_chain,
+                                   NETDEV_CHANGEMTU, dev);
        return err;
 }
 
        return err;
 }
 
@@ -2520,8 +2277,7 @@ int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa)
                return -ENODEV;
        err = dev->set_mac_address(dev, sa);
        if (!err)
                return -ENODEV;
        err = dev->set_mac_address(dev, sa);
        if (!err)
-               raw_notifier_call_chain(&netdev_chain,
-                               NETDEV_CHANGEADDR, dev);
+               notifier_call_chain(&netdev_chain, NETDEV_CHANGEADDR, dev);
        return err;
 }
 
        return err;
 }
 
@@ -2577,7 +2333,7 @@ static int dev_ifsioc(struct ifreq *ifr, unsigned int cmd)
                                return -EINVAL;
                        memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data,
                               min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len));
                                return -EINVAL;
                        memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data,
                               min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len));
-                       raw_notifier_call_chain(&netdev_chain,
+                       notifier_call_chain(&netdev_chain,
                                            NETDEV_CHANGEADDR, dev);
                        return 0;
 
                                            NETDEV_CHANGEADDR, dev);
                        return 0;
 
@@ -2696,9 +2452,9 @@ int dev_ioctl(unsigned int cmd, void __user *arg)
         */
 
        if (cmd == SIOCGIFCONF) {
         */
 
        if (cmd == SIOCGIFCONF) {
-               rtnl_lock();
+               rtnl_shlock();
                ret = dev_ifconf((char __user *) arg);
                ret = dev_ifconf((char __user *) arg);
-               rtnl_unlock();
+               rtnl_shunlock();
                return ret;
        }
        if (cmd == SIOCGIFNAME)
                return ret;
        }
        if (cmd == SIOCGIFNAME)
@@ -2842,14 +2598,13 @@ int dev_ioctl(unsigned int cmd, void __user *arg)
                                        ret = -EFAULT;
                                return ret;
                        }
                                        ret = -EFAULT;
                                return ret;
                        }
-#ifdef CONFIG_WIRELESS_EXT
+#ifdef WIRELESS_EXT
                        /* Take care of Wireless Extensions */
                        if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
                                /* If command is `set a parameter', or
                                 * `get the encoding parameters', check if
                                 * the user has the right to do it */
                        /* Take care of Wireless Extensions */
                        if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
                                /* If command is `set a parameter', or
                                 * `get the encoding parameters', check if
                                 * the user has the right to do it */
-                               if (IW_IS_SET(cmd) || cmd == SIOCGIWENCODE
-                                   || cmd == SIOCGIWENCODEEXT) {
+                               if (IW_IS_SET(cmd) || cmd == SIOCGIWENCODE) {
                                        if (!capable(CAP_NET_ADMIN))
                                                return -EPERM;
                                }
                                        if (!capable(CAP_NET_ADMIN))
                                                return -EPERM;
                                }
@@ -2864,7 +2619,7 @@ int dev_ioctl(unsigned int cmd, void __user *arg)
                                        ret = -EFAULT;
                                return ret;
                        }
                                        ret = -EFAULT;
                                return ret;
                        }
-#endif /* CONFIG_WIRELESS_EXT */
+#endif /* WIRELESS_EXT */
                        return -EINVAL;
        }
 }
                        return -EINVAL;
        }
 }
@@ -2927,13 +2682,11 @@ int register_netdevice(struct net_device *dev)
        BUG_ON(dev_boot_phase);
        ASSERT_RTNL();
 
        BUG_ON(dev_boot_phase);
        ASSERT_RTNL();
 
-       might_sleep();
-
        /* When net_device's are persistent, this will be fatal. */
        BUG_ON(dev->reg_state != NETREG_UNINITIALIZED);
 
        spin_lock_init(&dev->queue_lock);
        /* When net_device's are persistent, this will be fatal. */
        BUG_ON(dev->reg_state != NETREG_UNINITIALIZED);
 
        spin_lock_init(&dev->queue_lock);
-       spin_lock_init(&dev->_xmit_lock);
+       spin_lock_init(&dev->xmit_lock);
        dev->xmit_lock_owner = -1;
 #ifdef CONFIG_NET_CLS_ACT
        spin_lock_init(&dev->ingress_lock);
        dev->xmit_lock_owner = -1;
 #ifdef CONFIG_NET_CLS_ACT
        spin_lock_init(&dev->ingress_lock);
@@ -2977,7 +2730,9 @@ int register_netdevice(struct net_device *dev)
 
        /* Fix illegal SG+CSUM combinations. */
        if ((dev->features & NETIF_F_SG) &&
 
        /* Fix illegal SG+CSUM combinations. */
        if ((dev->features & NETIF_F_SG) &&
-           !(dev->features & NETIF_F_ALL_CSUM)) {
+           !(dev->features & (NETIF_F_IP_CSUM |
+                              NETIF_F_NO_CSUM |
+                              NETIF_F_HW_CSUM))) {
                printk("%s: Dropping NETIF_F_SG since no checksum feature.\n",
                       dev->name);
                dev->features &= ~NETIF_F_SG;
                printk("%s: Dropping NETIF_F_SG since no checksum feature.\n",
                       dev->name);
                dev->features &= ~NETIF_F_SG;
@@ -3013,11 +2768,6 @@ int register_netdevice(struct net_device *dev)
        if (!dev->rebuild_header)
                dev->rebuild_header = default_rebuild_header;
 
        if (!dev->rebuild_header)
                dev->rebuild_header = default_rebuild_header;
 
-       ret = netdev_register_sysfs(dev);
-       if (ret)
-               goto out_err;
-       dev->reg_state = NETREG_REGISTERED;
-
        /*
         *      Default initial state at registry is that the
         *      device is present.
        /*
         *      Default initial state at registry is that the
         *      device is present.
@@ -3033,11 +2783,14 @@ int register_netdevice(struct net_device *dev)
        hlist_add_head(&dev->name_hlist, head);
        hlist_add_head(&dev->index_hlist, dev_index_hash(dev->ifindex));
        dev_hold(dev);
        hlist_add_head(&dev->name_hlist, head);
        hlist_add_head(&dev->index_hlist, dev_index_hash(dev->ifindex));
        dev_hold(dev);
+       dev->reg_state = NETREG_REGISTERING;
        write_unlock_bh(&dev_base_lock);
 
        /* Notify protocols, that a new device appeared. */
        write_unlock_bh(&dev_base_lock);
 
        /* Notify protocols, that a new device appeared. */
-       raw_notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev);
+       notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev);
 
 
+       /* Finish registration after unlock */
+       net_set_todo(dev);
        ret = 0;
 
 out:
        ret = 0;
 
 out:
@@ -3110,10 +2863,10 @@ static void netdev_wait_allrefs(struct net_device *dev)
        rebroadcast_time = warning_time = jiffies;
        while (atomic_read(&dev->refcnt) != 0) {
                if (time_after(jiffies, rebroadcast_time + 1 * HZ)) {
        rebroadcast_time = warning_time = jiffies;
        while (atomic_read(&dev->refcnt) != 0) {
                if (time_after(jiffies, rebroadcast_time + 1 * HZ)) {
-                       rtnl_lock();
+                       rtnl_shlock();
 
                        /* Rebroadcast unregister notification */
 
                        /* Rebroadcast unregister notification */
-                       raw_notifier_call_chain(&netdev_chain,
+                       notifier_call_chain(&netdev_chain,
                                            NETDEV_UNREGISTER, dev);
 
                        if (test_bit(__LINK_STATE_LINKWATCH_PENDING,
                                            NETDEV_UNREGISTER, dev);
 
                        if (test_bit(__LINK_STATE_LINKWATCH_PENDING,
@@ -3127,7 +2880,7 @@ static void netdev_wait_allrefs(struct net_device *dev)
                                linkwatch_run_queue();
                        }
 
                                linkwatch_run_queue();
                        }
 
-                       __rtnl_unlock();
+                       rtnl_shunlock();
 
                        rebroadcast_time = jiffies;
                }
 
                        rebroadcast_time = jiffies;
                }
@@ -3160,18 +2913,20 @@ static void netdev_wait_allrefs(struct net_device *dev)
  *
  * We are invoked by rtnl_unlock() after it drops the semaphore.
  * This allows us to deal with problems:
  *
  * We are invoked by rtnl_unlock() after it drops the semaphore.
  * This allows us to deal with problems:
- * 1) We can delete sysfs objects which invoke hotplug
+ * 1) We can create/delete sysfs objects which invoke hotplug
  *    without deadlocking with linkwatch via keventd.
  * 2) Since we run with the RTNL semaphore not held, we can sleep
  *    safely in order to wait for the netdev refcnt to drop to zero.
  */
  *    without deadlocking with linkwatch via keventd.
  * 2) Since we run with the RTNL semaphore not held, we can sleep
  *    safely in order to wait for the netdev refcnt to drop to zero.
  */
-static DEFINE_MUTEX(net_todo_run_mutex);
+static DECLARE_MUTEX(net_todo_run_mutex);
 void netdev_run_todo(void)
 {
        struct list_head list = LIST_HEAD_INIT(list);
 void netdev_run_todo(void)
 {
        struct list_head list = LIST_HEAD_INIT(list);
+       int err;
+
 
        /* Need to guard against multiple cpu's getting out of order. */
 
        /* Need to guard against multiple cpu's getting out of order. */
-       mutex_lock(&net_todo_run_mutex);
+       down(&net_todo_run_mutex);
 
        /* Not safe to do outside the semaphore.  We must not return
         * until all unregister events invoked by the local processor
 
        /* Not safe to do outside the semaphore.  We must not return
         * until all unregister events invoked by the local processor
@@ -3191,33 +2946,44 @@ void netdev_run_todo(void)
                        = list_entry(list.next, struct net_device, todo_list);
                list_del(&dev->todo_list);
 
                        = list_entry(list.next, struct net_device, todo_list);
                list_del(&dev->todo_list);
 
-               if (unlikely(dev->reg_state != NETREG_UNREGISTERING)) {
-                       printk(KERN_ERR "network todo '%s' but state %d\n",
-                              dev->name, dev->reg_state);
-                       dump_stack();
-                       continue;
-               }
+               switch(dev->reg_state) {
+               case NETREG_REGISTERING:
+                       dev->reg_state = NETREG_REGISTERED;
+                       err = netdev_register_sysfs(dev);
+                       if (err)
+                               printk(KERN_ERR "%s: failed sysfs registration (%d)\n",
+                                      dev->name, err);
+                       break;
 
 
-               netdev_unregister_sysfs(dev);
-               dev->reg_state = NETREG_UNREGISTERED;
+               case NETREG_UNREGISTERING:
+                       netdev_unregister_sysfs(dev);
+                       dev->reg_state = NETREG_UNREGISTERED;
 
 
-               netdev_wait_allrefs(dev);
+                       netdev_wait_allrefs(dev);
 
 
-               /* paranoia */
-               BUG_ON(atomic_read(&dev->refcnt));
-               BUG_TRAP(!dev->ip_ptr);
-               BUG_TRAP(!dev->ip6_ptr);
-               BUG_TRAP(!dev->dn_ptr);
+                       /* paranoia */
+                       BUG_ON(atomic_read(&dev->refcnt));
+                       BUG_TRAP(!dev->ip_ptr);
+                       BUG_TRAP(!dev->ip6_ptr);
+                       BUG_TRAP(!dev->dn_ptr);
 
 
-               /* It must be the very last action,
-                * after this 'dev' may point to freed up memory.
-                */
-               if (dev->destructor)
-                       dev->destructor(dev);
+
+                       /* It must be the very last action, 
+                        * after this 'dev' may point to freed up memory.
+                        */
+                       if (dev->destructor)
+                               dev->destructor(dev);
+                       break;
+
+               default:
+                       printk(KERN_ERR "network todo '%s' but state %d\n",
+                              dev->name, dev->reg_state);
+                       break;
+               }
        }
 
 out:
        }
 
 out:
-       mutex_unlock(&net_todo_run_mutex);
+       up(&net_todo_run_mutex);
 }
 
 /**
 }
 
 /**
@@ -3240,11 +3006,12 @@ struct net_device *alloc_netdev(int sizeof_priv, const char *name,
        alloc_size = (sizeof(*dev) + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST;
        alloc_size += sizeof_priv + NETDEV_ALIGN_CONST;
 
        alloc_size = (sizeof(*dev) + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST;
        alloc_size += sizeof_priv + NETDEV_ALIGN_CONST;
 
-       p = kzalloc(alloc_size, GFP_KERNEL);
+       p = kmalloc(alloc_size, GFP_KERNEL);
        if (!p) {
                printk(KERN_ERR "alloc_dev: Unable to allocate device.\n");
                return NULL;
        }
        if (!p) {
                printk(KERN_ERR "alloc_dev: Unable to allocate device.\n");
                return NULL;
        }
+       memset(p, 0, alloc_size);
 
        dev = (struct net_device *)
                (((long)p + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST);
 
        dev = (struct net_device *)
                (((long)p + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST);
@@ -3270,7 +3037,7 @@ EXPORT_SYMBOL(alloc_netdev);
 void free_netdev(struct net_device *dev)
 {
 #ifdef CONFIG_SYSFS
 void free_netdev(struct net_device *dev)
 {
 #ifdef CONFIG_SYSFS
-       /*  Compatibility with error handling in drivers */
+       /*  Compatiablity with error handling in drivers */
        if (dev->reg_state == NETREG_UNINITIALIZED) {
                kfree((char *)dev - dev->padded);
                return;
        if (dev->reg_state == NETREG_UNINITIALIZED) {
                kfree((char *)dev - dev->padded);
                return;
@@ -3355,7 +3122,7 @@ int unregister_netdevice(struct net_device *dev)
        /* Notify protocols, that we are about to destroy
           this device. They should clean all the things.
        */
        /* Notify protocols, that we are about to destroy
           this device. They should clean all the things.
        */
-       raw_notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev);
+       notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev);
        
        /*
         *      Flush the multicast chain
        
        /*
         *      Flush the multicast chain
@@ -3486,7 +3253,7 @@ static int __init net_dev_init(void)
         *      Initialise the packet receive queues.
         */
 
         *      Initialise the packet receive queues.
         */
 
-       for_each_possible_cpu(i) {
+       for_each_cpu(i) {
                struct softnet_data *queue;
 
                queue = &per_cpu(softnet_data, i);
                struct softnet_data *queue;
 
                queue = &per_cpu(softnet_data, i);
@@ -3517,6 +3284,7 @@ subsys_initcall(net_dev_init);
 EXPORT_SYMBOL(__dev_get_by_index);
 EXPORT_SYMBOL(__dev_get_by_name);
 EXPORT_SYMBOL(__dev_remove_pack);
 EXPORT_SYMBOL(__dev_get_by_index);
 EXPORT_SYMBOL(__dev_get_by_name);
 EXPORT_SYMBOL(__dev_remove_pack);
+EXPORT_SYMBOL(__skb_linearize);
 EXPORT_SYMBOL(dev_valid_name);
 EXPORT_SYMBOL(dev_add_pack);
 EXPORT_SYMBOL(dev_alloc_name);
 EXPORT_SYMBOL(dev_valid_name);
 EXPORT_SYMBOL(dev_add_pack);
 EXPORT_SYMBOL(dev_alloc_name);
@@ -3551,7 +3319,6 @@ EXPORT_SYMBOL(unregister_netdevice_notifier);
 EXPORT_SYMBOL(net_enable_timestamp);
 EXPORT_SYMBOL(net_disable_timestamp);
 EXPORT_SYMBOL(dev_get_flags);
 EXPORT_SYMBOL(net_enable_timestamp);
 EXPORT_SYMBOL(net_disable_timestamp);
 EXPORT_SYMBOL(dev_get_flags);
-EXPORT_SYMBOL(skb_checksum_setup);
 
 #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
 EXPORT_SYMBOL(br_handle_frame_hook);
 
 #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
 EXPORT_SYMBOL(br_handle_frame_hook);