diff options
Diffstat (limited to 'drivers/infiniband/hw/qib/qib_iba7322.c')
-rw-r--r-- | drivers/infiniband/hw/qib/qib_iba7322.c | 393 |
1 files changed, 359 insertions, 34 deletions
diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c index 3f6b21e9dc11..f7c4b44b1f93 100644 --- a/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/drivers/infiniband/hw/qib/qib_iba7322.c | |||
@@ -44,6 +44,9 @@ | |||
44 | #include <linux/module.h> | 44 | #include <linux/module.h> |
45 | #include <rdma/ib_verbs.h> | 45 | #include <rdma/ib_verbs.h> |
46 | #include <rdma/ib_smi.h> | 46 | #include <rdma/ib_smi.h> |
47 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
48 | #include <linux/dca.h> | ||
49 | #endif | ||
47 | 50 | ||
48 | #include "qib.h" | 51 | #include "qib.h" |
49 | #include "qib_7322_regs.h" | 52 | #include "qib_7322_regs.h" |
@@ -519,6 +522,14 @@ static const u8 qib_7322_physportstate[0x20] = { | |||
519 | [0x17] = IB_PHYSPORTSTATE_CFG_TRAIN | 522 | [0x17] = IB_PHYSPORTSTATE_CFG_TRAIN |
520 | }; | 523 | }; |
521 | 524 | ||
525 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
526 | struct qib_irq_notify { | ||
527 | int rcv; | ||
528 | void *arg; | ||
529 | struct irq_affinity_notify notify; | ||
530 | }; | ||
531 | #endif | ||
532 | |||
522 | struct qib_chip_specific { | 533 | struct qib_chip_specific { |
523 | u64 __iomem *cregbase; | 534 | u64 __iomem *cregbase; |
524 | u64 *cntrs; | 535 | u64 *cntrs; |
@@ -546,6 +557,12 @@ struct qib_chip_specific { | |||
546 | u32 lastbuf_for_pio; | 557 | u32 lastbuf_for_pio; |
547 | u32 stay_in_freeze; | 558 | u32 stay_in_freeze; |
548 | u32 recovery_ports_initted; | 559 | u32 recovery_ports_initted; |
560 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
561 | u32 dca_ctrl; | ||
562 | int rhdr_cpu[18]; | ||
563 | int sdma_cpu[2]; | ||
564 | u64 dca_rcvhdr_ctrl[5]; /* B, C, D, E, F */ | ||
565 | #endif | ||
549 | struct qib_msix_entry *msix_entries; | 566 | struct qib_msix_entry *msix_entries; |
550 | unsigned long *sendchkenable; | 567 | unsigned long *sendchkenable; |
551 | unsigned long *sendgrhchk; | 568 | unsigned long *sendgrhchk; |
@@ -573,7 +590,7 @@ struct vendor_txdds_ent { | |||
573 | static void write_tx_serdes_param(struct qib_pportdata *, struct txdds_ent *); | 590 | static void write_tx_serdes_param(struct qib_pportdata *, struct txdds_ent *); |
574 | 591 | ||
575 | #define TXDDS_TABLE_SZ 16 /* number of entries per speed in onchip table */ | 592 | #define TXDDS_TABLE_SZ 16 /* number of entries per speed in onchip table */ |
576 | #define TXDDS_EXTRA_SZ 13 /* number of extra tx settings entries */ | 593 | #define TXDDS_EXTRA_SZ 18 /* number of extra tx settings entries */ |
577 | #define TXDDS_MFG_SZ 2 /* number of mfg tx settings entries */ | 594 | #define TXDDS_MFG_SZ 2 /* number of mfg tx settings entries */ |
578 | #define SERDES_CHANS 4 /* yes, it's obvious, but one less magic number */ | 595 | #define SERDES_CHANS 4 /* yes, it's obvious, but one less magic number */ |
579 | 596 | ||
@@ -642,28 +659,76 @@ static struct { | |||
642 | irq_handler_t handler; | 659 | irq_handler_t handler; |
643 | int lsb; | 660 | int lsb; |
644 | int port; /* 0 if not port-specific, else port # */ | 661 | int port; /* 0 if not port-specific, else port # */ |
662 | int dca; | ||
645 | } irq_table[] = { | 663 | } irq_table[] = { |
646 | { "", qib_7322intr, -1, 0 }, | 664 | { "", qib_7322intr, -1, 0, 0 }, |
647 | { " (buf avail)", qib_7322bufavail, | 665 | { " (buf avail)", qib_7322bufavail, |
648 | SYM_LSB(IntStatus, SendBufAvail), 0 }, | 666 | SYM_LSB(IntStatus, SendBufAvail), 0, 0}, |
649 | { " (sdma 0)", sdma_intr, | 667 | { " (sdma 0)", sdma_intr, |
650 | SYM_LSB(IntStatus, SDmaInt_0), 1 }, | 668 | SYM_LSB(IntStatus, SDmaInt_0), 1, 1 }, |
651 | { " (sdma 1)", sdma_intr, | 669 | { " (sdma 1)", sdma_intr, |
652 | SYM_LSB(IntStatus, SDmaInt_1), 2 }, | 670 | SYM_LSB(IntStatus, SDmaInt_1), 2, 1 }, |
653 | { " (sdmaI 0)", sdma_idle_intr, | 671 | { " (sdmaI 0)", sdma_idle_intr, |
654 | SYM_LSB(IntStatus, SDmaIdleInt_0), 1 }, | 672 | SYM_LSB(IntStatus, SDmaIdleInt_0), 1, 1}, |
655 | { " (sdmaI 1)", sdma_idle_intr, | 673 | { " (sdmaI 1)", sdma_idle_intr, |
656 | SYM_LSB(IntStatus, SDmaIdleInt_1), 2 }, | 674 | SYM_LSB(IntStatus, SDmaIdleInt_1), 2, 1}, |
657 | { " (sdmaP 0)", sdma_progress_intr, | 675 | { " (sdmaP 0)", sdma_progress_intr, |
658 | SYM_LSB(IntStatus, SDmaProgressInt_0), 1 }, | 676 | SYM_LSB(IntStatus, SDmaProgressInt_0), 1, 1 }, |
659 | { " (sdmaP 1)", sdma_progress_intr, | 677 | { " (sdmaP 1)", sdma_progress_intr, |
660 | SYM_LSB(IntStatus, SDmaProgressInt_1), 2 }, | 678 | SYM_LSB(IntStatus, SDmaProgressInt_1), 2, 1 }, |
661 | { " (sdmaC 0)", sdma_cleanup_intr, | 679 | { " (sdmaC 0)", sdma_cleanup_intr, |
662 | SYM_LSB(IntStatus, SDmaCleanupDone_0), 1 }, | 680 | SYM_LSB(IntStatus, SDmaCleanupDone_0), 1, 0 }, |
663 | { " (sdmaC 1)", sdma_cleanup_intr, | 681 | { " (sdmaC 1)", sdma_cleanup_intr, |
664 | SYM_LSB(IntStatus, SDmaCleanupDone_1), 2 }, | 682 | SYM_LSB(IntStatus, SDmaCleanupDone_1), 2 , 0}, |
665 | }; | 683 | }; |
666 | 684 | ||
685 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
686 | |||
687 | static const struct dca_reg_map { | ||
688 | int shadow_inx; | ||
689 | int lsb; | ||
690 | u64 mask; | ||
691 | u16 regno; | ||
692 | } dca_rcvhdr_reg_map[] = { | ||
693 | { 0, SYM_LSB(DCACtrlB, RcvHdrq0DCAOPH), | ||
694 | ~SYM_MASK(DCACtrlB, RcvHdrq0DCAOPH) , KREG_IDX(DCACtrlB) }, | ||
695 | { 0, SYM_LSB(DCACtrlB, RcvHdrq1DCAOPH), | ||
696 | ~SYM_MASK(DCACtrlB, RcvHdrq1DCAOPH) , KREG_IDX(DCACtrlB) }, | ||
697 | { 0, SYM_LSB(DCACtrlB, RcvHdrq2DCAOPH), | ||
698 | ~SYM_MASK(DCACtrlB, RcvHdrq2DCAOPH) , KREG_IDX(DCACtrlB) }, | ||
699 | { 0, SYM_LSB(DCACtrlB, RcvHdrq3DCAOPH), | ||
700 | ~SYM_MASK(DCACtrlB, RcvHdrq3DCAOPH) , KREG_IDX(DCACtrlB) }, | ||
701 | { 1, SYM_LSB(DCACtrlC, RcvHdrq4DCAOPH), | ||
702 | ~SYM_MASK(DCACtrlC, RcvHdrq4DCAOPH) , KREG_IDX(DCACtrlC) }, | ||
703 | { 1, SYM_LSB(DCACtrlC, RcvHdrq5DCAOPH), | ||
704 | ~SYM_MASK(DCACtrlC, RcvHdrq5DCAOPH) , KREG_IDX(DCACtrlC) }, | ||
705 | { 1, SYM_LSB(DCACtrlC, RcvHdrq6DCAOPH), | ||
706 | ~SYM_MASK(DCACtrlC, RcvHdrq6DCAOPH) , KREG_IDX(DCACtrlC) }, | ||
707 | { 1, SYM_LSB(DCACtrlC, RcvHdrq7DCAOPH), | ||
708 | ~SYM_MASK(DCACtrlC, RcvHdrq7DCAOPH) , KREG_IDX(DCACtrlC) }, | ||
709 | { 2, SYM_LSB(DCACtrlD, RcvHdrq8DCAOPH), | ||
710 | ~SYM_MASK(DCACtrlD, RcvHdrq8DCAOPH) , KREG_IDX(DCACtrlD) }, | ||
711 | { 2, SYM_LSB(DCACtrlD, RcvHdrq9DCAOPH), | ||
712 | ~SYM_MASK(DCACtrlD, RcvHdrq9DCAOPH) , KREG_IDX(DCACtrlD) }, | ||
713 | { 2, SYM_LSB(DCACtrlD, RcvHdrq10DCAOPH), | ||
714 | ~SYM_MASK(DCACtrlD, RcvHdrq10DCAOPH) , KREG_IDX(DCACtrlD) }, | ||
715 | { 2, SYM_LSB(DCACtrlD, RcvHdrq11DCAOPH), | ||
716 | ~SYM_MASK(DCACtrlD, RcvHdrq11DCAOPH) , KREG_IDX(DCACtrlD) }, | ||
717 | { 3, SYM_LSB(DCACtrlE, RcvHdrq12DCAOPH), | ||
718 | ~SYM_MASK(DCACtrlE, RcvHdrq12DCAOPH) , KREG_IDX(DCACtrlE) }, | ||
719 | { 3, SYM_LSB(DCACtrlE, RcvHdrq13DCAOPH), | ||
720 | ~SYM_MASK(DCACtrlE, RcvHdrq13DCAOPH) , KREG_IDX(DCACtrlE) }, | ||
721 | { 3, SYM_LSB(DCACtrlE, RcvHdrq14DCAOPH), | ||
722 | ~SYM_MASK(DCACtrlE, RcvHdrq14DCAOPH) , KREG_IDX(DCACtrlE) }, | ||
723 | { 3, SYM_LSB(DCACtrlE, RcvHdrq15DCAOPH), | ||
724 | ~SYM_MASK(DCACtrlE, RcvHdrq15DCAOPH) , KREG_IDX(DCACtrlE) }, | ||
725 | { 4, SYM_LSB(DCACtrlF, RcvHdrq16DCAOPH), | ||
726 | ~SYM_MASK(DCACtrlF, RcvHdrq16DCAOPH) , KREG_IDX(DCACtrlF) }, | ||
727 | { 4, SYM_LSB(DCACtrlF, RcvHdrq17DCAOPH), | ||
728 | ~SYM_MASK(DCACtrlF, RcvHdrq17DCAOPH) , KREG_IDX(DCACtrlF) }, | ||
729 | }; | ||
730 | #endif | ||
731 | |||
667 | /* ibcctrl bits */ | 732 | /* ibcctrl bits */ |
668 | #define QLOGIC_IB_IBCC_LINKINITCMD_DISABLE 1 | 733 | #define QLOGIC_IB_IBCC_LINKINITCMD_DISABLE 1 |
669 | /* cycle through TS1/TS2 till OK */ | 734 | /* cycle through TS1/TS2 till OK */ |
@@ -686,6 +751,13 @@ static void write_7322_init_portregs(struct qib_pportdata *); | |||
686 | static void setup_7322_link_recovery(struct qib_pportdata *, u32); | 751 | static void setup_7322_link_recovery(struct qib_pportdata *, u32); |
687 | static void check_7322_rxe_status(struct qib_pportdata *); | 752 | static void check_7322_rxe_status(struct qib_pportdata *); |
688 | static u32 __iomem *qib_7322_getsendbuf(struct qib_pportdata *, u64, u32 *); | 753 | static u32 __iomem *qib_7322_getsendbuf(struct qib_pportdata *, u64, u32 *); |
754 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
755 | static void qib_setup_dca(struct qib_devdata *dd); | ||
756 | static void setup_dca_notifier(struct qib_devdata *dd, | ||
757 | struct qib_msix_entry *m); | ||
758 | static void reset_dca_notifier(struct qib_devdata *dd, | ||
759 | struct qib_msix_entry *m); | ||
760 | #endif | ||
689 | 761 | ||
690 | /** | 762 | /** |
691 | * qib_read_ureg32 - read 32-bit virtualized per-context register | 763 | * qib_read_ureg32 - read 32-bit virtualized per-context register |
@@ -2558,6 +2630,162 @@ static void qib_setup_7322_setextled(struct qib_pportdata *ppd, u32 on) | |||
2558 | qib_write_kreg_port(ppd, krp_rcvpktledcnt, ledblink); | 2630 | qib_write_kreg_port(ppd, krp_rcvpktledcnt, ledblink); |
2559 | } | 2631 | } |
2560 | 2632 | ||
2633 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
2634 | |||
2635 | static int qib_7322_notify_dca(struct qib_devdata *dd, unsigned long event) | ||
2636 | { | ||
2637 | switch (event) { | ||
2638 | case DCA_PROVIDER_ADD: | ||
2639 | if (dd->flags & QIB_DCA_ENABLED) | ||
2640 | break; | ||
2641 | if (!dca_add_requester(&dd->pcidev->dev)) { | ||
2642 | qib_devinfo(dd->pcidev, "DCA enabled\n"); | ||
2643 | dd->flags |= QIB_DCA_ENABLED; | ||
2644 | qib_setup_dca(dd); | ||
2645 | } | ||
2646 | break; | ||
2647 | case DCA_PROVIDER_REMOVE: | ||
2648 | if (dd->flags & QIB_DCA_ENABLED) { | ||
2649 | dca_remove_requester(&dd->pcidev->dev); | ||
2650 | dd->flags &= ~QIB_DCA_ENABLED; | ||
2651 | dd->cspec->dca_ctrl = 0; | ||
2652 | qib_write_kreg(dd, KREG_IDX(DCACtrlA), | ||
2653 | dd->cspec->dca_ctrl); | ||
2654 | } | ||
2655 | break; | ||
2656 | } | ||
2657 | return 0; | ||
2658 | } | ||
2659 | |||
2660 | static void qib_update_rhdrq_dca(struct qib_ctxtdata *rcd, int cpu) | ||
2661 | { | ||
2662 | struct qib_devdata *dd = rcd->dd; | ||
2663 | struct qib_chip_specific *cspec = dd->cspec; | ||
2664 | |||
2665 | if (!(dd->flags & QIB_DCA_ENABLED)) | ||
2666 | return; | ||
2667 | if (cspec->rhdr_cpu[rcd->ctxt] != cpu) { | ||
2668 | const struct dca_reg_map *rmp; | ||
2669 | |||
2670 | cspec->rhdr_cpu[rcd->ctxt] = cpu; | ||
2671 | rmp = &dca_rcvhdr_reg_map[rcd->ctxt]; | ||
2672 | cspec->dca_rcvhdr_ctrl[rmp->shadow_inx] &= rmp->mask; | ||
2673 | cspec->dca_rcvhdr_ctrl[rmp->shadow_inx] |= | ||
2674 | (u64) dca3_get_tag(&dd->pcidev->dev, cpu) << rmp->lsb; | ||
2675 | qib_devinfo(dd->pcidev, | ||
2676 | "Ctxt %d cpu %d dca %llx\n", rcd->ctxt, cpu, | ||
2677 | (long long) cspec->dca_rcvhdr_ctrl[rmp->shadow_inx]); | ||
2678 | qib_write_kreg(dd, rmp->regno, | ||
2679 | cspec->dca_rcvhdr_ctrl[rmp->shadow_inx]); | ||
2680 | cspec->dca_ctrl |= SYM_MASK(DCACtrlA, RcvHdrqDCAEnable); | ||
2681 | qib_write_kreg(dd, KREG_IDX(DCACtrlA), cspec->dca_ctrl); | ||
2682 | } | ||
2683 | } | ||
2684 | |||
2685 | static void qib_update_sdma_dca(struct qib_pportdata *ppd, int cpu) | ||
2686 | { | ||
2687 | struct qib_devdata *dd = ppd->dd; | ||
2688 | struct qib_chip_specific *cspec = dd->cspec; | ||
2689 | unsigned pidx = ppd->port - 1; | ||
2690 | |||
2691 | if (!(dd->flags & QIB_DCA_ENABLED)) | ||
2692 | return; | ||
2693 | if (cspec->sdma_cpu[pidx] != cpu) { | ||
2694 | cspec->sdma_cpu[pidx] = cpu; | ||
2695 | cspec->dca_rcvhdr_ctrl[4] &= ~(ppd->hw_pidx ? | ||
2696 | SYM_MASK(DCACtrlF, SendDma1DCAOPH) : | ||
2697 | SYM_MASK(DCACtrlF, SendDma0DCAOPH)); | ||
2698 | cspec->dca_rcvhdr_ctrl[4] |= | ||
2699 | (u64) dca3_get_tag(&dd->pcidev->dev, cpu) << | ||
2700 | (ppd->hw_pidx ? | ||
2701 | SYM_LSB(DCACtrlF, SendDma1DCAOPH) : | ||
2702 | SYM_LSB(DCACtrlF, SendDma0DCAOPH)); | ||
2703 | qib_devinfo(dd->pcidev, | ||
2704 | "sdma %d cpu %d dca %llx\n", ppd->hw_pidx, cpu, | ||
2705 | (long long) cspec->dca_rcvhdr_ctrl[4]); | ||
2706 | qib_write_kreg(dd, KREG_IDX(DCACtrlF), | ||
2707 | cspec->dca_rcvhdr_ctrl[4]); | ||
2708 | cspec->dca_ctrl |= ppd->hw_pidx ? | ||
2709 | SYM_MASK(DCACtrlA, SendDMAHead1DCAEnable) : | ||
2710 | SYM_MASK(DCACtrlA, SendDMAHead0DCAEnable); | ||
2711 | qib_write_kreg(dd, KREG_IDX(DCACtrlA), cspec->dca_ctrl); | ||
2712 | } | ||
2713 | } | ||
2714 | |||
2715 | static void qib_setup_dca(struct qib_devdata *dd) | ||
2716 | { | ||
2717 | struct qib_chip_specific *cspec = dd->cspec; | ||
2718 | int i; | ||
2719 | |||
2720 | for (i = 0; i < ARRAY_SIZE(cspec->rhdr_cpu); i++) | ||
2721 | cspec->rhdr_cpu[i] = -1; | ||
2722 | for (i = 0; i < ARRAY_SIZE(cspec->sdma_cpu); i++) | ||
2723 | cspec->sdma_cpu[i] = -1; | ||
2724 | cspec->dca_rcvhdr_ctrl[0] = | ||
2725 | (1ULL << SYM_LSB(DCACtrlB, RcvHdrq0DCAXfrCnt)) | | ||
2726 | (1ULL << SYM_LSB(DCACtrlB, RcvHdrq1DCAXfrCnt)) | | ||
2727 | (1ULL << SYM_LSB(DCACtrlB, RcvHdrq2DCAXfrCnt)) | | ||
2728 | (1ULL << SYM_LSB(DCACtrlB, RcvHdrq3DCAXfrCnt)); | ||
2729 | cspec->dca_rcvhdr_ctrl[1] = | ||
2730 | (1ULL << SYM_LSB(DCACtrlC, RcvHdrq4DCAXfrCnt)) | | ||
2731 | (1ULL << SYM_LSB(DCACtrlC, RcvHdrq5DCAXfrCnt)) | | ||
2732 | (1ULL << SYM_LSB(DCACtrlC, RcvHdrq6DCAXfrCnt)) | | ||
2733 | (1ULL << SYM_LSB(DCACtrlC, RcvHdrq7DCAXfrCnt)); | ||
2734 | cspec->dca_rcvhdr_ctrl[2] = | ||
2735 | (1ULL << SYM_LSB(DCACtrlD, RcvHdrq8DCAXfrCnt)) | | ||
2736 | (1ULL << SYM_LSB(DCACtrlD, RcvHdrq9DCAXfrCnt)) | | ||
2737 | (1ULL << SYM_LSB(DCACtrlD, RcvHdrq10DCAXfrCnt)) | | ||
2738 | (1ULL << SYM_LSB(DCACtrlD, RcvHdrq11DCAXfrCnt)); | ||
2739 | cspec->dca_rcvhdr_ctrl[3] = | ||
2740 | (1ULL << SYM_LSB(DCACtrlE, RcvHdrq12DCAXfrCnt)) | | ||
2741 | (1ULL << SYM_LSB(DCACtrlE, RcvHdrq13DCAXfrCnt)) | | ||
2742 | (1ULL << SYM_LSB(DCACtrlE, RcvHdrq14DCAXfrCnt)) | | ||
2743 | (1ULL << SYM_LSB(DCACtrlE, RcvHdrq15DCAXfrCnt)); | ||
2744 | cspec->dca_rcvhdr_ctrl[4] = | ||
2745 | (1ULL << SYM_LSB(DCACtrlF, RcvHdrq16DCAXfrCnt)) | | ||
2746 | (1ULL << SYM_LSB(DCACtrlF, RcvHdrq17DCAXfrCnt)); | ||
2747 | for (i = 0; i < ARRAY_SIZE(cspec->sdma_cpu); i++) | ||
2748 | qib_write_kreg(dd, KREG_IDX(DCACtrlB) + i, | ||
2749 | cspec->dca_rcvhdr_ctrl[i]); | ||
2750 | for (i = 0; i < cspec->num_msix_entries; i++) | ||
2751 | setup_dca_notifier(dd, &cspec->msix_entries[i]); | ||
2752 | } | ||
2753 | |||
2754 | static void qib_irq_notifier_notify(struct irq_affinity_notify *notify, | ||
2755 | const cpumask_t *mask) | ||
2756 | { | ||
2757 | struct qib_irq_notify *n = | ||
2758 | container_of(notify, struct qib_irq_notify, notify); | ||
2759 | int cpu = cpumask_first(mask); | ||
2760 | |||
2761 | if (n->rcv) { | ||
2762 | struct qib_ctxtdata *rcd = (struct qib_ctxtdata *)n->arg; | ||
2763 | qib_update_rhdrq_dca(rcd, cpu); | ||
2764 | } else { | ||
2765 | struct qib_pportdata *ppd = (struct qib_pportdata *)n->arg; | ||
2766 | qib_update_sdma_dca(ppd, cpu); | ||
2767 | } | ||
2768 | } | ||
2769 | |||
2770 | static void qib_irq_notifier_release(struct kref *ref) | ||
2771 | { | ||
2772 | struct qib_irq_notify *n = | ||
2773 | container_of(ref, struct qib_irq_notify, notify.kref); | ||
2774 | struct qib_devdata *dd; | ||
2775 | |||
2776 | if (n->rcv) { | ||
2777 | struct qib_ctxtdata *rcd = (struct qib_ctxtdata *)n->arg; | ||
2778 | dd = rcd->dd; | ||
2779 | } else { | ||
2780 | struct qib_pportdata *ppd = (struct qib_pportdata *)n->arg; | ||
2781 | dd = ppd->dd; | ||
2782 | } | ||
2783 | qib_devinfo(dd->pcidev, | ||
2784 | "release on HCA notify 0x%p n 0x%p\n", ref, n); | ||
2785 | kfree(n); | ||
2786 | } | ||
2787 | #endif | ||
2788 | |||
2561 | /* | 2789 | /* |
2562 | * Disable MSIx interrupt if enabled, call generic MSIx code | 2790 | * Disable MSIx interrupt if enabled, call generic MSIx code |
2563 | * to cleanup, and clear pending MSIx interrupts. | 2791 | * to cleanup, and clear pending MSIx interrupts. |
@@ -2575,6 +2803,9 @@ static void qib_7322_nomsix(struct qib_devdata *dd) | |||
2575 | 2803 | ||
2576 | dd->cspec->num_msix_entries = 0; | 2804 | dd->cspec->num_msix_entries = 0; |
2577 | for (i = 0; i < n; i++) { | 2805 | for (i = 0; i < n; i++) { |
2806 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
2807 | reset_dca_notifier(dd, &dd->cspec->msix_entries[i]); | ||
2808 | #endif | ||
2578 | irq_set_affinity_hint( | 2809 | irq_set_affinity_hint( |
2579 | dd->cspec->msix_entries[i].msix.vector, NULL); | 2810 | dd->cspec->msix_entries[i].msix.vector, NULL); |
2580 | free_cpumask_var(dd->cspec->msix_entries[i].mask); | 2811 | free_cpumask_var(dd->cspec->msix_entries[i].mask); |
@@ -2602,6 +2833,15 @@ static void qib_setup_7322_cleanup(struct qib_devdata *dd) | |||
2602 | { | 2833 | { |
2603 | int i; | 2834 | int i; |
2604 | 2835 | ||
2836 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
2837 | if (dd->flags & QIB_DCA_ENABLED) { | ||
2838 | dca_remove_requester(&dd->pcidev->dev); | ||
2839 | dd->flags &= ~QIB_DCA_ENABLED; | ||
2840 | dd->cspec->dca_ctrl = 0; | ||
2841 | qib_write_kreg(dd, KREG_IDX(DCACtrlA), dd->cspec->dca_ctrl); | ||
2842 | } | ||
2843 | #endif | ||
2844 | |||
2605 | qib_7322_free_irq(dd); | 2845 | qib_7322_free_irq(dd); |
2606 | kfree(dd->cspec->cntrs); | 2846 | kfree(dd->cspec->cntrs); |
2607 | kfree(dd->cspec->sendchkenable); | 2847 | kfree(dd->cspec->sendchkenable); |
@@ -3068,6 +3308,53 @@ static irqreturn_t sdma_cleanup_intr(int irq, void *data) | |||
3068 | return IRQ_HANDLED; | 3308 | return IRQ_HANDLED; |
3069 | } | 3309 | } |
3070 | 3310 | ||
3311 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
3312 | |||
3313 | static void reset_dca_notifier(struct qib_devdata *dd, struct qib_msix_entry *m) | ||
3314 | { | ||
3315 | if (!m->dca) | ||
3316 | return; | ||
3317 | qib_devinfo(dd->pcidev, | ||
3318 | "Disabling notifier on HCA %d irq %d\n", | ||
3319 | dd->unit, | ||
3320 | m->msix.vector); | ||
3321 | irq_set_affinity_notifier( | ||
3322 | m->msix.vector, | ||
3323 | NULL); | ||
3324 | m->notifier = NULL; | ||
3325 | } | ||
3326 | |||
3327 | static void setup_dca_notifier(struct qib_devdata *dd, struct qib_msix_entry *m) | ||
3328 | { | ||
3329 | struct qib_irq_notify *n; | ||
3330 | |||
3331 | if (!m->dca) | ||
3332 | return; | ||
3333 | n = kzalloc(sizeof(*n), GFP_KERNEL); | ||
3334 | if (n) { | ||
3335 | int ret; | ||
3336 | |||
3337 | m->notifier = n; | ||
3338 | n->notify.irq = m->msix.vector; | ||
3339 | n->notify.notify = qib_irq_notifier_notify; | ||
3340 | n->notify.release = qib_irq_notifier_release; | ||
3341 | n->arg = m->arg; | ||
3342 | n->rcv = m->rcv; | ||
3343 | qib_devinfo(dd->pcidev, | ||
3344 | "set notifier irq %d rcv %d notify %p\n", | ||
3345 | n->notify.irq, n->rcv, &n->notify); | ||
3346 | ret = irq_set_affinity_notifier( | ||
3347 | n->notify.irq, | ||
3348 | &n->notify); | ||
3349 | if (ret) { | ||
3350 | m->notifier = NULL; | ||
3351 | kfree(n); | ||
3352 | } | ||
3353 | } | ||
3354 | } | ||
3355 | |||
3356 | #endif | ||
3357 | |||
3071 | /* | 3358 | /* |
3072 | * Set up our chip-specific interrupt handler. | 3359 | * Set up our chip-specific interrupt handler. |
3073 | * The interrupt type has already been setup, so | 3360 | * The interrupt type has already been setup, so |
@@ -3149,6 +3436,9 @@ try_intx: | |||
3149 | void *arg; | 3436 | void *arg; |
3150 | u64 val; | 3437 | u64 val; |
3151 | int lsb, reg, sh; | 3438 | int lsb, reg, sh; |
3439 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
3440 | int dca = 0; | ||
3441 | #endif | ||
3152 | 3442 | ||
3153 | dd->cspec->msix_entries[msixnum]. | 3443 | dd->cspec->msix_entries[msixnum]. |
3154 | name[sizeof(dd->cspec->msix_entries[msixnum].name) - 1] | 3444 | name[sizeof(dd->cspec->msix_entries[msixnum].name) - 1] |
@@ -3161,6 +3451,9 @@ try_intx: | |||
3161 | arg = dd->pport + irq_table[i].port - 1; | 3451 | arg = dd->pport + irq_table[i].port - 1; |
3162 | } else | 3452 | } else |
3163 | arg = dd; | 3453 | arg = dd; |
3454 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
3455 | dca = irq_table[i].dca; | ||
3456 | #endif | ||
3164 | lsb = irq_table[i].lsb; | 3457 | lsb = irq_table[i].lsb; |
3165 | handler = irq_table[i].handler; | 3458 | handler = irq_table[i].handler; |
3166 | snprintf(dd->cspec->msix_entries[msixnum].name, | 3459 | snprintf(dd->cspec->msix_entries[msixnum].name, |
@@ -3178,6 +3471,9 @@ try_intx: | |||
3178 | continue; | 3471 | continue; |
3179 | if (qib_krcvq01_no_msi && ctxt < 2) | 3472 | if (qib_krcvq01_no_msi && ctxt < 2) |
3180 | continue; | 3473 | continue; |
3474 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
3475 | dca = 1; | ||
3476 | #endif | ||
3181 | lsb = QIB_I_RCVAVAIL_LSB + ctxt; | 3477 | lsb = QIB_I_RCVAVAIL_LSB + ctxt; |
3182 | handler = qib_7322pintr; | 3478 | handler = qib_7322pintr; |
3183 | snprintf(dd->cspec->msix_entries[msixnum].name, | 3479 | snprintf(dd->cspec->msix_entries[msixnum].name, |
@@ -3203,6 +3499,11 @@ try_intx: | |||
3203 | goto try_intx; | 3499 | goto try_intx; |
3204 | } | 3500 | } |
3205 | dd->cspec->msix_entries[msixnum].arg = arg; | 3501 | dd->cspec->msix_entries[msixnum].arg = arg; |
3502 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
3503 | dd->cspec->msix_entries[msixnum].dca = dca; | ||
3504 | dd->cspec->msix_entries[msixnum].rcv = | ||
3505 | handler == qib_7322pintr; | ||
3506 | #endif | ||
3206 | if (lsb >= 0) { | 3507 | if (lsb >= 0) { |
3207 | reg = lsb / IBA7322_REDIRECT_VEC_PER_REG; | 3508 | reg = lsb / IBA7322_REDIRECT_VEC_PER_REG; |
3208 | sh = (lsb % IBA7322_REDIRECT_VEC_PER_REG) * | 3509 | sh = (lsb % IBA7322_REDIRECT_VEC_PER_REG) * |
@@ -6885,6 +7186,9 @@ struct qib_devdata *qib_init_iba7322_funcs(struct pci_dev *pdev, | |||
6885 | dd->f_sdma_init_early = qib_7322_sdma_init_early; | 7186 | dd->f_sdma_init_early = qib_7322_sdma_init_early; |
6886 | dd->f_writescratch = writescratch; | 7187 | dd->f_writescratch = writescratch; |
6887 | dd->f_tempsense_rd = qib_7322_tempsense_rd; | 7188 | dd->f_tempsense_rd = qib_7322_tempsense_rd; |
7189 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
7190 | dd->f_notify_dca = qib_7322_notify_dca; | ||
7191 | #endif | ||
6888 | /* | 7192 | /* |
6889 | * Do remaining PCIe setup and save PCIe values in dd. | 7193 | * Do remaining PCIe setup and save PCIe values in dd. |
6890 | * Any error printing is already done by the init code. | 7194 | * Any error printing is already done by the init code. |
@@ -6921,7 +7225,7 @@ struct qib_devdata *qib_init_iba7322_funcs(struct pci_dev *pdev, | |||
6921 | actual_cnt -= dd->num_pports; | 7225 | actual_cnt -= dd->num_pports; |
6922 | 7226 | ||
6923 | tabsize = actual_cnt; | 7227 | tabsize = actual_cnt; |
6924 | dd->cspec->msix_entries = kmalloc(tabsize * | 7228 | dd->cspec->msix_entries = kzalloc(tabsize * |
6925 | sizeof(struct qib_msix_entry), GFP_KERNEL); | 7229 | sizeof(struct qib_msix_entry), GFP_KERNEL); |
6926 | if (!dd->cspec->msix_entries) { | 7230 | if (!dd->cspec->msix_entries) { |
6927 | qib_dev_err(dd, "No memory for MSIx table\n"); | 7231 | qib_dev_err(dd, "No memory for MSIx table\n"); |
@@ -6941,7 +7245,13 @@ struct qib_devdata *qib_init_iba7322_funcs(struct pci_dev *pdev, | |||
6941 | 7245 | ||
6942 | /* clear diagctrl register, in case diags were running and crashed */ | 7246 | /* clear diagctrl register, in case diags were running and crashed */ |
6943 | qib_write_kreg(dd, kr_hwdiagctrl, 0); | 7247 | qib_write_kreg(dd, kr_hwdiagctrl, 0); |
6944 | 7248 | #ifdef CONFIG_INFINIBAND_QIB_DCA | |
7249 | if (!dca_add_requester(&pdev->dev)) { | ||
7250 | qib_devinfo(dd->pcidev, "DCA enabled\n"); | ||
7251 | dd->flags |= QIB_DCA_ENABLED; | ||
7252 | qib_setup_dca(dd); | ||
7253 | } | ||
7254 | #endif | ||
6945 | goto bail; | 7255 | goto bail; |
6946 | 7256 | ||
6947 | bail_cleanup: | 7257 | bail_cleanup: |
@@ -7156,15 +7466,20 @@ static const struct txdds_ent txdds_extra_sdr[TXDDS_EXTRA_SZ] = { | |||
7156 | { 0, 0, 0, 1 }, /* QMH7342 backplane settings */ | 7466 | { 0, 0, 0, 1 }, /* QMH7342 backplane settings */ |
7157 | { 0, 0, 0, 2 }, /* QMH7342 backplane settings */ | 7467 | { 0, 0, 0, 2 }, /* QMH7342 backplane settings */ |
7158 | { 0, 0, 0, 2 }, /* QMH7342 backplane settings */ | 7468 | { 0, 0, 0, 2 }, /* QMH7342 backplane settings */ |
7159 | { 0, 0, 0, 11 }, /* QME7342 backplane settings */ | ||
7160 | { 0, 0, 0, 11 }, /* QME7342 backplane settings */ | ||
7161 | { 0, 0, 0, 11 }, /* QME7342 backplane settings */ | ||
7162 | { 0, 0, 0, 11 }, /* QME7342 backplane settings */ | ||
7163 | { 0, 0, 0, 11 }, /* QME7342 backplane settings */ | ||
7164 | { 0, 0, 0, 11 }, /* QME7342 backplane settings */ | ||
7165 | { 0, 0, 0, 11 }, /* QME7342 backplane settings */ | ||
7166 | { 0, 0, 0, 3 }, /* QMH7342 backplane settings */ | 7469 | { 0, 0, 0, 3 }, /* QMH7342 backplane settings */ |
7167 | { 0, 0, 0, 4 }, /* QMH7342 backplane settings */ | 7470 | { 0, 0, 0, 4 }, /* QMH7342 backplane settings */ |
7471 | { 0, 1, 4, 15 }, /* QME7342 backplane settings 1.0 */ | ||
7472 | { 0, 1, 3, 15 }, /* QME7342 backplane settings 1.0 */ | ||
7473 | { 0, 1, 0, 12 }, /* QME7342 backplane settings 1.0 */ | ||
7474 | { 0, 1, 0, 11 }, /* QME7342 backplane settings 1.0 */ | ||
7475 | { 0, 1, 0, 9 }, /* QME7342 backplane settings 1.0 */ | ||
7476 | { 0, 1, 0, 14 }, /* QME7342 backplane settings 1.0 */ | ||
7477 | { 0, 1, 2, 15 }, /* QME7342 backplane settings 1.0 */ | ||
7478 | { 0, 1, 0, 11 }, /* QME7342 backplane settings 1.1 */ | ||
7479 | { 0, 1, 0, 7 }, /* QME7342 backplane settings 1.1 */ | ||
7480 | { 0, 1, 0, 9 }, /* QME7342 backplane settings 1.1 */ | ||
7481 | { 0, 1, 0, 6 }, /* QME7342 backplane settings 1.1 */ | ||
7482 | { 0, 1, 0, 8 }, /* QME7342 backplane settings 1.1 */ | ||
7168 | }; | 7483 | }; |
7169 | 7484 | ||
7170 | static const struct txdds_ent txdds_extra_ddr[TXDDS_EXTRA_SZ] = { | 7485 | static const struct txdds_ent txdds_extra_ddr[TXDDS_EXTRA_SZ] = { |
@@ -7173,15 +7488,20 @@ static const struct txdds_ent txdds_extra_ddr[TXDDS_EXTRA_SZ] = { | |||
7173 | { 0, 0, 0, 7 }, /* QMH7342 backplane settings */ | 7488 | { 0, 0, 0, 7 }, /* QMH7342 backplane settings */ |
7174 | { 0, 0, 0, 8 }, /* QMH7342 backplane settings */ | 7489 | { 0, 0, 0, 8 }, /* QMH7342 backplane settings */ |
7175 | { 0, 0, 0, 8 }, /* QMH7342 backplane settings */ | 7490 | { 0, 0, 0, 8 }, /* QMH7342 backplane settings */ |
7176 | { 0, 0, 0, 13 }, /* QME7342 backplane settings */ | ||
7177 | { 0, 0, 0, 13 }, /* QME7342 backplane settings */ | ||
7178 | { 0, 0, 0, 13 }, /* QME7342 backplane settings */ | ||
7179 | { 0, 0, 0, 13 }, /* QME7342 backplane settings */ | ||
7180 | { 0, 0, 0, 13 }, /* QME7342 backplane settings */ | ||
7181 | { 0, 0, 0, 13 }, /* QME7342 backplane settings */ | ||
7182 | { 0, 0, 0, 13 }, /* QME7342 backplane settings */ | ||
7183 | { 0, 0, 0, 9 }, /* QMH7342 backplane settings */ | 7491 | { 0, 0, 0, 9 }, /* QMH7342 backplane settings */ |
7184 | { 0, 0, 0, 10 }, /* QMH7342 backplane settings */ | 7492 | { 0, 0, 0, 10 }, /* QMH7342 backplane settings */ |
7493 | { 0, 1, 4, 15 }, /* QME7342 backplane settings 1.0 */ | ||
7494 | { 0, 1, 3, 15 }, /* QME7342 backplane settings 1.0 */ | ||
7495 | { 0, 1, 0, 12 }, /* QME7342 backplane settings 1.0 */ | ||
7496 | { 0, 1, 0, 11 }, /* QME7342 backplane settings 1.0 */ | ||
7497 | { 0, 1, 0, 9 }, /* QME7342 backplane settings 1.0 */ | ||
7498 | { 0, 1, 0, 14 }, /* QME7342 backplane settings 1.0 */ | ||
7499 | { 0, 1, 2, 15 }, /* QME7342 backplane settings 1.0 */ | ||
7500 | { 0, 1, 0, 11 }, /* QME7342 backplane settings 1.1 */ | ||
7501 | { 0, 1, 0, 7 }, /* QME7342 backplane settings 1.1 */ | ||
7502 | { 0, 1, 0, 9 }, /* QME7342 backplane settings 1.1 */ | ||
7503 | { 0, 1, 0, 6 }, /* QME7342 backplane settings 1.1 */ | ||
7504 | { 0, 1, 0, 8 }, /* QME7342 backplane settings 1.1 */ | ||
7185 | }; | 7505 | }; |
7186 | 7506 | ||
7187 | static const struct txdds_ent txdds_extra_qdr[TXDDS_EXTRA_SZ] = { | 7507 | static const struct txdds_ent txdds_extra_qdr[TXDDS_EXTRA_SZ] = { |
@@ -7190,15 +7510,20 @@ static const struct txdds_ent txdds_extra_qdr[TXDDS_EXTRA_SZ] = { | |||
7190 | { 0, 1, 0, 5 }, /* QMH7342 backplane settings */ | 7510 | { 0, 1, 0, 5 }, /* QMH7342 backplane settings */ |
7191 | { 0, 1, 0, 6 }, /* QMH7342 backplane settings */ | 7511 | { 0, 1, 0, 6 }, /* QMH7342 backplane settings */ |
7192 | { 0, 1, 0, 8 }, /* QMH7342 backplane settings */ | 7512 | { 0, 1, 0, 8 }, /* QMH7342 backplane settings */ |
7193 | { 0, 1, 12, 10 }, /* QME7342 backplane setting */ | ||
7194 | { 0, 1, 12, 11 }, /* QME7342 backplane setting */ | ||
7195 | { 0, 1, 12, 12 }, /* QME7342 backplane setting */ | ||
7196 | { 0, 1, 12, 14 }, /* QME7342 backplane setting */ | ||
7197 | { 0, 1, 12, 6 }, /* QME7342 backplane setting */ | ||
7198 | { 0, 1, 12, 7 }, /* QME7342 backplane setting */ | ||
7199 | { 0, 1, 12, 8 }, /* QME7342 backplane setting */ | ||
7200 | { 0, 1, 0, 10 }, /* QMH7342 backplane settings */ | 7513 | { 0, 1, 0, 10 }, /* QMH7342 backplane settings */ |
7201 | { 0, 1, 0, 12 }, /* QMH7342 backplane settings */ | 7514 | { 0, 1, 0, 12 }, /* QMH7342 backplane settings */ |
7515 | { 0, 1, 4, 15 }, /* QME7342 backplane settings 1.0 */ | ||
7516 | { 0, 1, 3, 15 }, /* QME7342 backplane settings 1.0 */ | ||
7517 | { 0, 1, 0, 12 }, /* QME7342 backplane settings 1.0 */ | ||
7518 | { 0, 1, 0, 11 }, /* QME7342 backplane settings 1.0 */ | ||
7519 | { 0, 1, 0, 9 }, /* QME7342 backplane settings 1.0 */ | ||
7520 | { 0, 1, 0, 14 }, /* QME7342 backplane settings 1.0 */ | ||
7521 | { 0, 1, 2, 15 }, /* QME7342 backplane settings 1.0 */ | ||
7522 | { 0, 1, 0, 11 }, /* QME7342 backplane settings 1.1 */ | ||
7523 | { 0, 1, 0, 7 }, /* QME7342 backplane settings 1.1 */ | ||
7524 | { 0, 1, 0, 9 }, /* QME7342 backplane settings 1.1 */ | ||
7525 | { 0, 1, 0, 6 }, /* QME7342 backplane settings 1.1 */ | ||
7526 | { 0, 1, 0, 8 }, /* QME7342 backplane settings 1.1 */ | ||
7202 | }; | 7527 | }; |
7203 | 7528 | ||
7204 | static const struct txdds_ent txdds_extra_mfg[TXDDS_MFG_SZ] = { | 7529 | static const struct txdds_ent txdds_extra_mfg[TXDDS_MFG_SZ] = { |