aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRalph Campbell <ralph.campbell@qlogic.com>2008-01-07 00:02:33 -0500
committerRoland Dreier <rolandd@cisco.com>2008-01-25 17:15:38 -0500
commit6c719cae0b91f577738dfb4007baee28f03e48a5 (patch)
treefef7fb60092c5ed84fe14f7aaafdf55a0551016a
parent7aa54bd730df1468c90ae84b56ade7f322b44de7 (diff)
IB/ipath: MAD performance sampling registers support
Add support for QLogic HCAs which have hardware performance sampling registers for PortSamplesControl and PortSamplesResult MADs. Signed-off-by: Ralph Campbell <ralph.campbell@qlogic.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r--drivers/infiniband/hw/ipath/ipath_kernel.h9
-rw-r--r--drivers/infiniband/hw/ipath/ipath_mad.c119
-rw-r--r--drivers/infiniband/hw/ipath/ipath_registers.h14
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs.c1
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs.h2
5 files changed, 101 insertions, 44 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h
index 7bb0d08820d8..a59c06943de6 100644
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h
@@ -930,6 +930,15 @@ static inline u32 ipath_read_creg32(const struct ipath_devdata *dd,
930 (char __iomem *)dd->ipath_kregbase)); 930 (char __iomem *)dd->ipath_kregbase));
931} 931}
932 932
933static inline void ipath_write_creg(const struct ipath_devdata *dd,
934 ipath_creg regno, u64 value)
935{
936 if (dd->ipath_kregbase)
937 writeq(value, regno + (u64 __iomem *)
938 (dd->ipath_cregbase +
939 (char __iomem *)dd->ipath_kregbase));
940}
941
933static inline void ipath_clear_rcvhdrtail(const struct ipath_portdata *pd) 942static inline void ipath_clear_rcvhdrtail(const struct ipath_portdata *pd)
934{ 943{
935 *((u64 *) pd->port_rcvhdrtail_kvaddr) = 0ULL; 944 *((u64 *) pd->port_rcvhdrtail_kvaddr) = 0ULL;
diff --git a/drivers/infiniband/hw/ipath/ipath_mad.c b/drivers/infiniband/hw/ipath/ipath_mad.c
index 1978c346b5c5..d98d5f103700 100644
--- a/drivers/infiniband/hw/ipath/ipath_mad.c
+++ b/drivers/infiniband/hw/ipath/ipath_mad.c
@@ -934,6 +934,7 @@ static int recv_pma_get_portsamplescontrol(struct ib_perf *pmp,
934 struct ib_pma_portsamplescontrol *p = 934 struct ib_pma_portsamplescontrol *p =
935 (struct ib_pma_portsamplescontrol *)pmp->data; 935 (struct ib_pma_portsamplescontrol *)pmp->data;
936 struct ipath_ibdev *dev = to_idev(ibdev); 936 struct ipath_ibdev *dev = to_idev(ibdev);
937 struct ipath_cregs const *crp = dev->dd->ipath_cregs;
937 unsigned long flags; 938 unsigned long flags;
938 u8 port_select = p->port_select; 939 u8 port_select = p->port_select;
939 940
@@ -955,7 +956,10 @@ static int recv_pma_get_portsamplescontrol(struct ib_perf *pmp,
955 p->counter_width = 4; /* 32 bit counters */ 956 p->counter_width = 4; /* 32 bit counters */
956 p->counter_mask0_9 = COUNTER_MASK0_9; 957 p->counter_mask0_9 = COUNTER_MASK0_9;
957 spin_lock_irqsave(&dev->pending_lock, flags); 958 spin_lock_irqsave(&dev->pending_lock, flags);
958 p->sample_status = dev->pma_sample_status; 959 if (crp->cr_psstat)
960 p->sample_status = ipath_read_creg32(dev->dd, crp->cr_psstat);
961 else
962 p->sample_status = dev->pma_sample_status;
959 p->sample_start = cpu_to_be32(dev->pma_sample_start); 963 p->sample_start = cpu_to_be32(dev->pma_sample_start);
960 p->sample_interval = cpu_to_be32(dev->pma_sample_interval); 964 p->sample_interval = cpu_to_be32(dev->pma_sample_interval);
961 p->tag = cpu_to_be16(dev->pma_tag); 965 p->tag = cpu_to_be16(dev->pma_tag);
@@ -975,8 +979,9 @@ static int recv_pma_set_portsamplescontrol(struct ib_perf *pmp,
975 struct ib_pma_portsamplescontrol *p = 979 struct ib_pma_portsamplescontrol *p =
976 (struct ib_pma_portsamplescontrol *)pmp->data; 980 (struct ib_pma_portsamplescontrol *)pmp->data;
977 struct ipath_ibdev *dev = to_idev(ibdev); 981 struct ipath_ibdev *dev = to_idev(ibdev);
982 struct ipath_cregs const *crp = dev->dd->ipath_cregs;
978 unsigned long flags; 983 unsigned long flags;
979 u32 start; 984 u8 status;
980 int ret; 985 int ret;
981 986
982 if (pmp->attr_mod != 0 || 987 if (pmp->attr_mod != 0 ||
@@ -986,59 +991,67 @@ static int recv_pma_set_portsamplescontrol(struct ib_perf *pmp,
986 goto bail; 991 goto bail;
987 } 992 }
988 993
989 start = be32_to_cpu(p->sample_start); 994 spin_lock_irqsave(&dev->pending_lock, flags);
990 if (start != 0) { 995 if (crp->cr_psstat)
991 spin_lock_irqsave(&dev->pending_lock, flags); 996 status = ipath_read_creg32(dev->dd, crp->cr_psstat);
992 if (dev->pma_sample_status == IB_PMA_SAMPLE_STATUS_DONE) { 997 else
993 dev->pma_sample_status = 998 status = dev->pma_sample_status;
994 IB_PMA_SAMPLE_STATUS_STARTED; 999 if (status == IB_PMA_SAMPLE_STATUS_DONE) {
995 dev->pma_sample_start = start; 1000 dev->pma_sample_start = be32_to_cpu(p->sample_start);
996 dev->pma_sample_interval = 1001 dev->pma_sample_interval = be32_to_cpu(p->sample_interval);
997 be32_to_cpu(p->sample_interval); 1002 dev->pma_tag = be16_to_cpu(p->tag);
998 dev->pma_tag = be16_to_cpu(p->tag); 1003 dev->pma_counter_select[0] = p->counter_select[0];
999 if (p->counter_select[0]) 1004 dev->pma_counter_select[1] = p->counter_select[1];
1000 dev->pma_counter_select[0] = 1005 dev->pma_counter_select[2] = p->counter_select[2];
1001 p->counter_select[0]; 1006 dev->pma_counter_select[3] = p->counter_select[3];
1002 if (p->counter_select[1]) 1007 dev->pma_counter_select[4] = p->counter_select[4];
1003 dev->pma_counter_select[1] = 1008 if (crp->cr_psstat) {
1004 p->counter_select[1]; 1009 ipath_write_creg(dev->dd, crp->cr_psinterval,
1005 if (p->counter_select[2]) 1010 dev->pma_sample_interval);
1006 dev->pma_counter_select[2] = 1011 ipath_write_creg(dev->dd, crp->cr_psstart,
1007 p->counter_select[2]; 1012 dev->pma_sample_start);
1008 if (p->counter_select[3]) 1013 } else
1009 dev->pma_counter_select[3] = 1014 dev->pma_sample_status = IB_PMA_SAMPLE_STATUS_STARTED;
1010 p->counter_select[3];
1011 if (p->counter_select[4])
1012 dev->pma_counter_select[4] =
1013 p->counter_select[4];
1014 }
1015 spin_unlock_irqrestore(&dev->pending_lock, flags);
1016 } 1015 }
1016 spin_unlock_irqrestore(&dev->pending_lock, flags);
1017
1017 ret = recv_pma_get_portsamplescontrol(pmp, ibdev, port); 1018 ret = recv_pma_get_portsamplescontrol(pmp, ibdev, port);
1018 1019
1019bail: 1020bail:
1020 return ret; 1021 return ret;
1021} 1022}
1022 1023
1023static u64 get_counter(struct ipath_ibdev *dev, __be16 sel) 1024static u64 get_counter(struct ipath_ibdev *dev,
1025 struct ipath_cregs const *crp,
1026 __be16 sel)
1024{ 1027{
1025 u64 ret; 1028 u64 ret;
1026 1029
1027 switch (sel) { 1030 switch (sel) {
1028 case IB_PMA_PORT_XMIT_DATA: 1031 case IB_PMA_PORT_XMIT_DATA:
1029 ret = dev->ipath_sword; 1032 ret = (crp->cr_psxmitdatacount) ?
1033 ipath_read_creg32(dev->dd, crp->cr_psxmitdatacount) :
1034 dev->ipath_sword;
1030 break; 1035 break;
1031 case IB_PMA_PORT_RCV_DATA: 1036 case IB_PMA_PORT_RCV_DATA:
1032 ret = dev->ipath_rword; 1037 ret = (crp->cr_psrcvdatacount) ?
1038 ipath_read_creg32(dev->dd, crp->cr_psrcvdatacount) :
1039 dev->ipath_rword;
1033 break; 1040 break;
1034 case IB_PMA_PORT_XMIT_PKTS: 1041 case IB_PMA_PORT_XMIT_PKTS:
1035 ret = dev->ipath_spkts; 1042 ret = (crp->cr_psxmitpktscount) ?
1043 ipath_read_creg32(dev->dd, crp->cr_psxmitpktscount) :
1044 dev->ipath_spkts;
1036 break; 1045 break;
1037 case IB_PMA_PORT_RCV_PKTS: 1046 case IB_PMA_PORT_RCV_PKTS:
1038 ret = dev->ipath_rpkts; 1047 ret = (crp->cr_psrcvpktscount) ?
1048 ipath_read_creg32(dev->dd, crp->cr_psrcvpktscount) :
1049 dev->ipath_rpkts;
1039 break; 1050 break;
1040 case IB_PMA_PORT_XMIT_WAIT: 1051 case IB_PMA_PORT_XMIT_WAIT:
1041 ret = dev->ipath_xmit_wait; 1052 ret = (crp->cr_psxmitwaitcount) ?
1053 ipath_read_creg32(dev->dd, crp->cr_psxmitwaitcount) :
1054 dev->ipath_xmit_wait;
1042 break; 1055 break;
1043 default: 1056 default:
1044 ret = 0; 1057 ret = 0;
@@ -1053,14 +1066,21 @@ static int recv_pma_get_portsamplesresult(struct ib_perf *pmp,
1053 struct ib_pma_portsamplesresult *p = 1066 struct ib_pma_portsamplesresult *p =
1054 (struct ib_pma_portsamplesresult *)pmp->data; 1067 (struct ib_pma_portsamplesresult *)pmp->data;
1055 struct ipath_ibdev *dev = to_idev(ibdev); 1068 struct ipath_ibdev *dev = to_idev(ibdev);
1069 struct ipath_cregs const *crp = dev->dd->ipath_cregs;
1070 u8 status;
1056 int i; 1071 int i;
1057 1072
1058 memset(pmp->data, 0, sizeof(pmp->data)); 1073 memset(pmp->data, 0, sizeof(pmp->data));
1059 p->tag = cpu_to_be16(dev->pma_tag); 1074 p->tag = cpu_to_be16(dev->pma_tag);
1060 p->sample_status = cpu_to_be16(dev->pma_sample_status); 1075 if (crp->cr_psstat)
1076 status = ipath_read_creg32(dev->dd, crp->cr_psstat);
1077 else
1078 status = dev->pma_sample_status;
1079 p->sample_status = cpu_to_be16(status);
1061 for (i = 0; i < ARRAY_SIZE(dev->pma_counter_select); i++) 1080 for (i = 0; i < ARRAY_SIZE(dev->pma_counter_select); i++)
1062 p->counter[i] = cpu_to_be32( 1081 p->counter[i] = (status != IB_PMA_SAMPLE_STATUS_DONE) ? 0 :
1063 get_counter(dev, dev->pma_counter_select[i])); 1082 cpu_to_be32(
1083 get_counter(dev, crp, dev->pma_counter_select[i]));
1064 1084
1065 return reply((struct ib_smp *) pmp); 1085 return reply((struct ib_smp *) pmp);
1066} 1086}
@@ -1071,16 +1091,23 @@ static int recv_pma_get_portsamplesresult_ext(struct ib_perf *pmp,
1071 struct ib_pma_portsamplesresult_ext *p = 1091 struct ib_pma_portsamplesresult_ext *p =
1072 (struct ib_pma_portsamplesresult_ext *)pmp->data; 1092 (struct ib_pma_portsamplesresult_ext *)pmp->data;
1073 struct ipath_ibdev *dev = to_idev(ibdev); 1093 struct ipath_ibdev *dev = to_idev(ibdev);
1094 struct ipath_cregs const *crp = dev->dd->ipath_cregs;
1095 u8 status;
1074 int i; 1096 int i;
1075 1097
1076 memset(pmp->data, 0, sizeof(pmp->data)); 1098 memset(pmp->data, 0, sizeof(pmp->data));
1077 p->tag = cpu_to_be16(dev->pma_tag); 1099 p->tag = cpu_to_be16(dev->pma_tag);
1078 p->sample_status = cpu_to_be16(dev->pma_sample_status); 1100 if (crp->cr_psstat)
1101 status = ipath_read_creg32(dev->dd, crp->cr_psstat);
1102 else
1103 status = dev->pma_sample_status;
1104 p->sample_status = cpu_to_be16(status);
1079 /* 64 bits */ 1105 /* 64 bits */
1080 p->extended_width = __constant_cpu_to_be32(0x80000000); 1106 p->extended_width = __constant_cpu_to_be32(0x80000000);
1081 for (i = 0; i < ARRAY_SIZE(dev->pma_counter_select); i++) 1107 for (i = 0; i < ARRAY_SIZE(dev->pma_counter_select); i++)
1082 p->counter[i] = cpu_to_be64( 1108 p->counter[i] = (status != IB_PMA_SAMPLE_STATUS_DONE) ? 0 :
1083 get_counter(dev, dev->pma_counter_select[i])); 1109 cpu_to_be64(
1110 get_counter(dev, crp, dev->pma_counter_select[i]));
1084 1111
1085 return reply((struct ib_smp *) pmp); 1112 return reply((struct ib_smp *) pmp);
1086} 1113}
@@ -1113,6 +1140,8 @@ static int recv_pma_get_portcounters(struct ib_perf *pmp,
1113 dev->z_local_link_integrity_errors; 1140 dev->z_local_link_integrity_errors;
1114 cntrs.excessive_buffer_overrun_errors -= 1141 cntrs.excessive_buffer_overrun_errors -=
1115 dev->z_excessive_buffer_overrun_errors; 1142 dev->z_excessive_buffer_overrun_errors;
1143 cntrs.vl15_dropped -= dev->z_vl15_dropped;
1144 cntrs.vl15_dropped += dev->n_vl15_dropped;
1116 1145
1117 memset(pmp->data, 0, sizeof(pmp->data)); 1146 memset(pmp->data, 0, sizeof(pmp->data));
1118 1147
@@ -1156,10 +1185,10 @@ static int recv_pma_get_portcounters(struct ib_perf *pmp,
1156 cntrs.excessive_buffer_overrun_errors = 0xFUL; 1185 cntrs.excessive_buffer_overrun_errors = 0xFUL;
1157 p->lli_ebor_errors = (cntrs.local_link_integrity_errors << 4) | 1186 p->lli_ebor_errors = (cntrs.local_link_integrity_errors << 4) |
1158 cntrs.excessive_buffer_overrun_errors; 1187 cntrs.excessive_buffer_overrun_errors;
1159 if (dev->n_vl15_dropped > 0xFFFFUL) 1188 if (cntrs.vl15_dropped > 0xFFFFUL)
1160 p->vl15_dropped = __constant_cpu_to_be16(0xFFFF); 1189 p->vl15_dropped = __constant_cpu_to_be16(0xFFFF);
1161 else 1190 else
1162 p->vl15_dropped = cpu_to_be16((u16)dev->n_vl15_dropped); 1191 p->vl15_dropped = cpu_to_be16((u16)cntrs.vl15_dropped);
1163 if (cntrs.port_xmit_data > 0xFFFFFFFFUL) 1192 if (cntrs.port_xmit_data > 0xFFFFFFFFUL)
1164 p->port_xmit_data = __constant_cpu_to_be32(0xFFFFFFFF); 1193 p->port_xmit_data = __constant_cpu_to_be32(0xFFFFFFFF);
1165 else 1194 else
@@ -1262,8 +1291,10 @@ static int recv_pma_set_portcounters(struct ib_perf *pmp,
1262 dev->z_excessive_buffer_overrun_errors = 1291 dev->z_excessive_buffer_overrun_errors =
1263 cntrs.excessive_buffer_overrun_errors; 1292 cntrs.excessive_buffer_overrun_errors;
1264 1293
1265 if (p->counter_select & IB_PMA_SEL_PORT_VL15_DROPPED) 1294 if (p->counter_select & IB_PMA_SEL_PORT_VL15_DROPPED) {
1266 dev->n_vl15_dropped = 0; 1295 dev->n_vl15_dropped = 0;
1296 dev->z_vl15_dropped = cntrs.vl15_dropped;
1297 }
1267 1298
1268 if (p->counter_select & IB_PMA_SEL_PORT_XMIT_DATA) 1299 if (p->counter_select & IB_PMA_SEL_PORT_XMIT_DATA)
1269 dev->z_port_xmit_data = cntrs.port_xmit_data; 1300 dev->z_port_xmit_data = cntrs.port_xmit_data;
diff --git a/drivers/infiniband/hw/ipath/ipath_registers.h b/drivers/infiniband/hw/ipath/ipath_registers.h
index d7181d444ed7..156ef1473466 100644
--- a/drivers/infiniband/hw/ipath/ipath_registers.h
+++ b/drivers/infiniband/hw/ipath/ipath_registers.h
@@ -469,6 +469,20 @@ struct ipath_cregs {
469 ipath_creg cr_unsupvlcnt; 469 ipath_creg cr_unsupvlcnt;
470 ipath_creg cr_wordrcvcnt; 470 ipath_creg cr_wordrcvcnt;
471 ipath_creg cr_wordsendcnt; 471 ipath_creg cr_wordsendcnt;
472 ipath_creg cr_vl15droppedpktcnt;
473 ipath_creg cr_rxotherlocalphyerrcnt;
474 ipath_creg cr_excessbufferovflcnt;
475 ipath_creg cr_locallinkintegrityerrcnt;
476 ipath_creg cr_rxvlerrcnt;
477 ipath_creg cr_rxdlidfltrcnt;
478 ipath_creg cr_psstat;
479 ipath_creg cr_psstart;
480 ipath_creg cr_psinterval;
481 ipath_creg cr_psrcvdatacount;
482 ipath_creg cr_psrcvpktscount;
483 ipath_creg cr_psxmitdatacount;
484 ipath_creg cr_psxmitpktscount;
485 ipath_creg cr_psxmitwaitcount;
472}; 486};
473 487
474#endif /* _IPATH_REGISTERS_H */ 488#endif /* _IPATH_REGISTERS_H */
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c
index c4c998446c7b..a2baa618daf2 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.c
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.c
@@ -1641,6 +1641,7 @@ int ipath_register_ib_device(struct ipath_devdata *dd)
1641 cntrs.local_link_integrity_errors; 1641 cntrs.local_link_integrity_errors;
1642 idev->z_excessive_buffer_overrun_errors = 1642 idev->z_excessive_buffer_overrun_errors =
1643 cntrs.excessive_buffer_overrun_errors; 1643 cntrs.excessive_buffer_overrun_errors;
1644 idev->z_vl15_dropped = cntrs.vl15_dropped;
1644 1645
1645 /* 1646 /*
1646 * The system image GUID is supposed to be the same for all 1647 * The system image GUID is supposed to be the same for all
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.h b/drivers/infiniband/hw/ipath/ipath_verbs.h
index 6ccb54f104a3..1c8985012743 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.h
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.h
@@ -554,6 +554,7 @@ struct ipath_ibdev {
554 u32 z_pkey_violations; /* starting count for PMA */ 554 u32 z_pkey_violations; /* starting count for PMA */
555 u32 z_local_link_integrity_errors; /* starting count for PMA */ 555 u32 z_local_link_integrity_errors; /* starting count for PMA */
556 u32 z_excessive_buffer_overrun_errors; /* starting count for PMA */ 556 u32 z_excessive_buffer_overrun_errors; /* starting count for PMA */
557 u32 z_vl15_dropped; /* starting count for PMA */
557 u32 n_rc_resends; 558 u32 n_rc_resends;
558 u32 n_rc_acks; 559 u32 n_rc_acks;
559 u32 n_rc_qacks; 560 u32 n_rc_qacks;
@@ -598,6 +599,7 @@ struct ipath_verbs_counters {
598 u64 port_rcv_packets; 599 u64 port_rcv_packets;
599 u32 local_link_integrity_errors; 600 u32 local_link_integrity_errors;
600 u32 excessive_buffer_overrun_errors; 601 u32 excessive_buffer_overrun_errors;
602 u32 vl15_dropped;
601}; 603};
602 604
603static inline struct ipath_mr *to_imr(struct ib_mr *ibmr) 605static inline struct ipath_mr *to_imr(struct ib_mr *ibmr)