171 lines · c
1// SPDX-License-Identifier: GPL-2.02 3/* Copyright (C) 2021-2024 Linaro Ltd. */4 5#include <linux/device.h>6#include <linux/sysfs.h>7#include <linux/types.h>8 9#include "ipa.h"10#include "ipa_sysfs.h"11#include "ipa_version.h"12 13static const char *ipa_version_string(struct ipa *ipa)14{15 switch (ipa->version) {16 case IPA_VERSION_3_0:17 return "3.0";18 case IPA_VERSION_3_1:19 return "3.1";20 case IPA_VERSION_3_5:21 return "3.5";22 case IPA_VERSION_3_5_1:23 return "3.5.1";24 case IPA_VERSION_4_0:25 return "4.0";26 case IPA_VERSION_4_1:27 return "4.1";28 case IPA_VERSION_4_2:29 return "4.2";30 case IPA_VERSION_4_5:31 return "4.5";32 case IPA_VERSION_4_7:33 return "4.7";34 case IPA_VERSION_4_9:35 return "4.9";36 case IPA_VERSION_4_11:37 return "4.11";38 case IPA_VERSION_5_0:39 return "5.0";40 default:41 return "0.0"; /* Won't happen (checked at probe time) */42 }43}44 45static ssize_t46version_show(struct device *dev, struct device_attribute *attr, char *buf)47{48 struct ipa *ipa = dev_get_drvdata(dev);49 50 return sysfs_emit(buf, "%s\n", ipa_version_string(ipa));51}52 53static DEVICE_ATTR_RO(version);54 55static struct attribute *ipa_attrs[] = {56 &dev_attr_version.attr,57 NULL58};59 60const struct attribute_group ipa_attribute_group = {61 .attrs = ipa_attrs,62};63 64static const char *ipa_offload_string(struct ipa *ipa)65{66 return ipa->version < IPA_VERSION_4_5 ? "MAPv4" : "MAPv5";67}68 69static ssize_t rx_offload_show(struct device *dev,70 struct device_attribute *attr, char *buf)71{72 struct ipa *ipa = dev_get_drvdata(dev);73 74 return sysfs_emit(buf, "%s\n", ipa_offload_string(ipa));75}76 77static DEVICE_ATTR_RO(rx_offload);78 79static ssize_t tx_offload_show(struct device *dev,80 struct device_attribute *attr, char *buf)81{82 struct ipa *ipa = dev_get_drvdata(dev);83 84 return sysfs_emit(buf, "%s\n", ipa_offload_string(ipa));85}86 87static DEVICE_ATTR_RO(tx_offload);88 89static struct attribute *ipa_feature_attrs[] = {90 &dev_attr_rx_offload.attr,91 &dev_attr_tx_offload.attr,92 NULL93};94 95const struct attribute_group ipa_feature_attribute_group = {96 .name = "feature",97 .attrs = ipa_feature_attrs,98};99 100static umode_t ipa_endpoint_id_is_visible(struct kobject *kobj,101 struct attribute *attr, int n)102{103 struct ipa *ipa = dev_get_drvdata(kobj_to_dev(kobj));104 struct device_attribute *dev_attr;105 struct dev_ext_attribute *ea;106 bool visible;107 108 /* An endpoint id attribute is only visible if it's defined */109 dev_attr = container_of(attr, struct device_attribute, attr);110 ea = container_of(dev_attr, struct dev_ext_attribute, attr);111 112 visible = !!ipa->name_map[(enum ipa_endpoint_name)(uintptr_t)ea->var];113 114 return visible ? attr->mode : 0;115}116 117static ssize_t endpoint_id_attr_show(struct device *dev,118 struct device_attribute *attr, char *buf)119{120 struct ipa *ipa = dev_get_drvdata(dev);121 struct ipa_endpoint *endpoint;122 struct dev_ext_attribute *ea;123 124 ea = container_of(attr, struct dev_ext_attribute, attr);125 endpoint = ipa->name_map[(enum ipa_endpoint_name)(uintptr_t)ea->var];126 127 return sysfs_emit(buf, "%u\n", endpoint->endpoint_id);128}129 130#define ENDPOINT_ID_ATTR(_n, _endpoint_name) \131 static struct dev_ext_attribute dev_attr_endpoint_id_ ## _n = { \132 .attr = __ATTR(_n, 0444, endpoint_id_attr_show, NULL), \133 .var = (void *)(_endpoint_name), \134 }135 136ENDPOINT_ID_ATTR(modem_rx, IPA_ENDPOINT_AP_MODEM_RX);137ENDPOINT_ID_ATTR(modem_tx, IPA_ENDPOINT_AP_MODEM_TX);138 139static struct attribute *ipa_endpoint_id_attrs[] = {140 &dev_attr_endpoint_id_modem_rx.attr.attr,141 &dev_attr_endpoint_id_modem_tx.attr.attr,142 NULL143};144 145const struct attribute_group ipa_endpoint_id_attribute_group = {146 .name = "endpoint_id",147 .is_visible = ipa_endpoint_id_is_visible,148 .attrs = ipa_endpoint_id_attrs,149};150 151/* Reuse endpoint ID attributes for the legacy modem endpoint IDs */152#define MODEM_ATTR(_n, _endpoint_name) \153 static struct dev_ext_attribute dev_attr_modem_ ## _n = { \154 .attr = __ATTR(_n, 0444, endpoint_id_attr_show, NULL), \155 .var = (void *)(_endpoint_name), \156 }157 158MODEM_ATTR(rx_endpoint_id, IPA_ENDPOINT_AP_MODEM_RX);159MODEM_ATTR(tx_endpoint_id, IPA_ENDPOINT_AP_MODEM_TX);160 161static struct attribute *ipa_modem_attrs[] = {162 &dev_attr_modem_rx_endpoint_id.attr.attr,163 &dev_attr_modem_tx_endpoint_id.attr.attr,164 NULL,165};166 167const struct attribute_group ipa_modem_attribute_group = {168 .name = "modem",169 .attrs = ipa_modem_attrs,170};171