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_RX_PCD: 75 str = "Rx PCD"; 76 break; 77 case FQ_TYPE_TX_CONFIRM: 78 str = "Tx default confirmation"; 79 break; 80 case FQ_TYPE_TX_CONF_MQ: 81 str = "Tx confirmation (mq)"; 82 break; 83 case FQ_TYPE_TX_ERROR: 84 str = "Tx error"; 85 break; 86 case FQ_TYPE_TX: 87 str = "Tx"; 88 break; 89 default: 90 str = "Unknown"; 91 } 92 93 if (prev && (abs(fq->fqid - prev->fqid) != 1 || 94 str != prevstr)) { 95 if (last_fqid == first_fqid) 96 bytes += sprintf(buf + bytes, 97 "%s: %d\n", prevstr, prev->fqid); 98 else 99 bytes += sprintf(buf + bytes, 100 "%s: %d - %d\n", prevstr, 101 first_fqid, last_fqid); 102 } 103 104 if (prev && abs(fq->fqid - prev->fqid) == 1 && 105 str == prevstr) { 106 last_fqid = fq->fqid; 107 } else { 108 first_fqid = fq->fqid; 109 last_fqid = fq->fqid; 110 } 111 112 prev = fq; 113 prevstr = str; 114 i++; 115 } 116 117 if (prev) { 118 if (last_fqid == first_fqid) 119 bytes += sprintf(buf + bytes, "%s: %d\n", prevstr, 120 prev->fqid); 121 else 122 bytes += sprintf(buf + bytes, "%s: %d - %d\n", prevstr, 123 first_fqid, last_fqid); 124 } 125 126 return bytes; 127 } 128 129 static ssize_t dpaa_eth_show_bpids(struct device *dev, 130 struct device_attribute *attr, char *buf) 131 { 132 struct dpaa_priv *priv = netdev_priv(to_net_dev(dev)); 133 ssize_t bytes = 0; 134 int i = 0; 135 136 for (i = 0; i < DPAA_BPS_NUM; i++) 137 bytes += snprintf(buf + bytes, PAGE_SIZE - bytes, "%u\n", 138 priv->dpaa_bps[i]->bpid); 139 140 return bytes; 141 } 142 143 static struct device_attribute dpaa_eth_attrs[] = { 144 __ATTR(device_addr, 0444, dpaa_eth_show_addr, NULL), 145 __ATTR(fqids, 0444, dpaa_eth_show_fqids, NULL), 146 __ATTR(bpids, 0444, dpaa_eth_show_bpids, NULL), 147 }; 148 149 void dpaa_eth_sysfs_init(struct device *dev) 150 { 151 int i; 152 153 for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++) 154 if (device_create_file(dev, &dpaa_eth_attrs[i])) { 155 dev_err(dev, "Error creating sysfs file\n"); 156 while (i > 0) 157 device_remove_file(dev, &dpaa_eth_attrs[--i]); 158 return; 159 } 160 } 161 162 void dpaa_eth_sysfs_remove(struct device *dev) 163 { 164 int i; 165 166 for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++) 167 device_remove_file(dev, &dpaa_eth_attrs[i]); 168 } 169