1 // SPDX-License-Identifier: GPL-2.0 2 3 /* Copyright (C) 2021 Linaro Ltd. */ 4 5 #include <linux/kernel.h> 6 #include <linux/types.h> 7 #include <linux/device.h> 8 #include <linux/sysfs.h> 9 10 #include "ipa.h" 11 #include "ipa_version.h" 12 #include "ipa_sysfs.h" 13 14 static const char *ipa_version_string(struct ipa *ipa) 15 { 16 switch (ipa->version) { 17 case IPA_VERSION_3_0: 18 return "3.0"; 19 case IPA_VERSION_3_1: 20 return "3.1"; 21 case IPA_VERSION_3_5: 22 return "3.5"; 23 case IPA_VERSION_3_5_1: 24 return "3.5.1"; 25 case IPA_VERSION_4_0: 26 return "4.0"; 27 case IPA_VERSION_4_1: 28 return "4.1"; 29 case IPA_VERSION_4_2: 30 return "4.2"; 31 case IPA_VERSION_4_5: 32 return "4.5"; 33 case IPA_VERSION_4_7: 34 return "4.7"; 35 case IPA_VERSION_4_9: 36 return "4.9"; 37 case IPA_VERSION_4_11: 38 return "4.11"; 39 default: 40 return "0.0"; /* Won't happen (checked at probe time) */ 41 } 42 } 43 44 static ssize_t 45 version_show(struct device *dev, struct device_attribute *attr, char *buf) 46 { 47 struct ipa *ipa = dev_get_drvdata(dev); 48 49 return scnprintf(buf, PAGE_SIZE, "%s\n", ipa_version_string(ipa)); 50 } 51 52 static DEVICE_ATTR_RO(version); 53 54 static struct attribute *ipa_attrs[] = { 55 &dev_attr_version.attr, 56 NULL 57 }; 58 59 const struct attribute_group ipa_attribute_group = { 60 .attrs = ipa_attrs, 61 }; 62 63 static const char *ipa_offload_string(struct ipa *ipa) 64 { 65 return ipa->version < IPA_VERSION_4_5 ? "MAPv4" : "MAPv5"; 66 } 67 68 static ssize_t rx_offload_show(struct device *dev, 69 struct device_attribute *attr, char *buf) 70 { 71 struct ipa *ipa = dev_get_drvdata(dev); 72 73 return scnprintf(buf, PAGE_SIZE, "%s\n", ipa_offload_string(ipa)); 74 } 75 76 static DEVICE_ATTR_RO(rx_offload); 77 78 static ssize_t tx_offload_show(struct device *dev, 79 struct device_attribute *attr, char *buf) 80 { 81 struct ipa *ipa = dev_get_drvdata(dev); 82 83 return scnprintf(buf, PAGE_SIZE, "%s\n", ipa_offload_string(ipa)); 84 } 85 86 static DEVICE_ATTR_RO(tx_offload); 87 88 static struct attribute *ipa_feature_attrs[] = { 89 &dev_attr_rx_offload.attr, 90 &dev_attr_tx_offload.attr, 91 NULL 92 }; 93 94 const struct attribute_group ipa_feature_attribute_group = { 95 .name = "feature", 96 .attrs = ipa_feature_attrs, 97 }; 98 99 static ssize_t 100 ipa_endpoint_id_show(struct ipa *ipa, char *buf, enum ipa_endpoint_name name) 101 { 102 u32 endpoint_id = ipa->name_map[name]->endpoint_id; 103 104 return scnprintf(buf, PAGE_SIZE, "%u\n", endpoint_id); 105 } 106 107 static ssize_t rx_endpoint_id_show(struct device *dev, 108 struct device_attribute *attr, char *buf) 109 { 110 struct ipa *ipa = dev_get_drvdata(dev); 111 112 return ipa_endpoint_id_show(ipa, buf, IPA_ENDPOINT_AP_MODEM_RX); 113 } 114 115 static DEVICE_ATTR_RO(rx_endpoint_id); 116 117 static ssize_t tx_endpoint_id_show(struct device *dev, 118 struct device_attribute *attr, char *buf) 119 { 120 struct ipa *ipa = dev_get_drvdata(dev); 121 122 return ipa_endpoint_id_show(ipa, buf, IPA_ENDPOINT_AP_MODEM_TX); 123 } 124 125 static DEVICE_ATTR_RO(tx_endpoint_id); 126 127 static struct attribute *ipa_modem_attrs[] = { 128 &dev_attr_rx_endpoint_id.attr, 129 &dev_attr_tx_endpoint_id.attr, 130 NULL 131 }; 132 133 const struct attribute_group ipa_modem_attribute_group = { 134 .name = "modem", 135 .attrs = ipa_modem_attrs, 136 }; 137