From 693e5a62fc2d8798e576054ffed8db5f5f2ecbd4 Mon Sep 17 00:00:00 2001
From: nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Date: Sat, 14 Jan 2006 17:49:21 +0000
Subject: sync kmod-switch with whiterussian

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@2981 3c298f89-4303-0410-b956-a3cf2f4a3e73
---
 .../target/linux/package/switch/src/switch-adm.c   | 112 +++++++++++++++------
 .../target/linux/package/switch/src/switch-robo.c  |  26 +++--
 2 files changed, 104 insertions(+), 34 deletions(-)

(limited to 'openwrt/target/linux')

diff --git a/openwrt/target/linux/package/switch/src/switch-adm.c b/openwrt/target/linux/package/switch/src/switch-adm.c
index f2bc8e152..2ce87e777 100644
--- a/openwrt/target/linux/package/switch/src/switch-adm.c
+++ b/openwrt/target/linux/package/switch/src/switch-adm.c
@@ -34,10 +34,10 @@
 #define DRIVER_NAME "adm6996"
 #define DRIVER_VERSION "0.01"
 
-static int eecs = 2;
-static int eesk = 3;
-static int eedi = 5;
-static int eerc = 6;
+static int eecs = 0;
+static int eesk = 0;
+static int eedi = 0;
+static int eerc = 0;
 static int force = 0;
 
 MODULE_AUTHOR("Felix Fietkau <openwrt@nbd.name>");
@@ -60,8 +60,34 @@ MODULE_PARM(force, "i");
 
 #define atoi(str) simple_strtoul(((str != NULL) ? str : ""), NULL, 0)
 
+#if defined(BCMGPIO2) || defined(BCMGPIO)
 extern char *nvram_get(char *name);
 
