1 /* Copyright 2008-2016 Freescale Semiconductor Inc. 2 * 3 * Redistribution and use in source and binary forms, with or without 4 * modification, are permitted provided that the following conditions are met: 5 * * Redistributions of source code must retain the above copyright 6 * notice, this list of conditions and the following disclaimer. 7 * * Redistributions in binary form must reproduce the above copyright 8 * notice, this list of conditions and the following disclaimer in the 9 * documentation and/or other materials provided with the distribution. 10 * * Neither the name of Freescale Semiconductor nor the 11 * names of its contributors may be used to endorse or promote products 12 * derived from this software without specific prior written permission. 13 * 14 * 15 * ALTERNATIVELY, this software may be distributed under the terms of the 16 * GNU General Public License ("GPL") as published by the Free Software 17 * Foundation, either version 2 of that License or (at your option) any 18 * later version. 19 * 20 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY 21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY 24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <linux/init.h> 33 #include <linux/module.h> 34 #include <linux/io.h> 35 #include <linux/of_net.h> 36 #include "dpaa_eth.h" 37 #include "mac.h" 38 39 static ssize_t dpaa_eth_show_addr(struct device *dev, 40 struct device_attribute *attr, char *buf) 41 { 42 struct dpaa_priv *priv = netdev_priv(to_net_dev(dev)); 43 struct mac_device *mac_dev = priv->mac_dev; 44 45 if (mac_dev) 46 return sprintf(buf, "%llx", 47 (unsigned long long)mac_dev->res->start); 48 else 49 return sprintf(buf, "none"); 50 } 51 52 static ssize_t dpaa_eth_show_fqids(struct device *dev, 53 struct device_attribute *attr, char *buf) 54 { 55 struct dpaa_priv *priv = netdev_priv(to_net_dev(dev)); 56 struct dpaa_fq *prev = NULL; 57 char *prevstr = NULL; 58 struct dpaa_fq *tmp; 59 struct dpaa_fq *fq; 60 u32 first_fqid = 0; 61 u32 last_fqid = 0; 62 ssize_t bytes = 0; 63 char *str; 64 int i = 0; 65 66 list_for_each_entry_safe(fq, tmp, &priv->dpaa_fq_list, list) { 67 switch (fq->fq_type) { 68 case FQ_TYPE_RX_DEFAULT: 69 str = "Rx default"; 70 break; 71 case FQ_TYPE_RX_ERROR: 72 str = "Rx error"; 73 break; 74 case FQ_TYPE_TX_CONFIRM: 75 str = "Tx default confirmation"; 76 break; 77 case FQ_TYPE_TX_CONF_MQ: 78 str = "Tx confirmation (mq)"; 79 break; 80 case FQ_TYPE_TX_ERROR: 81 str = "Tx error"; 82 break; 83 case FQ_TYPE_TX: 84 str = "Tx"; 85 break; 86 default: 87 str = "Unknown"; 88 } 89 90 if (prev && (abs(fq->fqid - prev->fqid) != 1 || 91 str != prevstr)) { 92 if (last_fqid == first_fqid) 93 bytes += sprintf(buf + bytes, 94 "%s: %d\n", prevstr, prev->fqid); 95 else 96 bytes += sprintf(buf + bytes, 97 "%s: %d - %d\n", prevstr, 98 first_fqid, last_fqid); 99 } 100 101 if (prev && abs(fq->fqid - prev->fqid) == 1 && 102 str == prevstr) { 103 last_fqid = fq->fqid; 104 } else { 105 first_fqid = fq->fqid; 106 last_fqid = fq->fqid; 107 } 108 109 prev = fq; 110 prevstr = str; 111 i++; 112 } 113 114 if (prev) { 115 if (last_fqid == first_fqid) 116 bytes += sprintf(buf + bytes, "%s: %d\n", prevstr, 117 prev->fqid); 118 else 119 bytes += sprintf(buf + bytes, "%s: %d - %d\n", prevstr, 120 first_fqid, last_fqid); 121 } 122 123 return bytes; 124 } 125 126 static ssize_t dpaa_eth_show_bpids(struct device *dev, 127 struct device_attribute *attr, char *buf) 128 { 129 struct dpaa_priv *priv = netdev_priv(to_net_dev(dev)); 130 ssize_t bytes = 0; 131 int i = 0; 132 133 for (i = 0; i < DPAA_BPS_NUM; i++) 134 bytes += snprintf(buf + bytes, PAGE_SIZE - bytes, "%u\n", 135 priv->dpaa_bps[i]->bpid); 136 137 return bytes; 138 } 139 140 static struct device_attribute dpaa_eth_attrs[] = { 141 __ATTR(device_addr, 0444, dpaa_eth_show_addr, NULL), 142 __ATTR(fqids, 0444, dpaa_eth_show_fqids, NULL), 143 __ATTR(bpids, 0444, dpaa_eth_show_bpids, NULL), 144 }; 145 146 void dpaa_eth_sysfs_init(struct device *dev) 147 { 148 int i; 149 150 for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++) 151 if (device_create_file(dev, &dpaa_eth_attrs[i])) { 152 dev_err(dev, "Error creating sysfs file\n"); 153 while (i > 0) 154 device_remove_file(dev, &dpaa_eth_attrs[--i]); 155 return; 156 } 157 } 158 159 void dpaa_eth_sysfs_remove(struct device *dev) 160 { 161 int i; 162 163 for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++) 164 device_remove_file(dev, &dpaa_eth_attrs[i]); 165 } 166