diff options
Diffstat (limited to 'drivers/s390/net/qeth_main.c')
-rw-r--r-- | drivers/s390/net/qeth_main.c | 316 |
1 files changed, 240 insertions, 76 deletions
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 692003c9f896..f8f55cc468ba 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.251 $) |
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.251 $ $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.251 $" |
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 */ |
@@ -515,7 +518,8 @@ __qeth_set_offline(struct ccwgroup_device *cgdev, int recovery_mode) | |||
515 | 518 | ||
516 | QETH_DBF_TEXT(setup, 3, "setoffl"); | 519 | QETH_DBF_TEXT(setup, 3, "setoffl"); |
517 | QETH_DBF_HEX(setup, 3, &card, sizeof(void *)); | 520 | QETH_DBF_HEX(setup, 3, &card, sizeof(void *)); |
518 | 521 | ||
522 | netif_carrier_off(card->dev); | ||
519 | recover_flag = card->state; | 523 | recover_flag = card->state; |
520 | if (qeth_stop_card(card, recovery_mode) == -ERESTARTSYS){ | 524 | if (qeth_stop_card(card, recovery_mode) == -ERESTARTSYS){ |
521 | PRINT_WARN("Stopping card %s interrupted by user!\n", | 525 | PRINT_WARN("Stopping card %s interrupted by user!\n", |
@@ -602,11 +606,20 @@ __qeth_ref_ip_on_card(struct qeth_card *card, struct qeth_ipaddr *todo, | |||
602 | int found = 0; | 606 | int found = 0; |
603 | 607 | ||
604 | list_for_each_entry(addr, &card->ip_list, entry) { | 608 | list_for_each_entry(addr, &card->ip_list, entry) { |
609 | if (card->options.layer2) { | ||
610 | if ((addr->type == todo->type) && | ||
611 | (memcmp(&addr->mac, &todo->mac, | ||
612 | OSA_ADDR_LEN) == 0)) { | ||
613 | found = 1; | ||
614 | break; | ||
615 | } | ||
616 | continue; | ||
617 | } | ||
605 | if ((addr->proto == QETH_PROT_IPV4) && | 618 | if ((addr->proto == QETH_PROT_IPV4) && |
606 | (todo->proto == QETH_PROT_IPV4) && | 619 | (todo->proto == QETH_PROT_IPV4) && |
607 | (addr->type == todo->type) && | 620 | (addr->type == todo->type) && |
608 | (addr->u.a4.addr == todo->u.a4.addr) && | 621 | (addr->u.a4.addr == todo->u.a4.addr) && |
609 | (addr->u.a4.mask == todo->u.a4.mask) ){ | 622 | (addr->u.a4.mask == todo->u.a4.mask)) { |
610 | found = 1; | 623 | found = 1; |
611 | break; | 624 | break; |
612 | } | 625 | } |
@@ -615,12 +628,12 @@ __qeth_ref_ip_on_card(struct qeth_card *card, struct qeth_ipaddr *todo, | |||
615 | (addr->type == todo->type) && | 628 | (addr->type == todo->type) && |
616 | (addr->u.a6.pfxlen == todo->u.a6.pfxlen) && | 629 | (addr->u.a6.pfxlen == todo->u.a6.pfxlen) && |
617 | (memcmp(&addr->u.a6.addr, &todo->u.a6.addr, | 630 | (memcmp(&addr->u.a6.addr, &todo->u.a6.addr, |
618 | sizeof(struct in6_addr)) == 0)) { | 631 | sizeof(struct in6_addr)) == 0)) { |
619 | found = 1; | 632 | found = 1; |
620 | break; | 633 | break; |
621 | } | 634 | } |
622 | } | 635 | } |
623 | if (found){ | 636 | if (found) { |
624 | addr->users += todo->users; | 637 | addr->users += todo->users; |
625 | if (addr->users <= 0){ | 638 | if (addr->users <= 0){ |
626 | *__addr = addr; | 639 | *__addr = addr; |
@@ -632,7 +645,7 @@ __qeth_ref_ip_on_card(struct qeth_card *card, struct qeth_ipaddr *todo, | |||
632 | return 0; | 645 | return 0; |
633 | } | 646 | } |
634 | } | 647 | } |
635 | if (todo->users > 0){ | 648 | if (todo->users > 0) { |
636 | /* for VIPA and RXIP limit refcount to 1 */ | 649 | /* for VIPA and RXIP limit refcount to 1 */ |
637 | if (todo->type != QETH_IP_TYPE_NORMAL) | 650 | if (todo->type != QETH_IP_TYPE_NORMAL) |
638 | todo->users = 1; | 651 | todo->users = 1; |
@@ -682,12 +695,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) && | 695 | if ((addr->type == QETH_IP_TYPE_DEL_ALL_MC) && |
683 | (tmp->type == QETH_IP_TYPE_DEL_ALL_MC)) | 696 | (tmp->type == QETH_IP_TYPE_DEL_ALL_MC)) |
684 | return 0; | 697 | return 0; |
698 | if (card->options.layer2) { | ||
699 | if ((tmp->type == addr->type) && | ||
700 | (tmp->is_multicast == addr->is_multicast) && | ||
701 | (memcmp(&tmp->mac, &addr->mac, | ||
702 | OSA_ADDR_LEN) == 0)) { | ||
703 | found = 1; | ||
704 | break; | ||
705 | } | ||
706 | continue; | ||
707 | } | ||
685 | if ((tmp->proto == QETH_PROT_IPV4) && | 708 | if ((tmp->proto == QETH_PROT_IPV4) && |
686 | (addr->proto == QETH_PROT_IPV4) && | 709 | (addr->proto == QETH_PROT_IPV4) && |
687 | (tmp->type == addr->type) && | 710 | (tmp->type == addr->type) && |
688 | (tmp->is_multicast == addr->is_multicast) && | 711 | (tmp->is_multicast == addr->is_multicast) && |
689 | (tmp->u.a4.addr == addr->u.a4.addr) && | 712 | (tmp->u.a4.addr == addr->u.a4.addr) && |
690 | (tmp->u.a4.mask == addr->u.a4.mask) ){ | 713 | (tmp->u.a4.mask == addr->u.a4.mask)) { |
691 | found = 1; | 714 | found = 1; |
692 | break; | 715 | break; |
693 | } | 716 | } |
@@ -697,7 +720,7 @@ __qeth_insert_ip_todo(struct qeth_card *card, struct qeth_ipaddr *addr, int add) | |||
697 | (tmp->is_multicast == addr->is_multicast) && | 720 | (tmp->is_multicast == addr->is_multicast) && |
698 | (tmp->u.a6.pfxlen == addr->u.a6.pfxlen) && | 721 | (tmp->u.a6.pfxlen == addr->u.a6.pfxlen) && |
699 | (memcmp(&tmp->u.a6.addr, &addr->u.a6.addr, | 722 | (memcmp(&tmp->u.a6.addr, &addr->u.a6.addr, |
700 | sizeof(struct in6_addr)) == 0) ){ | 723 | sizeof(struct in6_addr)) == 0)) { |
701 | found = 1; | 724 | found = 1; |
702 | break; | 725 | break; |
703 | } | 726 | } |
@@ -707,7 +730,7 @@ __qeth_insert_ip_todo(struct qeth_card *card, struct qeth_ipaddr *addr, int add) | |||
707 | tmp->users += addr->users; | 730 | tmp->users += addr->users; |
708 | else | 731 | else |
709 | tmp->users += add? 1:-1; | 732 | tmp->users += add? 1:-1; |
710 | if (tmp->users == 0){ | 733 | if (tmp->users == 0) { |
711 | list_del(&tmp->entry); | 734 | list_del(&tmp->entry); |
712 | kfree(tmp); | 735 | kfree(tmp); |
713 | } | 736 | } |
@@ -738,12 +761,15 @@ qeth_delete_ip(struct qeth_card *card, struct qeth_ipaddr *addr) | |||
738 | unsigned long flags; | 761 | unsigned long flags; |
739 | int rc = 0; | 762 | int rc = 0; |
740 | 763 | ||
741 | QETH_DBF_TEXT(trace,4,"delip"); | 764 | QETH_DBF_TEXT(trace, 4, "delip"); |
742 | if (addr->proto == QETH_PROT_IPV4) | 765 | |
743 | QETH_DBF_HEX(trace,4,&addr->u.a4.addr,4); | 766 | if (card->options.layer2) |
767 | QETH_DBF_HEX(trace, 4, &addr->mac, 6); | ||
768 | else if (addr->proto == QETH_PROT_IPV4) | ||
769 | QETH_DBF_HEX(trace, 4, &addr->u.a4.addr, 4); | ||
744 | else { | 770 | else { |
745 | QETH_DBF_HEX(trace,4,&addr->u.a6.addr,8); | 771 | QETH_DBF_HEX(trace, 4, &addr->u.a6.addr, 8); |
746 | QETH_DBF_HEX(trace,4,((char *)&addr->u.a6.addr)+8,8); | 772 | QETH_DBF_HEX(trace, 4, ((char *)&addr->u.a6.addr) + 8, 8); |
747 | } | 773 | } |
748 | spin_lock_irqsave(&card->ip_lock, flags); | 774 | spin_lock_irqsave(&card->ip_lock, flags); |
749 | rc = __qeth_insert_ip_todo(card, addr, 0); | 775 | rc = __qeth_insert_ip_todo(card, addr, 0); |
@@ -757,12 +783,14 @@ qeth_add_ip(struct qeth_card *card, struct qeth_ipaddr *addr) | |||
757 | unsigned long flags; | 783 | unsigned long flags; |
758 | int rc = 0; | 784 | int rc = 0; |
759 | 785 | ||
760 | QETH_DBF_TEXT(trace,4,"addip"); | 786 | QETH_DBF_TEXT(trace, 4, "addip"); |
761 | if (addr->proto == QETH_PROT_IPV4) | 787 | if (card->options.layer2) |
762 | QETH_DBF_HEX(trace,4,&addr->u.a4.addr,4); | 788 | QETH_DBF_HEX(trace, 4, &addr->mac, 6); |
789 | else if (addr->proto == QETH_PROT_IPV4) | ||
790 | QETH_DBF_HEX(trace, 4, &addr->u.a4.addr, 4); | ||
763 | else { | 791 | else { |
764 | QETH_DBF_HEX(trace,4,&addr->u.a6.addr,8); | 792 | QETH_DBF_HEX(trace, 4, &addr->u.a6.addr, 8); |
765 | QETH_DBF_HEX(trace,4,((char *)&addr->u.a6.addr)+8,8); | 793 | QETH_DBF_HEX(trace, 4, ((char *)&addr->u.a6.addr) + 8, 8); |
766 | } | 794 | } |
767 | spin_lock_irqsave(&card->ip_lock, flags); | 795 | spin_lock_irqsave(&card->ip_lock, flags); |
768 | rc = __qeth_insert_ip_todo(card, addr, 1); | 796 | rc = __qeth_insert_ip_todo(card, addr, 1); |
@@ -775,7 +803,7 @@ __qeth_delete_all_mc(struct qeth_card *card, unsigned long *flags) | |||
775 | { | 803 | { |
776 | struct qeth_ipaddr *addr, *tmp; | 804 | struct qeth_ipaddr *addr, *tmp; |
777 | int rc; | 805 | int rc; |
778 | 806 | again: | |
779 | list_for_each_entry_safe(addr, tmp, &card->ip_list, entry) { | 807 | list_for_each_entry_safe(addr, tmp, &card->ip_list, entry) { |
780 | if (addr->is_multicast) { | 808 | if (addr->is_multicast) { |
781 | spin_unlock_irqrestore(&card->ip_lock, *flags); | 809 | spin_unlock_irqrestore(&card->ip_lock, *flags); |
@@ -784,6 +812,7 @@ __qeth_delete_all_mc(struct qeth_card *card, unsigned long *flags) | |||
784 | if (!rc) { | 812 | if (!rc) { |
785 | list_del(&addr->entry); | 813 | list_del(&addr->entry); |
786 | kfree(addr); | 814 | kfree(addr); |
815 | goto again; | ||
787 | } | 816 | } |
788 | } | 817 | } |
789 | } | 818 | } |
@@ -851,6 +880,7 @@ qeth_set_ip_addr_list(struct qeth_card *card) | |||
851 | 880 | ||
852 | static void qeth_delete_mc_addresses(struct qeth_card *); | 881 | static void qeth_delete_mc_addresses(struct qeth_card *); |
853 | static void qeth_add_multicast_ipv4(struct qeth_card *); | 882 | static void qeth_add_multicast_ipv4(struct qeth_card *); |
883 | static void qeth_layer2_add_multicast(struct qeth_card *); | ||
854 | #ifdef CONFIG_QETH_IPV6 | 884 | #ifdef CONFIG_QETH_IPV6 |
855 | static void qeth_add_multicast_ipv6(struct qeth_card *); | 885 | static void qeth_add_multicast_ipv6(struct qeth_card *); |
856 | #endif | 886 | #endif |
@@ -939,6 +969,24 @@ qeth_register_ip_addresses(void *ptr) | |||
939 | return 0; | 969 | return 0; |
940 | } | 970 | } |
941 | 971 | ||
972 | /* | ||
973 | * Drive the SET_PROMISC_MODE thread | ||
974 | */ | ||
975 | static int | ||
976 | qeth_set_promisc_mode(void *ptr) | ||
977 | { | ||
978 | struct qeth_card *card = (struct qeth_card *) ptr; | ||
979 | |||
980 | daemonize("qeth_setprm"); | ||
981 | QETH_DBF_TEXT(trace,4,"setprm1"); | ||
982 | if (!qeth_do_run_thread(card, QETH_SET_PROMISC_MODE_THREAD)) | ||
983 | return 0; | ||
984 | QETH_DBF_TEXT(trace,4,"setprm2"); | ||
985 | qeth_setadp_promisc_mode(card); | ||
986 | qeth_clear_thread_running_bit(card, QETH_SET_PROMISC_MODE_THREAD); | ||
987 | return 0; | ||
988 | } | ||
989 | |||
942 | static int | 990 | static int |
943 | qeth_recover(void *ptr) | 991 | qeth_recover(void *ptr) |
944 | { | 992 | { |
@@ -973,7 +1021,6 @@ void | |||
973 | qeth_schedule_recovery(struct qeth_card *card) | 1021 | qeth_schedule_recovery(struct qeth_card *card) |
974 | { | 1022 | { |
975 | QETH_DBF_TEXT(trace,2,"startrec"); | 1023 | QETH_DBF_TEXT(trace,2,"startrec"); |
976 | |||
977 | if (qeth_set_thread_start_bit(card, QETH_RECOVER_THREAD) == 0) | 1024 | if (qeth_set_thread_start_bit(card, QETH_RECOVER_THREAD) == 0) |
978 | schedule_work(&card->kernel_thread_starter); | 1025 | schedule_work(&card->kernel_thread_starter); |
979 | } | 1026 | } |
@@ -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 | } |
@@ -1661,7 +1710,6 @@ qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob) | |||
1661 | "IP address reset.\n", | 1710 | "IP address reset.\n", |
1662 | QETH_CARD_IFNAME(card), | 1711 | QETH_CARD_IFNAME(card), |
1663 | card->info.chpid); | 1712 | card->info.chpid); |
1664 | netif_carrier_on(card->dev); | ||
1665 | qeth_schedule_recovery(card); | 1713 | qeth_schedule_recovery(card); |
1666 | return NULL; | 1714 | return NULL; |
1667 | case IPA_CMD_MODCCID: | 1715 | case IPA_CMD_MODCCID: |
@@ -1910,7 +1958,7 @@ qeth_osn_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, | |||
1910 | { | 1958 | { |
1911 | u16 s1, s2; | 1959 | u16 s1, s2; |
1912 | 1960 | ||
1913 | QETH_DBF_TEXT(trace,4,"osndipa"); | 1961 | QETH_DBF_TEXT(trace,4,"osndipa"); |
1914 | 1962 | ||
1915 | qeth_prepare_ipa_cmd(card, iob, QETH_PROT_OSN2); | 1963 | qeth_prepare_ipa_cmd(card, iob, QETH_PROT_OSN2); |
1916 | s1 = (u16)(IPA_PDU_HEADER_SIZE + data_len); | 1964 | s1 = (u16)(IPA_PDU_HEADER_SIZE + data_len); |
@@ -2154,24 +2202,21 @@ qeth_ulp_setup(struct qeth_card *card) | |||
2154 | } | 2202 | } |
2155 | 2203 | ||
2156 | static inline int | 2204 | static inline int |
2157 | qeth_check_for_inbound_error(struct qeth_qdio_buffer *buf, | 2205 | qeth_check_qdio_errors(struct qdio_buffer *buf, unsigned int qdio_error, |
2158 | unsigned int qdio_error, | 2206 | unsigned int siga_error, const char *dbftext) |
2159 | unsigned int siga_error) | ||
2160 | { | 2207 | { |
2161 | int rc = 0; | ||
2162 | |||
2163 | if (qdio_error || siga_error) { | 2208 | if (qdio_error || siga_error) { |
2164 | QETH_DBF_TEXT(trace, 2, "qdinerr"); | 2209 | QETH_DBF_TEXT(trace, 2, dbftext); |
2165 | QETH_DBF_TEXT(qerr, 2, "qdinerr"); | 2210 | QETH_DBF_TEXT(qerr, 2, dbftext); |
2166 | QETH_DBF_TEXT_(qerr, 2, " F15=%02X", | 2211 | QETH_DBF_TEXT_(qerr, 2, " F15=%02X", |
2167 | buf->buffer->element[15].flags & 0xff); | 2212 | buf->element[15].flags & 0xff); |
2168 | QETH_DBF_TEXT_(qerr, 2, " F14=%02X", | 2213 | QETH_DBF_TEXT_(qerr, 2, " F14=%02X", |
2169 | buf->buffer->element[14].flags & 0xff); | 2214 | buf->element[14].flags & 0xff); |
2170 | QETH_DBF_TEXT_(qerr, 2, " qerr=%X", qdio_error); | 2215 | QETH_DBF_TEXT_(qerr, 2, " qerr=%X", qdio_error); |
2171 | QETH_DBF_TEXT_(qerr, 2, " serr=%X", siga_error); | 2216 | QETH_DBF_TEXT_(qerr, 2, " serr=%X", siga_error); |
2172 | rc = 1; | 2217 | return 1; |
2173 | } | 2218 | } |
2174 | return rc; | 2219 | return 0; |
2175 | } | 2220 | } |
2176 | 2221 | ||
2177 | static inline struct sk_buff * | 2222 | static inline struct sk_buff * |
@@ -2720,8 +2765,9 @@ qeth_qdio_input_handler(struct ccw_device * ccwdev, unsigned int status, | |||
2720 | for (i = first_element; i < (first_element + count); ++i) { | 2765 | for (i = first_element; i < (first_element + count); ++i) { |
2721 | index = i % QDIO_MAX_BUFFERS_PER_Q; | 2766 | index = i % QDIO_MAX_BUFFERS_PER_Q; |
2722 | buffer = &card->qdio.in_q->bufs[index]; | 2767 | buffer = &card->qdio.in_q->bufs[index]; |
2723 | if (!((status == QDIO_STATUS_LOOK_FOR_ERROR) && | 2768 | if (!((status & QDIO_STATUS_LOOK_FOR_ERROR) && |
2724 | qeth_check_for_inbound_error(buffer, qdio_err, siga_err))) | 2769 | qeth_check_qdio_errors(buffer->buffer, |
2770 | qdio_err, siga_err,"qinerr"))) | ||
2725 | qeth_process_inbound_buffer(card, buffer, index); | 2771 | qeth_process_inbound_buffer(card, buffer, index); |
2726 | /* clear buffer and give back to hardware */ | 2772 | /* clear buffer and give back to hardware */ |
2727 | qeth_put_buffer_pool_entry(card, buffer->pool_entry); | 2773 | qeth_put_buffer_pool_entry(card, buffer->pool_entry); |
@@ -2736,12 +2782,13 @@ qeth_qdio_input_handler(struct ccw_device * ccwdev, unsigned int status, | |||
2736 | static inline int | 2782 | static inline int |
2737 | qeth_handle_send_error(struct qeth_card *card, | 2783 | qeth_handle_send_error(struct qeth_card *card, |
2738 | struct qeth_qdio_out_buffer *buffer, | 2784 | struct qeth_qdio_out_buffer *buffer, |
2739 | int qdio_err, int siga_err) | 2785 | unsigned int qdio_err, unsigned int siga_err) |
2740 | { | 2786 | { |
2741 | int sbalf15 = buffer->buffer->element[15].flags & 0xff; | 2787 | int sbalf15 = buffer->buffer->element[15].flags & 0xff; |
2742 | int cc = siga_err & 3; | 2788 | int cc = siga_err & 3; |
2743 | 2789 | ||
2744 | QETH_DBF_TEXT(trace, 6, "hdsnderr"); | 2790 | QETH_DBF_TEXT(trace, 6, "hdsnderr"); |
2791 | qeth_check_qdio_errors(buffer->buffer, qdio_err, siga_err, "qouterr"); | ||
2745 | switch (cc) { | 2792 | switch (cc) { |
2746 | case 0: | 2793 | case 0: |
2747 | if (qdio_err){ | 2794 | if (qdio_err){ |
@@ -2998,7 +3045,8 @@ qeth_qdio_output_handler(struct ccw_device * ccwdev, unsigned int status, | |||
2998 | for(i = first_element; i < (first_element + count); ++i){ | 3045 | for(i = first_element; i < (first_element + count); ++i){ |
2999 | buffer = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q]; | 3046 | buffer = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q]; |
3000 | /*we only handle the KICK_IT error by doing a recovery */ | 3047 | /*we only handle the KICK_IT error by doing a recovery */ |
3001 | if (qeth_handle_send_error(card, buffer, qdio_error, siga_error) | 3048 | if (qeth_handle_send_error(card, buffer, |
3049 | qdio_error, siga_error) | ||
3002 | == QETH_SEND_ERROR_KICK_IT){ | 3050 | == QETH_SEND_ERROR_KICK_IT){ |
3003 | netif_stop_queue(card->dev); | 3051 | netif_stop_queue(card->dev); |
3004 | qeth_schedule_recovery(card); | 3052 | qeth_schedule_recovery(card); |
@@ -3240,7 +3288,6 @@ qeth_init_qdio_info(struct qeth_card *card) | |||
3240 | card->qdio.in_buf_pool.buf_count = card->qdio.init_pool.buf_count; | 3288 | card->qdio.in_buf_pool.buf_count = card->qdio.init_pool.buf_count; |
3241 | INIT_LIST_HEAD(&card->qdio.in_buf_pool.entry_list); | 3289 | INIT_LIST_HEAD(&card->qdio.in_buf_pool.entry_list); |
3242 | INIT_LIST_HEAD(&card->qdio.init_pool.entry_list); | 3290 | INIT_LIST_HEAD(&card->qdio.init_pool.entry_list); |
3243 | /* outbound */ | ||
3244 | } | 3291 | } |
3245 | 3292 | ||
3246 | static int | 3293 | static int |
@@ -3682,6 +3729,9 @@ qeth_verify_vlan_dev(struct net_device *dev, struct qeth_card *card) | |||
3682 | break; | 3729 | break; |
3683 | } | 3730 | } |
3684 | } | 3731 | } |
3732 | if (rc && !(VLAN_DEV_INFO(dev)->real_dev->priv == (void *)card)) | ||
3733 | return 0; | ||
3734 | |||
3685 | #endif | 3735 | #endif |
3686 | return rc; | 3736 | return rc; |
3687 | } | 3737 | } |
@@ -3749,7 +3799,7 @@ qeth_open(struct net_device *dev) | |||
3749 | 3799 | ||
3750 | if ( (card->info.type != QETH_CARD_TYPE_OSN) && | 3800 | if ( (card->info.type != QETH_CARD_TYPE_OSN) && |
3751 | (card->options.layer2) && | 3801 | (card->options.layer2) && |
3752 | (!card->info.layer2_mac_registered)) { | 3802 | (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))) { |
3753 | QETH_DBF_TEXT(trace,4,"nomacadr"); | 3803 | QETH_DBF_TEXT(trace,4,"nomacadr"); |
3754 | return -EPERM; | 3804 | return -EPERM; |
3755 | } | 3805 | } |
@@ -3758,10 +3808,8 @@ qeth_open(struct net_device *dev) | |||
3758 | card->data.state = CH_STATE_UP; | 3808 | card->data.state = CH_STATE_UP; |
3759 | card->state = CARD_STATE_UP; | 3809 | card->state = CARD_STATE_UP; |
3760 | 3810 | ||
3761 | if (!card->lan_online){ | 3811 | if (!card->lan_online && netif_carrier_ok(dev)) |
3762 | if (netif_carrier_ok(dev)) | 3812 | netif_carrier_off(dev); |
3763 | netif_carrier_off(dev); | ||
3764 | } | ||
3765 | return 0; | 3813 | return 0; |
3766 | } | 3814 | } |
3767 | 3815 | ||
@@ -4311,6 +4359,8 @@ qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue, | |||
4311 | out: | 4359 | out: |
4312 | if (flush_count) | 4360 | if (flush_count) |
4313 | qeth_flush_buffers(queue, 0, start_index, flush_count); | 4361 | qeth_flush_buffers(queue, 0, start_index, flush_count); |
4362 | else if (!atomic_read(&queue->set_pci_flags_count)) | ||
4363 | atomic_swap(&queue->state, QETH_OUT_Q_LOCKED_FLUSH); | ||
4314 | /* | 4364 | /* |
4315 | * queue->state will go from LOCKED -> UNLOCKED or from | 4365 | * queue->state will go from LOCKED -> UNLOCKED or from |
4316 | * LOCKED_FLUSH -> LOCKED if output_handler wanted to 'notify' us | 4366 | * LOCKED_FLUSH -> LOCKED if output_handler wanted to 'notify' us |
@@ -4975,6 +5025,10 @@ qeth_default_setassparms_cb(struct qeth_card *, struct qeth_reply *, | |||
4975 | unsigned long); | 5025 | unsigned long); |
4976 | 5026 | ||
4977 | static int | 5027 | static int |
5028 | qeth_default_setadapterparms_cb(struct qeth_card *card, | ||
5029 | struct qeth_reply *reply, | ||
5030 | unsigned long data); | ||
5031 | static int | ||
4978 | qeth_send_setassparms(struct qeth_card *, struct qeth_cmd_buffer *, | 5032 | qeth_send_setassparms(struct qeth_card *, struct qeth_cmd_buffer *, |
4979 | __u16, long, | 5033 | __u16, long, |
4980 | int (*reply_cb) | 5034 | int (*reply_cb) |
@@ -5301,8 +5355,7 @@ qeth_free_vlan_addresses4(struct qeth_card *card, unsigned short vid) | |||
5301 | struct qeth_ipaddr *addr; | 5355 | struct qeth_ipaddr *addr; |
5302 | 5356 | ||
5303 | QETH_DBF_TEXT(trace, 4, "frvaddr4"); | 5357 | QETH_DBF_TEXT(trace, 4, "frvaddr4"); |
5304 | if (!card->vlangrp) | 5358 | |
5305 | return; | ||
5306 | rcu_read_lock(); | 5359 | rcu_read_lock(); |
5307 | in_dev = __in_dev_get_rcu(card->vlangrp->vlan_devices[vid]); | 5360 | in_dev = __in_dev_get_rcu(card->vlangrp->vlan_devices[vid]); |
5308 | if (!in_dev) | 5361 | if (!in_dev) |
@@ -5330,8 +5383,7 @@ qeth_free_vlan_addresses6(struct qeth_card *card, unsigned short vid) | |||
5330 | struct qeth_ipaddr *addr; | 5383 | struct qeth_ipaddr *addr; |
5331 | 5384 | ||
5332 | QETH_DBF_TEXT(trace, 4, "frvaddr6"); | 5385 | QETH_DBF_TEXT(trace, 4, "frvaddr6"); |
5333 | if (!card->vlangrp) | 5386 | |
5334 | return; | ||
5335 | in6_dev = in6_dev_get(card->vlangrp->vlan_devices[vid]); | 5387 | in6_dev = in6_dev_get(card->vlangrp->vlan_devices[vid]); |
5336 | if (!in6_dev) | 5388 | if (!in6_dev) |
5337 | return; | 5389 | return; |
@@ -5351,10 +5403,38 @@ qeth_free_vlan_addresses6(struct qeth_card *card, unsigned short vid) | |||
5351 | } | 5403 | } |
5352 | 5404 | ||
5353 | static void | 5405 | static void |
5406 | qeth_free_vlan_addresses(struct qeth_card *card, unsigned short vid) | ||
5407 | { | ||
5408 | if (card->options.layer2 || !card->vlangrp) | ||
5409 | return; | ||
5410 | qeth_free_vlan_addresses4(card, vid); | ||
5411 | qeth_free_vlan_addresses6(card, vid); | ||
5412 | } | ||
5413 | |||
5414 | static int | ||
5415 | qeth_layer2_send_setdelvlan_cb(struct qeth_card *card, | ||
5416 | struct qeth_reply *reply, | ||
5417 | unsigned long data) | ||
5418 | { | ||
5419 | struct qeth_ipa_cmd *cmd; | ||
5420 | |||
5421 | QETH_DBF_TEXT(trace, 2, "L2sdvcb"); | ||
5422 | cmd = (struct qeth_ipa_cmd *) data; | ||
5423 | if (cmd->hdr.return_code) { | ||
5424 | PRINT_ERR("Error in processing VLAN %i on %s: 0x%x. " | ||
5425 | "Continuing\n",cmd->data.setdelvlan.vlan_id, | ||
5426 | QETH_CARD_IFNAME(card), cmd->hdr.return_code); | ||
5427 | QETH_DBF_TEXT_(trace, 2, "L2VL%4x", cmd->hdr.command); | ||
5428 | QETH_DBF_TEXT_(trace, 2, "L2%s", CARD_BUS_ID(card)); | ||
5429 | QETH_DBF_TEXT_(trace, 2, "err%d", cmd->hdr.return_code); | ||
5430 | } | ||
5431 | return 0; | ||
5432 | } | ||
5433 | |||
5434 | static int | ||
5354 | qeth_layer2_send_setdelvlan(struct qeth_card *card, __u16 i, | 5435 | qeth_layer2_send_setdelvlan(struct qeth_card *card, __u16 i, |
5355 | enum qeth_ipa_cmds ipacmd) | 5436 | enum qeth_ipa_cmds ipacmd) |
5356 | { | 5437 | { |
5357 | int rc; | ||
5358 | struct qeth_ipa_cmd *cmd; | 5438 | struct qeth_ipa_cmd *cmd; |
5359 | struct qeth_cmd_buffer *iob; | 5439 | struct qeth_cmd_buffer *iob; |
5360 | 5440 | ||
@@ -5362,15 +5442,8 @@ qeth_layer2_send_setdelvlan(struct qeth_card *card, __u16 i, | |||
5362 | iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4); | 5442 | iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4); |
5363 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 5443 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
5364 | cmd->data.setdelvlan.vlan_id = i; | 5444 | cmd->data.setdelvlan.vlan_id = i; |
5365 | 5445 | return qeth_send_ipa_cmd(card, iob, | |
5366 | rc = qeth_send_ipa_cmd(card, iob, NULL, NULL); | 5446 | 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 | } | 5447 | } |
5375 | 5448 | ||
5376 | static void | 5449 | static void |
@@ -5420,8 +5493,7 @@ qeth_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) | |||
5420 | qeth_free_vlan_skbs(card, vid); | 5493 | qeth_free_vlan_skbs(card, vid); |
5421 | spin_lock_irqsave(&card->vlanlock, flags); | 5494 | spin_lock_irqsave(&card->vlanlock, flags); |
5422 | /* unregister IP addresses of vlan device */ | 5495 | /* unregister IP addresses of vlan device */ |
5423 | qeth_free_vlan_addresses4(card, vid); | 5496 | qeth_free_vlan_addresses(card, vid); |
5424 | qeth_free_vlan_addresses6(card, vid); | ||
5425 | if (card->vlangrp) | 5497 | if (card->vlangrp) |
5426 | card->vlangrp->vlan_devices[vid] = NULL; | 5498 | card->vlangrp->vlan_devices[vid] = NULL; |
5427 | spin_unlock_irqrestore(&card->vlanlock, flags); | 5499 | spin_unlock_irqrestore(&card->vlanlock, flags); |
@@ -5430,6 +5502,59 @@ qeth_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) | |||
5430 | qeth_set_multicast_list(card->dev); | 5502 | qeth_set_multicast_list(card->dev); |
5431 | } | 5503 | } |
5432 | #endif | 5504 | #endif |
5505 | /** | ||
5506 | * Examine hardware response to SET_PROMISC_MODE | ||
5507 | */ | ||
5508 | static int | ||
5509 | qeth_setadp_promisc_mode_cb(struct qeth_card *card, | ||
5510 | struct qeth_reply *reply, | ||
5511 | unsigned long data) | ||
5512 | { | ||
5513 | struct qeth_ipa_cmd *cmd; | ||
5514 | struct qeth_ipacmd_setadpparms *setparms; | ||
5515 | |||
5516 | QETH_DBF_TEXT(trace,4,"prmadpcb"); | ||
5517 | |||
5518 | cmd = (struct qeth_ipa_cmd *) data; | ||
5519 | setparms = &(cmd->data.setadapterparms); | ||
5520 | |||
5521 | qeth_default_setadapterparms_cb(card, reply, (unsigned long)cmd); | ||
5522 | if (cmd->hdr.return_code) { | ||
5523 | QETH_DBF_TEXT_(trace,4,"prmrc%2.2x",cmd->hdr.return_code); | ||
5524 | setparms->data.mode = SET_PROMISC_MODE_OFF; | ||
5525 | } | ||
5526 | card->info.promisc_mode = setparms->data.mode; | ||
5527 | return 0; | ||
5528 | } | ||
5529 | /* | ||
5530 | * Set promiscuous mode (on or off) (SET_PROMISC_MODE command) | ||
5531 | */ | ||
5532 | static void | ||
5533 | qeth_setadp_promisc_mode(struct qeth_card *card) | ||
5534 | { | ||
5535 | enum qeth_ipa_promisc_modes mode; | ||
5536 | struct net_device *dev = card->dev; | ||
5537 | struct qeth_cmd_buffer *iob; | ||
5538 | struct qeth_ipa_cmd *cmd; | ||
5539 | |||
5540 | QETH_DBF_TEXT(trace, 4, "setprom"); | ||
5541 | |||
5542 | if (((dev->flags & IFF_PROMISC) && | ||
5543 | (card->info.promisc_mode == SET_PROMISC_MODE_ON)) || | ||
5544 | (!(dev->flags & IFF_PROMISC) && | ||
5545 | (card->info.promisc_mode == SET_PROMISC_MODE_OFF))) | ||
5546 | return; | ||
5547 | mode = SET_PROMISC_MODE_OFF; | ||
5548 | if (dev->flags & IFF_PROMISC) | ||
5549 | mode = SET_PROMISC_MODE_ON; | ||
5550 | QETH_DBF_TEXT_(trace, 4, "mode:%x", mode); | ||
5551 | |||
5552 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_PROMISC_MODE, | ||
5553 | sizeof(struct qeth_ipacmd_setadpparms)); | ||
5554 | cmd = (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE); | ||
5555 | cmd->data.setadapterparms.data.mode = mode; | ||
5556 | qeth_send_ipa_cmd(card, iob, qeth_setadp_promisc_mode_cb, NULL); | ||
5557 | } | ||
5433 | 5558 | ||
5434 | /** | 5559 | /** |
5435 | * set multicast address on card | 5560 | * set multicast address on card |
@@ -5444,12 +5569,22 @@ qeth_set_multicast_list(struct net_device *dev) | |||
5444 | 5569 | ||
5445 | QETH_DBF_TEXT(trace,3,"setmulti"); | 5570 | QETH_DBF_TEXT(trace,3,"setmulti"); |
5446 | qeth_delete_mc_addresses(card); | 5571 | qeth_delete_mc_addresses(card); |
5572 | if (card->options.layer2) { | ||
5573 | qeth_layer2_add_multicast(card); | ||
5574 | goto out; | ||
5575 | } | ||
5447 | qeth_add_multicast_ipv4(card); | 5576 | qeth_add_multicast_ipv4(card); |
5448 | #ifdef CONFIG_QETH_IPV6 | 5577 | #ifdef CONFIG_QETH_IPV6 |
5449 | qeth_add_multicast_ipv6(card); | 5578 | qeth_add_multicast_ipv6(card); |
5450 | #endif | 5579 | #endif |
5580 | out: | ||
5451 | if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0) | 5581 | if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0) |
5452 | schedule_work(&card->kernel_thread_starter); | 5582 | schedule_work(&card->kernel_thread_starter); |
5583 | if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE)) | ||
5584 | return; | ||
5585 | if (qeth_set_thread_start_bit(card, QETH_SET_PROMISC_MODE_THREAD)==0) | ||
5586 | schedule_work(&card->kernel_thread_starter); | ||
5587 | |||
5453 | } | 5588 | } |
5454 | 5589 | ||
5455 | static int | 5590 | static int |
@@ -5657,6 +5792,24 @@ qeth_add_multicast_ipv4(struct qeth_card *card) | |||
5657 | in_dev_put(in4_dev); | 5792 | in_dev_put(in4_dev); |
5658 | } | 5793 | } |
5659 | 5794 | ||
5795 | static void | ||
5796 | qeth_layer2_add_multicast(struct qeth_card *card) | ||
5797 | { | ||
5798 | struct qeth_ipaddr *ipm; | ||
5799 | struct dev_mc_list *dm; | ||
5800 | |||
5801 | QETH_DBF_TEXT(trace,4,"L2addmc"); | ||
5802 | for (dm = card->dev->mc_list; dm; dm = dm->next) { | ||
5803 | ipm = qeth_get_addr_buffer(QETH_PROT_IPV4); | ||
5804 | if (!ipm) | ||
5805 | continue; | ||
5806 | memcpy(ipm->mac,dm->dmi_addr,MAX_ADDR_LEN); | ||
5807 | ipm->is_multicast = 1; | ||
5808 | if (!qeth_add_ip(card, ipm)) | ||
5809 | kfree(ipm); | ||
5810 | } | ||
5811 | } | ||
5812 | |||
5660 | #ifdef CONFIG_QETH_IPV6 | 5813 | #ifdef CONFIG_QETH_IPV6 |
5661 | static inline void | 5814 | static inline void |
5662 | qeth_add_mc6(struct qeth_card *card, struct inet6_dev *in6_dev) | 5815 | qeth_add_mc6(struct qeth_card *card, struct inet6_dev *in6_dev) |
@@ -5716,10 +5869,8 @@ qeth_add_multicast_ipv6(struct qeth_card *card) | |||
5716 | struct inet6_dev *in6_dev; | 5869 | struct inet6_dev *in6_dev; |
5717 | 5870 | ||
5718 | QETH_DBF_TEXT(trace,4,"chkmcv6"); | 5871 | QETH_DBF_TEXT(trace,4,"chkmcv6"); |
5719 | if ((card->options.layer2 == 0) && | 5872 | if (!qeth_is_supported(card, IPA_IPV6)) |
5720 | (!qeth_is_supported(card, IPA_IPV6)) ) | ||
5721 | return ; | 5873 | return ; |
5722 | |||
5723 | in6_dev = in6_dev_get(card->dev); | 5874 | in6_dev = in6_dev_get(card->dev); |
5724 | if (in6_dev == NULL) | 5875 | if (in6_dev == NULL) |
5725 | return; | 5876 | return; |
@@ -5825,10 +5976,10 @@ qeth_layer2_send_setmac_cb(struct qeth_card *card, | |||
5825 | PRINT_WARN("Error in registering MAC address on " \ | 5976 | PRINT_WARN("Error in registering MAC address on " \ |
5826 | "device %s: x%x\n", CARD_BUS_ID(card), | 5977 | "device %s: x%x\n", CARD_BUS_ID(card), |
5827 | cmd->hdr.return_code); | 5978 | cmd->hdr.return_code); |
5828 | card->info.layer2_mac_registered = 0; | 5979 | card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; |
5829 | cmd->hdr.return_code = -EIO; | 5980 | cmd->hdr.return_code = -EIO; |
5830 | } else { | 5981 | } else { |
5831 | card->info.layer2_mac_registered = 1; | 5982 | card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED; |
5832 | memcpy(card->dev->dev_addr,cmd->data.setdelmac.mac, | 5983 | memcpy(card->dev->dev_addr,cmd->data.setdelmac.mac, |
5833 | OSA_ADDR_LEN); | 5984 | OSA_ADDR_LEN); |
5834 | PRINT_INFO("MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x " | 5985 | PRINT_INFO("MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x " |
@@ -5866,7 +6017,7 @@ qeth_layer2_send_delmac_cb(struct qeth_card *card, | |||
5866 | cmd->hdr.return_code = -EIO; | 6017 | cmd->hdr.return_code = -EIO; |
5867 | return 0; | 6018 | return 0; |
5868 | } | 6019 | } |
5869 | card->info.layer2_mac_registered = 0; | 6020 | card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; |
5870 | 6021 | ||
5871 | return 0; | 6022 | return 0; |
5872 | } | 6023 | } |
@@ -5874,7 +6025,7 @@ static int | |||
5874 | qeth_layer2_send_delmac(struct qeth_card *card, __u8 *mac) | 6025 | qeth_layer2_send_delmac(struct qeth_card *card, __u8 *mac) |
5875 | { | 6026 | { |
5876 | QETH_DBF_TEXT(trace, 2, "L2Delmac"); | 6027 | QETH_DBF_TEXT(trace, 2, "L2Delmac"); |
5877 | if (!card->info.layer2_mac_registered) | 6028 | if (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED)) |
5878 | return 0; | 6029 | return 0; |
5879 | return qeth_layer2_send_setdelmac(card, mac, IPA_CMD_DELVMAC, | 6030 | return qeth_layer2_send_setdelmac(card, mac, IPA_CMD_DELVMAC, |
5880 | qeth_layer2_send_delmac_cb); | 6031 | qeth_layer2_send_delmac_cb); |
@@ -5896,7 +6047,7 @@ qeth_layer2_set_mac_address(struct net_device *dev, void *p) | |||
5896 | card = (struct qeth_card *) dev->priv; | 6047 | card = (struct qeth_card *) dev->priv; |
5897 | 6048 | ||
5898 | if (!card->options.layer2) { | 6049 | if (!card->options.layer2) { |
5899 | PRINT_WARN("Setting MAC address on %s is not supported" | 6050 | PRINT_WARN("Setting MAC address on %s is not supported " |
5900 | "in Layer 3 mode.\n", dev->name); | 6051 | "in Layer 3 mode.\n", dev->name); |
5901 | QETH_DBF_TEXT(trace, 3, "setmcLY3"); | 6052 | QETH_DBF_TEXT(trace, 3, "setmcLY3"); |
5902 | return -EOPNOTSUPP; | 6053 | return -EOPNOTSUPP; |
@@ -6441,6 +6592,8 @@ qeth_default_setadapterparms_cb(struct qeth_card *card, | |||
6441 | return 0; | 6592 | return 0; |
6442 | } | 6593 | } |
6443 | 6594 | ||
6595 | |||
6596 | |||
6444 | static int | 6597 | static int |
6445 | qeth_query_setadapterparms_cb(struct qeth_card *card, struct qeth_reply *reply, | 6598 | qeth_query_setadapterparms_cb(struct qeth_card *card, struct qeth_reply *reply, |
6446 | unsigned long data) | 6599 | unsigned long data) |
@@ -6481,8 +6634,13 @@ qeth_setadpparms_change_macaddr_cb(struct qeth_card *card, | |||
6481 | QETH_DBF_TEXT(trace,4,"chgmaccb"); | 6634 | QETH_DBF_TEXT(trace,4,"chgmaccb"); |
6482 | 6635 | ||
6483 | cmd = (struct qeth_ipa_cmd *) data; | 6636 | cmd = (struct qeth_ipa_cmd *) data; |
6484 | memcpy(card->dev->dev_addr, | 6637 | if (!card->options.layer2 || card->info.guestlan || |
6485 | &cmd->data.setadapterparms.data.change_addr.addr,OSA_ADDR_LEN); | 6638 | !(card->info.mac_bits & QETH_LAYER2_MAC_READ)) { |
6639 | memcpy(card->dev->dev_addr, | ||
6640 | &cmd->data.setadapterparms.data.change_addr.addr, | ||
6641 | OSA_ADDR_LEN); | ||
6642 | card->info.mac_bits |= QETH_LAYER2_MAC_READ; | ||
6643 | } | ||
6486 | qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd); | 6644 | qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd); |
6487 | return 0; | 6645 | return 0; |
6488 | } | 6646 | } |
@@ -6602,6 +6760,12 @@ qeth_layer2_initialize(struct qeth_card *card) | |||
6602 | QETH_DBF_TEXT(setup, 2, "doL2init"); | 6760 | QETH_DBF_TEXT(setup, 2, "doL2init"); |
6603 | QETH_DBF_TEXT_(setup, 2, "doL2%s", CARD_BUS_ID(card)); | 6761 | QETH_DBF_TEXT_(setup, 2, "doL2%s", CARD_BUS_ID(card)); |
6604 | 6762 | ||
6763 | rc = qeth_query_setadapterparms(card); | ||
6764 | if (rc) { | ||
6765 | PRINT_WARN("could not query adapter parameters on device %s: " | ||
6766 | "x%x\n", CARD_BUS_ID(card), rc); | ||
6767 | } | ||
6768 | |||
6605 | rc = qeth_setadpparms_change_macaddr(card); | 6769 | rc = qeth_setadpparms_change_macaddr(card); |
6606 | if (rc) { | 6770 | if (rc) { |
6607 | PRINT_WARN("couldn't get MAC address on " | 6771 | PRINT_WARN("couldn't get MAC address on " |
@@ -7769,8 +7933,8 @@ __qeth_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
7769 | QETH_DBF_TEXT_(setup, 2, "6err%d", rc); | 7933 | QETH_DBF_TEXT_(setup, 2, "6err%d", rc); |
7770 | goto out_remove; | 7934 | goto out_remove; |
7771 | } | 7935 | } |
7772 | /*maybe it was set offline without ifconfig down | 7936 | netif_carrier_on(card->dev); |
7773 | * we can also use this state for recovery purposes*/ | 7937 | |
7774 | qeth_set_allowed_threads(card, 0xffffffff, 0); | 7938 | qeth_set_allowed_threads(card, 0xffffffff, 0); |
7775 | if (recover_flag == CARD_STATE_RECOVER) | 7939 | if (recover_flag == CARD_STATE_RECOVER) |
7776 | qeth_start_again(card, recovery_mode); | 7940 | qeth_start_again(card, recovery_mode); |
@@ -8548,7 +8712,7 @@ EXPORT_SYMBOL(qeth_osn_deregister); | |||
8548 | EXPORT_SYMBOL(qeth_osn_assist); | 8712 | EXPORT_SYMBOL(qeth_osn_assist); |
8549 | module_init(qeth_init); | 8713 | module_init(qeth_init); |
8550 | module_exit(qeth_exit); | 8714 | module_exit(qeth_exit); |
8551 | MODULE_AUTHOR("Frank Pavlic <pavlic@de.ibm.com>"); | 8715 | MODULE_AUTHOR("Frank Pavlic <fpavlic@de.ibm.com>"); |
8552 | MODULE_DESCRIPTION("Linux on zSeries OSA Express and HiperSockets support\n" \ | 8716 | MODULE_DESCRIPTION("Linux on zSeries OSA Express and HiperSockets support\n" \ |
8553 | "Copyright 2000,2003 IBM Corporation\n"); | 8717 | "Copyright 2000,2003 IBM Corporation\n"); |
8554 | 8718 | ||