[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 ]