Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 3194

kernel-2.6.18-194.11.1.el5.src.rpm

From: Hans-Joachim Picht <hpicht@redhat.com>
Date: Thu, 12 Mar 2009 15:22:19 +0100
Subject: [s390] qeth: ipv6 support for hiper socket layer 3
Message-id: 20090312142219.GC5103@redhat.com
O-Subject: [RHEL5 U4 PATCH 2/20] FEAT: s390 - qeth: ipv6 support for hiper socket layer 3
Bugzilla: 475572
RH-Acked-by: Pete Zaitcev <zaitcev@redhat.com>

Description
============

This patch provides IPv6 support for hiper socket devices running
in layer 3 mode.

Bugzilla
=========

BZ 475572
https://bugzilla.redhat.com/show_bug.cgi?id=475572

Upstream status of the patch:
=============================

The patch was introducted upstream as port of the qeth driver
rewrite in git commit 71df50047f0db65ea09b1be155852e81a45eba

Test status:
============

The patch has been tested by the IBM test department.

Please ACK.

With best regards,

	--Hans

diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 1cc3d37..23182d6 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -4043,7 +4043,8 @@ __qeth_prepare_skb(struct qeth_card *card, struct sk_buff *skb, int ipv)
 #ifdef CONFIG_QETH_VLAN
 	u16 *tag;
 	if (card->vlangrp && vlan_tx_tag_present(skb) &&
-	    ((ipv == 6) || card->options.layer2) ) {
+	    (((ipv == 6) && (card->info.type != QETH_CARD_TYPE_IQD)) ||
+		card->options.layer2)) {
 		/*
 		 * Move the mac addresses (6 bytes src, 6 bytes dest)
 		 * to the beginning of the new header.  We are using three
@@ -4199,9 +4200,10 @@ qeth_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
 	 * v6 uses passthrough, v4 sets the tag in the QDIO header.
 	 */
 	if (card->vlangrp && vlan_tx_tag_present(skb)) {
-		hdr->hdr.l3.ext_flags = (ipv == 4) ?
-			QETH_HDR_EXT_VLAN_FRAME :
-			QETH_HDR_EXT_INCLUDE_VLAN_TAG;
+		if ((ipv == 4) || (card->info.type == QETH_CARD_TYPE_IQD))
+			hdr->hdr.l3.ext_flags = QETH_HDR_EXT_VLAN_FRAME;
+		else
+			hdr->hdr.l3.ext_flags = QETH_HDR_EXT_INCLUDE_VLAN_TAG;
 		hdr->hdr.l3.vlan_id = vlan_tx_tag_get(skb);
 	}
 #endif /* CONFIG_QETH_VLAN */
@@ -4218,6 +4220,8 @@ qeth_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
 		}
 	} else if (ipv == 6) { /* IPv6 or passthru */
 		hdr->hdr.l3.flags = qeth_get_qeth_hdr_flags6(cast_type);
+		if (card->info.type == QETH_CARD_TYPE_IQD)
+			hdr->hdr.l3.flags &= ~QETH_HDR_PASSTHRU;
 		if ((skb->dst) && (skb->dst->neighbour)) {
 			memcpy(hdr->hdr.l3.dest_addr,
 			       skb->dst->neighbour->primary_key, 16);
@@ -7012,9 +7016,6 @@ qeth_query_ipassists_cb(struct qeth_card *card, struct qeth_reply *reply,
 	if (cmd->hdr.prot_version == QETH_PROT_IPV4) {
 		card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported;
 		card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled;
-		/* Disable IPV6 support hard coded for Hipersockets */
-		if(card->info.type == QETH_CARD_TYPE_IQD)
-			card->options.ipa4.supported_funcs &= ~IPA_IPV6;
 	} else {
 #ifdef CONFIG_QETH_IPV6
 		card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported;
@@ -7259,6 +7260,9 @@ qeth_softsetup_ipv6(struct qeth_card *card)
 
 	QETH_DBF_TEXT(trace,3,"softipv6");
 
+	if (card->info.type == QETH_CARD_TYPE_IQD)
+		goto out;
+
 	rc = qeth_query_ipassists(card,QETH_PROT_IPV6);
 	if (rc) {
 		PRINT_ERR("IPv6 query ipassist failed on %s\n",
@@ -7289,6 +7293,7 @@ qeth_softsetup_ipv6(struct qeth_card *card)
 			   QETH_CARD_IFNAME(card), rc);
 		return rc;
 	}
+out:
 	PRINT_INFO("IPV6 enabled \n");
 	return 0;
 }
@@ -7694,6 +7699,10 @@ qeth_put_unique_id(struct qeth_card *card)
 	if ((card->info.unique_id & UNIQUE_ID_NOT_BY_CARD) ==
 	    	UNIQUE_ID_NOT_BY_CARD)
 		return -1;
+
+	if (card->info.type == QETH_CARD_TYPE_IQD)
+		return 0;
+
 	iob = qeth_get_ipacmd_buffer(card, IPA_CMD_DESTROY_ADDR,
 				     QETH_PROT_IPV6);
 	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
@@ -7852,6 +7861,13 @@ qeth_get_unique_id(struct qeth_card *card)
 		return 0;
 	}
 
+	if (card->info.type == QETH_CARD_TYPE_IQD) {
+		__u16 uid;
+		get_random_bytes(&uid, 2);
+		card->info.unique_id = uid;
+		return 0;
+	}
+
 	iob = qeth_get_ipacmd_buffer(card, IPA_CMD_CREATE_ADDR,
 				     QETH_PROT_IPV6);
 	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);