aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/s390/net/qeth_main.c106
1 files changed, 80 insertions, 26 deletions
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index ab50e0ea9313..0a5d758b531e 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * 2 *
3 * linux/drivers/s390/net/qeth_main.c ($Revision: 1.235 $) 3 * linux/drivers/s390/net/qeth_main.c ($Revision: 1.236 $)
4 * 4 *
5 * Linux on zSeries OSA Express and HiperSockets support 5 * Linux on zSeries OSA Express and HiperSockets support
6 * 6 *
@@ -12,7 +12,7 @@
12 * Frank Pavlic (pavlic@de.ibm.com) and 12 * Frank Pavlic (pavlic@de.ibm.com) and
13 * Thomas Spatzier <tspat@de.ibm.com> 13 * Thomas Spatzier <tspat@de.ibm.com>
14 * 14 *
15 * $Revision: 1.235 $ $Date: 2005/05/04 20:19:18 $ 15 * $Revision: 1.236 $ $Date: 2005/05/04 20:19:18 $
16 * 16 *
17 * This program is free software; you can redistribute it and/or modify 17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by 18 * it under the terms of the GNU General Public License as published by
@@ -72,7 +72,7 @@
72#include "qeth_eddp.h" 72#include "qeth_eddp.h"
73#include "qeth_tso.h" 73#include "qeth_tso.h"
74 74
75#define VERSION_QETH_C "$Revision: 1.235 $" 75#define VERSION_QETH_C "$Revision: 1.236 $"
76static const char *version = "qeth S/390 OSA-Express driver"; 76static const char *version = "qeth S/390 OSA-Express driver";
77 77
78/** 78/**
@@ -602,11 +602,20 @@ __qeth_ref_ip_on_card(struct qeth_card *card, struct qeth_ipaddr *todo,
602 int found = 0; 602 int found = 0;
603 603
604 list_for_each_entry(addr, &card->ip_list, entry) { 604 list_for_each_entry(addr, &card->ip_list, entry) {
605 if (card->options.layer2) {
606 if ((addr->type == todo->type) &&
607 (memcmp(&addr->mac, &todo->mac,
608 OSA_ADDR_LEN) == 0)) {
609 found = 1;
610 break;
611 }
612 continue;
613 }
605 if ((addr->proto == QETH_PROT_IPV4) && 614 if ((addr->proto == QETH_PROT_IPV4) &&
606 (todo->proto == QETH_PROT_IPV4) && 615 (todo->proto == QETH_PROT_IPV4) &&
607 (addr->type == todo->type) && 616 (addr->type == todo->type) &&
608 (addr->u.a4.addr == todo->u.a4.addr) && 617 (addr->u.a4.addr == todo->u.a4.addr) &&
609 (addr->u.a4.mask == todo->u.a4.mask) ){ 618 (addr->u.a4.mask == todo->u.a4.mask)) {
610 found = 1; 619 found = 1;
611 break; 620 break;
612 } 621 }
@@ -615,12 +624,12 @@ __qeth_ref_ip_on_card(struct qeth_card *card, struct qeth_ipaddr *todo,
615 (addr->type == todo->type) && 624 (addr->type == todo->type) &&
616 (addr->u.a6.pfxlen == todo->u.a6.pfxlen) && 625 (addr->u.a6.pfxlen == todo->u.a6.pfxlen) &&
617 (memcmp(&addr->u.a6.addr, &todo->u.a6.addr, 626 (memcmp(&addr->u.a6.addr, &todo->u.a6.addr,
618 sizeof(struct in6_addr)) == 0)) { 627 sizeof(struct in6_addr)) == 0)) {
619 found = 1; 628 found = 1;
620 break; 629 break;
621 } 630 }
622 } 631 }
623 if (found){ 632 if (found) {
624 addr->users += todo->users; 633 addr->users += todo->users;
625 if (addr->users <= 0){ 634 if (addr->users <= 0){
626 *__addr = addr; 635 *__addr = addr;
@@ -632,7 +641,7 @@ __qeth_ref_ip_on_card(struct qeth_card *card, struct qeth_ipaddr *todo,
632 return 0; 641 return 0;
633 } 642 }
634 } 643 }
635 if (todo->users > 0){ 644 if (todo->users > 0) {
636 /* for VIPA and RXIP limit refcount to 1 */ 645 /* for VIPA and RXIP limit refcount to 1 */
637 if (todo->type != QETH_IP_TYPE_NORMAL) 646 if (todo->type != QETH_IP_TYPE_NORMAL)
638 todo->users = 1; 647 todo->users = 1;
@@ -682,12 +691,22 @@ __qeth_insert_ip_todo(struct qeth_card *card, struct qeth_ipaddr *addr, int add)
682 if ((addr->type == QETH_IP_TYPE_DEL_ALL_MC) && 691 if ((addr->type == QETH_IP_TYPE_DEL_ALL_MC) &&
683 (tmp->type == QETH_IP_TYPE_DEL_ALL_MC)) 692 (tmp->type == QETH_IP_TYPE_DEL_ALL_MC))
684 return 0; 693 return 0;
694 if (card->options.layer2) {
695 if ((tmp->type == addr->type) &&
696 (tmp->is_multicast == addr->is_multicast) &&
697 (memcmp(&tmp->mac, &addr->mac,
698 OSA_ADDR_LEN) == 0)) {
699 found = 1;
700 break;
701 }
702 continue;
703 }
685 if ((tmp->proto == QETH_PROT_IPV4) && 704 if ((tmp->proto == QETH_PROT_IPV4) &&
686 (addr->proto == QETH_PROT_IPV4) && 705 (addr->proto == QETH_PROT_IPV4) &&
687 (tmp->type == addr->type) && 706 (tmp->type == addr->type) &&
688 (tmp->is_multicast == addr->is_multicast) && 707 (tmp->is_multicast == addr->is_multicast) &&
689 (tmp->u.a4.addr == addr->u.a4.addr) && 708 (tmp->u.a4.addr == addr->u.a4.addr) &&
690 (tmp->u.a4.mask == addr->u.a4.mask) ){ 709 (tmp->u.a4.mask == addr->u.a4.mask)) {
691 found = 1; 710 found = 1;
692 break; 711 break;
693 } 712 }
@@ -697,7 +716,7 @@ __qeth_insert_ip_todo(struct qeth_card *card, struct qeth_ipaddr *addr, int add)
697 (tmp->is_multicast == addr->is_multicast) && 716 (tmp->is_multicast == addr->is_multicast) &&
698 (tmp->u.a6.pfxlen == addr->u.a6.pfxlen) && 717 (tmp->u.a6.pfxlen == addr->u.a6.pfxlen) &&
699 (memcmp(&tmp->u.a6.addr, &addr->u.a6.addr, 718 (memcmp(&tmp->u.a6.addr, &addr->u.a6.addr,
700 sizeof(struct in6_addr)) == 0) ){ 719 sizeof(struct in6_addr)) == 0)) {
701 found = 1; 720 found = 1;
702 break; 721 break;
703 } 722 }
@@ -707,7 +726,7 @@ __qeth_insert_ip_todo(struct qeth_card *card, struct qeth_ipaddr *addr, int add)
707 tmp->users += addr->users; 726 tmp->users += addr->users;
708 else 727 else
709 tmp->users += add? 1:-1; 728 tmp->users += add? 1:-1;
710 if (tmp->users == 0){ 729 if (tmp->users == 0) {
711 list_del(&tmp->entry); 730 list_del(&tmp->entry);
712 kfree(tmp); 731 kfree(tmp);
713 } 732 }
@@ -738,12 +757,15 @@ qeth_delete_ip(struct qeth_card *card, struct qeth_ipaddr *addr)
738 unsigned long flags; 757 unsigned long flags;
739 int rc = 0; 758 int rc = 0;
740 759
741 QETH_DBF_TEXT(trace,4,"delip"); 760 QETH_DBF_TEXT(trace, 4, "delip");
742 if (addr->proto == QETH_PROT_IPV4) 761
743 QETH_DBF_HEX(trace,4,&addr->u.a4.addr,4); 762 if (card->options.layer2)
763 QETH_DBF_HEX(trace, 4, &addr->mac, 6);
764 else if (addr->proto == QETH_PROT_IPV4)
765 QETH_DBF_HEX(trace, 4, &addr->u.a4.addr, 4);
744 else { 766 else {
745 QETH_DBF_HEX(trace,4,&addr->u.a6.addr,8); 767 QETH_DBF_HEX(trace, 4, &addr->u.a6.addr, 8);
746 QETH_DBF_HEX(trace,4,((char *)&addr->u.a6.addr)+8,8); 768 QETH_DBF_HEX(trace, 4, ((char *)&addr->u.a6.addr) + 8, 8);
747 } 769 }
748 spin_lock_irqsave(&card->ip_lock, flags); 770 spin_lock_irqsave(&card->ip_lock, flags);
749 rc = __qeth_insert_ip_todo(card, addr, 0); 771 rc = __qeth_insert_ip_todo(card, addr, 0);
@@ -757,12 +779,14 @@ qeth_add_ip(struct qeth_card *card, struct qeth_ipaddr *addr)
757 unsigned long flags; 779 unsigned long flags;
758 int rc = 0; 780 int rc = 0;
759 781
760 QETH_DBF_TEXT(trace,4,"addip"); 782 QETH_DBF_TEXT(trace, 4, "addip");
761 if (addr->proto == QETH_PROT_IPV4) 783 if (card->options.layer2)
762 QETH_DBF_HEX(trace,4,&addr->u.a4.addr,4); 784 QETH_DBF_HEX(trace, 4, &addr->mac, 6);
785 else if (addr->proto == QETH_PROT_IPV4)
786 QETH_DBF_HEX(trace, 4, &addr->u.a4.addr, 4);
763 else { 787 else {
764 QETH_DBF_HEX(trace,4,&addr->u.a6.addr,8); 788 QETH_DBF_HEX(trace, 4, &addr->u.a6.addr, 8);
765 QETH_DBF_HEX(trace,4,((char *)&addr->u.a6.addr)+8,8); 789 QETH_DBF_HEX(trace, 4, ((char *)&addr->u.a6.addr) + 8, 8);
766 } 790 }
767 spin_lock_irqsave(&card->ip_lock, flags); 791 spin_lock_irqsave(&card->ip_lock, flags);
768 rc = __qeth_insert_ip_todo(card, addr, 1); 792 rc = __qeth_insert_ip_todo(card, addr, 1);
@@ -851,6 +875,7 @@ qeth_set_ip_addr_list(struct qeth_card *card)
851 875
852static void qeth_delete_mc_addresses(struct qeth_card *); 876static void qeth_delete_mc_addresses(struct qeth_card *);
853static void qeth_add_multicast_ipv4(struct qeth_card *); 877static void qeth_add_multicast_ipv4(struct qeth_card *);
878static void qeth_layer2_add_multicast(struct qeth_card *);
854#ifdef CONFIG_QETH_IPV6 879#ifdef CONFIG_QETH_IPV6
855static void qeth_add_multicast_ipv6(struct qeth_card *); 880static void qeth_add_multicast_ipv6(struct qeth_card *);
856#endif 881#endif
@@ -5301,8 +5326,7 @@ qeth_free_vlan_addresses4(struct qeth_card *card, unsigned short vid)
5301 struct qeth_ipaddr *addr; 5326 struct qeth_ipaddr *addr;
5302 5327
5303 QETH_DBF_TEXT(trace, 4, "frvaddr4"); 5328 QETH_DBF_TEXT(trace, 4, "frvaddr4");
5304 if (!card->vlangrp) 5329
5305 return;
5306 rcu_read_lock(); 5330 rcu_read_lock();
5307 in_dev = __in_dev_get_rcu(card->vlangrp->vlan_devices[vid]); 5331 in_dev = __in_dev_get_rcu(card->vlangrp->vlan_devices[vid]);
5308 if (!in_dev) 5332 if (!in_dev)
@@ -5330,8 +5354,7 @@ qeth_free_vlan_addresses6(struct qeth_card *card, unsigned short vid)
5330 struct qeth_ipaddr *addr; 5354 struct qeth_ipaddr *addr;
5331 5355
5332 QETH_DBF_TEXT(trace, 4, "frvaddr6"); 5356 QETH_DBF_TEXT(trace, 4, "frvaddr6");
5333 if (!card->vlangrp) 5357
5334 return;
5335 in6_dev = in6_dev_get(card->vlangrp->vlan_devices[vid]); 5358 in6_dev = in6_dev_get(card->vlangrp->vlan_devices[vid]);
5336 if (!in6_dev) 5359 if (!in6_dev)
5337 return; 5360 return;
@@ -5350,6 +5373,15 @@ qeth_free_vlan_addresses6(struct qeth_card *card, unsigned short vid)
5350#endif /* CONFIG_QETH_IPV6 */ 5373#endif /* CONFIG_QETH_IPV6 */
5351} 5374}
5352 5375
5376static void
5377qeth_free_vlan_addresses(struct qeth_card *card, unsigned short vid)
5378{
5379 if (card->options.layer2 || !card->vlangrp)
5380 return;
5381 qeth_free_vlan_addresses4(card, vid);
5382 qeth_free_vlan_addresses6(card, vid);
5383}
5384
5353static int 5385static int
5354qeth_layer2_send_setdelvlan_cb(struct qeth_card *card, 5386qeth_layer2_send_setdelvlan_cb(struct qeth_card *card,
5355 struct qeth_reply *reply, 5387 struct qeth_reply *reply,
@@ -5432,8 +5464,7 @@ qeth_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
5432 qeth_free_vlan_skbs(card, vid); 5464 qeth_free_vlan_skbs(card, vid);
5433 spin_lock_irqsave(&card->vlanlock, flags); 5465 spin_lock_irqsave(&card->vlanlock, flags);
5434 /* unregister IP addresses of vlan device */ 5466 /* unregister IP addresses of vlan device */
5435 qeth_free_vlan_addresses4(card, vid); 5467 qeth_free_vlan_addresses(card, vid);
5436 qeth_free_vlan_addresses6(card, vid);
5437 if (card->vlangrp) 5468 if (card->vlangrp)
5438 card->vlangrp->vlan_devices[vid] = NULL; 5469 card->vlangrp->vlan_devices[vid] = NULL;
5439 spin_unlock_irqrestore(&card->vlanlock, flags); 5470 spin_unlock_irqrestore(&card->vlanlock, flags);
@@ -5456,10 +5487,15 @@ qeth_set_multicast_list(struct net_device *dev)
5456 5487
5457 QETH_DBF_TEXT(trace,3,"setmulti"); 5488 QETH_DBF_TEXT(trace,3,"setmulti");
5458 qeth_delete_mc_addresses(card); 5489 qeth_delete_mc_addresses(card);
5490 if (card->options.layer2) {
5491 qeth_layer2_add_multicast(card);
5492 goto out;
5493 }
5459 qeth_add_multicast_ipv4(card); 5494 qeth_add_multicast_ipv4(card);
5460#ifdef CONFIG_QETH_IPV6 5495#ifdef CONFIG_QETH_IPV6
5461 qeth_add_multicast_ipv6(card); 5496 qeth_add_multicast_ipv6(card);
5462#endif 5497#endif
5498out:
5463 if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0) 5499 if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0)
5464 schedule_work(&card->kernel_thread_starter); 5500 schedule_work(&card->kernel_thread_starter);
5465} 5501}
@@ -5669,6 +5705,24 @@ qeth_add_multicast_ipv4(struct qeth_card *card)
5669 in_dev_put(in4_dev); 5705 in_dev_put(in4_dev);
5670} 5706}
5671 5707
5708static void
5709qeth_layer2_add_multicast(struct qeth_card *card)
5710{
5711 struct qeth_ipaddr *ipm;
5712 struct dev_mc_list *dm;
5713
5714 QETH_DBF_TEXT(trace,4,"L2addmc");
5715 for (dm = card->dev->mc_list; dm; dm = dm->next) {
5716 ipm = qeth_get_addr_buffer(QETH_PROT_IPV4);
5717 if (!ipm)
5718 continue;
5719 memcpy(ipm->mac,dm->dmi_addr,MAX_ADDR_LEN);
5720 ipm->is_multicast = 1;
5721 if (!qeth_add_ip(card, ipm))
5722 kfree(ipm);
5723 }
5724}
5725
5672#ifdef CONFIG_QETH_IPV6 5726#ifdef CONFIG_QETH_IPV6
5673static inline void 5727static inline void
5674qeth_add_mc6(struct qeth_card *card, struct inet6_dev *in6_dev) 5728qeth_add_mc6(struct qeth_card *card, struct inet6_dev *in6_dev)