This is the mail archive of the
ecos-patches@sources.redhat.com
mailing list for the eCos project.
FEC - Use CPM/DPRAM allocatos
- From: Gary Thomas <gary at mlbassoc dot com>
- To: eCos patches <ecos-patches at sources dot redhat dot com>
- Date: 28 Mar 2003 06:12:36 -0700
- Subject: FEC - Use CPM/DPRAM allocatos
Index: devs/eth/powerpc/fec/current/ChangeLog
===================================================================
RCS file: /misc/cvsfiles/ecos/packages/devs/eth/powerpc/fec/current/ChangeLog,v
retrieving revision 1.15
diff -u -5 -p -r1.15 ChangeLog
--- devs/eth/powerpc/fec/current/ChangeLog 20 Jan 2003 11:13:55 -0000 1.15
+++ devs/eth/powerpc/fec/current/ChangeLog 28 Mar 2003 13:06:23 -0000
@@ -1,5 +1,10 @@
+2003-03-28 Gary Thomas <gary at mlbassoc dot com>
+
+ * src/if_fec.c: Use new CPM/DPRAM buffer allocation scheme. Also,
+ better handling when aligning buffers to cache lines.
+
2003-01-20 Gary Thomas <gary at mlbassoc dot com>
* cdl/fec_eth_drivers.cdl: Increase number of allowed buffers.
2002-11-14 Gary Thomas <gthomas at ecoscentric dot com>
Index: devs/eth/powerpc/fec/current/src/if_fec.c
===================================================================
RCS file: /misc/cvsfiles/ecos/packages/devs/eth/powerpc/fec/current/src/if_fec.c,v
retrieving revision 1.14
diff -u -5 -p -r1.14 if_fec.c
--- devs/eth/powerpc/fec/current/src/if_fec.c 18 Oct 2002 16:56:54 -0000 1.14
+++ devs/eth/powerpc/fec/current/src/if_fec.c 28 Mar 2003 13:06:25 -0000
@@ -7,11 +7,11 @@
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
-// Copyright (C) 2002 Gary Thomas
+// Copyright (C) 2002, 2003 Gary Thomas
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
@@ -76,21 +76,17 @@
#include <cyg/io/eth/netdev.h>
#include <cyg/io/eth/eth_drv.h>
#include "fec.h"
-// Define this to force the buffer descriptors into the EPPC memory
-#define FEC_USE_EPPC_BD
+// Align buffers on a cache boundary
+#define CACHE_ALIGN(b) (((unsigned long)(b) + (HAL_DCACHE_LINE_SIZE-1)) & ~(HAL_DCACHE_LINE_SIZE-1))
-#ifndef FEC_USE_EPPC_BD
-static struct fec_bd fec_eth_rxring[CYGNUM_DEVS_ETH_POWERPC_FEC_RxNUM];
-static struct fec_bd fec_eth_txring[CYGNUM_DEVS_ETH_POWERPC_FEC_TxNUM];
-#endif
-static unsigned char fec_eth_rxbufs[CYGNUM_DEVS_ETH_POWERPC_FEC_RxNUM+1]
- [CYGNUM_DEVS_ETH_POWERPC_FEC_BUFSIZE];
-static unsigned char fec_eth_txbufs[CYGNUM_DEVS_ETH_POWERPC_FEC_TxNUM+1]
- [CYGNUM_DEVS_ETH_POWERPC_FEC_BUFSIZE];
+#define RxBUFSIZE CYGNUM_DEVS_ETH_POWERPC_FEC_RxNUM*CYGNUM_DEVS_ETH_POWERPC_FEC_BUFSIZE+HAL_DCACHE_LINE_SIZE
+#define TxBUFSIZE CYGNUM_DEVS_ETH_POWERPC_FEC_TxNUM*CYGNUM_DEVS_ETH_POWERPC_FEC_BUFSIZE+HAL_DCACHE_LINE_SIZE
+static unsigned char fec_eth_rxbufs[RxBUFSIZE];
+static unsigned char fec_eth_txbufs[TxBUFSIZE];
static struct fec_eth_info fec_eth0_info;
static unsigned char _default_enaddr[] = { 0x08, 0x00, 0x3E, 0x28, 0x7A, 0xBA};
static unsigned char enaddr[6];
#ifdef CYGPKG_REDBOOT
@@ -256,10 +252,11 @@ fec_eth_reset(struct eth_drv_sc *sc, uns
volatile struct fec *fec = (volatile struct fec *)((unsigned char *)eppc + FEC_OFFSET);
volatile struct fec_bd *rxbd, *txbd;
unsigned char *RxBUF, *TxBUF;
int cache_state, int_state;
int i;
+ int TxBD, RxBD;
// Ignore unless device is idle/stopped
if ((qi->fec->eControl & eControl_EN) != 0) {
return true;
}
@@ -267,13 +264,14 @@ fec_eth_reset(struct eth_drv_sc *sc, uns
// Make sure interrupts are off while we mess with the device
HAL_DISABLE_INTERRUPTS(int_state);
// Ensure consistent state between cache and what the FEC sees
HAL_DCACHE_IS_ENABLED(cache_state);
- if (cache_state)
+ if (cache_state) {
HAL_DCACHE_SYNC();
- HAL_DCACHE_DISABLE();
+ HAL_DCACHE_DISABLE();
+ }
// Shut down ethernet controller, in case it is already running
fec->eControl = eControl_RESET;
i = 0;
while ((fec->eControl & eControl_RESET) != 0) {
@@ -288,24 +286,20 @@ fec_eth_reset(struct eth_drv_sc *sc, uns
fec->iMask = 0x0000000; // Disables all interrupts
fec->iEvent = 0xFFFFFFFF; // Clear all interrupts
fec->iVector = (1<<29); // Caution - must match FEC_ETH_INT above
-#define ROUNDUP(b,s) (((unsigned long)(b) + (s-1)) & ~(s-1))
-#ifdef FEC_USE_EPPC_BD
- txbd = (struct fec_bd *)(FEC_EPPC_BD_OFFSET + (cyg_uint32)eppc);
- rxbd = &txbd[CYGNUM_DEVS_ETH_POWERPC_FEC_TxNUM];
-#else
- txbd = fec_eth_txring;
- rxbd = fec_eth_rxring;
-#endif
+ TxBD = _mpc8xx_allocBd(CYGNUM_DEVS_ETH_POWERPC_FEC_TxNUM * sizeof(struct cp_bufdesc));
+ RxBD = _mpc8xx_allocBd(CYGNUM_DEVS_ETH_POWERPC_FEC_RxNUM * sizeof(struct cp_bufdesc));
+ txbd = (struct fec_bd *)(TxBD + (cyg_uint32)eppc);
+ rxbd = (struct fec_bd *)(RxBD + (cyg_uint32)eppc);
qi->tbase = qi->txbd = qi->tnext = txbd;
qi->rbase = qi->rxbd = qi->rnext = rxbd;
qi->txactive = 0;
- RxBUF = (unsigned char *)ROUNDUP(&fec_eth_rxbufs[0][0], 32);
- TxBUF = (unsigned char *)ROUNDUP(&fec_eth_txbufs[0][0], 32);
+ RxBUF = (unsigned char *)CACHE_ALIGN(&fec_eth_rxbufs[0]);
+ TxBUF = (unsigned char *)CACHE_ALIGN(&fec_eth_txbufs[0]);
// setup buffer descriptors
for (i = 0; i < CYGNUM_DEVS_ETH_POWERPC_FEC_RxNUM; i++) {
rxbd->length = 0;
rxbd->buffer = RxBUF;
@@ -405,13 +399,14 @@ fec_eth_init(struct cyg_netdevtab_entry
unsigned short phy_state = 0;
#endif
// Ensure consistent state between cache and what the FEC sees
HAL_DCACHE_IS_ENABLED(cache_state);
- if (cache_state)
+ if (cache_state) {
HAL_DCACHE_SYNC();
- HAL_DCACHE_DISABLE();
+ HAL_DCACHE_DISABLE();
+ }
qi->fec = fec;
fec_eth_stop(sc); // Make sure it's not running yet
#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
@@ -642,22 +637,17 @@ fec_eth_send(struct eth_drv_sc *sc, stru
bp += sg_list[i].len;
}
txbd->length = total_len;
txindex = ((unsigned long)txbd - (unsigned long)qi->tbase) / sizeof(*txbd);
qi->txkey[txindex] = key;
- // Note: the MPC860 does not seem to snoop/invalidate the data cache properly!
+ // Note: the MPC8xx does not seem to snoop/invalidate the data cache properly!
HAL_DCACHE_IS_ENABLED(cache_state);
if (cache_state) {
HAL_DCACHE_FLUSH(txbd->buffer, txbd->length); // Make sure no stale data
}
// Send it on it's way
txbd->ctrl |= FEC_BD_Tx_Ready | FEC_BD_Tx_Last | FEC_BD_Tx_TC;
-#ifndef FEC_USE_EPPC_BD
- if (cache_state) {
- HAL_DCACHE_FLUSH(fec_eth_txring, sizeof(fec_eth_txring)); // Make sure no stale data
- }
-#endif
qi->txactive++;
qi->fec->TxUpdate = 0x01000000; // Any write tells machine to look for work
set_led(LED_TxACTIVE);
// Remember the next buffer to try
if (txbd->ctrl & FEC_BD_Tx_Wrap) {
@@ -679,17 +669,12 @@ fec_eth_RxEvent(struct eth_drv_sc *sc)
{
struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
volatile struct fec_bd *rxbd, *rxfirst;
int cache_state;
- // Note: the MPC860 does not seem to snoop/invalidate the data cache properly!
+ // Note: the MPC8xx does not seem to snoop/invalidate the data cache properly!
HAL_DCACHE_IS_ENABLED(cache_state);
-#ifndef FEC_USE_EPPC_BD
- if (cache_state) {
- HAL_DCACHE_INVALIDATE(fec_eth_rxring, sizeof(fec_eth_rxring)); // Make sure no stale data
- }
-#endif
rxbd = rxfirst = qi->rnext;
while (true) {
if ((rxbd->ctrl & FEC_BD_Rx_Empty) == 0) {
qi->rxbd = rxbd; // Save for callback
set_led(LED_RxACTIVE);
@@ -704,15 +689,10 @@ fec_eth_RxEvent(struct eth_drv_sc *sc)
break;
}
}
// Remember where we left off
qi->rnext = (struct fec_bd *)rxbd;
-#ifndef FEC_USE_EPPC_BD
- if (cache_state) {
- HAL_DCACHE_INVALIDATE(fec_eth_rxring, sizeof(fec_eth_rxring)); // Make sure no stale data
- }
-#endif
qi->fec->RxUpdate = 0x0F0F0F0F; // Any write tells machine to look for work
}
//
// This function is called as a result of the "eth_drv_recv()" call above.
@@ -727,11 +707,11 @@ fec_eth_recv(struct eth_drv_sc *sc, stru
struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
unsigned char *bp;
int i, cache_state;
bp = (unsigned char *)qi->rxbd->buffer;
- // Note: the MPC860 does not seem to snoop/invalidate the data cache properly!
+ // Note: the MPC8xx does not seem to snoop/invalidate the data cache properly!
HAL_DCACHE_IS_ENABLED(cache_state);
if (cache_state) {
HAL_DCACHE_INVALIDATE(qi->rxbd->buffer, qi->rxbd->length); // Make sure no stale data
}
for (i = 0; i < sg_len; i++) {
@@ -747,18 +727,12 @@ fec_eth_recv(struct eth_drv_sc *sc, stru
static void
fec_eth_TxEvent(struct eth_drv_sc *sc)
{
struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
volatile struct fec_bd *txbd;
- int key, txindex, cache_state;
+ int key, txindex;
- HAL_DCACHE_IS_ENABLED(cache_state);
-#ifndef FEC_USE_EPPC_BD
- if (cache_state) {
- HAL_DCACHE_FLUSH(fec_eth_txring, sizeof(fec_eth_txring)); // Make sure no stale data
- }
-#endif
txbd = qi->tnext;
// Note: TC field is used to indicate the buffer has/had data in it
while ((txbd->ctrl & (FEC_BD_Tx_Ready|FEC_BD_Tx_TC)) == FEC_BD_Tx_TC) {
txindex = ((unsigned long)txbd - (unsigned long)qi->tbase) / sizeof(*txbd);
if ((key = qi->txkey[txindex]) != 0) {
@@ -775,15 +749,10 @@ fec_eth_TxEvent(struct eth_drv_sc *sc)
txbd++;
}
}
// Remember where we left off
qi->tnext = (struct fec_bd *)txbd;
-#ifndef FEC_USE_EPPC_BD
- if (cache_state) {
- HAL_DCACHE_FLUSH(fec_eth_txring, sizeof(fec_eth_txring)); // Make sure no stale data
- }
-#endif
}
//
// Interrupt processing
//
--
------------------------------------------------------------
Gary Thomas |
MLB Associates | Consulting for the
+1 (970) 229-1963 | Embedded world
http://www.mlbassoc.com/ |
email: <gary at mlbassoc dot com> |
gpg: http://www.chez-thomas.org/gary/gpg_key.asc
------------------------------------------------------------