diff options
author | Steve French <sfrench@us.ibm.com> | 2005-11-12 22:53:33 -0500 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2005-11-12 22:53:33 -0500 |
commit | 1b98a8221e3c9c86ae7e292ba7542d2dd6f10eb9 (patch) | |
tree | 2e0051ccb147b0553d50c14681c50881098859d6 /drivers/s390/net | |
parent | e89dc9209692293434da45ec31826a55becb91c0 (diff) | |
parent | 9e6c67fd2716720d9029d38ea25884efcfdedeb6 (diff) |
Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Diffstat (limited to 'drivers/s390/net')
-rw-r--r-- | drivers/s390/net/lcs.c | 4 | ||||
-rw-r--r-- | drivers/s390/net/qeth.h | 77 | ||||
-rw-r--r-- | drivers/s390/net/qeth_main.c | 261 | ||||
-rw-r--r-- | drivers/s390/net/qeth_mpc.c | 2 | ||||
-rw-r--r-- | drivers/s390/net/qeth_mpc.h | 13 | ||||
-rw-r--r-- | drivers/s390/net/qeth_sys.c | 8 | ||||
-rw-r--r-- | drivers/s390/net/qeth_tso.h | 2 |
7 files changed, 289 insertions, 78 deletions
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 1c8ad2fcad8a..da8c515743e8 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * Author(s): Original Code written by | 8 | * Author(s): Original Code written by |
9 | * DJ Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) | 9 | * DJ Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) |
10 | * Rewritten by | 10 | * Rewritten by |
11 | * Frank Pavlic (pavlic@de.ibm.com) and | 11 | * Frank Pavlic (fpavlic@de.ibm.com) and |
12 | * Martin Schwidefsky <schwidefsky@de.ibm.com> | 12 | * Martin Schwidefsky <schwidefsky@de.ibm.com> |
13 | * | 13 | * |
14 | * $Revision: 1.99 $ $Date: 2005/05/11 08:10:17 $ | 14 | * $Revision: 1.99 $ $Date: 2005/05/11 08:10:17 $ |
@@ -2342,6 +2342,6 @@ __exit lcs_cleanup_module(void) | |||
2342 | module_init(lcs_init_module); | 2342 | module_init(lcs_init_module); |
2343 | module_exit(lcs_cleanup_module); | 2343 | module_exit(lcs_cleanup_module); |
2344 | 2344 | ||
2345 | MODULE_AUTHOR("Frank Pavlic <pavlic@de.ibm.com>"); | 2345 | MODULE_AUTHOR("Frank Pavlic <fpavlic@de.ibm.com>"); |
2346 | MODULE_LICENSE("GPL"); | 2346 | MODULE_LICENSE("GPL"); |
2347 | 2347 | ||
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h index 38a2441564d7..d238c7ed103b 100644 --- a/drivers/s390/net/qeth.h +++ b/drivers/s390/net/qeth.h | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/trdevice.h> | 8 | #include <linux/trdevice.h> |
9 | #include <linux/etherdevice.h> | 9 | #include <linux/etherdevice.h> |
10 | #include <linux/if_vlan.h> | 10 | #include <linux/if_vlan.h> |
11 | #include <linux/ctype.h> | ||
11 | 12 | ||
12 | #include <net/ipv6.h> | 13 | #include <net/ipv6.h> |
13 | #include <linux/in6.h> | 14 | #include <linux/in6.h> |
@@ -24,7 +25,7 @@ | |||
24 | 25 | ||
25 | #include "qeth_mpc.h" | 26 | #include "qeth_mpc.h" |
26 | 27 | ||
27 | #define VERSION_QETH_H "$Revision: 1.142 $" | 28 | #define VERSION_QETH_H "$Revision: 1.152 $" |
28 | 29 | ||
29 | #ifdef CONFIG_QETH_IPV6 | 30 | #ifdef CONFIG_QETH_IPV6 |
30 | #define QETH_VERSION_IPV6 ":IPv6" | 31 | #define QETH_VERSION_IPV6 ":IPv6" |
@@ -718,8 +719,6 @@ struct qeth_reply { | |||
718 | atomic_t refcnt; | 719 | atomic_t refcnt; |
719 | }; | 720 | }; |
720 | 721 | ||
721 | #define QETH_BROADCAST_WITH_ECHO 1 | ||
722 | #define QETH_BROADCAST_WITHOUT_ECHO 2 | ||
723 | 722 | ||
724 | struct qeth_card_blkt { | 723 | struct qeth_card_blkt { |
725 | int time_total; | 724 | int time_total; |
@@ -727,8 +726,10 @@ struct qeth_card_blkt { | |||
727 | int inter_packet_jumbo; | 726 | int inter_packet_jumbo; |
728 | }; | 727 | }; |
729 | 728 | ||
730 | 729 | #define QETH_BROADCAST_WITH_ECHO 0x01 | |
731 | 730 | #define QETH_BROADCAST_WITHOUT_ECHO 0x02 | |
731 | #define QETH_LAYER2_MAC_READ 0x01 | ||
732 | #define QETH_LAYER2_MAC_REGISTERED 0x02 | ||
732 | struct qeth_card_info { | 733 | struct qeth_card_info { |
733 | unsigned short unit_addr2; | 734 | unsigned short unit_addr2; |
734 | unsigned short cula; | 735 | unsigned short cula; |
@@ -736,7 +737,7 @@ struct qeth_card_info { | |||
736 | __u16 func_level; | 737 | __u16 func_level; |
737 | char mcl_level[QETH_MCL_LENGTH + 1]; | 738 | char mcl_level[QETH_MCL_LENGTH + 1]; |
738 | int guestlan; | 739 | int guestlan; |
739 | int layer2_mac_registered; | 740 | int mac_bits; |
740 | int portname_required; | 741 | int portname_required; |
741 | int portno; | 742 | int portno; |
742 | char portname[9]; | 743 | char portname[9]; |
@@ -749,6 +750,7 @@ struct qeth_card_info { | |||
749 | int unique_id; | 750 | int unique_id; |
750 | struct qeth_card_blkt blkt; | 751 | struct qeth_card_blkt blkt; |
751 | __u32 csum_mask; | 752 | __u32 csum_mask; |
753 | enum qeth_ipa_promisc_modes promisc_mode; | ||
752 | }; | 754 | }; |
753 | 755 | ||
754 | struct qeth_card_options { | 756 | struct qeth_card_options { |
@@ -775,6 +777,7 @@ struct qeth_card_options { | |||
775 | enum qeth_threads { | 777 | enum qeth_threads { |
776 | QETH_SET_IP_THREAD = 1, | 778 | QETH_SET_IP_THREAD = 1, |
777 | QETH_RECOVER_THREAD = 2, | 779 | QETH_RECOVER_THREAD = 2, |
780 | QETH_SET_PROMISC_MODE_THREAD = 4, | ||
778 | }; | 781 | }; |
779 | 782 | ||
780 | struct qeth_osn_info { | 783 | struct qeth_osn_info { |
@@ -1074,6 +1077,26 @@ qeth_get_qdio_q_format(struct qeth_card *card) | |||
1074 | } | 1077 | } |
1075 | } | 1078 | } |
1076 | 1079 | ||
1080 | static inline int | ||
1081 | qeth_isdigit(char * buf) | ||
1082 | { | ||
1083 | while (*buf) { | ||
1084 | if (!isdigit(*buf++)) | ||
1085 | return 0; | ||
1086 | } | ||
1087 | return 1; | ||
1088 | } | ||
1089 | |||
1090 | static inline int | ||
1091 | qeth_isxdigit(char * buf) | ||
1092 | { | ||
1093 | while (*buf) { | ||
1094 | if (!isxdigit(*buf++)) | ||
1095 | return 0; | ||
1096 | } | ||
1097 | return 1; | ||
1098 | } | ||
1099 | |||
1077 | static inline void | 1100 | static inline void |
1078 | qeth_ipaddr4_to_string(const __u8 *addr, char *buf) | 1101 | qeth_ipaddr4_to_string(const __u8 *addr, char *buf) |
1079 | { | 1102 | { |
@@ -1090,18 +1113,27 @@ qeth_string_to_ipaddr4(const char *buf, __u8 *addr) | |||
1090 | int i; | 1113 | int i; |
1091 | 1114 | ||
1092 | start = buf; | 1115 | start = buf; |
1093 | for (i = 0; i < 3; i++) { | 1116 | for (i = 0; i < 4; i++) { |
1094 | if (!(end = strchr(start, '.'))) | 1117 | if (i == 3) { |
1118 | end = strchr(start,0xa); | ||
1119 | if (end) | ||
1120 | len = end - start; | ||
1121 | else | ||
1122 | len = strlen(start); | ||
1123 | } | ||
1124 | else { | ||
1125 | end = strchr(start, '.'); | ||
1126 | len = end - start; | ||
1127 | } | ||
1128 | if ((len <= 0) || (len > 3)) | ||
1095 | return -EINVAL; | 1129 | return -EINVAL; |
1096 | len = end - start; | ||
1097 | memset(abuf, 0, 4); | 1130 | memset(abuf, 0, 4); |
1098 | strncpy(abuf, start, len); | 1131 | strncpy(abuf, start, len); |
1132 | if (!qeth_isdigit(abuf)) | ||
1133 | return -EINVAL; | ||
1099 | addr[i] = simple_strtoul(abuf, &tmp, 10); | 1134 | addr[i] = simple_strtoul(abuf, &tmp, 10); |
1100 | start = end + 1; | 1135 | start = end + 1; |
1101 | } | 1136 | } |
1102 | memset(abuf, 0, 4); | ||
1103 | strcpy(abuf, start); | ||
1104 | addr[3] = simple_strtoul(abuf, &tmp, 10); | ||
1105 | return 0; | 1137 | return 0; |
1106 | } | 1138 | } |
1107 | 1139 | ||
@@ -1128,18 +1160,27 @@ qeth_string_to_ipaddr6(const char *buf, __u8 *addr) | |||
1128 | 1160 | ||
1129 | tmp_addr = (u16 *)addr; | 1161 | tmp_addr = (u16 *)addr; |
1130 | start = buf; | 1162 | start = buf; |
1131 | for (i = 0; i < 7; i++) { | 1163 | for (i = 0; i < 8; i++) { |
1132 | if (!(end = strchr(start, ':'))) | 1164 | if (i == 7) { |
1165 | end = strchr(start,0xa); | ||
1166 | if (end) | ||
1167 | len = end - start; | ||
1168 | else | ||
1169 | len = strlen(start); | ||
1170 | } | ||
1171 | else { | ||
1172 | end = strchr(start, ':'); | ||
1173 | len = end - start; | ||
1174 | } | ||
1175 | if ((len <= 0) || (len > 4)) | ||
1133 | return -EINVAL; | 1176 | return -EINVAL; |
1134 | len = end - start; | ||
1135 | memset(abuf, 0, 5); | 1177 | memset(abuf, 0, 5); |
1136 | strncpy(abuf, start, len); | 1178 | strncpy(abuf, start, len); |
1179 | if (!qeth_isxdigit(abuf)) | ||
1180 | return -EINVAL; | ||
1137 | tmp_addr[i] = simple_strtoul(abuf, &tmp, 16); | 1181 | tmp_addr[i] = simple_strtoul(abuf, &tmp, 16); |
1138 | start = end + 1; | 1182 | start = end + 1; |
1139 | } | 1183 | } |
1140 | memset(abuf, 0, 5); | ||
1141 | strcpy(abuf, start); | ||
1142 | tmp_addr[7] = simple_strtoul(abuf, &tmp, 16); | ||
1143 | return 0; | 1184 | return 0; |
1144 | } | 1185 | } |
1145 | 1186 | ||
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 692003c9f896..99cceb242ec4 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.224 $) | 3 | * linux/drivers/s390/net/qeth_main.c ($Revision: 1.242 $) |
4 | * | 4 | * |
5 | * Linux on zSeries OSA Express and HiperSockets support | 5 | * Linux on zSeries OSA Express and HiperSockets support |
6 | * | 6 | * |
@@ -9,10 +9,10 @@ | |||
9 | * Author(s): Original Code written by | 9 | * Author(s): Original Code written by |
10 | * Utz Bacher (utz.bacher@de.ibm.com) | 10 | * Utz Bacher (utz.bacher@de.ibm.com) |
11 | * Rewritten by | 11 | * Rewritten by |
12 | * Frank Pavlic (pavlic@de.ibm.com) and | 12 | * Frank Pavlic (fpavlic@de.ibm.com) and |
13 | * Thomas Spatzier <tspat@de.ibm.com> | 13 | * Thomas Spatzier <tspat@de.ibm.com> |
14 | * | 14 | * |
15 | * $Revision: 1.224 $ $Date: 2005/05/04 20:19:18 $ | 15 | * $Revision: 1.242 $ $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.224 $" | 75 | #define VERSION_QETH_C "$Revision: 1.242 $" |
76 | static const char *version = "qeth S/390 OSA-Express driver"; | 76 | static const char *version = "qeth S/390 OSA-Express driver"; |
77 | 77 | ||
78 | /** | 78 | /** |
@@ -160,6 +160,9 @@ static void | |||
160 | qeth_set_multicast_list(struct net_device *); | 160 | qeth_set_multicast_list(struct net_device *); |
161 | 161 | ||
162 | static void | 162 | static void |
163 | qeth_setadp_promisc_mode(struct qeth_card *); | ||
164 | |||
165 | static void | ||
163 | qeth_notify_processes(void) | 166 | qeth_notify_processes(void) |
164 | { | 167 | { |
165 | /*notify all registered processes */ | 168 | /*notify all registered processes */ |
@@ -602,11 +605,20 @@ __qeth_ref_ip_on_card(struct qeth_card *card, struct qeth_ipaddr *todo, | |||
602 | int found = 0; | 605 | int found = 0; |
603 | 606 | ||
604 | list_for_each_entry(addr, &card->ip_list, entry) { | 607 | list_for_each_entry(addr, &card->ip_list, entry) { |
608 | if (card->options.layer2) { | ||
609 | if ((addr->type == todo->type) && | ||
610 | (memcmp(&addr->mac, &todo->mac, | ||
611 | OSA_ADDR_LEN) == 0)) { | ||
612 | found = 1; | ||
613 | break; | ||
614 | } | ||
615 | continue; | ||
616 | } | ||
605 | if ((addr->proto == QETH_PROT_IPV4) && | 617 | if ((addr->proto == QETH_PROT_IPV4) && |
606 | (todo->proto == QETH_PROT_IPV4) && | 618 | (todo->proto == QETH_PROT_IPV4) && |
607 | (addr->type == todo->type) && | 619 | (addr->type == todo->type) && |
608 | (addr->u.a4.addr == todo->u.a4.addr) && | 620 | (addr->u.a4.addr == todo->u.a4.addr) && |
609 | (addr->u.a4.mask == todo->u.a4.mask) ){ | 621 | (addr->u.a4.mask == todo->u.a4.mask)) { |
610 | found = 1; | 622 | found = 1; |
611 | break; | 623 | break; |
612 | } | 624 | } |
@@ -615,12 +627,12 @@ __qeth_ref_ip_on_card(struct qeth_card *card, struct qeth_ipaddr *todo, | |||
615 | (addr->type == todo->type) && | 627 | (addr->type == todo->type) && |
616 | (addr->u.a6.pfxlen == todo->u.a6.pfxlen) && | 628 | (addr->u.a6.pfxlen == todo->u.a6.pfxlen) && |
617 | (memcmp(&addr->u.a6.addr, &todo->u.a6.addr, | 629 | (memcmp(&addr->u.a6.addr, &todo->u.a6.addr, |
618 | sizeof(struct in6_addr)) == 0)) { | 630 | sizeof(struct in6_addr)) == 0)) { |
619 | found = 1; | 631 | found = 1; |
620 | break; | 632 | break; |
621 | } | 633 | } |
622 | } | 634 | } |
623 | if (found){ | 635 | if (found) { |
624 | addr->users += todo->users; | 636 | addr->users += todo->users; |
625 | if (addr->users <= 0){ | 637 | if (addr->users <= 0){ |
626 | *__addr = addr; | 638 | *__addr = addr; |
@@ -632,7 +644,7 @@ __qeth_ref_ip_on_card(struct qeth_card *card, struct qeth_ipaddr *todo, | |||
632 | return 0; | 644 | return 0; |
633 | } | 645 | } |
634 | } | 646 | } |
635 | if (todo->users > 0){ | 647 | if (todo->users > 0) { |
636 | /* for VIPA and RXIP limit refcount to 1 */ | 648 | /* for VIPA and RXIP limit refcount to 1 */ |
637 | if (todo->type != QETH_IP_TYPE_NORMAL) | 649 | if (todo->type != QETH_IP_TYPE_NORMAL) |
638 | todo->users = 1; | 650 | todo->users = 1; |
@@ -682,12 +694,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) && | 694 | if ((addr->type == QETH_IP_TYPE_DEL_ALL_MC) && |
683 | (tmp->type == QETH_IP_TYPE_DEL_ALL_MC)) | 695 | (tmp->type == QETH_IP_TYPE_DEL_ALL_MC)) |
684 | return 0; | 696 | return 0; |
697 | if (card->options.layer2) { | ||
698 | if ((tmp->type == addr->type) && | ||
699 | (tmp->is_multicast == addr->is_multicast) && | ||
700 | (memcmp(&tmp->mac, &addr->mac, | ||
701 | OSA_ADDR_LEN) == 0)) { | ||
702 | found = 1; | ||
703 | break; | ||
704 | } | ||
705 | continue; | ||
706 | } | ||
685 | if ((tmp->proto == QETH_PROT_IPV4) && | 707 | if ((tmp->proto == QETH_PROT_IPV4) && |
686 | (addr->proto == QETH_PROT_IPV4) && | 708 | (addr->proto == QETH_PROT_IPV4) && |
687 | (tmp->type == addr->type) && | 709 | (tmp->type == addr->type) && |
688 | (tmp->is_multicast == addr->is_multicast) && | 710 | (tmp->is_multicast == addr->is_multicast) && |
689 | (tmp->u.a4.addr == addr->u.a4.addr) && | 711 | (tmp->u.a4.addr == addr->u.a4.addr) && |
690 | (tmp->u.a4.mask == addr->u.a4.mask) ){ | 712 | (tmp->u.a4.mask == addr->u.a4.mask)) { |
691 | found = 1; | 713 | found = 1; |
692 | break; | 714 | break; |
693 | } | 715 | } |
@@ -697,7 +719,7 @@ __qeth_insert_ip_todo(struct qeth_card *card, struct qeth_ipaddr *addr, int add) | |||
697 | (tmp->is_multicast == addr->is_multicast) && | 719 | (tmp->is_multicast == addr->is_multicast) && |
698 | (tmp->u.a6.pfxlen == addr->u.a6.pfxlen) && | 720 | (tmp->u.a6.pfxlen == addr->u.a6.pfxlen) && |
699 | (memcmp(&tmp->u.a6.addr, &addr->u.a6.addr, | 721 | (memcmp(&tmp->u.a6.addr, &addr->u.a6.addr, |
700 | sizeof(struct in6_addr)) == 0) ){ | 722 | sizeof(struct in6_addr)) == 0)) { |
701 | found = 1; | 723 | found = 1; |
702 | break; | 724 | break; |
703 | } | 725 | } |
@@ -707,7 +729,7 @@ __qeth_insert_ip_todo(struct qeth_card *card, struct qeth_ipaddr *addr, int add) | |||
707 | tmp->users += addr->users; | 729 | tmp->users += addr->users; |
708 | else | 730 | else |
709 | tmp->users += add? 1:-1; | 731 | tmp->users += add? 1:-1; |
710 | if (tmp->users == 0){ | 732 | if (tmp->users == 0) { |
711 | list_del(&tmp->entry); | 733 | list_del(&tmp->entry); |
712 | kfree(tmp); | 734 | kfree(tmp); |
713 | } | 735 | } |
@@ -738,12 +760,15 @@ qeth_delete_ip(struct qeth_card *card, struct qeth_ipaddr *addr) | |||
738 | unsigned long flags; | 760 | unsigned long flags; |
739 | int rc = 0; | 761 | int rc = 0; |
740 | 762 | ||
741 | QETH_DBF_TEXT(trace,4,"delip"); | 763 | QETH_DBF_TEXT(trace, 4, "delip"); |
742 | if (addr->proto == QETH_PROT_IPV4) | 764 | |
743 | QETH_DBF_HEX(trace,4,&addr->u.a4.addr,4); | 765 | if (card->options.layer2) |
766 | QETH_DBF_HEX(trace, 4, &addr->mac, 6); | ||
767 | else if (addr->proto == QETH_PROT_IPV4) | ||
768 | QETH_DBF_HEX(trace, 4, &addr->u.a4.addr, 4); | ||
744 | else { | 769 | else { |
745 | QETH_DBF_HEX(trace,4,&addr->u.a6.addr,8); | 770 | QETH_DBF_HEX(trace, 4, &addr->u.a6.addr, 8); |
746 | QETH_DBF_HEX(trace,4,((char *)&addr->u.a6.addr)+8,8); | 771 | QETH_DBF_HEX(trace, 4, ((char *)&addr->u.a6.addr) + 8, 8); |
747 | } | 772 | } |
748 | spin_lock_irqsave(&card->ip_lock, flags); | 773 | spin_lock_irqsave(&card->ip_lock, flags); |
749 | rc = __qeth_insert_ip_todo(card, addr, 0); | 774 | rc = __qeth_insert_ip_todo(card, addr, 0); |
@@ -757,12 +782,14 @@ qeth_add_ip(struct qeth_card *card, struct qeth_ipaddr *addr) | |||
757 | unsigned long flags; | 782 | unsigned long flags; |
758 | int rc = 0; | 783 | int rc = 0; |
759 | 784 | ||
760 | QETH_DBF_TEXT(trace,4,"addip"); | 785 | QETH_DBF_TEXT(trace, 4, "addip"); |
761 | if (addr->proto == QETH_PROT_IPV4) | 786 | if (card->options.layer2) |
762 | QETH_DBF_HEX(trace,4,&addr->u.a4.addr,4); | 787 | QETH_DBF_HEX(trace, 4, &addr->mac, 6); |
788 | else if (addr->proto == QETH_PROT_IPV4) | ||
789 | QETH_DBF_HEX(trace, 4, &addr->u.a4.addr, 4); | ||
763 | else { | 790 | else { |
764 | QETH_DBF_HEX(trace,4,&addr->u.a6.addr,8); | 791 | QETH_DBF_HEX(trace, 4, &addr->u.a6.addr, 8); |
765 | QETH_DBF_HEX(trace,4,((char *)&addr->u.a6.addr)+8,8); | 792 | QETH_DBF_HEX(trace, 4, ((char *)&addr->u.a6.addr) + 8, 8); |
766 | } | 793 | } |
767 | spin_lock_irqsave(&card->ip_lock, flags); | 794 | spin_lock_irqsave(&card->ip_lock, flags); |
768 | rc = __qeth_insert_ip_todo(card, addr, 1); | 795 | rc = __qeth_insert_ip_todo(card, addr, 1); |
@@ -775,7 +802,7 @@ __qeth_delete_all_mc(struct qeth_card *card, unsigned long *flags) | |||
775 | { | 802 | { |
776 | struct qeth_ipaddr *addr, *tmp; | 803 | struct qeth_ipaddr *addr, *tmp; |
777 | int rc; | 804 | int rc; |
778 | 805 | again: | |
779 | list_for_each_entry_safe(addr, tmp, &card->ip_list, entry) { | 806 | list_for_each_entry_safe(addr, tmp, &card->ip_list, entry) { |
780 | if (addr->is_multicast) { | 807 | if (addr->is_multicast) { |
781 | spin_unlock_irqrestore(&card->ip_lock, *flags); | 808 | spin_unlock_irqrestore(&card->ip_lock, *flags); |
@@ -784,6 +811,7 @@ __qeth_delete_all_mc(struct qeth_card *card, unsigned long *flags) | |||
784 | if (!rc) { | 811 | if (!rc) { |
785 | list_del(&addr->entry); | 812 | list_del(&addr->entry); |
786 | kfree(addr); | 813 | kfree(addr); |
814 | goto again; | ||
787 | } | 815 | } |
788 | } | 816 | } |
789 | } | 817 | } |
@@ -851,6 +879,7 @@ qeth_set_ip_addr_list(struct qeth_card *card) | |||
851 | 879 | ||
852 | static void qeth_delete_mc_addresses(struct qeth_card *); | 880 | static void qeth_delete_mc_addresses(struct qeth_card *); |
853 | static void qeth_add_multicast_ipv4(struct qeth_card *); | 881 | static void qeth_add_multicast_ipv4(struct qeth_card *); |
882 | static void qeth_layer2_add_multicast(struct qeth_card *); | ||
854 | #ifdef CONFIG_QETH_IPV6 | 883 | #ifdef CONFIG_QETH_IPV6 |
855 | static void qeth_add_multicast_ipv6(struct qeth_card *); | 884 | static void qeth_add_multicast_ipv6(struct qeth_card *); |
856 | #endif | 885 | #endif |
@@ -939,6 +968,24 @@ qeth_register_ip_addresses(void *ptr) | |||
939 | return 0; | 968 | return 0; |
940 | } | 969 | } |
941 | 970 | ||
971 | /* | ||
972 | * Drive the SET_PROMISC_MODE thread | ||
973 | */ | ||
974 | static int | ||
975 | qeth_set_promisc_mode(void *ptr) | ||
976 | { | ||
977 | struct qeth_card *card = (struct qeth_card *) ptr; | ||
978 | |||
979 | daemonize("qeth_setprm"); | ||
980 | QETH_DBF_TEXT(trace,4,"setprm1"); | ||
981 | if (!qeth_do_run_thread(card, QETH_SET_PROMISC_MODE_THREAD)) | ||
982 | return 0; | ||
983 | QETH_DBF_TEXT(trace,4,"setprm2"); | ||
984 | qeth_setadp_promisc_mode(card); | ||
985 | qeth_clear_thread_running_bit(card, QETH_SET_PROMISC_MODE_THREAD); | ||
986 | return 0; | ||
987 | } | ||
988 | |||
942 | static int | 989 | static int |
943 | qeth_recover(void *ptr) | 990 | qeth_recover(void *ptr) |
944 | { | 991 | { |
@@ -1005,6 +1052,8 @@ qeth_start_kernel_thread(struct qeth_card *card) | |||
1005 | 1052 | ||
1006 | if (qeth_do_start_thread(card, QETH_SET_IP_THREAD)) | 1053 | if (qeth_do_start_thread(card, QETH_SET_IP_THREAD)) |
1007 | kernel_thread(qeth_register_ip_addresses, (void *)card,SIGCHLD); | 1054 | kernel_thread(qeth_register_ip_addresses, (void *)card,SIGCHLD); |
1055 | if (qeth_do_start_thread(card, QETH_SET_PROMISC_MODE_THREAD)) | ||
1056 | kernel_thread(qeth_set_promisc_mode, (void *)card, SIGCHLD); | ||
1008 | if (qeth_do_start_thread(card, QETH_RECOVER_THREAD)) | 1057 | if (qeth_do_start_thread(card, QETH_RECOVER_THREAD)) |
1009 | kernel_thread(qeth_recover, (void *) card, SIGCHLD); | 1058 | kernel_thread(qeth_recover, (void *) card, SIGCHLD); |
1010 | } | 1059 | } |
@@ -3749,7 +3798,7 @@ qeth_open(struct net_device *dev) | |||
3749 | 3798 | ||
3750 | if ( (card->info.type != QETH_CARD_TYPE_OSN) && | 3799 | if ( (card->info.type != QETH_CARD_TYPE_OSN) && |
3751 | (card->options.layer2) && | 3800 | (card->options.layer2) && |
3752 | (!card->info.layer2_mac_registered)) { | 3801 | (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))) { |
3753 | QETH_DBF_TEXT(trace,4,"nomacadr"); | 3802 | QETH_DBF_TEXT(trace,4,"nomacadr"); |
3754 | return -EPERM; | 3803 | return -EPERM; |
3755 | } | 3804 | } |
@@ -4311,6 +4360,8 @@ qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue, | |||
4311 | out: | 4360 | out: |
4312 | if (flush_count) | 4361 | if (flush_count) |
4313 | qeth_flush_buffers(queue, 0, start_index, flush_count); | 4362 | qeth_flush_buffers(queue, 0, start_index, flush_count); |
4363 | else if (!atomic_read(&queue->set_pci_flags_count)) | ||
4364 | atomic_swap(&queue->state, QETH_OUT_Q_LOCKED_FLUSH); | ||
4314 | /* | 4365 | /* |
4315 | * queue->state will go from LOCKED -> UNLOCKED or from | 4366 | * queue->state will go from LOCKED -> UNLOCKED or from |
4316 | * LOCKED_FLUSH -> LOCKED if output_handler wanted to 'notify' us | 4367 | * LOCKED_FLUSH -> LOCKED if output_handler wanted to 'notify' us |
@@ -4975,6 +5026,10 @@ qeth_default_setassparms_cb(struct qeth_card *, struct qeth_reply *, | |||
4975 | unsigned long); | 5026 | unsigned long); |
4976 | 5027 | ||
4977 | static int | 5028 | static int |
5029 | qeth_default_setadapterparms_cb(struct qeth_card *card, | ||
5030 | struct qeth_reply *reply, | ||
5031 | unsigned long data); | ||
5032 | static int | ||
4978 | qeth_send_setassparms(struct qeth_card *, struct qeth_cmd_buffer *, | 5033 | qeth_send_setassparms(struct qeth_card *, struct qeth_cmd_buffer *, |
4979 | __u16, long, | 5034 | __u16, long, |
4980 | int (*reply_cb) | 5035 | int (*reply_cb) |
@@ -5301,8 +5356,7 @@ qeth_free_vlan_addresses4(struct qeth_card *card, unsigned short vid) | |||
5301 | struct qeth_ipaddr *addr; | 5356 | struct qeth_ipaddr *addr; |
5302 | 5357 | ||
5303 | QETH_DBF_TEXT(trace, 4, "frvaddr4"); | 5358 | QETH_DBF_TEXT(trace, 4, "frvaddr4"); |
5304 | if (!card->vlangrp) | 5359 | |
5305 | return; | ||
5306 | rcu_read_lock(); | 5360 | rcu_read_lock(); |
5307 | in_dev = __in_dev_get_rcu(card->vlangrp->vlan_devices[vid]); | 5361 | in_dev = __in_dev_get_rcu(card->vlangrp->vlan_devices[vid]); |
5308 | if (!in_dev) | 5362 | if (!in_dev) |
@@ -5330,8 +5384,7 @@ qeth_free_vlan_addresses6(struct qeth_card *card, unsigned short vid) | |||
5330 | struct qeth_ipaddr *addr; | 5384 | struct qeth_ipaddr *addr; |
5331 | 5385 | ||
5332 | QETH_DBF_TEXT(trace, 4, "frvaddr6"); | 5386 | QETH_DBF_TEXT(trace, 4, "frvaddr6"); |
5333 | if (!card->vlangrp) | 5387 | |
5334 | return; | ||
5335 | in6_dev = in6_dev_get(card->vlangrp->vlan_devices[vid]); | 5388 | in6_dev = in6_dev_get(card->vlangrp->vlan_devices[vid]); |
5336 | if (!in6_dev) | 5389 | if (!in6_dev) |
5337 | return; | 5390 | return; |
@@ -5351,10 +5404,38 @@ qeth_free_vlan_addresses6(struct qeth_card *card, unsigned short vid) | |||
5351 | } | 5404 | } |
5352 | 5405 | ||
5353 | static void | 5406 | static void |
5407 | qeth_free_vlan_addresses(struct qeth_card *card, unsigned short vid) | ||
5408 | { | ||
5409 | if (card->options.layer2 || !card->vlangrp) | ||
5410 | return; | ||
5411 | qeth_free_vlan_addresses4(card, vid); | ||
5412 | qeth_free_vlan_addresses6(card, vid); | ||
5413 | } | ||
5414 | |||
5415 | static int | ||
5416 | qeth_layer2_send_setdelvlan_cb(struct qeth_card *card, | ||
5417 | struct qeth_reply *reply, | ||
5418 | unsigned long data) | ||
5419 | { | ||
5420 | struct qeth_ipa_cmd *cmd; | ||
5421 | |||
5422 | QETH_DBF_TEXT(trace, 2, "L2sdvcb"); | ||
5423 | cmd = (struct qeth_ipa_cmd *) data; | ||
5424 | if (cmd->hdr.return_code) { | ||
5425 | PRINT_ERR("Error in processing VLAN %i on %s: 0x%x. " | ||
5426 | "Continuing\n",cmd->data.setdelvlan.vlan_id, | ||
5427 | QETH_CARD_IFNAME(card), cmd->hdr.return_code); | ||
5428 | QETH_DBF_TEXT_(trace, 2, "L2VL%4x", cmd->hdr.command); | ||
5429 | QETH_DBF_TEXT_(trace, 2, "L2%s", CARD_BUS_ID(card)); | ||
5430 | QETH_DBF_TEXT_(trace, 2, "err%d", cmd->hdr.return_code); | ||
5431 | } | ||
5432 | return 0; | ||
5433 | } | ||
5434 | |||
5435 | static int | ||
5354 | qeth_layer2_send_setdelvlan(struct qeth_card *card, __u16 i, | 5436 | qeth_layer2_send_setdelvlan(struct qeth_card *card, __u16 i, |
5355 | enum qeth_ipa_cmds ipacmd) | 5437 | enum qeth_ipa_cmds ipacmd) |
5356 | { | 5438 | { |
5357 | int rc; | ||
5358 | struct qeth_ipa_cmd *cmd; | 5439 | struct qeth_ipa_cmd *cmd; |
5359 | struct qeth_cmd_buffer *iob; | 5440 | struct qeth_cmd_buffer *iob; |
5360 | 5441 | ||
@@ -5362,15 +5443,8 @@ qeth_layer2_send_setdelvlan(struct qeth_card *card, __u16 i, | |||
5362 | iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4); | 5443 | iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4); |
5363 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 5444 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
5364 | cmd->data.setdelvlan.vlan_id = i; | 5445 | cmd->data.setdelvlan.vlan_id = i; |
5365 | 5446 | return qeth_send_ipa_cmd(card, iob, | |
5366 | rc = qeth_send_ipa_cmd(card, iob, NULL, NULL); | 5447 | qeth_layer2_send_setdelvlan_cb, NULL); |
5367 | if (rc) { | ||
5368 | PRINT_ERR("Error in processing VLAN %i on %s: 0x%x. " | ||
5369 | "Continuing\n",i, QETH_CARD_IFNAME(card), rc); | ||
5370 | QETH_DBF_TEXT_(trace, 2, "L2VL%4x", ipacmd); | ||
5371 | QETH_DBF_TEXT_(trace, 2, "L2%s", CARD_BUS_ID(card)); | ||
5372 | QETH_DBF_TEXT_(trace, 2, "err%d", rc); | ||
5373 | } | ||
5374 | } | 5448 | } |
5375 | 5449 | ||
5376 | static void | 5450 | static void |
@@ -5420,8 +5494,7 @@ qeth_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) | |||
5420 | qeth_free_vlan_skbs(card, vid); | 5494 | qeth_free_vlan_skbs(card, vid); |
5421 | spin_lock_irqsave(&card->vlanlock, flags); | 5495 | spin_lock_irqsave(&card->vlanlock, flags); |
5422 | /* unregister IP addresses of vlan device */ | 5496 | /* unregister IP addresses of vlan device */ |
5423 | qeth_free_vlan_addresses4(card, vid); | 5497 | qeth_free_vlan_addresses(card, vid); |
5424 | qeth_free_vlan_addresses6(card, vid); | ||
5425 | if (card->vlangrp) | 5498 | if (card->vlangrp) |
5426 | card->vlangrp->vlan_devices[vid] = NULL; | 5499 | card->vlangrp->vlan_devices[vid] = NULL; |
5427 | spin_unlock_irqrestore(&card->vlanlock, flags); | 5500 | spin_unlock_irqrestore(&card->vlanlock, flags); |
@@ -5430,6 +5503,59 @@ qeth_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) | |||
5430 | qeth_set_multicast_list(card->dev); | 5503 | qeth_set_multicast_list(card->dev); |
5431 | } | 5504 | } |
5432 | #endif | 5505 | #endif |
5506 | /** | ||
5507 | * Examine hardware response to SET_PROMISC_MODE | ||
5508 | */ | ||
5509 | static int | ||
5510 | qeth_setadp_promisc_mode_cb(struct qeth_card *card, | ||
5511 | struct qeth_reply *reply, | ||
5512 | unsigned long data) | ||
5513 | { | ||
5514 | struct qeth_ipa_cmd *cmd; | ||
5515 | struct qeth_ipacmd_setadpparms *setparms; | ||
5516 | |||
5517 | QETH_DBF_TEXT(trace,4,"prmadpcb"); | ||
5518 | |||
5519 | cmd = (struct qeth_ipa_cmd *) data; | ||
5520 | setparms = &(cmd->data.setadapterparms); | ||
5521 | |||
5522 | qeth_default_setadapterparms_cb(card, reply, (unsigned long)cmd); | ||
5523 | if (cmd->hdr.return_code) { | ||
5524 | QETH_DBF_TEXT_(trace,4,"prmrc%2.2x",cmd->hdr.return_code); | ||
5525 | setparms->data.mode = SET_PROMISC_MODE_OFF; | ||
5526 | } | ||
5527 | card->info.promisc_mode = setparms->data.mode; | ||
5528 | return 0; | ||
5529 | } | ||
5530 | /* | ||
5531 | * Set promiscuous mode (on or off) (SET_PROMISC_MODE command) | ||
5532 | */ | ||
5533 | static void | ||
5534 | qeth_setadp_promisc_mode(struct qeth_card *card) | ||
5535 | { | ||
5536 | enum qeth_ipa_promisc_modes mode; | ||
5537 | struct net_device *dev = card->dev; | ||
5538 | struct qeth_cmd_buffer *iob; | ||
5539 | struct qeth_ipa_cmd *cmd; | ||
5540 | |||
5541 | QETH_DBF_TEXT(trace, 4, "setprom"); | ||
5542 | |||
5543 | if (((dev->flags & IFF_PROMISC) && | ||
5544 | (card->info.promisc_mode == SET_PROMISC_MODE_ON)) || | ||
5545 | (!(dev->flags & IFF_PROMISC) && | ||
5546 | (card->info.promisc_mode == SET_PROMISC_MODE_OFF))) | ||
5547 | return; | ||
5548 | mode = SET_PROMISC_MODE_OFF; | ||
5549 | if (dev->flags & IFF_PROMISC) | ||
5550 | mode = SET_PROMISC_MODE_ON; | ||
5551 | QETH_DBF_TEXT_(trace, 4, "mode:%x", mode); | ||
5552 | |||
5553 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_PROMISC_MODE, | ||
5554 | sizeof(struct qeth_ipacmd_setadpparms)); | ||
5555 | cmd = (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE); | ||
5556 | cmd->data.setadapterparms.data.mode = mode; | ||
5557 | qeth_send_ipa_cmd(card, iob, qeth_setadp_promisc_mode_cb, NULL); | ||
5558 | } | ||
5433 | 5559 | ||
5434 | /** | 5560 | /** |
5435 | * set multicast address on card | 5561 | * set multicast address on card |
@@ -5444,12 +5570,22 @@ qeth_set_multicast_list(struct net_device *dev) | |||
5444 | 5570 | ||
5445 | QETH_DBF_TEXT(trace,3,"setmulti"); | 5571 | QETH_DBF_TEXT(trace,3,"setmulti"); |
5446 | qeth_delete_mc_addresses(card); | 5572 | qeth_delete_mc_addresses(card); |
5573 | if (card->options.layer2) { | ||
5574 | qeth_layer2_add_multicast(card); | ||
5575 | goto out; | ||
5576 | } | ||
5447 | qeth_add_multicast_ipv4(card); | 5577 | qeth_add_multicast_ipv4(card); |
5448 | #ifdef CONFIG_QETH_IPV6 | 5578 | #ifdef CONFIG_QETH_IPV6 |
5449 | qeth_add_multicast_ipv6(card); | 5579 | qeth_add_multicast_ipv6(card); |
5450 | #endif | 5580 | #endif |
5581 | out: | ||
5451 | if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0) | 5582 | if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0) |
5452 | schedule_work(&card->kernel_thread_starter); | 5583 | schedule_work(&card->kernel_thread_starter); |
5584 | if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE)) | ||
5585 | return; | ||
5586 | if (qeth_set_thread_start_bit(card, QETH_SET_PROMISC_MODE_THREAD)==0) | ||
5587 | schedule_work(&card->kernel_thread_starter); | ||
5588 | |||
5453 | } | 5589 | } |
5454 | 5590 | ||
5455 | static int | 5591 | static int |
@@ -5657,6 +5793,24 @@ qeth_add_multicast_ipv4(struct qeth_card *card) | |||
5657 | in_dev_put(in4_dev); | 5793 | in_dev_put(in4_dev); |
5658 | } | 5794 | } |
5659 | 5795 | ||
5796 | static void | ||
5797 | qeth_layer2_add_multicast(struct qeth_card *card) | ||
5798 | { | ||
5799 | struct qeth_ipaddr *ipm; | ||
5800 | struct dev_mc_list *dm; | ||
5801 | |||
5802 | QETH_DBF_TEXT(trace,4,"L2addmc"); | ||
5803 | for (dm = card->dev->mc_list; dm; dm = dm->next) { | ||
5804 | ipm = qeth_get_addr_buffer(QETH_PROT_IPV4); | ||
5805 | if (!ipm) | ||
5806 | continue; | ||
5807 | memcpy(ipm->mac,dm->dmi_addr,MAX_ADDR_LEN); | ||
5808 | ipm->is_multicast = 1; | ||
5809 | if (!qeth_add_ip(card, ipm)) | ||
5810 | kfree(ipm); | ||
5811 | } | ||
5812 | } | ||
5813 | |||
5660 | #ifdef CONFIG_QETH_IPV6 | 5814 | #ifdef CONFIG_QETH_IPV6 |
5661 | static inline void | 5815 | static inline void |
5662 | qeth_add_mc6(struct qeth_card *card, struct inet6_dev *in6_dev) | 5816 | qeth_add_mc6(struct qeth_card *card, struct inet6_dev *in6_dev) |
@@ -5825,10 +5979,10 @@ qeth_layer2_send_setmac_cb(struct qeth_card *card, | |||
5825 | PRINT_WARN("Error in registering MAC address on " \ | 5979 | PRINT_WARN("Error in registering MAC address on " \ |
5826 | "device %s: x%x\n", CARD_BUS_ID(card), | 5980 | "device %s: x%x\n", CARD_BUS_ID(card), |
5827 | cmd->hdr.return_code); | 5981 | cmd->hdr.return_code); |
5828 | card->info.layer2_mac_registered = 0; | 5982 | card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; |
5829 | cmd->hdr.return_code = -EIO; | 5983 | cmd->hdr.return_code = -EIO; |
5830 | } else { | 5984 | } else { |
5831 | card->info.layer2_mac_registered = 1; | 5985 | card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED; |
5832 | memcpy(card->dev->dev_addr,cmd->data.setdelmac.mac, | 5986 | memcpy(card->dev->dev_addr,cmd->data.setdelmac.mac, |
5833 | OSA_ADDR_LEN); | 5987 | OSA_ADDR_LEN); |
5834 | PRINT_INFO("MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x " | 5988 | PRINT_INFO("MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x " |
@@ -5866,7 +6020,7 @@ qeth_layer2_send_delmac_cb(struct qeth_card *card, | |||
5866 | cmd->hdr.return_code = -EIO; | 6020 | cmd->hdr.return_code = -EIO; |
5867 | return 0; | 6021 | return 0; |
5868 | } | 6022 | } |
5869 | card->info.layer2_mac_registered = 0; | 6023 | card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; |
5870 | 6024 | ||
5871 | return 0; | 6025 | return 0; |
5872 | } | 6026 | } |
@@ -5874,7 +6028,7 @@ static int | |||
5874 | qeth_layer2_send_delmac(struct qeth_card *card, __u8 *mac) | 6028 | qeth_layer2_send_delmac(struct qeth_card *card, __u8 *mac) |
5875 | { | 6029 | { |
5876 | QETH_DBF_TEXT(trace, 2, "L2Delmac"); | 6030 | QETH_DBF_TEXT(trace, 2, "L2Delmac"); |
5877 | if (!card->info.layer2_mac_registered) | 6031 | if (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED)) |
5878 | return 0; | 6032 | return 0; |
5879 | return qeth_layer2_send_setdelmac(card, mac, IPA_CMD_DELVMAC, | 6033 | return qeth_layer2_send_setdelmac(card, mac, IPA_CMD_DELVMAC, |
5880 | qeth_layer2_send_delmac_cb); | 6034 | qeth_layer2_send_delmac_cb); |
@@ -5896,7 +6050,7 @@ qeth_layer2_set_mac_address(struct net_device *dev, void *p) | |||
5896 | card = (struct qeth_card *) dev->priv; | 6050 | card = (struct qeth_card *) dev->priv; |
5897 | 6051 | ||
5898 | if (!card->options.layer2) { | 6052 | if (!card->options.layer2) { |
5899 | PRINT_WARN("Setting MAC address on %s is not supported" | 6053 | PRINT_WARN("Setting MAC address on %s is not supported " |
5900 | "in Layer 3 mode.\n", dev->name); | 6054 | "in Layer 3 mode.\n", dev->name); |
5901 | QETH_DBF_TEXT(trace, 3, "setmcLY3"); | 6055 | QETH_DBF_TEXT(trace, 3, "setmcLY3"); |
5902 | return -EOPNOTSUPP; | 6056 | return -EOPNOTSUPP; |
@@ -6441,6 +6595,8 @@ qeth_default_setadapterparms_cb(struct qeth_card *card, | |||
6441 | return 0; | 6595 | return 0; |
6442 | } | 6596 | } |
6443 | 6597 | ||
6598 | |||
6599 | |||
6444 | static int | 6600 | static int |
6445 | qeth_query_setadapterparms_cb(struct qeth_card *card, struct qeth_reply *reply, | 6601 | qeth_query_setadapterparms_cb(struct qeth_card *card, struct qeth_reply *reply, |
6446 | unsigned long data) | 6602 | unsigned long data) |
@@ -6481,8 +6637,13 @@ qeth_setadpparms_change_macaddr_cb(struct qeth_card *card, | |||
6481 | QETH_DBF_TEXT(trace,4,"chgmaccb"); | 6637 | QETH_DBF_TEXT(trace,4,"chgmaccb"); |
6482 | 6638 | ||
6483 | cmd = (struct qeth_ipa_cmd *) data; | 6639 | cmd = (struct qeth_ipa_cmd *) data; |
6484 | memcpy(card->dev->dev_addr, | 6640 | if (!card->options.layer2 || card->info.guestlan || |
6485 | &cmd->data.setadapterparms.data.change_addr.addr,OSA_ADDR_LEN); | 6641 | !(card->info.mac_bits & QETH_LAYER2_MAC_READ)) { |
6642 | memcpy(card->dev->dev_addr, | ||
6643 | &cmd->data.setadapterparms.data.change_addr.addr, | ||
6644 | OSA_ADDR_LEN); | ||
6645 | card->info.mac_bits |= QETH_LAYER2_MAC_READ; | ||
6646 | } | ||
6486 | qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd); | 6647 | qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd); |
6487 | return 0; | 6648 | return 0; |
6488 | } | 6649 | } |
@@ -6602,6 +6763,12 @@ qeth_layer2_initialize(struct qeth_card *card) | |||
6602 | QETH_DBF_TEXT(setup, 2, "doL2init"); | 6763 | QETH_DBF_TEXT(setup, 2, "doL2init"); |
6603 | QETH_DBF_TEXT_(setup, 2, "doL2%s", CARD_BUS_ID(card)); | 6764 | QETH_DBF_TEXT_(setup, 2, "doL2%s", CARD_BUS_ID(card)); |
6604 | 6765 | ||
6766 | rc = qeth_query_setadapterparms(card); | ||
6767 | if (rc) { | ||
6768 | PRINT_WARN("could not query adapter parameters on device %s: " | ||
6769 | "x%x\n", CARD_BUS_ID(card), rc); | ||
6770 | } | ||
6771 | |||
6605 | rc = qeth_setadpparms_change_macaddr(card); | 6772 | rc = qeth_setadpparms_change_macaddr(card); |
6606 | if (rc) { | 6773 | if (rc) { |
6607 | PRINT_WARN("couldn't get MAC address on " | 6774 | PRINT_WARN("couldn't get MAC address on " |
@@ -8548,7 +8715,7 @@ EXPORT_SYMBOL(qeth_osn_deregister); | |||
8548 | EXPORT_SYMBOL(qeth_osn_assist); | 8715 | EXPORT_SYMBOL(qeth_osn_assist); |
8549 | module_init(qeth_init); | 8716 | module_init(qeth_init); |
8550 | module_exit(qeth_exit); | 8717 | module_exit(qeth_exit); |
8551 | MODULE_AUTHOR("Frank Pavlic <pavlic@de.ibm.com>"); | 8718 | MODULE_AUTHOR("Frank Pavlic <fpavlic@de.ibm.com>"); |
8552 | MODULE_DESCRIPTION("Linux on zSeries OSA Express and HiperSockets support\n" \ | 8719 | MODULE_DESCRIPTION("Linux on zSeries OSA Express and HiperSockets support\n" \ |
8553 | "Copyright 2000,2003 IBM Corporation\n"); | 8720 | "Copyright 2000,2003 IBM Corporation\n"); |
8554 | 8721 | ||
diff --git a/drivers/s390/net/qeth_mpc.c b/drivers/s390/net/qeth_mpc.c index 30e053d3cac2..f0a080a9e515 100644 --- a/drivers/s390/net/qeth_mpc.c +++ b/drivers/s390/net/qeth_mpc.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Linux on zSeries OSA Express and HiperSockets support | 4 | * Linux on zSeries OSA Express and HiperSockets support |
5 | * | 5 | * |
6 | * Copyright 2000,2003 IBM Corporation | 6 | * Copyright 2000,2003 IBM Corporation |
7 | * Author(s): Frank Pavlic <pavlic@de.ibm.com> | 7 | * Author(s): Frank Pavlic <fpavlic@de.ibm.com> |
8 | * Thomas Spatzier <tspat@de.ibm.com> | 8 | * Thomas Spatzier <tspat@de.ibm.com> |
9 | * | 9 | * |
10 | */ | 10 | */ |
diff --git a/drivers/s390/net/qeth_mpc.h b/drivers/s390/net/qeth_mpc.h index 7edc5f1fc0d2..5f71486e708c 100644 --- a/drivers/s390/net/qeth_mpc.h +++ b/drivers/s390/net/qeth_mpc.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * Copyright 2000,2003 IBM Corporation | 6 | * Copyright 2000,2003 IBM Corporation |
7 | * Author(s): Utz Bacher <utz.bacher@de.ibm.com> | 7 | * Author(s): Utz Bacher <utz.bacher@de.ibm.com> |
8 | * Thomas Spatzier <tspat@de.ibm.com> | 8 | * Thomas Spatzier <tspat@de.ibm.com> |
9 | * Frank Pavlic <pavlic@de.ibm.com> | 9 | * Frank Pavlic <fpavlic@de.ibm.com> |
10 | * | 10 | * |
11 | */ | 11 | */ |
12 | #ifndef __QETH_MPC_H__ | 12 | #ifndef __QETH_MPC_H__ |
@@ -14,7 +14,7 @@ | |||
14 | 14 | ||
15 | #include <asm/qeth.h> | 15 | #include <asm/qeth.h> |
16 | 16 | ||
17 | #define VERSION_QETH_MPC_H "$Revision: 1.43 $" | 17 | #define VERSION_QETH_MPC_H "$Revision: 1.44 $" |
18 | 18 | ||
19 | extern const char *VERSION_QETH_MPC_C; | 19 | extern const char *VERSION_QETH_MPC_C; |
20 | 20 | ||
@@ -217,7 +217,7 @@ enum qeth_ipa_setadp_cmd { | |||
217 | IPA_SETADP_SEND_OSA_MESSAGE = 0x0100, | 217 | IPA_SETADP_SEND_OSA_MESSAGE = 0x0100, |
218 | IPA_SETADP_SET_SNMP_CONTROL = 0x0200, | 218 | IPA_SETADP_SET_SNMP_CONTROL = 0x0200, |
219 | IPA_SETADP_READ_SNMP_PARMS = 0x0400, | 219 | IPA_SETADP_READ_SNMP_PARMS = 0x0400, |
220 | IPA_SETADP_WRITE_SNMP_PARMS = 0x0800, | 220 | IPA_SETADP_SET_PROMISC_MODE = 0x0800, |
221 | IPA_SETADP_QUERY_CARD_INFO = 0x1000, | 221 | IPA_SETADP_QUERY_CARD_INFO = 0x1000, |
222 | }; | 222 | }; |
223 | enum qeth_ipa_mac_ops { | 223 | enum qeth_ipa_mac_ops { |
@@ -232,9 +232,12 @@ enum qeth_ipa_addr_ops { | |||
232 | CHANGE_ADDR_ADD_ADDR = 1, | 232 | CHANGE_ADDR_ADD_ADDR = 1, |
233 | CHANGE_ADDR_DEL_ADDR = 2, | 233 | CHANGE_ADDR_DEL_ADDR = 2, |
234 | CHANGE_ADDR_FLUSH_ADDR_TABLE = 4, | 234 | CHANGE_ADDR_FLUSH_ADDR_TABLE = 4, |
235 | |||
236 | |||
237 | }; | 235 | }; |
236 | enum qeth_ipa_promisc_modes { | ||
237 | SET_PROMISC_MODE_OFF = 0, | ||
238 | SET_PROMISC_MODE_ON = 1, | ||
239 | }; | ||
240 | |||
238 | /* (SET)DELIP(M) IPA stuff ***************************************************/ | 241 | /* (SET)DELIP(M) IPA stuff ***************************************************/ |
239 | struct qeth_ipacmd_setdelip4 { | 242 | struct qeth_ipacmd_setdelip4 { |
240 | __u8 ip_addr[4]; | 243 | __u8 ip_addr[4]; |
diff --git a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c index f91a02db5743..ddd6019ba092 100644 --- a/drivers/s390/net/qeth_sys.c +++ b/drivers/s390/net/qeth_sys.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * | 2 | * |
3 | * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.55 $) | 3 | * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.58 $) |
4 | * | 4 | * |
5 | * Linux on zSeries OSA Express and HiperSockets support | 5 | * Linux on zSeries OSA Express and HiperSockets support |
6 | * This file contains code related to sysfs. | 6 | * This file contains code related to sysfs. |
@@ -8,7 +8,7 @@ | |||
8 | * Copyright 2000,2003 IBM Corporation | 8 | * Copyright 2000,2003 IBM Corporation |
9 | * | 9 | * |
10 | * Author(s): Thomas Spatzier <tspat@de.ibm.com> | 10 | * Author(s): Thomas Spatzier <tspat@de.ibm.com> |
11 | * Frank Pavlic <pavlic@de.ibm.com> | 11 | * Frank Pavlic <fpavlic@de.ibm.com> |
12 | * | 12 | * |
13 | */ | 13 | */ |
14 | #include <linux/list.h> | 14 | #include <linux/list.h> |
@@ -20,7 +20,7 @@ | |||
20 | #include "qeth_mpc.h" | 20 | #include "qeth_mpc.h" |
21 | #include "qeth_fs.h" | 21 | #include "qeth_fs.h" |
22 | 22 | ||
23 | const char *VERSION_QETH_SYS_C = "$Revision: 1.55 $"; | 23 | const char *VERSION_QETH_SYS_C = "$Revision: 1.58 $"; |
24 | 24 | ||
25 | /*****************************************************************************/ | 25 | /*****************************************************************************/ |
26 | /* */ | 26 | /* */ |
@@ -1117,7 +1117,7 @@ qeth_parse_ipatoe(const char* buf, enum qeth_prot_versions proto, | |||
1117 | start = buf; | 1117 | start = buf; |
1118 | /* get address string */ | 1118 | /* get address string */ |
1119 | end = strchr(start, '/'); | 1119 | end = strchr(start, '/'); |
1120 | if (!end){ | 1120 | if (!end || (end-start >= 49)){ |
1121 | PRINT_WARN("Invalid format for ipato_addx/delx. " | 1121 | PRINT_WARN("Invalid format for ipato_addx/delx. " |
1122 | "Use <ip addr>/<mask bits>\n"); | 1122 | "Use <ip addr>/<mask bits>\n"); |
1123 | return -EINVAL; | 1123 | return -EINVAL; |
diff --git a/drivers/s390/net/qeth_tso.h b/drivers/s390/net/qeth_tso.h index ad33e6f466f1..e245af3c4cbd 100644 --- a/drivers/s390/net/qeth_tso.h +++ b/drivers/s390/net/qeth_tso.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * Copyright 2004 IBM Corporation | 6 | * Copyright 2004 IBM Corporation |
7 | * | 7 | * |
8 | * Author(s): Frank Pavlic <pavlic@de.ibm.com> | 8 | * Author(s): Frank Pavlic <fpavlic@de.ibm.com> |
9 | * | 9 | * |
10 | * $Revision: 1.7 $ $Date: 2005/05/04 20:19:18 $ | 10 | * $Revision: 1.7 $ $Date: 2005/05/04 20:19:18 $ |
11 | * | 11 | * |