patch-2.4.27 linux-2.4.27/arch/ppc/cpm2_io/fcc_enet.c
Next file: linux-2.4.27/arch/ppc/kernel/head_44x.S
Previous file: linux-2.4.27/arch/ppc/config.in
Back to the patch index
Back to the overall index
- Lines: 58
- Date:
2004-08-07 16:26:04.582343819 -0700
- Orig file:
linux-2.4.26/arch/ppc/cpm2_io/fcc_enet.c
- Orig date:
2004-04-14 06:05:27.000000000 -0700
diff -urN linux-2.4.26/arch/ppc/cpm2_io/fcc_enet.c linux-2.4.27/arch/ppc/cpm2_io/fcc_enet.c
@@ -305,6 +305,8 @@
ushort skb_cur;
ushort skb_dirty;
+ atomic_t n_pkts; /* Number of packets in tx ring */
+
/* CPM dual port RAM relative addresses.
*/
cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */
@@ -396,13 +398,15 @@
bdp->cbd_datlen = skb->len;
bdp->cbd_bufaddr = __pa(skb->data);
+ spin_lock_irq(&cep->lock);
+
/* Save skb pointer. */
cep->tx_skbuff[cep->skb_cur] = skb;
cep->stats.tx_bytes += skb->len;
cep->skb_cur = (cep->skb_cur+1) & TX_RING_MOD_MASK;
- spin_lock_irq(&cep->lock);
+ atomic_inc(&cep->n_pkts);
/* Send it on its way. Tell CPM its ready, interrupt when done,
* its the last BD of the frame, and to put the CRC on the end.
@@ -421,9 +425,12 @@
else
bdp++;
- if (bdp->cbd_sc & BD_ENET_TX_READY) {
- netif_stop_queue(dev);
+ /* If the tx_ring is full, stop the queue */
+ if (atomic_read(&cep->n_pkts) >= (TX_RING_SIZE-1)) {
+ if (!netif_queue_stopped(dev)) {
+ netif_stop_queue(dev);
cep->tx_full = 1;
+ }
}
cep->cur_tx = (cbd_t *)bdp;
@@ -542,6 +549,8 @@
dev_kfree_skb_irq(cep->tx_skbuff[cep->skb_dirty]);
cep->skb_dirty = (cep->skb_dirty + 1) & TX_RING_MOD_MASK;
+ atomic_dec(&cep->n_pkts);
+
/* Update pointer to next buffer descriptor to be transmitted. */
if (bdp->cbd_sc & BD_ENET_TX_WRAP)
bdp = cep->tx_bd_base;
@@ -1782,6 +1791,7 @@
while (cp->cp_cpcr & CPM_CR_FLG);
cep->skb_cur = cep->skb_dirty = 0;
+ atomic_set(&cep->n_pkts, 0);
}
/* Let 'er rip.
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)