diff options
Diffstat (limited to 'drivers/ieee1394/eth1394.c')
-rw-r--r-- | drivers/ieee1394/eth1394.c | 802 |
1 files changed, 359 insertions, 443 deletions
diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c index 03e44b337eb..2296d43a241 100644 --- a/drivers/ieee1394/eth1394.c +++ b/drivers/ieee1394/eth1394.c @@ -1,5 +1,5 @@ /* - * eth1394.c -- Ethernet driver for Linux IEEE-1394 Subsystem + * eth1394.c -- IPv4 driver for Linux IEEE-1394 Subsystem * * Copyright (C) 2001-2003 Ben Collins <bcollins@debian.org> * 2000 Bonin Franck <boninf@free.fr> @@ -22,10 +22,9 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* This driver intends to support RFC 2734, which describes a method for - * transporting IPv4 datagrams over IEEE-1394 serial busses. This driver - * will ultimately support that method, but currently falls short in - * several areas. +/* + * This driver intends to support RFC 2734, which describes a method for + * transporting IPv4 datagrams over IEEE-1394 serial busses. * * TODO: * RFC 2734 related: @@ -40,7 +39,6 @@ * - Consider garbage collecting old partial datagrams after X amount of time */ - #include <linux/module.h> #include <linux/kernel.h> @@ -52,7 +50,6 @@ #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> @@ -84,10 +81,6 @@ #define ETH1394_PRINT(level, dev_name, fmt, args...) \ printk(level "%s: %s: " fmt, driver_name, dev_name, ## args) -#define DEBUG(fmt, args...) \ - printk(KERN_ERR "%s:%s[%d]: " fmt "\n", driver_name, __FUNCTION__, __LINE__, ## args) -#define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__) - struct fragment_info { struct list_head list; int offset; @@ -105,9 +98,9 @@ struct partial_datagram { }; struct pdg_list { - struct list_head list; /* partial datagram list per node */ - unsigned int sz; /* partial datagram list size per node */ - spinlock_t lock; /* partial datagram lock */ + struct list_head list; /* partial datagram list per node */ + unsigned int sz; /* partial datagram list size per node */ + spinlock_t lock; /* partial datagram lock */ }; struct eth1394_host_info { @@ -121,16 +114,14 @@ struct eth1394_node_ref { }; struct eth1394_node_info { - u16 maxpayload; /* Max payload */ - u8 sspd; /* Max speed */ - u64 fifo; /* FIFO address */ - struct pdg_list pdg; /* partial RX datagram lists */ - int dgl; /* Outgoing datagram label */ + u16 maxpayload; /* max payload */ + u8 sspd; /* max speed */ + u64 fifo; /* FIFO address */ + struct pdg_list pdg; /* partial RX datagram lists */ + int dgl; /* outgoing datagram label */ }; -/* Our ieee1394 highlevel driver */ -#define ETH1394_DRIVER_NAME "eth1394" -static const char driver_name[] = ETH1394_DRIVER_NAME; +static const char driver_name[] = "eth1394"; static struct kmem_cache *packet_task_cache; @@ -138,18 +129,12 @@ static struct hpsb_highlevel eth1394_highlevel; /* Use common.lf to determine header len */ static const int hdr_type_len[] = { - sizeof (struct eth1394_uf_hdr), - sizeof (struct eth1394_ff_hdr), - sizeof (struct eth1394_sf_hdr), - sizeof (struct eth1394_sf_hdr) + sizeof(struct eth1394_uf_hdr), + sizeof(struct eth1394_ff_hdr), + sizeof(struct eth1394_sf_hdr), + sizeof(struct eth1394_sf_hdr) }; -/* Change this to IEEE1394_SPEED_S100 to make testing easier */ -#define ETH1394_SPEED_DEF IEEE1394_SPEED_MAX - -/* 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 @@ -159,7 +144,8 @@ MODULE_AUTHOR("Ben Collins (bcollins@debian.org)"); MODULE_DESCRIPTION("IEEE 1394 IPv4 Driver (IPv4-over-1394 as per RFC 2734)"); MODULE_LICENSE("GPL"); -/* The max_partial_datagrams parameter is the maximum number of fragmented +/* + * The max_partial_datagrams parameter is the maximum number of fragmented * datagrams per node that eth1394 will keep in memory. Providing an upper * bound allows us to limit the amount of memory that partial datagrams * consume in the event that some partial datagrams are never completed. @@ -179,10 +165,7 @@ 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 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); - -static void purge_partial_datagram(struct list_head *old); + unsigned char *haddr); static int ether1394_tx(struct sk_buff *skb, struct net_device *dev); static void ether1394_iso(struct hpsb_iso *iso); @@ -190,9 +173,9 @@ static struct ethtool_ops ethtool_ops; static int ether1394_write(struct hpsb_host *host, int srcid, int destid, quadlet_t *data, u64 addr, size_t len, u16 flags); -static void ether1394_add_host (struct hpsb_host *host); -static void ether1394_remove_host (struct hpsb_host *host); -static void ether1394_host_reset (struct hpsb_host *host); +static void ether1394_add_host(struct hpsb_host *host); +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 = { @@ -207,89 +190,107 @@ static struct hpsb_highlevel eth1394_highlevel = { .host_reset = ether1394_host_reset, }; +static int ether1394_recv_init(struct eth1394_priv *priv) +{ + unsigned int iso_buf_size; + + /* FIXME: rawiso limits us to PAGE_SIZE */ + iso_buf_size = min((unsigned int)PAGE_SIZE, + 2 * (1U << (priv->host->csr.max_rec + 1))); + + priv->iso = hpsb_iso_recv_init(priv->host, + ETHER1394_GASP_BUFFERS * iso_buf_size, + ETHER1394_GASP_BUFFERS, + priv->broadcast_channel, + HPSB_ISO_DMA_PACKET_PER_BUFFER, + 1, ether1394_iso); + if (priv->iso == NULL) { + ETH1394_PRINT_G(KERN_ERR, "Failed to allocate IR context\n"); + priv->bc_state = ETHER1394_BC_ERROR; + return -EAGAIN; + } + + if (hpsb_iso_recv_start(priv->iso, -1, (1 << 3), -1) < 0) + priv->bc_state = ETHER1394_BC_STOPPED; + else + priv->bc_state = ETHER1394_BC_RUNNING; + return 0; +} /* This is called after an "ifup" */ -static int ether1394_open (struct net_device *dev) +static int ether1394_open(struct net_device *dev) { struct eth1394_priv *priv = netdev_priv(dev); - int ret = 0; + int ret; - /* Something bad happened, don't even try */ if (priv->bc_state == ETHER1394_BC_ERROR) { - /* we'll try again */ - priv->iso = hpsb_iso_recv_init(priv->host, - ETHER1394_ISO_BUF_SIZE, - ETHER1394_GASP_BUFFERS, - priv->broadcast_channel, - 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"); - priv->bc_state = ETHER1394_BC_ERROR; - ret = -EAGAIN; - } else { - if (hpsb_iso_recv_start(priv->iso, -1, (1 << 3), -1) < 0) - priv->bc_state = ETHER1394_BC_STOPPED; - else - priv->bc_state = ETHER1394_BC_RUNNING; - } + ret = ether1394_recv_init(priv); + if (ret) + return ret; } - - if (ret) - return ret; - - netif_start_queue (dev); + netif_start_queue(dev); return 0; } /* This is called after an "ifdown" */ -static int ether1394_stop (struct net_device *dev) +static int ether1394_stop(struct net_device *dev) { - netif_stop_queue (dev); + netif_stop_queue(dev); return 0; } /* Return statistics to the caller */ -static struct net_device_stats *ether1394_stats (struct net_device *dev) +static struct net_device_stats *ether1394_stats(struct net_device *dev) { return &(((struct eth1394_priv *)netdev_priv(dev))->stats); } -/* 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) +/* 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) { - ETH1394_PRINT (KERN_ERR, dev->name, "Timeout, resetting host %s\n", - ((struct eth1394_priv *)netdev_priv(dev))->host->driver->name); + struct hpsb_host *host = + ((struct eth1394_priv *)netdev_priv(dev))->host; - highlevel_host_reset (((struct eth1394_priv *)netdev_priv(dev))->host); + ETH1394_PRINT(KERN_ERR, dev->name, "Timeout, resetting host\n"); + ether1394_host_reset(host); +} - netif_wake_queue (dev); +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) { - struct eth1394_priv *priv = netdev_priv(dev); + int max_mtu; - if ((new_mtu < 68) || - (new_mtu > min(ETH1394_DATA_LEN, - (int)((1 << (priv->host->csr.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; } static void purge_partial_datagram(struct list_head *old) { - struct partial_datagram *pd = list_entry(old, struct partial_datagram, list); + struct partial_datagram *pd; struct list_head *lh, *n; + struct fragment_info *fi; + + pd = list_entry(old, struct partial_datagram, list); list_for_each_safe(lh, n, &pd->frag_info) { - struct fragment_info *fi = list_entry(lh, struct fragment_info, list); + fi = list_entry(lh, struct fragment_info, list); list_del(lh); kfree(fi); } @@ -330,35 +331,26 @@ static struct eth1394_node_ref *eth1394_find_node_nodeid(struct list_head *inl, nodeid_t nodeid) { struct eth1394_node_ref *node; - list_for_each_entry(node, inl, list) { + + list_for_each_entry(node, inl, list) if (node->ud->ne->nodeid == nodeid) return node; - } 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(ð1394_highlevel, ud->ne->host); - if (!hi) - return -ENOENT; - - new_node = kmalloc(sizeof(*new_node), - in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); + new_node = kmalloc(sizeof(*new_node), GFP_KERNEL); if (!new_node) return -ENOMEM; - node_info = kmalloc(sizeof(*node_info), - in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); + node_info = kmalloc(sizeof(*node_info), GFP_KERNEL); if (!node_info) { kfree(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(ð1394_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; @@ -396,24 +400,23 @@ static int eth1394_remove(struct device *dev) priv = netdev_priv(hi->dev); old_node = eth1394_find_node(&priv->ip_node_list, ud); + if (!old_node) + return 0; - if (old_node) { - list_del(&old_node->list); - kfree(old_node); + list_del(&old_node->list); + kfree(old_node); - node_info = (struct eth1394_node_info*)ud->device.driver_data; + node_info = (struct eth1394_node_info*)ud->device.driver_data; - spin_lock_irqsave(&node_info->pdg.lock, flags); - /* The partial datagram list should be empty, but we'll just - * make sure anyway... */ - list_for_each_safe(lh, n, &node_info->pdg.list) { - purge_partial_datagram(lh); - } - spin_unlock_irqrestore(&node_info->pdg.lock, flags); + spin_lock_irqsave(&node_info->pdg.lock, flags); + /* The partial datagram list should be empty, but we'll just + * make sure anyway... */ + list_for_each_safe(lh, n, &node_info->pdg.list) + purge_partial_datagram(lh); + spin_unlock_irqrestore(&node_info->pdg.lock, flags); - kfree(node_info); - ud->device.driver_data = NULL; - } + kfree(node_info); + ud->device.driver_data = NULL; return 0; } @@ -422,44 +425,19 @@ 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(ð1394_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; - if (!node) { - node = kmalloc(sizeof(*node), - in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); - if (!node) - return -ENOMEM; - - node_info = kmalloc(sizeof(*node_info), - in_interrupt() ? GFP_ATOMIC : 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[] = { { .match_flags = (IEEE1394_MATCH_SPECIFIER_ID | @@ -473,7 +451,7 @@ static struct ieee1394_device_id eth1394_id_table[] = { MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table); static struct hpsb_protocol_driver eth1394_proto_driver = { - .name = ETH1394_DRIVER_NAME, + .name = driver_name, .id_table = eth1394_id_table, .update = eth1394_update, .driver = { @@ -482,47 +460,50 @@ static struct hpsb_protocol_driver eth1394_proto_driver = { }, }; - -static void ether1394_reset_priv (struct net_device *dev, int set_mtu) +static void ether1394_reset_priv(struct net_device *dev, int set_mtu) { unsigned long flags; int i; struct eth1394_priv *priv = netdev_priv(dev); struct hpsb_host *host = priv->host; - u64 guid = get_unaligned((u64*)&(host->csr.rom->bus_info_data[3])); - u16 maxpayload = 1 << (host->csr.max_rec + 1); + u64 guid = get_unaligned((u64 *)&(host->csr.rom->bus_info_data[3])); int max_speed = IEEE1394_SPEED_MAX; - spin_lock_irqsave (&priv->lock, flags); + 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 maxpayload as the default mtu */ if (set_mtu) { - dev->mtu = min(ETH1394_DATA_LEN, - (int)(maxpayload - - (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)); memset(dev->broadcast, 0xff, sizeof(u64)); } - spin_unlock_irqrestore (&priv->lock, flags); + spin_unlock_irqrestore(&priv->lock, flags); } -/* This function is called right before register_netdev */ -static void ether1394_init_dev (struct net_device *dev) +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; @@ -535,10 +516,9 @@ static void ether1394_init_dev (struct net_device *dev) 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; + SET_ETHTOOL_OPS(dev, ðtool_ops); - /* Some constants */ dev->watchdog_timeo = ETHER1394_TIMEOUT; dev->flags = IFF_BROADCAST | IFF_MULTICAST; dev->features = NETIF_F_HIGHDMA; @@ -546,7 +526,8 @@ 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; } /* @@ -554,34 +535,33 @@ static void ether1394_init_dev (struct net_device *dev) * when the module is installed. This is where we add all of our ethernet * devices. One for each host. */ -static void ether1394_add_host (struct hpsb_host *host) +static void ether1394_add_host(struct hpsb_host *host) { struct eth1394_host_info *hi = NULL; struct net_device *dev = NULL; struct eth1394_priv *priv; u64 fifo_addr; - if (!(host->config_roms & HPSB_CONFIG_ROM_ENTRY_IP1394)) + if (hpsb_config_rom_ip1394_add(host) != 0) { + ETH1394_PRINT_G(KERN_ERR, "Can't add IP-over-1394 ROM entry\n"); return; + } fifo_addr = hpsb_allocate_and_register_addrspace( ð1394_highlevel, host, &addr_ops, ETHER1394_REGION_ADDR_LEN, ETHER1394_REGION_ADDR_LEN, CSR1212_INVALID_ADDR_SPACE, CSR1212_INVALID_ADDR_SPACE); - if (fifo_addr == CSR1212_INVALID_ADDR_SPACE) - goto out; - - /* 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)); + if (fifo_addr == CSR1212_INVALID_ADDR_SPACE) { + ETH1394_PRINT_G(KERN_ERR, "Cannot register CSR space\n"); + hpsb_config_rom_ip1394_remove(host); + return; + } + 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 @@ -590,31 +570,26 @@ static void ether1394_add_host (struct hpsb_host *host) #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; hi = hpsb_create_hostinfo(ð1394_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; @@ -623,61 +598,37 @@ 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; - priv->iso = hpsb_iso_recv_init(host, - ETHER1394_ISO_BUF_SIZE, - ETHER1394_GASP_BUFFERS, - priv->broadcast_channel, - 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"); - priv->bc_state = ETHER1394_BC_ERROR; - } else { - if (hpsb_iso_recv_start(priv->iso, -1, (1 << 3), -1) < 0) - priv->bc_state = ETHER1394_BC_STOPPED; - else - priv->bc_state = ETHER1394_BC_RUNNING; - } - + ether1394_recv_init(priv); return; - out: - if (dev != NULL) + if (dev) free_netdev(dev); if (hi) hpsb_destroy_hostinfo(ð1394_highlevel, host); - - return; + hpsb_unregister_addrspace(ð1394_highlevel, host, fifo_addr); + hpsb_config_rom_ip1394_remove(host); } /* Remove a card from our list */ -static void ether1394_remove_host (struct hpsb_host *host) +static void ether1394_remove_host(struct hpsb_host *host) { struct eth1394_host_info *hi; + struct eth1394_priv *priv; hi = hpsb_get_hostinfo(ð1394_highlevel, host); - if (hi != NULL) { - struct eth1394_priv *priv = netdev_priv(hi->dev); - - hpsb_unregister_addrspace(ð1394_highlevel, host, - priv->local_fifo); - - if (priv->iso != NULL) - hpsb_iso_shutdown(priv->iso); - - if (hi->dev) { - unregister_netdev (hi->dev); - free_netdev(hi->dev); - } - } - - return; + if (!hi) + return; + priv = netdev_priv(hi->dev); + hpsb_unregister_addrspace(ð1394_highlevel, host, priv->local_fifo); + hpsb_config_rom_ip1394_remove(host); + if (priv->iso) + hpsb_iso_shutdown(priv->iso); + unregister_netdev(hi->dev); + free_netdev(hi->dev); } -/* A reset has just arisen */ -static void ether1394_host_reset (struct hpsb_host *host) +/* A bus reset happened */ +static void ether1394_host_reset(struct hpsb_host *host) { struct eth1394_host_info *hi; struct eth1394_priv *priv; @@ -690,24 +641,23 @@ static void ether1394_host_reset (struct hpsb_host *host) hi = hpsb_get_hostinfo(ð1394_highlevel, host); /* This can happen for hosts that we don't use */ - if (hi == NULL) + if (!hi) return; dev = hi->dev; - priv = (struct eth1394_priv *)netdev_priv(dev); + priv = netdev_priv(dev); - /* Reset our private host data, but not our mtu */ - netif_stop_queue (dev); - ether1394_reset_priv (dev, 0); + /* Reset our private host data, but not our MTU */ + netif_stop_queue(dev); + ether1394_reset_priv(dev, 0); list_for_each_entry(node, &priv->ip_node_list, list) { - node_info = (struct eth1394_node_info*)node->ud->device.driver_data; + node_info = node->ud->device.driver_data; spin_lock_irqsave(&node_info->pdg.lock, flags); - list_for_each_safe(lh, n, &node_info->pdg.list) { + list_for_each_safe(lh, n, &node_info->pdg.list) purge_partial_datagram(lh); - } INIT_LIST_HEAD(&(node_info->pdg.list)); node_info->pdg.sz = 0; @@ -715,7 +665,7 @@ static void ether1394_host_reset (struct hpsb_host *host) spin_unlock_irqrestore(&node_info->pdg.lock, flags); } - netif_wake_queue (dev); + netif_wake_queue(dev); } /****************************************** @@ -723,7 +673,6 @@ static void ether1394_host_reset (struct hpsb_host *host) ******************************************/ /* These functions have been adapted from net/ethernet/eth.c */ - /* Create a fake MAC header for an arbitrary protocol layer. * saddr=NULL means use device source address * daddr=NULL means leave destination address (eg unresolved arp). */ @@ -731,25 +680,24 @@ static int ether1394_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { - struct eth1394hdr *eth = (struct eth1394hdr *)skb_push(skb, ETH1394_HLEN); + struct eth1394hdr *eth = + (struct eth1394hdr *)skb_push(skb, ETH1394_HLEN); eth->h_proto = htons(type); - if (dev->flags & (IFF_LOOPBACK|IFF_NOARP)) { + if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) { memset(eth->h_dest, 0, dev->addr_len); - return(dev->hard_header_len); + return dev->hard_header_len; } if (daddr) { - memcpy(eth->h_dest,daddr,dev->addr_len); + memcpy(eth->h_dest, daddr, dev->addr_len); return dev->hard_header_len; } return -dev->hard_header_len; - } - /* Rebuild the faked MAC header. This is called after an ARP * (or in future other address resolution) has completed on this * sk_buff. We now let ARP fill in the other fields. @@ -760,38 +708,30 @@ 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): - return arp_find((unsigned char*)ð->h_dest, skb); -#endif - default: - ETH1394_PRINT(KERN_DEBUG, dev->name, - "unable to resolve type %04x addresses.\n", - ntohs(eth->h_proto)); - break; - } + if (eth->h_proto == htons(ETH_P_IP)) + return arp_find((unsigned char *)ð->h_dest, skb); + 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) { struct net_device *dev = skb->dev; + memcpy(haddr, dev->dev_addr, ETH1394_ALEN); return ETH1394_ALEN; } - static int ether1394_header_cache(struct neighbour *neigh, struct hh_cache *hh) { unsigned short type = hh->hh_type; - struct eth1394hdr *eth = (struct eth1394hdr*)(((u8*)hh->hh_data) + - (16 - ETH1394_HLEN)); struct net_device *dev = neigh->dev; + struct eth1394hdr *eth = + (struct eth1394hdr *)((u8 *)hh->hh_data + 16 - ETH1394_HLEN); if (type == htons(ETH_P_802_3)) return -1; @@ -808,38 +748,25 @@ static void ether1394_header_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr) { - memcpy(((u8*)hh->hh_data) + (16 - ETH1394_HLEN), haddr, dev->addr_len); + 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 inline u16 ether1394_type_trans(struct sk_buff *skb, - struct net_device *dev) +static u16 ether1394_type_trans(struct sk_buff *skb, struct net_device *dev) { struct eth1394hdr *eth; unsigned char *rawp; - skb->mac.raw = skb->data; - skb_pull (skb, ETH1394_HLEN); + skb_reset_mac_header(skb); + skb_pull(skb, ETH1394_HLEN); eth = eth1394_hdr(skb); if (*eth->h_dest & 1) { - if (memcmp(eth->h_dest, dev->broadcast, dev->addr_len)==0) + if (memcmp(eth->h_dest, dev->broadcast, dev->addr_len) == 0) skb->pkt_type = PACKET_BROADCAST; #if 0 else @@ -848,47 +775,45 @@ static inline u16 ether1394_type_trans(struct sk_buff *skb, } else { if (memcmp(eth->h_dest, dev->dev_addr, dev->addr_len)) skb->pkt_type = PACKET_OTHERHOST; - } + } - if (ntohs (eth->h_proto) >= 1536) + if (ntohs(eth->h_proto) >= 1536) return eth->h_proto; rawp = skb->data; - if (*(unsigned short *)rawp == 0xFFFF) - return htons (ETH_P_802_3); + if (*(unsigned short *)rawp == 0xFFFF) + return htons(ETH_P_802_3); - return htons (ETH_P_802_2); + return htons(ETH_P_802_2); } /* Parse an encapsulated IP1394 header into an ethernet frame packet. * We also perform ARP translation here, if need be. */ -static inline u16 ether1394_parse_encap(struct sk_buff *skb, - struct net_device *dev, - nodeid_t srcid, nodeid_t destid, - u16 ether_type) +static u16 ether1394_parse_encap(struct sk_buff *skb, struct net_device *dev, + nodeid_t srcid, nodeid_t destid, + u16 ether_type) { struct eth1394_priv *priv = netdev_priv(dev); u64 dest_hw; unsigned short ret = 0; - /* Setup our hw addresses. We use these to build the - * ethernet header. */ + /* Setup our hw addresses. We use these to build the ethernet header. */ if (destid == (LOCAL_BUS | ALL_NODES)) dest_hw = ~0ULL; /* broadcast */ else - dest_hw = cpu_to_be64((((u64)priv->host->csr.guid_hi) << 32) | + dest_hw = cpu_to_be64((u64)priv->host->csr.guid_hi << 32 | priv->host->csr.guid_lo); /* If this is an ARP packet, convert it. First, we want to make * use of some of the fields, since they tell us a little bit * about the sending machine. */ if (ether_type == htons(ETH_P_ARP)) { - struct eth1394_arp *arp1394 = (struct eth1394_arp*)skb->data; + struct eth1394_arp *arp1394 = (struct eth1394_arp *)skb->data; struct arphdr *arp = (struct arphdr *)skb->data; unsigned char *arp_ptr = (unsigned char *)(arp + 1); u64 fifo_addr = (u64)ntohs(arp1394->fifo_hi) << 32 | - ntohl(arp1394->fifo_lo); + ntohl(arp1394->fifo_lo); u8 max_rec = min(priv->host->csr.max_rec, (u8)(arp1394->max_rec)); int sspd = arp1394->sspd; @@ -902,16 +827,17 @@ static inline u16 ether1394_parse_encap(struct sk_buff *skb, if (sspd > 5 || sspd < 0) sspd = 0; - maxpayload = min(eth1394_speedto_maxpayload[sspd], (u16)(1 << (max_rec + 1))); + maxpayload = min(eth1394_speedto_maxpayload[sspd], + (u16)(1 << (max_rec + 1))); guid = get_unaligned(&arp1394->s_uniq_id); node = eth1394_find_node_guid(&priv->ip_node_list, be64_to_cpu(guid)); - if (!node) { + if (!node) return 0; - } - node_info = (struct eth1394_node_info*)node->ud->device.driver_data; + node_info = + (struct eth1394_node_info *)node->ud->device.driver_data; /* Update our speed/payload/fifo_offset table */ node_info->maxpayload = maxpayload; @@ -930,7 +856,7 @@ static inline u16 ether1394_parse_encap(struct sk_buff *skb, arp->ar_hln = 8; arp_ptr += arp->ar_hln; /* skip over sender unique id */ - *(u32*)arp_ptr = arp1394->sip; /* move sender IP addr */ + *(u32 *)arp_ptr = arp1394->sip; /* move sender IP addr */ arp_ptr += arp->ar_pln; /* skip over sender IP addr */ if (arp->ar_op == htons(ARPOP_REQUEST)) @@ -947,65 +873,65 @@ static inline u16 ether1394_parse_encap(struct sk_buff *skb, return ret; } -static inline int fragment_overlap(struct list_head *frag_list, int offset, int len) +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; } -static inline struct list_head *find_partial_datagram(struct list_head *pdgl, int dgl) +static struct list_head *find_partial_datagram(struct list_head *pdgl, int dgl) { struct partial_datagram *pd; - list_for_each_entry(pd, pdgl, list) { + list_for_each_entry(pd, pdgl, list) if (pd->dgl == dgl) return &pd->list; - } + return NULL; } /* Assumes that new fragment does not overlap any existing fragments */ -static inline int new_fragment(struct list_head *frag_info, int offset, int len) +static int new_fragment(struct list_head *frag_info, int offset, int len) { struct list_head *lh; struct fragment_info *fi, *fi2, *new; list_for_each(lh, frag_info) { fi = list_entry(lh, struct fragment_info, list); - if ((fi->offset + fi->len) == offset) { + if (fi->offset + fi->len == offset) { /* The new fragment can be tacked on to the end */ fi->len += len; /* Did the new fragment plug a hole? */ fi2 = list_entry(lh->next, struct fragment_info, list); - if ((fi->offset + fi->len) == fi2->offset) { + if (fi->offset + fi->len == fi2->offset) { /* glue fragments together */ fi->len += fi2->len; list_del(lh->next); kfree(fi2); } return 0; - } else if ((offset + len) == fi->offset) { + } else if (offset + len == fi->offset) { /* The new fragment can be tacked on to the beginning */ fi->offset = offset; fi->len += len; /* Did the new fragment plug a hole? */ fi2 = list_entry(lh->prev, struct fragment_info, list); - if ((fi2->offset + fi2->len) == fi->offset) { + if (fi2->offset + fi2->len == fi->offset) { /* glue fragments together */ fi2->len += fi->len; list_del(lh); kfree(fi); } return 0; - } else if (offset > (fi->offset + fi->len)) { + } else if (offset > fi->offset + fi->len) { break; - } else if ((offset + len) < fi->offset) { + } else if (offset + len < fi->offset) { lh = lh->prev; break; } @@ -1019,14 +945,12 @@ static inline int new_fragment(struct list_head *frag_info, int offset, int len) new->len = len; list_add(&new->list, lh); - return 0; } -static inline int new_partial_datagram(struct net_device *dev, - struct list_head *pdgl, int dgl, - int dg_size, char *frag_buf, - int frag_off, int frag_len) +static int new_partial_datagram(struct net_device *dev, struct list_head *pdgl, + int dgl, int dg_size, char *frag_buf, + int frag_off, int frag_len) { struct partial_datagram *new; @@ -1059,33 +983,33 @@ static inline int new_partial_datagram(struct net_device *dev, memcpy(new->pbuf + frag_off, frag_buf, frag_len); list_add(&new->list, pdgl); - return 0; } -static inline int update_partial_datagram(struct list_head *pdgl, struct list_head *lh, - char *frag_buf, int frag_off, int frag_len) +static int update_partial_datagram(struct list_head *pdgl, struct list_head *lh, + char *frag_buf, int frag_off, int frag_len) { - struct partial_datagram *pd = list_entry(lh, struct partial_datagram, list); + struct partial_datagram *pd = + list_entry(lh, struct partial_datagram, list); - if (new_fragment(&pd->frag_info, frag_off, frag_len) < 0) { + if (new_fragment(&pd->frag_info, frag_off, frag_len) < 0) return -ENOMEM; - } memcpy(pd->pbuf + frag_off, frag_buf, frag_len); /* Move list entry to beginnig of list so that oldest partial * datagrams percolate to the end of the list */ list_move(lh, pdgl); - return 0; } -static inline int is_datagram_complete(struct list_head *lh, int dg_size) +static int is_datagram_complete(struct list_head *lh, int dg_size) { - struct partial_datagram *pd = list_entry(lh, struct partial_datagram, list); - struct fragment_info *fi = list_entry(pd->frag_info.next, - struct fragment_info, list); + struct partial_datagram *pd; + struct fragment_info *fi; + + pd = list_entry(lh, struct partial_datagram, list); + fi = list_entry(pd->frag_info.next, struct fragment_info, list); return (fi->len == dg_size); } @@ -1108,7 +1032,7 @@ 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)); @@ -1120,7 +1044,7 @@ static int ether1394_data_handler(struct net_device *dev, int srcid, int destid, priv->ud_list[NODEID_TO_NODE(srcid)] = ud; } - node_info = (struct eth1394_node_info*)ud->device.driver_data; + node_info = (struct eth1394_node_info *)ud->device.driver_data; /* First, did we receive a fragmented or unfragmented datagram? */ hdr->words.word1 = ntohs(hdr->words.word1); @@ -1133,13 +1057,14 @@ 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"); + if (unlikely(!skb)) { + ETH1394_PRINT_G(KERN_ERR, "Out of memory\n"); priv->stats.rx_dropped++; return -1; } skb_reserve(skb, (dev->hard_header_len + 15) & ~15); - memcpy(skb_put(skb, len - hdr_len), buf + hdr_len, len - hdr_len); + memcpy(skb_put(skb, len - hdr_len), buf + hdr_len, + len - hdr_len); ether_type = hdr->uf.ether_type; } else { /* A datagram fragment has been received, now the fun begins. */ @@ -1224,9 +1149,8 @@ static int ether1394_data_handler(struct net_device *dev, int srcid, int destid, pd = list_entry(lh, struct partial_datagram, list); - if (hdr->common.lf == ETH1394_HDR_LF_FF) { + if (hdr->common.lf == ETH1394_HDR_LF_FF) pd->ether_type = ether_type; - } if (is_datagram_complete(lh, dg_size)) { ether_type = pd->ether_type; @@ -1253,8 +1177,8 @@ static int ether1394_data_handler(struct net_device *dev, int srcid, int destid, skb->protocol = ether1394_parse_encap(skb, dev, srcid, destid, ether_type); - spin_lock_irqsave(&priv->lock, flags); + if (!skb->protocol) { priv->stats.rx_errors++; priv->stats.rx_dropped++; @@ -1288,9 +1212,9 @@ static int ether1394_write(struct hpsb_host *host, int srcid, int destid, struct eth1394_host_info *hi; hi = hpsb_get_hostinfo(ð1394_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; } @@ -1314,9 +1238,9 @@ static void ether1394_iso(struct hpsb_iso *iso) int nready; hi = hpsb_get_hostinfo(ð1394_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; } @@ -1326,20 +1250,20 @@ 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 = (quadlet_t *)(iso->data_buf.kvirt + info->offset); /* skip over GASP header */ buf = (char *)data + 8; len = info->len - 8; - specifier_id = (((be32_to_cpu(data[0]) & 0xffff) << 8) | - ((be32_to_cpu(data[1]) & 0xff000000) >> 24)); + specifier_id = (be32_to_cpu(data[0]) & 0xffff) << 8 | + (be32_to_cpu(data[1]) & 0xff000000) >> 24; source_id = be32_to_cpu(data[0]) >> 16; priv = netdev_priv(dev); - if (info->channel != (iso->host->csr.broadcast_channel & 0x3f) || - specifier_id != ETHER1394_GASP_SPECIFIER_ID) { + if (info->channel != (iso->host->csr.broadcast_channel & 0x3f) + || specifier_id != ETHER1394_GASP_SPECIFIER_ID) { /* This packet is not for us */ continue; } @@ -1367,35 +1291,31 @@ static void ether1394_iso(struct hpsb_iso *iso) * speed, and unicast FIFO address information between the sender_unique_id * and the IP addresses. */ -static inline void ether1394_arp_to_1394arp(struct sk_buff *skb, - struct net_device *dev) +static void ether1394_arp_to_1394arp(struct sk_buff *skb, + struct net_device *dev) { struct eth1394_priv *priv = netdev_priv(dev); - struct arphdr *arp = (struct arphdr *)skb->data; unsigned char *arp_ptr = (unsigned char *)(arp + 1); struct eth1394_arp *arp1394 = (struct eth1394_arp *)skb->data; - /* Believe it or not, all that need to happen is sender IP get moved - * and set hw_addr_len, max_rec, sspd, fifo_hi and fifo_lo. */ arp1394->hw_addr_len = 16; arp1394->sip = *(u32*)(arp_ptr + ETH1394_ALEN); arp1394->max_rec = priv->host->csr.max_rec; arp1394->sspd = priv->host->csr.lnk_spd; - arp1394->fifo_hi = htons (priv->local_fifo >> 32); - arp1394->fifo_lo = htonl (priv->local_fifo & ~0x0); - - return; + arp1394->fifo_hi = htons(priv->local_fifo >> 32); + arp1394->fifo_lo = htonl(priv->local_fifo & ~0x0); } /* We need to encapsulate the standard header with our own. We use the * ethernet header's proto for our own. */ -static inline unsigned int ether1394_encapsulate_prep(unsigned int max_payload, - __be16 proto, - union eth1394_hdr *hdr, - u16 dg_size, u16 dgl) +static unsigned int ether1394_encapsulate_prep(unsigned int max_payload, + __be16 proto, + union eth1394_hdr *hdr, + u16 dg_size, u16 dgl) { - unsigned int adj_max_payload = max_payload - hdr_type_len[ETH1394_HDR_LF_UF]; + unsigned int adj_max_payload = + max_payload - hdr_type_len[ETH1394_HDR_LF_UF]; /* Does it all fit in one packet? */ if (dg_size <= adj_max_payload) { @@ -1408,19 +1328,19 @@ static inline 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 (dg_size + adj_max_payload - 1) / adj_max_payload; } -static inline unsigned int ether1394_encapsulate(struct sk_buff *skb, - unsigned int max_payload, - union eth1394_hdr *hdr) +static unsigned int ether1394_encapsulate(struct sk_buff *skb, + unsigned int max_payload, + union eth1394_hdr *hdr) { union eth1394_hdr *bufhdr; int ftype = hdr->common.lf; int hdrsz = hdr_type_len[ftype]; unsigned int adj_max_payload = max_payload - hdrsz; - switch(ftype) { + switch (ftype) { case ETH1394_HDR_LF_UF: bufhdr = (union eth1394_hdr *)skb_push(skb, hdrsz); bufhdr->words.word1 = htons(hdr->words.word1); @@ -1449,11 +1369,10 @@ static inline unsigned int ether1394_encapsulate(struct sk_buff *skb, bufhdr->words.word3 = htons(hdr->words.word3); bufhdr->words.word4 = 0; } - return min(max_payload, skb->len); } -static inline struct hpsb_packet *ether1394_alloc_common_packet(struct hpsb_host *host) +static struct hpsb_packet *ether1394_alloc_common_packet(struct hpsb_host *host) { struct hpsb_packet *p; @@ -1466,61 +1385,57 @@ static inline struct hpsb_packet *ether1394_alloc_common_packet(struct hpsb_host return p; } -static inline int ether1394_prep_write_packet(struct hpsb_packet *p, - struct hpsb_host *host, - nodeid_t node, u64 addr, - void * data, int tx_len) +static int ether1394_prep_write_packet(struct hpsb_packet *p, + struct hpsb_host *host, nodeid_t node, + 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[1] = host->node_id << 16 | addr >> 32; p->header[2] = addr & 0xffffffff; 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)); + ETH1394_PRINT_G(KERN_ERR, "Out of tlabels\n"); return -1; } - p->header[0] = (p->node_id << 16) | (p->tlabel << 10) - | (1 << 8) | (TCODE_WRITEB << 4); + p->header[0] = + p->node_id << 16 | p->tlabel << 10 | 1 << 8 | TCODE_WRITEB << 4; p->header[3] = tx_len << 16; p->data_size = (tx_len + 3) & ~3; - p->data = (quadlet_t*)data; + p->data = data; return 0; } -static inline void ether1394_prep_gasp_packet(struct hpsb_packet *p, - struct eth1394_priv *priv, - struct sk_buff *skb, int length) +static void ether1394_prep_gasp_packet(struct hpsb_packet *p, + struct eth1394_priv *priv, + struct sk_buff *skb, int length) { p->header_size = 4; p->tcode = TCODE_STREAM_DATA; - p->header[0] = (length << 16) | (3 << 14) - | ((priv->broadcast_channel) << 8) - | (TCODE_STREAM_DATA << 4); + p->header[0] = length << 16 | 3 << 14 | priv->broadcast_channel << 8 | + TCODE_STREAM_DATA << 4; p->data_size = length; - p->data = ((quadlet_t*)skb->data) - 2; - p->data[0] = cpu_to_be32((priv->host->node_id << 16) | + p->data = (quadlet_t *)skb->data - 2; + p->data[0] = cpu_to_be32(priv->host->node_id << 16 | ETHER1394_GASP_SPECIFIER_ID_HI); - p->data[1] = cpu_to_be32((ETHER1394_GASP_SPECIFIER_ID_LO << 24) | + 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 inline void ether1394_free_packet(struct hpsb_packet *packet) +static void ether1394_free_packet(struct hpsb_packet *packet) { if (packet->tcode != TCODE_STREAM_DATA) hpsb_free_tlabel(packet); @@ -1539,7 +1454,7 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len) return -1; if (ptask->tx_type == ETH1394_GASP) { - int length = tx_len + (2 * sizeof(quadlet_t)); + int length = tx_len + 2 * sizeof(quadlet_t); ether1394_prep_gasp_packet(packet, priv, ptask->skb, length); } else if (ether1394_prep_write_packet(packet, priv->host, @@ -1562,13 +1477,11 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len) return 0; } - /* Task function to be run when a datagram transmission is completed */ -static inline void ether1394_dg_complete(struct packet_task *ptask, int fail) +static void ether1394_dg_complete(struct packet_task *ptask, int fail) { struct sk_buff *skb = ptask->skb; - struct net_device *dev = skb->dev; - struct eth1394_priv *priv = netdev_priv(dev); + struct eth1394_priv *priv = netdev_priv(skb->dev); unsigned long flags; /* Statistics */ @@ -1586,7 +1499,6 @@ static inline void ether1394_dg_complete(struct packet_task *ptask, int fail) kmem_cache_free(packet_task_cache, ptask); } - /* Callback for when a packet has been sent and the status of that packet is * known */ static void ether1394_complete_cb(void *__ptask) @@ -1614,19 +1526,15 @@ 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) +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 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; @@ -1635,29 +1543,24 @@ 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 - if ((skb = skb_share_check (skb, kmflags)) == NULL) { - 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; + eth = (struct eth1394hdr *)skb->data; skb_pull(skb, ETH1394_HLEN); proto = eth->h_proto; @@ -1668,11 +1571,11 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev) if (memcmp(eth->h_dest, dev->broadcast, ETH1394_ALEN) == 0 || proto == htons(ETH_P_ARP) || (proto == htons(ETH_P_IP) && - IN_MULTICAST(ntohl(skb->nh.iph->daddr)))) { + IN_MULTICAST(ntohl(ip_hdr(skb)->daddr)))) { tx_type = ETH1394_GASP; dest_node = LOCAL_BUS | ALL_NODES; max_payload = priv->bc_maxpayload - ETHER1394_GASP_OVERHEAD; - BUG_ON(max_payload < (512 - ETHER1394_GASP_OVERHEAD)); + BUG_ON(max_payload < 512 - ETHER1394_GASP_OVERHEAD); dgl = priv->bc_dgl; if (max_payload < dg_size + hdr_type_len[ETH1394_HDR_LF_UF]) priv->bc_dgl++; @@ -1681,19 +1584,17 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev) 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; + + node_info = + (struct eth1394_node_info *)node->ud->device.driver_data; + if (node_info->fifo == CSR1212_INVALID_ADDR_SPACE) goto fail; - } dest_node = node->ud->ne->nodeid; max_payload = node_info->maxpayload; - BUG_ON(max_payload < (512 - ETHER1394_GASP_OVERHEAD)); + BUG_ON(max_payload < 512 - ETHER1394_GASP_OVERHEAD); dgl = node_info->dgl; if (max_payload < dg_size + hdr_type_len[ETH1394_HDR_LF_UF]) @@ -1703,7 +1604,7 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev) /* If this is an ARP packet, convert it */ if (proto == htons(ETH_P_ARP)) - ether1394_arp_to_1394arp (skb, dev); + ether1394_arp_to_1394arp(skb, dev); ptask->hdr.words.word1 = 0; ptask->hdr.words.word2 = 0; @@ -1726,9 +1627,8 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev) ptask->tx_type = tx_type; ptask->max_payload = max_payload; - ptask->outstanding_pkts = ether1394_encapsulate_prep(max_payload, proto, - &ptask->hdr, dg_size, - dgl); + ptask->outstanding_pkts = ether1394_encapsulate_prep(max_payload, + proto, &ptask->hdr, dg_size, dgl); /* Add the encapsulation header to the fragment */ tx_len = ether1394_encapsulate(skb, max_payload, &ptask->hdr); @@ -1737,7 +1637,7 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev) goto fail; netif_wake_queue(dev); - return 0; + return NETDEV_TX_OK; fail: if (ptask) kmem_cache_free(packet_task_cache, ptask); @@ -1745,40 +1645,56 @@ fail: if (skb != NULL) dev_kfree_skb(skb); - spin_lock_irqsave (&priv->lock, flags); + spin_lock_irqsave(&priv->lock, flags); priv->stats.tx_dropped++; priv->stats.tx_errors++; - spin_unlock_irqrestore (&priv->lock, flags); + 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, struct ethtool_drvinfo *info) +static void ether1394_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { - strcpy (info->driver, driver_name); - /* FIXME XXX provide sane businfo */ - strcpy (info->bus_info, "ieee1394"); + strcpy(info->driver, driver_name); + strcpy(info->bus_info, "ieee1394"); /* FIXME provide more detail? */ } 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) { - packet_task_cache = kmem_cache_create("packet_task", sizeof(struct packet_task), + int err; + + packet_task_cache = kmem_cache_create("packet_task", + sizeof(struct packet_task), 0, 0, NULL, NULL); + if (!packet_task_cache) + return -ENOMEM; - /* Register ourselves as a highlevel driver */ hpsb_register_highlevel(ð1394_highlevel); - - return hpsb_register_protocol(ð1394_proto_driver); + err = hpsb_register_protocol(ð1394_proto_driver); + if (err) { + hpsb_unregister_highlevel(ð1394_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(ð1394_proto_driver); hpsb_unregister_highlevel(ð1394_highlevel); |