+/* Return gpio pin number assigned to the named pin */
+/*
+* Variable should be in format:
+*
+*	gpio<N>=pin_name
+*
+* 'def_pin' is returned if there is no such variable found.
+*/
+static unsigned int getgpiopin(char *pin_name, unsigned int def_pin)
+{
+	char name[] = "gpioXXXX";
+	char *val;
+	unsigned int pin;
+
+	/* Go thru all possibilities till a match in pin name */
+	for (pin = 0; pin < 16; pin ++) {
+		sprintf(name, "gpio%d", pin);
+		val = nvram_get(name);
+		if (val && !strcmp(val, pin_name))
+			return pin;
+	}
+	return def_pin;
+}
+#endif
+
 
 static void adm_write(int cs, char *buf, unsigned int bits)
 {
@@ -255,7 +281,16 @@ static int handle_vlan_port_read(void *driver, char *buf, int nr)
 	for (i = 0; i <= 5; i++) {
 		if (ports & vlan_ports[i]) {
 			c = adm_rreg(0, port_conf[i]);
-			len += sprintf(buf + len, (c & (1 << 4) ? "%dt\t" : (i == 5 ? "%du\t" : "%d\t")), i);
+			
+			len += sprintf(buf + len, "%d", i);
+			if (c & (1 << 4)) {
+				buf[len++] = 't';
+				if (((c & (0xf << 10)) >> 10) == nr)
+					buf[len++] = '*';
+			} else if (i == 5)
+				buf[len++] = 'u';
+
+			buf[len++] = '\t';
 		}
 	}
 	len += sprintf(buf + len, "\n");
@@ -386,23 +421,24 @@ static int handle_reset(void *driver, char *buf, int nr)
 	 * reset logic therefore we must explicitly perform the
 	 * sequence in software.
 	 */
-	/* Keep RC high for at least 20ms */
-	adm_enout(eerc, eerc);
-	for (i = 0; i < 20; i ++)
-		udelay(1000);
-	/* Keep RC low for at least 100ms */
-	adm_enout(eerc, 0);
-	for (i = 0; i < 100; i++)
-		udelay(1000);
-	/* Set default configuration */
-	adm_enout((__u8)(eesk | eedi), eesk);
-	/* Keep RC high for at least 30ms */
-	adm_enout(eerc, eerc);
-	for (i = 0; i < 30; i++)
-		udelay(1000);
-	/* Leave RC high and disable GPIO outputs */
-	adm_disout((__u8)(eecs | eesk | eedi));
-
+	if (eerc) {
+		/* Keep RC high for at least 20ms */
+		adm_enout(eerc, eerc);
+		for (i = 0; i < 20; i ++)
+			udelay(1000);
+		/* Keep RC low for at least 100ms */
+		adm_enout(eerc, 0);
+		for (i = 0; i < 100; i++)
+			udelay(1000);
+		/* Set default configuration */
+		adm_enout((__u8)(eesk | eedi), eesk);
+		/* Keep RC high for at least 30ms */
+		adm_enout(eerc, eerc);
+		for (i = 0; i < 30; i++)
+			udelay(1000);
+		/* Leave RC high and disable GPIO outputs */
+		adm_disout((__u8)(eecs | eesk | eedi));
+	}
 	/* set up initial configuration for ports */
 	for (i = 0; i <= 5; i++) {
 		int cfg = 0x8000 | /* Auto MDIX */
@@ -446,10 +482,34 @@ static int detect_adm()
 #if defined(BCMGPIO2) || defined(BCMGPIO)
 	int boardflags = atoi(nvram_get("boardflags"));
 
-	if ((boardflags & 0x80) || force)
+	if ((boardflags & 0x80) || force) {
+		ret = 1;
+
+		eecs = getgpiopin("adm_eecs", 2);
+		eesk = getgpiopin("adm_eesk", 3);
+		eedi = getgpiopin("adm_eedi", 4);
+		eerc = getgpiopin("adm_rc", 0);
+
+	} else if ((strcmp(nvram_get("boardtype"), "bcm94710dev") == 0) &&
+			(strncmp(nvram_get("boardnum"), "42", 2) == 0)) {
+		/* WRT54G v1.1 hack */
+		eecs = 2;
+		eesk = 3;
+		eedi = 5;
+		eerc = 6;
+
 		ret = 1;
-	else 
+	} else
 		printk("BFL_ENETADM not set in boardflags. Use force=1 to ignore.\n");
+		
+	if (eecs)
+		eecs = (1 << eecs);
+	if (eesk)
+		eesk = (1 << eesk);
+	if (eedi)
+		eedi = (1 << eedi);
+	if (eerc)
+		eerc = (1 << eerc);
 #else
 	ret = 1;
 #endif
@@ -487,10 +547,6 @@ static int __init adm_init()
 		vlan_handlers: vlan,
 	};
 
-	eecs = (1 << eecs);
-	eesk = (1 << eesk);
-	eedi = (1 << eedi);
-
 	if (!detect_adm())
 		return -ENODEV;
 
diff --git a/openwrt/target/linux/package/switch/src/switch-robo.c b/openwrt/target/linux/package/switch/src/switch-robo.c
index 63110d7c9..6af0ff713 100644
--- a/openwrt/target/linux/package/switch/src/switch-robo.c
+++ b/openwrt/target/linux/package/switch/src/switch-robo.c
@@ -278,8 +278,15 @@ static int handle_vlan_port_read(void *driver, char *buf, int nr)
 		if ((val32 & (1 << 20)) /* valid */) {
 			for (j = 0; j < 6; j++) {
 				if (val32 & (1 << j)) {
-					len += sprintf(buf + len, "%d%s\t", j, 
-						(val32 & (1 << (j + 6))) ? (j == 5 ? "u" : "") : "t");
+					len += sprintf(buf + len, "%d", j);
+					if (val32 & (1 << (j + 6))) {
+						if (j == 5) buf[len++] = 'u';
+					} else {
+						buf[len++] = 't';
+						if (robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_PORT0_DEF_TAG + (j << 1)) == nr)
+							buf[len++] = '*';
+					}
+					buf[len++] = '\t';
 				}
 			}
 			len += sprintf(buf + len, "\n");
@@ -291,8 +298,15 @@ static int handle_vlan_port_read(void *driver, char *buf, int nr)
 		if ((val16 & (1 << 14)) /* valid */) {
 			for (j = 0; j < 6; j++) {
 				if (val16 & (1 << j)) {
-					len += sprintf(buf + len, "%d%s\t", j, (val16 & (1 << (j + 7))) ? 
-						(j == 5 ? "u" : "") : "t");
+					len += sprintf(buf + len, "%d", j);
+					if (val16 & (1 << (j + 7))) {
+						if (j == 5) buf[len++] = 'u';
+					} else {
+						buf[len++] = 't';
+						if (robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_PORT0_DEF_TAG + (j << 1)) == nr)
+							buf[len++] = '*';
+					}
+					buf[len++] = '\t';
 				}
 			}
 			len += sprintf(buf + len, "\n");
@@ -415,7 +429,7 @@ static int __init robo_init()
 	if (notfound)
 		return -ENODEV;
 	else {
-		switch_config main[] = {
+		switch_config cfg[] = {
 			{"enable", handle_enable_read, handle_enable_write},
 			{"enable_vlan", handle_enable_vlan_read, handle_enable_vlan_write},
 			{"reset", NULL, handle_reset},
@@ -432,7 +446,7 @@ static int __init robo_init()
 			cpuport: 5,
 			ports: 6,
 			vlans: 16,
-			driver_handlers: main,
+			driver_handlers: cfg,
 			port_handlers: NULL,
 			vlan_handlers: vlan,
 		};
-- 
cgit v1.2.3