diff options
author | Frank Pavlic <fpavlic@de.ibm.com> | 2006-09-15 10:25:56 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-09-17 01:03:07 -0400 |
commit | 330b636908b44e73c714fb2632602ddd96f72c01 (patch) | |
tree | 684d601d2ed50ed91f1057b2eea2d5cd485b2ebd | |
parent | f449c565ea324397f83adb65e9d0b599cfbc7dab (diff) |
[PATCH] s390: qeth driver fixes [1/6]
[PATCH 4/9] s390: qeth driver fixes [1/6]
From: Frank Pavlic <fpavlic@de.ibm.com>
- Drop incoming packets with vlan_tag set
if card->vlangrp is not set.
- use always vlan_hwaccel_rx to pass
vlan frames to the stack.
- fix recovery problem. Device was recovered
properly but still not working.
netif_carrier_on call right before
recovery start fixes it.
Signed-off-by: Frank Pavlic <fpavlic@de.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r-- | drivers/s390/net/qeth_main.c | 49 |
1 files changed, 23 insertions, 26 deletions
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index e1327b8fce00..ffff7a12b54d 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c | |||
@@ -1708,6 +1708,7 @@ qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob) | |||
1708 | "IP address reset.\n", | 1708 | "IP address reset.\n", |
1709 | QETH_CARD_IFNAME(card), | 1709 | QETH_CARD_IFNAME(card), |
1710 | card->info.chpid); | 1710 | card->info.chpid); |
1711 | netif_carrier_on(card->dev); | ||
1711 | qeth_schedule_recovery(card); | 1712 | qeth_schedule_recovery(card); |
1712 | return NULL; | 1713 | return NULL; |
1713 | case IPA_CMD_MODCCID: | 1714 | case IPA_CMD_MODCCID: |
@@ -2464,24 +2465,6 @@ qeth_rebuild_skb_fake_ll(struct qeth_card *card, struct sk_buff *skb, | |||
2464 | qeth_rebuild_skb_fake_ll_eth(card, skb, hdr); | 2465 | qeth_rebuild_skb_fake_ll_eth(card, skb, hdr); |
2465 | } | 2466 | } |
2466 | 2467 | ||
2467 | static inline void | ||
2468 | qeth_rebuild_skb_vlan(struct qeth_card *card, struct sk_buff *skb, | ||
2469 | struct qeth_hdr *hdr) | ||
2470 | { | ||
2471 | #ifdef CONFIG_QETH_VLAN | ||
2472 | u16 *vlan_tag; | ||
2473 | |||
2474 | if (hdr->hdr.l3.ext_flags & | ||
2475 | (QETH_HDR_EXT_VLAN_FRAME | QETH_HDR_EXT_INCLUDE_VLAN_TAG)) { | ||
2476 | vlan_tag = (u16 *) skb_push(skb, VLAN_HLEN); | ||
2477 | *vlan_tag = (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_VLAN_FRAME)? | ||
2478 | hdr->hdr.l3.vlan_id : *((u16 *)&hdr->hdr.l3.dest_addr[12]); | ||
2479 | *(vlan_tag + 1) = skb->protocol; | ||
2480 | skb->protocol = __constant_htons(ETH_P_8021Q); | ||
2481 | } | ||
2482 | #endif /* CONFIG_QETH_VLAN */ | ||
2483 | } | ||
2484 | |||
2485 | static inline __u16 | 2468 | static inline __u16 |
2486 | qeth_layer2_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, | 2469 | qeth_layer2_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, |
2487 | struct qeth_hdr *hdr) | 2470 | struct qeth_hdr *hdr) |
@@ -2510,15 +2493,16 @@ qeth_layer2_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, | |||
2510 | return vlan_id; | 2493 | return vlan_id; |
2511 | } | 2494 | } |
2512 | 2495 | ||
2513 | static inline void | 2496 | static inline __u16 |
2514 | qeth_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, | 2497 | qeth_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, |
2515 | struct qeth_hdr *hdr) | 2498 | struct qeth_hdr *hdr) |
2516 | { | 2499 | { |
2500 | unsigned short vlan_id = 0; | ||
2517 | #ifdef CONFIG_QETH_IPV6 | 2501 | #ifdef CONFIG_QETH_IPV6 |
2518 | if (hdr->hdr.l3.flags & QETH_HDR_PASSTHRU) { | 2502 | if (hdr->hdr.l3.flags & QETH_HDR_PASSTHRU) { |
2519 | skb->pkt_type = PACKET_HOST; | 2503 | skb->pkt_type = PACKET_HOST; |
2520 | skb->protocol = qeth_type_trans(skb, card->dev); | 2504 | skb->protocol = qeth_type_trans(skb, card->dev); |
2521 | return; | 2505 | return 0; |
2522 | } | 2506 | } |
2523 | #endif /* CONFIG_QETH_IPV6 */ | 2507 | #endif /* CONFIG_QETH_IPV6 */ |
2524 | skb->protocol = htons((hdr->hdr.l3.flags & QETH_HDR_IPV6)? ETH_P_IPV6 : | 2508 | skb->protocol = htons((hdr->hdr.l3.flags & QETH_HDR_IPV6)? ETH_P_IPV6 : |
@@ -2540,7 +2524,13 @@ qeth_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, | |||
2540 | default: | 2524 | default: |
2541 | skb->pkt_type = PACKET_HOST; | 2525 | skb->pkt_type = PACKET_HOST; |
2542 | } | 2526 | } |
2543 | qeth_rebuild_skb_vlan(card, skb, hdr); | 2527 | |
2528 | if (hdr->hdr.l3.ext_flags & | ||
2529 | (QETH_HDR_EXT_VLAN_FRAME | QETH_HDR_EXT_INCLUDE_VLAN_TAG)) { | ||
2530 | vlan_id = (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_VLAN_FRAME)? | ||
2531 | hdr->hdr.l3.vlan_id : *((u16 *)&hdr->hdr.l3.dest_addr[12]); | ||
2532 | } | ||
2533 | |||
2544 | if (card->options.fake_ll) | 2534 | if (card->options.fake_ll) |
2545 | qeth_rebuild_skb_fake_ll(card, skb, hdr); | 2535 | qeth_rebuild_skb_fake_ll(card, skb, hdr); |
2546 | else | 2536 | else |
@@ -2556,6 +2546,7 @@ qeth_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, | |||
2556 | else | 2546 | else |
2557 | skb->ip_summed = SW_CHECKSUMMING; | 2547 | skb->ip_summed = SW_CHECKSUMMING; |
2558 | } | 2548 | } |
2549 | return vlan_id; | ||
2559 | } | 2550 | } |
2560 | 2551 | ||
2561 | static inline void | 2552 | static inline void |
@@ -2568,6 +2559,7 @@ qeth_process_inbound_buffer(struct qeth_card *card, | |||
2568 | int offset; | 2559 | int offset; |
2569 | int rxrc; | 2560 | int rxrc; |
2570 | __u16 vlan_tag = 0; | 2561 | __u16 vlan_tag = 0; |
2562 | __u16 *vlan_addr; | ||
2571 | 2563 | ||
2572 | /* get first element of current buffer */ | 2564 | /* get first element of current buffer */ |
2573 | element = (struct qdio_buffer_element *)&buf->buffer->element[0]; | 2565 | element = (struct qdio_buffer_element *)&buf->buffer->element[0]; |
@@ -2581,7 +2573,7 @@ qeth_process_inbound_buffer(struct qeth_card *card, | |||
2581 | if (hdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2) | 2573 | if (hdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2) |
2582 | vlan_tag = qeth_layer2_rebuild_skb(card, skb, hdr); | 2574 | vlan_tag = qeth_layer2_rebuild_skb(card, skb, hdr); |
2583 | else if (hdr->hdr.l3.id == QETH_HEADER_TYPE_LAYER3) | 2575 | else if (hdr->hdr.l3.id == QETH_HEADER_TYPE_LAYER3) |
2584 | qeth_rebuild_skb(card, skb, hdr); | 2576 | vlan_tag = qeth_rebuild_skb(card, skb, hdr); |
2585 | else { /*in case of OSN*/ | 2577 | else { /*in case of OSN*/ |
2586 | skb_push(skb, sizeof(struct qeth_hdr)); | 2578 | skb_push(skb, sizeof(struct qeth_hdr)); |
2587 | memcpy(skb->data, hdr, sizeof(struct qeth_hdr)); | 2579 | memcpy(skb->data, hdr, sizeof(struct qeth_hdr)); |
@@ -2591,14 +2583,19 @@ qeth_process_inbound_buffer(struct qeth_card *card, | |||
2591 | dev_kfree_skb_any(skb); | 2583 | dev_kfree_skb_any(skb); |
2592 | continue; | 2584 | continue; |
2593 | } | 2585 | } |
2586 | if (card->info.type == QETH_CARD_TYPE_OSN) | ||
2587 | rxrc = card->osn_info.data_cb(skb); | ||
2588 | else | ||
2594 | #ifdef CONFIG_QETH_VLAN | 2589 | #ifdef CONFIG_QETH_VLAN |
2595 | if (vlan_tag) | 2590 | if (vlan_tag) |
2596 | vlan_hwaccel_rx(skb, card->vlangrp, vlan_tag); | 2591 | if (card->vlangrp) |
2592 | vlan_hwaccel_rx(skb, card->vlangrp, vlan_tag); | ||
2593 | else { | ||
2594 | dev_kfree_skb_any(skb); | ||
2595 | continue; | ||
2596 | } | ||
2597 | else | 2597 | else |
2598 | #endif | 2598 | #endif |
2599 | if (card->info.type == QETH_CARD_TYPE_OSN) | ||
2600 | rxrc = card->osn_info.data_cb(skb); | ||
2601 | else | ||
2602 | rxrc = netif_rx(skb); | 2599 | rxrc = netif_rx(skb); |
2603 | card->dev->last_rx = jiffies; | 2600 | card->dev->last_rx = jiffies; |
2604 | card->stats.rx_packets++; | 2601 | card->stats.rx_packets++; |