[parisc-linux-cvs] HSC-PCI diff

Thomas Bogendoerfer tsbogend@alpha.franken.de
Thu, 13 Dec 2001 23:58:58 +0100


Hi,

I've got the HSC-PCI going in my B132. I had to fix the irq numbering in
dino.c and add a fake mediatable to tulip. And since the HSC-PCI has
a special phy interrupt thing, I had to add support for that, too.

Thomas.

Index: eeprom.c
===================================================================
RCS file: /var/cvs/linux/drivers/net/tulip/eeprom.c,v
retrieving revision 1.12
diff -u -r1.12 eeprom.c
--- eeprom.c	2001/11/09 23:36:08	1.12
+++ eeprom.c	2001/12/13 22:35:32
@@ -136,6 +136,48 @@
 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[3] == 0x10) {  /* sub device id */
+			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		
 	} else if (tp->chip_id == DC21041) {
 		unsigned char *p = (void *)ee_data + ee_data[27 + controller_index*3];
 		int media = get_u16(p);
Index: interrupt.c
===================================================================
RCS file: /var/cvs/linux/drivers/net/tulip/interrupt.c,v
retrieving revision 1.11
diff -u -r1.11 interrupt.c
--- interrupt.c	2001/11/29 15:49:38	1.11
+++ interrupt.c	2001/12/13 22:35:33
@@ -291,6 +291,25 @@
 #endif
 }
 
+#ifdef __hppa__
+static inline void phy_interrupt (struct net_device *dev, struct tulip_private *tp, long ioaddr)
+{
+	int csr12;
+	
+	csr12 = inl(ioaddr + CSR12) & 0xff;
+	if (csr12 != tp->csr12_shadow) {
+		/* ack interrupt */
+		outl(csr12 | 0x02, ioaddr + 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 | 0x00, ioaddr + CSR12);
+	}
+}
+#endif
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
@@ -313,6 +332,12 @@
 	/* 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
+    
 	if ((csr5 & (NormalIntr|AbnormalIntr)) == 0)
 		return;
 
Index: tulip.h
===================================================================
RCS file: /var/cvs/linux/drivers/net/tulip/tulip.h,v
retrieving revision 1.8
diff -u -r1.8 tulip.h
--- tulip.h	2001/11/29 15:49:39	1.8
+++ tulip.h	2001/12/13 22:35:34
@@ -63,6 +63,7 @@
 	HAS_8023X		= 0x0400,
 	COMET_MAC_ADDR		= 0x0800,
 	HAS_PCI_MWI		= 0x1000,
+        HAS_PHY_IRQ             = 0x2000,
 };
 
 
@@ -387,7 +388,12 @@
 	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	
 };
 
 
Index: dino.c
===================================================================
RCS file: /var/cvs/linux/drivers/gsc/dino.c,v
retrieving revision 1.46
diff -u -r1.46 dino.c
--- dino.c	2001/11/05 07:42:15	1.46
+++ dino.c	2001/12/13 22:57:59
@@ -564,7 +564,7 @@
 	** The additional "-1" adjusts for skewing the IRQ<->slot.
 	*/
 	dino_cfg_read8(dev, PCI_INTERRUPT_PIN, &irq_pin); 
-	dev->irq = (irq_pin + (dev->devfn >> 3) - 2) % 4 ;
+	dev->irq = (irq_pin + (dev->devfn >> 3) - 1) % 4 ;
 
 
 	/* Shouldn't really need to do this but it's in case someone tries


-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessary a
good idea.                                 [ Alexander Viro on linux-kernel ]