[tulip] [PATCH] making old Conexant driver work

Pavel Roskin proski@gnu.org
Wed Jan 23 19:08:01 2002


Hello!

Sorry for the crosspost to so many people and lists - I don't know who is
subscribed to what and which lists are alive.  Please trim To: and Cc:  
accordingly.

I'm trying to add Linux support for Zoom PCI Cable Modem model 5001.  
Zoom distributes closed source drivers at
http://www.zoomtel.com/cable/linuxdrivers.shtml

The latest kernel they support is 2.4.4.  I stronly believe that using
closed source drivers is not a good idea, especially if it forces
downgrading the kernel.

Zoom PCI Cable Modem model 5001 consists essentially of two devices on one 
board - an ethernet interface on the RS7112 (aka CN7112) chip and a cable 
modem on the CN9414 chip.  Both chips are produuced by Conexant.

It appears that having a working driver for the RS7112 chip is sufficient
- the cable modem appears as an external device connected to the ethernet
port.

Search on the web shows that the support for Conexant existed in the Tulip
driver in the past, but was removed later.  As Donald Becker writes on
http://www.geocrawler.com/archives/3/425/2001/11/0/7170033/ , "The
divergent Tulip driver distributed with the 2.4 kernels never really
supported the Conexant chip".

However, there is a thread starting here 
http://www.tux.org/hypermail/linux-tulip/2001-Jul/0054.html , in which 
Kent Hunt says that Conexant LANfinity is actually working for him.

Further in the thread, at
http://www.tux.org/hypermail/linux-tulip/2001-Jul/0077.html , Christoph 
Lameter publishes a tarball containing the driver supporting Conexant 
LANfinity.

I took the driver and compiled in it under Linux-2.4.18-pre6, and it 
worked!  I could use the cable modem without any problems.  I only had to 
make some changes for compatibility with the modern kernels, that I'm 
attaching to this message.

The changes are:

1) APM support didn't compile.  Modern API is very different.  I disabled
APM support because fixing it would take hours of my time (I'm not a
hard-core kernel hacker), and because the right thing is to fix the modern
driver to support Conexant, not to fix this driver which is not even using
modern PCI API.

2) request_region and release_region are redefined to use memory if momory
I/O is used.  In fact, request_region used to fail, and release_region
reported and error to the syslog.  Now request_region actually allocates
the memory.

3) linux/slab.h used instead of linux/malloc.h to fix a warning

4) MODULE_LICENSE added.

5) "make install" is supported now.  Not guaranteed to be correct if
compiling for the kernel which is now running now, but still convenient 
and safer that copying by hand.

=====================================
--- Makefile
+++ Makefile
@@ -2,6 +2,7 @@
 OPTIONSCOMMON = -D__KERNEL__ -DMODULE -Wall -Wstrict-prototypes -O2 -I/usr/src/linux/include -fomit-frame-pointer -fno-strict-aliasing -Wno-trigraphs -fno-common -pipe -mpreferred-stack-boundary=2 -march=i686 -DMODVERSIONS  -include /usr/src/linux/include/linux/modversions.h
 OPTIONSTULIP = $(OPTIONSCOMMON)
 OPTIONSPCISN = $(OPTIONSCOMMON)  -DEXPORT_SYMTAB
+MODULE_INSTDIR = /lib/modules/`uname -r`/kernel/drivers//net/tulip/
 
 all:
 	$(CC) $(OPTIONSTULIP) -c tulip.c
@@ -9,3 +10,8 @@
 
 clean:
 	rm -f *~ pci-scan.o tulip.o
+
+install:
+	install -d $(MODULE_INSTDIR)
+	install -m 644 pci-scan.o tulip.o $(MODULE_INSTDIR)
+	/sbin/depmod
--- pci-scan.c
+++ pci-scan.c
@@ -62,10 +62,11 @@ static int min_pci_latency = 32;
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/ioport.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <asm/io.h>
 #include "pci-scan.h"
 #include "kern_compat.h"
+#undef CONFIG_APM
 #ifdef CONFIG_APM
 #include <linux/apm_bios.h>
 #endif
@@ -82,6 +83,7 @@ char kernel_version[] = UTS_RELEASE;
 int (*register_cb_hook)(struct drv_id_info *did);
 void (*unregister_cb_hook)(struct drv_id_info *did);
 
