aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@linux-foundation.org>2007-10-09 04:40:57 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:52:52 -0400
commit3b04ddde02cf1b6f14f2697da5c20eca5715017f (patch)
tree9da1341a5a399a507b5ea6bf5a3047506b8d8f8f /drivers/s390
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/s390')
-rw-r--r--drivers/s390/net/qeth.h3
-rw-r--r--drivers/s390/net/qeth_main.c44
2 files changed, 27 insertions, 20 deletions
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h
index 6d4959807abc..8c6b72d05b1d 100644
--- a/drivers/s390/net/qeth.h
+++ b/drivers/s390/net/qeth.h
@@ -833,8 +833,7 @@ struct qeth_card {
833 struct qeth_qdio_info qdio; 833 struct qeth_qdio_info qdio;
834 struct qeth_perf_stats perf_stats; 834 struct qeth_perf_stats perf_stats;
835 int use_hard_stop; 835 int use_hard_stop;
836 int (*orig_hard_header)(struct sk_buff *,struct net_device *, 836 const struct header_ops *orig_header_ops;
837 unsigned short,void *,void *,unsigned);
838 struct qeth_osn_info osn_info; 837 struct qeth_osn_info osn_info;
839 atomic_t force_alloc_skb; 838 atomic_t force_alloc_skb;
840}; 839};
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 65225b3989dd..778ddfb99077 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 *);
160static void 160static void
161qeth_setadp_promisc_mode(struct qeth_card *); 161qeth_setadp_promisc_mode(struct qeth_card *);
162 162
163static int
164qeth_hard_header_parse(const struct sk_buff *skb, unsigned char *haddr);
165
163static void 166static void
164qeth_notify_processes(void) 167qeth_notify_processes(void)
165{ 168{
@@ -3787,8 +3790,8 @@ qeth_get_netdevice(enum qeth_card_types type, enum qeth_link_types linktype)
3787/*hard_header fake function; used in case fake_ll is set */ 3790/*hard_header fake function; used in case fake_ll is set */
3788static int 3791static int
3789qeth_fake_header(struct sk_buff *skb, struct net_device *dev, 3792qeth_fake_header(struct sk_buff *skb, struct net_device *dev,
3790 unsigned short type, void *daddr, void *saddr, 3793 unsigned short type, const void *daddr, const void *saddr,
3791 unsigned len) 3794 unsigned len)
3792{ 3795{
3793 if(dev->type == ARPHRD_IEEE802_TR){ 3796 if(dev->type == ARPHRD_IEEE802_TR){
3794 struct trh_hdr *hdr; 3797 struct trh_hdr *hdr;
@@ -3811,6 +3814,11 @@ qeth_fake_header(struct sk_buff *skb, struct net_device *dev,
3811 } 3814 }
3812} 3815}
3813 3816
3817static const struct header_ops qeth_fake_ops = {
3818 .create = qeth_fake_header,
3819 .parse = qeth_hard_header_parse,
3820};
3821
3814static int 3822static int
3815qeth_send_packet(struct qeth_card *, struct sk_buff *); 3823qeth_send_packet(struct qeth_card *, struct sk_buff *);
3816 3824
@@ -4649,7 +4657,7 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
4649 [qeth_get_priority_queue(card, skb, ipv, cast_type)]; 4657 [qeth_get_priority_queue(card, skb, ipv, cast_type)];
4650 if (!card->options.layer2) { 4658 if (!card->options.layer2) {
4651 ipv = qeth_get_ip_version(skb); 4659 ipv = qeth_get_ip_version(skb);
4652 if ((card->dev->hard_header == qeth_fake_header) && ipv) { 4660 if ((card->dev->header_ops == &qeth_fake_ops) && ipv) {
4653 new_skb = qeth_pskb_unshare(skb, GFP_ATOMIC); 4661 new_skb = qeth_pskb_unshare(skb, GFP_ATOMIC);
4654 if (!new_skb) 4662 if (!new_skb)
4655 return -ENOMEM; 4663 return -ENOMEM;
@@ -6566,6 +6574,9 @@ qeth_hard_header_parse(const struct sk_buff *skb, unsigned char *haddr)
6566 const struct qeth_card *card; 6574 const struct qeth_card *card;
6567 const struct ethhdr *eth; 6575 const struct ethhdr *eth;
6568 6576
6577 if (dev->type != ARPHRD_IEEE802_TR)
6578 return 0;
6579
6569 card = qeth_get_card_from_dev(skb->dev); 6580 card = qeth_get_card_from_dev(skb->dev);
6570 if (card->options.layer2) 6581 if (card->options.layer2)
6571 goto haveheader; 6582 goto haveheader;
@@ -6596,6 +6607,10 @@ haveheader:
6596 return ETH_ALEN; 6607 return ETH_ALEN;
6597} 6608}
6598 6609
6610static const struct header_ops qeth_null_ops = {
6611 .parse = qeth_hard_header_parse,
6612};
6613
6599static int 6614static int
6600qeth_netdev_init(struct net_device *dev) 6615qeth_netdev_init(struct net_device *dev)
6601{ 6616{
@@ -6620,12 +6635,8 @@ qeth_netdev_init(struct net_device *dev)
6620 dev->vlan_rx_kill_vid = qeth_vlan_rx_kill_vid; 6635 dev->vlan_rx_kill_vid = qeth_vlan_rx_kill_vid;
6621 dev->vlan_rx_add_vid = qeth_vlan_rx_add_vid; 6636 dev->vlan_rx_add_vid = qeth_vlan_rx_add_vid;
6622#endif 6637#endif
6623 if (qeth_get_netdev_flags(card) & IFF_NOARP) { 6638 dev->header_ops = &qeth_null_ops;
6624 dev->rebuild_header = NULL; 6639
6625 dev->hard_header = NULL;
6626 dev->header_cache_update = NULL;
6627 dev->hard_header_cache = NULL;
6628 }
6629#ifdef CONFIG_QETH_IPV6 6640#ifdef CONFIG_QETH_IPV6
6630 /*IPv6 address autoconfiguration stuff*/ 6641 /*IPv6 address autoconfiguration stuff*/
6631 if (!(card->info.unique_id & UNIQUE_ID_NOT_BY_CARD)) 6642 if (!(card->info.unique_id & UNIQUE_ID_NOT_BY_CARD))
@@ -6633,11 +6644,8 @@ qeth_netdev_init(struct net_device *dev)
6633#endif 6644#endif
6634 if (card->options.fake_ll && 6645 if (card->options.fake_ll &&
6635 (qeth_get_netdev_flags(card) & IFF_NOARP)) 6646 (qeth_get_netdev_flags(card) & IFF_NOARP))
6636 dev->hard_header = qeth_fake_header; 6647 dev->header_ops = &qeth_fake_ops;
6637 if (dev->type == ARPHRD_IEEE802_TR) 6648
6638 dev->hard_header_parse = NULL;
6639 else
6640 dev->hard_header_parse = qeth_hard_header_parse;
6641 dev->set_mac_address = qeth_layer2_set_mac_address; 6649 dev->set_mac_address = qeth_layer2_set_mac_address;
6642 dev->flags |= qeth_get_netdev_flags(card); 6650 dev->flags |= qeth_get_netdev_flags(card);
6643 if ((card->options.fake_broadcast) || 6651 if ((card->options.fake_broadcast) ||
@@ -6740,10 +6748,10 @@ retry:
6740 } 6748 }
6741 /*network device will be recovered*/ 6749 /*network device will be recovered*/
6742 if (card->dev) { 6750 if (card->dev) {
6743 card->dev->hard_header = card->orig_hard_header; 6751 card->dev->header_ops = card->orig_header_ops;
6744 if (card->options.fake_ll && 6752 if (card->options.fake_ll &&
6745 (qeth_get_netdev_flags(card) & IFF_NOARP)) 6753 (qeth_get_netdev_flags(card) & IFF_NOARP))
6746 card->dev->hard_header = qeth_fake_header; 6754 card->dev->header_ops = &qeth_fake_ops;
6747 return 0; 6755 return 0;
6748 } 6756 }
6749 /* at first set_online allocate netdev */ 6757 /* at first set_online allocate netdev */
@@ -6757,7 +6765,7 @@ retry:
6757 goto out; 6765 goto out;
6758 } 6766 }
6759 card->dev->priv = card; 6767 card->dev->priv = card;
6760 card->orig_hard_header = card->dev->hard_header; 6768 card->orig_header_ops = card->dev->header_ops;
6761 card->dev->type = qeth_get_arphdr_type(card->info.type, 6769 card->dev->type = qeth_get_arphdr_type(card->info.type,
6762 card->info.link_type); 6770 card->info.link_type);
6763 card->dev->init = qeth_netdev_init; 6771 card->dev->init = qeth_netdev_init;
@@ -8308,7 +8316,7 @@ qeth_arp_constructor(struct neighbour *neigh)
8308 if (card == NULL) 8316 if (card == NULL)
8309 goto out; 8317 goto out;
8310 if((card->options.layer2) || 8318 if((card->options.layer2) ||
8311 (card->dev->hard_header == qeth_fake_header)) 8319 (card->dev->header_ops == &qeth_fake_ops))
8312 goto out; 8320 goto out;
8313 8321
8314 rcu_read_lock(); 8322 rcu_read_lock();