summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2009-06-07 22:57:53 +0200
committerStefan Richter <stefanr@s5r6.in-berlin.de>2009-06-14 14:26:29 +0200
commitf91e3bd842ec6f5cea245993926ee8ff26250467 (patch)
treec7b66078c862a85fdc7d21bc2eb61f9c32a530ca /drivers
parentb9530fd6c3f057bda258c8e2631ad1a25959f4a2 (diff)
firewire: net: style changes
Change names of types, variables, functions. Omit debug code. Use get_unaligned*, put_unaligned*. Annotate big endian data. Handle errors in __init. Change whitespace. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/firewire/core-card.c2
-rw-r--r--drivers/firewire/net.c2041
2 files changed, 966 insertions, 1077 deletions
diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c
index cdab32b20675..8c45e43da7c5 100644
--- a/drivers/firewire/core-card.c
+++ b/drivers/firewire/core-card.c
@@ -430,7 +430,7 @@ void fw_card_initialize(struct fw_card *card,
INIT_DELAYED_WORK(&card->work, fw_card_bm_work);
card->netdev = NULL;
- INIT_LIST_HEAD(&card->ipv4_nodes);
+ INIT_LIST_HEAD(&card->peer_list);
}
EXPORT_SYMBOL(fw_card_initialize);
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index 15353886bd80..ba6f924b1b13 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -6,6 +6,7 @@
* based on eth1394 by Ben Collins et al
*/
+#include <linux/bug.h>
#include <linux/device.h>
#include <linux/ethtool.h>
#include <linux/firewire.h>
@@ -13,6 +14,7 @@
#include <linux/highmem.h>
#include <linux/in.h>
#include <linux/ip.h>
+#include <linux/jiffies.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
@@ -22,181 +24,109 @@
#include <asm/unaligned.h>
#include <net/arp.h>
-/* Things to potentially make runtime cofigurable */
-/* must be at least as large as our maximum receive size */
-#define FIFO_SIZE 4096
-/* Network timeout in glibbles */
-#define IPV4_TIMEOUT 100000
+#define FWNET_MAX_FRAGMENTS 25 /* arbitrary limit */
+#define FWNET_ISO_PAGE_COUNT (PAGE_SIZE < 16 * 1024 ? 4 : 2)
-/* Runitme configurable paramaters */
-static int ipv4_mpd = 25;
-static int ipv4_max_xmt = 0;
-/* 16k for receiving arp and broadcast packets. Enough? */
-static int ipv4_iso_page_count = 4;
+#define IEEE1394_BROADCAST_CHANNEL 31
+#define IEEE1394_ALL_NODES (0xffc0 | 0x003f)
+#define IEEE1394_MAX_PAYLOAD_S100 512
+#define FWNET_NO_FIFO_ADDR (~0ULL)
-MODULE_AUTHOR("Jay Fenlason (fenlason@redhat.com)");
-MODULE_DESCRIPTION("Firewire IPv4 Driver (IPv4-over-IEEE1394 as per RFC 2734)");
-MODULE_LICENSE("GPL");
-MODULE_DEVICE_TABLE(ieee1394, ipv4_id_table);
-module_param_named(max_partial_datagrams, ipv4_mpd, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(max_partial_datagrams, "Maximum number of received"
- " incomplete fragmented datagrams (default = 25).");
-
-/* Max xmt is useful for forcing fragmentation, which makes testing easier. */
-module_param_named(max_transmit, ipv4_max_xmt, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(max_transmit, "Maximum datagram size to transmit"
- " (larger datagrams will be fragmented) (default = 0 (use hardware defaults).");
-
-/* iso page count controls how many pages will be used for receiving broadcast packets. */
-module_param_named(iso_pages, ipv4_iso_page_count, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(iso_pages, "Number of pages to use for receiving broadcast packets"
- " (default = 4).");
-
-/* uncomment this line to do debugging */
-#define fw_debug(s, args...) printk(KERN_DEBUG KBUILD_MODNAME ": " s, ## args)
-
-/* comment out these lines to do debugging. */
-/* #undef fw_debug */
-/* #define fw_debug(s...) */
-/* #define print_hex_dump(l...) */
-
-/* Define a fake hardware header format for the networking core. Note that
- * header size cannot exceed 16 bytes as that is the size of the header cache.
- * Also, we do not need the source address in the header so we omit it and
- * keep the header to under 16 bytes */
-#define IPV4_ALEN (8)
-/* This must equal sizeof(struct ipv4_ether_hdr) */
-#define IPV4_HLEN (10)
-
-/* FIXME: what's a good size for this? */
-#define INVALID_FIFO_ADDR (u64)~0ULL
-
-/* Things specified by standards */
-#define BROADCAST_CHANNEL 31
-
-#define S100_BUFFER_SIZE 512
-#define MAX_BUFFER_SIZE 4096
-
-#define IPV4_GASP_SPECIFIER_ID 0x00005EU
-#define IPV4_GASP_VERSION 0x00000001U
-
-#define IPV4_GASP_OVERHEAD (2 * sizeof(u32)) /* for GASP header */
-
-#define IPV4_UNFRAG_HDR_SIZE sizeof(u32)
-#define IPV4_FRAG_HDR_SIZE (2 * sizeof(u32))
-#define IPV4_FRAG_OVERHEAD sizeof(u32)
-
-#define ALL_NODES (0xffc0 | 0x003f)
-
-#define IPV4_HDR_UNFRAG 0 /* unfragmented */
-#define IPV4_HDR_FIRSTFRAG 1 /* first fragment */
-#define IPV4_HDR_LASTFRAG 2 /* last fragment */
-#define IPV4_HDR_INTFRAG 3 /* interior fragment */
-
-/* Our arp packet (ARPHRD_IEEE1394) */
-/* FIXME: note that this is probably bogus on weird-endian machines */
-struct ipv4_arp {
- u16 hw_type; /* 0x0018 */
- u16 proto_type; /* 0x0806 */
- u8 hw_addr_len; /* 16 */
- u8 ip_addr_len; /* 4 */
- u16 opcode; /* ARP Opcode */
- /* Above is exactly the same format as struct arphdr */
-
- u64 s_uniq_id; /* Sender's 64bit EUI */
- u8 max_rec; /* Sender's max packet size */
- u8 sspd; /* Sender's max speed */
- u16 fifo_hi; /* hi 16bits of sender's FIFO addr */
- u32 fifo_lo; /* lo 32bits of sender's FIFO addr */
- u32 sip; /* Sender's IP Address */
- u32 tip; /* IP Address of requested hw addr */
-} __attribute__((packed));
+#define IANA_SPECIFIER_ID 0x00005eU
+#define RFC2734_SW_VERSION 0x000001U
-struct ipv4_ether_hdr {
- unsigned char h_dest[IPV4_ALEN]; /* destination address */
- unsigned short h_proto; /* packet type ID field */
-} __attribute__((packed));
+#define IEEE1394_GASP_HDR_SIZE 8
-static inline struct ipv4_ether_hdr *ipv4_ether_hdr(const struct sk_buff *skb)
-{
- return (struct ipv4_ether_hdr *)skb_mac_header(skb);
-}
+#define RFC2374_UNFRAG_HDR_SIZE 4
+#define RFC2374_FRAG_HDR_SIZE 8
+#define RFC2374_FRAG_OVERHEAD 4
-enum ipv4_tx_type {
- IPV4_UNKNOWN = 0,
- IPV4_GASP = 1,
- IPV4_WRREQ = 2,
-};
+#define RFC2374_HDR_UNFRAG 0 /* unfragmented */
+#define RFC2374_HDR_FIRSTFRAG 1 /* first fragment */
+#define RFC2374_HDR_LASTFRAG 2 /* last fragment */
+#define RFC2374_HDR_INTFRAG 3 /* interior fragment */
-enum ipv4_broadcast_state {
- IPV4_BROADCAST_ERROR,
- IPV4_BROADCAST_RUNNING,
- IPV4_BROADCAST_STOPPED,
-};
+#define RFC2734_HW_ADDR_LEN 16
-#define ipv4_get_hdr_lf(h) (((h)->w0&0xC0000000)>>30)
-#define ipv4_get_hdr_ether_type(h) (((h)->w0&0x0000FFFF) )
-#define ipv4_get_hdr_dg_size(h) (((h)->w0&0x0FFF0000)>>16)
-#define ipv4_get_hdr_fg_off(h) (((h)->w0&0x00000FFF) )
-#define ipv4_get_hdr_dgl(h) (((h)->w1&0xFFFF0000)>>16)
+struct rfc2734_arp {
+ __be16 hw_type; /* 0x0018 */
+ __be16 proto_type; /* 0x0806 */
+ u8 hw_addr_len; /* 16 */
+ u8 ip_addr_len; /* 4 */
+ __be16 opcode; /* ARP Opcode */
+ /* Above is exactly the same format as struct arphdr */
-#define ipv4_set_hdr_lf(lf) (( lf)<<30)
-#define ipv4_set_hdr_ether_type(et) (( et) )
-#define ipv4_set_hdr_dg_size(dgs) ((dgs)<<16)
-#define ipv4_set_hdr_fg_off(fgo) ((fgo) )
+ __be64 s_uniq_id; /* Sender's 64bit EUI */
+ u8 max_rec; /* Sender's max packet size */
+ u8 sspd; /* Sender's max speed */
+ __be16 fifo_hi; /* hi 16bits of sender's FIFO addr */
+ __be32 fifo_lo; /* lo 32bits of sender's FIFO addr */
+ __be32 sip; /* Sender's IP Address */
+ __be32 tip; /* IP Address of requested hw addr */
+} __attribute__((packed));
-#define ipv4_set_hdr_dgl(dgl) ((dgl)<<16)
+/* This header format is specific to this driver implementation. */
+#define FWNET_ALEN 8
+#define FWNET_HLEN 10
+struct fwnet_header {
+ u8 h_dest[FWNET_ALEN]; /* destination address */
+ __be16 h_proto; /* packet type ID field */
+} __attribute__((packed));
-struct ipv4_hdr {
+/* IPv4 and IPv6 encapsulation header */
+struct rfc2734_header {
u32 w0;
u32 w1;
};
-static inline void ipv4_make_uf_hdr( struct ipv4_hdr *hdr, unsigned ether_type) {
- hdr->w0 = ipv4_set_hdr_lf(IPV4_HDR_UNFRAG)
- |ipv4_set_hdr_ether_type(ether_type);
- fw_debug ( "Setting unfragmented header %p to %x\n", hdr, hdr->w0 );
-}
+#define fwnet_get_hdr_lf(h) (((h)->w0 & 0xc0000000) >> 30)
+#define fwnet_get_hdr_ether_type(h) (((h)->w0 & 0x0000ffff))
+#define fwnet_get_hdr_dg_size(h) (((h)->w0 & 0x0fff0000) >> 16)
+#define fwnet_get_hdr_fg_off(h) (((h)->w0 & 0x00000fff))
+#define fwnet_get_hdr_dgl(h) (((h)->w1 & 0xffff0000) >> 16)
-static inline void ipv4_make_ff_hdr ( struct ipv4_hdr *hdr, unsigned ether_type, unsigned dg_size, unsigned dgl ) {
- hdr->w0 = ipv4_set_hdr_lf(IPV4_HDR_FIRSTFRAG)
- |ipv4_set_hdr_dg_size(dg_size)
- |ipv4_set_hdr_ether_type(ether_type);
- hdr->w1 = ipv4_set_hdr_dgl(dgl);
- fw_debug ( "Setting fragmented header %p to first_frag %x,%x (et %x, dgs %x, dgl %x)\n", hdr, hdr->w0, hdr->w1,
- ether_type, dg_size, dgl );
-}
+#define fwnet_set_hdr_lf(lf) ((lf) << 30)
+#define fwnet_set_hdr_ether_type(et) (et)
+#define fwnet_set_hdr_dg_size(dgs) ((dgs) << 16)
+#define fwnet_set_hdr_fg_off(fgo) (fgo)
-static inline void ipv4_make_sf_hdr ( struct ipv4_hdr *hdr, unsigned lf, unsigned dg_size, unsigned fg_off, unsigned dgl) {
- hdr->w0 = ipv4_set_hdr_lf(lf)
- |ipv4_set_hdr_dg_size(dg_size)
- |ipv4_set_hdr_fg_off(fg_off);
- hdr->w1 = ipv4_set_hdr_dgl(dgl);
- fw_debug ( "Setting fragmented header %p to %x,%x (lf %x, dgs %x, fo %x dgl %x)\n",
- hdr, hdr->w0, hdr->w1,
- lf, dg_size, fg_off, dgl );
-}
+#define fwnet_set_hdr_dgl(dgl) ((dgl) << 16)
-/* End of IP1394 headers */
+static inline void fwnet_make_uf_hdr(struct rfc2734_header *hdr,
+ unsigned ether_type)
+{
+ hdr->w0 = fwnet_set_hdr_lf(RFC2374_HDR_UNFRAG)
+ | fwnet_set_hdr_ether_type(ether_type);
+}
-/* Fragment types */
-#define ETH1394_HDR_LF_UF 0 /* unfragmented */
-#define ETH1394_HDR_LF_FF 1 /* first fragment */
-#define ETH1394_HDR_LF_LF 2 /* last fragment */
-#define ETH1394_HDR_LF_IF 3 /* interior fragment */
+static inline void fwnet_make_ff_hdr(struct rfc2734_header *hdr,
+ unsigned ether_type, unsigned dg_size, unsigned dgl)
+{
+ hdr->w0 = fwnet_set_hdr_lf(RFC2374_HDR_FIRSTFRAG)
+ | fwnet_set_hdr_dg_size(dg_size)
+ | fwnet_set_hdr_ether_type(ether_type);
+ hdr->w1 = fwnet_set_hdr_dgl(dgl);
+}
-#define IP1394_HW_ADDR_LEN 16 /* As per RFC */
+static inline void fwnet_make_sf_hdr(struct rfc2734_header *hdr,
+ unsigned lf, unsigned dg_size, unsigned fg_off, unsigned dgl)
+{
+ hdr->w0 = fwnet_set_hdr_lf(lf)
+ | fwnet_set_hdr_dg_size(dg_size)
+ | fwnet_set_hdr_fg_off(fg_off);
+ hdr->w1 = fwnet_set_hdr_dgl(dgl);
+}
/* This list keeps track of what parts of the datagram have been filled in */
-struct ipv4_fragment_info {
- struct list_head fragment_info;
+struct fwnet_fragment_info {
+ struct list_head fi_link;
u16 offset;
u16 len;
};
-struct ipv4_partial_datagram {
- struct list_head pdg_list;
- struct list_head fragment_info;
+struct fwnet_partial_datagram {
+ struct list_head pd_link;
+ struct list_head fi_list;
struct sk_buff *skb;
/* FIXME Why not use skb->data? */
char *pbuf;
@@ -208,40 +138,43 @@ struct ipv4_partial_datagram {
/*
* We keep one of these for each IPv4 capable device attached to a fw_card.
* The list of them is stored in the fw_card structure rather than in the
- * ipv4_priv because the remote IPv4 nodes may be probed before the card is,
- * so we need a place to store them before the ipv4_priv structure is
+ * fwnet_device because the remote IPv4 nodes may be probed before the card is,
+ * so we need a place to store them before the fwnet_device structure is
* allocated.
*/
-struct ipv4_node {
- struct list_head ipv4_nodes;
- /* guid of the remote node */
+struct fwnet_peer {
+ struct list_head peer_link;
+ /* guid of the remote peer */
u64 guid;
- /* FIFO address to transmit datagrams to, or INVALID_FIFO_ADDR */
+ /* FIFO address to transmit datagrams to, or FWNET_NO_FIFO_ADDR */
u64 fifo;
spinlock_t pdg_lock; /* partial datagram lock */
- /* List of partial datagrams received from this node */
- struct list_head pdg_list;
- /* Number of entries in pdg_list at the moment */
+ /* List of partial datagrams received from this peer */
+ struct list_head pd_list;
+ /* Number of entries in pd_list at the moment */
unsigned pdg_size;
- /* max payload to transmit to this remote node */
- /* This already includes the IPV4_FRAG_HDR_SIZE overhead */
+ /* max payload to transmit to this remote peer */
+ /* This already includes the RFC2374_FRAG_HDR_SIZE overhead */
u16 max_payload;
/* outgoing datagram label */
u16 datagram_label;
- /* Current node_id of the remote node */
- u16 nodeid;
- /* current generation of the remote node */
+ /* Current node_id of the remote peer */
+ u16 node_id;
+ /* current generation of the remote peer */
u8 generation;
- /* max speed that this node can receive at */
+ /* max speed that this peer can receive at */
u8 xmt_speed;
};
-struct ipv4_priv {
+struct fwnet_device {
spinlock_t lock;
-
- enum ipv4_broadcast_state broadcast_state;
+ enum {
+ FWNET_BROADCAST_ERROR,
+ FWNET_BROADCAST_RUNNING,
+ FWNET_BROADCAST_STOPPED,
+ } broadcast_state;
struct fw_iso_context *broadcast_rcv_context;
struct fw_iso_buffer broadcast_rcv_buffer;
void **broadcast_rcv_buffer_ptrs;
@@ -257,14 +190,12 @@ struct ipv4_priv {
u16 broadcast_xmt_datagramlabel;
/*
- * The csr address that remote nodes must send datagrams to for us to
+ * The CSR address that remote nodes must send datagrams to for us to
* receive them.
*/
struct fw_address_handler handler;
u64 local_fifo;
- /* Wake up to xmt */
- /* struct work_struct wake;*/
/* List of packets to be sent */
struct list_head packet_list;
/*
@@ -279,17 +210,17 @@ struct ipv4_priv {
};
/* This is our task struct. It's used for the packet complete callback. */
-struct ipv4_packet_task {
+struct fwnet_packet_task {
/*
- * ptask can actually be on priv->packet_list, priv->broadcasted_list,
- * or priv->sent_list depending on its current state.
+ * ptask can actually be on dev->packet_list, dev->broadcasted_list,
+ * or dev->sent_list depending on its current state.
*/
- struct list_head packet_list;
+ struct list_head pt_link;
struct fw_transaction transaction;
- struct ipv4_hdr hdr;
+ struct rfc2734_header hdr;
struct sk_buff *skb;
- struct ipv4_priv *priv;
- enum ipv4_tx_type tx_type;
+ struct fwnet_device *dev;
+
int outstanding_pkts;
unsigned max_payload;
u64 fifo_addr;
@@ -298,243 +229,192 @@ struct ipv4_packet_task {
u8 speed;
};
-static struct kmem_cache *ipv4_packet_task_cache;
-
-static const char ipv4_driver_name[] = "firewire-ipv4";
-
-static const struct ieee1394_device_id ipv4_id_table[] = {
- {
- .match_flags = IEEE1394_MATCH_SPECIFIER_ID |
- IEEE1394_MATCH_VERSION,
- .specifier_id = IPV4_GASP_SPECIFIER_ID,
- .version = IPV4_GASP_VERSION,
- },
- { }
-};
-
-static u32 ipv4_unit_directory_data[] = {
- 0x00040000, /* unit directory */
- 0x12000000 | IPV4_GASP_SPECIFIER_ID, /* specifier ID */
- 0x81000003, /* text descriptor */
- 0x13000000 | IPV4_GASP_VERSION, /* version */
- 0x81000005, /* text descriptor */
-
- 0x00030000, /* Three quadlets */
- 0x00000000, /* Text */
- 0x00000000, /* Language 0 */
- 0x49414e41, /* I A N A */
- 0x00030000, /* Three quadlets */
- 0x00000000, /* Text */
- 0x00000000, /* Language 0 */
- 0x49507634, /* I P v 4 */
-};
-
-static struct fw_descriptor ipv4_unit_directory = {
- .length = ARRAY_SIZE(ipv4_unit_directory_data),
- .key = 0xd1000000,
- .data = ipv4_unit_directory_data
-};
-
-static int ipv4_send_packet(struct ipv4_packet_task *ptask );
-
-/* ------------------------------------------------------------------ */
-/******************************************
- * HW Header net device functions
- ******************************************/
- /* 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). */
+/*
+ * saddr == NULL means use device source address.
+ * daddr == NULL means leave destination address (eg unresolved arp).
+ */
+static int fwnet_header_create(struct sk_buff *skb, struct net_device *net,
+ unsigned short type, const void *daddr,
+ const void *saddr, unsigned len)
+{
+ struct fwnet_header *h;
-static int ipv4_header ( struct sk_buff *skb, struct net_device *dev,
- unsigned short type, const void *daddr,
- const void *saddr, unsigned len) {
- struct ipv4_ether_hdr *eth;
+ h = (struct fwnet_header *)skb_push(skb, sizeof(*h));
+ put_unaligned_be16(type, &h->h_proto);
- eth = (struct ipv4_ether_hdr *)skb_push(skb, sizeof(*eth));
- eth->h_proto = htons(type);
+ if (net->flags & (IFF_LOOPBACK | IFF_NOARP)) {
+ memset(h->h_dest, 0, net->addr_len);
- if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
- memset(eth->h_dest, 0, dev->addr_len);
- return dev->hard_header_len;
+ return net->hard_header_len;
}
if (daddr) {
- memcpy(eth->h_dest, daddr, dev->addr_len);
- return dev->hard_header_len;
+ memcpy(h->h_dest, daddr, net->addr_len);
+
+ return net->hard_header_len;
}
- return -dev->hard_header_len;
+ return -net->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.
- *
- * This routine CANNOT use cached dst->neigh!
- * Really, it is used only when dst->neigh is wrong.
- */
-
-static int ipv4_rebuild_header(struct sk_buff *skb)
+static int fwnet_header_rebuild(struct sk_buff *skb)
{
- struct ipv4_ether_hdr *eth;
+ struct fwnet_header *h = (struct fwnet_header *)skb->data;
- eth = (struct ipv4_ether_hdr *)skb->data;
- if (eth->h_proto == htons(ETH_P_IP))
- return arp_find((unsigned char *)&eth->h_dest, skb);
+ if (get_unaligned_be16(&h->h_proto) == ETH_P_IP)
+ return arp_find((unsigned char *)&h->h_dest, skb);
- fw_notify ( "%s: unable to resolve type %04x addresses\n",
- skb->dev->name,ntohs(eth->h_proto) );
+ fw_notify("%s: unable to resolve type %04x addresses\n",
+ skb->dev->name, be16_to_cpu(h->h_proto));
return 0;
}
-static int ipv4_header_cache(const struct neighbour *neigh, struct hh_cache *hh) {
- unsigned short type = hh->hh_type;
- struct net_device *dev;
- struct ipv4_ether_hdr *eth;
+static int fwnet_header_cache(const struct neighbour *neigh,
+ struct hh_cache *hh)
+{
+ struct net_device *net;
+ struct fwnet_header *h;
- if (type == htons(ETH_P_802_3))
+ if (hh->hh_type == cpu_to_be16(ETH_P_802_3))
return -1;
- dev = neigh->dev;
- eth = (struct ipv4_ether_hdr *)((u8 *)hh->hh_data + 16 - sizeof(*eth));
- eth->h_proto = type;
- memcpy(eth->h_dest, neigh->ha, dev->addr_len);
+ net = neigh->dev;
+ h = (struct fwnet_header *)((u8 *)hh->hh_data + 16 - sizeof(*h));
+ h->h_proto = hh->hh_type;
+ memcpy(h->h_dest, neigh->ha, net->addr_len);
+ hh->hh_len = FWNET_HLEN;
- hh->hh_len = IPV4_HLEN;
return 0;
}
/* Called by Address Resolution module to notify changes in address. */
-static void ipv4_header_cache_update(struct hh_cache *hh, const struct net_device *dev, const unsigned char * haddr ) {
- memcpy((u8 *)hh->hh_data + 16 - IPV4_HLEN, haddr, dev->addr_len);
+static void fwnet_header_cache_update(struct hh_cache *hh,
+ const struct net_device *net, const unsigned char *haddr)
+{
+ memcpy((u8 *)hh->hh_data + 16 - FWNET_HLEN, haddr, net->addr_len);
}
-static int ipv4_header_parse(const struct sk_buff *skb, unsigned char *haddr) {
- memcpy(haddr, skb->dev->dev_addr, IPV4_ALEN);
- return IPV4_ALEN;
+static int fwnet_header_parse(const struct sk_buff *skb, unsigned char *haddr)
+{
+ memcpy(haddr, skb->dev->dev_addr, FWNET_ALEN);
+
+ return FWNET_ALEN;
}
-static const struct header_ops ipv4_header_ops = {
- .create = ipv4_header,
- .rebuild = ipv4_rebuild_header,
- .cache = ipv4_header_cache,
- .cache_update = ipv4_header_cache_update,
- .parse = ipv4_header_parse,
+static const struct header_ops fwnet_header_ops = {
+ .create = fwnet_header_create,
+ .rebuild = fwnet_header_rebuild,
+ .cache = fwnet_header_cache,
+ .cache_update = fwnet_header_cache_update,
+ .parse = fwnet_header_parse,
};
-/* ------------------------------------------------------------------ */
-
/* FIXME: is this correct for all cases? */
-static bool ipv4_frag_overlap(struct ipv4_partial_datagram *pd, unsigned offset, unsigned len)
+static bool fwnet_frag_overlap(struct fwnet_partial_datagram *pd,
+ unsigned offset, unsigned len)
{
- struct ipv4_fragment_info *fi;
+ struct fwnet_fragment_info *fi;
unsigned end = offset + len;
- list_for_each_entry(fi, &pd->fragment_info, fragment_info) {
- if (offset < fi->offset + fi->len && end > fi->offset) {
- fw_debug ( "frag_overlap pd %p fi %p (%x@%x) with %x@%x\n", pd, fi, fi->len, fi->offset, len, offset );
+ list_for_each_entry(fi, &pd->fi_list, fi_link)
+ if (offset < fi->offset + fi->len && end > fi->offset)
return true;
- }
- }
- fw_debug ( "frag_overlap %p does not overlap with %x@%x\n", pd, len, offset );
+
return false;
}
/* Assumes that new fragment does not overlap any existing fragments */
-static struct ipv4_fragment_info *ipv4_frag_new ( struct ipv4_partial_datagram *pd, unsigned offset, unsigned len ) {
- struct ipv4_fragment_info *fi, *fi2, *new;
+static struct fwnet_fragment_info *fwnet_frag_new(
+ struct fwnet_partial_datagram *pd, unsigned offset, unsigned len)
+{
+ struct fwnet_fragment_info *fi, *fi2, *new;
struct list_head *list;
- fw_debug ( "frag_new pd %p %x@%x\n", pd, len, offset );
- list = &pd->fragment_info;
- list_for_each_entry(fi, &pd->fragment_info, fragment_info) {
+ list = &pd->fi_list;
+ list_for_each_entry(fi, &pd->fi_list, fi_link) {
if (fi->offset + fi->len == offset) {
/* The new fragment can be tacked on to the end */
/* Did the new fragment plug a hole? */
- fi2 = list_entry(fi->fragment_info.next, struct ipv4_fragment_info, fragment_info);
+ fi2 = list_entry(fi->fi_link.next,
+ struct fwnet_fragment_info, fi_link);
if (fi->offset + fi->len == fi2->offset) {
- fw_debug ( "pd %p: hole filling %p (%x@%x) and %p(%x@%x): now %x@%x\n", pd, fi, fi->len, fi->offset,
- fi2, fi2->len, fi2->offset, fi->len + len + fi2->len, fi->offset );
/* glue fragments together */
fi->len += len + fi2->len;
- list_del(&fi2->fragment_info);
+ list_del(&fi2->fi_link);
kfree(fi2);
} else {
- fw_debug ( "pd %p: extending %p from %x@%x to %x@%x\n", pd, fi, fi->len, fi->offset, fi->len+len, fi->offset );
fi->len += len;
}
+
return fi;
}
if (offset + len == fi->offset) {
/* The new fragment can be tacked on to the beginning */
/* Did the new fragment plug a hole? */
- fi2 = list_entry(fi->fragment_info.prev, struct ipv4_fragment_info, fragment_info);
+ fi2 = list_entry(fi->fi_link.prev,
+ struct fwnet_fragment_info, fi_link);
if (fi2->offset + fi2->len == fi->offset) {
/* glue fragments together */
- fw_debug ( "pd %p: extending %p and merging with %p from %x@%x to %x@%x\n",
- pd, fi2, fi, fi2->len, fi2->offset, fi2->len + fi->len + len, fi2->offset );
fi2->len += fi->len + len;
- list_del(&fi->fragment_info);
+ list_del(&fi->fi_link);
kfree(fi);
+
return fi2;
}
- fw_debug ( "pd %p: extending %p from %x@%x to %x@%x\n", pd, fi, fi->len, fi->offset, offset, fi->len + len );
fi->offset = offset;
fi->len += len;
+
return fi;
}
if (offset > fi->offset + fi->len) {
- list = &fi->fragment_info;
+ list = &fi->fi_link;
break;
}
if (offset + len < fi->offset) {
- list = fi->fragment_info.prev;
+ list = fi->fi_link.prev;
break;
}
}
new = kmalloc(sizeof(*new), GFP_ATOMIC);
if (!new) {
- fw_error ( "out of memory in fragment handling!\n" );
+ fw_error("out of memory\n");
return NULL;
}
new->offset = offset;
new->len = len;
- list_add(&new->fragment_info, list);
- fw_debug ( "pd %p: new frag %p %x@%x\n", pd, new, new->len, new->offset );
- list_for_each_entry( fi, &pd->fragment_info, fragment_info )
- fw_debug ( "fi %p %x@%x\n", fi, fi->len, fi->offset );
+ list_add(&new->fi_link, list);
+
return new;
}
-/* ------------------------------------------------------------------ */
-
-static struct ipv4_partial_datagram *ipv4_pd_new(struct net_device *netdev,
- struct ipv4_node *node, u16 datagram_label, unsigned dg_size, u32 *frag_buf,
- unsigned frag_off, unsigned frag_len) {
- struct ipv4_partial_datagram *new;
- struct ipv4_fragment_info *fi;
+static struct fwnet_partial_datagram *fwnet_pd_new(struct net_device *net,
+ struct fwnet_peer *peer, u16 datagram_label, unsigned dg_size,
+ void *frag_buf, unsigned frag_off, unsigned frag_len)
+{
+ struct fwnet_partial_datagram *new;
+ struct fwnet_fragment_info *fi;
new = kmalloc(sizeof(*new), GFP_ATOMIC);
if (!new)
goto fail;
- INIT_LIST_HEAD(&new->fragment_info);
- fi = ipv4_frag_new ( new, frag_off, frag_len);
- if ( fi == NULL )
+
+ INIT_LIST_HEAD(&new->fi_list);
+ fi = fwnet_frag_new(new, frag_off, frag_len);
+ if (fi == NULL)
goto fail_w_new;
+
new->datagram_label = datagram_label;
new->datagram_size = dg_size;
- new->skb = dev_alloc_skb(dg_size + netdev->hard_header_len + 15);
- if ( new->skb == NULL )
+ new->skb = dev_alloc_skb(dg_size + net->hard_header_len + 15);
+ if (new->skb == NULL)
goto fail_w_fi;
- skb_reserve(new->skb, (netdev->hard_header_len + 15) & ~15);
+
+ skb_reserve(new->skb, (net->hard_header_len + 15) & ~15);
new->pbuf = skb_put(new->skb, dg_size);
memcpy(new->pbuf + frag_off, frag_buf, frag_len);
- list_add_tail(&new->pdg_list, &node->pdg_list);
- fw_debug ( "pd_new: new pd %p { dgl %u, dg_size %u, skb %p, pbuf %p } on node %p\n",
- new, new->datagram_label, new->datagram_size, new->skb, new->pbuf, node );
+ list_add_tail(&new->pd_link, &peer->pd_list);
+
return new;
fail_w_fi:
@@ -542,174 +422,171 @@ fail_w_fi:
fail_w_new:
kfree(new);
fail:
- fw_error("ipv4_pd_new: no memory\n");
+ fw_error("out of memory\n");
+
return NULL;
}
-static struct ipv4_partial_datagram *ipv4_pd_find(struct ipv4_node *node, u16 datagram_label) {
- struct ipv4_partial_datagram *pd;
+static struct fwnet_partial_datagram *fwnet_pd_find(struct fwnet_peer *peer,
+ u16 datagram_label)
+{
+ struct fwnet_partial_datagram *pd;
- list_for_each_entry(pd, &node->pdg_list, pdg_list) {
- if ( pd->datagram_label == datagram_label ) {
- fw_debug ( "pd_find(node %p, label %u): pd %p\n", node, datagram_label, pd );
+ list_for_each_entry(pd, &peer->pd_list, pd_link)
+ if (pd->datagram_label == datagram_label)
return pd;
- }
- }
- fw_debug ( "pd_find(node %p, label %u) no entry\n", node, datagram_label );
+
return NULL;
}
-static void ipv4_pd_delete ( struct ipv4_partial_datagram *old ) {
- struct ipv4_fragment_info *fi, *n;
+static void fwnet_pd_delete(struct fwnet_partial_datagram *old)
+{
+ struct fwnet_fragment_info *fi, *n;
- fw_debug ( "pd_delete %p\n", old );
- list_for_each_entry_safe(fi, n, &old->fragment_info, fragment_info) {
- fw_debug ( "Freeing fi %p\n", fi );
+ list_for_each_entry_safe(fi, n, &old->fi_list, fi_link)
kfree(fi);
- }
- list_del(&old->pdg_list);
+
+ list_del(&old->pd_link);
dev_kfree_skb_any(old->skb);
kfree(old);
}
-static bool ipv4_pd_update ( struct ipv4_node *node, struct ipv4_partial_datagram *pd,
- u32 *frag_buf, unsigned frag_off, unsigned frag_len) {
- fw_debug ( "pd_update node %p, pd %p, frag_buf %p, %x@%x\n", node, pd, frag_buf, frag_len, frag_off );
- if ( ipv4_frag_new ( pd, frag_off, frag_len ) == NULL)
+static bool fwnet_pd_update(struct fwnet_peer *peer,
+ struct fwnet_partial_datagram *pd, void *frag_buf,
+ unsigned frag_off, unsigned frag_len)
+{
+ if (fwnet_frag_new(pd, frag_off, frag_len) == NULL)
return false;
+
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_tail(&pd->pdg_list, &node->pdg_list);
- fw_debug ( "New pd list:\n" );
- list_for_each_entry ( pd, &node->pdg_list, pdg_list ) {
- fw_debug ( "pd %p\n", pd );
- }
+ list_move_tail(&pd->pd_link, &peer->pd_list);
+
return true;
}
-static bool ipv4_pd_is_complete ( struct ipv4_partial_datagram *pd ) {
- struct ipv4_fragment_info *fi;
- bool ret;
+static bool fwnet_pd_is_complete(struct fwnet_partial_datagram *pd)
+{
+ struct fwnet_fragment_info *fi;
- fi = list_entry(pd->fragment_info.next, struct ipv4_fragment_info, fragment_info);
+ fi = list_entry(pd->fi_list.next, struct fwnet_fragment_info, fi_link);
- ret = (fi->len == pd->datagram_size);
- fw_debug ( "pd_is_complete (pd %p, dgs %x): fi %p (%x@%x) %s\n", pd, pd->datagram_size, fi, fi->len, fi->offset, ret ? "yes" : "no" );
- return ret;
+ return fi->len == pd->datagram_size;
}
-/* ------------------------------------------------------------------ */
+static int fwnet_peer_new(struct fw_card *card, struct fw_device *device)
+{
+ struct fwnet_peer *peer;
-static int ipv4_node_new ( struct fw_card *card, struct fw_device *device ) {
- struct ipv4_node *node;
+ peer = kmalloc(sizeof(*peer), GFP_KERNEL);
+ if (!peer) {
+ fw_error("out of memory\n");
- node = kmalloc ( sizeof(*node), GFP_KERNEL );
- if ( ! node ) {
- fw_error ( "allocate new node failed\n" );
return -ENOMEM;
}
- node->guid = (u64)device->config_rom[3] << 32 | device->config_rom[4];
- node->fifo = INVALID_FIFO_ADDR;
- INIT_LIST_HEAD(&node->pdg_list);
- spin_lock_init(&node->pdg_lock);
- node->pdg_size = 0;
- node->generation = device->generation;
+ peer->guid = (u64)device->config_rom[3] << 32 | device->config_rom[4];
+ peer->fifo = FWNET_NO_FIFO_ADDR;
+ INIT_LIST_HEAD(&peer->pd_list);
+ spin_lock_init(&peer->pdg_lock);
+ peer->pdg_size = 0;
+ peer->generation = device->generation;
rmb();
- node->nodeid = device->node_id;
+ peer->node_id = device->node_id;
/* FIXME what should it really be? */
- node->max_payload = S100_BUFFER_SIZE - IPV4_UNFRAG_HDR_SIZE;
- node->datagram_label = 0U;
- node->xmt_speed = device->max_speed;
- list_add_tail ( &node->ipv4_nodes, &card->ipv4_nodes );
- fw_debug ( "node_new: %p { guid %016llx, generation %u, nodeid %x, max_payload %x, xmt_speed %x } added\n",
- node, (unsigned long long)node->guid, node->generation, node->nodeid, node->max_payload, node->xmt_speed );
+ peer->max_payload = IEEE1394_MAX_PAYLOAD_S100 - RFC2374_UNFRAG_HDR_SIZE;
+ peer->datagram_label = 0U;
+ peer->xmt_speed = device->max_speed;
+ list_add_tail(&peer->peer_link, &card->peer_list);
+
return 0;
}
-static struct ipv4_node *ipv4_node_find_by_guid(struct ipv4_priv *priv, u64 guid) {
- struct ipv4_node *node;
+/* FIXME caller must take the lock, or peer needs to be reference-counted */
+static struct fwnet_peer *fwnet_peer_find_by_guid(struct fwnet_device *dev,
+ u64 guid)
+{
+ struct fwnet_peer *p, *peer = NULL;
unsigned long flags;
- spin_lock_irqsave(&priv->lock, flags);
- list_for_each_entry(node, &priv->card->ipv4_nodes, ipv4_nodes)
- if (node->guid == guid) {
- /* FIXME: lock the node first? */
- spin_unlock_irqrestore ( &priv->lock, flags );
- fw_debug ( "node_find_by_guid (%016llx) found %p\n", (unsigned long long)guid, node );
- return node;
+ spin_lock_irqsave(&dev->lock, flags);
+ list_for_each_entry(p, &dev->card->peer_list, peer_link)
+ if (p->guid == guid) {
+ peer = p;
+ break;
}
+ spin_unlock_irqrestore(&dev->lock, flags);
- spin_unlock_irqrestore ( &priv->lock, flags );
- fw_debug ( "node_find_by_guid (%016llx) not found\n", (unsigned long long)guid );
- return NULL;
+ return peer;
}
-static struct ipv4_node *ipv4_node_find_by_nodeid(struct ipv4_priv *priv, u16 nodeid) {
- struct ipv4_node *node;
+/* FIXME caller must take the lock, or peer needs to be reference-counted */
+/* FIXME node_id doesn't mean anything without generation */
+static struct fwnet_peer *fwnet_peer_find_by_node_id(struct fwnet_device *dev,
+ u16 node_id)
+{
+ struct fwnet_peer *p, *peer = NULL;
unsigned long flags;
- spin_lock_irqsave(&priv->lock, flags);
- list_for_each_entry(node, &priv->card->ipv4_nodes, ipv4_nodes)
- if (node->nodeid == nodeid) {
- /* FIXME: lock the node first? */
- spin_unlock_irqrestore ( &priv->lock, flags );
- fw_debug ( "node_find_by_nodeid (%x) found %p\n", nodeid, node );
- return node;
+ spin_lock_irqsave(&dev->lock, flags);
+ list_for_each_entry(p, &dev->card->peer_list, peer_link)
+ if (p->node_id == node_id) {
+ peer = p;
+ break;
}
- fw_debug ( "node_find_by_nodeid (%x) not found\n", nodeid );
- spin_unlock_irqrestore ( &priv->lock, flags );
- return NULL;
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+ return peer;
}
-/* This is only complicated because we can't assume priv exists */
-static void ipv4_node_delete ( struct fw_card *card, struct fw_device *device ) {
- struct net_device *netdev;
- struct ipv4_priv *priv;
- struct ipv4_node *node;
+/* FIXME */
+static void fwnet_peer_delete(struct fw_card *card, struct fw_device *device)
+{
+ struct net_device *net;
+ struct fwnet_device *dev;
+ struct fwnet_peer *peer;
u64 guid;
unsigned long flags;
- struct ipv4_partial_datagram *pd, *pd_next;
+ struct fwnet_partial_datagram *pd, *pd_next;
guid = (u64)device->config_rom[3] << 32 | device->config_rom[4];
- netdev = card->netdev;
- if ( netdev )
- priv = netdev_priv ( netdev );
+ net = card->netdev;
+ if (net)
+ dev = netdev_priv(net);
else
- priv = NULL;
- if ( priv )
- spin_lock_irqsave ( &priv->lock, flags );
- list_for_each_entry( node, &card->ipv4_nodes, ipv4_nodes ) {
- if ( node->guid == guid ) {
- list_del ( &node->ipv4_nodes );
- list_for_each_entry_safe( pd, pd_next, &node->pdg_list, pdg_list )
- ipv4_pd_delete ( pd );
+ dev = NULL;
+ if (dev)
+ spin_lock_irqsave(&dev->lock, flags);
+
+ list_for_each_entry(peer, &card->peer_list, peer_link) {
+ if (peer->guid == guid) {
+ list_del(&peer->peer_link);
+ list_for_each_entry_safe(pd, pd_next, &peer->pd_list,
+ pd_link)
+ fwnet_pd_delete(pd);
break;
}
}
- if ( priv )
- spin_unlock_irqrestore ( &priv->lock, flags );
+ if (dev)
+ spin_unlock_irqrestore(&dev->lock, flags);
}
-/* ------------------------------------------------------------------ */
-
-
-static int ipv4_finish_incoming_packet ( struct net_device *netdev,
- struct sk_buff *skb, u16 source_node_id, bool is_broadcast, u16 ether_type ) {
- struct ipv4_priv *priv;
- static u64 broadcast_hw = ~0ULL;
+static int fwnet_finish_incoming_packet(struct net_device *net,
+ struct sk_buff *skb, u16 source_node_id,
+ bool is_broadcast, u16 ether_type)
+{
+ struct fwnet_device *dev;
+ static const __be64 broadcast_hw = cpu_to_be64(~0ULL);
int status;