aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ntb/ntb_transport.c
diff options
context:
space:
mode:
authorJon Mason <jon.mason@intel.com>2013-01-30 13:40:52 -0500
committerJon Mason <jon.mason@intel.com>2013-05-15 13:57:40 -0400
commit113fc505b83b2d16e820ca74fa07f99a34877b1d (patch)
treeb128844cff7e10850abcb8fa363999c8c1d09b22 /drivers/ntb/ntb_transport.c
parentcc0f868d8adef7bdc12cda132654870086d766bc (diff)
NTB: Handle 64bit BAR sizes
64bit BAR sizes are permissible with an NTB device. To support them various modifications and clean-ups were required, most significantly using 2 32bit scratch pad registers for each BAR. Also, modify the driver to allow more than 2 Memory Windows. Signed-off-by: Jon Mason <jon.mason@intel.com>
Diffstat (limited to 'drivers/ntb/ntb_transport.c')
-rw-r--r--drivers/ntb/ntb_transport.c121
1 files changed, 73 insertions, 48 deletions
diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c
index 00f5e80dee35..79a3203eccd9 100644
--- a/drivers/ntb/ntb_transport.c
+++ b/drivers/ntb/ntb_transport.c
@@ -58,7 +58,7 @@
58#include <linux/ntb.h> 58#include <linux/ntb.h>
59#include "ntb_hw.h" 59#include "ntb_hw.h"
60 60
61#define NTB_TRANSPORT_VERSION 2 61#define NTB_TRANSPORT_VERSION 3
62 62
63static unsigned int transport_mtu = 0x401E; 63static unsigned int transport_mtu = 0x401E;
64module_param(transport_mtu, uint, 0644); 64module_param(transport_mtu, uint, 0644);
@@ -173,10 +173,13 @@ struct ntb_payload_header {
173 173
174enum { 174enum {
175 VERSION = 0, 175 VERSION = 0,
176 MW0_SZ,
177 MW1_SZ,
178 NUM_QPS,
179 QP_LINKS, 176 QP_LINKS,
177 NUM_QPS,
178 NUM_MWS,
179 MW0_SZ_HIGH,
180 MW0_SZ_LOW,
181 MW1_SZ_HIGH,
182 MW1_SZ_LOW,
180 MAX_SPAD, 183 MAX_SPAD,
181}; 184};
182 185
@@ -526,6 +529,18 @@ static int ntb_set_mw(struct ntb_transport *nt, int num_mw, unsigned int size)
526 return 0; 529 return 0;
527} 530}
528 531
532static void ntb_free_mw(struct ntb_transport *nt, int num_mw)
533{
534 struct ntb_transport_mw *mw = &nt->mw[num_mw];
535 struct pci_dev *pdev = ntb_query_pdev(nt->ndev);
536
537 if (!mw->virt_addr)
538 return;
539
540 dma_free_coherent(&pdev->dev, mw->size, mw->virt_addr, mw->dma_addr);
541 mw->virt_addr = NULL;
542}
543
529static void ntb_qp_link_cleanup(struct work_struct *work) 544static void ntb_qp_link_cleanup(struct work_struct *work)
530{ 545{
531 struct ntb_transport_qp *qp = container_of(work, 546 struct ntb_transport_qp *qp = container_of(work,
@@ -604,25 +619,31 @@ static void ntb_transport_link_work(struct work_struct *work)
604 u32 val; 619 u32 val;
605 int rc, i; 620 int rc, i;
606 621
607 /* send the local info */ 622 /* send the local info, in the opposite order of the way we read it */
608 rc = ntb_write_remote_spad(ndev, VERSION, NTB_TRANSPORT_VERSION); 623 for (i = 0; i < NTB_NUM_MW; i++) {
609 if (rc) { 624 rc = ntb_write_remote_spad(ndev, MW0_SZ_HIGH + (i * 2),
610 dev_err(&pdev->dev, "Error writing %x to remote spad %d\n", 625 ntb_get_mw_size(ndev, i) >> 32);
611 0, VERSION); 626 if (rc) {
612 goto out; 627 dev_err(&pdev->dev, "Error writing %u to remote spad %d\n",
613 } 628 (u32)(ntb_get_mw_size(ndev, i) >> 32),
629 MW0_SZ_HIGH + (i * 2));
630 goto out;
631 }
614 632
615 rc = ntb_write_remote_spad(ndev, MW0_SZ, ntb_get_mw_size(ndev, 0)); 633 rc = ntb_write_remote_spad(ndev, MW0_SZ_LOW + (i * 2),
616 if (rc) { 634 (u32) ntb_get_mw_size(ndev, i));
617 dev_err(&pdev->dev, "Error writing %x to remote spad %d\n", 635 if (rc) {
618 (u32) ntb_get_mw_size(ndev, 0), MW0_SZ); 636 dev_err(&pdev->dev, "Error writing %u to remote spad %d\n",
619 goto out; 637 (u32) ntb_get_mw_size(ndev, i),
638 MW0_SZ_LOW + (i * 2));
639 goto out;
640 }
620 } 641 }
621 642
622 rc = ntb_write_remote_spad(ndev, MW1_SZ, ntb_get_mw_size(ndev, 1)); 643 rc = ntb_write_remote_spad(ndev, NUM_MWS, NTB_NUM_MW);
623 if (rc) { 644 if (rc) {
624 dev_err(&pdev->dev, "Error writing %x to remote spad %d\n", 645 dev_err(&pdev->dev, "Error writing %x to remote spad %d\n",
625 (u32) ntb_get_mw_size(ndev, 1), MW1_SZ); 646 NTB_NUM_MW, NUM_MWS);
626 goto out; 647 goto out;
627 } 648 }
628 649
@@ -633,16 +654,10 @@ static void ntb_transport_link_work(struct work_struct *work)
633 goto out; 654 goto out;
634 } 655 }
635 656
636 rc = ntb_read_local_spad(nt->ndev, QP_LINKS, &val); 657 rc = ntb_write_remote_spad(ndev, VERSION, NTB_TRANSPORT_VERSION);
637 if (rc) {
638 dev_err(&pdev->dev, "Error reading spad %d\n", QP_LINKS);
639 goto out;
640 }
641
642 rc = ntb_write_remote_spad(ndev, QP_LINKS, val);
643 if (rc) { 658 if (rc) {
644 dev_err(&pdev->dev, "Error writing %x to remote spad %d\n", 659 dev_err(&pdev->dev, "Error writing %x to remote spad %d\n",
645 val, QP_LINKS); 660 NTB_TRANSPORT_VERSION, VERSION);
646 goto out; 661 goto out;
647 } 662 }
648 663
@@ -667,33 +682,43 @@ static void ntb_transport_link_work(struct work_struct *work)
667 goto out; 682 goto out;
668 dev_dbg(&pdev->dev, "Remote max number of qps = %d\n", val); 683 dev_dbg(&pdev->dev, "Remote max number of qps = %d\n", val);
669 684
670 rc = ntb_read_remote_spad(ndev, MW0_SZ, &val); 685 rc = ntb_read_remote_spad(ndev, NUM_MWS, &val);
671 if (rc) { 686 if (rc) {
672 dev_err(&pdev->dev, "Error reading remote spad %d\n", MW0_SZ); 687 dev_err(&pdev->dev, "Error reading remote spad %d\n", NUM_MWS);
673 goto out; 688 goto out;
674 } 689 }
675 690
676 if (!val) 691 if (val != NTB_NUM_MW)
677 goto out; 692 goto out;
678 dev_dbg(&pdev->dev, "Remote MW0 size = %d\n", val); 693 dev_dbg(&pdev->dev, "Remote number of mws = %d\n", val);
679 694
680 rc = ntb_set_mw(nt, 0, val); 695 for (i = 0; i < NTB_NUM_MW; i++) {
681 if (rc) 696 u64 val64;
682 goto out;
683 697
684 rc = ntb_read_remote_spad(ndev, MW1_SZ, &val); 698 rc = ntb_read_remote_spad(ndev, MW0_SZ_HIGH + (i * 2), &val);
685 if (rc) { 699 if (rc) {
686 dev_err(&pdev->dev, "Error reading remote spad %d\n", MW1_SZ); 700 dev_err(&pdev->dev, "Error reading remote spad %d\n",
687 goto out; 701 MW0_SZ_HIGH + (i * 2));
688 } 702 goto out1;
703 }
689 704
690 if (!val) 705 val64 = (u64) val << 32;
691 goto out;
692 dev_dbg(&pdev->dev, "Remote MW1 size = %d\n", val);
693 706
694 rc = ntb_set_mw(nt, 1, val); 707 rc = ntb_read_remote_spad(ndev, MW0_SZ_LOW + (i * 2), &val);
695 if (rc) 708 if (rc) {
696 goto out; 709 dev_err(&pdev->dev, "Error reading remote spad %d\n",
710 MW0_SZ_LOW + (i * 2));
711 goto out1;
712 }
713
714 val64 |= val;
715
716 dev_dbg(&pdev->dev, "Remote MW%d size = %llu\n", i, val64);
717
718 rc = ntb_set_mw(nt, i, val64);
719 if (rc)
720 goto out1;
721 }
697 722
698 nt->transport_link = NTB_LINK_UP; 723 nt->transport_link = NTB_LINK_UP;
699 724
@@ -708,6 +733,9 @@ static void ntb_transport_link_work(struct work_struct *work)
708 733
709 return; 734 return;
710 735
736out1:
737 for (i = 0; i < NTB_NUM_MW; i++)
738 ntb_free_mw(nt, i);
711out: 739out:
712 if (ntb_hw_link_status(ndev)) 740 if (ntb_hw_link_status(ndev))
713 schedule_delayed_work(&nt->link_work, 741 schedule_delayed_work(&nt->link_work,
@@ -897,10 +925,7 @@ void ntb_transport_free(void *transport)
897 pdev = ntb_query_pdev(nt->ndev); 925 pdev = ntb_query_pdev(nt->ndev);
898 926
899 for (i = 0; i < NTB_NUM_MW; i++) 927 for (i = 0; i < NTB_NUM_MW; i++)
900 if (nt->mw[i].virt_addr) 928 ntb_free_mw(nt, i);
901 dma_free_coherent(&pdev->dev, nt->mw[i].size,
902 nt->mw[i].virt_addr,
903 nt->mw[i].dma_addr);
904 929
905 kfree(nt->qps); 930 kfree(nt->qps);
906 ntb_unregister_transport(nt->ndev); 931 ntb_unregister_transport(nt->ndev);