diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/spider_net.c | 43 | ||||
-rw-r--r-- | drivers/net/spider_net.h | 8 |
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 | ||
721 | static void | ||
722 | spider_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 | ||
360 | struct spider_net_descr { | 359 | struct 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 | ||