This is the mail archive of the
ecos-patches@sourceware.org
mailing list for the eCos project.
dm9000 ethernet: interrupt support
- From: David Vrabel <dvrabel at arcom dot com>
- To: eCos Patches <ecos-patches at ecos dot sourceware dot org>
- Date: Mon, 07 Nov 2005 14:39:59 +0000
- Subject: dm9000 ethernet: interrupt support
Hi,
Attached patch adds support for using interrupts in the Davicom DM9000
ethernet driver. Tested on an PXA270 (ARM) platform.
David Vrabel
--
David Vrabel, Design Engineer
Arcom, Clifton Road Tel: +44 (0)1223 411200 ext. 3233
Cambridge CB1 7EA, UK Web: http://www.arcom.com/
Index: ecos-working/packages/devs/eth/davicom/dm9000/current/cdl/davicom_dm9000_eth_drivers.cdl
===================================================================
--- ecos-working.orig/packages/devs/eth/davicom/dm9000/current/cdl/davicom_dm9000_eth_drivers.cdl 2005-11-07 13:20:10.000000000 +0000
+++ ecos-working/packages/devs/eth/davicom/dm9000/current/cdl/davicom_dm9000_eth_drivers.cdl 2005-11-07 13:21:37.000000000 +0000
@@ -94,7 +94,7 @@
display "Additional compiler flags"
flavor data
no_define
- default_value { "" }
+ default_value { "-D_KERNEL -D__ECOS" }
description "
This option modifies the set of compiler flags for
building the Davicom DM9000 ethernet driver package.
Index: ecos-working/packages/devs/eth/davicom/dm9000/current/include/dm9000_info.h
===================================================================
--- ecos-working.orig/packages/devs/eth/davicom/dm9000/current/include/dm9000_info.h 2005-11-07 13:20:10.000000000 +0000
+++ ecos-working/packages/devs/eth/davicom/dm9000/current/include/dm9000_info.h 2005-11-07 13:21:37.000000000 +0000
@@ -61,9 +61,14 @@
unsigned long txkey;
volatile unsigned char *io_addr; // addr register
volatile unsigned char *io_data; // data register
+ cyg_vector_t interrupt; // Interrupt vector used by controller
int (*read_data)(struct dm9000 *p, cyg_uint8 *dest);
int (*write_data)(struct dm9000 *p, cyg_uint8 *src);
int buswidth;
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ cyg_handle_t interrupt_handle;
+ cyg_interrupt interrupt_object;
+#endif
};
#define CYGDAT_DEVS_ETH_DESCRIPTION "Davicom DM9000 Ethernet"
Index: ecos-working/packages/devs/eth/davicom/dm9000/current/src/if_dm9000.c
===================================================================
--- ecos-working.orig/packages/devs/eth/davicom/dm9000/current/src/if_dm9000.c 2005-11-07 13:20:10.000000000 +0000
+++ ecos-working/packages/devs/eth/davicom/dm9000/current/src/if_dm9000.c 2005-11-07 13:29:09.000000000 +0000
@@ -53,6 +53,7 @@
#include <pkgconf/system.h>
#include <pkgconf/io_eth_drivers.h>
#include <pkgconf/devs_eth_davicom_dm9000.h>
+
#include <cyg/infra/cyg_type.h>
#include <cyg/infra/cyg_ass.h>
#include <cyg/hal/hal_arch.h>
@@ -447,6 +448,19 @@
return 1;
}
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+static cyg_uint32 dm9000_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+ struct eth_drv_sc *sc = (struct eth_drv_sc *)data;
+ struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
+
+ cyg_drv_interrupt_mask(priv->interrupt);
+ cyg_drv_interrupt_acknowledge(priv->interrupt);
+
+ return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+}
+#endif
+
// ------------------------------------------------------------------------
//
@@ -480,6 +494,19 @@
if (id != 0x90000A46)
return 0;
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ cyg_drv_interrupt_create(priv->interrupt,
+ 0,
+ (cyg_addrword_t)sc,
+ dm9000_isr,
+ eth_drv_dsr,
+ &priv->interrupt_handle,
+ &priv->interrupt_object);
+ cyg_drv_interrupt_attach(priv->interrupt_handle);
+ cyg_drv_interrupt_acknowledge(priv->interrupt);
+ cyg_drv_interrupt_unmask(priv->interrupt);
+#endif // !CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
+
for (i = 0; i < 64; i++)
u16tab[i] = eeprom_read(priv, i);
@@ -683,6 +710,9 @@
save_len = total_len;
tail_extra = 0;
+ /* Disable all interrupts */
+ putreg(priv, DM_IMR, IMR_PAR);
+
HAL_WRITE_UINT8(priv->io_addr, DM_MWCMD);
while (total_len > 0) {
@@ -734,6 +764,9 @@
putreg(priv, DM_TXPLH, save_len >> 8);
putreg(priv, DM_TCR, TCR_TXREQ);
+
+ /* Re-enable interrupt */
+ putreg(priv, DM_IMR, IMR_PAR | IMR_PTM | IMR_PRM);
}
// ------------------------------------------------------------------------
@@ -853,7 +886,13 @@
static void
dm9000_deliver(struct eth_drv_sc *sc)
{
+ struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
+
dm9000_poll(sc);
+
+#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
+ cyg_drv_interrupt_unmask(priv->interrupt);
+#endif
}
// ------------------------------------------------------------------------
@@ -864,10 +903,9 @@
static int
dm9000_int_vector(struct eth_drv_sc *sc)
{
- struct dm9000 *priv;
- priv = (struct dm9000 *)sc->driver_private;
+ struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
- return -1;
+ return priv->interrupt;
}
Index: ecos-working/packages/devs/eth/davicom/dm9000/current/ChangeLog
===================================================================
--- ecos-working.orig/packages/devs/eth/davicom/dm9000/current/ChangeLog 2005-11-01 13:00:26.000000000 +0000
+++ ecos-working/packages/devs/eth/davicom/dm9000/current/ChangeLog 2005-11-07 13:28:26.000000000 +0000
@@ -1,3 +1,11 @@
+2005-11-07 David Vrabel <dvrabel@arcom.com>
+
+ * src/if_dm9000.c, include/dm9000_info.h: Support interrupts.
+
+ * cdl/davicom_dm9000_eth_drivers.cdl
+ (CYGPKG_DEVS_ETH_DAVICOM_DM9000_CFLAGS_ADD): Need _KERNEL and
+ __ECOS defined for non-stand-alone builds.
+
2005-10-25 David Vrabel <dvrabel@arcom.com>
* src/if_dm9000.c (eeprom_read, eeprom_write, eeprom_reload):