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);
+ 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);
spin_unlock_irqrestore(&priv->lock, flags);
}
+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 void ether1394_init_dev(struct net_device *dev)
{
dev->open = ether1394_open;
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->header_ops = ðer1394_header_ops;
SET_ETHTOOL_OPS(dev, ðtool_ops);
goto out;
}
- SET_MODULE_OWNER(dev);
-
- /* This used to be &host->device in Linux 2.6.20 and before. */
- SET_NETDEV_DEV(dev, host->device.parent);
+ SET_NETDEV_DEV(dev, &host->device);
priv = netdev_priv(dev);
INIT_LIST_HEAD(&priv->ip_node_list);
* 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);
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;
struct net_device *dev = neigh->dev;
/* 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);
}
}
/* 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;
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)) {
priv->stats.rx_errors++;
priv->stats.rx_dropped++;
dev_kfree_skb_any(skb);
- goto bad_proto;
- }
-
- if (netif_rx(skb) == NET_RX_DROP) {
+ } else if (netif_rx(skb) == NET_RX_DROP) {
priv->stats.rx_errors++;
priv->stats.rx_dropped++;
- goto bad_proto;
+ } else {
+ priv->stats.rx_packets++;
+ priv->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;
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,
/* Transmit a packet (called by kernel) */
static int ether1394_tx(struct sk_buff *skb, struct net_device *dev)
{
- struct eth1394hdr *eth;
+ struct eth1394hdr hdr_buf;
struct eth1394_priv *priv = netdev_priv(dev);
__be16 proto;
unsigned long flags;
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)))) {
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((u64 *)hdr_buf.h_dest);
node = eth1394_find_node_guid(&priv->ip_node_list,
be64_to_cpu(guid));
if (dest_node == (LOCAL_BUS | ALL_NODES))
goto fail;
+ /* 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;
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;