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);