aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/qib/qib_iba7322.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/qib/qib_iba7322.c')
-rw-r--r--drivers/infiniband/hw/qib/qib_iba7322.c393
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
526struct qib_irq_notify {
527 int rcv;
528 void *arg;
529 struct irq_affinity_notify notify;
530};
531#endif
532
522struct qib_chip_specific { 533struct 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 {
573static void write_tx_serdes_param(struct qib_pportdata *, struct txdds_ent *); 590static 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
687static 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 *);
686static void setup_7322_link_recovery(struct qib_pportdata *, u32); 751static void setup_7322_link_recovery(struct qib_pportdata *, u32);
687static void check_7322_rxe_status(struct qib_pportdata *); 752static void check_7322_rxe_status(struct qib_pportdata *);
688static u32 __iomem *qib_7322_getsendbuf(struct qib_pportdata *, u64, u32 *); 753static u32 __iomem *qib_7322_getsendbuf(struct qib_pportdata *, u64, u32 *);
754#ifdef CONFIG_INFINIBAND_QIB_DCA
755static void qib_setup_dca(struct qib_devdata *dd);
756static void setup_dca_notifier(struct qib_devdata *dd,
757 struct qib_msix_entry *m);
758static 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
2635static 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
2660static 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
2685static 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
2715static 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
2754static 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
2770static 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
3313static 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
3327static 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
6947bail_cleanup: 7257bail_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
7170static const struct txdds_ent txdds_extra_ddr[TXDDS_EXTRA_SZ] = { 7485static 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
7187static const struct txdds_ent txdds_extra_qdr[TXDDS_EXTRA_SZ] = { 7507static 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
7204static const struct txdds_ent txdds_extra_mfg[TXDDS_MFG_SZ] = { 7529static const struct txdds_ent txdds_extra_mfg[TXDDS_MFG_SZ] = {