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).
This commit is contained in:
Till Straumann
2010-02-10 00:15:06 +00:00
parent e5e4e3fbf9
commit 5068f3f994
2 changed files with 42 additions and 4 deletions

View File

@@ -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.

View File

@@ -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;