[parisc-linux-cvs] [PATCH] tulip update for the 3x5 HSC cards.

Ryan Bradetich rbradetich@uswest.net
11 Sep 2002 00:59:54 -0600


This patch contains tulip updates sent off to Jeff Garzik to support
the 3x5 HSC cards.  Neither Grant nor I have heard a status update if
this patch was accepted or not, so I am just going to commit it and
deal with any fall out at a later merge.  [Note: I had a farily sizable
diff in my local tree that I am trying to get cleaned up and committed].

There is one additional patch (the ccio resource) patch that is needed
to get these cards working on the K-Class systems, but Willy and I are
still thinking of how to impliment the ccio resource patch cleanly into
the parisc-linux tree.

Thanks,

- Ryan

Index: Makefile
===================================================================
RCS file: /var/cvs/linux/Makefile,v
retrieving revision 1.347
diff -u -p -r1.347 Makefile
--- Makefile	11 Sep 2002 06:49:49 -0000	1.347
+++ Makefile	11 Sep 2002 06:53:34 -0000
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 19
-EXTRAVERSION = -pa12
+EXTRAVERSION = -pa13
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
Index: drivers/net/tulip/eeprom.c
===================================================================
RCS file: /var/cvs/linux/drivers/net/tulip/eeprom.c,v
retrieving revision 1.14
diff -u -p -r1.14 eeprom.c
--- drivers/net/tulip/eeprom.c	29 Aug 2002 21:02:18 -0000	1.14
+++ drivers/net/tulip/eeprom.c	11 Sep 2002 06:53:34 -0000
@@ -75,6 +75,61 @@ static const char *block_name[] __devini
 };
 

