Patchwork [RFC] National Semiconductor DP83815 NIC patch

login
register
about
Submitter Andrew Morgan
Date 2010-06-04 03:07:13
Message ID <4C086DE1.4070703@ziltro.com>
Download mbox | patch
Permalink /patch/1463/
State Superseded
Headers show

Comments

Andrew Morgan - 2010-06-04 03:07:13
Hi,

I have a couple of Netgear FA311 network cards, which have DP83815DVNG 
chips on board, and a space to mount a 32-pin boot ROM socket. Looking 
at the datasheet for the chip I have created this patch.

The datasheet suggests that reads and writes must be done 32 bits at a 
time, and only at 32 bit offsets. This seems strange for chips which 
have an 8 bit data bus.

I don't think this code is ready for inclusion in flashrom yet, but if 
anyone has a card with this chip and can test it out then give it a go. 
I'm pretty sure it won't just work though. It might even destroy your 
computer/house/planet.

I can't test it yet because the cards don't have a 32pin socket mounted 
on them. If and when I can add one then I can do some tests.

This is my first 'large' patch so let me know what I have got wrong. :)

Signed-off-by: Andrew Morgan <ziltro@ziltro.com>
Carl-Daniel Hailfinger - 2010-06-04 14:13:15
On 04.06.2010 05:07, Andrew Morgan wrote:
> I have a couple of Netgear FA311 network cards, which have DP83815DVNG
> chips on board, and a space to mount a 32-pin boot ROM socket. Looking
> at the datasheet for the chip I have created this patch.
>
> The datasheet suggests that reads and writes must be done 32 bits at a
> time, and only at 32 bit offsets. This seems strange for chips which
> have an 8 bit data bus.
>
> I don't think this code is ready for inclusion in flashrom yet, but if
> anyone has a card with this chip and can test it out then give it a
> go. I'm pretty sure it won't just work though. It might even destroy
> your computer/house/planet.
>
> I can't test it yet because the cards don't have a 32pin socket
> mounted on them. If and when I can add one then I can do some tests.
>
> This is my first 'large' patch so let me know what I have got wrong. :)
>
> Signed-off-by: Andrew Morgan <ziltro@ziltro.com>

Oh, it looks really nice.

In fact, we could commit this instantly except for two reasons:
1. It's untested, and completely untested drivers should default to no
in the Makefile. Once we have the first successful test, we can change
it to yes.
2. The INB/OUTB for data contradicts the datasheet (I know, the
datasheet might very well be wrong), so a comment would be appreciated
in those places, e.g. "The datasheet says this register can only be
accessed with full 32 bit width, but that would make 8 bit writes
impossible. Due to that, we assume the meaning was garbled in translation."

Hm. It is entirely possible that the datasheet means the register access
mode is 32 bit. The contents of the data register might only care about
the lowest 8 bits. That would also mean your driver could work...

Change those two things, and you get an ack from me and I'll commit.

Regards,
Carl-Daniel

Patch

Index: flash.h
===================================================================
--- flash.h	(revision 1028)
+++ flash.h	(working copy)
@@ -49,6 +49,9 @@ 
 	PROGRAMMER_NICREALTEK,
 	PROGRAMMER_NICREALTEK2,
 #endif	
+#if CONFIG_NICNATSEMI == 1
+	PROGRAMMER_NICNATSEMI,
+#endif	
 #if CONFIG_GFXNVIDIA == 1
 	PROGRAMMER_GFXNVIDIA,
 #endif
@@ -345,7 +348,7 @@ 
 /* print.c */
 char *flashbuses_to_text(enum chipbustype bustype);
 void print_supported(void);
-#if CONFIG_NIC3COM+CONFIG_NICREALTEK+CONFIG_GFXNVIDIA+CONFIG_DRKAISER+CONFIG_SATASII+CONFIG_ATAHPT >= 1
+#if CONFIG_NIC3COM+CONFIG_NICREALTEK+CONFIG_NICNATSEMI+CONFIG_GFXNVIDIA+CONFIG_DRKAISER+CONFIG_SATASII+CONFIG_ATAHPT >= 1
 void print_supported_pcidevs(struct pcidev_status *devs);
 #endif
 void print_supported_wiki(void);
@@ -494,6 +497,14 @@ 
 extern struct pcidev_status nics_realteksmc1211[];
 #endif
 
+/* nicnatsemi.c */
+#if CONFIG_NICNATSEMI == 1
+int nicnatsemi_init(void);
+int nicnatsemi_shutdown(void);
+void nicnatsemi_chip_writeb(uint8_t val, chipaddr addr);
+uint8_t nicnatsemi_chip_readb(const chipaddr addr);
+extern struct pcidev_status nics_natsemi[];
+#endif
 
 /* satasii.c */
 #if CONFIG_SATASII == 1
Index: Makefile
===================================================================
--- Makefile	(revision 1028)
+++ Makefile	(working copy)
@@ -113,6 +113,9 @@ 
 # Always enable Realtek NICs for now.
 CONFIG_NICREALTEK ?= yes
 
+# Always enable National Semiconductor NICs for now.
+CONFIG_NICNATSEMI ?= yes
+
 # Always enable Bus Pirate SPI for now.
 CONFIG_BUSPIRATE_SPI ?= yes
 
