diff options
author | Frank Blaschka <Frank.Blaschka@de.ibm.com> | 2007-01-08 11:29:58 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-01-09 02:18:32 -0500 |
commit | 2d36c16eb032239cb038ad875ecf83c545002461 (patch) | |
tree | 795422551e07b115390457711a371fda147891e7 /drivers/s390 | |
parent | 95c78c8bfe8d0b49a43f392b9a74e2f9e89765ab (diff) |
s390: qeth driver fixes: packet socket
- packet socket support is not complete.
Recvfrom a packet socket does not fill the sockaddr_ll structure.
device function hard_header_parse is not implemented.
For layer 2 mode and layer 3 mode with fake_ll turned on, we have
the information to fill sockaddr_ll.
Signed-off-by: Frank Pavlic <fpavlic@de.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/net/qeth_main.c | 58 |
1 files changed, 53 insertions, 5 deletions
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 015dc4c9fc16..bfc37bae19bc 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c | |||
@@ -3952,13 +3952,22 @@ static inline struct sk_buff * | |||
3952 | qeth_prepare_skb(struct qeth_card *card, struct sk_buff *skb, | 3952 | qeth_prepare_skb(struct qeth_card *card, struct sk_buff *skb, |
3953 | struct qeth_hdr **hdr, int ipv) | 3953 | struct qeth_hdr **hdr, int ipv) |
3954 | { | 3954 | { |
3955 | struct sk_buff *new_skb; | 3955 | struct sk_buff *new_skb, *new_skb2; |
3956 | 3956 | ||
3957 | QETH_DBF_TEXT(trace, 6, "prepskb"); | 3957 | QETH_DBF_TEXT(trace, 6, "prepskb"); |
3958 | 3958 | new_skb = skb; | |
3959 | new_skb = qeth_realloc_headroom(card, skb, sizeof(struct qeth_hdr)); | 3959 | new_skb = qeth_pskb_unshare(skb, GFP_ATOMIC); |
3960 | if (new_skb == NULL) | 3960 | if (!new_skb) |
3961 | return NULL; | 3961 | return NULL; |
3962 | new_skb2 = qeth_realloc_headroom(card, new_skb, | ||
3963 | sizeof(struct qeth_hdr)); | ||
3964 | if (!new_skb2) { | ||
3965 | __qeth_free_new_skb(skb, new_skb); | ||
3966 | return NULL; | ||
3967 | } | ||
3968 | if (new_skb != skb) | ||
3969 | __qeth_free_new_skb(new_skb2, new_skb); | ||
3970 | new_skb = new_skb2; | ||
3962 | *hdr = __qeth_prepare_skb(card, new_skb, ipv); | 3971 | *hdr = __qeth_prepare_skb(card, new_skb, ipv); |
3963 | if (*hdr == NULL) { | 3972 | if (*hdr == NULL) { |
3964 | __qeth_free_new_skb(skb, new_skb); | 3973 | __qeth_free_new_skb(skb, new_skb); |
@@ -6339,6 +6348,42 @@ static struct ethtool_ops qeth_ethtool_ops = { | |||
6339 | }; | 6348 | }; |
6340 | 6349 | ||
6341 | static int | 6350 | static int |
6351 | qeth_hard_header_parse(struct sk_buff *skb, unsigned char *haddr) | ||
6352 | { | ||
6353 | struct qeth_card *card; | ||
6354 | struct ethhdr *eth; | ||
6355 | |||
6356 | card = qeth_get_card_from_dev(skb->dev); | ||
6357 | if (card->options.layer2) | ||
6358 | goto haveheader; | ||
6359 | #ifdef CONFIG_QETH_IPV6 | ||
6360 | /* cause of the manipulated arp constructor and the ARP | ||
6361 | flag for OSAE devices we have some nasty exceptions */ | ||
6362 | if (card->info.type == QETH_CARD_TYPE_OSAE) { | ||
6363 | if (!card->options.fake_ll) { | ||
6364 | if ((skb->pkt_type==PACKET_OUTGOING) && | ||
6365 | (skb->protocol==ETH_P_IPV6)) | ||
6366 | goto haveheader; | ||
6367 | else | ||
6368 | return 0; | ||
6369 | } else { | ||
6370 | if ((skb->pkt_type==PACKET_OUTGOING) && | ||
6371 | (skb->protocol==ETH_P_IP)) | ||
6372 | return 0; | ||
6373 | else | ||
6374 | goto haveheader; | ||
6375 | } | ||
6376 | } | ||
6377 | #endif | ||
6378 | if (!card->options.fake_ll) | ||
6379 | return 0; | ||
6380 | haveheader: | ||
6381 | eth = eth_hdr(skb); | ||
6382 | memcpy(haddr, eth->h_source, ETH_ALEN); | ||
6383 | return ETH_ALEN; | ||
6384 | } | ||
6385 | |||
6386 | static int | ||
6342 | qeth_netdev_init(struct net_device *dev) | 6387 | qeth_netdev_init(struct net_device *dev) |
6343 | { | 6388 | { |
6344 | struct qeth_card *card; | 6389 | struct qeth_card *card; |
@@ -6376,7 +6421,10 @@ qeth_netdev_init(struct net_device *dev) | |||
6376 | if (card->options.fake_ll && | 6421 | if (card->options.fake_ll && |
6377 | (qeth_get_netdev_flags(card) & IFF_NOARP)) | 6422 | (qeth_get_netdev_flags(card) & IFF_NOARP)) |
6378 | dev->hard_header = qeth_fake_header; | 6423 | dev->hard_header = qeth_fake_header; |
6379 | dev->hard_header_parse = NULL; | 6424 | if (dev->type == ARPHRD_IEEE802_TR) |
6425 | dev->hard_header_parse = NULL; | ||
6426 | else | ||
6427 | dev->hard_header_parse = qeth_hard_header_parse; | ||
6380 | dev->set_mac_address = qeth_layer2_set_mac_address; | 6428 | dev->set_mac_address = qeth_layer2_set_mac_address; |
6381 | dev->flags |= qeth_get_netdev_flags(card); | 6429 | dev->flags |= qeth_get_netdev_flags(card); |
6382 | if ((card->options.fake_broadcast) || | 6430 | if ((card->options.fake_broadcast) || |