+/**
+ * tulip_build_fake_mediatable - Build a fake mediatable entry.
+ * @tp: Ptr to the tulip private data.
+ *
+ * Some cards like the 3x5 HSC cards (J3514A) do not have a standard 
+ * srom and can not be handled under the fixup routine.  These cards
+ * still need a valid mediatable entry for correct csr12 setup and 
+ * mii handling.
+ * 
+ * Since this is currently a parisc-linux specific function, the
+ * #ifdef __hppa__ should completely optimize this function away for
+ * non-parisc hardware.
+ */
+static void __devinit tulip_build_fake_mediatable(struct tulip_private *tp)
+{
+#ifdef __hppa__
+	unsigned char *ee_data = tp->eeprom;
+
+	if (ee_data[0] == 0x3c && ee_data[1] == 0x10 && 
+		(ee_data[2] == 0x63 || ee_data[2] == 0x61) && ee_data[3] == 0x10) {
+
+		static unsigned char leafdata[] =
+			{ 0x01,       /* phy number */
+			  0x02,       /* gpr setup sequence length */
+			  0x02, 0x00, /* gpr setup sequence */
+			  0x02,       /* phy reset sequence length */
+			  0x01, 0x00, /* phy reset sequence */
+			  0x00, 0x78, /* media capabilities */
+			  0x00, 0xe0, /* nway advertisment */
+			  0x00, 0x05, /* fdx bit map */
+			  0x00, 0x06  /* ttm bit map */
+			};
+
+		tp->mtable = (struct mediatable *)
+			kmalloc(sizeof(struct mediatable) + sizeof(struct medialeaf), GFP_KERNEL);
+
+		if (tp->mtable == NULL)
+			return; /* Horrible, impossible failure. */
+
+		tp->mtable->defaultmedia = 0x800;
+		tp->mtable->leafcount = 1;
+		tp->mtable->csr12dir = 0x3f; /* inputs on bit7 for hsc-pci, bit6 for pci-fx */
+		tp->mtable->has_nonmii = 0;
+		tp->mtable->has_reset = 0;
+		tp->mtable->has_mii = 1;
+		tp->mtable->csr15dir = tp->mtable->csr15val = 0;
+		tp->mtable->mleaf[0].type = 1;
+		tp->mtable->mleaf[0].media = 11;
+		tp->mtable->mleaf[0].leafdata = &leafdata[0];
+		tp->flags |= HAS_PHY_IRQ;
+		tp->csr12_shadow = -1;
+	}
+#endif 
+}
+
 void __devinit tulip_parse_eeprom(struct net_device *dev)
 {
 	/* The last media info list parsed, for multiport boards.  */
@@ -136,50 +191,7 @@ void __devinit tulip_parse_eeprom(struct
 subsequent_board:
 
 	if (ee_data[27] == 0) {		/* No valid media table. */
-#ifdef __hppa__
-		/*
-		 * HSC-PCI cards don't have a standard srom,
-		 * but we need to setup a fake mediatable
-		 * for a correct csr12 setup and mii handling
-		 */
-		if (ee_data[0] == 0x3c && ee_data[1] == 0x10   && /* sub vendor id */
-		    (ee_data[2] == 0x63 || ee_data[2] == 0x61) && /* sub device id */
-		     ee_data[3] == 0x10) { 
-
-			static unsigned char leafdata[] =
-			        { 0x01,       /* phy number */
-				  0x02,       /* gpr setup sequence length */
-				  0x02, 0x00, /* gpr setup sequence */
-				  0x02,       /* phy reset sequence length */
-				  0x01, 0x00, /* phy reset sequence */
-				  0x00, 0x78, /* media capabilities */
-				  0x00, 0xe0, /* nway advertisment */
-				  0x00, 0x05, /* fdx bit map */
-				  0x00, 0x06  /* ttm bit map */
-				};
-			struct mediatable *mtable;
-			
-			mtable = (struct mediatable *)
-				kmalloc(sizeof(struct mediatable) + sizeof(struct medialeaf),
-					GFP_KERNEL);
-			if (mtable == NULL)
-				return;				/* Horrible, impossible failure. */
-			
-			tp->mtable = mtable;
-			mtable->defaultmedia = 0x800;
-			mtable->leafcount = 1;
-			mtable->csr12dir = 0x3f; /* inputs on bit7 for hsc-pci, bit6 for pci-fx */
-			mtable->has_nonmii = 0;
-			mtable->has_reset = 0;
-			mtable->has_mii = 1;
-			mtable->csr15dir = mtable->csr15val = 0;
-			mtable->mleaf[0].type = 1;
-			mtable->mleaf[0].media = 11;
-			mtable->mleaf[0].leafdata = &leafdata[0];
-		        tp->flags |= HAS_PHY_IRQ;
-			tp->csr12_shadow = -1;
-		}
-#endif		
+		tulip_build_fake_mediatable(tp);
 	} else if (tp->chip_id == DC21041) {
 		unsigned char *p = (void *)ee_data + ee_data[27 + controller_index*3];
 		int media = get_u16(p);
Index: drivers/net/tulip/interrupt.c
===================================================================
RCS file: /var/cvs/linux/drivers/net/tulip/interrupt.c,v
retrieving revision 1.13
diff -u -p -r1.13 interrupt.c
--- drivers/net/tulip/interrupt.c	25 Feb 2002 23:12:32 -0000	1.13
+++ drivers/net/tulip/interrupt.c	11 Sep 2002 06:53:34 -0000
@@ -291,25 +291,25 @@ throttle:
 #endif
 }
 
-#ifdef __hppa__
-static inline void phy_interrupt (struct net_device *dev, struct tulip_private *tp, long ioaddr)
+static inline void phy_interrupt (struct net_device *dev)
 {
-	int csr12;
-	
-	csr12 = inl(ioaddr + CSR12) & 0xff;
+#ifdef __hppa__
+	int csr12 = inl(dev->base_addr + CSR12) & 0xff;
+	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+
 	if (csr12 != tp->csr12_shadow) {
 		/* ack interrupt */
-		outl(csr12 | 0x02, ioaddr + CSR12);
+		outl(csr12 | 0x02, dev->base_addr + CSR12);
 		tp->csr12_shadow = csr12;
 		/* do link change stuff */
 		spin_lock(&tp->lock);
 		tulip_check_duplex(dev);
 		spin_unlock(&tp->lock);
 		/* clear irq ack bit */
-		outl(csr12 & ~0x02, ioaddr + CSR12);
+		outl(csr12 & ~0x02, dev->base_addr + CSR12);
 	}
-}
 #endif
+}
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
@@ -332,11 +332,8 @@ void tulip_interrupt(int irq, void *dev_
 	/* Let's see whether the interrupt really is for us */
 	csr5 = inl(ioaddr + CSR5);
 
-    
-#ifdef __hppa__
         if (tp->flags & HAS_PHY_IRQ)
-	        phy_interrupt (dev, tp, ioaddr);
-#endif
+	        phy_interrupt (dev);
     
 	if ((csr5 & (NormalIntr|AbnormalIntr)) == 0)
 		return;
Index: drivers/net/tulip/media.c
===================================================================
RCS file: /var/cvs/linux/drivers/net/tulip/media.c,v
retrieving revision 1.12
diff -u -p -r1.12 media.c
--- drivers/net/tulip/media.c	4 Aug 2002 22:58:40 -0000	1.12
+++ drivers/net/tulip/media.c	11 Sep 2002 06:53:34 -0000
@@ -285,6 +285,16 @@ void tulip_select_media(struct net_devic
 					outl(init_sequence[i], ioaddr + CSR12);
 			}
 
+			/* FIXME: this is WRONG! ggg says we need to poll bit 15 
+			 * of Basic Mode Control register (address 00h) until it 
+			 * is zero again.
+			 * the right sequence in that code should be:
+			 *   1) send reset_sequence[]
+			 *   2) poll bit 15 until it's zero again
+			 *   3) udelay(500)
+ 			 *   4) send init_sequence[]
+			 * this based on the DP83840A Phy spec.
+			 */
 			inl(ioaddr + CSR6);	/* flush posted writes */
 			udelay(500);
 
Index: drivers/net/tulip/tulip.h
===================================================================
RCS file: /var/cvs/linux/drivers/net/tulip/tulip.h,v
retrieving revision 1.9
diff -u -p -r1.9 tulip.h
--- drivers/net/tulip/tulip.h	13 Dec 2001 22:37:14 -0000	1.9
+++ drivers/net/tulip/tulip.h	11 Sep 2002 06:53:34 -0000
@@ -388,12 +388,8 @@ struct tulip_private {
 	int susp_rx;
 	unsigned long nir;
 	unsigned long base_addr;
-#ifdef __hppa__
 	int csr12_shadow;
-	int pad1;
-#else	
-	int pad0, pad1;		/* Used for 8-byte alignment */
-#endif	
+	int pad0;		/* Used for 8-byte alignment */
 };
 

Index: drivers/net/tulip/tulip_core.c
===================================================================
RCS file: /var/cvs/linux/drivers/net/tulip/tulip_core.c,v
retrieving revision 1.24
diff -u -p -r1.24 tulip_core.c
--- drivers/net/tulip/tulip_core.c	29 Aug 2002 21:02:18 -0000	1.24
+++ drivers/net/tulip/tulip_core.c	11 Sep 2002 06:53:35 -0000
@@ -1579,17 +1579,18 @@ static int __devinit tulip_init_one (str
                }
 #endif
 #ifdef __hppa__
-		/* Check to see if we have a broken srom */
+		/* 3x5 HSC (J3514A) has a broken srom */
 		if(ee_data[0] == 0x61 && ee_data[1] == 0x10) {
-			/* subsys_vendor and subsys_id are swapped */
+			/* pci_vendor_id and subsystem_id are swapped */
 			ee_data[0] = ee_data[2];
 			ee_data[1] = ee_data[3];
 			ee_data[2] = 0x61;
 			ee_data[3] = 0x10;
 
-			/* HSC-PCI boards need to be byte-swaped and shifted
-			**   up 1 word. 
-			*/
+			/* srom need to be byte-swaped and shifted up 1 word.  
+			 * This shift needs to happen at the end of the MAC
+			 * first because of the 2 byte overlap.
+			 */
 			for(i = 4; i >= 0; i -= 2) {
 				ee_data[17 + i + 3] = ee_data[17 + i];
 				ee_data[16 + i + 5] = ee_data[16 + i];