aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorLinas Vepstas <linas@austin.ibm.com>2007-02-20 17:40:06 -0500
committerJeff Garzik <jeff@garzik.org>2007-02-27 04:16:03 -0500
commit4cb6f9e57d5d7c26d08809c1ce6310c8a7dc96d2 (patch)
tree28d5202963a7f11e40d57eae3a5d2a1271f1f677 /drivers/net
parent4b23a554db1571306d9e9cfb2321c3a44770371e (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')
-rw-r--r--drivers/net/spider_net.c150
-rw-r--r--drivers/net/spider_net.h16
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 */
301static inline int 301static inline int
302spider_net_get_descr_status(struct spider_net_descr *descr) 302spider_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
416spider_net_prepare_rx_descr(struct spider_net_card *card, 419spider_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,
725static int 732static int
726spider_net_set_low_watermark(struct spider_net_card *card) 733spider_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
958spider_net_pass_skb_up(struct spider_net_descr *descr, 970spider_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
1115bad_desc: 1128bad_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
367struct spider_net_descr { 367/* Descriptor, as defined by the hardware */
368 /* as defined by the hardware */ 368struct 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 */ 379struct 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
385struct spider_net_descr_chain { 387struct 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...) \