0001
0002
0003
0004
0005 #include <linux/kernel.h>
0006 #include <linux/types.h>
0007 #include <linux/device.h>
0008 #include <linux/sysfs.h>
0009
0010 #include "ipa.h"
0011 #include "ipa_version.h"
0012 #include "ipa_sysfs.h"
0013
0014 static const char *ipa_version_string(struct ipa *ipa)
0015 {
0016 switch (ipa->version) {
0017 case IPA_VERSION_3_0:
0018 return "3.0";
0019 case IPA_VERSION_3_1:
0020 return "3.1";
0021 case IPA_VERSION_3_5:
0022 return "3.5";
0023 case IPA_VERSION_3_5_1:
0024 return "3.5.1";
0025 case IPA_VERSION_4_0:
0026 return "4.0";
0027 case IPA_VERSION_4_1:
0028 return "4.1";
0029 case IPA_VERSION_4_2:
0030 return "4.2";
0031 case IPA_VERSION_4_5:
0032 return "4.5";
0033 case IPA_VERSION_4_7:
0034 return "4.7";
0035 case IPA_VERSION_4_9:
0036 return "4.9";
0037 case IPA_VERSION_4_11:
0038 return "4.11";
0039 default:
0040 return "0.0";
0041 }
0042 }
0043
0044 static ssize_t
0045 version_show(struct device *dev, struct device_attribute *attr, char *buf)
0046 {
0047 struct ipa *ipa = dev_get_drvdata(dev);
0048
0049 return scnprintf(buf, PAGE_SIZE, "%s\n", ipa_version_string(ipa));
0050 }
0051
0052 static DEVICE_ATTR_RO(version);
0053
0054 static struct attribute *ipa_attrs[] = {
0055 &dev_attr_version.attr,
0056 NULL
0057 };
0058
0059 const struct attribute_group ipa_attribute_group = {
0060 .attrs = ipa_attrs,
0061 };
0062
0063 static const char *ipa_offload_string(struct ipa *ipa)
0064 {
0065 return ipa->version < IPA_VERSION_4_5 ? "MAPv4" : "MAPv5";
0066 }
0067
0068 static ssize_t rx_offload_show(struct device *dev,
0069 struct device_attribute *attr, char *buf)
0070 {
0071 struct ipa *ipa = dev_get_drvdata(dev);
0072
0073 return scnprintf(buf, PAGE_SIZE, "%s\n", ipa_offload_string(ipa));
0074 }
0075
0076 static DEVICE_ATTR_RO(rx_offload);
0077
0078 static ssize_t tx_offload_show(struct device *dev,
0079 struct device_attribute *attr, char *buf)
0080 {
0081 struct ipa *ipa = dev_get_drvdata(dev);
0082
0083 return scnprintf(buf, PAGE_SIZE, "%s\n", ipa_offload_string(ipa));
0084 }
0085
0086 static DEVICE_ATTR_RO(tx_offload);
0087
0088 static struct attribute *ipa_feature_attrs[] = {
0089 &dev_attr_rx_offload.attr,
0090 &dev_attr_tx_offload.attr,
0091 NULL
0092 };
0093
0094 const struct attribute_group ipa_feature_attribute_group = {
0095 .name = "feature",
0096 .attrs = ipa_feature_attrs,
0097 };
0098
0099 static umode_t ipa_endpoint_id_is_visible(struct kobject *kobj,
0100 struct attribute *attr, int n)
0101 {
0102 struct ipa *ipa = dev_get_drvdata(kobj_to_dev(kobj));
0103 struct device_attribute *dev_attr;
0104 struct dev_ext_attribute *ea;
0105 bool visible;
0106
0107
0108 dev_attr = container_of(attr, struct device_attribute, attr);
0109 ea = container_of(dev_attr, struct dev_ext_attribute, attr);
0110
0111 visible = !!ipa->name_map[(enum ipa_endpoint_name)(uintptr_t)ea->var];
0112
0113 return visible ? attr->mode : 0;
0114 }
0115
0116 static ssize_t endpoint_id_attr_show(struct device *dev,
0117 struct device_attribute *attr, char *buf)
0118 {
0119 struct ipa *ipa = dev_get_drvdata(dev);
0120 struct ipa_endpoint *endpoint;
0121 struct dev_ext_attribute *ea;
0122
0123 ea = container_of(attr, struct dev_ext_attribute, attr);
0124 endpoint = ipa->name_map[(enum ipa_endpoint_name)(uintptr_t)ea->var];
0125
0126 return sysfs_emit(buf, "%u\n", endpoint->endpoint_id);
0127 }
0128
0129 #define ENDPOINT_ID_ATTR(_n, _endpoint_name) \
0130 static struct dev_ext_attribute dev_attr_endpoint_id_ ## _n = { \
0131 .attr = __ATTR(_n, 0444, endpoint_id_attr_show, NULL), \
0132 .var = (void *)(_endpoint_name), \
0133 }
0134
0135 ENDPOINT_ID_ATTR(modem_rx, IPA_ENDPOINT_AP_MODEM_RX);
0136 ENDPOINT_ID_ATTR(modem_tx, IPA_ENDPOINT_AP_MODEM_TX);
0137
0138 static struct attribute *ipa_endpoint_id_attrs[] = {
0139 &dev_attr_endpoint_id_modem_rx.attr.attr,
0140 &dev_attr_endpoint_id_modem_tx.attr.attr,
0141 NULL
0142 };
0143
0144 const struct attribute_group ipa_endpoint_id_attribute_group = {
0145 .name = "endpoint_id",
0146 .is_visible = ipa_endpoint_id_is_visible,
0147 .attrs = ipa_endpoint_id_attrs,
0148 };
0149
0150
0151 #define MODEM_ATTR(_n, _endpoint_name) \
0152 static struct dev_ext_attribute dev_attr_modem_ ## _n = { \
0153 .attr = __ATTR(_n, 0444, endpoint_id_attr_show, NULL), \
0154 .var = (void *)(_endpoint_name), \
0155 }
0156
0157 MODEM_ATTR(rx_endpoint_id, IPA_ENDPOINT_AP_MODEM_RX);
0158 MODEM_ATTR(tx_endpoint_id, IPA_ENDPOINT_AP_MODEM_TX);
0159
0160 static struct attribute *ipa_modem_attrs[] = {
0161 &dev_attr_modem_rx_endpoint_id.attr.attr,
0162 &dev_attr_modem_tx_endpoint_id.attr.attr,
0163 NULL,
0164 };
0165
0166 const struct attribute_group ipa_modem_attribute_group = {
0167 .name = "modem",
0168 .attrs = ipa_modem_attrs,
0169 };