summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/beatnik
diff options
context:
space:
mode:
authorTill Straumann <strauman@slac.stanford.edu>2010-02-10 00:15:06 +0000
committerTill Straumann <strauman@slac.stanford.edu>2010-02-10 00:15:06 +0000
commit5068f3f9944156b341e49055edaaac977dd66fbe (patch)
tree85d0ad8121b6b58b2442611b05add4a47899ddf8 /c/src/lib/libbsp/powerpc/beatnik
parentAdd cloog-ppl. (diff)
downloadrtems-5068f3f9944156b341e49055edaaac977dd66fbe.tar.bz2
2010-02-09 Till Straumann <strauman@slac.stanford.edu>
* network/if_mve/mv643xx_eth.c: Fixed alignment attribute in descriptor declaration. Not the pointers to the descriptors have to be aligned but the descriptors themselves (didn't cause problems but caused unnecessary holes in 'private' struct). FIX: Added more robustness when number of available TX descriptors drops to zero. (This can e.g., happen if the link goes bad causing packets to stall in the FIFO.) At the following points the transmitter is explicitly (re-)started: o when link comes up and number of available TXDs is zero the TX is restarted. o on a failed attempt to send data due to lack of TXDs the TX is restarted if swiping the TX ring doesn't yield any buffers (i.e., if the # of available buffers is still zero after the swipe).
Diffstat (limited to 'c/src/lib/libbsp/powerpc/beatnik')
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/ChangeLog18
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/network/if_mve/mv643xx_eth.c28
2 files changed, 42 insertions, 4 deletions
diff --git a/c/src/lib/libbsp/powerpc/beatnik/ChangeLog b/c/src/lib/libbsp/powerpc/beatnik/ChangeLog
index eb768cb15b..e8dd64c9ea 100644
--- a/c/src/lib/libbsp/powerpc/beatnik/ChangeLog
+++ b/c/src/lib/libbsp/powerpc/beatnik/ChangeLog
@@ -1,3 +1,21 @@
+2010-02-09 Till Straumann <strauman@slac.stanford.edu>
+
+ * network/if_mve/mv643xx_eth.c: Fixed alignment attribute
+ in descriptor declaration. Not the pointers to the descriptors
+ have to be aligned but the descriptors themselves (didn't
+ cause problems but caused unnecessary holes in 'private' struct).
+
+ FIX: Added more robustness when number of available TX descriptors
+ drops to zero. (This can e.g., happen if the link goes bad causing
+ packets to stall in the FIFO.) At the following points the transmitter
+ is explicitly (re-)started:
+ o when link comes up and number of available TXDs is zero the
+ TX is restarted.
+ o on a failed attempt to send data due to lack of TXDs the
+ TX is restarted if swiping the TX ring doesn't yield any
+ buffers (i.e., if the # of available buffers is still zero
+ after the swipe).
+
2009-12-14 Sebastian Huber <sebastian.huber@embedded-brains.de>
* Makefile.am, preinstall.am: Removed ppc_exc_bspsupp.h include file.
diff --git a/c/src/lib/libbsp/powerpc/beatnik/network/if_mve/mv643xx_eth.c b/c/src/lib/libbsp/powerpc/beatnik/network/if_mve/mv643xx_eth.c
index e9e1779574..812961ebc2 100644
--- a/c/src/lib/libbsp/powerpc/beatnik/network/if_mve/mv643xx_eth.c
+++ b/c/src/lib/libbsp/powerpc/beatnik/network/if_mve/mv643xx_eth.c
@@ -687,8 +687,7 @@ typedef volatile struct mveth_rx_desc {
void *u_buf; /* user buffer */
volatile struct mveth_rx_desc *next; /* next descriptor (CPU address; next_desc_ptr is a DMA address) */
uint32_t pad[2];
-} MvEthRxDescRec, *MvEthRxDesc
-__attribute__(( aligned(RING_ALIGNMENT) ));
+} __attribute__(( aligned(RING_ALIGNMENT) )) MvEthRxDescRec, *MvEthRxDesc;
typedef volatile struct mveth_tx_desc {
#ifndef __BIG_ENDIAN__
@@ -703,8 +702,7 @@ typedef volatile struct mveth_tx_desc {
uint32_t workaround[2]; /* use this space to work around the 8byte problem (is this real?) */
void *u_buf; /* user buffer */
volatile struct mveth_tx_desc *next; /* next descriptor (CPU address; next_desc_ptr is a DMA address) */
-} MvEthTxDescRec, *MvEthTxDesc
-__attribute__(( aligned(RING_ALIGNMENT) ));
+} __attribute__(( aligned(RING_ALIGNMENT) )) MvEthTxDescRec, *MvEthTxDesc;
/* Assume there are never more then 64k aliasing entries */
typedef uint16_t Mc_Refcnt[MV643XX_ETH_NUM_MCAST_ENTRIES*4];
@@ -1222,6 +1220,19 @@ unsigned wc = 0;
/* MID-LAYER SUPPORT ROUTINES */
+/* Start TX if descriptors are exhausted */
+static __inline__ void
+mveth_start_tx(struct mveth_private *mp)
+{
+uint32_t running;
+ if ( mp->avail <= 0 ) {
+ running = MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_R(mp->port_num));
+ if ( ! (running & MV643XX_ETH_TX_START(0)) ) {
+ MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_R(mp->port_num), MV643XX_ETH_TX_START(0));
+ }
+ }
+}
+
/* Stop TX and wait for the command queues to stop and the fifo to drain */
static uint32_t
mveth_stop_tx(int port)
@@ -1955,6 +1966,8 @@ startover:
/* if no descriptor is available; try to wipe the queue */
if ( (mp->avail < 1) && MVETH_CLEAN_ON_SEND(mp)<=0 ) {
+ /* Maybe TX is stalled and needs to be restarted */
+ mveth_start_tx(mp);
return -1;
}
@@ -2000,6 +2013,9 @@ startover:
nmbs++;
if ( mp->avail < 1 && MVETH_CLEAN_ON_SEND(mp)<=0 ) {
+ /* Maybe TX was stalled - try to restart */
+ mveth_start_tx(mp);
+
/* not enough descriptors; cleanup...
* the first slot was never used, so we start
* at mp->d_tx_h->next;
@@ -2142,6 +2158,8 @@ int frst_len;
/* if no descriptor is available; try to wipe the queue */
if ( ( mp->avail < needed )
&& ( MVETH_CLEAN_ON_SEND(mp) <= 0 || mp->avail < needed ) ) {
+ /* Maybe TX was stalled and needs a restart */
+ mveth_start_tx(mp);
return -1;
}
@@ -2606,6 +2624,8 @@ int media = IFM_MAKEWORD(0,0,0,0);
if ( 0 == BSP_mve_media_ioctl(mp, SIOCGIFMEDIA, &media)) {
if ( IFM_LINK_OK & media ) {
mveth_update_serial_port(mp, media);
+ /* If TX stalled because there was no buffer then whack it */
+ mveth_start_tx(mp);
}
if ( pmedia )
*pmedia = media;