aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/spider_net.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/spider_net.c')
-rw-r--r--drivers/net/spider_net.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index d779a0b9d456..96b5d00c21da 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -684,6 +684,7 @@ spider_net_prepare_tx_descr(struct spider_net_card *card,
684 break; 684 break;
685 } 685 }
686 686
687 /* Chain the bus address, so that the DMA engine finds this descr. */
687 descr->prev->next_descr_addr = descr->bus_addr; 688 descr->prev->next_descr_addr = descr->bus_addr;
688 689
689 card->netdev->trans_start = jiffies; /* set netdev watchdog timer */ 690 card->netdev->trans_start = jiffies; /* set netdev watchdog timer */
@@ -717,6 +718,41 @@ spider_net_release_tx_descr(struct spider_net_card *card)
717 dev_kfree_skb_any(skb); 718 dev_kfree_skb_any(skb);
718} 719}
719 720
721static void
722spider_net_set_low_watermark(struct spider_net_card *card)
723{
724 int status;
725 int cnt=0;
726 int i;
727 struct spider_net_descr *descr = card->tx_chain.tail;
728
729 /* Measure the length of the queue. */
730 while (descr != card->tx_chain.head) {
731 status = descr->dmac_cmd_status & SPIDER_NET_DESCR_NOT_IN_USE;
732 if (status == SPIDER_NET_DESCR_NOT_IN_USE)
733 break;
734 descr = descr->next;
735 cnt++;
736 }
737
738 /* If TX queue is short, don't even bother with interrupts */
739 if (cnt < card->tx_desc/4)
740 return;
741
742 /* Set low-watermark 3/4th's of the way into the queue. */
743 descr = card->tx_chain.tail;
744 cnt = (cnt*3)/4;
745 for (i=0;i<cnt; i++)
746 descr = descr->next;
747
748 /* Set the new watermark, clear the old watermark */
749 descr->dmac_cmd_status |= SPIDER_NET_DESCR_TXDESFLG;
750 if (card->low_watermark && card->low_watermark != descr)
751 card->low_watermark->dmac_cmd_status =
752 card->low_watermark->dmac_cmd_status & ~SPIDER_NET_DESCR_TXDESFLG;
753 card->low_watermark = descr;
754}
755
720/** 756/**
721 * spider_net_release_tx_chain - processes sent tx descriptors 757 * spider_net_release_tx_chain - processes sent tx descriptors
722 * @card: adapter structure 758 * @card: adapter structure
@@ -838,6 +874,7 @@ spider_net_xmit(struct sk_buff *skb, struct net_device *netdev)
838 return NETDEV_TX_BUSY; 874 return NETDEV_TX_BUSY;
839 } 875 }
840 876
877 spider_net_set_low_watermark(card);
841 spider_net_kick_tx_dma(card); 878 spider_net_kick_tx_dma(card);
842 card->tx_chain.head = card->tx_chain.head->next; 879 card->tx_chain.head = card->tx_chain.head->next;
843 spin_unlock_irqrestore(&chain->lock, flags); 880 spin_unlock_irqrestore(&chain->lock, flags);
@@ -1467,6 +1504,10 @@ spider_net_interrupt(int irq, void *ptr)
1467 spider_net_rx_irq_off(card); 1504 spider_net_rx_irq_off(card);
1468 netif_rx_schedule(netdev); 1505 netif_rx_schedule(netdev);
1469 } 1506 }
1507 if (status_reg & SPIDER_NET_TXINT ) {
1508 spider_net_cleanup_tx_ring(card);
1509 netif_wake_queue(netdev);
1510 }
1470 1511
1471 if (status_reg & SPIDER_NET_ERRINT ) 1512 if (status_reg & SPIDER_NET_ERRINT )
1472 spider_net_handle_error_irq(card, status_reg); 1513 spider_net_handle_error_irq(card, status_reg);
@@ -1629,6 +1670,8 @@ spider_net_open(struct net_device *netdev)
1629 PCI_DMA_TODEVICE, card->tx_desc)) 1670 PCI_DMA_TODEVICE, card->tx_desc))
1630 goto alloc_tx_failed; 1671 goto alloc_tx_failed;
1631 1672
1673 card->low_watermark = NULL;
1674
1632 /* rx_chain is after tx_chain, so offset is descr + tx_count */ 1675 /* rx_chain is after tx_chain, so offset is descr + tx_count */
1633 if (spider_net_init_chain(card, &card->rx_chain, 1676 if (spider_net_init_chain(card, &card->rx_chain,
1634 card->descr + card->tx_desc, 1677 card->descr + card->tx_desc,