<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>change log for rtems (2011-06-17)</title>
</head>
<body text='#000000' bgcolor='#ffffff'>
<a name='cs1'></a>
<table border='0' cellspacing='0' cellpadding='5' width='100%' bgcolor='#eeeeee'>
<tr><td colspan='3' bgcolor='#dddddd'>
<font color='#bb2222'><strong>sh</strong></font>
</td></tr>
<tr><td colspan='3' bgcolor='#dddddd'><pre>2011-06-17 Sebastian Huber <sebastian.huber@embedded-brains.de>
* Makefile.am: Added custom memcpy(). Update for network sources.
* configure.ac: Enable interrupt driven Termios for all BSPs.
* ide/pcmcia_ide.c: Disable broken DMA support.
* include/bsp.h: Fixed NEED_LOW_LEVEL_INIT define. Set default
console baud to 115200.
* include/irq.h, irq/irq.c: Fixed interrupt handling to avoid the
following problems: 1. multiple invokation of peripheral interrupt
handlers, 2. missing synchronization after mask write and enabling of
external exceptions, and 3. logic overhead.
* network_5200/network.c: Added MII interface. Fixed controller
restart after FIFO errors. Performance improvements.
* start/start.S: Fixed ROM startup. Initialize XLB arbiter for all
BSPs.
* startup/bspstart.c: Special intialization for MPC5200B (B variant).
Install standard alignment handler.
* startup/cpuinit.c, startup/linkcmds.brs5l, startup/linkcmds.dp2,
startup/linkcmds.icecube, startup/linkcmds.pm520_cr825,
startup/linkcmds.pm520_ze30: Avoid accesses outside the RAM area.
</pre></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/c/src/lib/libbsp/powerpc/gen5200/ChangeLog.diff?r1=text&tr1=1.155&r2=text&tr2=1.156&diff_format=h">M</a></td><td width='1%'>1.156</td><td width='100%'>c/src/lib/libbsp/powerpc/gen5200/ChangeLog</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/c/src/lib/libbsp/powerpc/gen5200/Makefile.am.diff?r1=text&tr1=1.43&r2=text&tr2=1.44&diff_format=h">M</a></td><td width='1%'>1.44</td><td width='100%'>c/src/lib/libbsp/powerpc/gen5200/Makefile.am</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/c/src/lib/libbsp/powerpc/gen5200/configure.ac.diff?r1=text&tr1=1.21&r2=text&tr2=1.22&diff_format=h">M</a></td><td width='1%'>1.22</td><td width='100%'>c/src/lib/libbsp/powerpc/gen5200/configure.ac</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/c/src/lib/libbsp/powerpc/gen5200/ide/pcmcia_ide.c.diff?r1=text&tr1=1.13&r2=text&tr2=1.14&diff_format=h">M</a></td><td width='1%'>1.14</td><td width='100%'>c/src/lib/libbsp/powerpc/gen5200/ide/pcmcia_ide.c</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/c/src/lib/libbsp/powerpc/gen5200/include/bsp.h.diff?r1=text&tr1=1.26&r2=text&tr2=1.27&diff_format=h">M</a></td><td width='1%'>1.27</td><td width='100%'>c/src/lib/libbsp/powerpc/gen5200/include/bsp.h</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/c/src/lib/libbsp/powerpc/gen5200/include/irq.h.diff?r1=text&tr1=1.3&r2=text&tr2=1.4&diff_format=h">M</a></td><td width='1%'>1.4</td><td width='100%'>c/src/lib/libbsp/powerpc/gen5200/include/irq.h</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/c/src/lib/libbsp/powerpc/gen5200/irq/irq.c.diff?r1=text&tr1=1.23&r2=text&tr2=1.24&diff_format=h">M</a></td><td width='1%'>1.24</td><td width='100%'>c/src/lib/libbsp/powerpc/gen5200/irq/irq.c</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/c/src/lib/libbsp/powerpc/gen5200/network_5200/network.c.diff?r1=text&tr1=1.14&r2=text&tr2=1.15&diff_format=h">M</a></td><td width='1%'>1.15</td><td width='100%'>c/src/lib/libbsp/powerpc/gen5200/network_5200/network.c</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/c/src/lib/libbsp/powerpc/gen5200/start/start.S.diff?r1=text&tr1=1.15&r2=text&tr2=1.16&diff_format=h">M</a></td><td width='1%'>1.16</td><td width='100%'>c/src/lib/libbsp/powerpc/gen5200/start/start.S</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/c/src/lib/libbsp/powerpc/gen5200/startup/bspstart.c.diff?r1=text&tr1=1.32&r2=text&tr2=1.33&diff_format=h">M</a></td><td width='1%'>1.33</td><td width='100%'>c/src/lib/libbsp/powerpc/gen5200/startup/bspstart.c</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/c/src/lib/libbsp/powerpc/gen5200/startup/cpuinit.c.diff?r1=text&tr1=1.10&r2=text&tr2=1.11&diff_format=h">M</a></td><td width='1%'>1.11</td><td width='100%'>c/src/lib/libbsp/powerpc/gen5200/startup/cpuinit.c</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.brs5l.diff?r1=text&tr1=1.8&r2=text&tr2=1.9&diff_format=h">M</a></td><td width='1%'>1.9</td><td width='100%'>c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.brs5l</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.dp2.diff?r1=text&tr1=1.1&r2=text&tr2=1.2&diff_format=h">M</a></td><td width='1%'>1.2</td><td width='100%'>c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.dp2</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.icecube.diff?r1=text&tr1=1.4&r2=text&tr2=1.5&diff_format=h">M</a></td><td width='1%'>1.5</td><td width='100%'>c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.icecube</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.pm520_cr825.diff?r1=text&tr1=1.1&r2=text&tr2=1.2&diff_format=h">M</a></td><td width='1%'>1.2</td><td width='100%'>c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.pm520_cr825</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.pm520_ze30.diff?r1=text&tr1=1.1&r2=text&tr2=1.2&diff_format=h">M</a></td><td width='1%'>1.2</td><td width='100%'>c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.pm520_ze30</td></tr>
</table>
<pre>
<font color='#006600'>diff -u rtems/c/src/lib/libbsp/powerpc/gen5200/ChangeLog:1.155 rtems/c/src/lib/libbsp/powerpc/gen5200/ChangeLog:1.156
--- rtems/c/src/lib/libbsp/powerpc/gen5200/ChangeLog:1.155 Tue Jun 7 08:38:54 2011
+++ rtems/c/src/lib/libbsp/powerpc/gen5200/ChangeLog Fri Jun 17 06:58:41 2011
</font><font color='#997700'>@@ -1,3 +1,24 @@
</font><font color='#000088'>+2011-06-17 Sebastian Huber <sebastian.huber@embedded-brains.de>
+
+ * Makefile.am: Added custom memcpy(). Update for network sources.
+ * configure.ac: Enable interrupt driven Termios for all BSPs.
+ * ide/pcmcia_ide.c: Disable broken DMA support.
+ * include/bsp.h: Fixed NEED_LOW_LEVEL_INIT define. Set default
+ console baud to 115200.
+ * include/irq.h, irq/irq.c: Fixed interrupt handling to avoid the
+ following problems: 1. multiple invokation of peripheral interrupt
+ handlers, 2. missing synchronization after mask write and enabling of
+ external exceptions, and 3. logic overhead.
+ * network_5200/network.c: Added MII interface. Fixed controller
+ restart after FIFO errors. Performance improvements.
+ * start/start.S: Fixed ROM startup. Initialize XLB arbiter for all
+ BSPs.
+ * startup/bspstart.c: Special intialization for MPC5200B (B variant).
+ Install standard alignment handler.
+ * startup/cpuinit.c, startup/linkcmds.brs5l, startup/linkcmds.dp2,
+ startup/linkcmds.icecube, startup/linkcmds.pm520_cr825,
+ startup/linkcmds.pm520_ze30: Avoid accesses outside the RAM area.
+
</font> 2011-06-07 Sebastian Huber <sebastian.huber@embedded-brains.de>
* configure.ac, startup/bspstart.c: Use standard cache BSP options.
<font color='#006600'>diff -u rtems/c/src/lib/libbsp/powerpc/gen5200/Makefile.am:1.43 rtems/c/src/lib/libbsp/powerpc/gen5200/Makefile.am:1.44
--- rtems/c/src/lib/libbsp/powerpc/gen5200/Makefile.am:1.43 Thu Dec 30 07:04:23 2010
+++ rtems/c/src/lib/libbsp/powerpc/gen5200/Makefile.am Fri Jun 17 06:58:41 2011
</font><font color='#997700'>@@ -142,17 +142,13 @@
</font> startup/bspreset.c \
../../shared/bspgetworkarea.c \
../shared/startup/bspidle.c \
<font color='#000088'>+ ../shared/src/memcpy.c \
</font> startup/bspstart.c \
startup/cpuinit.c \
startup/uboot_support.c
if HAS_NETWORKING
<font color='#880000'>-network_CPPFLAGS = -D__INSIDE_RTEMS_BSD_TCPIP_STACK__
-network_CPPFLAGS += -D__BSD_VISIBLE
-noinst_PROGRAMS += network.rel
-network_rel_SOURCES = network_5200/network.c
-network_rel_CPPFLAGS = $(AM_CPPFLAGS) $(network_CPPFLAGS)
-network_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
</font><font color='#000088'>+libbsp_a_SOURCES += network_5200/network.c
</font> endif
libbsp_a_LIBADD = ../../../libcpu/@RTEMS_CPU@/shared/cpuIdent.rel \
<font color='#997700'>@@ -163,9 +159,5 @@
</font> ../../../libcpu/@RTEMS_CPU@/mpc6xx/mmu.rel \
../../../libcpu/@RTEMS_CPU@/mpc6xx/timer.rel
<font color='#880000'>-if HAS_NETWORKING
-libbsp_a_LIBADD += network.rel
-endif
-
</font> include $(srcdir)/preinstall.am
include $(top_srcdir)/../../../../automake/local.am
<font color='#006600'>diff -u rtems/c/src/lib/libbsp/powerpc/gen5200/configure.ac:1.21 rtems/c/src/lib/libbsp/powerpc/gen5200/configure.ac:1.22
--- rtems/c/src/lib/libbsp/powerpc/gen5200/configure.ac:1.21 Tue Jun 7 08:38:54 2011
+++ rtems/c/src/lib/libbsp/powerpc/gen5200/configure.ac Fri Jun 17 06:58:41 2011
</font><font color='#997700'>@@ -82,11 +82,10 @@
</font> RTEMS_BSPOPTS_SET([MPC5200_PSC_INDEX_FOR_GPS_MODULE],[dp2],[5])
RTEMS_BSPOPTS_HELP([MPC5200_PSC_INDEX_FOR_GPS_MODULE],[PSC index for GPS module, if defined results in '/dev/gps'])
<font color='#880000'>-RTEMS_BSPOPTS_SET([SINGLE_CHAR_MODE],[dp2],[])
-RTEMS_BSPOPTS_SET([SINGLE_CHAR_MODE],[*],[1])
</font><font color='#000088'>+RTEMS_BSPOPTS_SET([SINGLE_CHAR_MODE],[*],[])
</font> RTEMS_BSPOPTS_HELP([SINGLE_CHAR_MODE],[enable single character mode for the PSC console driver])
<font color='#880000'>-RTEMS_BSPOPTS_SET([UARTS_USE_TERMIOS_INT],[dp2],[1])
</font><font color='#000088'>+RTEMS_BSPOPTS_SET([UARTS_USE_TERMIOS_INT],[*],[1])
</font> RTEMS_BSPOPTS_HELP([UARTS_USE_TERMIOS_INT],[enable interrupt support for the PSC console driver])
RTEMS_BSPOPTS_SET([PRINTK_MINOR],[dp2],[1])
<font color='#006600'>diff -u rtems/c/src/lib/libbsp/powerpc/gen5200/ide/pcmcia_ide.c:1.13 rtems/c/src/lib/libbsp/powerpc/gen5200/ide/pcmcia_ide.c:1.14
--- rtems/c/src/lib/libbsp/powerpc/gen5200/ide/pcmcia_ide.c:1.13 Mon Nov 15 04:55:02 2010
+++ rtems/c/src/lib/libbsp/powerpc/gen5200/ide/pcmcia_ide.c Fri Jun 17 06:58:41 2011
</font><font color='#997700'>@@ -92,23 +92,13 @@
</font> #endif
#define IDE_DMA_TEST FALSE
<font color='#880000'>-#ifdef BRS5L
-#define IDE_USE_INT TRUE
-#define IDE_READ_USE_DMA TRUE
-#define IDE_USE_READ_PIO_OPT FALSE
-#define IDE_WRITE_USE_DMA TRUE
-#define IDE_USE_WRITE_PIO_OPT TRUE
-/* #define IDE_USE_DMA (IDE_READ_USE_DMA||IDE_WRITE_USE_DMA) */
-#define IDE_USE_DMA TRUE
-#else
</font><font color='#000088'>+/* DMA supported PIO mode is broken */
</font> #define IDE_USE_INT TRUE
#define IDE_READ_USE_DMA FALSE
#define IDE_USE_READ_PIO_OPT FALSE
#define IDE_WRITE_USE_DMA FALSE
#define IDE_USE_WRITE_PIO_OPT FALSE
<font color='#880000'>-/* #define IDE_USE_DMA (IDE_READ_USE_DMA||IDE_WRITE_USE_DMA) */
-#define IDE_USE_DMA FALSE
-#endif
</font><font color='#000088'>+#define IDE_USE_DMA (IDE_READ_USE_DMA || IDE_WRITE_USE_DMA)
</font>
#define IDE_USE_STATISTICS TRUE
<font color='#997700'>@@ -464,6 +454,7 @@
</font> (*cbuf)++;
(*pos) += bufs[bufs_from_dma].length;
bufs_from_dma++;
<font color='#000088'>+ bds_free++;
</font> }
} while ((nxt_bd_idx != TASK_ERR_BD_RING_EMPTY) &&
(nxt_bd_idx != TASK_ERR_BD_BUSY) &&
<font color='#006600'>diff -u rtems/c/src/lib/libbsp/powerpc/gen5200/include/bsp.h:1.26 rtems/c/src/lib/libbsp/powerpc/gen5200/include/bsp.h:1.27
--- rtems/c/src/lib/libbsp/powerpc/gen5200/include/bsp.h:1.26 Thu Dec 30 07:04:23 2010
+++ rtems/c/src/lib/libbsp/powerpc/gen5200/include/bsp.h Fri Jun 17 06:58:41 2011
</font><font color='#997700'>@@ -79,6 +79,11 @@
</font> #define PM520
#endif
<font color='#000088'>+#if !defined(HAS_UBOOT)
+ /* we need the low level initialization in start.S*/
+ #define NEED_LOW_LEVEL_INIT
+#endif
+
</font> #if defined(BRS5L)
/*
* IMD Custom Board BRS5L
<font color='#997700'>@@ -118,11 +123,6 @@
</font> #include <bsp/vectors.h>
#include <bsp/u-boot.h>
<font color='#880000'>-#if !defined(HAS_UBOOT)
- /* we need the low level initialization in start.S*/
- #define NEED_LOW_LEVEL_INIT
-#endif
-
</font> /*
* Network driver configuration
*/
<font color='#997700'>@@ -179,7 +179,7 @@
</font> #if defined(HAS_UBOOT)
#define GEN5200_CONSOLE_BAUD (bsp_uboot_board_info.bi_baudrate)
#else
<font color='#880000'>-#define GEN5200_CONSOLE_BAUD 9600
</font><font color='#000088'>+#define GEN5200_CONSOLE_BAUD 115200
</font> #endif
/*
<font color='#006600'>diff -u rtems/c/src/lib/libbsp/powerpc/gen5200/include/irq.h:1.3 rtems/c/src/lib/libbsp/powerpc/gen5200/include/irq.h:1.4
--- rtems/c/src/lib/libbsp/powerpc/gen5200/include/irq.h:1.3 Fri Jan 28 14:29:51 2011
+++ rtems/c/src/lib/libbsp/powerpc/gen5200/include/irq.h Fri Jun 17 06:58:41 2011
</font><font color='#997700'>@@ -87,16 +87,13 @@
</font> #ifndef LIBBSP_POWERPC_GEN5200_IRQ_H
#define LIBBSP_POWERPC_GEN5200_IRQ_H
<font color='#880000'>-#define CHK_CE_SHADOW(_pmce) ((_pmce) & 0x00000001)
-#define CHK_CSE_STICKY(_pmce) (((_pmce) >> 10) & 0x00000001)
-#define CHK_MSE_STICKY(_pmce) (((_pmce) >> 21) & 0x00000001)
-#define CHK_PSE_STICKY(_pmce) (((_pmce) >> 29) & 0x00000001)
-#define CLR_CSE_STICKY(_pmce) ((_pmce) |= (1 << 29 ))
-#define CLR_MSE_STICKY(_pmce) ((_pmce) |= (1 << 21 ))
-#define CLR_PSE_STICKY(_pmce) ((_pmce) |= (1 << 10 ))
-#define CSE_SOURCE(_source) (((_source) >> 8) & 0x00000003)
-#define MSE_SOURCE(_source) (((_source) >> 16) & 0x0000001F)
-#define PSE_SOURCE(_source) (((_source) >> 24) & 0x0000001F)
</font><font color='#000088'>+#define PMCE_CE_SHADOW (1U << (31 - 31))
+#define PMCE_CSE_STICKY (1U << (31 - 21))
+#define PMCE_MSE_STICKY (1U << (31 - 10))
+#define PMCE_PSE_STICKY (1U << (31 - 2))
+#define PMCE_CSE_SOURCE(_pmce) (((_pmce) >> 8) & 0x3U)
+#define PMCE_MSE_SOURCE(_pmce) (((_pmce) >> 16) & 0x1fU)
+#define PMCE_PSE_SOURCE(_pmce) (((_pmce) >> 24) & 0x1fU)
</font>
/*
* Peripheral IRQ handlers related definitions
<font color='#006600'>diff -u rtems/c/src/lib/libbsp/powerpc/gen5200/irq/irq.c:1.23 rtems/c/src/lib/libbsp/powerpc/gen5200/irq/irq.c:1.24
--- rtems/c/src/lib/libbsp/powerpc/gen5200/irq/irq.c:1.23 Fri Jan 28 14:29:51 2011
+++ rtems/c/src/lib/libbsp/powerpc/gen5200/irq/irq.c Fri Jun 17 06:58:41 2011
</font><font color='#997700'>@@ -171,10 +171,6 @@
</font> uint8_t lo_hi_ind = 0,
prio_index_offset;
uint32_t *reg;
<font color='#880000'>- volatile uint32_t per_pri_1,
- main_pri_1,
- crit_pri_main_mask,
- per_mask;
</font>
/* calculate the index offset of priority value bit field */
prio_index_offset = (irqLine - BSP_PER_IRQ_LOWEST_OFFSET) % 8;
<font color='#997700'>@@ -223,11 +219,11 @@
</font> /* enable (unmask) peripheral interrupt */
mpc5200.per_mask &= ~(0x80000000 >> SIU_MaskBit [irqLine]);
<font color='#880000'>- main_pri_1 = mpc5200.main_pri_1;
- crit_pri_main_mask = mpc5200.crit_pri_main_mask;
- per_pri_1 = mpc5200.per_pri_1;
- per_mask = mpc5200.per_mask;
-
</font><font color='#000088'>+ /* FIXME: Why? */
+ mpc5200.main_pri_1;
+ mpc5200.crit_pri_main_mask;
+ mpc5200.per_pri_1;
+ mpc5200.per_mask;
</font> }
static inline void BSP_enable_main_irq_at_siu(
<font color='#997700'>@@ -484,15 +480,15 @@
</font> {
#if (ALLOW_IRQ_NESTING == 1)
uint32_t msr;
<font color='#000088'>+ uint32_t mask = *maskreg;
</font> #endif
<font color='#880000'>- uint32_t mask = *maskreg;
-
</font> irq += offset;
<font color='#880000'>- *maskreg = mask | irqMaskTable [irq];
-
</font> #if (ALLOW_IRQ_NESTING == 1)
<font color='#000088'>+ *maskreg = mask | irqMaskTable [irq];
+ /* Make sure that the write operation completed (cache inhibited area) */
+ *maskreg;
</font> msr = ppc_external_exceptions_enable();
#endif
<font color='#997700'>@@ -500,9 +496,8 @@
</font>
#if (ALLOW_IRQ_NESTING == 1)
ppc_external_exceptions_disable(msr);
<font color='#000088'>+ *maskreg = mask;
</font> #endif
<font color='#880000'>-
- *maskreg = mask;
</font> }
/*
<font color='#997700'>@@ -526,151 +521,92 @@
</font> printk( "not counting %d\n", excNum);
#endif
<font color='#880000'>- switch (excNum) {
- /*
- * Handle decrementer interrupt
- */
- case ASM_DEC_VECTOR:
-
- /* Dispatch interrupt handlers */
- bsp_interrupt_handler_dispatch( BSP_DECREMENTER);
-
- break;
</font><font color='#000088'>+ /* get the content of main interrupt status register */
+ pmce = mpc5200.pmce;
</font>
<font color='#880000'>- case ASM_EXT_VECTOR:
- case ASM_60X_SYSMGMT_VECTOR:
- /* get the content of main interrupt status register */
- pmce = mpc5200.pmce;
</font><font color='#000088'>+ /* critical interrupts are routed to the core_int, see premature
+ * initialization
+ */
+ while ((pmce & (PMCE_CSE_STICKY | PMCE_MSE_STICKY)) != 0) {
+ /* first: check for critical interrupt sources (hierarchical order)
+ * -> HI_int indicates peripheral sources
+ */
+ if ((pmce & PMCE_CSE_STICKY) != 0) {
+ /* get source of critical interrupt */
+ irq = PMCE_CSE_SOURCE(pmce);
+
+ switch (irq) {
+ /* peripheral HI_int interrupt source detected */
+ case 2:
+ /* check for valid peripheral interrupt source */
+ if ((pmce & PMCE_PSE_STICKY) != 0) {
+ /* get source of peripheral interrupt */
+ irq = PMCE_PSE_SOURCE(pmce);
+
+ dispatch(irq, BSP_PER_IRQ_LOWEST_OFFSET, &mpc5200.per_mask);
+ } else {
+ /* this case may not occur: no valid peripheral
+ * interrupt source */
+ printk( "No valid peripheral HI_int interrupt source\n");
+ }
+ break;
</font>
<font color='#880000'>- /* critical interrupts may be routed to the core_int
- * dependent on premature initialization, see bit 31 (CEbsH)
- */
- while ((CHK_CE_SHADOW( pmce) && CHK_CSE_STICKY( pmce))
- || CHK_MSE_STICKY( pmce) || CHK_PSE_STICKY( pmce)) {
</font><font color='#000088'>+ /* irq0, slice timer 1 or ccs wakeup detected */
+ case 0:
+ case 1:
+ case 3:
+
+ /* add proper offset for critical interrupts in the siu
+ * handler array */
+ irq += BSP_CRIT_IRQ_LOWEST_OFFSET;
+
+ /* Dispatch interrupt handlers */
+ bsp_interrupt_handler_dispatch( irq);
+
+ break;
+
+ default:
+ /* error: unknown interrupt source */
+ printk( "Unknown HI_int interrupt source\n");
+ break;
+ }
+ }
</font>
<font color='#880000'>- /* first: check for critical interrupt sources (hierarchical order)
- * -> HI_int indicates peripheral sources
- */
- if (CHK_CE_SHADOW( pmce) && CHK_CSE_STICKY( pmce)) {
- /* get source of critical interrupt */
- irq = CSE_SOURCE( pmce);
- switch (irq) {
- /* irq0, slice timer 1 or ccs wakeup detected */
- case 0:
- case 1:
- case 3:
-
- /* add proper offset for critical interrupts in the siu
- * handler array */
- irq += BSP_CRIT_IRQ_LOWEST_OFFSET;
-
- /* Dispatch interrupt handlers */
- bsp_interrupt_handler_dispatch( irq);
-
- break;
-
- /* peripheral HI_int interrupt source detected */
- case 2:
- /* check for valid peripheral interrupt source */
- if (CHK_PSE_STICKY( pmce)) {
- /* get source of peripheral interrupt */
- irq = PSE_SOURCE( pmce);
-
- dispatch(irq, BSP_PER_IRQ_LOWEST_OFFSET, &mpc5200.per_mask);
-
- /* force re-evaluation of peripheral interrupts */
- CLR_PSE_STICKY( mpc5200.pmce);
- } else {
- /* this case may not occur: no valid peripheral
- * interrupt source */
- printk( "No valid peripheral HI_int interrupt source\n");
- }
- break;
- default:
- /* error: unknown interrupt source */
- printk( "Unknown HI_int interrupt source\n");
- break;
</font><font color='#000088'>+ /* second: check for main interrupt sources (hierarchical order)
+ * -> LO_int indicates peripheral sources */
+ if ((pmce & PMCE_MSE_STICKY) != 0) {
+ /* get source of main interrupt */
+ irq = PMCE_MSE_SOURCE(pmce);
+
+ if (irq == 4) {
+ /* peripheral LO_int interrupt source detected */
+ /* check for valid peripheral interrupt source */
+ if ((pmce & PMCE_PSE_STICKY) != 0) {
+ /* get source of peripheral interrupt */
+ irq = PMCE_PSE_SOURCE(pmce);
+
+ dispatch(irq, BSP_PER_IRQ_LOWEST_OFFSET, &mpc5200.per_mask);
+ } else {
+ /* this case may not occur: no valid peripheral
+ * interrupt source */
+ printk( "No valid peripheral LO_int interrupt source\n");
</font> }
<font color='#880000'>- /* force re-evaluation of critical interrupts */
- CLR_CSE_STICKY( mpc5200.pmce);
- }
-
- /* second: check for main interrupt sources (hierarchical order)
- * -> LO_int indicates peripheral sources */
- if (CHK_MSE_STICKY( pmce)) {
- /* get source of main interrupt */
- irq = MSE_SOURCE( pmce);
-
- switch (irq) {
-
- /* irq1-3, RTC, GPIO, TMR0-7 detected (attention: slice timer
- * 2 is always routed to SMI) */
- case 0:
- case 1:
- case 2:
- case 3:
- case 5:
- case 6:
- case 7:
- case 8:
- case 9:
- case 10:
- case 11:
- case 12:
- case 13:
- case 14:
- case 15:
- case 16:
- dispatch(irq, BSP_MAIN_IRQ_LOWEST_OFFSET, &mpc5200.crit_pri_main_mask);
- break;
-
- /* peripheral LO_int interrupt source detected */
- case 4:
- /* check for valid peripheral interrupt source */
- if (CHK_PSE_STICKY( pmce)) {
- /* get source of peripheral interrupt */
- irq = PSE_SOURCE( pmce);
-
- dispatch(irq, BSP_PER_IRQ_LOWEST_OFFSET, &mpc5200.per_mask);
-
- /* force re-evaluation of peripheral interrupts */
- CLR_PSE_STICKY( mpc5200.pmce);
- } else {
- /* this case may not occur: no valid peripheral
- * interrupt source */
- printk( "No valid peripheral LO_int interrupt source\n");
- }
- break;
-
- /* error: unknown interrupt source */
- default:
- printk( "Unknown peripheral LO_int interrupt source\n");
- break;
- }
- /* force re-evaluation of main interrupts */
- CLR_MSE_STICKY( mpc5200.pmce);
- }
-
- if (CHK_PSE_STICKY( pmce)) {
- /* get source of peripheral interrupt */
- irq = PSE_SOURCE( pmce);
-
- dispatch(irq, BSP_PER_IRQ_LOWEST_OFFSET, &mpc5200.per_mask);
-
- /* force re-evaluation of peripheral interrupts */
- CLR_PSE_STICKY( mpc5200.pmce);
- }
-
- /* get the content of main interrupt status register */
- pmce = mpc5200.pmce;
</font><font color='#000088'>+ } else if (irq <= 16) {
+ /* irq1-3, RTC, GPIO, TMR0-7 detected (attention: slice timer
+ * 2 is always routed to SMI) */
+ dispatch(irq, BSP_MAIN_IRQ_LOWEST_OFFSET, &mpc5200.crit_pri_main_mask);
+ } else {
+ /* error: unknown interrupt source */
+ printk( "Unknown peripheral LO_int interrupt source\n");
</font> }
<font color='#880000'>- break;
</font><font color='#000088'>+ }
</font>
<font color='#880000'>- default:
- printk( "Unknown processor exception\n");
- break;
</font><font color='#000088'>+ /* force re-evaluation of interrupts */
+ mpc5200.pmce = PMCE_CSE_STICKY | PMCE_MSE_STICKY | PMCE_PSE_STICKY;
</font>
<font color='#880000'>- } /* end of switch( excNum) */
</font><font color='#000088'>+ /* get the content of main interrupt status register */
+ pmce = mpc5200.pmce;
+ }
</font>
#if (BENCHMARK_IRQ_PROCESSING == 1)
stop = PPC_Get_timebase_register();
<font color='#997700'>@@ -771,9 +707,6 @@
</font> if (ppc_exc_set_handler( ASM_EXT_VECTOR, C_dispatch_irq_handler)) {
return RTEMS_IO_ERROR;
}
<font color='#880000'>- if (ppc_exc_set_handler( ASM_DEC_VECTOR, C_dispatch_irq_handler)) {
- return RTEMS_IO_ERROR;
- }
</font> if (ppc_exc_set_handler( ASM_E300_SYSMGMT_VECTOR, C_dispatch_irq_handler)) {
return RTEMS_IO_ERROR;
}
<font color='#006600'>diff -u rtems/c/src/lib/libbsp/powerpc/gen5200/network_5200/network.c:1.14 rtems/c/src/lib/libbsp/powerpc/gen5200/network_5200/network.c:1.15
--- rtems/c/src/lib/libbsp/powerpc/gen5200/network_5200/network.c:1.14 Mon Nov 15 04:55:02 2010
+++ rtems/c/src/lib/libbsp/powerpc/gen5200/network_5200/network.c Fri Jun 17 06:58:41 2011
</font><font color='#997700'>@@ -53,10 +53,16 @@
</font> * Copyright (c) 1999, National Research Council of Canada
*
*/
<font color='#000088'>+
+#define __INSIDE_RTEMS_BSD_TCPIP_STACK__ 1
+#define __BSD_VISIBLE 1
+
</font> #include <rtems.h>
#include <rtems/error.h>
#include <rtems/rtems_bsdnet.h>
<font color='#000088'>+#include <rtems/rtems_mii_ioctl.h>
</font> #include <stdio.h>
<font color='#000088'>+#include <inttypes.h>
</font> #include <sys/param.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
<font color='#997700'>@@ -66,43 +72,23 @@
</font> #include <netinet/if_ether.h>
#include <bsp.h>
#include <bsp/irq.h>
<font color='#880000'>-#include "../include/mpc5200.h"
</font><font color='#000088'>+#include <bsp/mpc5200.h>
</font> #include <net/if_var.h>
#include <errno.h>
<font color='#880000'>-/* motorola-capi-specifics... */
-#include "../bestcomm/include/ppctypes.h" /* uint32, et. al. */
-#include "../bestcomm/dma_image.h"
-#include "../bestcomm/bestcomm_glue.h"
-
-
-#define SDMA_BD_TFD 0x08000000 /*< Transmit Frame Done */
-#define SDMA_BD_INT 0x04000000 /*< Interrupt on frame done */
-#define SDMA_BD_RX_NUM 64 /* Number of receive buffer descriptors */
-#define SDMA_BD_TX_NUM 64 /* Number of transmit buffer descriptors */
-
-#define SET_BD_STATUS(bd, stat) { \
- (bd)->Status &= 0x0000ffff; \
- (bd)->Status |= 0xffff0000 & stat; \
-}
-#define SET_BD_LENGTH(bd, len) { \
- (bd)->Status &= 0xffff0000; \
- (bd)->Status |= 0x0000ffff & len; \
-}
-#define GET_BD_STATUS(bd) ((bd)->Status & 0xffff0000)
-#define GET_BD_LENGTH(bd) ((bd)->Status & 0x0000ffff)
-#define GET_SDMA_PENDINGBIT(Bit) \
- (mpc5200.sdma.IntPend & (uint32)(1<<Bit))
-
-#include "../bestcomm/bestcomm_api.h"
-#include "../bestcomm/task_api/bestcomm_cntrl.h"
-#include "../bestcomm/task_api/tasksetup_bdtable.h"
-
-static TaskId rxTaskId; /* SDMA RX task ID */
-static TaskId txTaskId; /* SDMA TX task ID */
</font><font color='#000088'>+#include <bsp/bestcomm/include/ppctypes.h>
+#include <bsp/bestcomm/dma_image.h>
+#include <bsp/bestcomm/bestcomm_glue.h>
+#include <bsp/bestcomm/bestcomm_api.h>
+#include <bsp/bestcomm/task_api/bestcomm_cntrl.h>
+#include <bsp/bestcomm/task_api/tasksetup_bdtable.h>
</font>
/* #define ETH_DEBUG */
<font color='#000088'>+#define FEC_BD_LAST TASK_BD_TFD
+#define FEC_BD_INT TASK_BD_INT
+#define FEC_BD_READY SDMA_BD_MASK_READY
+
</font> /*
* Number of interfaces supported by this driver
*/
<font color='#997700'>@@ -113,25 +99,12 @@
</font> * The number of transmit buffer descriptors has to be quite large
* since a single frame often uses four or more buffer descriptors.
*/
<font color='#880000'>-#define RX_BUF_COUNT SDMA_BD_RX_NUM
-#define TX_BUF_COUNT SDMA_BD_TX_NUM
-#define TX_BD_PER_BUF 1
</font><font color='#000088'>+#define RX_BUF_COUNT 64
+#define TX_BUF_COUNT 64
</font>
#define INET_ADDR_MAX_BUF_SIZE (sizeof "255.255.255.255")
<font color='#880000'>-
-/*
- * RTEMS event used by interrupt handler to signal daemons.
- * This must *not* be the same event used by the TCP/IP task synchronization.
- */
-#define INTERRUPT_EVENT RTEMS_EVENT_1
-#define FATAL_INT_EVENT RTEMS_EVENT_3
-
-/*
- * RTEMS event used to start transmit daemon.
- * This must not be the same as INTERRUPT_EVENT.
- */
-#define START_TRANSMIT_EVENT RTEMS_EVENT_2
</font><font color='#000088'>+#define FEC_EVENT RTEMS_EVENT_0
</font>
/* Task number assignment */
#define FEC_RECV_TASK_NO TASK_FEC_RX
<font color='#997700'>@@ -186,31 +159,24 @@
</font> #define MPC5200_FEC_MII_DATA_RA_SHIFT 0x12 /* MII Register address bits */
#define MPC5200_FEC_MII_DATA_PA_SHIFT 0x17 /* MII PHY address bits */
<font color='#880000'>-
-/* Receive & Transmit Buffer Descriptor definitions */
-typedef struct mpc5200_buffer_desc_
- {
- volatile uint16_t status;
- volatile uint16_t length;
- volatile void *buffer;
- } mpc5200_buffer_desc_t;
-
-
</font> #define FEC_INTR_MASK_USED \
(FEC_INTR_LCEN |FEC_INTR_CRLEN |\
FEC_INTR_XFUNEN|FEC_INTR_XFERREN|FEC_INTR_RFERREN)
<font color='#000088'>+typedef enum {
+ FEC_STATE_RESTART_0,
+ FEC_STATE_RESTART_1,
+ FEC_STATE_NORMAL,
+} mpc5200_fec_state;
+
</font> /*
* Device data
*/
<font color='#880000'>-struct mpc5200_enet_struct {
-#if 0
- struct ifnet ac_if;
-#else
</font><font color='#000088'>+typedef struct {
</font> struct arpcom arpcom;
<font color='#880000'>-#endif
</font> struct mbuf **rxMbuf;
struct mbuf **txMbuf;
<font color='#000088'>+ mpc5200_fec_state state;
</font> int acceptBroadcast;
int rxBdCount;
int txBdCount;
<font color='#997700'>@@ -226,83 +192,60 @@
</font> unsigned long rxGiant;
unsigned long rxNonOctet;
unsigned long rxBadCRC;
<font color='#880000'>- unsigned long rxOverrun;
</font><font color='#000088'>+ unsigned long rxFIFOError;
</font> unsigned long rxCollision;
unsigned long txInterrupts;
unsigned long txDeferred;
unsigned long txLateCollision;
unsigned long txUnderrun;
<font color='#000088'>+ unsigned long txFIFOError;
</font> unsigned long txMisaligned;
unsigned long rxNotFirst;
unsigned long txRetryLimit;
<font color='#880000'>- };
</font>
<font color='#880000'>-static struct mpc5200_enet_struct enet_driver[NIFACES];
</font><font color='#000088'>+ struct rtems_mdio_info mdio;
+ int phyAddr;
+ bool phyInitialized;
+} mpc5200_fec_context;
</font>
<font color='#880000'>-extern int taskTable;
-static void mpc5200_fec_restart(struct mpc5200_enet_struct *sc);
</font><font color='#000088'>+static mpc5200_fec_context enet_driver[NIFACES];
</font>
<font color='#000088'>+static void mpc5200_fec_send_event(rtems_id task)
+{
+ rtems_event_send(task, FEC_EVENT);
+}
</font>
<font color='#000088'>+static void mpc5200_fec_wait_for_event(void)
+{
+ rtems_event_set out;
+ rtems_bsdnet_event_receive(
+ FEC_EVENT,
+ RTEMS_EVENT_ANY | RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT,
+ &out
+ );
+}
</font>
<font color='#880000'>-/*
- * Function: mpc5200_fec_rx_bd_init
- *
- * Description: Initialize the receive buffer descriptor ring.
- *
- * Returns: void
- *
- * Notes: Space for the buffers of rx BDs is allocated by the rx deamon
- *
- */
-static void mpc5200_fec_rx_bd_init(struct mpc5200_enet_struct *sc) {
- int rxBdIndex;
- struct mbuf *m;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- BDIdx bdi;
</font><font color='#000088'>+static void mpc5200_fec_stop_dma(void)
+{
+ TaskStop(FEC_RECV_TASK_NO);
+ TaskStop(FEC_XMIT_TASK_NO);
+}
</font>
<font color='#880000'>- /*
- * Fill RX buffer descriptor ring.
- */
- for( rxBdIndex = 0; rxBdIndex < sc->rxBdCount; rxBdIndex++ ) {
- MGETHDR (m, M_WAIT, MT_DATA);
- MCLGET (m, M_WAIT);
-
- m->m_pkthdr.rcvif = ifp;
- sc->rxMbuf[rxBdIndex] = m;
- bdi = TaskBDAssign( rxTaskId,
- mtod(m, void *),
- NULL,
- ETHER_MAX_LEN,
- 0 );
- if (bdi != rxBdIndex) {
- rtems_panic("network rx buffer indices out of sync");
- }
- }
</font><font color='#000088'>+static void mpc5200_fec_request_restart(mpc5200_fec_context *self)
+{
+ self->state = FEC_STATE_RESTART_0;
+ mpc5200_fec_send_event(self->txDaemonTid);
+ mpc5200_fec_send_event(self->rxDaemonTid);
</font> }
<font color='#880000'>-/*
- * Function: mpc5200_fec_rx_bd_cleanup
- *
- * Description: put all mbufs pending in rx BDs back to buffer pool
- *
- * Returns: void
- *
- */
-static void mpc5200_fec_rx_bd_cleanup(struct mpc5200_enet_struct *sc) {
- int rxBdIndex;
- struct mbuf *m,*n;
</font><font color='#000088'>+static void mpc5200_fec_start_dma_and_controller(void)
+{
+ TaskStart(FEC_RECV_TASK_NO, 1, FEC_RECV_TASK_NO, 1);
+ TaskStart(FEC_XMIT_TASK_NO, 1, FEC_XMIT_TASK_NO, 1);
</font>
<font color='#880000'>- /*
- * Drain RX buffer descriptor ring.
- */
- for( rxBdIndex = 0; rxBdIndex < sc->rxBdCount; rxBdIndex++ ) {
- n = sc->rxMbuf[rxBdIndex];
- while (n != NULL) {
- m = n;
- MFREE(m,n);
- }
- }
</font><font color='#000088'>+ mpc5200.ecntrl |= FEC_ECNTRL_OE | FEC_ECNTRL_EN;
</font> }
/*
<font color='#997700'>@@ -316,7 +259,7 @@
</font> * Notes:
*
*/
<font color='#880000'>-static void mpc5200_eth_addr_filter_set(struct mpc5200_enet_struct *sc) {
</font><font color='#000088'>+static void mpc5200_eth_addr_filter_set(mpc5200_fec_context *self) {
</font> unsigned char *mac;
unsigned char currByte; /* byte for which to compute the CRC */
int byte; /* loop - counter */
<font color='#997700'>@@ -326,7 +269,7 @@
</font> /*
* Get the mac address of ethernet controller
*/
<font color='#880000'>- mac = (unsigned char *)(&sc->arpcom.ac_enaddr);
</font><font color='#000088'>+ mac = (unsigned char *)(&self->arpcom.ac_enaddr);
</font>
/*
* The algorithm used is the following:
<font color='#997700'>@@ -399,125 +342,68 @@
</font>
}
<font color='#880000'>-
-/*
- * Function: mpc5200_eth_mii_read
- *
- * Description: Read a media independent interface (MII) register on an
- * 18-wire ethernet tranceiver (PHY). Please see your PHY
- * documentation for the register map.
- *
- * Returns: 32-bit register value
- *
- * Notes:
- *
- */
-int mpc5200_eth_mii_read(struct mpc5200_enet_struct *sc, unsigned char phyAddr, unsigned char regAddr, unsigned short * retVal)
- {
- unsigned long reg; /* convenient holder for the PHY register */
- unsigned long phy; /* convenient holder for the PHY */
</font><font color='#000088'>+static int mpc5200_eth_mii_transfer(
+ int phyAddr,
+ unsigned regAddr,
+ uint32_t data
+)
+{
</font> int timeout = 0xffff;
<font color='#880000'>- /*
- * reading from any PHY's register is done by properly
- * programming the FEC's MII data register.
- */
- reg = regAddr << MPC5200_FEC_MII_DATA_RA_SHIFT;
- phy = phyAddr << MPC5200_FEC_MII_DATA_PA_SHIFT;
</font><font color='#000088'>+ mpc5200.ievent = FEC_INTR_MII;
</font>
<font color='#880000'>- mpc5200.mii_data = (MPC5200_FEC_MII_DATA_ST | MPC5200_FEC_MII_DATA_OP_RD | MPC5200_FEC_MII_DATA_TA | phy | reg);
-
- /*
- * wait for the related interrupt
- */
- while ((timeout--) && (!(mpc5200.ievent & 0x00800000)));
-
- if(timeout == 0)
- {
-
-#ifdef ETH_DEBUG
- printf ("Read MDIO failed..." "\r\n");
-#endif
-
- return false;
-
- }
-
- /*
- * clear mii interrupt bit
- */
- mpc5200.ievent = 0x00800000;
-
- /*
- * it's now safe to read the PHY's register
- */
- *retVal = (unsigned short)mpc5200.mii_data;
-
- return true;
</font><font color='#000088'>+ mpc5200.mii_data = MPC5200_FEC_MII_DATA_ST
+ | MPC5200_FEC_MII_DATA_TA
+ | (phyAddr << MPC5200_FEC_MII_DATA_PA_SHIFT)
+ | (regAddr << MPC5200_FEC_MII_DATA_RA_SHIFT)
+ | data;
</font>
<font color='#000088'>+ while (timeout > 0 && (mpc5200.ievent & FEC_INTR_MII) == 0) {
+ --timeout;
</font> }
<font color='#880000'>-/*
- * Function: mpc5200_eth_mii_write
- *
- * Description: Write a media independent interface (MII) register on an
- * 18-wire ethernet tranceiver (PHY). Please see your PHY
- * documentation for the register map.
- *
- * Returns: Success (boolean)
- *
- * Notes:
- *
- */
-static int mpc5200_eth_mii_write(struct mpc5200_enet_struct *sc, unsigned char phyAddr, unsigned char regAddr, unsigned short data)
- {
- unsigned long reg; /* convenient holder for the PHY register */
- unsigned long phy; /* convenient holder for the PHY */
- int timeout = 0xffff;
-
- reg = regAddr << MPC5200_FEC_MII_DATA_RA_SHIFT;
- phy = phyAddr << MPC5200_FEC_MII_DATA_PA_SHIFT;
-
- mpc5200.mii_data = (MPC5200_FEC_MII_DATA_ST | MPC5200_FEC_MII_DATA_OP_WR | MPC5200_FEC_MII_DATA_TA | phy | reg | data);
-
- /*
- * wait for the MII interrupt
- */
- while ((timeout--) && (!(mpc5200.ievent & 0x00800000)));
-
- if(timeout == 0)
- {
-
-#ifdef ETH_DEBUG
- printf ("Write MDIO failed..." "\r\n");
-#endif
-
- return false;
</font><font color='#000088'>+ return timeout > 0 ? 0 : -1;
+}
</font>
<font color='#880000'>- }
</font><font color='#000088'>+/* FIXME: Make this static, this needs a fix in an application */
+int mpc5200_eth_mii_read(
+ int phyAddr,
+ void *arg,
+ unsigned regAddr,
+ uint32_t *retVal
+)
+{
+ int rv = mpc5200_eth_mii_transfer(
+ phyAddr,
+ regAddr,
+ MPC5200_FEC_MII_DATA_OP_RD
+ );
</font>
<font color='#880000'>- /*
- * clear MII interrupt bit
- */
- mpc5200.ievent = 0x00800000;
</font><font color='#000088'>+ *retVal = mpc5200.mii_data & 0xffff;
</font>
<font color='#880000'>- return true;
</font><font color='#000088'>+ return rv;
+}
</font>
<font color='#880000'>- }
</font><font color='#000088'>+static int mpc5200_eth_mii_write(
+ int phyAddr,
+ void *arg,
+ unsigned regAddr,
+ uint32_t data
+)
+{
+ return mpc5200_eth_mii_transfer(
+ phyAddr,
+ regAddr,
+ MPC5200_FEC_MII_DATA_OP_WR | data
+ );
+}
</font>
/*
<font color='#880000'>- * Function: mpc5200_fec_reset
- *
- * Description: Reset a running ethernet driver including the hardware
- * FIFOs and the FEC.
- *
- * Returns: Success (boolean)
- *
- * Notes:
- *
</font><font color='#000088'>+ * Reset a running ethernet driver including the hardware FIFOs and the FEC.
</font> */
<font color='#880000'>-static int mpc5200_fec_reset(struct mpc5200_enet_struct *sc) {
</font><font color='#000088'>+static void mpc5200_fec_reset(mpc5200_fec_context *self)
+{
</font> volatile int delay;
/*
* Clear FIFO status registers
<font color='#997700'>@@ -543,8 +429,6 @@
</font> * wait at least 16 clock cycles
*/
for (delay = 0;delay < 16*4;delay++) {};
<font color='#880000'>-
- return true;
</font> }
<font color='#997700'>@@ -559,28 +443,28 @@
</font> * Notes:
*
*/
<font color='#880000'>-void mpc5200_fec_off(struct mpc5200_enet_struct *sc)
</font><font color='#000088'>+void mpc5200_fec_off(mpc5200_fec_context *self)
</font> {
int counter = 0xffff;
#if defined(ETH_DEBUG)
<font color='#880000'>- unsigned short phyStatus, i;
- unsigned char phyAddr = 0;
</font><font color='#000088'>+ uint32_t phyStatus;
+ int i;
</font>
for(i = 0; i < 9; i++)
{
<font color='#880000'>- mpc5200_eth_mii_read(sc, phyAddr, i, &phyStatus);
- printf ("Mii reg %d: 0x%04x" "\r\n", i, phyStatus);
</font><font color='#000088'>+ mpc5200_eth_mii_read(self->phyAddr, self, i, &phyStatus);
+ printf ("Mii reg %d: 0x%04" PRIx32 "\r\n", i, phyStatus);
</font>
}
for(i = 16; i < 21; i++)
{
<font color='#880000'>- mpc5200_eth_mii_read(sc, phyAddr, i, &phyStatus);
- printf ("Mii reg %d: 0x%04x" "\r\n", i, phyStatus);
</font><font color='#000088'>+ mpc5200_eth_mii_read(self->phyAddr, self, i, &phyStatus);
+ printf ("Mii reg %d: 0x%04" PRIx32 "\r\n", i, phyStatus);
</font>
}
#endif /* ETH_DEBUG */
<font color='#997700'>@@ -601,11 +485,8 @@
</font> */
while((counter--) && (!(mpc5200.ievent & FEC_INTR_GRA)));
<font color='#880000'>- /*
- * Disable the SmartDMA transmit and receive tasks.
- */
- TaskStop( rxTaskId );
- TaskStop( txTaskId );
</font><font color='#000088'>+ mpc5200_fec_stop_dma();
+
</font> /*
* Disable transmit / receive interrupts
*/
<font color='#997700'>@@ -616,20 +497,14 @@
</font> * Disable the Ethernet Controller
*/
mpc5200.ecntrl &= ~(FEC_ECNTRL_OE | FEC_ECNTRL_EN);
<font color='#880000'>-
- /*
- * cleanup all buffers
- */
- mpc5200_fec_rx_bd_cleanup(sc);
-
- }
</font><font color='#000088'>+}
</font>
/*
* MPC5200 FEC interrupt handler
*/
void mpc5200_fec_irq_handler(rtems_irq_hdl_param handle)
{
<font color='#880000'>- struct mpc5200_enet_struct *sc = (struct mpc5200_enet_struct *) handle;
</font><font color='#000088'>+ mpc5200_fec_context *self = (mpc5200_fec_context *) handle;
</font> volatile uint32_t ievent;
ievent = mpc5200.ievent;
<font color='#997700'>@@ -639,424 +514,55 @@
</font> * check errors, update statistics
*/
if (ievent & FEC_INTR_LATE_COL) {
<font color='#880000'>- sc->txLateCollision++;
</font><font color='#000088'>+ self->txLateCollision++;
</font> }
if (ievent & FEC_INTR_COL_RETRY) {
<font color='#880000'>- sc->txRetryLimit++;
</font><font color='#000088'>+ self->txRetryLimit++;
</font> }
if (ievent & FEC_INTR_XFIFO_UN) {
<font color='#880000'>- sc->txUnderrun++;
</font><font color='#000088'>+ self->txUnderrun++;
</font> }
if (ievent & FEC_INTR_XFIFO_ERR) {
<font color='#880000'>- sc->txUnderrun++;
</font><font color='#000088'>+ self->txFIFOError++;
</font> }
if (ievent & FEC_INTR_RFIFO_ERR) {
<font color='#880000'>- sc->rxOverrun++;
</font><font color='#000088'>+ self->rxFIFOError++;
</font> }
/*
* fatal error ocurred?
*/
if (ievent & (FEC_INTR_XFIFO_ERR | FEC_INTR_RFIFO_ERR)) {
mpc5200.imask &= ~(FEC_INTR_XFERREN | FEC_INTR_RFERREN);
<font color='#880000'>- rtems_event_send(enet_driver[0].rxDaemonTid, FATAL_INT_EVENT);
</font><font color='#000088'>+ mpc5200_fec_request_restart(self);
</font> }
}
<font color='#880000'>-/*
- * MPC5200 SmartComm ethernet interrupt handler
- */
-void mpc5200_smartcomm_rx_irq_handler(rtems_irq_hdl_param unused)
- {
- /* Frame received? */
- if(GET_SDMA_PENDINGBIT(FEC_RECV_TASK_NO))
- {
-
- SDMA_CLEAR_IEVENT(&mpc5200.sdma.IntPend,FEC_RECV_TASK_NO);
-
- bestcomm_glue_irq_disable(FEC_RECV_TASK_NO);/*Disable receive ints*/
-
- enet_driver[0].rxInterrupts++;<span style="background-color: #FF0000"> </span> /* Rx int has occurred */
-
- rtems_event_send(enet_driver[0].rxDaemonTid, INTERRUPT_EVENT);
-
- }
- }
-
-/*
- * MPC5200 SmartComm ethernet interrupt handler
- */
-void mpc5200_smartcomm_tx_irq_handler(rtems_irq_hdl_param unused)
- {
- /* Buffer transmitted or transmitter error? */
- if(GET_SDMA_PENDINGBIT(FEC_XMIT_TASK_NO))
- {
-
- SDMA_CLEAR_IEVENT(&mpc5200.sdma.IntPend,FEC_XMIT_TASK_NO);
-
- bestcomm_glue_irq_disable(FEC_XMIT_TASK_NO);/*Disable tx ints*/
-
- enet_driver[0].txInterrupts++; /* Tx int has occurred */
-
- rtems_event_send(enet_driver[0].txDaemonTid, INTERRUPT_EVENT);
-
- }
-
- }
-
-
-
-
-
- /*
- * Function: mpc5200_fec_retire_tbd
- *
- * Description: Soak up buffer descriptors that have been sent.
- *
- * Returns: void
- *
- * Notes:
- *
- */
-static void mpc5200_fec_retire_tbd(struct mpc5200_enet_struct *sc,
- bool force)
</font><font color='#000088'>+void mpc5200_smartcomm_rx_irq_handler(void *arg)
</font> {
<font color='#880000'>- struct mbuf *n;
- TaskBD1_t *bdRing = (TaskBD1_t *)TaskGetBDRing( txTaskId );;
- /*
- * Clear already transmitted BDs first. Will not work calling same
- * from fecExceptionHandler(TFINT).
- */
</font><font color='#000088'>+ mpc5200_fec_context *self = arg;
</font>
<font color='#880000'>- while ((sc->txBdActiveCount > 0) &&
- (force || (bdRing[sc->txBdTail].Status == 0x0))) {
- if (sc->txMbuf[sc->txBdTail] != NULL) {
- /*
- * NOTE: txMbuf can be NULL, if mbuf has been split into different BDs
- */
- MFREE (sc->txMbuf[sc->txBdTail],n);
- sc->txMbuf[sc->txBdTail] = NULL;
- }
- sc->txBdActiveCount--;
- if(++sc->txBdTail >= sc->txBdCount) {
- sc->txBdTail = 0;
- }
- }
</font><font color='#000088'>+ ++self->rxInterrupts;
+ mpc5200_fec_send_event(self->rxDaemonTid);
+ SDMA_CLEAR_IEVENT(&mpc5200.sdma.IntPend, FEC_RECV_TASK_NO);
+ bestcomm_glue_irq_disable(FEC_RECV_TASK_NO);
</font> }
<font color='#880000'>-#if 0
- /*
- * Function: mpc5200_fec_tx_bd_requeue
- *
- * Description: put buffers back to interface output queue
- *
- * Returns: void
- *
- * Notes:
- *
- */
-static void mpc5200_fec_tx_bd_requeue(struct mpc5200_enet_struct *sc)
</font><font color='#000088'>+void mpc5200_smartcomm_tx_irq_handler(void *arg)
</font> {
<font color='#880000'>- /*
- * Clear already transmitted BDs first. Will not work calling same
- * from fecExceptionHandler(TFINT).
- */
-
- while (sc->txBdActiveCount > 0) {
- if (sc->txMbuf[sc->txBdHead] != NULL) {
- /*
- * NOTE: txMbuf can be NULL, if mbuf has been split into different BDs
- */
- IF_PREPEND(&(sc->arpcom.ac_if.if_snd),sc->txMbuf[sc->txBdHead]);
- sc->txMbuf[sc->txBdHead] = NULL;
- }
- sc->txBdActiveCount--;
- if(--sc->txBdHead < 0) {
- sc->txBdHead = sc->txBdCount-1;
- }
- }
-}
-#endif
-
-static void mpc5200_fec_sendpacket(struct ifnet *ifp,struct mbuf *m) {
- struct mpc5200_enet_struct *sc = ifp->if_softc;
- struct mbuf *l = NULL;
- int nAdded;
- uint32_t status;
- rtems_event_set events;
- TaskBD1_t *bdRing = (TaskBD1_t *)TaskGetBDRing( txTaskId );
- TaskBD1_t *thisBd;
- TaskBD1_t *firstBd = NULL;
- void *data_ptr;
- size_t data_len;
-
- /*
- * Free up buffer descriptors
- */
- mpc5200_fec_retire_tbd(sc,false);
-
- /*
- * Set up the transmit buffer descriptors.
- * No need to pad out short packets since the
- * hardware takes care of that automatically.
- * No need to copy the packet to a contiguous buffer
- * since the hardware is capable of scatter/gather DMA.
- */
- nAdded = 0;
</font><font color='#000088'>+ mpc5200_fec_context *self = arg;
</font>
<font color='#880000'>- for(;;) {
-
- /*
- * Wait for buffer descriptor to become available.
- */
- if((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
-
- /*
- * Clear old events
- */
- SDMA_CLEAR_IEVENT(&mpc5200.sdma.IntPend,FEC_XMIT_TASK_NO);
-
- /*
- * Wait for buffer descriptor to become available.
- * Note that the buffer descriptors are checked
- * *before* * entering the wait loop -- this catches
- * the possibility that a buffer descriptor became
- * available between the `if' above, and the clearing
- * of the event register.
- * This is to catch the case where the transmitter
- * stops in the middle of a frame -- and only the
- * last buffer descriptor in a frame can generate
- * an interrupt.
- */
- mpc5200_fec_retire_tbd(sc,false);
-
- while((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
- bestcomm_glue_irq_enable(FEC_XMIT_TASK_NO);
- rtems_bsdnet_event_receive(INTERRUPT_EVENT,
- RTEMS_WAIT | RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT, &events);
- mpc5200_fec_retire_tbd(sc,false);
- }
- }
-
- if(m->m_len == 0) {
- /*
- * Just toss empty mbufs
- */
- struct mbuf *n;
- MFREE(m, n);
- m = n;
- if(l != NULL) {
- l->m_next = m;
- }
- }
- else {
- /*
- * Flush the buffer for this descriptor
- */
- /*rtems_cache_flush_multiple_data_lines((const void *)mtod(m, void *), m->m_len);*/
- /*
- * Fill in the buffer descriptor,
- * set "end of frame" bit in status,
- * if last mbuf in chain
- */
- thisBd = bdRing + sc->txBdHead;
- /*
- * FIXME: do not send interrupt after every frame
- * doing this every quarter of BDs is much more efficent
- */
- status = ((m->m_next == NULL)
- ? TASK_BD_TFD | TASK_BD_INT
- : 0);
- /*
- * Don't set the READY flag till the
- * whole packet has been readied.
- */
- if (firstBd != NULL) {
- status |= (uint32)SDMA_BD_MASK_READY;
- }
- else {
- firstBd = thisBd;
- }
-
- data_ptr = mtod(m, void *);
- data_len = (uint32)m->m_len;
- sc->txMbuf[sc->txBdHead] = m;
- /* go to next part in chain */
- l = m;
- m = m->m_next;
-
- thisBd->DataPtr[0] = (uint32)data_ptr;
- thisBd->Status = (status
- |((uint32)SDMA_DRD_MASK_LENGTH & data_len));
-
- nAdded++;
- if(++(sc->txBdHead) == sc->txBdCount) {
- sc->txBdHead = 0;
- }
- }
- /*
- * Set the transmit buffer status.
- * Break out of the loop if this mbuf is the last in the frame.
- */
- if(m == NULL) {
- if(nAdded) {
- firstBd->Status |= SDMA_BD_MASK_READY;
- SDMA_TASK_ENABLE(SDMA_TCR, txTaskId);
- sc->txBdActiveCount += nAdded;
- }
- break;
- }
- } /* end of for(;;) */
</font><font color='#000088'>+ ++self->txInterrupts;
+ mpc5200_fec_send_event(self->txDaemonTid);
+ SDMA_CLEAR_IEVENT(&mpc5200.sdma.IntPend, FEC_XMIT_TASK_NO);
+ bestcomm_glue_irq_disable(FEC_XMIT_TASK_NO);
</font> }
<font color='#880000'>-
-/*
- * Driver transmit daemon
- */
-void mpc5200_fec_txDaemon(void *arg)
- {
- struct mpc5200_enet_struct *sc = (struct mpc5200_enet_struct *)arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- struct mbuf *m;
- rtems_event_set events;
-
- for(;;) {
- /*
- * Wait for packet
- */
- bestcomm_glue_irq_enable(FEC_XMIT_TASK_NO);
- rtems_bsdnet_event_receive(START_TRANSMIT_EVENT|INTERRUPT_EVENT,
- RTEMS_EVENT_ANY | RTEMS_WAIT,
- RTEMS_NO_TIMEOUT,
- &events);
-
- /*
- * Send packets till queue is empty
- */
- for(;;)
- {
-
- /*
- * Get the next mbuf chain to transmit.
- */
- IF_DEQUEUE(&ifp->if_snd, m);
-
- if (!m)
- break;
-
- mpc5200_fec_sendpacket(ifp, m);
-
- }
-
- ifp->if_flags &= ~IFF_OACTIVE;
-
- }
-
- }
-
-
-/*
- * reader task
- */
-static void mpc5200_fec_rxDaemon(void *arg){
- struct mpc5200_enet_struct *sc = (struct mpc5200_enet_struct *)arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- struct mbuf *m;
- struct ether_header *eh;
- int rxBdIndex;
- uint32_t status;
- size_t size;
- rtems_event_set events;
- uint16 len = 1;
- TaskBD1_t *bd;
- void *dptr;
- TaskBD1_t *bdRing = (TaskBD1_t *)TaskGetBDRing( rxTaskId );;
-
- /*
- * Input packet handling loop
- */
- rxBdIndex = 0;
-
- for (;;) {
- /*
- * Clear old events
- */
- SDMA_CLEAR_IEVENT(&mpc5200.sdma.IntPend,FEC_RECV_TASK_NO);
- /*
- * Get the first BD pointer and its length.
- */
- bd = bdRing + rxBdIndex;
- status = bd->Status;
- len = (uint16)GET_BD_LENGTH( bd );
-
- /*
- * Loop through BDs until we find an empty one. This indicates that
- * the SmartDMA is still using it.
- */
- while( !(status & SDMA_BD_MASK_READY) ) {
-
- /*
- * Remember the data pointer from this transfer.
- */
- dptr = (void *)bd->DataPtr[0];
- m = sc->rxMbuf[rxBdIndex];
- m->m_len = m->m_pkthdr.len = (len
- - sizeof(uint32_t)
- - sizeof(struct ether_header));
- eh = mtod(m, struct ether_header *);
- m->m_data += sizeof(struct ether_header);
- ether_input(ifp, eh, m);
-
- /*
- * Done w/ the BD. Clean it.
- */
- sc->rxMbuf[rxBdIndex] = NULL;
-
- /*
- * Add a new buffer to the ring.
- */
- MGETHDR (m, M_WAIT, MT_DATA);
- MCLGET (m, M_WAIT);
- m->m_pkthdr.rcvif = ifp;
- size = ETHER_MAX_LEN;
-
- sc->rxMbuf[rxBdIndex] = m;
- bd->DataPtr[0] = (uint32)mtod(m, void *);
- bd->Status = ( ( (uint32)SDMA_DRD_MASK_LENGTH & (uint32)size)
- | ((uint32)SDMA_BD_MASK_READY));
-
- /*
- * advance to next BD
- */
- if (++rxBdIndex >= sc->rxBdCount) {
- rxBdIndex = 0;
- }
- /*
- * Get next BD pointer and its length.
- */
- bd = bdRing + rxBdIndex;
- status = bd->Status;
- len = (uint16)GET_BD_LENGTH( bd );
- }
- /*
- * Unmask RXF (Full frame received) event
- */
- bestcomm_glue_irq_enable(FEC_RECV_TASK_NO);
-
- rtems_bsdnet_event_receive (INTERRUPT_EVENT | FATAL_INT_EVENT,
- RTEMS_WAIT | RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT, &events);
- if (events & FATAL_INT_EVENT) {
- /*
- * fatal interrupt ocurred, so reinit fec and restart bestcomm tasks
- */
- mpc5200_fec_restart(sc);
- rxBdIndex = 0;
- }
- }
</font><font color='#000088'>+static void mpc5200_fec_init_mib(mpc5200_fec_context *self)
+{
+ memset(&mpc5200.RES [0], 0, 0x2e4);
+ mpc5200.mib_control = 0x40000000;
</font> }
<font color='#880000'>-
</font> /*
* Function: mpc5200_fec_initialize_hardware
*
<font color='#997700'>@@ -1068,13 +574,17 @@
</font> * Notes:
*
*/
<font color='#880000'>-static void mpc5200_fec_initialize_hardware(struct mpc5200_enet_struct *sc)
- {
</font><font color='#000088'>+static void mpc5200_fec_initialize_hardware(mpc5200_fec_context *self)
+{
+ /* We want at most 2.5MHz */
+ uint32_t div = 2 * 2500000;
+ uint32_t mii_speed = (IPB_CLOCK + div - 1) / div;
</font>
/*
* Reset mpc5200 FEC
*/
<font color='#880000'>- mpc5200_fec_reset(sc);
</font><font color='#000088'>+ mpc5200_fec_reset(self);
+ mpc5200_fec_init_mib(self);
</font>
/*
* Clear FEC-Lite interrupt event register (IEVENT)
<font color='#997700'>@@ -1102,10 +612,10 @@
</font>
/*
<font color='#880000'>- * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock(33Mhz)
</font><font color='#000088'>+ * Set MII_SPEED = IPB clock / (2 * mii_speed))
</font> * and do not drop the Preamble.
*/
<font color='#880000'>- mpc5200.mii_speed = (7 << 1); /* ipb_clk = 33 MHz */
</font><font color='#000088'>+ mpc5200.mii_speed = mii_speed << 1;
</font>
/*
* Set Opcode/Pause Duration Register
<font color='#997700'>@@ -1135,7 +645,7 @@
</font> * Set individual address filter for unicast address
* and set physical address registers.
*/
<font color='#880000'>- mpc5200_eth_addr_filter_set(sc);
</font><font color='#000088'>+ mpc5200_eth_addr_filter_set(self);
</font>
/*
* Set multicast address filter
<font color='#997700'>@@ -1147,7 +657,7 @@
</font> * enable CRC in finite state machine register
*/
mpc5200.xmit_fsm = FEC_FSM_CRC | FEC_FSM_ENFSM;
<font color='#880000'>- }
</font><font color='#000088'>+}
</font>
/*
* Initialize PHY(LXT971A):
<font color='#997700'>@@ -1174,16 +684,18 @@
</font> * Notes:
*
*/
<font color='#880000'>-static void mpc5200_fec_initialize_phy(struct mpc5200_enet_struct *sc)
- {
- int timeout;
- unsigned short phyAddr = 0;
-
</font><font color='#000088'>+static void mpc5200_fec_initialize_phy(mpc5200_fec_context *self)
+{
+ if (self->phyInitialized) {
+ return;
+ } else {
+ self->phyInitialized = true;
+ }
</font>
/*
* Reset PHY, then delay 300ns
*/
<font color='#880000'>- mpc5200_eth_mii_write(sc, phyAddr, 0x0, 0x8000);
</font><font color='#000088'>+ mpc5200_eth_mii_write(self->phyAddr, self, 0x0, 0x8000);
</font>
rtems_task_wake_after(2);
<font color='#997700'>@@ -1192,18 +704,19 @@
</font> /*
* Set the auto-negotiation advertisement register bits
*/
<font color='#880000'>- mpc5200_eth_mii_write(sc, phyAddr, 0x4, 0x01e1);
</font><font color='#000088'>+ mpc5200_eth_mii_write(self->phyAddr, self, 0x4, 0x01e1);
</font>
/*
* Set MDIO bit 0.12 = 1(&& bit 0.9=1?) to enable auto-negotiation
*/
<font color='#880000'>- mpc5200_eth_mii_write(sc, phyAddr, 0x0, 0x1200);
</font><font color='#000088'>+ mpc5200_eth_mii_write(self->phyAddr, self, 0x0, 0x1200);
</font>
/*
* Wait for AN completion
*/
<font color='#880000'>- timeout = 0x100;
</font> #if 0
<font color='#000088'>+ int timeout = 0x100;
+ uint32_t phyStatus;
</font> do
{
<font color='#997700'>@@ -1218,11 +731,11 @@
</font>
}
<font color='#880000'>- if(mpc5200_eth_mii_read(sc, phyAddr, 0x1, &phyStatus) != true)
</font><font color='#000088'>+ if(mpc5200_eth_mii_read(self->phyAddr, self, 0x1, &phyStatus) != true)
</font> {
#if defined(ETH_DEBUG)
<font color='#880000'>- printf ("MPC5200FEC PHY auto neg failed: 0x%04x." "\r\n", phyStatus);
</font><font color='#000088'>+ printf ("MPC5200FEC PHY auto neg failed: 0x%04" PRIx32 ".\r\n", phyStatus);
</font> #endif
return;
<font color='#997700'>@@ -1242,29 +755,45 @@
</font>
#if defined(ETH_DEBUG)
int i;
<font color='#880000'>- unsigned short phyStatus;
</font><font color='#000088'>+ uint32_t phyStatus;
</font> /*
* Print PHY registers after initialization.
*/
for(i = 0; i < 9; i++)
{
<font color='#880000'>- mpc5200_eth_mii_read(sc, phyAddr, i, &phyStatus);
- printf ("Mii reg %d: 0x%04x" "\r\n", i, phyStatus);
</font><font color='#000088'>+ mpc5200_eth_mii_read(self->phyAddr, self, i, &phyStatus);
+ printf ("Mii reg %d: 0x%04" PRIx32 "\r\n", i, phyStatus);
</font>
}
for(i = 16; i < 21; i++)
{
<font color='#880000'>- mpc5200_eth_mii_read(sc, phyAddr, i, &phyStatus);
- printf ("Mii reg %d: 0x%04x" "\r\n", i, phyStatus);
</font><font color='#000088'>+ mpc5200_eth_mii_read(self->phyAddr, self, i, &phyStatus);
+ printf ("Mii reg %d: 0x%04" PRIx32 "\r\n", i, phyStatus);
</font>
}
#endif /* ETH_DEBUG */
}
<font color='#000088'>+static void mpc5200_fec_restart(mpc5200_fec_context *self, rtems_id otherDaemon)
+{
+ if (self->state == FEC_STATE_RESTART_1) {
+ mpc5200_fec_initialize_hardware(self);
+ mpc5200_fec_initialize_phy(self);
+ mpc5200_fec_start_dma_and_controller();
+ self->state = FEC_STATE_NORMAL;
+ } else {
+ self->state = FEC_STATE_RESTART_1;
+ }
+
+ mpc5200_fec_send_event(otherDaemon);
+ while (self->state != FEC_STATE_NORMAL) {
+ mpc5200_fec_wait_for_event();
+ }
+}
</font>
/*
* Send packet (caller provides header).
<font color='#997700'>@@ -1272,159 +801,453 @@
</font> static void mpc5200_fec_tx_start(struct ifnet *ifp)
{
<font color='#880000'>- struct mpc5200_enet_struct *sc = ifp->if_softc;
</font><font color='#000088'>+ mpc5200_fec_context *self = ifp->if_softc;
</font>
ifp->if_flags |= IFF_OACTIVE;
<font color='#880000'>- rtems_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT);
</font><font color='#000088'>+ mpc5200_fec_send_event(self->txDaemonTid);
</font>
}
<font color='#000088'>+static TaskBD1_t *mpc5200_fec_init_tx_dma(int bdCount, struct mbuf **mbufs)
+{
+ TaskSetupParamSet_t param = {
+ .NumBD = bdCount,
+ .Size = {
+ .MaxBuf = ETHER_MAX_LEN
+ },
+ .Initiator = 0,
+ .StartAddrSrc = 0,
+ .IncrSrc = sizeof(uint32_t),
+ .SzSrc = sizeof(uint32_t),
+ .StartAddrDst = (uint32) &mpc5200.tfifo_data,
+ .IncrDst = 0,
+ .SzDst = sizeof(uint32_t)
+ };
+ int bdIndex = 0;
</font>
<font color='#880000'>-/*
- * set up sdma tasks for ethernet
- */
-static void mpc5200_sdma_task_setup(struct mpc5200_enet_struct *sc) {
- TaskSetupParamSet_t rxParam; /* RX task setup parameters */
- TaskSetupParamSet_t txParam; /* TX task setup parameters */
</font><font color='#000088'>+ TaskSetup(FEC_XMIT_TASK_NO, ¶m);
</font>
<font color='#880000'>- /*
- * Setup the SDMA RX task.
- */
- rxParam.NumBD = sc->rxBdCount;
- rxParam.Size.MaxBuf = ETHER_MAX_LEN;
- rxParam.Initiator = 0;
- rxParam.StartAddrSrc = (uint32)&(mpc5200.rfifo_data);
- rxParam.IncrSrc = 0;
- rxParam.SzSrc = sizeof(uint32_t);
- rxParam.StartAddrDst = (uint32)NULL;
- rxParam.IncrDst = sizeof(uint32_t);
- rxParam.SzDst = sizeof(uint32_t);
- rxTaskId = TaskSetup(TASK_FEC_RX,&rxParam );
</font><font color='#000088'>+ for (bdIndex = 0; bdIndex < bdCount; ++bdIndex) {
+ mbufs [bdIndex] = NULL;
+ }
</font>
<font color='#880000'>- /*
- * Setup the TX task.
- */
- txParam.NumBD = sc->txBdCount;
- txParam.Size.MaxBuf = ETHER_MAX_LEN;
- txParam.Initiator = 0;
- txParam.StartAddrSrc = (uint32)NULL;
- txParam.IncrSrc = sizeof(uint32_t);
- txParam.SzSrc = sizeof(uint32_t);
- txParam.StartAddrDst = (uint32)&(mpc5200.tfifo_data);
- txParam.IncrDst = 0;
- txParam.SzDst = sizeof(uint32_t);
</font><font color='#000088'>+ return (TaskBD1_t *) TaskGetBDRing(FEC_XMIT_TASK_NO);
+}
+
+#if 0
+static void mpc5200_fec_requeue_and_discard_tx_frames(
+ int bdIndex,
+ int bdCount,
+ TaskBD1_t *bdRing,
+ struct mbuf **mbufs
+)
+{
+ int bdStop = bdIndex;
+ struct mbuf *previous = NULL;
</font>
<font color='#880000'>- txTaskId = TaskSetup( TASK_FEC_TX, &txParam );
</font><font color='#000088'>+ do {
+ struct mbuf *current = NULL;
+ uint32 status = 0;
+ TaskBD1_t *bd = NULL;
+
+ if (bdIndex > 1) {
+ --bdIndex;
+ } else {
+ bdIndex = bdCount - 1;
+ }
+
+ current = mbufs [bdIndex];
+ mbufs [bdIndex] = NULL;
+
+ status = bdRing [bdIndex].Status;
+ bdRing [bdIndex].Status = 0;
+
+ if (current != NULL) {
+ if ((status & FEC_BD_LAST) != 0) {
+ if (previous != NULL) {
+ IF_PREPEND(&ifp->if_snd, previous);
+ }
+ }
+ } else {
+ break;
+ }
</font>
<font color='#000088'>+ previous = current;
+ } while (bdIndex != bdStop);
</font> }
<font color='#000088'>+#endif
</font>
<font color='#880000'>-void mpc5200_fec_irq_on(const rtems_irq_connect_data* ptr)
</font><font color='#000088'>+static void mpc5200_fec_discard_tx_frames(
+ int bdCount,
+ struct mbuf **mbufs
+)
</font> {
<font color='#880000'>- mpc5200.imask = FEC_INTR_MASK_USED;
</font><font color='#000088'>+ int bdIndex = 0;
+
+ for (bdIndex = 0; bdIndex < bdCount; ++bdIndex) {
+ struct mbuf *m = mbufs [bdIndex];
+
+ if (m != NULL) {
+ mbufs [bdIndex] = NULL;
+ m_free(m);
+ }
+ }
</font> }
<font color='#000088'>+static void mpc5200_fec_reset_tx_dma(
+ int bdCount,
+ TaskBD1_t *bdRing,
+ struct mbuf **mbufs,
+ struct mbuf *m
+)
+{
+ TaskStop(FEC_XMIT_TASK_NO);
+ TaskBDReset(FEC_XMIT_TASK_NO);
+ mpc5200_fec_discard_tx_frames(bdCount, mbufs);
+ while (m != NULL) {
+ m = m_free(m);
+ }
+}
</font>
<font color='#880000'>-int mpc5200_fec_irq_isOn(const rtems_irq_connect_data* ptr)
</font><font color='#000088'>+static struct mbuf *mpc5200_fec_next_fragment(
+ struct ifnet *ifp,
+ struct mbuf *m,
+ bool *isFirst
+)
</font> {
<font color='#880000'>- return mpc5200.imask != 0;
</font><font color='#000088'>+ struct mbuf *n = NULL;
+
+ *isFirst = false;
+
+ while (true) {
+ if (m == NULL) {
+ IF_DEQUEUE(&ifp->if_snd, m);
+
+ if (m != NULL) {
+ *isFirst = true;
+ } else {
+ ifp->if_flags &= ~IFF_OACTIVE;
+
+ return NULL;
+ }
+ }
+
+ if (m->m_len > 0) {
+ break;
+ } else {
+ m = m_free(m);
+ }
+ }
+
+ n = m->m_next;
+ while (n != NULL && n->m_len <= 0) {
+ n = m_free(n);
+ }
+ m->m_next = n;
+
+ return m;
</font> }
<font color='#000088'>+static bool mpc5200_fec_transmit(
+ struct ifnet *ifp,
+ int bdCount,
+ TaskBD1_t *bdRing,
+ struct mbuf **mbufs,
+ int *bdIndexPtr,
+ struct mbuf **mPtr,
+ TaskBD1_t **firstPtr
+)
+{
+ bool bdShortage = false;
+ int bdIndex = *bdIndexPtr;
+ struct mbuf *m = *mPtr;
+ TaskBD1_t *first = *firstPtr;
+
+ while (true) {
+ TaskBD1_t *bd = &bdRing [bdIndex];
+
+ if (bd->Status == 0) {
+ struct mbuf *done = mbufs [bdIndex];
+ bool isFirst = false;
+
+ if (done != NULL) {
+ m_free(done);
+ mbufs [bdIndex] = NULL;
+ }
+
+ m = mpc5200_fec_next_fragment(ifp, m, &isFirst);
+ if (m != NULL) {
+ uint32 status = (uint32) m->m_len;
+
+ mbufs [bdIndex] = m;
+
+ rtems_cache_flush_multiple_data_lines(mtod(m, void *), m->m_len);
+
+ if (isFirst) {
+ first = bd;
+ } else {
+ status |= FEC_BD_READY;
+ }
+
+ bd->DataPtr [0] = mtod(m, uint32);
+
+ if (m->m_next != NULL) {
+ bd->Status = status;
+ } else {
+ bd->Status = status | FEC_BD_INT | FEC_BD_LAST;
+ first->Status |= FEC_BD_READY;
+ SDMA_TASK_ENABLE(SDMA_TCR, FEC_XMIT_TASK_NO);
+ }
+
+ m = m->m_next;
+ } else {
+ break;
+ }
+ } else {
+ bdShortage = true;
+ break;
+ }
+
+ if (bdIndex < bdCount - 1) {
+ ++bdIndex;
+ } else {
+ bdIndex = 0;
+ }
+ }
+
+ *bdIndexPtr = bdIndex;
+ *mPtr = m;
+ *firstPtr = first;
+
+ return bdShortage;
+}
</font>
<font color='#880000'>-void mpc5200_fec_irq_off(const rtems_irq_connect_data* ptr)
</font><font color='#000088'>+static void mpc5200_fec_tx_daemon(void *arg)
</font> {
<font color='#880000'>- mpc5200.imask = 0;
</font><font color='#000088'>+ mpc5200_fec_context *self = arg;
+ struct ifnet *ifp = &self->arpcom.ac_if;
+ int bdIndex = 0;
+ int bdCount = self->txBdCount;
+ struct mbuf **mbufs = &self->txMbuf [0];
+ struct mbuf *m = NULL;
+ TaskBD1_t *bdRing = mpc5200_fec_init_tx_dma(bdCount, mbufs);
+ TaskBD1_t *first = NULL;
+ bool bdShortage = false;
+
+ while (true) {
+ if (bdShortage) {
+ bestcomm_glue_irq_enable(FEC_XMIT_TASK_NO);
+ }
+ mpc5200_fec_wait_for_event();
+
+ if (self->state != FEC_STATE_NORMAL) {
+ mpc5200_fec_reset_tx_dma(bdCount, bdRing, mbufs, m);
+ mpc5200_fec_restart(self, self->rxDaemonTid);
+ bdIndex = 0;
+ m = NULL;
+ first = NULL;
+ }
+
+ bdShortage = mpc5200_fec_transmit(
+ ifp,
+ bdCount,
+ bdRing,
+ mbufs,
+ &bdIndex,
+ &m,
+ &first
+ );
+ }
</font> }
<font color='#000088'>+static struct mbuf *mpc5200_fec_add_mbuf(struct ifnet *ifp, TaskBD1_t *bd)
+{
+ struct mbuf *m = NULL;
+
+ MGETHDR (m, M_WAIT, MT_DATA);
+ MCLGET (m, M_WAIT);
+ m->m_pkthdr.rcvif = ifp;
+
+ /* XXX: The dcbi operation does not work properly */
+ rtems_cache_flush_multiple_data_lines(mtod(m, void *), ETHER_MAX_LEN);
+
+ bd->DataPtr [0] = mtod(m, uint32);
+ bd->Status = ETHER_MAX_LEN | FEC_BD_READY;
+
+ return m;
+}
+
+static TaskBD1_t *mpc5200_fec_init_rx_dma(
+ struct ifnet *ifp,
+ int bdCount,
+ struct mbuf **mbufs
+)
+{
+ TaskSetupParamSet_t param = {
+ .NumBD = bdCount,
+ .Size = {
+ .MaxBuf = ETHER_MAX_LEN
+ },
+ .Initiator = 0,
+ .StartAddrSrc = (uint32) &mpc5200.rfifo_data,
+ .IncrSrc = 0,
+ .SzSrc = sizeof(uint32_t),
+ .StartAddrDst = 0,
+ .IncrDst = sizeof(uint32_t),
+ .SzDst = sizeof(uint32_t)
+ };
+ TaskBD1_t *bdRing = NULL;
+ int bdIndex = 0;
+
+ TaskSetup(FEC_RECV_TASK_NO, ¶m);
+ bdRing = (TaskBD1_t *) TaskGetBDRing(FEC_RECV_TASK_NO);
+
+ for (bdIndex = 0; bdIndex < bdCount; ++bdIndex) {
+ mbufs [bdIndex] = mpc5200_fec_add_mbuf(ifp, &bdRing [bdIndex]);
+ }
+
+ return bdRing;
+}
+
+static void mpc5200_fec_reset_rx_dma(int bdCount, TaskBD1_t *bdRing)
+{
+ int bdIndex = 0;
+
+ TaskStop(FEC_RECV_TASK_NO);
+ TaskBDReset(FEC_RECV_TASK_NO);
+
+ for (bdIndex = 0; bdIndex < bdCount; ++bdIndex) {
+ bdRing [bdIndex].Status = ETHER_MAX_LEN | FEC_BD_READY;
+ }
+}
+
+static int mpc5200_fec_ether_input(
+ struct ifnet *ifp,
+ int bdIndex,
+ int bdCount,
+ TaskBD1_t *bdRing,
+ struct mbuf **mbufs
+)
+{
+ while (true) {
+ TaskBD1_t *bd = &bdRing [bdIndex];
+ struct mbuf *m = mbufs [bdIndex];
+ uint32 status = 0;
+ int len = 0;
+ struct ether_header *eh = NULL;
+
+ SDMA_CLEAR_IEVENT(&mpc5200.sdma.IntPend, FEC_RECV_TASK_NO);
+ status = bd->Status;
+
+ if ((status & FEC_BD_READY) != 0) {
+ break;
+ }
+
+ eh = mtod(m, struct ether_header *);
+
+ len = (status & 0xffff) - ETHER_HDR_LEN - ETHER_CRC_LEN;
+ m->m_len = len;
+ m->m_pkthdr.len = len;
+ m->m_data = mtod(m, char *) + ETHER_HDR_LEN;
+
+ ether_input(ifp, eh, m);
+
+ mbufs [bdIndex] = mpc5200_fec_add_mbuf(ifp, bd);
+
+ if (bdIndex < bdCount - 1) {
+ ++bdIndex;
+ } else {
+ bdIndex = 0;
+ }
+ }
+
+ return bdIndex;
+}
+
+static void mpc5200_fec_rx_daemon(void *arg)
+{
+ mpc5200_fec_context *self = arg;
+ struct ifnet *ifp = &self->arpcom.ac_if;
+ int bdIndex = 0;
+ int bdCount = self->rxBdCount;
+ struct mbuf **mbufs = &self->rxMbuf [0];
+ TaskBD1_t *bdRing = mpc5200_fec_init_rx_dma(ifp, bdCount, mbufs);
+
+ while (true) {
+ bestcomm_glue_irq_enable(FEC_RECV_TASK_NO);
+ mpc5200_fec_wait_for_event();
+
+ bdIndex = mpc5200_fec_ether_input(ifp, bdIndex, bdCount, bdRing, mbufs);
+
+ if (self->state != FEC_STATE_NORMAL) {
+ mpc5200_fec_reset_rx_dma(bdCount, bdRing);
+ mpc5200_fec_restart(self, self->txDaemonTid);
+ bdIndex = 0;
+ }
+ }
+}
</font>
/*
* Initialize and start the device
*/
static void mpc5200_fec_init(void *arg)
{
<font color='#880000'>- struct mpc5200_enet_struct *sc = (struct mpc5200_enet_struct *)arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- rtems_irq_connect_data fec_irq_data = {
- BSP_SIU_IRQ_ETH,
- mpc5200_fec_irq_handler, /* rtems_irq_hdl */
- (rtems_irq_hdl_param)sc, /* (rtems_irq_hdl_param) */
- mpc5200_fec_irq_on, /* (rtems_irq_enable) */
- mpc5200_fec_irq_off, /* (rtems_irq_disable) */
- mpc5200_fec_irq_isOn /* (rtems_irq_is_enabled) */
- };
-
</font><font color='#000088'>+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ mpc5200_fec_context *self = (mpc5200_fec_context *)arg;
+ struct ifnet *ifp = &self->arpcom.ac_if;
</font>
<font color='#880000'>- if(sc->txDaemonTid == 0)
</font><font color='#000088'>+ if(self->txDaemonTid == 0)
</font> {
<font color='#000088'>+ size_t rxMbufTableSize = self->rxBdCount * sizeof(*self->rxMbuf);
+ size_t txMbufTableSize = self->txBdCount * sizeof(*self->txMbuf);
+
</font> /*
* Allocate a set of mbuf pointers
*/
<font color='#880000'>- sc->rxMbuf =
- malloc(sc->rxBdCount * sizeof *sc->rxMbuf, M_MBUF, M_NOWAIT);
- sc->txMbuf =
- malloc(sc->txBdCount * sizeof *sc->txMbuf, M_MBUF, M_NOWAIT);
</font><font color='#000088'>+ self->rxMbuf = malloc(rxMbufTableSize, M_MBUF, M_NOWAIT);
+ self->txMbuf = malloc(txMbufTableSize, M_MBUF, M_NOWAIT);
</font>
<font color='#880000'>- if(!sc->rxMbuf || !sc->txMbuf)
</font><font color='#000088'>+ if(!self->rxMbuf || !self->txMbuf)
</font> rtems_panic ("No memory for mbuf pointers");
<font color='#000088'>+ /*
+ * DMA setup
+ */
</font> bestcomm_glue_init();
<font color='#880000'>-
- mpc5200_sdma_task_setup(sc);
</font><font color='#000088'>+ mpc5200.sdma.ipr [0] = 4; /* always initiator */
+ mpc5200.sdma.ipr [3] = 6; /* eth rx initiator */
+ mpc5200.sdma.ipr [4] = 5; /* eth tx initiator */
</font>
/*
* Set up interrupts
*/
bestcomm_glue_irq_install(FEC_RECV_TASK_NO,
mpc5200_smartcomm_rx_irq_handler,
<font color='#880000'>- NULL);
</font><font color='#000088'>+ self);
</font> bestcomm_glue_irq_install(FEC_XMIT_TASK_NO,
mpc5200_smartcomm_tx_irq_handler,
<font color='#880000'>- NULL);
- if(!BSP_install_rtems_irq_handler (&fec_irq_data)) {
</font><font color='#000088'>+ self);
+ sc = rtems_interrupt_handler_install(
+ BSP_SIU_IRQ_ETH,
+ "FEC",
+ RTEMS_INTERRUPT_UNIQUE,
+ mpc5200_fec_irq_handler,
+ self
+ );
+ if(sc != RTEMS_SUCCESSFUL) {
</font> rtems_panic ("Can't attach MPC5x00 FEX interrupt handler\n");
}
<font color='#880000'>- /* mpc5200_fec_tx_bd_init(sc); */
- mpc5200_fec_rx_bd_init(sc);
-
- /*
- * reset and Set up mpc5200 FEC hardware
- */
- mpc5200_fec_initialize_hardware(sc);
- /*
- * Set up the phy
- */
- mpc5200_fec_initialize_phy(sc);
- /*
- * Set priority of different initiators
- */
- mpc5200.sdma.ipr [0] = 7; /* always initiator */
- mpc5200.sdma.ipr [3] = 6; /* eth rx initiator */
- mpc5200.sdma.ipr [4] = 5; /* eth tx initiator */
-
</font> /*
* Start driver tasks
*/
<font color='#880000'>- sc->txDaemonTid = rtems_bsdnet_newproc("FEtx", 4096, mpc5200_fec_txDaemon, sc);
- sc->rxDaemonTid = rtems_bsdnet_newproc("FErx", 4096, mpc5200_fec_rxDaemon, sc);
- /*
- * Clear SmartDMA task interrupt pending bits.
- */
- TaskIntClear( rxTaskId );
-
- /*
- * Enable the SmartDMA receive task.
- */
- TaskStart( rxTaskId, 1, rxTaskId, 1 );
- TaskStart( txTaskId, 1, txTaskId, 1 );
- /*
- * Enable FEC-Lite controller
- */
- mpc5200.ecntrl |= (FEC_ECNTRL_OE | FEC_ECNTRL_EN);
-
-
</font><font color='#000088'>+ self->txDaemonTid = rtems_bsdnet_newproc("FEtx", 4096, mpc5200_fec_tx_daemon, self);
+ self->rxDaemonTid = rtems_bsdnet_newproc("FErx", 4096, mpc5200_fec_rx_daemon, self);
</font> }
<font color='#000088'>+ mpc5200_fec_request_restart(self);
+
</font> /*
* Set flags appropriately
*/
<font color='#997700'>@@ -1439,123 +1262,41 @@
</font> ifp->if_flags |= IFF_RUNNING;
}
<font color='#880000'>-
-static void enet_stats (struct mpc5200_enet_struct *sc)
</font><font color='#000088'>+static void enet_stats (mpc5200_fec_context *self)
</font> {
<font color='#880000'>- printf (" Rx Interrupts:%-8lu", sc->rxInterrupts);
- printf (" Not First:%-8lu", sc->rxNotFirst);
- printf (" Not Last:%-8lu\n", sc->rxNotLast);
- printf (" Giant:%-8lu", sc->rxGiant);
- printf (" Non-octet:%-8lu\n", sc->rxNonOctet);
- printf (" Bad CRC:%-8lu", sc->rxBadCRC);
- printf (" Overrun:%-8lu", sc->rxOverrun);
- printf (" Collision:%-8lu\n", sc->rxCollision);
-
- printf (" Tx Interrupts:%-8lu", sc->txInterrupts);
- printf (" Deferred:%-8lu", sc->txDeferred);
- printf (" Late Collision:%-8lu\n", sc->txLateCollision);
- printf (" Retransmit Limit:%-8lu", sc->txRetryLimit);
- printf (" Underrun:%-8lu", sc->txUnderrun);
- printf (" Misaligned:%-8lu\n", sc->txMisaligned);
-
-}
-
-/*
- * restart the driver, reinit the fec
- * this function is responsible to reinitialize the FEC in case a fatal
- * error has ocurred. This is needed, wen a RxFIFO Overrun or a TxFIFO underrun
- * has ocurred. In these cases, the FEC is automatically disabled, and
- * both FIFOs must be reset and the BestComm tasks must be restarted
- *
- * Note: the daemon tasks will continue to run
- * (in fact this function will be called in the context of the rx daemon task)
- */
-#define NEW_SDMA_SETUP
-
-static void mpc5200_fec_restart(struct mpc5200_enet_struct *sc)
-{
- /*
- * FIXME: bring Tx Daemon into idle state
- */
-#ifdef NEW_SDMA_SETUP
- /*
- * cleanup remaining receive mbufs
- */
- mpc5200_fec_rx_bd_cleanup(sc);
-#endif
- /*
- * Stop SDMA tasks
- */
- TaskStop( rxTaskId);
- TaskStop( txTaskId);
- /*
- * FIXME: wait, until Tx Daemon is in idle state
- */
-
- /*
- * Disable transmit / receive interrupts
- */
- bestcomm_glue_irq_disable(FEC_XMIT_TASK_NO);
- bestcomm_glue_irq_disable(FEC_RECV_TASK_NO);
-#ifdef NEW_SDMA_SETUP
- /*
- * recycle pending tx buffers
- * FIXME: try to extract pending Tx buffers
- */
-#if 0
- mpc5200_fec_tx_bd_requeue(sc);
-#else
- mpc5200_fec_retire_tbd(sc,true);
-#endif
-#endif
- /*
- * re-initialize the FEC hardware
- */
- mpc5200_fec_initialize_hardware(sc);
-
-#ifdef NEW_SDMA_SETUP
- /*
- * completely reinitialize Bestcomm tasks
- */
- mpc5200_sdma_task_setup(sc);
-
- /*
- * reinit receive mbufs
- */
- mpc5200_fec_rx_bd_init(sc);
-#endif
- /*
- * Clear SmartDMA task interrupt pending bits.
- */
- TaskIntClear( rxTaskId );
-
- /*
- * Enable the SmartDMA receive/transmit task.
- */
- TaskStart( rxTaskId, 1, rxTaskId, 1 );
- TaskStart( txTaskId, 1, txTaskId, 1 );
- /*
- * reenable rx/tx interrupts
- */
- bestcomm_glue_irq_enable(FEC_XMIT_TASK_NO);
- bestcomm_glue_irq_enable(FEC_RECV_TASK_NO);
- /*
- * (re-)init fec hardware
- */
- mpc5200_fec_initialize_hardware(sc);
- /*
- * reenable fec FIFO error interrupts
- */
- mpc5200.imask = FEC_INTR_MASK_USED;
- /*
- * Enable FEC-Lite controller
- */
- mpc5200.ecntrl |= (FEC_ECNTRL_OE | FEC_ECNTRL_EN);
</font><font color='#000088'>+ if (self->phyAddr >= 0) {
+ struct ifnet *ifp = &self->arpcom.ac_if;
+ int media = IFM_MAKEWORD(0, 0, 0, self->phyAddr);
+ int rv = (*ifp->if_ioctl)(ifp, SIOCGIFMEDIA, (caddr_t) &media);
+
+ if (rv == 0) {
+ rtems_ifmedia2str(media, NULL, 0);
+ printf ("\n");
+ } else {
+ printf ("PHY communication error\n");
+ }
+ }
+ printf (" Rx Interrupts:%-8lu", self->rxInterrupts);
+ printf (" Rx Not First:%-8lu", self->rxNotFirst);
+ printf (" Rx Not Last:%-8lu\n", self->rxNotLast);
+ printf (" Rx Giant:%-8lu", self->rxGiant);
+ printf (" Rx Non-octet:%-8lu", self->rxNonOctet);
+ printf (" Rx Bad CRC:%-8lu\n", self->rxBadCRC);
+ printf (" Rx FIFO Error:%-8lu", self->rxFIFOError);
+ printf (" Rx Collision:%-8lu", self->rxCollision);
+
+ printf (" Tx Interrupts:%-8lu\n", self->txInterrupts);
+ printf (" Tx Deferred:%-8lu", self->txDeferred);
+ printf (" Tx Late Collision:%-8lu", self->txLateCollision);
+ printf (" Tx Retransmit Limit:%-8lu\n", self->txRetryLimit);
+ printf (" Tx Underrun:%-8lu", self->txUnderrun);
+ printf (" Tx FIFO Error:%-8lu", self->txFIFOError);
+ printf (" Tx Misaligned:%-8lu\n", self->txMisaligned);
</font> }
int32_t mpc5200_fec_setMultiFilter(struct ifnet *ifp)
{
<font color='#880000'>- /*struct mpc5200_enet_struct *sc = ifp->if_softc; */
</font><font color='#000088'>+ /*mpc5200_fec_context *self = ifp->if_softc; */
</font> /* XXX anything to do? */
return 0;
}
<font color='#997700'>@@ -1566,7 +1307,7 @@
</font> */
static int mpc5200_fec_ioctl (struct ifnet *ifp, ioctl_command_t command, caddr_t data)
{
<font color='#880000'>- struct mpc5200_enet_struct *sc = ifp->if_softc;
</font><font color='#000088'>+ mpc5200_fec_context *self = ifp->if_softc;
</font> int error = 0;
switch(command)
<font color='#997700'>@@ -1583,8 +1324,8 @@
</font> case SIOCDELMULTI: {
struct ifreq* ifr = (struct ifreq*) data;
error = (command == SIOCADDMULTI)
<font color='#880000'>- ? ether_addmulti(ifr, &sc->arpcom)
- : ether_delmulti(ifr, &sc->arpcom);
</font><font color='#000088'>+ ? ether_addmulti(ifr, &self->arpcom)
+ : ether_delmulti(ifr, &self->arpcom);
</font>
if (error == ENETRESET) {
if (ifp->if_flags & IFF_RUNNING)
<font color='#997700'>@@ -1602,20 +1343,20 @@
</font>
case IFF_RUNNING:
<font color='#880000'>- mpc5200_fec_off(sc);
</font><font color='#000088'>+ mpc5200_fec_off(self);
</font>
break;
case IFF_UP:
<font color='#880000'>- mpc5200_fec_init(sc);
</font><font color='#000088'>+ mpc5200_fec_init(self);
</font>
break;
case IFF_UP | IFF_RUNNING:
<font color='#880000'>- mpc5200_fec_off(sc);
- mpc5200_fec_init(sc);
</font><font color='#000088'>+ mpc5200_fec_off(self);
+ mpc5200_fec_init(self);
</font>
break;
<font color='#997700'>@@ -1626,9 +1367,14 @@
</font>
break;
<font color='#000088'>+ case SIOCGIFMEDIA:
+ case SIOCSIFMEDIA:
+ error = rtems_mii_ioctl(&self->mdio, self, command, (int *) data);
+ break;
+
</font> case SIO_RTEMS_SHOW_STATS:
<font color='#880000'>- enet_stats(sc);
</font><font color='#000088'>+ enet_stats(self);
</font>
break;
<font color='#997700'>@@ -1653,7 +1399,7 @@
</font> */
int rtems_mpc5200_fec_driver_attach(struct rtems_bsdnet_ifconfig *config)
{
<font color='#880000'>- struct mpc5200_enet_struct *sc;
</font><font color='#000088'>+ mpc5200_fec_context *self;
</font> struct ifnet *ifp;
int mtu;
int unitNumber;
<font color='#997700'>@@ -1676,8 +1422,8 @@
</font>
}
<font color='#880000'>- sc = &enet_driver[unitNumber - 1];
- ifp = &sc->arpcom.ac_if;
</font><font color='#000088'>+ self = &enet_driver[unitNumber - 1];
+ ifp = &self->arpcom.ac_if;
</font>
if(ifp->if_softc != NULL)
{
<font color='#997700'>@@ -1687,6 +1433,9 @@
</font>
}
<font color='#000088'>+ self->mdio.mdio_r = mpc5200_eth_mii_read;
+ self->mdio.mdio_w = mpc5200_eth_mii_write;
+
</font> /*
* Process options
*/
<font color='#997700'>@@ -1726,7 +1475,7 @@
</font> {
/* Anything in the first three bytes indicates a non-zero entry, copy value */
<font color='#880000'>-<span style="background-color: #FF0000"> </span> memcpy((void *)sc->arpcom.ac_enaddr, &nvram->enaddr, ETHER_ADDR_LEN);
</font><font color='#000088'>+<span style="background-color: #FF0000"> </span> memcpy((void *)self->arpcom.ac_enaddr, &nvram->enaddr, ETHER_ADDR_LEN);
</font>
}
else
<font color='#997700'>@@ -1734,7 +1483,7 @@
</font> {
/* There is no entry in NVRAM, but there is in the ifconfig struct, so use it. */
<font color='#880000'>- memcpy((void *)sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
</font><font color='#000088'>+ memcpy((void *)self->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
</font> }
else
{
<font color='#997700'>@@ -1749,7 +1498,7 @@
</font> if(config->hardware_address)
{
<font color='#880000'>- memcpy(sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
</font><font color='#000088'>+ memcpy(self->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
</font>
}
else
<font color='#997700'>@@ -1764,11 +1513,11 @@
</font>
#endif /* NVRAM_CONFIGURE != 1 */
#ifdef HAS_UBOOT
<font color='#880000'>- if ((sc->arpcom.ac_enaddr[0] == 0) &&
- (sc->arpcom.ac_enaddr[1] == 0) &&
- (sc->arpcom.ac_enaddr[2] == 0)) {
</font><font color='#000088'>+ if ((self->arpcom.ac_enaddr[0] == 0) &&
+ (self->arpcom.ac_enaddr[1] == 0) &&
+ (self->arpcom.ac_enaddr[2] == 0)) {
</font> memcpy(
<font color='#880000'>- (void *)sc->arpcom.ac_enaddr,
</font><font color='#000088'>+ (void *)self->arpcom.ac_enaddr,
</font> bsp_uboot_board_info.bi_enetaddr,
ETHER_ADDR_LEN
);
<font color='#997700'>@@ -1780,21 +1529,21 @@
</font> mtu = ETHERMTU;
if(config->rbuf_count)
<font color='#880000'>- sc->rxBdCount = config->rbuf_count;
</font><font color='#000088'>+ self->rxBdCount = config->rbuf_count;
</font> else
<font color='#880000'>- sc->rxBdCount = RX_BUF_COUNT;
</font><font color='#000088'>+ self->rxBdCount = RX_BUF_COUNT;
</font>
if(config->xbuf_count)
<font color='#880000'>- sc->txBdCount = config->xbuf_count;
</font><font color='#000088'>+ self->txBdCount = config->xbuf_count;
</font> else
<font color='#880000'>- sc->txBdCount = TX_BUF_COUNT * TX_BD_PER_BUF;
</font><font color='#000088'>+ self->txBdCount = TX_BUF_COUNT;
</font>
<font color='#880000'>- sc->acceptBroadcast = !config->ignore_broadcast;
</font><font color='#000088'>+ self->acceptBroadcast = !config->ignore_broadcast;
</font>
/*
* Set up network interface values
*/
<font color='#880000'>- ifp->if_softc = sc;
</font><font color='#000088'>+ ifp->if_softc = self;
</font> ifp->if_unit = unitNumber;
ifp->if_name = unitName;
ifp->if_mtu = mtu;
<font color='#006600'>diff -u rtems/c/src/lib/libbsp/powerpc/gen5200/start/start.S:1.15 rtems/c/src/lib/libbsp/powerpc/gen5200/start/start.S:1.16
--- rtems/c/src/lib/libbsp/powerpc/gen5200/start/start.S:1.15 Thu Dec 30 07:04:24 2010
+++ rtems/c/src/lib/libbsp/powerpc/gen5200/start/start.S Fri Jun 17 06:58:41 2011
</font><font color='#997700'>@@ -156,6 +156,68 @@
</font>
.extern boot_card
<font color='#000088'>+.section ".vectors", "ax"
+ bl start
+ .rep 63
+ .long 0x04000400
+ .endr
+__vec2: b __vec2
+ .rep 63
+ .long 0x04000400
+ .endr
+__vec3: b __vec3
+ .rep 63
+ .long 0x04000400
+ .endr
+__vec4: b __vec4
+ .rep 63
+ .long 0x04000400
+ .endr
+__vec5: b __vec5
+ .rep 63
+ .long 0x04000400
+ .endr
+__vec6: b __vec6
+ .rep 63
+ .long 0x04000400
+ .endr
+__vec7: b __vec7
+ .rep 63
+ .long 0x04000400
+ .endr
+__vec8: b __vec8
+ .rep 63
+ .long 0x04000400
+ .endr
+__vec9: b __vec9
+ .rep 63
+ .long 0x04000400
+ .endr
+__veca: b __veca
+ .rep 63
+ .long 0x04000400
+ .endr
+__vecb: b __vecb
+ .rep 63
+ .long 0x04000400
+ .endr
+__vecc: b __vecc
+ .rep 63
+ .long 0x04000400
+ .endr
+__vecd: b __vecd
+ .rep 63
+ .long 0x04000400
+ .endr
+__vece: b __vece
+ .rep 63
+ .long 0x04000400
+ .endr
+__vecf: b __vecf
+ .rep 63+1024
+ .long 0x04000400
+ .endr
+
</font> .section ".entry"
PUBLIC_VAR (start)
start:
<font color='#997700'>@@ -243,7 +305,7 @@
</font> rlwinm r30, r30,17,15,31
stw r30, CS0STR(r31)<span style="background-color: #FF0000"> </span> /* Set CS0STR */
<font color='#880000'>- LWI r30, bsp_rom_end
</font><font color='#000088'>+ LWI r30, bsp_rom_end - 1
</font>
rlwinm r30, r30,17,15,31
stw r30, CS0STP(r31)<span style="background-color: #FF0000"> </span> /* Set CS0STP */
<font color='#997700'>@@ -279,18 +341,7 @@
</font>
bl SDRAM_init /* Initialize SDRAM controller */
<font color='#880000'>-/* init arbiter and stuff... */
- LWI r30, 0x8000a06e
- stw r30, ARBCFG(r31)<span style="background-color: #FF0000"> </span> /* Set ARBCFG */
-
- LWI r30, 0x000000ff
- stw r30, ARBMPREN(r31)<span style="background-color: #FF0000"> </span> /* Set ARBMPREN */
-
- LWI r30, 0x00001234
- stw r30, ARBMPRIO(r31)<span style="background-color: #FF0000"> </span> /* Set ARBPRIO */
-
- LWI r30, 0x0000001e
- stw r30, ARBSNOOP(r31)<span style="background-color: #FF0000"> </span> /* Set ARBSNOOP */
</font><font color='#000088'>+ bl XLB_init
</font> /* copy .text section from ROM to RAM location (unique for ROM startup) */
LA r30, bsp_section_text_start /* get start address of text section in RAM */
<font color='#997700'>@@ -395,6 +446,8 @@
</font>
bl clr_mem /* Clear onchip SRAM */
<font color='#000088'>+#else /* defined(NEED_LOW_LEVEL_INIT) */
+ bl XLB_init
</font> #endif /* defined(NEED_LOW_LEVEL_INIT) */
/* clear .bss section (unique for ROM startup) */
LWI r30, bsp_section_bss_start /* get start address of bss section */
<font color='#997700'>@@ -843,5 +896,18 @@
</font> clr_mem_end:
blr /* return */
<font color='#000088'>+XLB_init:
+/* init arbiter and stuff... */
+ LWI r30, 0x8000a06e
+ stw r30, ARBCFG(r31)<span style="background-color: #FF0000"> </span> /* Set ARBCFG */
+
+ LWI r30, 0x000000ff
+ stw r30, ARBMPREN(r31)<span style="background-color: #FF0000"> </span> /* Set ARBMPREN */
</font>
<font color='#000088'>+ LWI r30, 0x00001234
+ stw r30, ARBMPRIO(r31)<span style="background-color: #FF0000"> </span> /* Set ARBPRIO */
+
+ LWI r30, 0x0000001e
+ stw r30, ARBSNOOP(r31)<span style="background-color: #FF0000"> </span> /* Set ARBSNOOP */
</font>
<font color='#000088'>+ blr
</font>
<font color='#006600'>diff -u rtems/c/src/lib/libbsp/powerpc/gen5200/startup/bspstart.c:1.32 rtems/c/src/lib/libbsp/powerpc/gen5200/startup/bspstart.c:1.33
--- rtems/c/src/lib/libbsp/powerpc/gen5200/startup/bspstart.c:1.32 Tue Jun 7 08:38:54 2011
+++ rtems/c/src/lib/libbsp/powerpc/gen5200/startup/bspstart.c Fri Jun 17 06:58:41 2011
</font><font color='#997700'>@@ -103,6 +103,7 @@
</font> #include <bsp/bootcard.h>
#include <bsp/irq.h>
#include <bsp/irq-generic.h>
<font color='#000088'>+#include <bsp/mpc5200.h>
</font>
/*
* Driver configuration parameters
<font color='#997700'>@@ -144,6 +145,18 @@
</font>
cpu_init();
<font color='#000088'>+ if(get_ppc_cpu_revision() >= 0x2014) {
+ /* Special settings for MPC5200B (B variant) */
+ uint32_t xlb_cfg = mpc5200.config;
+
+ /* XXX: The Freescale documentation for BSDIS seems to be wrong */
+ xlb_cfg |= XLB_CFG_BSDIS;
+
+ xlb_cfg &= ~XLB_CFG_PLDIS;
+
+ mpc5200.config = xlb_cfg;
+ }
+
</font> bsp_clicks_per_usec = (XLB_CLOCK/4000000);
/*
<font color='#997700'>@@ -166,6 +179,7 @@
</font> if (sc != RTEMS_SUCCESSFUL) {
BSP_panic("cannot initialize exceptions");
}
<font color='#000088'>+ ppc_exc_set_handler(ASM_ALIGN_VECTOR, ppc_exc_alignment_handler);
</font>
/* Initalize interrupt support */
sc = bsp_interrupt_initialize();
<font color='#006600'>diff -u rtems/c/src/lib/libbsp/powerpc/gen5200/startup/cpuinit.c:1.10 rtems/c/src/lib/libbsp/powerpc/gen5200/startup/cpuinit.c:1.11
--- rtems/c/src/lib/libbsp/powerpc/gen5200/startup/cpuinit.c:1.10 Mon Nov 15 04:55:02 2010
+++ rtems/c/src/lib/libbsp/powerpc/gen5200/startup/cpuinit.c Fri Jun 17 06:58:41 2011
</font><font color='#997700'>@@ -169,6 +169,14 @@
</font> uint32_t start = 0;
/*
<font color='#000088'>+ * Accesses (also speculative accesses) outside of the RAM area are a
+ * disaster especially in combination with the BestComm. For safety reasons
+ * we make the available RAM a little bit smaller to have an unused area at
+ * the end.
+ */
+ bsp_uboot_board_info.bi_memsize -= 4 * 1024;
+
+ /*
</font> * Program BAT0 for RAM
*/
calc_dbat_regvals(
<font color='#006600'>diff -u rtems/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.brs5l:1.8 rtems/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.brs5l:1.9
--- rtems/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.brs5l:1.8 Mon Nov 15 04:55:02 2010
+++ rtems/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.brs5l Fri Jun 17 06:58:41 2011
</font><font color='#997700'>@@ -5,7 +5,8 @@
</font> */
MEMORY {
<font color='#880000'>- RAM : ORIGIN = 0x0, LENGTH = 128M
</font><font color='#000088'>+ /* For the 4k adjustment see cpuinit.c */
+ RAM : ORIGIN = 0x0, LENGTH = 128M - 4k
</font> ROM : ORIGIN = 0xffe00000, LENGTH = 2M
DPRAM : ORIGIN = 0xff000000, LENGTH = 1k
REGS : ORIGIN = 0xf0000000, LENGTH = 64k
<font color='#006600'>diff -u rtems/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.dp2:1.1 rtems/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.dp2:1.2
--- rtems/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.dp2:1.1 Mon Nov 15 04:55:02 2010
+++ rtems/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.dp2 Fri Jun 17 06:58:41 2011
</font><font color='#997700'>@@ -5,10 +5,11 @@
</font> */
MEMORY {
<font color='#880000'>- RAM : ORIGIN = 0x0, LENGTH = 64M
</font><font color='#000088'>+ /* For the 4k adjustment see cpuinit.c */
+ RAM : ORIGIN = 0x0, LENGTH = 64M - 4k
</font> ROM : ORIGIN = 0xffe00000, LENGTH = 2M
<font color='#880000'>- DPRAM : ORIGIN = 0xff000000, LENGTH = 1k
</font> REGS : ORIGIN = 0xf0000000, LENGTH = 64k
<font color='#000088'>+ DPRAM : ORIGIN = 0x0, LENGTH = 0
</font> NIRVANA : ORIGIN = 0x0, LENGTH = 0
}
<font color='#006600'>diff -u rtems/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.icecube:1.4 rtems/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.icecube:1.5
--- rtems/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.icecube:1.4 Wed Sep 3 10:40:11 2008
+++ rtems/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.icecube Fri Jun 17 06:58:41 2011
</font><font color='#997700'>@@ -5,11 +5,12 @@
</font> */
MEMORY {
<font color='#880000'>- RAM : ORIGIN = 0x0, LENGTH = 128M
</font><font color='#000088'>+ /* For the 4k adjustment see cpuinit.c */
+ RAM : ORIGIN = 0x0, LENGTH = 128M - 4k
</font> ROM : ORIGIN = 0xffe00000, LENGTH = 2M
REGS : ORIGIN = 0xf0000000, LENGTH = 64k
<font color='#880000'>- NIRVANA : ORIGIN = 0x0, LENGTH = 0
</font> DPRAM : ORIGIN = 0x0, LENGTH = 0
<font color='#000088'>+ NIRVANA : ORIGIN = 0x0, LENGTH = 0
</font> }
INCLUDE linkcmds.base
<font color='#006600'>diff -u rtems/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.pm520_cr825:1.1 rtems/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.pm520_cr825:1.2
--- rtems/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.pm520_cr825:1.1 Tue Nov 3 22:20:25 2009
+++ rtems/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.pm520_cr825 Fri Jun 17 06:58:41 2011
</font><font color='#997700'>@@ -5,10 +5,11 @@
</font> */
MEMORY {
<font color='#880000'>- RAM : ORIGIN = 0x0, LENGTH = 64M
</font><font color='#000088'>+ /* For the 4k adjustment see cpuinit.c */
+ RAM : ORIGIN = 0x0, LENGTH = 64M - 4k
</font> ROM : ORIGIN = 0xffe00000, LENGTH = 2M
<font color='#880000'>- DPRAM : ORIGIN = 0xff000000, LENGTH = 1k
</font> REGS : ORIGIN = 0xf0000000, LENGTH = 64k
<font color='#000088'>+ DPRAM : ORIGIN = 0xff000000, LENGTH = 1k
</font> NIRVANA : ORIGIN = 0x0, LENGTH = 0
}
<font color='#006600'>diff -u rtems/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.pm520_ze30:1.1 rtems/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.pm520_ze30:1.2
--- rtems/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.pm520_ze30:1.1 Tue Nov 3 22:20:25 2009
+++ rtems/c/src/lib/libbsp/powerpc/gen5200/startup/linkcmds.pm520_ze30 Fri Jun 17 06:58:41 2011
</font><font color='#997700'>@@ -5,10 +5,11 @@
</font> */
MEMORY {
<font color='#880000'>- RAM : ORIGIN = 0x0, LENGTH = 64M
</font><font color='#000088'>+ /* For the 4k adjustment see cpuinit.c */
+ RAM : ORIGIN = 0x0, LENGTH = 64M - 4k
</font> ROM : ORIGIN = 0xffe00000, LENGTH = 2M
<font color='#880000'>- DPRAM : ORIGIN = 0xff000000, LENGTH = 1k
</font> REGS : ORIGIN = 0xf0000000, LENGTH = 64k
<font color='#000088'>+ DPRAM : ORIGIN = 0xff000000, LENGTH = 1k
</font> NIRVANA : ORIGIN = 0x0, LENGTH = 0
}
</pre>
<p> </p>
<p>--<br />
<small>Generated by <a href="http://www.codewiz.org/projects/index.html#loginfo">Deluxe Loginfo</a> 2.122 by Bernardo Innocenti <bernie@develer.com></small></p>
</body>
</html>