+MODULE_LICENSE("GPL");
 #if LINUX_VERSION_CODE > 0x20118  &&  defined(MODULE)
 MODULE_PARM(debug, "i");
 MODULE_PARM(min_pci_latency, "i");
--- tulip.c
+++ tulip.c
@@ -145,7 +145,7 @@ static int csr0 = 0x00A00000 | 0x4800;
 #include <linux/timer.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
@@ -172,6 +172,7 @@ char kernel_version[] = UTS_RELEASE;
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("Digital 21*4* Tulip ethernet driver");
+MODULE_LICENSE("GPL");
 MODULE_PARM(debug, "i");
 MODULE_PARM(max_interrupt_work, "i");
 MODULE_PARM(reverse_probe, "i");
@@ -198,6 +199,8 @@ MODULE_PARM(full_duplex, "1-" __MODULE_S
 #define outb writeb
 #define outw writew
 #define outl writel
+#define request_region(start,n,name) request_mem_region(start,n,name)
+#define release_region(start,n) release_mem_region(start,n)
 #endif
 
 /*
=====================================

Christoph, please update the driver.

Whether Conexant wants us to support their chips or not, there is a
working open-source driver for RS7112, so their reluctance is no excuse
(IMHO) and it's time to add it's support to the modern driver.

I have made some changes to it, but it doesn't work so far.  It cannot 
find EEPROM and doesn't detect the MAC address correctly:

eth1: Conexant LANfinity rev 8 at 0xac00, EEPROM not present, 
00:4C:69:6E:75:79, IRQ 11.

00:4C:69:6E:75:79 is "\000Linux"

This patch is a work in progress.  I'm going to work on in tomorrow, but
I'm posting it here just in case, maybe somebody has a working driver
already or can help me finish this patch.  The patch is against Linux
2.4.18-pre6.

=====================================
--- tulip_core.c
+++ tulip_core.c
@@ -188,6 +188,10 @@ struct tulip_chip_table tulip_tbl[] = {
   { "Davicom DM9102/DM9102A", 128, 0x0001ebef,
 	HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_ACPI,
 	tulip_timer },
+
+  /* RS7112 */
+  { "Conexant LANfinity", 256, 0x0001ebef,
+	HAS_MII | HAS_ACPI, tulip_timer },
 };
 
 
@@ -216,6 +220,7 @@ static struct pci_device_id tulip_pci_tb
 	{ 0x1113, 0x1216, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x1113, 0x1217, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 },
 	{ 0x1113, 0x9511, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+	{ 0x14f1, 0x1803, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CONEXANT },
 	{ } /* terminate list */
 };
 MODULE_DEVICE_TABLE(pci, tulip_pci_tbl);
@@ -448,7 +453,7 @@ media_picked:
 		tp->csr6 = 0x01a80200;
 		outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80);
 		outl(0x11000 | inw(ioaddr + 0xa0), ioaddr + 0xa0);
-	} else if (tp->chip_id == COMET) {
+	} else if (tp->chip_id == COMET || tp->chip_id == CONEXANT) {
 		/* Enable automatic Tx underrun recovery. */
 		outl(inl(ioaddr + 0x88) | 1, ioaddr + 0x88);
 		dev->if_port = tp->mii_cnt ? 11 : 0;
@@ -1583,7 +1588,12 @@ static int __devinit tulip_init_one (str
 		for (i = 0; i < 8; i ++)
 			if (ee_data[i] != ee_data[16+i])
 				sa_offset = 20;
-		if (ee_data[0] == 0xff  &&  ee_data[1] == 0xff &&  ee_data[2] == 0) {
+		if (chip_idx == CONEXANT) {
+			/* Check that the tuple type and length is correct. */
+			if (ee_data[0x198] == 0x04  &&  ee_data[0x199] == 6)
+				sa_offset = 0x19A;
+		} else if (ee_data[0] == 0xff  &&  ee_data[1] == 0xff &&
+				   ee_data[2] == 0) {
 			sa_offset = 2;		/* Grrr, damn Matrox boards. */
 			multiport_cnt = 4;
 		}
--- tulip.h
+++ tulip.h
@@ -84,6 +84,7 @@
 	COMPEX9881,
 	I21145,
 	DM910X,
+	CONEXANT,
 };
 
 
=====================================

-- 
Regards,
Pavel Roskin