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