aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/infiniband/hw/ipath/ipath_common.h4
-rw-r--r--drivers/infiniband/hw/ipath/ipath_driver.c11
-rw-r--r--drivers/infiniband/hw/ipath/ipath_intr.c162
-rw-r--r--drivers/infiniband/hw/ipath/ipath_stats.c1
4 files changed, 105 insertions, 73 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_common.h b/drivers/infiniband/hw/ipath/ipath_common.h
index 3a849e71638e..7a8a086a579a 100644
--- a/drivers/infiniband/hw/ipath/ipath_common.h
+++ b/drivers/infiniband/hw/ipath/ipath_common.h
@@ -97,8 +97,8 @@ struct infinipath_stats {
97 __u64 sps_hwerrs; 97 __u64 sps_hwerrs;
98 /* number of times IB link changed state unexpectedly */ 98 /* number of times IB link changed state unexpectedly */
99 __u64 sps_iblink; 99 __u64 sps_iblink;
100 /* no longer used; left for compatibility */ 100 /* kernel receive interrupts that didn't read intstat */
101 __u64 sps_unused3; 101 __u64 sps_fastrcvint;
102 /* number of kernel (port0) packets received */ 102 /* number of kernel (port0) packets received */
103 __u64 sps_port0pkts; 103 __u64 sps_port0pkts;
104 /* number of "ethernet" packets sent by driver */ 104 /* number of "ethernet" packets sent by driver */
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index 0b88642381f8..eb745234d8c3 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -888,12 +888,7 @@ void ipath_kreceive(struct ipath_devdata *dd)
888 (u32)le64_to_cpu(*dd->ipath_hdrqtailptr)) 888 (u32)le64_to_cpu(*dd->ipath_hdrqtailptr))
889 goto done; 889 goto done;
890 890
891gotmore: 891 /* read only once at start for performance */
892 /*
893 * read only once at start. If in flood situation, this helps
894 * performance slightly. If more arrive while we are processing,
895 * we'll come back here and do them
896 */
897 hdrqtail = (u32)le64_to_cpu(*dd->ipath_hdrqtailptr); 892 hdrqtail = (u32)le64_to_cpu(*dd->ipath_hdrqtailptr);
898 893
899 for (i = 0, l = dd->ipath_port0head; l != hdrqtail; i++) { 894 for (i = 0, l = dd->ipath_port0head; l != hdrqtail; i++) {
@@ -1022,10 +1017,6 @@ gotmore:
1022 1017
1023 dd->ipath_port0head = l; 1018 dd->ipath_port0head = l;
1024 1019
1025 if (hdrqtail != (u32)le64_to_cpu(*dd->ipath_hdrqtailptr))
1026 /* more arrived while we handled first batch */
1027 goto gotmore;
1028
1029 if (pkttot > ipath_stats.sps_maxpkts_call) 1020 if (pkttot > ipath_stats.sps_maxpkts_call)
1030 ipath_stats.sps_maxpkts_call = pkttot; 1021 ipath_stats.sps_maxpkts_call = pkttot;
1031 ipath_stats.sps_port0pkts += pkttot; 1022 ipath_stats.sps_port0pkts += pkttot;
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c
index 8a4d732b4858..e8c8a25cd922 100644
--- a/drivers/infiniband/hw/ipath/ipath_intr.c
+++ b/drivers/infiniband/hw/ipath/ipath_intr.c
@@ -539,10 +539,10 @@ static void handle_errors(struct ipath_devdata *dd, ipath_err_t errs)
539 continue; 539 continue;
540 if (hd == (tl + 1) || 540 if (hd == (tl + 1) ||
541 (!hd && tl == dd->ipath_hdrqlast)) { 541 (!hd && tl == dd->ipath_hdrqlast)) {
542 dd->ipath_lastrcvhdrqtails[i] = tl;
543 pd->port_hdrqfull++;
544 if (i == 0) 542 if (i == 0)
545 chkerrpkts = 1; 543 chkerrpkts = 1;
544 dd->ipath_lastrcvhdrqtails[i] = tl;
545 pd->port_hdrqfull++;
546 } 546 }
547 } 547 }
548 } 548 }
@@ -724,7 +724,12 @@ set:
724 dd->ipath_sendctrl); 724 dd->ipath_sendctrl);
725} 725}
726 726
727static void handle_rcv(struct ipath_devdata *dd, u32 istat) 727/*
728 * Handle receive interrupts for user ports; this means a user
729 * process was waiting for a packet to arrive, and didn't want
730 * to poll
731 */
732static void handle_urcv(struct ipath_devdata *dd, u32 istat)
728{ 733{
729 u64 portr; 734 u64 portr;
730 int i; 735 int i;
@@ -734,22 +739,17 @@ static void handle_rcv(struct ipath_devdata *dd, u32 istat)
734 infinipath_i_rcvavail_mask) 739 infinipath_i_rcvavail_mask)
735 | ((istat >> INFINIPATH_I_RCVURG_SHIFT) & 740 | ((istat >> INFINIPATH_I_RCVURG_SHIFT) &
736 infinipath_i_rcvurg_mask); 741 infinipath_i_rcvurg_mask);
737 for (i = 0; i < dd->ipath_cfgports; i++) { 742 for (i = 1; i < dd->ipath_cfgports; i++) {
738 struct ipath_portdata *pd = dd->ipath_pd[i]; 743 struct ipath_portdata *pd = dd->ipath_pd[i];
739 if (portr & (1 << i) && pd && 744 if (portr & (1 << i) && pd && pd->port_cnt &&
740 pd->port_cnt) { 745 test_bit(IPATH_PORT_WAITING_RCV, &pd->port_flag)) {
741 if (i == 0) 746 int rcbit;
742 ipath_kreceive(dd); 747 clear_bit(IPATH_PORT_WAITING_RCV,
743 else if (test_bit(IPATH_PORT_WAITING_RCV, 748 &pd->port_flag);
744 &pd->port_flag)) { 749 rcbit = i + INFINIPATH_R_INTRAVAIL_SHIFT;
745 int rcbit; 750 clear_bit(1UL << rcbit, &dd->ipath_rcvctrl);
746 clear_bit(IPATH_PORT_WAITING_RCV, 751 wake_up_interruptible(&pd->port_wait);
747 &pd->port_flag); 752 rcvdint = 1;
748 rcbit = i + INFINIPATH_R_INTRAVAIL_SHIFT;
749 clear_bit(1UL << rcbit, &dd->ipath_rcvctrl);
750 wake_up_interruptible(&pd->port_wait);
751 rcvdint = 1;
752 }
753 } 753 }
754 } 754 }
755 if (rcvdint) { 755 if (rcvdint) {
@@ -767,14 +767,17 @@ irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs)
767 struct ipath_devdata *dd = data; 767 struct ipath_devdata *dd = data;
768 u32 istat; 768 u32 istat;
769 ipath_err_t estat = 0; 769 ipath_err_t estat = 0;
770 static unsigned unexpected = 0;
771 irqreturn_t ret; 770 irqreturn_t ret;
771 u32 p0bits;
772 static unsigned unexpected = 0;
773 static const u32 port0rbits = (1U<<INFINIPATH_I_RCVAVAIL_SHIFT) |
774 (1U<<INFINIPATH_I_RCVURG_SHIFT);
775
776 ipath_stats.sps_ints++;
772 777
773 if(!(dd->ipath_flags & IPATH_PRESENT)) { 778 if (!(dd->ipath_flags & IPATH_PRESENT)) {
774 /* this is mostly so we don't try to touch the chip while
775 * it is being reset */
776 /* 779 /*
777 * This return value is perhaps odd, but we do not want the 780 * This return value is not great, but we do not want the
778 * interrupt core code to remove our interrupt handler 781 * interrupt core code to remove our interrupt handler
779 * because we don't appear to be handling an interrupt 782 * because we don't appear to be handling an interrupt
780 * during a chip reset. 783 * during a chip reset.
@@ -782,6 +785,50 @@ irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs)
782 return IRQ_HANDLED; 785 return IRQ_HANDLED;
783 } 786 }
784 787
788 /*
789 * this needs to be flags&initted, not statusp, so we keep
790 * taking interrupts even after link goes down, etc.
791 * Also, we *must* clear the interrupt at some point, or we won't
792 * take it again, which can be real bad for errors, etc...
793 */
794
795 if (!(dd->ipath_flags & IPATH_INITTED)) {
796 ipath_bad_intr(dd, &unexpected);
797 ret = IRQ_NONE;
798 goto bail;
799 }
800
801 /*
802 * We try to avoid reading the interrupt status register, since
803 * that's a PIO read, and stalls the processor for up to about
804 * ~0.25 usec. The idea is that if we processed a port0 packet,
805 * we blindly clear the port 0 receive interrupt bits, and nothing
806 * else, then return. If other interrupts are pending, the chip
807 * will re-interrupt us as soon as we write the intclear register.
808 * We then won't process any more kernel packets (if not the 2nd
809 * time, then the 3rd or 4th) and we'll then handle the other
810 * interrupts. We clear the interrupts first so that we don't
811 * lose intr for later packets that arrive while we are processing.
812 */
813 if (dd->ipath_port0head !=
814 (u32)le64_to_cpu(*dd->ipath_hdrqtailptr)) {
815 u32 oldhead = dd->ipath_port0head;
816 if (dd->ipath_flags & IPATH_GPIO_INTR) {
817 ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear,
818 (u64) (1 << 2));
819 p0bits = port0rbits | INFINIPATH_I_GPIO;
820 }
821 else
822 p0bits = port0rbits;
823 ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, p0bits);
824 ipath_kreceive(dd);
825 if (oldhead != dd->ipath_port0head) {
826 ipath_stats.sps_fastrcvint++;
827 goto done;
828 }
829 istat = ipath_read_kreg32(dd, dd->ipath_kregs->kr_intstatus);
830 }
831
785 istat = ipath_read_kreg32(dd, dd->ipath_kregs->kr_intstatus); 832 istat = ipath_read_kreg32(dd, dd->ipath_kregs->kr_intstatus);
786 if (unlikely(!istat)) { 833 if (unlikely(!istat)) {
787 ipath_stats.sps_nullintr++; 834 ipath_stats.sps_nullintr++;
@@ -795,31 +842,17 @@ irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs)
795 goto bail; 842 goto bail;
796 } 843 }
797 844
798 ipath_stats.sps_ints++;
799
800 /*
801 * this needs to be flags&initted, not statusp, so we keep
802 * taking interrupts even after link goes down, etc.
803 * Also, we *must* clear the interrupt at some point, or we won't
804 * take it again, which can be real bad for errors, etc...
805 */
806
807 if (!(dd->ipath_flags & IPATH_INITTED)) {
808 ipath_bad_intr(dd, &unexpected);
809 ret = IRQ_NONE;
810 goto bail;
811 }
812 if (unexpected) 845 if (unexpected)
813 unexpected = 0; 846 unexpected = 0;
814 847
815 ipath_cdbg(VERBOSE, "intr stat=0x%x\n", istat); 848 if (unlikely(istat & ~infinipath_i_bitsextant))
816
817 if (istat & ~infinipath_i_bitsextant)
818 ipath_dev_err(dd, 849 ipath_dev_err(dd,
819 "interrupt with unknown interrupts %x set\n", 850 "interrupt with unknown interrupts %x set\n",
820 istat & (u32) ~ infinipath_i_bitsextant); 851 istat & (u32) ~ infinipath_i_bitsextant);
852 else
853 ipath_cdbg(VERBOSE, "intr stat=0x%x\n", istat);
821 854
822 if (istat & INFINIPATH_I_ERROR) { 855 if (unlikely(istat & INFINIPATH_I_ERROR)) {
823 ipath_stats.sps_errints++; 856 ipath_stats.sps_errints++;
824 estat = ipath_read_kreg64(dd, 857 estat = ipath_read_kreg64(dd,
825 dd->ipath_kregs->kr_errorstatus); 858 dd->ipath_kregs->kr_errorstatus);
@@ -837,7 +870,14 @@ irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs)
837 handle_errors(dd, estat); 870 handle_errors(dd, estat);
838 } 871 }
839 872
873 p0bits = port0rbits;
840 if (istat & INFINIPATH_I_GPIO) { 874 if (istat & INFINIPATH_I_GPIO) {
875 /*
876 * Packets are available in the port 0 rcv queue.
877 * Eventually this needs to be generalized to check
878 * IPATH_GPIO_INTR, and the specific GPIO bit, if
879 * GPIO interrupts are used for anything else.
880 */
841 if (unlikely(!(dd->ipath_flags & IPATH_GPIO_INTR))) { 881 if (unlikely(!(dd->ipath_flags & IPATH_GPIO_INTR))) {
842 u32 gpiostatus; 882 u32 gpiostatus;
843 gpiostatus = ipath_read_kreg32( 883 gpiostatus = ipath_read_kreg32(
@@ -851,14 +891,7 @@ irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs)
851 /* Clear GPIO status bit 2 */ 891 /* Clear GPIO status bit 2 */
852 ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear, 892 ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear,
853 (u64) (1 << 2)); 893 (u64) (1 << 2));
854 894 p0bits |= INFINIPATH_I_GPIO;
855 /*
856 * Packets are available in the port 0 rcv queue.
857 * Eventually this needs to be generalized to check
858 * IPATH_GPIO_INTR, and the specific GPIO bit, if
859 * GPIO interrupts are used for anything else.
860 */
861 ipath_kreceive(dd);
862 } 895 }
863 } 896 }
864 897
@@ -871,6 +904,25 @@ irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs)
871 */ 904 */
872 ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, istat); 905 ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, istat);
873 906
907 /*
908 * we check for both transition from empty to non-empty, and urgent
909 * packets (those with the interrupt bit set in the header), and
910 * if enabled, the GPIO bit 2 interrupt used for port0 on some
911 * HT-400 boards.
912 * Do this before checking for pio buffers available, since
913 * receives can overflow; piobuf waiters can afford a few
914 * extra cycles, since they were waiting anyway.
915 */
916 if (istat & p0bits) {
917 ipath_kreceive(dd);
918 istat &= ~port0rbits;
919 }
920 if (istat & ((infinipath_i_rcvavail_mask <<
921 INFINIPATH_I_RCVAVAIL_SHIFT)
922 | (infinipath_i_rcvurg_mask <<
923 INFINIPATH_I_RCVURG_SHIFT)))
924 handle_urcv(dd, istat);
925
874 if (istat & INFINIPATH_I_SPIOBUFAVAIL) { 926 if (istat & INFINIPATH_I_SPIOBUFAVAIL) {
875 clear_bit(IPATH_S_PIOINTBUFAVAIL, &dd->ipath_sendctrl); 927 clear_bit(IPATH_S_PIOINTBUFAVAIL, &dd->ipath_sendctrl);
876 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, 928 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
@@ -882,17 +934,7 @@ irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs)
882 handle_layer_pioavail(dd); 934 handle_layer_pioavail(dd);
883 } 935 }
884 936
885 /* 937done:
886 * we check for both transition from empty to non-empty, and urgent
887 * packets (those with the interrupt bit set in the header)
888 */
889
890 if (istat & ((infinipath_i_rcvavail_mask <<
891 INFINIPATH_I_RCVAVAIL_SHIFT)
892 | (infinipath_i_rcvurg_mask <<
893 INFINIPATH_I_RCVURG_SHIFT)))
894 handle_rcv(dd, istat);
895
896 ret = IRQ_HANDLED; 938 ret = IRQ_HANDLED;
897 939
898bail: 940bail:
diff --git a/drivers/infiniband/hw/ipath/ipath_stats.c b/drivers/infiniband/hw/ipath/ipath_stats.c
index 2651701ce1b5..70351b7e35c0 100644
--- a/drivers/infiniband/hw/ipath/ipath_stats.c
+++ b/drivers/infiniband/hw/ipath/ipath_stats.c
@@ -186,7 +186,6 @@ static void ipath_qcheck(struct ipath_devdata *dd)
186 dd->ipath_port0head, 186 dd->ipath_port0head,
187 (unsigned long long) 187 (unsigned long long)
188 ipath_stats.sps_port0pkts); 188 ipath_stats.sps_port0pkts);
189 ipath_kreceive(dd);
190 } 189 }
191 dd->ipath_lastport0rcv_cnt = ipath_stats.sps_port0pkts; 190 dd->ipath_lastport0rcv_cnt = ipath_stats.sps_port0pkts;
192 } 191 }