diff options
Diffstat (limited to 'drivers/s390/net/qeth_main.c')
-rw-r--r-- | drivers/s390/net/qeth_main.c | 174 |
1 files changed, 82 insertions, 92 deletions
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 79c74f3a11f..bd28e2438d7 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.214 $) | 3 | * linux/drivers/s390/net/qeth_main.c ($Revision: 1.224 $) |
4 | * | 4 | * |
5 | * Linux on zSeries OSA Express and HiperSockets support | 5 | * Linux on zSeries OSA Express and HiperSockets support |
6 | * | 6 | * |
@@ -12,7 +12,7 @@ | |||
12 | * Frank Pavlic (pavlic@de.ibm.com) and | 12 | * Frank Pavlic (pavlic@de.ibm.com) and |
13 | * Thomas Spatzier <tspat@de.ibm.com> | 13 | * Thomas Spatzier <tspat@de.ibm.com> |
14 | * | 14 | * |
15 | * $Revision: 1.214 $ $Date: 2005/05/04 20:19:18 $ | 15 | * $Revision: 1.224 $ $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 |
@@ -29,14 +29,6 @@ | |||
29 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 29 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
30 | */ | 30 | */ |
31 | 31 | ||
32 | /*** | ||
33 | * eye catcher; just for debugging purposes | ||
34 | */ | ||
35 | void volatile | ||
36 | qeth_eyecatcher(void) | ||
37 | { | ||
38 | return; | ||
39 | } | ||
40 | 32 | ||
41 | #include <linux/config.h> | 33 | #include <linux/config.h> |
42 | #include <linux/module.h> | 34 | #include <linux/module.h> |
@@ -80,7 +72,7 @@ qeth_eyecatcher(void) | |||
80 | #include "qeth_eddp.h" | 72 | #include "qeth_eddp.h" |
81 | #include "qeth_tso.h" | 73 | #include "qeth_tso.h" |
82 | 74 | ||
83 | #define VERSION_QETH_C "$Revision: 1.214 $" | 75 | #define VERSION_QETH_C "$Revision: 1.224 $" |
84 | static const char *version = "qeth S/390 OSA-Express driver"; | 76 | static const char *version = "qeth S/390 OSA-Express driver"; |
85 | 77 | ||
86 | /** | 78 | /** |
@@ -519,7 +511,7 @@ static int | |||
519 | __qeth_set_offline(struct ccwgroup_device *cgdev, int recovery_mode) | 511 | __qeth_set_offline(struct ccwgroup_device *cgdev, int recovery_mode) |
520 | { | 512 | { |
521 | struct qeth_card *card = (struct qeth_card *) cgdev->dev.driver_data; | 513 | struct qeth_card *card = (struct qeth_card *) cgdev->dev.driver_data; |
522 | int rc = 0; | 514 | int rc = 0, rc2 = 0, rc3 = 0; |
523 | enum qeth_card_states recover_flag; | 515 | enum qeth_card_states recover_flag; |
524 | 516 | ||
525 | QETH_DBF_TEXT(setup, 3, "setoffl"); | 517 | QETH_DBF_TEXT(setup, 3, "setoffl"); |
@@ -531,11 +523,13 @@ __qeth_set_offline(struct ccwgroup_device *cgdev, int recovery_mode) | |||
531 | CARD_BUS_ID(card)); | 523 | CARD_BUS_ID(card)); |
532 | return -ERESTARTSYS; | 524 | return -ERESTARTSYS; |
533 | } | 525 | } |
534 | if ((rc = ccw_device_set_offline(CARD_DDEV(card))) || | 526 | rc = ccw_device_set_offline(CARD_DDEV(card)); |
535 | (rc = ccw_device_set_offline(CARD_WDEV(card))) || | 527 | rc2 = ccw_device_set_offline(CARD_WDEV(card)); |
536 | (rc = ccw_device_set_offline(CARD_RDEV(card)))) { | 528 | rc3 = ccw_device_set_offline(CARD_RDEV(card)); |
529 | if (!rc) | ||
530 | rc = (rc2) ? rc2 : rc3; | ||
531 | if (rc) | ||
537 | QETH_DBF_TEXT_(setup, 2, "1err%d", rc); | 532 | QETH_DBF_TEXT_(setup, 2, "1err%d", rc); |
538 | } | ||
539 | if (recover_flag == CARD_STATE_UP) | 533 | if (recover_flag == CARD_STATE_UP) |
540 | card->state = CARD_STATE_RECOVER; | 534 | card->state = CARD_STATE_RECOVER; |
541 | qeth_notify_processes(); | 535 | qeth_notify_processes(); |
@@ -1054,6 +1048,7 @@ qeth_setup_card(struct qeth_card *card) | |||
1054 | spin_lock_init(&card->vlanlock); | 1048 | spin_lock_init(&card->vlanlock); |
1055 | card->vlangrp = NULL; | 1049 | card->vlangrp = NULL; |
1056 | #endif | 1050 | #endif |
1051 | spin_lock_init(&card->lock); | ||
1057 | spin_lock_init(&card->ip_lock); | 1052 | spin_lock_init(&card->ip_lock); |
1058 | spin_lock_init(&card->thread_mask_lock); | 1053 | spin_lock_init(&card->thread_mask_lock); |
1059 | card->thread_start_mask = 0; | 1054 | card->thread_start_mask = 0; |
@@ -1634,16 +1629,6 @@ qeth_cmd_timeout(unsigned long data) | |||
1634 | spin_unlock_irqrestore(&reply->card->lock, flags); | 1629 | spin_unlock_irqrestore(&reply->card->lock, flags); |
1635 | } | 1630 | } |
1636 | 1631 | ||
1637 | static void | ||
1638 | qeth_reset_ip_addresses(struct qeth_card *card) | ||
1639 | { | ||
1640 | QETH_DBF_TEXT(trace, 2, "rstipadd"); | ||
1641 | |||
1642 | qeth_clear_ip_list(card, 0, 1); | ||
1643 | /* this function will also schedule the SET_IP_THREAD */ | ||
1644 | qeth_set_multicast_list(card->dev); | ||
1645 | } | ||
1646 | |||
1647 | static struct qeth_ipa_cmd * | 1632 | static struct qeth_ipa_cmd * |
1648 | qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob) | 1633 | qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob) |
1649 | { | 1634 | { |
@@ -1672,9 +1657,8 @@ qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob) | |||
1672 | "IP address reset.\n", | 1657 | "IP address reset.\n", |
1673 | QETH_CARD_IFNAME(card), | 1658 | QETH_CARD_IFNAME(card), |
1674 | card->info.chpid); | 1659 | card->info.chpid); |
1675 | card->lan_online = 1; | ||
1676 | netif_carrier_on(card->dev); | 1660 | netif_carrier_on(card->dev); |
1677 | qeth_reset_ip_addresses(card); | 1661 | qeth_schedule_recovery(card); |
1678 | return NULL; | 1662 | return NULL; |
1679 | case IPA_CMD_REGISTER_LOCAL_ADDR: | 1663 | case IPA_CMD_REGISTER_LOCAL_ADDR: |
1680 | QETH_DBF_TEXT(trace,3, "irla"); | 1664 | QETH_DBF_TEXT(trace,3, "irla"); |
@@ -2395,6 +2379,7 @@ qeth_layer2_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, | |||
2395 | skb_pull(skb, VLAN_HLEN); | 2379 | skb_pull(skb, VLAN_HLEN); |
2396 | } | 2380 | } |
2397 | #endif | 2381 | #endif |
2382 | *((__u32 *)skb->cb) = ++card->seqno.pkt_seqno; | ||
2398 | return vlan_id; | 2383 | return vlan_id; |
2399 | } | 2384 | } |
2400 | 2385 | ||
@@ -2759,11 +2744,9 @@ qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int, | |||
2759 | queue->card->perf_stats.outbound_do_qdio_start_time; | 2744 | queue->card->perf_stats.outbound_do_qdio_start_time; |
2760 | #endif | 2745 | #endif |
2761 | if (rc){ | 2746 | if (rc){ |
2762 | QETH_DBF_SPRINTF(trace, 0, "qeth_flush_buffers: do_QDIO " | ||
2763 | "returned error (%i) on device %s.", | ||
2764 | rc, CARD_DDEV_ID(queue->card)); | ||
2765 | QETH_DBF_TEXT(trace, 2, "flushbuf"); | 2747 | QETH_DBF_TEXT(trace, 2, "flushbuf"); |
2766 | QETH_DBF_TEXT_(trace, 2, " err%d", rc); | 2748 | QETH_DBF_TEXT_(trace, 2, " err%d", rc); |
2749 | QETH_DBF_TEXT_(trace, 2, "%s", CARD_DDEV_ID(queue->card)); | ||
2767 | queue->card->stats.tx_errors += count; | 2750 | queue->card->stats.tx_errors += count; |
2768 | /* this must not happen under normal circumstances. if it | 2751 | /* this must not happen under normal circumstances. if it |
2769 | * happens something is really wrong -> recover */ | 2752 | * happens something is really wrong -> recover */ |
@@ -2909,11 +2892,8 @@ qeth_qdio_output_handler(struct ccw_device * ccwdev, unsigned int status, | |||
2909 | QETH_DBF_TEXT(trace, 6, "qdouhdl"); | 2892 | QETH_DBF_TEXT(trace, 6, "qdouhdl"); |
2910 | if (status & QDIO_STATUS_LOOK_FOR_ERROR) { | 2893 | if (status & QDIO_STATUS_LOOK_FOR_ERROR) { |
2911 | if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION){ | 2894 | if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION){ |
2912 | QETH_DBF_SPRINTF(trace, 2, "On device %s: " | 2895 | QETH_DBF_TEXT(trace, 2, "achkcond"); |
2913 | "received active check " | 2896 | QETH_DBF_TEXT_(trace, 2, "%s", CARD_BUS_ID(card)); |
2914 | "condition (0x%08x).", | ||
2915 | CARD_BUS_ID(card), status); | ||
2916 | QETH_DBF_TEXT(trace, 2, "chkcond"); | ||
2917 | QETH_DBF_TEXT_(trace, 2, "%08x", status); | 2897 | QETH_DBF_TEXT_(trace, 2, "%08x", status); |
2918 | netif_stop_queue(card->dev); | 2898 | netif_stop_queue(card->dev); |
2919 | qeth_schedule_recovery(card); | 2899 | qeth_schedule_recovery(card); |
@@ -3027,7 +3007,7 @@ qeth_alloc_buffer_pool(struct qeth_card *card) | |||
3027 | return -ENOMEM; | 3007 | return -ENOMEM; |
3028 | } | 3008 | } |
3029 | for(j = 0; j < QETH_MAX_BUFFER_ELEMENTS(card); ++j){ | 3009 | for(j = 0; j < QETH_MAX_BUFFER_ELEMENTS(card); ++j){ |
3030 | ptr = (void *) __get_free_page(GFP_KERNEL); | 3010 | ptr = (void *) __get_free_page(GFP_KERNEL|GFP_DMA); |
3031 | if (!ptr) { | 3011 | if (!ptr) { |
3032 | while (j > 0) | 3012 | while (j > 0) |
3033 | free_page((unsigned long) | 3013 | free_page((unsigned long) |
@@ -3071,7 +3051,8 @@ qeth_alloc_qdio_buffers(struct qeth_card *card) | |||
3071 | if (card->qdio.state == QETH_QDIO_ALLOCATED) | 3051 | if (card->qdio.state == QETH_QDIO_ALLOCATED) |
3072 | return 0; | 3052 | return 0; |
3073 | 3053 | ||
3074 | card->qdio.in_q = kmalloc(sizeof(struct qeth_qdio_q), GFP_KERNEL); | 3054 | card->qdio.in_q = kmalloc(sizeof(struct qeth_qdio_q), |
3055 | GFP_KERNEL|GFP_DMA); | ||
3075 | if (!card->qdio.in_q) | 3056 | if (!card->qdio.in_q) |
3076 | return - ENOMEM; | 3057 | return - ENOMEM; |
3077 | QETH_DBF_TEXT(setup, 2, "inq"); | 3058 | QETH_DBF_TEXT(setup, 2, "inq"); |
@@ -3096,7 +3077,7 @@ qeth_alloc_qdio_buffers(struct qeth_card *card) | |||
3096 | } | 3077 | } |
3097 | for (i = 0; i < card->qdio.no_out_queues; ++i){ | 3078 | for (i = 0; i < card->qdio.no_out_queues; ++i){ |
3098 | card->qdio.out_qs[i] = kmalloc(sizeof(struct qeth_qdio_out_q), | 3079 | card->qdio.out_qs[i] = kmalloc(sizeof(struct qeth_qdio_out_q), |
3099 | GFP_KERNEL); | 3080 | GFP_KERNEL|GFP_DMA); |
3100 | if (!card->qdio.out_qs[i]){ | 3081 | if (!card->qdio.out_qs[i]){ |
3101 | while (i > 0) | 3082 | while (i > 0) |
3102 | kfree(card->qdio.out_qs[--i]); | 3083 | kfree(card->qdio.out_qs[--i]); |
@@ -3356,26 +3337,32 @@ qeth_halt_channel(struct qeth_channel *channel) | |||
3356 | static int | 3337 | static int |
3357 | qeth_halt_channels(struct qeth_card *card) | 3338 | qeth_halt_channels(struct qeth_card *card) |
3358 | { | 3339 | { |
3359 | int rc = 0; | 3340 | int rc1 = 0, rc2=0, rc3 = 0; |
3360 | 3341 | ||
3361 | QETH_DBF_TEXT(trace,3,"haltchs"); | 3342 | QETH_DBF_TEXT(trace,3,"haltchs"); |
3362 | if ((rc = qeth_halt_channel(&card->read))) | 3343 | rc1 = qeth_halt_channel(&card->read); |
3363 | return rc; | 3344 | rc2 = qeth_halt_channel(&card->write); |
3364 | if ((rc = qeth_halt_channel(&card->write))) | 3345 | rc3 = qeth_halt_channel(&card->data); |
3365 | return rc; | 3346 | if (rc1) |
3366 | return qeth_halt_channel(&card->data); | 3347 | return rc1; |
3348 | if (rc2) | ||
3349 | return rc2; | ||
3350 | return rc3; | ||
3367 | } | 3351 | } |
3368 | static int | 3352 | static int |
3369 | qeth_clear_channels(struct qeth_card *card) | 3353 | qeth_clear_channels(struct qeth_card *card) |
3370 | { | 3354 | { |
3371 | int rc = 0; | 3355 | int rc1 = 0, rc2=0, rc3 = 0; |
3372 | 3356 | ||
3373 | QETH_DBF_TEXT(trace,3,"clearchs"); | 3357 | QETH_DBF_TEXT(trace,3,"clearchs"); |
3374 | if ((rc = qeth_clear_channel(&card->read))) | 3358 | rc1 = qeth_clear_channel(&card->read); |
3375 | return rc; | 3359 | rc2 = qeth_clear_channel(&card->write); |
3376 | if ((rc = qeth_clear_channel(&card->write))) | 3360 | rc3 = qeth_clear_channel(&card->data); |
3377 | return rc; | 3361 | if (rc1) |
3378 | return qeth_clear_channel(&card->data); | 3362 | return rc1; |
3363 | if (rc2) | ||
3364 | return rc2; | ||
3365 | return rc3; | ||
3379 | } | 3366 | } |
3380 | 3367 | ||
3381 | static int | 3368 | static int |
@@ -3445,23 +3432,23 @@ qeth_mpc_initialize(struct qeth_card *card) | |||
3445 | } | 3432 | } |
3446 | if ((rc = qeth_cm_enable(card))){ | 3433 | if ((rc = qeth_cm_enable(card))){ |
3447 | QETH_DBF_TEXT_(setup, 2, "2err%d", rc); | 3434 | QETH_DBF_TEXT_(setup, 2, "2err%d", rc); |
3448 | return rc; | 3435 | goto out_qdio; |
3449 | } | 3436 | } |
3450 | if ((rc = qeth_cm_setup(card))){ | 3437 | if ((rc = qeth_cm_setup(card))){ |
3451 | QETH_DBF_TEXT_(setup, 2, "3err%d", rc); | 3438 | QETH_DBF_TEXT_(setup, 2, "3err%d", rc); |
3452 | return rc; | 3439 | goto out_qdio; |
3453 | } | 3440 | } |
3454 | if ((rc = qeth_ulp_enable(card))){ | 3441 | if ((rc = qeth_ulp_enable(card))){ |
3455 | QETH_DBF_TEXT_(setup, 2, "4err%d", rc); | 3442 | QETH_DBF_TEXT_(setup, 2, "4err%d", rc); |
3456 | return rc; | 3443 | goto out_qdio; |
3457 | } | 3444 | } |
3458 | if ((rc = qeth_ulp_setup(card))){ | 3445 | if ((rc = qeth_ulp_setup(card))){ |
3459 | QETH_DBF_TEXT_(setup, 2, "5err%d", rc); | 3446 | QETH_DBF_TEXT_(setup, 2, "5err%d", rc); |
3460 | return rc; | 3447 | goto out_qdio; |
3461 | } | 3448 | } |
3462 | if ((rc = qeth_alloc_qdio_buffers(card))){ | 3449 | if ((rc = qeth_alloc_qdio_buffers(card))){ |
3463 | QETH_DBF_TEXT_(setup, 2, "5err%d", rc); | 3450 | QETH_DBF_TEXT_(setup, 2, "5err%d", rc); |
3464 | return rc; | 3451 | goto out_qdio; |
3465 | } | 3452 | } |
3466 | if ((rc = qeth_qdio_establish(card))){ | 3453 | if ((rc = qeth_qdio_establish(card))){ |
3467 | QETH_DBF_TEXT_(setup, 2, "6err%d", rc); | 3454 | QETH_DBF_TEXT_(setup, 2, "6err%d", rc); |
@@ -3795,12 +3782,16 @@ static inline int | |||
3795 | qeth_prepare_skb(struct qeth_card *card, struct sk_buff **skb, | 3782 | qeth_prepare_skb(struct qeth_card *card, struct sk_buff **skb, |
3796 | struct qeth_hdr **hdr, int ipv) | 3783 | struct qeth_hdr **hdr, int ipv) |
3797 | { | 3784 | { |
3785 | int rc; | ||
3798 | #ifdef CONFIG_QETH_VLAN | 3786 | #ifdef CONFIG_QETH_VLAN |
3799 | u16 *tag; | 3787 | u16 *tag; |
3800 | #endif | 3788 | #endif |
3801 | 3789 | ||
3802 | QETH_DBF_TEXT(trace, 6, "prepskb"); | 3790 | QETH_DBF_TEXT(trace, 6, "prepskb"); |
3803 | 3791 | ||
3792 | rc = qeth_realloc_headroom(card, skb, sizeof(struct qeth_hdr)); | ||
3793 | if (rc) | ||
3794 | return rc; | ||
3804 | #ifdef CONFIG_QETH_VLAN | 3795 | #ifdef CONFIG_QETH_VLAN |
3805 | if (card->vlangrp && vlan_tx_tag_present(*skb) && | 3796 | if (card->vlangrp && vlan_tx_tag_present(*skb) && |
3806 | ((ipv == 6) || card->options.layer2) ) { | 3797 | ((ipv == 6) || card->options.layer2) ) { |
@@ -4251,7 +4242,8 @@ out: | |||
4251 | } | 4242 | } |
4252 | 4243 | ||
4253 | static inline int | 4244 | static inline int |
4254 | qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb) | 4245 | qeth_get_elements_no(struct qeth_card *card, void *hdr, |
4246 | struct sk_buff *skb, int elems) | ||
4255 | { | 4247 | { |
4256 | int elements_needed = 0; | 4248 | int elements_needed = 0; |
4257 | 4249 | ||
@@ -4261,9 +4253,10 @@ qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb) | |||
4261 | if (elements_needed == 0 ) | 4253 | if (elements_needed == 0 ) |
4262 | elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE) | 4254 | elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE) |
4263 | + skb->len) >> PAGE_SHIFT); | 4255 | + skb->len) >> PAGE_SHIFT); |
4264 | if (elements_needed > QETH_MAX_BUFFER_ELEMENTS(card)){ | 4256 | if ((elements_needed + elems) > QETH_MAX_BUFFER_ELEMENTS(card)){ |
4265 | PRINT_ERR("qeth_do_send_packet: invalid size of " | 4257 | PRINT_ERR("qeth_do_send_packet: invalid size of " |
4266 | "IP packet. Discarded."); | 4258 | "IP packet (Number=%d / Length=%d). Discarded.\n", |
4259 | (elements_needed+elems), skb->len); | ||
4267 | return 0; | 4260 | return 0; |
4268 | } | 4261 | } |
4269 | return elements_needed; | 4262 | return elements_needed; |
@@ -4275,7 +4268,7 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) | |||
4275 | int ipv = 0; | 4268 | int ipv = 0; |
4276 | int cast_type; | 4269 | int cast_type; |
4277 | struct qeth_qdio_out_q *queue; | 4270 | struct qeth_qdio_out_q *queue; |
4278 | struct qeth_hdr *hdr; | 4271 | struct qeth_hdr *hdr = NULL; |
4279 | int elements_needed = 0; | 4272 | int elements_needed = 0; |
4280 | enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO; | 4273 | enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO; |
4281 | struct qeth_eddp_context *ctx = NULL; | 4274 | struct qeth_eddp_context *ctx = NULL; |
@@ -4337,9 +4330,11 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) | |||
4337 | return -EINVAL; | 4330 | return -EINVAL; |
4338 | } | 4331 | } |
4339 | } else { | 4332 | } else { |
4340 | elements_needed += qeth_get_elements_no(card,(void*) hdr, skb); | 4333 | int elems = qeth_get_elements_no(card,(void*) hdr, skb, |
4341 | if (!elements_needed) | 4334 | elements_needed); |
4335 | if (!elems) | ||
4342 | return -EINVAL; | 4336 | return -EINVAL; |
4337 | elements_needed += elems; | ||
4343 | } | 4338 | } |
4344 | 4339 | ||
4345 | if (card->info.type != QETH_CARD_TYPE_IQD) | 4340 | if (card->info.type != QETH_CARD_TYPE_IQD) |
@@ -4504,7 +4499,11 @@ qeth_arp_set_no_entries(struct qeth_card *card, int no_entries) | |||
4504 | 4499 | ||
4505 | QETH_DBF_TEXT(trace,3,"arpstnoe"); | 4500 | QETH_DBF_TEXT(trace,3,"arpstnoe"); |
4506 | 4501 | ||
4507 | /* TODO: really not supported by GuestLAN? */ | 4502 | /* |
4503 | * currently GuestLAN only supports the ARP assist function | ||
4504 | * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_SET_NO_ENTRIES; | ||
4505 | * thus we say EOPNOTSUPP for this ARP function | ||
4506 | */ | ||
4508 | if (card->info.guestlan) | 4507 | if (card->info.guestlan) |
4509 | return -EOPNOTSUPP; | 4508 | return -EOPNOTSUPP; |
4510 | if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) { | 4509 | if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) { |
@@ -4681,14 +4680,6 @@ qeth_arp_query(struct qeth_card *card, char *udata) | |||
4681 | 4680 | ||
4682 | QETH_DBF_TEXT(trace,3,"arpquery"); | 4681 | QETH_DBF_TEXT(trace,3,"arpquery"); |
4683 | 4682 | ||
4684 | /* | ||
4685 | * currently GuestLAN does only deliver all zeros on query arp, | ||
4686 | * even though arp processing is supported (according to IPA supp. | ||
4687 | * funcs flags); since all zeros is no valueable information, | ||
4688 | * we say EOPNOTSUPP for all ARP functions | ||
4689 | */ | ||
4690 | /*if (card->info.guestlan) | ||
4691 | return -EOPNOTSUPP; */ | ||
4692 | if (!qeth_is_supported(card,/*IPA_QUERY_ARP_ADDR_INFO*/ | 4683 | if (!qeth_is_supported(card,/*IPA_QUERY_ARP_ADDR_INFO*/ |
4693 | IPA_ARP_PROCESSING)) { | 4684 | IPA_ARP_PROCESSING)) { |
4694 | PRINT_WARN("ARP processing not supported " | 4685 | PRINT_WARN("ARP processing not supported " |
@@ -4894,10 +4885,9 @@ qeth_arp_add_entry(struct qeth_card *card, struct qeth_arp_cache_entry *entry) | |||
4894 | QETH_DBF_TEXT(trace,3,"arpadent"); | 4885 | QETH_DBF_TEXT(trace,3,"arpadent"); |
4895 | 4886 | ||
4896 | /* | 4887 | /* |
4897 | * currently GuestLAN does only deliver all zeros on query arp, | 4888 | * currently GuestLAN only supports the ARP assist function |
4898 | * even though arp processing is supported (according to IPA supp. | 4889 | * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_ADD_ENTRY; |
4899 | * funcs flags); since all zeros is no valueable information, | 4890 | * thus we say EOPNOTSUPP for this ARP function |
4900 | * we say EOPNOTSUPP for all ARP functions | ||
4901 | */ | 4891 | */ |
4902 | if (card->info.guestlan) | 4892 | if (card->info.guestlan) |
4903 | return -EOPNOTSUPP; | 4893 | return -EOPNOTSUPP; |
@@ -4937,10 +4927,9 @@ qeth_arp_remove_entry(struct qeth_card *card, struct qeth_arp_cache_entry *entry | |||
4937 | QETH_DBF_TEXT(trace,3,"arprment"); | 4927 | QETH_DBF_TEXT(trace,3,"arprment"); |
4938 | 4928 | ||
4939 | /* | 4929 | /* |
4940 | * currently GuestLAN does only deliver all zeros on query arp, | 4930 | * currently GuestLAN only supports the ARP assist function |
4941 | * even though arp processing is supported (according to IPA supp. | 4931 | * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_REMOVE_ENTRY; |
4942 | * funcs flags); since all zeros is no valueable information, | 4932 | * thus we say EOPNOTSUPP for this ARP function |
4943 | * we say EOPNOTSUPP for all ARP functions | ||
4944 | */ | 4933 | */ |
4945 | if (card->info.guestlan) | 4934 | if (card->info.guestlan) |
4946 | return -EOPNOTSUPP; | 4935 | return -EOPNOTSUPP; |
@@ -4978,11 +4967,10 @@ qeth_arp_flush_cache(struct qeth_card *card) | |||
4978 | QETH_DBF_TEXT(trace,3,"arpflush"); | 4967 | QETH_DBF_TEXT(trace,3,"arpflush"); |
4979 | 4968 | ||
4980 | /* | 4969 | /* |
4981 | * currently GuestLAN does only deliver all zeros on query arp, | 4970 | * currently GuestLAN only supports the ARP assist function |
4982 | * even though arp processing is supported (according to IPA supp. | 4971 | * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_FLUSH_CACHE; |
4983 | * funcs flags); since all zeros is no valueable information, | 4972 | * thus we say EOPNOTSUPP for this ARP function |
4984 | * we say EOPNOTSUPP for all ARP functions | 4973 | */ |
4985 | */ | ||
4986 | if (card->info.guestlan || (card->info.type == QETH_CARD_TYPE_IQD)) | 4974 | if (card->info.guestlan || (card->info.type == QETH_CARD_TYPE_IQD)) |
4987 | return -EOPNOTSUPP; | 4975 | return -EOPNOTSUPP; |
4988 | if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) { | 4976 | if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) { |
@@ -5206,7 +5194,7 @@ qeth_free_vlan_addresses4(struct qeth_card *card, unsigned short vid) | |||
5206 | if (!card->vlangrp) | 5194 | if (!card->vlangrp) |
5207 | return; | 5195 | return; |
5208 | rcu_read_lock(); | 5196 | rcu_read_lock(); |
5209 | in_dev = __in_dev_get(card->vlangrp->vlan_devices[vid]); | 5197 | in_dev = __in_dev_get_rcu(card->vlangrp->vlan_devices[vid]); |
5210 | if (!in_dev) | 5198 | if (!in_dev) |
5211 | goto out; | 5199 | goto out; |
5212 | for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) { | 5200 | for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) { |
@@ -6476,6 +6464,9 @@ qeth_query_ipassists_cb(struct qeth_card *card, struct qeth_reply *reply, | |||
6476 | if (cmd->hdr.prot_version == QETH_PROT_IPV4) { | 6464 | if (cmd->hdr.prot_version == QETH_PROT_IPV4) { |
6477 | card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported; | 6465 | card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported; |
6478 | card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled; | 6466 | card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled; |
6467 | /* Disable IPV6 support hard coded for Hipersockets */ | ||
6468 | if(card->info.type == QETH_CARD_TYPE_IQD) | ||
6469 | card->options.ipa4.supported_funcs &= ~IPA_IPV6; | ||
6479 | } else { | 6470 | } else { |
6480 | #ifdef CONFIG_QETH_IPV6 | 6471 | #ifdef CONFIG_QETH_IPV6 |
6481 | card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported; | 6472 | card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported; |
@@ -7038,14 +7029,16 @@ qeth_setrouting_v6(struct qeth_card *card) | |||
7038 | } | 7029 | } |
7039 | 7030 | ||
7040 | int | 7031 | int |
7041 | qeth_set_large_send(struct qeth_card *card) | 7032 | qeth_set_large_send(struct qeth_card *card, enum qeth_large_send_types type) |
7042 | { | 7033 | { |
7043 | int rc = 0; | 7034 | int rc = 0; |
7044 | 7035 | ||
7045 | if (card->dev == NULL) | 7036 | if (card->dev == NULL) { |
7037 | card->options.large_send = type; | ||
7046 | return 0; | 7038 | return 0; |
7047 | 7039 | } | |
7048 | netif_stop_queue(card->dev); | 7040 | netif_stop_queue(card->dev); |
7041 | card->options.large_send = type; | ||
7049 | switch (card->options.large_send) { | 7042 | switch (card->options.large_send) { |
7050 | case QETH_LARGE_SEND_EDDP: | 7043 | case QETH_LARGE_SEND_EDDP: |
7051 | card->dev->features |= NETIF_F_TSO | NETIF_F_SG; | 7044 | card->dev->features |= NETIF_F_TSO | NETIF_F_SG; |
@@ -7066,7 +7059,6 @@ qeth_set_large_send(struct qeth_card *card) | |||
7066 | card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG); | 7059 | card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG); |
7067 | break; | 7060 | break; |
7068 | } | 7061 | } |
7069 | |||
7070 | netif_wake_queue(card->dev); | 7062 | netif_wake_queue(card->dev); |
7071 | return rc; | 7063 | return rc; |
7072 | } | 7064 | } |
@@ -7730,7 +7722,7 @@ qeth_arp_constructor(struct neighbour *neigh) | |||
7730 | goto out; | 7722 | goto out; |
7731 | 7723 | ||
7732 | rcu_read_lock(); | 7724 | rcu_read_lock(); |
7733 | in_dev = rcu_dereference(__in_dev_get(dev)); | 7725 | in_dev = __in_dev_get_rcu(dev); |
7734 | if (in_dev == NULL) { | 7726 | if (in_dev == NULL) { |
7735 | rcu_read_unlock(); | 7727 | rcu_read_unlock(); |
7736 | return -EINVAL; | 7728 | return -EINVAL; |
@@ -8257,7 +8249,6 @@ qeth_init(void) | |||
8257 | { | 8249 | { |
8258 | int rc=0; | 8250 | int rc=0; |
8259 | 8251 | ||
8260 | qeth_eyecatcher(); | ||
8261 | PRINT_INFO("loading %s (%s/%s/%s/%s/%s/%s/%s %s %s)\n", | 8252 | PRINT_INFO("loading %s (%s/%s/%s/%s/%s/%s/%s %s %s)\n", |
8262 | version, VERSION_QETH_C, VERSION_QETH_H, | 8253 | version, VERSION_QETH_C, VERSION_QETH_H, |
8263 | VERSION_QETH_MPC_H, VERSION_QETH_MPC_C, | 8254 | VERSION_QETH_MPC_H, VERSION_QETH_MPC_C, |
@@ -8338,7 +8329,6 @@ again: | |||
8338 | printk("qeth: removed\n"); | 8329 | printk("qeth: removed\n"); |
8339 | } | 8330 | } |
8340 | 8331 | ||
8341 | EXPORT_SYMBOL(qeth_eyecatcher); | ||
8342 | module_init(qeth_init); | 8332 | module_init(qeth_init); |
8343 | module_exit(qeth_exit); | 8333 | module_exit(qeth_exit); |
8344 | MODULE_AUTHOR("Frank Pavlic <pavlic@de.ibm.com>"); | 8334 | MODULE_AUTHOR("Frank Pavlic <pavlic@de.ibm.com>"); |