[PATCH] s390: qeth driver fixes [1/6]
authorFrank Pavlic <fpavlic@de.ibm.com>
Fri, 15 Sep 2006 14:25:56 +0000 (16:25 +0200)
committerJeff Garzik <jeff@garzik.org>
Sun, 17 Sep 2006 05:03:07 +0000 (01:03 -0400)
[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>
drivers/s390/net/qeth_main.c

index e1327b8fce003c31600452ded9814a50e5aa8001..ffff7a12b54d29728886d37278de5630ec3730cf 100644 (file)
@@ -1708,6 +1708,7 @@ qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob)
                                           "IP address reset.\n",
                                           QETH_CARD_IFNAME(card),
                                           card->info.chpid);
+                               netif_carrier_on(card->dev);
                                qeth_schedule_recovery(card);
                                return NULL;
                        case IPA_CMD_MODCCID:
@@ -2464,24 +2465,6 @@ qeth_rebuild_skb_fake_ll(struct qeth_card *card, struct sk_buff *skb,
                qeth_rebuild_skb_fake_ll_eth(card, skb, hdr);
 }
 
-static inline void
-qeth_rebuild_skb_vlan(struct qeth_card *card, struct sk_buff *skb,
-                     struct qeth_hdr *hdr)
-{
-#ifdef CONFIG_QETH_VLAN
-       u16 *vlan_tag;
-
-       if (hdr->hdr.l3.ext_flags &
-           (QETH_HDR_EXT_VLAN_FRAME | QETH_HDR_EXT_INCLUDE_VLAN_TAG)) {
-               vlan_tag = (u16 *) skb_push(skb, VLAN_HLEN);
-               *vlan_tag = (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_VLAN_FRAME)?
-                       hdr->hdr.l3.vlan_id : *((u16 *)&hdr->hdr.l3.dest_addr[12]);
-               *(vlan_tag + 1) = skb->protocol;
-               skb->protocol = __constant_htons(ETH_P_8021Q);
-       }
-#endif /* CONFIG_QETH_VLAN */
-}
-
 static inline __u16
 qeth_layer2_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
                        struct qeth_hdr *hdr)
@@ -2510,15 +2493,16 @@ qeth_layer2_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
        return vlan_id;
 }
 
-static inline void
+static inline __u16
 qeth_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
                 struct qeth_hdr *hdr)
 {
+       unsigned short vlan_id = 0;
 #ifdef CONFIG_QETH_IPV6
        if (hdr->hdr.l3.flags & QETH_HDR_PASSTHRU) {
                skb->pkt_type = PACKET_HOST;
                skb->protocol = qeth_type_trans(skb, card->dev);
-               return;
+               return 0;
        }
 #endif /* CONFIG_QETH_IPV6 */
        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,
        default:
                skb->pkt_type = PACKET_HOST;
        }
-       qeth_rebuild_skb_vlan(card, skb, hdr);
+
+       if (hdr->hdr.l3.ext_flags &
+           (QETH_HDR_EXT_VLAN_FRAME | QETH_HDR_EXT_INCLUDE_VLAN_TAG)) {
+               vlan_id = (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_VLAN_FRAME)?
+                       hdr->hdr.l3.vlan_id : *((u16 *)&hdr->hdr.l3.dest_addr[12]);
+       }
+
        if (card->options.fake_ll)
                qeth_rebuild_skb_fake_ll(card, skb, hdr);
        else
@@ -2556,6 +2546,7 @@ qeth_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
                else
                        skb->ip_summed = SW_CHECKSUMMING;
        }
+       return vlan_id;
 }
 
 static inline void
@@ -2568,6 +2559,7 @@ qeth_process_inbound_buffer(struct qeth_card *card,
        int offset;
        int rxrc;
        __u16 vlan_tag = 0;
+       __u16 *vlan_addr;
 
        /* get first element of current buffer */
        element = (struct qdio_buffer_element *)&buf->buffer->element[0];
@@ -2581,7 +2573,7 @@ qeth_process_inbound_buffer(struct qeth_card *card,
                if (hdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2)
                        vlan_tag = qeth_layer2_rebuild_skb(card, skb, hdr);
                else if (hdr->hdr.l3.id == QETH_HEADER_TYPE_LAYER3)
-                       qeth_rebuild_skb(card, skb, hdr);
+                       vlan_tag = qeth_rebuild_skb(card, skb, hdr);
                else { /*in case of OSN*/
                        skb_push(skb, sizeof(struct qeth_hdr));
                        memcpy(skb->data, hdr, sizeof(struct qeth_hdr));
@@ -2591,14 +2583,19 @@ qeth_process_inbound_buffer(struct qeth_card *card,
                        dev_kfree_skb_any(skb);
                        continue;
                }
+               if (card->info.type == QETH_CARD_TYPE_OSN)
+                       rxrc = card->osn_info.data_cb(skb);
+               else
 #ifdef CONFIG_QETH_VLAN
                if (vlan_tag)
-                       vlan_hwaccel_rx(skb, card->vlangrp, vlan_tag);
+                       if (card->vlangrp)
+                               vlan_hwaccel_rx(skb, card->vlangrp, vlan_tag);
+                       else {
+                               dev_kfree_skb_any(skb);
+                               continue;
+                       }
                else
 #endif
-               if (card->info.type == QETH_CARD_TYPE_OSN)
-                       rxrc = card->osn_info.data_cb(skb);
-               else
                        rxrc = netif_rx(skb);
                card->dev->last_rx = jiffies;
                card->stats.rx_packets++;