diff options
author | Linus Torvalds <torvalds@woody.osdl.org> | 2007-01-09 12:36:06 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2007-01-09 12:36:06 -0500 |
commit | 97bee8e25da4dfc3b7a369fb2c2f280f5c1918c2 (patch) | |
tree | 75dcf606ca1c29bd3aca571834355ccf6f06bd5b /drivers/s390 | |
parent | 8ba1f2798224086c72c1132acd6fdb45068279d7 (diff) | |
parent | 77aab8bf22042d1658d4adbca8b71779e7f2d0ff (diff) |
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6:
pcnet_cs : add new id
chelsio: error path fix
s390: iucv Kconfig help description changes
s390: qeth driver fixes: atomic context fixups
s390: qeth driver fixes: packet socket
s390: qeth driver fixes: VLAN hdr, perf stats
forcedeth: sideband management fix
Revert "[PATCH] e1000: disable TSO on the 82544 with slab debugging"
qeth: fix uaccess handling and get rid of unused variable
qla3xxx: Add delay to NVRAM register access.
qla3xxx: Remove NETIF_F_LLTX from driver features.
ixgb: Write RA register high word first, increment version
ixgb: Maybe stop TX if not enough free descriptors
ixgb: Fix early TSO completion
[PATCH] ipw2100: Fix dropping fragmented small packet problem
[PATCH] ieee80211: WLAN_GET_SEQ_SEQ fix (select correct region)
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/net/Kconfig | 5 | ||||
-rw-r--r-- | drivers/s390/net/qeth.h | 2 | ||||
-rw-r--r-- | drivers/s390/net/qeth_main.c | 217 |
3 files changed, 95 insertions, 129 deletions
diff --git a/drivers/s390/net/Kconfig b/drivers/s390/net/Kconfig index 1a93fa684e9f..52625153a4f0 100644 --- a/drivers/s390/net/Kconfig +++ b/drivers/s390/net/Kconfig | |||
@@ -27,10 +27,7 @@ config IUCV | |||
27 | help | 27 | help |
28 | Select this option if you want to use inter-user communication | 28 | Select this option if you want to use inter-user communication |
29 | under VM or VIF. If unsure, say "Y" to enable a fast communication | 29 | under VM or VIF. If unsure, say "Y" to enable a fast communication |
30 | link between VM guests. At boot time the user ID of the guest needs | 30 | link between VM guests. |
31 | to be passed to the kernel. Note that both kernels need to be | ||
32 | compiled with this option and both need to be booted with the user ID | ||
33 | of the other VM guest. | ||
34 | 31 | ||
35 | config NETIUCV | 32 | config NETIUCV |
36 | tristate "IUCV network device support (VM only)" | 33 | tristate "IUCV network device support (VM only)" |
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h index 53c358c7d368..e95c281f1e36 100644 --- a/drivers/s390/net/qeth.h +++ b/drivers/s390/net/qeth.h | |||
@@ -710,7 +710,7 @@ struct qeth_reply { | |||
710 | int (*callback)(struct qeth_card *,struct qeth_reply *,unsigned long); | 710 | int (*callback)(struct qeth_card *,struct qeth_reply *,unsigned long); |
711 | u32 seqno; | 711 | u32 seqno; |
712 | unsigned long offset; | 712 | unsigned long offset; |
713 | int received; | 713 | atomic_t received; |
714 | int rc; | 714 | int rc; |
715 | void *param; | 715 | void *param; |
716 | struct qeth_card *card; | 716 | struct qeth_card *card; |
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 2bde4f1fb9c2..d2efa5ff125d 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c | |||
@@ -471,7 +471,7 @@ qeth_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) | |||
471 | channel->state == CH_STATE_UP) | 471 | channel->state == CH_STATE_UP) |
472 | qeth_issue_next_read(card); | 472 | qeth_issue_next_read(card); |
473 | 473 | ||
474 | tasklet_schedule(&channel->irq_tasklet); | 474 | qeth_irq_tasklet((unsigned long)channel); |
475 | return; | 475 | return; |
476 | out: | 476 | out: |
477 | wake_up(&card->wait_q); | 477 | wake_up(&card->wait_q); |
@@ -951,40 +951,6 @@ qeth_do_run_thread(struct qeth_card *card, unsigned long thread) | |||
951 | } | 951 | } |
952 | 952 | ||
953 | static int | 953 | static int |
954 | qeth_register_ip_addresses(void *ptr) | ||
955 | { | ||
956 | struct qeth_card *card; | ||
957 | |||
958 | card = (struct qeth_card *) ptr; | ||
959 | daemonize("qeth_reg_ip"); | ||
960 | QETH_DBF_TEXT(trace,4,"regipth1"); | ||
961 | if (!qeth_do_run_thread(card, QETH_SET_IP_THREAD)) | ||
962 | return 0; | ||
963 | QETH_DBF_TEXT(trace,4,"regipth2"); | ||
964 | qeth_set_ip_addr_list(card); | ||
965 | qeth_clear_thread_running_bit(card, QETH_SET_IP_THREAD); | ||
966 | return 0; | ||
967 | } | ||
968 | |||
969 | /* | ||
970 | * Drive the SET_PROMISC_MODE thread | ||
971 | */ | ||
972 | static int | ||
973 | qeth_set_promisc_mode(void *ptr) | ||
974 | { | ||
975 | struct qeth_card *card = (struct qeth_card *) ptr; | ||
976 | |||
977 | daemonize("qeth_setprm"); | ||
978 | QETH_DBF_TEXT(trace,4,"setprm1"); | ||
979 | if (!qeth_do_run_thread(card, QETH_SET_PROMISC_MODE_THREAD)) | ||
980 | return 0; | ||
981 | QETH_DBF_TEXT(trace,4,"setprm2"); | ||
982 | qeth_setadp_promisc_mode(card); | ||
983 | qeth_clear_thread_running_bit(card, QETH_SET_PROMISC_MODE_THREAD); | ||
984 | return 0; | ||
985 | } | ||
986 | |||
987 | static int | ||
988 | qeth_recover(void *ptr) | 954 | qeth_recover(void *ptr) |
989 | { | 955 | { |
990 | struct qeth_card *card; | 956 | struct qeth_card *card; |
@@ -1047,11 +1013,6 @@ qeth_start_kernel_thread(struct work_struct *work) | |||
1047 | if (card->read.state != CH_STATE_UP && | 1013 | if (card->read.state != CH_STATE_UP && |
1048 | card->write.state != CH_STATE_UP) | 1014 | card->write.state != CH_STATE_UP) |
1049 | return; | 1015 | return; |
1050 | |||
1051 | if (qeth_do_start_thread(card, QETH_SET_IP_THREAD)) | ||
1052 | kernel_thread(qeth_register_ip_addresses, (void *)card,SIGCHLD); | ||
1053 | if (qeth_do_start_thread(card, QETH_SET_PROMISC_MODE_THREAD)) | ||
1054 | kernel_thread(qeth_set_promisc_mode, (void *)card, SIGCHLD); | ||
1055 | if (qeth_do_start_thread(card, QETH_RECOVER_THREAD)) | 1016 | if (qeth_do_start_thread(card, QETH_RECOVER_THREAD)) |
1056 | kernel_thread(qeth_recover, (void *) card, SIGCHLD); | 1017 | kernel_thread(qeth_recover, (void *) card, SIGCHLD); |
1057 | } | 1018 | } |
@@ -1074,7 +1035,7 @@ qeth_set_intial_options(struct qeth_card *card) | |||
1074 | card->options.layer2 = 1; | 1035 | card->options.layer2 = 1; |
1075 | else | 1036 | else |
1076 | card->options.layer2 = 0; | 1037 | card->options.layer2 = 0; |
1077 | card->options.performance_stats = 1; | 1038 | card->options.performance_stats = 0; |
1078 | } | 1039 | } |
1079 | 1040 | ||
1080 | /** | 1041 | /** |
@@ -1613,8 +1574,6 @@ qeth_issue_next_read(struct qeth_card *card) | |||
1613 | return -ENOMEM; | 1574 | return -ENOMEM; |
1614 | } | 1575 | } |
1615 | qeth_setup_ccw(&card->read, iob->data, QETH_BUFSIZE); | 1576 | qeth_setup_ccw(&card->read, iob->data, QETH_BUFSIZE); |
1616 | wait_event(card->wait_q, | ||
1617 | atomic_cmpxchg(&card->read.irq_pending, 0, 1) == 0); | ||
1618 | QETH_DBF_TEXT(trace, 6, "noirqpnd"); | 1577 | QETH_DBF_TEXT(trace, 6, "noirqpnd"); |
1619 | rc = ccw_device_start(card->read.ccwdev, &card->read.ccw, | 1578 | rc = ccw_device_start(card->read.ccwdev, &card->read.ccw, |
1620 | (addr_t) iob, 0, 0); | 1579 | (addr_t) iob, 0, 0); |
@@ -1635,6 +1594,7 @@ qeth_alloc_reply(struct qeth_card *card) | |||
1635 | reply = kzalloc(sizeof(struct qeth_reply), GFP_ATOMIC); | 1594 | reply = kzalloc(sizeof(struct qeth_reply), GFP_ATOMIC); |
1636 | if (reply){ | 1595 | if (reply){ |
1637 | atomic_set(&reply->refcnt, 1); | 1596 | atomic_set(&reply->refcnt, 1); |
1597 | atomic_set(&reply->received, 0); | ||
1638 | reply->card = card; | 1598 | reply->card = card; |
1639 | }; | 1599 | }; |
1640 | return reply; | 1600 | return reply; |
@@ -1655,31 +1615,6 @@ qeth_put_reply(struct qeth_reply *reply) | |||
1655 | kfree(reply); | 1615 | kfree(reply); |
1656 | } | 1616 | } |
1657 | 1617 | ||
1658 | static void | ||
1659 | qeth_cmd_timeout(unsigned long data) | ||
1660 | { | ||
1661 | struct qeth_reply *reply, *list_reply, *r; | ||
1662 | unsigned long flags; | ||
1663 | |||
1664 | reply = (struct qeth_reply *) data; | ||
1665 | spin_lock_irqsave(&reply->card->lock, flags); | ||
1666 | list_for_each_entry_safe(list_reply, r, | ||
1667 | &reply->card->cmd_waiter_list, list) { | ||
1668 | if (reply == list_reply){ | ||
1669 | qeth_get_reply(reply); | ||
1670 | list_del_init(&reply->list); | ||
1671 | spin_unlock_irqrestore(&reply->card->lock, flags); | ||
1672 | reply->rc = -ETIME; | ||
1673 | reply->received = 1; | ||
1674 | wake_up(&reply->wait_q); | ||
1675 | qeth_put_reply(reply); | ||
1676 | return; | ||
1677 | } | ||
1678 | } | ||
1679 | spin_unlock_irqrestore(&reply->card->lock, flags); | ||
1680 | } | ||
1681 | |||
1682 | |||
1683 | static struct qeth_ipa_cmd * | 1618 | static struct qeth_ipa_cmd * |
1684 | qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob) | 1619 | qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob) |
1685 | { | 1620 | { |
@@ -1745,7 +1680,7 @@ qeth_clear_ipacmd_list(struct qeth_card *card) | |||
1745 | list_for_each_entry_safe(reply, r, &card->cmd_waiter_list, list) { | 1680 | list_for_each_entry_safe(reply, r, &card->cmd_waiter_list, list) { |
1746 | qeth_get_reply(reply); | 1681 | qeth_get_reply(reply); |
1747 | reply->rc = -EIO; | 1682 | reply->rc = -EIO; |
1748 | reply->received = 1; | 1683 | atomic_inc(&reply->received); |
1749 | list_del_init(&reply->list); | 1684 | list_del_init(&reply->list); |
1750 | wake_up(&reply->wait_q); | 1685 | wake_up(&reply->wait_q); |
1751 | qeth_put_reply(reply); | 1686 | qeth_put_reply(reply); |
@@ -1814,7 +1749,7 @@ qeth_send_control_data_cb(struct qeth_channel *channel, | |||
1814 | &card->cmd_waiter_list); | 1749 | &card->cmd_waiter_list); |
1815 | spin_unlock_irqrestore(&card->lock, flags); | 1750 | spin_unlock_irqrestore(&card->lock, flags); |
1816 | } else { | 1751 | } else { |
1817 | reply->received = 1; | 1752 | atomic_inc(&reply->received); |
1818 | wake_up(&reply->wait_q); | 1753 | wake_up(&reply->wait_q); |
1819 | } | 1754 | } |
1820 | qeth_put_reply(reply); | 1755 | qeth_put_reply(reply); |
@@ -1858,7 +1793,7 @@ qeth_send_control_data(struct qeth_card *card, int len, | |||
1858 | int rc; | 1793 | int rc; |
1859 | unsigned long flags; | 1794 | unsigned long flags; |
1860 | struct qeth_reply *reply = NULL; | 1795 | struct qeth_reply *reply = NULL; |
1861 | struct timer_list timer; | 1796 | unsigned long timeout; |
1862 | 1797 | ||
1863 | QETH_DBF_TEXT(trace, 2, "sendctl"); | 1798 | QETH_DBF_TEXT(trace, 2, "sendctl"); |
1864 | 1799 | ||
@@ -1873,21 +1808,20 @@ qeth_send_control_data(struct qeth_card *card, int len, | |||
1873 | reply->seqno = QETH_IDX_COMMAND_SEQNO; | 1808 | reply->seqno = QETH_IDX_COMMAND_SEQNO; |
1874 | else | 1809 | else |
1875 | reply->seqno = card->seqno.ipa++; | 1810 | reply->seqno = card->seqno.ipa++; |
1876 | init_timer(&timer); | ||
1877 | timer.function = qeth_cmd_timeout; | ||
1878 | timer.data = (unsigned long) reply; | ||
1879 | init_waitqueue_head(&reply->wait_q); | 1811 | init_waitqueue_head(&reply->wait_q); |
1880 | spin_lock_irqsave(&card->lock, flags); | 1812 | spin_lock_irqsave(&card->lock, flags); |
1881 | list_add_tail(&reply->list, &card->cmd_waiter_list); | 1813 | list_add_tail(&reply->list, &card->cmd_waiter_list); |
1882 | spin_unlock_irqrestore(&card->lock, flags); | 1814 | spin_unlock_irqrestore(&card->lock, flags); |
1883 | QETH_DBF_HEX(control, 2, iob->data, QETH_DBF_CONTROL_LEN); | 1815 | QETH_DBF_HEX(control, 2, iob->data, QETH_DBF_CONTROL_LEN); |
1884 | wait_event(card->wait_q, | 1816 | |
1885 | atomic_cmpxchg(&card->write.irq_pending, 0, 1) == 0); | 1817 | while (atomic_cmpxchg(&card->write.irq_pending, 0, 1)) ; |
1886 | qeth_prepare_control_data(card, len, iob); | 1818 | qeth_prepare_control_data(card, len, iob); |
1819 | |||
1887 | if (IS_IPA(iob->data)) | 1820 | if (IS_IPA(iob->data)) |
1888 | timer.expires = jiffies + QETH_IPA_TIMEOUT; | 1821 | timeout = jiffies + QETH_IPA_TIMEOUT; |
1889 | else | 1822 | else |
1890 | timer.expires = jiffies + QETH_TIMEOUT; | 1823 | timeout = jiffies + QETH_TIMEOUT; |
1824 | |||
1891 | QETH_DBF_TEXT(trace, 6, "noirqpnd"); | 1825 | QETH_DBF_TEXT(trace, 6, "noirqpnd"); |
1892 | spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags); | 1826 | spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags); |
1893 | rc = ccw_device_start(card->write.ccwdev, &card->write.ccw, | 1827 | rc = ccw_device_start(card->write.ccwdev, &card->write.ccw, |
@@ -1906,9 +1840,16 @@ qeth_send_control_data(struct qeth_card *card, int len, | |||
1906 | wake_up(&card->wait_q); | 1840 | wake_up(&card->wait_q); |
1907 | return rc; | 1841 | return rc; |
1908 | } | 1842 | } |
1909 | add_timer(&timer); | 1843 | while (!atomic_read(&reply->received)) { |
1910 | wait_event(reply->wait_q, reply->received); | 1844 | if (time_after(jiffies, timeout)) { |
1911 | del_timer_sync(&timer); | 1845 | spin_lock_irqsave(&reply->card->lock, flags); |
1846 | list_del_init(&reply->list); | ||
1847 | spin_unlock_irqrestore(&reply->card->lock, flags); | ||
1848 | reply->rc = -ETIME; | ||
1849 | atomic_inc(&reply->received); | ||
1850 | wake_up(&reply->wait_q); | ||
1851 | } | ||
1852 | }; | ||
1912 | rc = reply->rc; | 1853 | rc = reply->rc; |
1913 | qeth_put_reply(reply); | 1854 | qeth_put_reply(reply); |
1914 | return rc; | 1855 | return rc; |
@@ -2466,32 +2407,17 @@ qeth_rebuild_skb_fake_ll(struct qeth_card *card, struct sk_buff *skb, | |||
2466 | qeth_rebuild_skb_fake_ll_eth(card, skb, hdr); | 2407 | qeth_rebuild_skb_fake_ll_eth(card, skb, hdr); |
2467 | } | 2408 | } |
2468 | 2409 | ||
2469 | static inline __u16 | 2410 | static inline void |
2470 | qeth_layer2_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, | 2411 | qeth_layer2_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, |
2471 | struct qeth_hdr *hdr) | 2412 | struct qeth_hdr *hdr) |
2472 | { | 2413 | { |
2473 | unsigned short vlan_id = 0; | ||
2474 | #ifdef CONFIG_QETH_VLAN | ||
2475 | struct vlan_hdr *vhdr; | ||
2476 | #endif | ||
2477 | |||
2478 | skb->pkt_type = PACKET_HOST; | 2414 | skb->pkt_type = PACKET_HOST; |
2479 | skb->protocol = qeth_type_trans(skb, skb->dev); | 2415 | skb->protocol = qeth_type_trans(skb, skb->dev); |
2480 | if (card->options.checksum_type == NO_CHECKSUMMING) | 2416 | if (card->options.checksum_type == NO_CHECKSUMMING) |
2481 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 2417 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
2482 | else | 2418 | else |
2483 | skb->ip_summed = CHECKSUM_NONE; | 2419 | skb->ip_summed = CHECKSUM_NONE; |
2484 | #ifdef CONFIG_QETH_VLAN | ||
2485 | if (hdr->hdr.l2.flags[2] & (QETH_LAYER2_FLAG_VLAN)) { | ||
2486 | vhdr = (struct vlan_hdr *) skb->data; | ||
2487 | skb->protocol = | ||
2488 | __constant_htons(vhdr->h_vlan_encapsulated_proto); | ||
2489 | vlan_id = hdr->hdr.l2.vlan_id; | ||
2490 | skb_pull(skb, VLAN_HLEN); | ||
2491 | } | ||
2492 | #endif | ||
2493 | *((__u32 *)skb->cb) = ++card->seqno.pkt_seqno; | 2420 | *((__u32 *)skb->cb) = ++card->seqno.pkt_seqno; |
2494 | return vlan_id; | ||
2495 | } | 2421 | } |
2496 | 2422 | ||
2497 | static inline __u16 | 2423 | static inline __u16 |
@@ -2560,7 +2486,6 @@ qeth_process_inbound_buffer(struct qeth_card *card, | |||
2560 | int offset; | 2486 | int offset; |
2561 | int rxrc; | 2487 | int rxrc; |
2562 | __u16 vlan_tag = 0; | 2488 | __u16 vlan_tag = 0; |
2563 | __u16 *vlan_addr; | ||
2564 | 2489 | ||
2565 | /* get first element of current buffer */ | 2490 | /* get first element of current buffer */ |
2566 | element = (struct qdio_buffer_element *)&buf->buffer->element[0]; | 2491 | element = (struct qdio_buffer_element *)&buf->buffer->element[0]; |
@@ -2571,7 +2496,7 @@ qeth_process_inbound_buffer(struct qeth_card *card, | |||
2571 | &offset, &hdr))) { | 2496 | &offset, &hdr))) { |
2572 | skb->dev = card->dev; | 2497 | skb->dev = card->dev; |
2573 | if (hdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2) | 2498 | if (hdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2) |
2574 | vlan_tag = qeth_layer2_rebuild_skb(card, skb, hdr); | 2499 | qeth_layer2_rebuild_skb(card, skb, hdr); |
2575 | else if (hdr->hdr.l3.id == QETH_HEADER_TYPE_LAYER3) | 2500 | else if (hdr->hdr.l3.id == QETH_HEADER_TYPE_LAYER3) |
2576 | vlan_tag = qeth_rebuild_skb(card, skb, hdr); | 2501 | vlan_tag = qeth_rebuild_skb(card, skb, hdr); |
2577 | else { /*in case of OSN*/ | 2502 | else { /*in case of OSN*/ |
@@ -3968,13 +3893,22 @@ static inline struct sk_buff * | |||
3968 | qeth_prepare_skb(struct qeth_card *card, struct sk_buff *skb, | 3893 | qeth_prepare_skb(struct qeth_card *card, struct sk_buff *skb, |
3969 | struct qeth_hdr **hdr, int ipv) | 3894 | struct qeth_hdr **hdr, int ipv) |
3970 | { | 3895 | { |
3971 | struct sk_buff *new_skb; | 3896 | struct sk_buff *new_skb, *new_skb2; |
3972 | 3897 | ||
3973 | QETH_DBF_TEXT(trace, 6, "prepskb"); | 3898 | QETH_DBF_TEXT(trace, 6, "prepskb"); |
3974 | 3899 | new_skb = skb; | |
3975 | new_skb = qeth_realloc_headroom(card, skb, sizeof(struct qeth_hdr)); | 3900 | new_skb = qeth_pskb_unshare(skb, GFP_ATOMIC); |
3976 | if (new_skb == NULL) | 3901 | if (!new_skb) |
3902 | return NULL; | ||
3903 | new_skb2 = qeth_realloc_headroom(card, new_skb, | ||
3904 | sizeof(struct qeth_hdr)); | ||
3905 | if (!new_skb2) { | ||
3906 | __qeth_free_new_skb(skb, new_skb); | ||
3977 | return NULL; | 3907 | return NULL; |
3908 | } | ||
3909 | if (new_skb != skb) | ||
3910 | __qeth_free_new_skb(new_skb2, new_skb); | ||
3911 | new_skb = new_skb2; | ||
3978 | *hdr = __qeth_prepare_skb(card, new_skb, ipv); | 3912 | *hdr = __qeth_prepare_skb(card, new_skb, ipv); |
3979 | if (*hdr == NULL) { | 3913 | if (*hdr == NULL) { |
3980 | __qeth_free_new_skb(skb, new_skb); | 3914 | __qeth_free_new_skb(skb, new_skb); |
@@ -4844,9 +4778,11 @@ qeth_arp_query(struct qeth_card *card, char __user *udata) | |||
4844 | "(0x%x/%d)\n", | 4778 | "(0x%x/%d)\n", |
4845 | QETH_CARD_IFNAME(card), qeth_arp_get_error_cause(&rc), | 4779 | QETH_CARD_IFNAME(card), qeth_arp_get_error_cause(&rc), |
4846 | tmp, tmp); | 4780 | tmp, tmp); |
4847 | copy_to_user(udata, qinfo.udata, 4); | 4781 | if (copy_to_user(udata, qinfo.udata, 4)) |
4782 | rc = -EFAULT; | ||
4848 | } else { | 4783 | } else { |
4849 | copy_to_user(udata, qinfo.udata, qinfo.udata_len); | 4784 | if (copy_to_user(udata, qinfo.udata, qinfo.udata_len)) |
4785 | rc = -EFAULT; | ||
4850 | } | 4786 | } |
4851 | kfree(qinfo.udata); | 4787 | kfree(qinfo.udata); |
4852 | return rc; | 4788 | return rc; |
@@ -4992,8 +4928,10 @@ qeth_snmp_command(struct qeth_card *card, char __user *udata) | |||
4992 | if (rc) | 4928 | if (rc) |
4993 | PRINT_WARN("SNMP command failed on %s: (0x%x)\n", | 4929 | PRINT_WARN("SNMP command failed on %s: (0x%x)\n", |
4994 | QETH_CARD_IFNAME(card), rc); | 4930 | QETH_CARD_IFNAME(card), rc); |
4995 | else | 4931 | else { |
4996 | copy_to_user(udata, qinfo.udata, qinfo.udata_len); | 4932 | if (copy_to_user(udata, qinfo.udata, qinfo.udata_len)) |
4933 | rc = -EFAULT; | ||
4934 | } | ||
4997 | 4935 | ||
4998 | kfree(ureq); | 4936 | kfree(ureq); |
4999 | kfree(qinfo.udata); | 4937 | kfree(qinfo.udata); |
@@ -5544,12 +5482,10 @@ qeth_set_multicast_list(struct net_device *dev) | |||
5544 | qeth_add_multicast_ipv6(card); | 5482 | qeth_add_multicast_ipv6(card); |
5545 | #endif | 5483 | #endif |
5546 | out: | 5484 | out: |
5547 | if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0) | 5485 | qeth_set_ip_addr_list(card); |
5548 | schedule_work(&card->kernel_thread_starter); | ||
5549 | if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE)) | 5486 | if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE)) |
5550 | return; | 5487 | return; |
5551 | if (qeth_set_thread_start_bit(card, QETH_SET_PROMISC_MODE_THREAD)==0) | 5488 | qeth_setadp_promisc_mode(card); |
5552 | schedule_work(&card->kernel_thread_starter); | ||
5553 | } | 5489 | } |
5554 | 5490 | ||
5555 | static int | 5491 | static int |
@@ -6351,6 +6287,42 @@ static struct ethtool_ops qeth_ethtool_ops = { | |||
6351 | }; | 6287 | }; |
6352 | 6288 | ||
6353 | static int | 6289 | static int |
6290 | qeth_hard_header_parse(struct sk_buff *skb, unsigned char *haddr) | ||
6291 | { | ||
6292 | struct qeth_card *card; | ||
6293 | struct ethhdr *eth; | ||
6294 | |||
6295 | card = qeth_get_card_from_dev(skb->dev); | ||
6296 | if (card->options.layer2) | ||
6297 | goto haveheader; | ||
6298 | #ifdef CONFIG_QETH_IPV6 | ||
6299 | /* cause of the manipulated arp constructor and the ARP | ||
6300 | flag for OSAE devices we have some nasty exceptions */ | ||
6301 | if (card->info.type == QETH_CARD_TYPE_OSAE) { | ||
6302 | if (!card->options.fake_ll) { | ||
6303 | if ((skb->pkt_type==PACKET_OUTGOING) && | ||
6304 | (skb->protocol==ETH_P_IPV6)) | ||
6305 | goto haveheader; | ||
6306 | else | ||
6307 | return 0; | ||
6308 | } else { | ||
6309 | if ((skb->pkt_type==PACKET_OUTGOING) && | ||
6310 | (skb->protocol==ETH_P_IP)) | ||
6311 | return 0; | ||
6312 | else | ||
6313 | goto haveheader; | ||
6314 | } | ||
6315 | } | ||
6316 | #endif | ||
6317 | if (!card->options.fake_ll) | ||
6318 | return 0; | ||
6319 | haveheader: | ||
6320 | eth = eth_hdr(skb); | ||
6321 | memcpy(haddr, eth->h_source, ETH_ALEN); | ||
6322 | return ETH_ALEN; | ||
6323 | } | ||
6324 | |||
6325 | static int | ||
6354 | qeth_netdev_init(struct net_device *dev) | 6326 | qeth_netdev_init(struct net_device *dev) |
6355 | { | 6327 | { |
6356 | struct qeth_card *card; | 6328 | struct qeth_card *card; |
@@ -6388,7 +6360,10 @@ qeth_netdev_init(struct net_device *dev) | |||
6388 | if (card->options.fake_ll && | 6360 | if (card->options.fake_ll && |
6389 | (qeth_get_netdev_flags(card) & IFF_NOARP)) | 6361 | (qeth_get_netdev_flags(card) & IFF_NOARP)) |
6390 | dev->hard_header = qeth_fake_header; | 6362 | dev->hard_header = qeth_fake_header; |
6391 | dev->hard_header_parse = NULL; | 6363 | if (dev->type == ARPHRD_IEEE802_TR) |
6364 | dev->hard_header_parse = NULL; | ||
6365 | else | ||
6366 | dev->hard_header_parse = qeth_hard_header_parse; | ||
6392 | dev->set_mac_address = qeth_layer2_set_mac_address; | 6367 | dev->set_mac_address = qeth_layer2_set_mac_address; |
6393 | dev->flags |= qeth_get_netdev_flags(card); | 6368 | dev->flags |= qeth_get_netdev_flags(card); |
6394 | if ((card->options.fake_broadcast) || | 6369 | if ((card->options.fake_broadcast) || |
@@ -8235,8 +8210,7 @@ qeth_add_vipa(struct qeth_card *card, enum qeth_prot_versions proto, | |||
8235 | } | 8210 | } |
8236 | if (!qeth_add_ip(card, ipaddr)) | 8211 | if (!qeth_add_ip(card, ipaddr)) |
8237 | kfree(ipaddr); | 8212 | kfree(ipaddr); |
8238 | if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0) | 8213 | qeth_set_ip_addr_list(card); |
8239 | schedule_work(&card->kernel_thread_starter); | ||
8240 | return rc; | 8214 | return rc; |
8241 | } | 8215 | } |
8242 | 8216 | ||
@@ -8264,8 +8238,7 @@ qeth_del_vipa(struct qeth_card *card, enum qeth_prot_versions proto, | |||
8264 | return; | 8238 | return; |
8265 | if (!qeth_delete_ip(card, ipaddr)) | 8239 | if (!qeth_delete_ip(card, ipaddr)) |
8266 | kfree(ipaddr); | 8240 | kfree(ipaddr); |
8267 | if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0) | 8241 | qeth_set_ip_addr_list(card); |
8268 | schedule_work(&card->kernel_thread_starter); | ||
8269 | } | 8242 | } |
8270 | 8243 | ||
8271 | /* | 8244 | /* |
@@ -8308,8 +8281,7 @@ qeth_add_rxip(struct qeth_card *card, enum qeth_prot_versions proto, | |||
8308 | } | 8281 | } |
8309 | if (!qeth_add_ip(card, ipaddr)) | 8282 | if (!qeth_add_ip(card, ipaddr)) |
8310 | kfree(ipaddr); | 8283 | kfree(ipaddr); |
8311 | if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0) | 8284 | qeth_set_ip_addr_list(card); |
8312 | schedule_work(&card->kernel_thread_starter); | ||
8313 | return 0; | 8285 | return 0; |
8314 | } | 8286 | } |
8315 | 8287 | ||
@@ -8337,8 +8309,7 @@ qeth_del_rxip(struct qeth_card *card, enum qeth_prot_versions proto, | |||
8337 | return; | 8309 | return; |
8338 | if (!qeth_delete_ip(card, ipaddr)) | 8310 | if (!qeth_delete_ip(card, ipaddr)) |
8339 | kfree(ipaddr); | 8311 | kfree(ipaddr); |
8340 | if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0) | 8312 | qeth_set_ip_addr_list(card); |
8341 | schedule_work(&card->kernel_thread_starter); | ||
8342 | } | 8313 | } |
8343 | 8314 | ||
8344 | /** | 8315 | /** |
@@ -8380,8 +8351,7 @@ qeth_ip_event(struct notifier_block *this, | |||
8380 | default: | 8351 | default: |
8381 | break; | 8352 | break; |
8382 | } | 8353 | } |
8383 | if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0) | 8354 | qeth_set_ip_addr_list(card); |
8384 | schedule_work(&card->kernel_thread_starter); | ||
8385 | out: | 8355 | out: |
8386 | return NOTIFY_DONE; | 8356 | return NOTIFY_DONE; |
8387 | } | 8357 | } |
@@ -8433,8 +8403,7 @@ qeth_ip6_event(struct notifier_block *this, | |||
8433 | default: | 8403 | default: |
8434 | break; | 8404 | break; |
8435 | } | 8405 | } |
8436 | if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0) | 8406 | qeth_set_ip_addr_list(card); |
8437 | schedule_work(&card->kernel_thread_starter); | ||
8438 | out: | 8407 | out: |
8439 | return NOTIFY_DONE; | 8408 | return NOTIFY_DONE; |
8440 | } | 8409 | } |