aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cmd.c32
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cmd.h9
-rw-r--r--drivers/infiniband/hw/mthca/mthca_dev.h5
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c122
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c10
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
1088static 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
1088int mthca_QUERY_ADAPTER(struct mthca_dev *dev, 1116int 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
1117out: 1149out:
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
186struct mthca_adapter { 186struct 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
193struct mthca_init_hca_param { 194struct 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
71enum { 71enum {
72 MTHCA_BOARD_ID_LEN = 64
73};
74
75enum {
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
291err_close:
292 mthca_CLOSE_HCA(mdev, 0, &status);
293
294err_disable: 275err_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
595err_free_icm: 560err_free_icm:
@@ -615,12 +580,68 @@ err_disable:
615 return err; 580 return err;
616} 581}
617 582
583static 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
618static int __devinit mthca_init_hca(struct mthca_dev *mdev) 610static 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
642err_close:
643 mthca_close_hca(mdev);
644 return err;
624} 645}
625 646
626static int __devinit mthca_setup_hca(struct mthca_dev *dev) 647static 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
848static 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 */
876enum { 870enum {
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
961static 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
961static CLASS_DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL); 967static CLASS_DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
962static CLASS_DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL); 968static CLASS_DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);
963static CLASS_DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL); 969static CLASS_DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL);
970static CLASS_DEVICE_ATTR(board_id, S_IRUGO, show_board, NULL);
964 971
965static struct class_device_attribute *mthca_class_attributes[] = { 972static 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
971int mthca_register_device(struct mthca_dev *dev) 979int mthca_register_device(struct mthca_dev *dev)