aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/spider_net.c43
-rw-r--r--drivers/net/spider_net.h8
2 files changed, 47 insertions, 4 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,
diff --git a/drivers/net/spider_net.h b/drivers/net/spider_net.h
index 6c9d7ce7f731..1f5c9dc806a0 100644
--- a/drivers/net/spider_net.h
+++ b/drivers/net/spider_net.h
@@ -49,7 +49,7 @@ extern char spider_net_driver_name[];
49#define SPIDER_NET_TX_DESCRIPTORS_MIN 16 49#define SPIDER_NET_TX_DESCRIPTORS_MIN 16
50#define SPIDER_NET_TX_DESCRIPTORS_MAX 512 50#define SPIDER_NET_TX_DESCRIPTORS_MAX 512
51 51
52#define SPIDER_NET_TX_TIMER 20 52#define SPIDER_NET_TX_TIMER (HZ/5)
53 53
54#define SPIDER_NET_RX_CSUM_DEFAULT 1 54#define SPIDER_NET_RX_CSUM_DEFAULT 1
55 55
@@ -328,9 +328,7 @@ enum spider_net_int2_status {
328 SPIDER_NET_GRISPDNGINT 328 SPIDER_NET_GRISPDNGINT
329}; 329};
330 330
331#define SPIDER_NET_TXINT ( (1 << SPIDER_NET_GTTEDINT) | \ 331#define SPIDER_NET_TXINT ( (1 << SPIDER_NET_GDTFDCINT) )
332 (1 << SPIDER_NET_GDTDCEINT) | \
333 (1 << SPIDER_NET_GDTFDCINT) )
334 332
335/* We rely on flagged descriptor interrupts */ 333/* We rely on flagged descriptor interrupts */
336#define SPIDER_NET_RXINT ( (1 << SPIDER_NET_GDAFDCINT) ) 334#define SPIDER_NET_RXINT ( (1 << SPIDER_NET_GDAFDCINT) )
@@ -356,6 +354,7 @@ enum spider_net_int2_status {
356#define SPIDER_NET_DESCR_FORCE_END 0x50000000 /* used in rx and tx */ 354#define SPIDER_NET_DESCR_FORCE_END 0x50000000 /* used in rx and tx */
357#define SPIDER_NET_DESCR_CARDOWNED 0xA0000000 /* used in rx and tx */ 355#define SPIDER_NET_DESCR_CARDOWNED 0xA0000000 /* used in rx and tx */
358#define SPIDER_NET_DESCR_NOT_IN_USE 0xF0000000 356#define SPIDER_NET_DESCR_NOT_IN_USE 0xF0000000
357#define SPIDER_NET_DESCR_TXDESFLG 0x00800000
359 358
360struct spider_net_descr { 359struct spider_net_descr {
361 /* as defined by the hardware */ 360 /* as defined by the hardware */
@@ -440,6 +439,7 @@ struct spider_net_card {
440 439
441 struct spider_net_descr_chain tx_chain; 440 struct spider_net_descr_chain tx_chain;
442 struct spider_net_descr_chain rx_chain; 441 struct spider_net_descr_chain rx_chain;
442 struct spider_net_descr *low_watermark;
443 443
444 struct net_device_stats netdev_stats; 444 struct net_device_stats netdev_stats;
445 445