Package: linux-image-2.6.26-1-orion5x
Severity: normal
Tags: patch

The attached patch improves the kernel's support for the DNS-323 in a few
areas:

* It reads the MAC address for the on-board NIC out of flash, and uses it in
  the NIC initialisation (all DNS-323 models); and

* The SATA controller for the rev B1 hardware (also used in the CH3SNAS)
  requires PCI to be disabled, and the SATA controller to be initialised
  separately.

* The rev B1 hardware also has different MPP mappings.

A functionally-equivalent patch has been prepared for the mainline kernel,
and I'm working on getting that accepted upstream at the moment.

- Matt
--- dns323-setup.c.orig	2008-10-17 21:56:01.000000000 +1100
+++ dns323-setup.c	2008-10-21 09:25:42.000000000 +1100
@@ -21,6 +21,7 @@
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
 #include <linux/i2c.h>
+#include <linux/ata_platform.h>
 #include <asm/mach-types.h>
 #include <asm/gpio.h>
 #include <asm/mach/arch.h>
@@ -67,8 +68,18 @@
 
 static int __init dns323_pci_init(void)
 {
-	if (machine_is_dns323())
-		pci_common_init(&dns323_pci);
+	u32 dev, rev;
+	
+	orion5x_pcie_id(&dev, &rev);
+	
+	if (machine_is_dns323()) {
+		if (dev != MV88F5182_DEV_ID) {
+			/* The 5182 doesn't really use it's PCI bus, so
+			 * we don't initialise it.
+			 */
+			pci_common_init(&dns323_pci);
+		}
+	}
 
 	return 0;
 }
@@ -76,15 +87,6 @@
 subsys_initcall(dns323_pci_init);
 
 /****************************************************************************
- * Ethernet
- */
-
-static struct mv643xx_eth_platform_data dns323_eth_data = {
-	.phy_addr = 8,
-	.force_phy_addr = 1,
-};
-
-/****************************************************************************
  * 8MiB NOR flash (Spansion S29GL064M90TFIR4)
  *
  * Layout as used by D-Link:
@@ -143,6 +145,79 @@
 };
 
 /****************************************************************************
+ * Ethernet
+ */
+
+static struct mv643xx_eth_platform_data dns323_eth_data = {
+	.phy_addr = 8,
+	.force_phy_addr = 1,
+};
+
+/* parse_hex_*() taken from ts209-setup.c; should a common copy of these
+ * functions be kept somewhere?
+ */
+static int __init parse_hex_nibble(char n)
+{
+	if (n >= '0' && n <= '9')
+		return n - '0';
+
+	if (n >= 'A' && n <= 'F')
+		return n - 'A' + 10;
+
+	if (n >= 'a' && n <= 'f')
+		return n - 'a' + 10;
+
+	return -1;
+}
+
+static int __init parse_hex_byte(const char *b)
+{
+	int hi;
+	int lo;
+
+	hi = parse_hex_nibble(b[0]);
+	lo = parse_hex_nibble(b[1]);
+
+	if (hi < 0 || lo < 0)
+		return -1;
+
+	return (hi << 4) | lo;
+}
+
+static int __init dns323_read_mac_addr(void)
+{
+	u_int8_t addr[6] = { 0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF };
+	int i;
+	char *mac_page;
+	
+	/* MAC address is stored as a regular ol' string in /dev/mtdblock4
+	 * (0x007d0000-0x00800000) starting at offset 196480 (0x2ff80).
+	 */
+	mac_page = ioremap(DNS323_NOR_BOOT_BASE + 0x7d0000 + 196480, 1024);
+	
+	for (i = 0; i < 6; i++)	{
+		int byte;
+		
+		byte = parse_hex_byte(mac_page + (i * 3));
+		if (byte < 0) {
+			iounmap(mac_page);
+			return -1;
+		}
+		
+		addr[i] = byte;
+	}
+	
+	iounmap(mac_page);
+	printk("DNS323: Found ethernet MAC address: ");
+	for (i = 0; i < 6; i++)
+		printk("%.2x%s", addr[i], (i < 5) ? ":" : ".\n");
+	
+	memcpy(dns323_eth_data.mac_addr, addr, 6);
+	
+	return 0;
+}
+
+/****************************************************************************
  * GPIO LEDs (simple - doesn't use hardware blinking support)
  */
 
@@ -204,6 +279,13 @@
 	.dev		= { .platform_data  = &dns323_button_data, },
 };
 
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+static struct mv_sata_platform_data dns323_sata_data = {
+	.n_ports        = 2,
+};
+
 /****************************************************************************
  * General Setup
  */
@@ -247,6 +329,11 @@
 
 static void __init dns323_init(void)
 {
+	u32 rev, dev;
+	
+	/* Whooooooo are we?  Who who, who who? */
+	orion5x_pcie_id(&dev, &rev);
+	
 	/* Setup basic Orion functions. Need to be called early. */
 	orion5x_init();
 
@@ -262,11 +349,21 @@
 	orion5x_setup_pcie_wa_win(ORION5X_PCIE_WA_PHYS_BASE,
 				ORION5X_PCIE_WA_SIZE);
 
-	/* set MPP to 0 as D-Link's 2.6.12.6 kernel did */
-	orion5x_write(MPP_0_7_CTRL, 0);
-	orion5x_write(MPP_8_15_CTRL, 0);
-	orion5x_write(MPP_16_19_CTRL, 0);
-	orion5x_write(MPP_DEV_CTRL, 0);
+	if (dev == MV88F5182_DEV_ID) {
+		/* The 5182 has a different MPP map, so we wire it up this way
+		 * to let the HDD LEDs do their thing.  Values taken directly
+		 * from the D-Link kernel.
+		 */
+		orion5x_write(MPP_0_7_CTRL, 0x3);
+		orion5x_write(MPP_8_15_CTRL, 0x55550000);
+		orion5x_write(MPP_16_19_CTRL, 0x5555);
+	} else {
+		/* set MPP to 0 as D-Link's 2.6.12.6 kernel did */
+		orion5x_write(MPP_0_7_CTRL, 0);
+		orion5x_write(MPP_8_15_CTRL, 0);
+		orion5x_write(MPP_16_19_CTRL, 0);
+		orion5x_write(MPP_DEV_CTRL, 0);
+	}
 
 	/* Define used GPIO pins
 
@@ -305,7 +402,15 @@
 	i2c_register_board_info(0, dns323_i2c_devices,
 				ARRAY_SIZE(dns323_i2c_devices));
 
+	if (dns323_read_mac_addr() < 0)
+		printk("ERROR: Failed to read MAC address\n");
+		
 	orion5x_eth_init(&dns323_eth_data);
+	/* The 5182 has it's SATA controller internally, and it needs it's own
+	 * little init routine.
+	 */
+	if (dev == MV88F5182_DEV_ID)
+		orion5x_sata_init(&dns323_sata_data);
 }
 
 /* Warning: D-Link uses a wrong mach-type (=526) in their bootloader */

Reply via email to