aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@linux-foundation.org>2007-10-09 01:40:57 -0700
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 16:52:52 -0700
commit3b04ddde02cf1b6f14f2697da5c20eca5715017f (patch)
tree9da1341a5a399a507b5ea6bf5a3047506b8d8f8f /drivers
parentb95cce3576813ac3f86bafa6b5daaaaf7574b0fe (diff)
[NET]: Move hardware header operations out of netdevice.
Since hardware header operations are part of the protocol class not the device instance, make them into a separate object and save memory. Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ieee1394/eth1394.c40
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c8
-rw-r--r--drivers/isdn/i4l/isdn_net.c105
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.c9
-rw-r--r--drivers/net/appletalk/cops.c20
-rw-r--r--drivers/net/appletalk/ltpc.c10
-rw-r--r--drivers/net/arcnet/arcnet.c18
-rw-r--r--drivers/net/hamradio/6pack.c13
-rw-r--r--drivers/net/hamradio/baycom_epp.c3
-rw-r--r--drivers/net/hamradio/bpqether.c3
-rw-r--r--drivers/net/hamradio/dmascc.c3
-rw-r--r--drivers/net/hamradio/hdlcdrv.c3
-rw-r--r--drivers/net/hamradio/mkiss.c14
-rw-r--r--drivers/net/hamradio/scc.c4
-rw-r--r--drivers/net/hamradio/yam.c3
-rw-r--r--drivers/net/loopback.c8
-rw-r--r--drivers/net/macvlan.c15
-rw-r--r--drivers/net/myri_sbus.c28
-rw-r--r--drivers/net/plip.c50
-rw-r--r--drivers/net/shaper.c61
-rw-r--r--drivers/net/skfp/skfddi.c1
-rw-r--r--drivers/net/wan/cycx_x25.c31
-rw-r--r--drivers/net/wan/dlci.c10
-rw-r--r--drivers/net/wan/hdlc.c10
-rw-r--r--drivers/net/wan/hdlc_cisco.c10
-rw-r--r--drivers/net/wan/hdlc_ppp.c2
-rw-r--r--drivers/net/wan/lmc/lmc_proto.c2
-rw-r--r--drivers/net/wan/syncppp.c19
-rw-r--r--drivers/net/wireless/airo.c6
-rw-r--r--drivers/net/wireless/hostap/hostap.h3
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c3
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c5
-rw-r--r--drivers/net/wireless/hostap/hostap_main.c47
-rw-r--r--drivers/net/wireless/hostap/hostap_wlan.h2
-rw-r--r--drivers/net/wireless/strip.c13
-rw-r--r--drivers/s390/net/qeth.h3
-rw-r--r--drivers/s390/net/qeth_main.c44
37 files changed, 298 insertions, 331 deletions
diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
index b31f90082e3..dc9dce22f6a 100644
--- a/drivers/ieee1394/eth1394.c
+++ b/drivers/ieee1394/eth1394.c
@@ -159,15 +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(const struct sk_buff *skb,
unsigned char *haddr);
-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);
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);
@@ -507,6 +508,14 @@ static void ether1394_reset_priv(struct net_device *dev, int set_mtu)
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;
@@ -516,11 +525,7 @@ static void ether1394_init_dev(struct net_device *dev)
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 = &ether1394_header_ops;
SET_ETHTOOL_OPS(dev, &ethtool_ops);
@@ -711,8 +716,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);
@@ -759,7 +764,8 @@ static int ether1394_header_parse(const struct sk_buff *skb,
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;
@@ -778,8 +784,8 @@ 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);
}
@@ -899,8 +905,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;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index b1c3d6cd8eb..2bd76ef5715 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -780,7 +780,7 @@ static void ipoib_timeout(struct net_device *dev)
static int ipoib_hard_header(struct sk_buff *skb,
struct net_device *dev,
unsigned short type,
- void *daddr, void *saddr, unsigned len)
+ const void *daddr, const void *saddr, unsigned len)
{
struct ipoib_header *header;
@@ -940,6 +940,10 @@ void ipoib_dev_cleanup(struct net_device *dev)
priv->tx_ring = NULL;
}
+static const struct header_ops ipoib_header_ops = {
+ .create = ipoib_hard_header,
+};
+
static void ipoib_setup(struct net_device *dev)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
@@ -950,7 +954,7 @@ static void ipoib_setup(struct net_device *dev)
dev->hard_start_xmit = ipoib_start_xmit;
dev->get_stats = ipoib_get_stats;
dev->tx_timeout = ipoib_timeout;
- dev->hard_header = ipoib_hard_header;
+ dev->header_ops = &ipoib_header_ops;
dev->set_multicast_list = ipoib_set_mcast_list;
dev->neigh_setup = ipoib_neigh_setup_dev;
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c
index aa83277aba7..54546604656 100644
--- a/drivers/isdn/i4l/isdn_net.c
+++ b/drivers/isdn/i4l/isdn_net.c
@@ -1873,54 +1873,14 @@ isdn_net_rcv_skb(int idx, struct sk_buff *skb)
return 0;
}
-static int
-my_eth_header(struct sk_buff *skb, struct net_device *dev, unsigned short type,
- void *daddr, void *saddr, unsigned len)
-{
- struct ethhdr *eth = (struct ethhdr *) skb_push(skb, ETH_HLEN);
-
- /*
- * Set the protocol type. For a packet of type ETH_P_802_3 we
- * put the length here instead. It is up to the 802.2 layer to
- * carry protocol information.
- */
-
- if (type != ETH_P_802_3)
- eth->h_proto = htons(type);
- else
- eth->h_proto = htons(len);
-
- /*
- * Set the source hardware address.
- */
- if (saddr)
- memcpy(eth->h_source, saddr, dev->addr_len);
- else
- memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
-
- /*
- * Anyway, the loopback-device should never use this function...
- */
-
- if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
- memset(eth->h_dest, 0, dev->addr_len);
- return ETH_HLEN /*(dev->hard_header_len)*/;
- }
- if (daddr) {
- memcpy(eth->h_dest, daddr, dev->addr_len);
- return ETH_HLEN /*dev->hard_header_len*/;
- }
- return -ETH_HLEN /*dev->hard_header_len*/;
-}
-
/*
* build an header
* depends on encaps that is being used.
*/
-static int
-isdn_net_header(struct sk_buff *skb, struct net_device *dev, unsigned short type,
- void *daddr, void *saddr, unsigned plen)
+static int isdn_net_header(struct sk_buff *skb, struct net_device *dev,
+ unsigned short type,
+ const void *daddr, const void *saddr, unsigned plen)
{
isdn_net_local *lp = dev->priv;
unsigned char *p;
@@ -1928,7 +1888,7 @@ isdn_net_header(struct sk_buff *skb, struct net_device *dev, unsigned short type
switch (lp->p_encap) {
case ISDN_NET_ENCAP_ETHER:
- len = my_eth_header(skb, dev, type, daddr, saddr, plen);
+ len = eth_header(skb, dev, type, daddr, saddr, plen);
break;
#ifdef CONFIG_ISDN_PPP
case ISDN_NET_ENCAP_SYNCPPP:
@@ -2005,6 +1965,32 @@ isdn_net_rebuild_header(struct sk_buff *skb)
return ret;
}
+static int isdn_header_cache(const struct neighbour *neigh, struct hh_cache *hh)
+{
+ const struct net_device *dev = neigh->dev;
+ isdn_net_local *lp = dev->priv;
+
+ if (lp->p_encap == ISDN_NET_ENCAP_ETHER)
+ return eth_header_cache(neigh, hh);
+ return -1;
+}
+
+static void isdn_header_cache_update(struct hh_cache *hh,
+ const struct net_device *dev,
+ const unsigned char *haddr)
+{
+ isdn_net_local *lp = dev->priv;
+ if (lp->p_encap == ISDN_NET_ENCAP_ETHER)
+ return eth_header_cache_update(hh, dev, haddr);
+}
+
+static const struct header_ops isdn_header_ops = {
+ .create = isdn_net_header,
+ .rebuild = isdn_net_rebuild_header,
+ .cache = isdn_header_cache,
+ .cache_update = isdn_header_cache_update,
+};
+
/*
* Interface-setup. (just after registering a new interface)
*/
@@ -2012,18 +1998,12 @@ static int
isdn_net_init(struct net_device *ndev)
{
ushort max_hlhdr_len = 0;
- isdn_net_local *lp = (isdn_net_local *) ndev->priv;
- int drvidx, i;
+ int drvidx;
ether_setup(ndev);
- lp->org_hhc = ndev->hard_header_cache;
- lp->org_hcu = ndev->header_cache_update;
+ ndev->header_ops = NULL;
/* Setup the generic properties */
-
- ndev->hard_header = NULL;
- ndev->hard_header_cache = NULL;
- ndev->header_cache_update = NULL;
ndev->mtu = 1500;
ndev->flags = IFF_NOARP|IFF_POINTOPOINT;
ndev->type = ARPHRD_ETHER;
@@ -2032,9 +2012,6 @@ isdn_net_init(struct net_device *ndev)
/* for clients with MPPP maybe higher values better */
ndev->tx_queue_len = 30;
- for (i = 0; i < ETH_ALEN; i++)
- ndev->broadcast[i] = 0xff;
-
/* The ISDN-specific entries in the device structure. */
ndev->open = &isdn_net_open;
ndev->hard_start_xmit = &isdn_net_start_xmit;
@@ -2052,7 +2029,6 @@ isdn_net_init(struct net_device *ndev)
ndev->hard_header_len = ETH_HLEN + max_hlhdr_len;
ndev->stop = &isdn_net_close;
ndev->get_stats = &isdn_net_get_stats;
- ndev->rebuild_header = &isdn_net_rebuild_header;
ndev->do_ioctl = NULL;
return 0;
}
@@ -2861,21 +2837,14 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
}
if (cfg->p_encap != lp->p_encap) {
if (cfg->p_encap == ISDN_NET_ENCAP_RAWIP) {
- p->dev.hard_header = NULL;
- p->dev.hard_header_cache = NULL;
- p->dev.header_cache_update = NULL;
+ p->dev.header_ops = NULL;
p->dev.flags = IFF_NOARP|IFF_POINTOPOINT;
} else {
- p->dev.hard_header = isdn_net_header;
- if (cfg->p_encap == ISDN_NET_ENCAP_ETHER) {
- p->dev.hard_header_cache = lp->org_hhc;
- p->dev.header_cache_update = lp->org_hcu;
+ p->dev.header_ops = &isdn_header_ops;
+ if (cfg->p_encap == ISDN_NET_ENCAP_ETHER)
p->dev.flags = IFF_BROADCAST | IFF_MULTICAST;
- } else {
- p->dev.hard_header_cache = NULL;
- p->dev.header_cache_update = NULL;
+ else
p->dev.flags = IFF_NOARP|IFF_POINTOPOINT;
- }
}
}
lp->p_encap = cfg->p_encap;
@@ -3127,8 +3096,6 @@ isdn_net_realrm(isdn_net_dev * p, isdn_net_dev * q)
((isdn_net_local *) (p->local->master->priv))->slave = p->local->slave;
} else {
/* Unregister only if it's a master-device */
- p->dev.hard_header_cache = p->local->org_hhc;
- p->dev.header_cache_update = p->local->org_hcu;
unregister_netdev(&p->dev);
}
/* Unlink device from chain */
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
index bdd797071cb..06800e5a077 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -1225,10 +1225,17 @@ static struct net_device_stats * dvb_net_get_stats(struct net_device *dev)
return &((struct dvb_net_priv*) dev->priv)->stats;
}
+static const struct header_ops dvb_header_ops = {
+ .create = eth_header,
+ .parse = eth_header_parse,
+ .rebuild = eth_rebuild_header,
+};
+
static void dvb_net_setup(struct net_device *dev)
{
ether_setup(dev);
+ dev->header_ops = &dvb_header_ops;
dev->open = dvb_net_open;
dev->stop = dvb_net_stop;
dev->hard_start_xmit = dvb_net_tx;
@@ -1237,7 +1244,7 @@ static void dvb_net_setup(struct net_device *dev)
dev->set_mac_address = dvb_net_set_mac;
dev->mtu = 4096;
dev->mc_count = 0;
- dev->hard_header_cache = NULL;
+
dev->flags |= IFF_NOARP;
}
diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c
index c4b560d42a6..92c3a4cf0bb 100644
--- a/drivers/net/appletalk/cops.c
+++ b/drivers/net/appletalk/cops.c
@@ -194,10 +194,6 @@ static void cops_timeout(struct net_device *dev);
static void cops_rx (struct net_device *dev);
static int cops_send_packet (struct sk_buff *skb, struct net_device *dev);
static void set_multicast_list (struct net_device *dev);
-static int cops_hard_header (struct sk_buff *skb, struct net_device *dev,
- unsigned short type, void *daddr, void *saddr,
- unsigned len);
-
static int cops_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
static int cops_close (struct net_device *dev);
static struct net_device_stats *cops_get_stats (struct net_device *dev);
@@ -331,7 +327,6 @@ static int __init cops_probe1(struct net_device *dev, int ioaddr)
dev->base_addr = ioaddr;
lp = netdev_priv(dev);
- memset(lp, 0, sizeof(struct cops_local));
spin_lock_init(&lp->lock);
/* Copy local board variable to lp struct. */
@@ -340,7 +335,7 @@ static int __init cops_probe1(struct net_device *dev, int ioaddr)
dev->hard_start_xmit = cops_send_packet;
dev->tx_timeout = cops_timeout;
dev->watchdog_timeo = HZ * 2;
- dev->hard_header = cops_hard_header;
+
dev->get_stats = cops_get_stats;
dev->open = cops_open;
dev->stop = cops_close;
@@ -945,19 +940,6 @@ static void set_multicast_list(struct net_device *dev)
}
/*
- * Another Dummy function to keep the Appletalk layer happy.
- */
-
-static int cops_hard_header(struct sk_buff *skb, struct net_device *dev,
- unsigned short type, void *daddr, void *saddr,
- unsigned len)
-{
- if(cops_debug >= 3)
- printk("%s: cops_hard_header executed. Wow!\n", dev->name);
- return 0;
-}
-
-/*
* System ioctls for the COPS LocalTalk card.
*/
diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c
index cb4744e5690..6ab2c2d4d67 100644
--- a/drivers/net/appletalk/ltpc.c
+++ b/drivers/net/appletalk/ltpc.c
@@ -870,15 +870,6 @@ static void set_multicast_list(struct net_device *dev)
/* Actually netatalk needs fixing! */
}
-static int ltpc_hard_header (struct sk_buff *skb, struct net_device *dev,
- unsigned short type, void *daddr, void *saddr, unsigned len)
-{
- if(debug & DEBUG_VERBOSE)
- printk("ltpc_hard_header called for device %s\n",
- dev->name);
- return 0;
-}
-
static int ltpc_poll_counter;
static void ltpc_poll(unsigned long l)
@@ -1141,7 +1132,6 @@ struct net_device * __init ltpc_probe(void)
/* Fill in the fields of the device structure with ethernet-generic values. */
dev->hard_start_xmit = ltpc_xmit;
- dev->hard_header = ltpc_hard_header;
dev->get_stats = ltpc_get_stats;
/* add the ltpc-specific things */
diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
index 681e20b8466..c59c8067de9 100644
--- a/drivers/net/arcnet/arcnet.c
+++ b/drivers/net/arcnet/arcnet.c
@@ -102,8 +102,8 @@ static int arcnet_close(struct net_device *dev);
static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev);
static void arcnet_timeout(struct net_device *dev);
static int arcnet_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 arcnet_rebuild_header(struct sk_buff *skb);
static struct net_device_stats *arcnet_get_stats(struct net_device *dev);
static int go_tx(struct net_device *dev);
@@ -317,11 +317,17 @@ static int choose_mtu(void)
return mtu == 65535 ? XMTU : mtu;
}
+static const struct header_ops arcnet_header_ops = {
+ .create = arcnet_header,
+ .rebuild = arcnet_rebuild_header,
+};
+
/* Setup a struct device for ARCnet. */
static void arcdev_setup(struct net_device *dev)
{
dev->type = ARPHRD_ARCNET;
+ dev->header_ops = &arcnet_header_ops;
dev->hard_header_len = sizeof(struct archdr);
dev->mtu = choose_mtu();
@@ -342,8 +348,6 @@ static void arcdev_setup(struct net_device *dev)
dev->hard_start_xmit = arcnet_send_packet;
dev->tx_timeout = arcnet_timeout;
dev->get_stats = arcnet_get_stats;
- dev->hard_header = arcnet_header;
- dev->rebuild_header = arcnet_rebuild_header;
}
struct net_device *alloc_arcdev(char *name)
@@ -488,10 +492,10 @@ static int arcnet_close(struct net_device *dev)
static int arcnet_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 arcnet_local *lp = dev->priv;
+ const struct arcnet_local *lp = netdev_priv(dev);
uint8_t _daddr, proto_num;
struct ArcProto *proto;
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 0a847326a5e..ecd156def03 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -288,7 +288,8 @@ static int sp_close(struct net_device *dev)
/* Return the frame type ID */
static int sp_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)
{
#ifdef CONFIG_INET
if (type != htons(ETH_P_AX25))
@@ -323,6 +324,11 @@ static int sp_rebuild_header(struct sk_buff *skb)
#endif
}
+static const struct header_ops sp_header_ops = {
+ .create = sp_header,
+ .rebuild = sp_rebuild_header,
+};
+
static void sp_setup(struct net_device *dev)
{
/* Finish setting up the DEVICE info. */
@@ -331,14 +337,15 @@ static void sp_setup(struct net_device *dev)
dev->open = sp_open_dev;
dev->destructor = free_netdev;
dev->stop = sp_close;
- dev->hard_header = sp_header;
+
dev->get_stats = sp_get_stats;
dev->set_mac_address = sp_set_mac_address;
dev->hard_header_len = AX25_MAX_HEADER_LEN;
+ dev->header_ops = &sp_header_ops;
+
dev->addr_len = AX25_ADDR_LEN;
dev->type = ARPHRD_AX25;
dev->tx_queue_len = 10;
- dev->rebuild_header = sp_rebuild_header;
dev->tx_timeout = NULL;
/* Only activated in AX.25 mode */
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
index 355c6cf3d11..1a5a75acf73 100644
--- a/drivers/net/hamradio/baycom_epp.c
+++ b/drivers/net/hamradio/baycom_epp.c
@@ -1159,8 +1159,7 @@ static void baycom_probe(struct net_device *dev)
/* Fill in the fields of the device structure */
bc->skb = NULL;
- dev->hard_header = ax25_hard_header;
- dev->rebuild_header = ax25_rebuild_header;
+ dev->header_ops = &ax25_header_ops;
dev->set_mac_address = baycom_set_mac_address;
dev->type = ARPHRD_AX25; /* AF_AX25 device */
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index 4bff23e3b97..5ddf8b0c34f 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -483,8 +483,7 @@ static void bpq_setup(struct net_device *dev)
dev->flags = 0;
#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
- dev->hard_header = ax25_hard_header;
- dev->rebuild_header = ax25_rebuild_header;
+ dev->header_ops = &ax25_header_ops;
#endif
dev->type = ARPHRD_AX25;
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c
index 205f0967249..bc02e469480 100644
--- a/drivers/net/hamradio/dmascc.c
+++ b/drivers/net/hamradio/dmascc.c
@@ -581,8 +581,7 @@ static int __init setup_adapter(int card_base, int type, int n)
dev->do_ioctl = scc_ioctl;
dev->hard_start_xmit = scc_send_packet;
dev->get_stats = scc_get_stats;
- dev->hard_header = ax25_hard_header;
- dev->rebuild_header = ax25_rebuild_header;
+ dev->header_ops = &ax25_header_ops;
dev->set_mac_address = scc_set_mac_address;
}
if (register_netdev(info->dev[0])) {
diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c
index b33adc6a340..ae9629fa688 100644
--- a/drivers/net/hamradio/hdlcdrv.c
+++ b/drivers/net/hamradio/hdlcdrv.c
@@ -682,8 +682,7 @@ static void hdlcdrv_setup(struct net_device *dev)
s->skb = NULL;
- dev->hard_header = ax25_hard_header;
- dev->rebuild_header = ax25_rebuild_header;
+ dev->header_ops = &ax25_header_ops;
dev->set_mac_address = hdlcdrv_set_mac_address;
dev->type = ARPHRD_AX25; /* AF_AX25 device */
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index d08fbc39664..9e43c47691c 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -578,8 +578,9 @@ static int ax_open_dev(struct net_device *dev)
#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
/* Return the frame type ID */
-static int ax_header(struct sk_buff *skb, struct net_device *dev, unsigned short type,
- void *daddr, void *saddr, unsigned len)
+static int ax_header(struct sk_buff *skb, struct net_device *dev,
+ unsigned short type, const void *daddr,
+ const void *saddr, unsigned len)
{
#ifdef CONFIG_INET
if (type != htons(ETH_P_AX25))
@@ -670,6 +671,11 @@ static struct net_device_stats *ax_get_stats(struct net_device *dev)
return &ax->stats;
}
+static const struct header_ops ax_header_ops = {
+ .create = ax_header,
+ .rebuild = ax_rebuild_header,
+};
+
static void ax_setup(struct net_device *dev)
{
/* Finish setting up the DEVICE info. */
@@ -683,8 +689,8 @@ static void ax_setup(struct net_device *dev)
dev->addr_len = 0;
dev->type = ARPHRD_AX25;
dev->tx_queue_len = 10;
- dev->hard_header = ax_header;
- dev->rebuild_header = ax_rebuild_header;
+ dev->header_ops = &ax_header_ops;
+
memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
memcpy(dev->dev_addr, &ax25_defaddr, AX25_ADDR_LEN);
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
index 39b3b82aa4a..353d13e543c 100644
--- a/drivers/net/hamradio/scc.c
+++ b/drivers/net/hamradio/scc.c
@@ -1551,8 +1551,8 @@ static void scc_net_setup(struct net_device *dev)
dev->stop = scc_net_close;
dev->hard_start_xmit = scc_net_tx;
- dev->hard_header = ax25_hard_header;
- dev->rebuild_header = ax25_rebuild_header;
+ dev->header_ops = &ax25_header_ops;
+
dev->set_mac_address = scc_net_set_mac_address;
dev->get_stats = scc_net_get_stats;
dev->do_ioctl = scc_net_ioctl;
diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c
index 401724ddafc..1c942862a3f 100644
--- a/drivers/net/hamradio/yam.c
+++ b/drivers/net/hamradio/yam.c
@@ -1097,8 +1097,7 @@ static void yam_setup(struct net_device *dev)
skb_queue_head_init(&yp->send_queue);
- dev->hard_header = ax25_hard_header;
- dev->rebuild_header = ax25_rebuild_header;
+ dev->header_ops = &ax25_header_ops;
dev->set_mac_address = yam_set_mac_address;
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index f11120b7a3b..b6d4ae3ad50 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -221,22 +221,17 @@ static void loopback_dev_free(struct net_device *dev)
}
/*
- * The loopback device is special. There is only one instance and
- * it is statically allocated. Don't do this for other devices.
+ * The loopback device is special. There is only one instance.
*/
static void loopback_setup(struct net_device *dev)
{
dev->get_stats = &get_stats;
dev->mtu = (16 * 1024) + 20 + 20 + 12;
dev->hard_start_xmit = loopback_xmit;
- dev->hard_header = eth_header;
- dev->hard_header_cache = eth_header_cache;
- dev->header_cache_update = eth_header_cache_update;
dev->hard_header_len = ETH_HLEN; /* 14 */
dev->addr_len = ETH_ALEN; /* 6 */
dev->tx_queue_len = 0;
dev->type = ARPHRD_LOOPBACK; /* 0x0001*/
- dev->rebuild_header = eth_rebuild_header;
dev->flags = IFF_LOOPBACK;
dev->features = NETIF_F_SG | NETIF_F_FRAGLIST
#ifdef LOOPBACK_TSO
@@ -247,6 +242,7 @@ static void loopback_setup(struct net_device *dev)
| NETIF_F_LLTX
| NETIF_F_NETNS_LOCAL,
dev->ethtool_ops = &loopback_ethtool_ops;
+ dev->header_ops = &eth_header_ops;
dev->init = loopback_dev_init;
dev->destructor = loopback_dev_free;
}
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index a22087ca968..b7c81c874f7 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -164,8 +164,8 @@ static int macvlan_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
static int macvlan_hard_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)
{
const struct macvlan_dev *vlan = netdev_priv(dev);
struct net_device *lowerdev = vlan->lowerdev;
@@ -174,6 +174,15 @@ static int macvlan_hard_header(struct sk_buff *skb, struct net_device *dev,
saddr ? : dev->dev_addr, len);
}
+static const struct header_ops macvlan_hard_header_ops = {
+ .create = macvlan_hard_header,
+ .rebuild = eth_rebuild_header,
+ .parse = eth_header_parse,
+ .rebuild = eth_rebuild_header,
+ .cache = eth_header_cache,
+ .cache_update = eth_header_cache_update,
+};
+
static int macvlan_open(struct net_device *dev)
{
struct macvlan_dev *vlan = netdev_priv(dev);
@@ -295,9 +304,9 @@ static void macvlan_setup(struct net_device *dev)
dev->change_mtu = macvlan_change_mtu;
dev->change_rx_flags = macvlan_change_rx_flags;
dev->set_multicast_list = macvlan_set_multicast_list;
- dev->hard_header = macvlan_hard_header;
dev->hard_start_xmit = macvlan_hard_start_xmit;
dev->destructor = free_netdev;
+ dev->header_ops = &macvlan_hard_header_ops,
dev->ethtool_ops = &macvlan_ethtool_ops;
dev->tx_queue_len = 0;
}
diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c
index d68ee51c095..8d29319cc5c 100644
--- a/drivers/net/myri_sbus.c
+++ b/drivers/net/myri_sbus.c
@@ -676,8 +676,9 @@ static int myri_start_xmit(struct sk_buff *skb, struct net_device *dev)
* saddr=NULL means use device source address
* daddr=NULL means leave destination address (eg unresolved arp)
*/
-static int myri_header(struct sk_buff *skb, struct net_device *dev, unsigned short type,
- void *daddr, void *saddr, unsigned len)
+static int myri_header(struct sk_buff *skb, struct net_device *dev,
+ unsigned short type, const void *daddr,
+ const void *saddr, unsigned len)
{
struct ethhdr *eth = (struct ethhdr *) skb_push(skb, ETH_HLEN);
unsigned char *pad = (unsigned char *) skb_push(skb, MYRI_PAD_LEN);
@@ -759,18 +760,18 @@ static int myri_rebuild_header(struct sk_buff *skb)
return 0;
}
-int myri_header_cache(struct neighbour *neigh, struct hh_cache *hh)
+static int myri_header_cache(const struct neighbour *neigh, struct hh_cache *hh)
{
unsigned short type = hh->hh_type;
unsigned char *pad;
struct ethhdr *eth;
- struct net_device *dev = neigh->dev;
+ const struct net_device *dev = neigh->dev;
pad = ((unsigned char *) hh->hh_data) +
HH_DATA_OFF(sizeof(*eth) + MYRI_PAD_LEN);
eth = (struct ethhdr *) (pad + MYRI_PAD_LEN);
- if (type == __constant_htons(ETH_P_802_3))
+ if (type == htons(ETH_P_802_3))
return -1;
/* Refill MyriNet padding identifiers, this is just being anal. */
@@ -786,7 +787,9 @@ int myri_header_cache(struct neighbour *neigh, struct hh_cache *hh)
/* Called by Address Resolution module to notify changes in address. */
-void myri_header_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr)
+void myri_header_cache_update(struct hh_cache *hh,
+ const struct net_device *dev,
+ const unsigned char * haddr)
{
memcpy(((u8*)hh->hh_data) + HH_DATA_OFF(sizeof(struct ethhdr)),
haddr, dev->addr_len);
@@ -881,6 +884,13 @@ static void dump_eeprom(struct myri_eth *mp)
}
#endif
+static const struct header_ops myri_header_ops = {
+ .create = myri_header,
+ .rebuild = myri_rebuild_header,
+ .cache = myri_header_cache,
+ .cache_update = myri_header_cache_update,
+};
+
static int __devinit myri_ether_init(struct sbus_dev *sdev)
{
static int num;
@@ -1065,11 +1075,9 @@ static int __devinit myri_ether_init(struct sbus_dev *sdev)
dev->mtu = MYRINET_MTU;
dev->change_mtu = myri_change_mtu;
- dev->hard_header = myri_header;
- dev->rebuild_header = myri_rebuild_header;
+ dev->header_ops = &myri_header_ops;
+
dev->hard_header_len = (ETH_HLEN + MYRI_PAD_LEN);
- dev->hard_header_cache = myri_header_cache;
- dev->header_cache_update= myri_header_cache_update;
/* Load code onto the LANai. */
DET(("Loading LANAI firmware\n"));
diff --git a/drivers/net/plip.c b/drivers/net/plip.c
index c17d9ac9ff3..b5e9981d106 100644
--- a/drivers/net/plip.c
+++ b/drivers/net/plip.c
@@ -148,9 +148,9 @@ static void plip_interrupt(int irq, void *dev_id);
/* Functions for DEV methods */
static int plip_tx_packet(struct sk_buff *skb, struct net_device *dev);
static int plip_hard_header(struct sk_buff *skb, struct net_device *dev,
- unsigned short type, void *daddr,
- void *saddr, unsigned len);
-static int plip_hard_header_cache(struct neighbour *neigh,
+ unsigned short type, const void *daddr,
+ const void *saddr, unsigned len);
+static int plip_hard_header_cache(const struct neighbour *neigh,
struct hh_cache *hh);
static int plip_open(struct net_device *dev);
static int plip_close(struct net_device *dev);
@@ -219,11 +219,6 @@ struct net_local {
int is_deferred;
int port_owner;
int should_relinquish;
- int (*orig_hard_header)(struct sk_buff *skb, struct net_device *dev,
- unsigned short type, void *daddr,
- void *saddr, unsigned len);
- int (*orig_hard_header_cache)(struct neighbour *neigh,
- struct hh_cache *hh);
spinlock_t lock;
atomic_t kill_timer;
struct semaphore killed_timer_sem;
@@ -265,6 +260,11 @@ static inline unsigned char read_status (struct net_device *dev)
return port->ops->read_status (port);
}
+static const struct header_ops plip_header_ops = {
+ .create = plip_hard_header,
+ .cache = plip_hard_header_cache,
+};
+
/* Entry point of PLIP driver.
Probe the hardware, and register/initialize the driver.
@@ -284,17 +284,12 @@ plip_init_netdev(struct net_device *dev)
dev->open = plip_open;
dev->stop = plip_close;
dev->do_ioctl = plip_ioctl;
- dev->header_cache_update = NULL;
+
dev->tx_queue_len = 10;
dev->flags = IFF_POINTOPOINT|IFF_NOARP;
memset(dev->dev_addr, 0xfc, ETH_ALEN);
- /* Set the private structure */
- nl->orig_hard_header = dev->hard_header;
- dev->hard_header = plip_hard_header;
-
- nl->orig_hard_header_cache = dev->hard_header_cache;
- dev->hard_header_cache = plip_hard_header_cache;
+ dev->header_ops = &plip_header_ops;
nl->port_owner = 0;
@@ -993,14 +988,14 @@ plip_tx_packet(struct sk_buff *skb, struct net_device *dev)
}
static void
-plip_rewrite_address(struct net_device *dev, struct ethhdr *eth)
+plip_rewrite_address(const struct net_device *dev, struct ethhdr *eth)
{
- struct in_device *in_dev;
+ const struct in_device *in_dev = dev->ip_ptr;
- if ((in_dev=dev->ip_ptr) != NULL) {
+ if (in_dev) {
/* Any address will do - we take the first */
- struct in_ifaddr *ifa=in_dev->ifa_list;
- if (ifa != NULL) {
+ const struct in_ifaddr *ifa = in_dev->ifa_list;
+ if (ifa) {
memcpy(eth->h_source, dev->dev_addr, 6);
memset(eth->h_dest, 0xfc, 2);
memcpy(eth->h_dest+2, &ifa->ifa_address, 4);
@@ -1010,26 +1005,25 @@ plip_rewrite_address(struct net_device *dev, struct ethhdr *eth)
static int
plip_hard_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 net_local *nl = netdev_priv(dev);
int ret;
- if ((ret = nl->orig_hard_header(skb, dev, type, daddr, saddr, len)) >= 0)
+ ret = eth_header(skb, dev, type, daddr, saddr, len);
+ if (ret >= 0)
plip_rewrite_address (dev, (struct ethhdr *)skb->data);
return ret;
}
-int plip_hard_header_cache(struct neighbour *neigh,
+int plip_hard_header_cache(const struct neighbour *neigh,
struct hh_cache *hh)
{
- struct net_local *nl = neigh->dev->priv;
int ret;
- if ((ret = nl->orig_hard_header_cache(neigh, hh)) == 0)
- {
+ ret = eth_header_cache(neigh, hh);
+ if (ret == 0) {
struct ethhdr *eth;
eth = (struct ethhdr*)(((u8*)hh->hh_data) +
diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c
index 315feba7dac..228f650250f 100644
--- a/drivers/net/shaper.c
+++ b/drivers/net/shaper.c
@@ -331,15 +331,16 @@ static int shaper_close(struct net_device *dev)
*/
static int shaper_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 shaper *sh=dev->priv;
int v;
if(sh_debug)
printk("Shaper header\n");
- skb->dev=sh->dev;
- v=sh->hard_header(skb,sh->dev,type,daddr,saddr,len);
- skb->dev=dev;
+ skb->dev = sh->dev;
+ v = dev_hard_header(skb, sh->dev, type, daddr, saddr, len);
+ skb->dev = dev;
return v;
}
@@ -351,7 +352,7 @@ static int shaper_rebuild_header(struct sk_buff *skb)
if(sh_debug)
printk("Shaper rebuild header\n");
skb->dev=sh->dev;
- v=sh->rebuild_header(skb);
+ v = sh->dev->header_ops->rebuild(skb);
skb->dev=dev;
return v;
}
@@ -415,51 +416,17 @@ static int shaper_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p)
#endif
+static const struct header_ops shaper_ops = {
+ .create = shaper_header,
+ .rebuild = shaper_rebuild_header,
+};
+
static int shaper_attach(struct net_device *shdev, struct shaper *sh, struct net_device *dev)
{
sh->dev = dev;
- sh->hard_start_xmit=dev->hard_start_xmit;
sh->get_stats=dev->get_stats;
- if(dev->hard_header)
- {
- sh->hard_header=dev->hard_header;
- shdev->hard_header = shaper_header;
- }
- else
- shdev->hard_header = NULL;
- if(dev->rebuild_header)
- {
- sh->rebuild_header = dev->rebuild_header;
- shdev->rebuild_header = shaper_rebuild_header;
- }
- else
- shdev->rebuild_header = NULL;
-
-#if 0
- if(dev->hard_header_cache)
- {
- sh->hard_header_cache = dev->hard_header_cache;
- shdev->hard_header_cache= shaper_cache;
- }
- else
- {
- shdev->hard_header_cache= NULL;
- }
-
- if(dev->header_cache_update)
- {
- sh->header_cache_update = dev->header_cache_update;
- shdev->header_cache_update = shaper_cache_update;
- }
- else
- shdev->header_cache_update= NULL;
-#else
- shdev->header_cache_update = NULL;
- shdev->hard_header_cache = NULL;
-#endif
shdev->neigh_setup = shaper_neigh_setup_dev;
-
shdev->hard_header_len=dev->hard_header_len;
shdev->type=dev->type;
shdev->addr_len=dev->addr_len;
@@ -542,12 +509,6 @@ static void __init shaper_setup(struct net_device *dev)
* Handlers for when we attach to a device.
*/
- dev->hard_header = shaper_header;
- dev->rebuild_header = shaper_rebuild_header;
-#if 0
- dev->hard_header_cache = shaper_cache;
- dev->header_cache_update= shaper_cache_update;
-#endif
dev->neigh_setup = shaper_neigh_setup_dev;
dev->do_ioctl = shaper_ioctl;
dev->hard_header_len = 0;
diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c
index ca508708229..7cf9b9f35de 100644
--- a/drivers/net/skfp/skfddi.c
+++ b/drivers/net/skfp/skfddi.c
@@ -260,7 +260,6 @@ static int skfp_init_one(struct pci_dev *pdev,
dev->set_multicast_list = &skfp_ctl_set_multicast_list;
dev->set_mac_address = &skfp_ctl_set_mac_address;
dev->do_ioctl = &skfp_ioctl;
- dev->header_cache_update = NULL; /* not supported */
SET_NETDEV_DEV(dev, &pdev->dev);
diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c
index 46e053106d4..8a1778cf98d 100644
--- a/drivers/net/wan/cycx_x25.c
+++ b/drivers/net/wan/cycx_x25.c
@@ -131,14 +131,15 @@ static int cycx_wan_update(struct wan_device *wandev),
cycx_wan_del_if(struct wan_device *wandev, struct net_device *dev);
/* Network device interface */
-static int cycx_netdevice_init(struct net_device *dev),
- cycx_netdevice_open(struct net_device *dev),
- cycx_netdevice_stop(struct net_device *dev),
- cycx_netdevice_hard_header(struct sk_buff *skb,
- struct net_device *dev, u16 type,
- void *daddr, void *saddr, unsigned len),
- cycx_netdevice_rebuild_header(struct sk_buff *skb),
- cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
+static int cycx_netdevice_init(struct net_device *dev);
+static int cycx_netdevice_open(struct net_device *dev);
+static int cycx_netdevice_stop(struct net_device *dev);
+static int cycx_netdevice_hard_header(struct sk_buff *skb,
+ struct net_device *dev, u16 type,
+ const void *daddr, const void *saddr,
+ unsigned len);
+static int cycx_netdevice_rebuild_header(struct sk_buff *skb);
+static int cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
struct net_device *dev);
static struct net_device_stats *
@@ -468,7 +469,14 @@ static int cycx_wan_del_if(struct wan_device *wandev, struct net_device *dev)
return 0;
}
+
/* Network Device Interface */
+
+static const struct header_ops cycx_header_ops = {
+ .create = cycx_netdevice_hard_header,
+ .rebuild = cycx_netdevice_rebuild_header,
+};
+
/* Initialize Linux network interface.
*
* This routine is called only once for each interface, during Linux network
@@ -483,8 +491,8 @@ static int cycx_netdevice_init(struct net_device *dev)
/* Initialize device driver entry points */
dev->open = cycx_netdevice_open;
dev->stop = cycx_netdevice_stop;
- dev->hard_header = cycx_netdevice_hard_header;
- dev->rebuild_header = cycx_netdevice_rebuild_header;
+ dev->header_ops = &cycx_header_ops;
+
dev->hard_start_xmit = cycx_netdevice_hard_start_xmit;
dev->get_stats = cycx_netdevice_get_stats;
@@ -554,7 +562,8 @@ static int cycx_netdevice_stop(struct net_device *dev)
* Return: media header length. */
static int cycx_netdevice_hard_header(struct sk_buff *skb,
struct net_device *dev, u16 type,
- void *daddr, void *saddr, unsigned len)
+ const void *daddr, const void *saddr,
+ unsigned len)
{
skb->protocol = type;
diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c
index bc12810157e..96b232446c0 100644
--- a/drivers/net/wan/dlci.c
+++ b/drivers/net/wan/dlci.c
@@ -66,8 +66,8 @@ static void dlci_setup(struct net_device *);
*/
static int dlci_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 frhdr hdr;
struct dlci_local *dlp;
@@ -485,6 +485,10 @@ static int dlci_ioctl(unsigned int cmd, void __user *arg)
return(err);
}
+static const struct header_ops dlci_header_ops = {
+ .create = dlci_header,
+};
+
static void dlci_setup(struct net_device *dev)
{
struct dlci_local *dlp = dev->priv;
@@ -494,7 +498,7 @@ static void dlci_setup(struct net_device *dev)
dev->stop = dlci_close;
dev->do_ioctl = dlci_dev_ioctl;
dev->hard_start_xmit = dlci_transmit;
- dev->hard_header = dlci_header;
+ dev->header_ops = &dlci_header_ops;
dev->get_stats = dlci_get_stats;
dev->change_mtu = dlci_change_mtu;
dev->destructor = free_netdev;
diff --git a/drivers/net/wan/hdlc.c b/drivers/net/wan/hdlc.c
index ee23b91f23d..d553e6f3285 100644
--- a/drivers/net/wan/hdlc.c
+++ b/drivers/net/wan/hdlc.c
@@ -232,6 +232,8 @@ int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return -EINVAL;
}
+static const struct header_ops hdlc_null_ops;
+
static void hdlc_setup_dev(struct net_device *dev)
{
/* Re-init all variables changed by HDLC protocol drivers,
@@ -243,13 +245,9 @@ static void hdlc_setup_dev(struct net_device *dev)
dev->type = ARPHRD_RAWHDLC;
dev->hard_header_len = 16;
dev->addr_len = 0;
- dev->hard_header = NULL;
- dev->rebuild_header = NULL;
- dev->set_mac_address = NULL;
- dev->hard_header_cache = NULL;
- dev->header_cache_update = NULL;
+ dev->header_ops = &hdlc_null_ops;
+
dev->change_mtu = hdlc_change_mtu;
- dev->hard_header_parse = NULL;
}
static void hdlc_setup(struct net_device *dev)
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index 9ec6cf2e510..038a6e748bb 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -74,7 +74,7 @@ static inline struct cisco_state * state(hdlc_device *hdlc)
static int cisco_hard_header(struct sk_buff *skb, struct net_device *dev,
- u16 type, void *daddr, void *saddr,
+ u16 type, const void *daddr, const void *saddr,
unsigned int len)
{
struct hdlc_header *data;
@@ -309,7 +309,6 @@ static void cisco_stop(struct net_device *dev)
}
-
static struct hdlc_proto proto = {
.start = cisco_start,
.stop = cisco_stop,
@@ -317,7 +316,10 @@ static struct hdlc_proto proto = {
.ioctl = cisco_ioctl,
.module = THIS_MODULE,
};
-
+
+static const struct header_ops cisco_header_ops = {
+ .create = cisco_hard_header,
+};
static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr)
{
@@ -365,7 +367,7 @@ static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr)
memcpy(&state(hdlc)->settings, &new_settings, size);
dev->hard_start_xmit = hdlc->xmit;
- dev->hard_header = cisco_hard_header;
+ dev->header_ops = &cisco_header_ops;
dev->type = ARPHRD_CISCO;
netif_dormant_on(dev);
return 0;
diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c
index 4591437dd2f..3caeb528eac 100644
--- a/drivers/net/wan/hdlc_ppp.c
+++ b/drivers/net/wan/hdlc_ppp.c
@@ -73,7 +73,7 @@ static void ppp_close(struct net_device *dev)
sppp_close(dev);
sppp_detach(dev);
- dev->rebuild_header = NULL;
+
dev->change_mtu = state(hdlc)->old_change_mtu;
dev->mtu = HDLC_MAX_MTU;
dev->hard_header_len = 16;
diff --git a/drivers/net/wan/lmc/lmc_proto.c b/drivers/net/wan/lmc/lmc_proto.c
index 31e1799571a..426c0678d98 100644
--- a/drivers/net/wan/lmc/lmc_proto.c
+++ b/drivers/net/wan/lmc/lmc_proto.c
@@ -111,7 +111,7 @@ void lmc_proto_attach(lmc_softc_t *sc) /*FOLD00*/
* They set a few basics because they don't use sync_ppp
*/
dev->flags |= IFF_POINTOPOINT;
- dev->hard_header = NULL;
+
dev->hard_header_len = 0;
dev->addr_len = 0;
}
diff --git a/drivers/net/wan/syncppp.c b/drivers/net/wan/syncppp.c
index 5c71af6ea3a..232ecba5340 100644
--- a/drivers/net/wan/syncppp.c
+++ b/drivers/net/wan/syncppp.c
@@ -359,8 +359,10 @@ done:
* Handle transmit packets.
*/
-static int sppp_hard_header(struct sk_buff *skb, struct net_device *dev, __u16 type,
- void *daddr, void *saddr, unsigned int len)
+static int sppp_hard_header(struct sk_buff *skb,
+ struct net_device *dev, __u16 type,
+ const void *daddr, const void *saddr,
+ unsigned int len)
{
struct sppp *sp = (struct sppp *)sppp_of(dev);
struct ppp_header *h;
@@ -392,10 +394,9 @@ static int sppp_hard_header(struct sk_buff *skb, struct net_device *dev, __u16 t
return sizeof(struct ppp_header);
}
-static int sppp_rebuild_header(struct sk_buff *skb)
-{
- return 0;
-}
+static const struct header_ops sppp_header_ops = {
+ .create = sppp_hard_header,
+};
/*
* Send keepalive packets, every 10 seconds.
@@ -1098,8 +1099,8 @@ void sppp_attach(struct ppp_device *pd)
* hard_start_xmit.
*/
- dev->hard_header = sppp_hard_header;
- dev->rebuild_header = sppp_rebuild_header;
+ dev->header_ops = &sppp_header_ops;
+
dev->tx_queue_len = 10;
dev->type = ARPHRD_HDLC;
dev->addr_len = 0;
@@ -1115,8 +1116,6 @@ void sppp_attach(struct ppp_device *pd)
dev->stop = sppp_close;
#endif
dev->change_mtu = sppp_change_mtu;
- dev->hard_header_cache = NULL;
- dev->header_cache_update = NULL;
dev->flags = IFF_MULTICAST|IFF_POINTOPOINT|IFF_NOARP;
}
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index cd03a61359a..074055e18c5 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -2696,9 +2696,13 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci)
return rc;
}
+static const struct header_ops airo_header_ops = {
+ .parse = wll_header_parse,
+};
+
static void wifi_setup(struct net_device *dev)
{
- dev->hard_header_parse = wll_header_parse;
+ dev->header_ops = &airo_header_ops;
dev->hard_start_xmit = &airo_start_xmit11;
dev->get_stats = &airo_get_stats;
dev->set_mac_address = &airo_set_mac_address;
diff --git a/drivers/net/wireless/hostap/hostap.h b/drivers/net/wireless/hostap/hostap.h
index ef37a75d550..951df83702f 100644
--- a/drivers/net/wireless/hostap/hostap.h
+++ b/drivers/net/wireless/hostap/hostap.h
@@ -30,8 +30,7 @@ void hostap_dump_rx_header(const char *name,
const struct hfa384x_rx_frame *rx);
void hostap_dump_tx_header(const char *name,
const struct hfa384x_tx_frame *tx);
-int hostap_80211_header_parse(struct sk_buff *skb, unsigned char *haddr);
-int hostap_80211_prism_header_parse(struct sk_buff *skb, unsigned char *haddr);
+extern const struct header_ops hostap_80211_ops;
int hostap_80211_get_hdrlen(u16 fc);
struct net_device_stats *hostap_get_stats(struct net_device *dev);
void hostap_setup_dev(struct net_device *dev, local_info_t *local,
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index 7fa7ab0a4b2..b20bb013d57 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -3258,11 +3258,10 @@ while (0)
INIT_LIST_HEAD(&local->bss_list);
hostap_setup_dev(dev, local, 1);
- local->saved_eth_header_parse = dev->hard_header_parse;
dev->hard_start_xmit = hostap_master_start_xmit;
dev->type = ARPHRD_IEEE80211;
- dev->hard_header_parse = hostap_80211_header_parse;
+ dev->header_ops = &hostap_80211_ops;
rtnl_lock();
ret = dev_alloc_name(dev, "wifi%d");
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index 7036ecff5ec..40f516d42c5 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -897,11 +897,8 @@ static void hostap_monitor_set_type(local_info_t *local)
if (local->monitor_type == PRISM2_MONITOR_PRISM ||
local->monitor_type == PRISM2_MONITOR_CAPHDR) {
dev->type = ARPHRD_IEEE80211_PRISM;
- dev->hard_header_parse =
- hostap_80211_prism_header_parse;
} else {
dev->type = ARPHRD_IEEE80211;
- dev->hard_header_parse = hostap_80211_header_parse;
}
}
@@ -1141,7 +1138,7 @@ static int hostap_monitor_mode_disable(local_info_t *local)
printk(KERN_DEBUG "%s: Disabling monitor mode\n", dev->name);
dev->type = ARPHRD_ETHER;
- dev->hard_header_parse = local->saved_eth_header_parse;
+
if (local->func->cmd(dev, HFA384X_CMDCODE_TEST |
(HFA384X_TEST_STOP << 8),
0, NULL, NULL))
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c
index 4cb09d81b40..b75cf9205ce 100644
--- a/drivers/net/wireless/hostap/hostap_main.c
+++ b/drivers/net/wireless/hostap/hostap_main.c
@@ -594,24 +594,27 @@ void hostap_dump_tx_header(const char *name, const struct hfa384x_tx_frame *tx)
}
-int hostap_80211_header_parse(struct sk_buff *skb, unsigned char *haddr)
+int hostap_80211_header_parse(const struct sk_buff *skb, unsigned char *haddr)
{
- memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); /* addr2 */
- return ETH_ALEN;
-}
-
+ struct hostap_interface *iface = netdev_priv(skb->dev);
+ local_info_t *local = iface->local;
+
+ if (local->monitor_type == PRISM2_MONITOR_PRISM ||
+ local->monitor_type == PRISM2_MONITOR_CAPHDR) {
+ const unsigned char *mac = skb_mac_header(skb);
+
+ if (*(u32 *)mac == LWNG_CAP_DID_BASE) {
+ memcpy(haddr,
+ mac + sizeof(struct linux_wlan_ng_prism_hdr) + 10,
+ ETH_ALEN); /* addr2 */
+ } else { /* (*(u32 *)mac == htonl(LWNG_CAPHDR_VERSION)) */
+ memcpy(haddr,
+ mac + sizeof(struct linux_wlan_ng_cap_hdr) + 10,
+ ETH_ALEN); /* addr2 */
+ }
+ } else
+ memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); /* addr2 */
-int hostap_80211_prism_header_parse(struct sk_buff *skb, unsigned char *haddr)
-{
- const unsigned char *mac = skb_mac_header(skb);
-
- if (*(u32 *)mac == LWNG_CAP_DID_BASE) {
- memcpy(haddr, mac + sizeof(struct linux_wlan_ng_prism_hdr) + 10,
- ETH_ALEN); /* addr2 */
- } else { /* (*(u32 *)mac == htonl(LWNG_CAPHDR_VERSION)) */
- memcpy(haddr, mac + sizeof(struct linux_wlan_ng_cap_hdr) + 10,
- ETH_ALEN); /* addr2 */
- }
return ETH_ALEN;
}
@@ -843,6 +846,15 @@ static void prism2_tx_timeout(struct net_device *dev)
local->func->schedule_reset(local);
}
+const struct header_ops hostap_80211_ops = {
+ .create = eth_header,
+ .rebuild = eth_rebuild_header,
+ .cache = eth_header_cache,
+ .cache_update = eth_header_cache_update,
+
+ .parse = hostap_80211_header_parse,
+};
+EXPORT_SYMBOL(hostap_80211_ops);
void hostap_setup_dev(struct net_device *dev, local_info_t *local,
int main_dev)
@@ -883,7 +895,6 @@ void hostap_setup_dev(struct net_device *dev, local_info_t *local,
netif_stop_queue(dev);
}
-
static int hostap_enable_hostapd(local_info_t *local, int rtnl_locked)
{
struct net_device *dev = local->dev;
@@ -901,7 +912,7 @@ static int hostap_enable_hostapd(local_info_t *local, int rtnl_locked)
local->apdev->hard_start_xmit = hostap_mgmt_start_xmit;
local->apdev->type = ARPHRD_IEEE80211;
- local->apdev->hard_header_parse = hostap_80211_header_parse;
+ local->apdev->header_ops = &hostap_80211_ops;
return 0;
}
diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h
index a42325c145b..c27b2c1c06a 100644
--- a/drivers/net/wireless/hostap/hostap_wlan.h
+++ b/drivers/net/wireless/hostap/hostap_wlan.h
@@ -736,8 +736,6 @@ struct local_info {
PRISM2_MONITOR_80211 = 0, PRISM2_MONITOR_PRISM = 1,
PRISM2_MONITOR_CAPHDR = 2
} monitor_type;
- int (*saved_eth_header_parse)(struct sk_buff *skb,
- unsigned char *haddr);
int monitor_allow_fcserr;
int hostapd; /* whether user space daemon, hostapd, is used for AP
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
index 404cd151231..4bd14b33186 100644
--- a/drivers/net/wireless/strip.c
+++ b/drivers/net/wireless/strip.c
@@ -1631,8 +1631,8 @@ static void strip_IdleTask(unsigned long parameter)
*/
static int strip_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 strip *strip_info = netdev_priv(dev);
STRIP_Header *header = (STRIP_Header *) skb_push(skb, sizeof(STRIP_Header));
@@ -2497,6 +2497,11 @@ static int strip_close_low(struct net_device *dev)
return 0;
}
+static const struct header_ops strip_header_ops = {
+ .create = strip_header,
+ .rebuild = strip_rebuild_header,
+};
+
/*
* This routine is called by DDI when the
* (dynamically assigned) device is registered
@@ -2531,8 +2536,8 @@ static void strip_dev_setup(struct net_device *dev)
dev->open = strip_open_low;
dev->stop = strip_close_low;
dev->hard_start_xmit = strip_xmit;
- dev->hard_header = strip_header;
- dev->rebuild_header = strip_rebuild_header;
+ dev->header_ops = &strip_header_ops;
+
dev->set_mac_address = strip_set_mac_address;
dev->get_stats = strip_get_stats;
dev->change_mtu = strip_change_mtu;
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h
index 6d4959807ab..8c6b72d05b1 100644
--- a/drivers/s390/net/qeth.h
+++ b/drivers/s390/net/qeth.h
@@ -833,8 +833,7 @@ struct qeth_card {
struct qeth_qdio_info qdio;
struct qeth_perf_stats perf_stats;
int use_hard_stop;
- int (*orig_hard_header)(struct sk_buff *,struct net_device *,
- unsigned short,void *,void *,unsigned);
+ const struct header_ops *orig_header_ops;
struct qeth_osn_info osn_info;
atomic_t force_alloc_skb;
};
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 65225b3989d..778ddfb9907 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -160,6 +160,9 @@ qeth_set_multicast_list(struct net_device *);
static void
qeth_setadp_promisc_mode(struct qeth_card *);
+static int
+qeth_hard_header_parse(const struct sk_buff *skb, unsigned char *haddr);
+
static void
qeth_notify_processes(void)
{
@@ -3787,8 +3790,8 @@ qeth_get_netdevice(enum qeth_card_types type, enum qeth_link_types linktype)
/*hard_header fake function; used in case fake_ll is set */
static int
qeth_fake_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)
{
if(dev->type == ARPHRD_IEEE802_TR){
struct trh_hdr *hdr;
@@ -3811,6 +3814,11 @@ qeth_fake_header(struct sk_buff *skb, struct net_device *dev,
}
}
+static const struct header_ops qeth_fake_ops = {
+ .create = qeth_fake_header,
+ .parse = qeth_hard_header_parse,
+};
+
static int
qeth_send_packet(struct qeth_card *, struct sk_buff *);
@@ -4649,7 +4657,7 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
[qeth_get_priority_queue(card, skb, ipv, cast_type)];
if (!card->options.layer2) {
ipv = qeth_get_ip_version(skb);
- if ((card->dev->hard_header == qeth_fake_header) && ipv) {
+ if ((card->dev->header_ops == &qeth_fake_ops) && ipv) {
new_skb = qeth_pskb_unshare(skb, GFP_ATOMIC);
if (!new_skb)
return -ENOMEM;
@@ -6566,6 +6574,9 @@ qeth_hard_header_parse(const struct sk_buff *skb, unsigned char *haddr)
const struct qeth_card *card;
const struct ethhdr *eth;
+ if (dev->type != ARPHRD_IEEE802_TR)
+ return 0;
+
card = qeth_get_card_from_dev(skb->dev);
if (card->options.layer2)
goto haveheader;
@@ -6596,6 +6607,10 @@ haveheader:
return ETH_ALEN;
}
+static const struct header_ops qeth_null_ops = {
+ .parse = qeth_hard_header_parse,
+};
+
static int
qeth_netdev_init(struct net_device *dev)
{
@@ -6620,12 +6635,8 @@ qeth_netdev_init(struct net_device *dev)
dev->vlan_rx_kill_vid = qeth_vlan_rx_kill_vid;
dev->vlan_rx_add_vid = qeth_vlan_rx_add_vid;
#endif
- if (qeth_get_netdev_flags(card) & IFF_NOARP) {
- dev->rebuild_header = NULL;
- dev->hard_header = NULL;
- dev->header_cache_update = NULL;
- dev->hard_header_cache = NULL;
- }
+ dev->header_ops = &qeth_null_ops;
+
#ifdef CONFIG_QETH_IPV6
/*IPv6 address autoconfiguration stuff*/
if (!(card->info.unique_id & UNIQUE_ID_NOT_BY_CARD))
@@ -6633,11 +6644,8 @@ qeth_netdev_init(struct net_device *dev)
#endif
if (card->options.fake_ll &&
(qeth_get_netdev_flags(card) & IFF_NOARP))
- dev->hard_header = qeth_fake_header;
- if (dev->type == ARPHRD_IEEE802_TR)
- dev->hard_header_parse = NULL;
- else
- dev->hard_header_parse = qeth_hard_header_parse;
+ dev->header_ops = &qeth_fake_ops;
+
dev->set_mac_address = qeth_layer2_set_mac_address;
dev->flags |= qeth_get_netdev_flags(card);
if ((card->options.fake_broadcast) ||
@@ -6740,10 +6748,10 @@ retry:
}
/*network device will be recovered*/
if (card->dev) {
- card->dev->hard_header = card->orig_hard_header;
+ card->dev->header_ops = card->orig_header_ops;
if (card->options.fake_ll &&
(qeth_get_netdev_flags(card) & IFF_NOARP))
- card->dev->hard_header = qeth_fake_header;
+ card->dev->header_ops = &qeth_fake_ops;
return 0;
}
/* at first set_online allocate netdev */
@@ -6757,7 +6765,7 @@ retry:
goto out;
}
card->dev->priv = card;
- card->orig_hard_header = card->dev->hard_header;
+ card->orig_header_ops = card->dev->header_ops;
card->dev->type = qeth_get_arphdr_type(card->info.type,
card->info.link_type);
card->dev->init = qeth_netdev_init;
@@ -8308,7 +8316,7 @@ qeth_arp_constructor(struct neighbour *neigh)
if (card == NULL)
goto out;
if((card->options.layer2) ||
- (card->dev->hard_header == qeth_fake_header))
+ (card->dev->header_ops == &qeth_fake_ops))
goto out;
rcu_read_lock();