@@ -192,6 +195,12 @@ 
 NEED_PCI := yes
 endif
 
+ifeq ($(CONFIG_NICNATSEMI), yes)
+FEATURE_CFLAGS += -D'CONFIG_NICNATSEMI=1'
+PROGRAMMER_OBJS += nicnatsemi.o
+NEED_PCI := yes
+endif
+
 ifeq ($(CONFIG_BUSPIRATE_SPI), yes)
 FEATURE_CFLAGS += -D'CONFIG_BUSPIRATE_SPI=1'
 PROGRAMMER_OBJS += buspirate_spi.o
Index: flashrom.c
===================================================================
--- flashrom.c	(revision 1028)
+++ flashrom.c	(working copy)
@@ -48,7 +48,7 @@ 
  * if more than one of them is selected. If only one is selected, it is clear
  * that the user wants that one to become the default.
  */
-#if CONFIG_NIC3COM+CONFIG_NICREALTEK+CONFIG_GFXNVIDIA+CONFIG_DRKAISER+CONFIG_SATASII+CONFIG_ATAHPT+CONFIG_FT2232_SPI+CONFIG_SERPROG+CONFIG_BUSPIRATE_SPI+CONFIG_DEDIPROG > 1
+#if CONFIG_NIC3COM+CONFIG_NICREALTEK+CONFIG_NICNATSEMI+CONFIG_GFXNVIDIA+CONFIG_DRKAISER+CONFIG_SATASII+CONFIG_ATAHPT+CONFIG_FT2232_SPI+CONFIG_SERPROG+CONFIG_BUSPIRATE_SPI+CONFIG_DEDIPROG > 1
 #error Please enable either CONFIG_DUMMY or CONFIG_INTERNAL or disable support for all programmers except one.
 #endif
 enum programmer programmer =
@@ -59,6 +59,9 @@ 
 	PROGRAMMER_NICREALTEK
 	PROGRAMMER_NICREALTEK2
 #endif
+#if CONFIG_NICNATSEMI == 1
+	PROGRAMMER_NICNATSEMI
+#endif
 #if CONFIG_GFXNVIDIA == 1
 	PROGRAMMER_GFXNVIDIA
 #endif
@@ -199,6 +202,24 @@ 
 	},
 #endif
 
+#if CONFIG_NICNATSEMI == 1
+	{
+		.name                   = "nicnatsemi",
+		.init                   = nicnatsemi_init,
+		.shutdown               = nicnatsemi_shutdown,
+		.map_flash_region       = fallback_map,
+		.unmap_flash_region     = fallback_unmap,
+		.chip_readb             = nicnatsemi_chip_readb,
+		.chip_readw             = fallback_chip_readw,
+		.chip_readl             = fallback_chip_readl,
+		.chip_readn             = fallback_chip_readn,
+		.chip_writeb            = nicnatsemi_chip_writeb,
+		.chip_writew            = fallback_chip_writew,
+		.chip_writel            = fallback_chip_writel,
+		.chip_writen            = fallback_chip_writen,
+		.delay                  = internal_delay,
+	},
+#endif
 
 #if CONFIG_GFXNVIDIA == 1
 	{
Index: nicnatsemi.c
===================================================================
--- nicnatsemi.c	(revision 0)
+++ nicnatsemi.c	(revision 0)
@@ -0,0 +1,70 @@ 
+/*
+ * This file is part of the flashrom project.
+ *
+ * Copyright (C) 2010 Andrew Morgan <ziltro@ziltro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#if defined(__i386__) || defined(__x86_64__)
+
+#include <stdlib.h>
+#include "flash.h"
+
+#define PCI_VENDOR_ID_NATSEMI	0x100b
+
+#define BOOT_ROM_ADDR		0x50
+#define BOOT_ROM_DATA		0x54
+
+struct pcidev_status nics_natsemi[] = {
+	{0x100b, 0x0020, NT, "National Semiconductor", "DP83815"},
+	{},
+};
+
+int nicnatsemi_init(void)
+{
+	get_io_perms();
+
+	io_base_addr = pcidev_init(PCI_VENDOR_ID_NATSEMI, PCI_BASE_ADDRESS_0,
+				   nics_natsemi, programmer_param);
+
+	buses_supported = CHIP_BUSTYPE_PARALLEL;
+
+	return 0;
+}
+
+int nicnatsemi_shutdown(void)
+{
+	free(programmer_param);
+	pci_cleanup(pacc);
+	release_io_perms();
+	return 0;
+}
+
+void nicnatsemi_chip_writeb(uint8_t val, chipaddr addr)
+{
+	OUTL((uint32_t)addr & 0x0000FFFF, io_base_addr + BOOT_ROM_ADDR);
+	OUTB(val, io_base_addr + BOOT_ROM_DATA);
+}
+
+uint8_t nicnatsemi_chip_readb(const chipaddr addr)
+{
+	OUTL(((uint32_t)addr & 0x0000FFFF), io_base_addr + BOOT_ROM_ADDR);
+	return INB(io_base_addr + BOOT_ROM_DATA);
+}
+
+#else
+#error PCI port I/O access is not supported on this architecture yet.
+#endif