Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 89877e42827f16fa5f86b1df0c2860b1 > files > 1962

kernel-2.6.18-128.1.10.el5.src.rpm

From: Hans-Joachim Picht <hpicht@redhat.com>
Date: Wed, 9 Jan 2008 17:23:29 +0100
Subject: [s390] HiperSockets MAC layer routing support
Message-id: 20080109162329.GB27770@redhat.com
O-Subject: [RHEL5 U2 PATCH 2/4 ] HiperSockets MAC layer routing support
Bugzilla: 319001

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

qeth: System z HiperSockets layer-2 support.
The existing OSA layer-2 support is utilized to enable
HiperSockets layer-2, including IPv6 support for
HiperSockets layer-2.

Bugzilla
=========

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

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

The code will be submitted upstream soon.

Test status:
============
Kernel with patch was built and successfully tested

Please ACK.

With best regards,

Hans

diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h
index 451e2bb..315b6b3 100644
--- a/drivers/s390/net/qeth.h
+++ b/drivers/s390/net/qeth.h
@@ -834,6 +834,10 @@ struct qeth_card {
 	int use_hard_stop;
 	int (*orig_hard_header)(struct sk_buff *,struct net_device *,
 				unsigned short,void *,void *,unsigned);
+	int (*orig_rebuild_header)(struct sk_buff *);
+	int (*orig_hard_header_cache)(struct neighbour *,struct hh_cache *);
+	void (*orig_header_cache_update)(struct hh_cache *,struct net_device *,
+				unsigned char *);
 	struct qeth_osn_info osn_info;
 	atomic_t force_alloc_skb;
 };
@@ -943,7 +947,8 @@ static inline unsigned short
 qeth_get_netdev_flags(struct qeth_card *card)
 {
 	if (card->options.layer2 &&
-	   (card->info.type == QETH_CARD_TYPE_OSAE))
+	   ((card->info.type == QETH_CARD_TYPE_OSAE) ||
+		(card->info.type == QETH_CARD_TYPE_IQD)))
 		return 0;
 	switch (card->info.type) {
 	case QETH_CARD_TYPE_IQD:
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 51f9fd9..e83941b 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -6538,6 +6538,58 @@ qeth_init_func_level(struct qeth_card *card)
 	}
 }
 
+/* Layer 2 specific stuff */
+#define IGNORE_PARAM_EQ(option,value,reset_value,msg) \
+        if (card->options.option == value) { \
+                PRINT_ERR("%s not supported with layer 2 " \
+                          "functionality, ignoring option on read" \
+			  "channel device %s .\n",msg,CARD_RDEV_ID(card)); \
+                card->options.option = reset_value; \
+        }
+#define IGNORE_PARAM_NEQ(option,value,reset_value,msg) \
+        if (card->options.option != value) { \
+                PRINT_ERR("%s not supported with layer 2 " \
+                          "functionality, ignoring option on read" \
+			  "channel device %s .\n",msg,CARD_RDEV_ID(card)); \
+                card->options.option = reset_value; \
+        }
+
+static void qeth_make_parameters_consistent(struct qeth_card *card)
+{
+
+	if (card->options.layer2 == 0)
+		return;
+	if (card->info.type == QETH_CARD_TYPE_OSN)
+		return;
+	if ((card->info.type == QETH_CARD_TYPE_IQD) &&
+		(card->info.guestlan)) {
+       		PRINT_ERR("Device %s does not support layer 2 functionality." \
+	               	  " Ignoring layer2 option.\n",CARD_BUS_ID(card));
+       		card->options.layer2 = 0;
+		return;
+	}
+       	IGNORE_PARAM_NEQ(route4.type, NO_ROUTER, NO_ROUTER,
+               	         "Routing options are");
+#ifdef CONFIG_QETH_IPV6
+       	IGNORE_PARAM_NEQ(route6.type, NO_ROUTER, NO_ROUTER,
+               	         "Routing options are");
+#endif
+       	IGNORE_PARAM_EQ(checksum_type, HW_CHECKSUMMING,
+                       	QETH_CHECKSUM_DEFAULT,
+               	        "Checksumming options are");
+       	IGNORE_PARAM_NEQ(broadcast_mode, QETH_TR_BROADCAST_ALLRINGS,
+                       	 QETH_TR_BROADCAST_ALLRINGS,
+               	         "Broadcast mode options are");
+       	IGNORE_PARAM_NEQ(macaddr_mode, QETH_TR_MACADDR_NONCANONICAL,
+                       	 QETH_TR_MACADDR_NONCANONICAL,
+               	         "Canonical MAC addr options are");
+       	IGNORE_PARAM_NEQ(fake_broadcast, 0, 0,
+			 "Broadcast faking options are");
+       	IGNORE_PARAM_NEQ(add_hhlen, DEFAULT_ADD_HHLEN,
+       	                 DEFAULT_ADD_HHLEN,"Option add_hhlen is");
+        IGNORE_PARAM_NEQ(fake_ll, 0, 0,"Option fake_ll is");
+}
+
 /**
  * hardsetup card, initialize MPC and QDIO stuff
  */
@@ -6575,6 +6627,7 @@ retry:
 		QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
 		return rc;
 	}
+	qeth_make_parameters_consistent(card);
 	qeth_init_tokens(card);
 	qeth_init_func_level(card);
 	rc = qeth_idx_activate_channel(&card->read, qeth_idx_read_cb);
