diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-09-01 18:02:27 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-09-01 18:02:27 -0400 |
commit | ceeec3dc375e3b0618f16b34efc56fe093918f8b (patch) | |
tree | 2293d02721ee05131aaf1c60e4fba7e281585eec /drivers/infiniband/hw/mthca/mthca_main.c | |
parent | fbff868db3a4cc6a89d51da9a6d49b26c29d04fb (diff) | |
parent | e3ee3b78f83688a0ae4315e8be71b2eac559904a (diff) |
/spare/repo/netdev-2.6 branch 'ieee80211'
Diffstat (limited to 'drivers/infiniband/hw/mthca/mthca_main.c')
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_main.c | 179 |
1 files changed, 106 insertions, 73 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c index 2ef916859e17..3241d6c9dc11 100644 --- a/drivers/infiniband/hw/mthca/mthca_main.c +++ b/drivers/infiniband/hw/mthca/mthca_main.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. | 2 | * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. |
3 | * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. | 3 | * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. |
4 | * Copyright (c) 2005 Mellanox Technologies. All rights reserved. | ||
4 | * | 5 | * |
5 | * This software is available to you under a choice of one of two | 6 | * This software is available to you under a choice of one of two |
6 | * licenses. You may choose to be licensed under the terms of the GNU | 7 | * licenses. You may choose to be licensed under the terms of the GNU |
@@ -34,7 +35,6 @@ | |||
34 | */ | 35 | */ |
35 | 36 | ||
36 | #include <linux/config.h> | 37 | #include <linux/config.h> |
37 | #include <linux/version.h> | ||
38 | #include <linux/module.h> | 38 | #include <linux/module.h> |
39 | #include <linux/init.h> | 39 | #include <linux/init.h> |
40 | #include <linux/errno.h> | 40 | #include <linux/errno.h> |
@@ -171,6 +171,7 @@ static int __devinit mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim | |||
171 | mdev->limits.reserved_mrws = dev_lim->reserved_mrws; | 171 | mdev->limits.reserved_mrws = dev_lim->reserved_mrws; |
172 | mdev->limits.reserved_uars = dev_lim->reserved_uars; | 172 | mdev->limits.reserved_uars = dev_lim->reserved_uars; |
173 | mdev->limits.reserved_pds = dev_lim->reserved_pds; | 173 | mdev->limits.reserved_pds = dev_lim->reserved_pds; |
174 | mdev->limits.port_width_cap = dev_lim->max_port_width; | ||
174 | 175 | ||
175 | /* IB_DEVICE_RESIZE_MAX_WR not supported by driver. | 176 | /* IB_DEVICE_RESIZE_MAX_WR not supported by driver. |
176 | May be doable since hardware supports it for SRQ. | 177 | May be doable since hardware supports it for SRQ. |
@@ -212,7 +213,6 @@ static int __devinit mthca_init_tavor(struct mthca_dev *mdev) | |||
212 | struct mthca_dev_lim dev_lim; | 213 | struct mthca_dev_lim dev_lim; |
213 | struct mthca_profile profile; | 214 | struct mthca_profile profile; |
214 | struct mthca_init_hca_param init_hca; | 215 | struct mthca_init_hca_param init_hca; |
215 | struct mthca_adapter adapter; | ||
216 | 216 | ||
217 | err = mthca_SYS_EN(mdev, &status); | 217 | err = mthca_SYS_EN(mdev, &status); |
218 | if (err) { | 218 | if (err) { |
@@ -253,6 +253,8 @@ static int __devinit mthca_init_tavor(struct mthca_dev *mdev) | |||
253 | profile = default_profile; | 253 | profile = default_profile; |
254 | profile.num_uar = dev_lim.uar_size / PAGE_SIZE; | 254 | profile.num_uar = dev_lim.uar_size / PAGE_SIZE; |
255 | profile.uarc_size = 0; | 255 | profile.uarc_size = 0; |
256 | if (mdev->mthca_flags & MTHCA_FLAG_SRQ) | ||
257 | profile.num_srq = dev_lim.max_srqs; | ||
256 | 258 | ||
257 | err = mthca_make_profile(mdev, &profile, &dev_lim, &init_hca); | 259 | err = mthca_make_profile(mdev, &profile, &dev_lim, &init_hca); |
258 | if (err < 0) | 260 | if (err < 0) |
@@ -270,26 +272,8 @@ static int __devinit mthca_init_tavor(struct mthca_dev *mdev) | |||
270 | goto err_disable; | 272 | goto err_disable; |
271 | } | 273 | } |
272 | 274 | ||
273 | err = mthca_QUERY_ADAPTER(mdev, &adapter, &status); | ||
274 | if (err) { | ||
275 | mthca_err(mdev, "QUERY_ADAPTER command failed, aborting.\n"); | ||
276 | goto err_close; | ||
277 | } | ||
278 | if (status) { | ||
279 | mthca_err(mdev, "QUERY_ADAPTER returned status 0x%02x, " | ||
280 | "aborting.\n", status); | ||
281 | err = -EINVAL; | ||
282 | goto err_close; | ||
283 | } | ||
284 | |||
285 | mdev->eq_table.inta_pin = adapter.inta_pin; | ||
286 | mdev->rev_id = adapter.revision_id; | ||
287 | |||
288 | return 0; | 275 | return 0; |
289 | 276 | ||
290 | err_close: | ||
291 | mthca_CLOSE_HCA(mdev, 0, &status); | ||
292 | |||
293 | err_disable: | 277 | err_disable: |
294 | mthca_SYS_DIS(mdev, &status); | 278 | mthca_SYS_DIS(mdev, &status); |
295 | 279 | ||
@@ -442,15 +426,29 @@ static int __devinit mthca_init_icm(struct mthca_dev *mdev, | |||
442 | } | 426 | } |
443 | 427 | ||
444 | mdev->cq_table.table = mthca_alloc_icm_table(mdev, init_hca->cqc_base, | 428 | mdev->cq_table.table = mthca_alloc_icm_table(mdev, init_hca->cqc_base, |
445 | dev_lim->cqc_entry_sz, | 429 | dev_lim->cqc_entry_sz, |
446 | mdev->limits.num_cqs, | 430 | mdev->limits.num_cqs, |
447 | mdev->limits.reserved_cqs, 0); | 431 | mdev->limits.reserved_cqs, 0); |
448 | if (!mdev->cq_table.table) { | 432 | if (!mdev->cq_table.table) { |
449 | mthca_err(mdev, "Failed to map CQ context memory, aborting.\n"); | 433 | mthca_err(mdev, "Failed to map CQ context memory, aborting.\n"); |
450 | err = -ENOMEM; | 434 | err = -ENOMEM; |
451 | goto err_unmap_rdb; | 435 | goto err_unmap_rdb; |
452 | } | 436 | } |
453 | 437 | ||
438 | if (mdev->mthca_flags & MTHCA_FLAG_SRQ) { | ||
439 | mdev->srq_table.table = | ||
440 | mthca_alloc_icm_table(mdev, init_hca->srqc_base, | ||
441 | dev_lim->srq_entry_sz, | ||
442 | mdev->limits.num_srqs, | ||
443 | mdev->limits.reserved_srqs, 0); | ||
444 | if (!mdev->srq_table.table) { | ||
445 | mthca_err(mdev, "Failed to map SRQ context memory, " | ||
446 | "aborting.\n"); | ||
447 | err = -ENOMEM; | ||
448 | goto err_unmap_cq; | ||
449 | } | ||
450 | } | ||
451 | |||
454 | /* | 452 | /* |
455 | * It's not strictly required, but for simplicity just map the | 453 | * It's not strictly required, but for simplicity just map the |
456 | * whole multicast group table now. The table isn't very big | 454 | * whole multicast group table now. The table isn't very big |
@@ -466,11 +464,15 @@ static int __devinit mthca_init_icm(struct mthca_dev *mdev, | |||
466 | if (!mdev->mcg_table.table) { | 464 | if (!mdev->mcg_table.table) { |
467 | mthca_err(mdev, "Failed to map MCG context memory, aborting.\n"); | 465 | mthca_err(mdev, "Failed to map MCG context memory, aborting.\n"); |
468 | err = -ENOMEM; | 466 | err = -ENOMEM; |
469 | goto err_unmap_cq; | 467 | goto err_unmap_srq; |
470 | } | 468 | } |
471 | 469 | ||
472 | return 0; | 470 | return 0; |
473 | 471 | ||
472 | err_unmap_srq: | ||
473 | if (mdev->mthca_flags & MTHCA_FLAG_SRQ) | ||
474 | mthca_free_icm_table(mdev, mdev->srq_table.table); | ||
475 | |||
474 | err_unmap_cq: | 476 | err_unmap_cq: |
475 | mthca_free_icm_table(mdev, mdev->cq_table.table); | 477 | mthca_free_icm_table(mdev, mdev->cq_table.table); |
476 | 478 | ||
@@ -506,7 +508,6 @@ static int __devinit mthca_init_arbel(struct mthca_dev *mdev) | |||
506 | struct mthca_dev_lim dev_lim; | 508 | struct mthca_dev_lim dev_lim; |
507 | struct mthca_profile profile; | 509 | struct mthca_profile profile; |
508 | struct mthca_init_hca_param init_hca; | 510 | struct mthca_init_hca_param init_hca; |
509 | struct mthca_adapter adapter; | ||
510 | u64 icm_size; | 511 | u64 icm_size; |
511 | u8 status; | 512 | u8 status; |
512 | int err; | 513 | int err; |
@@ -551,6 +552,8 @@ static int __devinit mthca_init_arbel(struct mthca_dev *mdev) | |||
551 | profile = default_profile; | 552 | profile = default_profile; |
552 | profile.num_uar = dev_lim.uar_size / PAGE_SIZE; | 553 | profile.num_uar = dev_lim.uar_size / PAGE_SIZE; |
553 | profile.num_udav = 0; | 554 | profile.num_udav = 0; |
555 | if (mdev->mthca_flags & MTHCA_FLAG_SRQ) | ||
556 | profile.num_srq = dev_lim.max_srqs; | ||
554 | 557 | ||
555 | icm_size = mthca_make_profile(mdev, &profile, &dev_lim, &init_hca); | 558 | icm_size = mthca_make_profile(mdev, &profile, &dev_lim, &init_hca); |
556 | if ((int) icm_size < 0) { | 559 | if ((int) icm_size < 0) { |
@@ -574,24 +577,11 @@ static int __devinit mthca_init_arbel(struct mthca_dev *mdev) | |||
574 | goto err_free_icm; | 577 | goto err_free_icm; |
575 | } | 578 | } |
576 | 579 | ||
577 | err = mthca_QUERY_ADAPTER(mdev, &adapter, &status); | ||
578 | if (err) { | ||
579 | mthca_err(mdev, "QUERY_ADAPTER command failed, aborting.\n"); | ||
580 | goto err_free_icm; | ||
581 | } | ||
582 | if (status) { | ||
583 | mthca_err(mdev, "QUERY_ADAPTER returned status 0x%02x, " | ||
584 | "aborting.\n", status); | ||
585 | err = -EINVAL; | ||
586 | goto err_free_icm; | ||
587 | } | ||
588 | |||
589 | mdev->eq_table.inta_pin = adapter.inta_pin; | ||
590 | mdev->rev_id = adapter.revision_id; | ||
591 | |||
592 | return 0; | 580 | return 0; |
593 | 581 | ||
594 | err_free_icm: | 582 | err_free_icm: |
583 | if (mdev->mthca_flags & MTHCA_FLAG_SRQ) | ||
584 | mthca_free_icm_table(mdev, mdev->srq_table.table); | ||
595 | mthca_free_icm_table(mdev, mdev->cq_table.table); | 585 | mthca_free_icm_table(mdev, mdev->cq_table.table); |
596 | mthca_free_icm_table(mdev, mdev->qp_table.rdb_table); | 586 | mthca_free_icm_table(mdev, mdev->qp_table.rdb_table); |
597 | mthca_free_icm_table(mdev, mdev->qp_table.eqp_table); | 587 | mthca_free_icm_table(mdev, mdev->qp_table.eqp_table); |
@@ -614,12 +604,70 @@ err_disable: | |||
614 | return err; | 604 | return err; |
615 | } | 605 | } |
616 | 606 | ||
607 | static void mthca_close_hca(struct mthca_dev *mdev) | ||
608 | { | ||
609 | u8 status; | ||
610 | |||
611 | mthca_CLOSE_HCA(mdev, 0, &status); | ||
612 | |||
613 | if (mthca_is_memfree(mdev)) { | ||
614 | if (mdev->mthca_flags & MTHCA_FLAG_SRQ) | ||
615 | mthca_free_icm_table(mdev, mdev->srq_table.table); | ||
616 | mthca_free_icm_table(mdev, mdev->cq_table.table); | ||
617 | mthca_free_icm_table(mdev, mdev->qp_table.rdb_table); | ||
618 | mthca_free_icm_table(mdev, mdev->qp_table.eqp_table); | ||
619 | mthca_free_icm_table(mdev, mdev->qp_table.qp_table); | ||
620 | mthca_free_icm_table(mdev, mdev->mr_table.mpt_table); | ||
621 | mthca_free_icm_table(mdev, mdev->mr_table.mtt_table); | ||
622 | mthca_unmap_eq_icm(mdev); | ||
623 | |||
624 | mthca_UNMAP_ICM_AUX(mdev, &status); | ||
625 | mthca_free_icm(mdev, mdev->fw.arbel.aux_icm); | ||
626 | |||
627 | mthca_UNMAP_FA(mdev, &status); | ||
628 | mthca_free_icm(mdev, mdev->fw.arbel.fw_icm); | ||
629 | |||
630 | if (!(mdev->mthca_flags & MTHCA_FLAG_NO_LAM)) | ||
631 | mthca_DISABLE_LAM(mdev, &status); | ||
632 | } else | ||
633 | mthca_SYS_DIS(mdev, &status); | ||
634 | } | ||
635 | |||
617 | static int __devinit mthca_init_hca(struct mthca_dev *mdev) | 636 | static int __devinit mthca_init_hca(struct mthca_dev *mdev) |
618 | { | 637 | { |
638 | u8 status; | ||
639 | int err; | ||
640 | struct mthca_adapter adapter; | ||
641 | |||
619 | if (mthca_is_memfree(mdev)) | 642 | if (mthca_is_memfree(mdev)) |
620 | return mthca_init_arbel(mdev); | 643 | err = mthca_init_arbel(mdev); |
621 | else | 644 | else |
622 | return mthca_init_tavor(mdev); | 645 | err = mthca_init_tavor(mdev); |
646 | |||
647 | if (err) | ||
648 | return err; | ||
649 | |||
650 | err = mthca_QUERY_ADAPTER(mdev, &adapter, &status); | ||
651 | if (err) { | ||
652 | mthca_err(mdev, "QUERY_ADAPTER command failed, aborting.\n"); | ||
653 | goto err_close; | ||
654 | } | ||
655 | if (status) { | ||
656 | mthca_err(mdev, "QUERY_ADAPTER returned status 0x%02x, " | ||
657 | "aborting.\n", status); | ||
658 | err = -EINVAL; | ||
659 | goto err_close; | ||
660 | } | ||
661 | |||
662 | mdev->eq_table.inta_pin = adapter.inta_pin; | ||
663 | mdev->rev_id = adapter.revision_id; | ||
664 | memcpy(mdev->board_id, adapter.board_id, sizeof mdev->board_id); | ||
665 | |||
666 | return 0; | ||
667 | |||
668 | err_close: | ||
669 | mthca_close_hca(mdev); | ||
670 | return err; | ||
623 | } | 671 | } |
624 | 672 | ||
625 | static int __devinit mthca_setup_hca(struct mthca_dev *dev) | 673 | static int __devinit mthca_setup_hca(struct mthca_dev *dev) |
@@ -709,11 +757,18 @@ static int __devinit mthca_setup_hca(struct mthca_dev *dev) | |||
709 | goto err_cmd_poll; | 757 | goto err_cmd_poll; |
710 | } | 758 | } |
711 | 759 | ||
760 | err = mthca_init_srq_table(dev); | ||
761 | if (err) { | ||
762 | mthca_err(dev, "Failed to initialize " | ||
763 | "shared receive queue table, aborting.\n"); | ||
764 | goto err_cq_table_free; | ||
765 | } | ||
766 | |||
712 | err = mthca_init_qp_table(dev); | 767 | err = mthca_init_qp_table(dev); |
713 | if (err) { | 768 | if (err) { |
714 | mthca_err(dev, "Failed to initialize " | 769 | mthca_err(dev, "Failed to initialize " |
715 | "queue pair table, aborting.\n"); | 770 | "queue pair table, aborting.\n"); |
716 | goto err_cq_table_free; | 771 | goto err_srq_table_free; |
717 | } | 772 | } |
718 | 773 | ||
719 | err = mthca_init_av_table(dev); | 774 | err = mthca_init_av_table(dev); |
@@ -738,6 +793,9 @@ err_av_table_free: | |||
738 | err_qp_table_free: | 793 | err_qp_table_free: |
739 | mthca_cleanup_qp_table(dev); | 794 | mthca_cleanup_qp_table(dev); |
740 | 795 | ||
796 | err_srq_table_free: | ||
797 | mthca_cleanup_srq_table(dev); | ||
798 | |||
741 | err_cq_table_free: | 799 | err_cq_table_free: |
742 | mthca_cleanup_cq_table(dev); | 800 | mthca_cleanup_cq_table(dev); |
743 | 801 | ||
@@ -844,33 +902,6 @@ static int __devinit mthca_enable_msi_x(struct mthca_dev *mdev) | |||
844 | return 0; | 902 | return 0; |
845 | } | 903 | } |
846 | 904 | ||
847 | static void mthca_close_hca(struct mthca_dev *mdev) | ||
848 | { | ||
849 | u8 status; | ||
850 | |||
851 | mthca_CLOSE_HCA(mdev, 0, &status); | ||
852 | |||
853 | if (mthca_is_memfree(mdev)) { | ||
854 | mthca_free_icm_table(mdev, mdev->cq_table.table); | ||
855 | mthca_free_icm_table(mdev, mdev->qp_table.rdb_table); | ||
856 | mthca_free_icm_table(mdev, mdev->qp_table.eqp_table); | ||
857 | mthca_free_icm_table(mdev, mdev->qp_table.qp_table); | ||
858 | mthca_free_icm_table(mdev, mdev->mr_table.mpt_table); | ||
859 | mthca_free_icm_table(mdev, mdev->mr_table.mtt_table); | ||
860 | mthca_unmap_eq_icm(mdev); | ||
861 | |||
862 | mthca_UNMAP_ICM_AUX(mdev, &status); | ||
863 | mthca_free_icm(mdev, mdev->fw.arbel.aux_icm); | ||
864 | |||
865 | mthca_UNMAP_FA(mdev, &status); | ||
866 | mthca_free_icm(mdev, mdev->fw.arbel.fw_icm); | ||
867 | |||
868 | if (!(mdev->mthca_flags & MTHCA_FLAG_NO_LAM)) | ||
869 | mthca_DISABLE_LAM(mdev, &status); | ||
870 | } else | ||
871 | mthca_SYS_DIS(mdev, &status); | ||
872 | } | ||
873 | |||
874 | /* Types of supported HCA */ | 905 | /* Types of supported HCA */ |
875 | enum { | 906 | enum { |
876 | TAVOR, /* MT23108 */ | 907 | TAVOR, /* MT23108 */ |
@@ -887,9 +918,9 @@ static struct { | |||
887 | int is_memfree; | 918 | int is_memfree; |
888 | int is_pcie; | 919 | int is_pcie; |
889 | } mthca_hca_table[] = { | 920 | } mthca_hca_table[] = { |
890 | [TAVOR] = { .latest_fw = MTHCA_FW_VER(3, 3, 2), .is_memfree = 0, .is_pcie = 0 }, | 921 | [TAVOR] = { .latest_fw = MTHCA_FW_VER(3, 3, 3), .is_memfree = 0, .is_pcie = 0 }, |
891 | [ARBEL_COMPAT] = { .latest_fw = MTHCA_FW_VER(4, 6, 2), .is_memfree = 0, .is_pcie = 1 }, | 922 | [ARBEL_COMPAT] = { .latest_fw = MTHCA_FW_VER(4, 7, 0), .is_memfree = 0, .is_pcie = 1 }, |
892 | [ARBEL_NATIVE] = { .latest_fw = MTHCA_FW_VER(5, 0, 1), .is_memfree = 1, .is_pcie = 1 }, | 923 | [ARBEL_NATIVE] = { .latest_fw = MTHCA_FW_VER(5, 1, 0), .is_memfree = 1, .is_pcie = 1 }, |
893 | [SINAI] = { .latest_fw = MTHCA_FW_VER(1, 0, 1), .is_memfree = 1, .is_pcie = 1 } | 924 | [SINAI] = { .latest_fw = MTHCA_FW_VER(1, 0, 1), .is_memfree = 1, .is_pcie = 1 } |
894 | }; | 925 | }; |
895 | 926 | ||
@@ -1051,6 +1082,7 @@ err_cleanup: | |||
1051 | mthca_cleanup_mcg_table(mdev); | 1082 | mthca_cleanup_mcg_table(mdev); |
1052 | mthca_cleanup_av_table(mdev); | 1083 | mthca_cleanup_av_table(mdev); |
1053 | mthca_cleanup_qp_table(mdev); | 1084 | mthca_cleanup_qp_table(mdev); |
1085 | mthca_cleanup_srq_table(mdev); | ||
1054 | mthca_cleanup_cq_table(mdev); | 1086 | mthca_cleanup_cq_table(mdev); |
1055 | mthca_cmd_use_polling(mdev); | 1087 | mthca_cmd_use_polling(mdev); |
1056 | mthca_cleanup_eq_table(mdev); | 1088 | mthca_cleanup_eq_table(mdev); |
@@ -1100,6 +1132,7 @@ static void __devexit mthca_remove_one(struct pci_dev *pdev) | |||
1100 | mthca_cleanup_mcg_table(mdev); | 1132 | mthca_cleanup_mcg_table(mdev); |
1101 | mthca_cleanup_av_table(mdev); | 1133 | mthca_cleanup_av_table(mdev); |
1102 | mthca_cleanup_qp_table(mdev); | 1134 | mthca_cleanup_qp_table(mdev); |
1135 | mthca_cleanup_srq_table(mdev); | ||
1103 | mthca_cleanup_cq_table(mdev); | 1136 | mthca_cleanup_cq_table(mdev); |
1104 | mthca_cmd_use_polling(mdev); | 1137 | mthca_cmd_use_polling(mdev); |
1105 | mthca_cleanup_eq_table(mdev); | 1138 | mthca_cleanup_eq_table(mdev); |