aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRoland Dreier <roland@topspin.com>2005-04-16 18:26:34 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:26:34 -0400
commit68a3c21203b73696769dfdceb68d2d7f5d3c20a0 (patch)
tree876aae59e6f49437b0388f9a95a708edc252bac4 /drivers
parent08aeb14e5f6c28878266b01c87cc5ce31101afa8 (diff)
[PATCH] IB/mthca: add support for new MT25204 HCA
Decouple table of HCA features from exact HCA device type. Add a current FW version field so we can warn when someone is using old FW. Add support for new MT25204 HCA. Remove the warning about mem-free support, since it should be pretty solid at this point. Signed-off-by: Roland Dreier <roland@topspin.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/infiniband/hw/mthca/mthca_dev.h13
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c67
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c17
-rw-r--r--drivers/infiniband/hw/mthca/mthca_reset.c2
4 files changed, 73 insertions, 26 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h
index d014b443dc3..e3d79e267dc 100644
--- a/drivers/infiniband/hw/mthca/mthca_dev.h
+++ b/drivers/infiniband/hw/mthca/mthca_dev.h
@@ -49,20 +49,15 @@
49#define DRV_VERSION "0.06-pre" 49#define DRV_VERSION "0.06-pre"
50#define DRV_RELDATE "November 8, 2004" 50#define DRV_RELDATE "November 8, 2004"
51 51
52/* Types of supported HCA */
53enum {
54 TAVOR, /* MT23108 */
55 ARBEL_COMPAT, /* MT25208 in Tavor compat mode */
56 ARBEL_NATIVE /* MT25208 with extended features */
57};
58
59enum { 52enum {
60 MTHCA_FLAG_DDR_HIDDEN = 1 << 1, 53 MTHCA_FLAG_DDR_HIDDEN = 1 << 1,
61 MTHCA_FLAG_SRQ = 1 << 2, 54 MTHCA_FLAG_SRQ = 1 << 2,
62 MTHCA_FLAG_MSI = 1 << 3, 55 MTHCA_FLAG_MSI = 1 << 3,
63 MTHCA_FLAG_MSI_X = 1 << 4, 56 MTHCA_FLAG_MSI_X = 1 << 4,
64 MTHCA_FLAG_NO_LAM = 1 << 5, 57 MTHCA_FLAG_NO_LAM = 1 << 5,
65 MTHCA_FLAG_FMR = 1 << 6 58 MTHCA_FLAG_FMR = 1 << 6,
59 MTHCA_FLAG_MEMFREE = 1 << 7,
60 MTHCA_FLAG_PCIE = 1 << 8
66}; 61};
67 62
68enum { 63enum {
@@ -473,7 +468,7 @@ static inline struct mthca_dev *to_mdev(struct ib_device *ibdev)
473 468
474static inline int mthca_is_memfree(struct mthca_dev *dev) 469static inline int mthca_is_memfree(struct mthca_dev *dev)
475{ 470{
476 return dev->hca_type == ARBEL_NATIVE; 471 return dev->mthca_flags & MTHCA_FLAG_MEMFREE;
477} 472}
478 473
479#endif /* MTHCA_DEV_H */ 474#endif /* MTHCA_DEV_H */
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 014369626f6..a1fa326dceb 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -103,7 +103,7 @@ static int __devinit mthca_tune_pci(struct mthca_dev *mdev)
103 "aborting.\n"); 103 "aborting.\n");
104 return -ENODEV; 104 return -ENODEV;
105 } 105 }
106 } else if (mdev->hca_type == TAVOR) 106 } else if (!(mdev->mthca_flags & MTHCA_FLAG_PCIE))
107 mthca_info(mdev, "No PCI-X capability, not setting RBC.\n"); 107 mthca_info(mdev, "No PCI-X capability, not setting RBC.\n");
108 108
109 cap = pci_find_capability(mdev->pdev, PCI_CAP_ID_EXP); 109 cap = pci_find_capability(mdev->pdev, PCI_CAP_ID_EXP);
@@ -119,8 +119,7 @@ static int __devinit mthca_tune_pci(struct mthca_dev *mdev)
119 "register, aborting.\n"); 119 "register, aborting.\n");
120 return -ENODEV; 120 return -ENODEV;
121 } 121 }
122 } else if (mdev->hca_type == ARBEL_NATIVE || 122 } else if (mdev->mthca_flags & MTHCA_FLAG_PCIE)
123 mdev->hca_type == ARBEL_COMPAT)
124 mthca_info(mdev, "No PCI Express capability, " 123 mthca_info(mdev, "No PCI Express capability, "
125 "not setting Max Read Request Size.\n"); 124 "not setting Max Read Request Size.\n");
126 125
@@ -438,7 +437,7 @@ static int __devinit mthca_init_icm(struct mthca_dev *mdev,
438 if (!mdev->qp_table.rdb_table) { 437 if (!mdev->qp_table.rdb_table) {
439 mthca_err(mdev, "Failed to map RDB context memory, aborting\n"); 438 mthca_err(mdev, "Failed to map RDB context memory, aborting\n");
440 err = -ENOMEM; 439 err = -ENOMEM;
441 goto err_unmap_eqp; 440 goto err_unmap_rdb;
442 } 441 }
443 442
444 mdev->cq_table.table = mthca_alloc_icm_table(mdev, init_hca->cqc_base, 443 mdev->cq_table.table = mthca_alloc_icm_table(mdev, init_hca->cqc_base,
@@ -593,6 +592,7 @@ static int __devinit mthca_init_arbel(struct mthca_dev *mdev)
593 592
594err_free_icm: 593err_free_icm:
595 mthca_free_icm_table(mdev, mdev->cq_table.table); 594 mthca_free_icm_table(mdev, mdev->cq_table.table);
595 mthca_free_icm_table(mdev, mdev->qp_table.rdb_table);
596 mthca_free_icm_table(mdev, mdev->qp_table.eqp_table); 596 mthca_free_icm_table(mdev, mdev->qp_table.eqp_table);
597 mthca_free_icm_table(mdev, mdev->qp_table.qp_table); 597 mthca_free_icm_table(mdev, mdev->qp_table.qp_table);
598 mthca_free_icm_table(mdev, mdev->mr_table.mpt_table); 598 mthca_free_icm_table(mdev, mdev->mr_table.mpt_table);
@@ -851,6 +851,7 @@ static void mthca_close_hca(struct mthca_dev *mdev)
851 851
852 if (mthca_is_memfree(mdev)) { 852 if (mthca_is_memfree(mdev)) {
853 mthca_free_icm_table(mdev, mdev->cq_table.table); 853 mthca_free_icm_table(mdev, mdev->cq_table.table);
854 mthca_free_icm_table(mdev, mdev->qp_table.rdb_table);
854 mthca_free_icm_table(mdev, mdev->qp_table.eqp_table); 855 mthca_free_icm_table(mdev, mdev->qp_table.eqp_table);
855 mthca_free_icm_table(mdev, mdev->qp_table.qp_table); 856 mthca_free_icm_table(mdev, mdev->qp_table.qp_table);
856 mthca_free_icm_table(mdev, mdev->mr_table.mpt_table); 857 mthca_free_icm_table(mdev, mdev->mr_table.mpt_table);
@@ -869,11 +870,32 @@ static void mthca_close_hca(struct mthca_dev *mdev)
869 mthca_SYS_DIS(mdev, &status); 870 mthca_SYS_DIS(mdev, &status);
870} 871}
871 872
873/* Types of supported HCA */
874enum {
875 TAVOR, /* MT23108 */
876 ARBEL_COMPAT, /* MT25208 in Tavor compat mode */
877 ARBEL_NATIVE, /* MT25208 with extended features */
878 SINAI /* MT25204 */
879};
880
881#define MTHCA_FW_VER(major, minor, subminor) \
882 (((u64) (major) << 32) | ((u64) (minor) << 16) | (u64) (subminor))
883
884static struct {
885 u64 latest_fw;
886 int is_memfree;
887 int is_pcie;
888} mthca_hca_table[] = {
889 [TAVOR] = { .latest_fw = MTHCA_FW_VER(3, 3, 2), .is_memfree = 0, .is_pcie = 0 },
890 [ARBEL_COMPAT] = { .latest_fw = MTHCA_FW_VER(4, 6, 2), .is_memfree = 0, .is_pcie = 1 },
891 [ARBEL_NATIVE] = { .latest_fw = MTHCA_FW_VER(5, 0, 1), .is_memfree = 1, .is_pcie = 1 },
892 [SINAI] = { .latest_fw = MTHCA_FW_VER(1, 0, 1), .is_memfree = 1, .is_pcie = 1 }
893};
894
872static int __devinit mthca_init_one(struct pci_dev *pdev, 895static int __devinit mthca_init_one(struct pci_dev *pdev,
873 const struct pci_device_id *id) 896 const struct pci_device_id *id)
874{ 897{
875 static int mthca_version_printed = 0; 898 static int mthca_version_printed = 0;
876 static int mthca_memfree_warned = 0;
877 int ddr_hidden = 0; 899 int ddr_hidden = 0;
878 int err; 900 int err;
879 struct mthca_dev *mdev; 901 struct mthca_dev *mdev;
@@ -886,6 +908,12 @@ static int __devinit mthca_init_one(struct pci_dev *pdev,
886 printk(KERN_INFO PFX "Initializing %s (%s)\n", 908 printk(KERN_INFO PFX "Initializing %s (%s)\n",
887 pci_pretty_name(pdev), pci_name(pdev)); 909 pci_pretty_name(pdev), pci_name(pdev));
888 910
911 if (id->driver_data >= ARRAY_SIZE(mthca_hca_table)) {
912 printk(KERN_ERR PFX "%s (%s) has invalid driver data %lx\n",
913 pci_pretty_name(pdev), pci_name(pdev), id->driver_data);
914 return -ENODEV;
915 }
916
889 err = pci_enable_device(pdev); 917 err = pci_enable_device(pdev);
890 if (err) { 918 if (err) {
891 dev_err(&pdev->dev, "Cannot enable PCI device, " 919 dev_err(&pdev->dev, "Cannot enable PCI device, "
@@ -950,15 +978,14 @@ static int __devinit mthca_init_one(struct pci_dev *pdev,
950 goto err_free_res; 978 goto err_free_res;
951 } 979 }
952 980
953 mdev->pdev = pdev; 981 mdev->pdev = pdev;
954 mdev->hca_type = id->driver_data;
955
956 if (mthca_is_memfree(mdev) && !mthca_memfree_warned++)
957 mthca_warn(mdev, "Warning: native MT25208 mode support is incomplete. "
958 "Your HCA may not work properly.\n");
959 982
960 if (ddr_hidden) 983 if (ddr_hidden)
961 mdev->mthca_flags |= MTHCA_FLAG_DDR_HIDDEN; 984 mdev->mthca_flags |= MTHCA_FLAG_DDR_HIDDEN;
985 if (mthca_hca_table[id->driver_data].is_memfree)
986 mdev->mthca_flags |= MTHCA_FLAG_MEMFREE;
987 if (mthca_hca_table[id->driver_data].is_pcie)
988 mdev->mthca_flags |= MTHCA_FLAG_PCIE;
962 989
963 /* 990 /*
964 * Now reset the HCA before we touch the PCI capabilities or 991 * Now reset the HCA before we touch the PCI capabilities or
@@ -997,6 +1024,16 @@ static int __devinit mthca_init_one(struct pci_dev *pdev,
997 if (err) 1024 if (err)
998 goto err_iounmap; 1025 goto err_iounmap;
999 1026
1027 if (mdev->fw_ver < mthca_hca_table[id->driver_data].latest_fw) {
1028 mthca_warn(mdev, "HCA FW version %x.%x.%x is old (%x.%x.%x is current).\n",
1029 (int) (mdev->fw_ver >> 32), (int) (mdev->fw_ver >> 16) & 0xffff,
1030 (int) (mdev->fw_ver & 0xffff),
1031 (int) (mthca_hca_table[id->driver_data].latest_fw >> 32),
1032 (int) (mthca_hca_table[id->driver_data].latest_fw >> 16) & 0xffff,
1033 (int) (mthca_hca_table[id->driver_data].latest_fw & 0xffff));
1034 mthca_warn(mdev, "If you have problems, try updating your HCA FW.\n");
1035 }
1036
1000 err = mthca_setup_hca(mdev); 1037 err = mthca_setup_hca(mdev);
1001 if (err) 1038 if (err)
1002 goto err_close; 1039 goto err_close;
@@ -1112,6 +1149,14 @@ static struct pci_device_id mthca_pci_table[] = {
1112 .driver_data = ARBEL_NATIVE }, 1149 .driver_data = ARBEL_NATIVE },
1113 { PCI_DEVICE(PCI_VENDOR_ID_TOPSPIN, PCI_DEVICE_ID_MELLANOX_ARBEL), 1150 { PCI_DEVICE(PCI_VENDOR_ID_TOPSPIN, PCI_DEVICE_ID_MELLANOX_ARBEL),
1114 .driver_data = ARBEL_NATIVE }, 1151 .driver_data = ARBEL_NATIVE },
1152 { PCI_DEVICE(PCI_VENDOR_ID_MELLANOX, PCI_DEVICE_ID_MELLANOX_SINAI),
1153 .driver_data = SINAI },
1154 { PCI_DEVICE(PCI_VENDOR_ID_TOPSPIN, PCI_DEVICE_ID_MELLANOX_SINAI),
1155 .driver_data = SINAI },
1156 { PCI_DEVICE(PCI_VENDOR_ID_MELLANOX, PCI_DEVICE_ID_MELLANOX_SINAI_OLD),
1157 .driver_data = SINAI },
1158 { PCI_DEVICE(PCI_VENDOR_ID_TOPSPIN, PCI_DEVICE_ID_MELLANOX_SINAI_OLD),
1159 .driver_data = SINAI },
1115 { 0, } 1160 { 0, }
1116}; 1161};
1117 1162
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index 501c9cc4e1a..159f4e6c312 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -659,11 +659,18 @@ static ssize_t show_fw_ver(struct class_device *cdev, char *buf)
659static ssize_t show_hca(struct class_device *cdev, char *buf) 659static ssize_t show_hca(struct class_device *cdev, char *buf)
660{ 660{
661 struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev); 661 struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev);
662 switch (dev->hca_type) { 662 switch (dev->pdev->device) {
663 case TAVOR: return sprintf(buf, "MT23108\n"); 663 case PCI_DEVICE_ID_MELLANOX_TAVOR:
664 case ARBEL_COMPAT: return sprintf(buf, "MT25208 (MT23108 compat mode)\n"); 664 return sprintf(buf, "MT23108\n");
665 case ARBEL_NATIVE: return sprintf(buf, "MT25208\n"); 665 case PCI_DEVICE_ID_MELLANOX_ARBEL_COMPAT:
666 default: return sprintf(buf, "unknown\n"); 666 return sprintf(buf, "MT25208 (MT23108 compat mode)\n");
667 case PCI_DEVICE_ID_MELLANOX_ARBEL:
668 return sprintf(buf, "MT25208\n");
669 case PCI_DEVICE_ID_MELLANOX_SINAI:
670 case PCI_DEVICE_ID_MELLANOX_SINAI_OLD:
671 return sprintf(buf, "MT25204\n");
672 default:
673 return sprintf(buf, "unknown\n");
667 } 674 }
668} 675}
669 676
diff --git a/drivers/infiniband/hw/mthca/mthca_reset.c b/drivers/infiniband/hw/mthca/mthca_reset.c
index ce3fff7d02b..8ea801271a4 100644
--- a/drivers/infiniband/hw/mthca/mthca_reset.c
+++ b/drivers/infiniband/hw/mthca/mthca_reset.c
@@ -63,7 +63,7 @@ int mthca_reset(struct mthca_dev *mdev)
63 * header as well. 63 * header as well.
64 */ 64 */
65 65
66 if (mdev->hca_type == TAVOR) { 66 if (!(mdev->mthca_flags & MTHCA_FLAG_PCIE)) {
67 /* Look for the bridge -- its device ID will be 2 more 67 /* Look for the bridge -- its device ID will be 2 more
68 than HCA's device ID. */ 68 than HCA's device ID. */
69 while ((bridge = pci_get_device(mdev->pdev->vendor, 69 while ((bridge = pci_get_device(mdev->pdev->vendor,