bugfix patch to arch/ppc/8260_io/fcc_enet.c
David Schleef
ds at schleef.org
Sat Apr 7 00:16:44 EST 2001
The attached patch fixes a bug with 8260 fcc_enet driver that
is related to when the TX buffer becomes full. Currently,
the driver relies on the BD_ENET_TX_READY for determining if
a ring slot is available for a tx buffer. This is not a
valid criterion, because the interrupt handler may not have
cleared the slot from a previous tx buffer. This bug is easy
to generate by writing files over NFS with large wsize.
The patch should apply cleanly to 2_4 and 2_5.
dave...
-------------- next part --------------
--- fcc_enet.c.25 Fri Apr 6 03:29:06 2001
+++ fcc_enet.c Fri Apr 6 04:59:36 2001
@@ -219,8 +219,8 @@
struct fcc_enet_private {
/* The saved address of a sent-in-place packet/buffer, for skfree(). */
struct sk_buff* tx_skbuff[TX_RING_SIZE];
- ushort skb_cur;
- ushort skb_dirty;
+ uint skb_cur;
+ uint skb_dirty;
/* CPM dual port RAM relative addresses.
*/
@@ -329,10 +329,10 @@
/* Save skb pointer.
*/
- cep->tx_skbuff[cep->skb_cur] = skb;
+ cep->tx_skbuff[(cep->skb_cur & TX_RING_MOD_MASK)] = skb;
cep->stats.tx_bytes += skb->len;
- cep->skb_cur = (cep->skb_cur+1) & TX_RING_MOD_MASK;
+ cep->skb_cur++;
spin_lock_irq(&cep->lock);
@@ -355,7 +355,7 @@
else
bdp++;
- if (bdp->cbd_sc & BD_ENET_TX_READY) {
+ if(cep->skb_cur - cep->skb_dirty >= TX_RING_SIZE){
netif_stop_queue(dev);
cep->tx_full = 1;
}
@@ -475,8 +475,8 @@
/* Free the sk buffer associated with this last transmit.
*/
- dev_kfree_skb_irq(cep->tx_skbuff[cep->skb_dirty]);
- cep->skb_dirty = (cep->skb_dirty + 1) & TX_RING_MOD_MASK;
+ dev_kfree_skb_irq(cep->tx_skbuff[(cep->skb_dirty & TX_RING_MOD_MASK)]);
+ cep->skb_dirty++;
/* Update pointer to next buffer descriptor to be transmitted.
*/
More information about the Linuxppc-dev
mailing list