Skip to content

Commit

Permalink
[NET]: Move hardware header operations out of netdevice.
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Stephen Hemminger authored and David S. Miller committed Oct 10, 2007
1 parent b95cce3 commit 3b04ddd
Show file tree
Hide file tree
Showing 65 changed files with 481 additions and 475 deletions.
40 changes: 23 additions & 17 deletions drivers/ieee1394/eth1394.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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;
Expand All @@ -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);

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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);
}
Expand Down Expand Up @@ -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;
Expand Down
8 changes: 6 additions & 2 deletions drivers/infiniband/ulp/ipoib/ipoib_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand All @@ -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;

Expand Down
105 changes: 36 additions & 69 deletions drivers/isdn/i4l/isdn_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -1873,62 +1873,22 @@ 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;
ushort len = 0;

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:
Expand Down Expand Up @@ -2005,25 +1965,45 @@ 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)
*/
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;
Expand All @@ -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;
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 */
Expand Down
9 changes: 8 additions & 1 deletion drivers/media/dvb/dvb-core/dvb_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}

Expand Down
20 changes: 1 addition & 19 deletions drivers/net/appletalk/cops.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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. */
Expand All @@ -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;
Expand Down Expand Up @@ -944,19 +939,6 @@ static void set_multicast_list(struct net_device *dev)
printk("%s: set_multicast_list executed\n", dev->name);
}

/*
* 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.
*/
Expand Down
10 changes: 0 additions & 10 deletions drivers/net/appletalk/ltpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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 */
Expand Down
Loading

0 comments on commit 3b04ddd

Please sign in to comment.