diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/spider_net.c | 150 | ||||
-rw-r--r-- | drivers/net/spider_net.h | 16 |
2 files changed, 95 insertions, 71 deletions
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index e4a9bdd8d77c..10f9e29c1bbf 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c | |||
@@ -299,9 +299,9 @@ spider_net_get_mac_address(struct net_device *netdev) | |||
299 | * returns the status as in the dmac_cmd_status field of the descriptor | 299 | * returns the status as in the dmac_cmd_status field of the descriptor |
300 | */ | 300 | */ |
301 | static inline int | 301 | static inline int |
302 | spider_net_get_descr_status(struct spider_net_descr *descr) | 302 | spider_net_get_descr_status(struct spider_net_hw_descr *hwdescr) |
303 | { | 303 | { |
304 | return descr->dmac_cmd_status & SPIDER_NET_DESCR_IND_PROC_MASK; | 304 | return hwdescr->dmac_cmd_status & SPIDER_NET_DESCR_IND_PROC_MASK; |
305 | } | 305 | } |
306 | 306 | ||
307 | /** | 307 | /** |
@@ -319,12 +319,12 @@ spider_net_free_chain(struct spider_net_card *card, | |||
319 | descr = chain->ring; | 319 | descr = chain->ring; |
320 | do { | 320 | do { |
321 | descr->bus_addr = 0; | 321 | descr->bus_addr = 0; |
322 | descr->next_descr_addr = 0; | 322 | descr->hwdescr->next_descr_addr = 0; |
323 | descr = descr->next; | 323 | descr = descr->next; |
324 | } while (descr != chain->ring); | 324 | } while (descr != chain->ring); |
325 | 325 | ||
326 | dma_free_coherent(&card->pdev->dev, chain->num_desc, | 326 | dma_free_coherent(&card->pdev->dev, chain->num_desc, |
327 | chain->ring, chain->dma_addr); | 327 | chain->hwring, chain->dma_addr); |
328 | } | 328 | } |
329 | 329 | ||
330 | /** | 330 | /** |
@@ -343,31 +343,34 @@ spider_net_init_chain(struct spider_net_card *card, | |||
343 | { | 343 | { |
344 | int i; | 344 | int i; |
345 | struct spider_net_descr *descr; | 345 | struct spider_net_descr *descr; |
346 | struct spider_net_hw_descr *hwdescr; | ||
346 | dma_addr_t buf; | 347 | dma_addr_t buf; |
347 | size_t alloc_size; | 348 | size_t alloc_size; |
348 | 349 | ||
349 | alloc_size = chain->num_desc * sizeof (struct spider_net_descr); | 350 | alloc_size = chain->num_desc * sizeof(struct spider_net_hw_descr); |
350 | 351 | ||
351 | chain->ring = dma_alloc_coherent(&card->pdev->dev, alloc_size, | 352 | chain->hwring = dma_alloc_coherent(&card->pdev->dev, alloc_size, |
352 | &chain->dma_addr, GFP_KERNEL); | 353 | &chain->dma_addr, GFP_KERNEL); |
353 | 354 | ||
354 | if (!chain->ring) | 355 | if (!chain->hwring) |
355 | return -ENOMEM; | 356 | return -ENOMEM; |
356 | 357 | ||
357 | descr = chain->ring; | 358 | memset(chain->ring, 0, chain->num_desc * sizeof(struct spider_net_descr)); |
358 | memset(descr, 0, alloc_size); | ||
359 | 359 | ||
360 | /* Set up the hardware pointers in each descriptor */ | 360 | /* Set up the hardware pointers in each descriptor */ |
361 | descr = chain->ring; | ||
362 | hwdescr = chain->hwring; | ||
361 | buf = chain->dma_addr; | 363 | buf = chain->dma_addr; |
362 | for (i=0; i < chain->num_desc; i++, descr++) { | 364 | for (i=0; i < chain->num_desc; i++, descr++, hwdescr++) { |
363 | descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; | 365 | hwdescr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; |
366 | hwdescr->next_descr_addr = 0; | ||
364 | 367 | ||
368 | descr->hwdescr = hwdescr; | ||
365 | descr->bus_addr = buf; | 369 | descr->bus_addr = buf; |
366 | descr->next_descr_addr = 0; | ||
367 | descr->next = descr + 1; | 370 | descr->next = descr + 1; |
368 | descr->prev = descr - 1; | 371 | descr->prev = descr - 1; |
369 | 372 | ||
370 | buf += sizeof(struct spider_net_descr); | 373 | buf += sizeof(struct spider_net_hw_descr); |
371 | } | 374 | } |
372 | /* do actual circular list */ | 375 | /* do actual circular list */ |
373 | (descr-1)->next = chain->ring; | 376 | (descr-1)->next = chain->ring; |
@@ -394,7 +397,7 @@ spider_net_free_rx_chain_contents(struct spider_net_card *card) | |||
394 | do { | 397 | do { |
395 | if (descr->skb) { | 398 | if (descr->skb) { |
396 | dev_kfree_skb(descr->skb); | 399 | dev_kfree_skb(descr->skb); |
397 | pci_unmap_single(card->pdev, descr->buf_addr, | 400 | pci_unmap_single(card->pdev, descr->hwdescr->buf_addr, |
398 | SPIDER_NET_MAX_FRAME, | 401 | SPIDER_NET_MAX_FRAME, |
399 | PCI_DMA_BIDIRECTIONAL); | 402 | PCI_DMA_BIDIRECTIONAL); |
400 | } | 403 | } |
@@ -416,6 +419,7 @@ static int | |||
416 | spider_net_prepare_rx_descr(struct spider_net_card *card, | 419 | spider_net_prepare_rx_descr(struct spider_net_card *card, |
417 | struct spider_net_descr *descr) | 420 | struct spider_net_descr *descr) |
418 | { | 421 | { |
422 | struct spider_net_hw_descr *hwdescr = descr->hwdescr; | ||
419 | dma_addr_t buf; | 423 | dma_addr_t buf; |
420 | int offset; | 424 | int offset; |
421 | int bufsize; | 425 | int bufsize; |
@@ -434,11 +438,11 @@ spider_net_prepare_rx_descr(struct spider_net_card *card, | |||
434 | card->spider_stats.alloc_rx_skb_error++; | 438 | card->spider_stats.alloc_rx_skb_error++; |
435 | return -ENOMEM; | 439 | return -ENOMEM; |
436 | } | 440 | } |
437 | descr->buf_size = bufsize; | 441 | hwdescr->buf_size = bufsize; |
438 | descr->result_size = 0; | 442 | hwdescr->result_size = 0; |
439 | descr->valid_size = 0; | 443 | hwdescr->valid_size = 0; |
440 | descr->data_status = 0; | 444 | hwdescr->data_status = 0; |
441 | descr->data_error = 0; | 445 | hwdescr->data_error = 0; |
442 | 446 | ||
443 | offset = ((unsigned long)descr->skb->data) & | 447 | offset = ((unsigned long)descr->skb->data) & |
444 | (SPIDER_NET_RXBUF_ALIGN - 1); | 448 | (SPIDER_NET_RXBUF_ALIGN - 1); |
@@ -447,21 +451,21 @@ spider_net_prepare_rx_descr(struct spider_net_card *card, | |||
447 | /* iommu-map the skb */ | 451 | /* iommu-map the skb */ |
448 | buf = pci_map_single(card->pdev, descr->skb->data, | 452 | buf = pci_map_single(card->pdev, descr->skb->data, |
449 | SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); | 453 | SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); |
450 | descr->buf_addr = buf; | ||
451 | if (pci_dma_mapping_error(buf)) { | 454 | if (pci_dma_mapping_error(buf)) { |
452 | dev_kfree_skb_any(descr->skb); | 455 | dev_kfree_skb_any(descr->skb); |
453 | if (netif_msg_rx_err(card) && net_ratelimit()) | 456 | if (netif_msg_rx_err(card) && net_ratelimit()) |
454 | pr_err("Could not iommu-map rx buffer\n"); | 457 | pr_err("Could not iommu-map rx buffer\n"); |
455 | card->spider_stats.rx_iommu_map_error++; | 458 | card->spider_stats.rx_iommu_map_error++; |
456 | descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; | 459 | hwdescr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; |
457 | } else { | 460 | } else { |
458 | descr->next_descr_addr = 0; | 461 | hwdescr->buf_addr = buf; |
462 | hwdescr->next_descr_addr = 0; | ||
459 | wmb(); | 463 | wmb(); |
460 | descr->dmac_cmd_status = SPIDER_NET_DESCR_CARDOWNED | | 464 | hwdescr->dmac_cmd_status = SPIDER_NET_DESCR_CARDOWNED | |
461 | SPIDER_NET_DMAC_NOINTR_COMPLETE; | 465 | SPIDER_NET_DMAC_NOINTR_COMPLETE; |
462 | 466 | ||
463 | wmb(); | 467 | wmb(); |
464 | descr->prev->next_descr_addr = descr->bus_addr; | 468 | descr->prev->hwdescr->next_descr_addr = descr->bus_addr; |
465 | } | 469 | } |
466 | 470 | ||
467 | return 0; | 471 | return 0; |
@@ -517,7 +521,7 @@ spider_net_refill_rx_chain(struct spider_net_card *card) | |||
517 | if (!spin_trylock_irqsave(&chain->lock, flags)) | 521 | if (!spin_trylock_irqsave(&chain->lock, flags)) |
518 | return; | 522 | return; |
519 | 523 | ||
520 | while (spider_net_get_descr_status(chain->head) == | 524 | while (spider_net_get_descr_status(chain->head->hwdescr) == |
521 | SPIDER_NET_DESCR_NOT_IN_USE) { | 525 | SPIDER_NET_DESCR_NOT_IN_USE) { |
522 | if (spider_net_prepare_rx_descr(card, chain->head)) | 526 | if (spider_net_prepare_rx_descr(card, chain->head)) |
523 | break; | 527 | break; |
@@ -679,6 +683,7 @@ spider_net_prepare_tx_descr(struct spider_net_card *card, | |||
679 | struct sk_buff *skb) | 683 | struct sk_buff *skb) |
680 | { | 684 | { |
681 | struct spider_net_descr *descr; | 685 | struct spider_net_descr *descr; |
686 | struct spider_net_hw_descr *hwdescr; | ||
682 | dma_addr_t buf; | 687 | dma_addr_t buf; |
683 | unsigned long flags; | 688 | unsigned long flags; |
684 | 689 | ||
@@ -693,30 +698,32 @@ spider_net_prepare_tx_descr(struct spider_net_card *card, | |||
693 | 698 | ||
694 | spin_lock_irqsave(&card->tx_chain.lock, flags); | 699 | spin_lock_irqsave(&card->tx_chain.lock, flags); |
695 | descr = card->tx_chain.head; | 700 | descr = card->tx_chain.head; |
701 | hwdescr = descr->hwdescr; | ||
696 | card->tx_chain.head = descr->next; | 702 | card->tx_chain.head = descr->next; |
697 | 703 | ||
698 | descr->buf_addr = buf; | ||
699 | descr->buf_size = skb->len; | ||
700 | descr->next_descr_addr = 0; | ||
701 | descr->skb = skb; | 704 | descr->skb = skb; |
702 | descr->data_status = 0; | 705 | hwdescr->buf_addr = buf; |
706 | hwdescr->buf_size = skb->len; | ||
707 | hwdescr->next_descr_addr = 0; | ||
708 | hwdescr->data_status = 0; | ||
703 | 709 | ||
704 | descr->dmac_cmd_status = | 710 | hwdescr->dmac_cmd_status = |
705 | SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_NOCS; | 711 | SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_NOCS; |
706 | spin_unlock_irqrestore(&card->tx_chain.lock, flags); | 712 | spin_unlock_irqrestore(&card->tx_chain.lock, flags); |
707 | 713 | ||
708 | if (skb->protocol == htons(ETH_P_IP)) | 714 | if (skb->protocol == htons(ETH_P_IP)) |
709 | switch (skb->nh.iph->protocol) { | 715 | switch (skb->nh.iph->protocol) { |
710 | case IPPROTO_TCP: | 716 | case IPPROTO_TCP: |
711 | descr->dmac_cmd_status |= SPIDER_NET_DMAC_TCP; | 717 | hwdescr->dmac_cmd_status |= SPIDER_NET_DMAC_TCP; |
712 | break; | 718 | break; |
713 | case IPPROTO_UDP: | 719 | case IPPROTO_UDP: |
714 | descr->dmac_cmd_status |= SPIDER_NET_DMAC_UDP; | 720 | hwdescr->dmac_cmd_status |= SPIDER_NET_DMAC_UDP; |
715 | break; | 721 | break; |
716 | } | 722 | } |
717 | 723 | ||
718 | /* Chain the bus address, so that the DMA engine finds this descr. */ | 724 | /* Chain the bus address, so that the DMA engine finds this descr. */ |
719 | descr->prev->next_descr_addr = descr->bus_addr; | 725 | wmb(); |
726 | descr->prev->hwdescr->next_descr_addr = descr->bus_addr; | ||
720 | 727 | ||
721 | card->netdev->trans_start = jiffies; /* set netdev watchdog timer */ | 728 | card->netdev->trans_start = jiffies; /* set netdev watchdog timer */ |
722 | return 0; | 729 | return 0; |
@@ -725,16 +732,17 @@ spider_net_prepare_tx_descr(struct spider_net_card *card, | |||
725 | static int | 732 | static int |
726 | spider_net_set_low_watermark(struct spider_net_card *card) | 733 | spider_net_set_low_watermark(struct spider_net_card *card) |
727 | { | 734 | { |
735 | struct spider_net_descr *descr = card->tx_chain.tail; | ||
736 | struct spider_net_hw_descr *hwdescr; | ||
728 | unsigned long flags; | 737 | unsigned long flags; |
729 | int status; | 738 | int status; |
730 | int cnt=0; | 739 | int cnt=0; |
731 | int i; | 740 | int i; |
732 | struct spider_net_descr *descr = card->tx_chain.tail; | ||
733 | 741 | ||
734 | /* Measure the length of the queue. Measurement does not | 742 | /* Measure the length of the queue. Measurement does not |
735 | * need to be precise -- does not need a lock. */ | 743 | * need to be precise -- does not need a lock. */ |
736 | while (descr != card->tx_chain.head) { | 744 | while (descr != card->tx_chain.head) { |
737 | status = descr->dmac_cmd_status & SPIDER_NET_DESCR_NOT_IN_USE; | 745 | status = descr->hwdescr->dmac_cmd_status & SPIDER_NET_DESCR_NOT_IN_USE; |
738 | if (status == SPIDER_NET_DESCR_NOT_IN_USE) | 746 | if (status == SPIDER_NET_DESCR_NOT_IN_USE) |
739 | break; | 747 | break; |
740 | descr = descr->next; | 748 | descr = descr->next; |
@@ -753,10 +761,12 @@ spider_net_set_low_watermark(struct spider_net_card *card) | |||
753 | 761 | ||
754 | /* Set the new watermark, clear the old watermark */ | 762 | /* Set the new watermark, clear the old watermark */ |
755 | spin_lock_irqsave(&card->tx_chain.lock, flags); | 763 | spin_lock_irqsave(&card->tx_chain.lock, flags); |
756 | descr->dmac_cmd_status |= SPIDER_NET_DESCR_TXDESFLG; | 764 | descr->hwdescr->dmac_cmd_status |= SPIDER_NET_DESCR_TXDESFLG; |
757 | if (card->low_watermark && card->low_watermark != descr) | 765 | if (card->low_watermark && card->low_watermark != descr) { |
758 | card->low_watermark->dmac_cmd_status = | 766 | hwdescr = card->low_watermark->hwdescr; |
759 | card->low_watermark->dmac_cmd_status & ~SPIDER_NET_DESCR_TXDESFLG; | 767 | hwdescr->dmac_cmd_status = |
768 | hwdescr->dmac_cmd_status & ~SPIDER_NET_DESCR_TXDESFLG; | ||
769 | } | ||
760 | card->low_watermark = descr; | 770 | card->low_watermark = descr; |
761 | spin_unlock_irqrestore(&card->tx_chain.lock, flags); | 771 | spin_unlock_irqrestore(&card->tx_chain.lock, flags); |
762 | return cnt; | 772 | return cnt; |
@@ -779,6 +789,7 @@ spider_net_release_tx_chain(struct spider_net_card *card, int brutal) | |||
779 | { | 789 | { |
780 | struct spider_net_descr_chain *chain = &card->tx_chain; | 790 | struct spider_net_descr_chain *chain = &card->tx_chain; |
781 | struct spider_net_descr *descr; | 791 | struct spider_net_descr *descr; |
792 | struct spider_net_hw_descr *hwdescr; | ||
782 | struct sk_buff *skb; | 793 | struct sk_buff *skb; |
783 | u32 buf_addr; | 794 | u32 buf_addr; |
784 | unsigned long flags; | 795 | unsigned long flags; |
@@ -787,8 +798,9 @@ spider_net_release_tx_chain(struct spider_net_card *card, int brutal) | |||
787 | while (chain->tail != chain->head) { | 798 | while (chain->tail != chain->head) { |
788 | spin_lock_irqsave(&chain->lock, flags); | 799 | spin_lock_irqsave(&chain->lock, flags); |
789 | descr = chain->tail; | 800 | descr = chain->tail; |
801 | hwdescr = descr->hwdescr; | ||
790 | 802 | ||
791 | status = spider_net_get_descr_status(descr); | 803 | status = spider_net_get_descr_status(hwdescr); |
792 | switch (status) { | 804 | switch (status) { |
793 | case SPIDER_NET_DESCR_COMPLETE: | 805 | case SPIDER_NET_DESCR_COMPLETE: |
794 | card->netdev_stats.tx_packets++; | 806 | card->netdev_stats.tx_packets++; |
@@ -824,9 +836,9 @@ spider_net_release_tx_chain(struct spider_net_card *card, int brutal) | |||
824 | } | 836 | } |
825 | 837 | ||
826 | chain->tail = descr->next; | 838 | chain->tail = descr->next; |
827 | descr->dmac_cmd_status |= SPIDER_NET_DESCR_NOT_IN_USE; | 839 | hwdescr->dmac_cmd_status |= SPIDER_NET_DESCR_NOT_IN_USE; |
828 | skb = descr->skb; | 840 | skb = descr->skb; |
829 | buf_addr = descr->buf_addr; | 841 | buf_addr = hwdescr->buf_addr; |
830 | spin_unlock_irqrestore(&chain->lock, flags); | 842 | spin_unlock_irqrestore(&chain->lock, flags); |
831 | 843 | ||
832 | /* unmap the skb */ | 844 | /* unmap the skb */ |
@@ -862,7 +874,7 @@ spider_net_kick_tx_dma(struct spider_net_card *card) | |||
862 | 874 | ||
863 | descr = card->tx_chain.tail; | 875 | descr = card->tx_chain.tail; |
864 | for (;;) { | 876 | for (;;) { |
865 | if (spider_net_get_descr_status(descr) == | 877 | if (spider_net_get_descr_status(descr->hwdescr) == |
866 | SPIDER_NET_DESCR_CARDOWNED) { | 878 | SPIDER_NET_DESCR_CARDOWNED) { |
867 | spider_net_write_reg(card, SPIDER_NET_GDTDCHA, | 879 | spider_net_write_reg(card, SPIDER_NET_GDTDCHA, |
868 | descr->bus_addr); | 880 | descr->bus_addr); |
@@ -958,17 +970,18 @@ static void | |||
958 | spider_net_pass_skb_up(struct spider_net_descr *descr, | 970 | spider_net_pass_skb_up(struct spider_net_descr *descr, |
959 | struct spider_net_card *card) | 971 | struct spider_net_card *card) |
960 | { | 972 | { |
973 | struct spider_net_hw_descr *hwdescr= descr->hwdescr; | ||
961 | struct sk_buff *skb; | 974 | struct sk_buff *skb; |
962 | struct net_device *netdev; | 975 | struct net_device *netdev; |
963 | u32 data_status, data_error; | 976 | u32 data_status, data_error; |
964 | 977 | ||
965 | data_status = descr->data_status; | 978 | data_status = hwdescr->data_status; |
966 | data_error = descr->data_error; | 979 | data_error = hwdescr->data_error; |
967 | netdev = card->netdev; | 980 | netdev = card->netdev; |
968 | 981 | ||
969 | skb = descr->skb; | 982 | skb = descr->skb; |
970 | skb->dev = netdev; | 983 | skb->dev = netdev; |
971 | skb_put(skb, descr->valid_size); | 984 | skb_put(skb, hwdescr->valid_size); |
972 | 985 | ||
973 | /* the card seems to add 2 bytes of junk in front | 986 | /* the card seems to add 2 bytes of junk in front |
974 | * of the ethernet frame */ | 987 | * of the ethernet frame */ |
@@ -1044,9 +1057,10 @@ spider_net_decode_one_descr(struct spider_net_card *card) | |||
1044 | { | 1057 | { |
1045 | struct spider_net_descr_chain *chain = &card->rx_chain; | 1058 | struct spider_net_descr_chain *chain = &card->rx_chain; |
1046 | struct spider_net_descr *descr = chain->tail; | 1059 | struct spider_net_descr *descr = chain->tail; |
1060 | struct spider_net_hw_descr *hwdescr = descr->hwdescr; | ||
1047 | int status; | 1061 | int status; |
1048 | 1062 | ||
1049 | status = spider_net_get_descr_status(descr); | 1063 | status = spider_net_get_descr_status(hwdescr); |
1050 | 1064 | ||
1051 | /* Nothing in the descriptor, or ring must be empty */ | 1065 | /* Nothing in the descriptor, or ring must be empty */ |
1052 | if ((status == SPIDER_NET_DESCR_CARDOWNED) || | 1066 | if ((status == SPIDER_NET_DESCR_CARDOWNED) || |
@@ -1057,7 +1071,7 @@ spider_net_decode_one_descr(struct spider_net_card *card) | |||
1057 | chain->tail = descr->next; | 1071 | chain->tail = descr->next; |
1058 | 1072 | ||
1059 | /* unmap descriptor */ | 1073 | /* unmap descriptor */ |
1060 | pci_unmap_single(card->pdev, descr->buf_addr, | 1074 | pci_unmap_single(card->pdev, hwdescr->buf_addr, |
1061 | SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); | 1075 | SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); |
1062 | 1076 | ||
1063 | if ( (status == SPIDER_NET_DESCR_RESPONSE_ERROR) || | 1077 | if ( (status == SPIDER_NET_DESCR_RESPONSE_ERROR) || |
@@ -1080,27 +1094,26 @@ spider_net_decode_one_descr(struct spider_net_card *card) | |||
1080 | } | 1094 | } |
1081 | 1095 | ||
1082 | /* The cases we'll throw away the packet immediately */ | 1096 | /* The cases we'll throw away the packet immediately */ |
1083 | if (descr->data_error & SPIDER_NET_DESTROY_RX_FLAGS) { | 1097 | if (hwdescr->data_error & SPIDER_NET_DESTROY_RX_FLAGS) { |
1084 | if (netif_msg_rx_err(card)) | 1098 | if (netif_msg_rx_err(card)) |
1085 | pr_err("%s: error in received descriptor found, " | 1099 | pr_err("%s: error in received descriptor found, " |
1086 | "data_status=x%08x, data_error=x%08x\n", | 1100 | "data_status=x%08x, data_error=x%08x\n", |
1087 | card->netdev->name, | 1101 | card->netdev->name, |
1088 | descr->data_status, descr->data_error); | 1102 | hwdescr->data_status, hwdescr->data_error); |
1089 | goto bad_desc; | 1103 | goto bad_desc; |
1090 | } | 1104 | } |
1091 | 1105 | ||
1092 | if (descr->dmac_cmd_status & 0xfefe) { | 1106 | if (hwdescr->dmac_cmd_status & 0xfefe) { |
1093 | pr_err("%s: bad status, cmd_status=x%08x\n", | 1107 | pr_err("%s: bad status, cmd_status=x%08x\n", |
1094 | card->netdev->name, | 1108 | card->netdev->name, |
1095 | descr->dmac_cmd_status); | 1109 | hwdescr->dmac_cmd_status); |
1096 | pr_err("buf_addr=x%08x\n", descr->buf_addr); | 1110 | pr_err("buf_addr=x%08x\n", hwdescr->buf_addr); |
1097 | pr_err("buf_size=x%08x\n", descr->buf_size); | 1111 | pr_err("buf_size=x%08x\n", hwdescr->buf_size); |
1098 | pr_err("next_descr_addr=x%08x\n", descr->next_descr_addr); | 1112 | pr_err("next_descr_addr=x%08x\n", hwdescr->next_descr_addr); |
1099 | pr_err("result_size=x%08x\n", descr->result_size); | 1113 | pr_err("result_size=x%08x\n", hwdescr->result_size); |
1100 | pr_err("valid_size=x%08x\n", descr->valid_size); | 1114 | pr_err("valid_size=x%08x\n", hwdescr->valid_size); |
1101 | pr_err("data_status=x%08x\n", descr->data_status); | 1115 | pr_err("data_status=x%08x\n", hwdescr->data_status); |
1102 | pr_err("data_error=x%08x\n", descr->data_error); | 1116 | pr_err("data_error=x%08x\n", hwdescr->data_error); |
1103 | pr_err("bus_addr=x%08x\n", descr->bus_addr); | ||
1104 | pr_err("which=%ld\n", descr - card->rx_chain.ring); | 1117 | pr_err("which=%ld\n", descr - card->rx_chain.ring); |
1105 | 1118 | ||
1106 | card->spider_stats.rx_desc_error++; | 1119 | card->spider_stats.rx_desc_error++; |
@@ -1109,12 +1122,12 @@ spider_net_decode_one_descr(struct spider_net_card *card) | |||
1109 | 1122 | ||
1110 | /* Ok, we've got a packet in descr */ | 1123 | /* Ok, we've got a packet in descr */ |
1111 | spider_net_pass_skb_up(descr, card); | 1124 | spider_net_pass_skb_up(descr, card); |
1112 | descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; | 1125 | hwdescr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; |
1113 | return 1; | 1126 | return 1; |
1114 | 1127 | ||
1115 | bad_desc: | 1128 | bad_desc: |
1116 | dev_kfree_skb_irq(descr->skb); | 1129 | dev_kfree_skb_irq(descr->skb); |
1117 | descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; | 1130 | hwdescr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; |
1118 | return 0; | 1131 | return 0; |
1119 | } | 1132 | } |
1120 | 1133 | ||
@@ -2200,9 +2213,6 @@ spider_net_setup_netdev(struct spider_net_card *card) | |||
2200 | 2213 | ||
2201 | card->options.rx_csum = SPIDER_NET_RX_CSUM_DEFAULT; | 2214 | card->options.rx_csum = SPIDER_NET_RX_CSUM_DEFAULT; |
2202 | 2215 | ||
2203 | card->tx_chain.num_desc = tx_descriptors; | ||
2204 | card->rx_chain.num_desc = rx_descriptors; | ||
2205 | |||
2206 | spider_net_setup_netdev_ops(netdev); | 2216 | spider_net_setup_netdev_ops(netdev); |
2207 | 2217 | ||
2208 | netdev->features = NETIF_F_HW_CSUM | NETIF_F_LLTX; | 2218 | netdev->features = NETIF_F_HW_CSUM | NETIF_F_LLTX; |
@@ -2250,8 +2260,11 @@ spider_net_alloc_card(void) | |||
2250 | { | 2260 | { |
2251 | struct net_device *netdev; | 2261 | struct net_device *netdev; |
2252 | struct spider_net_card *card; | 2262 | struct spider_net_card *card; |
2263 | size_t alloc_size; | ||
2253 | 2264 | ||
2254 | netdev = alloc_etherdev(sizeof(struct spider_net_card)); | 2265 | alloc_size = sizeof(struct spider_net_card) + |
2266 | (tx_descriptors + rx_descriptors) * sizeof(struct spider_net_descr); | ||
2267 | netdev = alloc_etherdev(alloc_size); | ||
2255 | if (!netdev) | 2268 | if (!netdev) |
2256 | return NULL; | 2269 | return NULL; |
2257 | 2270 | ||
@@ -2262,6 +2275,11 @@ spider_net_alloc_card(void) | |||
2262 | init_waitqueue_head(&card->waitq); | 2275 | init_waitqueue_head(&card->waitq); |
2263 | atomic_set(&card->tx_timeout_task_counter, 0); | 2276 | atomic_set(&card->tx_timeout_task_counter, 0); |
2264 | 2277 | ||
2278 | card->rx_chain.num_desc = rx_descriptors; | ||
2279 | card->rx_chain.ring = card->darray; | ||
2280 | card->tx_chain.num_desc = tx_descriptors; | ||
2281 | card->tx_chain.ring = card->darray + rx_descriptors; | ||
2282 | |||
2265 | return card; | 2283 | return card; |
2266 | } | 2284 | } |
2267 | 2285 | ||
diff --git a/drivers/net/spider_net.h b/drivers/net/spider_net.h index f7d1310ff473..a1a42d5821b5 100644 --- a/drivers/net/spider_net.h +++ b/drivers/net/spider_net.h | |||
@@ -25,7 +25,7 @@ | |||
25 | #ifndef _SPIDER_NET_H | 25 | #ifndef _SPIDER_NET_H |
26 | #define _SPIDER_NET_H | 26 | #define _SPIDER_NET_H |
27 | 27 | ||
28 | #define VERSION "1.6 B" | 28 | #define VERSION "1.6 C" |
29 | 29 | ||
30 | #include "sungem_phy.h" | 30 | #include "sungem_phy.h" |
31 | 31 | ||
@@ -364,8 +364,8 @@ enum spider_net_int2_status { | |||
364 | #define SPIDER_NET_DESCR_NOT_IN_USE 0xF0000000 | 364 | #define SPIDER_NET_DESCR_NOT_IN_USE 0xF0000000 |
365 | #define SPIDER_NET_DESCR_TXDESFLG 0x00800000 | 365 | #define SPIDER_NET_DESCR_TXDESFLG 0x00800000 |
366 | 366 | ||
367 | struct spider_net_descr { | 367 | /* Descriptor, as defined by the hardware */ |
368 | /* as defined by the hardware */ | 368 | struct spider_net_hw_descr { |
369 | u32 buf_addr; | 369 | u32 buf_addr; |
370 | u32 buf_size; | 370 | u32 buf_size; |
371 | u32 next_descr_addr; | 371 | u32 next_descr_addr; |
@@ -374,13 +374,15 @@ struct spider_net_descr { | |||
374 | u32 valid_size; /* all zeroes for tx */ | 374 | u32 valid_size; /* all zeroes for tx */ |
375 | u32 data_status; | 375 | u32 data_status; |
376 | u32 data_error; /* all zeroes for tx */ | 376 | u32 data_error; /* all zeroes for tx */ |
377 | } __attribute__((aligned(32))); | ||
377 | 378 | ||
378 | /* used in the driver */ | 379 | struct spider_net_descr { |
380 | struct spider_net_hw_descr *hwdescr; | ||
379 | struct sk_buff *skb; | 381 | struct sk_buff *skb; |
380 | u32 bus_addr; | 382 | u32 bus_addr; |
381 | struct spider_net_descr *next; | 383 | struct spider_net_descr *next; |
382 | struct spider_net_descr *prev; | 384 | struct spider_net_descr *prev; |
383 | } __attribute__((aligned(32))); | 385 | }; |
384 | 386 | ||
385 | struct spider_net_descr_chain { | 387 | struct spider_net_descr_chain { |
386 | spinlock_t lock; | 388 | spinlock_t lock; |
@@ -388,6 +390,7 @@ struct spider_net_descr_chain { | |||
388 | struct spider_net_descr *tail; | 390 | struct spider_net_descr *tail; |
389 | struct spider_net_descr *ring; | 391 | struct spider_net_descr *ring; |
390 | int num_desc; | 392 | int num_desc; |
393 | struct spider_net_hw_descr *hwring; | ||
391 | dma_addr_t dma_addr; | 394 | dma_addr_t dma_addr; |
392 | }; | 395 | }; |
393 | 396 | ||
@@ -464,6 +467,9 @@ struct spider_net_card { | |||
464 | struct net_device_stats netdev_stats; | 467 | struct net_device_stats netdev_stats; |
465 | struct spider_net_extra_stats spider_stats; | 468 | struct spider_net_extra_stats spider_stats; |
466 | struct spider_net_options options; | 469 | struct spider_net_options options; |
470 | |||
471 | /* Must be last item in struct */ | ||
472 | struct spider_net_descr darray[0]; | ||
467 | }; | 473 | }; |
468 | 474 | ||
469 | #define pr_err(fmt,arg...) \ | 475 | #define pr_err(fmt,arg...) \ |