diff options
Diffstat (limited to 'drivers/s390/net')
-rw-r--r-- | drivers/s390/net/ctcmain.c | 41 | ||||
-rw-r--r-- | drivers/s390/net/qeth.h | 4 | ||||
-rw-r--r-- | drivers/s390/net/qeth_main.c | 133 | ||||
-rw-r--r-- | drivers/s390/net/qeth_sys.c | 17 |
4 files changed, 95 insertions, 100 deletions
diff --git a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c index 96ca863eaff2..0db4f57a6a95 100644 --- a/drivers/s390/net/ctcmain.c +++ b/drivers/s390/net/ctcmain.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: ctcmain.c,v 1.74 2005/03/24 09:04:17 mschwide Exp $ | 2 | * $Id: ctcmain.c,v 1.78 2005/09/07 12:18:02 pavlic Exp $ |
3 | * | 3 | * |
4 | * CTC / ESCON network driver | 4 | * CTC / ESCON network driver |
5 | * | 5 | * |
@@ -37,10 +37,9 @@ | |||
37 | * along with this program; if not, write to the Free Software | 37 | * along with this program; if not, write to the Free Software |
38 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 38 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
39 | * | 39 | * |
40 | * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.74 $ | 40 | * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.78 $ |
41 | * | 41 | * |
42 | */ | 42 | */ |
43 | |||
44 | #undef DEBUG | 43 | #undef DEBUG |
45 | #include <linux/module.h> | 44 | #include <linux/module.h> |
46 | #include <linux/init.h> | 45 | #include <linux/init.h> |
@@ -135,7 +134,7 @@ static const char *dev_event_names[] = { | |||
135 | "TX down", | 134 | "TX down", |
136 | "Restart", | 135 | "Restart", |
137 | }; | 136 | }; |
138 | 137 | ||
139 | /** | 138 | /** |
140 | * Events of the channel statemachine | 139 | * Events of the channel statemachine |
141 | */ | 140 | */ |
@@ -249,7 +248,7 @@ static void | |||
249 | print_banner(void) | 248 | print_banner(void) |
250 | { | 249 | { |
251 | static int printed = 0; | 250 | static int printed = 0; |
252 | char vbuf[] = "$Revision: 1.74 $"; | 251 | char vbuf[] = "$Revision: 1.78 $"; |
253 | char *version = vbuf; | 252 | char *version = vbuf; |
254 | 253 | ||
255 | if (printed) | 254 | if (printed) |
@@ -334,7 +333,7 @@ static const char *ch_state_names[] = { | |||
334 | "Restarting", | 333 | "Restarting", |
335 | "Not operational", | 334 | "Not operational", |
336 | }; | 335 | }; |
337 | 336 | ||
338 | #ifdef DEBUG | 337 | #ifdef DEBUG |
339 | /** | 338 | /** |
340 | * Dump header and first 16 bytes of an sk_buff for debugging purposes. | 339 | * Dump header and first 16 bytes of an sk_buff for debugging purposes. |
@@ -671,7 +670,7 @@ static void | |||
671 | fsm_action_nop(fsm_instance * fi, int event, void *arg) | 670 | fsm_action_nop(fsm_instance * fi, int event, void *arg) |
672 | { | 671 | { |
673 | } | 672 | } |
674 | 673 | ||
675 | /** | 674 | /** |
676 | * Actions for channel - statemachines. | 675 | * Actions for channel - statemachines. |
677 | *****************************************************************************/ | 676 | *****************************************************************************/ |
@@ -1514,7 +1513,6 @@ ch_action_reinit(fsm_instance *fi, int event, void *arg) | |||
1514 | fsm_addtimer(&privptr->restart_timer, 1000, DEV_EVENT_RESTART, dev); | 1513 | fsm_addtimer(&privptr->restart_timer, 1000, DEV_EVENT_RESTART, dev); |
1515 | } | 1514 | } |
1516 | 1515 | ||
1517 | |||
1518 | /** | 1516 | /** |
1519 | * The statemachine for a channel. | 1517 | * The statemachine for a channel. |
1520 | */ | 1518 | */ |
@@ -1625,7 +1623,7 @@ static const fsm_node ch_fsm[] = { | |||
1625 | }; | 1623 | }; |
1626 | 1624 | ||
1627 | static const int CH_FSM_LEN = sizeof (ch_fsm) / sizeof (fsm_node); | 1625 | static const int CH_FSM_LEN = sizeof (ch_fsm) / sizeof (fsm_node); |
1628 | 1626 | ||
1629 | /** | 1627 | /** |
1630 | * Functions related to setup and device detection. | 1628 | * Functions related to setup and device detection. |
1631 | *****************************************************************************/ | 1629 | *****************************************************************************/ |
@@ -1976,7 +1974,7 @@ ctc_irq_handler(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) | |||
1976 | fsm_event(ch->fsm, CH_EVENT_IRQ, ch); | 1974 | fsm_event(ch->fsm, CH_EVENT_IRQ, ch); |
1977 | 1975 | ||
1978 | } | 1976 | } |
1979 | 1977 | ||
1980 | /** | 1978 | /** |
1981 | * Actions for interface - statemachine. | 1979 | * Actions for interface - statemachine. |
1982 | *****************************************************************************/ | 1980 | *****************************************************************************/ |
@@ -2209,13 +2207,18 @@ transmit_skb(struct channel *ch, struct sk_buff *skb) | |||
2209 | int rc = 0; | 2207 | int rc = 0; |
2210 | 2208 | ||
2211 | DBF_TEXT(trace, 5, __FUNCTION__); | 2209 | DBF_TEXT(trace, 5, __FUNCTION__); |
2210 | /* we need to acquire the lock for testing the state | ||
2211 | * otherwise we can have an IRQ changing the state to | ||
2212 | * TXIDLE after the test but before acquiring the lock. | ||
2213 | */ | ||
2214 | spin_lock_irqsave(&ch->collect_lock, saveflags); | ||
2212 | if (fsm_getstate(ch->fsm) != CH_STATE_TXIDLE) { | 2215 | if (fsm_getstate(ch->fsm) != CH_STATE_TXIDLE) { |
2213 | int l = skb->len + LL_HEADER_LENGTH; | 2216 | int l = skb->len + LL_HEADER_LENGTH; |
2214 | 2217 | ||
2215 | spin_lock_irqsave(&ch->collect_lock, saveflags); | 2218 | if (ch->collect_len + l > ch->max_bufsize - 2) { |
2216 | if (ch->collect_len + l > ch->max_bufsize - 2) | 2219 | spin_unlock_irqrestore(&ch->collect_lock, saveflags); |
2217 | rc = -EBUSY; | 2220 | return -EBUSY; |
2218 | else { | 2221 | } else { |
2219 | atomic_inc(&skb->users); | 2222 | atomic_inc(&skb->users); |
2220 | header.length = l; | 2223 | header.length = l; |
2221 | header.type = skb->protocol; | 2224 | header.type = skb->protocol; |
@@ -2231,7 +2234,7 @@ transmit_skb(struct channel *ch, struct sk_buff *skb) | |||
2231 | int ccw_idx; | 2234 | int ccw_idx; |
2232 | struct sk_buff *nskb; | 2235 | struct sk_buff *nskb; |
2233 | unsigned long hi; | 2236 | unsigned long hi; |
2234 | 2237 | spin_unlock_irqrestore(&ch->collect_lock, saveflags); | |
2235 | /** | 2238 | /** |
2236 | * Protect skb against beeing free'd by upper | 2239 | * Protect skb against beeing free'd by upper |
2237 | * layers. | 2240 | * layers. |
@@ -2256,6 +2259,7 @@ transmit_skb(struct channel *ch, struct sk_buff *skb) | |||
2256 | if (!nskb) { | 2259 | if (!nskb) { |
2257 | atomic_dec(&skb->users); | 2260 | atomic_dec(&skb->users); |
2258 | skb_pull(skb, LL_HEADER_LENGTH + 2); | 2261 | skb_pull(skb, LL_HEADER_LENGTH + 2); |
2262 | ctc_clear_busy(ch->netdev); | ||
2259 | return -ENOMEM; | 2263 | return -ENOMEM; |
2260 | } else { | 2264 | } else { |
2261 | memcpy(skb_put(nskb, skb->len), | 2265 | memcpy(skb_put(nskb, skb->len), |
@@ -2281,6 +2285,7 @@ transmit_skb(struct channel *ch, struct sk_buff *skb) | |||
2281 | */ | 2285 | */ |
2282 | atomic_dec(&skb->users); | 2286 | atomic_dec(&skb->users); |
2283 | skb_pull(skb, LL_HEADER_LENGTH + 2); | 2287 | skb_pull(skb, LL_HEADER_LENGTH + 2); |
2288 | ctc_clear_busy(ch->netdev); | ||
2284 | return -EBUSY; | 2289 | return -EBUSY; |
2285 | } | 2290 | } |
2286 | 2291 | ||
@@ -2327,9 +2332,10 @@ transmit_skb(struct channel *ch, struct sk_buff *skb) | |||
2327 | } | 2332 | } |
2328 | } | 2333 | } |
2329 | 2334 | ||
2335 | ctc_clear_busy(ch->netdev); | ||
2330 | return rc; | 2336 | return rc; |
2331 | } | 2337 | } |
2332 | 2338 | ||
2333 | /** | 2339 | /** |
2334 | * Interface API for upper network layers | 2340 | * Interface API for upper network layers |
2335 | *****************************************************************************/ | 2341 | *****************************************************************************/ |
@@ -2421,7 +2427,6 @@ ctc_tx(struct sk_buff *skb, struct net_device * dev) | |||
2421 | dev->trans_start = jiffies; | 2427 | dev->trans_start = jiffies; |
2422 | if (transmit_skb(privptr->channel[WRITE], skb) != 0) | 2428 | if (transmit_skb(privptr->channel[WRITE], skb) != 0) |
2423 | rc = 1; | 2429 | rc = 1; |
2424 | ctc_clear_busy(dev); | ||
2425 | return rc; | 2430 | return rc; |
2426 | } | 2431 | } |
2427 | 2432 | ||
@@ -2610,7 +2615,6 @@ stats_write(struct device *dev, struct device_attribute *attr, const char *buf, | |||
2610 | return count; | 2615 | return count; |
2611 | } | 2616 | } |
2612 | 2617 | ||
2613 | |||
2614 | static void | 2618 | static void |
2615 | ctc_netdev_unregister(struct net_device * dev) | 2619 | ctc_netdev_unregister(struct net_device * dev) |
2616 | { | 2620 | { |
@@ -2685,7 +2689,6 @@ ctc_proto_store(struct device *dev, struct device_attribute *attr, const char *b | |||
2685 | return count; | 2689 | return count; |
2686 | } | 2690 | } |
2687 | 2691 | ||
2688 | |||
2689 | static ssize_t | 2692 | static ssize_t |
2690 | ctc_type_show(struct device *dev, struct device_attribute *attr, char *buf) | 2693 | ctc_type_show(struct device *dev, struct device_attribute *attr, char *buf) |
2691 | { | 2694 | { |
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h index 3a0285669adf..2ad4797ce024 100644 --- a/drivers/s390/net/qeth.h +++ b/drivers/s390/net/qeth.h | |||
@@ -24,7 +24,7 @@ | |||
24 | 24 | ||
25 | #include "qeth_mpc.h" | 25 | #include "qeth_mpc.h" |
26 | 26 | ||
27 | #define VERSION_QETH_H "$Revision: 1.139 $" | 27 | #define VERSION_QETH_H "$Revision: 1.142 $" |
28 | 28 | ||
29 | #ifdef CONFIG_QETH_IPV6 | 29 | #ifdef CONFIG_QETH_IPV6 |
30 | #define QETH_VERSION_IPV6 ":IPv6" | 30 | #define QETH_VERSION_IPV6 ":IPv6" |
@@ -1172,7 +1172,7 @@ extern int | |||
1172 | qeth_realloc_buffer_pool(struct qeth_card *, int); | 1172 | qeth_realloc_buffer_pool(struct qeth_card *, int); |
1173 | 1173 | ||
1174 | extern int | 1174 | extern int |
1175 | qeth_set_large_send(struct qeth_card *); | 1175 | qeth_set_large_send(struct qeth_card *, enum qeth_large_send_types); |
1176 | 1176 | ||
1177 | extern void | 1177 | extern void |
1178 | qeth_fill_header(struct qeth_card *, struct qeth_hdr *, | 1178 | qeth_fill_header(struct qeth_card *, struct qeth_hdr *, |
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 79c74f3a11f5..86582cf1e19e 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 | /** |
@@ -2759,11 +2751,9 @@ qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int, | |||
2759 | queue->card->perf_stats.outbound_do_qdio_start_time; | 2751 | queue->card->perf_stats.outbound_do_qdio_start_time; |
2760 | #endif | 2752 | #endif |
2761 | if (rc){ | 2753 | 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"); | 2754 | QETH_DBF_TEXT(trace, 2, "flushbuf"); |
2766 | QETH_DBF_TEXT_(trace, 2, " err%d", rc); | 2755 | QETH_DBF_TEXT_(trace, 2, " err%d", rc); |
2756 | QETH_DBF_TEXT_(trace, 2, "%s", CARD_DDEV_ID(queue->card)); | ||
2767 | queue->card->stats.tx_errors += count; | 2757 | queue->card->stats.tx_errors += count; |
2768 | /* this must not happen under normal circumstances. if it | 2758 | /* this must not happen under normal circumstances. if it |
2769 | * happens something is really wrong -> recover */ | 2759 | * happens something is really wrong -> recover */ |
@@ -2909,11 +2899,8 @@ qeth_qdio_output_handler(struct ccw_device * ccwdev, unsigned int status, | |||
2909 | QETH_DBF_TEXT(trace, 6, "qdouhdl"); | 2899 | QETH_DBF_TEXT(trace, 6, "qdouhdl"); |
2910 | if (status & QDIO_STATUS_LOOK_FOR_ERROR) { | 2900 | if (status & QDIO_STATUS_LOOK_FOR_ERROR) { |
2911 | if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION){ | 2901 | if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION){ |
2912 | QETH_DBF_SPRINTF(trace, 2, "On device %s: " | 2902 | QETH_DBF_TEXT(trace, 2, "achkcond"); |
2913 | "received active check " | 2903 | 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); | 2904 | QETH_DBF_TEXT_(trace, 2, "%08x", status); |
2918 | netif_stop_queue(card->dev); | 2905 | netif_stop_queue(card->dev); |
2919 | qeth_schedule_recovery(card); | 2906 | qeth_schedule_recovery(card); |
@@ -3356,26 +3343,32 @@ qeth_halt_channel(struct qeth_channel *channel) | |||
3356 | static int | 3343 | static int |
3357 | qeth_halt_channels(struct qeth_card *card) | 3344 | qeth_halt_channels(struct qeth_card *card) |
3358 | { | 3345 | { |
3359 | int rc = 0; | 3346 | int rc1 = 0, rc2=0, rc3 = 0; |
3360 | 3347 | ||
3361 | QETH_DBF_TEXT(trace,3,"haltchs"); | 3348 | QETH_DBF_TEXT(trace,3,"haltchs"); |
3362 | if ((rc = qeth_halt_channel(&card->read))) | 3349 | rc1 = qeth_halt_channel(&card->read); |
3363 | return rc; | 3350 | rc2 = qeth_halt_channel(&card->write); |
3364 | if ((rc = qeth_halt_channel(&card->write))) | 3351 | rc3 = qeth_halt_channel(&card->data); |
3365 | return rc; | 3352 | if (rc1) |
3366 | return qeth_halt_channel(&card->data); | 3353 | return rc1; |
3354 | if (rc2) | ||
3355 | return rc2; | ||
3356 | return rc3; | ||
3367 | } | 3357 | } |
3368 | static int | 3358 | static int |
3369 | qeth_clear_channels(struct qeth_card *card) | 3359 | qeth_clear_channels(struct qeth_card *card) |
3370 | { | 3360 | { |
3371 | int rc = 0; | 3361 | int rc1 = 0, rc2=0, rc3 = 0; |
3372 | 3362 | ||
3373 | QETH_DBF_TEXT(trace,3,"clearchs"); | 3363 | QETH_DBF_TEXT(trace,3,"clearchs"); |
3374 | if ((rc = qeth_clear_channel(&card->read))) | 3364 | rc1 = qeth_clear_channel(&card->read); |
3375 | return rc; | 3365 | rc2 = qeth_clear_channel(&card->write); |
3376 | if ((rc = qeth_clear_channel(&card->write))) | 3366 | rc3 = qeth_clear_channel(&card->data); |
3377 | return rc; | 3367 | if (rc1) |
3378 | return qeth_clear_channel(&card->data); | 3368 | return rc1; |
3369 | if (rc2) | ||
3370 | return rc2; | ||
3371 | return rc3; | ||
3379 | } | 3372 | } |
3380 | 3373 | ||
3381 | static int | 3374 | static int |
@@ -3445,23 +3438,23 @@ qeth_mpc_initialize(struct qeth_card *card) | |||
3445 | } | 3438 | } |
3446 | if ((rc = qeth_cm_enable(card))){ | 3439 | if ((rc = qeth_cm_enable(card))){ |
3447 | QETH_DBF_TEXT_(setup, 2, "2err%d", rc); | 3440 | QETH_DBF_TEXT_(setup, 2, "2err%d", rc); |
3448 | return rc; | 3441 | goto out_qdio; |
3449 | } | 3442 | } |
3450 | if ((rc = qeth_cm_setup(card))){ | 3443 | if ((rc = qeth_cm_setup(card))){ |
3451 | QETH_DBF_TEXT_(setup, 2, "3err%d", rc); | 3444 | QETH_DBF_TEXT_(setup, 2, "3err%d", rc); |
3452 | return rc; | 3445 | goto out_qdio; |
3453 | } | 3446 | } |
3454 | if ((rc = qeth_ulp_enable(card))){ | 3447 | if ((rc = qeth_ulp_enable(card))){ |
3455 | QETH_DBF_TEXT_(setup, 2, "4err%d", rc); | 3448 | QETH_DBF_TEXT_(setup, 2, "4err%d", rc); |
3456 | return rc; | 3449 | goto out_qdio; |
3457 | } | 3450 | } |
3458 | if ((rc = qeth_ulp_setup(card))){ | 3451 | if ((rc = qeth_ulp_setup(card))){ |
3459 | QETH_DBF_TEXT_(setup, 2, "5err%d", rc); | 3452 | QETH_DBF_TEXT_(setup, 2, "5err%d", rc); |
3460 | return rc; | 3453 | goto out_qdio; |
3461 | } | 3454 | } |
3462 | if ((rc = qeth_alloc_qdio_buffers(card))){ | 3455 | if ((rc = qeth_alloc_qdio_buffers(card))){ |
3463 | QETH_DBF_TEXT_(setup, 2, "5err%d", rc); | 3456 | QETH_DBF_TEXT_(setup, 2, "5err%d", rc); |
3464 | return rc; | 3457 | goto out_qdio; |
3465 | } | 3458 | } |
3466 | if ((rc = qeth_qdio_establish(card))){ | 3459 | if ((rc = qeth_qdio_establish(card))){ |
3467 | QETH_DBF_TEXT_(setup, 2, "6err%d", rc); | 3460 | QETH_DBF_TEXT_(setup, 2, "6err%d", rc); |
@@ -3795,12 +3788,16 @@ static inline int | |||
3795 | qeth_prepare_skb(struct qeth_card *card, struct sk_buff **skb, | 3788 | qeth_prepare_skb(struct qeth_card *card, struct sk_buff **skb, |
3796 | struct qeth_hdr **hdr, int ipv) | 3789 | struct qeth_hdr **hdr, int ipv) |
3797 | { | 3790 | { |
3791 | int rc; | ||
3798 | #ifdef CONFIG_QETH_VLAN | 3792 | #ifdef CONFIG_QETH_VLAN |
3799 | u16 *tag; | 3793 | u16 *tag; |
3800 | #endif | 3794 | #endif |
3801 | 3795 | ||
3802 | QETH_DBF_TEXT(trace, 6, "prepskb"); | 3796 | QETH_DBF_TEXT(trace, 6, "prepskb"); |
3803 | 3797 | ||
3798 | rc = qeth_realloc_headroom(card, skb, sizeof(struct qeth_hdr)); | ||
3799 | if (rc) | ||
3800 | return rc; | ||
3804 | #ifdef CONFIG_QETH_VLAN | 3801 | #ifdef CONFIG_QETH_VLAN |
3805 | if (card->vlangrp && vlan_tx_tag_present(*skb) && | 3802 | if (card->vlangrp && vlan_tx_tag_present(*skb) && |
3806 | ((ipv == 6) || card->options.layer2) ) { | 3803 | ((ipv == 6) || card->options.layer2) ) { |
@@ -4251,7 +4248,8 @@ out: | |||
4251 | } | 4248 | } |
4252 | 4249 | ||
4253 | static inline int | 4250 | static inline int |
4254 | qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb) | 4251 | qeth_get_elements_no(struct qeth_card *card, void *hdr, |
4252 | struct sk_buff *skb, int elems) | ||
4255 | { | 4253 | { |
4256 | int elements_needed = 0; | 4254 | int elements_needed = 0; |
4257 | 4255 | ||
@@ -4261,9 +4259,10 @@ qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb) | |||
4261 | if (elements_needed == 0 ) | 4259 | if (elements_needed == 0 ) |
4262 | elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE) | 4260 | elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE) |
4263 | + skb->len) >> PAGE_SHIFT); | 4261 | + skb->len) >> PAGE_SHIFT); |
4264 | if (elements_needed > QETH_MAX_BUFFER_ELEMENTS(card)){ | 4262 | if ((elements_needed + elems) > QETH_MAX_BUFFER_ELEMENTS(card)){ |
4265 | PRINT_ERR("qeth_do_send_packet: invalid size of " | 4263 | PRINT_ERR("qeth_do_send_packet: invalid size of " |
4266 | "IP packet. Discarded."); | 4264 | "IP packet (Number=%d / Length=%d). Discarded.\n", |
4265 | (elements_needed+elems), skb->len); | ||
4267 | return 0; | 4266 | return 0; |
4268 | } | 4267 | } |
4269 | return elements_needed; | 4268 | return elements_needed; |
@@ -4275,7 +4274,7 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) | |||
4275 | int ipv = 0; | 4274 | int ipv = 0; |
4276 | int cast_type; | 4275 | int cast_type; |
4277 | struct qeth_qdio_out_q *queue; | 4276 | struct qeth_qdio_out_q *queue; |
4278 | struct qeth_hdr *hdr; | 4277 | struct qeth_hdr *hdr = NULL; |
4279 | int elements_needed = 0; | 4278 | int elements_needed = 0; |
4280 | enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO; | 4279 | enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO; |
4281 | struct qeth_eddp_context *ctx = NULL; | 4280 | struct qeth_eddp_context *ctx = NULL; |
@@ -4337,9 +4336,11 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) | |||
4337 | return -EINVAL; | 4336 | return -EINVAL; |
4338 | } | 4337 | } |
4339 | } else { | 4338 | } else { |
4340 | elements_needed += qeth_get_elements_no(card,(void*) hdr, skb); | 4339 | int elems = qeth_get_elements_no(card,(void*) hdr, skb, |
4341 | if (!elements_needed) | 4340 | elements_needed); |
4341 | if (!elems) | ||
4342 | return -EINVAL; | 4342 | return -EINVAL; |
4343 | elements_needed += elems; | ||
4343 | } | 4344 | } |
4344 | 4345 | ||
4345 | if (card->info.type != QETH_CARD_TYPE_IQD) | 4346 | if (card->info.type != QETH_CARD_TYPE_IQD) |
@@ -4504,7 +4505,11 @@ qeth_arp_set_no_entries(struct qeth_card *card, int no_entries) | |||
4504 | 4505 | ||
4505 | QETH_DBF_TEXT(trace,3,"arpstnoe"); | 4506 | QETH_DBF_TEXT(trace,3,"arpstnoe"); |
4506 | 4507 | ||
4507 | /* TODO: really not supported by GuestLAN? */ | 4508 | /* |
4509 | * currently GuestLAN only supports the ARP assist function | ||
4510 | * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_SET_NO_ENTRIES; | ||
4511 | * thus we say EOPNOTSUPP for this ARP function | ||
4512 | */ | ||
4508 | if (card->info.guestlan) | 4513 | if (card->info.guestlan) |
4509 | return -EOPNOTSUPP; | 4514 | return -EOPNOTSUPP; |
4510 | if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) { | 4515 | if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) { |
@@ -4681,14 +4686,6 @@ qeth_arp_query(struct qeth_card *card, char *udata) | |||
4681 | 4686 | ||
4682 | QETH_DBF_TEXT(trace,3,"arpquery"); | 4687 | QETH_DBF_TEXT(trace,3,"arpquery"); |
4683 | 4688 | ||
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*/ | 4689 | if (!qeth_is_supported(card,/*IPA_QUERY_ARP_ADDR_INFO*/ |
4693 | IPA_ARP_PROCESSING)) { | 4690 | IPA_ARP_PROCESSING)) { |
4694 | PRINT_WARN("ARP processing not supported " | 4691 | PRINT_WARN("ARP processing not supported " |
@@ -4894,10 +4891,9 @@ qeth_arp_add_entry(struct qeth_card *card, struct qeth_arp_cache_entry *entry) | |||
4894 | QETH_DBF_TEXT(trace,3,"arpadent"); | 4891 | QETH_DBF_TEXT(trace,3,"arpadent"); |
4895 | 4892 | ||
4896 | /* | 4893 | /* |
4897 | * currently GuestLAN does only deliver all zeros on query arp, | 4894 | * currently GuestLAN only supports the ARP assist function |
4898 | * even though arp processing is supported (according to IPA supp. | 4895 | * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_ADD_ENTRY; |
4899 | * funcs flags); since all zeros is no valueable information, | 4896 | * thus we say EOPNOTSUPP for this ARP function |
4900 | * we say EOPNOTSUPP for all ARP functions | ||
4901 | */ | 4897 | */ |
4902 | if (card->info.guestlan) | 4898 | if (card->info.guestlan) |
4903 | return -EOPNOTSUPP; | 4899 | return -EOPNOTSUPP; |
@@ -4937,10 +4933,9 @@ qeth_arp_remove_entry(struct qeth_card *card, struct qeth_arp_cache_entry *entry | |||
4937 | QETH_DBF_TEXT(trace,3,"arprment"); | 4933 | QETH_DBF_TEXT(trace,3,"arprment"); |
4938 | 4934 | ||
4939 | /* | 4935 | /* |
4940 | * currently GuestLAN does only deliver all zeros on query arp, | 4936 | * currently GuestLAN only supports the ARP assist function |
4941 | * even though arp processing is supported (according to IPA supp. | 4937 | * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_REMOVE_ENTRY; |
4942 | * funcs flags); since all zeros is no valueable information, | 4938 | * thus we say EOPNOTSUPP for this ARP function |
4943 | * we say EOPNOTSUPP for all ARP functions | ||
4944 | */ | 4939 | */ |
4945 | if (card->info.guestlan) | 4940 | if (card->info.guestlan) |
4946 | return -EOPNOTSUPP; | 4941 | return -EOPNOTSUPP; |
@@ -4978,11 +4973,10 @@ qeth_arp_flush_cache(struct qeth_card *card) | |||
4978 | QETH_DBF_TEXT(trace,3,"arpflush"); | 4973 | QETH_DBF_TEXT(trace,3,"arpflush"); |
4979 | 4974 | ||
4980 | /* | 4975 | /* |
4981 | * currently GuestLAN does only deliver all zeros on query arp, | 4976 | * currently GuestLAN only supports the ARP assist function |
4982 | * even though arp processing is supported (according to IPA supp. | 4977 | * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_FLUSH_CACHE; |
4983 | * funcs flags); since all zeros is no valueable information, | 4978 | * thus we say EOPNOTSUPP for this ARP function |
4984 | * we say EOPNOTSUPP for all ARP functions | 4979 | */ |
4985 | */ | ||
4986 | if (card->info.guestlan || (card->info.type == QETH_CARD_TYPE_IQD)) | 4980 | if (card->info.guestlan || (card->info.type == QETH_CARD_TYPE_IQD)) |
4987 | return -EOPNOTSUPP; | 4981 | return -EOPNOTSUPP; |
4988 | if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) { | 4982 | if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) { |
@@ -7038,14 +7032,16 @@ qeth_setrouting_v6(struct qeth_card *card) | |||
7038 | } | 7032 | } |
7039 | 7033 | ||
7040 | int | 7034 | int |
7041 | qeth_set_large_send(struct qeth_card *card) | 7035 | qeth_set_large_send(struct qeth_card *card, enum qeth_large_send_types type) |
7042 | { | 7036 | { |
7043 | int rc = 0; | 7037 | int rc = 0; |
7044 | 7038 | ||
7045 | if (card->dev == NULL) | 7039 | if (card->dev == NULL) { |
7040 | card->options.large_send = type; | ||
7046 | return 0; | 7041 | return 0; |
7047 | 7042 | } | |
7048 | netif_stop_queue(card->dev); | 7043 | netif_stop_queue(card->dev); |
7044 | card->options.large_send = type; | ||
7049 | switch (card->options.large_send) { | 7045 | switch (card->options.large_send) { |
7050 | case QETH_LARGE_SEND_EDDP: | 7046 | case QETH_LARGE_SEND_EDDP: |
7051 | card->dev->features |= NETIF_F_TSO | NETIF_F_SG; | 7047 | card->dev->features |= NETIF_F_TSO | NETIF_F_SG; |
@@ -7066,7 +7062,6 @@ qeth_set_large_send(struct qeth_card *card) | |||
7066 | card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG); | 7062 | card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG); |
7067 | break; | 7063 | break; |
7068 | } | 7064 | } |
7069 | |||
7070 | netif_wake_queue(card->dev); | 7065 | netif_wake_queue(card->dev); |
7071 | return rc; | 7066 | return rc; |
7072 | } | 7067 | } |
@@ -8257,7 +8252,6 @@ qeth_init(void) | |||
8257 | { | 8252 | { |
8258 | int rc=0; | 8253 | int rc=0; |
8259 | 8254 | ||
8260 | qeth_eyecatcher(); | ||
8261 | PRINT_INFO("loading %s (%s/%s/%s/%s/%s/%s/%s %s %s)\n", | 8255 | PRINT_INFO("loading %s (%s/%s/%s/%s/%s/%s/%s %s %s)\n", |
8262 | version, VERSION_QETH_C, VERSION_QETH_H, | 8256 | version, VERSION_QETH_C, VERSION_QETH_H, |
8263 | VERSION_QETH_MPC_H, VERSION_QETH_MPC_C, | 8257 | VERSION_QETH_MPC_H, VERSION_QETH_MPC_C, |
@@ -8338,7 +8332,6 @@ again: | |||
8338 | printk("qeth: removed\n"); | 8332 | printk("qeth: removed\n"); |
8339 | } | 8333 | } |
8340 | 8334 | ||
8341 | EXPORT_SYMBOL(qeth_eyecatcher); | ||
8342 | module_init(qeth_init); | 8335 | module_init(qeth_init); |
8343 | module_exit(qeth_exit); | 8336 | module_exit(qeth_exit); |
8344 | MODULE_AUTHOR("Frank Pavlic <pavlic@de.ibm.com>"); | 8337 | MODULE_AUTHOR("Frank Pavlic <pavlic@de.ibm.com>"); |
diff --git a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c index 98bedb0cb387..dda105b73063 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.51 $) | 3 | * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.54 $) |
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. |
@@ -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.51 $"; | 23 | const char *VERSION_QETH_SYS_C = "$Revision: 1.54 $"; |
24 | 24 | ||
25 | /*****************************************************************************/ | 25 | /*****************************************************************************/ |
26 | /* */ | 26 | /* */ |
@@ -722,10 +722,13 @@ qeth_dev_layer2_store(struct device *dev, struct device_attribute *attr, const c | |||
722 | 722 | ||
723 | if (!card) | 723 | if (!card) |
724 | return -EINVAL; | 724 | return -EINVAL; |
725 | if (card->info.type == QETH_CARD_TYPE_IQD) { | ||
726 | PRINT_WARN("Layer2 on Hipersockets is not supported! \n"); | ||
727 | return -EPERM; | ||
728 | } | ||
725 | 729 | ||
726 | if (((card->state != CARD_STATE_DOWN) && | 730 | if (((card->state != CARD_STATE_DOWN) && |
727 | (card->state != CARD_STATE_RECOVER)) || | 731 | (card->state != CARD_STATE_RECOVER))) |
728 | (card->info.type != QETH_CARD_TYPE_OSAE)) | ||
729 | return -EPERM; | 732 | return -EPERM; |
730 | 733 | ||
731 | i = simple_strtoul(buf, &tmp, 16); | 734 | i = simple_strtoul(buf, &tmp, 16); |
@@ -771,9 +774,7 @@ qeth_dev_large_send_store(struct device *dev, struct device_attribute *attr, con | |||
771 | 774 | ||
772 | if (!card) | 775 | if (!card) |
773 | return -EINVAL; | 776 | return -EINVAL; |
774 | |||
775 | tmp = strsep((char **) &buf, "\n"); | 777 | tmp = strsep((char **) &buf, "\n"); |
776 | |||
777 | if (!strcmp(tmp, "no")){ | 778 | if (!strcmp(tmp, "no")){ |
778 | type = QETH_LARGE_SEND_NO; | 779 | type = QETH_LARGE_SEND_NO; |
779 | } else if (!strcmp(tmp, "EDDP")) { | 780 | } else if (!strcmp(tmp, "EDDP")) { |
@@ -786,10 +787,8 @@ qeth_dev_large_send_store(struct device *dev, struct device_attribute *attr, con | |||
786 | } | 787 | } |
787 | if (card->options.large_send == type) | 788 | if (card->options.large_send == type) |
788 | return count; | 789 | return count; |
789 | card->options.large_send = type; | 790 | if ((rc = qeth_set_large_send(card, type))) |
790 | if ((rc = qeth_set_large_send(card))) | ||
791 | return rc; | 791 | return rc; |
792 | |||
793 | return count; | 792 | return count; |
794 | } | 793 | } |
795 | 794 | ||