diff options
| -rw-r--r-- | drivers/infiniband/hw/mthca/mthca_cmd.c | 32 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mthca/mthca_cmd.h | 9 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mthca/mthca_dev.h | 5 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mthca/mthca_main.c | 122 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mthca/mthca_provider.c | 10 |
5 files changed, 109 insertions, 69 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index 1e60487ecd7f..e15c1e2deab4 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c | |||
| @@ -1085,6 +1085,34 @@ out: | |||
| 1085 | return err; | 1085 | return err; |
| 1086 | } | 1086 | } |
| 1087 | 1087 | ||
| 1088 | static void get_board_id(void *vsd, char *board_id) | ||
| 1089 | { | ||
| 1090 | int i; | ||
| 1091 | |||
| 1092 | #define VSD_OFFSET_SIG1 0x00 | ||
| 1093 | #define VSD_OFFSET_SIG2 0xde | ||
| 1094 | #define VSD_OFFSET_MLX_BOARD_ID 0xd0 | ||
| 1095 | #define VSD_OFFSET_TS_BOARD_ID 0x20 | ||
| 1096 | |||
| 1097 | #define VSD_SIGNATURE_TOPSPIN 0x5ad | ||
| 1098 | |||
| 1099 | memset(board_id, 0, MTHCA_BOARD_ID_LEN); | ||
| 1100 | |||
| 1101 | if (be16_to_cpup(vsd + VSD_OFFSET_SIG1) == VSD_SIGNATURE_TOPSPIN && | ||
| 1102 | be16_to_cpup(vsd + VSD_OFFSET_SIG2) == VSD_SIGNATURE_TOPSPIN) { | ||
| 1103 | strlcpy(board_id, vsd + VSD_OFFSET_TS_BOARD_ID, MTHCA_BOARD_ID_LEN); | ||
| 1104 | } else { | ||
| 1105 | /* | ||
| 1106 | * The board ID is a string but the firmware byte | ||
| 1107 | * swaps each 4-byte word before passing it back to | ||
| 1108 | * us. Therefore we need to swab it before printing. | ||
| 1109 | */ | ||
| 1110 | for (i = 0; i < 4; ++i) | ||
| 1111 | ((u32 *) board_id)[i] = | ||
| 1112 | swab32(*(u32 *) (vsd + VSD_OFFSET_MLX_BOARD_ID + i * 4)); | ||
| 1113 | } | ||
| 1114 | } | ||
| 1115 | |||
| 1088 | int mthca_QUERY_ADAPTER(struct mthca_dev *dev, | 1116 | int mthca_QUERY_ADAPTER(struct mthca_dev *dev, |
| 1089 | struct mthca_adapter *adapter, u8 *status) | 1117 | struct mthca_adapter *adapter, u8 *status) |
| 1090 | { | 1118 | { |
| @@ -1097,6 +1125,7 @@ int mthca_QUERY_ADAPTER(struct mthca_dev *dev, | |||
| 1097 | #define QUERY_ADAPTER_DEVICE_ID_OFFSET 0x04 | 1125 | #define QUERY_ADAPTER_DEVICE_ID_OFFSET 0x04 |
| 1098 | #define QUERY_ADAPTER_REVISION_ID_OFFSET 0x08 | 1126 | #define QUERY_ADAPTER_REVISION_ID_OFFSET 0x08 |
| 1099 | #define QUERY_ADAPTER_INTA_PIN_OFFSET 0x10 | 1127 | #define QUERY_ADAPTER_INTA_PIN_OFFSET 0x10 |
| 1128 | #define QUERY_ADAPTER_VSD_OFFSET 0x20 | ||
| 1100 | 1129 | ||
| 1101 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); | 1130 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
| 1102 | if (IS_ERR(mailbox)) | 1131 | if (IS_ERR(mailbox)) |
| @@ -1114,6 +1143,9 @@ int mthca_QUERY_ADAPTER(struct mthca_dev *dev, | |||
| 1114 | MTHCA_GET(adapter->revision_id, outbox, QUERY_ADAPTER_REVISION_ID_OFFSET); | 1143 | MTHCA_GET(adapter->revision_id, outbox, QUERY_ADAPTER_REVISION_ID_OFFSET); |
| 1115 | MTHCA_GET(adapter->inta_pin, outbox, QUERY_ADAPTER_INTA_PIN_OFFSET); | 1144 | MTHCA_GET(adapter->inta_pin, outbox, QUERY_ADAPTER_INTA_PIN_OFFSET); |
| 1116 | 1145 | ||
| 1146 | get_board_id(outbox + QUERY_ADAPTER_VSD_OFFSET / 4, | ||
| 1147 | adapter->board_id); | ||
| 1148 | |||
| 1117 | out: | 1149 | out: |
| 1118 | mthca_free_mailbox(dev, mailbox); | 1150 | mthca_free_mailbox(dev, mailbox); |
| 1119 | return err; | 1151 | return err; |
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.h b/drivers/infiniband/hw/mthca/mthca_cmd.h index 75a629639445..4e0062778ff9 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.h +++ b/drivers/infiniband/hw/mthca/mthca_cmd.h | |||
| @@ -184,10 +184,11 @@ struct mthca_dev_lim { | |||
| 184 | }; | 184 | }; |
| 185 | 185 | ||
| 186 | struct mthca_adapter { | 186 | struct mthca_adapter { |
| 187 | u32 vendor_id; | 187 | u32 vendor_id; |
| 188 | u32 device_id; | 188 | u32 device_id; |
| 189 | u32 revision_id; | 189 | u32 revision_id; |
| 190 | u8 inta_pin; | 190 | char board_id[MTHCA_BOARD_ID_LEN]; |
| 191 | u8 inta_pin; | ||
| 191 | }; | 192 | }; |
| 192 | 193 | ||
| 193 | struct mthca_init_hca_param { | 194 | struct mthca_init_hca_param { |
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h index 3519ca4e086c..c8f67c034183 100644 --- a/drivers/infiniband/hw/mthca/mthca_dev.h +++ b/drivers/infiniband/hw/mthca/mthca_dev.h | |||
| @@ -69,6 +69,10 @@ enum { | |||
| 69 | }; | 69 | }; |
| 70 | 70 | ||
| 71 | enum { | 71 | enum { |
| 72 | MTHCA_BOARD_ID_LEN = 64 | ||
| 73 | }; | ||
| 74 | |||
| 75 | enum { | ||
| 72 | MTHCA_EQ_CONTEXT_SIZE = 0x40, | 76 | MTHCA_EQ_CONTEXT_SIZE = 0x40, |
| 73 | MTHCA_CQ_CONTEXT_SIZE = 0x40, | 77 | MTHCA_CQ_CONTEXT_SIZE = 0x40, |
| 74 | MTHCA_QP_CONTEXT_SIZE = 0x200, | 78 | MTHCA_QP_CONTEXT_SIZE = 0x200, |
| @@ -248,6 +252,7 @@ struct mthca_dev { | |||
| 248 | unsigned long device_cap_flags; | 252 | unsigned long device_cap_flags; |
| 249 | 253 | ||
| 250 | u32 rev_id; | 254 | u32 rev_id; |
| 255 | char board_id[MTHCA_BOARD_ID_LEN]; | ||
| 251 | 256 | ||
| 252 | /* firmware info */ | 257 | /* firmware info */ |
| 253 | u64 fw_ver; | 258 | u64 fw_ver; |
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c index 2d539403bdac..2f039680239c 100644 --- a/drivers/infiniband/hw/mthca/mthca_main.c +++ b/drivers/infiniband/hw/mthca/mthca_main.c | |||
| @@ -213,7 +213,6 @@ static int __devinit mthca_init_tavor(struct mthca_dev *mdev) | |||
| 213 | struct mthca_dev_lim dev_lim; | 213 | struct mthca_dev_lim dev_lim; |
| 214 | struct mthca_profile profile; | 214 | struct mthca_profile profile; |
| 215 | struct mthca_init_hca_param init_hca; | 215 | struct mthca_init_hca_param init_hca; |
| 216 | struct mthca_adapter adapter; | ||
| 217 | 216 | ||
| 218 | err = mthca_SYS_EN(mdev, &status); | 217 | err = mthca_SYS_EN(mdev, &status); |
| 219 | if (err) { | 218 | if (err) { |
| @@ -271,26 +270,8 @@ static int __devinit mthca_init_tavor(struct mthca_dev *mdev) | |||
| 271 | goto err_disable; | 270 | goto err_disable; |
| 272 | } | 271 | } |
| 273 | 272 | ||
| 274 | err = mthca_QUERY_ADAPTER(mdev, &adapter, &status); | ||
| 275 | if (err) { | ||
| 276 | mthca_err(mdev, "QUERY_ADAPTER command failed, aborting.\n"); | ||
| 277 | goto err_close; | ||
| 278 | } | ||
| 279 | if (status) { | ||
| 280 | mthca_err(mdev, "QUERY_ADAPTER returned status 0x%02x, " | ||
| 281 | "aborting.\n", status); | ||
| 282 | err = -EINVAL; | ||
| 283 | goto err_close; | ||
| 284 | } | ||
| 285 | |||
| 286 | mdev->eq_table.inta_pin = adapter.inta_pin; | ||
| 287 | mdev->rev_id = adapter.revision_id; | ||
| 288 | |||
| 289 | return 0; | 273 | return 0; |
| 290 | 274 | ||
| 291 | err_close: | ||
| 292 | mthca_CLOSE_HCA(mdev, 0, &status); | ||
| 293 | |||
| 294 | err_disable: | 275 | err_disable: |
| 295 | mthca_SYS_DIS(mdev, &status); | 276 | mthca_SYS_DIS(mdev, &status); |
| 296 | 277 | ||
| @@ -507,7 +488,6 @@ static int __devinit mthca_init_arbel(struct mthca_dev *mdev) | |||
| 507 | struct mthca_dev_lim dev_lim; | 488 | struct mthca_dev_lim dev_lim; |
| 508 | struct mthca_profile profile; | 489 | struct mthca_profile profile; |
| 509 | struct mthca_init_hca_param init_hca; | 490 | struct mthca_init_hca_param init_hca; |
| 510 | struct mthca_adapter adapter; | ||
| 511 | u64 icm_size; | 491 | u64 icm_size; |
| 512 | u8 status; | 492 | u8 status; |
| 513 | int err; | 493 | int err; |
| @@ -575,21 +555,6 @@ static int __devinit mthca_init_arbel(struct mthca_dev *mdev) | |||
| 575 | goto err_free_icm; | 555 | goto err_free_icm; |
| 576 | } | 556 | } |
| 577 | 557 | ||
| 578 | err = mthca_QUERY_ADAPTER(mdev, &adapter, &status); | ||
| 579 | if (err) { | ||
| 580 | mthca_err(mdev, "QUERY_ADAPTER command failed, aborting.\n"); | ||
| 581 | goto err_free_icm; | ||
| 582 | } | ||
| 583 | if (status) { | ||
| 584 | mthca_err(mdev, "QUERY_ADAPTER returned status 0x%02x, " | ||
| 585 | "aborting.\n", status); | ||
| 586 | err = -EINVAL; | ||
| 587 | goto err_free_icm; | ||
| 588 | } | ||
| 589 | |||
| 590 | mdev->eq_table.inta_pin = adapter.inta_pin; | ||
| 591 | mdev->rev_id = adapter.revision_id; | ||
| 592 | |||
| 593 | return 0; | 558 | return 0; |
| 594 | 559 | ||
| 595 | err_free_icm: | 560 | err_free_icm: |
| @@ -615,12 +580,68 @@ err_disable: | |||
| 615 | return err; | 580 | return err; |
| 616 | } | 581 | } |
| 617 | 582 | ||
| 583 | static void mthca_close_hca(struct mthca_dev *mdev) | ||
| 584 | { | ||
| 585 | u8 status; | ||
| 586 | |||
| 587 | mthca_CLOSE_HCA(mdev, 0, &status); | ||
| 588 | |||
| 589 | if (mthca_is_memfree(mdev)) { | ||
| 590 | mthca_free_icm_table(mdev, mdev->cq_table.table); | ||
| 591 | mthca_free_icm_table(mdev, mdev->qp_table.rdb_table); | ||
| 592 | mthca_free_icm_table(mdev, mdev->qp_table.eqp_table); | ||
| 593 | mthca_free_icm_table(mdev, mdev->qp_table.qp_table); | ||
| 594 | mthca_free_icm_table(mdev, mdev->mr_table.mpt_table); | ||
| 595 | mthca_free_icm_table(mdev, mdev->mr_table.mtt_table); | ||
| 596 | mthca_unmap_eq_icm(mdev); | ||
| 597 | |||
| 598 | mthca_UNMAP_ICM_AUX(mdev, &status); | ||
| 599 | mthca_free_icm(mdev, mdev->fw.arbel.aux_icm); | ||
| 600 | |||
| 601 | mthca_UNMAP_FA(mdev, &status); | ||
| 602 | mthca_free_icm(mdev, mdev->fw.arbel.fw_icm); | ||
| 603 | |||
| 604 | if (!(mdev->mthca_flags & MTHCA_FLAG_NO_LAM)) | ||
| 605 | mthca_DISABLE_LAM(mdev, &status); | ||
| 606 | } else | ||
| 607 | mthca_SYS_DIS(mdev, &status); | ||
| 608 | } | ||
| 609 | |||
| 618 | static int __devinit mthca_init_hca(struct mthca_dev *mdev) | 610 | static int __devinit mthca_init_hca(struct mthca_dev *mdev) |
| 619 | { | 611 | { |
| 612 | u8 status; | ||
| 613 | int err; | ||
| 614 | struct mthca_adapter adapter; | ||
| 615 | |||
| 620 | if (mthca_is_memfree(mdev)) | 616 | if (mthca_is_memfree(mdev)) |
| 621 | return mthca_init_arbel(mdev); | 617 | err = mthca_init_arbel(mdev); |
| 622 | else | 618 | else |
| 623 | return mthca_init_tavor(mdev); | 619 | err = mthca_init_tavor(mdev); |
| 620 | |||
| 621 | if (err) | ||
| 622 | return err; | ||
| 623 | |||
| 624 | err = mthca_QUERY_ADAPTER(mdev, &adapter, &status); | ||
| 625 | if (err) { | ||
| 626 | mthca_err(mdev, "QUERY_ADAPTER command failed, aborting.\n"); | ||
| 627 | goto err_close; | ||
| 628 | } | ||
| 629 | if (status) { | ||
| 630 | mthca_err(mdev, "QUERY_ADAPTER returned status 0x%02x, " | ||
| 631 | "aborting.\n", status); | ||
| 632 | err = -EINVAL; | ||
| 633 | goto err_close; | ||
| 634 | } | ||
| 635 | |||
| 636 | mdev->eq_table.inta_pin = adapter.inta_pin; | ||
| 637 | mdev->rev_id = adapter.revision_id; | ||
| 638 | memcpy(mdev->board_id, adapter.board_id, sizeof mdev->board_id); | ||
| 639 | |||
| 640 | return 0; | ||
| 641 | |||
| 642 | err_close: | ||
| 643 | mthca_close_hca(mdev); | ||
| 644 | return err; | ||
| 624 | } | 645 | } |
| 625 | 646 | ||
| 626 | static int __devinit mthca_setup_hca(struct mthca_dev *dev) | 647 | static int __devinit mthca_setup_hca(struct mthca_dev *dev) |
| @@ -845,33 +866,6 @@ static int __devinit mthca_enable_msi_x(struct mthca_dev *mdev) | |||
| 845 | return 0; | 866 | return 0; |
| 846 | } | 867 | } |
| 847 | 868 | ||
| 848 | static void mthca_close_hca(struct mthca_dev *mdev) | ||
| 849 | { | ||
| 850 | u8 status; | ||
| 851 | |||
| 852 | mthca_CLOSE_HCA(mdev, 0, &status); | ||
| 853 | |||
| 854 | if (mthca_is_memfree(mdev)) { | ||
| 855 | mthca_free_icm_table(mdev, mdev->cq_table.table); | ||
| 856 | mthca_free_icm_table(mdev, mdev->qp_table.rdb_table); | ||
| 857 | mthca_free_icm_table(mdev, mdev->qp_table.eqp_table); | ||
| 858 | mthca_free_icm_table(mdev, mdev->qp_table.qp_table); | ||
| 859 | mthca_free_icm_table(mdev, mdev->mr_table.mpt_table); | ||
| 860 | mthca_free_icm_table(mdev, mdev->mr_table.mtt_table); | ||
| 861 | mthca_unmap_eq_icm(mdev); | ||
| 862 | |||
| 863 | mthca_UNMAP_ICM_AUX(mdev, &status); | ||
| 864 | mthca_free_icm(mdev, mdev->fw.arbel.aux_icm); | ||
| 865 | |||
| 866 | mthca_UNMAP_FA(mdev, &status); | ||
| 867 | mthca_free_icm(mdev, mdev->fw.arbel.fw_icm); | ||
| 868 | |||
| 869 | if (!(mdev->mthca_flags & MTHCA_FLAG_NO_LAM)) | ||
| 870 | mthca_DISABLE_LAM(mdev, &status); | ||
| 871 | } else | ||
| 872 | mthca_SYS_DIS(mdev, &status); | ||
| 873 | } | ||
| 874 | |||
| 875 | /* Types of supported HCA */ | 869 | /* Types of supported HCA */ |
| 876 | enum { | 870 | enum { |
| 877 | TAVOR, /* MT23108 */ | 871 | TAVOR, /* MT23108 */ |
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index e2db5e001869..f5e135f1dc59 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c | |||
| @@ -958,14 +958,22 @@ static ssize_t show_hca(struct class_device *cdev, char *buf) | |||
| 958 | } | 958 | } |
| 959 | } | 959 | } |
| 960 | 960 | ||
| 961 | static ssize_t show_board(struct class_device *cdev, char *buf) | ||
| 962 | { | ||
| 963 | struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev); | ||
| 964 | return sprintf(buf, "%.*s\n", MTHCA_BOARD_ID_LEN, dev->board_id); | ||
| 965 | } | ||
| 966 | |||
| 961 | static CLASS_DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL); | 967 | static CLASS_DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL); |
| 962 | static CLASS_DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL); | 968 | static CLASS_DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL); |
| 963 | static CLASS_DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL); | 969 | static CLASS_DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL); |
| 970 | static CLASS_DEVICE_ATTR(board_id, S_IRUGO, show_board, NULL); | ||
| 964 | 971 | ||
| 965 | static struct class_device_attribute *mthca_class_attributes[] = { | 972 | static struct class_device_attribute *mthca_class_attributes[] = { |
| 966 | &class_device_attr_hw_rev, | 973 | &class_device_attr_hw_rev, |
| 967 | &class_device_attr_fw_ver, | 974 | &class_device_attr_fw_ver, |
| 968 | &class_device_attr_hca_type | 975 | &class_device_attr_hca_type, |
| 976 | &class_device_attr_board_id | ||
| 969 | }; | 977 | }; |
| 970 | 978 | ||
| 971 | int mthca_register_device(struct mthca_dev *dev) | 979 | int mthca_register_device(struct mthca_dev *dev) |
