0001
0002
0003
0004
0005
0006 #include <linux/init.h>
0007 #include <linux/module.h>
0008 #include <linux/io.h>
0009 #include <linux/of_net.h>
0010 #include "dpaa_eth.h"
0011 #include "mac.h"
0012
0013 static ssize_t dpaa_eth_show_addr(struct device *dev,
0014 struct device_attribute *attr, char *buf)
0015 {
0016 struct dpaa_priv *priv = netdev_priv(to_net_dev(dev));
0017 struct mac_device *mac_dev = priv->mac_dev;
0018
0019 if (mac_dev)
0020 return sprintf(buf, "%llx",
0021 (unsigned long long)mac_dev->res->start);
0022 else
0023 return sprintf(buf, "none");
0024 }
0025
0026 static ssize_t dpaa_eth_show_fqids(struct device *dev,
0027 struct device_attribute *attr, char *buf)
0028 {
0029 struct dpaa_priv *priv = netdev_priv(to_net_dev(dev));
0030 struct dpaa_fq *prev = NULL;
0031 char *prevstr = NULL;
0032 struct dpaa_fq *tmp;
0033 struct dpaa_fq *fq;
0034 u32 first_fqid = 0;
0035 u32 last_fqid = 0;
0036 ssize_t bytes = 0;
0037 char *str;
0038 int i = 0;
0039
0040 list_for_each_entry_safe(fq, tmp, &priv->dpaa_fq_list, list) {
0041 switch (fq->fq_type) {
0042 case FQ_TYPE_RX_DEFAULT:
0043 str = "Rx default";
0044 break;
0045 case FQ_TYPE_RX_ERROR:
0046 str = "Rx error";
0047 break;
0048 case FQ_TYPE_RX_PCD:
0049 str = "Rx PCD";
0050 break;
0051 case FQ_TYPE_TX_CONFIRM:
0052 str = "Tx default confirmation";
0053 break;
0054 case FQ_TYPE_TX_CONF_MQ:
0055 str = "Tx confirmation (mq)";
0056 break;
0057 case FQ_TYPE_TX_ERROR:
0058 str = "Tx error";
0059 break;
0060 case FQ_TYPE_TX:
0061 str = "Tx";
0062 break;
0063 default:
0064 str = "Unknown";
0065 }
0066
0067 if (prev && (abs(fq->fqid - prev->fqid) != 1 ||
0068 str != prevstr)) {
0069 if (last_fqid == first_fqid)
0070 bytes += sprintf(buf + bytes,
0071 "%s: %d\n", prevstr, prev->fqid);
0072 else
0073 bytes += sprintf(buf + bytes,
0074 "%s: %d - %d\n", prevstr,
0075 first_fqid, last_fqid);
0076 }
0077
0078 if (prev && abs(fq->fqid - prev->fqid) == 1 &&
0079 str == prevstr) {
0080 last_fqid = fq->fqid;
0081 } else {
0082 first_fqid = fq->fqid;
0083 last_fqid = fq->fqid;
0084 }
0085
0086 prev = fq;
0087 prevstr = str;
0088 i++;
0089 }
0090
0091 if (prev) {
0092 if (last_fqid == first_fqid)
0093 bytes += sprintf(buf + bytes, "%s: %d\n", prevstr,
0094 prev->fqid);
0095 else
0096 bytes += sprintf(buf + bytes, "%s: %d - %d\n", prevstr,
0097 first_fqid, last_fqid);
0098 }
0099
0100 return bytes;
0101 }
0102
0103 static ssize_t dpaa_eth_show_bpids(struct device *dev,
0104 struct device_attribute *attr, char *buf)
0105 {
0106 struct dpaa_priv *priv = netdev_priv(to_net_dev(dev));
0107 ssize_t bytes = 0;
0108
0109 bytes += snprintf(buf + bytes, PAGE_SIZE - bytes, "%u\n",
0110 priv->dpaa_bp->bpid);
0111
0112 return bytes;
0113 }
0114
0115 static struct device_attribute dpaa_eth_attrs[] = {
0116 __ATTR(device_addr, 0444, dpaa_eth_show_addr, NULL),
0117 __ATTR(fqids, 0444, dpaa_eth_show_fqids, NULL),
0118 __ATTR(bpids, 0444, dpaa_eth_show_bpids, NULL),
0119 };
0120
0121 void dpaa_eth_sysfs_init(struct device *dev)
0122 {
0123 int i;
0124
0125 for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++)
0126 if (device_create_file(dev, &dpaa_eth_attrs[i])) {
0127 dev_err(dev, "Error creating sysfs file\n");
0128 while (i > 0)
0129 device_remove_file(dev, &dpaa_eth_attrs[--i]);
0130 return;
0131 }
0132 }
0133
0134 void dpaa_eth_sysfs_remove(struct device *dev)
0135 {
0136 int i;
0137
0138 for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++)
0139 device_remove_file(dev, &dpaa_eth_attrs[i]);
0140 }