diff options
Diffstat (limited to 'drivers/net/spider_net.c')
| -rw-r--r-- | drivers/net/spider_net.c | 246 |
1 files changed, 148 insertions, 98 deletions
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 46a009085f7c..418138dd6c68 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c | |||
| @@ -55,12 +55,13 @@ MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com> and Jens Osterkamp " \ | |||
| 55 | "<Jens.Osterkamp@de.ibm.com>"); | 55 | "<Jens.Osterkamp@de.ibm.com>"); |
| 56 | MODULE_DESCRIPTION("Spider Southbridge Gigabit Ethernet driver"); | 56 | MODULE_DESCRIPTION("Spider Southbridge Gigabit Ethernet driver"); |
| 57 | MODULE_LICENSE("GPL"); | 57 | MODULE_LICENSE("GPL"); |
| 58 | MODULE_VERSION(VERSION); | ||
| 58 | 59 | ||
| 59 | static int rx_descriptors = SPIDER_NET_RX_DESCRIPTORS_DEFAULT; | 60 | static int rx_descriptors = SPIDER_NET_RX_DESCRIPTORS_DEFAULT; |
| 60 | static int tx_descriptors = SPIDER_NET_TX_DESCRIPTORS_DEFAULT; | 61 | static int tx_descriptors = SPIDER_NET_TX_DESCRIPTORS_DEFAULT; |
| 61 | 62 | ||
| 62 | module_param(rx_descriptors, int, 0644); | 63 | module_param(rx_descriptors, int, 0444); |
| 63 | module_param(tx_descriptors, int, 0644); | 64 | module_param(tx_descriptors, int, 0444); |
| 64 | 65 | ||
| 65 | MODULE_PARM_DESC(rx_descriptors, "number of descriptors used " \ | 66 | MODULE_PARM_DESC(rx_descriptors, "number of descriptors used " \ |
| 66 | "in rx chains"); | 67 | "in rx chains"); |
| @@ -300,7 +301,7 @@ static int | |||
| 300 | spider_net_init_chain(struct spider_net_card *card, | 301 | spider_net_init_chain(struct spider_net_card *card, |
| 301 | struct spider_net_descr_chain *chain, | 302 | struct spider_net_descr_chain *chain, |
| 302 | struct spider_net_descr *start_descr, | 303 | struct spider_net_descr *start_descr, |
| 303 | int direction, int no) | 304 | int no) |
| 304 | { | 305 | { |
| 305 | int i; | 306 | int i; |
| 306 | struct spider_net_descr *descr; | 307 | struct spider_net_descr *descr; |
| @@ -315,7 +316,7 @@ spider_net_init_chain(struct spider_net_card *card, | |||
| 315 | 316 | ||
| 316 | buf = pci_map_single(card->pdev, descr, | 317 | buf = pci_map_single(card->pdev, descr, |
| 317 | SPIDER_NET_DESCR_SIZE, | 318 | SPIDER_NET_DESCR_SIZE, |
| 318 | direction); | 319 | PCI_DMA_BIDIRECTIONAL); |
| 319 | 320 | ||
| 320 | if (pci_dma_mapping_error(buf)) | 321 | if (pci_dma_mapping_error(buf)) |
| 321 | goto iommu_error; | 322 | goto iommu_error; |
| @@ -329,11 +330,6 @@ spider_net_init_chain(struct spider_net_card *card, | |||
| 329 | (descr-1)->next = start_descr; | 330 | (descr-1)->next = start_descr; |
| 330 | start_descr->prev = descr-1; | 331 | start_descr->prev = descr-1; |
| 331 | 332 | ||
| 332 | descr = start_descr; | ||
| 333 | if (direction == PCI_DMA_FROMDEVICE) | ||
| 334 | for (i=0; i < no; i++, descr++) | ||
| 335 | descr->next_descr_addr = descr->next->bus_addr; | ||
| 336 | |||
| 337 | spin_lock_init(&chain->lock); | 333 | spin_lock_init(&chain->lock); |
| 338 | chain->head = start_descr; | 334 | chain->head = start_descr; |
| 339 | chain->tail = start_descr; | 335 | chain->tail = start_descr; |
| @@ -346,7 +342,7 @@ iommu_error: | |||
| 346 | if (descr->bus_addr) | 342 | if (descr->bus_addr) |
| 347 | pci_unmap_single(card->pdev, descr->bus_addr, | 343 | pci_unmap_single(card->pdev, descr->bus_addr, |
| 348 | SPIDER_NET_DESCR_SIZE, | 344 | SPIDER_NET_DESCR_SIZE, |
| 349 | direction); | 345 | PCI_DMA_BIDIRECTIONAL); |
| 350 | return -ENOMEM; | 346 | return -ENOMEM; |
| 351 | } | 347 | } |
| 352 | 348 | ||
| @@ -362,15 +358,15 @@ spider_net_free_rx_chain_contents(struct spider_net_card *card) | |||
| 362 | struct spider_net_descr *descr; | 358 | struct spider_net_descr *descr; |
| 363 | 359 | ||
| 364 | descr = card->rx_chain.head; | 360 | descr = card->rx_chain.head; |
| 365 | while (descr->next != card->rx_chain.head) { | 361 | do { |
| 366 | if (descr->skb) { | 362 | if (descr->skb) { |
| 367 | dev_kfree_skb(descr->skb); | 363 | dev_kfree_skb(descr->skb); |
| 368 | pci_unmap_single(card->pdev, descr->buf_addr, | 364 | pci_unmap_single(card->pdev, descr->buf_addr, |
| 369 | SPIDER_NET_MAX_FRAME, | 365 | SPIDER_NET_MAX_FRAME, |
| 370 | PCI_DMA_FROMDEVICE); | 366 | PCI_DMA_BIDIRECTIONAL); |
| 371 | } | 367 | } |
| 372 | descr = descr->next; | 368 | descr = descr->next; |
| 373 | } | 369 | } while (descr != card->rx_chain.head); |
| 374 | } | 370 | } |
| 375 | 371 | ||
| 376 | /** | 372 | /** |
| @@ -645,26 +641,41 @@ static int | |||
| 645 | spider_net_prepare_tx_descr(struct spider_net_card *card, | 641 | spider_net_prepare_tx_descr(struct spider_net_card *card, |
| 646 | struct sk_buff *skb) | 642 | struct sk_buff *skb) |
| 647 | { | 643 | { |
| 648 | struct spider_net_descr *descr = card->tx_chain.head; | 644 | struct spider_net_descr *descr; |
| 649 | dma_addr_t buf; | 645 | dma_addr_t buf; |
| 646 | unsigned long flags; | ||
| 647 | int length; | ||
| 650 | 648 | ||
| 651 | buf = pci_map_single(card->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); | 649 | length = skb->len; |
| 650 | if (length < ETH_ZLEN) { | ||
| 651 | if (skb_pad(skb, ETH_ZLEN-length)) | ||
| 652 | return 0; | ||
| 653 | length = ETH_ZLEN; | ||
| 654 | } | ||
| 655 | |||
| 656 | buf = pci_map_single(card->pdev, skb->data, length, PCI_DMA_TODEVICE); | ||
| 652 | if (pci_dma_mapping_error(buf)) { | 657 | if (pci_dma_mapping_error(buf)) { |
| 653 | if (netif_msg_tx_err(card) && net_ratelimit()) | 658 | if (netif_msg_tx_err(card) && net_ratelimit()) |
| 654 | pr_err("could not iommu-map packet (%p, %i). " | 659 | pr_err("could not iommu-map packet (%p, %i). " |
| 655 | "Dropping packet\n", skb->data, skb->len); | 660 | "Dropping packet\n", skb->data, length); |
| 656 | card->spider_stats.tx_iommu_map_error++; | 661 | card->spider_stats.tx_iommu_map_error++; |
| 657 | return -ENOMEM; | 662 | return -ENOMEM; |
| 658 | } | 663 | } |
| 659 | 664 | ||
| 665 | spin_lock_irqsave(&card->tx_chain.lock, flags); | ||
| 666 | descr = card->tx_chain.head; | ||
| 667 | card->tx_chain.head = descr->next; | ||
| 668 | |||
| 660 | descr->buf_addr = buf; | 669 | descr->buf_addr = buf; |
| 661 | descr->buf_size = skb->len; | 670 | descr->buf_size = length; |
| 662 | descr->next_descr_addr = 0; | 671 | descr->next_descr_addr = 0; |
| 663 | descr->skb = skb; | 672 | descr->skb = skb; |
| 664 | descr->data_status = 0; | 673 | descr->data_status = 0; |
| 665 | 674 | ||
| 666 | descr->dmac_cmd_status = | 675 | descr->dmac_cmd_status = |
| 667 | SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_NOCS; | 676 | SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_NOCS; |
| 677 | spin_unlock_irqrestore(&card->tx_chain.lock, flags); | ||
| 678 | |||
| 668 | if (skb->protocol == htons(ETH_P_IP)) | 679 | if (skb->protocol == htons(ETH_P_IP)) |
| 669 | switch (skb->nh.iph->protocol) { | 680 | switch (skb->nh.iph->protocol) { |
| 670 | case IPPROTO_TCP: | 681 | case IPPROTO_TCP: |
| @@ -675,32 +686,51 @@ spider_net_prepare_tx_descr(struct spider_net_card *card, | |||
| 675 | break; | 686 | break; |
| 676 | } | 687 | } |
| 677 | 688 | ||
| 689 | /* Chain the bus address, so that the DMA engine finds this descr. */ | ||
| 678 | descr->prev->next_descr_addr = descr->bus_addr; | 690 | descr->prev->next_descr_addr = descr->bus_addr; |
| 679 | 691 | ||
| 692 | card->netdev->trans_start = jiffies; /* set netdev watchdog timer */ | ||
| 680 | return 0; | 693 | return 0; |
| 681 | } | 694 | } |
| 682 | 695 | ||
| 683 | /** | 696 | static int |
| 684 | * spider_net_release_tx_descr - processes a used tx descriptor | 697 | spider_net_set_low_watermark(struct spider_net_card *card) |
| 685 | * @card: card structure | ||
| 686 | * @descr: descriptor to release | ||
| 687 | * | ||
| 688 | * releases a used tx descriptor (unmapping, freeing of skb) | ||
| 689 | */ | ||
| 690 | static inline void | ||
| 691 | spider_net_release_tx_descr(struct spider_net_card *card) | ||
| 692 | { | 698 | { |
| 699 | unsigned long flags; | ||
| 700 | int status; | ||
| 701 | int cnt=0; | ||
| 702 | int i; | ||
| 693 | struct spider_net_descr *descr = card->tx_chain.tail; | 703 | struct spider_net_descr *descr = card->tx_chain.tail; |
| 694 | struct sk_buff *skb; | ||
| 695 | 704 | ||
| 696 | card->tx_chain.tail = card->tx_chain.tail->next; | 705 | /* Measure the length of the queue. Measurement does not |
| 697 | descr->dmac_cmd_status |= SPIDER_NET_DESCR_NOT_IN_USE; | 706 | * need to be precise -- does not need a lock. */ |
| 707 | while (descr != card->tx_chain.head) { | ||
| 708 | status = descr->dmac_cmd_status & SPIDER_NET_DESCR_NOT_IN_USE; | ||
| 709 | if (status == SPIDER_NET_DESCR_NOT_IN_USE) | ||
| 710 | break; | ||
| 711 | descr = descr->next; | ||
| 712 | cnt++; | ||
| 713 | } | ||
| 698 | 714 | ||
| 699 | /* unmap the skb */ | 715 | /* If TX queue is short, don't even bother with interrupts */ |
| 700 | skb = descr->skb; | 716 | if (cnt < card->num_tx_desc/4) |
| 701 | pci_unmap_single(card->pdev, descr->buf_addr, skb->len, | 717 | return cnt; |
| 702 | PCI_DMA_TODEVICE); | 718 | |
| 703 | dev_kfree_skb_any(skb); | 719 | /* Set low-watermark 3/4th's of the way into the queue. */ |
| 720 | descr = card->tx_chain.tail; | ||
| 721 | cnt = (cnt*3)/4; | ||
| 722 | for (i=0;i<cnt; i++) | ||
| 723 | descr = descr->next; | ||
| 724 | |||
| 725 | /* Set the new watermark, clear the old watermark */ | ||
| 726 | spin_lock_irqsave(&card->tx_chain.lock, flags); | ||
| 727 | descr->dmac_cmd_status |= SPIDER_NET_DESCR_TXDESFLG; | ||
| 728 | if (card->low_watermark && card->low_watermark != descr) | ||
| 729 | card->low_watermark->dmac_cmd_status = | ||
| 730 | card->low_watermark->dmac_cmd_status & ~SPIDER_NET_DESCR_TXDESFLG; | ||
| 731 | card->low_watermark = descr; | ||
| 732 | spin_unlock_irqrestore(&card->tx_chain.lock, flags); | ||
| 733 | return cnt; | ||
| 704 | } | 734 | } |
| 705 | 735 | ||
| 706 | /** | 736 | /** |
| @@ -719,21 +749,29 @@ static int | |||
| 719 | spider_net_release_tx_chain(struct spider_net_card *card, int brutal) | 749 | spider_net_release_tx_chain(struct spider_net_card *card, int brutal) |
| 720 | { | 750 | { |
| 721 | struct spider_net_descr_chain *chain = &card->tx_chain; | 751 | struct spider_net_descr_chain *chain = &card->tx_chain; |
| 752 | struct spider_net_descr *descr; | ||
| 753 | struct sk_buff *skb; | ||
| 754 | u32 buf_addr; | ||
| 755 | unsigned long flags; | ||
| 722 | int status; | 756 | int status; |
| 723 | 757 | ||
| 724 | spider_net_read_reg(card, SPIDER_NET_GDTDMACCNTR); | ||
| 725 | |||
| 726 | while (chain->tail != chain->head) { | 758 | while (chain->tail != chain->head) { |
| 727 | status = spider_net_get_descr_status(chain->tail); | 759 | spin_lock_irqsave(&chain->lock, flags); |
| 760 | descr = chain->tail; | ||
| 761 | |||
| 762 | status = spider_net_get_descr_status(descr); | ||
| 728 | switch (status) { | 763 | switch (status) { |
| 729 | case SPIDER_NET_DESCR_COMPLETE: | 764 | case SPIDER_NET_DESCR_COMPLETE: |
| 730 | card->netdev_stats.tx_packets++; | 765 | card->netdev_stats.tx_packets++; |
| 731 | card->netdev_stats.tx_bytes += chain->tail->skb->len; | 766 | card->netdev_stats.tx_bytes += descr->skb->len; |
| 732 | break; | 767 | break; |
| 733 | 768 | ||
| 734 | case SPIDER_NET_DESCR_CARDOWNED: | 769 | case SPIDER_NET_DESCR_CARDOWNED: |
| 735 | if (!brutal) | 770 | if (!brutal) { |
| 771 | spin_unlock_irqrestore(&chain->lock, flags); | ||
| 736 | return 1; | 772 | return 1; |
| 773 | } | ||
| 774 | |||
| 737 | /* fallthrough, if we release the descriptors | 775 | /* fallthrough, if we release the descriptors |
| 738 | * brutally (then we don't care about | 776 | * brutally (then we don't care about |
| 739 | * SPIDER_NET_DESCR_CARDOWNED) */ | 777 | * SPIDER_NET_DESCR_CARDOWNED) */ |
| @@ -750,11 +788,25 @@ spider_net_release_tx_chain(struct spider_net_card *card, int brutal) | |||
| 750 | 788 | ||
| 751 | default: | 789 | default: |
| 752 | card->netdev_stats.tx_dropped++; | 790 | card->netdev_stats.tx_dropped++; |
| 753 | return 1; | 791 | if (!brutal) { |
| 792 | spin_unlock_irqrestore(&chain->lock, flags); | ||
| 793 | return 1; | ||
| 794 | } | ||
| 754 | } | 795 | } |
| 755 | spider_net_release_tx_descr(card); | ||
| 756 | } | ||
| 757 | 796 | ||
| 797 | chain->tail = descr->next; | ||
| 798 | descr->dmac_cmd_status |= SPIDER_NET_DESCR_NOT_IN_USE; | ||
| 799 | skb = descr->skb; | ||
| 800 | buf_addr = descr->buf_addr; | ||
| 801 | spin_unlock_irqrestore(&chain->lock, flags); | ||
| 802 | |||
| 803 | /* unmap the skb */ | ||
| 804 | if (skb) { | ||
| 805 | int len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len; | ||
| 806 | pci_unmap_single(card->pdev, buf_addr, len, PCI_DMA_TODEVICE); | ||
| 807 | dev_kfree_skb(skb); | ||
| 808 | } | ||
| 809 | } | ||
| 758 | return 0; | 810 | return 0; |
| 759 | } | 811 | } |
| 760 | 812 | ||
| @@ -763,8 +815,12 @@ spider_net_release_tx_chain(struct spider_net_card *card, int brutal) | |||
| 763 | * @card: card structure | 815 | * @card: card structure |
| 764 | * @descr: descriptor address to enable TX processing at | 816 | * @descr: descriptor address to enable TX processing at |
| 765 | * | 817 | * |
| 766 | * spider_net_kick_tx_dma writes the current tx chain head as start address | 818 | * This routine will start the transmit DMA running if |
| 767 | * of the tx descriptor chain and enables the transmission DMA engine | 819 | * it is not already running. This routine ned only be |
| 820 | * called when queueing a new packet to an empty tx queue. | ||
| 821 | * Writes the current tx chain head as start address | ||
| 822 | * of the tx descriptor chain and enables the transmission | ||
| 823 | * DMA engine. | ||
| 768 | */ | 824 | */ |
| 769 | static inline void | 825 | static inline void |
| 770 | spider_net_kick_tx_dma(struct spider_net_card *card) | 826 | spider_net_kick_tx_dma(struct spider_net_card *card) |
| @@ -804,65 +860,43 @@ out: | |||
| 804 | static int | 860 | static int |
| 805 | spider_net_xmit(struct sk_buff *skb, struct net_device *netdev) | 861 | spider_net_xmit(struct sk_buff *skb, struct net_device *netdev) |
| 806 | { | 862 | { |
| 863 | int cnt; | ||
| 807 | struct spider_net_card *card = netdev_priv(netdev); | 864 | struct spider_net_card *card = netdev_priv(netdev); |
| 808 | struct spider_net_descr_chain *chain = &card->tx_chain; | 865 | struct spider_net_descr_chain *chain = &card->tx_chain; |
| 809 | struct spider_net_descr *descr = chain->head; | ||
| 810 | unsigned long flags; | ||
| 811 | int result; | ||
| 812 | |||
| 813 | spin_lock_irqsave(&chain->lock, flags); | ||
| 814 | 866 | ||
| 815 | spider_net_release_tx_chain(card, 0); | 867 | spider_net_release_tx_chain(card, 0); |
| 816 | 868 | ||
| 817 | if (chain->head->next == chain->tail->prev) { | 869 | if ((chain->head->next == chain->tail->prev) || |
| 818 | card->netdev_stats.tx_dropped++; | 870 | (spider_net_prepare_tx_descr(card, skb) != 0)) { |
| 819 | result = NETDEV_TX_LOCKED; | ||
| 820 | goto out; | ||
| 821 | } | ||
| 822 | 871 | ||
| 823 | if (spider_net_get_descr_status(descr) != SPIDER_NET_DESCR_NOT_IN_USE) { | ||
| 824 | card->netdev_stats.tx_dropped++; | 872 | card->netdev_stats.tx_dropped++; |
| 825 | result = NETDEV_TX_LOCKED; | 873 | netif_stop_queue(netdev); |
| 826 | goto out; | 874 | return NETDEV_TX_BUSY; |
| 827 | } | 875 | } |
| 828 | 876 | ||
| 829 | if (spider_net_prepare_tx_descr(card, skb) != 0) { | 877 | cnt = spider_net_set_low_watermark(card); |
| 830 | card->netdev_stats.tx_dropped++; | 878 | if (cnt < 5) |
| 831 | result = NETDEV_TX_BUSY; | 879 | spider_net_kick_tx_dma(card); |
| 832 | goto out; | 880 | return NETDEV_TX_OK; |
| 833 | } | ||
| 834 | |||
| 835 | result = NETDEV_TX_OK; | ||
| 836 | |||
| 837 | spider_net_kick_tx_dma(card); | ||
| 838 | card->tx_chain.head = card->tx_chain.head->next; | ||
| 839 | |||
| 840 | out: | ||
| 841 | spin_unlock_irqrestore(&chain->lock, flags); | ||
| 842 | netif_wake_queue(netdev); | ||
| 843 | return result; | ||
| 844 | } | 881 | } |
| 845 | 882 | ||
| 846 | /** | 883 | /** |
| 847 | * spider_net_cleanup_tx_ring - cleans up the TX ring | 884 | * spider_net_cleanup_tx_ring - cleans up the TX ring |
| 848 | * @card: card structure | 885 | * @card: card structure |
| 849 | * | 886 | * |
| 850 | * spider_net_cleanup_tx_ring is called by the tx_timer (as we don't use | 887 | * spider_net_cleanup_tx_ring is called by either the tx_timer |
| 851 | * interrupts to cleanup our TX ring) and returns sent packets to the stack | 888 | * or from the NAPI polling routine. |
| 852 | * by freeing them | 889 | * This routine releases resources associted with transmitted |
| 890 | * packets, including updating the queue tail pointer. | ||
| 853 | */ | 891 | */ |
| 854 | static void | 892 | static void |
| 855 | spider_net_cleanup_tx_ring(struct spider_net_card *card) | 893 | spider_net_cleanup_tx_ring(struct spider_net_card *card) |
| 856 | { | 894 | { |
| 857 | unsigned long flags; | ||
| 858 | |||
| 859 | spin_lock_irqsave(&card->tx_chain.lock, flags); | ||
| 860 | |||
| 861 | if ((spider_net_release_tx_chain(card, 0) != 0) && | 895 | if ((spider_net_release_tx_chain(card, 0) != 0) && |
| 862 | (card->netdev->flags & IFF_UP)) | 896 | (card->netdev->flags & IFF_UP)) { |
| 863 | spider_net_kick_tx_dma(card); | 897 | spider_net_kick_tx_dma(card); |
| 864 | 898 | netif_wake_queue(card->netdev); | |
| 865 | spin_unlock_irqrestore(&card->tx_chain.lock, flags); | 899 | } |
| 866 | } | 900 | } |
| 867 | 901 | ||
| 868 | /** | 902 | /** |
| @@ -1053,6 +1087,7 @@ spider_net_poll(struct net_device *netdev, int *budget) | |||
| 1053 | int packets_to_do, packets_done = 0; | 1087 | int packets_to_do, packets_done = 0; |
| 1054 | int no_more_packets = 0; | 1088 | int no_more_packets = 0; |
| 1055 | 1089 | ||
| 1090 | spider_net_cleanup_tx_ring(card); | ||
| 1056 | packets_to_do = min(*budget, netdev->quota); | 1091 | packets_to_do = min(*budget, netdev->quota); |
| 1057 | 1092 | ||
| 1058 | while (packets_to_do) { | 1093 | while (packets_to_do) { |
| @@ -1243,12 +1278,15 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) | |||
| 1243 | case SPIDER_NET_PHYINT: | 1278 | case SPIDER_NET_PHYINT: |
| 1244 | case SPIDER_NET_GMAC2INT: | 1279 | case SPIDER_NET_GMAC2INT: |
| 1245 | case SPIDER_NET_GMAC1INT: | 1280 | case SPIDER_NET_GMAC1INT: |
| 1246 | case SPIDER_NET_GIPSINT: | ||
| 1247 | case SPIDER_NET_GFIFOINT: | 1281 | case SPIDER_NET_GFIFOINT: |
| 1248 | case SPIDER_NET_DMACINT: | 1282 | case SPIDER_NET_DMACINT: |
| 1249 | case SPIDER_NET_GSYSINT: | 1283 | case SPIDER_NET_GSYSINT: |
| 1250 | break; */ | 1284 | break; */ |
| 1251 | 1285 | ||
| 1286 | case SPIDER_NET_GIPSINT: | ||
| 1287 | show_error = 0; | ||
| 1288 | break; | ||
| 1289 | |||
| 1252 | case SPIDER_NET_GPWOPCMPINT: | 1290 | case SPIDER_NET_GPWOPCMPINT: |
| 1253 | /* PHY write operation completed */ | 1291 | /* PHY write operation completed */ |
| 1254 | show_error = 0; | 1292 | show_error = 0; |
| @@ -1307,9 +1345,10 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) | |||
| 1307 | case SPIDER_NET_GDTDCEINT: | 1345 | case SPIDER_NET_GDTDCEINT: |
| 1308 | /* chain end. If a descriptor should be sent, kick off | 1346 | /* chain end. If a descriptor should be sent, kick off |
| 1309 | * tx dma | 1347 | * tx dma |
| 1310 | if (card->tx_chain.tail == card->tx_chain.head) | 1348 | if (card->tx_chain.tail != card->tx_chain.head) |
| 1311 | spider_net_kick_tx_dma(card); | 1349 | spider_net_kick_tx_dma(card); |
| 1312 | show_error = 0; */ | 1350 | */ |
| 1351 | show_error = 0; | ||
| 1313 | break; | 1352 | break; |
| 1314 | 1353 | ||
| 1315 | /* case SPIDER_NET_G1TMCNTINT: not used. print a message */ | 1354 | /* case SPIDER_NET_G1TMCNTINT: not used. print a message */ |
| @@ -1354,7 +1393,7 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) | |||
| 1354 | if (netif_msg_intr(card)) | 1393 | if (netif_msg_intr(card)) |
| 1355 | pr_err("got descriptor chain end interrupt, " | 1394 | pr_err("got descriptor chain end interrupt, " |
| 1356 | "restarting DMAC %c.\n", | 1395 | "restarting DMAC %c.\n", |
| 1357 | 'D'+i-SPIDER_NET_GDDDCEINT); | 1396 | 'D'-(i-SPIDER_NET_GDDDCEINT)/3); |
| 1358 | spider_net_refill_rx_chain(card); | 1397 | spider_net_refill_rx_chain(card); |
| 1359 | spider_net_enable_rxdmac(card); | 1398 | spider_net_enable_rxdmac(card); |
| 1360 | show_error = 0; | 1399 | show_error = 0; |
| @@ -1423,8 +1462,9 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) | |||
| 1423 | } | 1462 | } |
| 1424 | 1463 | ||
| 1425 | if ((show_error) && (netif_msg_intr(card))) | 1464 | if ((show_error) && (netif_msg_intr(card))) |
| 1426 | pr_err("Got error interrupt, GHIINT0STS = 0x%08x, " | 1465 | pr_err("Got error interrupt on %s, GHIINT0STS = 0x%08x, " |
| 1427 | "GHIINT1STS = 0x%08x, GHIINT2STS = 0x%08x\n", | 1466 | "GHIINT1STS = 0x%08x, GHIINT2STS = 0x%08x\n", |
| 1467 | card->netdev->name, | ||
| 1428 | status_reg, error_reg1, error_reg2); | 1468 | status_reg, error_reg1, error_reg2); |
| 1429 | 1469 | ||
| 1430 | /* clear interrupt sources */ | 1470 | /* clear interrupt sources */ |
| @@ -1460,6 +1500,8 @@ spider_net_interrupt(int irq, void *ptr) | |||
| 1460 | spider_net_rx_irq_off(card); | 1500 | spider_net_rx_irq_off(card); |
| 1461 | netif_rx_schedule(netdev); | 1501 | netif_rx_schedule(netdev); |
| 1462 | } | 1502 | } |
| 1503 | if (status_reg & SPIDER_NET_TXINT) | ||
| 1504 | netif_rx_schedule(netdev); | ||
| 1463 | 1505 | ||
| 1464 | if (status_reg & SPIDER_NET_ERRINT ) | 1506 | if (status_reg & SPIDER_NET_ERRINT ) |
| 1465 | spider_net_handle_error_irq(card, status_reg); | 1507 | spider_net_handle_error_irq(card, status_reg); |
| @@ -1599,7 +1641,7 @@ spider_net_enable_card(struct spider_net_card *card) | |||
| 1599 | SPIDER_NET_INT2_MASK_VALUE); | 1641 | SPIDER_NET_INT2_MASK_VALUE); |
| 1600 | 1642 | ||
| 1601 | spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, | 1643 | spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, |
| 1602 | SPIDER_NET_GDTDCEIDIS); | 1644 | SPIDER_NET_GDTBSTA | SPIDER_NET_GDTDCEIDIS); |
| 1603 | } | 1645 | } |
| 1604 | 1646 | ||
| 1605 | /** | 1647 | /** |
| @@ -1615,17 +1657,26 @@ int | |||
| 1615 | spider_net_open(struct net_device *netdev) | 1657 | spider_net_open(struct net_device *netdev) |
| 1616 | { | 1658 | { |
| 1617 | struct spider_net_card *card = netdev_priv(netdev); | 1659 | struct spider_net_card *card = netdev_priv(netdev); |
| 1618 | int result; | 1660 | struct spider_net_descr *descr; |
| 1661 | int i, result; | ||
| 1619 | 1662 | ||
| 1620 | result = -ENOMEM; | 1663 | result = -ENOMEM; |
| 1621 | if (spider_net_init_chain(card, &card->tx_chain, card->descr, | 1664 | if (spider_net_init_chain(card, &card->tx_chain, card->descr, |
| 1622 | PCI_DMA_TODEVICE, card->tx_desc)) | 1665 | card->num_tx_desc)) |
| 1623 | goto alloc_tx_failed; | 1666 | goto alloc_tx_failed; |
| 1667 | |||
| 1668 | card->low_watermark = NULL; | ||
| 1669 | |||
| 1670 | /* rx_chain is after tx_chain, so offset is descr + tx_count */ | ||
| 1624 | if (spider_net_init_chain(card, &card->rx_chain, | 1671 | if (spider_net_init_chain(card, &card->rx_chain, |
| 1625 | card->descr + card->rx_desc, | 1672 | card->descr + card->num_tx_desc, |
| 1626 | PCI_DMA_FROMDEVICE, card->rx_desc)) | 1673 | card->num_rx_desc)) |
| 1627 | goto alloc_rx_failed; | 1674 | goto alloc_rx_failed; |
| 1628 | 1675 | ||
| 1676 | descr = card->rx_chain.head; | ||
| 1677 | for (i=0; i < card->num_rx_desc; i++, descr++) | ||
| 1678 | descr->next_descr_addr = descr->next->bus_addr; | ||
| 1679 | |||
| 1629 | /* allocate rx skbs */ | 1680 | /* allocate rx skbs */ |
| 1630 | if (spider_net_alloc_rx_skbs(card)) | 1681 | if (spider_net_alloc_rx_skbs(card)) |
| 1631 | goto alloc_skbs_failed; | 1682 | goto alloc_skbs_failed; |
| @@ -1878,10 +1929,7 @@ spider_net_stop(struct net_device *netdev) | |||
| 1878 | spider_net_disable_rxdmac(card); | 1929 | spider_net_disable_rxdmac(card); |
| 1879 | 1930 | ||
| 1880 | /* release chains */ | 1931 | /* release chains */ |
| 1881 | if (spin_trylock(&card->tx_chain.lock)) { | 1932 | spider_net_release_tx_chain(card, 1); |
| 1882 | spider_net_release_tx_chain(card, 1); | ||
| 1883 | spin_unlock(&card->tx_chain.lock); | ||
| 1884 | } | ||
| 1885 | 1933 | ||
| 1886 | spider_net_free_chain(card, &card->tx_chain); | 1934 | spider_net_free_chain(card, &card->tx_chain); |
| 1887 | spider_net_free_chain(card, &card->rx_chain); | 1935 | spider_net_free_chain(card, &card->rx_chain); |
| @@ -2012,8 +2060,8 @@ spider_net_setup_netdev(struct spider_net_card *card) | |||
| 2012 | 2060 | ||
| 2013 | card->options.rx_csum = SPIDER_NET_RX_CSUM_DEFAULT; | 2061 | card->options.rx_csum = SPIDER_NET_RX_CSUM_DEFAULT; |
| 2014 | 2062 | ||
| 2015 | card->tx_desc = tx_descriptors; | 2063 | card->num_tx_desc = tx_descriptors; |
| 2016 | card->rx_desc = rx_descriptors; | 2064 | card->num_rx_desc = rx_descriptors; |
| 2017 | 2065 | ||
| 2018 | spider_net_setup_netdev_ops(netdev); | 2066 | spider_net_setup_netdev_ops(netdev); |
| 2019 | 2067 | ||
| @@ -2252,6 +2300,8 @@ static struct pci_driver spider_net_driver = { | |||
| 2252 | */ | 2300 | */ |
| 2253 | static int __init spider_net_init(void) | 2301 | static int __init spider_net_init(void) |
| 2254 | { | 2302 | { |
| 2303 | printk(KERN_INFO "Spidernet version %s.\n", VERSION); | ||
| 2304 | |||
| 2255 | if (rx_descriptors < SPIDER_NET_RX_DESCRIPTORS_MIN) { | 2305 | if (rx_descriptors < SPIDER_NET_RX_DESCRIPTORS_MIN) { |
| 2256 | rx_descriptors = SPIDER_NET_RX_DESCRIPTORS_MIN; | 2306 | rx_descriptors = SPIDER_NET_RX_DESCRIPTORS_MIN; |
| 2257 | pr_info("adjusting rx descriptors to %i.\n", rx_descriptors); | 2307 | pr_info("adjusting rx descriptors to %i.\n", rx_descriptors); |
