Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
[safe/jmp/linux-2.6] / drivers / ieee1394 / eth1394.c
index e1fdfb5..1a919df 100644 (file)
 #include <linux/types.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/workqueue.h>
 
 #include <linux/netdevice.h>
 #include <linux/inetdevice.h>
-#include <linux/etherdevice.h>
 #include <linux/if_arp.h>
 #include <linux/if_ether.h>
 #include <linux/ip.h>
@@ -92,7 +92,7 @@ struct partial_datagram {
        struct list_head list;
        u16 dgl;
        u16 dg_size;
-       u16 ether_type;
+       __be16 ether_type;
        struct sk_buff *skb;
        char *pbuf;
        struct list_head frag_info;
@@ -136,9 +136,6 @@ static const int hdr_type_len[] = {
        sizeof(struct eth1394_sf_hdr)
 };
 
-/* For now, this needs to be 1500, so that XP works with us */
-#define ETH1394_DATA_LEN       ETH_DATA_LEN
-
 static const u16 eth1394_speedto_maxpayload[] = {
 /*     S100, S200, S400, S800, S1600, S3200 */
        512, 1024, 2048, 4096,  4096,  4096
@@ -162,16 +159,16 @@ MODULE_PARM_DESC(max_partial_datagrams,
 
 
 static int ether1394_header(struct sk_buff *skb, struct net_device *dev,
-                           unsigned short type, void *daddr, void *saddr,
-                           unsigned len);
+                           unsigned short type, const void *daddr,
+                           const void *saddr, unsigned len);
 static int ether1394_rebuild_header(struct sk_buff *skb);
-static int ether1394_header_parse(struct sk_buff *skb, unsigned char *haddr);
-static int ether1394_header_cache(struct neighbour *neigh, struct hh_cache *hh);
+static int ether1394_header_parse(const struct sk_buff *skb,
+                                 unsigned char *haddr);
+static int ether1394_header_cache(const struct neighbour *neigh,
+                                 struct hh_cache *hh);
 static void ether1394_header_cache_update(struct hh_cache *hh,
-                                         struct net_device *dev,
-                                         unsigned char *haddr);
-static int ether1394_mac_addr(struct net_device *dev, void *p);
-
+                                         const struct net_device *dev,
+                                         const unsigned char *haddr);
 static int ether1394_tx(struct sk_buff *skb, struct net_device *dev);
 static void ether1394_iso(struct hpsb_iso *iso);
 
@@ -184,7 +181,7 @@ static void ether1394_remove_host(struct hpsb_host *host);
 static void ether1394_host_reset(struct hpsb_host *host);
 
 /* Function for incoming 1394 packets */
-static struct hpsb_address_ops addr_ops = {
+const static struct hpsb_address_ops addr_ops = {
        .write =        ether1394_write,
 };
 
@@ -196,9 +193,8 @@ static struct hpsb_highlevel eth1394_highlevel = {
        .host_reset =   ether1394_host_reset,
 };
 
-static int ether1394_recv_init(struct net_device *dev)
+static int ether1394_recv_init(struct eth1394_priv *priv)
 {
-       struct eth1394_priv *priv = netdev_priv(dev);
        unsigned int iso_buf_size;
 
        /* FIXME: rawiso limits us to PAGE_SIZE */
@@ -212,9 +208,7 @@ static int ether1394_recv_init(struct net_device *dev)
                                       HPSB_ISO_DMA_PACKET_PER_BUFFER,
                                       1, ether1394_iso);
        if (priv->iso == NULL) {
-               ETH1394_PRINT(KERN_ERR, dev->name,
-                             "Could not allocate isochronous receive "
-                             "context for the broadcast channel\n");
+               ETH1394_PRINT_G(KERN_ERR, "Failed to allocate IR context\n");
                priv->bc_state = ETHER1394_BC_ERROR;
                return -EAGAIN;
        }
@@ -233,7 +227,7 @@ static int ether1394_open(struct net_device *dev)
        int ret;
 
        if (priv->bc_state == ETHER1394_BC_ERROR) {
-               ret = ether1394_recv_init(dev);
+               ret = ether1394_recv_init(priv);
                if (ret)
                        return ret;
        }
@@ -244,16 +238,13 @@ static int ether1394_open(struct net_device *dev)
 /* This is called after an "ifdown" */
 static int ether1394_stop(struct net_device *dev)
 {
+       /* flush priv->wake */
+       flush_scheduled_work();
+
        netif_stop_queue(dev);
        return 0;
 }
 
-/* Return statistics to the caller */
-static struct net_device_stats *ether1394_stats(struct net_device *dev)
-{
-       return &(((struct eth1394_priv *)netdev_priv(dev))->stats);
-}
-
 /* FIXME: What to do if we timeout? I think a host reset is probably in order,
  * so that's what we do. Should we increment the stat counters too?  */
 static void ether1394_tx_timeout(struct net_device *dev)
@@ -261,23 +252,31 @@ static void ether1394_tx_timeout(struct net_device *dev)
        struct hpsb_host *host =
                        ((struct eth1394_priv *)netdev_priv(dev))->host;
 
-       ETH1394_PRINT(KERN_ERR, dev->name, "Timeout, resetting host %s\n",
-                     host->driver->name);
-       highlevel_host_reset(host);
-       netif_wake_queue(dev);
+       ETH1394_PRINT(KERN_ERR, dev->name, "Timeout, resetting host\n");
+       ether1394_host_reset(host);
+}
+
+static inline int ether1394_max_mtu(struct hpsb_host* host)
+{
+       return (1 << (host->csr.max_rec + 1))
+                       - sizeof(union eth1394_hdr) - ETHER1394_GASP_OVERHEAD;
 }
 
 static int ether1394_change_mtu(struct net_device *dev, int new_mtu)
 {
-       int max_rec =
-               ((struct eth1394_priv *)netdev_priv(dev))->host->csr.max_rec;
+       int max_mtu;
 
-       if (new_mtu < 68 ||
-           new_mtu > ETH1394_DATA_LEN ||
-           new_mtu > (1 << (max_rec + 1)) - sizeof(union eth1394_hdr) -
-                     ETHER1394_GASP_OVERHEAD)
+       if (new_mtu < 68)
                return -EINVAL;
 
+       max_mtu = ether1394_max_mtu(
+                       ((struct eth1394_priv *)netdev_priv(dev))->host);
+       if (new_mtu > max_mtu) {
+               ETH1394_PRINT(KERN_INFO, dev->name,
+                             "Local node constrains MTU to %d\n", max_mtu);
+               return -ERANGE;
+       }
+
        dev->mtu = new_mtu;
        return 0;
 }
@@ -340,20 +339,13 @@ static struct eth1394_node_ref *eth1394_find_node_nodeid(struct list_head *inl,
        return NULL;
 }
 
-static int eth1394_probe(struct device *dev)
+static int eth1394_new_node(struct eth1394_host_info *hi,
+                           struct unit_directory *ud)
 {
-       struct unit_directory *ud;
-       struct eth1394_host_info *hi;
        struct eth1394_priv *priv;
        struct eth1394_node_ref *new_node;
        struct eth1394_node_info *node_info;
 
-       ud = container_of(dev, struct unit_directory, device);
-
-       hi = hpsb_get_hostinfo(&eth1394_highlevel, ud->ne->host);
-       if (!hi)
-               return -ENOENT;
-
        new_node = kmalloc(sizeof(*new_node), GFP_KERNEL);
        if (!new_node)
                return -ENOMEM;
@@ -374,10 +366,22 @@ static int eth1394_probe(struct device *dev)
 
        priv = netdev_priv(hi->dev);
        list_add_tail(&new_node->list, &priv->ip_node_list);
-
        return 0;
 }
 
+static int eth1394_probe(struct device *dev)
+{
+       struct unit_directory *ud;
+       struct eth1394_host_info *hi;
+
+       ud = container_of(dev, struct unit_directory, device);
+       hi = hpsb_get_hostinfo(&eth1394_highlevel, ud->ne->host);
+       if (!hi)
+               return -ENOENT;
+
+       return eth1394_new_node(hi, ud);
+}
+
 static int eth1394_remove(struct device *dev)
 {
        struct unit_directory *ud;
@@ -421,38 +425,17 @@ static int eth1394_update(struct unit_directory *ud)
        struct eth1394_host_info *hi;
        struct eth1394_priv *priv;
        struct eth1394_node_ref *node;
-       struct eth1394_node_info *node_info;
 
        hi = hpsb_get_hostinfo(&eth1394_highlevel, ud->ne->host);
        if (!hi)
                return -ENOENT;
 
        priv = netdev_priv(hi->dev);
-
        node = eth1394_find_node(&priv->ip_node_list, ud);
        if (node)
                return 0;
 
-       node = kmalloc(sizeof(*node), GFP_KERNEL);
-       if (!node)
-               return -ENOMEM;
-
-       node_info = kmalloc(sizeof(*node_info), GFP_KERNEL);
-       if (!node_info) {
-               kfree(node);
-               return -ENOMEM;
-       }
-
-       spin_lock_init(&node_info->pdg.lock);
-       INIT_LIST_HEAD(&node_info->pdg.list);
-       node_info->pdg.sz = 0;
-
-       ud->device.driver_data = node_info;
-       node->ud = ud;
-
-       priv = netdev_priv(hi->dev);
-       list_add_tail(&node->list, &priv->ip_node_list);
-       return 0;
+       return eth1394_new_node(hi, ud);
 }
 
 static struct ieee1394_device_id eth1394_id_table[] = {
@@ -488,22 +471,28 @@ static void ether1394_reset_priv(struct net_device *dev, int set_mtu)
 
        spin_lock_irqsave(&priv->lock, flags);
 
-       memset(priv->ud_list, 0, sizeof(struct node_entry*) * ALL_NODES);
+       memset(priv->ud_list, 0, sizeof(priv->ud_list));
        priv->bc_maxpayload = 512;
 
        /* Determine speed limit */
-       for (i = 0; i < host->node_count; i++)
+       /* FIXME: This is broken for nodes with link speed < PHY speed,
+        * and it is suboptimal for S200B...S800B hardware.
+        * The result of nodemgr's speed probe should be used somehow. */
+       for (i = 0; i < host->node_count; i++) {
+               /* take care of S100B...S400B PHY ports */
+               if (host->speed[i] == SELFID_SPEED_UNKNOWN) {
+                       max_speed = IEEE1394_SPEED_100;
+                       break;
+               }
                if (max_speed > host->speed[i])
                        max_speed = host->speed[i];
+       }
        priv->bc_sspd = max_speed;
 
-       /* We'll use our maximum payload as the default MTU */
        if (set_mtu) {
-               int max_payload = 1 << (host->csr.max_rec + 1);
-
-               dev->mtu = min(ETH1394_DATA_LEN,
-                              (int)(max_payload - sizeof(union eth1394_hdr) -
-                                    ETHER1394_GASP_OVERHEAD));
+               /* Use the RFC 2734 default 1500 octets or the maximum payload
+                * as initial MTU */
+               dev->mtu = min(1500, ether1394_max_mtu(host));
 
                /* Set our hardware address while we're at it */
                memcpy(dev->dev_addr, &guid, sizeof(u64));
@@ -513,26 +502,30 @@ static void ether1394_reset_priv(struct net_device *dev, int set_mtu)
        spin_unlock_irqrestore(&priv->lock, flags);
 }
 
-/* This function is called right before register_netdev */
+static const struct header_ops ether1394_header_ops = {
+       .create         = ether1394_header,
+       .rebuild        = ether1394_rebuild_header,
+       .cache          = ether1394_header_cache,
+       .cache_update   = ether1394_header_cache_update,
+       .parse          = ether1394_header_parse,
+};
+
+static const struct net_device_ops ether1394_netdev_ops = {
+       .ndo_open       = ether1394_open,
+       .ndo_stop       = ether1394_stop,
+       .ndo_start_xmit = ether1394_tx,
+       .ndo_tx_timeout = ether1394_tx_timeout,
+       .ndo_change_mtu = ether1394_change_mtu,
+};
+
 static void ether1394_init_dev(struct net_device *dev)
 {
-       /* Our functions */
-       dev->open               = ether1394_open;
-       dev->stop               = ether1394_stop;
-       dev->hard_start_xmit    = ether1394_tx;
-       dev->get_stats          = ether1394_stats;
-       dev->tx_timeout         = ether1394_tx_timeout;
-       dev->change_mtu         = ether1394_change_mtu;
-
-       dev->hard_header        = ether1394_header;
-       dev->rebuild_header     = ether1394_rebuild_header;
-       dev->hard_header_cache  = ether1394_header_cache;
-       dev->header_cache_update= ether1394_header_cache_update;
-       dev->hard_header_parse  = ether1394_header_parse;
-       dev->set_mac_address    = ether1394_mac_addr;
+
+       dev->header_ops         = &ether1394_header_ops;
+       dev->netdev_ops         = &ether1394_netdev_ops;
+
        SET_ETHTOOL_OPS(dev, &ethtool_ops);
 
-       /* Some constants */
        dev->watchdog_timeo     = ETHER1394_TIMEOUT;
        dev->flags              = IFF_BROADCAST | IFF_MULTICAST;
        dev->features           = NETIF_F_HIGHDMA;
@@ -540,7 +533,39 @@ static void ether1394_init_dev(struct net_device *dev)
        dev->hard_header_len    = ETH1394_HLEN;
        dev->type               = ARPHRD_IEEE1394;
 
-       ether1394_reset_priv(dev, 1);
+       /* FIXME: This value was copied from ether_setup(). Is it too much? */
+       dev->tx_queue_len       = 1000;
+}
+
+/*
+ * Wake the queue up after commonly encountered transmit failure conditions are
+ * hopefully over.  Currently only tlabel exhaustion is accounted for.
+ */
+static void ether1394_wake_queue(struct work_struct *work)
+{
+       struct eth1394_priv *priv;
+       struct hpsb_packet *packet;
+
+       priv = container_of(work, struct eth1394_priv, wake);
+       packet = hpsb_alloc_packet(0);
+
+       /* This is really bad, but unjam the queue anyway. */
+       if (!packet)
+               goto out;
+
+       packet->host = priv->host;
+       packet->node_id = priv->wake_node;
+       /*
+        * A transaction label is all we really want.  If we get one, it almost
+        * always means we can get a lot more because the ieee1394 core recycled
+        * a whole batch of tlabels, at last.
+        */
+       if (hpsb_get_tlabel(packet) == 0)
+               hpsb_free_tlabel(packet);
+
+       hpsb_free_packet(packet);
+out:
+       netif_wake_queue(priv->wake_dev);
 }
 
 /*
@@ -570,50 +595,37 @@ static void ether1394_add_host(struct hpsb_host *host)
                return;
        }
 
-       /* We should really have our own alloc_hpsbdev() function in
-        * net_init.c instead of calling the one for ethernet then hijacking
-        * it for ourselves.  That way we'd be a real networking device. */
-       dev = alloc_etherdev(sizeof (struct eth1394_priv));
-
+       dev = alloc_netdev(sizeof(*priv), "eth%d", ether1394_init_dev);
        if (dev == NULL) {
-               ETH1394_PRINT_G (KERN_ERR, "Out of memory trying to allocate "
-                                "etherdevice for IEEE 1394 device %s-%d\n",
-                                host->driver->name, host->id);
+               ETH1394_PRINT_G(KERN_ERR, "Out of memory\n");
                goto out;
        }
 
-       SET_MODULE_OWNER(dev);
-#if 0
-       /* FIXME - Is this the correct parent device anyway? */
        SET_NETDEV_DEV(dev, &host->device);
-#endif
 
        priv = netdev_priv(dev);
-
        INIT_LIST_HEAD(&priv->ip_node_list);
-
        spin_lock_init(&priv->lock);
        priv->host = host;
        priv->local_fifo = fifo_addr;
+       INIT_WORK(&priv->wake, ether1394_wake_queue);
+       priv->wake_dev = dev;
 
        hi = hpsb_create_hostinfo(&eth1394_highlevel, host, sizeof(*hi));
-
        if (hi == NULL) {
-               ETH1394_PRINT_G (KERN_ERR, "Out of memory trying to create "
-                                "hostinfo for IEEE 1394 device %s-%d\n",
-                                host->driver->name, host->id);
+               ETH1394_PRINT_G(KERN_ERR, "Out of memory\n");
                goto out;
        }
 
-       ether1394_init_dev(dev);
+       ether1394_reset_priv(dev, 1);
 
-       if (register_netdev (dev)) {
-               ETH1394_PRINT (KERN_ERR, dev->name, "Error registering network driver\n");
+       if (register_netdev(dev)) {
+               ETH1394_PRINT_G(KERN_ERR, "Cannot register the driver\n");
                goto out;
        }
 
-       ETH1394_PRINT (KERN_INFO, dev->name, "IEEE-1394 IPv4 over 1394 Ethernet (fw-host%d)\n",
-                      host->id);
+       ETH1394_PRINT(KERN_INFO, dev->name, "IPv4 over IEEE 1394 (fw-host%d)\n",
+                     host->id);
 
        hi->host = host;
        hi->dev = dev;
@@ -622,7 +634,7 @@ static void ether1394_add_host(struct hpsb_host *host)
         * be checked when the eth device is opened. */
        priv->broadcast_channel = host->csr.broadcast_channel & 0x3f;
 
-       ether1394_recv_init(dev);
+       ether1394_recv_init(priv);
        return;
 out:
        if (dev)
@@ -701,8 +713,8 @@ static void ether1394_host_reset(struct hpsb_host *host)
  * saddr=NULL means use device source address
  * daddr=NULL means leave destination address (eg unresolved arp). */
 static int ether1394_header(struct sk_buff *skb, struct net_device *dev,
-                           unsigned short type, void *daddr, void *saddr,
-                           unsigned len)
+                           unsigned short type, const void *daddr,
+                           const void *saddr, unsigned len)
 {
        struct eth1394hdr *eth =
                        (struct eth1394hdr *)skb_push(skb, ETH1394_HLEN);
@@ -732,35 +744,27 @@ static int ether1394_header(struct sk_buff *skb, struct net_device *dev,
 static int ether1394_rebuild_header(struct sk_buff *skb)
 {
        struct eth1394hdr *eth = (struct eth1394hdr *)skb->data;
-       struct net_device *dev = skb->dev;
-
-       switch (eth->h_proto) {
 
-#ifdef CONFIG_INET
-       case __constant_htons(ETH_P_IP):
+       if (eth->h_proto == htons(ETH_P_IP))
                return arp_find((unsigned char *)&eth->h_dest, skb);
-#endif
-       default:
-               ETH1394_PRINT(KERN_DEBUG, dev->name,
-                             "unable to resolve type %04x addresses.\n",
-                             ntohs(eth->h_proto));
-               break;
-       }
 
+       ETH1394_PRINT(KERN_DEBUG, skb->dev->name,
+                     "unable to resolve type %04x addresses\n",
+                     ntohs(eth->h_proto));
        return 0;
 }
 
-static int ether1394_header_parse(struct sk_buff *skb, unsigned char *haddr)
+static int ether1394_header_parse(const struct sk_buff *skb,
+                                 unsigned char *haddr)
 {
-       struct net_device *dev = skb->dev;
-
-       memcpy(haddr, dev->dev_addr, ETH1394_ALEN);
+       memcpy(haddr, skb->dev->dev_addr, ETH1394_ALEN);
        return ETH1394_ALEN;
 }
 
-static int ether1394_header_cache(struct neighbour *neigh, struct hh_cache *hh)
+static int ether1394_header_cache(const struct neighbour *neigh,
+                                 struct hh_cache *hh)
 {
-       unsigned short type = hh->hh_type;
+       __be16 type = hh->hh_type;
        struct net_device *dev = neigh->dev;
        struct eth1394hdr *eth =
                (struct eth1394hdr *)((u8 *)hh->hh_data + 16 - ETH1394_HLEN);
@@ -777,28 +781,18 @@ static int ether1394_header_cache(struct neighbour *neigh, struct hh_cache *hh)
 
 /* Called by Address Resolution module to notify changes in address. */
 static void ether1394_header_cache_update(struct hh_cache *hh,
-                                         struct net_device *dev,
-                                         unsigned char * haddr)
+                                         const struct net_device *dev,
+                                         const unsigned char * haddr)
 {
        memcpy((u8 *)hh->hh_data + 16 - ETH1394_HLEN, haddr, dev->addr_len);
 }
 
-static int ether1394_mac_addr(struct net_device *dev, void *p)
-{
-       if (netif_running(dev))
-               return -EBUSY;
-
-       /* Not going to allow setting the MAC address, we really need to use
-        * the real one supplied by the hardware */
-        return -EINVAL;
-}
-
 /******************************************
  * Datagram reception code
  ******************************************/
 
 /* Copied from net/ethernet/eth.c */
-static u16 ether1394_type_trans(struct sk_buff *skb, struct net_device *dev)
+static __be16 ether1394_type_trans(struct sk_buff *skb, struct net_device *dev)
 {
        struct eth1394hdr *eth;
        unsigned char *rawp;
@@ -832,17 +826,17 @@ static u16 ether1394_type_trans(struct sk_buff *skb, struct net_device *dev)
 
 /* Parse an encapsulated IP1394 header into an ethernet frame packet.
  * We also perform ARP translation here, if need be.  */
-static u16 ether1394_parse_encap(struct sk_buff *skb, struct net_device *dev,
+static __be16 ether1394_parse_encap(struct sk_buff *skb, struct net_device *dev,
                                 nodeid_t srcid, nodeid_t destid,
-                                u16 ether_type)
+                                __be16 ether_type)
 {
        struct eth1394_priv *priv = netdev_priv(dev);
-       u64 dest_hw;
-       unsigned short ret = 0;
+       __be64 dest_hw;
+       __be16 ret = 0;
 
        /* Setup our hw addresses. We use these to build the ethernet header. */
        if (destid == (LOCAL_BUS | ALL_NODES))
-               dest_hw = ~0ULL;  /* broadcast */
+               dest_hw = ~cpu_to_be64(0);  /* broadcast */
        else
                dest_hw = cpu_to_be64((u64)priv->host->csr.guid_hi << 32 |
                                      priv->host->csr.guid_lo);
@@ -876,7 +870,7 @@ static u16 ether1394_parse_encap(struct sk_buff *skb, struct net_device *dev,
                node = eth1394_find_node_guid(&priv->ip_node_list,
                                              be64_to_cpu(guid));
                if (!node)
-                       return 0;
+                       return cpu_to_be16(0);
 
                node_info =
                    (struct eth1394_node_info *)node->ud->device.driver_data;
@@ -908,8 +902,8 @@ static u16 ether1394_parse_encap(struct sk_buff *skb, struct net_device *dev,
        }
 
        /* Now add the ethernet header. */
-       if (dev->hard_header(skb, dev, ntohs(ether_type), &dest_hw, NULL,
-                            skb->len) >= 0)
+       if (dev_hard_header(skb, dev, ntohs(ether_type), &dest_hw, NULL,
+                           skb->len) >= 0)
                ret = ether1394_type_trans(skb, dev);
 
        return ret;
@@ -918,12 +912,12 @@ static u16 ether1394_parse_encap(struct sk_buff *skb, struct net_device *dev,
 static int fragment_overlap(struct list_head *frag_list, int offset, int len)
 {
        struct fragment_info *fi;
+       int end = offset + len;
 
-       list_for_each_entry(fi, frag_list, list) {
-               if ( ! ((offset > (fi->offset + fi->len - 1)) ||
-                      ((offset + len - 1) < fi->offset)))
+       list_for_each_entry(fi, frag_list, list)
+               if (offset < fi->offset + fi->len && end > fi->offset)
                        return 1;
-       }
+
        return 0;
 }
 
@@ -1066,7 +1060,7 @@ static int ether1394_data_handler(struct net_device *dev, int srcid, int destid,
        unsigned long flags;
        struct eth1394_priv *priv = netdev_priv(dev);
        union eth1394_hdr *hdr = (union eth1394_hdr *)buf;
-       u16 ether_type = 0;  /* initialized to clear warning */
+       __be16 ether_type = cpu_to_be16(0);  /* initialized to clear warning */
        int hdr_len;
        struct unit_directory *ud = priv->ud_list[NODEID_TO_NODE(srcid)];
        struct eth1394_node_info *node_info;
@@ -1074,11 +1068,11 @@ static int ether1394_data_handler(struct net_device *dev, int srcid, int destid,
        if (!ud) {
                struct eth1394_node_ref *node;
                node = eth1394_find_node_nodeid(&priv->ip_node_list, srcid);
-               if (!node) {
+               if (unlikely(!node)) {
                        HPSB_PRINT(KERN_ERR, "ether1394 rx: sender nodeid "
                                   "lookup failure: " NODE_BUS_FMT,
                                   NODE_BUS_ARGS(priv->host, srcid));
-                       priv->stats.rx_dropped++;
+                       dev->stats.rx_dropped++;
                        return -1;
                }
                ud = node->ud;
@@ -1099,9 +1093,9 @@ static int ether1394_data_handler(struct net_device *dev, int srcid, int destid,
                 * high level network layer. */
 
                skb = dev_alloc_skb(len + dev->hard_header_len + 15);
-               if (!skb) {
-                       HPSB_PRINT (KERN_ERR, "ether1394 rx: low on mem\n");
-                       priv->stats.rx_dropped++;
+               if (unlikely(!skb)) {
+                       ETH1394_PRINT_G(KERN_ERR, "Out of memory\n");
+                       dev->stats.rx_dropped++;
                        return -1;
                }
                skb_reserve(skb, (dev->hard_header_len + 15) & ~15);
@@ -1156,8 +1150,6 @@ static int ether1394_data_handler(struct net_device *dev, int srcid, int destid,
                        pdg->sz++;
                        lh = find_partial_datagram(pdgl, dgl);
                } else {
-                       struct partial_datagram *pd;
-
                        pd = list_entry(lh, struct partial_datagram, list);
 
                        if (fragment_overlap(&pd->frag_info, fg_off, fg_len)) {
@@ -1222,28 +1214,22 @@ static int ether1394_data_handler(struct net_device *dev, int srcid, int destid,
        spin_lock_irqsave(&priv->lock, flags);
 
        if (!skb->protocol) {
-               priv->stats.rx_errors++;
-               priv->stats.rx_dropped++;
+               dev->stats.rx_errors++;
+               dev->stats.rx_dropped++;
                dev_kfree_skb_any(skb);
-               goto bad_proto;
-       }
-
-       if (netif_rx(skb) == NET_RX_DROP) {
-               priv->stats.rx_errors++;
-               priv->stats.rx_dropped++;
-               goto bad_proto;
+       } else if (netif_rx(skb) == NET_RX_DROP) {
+               dev->stats.rx_errors++;
+               dev->stats.rx_dropped++;
+       } else {
+               dev->stats.rx_packets++;
+               dev->stats.rx_bytes += skb->len;
        }
 
-       /* Statistics */
-       priv->stats.rx_packets++;
-       priv->stats.rx_bytes += skb->len;
+       spin_unlock_irqrestore(&priv->lock, flags);
 
 bad_proto:
        if (netif_queue_stopped(dev))
                netif_wake_queue(dev);
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       dev->last_rx = jiffies;
 
        return 0;
 }
@@ -1254,9 +1240,9 @@ static int ether1394_write(struct hpsb_host *host, int srcid, int destid,
        struct eth1394_host_info *hi;
 
        hi = hpsb_get_hostinfo(&eth1394_highlevel, host);
-       if (hi == NULL) {
-               ETH1394_PRINT_G(KERN_ERR, "Could not find net device for host %s\n",
-                               host->driver->name);
+       if (unlikely(!hi)) {
+               ETH1394_PRINT_G(KERN_ERR, "No net device at fw-host%d\n",
+                               host->id);
                return RCODE_ADDRESS_ERROR;
        }
 
@@ -1268,7 +1254,7 @@ static int ether1394_write(struct hpsb_host *host, int srcid, int destid,
 
 static void ether1394_iso(struct hpsb_iso *iso)
 {
-       quadlet_t *data;
+       __be32 *data;
        char *buf;
        struct eth1394_host_info *hi;
        struct net_device *dev;
@@ -1280,9 +1266,9 @@ static void ether1394_iso(struct hpsb_iso *iso)
        int nready;
 
        hi = hpsb_get_hostinfo(&eth1394_highlevel, iso->host);
-       if (hi == NULL) {
-               ETH1394_PRINT_G(KERN_ERR, "Could not find net device for host %s\n",
-                               iso->host->driver->name);
+       if (unlikely(!hi)) {
+               ETH1394_PRINT_G(KERN_ERR, "No net device at fw-host%d\n",
+                               iso->host->id);
                return;
        }
 
@@ -1292,7 +1278,7 @@ static void ether1394_iso(struct hpsb_iso *iso)
        for (i = 0; i < nready; i++) {
                struct hpsb_iso_packet_info *info =
                        &iso->infos[(iso->first_packet + i) % iso->buf_packets];
-               data = (quadlet_t *)(iso->data_buf.kvirt + info->offset);
+               data = (__be32 *)(iso->data_buf.kvirt + info->offset);
 
                /* skip over GASP header */
                buf = (char *)data + 8;
@@ -1370,7 +1356,7 @@ static unsigned int ether1394_encapsulate_prep(unsigned int max_payload,
                hdr->ff.dgl = dgl;
                adj_max_payload = max_payload - hdr_type_len[ETH1394_HDR_LF_FF];
        }
-       return (dg_size + adj_max_payload - 1) / adj_max_payload;
+       return DIV_ROUND_UP(dg_size, adj_max_payload);
 }
 
 static unsigned int ether1394_encapsulate(struct sk_buff *skb,
@@ -1432,23 +1418,17 @@ static int ether1394_prep_write_packet(struct hpsb_packet *p,
                                       u64 addr, void *data, int tx_len)
 {
        p->node_id = node;
-       p->data = NULL;
 
-       p->tcode = TCODE_WRITEB;
-       p->header[1] = host->node_id << 16 | addr >> 32;
-       p->header[2] = addr & 0xffffffff;
+       if (hpsb_get_tlabel(p))
+               return -EAGAIN;
 
+       p->tcode = TCODE_WRITEB;
        p->header_size = 16;
        p->expect_response = 1;
-
-       if (hpsb_get_tlabel(p)) {
-               ETH1394_PRINT_G(KERN_ERR, "No more tlabels left while sending "
-                               "to node " NODE_BUS_FMT "\n", NODE_BUS_ARGS(host, node));
-               return -1;
-       }
        p->header[0] =
                p->node_id << 16 | p->tlabel << 10 | 1 << 8 | TCODE_WRITEB << 4;
-
+       p->header[1] = host->node_id << 16 | addr >> 32;
+       p->header[2] = addr & 0xffffffff;
        p->header[3] = tx_len << 16;
        p->data_size = (tx_len + 3) & ~3;
        p->data = data;
@@ -1472,11 +1452,10 @@ static void ether1394_prep_gasp_packet(struct hpsb_packet *p,
        p->data[1] = cpu_to_be32(ETHER1394_GASP_SPECIFIER_ID_LO << 24 |
                                 ETHER1394_GASP_VERSION);
 
-       /* Setting the node id to ALL_NODES (not LOCAL_BUS | ALL_NODES)
-        * prevents hpsb_send_packet() from setting the speed to an arbitrary
-        * value based on packet->node_id if packet->node_id is not set. */
-       p->node_id = ALL_NODES;
        p->speed_code = priv->bc_sspd;
+
+       /* prevent hpsb_send_packet() from overriding our speed code */
+       p->node_id = LOCAL_BUS | ALL_NODES;
 }
 
 static void ether1394_free_packet(struct hpsb_packet *packet)
@@ -1495,7 +1474,7 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len)
 
        packet = ether1394_alloc_common_packet(priv->host);
        if (!packet)
-               return -1;
+               return -ENOMEM;
 
        if (ptask->tx_type == ETH1394_GASP) {
                int length = tx_len + 2 * sizeof(quadlet_t);
@@ -1506,7 +1485,7 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len)
                                               ptask->addr, ptask->skb->data,
                                               tx_len)) {
                hpsb_free_packet(packet);
-               return -1;
+               return -EAGAIN;
        }
 
        ptask->packet = packet;
@@ -1515,7 +1494,7 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len)
 
        if (hpsb_send_packet(packet) < 0) {
                ether1394_free_packet(packet);
-               return -1;
+               return -EIO;
        }
 
        return 0;
@@ -1525,17 +1504,18 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len)
 static void ether1394_dg_complete(struct packet_task *ptask, int fail)
 {
        struct sk_buff *skb = ptask->skb;
-       struct eth1394_priv *priv = netdev_priv(skb->dev);
+       struct net_device *dev = skb->dev;
+       struct eth1394_priv *priv = netdev_priv(dev);
        unsigned long flags;
 
        /* Statistics */
        spin_lock_irqsave(&priv->lock, flags);
        if (fail) {
-               priv->stats.tx_dropped++;
-               priv->stats.tx_errors++;
+               dev->stats.tx_dropped++;
+               dev->stats.tx_errors++;
        } else {
-               priv->stats.tx_bytes += skb->len;
-               priv->stats.tx_packets++;
+               dev->stats.tx_bytes += skb->len;
+               dev->stats.tx_packets++;
        }
        spin_unlock_irqrestore(&priv->lock, flags);
 
@@ -1558,13 +1538,18 @@ static void ether1394_complete_cb(void *__ptask)
 
        ptask->outstanding_pkts--;
        if (ptask->outstanding_pkts > 0 && !fail) {
-               int tx_len;
+               int tx_len, err;
 
                /* Add the encapsulation header to the fragment */
                tx_len = ether1394_encapsulate(ptask->skb, ptask->max_payload,
                                               &ptask->hdr);
-               if (ether1394_send_packet(ptask, tx_len))
+               err = ether1394_send_packet(ptask, tx_len);
+               if (err) {
+                       if (err == -EAGAIN)
+                               ETH1394_PRINT_G(KERN_ERR, "Out of tlabels\n");
+
                        ether1394_dg_complete(ptask, 1);
+               }
        } else {
                ether1394_dg_complete(ptask, fail);
        }
@@ -1573,14 +1558,12 @@ static void ether1394_complete_cb(void *__ptask)
 /* Transmit a packet (called by kernel) */
 static int ether1394_tx(struct sk_buff *skb, struct net_device *dev)
 {
-       gfp_t kmflags = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
-       struct eth1394hdr *eth;
+       struct eth1394hdr hdr_buf;
        struct eth1394_priv *priv = netdev_priv(dev);
        __be16 proto;
        unsigned long flags;
        nodeid_t dest_node;
        eth1394_tx_type tx_type;
-       int ret = 0;
        unsigned int tx_len;
        unsigned int max_payload;
        u16 dg_size;
@@ -1589,38 +1572,33 @@ static int ether1394_tx(struct sk_buff *skb, struct net_device *dev)
        struct eth1394_node_ref *node;
        struct eth1394_node_info *node_info = NULL;
 
-       ptask = kmem_cache_alloc(packet_task_cache, kmflags);
-       if (ptask == NULL) {
-               ret = -ENOMEM;
+       ptask = kmem_cache_alloc(packet_task_cache, GFP_ATOMIC);
+       if (ptask == NULL)
                goto fail;
-       }
 
        /* XXX Ignore this for now. Noticed that when MacOSX is the IRM,
         * it does not set our validity bit. We need to compensate for
         * that somewhere else, but not in eth1394. */
 #if 0
-       if ((priv->host->csr.broadcast_channel & 0xc0000000) != 0xc0000000) {
-               ret = -EAGAIN;
+       if ((priv->host->csr.broadcast_channel & 0xc0000000) != 0xc0000000)
                goto fail;
-       }
 #endif
 
-       skb = skb_share_check(skb, kmflags);
-       if (!skb) {
-               ret = -ENOMEM;
+       skb = skb_share_check(skb, GFP_ATOMIC);
+       if (!skb)
                goto fail;
-       }
 
-       /* Get rid of the fake eth1394 header, but save a pointer */
-       eth = (struct eth1394hdr *)skb->data;
+       /* Get rid of the fake eth1394 header, but first make a copy.
+        * We might need to rebuild the header on tx failure. */
+       memcpy(&hdr_buf, skb->data, sizeof(hdr_buf));
        skb_pull(skb, ETH1394_HLEN);
 
-       proto = eth->h_proto;
+       proto = hdr_buf.h_proto;
        dg_size = skb->len;
 
        /* Set the transmission type for the packet.  ARP packets and IP
         * broadcast packets are sent via GASP. */
-       if (memcmp(eth->h_dest, dev->broadcast, ETH1394_ALEN) == 0 ||
+       if (memcmp(hdr_buf.h_dest, dev->broadcast, ETH1394_ALEN) == 0 ||
            proto == htons(ETH_P_ARP) ||
            (proto == htons(ETH_P_IP) &&
             IN_MULTICAST(ntohl(ip_hdr(skb)->daddr)))) {
@@ -1632,20 +1610,17 @@ static int ether1394_tx(struct sk_buff *skb, struct net_device *dev)
                if (max_payload < dg_size + hdr_type_len[ETH1394_HDR_LF_UF])
                        priv->bc_dgl++;
        } else {
-               __be64 guid = get_unaligned((u64 *)eth->h_dest);
+               __be64 guid = get_unaligned((__be64 *)hdr_buf.h_dest);
 
                node = eth1394_find_node_guid(&priv->ip_node_list,
                                              be64_to_cpu(guid));
-               if (!node) {
-                       ret = -EAGAIN;
+               if (!node)
                        goto fail;
-               }
+
                node_info =
                    (struct eth1394_node_info *)node->ud->device.driver_data;
-               if (node_info->fifo == CSR1212_INVALID_ADDR_SPACE) {
-                       ret = -EAGAIN;
+               if (node_info->fifo == CSR1212_INVALID_ADDR_SPACE)
                        goto fail;
-               }
 
                dest_node = node->ud->ne->nodeid;
                max_payload = node_info->maxpayload;
@@ -1688,11 +1663,27 @@ static int ether1394_tx(struct sk_buff *skb, struct net_device *dev)
        /* Add the encapsulation header to the fragment */
        tx_len = ether1394_encapsulate(skb, max_payload, &ptask->hdr);
        dev->trans_start = jiffies;
-       if (ether1394_send_packet(ptask, tx_len))
-               goto fail;
+       if (ether1394_send_packet(ptask, tx_len)) {
+               if (dest_node == (LOCAL_BUS | ALL_NODES))
+                       goto fail;
 
-       netif_wake_queue(dev);
-       return 0;
+               /* At this point we want to restore the packet.  When we return
+                * here with NETDEV_TX_BUSY we will get another entrance in this
+                * routine with the same skb and we need it to look the same.
+                * So we pull 4 more bytes, then build the header again. */
+               skb_pull(skb, 4);
+               ether1394_header(skb, dev, ntohs(hdr_buf.h_proto),
+                                hdr_buf.h_dest, NULL, 0);
+
+               /* Most failures of ether1394_send_packet are recoverable. */
+               netif_stop_queue(dev);
+               priv->wake_node = dest_node;
+               schedule_work(&priv->wake);
+               kmem_cache_free(packet_task_cache, ptask);
+               return NETDEV_TX_BUSY;
+       }
+
+       return NETDEV_TX_OK;
 fail:
        if (ptask)
                kmem_cache_free(packet_task_cache, ptask);
@@ -1701,14 +1692,19 @@ fail:
                dev_kfree_skb(skb);
 
        spin_lock_irqsave(&priv->lock, flags);
-       priv->stats.tx_dropped++;
-       priv->stats.tx_errors++;
+       dev->stats.tx_dropped++;
+       dev->stats.tx_errors++;
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       if (netif_queue_stopped(dev))
-               netif_wake_queue(dev);
-
-       return 0;  /* returning non-zero causes serious problems */
+       /*
+        * FIXME: According to a patch from 2003-02-26, "returning non-zero
+        * causes serious problems" here, allegedly.  Before that patch,
+        * -ERRNO was returned which is not appropriate under Linux 2.6.
+        * Perhaps more needs to be done?  Stop the queue in serious
+        * conditions and restart it elsewhere?
+        */
+       /* return NETDEV_TX_BUSY; */
+       return NETDEV_TX_OK;
 }
 
 static void ether1394_get_drvinfo(struct net_device *dev,
@@ -1722,17 +1718,26 @@ static struct ethtool_ops ethtool_ops = {
        .get_drvinfo = ether1394_get_drvinfo
 };
 
-static int __init ether1394_init_module (void)
+static int __init ether1394_init_module(void)
 {
+       int err;
+
        packet_task_cache = kmem_cache_create("packet_task",
                                              sizeof(struct packet_task),
-                                             0, 0, NULL, NULL);
+                                             0, 0, NULL);
+       if (!packet_task_cache)
+               return -ENOMEM;
 
        hpsb_register_highlevel(&eth1394_highlevel);
-       return hpsb_register_protocol(&eth1394_proto_driver);
+       err = hpsb_register_protocol(&eth1394_proto_driver);
+       if (err) {
+               hpsb_unregister_highlevel(&eth1394_highlevel);
+               kmem_cache_destroy(packet_task_cache);
+       }
+       return err;
 }
 
-static void __exit ether1394_exit_module (void)
+static void __exit ether1394_exit_module(void)
 {
        hpsb_unregister_protocol(&eth1394_proto_driver);
        hpsb_unregister_highlevel(&eth1394_highlevel);