diff options
author | Arthur Jones <arthur.jones@qlogic.com> | 2008-04-17 00:01:12 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2008-04-17 00:01:12 -0400 |
commit | 6ca2abf4c02fb3e35247a985c2b6f5834e995033 (patch) | |
tree | cbf950decc213d2c5f05d72e0a2030dc7794f303 /drivers | |
parent | f2ceb4929ab543e54efaadcad215a105df684f36 (diff) |
IB/ipath: Provide I/O bus speeds for diagnostic purposes
Modern I/O buses like PCIe and HT can be configured for multiple speeds
and widths. When an ipath HCA seems to have lower than expected
performance, it is very useful to be able to display what the driver
thinks the bus speed is.
Signed-off-by: Dave Olson <dave.olson@qlogic.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_iba6110.c | 14 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_iba6120.c | 74 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_kernel.h | 9 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_sysfs.c | 11 |
4 files changed, 85 insertions, 23 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6110.c b/drivers/infiniband/hw/ipath/ipath_iba6110.c index 684c27e42406..19e3955304c0 100644 --- a/drivers/infiniband/hw/ipath/ipath_iba6110.c +++ b/drivers/infiniband/hw/ipath/ipath_iba6110.c | |||
@@ -742,11 +742,10 @@ static int ipath_ht_boardname(struct ipath_devdata *dd, char *name, | |||
742 | */ | 742 | */ |
743 | dd->ipath_flags |= IPATH_32BITCOUNTERS; | 743 | dd->ipath_flags |= IPATH_32BITCOUNTERS; |
744 | dd->ipath_flags |= IPATH_GPIO_INTR; | 744 | dd->ipath_flags |= IPATH_GPIO_INTR; |
745 | if (dd->ipath_htspeed != 800) | 745 | if (dd->ipath_lbus_speed != 800) |
746 | ipath_dev_err(dd, | 746 | ipath_dev_err(dd, |
747 | "Incorrectly configured for HT @ %uMHz\n", | 747 | "Incorrectly configured for HT @ %uMHz\n", |
748 | dd->ipath_htspeed); | 748 | dd->ipath_lbus_speed); |
749 | ret = 0; | ||
750 | 749 | ||
751 | /* | 750 | /* |
752 | * set here, not in ipath_init_*_funcs because we have to do | 751 | * set here, not in ipath_init_*_funcs because we have to do |
@@ -911,7 +910,7 @@ static void slave_or_pri_blk(struct ipath_devdata *dd, struct pci_dev *pdev, | |||
911 | break; | 910 | break; |
912 | } | 911 | } |
913 | 912 | ||
914 | dd->ipath_htwidth = width; | 913 | dd->ipath_lbus_width = width; |
915 | 914 | ||
916 | if (linkwidth != 0x11) { | 915 | if (linkwidth != 0x11) { |
917 | ipath_dev_err(dd, "Not configured for 16 bit HT " | 916 | ipath_dev_err(dd, "Not configured for 16 bit HT " |
@@ -959,8 +958,13 @@ static void slave_or_pri_blk(struct ipath_devdata *dd, struct pci_dev *pdev, | |||
959 | speed = 200; | 958 | speed = 200; |
960 | break; | 959 | break; |
961 | } | 960 | } |
962 | dd->ipath_htspeed = speed; | 961 | dd->ipath_lbus_speed = speed; |
963 | } | 962 | } |
963 | |||
964 | snprintf(dd->ipath_lbus_info, sizeof(dd->ipath_lbus_info), | ||
965 | "HyperTransport,%uMHz,x%u\n", | ||
966 | dd->ipath_lbus_speed, | ||
967 | dd->ipath_lbus_width); | ||
964 | } | 968 | } |
965 | 969 | ||
966 | static int ipath_ht_intconfig(struct ipath_devdata *dd) | 970 | static int ipath_ht_intconfig(struct ipath_devdata *dd) |
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6120.c b/drivers/infiniband/hw/ipath/ipath_iba6120.c index 8423fee6344b..828066e20ad7 100644 --- a/drivers/infiniband/hw/ipath/ipath_iba6120.c +++ b/drivers/infiniband/hw/ipath/ipath_iba6120.c | |||
@@ -626,7 +626,6 @@ static int ipath_pe_boardname(struct ipath_devdata *dd, char *name, | |||
626 | dd->ipath_f_put_tid = ipath_pe_put_tid_2; | 626 | dd->ipath_f_put_tid = ipath_pe_put_tid_2; |
627 | } | 627 | } |
628 | 628 | ||
629 | |||
630 | /* | 629 | /* |
631 | * set here, not in ipath_init_*_funcs because we have to do | 630 | * set here, not in ipath_init_*_funcs because we have to do |
632 | * it after we can read chip registers. | 631 | * it after we can read chip registers. |
@@ -879,6 +878,62 @@ static void ipath_setup_pe_cleanup(struct ipath_devdata *dd) | |||
879 | pci_disable_msi(dd->pcidev); | 878 | pci_disable_msi(dd->pcidev); |
880 | } | 879 | } |
881 | 880 | ||
881 | static void ipath_6120_pcie_params(struct ipath_devdata *dd) | ||
882 | { | ||
883 | u16 linkstat, speed; | ||
884 | int pos; | ||
885 | |||
886 | pos = pci_find_capability(dd->pcidev, PCI_CAP_ID_EXP); | ||
887 | if (!pos) { | ||
888 | ipath_dev_err(dd, "Can't find PCI Express capability!\n"); | ||
889 | goto bail; | ||
890 | } | ||
891 | |||
892 | pci_read_config_word(dd->pcidev, pos + PCI_EXP_LNKSTA, | ||
893 | &linkstat); | ||
894 | /* | ||
895 | * speed is bits 0-4, linkwidth is bits 4-8 | ||
896 | * no defines for them in headers | ||
897 | */ | ||
898 | speed = linkstat & 0xf; | ||
899 | linkstat >>= 4; | ||
900 | linkstat &= 0x1f; | ||
901 | dd->ipath_lbus_width = linkstat; | ||
902 | |||
903 | switch (speed) { | ||
904 | case 1: | ||
905 | dd->ipath_lbus_speed = 2500; /* Gen1, 2.5GHz */ | ||
906 | break; | ||
907 | case 2: | ||
908 | dd->ipath_lbus_speed = 5000; /* Gen1, 5GHz */ | ||
909 | break; | ||
910 | default: /* not defined, assume gen1 */ | ||
911 | dd->ipath_lbus_speed = 2500; | ||
912 | break; | ||
913 | } | ||
914 | |||
915 | if (linkstat < 8) | ||
916 | ipath_dev_err(dd, | ||
917 | "PCIe width %u (x8 HCA), performance reduced\n", | ||
918 | linkstat); | ||
919 | else | ||
920 | ipath_cdbg(VERBOSE, "PCIe speed %u width %u (x8 HCA)\n", | ||
921 | dd->ipath_lbus_speed, linkstat); | ||
922 | |||
923 | if (speed != 1) | ||
924 | ipath_dev_err(dd, | ||
925 | "PCIe linkspeed %u is incorrect; " | ||
926 | "should be 1 (2500)!\n", speed); | ||
927 | bail: | ||
928 | /* fill in string, even on errors */ | ||
929 | snprintf(dd->ipath_lbus_info, sizeof(dd->ipath_lbus_info), | ||
930 | "PCIe,%uMHz,x%u\n", | ||
931 | dd->ipath_lbus_speed, | ||
932 | dd->ipath_lbus_width); | ||
933 | |||
934 | return; | ||
935 | } | ||
936 | |||
882 | /** | 937 | /** |
883 | * ipath_setup_pe_config - setup PCIe config related stuff | 938 | * ipath_setup_pe_config - setup PCIe config related stuff |
884 | * @dd: the infinipath device | 939 | * @dd: the infinipath device |
@@ -936,19 +991,8 @@ static int ipath_setup_pe_config(struct ipath_devdata *dd, | |||
936 | } else | 991 | } else |
937 | ipath_dev_err(dd, "Can't find MSI capability, " | 992 | ipath_dev_err(dd, "Can't find MSI capability, " |
938 | "can't save MSI settings for reset\n"); | 993 | "can't save MSI settings for reset\n"); |
939 | if ((pos = pci_find_capability(dd->pcidev, PCI_CAP_ID_EXP))) { | 994 | |
940 | u16 linkstat; | 995 | ipath_6120_pcie_params(dd); |
941 | pci_read_config_word(dd->pcidev, pos + PCI_EXP_LNKSTA, | ||
942 | &linkstat); | ||
943 | linkstat >>= 4; | ||
944 | linkstat &= 0x1f; | ||
945 | if (linkstat != 8) | ||
946 | ipath_dev_err(dd, "PCIe width %u, " | ||
947 | "performance reduced\n", linkstat); | ||
948 | } | ||
949 | else | ||
950 | ipath_dev_err(dd, "Can't find PCI Express " | ||
951 | "capability!\n"); | ||
952 | 996 | ||
953 | dd->ipath_link_width_supported = IB_WIDTH_1X | IB_WIDTH_4X; | 997 | dd->ipath_link_width_supported = IB_WIDTH_1X | IB_WIDTH_4X; |
954 | dd->ipath_link_speed_supported = IPATH_IB_SDR; | 998 | dd->ipath_link_speed_supported = IPATH_IB_SDR; |
@@ -1206,6 +1250,8 @@ static int ipath_setup_pe_reset(struct ipath_devdata *dd) | |||
1206 | ret = 0; /* failed */ | 1250 | ret = 0; /* failed */ |
1207 | 1251 | ||
1208 | bail: | 1252 | bail: |
1253 | if (ret) | ||
1254 | ipath_6120_pcie_params(dd); | ||
1209 | return ret; | 1255 | return ret; |
1210 | } | 1256 | } |
1211 | 1257 | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h index 3d4a254ffca0..59dc89516243 100644 --- a/drivers/infiniband/hw/ipath/ipath_kernel.h +++ b/drivers/infiniband/hw/ipath/ipath_kernel.h | |||
@@ -546,10 +546,10 @@ struct ipath_devdata { | |||
546 | u32 ipath_init_ibmaxlen; | 546 | u32 ipath_init_ibmaxlen; |
547 | /* size of each rcvegrbuffer */ | 547 | /* size of each rcvegrbuffer */ |
548 | u32 ipath_rcvegrbufsize; | 548 | u32 ipath_rcvegrbufsize; |
549 | /* width (2,4,8,16,32) from HT config reg */ | 549 | /* localbus width (1, 2,4,8,16,32) from config space */ |
550 | u32 ipath_htwidth; | 550 | u32 ipath_lbus_width; |
551 | /* HT speed (200,400,800,1000) from HT config */ | 551 | /* localbus speed (HT: 200,400,800,1000; PCIe 2500) */ |
552 | u32 ipath_htspeed; | 552 | u32 ipath_lbus_speed; |
553 | /* | 553 | /* |
554 | * number of sequential ibcstatus change for polling active/quiet | 554 | * number of sequential ibcstatus change for polling active/quiet |
555 | * (i.e., link not coming up). | 555 | * (i.e., link not coming up). |
@@ -574,6 +574,7 @@ struct ipath_devdata { | |||
574 | u8 ipath_serial[16]; | 574 | u8 ipath_serial[16]; |
575 | /* human readable board version */ | 575 | /* human readable board version */ |
576 | u8 ipath_boardversion[80]; | 576 | u8 ipath_boardversion[80]; |
577 | u8 ipath_lbus_info[32]; /* human readable localbus info */ | ||
577 | /* chip major rev, from ipath_revision */ | 578 | /* chip major rev, from ipath_revision */ |
578 | u8 ipath_majrev; | 579 | u8 ipath_majrev; |
579 | /* chip minor rev, from ipath_revision */ | 580 | /* chip minor rev, from ipath_revision */ |
diff --git a/drivers/infiniband/hw/ipath/ipath_sysfs.c b/drivers/infiniband/hw/ipath/ipath_sysfs.c index 56dfc8a2344c..bb41c3f6aad3 100644 --- a/drivers/infiniband/hw/ipath/ipath_sysfs.c +++ b/drivers/infiniband/hw/ipath/ipath_sysfs.c | |||
@@ -163,6 +163,15 @@ static ssize_t show_boardversion(struct device *dev, | |||
163 | return scnprintf(buf, PAGE_SIZE, "%s", dd->ipath_boardversion); | 163 | return scnprintf(buf, PAGE_SIZE, "%s", dd->ipath_boardversion); |
164 | } | 164 | } |
165 | 165 | ||
166 | static ssize_t show_localbus_info(struct device *dev, | ||
167 | struct device_attribute *attr, | ||
168 | char *buf) | ||
169 | { | ||
170 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
171 | /* The string printed here is already newline-terminated. */ | ||
172 | return scnprintf(buf, PAGE_SIZE, "%s", dd->ipath_lbus_info); | ||
173 | } | ||
174 | |||
166 | static ssize_t show_lmc(struct device *dev, | 175 | static ssize_t show_lmc(struct device *dev, |
167 | struct device_attribute *attr, | 176 | struct device_attribute *attr, |
168 | char *buf) | 177 | char *buf) |
@@ -1011,6 +1020,7 @@ static DEVICE_ATTR(unit, S_IRUGO, show_unit, NULL); | |||
1011 | static DEVICE_ATTR(rx_pol_inv, S_IWUSR, NULL, store_rx_pol_inv); | 1020 | static DEVICE_ATTR(rx_pol_inv, S_IWUSR, NULL, store_rx_pol_inv); |
1012 | static DEVICE_ATTR(led_override, S_IWUSR, NULL, store_led_override); | 1021 | static DEVICE_ATTR(led_override, S_IWUSR, NULL, store_led_override); |
1013 | static DEVICE_ATTR(logged_errors, S_IRUGO, show_logged_errs, NULL); | 1022 | static DEVICE_ATTR(logged_errors, S_IRUGO, show_logged_errs, NULL); |
1023 | static DEVICE_ATTR(localbus_info, S_IRUGO, show_localbus_info, NULL); | ||
1014 | static DEVICE_ATTR(jint_max_packets, S_IWUSR | S_IRUGO, | 1024 | static DEVICE_ATTR(jint_max_packets, S_IWUSR | S_IRUGO, |
1015 | show_jint_max_packets, store_jint_max_packets); | 1025 | show_jint_max_packets, store_jint_max_packets); |
1016 | static DEVICE_ATTR(jint_idle_ticks, S_IWUSR | S_IRUGO, | 1026 | static DEVICE_ATTR(jint_idle_ticks, S_IWUSR | S_IRUGO, |
@@ -1034,6 +1044,7 @@ static struct attribute *dev_attributes[] = { | |||
1034 | &dev_attr_rx_pol_inv.attr, | 1044 | &dev_attr_rx_pol_inv.attr, |
1035 | &dev_attr_led_override.attr, | 1045 | &dev_attr_led_override.attr, |
1036 | &dev_attr_logged_errors.attr, | 1046 | &dev_attr_logged_errors.attr, |
1047 | &dev_attr_localbus_info.attr, | ||
1037 | NULL | 1048 | NULL |
1038 | }; | 1049 | }; |
1039 | 1050 | ||