@@ -6605,7 +6658,26 @@ retry:
 	}
 	/*network device will be recovered*/
 	if (card->dev) {
+	if (!card->options.layer2 &&
+	     card->info.type == QETH_CARD_TYPE_IQD) {
+		memset(card->dev->dev_addr,
+		       0x00,
+		       OSA_ADDR_LEN);
+		card->info.mac_bits &= ~QETH_LAYER2_MAC_READ;
+	}
 		card->dev->hard_header = card->orig_hard_header;
+	if (qeth_get_netdev_flags(card) & IFF_NOARP) {
+		card->dev->flags |= IFF_NOARP;
+		card->dev->rebuild_header = NULL;
+		card->dev->hard_header = NULL;
+		card->dev->header_cache_update = NULL;
+		card->dev->hard_header_cache = NULL;
+	} else {
+		card->dev->flags &= ~IFF_NOARP;
+		card->dev->rebuild_header = card->orig_rebuild_header;
+		card->dev->header_cache_update = card->orig_header_cache_update;
+		card->dev->hard_header_cache = card->orig_hard_header_cache;
+	}
 		if (card->options.fake_ll &&
 		    (qeth_get_netdev_flags(card) & IFF_NOARP))
 			card->dev->hard_header = qeth_fake_header;
@@ -6623,6 +6695,9 @@ retry:
 	}
 	card->dev->priv = card;
 	card->orig_hard_header = card->dev->hard_header;
+	card->orig_rebuild_header = card->dev->rebuild_header;
+	card->orig_header_cache_update = card->dev->header_cache_update;
+	card->orig_hard_header_cache = card->dev->hard_header_cache;
 	card->dev->type = qeth_get_arphdr_type(card->info.type,
 					       card->info.link_type);
 	card->dev->init = qeth_netdev_init;
@@ -6900,6 +6975,8 @@ qeth_send_stoplan(struct qeth_card *card)
 	 */
 	QETH_DBF_TEXT(trace, 2, "stoplan");
 
+	if (card->info.type == QETH_CARD_TYPE_IQD)
+		return 0;
 	rc = qeth_send_startstoplan(card, IPA_CMD_STOPLAN, QETH_PROT_IPV4);
 	return rc;
 }
@@ -7895,57 +7972,6 @@ qeth_start_again(struct qeth_card *card, int recovery_mode)
 }
 
 
-/* Layer 2 specific stuff */
-#define IGNORE_PARAM_EQ(option,value,reset_value,msg) \
-        if (card->options.option == value) { \
-                PRINT_ERR("%s not supported with layer 2 " \
-                          "functionality, ignoring option on read" \
-			  "channel device %s .\n",msg,CARD_RDEV_ID(card)); \
-                card->options.option = reset_value; \
-        }
-#define IGNORE_PARAM_NEQ(option,value,reset_value,msg) \
-        if (card->options.option != value) { \
-                PRINT_ERR("%s not supported with layer 2 " \
-                          "functionality, ignoring option on read" \
-			  "channel device %s .\n",msg,CARD_RDEV_ID(card)); \
-                card->options.option = reset_value; \
-        }
-
-
-static void qeth_make_parameters_consistent(struct qeth_card *card)
-{
-
-	if (card->options.layer2 == 0)
-		return;
-	if (card->info.type == QETH_CARD_TYPE_OSN)
-		return;
-	if (card->info.type == QETH_CARD_TYPE_IQD) {
-       		PRINT_ERR("Device %s does not support layer 2 functionality." \
-	               	  " Ignoring layer2 option.\n",CARD_BUS_ID(card));
-       		card->options.layer2 = 0;
-		return;
-	}
-       	IGNORE_PARAM_NEQ(route4.type, NO_ROUTER, NO_ROUTER,
-               	         "Routing options are");
-#ifdef CONFIG_QETH_IPV6
-       	IGNORE_PARAM_NEQ(route6.type, NO_ROUTER, NO_ROUTER,
-               	         "Routing options are");
-#endif
-       	IGNORE_PARAM_EQ(checksum_type, HW_CHECKSUMMING,
-                       	QETH_CHECKSUM_DEFAULT,
-               	        "Checksumming options are");
-       	IGNORE_PARAM_NEQ(broadcast_mode, QETH_TR_BROADCAST_ALLRINGS,
-                       	 QETH_TR_BROADCAST_ALLRINGS,
-               	         "Broadcast mode options are");
-       	IGNORE_PARAM_NEQ(macaddr_mode, QETH_TR_MACADDR_NONCANONICAL,
-                       	 QETH_TR_MACADDR_NONCANONICAL,
-               	         "Canonical MAC addr options are");
-       	IGNORE_PARAM_NEQ(fake_broadcast, 0, 0,
-			 "Broadcast faking options are");
-       	IGNORE_PARAM_NEQ(add_hhlen, DEFAULT_ADD_HHLEN,
-       	                 DEFAULT_ADD_HHLEN,"Option add_hhlen is");
-        IGNORE_PARAM_NEQ(fake_ll, 0, 0,"Option fake_ll is");
-}
 
 
 static int
@@ -7974,8 +8000,6 @@ __qeth_set_online(struct ccwgroup_device *gdev, int recovery_mode)
 		return -EIO;
 	}
 
-	qeth_make_parameters_consistent(card);
-
 	if ((rc = qeth_hardsetup_card(card))){
 		QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
 		goto out_remove;
diff --git a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c
index 5836737..273faad 100644
--- a/drivers/s390/net/qeth_sys.c
+++ b/drivers/s390/net/qeth_sys.c
@@ -720,10 +720,6 @@ qeth_dev_layer2_store(struct device *dev, struct device_attribute *attr, const c
 
 	if (!card)
 		return -EINVAL;
-	if (card->info.type == QETH_CARD_TYPE_IQD) {
-                PRINT_WARN("Layer2 on Hipersockets is not supported! \n");
-                return -EPERM;
-        }
 
 	if (((card->state != CARD_STATE_DOWN) &&
 	     (card->state != CARD_STATE_RECOVER)))