diff options
author | Linas Vepstas <linas@austin.ibm.com> | 2007-02-20 17:40:06 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-02-27 04:16:03 -0500 |
commit | 4cb6f9e57d5d7c26d08809c1ce6310c8a7dc96d2 (patch) | |
tree | 28d5202963a7f11e40d57eae3a5d2a1271f1f677 /drivers/net/spider_net.c | |
parent | 4b23a554db1571306d9e9cfb2321c3a44770371e (diff) |
spidernet: separate hardware state from driver state.
This patch separates the hardware descriptor state from the
driver descriptor state, per (old) suggestion from Ben Herrenschmidt.
This compiles and boots and seems to work.
Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Cc: Jens Osterkamp <Jens.Osterkamp@de.ibm.com>
Cc: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/spider_net.c')
-rw-r--r-- | drivers/net/spider_net.c | 150 |
1 files changed, 84 insertions, 66 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 | ||