aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorFrank Blaschka <Frank.Blaschka@de.ibm.com>2007-01-08 11:29:58 -0500
committerJeff Garzik <jeff@garzik.org>2007-01-09 02:18:32 -0500
commit2d36c16eb032239cb038ad875ecf83c545002461 (patch)
tree795422551e07b115390457711a371fda147891e7 /drivers
parent95c78c8bfe8d0b49a43f392b9a74e2f9e89765ab (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')
-rw-r--r--drivers/s390/net/qeth_main.c58
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 *
3952qeth_prepare_skb(struct qeth_card *card, struct sk_buff *skb, 3952qeth_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
6341static int 6350static int
6351qeth_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;
6380haveheader:
6381 eth = eth_hdr(skb);
6382 memcpy(haddr, eth->h_source, ETH_ALEN);
6383 return ETH_ALEN;
6384}
6385
6386static int
6342qeth_netdev_init(struct net_device *dev) 6387qeth_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) ||