diff options
author | Roland Dreier <roland@topspin.com> | 2005-04-16 18:26:34 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:26:34 -0400 |
commit | 68a3c21203b73696769dfdceb68d2d7f5d3c20a0 (patch) | |
tree | 876aae59e6f49437b0388f9a95a708edc252bac4 /drivers | |
parent | 08aeb14e5f6c28878266b01c87cc5ce31101afa8 (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.h | 13 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_main.c | 67 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_provider.c | 17 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_reset.c | 2 |
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 */ | ||
53 | enum { | ||
54 | TAVOR, /* MT23108 */ | ||
55 | ARBEL_COMPAT, /* MT25208 in Tavor compat mode */ | ||
56 | ARBEL_NATIVE /* MT25208 with extended features */ | ||
57 | }; | ||
58 | |||
59 | enum { | 52 | enum { |
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 | ||
68 | enum { | 63 | enum { |
@@ -473,7 +468,7 @@ static inline struct mthca_dev *to_mdev(struct ib_device *ibdev) | |||
473 | 468 | ||
474 | static inline int mthca_is_memfree(struct mthca_dev *dev) | 469 | static 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 | ||
594 | err_free_icm: | 593 | err_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 */ | ||
874 | enum { | ||
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 | |||
884 | static 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 | |||
872 | static int __devinit mthca_init_one(struct pci_dev *pdev, | 895 | static 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) | |||
659 | static ssize_t show_hca(struct class_device *cdev, char *buf) | 659 | static 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, |