-
- jme_process_receive(jme);
- if(jme->flags & JME_FLAG_RXQ0_EMPTY) {
- jme_restart_rx_engine(jme);
- jme->flags &= ~JME_FLAG_RXQ0_EMPTY;
+ struct jme_ring *txring = &(jme->txring[0]);
+ volatile struct txdesc *txdesc = txring->desc;
+ struct jme_buffer_info *txbi = txring->bufinf, *ctxbi, *ttxbi;
+ int i, j, cnt = 0, max;
+
+ spin_lock(&jme->tx_lock);
+ max = RING_DESC_NR - txring->nr_free;
+ spin_unlock(&jme->tx_lock);
+
+ tx_dbg(jme->dev->name, "Tx Tasklet: In\n");
+
+ for(i = txring->next_to_clean ; cnt < max ; ) {
+
+ ctxbi = txbi + i;
+
+ if(ctxbi->skb && !(txdesc[i].desc1.flags & TXFLAG_OWN)) {
+
+ tx_dbg(jme->dev->name,
+ "Tx Tasklet: Clean %d+%d\n",
+ i, ctxbi->nr_desc);
+
+ for(j = 1 ; j < ctxbi->nr_desc ; ++j) {
+ ttxbi = txbi + ((i + j) & (RING_DESC_NR - 1));
+ txdesc[(i+j)&(RING_DESC_NR-1)].dw[0] = 0;
+
+ pci_unmap_single(jme->pdev,
+ ttxbi->mapping,
+ ttxbi->len,
+ PCI_DMA_TODEVICE);
+
+ NET_STAT(jme).tx_bytes += ttxbi->len;
+ ttxbi->mapping = 0;
+ ttxbi->len = 0;
+ }
+
+ dev_kfree_skb(ctxbi->skb);
+ ctxbi->skb = NULL;
+
+ cnt += ctxbi->nr_desc;
+
+ ++(NET_STAT(jme).tx_packets);
+ }
+ else {
+ if(!ctxbi->skb)
+ tx_dbg(jme->dev->name,
+ "Tx Tasklet:"
+ " Stoped due to no skb.\n");
+ else
+ tx_dbg(jme->dev->name,
+ "Tx Tasklet:"
+ "Stoped due to not done.\n");
+ break;
+ }
+
+ if(unlikely((i += ctxbi->nr_desc) >= RING_DESC_NR))
+ i -= RING_DESC_NR;
+
+ ctxbi->nr_desc = 0;