diff options
author | Michael Albaugh <michael.albaugh@qlogic.com> | 2008-01-08 03:37:34 -0500 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2008-01-25 17:17:32 -0500 |
commit | 359193ef433061515fe24d57e5bd5a1318d71bc3 (patch) | |
tree | 270f18f7a3752bf1ac9f98f4a8e88eb9b95f8c71 /drivers/infiniband/hw/ipath | |
parent | c4bce8032ef4368063c84d665b19804878d63e7c (diff) |
IB/ipath: New sysfs entries to control 7220 features
IBA7220 includes many more configurable IB settings. Getting/setting
these is now grouped into a pair of chip specific functions accessed via
function pointers. Provide sysfs access to these settings.
Signed-off-by: Michael Albaugh <michael.albaugh@qlogic.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw/ipath')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_kernel.h | 3 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_sysfs.c | 363 |
2 files changed, 366 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h index 6a5fe0157330..3da8dd79d26e 100644 --- a/drivers/infiniband/hw/ipath/ipath_kernel.h +++ b/drivers/infiniband/hw/ipath/ipath_kernel.h | |||
@@ -824,6 +824,9 @@ int ipath_set_rx_pol_inv(struct ipath_devdata *dd, u8 new_pol_inv); | |||
824 | /* Use GPIO interrupts for new counters */ | 824 | /* Use GPIO interrupts for new counters */ |
825 | #define IPATH_GPIO_ERRINTRS 0x100000 | 825 | #define IPATH_GPIO_ERRINTRS 0x100000 |
826 | #define IPATH_SWAP_PIOBUFS 0x200000 | 826 | #define IPATH_SWAP_PIOBUFS 0x200000 |
827 | /* Suppress heartbeat, even if turning off loopback */ | ||
828 | #define IPATH_NO_HRTBT 0x1000000 | ||
829 | #define IPATH_HAS_MULT_IB_SPEED 0x8000000 | ||
827 | 830 | ||
828 | /* Bits in GPIO for the added interrupts */ | 831 | /* Bits in GPIO for the added interrupts */ |
829 | #define IPATH_GPIO_PORT0_BIT 2 | 832 | #define IPATH_GPIO_PORT0_BIT 2 |
diff --git a/drivers/infiniband/hw/ipath/ipath_sysfs.c b/drivers/infiniband/hw/ipath/ipath_sysfs.c index e2a65349c824..56dfc8a2344c 100644 --- a/drivers/infiniband/hw/ipath/ipath_sysfs.c +++ b/drivers/infiniband/hw/ipath/ipath_sysfs.c | |||
@@ -363,6 +363,60 @@ static ssize_t show_unit(struct device *dev, | |||
363 | return scnprintf(buf, PAGE_SIZE, "%u\n", dd->ipath_unit); | 363 | return scnprintf(buf, PAGE_SIZE, "%u\n", dd->ipath_unit); |
364 | } | 364 | } |
365 | 365 | ||
366 | static ssize_t show_jint_max_packets(struct device *dev, | ||
367 | struct device_attribute *attr, | ||
368 | char *buf) | ||
369 | { | ||
370 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
371 | |||
372 | return scnprintf(buf, PAGE_SIZE, "%hu\n", dd->ipath_jint_max_packets); | ||
373 | } | ||
374 | |||
375 | static ssize_t store_jint_max_packets(struct device *dev, | ||
376 | struct device_attribute *attr, | ||
377 | const char *buf, | ||
378 | size_t count) | ||
379 | { | ||
380 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
381 | u16 v = 0; | ||
382 | int ret; | ||
383 | |||
384 | ret = ipath_parse_ushort(buf, &v); | ||
385 | if (ret < 0) | ||
386 | ipath_dev_err(dd, "invalid jint_max_packets.\n"); | ||
387 | else | ||
388 | dd->ipath_f_config_jint(dd, dd->ipath_jint_idle_ticks, v); | ||
389 | |||
390 | return ret; | ||
391 | } | ||
392 | |||
393 | static ssize_t show_jint_idle_ticks(struct device *dev, | ||
394 | struct device_attribute *attr, | ||
395 | char *buf) | ||
396 | { | ||
397 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
398 | |||
399 | return scnprintf(buf, PAGE_SIZE, "%hu\n", dd->ipath_jint_idle_ticks); | ||
400 | } | ||
401 | |||
402 | static ssize_t store_jint_idle_ticks(struct device *dev, | ||
403 | struct device_attribute *attr, | ||
404 | const char *buf, | ||
405 | size_t count) | ||
406 | { | ||
407 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
408 | u16 v = 0; | ||
409 | int ret; | ||
410 | |||
411 | ret = ipath_parse_ushort(buf, &v); | ||
412 | if (ret < 0) | ||
413 | ipath_dev_err(dd, "invalid jint_idle_ticks.\n"); | ||
414 | else | ||
415 | dd->ipath_f_config_jint(dd, v, dd->ipath_jint_max_packets); | ||
416 | |||
417 | return ret; | ||
418 | } | ||
419 | |||
366 | #define DEVICE_COUNTER(name, attr) \ | 420 | #define DEVICE_COUNTER(name, attr) \ |
367 | static ssize_t show_counter_##name(struct device *dev, \ | 421 | static ssize_t show_counter_##name(struct device *dev, \ |
368 | struct device_attribute *attr, \ | 422 | struct device_attribute *attr, \ |
@@ -670,6 +724,257 @@ static ssize_t show_logged_errs(struct device *dev, | |||
670 | return count; | 724 | return count; |
671 | } | 725 | } |
672 | 726 | ||
727 | /* | ||
728 | * New sysfs entries to control various IB config. These all turn into | ||
729 | * accesses via ipath_f_get/set_ib_cfg. | ||
730 | * | ||
731 | * Get/Set heartbeat enable. Or of 1=enabled, 2=auto | ||
732 | */ | ||
733 | static ssize_t show_hrtbt_enb(struct device *dev, | ||
734 | struct device_attribute *attr, | ||
735 | char *buf) | ||
736 | { | ||
737 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
738 | int ret; | ||
739 | |||
740 | ret = dd->ipath_f_get_ib_cfg(dd, IPATH_IB_CFG_HRTBT); | ||
741 | if (ret >= 0) | ||
742 | ret = scnprintf(buf, PAGE_SIZE, "%d\n", ret); | ||
743 | return ret; | ||
744 | } | ||
745 | |||
746 | static ssize_t store_hrtbt_enb(struct device *dev, | ||
747 | struct device_attribute *attr, | ||
748 | const char *buf, | ||
749 | size_t count) | ||
750 | { | ||
751 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
752 | int ret, r; | ||
753 | u16 val; | ||
754 | |||
755 | ret = ipath_parse_ushort(buf, &val); | ||
756 | if (ret >= 0 && val > 3) | ||
757 | ret = -EINVAL; | ||
758 | if (ret < 0) { | ||
759 | ipath_dev_err(dd, "attempt to set invalid Heartbeat enable\n"); | ||
760 | goto bail; | ||
761 | } | ||
762 | |||
763 | /* | ||
764 | * Set the "intentional" heartbeat enable per either of | ||
765 | * "Enable" and "Auto", as these are normally set together. | ||
766 | * This bit is consulted when leaving loopback mode, | ||
767 | * because entering loopback mode overrides it and automatically | ||
768 | * disables heartbeat. | ||
769 | */ | ||
770 | r = dd->ipath_f_set_ib_cfg(dd, IPATH_IB_CFG_HRTBT, val); | ||
771 | if (r < 0) | ||
772 | ret = r; | ||
773 | else if (val == IPATH_IB_HRTBT_OFF) | ||
774 | dd->ipath_flags |= IPATH_NO_HRTBT; | ||
775 | else | ||
776 | dd->ipath_flags &= ~IPATH_NO_HRTBT; | ||
777 | |||
778 | bail: | ||
779 | return ret; | ||
780 | } | ||
781 | |||
782 | /* | ||
783 | * Get/Set Link-widths enabled. Or of 1=1x, 2=4x (this is human/IB centric, | ||
784 | * _not_ the particular encoding of any given chip) | ||
785 | */ | ||
786 | static ssize_t show_lwid_enb(struct device *dev, | ||
787 | struct device_attribute *attr, | ||
788 | char *buf) | ||
789 | { | ||
790 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
791 | int ret; | ||
792 | |||
793 | ret = dd->ipath_f_get_ib_cfg(dd, IPATH_IB_CFG_LWID_ENB); | ||
794 | if (ret >= 0) | ||
795 | ret = scnprintf(buf, PAGE_SIZE, "%d\n", ret); | ||
796 | return ret; | ||
797 | } | ||
798 | |||
799 | static ssize_t store_lwid_enb(struct device *dev, | ||
800 | struct device_attribute *attr, | ||
801 | const char *buf, | ||
802 | size_t count) | ||
803 | { | ||
804 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
805 | int ret, r; | ||
806 | u16 val; | ||
807 | |||
808 | ret = ipath_parse_ushort(buf, &val); | ||
809 | if (ret >= 0 && (val == 0 || val > 3)) | ||
810 | ret = -EINVAL; | ||
811 | if (ret < 0) { | ||
812 | ipath_dev_err(dd, | ||
813 | "attempt to set invalid Link Width (enable)\n"); | ||
814 | goto bail; | ||
815 | } | ||
816 | |||
817 | r = dd->ipath_f_set_ib_cfg(dd, IPATH_IB_CFG_LWID_ENB, val); | ||
818 | if (r < 0) | ||
819 | ret = r; | ||
820 | |||
821 | bail: | ||
822 | return ret; | ||
823 | } | ||
824 | |||
825 | /* Get current link width */ | ||
826 | static ssize_t show_lwid(struct device *dev, | ||
827 | struct device_attribute *attr, | ||
828 | char *buf) | ||
829 | |||
830 | { | ||
831 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
832 | int ret; | ||
833 | |||
834 | ret = dd->ipath_f_get_ib_cfg(dd, IPATH_IB_CFG_LWID); | ||
835 | if (ret >= 0) | ||
836 | ret = scnprintf(buf, PAGE_SIZE, "%d\n", ret); | ||
837 | return ret; | ||
838 | } | ||
839 | |||
840 | /* | ||
841 | * Get/Set Link-speeds enabled. Or of 1=SDR 2=DDR. | ||
842 | */ | ||
843 | static ssize_t show_spd_enb(struct device *dev, | ||
844 | struct device_attribute *attr, | ||
845 | char *buf) | ||
846 | { | ||
847 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
848 | int ret; | ||
849 | |||
850 | ret = dd->ipath_f_get_ib_cfg(dd, IPATH_IB_CFG_SPD_ENB); | ||
851 | if (ret >= 0) | ||
852 | ret = scnprintf(buf, PAGE_SIZE, "%d\n", ret); | ||
853 | return ret; | ||
854 | } | ||
855 | |||
856 | static ssize_t store_spd_enb(struct device *dev, | ||
857 | struct device_attribute *attr, | ||
858 | const char *buf, | ||
859 | size_t count) | ||
860 | { | ||
861 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
862 | int ret, r; | ||
863 | u16 val; | ||
864 | |||
865 | ret = ipath_parse_ushort(buf, &val); | ||
866 | if (ret >= 0 && (val == 0 || val > (IPATH_IB_SDR | IPATH_IB_DDR))) | ||
867 | ret = -EINVAL; | ||
868 | if (ret < 0) { | ||
869 | ipath_dev_err(dd, | ||
870 | "attempt to set invalid Link Speed (enable)\n"); | ||
871 | goto bail; | ||
872 | } | ||
873 | |||
874 | r = dd->ipath_f_set_ib_cfg(dd, IPATH_IB_CFG_SPD_ENB, val); | ||
875 | if (r < 0) | ||
876 | ret = r; | ||
877 | |||
878 | bail: | ||
879 | return ret; | ||
880 | } | ||
881 | |||
882 | /* Get current link speed */ | ||
883 | static ssize_t show_spd(struct device *dev, | ||
884 | struct device_attribute *attr, | ||
885 | char *buf) | ||
886 | { | ||
887 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
888 | int ret; | ||
889 | |||
890 | ret = dd->ipath_f_get_ib_cfg(dd, IPATH_IB_CFG_SPD); | ||
891 | if (ret >= 0) | ||
892 | ret = scnprintf(buf, PAGE_SIZE, "%d\n", ret); | ||
893 | return ret; | ||
894 | } | ||
895 | |||
896 | /* | ||
897 | * Get/Set RX polarity-invert enable. 0=no, 1=yes. | ||
898 | */ | ||
899 | static ssize_t show_rx_polinv_enb(struct device *dev, | ||
900 | struct device_attribute *attr, | ||
901 | char *buf) | ||
902 | { | ||
903 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
904 | int ret; | ||
905 | |||
906 | ret = dd->ipath_f_get_ib_cfg(dd, IPATH_IB_CFG_RXPOL_ENB); | ||
907 | if (ret >= 0) | ||
908 | ret = scnprintf(buf, PAGE_SIZE, "%d\n", ret); | ||
909 | return ret; | ||
910 | } | ||
911 | |||
912 | static ssize_t store_rx_polinv_enb(struct device *dev, | ||
913 | struct device_attribute *attr, | ||
914 | const char *buf, | ||
915 | size_t count) | ||
916 | { | ||
917 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
918 | int ret, r; | ||
919 | u16 val; | ||
920 | |||
921 | ret = ipath_parse_ushort(buf, &val); | ||
922 | if (ret < 0 || val > 1) | ||
923 | goto invalid; | ||
924 | |||
925 | r = dd->ipath_f_set_ib_cfg(dd, IPATH_IB_CFG_RXPOL_ENB, val); | ||
926 | if (r < 0) { | ||
927 | ret = r; | ||
928 | goto bail; | ||
929 | } | ||
930 | |||
931 | goto bail; | ||
932 | invalid: | ||
933 | ipath_dev_err(dd, "attempt to set invalid Rx Polarity (enable)\n"); | ||
934 | bail: | ||
935 | return ret; | ||
936 | } | ||
937 | /* | ||
938 | * Get/Set RX lane-reversal enable. 0=no, 1=yes. | ||
939 | */ | ||
940 | static ssize_t show_lanerev_enb(struct device *dev, | ||
941 | struct device_attribute *attr, | ||
942 | char *buf) | ||
943 | { | ||
944 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
945 | int ret; | ||
946 | |||
947 | ret = dd->ipath_f_get_ib_cfg(dd, IPATH_IB_CFG_LREV_ENB); | ||
948 | if (ret >= 0) | ||
949 | ret = scnprintf(buf, PAGE_SIZE, "%d\n", ret); | ||
950 | return ret; | ||
951 | } | ||
952 | |||
953 | static ssize_t store_lanerev_enb(struct device *dev, | ||
954 | struct device_attribute *attr, | ||
955 | const char *buf, | ||
956 | size_t count) | ||
957 | { | ||
958 | struct ipath_devdata *dd = dev_get_drvdata(dev); | ||
959 | int ret, r; | ||
960 | u16 val; | ||
961 | |||
962 | ret = ipath_parse_ushort(buf, &val); | ||
963 | if (ret >= 0 && val > 1) { | ||
964 | ret = -EINVAL; | ||
965 | ipath_dev_err(dd, | ||
966 | "attempt to set invalid Lane reversal (enable)\n"); | ||
967 | goto bail; | ||
968 | } | ||
969 | |||
970 | r = dd->ipath_f_set_ib_cfg(dd, IPATH_IB_CFG_LREV_ENB, val); | ||
971 | if (r < 0) | ||
972 | ret = r; | ||
973 | |||
974 | bail: | ||
975 | return ret; | ||
976 | } | ||
977 | |||
673 | static DRIVER_ATTR(num_units, S_IRUGO, show_num_units, NULL); | 978 | static DRIVER_ATTR(num_units, S_IRUGO, show_num_units, NULL); |
674 | static DRIVER_ATTR(version, S_IRUGO, show_version, NULL); | 979 | static DRIVER_ATTR(version, S_IRUGO, show_version, NULL); |
675 | 980 | ||
@@ -706,6 +1011,10 @@ static DEVICE_ATTR(unit, S_IRUGO, show_unit, NULL); | |||
706 | static DEVICE_ATTR(rx_pol_inv, S_IWUSR, NULL, store_rx_pol_inv); | 1011 | static DEVICE_ATTR(rx_pol_inv, S_IWUSR, NULL, store_rx_pol_inv); |
707 | static DEVICE_ATTR(led_override, S_IWUSR, NULL, store_led_override); | 1012 | static DEVICE_ATTR(led_override, S_IWUSR, NULL, store_led_override); |
708 | static DEVICE_ATTR(logged_errors, S_IRUGO, show_logged_errs, NULL); | 1013 | static DEVICE_ATTR(logged_errors, S_IRUGO, show_logged_errs, NULL); |
1014 | static DEVICE_ATTR(jint_max_packets, S_IWUSR | S_IRUGO, | ||
1015 | show_jint_max_packets, store_jint_max_packets); | ||
1016 | static DEVICE_ATTR(jint_idle_ticks, S_IWUSR | S_IRUGO, | ||
1017 | show_jint_idle_ticks, store_jint_idle_ticks); | ||
709 | 1018 | ||
710 | static struct attribute *dev_attributes[] = { | 1019 | static struct attribute *dev_attributes[] = { |
711 | &dev_attr_guid.attr, | 1020 | &dev_attr_guid.attr, |
@@ -732,6 +1041,34 @@ static struct attribute_group dev_attr_group = { | |||
732 | .attrs = dev_attributes | 1041 | .attrs = dev_attributes |
733 | }; | 1042 | }; |
734 | 1043 | ||
1044 | static DEVICE_ATTR(hrtbt_enable, S_IWUSR | S_IRUGO, show_hrtbt_enb, | ||
1045 | store_hrtbt_enb); | ||
1046 | static DEVICE_ATTR(link_width_enable, S_IWUSR | S_IRUGO, show_lwid_enb, | ||
1047 | store_lwid_enb); | ||
1048 | static DEVICE_ATTR(link_width, S_IRUGO, show_lwid, NULL); | ||
1049 | static DEVICE_ATTR(link_speed_enable, S_IWUSR | S_IRUGO, show_spd_enb, | ||
1050 | store_spd_enb); | ||
1051 | static DEVICE_ATTR(link_speed, S_IRUGO, show_spd, NULL); | ||
1052 | static DEVICE_ATTR(rx_pol_inv_enable, S_IWUSR | S_IRUGO, show_rx_polinv_enb, | ||
1053 | store_rx_polinv_enb); | ||
1054 | static DEVICE_ATTR(rx_lane_rev_enable, S_IWUSR | S_IRUGO, show_lanerev_enb, | ||
1055 | store_lanerev_enb); | ||
1056 | |||
1057 | static struct attribute *dev_ibcfg_attributes[] = { | ||
1058 | &dev_attr_hrtbt_enable.attr, | ||
1059 | &dev_attr_link_width_enable.attr, | ||
1060 | &dev_attr_link_width.attr, | ||
1061 | &dev_attr_link_speed_enable.attr, | ||
1062 | &dev_attr_link_speed.attr, | ||
1063 | &dev_attr_rx_pol_inv_enable.attr, | ||
1064 | &dev_attr_rx_lane_rev_enable.attr, | ||
1065 | NULL | ||
1066 | }; | ||
1067 | |||
1068 | static struct attribute_group dev_ibcfg_attr_group = { | ||
1069 | .attrs = dev_ibcfg_attributes | ||
1070 | }; | ||
1071 | |||
735 | /** | 1072 | /** |
736 | * ipath_expose_reset - create a device reset file | 1073 | * ipath_expose_reset - create a device reset file |
737 | * @dev: the device structure | 1074 | * @dev: the device structure |
@@ -770,8 +1107,27 @@ int ipath_device_create_group(struct device *dev, struct ipath_devdata *dd) | |||
770 | if (ret) | 1107 | if (ret) |
771 | goto bail_attrs; | 1108 | goto bail_attrs; |
772 | 1109 | ||
1110 | if (dd->ipath_flags & IPATH_HAS_MULT_IB_SPEED) { | ||
1111 | ret = device_create_file(dev, &dev_attr_jint_idle_ticks); | ||
1112 | if (ret) | ||
1113 | goto bail_counter; | ||
1114 | ret = device_create_file(dev, &dev_attr_jint_max_packets); | ||
1115 | if (ret) | ||
1116 | goto bail_idle; | ||
1117 | |||
1118 | ret = sysfs_create_group(&dev->kobj, &dev_ibcfg_attr_group); | ||
1119 | if (ret) | ||
1120 | goto bail_max; | ||
1121 | } | ||
1122 | |||
773 | return 0; | 1123 | return 0; |
774 | 1124 | ||
1125 | bail_max: | ||
1126 | device_remove_file(dev, &dev_attr_jint_max_packets); | ||
1127 | bail_idle: | ||
1128 | device_remove_file(dev, &dev_attr_jint_idle_ticks); | ||
1129 | bail_counter: | ||
1130 | sysfs_remove_group(&dev->kobj, &dev_counter_attr_group); | ||
775 | bail_attrs: | 1131 | bail_attrs: |
776 | sysfs_remove_group(&dev->kobj, &dev_attr_group); | 1132 | sysfs_remove_group(&dev->kobj, &dev_attr_group); |
777 | bail: | 1133 | bail: |
@@ -781,6 +1137,13 @@ bail: | |||
781 | void ipath_device_remove_group(struct device *dev, struct ipath_devdata *dd) | 1137 | void ipath_device_remove_group(struct device *dev, struct ipath_devdata *dd) |
782 | { | 1138 | { |
783 | sysfs_remove_group(&dev->kobj, &dev_counter_attr_group); | 1139 | sysfs_remove_group(&dev->kobj, &dev_counter_attr_group); |
1140 | |||
1141 | if (dd->ipath_flags & IPATH_HAS_MULT_IB_SPEED) { | ||
1142 | sysfs_remove_group(&dev->kobj, &dev_ibcfg_attr_group); | ||
1143 | device_remove_file(dev, &dev_attr_jint_idle_ticks); | ||
1144 | device_remove_file(dev, &dev_attr_jint_max_packets); | ||
1145 | } | ||
1146 | |||
784 | sysfs_remove_group(&dev->kobj, &dev_attr_group); | 1147 | sysfs_remove_group(&dev->kobj, &dev_attr_group); |
785 | 1148 | ||
786 | device_remove_file(dev, &dev_attr_reset); | 1149 | device_remove_file(dev, &dev_attr_reset); |