aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/atm
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2009-01-28 00:46:56 -0500
committerDavid Woodhouse <David.Woodhouse@intel.com>2009-01-28 00:46:56 -0500
commit909372317e67bdbbfced5dab3ade3437e3f2b254 (patch)
treeafb45c7a2537df688b1a56bec9b8d11591a4cdae /drivers/atm
parentc0fe30265a1fe3a69e0ce0d08b49de1dda9c1190 (diff)
solos: First attempt at DMA support
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/atm')
-rw-r--r--drivers/atm/solos-pci.c118
1 files changed, 90 insertions, 28 deletions
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index b7d4af3df2a6..63c9ad03aec8 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -55,6 +55,8 @@
55#define FLASH_BUSY 0x60 55#define FLASH_BUSY 0x60
56#define FPGA_MODE 0x5C 56#define FPGA_MODE 0x5C
57#define FLASH_MODE 0x58 57#define FLASH_MODE 0x58
58#define TX_DMA_ADDR(port) (0x40 + (4 * (port)))
59#define RX_DMA_ADDR(port) (0x30 + (4 * (port)))
58 60
59#define DATA_RAM_SIZE 32768 61#define DATA_RAM_SIZE 32768
60#define BUF_SIZE 4096 62#define BUF_SIZE 4096
@@ -78,6 +80,14 @@ struct pkt_hdr {
78 __le16 type; 80 __le16 type;
79}; 81};
80 82
83struct solos_skb_cb {
84 struct atm_vcc *vcc;
85 uint32_t dma_addr;
86};
87
88
89#define SKB_CB(skb) ((struct solos_skb_cb *)skb->cb)
90
81#define PKT_DATA 0 91#define PKT_DATA 0
82#define PKT_COMMAND 1 92#define PKT_COMMAND 1
83#define PKT_POPEN 3 93#define PKT_POPEN 3
@@ -98,8 +108,11 @@ struct solos_card {
98 struct list_head param_queue; 108 struct list_head param_queue;
99 struct sk_buff_head tx_queue[4]; 109 struct sk_buff_head tx_queue[4];
100 struct sk_buff_head cli_queue[4]; 110 struct sk_buff_head cli_queue[4];
111 struct sk_buff *tx_skb[4];
112 struct sk_buff *rx_skb[4];
101 wait_queue_head_t param_wq; 113 wait_queue_head_t param_wq;
102 wait_queue_head_t fw_wq; 114 wait_queue_head_t fw_wq;
115 int using_dma;
103}; 116};
104 117
105 118
@@ -588,44 +601,64 @@ void solos_bh(unsigned long card_arg)
588 601
589 for (port = 0; port < card->nr_ports; port++) { 602 for (port = 0; port < card->nr_ports; port++) {
590 if (card_flags & (0x10 << port)) { 603 if (card_flags & (0x10 << port)) {
591 struct pkt_hdr header; 604 struct pkt_hdr _hdr, *header;
592 struct sk_buff *skb; 605 struct sk_buff *skb;
593 struct atm_vcc *vcc; 606 struct atm_vcc *vcc;
594 int size; 607 int size;
595 608
596 rx_done |= 0x10 << port; 609 if (card->using_dma) {
610 skb = card->rx_skb[port];
611 pci_unmap_single(card->dev, SKB_CB(skb)->dma_addr, skb->len,
612 PCI_DMA_FROMDEVICE);
613
614 card->rx_skb[port] = alloc_skb(2048, GFP_ATOMIC);
615 if (card->rx_skb[port]) {
616 SKB_CB(card->rx_skb[port])->dma_addr =
617 pci_map_single(card->dev, skb->data, skb->len,
618 PCI_DMA_FROMDEVICE);
619 iowrite32(SKB_CB(card->rx_skb[port])->dma_addr,
620 card->config_regs + RX_DMA_ADDR(port));
621 }
622 header = (void *)skb->data;
623 size = le16_to_cpu(header->size);
624 skb_put(skb, size + sizeof(*header));
625 skb_pull(skb, sizeof(*header));
626 } else {
627 header = &_hdr;
597 628
598 memcpy_fromio(&header, RX_BUF(card, port), sizeof(header)); 629 rx_done |= 0x10 << port;
599 630
600 size = le16_to_cpu(header.size); 631 memcpy_fromio(header, RX_BUF(card, port), sizeof(*header));
601 632
602 skb = alloc_skb(size + 1, GFP_ATOMIC); 633 size = le16_to_cpu(header->size);
603 if (!skb) {
604 if (net_ratelimit())
605 dev_warn(&card->dev->dev, "Failed to allocate sk_buff for RX\n");
606 continue;
607 }
608 634
609 memcpy_fromio(skb_put(skb, size), 635 skb = alloc_skb(size + 1, GFP_ATOMIC);
610 RX_BUF(card, port) + sizeof(header), 636 if (!skb) {
611 size); 637 if (net_ratelimit())
638 dev_warn(&card->dev->dev, "Failed to allocate sk_buff for RX\n");
639 continue;
640 }
612 641
642 memcpy_fromio(skb_put(skb, size),
643 RX_BUF(card, port) + sizeof(*header),
644 size);
645 }
613 if (atmdebug) { 646 if (atmdebug) {
614 dev_info(&card->dev->dev, "Received: device %d\n", port); 647 dev_info(&card->dev->dev, "Received: device %d\n", port);
615 dev_info(&card->dev->dev, "size: %d VPI: %d VCI: %d\n", 648 dev_info(&card->dev->dev, "size: %d VPI: %d VCI: %d\n",
616 size, le16_to_cpu(header.vpi), 649 size, le16_to_cpu(header->vpi),
617 le16_to_cpu(header.vci)); 650 le16_to_cpu(header->vci));
618 print_buffer(skb); 651 print_buffer(skb);
619 } 652 }
620 653
621 switch (le16_to_cpu(header.type)) { 654 switch (le16_to_cpu(header->type)) {
622 case PKT_DATA: 655 case PKT_DATA:
623 vcc = find_vcc(card->atmdev[port], le16_to_cpu(header.vpi), 656 vcc = find_vcc(card->atmdev[port], le16_to_cpu(header->vpi),
624 le16_to_cpu(header.vci)); 657 le16_to_cpu(header->vci));
625 if (!vcc) { 658 if (!vcc) {
626 if (net_ratelimit()) 659 if (net_ratelimit())
627 dev_warn(&card->dev->dev, "Received packet for unknown VCI.VPI %d.%d on port %d\n", 660 dev_warn(&card->dev->dev, "Received packet for unknown VCI.VPI %d.%d on port %d\n",
628 le16_to_cpu(header.vci), le16_to_cpu(header.vpi), 661 le16_to_cpu(header->vci), le16_to_cpu(header->vpi),
629 port); 662 port);
630 continue; 663 continue;
631 } 664 }
@@ -839,7 +872,7 @@ static void fpga_queue(struct solos_card *card, int port, struct sk_buff *skb,
839{ 872{
840 int old_len; 873 int old_len;
841 874
842 *(void **)skb->cb = vcc; 875 SKB_CB(skb)->vcc = vcc;
843 876
844 spin_lock(&card->tx_queue_lock); 877 spin_lock(&card->tx_queue_lock);
845 old_len = skb_queue_len(&card->tx_queue[port]); 878 old_len = skb_queue_len(&card->tx_queue[port]);
@@ -881,17 +914,37 @@ static int fpga_tx(struct solos_card *card)
881 port); 914 port);
882 print_buffer(skb); 915 print_buffer(skb);
883 } 916 }
884 memcpy_toio(TX_BUF(card, port), skb->data, skb->len); 917 if (card->using_dma) {
918 if (card->tx_skb[port]) {
919 struct sk_buff *oldskb = card->tx_skb[port];
885 920
886 vcc = *(void **)skb->cb; 921 pci_unmap_single(card->dev, SKB_CB(oldskb)->dma_addr,
922 oldskb->len, PCI_DMA_TODEVICE);
887 923
888 if (vcc) { 924 vcc = SKB_CB(oldskb)->vcc;
889 atomic_inc(&vcc->stats->tx);
890 solos_pop(vcc, skb);
891 } else
892 dev_kfree_skb_irq(skb);
893 925
894 tx_started |= 1 << port; //Set TX full flag 926 if (vcc) {
927 atomic_inc(&vcc->stats->tx);
928 solos_pop(vcc, oldskb);
929 } else
930 dev_kfree_skb_irq(oldskb);
931 }
932
933 SKB_CB(skb)->dma_addr = pci_map_single(card->dev, skb->data,
934 skb->len, PCI_DMA_TODEVICE);
935 iowrite32(SKB_CB(skb)->dma_addr, card->config_regs + TX_DMA_ADDR(port));
936 } else {
937 memcpy_toio(TX_BUF(card, port), skb->data, skb->len);
938 tx_started |= 1 << port; //Set TX full flag
939
940 vcc = SKB_CB(skb)->vcc;
941
942 if (vcc) {
943 atomic_inc(&vcc->stats->tx);
944 solos_pop(vcc, skb);
945 } else
946 dev_kfree_skb_irq(skb);
947 }
895 } 948 }
896 } 949 }
897 if (tx_started) 950 if (tx_started)
@@ -999,6 +1052,12 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
999 goto out; 1052 goto out;
1000 } 1053 }
1001 1054
1055 err = pci_set_dma_mask(dev, DMA_32BIT_MASK);
1056 if (err) {
1057 dev_warn(&dev->dev, "Failed to set 32-bit DMA mask\n");
1058 goto out;
1059 }
1060
1002 err = pci_request_regions(dev, "solos"); 1061 err = pci_request_regions(dev, "solos");
1003 if (err) { 1062 if (err) {
1004 dev_warn(&dev->dev, "Failed to request regions\n"); 1063 dev_warn(&dev->dev, "Failed to request regions\n");
@@ -1035,6 +1094,9 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
1035 dev_info(&dev->dev, "Solos FPGA Version %d.%02d svn-%d\n", 1094 dev_info(&dev->dev, "Solos FPGA Version %d.%02d svn-%d\n",
1036 major_ver, minor_ver, fpga_ver); 1095 major_ver, minor_ver, fpga_ver);
1037 1096
1097 if (fpga_ver > 27)
1098 card->using_dma = 1;
1099
1038 card->nr_ports = 2; /* FIXME: Detect daughterboard */ 1100 card->nr_ports = 2; /* FIXME: Detect daughterboard */
1039 1101
1040 pci_set_drvdata(dev, card); 1102 pci_set_drvdata(dev, card);